summaryrefslogtreecommitdiff
path: root/i/pc104/initrd/conf/busybox/coreutils
diff options
context:
space:
mode:
Diffstat (limited to 'i/pc104/initrd/conf/busybox/coreutils')
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/Config.in782
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/Kbuild85
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/basename.c51
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/cal.c352
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/cat.c43
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/catv.c70
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/chgrp.c28
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/chmod.c159
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/chown.c167
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/chroot.c38
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/cksum.c54
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/cmp.c145
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/comm.c127
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/cp.c100
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/cut.c287
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/date.c241
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/dd.c249
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/df.c155
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/diff.c1227
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/dirname.c27
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/dos2unix.c116
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/du.c247
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/echo.c159
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/env.c128
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/expr.c506
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/false.c20
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/fold.c155
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/head.c140
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/hostid.c26
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/id.c130
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/install.c202
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/length.c20
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/libcoreutils/Kbuild12
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/libcoreutils/coreutils.h16
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/libcoreutils/cp_mv_stat.c43
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/libcoreutils/getopt_mk_fifo_nod.c51
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/ln.c105
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/logname.c43
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/ls.c957
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/md5_sha1_sum.c185
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/mkdir.c82
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/mkfifo.c39
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/mknod.c51
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/mv.c137
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/nice.c55
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/nohup.c60
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/od.c225
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/od_bloaty.c1465
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/printenv.c42
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/printf.c313
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/pwd.c26
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/realpath.c47
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/rm.c53
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/rmdir.c61
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/seq.c41
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/sleep.c68
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/sort.c401
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/stat.c676
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/stty.c1189
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/sum.c100
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/sync.c24
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/tail.c278
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/tee.c101
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/test.c586
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/touch.c62
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/tr.c254
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/true.c20
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/tty.c44
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/uname.c108
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/uniq.c104
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/usleep.c29
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/uudecode.c181
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/uuencode.c76
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/watch.c80
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/wc.c205
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/who.c76
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/whoami.c26
-rw-r--r--i/pc104/initrd/conf/busybox/coreutils/yes.c42
78 files changed, 15075 insertions, 0 deletions
diff --git a/i/pc104/initrd/conf/busybox/coreutils/Config.in b/i/pc104/initrd/conf/busybox/coreutils/Config.in
new file mode 100644
index 0000000..000f3a8
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/Config.in
@@ -0,0 +1,782 @@
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Coreutils"
+
+config BASENAME
+ bool "basename"
+ default n
+ help
+ basename is used to strip the directory and suffix from filenames,
+ leaving just the filename itself. Enable this option if you wish
+ to enable the 'basename' utility.
+
+config CAL
+ bool "cal"
+ default n
+ help
+ cal is used to display a monthly calender.
+
+config CAT
+ bool "cat"
+ default n
+ help
+ cat is used to concatenate files and print them to the standard
+ output. Enable this option if you wish to enable the 'cat' utility.
+
+config CATV
+ bool "catv"
+ default n
+ help
+ Display nonprinting characters as escape sequences (like some
+ implementations' cat -v option).
+
+config CHGRP
+ bool "chgrp"
+ default n
+ help
+ chgrp is used to change the group ownership of files.
+
+config CHMOD
+ bool "chmod"
+ default n
+ help
+ chmod is used to change the access permission of files.
+
+config CHOWN
+ bool "chown"
+ default n
+ help
+ chown is used to change the user and/or group ownership
+ of files.
+
+config CHROOT
+ bool "chroot"
+ default n
+ help
+ chroot is used to change the root directory and run a command.
+ The default command is `/bin/sh'.
+
+config CKSUM
+ bool "cksum"
+ default n
+ help
+ cksum is used to calculate the CRC32 checksum of a file.
+
+config CMP
+ bool "cmp"
+ default n
+ help
+ cmp is used to compare two files and returns the result
+ to standard output.
+
+config COMM
+ bool "comm"
+ default n
+ help
+ comm is used to compare two files line by line and return
+ a three-column output.
+
+config CP
+ bool "cp"
+ default n
+ help
+ cp is used to copy files and directories.
+
+config CUT
+ bool "cut"
+ default n
+ help
+ cut is used to print selected parts of lines from
+ each file to stdout.
+
+config DATE
+ bool "date"
+ default n
+ help
+ date is used to set the system date or display the
+ current time in the given format.
+
+config FEATURE_DATE_ISOFMT
+ bool "Enable ISO date format output (-I)"
+ default y
+ depends on DATE
+ help
+ Enable option (-I) to output an ISO-8601 compliant
+ date/time string.
+
+config DD
+ bool "dd"
+ default n
+ help
+ dd copies a file (from standard input to standard output,
+ by default) using specific input and output blocksizes,
+ while optionally performing conversions on it.
+
+config FEATURE_DD_SIGNAL_HANDLING
+ bool "Enable DD signal handling for status reporting"
+ default y
+ depends on DD
+ help
+ sending a SIGUSR1 signal to a running `dd' process makes it
+ print to standard error the number of records read and written
+ so far, then to resume copying.
+
+ $ dd if=/dev/zero of=/dev/null& pid=$! $ kill -USR1 $pid; sleep 1; kill $pid
+ 10899206+0 records in 10899206+0 records out
+
+config FEATURE_DD_IBS_OBS
+ bool "Enable ibs, obs and conv options"
+ default n
+ depends on DD
+ help
+ Enables support for writing a certain number of bytes in and out,
+ at a time, and performing conversions on the data stream.
+
+config DF
+ bool "df"
+ default n
+ help
+ df reports the amount of disk space used and available
+ on filesystems.
+
+config DIFF
+ bool "diff"
+ default n
+ help
+ diff compares two files or directories and outputs the
+ differences between them in a form that can be given to
+ the patch command.
+
+config FEATURE_DIFF_BINARY
+ bool "Enable checks for binary files"
+ default y
+ depends on DIFF
+ help
+ This option enables support for checking for binary files
+ before a comparison is carried out.
+
+config FEATURE_DIFF_DIR
+ bool "Enable directory support"
+ default y
+ depends on DIFF
+ help
+ This option enables support for directory and subdirectory
+ comparison.
+
+config FEATURE_DIFF_MINIMAL
+ bool "Enable -d option to find smaller sets of changes"
+ default n
+ depends on DIFF
+ help
+ Enabling this option allows the use of -d to make diff
+ try hard to find the smallest possible set of changes.
+
+config DIRNAME
+ bool "dirname"
+ default n
+ help
+ dirname is used to strip a non-directory suffix from
+ a file name.
+
+config DOS2UNIX
+ bool "dos2unix/unix2dos"
+ default n
+ help
+ dos2unix is used to convert a text file from DOS format to
+ UNIX format, and vice versa.
+
+config UNIX2DOS
+ bool
+ default y
+ depends on DOS2UNIX
+ help
+ unix2dos is used to convert a text file from UNIX format to
+ DOS format, and vice versa.
+
+config DU
+ bool "du (default blocksize of 512 bytes)"
+ default n
+ help
+ du is used to report the amount of disk space used
+ for specified files.
+
+config FEATURE_DU_DEFAULT_BLOCKSIZE_1K
+ bool "Use a default blocksize of 1024 bytes (1K)"
+ default y
+ depends on DU
+ help
+ Use a blocksize of (1K) instead of the default 512b.
+
+config ECHO
+ bool "echo (basic SuSv3 version taking no options)"
+ default n
+ help
+ echo is used to print a specified string to stdout.
+
+# this entry also appears in shell/Config.in, next to the echo builtin
+config FEATURE_FANCY_ECHO
+ bool "Enable echo options (-n and -e)"
+ default y
+ depends on ECHO
+ help
+ This adds options (-n and -e) to echo.
+
+config ENV
+ bool "env"
+ default n
+ help
+ env is used to set an environment variable and run
+ a command; without options it displays the current
+ environment.
+
+config FEATURE_ENV_LONG_OPTIONS
+ bool "Enable long options"
+ default n
+ depends on ENV && GETOPT_LONG
+ help
+ Support long options for the env applet.
+
+config EXPR
+ bool "expr"
+ default n
+ help
+ expr is used to calculate numbers and print the result
+ to standard output.
+
+config EXPR_MATH_SUPPORT_64
+ bool "Extend Posix numbers support to 64 bit"
+ default n
+ depends on EXPR
+ help
+ Enable 64-bit math support in the expr applet. This will make
+ the applet slightly larger, but will allow computation with very
+ large numbers.
+
+config FALSE
+ bool "false"
+ default n
+ help
+ false returns an exit code of FALSE (1).
+
+config FOLD
+ bool "fold"
+ default n
+ help
+ Wrap text to fit a specific width.
+
+config HEAD
+ bool "head"
+ default n
+ help
+ head is used to print the first specified number of lines
+ from files.
+
+config FEATURE_FANCY_HEAD
+ bool "Enable head options (-c, -q, and -v)"
+ default n
+ depends on HEAD
+ help
+ This enables the head options (-c, -q, and -v).
+
+config HOSTID
+ bool "hostid"
+ default n
+ help
+ hostid prints the numeric identifier (in hexadecimal) for
+ the current host.
+
+config ID
+ bool "id"
+ default n
+ help
+ id displays the current user and group ID names.
+
+config INSTALL
+ bool "install"
+ default n
+ help
+ Copy files and set attributes.
+
+config FEATURE_INSTALL_LONG_OPTIONS
+ bool "Enable long options"
+ default n
+ depends on INSTALL && GETOPT_LONG
+ help
+ Support long options for the install applet.
+
+config LENGTH
+ bool "length"
+ default n
+ help
+ length is used to print out the length of a specified string.
+
+config LN
+ bool "ln"
+ default n
+ help
+ ln is used to create hard or soft links between files.
+
+config LOGNAME
+ bool "logname"
+ default n
+ help
+ logname is used to print the current user's login name.
+
+config LS
+ bool "ls"
+ default n
+ help
+ ls is used to list the contents of directories.
+
+config FEATURE_LS_FILETYPES
+ bool "Enable filetyping options (-p and -F)"
+ default y
+ depends on LS
+ help
+ Enable the ls options (-p and -F).
+
+config FEATURE_LS_FOLLOWLINKS
+ bool "Enable symlinks dereferencing (-L)"
+ default y
+ depends on LS
+ help
+ Enable the ls option (-L).
+
+config FEATURE_LS_RECURSIVE
+ bool "Enable recursion (-R)"
+ default y
+ depends on LS
+ help
+ Enable the ls option (-R).
+
+config FEATURE_LS_SORTFILES
+ bool "Sort the file names"
+ default y
+ depends on LS
+ help
+ Allow ls to sort file names alphabetically.
+
+config FEATURE_LS_TIMESTAMPS
+ bool "Show file timestamps"
+ default y
+ depends on LS
+ help
+ Allow ls to display timestamps for files.
+
+config FEATURE_LS_USERNAME
+ bool "Show username/groupnames"
+ default y
+ depends on LS
+ help
+ Allow ls to display username/groupname for files.
+
+config FEATURE_LS_COLOR
+ bool "Allow use of color to identify file types"
+ default y
+ depends on LS && GETOPT_LONG
+ help
+ This enables the --color option to ls.
+
+config FEATURE_LS_COLOR_IS_DEFAULT
+ bool "Produce colored ls output by default"
+ default n
+ depends on FEATURE_LS_COLOR
+ help
+ Saying yes here will turn coloring on by default,
+ even if no "--color" option is given to the ls command.
+ This is not recommended, since the colors are not
+ configurable, and the output may not be legible on
+ many output screens.
+
+config MD5SUM
+ bool "md5sum"
+ default n
+ help
+ md5sum is used to print or check MD5 checksums.
+
+config MKDIR
+ bool "mkdir"
+ default n
+ help
+ mkdir is used to create directories with the specified names.
+
+config FEATURE_MKDIR_LONG_OPTIONS
+ bool "Enable long options"
+ default n
+ depends on MKDIR && GETOPT_LONG
+ help
+ Support long options for the mkdir applet.
+
+config MKFIFO
+ bool "mkfifo"
+ default n
+ help
+ mkfifo is used to create FIFOs (named pipes).
+ The `mknod' program can also create FIFOs.
+
+config MKNOD
+ bool "mknod"
+ default n
+ help
+ mknod is used to create FIFOs or block/character special
+ files with the specified names.
+
+config MV
+ bool "mv"
+ default n
+ help
+ mv is used to move or rename files or directories.
+
+config FEATURE_MV_LONG_OPTIONS
+ bool "Enable long options"
+ default n
+ depends on MV && GETOPT_LONG
+ help
+ Support long options for the mv applet.
+
+config NICE
+ bool "nice"
+ default n
+ help
+ nice runs a program with modified scheduling priority.
+
+config NOHUP
+ bool "nohup"
+ default n
+ help
+ run a command immune to hangups, with output to a non-tty.
+
+config OD
+ bool "od"
+ default n
+ help
+ od is used to dump binary files in octal and other formats.
+
+config PRINTENV
+ bool "printenv"
+ default n
+ help
+ printenv is used to print all or part of environment.
+
+config PRINTF
+ bool "printf"
+ default n
+ help
+ printf is used to format and print specified strings.
+ It's similar to `echo' except it has more options.
+
+config PWD
+ bool "pwd"
+ default n
+ help
+ pwd is used to print the current directory.
+
+config REALPATH
+ bool "realpath"
+ default n
+ help
+ Return the canonicalized absolute pathname.
+ This isn't provided by GNU shellutils, but where else does it belong.
+
+config RM
+ bool "rm"
+ default n
+ help
+ rm is used to remove files or directories.
+
+config RMDIR
+ bool "rmdir"
+ default n
+ help
+ rmdir is used to remove empty directories.
+
+config SEQ
+ bool "seq"
+ default n
+ help
+ print a sequence of numbers
+
+config SHA1SUM
+ bool "sha1sum"
+ default n
+ help
+ Compute and check SHA1 message digest
+
+config SLEEP
+ bool "sleep (single integer arg with no suffix)"
+ default n
+ help
+ sleep is used to pause for a specified number of seconds,
+
+config FEATURE_FANCY_SLEEP
+ bool "Enable multiple integer args and optional time suffixes"
+ default n
+ depends on SLEEP
+ help
+ Allow sleep to pause for specified minutes, hours, and days.
+
+config SORT
+ bool "sort"
+ default n
+ help
+ sort is used to sort lines of text in specified files.
+
+config FEATURE_SORT_BIG
+ bool "full SuSv3 compliant sort (Support -ktcsbdfiozgM)"
+ default y
+ depends on SORT
+ help
+ Without this, sort only supports -r, -u, and an integer version
+ of -n. Selecting this adds sort keys, floating point support, and
+ more. This adds a little over 3k to a nonstatic build on x86.
+
+ The SuSv3 sort standard is available at:
+ http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html
+
+config STAT
+ bool "stat"
+ default n
+ help
+ display file or filesystem status.
+
+config FEATURE_STAT_FORMAT
+ bool "Enable custom formats (-c)"
+ default n
+ depends on STAT
+ help
+ Without this, stat will not support the '-c format' option where
+ users can pass a custom format string for output. This adds about
+ 7k to a nonstatic build on amd64.
+
+config STTY
+ bool "stty"
+ default n
+ help
+ stty is used to change and print terminal line settings.
+
+config SUM
+ bool "sum"
+ default n
+ help
+ checksum and count the blocks in a file
+
+config SYNC
+ bool "sync"
+ default n
+ help
+ sync is used to flush filesystem buffers.
+
+config TAIL
+ bool "tail"
+ default n
+ help
+ tail is used to print the last specified number of lines
+ from files.
+
+config FEATURE_FANCY_TAIL
+ bool "Enable extra tail options (-q, -s, and -v)"
+ default y
+ depends on TAIL
+ help
+ The options (-q, -s, and -v) are provided by GNU tail, but
+ are not specific in the SUSv3 standard.
+
+config TEE
+ bool "tee"
+ default n
+ help
+ tee is used to read from standard input and write
+ to standard output and files.
+
+config FEATURE_TEE_USE_BLOCK_IO
+ bool "Enable block i/o (larger/faster) instead of byte i/o."
+ default n
+ depends on TEE
+ help
+ Enable this option for a faster tee, at expense of size.
+
+config TEST
+ bool "test"
+ default n
+ help
+ test is used to check file types and compare values,
+ returning an appropriate exit code. The bash shell
+ has test built in, ash can build it in optionally.
+
+config FEATURE_TEST_64
+ bool "Extend test to 64 bit"
+ default n
+ depends on TEST
+ help
+ Enable 64-bit support in test.
+
+config TOUCH
+ bool "touch"
+ default n
+ help
+ touch is used to create or change the access and/or
+ modification timestamp of specified files.
+
+config TR
+ bool "tr"
+ default n
+ help
+ tr is used to squeeze, and/or delete characters from standard
+ input, writing to standard output.
+
+config FEATURE_TR_CLASSES
+ bool "Enable character classes (such as [:upper:])"
+ default n
+ depends on TR
+ help
+ Enable character classes, enabling commands such as:
+ tr [:upper:] [:lower:] to convert input into lowercase.
+
+config FEATURE_TR_EQUIV
+ bool "Enable equivalence classes"
+ default n
+ depends on TR
+ help
+ Enable equivalence classes, which essentially add the enclosed
+ character to the current set. For instance, tr [=a=] xyz would
+ replace all instances of 'a' with 'xyz'. This option is mainly
+ useful for cases when no other way of expressing a character
+ is possible.
+
+config TRUE
+ bool "true"
+ default n
+ help
+ true returns an exit code of TRUE (0).
+
+config TTY
+ bool "tty"
+ default n
+ help
+ tty is used to print the name of the current terminal to
+ standard output.
+
+config UNAME
+ bool "uname"
+ default n
+ help
+ uname is used to print system information.
+
+config UNIQ
+ bool "uniq"
+ default n
+ help
+ uniq is used to remove duplicate lines from a sorted file.
+
+config USLEEP
+ bool "usleep"
+ default n
+ help
+ usleep is used to pause for a specified number of microseconds.
+
+config UUDECODE
+ bool "uudecode"
+ default n
+ help
+ uudecode is used to decode a uuencoded file.
+
+config UUENCODE
+ bool "uuencode"
+ default n
+ help
+ uuencode is used to uuencode a file.
+
+config WATCH
+ bool "watch"
+ default n
+ select DATE
+ help
+ watch is used to execute a program periodically, showing
+ output to the screen.
+
+config WC
+ bool "wc"
+ default n
+ help
+ wc is used to print the number of bytes, words, and lines,
+ in specified files.
+
+config FEATURE_WC_LARGE
+ bool "Support very large files in wc"
+ default n
+ depends on WC
+ help
+ Use "unsigned long long" in wc for count variables
+
+config WHO
+ bool "who"
+ default n
+ select FEATURE_UTMP
+ help
+ who is used to show who is logged on.
+
+config WHOAMI
+ bool "whoami"
+ default n
+ help
+ whoami is used to print the username of the current
+ user id (same as id -un).
+
+config YES
+ bool "yes"
+ default n
+ help
+ yes is used to repeatedly output a specific string, or
+ the default string `y'.
+
+comment "Common options for cp and mv"
+ depends on CP || MV
+
+config FEATURE_PRESERVE_HARDLINKS
+ bool "Preserve hard links"
+ default n
+ depends on CP || MV
+ help
+ Allow cp and mv to preserve hard links.
+
+comment "Common options for ls, more and telnet"
+ depends on LS || MORE || TELNET
+
+config FEATURE_AUTOWIDTH
+ bool "Calculate terminal & column widths"
+ default y
+ depends on LS || MORE || TELNET
+ help
+ This option allows utilities such as 'ls', 'more' and 'telnet'
+ to determine the width of the screen, which can allow them to
+ display additional text or avoid wrapping text onto the next line.
+ If you leave this disabled, your utilities will be especially
+ primitive and will be unable to determine the current screen width.
+
+comment "Common options for df, du, ls"
+ depends on DF || DU || LS
+
+config FEATURE_HUMAN_READABLE
+ bool "Support for human readable output (example 13k, 23M, 235G)"
+ default n
+ depends on DF || DU || LS
+ help
+ Allow df, du, and ls to have human readable output.
+
+comment "Common options for md5sum, sha1sum"
+ depends on MD5SUM || SHA1SUM
+
+config FEATURE_MD5_SHA1_SUM_CHECK
+ bool "Enable -c, -s and -w options"
+ default n
+ depends on MD5SUM || SHA1SUM
+ help
+ Enabling the -c options allows files to be checked
+ against pre-calculated hash values.
+
+ -s and -w are useful options when verifying checksums.
+
+endmenu
diff --git a/i/pc104/initrd/conf/busybox/coreutils/Kbuild b/i/pc104/initrd/conf/busybox/coreutils/Kbuild
new file mode 100644
index 0000000..dfdcbd4
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/Kbuild
@@ -0,0 +1,85 @@
+# Makefile for busybox
+#
+# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
+#
+# Licensed under the GPL v2, see the file LICENSE in this tarball.
+
+libs-y += libcoreutils/
+
+lib-y:=
+lib-$(CONFIG_BASENAME) += basename.o
+lib-$(CONFIG_CAL) += cal.o
+lib-$(CONFIG_CAT) += cat.o
+lib-$(CONFIG_MORE) += cat.o # more uses it if stdout isn't a tty
+lib-$(CONFIG_LESS) += cat.o # less too
+lib-$(CONFIG_CATV) += catv.o
+lib-$(CONFIG_CHGRP) += chgrp.o chown.o
+lib-$(CONFIG_CHMOD) += chmod.o
+lib-$(CONFIG_CHOWN) += chown.o
+lib-$(CONFIG_CHROOT) += chroot.o
+lib-$(CONFIG_CKSUM) += cksum.o
+lib-$(CONFIG_CMP) += cmp.o
+lib-$(CONFIG_COMM) += comm.o
+lib-$(CONFIG_CP) += cp.o
+lib-$(CONFIG_CUT) += cut.o
+lib-$(CONFIG_DATE) += date.o
+lib-$(CONFIG_DD) += dd.o
+lib-$(CONFIG_DF) += df.o
+lib-$(CONFIG_DIFF) += diff.o
+lib-$(CONFIG_DIRNAME) += dirname.o
+lib-$(CONFIG_DOS2UNIX) += dos2unix.o
+lib-$(CONFIG_DU) += du.o
+lib-$(CONFIG_ECHO) += echo.o
+lib-$(CONFIG_ASH) += echo.o # used by ash
+lib-$(CONFIG_ENV) += env.o
+lib-$(CONFIG_EXPR) += expr.o
+lib-$(CONFIG_FALSE) += false.o
+lib-$(CONFIG_FOLD) += fold.o
+lib-$(CONFIG_HEAD) += head.o
+lib-$(CONFIG_HOSTID) += hostid.o
+lib-$(CONFIG_ID) += id.o
+lib-$(CONFIG_INSTALL) += install.o
+lib-$(CONFIG_LENGTH) += length.o
+lib-$(CONFIG_LN) += ln.o
+lib-$(CONFIG_LOGNAME) += logname.o
+lib-$(CONFIG_LS) += ls.o
+lib-$(CONFIG_MD5SUM) += md5_sha1_sum.o
+lib-$(CONFIG_MKDIR) += mkdir.o
+lib-$(CONFIG_MKFIFO) += mkfifo.o
+lib-$(CONFIG_MKNOD) += mknod.o
+lib-$(CONFIG_MV) += mv.o
+lib-$(CONFIG_NICE) += nice.o
+lib-$(CONFIG_NOHUP) += nohup.o
+lib-$(CONFIG_OD) += od.o
+lib-$(CONFIG_PRINTENV) += printenv.o
+lib-$(CONFIG_PRINTF) += printf.o
+lib-$(CONFIG_PWD) += pwd.o
+lib-$(CONFIG_REALPATH) += realpath.o
+lib-$(CONFIG_RM) += rm.o
+lib-$(CONFIG_RMDIR) += rmdir.o
+lib-$(CONFIG_SEQ) += seq.o
+lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o
+lib-$(CONFIG_SLEEP) += sleep.o
+lib-$(CONFIG_SORT) += sort.o
+lib-$(CONFIG_STAT) += stat.o
+lib-$(CONFIG_STTY) += stty.o
+lib-$(CONFIG_SUM) += sum.o
+lib-$(CONFIG_SYNC) += sync.o
+lib-$(CONFIG_TAIL) += tail.o
+lib-$(CONFIG_TEE) += tee.o
+lib-$(CONFIG_TEST) += test.o
+lib-$(CONFIG_ASH) += test.o # used by ash
+lib-$(CONFIG_TOUCH) += touch.o
+lib-$(CONFIG_TR) += tr.o
+lib-$(CONFIG_TRUE) += true.o
+lib-$(CONFIG_TTY) += tty.o
+lib-$(CONFIG_UNAME) += uname.o
+lib-$(CONFIG_UNIQ) += uniq.o
+lib-$(CONFIG_USLEEP) += usleep.o
+lib-$(CONFIG_UUDECODE) += uudecode.o
+lib-$(CONFIG_UUENCODE) += uuencode.o
+lib-$(CONFIG_WATCH) += watch.o
+lib-$(CONFIG_WC) += wc.o
+lib-$(CONFIG_WHO) += who.o
+lib-$(CONFIG_WHOAMI) += whoami.o
+lib-$(CONFIG_YES) += yes.o
diff --git a/i/pc104/initrd/conf/busybox/coreutils/basename.c b/i/pc104/initrd/conf/busybox/coreutils/basename.c
new file mode 100644
index 0000000..46f7122
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/basename.c
@@ -0,0 +1,51 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini basename implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/basename.html */
+
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Changes:
+ * 1) Now checks for too many args. Need at least one and at most two.
+ * 2) Don't check for options, as per SUSv3.
+ * 3) Save some space by using strcmp(). Calling strncmp() here was silly.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "busybox.h"
+
+int basename_main(int argc, char **argv);
+int basename_main(int argc, char **argv)
+{
+ size_t m, n;
+ char *s;
+
+ if (((unsigned int)(argc-2)) >= 2) {
+ bb_show_usage();
+ }
+
+ s = bb_get_last_path_component(*++argv);
+
+ if (*++argv) {
+ n = strlen(*argv);
+ m = strlen(s);
+ if ((m > n) && ((strcmp)(s+m-n, *argv) == 0)) {
+ s[m-n] = '\0';
+ }
+ }
+
+ puts(s);
+
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/cal.c b/i/pc104/initrd/conf/busybox/coreutils/cal.c
new file mode 100644
index 0000000..3d61791
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/cal.c
@@ -0,0 +1,352 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Calendar implementation for busybox
+ *
+ * See original copyright at the end of this file
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant with -j and -y extensions (from util-linux). */
+/* BB_AUDIT BUG: The output of 'cal -j 1752' is incorrect. The upstream
+ * BB_AUDIT BUG: version in util-linux seems to be broken as well. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/cal.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Major size reduction... over 50% (>1.5k) on i386.
+ */
+
+#include "busybox.h"
+
+#define THURSDAY 4 /* for reformation */
+#define SATURDAY 6 /* 1 Jan 1 was a Saturday */
+
+#define FIRST_MISSING_DAY 639787 /* 3 Sep 1752 */
+#define NUMBER_MISSING_DAYS 11 /* 11 day correction */
+
+#define MAXDAYS 42 /* max slots in a month array */
+#define SPACE -1 /* used in day array */
+
+static const char days_in_month[] = {
+ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+static const char sep1752[] = {
+ 1, 2, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30
+};
+
+static int julian;
+
+/* leap year -- account for Gregorian reformation in 1752 */
+#define leap_year(yr) \
+ ((yr) <= 1752 ? !((yr) % 4) : \
+ (!((yr) % 4) && ((yr) % 100)) || !((yr) % 400))
+
+static int is_leap_year(int year)
+{
+ return leap_year(year);
+}
+#undef leap_year
+#define leap_year(yr) is_leap_year(yr)
+
+/* number of centuries since 1700, not inclusive */
+#define centuries_since_1700(yr) \
+ ((yr) > 1700 ? (yr) / 100 - 17 : 0)
+
+/* number of centuries since 1700 whose modulo of 400 is 0 */
+#define quad_centuries_since_1700(yr) \
+ ((yr) > 1600 ? ((yr) - 1600) / 400 : 0)
+
+/* number of leap years between year 1 and this year, not inclusive */
+#define leap_years_since_year_1(yr) \
+ ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr))
+
+static void center (char *, int, int);
+static void day_array (int, int, int *);
+static void trim_trailing_spaces_and_print (char *);
+
+static void blank_string(char *buf, size_t buflen);
+static char *build_row(char *p, int *dp);
+
+#define DAY_LEN 3 /* 3 spaces per day */
+#define J_DAY_LEN (DAY_LEN + 1)
+#define WEEK_LEN 20 /* 7 * 3 - one space at the end */
+#define J_WEEK_LEN (WEEK_LEN + 7)
+#define HEAD_SEP 2 /* spaces between day headings */
+
+int cal_main(int argc, char **argv);
+int cal_main(int argc, char **argv)
+{
+ struct tm *local_time;
+ struct tm zero_tm;
+ time_t now;
+ int month, year, flags, i;
+ char *month_names[12];
+ char day_headings[28]; /* 28 for julian, 21 for nonjulian */
+ char buf[40];
+
+ flags = getopt32(argc, argv, "jy");
+
+ julian = flags & 1;
+
+ argv += optind;
+
+ month = 0;
+
+ if ((argc -= optind) > 2) {
+ bb_show_usage();
+ }
+
+ if (!argc) {
+ time(&now);
+ local_time = localtime(&now);
+ year = local_time->tm_year + 1900;
+ if (!(flags & 2)) {
+ month = local_time->tm_mon + 1;
+ }
+ } else {
+ if (argc == 2) {
+ month = xatoul_range(*argv++, 1, 12);
+ }
+ year = xatoul_range(*argv, 1, 9999);
+ }
+
+ blank_string(day_headings, sizeof(day_headings) - 7 + 7*julian);
+
+ i = 0;
+ do {
+ zero_tm.tm_mon = i;
+ strftime(buf, sizeof(buf), "%B", &zero_tm);
+ month_names[i] = xstrdup(buf);
+
+ if (i < 7) {
+ zero_tm.tm_wday = i;
+ strftime(buf, sizeof(buf), "%a", &zero_tm);
+ strncpy(day_headings + i * (3+julian) + julian, buf, 2);
+ }
+ } while (++i < 12);
+
+ if (month) {
+ int row, len, days[MAXDAYS];
+ int *dp = days;
+ char lineout[30];
+
+ day_array(month, year, dp);
+ len = sprintf(lineout, "%s %d", month_names[month - 1], year);
+ printf("%*s%s\n%s\n",
+ ((7*julian + WEEK_LEN) - len) / 2, "",
+ lineout, day_headings);
+ for (row = 0; row < 6; row++) {
+ build_row(lineout, dp)[0] = '\0';
+ dp += 7;
+ trim_trailing_spaces_and_print(lineout);
+ }
+ } else {
+ int row, which_cal, week_len, days[12][MAXDAYS];
+ int *dp;
+ char lineout[80];
+
+ sprintf(lineout, "%d", year);
+ center(lineout,
+ (WEEK_LEN * 3 + HEAD_SEP * 2)
+ + julian * (J_WEEK_LEN * 2 + HEAD_SEP
+ - (WEEK_LEN * 3 + HEAD_SEP * 2)),
+ 0);
+ puts("\n"); /* two \n's */
+ for (i = 0; i < 12; i++) {
+ day_array(i + 1, year, days[i]);
+ }
+ blank_string(lineout, sizeof(lineout));
+ week_len = WEEK_LEN + julian * (J_WEEK_LEN - WEEK_LEN);
+ for (month = 0; month < 12; month += 3-julian) {
+ center(month_names[month], week_len, HEAD_SEP);
+ if (!julian) {
+ center(month_names[month + 1], week_len, HEAD_SEP);
+ }
+ center(month_names[month + 2 - julian], week_len, 0);
+ printf("\n%s%*s%s", day_headings, HEAD_SEP, "", day_headings);
+ if (!julian) {
+ printf("%*s%s", HEAD_SEP, "", day_headings);
+ }
+ putchar('\n');
+ for (row = 0; row < (6*7); row += 7) {
+ for (which_cal = 0; which_cal < 3-julian; which_cal++) {
+ dp = days[month + which_cal] + row;
+ build_row(lineout + which_cal * (week_len + 2), dp);
+ }
+ /* blank_string took care of nul termination. */
+ trim_trailing_spaces_and_print(lineout);
+ }
+ }
+ }
+
+ fflush_stdout_and_exit(0);
+}
+
+/*
+ * day_array --
+ * Fill in an array of 42 integers with a calendar. Assume for a moment
+ * that you took the (maximum) 6 rows in a calendar and stretched them
+ * out end to end. You would have 42 numbers or spaces. This routine
+ * builds that array for any month from Jan. 1 through Dec. 9999.
+ */
+static void day_array(int month, int year, int *days)
+{
+ long temp;
+ int i;
+ int j_offset;
+ int day, dw, dm;
+
+ memset(days, SPACE, MAXDAYS * sizeof(int));
+
+ if ((month == 9) && (year == 1752)) {
+ size_t oday = 0;
+
+ j_offset = julian * 244;
+ do {
+ days[oday+2] = sep1752[oday] + j_offset;
+ } while (++oday < sizeof(sep1752));
+
+ return;
+ }
+
+ /* day_in_year
+ * return the 1 based day number within the year
+ */
+ day = 1;
+ if ((month > 2) && leap_year(year)) {
+ ++day;
+ }
+
+ i = month;
+ while (i) {
+ day += days_in_month[--i];
+ }
+
+ /* day_in_week
+ * return the 0 based day number for any date from 1 Jan. 1 to
+ * 31 Dec. 9999. Assumes the Gregorian reformation eliminates
+ * 3 Sep. 1752 through 13 Sep. 1752. Returns Thursday for all
+ * missing days.
+ */
+ dw = THURSDAY;
+ temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1)
+ + day;
+ if (temp < FIRST_MISSING_DAY) {
+ dw = ((temp - 1 + SATURDAY) % 7);
+ } else if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS)) {
+ dw = (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7);
+ }
+
+ if (!julian) {
+ day = 1;
+ }
+
+ dm = days_in_month[month];
+ if ((month == 2) && leap_year(year)) {
+ ++dm;
+ }
+
+ while (dm) {
+ days[dw++] = day++;
+ --dm;
+ }
+}
+
+static void trim_trailing_spaces_and_print(char *s)
+{
+ char *p = s;
+
+ while (*p) {
+ ++p;
+ }
+ while (p > s) {
+ --p;
+ if (!(isspace)(*p)) { /* We want the function... not the inline. */
+ p[1] = '\0';
+ break;
+ }
+ }
+
+ puts(s);
+}
+
+static void center(char *str, int len, int separate)
+{
+ int n = strlen(str);
+ len -= n;
+ printf("%*s%*s", (len/2) + n, str, (len/2) + (len % 2) + separate, "");
+}
+
+static void blank_string(char *buf, size_t buflen)
+{
+ memset(buf, ' ', buflen);
+ buf[buflen-1] = '\0';
+}
+
+static char *build_row(char *p, int *dp)
+{
+ int col, val, day;
+
+ memset(p, ' ', (julian + DAY_LEN) * 7);
+
+ col = 0;
+ do {
+ if ((day = *dp++) != SPACE) {
+ if (julian) {
+ ++p;
+ if (day >= 100) {
+ *p = '0';
+ p[-1] = (day / 100) + '0';
+ day %= 100;
+ }
+ }
+ if ((val = day / 10) > 0) {
+ *p = val + '0';
+ }
+ *++p = day % 10 + '0';
+ p += 2;
+ } else {
+ p += DAY_LEN + julian;
+ }
+ } while (++col < 7);
+
+ return p;
+}
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Kim Letkeman.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
diff --git a/i/pc104/initrd/conf/busybox/coreutils/cat.c b/i/pc104/initrd/conf/busybox/coreutils/cat.c
new file mode 100644
index 0000000..7bab325
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/cat.c
@@ -0,0 +1,43 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * cat implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2, see file License in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/cat.html */
+
+#include "busybox.h"
+
+int bb_cat(char **argv)
+{
+ static const char *const argv_dash[] = { "-", NULL };
+ FILE *f;
+ int retval = EXIT_SUCCESS;
+
+ if (!*argv) argv = (char**) &argv_dash;
+
+ do {
+ f = fopen_or_warn_stdin(*argv);
+ if (f) {
+ off_t r = bb_copyfd_eof(fileno(f), STDOUT_FILENO);
+ fclose_if_not_stdin(f);
+ if (r >= 0)
+ continue;
+ }
+ retval = EXIT_FAILURE;
+ } while (*++argv);
+
+ return retval;
+}
+
+int cat_main(int argc, char **argv);
+int cat_main(int argc, char **argv)
+{
+ getopt32(argc, argv, "u");
+ argv += optind;
+ return bb_cat(argv);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/catv.c b/i/pc104/initrd/conf/busybox/coreutils/catv.c
new file mode 100644
index 0000000..826e0e9
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/catv.c
@@ -0,0 +1,70 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * cat -v implementation for busybox
+ *
+ * Copyright (C) 2006 Rob Landley <rob@landley.net>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* See "Cat -v considered harmful" at
+ * http://cm.bell-labs.com/cm/cs/doc/84/kp.ps.gz */
+
+#include "busybox.h"
+
+int catv_main(int argc, char **argv);
+int catv_main(int argc, char **argv)
+{
+ int retval = EXIT_SUCCESS, fd;
+ unsigned flags;
+
+ flags = getopt32(argc, argv, "etv");
+#define CATV_OPT_e (1<<0)
+#define CATV_OPT_t (1<<1)
+#define CATV_OPT_v (1<<2)
+ flags ^= CATV_OPT_v;
+
+ argv += optind;
+ do {
+ /* Read from stdin if there's nothing else to do. */
+ fd = 0;
+ if (*argv && 0 > (fd = xopen(*argv, O_RDONLY)))
+ retval = EXIT_FAILURE;
+ else for (;;) {
+ int i, res;
+
+ res = read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1));
+ if (res < 0)
+ retval = EXIT_FAILURE;
+ if (res < 1)
+ break;
+ for (i = 0; i < res; i++) {
+ char c = bb_common_bufsiz1[i];
+
+ if (c > 126 && (flags & CATV_OPT_v)) {
+ if (c == 127) {
+ printf("^?");
+ continue;
+ } else {
+ printf("M-");
+ c -= 128;
+ }
+ }
+ if (c < 32) {
+ if (c == 10) {
+ if (flags & CATV_OPT_e)
+ putchar('$');
+ } else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) {
+ printf("^%c", c+'@');
+ continue;
+ }
+ }
+ putchar(c);
+ }
+ }
+ if (ENABLE_FEATURE_CLEAN_UP && fd)
+ close(fd);
+ } while (*++argv);
+
+ fflush_stdout_and_exit(retval);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/chgrp.c b/i/pc104/initrd/conf/busybox/coreutils/chgrp.c
new file mode 100644
index 0000000..cfb8c15
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/chgrp.c
@@ -0,0 +1,28 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini chgrp implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 defects - none? */
+/* BB_AUDIT GNU defects - unsupported long options. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/chgrp.html */
+
+#include "busybox.h"
+
+int chgrp_main(int argc, char **argv);
+int chgrp_main(int argc, char **argv)
+{
+ /* "chgrp [opts] abc file(s)" == "chown [opts] :abc file(s)" */
+ char **p = argv;
+ while (*++p) {
+ if (p[0][0] != '-') {
+ p[0] = xasprintf(":%s", p[0]);
+ break;
+ }
+ }
+ return chown_main(argc, argv);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/chmod.c b/i/pc104/initrd/conf/busybox/coreutils/chmod.c
new file mode 100644
index 0000000..11c6731
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/chmod.c
@@ -0,0 +1,159 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini chmod implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Reworked by (C) 2002 Vladimir Oleynik <dzo@simtreas.ru>
+ * to correctly parse '-rwxgoa'
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* BB_AUDIT GNU defects - unsupported long options. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
+
+#include "busybox.h"
+
+#define OPT_RECURSE (option_mask32 & 1)
+#define OPT_VERBOSE (USE_DESKTOP(option_mask32 & 2) SKIP_DESKTOP(0))
+#define OPT_CHANGED (USE_DESKTOP(option_mask32 & 4) SKIP_DESKTOP(0))
+#define OPT_QUIET (USE_DESKTOP(option_mask32 & 8) SKIP_DESKTOP(0))
+#define OPT_STR "R" USE_DESKTOP("vcf")
+
+/* coreutils:
+ * chmod never changes the permissions of symbolic links; the chmod
+ * system call cannot change their permissions. This is not a problem
+ * since the permissions of symbolic links are never used.
+ * However, for each symbolic link listed on the command line, chmod changes
+ * the permissions of the pointed-to file. In contrast, chmod ignores
+ * symbolic links encountered during recursive directory traversals.
+ */
+
+static int fileAction(const char *fileName, struct stat *statbuf, void* param, int depth)
+{
+ mode_t newmode;
+
+ /* match coreutils behavior */
+ if (depth == 0) {
+ /* statbuf holds lstat result, but we need stat (follow link) */
+ if (stat(fileName, statbuf))
+ goto err;
+ } else { /* depth > 0: skip links */
+ if (S_ISLNK(statbuf->st_mode))
+ return TRUE;
+ }
+ newmode = statbuf->st_mode;
+
+ if (!bb_parse_mode((char *)param, &newmode))
+ bb_error_msg_and_die("invalid mode: %s", (char *)param);
+
+ if (chmod(fileName, newmode) == 0) {
+ if (OPT_VERBOSE
+ || (OPT_CHANGED && statbuf->st_mode != newmode)
+ ) {
+ printf("mode of '%s' changed to %04o (%s)\n", fileName,
+ newmode & 07777, bb_mode_string(newmode)+1);
+ }
+ return TRUE;
+ }
+ err:
+ if (!OPT_QUIET)
+ bb_perror_msg("%s", fileName);
+ return FALSE;
+}
+
+int chmod_main(int argc, char **argv);
+int chmod_main(int argc, char **argv)
+{
+ int retval = EXIT_SUCCESS;
+ char *arg, **argp;
+ char *smode;
+
+ /* Convert first encountered -r into ar, -w into aw etc
+ * so that getopt would not eat it */
+ argp = argv;
+ while ((arg = *++argp)) {
+ /* Mode spec must be the first arg (sans -R etc) */
+ /* (protect against mishandling e.g. "chmod 644 -r") */
+ if (arg[0] != '-') {
+ arg = NULL;
+ break;
+ }
+ /* An option. Not a -- or valid option? */
+ if (arg[1] && !strchr("-"OPT_STR, arg[1])) {
+ arg[0] = 'a';
+ break;
+ }
+ }
+
+ /* Parse options */
+ opt_complementary = "-2";
+ getopt32(argc, argv, ("-"OPT_STR) + 1); /* Reuse string */
+ argv += optind;
+
+ /* Restore option-like mode if needed */
+ if (arg) arg[0] = '-';
+
+ /* Ok, ready to do the deed now */
+ smode = *argv++;
+ do {
+ if (!recursive_action(*argv,
+ OPT_RECURSE, // recurse
+ FALSE, // follow links: coreutils doesn't
+ FALSE, // depth first
+ fileAction, // file action
+ fileAction, // dir action
+ smode, // user data
+ 0) // depth
+ ) {
+ retval = EXIT_FAILURE;
+ }
+ } while (*++argv);
+
+ return retval;
+}
+
+/*
+Security: chmod is too important and too subtle.
+This is a test script (busybox chmod versus coreutils).
+Run it in empty directory.
+
+#!/bin/sh
+t1="/tmp/busybox chmod"
+t2="/usr/bin/chmod"
+create() {
+ rm -rf $1; mkdir $1
+ (
+ cd $1 || exit 1
+ mkdir dir
+ >up
+ >file
+ >dir/file
+ ln -s dir linkdir
+ ln -s file linkfile
+ ln -s ../up dir/up
+ )
+}
+tst() {
+ (cd test1; $t1 $1)
+ (cd test2; $t2 $1)
+ (cd test1; ls -lR) >out1
+ (cd test2; ls -lR) >out2
+ echo "chmod $1" >out.diff
+ if ! diff -u out1 out2 >>out.diff; then exit 1; fi
+ rm out.diff
+}
+echo "If script produced 'out.diff' file, then at least one testcase failed"
+create test1; create test2
+tst "a+w file"
+tst "a-w dir"
+tst "a+w linkfile"
+tst "a-w linkdir"
+tst "-R a+w file"
+tst "-R a-w dir"
+tst "-R a+w linkfile"
+tst "-R a-w linkdir"
+tst "a-r,a+x linkfile"
+*/
diff --git a/i/pc104/initrd/conf/busybox/coreutils/chown.c b/i/pc104/initrd/conf/busybox/coreutils/chown.c
new file mode 100644
index 0000000..f92299e
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/chown.c
@@ -0,0 +1,167 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini chown implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 defects - none? */
+/* BB_AUDIT GNU defects - unsupported long options. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */
+
+#include "busybox.h"
+
+#define OPT_STR ("Rh" USE_DESKTOP("vcfLHP"))
+#define BIT_RECURSE 1
+#define OPT_RECURSE (option_mask32 & 1)
+#define OPT_NODEREF (option_mask32 & 2)
+#define OPT_VERBOSE (USE_DESKTOP(option_mask32 & 0x04) SKIP_DESKTOP(0))
+#define OPT_CHANGED (USE_DESKTOP(option_mask32 & 0x08) SKIP_DESKTOP(0))
+#define OPT_QUIET (USE_DESKTOP(option_mask32 & 0x10) SKIP_DESKTOP(0))
+/* POSIX options
+ * -L traverse every symbolic link to a directory encountered
+ * -H if a command line argument is a symbolic link to a directory, traverse it
+ * -P do not traverse any symbolic links (default)
+ * We do not conform to the following:
+ * "Specifying more than one of -H, -L, and -P is not an error.
+ * The last option specified shall determine the behavior of the utility." */
+/* -L */
+#define BIT_TRAVERSE 0x20
+#define OPT_TRAVERSE (USE_DESKTOP(option_mask32 & BIT_TRAVERSE) SKIP_DESKTOP(0))
+/* -H or -L */
+#define BIT_TRAVERSE_TOP (0x20|0x40)
+#define OPT_TRAVERSE_TOP (USE_DESKTOP(option_mask32 & BIT_TRAVERSE_TOP) SKIP_DESKTOP(0))
+
+typedef int (*chown_fptr)(const char *, uid_t, gid_t);
+
+static struct bb_uidgid_t ugid = { -1, -1 };
+
+static int fileAction(const char *fileName, struct stat *statbuf,
+ void *cf, int depth)
+{
+ uid_t u = (ugid.uid == (uid_t)-1) ? statbuf->st_uid : ugid.uid;
+ gid_t g = (ugid.gid == (gid_t)-1) ? statbuf->st_gid : ugid.gid;
+
+ if (!((chown_fptr)cf)(fileName, u, g)) {
+ if (OPT_VERBOSE
+ || (OPT_CHANGED && (statbuf->st_uid != u || statbuf->st_gid != g))
+ ) {
+ printf("changed ownership of '%s' to %u:%u\n",
+ fileName, (unsigned)u, (unsigned)g);
+ }
+ return TRUE;
+ }
+ if (!OPT_QUIET)
+ bb_perror_msg("%s", fileName); /* A filename can have % in it... */
+ return FALSE;
+}
+
+int chown_main(int argc, char **argv);
+int chown_main(int argc, char **argv)
+{
+ int retval = EXIT_SUCCESS;
+ chown_fptr chown_func;
+
+ opt_complementary = "-2";
+ getopt32(argc, argv, OPT_STR);
+ argv += optind;
+
+ /* This matches coreutils behavior (almost - see below) */
+ chown_func = chown;
+ if (OPT_NODEREF
+ /* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */
+ USE_DESKTOP( || (option_mask32 & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE)
+ ) {
+ chown_func = lchown;
+ }
+
+ parse_chown_usergroup_or_die(&ugid, argv[0]);
+
+ /* Ok, ready to do the deed now */
+ argv++;
+ do {
+ char *arg = *argv;
+
+ if (OPT_TRAVERSE_TOP) {
+ /* resolves symlink (even recursive) */
+ arg = xmalloc_realpath(arg);
+ if (!arg)
+ continue;
+ }
+
+ if (!recursive_action(arg,
+ OPT_RECURSE, // recurse
+ OPT_TRAVERSE, // follow links if -L
+ FALSE, // depth first
+ fileAction, // file action
+ fileAction, // dir action
+ chown_func, // user data
+ 0) // depth
+ ) {
+ retval = EXIT_FAILURE;
+ }
+
+ if (OPT_TRAVERSE_TOP)
+ free(arg);
+ } while (*++argv);
+
+ return retval;
+}
+
+/*
+Testcase. Run in empty directory.
+
+#!/bin/sh
+t1="/tmp/busybox chown"
+t2="/usr/bin/chown"
+create() {
+ rm -rf $1; mkdir $1
+ (
+ cd $1 || exit 1
+ mkdir dir dir2
+ >up
+ >file
+ >dir/file
+ >dir2/file
+ ln -s dir linkdir
+ ln -s file linkfile
+ ln -s ../up dir/linkup
+ ln -s ../dir2 dir/linkupdir2
+ )
+ chown -R 0:0 $1
+}
+tst() {
+ create test1
+ create test2
+ (cd test1; $t1 $1)
+ (cd test2; $t2 $1)
+ (cd test1; ls -lnR) >out1
+ (cd test2; ls -lnR) >out2
+ echo "chown $1" >out.diff
+ if ! diff -u out1 out2 >>out.diff; then exit 1; fi
+ rm out.diff
+}
+tst_for_each() {
+ tst "$1 1:1 file"
+ tst "$1 1:1 dir"
+ tst "$1 1:1 linkdir"
+ tst "$1 1:1 linkfile"
+}
+echo "If script produced 'out.diff' file, then at least one testcase failed"
+# These match coreutils 6.8:
+tst_for_each ""
+tst_for_each "-R"
+tst_for_each "-RP"
+tst_for_each "-RL"
+tst_for_each "-RH"
+tst_for_each "-h"
+tst_for_each "-hR"
+tst_for_each "-hRP"
+# Below: with "chown linkdir" coreutils 6.8 will chown linkdir _target_,
+# we lchown _the link_. I believe we are "more correct".
+#tst_for_each "-hRL"
+#tst_for_each "-hRH"
+
+*/
diff --git a/i/pc104/initrd/conf/busybox/coreutils/chroot.c b/i/pc104/initrd/conf/busybox/coreutils/chroot.c
new file mode 100644
index 0000000..fcd70f2
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/chroot.c
@@ -0,0 +1,38 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini chroot implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
+
+#include "busybox.h"
+
+int chroot_main(int argc, char **argv);
+int chroot_main(int argc, char **argv)
+{
+ if (argc < 2) {
+ bb_show_usage();
+ }
+
+ ++argv;
+ if (chroot(*argv)) {
+ bb_perror_msg_and_die("cannot change root directory to %s", *argv);
+ }
+ xchdir("/");
+
+ ++argv;
+ if (argc == 2) {
+ argv -= 2;
+ if (!(*argv = getenv("SHELL"))) {
+ *argv = (char *) DEFAULT_SHELL;
+ }
+ argv[1] = (char *) "-i";
+ }
+
+ BB_EXECVP(*argv, argv);
+ bb_perror_msg_and_die("cannot execute %s", *argv);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/cksum.c b/i/pc104/initrd/conf/busybox/coreutils/cksum.c
new file mode 100644
index 0000000..66a255c
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/cksum.c
@@ -0,0 +1,54 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * cksum - calculate the CRC32 checksum of a file
+ *
+ * Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */
+
+#include "busybox.h"
+
+int cksum_main(int argc, char **argv);
+int cksum_main(int argc, char **argv)
+{
+
+ uint32_t *crc32_table = crc32_filltable(1);
+
+ FILE *fp;
+ uint32_t crc;
+ long length, filesize;
+ int bytes_read;
+ char *cp;
+
+ int inp_stdin = (argc == optind) ? 1 : 0;
+
+ do {
+ fp = fopen_or_warn_stdin((inp_stdin) ? bb_msg_standard_input : *++argv);
+
+ crc = 0;
+ length = 0;
+
+ while ((bytes_read = fread(bb_common_bufsiz1, 1, BUFSIZ, fp)) > 0) {
+ cp = bb_common_bufsiz1;
+ length += bytes_read;
+ while (bytes_read--)
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL];
+ }
+
+ filesize = length;
+
+ for (; length; length >>= 8)
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL];
+ crc ^= 0xffffffffL;
+
+ if (inp_stdin) {
+ printf("%" PRIu32 " %li\n", crc, filesize);
+ break;
+ }
+
+ printf("%" PRIu32 " %li %s\n", crc, filesize, *argv);
+ fclose(fp);
+ } while (*(argv + 1));
+
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/cmp.c b/i/pc104/initrd/conf/busybox/coreutils/cmp.c
new file mode 100644
index 0000000..cff1182
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/cmp.c
@@ -0,0 +1,145 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini cmp implementation for busybox
+ *
+ * Copyright (C) 2000,2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 (virtually) compliant -- uses nicer GNU format for -l. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/cmp.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Original version majorly reworked for SUSv3 compliance, bug fixes, and
+ * size optimizations. Changes include:
+ * 1) Now correctly distinguishes between errors and actual file differences.
+ * 2) Proper handling of '-' args.
+ * 3) Actual error checking of i/o.
+ * 4) Accept SUSv3 -l option. Note that we use the slightly nicer gnu format
+ * in the '-l' case.
+ */
+
+#include "busybox.h"
+
+static FILE *cmp_xfopen_input(const char * const filename)
+{
+ FILE *fp;
+
+ fp = fopen_or_warn_stdin(filename);
+ if (fp)
+ return fp;
+ exit(xfunc_error_retval); /* We already output an error message. */
+}
+
+static const char fmt_eof[] = "cmp: EOF on %s\n";
+static const char fmt_differ[] = "%s %s differ: char %"OFF_FMT"d, line %d\n";
+// This fmt_l_opt uses gnu-isms. SUSv3 would be "%.0s%.0s%"OFF_FMT"d %o %o\n"
+static const char fmt_l_opt[] = "%.0s%.0s%"OFF_FMT"d %3o %3o\n";
+
+static const char opt_chars[] = "sl";
+#define CMP_OPT_s (1<<0)
+#define CMP_OPT_l (1<<1)
+
+int cmp_main(int argc, char **argv);
+int cmp_main(int argc, char **argv)
+{
+ FILE *fp1, *fp2, *outfile = stdout;
+ const char *filename1, *filename2 = "-";
+ USE_DESKTOP(off_t skip1 = 0, skip2 = 0;)
+ off_t char_pos = 0;
+ int line_pos = 1; /* Hopefully won't overflow... */
+ const char *fmt;
+ int c1, c2;
+ unsigned opt;
+ int retval = 0;
+
+ xfunc_error_retval = 2; /* 1 is returned if files are different. */
+
+ opt_complementary = "?:-1"
+ USE_DESKTOP(":?4")
+ SKIP_DESKTOP(":?2")
+ ":l--s:s--l";
+ opt = getopt32(argc, argv, opt_chars);
+ argv += optind;
+
+ filename1 = *argv;
+ fp1 = cmp_xfopen_input(filename1);
+
+ if (*++argv) {
+ filename2 = *argv;
+#if ENABLE_DESKTOP
+ if (*++argv) {
+ skip1 = XATOOFF(*argv);
+ if (*++argv) {
+ skip2 = XATOOFF(*argv);
+ }
+ }
+#endif
+ }
+
+ fp2 = cmp_xfopen_input(filename2);
+ if (fp1 == fp2) { /* Paranoia check... stdin == stdin? */
+ /* Note that we don't bother reading stdin. Neither does gnu wc.
+ * But perhaps we should, so that other apps down the chain don't
+ * get the input. Consider 'echo hello | (cmp - - && cat -)'.
+ */
+ return 0;
+ }
+
+ if (opt & CMP_OPT_l)
+ fmt = fmt_l_opt;
+ else
+ fmt = fmt_differ;
+
+#if ENABLE_DESKTOP
+ while (skip1) { getc(fp1); skip1--; }
+ while (skip2) { getc(fp2); skip2--; }
+#endif
+ do {
+ c1 = getc(fp1);
+ c2 = getc(fp2);
+ ++char_pos;
+ if (c1 != c2) { /* Remember: a read error may have occurred. */
+ retval = 1; /* But assume the files are different for now. */
+ if (c2 == EOF) {
+ /* We know that fp1 isn't at EOF or in an error state. But to
+ * save space below, things are setup to expect an EOF in fp1
+ * if an EOF occurred. So, swap things around.
+ */
+ fp1 = fp2;
+ filename1 = filename2;
+ c1 = c2;
+ }
+ if (c1 == EOF) {
+ die_if_ferror(fp1, filename1);
+ fmt = fmt_eof; /* Well, no error, so it must really be EOF. */
+ outfile = stderr;
+ /* There may have been output to stdout (option -l), so
+ * make sure we fflush before writing to stderr. */
+ xfflush_stdout();
+ }
+ if (!(opt & CMP_OPT_s)) {
+ if (opt & CMP_OPT_l) {
+ line_pos = c1; /* line_pos is unused in the -l case. */
+ }
+ fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2);
+ if (opt) { /* This must be -l since not -s. */
+ /* If we encountered an EOF,
+ * the while check will catch it. */
+ continue;
+ }
+ }
+ break;
+ }
+ if (c1 == '\n') {
+ ++line_pos;
+ }
+ } while (c1 != EOF);
+
+ die_if_ferror(fp1, filename1);
+ die_if_ferror(fp2, filename2);
+
+ fflush_stdout_and_exit(retval);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/comm.c b/i/pc104/initrd/conf/busybox/coreutils/comm.c
new file mode 100644
index 0000000..b641296
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/comm.c
@@ -0,0 +1,127 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini comm implementation for busybox
+ *
+ * Copyright (C) 2005 by Robert Sullivan <cogito.ergo.cogito@gmail.com>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+
+#define COMM_OPT_1 0x01
+#define COMM_OPT_2 0x02
+#define COMM_OPT_3 0x04
+
+/* These three variables control behaviour if non-zero */
+
+static int only_file_1;
+static int only_file_2;
+static int both;
+
+/* writeline outputs the input given, appropriately aligned according to class */
+static void writeline(char *line, int class)
+{
+ if (class == 0) {
+ if (!only_file_1)
+ return;
+ } else if (class == 1) {
+ if (!only_file_2)
+ return;
+ if (only_file_1)
+ putchar('\t');
+ }
+ else /*if (class == 2)*/ {
+ if (!both)
+ return;
+ if (only_file_1)
+ putchar('\t');
+ if (only_file_2)
+ putchar('\t');
+ }
+ fputs(line, stdout);
+}
+
+/* This is the real core of the program - lines are compared here */
+static void cmp_files(char **infiles)
+{
+#define LINE_LEN 100
+#define BB_EOF_0 0x1
+#define BB_EOF_1 0x2
+ char thisline[2][LINE_LEN];
+ FILE *streams[2];
+ int i;
+
+ for (i = 0; i < 2; ++i) {
+ streams[i] = ((infiles[i][0] == '=' && infiles[i][1]) ? stdin : xfopen(infiles[i], "r"));
+ fgets(thisline[i], LINE_LEN, streams[i]);
+ }
+
+ while (*thisline[0] || *thisline[1]) {
+ int order = 0;
+
+ i = 0;
+ if (feof(streams[0])) i |= BB_EOF_0;
+ if (feof(streams[1])) i |= BB_EOF_1;
+
+ if (!*thisline[0])
+ order = 1;
+ else if (!*thisline[1])
+ order = -1;
+ else {
+ int tl0_len, tl1_len;
+ tl0_len = strlen(thisline[0]);
+ tl1_len = strlen(thisline[1]);
+ order = memcmp(thisline[0], thisline[1], tl0_len < tl1_len ? tl0_len : tl1_len);
+ if (!order)
+ order = tl0_len < tl1_len ? -1 : tl0_len != tl1_len;
+ }
+
+ if (order == 0 && !i)
+ writeline(thisline[1], 2);
+ else if (order > 0 && !(i & BB_EOF_1))
+ writeline(thisline[1], 1);
+ else if (order < 0 && !(i & BB_EOF_0))
+ writeline(thisline[0], 0);
+
+ if (i & BB_EOF_0 & BB_EOF_1) {
+ break;
+
+ } else if (i) {
+ i = (i & BB_EOF_0 ? 1 : 0);
+ while (!feof(streams[i])) {
+ if ((order < 0 && i) || (order > 0 && !i))
+ writeline(thisline[i], i);
+ fgets(thisline[i], LINE_LEN, streams[i]);
+ }
+ break;
+
+ } else {
+ if (order >= 0)
+ fgets(thisline[1], LINE_LEN, streams[1]);
+ if (order <= 0)
+ fgets(thisline[0], LINE_LEN, streams[0]);
+ }
+ }
+
+ fclose(streams[0]);
+ fclose(streams[1]);
+}
+
+int comm_main(int argc, char **argv);
+int comm_main(int argc, char **argv)
+{
+ unsigned long flags;
+
+ flags = getopt32(argc, argv, "123");
+
+ if (optind + 2 != argc)
+ bb_show_usage();
+
+ only_file_1 = !(flags & COMM_OPT_1);
+ only_file_2 = !(flags & COMM_OPT_2);
+ both = !(flags & COMM_OPT_3);
+
+ cmp_files(argv + optind);
+ exit(EXIT_SUCCESS);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/cp.c b/i/pc104/initrd/conf/busybox/coreutils/cp.c
new file mode 100644
index 0000000..a80e0d2
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/cp.c
@@ -0,0 +1,100 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini cp implementation for busybox
+ *
+ * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
+ * SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp>
+ *
+ * Licensed under GPL v2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Size reduction.
+ */
+
+#include "busybox.h"
+#include "libcoreutils/coreutils.h"
+
+int cp_main(int argc, char **argv);
+int cp_main(int argc, char **argv)
+{
+ struct stat source_stat;
+ struct stat dest_stat;
+ const char *last;
+ const char *dest;
+ int s_flags;
+ int d_flags;
+ int flags;
+ int status = 0;
+ enum {
+ OPT_a = 1 << (sizeof(FILEUTILS_CP_OPTSTR)-1),
+ OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)),
+ OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1),
+ OPT_H = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2),
+ OPT_L = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3),
+ };
+
+ // Soft- and hardlinking don't mix
+ // -P and -d are the same (-P is POSIX, -d is GNU)
+ // -r and -R are the same
+ // -a = -pdR
+ opt_complementary = "?:l--s:s--l:Pd:rR:apdR";
+ flags = getopt32(argc, argv, FILEUTILS_CP_OPTSTR "arPHL");
+ /* Default behavior of cp is to dereference, so we don't have to do
+ * anything special when we are given -L.
+ * The behavior of -H is *almost* like -L, but not quite, so let's
+ * just ignore it too for fun.
+ if (flags & OPT_L) ...
+ if (flags & OPT_H) ... // deref command-line params only
+ */
+
+#if ENABLE_SELINUX
+ if (flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) {
+ selinux_or_die();
+ }
+#endif
+
+ flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */
+
+ if (optind + 2 > argc) {
+ bb_show_usage();
+ }
+
+ last = argv[argc - 1];
+ argv += optind;
+
+ /* If there are only two arguments and... */
+ if (optind + 2 == argc) {
+ s_flags = cp_mv_stat2(*argv, &source_stat,
+ (flags & FILEUTILS_DEREFERENCE) ? stat : lstat);
+ if (s_flags < 0)
+ return EXIT_FAILURE;
+ d_flags = cp_mv_stat(last, &dest_stat);
+ if (d_flags < 0)
+ return EXIT_FAILURE;
+
+ /* ...if neither is a directory or... */
+ if ( !((s_flags | d_flags) & 2) ||
+ /* ...recursing, the 1st is a directory, and the 2nd doesn't exist... */
+ ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags)
+ ) {
+ /* ...do a simple copy. */
+ dest = xstrdup(last);
+ goto DO_COPY; /* Note: optind+2==argc implies argv[1]==last below. */
+ }
+ }
+
+ do {
+ dest = concat_path_file(last, bb_get_last_path_component(*argv));
+ DO_COPY:
+ if (copy_file(*argv, dest, flags) < 0) {
+ status = 1;
+ }
+ free((void*)dest);
+ } while (*++argv != last);
+
+ return status;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/cut.c b/i/pc104/initrd/conf/busybox/coreutils/cut.c
new file mode 100644
index 0000000..22014fc
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/cut.c
@@ -0,0 +1,287 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * cut.c - minimalist version of cut
+ *
+ * Copyright (C) 1999,2000,2001 by Lineo, inc.
+ * Written by Mark Whitley <markw@codepoet.org>
+ * debloated by Bernhard Fischer
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+
+/* option vars */
+static const char optstring[] = "b:c:f:d:sn";
+#define CUT_OPT_BYTE_FLGS (1<<0)
+#define CUT_OPT_CHAR_FLGS (1<<1)
+#define CUT_OPT_FIELDS_FLGS (1<<2)
+#define CUT_OPT_DELIM_FLGS (1<<3)
+#define CUT_OPT_SUPPRESS_FLGS (1<<4)
+
+static char delim = '\t'; /* delimiter, default is tab */
+
+struct cut_list {
+ int startpos;
+ int endpos;
+};
+
+enum {
+ BOL = 0,
+ EOL = INT_MAX,
+ NON_RANGE = -1
+};
+
+/* growable array holding a series of lists */
+static struct cut_list *cut_lists;
+static unsigned int nlists; /* number of elements in above list */
+
+
+static int cmpfunc(const void *a, const void *b)
+{
+ return (((struct cut_list *) a)->startpos -
+ ((struct cut_list *) b)->startpos);
+
+}
+
+static void cut_file(FILE * file)
+{
+ char *line = NULL;
+ unsigned int linenum = 0; /* keep these zero-based to be consistent */
+
+ /* go through every line in the file */
+ while ((line = xmalloc_getline(file)) != NULL) {
+
+ /* set up a list so we can keep track of what's been printed */
+ char * printed = xzalloc(strlen(line) * sizeof(char));
+ char * orig_line = line;
+ unsigned int cl_pos = 0;
+ int spos;
+
+ /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */
+ if (option_mask32 & (CUT_OPT_CHAR_FLGS | CUT_OPT_BYTE_FLGS)) {
+ /* print the chars specified in each cut list */
+ for (; cl_pos < nlists; cl_pos++) {
+ spos = cut_lists[cl_pos].startpos;
+ while (spos < strlen(line)) {
+ if (!printed[spos]) {
+ printed[spos] = 'X';
+ putchar(line[spos]);
+ }
+ spos++;
+ if (spos > cut_lists[cl_pos].endpos
+ || cut_lists[cl_pos].endpos == NON_RANGE)
+ break;
+ }
+ }
+ } else if (delim == '\n') { /* cut by lines */
+ spos = cut_lists[cl_pos].startpos;
+
+ /* get out if we have no more lists to process or if the lines
+ * are lower than what we're interested in */
+ if (linenum < spos || cl_pos >= nlists)
+ goto next_line;
+
+ /* if the line we're looking for is lower than the one we were
+ * passed, it means we displayed it already, so move on */
+ while (spos < linenum) {
+ spos++;
+ /* go to the next list if we're at the end of this one */
+ if (spos > cut_lists[cl_pos].endpos
+ || cut_lists[cl_pos].endpos == NON_RANGE) {
+ cl_pos++;
+ /* get out if there's no more lists to process */
+ if (cl_pos >= nlists)
+ goto next_line;
+ spos = cut_lists[cl_pos].startpos;
+ /* get out if the current line is lower than the one
+ * we just became interested in */
+ if (linenum < spos)
+ goto next_line;
+ }
+ }
+
+ /* If we made it here, it means we've found the line we're
+ * looking for, so print it */
+ puts(line);
+ goto next_line;
+ } else { /* cut by fields */
+ int ndelim = -1; /* zero-based / one-based problem */
+ int nfields_printed = 0;
+ char *field = NULL;
+ const char delimiter[2] = { delim, 0 };
+
+ /* does this line contain any delimiters? */
+ if (strchr(line, delim) == NULL) {
+ if (!(option_mask32 & CUT_OPT_SUPPRESS_FLGS))
+ puts(line);
+ goto next_line;
+ }
+
+ /* process each list on this line, for as long as we've got
+ * a line to process */
+ for (; cl_pos < nlists && line; cl_pos++) {
+ spos = cut_lists[cl_pos].startpos;
+ do {
+ /* find the field we're looking for */
+ while (line && ndelim < spos) {
+ field = strsep(&line, delimiter);
+ ndelim++;
+ }
+
+ /* we found it, and it hasn't been printed yet */
+ if (field && ndelim == spos && !printed[ndelim]) {
+ /* if this isn't our first time through, we need to
+ * print the delimiter after the last field that was
+ * printed */
+ if (nfields_printed > 0)
+ putchar(delim);
+ fputs(field, stdout);
+ printed[ndelim] = 'X';
+ nfields_printed++; /* shouldn't overflow.. */
+ }
+
+ spos++;
+
+ /* keep going as long as we have a line to work with,
+ * this is a list, and we're not at the end of that
+ * list */
+ } while (spos <= cut_lists[cl_pos].endpos && line
+ && cut_lists[cl_pos].endpos != NON_RANGE);
+ }
+ }
+ /* if we printed anything at all, we need to finish it with a
+ * newline cuz we were handed a chomped line */
+ putchar('\n');
+ next_line:
+ linenum++;
+ free(printed);
+ free(orig_line);
+ }
+}
+
+static const char _op_on_field[] = " only when operating on fields";
+
+int cut_main(int argc, char **argv);
+int cut_main(int argc, char **argv)
+{
+ char *sopt, *ltok;
+
+ opt_complementary = "b--bcf:c--bcf:f--bcf";
+ getopt32(argc, argv, optstring, &sopt, &sopt, &sopt, &ltok);
+// argc -= optind;
+ argv += optind;
+ if (!(option_mask32 & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS)))
+ bb_error_msg_and_die("expected a list of bytes, characters, or fields");
+ if (option_mask32 & BB_GETOPT_ERROR)
+ bb_error_msg_and_die("only one type of list may be specified");
+
+ if (option_mask32 & CUT_OPT_DELIM_FLGS) {
+ if (strlen(ltok) > 1) {
+ bb_error_msg_and_die("the delimiter must be a single character");
+ }
+ delim = ltok[0];
+ }
+
+ /* non-field (char or byte) cutting has some special handling */
+ if (!(option_mask32 & CUT_OPT_FIELDS_FLGS)) {
+ if (option_mask32 & CUT_OPT_SUPPRESS_FLGS) {
+ bb_error_msg_and_die
+ ("suppressing non-delimited lines makes sense%s",
+ _op_on_field);
+ }
+ if (delim != '\t') {
+ bb_error_msg_and_die
+ ("a delimiter may be specified%s", _op_on_field);
+ }
+ }
+
+ /*
+ * parse list and put values into startpos and endpos.
+ * valid list formats: N, N-, N-M, -M
+ * more than one list can be separated by commas
+ */
+ {
+ char *ntok;
+ int s = 0, e = 0;
+
+ /* take apart the lists, one by one (they are separated with commas */
+ while ((ltok = strsep(&sopt, ",")) != NULL) {
+
+ /* it's actually legal to pass an empty list */
+ if (strlen(ltok) == 0)
+ continue;
+
+ /* get the start pos */
+ ntok = strsep(&ltok, "-");
+ if (ntok == NULL) {
+ bb_error_msg
+ ("internal error: ntok is null for start pos!?\n");
+ } else if (strlen(ntok) == 0) {
+ s = BOL;
+ } else {
+ s = xatoi_u(ntok);
+ /* account for the fact that arrays are zero based, while
+ * the user expects the first char on the line to be char #1 */
+ if (s != 0)
+ s--;
+ }
+
+ /* get the end pos */
+ ntok = strsep(&ltok, "-");
+ if (ntok == NULL) {
+ e = NON_RANGE;
+ } else if (strlen(ntok) == 0) {
+ e = EOL;
+ } else {
+ e = xatoi_u(ntok);
+ /* if the user specified and end position of 0, that means "til the
+ * end of the line */
+ if (e == 0)
+ e = EOL;
+ e--; /* again, arrays are zero based, lines are 1 based */
+ if (e == s)
+ e = NON_RANGE;
+ }
+
+ /* if there's something left to tokenize, the user passed
+ * an invalid list */
+ if (ltok)
+ bb_error_msg_and_die("invalid byte or field list");
+
+ /* add the new list */
+ cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists));
+ cut_lists[nlists-1].startpos = s;
+ cut_lists[nlists-1].endpos = e;
+ }
+
+ /* make sure we got some cut positions out of all that */
+ if (nlists == 0)
+ bb_error_msg_and_die("missing list of positions");
+
+ /* now that the lists are parsed, we need to sort them to make life
+ * easier on us when it comes time to print the chars / fields / lines
+ */
+ qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc);
+ }
+
+ /* argv[0..argc-1] should be names of file to process. If no
+ * files were specified or '-' was specified, take input from stdin.
+ * Otherwise, we process all the files specified. */
+ if (argv[0] == NULL || LONE_DASH(argv[0])) {
+ cut_file(stdin);
+ } else {
+ FILE *file;
+
+ do {
+ file = fopen_or_warn(argv[0], "r");
+ if (file) {
+ cut_file(file);
+ fclose(file);
+ }
+ } while (*++argv);
+ }
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(cut_lists);
+ return EXIT_SUCCESS;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/date.c b/i/pc104/initrd/conf/busybox/coreutils/date.c
new file mode 100644
index 0000000..dfc8b2f
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/date.c
@@ -0,0 +1,241 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini date implementation for busybox
+ *
+ * by Matthew Grant <grantma@anathoth.gen.nz>
+ *
+ * iso-format handling added by Robert Griebl <griebl@gmx.de>
+ * bugfixes and cleanup by Bernhard Fischer
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+*/
+
+#include "busybox.h"
+
+/* This 'date' command supports only 2 time setting formats,
+ all the GNU strftime stuff (its in libc, lets use it),
+ setting time using UTC and displaying it, as well as
+ an RFC 2822 compliant date output for shell scripting
+ mail commands */
+
+/* Input parsing code is always bulky - used heavy duty libc stuff as
+ much as possible, missed out a lot of bounds checking */
+
+/* Default input handling to save surprising some people */
+
+
+#define DATE_OPT_RFC2822 0x01
+#define DATE_OPT_SET 0x02
+#define DATE_OPT_UTC 0x04
+#define DATE_OPT_DATE 0x08
+#define DATE_OPT_REFERENCE 0x10
+#define DATE_OPT_TIMESPEC 0x20
+#define DATE_OPT_HINT 0x40
+
+static void xputenv(char *s)
+{
+ if (putenv(s) != 0)
+ bb_error_msg_and_die(bb_msg_memory_exhausted);
+}
+
+static void maybe_set_utc(int opt)
+{
+ if (opt & DATE_OPT_UTC)
+ xputenv((char*)"TZ=UTC0");
+}
+
+int date_main(int argc, char **argv);
+int date_main(int argc, char **argv)
+{
+ time_t tm;
+ struct tm tm_time;
+ unsigned opt;
+ int ifmt = -1;
+ char *date_str = NULL;
+ char *date_fmt = NULL;
+ char *filename = NULL;
+ char *isofmt_arg;
+ char *hintfmt_arg;
+
+ opt_complementary = "?:d--s:s--d"
+ USE_FEATURE_DATE_ISOFMT(":R--I:I--R");
+ opt = getopt32(argc, argv, "Rs:ud:r:"
+ USE_FEATURE_DATE_ISOFMT("I::D:"),
+ &date_str, &date_str, &filename
+ USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg));
+ maybe_set_utc(opt);
+
+ if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) {
+ if (!isofmt_arg) {
+ ifmt = 0; /* default is date */
+ } else {
+ const char * const isoformats[] =
+ {"date", "hours", "minutes", "seconds"};
+
+ for (ifmt = 0; ifmt < 4; ifmt++)
+ if (!strcmp(isofmt_arg, isoformats[ifmt])) {
+ break;
+ }
+ if (ifmt == 4) /* parse error */
+ bb_show_usage();
+ }
+ }
+
+ /* XXX, date_fmt == NULL from this always */
+ if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) {
+ date_fmt = &argv[optind][1]; /* Skip over the '+' */
+ } else if (date_str == NULL) {
+ opt |= DATE_OPT_SET;
+ date_str = argv[optind];
+ }
+
+ /* Now we have parsed all the information except the date format
+ which depends on whether the clock is being set or read */
+
+ if (filename) {
+ struct stat statbuf;
+ xstat(filename, &statbuf);
+ tm = statbuf.st_mtime;
+ } else
+ time(&tm);
+ memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
+ /* Zero out fields - take her back to midnight! */
+ if (date_str != NULL) {
+ tm_time.tm_sec = 0;
+ tm_time.tm_min = 0;
+ tm_time.tm_hour = 0;
+
+ /* Process any date input to UNIX time since 1 Jan 1970 */
+ if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) {
+ strptime(date_str, hintfmt_arg, &tm_time);
+ } else if (strchr(date_str, ':') != NULL) {
+ /* Parse input and assign appropriately to tm_time */
+
+ if (sscanf(date_str, "%d:%d:%d", &tm_time.tm_hour, &tm_time.tm_min,
+ &tm_time.tm_sec) == 3) {
+ /* no adjustments needed */
+ } else if (sscanf(date_str, "%d:%d", &tm_time.tm_hour,
+ &tm_time.tm_min) == 2) {
+ /* no adjustments needed */
+ } else if (sscanf(date_str, "%d.%d-%d:%d:%d", &tm_time.tm_mon,
+ &tm_time.tm_mday, &tm_time.tm_hour,
+ &tm_time.tm_min, &tm_time.tm_sec) == 5) {
+ /* Adjust dates from 1-12 to 0-11 */
+ tm_time.tm_mon -= 1;
+ } else if (sscanf(date_str, "%d.%d-%d:%d", &tm_time.tm_mon,
+ &tm_time.tm_mday,
+ &tm_time.tm_hour, &tm_time.tm_min) == 4) {
+ /* Adjust dates from 1-12 to 0-11 */
+ tm_time.tm_mon -= 1;
+ } else if (sscanf(date_str, "%d.%d.%d-%d:%d:%d", &tm_time.tm_year,
+ &tm_time.tm_mon, &tm_time.tm_mday,
+ &tm_time.tm_hour, &tm_time.tm_min,
+ &tm_time.tm_sec) == 6) {
+ tm_time.tm_year -= 1900; /* Adjust years */
+ tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
+ } else if (sscanf(date_str, "%d.%d.%d-%d:%d", &tm_time.tm_year,
+ &tm_time.tm_mon, &tm_time.tm_mday,
+ &tm_time.tm_hour, &tm_time.tm_min) == 5) {
+ tm_time.tm_year -= 1900; /* Adjust years */
+ tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
+ } else {
+ bb_error_msg_and_die(bb_msg_invalid_date, date_str);
+ }
+ } else {
+ int nr;
+ char *cp;
+
+ nr = sscanf(date_str, "%2d%2d%2d%2d%d", &tm_time.tm_mon,
+ &tm_time.tm_mday, &tm_time.tm_hour, &tm_time.tm_min,
+ &tm_time.tm_year);
+
+ if (nr < 4 || nr > 5) {
+ bb_error_msg_and_die(bb_msg_invalid_date, date_str);
+ }
+
+ cp = strchr(date_str, '.');
+ if (cp) {
+ nr = sscanf(cp + 1, "%2d", &tm_time.tm_sec);
+ if (nr != 1) {
+ bb_error_msg_and_die(bb_msg_invalid_date, date_str);
+ }
+ }
+
+ /* correct for century - minor Y2K problem here? */
+ if (tm_time.tm_year >= 1900) {
+ tm_time.tm_year -= 1900;
+ }
+ /* adjust date */
+ tm_time.tm_mon -= 1;
+ }
+
+ /* Correct any day of week and day of year etc. fields */
+ tm_time.tm_isdst = -1; /* Be sure to recheck dst. */
+ tm = mktime(&tm_time);
+ if (tm < 0) {
+ bb_error_msg_and_die(bb_msg_invalid_date, date_str);
+ }
+ maybe_set_utc(opt);
+
+ /* if setting time, set it */
+ if ((opt & DATE_OPT_SET) && stime(&tm) < 0) {
+ bb_perror_msg("cannot set date");
+ }
+ }
+
+ /* Display output */
+
+ /* Deal with format string */
+
+ if (date_fmt == NULL) {
+ int i;
+ date_fmt = xzalloc(32);
+ if (ENABLE_FEATURE_DATE_ISOFMT && ifmt >= 0) {
+ strcpy(date_fmt, "%Y-%m-%d");
+ if (ifmt > 0) {
+ i = 8;
+ date_fmt[i++] = 'T';
+ date_fmt[i++] = '%';
+ date_fmt[i++] = 'H';
+ if (ifmt > 1) {
+ date_fmt[i++] = ':';
+ date_fmt[i++] = '%';
+ date_fmt[i++] = 'M';
+ }
+ if (ifmt > 2) {
+ date_fmt[i++] = ':';
+ date_fmt[i++] = '%';
+ date_fmt[i++] = 'S';
+ }
+format_utc:
+ date_fmt[i++] = '%';
+ date_fmt[i] = (opt & DATE_OPT_UTC) ? 'Z' : 'z';
+ }
+ } else if (opt & DATE_OPT_RFC2822) {
+ /* Undo busybox.c for date -R */
+ if (ENABLE_LOCALE_SUPPORT)
+ setlocale(LC_TIME, "C");
+ strcpy(date_fmt, "%a, %d %b %Y %H:%M:%S ");
+ i = 22;
+ goto format_utc;
+ } else /* default case */
+ date_fmt = (char*)"%a %b %e %H:%M:%S %Z %Y";
+ }
+
+ if (*date_fmt == '\0') {
+ /* With no format string, just print a blank line */
+ *bb_common_bufsiz1 = 0;
+ } else {
+ /* Handle special conversions */
+
+ if (strncmp(date_fmt, "%f", 2) == 0) {
+ date_fmt = (char*)"%Y.%m.%d-%H:%M:%S";
+ }
+
+ /* Generate output string */
+ strftime(bb_common_bufsiz1, 200, date_fmt, &tm_time);
+ }
+ puts(bb_common_bufsiz1);
+
+ return EXIT_SUCCESS;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/dd.c b/i/pc104/initrd/conf/busybox/coreutils/dd.c
new file mode 100644
index 0000000..4a094e8
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/dd.c
@@ -0,0 +1,249 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini dd implementation for busybox
+ *
+ *
+ * Copyright (C) 2000,2001 Matt Kraai
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+#include <signal.h> /* For FEATURE_DD_SIGNAL_HANDLING */
+
+static const struct suffix_mult dd_suffixes[] = {
+ { "c", 1 },
+ { "w", 2 },
+ { "b", 512 },
+ { "kD", 1000 },
+ { "k", 1024 },
+ { "K", 1024 }, // compat with coreutils dd
+ { "MD", 1000000 },
+ { "M", 1048576 },
+ { "GD", 1000000000 },
+ { "G", 1073741824 },
+ { NULL, 0 }
+};
+
+static off_t out_full, out_part, in_full, in_part;
+
+static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal)
+{
+ fprintf(stderr, "%"OFF_FMT"d+%"OFF_FMT"d records in\n"
+ "%"OFF_FMT"d+%"OFF_FMT"d records out\n",
+ in_full, in_part,
+ out_full, out_part);
+}
+
+static ssize_t full_write_or_warn(int fd, const void *buf, size_t len,
+ const char* filename)
+{
+ ssize_t n = full_write(fd, buf, len);
+ if (n < 0)
+ bb_perror_msg("writing '%s'", filename);
+ return n;
+}
+
+#if ENABLE_LFS
+#define XATOU_SFX xatoull_sfx
+#else
+#define XATOU_SFX xatoul_sfx
+#endif
+
+int dd_main(int argc, char **argv);
+int dd_main(int argc, char **argv)
+{
+ enum {
+ sync_flag = 1 << 0,
+ noerror = 1 << 1,
+ trunc_flag = 1 << 2,
+ twobufs_flag = 1 << 3,
+ };
+ int flags = trunc_flag;
+ size_t oc = 0, ibs = 512, obs = 512;
+ ssize_t n, w;
+ off_t seek = 0, skip = 0, count = OFF_T_MAX;
+ int oflag, ifd, ofd;
+ const char *infile = NULL, *outfile = NULL;
+ char *ibuf, *obuf;
+
+ if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) {
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = dd_output_status;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGUSR1, &sa, 0);
+ }
+
+ for (n = 1; n < argc; n++) {
+ char *arg = argv[n];
+ /* Must fit into positive ssize_t */
+ if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", arg, 4))
+ ibs = xatoul_range_sfx(arg+4, 0, ((size_t)-1L)/2, dd_suffixes);
+ else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", arg, 4))
+ obs = xatoul_range_sfx(arg+4, 0, ((size_t)-1L)/2, dd_suffixes);
+ else if (!strncmp("bs=", arg, 3))
+ ibs = obs = xatoul_range_sfx(arg+3, 0, ((size_t)-1L)/2, dd_suffixes);
+ /* These can be large: */
+ else if (!strncmp("count=", arg, 6))
+ count = XATOU_SFX(arg+6, dd_suffixes);
+ else if (!strncmp("seek=", arg, 5))
+ seek = XATOU_SFX(arg+5, dd_suffixes);
+ else if (!strncmp("skip=", arg, 5))
+ skip = XATOU_SFX(arg+5, dd_suffixes);
+
+ else if (!strncmp("if=", arg, 3))
+ infile = arg+3;
+ else if (!strncmp("of=", arg, 3))
+ outfile = arg+3;
+ else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", arg, 5)) {
+ arg += 5;
+ while (1) {
+ if (!strncmp("notrunc", arg, 7)) {
+ flags &= ~trunc_flag;
+ arg += 7;
+ } else if (!strncmp("sync", arg, 4)) {
+ flags |= sync_flag;
+ arg += 4;
+ } else if (!strncmp("noerror", arg, 7)) {
+ flags |= noerror;
+ arg += 7;
+ } else {
+ bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv");
+ }
+ if (arg[0] == '\0') break;
+ if (*arg++ != ',') bb_show_usage();
+ }
+ } else
+ bb_show_usage();
+ }
+
+ ibuf = obuf = xmalloc(ibs);
+ if (ibs != obs) {
+ flags |= twobufs_flag;
+ obuf = xmalloc(obs);
+ }
+
+ if (infile != NULL)
+ ifd = xopen(infile, O_RDONLY);
+ else {
+ ifd = STDIN_FILENO;
+ infile = bb_msg_standard_input;
+ }
+
+ if (outfile != NULL) {
+ oflag = O_WRONLY | O_CREAT;
+
+ if (!seek && (flags & trunc_flag))
+ oflag |= O_TRUNC;
+
+ ofd = xopen(outfile, oflag);
+
+ if (seek && (flags & trunc_flag)) {
+ if (ftruncate(ofd, seek * obs) < 0) {
+ struct stat st;
+
+ if (fstat(ofd, &st) < 0 || S_ISREG(st.st_mode) ||
+ S_ISDIR(st.st_mode))
+ goto die_outfile;
+ }
+ }
+ } else {
+ ofd = STDOUT_FILENO;
+ outfile = bb_msg_standard_output;
+ }
+
+ if (skip) {
+ if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) {
+ while (skip-- > 0) {
+ n = safe_read(ifd, ibuf, ibs);
+ if (n < 0)
+ bb_perror_msg_and_die("%s", infile);
+ if (n == 0)
+ break;
+ }
+ }
+ }
+
+ if (seek) {
+ if (lseek(ofd, seek * obs, SEEK_CUR) < 0)
+ goto die_outfile;
+ }
+
+ while (in_full + in_part != count) {
+ if (flags & noerror) {
+ /* Pre-zero the buffer when doing the noerror thing */
+ memset(ibuf, '\0', ibs);
+ }
+
+ n = safe_read(ifd, ibuf, ibs);
+ if (n == 0)
+ break;
+ if (n < 0) {
+ if (flags & noerror) {
+ n = ibs;
+ bb_perror_msg("%s", infile);
+ } else
+ bb_perror_msg_and_die("%s", infile);
+ }
+ if ((size_t)n == ibs)
+ in_full++;
+ else {
+ in_part++;
+ if (flags & sync_flag) {
+ memset(ibuf + n, '\0', ibs - n);
+ n = ibs;
+ }
+ }
+ if (flags & twobufs_flag) {
+ char *tmp = ibuf;
+ while (n) {
+ size_t d = obs - oc;
+
+ if (d > n)
+ d = n;
+ memcpy(obuf + oc, tmp, d);
+ n -= d;
+ tmp += d;
+ oc += d;
+ if (oc == obs) {
+ w = full_write_or_warn(ofd, obuf, obs, outfile);
+ if (w < 0) goto out_status;
+ if (w == obs)
+ out_full++;
+ else if (w > 0)
+ out_part++;
+ oc = 0;
+ }
+ }
+ } else {
+ w = full_write_or_warn(ofd, ibuf, n, outfile);
+ if (w < 0) goto out_status;
+ if (w == obs)
+ out_full++;
+ else if (w > 0)
+ out_part++;
+ }
+ }
+
+ if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
+ w = full_write_or_warn(ofd, obuf, oc, outfile);
+ if (w < 0) goto out_status;
+ if (w > 0)
+ out_part++;
+ }
+ if (close(ifd) < 0) {
+ bb_perror_msg_and_die("%s", infile);
+ }
+
+ if (close(ofd) < 0) {
+ die_outfile:
+ bb_perror_msg_and_die("%s", outfile);
+ }
+ out_status:
+ dd_output_status(0);
+
+ return EXIT_SUCCESS;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/df.c b/i/pc104/initrd/conf/busybox/coreutils/df.c
new file mode 100644
index 0000000..484cabb
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/df.c
@@ -0,0 +1,155 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini df implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ * based on original code by (I think) Bruce Perens <bruce@pixar.com>.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 _NOT_ compliant -- options -P and -t missing. Also blocksize. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/df.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Size reduction. Removed floating point dependency. Added error checking
+ * on output. Output stats on 0-sized filesystems if specifically listed on
+ * the command line. Properly round *-blocks, Used, and Available quantities.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <mntent.h>
+#include <sys/vfs.h>
+#include "busybox.h"
+
+#ifndef CONFIG_FEATURE_HUMAN_READABLE
+static long kscale(long b, long bs)
+{
+ return ( b * (long long) bs + 1024/2 ) / 1024;
+}
+#endif
+
+int df_main(int argc, char **argv);
+int df_main(int argc, char **argv)
+{
+ long blocks_used;
+ long blocks_percent_used;
+#ifdef CONFIG_FEATURE_HUMAN_READABLE
+ unsigned long df_disp_hr = 1024;
+#endif
+ int status = EXIT_SUCCESS;
+ unsigned opt;
+ FILE *mount_table;
+ struct mntent *mount_entry;
+ struct statfs s;
+ static const char hdr_1k[] = "1k-blocks"; /* default display is kilobytes */
+ const char *disp_units_hdr = hdr_1k;
+
+#ifdef CONFIG_FEATURE_HUMAN_READABLE
+ opt_complementary = "h-km:k-hm:m-hk";
+ opt = getopt32(argc, argv, "hmk");
+ if (opt & 1) {
+ df_disp_hr = 0;
+ disp_units_hdr = " Size";
+ }
+ if (opt & 2) {
+ df_disp_hr = 1024*1024;
+ disp_units_hdr = "1M-blocks";
+ }
+#else
+ opt = getopt32(argc, argv, "k");
+#endif
+
+ printf("Filesystem%11s%-15sUsed Available Use%% Mounted on\n",
+ "", disp_units_hdr);
+
+ mount_table = NULL;
+ argv += optind;
+ if (optind >= argc) {
+ mount_table = setmntent(bb_path_mtab_file, "r");
+ if (!mount_table) {
+ bb_perror_msg_and_die(bb_path_mtab_file);
+ }
+ }
+
+ do {
+ const char *device;
+ const char *mount_point;
+
+ if (mount_table) {
+ mount_entry = getmntent(mount_table);
+ if (!mount_entry) {
+ endmntent(mount_table);
+ break;
+ }
+ } else {
+ mount_point = *argv++;
+ if (!mount_point) {
+ break;
+ }
+ mount_entry = find_mount_point(mount_point, bb_path_mtab_file);
+ if (!mount_entry) {
+ bb_error_msg("%s: can't find mount point", mount_point);
+ SET_ERROR:
+ status = EXIT_FAILURE;
+ continue;
+ }
+ }
+
+ device = mount_entry->mnt_fsname;
+ mount_point = mount_entry->mnt_dir;
+
+ if (statfs(mount_point, &s) != 0) {
+ bb_perror_msg("%s", mount_point);
+ goto SET_ERROR;
+ }
+
+ if ((s.f_blocks > 0) || !mount_table){
+ blocks_used = s.f_blocks - s.f_bfree;
+ blocks_percent_used = 0;
+ if (blocks_used + s.f_bavail) {
+ blocks_percent_used = (((long long) blocks_used) * 100
+ + (blocks_used + s.f_bavail)/2
+ ) / (blocks_used + s.f_bavail);
+ }
+
+ if (strcmp(device, "rootfs") == 0) {
+ continue;
+ } else if (strcmp(device, "/dev/root") == 0) {
+ /* Adjusts device to be the real root device,
+ * or leaves device alone if it can't find it */
+ device = find_block_device("/");
+ if (!device) {
+ goto SET_ERROR;
+ }
+ }
+
+#ifdef CONFIG_FEATURE_HUMAN_READABLE
+ printf("%-20s %9s ", device,
+ make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr));
+
+ printf("%9s ",
+ make_human_readable_str( (s.f_blocks - s.f_bfree),
+ s.f_bsize, df_disp_hr));
+
+ printf("%9s %3ld%% %s\n",
+ make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr),
+ blocks_percent_used, mount_point);
+#else
+ printf("%-20s %9ld %9ld %9ld %3ld%% %s\n",
+ device,
+ kscale(s.f_blocks, s.f_bsize),
+ kscale(s.f_blocks-s.f_bfree, s.f_bsize),
+ kscale(s.f_bavail, s.f_bsize),
+ blocks_percent_used, mount_point);
+#endif
+ }
+
+ } while (1);
+
+ fflush_stdout_and_exit(status);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/diff.c b/i/pc104/initrd/conf/busybox/coreutils/diff.c
new file mode 100644
index 0000000..fa6ef10
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/diff.c
@@ -0,0 +1,1227 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini diff implementation for busybox, adapted from OpenBSD diff.
+ *
+ * Copyright (C) 2006 by Robert Sullivan <cogito.ergo.cogito@hotmail.com>
+ * Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+
+#define FSIZE_MAX 32768
+
+/*
+ * Output flags
+ */
+#define D_HEADER 1 /* Print a header/footer between files */
+#define D_EMPTY1 2 /* Treat first file as empty (/dev/null) */
+#define D_EMPTY2 4 /* Treat second file as empty (/dev/null) */
+
+/*
+ * Status values for print_status() and diffreg() return values
+ * Guide:
+ * D_SAME - files are the same
+ * D_DIFFER - files differ
+ * D_BINARY - binary files differ
+ * D_COMMON - subdirectory common to both dirs
+ * D_ONLY - file only exists in one dir
+ * D_MISMATCH1 - path1 a dir, path2 a file
+ * D_MISMATCH2 - path1 a file, path2 a dir
+ * D_ERROR - error occurred
+ * D_SKIPPED1 - skipped path1 as it is a special file
+ * D_SKIPPED2 - skipped path2 as it is a special file
+ */
+
+#define D_SAME 0
+#define D_DIFFER (1<<0)
+#define D_BINARY (1<<1)
+#define D_COMMON (1<<2)
+#define D_ONLY (1<<3)
+#define D_MISMATCH1 (1<<4)
+#define D_MISMATCH2 (1<<5)
+#define D_ERROR (1<<6)
+#define D_SKIPPED1 (1<<7)
+#define D_SKIPPED2 (1<<8)
+
+/* Command line options */
+#define FLAG_a (1<<0)
+#define FLAG_b (1<<1)
+#define FLAG_d (1<<2)
+#define FLAG_i (1<<3)
+#define FLAG_L (1<<4)
+#define FLAG_N (1<<5)
+#define FLAG_q (1<<6)
+#define FLAG_r (1<<7)
+#define FLAG_s (1<<8)
+#define FLAG_S (1<<9)
+#define FLAG_t (1<<10)
+#define FLAG_T (1<<11)
+#define FLAG_U (1<<12)
+#define FLAG_w (1<<13)
+
+/* The following variables should be static, but gcc currently
+ * creates a much bigger object if we do this. [which version of gcc? --vda] */
+/* 4.x, IIRC also 3.x --bernhard */
+/* Works for gcc 3.4.3. Sizes without and with "static":
+ # size busybox.t[34]/coreutils/diff.o
+ text data bss dec hex filename
+ 6969 8 305 7282 1c72 busybox.t3/coreutils/diff.o
+ 6969 8 305 7282 1c72 busybox.t4/coreutils/diff.o
+ --vda
+ */
+/* This is the default number of lines of context. */
+static int context = 3;
+static int status;
+static char *start;
+static const char *label1;
+static const char *label2;
+static struct stat stb1, stb2;
+USE_FEATURE_DIFF_DIR(static char **dl;)
+USE_FEATURE_DIFF_DIR(static int dl_count;)
+
+struct cand {
+ int x;
+ int y;
+ int pred;
+};
+
+static struct line {
+ int serial;
+ int value;
+} *file[2];
+
+/*
+ * The following struct is used to record change information
+ * doing a "context" or "unified" diff. (see routine "change" to
+ * understand the highly mnemonic field names)
+ */
+struct context_vec {
+ int a; /* start line in old file */
+ int b; /* end line in old file */
+ int c; /* start line in new file */
+ int d; /* end line in new file */
+};
+
+static int *J; /* will be overlaid on class */
+static int *class; /* will be overlaid on file[0] */
+static int *klist; /* will be overlaid on file[0] after class */
+static int *member; /* will be overlaid on file[1] */
+static int clen;
+static int len[2];
+static int pref, suff; /* length of prefix and suffix */
+static int slen[2];
+static bool anychange;
+static long *ixnew; /* will be overlaid on file[1] */
+static long *ixold; /* will be overlaid on klist */
+static struct cand *clist; /* merely a free storage pot for candidates */
+static int clistlen; /* the length of clist */
+static struct line *sfile[2]; /* shortened by pruning common prefix/suffix */
+static struct context_vec *context_vec_start;
+static struct context_vec *context_vec_end;
+static struct context_vec *context_vec_ptr;
+
+
+static void print_only(const char *path, size_t dirlen, const char *entry)
+{
+ if (dirlen > 1)
+ dirlen--;
+ printf("Only in %.*s: %s\n", (int) dirlen, path, entry);
+}
+
+
+static void print_status(int val, char *path1, char *path2, char *entry)
+{
+ const char * const _entry = entry ? entry : "";
+ char * const _path1 = entry ? concat_path_file(path1, _entry) : path1;
+ char * const _path2 = entry ? concat_path_file(path2, _entry) : path2;
+
+ switch (val) {
+ case D_ONLY:
+ print_only(path1, strlen(path1), entry);
+ break;
+ case D_COMMON:
+ printf("Common subdirectories: %s and %s\n", _path1, _path2);
+ break;
+ case D_BINARY:
+ printf("Binary files %s and %s differ\n", _path1, _path2);
+ break;
+ case D_DIFFER:
+ if (option_mask32 & FLAG_q)
+ printf("Files %s and %s differ\n", _path1, _path2);
+ break;
+ case D_SAME:
+ if (option_mask32 & FLAG_s)
+ printf("Files %s and %s are identical\n", _path1, _path2);
+ break;
+ case D_MISMATCH1:
+ printf("File %s is a %s while file %s is a %s\n",
+ _path1, "directory", _path2, "regular file");
+ break;
+ case D_MISMATCH2:
+ printf("File %s is a %s while file %s is a %s\n",
+ _path1, "regular file", _path2, "directory");
+ break;
+ case D_SKIPPED1:
+ printf("File %s is not a regular file or directory and was skipped\n",
+ _path1);
+ break;
+ case D_SKIPPED2:
+ printf("File %s is not a regular file or directory and was skipped\n",
+ _path2);
+ break;
+ }
+ if (entry) {
+ free(_path1);
+ free(_path2);
+ }
+}
+static void fiddle_sum(int *sum, int t)
+{
+ *sum = (int)(*sum * 127 + t);
+}
+/*
+ * Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578.
+ */
+static int readhash(FILE * f)
+{
+ int i, t, space;
+ int sum;
+
+ sum = 1;
+ space = 0;
+ if (!(option_mask32 & (FLAG_b | FLAG_w))) {
+ for (i = 0; (t = getc(f)) != '\n'; i++) {
+ if (t == EOF) {
+ if (i == 0)
+ return 0;
+ break;
+ }
+ fiddle_sum(&sum, t);
+ }
+ } else {
+ for (i = 0;;) {
+ switch (t = getc(f)) {
+ case '\t':
+ case '\r':
+ case '\v':
+ case '\f':
+ case ' ':
+ space++;
+ continue;
+ default:
+ if (space && !(option_mask32 & FLAG_w)) {
+ i++;
+ space = 0;
+ }
+ fiddle_sum(&sum, t);
+ i++;
+ continue;
+ case EOF:
+ if (i == 0)
+ return 0;
+ /* FALLTHROUGH */
+ case '\n':
+ break;
+ }
+ break;
+ }
+ }
+ /*
+ * There is a remote possibility that we end up with a zero sum.
+ * Zero is used as an EOF marker, so return 1 instead.
+ */
+ return (sum == 0 ? 1 : sum);
+}
+
+
+/*
+ * Check to see if the given files differ.
+ * Returns 0 if they are the same, 1 if different, and -1 on error.
+ */
+static int files_differ(FILE * f1, FILE * f2, int flags)
+{
+ size_t i, j;
+
+ if ((flags & (D_EMPTY1 | D_EMPTY2)) || stb1.st_size != stb2.st_size
+ || (stb1.st_mode & S_IFMT) != (stb2.st_mode & S_IFMT)
+ ) {
+ return 1;
+ }
+ while (1) {
+ i = fread(bb_common_bufsiz1, 1, BUFSIZ/2, f1);
+ j = fread(bb_common_bufsiz1 + BUFSIZ/2, 1, BUFSIZ/2, f2);
+ if (i != j)
+ return 1;
+ if (i == 0)
+ return (ferror(f1) || ferror(f2));
+ if (memcmp(bb_common_bufsiz1,
+ bb_common_bufsiz1 + BUFSIZ/2, i) != 0)
+ return 1;
+ }
+}
+
+
+static void prepare(int i, FILE * fd, off_t filesize)
+{
+ struct line *p;
+ int h;
+ size_t j, sz;
+
+ rewind(fd);
+
+ sz = (filesize <= FSIZE_MAX ? filesize : FSIZE_MAX) / 25;
+ if (sz < 100)
+ sz = 100;
+
+ p = xmalloc((sz + 3) * sizeof(struct line));
+ j = 0;
+ while ((h = readhash(fd))) {
+ if (j == sz) {
+ sz = sz * 3 / 2;
+ p = xrealloc(p, (sz + 3) * sizeof(struct line));
+ }
+ p[++j].value = h;
+ }
+ len[i] = j;
+ file[i] = p;
+}
+
+
+static void prune(void)
+{
+ int i, j;
+
+ for (pref = 0; pref < len[0] && pref < len[1] &&
+ file[0][pref + 1].value == file[1][pref + 1].value; pref++)
+ ;
+ for (suff = 0; suff < len[0] - pref && suff < len[1] - pref &&
+ file[0][len[0] - suff].value == file[1][len[1] - suff].value;
+ suff++)
+ ;
+ for (j = 0; j < 2; j++) {
+ sfile[j] = file[j] + pref;
+ slen[j] = len[j] - pref - suff;
+ for (i = 0; i <= slen[j]; i++)
+ sfile[j][i].serial = i;
+ }
+}
+
+
+static void equiv(struct line *a, int n, struct line *b, int m, int *c)
+{
+ int i, j;
+
+ i = j = 1;
+ while (i <= n && j <= m) {
+ if (a[i].value < b[j].value)
+ a[i++].value = 0;
+ else if (a[i].value == b[j].value)
+ a[i++].value = j;
+ else
+ j++;
+ }
+ while (i <= n)
+ a[i++].value = 0;
+ b[m + 1].value = 0;
+ j = 0;
+ while (++j <= m) {
+ c[j] = -b[j].serial;
+ while (b[j + 1].value == b[j].value) {
+ j++;
+ c[j] = b[j].serial;
+ }
+ }
+ c[j] = -1;
+}
+
+
+static int isqrt(int n)
+{
+ int y, x;
+
+ if (n == 0)
+ return 0;
+ x = 1;
+ do {
+ y = x;
+ x = n / x;
+ x += y;
+ x /= 2;
+ } while ((x - y) > 1 || (x - y) < -1);
+
+ return x;
+}
+
+
+static int newcand(int x, int y, int pred)
+{
+ struct cand *q;
+
+ if (clen == clistlen) {
+ clistlen = clistlen * 11 / 10;
+ clist = xrealloc(clist, clistlen * sizeof(struct cand));
+ }
+ q = clist + clen;
+ q->x = x;
+ q->y = y;
+ q->pred = pred;
+ return clen++;
+}
+
+
+static int search(int *c, int k, int y)
+{
+ int i, j, l, t;
+
+ if (clist[c[k]].y < y) /* quick look for typical case */
+ return k + 1;
+ i = 0;
+ j = k + 1;
+ while (1) {
+ l = i + j;
+ if ((l >>= 1) <= i)
+ break;
+ t = clist[c[l]].y;
+ if (t > y)
+ j = l;
+ else if (t < y)
+ i = l;
+ else
+ return l;
+ }
+ return l + 1;
+}
+
+
+static int stone(int *a, int n, int *b, int *c)
+{
+ int i, k, y, j, l;
+ int oldc, tc, oldl;
+ unsigned int numtries;
+
+#if ENABLE_FEATURE_DIFF_MINIMAL
+ const unsigned int bound =
+ (option_mask32 & FLAG_d) ? UINT_MAX : MAX(256, isqrt(n));
+#else
+ const unsigned int bound = MAX(256, isqrt(n));
+#endif
+ k = 0;
+ c[0] = newcand(0, 0, 0);
+ for (i = 1; i <= n; i++) {
+ j = a[i];
+ if (j == 0)
+ continue;
+ y = -b[j];
+ oldl = 0;
+ oldc = c[0];
+ numtries = 0;
+ do {
+ if (y <= clist[oldc].y)
+ continue;
+ l = search(c, k, y);
+ if (l != oldl + 1)
+ oldc = c[l - 1];
+ if (l <= k) {
+ if (clist[c[l]].y <= y)
+ continue;
+ tc = c[l];
+ c[l] = newcand(i, y, oldc);
+ oldc = tc;
+ oldl = l;
+ numtries++;
+ } else {
+ c[l] = newcand(i, y, oldc);
+ k++;
+ break;
+ }
+ } while ((y = b[++j]) > 0 && numtries < bound);
+ }
+ return k;
+}
+
+
+static void unravel(int p)
+{
+ struct cand *q;
+ int i;
+
+ for (i = 0; i <= len[0]; i++)
+ J[i] = i <= pref ? i : i > len[0] - suff ? i + len[1] - len[0] : 0;
+ for (q = clist + p; q->y != 0; q = clist + q->pred)
+ J[q->x + pref] = q->y + pref;
+}
+
+
+static void unsort(struct line *f, int l, int *b)
+{
+ int *a, i;
+
+ a = xmalloc((l + 1) * sizeof(int));
+ for (i = 1; i <= l; i++)
+ a[f[i].serial] = f[i].value;
+ for (i = 1; i <= l; i++)
+ b[i] = a[i];
+ free(a);
+}
+
+
+static int skipline(FILE * f)
+{
+ int i, c;
+
+ for (i = 1; (c = getc(f)) != '\n' && c != EOF; i++)
+ continue;
+ return i;
+}
+
+
+/*
+ * Check does double duty:
+ * 1. ferret out any fortuitous correspondences due
+ * to confounding by hashing (which result in "jackpot")
+ * 2. collect random access indexes to the two files
+ */
+static void check(FILE * f1, FILE * f2)
+{
+ int i, j, jackpot, c, d;
+ long ctold, ctnew;
+
+ rewind(f1);
+ rewind(f2);
+ j = 1;
+ ixold[0] = ixnew[0] = 0;
+ jackpot = 0;
+ ctold = ctnew = 0;
+ for (i = 1; i <= len[0]; i++) {
+ if (J[i] == 0) {
+ ixold[i] = ctold += skipline(f1);
+ continue;
+ }
+ while (j < J[i]) {
+ ixnew[j] = ctnew += skipline(f2);
+ j++;
+ }
+ if ((option_mask32 & FLAG_b) || (option_mask32 & FLAG_w)
+ || (option_mask32 & FLAG_i)) {
+ while (1) {
+ c = getc(f1);
+ d = getc(f2);
+ /*
+ * GNU diff ignores a missing newline
+ * in one file if bflag || wflag.
+ */
+ if (((option_mask32 & FLAG_b) || (option_mask32 & FLAG_w)) &&
+ ((c == EOF && d == '\n') || (c == '\n' && d == EOF))) {
+ break;
+ }
+ ctold++;
+ ctnew++;
+ if ((option_mask32 & FLAG_b) && isspace(c) && isspace(d)) {
+ do {
+ if (c == '\n')
+ break;
+ ctold++;
+ } while (isspace(c = getc(f1)));
+ do {
+ if (d == '\n')
+ break;
+ ctnew++;
+ } while (isspace(d = getc(f2)));
+ } else if (option_mask32 & FLAG_w) {
+ while (isspace(c) && c != '\n') {
+ c = getc(f1);
+ ctold++;
+ }
+ while (isspace(d) && d != '\n') {
+ d = getc(f2);
+ ctnew++;
+ }
+ }
+ if (c != d) {
+ jackpot++;
+ J[i] = 0;
+ if (c != '\n' && c != EOF)
+ ctold += skipline(f1);
+ if (d != '\n' && c != EOF)
+ ctnew += skipline(f2);
+ break;
+ }
+ if (c == '\n' || c == EOF)
+ break;
+ }
+ } else {
+ while (1) {
+ ctold++;
+ ctnew++;
+ if ((c = getc(f1)) != (d = getc(f2))) {
+ J[i] = 0;
+ if (c != '\n' && c != EOF)
+ ctold += skipline(f1);
+ if (d != '\n' && c != EOF)
+ ctnew += skipline(f2);
+ break;
+ }
+ if (c == '\n' || c == EOF)
+ break;
+ }
+ }
+ ixold[i] = ctold;
+ ixnew[j] = ctnew;
+ j++;
+ }
+ for (; j <= len[1]; j++)
+ ixnew[j] = ctnew += skipline(f2);
+}
+
+
+/* shellsort CACM #201 */
+static void sort(struct line *a, int n)
+{
+ struct line *ai, *aim, w;
+ int j, m = 0, k;
+
+ if (n == 0)
+ return;
+ for (j = 1; j <= n; j *= 2)
+ m = 2 * j - 1;
+ for (m /= 2; m != 0; m /= 2) {
+ k = n - m;
+ for (j = 1; j <= k; j++) {
+ for (ai = &a[j]; ai > a; ai -= m) {
+ aim = &ai[m];
+ if (aim < ai)
+ break; /* wraparound */
+ if (aim->value > ai[0].value ||
+ (aim->value == ai[0].value && aim->serial > ai[0].serial))
+ break;
+ w.value = ai[0].value;
+ ai[0].value = aim->value;
+ aim->value = w.value;
+ w.serial = ai[0].serial;
+ ai[0].serial = aim->serial;
+ aim->serial = w.serial;
+ }
+ }
+ }
+}
+
+
+static void uni_range(int a, int b)
+{
+ if (a < b)
+ printf("%d,%d", a, b - a + 1);
+ else if (a == b)
+ printf("%d", b);
+ else
+ printf("%d,0", b);
+}
+
+
+static void fetch(long *f, int a, int b, FILE * lb, int ch)
+{
+ int i, j, c, lastc, col, nc;
+
+ if (a > b)
+ return;
+ for (i = a; i <= b; i++) {
+ fseek(lb, f[i - 1], SEEK_SET);
+ nc = f[i] - f[i - 1];
+ if (ch != '\0') {
+ putchar(ch);
+ if (option_mask32 & FLAG_T)
+ putchar('\t');
+ }
+ col = 0;
+ for (j = 0, lastc = '\0'; j < nc; j++, lastc = c) {
+ if ((c = getc(lb)) == EOF) {
+ printf("\n\\ No newline at end of file\n");
+ return;
+ }
+ if (c == '\t' && (option_mask32 & FLAG_t)) {
+ do {
+ putchar(' ');
+ } while (++col & 7);
+ } else {
+ putchar(c);
+ col++;
+ }
+ }
+ }
+}
+
+
+static int asciifile(FILE * f)
+{
+#if ENABLE_FEATURE_DIFF_BINARY
+ int i, cnt;
+#endif
+
+ if ((option_mask32 & FLAG_a) || f == NULL)
+ return 1;
+
+#if ENABLE_FEATURE_DIFF_BINARY
+ rewind(f);
+ cnt = fread(bb_common_bufsiz1, 1, BUFSIZ, f);
+ for (i = 0; i < cnt; i++) {
+ if (!isprint(bb_common_bufsiz1[i])
+ && !isspace(bb_common_bufsiz1[i])) {
+ return 0;
+ }
+ }
+#endif
+ return 1;
+}
+
+
+/* dump accumulated "unified" diff changes */
+static void dump_unified_vec(FILE * f1, FILE * f2)
+{
+ struct context_vec *cvp = context_vec_start;
+ int lowa, upb, lowc, upd;
+ int a, b, c, d;
+ char ch;
+
+ if (context_vec_start > context_vec_ptr)
+ return;
+
+ b = d = 0; /* gcc */
+ lowa = MAX(1, cvp->a - context);
+ upb = MIN(len[0], context_vec_ptr->b + context);
+ lowc = MAX(1, cvp->c - context);
+ upd = MIN(len[1], context_vec_ptr->d + context);
+
+ printf("@@ -");
+ uni_range(lowa, upb);
+ printf(" +");
+ uni_range(lowc, upd);
+ printf(" @@\n");
+
+ /*
+ * Output changes in "unified" diff format--the old and new lines
+ * are printed together.
+ */
+ for (; cvp <= context_vec_ptr; cvp++) {
+ a = cvp->a;
+ b = cvp->b;
+ c = cvp->c;
+ d = cvp->d;
+
+ /*
+ * c: both new and old changes
+ * d: only changes in the old file
+ * a: only changes in the new file
+ */
+ if (a <= b && c <= d)
+ ch = 'c';
+ else
+ ch = (a <= b) ? 'd' : 'a';
+ if (ch == 'c' || ch == 'd') {
+ fetch(ixold, lowa, a - 1, f1, ' ');
+ fetch(ixold, a, b, f1, '-');
+ }
+ if (ch == 'a')
+ fetch(ixnew, lowc, c - 1, f2, ' ');
+ if (ch == 'c' || ch == 'a')
+ fetch(ixnew, c, d, f2, '+');
+ lowa = b + 1;
+ lowc = d + 1;
+ }
+ fetch(ixnew, d + 1, upd, f2, ' ');
+
+ context_vec_ptr = context_vec_start - 1;
+}
+
+
+static void print_header(const char *file1, const char *file2)
+{
+ if (label1)
+ printf("--- %s\n", label1);
+ else
+ printf("--- %s\t%s", file1, ctime(&stb1.st_mtime));
+ if (label2)
+ printf("+++ %s\n", label2);
+ else
+ printf("+++ %s\t%s", file2, ctime(&stb2.st_mtime));
+}
+
+
+/*
+ * Indicate that there is a difference between lines a and b of the from file
+ * to get to lines c to d of the to file. If a is greater than b then there
+ * are no lines in the from file involved and this means that there were
+ * lines appended (beginning at b). If c is greater than d then there are
+ * lines missing from the to file.
+ */
+static void change(char *file1, FILE * f1, char *file2, FILE * f2, int a,
+ int b, int c, int d)
+{
+ static size_t max_context = 64;
+
+ if ((a > b && c > d) || (option_mask32 & FLAG_q)) {
+ anychange = 1;
+ return;
+ }
+
+ /*
+ * Allocate change records as needed.
+ */
+ if (context_vec_ptr == context_vec_end - 1) {
+ ptrdiff_t offset = context_vec_ptr - context_vec_start;
+
+ max_context <<= 1;
+ context_vec_start = xrealloc(context_vec_start,
+ max_context * sizeof(struct context_vec));
+ context_vec_end = context_vec_start + max_context;
+ context_vec_ptr = context_vec_start + offset;
+ }
+ if (anychange == 0) {
+ /*
+ * Print the context/unidiff header first time through.
+ */
+ print_header(file1, file2);
+ } else if (a > context_vec_ptr->b + (2 * context) + 1 &&
+ c > context_vec_ptr->d + (2 * context) + 1) {
+ /*
+ * If this change is more than 'context' lines from the
+ * previous change, dump the record and reset it.
+ */
+ dump_unified_vec(f1, f2);
+ }
+ context_vec_ptr++;
+ context_vec_ptr->a = a;
+ context_vec_ptr->b = b;
+ context_vec_ptr->c = c;
+ context_vec_ptr->d = d;
+ anychange = 1;
+}
+
+
+static void output(char *file1, FILE * f1, char *file2, FILE * f2)
+{
+ /* Note that j0 and j1 can't be used as they are defined in math.h.
+ * This also allows the rather amusing variable 'j00'... */
+ int m, i0, i1, j00, j01;
+
+ rewind(f1);
+ rewind(f2);
+ m = len[0];
+ J[0] = 0;
+ J[m + 1] = len[1] + 1;
+ for (i0 = 1; i0 <= m; i0 = i1 + 1) {
+ while (i0 <= m && J[i0] == J[i0 - 1] + 1)
+ i0++;
+ j00 = J[i0 - 1] + 1;
+ i1 = i0 - 1;
+ while (i1 < m && J[i1 + 1] == 0)
+ i1++;
+ j01 = J[i1 + 1] - 1;
+ J[i1] = j01;
+ change(file1, f1, file2, f2, i0, i1, j00, j01);
+ }
+ if (m == 0) {
+ change(file1, f1, file2, f2, 1, 0, 1, len[1]);
+ }
+ if (anychange != 0 && !(option_mask32 & FLAG_q)) {
+ dump_unified_vec(f1, f2);
+ }
+}
+
+/*
+ * The following code uses an algorithm due to Harold Stone,
+ * which finds a pair of longest identical subsequences in
+ * the two files.
+ *
+ * The major goal is to generate the match vector J.
+ * J[i] is the index of the line in file1 corresponding
+ * to line i file0. J[i] = 0 if there is no
+ * such line in file1.
+ *
+ * Lines are hashed so as to work in core. All potential
+ * matches are located by sorting the lines of each file
+ * on the hash (called ``value''). In particular, this
+ * collects the equivalence classes in file1 together.
+ * Subroutine equiv replaces the value of each line in
+ * file0 by the index of the first element of its
+ * matching equivalence in (the reordered) file1.
+ * To save space equiv squeezes file1 into a single
+ * array member in which the equivalence classes
+ * are simply concatenated, except that their first
+ * members are flagged by changing sign.
+ *
+ * Next the indices that point into member are unsorted into
+ * array class according to the original order of file0.
+ *
+ * The cleverness lies in routine stone. This marches
+ * through the lines of file0, developing a vector klist
+ * of "k-candidates". At step i a k-candidate is a matched
+ * pair of lines x,y (x in file0 y in file1) such that
+ * there is a common subsequence of length k
+ * between the first i lines of file0 and the first y
+ * lines of file1, but there is no such subsequence for
+ * any smaller y. x is the earliest possible mate to y
+ * that occurs in such a subsequence.
+ *
+ * Whenever any of the members of the equivalence class of
+ * lines in file1 matable to a line in file0 has serial number
+ * less than the y of some k-candidate, that k-candidate
+ * with the smallest such y is replaced. The new
+ * k-candidate is chained (via pred) to the current
+ * k-1 candidate so that the actual subsequence can
+ * be recovered. When a member has serial number greater
+ * that the y of all k-candidates, the klist is extended.
+ * At the end, the longest subsequence is pulled out
+ * and placed in the array J by unravel
+ *
+ * With J in hand, the matches there recorded are
+ * checked against reality to assure that no spurious
+ * matches have crept in due to hashing. If they have,
+ * they are broken, and "jackpot" is recorded--a harmless
+ * matter except that a true match for a spuriously
+ * mated line may now be unnecessarily reported as a change.
+ *
+ * Much of the complexity of the program comes simply
+ * from trying to minimize core utilization and
+ * maximize the range of doable problems by dynamically
+ * allocating what is needed and reusing what is not.
+ * The core requirements for problems larger than somewhat
+ * are (in words) 2*length(file0) + length(file1) +
+ * 3*(number of k-candidates installed), typically about
+ * 6n words for files of length n.
+ */
+static unsigned diffreg(char * ofile1, char * ofile2, int flags)
+{
+ char *file1 = ofile1;
+ char *file2 = ofile2;
+ FILE *f1 = stdin, *f2 = stdin;
+ unsigned rval;
+ int i;
+
+ anychange = 0;
+ context_vec_ptr = context_vec_start - 1;
+
+ if (S_ISDIR(stb1.st_mode) != S_ISDIR(stb2.st_mode))
+ return (S_ISDIR(stb1.st_mode) ? D_MISMATCH1 : D_MISMATCH2);
+
+ rval = D_SAME;
+
+ if (LONE_DASH(file1) && LONE_DASH(file2))
+ goto closem;
+
+ if (flags & D_EMPTY1)
+ f1 = xfopen(bb_dev_null, "r");
+ else if (NOT_LONE_DASH(file1))
+ f1 = xfopen(file1, "r");
+ if (flags & D_EMPTY2)
+ f2 = xfopen(bb_dev_null, "r");
+ else if (NOT_LONE_DASH(file2))
+ f2 = xfopen(file2, "r");
+
+/* We can't diff non-seekable stream - we use rewind(), fseek().
+ * This can be fixed (volunteers?).
+ * Meanwhile we should check it here by stat'ing input fds,
+ * but I am lazy and check that in main() instead.
+ * Check in main won't catch "diffing fifos buried in subdirectories"
+ * failure scenario - not very likely in real life... */
+
+ i = files_differ(f1, f2, flags);
+ if (i == 0)
+ goto closem;
+ else if (i != 1) { /* 1 == ok */
+ /* error */
+ status |= 2;
+ goto closem;
+ }
+
+ if (!asciifile(f1) || !asciifile(f2)) {
+ rval = D_BINARY;
+ status |= 1;
+ goto closem;
+ }
+
+ prepare(0, f1, stb1.st_size);
+ prepare(1, f2, stb2.st_size);
+ prune();
+ sort(sfile[0], slen[0]);
+ sort(sfile[1], slen[1]);
+
+ member = (int *) file[1];
+ equiv(sfile[0], slen[0], sfile[1], slen[1], member);
+ member = xrealloc(member, (slen[1] + 2) * sizeof(int));
+
+ class = (int *) file[0];
+ unsort(sfile[0], slen[0], class);
+ class = xrealloc(class, (slen[0] + 2) * sizeof(int));
+
+ klist = xmalloc((slen[0] + 2) * sizeof(int));
+ clen = 0;
+ clistlen = 100;
+ clist = xmalloc(clistlen * sizeof(struct cand));
+ i = stone(class, slen[0], member, klist);
+ free(member);
+ free(class);
+
+ J = xrealloc(J, (len[0] + 2) * sizeof(int));
+ unravel(klist[i]);
+ free(clist);
+ free(klist);
+
+ ixold = xrealloc(ixold, (len[0] + 2) * sizeof(long));
+ ixnew = xrealloc(ixnew, (len[1] + 2) * sizeof(long));
+ check(f1, f2);
+ output(file1, f1, file2, f2);
+
+ closem:
+ if (anychange) {
+ status |= 1;
+ if (rval == D_SAME)
+ rval = D_DIFFER;
+ }
+ fclose_if_not_stdin(f1);
+ fclose_if_not_stdin(f2);
+ if (file1 != ofile1)
+ free(file1);
+ if (file2 != ofile2)
+ free(file2);
+ return rval;
+}
+
+
+#if ENABLE_FEATURE_DIFF_DIR
+static void do_diff(char *dir1, char *path1, char *dir2, char *path2)
+{
+ int flags = D_HEADER;
+ int val;
+
+ char *fullpath1 = concat_path_file(dir1, path1);
+ char *fullpath2 = concat_path_file(dir2, path2);
+
+ if (stat(fullpath1, &stb1) != 0) {
+ flags |= D_EMPTY1;
+ memset(&stb1, 0, sizeof(stb1));
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(fullpath1);
+ fullpath1 = concat_path_file(dir1, path2);
+ }
+ if (stat(fullpath2, &stb2) != 0) {
+ flags |= D_EMPTY2;
+ memset(&stb2, 0, sizeof(stb2));
+ stb2.st_mode = stb1.st_mode;
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(fullpath2);
+ fullpath2 = concat_path_file(dir2, path1);
+ }
+
+ if (stb1.st_mode == 0)
+ stb1.st_mode = stb2.st_mode;
+
+ if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
+ printf("Common subdirectories: %s and %s\n", fullpath1, fullpath2);
+ return;
+ }
+
+ if (!S_ISREG(stb1.st_mode) && !S_ISDIR(stb1.st_mode))
+ val = D_SKIPPED1;
+ else if (!S_ISREG(stb2.st_mode) && !S_ISDIR(stb2.st_mode))
+ val = D_SKIPPED2;
+ else
+ val = diffreg(fullpath1, fullpath2, flags);
+
+ print_status(val, fullpath1, fullpath2, NULL);
+}
+#endif
+
+
+#if ENABLE_FEATURE_DIFF_DIR
+static int dir_strcmp(const void *p1, const void *p2)
+{
+ return strcmp(*(char *const *) p1, *(char *const *) p2);
+}
+
+
+/* This function adds a filename to dl, the directory listing. */
+static int add_to_dirlist(const char *filename,
+ struct stat ATTRIBUTE_UNUSED * sb, void *userdata,
+ int depth ATTRIBUTE_UNUSED)
+{
+ /* +2: with space for eventual trailing NULL */
+ dl = xrealloc(dl, (dl_count+2) * sizeof(dl[0]));
+ dl[dl_count] = xstrdup(filename + (int)(ptrdiff_t)userdata);
+ dl_count++;
+ return TRUE;
+}
+
+
+/* This returns a sorted directory listing. */
+static char **get_dir(char *path)
+{
+ dl_count = 0;
+ dl = NULL;
+
+ /* If -r has been set, then the recursive_action function will be
+ * used. Unfortunately, this outputs the root directory along with
+ * the recursed paths, so use void *userdata to specify the string
+ * length of the root directory - '(void*)(strlen(path)+)'.
+ * add_to_dirlist then removes root dir prefix. */
+
+ if (option_mask32 & FLAG_r) {
+ recursive_action(path, TRUE, TRUE, FALSE, add_to_dirlist, NULL,
+ (void*)(strlen(path)+1), 0);
+ } else {
+ DIR *dp;
+ struct dirent *ep;
+
+ dp = warn_opendir(path);
+ while ((ep = readdir(dp))) {
+ if (!strcmp(ep->d_name, "..") || LONE_CHAR(ep->d_name, '.'))
+ continue;
+ add_to_dirlist(ep->d_name, NULL, (void*)(int)0, 0);
+ }
+ closedir(dp);
+ }
+
+ /* Sort dl alphabetically. */
+ qsort(dl, dl_count, sizeof(char *), dir_strcmp);
+
+ dl[dl_count] = NULL;
+ return dl;
+}
+
+
+static void diffdir(char *p1, char *p2)
+{
+ char **dirlist1, **dirlist2;
+ char *dp1, *dp2;
+ int pos;
+
+ /* Check for trailing slashes. */
+ dp1 = last_char_is(p1, '/');
+ if (dp1 != NULL)
+ *dp1 = '\0';
+ dp2 = last_char_is(p2, '/');
+ if (dp2 != NULL)
+ *dp2 = '\0';
+
+ /* Get directory listings for p1 and p2. */
+
+ dirlist1 = get_dir(p1);
+ dirlist2 = get_dir(p2);
+
+ /* If -S was set, find the starting point. */
+ if (start) {
+ while (*dirlist1 != NULL && strcmp(*dirlist1, start) < 0)
+ dirlist1++;
+ while (*dirlist2 != NULL && strcmp(*dirlist2, start) < 0)
+ dirlist2++;
+ if ((*dirlist1 == NULL) || (*dirlist2 == NULL))
+ bb_error_msg(bb_msg_invalid_arg, "NULL", "-S");
+ }
+
+ /* Now that both dirlist1 and dirlist2 contain sorted directory
+ * listings, we can start to go through dirlist1. If both listings
+ * contain the same file, then do a normal diff. Otherwise, behaviour
+ * is determined by whether the -N flag is set. */
+ while (*dirlist1 != NULL || *dirlist2 != NULL) {
+ dp1 = *dirlist1;
+ dp2 = *dirlist2;
+ pos = dp1 == NULL ? 1 : dp2 == NULL ? -1 : strcmp(dp1, dp2);
+ if (pos == 0) {
+ do_diff(p1, dp1, p2, dp2);
+ dirlist1++;
+ dirlist2++;
+ } else if (pos < 0) {
+ if (option_mask32 & FLAG_N)
+ do_diff(p1, dp1, p2, NULL);
+ else
+ print_only(p1, strlen(p1) + 1, dp1);
+ dirlist1++;
+ } else {
+ if (option_mask32 & FLAG_N)
+ do_diff(p1, NULL, p2, dp2);
+ else
+ print_only(p2, strlen(p2) + 1, dp2);
+ dirlist2++;
+ }
+ }
+}
+#endif
+
+
+int diff_main(int argc, char **argv);
+int diff_main(int argc, char **argv)
+{
+ bool gotstdin = 0;
+ char *U_opt;
+ char *f1, *f2;
+ llist_t *L_arg = NULL;
+
+ /* exactly 2 params; collect multiple -L <label> */
+ opt_complementary = "=2:L::";
+ getopt32(argc, argv, "abdiL:NqrsS:tTU:wu"
+ "p" /* ignored (for compatibility) */,
+ &L_arg, &start, &U_opt);
+ /*argc -= optind;*/
+ argv += optind;
+ while (L_arg) {
+ if (label1 && label2)
+ bb_show_usage();
+ if (!label1)
+ label1 = L_arg->data;
+ else { /* then label2 is NULL */
+ label2 = label1;
+ label1 = L_arg->data;
+ }
+ /* we leak L_arg here... */
+ L_arg = L_arg->link;
+ }
+ if (option_mask32 & FLAG_U)
+ context = xatoi_u(U_opt);
+
+ /*
+ * Do sanity checks, fill in stb1 and stb2 and call the appropriate
+ * driver routine. Both drivers use the contents of stb1 and stb2.
+ */
+
+ f1 = argv[0];
+ f2 = argv[1];
+ if (LONE_DASH(f1)) {
+ fstat(STDIN_FILENO, &stb1);
+ gotstdin = 1;
+ } else
+ xstat(f1, &stb1);
+ if (LONE_DASH(f2)) {
+ fstat(STDIN_FILENO, &stb2);
+ gotstdin = 1;
+ } else
+ xstat(f2, &stb2);
+ if (gotstdin && (S_ISDIR(stb1.st_mode) || S_ISDIR(stb2.st_mode)))
+ bb_error_msg_and_die("can't compare - to a directory");
+ if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
+#if ENABLE_FEATURE_DIFF_DIR
+ diffdir(f1, f2);
+#else
+ bb_error_msg_and_die("directory comparison not supported");
+#endif
+ } else {
+ if (S_ISDIR(stb1.st_mode)) {
+ f1 = concat_path_file(f1, f2);
+ xstat(f1, &stb1);
+ }
+ if (S_ISDIR(stb2.st_mode)) {
+ f2 = concat_path_file(f2, f1);
+ xstat(f2, &stb2);
+ }
+/* XXX: FIXME: */
+/* We can't diff e.g. stdin supplied by a pipe - we use rewind(), fseek().
+ * This can be fixed (volunteers?) */
+ if (!S_ISREG(stb1.st_mode) || !S_ISREG(stb2.st_mode))
+ bb_error_msg_and_die("can't diff non-seekable stream");
+ print_status(diffreg(f1, f2, 0), f1, f2, NULL);
+ }
+ return status;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/dirname.c b/i/pc104/initrd/conf/busybox/coreutils/dirname.c
new file mode 100644
index 0000000..4ecde31
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/dirname.c
@@ -0,0 +1,27 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini dirname implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/dirname.html */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "busybox.h"
+
+int dirname_main(int argc, char **argv);
+int dirname_main(int argc, char **argv)
+{
+ if (argc != 2) {
+ bb_show_usage();
+ }
+
+ puts(dirname(argv[1]));
+
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/dos2unix.c b/i/pc104/initrd/conf/busybox/coreutils/dos2unix.c
new file mode 100644
index 0000000..62c1361
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/dos2unix.c
@@ -0,0 +1,116 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * dos2unix for BusyBox
+ *
+ * dos2unix '\n' convertor 0.5.0
+ * based on Unix2Dos 0.9.0 by Peter Hanecak (made 19.2.1997)
+ * Copyright 1997,.. by Peter Hanecak <hanecak@megaloman.sk>.
+ * All rights reserved.
+ *
+ * dos2unix filters reading input from stdin and writing output to stdout.
+ *
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+*/
+
+#include "busybox.h"
+
+enum ConvType {
+ CT_UNIX2DOS = 1,
+ CT_DOS2UNIX
+} ConvType;
+
+/* if fn is NULL then input is stdin and output is stdout */
+static int convert(char *fn)
+{
+ FILE *in, *out;
+ int i;
+
+ if (fn != NULL) {
+ in = xfopen(fn, "rw");
+ /*
+ The file is then created with mode read/write and
+ permissions 0666 for glibc 2.0.6 and earlier or
+ 0600 for glibc 2.0.7 and later.
+ */
+ snprintf(bb_common_bufsiz1, sizeof(bb_common_bufsiz1), "%sXXXXXX", fn);
+ /*
+ sizeof bb_common_bufsiz1 is 4096, so it should be big enough to
+ hold the full path. However if the output is truncated the
+ subsequent call to mkstemp would fail.
+ */
+ if ((i = mkstemp(&bb_common_bufsiz1[0])) == -1
+ || chmod(bb_common_bufsiz1, 0600) == -1) {
+ bb_perror_nomsg_and_die();
+ }
+ out = fdopen(i, "w+");
+ if (!out) {
+ close(i);
+ remove(bb_common_bufsiz1);
+ }
+ } else {
+ in = stdin;
+ out = stdout;
+ }
+
+ while ((i = fgetc(in)) != EOF) {
+ if (i == '\r')
+ continue;
+ if (i == '\n') {
+ if (ConvType == CT_UNIX2DOS)
+ fputc('\r', out);
+ fputc('\n', out);
+ continue;
+ }
+ fputc(i, out);
+ }
+
+ if (fn != NULL) {
+ if (fclose(in) < 0 || fclose(out) < 0) {
+ bb_perror_nomsg();
+ remove(bb_common_bufsiz1);
+ return -2;
+ }
+ /* Assume they are both on the same filesystem (which
+ * should be true since we put them into the same directory
+ * so we _should_ be ok, but you never know... */
+ if (rename(bb_common_bufsiz1, fn) < 0) {
+ bb_perror_msg("cannot rename '%s' as '%s'", bb_common_bufsiz1, fn);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int dos2unix_main(int argc, char *argv[]);
+int dos2unix_main(int argc, char *argv[])
+{
+ int o;
+
+ /* See if we are supposed to be doing dos2unix or unix2dos */
+ if (applet_name[0] == 'd') {
+ ConvType = CT_DOS2UNIX; /*2 */
+ } else {
+ ConvType = CT_UNIX2DOS; /*1 */
+ }
+ /* -u and -d are mutally exclusive */
+ opt_complementary = "?:u--d:d--u";
+ /* process parameters */
+ /* -u convert to unix */
+ /* -d convert to dos */
+ o = getopt32(argc, argv, "du");
+
+ /* Do the conversion requested by an argument else do the default
+ * conversion depending on our name. */
+ if (o)
+ ConvType = o;
+
+ if (optind < argc) {
+ while (optind < argc)
+ if ((o = convert(argv[optind++])) < 0)
+ break;
+ } else
+ o = convert(NULL);
+
+ return o;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/du.c b/i/pc104/initrd/conf/busybox/coreutils/du.c
new file mode 100644
index 0000000..e5fe5ff
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/du.c
@@ -0,0 +1,247 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini du implementation for busybox
+ *
+ * Copyright (C) 1999,2000,2001 by Lineo, inc. and John Beppu
+ * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
+ * Copyright (C) 2002 Edward Betts <edward@debian.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant (unless default blocksize set to 1k) */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/du.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Mostly rewritten for SUSv3 compliance and to fix bugs/defects.
+ * 1) Added support for SUSv3 -a, -H, -L, gnu -c, and (busybox) -d options.
+ * The -d option allows setting of max depth (similar to gnu --max-depth).
+ * 2) Fixed incorrect size calculations for links and directories, especially
+ * when errors occurred. Calculates sizes should now match gnu du output.
+ * 3) Added error checking of output.
+ * 4) Fixed busybox bug #1284 involving long overflow with human_readable.
+ */
+
+#include "busybox.h"
+
+#if ENABLE_FEATURE_HUMAN_READABLE
+# if ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
+static unsigned long disp_hr = 1024;
+# else
+static unsigned long disp_hr = 512;
+# endif
+#elif ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
+static unsigned disp_k = 1;
+#else
+static unsigned disp_k; /* bss inits to 0 */
+#endif
+
+static int max_print_depth = INT_MAX;
+static nlink_t count_hardlinks = 1;
+
+static int status;
+static int print_files;
+static int slink_depth;
+static int du_depth;
+static int one_file_system;
+static dev_t dir_dev;
+
+
+static void print(long size, const char * const filename)
+{
+ /* TODO - May not want to defer error checking here. */
+#if ENABLE_FEATURE_HUMAN_READABLE
+ printf("%s\t%s\n", make_human_readable_str(size, 512, disp_hr),
+ filename);
+#else
+ if (disp_k) {
+ size++;
+ size >>= 1;
+ }
+ printf("%ld\t%s\n", size, filename);
+#endif
+}
+
+/* tiny recursive du */
+static long du(const char * const filename)
+{
+ struct stat statbuf;
+ long sum;
+
+ if (lstat(filename, &statbuf) != 0) {
+ bb_perror_msg("%s", filename);
+ status = EXIT_FAILURE;
+ return 0;
+ }
+
+ if (one_file_system) {
+ if (du_depth == 0) {
+ dir_dev = statbuf.st_dev;
+ } else if (dir_dev != statbuf.st_dev) {
+ return 0;
+ }
+ }
+
+ sum = statbuf.st_blocks;
+
+ if (S_ISLNK(statbuf.st_mode)) {
+ if (slink_depth > du_depth) { /* -H or -L */
+ if (stat(filename, &statbuf) != 0) {
+ bb_perror_msg("%s", filename);
+ status = EXIT_FAILURE;
+ return 0;
+ }
+ sum = statbuf.st_blocks;
+ if (slink_depth == 1) {
+ slink_depth = INT_MAX; /* Convert -H to -L. */
+ }
+ }
+ }
+
+ if (statbuf.st_nlink > count_hardlinks) {
+ /* Add files/directories with links only once */
+ if (is_in_ino_dev_hashtable(&statbuf)) {
+ return 0;
+ }
+ add_to_ino_dev_hashtable(&statbuf, NULL);
+ }
+
+ if (S_ISDIR(statbuf.st_mode)) {
+ DIR *dir;
+ struct dirent *entry;
+ char *newfile;
+
+ dir = warn_opendir(filename);
+ if (!dir) {
+ status = EXIT_FAILURE;
+ return sum;
+ }
+
+ newfile = last_char_is(filename, '/');
+ if (newfile)
+ *newfile = '\0';
+
+ while ((entry = readdir(dir))) {
+ char *name = entry->d_name;
+
+ newfile = concat_subpath_file(filename, name);
+ if (newfile == NULL)
+ continue;
+ ++du_depth;
+ sum += du(newfile);
+ --du_depth;
+ free(newfile);
+ }
+ closedir(dir);
+ } else if (du_depth > print_files) {
+ return sum;
+ }
+ if (du_depth <= max_print_depth) {
+ print(sum, filename);
+ }
+ return sum;
+}
+
+int du_main(int argc, char **argv);
+int du_main(int argc, char **argv)
+{
+ long total;
+ int slink_depth_save;
+ int print_final_total;
+ char *smax_print_depth;
+ unsigned opt;
+
+#if ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
+ if (getenv("POSIXLY_CORRECT")) { /* TODO - a new libbb function? */
+#if ENABLE_FEATURE_HUMAN_READABLE
+ disp_hr = 512;
+#else
+ disp_k = 0;
+#endif
+ }
+#endif
+
+ /* Note: SUSv3 specifies that -a and -s options cannot be used together
+ * in strictly conforming applications. However, it also says that some
+ * du implementations may produce output when -a and -s are used together.
+ * gnu du exits with an error code in this case. We choose to simply
+ * ignore -a. This is consistent with -s being equivalent to -d 0.
+ */
+#if ENABLE_FEATURE_HUMAN_READABLE
+ opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s";
+ opt = getopt32(argc, argv, "aHkLsx" "d:" "lc" "hm", &smax_print_depth);
+ if (opt & (1 << 9)) {
+ /* -h opt */
+ disp_hr = 0;
+ }
+ if (opt & (1 << 10)) {
+ /* -m opt */
+ disp_hr = 1024*1024;
+ }
+ if (opt & (1 << 2)) {
+ /* -k opt */
+ disp_hr = 1024;
+ }
+#else
+ opt_complementary = "H-L:L-H:s-d:d-s";
+ opt = getopt32(argc, argv, "aHkLsx" "d:" "lc", &smax_print_depth);
+#if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
+ if (opt & (1 << 2)) {
+ /* -k opt */
+ disp_k = 1;
+ }
+#endif
+#endif
+ if (opt & (1 << 0)) {
+ /* -a opt */
+ print_files = INT_MAX;
+ }
+ if (opt & (1 << 1)) {
+ /* -H opt */
+ slink_depth = 1;
+ }
+ if (opt & (1 << 3)) {
+ /* -L opt */
+ slink_depth = INT_MAX;
+ }
+ if (opt & (1 << 4)) {
+ /* -s opt */
+ max_print_depth = 0;
+ }
+ one_file_system = opt & (1 << 5); /* -x opt */
+ if (opt & (1 << 6)) {
+ /* -d opt */
+ max_print_depth = xatoi_u(smax_print_depth);
+ }
+ if (opt & (1 << 7)) {
+ /* -l opt */
+ count_hardlinks = MAXINT(nlink_t);
+ }
+ print_final_total = opt & (1 << 8); /* -c opt */
+
+ /* go through remaining args (if any) */
+ argv += optind;
+ if (optind >= argc) {
+ *--argv = (char*)".";
+ if (slink_depth == 1) {
+ slink_depth = 0;
+ }
+ }
+
+ slink_depth_save = slink_depth;
+ total = 0;
+ do {
+ total += du(*argv);
+ slink_depth = slink_depth_save;
+ } while (*++argv);
+#if ENABLE_FEATURE_CLEAN_UP
+ reset_ino_dev_hashtable();
+#endif
+
+ if (print_final_total) {
+ print(total, "total");
+ }
+
+ fflush_stdout_and_exit(status);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/echo.c b/i/pc104/initrd/conf/busybox/coreutils/echo.c
new file mode 100644
index 0000000..8270fc0
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/echo.c
@@ -0,0 +1,159 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * echo implementation for busybox
+ *
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ * Original copyright notice is retained at the end of this file.
+ */
+
+/* BB_AUDIT SUSv3 compliant -- unless configured as fancy echo. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/echo.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Because of behavioral differences, implemented configurable SUSv3
+ * or 'fancy' gnu-ish behaviors. Also, reduced size and fixed bugs.
+ * 1) In handling '\c' escape, the previous version only suppressed the
+ * trailing newline. SUSv3 specifies _no_ output after '\c'.
+ * 2) SUSv3 specifies that octal escapes are of the form \0{#{#{#}}}.
+ * The previous version version did not allow 4-digit octals.
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "busybox.h"
+
+int bb_echo(char **argv)
+{
+#ifndef CONFIG_FEATURE_FANCY_ECHO
+#define eflag '\\'
+ ++argv;
+#else
+ const char *p;
+ int nflag = 1;
+ int eflag = 0;
+
+ while (*++argv && (**argv == '-')) {
+ /* If it appears that we are handling options, then make sure
+ * that all of the options specified are actually valid.
+ * Otherwise, the string should just be echoed.
+ */
+
+ if (!*(p = *argv + 1)) { /* A single '-', so echo it. */
+ goto just_echo;
+ }
+
+ do {
+ if (strrchr("neE", *p) == 0) {
+ goto just_echo;
+ }
+ } while (*++p);
+
+ /* All of the options in this arg are valid, so handle them. */
+ p = *argv + 1;
+ do {
+ if (*p == 'n') {
+ nflag = 0;
+ } else if (*p == 'e') {
+ eflag = '\\';
+ } else {
+ eflag = 0;
+ }
+ } while (*++p);
+ }
+
+just_echo:
+#endif
+ while (*argv) {
+ int c;
+
+ while ((c = *(*argv)++)) {
+ if (c == eflag) { /* Check for escape seq. */
+ if (**argv == 'c') {
+ /* '\c' means cancel newline and
+ * ignore all subsequent chars. */
+ return 0;
+ }
+#ifndef CONFIG_FEATURE_FANCY_ECHO
+ /* SUSv3 specifies that octal escapes must begin with '0'. */
+ if (((unsigned int)(**argv - '1')) >= 7)
+#endif
+ {
+ /* Since SUSv3 mandates a first digit of 0, 4-digit octals
+ * of the form \0### are accepted. */
+ if ((**argv == '0') && (((unsigned int)(argv[0][1] - '0')) < 8)) {
+ (*argv)++;
+ }
+ /* bb_process_escape_sequence can handle nul correctly */
+ c = bb_process_escape_sequence((const char **) argv);
+ }
+ }
+ putchar(c);
+ }
+
+ if (*++argv) {
+ putchar(' ');
+ }
+ }
+
+#ifdef CONFIG_FEATURE_FANCY_ECHO
+ if (nflag) {
+ putchar('\n');
+ }
+#else
+ putchar('\n');
+#endif
+ return 0;
+}
+
+int echo_main(int argc, char** argv);
+int echo_main(int argc, char** argv)
+{
+ (void)bb_echo(argv);
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+}
+
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Kenneth Almquist.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
+ * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
+ *
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)echo.c 8.1 (Berkeley) 5/31/93
+ */
diff --git a/i/pc104/initrd/conf/busybox/coreutils/env.c b/i/pc104/initrd/conf/busybox/coreutils/env.c
new file mode 100644
index 0000000..f47d450
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/env.c
@@ -0,0 +1,128 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * env implementation for busybox
+ *
+ * Copyright (c) 1988, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ * Original copyright notice is retained at the end of this file.
+ *
+ * Modified for BusyBox by Erik Andersen <andersen@codepoet.org>
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/env.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Fixed bug involving exit return codes if execvp fails. Also added
+ * output error checking.
+ */
+
+/*
+ * Modified by Vladimir Oleynik <dzo@simtreas.ru> (C) 2003
+ * - correct "-" option usage
+ * - multiple "-u unsetenv" support
+ * - GNU long option support
+ * - use xfunc_error_retval
+ */
+
+#include "busybox.h"
+#include <errno.h>
+#include <getopt.h> /* struct option */
+
+#if ENABLE_FEATURE_ENV_LONG_OPTIONS
+static const struct option env_long_options[] = {
+ { "ignore-environment", 0, NULL, 'i' },
+ { "unset", 1, NULL, 'u' },
+ { 0, 0, 0, 0 }
+};
+#endif
+
+int env_main(int argc, char** argv);
+int env_main(int argc, char** argv)
+{
+ /* cleanenv was static - why? */
+ char *cleanenv[1];
+ char **ep;
+ unsigned opt;
+ llist_t *unset_env = NULL;
+ extern char **environ;
+
+ opt_complementary = "u::";
+#if ENABLE_FEATURE_ENV_LONG_OPTIONS
+ applet_long_options = env_long_options;
+#endif
+ opt = getopt32(argc, argv, "+iu:", &unset_env);
+ argv += optind;
+ if (*argv && LONE_DASH(argv[0])) {
+ opt |= 1;
+ ++argv;
+ }
+ if (opt & 1) {
+ cleanenv[0] = NULL;
+ environ = cleanenv;
+ } else if (opt & 2) {
+ while (unset_env) {
+ unsetenv(unset_env->data);
+ unset_env = unset_env->link;
+ }
+ }
+
+ while (*argv && (strchr(*argv, '=') != NULL)) {
+ if (putenv(*argv) < 0) {
+ bb_perror_msg_and_die("putenv");
+ }
+ ++argv;
+ }
+
+ if (*argv) {
+ BB_EXECVP(*argv, argv);
+ /* SUSv3-mandated exit codes. */
+ xfunc_error_retval = (errno == ENOENT) ? 127 : 126;
+ bb_perror_msg_and_die("%s", *argv);
+ }
+
+ for (ep = environ; *ep; ep++) {
+ puts(*ep);
+ }
+
+ fflush_stdout_and_exit(0);
+}
+
+/*
+ * Copyright (c) 1988, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
+ * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
+ *
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
diff --git a/i/pc104/initrd/conf/busybox/coreutils/expr.c b/i/pc104/initrd/conf/busybox/coreutils/expr.c
new file mode 100644
index 0000000..b7e33de
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/expr.c
@@ -0,0 +1,506 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini expr implementation for busybox
+ *
+ * based on GNU expr Mike Parker.
+ * Copyright (C) 86, 1991-1997, 1999 Free Software Foundation, Inc.
+ *
+ * Busybox modifications
+ * Copyright (c) 2000 Edward Betts <edward@debian.org>.
+ * Copyright (C) 2003-2005 Vladimir Oleynik <dzo@simtreas.ru>
+ * - reduced 464 bytes.
+ * - 64 math support
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* This program evaluates expressions. Each token (operator, operand,
+ * parenthesis) of the expression must be a separate argument. The
+ * parser used is a reasonably general one, though any incarnation of
+ * it is language-specific. It is especially nice for expressions.
+ *
+ * No parse tree is needed; a new node is evaluated immediately.
+ * One function can handle multiple operators all of equal precedence,
+ * provided they all associate ((x op x) op x). */
+
+/* no getopt needed */
+
+#include "busybox.h"
+#include "xregex.h"
+
+/* The kinds of value we can have. */
+enum valtype {
+ integer,
+ string
+};
+typedef enum valtype TYPE;
+
+#if ENABLE_EXPR_MATH_SUPPORT_64
+typedef int64_t arith_t;
+
+#define PF_REZ "ll"
+#define PF_REZ_TYPE (long long)
+#define STRTOL(s, e, b) strtoll(s, e, b)
+#else
+typedef long arith_t;
+
+#define PF_REZ "l"
+#define PF_REZ_TYPE (long)
+#define STRTOL(s, e, b) strtol(s, e, b)
+#endif
+
+/* TODO: use bb_strtol[l]? It's easier to check for errors... */
+
+/* A value is.... */
+struct valinfo {
+ TYPE type; /* Which kind. */
+ union { /* The value itself. */
+ arith_t i;
+ char *s;
+ } u;
+};
+typedef struct valinfo VALUE;
+
+/* The arguments given to the program, minus the program name. */
+static char **args;
+
+static VALUE *docolon(VALUE * sv, VALUE * pv);
+static VALUE *eval(void);
+static VALUE *int_value(arith_t i);
+static VALUE *str_value(const char *s);
+static int nextarg(const char *str);
+static int null(VALUE * v);
+static int toarith(VALUE * v);
+static void freev(VALUE * v);
+static void tostring(VALUE * v);
+
+int expr_main(int argc, char **argv);
+int expr_main(int argc, char **argv)
+{
+ VALUE *v;
+
+ if (argc == 1) {
+ bb_error_msg_and_die("too few arguments");
+ }
+
+ args = argv + 1;
+
+ v = eval();
+ if (*args)
+ bb_error_msg_and_die("syntax error");
+
+ if (v->type == integer)
+ printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i);
+ else
+ puts(v->u.s);
+
+ fflush_stdout_and_exit(null(v));
+}
+
+/* Return a VALUE for I. */
+
+static VALUE *int_value(arith_t i)
+{
+ VALUE *v;
+
+ v = xmalloc(sizeof(VALUE));
+ v->type = integer;
+ v->u.i = i;
+ return v;
+}
+
+/* Return a VALUE for S. */
+
+static VALUE *str_value(const char *s)
+{
+ VALUE *v;
+
+ v = xmalloc(sizeof(VALUE));
+ v->type = string;
+ v->u.s = xstrdup(s);
+ return v;
+}
+
+/* Free VALUE V, including structure components. */
+
+static void freev(VALUE * v)
+{
+ if (v->type == string)
+ free(v->u.s);
+ free(v);
+}
+
+/* Return nonzero if V is a null-string or zero-number. */
+
+static int null(VALUE * v)
+{
+ if (v->type == integer)
+ return v->u.i == 0;
+ /* string: */
+ return v->u.s[0] == '\0' || LONE_CHAR(v->u.s, '0');
+}
+
+/* Coerce V to a string value (can't fail). */
+
+static void tostring(VALUE * v)
+{
+ if (v->type == integer) {
+ v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i);
+ v->type = string;
+ }
+}
+
+/* Coerce V to an integer value. Return 1 on success, 0 on failure. */
+
+static int toarith(VALUE * v)
+{
+ if (v->type == string) {
+ arith_t i;
+ char *e;
+
+ /* Don't interpret the empty string as an integer. */
+ /* Currently does not worry about overflow or int/long differences. */
+ i = STRTOL(v->u.s, &e, 10);
+ if ((v->u.s == e) || *e)
+ return 0;
+ free(v->u.s);
+ v->u.i = i;
+ v->type = integer;
+ }
+ return 1;
+}
+
+/* Return nonzero if the next token matches STR exactly.
+ STR must not be NULL. */
+
+static int nextarg(const char *str)
+{
+ if (*args == NULL)
+ return 0;
+ return strcmp(*args, str) == 0;
+}
+
+/* The comparison operator handling functions. */
+
+static int cmp_common(VALUE * l, VALUE * r, int op)
+{
+ int cmpval;
+
+ if (l->type == string || r->type == string) {
+ tostring(l);
+ tostring(r);
+ cmpval = strcmp(l->u.s, r->u.s);
+ } else
+ cmpval = l->u.i - r->u.i;
+ if (op == '<')
+ return cmpval < 0;
+ if (op == ('L' + 'E'))
+ return cmpval <= 0;
+ if (op == '=')
+ return cmpval == 0;
+ if (op == '!')
+ return cmpval != 0;
+ if (op == '>')
+ return cmpval > 0;
+ /* >= */
+ return cmpval >= 0;
+}
+
+/* The arithmetic operator handling functions. */
+
+static arith_t arithmetic_common(VALUE * l, VALUE * r, int op)
+{
+ arith_t li, ri;
+
+ if (!toarith(l) || !toarith(r))
+ bb_error_msg_and_die("non-numeric argument");
+ li = l->u.i;
+ ri = r->u.i;
+ if ((op == '/' || op == '%') && ri == 0)
+ bb_error_msg_and_die("division by zero");
+ if (op == '+')
+ return li + ri;
+ else if (op == '-')
+ return li - ri;
+ else if (op == '*')
+ return li * ri;
+ else if (op == '/')
+ return li / ri;
+ else
+ return li % ri;
+}
+
+/* Do the : operator.
+ SV is the VALUE for the lhs (the string),
+ PV is the VALUE for the rhs (the pattern). */
+
+static VALUE *docolon(VALUE * sv, VALUE * pv)
+{
+ VALUE *v;
+ regex_t re_buffer;
+ const int NMATCH = 2;
+ regmatch_t re_regs[NMATCH];
+
+ tostring(sv);
+ tostring(pv);
+
+ if (pv->u.s[0] == '^') {
+ fprintf(stderr, "\
+warning: unportable BRE: `%s': using `^' as the first character\n\
+of a basic regular expression is not portable; it is being ignored", pv->u.s);
+ }
+
+ memset(&re_buffer, 0, sizeof(re_buffer));
+ memset(re_regs, 0, sizeof(*re_regs));
+ if (regcomp(&re_buffer, pv->u.s, 0) != 0)
+ bb_error_msg_and_die("invalid regular expression");
+
+ /* expr uses an anchored pattern match, so check that there was a
+ * match and that the match starts at offset 0. */
+ if (regexec(&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH &&
+ re_regs[0].rm_so == 0) {
+ /* Were \(...\) used? */
+ if (re_buffer.re_nsub > 0) {
+ sv->u.s[re_regs[1].rm_eo] = '\0';
+ v = str_value(sv->u.s + re_regs[1].rm_so);
+ } else
+ v = int_value(re_regs[0].rm_eo);
+ } else {
+ /* Match failed -- return the right kind of null. */
+ if (re_buffer.re_nsub > 0)
+ v = str_value("");
+ else
+ v = int_value(0);
+ }
+ return v;
+}
+
+/* Handle bare operands and ( expr ) syntax. */
+
+static VALUE *eval7(void)
+{
+ VALUE *v;
+
+ if (!*args)
+ bb_error_msg_and_die("syntax error");
+
+ if (nextarg("(")) {
+ args++;
+ v = eval();
+ if (!nextarg(")"))
+ bb_error_msg_and_die("syntax error");
+ args++;
+ return v;
+ }
+
+ if (nextarg(")"))
+ bb_error_msg_and_die("syntax error");
+
+ return str_value(*args++);
+}
+
+/* Handle match, substr, index, length, and quote keywords. */
+
+static VALUE *eval6(void)
+{
+ VALUE *l, *r, *v, *i1, *i2;
+
+ if (nextarg("quote")) {
+ args++;
+ if (!*args)
+ bb_error_msg_and_die("syntax error");
+ return str_value(*args++);
+ } else if (nextarg("length")) {
+ args++;
+ r = eval6();
+ tostring(r);
+ v = int_value(strlen(r->u.s));
+ freev(r);
+ return v;
+ } else if (nextarg("match")) {
+ args++;
+ l = eval6();
+ r = eval6();
+ v = docolon(l, r);
+ freev(l);
+ freev(r);
+ return v;
+ } else if (nextarg("index")) {
+ args++;
+ l = eval6();
+ r = eval6();
+ tostring(l);
+ tostring(r);
+ v = int_value(strcspn(l->u.s, r->u.s) + 1);
+ if (v->u.i == (arith_t) strlen(l->u.s) + 1)
+ v->u.i = 0;
+ freev(l);
+ freev(r);
+ return v;
+ } else if (nextarg("substr")) {
+ args++;
+ l = eval6();
+ i1 = eval6();
+ i2 = eval6();
+ tostring(l);
+ if (!toarith(i1) || !toarith(i2)
+ || i1->u.i > (arith_t) strlen(l->u.s)
+ || i1->u.i <= 0 || i2->u.i <= 0)
+ v = str_value("");
+ else {
+ v = xmalloc(sizeof(VALUE));
+ v->type = string;
+ v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i);
+ }
+ freev(l);
+ freev(i1);
+ freev(i2);
+ return v;
+ } else
+ return eval7();
+}
+
+/* Handle : operator (pattern matching).
+ Calls docolon to do the real work. */
+
+static VALUE *eval5(void)
+{
+ VALUE *l, *r, *v;
+
+ l = eval6();
+ while (nextarg(":")) {
+ args++;
+ r = eval6();
+ v = docolon(l, r);
+ freev(l);
+ freev(r);
+ l = v;
+ }
+ return l;
+}
+
+/* Handle *, /, % operators. */
+
+static VALUE *eval4(void)
+{
+ VALUE *l, *r;
+ int op;
+ arith_t val;
+
+ l = eval5();
+ while (1) {
+ if (nextarg("*"))
+ op = '*';
+ else if (nextarg("/"))
+ op = '/';
+ else if (nextarg("%"))
+ op = '%';
+ else
+ return l;
+ args++;
+ r = eval5();
+ val = arithmetic_common(l, r, op);
+ freev(l);
+ freev(r);
+ l = int_value(val);
+ }
+}
+
+/* Handle +, - operators. */
+
+static VALUE *eval3(void)
+{
+ VALUE *l, *r;
+ int op;
+ arith_t val;
+
+ l = eval4();
+ while (1) {
+ if (nextarg("+"))
+ op = '+';
+ else if (nextarg("-"))
+ op = '-';
+ else
+ return l;
+ args++;
+ r = eval4();
+ val = arithmetic_common(l, r, op);
+ freev(l);
+ freev(r);
+ l = int_value(val);
+ }
+}
+
+/* Handle comparisons. */
+
+static VALUE *eval2(void)
+{
+ VALUE *l, *r;
+ int op;
+ arith_t val;
+
+ l = eval3();
+ while (1) {
+ if (nextarg("<"))
+ op = '<';
+ else if (nextarg("<="))
+ op = 'L' + 'E';
+ else if (nextarg("=") || nextarg("=="))
+ op = '=';
+ else if (nextarg("!="))
+ op = '!';
+ else if (nextarg(">="))
+ op = 'G' + 'E';
+ else if (nextarg(">"))
+ op = '>';
+ else
+ return l;
+ args++;
+ r = eval3();
+ toarith(l);
+ toarith(r);
+ val = cmp_common(l, r, op);
+ freev(l);
+ freev(r);
+ l = int_value(val);
+ }
+}
+
+/* Handle &. */
+
+static VALUE *eval1(void)
+{
+ VALUE *l, *r;
+
+ l = eval2();
+ while (nextarg("&")) {
+ args++;
+ r = eval2();
+ if (null(l) || null(r)) {
+ freev(l);
+ freev(r);
+ l = int_value(0);
+ } else
+ freev(r);
+ }
+ return l;
+}
+
+/* Handle |. */
+
+static VALUE *eval(void)
+{
+ VALUE *l, *r;
+
+ l = eval1();
+ while (nextarg("|")) {
+ args++;
+ r = eval1();
+ if (null(l)) {
+ freev(l);
+ l = r;
+ } else
+ freev(r);
+ }
+ return l;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/false.c b/i/pc104/initrd/conf/busybox/coreutils/false.c
new file mode 100644
index 0000000..2a26e0e
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/false.c
@@ -0,0 +1,20 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini false implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/false.html */
+
+#include <stdlib.h>
+#include "busybox.h"
+
+int false_main(int ATTRIBUTE_UNUSED argc, char ATTRIBUTE_UNUSED **argv);
+int false_main(int ATTRIBUTE_UNUSED argc, char ATTRIBUTE_UNUSED **argv)
+{
+ return EXIT_FAILURE;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/fold.c b/i/pc104/initrd/conf/busybox/coreutils/fold.c
new file mode 100644
index 0000000..4ce52cf
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/fold.c
@@ -0,0 +1,155 @@
+/* vi: set sw=4 ts=4: */
+/* fold -- wrap each input line to fit in specified width.
+
+ Written by David MacKenzie, djm@gnu.ai.mit.edu.
+ Copyright (C) 91, 1995-2002 Free Software Foundation, Inc.
+
+ Modified for busybox based on coreutils v 5.0
+ Copyright (C) 2003 Glenn McGrath <bug1@iinet.net.au>
+
+ Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+*/
+
+#include "busybox.h"
+
+static unsigned long flags;
+#define FLAG_COUNT_BYTES 1
+#define FLAG_BREAK_SPACES 2
+#define FLAG_WIDTH 4
+
+/* Assuming the current column is COLUMN, return the column that
+ printing C will move the cursor to.
+ The first column is 0. */
+
+static int adjust_column(int column, char c)
+{
+ if (!(flags & FLAG_COUNT_BYTES)) {
+ if (c == '\b') {
+ if (column > 0)
+ column--;
+ } else if (c == '\r')
+ column = 0;
+ else if (c == '\t')
+ column = column + 8 - column % 8;
+ else /* if (isprint (c)) */
+ column++;
+ } else
+ column++;
+ return column;
+}
+
+int fold_main(int argc, char **argv);
+int fold_main(int argc, char **argv)
+{
+ char *w_opt;
+ int width = 80;
+ int i;
+ int errs = 0;
+
+ if (ENABLE_INCLUDE_SUSv2) {
+ /* Turn any numeric options into -w options. */
+ for (i = 1; i < argc; i++) {
+ char const *a = argv[i];
+
+ if (*a++ == '-') {
+ if (*a == '-' && !a[1])
+ break;
+ if (isdigit(*a)) {
+ argv[i] = xasprintf("-w%s", a);
+ }
+ }
+ }
+ }
+
+ flags = getopt32(argc, argv, "bsw:", &w_opt);
+ if (flags & FLAG_WIDTH)
+ width = xatoul_range(w_opt, 1, 10000);
+
+ argv += optind;
+ if (!*argv) {
+ *--argv = (char*)"-";
+ }
+
+ do {
+ FILE *istream = fopen_or_warn_stdin(*argv);
+ int c;
+ int column = 0; /* Screen column where next char will go. */
+ int offset_out = 0; /* Index in `line_out' for next char. */
+ static char *line_out = NULL;
+ static int allocated_out = 0;
+
+ if (istream == NULL) {
+ errs |= EXIT_FAILURE;
+ continue;
+ }
+
+ while ((c = getc(istream)) != EOF) {
+ if (offset_out + 1 >= allocated_out) {
+ allocated_out += 1024;
+ line_out = xrealloc(line_out, allocated_out);
+ }
+
+ if (c == '\n') {
+ line_out[offset_out++] = c;
+ fwrite(line_out, sizeof(char), (size_t) offset_out, stdout);
+ column = offset_out = 0;
+ continue;
+ }
+
+rescan:
+ column = adjust_column(column, c);
+
+ if (column > width) {
+ /* This character would make the line too long.
+ Print the line plus a newline, and make this character
+ start the next line. */
+ if (flags & FLAG_BREAK_SPACES) {
+ /* Look for the last blank. */
+ int logical_end;
+
+ for (logical_end = offset_out - 1; logical_end >= 0; logical_end--) {
+ if (isblank(line_out[logical_end])) {
+ break;
+ }
+ }
+ if (logical_end >= 0) {
+ /* Found a blank. Don't output the part after it. */
+ logical_end++;
+ fwrite(line_out, sizeof(char), (size_t) logical_end, stdout);
+ putchar('\n');
+ /* Move the remainder to the beginning of the next line.
+ The areas being copied here might overlap. */
+ memmove(line_out, line_out + logical_end, offset_out - logical_end);
+ offset_out -= logical_end;
+ for (column = i = 0; i < offset_out; i++) {
+ column = adjust_column(column, line_out[i]);
+ }
+ goto rescan;
+ }
+ } else {
+ if (offset_out == 0) {
+ line_out[offset_out++] = c;
+ continue;
+ }
+ }
+ line_out[offset_out++] = '\n';
+ fwrite(line_out, sizeof(char), (size_t) offset_out, stdout);
+ column = offset_out = 0;
+ goto rescan;
+ }
+
+ line_out[offset_out++] = c;
+ }
+
+ if (offset_out) {
+ fwrite(line_out, sizeof(char), (size_t) offset_out, stdout);
+ }
+
+ if (ferror(istream) || fclose_if_not_stdin(istream)) {
+ bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */
+ errs |= EXIT_FAILURE;
+ }
+ } while (*++argv);
+
+ fflush_stdout_and_exit(errs);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/head.c b/i/pc104/initrd/conf/busybox/coreutils/head.c
new file mode 100644
index 0000000..ed1d01d
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/head.c
@@ -0,0 +1,140 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * head implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* BB_AUDIT GNU compatible -c, -q, and -v options in 'fancy' configuration. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/head.html */
+
+#include "busybox.h"
+
+static const char head_opts[] =
+ "n:"
+#if ENABLE_FEATURE_FANCY_HEAD
+ "c:qv"
+#endif
+ ;
+
+#if ENABLE_FEATURE_FANCY_HEAD
+static const struct suffix_mult head_suffixes[] = {
+ { "b", 512 },
+ { "k", 1024 },
+ { "m", 1024*1024 },
+ { NULL, 0 }
+};
+#endif
+
+static const char header_fmt_str[] = "\n==> %s <==\n";
+
+int head_main(int argc, char **argv);
+int head_main(int argc, char **argv)
+{
+ unsigned long count = 10;
+ unsigned long i;
+#if ENABLE_FEATURE_FANCY_HEAD
+ int count_bytes = 0;
+ int header_threshhold = 1;
+#endif
+
+ FILE *fp;
+ const char *fmt;
+ char *p;
+ int opt;
+ int c;
+ int retval = EXIT_SUCCESS;
+
+#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
+ /* Allow legacy syntax of an initial numeric option without -n. */
+ if (argc > 1 && argv[1][0] == '-'
+ && isdigit(argv[1][1])
+ ) {
+ --argc;
+ ++argv;
+ p = (*argv) + 1;
+ goto GET_COUNT;
+ }
+#endif
+
+ /* No size benefit in converting this to getopt32 */
+ while ((opt = getopt(argc, argv, head_opts)) > 0) {
+ switch (opt) {
+#if ENABLE_FEATURE_FANCY_HEAD
+ case 'q':
+ header_threshhold = INT_MAX;
+ break;
+ case 'v':
+ header_threshhold = -1;
+ break;
+ case 'c':
+ count_bytes = 1;
+ /* fall through */
+#endif
+ case 'n':
+ p = optarg;
+#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
+ GET_COUNT:
+#endif
+
+#if !ENABLE_FEATURE_FANCY_HEAD
+ count = xatoul(p);
+#else
+ count = xatoul_sfx(p, head_suffixes);
+#endif
+ break;
+ default:
+ bb_show_usage();
+ }
+ }
+
+ argv += optind;
+ if (!*argv) {
+ *--argv = (char*)"-";
+ }
+
+ fmt = header_fmt_str + 1;
+#if ENABLE_FEATURE_FANCY_HEAD
+ if (argc - optind <= header_threshhold) {
+ header_threshhold = 0;
+ }
+#else
+ if (argc <= optind + 1) {
+ fmt += 11;
+ }
+ /* Now define some things here to avoid #ifdefs in the code below.
+ * These should optimize out of the if conditions below. */
+#define header_threshhold 1
+#define count_bytes 0
+#endif
+
+ do {
+ fp = fopen_or_warn_stdin(*argv);
+ if (fp) {
+ if (fp == stdin) {
+ *argv = (char *) bb_msg_standard_input;
+ }
+ if (header_threshhold) {
+ printf(fmt, *argv);
+ }
+ i = count;
+ while (i && ((c = getc(fp)) != EOF)) {
+ if (count_bytes || (c == '\n')) {
+ --i;
+ }
+ putchar(c);
+ }
+ if (fclose_if_not_stdin(fp)) {
+ bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */
+ retval = EXIT_FAILURE;
+ }
+ die_if_ferror_stdout();
+ }
+ fmt = header_fmt_str;
+ } while (*++argv);
+
+ fflush_stdout_and_exit(retval);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/hostid.c b/i/pc104/initrd/conf/busybox/coreutils/hostid.c
new file mode 100644
index 0000000..51a76c6
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/hostid.c
@@ -0,0 +1,26 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini hostid implementation for busybox
+ *
+ * Copyright (C) 2000 Edward Betts <edward@debian.org>.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "busybox.h"
+
+int hostid_main(int argc, char ATTRIBUTE_UNUSED **argv);
+int hostid_main(int argc, char ATTRIBUTE_UNUSED **argv)
+{
+ if (argc > 1) {
+ bb_show_usage();
+ }
+
+ printf("%lx\n", gethostid());
+
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/id.c b/i/pc104/initrd/conf/busybox/coreutils/id.c
new file mode 100644
index 0000000..8a60419
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/id.c
@@ -0,0 +1,130 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini id implementation for busybox
+ *
+ * Copyright (C) 2000 by Randolph Chung <tausq@debian.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */
+/* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to
+ * be more similar to GNU id.
+ * -Z option support: by Yuichi Nakamura <ynakam@hitachisoft.jp>
+ */
+
+#include "busybox.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#define PRINT_REAL 1
+#define NAME_NOT_NUMBER 2
+#define JUST_USER 4
+#define JUST_GROUP 8
+#if ENABLE_SELINUX
+#define JUST_CONTEXT 16
+#endif
+
+static short printf_full(unsigned int id, const char *arg, const char prefix)
+{
+ const char *fmt = "%cid=%u";
+ short status = EXIT_FAILURE;
+
+ if (arg) {
+ fmt = "%cid=%u(%s)";
+ status = EXIT_SUCCESS;
+ }
+ printf(fmt, prefix, id, arg);
+ return status;
+}
+
+int id_main(int argc, char **argv);
+int id_main(int argc, char **argv)
+{
+ struct passwd *p;
+ uid_t uid;
+ gid_t gid;
+ unsigned long flags;
+ short status;
+#if ENABLE_SELINUX
+ security_context_t scontext;
+#endif
+ /* Don't allow -n -r -nr -ug -rug -nug -rnug */
+ /* Don't allow more than one username */
+ opt_complementary = "?1:?:u--g:g--u:r?ug:n?ug" USE_SELINUX(":u--Z:Z--u:g--Z:Z--g");
+ flags = getopt32(argc, argv, "rnug" USE_SELINUX("Z"));
+
+ /* This values could be overwritten later */
+ uid = geteuid();
+ gid = getegid();
+ if (flags & PRINT_REAL) {
+ uid = getuid();
+ gid = getgid();
+ }
+
+ if (argv[optind]) {
+ p = getpwnam(argv[optind]);
+ /* xuname2uid is needed because it exits on failure */
+ uid = xuname2uid(argv[optind]);
+ gid = p->pw_gid;
+ /* in this case PRINT_REAL is the same */
+ }
+
+ if (flags & (JUST_GROUP | JUST_USER USE_SELINUX(| JUST_CONTEXT))) {
+ /* JUST_GROUP and JUST_USER are mutually exclusive */
+ if (flags & NAME_NOT_NUMBER) {
+ /* bb_getpwuid and bb_getgrgid exit on failure so puts cannot segfault */
+ puts((flags & JUST_USER) ? bb_getpwuid(NULL, uid, -1 ) : bb_getgrgid(NULL, gid, -1 ));
+ } else {
+ if (flags & JUST_USER) {
+ printf("%u\n", uid);
+ }
+ if (flags & JUST_GROUP) {
+ printf("%u\n", gid);
+ }
+ }
+
+#if ENABLE_SELINUX
+ if (flags & JUST_CONTEXT) {
+ selinux_or_die();
+ if (argc - optind == 1) {
+ bb_error_msg_and_die("user name can't be passed with -Z");
+ }
+
+ if (getcon(&scontext)) {
+ bb_error_msg_and_die("can't get process context");
+ }
+ printf("%s\n", scontext);
+ }
+#endif
+ /* exit */
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+ }
+
+ /* Print full info like GNU id */
+ /* bb_getpwuid doesn't exit on failure here */
+ status = printf_full(uid, bb_getpwuid(NULL, uid, 0), 'u');
+ putchar(' ');
+ /* bb_getgrgid doesn't exit on failure here */
+ status |= printf_full(gid, bb_getgrgid(NULL, gid, 0), 'g');
+
+#if ENABLE_SELINUX
+ if (is_selinux_enabled()) {
+ security_context_t mysid;
+ const char *context;
+
+ context = "unknown";
+ getcon(&mysid);
+ if (mysid) {
+ context = alloca(strlen(mysid) + 1);
+ strcpy((char*)context, mysid);
+ freecon(mysid);
+ }
+ printf(" context=%s", context);
+ }
+#endif
+
+ putchar('\n');
+ fflush_stdout_and_exit(status);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/install.c b/i/pc104/initrd/conf/busybox/coreutils/install.c
new file mode 100644
index 0000000..c80be01
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/install.c
@@ -0,0 +1,202 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Copyright (C) 2003 by Glenn McGrath <bug1@iinet.net.au>
+ * SELinux support: by Yuichi Nakamura <ynakam@hitachisoft.jp>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ * TODO: -d option, need a way of recursively making directories and changing
+ * owner/group, will probably modify bb_make_directory(...)
+ */
+
+#include "busybox.h"
+#include "libcoreutils/coreutils.h"
+#include <libgen.h>
+#include <getopt.h> /* struct option */
+
+#if ENABLE_FEATURE_INSTALL_LONG_OPTIONS
+static const struct option install_long_options[] = {
+ { "directory", 0, NULL, 'd' },
+ { "preserve-timestamps", 0, NULL, 'p' },
+ { "strip", 0, NULL, 's' },
+ { "group", 0, NULL, 'g' },
+ { "mode", 0, NULL, 'm' },
+ { "owner", 0, NULL, 'o' },
+#if ENABLE_SELINUX
+ { "context", 1, NULL, 'Z' },
+ { "preserve_context", 0, NULL, 0xff },
+ { "preserve-context", 0, NULL, 0xff },
+#endif
+ { 0, 0, 0, 0 }
+};
+#endif
+
+
+#if ENABLE_SELINUX
+static bool use_default_selinux_context = 1;
+
+static void setdefaultfilecon(const char *path) {
+ struct stat s;
+ security_context_t scontext = NULL;
+
+ if (!is_selinux_enabled()) {
+ return;
+ }
+ if (lstat(path, &s) != 0) {
+ return;
+ }
+
+ if (matchpathcon(path, s.st_mode, &scontext) < 0) {
+ goto out;
+ }
+ if (strcmp(scontext, "<<none>>") == 0) {
+ goto out;
+ }
+
+ if (lsetfilecon(path, scontext) < 0) {
+ if (errno != ENOTSUP) {
+ bb_perror_msg("warning: failed to change context of %s to %s", path, scontext);
+ }
+ }
+
+ out:
+ freecon(scontext);
+}
+
+#endif
+
+int install_main(int argc, char **argv);
+int install_main(int argc, char **argv)
+{
+ struct stat statbuf;
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+ const char *gid_str;
+ const char *uid_str;
+ const char *mode_str;
+ int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE;
+ int ret = EXIT_SUCCESS, flags, i, isdir;
+#if ENABLE_SELINUX
+ security_context_t scontext;
+#endif
+ enum {
+ OPT_CMD = 0x1,
+ OPT_DIRECTORY = 0x2,
+ OPT_PRESERVE_TIME = 0x4,
+ OPT_STRIP = 0x8,
+ OPT_GROUP = 0x10,
+ OPT_MODE = 0x20,
+ OPT_OWNER = 0x40,
+#if ENABLE_SELINUX
+ OPT_SET_SECURITY_CONTEXT = 0x80,
+ OPT_PRESERVE_SECURITY_CONTEXT = 0x100,
+#endif
+ };
+
+#if ENABLE_FEATURE_INSTALL_LONG_OPTIONS
+ applet_long_options = install_long_options;
+#endif
+ opt_complementary = "?:s--d:d--s" USE_SELINUX(":Z--\xff:\xff--Z");
+ /* -c exists for backwards compatibility, it's needed */
+
+ flags = getopt32(argc, argv, "cdpsg:m:o:" USE_SELINUX("Z:"), &gid_str, &mode_str, &uid_str USE_SELINUX(, &scontext));
+
+#if ENABLE_SELINUX
+ if (flags & OPT_PRESERVE_SECURITY_CONTEXT) {
+ use_default_selinux_context = 0;
+ copy_flags |= FILEUTILS_PRESERVE_SECURITY_CONTEXT;
+ selinux_or_die();
+ }
+ if (flags & OPT_SET_SECURITY_CONTEXT) {
+ selinux_or_die();
+ setfscreatecon_or_die(scontext);
+ use_default_selinux_context = 0;
+ copy_flags |= FILEUTILS_SET_SECURITY_CONTEXT;
+ }
+#endif
+
+ /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */
+ if (flags & OPT_PRESERVE_TIME) {
+ copy_flags |= FILEUTILS_PRESERVE_STATUS;
+ }
+ mode = 0666;
+ if (flags & OPT_MODE) bb_parse_mode(mode_str, &mode);
+ uid = (flags & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid();
+ gid = (flags & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid();
+ if (flags & (OPT_OWNER|OPT_GROUP)) umask(0);
+
+ /* Create directories
+ * don't use bb_make_directory() as it can't change uid or gid
+ * perhaps bb_make_directory() should be improved.
+ */
+ if (flags & OPT_DIRECTORY) {
+ for (argv += optind; *argv; argv++) {
+ char *old_argv_ptr = *argv + 1;
+ char *argv_ptr;
+ do {
+ argv_ptr = strchr(old_argv_ptr, '/');
+ old_argv_ptr = argv_ptr;
+ if (argv_ptr) {
+ *argv_ptr = '\0';
+ old_argv_ptr++;
+ }
+ if (mkdir(*argv, mode | 0111) == -1) {
+ if (errno != EEXIST) {
+ bb_perror_msg("cannot create %s", *argv);
+ ret = EXIT_FAILURE;
+ break;
+ }
+ }
+ if ((flags & (OPT_OWNER|OPT_GROUP))
+ && lchown(*argv, uid, gid) == -1
+ ) {
+ bb_perror_msg("cannot change ownership of %s", *argv);
+ ret = EXIT_FAILURE;
+ break;
+ }
+ if (argv_ptr) {
+ *argv_ptr = '/';
+ }
+ } while (old_argv_ptr);
+ }
+ return ret;
+ }
+
+ isdir = lstat(argv[argc - 1], &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode);
+
+ for (i = optind; i < argc - 1; i++) {
+ char *dest;
+
+ dest = argv[argc - 1];
+ if (isdir)
+ dest = concat_path_file(argv[argc - 1], basename(argv[i]));
+ ret |= copy_file(argv[i], dest, copy_flags);
+
+ /* Set the file mode */
+ if ((flags & OPT_MODE) && chmod(dest, mode) == -1) {
+ bb_perror_msg("cannot change permissions of %s", dest);
+ ret = EXIT_FAILURE;
+ }
+#if ENABLE_SELINUX
+ if (use_default_selinux_context)
+ setdefaultfilecon(dest);
+#endif
+ /* Set the user and group id */
+ if ((flags & (OPT_OWNER|OPT_GROUP))
+ && lchown(dest, uid, gid) == -1
+ ) {
+ bb_perror_msg("cannot change ownership of %s", dest);
+ ret = EXIT_FAILURE;
+ }
+ if (flags & OPT_STRIP) {
+ if (BB_EXECLP("strip", "strip", dest, NULL) == -1) {
+ bb_perror_msg("strip");
+ ret = EXIT_FAILURE;
+ }
+ }
+ if (ENABLE_FEATURE_CLEAN_UP && isdir) free(dest);
+ }
+
+ return ret;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/length.c b/i/pc104/initrd/conf/busybox/coreutils/length.c
new file mode 100644
index 0000000..1dc122c
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/length.c
@@ -0,0 +1,20 @@
+/* vi: set sw=4 ts=4: */
+
+/* BB_AUDIT SUSv3 N/A -- Apparently a busybox (obsolete?) extension. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "busybox.h"
+
+int length_main(int argc, char **argv);
+int length_main(int argc, char **argv)
+{
+ if ((argc != 2) || (**(++argv) == '-')) {
+ bb_show_usage();
+ }
+
+ printf("%lu\n", (unsigned long)strlen(*argv));
+
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/Kbuild b/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/Kbuild
new file mode 100644
index 0000000..755d01f
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/Kbuild
@@ -0,0 +1,12 @@
+# Makefile for busybox
+#
+# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+#
+# Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+
+lib-y:=
+lib-$(CONFIG_MKFIFO) += getopt_mk_fifo_nod.o
+lib-$(CONFIG_MKNOD) += getopt_mk_fifo_nod.o
+lib-$(CONFIG_INSTALL) += cp_mv_stat.o
+lib-$(CONFIG_CP) += cp_mv_stat.o
+lib-$(CONFIG_MV) += cp_mv_stat.o
diff --git a/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/coreutils.h b/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/coreutils.h
new file mode 100644
index 0000000..102c7b5
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/coreutils.h
@@ -0,0 +1,16 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+ */
+
+#ifndef COREUTILS_H
+#define COREUTILS_H 1
+
+typedef int (*stat_func)(const char *fn, struct stat *ps);
+
+extern int cp_mv_stat2(const char *fn, struct stat *fn_stat, stat_func sf);
+extern int cp_mv_stat(const char *fn, struct stat *fn_stat);
+
+extern mode_t getopt_mk_fifo_nod(int argc, char **argv);
+
+#endif
diff --git a/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/cp_mv_stat.c b/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/cp_mv_stat.c
new file mode 100644
index 0000000..2e4f25e
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/cp_mv_stat.c
@@ -0,0 +1,43 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * coreutils utility routine
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "libbb.h"
+#include "coreutils.h"
+
+int cp_mv_stat2(const char *fn, struct stat *fn_stat, stat_func sf)
+{
+ if (sf(fn, fn_stat) < 0) {
+ if (errno != ENOENT) {
+ bb_perror_msg("cannot stat '%s'", fn);
+ return -1;
+ }
+ return 0;
+ } else if (S_ISDIR(fn_stat->st_mode)) {
+ return 3;
+ }
+ return 1;
+}
+
+int cp_mv_stat(const char *fn, struct stat *fn_stat)
+{
+ return cp_mv_stat2(fn, fn_stat, stat);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/getopt_mk_fifo_nod.c b/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/getopt_mk_fifo_nod.c
new file mode 100644
index 0000000..32fa9be
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/libcoreutils/getopt_mk_fifo_nod.c
@@ -0,0 +1,51 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * coreutils utility routine
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include "libbb.h"
+#include "coreutils.h"
+
+mode_t getopt_mk_fifo_nod(int argc, char **argv)
+{
+ mode_t mode = 0666;
+ char *smode = NULL;
+#if ENABLE_SELINUX
+ security_context_t scontext;
+#endif
+ int opt;
+ opt = getopt32(argc, argv, "m:" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext));
+ if (opt & 1) {
+ if (bb_parse_mode(smode, &mode))
+ umask(0);
+ }
+
+#if ENABLE_SELINUX
+ if (opt & 2) {
+ selinux_or_die();
+ setfscreatecon_or_die(scontext);
+ }
+#endif
+
+ return mode;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/ln.c b/i/pc104/initrd/conf/busybox/coreutils/ln.c
new file mode 100644
index 0000000..7207134
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/ln.c
@@ -0,0 +1,105 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini ln implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* BB_AUDIT GNU options missing: -d, -F, -i, and -v. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/ln.html */
+
+#include "busybox.h"
+
+#define LN_SYMLINK 1
+#define LN_FORCE 2
+#define LN_NODEREFERENCE 4
+#define LN_BACKUP 8
+#define LN_SUFFIX 16
+
+int ln_main(int argc, char **argv);
+int ln_main(int argc, char **argv)
+{
+ int status = EXIT_SUCCESS;
+ int flag;
+ char *last;
+ char *src_name;
+ char *src;
+ char *suffix = (char*)"~";
+ struct stat statbuf;
+ int (*link_func)(const char *, const char *);
+
+ flag = getopt32(argc, argv, "sfnbS:", &suffix);
+
+ if (argc == optind) {
+ bb_show_usage();
+ }
+
+ last = argv[argc - 1];
+ argv += optind;
+
+ if (argc == optind + 1) {
+ *--argv = last;
+ last = bb_get_last_path_component(xstrdup(last));
+ }
+
+ do {
+ src_name = NULL;
+ src = last;
+
+ if (is_directory(src,
+ (flag & LN_NODEREFERENCE) ^ LN_NODEREFERENCE,
+ NULL)) {
+ src_name = xstrdup(*argv);
+ src = concat_path_file(src, bb_get_last_path_component(src_name));
+ free(src_name);
+ src_name = src;
+ }
+ if (!(flag & LN_SYMLINK) && stat(*argv, &statbuf)) {
+ // coreutils: "ln dangling_symlink new_hardlink" works
+ if (lstat(*argv, &statbuf) || !S_ISLNK(statbuf.st_mode)) {
+ bb_perror_msg("%s", *argv);
+ status = EXIT_FAILURE;
+ free(src_name);
+ continue;
+ }
+ }
+
+ if (flag & LN_BACKUP) {
+ char *backup;
+ backup = xasprintf("%s%s", src, suffix);
+ if (rename(src, backup) < 0 && errno != ENOENT) {
+ bb_perror_msg("%s", src);
+ status = EXIT_FAILURE;
+ free(backup);
+ continue;
+ }
+ free(backup);
+ /*
+ * When the source and dest are both hard links to the same
+ * inode, a rename may succeed even though nothing happened.
+ * Therefore, always unlink().
+ */
+ unlink(src);
+ } else if (flag & LN_FORCE) {
+ unlink(src);
+ }
+
+ link_func = link;
+ if (flag & LN_SYMLINK) {
+ link_func = symlink;
+ }
+
+ if (link_func(*argv, src) != 0) {
+ bb_perror_msg("%s", src);
+ status = EXIT_FAILURE;
+ }
+
+ free(src_name);
+
+ } while ((++argv)[1]);
+
+ return status;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/logname.c b/i/pc104/initrd/conf/busybox/coreutils/logname.c
new file mode 100644
index 0000000..743e229
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/logname.c
@@ -0,0 +1,43 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini logname implementation for busybox
+ *
+ * Copyright (C) 2000 Edward Betts <edward@debian.org>.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/logname.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * SUSv3 specifies the string used is that returned from getlogin().
+ * The previous implementation used getpwuid() for geteuid(), which
+ * is _not_ the same. Erik apparently made this change almost 3 years
+ * ago to avoid failing when no utmp was available. However, the
+ * correct course of action wrt SUSv3 for a failing getlogin() is
+ * a diagnostic message and an error return.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "busybox.h"
+
+int logname_main(int argc, char ATTRIBUTE_UNUSED **argv);
+int logname_main(int argc, char ATTRIBUTE_UNUSED **argv)
+{
+ const char *p;
+
+ if (argc > 1) {
+ bb_show_usage();
+ }
+
+ if ((p = getlogin()) != NULL) {
+ puts(p);
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+ }
+
+ bb_perror_msg_and_die("getlogin");
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/ls.c b/i/pc104/initrd/conf/busybox/coreutils/ls.c
new file mode 100644
index 0000000..34836ee
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/ls.c
@@ -0,0 +1,957 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * tiny-ls.c version 0.1.0: A minimalist 'ls'
+ * Copyright (C) 1996 Brian Candler <B.Candler@pobox.com>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/*
+ * To achieve a small memory footprint, this version of 'ls' doesn't do any
+ * file sorting, and only has the most essential command line switches
+ * (i.e., the ones I couldn't live without :-) All features which involve
+ * linking in substantial chunks of libc can be disabled.
+ *
+ * Although I don't really want to add new features to this program to
+ * keep it small, I *am* interested to receive bug fixes and ways to make
+ * it more portable.
+ *
+ * KNOWN BUGS:
+ * 1. ls -l of a directory doesn't give "total <blocks>" header
+ * 2. ls of a symlink to a directory doesn't list directory contents
+ * 3. hidden files can make column width too large
+ *
+ * NON-OPTIMAL BEHAVIOUR:
+ * 1. autowidth reads directories twice
+ * 2. if you do a short directory listing without filetype characters
+ * appended, there's no need to stat each one
+ * PORTABILITY:
+ * 1. requires lstat (BSD) - how do you do it without?
+ */
+
+#include "busybox.h"
+#include <getopt.h>
+
+enum {
+
+TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */
+COLUMN_GAP = 2, /* includes the file type char */
+
+/* what is the overall style of the listing */
+STYLE_COLUMNS = 1 << 21, /* fill columns */
+STYLE_LONG = 2 << 21, /* one record per line, extended info */
+STYLE_SINGLE = 3 << 21, /* one record per line */
+STYLE_MASK = STYLE_SINGLE,
+
+/* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */
+/* what file information will be listed */
+LIST_INO = 1 << 0,
+LIST_BLOCKS = 1 << 1,
+LIST_MODEBITS = 1 << 2,
+LIST_NLINKS = 1 << 3,
+LIST_ID_NAME = 1 << 4,
+LIST_ID_NUMERIC = 1 << 5,
+LIST_CONTEXT = 1 << 6,
+LIST_SIZE = 1 << 7,
+LIST_DEV = 1 << 8,
+LIST_DATE_TIME = 1 << 9,
+LIST_FULLTIME = 1 << 10,
+LIST_FILENAME = 1 << 11,
+LIST_SYMLINK = 1 << 12,
+LIST_FILETYPE = 1 << 13,
+LIST_EXEC = 1 << 14,
+LIST_MASK = (LIST_EXEC << 1) - 1,
+
+/* what files will be displayed */
+DISP_DIRNAME = 1 << 15, /* 2 or more items? label directories */
+DISP_HIDDEN = 1 << 16, /* show filenames starting with . */
+DISP_DOT = 1 << 17, /* show . and .. */
+DISP_NOLIST = 1 << 18, /* show directory as itself, not contents */
+DISP_RECURSIVE = 1 << 19, /* show directory and everything below it */
+DISP_ROWS = 1 << 20, /* print across rows */
+DISP_MASK = ((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1),
+
+/* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */
+SORT_FORWARD = 0, /* sort in reverse order */
+SORT_REVERSE = 1 << 27, /* sort in reverse order */
+
+SORT_NAME = 0, /* sort by file name */
+SORT_SIZE = 1 << 28, /* sort by file size */
+SORT_ATIME = 2 << 28, /* sort by last access time */
+SORT_CTIME = 3 << 28, /* sort by last change time */
+SORT_MTIME = 4 << 28, /* sort by last modification time */
+SORT_VERSION = 5 << 28, /* sort by version */
+SORT_EXT = 6 << 28, /* sort by file name extension */
+SORT_DIR = 7 << 28, /* sort by file or directory */
+SORT_MASK = (7 << 28) * ENABLE_FEATURE_LS_SORTFILES,
+
+/* which of the three times will be used */
+TIME_CHANGE = (1 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS,
+TIME_ACCESS = (1 << 24) * ENABLE_FEATURE_LS_TIMESTAMPS,
+TIME_MASK = (3 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS,
+
+FOLLOW_LINKS = (1 << 25) * ENABLE_FEATURE_LS_FOLLOWLINKS,
+
+LS_DISP_HR = (1 << 26) * ENABLE_FEATURE_HUMAN_READABLE,
+
+LIST_SHORT = LIST_FILENAME,
+LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \
+ LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK,
+
+SPLIT_DIR = 1,
+SPLIT_FILE = 0,
+SPLIT_SUBDIR = 2,
+
+};
+
+#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f)
+#define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)])
+#define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)])
+#define COLOR(mode) ("\000\043\043\043\042\000\043\043"\
+ "\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)])
+#define ATTR(mode) ("\00\00\01\00\01\00\01\00"\
+ "\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)])
+
+/* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */
+#if ENABLE_FEATURE_LS_COLOR
+static int show_color;
+/* long option entry used only for --color, which has no short option
+ * equivalent */
+static const struct option ls_color_opt[] = {
+ { "color", optional_argument, NULL, 1 },
+ { NULL, 0, NULL, 0 }
+};
+#else
+enum { show_color = 0 };
+#endif
+
+/*
+ * a directory entry and its stat info are stored here
+ */
+struct dnode { /* the basic node */
+ char *name; /* the dir entry name */
+ char *fullname; /* the dir entry name */
+ int allocated;
+ struct stat dstat; /* the file stat info */
+ USE_SELINUX(security_context_t sid;)
+ struct dnode *next; /* point at the next node */
+};
+typedef struct dnode dnode_t;
+
+static struct dnode **list_dir(const char *);
+static struct dnode **dnalloc(int);
+static int list_single(struct dnode *);
+
+static unsigned all_fmt;
+
+#if ENABLE_FEATURE_AUTOWIDTH
+static unsigned tabstops = COLUMN_GAP;
+static unsigned terminal_width = TERMINAL_WIDTH;
+#else
+enum {
+ tabstops = COLUMN_GAP,
+ terminal_width = TERMINAL_WIDTH,
+};
+#endif
+
+static int status = EXIT_SUCCESS;
+
+static struct dnode *my_stat(char *fullname, char *name, int force_follow)
+{
+ struct stat dstat;
+ struct dnode *cur;
+ USE_SELINUX(security_context_t sid = NULL;)
+
+ if ((all_fmt & FOLLOW_LINKS) || force_follow) {
+#if ENABLE_SELINUX
+ if (is_selinux_enabled()) {
+ getfilecon(fullname, &sid);
+ }
+#endif
+ if (stat(fullname, &dstat)) {
+ bb_perror_msg("%s", fullname);
+ status = EXIT_FAILURE;
+ return 0;
+ }
+ } else {
+#if ENABLE_SELINUX
+ if (is_selinux_enabled()) {
+ lgetfilecon(fullname, &sid);
+ }
+#endif
+ if (lstat(fullname, &dstat)) {
+ bb_perror_msg("%s", fullname);
+ status = EXIT_FAILURE;
+ return 0;
+ }
+ }
+
+ cur = xmalloc(sizeof(struct dnode));
+ cur->fullname = fullname;
+ cur->name = name;
+ cur->dstat = dstat;
+ USE_SELINUX(cur->sid = sid;)
+ return cur;
+}
+
+#if ENABLE_FEATURE_LS_COLOR
+static char fgcolor(mode_t mode)
+{
+ /* Check wheter the file is existing (if so, color it red!) */
+ if (errno == ENOENT)
+ return '\037';
+ if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return COLOR(0xF000); /* File is executable ... */
+ return COLOR(mode);
+}
+
+static char bgcolor(mode_t mode)
+{
+ if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return ATTR(0xF000); /* File is executable ... */
+ return ATTR(mode);
+}
+#endif
+
+#if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR
+static char append_char(mode_t mode)
+{
+ if (!(all_fmt & LIST_FILETYPE))
+ return '\0';
+ if (S_ISDIR(mode))
+ return '/';
+ if (!(all_fmt & LIST_EXEC))
+ return '\0';
+ if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return '*';
+ return APPCHAR(mode);
+}
+#endif
+
+#define countdirs(A, B) count_dirs((A), (B), 1)
+#define countsubdirs(A, B) count_dirs((A), (B), 0)
+static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs)
+{
+ int i, dirs;
+
+ if (!dn)
+ return 0;
+ dirs = 0;
+ for (i = 0; i < nfiles; i++) {
+ char *name;
+ if (!S_ISDIR(dn[i]->dstat.st_mode))
+ continue;
+ name = dn[i]->name;
+ if (notsubdirs
+ || name[0]!='.' || (name[1] && (name[1]!='.' || name[2]))
+ ) {
+ dirs++;
+ }
+ }
+ return dirs;
+}
+
+static int countfiles(struct dnode **dnp)
+{
+ int nfiles;
+ struct dnode *cur;
+
+ if (dnp == NULL)
+ return 0;
+ nfiles = 0;
+ for (cur = dnp[0]; cur->next; cur = cur->next)
+ nfiles++;
+ nfiles++;
+ return nfiles;
+}
+
+/* get memory to hold an array of pointers */
+static struct dnode **dnalloc(int num)
+{
+ if (num < 1)
+ return NULL;
+
+ return xzalloc(num * sizeof(struct dnode *));
+}
+
+#if ENABLE_FEATURE_LS_RECURSIVE
+static void dfree(struct dnode **dnp, int nfiles)
+{
+ int i;
+
+ if (dnp == NULL)
+ return;
+
+ for (i = 0; i < nfiles; i++) {
+ struct dnode *cur = dnp[i];
+ if (cur->allocated)
+ free(cur->fullname); /* free the filename */
+ free(cur); /* free the dnode */
+ }
+ free(dnp); /* free the array holding the dnode pointers */
+}
+#else
+#define dfree(...) ((void)0)
+#endif
+
+static struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which)
+{
+ int dncnt, i, d;
+ struct dnode **dnp;
+
+ if (dn == NULL || nfiles < 1)
+ return NULL;
+
+ /* count how many dirs and regular files there are */
+ if (which == SPLIT_SUBDIR)
+ dncnt = countsubdirs(dn, nfiles);
+ else {
+ dncnt = countdirs(dn, nfiles); /* assume we are looking for dirs */
+ if (which == SPLIT_FILE)
+ dncnt = nfiles - dncnt; /* looking for files */
+ }
+
+ /* allocate a file array and a dir array */
+ dnp = dnalloc(dncnt);
+
+ /* copy the entrys into the file or dir array */
+ for (d = i = 0; i < nfiles; i++) {
+ if (S_ISDIR(dn[i]->dstat.st_mode)) {
+ char *name;
+ if (!(which & (SPLIT_DIR|SPLIT_SUBDIR)))
+ continue;
+ name = dn[i]->name;
+ if ((which & SPLIT_DIR)
+ || name[0]!='.' || (name[1] && (name[1]!='.' || name[2]))
+ ) {
+ dnp[d++] = dn[i];
+ }
+ } else if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) {
+ dnp[d++] = dn[i];
+ }
+ }
+ return dnp;
+}
+
+#if ENABLE_FEATURE_LS_SORTFILES
+static int sortcmp(const void *a, const void *b)
+{
+ struct dnode *d1 = *(struct dnode **)a;
+ struct dnode *d2 = *(struct dnode **)b;
+ unsigned sort_opts = all_fmt & SORT_MASK;
+ int dif;
+
+ dif = 0; /* assume SORT_NAME */
+ // TODO: use pre-initialized function pointer
+ // instead of branch forest
+ if (sort_opts == SORT_SIZE) {
+ dif = (int) (d2->dstat.st_size - d1->dstat.st_size);
+ } else if (sort_opts == SORT_ATIME) {
+ dif = (int) (d2->dstat.st_atime - d1->dstat.st_atime);
+ } else if (sort_opts == SORT_CTIME) {
+ dif = (int) (d2->dstat.st_ctime - d1->dstat.st_ctime);
+ } else if (sort_opts == SORT_MTIME) {
+ dif = (int) (d2->dstat.st_mtime - d1->dstat.st_mtime);
+ } else if (sort_opts == SORT_DIR) {
+ dif = S_ISDIR(d2->dstat.st_mode) - S_ISDIR(d1->dstat.st_mode);
+ /* } else if (sort_opts == SORT_VERSION) { */
+ /* } else if (sort_opts == SORT_EXT) { */
+ }
+
+ if (dif == 0) {
+ /* sort by name - may be a tie_breaker for time or size cmp */
+ if (ENABLE_LOCALE_SUPPORT) dif = strcoll(d1->name, d2->name);
+ else dif = strcmp(d1->name, d2->name);
+ }
+
+ if (all_fmt & SORT_REVERSE) {
+ dif = -dif;
+ }
+ return dif;
+}
+
+static void dnsort(struct dnode **dn, int size)
+{
+ qsort(dn, size, sizeof(*dn), sortcmp);
+}
+#else
+#define dnsort(dn, size) ((void)0)
+#endif
+
+
+static void showfiles(struct dnode **dn, int nfiles)
+{
+ int i, ncols, nrows, row, nc;
+ int column = 0;
+ int nexttab = 0;
+ int column_width = 0; /* for STYLE_LONG and STYLE_SINGLE not used */
+
+ if (dn == NULL || nfiles < 1)
+ return;
+
+ if (all_fmt & STYLE_LONG) {
+ ncols = 1;
+ } else {
+ /* find the longest file name, use that as the column width */
+ for (i = 0; i < nfiles; i++) {
+ int len = strlen(dn[i]->name);
+ if (column_width < len)
+ column_width = len;
+ }
+ column_width += tabstops +
+ USE_SELINUX( ((all_fmt & LIST_CONTEXT) ? 33 : 0) + )
+ ((all_fmt & LIST_INO) ? 8 : 0) +
+ ((all_fmt & LIST_BLOCKS) ? 5 : 0);
+ ncols = (int) (terminal_width / column_width);
+ }
+
+ if (ncols > 1) {
+ nrows = nfiles / ncols;
+ if (nrows * ncols < nfiles)
+ nrows++; /* round up fractionals */
+ } else {
+ nrows = nfiles;
+ ncols = 1;
+ }
+
+ for (row = 0; row < nrows; row++) {
+ for (nc = 0; nc < ncols; nc++) {
+ /* reach into the array based on the column and row */
+ i = (nc * nrows) + row; /* assume display by column */
+ if (all_fmt & DISP_ROWS)
+ i = (row * ncols) + nc; /* display across row */
+ if (i < nfiles) {
+ if (column > 0) {
+ nexttab -= column;
+ printf("%*s", nexttab, "");
+ column += nexttab;
+ }
+ nexttab = column + column_width;
+ column += list_single(dn[i]);
+ }
+ }
+ putchar('\n');
+ column = 0;
+ }
+}
+
+
+static void showdirs(struct dnode **dn, int ndirs, int first)
+{
+ int i, nfiles;
+ struct dnode **subdnp;
+ int dndirs;
+ struct dnode **dnd;
+
+ if (dn == NULL || ndirs < 1)
+ return;
+
+ for (i = 0; i < ndirs; i++) {
+ if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) {
+ if (!first)
+ puts("");
+ first = 0;
+ printf("%s:\n", dn[i]->fullname);
+ }
+ subdnp = list_dir(dn[i]->fullname);
+ nfiles = countfiles(subdnp);
+ if (nfiles > 0) {
+ /* list all files at this level */
+ dnsort(subdnp, nfiles);
+ showfiles(subdnp, nfiles);
+ if (ENABLE_FEATURE_LS_RECURSIVE) {
+ if (all_fmt & DISP_RECURSIVE) {
+ /* recursive- list the sub-dirs */
+ dnd = splitdnarray(subdnp, nfiles, SPLIT_SUBDIR);
+ dndirs = countsubdirs(subdnp, nfiles);
+ if (dndirs > 0) {
+ dnsort(dnd, dndirs);
+ showdirs(dnd, dndirs, 0);
+ /* free the array of dnode pointers to the dirs */
+ free(dnd);
+ }
+ }
+ /* free the dnodes and the fullname mem */
+ dfree(subdnp, nfiles);
+ }
+ }
+ }
+}
+
+
+static struct dnode **list_dir(const char *path)
+{
+ struct dnode *dn, *cur, **dnp;
+ struct dirent *entry;
+ DIR *dir;
+ int i, nfiles;
+
+ if (path == NULL)
+ return NULL;
+
+ dn = NULL;
+ nfiles = 0;
+ dir = warn_opendir(path);
+ if (dir == NULL) {
+ status = EXIT_FAILURE;
+ return NULL; /* could not open the dir */
+ }
+ while ((entry = readdir(dir)) != NULL) {
+ char *fullname;
+
+ /* are we going to list the file- it may be . or .. or a hidden file */
+ if (entry->d_name[0] == '.') {
+ if ((entry->d_name[1] == 0 || (
+ entry->d_name[1] == '.'
+ && entry->d_name[2] == 0))
+ && !(all_fmt & DISP_DOT))
+ continue;
+ if (!(all_fmt & DISP_HIDDEN))
+ continue;
+ }
+ fullname = concat_path_file(path, entry->d_name);
+ cur = my_stat(fullname, strrchr(fullname, '/') + 1, 0);
+ if (!cur) {
+ free(fullname);
+ continue;
+ }
+ cur->allocated = 1;
+ cur->next = dn;
+ dn = cur;
+ nfiles++;
+ }
+ closedir(dir);
+
+ /* now that we know how many files there are
+ * allocate memory for an array to hold dnode pointers
+ */
+ if (dn == NULL)
+ return NULL;
+ dnp = dnalloc(nfiles);
+ for (i = 0, cur = dn; i < nfiles; i++) {
+ dnp[i] = cur; /* save pointer to node in array */
+ cur = cur->next;
+ }
+
+ return dnp;
+}
+
+
+#if ENABLE_FEATURE_LS_TIMESTAMPS
+/* Do time() just once. Saves one syscall per file for "ls -l" */
+/* Initialized in main() */
+static time_t current_time_t;
+#endif
+
+static int list_single(struct dnode *dn)
+{
+ int i, column = 0;
+
+#if ENABLE_FEATURE_LS_TIMESTAMPS
+ char *filetime;
+ time_t ttime, age;
+#endif
+#if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR
+ struct stat info;
+ char append;
+#endif
+
+ if (dn->fullname == NULL)
+ return 0;
+
+#if ENABLE_FEATURE_LS_TIMESTAMPS
+ ttime = dn->dstat.st_mtime; /* the default time */
+ if (all_fmt & TIME_ACCESS)
+ ttime = dn->dstat.st_atime;
+ if (all_fmt & TIME_CHANGE)
+ ttime = dn->dstat.st_ctime;
+ filetime = ctime(&ttime);
+#endif
+#if ENABLE_FEATURE_LS_FILETYPES
+ append = append_char(dn->dstat.st_mode);
+#endif
+
+ for (i = 0; i <= 31; i++) {
+ switch (all_fmt & (1 << i)) {
+ case LIST_INO:
+ column += printf("%7ld ", (long) dn->dstat.st_ino);
+ break;
+ case LIST_BLOCKS:
+ column += printf("%4"OFF_FMT"d ", (off_t) dn->dstat.st_blocks >> 1);
+ break;
+ case LIST_MODEBITS:
+ column += printf("%-10s ", (char *) bb_mode_string(dn->dstat.st_mode));
+ break;
+ case LIST_NLINKS:
+ column += printf("%4ld ", (long) dn->dstat.st_nlink);
+ break;
+ case LIST_ID_NAME:
+#if ENABLE_FEATURE_LS_USERNAME
+ printf("%-8.8s %-8.8s",
+ get_cached_username(dn->dstat.st_uid),
+ get_cached_groupname(dn->dstat.st_gid));
+ column += 17;
+ break;
+#endif
+ case LIST_ID_NUMERIC:
+ column += printf("%-8d %-8d", dn->dstat.st_uid, dn->dstat.st_gid);
+ break;
+ case LIST_SIZE:
+ case LIST_DEV:
+ if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) {
+ column += printf("%4d, %3d ", (int) major(dn->dstat.st_rdev),
+ (int) minor(dn->dstat.st_rdev));
+ } else {
+ if (all_fmt & LS_DISP_HR) {
+ column += printf("%9s ",
+ make_human_readable_str(dn->dstat.st_size, 1, 0));
+ } else {
+ column += printf("%9"OFF_FMT"d ", (off_t) dn->dstat.st_size);
+ }
+ }
+ break;
+#if ENABLE_FEATURE_LS_TIMESTAMPS
+ case LIST_FULLTIME:
+ printf("%24.24s ", filetime);
+ column += 25;
+ break;
+ case LIST_DATE_TIME:
+ if ((all_fmt & LIST_FULLTIME) == 0) {
+ /* current_time_t ~== time(NULL) */
+ age = current_time_t - ttime;
+ printf("%6.6s ", filetime + 4);
+ if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) {
+ /* hh:mm if less than 6 months old */
+ printf("%5.5s ", filetime + 11);
+ } else {
+ printf(" %4.4s ", filetime + 20);
+ }
+ column += 13;
+ }
+ break;
+#endif
+#if ENABLE_SELINUX
+ case LIST_CONTEXT:
+ {
+ char context[80];
+ int len = 0;
+
+ if (dn->sid) {
+ /* I assume sid initilized with NULL */
+ len = strlen(dn->sid) + 1;
+ safe_strncpy(context, dn->sid, len);
+ freecon(dn->sid);
+ } else {
+ safe_strncpy(context, "unknown", 8);
+ }
+ printf("%-32s ", context);
+ column += MAX(33, len);
+ }
+ break;
+#endif
+ case LIST_FILENAME:
+ errno = 0;
+#if ENABLE_FEATURE_LS_COLOR
+ if (show_color && !lstat(dn->fullname, &info)) {
+ printf("\033[%d;%dm", bgcolor(info.st_mode),
+ fgcolor(info.st_mode));
+ }
+#endif
+ column += printf("%s", dn->name);
+ if (show_color) {
+ printf("\033[0m");
+ }
+ break;
+ case LIST_SYMLINK:
+ if (S_ISLNK(dn->dstat.st_mode)) {
+ char *lpath = xmalloc_readlink_or_warn(dn->fullname);
+ if (!lpath) break;
+ printf(" -> ");
+#if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR
+ if (!stat(dn->fullname, &info)) {
+ append = append_char(info.st_mode);
+ }
+#endif
+#if ENABLE_FEATURE_LS_COLOR
+ if (show_color) {
+ errno = 0;
+ printf("\033[%d;%dm", bgcolor(info.st_mode),
+ fgcolor(info.st_mode));
+ }
+#endif
+ column += printf("%s", lpath) + 4;
+ if (show_color) {
+ printf("\033[0m");
+ }
+ free(lpath);
+ }
+ break;
+#if ENABLE_FEATURE_LS_FILETYPES
+ case LIST_FILETYPE:
+ if (append) {
+ putchar(append);
+ column++;
+ }
+ break;
+#endif
+ }
+ }
+
+ return column;
+}
+
+/* "[-]Cadil1", POSIX mandated options, busybox always supports */
+/* "[-]gnsx", POSIX non-mandated options, busybox always supports */
+/* "[-]Ak" GNU options, busybox always supports */
+/* "[-]FLRctur", POSIX mandated options, busybox optionally supports */
+/* "[-]p", POSIX non-mandated options, busybox optionally supports */
+/* "[-]SXvThw", GNU options, busybox optionally supports */
+/* "[-]K", SELinux mandated options, busybox optionally supports */
+/* "[-]e", I think we made this one up */
+static const char ls_options[] = "Cadil1gnsxAk"
+ USE_FEATURE_LS_TIMESTAMPS("cetu")
+ USE_FEATURE_LS_SORTFILES("SXrv")
+ USE_FEATURE_LS_FILETYPES("Fp")
+ USE_FEATURE_LS_FOLLOWLINKS("L")
+ USE_FEATURE_LS_RECURSIVE("R")
+ USE_FEATURE_HUMAN_READABLE("h")
+ USE_SELINUX("K")
+ USE_FEATURE_AUTOWIDTH("T:w:")
+ USE_SELINUX("Z");
+
+enum {
+ LIST_MASK_TRIGGER = 0,
+ STYLE_MASK_TRIGGER = STYLE_MASK,
+ DISP_MASK_TRIGGER = DISP_ROWS,
+ SORT_MASK_TRIGGER = SORT_MASK,
+};
+
+static const unsigned opt_flags[] = {
+ LIST_SHORT | STYLE_COLUMNS, /* C */
+ DISP_HIDDEN | DISP_DOT, /* a */
+ DISP_NOLIST, /* d */
+ LIST_INO, /* i */
+ LIST_LONG | STYLE_LONG, /* l - remember LS_DISP_HR in mask! */
+ LIST_SHORT | STYLE_SINGLE, /* 1 */
+ 0, /* g - ingored */
+ LIST_ID_NUMERIC, /* n */
+ LIST_BLOCKS, /* s */
+ DISP_ROWS, /* x */
+ DISP_HIDDEN, /* A */
+ ENABLE_SELINUX * LIST_CONTEXT, /* k (ignored if !SELINUX) */
+#if ENABLE_FEATURE_LS_TIMESTAMPS
+ TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */
+ LIST_FULLTIME, /* e */
+ ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */
+ TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */
+#endif
+#if ENABLE_FEATURE_LS_SORTFILES
+ SORT_SIZE, /* S */
+ SORT_EXT, /* X */
+ SORT_REVERSE, /* r */
+ SORT_VERSION, /* v */
+#endif
+#if ENABLE_FEATURE_LS_FILETYPES
+ LIST_FILETYPE | LIST_EXEC, /* F */
+ LIST_FILETYPE, /* p */
+#endif
+#if ENABLE_FEATURE_LS_FOLLOWLINKS
+ FOLLOW_LINKS, /* L */
+#endif
+#if ENABLE_FEATURE_LS_RECURSIVE
+ DISP_RECURSIVE, /* R */
+#endif
+#if ENABLE_FEATURE_HUMAN_READABLE
+ LS_DISP_HR, /* h */
+#endif
+#if ENABLE_SELINUX
+ LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */
+#endif
+#if ENABLE_FEATURE_AUTOWIDTH
+ 0, 0, /* T, w - ignored */
+#endif
+#if ENABLE_SELINUX
+ LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */
+#endif
+ (1U<<31)
+};
+
+
+/* THIS IS A "SAFE" APPLET, main() MAY BE CALLED INTERNALLY FROM SHELL */
+/* BE CAREFUL! */
+
+int ls_main(int argc, char **argv);
+int ls_main(int argc, char **argv)
+{
+ struct dnode **dnd;
+ struct dnode **dnf;
+ struct dnode **dnp;
+ struct dnode *dn;
+ struct dnode *cur;
+ unsigned opt;
+ int nfiles = 0;
+ int dnfiles;
+ int dndirs;
+ int oi;
+ int ac;
+ int i;
+ char **av;
+ USE_FEATURE_AUTOWIDTH(char *tabstops_str = NULL;)
+ USE_FEATURE_AUTOWIDTH(char *terminal_width_str = NULL;)
+ USE_FEATURE_LS_COLOR(char *color_opt;)
+
+#if ENABLE_FEATURE_LS_TIMESTAMPS
+ time(&current_time_t);
+#endif
+
+ all_fmt = LIST_SHORT |
+ (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_FORWARD));
+
+#if ENABLE_FEATURE_AUTOWIDTH
+ /* Obtain the terminal width */
+ get_terminal_width_height(STDOUT_FILENO, &terminal_width, NULL);
+ /* Go one less... */
+ terminal_width--;
+#endif
+
+ /* process options */
+ USE_FEATURE_LS_COLOR(applet_long_options = ls_color_opt;)
+#if ENABLE_FEATURE_AUTOWIDTH
+ opt = getopt32(argc, argv, ls_options, &tabstops_str, &terminal_width_str
+ USE_FEATURE_LS_COLOR(, &color_opt));
+ if (tabstops_str)
+ tabstops = xatou(tabstops_str);
+ if (terminal_width_str)
+ terminal_width = xatou(terminal_width_str);
+#else
+ opt = getopt32(argc, argv, ls_options USE_FEATURE_LS_COLOR(, &color_opt));
+#endif
+ for (i = 0; opt_flags[i] != (1U<<31); i++) {
+ if (opt & (1 << i)) {
+ unsigned flags = opt_flags[i];
+
+ if (flags & LIST_MASK_TRIGGER)
+ all_fmt &= ~LIST_MASK;
+ if (flags & STYLE_MASK_TRIGGER)
+ all_fmt &= ~STYLE_MASK;
+ if (flags & SORT_MASK_TRIGGER)
+ all_fmt &= ~SORT_MASK;
+ if (flags & DISP_MASK_TRIGGER)
+ all_fmt &= ~DISP_MASK;
+ if (flags & TIME_MASK)
+ all_fmt &= ~TIME_MASK;
+ if (flags & LIST_CONTEXT)
+ all_fmt |= STYLE_SINGLE;
+ /* huh?? opt cannot be 'l' */
+ //if (LS_DISP_HR && opt == 'l')
+ // all_fmt &= ~LS_DISP_HR;
+ all_fmt |= flags;
+ }
+ }
+
+#if ENABLE_FEATURE_LS_COLOR
+ /* find color bit value - last position for short getopt */
+ if (ENABLE_FEATURE_LS_COLOR_IS_DEFAULT && isatty(STDOUT_FILENO)) {
+ char *p = getenv("LS_COLORS");
+ /* LS_COLORS is unset, or (not empty && not "none") ? */
+ if (!p || (p[0] && strcmp(p, "none")))
+ show_color = 1;
+ }
+ if (opt & (1 << i)) { /* next flag after short options */
+ if (!color_opt || !strcmp("always", color_opt))
+ show_color = 1;
+ else if (color_opt && !strcmp("never", color_opt))
+ show_color = 0;
+ else if (color_opt && !strcmp("auto", color_opt) && isatty(STDOUT_FILENO))
+ show_color = 1;
+ }
+#endif
+
+ /* sort out which command line options take precedence */
+ if (ENABLE_FEATURE_LS_RECURSIVE && (all_fmt & DISP_NOLIST))
+ all_fmt &= ~DISP_RECURSIVE; /* no recurse if listing only dir */
+ if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) {
+ if (all_fmt & TIME_CHANGE)
+ all_fmt = (all_fmt & ~SORT_MASK) | SORT_CTIME;
+ if (all_fmt & TIME_ACCESS)
+ all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME;
+ }
+ if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */
+ all_fmt &= ~(LIST_ID_NUMERIC|LIST_FULLTIME|LIST_ID_NAME|LIST_ID_NUMERIC);
+ if (ENABLE_FEATURE_LS_USERNAME)
+ if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC))
+ all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */
+
+ /* choose a display format */
+ if (!(all_fmt & STYLE_MASK))
+ all_fmt |= (isatty(STDOUT_FILENO) ? STYLE_COLUMNS : STYLE_SINGLE);
+
+ /*
+ * when there are no cmd line args we have to supply a default "." arg.
+ * we will create a second argv array, "av" that will hold either
+ * our created "." arg, or the real cmd line args. The av array
+ * just holds the pointers- we don't move the date the pointers
+ * point to.
+ */
+ ac = argc - optind; /* how many cmd line args are left */
+ if (ac < 1) {
+ static const char *const dotdir[] = { "." };
+
+ av = (char **) dotdir;
+ ac = 1;
+ } else {
+ av = argv + optind;
+ }
+
+ /* now, everything is in the av array */
+ if (ac > 1)
+ all_fmt |= DISP_DIRNAME; /* 2 or more items? label directories */
+
+ /* stuff the command line file names into a dnode array */
+ dn = NULL;
+ for (oi = 0; oi < ac; oi++) {
+ /* ls w/o -l follows links on command line */
+ cur = my_stat(av[oi], av[oi], !(all_fmt & STYLE_LONG));
+ if (!cur)
+ continue;
+ cur->allocated = 0;
+ cur->next = dn;
+ dn = cur;
+ nfiles++;
+ }
+
+ /* now that we know how many files there are
+ * allocate memory for an array to hold dnode pointers
+ */
+ dnp = dnalloc(nfiles);
+ for (i = 0, cur = dn; i < nfiles; i++) {
+ dnp[i] = cur; /* save pointer to node in array */
+ cur = cur->next;
+ }
+
+ if (all_fmt & DISP_NOLIST) {
+ dnsort(dnp, nfiles);
+ if (nfiles > 0)
+ showfiles(dnp, nfiles);
+ } else {
+ dnd = splitdnarray(dnp, nfiles, SPLIT_DIR);
+ dnf = splitdnarray(dnp, nfiles, SPLIT_FILE);
+ dndirs = countdirs(dnp, nfiles);
+ dnfiles = nfiles - dndirs;
+ if (dnfiles > 0) {
+ dnsort(dnf, dnfiles);
+ showfiles(dnf, dnfiles);
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(dnf);
+ }
+ if (dndirs > 0) {
+ dnsort(dnd, dndirs);
+ showdirs(dnd, dndirs, dnfiles == 0);
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(dnd);
+ }
+ }
+ if (ENABLE_FEATURE_CLEAN_UP)
+ dfree(dnp, nfiles);
+ return status;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/md5_sha1_sum.c b/i/pc104/initrd/conf/busybox/coreutils/md5_sha1_sum.c
new file mode 100644
index 0000000..417e90b
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/md5_sha1_sum.c
@@ -0,0 +1,185 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Copyright (C) 2003 Glenn L. McGrath
+ * Copyright (C) 2003-2004 Erik Andersen
+ *
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+ */
+
+#include "busybox.h"
+
+typedef enum { HASH_SHA1, HASH_MD5 } hash_algo_t;
+
+#define FLAG_SILENT 1
+#define FLAG_CHECK 2
+#define FLAG_WARN 4
+
+/* This might be useful elsewhere */
+static unsigned char *hash_bin_to_hex(unsigned char *hash_value,
+ unsigned hash_length)
+{
+ /* xzalloc zero-terminates */
+ char *hex_value = xzalloc((hash_length * 2) + 1);
+ bin2hex(hex_value, (char*)hash_value, hash_length);
+ return hex_value;
+}
+
+static uint8_t *hash_file(const char *filename, hash_algo_t hash_algo)
+{
+ int src_fd, hash_len, count;
+ union _ctx_ {
+ sha1_ctx_t sha1;
+ md5_ctx_t md5;
+ } context;
+ uint8_t *hash_value = NULL;
+ RESERVE_CONFIG_UBUFFER(in_buf, 4096);
+ void (*update)(const void*, size_t, void*);
+ void (*final)(void*, void*);
+
+ src_fd = STDIN_FILENO;
+ if (NOT_LONE_DASH(filename)) {
+ src_fd = open(filename, O_RDONLY);
+ if (src_fd < 0) {
+ bb_perror_msg("%s", filename);
+ return NULL;
+ }
+ }
+
+ /* figure specific hash algorithims */
+ if (ENABLE_MD5SUM && hash_algo==HASH_MD5) {
+ md5_begin(&context.md5);
+ update = (void (*)(const void*, size_t, void*))md5_hash;
+ final = (void (*)(void*, void*))md5_end;
+ hash_len = 16;
+ } else if (ENABLE_SHA1SUM && hash_algo==HASH_SHA1) {
+ sha1_begin(&context.sha1);
+ update = (void (*)(const void*, size_t, void*))sha1_hash;
+ final = (void (*)(void*, void*))sha1_end;
+ hash_len = 20;
+ } else {
+ bb_error_msg_and_die("algorithm not supported");
+ }
+
+ while (0 < (count = safe_read(src_fd, in_buf, 4096))) {
+ update(in_buf, count, &context);
+ }
+
+ if (count == 0) {
+ final(in_buf, &context);
+ hash_value = hash_bin_to_hex(in_buf, hash_len);
+ }
+
+ RELEASE_CONFIG_BUFFER(in_buf);
+
+ if (src_fd != STDIN_FILENO) {
+ close(src_fd);
+ }
+
+ return hash_value;
+}
+
+int md5_sha1_sum_main(int argc, char **argv);
+int md5_sha1_sum_main(int argc, char **argv)
+{
+ int return_value = EXIT_SUCCESS;
+ uint8_t *hash_value;
+ unsigned flags;
+ hash_algo_t hash_algo = ENABLE_MD5SUM
+ ? (ENABLE_SHA1SUM ? (**argv=='m' ? HASH_MD5 : HASH_SHA1) : HASH_MD5)
+ : HASH_SHA1;
+
+ if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK)
+ flags = getopt32(argc, argv, "scw");
+ else optind = 1;
+
+ if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) {
+ if (flags & FLAG_SILENT) {
+ bb_error_msg_and_die
+ ("-%c is meaningful only when verifying checksums", 's');
+ } else if (flags & FLAG_WARN) {
+ bb_error_msg_and_die
+ ("-%c is meaningful only when verifying checksums", 'w');
+ }
+ }
+
+ if (argc == optind) {
+ argv[argc++] = (char*)"-";
+ }
+
+ if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) {
+ FILE *pre_computed_stream;
+ int count_total = 0;
+ int count_failed = 0;
+ char *file_ptr = argv[optind];
+ char *line;
+
+ if (optind + 1 != argc) {
+ bb_error_msg_and_die
+ ("only one argument may be specified when using -c");
+ }
+
+ pre_computed_stream = stdin;
+ if (NOT_LONE_DASH(file_ptr)) {
+ pre_computed_stream = xfopen(file_ptr, "r");
+ }
+
+ while ((line = xmalloc_getline(pre_computed_stream)) != NULL) {
+ char *filename_ptr;
+
+ count_total++;
+ filename_ptr = strstr(line, " ");
+ /* handle format for binary checksums */
+ if (filename_ptr == NULL) {
+ filename_ptr = strstr(line, " *");
+ }
+ if (filename_ptr == NULL) {
+ if (flags & FLAG_WARN) {
+ bb_error_msg("invalid format");
+ }
+ count_failed++;
+ return_value = EXIT_FAILURE;
+ free(line);
+ continue;
+ }
+ *filename_ptr = '\0';
+ filename_ptr += 2;
+
+ hash_value = hash_file(filename_ptr, hash_algo);
+
+ if (hash_value && (strcmp((char*)hash_value, line) == 0)) {
+ if (!(flags & FLAG_SILENT))
+ printf("%s: OK\n", filename_ptr);
+ } else {
+ if (!(flags & FLAG_SILENT))
+ printf("%s: FAILED\n", filename_ptr);
+ count_failed++;
+ return_value = EXIT_FAILURE;
+ }
+ /* possible free(NULL) */
+ free(hash_value);
+ free(line);
+ }
+ if (count_failed && !(flags & FLAG_SILENT)) {
+ bb_error_msg("WARNING: %d of %d computed checksums did NOT match",
+ count_failed, count_total);
+ }
+ /*
+ if (fclose_if_not_stdin(pre_computed_stream) == EOF) {
+ bb_perror_msg_and_die("cannot close file %s", file_ptr);
+ }
+ */
+ } else {
+ while (optind < argc) {
+ char *file_ptr = argv[optind++];
+
+ hash_value = hash_file(file_ptr, hash_algo);
+ if (hash_value == NULL) {
+ return_value = EXIT_FAILURE;
+ } else {
+ printf("%s %s\n", hash_value, file_ptr);
+ free(hash_value);
+ }
+ }
+ }
+ return return_value;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/mkdir.c b/i/pc104/initrd/conf/busybox/coreutils/mkdir.c
new file mode 100644
index 0000000..690e4ab
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/mkdir.c
@@ -0,0 +1,82 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini mkdir implementation for busybox
+ *
+ * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/mkdir.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Fixed broken permission setting when -p was used; especially in
+ * conjunction with -m.
+ */
+
+/* Nov 28, 2006 Yoshinori Sato <ysato@users.sourceforge.jp>: Add SELinux Support.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h> /* struct option */
+#include "busybox.h"
+
+#if ENABLE_FEATURE_MKDIR_LONG_OPTIONS
+static const struct option mkdir_long_options[] = {
+ { "mode", 1, NULL, 'm' },
+ { "parents", 0, NULL, 'p' },
+#if ENABLE_SELINUX
+ { "context", 1, NULL, 'Z' },
+#endif
+ { 0, 0, 0, 0 }
+};
+#endif
+
+int mkdir_main(int argc, char **argv);
+int mkdir_main(int argc, char **argv)
+{
+ mode_t mode = (mode_t)(-1);
+ int status = EXIT_SUCCESS;
+ int flags = 0;
+ unsigned opt;
+ char *smode;
+#if ENABLE_SELINUX
+ security_context_t scontext;
+#endif
+
+#if ENABLE_FEATURE_MKDIR_LONG_OPTIONS
+ applet_long_options = mkdir_long_options;
+#endif
+ opt = getopt32(argc, argv, "m:p" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext));
+ if (opt & 1) {
+ mode = 0777;
+ if (!bb_parse_mode(smode, &mode)) {
+ bb_error_msg_and_die("invalid mode '%s'", smode);
+ }
+ }
+ if (opt & 2)
+ flags |= FILEUTILS_RECUR;
+#if ENABLE_SELINUX
+ if (opt & 4) {
+ selinux_or_die();
+ setfscreatecon_or_die(scontext);
+ }
+#endif
+
+ if (optind == argc) {
+ bb_show_usage();
+ }
+
+ argv += optind;
+
+ do {
+ if (bb_make_directory(*argv, mode, flags)) {
+ status = EXIT_FAILURE;
+ }
+ } while (*++argv);
+
+ return status;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/mkfifo.c b/i/pc104/initrd/conf/busybox/coreutils/mkfifo.c
new file mode 100644
index 0000000..6d8aa41
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/mkfifo.c
@@ -0,0 +1,39 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * mkfifo implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/mkfifo.html */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include "busybox.h"
+#include "libcoreutils/coreutils.h"
+
+int mkfifo_main(int argc, char **argv);
+int mkfifo_main(int argc, char **argv)
+{
+ mode_t mode;
+ int retval = EXIT_SUCCESS;
+
+ mode = getopt_mk_fifo_nod(argc, argv);
+
+ if (!*(argv += optind)) {
+ bb_show_usage();
+ }
+
+ do {
+ if (mkfifo(*argv, mode) < 0) {
+ bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */
+ retval = EXIT_FAILURE;
+ }
+ } while (*++argv);
+
+ return retval;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/mknod.c b/i/pc104/initrd/conf/busybox/coreutils/mknod.c
new file mode 100644
index 0000000..6fa6d83
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/mknod.c
@@ -0,0 +1,51 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * mknod implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
+
+#include <sys/sysmacros.h> // For makedev
+
+#include "busybox.h"
+#include "libcoreutils/coreutils.h"
+
+static const char modes_chars[] = { 'p', 'c', 'u', 'b', 0, 1, 1, 2 };
+static const mode_t modes_cubp[] = { S_IFIFO, S_IFCHR, S_IFBLK };
+
+int mknod_main(int argc, char **argv);
+int mknod_main(int argc, char **argv)
+{
+ mode_t mode;
+ dev_t dev;
+ const char *name;
+
+ mode = getopt_mk_fifo_nod(argc, argv);
+ argv += optind;
+ argc -= optind;
+
+ if ((argc >= 2) && ((name = strchr(modes_chars, argv[1][0])) != NULL)) {
+ mode |= modes_cubp[(int)(name[4])];
+
+ dev = 0;
+ if ((*name != 'p') && ((argc -= 2) == 2)) {
+ /* Autodetect what the system supports; these macros should
+ * optimize out to two constants. */
+ dev = makedev(xatoul_range(argv[2], 0, major(UINT_MAX)),
+ xatoul_range(argv[3], 0, minor(UINT_MAX)));
+ }
+
+ if (argc == 2) {
+ name = *argv;
+ if (mknod(name, mode, dev) == 0) {
+ return EXIT_SUCCESS;
+ }
+ bb_perror_msg_and_die("%s", name);
+ }
+ }
+ bb_show_usage();
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/mv.c b/i/pc104/initrd/conf/busybox/coreutils/mv.c
new file mode 100644
index 0000000..c08d232
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/mv.c
@@ -0,0 +1,137 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini mv implementation for busybox
+ *
+ * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
+ * SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Size reduction and improved error checking.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <getopt.h> /* struct option */
+#include "busybox.h"
+#include "libcoreutils/coreutils.h"
+
+#if ENABLE_FEATURE_MV_LONG_OPTIONS
+static const struct option mv_long_options[] = {
+ { "interactive", 0, NULL, 'i' },
+ { "force", 0, NULL, 'f' },
+ { 0, 0, 0, 0 }
+};
+#endif
+
+#define OPT_FILEUTILS_FORCE 1
+#define OPT_FILEUTILS_INTERACTIVE 2
+
+static const char fmt[] = "cannot overwrite %sdirectory with %sdirectory";
+
+int mv_main(int argc, char **argv);
+int mv_main(int argc, char **argv)
+{
+ struct stat dest_stat;
+ const char *last;
+ const char *dest;
+ unsigned long flags;
+ int dest_exists;
+ int status = 0;
+ int copy_flag = 0;
+
+#if ENABLE_FEATURE_MV_LONG_OPTIONS
+ applet_long_options = mv_long_options;
+#endif
+ opt_complementary = "f-i:i-f";
+ flags = getopt32(argc, argv, "fi");
+ if (optind + 2 > argc) {
+ bb_show_usage();
+ }
+
+ last = argv[argc - 1];
+ argv += optind;
+
+ if (optind + 2 == argc) {
+ dest_exists = cp_mv_stat(last, &dest_stat);
+ if (dest_exists < 0) {
+ return 1;
+ }
+
+ if (!(dest_exists & 2)) {
+ dest = last;
+ goto DO_MOVE;
+ }
+ }
+
+ do {
+ dest = concat_path_file(last, bb_get_last_path_component(*argv));
+ dest_exists = cp_mv_stat(dest, &dest_stat);
+ if (dest_exists < 0) {
+ goto RET_1;
+ }
+
+DO_MOVE:
+
+ if (dest_exists && !(flags & OPT_FILEUTILS_FORCE) &&
+ ((access(dest, W_OK) < 0 && isatty(0)) ||
+ (flags & OPT_FILEUTILS_INTERACTIVE))) {
+ if (fprintf(stderr, "mv: overwrite '%s'? ", dest) < 0) {
+ goto RET_1; /* Ouch! fprintf failed! */
+ }
+ if (!bb_ask_confirmation()) {
+ goto RET_0;
+ }
+ }
+ if (rename(*argv, dest) < 0) {
+ struct stat source_stat;
+ int source_exists;
+
+ if (errno != EXDEV ||
+ (source_exists = cp_mv_stat(*argv, &source_stat)) < 1) {
+ bb_perror_msg("cannot rename '%s'", *argv);
+ } else {
+ if (dest_exists) {
+ if (dest_exists == 3) {
+ if (source_exists != 3) {
+ bb_error_msg(fmt, "", "non-");
+ goto RET_1;
+ }
+ } else {
+ if (source_exists == 3) {
+ bb_error_msg(fmt, "non-", "");
+ goto RET_1;
+ }
+ }
+ if (unlink(dest) < 0) {
+ bb_perror_msg("cannot remove '%s'", dest);
+ goto RET_1;
+ }
+ }
+ copy_flag = FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS;
+#if ENABLE_SELINUX
+ copy_flag |= FILEUTILS_PRESERVE_SECURITY_CONTEXT;
+#endif
+ if ((copy_file(*argv, dest, copy_flag) >= 0) &&
+ (remove_file(*argv, FILEUTILS_RECUR | FILEUTILS_FORCE) >= 0)) {
+ goto RET_0;
+ }
+ }
+RET_1:
+ status = 1;
+ }
+RET_0:
+ if (dest != last) {
+ free((void *) dest);
+ }
+ } while (*++argv != last);
+
+ return status;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/nice.c b/i/pc104/initrd/conf/busybox/coreutils/nice.c
new file mode 100644
index 0000000..3285315
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/nice.c
@@ -0,0 +1,55 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * nice implementation for busybox
+ *
+ * Copyright (C) 2005 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include <sys/resource.h>
+#include "busybox.h"
+
+int nice_main(int argc, char **argv);
+int nice_main(int argc, char **argv)
+{
+ int old_priority, adjustment;
+
+ old_priority = getpriority(PRIO_PROCESS, 0);
+
+ if (!*++argv) { /* No args, so (GNU) output current nice value. */
+ printf("%d\n", old_priority);
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+ }
+
+ adjustment = 10; /* Set default adjustment. */
+
+ if (argv[0][0] == '-') {
+ if (argv[0][1] == 'n') { /* -n */
+ if (argv[0][2]) { /* -nNNNN (w/o space) */
+ argv[0] += 2; argv--; argc++;
+ }
+ } else { /* -NNN (NNN may be negative) == -n NNN */
+ argv[0] += 1; argv--; argc++;
+ }
+ if (argc < 4) { /* Missing priority and/or utility! */
+ bb_show_usage();
+ }
+ adjustment = xatoi_range(argv[1], INT_MIN/2, INT_MAX/2);
+ argv += 2;
+ }
+
+ { /* Set our priority. */
+ int prio = old_priority + adjustment;
+
+ if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
+ bb_perror_msg_and_die("setpriority(%d)", prio);
+ }
+ }
+
+ BB_EXECVP(*argv, argv); /* Now exec the desired program. */
+
+ /* The exec failed... */
+ xfunc_error_retval = (errno == ENOENT) ? 127 : 126; /* SUSv3 */
+ bb_perror_msg_and_die("%s", *argv);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/nohup.c b/i/pc104/initrd/conf/busybox/coreutils/nohup.c
new file mode 100644
index 0000000..6a6c70e
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/nohup.c
@@ -0,0 +1,60 @@
+/* vi: set sw=4 ts=4: */
+/* nohup - invoke a utility immune to hangups.
+ *
+ * Busybox version based on nohup specification at
+ * http://www.opengroup.org/onlinepubs/007904975/utilities/nohup.html
+ *
+ * Copyright 2006 Rob Landley <rob@landley.net>
+ * Copyright 2006 Bernhard Fischer
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+
+int nohup_main(int argc, char **argv);
+int nohup_main(int argc, char **argv)
+{
+ int nullfd;
+ const char *nohupout;
+ char *home = NULL;
+
+ xfunc_error_retval = 127;
+
+ if (argc < 2) bb_show_usage();
+
+ nullfd = xopen(bb_dev_null, O_WRONLY|O_APPEND);
+ /* If stdin is a tty, detach from it. */
+ if (isatty(STDIN_FILENO))
+ dup2(nullfd, STDIN_FILENO);
+
+ nohupout = "nohup.out";
+ /* Redirect stdout to nohup.out, either in "." or in "$HOME". */
+ if (isatty(STDOUT_FILENO)) {
+ close(STDOUT_FILENO);
+ if (open(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR) < 0) {
+ home = getenv("HOME");
+ if (home) {
+ nohupout = concat_path_file(home, nohupout);
+ xopen3(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR);
+ }
+ }
+ } else dup2(nullfd, STDOUT_FILENO);
+
+ /* If we have a tty on stderr, announce filename and redirect to stdout.
+ * Else redirect to /dev/null.
+ */
+ if (isatty(STDERR_FILENO)) {
+ bb_error_msg("appending to %s", nohupout);
+ dup2(STDOUT_FILENO, STDERR_FILENO);
+ } else dup2(nullfd, STDERR_FILENO);
+
+ if (nullfd > 2)
+ close(nullfd);
+ signal(SIGHUP, SIG_IGN);
+
+ BB_EXECVP(argv[1], argv+1);
+ if (ENABLE_FEATURE_CLEAN_UP && home)
+ free((char*)nohupout);
+ bb_perror_msg_and_die("%s", argv[1]);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/od.c b/i/pc104/initrd/conf/busybox/coreutils/od.c
new file mode 100644
index 0000000..0de9def
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/od.c
@@ -0,0 +1,225 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * od implementation for busybox
+ * Based on code from util-linux v 2.11l
+ *
+ * Copyright (c) 1990
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ * Original copyright notice is retained at the end of this file.
+ */
+
+
+#include "busybox.h"
+#if ENABLE_DESKTOP
+/* This one provides -t (busybox's own build script needs it) */
+#include "od_bloaty.c"
+#else
+#include <getopt.h>
+
+#include "dump.h"
+
+#define isdecdigit(c) isdigit(c)
+#define ishexdigit(c) (isxdigit)(c)
+
+static void
+odoffset(int argc, char ***argvp)
+{
+ char *num, *p;
+ int base;
+ char *end;
+
+ /*
+ * The offset syntax of od(1) was genuinely bizarre. First, if
+ * it started with a plus it had to be an offset. Otherwise, if
+ * there were at least two arguments, a number or lower-case 'x'
+ * followed by a number makes it an offset. By default it was
+ * octal; if it started with 'x' or '0x' it was hex. If it ended
+ * in a '.', it was decimal. If a 'b' or 'B' was appended, it
+ * multiplied the number by 512 or 1024 byte units. There was
+ * no way to assign a block count to a hex offset.
+ *
+ * We assumes it's a file if the offset is bad.
+ */
+ p = **argvp;
+
+ if (!p) {
+ /* hey someone is probably piping to us ... */
+ return;
+ }
+
+ if ((*p != '+')
+ && (argc < 2
+ || (!isdecdigit(p[0])
+ && ((p[0] != 'x') || !ishexdigit(p[1])))))
+ return;
+
+ base = 0;
+ /*
+ * bb_dump_skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
+ * set base.
+ */
+ if (p[0] == '+')
+ ++p;
+ if (p[0] == 'x' && ishexdigit(p[1])) {
+ ++p;
+ base = 16;
+ } else if (p[0] == '0' && p[1] == 'x') {
+ p += 2;
+ base = 16;
+ }
+
+ /* bb_dump_skip over the number */
+ if (base == 16)
+ for (num = p; ishexdigit(*p); ++p);
+ else
+ for (num = p; isdecdigit(*p); ++p);
+
+ /* check for no number */
+ if (num == p)
+ return;
+
+ /* if terminates with a '.', base is decimal */
+ if (*p == '.') {
+ if (base)
+ return;
+ base = 10;
+ }
+
+ bb_dump_skip = strtol(num, &end, base ? base : 8);
+
+ /* if end isn't the same as p, we got a non-octal digit */
+ if (end != p)
+ bb_dump_skip = 0;
+ else {
+ if (*p) {
+ if (*p == 'b') {
+ bb_dump_skip *= 512;
+ ++p;
+ } else if (*p == 'B') {
+ bb_dump_skip *= 1024;
+ ++p;
+ }
+ }
+ if (*p)
+ bb_dump_skip = 0;
+ else {
+ ++*argvp;
+ /*
+ * If the offset uses a non-octal base, the base of
+ * the offset is changed as well. This isn't pretty,
+ * but it's easy.
+ */
+#define TYPE_OFFSET 7
+ {
+ char x_or_d;
+ if (base == 16) {
+ x_or_d = 'x';
+ goto DO_X_OR_D;
+ }
+ if (base == 10) {
+ x_or_d = 'd';
+ DO_X_OR_D:
+ bb_dump_fshead->nextfu->fmt[TYPE_OFFSET]
+ = bb_dump_fshead->nextfs->nextfu->fmt[TYPE_OFFSET]
+ = x_or_d;
+ }
+ }
+ }
+ }
+}
+
+static const char * const add_strings[] = {
+ "16/1 \"%3_u \" \"\\n\"", /* a */
+ "8/2 \" %06o \" \"\\n\"", /* B, o */
+ "16/1 \"%03o \" \"\\n\"", /* b */
+ "16/1 \"%3_c \" \"\\n\"", /* c */
+ "8/2 \" %05u \" \"\\n\"", /* d */
+ "4/4 \" %010u \" \"\\n\"", /* D */
+ "2/8 \" %21.14e \" \"\\n\"", /* e (undocumented in od), F */
+ "4/4 \" %14.7e \" \"\\n\"", /* f */
+ "4/4 \" %08x \" \"\\n\"", /* H, X */
+ "8/2 \" %04x \" \"\\n\"", /* h, x */
+ "4/4 \" %11d \" \"\\n\"", /* I, L, l */
+ "8/2 \" %6d \" \"\\n\"", /* i */
+ "4/4 \" %011o \" \"\\n\"", /* O */
+};
+
+static const char od_opts[] = "aBbcDdeFfHhIiLlOoXxv";
+
+static const char od_o2si[] = {
+ 0, 1, 2, 3, 5,
+ 4, 6, 6, 7, 8,
+ 9, 0xa, 0xb, 0xa, 0xa,
+ 0xb, 1, 8, 9,
+};
+
+int od_main(int argc, char **argv);
+int od_main(int argc, char **argv)
+{
+ int ch;
+ int first = 1;
+ char *p;
+ bb_dump_vflag = FIRST;
+ bb_dump_length = -1;
+
+ while ((ch = getopt(argc, argv, od_opts)) > 0) {
+ if (ch == 'v') {
+ bb_dump_vflag = ALL;
+ } else if (((p = strchr(od_opts, ch)) != NULL) && (*p != '\0')) {
+ if (first) {
+ first = 0;
+ bb_dump_add("\"%07.7_Ao\n\"");
+ bb_dump_add("\"%07.7_ao \"");
+ } else {
+ bb_dump_add("\" \"");
+ }
+ bb_dump_add(add_strings[(int)od_o2si[(p-od_opts)]]);
+ } else { /* P, p, s, w, or other unhandled */
+ bb_show_usage();
+ }
+ }
+ if (!bb_dump_fshead) {
+ bb_dump_add("\"%07.7_Ao\n\"");
+ bb_dump_add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\"");
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ odoffset(argc, &argv);
+
+ return bb_dump_dump(argv);
+}
+#endif /* ENABLE_DESKTOP */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
diff --git a/i/pc104/initrd/conf/busybox/coreutils/od_bloaty.c b/i/pc104/initrd/conf/busybox/coreutils/od_bloaty.c
new file mode 100644
index 0000000..74765f8
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/od_bloaty.c
@@ -0,0 +1,1465 @@
+/* od -- dump files in octal and other formats
+ Copyright (C) 92, 1995-2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Jim Meyering. */
+
+/* Busyboxed by Denis Vlasenko
+
+Based on od.c from coreutils-5.2.1
+Top bloat sources:
+
+00000073 t parse_old_offset
+0000007b t get_lcm
+00000090 r long_options
+00000092 t print_named_ascii
+000000bf t print_ascii
+00000168 t write_block
+00000366 t decode_format_string
+00000a71 T od_main
+
+Tested for compat with coreutils 6.3
+using this script. Minor differences fixed.
+
+#!/bin/sh
+echo STD
+time /path/to/coreutils/od \
+...params... \
+>std
+echo Exit code $?
+echo BBOX
+time ./busybox od \
+...params... \
+>bbox
+echo Exit code $?
+diff -u -a std bbox >bbox.diff || { echo Different!; sleep 1; }
+
+*/
+
+
+#include "busybox.h"
+#include <getopt.h>
+
+#define assert(a) ((void)0)
+
+/* Check for 0x7f is a coreutils 6.3 addition */
+#define ISPRINT(c) (((c)>=' ') && (c) != 0x7f)
+
+typedef long double longdouble_t;
+typedef unsigned long long ulonglong_t;
+typedef long long llong;
+
+#if ENABLE_LFS
+# define xstrtooff_sfx xstrtoull_sfx
+#else
+# define xstrtooff_sfx xstrtoul_sfx
+#endif
+
+/* The default number of input bytes per output line. */
+#define DEFAULT_BYTES_PER_BLOCK 16
+
+/* The number of decimal digits of precision in a float. */
+#ifndef FLT_DIG
+# define FLT_DIG 7
+#endif
+
+/* The number of decimal digits of precision in a double. */
+#ifndef DBL_DIG
+# define DBL_DIG 15
+#endif
+
+/* The number of decimal digits of precision in a long double. */
+#ifndef LDBL_DIG
+# define LDBL_DIG DBL_DIG
+#endif
+
+enum size_spec {
+ NO_SIZE,
+ CHAR,
+ SHORT,
+ INT,
+ LONG,
+ LONG_LONG,
+ FLOAT_SINGLE,
+ FLOAT_DOUBLE,
+ FLOAT_LONG_DOUBLE,
+ N_SIZE_SPECS
+};
+
+enum output_format {
+ SIGNED_DECIMAL,
+ UNSIGNED_DECIMAL,
+ OCTAL,
+ HEXADECIMAL,
+ FLOATING_POINT,
+ NAMED_CHARACTER,
+ CHARACTER
+};
+
+/* Each output format specification (from '-t spec' or from
+ old-style options) is represented by one of these structures. */
+struct tspec {
+ enum output_format fmt;
+ enum size_spec size;
+ void (*print_function) (size_t, const char *, const char *);
+ char *fmt_string;
+ int hexl_mode_trailer;
+ int field_width;
+};
+
+/* Convert the number of 8-bit bytes of a binary representation to
+ the number of characters (digits + sign if the type is signed)
+ required to represent the same quantity in the specified base/type.
+ For example, a 32-bit (4-byte) quantity may require a field width
+ as wide as the following for these types:
+ 11 unsigned octal
+ 11 signed decimal
+ 10 unsigned decimal
+ 8 unsigned hexadecimal */
+
+static const uint8_t bytes_to_oct_digits[] =
+{0, 3, 6, 8, 11, 14, 16, 19, 22, 25, 27, 30, 32, 35, 38, 41, 43};
+
+static const uint8_t bytes_to_signed_dec_digits[] =
+{1, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 28, 30, 33, 35, 37, 40};
+
+static const uint8_t bytes_to_unsigned_dec_digits[] =
+{0, 3, 5, 8, 10, 13, 15, 17, 20, 22, 25, 27, 29, 32, 34, 37, 39};
+
+static const uint8_t bytes_to_hex_digits[] =
+{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32};
+
+/* Convert enum size_spec to the size of the named type. */
+static const signed char width_bytes[] = {
+ -1,
+ sizeof(char),
+ sizeof(short),
+ sizeof(int),
+ sizeof(long),
+ sizeof(ulonglong_t),
+ sizeof(float),
+ sizeof(double),
+ sizeof(longdouble_t)
+};
+
+/* Ensure that for each member of 'enum size_spec' there is an
+ initializer in the width_bytes array. */
+struct dummy {
+ int assert_width_bytes_matches_size_spec_decl
+ [sizeof width_bytes / sizeof width_bytes[0] == N_SIZE_SPECS ? 1 : -1];
+};
+
+static size_t string_min;
+static int flag_dump_strings;
+
+/* Non-zero if an old-style 'pseudo-address' was specified. */
+static int flag_pseudo_start;
+
+/* The difference between the old-style pseudo starting address and
+ the number of bytes to skip. */
+static off_t pseudo_offset;
+
+/* Function that accepts an address and an optional following char,
+ and prints the address and char to stdout. */
+static void (*format_address) (off_t, char);
+
+/* The number of input bytes to skip before formatting and writing. */
+static off_t n_bytes_to_skip; // = 0;
+
+/* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
+ input is formatted. */
+static int limit_bytes_to_format; // = 0;
+
+/* The maximum number of bytes that will be formatted. */
+static off_t max_bytes_to_format;
+
+/* The offset of the first byte after the last byte to be formatted. */
+static off_t end_offset;
+
+/* When nonzero and two or more consecutive blocks are equal, format
+ only the first block and output an asterisk alone on the following
+ line to indicate that identical blocks have been elided. */
+static int abbreviate_duplicate_blocks = 1;
+
+/* An array of specs describing how to format each input block. */
+static size_t n_specs;
+static struct tspec *spec;
+
+/* The number of input bytes formatted per output line. It must be
+ a multiple of the least common multiple of the sizes associated with
+ the specified output types. It should be as large as possible, but
+ no larger than 16 -- unless specified with the -w option. */
+static size_t bytes_per_block;
+
+/* Human-readable representation of *file_list (for error messages).
+ It differs from *file_list only when *file_list is "-". */
+static char const *input_filename;
+
+/* A NULL-terminated list of the file-arguments from the command line. */
+static char const *const *file_list;
+
+/* Initializer for file_list if no file-arguments
+ were specified on the command line. */
+static char const *const default_file_list[] = { "-", NULL };
+
+/* The input stream associated with the current file. */
+static FILE *in_stream;
+
+static int ioerror;
+
+#define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t)
+static unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] = {
+ [sizeof(char)] = CHAR,
+#if USHRT_MAX != UCHAR_MAX
+ [sizeof(short)] = SHORT,
+#endif
+#if UINT_MAX != USHRT_MAX
+ [sizeof(int)] = INT,
+#endif
+#if ULONG_MAX != UINT_MAX
+ [sizeof(long)] = LONG,
+#endif
+#if ULLONG_MAX != ULONG_MAX
+ [sizeof(ulonglong_t)] = LONG_LONG,
+#endif
+};
+
+#define MAX_FP_TYPE_SIZE sizeof(longdouble_t)
+static unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] = {
+ /* gcc seems to allow repeated indexes. Last one stays */
+ [sizeof(longdouble_t)] = FLOAT_LONG_DOUBLE,
+ [sizeof(double)] = FLOAT_DOUBLE,
+ [sizeof(float)] = FLOAT_SINGLE,
+};
+
+
+static unsigned
+gcd(unsigned u, unsigned v)
+{
+ unsigned t;
+ while (v != 0) {
+ t = u % v;
+ u = v;
+ v = t;
+ }
+ return u;
+}
+
+/* Compute the least common multiple of U and V. */
+static unsigned
+lcm(unsigned u, unsigned v) {
+ unsigned t = gcd(u, v);
+ if (t == 0)
+ return 0;
+ return u * v / t;
+}
+
+static void
+print_s_char(size_t n_bytes, const char *block, const char *fmt_string)
+{
+ while (n_bytes--) {
+ int tmp = *(signed char *) block;
+ printf(fmt_string, tmp);
+ block += sizeof(unsigned char);
+ }
+}
+
+static void
+print_char(size_t n_bytes, const char *block, const char *fmt_string)
+{
+ while (n_bytes--) {
+ unsigned tmp = *(unsigned char *) block;
+ printf(fmt_string, tmp);
+ block += sizeof(unsigned char);
+ }
+}
+
+static void
+print_s_short(size_t n_bytes, const char *block, const char *fmt_string)
+{
+ n_bytes /= sizeof(signed short);
+ while (n_bytes--) {
+ int tmp = *(signed short *) block;
+ printf(fmt_string, tmp);
+ block += sizeof(unsigned short);
+ }
+}
+
+static void
+print_short(size_t n_bytes, const char *block, const char *fmt_string)
+{
+ n_bytes /= sizeof(unsigned short);
+ while (n_bytes--) {
+ unsigned tmp = *(unsigned short *) block;
+ printf(fmt_string, tmp);
+ block += sizeof(unsigned short);
+ }
+}
+
+static void
+print_int(size_t n_bytes, const char *block, const char *fmt_string)
+{
+ n_bytes /= sizeof(unsigned);
+ while (n_bytes--) {
+ unsigned tmp = *(unsigned *) block;
+ printf(fmt_string, tmp);
+ block += sizeof(unsigned);
+ }
+}
+
+#if UINT_MAX == ULONG_MAX
+# define print_long print_int
+#else
+static void
+print_long(size_t n_bytes, const char *block, const char *fmt_string)
+{
+ n_bytes /= sizeof(unsigned long);
+ while (n_bytes--) {
+ unsigned long tmp = *(unsigned long *) block;
+ printf(fmt_string, tmp);
+ block += sizeof(unsigned long);
+ }
+}
+#endif
+
+#if ULONG_MAX == ULLONG_MAX
+# define print_long_long print_long
+#else
+static void
+print_long_long(size_t n_bytes, const char *block, const char *fmt_string)
+{
+ n_bytes /= sizeof(ulonglong_t);
+ while (n_bytes--) {
+ ulonglong_t tmp = *(ulonglong_t *) block;
+ printf(fmt_string, tmp);
+ block += sizeof(ulonglong_t);
+ }
+}
+#endif
+
+static void
+print_float(size_t n_bytes, const char *block, const char *fmt_string)
+{
+ n_bytes /= sizeof(float);
+ while (n_bytes--) {
+ float tmp = *(float *) block;
+ printf(fmt_string, tmp);
+ block += sizeof(float);
+ }
+}
+
+static void
+print_double(size_t n_bytes, const char *block, const char *fmt_string)
+{
+ n_bytes /= sizeof(double);
+ while (n_bytes--) {
+ double tmp = *(double *) block;
+ printf(fmt_string, tmp);
+ block += sizeof(double);
+ }
+}
+
+static void
+print_long_double(size_t n_bytes, const char *block, const char *fmt_string)
+{
+ n_bytes /= sizeof(longdouble_t);
+ while (n_bytes--) {
+ longdouble_t tmp = *(longdouble_t *) block;
+ printf(fmt_string, tmp);
+ block += sizeof(longdouble_t);
+ }
+}
+
+/* print_[named]_ascii are optimized for speed.
+ * Remember, someday you may want to pump gigabytes thru this thing.
+ * Saving a dozen of .text bytes here is counter-productive */
+
+static void
+print_named_ascii(size_t n_bytes, const char *block,
+ const char *unused_fmt_string ATTRIBUTE_UNUSED)
+{
+ /* Names for some non-printing characters. */
+ static const char charname[33][3] = {
+ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
+ " bs", " ht", " nl", " vt", " ff", " cr", " so", " si",
+ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
+ "can", " em", "sub", "esc", " fs", " gs", " rs", " us",
+ " sp"
+ };
+ // buf[N] pos: 01234 56789
+ char buf[12] = " x\0 0xx\0";
+ // actually " x\0 xxx\0", but I want to share the string with below.
+ // [12] because we take three 32bit stack slots anyway, and
+ // gcc is too dumb to initialize with constant stores,
+ // it copies initializer from rodata. Oh well.
+
+ while (n_bytes--) {
+ unsigned masked_c = *(unsigned char *) block++;
+
+ masked_c &= 0x7f;
+ if (masked_c == 0x7f) {
+ fputs(" del", stdout);
+ continue;
+ }
+ if (masked_c > ' ') {
+ buf[3] = masked_c;
+ fputs(buf, stdout);
+ continue;
+ }
+ /* Why? Because printf(" %3.3s") is much slower... */
+ buf[6] = charname[masked_c][0];
+ buf[7] = charname[masked_c][1];
+ buf[8] = charname[masked_c][2];
+ fputs(buf+5, stdout);
+ }
+}
+
+static void
+print_ascii(size_t n_bytes, const char *block,
+ const char *unused_fmt_string ATTRIBUTE_UNUSED)
+{
+ // buf[N] pos: 01234 56789
+ char buf[12] = " x\0 0xx\0";
+
+ while (n_bytes--) {
+ const char *s;
+ unsigned c = *(unsigned char *) block++;
+
+ if (ISPRINT(c)) {
+ buf[3] = c;
+ fputs(buf, stdout);
+ continue;
+ }
+ switch (c) {
+ case '\0':
+ s = " \\0";
+ break;
+ case '\007':
+ s = " \\a";
+ break;
+ case '\b':
+ s = " \\b";
+ break;
+ case '\f':
+ s = " \\f";
+ break;
+ case '\n':
+ s = " \\n";
+ break;
+ case '\r':
+ s = " \\r";
+ break;
+ case '\t':
+ s = " \\t";
+ break;
+ case '\v':
+ s = " \\v";
+ break;
+ case '\x7f':
+ s = " 177";
+ break;
+ default: /* c is never larger than 040 */
+ buf[7] = (c >> 3) + '0';
+ buf[8] = (c & 7) + '0';
+ s = buf + 5;
+ }
+ fputs(s, stdout);
+ }
+}
+
+/* Given a list of one or more input filenames FILE_LIST, set the global
+ file pointer IN_STREAM and the global string INPUT_FILENAME to the
+ first one that can be successfully opened. Modify FILE_LIST to
+ reference the next filename in the list. A file name of "-" is
+ interpreted as standard input. If any file open fails, give an error
+ message and return nonzero. */
+
+static void
+open_next_file(void)
+{
+ while (1) {
+ input_filename = *file_list;
+ if (!input_filename)
+ return;
+ file_list++;
+ in_stream = fopen_or_warn_stdin(input_filename);
+ if (in_stream) {
+ if (in_stream == stdin)
+ input_filename = bb_msg_standard_input;
+ break;
+ }
+ ioerror = 1;
+ }
+
+ if (limit_bytes_to_format && !flag_dump_strings)
+ setbuf(in_stream, NULL);
+}
+
+/* Test whether there have been errors on in_stream, and close it if
+ it is not standard input. Return nonzero if there has been an error
+ on in_stream or stdout; return zero otherwise. This function will
+ report more than one error only if both a read and a write error
+ have occurred. IN_ERRNO, if nonzero, is the error number
+ corresponding to the most recent action for IN_STREAM. */
+
+static void
+check_and_close(void)
+{
+ if (in_stream) {
+ if (ferror(in_stream)) {
+ bb_error_msg("%s: read error", input_filename);
+ ioerror = 1;
+ }
+ fclose_if_not_stdin(in_stream);
+ in_stream = NULL;
+ }
+
+ if (ferror(stdout)) {
+ bb_error_msg("write error");
+ ioerror = 1;
+ }
+}
+
+/* If S points to a single valid modern od format string, put
+ a description of that format in *TSPEC, make *NEXT point at the
+ character following the just-decoded format (if *NEXT is non-NULL),
+ and return zero. For example, if S were "d4afL"
+ *NEXT would be set to "afL" and *TSPEC would be
+ {
+ fmt = SIGNED_DECIMAL;
+ size = INT or LONG; (whichever integral_type_size[4] resolves to)
+ print_function = print_int; (assuming size == INT)
+ fmt_string = "%011d%c";
+ }
+ S_ORIG is solely for reporting errors. It should be the full format
+ string argument. */
+
+static void
+decode_one_format(const char *s_orig, const char *s, const char **next,
+ struct tspec *tspec)
+{
+ enum size_spec size_spec;
+ unsigned size;
+ enum output_format fmt;
+ const char *p;
+ char *end;
+ char *fmt_string = NULL;
+ void (*print_function) (size_t, const char *, const char *);
+ unsigned c;
+ unsigned field_width = 0;
+ int pos;
+
+ assert(tspec != NULL);
+
+ switch (*s) {
+ case 'd':
+ case 'o':
+ case 'u':
+ case 'x': {
+ static const char CSIL[] = "CSIL";
+
+ c = *s++;
+ p = strchr(CSIL, *s);
+ if (!p) {
+ size = sizeof(int);
+ if (isdigit(s[0])) {
+ size = bb_strtou(s, &end, 0);
+ if (errno == ERANGE
+ || MAX_INTEGRAL_TYPE_SIZE < size
+ || integral_type_size[size] == NO_SIZE
+ ) {
+ bb_error_msg_and_die("invalid type string '%s'; "
+ "%u-byte %s type is not supported",
+ s_orig, size, "integral");
+ }
+ s = end;
+ }
+ } else {
+ static const uint8_t CSIL_sizeof[] = {
+ sizeof(char),
+ sizeof(short),
+ sizeof(int),
+ sizeof(long),
+ };
+ size = CSIL_sizeof[p - CSIL];
+ }
+
+#define ISPEC_TO_FORMAT(Spec, Min_format, Long_format, Max_format) \
+ ((Spec) == LONG_LONG ? (Max_format) \
+ : ((Spec) == LONG ? (Long_format) : (Min_format)))
+
+#define FMT_BYTES_ALLOCATED 9
+ size_spec = integral_type_size[size];
+
+ {
+ static const char doux[] = "doux";
+ static const char doux_fmt_letter[][4] = {
+ "lld", "llo", "llu", "llx"
+ };
+ static const enum output_format doux_fmt[] = {
+ SIGNED_DECIMAL,
+ OCTAL,
+ UNSIGNED_DECIMAL,
+ HEXADECIMAL,
+ };
+ static const uint8_t *const doux_bytes_to_XXX[] = {
+ bytes_to_signed_dec_digits,
+ bytes_to_oct_digits,
+ bytes_to_unsigned_dec_digits,
+ bytes_to_hex_digits,
+ };
+ static const char doux_fmtstring[][sizeof(" %%0%u%s")] = {
+ " %%%u%s",
+ " %%0%u%s",
+ " %%%u%s",
+ " %%0%u%s",
+ };
+
+ pos = strchr(doux, c) - doux;
+ fmt = doux_fmt[pos];
+ field_width = doux_bytes_to_XXX[pos][size];
+ p = doux_fmt_letter[pos] + 2;
+ if (size_spec == LONG) p--;
+ if (size_spec == LONG_LONG) p -= 2;
+ fmt_string = xasprintf(doux_fmtstring[pos], field_width, p);
+ }
+
+ switch (size_spec) {
+ case CHAR:
+ print_function = (fmt == SIGNED_DECIMAL
+ ? print_s_char
+ : print_char);
+ break;
+ case SHORT:
+ print_function = (fmt == SIGNED_DECIMAL
+ ? print_s_short
+ : print_short);
+ break;
+ case INT:
+ print_function = print_int;
+ break;
+ case LONG:
+ print_function = print_long;
+ break;
+ default: /* case LONG_LONG: */
+ print_function = print_long_long;
+ break;
+ }
+ break;
+ }
+
+ case 'f': {
+ static const char FDL[] = "FDL";
+
+ fmt = FLOATING_POINT;
+ ++s;
+ p = strchr(FDL, *s);
+ if (!p) {
+ size = sizeof(double);
+ if (isdigit(s[0])) {
+ size = bb_strtou(s, &end, 0);
+ if (errno == ERANGE || size > MAX_FP_TYPE_SIZE
+ || fp_type_size[size] == NO_SIZE
+ ) {
+ bb_error_msg_and_die("invalid type string '%s'; "
+ "%u-byte %s type is not supported",
+ s_orig, size, "floating point");
+ }
+ s = end;
+ }
+ } else {
+ static const uint8_t FDL_sizeof[] = {
+ sizeof(float),
+ sizeof(double),
+ sizeof(longdouble_t),
+ };
+
+ size = FDL_sizeof[p - FDL];
+ }
+
+ size_spec = fp_type_size[size];
+
+ switch (size_spec) {
+ case FLOAT_SINGLE:
+ print_function = print_float;
+ field_width = FLT_DIG + 8;
+ /* Don't use %#e; not all systems support it. */
+ fmt_string = xasprintf(" %%%d.%de", field_width, FLT_DIG);
+ break;
+ case FLOAT_DOUBLE:
+ print_function = print_double;
+ field_width = DBL_DIG + 8;
+ fmt_string = xasprintf(" %%%d.%de", field_width, DBL_DIG);
+ break;
+ default: /* case FLOAT_LONG_DOUBLE: */
+ print_function = print_long_double;
+ field_width = LDBL_DIG + 8;
+ fmt_string = xasprintf(" %%%d.%dLe", field_width, LDBL_DIG);
+ break;
+ }
+ break;
+ }
+
+ case 'a':
+ ++s;
+ fmt = NAMED_CHARACTER;
+ size_spec = CHAR;
+ print_function = print_named_ascii;
+ field_width = 3;
+ break;
+ case 'c':
+ ++s;
+ fmt = CHARACTER;
+ size_spec = CHAR;
+ print_function = print_ascii;
+ field_width = 3;
+ break;
+ default:
+ bb_error_msg_and_die("invalid character '%c' "
+ "in type string '%s'", *s, s_orig);
+ }
+
+ tspec->size = size_spec;
+ tspec->fmt = fmt;
+ tspec->print_function = print_function;
+ tspec->fmt_string = fmt_string;
+
+ tspec->field_width = field_width;
+ tspec->hexl_mode_trailer = (*s == 'z');
+ if (tspec->hexl_mode_trailer)
+ s++;
+
+ if (next != NULL)
+ *next = s;
+}
+
+/* Decode the modern od format string S. Append the decoded
+ representation to the global array SPEC, reallocating SPEC if
+ necessary. Return zero if S is valid, nonzero otherwise. */
+
+static void
+decode_format_string(const char *s)
+{
+ const char *s_orig = s;
+
+ while (*s != '\0') {
+ struct tspec tspec;
+ const char *next;
+
+ decode_one_format(s_orig, s, &next, &tspec);
+
+ assert(s != next);
+ s = next;
+ n_specs++;
+ spec = xrealloc(spec, n_specs * sizeof(*spec));
+ memcpy(&spec[n_specs-1], &tspec, sizeof *spec);
+ }
+}
+
+/* Given a list of one or more input filenames FILE_LIST, set the global
+ file pointer IN_STREAM to position N_SKIP in the concatenation of
+ those files. If any file operation fails or if there are fewer than
+ N_SKIP bytes in the combined input, give an error message and return
+ nonzero. When possible, use seek rather than read operations to
+ advance IN_STREAM. */
+
+static void
+skip(off_t n_skip)
+{
+ if (n_skip == 0)
+ return;
+
+ while (in_stream) { /* !EOF */
+ struct stat file_stats;
+
+ /* First try seeking. For large offsets, this extra work is
+ worthwhile. If the offset is below some threshold it may be
+ more efficient to move the pointer by reading. There are two
+ issues when trying to seek:
+ - the file must be seekable.
+ - before seeking to the specified position, make sure
+ that the new position is in the current file.
+ Try to do that by getting file's size using fstat.
+ But that will work only for regular files. */
+
+ /* The st_size field is valid only for regular files
+ (and for symbolic links, which cannot occur here).
+ If the number of bytes left to skip is at least
+ as large as the size of the current file, we can
+ decrement n_skip and go on to the next file. */
+ if (fstat(fileno(in_stream), &file_stats) == 0
+ && S_ISREG(file_stats.st_mode) && file_stats.st_size >= 0
+ ) {
+ if (file_stats.st_size < n_skip) {
+ n_skip -= file_stats.st_size;
+ /* take check&close / open_next route */
+ } else {
+ if (fseeko(in_stream, n_skip, SEEK_CUR) != 0)
+ ioerror = 1;
+ return;
+ }
+ } else {
+ /* If it's not a regular file with nonnegative size,
+ position the file pointer by reading. */
+ char buf[BUFSIZ];
+ size_t n_bytes_read, n_bytes_to_read = BUFSIZ;
+
+ while (n_skip > 0) {
+ if (n_skip < n_bytes_to_read)
+ n_bytes_to_read = n_skip;
+ n_bytes_read = fread(buf, 1, n_bytes_to_read, in_stream);
+ n_skip -= n_bytes_read;
+ if (n_bytes_read != n_bytes_to_read)
+ break; /* EOF on this file or error */
+ }
+ }
+ if (n_skip == 0)
+ return;
+
+ check_and_close();
+ open_next_file();
+ }
+
+ if (n_skip)
+ bb_error_msg_and_die("cannot skip past end of combined input");
+}
+
+
+typedef void FN_format_address(off_t address, char c);
+
+static void
+format_address_none(off_t address ATTRIBUTE_UNUSED, char c ATTRIBUTE_UNUSED)
+{
+}
+
+static char address_fmt[] = "%0n"OFF_FMT"xc";
+/* Corresponds to 'x' above */
+#define address_base_char address_fmt[sizeof(address_fmt)-3]
+/* Corresponds to 'n' above */
+#define address_pad_len_char address_fmt[2]
+
+static void
+format_address_std(off_t address, char c)
+{
+ /* Corresponds to 'c' */
+ address_fmt[sizeof(address_fmt)-2] = c;
+ printf(address_fmt, address);
+}
+
+#if ENABLE_GETOPT_LONG
+/* only used with --traditional */
+static void
+format_address_paren(off_t address, char c)
+{
+ putchar('(');
+ format_address_std(address, ')');
+ if (c) putchar(c);
+}
+
+static void
+format_address_label(off_t address, char c)
+{
+ format_address_std(address, ' ');
+ format_address_paren(address + pseudo_offset, c);
+}
+#endif
+
+static void
+dump_hexl_mode_trailer(size_t n_bytes, const char *block)
+{
+ fputs(" >", stdout);
+ while (n_bytes--) {
+ unsigned c = *(unsigned char *) block++;
+ c = (ISPRINT(c) ? c : '.');
+ putchar(c);
+ }
+ putchar('<');
+}
+
+/* Write N_BYTES bytes from CURR_BLOCK to standard output once for each
+ of the N_SPEC format specs. CURRENT_OFFSET is the byte address of
+ CURR_BLOCK in the concatenation of input files, and it is printed
+ (optionally) only before the output line associated with the first
+ format spec. When duplicate blocks are being abbreviated, the output
+ for a sequence of identical input blocks is the output for the first
+ block followed by an asterisk alone on a line. It is valid to compare
+ the blocks PREV_BLOCK and CURR_BLOCK only when N_BYTES == BYTES_PER_BLOCK.
+ That condition may be false only for the last input block -- and then
+ only when it has not been padded to length BYTES_PER_BLOCK. */
+
+static void
+write_block(off_t current_offset, size_t n_bytes,
+ const char *prev_block, const char *curr_block)
+{
+ static char first = 1;
+ static char prev_pair_equal = 0;
+ size_t i;
+
+ if (abbreviate_duplicate_blocks
+ && !first
+ && n_bytes == bytes_per_block
+ && memcmp(prev_block, curr_block, bytes_per_block) == 0
+ ) {
+ if (prev_pair_equal) {
+ /* The two preceding blocks were equal, and the current
+ block is the same as the last one, so print nothing. */
+ } else {
+ puts("*");
+ prev_pair_equal = 1;
+ }
+ } else {
+ first = 0;
+ prev_pair_equal = 0;
+ for (i = 0; i < n_specs; i++) {
+ if (i == 0)
+ format_address(current_offset, '\0');
+ else
+ printf("%*s", address_pad_len_char - '0', "");
+ (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string);
+ if (spec[i].hexl_mode_trailer) {
+ /* space-pad out to full line width, then dump the trailer */
+ int datum_width = width_bytes[spec[i].size];
+ int blank_fields = (bytes_per_block - n_bytes) / datum_width;
+ int field_width = spec[i].field_width + 1;
+ printf("%*s", blank_fields * field_width, "");
+ dump_hexl_mode_trailer(n_bytes, curr_block);
+ }
+ putchar('\n');
+ }
+ }
+}
+
+static void
+read_block(size_t n, char *block, size_t *n_bytes_in_buffer)
+{
+ assert(0 < n && n <= bytes_per_block);
+
+ *n_bytes_in_buffer = 0;
+
+ if (n == 0)
+ return;
+
+ while (in_stream != NULL) { /* EOF. */
+ size_t n_needed;
+ size_t n_read;
+
+ n_needed = n - *n_bytes_in_buffer;
+ n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, in_stream);
+ *n_bytes_in_buffer += n_read;
+ if (n_read == n_needed)
+ break;
+ /* error check is done in check_and_close */
+ check_and_close();
+ open_next_file();
+ }
+}
+
+/* Return the least common multiple of the sizes associated
+ with the format specs. */
+
+static int
+get_lcm(void)
+{
+ size_t i;
+ int l_c_m = 1;
+
+ for (i = 0; i < n_specs; i++)
+ l_c_m = lcm(l_c_m, width_bytes[(int) spec[i].size]);
+ return l_c_m;
+}
+
+#if ENABLE_GETOPT_LONG
+/* If S is a valid traditional offset specification with an optional
+ leading '+' return nonzero and set *OFFSET to the offset it denotes. */
+
+static int
+parse_old_offset(const char *s, off_t *offset)
+{
+ static const struct suffix_mult Bb[] = {
+ { "B", 1024 },
+ { "b", 512 },
+ { NULL, 0 }
+ };
+ char *p;
+ int radix;
+
+ /* Skip over any leading '+'. */
+ if (s[0] == '+') ++s;
+
+ /* Determine the radix we'll use to interpret S. If there is a '.',
+ * it's decimal, otherwise, if the string begins with '0X'or '0x',
+ * it's hexadecimal, else octal. */
+ p = strchr(s, '.');
+ radix = 8;
+ if (p) {
+ p[0] = '\0'; /* cheating */
+ radix = 10;
+ } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
+ radix = 16;
+
+ *offset = xstrtooff_sfx(s, radix, Bb);
+ if (p) p[0] = '.';
+
+ return (*offset >= 0);
+}
+#endif
+
+/* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
+ formatted block to standard output, and repeat until the specified
+ maximum number of bytes has been read or until all input has been
+ processed. If the last block read is smaller than BYTES_PER_BLOCK
+ and its size is not a multiple of the size associated with a format
+ spec, extend the input block with zero bytes until its length is a
+ multiple of all format spec sizes. Write the final block. Finally,
+ write on a line by itself the offset of the byte after the last byte
+ read. Accumulate return values from calls to read_block and
+ check_and_close, and if any was nonzero, return nonzero.
+ Otherwise, return zero. */
+
+static void
+dump(void)
+{
+ char *block[2];
+ off_t current_offset;
+ int idx;
+ size_t n_bytes_read;
+
+ block[0] = xmalloc(2*bytes_per_block);
+ block[1] = block[0] + bytes_per_block;
+
+ current_offset = n_bytes_to_skip;
+
+ idx = 0;
+ if (limit_bytes_to_format) {
+ while (1) {
+ size_t n_needed;
+ if (current_offset >= end_offset) {
+ n_bytes_read = 0;
+ break;
+ }
+ n_needed = MIN(end_offset - current_offset,
+ (off_t) bytes_per_block);
+ read_block(n_needed, block[idx], &n_bytes_read);
+ if (n_bytes_read < bytes_per_block)
+ break;
+ assert(n_bytes_read == bytes_per_block);
+ write_block(current_offset, n_bytes_read,
+ block[!idx], block[idx]);
+ current_offset += n_bytes_read;
+ idx = !idx;
+ }
+ } else {
+ while (1) {
+ read_block(bytes_per_block, block[idx], &n_bytes_read);
+ if (n_bytes_read < bytes_per_block)
+ break;
+ assert(n_bytes_read == bytes_per_block);
+ write_block(current_offset, n_bytes_read,
+ block[!idx], block[idx]);
+ current_offset += n_bytes_read;
+ idx = !idx;
+ }
+ }
+
+ if (n_bytes_read > 0) {
+ int l_c_m;
+ size_t bytes_to_write;
+
+ l_c_m = get_lcm();
+
+ /* Make bytes_to_write the smallest multiple of l_c_m that
+ is at least as large as n_bytes_read. */
+ bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
+
+ memset(block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
+ write_block(current_offset, bytes_to_write,
+ block[!idx], block[idx]);
+ current_offset += n_bytes_read;
+ }
+
+ format_address(current_offset, '\n');
+
+ if (limit_bytes_to_format && current_offset >= end_offset)
+ check_and_close();
+
+ free(block[0]);
+}
+
+/* Read a single byte into *C from the concatenation of the input files
+ named in the global array FILE_LIST. On the first call to this
+ function, the global variable IN_STREAM is expected to be an open
+ stream associated with the input file INPUT_FILENAME. If IN_STREAM
+ is at end-of-file, close it and update the global variables IN_STREAM
+ and INPUT_FILENAME so they correspond to the next file in the list.
+ Then try to read a byte from the newly opened file. Repeat if
+ necessary until EOF is reached for the last file in FILE_LIST, then
+ set *C to EOF and return. Subsequent calls do likewise. The return
+ value is nonzero if any errors occured, zero otherwise. */
+
+static void
+read_char(int *c)
+{
+ while (in_stream) { /* !EOF */
+ *c = fgetc(in_stream);
+ if (*c != EOF)
+ return;
+ check_and_close();
+ open_next_file();
+ }
+ *c = EOF;
+}
+
+/* Read N bytes into BLOCK from the concatenation of the input files
+ named in the global array FILE_LIST. On the first call to this
+ function, the global variable IN_STREAM is expected to be an open
+ stream associated with the input file INPUT_FILENAME. If all N
+ bytes cannot be read from IN_STREAM, close IN_STREAM and update
+ the global variables IN_STREAM and INPUT_FILENAME. Then try to
+ read the remaining bytes from the newly opened file. Repeat if
+ necessary until EOF is reached for the last file in FILE_LIST.
+ On subsequent calls, don't modify BLOCK and return zero. Set
+ *N_BYTES_IN_BUFFER to the number of bytes read. If an error occurs,
+ it will be detected through ferror when the stream is about to be
+ closed. If there is an error, give a message but continue reading
+ as usual and return nonzero. Otherwise return zero. */
+
+/* STRINGS mode. Find each "string constant" in the input.
+ A string constant is a run of at least 'string_min' ASCII
+ graphic (or formatting) characters terminated by a null.
+ Based on a function written by Richard Stallman for a
+ traditional version of od. Return nonzero if an error
+ occurs. Otherwise, return zero. */
+
+static void
+dump_strings(void)
+{
+ size_t bufsize = MAX(100, string_min);
+ char *buf = xmalloc(bufsize);
+ off_t address = n_bytes_to_skip;
+
+ while (1) {
+ size_t i;
+ int c;
+
+ /* See if the next 'string_min' chars are all printing chars. */
+ tryline:
+ if (limit_bytes_to_format && (end_offset - string_min <= address))
+ break;
+ i = 0;
+ while (!limit_bytes_to_format || address < end_offset) {
+ if (i == bufsize) {
+ bufsize += bufsize/8;
+ buf = xrealloc(buf, bufsize);
+ }
+ read_char(&c);
+ if (c < 0) { /* EOF */
+ free(buf);
+ return;
+ }
+ address++;
+ if (!c)
+ break;
+ if (!ISPRINT(c))
+ goto tryline; /* It isn't; give up on this string. */
+ buf[i++] = c; /* String continues; store it all. */
+ }
+
+ if (i < string_min) /* Too short! */
+ goto tryline;
+
+ /* If we get here, the string is all printable and null-terminated,
+ * so print it. It is all in 'buf' and 'i' is its length. */
+ buf[i] = 0;
+ format_address(address - i - 1, ' ');
+
+ for (i = 0; (c = buf[i]); i++) {
+ switch (c) {
+ case '\007': fputs("\\a", stdout); break;
+ case '\b': fputs("\\b", stdout); break;
+ case '\f': fputs("\\f", stdout); break;
+ case '\n': fputs("\\n", stdout); break;
+ case '\r': fputs("\\r", stdout); break;
+ case '\t': fputs("\\t", stdout); break;
+ case '\v': fputs("\\v", stdout); break;
+ default: putc(c, stdout);
+ }
+ }
+ putchar('\n');
+ }
+
+ /* We reach this point only if we search through
+ (max_bytes_to_format - string_min) bytes before reaching EOF. */
+ free(buf);
+
+ check_and_close();
+}
+
+int od_main(int argc, char **argv);
+int od_main(int argc, char **argv)
+{
+ static const struct suffix_mult bkm[] = {
+ { "b", 512 },
+ { "k", 1024 },
+ { "m", 1024*1024 },
+ { NULL, 0 }
+ };
+ unsigned opt;
+ int l_c_m;
+ /* The old-style 'pseudo starting address' to be printed in parentheses
+ after any true address. */
+ off_t pseudo_start = 0; // only for gcc
+ enum {
+ OPT_A = 1 << 0,
+ OPT_N = 1 << 1,
+ OPT_a = 1 << 2,
+ OPT_b = 1 << 3,
+ OPT_c = 1 << 4,
+ OPT_d = 1 << 5,
+ OPT_f = 1 << 6,
+ OPT_h = 1 << 7,
+ OPT_i = 1 << 8,
+ OPT_j = 1 << 9,
+ OPT_l = 1 << 10,
+ OPT_o = 1 << 11,
+ OPT_t = 1 << 12,
+ OPT_v = 1 << 13,
+ OPT_x = 1 << 14,
+ OPT_s = 1 << 15,
+ OPT_S = 1 << 16,
+ OPT_w = 1 << 17,
+ OPT_traditional = (1 << 18) * ENABLE_GETOPT_LONG,
+ };
+#if ENABLE_GETOPT_LONG
+ static const struct option long_options[] = {
+ { "skip-bytes", required_argument, NULL, 'j' },
+ { "address-radix", required_argument, NULL, 'A' },
+ { "read-bytes", required_argument, NULL, 'N' },
+ { "format", required_argument, NULL, 't' },
+ { "output-duplicates", no_argument, NULL, 'v' },
+ { "strings", optional_argument, NULL, 'S' },
+ { "width", optional_argument, NULL, 'w' },
+ { "traditional", no_argument, NULL, 0xff },
+ { NULL, 0, NULL, 0 }
+ };
+#endif
+ char *str_A, *str_N, *str_j, *str_S;
+ char *str_w = NULL;
+ llist_t *lst_t = NULL;
+
+ spec = NULL;
+ format_address = format_address_std;
+ address_base_char = 'o';
+ address_pad_len_char = '7';
+ flag_dump_strings = 0;
+
+ /* Parse command line */
+ opt_complementary = "t::"; // list
+#if ENABLE_GETOPT_LONG
+ applet_long_options = long_options;
+#endif
+ opt = getopt32(argc, argv, "A:N:abcdfhij:lot:vxsS:"
+ "w::", // -w with optional param
+ // -S was -s and also had optional parameter
+ // but in coreutils 6.3 it was renamed and now has
+ // _mandatory_ parameter
+ &str_A, &str_N, &str_j, &lst_t, &str_S, &str_w);
+ argc -= optind;
+ argv += optind;
+ if (opt & OPT_A) {
+ static const char doxn[] = "doxn";
+ static const char doxn_address_base_char[] = {
+ 'u', 'o', 'x', /* '?' fourth one is not important */
+ };
+ static const uint8_t doxn_address_pad_len_char[] = {
+ '7', '7', '6', /* '?' */
+ };
+ char *p;
+ int pos;
+ p = strchr(doxn, str_A[0]);
+ if (!p)
+ bb_error_msg_and_die("bad output address radix "
+ "'%c' (must be [doxn])", str_A[0]);
+ pos = p - doxn;
+ if (pos == 3) format_address = format_address_none;
+ address_base_char = doxn_address_base_char[pos];
+ address_pad_len_char = doxn_address_pad_len_char[pos];
+ }
+ if (opt & OPT_N) {
+ limit_bytes_to_format = 1;
+ max_bytes_to_format = xstrtooff_sfx(str_N, 0, bkm);
+ }
+ if (opt & OPT_a) decode_format_string("a");
+ if (opt & OPT_b) decode_format_string("oC");
+ if (opt & OPT_c) decode_format_string("c");
+ if (opt & OPT_d) decode_format_string("u2");
+ if (opt & OPT_f) decode_format_string("fF");
+ if (opt & OPT_h) decode_format_string("x2");
+ if (opt & OPT_i) decode_format_string("d2");
+ if (opt & OPT_j) n_bytes_to_skip = xstrtooff_sfx(str_j, 0, bkm);
+ if (opt & OPT_l) decode_format_string("d4");
+ if (opt & OPT_o) decode_format_string("o2");
+ //if (opt & OPT_t)...
+ lst_t = llist_rev(lst_t);
+ while (lst_t) {
+ decode_format_string(lst_t->data);
+ lst_t = lst_t->link;
+ }
+ if (opt & OPT_v) abbreviate_duplicate_blocks = 0;
+ if (opt & OPT_x) decode_format_string("x2");
+ if (opt & OPT_s) decode_format_string("d2");
+ if (opt & OPT_S) {
+ string_min = 3;
+ string_min = xstrtou_sfx(str_S, 0, bkm);
+ flag_dump_strings = 1;
+ }
+ //if (opt & OPT_w)...
+ //if (opt & OPT_traditional)...
+
+ if (flag_dump_strings && n_specs > 0)
+ bb_error_msg_and_die("no type may be specified when dumping strings");
+
+ /* If the --traditional option is used, there may be from
+ * 0 to 3 remaining command line arguments; handle each case
+ * separately.
+ * od [file] [[+]offset[.][b] [[+]label[.][b]]]
+ * The offset and pseudo_start have the same syntax.
+ *
+ * FIXME: POSIX 1003.1-2001 with XSI requires support for the
+ * traditional syntax even if --traditional is not given. */
+
+#if ENABLE_GETOPT_LONG
+ if (opt & OPT_traditional) {
+ off_t o1, o2;
+
+ if (argc == 1) {
+ if (parse_old_offset(argv[0], &o1)) {
+ n_bytes_to_skip = o1;
+ --argc;
+ ++argv;
+ }
+ } else if (argc == 2) {
+ if (parse_old_offset(argv[0], &o1)
+ && parse_old_offset(argv[1], &o2)
+ ) {
+ n_bytes_to_skip = o1;
+ flag_pseudo_start = 1;
+ pseudo_start = o2;
+ argv += 2;
+ argc -= 2;
+ } else if (parse_old_offset(argv[1], &o2)) {
+ n_bytes_to_skip = o2;
+ --argc;
+ argv[1] = argv[0];
+ ++argv;
+ } else {
+ bb_error_msg_and_die("invalid second operand "
+ "in compatibility mode '%s'", argv[1]);
+ }
+ } else if (argc == 3) {
+ if (parse_old_offset(argv[1], &o1)
+ && parse_old_offset(argv[2], &o2)
+ ) {
+ n_bytes_to_skip = o1;
+ flag_pseudo_start = 1;
+ pseudo_start = o2;
+ argv[2] = argv[0];
+ argv += 2;
+ argc -= 2;
+ } else {
+ bb_error_msg_and_die("in compatibility mode "
+ "the last two arguments must be offsets");
+ }
+ } else if (argc > 3) {
+ bb_error_msg_and_die("compatibility mode supports "
+ "at most three arguments");
+ }
+
+ if (flag_pseudo_start) {
+ if (format_address == format_address_none) {
+ address_base_char = 'o';
+ address_pad_len_char = '7';
+ format_address = format_address_paren;
+ } else
+ format_address = format_address_label;
+ }
+ }
+#endif
+
+ if (limit_bytes_to_format) {
+ end_offset = n_bytes_to_skip + max_bytes_to_format;
+ if (end_offset < n_bytes_to_skip)
+ bb_error_msg_and_die("skip-bytes + read-bytes is too large");
+ }
+
+ if (n_specs == 0) {
+ decode_format_string("o2");
+ n_specs = 1;
+ }
+
+ /* If no files were listed on the command line,
+ set the global pointer FILE_LIST so that it
+ references the null-terminated list of one name: "-". */
+ file_list = default_file_list;
+ if (argc > 0) {
+ /* Set the global pointer FILE_LIST so that it
+ references the first file-argument on the command-line. */
+ file_list = (char const *const *) argv;
+ }
+
+ /* open the first input file */
+ open_next_file();
+ /* skip over any unwanted header bytes */
+ skip(n_bytes_to_skip);
+ if (!in_stream)
+ return 1;
+
+ pseudo_offset = (flag_pseudo_start ? pseudo_start - n_bytes_to_skip : 0);
+
+ /* Compute output block length. */
+ l_c_m = get_lcm();
+
+ if (opt & OPT_w) { /* -w: width */
+ bytes_per_block = 32;
+ if (str_w)
+ bytes_per_block = xatou(str_w);
+ if (!bytes_per_block || bytes_per_block % l_c_m != 0) {
+ bb_error_msg("warning: invalid width %zu; using %d instead",
+ bytes_per_block, l_c_m);
+ bytes_per_block = l_c_m;
+ }
+ } else {
+ bytes_per_block = l_c_m;
+ if (l_c_m < DEFAULT_BYTES_PER_BLOCK)
+ bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m;
+ }
+
+#ifdef DEBUG
+ for (i = 0; i < n_specs; i++) {
+ printf("%d: fmt=\"%s\" width=%d\n",
+ i, spec[i].fmt_string, width_bytes[spec[i].size]);
+ }
+#endif
+
+ if (flag_dump_strings)
+ dump_strings();
+ else
+ dump();
+
+ if (fclose(stdin) == EOF)
+ bb_perror_msg_and_die(bb_msg_standard_input);
+
+ return (ioerror != 0); /* err != 0 - return 1 (failure) */
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/printenv.c b/i/pc104/initrd/conf/busybox/coreutils/printenv.c
new file mode 100644
index 0000000..1d41eeb
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/printenv.c
@@ -0,0 +1,42 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * printenv implementation for busybox
+ *
+ * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
+ * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "busybox.h"
+
+int printenv_main(int argc, char **argv);
+int printenv_main(int argc, char **argv)
+{
+ extern char **environ;
+ int e = 0;
+
+ /* no variables specified, show whole env */
+ if (argc == 1)
+ while (environ[e])
+ puts(environ[e++]);
+
+ /* search for specified variables and print them out if found */
+ else {
+ int i;
+ size_t l;
+ char *arg, *env;
+
+ for (i=1; (arg = argv[i]); ++i)
+ for (; (env = environ[e]); ++e) {
+ l = strlen(arg);
+ if (!strncmp(env, arg, l) && env[l] == '=')
+ puts(env + l + 1);
+ }
+ }
+
+ fflush_stdout_and_exit(0);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/printf.c b/i/pc104/initrd/conf/busybox/coreutils/printf.c
new file mode 100644
index 0000000..a2a82d2
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/printf.c
@@ -0,0 +1,313 @@
+/* vi: set sw=4 ts=4: */
+/* printf - format and print data
+
+ Copyright 1999 Dave Cinege
+ Portions copyright (C) 1990-1996 Free Software Foundation, Inc.
+
+ Licensed under GPL v2 or later, see file LICENSE in this tarball for details.
+*/
+
+/* Usage: printf format [argument...]
+
+ A front end to the printf function that lets it be used from the shell.
+
+ Backslash escapes:
+
+ \" = double quote
+ \\ = backslash
+ \a = alert (bell)
+ \b = backspace
+ \c = produce no further output
+ \f = form feed
+ \n = new line
+ \r = carriage return
+ \t = horizontal tab
+ \v = vertical tab
+ \0ooo = octal number (ooo is 0 to 3 digits)
+ \xhhh = hexadecimal number (hhh is 1 to 3 digits)
+
+ Additional directive:
+
+ %b = print an argument string, interpreting backslash escapes
+
+ The 'format' argument is re-used as many times as necessary
+ to convert all of the given arguments.
+
+ David MacKenzie <djm@gnu.ai.mit.edu> */
+
+
+// 19990508 Busy Boxed! Dave Cinege
+
+#include "busybox.h"
+
+typedef void (*converter)(const char *arg, void *result);
+
+static void multiconvert(const char *arg, void *result, converter convert)
+{
+ char s[sizeof(int)*3 + 2];
+
+ if (*arg == '"' || *arg == '\'') {
+ sprintf(s, "%d", (unsigned char)arg[1]);
+ arg = s;
+ }
+ convert(arg, result);
+ /* if there was conversion error, print unconverted string */
+ if (errno)
+ fputs(arg, stderr);
+}
+
+static void conv_strtoul(const char *arg, void *result)
+{
+ *(unsigned long*)result = bb_strtoul(arg, NULL, 0);
+}
+static void conv_strtol(const char *arg, void *result)
+{
+ *(long*)result = bb_strtol(arg, NULL, 0);
+}
+static void conv_strtod(const char *arg, void *result)
+{
+ char *end;
+ /* Well, this one allows leading whitespace... so what */
+ /* What I like much less is that "-" is accepted too! :( */
+ *(double*)result = strtod(arg, &end);
+ if (end[0]) errno = ERANGE;
+}
+
+static unsigned long my_xstrtoul(const char *arg)
+{
+ unsigned long result;
+ multiconvert(arg, &result, conv_strtoul);
+ return result;
+}
+
+static long my_xstrtol(const char *arg)
+{
+ long result;
+ multiconvert(arg, &result, conv_strtol);
+ return result;
+}
+
+static double my_xstrtod(const char *arg)
+{
+ double result;
+ multiconvert(arg, &result, conv_strtod);
+ return result;
+}
+
+static void print_esc_string(char *str)
+{
+ for (; *str; str++) {
+ if (*str == '\\') {
+ str++;
+ putchar(bb_process_escape_sequence((const char **)&str));
+ } else {
+ putchar(*str);
+ }
+
+ }
+}
+
+static void print_direc(char *start, size_t length, int field_width, int precision,
+ const char *argument)
+{
+ char *p; /* Null-terminated copy of % directive. */
+
+ p = xmalloc((unsigned) (length + 1));
+ strncpy(p, start, length);
+ p[length] = 0;
+
+ switch (p[length - 1]) {
+ case 'd':
+ case 'i':
+ if (field_width < 0) {
+ if (precision < 0)
+ printf(p, my_xstrtol(argument));
+ else
+ printf(p, precision, my_xstrtol(argument));
+ } else {
+ if (precision < 0)
+ printf(p, field_width, my_xstrtol(argument));
+ else
+ printf(p, field_width, precision, my_xstrtol(argument));
+ }
+ break;
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ if (field_width < 0) {
+ if (precision < 0)
+ printf(p, my_xstrtoul(argument));
+ else
+ printf(p, precision, my_xstrtoul(argument));
+ } else {
+ if (precision < 0)
+ printf(p, field_width, my_xstrtoul(argument));
+ else
+ printf(p, field_width, precision, my_xstrtoul(argument));
+ }
+ break;
+ case 'f':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ if (field_width < 0) {
+ if (precision < 0)
+ printf(p, my_xstrtod(argument));
+ else
+ printf(p, precision, my_xstrtod(argument));
+ } else {
+ if (precision < 0)
+ printf(p, field_width, my_xstrtod(argument));
+ else
+ printf(p, field_width, precision, my_xstrtod(argument));
+ }
+ break;
+ case 'c':
+ printf(p, *argument);
+ break;
+ case 's':
+ if (field_width < 0) {
+ if (precision < 0)
+ printf(p, argument);
+ else
+ printf(p, precision, argument);
+ } else {
+ if (precision < 0)
+ printf(p, field_width, argument);
+ else
+ printf(p, field_width, precision, argument);
+ }
+ break;
+ }
+
+ free(p);
+}
+
+/* Print the text in FORMAT, using ARGV (with ARGC elements) for
+ arguments to any '%' directives.
+ Return the number of elements of ARGV used. */
+
+static int print_formatted(char *format, int argc, char **argv)
+{
+ int save_argc = argc; /* Preserve original value. */
+ char *f; /* Pointer into 'format'. */
+ char *direc_start; /* Start of % directive. */
+ size_t direc_length; /* Length of % directive. */
+ int field_width; /* Arg to first '*', or -1 if none. */
+ int precision; /* Arg to second '*', or -1 if none. */
+
+ for (f = format; *f; ++f) {
+ switch (*f) {
+ case '%':
+ direc_start = f++;
+ direc_length = 1;
+ field_width = precision = -1;
+ if (*f == '%') {
+ putchar('%');
+ break;
+ }
+ if (*f == 'b') {
+ if (argc > 0) {
+ print_esc_string(*argv);
+ ++argv;
+ --argc;
+ }
+ break;
+ }
+ if (strchr("-+ #", *f)) {
+ ++f;
+ ++direc_length;
+ }
+ if (*f == '*') {
+ ++f;
+ ++direc_length;
+ if (argc > 0) {
+ field_width = my_xstrtoul(*argv);
+ ++argv;
+ --argc;
+ } else
+ field_width = 0;
+ } else {
+ while (isdigit(*f)) {
+ ++f;
+ ++direc_length;
+ }
+ }
+ if (*f == '.') {
+ ++f;
+ ++direc_length;
+ if (*f == '*') {
+ ++f;
+ ++direc_length;
+ if (argc > 0) {
+ precision = my_xstrtoul(*argv);
+ ++argv;
+ --argc;
+ } else
+ precision = 0;
+ } else
+ while (isdigit(*f)) {
+ ++f;
+ ++direc_length;
+ }
+ }
+ if (*f == 'l' || *f == 'L' || *f == 'h') {
+ ++f;
+ ++direc_length;
+ }
+ /*
+ if (!strchr ("diouxXfeEgGcs", *f))
+ fprintf(stderr, "%%%c: invalid directive", *f);
+ */
+ ++direc_length;
+ if (argc > 0) {
+ print_direc(direc_start, direc_length, field_width,
+ precision, *argv);
+ ++argv;
+ --argc;
+ } else
+ print_direc(direc_start, direc_length, field_width,
+ precision, "");
+ break;
+ case '\\':
+ if (*++f == 'c')
+ exit(0);
+ putchar(bb_process_escape_sequence((const char **)&f));
+ f--;
+ break;
+ default:
+ putchar(*f);
+ }
+ }
+
+ return save_argc - argc;
+}
+
+int printf_main(int argc, char **argv);
+int printf_main(int argc, char **argv)
+{
+ char *format;
+ int args_used;
+
+ if (argc <= 1 || argv[1][0] == '-') {
+ bb_show_usage();
+ }
+
+ format = argv[1];
+ argc -= 2;
+ argv += 2;
+
+ do {
+ args_used = print_formatted(format, argc, argv);
+ argc -= args_used;
+ argv += args_used;
+ } while (args_used > 0 && argc > 0);
+
+/* if (argc > 0)
+ fprintf(stderr, "excess args ignored");
+*/
+
+ return EXIT_SUCCESS;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/pwd.c b/i/pc104/initrd/conf/busybox/coreutils/pwd.c
new file mode 100644
index 0000000..d96f6a8
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/pwd.c
@@ -0,0 +1,26 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini pwd implementation for busybox
+ *
+ * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "busybox.h"
+
+int pwd_main(int argc, char **argv);
+int pwd_main(int argc, char **argv)
+{
+ char *buf;
+
+ buf = xrealloc_getcwd_or_warn(NULL);
+ if (buf != NULL) {
+ puts(buf);
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+ }
+
+ return EXIT_FAILURE;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/realpath.c b/i/pc104/initrd/conf/busybox/coreutils/realpath.c
new file mode 100644
index 0000000..b3f7e49
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/realpath.c
@@ -0,0 +1,47 @@
+/* vi: set sw=4 ts=4: */
+
+/* BB_AUDIT SUSv3 N/A -- Apparently a busybox extension. */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Now does proper error checking on output and returns a failure exit code
+ * if one or more paths cannot be resolved.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+
+int realpath_main(int argc, char **argv);
+int realpath_main(int argc, char **argv)
+{
+ int retval = EXIT_SUCCESS;
+
+#if PATH_MAX > (BUFSIZ+1)
+ RESERVE_CONFIG_BUFFER(resolved_path, PATH_MAX);
+# define resolved_path_MUST_FREE 1
+#else
+#define resolved_path bb_common_bufsiz1
+# define resolved_path_MUST_FREE 0
+#endif
+
+ if (--argc == 0) {
+ bb_show_usage();
+ }
+
+ do {
+ argv++;
+ if (realpath(*argv, resolved_path) != NULL) {
+ puts(resolved_path);
+ } else {
+ retval = EXIT_FAILURE;
+ bb_perror_msg("%s", *argv);
+ }
+ } while (--argc);
+
+#if ENABLE_FEATURE_CLEAN_UP && resolved_path_MUST_FREE
+ RELEASE_CONFIG_BUFFER(resolved_path);
+#endif
+
+ fflush_stdout_and_exit(retval);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/rm.c b/i/pc104/initrd/conf/busybox/coreutils/rm.c
new file mode 100644
index 0000000..1883fee
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/rm.c
@@ -0,0 +1,53 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini rm implementation for busybox
+ *
+ * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/rm.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Size reduction.
+ */
+
+#include <unistd.h>
+#include "busybox.h"
+
+int rm_main(int argc, char **argv);
+int rm_main(int argc, char **argv)
+{
+ int status = 0;
+ int flags = 0;
+ unsigned opt;
+
+ opt_complementary = "f-i:i-f";
+ opt = getopt32(argc, argv, "fiRr");
+ if(opt & 1)
+ flags |= FILEUTILS_FORCE;
+ if(opt & 2)
+ flags |= FILEUTILS_INTERACTIVE;
+ if(opt & 12)
+ flags |= FILEUTILS_RECUR;
+
+ if (*(argv += optind) != NULL) {
+ do {
+ const char *base = bb_get_last_path_component(*argv);
+
+ if ((base[0] == '.') && (!base[1] || ((base[1] == '.') && !base[2]))) {
+ bb_error_msg("cannot remove '.' or '..'");
+ } else if (remove_file(*argv, flags) >= 0) {
+ continue;
+ }
+ status = 1;
+ } while (*++argv);
+ } else if (!(flags & FILEUTILS_FORCE)) {
+ bb_show_usage();
+ }
+
+ return status;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/rmdir.c b/i/pc104/initrd/conf/busybox/coreutils/rmdir.c
new file mode 100644
index 0000000..8cbd6f1
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/rmdir.c
@@ -0,0 +1,61 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * rmdir implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <libgen.h>
+#include "busybox.h"
+
+int rmdir_main(int argc, char **argv);
+int rmdir_main(int argc, char **argv)
+{
+ int status = EXIT_SUCCESS;
+ int flags;
+ int do_dot;
+ char *path;
+
+ flags = getopt32(argc, argv, "p");
+
+ argv += optind;
+
+ if (!*argv) {
+ bb_show_usage();
+ }
+
+ do {
+ path = *argv;
+
+ /* Record if the first char was a '.' so we can use dirname later. */
+ do_dot = (*path == '.');
+
+ do {
+ if (rmdir(path) < 0) {
+ bb_perror_msg("'%s'", path); /* Match gnu rmdir msg. */
+ status = EXIT_FAILURE;
+ } else if (flags) {
+ /* Note: path was not empty or null since rmdir succeeded. */
+ path = dirname(path);
+ /* Path is now just the parent component. Note that dirname
+ * returns "." if there are no parents. We must distinguish
+ * this from the case of the original path starting with '.'.
+ */
+ if (do_dot || (*path != '.') || path[1]) {
+ continue;
+ }
+ }
+ break;
+ } while (1);
+
+ } while (*++argv);
+
+ return status;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/seq.c b/i/pc104/initrd/conf/busybox/coreutils/seq.c
new file mode 100644
index 0000000..e81a466
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/seq.c
@@ -0,0 +1,41 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * seq implementation for busybox
+ *
+ * Copyright (C) 2004, Glenn McGrath
+ *
+ * Licensed under the GPL v2, see the file LICENSE in this tarball.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "busybox.h"
+
+int seq_main(int argc, char **argv);
+int seq_main(int argc, char **argv)
+{
+ double last, first, increment, i;
+
+ first = increment = 1;
+ switch (argc) {
+ case 4:
+ increment = atof(argv[2]);
+ case 3:
+ first = atof(argv[1]);
+ case 2:
+ last = atof(argv[argc-1]);
+ break;
+ default:
+ bb_show_usage();
+ }
+
+ /* You should note that this is pos-5.0.91 semantics, -- FK. */
+ for (i = first;
+ (increment > 0 && i <= last) || (increment < 0 && i >=last);
+ i += increment)
+ {
+ printf("%g\n", i);
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/sleep.c b/i/pc104/initrd/conf/busybox/coreutils/sleep.c
new file mode 100644
index 0000000..b89b0fe
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/sleep.c
@@ -0,0 +1,68 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * sleep implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* BB_AUDIT GNU issues -- fancy version matches except args must be ints. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/sleep.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Rewritten to do proper arg and error checking.
+ * Also, added a 'fancy' configuration to accept multiple args with
+ * time suffixes for seconds, minutes, hours, and days.
+ */
+
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+#include "busybox.h"
+
+#ifdef CONFIG_FEATURE_FANCY_SLEEP
+static const struct suffix_mult sfx[] = {
+ { "s", 1 },
+ { "m", 60 },
+ { "h", 60*60 },
+ { "d", 24*60*60 },
+ { NULL, 0 }
+};
+#endif
+
+int sleep_main(int argc, char **argv);
+int sleep_main(int argc, char **argv)
+{
+ unsigned int duration;
+
+#ifdef CONFIG_FEATURE_FANCY_SLEEP
+
+ if (argc < 2) {
+ bb_show_usage();
+ }
+
+ ++argv;
+ duration = 0;
+ do {
+ duration += xatoul_range_sfx(*argv, 0, UINT_MAX-duration, sfx);
+ } while (*++argv);
+
+#else /* CONFIG_FEATURE_FANCY_SLEEP */
+
+ if (argc != 2) {
+ bb_show_usage();
+ }
+
+ duration = xatou(argv[1]);
+
+#endif /* CONFIG_FEATURE_FANCY_SLEEP */
+
+ if (sleep(duration)) {
+ bb_perror_nomsg_and_die();
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/sort.c b/i/pc104/initrd/conf/busybox/coreutils/sort.c
new file mode 100644
index 0000000..311d0cb
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/sort.c
@@ -0,0 +1,401 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * SuS3 compliant sort implementation for busybox
+ *
+ * Copyright (C) 2004 by Rob Landley <rob@landley.net>
+ *
+ * MAINTAINER: Rob Landley <rob@landley.net>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ * See SuS3 sort standard at:
+ * http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html
+ */
+
+#include "busybox.h"
+
+/*
+ sort [-m][-o output][-bdfinru][-t char][-k keydef]... [file...]
+ sort -c [-bdfinru][-t char][-k keydef][file]
+*/
+
+/* These are sort types */
+static const char OPT_STR[] = "ngMucszbrdfimS:T:o:k:t:";
+enum {
+ FLAG_n = 1, /* Numeric sort */
+ FLAG_g = 2, /* Sort using strtod() */
+ FLAG_M = 4, /* Sort date */
+/* ucsz apply to root level only, not keys. b at root level implies bb */
+ FLAG_u = 8, /* Unique */
+ FLAG_c = 0x10, /* Check: no output, exit(!ordered) */
+ FLAG_s = 0x20, /* Stable sort, no ascii fallback at end */
+ FLAG_z = 0x40, /* Input is null terminated, not \n */
+/* These can be applied to search keys, the previous four can't */
+ FLAG_b = 0x80, /* Ignore leading blanks */
+ FLAG_r = 0x100, /* Reverse */
+ FLAG_d = 0x200, /* Ignore !(isalnum()|isspace()) */
+ FLAG_f = 0x400, /* Force uppercase */
+ FLAG_i = 0x800, /* Ignore !isprint() */
+ FLAG_m = 0x1000, /* ignored: merge already sorted files; do not sort */
+ FLAG_S = 0x2000, /* ignored: -S, --buffer-size=SIZE */
+ FLAG_T = 0x4000, /* ignored: -T, --temporary-directory=DIR */
+ FLAG_o = 0x8000,
+ FLAG_k = 0x10000,
+ FLAG_t = 0x20000,
+ FLAG_bb = 0x80000000, /* Ignore trailing blanks */
+};
+
+#if ENABLE_FEATURE_SORT_BIG
+static char key_separator;
+
+static struct sort_key {
+ struct sort_key *next_key; /* linked list */
+ unsigned range[4]; /* start word, start char, end word, end char */
+ unsigned flags;
+} *key_list;
+
+static char *get_key(char *str, struct sort_key *key, int flags)
+{
+ int start = 0, end = 0, len, i, j;
+
+ /* Special case whole string, so we don't have to make a copy */
+ if (key->range[0] == 1 && !key->range[1] && !key->range[2] && !key->range[3]
+ && !(flags & (FLAG_b | FLAG_d | FLAG_f | FLAG_i | FLAG_bb))
+ ) {
+ return str;
+ }
+
+ /* Find start of key on first pass, end on second pass */
+ len = strlen(str);
+ for (j = 0; j < 2; j++) {
+ if (!key->range[2*j])
+ end = len;
+ /* Loop through fields */
+ else {
+ end = 0;
+ for (i = 1; i < key->range[2*j] + j; i++) {
+ if (key_separator) {
+ /* Skip body of key and separator */
+ while (str[end]) {
+ if (str[end++] == key_separator)
+ break;
+ }
+ } else {
+ /* Skip leading blanks */
+ while (isspace(str[end]))
+ end++;
+ /* Skip body of key */
+ while (str[end]) {
+ if (isspace(str[end]))
+ break;
+ end++;
+ }
+ }
+ }
+ }
+ if (!j) start = end;
+ }
+ /* Strip leading whitespace if necessary */
+//XXX: skip_whitespace()
+ if (flags & FLAG_b)
+ while (isspace(str[start])) start++;
+ /* Strip trailing whitespace if necessary */
+ if (flags & FLAG_bb)
+ while (end > start && isspace(str[end-1])) end--;
+ /* Handle offsets on start and end */
+ if (key->range[3]) {
+ end += key->range[3] - 1;
+ if (end > len) end = len;
+ }
+ if (key->range[1]) {
+ start += key->range[1] - 1;
+ if (start > len) start = len;
+ }
+ /* Make the copy */
+ if (end < start) end = start;
+ str = xstrndup(str+start, end-start);
+ /* Handle -d */
+ if (flags & FLAG_d) {
+ for (start = end = 0; str[end]; end++)
+ if (isspace(str[end]) || isalnum(str[end]))
+ str[start++] = str[end];
+ str[start] = '\0';
+ }
+ /* Handle -i */
+ if (flags & FLAG_i) {
+ for (start = end = 0; str[end]; end++)
+ if (isprint(str[end]))
+ str[start++] = str[end];
+ str[start] = '\0';
+ }
+ /* Handle -f */
+ if (flags & FLAG_f)
+ for (i = 0; str[i]; i++)
+ str[i] = toupper(str[i]);
+
+ return str;
+}
+
+static struct sort_key *add_key(void)
+{
+ struct sort_key **pkey = &key_list;
+ while (*pkey)
+ pkey = &((*pkey)->next_key);
+ return *pkey = xzalloc(sizeof(struct sort_key));
+}
+
+#define GET_LINE(fp) \
+ ((option_mask32 & FLAG_z) \
+ ? bb_get_chunk_from_file(fp, NULL) \
+ : xmalloc_getline(fp))
+#else
+#define GET_LINE(fp) xmalloc_getline(fp)
+#endif
+
+/* Iterate through keys list and perform comparisons */
+static int compare_keys(const void *xarg, const void *yarg)
+{
+ int flags = option_mask32, retval = 0;
+ char *x, *y;
+
+#if ENABLE_FEATURE_SORT_BIG
+ struct sort_key *key;
+
+ for (key = key_list; !retval && key; key = key->next_key) {
+ flags = key->flags ? key->flags : option_mask32;
+ /* Chop out and modify key chunks, handling -dfib */
+ x = get_key(*(char **)xarg, key, flags);
+ y = get_key(*(char **)yarg, key, flags);
+#else
+ /* This curly bracket serves no purpose but to match the nesting
+ level of the for () loop we're not using */
+ {
+ x = *(char **)xarg;
+ y = *(char **)yarg;
+#endif
+ /* Perform actual comparison */
+ switch (flags & 7) {
+ default:
+ bb_error_msg_and_die("unknown sort type");
+ break;
+ /* Ascii sort */
+ case 0:
+#if ENABLE_LOCALE_SUPPORT
+ retval = strcoll(x, y);
+#else
+ retval = strcmp(x, y);
+#endif
+ break;
+#if ENABLE_FEATURE_SORT_BIG
+ case FLAG_g: {
+ char *xx, *yy;
+ double dx = strtod(x, &xx);
+ double dy = strtod(y, &yy);
+ /* not numbers < NaN < -infinity < numbers < +infinity) */
+ if (x == xx)
+ retval = (y == yy ? 0 : -1);
+ else if (y == yy)
+ retval = 1;
+ /* Check for isnan */
+ else if (dx != dx)
+ retval = (dy != dy) ? 0 : -1;
+ else if (dy != dy)
+ retval = 1;
+ /* Check for infinity. Could underflow, but it avoids libm. */
+ else if (1.0 / dx == 0.0) {
+ if (dx < 0)
+ retval = (1.0 / dy == 0.0 && dy < 0) ? 0 : -1;
+ else
+ retval = (1.0 / dy == 0.0 && dy > 0) ? 0 : 1;
+ } else if (1.0 / dy == 0.0)
+ retval = (dy < 0) ? 1 : -1;
+ else
+ retval = (dx > dy) ? 1 : ((dx < dy) ? -1 : 0);
+ break;
+ }
+ case FLAG_M: {
+ struct tm thyme;
+ int dx;
+ char *xx, *yy;
+
+ xx = strptime(x, "%b", &thyme);
+ dx = thyme.tm_mon;
+ yy = strptime(y, "%b", &thyme);
+ if (!xx)
+ retval = (!yy) ? 0 : -1;
+ else if (!yy)
+ retval = 1;
+ else
+ retval = (dx == thyme.tm_mon) ? 0 : dx - thyme.tm_mon;
+ break;
+ }
+ /* Full floating point version of -n */
+ case FLAG_n: {
+ double dx = atof(x);
+ double dy = atof(y);
+ retval = (dx > dy) ? 1 : ((dx < dy) ? -1 : 0);
+ break;
+ }
+ } /* switch */
+ /* Free key copies. */
+ if (x != *(char **)xarg) free(x);
+ if (y != *(char **)yarg) free(y);
+ /* if (retval) break; - done by for () anyway */
+#else
+ /* Integer version of -n for tiny systems */
+ case FLAG_n:
+ retval = atoi(x) - atoi(y);
+ break;
+ } /* switch */
+#endif
+ } /* for */
+
+ /* Perform fallback sort if necessary */
+ if (!retval && !(option_mask32 & FLAG_s))
+ retval = strcmp(*(char **)xarg, *(char **)yarg);
+
+ if (flags & FLAG_r) return -retval;
+ return retval;
+}
+
+#if ENABLE_FEATURE_SORT_BIG
+static unsigned str2u(char **str)
+{
+ unsigned long lu;
+ if (!isdigit((*str)[0]))
+ bb_error_msg_and_die("bad field specification");
+ lu = strtoul(*str, str, 10);
+ if ((sizeof(long) > sizeof(int) && lu > INT_MAX) || !lu)
+ bb_error_msg_and_die("bad field specification");
+ return lu;
+}
+#endif
+
+int sort_main(int argc, char **argv);
+int sort_main(int argc, char **argv)
+{
+ FILE *fp, *outfile = stdout;
+ char *line, **lines = NULL;
+ char *str_ignored, *str_o, *str_t;
+ llist_t *lst_k = NULL;
+ int i, flag;
+ int linecount = 0;
+
+ xfunc_error_retval = 2;
+
+ /* Parse command line options */
+ /* -o and -t can be given at most once */
+ opt_complementary = "?:o--o:t--t:" /* -t, -o: maximum one of each */
+ "k::"; /* -k takes list */
+ getopt32(argc, argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t);
+#if ENABLE_FEATURE_SORT_BIG
+ if (option_mask32 & FLAG_o) outfile = xfopen(str_o, "w");
+ if (option_mask32 & FLAG_t) {
+ if (!str_t[0] || str_t[1])
+ bb_error_msg_and_die("bad -t parameter");
+ key_separator = str_t[0];
+ }
+ /* parse sort key */
+ lst_k = llist_rev(lst_k);
+ while (lst_k) {
+ enum {
+ FLAG_allowed_for_k =
+ FLAG_n | /* Numeric sort */
+ FLAG_g | /* Sort using strtod() */
+ FLAG_M | /* Sort date */
+ FLAG_b | /* Ignore leading blanks */
+ FLAG_r | /* Reverse */
+ FLAG_d | /* Ignore !(isalnum()|isspace()) */
+ FLAG_f | /* Force uppercase */
+ FLAG_i | /* Ignore !isprint() */
+ 0
+ };
+ struct sort_key *key = add_key();
+ char *str_k = lst_k->data;
+ const char *temp2;
+
+ i = 0; /* i==0 before comma, 1 after (-k3,6) */
+ while (*str_k) {
+ /* Start of range */
+ /* Cannot use bb_strtou - suffix can be a letter */
+ key->range[2*i] = str2u(&str_k);
+ if (*str_k == '.') {
+ str_k++;
+ key->range[2*i+1] = str2u(&str_k);
+ }
+ while (*str_k) {
+ if (*str_k == ',' && !i++) {
+ str_k++;
+ break;
+ } /* no else needed: fall through to syntax error
+ because comma isn't in OPT_STR */
+ temp2 = strchr(OPT_STR, *str_k);
+ if (!temp2)
+ bb_error_msg_and_die("unknown key option");
+ flag = 1 << (temp2 - OPT_STR);
+ if (flag & ~FLAG_allowed_for_k)
+ bb_error_msg_and_die("unknown sort type");
+ /* b after ',' means strip _trailing_ space */
+ if (i && flag == FLAG_b) flag = FLAG_bb;
+ key->flags |= flag;
+ str_k++;
+ }
+ }
+ /* leaking lst_k... */
+ lst_k = lst_k->link;
+ }
+#endif
+ /* global b strips leading and trailing spaces */
+ if (option_mask32 & FLAG_b) option_mask32 |= FLAG_bb;
+
+ /* Open input files and read data */
+ for (i = argv[optind] ? optind : optind-1; argv[i]; i++) {
+ fp = stdin;
+ if (i >= optind && NOT_LONE_DASH(argv[i]))
+ fp = xfopen(argv[i], "r");
+ for (;;) {
+ line = GET_LINE(fp);
+ if (!line) break;
+ if (!(linecount & 63))
+ lines = xrealloc(lines, sizeof(char *) * (linecount + 64));
+ lines[linecount++] = line;
+ }
+ fclose(fp);
+ }
+#if ENABLE_FEATURE_SORT_BIG
+ /* if no key, perform alphabetic sort */
+ if (!key_list)
+ add_key()->range[0] = 1;
+ /* handle -c */
+ if (option_mask32 & FLAG_c) {
+ int j = (option_mask32 & FLAG_u) ? -1 : 0;
+ for (i = 1; i < linecount; i++)
+ if (compare_keys(&lines[i-1], &lines[i]) > j) {
+ fprintf(stderr, "Check line %d\n", i);
+ return 1;
+ }
+ return 0;
+ }
+#endif
+ /* Perform the actual sort */
+ qsort(lines, linecount, sizeof(char *), compare_keys);
+ /* handle -u */
+ if (option_mask32 & FLAG_u) {
+ flag = 0;
+ /* coreutils 6.3 drop lines for which only key is the same */
+ /* -- disabling last-resort compare... */
+ option_mask32 |= FLAG_s;
+ for (i = 1; i < linecount; i++) {
+ if (!compare_keys(&lines[flag], &lines[i]))
+ free(lines[i]);
+ else
+ lines[++flag] = lines[i];
+ }
+ if (linecount) linecount = flag+1;
+ }
+ /* Print it */
+ for (i = 0; i < linecount; i++)
+ fprintf(outfile, "%s\n", lines[i]);
+
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/stat.c b/i/pc104/initrd/conf/busybox/coreutils/stat.c
new file mode 100644
index 0000000..a2cdbfb
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/stat.c
@@ -0,0 +1,676 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * stat -- display file or file system status
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation.
+ * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
+ * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
+ * Copyright (C) 2006 by Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * Written by Michael Meskes
+ * Taken from coreutils and turned into a busybox applet by Mike Frysinger
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+
+/* vars to control behavior */
+#define OPT_TERSE 2
+#define OPT_DEREFERENCE 4
+#define OPT_SELINUX 8
+static long flags;
+
+static char const *file_type(struct stat const *st)
+{
+ /* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107
+ * for some of these formats.
+ * To keep diagnostics grammatical in English, the
+ * returned string must start with a consonant.
+ */
+ if (S_ISREG(st->st_mode)) return st->st_size == 0 ? "regular empty file" : "regular file";
+ if (S_ISDIR(st->st_mode)) return "directory";
+ if (S_ISBLK(st->st_mode)) return "block special file";
+ if (S_ISCHR(st->st_mode)) return "character special file";
+ if (S_ISFIFO(st->st_mode)) return "fifo";
+ if (S_ISLNK(st->st_mode)) return "symbolic link";
+ if (S_ISSOCK(st->st_mode)) return "socket";
+ if (S_TYPEISMQ(st)) return "message queue";
+ if (S_TYPEISSEM(st)) return "semaphore";
+ if (S_TYPEISSHM(st)) return "shared memory object";
+#ifdef S_TYPEISTMO
+ if (S_TYPEISTMO(st)) return "typed memory object";
+#endif
+ return "weird file";
+}
+
+static char const *human_time(time_t t)
+{
+ /* Old
+ static char *str;
+ str = ctime(&t);
+ str[strlen(str)-1] = '\0';
+ return str;
+ */
+ /* coreutils 6.3 compat: */
+ static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")];
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S.000000000", localtime(&t));
+ return buf;
+}
+
+/* Return the type of the specified file system.
+ * Some systems have statfvs.f_basetype[FSTYPSZ]. (AIX, HP-UX, and Solaris)
+ * Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2)
+ * Still others have neither and have to get by with f_type (Linux).
+ */
+static char const *human_fstype(long f_type)
+{
+ int i;
+ static const struct types {
+ long type;
+ const char *fs;
+ } humantypes[] = {
+ { 0xADFF, "affs" },
+ { 0x1Cd1, "devpts" },
+ { 0x137D, "ext" },
+ { 0xEF51, "ext2" },
+ { 0xEF53, "ext2/ext3" },
+ { 0x3153464a, "jfs" },
+ { 0x58465342, "xfs" },
+ { 0xF995E849, "hpfs" },
+ { 0x9660, "isofs" },
+ { 0x4000, "isofs" },
+ { 0x4004, "isofs" },
+ { 0x137F, "minix" },
+ { 0x138F, "minix (30 char.)" },
+ { 0x2468, "minix v2" },
+ { 0x2478, "minix v2 (30 char.)" },
+ { 0x4d44, "msdos" },
+ { 0x4006, "fat" },
+ { 0x564c, "novell" },
+ { 0x6969, "nfs" },
+ { 0x9fa0, "proc" },
+ { 0x517B, "smb" },
+ { 0x012FF7B4, "xenix" },
+ { 0x012FF7B5, "sysv4" },
+ { 0x012FF7B6, "sysv2" },
+ { 0x012FF7B7, "coh" },
+ { 0x00011954, "ufs" },
+ { 0x012FD16D, "xia" },
+ { 0x5346544e, "ntfs" },
+ { 0x1021994, "tmpfs" },
+ { 0x52654973, "reiserfs" },
+ { 0x28cd3d45, "cramfs" },
+ { 0x7275, "romfs" },
+ { 0x858458f6, "romfs" },
+ { 0x73717368, "squashfs" },
+ { 0x62656572, "sysfs" },
+ { 0, "UNKNOWN" }
+ };
+ for (i=0; humantypes[i].type; ++i)
+ if (humantypes[i].type == f_type)
+ break;
+ return humantypes[i].fs;
+}
+
+#ifdef CONFIG_FEATURE_STAT_FORMAT
+/* print statfs info */
+static void print_statfs(char *pformat, size_t buf_len, char m,
+ char const *filename, void const *data
+ USE_SELINUX(,security_context_t scontext) )
+{
+ struct statfs const *statfsbuf = data;
+
+ switch (m) {
+ case 'n':
+ strncat(pformat, "s", buf_len);
+ printf(pformat, filename);
+ break;
+ case 'i':
+ strncat(pformat, "Lx", buf_len);
+ printf(pformat, statfsbuf->f_fsid);
+ break;
+ case 'l':
+ strncat(pformat, "lu", buf_len);
+ printf(pformat, statfsbuf->f_namelen);
+ break;
+ case 't':
+ strncat(pformat, "lx", buf_len);
+ printf(pformat, (unsigned long int) (statfsbuf->f_type)); /* no equiv. */
+ break;
+ case 'T':
+ strncat(pformat, "s", buf_len);
+ printf(pformat, human_fstype(statfsbuf->f_type));
+ break;
+ case 'b':
+ strncat(pformat, "jd", buf_len);
+ printf(pformat, (intmax_t) (statfsbuf->f_blocks));
+ break;
+ case 'f':
+ strncat(pformat, "jd", buf_len);
+ printf(pformat, (intmax_t) (statfsbuf->f_bfree));
+ break;
+ case 'a':
+ strncat(pformat, "jd", buf_len);
+ printf(pformat, (intmax_t) (statfsbuf->f_bavail));
+ break;
+ case 'S':
+ case 's':
+ strncat(pformat, "lu", buf_len);
+ printf(pformat, (unsigned long int) (statfsbuf->f_bsize));
+ break;
+ case 'c':
+ strncat(pformat, "jd", buf_len);
+ printf(pformat, (intmax_t) (statfsbuf->f_files));
+ break;
+ case 'd':
+ strncat(pformat, "jd", buf_len);
+ printf(pformat, (intmax_t) (statfsbuf->f_ffree));
+ break;
+#if ENABLE_SELINUX
+ case 'C':
+ if (flags & OPT_SELINUX) {
+ strncat(pformat, "s", buf_len);
+ printf(scontext);
+ }
+ break;
+#endif
+ default:
+ strncat(pformat, "c", buf_len);
+ printf(pformat, m);
+ break;
+ }
+}
+
+/* print stat info */
+static void print_stat(char *pformat, size_t buf_len, char m,
+ char const *filename, void const *data
+ USE_SELINUX(, security_context_t scontext))
+{
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+ struct stat *statbuf = (struct stat *) data;
+ struct passwd *pw_ent;
+ struct group *gw_ent;
+
+ switch (m) {
+ case 'n':
+ strncat(pformat, "s", buf_len);
+ printf(pformat, filename);
+ break;
+ case 'N':
+ strncat(pformat, "s", buf_len);
+ if (S_ISLNK(statbuf->st_mode)) {
+ char *linkname = xmalloc_readlink_or_warn(filename);
+ if (linkname == NULL) {
+ bb_perror_msg("cannot read symbolic link '%s'", filename);
+ return;
+ }
+ /*printf("\"%s\" -> \"%s\"", filename, linkname); */
+ printf(pformat, filename);
+ printf(" -> ");
+ printf(pformat, linkname);
+ } else {
+ printf(pformat, filename);
+ }
+ break;
+ case 'd':
+ strncat(pformat, "ju", buf_len);
+ printf(pformat, (uintmax_t) statbuf->st_dev);
+ break;
+ case 'D':
+ strncat(pformat, "jx", buf_len);
+ printf(pformat, (uintmax_t) statbuf->st_dev);
+ break;
+ case 'i':
+ strncat(pformat, "ju", buf_len);
+ printf(pformat, (uintmax_t) statbuf->st_ino);
+ break;
+ case 'a':
+ strncat(pformat, "lo", buf_len);
+ printf(pformat, (unsigned long int) (statbuf->st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)));
+ break;
+ case 'A':
+ strncat(pformat, "s", buf_len);
+ printf(pformat, bb_mode_string(statbuf->st_mode));
+ break;
+ case 'f':
+ strncat(pformat, "lx", buf_len);
+ printf(pformat, (unsigned long int) statbuf->st_mode);
+ break;
+ case 'F':
+ strncat(pformat, "s", buf_len);
+ printf(pformat, file_type(statbuf));
+ break;
+ case 'h':
+ strncat(pformat, "lu", buf_len);
+ printf(pformat, (unsigned long int) statbuf->st_nlink);
+ break;
+ case 'u':
+ strncat(pformat, "lu", buf_len);
+ printf(pformat, (unsigned long int) statbuf->st_uid);
+ break;
+ case 'U':
+ strncat(pformat, "s", buf_len);
+ setpwent();
+ pw_ent = getpwuid(statbuf->st_uid);
+ printf(pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN");
+ break;
+ case 'g':
+ strncat(pformat, "lu", buf_len);
+ printf(pformat, (unsigned long int) statbuf->st_gid);
+ break;
+ case 'G':
+ strncat(pformat, "s", buf_len);
+ setgrent();
+ gw_ent = getgrgid(statbuf->st_gid);
+ printf(pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
+ break;
+ case 't':
+ strncat(pformat, "lx", buf_len);
+ printf(pformat, (unsigned long int) major(statbuf->st_rdev));
+ break;
+ case 'T':
+ strncat(pformat, "lx", buf_len);
+ printf(pformat, (unsigned long int) minor(statbuf->st_rdev));
+ break;
+ case 's':
+ strncat(pformat, "ju", buf_len);
+ printf(pformat, (uintmax_t) (statbuf->st_size));
+ break;
+ case 'B':
+ strncat(pformat, "lu", buf_len);
+ printf(pformat, (unsigned long int) 512); //ST_NBLOCKSIZE
+ break;
+ case 'b':
+ strncat(pformat, "ju", buf_len);
+ printf(pformat, (uintmax_t) statbuf->st_blocks);
+ break;
+ case 'o':
+ strncat(pformat, "lu", buf_len);
+ printf(pformat, (unsigned long int) statbuf->st_blksize);
+ break;
+ case 'x':
+ strncat(pformat, "s", buf_len);
+ printf(pformat, human_time(statbuf->st_atime));
+ break;
+ case 'X':
+ strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
+ printf(pformat, (unsigned long int) statbuf->st_atime);
+ break;
+ case 'y':
+ strncat(pformat, "s", buf_len);
+ printf(pformat, human_time(statbuf->st_mtime));
+ break;
+ case 'Y':
+ strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
+ printf(pformat, (unsigned long int) statbuf->st_mtime);
+ break;
+ case 'z':
+ strncat(pformat, "s", buf_len);
+ printf(pformat, human_time(statbuf->st_ctime));
+ break;
+ case 'Z':
+ strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
+ printf(pformat, (unsigned long int) statbuf->st_ctime);
+ break;
+#if ENABLE_SELINUX
+ case 'C':
+ if (flags & OPT_SELINUX) {
+ strncat(pformat, "s", buf_len);
+ printf(pformat, scontext);
+ }
+ break;
+#endif
+ default:
+ strncat(pformat, "c", buf_len);
+ printf(pformat, m);
+ break;
+ }
+}
+
+static void print_it(char const *masterformat, char const *filename,
+ void (*print_func) (char *, size_t, char, char const *, void const *
+ USE_SELINUX(, security_context_t scontext)),
+ void const *data USE_SELINUX(, security_context_t scontext) )
+{
+ char *b;
+
+ /* create a working copy of the format string */
+ char *format = xstrdup(masterformat);
+
+ /* Add 2 to accomodate our conversion of the stat '%s' format string
+ * to the printf '%llu' one. */
+ size_t n_alloc = strlen(format) + 2 + 1;
+ char *dest = xmalloc(n_alloc);
+
+ b = format;
+ while (b) {
+ size_t len;
+ char *p = strchr(b, '%');
+ if (!p) {
+ /* coreutils 6.3 always print <cr> at the end */
+ /*fputs(b, stdout);*/
+ puts(b);
+ break;
+ }
+ *p++ = '\0';
+ fputs(b, stdout);
+
+ len = strspn(p, "#-+.I 0123456789");
+ dest[0] = '%';
+ memcpy(dest + 1, p, len);
+ dest[1 + len] = 0;
+ p += len;
+
+ b = p + 1;
+ switch (*p) {
+ case '\0':
+ b = NULL;
+ /* fall through */
+ case '%':
+ putchar('%');
+ break;
+ default:
+ print_func(dest, n_alloc, *p, filename, data USE_SELINUX(,scontext));
+ break;
+ }
+ }
+
+ free(format);
+ free(dest);
+}
+#endif
+
+/* Stat the file system and print what we find. */
+static int do_statfs(char const *filename, char const *format)
+{
+ struct statfs statfsbuf;
+
+#if ENABLE_SELINUX
+ security_context_t scontext = NULL;
+ if (flags & OPT_SELINUX) {
+ if ((flags & OPT_DEREFERENCE ? lgetfilecon(filename, scontext):
+ getfilecon(filename, scontext))< 0) {
+ bb_perror_msg(filename);
+ return 0;
+ }
+ }
+#endif
+ if (statfs(filename, &statfsbuf) != 0) {
+ bb_perror_msg("cannot read file system information for '%s'", filename);
+ return 0;
+ }
+
+#ifdef CONFIG_FEATURE_STAT_FORMAT
+ if (format == NULL)
+#ifndef ENABLE_SELINUX
+ format = (flags & OPT_TERSE
+ ? "%n %i %l %t %s %b %f %a %c %d\n"
+ : " File: \"%n\"\n"
+ " ID: %-8i Namelen: %-7l Type: %T\n"
+ "Block size: %-10s\n"
+ "Blocks: Total: %-10b Free: %-10f Available: %a\n"
+ "Inodes: Total: %-10c Free: %d");
+ print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext));
+#else
+ format = (flags & OPT_TERSE
+ ? (flags & OPT_SELINUX ? "%n %i %l %t %s %b %f %a %c %d %C\n":
+ "%n %i %l %t %s %b %f %a %c %d\n")
+ : (flags & OPT_SELINUX ?
+ " File: \"%n\"\n"
+ " ID: %-8i Namelen: %-7l Type: %T\n"
+ "Block size: %-10s\n"
+ "Blocks: Total: %-10b Free: %-10f Available: %a\n"
+ "Inodes: Total: %-10c Free: %d"
+ " S_context: %C\n":
+ " File: \"%n\"\n"
+ " ID: %-8i Namelen: %-7l Type: %T\n"
+ "Block size: %-10s\n"
+ "Blocks: Total: %-10b Free: %-10f Available: %a\n"
+ "Inodes: Total: %-10c Free: %d\n")
+ );
+ print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext));
+#endif /* SELINUX */
+#else /* FEATURE_STAT_FORMAT */
+ format = (flags & OPT_TERSE
+ ? "%s %llx %lu "
+ : " File: \"%s\"\n"
+ " ID: %-8Lx Namelen: %-7lu ");
+ printf(format,
+ filename,
+ statfsbuf.f_fsid,
+ statfsbuf.f_namelen);
+
+ if (flags & OPT_TERSE)
+ printf("%lx ", (unsigned long int) (statfsbuf.f_type));
+ else
+ printf("Type: %s\n", human_fstype(statfsbuf.f_type));
+
+#if !ENABLE_SELINUX
+ format = (flags & OPT_TERSE
+ ? "%lu %ld %ld %ld %ld %ld\n"
+ : "Block size: %-10lu\n"
+ "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n"
+ "Inodes: Total: %-10jd Free: %jd\n");
+ printf(format,
+ (unsigned long int) (statfsbuf.f_bsize),
+ (intmax_t) (statfsbuf.f_blocks),
+ (intmax_t) (statfsbuf.f_bfree),
+ (intmax_t) (statfsbuf.f_bavail),
+ (intmax_t) (statfsbuf.f_files),
+ (intmax_t) (statfsbuf.f_ffree));
+#else
+ format = (flags & OPT_TERSE
+ ? (flags & OPT_SELINUX ? "%lu %ld %ld %ld %ld %ld %C\n":
+ "%lu %ld %ld %ld %ld %ld\n")
+ : (flags & OPT_SELINUX ?
+ "Block size: %-10lu\n"
+ "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n"
+ "Inodes: Total: %-10jd Free: %jd"
+ "S_context: %C\n":
+ "Block size: %-10lu\n"
+ "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n"
+ "Inodes: Total: %-10jd Free: %jd\n"));
+ printf(format,
+ (unsigned long int) (statfsbuf.f_bsize),
+ (intmax_t) (statfsbuf.f_blocks),
+ (intmax_t) (statfsbuf.f_bfree),
+ (intmax_t) (statfsbuf.f_bavail),
+ (intmax_t) (statfsbuf.f_files),
+ (intmax_t) (statfsbuf.f_ffree),
+ scontext);
+
+ if (scontext)
+ freecon(scontext);
+#endif
+#endif /* FEATURE_STAT_FORMAT */
+ return 1;
+}
+
+/* stat the file and print what we find */
+static int do_stat(char const *filename, char const *format)
+{
+ struct stat statbuf;
+#if ENABLE_SELINUX
+ security_context_t scontext = NULL;
+ if (flags & OPT_SELINUX) {
+ if ((flags & OPT_DEREFERENCE ? lgetfilecon(filename, scontext):
+ getfilecon(filename, scontext))< 0) {
+ bb_perror_msg (filename);
+ return 0;
+ }
+ }
+#endif
+ if ((flags & OPT_DEREFERENCE ? stat : lstat) (filename, &statbuf) != 0) {
+ bb_perror_msg("cannot stat '%s'", filename);
+ return 0;
+ }
+
+#ifdef CONFIG_FEATURE_STAT_FORMAT
+ if (format == NULL) {
+#ifndef ENABLE_SELINUX
+ if (flags & OPT_TERSE) {
+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o";
+ } else {
+ if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
+ format =
+ " File: \"%N\"\n"
+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
+ "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
+ " Device type: %t,%T\n"
+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
+ "Access: %x\n" "Modify: %y\n" "Change: %z\n";
+ } else {
+ format =
+ " File: \"%N\"\n"
+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
+ "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
+ "Access: %x\n" "Modify: %y\n" "Change: %z\n";
+ }
+ }
+#else
+ if (flags & OPT_TERSE) {
+ format = (flags & OPT_SELINUX ?
+ "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n":
+ "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n");
+ } else {
+ if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
+ format = (flags & OPT_SELINUX ?
+ " File: \"%N\"\n"
+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
+ "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
+ " Device type: %t,%T\n"
+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
+ " S_Context: %C\n"
+ "Access: %x\n" "Modify: %y\n" "Change: %z\n":
+ " File: \"%N\"\n"
+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
+ "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
+ " Device type: %t,%T\n"
+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
+ "Access: %x\n" "Modify: %y\n" "Change: %z\n");
+ } else {
+ format = (flags & OPT_SELINUX ?
+ " File: \"%N\"\n"
+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
+ "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
+ "S_Context: %C\n"
+ "Access: %x\n" "Modify: %y\n" "Change: %z\n":
+ " File: \"%N\"\n"
+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
+ "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
+ "Access: %x\n" "Modify: %y\n" "Change: %z\n");
+ }
+ }
+#endif
+ }
+ print_it(format, filename, print_stat, &statbuf USE_SELINUX(, scontext));
+#else /* FEATURE_STAT_FORMAT */
+ if (flags & OPT_TERSE) {
+ printf("%s %ju %ju %lx %lu %lu %jx %ju %lu %lx %lx %lu %lu %lu %lu"
+ SKIP_SELINUX("\n"),
+ filename,
+ (uintmax_t) (statbuf.st_size),
+ (uintmax_t) statbuf.st_blocks,
+ (unsigned long int) statbuf.st_mode,
+ (unsigned long int) statbuf.st_uid,
+ (unsigned long int) statbuf.st_gid,
+ (uintmax_t) statbuf.st_dev,
+ (uintmax_t) statbuf.st_ino,
+ (unsigned long int) statbuf.st_nlink,
+ (unsigned long int) major(statbuf.st_rdev),
+ (unsigned long int) minor(statbuf.st_rdev),
+ (unsigned long int) statbuf.st_atime,
+ (unsigned long int) statbuf.st_mtime,
+ (unsigned long int) statbuf.st_ctime,
+ (unsigned long int) statbuf.st_blksize
+ );
+#if ENABLE_SELINUX
+ if (flags & OPT_SELINUX)
+ printf(" %lc\n", *scontext);
+ else
+ putchar('\n');
+#endif
+ } else {
+ char *linkname = NULL;
+
+ struct passwd *pw_ent;
+ struct group *gw_ent;
+ setgrent();
+ gw_ent = getgrgid(statbuf.st_gid);
+ setpwent();
+ pw_ent = getpwuid(statbuf.st_uid);
+
+ if (S_ISLNK(statbuf.st_mode))
+ linkname = xmalloc_readlink_or_warn(filename);
+ if (linkname)
+ printf(" File: \"%s\" -> \"%s\"\n", filename, linkname);
+ else
+ printf(" File: \"%s\"\n", filename);
+
+ printf(" Size: %-10ju\tBlocks: %-10ju IO Block: %-6lu %s\n"
+ "Device: %jxh/%jud\tInode: %-10ju Links: %-5lu",
+ (uintmax_t) (statbuf.st_size),
+ (uintmax_t) statbuf.st_blocks,
+ (unsigned long int) statbuf.st_blksize,
+ file_type(&statbuf),
+ (uintmax_t) statbuf.st_dev,
+ (uintmax_t) statbuf.st_dev,
+ (uintmax_t) statbuf.st_ino,
+ (unsigned long int) statbuf.st_nlink);
+ if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode))
+ printf(" Device type: %lx,%lx\n",
+ (unsigned long int) major(statbuf.st_rdev),
+ (unsigned long int) minor(statbuf.st_rdev));
+ else
+ putchar('\n');
+ printf("Access: (%04lo/%10.10s) Uid: (%5lu/%8s) Gid: (%5lu/%8s)\n",
+ (unsigned long int) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)),
+ bb_mode_string(statbuf.st_mode),
+ (unsigned long int) statbuf.st_uid,
+ (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN",
+ (unsigned long int) statbuf.st_gid,
+ (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
+#if ENABLE_SELINUX
+ printf(" S_Context: %lc\n", *scontext);
+#endif
+ printf("Access: %s\n" "Modify: %s\n" "Change: %s\n",
+ human_time(statbuf.st_atime),
+ human_time(statbuf.st_mtime),
+ human_time(statbuf.st_ctime));
+ }
+#endif /* FEATURE_STAT_FORMAT */
+ return 1;
+}
+
+int stat_main(int argc, char **argv);
+int stat_main(int argc, char **argv)
+{
+ int i;
+ char *format = NULL;
+ int ok = 1;
+ int (*statfunc)(char const *, char const *) = do_stat;
+
+ flags = getopt32(argc, argv, "ftL"
+ USE_SELINUX("Z")
+ USE_FEATURE_STAT_FORMAT("c:", &format)
+ );
+
+ if (flags & 1) /* -f */
+ statfunc = do_statfs;
+ if (argc == optind) /* files */
+ bb_show_usage();
+
+#if ENABLE_SELINUX
+ if (flags & OPT_SELINUX) {
+ selinux_or_die();
+ }
+#endif /* ENABLE_SELINUX */
+ for (i = optind; i < argc; ++i)
+ ok &= statfunc(argv[i], format);
+
+ return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/stty.c b/i/pc104/initrd/conf/busybox/coreutils/stty.c
new file mode 100644
index 0000000..15cb052
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/stty.c
@@ -0,0 +1,1189 @@
+/* vi: set sw=4 ts=4: */
+/* stty -- change and print terminal line settings
+ Copyright (C) 1990-1999 Free Software Foundation, Inc.
+
+ Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+*/
+/* Usage: stty [-ag] [-F device] [setting...]
+
+ Options:
+ -a Write all current settings to stdout in human-readable form.
+ -g Write all current settings to stdout in stty-readable form.
+ -F Open and use the specified device instead of stdin
+
+ If no args are given, write to stdout the baud rate and settings that
+ have been changed from their defaults. Mode reading and changes
+ are done on the specified device, or stdin if none was specified.
+
+ David MacKenzie <djm@gnu.ai.mit.edu>
+
+ Special for busybox ported by Vladimir Oleynik <dzo@simtreas.ru> 2001
+
+ */
+
+#include "busybox.h"
+
+#ifndef _POSIX_VDISABLE
+# define _POSIX_VDISABLE ((unsigned char) 0)
+#endif
+
+#define Control(c) ((c) & 0x1f)
+/* Canonical values for control characters */
+#ifndef CINTR
+# define CINTR Control('c')
+#endif
+#ifndef CQUIT
+# define CQUIT 28
+#endif
+#ifndef CERASE
+# define CERASE 127
+#endif
+#ifndef CKILL
+# define CKILL Control('u')
+#endif
+#ifndef CEOF
+# define CEOF Control('d')
+#endif
+#ifndef CEOL
+# define CEOL _POSIX_VDISABLE
+#endif
+#ifndef CSTART
+# define CSTART Control('q')
+#endif
+#ifndef CSTOP
+# define CSTOP Control('s')
+#endif
+#ifndef CSUSP
+# define CSUSP Control('z')
+#endif
+#if defined(VEOL2) && !defined(CEOL2)
+# define CEOL2 _POSIX_VDISABLE
+#endif
+/* ISC renamed swtch to susp for termios, but we'll accept either name */
+#if defined(VSUSP) && !defined(VSWTCH)
+# define VSWTCH VSUSP
+# define CSWTCH CSUSP
+#endif
+#if defined(VSWTCH) && !defined(CSWTCH)
+# define CSWTCH _POSIX_VDISABLE
+#endif
+
+/* SunOS 5.3 loses (^Z doesn't work) if 'swtch' is the same as 'susp'.
+ So the default is to disable 'swtch.' */
+#if defined (__sparc__) && defined (__svr4__)
+# undef CSWTCH
+# define CSWTCH _POSIX_VDISABLE
+#endif
+
+#if defined(VWERSE) && !defined (VWERASE) /* AIX-3.2.5 */
+# define VWERASE VWERSE
+#endif
+#if defined(VDSUSP) && !defined (CDSUSP)
+# define CDSUSP Control('y')
+#endif
+#if !defined(VREPRINT) && defined(VRPRNT) /* Irix 4.0.5 */
+# define VREPRINT VRPRNT
+#endif
+#if defined(VREPRINT) && !defined(CRPRNT)
+# define CRPRNT Control('r')
+#endif
+#if defined(VWERASE) && !defined(CWERASE)
+# define CWERASE Control('w')
+#endif
+#if defined(VLNEXT) && !defined(CLNEXT)
+# define CLNEXT Control('v')
+#endif
+#if defined(VDISCARD) && !defined(VFLUSHO)
+# define VFLUSHO VDISCARD
+#endif
+#if defined(VFLUSH) && !defined(VFLUSHO) /* Ultrix 4.2 */
+# define VFLUSHO VFLUSH
+#endif
+#if defined(CTLECH) && !defined(ECHOCTL) /* Ultrix 4.3 */
+# define ECHOCTL CTLECH
+#endif
+#if defined(TCTLECH) && !defined(ECHOCTL) /* Ultrix 4.2 */
+# define ECHOCTL TCTLECH
+#endif
+#if defined(CRTKIL) && !defined(ECHOKE) /* Ultrix 4.2 and 4.3 */
+# define ECHOKE CRTKIL
+#endif
+#if defined(VFLUSHO) && !defined(CFLUSHO)
+# define CFLUSHO Control('o')
+#endif
+#if defined(VSTATUS) && !defined(CSTATUS)
+# define CSTATUS Control('t')
+#endif
+
+/* Which speeds to set */
+enum speed_setting {
+ input_speed, output_speed, both_speeds
+};
+
+/* Which member(s) of 'struct termios' a mode uses */
+enum {
+ /* Do NOT change the order or values, as mode_type_flag()
+ * depends on them */
+ control, input, output, local, combination
+};
+
+static const char evenp [] = "evenp";
+static const char raw [] = "raw";
+static const char stty_min [] = "min";
+static const char stty_time [] = "time";
+static const char stty_swtch[] = "swtch";
+static const char stty_eol [] = "eol";
+static const char stty_eof [] = "eof";
+static const char parity [] = "parity";
+static const char stty_oddp [] = "oddp";
+static const char stty_nl [] = "nl";
+static const char stty_ek [] = "ek";
+static const char stty_sane [] = "sane";
+static const char cbreak [] = "cbreak";
+static const char stty_pass8[] = "pass8";
+static const char litout [] = "litout";
+static const char cooked [] = "cooked";
+static const char decctlq [] = "decctlq";
+static const char stty_tabs [] = "tabs";
+static const char stty_lcase[] = "lcase";
+static const char stty_LCASE[] = "LCASE";
+static const char stty_crt [] = "crt";
+static const char stty_dec [] = "dec";
+
+/* Flags for 'struct mode_info' */
+#define SANE_SET 1 /* Set in 'sane' mode */
+#define SANE_UNSET 2 /* Unset in 'sane' mode */
+#define REV 4 /* Can be turned off by prepending '-' */
+#define OMIT 8 /* Don't display value */
+
+/* Each mode */
+struct mode_info {
+ const char * const name; /* Name given on command line */
+ const unsigned char type; /* Which structure element to change */
+ const unsigned char flags; /* Setting and display options */
+ /* were using short here, but ppc32 was unhappy: */
+ const tcflag_t mask; /* Other bits to turn off for this mode */
+ const tcflag_t bits; /* Bits to set for this mode */
+};
+
+/* We can optimize it further by using name[8] instead of char *name */
+/* but beware of "if (info->name == evenp)" checks! */
+/* Need to replace them with "if (info == &mode_info[EVENP_INDX])" */
+
+#define MI_ENTRY(N,T,F,B,M) { N, T, F, M, B }
+
+static const struct mode_info mode_info[] = {
+ MI_ENTRY("parenb", control, REV, PARENB, 0 ),
+ MI_ENTRY("parodd", control, REV, PARODD, 0 ),
+ MI_ENTRY("cs5", control, 0, CS5, CSIZE),
+ MI_ENTRY("cs6", control, 0, CS6, CSIZE),
+ MI_ENTRY("cs7", control, 0, CS7, CSIZE),
+ MI_ENTRY("cs8", control, 0, CS8, CSIZE),
+ MI_ENTRY("hupcl", control, REV, HUPCL, 0 ),
+ MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 ),
+ MI_ENTRY("cstopb", control, REV, CSTOPB, 0 ),
+ MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 ),
+ MI_ENTRY("clocal", control, REV, CLOCAL, 0 ),
+#ifdef CRTSCTS
+ MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 ),
+#endif
+ MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 ),
+ MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 ),
+ MI_ENTRY("ignpar", input, REV, IGNPAR, 0 ),
+ MI_ENTRY("parmrk", input, REV, PARMRK, 0 ),
+ MI_ENTRY("inpck", input, REV, INPCK, 0 ),
+ MI_ENTRY("istrip", input, REV, ISTRIP, 0 ),
+ MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 ),
+ MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 ),
+ MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 ),
+ MI_ENTRY("ixon", input, REV, IXON, 0 ),
+ MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 ),
+ MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 ),
+#ifdef IUCLC
+ MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 ),
+#endif
+#ifdef IXANY
+ MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 ),
+#endif
+#ifdef IMAXBEL
+ MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 ),
+#endif
+ MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 ),
+#ifdef OLCUC
+ MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 ),
+#endif
+#ifdef OCRNL
+ MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 ),
+#endif
+#ifdef ONLCR
+ MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 ),
+#endif
+#ifdef ONOCR
+ MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 ),
+#endif
+#ifdef ONLRET
+ MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 ),
+#endif
+#ifdef OFILL
+ MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 ),
+#endif
+#ifdef OFDEL
+ MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 ),
+#endif
+#ifdef NLDLY
+ MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY),
+ MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY),
+#endif
+#ifdef CRDLY
+ MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY),
+ MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY),
+ MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY),
+ MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY),
+#endif
+
+#ifdef TABDLY
+ MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY),
+ MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY),
+ MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY),
+ MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY),
+#else
+# ifdef OXTABS
+ MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 ),
+# endif
+#endif
+
+#ifdef BSDLY
+ MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY),
+ MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY),
+#endif
+#ifdef VTDLY
+ MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY),
+ MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY),
+#endif
+#ifdef FFDLY
+ MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY),
+ MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY),
+#endif
+ MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 ),
+ MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 ),
+#ifdef IEXTEN
+ MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 ),
+#endif
+ MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 ),
+ MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 ),
+ MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 ),
+ MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 ),
+ MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 ),
+ MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 ),
+#ifdef XCASE
+ MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 ),
+#endif
+#ifdef TOSTOP
+ MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 ),
+#endif
+#ifdef ECHOPRT
+ MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 ),
+ MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 ),
+#endif
+#ifdef ECHOCTL
+ MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 ),
+ MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 ),
+#endif
+#ifdef ECHOKE
+ MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 ),
+ MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 ),
+#endif
+ MI_ENTRY(evenp, combination, REV | OMIT, 0, 0 ),
+ MI_ENTRY(parity, combination, REV | OMIT, 0, 0 ),
+ MI_ENTRY(stty_oddp, combination, REV | OMIT, 0, 0 ),
+ MI_ENTRY(stty_nl, combination, REV | OMIT, 0, 0 ),
+ MI_ENTRY(stty_ek, combination, OMIT, 0, 0 ),
+ MI_ENTRY(stty_sane, combination, OMIT, 0, 0 ),
+ MI_ENTRY(cooked, combination, REV | OMIT, 0, 0 ),
+ MI_ENTRY(raw, combination, REV | OMIT, 0, 0 ),
+ MI_ENTRY(stty_pass8, combination, REV | OMIT, 0, 0 ),
+ MI_ENTRY(litout, combination, REV | OMIT, 0, 0 ),
+ MI_ENTRY(cbreak, combination, REV | OMIT, 0, 0 ),
+#ifdef IXANY
+ MI_ENTRY(decctlq, combination, REV | OMIT, 0, 0 ),
+#endif
+#if defined(TABDLY) || defined(OXTABS)
+ MI_ENTRY(stty_tabs, combination, REV | OMIT, 0, 0 ),
+#endif
+#if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
+ MI_ENTRY(stty_lcase, combination, REV | OMIT, 0, 0 ),
+ MI_ENTRY(stty_LCASE, combination, REV | OMIT, 0, 0 ),
+#endif
+ MI_ENTRY(stty_crt, combination, OMIT, 0, 0 ),
+ MI_ENTRY(stty_dec, combination, OMIT, 0, 0 ),
+};
+
+enum {
+ NUM_mode_info = (sizeof(mode_info) / sizeof(mode_info[0]))
+};
+
+/* Control character settings */
+struct control_info {
+ const char * const name; /* Name given on command line */
+ const unsigned char saneval; /* Value to set for 'stty sane' */
+ const unsigned char offset; /* Offset in c_cc */
+};
+
+/* Control characters */
+
+static const struct control_info control_info[] = {
+ {"intr", CINTR, VINTR},
+ {"quit", CQUIT, VQUIT},
+ {"erase", CERASE, VERASE},
+ {"kill", CKILL, VKILL},
+ {stty_eof, CEOF, VEOF},
+ {stty_eol, CEOL, VEOL},
+#ifdef VEOL2
+ {"eol2", CEOL2, VEOL2},
+#endif
+#ifdef VSWTCH
+ {stty_swtch, CSWTCH, VSWTCH},
+#endif
+ {"start", CSTART, VSTART},
+ {"stop", CSTOP, VSTOP},
+ {"susp", CSUSP, VSUSP},
+#ifdef VDSUSP
+ {"dsusp", CDSUSP, VDSUSP},
+#endif
+#ifdef VREPRINT
+ {"rprnt", CRPRNT, VREPRINT},
+#endif
+#ifdef VWERASE
+ {"werase", CWERASE, VWERASE},
+#endif
+#ifdef VLNEXT
+ {"lnext", CLNEXT, VLNEXT},
+#endif
+#ifdef VFLUSHO
+ {"flush", CFLUSHO, VFLUSHO},
+#endif
+#ifdef VSTATUS
+ {"status", CSTATUS, VSTATUS},
+#endif
+ /* These must be last because of the display routines */
+ {stty_min, 1, VMIN},
+ {stty_time, 0, VTIME},
+};
+
+enum {
+ NUM_control_info = (sizeof(control_info) / sizeof(control_info[0]))
+};
+
+/* The width of the screen, for output wrapping */
+static unsigned max_col = 80; /* default */
+/* Current position, to know when to wrap */
+static unsigned current_col;
+static const char *device_name = bb_msg_standard_input;
+
+/* Return a string that is the printable representation of character CH */
+/* Adapted from 'cat' by Torbjorn Granlund */
+static const char *visible(unsigned int ch)
+{
+ static char buf[10];
+ char *bpout = buf;
+
+ if (ch == _POSIX_VDISABLE)
+ return "<undef>";
+
+ if (ch >= 128) {
+ ch -= 128;
+ *bpout++ = 'M';
+ *bpout++ = '-';
+ }
+
+ if (ch < 32) {
+ *bpout++ = '^';
+ *bpout++ = ch + 64;
+ } else if (ch < 127) {
+ *bpout++ = ch;
+ } else {
+ *bpout++ = '^';
+ *bpout++ = '?';
+ }
+
+ *bpout = '\0';
+ return buf;
+}
+
+static tcflag_t *mode_type_flag(unsigned type, const struct termios *mode)
+{
+ static const unsigned char tcflag_offsets[] = {
+ offsetof(struct termios, c_cflag), /* control */
+ offsetof(struct termios, c_iflag), /* input */
+ offsetof(struct termios, c_oflag), /* output */
+ offsetof(struct termios, c_lflag), /* local */
+ };
+
+ if (type <= local) {
+ return (tcflag_t*) (((char*)mode) + tcflag_offsets[type]);
+ }
+ return NULL;
+}
+
+static void set_speed_or_die(enum speed_setting type, const char * const arg,
+ struct termios * const mode)
+{
+ speed_t baud;
+
+ baud = tty_value_to_baud(xatou(arg));
+
+ if (type != output_speed) { /* either input or both */
+ cfsetispeed(mode, baud);
+ }
+ if (type != input_speed) { /* either output or both */
+ cfsetospeed(mode, baud);
+ }
+}
+
+static ATTRIBUTE_NORETURN void perror_on_device_and_die(const char *fmt)
+{
+ bb_perror_msg_and_die(fmt, device_name);
+}
+
+static void perror_on_device(const char *fmt)
+{
+ bb_perror_msg(fmt, device_name);
+}
+
+/* Print format string MESSAGE and optional args.
+ Wrap to next line first if it won't fit.
+ Print a space first unless MESSAGE will start a new line */
+static void wrapf(const char *message, ...)
+{
+ char buf[128];
+ va_list args;
+ int buflen;
+
+ va_start(args, message);
+ buflen = vsnprintf(buf, sizeof(buf), message, args);
+ va_end(args);
+ /* We seem to be called only with suitable lengths, but check if
+ somebody failed to adhere to this assumption just to be sure. */
+ if (!buflen || buflen >= sizeof(buf)) return;
+
+ if (current_col > 0) {
+ current_col++;
+ if (buf[0] != '\n') {
+ if (current_col + buflen >= max_col) {
+ putchar('\n');
+ current_col = 0;
+ } else
+ putchar(' ');
+ }
+ }
+ fputs(buf, stdout);
+ current_col += buflen;
+ if (buf[buflen-1] == '\n')
+ current_col = 0;
+}
+
+static void set_window_size(const int rows, const int cols)
+{
+ struct winsize win = { 0, 0, 0, 0};
+
+ if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win)) {
+ if (errno != EINVAL) {
+ goto bail;
+ }
+ memset(&win, 0, sizeof(win));
+ }
+
+ if (rows >= 0)
+ win.ws_row = rows;
+ if (cols >= 0)
+ win.ws_col = cols;
+
+ if (ioctl(STDIN_FILENO, TIOCSWINSZ, (char *) &win))
+bail:
+ perror_on_device("%s");
+}
+
+static void display_window_size(const int fancy)
+{
+ const char *fmt_str = "%s\0%s: no size information for this device";
+ unsigned width, height;
+
+ if (get_terminal_width_height(STDIN_FILENO, &width, &height)) {
+ if ((errno != EINVAL) || ((fmt_str += 2), !fancy)) {
+ perror_on_device(fmt_str);
+ }
+ } else {
+ wrapf(fancy ? "rows %d; columns %d;" : "%d %d\n",
+ height, width);
+ }
+}
+
+static const struct suffix_mult stty_suffixes[] = {
+ {"b", 512 },
+ {"k", 1024},
+ {"B", 1024},
+ {NULL, 0 }
+};
+
+static const struct mode_info *find_mode(const char *name)
+{
+ int i;
+ for (i = 0; i < NUM_mode_info; ++i)
+ if (!strcmp(name, mode_info[i].name))
+ return &mode_info[i];
+ return 0;
+}
+
+static const struct control_info *find_control(const char *name)
+{
+ int i;
+ for (i = 0; i < NUM_control_info; ++i)
+ if (!strcmp(name, control_info[i].name))
+ return &control_info[i];
+ return 0;
+}
+
+enum {
+ param_need_arg = 0x80,
+ param_line = 1 | 0x80,
+ param_rows = 2 | 0x80,
+ param_cols = 3 | 0x80,
+ param_size = 4,
+ param_speed = 5,
+ param_ispeed = 6 | 0x80,
+ param_ospeed = 7 | 0x80,
+};
+
+static int find_param(const char * const name)
+{
+ const char * const params[] = {
+ "line",
+ "rows",
+ "cols",
+ "columns",
+ "size",
+ "speed",
+ "ispeed",
+ "ospeed",
+ NULL
+ };
+ int i = index_in_str_array(params, name);
+ if (i < 0)
+ return 0;
+ if (!(i == 4 || i == 5))
+ i |= 0x80;
+
+ return i;
+}
+
+static int recover_mode(const char *arg, struct termios *mode)
+{
+ int i, n;
+ unsigned int chr;
+ unsigned long iflag, oflag, cflag, lflag;
+
+ /* Scan into temporaries since it is too much trouble to figure out
+ the right format for 'tcflag_t' */
+ if (sscanf(arg, "%lx:%lx:%lx:%lx%n",
+ &iflag, &oflag, &cflag, &lflag, &n) != 4)
+ return 0;
+ mode->c_iflag = iflag;
+ mode->c_oflag = oflag;
+ mode->c_cflag = cflag;
+ mode->c_lflag = lflag;
+ arg += n;
+ for (i = 0; i < NCCS; ++i) {
+ if (sscanf(arg, ":%x%n", &chr, &n) != 1)
+ return 0;
+ mode->c_cc[i] = chr;
+ arg += n;
+ }
+
+ /* Fail if there are too many fields */
+ if (*arg != '\0')
+ return 0;
+
+ return 1;
+}
+
+static void display_recoverable(const struct termios *mode,
+ const int ATTRIBUTE_UNUSED dummy)
+{
+ int i;
+ printf("%lx:%lx:%lx:%lx",
+ (unsigned long) mode->c_iflag, (unsigned long) mode->c_oflag,
+ (unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag);
+ for (i = 0; i < NCCS; ++i)
+ printf(":%x", (unsigned int) mode->c_cc[i]);
+ putchar('\n');
+}
+
+static void display_speed(const struct termios *mode, int fancy)
+{
+ //01234567 8 9
+ const char *fmt_str = "%lu %lu\n\0ispeed %lu baud; ospeed %lu baud;";
+ unsigned long ispeed, ospeed;
+
+ ospeed = ispeed = cfgetispeed(mode);
+ if (ispeed == 0 || ispeed == (ospeed = cfgetospeed(mode))) {
+ ispeed = ospeed; /* in case ispeed was 0 */
+ //0123 4 5 6 7 8 9
+ fmt_str = "%lu\n\0\0\0\0\0speed %lu baud;";
+ }
+ if (fancy) fmt_str += 9;
+ wrapf(fmt_str, tty_baud_to_value(ispeed), tty_baud_to_value(ospeed));
+}
+
+static void do_display(const struct termios *mode, const int all)
+{
+ int i;
+ tcflag_t *bitsp;
+ unsigned long mask;
+ int prev_type = control;
+
+ display_speed(mode, 1);
+ if (all)
+ display_window_size(1);
+#ifdef HAVE_C_LINE
+ wrapf("line = %d;\n", mode->c_line);
+#else
+ wrapf("\n");
+#endif
+
+ for (i = 0; control_info[i].name != stty_min; ++i) {
+ /* If swtch is the same as susp, don't print both */
+#if VSWTCH == VSUSP
+ if (control_info[i].name == stty_swtch)
+ continue;
+#endif
+ /* If eof uses the same slot as min, only print whichever applies */
+#if VEOF == VMIN
+ if ((mode->c_lflag & ICANON) == 0
+ && (control_info[i].name == stty_eof
+ || control_info[i].name == stty_eol)) continue;
+#endif
+ wrapf("%s = %s;", control_info[i].name,
+ visible(mode->c_cc[control_info[i].offset]));
+ }
+#if VEOF == VMIN
+ if ((mode->c_lflag & ICANON) == 0)
+#endif
+ wrapf("min = %d; time = %d;", mode->c_cc[VMIN], mode->c_cc[VTIME]);
+ if (current_col) wrapf("\n");
+
+ for (i = 0; i < NUM_mode_info; ++i) {
+ if (mode_info[i].flags & OMIT)
+ continue;
+ if (mode_info[i].type != prev_type) {
+ /* wrapf("\n"); */
+ if (current_col) wrapf("\n");
+ prev_type = mode_info[i].type;
+ }
+
+ bitsp = mode_type_flag(mode_info[i].type, mode);
+ mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits;
+ if ((*bitsp & mask) == mode_info[i].bits) {
+ if (all || (mode_info[i].flags & SANE_UNSET))
+ wrapf("%s", mode_info[i].name);
+ } else {
+ if ((all && mode_info[i].flags & REV) ||
+ (!all &&
+ (mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV)))
+ wrapf("-%s", mode_info[i].name);
+ }
+ }
+ if (current_col) wrapf("\n");
+}
+
+static void sane_mode(struct termios *mode)
+{
+ int i;
+ tcflag_t *bitsp;
+
+ for (i = 0; i < NUM_control_info; ++i) {
+#if VMIN == VEOF
+ if (control_info[i].name == stty_min)
+ break;
+#endif
+ mode->c_cc[control_info[i].offset] = control_info[i].saneval;
+ }
+
+ for (i = 0; i < NUM_mode_info; ++i) {
+ if (mode_info[i].flags & SANE_SET) {
+ bitsp = mode_type_flag(mode_info[i].type, mode);
+ *bitsp = (*bitsp & ~((unsigned long)mode_info[i].mask))
+ | mode_info[i].bits;
+ } else if (mode_info[i].flags & SANE_UNSET) {
+ bitsp = mode_type_flag(mode_info[i].type, mode);
+ *bitsp = *bitsp & ~((unsigned long)mode_info[i].mask)
+ & ~mode_info[i].bits;
+ }
+ }
+}
+
+/* Save set_mode from #ifdef forest plague */
+#ifndef ONLCR
+#define ONLCR 0
+#endif
+#ifndef OCRNL
+#define OCRNL 0
+#endif
+#ifndef ONLRET
+#define ONLRET 0
+#endif
+#ifndef XCASE
+#define XCASE 0
+#endif
+#ifndef IXANY
+#define IXANY 0
+#endif
+#ifndef TABDLY
+#define TABDLY 0
+#endif
+#ifndef OXTABS
+#define OXTABS 0
+#endif
+#ifndef IUCLC
+#define IUCLC 0
+#endif
+#ifndef OLCUC
+#define OLCUC 0
+#endif
+#ifndef ECHOCTL
+#define ECHOCTL 0
+#endif
+#ifndef ECHOKE
+#define ECHOKE 0
+#endif
+
+static void set_mode(const struct mode_info *info, int reversed,
+ struct termios *mode)
+{
+ tcflag_t *bitsp;
+
+ bitsp = mode_type_flag(info->type, mode);
+
+ if (bitsp) {
+ if (reversed)
+ *bitsp = *bitsp & ~info->mask & ~info->bits;
+ else
+ *bitsp = (*bitsp & ~info->mask) | info->bits;
+ return;
+ }
+
+ /* Combination mode */
+ if (info->name == evenp || info->name == parity) {
+ if (reversed)
+ mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
+ else
+ mode->c_cflag = (mode->c_cflag & ~PARODD & ~CSIZE) | PARENB | CS7;
+ } else if (info->name == stty_oddp) {
+ if (reversed)
+ mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
+ else
+ mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARODD | PARENB;
+ } else if (info->name == stty_nl) {
+ if (reversed) {
+ mode->c_iflag = (mode->c_iflag | ICRNL) & ~INLCR & ~IGNCR;
+ mode->c_oflag = (mode->c_oflag | ONLCR) & ~OCRNL & ~ONLRET;
+ } else {
+ mode->c_iflag = mode->c_iflag & ~ICRNL;
+ if (ONLCR) mode->c_oflag = mode->c_oflag & ~ONLCR;
+ }
+ } else if (info->name == stty_ek) {
+ mode->c_cc[VERASE] = CERASE;
+ mode->c_cc[VKILL] = CKILL;
+ } else if (info->name == stty_sane) {
+ sane_mode(mode);
+ }
+ else if (info->name == cbreak) {
+ if (reversed)
+ mode->c_lflag |= ICANON;
+ else
+ mode->c_lflag &= ~ICANON;
+ } else if (info->name == stty_pass8) {
+ if (reversed) {
+ mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB;
+ mode->c_iflag |= ISTRIP;
+ } else {
+ mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
+ mode->c_iflag &= ~ISTRIP;
+ }
+ } else if (info->name == litout) {
+ if (reversed) {
+ mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB;
+ mode->c_iflag |= ISTRIP;
+ mode->c_oflag |= OPOST;
+ } else {
+ mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
+ mode->c_iflag &= ~ISTRIP;
+ mode->c_oflag &= ~OPOST;
+ }
+ } else if (info->name == raw || info->name == cooked) {
+ if ((info->name[0] == 'r' && reversed)
+ || (info->name[0] == 'c' && !reversed)) {
+ /* Cooked mode */
+ mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON;
+ mode->c_oflag |= OPOST;
+ mode->c_lflag |= ISIG | ICANON;
+#if VMIN == VEOF
+ mode->c_cc[VEOF] = CEOF;
+#endif
+#if VTIME == VEOL
+ mode->c_cc[VEOL] = CEOL;
+#endif
+ } else {
+ /* Raw mode */
+ mode->c_iflag = 0;
+ mode->c_oflag &= ~OPOST;
+ mode->c_lflag &= ~(ISIG | ICANON | XCASE);
+ mode->c_cc[VMIN] = 1;
+ mode->c_cc[VTIME] = 0;
+ }
+ }
+ else if (IXANY && info->name == decctlq) {
+ if (reversed)
+ mode->c_iflag |= IXANY;
+ else
+ mode->c_iflag &= ~IXANY;
+ }
+ else if (TABDLY && info->name == stty_tabs) {
+ if (reversed)
+ mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB3;
+ else
+ mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB0;
+ }
+ else if (OXTABS && info->name == stty_tabs) {
+ if (reversed)
+ mode->c_oflag |= OXTABS;
+ else
+ mode->c_oflag &= ~OXTABS;
+ }
+ else if (XCASE && IUCLC && OLCUC
+ && (info->name == stty_lcase || info->name == stty_LCASE)) {
+ if (reversed) {
+ mode->c_lflag &= ~XCASE;
+ mode->c_iflag &= ~IUCLC;
+ mode->c_oflag &= ~OLCUC;
+ } else {
+ mode->c_lflag |= XCASE;
+ mode->c_iflag |= IUCLC;
+ mode->c_oflag |= OLCUC;
+ }
+ }
+ else if (info->name == stty_crt) {
+ mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE;
+ }
+ else if (info->name == stty_dec) {
+ mode->c_cc[VINTR] = 3; /* ^C */
+ mode->c_cc[VERASE] = 127; /* DEL */
+ mode->c_cc[VKILL] = 21; /* ^U */
+ mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE;
+ if (IXANY) mode->c_iflag &= ~IXANY;
+ }
+}
+
+static void set_control_char_or_die(const struct control_info *info,
+ const char *arg, struct termios *mode)
+{
+ unsigned char value;
+
+ if (info->name == stty_min || info->name == stty_time)
+ value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes);
+ else if (arg[0] == '\0' || arg[1] == '\0')
+ value = arg[0];
+ else if (!strcmp(arg, "^-") || !strcmp(arg, "undef"))
+ value = _POSIX_VDISABLE;
+ else if (arg[0] == '^') { /* Ignore any trailing junk (^Cjunk) */
+ value = arg[1] & 0x1f; /* Non-letters get weird results */
+ if (arg[1] == '?')
+ value = 127;
+ } else
+ value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes);
+ mode->c_cc[info->offset] = value;
+}
+
+#define STTY_require_set_attr (1<<0)
+#define STTY_speed_was_set (1<<1)
+#define STTY_verbose_output (1<<2)
+#define STTY_recoverable_output (1<<3)
+#define STTY_noargs (1<<4)
+int stty_main(int argc, char **argv);
+int stty_main(int argc, char **argv)
+{
+ struct termios mode;
+ void (*output_func)(const struct termios *, const int);
+ const char *file_name = NULL;
+ int display_all = 0;
+ int stty_state;
+ int k;
+
+ stty_state = STTY_noargs;
+ output_func = do_display;
+
+ /* First pass: only parse/verify command line params */
+ k = 0;
+ while (argv[++k]) {
+ const struct mode_info *mp;
+ const struct control_info *cp;
+ const char *arg = argv[k];
+ const char *argnext = argv[k+1];
+ int param;
+
+ if (arg[0] == '-') {
+ int i;
+ mp = find_mode(arg+1);
+ if (mp) {
+ if (!(mp->flags & REV))
+ goto invalid_argument;
+ stty_state &= ~STTY_noargs;
+ continue;
+ }
+ /* It is an option - parse it */
+ i = 0;
+ while (arg[++i]) {
+ switch (arg[i]) {
+ case 'a':
+ stty_state |= STTY_verbose_output;
+ output_func = do_display;
+ display_all = 1;
+ break;
+ case 'g':
+ stty_state |= STTY_recoverable_output;
+ output_func = display_recoverable;
+ break;
+ case 'F':
+ if (file_name)
+ bb_error_msg_and_die("only one device may be specified");
+ file_name = &arg[i+1]; /* "-Fdevice" ? */
+ if (!file_name[0]) { /* nope, "-F device" */
+ int p = k+1; /* argv[p] is argnext */
+ file_name = argnext;
+ if (!file_name)
+ bb_error_msg_and_die(bb_msg_requires_arg, "-F");
+ /* remove -F param from arg[vc] */
+ --argc;
+ while (argv[p]) { argv[p] = argv[p+1]; ++p; }
+ }
+ goto end_option;
+ default:
+ goto invalid_argument;
+ }
+ }
+end_option:
+ continue;
+ }
+
+ mp = find_mode(arg);
+ if (mp) {
+ stty_state &= ~STTY_noargs;
+ continue;
+ }
+
+ cp = find_control(arg);
+ if (cp) {
+ if (!argnext)
+ bb_error_msg_and_die(bb_msg_requires_arg, arg);
+ /* called for the side effect of xfunc death only */
+ set_control_char_or_die(cp, argnext, &mode);
+ stty_state &= ~STTY_noargs;
+ ++k;
+ continue;
+ }
+
+ param = find_param(arg);
+ if (param & param_need_arg) {
+ if (!argnext)
+ bb_error_msg_and_die(bb_msg_requires_arg, arg);
+ ++k;
+ }
+
+ switch (param) {
+#ifdef HAVE_C_LINE
+ case param_line:
+# ifndef TIOCGWINSZ
+ xatoul_range_sfx(argnext, 1, INT_MAX, stty_suffixes);
+ break;
+# endif /* else fall-through */
+#endif
+#ifdef TIOCGWINSZ
+ case param_rows:
+ case param_cols:
+ xatoul_range_sfx(argnext, 1, INT_MAX, stty_suffixes);
+ break;
+ case param_size:
+#endif
+ case param_speed:
+ break;
+ case param_ispeed:
+ /* called for the side effect of xfunc death only */
+ set_speed_or_die(input_speed, argnext, &mode);
+ break;
+ case param_ospeed:
+ /* called for the side effect of xfunc death only */
+ set_speed_or_die(output_speed, argnext, &mode);
+ break;
+ default:
+ if (recover_mode(arg, &mode) == 1) break;
+ if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) break;
+invalid_argument:
+ bb_error_msg_and_die("invalid argument '%s'", arg);
+ }
+ stty_state &= ~STTY_noargs;
+ }
+
+ /* Specifying both -a and -g is an error */
+ if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) ==
+ (STTY_verbose_output | STTY_recoverable_output))
+ bb_error_msg_and_die("verbose and stty-readable output styles are mutually exclusive");
+ /* Specifying -a or -g with non-options is an error */
+ if (!(stty_state & STTY_noargs) &&
+ (stty_state & (STTY_verbose_output | STTY_recoverable_output)))
+ bb_error_msg_and_die("modes may not be set when specifying an output style");
+
+ /* Now it is safe to start doing things */
+ if (file_name) {
+ int fd, fdflags;
+ device_name = file_name;
+ fd = xopen(device_name, O_RDONLY | O_NONBLOCK);
+ if (fd != STDIN_FILENO) {
+ dup2(fd, STDIN_FILENO);
+ close(fd);
+ }
+ fdflags = fcntl(STDIN_FILENO, F_GETFL);
+ if (fdflags < 0 ||
+ fcntl(STDIN_FILENO, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
+ perror_on_device_and_die("%s: cannot reset non-blocking mode");
+ }
+
+ /* Initialize to all zeroes so there is no risk memcmp will report a
+ spurious difference in an uninitialized portion of the structure */
+ memset(&mode, 0, sizeof(mode));
+ if (tcgetattr(STDIN_FILENO, &mode))
+ perror_on_device_and_die("%s");
+
+ if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) {
+ get_terminal_width_height(STDOUT_FILENO, &max_col, NULL);
+ output_func(&mode, display_all);
+ return EXIT_SUCCESS;
+ }
+
+ /* Second pass: perform actions */
+ k = 0;
+ while (argv[++k]) {
+ const struct mode_info *mp;
+ const struct control_info *cp;
+ const char *arg = argv[k];
+ const char *argnext = argv[k+1];
+ int param;
+
+ if (arg[0] == '-') {
+ mp = find_mode(arg+1);
+ if (mp) {
+ set_mode(mp, 1 /* reversed */, &mode);
+ stty_state |= STTY_require_set_attr;
+ }
+ /* It is an option - already parsed. Skip it */
+ continue;
+ }
+
+ mp = find_mode(arg);
+ if (mp) {
+ set_mode(mp, 0 /* non-reversed */, &mode);
+ stty_state |= STTY_require_set_attr;
+ continue;
+ }
+
+ cp = find_control(arg);
+ if (cp) {
+ ++k;
+ set_control_char_or_die(cp, argnext, &mode);
+ stty_state |= STTY_require_set_attr;
+ continue;
+ }
+
+ param = find_param(arg);
+ if (param & param_need_arg) {
+ ++k;
+ }
+
+ switch (param) {
+#ifdef HAVE_C_LINE
+ case param_line:
+ mode.c_line = xatoul_sfx(argnext, stty_suffixes);
+ stty_state |= STTY_require_set_attr;
+ break;
+#endif
+#ifdef TIOCGWINSZ
+ case param_cols:
+ set_window_size(-1, xatoul_sfx(argnext, stty_suffixes));
+ break;
+ case param_size:
+ display_window_size(0);
+ break;
+ case param_rows:
+ set_window_size(xatoul_sfx(argnext, stty_suffixes), -1);
+ break;
+#endif
+ case param_speed:
+ display_speed(&mode, 0);
+ break;
+ case param_ispeed:
+ set_speed_or_die(input_speed, argnext, &mode);
+ stty_state |= (STTY_require_set_attr | STTY_speed_was_set);
+ break;
+ case param_ospeed:
+ set_speed_or_die(output_speed, argnext, &mode);
+ stty_state |= (STTY_require_set_attr | STTY_speed_was_set);
+ break;
+ default:
+ if (recover_mode(arg, &mode) == 1)
+ stty_state |= STTY_require_set_attr;
+ else /* true: if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) */{
+ set_speed_or_die(both_speeds, arg, &mode);
+ stty_state |= (STTY_require_set_attr | STTY_speed_was_set);
+ } /* else - impossible (caught in the first pass):
+ bb_error_msg_and_die("invalid argument '%s'", arg); */
+ }
+ }
+
+ if (stty_state & STTY_require_set_attr) {
+ struct termios new_mode;
+
+ if (tcsetattr(STDIN_FILENO, TCSADRAIN, &mode))
+ perror_on_device_and_die("%s");
+
+ /* POSIX (according to Zlotnick's book) tcsetattr returns zero if
+ it performs *any* of the requested operations. This means it
+ can report 'success' when it has actually failed to perform
+ some proper subset of the requested operations. To detect
+ this partial failure, get the current terminal attributes and
+ compare them to the requested ones */
+
+ /* Initialize to all zeroes so there is no risk memcmp will report a
+ spurious difference in an uninitialized portion of the structure */
+ memset(&new_mode, 0, sizeof(new_mode));
+ if (tcgetattr(STDIN_FILENO, &new_mode))
+ perror_on_device_and_die("%s");
+
+ if (memcmp(&mode, &new_mode, sizeof(mode)) != 0) {
+#ifdef CIBAUD
+ /* SunOS 4.1.3 (at least) has the problem that after this sequence,
+ tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
+ sometimes (m1 != m2). The only difference is in the four bits
+ of the c_cflag field corresponding to the baud rate. To save
+ Sun users a little confusion, don't report an error if this
+ happens. But suppress the error only if we haven't tried to
+ set the baud rate explicitly -- otherwise we'd never give an
+ error for a true failure to set the baud rate */
+
+ new_mode.c_cflag &= (~CIBAUD);
+ if ((stty_state & STTY_speed_was_set)
+ || memcmp(&mode, &new_mode, sizeof(mode)) != 0)
+#endif
+ perror_on_device_and_die("%s: cannot perform all requested operations");
+ }
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/sum.c b/i/pc104/initrd/conf/busybox/coreutils/sum.c
new file mode 100644
index 0000000..9327ca5
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/sum.c
@@ -0,0 +1,100 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * sum -- checksum and count the blocks in a file
+ * Like BSD sum or SysV sum -r, except like SysV sum if -s option is given.
+ *
+ * Copyright (C) 86, 89, 91, 1995-2002, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
+ * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
+ *
+ * Written by Kayvan Aghaiepour and David MacKenzie
+ * Taken from coreutils and turned into a busybox applet by Mike Frysinger
+ *
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+ */
+
+#include "busybox.h"
+
+enum { SUM_BSD, PRINT_NAME, SUM_SYSV };
+
+/* BSD: calculate and print the rotated checksum and the size in 1K blocks
+ The checksum varies depending on sizeof (int). */
+/* SYSV: calculate and print the checksum and the size in 512-byte blocks */
+/* Return 1 if successful. */
+static unsigned sum_file(const char *file, const unsigned type)
+{
+#define buf bb_common_bufsiz1
+ uintmax_t total_bytes = 0;
+ int fd = 0, r;
+
+ /* The sum of all the input bytes, modulo (UINT_MAX + 1). */
+ unsigned s = 0;
+
+ if (NOT_LONE_DASH(file)) {
+ fd = open(file, O_RDONLY);
+ if (fd == -1)
+ goto ret_bad;
+ }
+
+ while (1) {
+ size_t bytes_read = safe_read(fd, buf, BUFSIZ);
+
+ if ((ssize_t)bytes_read <= 0) {
+ r = (fd && close(fd) != 0);
+ if (!bytes_read && !r)
+ /* no error */
+ break;
+ ret_bad:
+ bb_perror_msg(file);
+ return 0;
+ }
+
+ total_bytes += bytes_read;
+ if (type >= SUM_SYSV) {
+ do s += buf[--bytes_read]; while (bytes_read);
+ } else {
+ r = 0;
+ do {
+ s = (s >> 1) + ((s & 1) << 15);
+ s += buf[r++];
+ s &= 0xffff; /* Keep it within bounds. */
+ } while (--bytes_read);
+ }
+ }
+
+ if (type < PRINT_NAME)
+ file = "";
+ if (type >= SUM_SYSV) {
+ r = (s & 0xffff) + ((s & 0xffffffff) >> 16);
+ s = (r & 0xffff) + (r >> 16);
+ printf("%d %ju %s\n", s, (total_bytes+511)/512, file);
+ } else
+ printf("%05d %5ju %s\n", s, (total_bytes+1023)/1024, file);
+ return 1;
+#undef buf
+}
+
+int sum_main(int argc, char **argv);
+int sum_main(int argc, char **argv)
+{
+ unsigned n;
+ unsigned type = SUM_BSD;
+
+ n = getopt32(argc, argv, "sr");
+ if (n & 1) type = SUM_SYSV;
+ /* give the bsd priority over sysv func */
+ if (n & 2) type = SUM_BSD;
+
+ if (argc == optind) {
+ /* Do not print the name */
+ n = sum_file("-", type);
+ } else {
+ /* Need to print the name if either
+ - more than one file given
+ - doing sysv */
+ type += argc - 1 > optind || type == SUM_SYSV;
+ for (n = 1; optind < argc; optind++)
+ n &= sum_file(argv[optind], type);
+ }
+ return !n;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/sync.c b/i/pc104/initrd/conf/busybox/coreutils/sync.c
new file mode 100644
index 0000000..536c57a
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/sync.c
@@ -0,0 +1,24 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini sync implementation for busybox
+ *
+ * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "busybox.h"
+
+int sync_main(int argc, char **argv);
+int sync_main(int argc, char **argv)
+{
+ bb_warn_ignoring_args(argc - 1);
+
+ sync();
+
+ return EXIT_SUCCESS;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/tail.c b/i/pc104/initrd/conf/busybox/coreutils/tail.c
new file mode 100644
index 0000000..52bacb7
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/tail.c
@@ -0,0 +1,278 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini tail implementation for busybox
+ *
+ * Copyright (C) 2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant (need fancy for -c) */
+/* BB_AUDIT GNU compatible -c, -q, and -v options in 'fancy' configuration. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/tail.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Pretty much rewritten to fix numerous bugs and reduce realloc() calls.
+ * Bugs fixed (although I may have forgotten one or two... it was pretty bad)
+ * 1) mixing printf/write without fflush()ing stdout
+ * 2) no check that any open files are present
+ * 3) optstring had -q taking an arg
+ * 4) no error checking on write in some cases, and a warning even then
+ * 5) q and s interaction bug
+ * 6) no check for lseek error
+ * 7) lseek attempted when count==0 even if arg was +0 (from top)
+ */
+
+#include "busybox.h"
+
+static const struct suffix_mult tail_suffixes[] = {
+ { "b", 512 },
+ { "k", 1024 },
+ { "m", 1024*1024 },
+ { NULL, 0 }
+};
+
+static int status;
+
+static void tail_xprint_header(const char *fmt, const char *filename)
+{
+ if (fdprintf(STDOUT_FILENO, fmt, filename) < 0)
+ bb_perror_nomsg_and_die();
+}
+
+static ssize_t tail_read(int fd, char *buf, size_t count)
+{
+ ssize_t r;
+ off_t current, end;
+ struct stat sbuf;
+
+ end = current = lseek(fd, 0, SEEK_CUR);
+ if (!fstat(fd, &sbuf))
+ end = sbuf.st_size;
+ lseek(fd, end < current ? 0 : current, SEEK_SET);
+ r = safe_read(fd, buf, count);
+ if (r < 0) {
+ bb_perror_msg(bb_msg_read_error);
+ status = EXIT_FAILURE;
+ }
+
+ return r;
+}
+
+static const char header_fmt[] = "\n==> %s <==\n";
+
+static unsigned eat_num(const char *p) {
+ if (*p == '-') p++;
+ else if (*p == '+') { p++; status = 1; }
+ return xatou_sfx(p, tail_suffixes);
+}
+
+int tail_main(int argc, char **argv);
+int tail_main(int argc, char **argv)
+{
+ unsigned count = 10;
+ unsigned sleep_period = 1;
+ bool from_top;
+ int header_threshhold = 1;
+ const char *str_c, *str_n, *str_s;
+
+ char *tailbuf;
+ size_t tailbufsize;
+ int taillen = 0;
+ int newline = 0;
+ int nfiles, nread, nwrite, seen, i, opt;
+
+ int *fds;
+ char *s, *buf;
+ const char *fmt;
+
+#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_TAIL
+ /* Allow legacy syntax of an initial numeric option without -n. */
+ if (argc >= 2 && (argv[1][0] == '+' || argv[1][0] == '-')
+ && isdigit(argv[1][1])
+ ) {
+ argv[0] = (char*)"-n";
+ argv--;
+ argc++;
+ }
+#endif
+
+ opt = getopt32(argc, argv, "fc:n:" USE_FEATURE_FANCY_TAIL("qs:v"), &str_c, &str_n, &str_s);
+#define FOLLOW (opt & 0x1)
+#define COUNT_BYTES (opt & 0x2)
+ //if (opt & 0x1) // -f
+ if (opt & 0x2) count = eat_num(str_c); // -c
+ if (opt & 0x4) count = eat_num(str_n); // -n
+#if ENABLE_FEATURE_FANCY_TAIL
+ if (opt & 0x8) header_threshhold = INT_MAX; // -q
+ if (opt & 0x10) sleep_period = xatou(str_s); // -s
+ if (opt & 0x20) header_threshhold = 0; // -v
+#endif
+ argc -= optind;
+ argv += optind;
+ from_top = status;
+
+ /* open all the files */
+ fds = xmalloc(sizeof(int) * (argc + 1));
+ status = nfiles = i = 0;
+ if (argc == 0) {
+ struct stat statbuf;
+
+ if (!fstat(STDIN_FILENO, &statbuf) && S_ISFIFO(statbuf.st_mode)) {
+ opt &= ~1; /* clear FOLLOW */
+ }
+ *argv = (char *) bb_msg_standard_input;
+ goto DO_STDIN;
+ }
+
+ do {
+ if (NOT_LONE_DASH(argv[i])) {
+ fds[nfiles] = open(argv[i], O_RDONLY);
+ if (fds[nfiles] < 0) {
+ bb_perror_msg("%s", argv[i]);
+ status = EXIT_FAILURE;
+ continue;
+ }
+ } else {
+ DO_STDIN: /* "-" */
+ fds[nfiles] = STDIN_FILENO;
+ }
+ argv[nfiles] = argv[i];
+ ++nfiles;
+ } while (++i < argc);
+
+ if (!nfiles)
+ bb_error_msg_and_die("no files");
+
+ tailbufsize = BUFSIZ;
+
+ /* tail the files */
+ if (!from_top && COUNT_BYTES) {
+ if (tailbufsize < count) {
+ tailbufsize = count + BUFSIZ;
+ }
+ }
+
+ buf = tailbuf = xmalloc(tailbufsize);
+
+ fmt = header_fmt + 1; /* Skip header leading newline on first output. */
+ i = 0;
+ do {
+ /* Be careful. It would be possible to optimize the count-bytes
+ * case if the file is seekable. If you do though, remember that
+ * starting file position may not be the beginning of the file.
+ * Beware of backing up too far. See example in wc.c.
+ */
+ if (!(count | from_top) && lseek(fds[i], 0, SEEK_END) >= 0) {
+ continue;
+ }
+
+ if (nfiles > header_threshhold) {
+ tail_xprint_header(fmt, argv[i]);
+ fmt = header_fmt;
+ }
+
+ buf = tailbuf;
+ taillen = 0;
+ seen = 1;
+ newline = 0;
+
+ while ((nread = tail_read(fds[i], buf, tailbufsize-taillen)) > 0) {
+ if (from_top) {
+ nwrite = nread;
+ if (seen < count) {
+ if (COUNT_BYTES) {
+ nwrite -= (count - seen);
+ seen = count;
+ } else {
+ s = buf;
+ do {
+ --nwrite;
+ if (*s++ == '\n' && ++seen == count) {
+ break;
+ }
+ } while (nwrite);
+ }
+ }
+ xwrite(STDOUT_FILENO, buf + nread - nwrite, nwrite);
+ } else if (count) {
+ if (COUNT_BYTES) {
+ taillen += nread;
+ if (taillen > count) {
+ memmove(tailbuf, tailbuf + taillen - count, count);
+ taillen = count;
+ }
+ } else {
+ int k = nread;
+ int nbuf = 0;
+
+ while (k) {
+ --k;
+ if (buf[k] == '\n') {
+ ++nbuf;
+ }
+ }
+
+ if (newline + nbuf < count) {
+ newline += nbuf;
+ taillen += nread;
+
+ } else {
+ int extra = 0;
+ if (buf[nread-1] != '\n') {
+ extra = 1;
+ }
+
+ k = newline + nbuf + extra - count;
+ s = tailbuf;
+ while (k) {
+ if (*s == '\n') {
+ --k;
+ }
+ ++s;
+ }
+
+ taillen += nread - (s - tailbuf);
+ memmove(tailbuf, s, taillen);
+ newline = count - extra;
+ }
+ if (tailbufsize < taillen + BUFSIZ) {
+ tailbufsize = taillen + BUFSIZ;
+ tailbuf = xrealloc(tailbuf, tailbufsize);
+ }
+ }
+ buf = tailbuf + taillen;
+ }
+ }
+
+ if (!from_top) {
+ xwrite(STDOUT_FILENO, tailbuf, taillen);
+ }
+
+ taillen = 0;
+ } while (++i < nfiles);
+
+ buf = xrealloc(tailbuf, BUFSIZ);
+
+ fmt = NULL;
+
+ if (FOLLOW) while (1) {
+ sleep(sleep_period);
+ i = 0;
+ do {
+ if (nfiles > header_threshhold) {
+ fmt = header_fmt;
+ }
+ while ((nread = tail_read(fds[i], buf, sizeof(buf))) > 0) {
+ if (fmt) {
+ tail_xprint_header(fmt, argv[i]);
+ fmt = NULL;
+ }
+ xwrite(STDOUT_FILENO, buf, nread);
+ }
+ } while (++i < nfiles);
+ }
+
+ return status;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/tee.c b/i/pc104/initrd/conf/busybox/coreutils/tee.c
new file mode 100644
index 0000000..338232c
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/tee.c
@@ -0,0 +1,101 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * tee implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */
+
+#include "busybox.h"
+#include <signal.h>
+
+int tee_main(int argc, char **argv);
+int tee_main(int argc, char **argv)
+{
+ const char *mode = "w\0a";
+ FILE **files;
+ FILE **fp;
+ char **names;
+ char **np;
+ char retval;
+#if ENABLE_FEATURE_TEE_USE_BLOCK_IO
+ ssize_t c;
+# define buf bb_common_bufsiz1
+#else
+ int c;
+#endif
+ retval = getopt32(argc, argv, "ia"); /* 'a' must be 2nd */
+ argc -= optind;
+ argv += optind;
+
+ mode += (retval & 2); /* Since 'a' is the 2nd option... */
+
+ if (retval & 1) {
+ signal(SIGINT, SIG_IGN); /* TODO - switch to sigaction. */
+ }
+ retval = EXIT_SUCCESS;
+ /* gnu tee ignores SIGPIPE in case one of the output files is a pipe
+ * that doesn't consume all its input. Good idea... */
+ signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction. */
+
+ /* Allocate an array of FILE *'s, with one extra for a sentinal. */
+ fp = files = xzalloc(sizeof(FILE *) * (argc + 2));
+ np = names = argv - 1;
+
+ files[0] = stdout;
+ goto GOT_NEW_FILE;
+ do {
+ *fp = fopen_or_warn(*argv, mode);
+ if (*fp == NULL) {
+ retval = EXIT_FAILURE;
+ continue;
+ }
+ *np = *argv++;
+ GOT_NEW_FILE:
+ setbuf(*fp++, NULL); /* tee must not buffer output. */
+ np++;
+ } while (*argv);
+ /* names[0] will be filled later */
+
+#if ENABLE_FEATURE_TEE_USE_BLOCK_IO
+ while ((c = safe_read(STDIN_FILENO, buf, BUFSIZ)) > 0) {
+ fp = files;
+ do
+ fwrite(buf, 1, c, *fp++);
+ while (*fp);
+ }
+ if (c < 0) { /* Make sure read errors are signaled. */
+ retval = EXIT_FAILURE;
+ }
+#else
+ setvbuf(stdout, NULL, _IONBF, 0);
+ while ((c = getchar()) != EOF) {
+ fp = files;
+ do
+ putc(c, *fp++);
+ while (*fp);
+ }
+#endif
+
+ /* Now we need to check for i/o errors on stdin and the various
+ * output files. Since we know that the first entry in the output
+ * file table is stdout, we can save one "if ferror" test by
+ * setting the first entry to stdin and checking stdout error
+ * status with fflush_stdout_and_exit()... although fflush()ing
+ * is unnecessary here. */
+ np = names;
+ fp = files;
+ names[0] = (char *) bb_msg_standard_input;
+ files[0] = stdin;
+ do { /* Now check for input and output errors. */
+ /* Checking ferror should be sufficient, but we may want to fclose.
+ * If we do, remember not to close stdin! */
+ die_if_ferror(*fp++, *np++);
+ } while (*fp);
+
+ fflush_stdout_and_exit(retval);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/test.c b/i/pc104/initrd/conf/busybox/coreutils/test.c
new file mode 100644
index 0000000..6e0d5d3
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/test.c
@@ -0,0 +1,586 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * test implementation for busybox
+ *
+ * Copyright (c) by a whole pile of folks:
+ *
+ * test(1); version 7-like -- author Erik Baalbergen
+ * modified by Eric Gisin to be used as built-in.
+ * modified by Arnold Robbins to add SVR3 compatibility
+ * (-x -c -b -p -u -g -k) plus Korn's -L -nt -ot -ef and new -S (socket).
+ * modified by J.T. Conklin for NetBSD.
+ * modified by Herbert Xu to be used as built-in in ash.
+ * modified by Erik Andersen <andersen@codepoet.org> to be used
+ * in busybox.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ * Original copyright notice states:
+ * "This program is in the Public Domain."
+ */
+
+#include "busybox.h"
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <setjmp.h>
+
+/* test(1) accepts the following grammar:
+ oexpr ::= aexpr | aexpr "-o" oexpr ;
+ aexpr ::= nexpr | nexpr "-a" aexpr ;
+ nexpr ::= primary | "!" primary
+ primary ::= unary-operator operand
+ | operand binary-operator operand
+ | operand
+ | "(" oexpr ")"
+ ;
+ unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"|
+ "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S";
+
+ binary-operator ::= "="|"=="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"|
+ "-nt"|"-ot"|"-ef";
+ operand ::= <any legal UNIX file name>
+*/
+
+enum token {
+ EOI,
+ FILRD,
+ FILWR,
+ FILEX,
+ FILEXIST,
+ FILREG,
+ FILDIR,
+ FILCDEV,
+ FILBDEV,
+ FILFIFO,
+ FILSOCK,
+ FILSYM,
+ FILGZ,
+ FILTT,
+ FILSUID,
+ FILSGID,
+ FILSTCK,
+ FILNT,
+ FILOT,
+ FILEQ,
+ FILUID,
+ FILGID,
+ STREZ,
+ STRNZ,
+ STREQ,
+ STRNE,
+ STRLT,
+ STRGT,
+ INTEQ,
+ INTNE,
+ INTGE,
+ INTGT,
+ INTLE,
+ INTLT,
+ UNOT,
+ BAND,
+ BOR,
+ LPAREN,
+ RPAREN,
+ OPERAND
+};
+
+enum token_types {
+ UNOP,
+ BINOP,
+ BUNOP,
+ BBINOP,
+ PAREN
+};
+
+static const struct t_op {
+ const char *op_text;
+ short op_num, op_type;
+} ops[] = {
+ {
+ "-r", FILRD, UNOP}, {
+ "-w", FILWR, UNOP}, {
+ "-x", FILEX, UNOP}, {
+ "-e", FILEXIST, UNOP}, {
+ "-f", FILREG, UNOP}, {
+ "-d", FILDIR, UNOP}, {
+ "-c", FILCDEV, UNOP}, {
+ "-b", FILBDEV, UNOP}, {
+ "-p", FILFIFO, UNOP}, {
+ "-u", FILSUID, UNOP}, {
+ "-g", FILSGID, UNOP}, {
+ "-k", FILSTCK, UNOP}, {
+ "-s", FILGZ, UNOP}, {
+ "-t", FILTT, UNOP}, {
+ "-z", STREZ, UNOP}, {
+ "-n", STRNZ, UNOP}, {
+ "-h", FILSYM, UNOP}, /* for backwards compat */
+ {
+ "-O", FILUID, UNOP}, {
+ "-G", FILGID, UNOP}, {
+ "-L", FILSYM, UNOP}, {
+ "-S", FILSOCK, UNOP}, {
+ "=", STREQ, BINOP}, {
+ "==", STREQ, BINOP}, {
+ "!=", STRNE, BINOP}, {
+ "<", STRLT, BINOP}, {
+ ">", STRGT, BINOP}, {
+ "-eq", INTEQ, BINOP}, {
+ "-ne", INTNE, BINOP}, {
+ "-ge", INTGE, BINOP}, {
+ "-gt", INTGT, BINOP}, {
+ "-le", INTLE, BINOP}, {
+ "-lt", INTLT, BINOP}, {
+ "-nt", FILNT, BINOP}, {
+ "-ot", FILOT, BINOP}, {
+ "-ef", FILEQ, BINOP}, {
+ "!", UNOT, BUNOP}, {
+ "-a", BAND, BBINOP}, {
+ "-o", BOR, BBINOP}, {
+ "(", LPAREN, PAREN}, {
+ ")", RPAREN, PAREN}, {
+ 0, 0, 0}
+};
+
+#ifdef CONFIG_FEATURE_TEST_64
+typedef int64_t arith_t;
+#else
+typedef int arith_t;
+#endif
+
+static char **t_wp;
+static struct t_op const *t_wp_op;
+static gid_t *group_array;
+static int ngroups;
+
+static enum token t_lex(char *s);
+static arith_t oexpr(enum token n);
+static arith_t aexpr(enum token n);
+static arith_t nexpr(enum token n);
+static int binop(void);
+static arith_t primary(enum token n);
+static int filstat(char *nm, enum token mode);
+static arith_t getn(const char *s);
+static int newerf(const char *f1, const char *f2);
+static int olderf(const char *f1, const char *f2);
+static int equalf(const char *f1, const char *f2);
+static int test_eaccess(char *path, int mode);
+static int is_a_group_member(gid_t gid);
+static void initialize_group_array(void);
+
+static jmp_buf leaving;
+
+int bb_test(int argc, char **argv)
+{
+ int res;
+
+ if (LONE_CHAR(argv[0], '[')) {
+ --argc;
+ if (NOT_LONE_CHAR(argv[argc], ']')) {
+ bb_error_msg("missing ]");
+ return 2;
+ }
+ argv[argc] = NULL;
+ } else if (strcmp(argv[0], "[[") == 0) {
+ --argc;
+ if (strcmp(argv[argc], "]]")) {
+ bb_error_msg("missing ]]");
+ return 2;
+ }
+ argv[argc] = NULL;
+ }
+
+ res = setjmp(leaving);
+ if (res)
+ return res;
+
+ /* resetting ngroups is probably unnecessary. it will
+ * force a new call to getgroups(), which prevents using
+ * group data fetched during a previous call. but the
+ * only way the group data could be stale is if there's
+ * been an intervening call to setgroups(), and this
+ * isn't likely in the case of a shell. paranoia
+ * prevails...
+ */
+ ngroups = 0;
+
+ /* Implement special cases from POSIX.2, section 4.62.4 */
+ switch (argc) {
+ case 1:
+ return 1;
+ case 2:
+ return *argv[1] == '\0';
+ case 3:
+ if (argv[1][0] == '!' && argv[1][1] == '\0') {
+ return *argv[2] != '\0';
+ }
+ break;
+ case 4:
+ if (argv[1][0] != '!' || argv[1][1] != '\0') {
+ if (t_lex(argv[2]), t_wp_op && t_wp_op->op_type == BINOP) {
+ t_wp = &argv[1];
+ return binop() == 0;
+ }
+ }
+ break;
+ case 5:
+ if (argv[1][0] == '!' && argv[1][1] == '\0') {
+ if (t_lex(argv[3]), t_wp_op && t_wp_op->op_type == BINOP) {
+ t_wp = &argv[2];
+ return binop() != 0;
+ }
+ }
+ break;
+ }
+
+ t_wp = &argv[1];
+ res = !oexpr(t_lex(*t_wp));
+
+ if (*t_wp != NULL && *++t_wp != NULL) {
+ bb_error_msg("%s: unknown operand", *t_wp);
+ return 2;
+ }
+ return res;
+}
+
+static void syntax(const char *op, const char *msg)
+{
+ if (op && *op) {
+ bb_error_msg("%s: %s", op, msg);
+ } else {
+ bb_error_msg("%s", msg);
+ }
+ longjmp(leaving, 2);
+}
+
+static arith_t oexpr(enum token n)
+{
+ arith_t res;
+
+ res = aexpr(n);
+ if (t_lex(*++t_wp) == BOR) {
+ return oexpr(t_lex(*++t_wp)) || res;
+ }
+ t_wp--;
+ return res;
+}
+
+static arith_t aexpr(enum token n)
+{
+ arith_t res;
+
+ res = nexpr(n);
+ if (t_lex(*++t_wp) == BAND)
+ return aexpr(t_lex(*++t_wp)) && res;
+ t_wp--;
+ return res;
+}
+
+static arith_t nexpr(enum token n)
+{
+ if (n == UNOT)
+ return !nexpr(t_lex(*++t_wp));
+ return primary(n);
+}
+
+static arith_t primary(enum token n)
+{
+ arith_t res;
+
+ if (n == EOI) {
+ syntax(NULL, "argument expected");
+ }
+ if (n == LPAREN) {
+ res = oexpr(t_lex(*++t_wp));
+ if (t_lex(*++t_wp) != RPAREN)
+ syntax(NULL, "closing paren expected");
+ return res;
+ }
+ if (t_wp_op && t_wp_op->op_type == UNOP) {
+ /* unary expression */
+ if (*++t_wp == NULL)
+ syntax(t_wp_op->op_text, "argument expected");
+ switch (n) {
+ case STREZ:
+ return strlen(*t_wp) == 0;
+ case STRNZ:
+ return strlen(*t_wp) != 0;
+ case FILTT:
+ return isatty(getn(*t_wp));
+ default:
+ return filstat(*t_wp, n);
+ }
+ }
+
+ if (t_lex(t_wp[1]), t_wp_op && t_wp_op->op_type == BINOP) {
+ return binop();
+ }
+
+ return strlen(*t_wp) > 0;
+}
+
+static int binop(void)
+{
+ const char *opnd1, *opnd2;
+ struct t_op const *op;
+
+ opnd1 = *t_wp;
+ (void) t_lex(*++t_wp);
+ op = t_wp_op;
+
+ if ((opnd2 = *++t_wp) == (char *) 0)
+ syntax(op->op_text, "argument expected");
+
+ switch (op->op_num) {
+ case STREQ:
+ return strcmp(opnd1, opnd2) == 0;
+ case STRNE:
+ return strcmp(opnd1, opnd2) != 0;
+ case STRLT:
+ return strcmp(opnd1, opnd2) < 0;
+ case STRGT:
+ return strcmp(opnd1, opnd2) > 0;
+ case INTEQ:
+ return getn(opnd1) == getn(opnd2);
+ case INTNE:
+ return getn(opnd1) != getn(opnd2);
+ case INTGE:
+ return getn(opnd1) >= getn(opnd2);
+ case INTGT:
+ return getn(opnd1) > getn(opnd2);
+ case INTLE:
+ return getn(opnd1) <= getn(opnd2);
+ case INTLT:
+ return getn(opnd1) < getn(opnd2);
+ case FILNT:
+ return newerf(opnd1, opnd2);
+ case FILOT:
+ return olderf(opnd1, opnd2);
+ case FILEQ:
+ return equalf(opnd1, opnd2);
+ }
+ /* NOTREACHED */
+ return 1;
+}
+
+static int filstat(char *nm, enum token mode)
+{
+ struct stat s;
+ unsigned int i;
+
+ if (mode == FILSYM) {
+#ifdef S_IFLNK
+ if (lstat(nm, &s) == 0) {
+ i = S_IFLNK;
+ goto filetype;
+ }
+#endif
+ return 0;
+ }
+
+ if (stat(nm, &s) != 0)
+ return 0;
+
+ switch (mode) {
+ case FILRD:
+ return test_eaccess(nm, R_OK) == 0;
+ case FILWR:
+ return test_eaccess(nm, W_OK) == 0;
+ case FILEX:
+ return test_eaccess(nm, X_OK) == 0;
+ case FILEXIST:
+ return 1;
+ case FILREG:
+ i = S_IFREG;
+ goto filetype;
+ case FILDIR:
+ i = S_IFDIR;
+ goto filetype;
+ case FILCDEV:
+ i = S_IFCHR;
+ goto filetype;
+ case FILBDEV:
+ i = S_IFBLK;
+ goto filetype;
+ case FILFIFO:
+#ifdef S_IFIFO
+ i = S_IFIFO;
+ goto filetype;
+#else
+ return 0;
+#endif
+ case FILSOCK:
+#ifdef S_IFSOCK
+ i = S_IFSOCK;
+ goto filetype;
+#else
+ return 0;
+#endif
+ case FILSUID:
+ i = S_ISUID;
+ goto filebit;
+ case FILSGID:
+ i = S_ISGID;
+ goto filebit;
+ case FILSTCK:
+ i = S_ISVTX;
+ goto filebit;
+ case FILGZ:
+ return s.st_size > 0L;
+ case FILUID:
+ return s.st_uid == geteuid();
+ case FILGID:
+ return s.st_gid == getegid();
+ default:
+ return 1;
+ }
+
+ filetype:
+ return ((s.st_mode & S_IFMT) == i);
+
+ filebit:
+ return ((s.st_mode & i) != 0);
+}
+
+static enum token t_lex(char *s)
+{
+ struct t_op const *op = ops;
+
+ if (s == 0) {
+ t_wp_op = (struct t_op *) 0;
+ return EOI;
+ }
+ while (op->op_text) {
+ if (strcmp(s, op->op_text) == 0) {
+ t_wp_op = op;
+ return op->op_num;
+ }
+ op++;
+ }
+ t_wp_op = (struct t_op *) 0;
+ return OPERAND;
+}
+
+/* atoi with error detection */
+static arith_t getn(const char *s)
+{
+ char *p;
+#ifdef CONFIG_FEATURE_TEST_64
+ long long r;
+#else
+ long r;
+#endif
+
+ errno = 0;
+#ifdef CONFIG_FEATURE_TEST_64
+ r = strtoll(s, &p, 10);
+#else
+ r = strtol(s, &p, 10);
+#endif
+
+ if (errno != 0)
+ syntax(s, "out of range");
+
+ if (*(skip_whitespace(p)))
+ syntax(s, "bad number");
+
+ return r;
+}
+
+static int newerf(const char *f1, const char *f2)
+{
+ struct stat b1, b2;
+
+ return (stat(f1, &b1) == 0 &&
+ stat(f2, &b2) == 0 && b1.st_mtime > b2.st_mtime);
+}
+
+static int olderf(const char *f1, const char *f2)
+{
+ struct stat b1, b2;
+
+ return (stat(f1, &b1) == 0 &&
+ stat(f2, &b2) == 0 && b1.st_mtime < b2.st_mtime);
+}
+
+static int equalf(const char *f1, const char *f2)
+{
+ struct stat b1, b2;
+
+ return (stat(f1, &b1) == 0 &&
+ stat(f2, &b2) == 0 &&
+ b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino);
+}
+
+/* Do the same thing access(2) does, but use the effective uid and gid,
+ and don't make the mistake of telling root that any file is
+ executable. */
+static int test_eaccess(char *path, int mode)
+{
+ struct stat st;
+ unsigned int euid = geteuid();
+
+ if (stat(path, &st) < 0)
+ return -1;
+
+ if (euid == 0) {
+ /* Root can read or write any file. */
+ if (mode != X_OK)
+ return 0;
+
+ /* Root can execute any file that has any one of the execute
+ bits set. */
+ if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
+ return 0;
+ }
+
+ if (st.st_uid == euid) /* owner */
+ mode <<= 6;
+ else if (is_a_group_member(st.st_gid))
+ mode <<= 3;
+
+ if (st.st_mode & mode)
+ return 0;
+
+ return -1;
+}
+
+static void initialize_group_array(void)
+{
+ ngroups = getgroups(0, NULL);
+ if (ngroups > 0) {
+ group_array = xmalloc(ngroups * sizeof(gid_t));
+ getgroups(ngroups, group_array);
+ }
+}
+
+/* Return non-zero if GID is one that we have in our groups list. */
+static int is_a_group_member(gid_t gid)
+{
+ int i;
+
+ /* Short-circuit if possible, maybe saving a call to getgroups(). */
+ if (gid == getgid() || gid == getegid())
+ return 1;
+
+ if (ngroups == 0)
+ initialize_group_array();
+
+ /* Search through the list looking for GID. */
+ for (i = 0; i < ngroups; i++)
+ if (gid == group_array[i])
+ return 1;
+
+ return 0;
+}
+
+
+/* applet entry point */
+
+int test_main(int argc, char **argv);
+int test_main(int argc, char **argv)
+{
+ return bb_test(argc, argv);
+}
+
diff --git a/i/pc104/initrd/conf/busybox/coreutils/touch.c b/i/pc104/initrd/conf/busybox/coreutils/touch.c
new file mode 100644
index 0000000..ae4e689
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/touch.c
@@ -0,0 +1,62 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini touch implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 _NOT_ compliant -- options -a, -m, -r, -t not supported. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/touch.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Previous version called open() and then utime(). While this will be
+ * be necessary to implement -r and -t, it currently only makes things bigger.
+ * Also, exiting on a failure was a bug. All args should be processed.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <utime.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "busybox.h"
+
+int touch_main(int argc, char **argv);
+int touch_main(int argc, char **argv)
+{
+ int fd;
+ int status = EXIT_SUCCESS;
+ bool flags = (getopt32(argc, argv, "c") & 1);
+
+ argv += optind;
+
+ if (!*argv) {
+ bb_show_usage();
+ }
+
+ do {
+ if (utime(*argv, NULL)) {
+ if (errno == ENOENT) { /* no such file*/
+ if (flags) { /* Creation is disabled, so ignore. */
+ continue;
+ }
+ /* Try to create the file. */
+ fd = open(*argv, O_RDWR | O_CREAT,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
+ );
+ if ((fd >= 0) && !close(fd)) {
+ continue;
+ }
+ }
+ status = EXIT_FAILURE;
+ bb_perror_msg("%s", *argv);
+ }
+ } while (*++argv);
+
+ return status;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/tr.c b/i/pc104/initrd/conf/busybox/coreutils/tr.c
new file mode 100644
index 0000000..cea3b05
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/tr.c
@@ -0,0 +1,254 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini tr implementation for busybox
+ *
+ ** Copyright (c) 1987,1997, Prentice Hall All rights reserved.
+ *
+ * The name of Prentice Hall may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * Copyright (c) Michiel Huisjes
+ *
+ * This version of tr is adapted from Minix tr and was modified
+ * by Erik Andersen <andersen@codepoet.org> to be used in busybox.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+
+// Even with -funsigned-char, gcc still complains about char as an array index.
+
+#define GCC4_IS_STUPID int
+
+#define ASCII 0377
+
+/* some "globals" shared across this file */
+static char com_fl, del_fl, sq_fl;
+/* these last are pointers to static buffers declared in tr_main */
+static char *poutput, *pvector, *pinvec, *poutvec;
+
+static void convert(void)
+{
+ int read_chars = 0, in_index = 0, out_index = 0, c, coded, last = -1;
+
+ for (;;) {
+ // If we're out of input, flush output and read more input.
+
+ if (in_index == read_chars) {
+ if (out_index) {
+ if (write(1, (char *) poutput, out_index) != out_index)
+ bb_error_msg_and_die(bb_msg_write_error);
+ out_index = 0;
+ }
+
+ if ((read_chars = read(0, bb_common_bufsiz1, BUFSIZ)) <= 0) {
+ if (write(1, (char *) poutput, out_index) != out_index)
+ bb_error_msg(bb_msg_write_error);
+ exit(0);
+ }
+ in_index = 0;
+ }
+ c = bb_common_bufsiz1[in_index++];
+ coded = pvector[c];
+ if (del_fl && pinvec[c])
+ continue;
+ if (sq_fl && last == coded && (pinvec[c] || poutvec[coded]))
+ continue;
+ poutput[out_index++] = last = coded;
+ }
+
+ /* NOTREACHED */
+}
+
+static void map(char *string1, unsigned int string1_len,
+ char *string2, unsigned int string2_len)
+{
+ char last = '0';
+ unsigned int i, j;
+
+ for (j = 0, i = 0; i < string1_len; i++) {
+ if (string2_len <= j)
+ pvector[(GCC4_IS_STUPID)string1[i]] = last;
+ else
+ pvector[(GCC4_IS_STUPID)string1[i]] = last = string2[j++];
+ }
+}
+
+/* supported constructs:
+ * Ranges, e.g., [0-9] ==> 0123456789
+ * Escapes, e.g., \a ==> Control-G
+ * Character classes, e.g. [:upper:] ==> A ... Z
+ */
+static unsigned int expand(const char *arg, char *buffer)
+{
+ char *buffer_start = buffer;
+ int i, ac;
+
+ while (*arg) {
+ if (*arg == '\\') {
+ arg++;
+ *buffer++ = bb_process_escape_sequence(&arg);
+ } else if (*(arg+1) == '-') {
+ ac = *(arg+2);
+ if(ac == 0) {
+ *buffer++ = *arg++;
+ continue;
+ }
+ i = *arg;
+ while (i <= ac)
+ *buffer++ = i++;
+ arg += 3; /* Skip the assumed a-z */
+ } else if (*arg == '[') {
+ arg++;
+ i = *arg++;
+ if (ENABLE_FEATURE_TR_CLASSES && i == ':') {
+ if (strncmp(arg, "alpha", 5) == 0) {
+ for (i = 'A'; i <= 'Z'; i++)
+ *buffer++ = i;
+ for (i = 'a'; i <= 'z'; i++)
+ *buffer++ = i;
+ }
+ else if (strncmp(arg, "alnum", 5) == 0) {
+ for (i = '0'; i <= '9'; i++)
+ *buffer++ = i;
+ for (i = 'A'; i <= 'Z'; i++)
+ *buffer++ = i;
+ for (i = 'a'; i <= 'z'; i++)
+ *buffer++ = i;
+ }
+ else if (strncmp(arg, "digit", 5) == 0)
+ for (i = '0'; i <= '9'; i++)
+ *buffer++ = i;
+ else if (strncmp(arg, "lower", 5) == 0)
+ for (i = 'a'; i <= 'z'; i++)
+ *buffer++ = i;
+ else if (strncmp(arg, "upper", 5) == 0)
+ for (i = 'A'; i <= 'Z'; i++)
+ *buffer++ = i;
+ else if (strncmp(arg, "space", 5) == 0) {
+ const char s[] = "\t\n\v\f\r ";
+ strcat((char*)buffer, s);
+ buffer += sizeof(s) - 1;
+ }
+ else if (strncmp(arg, "blank", 5) == 0) {
+ *buffer++ = '\t';
+ *buffer++ = ' ';
+ }
+ /* gcc gives a warning if braces aren't used here */
+ else if (strncmp(arg, "punct", 5) == 0) {
+ for (i = 0; i <= ASCII; i++)
+ if (isprint(i) && (!isalnum(i)) && (!isspace(i)))
+ *buffer++ = i;
+ }
+ else if (strncmp(arg, "cntrl", 5) == 0) {
+ for (i = 0; i <= ASCII; i++)
+ if (iscntrl(i))
+ *buffer++ = i;
+ }
+ else {
+ *buffer++ = '[';
+ *buffer++ = ':';
+ continue;
+ }
+ break;
+ }
+ if (ENABLE_FEATURE_TR_EQUIV && i == '=') {
+ *buffer++ = *arg;
+ /* skip the closing =] */
+ arg += 3;
+ continue;
+ }
+ if (*arg++ != '-') {
+ *buffer++ = '[';
+ arg -= 2;
+ continue;
+ }
+ ac = *arg++;
+ while (i <= ac)
+ *buffer++ = i++;
+ arg++; /* Skip the assumed ']' */
+ } else
+ *buffer++ = *arg++;
+ }
+
+ return (buffer - buffer_start);
+}
+
+static int complement(char *buffer, int buffer_len)
+{
+ short i, j, ix;
+ char conv[ASCII + 2];
+
+ ix = 0;
+ for (i = 0; i <= ASCII; i++) {
+ for (j = 0; j < buffer_len; j++)
+ if (buffer[j] == i)
+ break;
+ if (j == buffer_len)
+ conv[ix++] = i & ASCII;
+ }
+ memcpy(buffer, conv, ix);
+ return ix;
+}
+
+int tr_main(int argc, char **argv);
+int tr_main(int argc, char **argv)
+{
+ unsigned char *ptr;
+ int output_length=0, input_length;
+ int idx = 1;
+ int i;
+ RESERVE_CONFIG_BUFFER(output, BUFSIZ);
+ RESERVE_CONFIG_BUFFER(vector, ASCII+1);
+ RESERVE_CONFIG_BUFFER(invec, ASCII+1);
+ RESERVE_CONFIG_BUFFER(outvec, ASCII+1);
+
+ /* ... but make them available globally */
+ poutput = output;
+ pvector = vector;
+ pinvec = invec;
+ poutvec = outvec;
+
+ if (argc > 1 && argv[idx][0] == '-') {
+ for (ptr = (unsigned char *) &argv[idx][1]; *ptr; ptr++) {
+ switch (*ptr) {
+ case 'c':
+ com_fl = TRUE;
+ break;
+ case 'd':
+ del_fl = TRUE;
+ break;
+ case 's':
+ sq_fl = TRUE;
+ break;
+ default:
+ bb_show_usage();
+ }
+ }
+ idx++;
+ }
+ for (i = 0; i <= ASCII; i++) {
+ vector[i] = i;
+ invec[i] = outvec[i] = FALSE;
+ }
+
+ if (argv[idx] != NULL) {
+ input_length = expand(argv[idx++], bb_common_bufsiz1);
+ if (com_fl)
+ input_length = complement(bb_common_bufsiz1, input_length);
+ if (argv[idx] != NULL) {
+ if (*argv[idx] == '\0')
+ bb_error_msg_and_die("STRING2 cannot be empty");
+ output_length = expand(argv[idx], output);
+ map(bb_common_bufsiz1, input_length, output, output_length);
+ }
+ for (i = 0; i < input_length; i++)
+ invec[(GCC4_IS_STUPID)bb_common_bufsiz1[i]] = TRUE;
+ for (i = 0; i < output_length; i++)
+ outvec[(GCC4_IS_STUPID)output[i]] = TRUE;
+ }
+ convert();
+ return 0;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/true.c b/i/pc104/initrd/conf/busybox/coreutils/true.c
new file mode 100644
index 0000000..b2f3a9b
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/true.c
@@ -0,0 +1,20 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini true implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/true.html */
+
+#include <stdlib.h>
+#include "busybox.h"
+
+int true_main(int argc, char **argv);
+int true_main(int argc, char **argv)
+{
+ return EXIT_SUCCESS;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/tty.c b/i/pc104/initrd/conf/busybox/coreutils/tty.c
new file mode 100644
index 0000000..c28aa33
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/tty.c
@@ -0,0 +1,44 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * tty implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/tty.html */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "busybox.h"
+
+int tty_main(int argc, char **argv);
+int tty_main(int argc, char **argv)
+{
+ const char *s;
+ USE_INCLUDE_SUSv2(int silent;) /* Note: No longer relevant in SUSv3. */
+ int retval;
+
+ xfunc_error_retval = 2; /* SUSv3 requires > 1 for error. */
+
+ USE_INCLUDE_SUSv2(silent = getopt32(argc, argv, "s");)
+
+ /* gnu tty outputs a warning that it is ignoring all args. */
+ bb_warn_ignoring_args(argc - optind);
+
+ retval = 0;
+
+ if ((s = ttyname(0)) == NULL) {
+ /* According to SUSv3, ttyname can on fail with EBADF or ENOTTY.
+ * We know the file descriptor is good, so failure means not a tty. */
+ s = "not a tty";
+ retval = 1;
+ }
+ USE_INCLUDE_SUSv2(if (!silent) puts(s);)
+ SKIP_INCLUDE_SUSv2(puts(s);)
+
+ fflush_stdout_and_exit(retval);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/uname.c b/i/pc104/initrd/conf/busybox/coreutils/uname.c
new file mode 100644
index 0000000..2faa893
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/uname.c
@@ -0,0 +1,108 @@
+/* vi: set sw=4 ts=4: */
+/* uname -- print system information
+ * Copyright (C) 1989-1999 Free Software Foundation, Inc.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/uname.html */
+
+/* Option Example
+
+ -s, --sysname SunOS
+ -n, --nodename rocky8
+ -r, --release 4.0
+ -v, --version
+ -m, --machine sun
+ -a, --all SunOS rocky8 4.0 sun
+
+ The default behavior is equivalent to `-s'.
+
+ David MacKenzie <djm@gnu.ai.mit.edu> */
+
+/* Busyboxed by Erik Andersen */
+
+/* Further size reductions by Glenn McGrath and Manuel Novoa III. */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Now does proper error checking on i/o. Plus some further space savings.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include "busybox.h"
+
+typedef struct {
+ struct utsname name;
+ char processor[8]; /* for "unknown" */
+} uname_info_t;
+
+static const char options[] = "snrvmpa";
+static const unsigned short int utsname_offset[] = {
+ offsetof(uname_info_t,name.sysname),
+ offsetof(uname_info_t,name.nodename),
+ offsetof(uname_info_t,name.release),
+ offsetof(uname_info_t,name.version),
+ offsetof(uname_info_t,name.machine),
+ offsetof(uname_info_t,processor)
+};
+
+int uname_main(int argc, char **argv);
+int uname_main(int argc, char **argv)
+{
+ uname_info_t uname_info;
+#if defined(__sparc__) && defined(__linux__)
+ char *fake_sparc = getenv("FAKE_SPARC");
+#endif
+ const unsigned short int *delta;
+ char toprint;
+
+ toprint = getopt32(argc, argv, options);
+
+ if (argc != optind) {
+ bb_show_usage();
+ }
+
+ if (toprint & (1 << 6)) {
+ toprint = 0x3f;
+ }
+
+ if (toprint == 0) {
+ toprint = 1; /* sysname */
+ }
+
+ if (uname(&uname_info.name) == -1) {
+ bb_error_msg_and_die("cannot get system name");
+ }
+
+#if defined(__sparc__) && defined(__linux__)
+ if ((fake_sparc != NULL)
+ && ((fake_sparc[0] == 'y')
+ || (fake_sparc[0] == 'Y'))) {
+ strcpy(uname_info.name.machine, "sparc");
+ }
+#endif
+
+ strcpy(uname_info.processor, "unknown");
+
+ delta = utsname_offset;
+ do {
+ if (toprint & 1) {
+ printf(((char *)(&uname_info)) + *delta);
+ if (toprint > 1) {
+ putchar(' ');
+ }
+ }
+ ++delta;
+ } while (toprint >>= 1);
+ putchar('\n');
+
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/uniq.c b/i/pc104/initrd/conf/busybox/coreutils/uniq.c
new file mode 100644
index 0000000..0cc0c83
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/uniq.c
@@ -0,0 +1,104 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * uniq implementation for busybox
+ *
+ * Copyright (C) 2005 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+ */
+
+/* BB_AUDIT SUSv3 compliant */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/uniq.html */
+
+#include "busybox.h"
+
+static const char uniq_opts[] = "f:s:" "cdu\0\1\2\4";
+
+static FILE *xgetoptfile_uniq_s(char **argv, int read0write2)
+{
+ const char *n;
+
+ if ((n = *argv) != NULL) {
+ if ((*n != '-') || n[1]) {
+ return xfopen(n, "r\0w" + read0write2);
+ }
+ }
+ return (read0write2) ? stdout : stdin;
+}
+
+int uniq_main(int argc, char **argv);
+int uniq_main(int argc, char **argv)
+{
+ FILE *in, *out;
+ unsigned long dups, skip_fields, skip_chars, i, uniq_flags;
+ const char *s0, *e0, *s1, *e1, *input_filename;
+ int opt;
+
+ uniq_flags = skip_fields = skip_chars = 0;
+
+ while ((opt = getopt(argc, argv, uniq_opts)) > 0) {
+ if ((opt == 'f') || (opt == 's')) {
+ unsigned long t = xatoul(optarg);
+ if (opt == 'f') {
+ skip_fields = t;
+ } else {
+ skip_chars = t;
+ }
+ } else if ((s0 = strchr(uniq_opts, opt)) != NULL) {
+ uniq_flags |= s0[4];
+ } else {
+ bb_show_usage();
+ }
+ }
+
+ input_filename = *(argv += optind);
+
+ in = xgetoptfile_uniq_s(argv, 0);
+ if (*argv) {
+ ++argv;
+ }
+ out = xgetoptfile_uniq_s(argv, 2);
+ if (*argv && argv[1]) {
+ bb_show_usage();
+ }
+
+ s1 = e1 = NULL; /* prime the pump */
+
+ do {
+ s0 = s1;
+ e0 = e1;
+ dups = 0;
+
+ /* gnu uniq ignores newlines */
+ while ((s1 = xmalloc_getline(in)) != NULL) {
+ e1 = s1;
+ for (i = skip_fields; i; i--) {
+ e1 = skip_whitespace(e1);
+ while (*e1 && !isspace(*e1)) {
+ ++e1;
+ }
+ }
+ for (i = skip_chars; *e1 && i; i--) {
+ ++e1;
+ }
+
+ if (!s0 || strcmp(e0, e1)) {
+ break;
+ }
+
+ ++dups; /* Note: Testing for overflow seems excessive. */
+ }
+
+ if (s0) {
+ if (!(uniq_flags & (2 << !!dups))) {
+ fprintf(out, "\0%d " + (uniq_flags & 1), dups + 1);
+ fprintf(out, "%s\n", s0);
+ }
+ free((void *)s0);
+ }
+ } while (s1);
+
+ die_if_ferror(in, input_filename);
+
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/usleep.c b/i/pc104/initrd/conf/busybox/coreutils/usleep.c
new file mode 100644
index 0000000..7dd9146
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/usleep.c
@@ -0,0 +1,29 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * usleep implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 N/A -- Apparently a busybox extension. */
+
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+#include "busybox.h"
+
+int usleep_main(int argc, char **argv);
+int usleep_main(int argc, char **argv)
+{
+ if (argc != 2) {
+ bb_show_usage();
+ }
+
+ if (usleep(xatou(argv[1]))) {
+ bb_perror_nomsg_and_die();
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/uudecode.c b/i/pc104/initrd/conf/busybox/coreutils/uudecode.c
new file mode 100644
index 0000000..c195a3e
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/uudecode.c
@@ -0,0 +1,181 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Copyright 2003, Glenn McGrath <bug1@iinet.net.au>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ * Based on specification from
+ * http://www.opengroup.org/onlinepubs/007904975/utilities/uuencode.html
+ *
+ * Bugs: the spec doesn't mention anything about "`\n`\n" prior to the
+ * "end" line
+ */
+
+
+#include "busybox.h"
+
+static void read_stduu(FILE *src_stream, FILE *dst_stream)
+{
+ char *line;
+
+ while ((line = xmalloc_getline(src_stream)) != NULL) {
+ int length;
+ char *line_ptr = line;
+
+ if (strcmp(line, "end") == 0) {
+ return;
+ }
+ length = ((*line_ptr - 0x20) & 0x3f)* 4 / 3;
+
+ if (length <= 0) {
+ /* Ignore the "`\n" line, why is it even in the encode file ? */
+ continue;
+ }
+ if (length > 60) {
+ bb_error_msg_and_die("line too long");
+ }
+
+ line_ptr++;
+ /* Tolerate an overly long line to accomodate a possible exta '`' */
+ if (strlen(line_ptr) < (size_t)length) {
+ bb_error_msg_and_die("short file");
+ }
+
+ while (length > 0) {
+ /* Merge four 6 bit chars to three 8 bit chars */
+ fputc(((line_ptr[0] - 0x20) & 077) << 2 | ((line_ptr[1] - 0x20) & 077) >> 4, dst_stream);
+ line_ptr++;
+ length--;
+ if (length == 0) {
+ break;
+ }
+
+ fputc(((line_ptr[0] - 0x20) & 077) << 4 | ((line_ptr[1] - 0x20) & 077) >> 2, dst_stream);
+ line_ptr++;
+ length--;
+ if (length == 0) {
+ break;
+ }
+
+ fputc(((line_ptr[0] - 0x20) & 077) << 6 | ((line_ptr[1] - 0x20) & 077), dst_stream);
+ line_ptr += 2;
+ length -= 2;
+ }
+ free(line);
+ }
+ bb_error_msg_and_die("short file");
+}
+
+static void read_base64(FILE *src_stream, FILE *dst_stream)
+{
+ static const char base64_table[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n";
+ int term_count = 0;
+
+ while (1) {
+ char translated[4];
+ int count = 0;
+
+ while (count < 4) {
+ char *table_ptr;
+ int ch;
+
+ /* Get next _valid_ character */
+ do {
+ ch = fgetc(src_stream);
+ if (ch == EOF) {
+ bb_error_msg_and_die("short file");
+ }
+ } while ((table_ptr = strchr(base64_table, ch)) == NULL);
+
+ /* Convert encoded charcter to decimal */
+ ch = table_ptr - base64_table;
+
+ if (*table_ptr == '=') {
+ if (term_count == 0) {
+ translated[count] = 0;
+ break;
+ }
+ term_count++;
+ }
+ else if (*table_ptr == '\n') {
+ /* Check for terminating line */
+ if (term_count == 5) {
+ return;
+ }
+ term_count = 1;
+ continue;
+ } else {
+ translated[count] = ch;
+ count++;
+ term_count = 0;
+ }
+ }
+
+ /* Merge 6 bit chars to 8 bit */
+ fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
+ if (count > 2) {
+ fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
+ }
+ if (count > 3) {
+ fputc(translated[2] << 6 | translated[3], dst_stream);
+ }
+ }
+}
+
+int uudecode_main(int argc, char **argv);
+int uudecode_main(int argc, char **argv)
+{
+ FILE *src_stream;
+ char *outname = NULL;
+ char *line;
+
+ getopt32(argc, argv, "o:", &outname);
+
+ if (optind == argc) {
+ src_stream = stdin;
+ } else if (optind + 1 == argc) {
+ src_stream = xfopen(argv[optind], "r");
+ } else {
+ bb_show_usage();
+ }
+
+ /* Search for the start of the encoding */
+ while ((line = xmalloc_getline(src_stream)) != NULL) {
+ void (*decode_fn_ptr)(FILE * src, FILE * dst);
+ char *line_ptr;
+ FILE *dst_stream;
+ int mode;
+
+ if (strncmp(line, "begin-base64 ", 13) == 0) {
+ line_ptr = line + 13;
+ decode_fn_ptr = read_base64;
+ } else if (strncmp(line, "begin ", 6) == 0) {
+ line_ptr = line + 6;
+ decode_fn_ptr = read_stduu;
+ } else {
+ free(line);
+ continue;
+ }
+
+ mode = strtoul(line_ptr, NULL, 8);
+ if (outname == NULL) {
+ outname = strchr(line_ptr, ' ');
+ if ((outname == NULL) || (*outname == '\0')) {
+ break;
+ }
+ outname++;
+ }
+ if (LONE_DASH(outname)) {
+ dst_stream = stdout;
+ } else {
+ dst_stream = xfopen(outname, "w");
+ chmod(outname, mode & (S_IRWXU | S_IRWXG | S_IRWXO));
+ }
+ free(line);
+ decode_fn_ptr(src_stream, dst_stream);
+ fclose_if_not_stdin(src_stream);
+ return EXIT_SUCCESS;
+ }
+ bb_error_msg_and_die("no 'begin' line");
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/uuencode.c b/i/pc104/initrd/conf/busybox/coreutils/uuencode.c
new file mode 100644
index 0000000..3207d72
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/uuencode.c
@@ -0,0 +1,76 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Copyright (C) 2000 by Glenn McGrath
+ *
+ * based on the function base64_encode from http.c in wget v1.6
+ * Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+
+
+#define SRC_BUF_SIZE 45 // This *MUST* be a multiple of 3
+#define DST_BUF_SIZE 4 * ((SRC_BUF_SIZE + 2) / 3)
+int uuencode_main(int argc, char **argv);
+int uuencode_main(int argc, char **argv)
+{
+ const size_t src_buf_size = SRC_BUF_SIZE;
+ const size_t dst_buf_size = DST_BUF_SIZE;
+ size_t write_size = dst_buf_size;
+ struct stat stat_buf;
+ FILE *src_stream = stdin;
+ const char *tbl;
+ size_t size;
+ mode_t mode;
+ RESERVE_CONFIG_BUFFER(src_buf, SRC_BUF_SIZE + 1);
+ RESERVE_CONFIG_BUFFER(dst_buf, DST_BUF_SIZE + 1);
+
+ tbl = bb_uuenc_tbl_std;
+ if (getopt32(argc, argv, "m") & 1) {
+ tbl = bb_uuenc_tbl_base64;
+ }
+
+ switch (argc - optind) {
+ case 2:
+ src_stream = xfopen(argv[optind], "r");
+ xstat(argv[optind], &stat_buf);
+ mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+ if (src_stream == stdout) {
+ puts("NULL");
+ }
+ break;
+ case 1:
+ mode = 0666 & ~umask(0666);
+ break;
+ default:
+ bb_show_usage();
+ }
+
+ printf("begin%s %o %s", tbl == bb_uuenc_tbl_std ? "" : "-base64", mode, argv[argc - 1]);
+
+ while ((size = fread(src_buf, 1, src_buf_size, src_stream)) > 0) {
+ if (size != src_buf_size) {
+ /* write_size is always 60 until the last line */
+ write_size = (4 * ((size + 2) / 3));
+ /* pad with 0s so we can just encode extra bits */
+ memset(&src_buf[size], 0, src_buf_size - size);
+ }
+ /* Encode the buffer we just read in */
+ bb_uuencode((unsigned char*)src_buf, dst_buf, size, tbl);
+
+ putchar('\n');
+ if (tbl == bb_uuenc_tbl_std) {
+ putchar(tbl[size]);
+ }
+ if (fwrite(dst_buf, 1, write_size, stdout) != write_size) {
+ bb_perror_msg_and_die(bb_msg_write_error);
+ }
+ }
+ printf(tbl == bb_uuenc_tbl_std ? "\n`\nend\n" : "\n====\n");
+
+ die_if_ferror(src_stream, "source"); /* TODO - Fix this! */
+
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/watch.c b/i/pc104/initrd/conf/busybox/coreutils/watch.c
new file mode 100644
index 0000000..60a4a71
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/watch.c
@@ -0,0 +1,80 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini watch implementation for busybox
+ *
+ * Copyright (C) 2001 by Michael Habermann <mhabermann@gmx.de>
+ * Copyrigjt (C) Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 N/A */
+/* BB_AUDIT GNU defects -- only option -n is supported. */
+
+#include "busybox.h"
+
+// procps 2.0.18:
+// watch [-d] [-n seconds]
+// [--differences[=cumulative]] [--interval=seconds] command
+//
+// procps-3.2.3:
+// watch [-dt] [-n seconds]
+// [--differences[=cumulative]] [--interval=seconds] [--no-title] command
+//
+// (procps 3.x and procps 2.x are forks, not newer/older versions of the same)
+
+int watch_main(int argc, char **argv);
+int watch_main(int argc, char **argv)
+{
+ unsigned opt;
+ unsigned period = 2;
+ unsigned cmdlen = 1; // 1 for terminal NUL
+ char *header = NULL;
+ char *cmd;
+ char *tmp;
+ char **p;
+
+ opt_complementary = "-1"; // at least one param please
+ opt = getopt32(argc, argv, "+dtn:", &tmp);
+ //if (opt & 0x1) // -d (ignore)
+ //if (opt & 0x2) // -t
+ if (opt & 0x4) period = xatou(tmp);
+ argv += optind;
+
+ p = argv;
+ while (*p)
+ cmdlen += strlen(*p++) + 1;
+ tmp = cmd = xmalloc(cmdlen);
+ while (*argv) {
+ tmp += sprintf(tmp, " %s", *argv);
+ argv++;
+ }
+ cmd++; // skip initial space
+
+ while (1) {
+ printf("\033[H\033[J");
+ if (!(opt & 0x2)) { // no -t
+ int width, len;
+ char *thyme;
+ time_t t;
+
+ get_terminal_width_height(STDOUT_FILENO, &width, 0);
+ header = xrealloc(header, width--);
+ // '%-*s' pads header with spaces to the full width
+ snprintf(header, width, "Every %ds: %-*s", period, width, cmd);
+ time(&t);
+ thyme = ctime(&t);
+ len = strlen(thyme);
+ if (len < width)
+ strcpy(header + width - len, thyme);
+ puts(header);
+ }
+ fflush(stdout);
+ // TODO: 'real' watch pipes cmd's output to itself
+ // and does not allow it to overflow the screen
+ // (taking into account linewrap!)
+ system(cmd);
+ sleep(period);
+ }
+ return 0; // gcc thinks we can reach this :)
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/wc.c b/i/pc104/initrd/conf/busybox/coreutils/wc.c
new file mode 100644
index 0000000..926b3ac
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/wc.c
@@ -0,0 +1,205 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * wc implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 _NOT_ compliant -- option -m is not currently supported. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/wc.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Rewritten to fix a number of problems and do some size optimizations.
+ * Problems in the previous busybox implementation (besides bloat) included:
+ * 1) broken 'wc -c' optimization (read note below)
+ * 2) broken handling of '-' args
+ * 3) no checking of ferror on EOF returns
+ * 4) isprint() wasn't considered when word counting.
+ *
+ * TODO:
+ *
+ * When locale support is enabled, count multibyte chars in the '-m' case.
+ *
+ * NOTES:
+ *
+ * The previous busybox wc attempted an optimization using stat for the
+ * case of counting chars only. I omitted that because it was broken.
+ * It didn't take into account the possibility of input coming from a
+ * pipe, or input from a file with file pointer not at the beginning.
+ *
+ * To implement such a speed optimization correctly, not only do you
+ * need the size, but also the file position. Note also that the
+ * file position may be past the end of file. Consider the example
+ * (adapted from example in gnu wc.c)
+ *
+ * echo hello > /tmp/testfile &&
+ * (dd ibs=1k skip=1 count=0 &> /dev/null ; wc -c) < /tmp/testfile
+ *
+ * for which 'wc -c' should output '0'.
+ */
+
+#include "busybox.h"
+
+#ifdef CONFIG_LOCALE_SUPPORT
+#define isspace_given_isprint(c) isspace(c)
+#else
+#undef isspace
+#undef isprint
+#define isspace(c) ((((c) == ' ') || (((unsigned int)((c) - 9)) <= (13 - 9))))
+#define isprint(c) (((unsigned int)((c) - 0x20)) <= (0x7e - 0x20))
+#define isspace_given_isprint(c) ((c) == ' ')
+#endif
+
+#if ENABLE_FEATURE_WC_LARGE
+#define COUNT_T unsigned long long
+#define COUNT_FMT "llu"
+#else
+#define COUNT_T unsigned
+#define COUNT_FMT "u"
+#endif
+
+enum {
+ WC_LINES = 0,
+ WC_WORDS = 1,
+ WC_CHARS = 2,
+ WC_LENGTH = 3
+};
+
+int wc_main(int argc, char **argv);
+int wc_main(int argc, char **argv)
+{
+ FILE *fp;
+ const char *s, *arg;
+ const char *start_fmt = "%9"COUNT_FMT;
+ const char *fname_fmt = " %s\n";
+ COUNT_T *pcounts;
+ COUNT_T counts[4];
+ COUNT_T totals[4];
+ unsigned linepos;
+ unsigned u;
+ int num_files = 0;
+ int c;
+ smallint status = EXIT_SUCCESS;
+ smallint in_word;
+ unsigned print_type;
+
+ print_type = getopt32(argc, argv, "lwcL");
+
+ if (print_type == 0) {
+ print_type = (1 << WC_LINES) | (1 << WC_WORDS) | (1 << WC_CHARS);
+ }
+
+ argv += optind;
+ if (!argv[0]) {
+ *--argv = (char *) bb_msg_standard_input;
+ fname_fmt = "\n";
+ if (!((print_type-1) & print_type)) /* exactly one option? */
+ start_fmt = "%"COUNT_FMT;
+ }
+
+ memset(totals, 0, sizeof(totals));
+
+ pcounts = counts;
+
+ while ((arg = *argv++) != 0) {
+ ++num_files;
+ fp = fopen_or_warn_stdin(arg);
+ if (!fp) {
+ status = EXIT_FAILURE;
+ continue;
+ }
+
+ memset(counts, 0, sizeof(counts));
+ linepos = 0;
+ in_word = 0;
+
+ do {
+ /* Our -w doesn't match GNU wc exactly... oh well */
+
+ ++counts[WC_CHARS];
+ c = getc(fp);
+ if (isprint(c)) {
+ ++linepos;
+ if (!isspace_given_isprint(c)) {
+ in_word = 1;
+ continue;
+ }
+ } else if (((unsigned int)(c - 9)) <= 4) {
+ /* \t 9
+ * \n 10
+ * \v 11
+ * \f 12
+ * \r 13
+ */
+ if (c == '\t') {
+ linepos = (linepos | 7) + 1;
+ } else { /* '\n', '\r', '\f', or '\v' */
+ DO_EOF:
+ if (linepos > counts[WC_LENGTH]) {
+ counts[WC_LENGTH] = linepos;
+ }
+ if (c == '\n') {
+ ++counts[WC_LINES];
+ }
+ if (c != '\v') {
+ linepos = 0;
+ }
+ }
+ } else if (c == EOF) {
+ if (ferror(fp)) {
+ bb_perror_msg("%s", arg);
+ status = EXIT_FAILURE;
+ }
+ --counts[WC_CHARS];
+ goto DO_EOF; /* Treat an EOF as '\r'. */
+ } else {
+ continue;
+ }
+
+ counts[WC_WORDS] += in_word;
+ in_word = 0;
+ if (c == EOF) {
+ break;
+ }
+ } while (1);
+
+ if (totals[WC_LENGTH] < counts[WC_LENGTH]) {
+ totals[WC_LENGTH] = counts[WC_LENGTH];
+ }
+ totals[WC_LENGTH] -= counts[WC_LENGTH];
+
+ fclose_if_not_stdin(fp);
+
+ OUTPUT:
+ /* coreutils wc tries hard to print pretty columns
+ * (saves results for all files, find max col len etc...)
+ * we won't try that hard, it will bloat us too much */
+ s = start_fmt;
+ u = 0;
+ do {
+ if (print_type & (1 << u)) {
+ printf(s, pcounts[u]);
+ s = " %9"COUNT_FMT; /* Ok... restore the leading space. */
+ }
+ totals[u] += pcounts[u];
+ } while (++u < 4);
+ printf(fname_fmt, arg);
+ }
+
+ /* If more than one file was processed, we want the totals. To save some
+ * space, we set the pcounts ptr to the totals array. This has the side
+ * effect of trashing the totals array after outputting it, but that's
+ * irrelavent since we no longer need it. */
+ if (num_files > 1) {
+ num_files = 0; /* Make sure we don't get here again. */
+ arg = "total";
+ pcounts = totals;
+ --argv;
+ goto OUTPUT;
+ }
+
+ fflush_stdout_and_exit(status);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/who.c b/i/pc104/initrd/conf/busybox/coreutils/who.c
new file mode 100644
index 0000000..a5d3b02
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/who.c
@@ -0,0 +1,76 @@
+/* vi: set sw=4 ts=4: */
+/*----------------------------------------------------------------------
+ * Mini who is used to display user name, login time,
+ * idle time and host name.
+ *
+ * Author: Da Chen <dchen@ayrnetworks.com>
+ *
+ * This is a free document; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation:
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Copyright (c) 2002 AYR Networks, Inc.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#include "busybox.h"
+#include <utmp.h>
+#include <time.h>
+
+static void idle_string(char *str6, time_t t)
+{
+ t = time(NULL) - t;
+
+ /*if (t < 60) {
+ str6[0] = '.';
+ str6[1] = '\0';
+ return;
+ }*/
+ if (t >= 0 && t < (24 * 60 * 60)) {
+ sprintf(str6, "%02d:%02d",
+ (int) (t / (60 * 60)),
+ (int) ((t % (60 * 60)) / 60));
+ return;
+ }
+ strcpy(str6, "old");
+}
+
+int who_main(int argc, char **argv);
+int who_main(int argc, char **argv)
+{
+ char str6[6];
+ struct utmp *ut;
+ struct stat st;
+ char *name;
+
+ if (argc > 1) {
+ bb_show_usage();
+ }
+
+ setutent();
+ printf("USER TTY IDLE TIME HOST\n");
+ while ((ut = getutent()) != NULL) {
+ if (ut->ut_user[0] && ut->ut_type == USER_PROCESS) {
+ time_t thyme = ut->ut_tv.tv_sec;
+
+ /* ut->ut_line is device name of tty - "/dev/" */
+ name = concat_path_file("/dev", ut->ut_line);
+ str6[0] = '?';
+ str6[1] = '\0';
+ if (stat(name, &st) == 0)
+ idle_string(str6, st.st_atime);
+ printf("%-10s %-8s %-9s %-14.14s %s\n",
+ ut->ut_user, ut->ut_line, str6,
+ ctime(&thyme) + 4, ut->ut_host);
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(name);
+ }
+ }
+ if (ENABLE_FEATURE_CLEAN_UP)
+ endutent();
+ return 0;
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/whoami.c b/i/pc104/initrd/conf/busybox/coreutils/whoami.c
new file mode 100644
index 0000000..3185817
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/whoami.c
@@ -0,0 +1,26 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini whoami implementation for busybox
+ *
+ * Copyright (C) 2000 Edward Betts <edward@debian.org>.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "busybox.h"
+
+int whoami_main(int argc, char **argv);
+int whoami_main(int argc, char **argv)
+{
+ if (argc > 1)
+ bb_show_usage();
+
+ puts(bb_getpwuid(NULL, geteuid(), -1));
+ /* exits on error */
+ fflush_stdout_and_exit(EXIT_SUCCESS);
+}
diff --git a/i/pc104/initrd/conf/busybox/coreutils/yes.c b/i/pc104/initrd/conf/busybox/coreutils/yes.c
new file mode 100644
index 0000000..2611c3e
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/coreutils/yes.c
@@ -0,0 +1,42 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * yes implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Size reductions and removed redundant applet name prefix from error messages.
+ */
+
+#include "busybox.h"
+
+int yes_main(int argc, char **argv);
+int yes_main(int argc, char **argv)
+{
+ static const char fmt_str[] = " %s";
+ const char *fmt;
+ char **first_arg;
+
+ *argv = (char*)"y";
+ if (argc != 1) {
+ ++argv;
+ }
+
+ first_arg = argv;
+ do {
+ fmt = fmt_str + 1;
+ do {
+ printf(fmt, *argv);
+ fmt = fmt_str;
+ } while (*++argv);
+ argv = first_arg;
+ } while (putchar('\n') != EOF);
+
+ bb_perror_nomsg_and_die();
+}