Clone the busybox_0_60_stable branch from the old busybox.stable CVS tree
|
@ -8,14 +8,14 @@ incorect, _please_ let me know.
|
|||
|
||||
-----------
|
||||
|
||||
Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
|
||||
Erik Andersen <andersen@codepoet.org>, <andersee@debian.org>
|
||||
Tons of new stuff, major rewrite of most of the
|
||||
core apps, tons of new apps as noted in header files.
|
||||
|
||||
Edward Betts <edward@debian.org>
|
||||
expr, hostid, logname, tty, wc, whoami, yes
|
||||
|
||||
John Beppu <beppu@lineo.com>
|
||||
John Beppu <beppu@codepoet.org>
|
||||
du, head, nslookup, sort, tee, uniq
|
||||
|
||||
Brian Candler <B.Candler@pobox.com>
|
||||
|
@ -28,9 +28,17 @@ Dave Cinege <dcinege@psychosis.com>
|
|||
more(v2), makedevs, dutmp, modularization, auto links file,
|
||||
various fixes, Linux Router Project maintenance
|
||||
|
||||
Magnus Damm <damm@opensource.se>
|
||||
tftp client
|
||||
insmod powerpc support
|
||||
|
||||
Larry Doolittle <ldoolitt@recycle.lbl.gov>
|
||||
pristine source directory compilation, lots of patches and fixes.
|
||||
|
||||
Gennady Feldman <gfeldman@cachier.com>
|
||||
Sysklogd (single threaded syslogd, IPC Circular buffer support,
|
||||
logread), various fixes.
|
||||
|
||||
Karl M. Hegbloom <karlheg@debian.org>
|
||||
cp_mv.c, the test suite, various fixes to utility.c, &c.
|
||||
|
||||
|
@ -38,7 +46,7 @@ Daniel Jacobowitz <dan@debian.org>
|
|||
mktemp.c
|
||||
|
||||
Matt Kraai <kraai@alumni.carnegiemellon.edu>
|
||||
documentation, bugfixes
|
||||
documentation, bugfixes, test suite
|
||||
|
||||
John Lombardo <john@deltanet.com>
|
||||
dirname, tr
|
||||
|
@ -46,9 +54,16 @@ John Lombardo <john@deltanet.com>
|
|||
Glenn McGrath <bug1@optushome.com.au>
|
||||
ar, dpkg, dpkg-deb
|
||||
|
||||
Vladimir Oleynik <dzo@simtreas.ru>
|
||||
cmdedit; ports: ash, stty, traceroute; locale, various fixes
|
||||
and irreconcilable critic of everything not perfect.
|
||||
|
||||
Bruce Perens <bruce@pixar.com>
|
||||
Original author of BusyBox. His code is still in many apps.
|
||||
|
||||
Tim Riker <Tim@Rikers.org>
|
||||
bug fixes, member of fan club
|
||||
|
||||
Kent Robotti <robotti@metconnect.com>
|
||||
reset, tons and tons of bug reports and patchs.
|
||||
|
||||
|
@ -64,7 +79,7 @@ Gyepi Sam <gyepi@praxis-sw.com>
|
|||
Linus Torvalds <torvalds@transmeta.com>
|
||||
mkswap, fsck.minix, mkfs.minix
|
||||
|
||||
Mark Whitley <markw@lineo.com> <markw@codepoet.org>
|
||||
Mark Whitley <markw@codepoet.org>
|
||||
grep, sed, cut, xargs, style-guide, new-applet-HOWTO, bug fixes, etc.
|
||||
|
||||
Charles P. Wright <cpwright@villagenet.com>
|
||||
|
@ -73,9 +88,6 @@ Charles P. Wright <cpwright@villagenet.com>
|
|||
Enrique Zanardi <ezanardi@ull.es>
|
||||
tarcat (since removed), loadkmap, various fixes, Debian maintenance
|
||||
|
||||
Vladimir Oleynik <dzo@simtreas.ru>
|
||||
cmdedit; ports: ash, stty, traceroute; locale, various fixes
|
||||
and irreconcilable critic of everything not perfect.
|
||||
Emanuele Aina <emanuele.aina@tiscali.it>
|
||||
run-parts
|
||||
|
||||
Tim Riker <Tim@Rikers.org>
|
||||
bug fixes, member of fan club
|
|
@ -1,18 +1,198 @@
|
|||
0.60.2.pre
|
||||
0.60.5
|
||||
|
||||
Stable Release
|
||||
|
||||
Bugfixes:
|
||||
* Fixed a race that could cause init to hang
|
||||
* Fixed init orphan process reaping
|
||||
* Fixed init to always attempt to provide a controlling tty.
|
||||
This should fix most cases where ash would print
|
||||
"job control disabled" -- the other cases are user error.
|
||||
* Fixed 'gunzip -c' to not delete the source source file
|
||||
* Fixed a silly math problem in the time applet
|
||||
* Fixed 'cp -a' so it will once again copy symlinks properly
|
||||
* Fixed a long standing problem in tftp with freeing memory
|
||||
* Fixed Makefile largefile settings
|
||||
* Fixed a buffer overflow in vi
|
||||
* Cosmetic cleanups in lsmod, lash, init, swapon/off, and hostname
|
||||
* Set the close-on-exec flag on files opened by init
|
||||
* The updated top applet was backported from unstable
|
||||
* Several ash bugfixes were backported from unstable
|
||||
* Several warnings in ash, md5sum, and ifconfig
|
||||
|
||||
-Erik Andersen, 26 October 2002
|
||||
|
||||
|
||||
|
||||
0.60.4
|
||||
|
||||
Stable Release
|
||||
|
||||
New Applets & New Features:
|
||||
none. :)
|
||||
|
||||
Known Problems (to be fixed in 0.60.2)
|
||||
* msh can segfault on constructs such as
|
||||
for i in `ls *.c` ; do echo $i ; done
|
||||
due to a memory allocation problem. This only seems to cause
|
||||
problems when the backtick expands to be several k in size.
|
||||
* Added new a 'top' applet (by special request)
|
||||
* Lots of small uClinux adjustments
|
||||
|
||||
Bugfixes:
|
||||
* This release has _lots_ of bugfixes. See Changelog.full
|
||||
for the complete list of what was changed.
|
||||
|
||||
-Erik Andersen, 18 September 2002
|
||||
|
||||
|
||||
|
||||
0.60.3
|
||||
|
||||
Stable Release
|
||||
|
||||
New Applets & New Features:
|
||||
* Added new a 'time' applet (by special request)
|
||||
* Added new a 'losetup' applet
|
||||
* The tftp has been fixed to work
|
||||
* Default shell is now ash.
|
||||
* msh shell should work properly on mmu-less systems again
|
||||
* ls can now do color
|
||||
|
||||
Bugfixes:
|
||||
* Erik Andersen
|
||||
-- Hacked together a new time applet
|
||||
-- Fixed dangling comma in init.c (s390 arch only)
|
||||
-- Fixed more so when it is run on files in the procfs that
|
||||
claim 0 length, it will not do weird things i.e. more /proc/pci
|
||||
-- Copyright message cleanups. Fixed sash attributions.
|
||||
-- Backporting of fixes and general maintenance.
|
||||
-- Fixed several cases where reboot, halt, and poweroff would fail
|
||||
to function properly when Linux is booted into an initrd.
|
||||
-- Fixed a silly compile bug in cpio
|
||||
-- nslookup now works properly with uClibc, remove old workaround
|
||||
-- Added conv=noerror support to dd
|
||||
-- Fixed ash and msh cmdedit to properly account for the current
|
||||
PATH setting
|
||||
-- Document netcat options and add -e support
|
||||
-- Fixed insanely broken insmod endianness handling
|
||||
-- Update init.c for better syle conformance, properly detach from
|
||||
terminal when necessary, better code reuse, FIFO inittab file
|
||||
reading/executing, allow init to be halted and restarted, etc.
|
||||
-- Allow gunzip to work on multiple archives, add -v option
|
||||
-- Updated x86 optimizations to save over 10k.
|
||||
* Edward Betts
|
||||
-- added -x switch to du.c
|
||||
* Cliff L. Biffle
|
||||
-- Added memory usage to the ps listings
|
||||
* Przemyslaw Czerpak
|
||||
-- Made telnet 8-bit clean, handle screen size, and is now RFC
|
||||
compliant. Works nicely now.
|
||||
* Wolfgang Denk
|
||||
-- hush now supports shell loops (for, while, until) and control
|
||||
operators (||, &&)
|
||||
* Russ Dill
|
||||
-- Added an 'restart' inittab action, allowing init to re-exec
|
||||
itself (or call a script which calls pivot_root then exec...)
|
||||
* Larry Doolittle
|
||||
-- Made syslogd not give up when errno is EINTR
|
||||
* Geoffrey Espin
|
||||
-- support find -newer <file>
|
||||
* Robert Griebl
|
||||
-- Reworked modprobe so it now reads and uses modules.dep
|
||||
* Karl M. Hegbloom
|
||||
-- Fixed a silly bug where CONTEXT and EGREP_ALIAS were coupled.
|
||||
* Kevin Hilman
|
||||
-- Fixed memory corruption from long pathnames in /etc/fstab
|
||||
* J.W.Janssen
|
||||
-- color ls support!
|
||||
* Matt Kraai
|
||||
-- Fixed get_line_from_file() so that NULL is treated as end of
|
||||
line, thereby fixing cut, grep, sed, etc. when working on binary
|
||||
files or anything that might contain a NULL.
|
||||
-- Fixed wget to do DNS initial DNS lookups, and do that only once
|
||||
to avoid skipping to a different server when round-robin DNS is
|
||||
in use (bug found by Mike Coleman <mkc@mathdogs.com>)
|
||||
-- Several sed fixes
|
||||
-- Added new losetup applet
|
||||
* Ben Low
|
||||
-- allow tftp to work with stdin as well as stdout.
|
||||
* Frank P. MacLachlan <fpm-plutus@tgs.indyme.com> avoid a potential
|
||||
NULL pointer problem in mount.
|
||||
* Glenn McGrath
|
||||
-- gunzip was incorrectly reporting a failed crc and length
|
||||
(Discovered by Change, Shu-Hao). The problem was the bitbuffer
|
||||
needs to be unwound after decompression as it was eating into the
|
||||
crc/size field.
|
||||
-- Reworked wc.c to fix severe efficiency problems and make it
|
||||
smaller. When just counting file chars, simply stat the file
|
||||
instead of reading the whole thing. (Fixes Debian bug #103302)
|
||||
-- Updated dmalloc options
|
||||
* Manuel Novoa III
|
||||
-- rewrote get_last_path_component() so it would not be so
|
||||
horrible, and would behave correctly in several important corner
|
||||
cases.
|
||||
* Vladimir Oleynik
|
||||
-- Fixed ash problem where ^C could be blocked
|
||||
-- Several command line editing updates (cmdedit now supports
|
||||
CTRL-K and CTRL-L, fixed a segfault, etc)
|
||||
-- Fixed ash problem where ^C could be blocked
|
||||
-- Several size optimizations for various applets
|
||||
* Tim Riker
|
||||
-- make ash prompt the same as other shells if cmdedit and
|
||||
fancyprompt are enabled.
|
||||
* Jeff Studer
|
||||
-- tftp now generates default values for localfilename and
|
||||
remotefilename based on provided file names when possible.
|
||||
* Stefan Soucek and Miles Bader
|
||||
-- Re-add mmu-less support to msh
|
||||
* Jim Treadway
|
||||
-- Fixed a buffer overflow in the local group handling code.
|
||||
-- Fixed a missing "\" in usage.h
|
||||
-- Made pidof not add trailing spaces
|
||||
-- Fixed msh bugs so things like "A = 1; B = `eval $A`; echo $B"
|
||||
can now work.
|
||||
* Mike Voytovich
|
||||
-- insmod big endian ARM support
|
||||
|
||||
|
||||
-Erik Andersen, 27 April 2002
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
0.60.2
|
||||
|
||||
Stable Release
|
||||
|
||||
* Please support busybox and help us buy busybox.net. See the
|
||||
(current) busybox webpage for details.
|
||||
|
||||
New Applets & New Features:
|
||||
* msh was reworked by Vladimir Oleynik's so it can handle things like
|
||||
for i in `ls *.c` ; do echo $i ; done
|
||||
unfortunately, this also means that msh is no-longer uClinux safe,
|
||||
and will require some surgery to make it use vfork() again.
|
||||
* Charles Steinkuehler <charles@steinkuehler.net> -- reworked hostname
|
||||
so it behaves as expected (backport from busybox unstable)
|
||||
|
||||
Known Problems
|
||||
none. :)
|
||||
|
||||
Bugfixes:
|
||||
* Erik Andersen
|
||||
-- Fixed grep -E and egrep so they actually behave as expected
|
||||
-- init cleanups and (theoretical) uClinux support
|
||||
-- Fixed large file (>2Gig) support (enable in the Makefile)
|
||||
-- Always enable test when a shell is enabled (least surprise)
|
||||
-- Made 'mount -a' use proc to avoid a static noauto list
|
||||
-- lots of source tree cleanups
|
||||
* Laurence Anderson
|
||||
-- Removed some traces of no-longer existant rpmunpack (which
|
||||
has been obsoleted by the rpm2cpio applet).
|
||||
-- Fixed unarchive.c to use the correct buffer when calling
|
||||
dirname, improve an error message, and plug some memory leaks.
|
||||
-- Fixed rpm2cpio.c mkfs_minix.c fsck_minix.c fbset.c to use
|
||||
standard types (s/u16/u_int16_t/g s/u32/u_int32_t/g etc)
|
||||
* ASA <llb@udm.net.ru> -- fixed ash handling of command line args
|
||||
when sourcing ('.') commands.
|
||||
* Ethan Benson <erbenson@alaska.net>
|
||||
-- Fix mount's noauto option to not automount as "usbdevfs"
|
||||
* David Kimdon <dwhedon@instant802.com> -- fixed md5sum binary sums
|
||||
* Matt Kraai
|
||||
-- Fix sed s/[/]// handling (noted by Dumas Patrice).
|
||||
-- Fix dirname(3) improper consts, allow libc version to override.
|
||||
|
@ -22,23 +202,19 @@
|
|||
-- Fixed basename to be SUSv2 compliant (which specifies that the
|
||||
extension should stay if it is identical to the basename.
|
||||
-- Fixed rmdir, since SuS2 says rmdir must provide -p
|
||||
* Ethan Benson <erbenson@alaska.net>
|
||||
-- Fix mount's noauto option to not automount as "usbdevfs"
|
||||
-- Fixed sed empty line substitutions (noted by Joshua Hudson).
|
||||
* Steve Merrifield <steve@labyrinth.net.au> -- make vi use xmalloc
|
||||
* Glenn McGrath
|
||||
-- dpkg cleanups, various bugfixes
|
||||
* Vladimir Oleynik
|
||||
-- Add support for `busybox --help APPLET'
|
||||
-- Fixed route so it properly displays all route entries
|
||||
-- Fix for ash leading redirections (i.e. '2>/dev/null ls rubbish')
|
||||
* Laurence Anderson
|
||||
-- Removed some traces of no-longer existant rpmunpack (which
|
||||
has been obsoleted by the rpm2cpio applet).
|
||||
-- Fixed unarchive.c to use the correct buffer when calling
|
||||
dirname, improve an error message, and plug some memory leaks.
|
||||
-- Fixed rpm2cpio.c mkfs_minix.c fsck_minix.c fbset.c to use
|
||||
standard types (s/u16/u_int16_t/g s/u32/u_int32_t/g etc)
|
||||
|
||||
* Andrew Tipton <andrew@cadre5.com> -- enable vi cursor keys when in
|
||||
edit mode as vim does.
|
||||
|
||||
|
||||
-Erik Andersen, --not yet released--
|
||||
-Erik Andersen, 20 November 2001
|
||||
|
||||
|
||||
|
||||
|
@ -608,7 +784,7 @@
|
|||
Arne Bernin <arne@matrix.loopback.org>
|
||||
* Fixed NFS so it supports 2.4.x kernels and NFSv3.
|
||||
* Brand, new versions of grep and sed which use libc regex routines,
|
||||
thanks to Mark Whitley <markw@lineo.com>. The hand-tooled
|
||||
thanks to Mark Whitley <markw@codepoet.org>. The hand-tooled
|
||||
"regexp.[ch]" files have been removed. Much help on these from
|
||||
Matt Kraai as well.
|
||||
|
||||
|
@ -631,7 +807,7 @@
|
|||
* Added a mini ar archive utility, especially written for BusyBox by
|
||||
Glenn McGrath <bug1@netconnect.com.au>
|
||||
* Added mktemp, contributed by Daniel Jacobowitz <dan@debian.org>
|
||||
* Added setkeycodes, for those that have wierd keyboard buttons.
|
||||
* Added setkeycodes, for those that have weird keyboard buttons.
|
||||
* Added md5sum, uuencode and uudecode -- thanks to Alfred M. Szmidt
|
||||
<ams@trillian.itslinux.org> for contributing these.
|
||||
* Added 'grep -v' option (inverted search) and updated
|
||||
|
@ -1002,7 +1178,7 @@
|
|||
init is not at PID 1 (like when running in an initrd).
|
||||
* Added a prelinary du implementation. Some parameter parsing
|
||||
stuff still needs to be added. -beppu (John Beppu
|
||||
<beppu@lineo.com>)
|
||||
<beppu@codepoet.org>)
|
||||
* Implemented tee. -beppu Implemented head. -beppu
|
||||
|
||||
-Erik Andersen, Dec 10, 1999
|
||||
|
@ -1145,7 +1321,7 @@
|
|||
0.32
|
||||
* More changes -- many thanks to Lineo for paying me to work on
|
||||
busybox. If you have any problems please let me know ASAP at
|
||||
andersen@lineo.com or andersee@debian.org
|
||||
andersee@debian.org
|
||||
* usage() now prints the BusyBox version. This will help folks
|
||||
realize that they are not in Kansas anymore.
|
||||
* Fixed mkdir -m option so that it works. kill segfaulted w/o any
|
|
@ -0,0 +1,138 @@
|
|||
2002-10-27 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* Makefile: Increment version number
|
||||
|
||||
* debian/control, debian/changelog: Update packaging info
|
||||
|
||||
2002-10-26 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* debian/Config.h-udeb:
|
||||
Don't support init being run as /linux in the debian installer
|
||||
-Erik
|
||||
|
||||
* swaponoff.c: last_patch64 from vodz:
|
||||
|
||||
The following usage from original user:
|
||||
$ ./busybox swapon -a
|
||||
Have typo problem:
|
||||
swapon: swapon: Operation not permitted
|
||||
|
||||
But regular version:
|
||||
swapon: /dev/hda5: Operation not permitted
|
||||
|
||||
Patch attached, reduced 9 bytes and advanced
|
||||
exit code also.
|
||||
|
||||
* vi.c:
|
||||
A patch from Jouni Malinen to avoid some buffer overflows in vi,
|
||||
closing bug #1270
|
||||
|
||||
* Makefile: Ivan Popov noticed that handling of PREFIX was bad.
|
||||
-Erik
|
||||
|
||||
2002-10-25 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* tftp.c: This patch from Magnus Damm fixed a long standing problem
|
||||
with freeing memory.
|
||||
|
||||
2002-10-23 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* top.c: Backport vodz' reworked top applet from unstable
|
||||
|
||||
2002-10-22 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* ash.c, ifconfig.c: Fix warnings
|
||||
|
||||
* md5sum.c: Fix undefined operation (temp = temp = <stuff>) and remove
|
||||
double definition.
|
||||
-Erik
|
||||
|
||||
* init.c: I committed the fflush in the wrong spot. I should go to bed
|
||||
earlier so I don't screw up such easy stuff.
|
||||
-Erik
|
||||
|
||||
* ash.c: Apply last_patch51_3 from vodz
|
||||
|
||||
* init.c: Be absurdly careful about flushing stdout.
|
||||
|
||||
2002-10-18 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* tests/sh.testcases: Missed a spot
|
||||
|
||||
* tests/sh.testcases: disambiguate a test
|
||||
|
||||
* lsmod.c: Fixup some needless formatting differences vs modutils
|
||||
|
||||
* hostname.c:
|
||||
Fixup slight difference in 'hostname -d' behavior vs GNU hostname
|
||||
|
||||
2002-10-12 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* init.c:
|
||||
After thinking about it, I think this patch from Matt Kraai is probably the
|
||||
best way to go. Sysvinit does not provide a controlling tty since it doesn't
|
||||
even try to open ttys for apps. We do. We we should _try_ to provide a
|
||||
controlling tty if possible, but we needn't freak out if it doesn't work. So
|
||||
we won't need to use openvt or similar, we'll just have init do the Right
|
||||
Thing(tm).
|
||||
|
||||
2002-10-08 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* docs/.cvsignore: oops
|
||||
|
||||
* docs/.cvsignore, Makefile: Remove docs/busybox.pod on 'make clean'
|
||||
|
||||
* init.c:
|
||||
Patch from Ben Gamsa <ben@somanetworks.com> to handle it when orphaned
|
||||
processes are created faster than busybox init reaps them.
|
||||
|
||||
* lsmod.c: Fix missing \n noticed by Robert Schwebel
|
||||
|
||||
* debian/Config.h-udeb: Enable pidof
|
||||
|
||||
* libbb/copy_file.c:
|
||||
Doh! It turns out I broke 'cp -a' symlink handling. Oops. This fix, from
|
||||
Tollef Fog Heen <tollef@add.no> fixes my stupid thinko so that 'cp -a' once
|
||||
again copies symlinks properly.
|
||||
|
||||
2002-09-30 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* usage.h: Fix docs
|
||||
|
||||
* lash.c:
|
||||
Use %m, not strerror (changing since strerror(err) was broken anyways)
|
||||
|
||||
* init.c: Set the close-on-exec flag, just to be safe
|
||||
|
||||
* time.c: Doh. We divide microseconds by 60?
|
||||
|
||||
2002-09-27 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* time.c: Bug fix from Nitin Gupta <gupta@equator.com>
|
||||
|
||||
2002-09-26 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* lash.c: Avoid calling exit() from within fork/vfork'ed processes.
|
||||
-Erik
|
||||
|
||||
2002-09-25 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* init.c:
|
||||
Ignoring SIGCHLD causes a race leading to the occasional hang of init
|
||||
when init will wait() on itself in waitfor() when the child exits before
|
||||
init is scheduled to run. Letting init hang is very seriously bad.
|
||||
-Erik
|
||||
|
||||
2002-09-22 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* Makefile: Fixup largefile settings.
|
||||
-Erik
|
||||
|
||||
2002-09-20 Erik Andersen <andersen@dillweed>
|
||||
|
||||
* gunzip.c: Doh! As noted by K.-P. Kirchdörfer" <kapeka@epost.de>,
|
||||
gunzip -c deletes the source source file! This fixes it.
|
||||
-Erik
|
||||
|
||||
* top.c: Don't leak FILEs
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
// BusyBox Applications
|
||||
//#define BB_ADJTIMEX
|
||||
//#define BB_AR
|
||||
//#define BB_ASH
|
||||
#define BB_ASH
|
||||
#define BB_BASENAME
|
||||
#define BB_CAT
|
||||
#define BB_CHGRP
|
||||
|
@ -68,6 +68,7 @@
|
|||
//#define BB_LOADKMAP
|
||||
#define BB_LOGGER
|
||||
//#define BB_LOGNAME
|
||||
//#define BB_LOSETUP
|
||||
#define BB_LS
|
||||
#define BB_LSMOD
|
||||
//#define BB_MAKEDEVS
|
||||
|
@ -81,7 +82,7 @@
|
|||
#define BB_MODPROBE
|
||||
#define BB_MORE
|
||||
#define BB_MOUNT
|
||||
#define BB_MSH
|
||||
//#define BB_MSH
|
||||
//#define BB_MT
|
||||
#define BB_MV
|
||||
//#define BB_NC
|
||||
|
@ -117,6 +118,8 @@
|
|||
//#define BB_TEST
|
||||
//#define BB_TELNET
|
||||
//#define BB_TFTP
|
||||
//#define BB_TIME
|
||||
//#define BB_TOP
|
||||
#define BB_TOUCH
|
||||
//#define BB_TR
|
||||
//#define BB_TRACEROUTE
|
||||
|
@ -151,10 +154,10 @@
|
|||
//
|
||||
// If you enabled one or more of the shells, you may select which one
|
||||
// should be run when sh is invoked:
|
||||
//#define BB_FEATURE_SH_IS_ASH
|
||||
#define BB_FEATURE_SH_IS_ASH
|
||||
//#define BB_FEATURE_SH_IS_HUSH
|
||||
//#define BB_FEATURE_SH_IS_LASH
|
||||
#define BB_FEATURE_SH_IS_MSH
|
||||
//#define BB_FEATURE_SH_IS_MSH
|
||||
//
|
||||
// BusyBox will, by default, malloc space for its buffers. This costs code
|
||||
// size for the call to xmalloc. You can use the following feature to have
|
||||
|
@ -179,12 +182,12 @@
|
|||
//#define BB_FEATURE_USE_DEVPS_PATCH
|
||||
//
|
||||
// show verbose usage messages
|
||||
//#define BB_FEATURE_VERBOSE_USAGE
|
||||
#define BB_FEATURE_VERBOSE_USAGE
|
||||
//
|
||||
// Use termios to manipulate the screen ('more' is prettier with this on)
|
||||
//#define BB_FEATURE_USE_TERMIOS
|
||||
//
|
||||
// calculate terminal & column widths (for more and ls)
|
||||
// calculate terminal & column widths (for more, ls, and telnet)
|
||||
#define BB_FEATURE_AUTOWIDTH
|
||||
//
|
||||
// show username/groupnames for ls
|
||||
|
@ -205,6 +208,9 @@
|
|||
// enable ls -L
|
||||
#define BB_FEATURE_LS_FOLLOWLINKS
|
||||
//
|
||||
// Use color to identify different file types
|
||||
#define BB_FEATURE_LS_COLOR
|
||||
//
|
||||
// Disable for a smaller (but less functional) ping
|
||||
#define BB_FEATURE_FANCY_PING
|
||||
//
|
||||
|
@ -295,6 +301,13 @@
|
|||
// Only relevant if a shell is enabled.
|
||||
//#define BB_FEATURE_SH_FANCY_PROMPT
|
||||
//
|
||||
// Uncomment this option to disable job control. Job control lets you
|
||||
// run jobs in the background (which completely useless for is all you
|
||||
// are doing is running scripts). Disabing this is bad for interactive
|
||||
// use, since when you hit ^C in an application, it will also kill the
|
||||
// shell. This adds about 2.5k on an x86 system.
|
||||
#define BB_FEATURE_ASH_JOB_CONTROL
|
||||
//
|
||||
//Turn on extra fbset options
|
||||
//#define BB_FEATURE_FBSET_FANCY
|
||||
//
|
||||
|
@ -302,7 +315,7 @@
|
|||
//#define BB_FEATURE_FBSET_READMODE
|
||||
//
|
||||
// Support insmod/lsmod/rmmod for post 2.1 kernels
|
||||
//#define BB_FEATURE_NEW_MODULE_INTERFACE
|
||||
#define BB_FEATURE_NEW_MODULE_INTERFACE
|
||||
//
|
||||
// Support insmod/lsmod/rmmod for pre 2.1 kernels
|
||||
//#define BB_FEATURE_OLD_MODULE_INTERFACE
|
||||
|
@ -360,9 +373,12 @@
|
|||
// Support for the find -perm option.
|
||||
#define BB_FEATURE_FIND_PERM
|
||||
//
|
||||
// Support for the find -mtine option.
|
||||
// Support for the find -mtime option.
|
||||
#define BB_FEATURE_FIND_MTIME
|
||||
//
|
||||
//// Support for the find -newer option.
|
||||
#define BB_FEATURE_FIND_NEWER
|
||||
//
|
||||
// Support for the -A -B and -C context flags in grep
|
||||
//#define BB_FEATURE_GREP_CONTEXT
|
||||
//
|
||||
|
@ -405,16 +421,11 @@
|
|||
// mere mortals so leave this stuff alone.
|
||||
//
|
||||
#include <features.h>
|
||||
#if defined __UCLIBC__ && ! defined __UCLIBC_HAS_MMU__
|
||||
#if defined(__uClinux__)
|
||||
#undef BB_ASH /* Not even a chance it will work */
|
||||
#undef BB_RPM2CPIO /* Uses gz_open(), which uses fork() */
|
||||
#undef BB_DPKG_DEB /* Uses gz_open(), which uses fork() */
|
||||
#undef BB_ASH /* Uses fork() */
|
||||
#undef BB_HUSH /* Uses fork() */
|
||||
#undef BB_LASH /* Uses fork() */
|
||||
#undef BB_INIT /* Uses fork() */
|
||||
#undef BB_FEATURE_TAR_GZIP /* Uses fork() */
|
||||
#undef BB_SYSLOGD /* Uses daemon() */
|
||||
#undef BB_KLOGD /* Uses daemon() */
|
||||
#undef BB_UPDATE /* Uses daemon() */
|
||||
#endif
|
||||
#if defined BB_ASH || defined BB_HUSH || defined BB_LASH || defined BB_MSH
|
|
@ -17,15 +17,14 @@ Copyright 1998 Dave Cinege <dcinege@psychosis.com>
|
|||
mini-gzip(gzip), mini-netcat(mnc)
|
||||
Copyright 1998 Charles P. Wright <cpwright@villagenet.com>
|
||||
|
||||
Tons of new stuff as noted in header files
|
||||
Copyright (C) 1999,2000,2001 by Lineo, inc. and written by
|
||||
Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
|
||||
|
||||
Tons of new stuff as noted in header files
|
||||
Copyright (C) 1999,2000 by Lineo, inc. and Erik Andersen
|
||||
Copyright (C) 1999,2000,2001 by Erik Andersen <andersee@debian.org>
|
||||
|
||||
|
||||
Please feed suggestions, bug reports, insults, and bribes back to:
|
||||
Erik Andersen
|
||||
<andersen@lineo.com>
|
||||
<andersen@codepoet.org>
|
||||
<andersee@debian.org>
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Makefile for busybox
|
||||
#
|
||||
# Copyright (C) 1999,2000,2001 Erik Andersen <andersee@debian.org>
|
||||
# Copyright (C) 1999-2002 Erik Andersen <andersee@debian.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
|
||||
|
@ -18,7 +18,7 @@
|
|||
#
|
||||
|
||||
PROG := busybox
|
||||
VERSION := 0.60.2.pre
|
||||
VERSION := 0.60.5
|
||||
BUILDTIME := $(shell TZ=UTC date -u "+%Y.%m.%d-%H:%M%z")
|
||||
export VERSION
|
||||
|
||||
|
@ -39,23 +39,31 @@ DOSTATIC = false
|
|||
# Leave this set to `false' for production use.
|
||||
DODEBUG = false
|
||||
|
||||
# Setting this to `true' will cause busybox to directly use the system's
|
||||
# password and group functions. Assuming you use GNU libc, when this is
|
||||
# `true', you will need to install the /etc/nsswitch.conf configuration file
|
||||
# and the required libnss_* libraries. This generally makes your embedded
|
||||
# system quite a bit larger... If you leave this off, busybox will directly use
|
||||
# the /etc/password, /etc/group files (and your system will be smaller, and I
|
||||
# will get fewer emails asking about how glibc NSS works). Enabling this adds
|
||||
# just 1.4k to the binary size (which is a _lot_ less then glibc NSS costs).
|
||||
# Note that if you want hostname resolution to work with glibc, you still need
|
||||
# the libnss_* libraries.
|
||||
# If you enable this option, busybox will use the system's password
|
||||
# and group functions. And if you are using the GNU C library
|
||||
# (glibc), you will then need to install the /etc/nsswitch.conf
|
||||
# configuration file and the required /lib/libnss_* libraries in
|
||||
# order for the password and group functions to work. This generally
|
||||
# makes your embedded system quite a bit larger.
|
||||
# Disabling this option will cause busybox to directly access the
|
||||
# system's /etc/password, /etc/group files (and your system will be
|
||||
# smaller, and I will get fewer emails asking about how glibc NSS
|
||||
# works). When this option is disabled, you will not be able to use
|
||||
# PAM to access remote LDAP password servers and whatnot. And if you
|
||||
# want hostname resolution to work with glibc, you still need the
|
||||
# /lib/libnss_* libraries.
|
||||
# If you disable this option, it will add about 1.5k to busybox.
|
||||
USE_SYSTEM_PWD_GRP = true
|
||||
|
||||
# This enables compiling with dmalloc ( http://dmalloc.com/ )
|
||||
# which is an excellent public domain mem leak and malloc problem
|
||||
# detector. To enable dmalloc, before running busybox you will
|
||||
# want to first set up your environment.
|
||||
# eg: `export DMALLOC_OPTIONS=debug=0x14f47d83,inter=100,log=logfile`
|
||||
# eg: `export DMALLOC_OPTIONS=debug=0x34f47d83,inter=100,log=logfile`
|
||||
# The debug= value is generated using the following command
|
||||
# dmalloc -p log-stats -p log-non-free -p log-bad-space -p log-elapsed-time \
|
||||
# -p check-fence -p check-heap -p check-lists -p check-blank \
|
||||
# -p check-funcs -p realloc-copy -p allow-free-null
|
||||
# Do not enable this for production builds...
|
||||
DODMALLOC = false
|
||||
|
||||
|
@ -74,7 +82,7 @@ DOLFS = false
|
|||
|
||||
# If you have a "pristine" source directory, point BB_SRC_DIR to it.
|
||||
# Experimental and incomplete; tell the mailing list
|
||||
# <busybox@opensource.lineo.com> if you do or don't like it so far.
|
||||
# <busybox@busybox.net> if you do or don't like it so far.
|
||||
BB_SRC_DIR =
|
||||
|
||||
# If you are running a cross compiler, you may want to set this
|
||||
|
@ -82,11 +90,11 @@ BB_SRC_DIR =
|
|||
CROSS =
|
||||
CC = $(CROSS)gcc
|
||||
AR = $(CROSS)ar
|
||||
STRIPTOOL = $(CROSS)strip
|
||||
STRIP = $(CROSS)strip
|
||||
|
||||
# To compile vs uClibc, just use the compiler wrapper built by uClibc...
|
||||
# Everything should compile and work as expected these days...
|
||||
#CC = ../uClibc/extra/gcc-uClibc/i386-uclibc-gcc
|
||||
#CC=/usr/i386-linux-uclibc/bin/i386-uclibc-gcc
|
||||
|
||||
# To compile vs some other alternative libc, you may need to use/adjust
|
||||
# the following lines to meet your needs...
|
||||
|
@ -106,15 +114,48 @@ STRIPTOOL = $(CROSS)strip
|
|||
#CROSS_CFLAGS+=-nostdinc -I$(LIBCDIR)/include -I$(GCCINCDIR)
|
||||
#GCCINCDIR = $(shell gcc -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp")
|
||||
|
||||
# use '-Os' optimization if available, else use -O2
|
||||
OPTIMIZATION := $(shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \
|
||||
then echo "-Os"; else echo "-O2" ; fi)
|
||||
|
||||
WARNINGS = -Wall -Wshadow
|
||||
|
||||
ARFLAGS = -r
|
||||
|
||||
#
|
||||
|
||||
TARGET_ARCH:=${shell $(CC) -dumpmachine | sed -e s'/-.*//' \
|
||||
-e 's/i.86/i386/' \
|
||||
-e 's/sparc.*/sparc/' \
|
||||
-e 's/arm.*/arm/g' \
|
||||
-e 's/m68k.*/m68k/' \
|
||||
-e 's/ppc/powerpc/g' \
|
||||
-e 's/v850.*/v850/g' \
|
||||
-e 's/sh[234]/sh/' \
|
||||
-e 's/mips.*/mips/' \
|
||||
}
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Arch specific compiler optimization stuff should go here.
|
||||
# Unless you want to override the defaults, do not set anything
|
||||
# for OPTIMIZATION...
|
||||
|
||||
# use '-Os' optimization if available, else use -O2
|
||||
OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \
|
||||
then echo "-Os"; else echo "-O2" ; fi}
|
||||
|
||||
# Some nice architecture specific optimizations
|
||||
ifeq ($(strip $(TARGET_ARCH)),arm)
|
||||
OPTIMIZATION+=-fstrict-aliasing
|
||||
endif
|
||||
ifeq ($(strip $(TARGET_ARCH)),i386)
|
||||
OPTIMIZATION+=-march=i386
|
||||
OPTIMIZATION+=${shell if $(CC) -mpreferred-stack-boundary=2 -S -o /dev/null -xc \
|
||||
/dev/null >/dev/null 2>&1; then echo "-mpreferred-stack-boundary=2"; fi}
|
||||
OPTIMIZATION+=${shell if $(CC) -falign-functions=1 -falign-jumps=0 -falign-loops=0 \
|
||||
-S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo \
|
||||
"-falign-functions=1 -falign-jumps=0 -falign-loops=0"; else \
|
||||
if $(CC) -malign-functions=0 -malign-jumps=0 -S -o /dev/null -xc \
|
||||
/dev/null >/dev/null 2>&1; then echo "-malign-functions=0 -malign-jumps=0"; fi; fi}
|
||||
endif
|
||||
OPTIMIZATIONS:=$(OPTIMIZATION) -fomit-frame-pointer
|
||||
|
||||
|
||||
#--------------------------------------------------------
|
||||
# If you're going to do a lot of builds with a non-vanilla configuration,
|
||||
# it makes sense to adjust parameters above, so you can type "make"
|
||||
|
@ -122,10 +163,9 @@ ARFLAGS = -r
|
|||
# every time. The stuff below, on the other hand, is probably less
|
||||
# prone to casual user adjustment.
|
||||
#
|
||||
|
||||
ifeq ($(strip $(DOLFS)),true)
|
||||
# For large file summit support
|
||||
CFLAGS+=-D_FILE_OFFSET_BITS=64
|
||||
# For large file support
|
||||
CFLAGS+=-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
|
||||
endif
|
||||
ifeq ($(strip $(DODMALLOC)),true)
|
||||
# For testing mem leaks with dmalloc
|
||||
|
@ -143,11 +183,11 @@ endif
|
|||
ifeq ($(strip $(DODEBUG)),true)
|
||||
CFLAGS += $(WARNINGS) -g -D_GNU_SOURCE
|
||||
LDFLAGS += -Wl,-warn-common
|
||||
STRIP =
|
||||
STRIPCMD = /bin/true -Since_we_are_debugging
|
||||
else
|
||||
CFLAGS += $(WARNINGS) $(OPTIMIZATION) -fomit-frame-pointer -D_GNU_SOURCE
|
||||
CFLAGS += $(WARNINGS) $(OPTIMIZATIONS) -D_GNU_SOURCE
|
||||
LDFLAGS += -s -Wl,-warn-common
|
||||
STRIP = $(STRIPTOOL) --remove-section=.note --remove-section=.comment $(PROG)
|
||||
STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment
|
||||
endif
|
||||
ifeq ($(strip $(DOSTATIC)),true)
|
||||
LDFLAGS += --static
|
||||
|
@ -164,7 +204,7 @@ ifeq ($(strip $(DOSTATIC)),true)
|
|||
#endif
|
||||
endif
|
||||
|
||||
ifndef $(PREFIX)
|
||||
ifeq ($(strip $(PREFIX)),)
|
||||
PREFIX = `pwd`/_install
|
||||
endif
|
||||
|
||||
|
@ -237,7 +277,7 @@ endif
|
|||
LIBBB = libbb
|
||||
LIBBB_LIB = libbb.a
|
||||
LIBBB_CSRC= ask_confirmation.c chomp.c concat_path_file.c copy_file.c \
|
||||
copy_file_chunk.c libc5.c device_open.c error_msg.c \
|
||||
copy_file_chunk.c libc5.c device_open.c error_msg.c inode_hash.c \
|
||||
error_msg_and_die.c fgets_str.c find_mount_point.c find_pid_by_name.c \
|
||||
find_root_device.c full_read.c full_write.c get_console.c \
|
||||
get_last_path_component.c get_line_from_file.c gz_open.c human_readable.c \
|
||||
|
@ -245,7 +285,7 @@ isdirectory.c kernel_version.c loop.c mode_string.c module_syscalls.c mtab.c \
|
|||
mtab_file.c my_getgrnam.c my_getgrgid.c my_getpwnam.c my_getpwnamegid.c \
|
||||
my_getpwuid.c parse_mode.c parse_number.c perror_msg.c perror_msg_and_die.c \
|
||||
print_file.c process_escape_sequence.c read_package_field.c recursive_action.c \
|
||||
safe_read.c safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c \
|
||||
safe_read.c safe_write.c safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c \
|
||||
trim.c unzip.c vdprintf.c verror_msg.c vperror_msg.c wfopen.c xfuncs.c \
|
||||
xgetcwd.c xreadlink.c xregcomp.c interface.c remove_file.c last_char_is.c \
|
||||
copyfd.c vherror_msg.c herror_msg.c herror_msg_and_die.c xgethostbyname.c \
|
||||
|
@ -303,15 +343,9 @@ docs/BusyBox.1: docs/busybox.pod
|
|||
- pod2man --center=BusyBox --release="version $(VERSION)" \
|
||||
$< > $@
|
||||
|
||||
docs/BusyBox.html: docs/busybox.lineo.com/BusyBox.html
|
||||
- mkdir -p docs
|
||||
-@ rm -f docs/BusyBox.html
|
||||
-@ ln -s busybox.lineo.com/BusyBox.html docs/BusyBox.html
|
||||
|
||||
docs/busybox.lineo.com/BusyBox.html: docs/busybox.pod
|
||||
-@ mkdir -p docs/busybox.lineo.com
|
||||
- pod2html --noindex $< > \
|
||||
docs/busybox.lineo.com/BusyBox.html
|
||||
docs/BusyBox.html: docs/busybox.pod
|
||||
-@ mkdir -p docs
|
||||
- pod2html --noindex $< > docs/BusyBox.html
|
||||
-@ rm -f pod2htm*
|
||||
|
||||
|
||||
|
@ -339,12 +373,12 @@ docs/busybox.pdf: docs/busybox.ps
|
|||
|
||||
docs/busybox/busyboxdocumentation.html: docs/busybox.sgml
|
||||
- mkdir -p docs
|
||||
(cd docs/busybox.lineo.com; sgmltools -b html ../busybox.sgml)
|
||||
(cd docs; sgmltools -b html ../busybox.sgml)
|
||||
|
||||
|
||||
busybox: $(PWD_LIB) $(LIBBB_LIB) $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBBB_LIB) $(PWD_LIB) $(LIBRARIES)
|
||||
$(STRIP)
|
||||
$(STRIPCMD) $(PROG)
|
||||
|
||||
# Without VPATH, rule expands to "/bin/sh busybox.mkll Config.h applets.h"
|
||||
# but with VPATH, some or all of those file names are resolved to the
|
||||
|
@ -362,19 +396,27 @@ else
|
|||
endif
|
||||
|
||||
$(PWD_OBJS): %.o: %.c Config.h busybox.h applets.h Makefile
|
||||
- mkdir -p $(PWD_GRP)
|
||||
ifneq ($(strip $(BB_SRC_DIR)),)
|
||||
-mkdir -p $(PWD_GRP)
|
||||
endif
|
||||
$(CC) $(CFLAGS) $(PWD_CFLAGS) -c $< -o $*.o
|
||||
|
||||
$(LIBBB_OBJS): %.o: %.c Config.h busybox.h applets.h Makefile libbb/libbb.h
|
||||
- mkdir -p $(LIBBB)
|
||||
ifneq ($(strip $(BB_SRC_DIR)),)
|
||||
-mkdir -p $(LIBBB)
|
||||
endif
|
||||
$(CC) $(CFLAGS) $(LIBBB_CFLAGS) -c $< -o $*.o
|
||||
|
||||
$(LIBBB_MOBJ): $(LIBBB_MSRC)
|
||||
- mkdir -p $(LIBBB)
|
||||
ifneq ($(strip $(BB_SRC_DIR)),)
|
||||
-mkdir -p $(LIBBB)
|
||||
endif
|
||||
$(CC) $(CFLAGS) $(LIBBB_CFLAGS) -DL_$(patsubst libbb/%,%,$*) -c $< -o $*.o
|
||||
|
||||
$(LIBBB_AROBJS): $(LIBBB_ARCSRC)
|
||||
- mkdir -p $(LIBBB)
|
||||
ifneq ($(strip $(BB_SRC_DIR)),)
|
||||
-mkdir -p $(LIBBB)
|
||||
endif
|
||||
$(CC) $(CFLAGS) $(LIBBB_CFLAGS) -DL_$(patsubst libbb/%,%,$*) -c $< -o $*.o
|
||||
|
||||
libpwd.a: $(PWD_OBJS)
|
||||
|
@ -398,14 +440,13 @@ test tests:
|
|||
|
||||
clean:
|
||||
- cd tests && $(MAKE) clean
|
||||
- rm -f docs/BusyBox.txt docs/BusyBox.1 docs/BusyBox.html \
|
||||
docs/busybox.lineo.com/BusyBox.html
|
||||
- rm -f docs/BusyBox.txt docs/BusyBox.1 docs/BusyBox.html docs/BusyBox.html
|
||||
- rm -f docs/busybox.txt docs/busybox.dvi docs/busybox.ps \
|
||||
docs/busybox.pdf docs/busybox.lineo.com/busybox.html
|
||||
docs/busybox.pdf docs/busybox.html docs/busybox.pod
|
||||
- rm -f multibuild.log Config.h.orig *.gdb *.elf
|
||||
- rm -rf docs/busybox _install libpwd.a libbb.a pod2htm*
|
||||
- rm -f busybox.links libbb/loop.h *~ slist.mk core applet_source_list
|
||||
- find -name \*.o -exec rm -f {} \;
|
||||
- rm -f busybox busybox.links libbb/loop.h *~ slist.mk core applet_source_list
|
||||
- find . -name \*.o -exec rm -f {} \;
|
||||
|
||||
distclean: clean
|
||||
- cd tests && $(MAKE) distclean
|
||||
|
@ -414,6 +455,9 @@ distclean: clean
|
|||
install: install.sh busybox busybox.links
|
||||
$(SHELL) $< $(PREFIX)
|
||||
|
||||
uninstall: busybox busybox.links
|
||||
for i in `cat busybox.links` ; do rm -f $$PREFIX$$i; done
|
||||
|
||||
install-hardlinks: install.sh busybox busybox.links
|
||||
$(SHELL) $< $(PREFIX) --hardlinks
|
||||
|
|
@ -39,8 +39,9 @@ Supported architectures:
|
|||
|
||||
Supported libcs:
|
||||
|
||||
glibc-2.0.x, glibc-2.1.x, Linux-libc5, uClibc. People are looking at
|
||||
newlib and diet-libc, but consider them unsupported, untested, or worse.
|
||||
glibc-2.0.x, glibc-2.1.x, glibc-2.2.x, Linux-libc5, uClibc. People
|
||||
are looking at newlib and diet-libc, but consider them unsupported,
|
||||
untested, or worse.
|
||||
|
||||
Supported kernels:
|
||||
|
||||
|
@ -82,7 +83,7 @@ top of ash.c as well, so check those out if you want to tweak things.
|
|||
Getting help:
|
||||
|
||||
When you find you need help, you can check out the BusyBox mailing list
|
||||
archives at http://opensource.lineo.com/lists/busybox/ or even join
|
||||
archives at http://busybox.net/lists/busybox/ or even join
|
||||
the mailing list if you are interested.
|
||||
|
||||
----------------
|
||||
|
@ -90,12 +91,12 @@ the mailing list if you are interested.
|
|||
Bugs:
|
||||
|
||||
If you find bugs, please submit a bug report. Full instructions on how to
|
||||
report a bug are found at http://bugs.lineo.com/Reporting.html.
|
||||
report a bug are found at http://bugs.busybox.net/Reporting.html.
|
||||
|
||||
For the impatient: To submit a bug, simply send an email describing the problem
|
||||
to submit@bugs.lineo.com. Bug reports should look something like this:
|
||||
to submit@bugs.busybox.net. Bug reports should look something like this:
|
||||
|
||||
To: submit@bugs.lineo.com
|
||||
To: submit@bugs.busybox.net
|
||||
From: diligent@testing.linux.org
|
||||
Subject: /bin/true doesn't work
|
||||
|
||||
|
@ -123,30 +124,25 @@ understanding.
|
|||
FTP:
|
||||
|
||||
Source for the latest released version can always be downloaded from
|
||||
ftp://ftp.lineo.com/pub/busybox.
|
||||
http://busybox.net/downloads/
|
||||
|
||||
----------------
|
||||
|
||||
CVS:
|
||||
|
||||
BusyBox now has its own publicly browsable CVS tree at:
|
||||
http://opensource.lineo.com/cgi-bin/cvsweb/busybox/
|
||||
http://busybox.net/cgi-bin/cvsweb/busybox/
|
||||
|
||||
Anonymous CVS access is available. For instructions, check out:
|
||||
http://opensource.lineo.com/cvs_anon.html
|
||||
http://busybox.net/cvs_anon.html
|
||||
|
||||
For those that are actively contributing there is even CVS write access:
|
||||
http://opensource.lineo.com/cvs_write.html
|
||||
http://busybox.net/cvs_write.html
|
||||
|
||||
----------------
|
||||
|
||||
Please feed suggestions, bug reports, insults, and bribes back to:
|
||||
Erik Andersen
|
||||
<andersen@lineo.com>
|
||||
<andersen@codepoet.org>
|
||||
<andersee@debian.org>
|
||||
<andersee@codepoet.org>
|
||||
|
||||
<blatant plug>
|
||||
Many thanks to go to Lineo for paying me to work on busybox.
|
||||
</blatant plug>
|
||||
|
|
@ -18,7 +18,6 @@ around to it some time. If you have any good ideas, please let me know.
|
|||
Possible apps to include some time:
|
||||
|
||||
* hwclock
|
||||
* start-stop-daemon
|
||||
* group/commonize strings, remove dups (for i18n, l10n)
|
||||
|
||||
-----------
|
||||
|
@ -46,10 +45,6 @@ libraries such as uClibc.
|
|||
Compile with debugging on, run 'nm --size-sort ./busybox'
|
||||
and then start with the biggest things and make them smaller...
|
||||
|
||||
-----------------------
|
||||
|
||||
du.c probably ought to have an -x switch like GNU du does...
|
||||
|
||||
-----------------------
|
||||
|
||||
xargs could use a -l option
|
|
@ -242,6 +242,9 @@
|
|||
#ifdef BB_LOGREAD
|
||||
APPLET(logread, logread_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_LOSETUP
|
||||
APPLET(losetup, losetup_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_LS
|
||||
APPLET(ls, ls_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
|
@ -401,6 +404,12 @@
|
|||
#ifdef BB_TFTP
|
||||
APPLET(tftp, tftp_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TIME
|
||||
APPLET(time, time_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TOP
|
||||
APPLET(top, top_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TOUCH
|
||||
APPLET(touch, touch_main, _BB_DIR_BIN)
|
||||
#endif
|
14452
busybox/ash.c → ash.c
|
@ -2,8 +2,8 @@
|
|||
/*
|
||||
* Mini basename implementation for busybox
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
|
||||
* Copyright (C) 1999,2000 by Lineo, inc. and Erik Andersen
|
||||
* Copyright (C) 1999,2000,2001 by Erik Andersen <andersee@debian.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
|
|
@ -18,28 +18,19 @@ const char *applet_name;
|
|||
* this should be consistent w/ the enum, busybox.h::Location,
|
||||
* or else...
|
||||
*/
|
||||
static char* install_dir[] = {
|
||||
"/",
|
||||
"/bin",
|
||||
"/sbin",
|
||||
"/usr/bin",
|
||||
"/usr/sbin",
|
||||
};
|
||||
static const char usr_bin [] ="/usr/bin";
|
||||
static const char usr_sbin[] ="/usr/sbin";
|
||||
static const char* const install_dir[] = {
|
||||
&usr_bin [8], /* "", equivalent to "/" for concat_path_file() */
|
||||
&usr_bin [4], /* "/bin" */
|
||||
&usr_sbin[4], /* "/sbin" */
|
||||
usr_bin,
|
||||
usr_sbin
|
||||
};
|
||||
|
||||
/* abstract link() */
|
||||
typedef int (*__link_f)(const char *, const char *);
|
||||
|
||||
/*
|
||||
* Where in the filesystem is this busybox?
|
||||
* [return]
|
||||
* malloc'd string w/ full pathname of busybox's location
|
||||
* NULL on failure
|
||||
*/
|
||||
static char *busybox_fullpath()
|
||||
{
|
||||
return xreadlink("/proc/self/exe");
|
||||
}
|
||||
|
||||
/* create (sym)links for each applet */
|
||||
static void install_links(const char *busybox, int use_symbolic_links)
|
||||
{
|
||||
|
@ -116,7 +107,7 @@ int busybox_main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/* link */
|
||||
busybox = busybox_fullpath();
|
||||
busybox = xreadlink("/proc/self/exe");
|
||||
if (busybox) {
|
||||
install_links(busybox, use_symbolic_links);
|
||||
free(busybox);
|
|
@ -101,6 +101,12 @@ extern const struct BB_applet applets[];
|
|||
/* Pull in the utility routines from libbb */
|
||||
#include "libbb/libbb.h"
|
||||
|
||||
|
||||
/* Try to pull in PATH_MAX */
|
||||
#include <limits.h>
|
||||
/* for PATH_MAX on systems that don't have it in limits.h */
|
||||
#include <sys/param.h>
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 256
|
||||
#endif
|
||||
|
||||
#endif /* _BB_INTERNAL_H_ */
|
|
@ -1,6 +1,6 @@
|
|||
%define name busybox
|
||||
%define epoch 0
|
||||
%define version 0.60.2.pre
|
||||
%define version 0.60.3
|
||||
%define release %(date -I | sed -e 's/-/_/g')
|
||||
%define serial 1
|
||||
|
||||
|
@ -12,10 +12,10 @@ Serial: %{serial}
|
|||
Copyright: GPL
|
||||
Group: System/Utilities
|
||||
Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
|
||||
URL: http://busybox.lineo.com/
|
||||
Source: ftp://oss.lineo.com/busybox/%{name}-%{version}.tar.gz
|
||||
URL: http://busybox.net/
|
||||
Source: ftp://busybox.net/busybox/%{name}-%{version}.tar.gz
|
||||
Buildroot: /var/tmp/%{name}-%{version}
|
||||
Packager : Erik Andersen <andersen@lineo.com>
|
||||
Packager : Erik Andersen <andersen@codepoet.org>
|
||||
|
||||
%Description
|
||||
BusyBox combines tiny versions of many common UNIX utilities into a single
|
|
@ -1,116 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Utility routines.
|
||||
*
|
||||
* Copyright (C) tons of folks. Tracking down who wrote what
|
||||
* isn't something I'm going to worry about... If you wrote something
|
||||
* here, please feel free to acknowledge your work.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Based in part on code from sash, Copyright (c) 1999 by David I. Bell
|
||||
* Permission has been granted to redistribute this code under the GPL.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "busybox.h"
|
||||
|
||||
#undef APPLET
|
||||
#undef APPLET_NOUSAGE
|
||||
#undef PROTOTYPES
|
||||
#include "applets.h"
|
||||
|
||||
struct BB_applet *applet_using;
|
||||
|
||||
/* The -1 arises because of the {0,NULL,0,-1} entry above. */
|
||||
const size_t NUM_APPLETS = (sizeof (applets) / sizeof (struct BB_applet) - 1);
|
||||
|
||||
extern void show_usage(void)
|
||||
{
|
||||
const char *format_string;
|
||||
const char *usage_string = usage_messages;
|
||||
int i;
|
||||
|
||||
for (i = applet_using - applets; i > 0; ) {
|
||||
if (!*usage_string++) {
|
||||
--i;
|
||||
}
|
||||
}
|
||||
format_string = "%s\n\nUsage: %s %s\n\n";
|
||||
if(*usage_string == 0)
|
||||
format_string = "%s\n\nNo help available.\n\n";
|
||||
fprintf(stderr, format_string,
|
||||
full_version, applet_using->name, usage_string);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static int applet_name_compare(const void *x, const void *y)
|
||||
{
|
||||
const char *name = x;
|
||||
const struct BB_applet *applet = y;
|
||||
|
||||
return strcmp(name, applet->name);
|
||||
}
|
||||
|
||||
extern const size_t NUM_APPLETS;
|
||||
|
||||
struct BB_applet *find_applet_by_name(const char *name)
|
||||
{
|
||||
return bsearch(name, applets, NUM_APPLETS, sizeof(struct BB_applet),
|
||||
applet_name_compare);
|
||||
}
|
||||
|
||||
void run_applet_by_name(const char *name, int argc, char **argv)
|
||||
{
|
||||
static int recurse_level = 0;
|
||||
extern int been_there_done_that; /* From busybox.c */
|
||||
|
||||
recurse_level++;
|
||||
/* Do a binary search to find the applet entry given the name. */
|
||||
if ((applet_using = find_applet_by_name(name)) != NULL) {
|
||||
applet_name = applet_using->name;
|
||||
if (argv[1] && strcmp(argv[1], "--help") == 0) {
|
||||
if (strcmp(applet_using->name, "busybox")==0) {
|
||||
if(argv[2])
|
||||
applet_using = find_applet_by_name(argv[2]);
|
||||
else
|
||||
applet_using = NULL;
|
||||
}
|
||||
if(applet_using)
|
||||
show_usage();
|
||||
been_there_done_that=1;
|
||||
busybox_main(0, NULL);
|
||||
}
|
||||
exit((*(applet_using->main)) (argc, argv));
|
||||
}
|
||||
/* Just in case they have renamed busybox - Check argv[1] */
|
||||
if (recurse_level == 1) {
|
||||
run_applet_by_name("busybox", argc, argv);
|
||||
}
|
||||
recurse_level--;
|
||||
}
|
||||
|
||||
|
||||
/* END CODE */
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "linux"
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
End:
|
||||
*/
|
|
@ -1,89 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini ar implementation for busybox
|
||||
*
|
||||
* Copyright (C) 2000 by Glenn McGrath
|
||||
* Written by Glenn McGrath <bug1@optushome.com.au> 1 June 2000
|
||||
*
|
||||
* Based in part on BusyBox tar, Debian dpkg-deb and GNU ar.
|
||||
*
|
||||
* 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 <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include "busybox.h"
|
||||
|
||||
extern int ar_main(int argc, char **argv)
|
||||
{
|
||||
FILE *src_stream = NULL;
|
||||
char **extract_names = NULL;
|
||||
char ar_magic[8];
|
||||
int extract_function = extract_unconditional;
|
||||
int opt;
|
||||
int num_of_entries = 0;
|
||||
extern off_t archive_offset;
|
||||
|
||||
while ((opt = getopt(argc, argv, "ovtpx")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
extract_function |= extract_preserve_date;
|
||||
break;
|
||||
case 'v':
|
||||
extract_function |= extract_verbose_list;
|
||||
break;
|
||||
case 't':
|
||||
extract_function |= extract_list;
|
||||
break;
|
||||
case 'p':
|
||||
extract_function |= extract_to_stdout;
|
||||
break;
|
||||
case 'x':
|
||||
extract_function |= extract_all_to_fs;
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
/* check the src filename was specified */
|
||||
if (optind == argc) {
|
||||
show_usage();
|
||||
}
|
||||
|
||||
src_stream = xfopen(argv[optind++], "r");
|
||||
|
||||
/* check ar magic */
|
||||
fread(ar_magic, 1, 8, src_stream);
|
||||
archive_offset = 8;
|
||||
if (strncmp(ar_magic,"!<arch>",7) != 0) {
|
||||
error_msg_and_die("invalid magic");
|
||||
}
|
||||
|
||||
/* Create a list of files to extract */
|
||||
while (optind < argc) {
|
||||
extract_names = xrealloc(extract_names, sizeof(char *) * (num_of_entries + 2));
|
||||
extract_names[num_of_entries] = xstrdup(argv[optind]);
|
||||
num_of_entries++;
|
||||
extract_names[num_of_entries] = NULL;
|
||||
optind++;
|
||||
}
|
||||
|
||||
unarchive(src_stream, stdout, &get_header_ar, extract_function, "./", extract_names);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,183 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Gzip implementation for busybox
|
||||
*
|
||||
* Based on GNU gzip v1.2.4 Copyright (C) 1992-1993 Jean-loup Gailly.
|
||||
*
|
||||
* Originally adjusted for busybox by Sven Rudolph <sr1@inf.tu-dresden.de>
|
||||
* based on gzip sources
|
||||
*
|
||||
* Adjusted further by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
|
||||
* to support files as well as stdin/stdout, and to generally behave itself wrt
|
||||
* command line handling.
|
||||
*
|
||||
* General cleanup to better adhere to the style guide and make use of standard
|
||||
* busybox functions by Glenn McGrath <bug1@optushome.com.au>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*
|
||||
* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* The unzip code was written and put in the public domain by Mark Adler.
|
||||
* Portions of the lzw code are derived from the public domain 'compress'
|
||||
* written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
|
||||
* Ken Turkowski, Dave Mack and Peter Jannesen.
|
||||
*
|
||||
* See the license_msg below and the file COPYING for the software license.
|
||||
* See the file algorithm.doc for the compression algorithms and file formats.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static char *license_msg[] = {
|
||||
" Copyright (C) 1992-1993 Jean-loup Gailly",
|
||||
" 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., 675 Mass Ave, Cambridge, MA 02139, USA.",
|
||||
0
|
||||
};
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include "busybox.h"
|
||||
|
||||
extern int gunzip_main(int argc, char **argv)
|
||||
{
|
||||
FILE *in_file = stdin;
|
||||
FILE *out_file = NULL;
|
||||
struct stat stat_buf;
|
||||
|
||||
char *if_name = NULL;
|
||||
char *of_name = NULL;
|
||||
char *delete_file_name = NULL;
|
||||
|
||||
const int gunzip_to_stdout = 1;
|
||||
const int gunzip_force = 2;
|
||||
const int gunzip_test = 4;
|
||||
|
||||
int flags = 0;
|
||||
int opt = 0;
|
||||
int delete_old_file = FALSE;
|
||||
|
||||
/* if called as zcat */
|
||||
if (strcmp(applet_name, "zcat") == 0)
|
||||
flags |= gunzip_to_stdout;
|
||||
|
||||
while ((opt = getopt(argc, argv, "ctfhdq")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
flags |= gunzip_to_stdout;
|
||||
break;
|
||||
case 'f':
|
||||
flags |= gunzip_force;
|
||||
break;
|
||||
case 't':
|
||||
flags |= gunzip_test;
|
||||
break;
|
||||
case 'd': /* Used to convert gzip to gunzip. */
|
||||
break;
|
||||
case 'q':
|
||||
error_msg("-q option not supported, ignored");
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
show_usage(); /* exit's inside usage */
|
||||
}
|
||||
}
|
||||
|
||||
/* Set input filename and number */
|
||||
if (argv[optind] == NULL || strcmp(argv[optind], "-") == 0) {
|
||||
flags |= gunzip_to_stdout;
|
||||
} else {
|
||||
if_name = strdup(argv[optind]);
|
||||
/* Open input file */
|
||||
in_file = xfopen(if_name, "r");
|
||||
|
||||
/* set the buffer size */
|
||||
setvbuf(in_file, NULL, _IOFBF, 0x8000);
|
||||
|
||||
/* Get the time stamp on the input file. */
|
||||
if (stat(if_name, &stat_buf) < 0) {
|
||||
error_msg_and_die("Couldn't stat file %s", if_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that the input is sane. */
|
||||
if (isatty(fileno(in_file)) && (flags & gunzip_force) == 0)
|
||||
error_msg_and_die("compressed data not read from terminal. Use -f to force it.");
|
||||
|
||||
/* Set output filename and number */
|
||||
if (flags & gunzip_test) {
|
||||
out_file = xfopen("/dev/null", "w"); /* why does test use filenum 2 ? */
|
||||
} else if (flags & gunzip_to_stdout) {
|
||||
out_file = stdout;
|
||||
} else {
|
||||
char *extension;
|
||||
int length = strlen(if_name);
|
||||
|
||||
delete_old_file = TRUE;
|
||||
extension = strrchr(if_name, '.');
|
||||
if (extension && strcmp(extension, ".gz") == 0) {
|
||||
length -= 3;
|
||||
} else if (extension && strcmp(extension, ".tgz") == 0) {
|
||||
length -= 4;
|
||||
} else {
|
||||
error_msg_and_die("Invalid extension");
|
||||
}
|
||||
of_name = (char *) xcalloc(sizeof(char), length + 1);
|
||||
strncpy(of_name, if_name, length);
|
||||
|
||||
/* Open output file */
|
||||
out_file = xfopen(of_name, "w");
|
||||
|
||||
/* Set permissions on the file */
|
||||
chmod(of_name, stat_buf.st_mode);
|
||||
}
|
||||
|
||||
/* do the decompression, and cleanup */
|
||||
if (unzip(in_file, out_file) == 0) {
|
||||
/* Success, remove .gz file */
|
||||
delete_file_name = if_name;
|
||||
} else {
|
||||
/* remove failed attempt */
|
||||
delete_file_name = of_name;
|
||||
}
|
||||
|
||||
fclose(out_file);
|
||||
fclose(in_file);
|
||||
|
||||
if (delete_old_file == TRUE) {
|
||||
if (unlink(delete_file_name) < 0) {
|
||||
error_msg_and_die("Couldnt remove %s", delete_file_name);
|
||||
}
|
||||
}
|
||||
|
||||
free(of_name);
|
||||
|
||||
return(EXIT_SUCCESS);
|
||||
}
|
|
@ -1,181 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "busybox.h"
|
||||
#ifdef BB_LOCALE_SUPPORT
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
int been_there_done_that = 0; /* Also used in applets.c */
|
||||
const char *applet_name;
|
||||
|
||||
#ifdef BB_FEATURE_INSTALLER
|
||||
/*
|
||||
* directory table
|
||||
* this should be consistent w/ the enum, busybox.h::Location,
|
||||
* or else...
|
||||
*/
|
||||
static char* install_dir[] = {
|
||||
"/",
|
||||
"/bin",
|
||||
"/sbin",
|
||||
"/usr/bin",
|
||||
"/usr/sbin",
|
||||
};
|
||||
|
||||
/* abstract link() */
|
||||
typedef int (*__link_f)(const char *, const char *);
|
||||
|
||||
/*
|
||||
* Where in the filesystem is this busybox?
|
||||
* [return]
|
||||
* malloc'd string w/ full pathname of busybox's location
|
||||
* NULL on failure
|
||||
*/
|
||||
static char *busybox_fullpath()
|
||||
{
|
||||
return xreadlink("/proc/self/exe");
|
||||
}
|
||||
|
||||
/* create (sym)links for each applet */
|
||||
static void install_links(const char *busybox, int use_symbolic_links)
|
||||
{
|
||||
__link_f Link = link;
|
||||
|
||||
char *fpc;
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
if (use_symbolic_links)
|
||||
Link = symlink;
|
||||
|
||||
for (i = 0; applets[i].name != NULL; i++) {
|
||||
fpc = concat_path_file(
|
||||
install_dir[applets[i].location], applets[i].name);
|
||||
rc = Link(busybox, fpc);
|
||||
if (rc!=0 && errno!=EEXIST) {
|
||||
perror_msg("%s", fpc);
|
||||
}
|
||||
free(fpc);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BB_FEATURE_INSTALLER */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
applet_name = argv[0];
|
||||
|
||||
if (applet_name[0] == '-')
|
||||
applet_name++;
|
||||
|
||||
for (s = applet_name; *s != '\0';) {
|
||||
if (*s++ == '/')
|
||||
applet_name = s;
|
||||
}
|
||||
|
||||
#ifdef BB_LOCALE_SUPPORT
|
||||
#ifdef BB_INIT
|
||||
if(getpid()!=1) /* Do not set locale for `init' */
|
||||
#endif
|
||||
{
|
||||
setlocale(LC_ALL, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
run_applet_by_name(applet_name, argc, argv);
|
||||
error_msg_and_die("applet not found");
|
||||
}
|
||||
|
||||
|
||||
int busybox_main(int argc, char **argv)
|
||||
{
|
||||
int col = 0, len, i;
|
||||
|
||||
#ifdef BB_FEATURE_INSTALLER
|
||||
/*
|
||||
* This style of argument parsing doesn't scale well
|
||||
* in the event that busybox starts wanting more --options.
|
||||
* If someone has a cleaner approach, by all means implement it.
|
||||
*/
|
||||
if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
|
||||
int use_symbolic_links = 0;
|
||||
int rc = 0;
|
||||
char *busybox;
|
||||
|
||||
/* to use symlinks, or not to use symlinks... */
|
||||
if (argc > 2) {
|
||||
if ((strcmp(argv[2], "-s") == 0)) {
|
||||
use_symbolic_links = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* link */
|
||||
busybox = busybox_fullpath();
|
||||
if (busybox) {
|
||||
install_links(busybox, use_symbolic_links);
|
||||
free(busybox);
|
||||
} else {
|
||||
rc = 1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif /* BB_FEATURE_INSTALLER */
|
||||
|
||||
argc--;
|
||||
|
||||
/* If we've already been here once, exit now */
|
||||
if (been_there_done_that == 1 || argc < 1) {
|
||||
const struct BB_applet *a = applets;
|
||||
|
||||
fprintf(stderr, "%s\n\n"
|
||||
"Usage: busybox [function] [arguments]...\n"
|
||||
" or: [function] [arguments]...\n\n"
|
||||
"\tBusyBox is a multi-call binary that combines many common Unix\n"
|
||||
"\tutilities into a single executable. Most people will create a\n"
|
||||
"\tlink to busybox for each function they wish to use, and BusyBox\n"
|
||||
"\twill act like whatever it was invoked as.\n"
|
||||
"\nCurrently defined functions:\n", full_version);
|
||||
|
||||
while (a->name != 0) {
|
||||
col +=
|
||||
fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
|
||||
(a++)->name);
|
||||
if (col > 60 && a->name != 0) {
|
||||
fprintf(stderr, ",\n");
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "\n\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Flag that we've been here already */
|
||||
been_there_done_that = 1;
|
||||
|
||||
/* Move the command line down a notch */
|
||||
len = argv[argc] + strlen(argv[argc]) - argv[1];
|
||||
memmove(argv[0], argv[1], len);
|
||||
memset(argv[0] + len, 0, argv[1] - argv[0]);
|
||||
|
||||
/* Fix up the argv pointers */
|
||||
len = argv[1] - argv[0];
|
||||
memmove(argv, argv + 1, sizeof(char *) * (argc + 1));
|
||||
for (i = 0; i < argc; i++)
|
||||
argv[i] -= len;
|
||||
|
||||
return (main(argc, argv));
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "linux"
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
End:
|
||||
*/
|
|
@ -1,24 +0,0 @@
|
|||
#!/bin/sh
|
||||
# Make busybox links list file.
|
||||
|
||||
# input $1: full path to Config.h
|
||||
# input $2: full path to applets.h
|
||||
# output (stdout): list of pathnames that should be linked to busybox
|
||||
|
||||
# Maintainer: Larry Doolittle <ldoolitt@recycle.lbl.gov>
|
||||
|
||||
export LC_ALL=POSIX
|
||||
export LC_CTYPE=POSIX
|
||||
|
||||
CONFIG_H=${1:-Config.h}
|
||||
APPLETS_H=${2:-applets.h}
|
||||
gcc -E -DMAKE_LINKS -include $CONFIG_H $APPLETS_H |
|
||||
awk '/^[ \t]*LINK/{
|
||||
dir=substr($2,8)
|
||||
gsub("_","/",dir)
|
||||
if(dir=="/ROOT") dir=""
|
||||
file=$3
|
||||
gsub("\"","",file)
|
||||
if (file=="busybox") next
|
||||
print tolower(dir) "/" file
|
||||
}'
|
|
@ -1,16 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
export LC_ALL=POSIX
|
||||
export LC_CTYPE=POSIX
|
||||
|
||||
RAW=` \
|
||||
$CC -E -dM ${1:-Config.h} | \
|
||||
sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*\<BB_\(.*\)\>/\1.c/gp;' \
|
||||
| tr A-Z a-z | sort
|
||||
`
|
||||
test "${RAW}" != "" || exit
|
||||
if [ -d "$BB_SRC_DIR" ]; then cd $BB_SRC_DIR; fi
|
||||
# By running $RAW through "ls", we avoid listing
|
||||
# source files that don't exist.
|
||||
ls $RAW 2>/dev/null | tr '\n' ' '
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
%define name busybox
|
||||
%define epoch 0
|
||||
%define version 0.60.2.pre
|
||||
%define release %(date -I | sed -e 's/-/_/g')
|
||||
%define serial 1
|
||||
|
||||
Name: %{name}
|
||||
#Epoch: %{epoch}
|
||||
Version: %{version}
|
||||
Release: %{release}
|
||||
Serial: %{serial}
|
||||
Copyright: GPL
|
||||
Group: System/Utilities
|
||||
Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
|
||||
URL: http://busybox.lineo.com/
|
||||
Source: ftp://oss.lineo.com/busybox/%{name}-%{version}.tar.gz
|
||||
Buildroot: /var/tmp/%{name}-%{version}
|
||||
Packager : Erik Andersen <andersen@lineo.com>
|
||||
|
||||
%Description
|
||||
BusyBox combines tiny versions of many common UNIX utilities into a single
|
||||
small executable. It provides minimalist replacements for most of the utilities
|
||||
you usually find in fileutils, shellutils, findutils, textutils, grep, gzip,
|
||||
tar, etc. BusyBox provides a fairly complete POSIX environment for any small
|
||||
or emdedded system. The utilities in BusyBox generally have fewer options then
|
||||
their full featured GNU cousins; however, the options that are provided behave
|
||||
very much like their GNU counterparts.
|
||||
|
||||
%Prep
|
||||
%setup -q -n %{name}-%{version}
|
||||
|
||||
%Build
|
||||
make
|
||||
|
||||
%Install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make PREFIX=$RPM_BUILD_ROOT install
|
||||
|
||||
%Clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%Files
|
||||
%defattr(-,root,root)
|
||||
/
|
|
@ -1,91 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini chown/chmod/chgrp implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "busybox.h"
|
||||
|
||||
/* Don't use lchown for libc5 or glibc older then 2.1.x */
|
||||
#if (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 1)
|
||||
#define lchown chown
|
||||
#endif
|
||||
|
||||
|
||||
static long gid;
|
||||
|
||||
static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
|
||||
{
|
||||
if (lchown(fileName, statbuf->st_uid, (gid == -1) ? statbuf->st_gid : gid) == 0) {
|
||||
return (TRUE);
|
||||
}
|
||||
perror(fileName);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
int chgrp_main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
int recursiveFlag = FALSE;
|
||||
char *p=NULL;
|
||||
|
||||
/* do normal option parsing */
|
||||
while ((opt = getopt(argc, argv, "R")) > 0) {
|
||||
switch (opt) {
|
||||
case 'R':
|
||||
recursiveFlag = TRUE;
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > optind && argc > 2 && argv[optind]) {
|
||||
/* Find the selected group */
|
||||
gid = strtoul(argv[optind], &p, 10); /* maybe it's already numeric */
|
||||
if (argv[optind] == p)
|
||||
gid = my_getgrnam(argv[optind]);
|
||||
} else {
|
||||
error_msg_and_die(too_few_args);
|
||||
}
|
||||
|
||||
/* Ok, ready to do the deed now */
|
||||
while (++optind < argc) {
|
||||
if (recursive_action (argv[optind], recursiveFlag, FALSE, FALSE,
|
||||
fileAction, fileAction, NULL) == FALSE) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "linux"
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
End:
|
||||
*/
|
|
@ -1,85 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini chown/chmod/chgrp implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include "busybox.h"
|
||||
|
||||
static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
|
||||
{
|
||||
if (!parse_mode((char *)junk, &(statbuf->st_mode)))
|
||||
error_msg_and_die("internal error");
|
||||
if (chmod(fileName, statbuf->st_mode) == 0)
|
||||
return (TRUE);
|
||||
perror(fileName);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
int chmod_main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int opt;
|
||||
int recursiveFlag = FALSE;
|
||||
|
||||
/* do normal option parsing */
|
||||
while ((opt = getopt(argc, argv, "R")) > 0) {
|
||||
switch (opt) {
|
||||
case 'R':
|
||||
recursiveFlag = TRUE;
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > optind && argc > 2 && argv[optind]) {
|
||||
/* Parse the specified mode */
|
||||
mode_t mode;
|
||||
if (parse_mode(argv[optind], &mode) == FALSE) {
|
||||
error_msg_and_die( "unknown mode: %s", argv[optind]);
|
||||
}
|
||||
} else {
|
||||
error_msg_and_die(too_few_args);
|
||||
}
|
||||
|
||||
/* Ok, ready to do the deed now */
|
||||
for (i = optind + 1; i < argc; i++) {
|
||||
if (recursive_action (argv[i], recursiveFlag, FALSE, FALSE, fileAction,
|
||||
fileAction, argv[optind]) == FALSE) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "linux"
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
End:
|
||||
*/
|
113
busybox/chown.c
|
@ -1,113 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini chown/chmod/chgrp implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "busybox.h"
|
||||
|
||||
/* Don't use lchown for libc5 or glibc older then 2.1.x */
|
||||
#if (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 1)
|
||||
#define lchown chown
|
||||
#endif
|
||||
|
||||
static long uid;
|
||||
static long gid;
|
||||
|
||||
static int (*chown_func)(const char *, __uid_t, __gid_t) = chown;
|
||||
|
||||
static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
|
||||
{
|
||||
if (chown_func(fileName, uid, (gid == -1) ? statbuf->st_gid : gid) == 0) {
|
||||
return (TRUE);
|
||||
}
|
||||
perror(fileName);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
int chown_main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
int recursiveFlag = FALSE,
|
||||
noderefFlag = FALSE;
|
||||
char *groupName=NULL;
|
||||
char *p=NULL;
|
||||
|
||||
/* do normal option parsing */
|
||||
while ((opt = getopt(argc, argv, "Rh")) > 0) {
|
||||
switch (opt) {
|
||||
case 'R':
|
||||
recursiveFlag = TRUE;
|
||||
break;
|
||||
case 'h':
|
||||
noderefFlag = TRUE;
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (noderefFlag) chown_func = lchown;
|
||||
|
||||
if (argc > optind && argc > 2 && argv[optind]) {
|
||||
/* First, check if there is a group name here */
|
||||
groupName = strchr(argv[optind], '.');
|
||||
if (groupName == NULL)
|
||||
groupName = strchr(argv[optind], ':');
|
||||
if (groupName) {
|
||||
*groupName++ = '\0';
|
||||
gid = strtoul(groupName, &p, 10);
|
||||
if (groupName == p)
|
||||
gid = my_getgrnam(groupName);
|
||||
} else {
|
||||
gid = -1;
|
||||
}
|
||||
/* Now check for the username */
|
||||
uid = strtoul(argv[optind], &p, 10); /* Is is numeric? */
|
||||
if (argv[optind] == p) {
|
||||
uid = my_getpwnam(argv[optind]);
|
||||
}
|
||||
} else {
|
||||
error_msg_and_die(too_few_args);
|
||||
}
|
||||
|
||||
/* Ok, ready to do the deed now */
|
||||
while (++optind < argc) {
|
||||
if (recursive_action (argv[optind], recursiveFlag, FALSE, FALSE,
|
||||
fileAction, fileAction, NULL) == FALSE) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "linux"
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
End:
|
||||
*/
|
|
@ -1,75 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini chroot implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "busybox.h"
|
||||
|
||||
int chroot_main(int argc, char **argv)
|
||||
{
|
||||
char *prog;
|
||||
|
||||
if ((argc < 2) || (**(argv + 1) == '-')) {
|
||||
show_usage();
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (chroot(*argv) || (chdir("/"))) {
|
||||
perror_msg_and_die("cannot change root directory to %s", *argv);
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
if (argc >= 1) {
|
||||
prog = *argv;
|
||||
execvp(*argv, argv);
|
||||
} else {
|
||||
#if defined shell_main && defined BB_FEATURE_SH_STANDALONE_SHELL
|
||||
char shell[] = "/bin/sh";
|
||||
char *shell_argv[2] = { shell, NULL };
|
||||
applet_name = shell;
|
||||
shell_main(1, shell_argv);
|
||||
return EXIT_SUCCESS;
|
||||
#else
|
||||
prog = getenv("SHELL");
|
||||
if (!prog)
|
||||
prog = "/bin/sh";
|
||||
execlp(prog, prog, NULL);
|
||||
#endif
|
||||
}
|
||||
perror_msg_and_die("cannot execute %s", prog);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "linux"
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
End:
|
||||
*/
|
|
@ -1,43 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* chvt.c - aeb - 940227 - Change virtual terminal
|
||||
*
|
||||
* busyboxed by Erik Andersen
|
||||
*/
|
||||
|
||||
/* getopt not needed */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "busybox.h"
|
||||
|
||||
/* From <linux/vt.h> */
|
||||
static const int VT_ACTIVATE = 0x5606; /* make vt active */
|
||||
static const int VT_WAITACTIVE = 0x5607; /* wait for vt active */
|
||||
|
||||
int chvt_main(int argc, char **argv)
|
||||
{
|
||||
int fd, num;
|
||||
|
||||
if ((argc != 2) || (**(argv + 1) == '-'))
|
||||
show_usage();
|
||||
fd = get_console_fd("/dev/console");
|
||||
num = atoi(argv[1]);
|
||||
if (ioctl(fd, VT_ACTIVATE, num))
|
||||
perror_msg_and_die("VT_ACTIVATE");
|
||||
if (ioctl(fd, VT_WAITACTIVE, num))
|
||||
perror_msg_and_die("VT_WAITACTIVE");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "linux"
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
End:
|
||||
*/
|
|
@ -1,6 +0,0 @@
|
|||
#ifndef CMDEDIT_H
|
||||
#define CMDEDIT_H
|
||||
|
||||
int cmdedit_read_input(char* promptStr, char* command);
|
||||
|
||||
#endif /* CMDEDIT_H */
|
|
@ -1,34 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini clear implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "busybox.h"
|
||||
|
||||
|
||||
extern int clear_main(int argc, char **argv)
|
||||
{
|
||||
printf("\033[H\033[J");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini reset implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
|
||||
* and Kent Robotti <robotti@metconnect.com>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "busybox.h"
|
||||
|
||||
extern int reset_main(int argc, char **argv)
|
||||
{
|
||||
printf("\033c");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* setkeycodes
|
||||
*
|
||||
* Copyright (C) 1994-1998 Andries E. Brouwer <aeb@cwi.nl>
|
||||
*
|
||||
* Adjusted for BusyBox by Erik Andersen <andersee@debian.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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "busybox.h"
|
||||
|
||||
|
||||
/* From <linux/kd.h> */
|
||||
struct kbkeycode {
|
||||
unsigned int scancode, keycode;
|
||||
};
|
||||
static const int KDSETKEYCODE = 0x4B4D; /* write kernel keycode table entry */
|
||||
|
||||
extern int
|
||||
setkeycodes_main(int argc, char** argv)
|
||||
{
|
||||
char *ep;
|
||||
int fd, sc;
|
||||
struct kbkeycode a;
|
||||
|
||||
if (argc % 2 != 1 || argc < 2) {
|
||||
show_usage();
|
||||
}
|
||||
|
||||
fd = get_console_fd("/dev/console");
|
||||
|
||||
while (argc > 2) {
|
||||
a.keycode = atoi(argv[2]);
|
||||
a.scancode = sc = strtol(argv[1], &ep, 16);
|
||||
if (*ep) {
|
||||
error_msg_and_die("error reading SCANCODE: '%s'", argv[1]);
|
||||
}
|
||||
if (a.scancode > 127) {
|
||||
a.scancode -= 0xe000;
|
||||
a.scancode += 128;
|
||||
}
|
||||
if (a.scancode > 255 || a.keycode > 127) {
|
||||
error_msg_and_die("SCANCODE or KEYCODE outside bounds");
|
||||
}
|
||||
if (ioctl(fd,KDSETKEYCODE,&a)) {
|
||||
perror("KDSETKEYCODE");
|
||||
error_msg_and_die("failed to set SCANCODE %x to KEYCODE %d", sc, a.keycode);
|
||||
}
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini cmp implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Matt Kraai <kraai@alumni.carnegiemellon.edu>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include "busybox.h"
|
||||
|
||||
int cmp_main(int argc, char **argv)
|
||||
{
|
||||
FILE *fp1 = NULL, *fp2 = stdin;
|
||||
char *filename1, *filename2 = "-";
|
||||
int c, c1, c2, char_pos = 1, line_pos = 1, silent = FALSE;
|
||||
|
||||
while ((c = getopt(argc, argv, "s")) != EOF) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
silent = TRUE;
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
filename1 = argv[optind];
|
||||
switch (argc - optind) {
|
||||
case 2:
|
||||
fp2 = xfopen(filename2 = argv[optind + 1], "r");
|
||||
case 1:
|
||||
fp1 = xfopen(filename1, "r");
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
|
||||
do {
|
||||
c1 = fgetc(fp1);
|
||||
c2 = fgetc(fp2);
|
||||
if (c1 != c2) {
|
||||
if (silent)
|
||||
return EXIT_FAILURE;
|
||||
if (c1 == EOF)
|
||||
printf("EOF on %s\n", filename1);
|
||||
else if (c2 == EOF)
|
||||
printf("EOF on %s\n", filename2);
|
||||
else
|
||||
printf("%s %s differ: char %d, line %d\n", filename1, filename2,
|
||||
char_pos, line_pos);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
char_pos++;
|
||||
if (c1 == '\n')
|
||||
line_pos++;
|
||||
} while (c1 != EOF);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini cp implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
|
||||
*
|
||||
* 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 <fcntl.h>
|
||||
#include <utime.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "busybox.h"
|
||||
|
||||
extern int cp_main(int argc, char **argv)
|
||||
{
|
||||
int status = 0;
|
||||
int opt;
|
||||
int flags = 0;
|
||||
int i;
|
||||
|
||||
while ((opt = getopt(argc, argv, "adfipR")) != -1)
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
flags |= FILEUTILS_PRESERVE_STATUS | FILEUTILS_RECUR;
|
||||
/* fallthrough */
|
||||
case 'd':
|
||||
flags |= FILEUTILS_PRESERVE_SYMLINKS;
|
||||
break;
|
||||
case 'f':
|
||||
flags |= FILEUTILS_FORCE;
|
||||
break;
|
||||
case 'i':
|
||||
flags |= FILEUTILS_INTERACTIVE;
|
||||
break;
|
||||
case 'p':
|
||||
flags |= FILEUTILS_PRESERVE_STATUS;
|
||||
break;
|
||||
case 'R':
|
||||
flags |= FILEUTILS_RECUR;
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
|
||||
if (optind + 2 > argc)
|
||||
show_usage();
|
||||
|
||||
/* If there are only two arguments and... */
|
||||
if (optind + 2 == argc) {
|
||||
struct stat source_stat;
|
||||
struct stat dest_stat;
|
||||
int source_exists = 1;
|
||||
int dest_exists = 1;
|
||||
|
||||
if (((flags & FILEUTILS_PRESERVE_SYMLINKS) &&
|
||||
lstat(argv[optind], &source_stat) < 0) ||
|
||||
(!(flags & FILEUTILS_PRESERVE_SYMLINKS) &&
|
||||
stat(argv[optind], &source_stat))) {
|
||||
if (errno != ENOENT)
|
||||
perror_msg_and_die("unable to stat `%s'", argv[optind]);
|
||||
source_exists = 0;
|
||||
}
|
||||
|
||||
if (stat(argv[optind + 1], &dest_stat) < 0) {
|
||||
if (errno != ENOENT)
|
||||
perror_msg_and_die("unable to stat `%s'", argv[optind + 1]);
|
||||
dest_exists = 0;
|
||||
}
|
||||
|
||||
/* ...if neither is a directory or... */
|
||||
if (((!source_exists || !S_ISDIR(source_stat.st_mode)) &&
|
||||
(!dest_exists || !S_ISDIR(dest_stat.st_mode))) ||
|
||||
/* ...recursing, the first is a directory, and the
|
||||
* second doesn't exist, then... */
|
||||
((flags & FILEUTILS_RECUR) && S_ISDIR(source_stat.st_mode) &&
|
||||
!dest_exists)) {
|
||||
/* ...do a simple copy. */
|
||||
if (copy_file(argv[optind], argv[optind + 1], flags) < 0)
|
||||
status = 1;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = optind; i < argc - 1; i++) {
|
||||
char *dest = concat_path_file(argv[argc - 1],
|
||||
get_last_path_component(argv[i]));
|
||||
if (copy_file(argv[i], dest, flags) < 0)
|
||||
status = 1;
|
||||
free(dest);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
|
@ -1,356 +0,0 @@
|
|||
/*
|
||||
* cut.c - minimalist version of cut
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Mark Whitley <markw@lineo.com>, <markw@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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h> /* getopt */
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "busybox.h"
|
||||
|
||||
|
||||
/* globals from other files */
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
|
||||
/* option vars */
|
||||
static char part = 0; /* (b)yte, (c)har, (f)ields */
|
||||
static unsigned int supress_non_delimited_lines = 0;
|
||||
static char delim = '\t'; /* delimiter, default is tab */
|
||||
|
||||
struct cut_list {
|
||||
int startpos;
|
||||
int endpos;
|
||||
};
|
||||
|
||||
static const int BOL = 0;
|
||||
static const int EOL = INT_MAX;
|
||||
static const int NON_RANGE = -1;
|
||||
|
||||
static struct cut_list *cut_lists = NULL; /* growable array holding a series of lists */
|
||||
static unsigned int nlists = 0; /* number of elements in above list */
|
||||
|
||||
|
||||
static int cmpfunc(const void *a, const void *b)
|
||||
{
|
||||
struct cut_list *la = (struct cut_list *)a;
|
||||
struct cut_list *lb = (struct cut_list *)b;
|
||||
|
||||
if (la->startpos > lb->startpos)
|
||||
return 1;
|
||||
if (la->startpos < lb->startpos)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* parse_lists() - parses a list and puts values into startpos and endpos.
|
||||
* valid list formats: N, N-, N-M, -M
|
||||
* more than one list can be seperated by commas
|
||||
*/
|
||||
static void parse_lists(char *lists)
|
||||
{
|
||||
char *ltok = NULL;
|
||||
char *ntok = NULL;
|
||||
char *junk;
|
||||
int s = 0, e = 0;
|
||||
|
||||
/* take apart the lists, one by one (they are seperated with commas */
|
||||
while ((ltok = strsep(&lists, ",")) != NULL) {
|
||||
|
||||
/* it's actually legal to pass an empty list */
|
||||
if (strlen(ltok) == 0)
|
||||
continue;
|
||||
|
||||
/* get the start pos */
|
||||
ntok = strsep(<ok, "-");
|
||||
if (ntok == NULL) {
|
||||
fprintf(stderr, "Help ntok is null for starting position! What do I do?\n");
|
||||
} else if (strlen(ntok) == 0) {
|
||||
s = BOL;
|
||||
} else {
|
||||
s = strtoul(ntok, &junk, 10);
|
||||
if(*junk != '\0' || s < 0)
|
||||
error_msg_and_die("invalid byte or field list");
|
||||
|
||||
/* 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(<ok, "-");
|
||||
if (ntok == NULL) {
|
||||
e = NON_RANGE;
|
||||
} else if (strlen(ntok) == 0) {
|
||||
e = EOL;
|
||||
} else {
|
||||
e = strtoul(ntok, &junk, 10);
|
||||
if(*junk != '\0' || e < 0)
|
||||
error_msg_and_die("invalid byte or field list");
|
||||
/* if the user specified and end position of 0, that means "til the
|
||||
* end of the line */
|
||||
if (e == 0)
|
||||
e = INT_MAX;
|
||||
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 past an invalid list */
|
||||
if (ltok)
|
||||
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)
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void cut_line_by_chars(const char *line)
|
||||
{
|
||||
int c, l;
|
||||
/* set up a list so we can keep track of what's been printed */
|
||||
char *printed = xcalloc(strlen(line), sizeof(char));
|
||||
|
||||
/* print the chars specified in each cut list */
|
||||
for (c = 0; c < nlists; c++) {
|
||||
l = cut_lists[c].startpos;
|
||||
while (l < strlen(line)) {
|
||||
if (!printed[l]) {
|
||||
putchar(line[l]);
|
||||
printed[l] = 'X';
|
||||
}
|
||||
l++;
|
||||
if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos)
|
||||
break;
|
||||
}
|
||||
}
|
||||
putchar('\n'); /* cuz we were handed a chomped line */
|
||||
free(printed);
|
||||
}
|
||||
|
||||
|
||||
static void cut_line_by_fields(char *line)
|
||||
{
|
||||
int c, f;
|
||||
int ndelim = -1; /* zero-based / one-based problem */
|
||||
int nfields_printed = 0;
|
||||
char *field = NULL;
|
||||
char d[2] = { delim, 0 };
|
||||
char *printed;
|
||||
|
||||
/* test the easy case first: does this line contain any delimiters? */
|
||||
if (strchr(line, delim) == NULL) {
|
||||
if (!supress_non_delimited_lines)
|
||||
puts(line);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set up a list so we can keep track of what's been printed */
|
||||
printed = xcalloc(strlen(line), sizeof(char));
|
||||
|
||||
/* process each list on this line, for as long as we've got a line to process */
|
||||
for (c = 0; c < nlists && line; c++) {
|
||||
f = cut_lists[c].startpos;
|
||||
do {
|
||||
|
||||
/* find the field we're looking for */
|
||||
while (line && ndelim < f) {
|
||||
field = strsep(&line, d);
|
||||
ndelim++;
|
||||
}
|
||||
|
||||
/* we found it, and it hasn't been printed yet */
|
||||
if (field && ndelim == f && !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++;
|
||||
}
|
||||
|
||||
f++;
|
||||
|
||||
/* 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 (line && cut_lists[c].endpos != NON_RANGE && f <= cut_lists[c].endpos);
|
||||
}
|
||||
|
||||
/* if we printed anything at all, we need to finish it with a newline cuz
|
||||
* we were handed a chomped line */
|
||||
putchar('\n');
|
||||
|
||||
free(printed);
|
||||
}
|
||||
|
||||
|
||||
static void cut_file_by_lines(const char *line, unsigned int linenum)
|
||||
{
|
||||
static int c = 0;
|
||||
static int l = -1;
|
||||
|
||||
/* I can't initialize this above cuz the "initializer isn't
|
||||
* constant" *sigh* */
|
||||
if (l == -1)
|
||||
l = cut_lists[c].startpos;
|
||||
|
||||
/* get out if we have no more lists to process or if the lines are lower
|
||||
* than what we're interested in */
|
||||
if (c >= nlists || linenum < l)
|
||||
return;
|
||||
|
||||
/* 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 (l < linenum) {
|
||||
l++;
|
||||
/* move on to the next list if we're at the end of this one */
|
||||
if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos) {
|
||||
c++;
|
||||
/* get out if there's no more lists to process */
|
||||
if (c >= nlists)
|
||||
return;
|
||||
l = cut_lists[c].startpos;
|
||||
/* get out if the current line is lower than the one we just became
|
||||
* interested in */
|
||||
if (linenum < l)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we made it here, it means we've found the line we're looking for, so print it */
|
||||
puts(line);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* snippy-snip
|
||||
*/
|
||||
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 = get_line_from_file(file)) != NULL) {
|
||||
chomp(line);
|
||||
|
||||
/* cut based on chars/bytes XXX: only works when sizeof(char) == byte */
|
||||
if (part == 'c' || part == 'b')
|
||||
cut_line_by_chars(line);
|
||||
|
||||
/* cut based on fields */
|
||||
else if (part == 'f') {
|
||||
if (delim == '\n')
|
||||
cut_file_by_lines(line, linenum);
|
||||
else
|
||||
cut_line_by_fields(line);
|
||||
}
|
||||
|
||||
linenum++;
|
||||
free(line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern int cut_main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
|
||||
while ((opt = getopt(argc, argv, "b:c:d:f:ns")) > 0) {
|
||||
switch (opt) {
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'f':
|
||||
/* make sure they didn't ask for two types of lists */
|
||||
if (part != 0) {
|
||||
error_msg_and_die("only one type of list may be specified");
|
||||
}
|
||||
part = (char)opt;
|
||||
parse_lists(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
if (strlen(optarg) > 1) {
|
||||
error_msg_and_die("the delimiter must be a single character");
|
||||
}
|
||||
delim = optarg[0];
|
||||
break;
|
||||
case 'n':
|
||||
/* no-op */
|
||||
break;
|
||||
case 's':
|
||||
supress_non_delimited_lines++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (part == 0) {
|
||||
error_msg_and_die("you must specify a list of bytes, characters, or fields");
|
||||
}
|
||||
|
||||
/* non-field (char or byte) cutting has some special handling */
|
||||
if (part != 'f') {
|
||||
if (supress_non_delimited_lines) {
|
||||
error_msg_and_die("suppressing non-delimited lines makes sense"
|
||||
" only when operating on fields");
|
||||
}
|
||||
if (delim != '\t' && part != 'f') {
|
||||
error_msg_and_die("a delimiter may be specified only when operating on fields");
|
||||
}
|
||||
}
|
||||
|
||||
/* argv[(optind)..(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[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
|
||||
cut_file(stdin);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
FILE *file;
|
||||
for (i = optind; i < argc; i++) {
|
||||
file = wfopen(argv[i], "r");
|
||||
if(file) {
|
||||
cut_file(file);
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,257 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini du implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by John Beppu <beppu@lineo.com>
|
||||
*
|
||||
* 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 <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "busybox.h"
|
||||
|
||||
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
static unsigned long disp_hr = KILOBYTE;
|
||||
#endif
|
||||
|
||||
typedef void (Display) (long, char *);
|
||||
|
||||
static int du_depth = 0;
|
||||
static int count_hardlinks = 0;
|
||||
|
||||
static Display *print;
|
||||
|
||||
static void print_normal(long size, char *filename)
|
||||
{
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
printf("%s\t%s\n", make_human_readable_str(size<<10, 1, disp_hr), filename);
|
||||
#else
|
||||
printf("%ld\t%s\n", size, filename);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void print_summary(long size, char *filename)
|
||||
{
|
||||
if (du_depth == 1) {
|
||||
print_normal(size, filename);
|
||||
}
|
||||
}
|
||||
|
||||
#define HASH_SIZE 311 /* Should be prime */
|
||||
#define hash_inode(i) ((i) % HASH_SIZE)
|
||||
|
||||
typedef struct ino_dev_hash_bucket_struct {
|
||||
struct ino_dev_hash_bucket_struct *next;
|
||||
ino_t ino;
|
||||
dev_t dev;
|
||||
char name[1];
|
||||
} ino_dev_hashtable_bucket_t;
|
||||
|
||||
static ino_dev_hashtable_bucket_t *ino_dev_hashtable[HASH_SIZE];
|
||||
|
||||
/*
|
||||
* Return 1 if statbuf->st_ino && statbuf->st_dev are recorded in
|
||||
* `ino_dev_hashtable', else return 0
|
||||
*
|
||||
* If NAME is a non-NULL pointer to a character pointer, and there is
|
||||
* a match, then set *NAME to the value of the name slot in that
|
||||
* bucket.
|
||||
*/
|
||||
static int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name)
|
||||
{
|
||||
ino_dev_hashtable_bucket_t *bucket;
|
||||
|
||||
bucket = ino_dev_hashtable[hash_inode(statbuf->st_ino)];
|
||||
while (bucket != NULL) {
|
||||
if ((bucket->ino == statbuf->st_ino) &&
|
||||
(bucket->dev == statbuf->st_dev))
|
||||
{
|
||||
if (name) *name = bucket->name;
|
||||
return 1;
|
||||
}
|
||||
bucket = bucket->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add statbuf to statbuf hash table */
|
||||
static void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name)
|
||||
{
|
||||
int i;
|
||||
size_t s;
|
||||
ino_dev_hashtable_bucket_t *bucket;
|
||||
|
||||
i = hash_inode(statbuf->st_ino);
|
||||
s = name ? strlen(name) : 0;
|
||||
bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + s);
|
||||
bucket->ino = statbuf->st_ino;
|
||||
bucket->dev = statbuf->st_dev;
|
||||
if (name)
|
||||
strcpy(bucket->name, name);
|
||||
else
|
||||
bucket->name[0] = '\0';
|
||||
bucket->next = ino_dev_hashtable[i];
|
||||
ino_dev_hashtable[i] = bucket;
|
||||
}
|
||||
|
||||
/* Clear statbuf hash table */
|
||||
static void reset_ino_dev_hashtable(void)
|
||||
{
|
||||
int i;
|
||||
ino_dev_hashtable_bucket_t *bucket;
|
||||
|
||||
for (i = 0; i < HASH_SIZE; i++) {
|
||||
while (ino_dev_hashtable[i] != NULL) {
|
||||
bucket = ino_dev_hashtable[i]->next;
|
||||
free(ino_dev_hashtable[i]);
|
||||
ino_dev_hashtable[i] = bucket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* tiny recursive du */
|
||||
static long du(char *filename)
|
||||
{
|
||||
struct stat statbuf;
|
||||
long sum;
|
||||
|
||||
if ((lstat(filename, &statbuf)) != 0) {
|
||||
perror_msg("%s", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
du_depth++;
|
||||
sum = (statbuf.st_blocks >> 1);
|
||||
|
||||
/* Don't add in stuff pointed to by symbolic links */
|
||||
if (S_ISLNK(statbuf.st_mode)) {
|
||||
sum = 0L;
|
||||
if (du_depth == 1) {
|
||||
}
|
||||
}
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
char *newfile;
|
||||
|
||||
dir = opendir(filename);
|
||||
if (!dir) {
|
||||
du_depth--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
newfile = last_char_is(filename, '/');
|
||||
if (newfile)
|
||||
*newfile = '\0';
|
||||
|
||||
while ((entry = readdir(dir))) {
|
||||
char *name = entry->d_name;
|
||||
|
||||
if ((strcmp(name, "..") == 0)
|
||||
|| (strcmp(name, ".") == 0)) {
|
||||
continue;
|
||||
}
|
||||
newfile = concat_path_file(filename, name);
|
||||
sum += du(newfile);
|
||||
free(newfile);
|
||||
}
|
||||
closedir(dir);
|
||||
print(sum, filename);
|
||||
}
|
||||
else if (statbuf.st_nlink > 1 && !count_hardlinks) {
|
||||
/* Add files with hard links only once */
|
||||
if (is_in_ino_dev_hashtable(&statbuf, NULL)) {
|
||||
sum = 0L;
|
||||
if (du_depth == 1)
|
||||
print(sum, filename);
|
||||
}
|
||||
else {
|
||||
add_to_ino_dev_hashtable(&statbuf, NULL);
|
||||
}
|
||||
}
|
||||
du_depth--;
|
||||
return sum;
|
||||
}
|
||||
|
||||
int du_main(int argc, char **argv)
|
||||
{
|
||||
int status = EXIT_SUCCESS;
|
||||
int i;
|
||||
int c;
|
||||
|
||||
/* default behaviour */
|
||||
print = print_normal;
|
||||
|
||||
/* parse argv[] */
|
||||
while ((c = getopt(argc, argv, "sl"
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
"hm"
|
||||
#endif
|
||||
"k")) != EOF) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
print = print_summary;
|
||||
break;
|
||||
case 'l':
|
||||
count_hardlinks = 1;
|
||||
break;
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
case 'h': disp_hr = 0; break;
|
||||
case 'm': disp_hr = MEGABYTE; break;
|
||||
#endif
|
||||
case 'k': break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
/* go through remaining args (if any) */
|
||||
if (optind >= argc) {
|
||||
if (du(".") == 0)
|
||||
status = EXIT_FAILURE;
|
||||
} else {
|
||||
long sum;
|
||||
|
||||
for (i=optind; i < argc; i++) {
|
||||
sum = du(argv[i]);
|
||||
if(is_directory(argv[i], FALSE, NULL)==FALSE) {
|
||||
print_normal(sum, argv[i]);
|
||||
}
|
||||
reset_ino_dev_hashtable();
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* $Id: du.c,v 1.50 2001/06/30 17:54:20 andersen Exp $ */
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "linux"
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
End:
|
||||
*/
|
|
@ -1,106 +0,0 @@
|
|||
/* 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.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Original copyright notice is retained at the end of this file.
|
||||
*
|
||||
* Modified for BusyBox by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "busybox.h"
|
||||
|
||||
extern int env_main(int argc, char** argv)
|
||||
{
|
||||
char **ep, *p;
|
||||
char *cleanenv[1];
|
||||
int ignore_environment = 0;
|
||||
int ch;
|
||||
|
||||
while ((ch = getopt(argc, argv, "+iu:")) != -1) {
|
||||
switch(ch) {
|
||||
case 'i':
|
||||
ignore_environment = 1;
|
||||
break;
|
||||
case 'u':
|
||||
unsetenv(optarg);
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
if (optind != argc && !strcmp(argv[optind], "-")) {
|
||||
ignore_environment = 1;
|
||||
argv++;
|
||||
}
|
||||
if (ignore_environment) {
|
||||
environ = cleanenv;
|
||||
cleanenv[0] = NULL;
|
||||
}
|
||||
for (argv += optind; *argv && (p = strchr(*argv, '=')); ++argv)
|
||||
if (putenv(*argv) < 0)
|
||||
perror_msg_and_die("%s", *argv);
|
||||
if (*argv) {
|
||||
execvp(*argv, argv);
|
||||
perror_msg_and_die("%s", *argv);
|
||||
}
|
||||
for (ep = environ; *ep; ep++)
|
||||
puts(*ep);
|
||||
return 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.
|
||||
*/
|
||||
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini head implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by John Beppu <beppu@lineo.com>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "busybox.h"
|
||||
|
||||
static int head(int len, FILE *fp)
|
||||
{
|
||||
int i;
|
||||
char *input;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if ((input = get_line_from_file(fp)) == NULL)
|
||||
break;
|
||||
fputs(input, stdout);
|
||||
free(input);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* BusyBoxed head(1) */
|
||||
int head_main(int argc, char **argv)
|
||||
{
|
||||
FILE *fp;
|
||||
int need_headers, opt, len = 10, status = EXIT_SUCCESS;
|
||||
|
||||
/* parse argv[] */
|
||||
while ((opt = getopt(argc, argv, "n:")) > 0) {
|
||||
switch (opt) {
|
||||
case 'n':
|
||||
len = atoi(optarg);
|
||||
if (len >= 1)
|
||||
break;
|
||||
/* fallthrough */
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
/* get rest of argv[] or stdin if nothing's left */
|
||||
if (argv[optind] == NULL) {
|
||||
head(len, stdin);
|
||||
return status;
|
||||
}
|
||||
|
||||
need_headers = optind != (argc - 1);
|
||||
while (argv[optind]) {
|
||||
if (strcmp(argv[optind], "-") == 0) {
|
||||
fp = stdin;
|
||||
argv[optind] = "standard input";
|
||||
} else {
|
||||
if ((fp = wfopen(argv[optind], "r")) == NULL)
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
if (fp) {
|
||||
if (need_headers) {
|
||||
printf("==> %s <==\n", argv[optind]);
|
||||
}
|
||||
head(len, fp);
|
||||
if (ferror(fp)) {
|
||||
perror_msg("%s", argv[optind]);
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
if (optind < argc - 1)
|
||||
putchar('\n');
|
||||
if (fp != stdin)
|
||||
fclose(fp);
|
||||
}
|
||||
optind++;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
|
@ -1,937 +0,0 @@
|
|||
/* 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>
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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?
|
||||
*/
|
||||
|
||||
enum {
|
||||
TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */
|
||||
COLUMN_WIDTH = 14, /* default if AUTOWIDTH not defined */
|
||||
COLUMN_GAP = 2, /* includes the file type char */
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "busybox.h"
|
||||
|
||||
#ifdef BB_FEATURE_LS_TIMESTAMPS
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAJOR
|
||||
#define MAJOR(dev) (((dev)>>8)&0xff)
|
||||
#define MINOR(dev) ((dev)&0xff)
|
||||
#endif
|
||||
|
||||
/* what is the overall style of the listing */
|
||||
enum {
|
||||
STYLE_AUTO = 0,
|
||||
STYLE_LONG = 1, /* one record per line, extended info */
|
||||
STYLE_SINGLE = 2, /* one record per line */
|
||||
STYLE_COLUMNS = 3 /* fill columns */
|
||||
};
|
||||
|
||||
/* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */
|
||||
/* what file information will be listed */
|
||||
#define LIST_INO (1<<0)
|
||||
#define LIST_BLOCKS (1<<1)
|
||||
#define LIST_MODEBITS (1<<2)
|
||||
#define LIST_NLINKS (1<<3)
|
||||
#define LIST_ID_NAME (1<<4)
|
||||
#define LIST_ID_NUMERIC (1<<5)
|
||||
#define LIST_SIZE (1<<6)
|
||||
#define LIST_DEV (1<<7)
|
||||
#define LIST_DATE_TIME (1<<8)
|
||||
#define LIST_FULLTIME (1<<9)
|
||||
#define LIST_FILENAME (1<<10)
|
||||
#define LIST_SYMLINK (1<<11)
|
||||
#define LIST_FILETYPE (1<<12)
|
||||
#define LIST_EXEC (1<<13)
|
||||
|
||||
/* what files will be displayed */
|
||||
#define DISP_NORMAL (0) /* show normal filenames */
|
||||
#define DISP_DIRNAME (1<<0) /* 2 or more items? label directories */
|
||||
#define DISP_HIDDEN (1<<1) /* show filenames starting with . */
|
||||
#define DISP_DOT (1<<2) /* show . and .. */
|
||||
#define DISP_NOLIST (1<<3) /* show directory as itself, not contents */
|
||||
#define DISP_RECURSIVE (1<<4) /* show directory and everything below it */
|
||||
#define DISP_ROWS (1<<5) /* print across rows */
|
||||
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
/* how will the files be sorted */
|
||||
static const int SORT_FORWARD = 0; /* sort in reverse order */
|
||||
static const int SORT_REVERSE = 1; /* sort in reverse order */
|
||||
static const int SORT_NAME = 2; /* sort by file name */
|
||||
static const int SORT_SIZE = 3; /* sort by file size */
|
||||
static const int SORT_ATIME = 4; /* sort by last access time */
|
||||
static const int SORT_CTIME = 5; /* sort by last change time */
|
||||
static const int SORT_MTIME = 6; /* sort by last modification time */
|
||||
static const int SORT_VERSION = 7; /* sort by version */
|
||||
static const int SORT_EXT = 8; /* sort by file name extension */
|
||||
static const int SORT_DIR = 9; /* sort by file or directory */
|
||||
#endif
|
||||
|
||||
#ifdef BB_FEATURE_LS_TIMESTAMPS
|
||||
/* which of the three times will be used */
|
||||
static const int TIME_MOD = 0;
|
||||
static const int TIME_CHANGE = 1;
|
||||
static const int TIME_ACCESS = 2;
|
||||
#endif
|
||||
|
||||
#define LIST_SHORT (LIST_FILENAME)
|
||||
#define LIST_ISHORT (LIST_INO | LIST_FILENAME)
|
||||
#define LIST_LONG (LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | \
|
||||
LIST_SIZE | LIST_DATE_TIME | LIST_FILENAME | \
|
||||
LIST_SYMLINK)
|
||||
#define LIST_ILONG (LIST_INO | LIST_LONG)
|
||||
|
||||
static const int SPLIT_DIR = 0;
|
||||
static const int SPLIT_FILE = 1;
|
||||
static const int SPLIT_SUBDIR = 2;
|
||||
|
||||
#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f)
|
||||
#define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)])
|
||||
#ifdef BB_FEATURE_LS_FILETYPES
|
||||
#define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)])
|
||||
#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 */
|
||||
struct stat dstat; /* the file stat info */
|
||||
struct dnode *next; /* point at the next node */
|
||||
};
|
||||
typedef struct dnode dnode_t;
|
||||
|
||||
static struct dnode **list_dir(char *);
|
||||
static struct dnode **dnalloc(int);
|
||||
static int list_single(struct dnode *);
|
||||
|
||||
static unsigned int disp_opts;
|
||||
static unsigned int style_fmt;
|
||||
static unsigned int list_fmt;
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
static unsigned int sort_opts;
|
||||
static unsigned int sort_order;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_TIMESTAMPS
|
||||
static unsigned int time_fmt;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_FOLLOWLINKS
|
||||
static unsigned int follow_links=FALSE;
|
||||
#endif
|
||||
|
||||
static unsigned short column = 0;
|
||||
#ifdef BB_FEATURE_AUTOWIDTH
|
||||
static unsigned short terminal_width = TERMINAL_WIDTH;
|
||||
static unsigned short column_width = COLUMN_WIDTH;
|
||||
static unsigned short tabstops = COLUMN_GAP;
|
||||
#else
|
||||
static unsigned short column_width = COLUMN_WIDTH;
|
||||
#endif
|
||||
|
||||
static int status = EXIT_SUCCESS;
|
||||
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
static unsigned long ls_disp_hr = 0;
|
||||
#endif
|
||||
|
||||
static int my_stat(struct dnode *cur)
|
||||
{
|
||||
#ifdef BB_FEATURE_LS_FOLLOWLINKS
|
||||
if (follow_links == TRUE) {
|
||||
if (stat(cur->fullname, &cur->dstat)) {
|
||||
perror_msg("%s", cur->fullname);
|
||||
status = EXIT_FAILURE;
|
||||
free(cur->fullname);
|
||||
free(cur);
|
||||
return -1;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (lstat(cur->fullname, &cur->dstat)) {
|
||||
perror_msg("%s", cur->fullname);
|
||||
status = EXIT_FAILURE;
|
||||
free(cur->fullname);
|
||||
free(cur);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void newline(void)
|
||||
{
|
||||
if (column > 0) {
|
||||
putchar('\n');
|
||||
column = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
#ifdef BB_FEATURE_LS_FILETYPES
|
||||
static char append_char(mode_t mode)
|
||||
{
|
||||
if ( !(list_fmt & LIST_FILETYPE))
|
||||
return '\0';
|
||||
if ((list_fmt & LIST_EXEC) && S_ISREG(mode)
|
||||
&& (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return '*';
|
||||
return APPCHAR(mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static void nexttabstop( void )
|
||||
{
|
||||
static short nexttab= 0;
|
||||
int n=0;
|
||||
|
||||
if (column > 0) {
|
||||
n= nexttab - column;
|
||||
if (n < 1) n= 1;
|
||||
while (n--) {
|
||||
putchar(' ');
|
||||
column++;
|
||||
}
|
||||
}
|
||||
nexttab= column + column_width + COLUMN_GAP;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int is_subdir(struct dnode *dn)
|
||||
{
|
||||
return (S_ISDIR(dn->dstat.st_mode) && strcmp(dn->name, ".") != 0 &&
|
||||
strcmp(dn->name, "..") != 0);
|
||||
}
|
||||
|
||||
static int countdirs(struct dnode **dn, int nfiles)
|
||||
{
|
||||
int i, dirs;
|
||||
|
||||
if (dn==NULL || nfiles < 1) return(0);
|
||||
dirs= 0;
|
||||
for (i=0; i<nfiles; i++) {
|
||||
if (S_ISDIR(dn[i]->dstat.st_mode)) dirs++;
|
||||
}
|
||||
return(dirs);
|
||||
}
|
||||
|
||||
static int countsubdirs(struct dnode **dn, int nfiles)
|
||||
{
|
||||
int i, subdirs;
|
||||
|
||||
if (dn == NULL || nfiles < 1) return 0;
|
||||
subdirs = 0;
|
||||
for (i = 0; i < nfiles; i++)
|
||||
if (is_subdir(dn[i]))
|
||||
subdirs++;
|
||||
return subdirs;
|
||||
}
|
||||
|
||||
static int countfiles(struct dnode **dnp)
|
||||
{
|
||||
int nfiles;
|
||||
struct dnode *cur;
|
||||
|
||||
if (dnp == NULL) return(0);
|
||||
nfiles= 0;
|
||||
for (cur= dnp[0]; cur->next != NULL ; cur= cur->next) nfiles++;
|
||||
nfiles++;
|
||||
return(nfiles);
|
||||
}
|
||||
|
||||
/* get memory to hold an array of pointers */
|
||||
static struct dnode **dnalloc(int num)
|
||||
{
|
||||
struct dnode **p;
|
||||
|
||||
if (num < 1) return(NULL);
|
||||
|
||||
p= (struct dnode **)xcalloc((size_t)num, (size_t)(sizeof(struct dnode *)));
|
||||
return(p);
|
||||
}
|
||||
|
||||
#ifdef BB_FEATURE_LS_RECURSIVE
|
||||
static void dfree(struct dnode **dnp)
|
||||
{
|
||||
struct dnode *cur, *next;
|
||||
|
||||
if(dnp == NULL) return;
|
||||
|
||||
cur=dnp[0];
|
||||
while (cur != NULL) {
|
||||
if (cur->fullname != NULL) free(cur->fullname); /* free the filename */
|
||||
next= cur->next;
|
||||
free(cur); /* free the dnode */
|
||||
cur= next;
|
||||
}
|
||||
free(dnp); /* free the array holding the dnode pointers */
|
||||
}
|
||||
#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 (which == SPLIT_DIR) {
|
||||
if (S_ISDIR(dn[i]->dstat.st_mode)) {
|
||||
dnp[d++]= dn[i];
|
||||
} /* else skip the file */
|
||||
} else if (which == SPLIT_SUBDIR) {
|
||||
if (is_subdir(dn[i])) {
|
||||
dnp[d++]= dn[i];
|
||||
} /* else skip the file or dir */
|
||||
} else {
|
||||
if (!(S_ISDIR(dn[i]->dstat.st_mode))) {
|
||||
dnp[d++]= dn[i];
|
||||
} /* else skip the dir */
|
||||
}
|
||||
}
|
||||
return(dnp);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
static int sortcmp(struct dnode *d1, struct dnode *d2)
|
||||
{
|
||||
int cmp, dif;
|
||||
|
||||
cmp= 0;
|
||||
if (sort_opts == SORT_SIZE) {
|
||||
dif= (int)(d1->dstat.st_size - d2->dstat.st_size);
|
||||
} else if (sort_opts == SORT_ATIME) {
|
||||
dif= (int)(d1->dstat.st_atime - d2->dstat.st_atime);
|
||||
} else if (sort_opts == SORT_CTIME) {
|
||||
dif= (int)(d1->dstat.st_ctime - d2->dstat.st_ctime);
|
||||
} else if (sort_opts == SORT_MTIME) {
|
||||
dif= (int)(d1->dstat.st_mtime - d2->dstat.st_mtime);
|
||||
} else if (sort_opts == SORT_DIR) {
|
||||
dif= S_ISDIR(d1->dstat.st_mode) - S_ISDIR(d2->dstat.st_mode);
|
||||
/* } else if (sort_opts == SORT_VERSION) { */
|
||||
/* } else if (sort_opts == SORT_EXT) { */
|
||||
} else { /* assume SORT_NAME */
|
||||
dif= 0;
|
||||
}
|
||||
|
||||
if (dif > 0) cmp= -1;
|
||||
if (dif < 0) cmp= 1;
|
||||
if (dif == 0) {
|
||||
/* sort by name- may be a tie_breaker for time or size cmp */
|
||||
dif= strcmp(d1->name, d2->name);
|
||||
if (dif > 0) cmp= 1;
|
||||
if (dif < 0) cmp= -1;
|
||||
}
|
||||
|
||||
if (sort_order == SORT_REVERSE) {
|
||||
cmp= -1 * cmp;
|
||||
}
|
||||
return(cmp);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static void shellsort(struct dnode **dn, int size)
|
||||
{
|
||||
struct dnode *temp;
|
||||
int gap, i, j;
|
||||
|
||||
/* shell short the array */
|
||||
if(dn==NULL || size < 2) return;
|
||||
|
||||
for (gap= size/2; gap>0; gap /=2) {
|
||||
for (i=gap; i<size; i++) {
|
||||
for (j= i-gap; j>=0; j-=gap) {
|
||||
if (sortcmp(dn[j], dn[j+gap]) <= 0)
|
||||
break;
|
||||
/* they are out of order, swap them */
|
||||
temp= dn[j];
|
||||
dn[j]= dn[j+gap];
|
||||
dn[j+gap]= temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static void showfiles(struct dnode **dn, int nfiles)
|
||||
{
|
||||
int i, ncols, nrows, row, nc;
|
||||
#ifdef BB_FEATURE_AUTOWIDTH
|
||||
int len;
|
||||
#endif
|
||||
|
||||
if(dn==NULL || nfiles < 1) return;
|
||||
|
||||
#ifdef BB_FEATURE_AUTOWIDTH
|
||||
/* find the longest file name- use that as the column width */
|
||||
column_width= 0;
|
||||
for (i=0; i<nfiles; i++) {
|
||||
len= strlen(dn[i]->name) +
|
||||
((list_fmt & LIST_INO) ? 8 : 0) +
|
||||
((list_fmt & LIST_BLOCKS) ? 5 : 0)
|
||||
;
|
||||
if (column_width < len)
|
||||
column_width= len;
|
||||
}
|
||||
if (column_width >= 6)
|
||||
ncols = (int)(terminal_width / (column_width + COLUMN_GAP));
|
||||
else {
|
||||
ncols = 1;
|
||||
column_width = COLUMN_WIDTH;
|
||||
}
|
||||
#else
|
||||
ncols= TERMINAL_WIDTH;
|
||||
#endif
|
||||
switch (style_fmt) {
|
||||
case STYLE_LONG: /* one record per line, extended info */
|
||||
case STYLE_SINGLE: /* one record per line */
|
||||
ncols= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ncols > 1) {
|
||||
nrows = nfiles / ncols;
|
||||
} else {
|
||||
nrows = nfiles;
|
||||
ncols = 1;
|
||||
}
|
||||
if ((nrows * ncols) < nfiles) nrows++; /* round up fractionals */
|
||||
|
||||
if (nrows > nfiles) nrows= nfiles;
|
||||
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 (disp_opts & DISP_ROWS)
|
||||
i= (row * ncols) + nc; /* display across row */
|
||||
if (i < nfiles) {
|
||||
nexttabstop();
|
||||
list_single(dn[i]);
|
||||
}
|
||||
}
|
||||
newline();
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static void showdirs(struct dnode **dn, int ndirs)
|
||||
{
|
||||
int i, nfiles;
|
||||
struct dnode **subdnp;
|
||||
#ifdef BB_FEATURE_LS_RECURSIVE
|
||||
int dndirs;
|
||||
struct dnode **dnd;
|
||||
#endif
|
||||
|
||||
if (dn==NULL || ndirs < 1) return;
|
||||
|
||||
for (i=0; i<ndirs; i++) {
|
||||
if (disp_opts & (DISP_DIRNAME | DISP_RECURSIVE)) {
|
||||
printf("\n%s:\n", dn[i]->fullname);
|
||||
}
|
||||
subdnp= list_dir(dn[i]->fullname);
|
||||
nfiles= countfiles(subdnp);
|
||||
if (nfiles > 0) {
|
||||
/* list all files at this level */
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
shellsort(subdnp, nfiles);
|
||||
#endif
|
||||
showfiles(subdnp, nfiles);
|
||||
#ifdef BB_FEATURE_LS_RECURSIVE
|
||||
if (disp_opts & DISP_RECURSIVE) {
|
||||
/* recursive- list the sub-dirs */
|
||||
dnd= splitdnarray(subdnp, nfiles, SPLIT_SUBDIR);
|
||||
dndirs= countsubdirs(subdnp, nfiles);
|
||||
if (dndirs > 0) {
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
shellsort(dnd, dndirs);
|
||||
#endif
|
||||
showdirs(dnd, dndirs);
|
||||
free(dnd); /* free the array of dnode pointers to the dirs */
|
||||
}
|
||||
}
|
||||
dfree(subdnp); /* free the dnodes and the fullname mem */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static struct dnode **list_dir(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 = opendir(path);
|
||||
if (dir == NULL) {
|
||||
perror_msg("%s", path);
|
||||
status = EXIT_FAILURE;
|
||||
return(NULL); /* could not open the dir */
|
||||
}
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
/* are we going to list the file- it may be . or .. or a hidden file */
|
||||
if ((strcmp(entry->d_name, ".")==0) && !(disp_opts & DISP_DOT))
|
||||
continue;
|
||||
if ((strcmp(entry->d_name, "..")==0) && !(disp_opts & DISP_DOT))
|
||||
continue;
|
||||
if ((entry->d_name[0] == '.') && !(disp_opts & DISP_HIDDEN))
|
||||
continue;
|
||||
cur= (struct dnode *)xmalloc(sizeof(struct dnode));
|
||||
cur->fullname = concat_path_file(path, entry->d_name);
|
||||
cur->name = cur->fullname +
|
||||
(strlen(cur->fullname) - strlen(entry->d_name));
|
||||
if (my_stat(cur))
|
||||
continue;
|
||||
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 (nfiles < 1) 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);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int list_single(struct dnode *dn)
|
||||
{
|
||||
int i;
|
||||
char scratch[BUFSIZ + 1];
|
||||
#ifdef BB_FEATURE_LS_TIMESTAMPS
|
||||
char *filetime;
|
||||
time_t ttime, age;
|
||||
#endif
|
||||
#if defined (BB_FEATURE_LS_FILETYPES)
|
||||
struct stat info;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_FILETYPES
|
||||
char append;
|
||||
#endif
|
||||
|
||||
if (dn==NULL || dn->fullname==NULL) return(0);
|
||||
|
||||
#ifdef BB_FEATURE_LS_TIMESTAMPS
|
||||
ttime= dn->dstat.st_mtime; /* the default time */
|
||||
if (time_fmt & TIME_ACCESS) ttime= dn->dstat.st_atime;
|
||||
if (time_fmt & TIME_CHANGE) ttime= dn->dstat.st_ctime;
|
||||
filetime= ctime(&ttime);
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_FILETYPES
|
||||
append = append_char(dn->dstat.st_mode);
|
||||
#endif
|
||||
|
||||
for (i=0; i<=31; i++) {
|
||||
switch (list_fmt & (1<<i)) {
|
||||
case LIST_INO:
|
||||
printf("%7ld ", (long int)dn->dstat.st_ino);
|
||||
column += 8;
|
||||
break;
|
||||
case LIST_BLOCKS:
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
fprintf(stdout, "%6s ", make_human_readable_str(dn->dstat.st_blocks>>1,
|
||||
KILOBYTE, (ls_disp_hr==TRUE)? 0: KILOBYTE));
|
||||
#else
|
||||
#if _FILE_OFFSET_BITS == 64
|
||||
printf("%4lld ", dn->dstat.st_blocks>>1);
|
||||
#else
|
||||
printf("%4ld ", dn->dstat.st_blocks>>1);
|
||||
#endif
|
||||
#endif
|
||||
column += 5;
|
||||
break;
|
||||
case LIST_MODEBITS:
|
||||
printf("%-10s ", (char *)mode_string(dn->dstat.st_mode));
|
||||
column += 10;
|
||||
break;
|
||||
case LIST_NLINKS:
|
||||
printf("%4ld ", (long)dn->dstat.st_nlink);
|
||||
column += 10;
|
||||
break;
|
||||
case LIST_ID_NAME:
|
||||
#ifdef BB_FEATURE_LS_USERNAME
|
||||
my_getpwuid(scratch, dn->dstat.st_uid);
|
||||
printf("%-8.8s ", scratch);
|
||||
my_getgrgid(scratch, dn->dstat.st_gid);
|
||||
printf("%-8.8s", scratch);
|
||||
column += 17;
|
||||
break;
|
||||
#endif
|
||||
case LIST_ID_NUMERIC:
|
||||
printf("%-8d %-8d", dn->dstat.st_uid, dn->dstat.st_gid);
|
||||
column += 17;
|
||||
break;
|
||||
case LIST_SIZE:
|
||||
case LIST_DEV:
|
||||
if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) {
|
||||
printf("%4d, %3d ", (int)MAJOR(dn->dstat.st_rdev), (int)MINOR(dn->dstat.st_rdev));
|
||||
} else {
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
if (ls_disp_hr==TRUE) {
|
||||
fprintf(stdout, "%8s ", make_human_readable_str(dn->dstat.st_size, 1, 0));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#if _FILE_OFFSET_BITS == 64
|
||||
printf("%9lld ", (long long)dn->dstat.st_size);
|
||||
#else
|
||||
printf("%9ld ", dn->dstat.st_size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
column += 10;
|
||||
break;
|
||||
#ifdef BB_FEATURE_LS_TIMESTAMPS
|
||||
case LIST_FULLTIME:
|
||||
case LIST_DATE_TIME:
|
||||
if (list_fmt & LIST_FULLTIME) {
|
||||
printf("%24.24s ", filetime);
|
||||
column += 25;
|
||||
break;
|
||||
}
|
||||
age = time(NULL) - 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
|
||||
case LIST_FILENAME:
|
||||
printf("%s", dn->name);
|
||||
column += strlen(dn->name);
|
||||
break;
|
||||
case LIST_SYMLINK:
|
||||
if (S_ISLNK(dn->dstat.st_mode)) {
|
||||
char *lpath = xreadlink(dn->fullname);
|
||||
if (lpath) {
|
||||
printf(" -> %s", lpath);
|
||||
#ifdef BB_FEATURE_LS_FILETYPES
|
||||
if (!stat(dn->fullname, &info)) {
|
||||
append = append_char(info.st_mode);
|
||||
}
|
||||
#endif
|
||||
column += strlen(lpath) + 4;
|
||||
free(lpath);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#ifdef BB_FEATURE_LS_FILETYPES
|
||||
case LIST_FILETYPE:
|
||||
if (append != '\0') {
|
||||
printf("%1c", append);
|
||||
column++;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
extern int ls_main(int argc, char **argv)
|
||||
{
|
||||
struct dnode **dnf, **dnd;
|
||||
int dnfiles, dndirs;
|
||||
struct dnode *dn, *cur, **dnp;
|
||||
int i, nfiles;
|
||||
int opt;
|
||||
int oi, ac;
|
||||
char **av;
|
||||
#ifdef BB_FEATURE_AUTOWIDTH
|
||||
struct winsize win = { 0, 0, 0, 0 };
|
||||
#endif
|
||||
|
||||
disp_opts= DISP_NORMAL;
|
||||
style_fmt= STYLE_AUTO;
|
||||
list_fmt= LIST_SHORT;
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
sort_opts= SORT_NAME;
|
||||
sort_order= SORT_FORWARD;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_TIMESTAMPS
|
||||
time_fmt= TIME_MOD;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_AUTOWIDTH
|
||||
ioctl(fileno(stdout), TIOCGWINSZ, &win);
|
||||
if (win.ws_row > 4)
|
||||
column_width = win.ws_row - 2;
|
||||
if (win.ws_col > 0)
|
||||
terminal_width = win.ws_col - 1;
|
||||
#endif
|
||||
nfiles=0;
|
||||
|
||||
/* process options */
|
||||
while ((opt = getopt(argc, argv, "1AaCdgilnsx"
|
||||
#ifdef BB_FEATURE_AUTOWIDTH
|
||||
"T:w:"
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_FILETYPES
|
||||
"Fp"
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_RECURSIVE
|
||||
"R"
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
"rSvX"
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_TIMESTAMPS
|
||||
"cetu"
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_FOLLOWLINKS
|
||||
"L"
|
||||
#endif
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
"h"
|
||||
#endif
|
||||
"k")) > 0) {
|
||||
switch (opt) {
|
||||
case '1': style_fmt = STYLE_SINGLE; break;
|
||||
case 'A': disp_opts |= DISP_HIDDEN; break;
|
||||
case 'a': disp_opts |= DISP_HIDDEN | DISP_DOT; break;
|
||||
case 'C': style_fmt = STYLE_COLUMNS; break;
|
||||
case 'd': disp_opts |= DISP_NOLIST; break;
|
||||
case 'g': /* ignore -- for ftp servers */ break;
|
||||
case 'i': list_fmt |= LIST_INO; break;
|
||||
case 'l':
|
||||
style_fmt = STYLE_LONG;
|
||||
list_fmt |= LIST_LONG;
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
ls_disp_hr = FALSE;
|
||||
#endif
|
||||
break;
|
||||
case 'n': list_fmt |= LIST_ID_NUMERIC; break;
|
||||
case 's': list_fmt |= LIST_BLOCKS; break;
|
||||
case 'x': disp_opts = DISP_ROWS; break;
|
||||
#ifdef BB_FEATURE_LS_FILETYPES
|
||||
case 'F': list_fmt |= LIST_FILETYPE | LIST_EXEC; break;
|
||||
case 'p': list_fmt |= LIST_FILETYPE; break;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_RECURSIVE
|
||||
case 'R': disp_opts |= DISP_RECURSIVE; break;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
case 'r': sort_order |= SORT_REVERSE; break;
|
||||
case 'S': sort_opts= SORT_SIZE; break;
|
||||
case 'v': sort_opts= SORT_VERSION; break;
|
||||
case 'X': sort_opts= SORT_EXT; break;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_TIMESTAMPS
|
||||
case 'e': list_fmt |= LIST_FULLTIME; break;
|
||||
case 'c':
|
||||
time_fmt = TIME_CHANGE;
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
sort_opts= SORT_CTIME;
|
||||
#endif
|
||||
break;
|
||||
case 'u':
|
||||
time_fmt = TIME_ACCESS;
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
sort_opts= SORT_ATIME;
|
||||
#endif
|
||||
break;
|
||||
case 't':
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
sort_opts= SORT_MTIME;
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LS_FOLLOWLINKS
|
||||
case 'L': follow_links= TRUE; break;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_AUTOWIDTH
|
||||
case 'T': tabstops= atoi(optarg); break;
|
||||
case 'w': terminal_width= atoi(optarg); break;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
case 'h': ls_disp_hr = TRUE; break;
|
||||
#endif
|
||||
case 'k': break;
|
||||
default:
|
||||
goto print_usage_message;
|
||||
}
|
||||
}
|
||||
|
||||
/* sort out which command line options take precedence */
|
||||
#ifdef BB_FEATURE_LS_RECURSIVE
|
||||
if (disp_opts & DISP_NOLIST)
|
||||
disp_opts &= ~DISP_RECURSIVE; /* no recurse if listing only dir */
|
||||
#endif
|
||||
#if defined (BB_FEATURE_LS_TIMESTAMPS) && defined (BB_FEATURE_LS_SORTFILES)
|
||||
if (time_fmt & TIME_CHANGE) sort_opts= SORT_CTIME;
|
||||
if (time_fmt & TIME_ACCESS) sort_opts= SORT_ATIME;
|
||||
#endif
|
||||
if (style_fmt != STYLE_LONG)
|
||||
list_fmt &= ~LIST_ID_NUMERIC; /* numeric uid only for long list */
|
||||
#ifdef BB_FEATURE_LS_USERNAME
|
||||
if (style_fmt == STYLE_LONG && (list_fmt & LIST_ID_NUMERIC))
|
||||
list_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */
|
||||
#endif
|
||||
|
||||
/* choose a display format */
|
||||
if (style_fmt == STYLE_AUTO)
|
||||
style_fmt = isatty(fileno(stdout)) ? 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) {
|
||||
av= (char **)xcalloc((size_t)1, (size_t)(sizeof(char *)));
|
||||
av[0]= xstrdup(".");
|
||||
ac=1;
|
||||
} else {
|
||||
av= (char **)xcalloc((size_t)ac, (size_t)(sizeof(char *)));
|
||||
for (oi=0 ; oi < ac; oi++) {
|
||||
av[oi]= argv[optind++]; /* copy pointer to real cmd line arg */
|
||||
}
|
||||
}
|
||||
|
||||
/* now, everything is in the av array */
|
||||
if (ac > 1)
|
||||
disp_opts |= DISP_DIRNAME; /* 2 or more items? label directories */
|
||||
|
||||
/* stuff the command line file names into an dnode array */
|
||||
dn=NULL;
|
||||
for (oi=0 ; oi < ac; oi++) {
|
||||
cur= (struct dnode *)xmalloc(sizeof(struct dnode));
|
||||
cur->fullname= xstrdup(av[oi]);
|
||||
cur->name= cur->fullname;
|
||||
if (my_stat(cur))
|
||||
continue;
|
||||
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 (disp_opts & DISP_NOLIST) {
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
shellsort(dnp, nfiles);
|
||||
#endif
|
||||
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) {
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
shellsort(dnf, dnfiles);
|
||||
#endif
|
||||
showfiles(dnf, dnfiles);
|
||||
}
|
||||
if (dndirs > 0) {
|
||||
#ifdef BB_FEATURE_LS_SORTFILES
|
||||
shellsort(dnd, dndirs);
|
||||
#endif
|
||||
showdirs(dnd, dndirs);
|
||||
}
|
||||
}
|
||||
return(status);
|
||||
|
||||
print_usage_message:
|
||||
show_usage();
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini uniq implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by John Beppu <beppu@lineo.com>
|
||||
* Rewritten by Matt Kraai <kraai@alumni.carnegiemellon.edu>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "busybox.h"
|
||||
|
||||
static int print_count;
|
||||
static int print_uniq = 1;
|
||||
static int print_duplicates = 1;
|
||||
|
||||
static void print_line(char *line, int count, FILE *fp)
|
||||
{
|
||||
if ((print_duplicates && count > 1) || (print_uniq && count == 1)) {
|
||||
if (print_count)
|
||||
fprintf(fp, "%7d\t%s", count, line);
|
||||
else
|
||||
fputs(line, fp);
|
||||
}
|
||||
}
|
||||
|
||||
int uniq_main(int argc, char **argv)
|
||||
{
|
||||
FILE *in = stdin, *out = stdout;
|
||||
char *lastline = NULL, *input;
|
||||
int opt, count = 0;
|
||||
|
||||
/* parse argv[] */
|
||||
while ((opt = getopt(argc, argv, "cdu")) > 0) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
print_count = 1;
|
||||
break;
|
||||
case 'd':
|
||||
print_duplicates = 1;
|
||||
print_uniq = 0;
|
||||
break;
|
||||
case 'u':
|
||||
print_duplicates = 0;
|
||||
print_uniq = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (argv[optind] != NULL) {
|
||||
in = xfopen(argv[optind], "r");
|
||||
if (argv[optind+1] != NULL)
|
||||
out = xfopen(argv[optind+1], "w");
|
||||
}
|
||||
|
||||
while ((input = get_line_from_file(in)) != NULL) {
|
||||
if (lastline == NULL || strcmp(input, lastline) != 0) {
|
||||
print_line(lastline, count, out);
|
||||
free(lastline);
|
||||
lastline = input;
|
||||
count = 0;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
print_line(lastline, count, out);
|
||||
free(lastline);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini cpio implementation for busybox
|
||||
*
|
||||
* Copyright (C) 2001 by Glenn McGrath
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Limitations:
|
||||
* Doesn't check CRC's
|
||||
* Only supports new ASCII and CRC formats
|
||||
*
|
||||
*/
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "busybox.h"
|
||||
|
||||
extern int cpio_main(int argc, char **argv)
|
||||
{
|
||||
FILE *src_stream = stdin;
|
||||
char **extract_names = NULL;
|
||||
int extract_function = 0;
|
||||
int num_of_entries = 0;
|
||||
int opt = 0;
|
||||
mode_t oldmask = 0;
|
||||
|
||||
while ((opt = getopt(argc, argv, "idmuvtF:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'i': // extract
|
||||
extract_function |= extract_all_to_fs;
|
||||
break;
|
||||
case 'd': // create _leading_ directories
|
||||
extract_function |= extract_create_leading_dirs;
|
||||
oldmask = umask(077); /* Make make_directory act like GNU cpio */
|
||||
break;
|
||||
case 'm': // preserve modification time
|
||||
extract_function |= extract_preserve_date;
|
||||
break;
|
||||
case 'v': // verbosly list files
|
||||
extract_function |= extract_verbose_list;
|
||||
break;
|
||||
case 'u': // unconditional
|
||||
extract_function |= extract_unconditional;
|
||||
break;
|
||||
case 't': // list files
|
||||
extract_function |= extract_list;
|
||||
break;
|
||||
case 'F':
|
||||
src_stream = xfopen(optarg, "r");
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if ((extract_function & extract_all_to_fs) && (extract_function & extract_list)) {
|
||||
extract_function ^= extract_all_to_fs; /* If specify t, don't extract*/
|
||||
}
|
||||
|
||||
if ((extract_function & extract_all_to_fs) && (extract_function & extract_verbose_list)) {
|
||||
/* The meaning of v changes on extract */
|
||||
extract_function ^= extract_verbose_list;
|
||||
extract_function |= extract_list;
|
||||
}
|
||||
|
||||
while (optind < argc) {
|
||||
extract_names = xrealloc(extract_names, sizeof(char *) * (num_of_entries + 2));
|
||||
extract_names[num_of_entries] = xstrdup(argv[optind]);
|
||||
num_of_entries++;
|
||||
extract_names[num_of_entries] = NULL;
|
||||
optind++;
|
||||
}
|
||||
|
||||
unarchive(src_stream, stdout, &get_header_cpio, extract_function, "./", extract_names);
|
||||
if (oldmask) {
|
||||
umask(oldmask); /* Restore umask if we changed it */
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
247
busybox/date.c
|
@ -1,247 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini date implementation for busybox
|
||||
*
|
||||
* by Matthew Grant <grantma@anathoth.gen.nz>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#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 int, as well as
|
||||
an RFC 822 complient 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 suprising some people */
|
||||
|
||||
static struct tm *date_conv_time(struct tm *tm_time, const char *t_string)
|
||||
{
|
||||
int nr;
|
||||
|
||||
nr = sscanf(t_string, "%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) {
|
||||
error_msg_and_die(invalid_date, t_string);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
return (tm_time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* The new stuff for LRP */
|
||||
|
||||
static struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string)
|
||||
{
|
||||
struct tm t;
|
||||
|
||||
/* Parse input and assign appropriately to tm_time */
|
||||
|
||||
if (t=*tm_time,sscanf(t_string, "%d:%d:%d",
|
||||
&t.tm_hour, &t.tm_min, &t.tm_sec) == 3) {
|
||||
/* no adjustments needed */
|
||||
|
||||
} else if (t=*tm_time,sscanf(t_string, "%d:%d",
|
||||
&t.tm_hour, &t.tm_min) == 2) {
|
||||
/* no adjustments needed */
|
||||
|
||||
|
||||
} else if (t=*tm_time,sscanf(t_string, "%d.%d-%d:%d:%d",
|
||||
&t.tm_mon,
|
||||
&t.tm_mday,
|
||||
&t.tm_hour,
|
||||
&t.tm_min, &t.tm_sec) == 5) {
|
||||
|
||||
t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
|
||||
|
||||
} else if (t=*tm_time,sscanf(t_string, "%d.%d-%d:%d",
|
||||
&t.tm_mon,
|
||||
&t.tm_mday,
|
||||
&t.tm_hour, &t.tm_min) == 4) {
|
||||
|
||||
t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
|
||||
|
||||
} else if (t=*tm_time,sscanf(t_string, "%d.%d.%d-%d:%d:%d",
|
||||
&t.tm_year,
|
||||
&t.tm_mon,
|
||||
&t.tm_mday,
|
||||
&t.tm_hour,
|
||||
&t.tm_min, &t.tm_sec) == 6) {
|
||||
|
||||
t.tm_year -= 1900; /* Adjust years */
|
||||
t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
|
||||
|
||||
} else if (t=*tm_time,sscanf(t_string, "%d.%d.%d-%d:%d",
|
||||
&t.tm_year,
|
||||
&t.tm_mon,
|
||||
&t.tm_mday,
|
||||
&t.tm_hour, &t.tm_min) == 5) {
|
||||
t.tm_year -= 1900; /* Adjust years */
|
||||
t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
|
||||
|
||||
} else {
|
||||
error_msg_and_die(invalid_date, t_string);
|
||||
}
|
||||
*tm_time = t;
|
||||
return (tm_time);
|
||||
}
|
||||
|
||||
|
||||
int date_main(int argc, char **argv)
|
||||
{
|
||||
char *date_str = NULL;
|
||||
char *date_fmt = NULL;
|
||||
char *t_buff;
|
||||
int c;
|
||||
int set_time = 0;
|
||||
int rfc822 = 0;
|
||||
int utc = 0;
|
||||
int use_arg = 0;
|
||||
time_t tm;
|
||||
struct tm tm_time;
|
||||
|
||||
/* Interpret command line args */
|
||||
while ((c = getopt(argc, argv, "Rs:ud:")) != EOF) {
|
||||
switch (c) {
|
||||
case 'R':
|
||||
rfc822 = 1;
|
||||
break;
|
||||
case 's':
|
||||
set_time = 1;
|
||||
if ((date_str != NULL) || ((date_str = optarg) == NULL)) {
|
||||
show_usage();
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
utc = 1;
|
||||
if (putenv("TZ=UTC0") != 0)
|
||||
error_msg_and_die(memory_exhausted);
|
||||
break;
|
||||
case 'd':
|
||||
use_arg = 1;
|
||||
if ((date_str != NULL) || ((date_str = optarg) == NULL))
|
||||
show_usage();
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+'))
|
||||
date_fmt = &argv[optind][1]; /* Skip over the '+' */
|
||||
else if (date_str == NULL) {
|
||||
set_time = 1;
|
||||
date_str = argv[optind];
|
||||
}
|
||||
#if 0
|
||||
else {
|
||||
error_msg("date_str='%s' date_fmt='%s'\n", date_str, date_fmt);
|
||||
show_usage();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now we have parsed all the information except the date format
|
||||
which depends on whether the clock is being set or read */
|
||||
|
||||
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 (date_str != NULL) {
|
||||
|
||||
if (strchr(date_str, ':') != NULL) {
|
||||
date_conv_ftime(&tm_time, date_str);
|
||||
} else {
|
||||
date_conv_time(&tm_time, date_str);
|
||||
}
|
||||
|
||||
/* Correct any day of week and day of year etc. fields */
|
||||
tm = mktime(&tm_time);
|
||||
if (tm < 0)
|
||||
error_msg_and_die(invalid_date, date_str);
|
||||
if ( utc ) {
|
||||
if (putenv("TZ=UTC0") != 0)
|
||||
error_msg_and_die(memory_exhausted);
|
||||
}
|
||||
|
||||
/* if setting time, set it */
|
||||
if (set_time) {
|
||||
if (stime(&tm) < 0) {
|
||||
perror_msg("cannot set date");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Display output */
|
||||
|
||||
/* Deal with format string */
|
||||
if (date_fmt == NULL) {
|
||||
date_fmt = (rfc822
|
||||
? (utc
|
||||
? "%a, %_d %b %Y %H:%M:%S GMT"
|
||||
: "%a, %_d %b %Y %H:%M:%S %z")
|
||||
: "%a %b %e %H:%M:%S %Z %Y");
|
||||
|
||||
} else if (*date_fmt == '\0') {
|
||||
/* Imitate what GNU 'date' does with NO format string! */
|
||||
printf("\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* Handle special conversions */
|
||||
|
||||
if (strncmp(date_fmt, "%f", 2) == 0) {
|
||||
date_fmt = "%Y.%m.%d-%H:%M:%S";
|
||||
}
|
||||
|
||||
/* Print OUTPUT (after ALL that!) */
|
||||
t_buff = xmalloc(201);
|
||||
strftime(t_buff, 200, date_fmt, &tm_time);
|
||||
puts(t_buff);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
154
busybox/dd.c
|
@ -1,154 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini dd implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "busybox.h"
|
||||
|
||||
|
||||
static const struct suffix_mult dd_suffixes[] = {
|
||||
{ "c", 1 },
|
||||
{ "w", 2 },
|
||||
{ "b", 512 },
|
||||
{ "kD", 1000 },
|
||||
{ "k", 1024 },
|
||||
{ "MD", 1000000 },
|
||||
{ "M", 1048576 },
|
||||
{ "GD", 1000000000 },
|
||||
{ "G", 1073741824 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
int dd_main(int argc, char **argv)
|
||||
{
|
||||
int i, ifd, ofd, oflag, sync_flag = FALSE, trunc = TRUE;
|
||||
size_t in_full = 0, in_part = 0, out_full = 0, out_part = 0;
|
||||
size_t bs = 512, count = -1;
|
||||
ssize_t n;
|
||||
off_t seek = 0, skip = 0;
|
||||
char *infile = NULL, *outfile = NULL, *buf;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strncmp("bs=", argv[i], 3) == 0)
|
||||
bs = parse_number(argv[i]+3, dd_suffixes);
|
||||
else if (strncmp("count=", argv[i], 6) == 0)
|
||||
count = parse_number(argv[i]+6, dd_suffixes);
|
||||
else if (strncmp("seek=", argv[i], 5) == 0)
|
||||
seek = parse_number(argv[i]+5, dd_suffixes);
|
||||
else if (strncmp("skip=", argv[i], 5) == 0)
|
||||
skip = parse_number(argv[i]+5, dd_suffixes);
|
||||
else if (strncmp("if=", argv[i], 3) == 0)
|
||||
infile = argv[i]+3;
|
||||
else if (strncmp("of=", argv[i], 3) == 0)
|
||||
outfile = argv[i]+3;
|
||||
else if (strncmp("conv=", argv[i], 5) == 0) {
|
||||
buf = argv[i]+5;
|
||||
while (1) {
|
||||
if (strncmp("notrunc", buf, 7) == 0) {
|
||||
trunc = FALSE;
|
||||
buf += 7;
|
||||
} else if (strncmp("sync", buf, 4) == 0) {
|
||||
sync_flag = TRUE;
|
||||
buf += 4;
|
||||
} else {
|
||||
error_msg_and_die("invalid conversion `%s'", argv[i]+5);
|
||||
}
|
||||
if (buf[0] == '\0')
|
||||
break;
|
||||
if (buf[0] == ',')
|
||||
buf++;
|
||||
}
|
||||
} else
|
||||
show_usage();
|
||||
}
|
||||
|
||||
buf = xmalloc(bs);
|
||||
|
||||
if (infile != NULL) {
|
||||
if ((ifd = open(infile, O_RDONLY)) < 0)
|
||||
perror_msg_and_die("%s", infile);
|
||||
} else {
|
||||
ifd = STDIN_FILENO;
|
||||
infile = "standard input";
|
||||
}
|
||||
|
||||
if (outfile != NULL) {
|
||||
oflag = O_WRONLY | O_CREAT;
|
||||
|
||||
if (!seek && trunc)
|
||||
oflag |= O_TRUNC;
|
||||
|
||||
if ((ofd = open(outfile, oflag, 0666)) < 0)
|
||||
perror_msg_and_die("%s", outfile);
|
||||
|
||||
if (seek && trunc) {
|
||||
if (ftruncate(ofd, seek * bs) < 0)
|
||||
perror_msg_and_die("%s", outfile);
|
||||
}
|
||||
} else {
|
||||
ofd = STDOUT_FILENO;
|
||||
outfile = "standard output";
|
||||
}
|
||||
|
||||
if (skip) {
|
||||
if (lseek(ifd, skip * bs, SEEK_CUR) < 0)
|
||||
perror_msg_and_die("%s", infile);
|
||||
}
|
||||
|
||||
if (seek) {
|
||||
if (lseek(ofd, seek * bs, SEEK_CUR) < 0)
|
||||
perror_msg_and_die("%s", outfile);
|
||||
}
|
||||
|
||||
while (in_full + in_part != count) {
|
||||
n = safe_read(ifd, buf, bs);
|
||||
if (n < 0)
|
||||
perror_msg_and_die("%s", infile);
|
||||
if (n == 0)
|
||||
break;
|
||||
if (n == bs)
|
||||
in_full++;
|
||||
else
|
||||
in_part++;
|
||||
if (sync_flag) {
|
||||
memset(buf + n, '\0', bs - n);
|
||||
n = bs;
|
||||
}
|
||||
n = full_write(ofd, buf, n);
|
||||
if (n < 0)
|
||||
perror_msg_and_die("%s", outfile);
|
||||
if (n == bs)
|
||||
out_full++;
|
||||
else
|
||||
out_part++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%ld+%ld records in\n", (long)in_full, (long)in_part);
|
||||
fprintf(stderr, "%ld+%ld records out\n", (long)out_full, (long)out_part);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* disalloc.c - aeb - 940501 - Disallocate virtual terminal(s)
|
||||
* Renamed deallocvt.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "busybox.h"
|
||||
|
||||
/* From <linux/vt.h> */
|
||||
static const int VT_DISALLOCATE = 0x5608; /* free memory associated to vt */
|
||||
|
||||
int deallocvt_main(int argc, char *argv[])
|
||||
{
|
||||
int fd, num, i;
|
||||
|
||||
//if ((argc > 2) || ((argv == 2) && (**(argv + 1) == '-')))
|
||||
if (argc > 2)
|
||||
show_usage();
|
||||
|
||||
fd = get_console_fd("/dev/console");
|
||||
|
||||
if (argc == 1) {
|
||||
/* deallocate all unused consoles */
|
||||
if (ioctl(fd, VT_DISALLOCATE, 0))
|
||||
perror_msg_and_die("VT_DISALLOCATE");
|
||||
} else {
|
||||
for (i = 1; i < argc; i++) {
|
||||
num = atoi(argv[i]);
|
||||
if (num == 0)
|
||||
error_msg("0: illegal VT number");
|
||||
else if (num == 1)
|
||||
error_msg("VT 1 cannot be deallocated");
|
||||
else if (ioctl(fd, VT_DISALLOCATE, num))
|
||||
perror_msg_and_die("VT_DISALLOCATE");
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
158
busybox/df.c
|
@ -1,158 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini df implementation for busybox
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
|
||||
* based on original code by (I think) Bruce Perens <bruce@pixar.com>.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mntent.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <getopt.h>
|
||||
#include "busybox.h"
|
||||
|
||||
extern const char mtab_file[]; /* Defined in utility.c */
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
static unsigned long df_disp_hr = KILOBYTE;
|
||||
#endif
|
||||
|
||||
static int do_df(char *device, const char *mount_point)
|
||||
{
|
||||
struct statfs s;
|
||||
long blocks_used;
|
||||
long blocks_percent_used;
|
||||
|
||||
if (statfs(mount_point, &s) != 0) {
|
||||
perror_msg("%s", mount_point);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (s.f_blocks > 0) {
|
||||
blocks_used = s.f_blocks - s.f_bfree;
|
||||
if(blocks_used == 0)
|
||||
blocks_percent_used = 0;
|
||||
else {
|
||||
blocks_percent_used = (long)
|
||||
(blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5);
|
||||
}
|
||||
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_real_root_device_name(device);
|
||||
if(device==NULL)
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef BB_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,
|
||||
(long) (s.f_blocks * (s.f_bsize / (double)KILOBYTE)),
|
||||
(long) ((s.f_blocks - s.f_bfree)*(s.f_bsize/(double)KILOBYTE)),
|
||||
(long) (s.f_bavail * (s.f_bsize / (double)KILOBYTE)),
|
||||
blocks_percent_used, mount_point);
|
||||
#endif
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
extern int df_main(int argc, char **argv)
|
||||
{
|
||||
int status = EXIT_SUCCESS;
|
||||
int opt = 0;
|
||||
int i = 0;
|
||||
char disp_units_hdr[80] = "1k-blocks"; /* default display is kilobytes */
|
||||
|
||||
while ((opt = getopt(argc, argv, "k"
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
"hm"
|
||||
#endif
|
||||
)) > 0)
|
||||
{
|
||||
switch (opt) {
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
case 'h':
|
||||
df_disp_hr = 0;
|
||||
strcpy(disp_units_hdr, " Size");
|
||||
break;
|
||||
case 'm':
|
||||
df_disp_hr = MEGABYTE;
|
||||
strcpy(disp_units_hdr, "1M-blocks");
|
||||
break;
|
||||
#endif
|
||||
case 'k':
|
||||
/* default display is kilobytes */
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
printf("%-20s %-14s %s %s %s %s\n", "Filesystem", disp_units_hdr,
|
||||
"Used", "Available", "Use%", "Mounted on");
|
||||
|
||||
if(optind < argc) {
|
||||
struct mntent *mount_entry;
|
||||
for(i = optind; i < argc; i++)
|
||||
{
|
||||
if ((mount_entry = find_mount_point(argv[i], mtab_file)) == 0) {
|
||||
error_msg("%s: can't find mount point.", argv[i]);
|
||||
status = EXIT_FAILURE;
|
||||
} else if (!do_df(mount_entry->mnt_fsname, mount_entry->mnt_dir))
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
} else {
|
||||
FILE *mount_table;
|
||||
struct mntent *mount_entry;
|
||||
|
||||
mount_table = setmntent(mtab_file, "r");
|
||||
if (mount_table == 0) {
|
||||
perror_msg("%s", mtab_file);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
while ((mount_entry = getmntent(mount_table))) {
|
||||
if (!do_df(mount_entry->mnt_fsname, mount_entry->mnt_dir))
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
endmntent(mount_table);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "linux"
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
End:
|
||||
*/
|
|
@ -1,40 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini dirname implementation for busybox
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.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
|
||||
*
|
||||
*/
|
||||
|
||||
/* getopt not needed */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "busybox.h"
|
||||
|
||||
extern int dirname_main(int argc, char **argv)
|
||||
{
|
||||
if ((argc < 2) || (**(argv + 1) == '-'))
|
||||
show_usage();
|
||||
argv++;
|
||||
|
||||
puts (dirname (argv[0]));
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
BusyBox.html
|
|
@ -1,404 +0,0 @@
|
|||
%!PS-Adobe-2.0
|
||||
%%Title: busybox-growth.ps
|
||||
%%Creator: gnuplot 3.5 (pre 3.6) patchlevel beta 347
|
||||
%%CreationDate: Tue Apr 10 14:03:36 2001
|
||||
%%DocumentFonts: (atend)
|
||||
%%BoundingBox: 50 40 554 770
|
||||
%%Orientation: Landscape
|
||||
%%Pages: (atend)
|
||||
%%EndComments
|
||||
/gnudict 120 dict def
|
||||
gnudict begin
|
||||
/Color true def
|
||||
/Solid true def
|
||||
/gnulinewidth 5.000 def
|
||||
/userlinewidth gnulinewidth def
|
||||
/vshift -46 def
|
||||
/dl {10 mul} def
|
||||
/hpt_ 31.5 def
|
||||
/vpt_ 31.5 def
|
||||
/hpt hpt_ def
|
||||
/vpt vpt_ def
|
||||
/M {moveto} bind def
|
||||
/L {lineto} bind def
|
||||
/R {rmoveto} bind def
|
||||
/V {rlineto} bind def
|
||||
/vpt2 vpt 2 mul def
|
||||
/hpt2 hpt 2 mul def
|
||||
/Lshow { currentpoint stroke M
|
||||
0 vshift R show } def
|
||||
/Rshow { currentpoint stroke M
|
||||
dup stringwidth pop neg vshift R show } def
|
||||
/Cshow { currentpoint stroke M
|
||||
dup stringwidth pop -2 div vshift R show } def
|
||||
/UP { dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
|
||||
/hpt2 hpt 2 mul def /vpt2 vpt 2 mul def } def
|
||||
/DL { Color {setrgbcolor Solid {pop []} if 0 setdash }
|
||||
{pop pop pop Solid {pop []} if 0 setdash} ifelse } def
|
||||
/BL { stroke gnulinewidth 2 mul setlinewidth } def
|
||||
/AL { stroke gnulinewidth 2 div setlinewidth } def
|
||||
/UL { gnulinewidth mul /userlinewidth exch def } def
|
||||
/PL { stroke userlinewidth setlinewidth } def
|
||||
/LTb { BL [] 0 0 0 DL } def
|
||||
/LTa { AL [1 dl 2 dl] 0 setdash 0 0 0 setrgbcolor } def
|
||||
/LT0 { PL [] 1 0 0 DL } def
|
||||
/LT1 { PL [4 dl 2 dl] 0 1 0 DL } def
|
||||
/LT2 { PL [2 dl 3 dl] 0 0 1 DL } def
|
||||
/LT3 { PL [1 dl 1.5 dl] 1 0 1 DL } def
|
||||
/LT4 { PL [5 dl 2 dl 1 dl 2 dl] 0 1 1 DL } def
|
||||
/LT5 { PL [4 dl 3 dl 1 dl 3 dl] 1 1 0 DL } def
|
||||
/LT6 { PL [2 dl 2 dl 2 dl 4 dl] 0 0 0 DL } def
|
||||
/LT7 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 1 0.3 0 DL } def
|
||||
/LT8 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 0.5 0.5 0.5 DL } def
|
||||
/Pnt { stroke [] 0 setdash
|
||||
gsave 1 setlinecap M 0 0 V stroke grestore } def
|
||||
/Dia { stroke [] 0 setdash 2 copy vpt add M
|
||||
hpt neg vpt neg V hpt vpt neg V
|
||||
hpt vpt V hpt neg vpt V closepath stroke
|
||||
Pnt } def
|
||||
/Pls { stroke [] 0 setdash vpt sub M 0 vpt2 V
|
||||
currentpoint stroke M
|
||||
hpt neg vpt neg R hpt2 0 V stroke
|
||||
} def
|
||||
/Box { stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
|
||||
0 vpt2 neg V hpt2 0 V 0 vpt2 V
|
||||
hpt2 neg 0 V closepath stroke
|
||||
Pnt } def
|
||||
/Crs { stroke [] 0 setdash exch hpt sub exch vpt add M
|
||||
hpt2 vpt2 neg V currentpoint stroke M
|
||||
hpt2 neg 0 R hpt2 vpt2 V stroke } def
|
||||
/TriU { stroke [] 0 setdash 2 copy vpt 1.12 mul add M
|
||||
hpt neg vpt -1.62 mul V
|
||||
hpt 2 mul 0 V
|
||||
hpt neg vpt 1.62 mul V closepath stroke
|
||||
Pnt } def
|
||||
/Star { 2 copy Pls Crs } def
|
||||
/BoxF { stroke [] 0 setdash exch hpt sub exch vpt add M
|
||||
0 vpt2 neg V hpt2 0 V 0 vpt2 V
|
||||
hpt2 neg 0 V closepath fill } def
|
||||
/TriUF { stroke [] 0 setdash vpt 1.12 mul add M
|
||||
hpt neg vpt -1.62 mul V
|
||||
hpt 2 mul 0 V
|
||||
hpt neg vpt 1.62 mul V closepath fill } def
|
||||
/TriD { stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
|
||||
hpt neg vpt 1.62 mul V
|
||||
hpt 2 mul 0 V
|
||||
hpt neg vpt -1.62 mul V closepath stroke
|
||||
Pnt } def
|
||||
/TriDF { stroke [] 0 setdash vpt 1.12 mul sub M
|
||||
hpt neg vpt 1.62 mul V
|
||||
hpt 2 mul 0 V
|
||||
hpt neg vpt -1.62 mul V closepath fill} def
|
||||
/DiaF { stroke [] 0 setdash vpt add M
|
||||
hpt neg vpt neg V hpt vpt neg V
|
||||
hpt vpt V hpt neg vpt V closepath fill } def
|
||||
/Pent { stroke [] 0 setdash 2 copy gsave
|
||||
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
|
||||
closepath stroke grestore Pnt } def
|
||||
/PentF { stroke [] 0 setdash gsave
|
||||
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
|
||||
closepath fill grestore } def
|
||||
/Circle { stroke [] 0 setdash 2 copy
|
||||
hpt 0 360 arc stroke Pnt } def
|
||||
/CircleF { stroke [] 0 setdash hpt 0 360 arc fill } def
|
||||
/C0 { BL [] 0 setdash 2 copy moveto vpt 90 450 arc } bind def
|
||||
/C1 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 0 90 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C2 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 90 180 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C3 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 0 180 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C4 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 180 270 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C5 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 0 90 arc
|
||||
2 copy moveto
|
||||
2 copy vpt 180 270 arc closepath fill
|
||||
vpt 0 360 arc } bind def
|
||||
/C6 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 90 270 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C7 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 0 270 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C8 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 270 360 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C9 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 270 450 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C10 { BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
|
||||
2 copy moveto
|
||||
2 copy vpt 90 180 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C11 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 0 180 arc closepath fill
|
||||
2 copy moveto
|
||||
2 copy vpt 270 360 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C12 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 180 360 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C13 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 0 90 arc closepath fill
|
||||
2 copy moveto
|
||||
2 copy vpt 180 360 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/C14 { BL [] 0 setdash 2 copy moveto
|
||||
2 copy vpt 90 360 arc closepath fill
|
||||
vpt 0 360 arc } bind def
|
||||
/C15 { BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
|
||||
vpt 0 360 arc closepath } bind def
|
||||
/Rec { newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
|
||||
neg 0 rlineto closepath } bind def
|
||||
/Square { dup Rec } bind def
|
||||
/Bsquare { vpt sub exch vpt sub exch vpt2 Square } bind def
|
||||
/S0 { BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare } bind def
|
||||
/S1 { BL [] 0 setdash 2 copy vpt Square fill Bsquare } bind def
|
||||
/S2 { BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def
|
||||
/S3 { BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare } bind def
|
||||
/S4 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def
|
||||
/S5 { BL [] 0 setdash 2 copy 2 copy vpt Square fill
|
||||
exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def
|
||||
/S6 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare } bind def
|
||||
/S7 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
|
||||
2 copy vpt Square fill
|
||||
Bsquare } bind def
|
||||
/S8 { BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare } bind def
|
||||
/S9 { BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare } bind def
|
||||
/S10 { BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
|
||||
Bsquare } bind def
|
||||
/S11 { BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
|
||||
Bsquare } bind def
|
||||
/S12 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare } bind def
|
||||
/S13 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
|
||||
2 copy vpt Square fill Bsquare } bind def
|
||||
/S14 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
|
||||
2 copy exch vpt sub exch vpt Square fill Bsquare } bind def
|
||||
/S15 { BL [] 0 setdash 2 copy Bsquare fill Bsquare } bind def
|
||||
/D0 { gsave translate 45 rotate 0 0 S0 stroke grestore } bind def
|
||||
/D1 { gsave translate 45 rotate 0 0 S1 stroke grestore } bind def
|
||||
/D2 { gsave translate 45 rotate 0 0 S2 stroke grestore } bind def
|
||||
/D3 { gsave translate 45 rotate 0 0 S3 stroke grestore } bind def
|
||||
/D4 { gsave translate 45 rotate 0 0 S4 stroke grestore } bind def
|
||||
/D5 { gsave translate 45 rotate 0 0 S5 stroke grestore } bind def
|
||||
/D6 { gsave translate 45 rotate 0 0 S6 stroke grestore } bind def
|
||||
/D7 { gsave translate 45 rotate 0 0 S7 stroke grestore } bind def
|
||||
/D8 { gsave translate 45 rotate 0 0 S8 stroke grestore } bind def
|
||||
/D9 { gsave translate 45 rotate 0 0 S9 stroke grestore } bind def
|
||||
/D10 { gsave translate 45 rotate 0 0 S10 stroke grestore } bind def
|
||||
/D11 { gsave translate 45 rotate 0 0 S11 stroke grestore } bind def
|
||||
/D12 { gsave translate 45 rotate 0 0 S12 stroke grestore } bind def
|
||||
/D13 { gsave translate 45 rotate 0 0 S13 stroke grestore } bind def
|
||||
/D14 { gsave translate 45 rotate 0 0 S14 stroke grestore } bind def
|
||||
/D15 { gsave translate 45 rotate 0 0 S15 stroke grestore } bind def
|
||||
/DiaE { stroke [] 0 setdash vpt add M
|
||||
hpt neg vpt neg V hpt vpt neg V
|
||||
hpt vpt V hpt neg vpt V closepath stroke } def
|
||||
/BoxE { stroke [] 0 setdash exch hpt sub exch vpt add M
|
||||
0 vpt2 neg V hpt2 0 V 0 vpt2 V
|
||||
hpt2 neg 0 V closepath stroke } def
|
||||
/TriUE { stroke [] 0 setdash vpt 1.12 mul add M
|
||||
hpt neg vpt -1.62 mul V
|
||||
hpt 2 mul 0 V
|
||||
hpt neg vpt 1.62 mul V closepath stroke } def
|
||||
/TriDE { stroke [] 0 setdash vpt 1.12 mul sub M
|
||||
hpt neg vpt 1.62 mul V
|
||||
hpt 2 mul 0 V
|
||||
hpt neg vpt -1.62 mul V closepath stroke } def
|
||||
/PentE { stroke [] 0 setdash gsave
|
||||
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
|
||||
closepath stroke grestore } def
|
||||
/CircE { stroke [] 0 setdash
|
||||
hpt 0 360 arc stroke } def
|
||||
/Opaque { gsave closepath 1 setgray fill grestore 0 setgray closepath } def
|
||||
/DiaW { stroke [] 0 setdash vpt add M
|
||||
hpt neg vpt neg V hpt vpt neg V
|
||||
hpt vpt V hpt neg vpt V Opaque stroke } def
|
||||
/BoxW { stroke [] 0 setdash exch hpt sub exch vpt add M
|
||||
0 vpt2 neg V hpt2 0 V 0 vpt2 V
|
||||
hpt2 neg 0 V Opaque stroke } def
|
||||
/TriUW { stroke [] 0 setdash vpt 1.12 mul add M
|
||||
hpt neg vpt -1.62 mul V
|
||||
hpt 2 mul 0 V
|
||||
hpt neg vpt 1.62 mul V Opaque stroke } def
|
||||
/TriDW { stroke [] 0 setdash vpt 1.12 mul sub M
|
||||
hpt neg vpt 1.62 mul V
|
||||
hpt 2 mul 0 V
|
||||
hpt neg vpt -1.62 mul V Opaque stroke } def
|
||||
/PentW { stroke [] 0 setdash gsave
|
||||
translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
|
||||
Opaque stroke grestore } def
|
||||
/CircW { stroke [] 0 setdash
|
||||
hpt 0 360 arc Opaque stroke } def
|
||||
/BoxFill { gsave Rec 1 setgray fill grestore } def
|
||||
end
|
||||
%%EndProlog
|
||||
%%Page: 1 1
|
||||
gnudict begin
|
||||
gsave
|
||||
50 50 translate
|
||||
0.100 0.100 scale
|
||||
90 rotate
|
||||
0 -5040 translate
|
||||
0 setgray
|
||||
newpath
|
||||
(Helvetica) findfont 140 scalefont setfont
|
||||
1.000 UL
|
||||
LTb
|
||||
560 420 M
|
||||
63 0 V
|
||||
6409 0 R
|
||||
-63 0 V
|
||||
476 420 M
|
||||
(0) Rshow
|
||||
560 1056 M
|
||||
63 0 V
|
||||
6409 0 R
|
||||
-63 0 V
|
||||
-6493 0 R
|
||||
(100) Rshow
|
||||
560 1692 M
|
||||
63 0 V
|
||||
6409 0 R
|
||||
-63 0 V
|
||||
-6493 0 R
|
||||
(200) Rshow
|
||||
560 2328 M
|
||||
63 0 V
|
||||
6409 0 R
|
||||
-63 0 V
|
||||
-6493 0 R
|
||||
(300) Rshow
|
||||
560 2964 M
|
||||
63 0 V
|
||||
6409 0 R
|
||||
-63 0 V
|
||||
-6493 0 R
|
||||
(400) Rshow
|
||||
560 3600 M
|
||||
63 0 V
|
||||
6409 0 R
|
||||
-63 0 V
|
||||
-6493 0 R
|
||||
(500) Rshow
|
||||
560 4236 M
|
||||
63 0 V
|
||||
6409 0 R
|
||||
-63 0 V
|
||||
-6493 0 R
|
||||
(600) Rshow
|
||||
560 4872 M
|
||||
63 0 V
|
||||
6409 0 R
|
||||
-63 0 V
|
||||
-6493 0 R
|
||||
(700) Rshow
|
||||
1531 420 M
|
||||
0 63 V
|
||||
0 4389 R
|
||||
0 -63 V
|
||||
0 -4529 R
|
||||
(400) Cshow
|
||||
2825 420 M
|
||||
0 63 V
|
||||
0 4389 R
|
||||
0 -63 V
|
||||
0 -4529 R
|
||||
(600) Cshow
|
||||
4120 420 M
|
||||
0 63 V
|
||||
0 4389 R
|
||||
0 -63 V
|
||||
0 -4529 R
|
||||
(800) Cshow
|
||||
5414 420 M
|
||||
0 63 V
|
||||
0 4389 R
|
||||
0 -63 V
|
||||
0 -4529 R
|
||||
(1000) Cshow
|
||||
6708 420 M
|
||||
0 63 V
|
||||
0 4389 R
|
||||
0 -63 V
|
||||
0 -4529 R
|
||||
(1200) Cshow
|
||||
1.000 UL
|
||||
LTb
|
||||
560 420 M
|
||||
6472 0 V
|
||||
0 4452 V
|
||||
-6472 0 V
|
||||
560 420 L
|
||||
0 2646 M
|
||||
currentpoint gsave translate 90 rotate 0 0 M
|
||||
(tar.gz size \(Kb\)) Cshow
|
||||
grestore
|
||||
3796 140 M
|
||||
(time \(days since Jan 1, 1998\)) Cshow
|
||||
1.000 UL
|
||||
LT0
|
||||
696 420 M
|
||||
0 593 V
|
||||
1255 0 V
|
||||
0 15 V
|
||||
214 0 V
|
||||
0 6 V
|
||||
958 0 V
|
||||
0 1 V
|
||||
-84 0 V
|
||||
0 37 V
|
||||
168 0 V
|
||||
0 262 V
|
||||
13 0 V
|
||||
0 56 V
|
||||
91 0 V
|
||||
0 33 V
|
||||
6 0 V
|
||||
0 1 V
|
||||
19 0 V
|
||||
0 11 V
|
||||
20 0 V
|
||||
0 13 V
|
||||
32 0 V
|
||||
0 104 V
|
||||
52 0 V
|
||||
0 27 V
|
||||
65 0 V
|
||||
0 15 V
|
||||
39 0 V
|
||||
0 126 V
|
||||
174 0 V
|
||||
0 103 V
|
||||
52 0 V
|
||||
0 49 V
|
||||
175 0 V
|
||||
0 56 V
|
||||
433 0 V
|
||||
0 661 V
|
||||
415 0 V
|
||||
0 857 V
|
||||
123 0 V
|
||||
0 -291 V
|
||||
498 0 V
|
||||
0 208 V
|
||||
505 0 V
|
||||
0 66 V
|
||||
291 0 V
|
||||
0 115 V
|
||||
311 0 V
|
||||
0 449 V
|
||||
162 0 V
|
||||
0 309 V
|
||||
stroke
|
||||
grestore
|
||||
end
|
||||
showpage
|
||||
%%Trailer
|
||||
%%DocumentFonts: Helvetica
|
||||
%%Pages: 1
|
Before Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 4.3 KiB |
|
@ -1,394 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>BusyBox</TITLE>
|
||||
</HEAD>
|
||||
|
||||
<body text="#000000" alink="#660000" link="#660000" bgcolor="#dee2de" vlink="#660000">
|
||||
|
||||
<basefont face="lucida, helvetica, arial" size="3">
|
||||
|
||||
|
||||
<CENTER>
|
||||
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2>
|
||||
<TR>
|
||||
<td bgcolor="#000000">
|
||||
<FONT FACE="lucida, helvetica" COLOR="#ccccc0">
|
||||
<B>B u s y B o x</B>
|
||||
</FONT>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<a href="/"><IMG SRC="images/busybox2.jpg" alt="BusyBox" border="0" width="360" height="230"></a><BR>
|
||||
|
||||
|
||||
<!-- Begin Introduction section -->
|
||||
|
||||
|
||||
<TABLE WIDTH="95%" CELLSPACING=1 CELLPADDING=4 BORDER=1>
|
||||
<TR><TD BGCOLOR="#ccccc0" ALIGN=center>
|
||||
<A NAME="intro"> <BIG><B>
|
||||
The Swiss Army Knife of Embedded Linux
|
||||
</B></BIG></A>
|
||||
</TD></TR>
|
||||
<TR><TD BGCOLOR="#eeeee0">
|
||||
|
||||
BusyBox combines tiny versions of many common UNIX utilities into a single
|
||||
small executable. It provides minimalist replacements for most of the utilities
|
||||
you usually find in fileutils, shellutils, findutils, textutils, grep, gzip,
|
||||
tar, etc. BusyBox provides a fairly complete POSIX environment for any small or
|
||||
embedded system. The utilities in BusyBox generally have fewer options than
|
||||
their full featured GNU cousins; however, the options that are included provide
|
||||
the expected functionality and behave very much like their GNU counterparts.
|
||||
<p>
|
||||
BusyBox has been written with size-optimization and limited resources in mind.
|
||||
It is also extremely modular so you can easily include or exclude commands (or
|
||||
features) at compile time. This makes it easy to customize your embedded
|
||||
systems. To create a working system, just add /dev, /etc, and a kernel.
|
||||
<p>
|
||||
|
||||
BusyBox is now maintained by
|
||||
<a href="http://codepoet.org/andersen/erik/erik.html">
|
||||
Erik Andersen</a>, and its ongoing development is being sponsored by
|
||||
<a href="http://www.lineo.com/">Lineo</a>.
|
||||
<p>
|
||||
BusyBox is licensed under the
|
||||
<a href="http://www.gnu.org/copyleft/gpl.html">GNU GENERAL PUBLIC LICENSE</a>.
|
||||
<p>
|
||||
|
||||
|
||||
<h3> Screenshot </h3>
|
||||
|
||||
<p> Because everybody loves screenshots, a screenshot of BusyBox
|
||||
is now available <a href="screenshot.html">right here</a>.
|
||||
|
||||
|
||||
<H3>Mailing List Information</h3>
|
||||
BusyBox now has a <a href="http://opensource.lineo.com/lists/busybox/">mailing list</a>!
|
||||
To subscribe, go and visit <a href="http://opensource.lineo.com/mailman/listinfo/busybox">this page</a>.
|
||||
|
||||
<!-- Begin Latest News section -->
|
||||
|
||||
<TR><TD BGCOLOR="#ccccc0" ALIGN=center>
|
||||
<A NAME="news">
|
||||
<BIG><B>
|
||||
Latest News
|
||||
</B></BIG>
|
||||
</A>
|
||||
</TD></TR>
|
||||
<TR><TD BGCOLOR="#eeeee0">
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <b>23 August 2001 -- BusyBox 0.60.1 released</b>
|
||||
<br>
|
||||
|
||||
This is a relatively minor bug fixing release that fixes
|
||||
up the bugs that have shown up in the stable release in
|
||||
the last few weeks. Fortunately, nothing <em>too</em>
|
||||
serious has shown up. This release only fixes bugs -- no
|
||||
new features, no new applets. So without further ado,
|
||||
here it is. Come and get it.
|
||||
<p>
|
||||
The
|
||||
<a href="ftp://oss.lineo.com/busybox/Changelog">changelog</a> has all
|
||||
the details. As usual BusyBox 0.60.1 can be downloaded from
|
||||
<a href="ftp://oss.lineo.com/busybox">ftp://oss.lineo.com/busybox</a>.
|
||||
<p>Have Fun!
|
||||
<p>
|
||||
|
||||
|
||||
<li> <b>2 August 2001 -- BusyBox 0.60.0 released</b>
|
||||
<br>
|
||||
I am very pleased to announce the immediate availability of
|
||||
BusyBox 0.60.0. I have personally tested this release with libc5, glibc,
|
||||
and <a href="http://cvs.uclinux.org/uClibc.html">uClibc</a> on
|
||||
x86, ARM, and powerpc using linux 2.2 and 2.4, and I know a number
|
||||
of people using it on everything from ia64 to m68k with great success.
|
||||
Everything seems to be working very nicely now, so getting a nice
|
||||
stable bug-free(tm) release out seems to be in order. This releases fixes
|
||||
a memory leak in syslogd, a number of bugs in the ash and msh shells, and
|
||||
cleans up a number of things.
|
||||
|
||||
<p>
|
||||
|
||||
Those wanting an easy way to test the 0.60.0 release with uClibc can
|
||||
use <a href="http://user-mode-linux.sourceforge.net/">User-Mode Linux</a>
|
||||
to give it a try by downloading and compiling
|
||||
<a href="ftp://oss.lineo.com/buildroot.tar.gz">buildroot.tar.gz</a>.
|
||||
You don't have to be root or reboot your machine to run test this way.
|
||||
Preconfigured User-Mode Linux kernel source is also on oss.lineo.com.
|
||||
<p>
|
||||
Another cool thing is the nifty <a href="ftp://oss.lineo.com/busybox/tutorial/index.html">
|
||||
BusyBox Tutorial</a> contributed by K Computing. This requires
|
||||
a ShockWave plugin (or standalone viewer), so you may want to grab the
|
||||
the GPLed shockwave viewer from <a href="http://www.swift-tools.com/Flash/flash-0.4.10.tgz">here</a>
|
||||
to view the tutorial.
|
||||
<p>
|
||||
|
||||
Finally, In case you didn't notice anything odd about the
|
||||
version number of this release, let me point out that this release
|
||||
is <em>not</em> 0.53, because I bumped the version number up a
|
||||
bit. This reflects the fact that this release is intended to form
|
||||
a new stable BusyBox release series. If you need to rely on a
|
||||
stable version of BusyBox, you should plan on using the stable
|
||||
0.60.x series. If bugs show up then I will release 0.60.1, then
|
||||
0.60.2, etc... This is also intended to deal with the fact that
|
||||
the BusyBox build system will be getting a major overhaul for the
|
||||
next release and I don't want that to break products that people
|
||||
are shipping. To avoid that, the new build system will be
|
||||
released as part of a new BusyBox development series that will
|
||||
have some not-yet-decided-on odd version number. Once things
|
||||
stabilize and the new build system is working for everyone, then
|
||||
I will release that as a new stable release series.
|
||||
|
||||
<p>
|
||||
The
|
||||
<a href="ftp://oss.lineo.com/busybox/Changelog">changelog</a> has all
|
||||
the details. As usual BusyBox 0.60.0 can be downloaded from
|
||||
<a href="ftp://oss.lineo.com/busybox">ftp://oss.lineo.com/busybox</a>.
|
||||
<p>Have Fun!
|
||||
<p>
|
||||
|
||||
|
||||
<li> <b>7 July 2001 -- BusyBox 0.52 released</b>
|
||||
<br>
|
||||
|
||||
I am very pleased to announce the immediate availability of
|
||||
BusyBox 0.52 (the "new-and-improved rock-solid release"). This
|
||||
release is the result of <em>many</em> hours of work and has tons
|
||||
of bugfixes, optimizations, and cleanups. This release adds
|
||||
several new applets, including several new shells (such as hush, msh,
|
||||
and ash).
|
||||
|
||||
<p>
|
||||
The
|
||||
<a href="ftp://oss.lineo.com/busybox/Changelog">changelog</a> covers
|
||||
some of the more obvious details, but there are many many things that
|
||||
are not mentioned, but have been improved in subtle ways. As usual,
|
||||
BusyBox 0.52 can be downloaded from
|
||||
<a href="ftp://oss.lineo.com/busybox">ftp://oss.lineo.com/busybox</a>.
|
||||
<p>Have Fun!
|
||||
<p>
|
||||
|
||||
|
||||
<li> <b>10 April 2001 - Graph of Busybox Growth </b>
|
||||
<br>
|
||||
The illustrious Larry Doolittle has made a PostScript chart of the growth
|
||||
of the Busybox tarball size over time. It is available for downloading /
|
||||
viewing <a href= "busybox-growth.ps"> right here</a>.
|
||||
|
||||
<p> (Note that while the number of applets in Busybox has increased, you
|
||||
can still configure Busybox to be as small as you want by selectively
|
||||
turning off whichever applets you don't need.)
|
||||
<p>
|
||||
|
||||
|
||||
|
||||
<li> <b>Old News</b>
|
||||
<br>
|
||||
For the old news, visit <a href="http://busybox.lineo.com/oldnews.html">the old news page</a>.
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- Begin Download section -->
|
||||
|
||||
<TR><TD BGCOLOR="#ccccc0" ALIGN=center>
|
||||
<A NAME="download"><BIG><B>
|
||||
Download
|
||||
</B></BIG></A>
|
||||
</TD></TR>
|
||||
<TR><TD BGCOLOR="#eeeee0">
|
||||
<ul>
|
||||
|
||||
<li> Source for the latest release can always be downloaded from
|
||||
<a href="ftp://oss.lineo.com/busybox">ftp://oss.lineo.com/busybox</a>.
|
||||
|
||||
<li> A new snapshot of the source is made daily and is available as a GNU
|
||||
gzipped tarball <a href="busybox.tar.gz"> right here</a>.
|
||||
|
||||
<li> BusyBox now has its own publically browsable
|
||||
<a href="http://opensource.lineo.com/cgi-bin/cvsweb/busybox/">CVS tree</a>,
|
||||
anonymous
|
||||
<a href="http://opensource.lineo.com/cvs_anon.html">CVS access</a>, and
|
||||
for those that are actively contributing there is even
|
||||
<a href="http://opensource.lineo.com/cvs_write.html">CVS write access</a>.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- Begin Docs section -->
|
||||
|
||||
<TR><TD BGCOLOR="#ccccc0" ALIGN=center>
|
||||
<A NAME="docs"><BIG><B>
|
||||
Documentation
|
||||
</B></BIG></A>
|
||||
</TD></TR>
|
||||
<TR><TD BGCOLOR="#eeeee0">
|
||||
Current documentation for BusyBox includes:
|
||||
<ul>
|
||||
<li> <a href="ftp://oss.lineo.com/busybox/BusyBox.html">BusyBox.html</a>.
|
||||
This is a list of the all the available commands in BusyBox with
|
||||
complete usage information and examples of how to use each app. I
|
||||
have spent a <em>lot</em> of time updating these docs and trying to
|
||||
make them fairly comprehensive. If you find any errors (factual,
|
||||
grammatical, whatever) please let me know.
|
||||
<li> <a href="ftp://oss.lineo.com/busybox/README">README</a>.
|
||||
This is the README file included in the busybox source release.
|
||||
<li> <a href="http://bugs.lineo.com/db/pa/lbusybox.html">BusyBox Bugs</a>.
|
||||
Need to report a bug? Need to check if a bug has been filed?
|
||||
<li> If you need more help, the BusyBox
|
||||
<a href="http://opensource.lineo.com/lists/busybox/">mailing list</a> is
|
||||
a good place to start.
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- Begin Links section -->
|
||||
|
||||
<TR><TD BGCOLOR="#ccccc0" ALIGN=center>
|
||||
<A NAME="links">
|
||||
<BIG><B>
|
||||
Important Links
|
||||
</B></BIG>
|
||||
</A>
|
||||
</TD></TR>
|
||||
<TR><TD BGCOLOR="#eeeee0">
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <A HREF="http://perens.com/FreeSoftware/">
|
||||
Free Software from Bruce Perens</A><br>
|
||||
The original idea for BusyBox, and all versions up to 0.26 were written
|
||||
by <A HREF="mailto:bruce@perens.com">Bruce Perens</a>. This is his BusyBox website.
|
||||
<p>
|
||||
|
||||
<li> <A HREF="http://freshmeat.net/projects/busybox/">
|
||||
Freshmeat AppIndex record for BusyBox</A>
|
||||
<p>
|
||||
<li><a href="http://tinylogin.lineo.com/">TinyLogin</a>
|
||||
is a nice embedded tool for handling authentication, changing passwords,
|
||||
and similar tasks which nicely complements BusyBox.
|
||||
<p>
|
||||
|
||||
<li><a href="http://cvs.uclinux.org/uClibc.html">uClibc</a>
|
||||
is a C library for embedded systems. You can actually statically link
|
||||
a "Hello World" application under x86 that only takes 4k (as opposed to
|
||||
200k under GNU libc). It can do dynamic linking too and works nicely with
|
||||
BusyBox to create very small embedded systems.
|
||||
<p>
|
||||
|
||||
<li> <a href="http://opensource.lineo.com/software.html">Other cool embedded software</a>.
|
||||
<p>
|
||||
|
||||
<li> <a href="http://opensource.lineo.com/">opensource.lineo.com</a>.
|
||||
<p>
|
||||
|
||||
<li> <A HREF="http://www.lineo.com/">Lineo</A> is sponsoring BusyBox development.
|
||||
<p>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- Begin Projects section -->
|
||||
|
||||
<TR><TD BGCOLOR="#ccccc0" ALIGN=center>
|
||||
<A NAME="projects"><BIG><B>
|
||||
Products/Projects Using BusyBox
|
||||
</B></BIG></A>
|
||||
</TD></TR>
|
||||
<TR><TD BGCOLOR="#eeeee0">
|
||||
|
||||
<p> I know of the following products and/or projects that use BusyBox --
|
||||
listed in the order I happen to add them to the web page:
|
||||
|
||||
<ul>
|
||||
<li> <a href="http://www.lineo.com/products/embedix_linux/">Lineo Embedix Linux</a>
|
||||
<li> <a href="http://cvs.debian.org/boot-floppies/">Debian installer (boot floppies) project</a>
|
||||
<li> <a href="http://www.linuxrouter.org/">Linux Router Project </a>
|
||||
<li> <a href="http://linux-embedded.org/">LEM</a>
|
||||
<li> <a href="http://www.toms.net/rb/">tomsrtbt</a>
|
||||
<li> <a href="http://www.stormix.com/">Stormix Installer</a>
|
||||
<li> <a href="http://www.emacinc.com/linux2_sbc.htm">EMAC Linux 2.0 SBC</a>
|
||||
<li> <a href="http://www.trinux.org/">Trinux</a>
|
||||
<li> <a href="http://oddas.sourceforge.net/">ODDAS project</a>
|
||||
<li> <a href="http://www.kerbango.com/">The Kerbango Internet Radio</a>
|
||||
<li> <a href="http://www.linuxmagic.com/vpn/">LinuxMagic VPN Firewall</a>
|
||||
<li> <a href="http://byld.sourceforge.net/">Build Your Linux Disk</a>
|
||||
<li> <a href="http://homepages.ihug.co.nz/~ichi/baslinux.html">BasicLinux</a>
|
||||
<li> <a href="http://ibiblio.org/pub/Linux/system/recovery">Zdisk</a>
|
||||
<li> <a href="http://www.adtran.com">AdTran - VPN/firewall VPN Linux Distribution</a>
|
||||
<li> <a href="http://mkcdrec.ota.be/">mkCDrec - make CD-ROM recovery</a>
|
||||
<li> <a href="http://recycle.lbl.gov/~ldoolitt/bse/">Linux on nanoEngine</a>
|
||||
<li> <a href="http://www.zelow.no/floppyfw/"> Floppyfw</a>
|
||||
|
||||
<li> <a href="http://midori.transmeta.com/"> Midori Linux</a> - <a href=
|
||||
"http://www.wired.com/news/technology/0,1282,42399,00.html"> Article on
|
||||
Midori Linux</a> on <a href= "http://www.wired.com"> Wired</a>. Quote from
|
||||
Erik at the top of <a href=
|
||||
"http://www.wired.com/news/technology/0,1282,42399-2,00.html"> this
|
||||
page</a>
|
||||
|
||||
<li> <a href="http://www.ltsp.org/">Linux Terminal Server Project</a>
|
||||
<li> <a href="http://www.devil-linux.org/">Devil-Linux</a>
|
||||
|
||||
</ul>
|
||||
|
||||
<p> Do you use BusyBox? I'd love to know about it and I'd be happy to link to
|
||||
you.
|
||||
|
||||
|
||||
|
||||
<!-- End of Table -->
|
||||
|
||||
</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
|
||||
|
||||
<!-- Footer -->
|
||||
<HR>
|
||||
<TABLE WIDTH="100%">
|
||||
<TR>
|
||||
<TD>
|
||||
<font size="-1" face="arial, helvetica, sans-serif">
|
||||
Mail all comments, insults, suggestions and bribes to
|
||||
<a href="mailto:andersen@lineo.com">Erik Andersen</a><BR>
|
||||
The Busybox logo is copyright 1999,2000,2001, Erik Andersen.
|
||||
</font>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<a href="http://www.vim.org"><img border=0 width=90 height=36
|
||||
src="images/written.in.vi.png"
|
||||
alt="This site created with the vi editor"></a>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<a href="http://www.gimp.org/"><img border=0 width=90 height=36
|
||||
src="images/gfx_by_gimp.png" alt="Graphics by GIMP"></a>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<a href="http://www.linuxtoday.com"><img width=90 height=36
|
||||
src="images/ltbutton2.png" alt="Linux Today"></a>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<p><a href="http://slashdot.org"><img width=90 height=36
|
||||
src="images/sdsmall.png" alt="Slashdot"></a>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<a href="http://freshmeat.net"><img width=90 height=36
|
||||
src="images/fm.mini.png" alt="Freshmeat"></a>
|
||||
</TD>
|
||||
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
|
||||
</CENTER>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
|
@ -1,465 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>BusyBox</TITLE>
|
||||
</HEAD>
|
||||
|
||||
<body text="#000000" alink="#660000" link="#660000" bgcolor="#dee2de" vlink="#660000">
|
||||
|
||||
<basefont face="lucida, helvetica, arial" size="3">
|
||||
|
||||
|
||||
<CENTER>
|
||||
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2>
|
||||
<TR>
|
||||
<td bgcolor="#000000">
|
||||
<FONT FACE="lucida, helvetica" COLOR="#ccccc0">
|
||||
<B>B u s y B o x</B>
|
||||
</FONT>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<a href="/"><IMG SRC="images/busybox2.jpg" alt="BusyBox" border="0" width="360" height="230"</a><BR>
|
||||
|
||||
|
||||
<TABLE WIDTH=95% CELLSPACING=1 CELLPADDING=4 BORDER=1>
|
||||
|
||||
<!-- Begin Older News section -->
|
||||
|
||||
<TR><TD BGCOLOR="#ccccc0" ALIGN=center>
|
||||
<A NAME="news">
|
||||
<BIG><B>
|
||||
Older BusyBox News</A>
|
||||
</B></BIG>
|
||||
</A>
|
||||
</TD></TR>
|
||||
<TR><TD BGCOLOR="#eeeee0">
|
||||
|
||||
<ul>
|
||||
|
||||
<p> <li> <b>Take me back to the <a href="http://busybox.lineo.com/">BusyBox</a> web site.</b>
|
||||
<hr>
|
||||
|
||||
<li> <b>10 April 2001 -- BusyBox 0.51 released</b>
|
||||
<br>
|
||||
|
||||
BusyBox 0.51 (the "rock-solid release") is now out there. This
|
||||
release adds only 2 new applets: env and vi. The vi applet,
|
||||
contributed by Sterling Huxley, is very functional, and is only
|
||||
22k. This release fixes 3 critical bugs in the 0.50 release.
|
||||
There were 2 potential segfaults in lash (the busybox shell) in
|
||||
the 0.50 release which are now fixed. Another critical bug in
|
||||
0.50 which is now fixed: syslogd from 0.50 could potentially
|
||||
deadlock the init process and thereby break your entire system.
|
||||
<p>
|
||||
|
||||
There are a number of improvements in this release as well. For
|
||||
one thing, the wget applet is greatly improved. Dmitry Zakharov
|
||||
added FTP support, and Laurence Anderson make wget fully RFC
|
||||
compliant for HTTP 1.1. The mechanism for including utility
|
||||
functions in previous releases was clumsy and error prone. Now
|
||||
all utility functions are part of a new libbb library, which makes
|
||||
maintaining utility functions much simpler. And BusyBox now
|
||||
compiles on itanium systems (thanks to the Debian itanium porters
|
||||
for letting me use their system!).
|
||||
<p>
|
||||
You can read the
|
||||
<a href="ftp://oss.lineo.com/busybox/Changelog">changelog</a> for
|
||||
complete details. BusyBox 0.51 can be downloaded from
|
||||
<a href="ftp://oss.lineo.com/busybox">ftp://oss.lineo.com/busybox</a>.
|
||||
<p>Have Fun!
|
||||
<p>
|
||||
|
||||
<li> <b>Busybox Boot-Floppy Image</b>
|
||||
|
||||
<p>Because you asked for it, we have made available a <a href=
|
||||
"ftp://opensource.lineo.com/busybox/busybox.floppy.img"> Busybox boot floppy
|
||||
image</a>. Here's how you use it:
|
||||
|
||||
<ol>
|
||||
|
||||
<li> <a href= "ftp://opensource.lineo.com/busybox/busybox.floppy.img">
|
||||
Download the image</a>
|
||||
|
||||
<li> dd it onto a floppy like so: <tt> dd if=busybox.floppy.img
|
||||
of=/dev/fd0 ; sync </tt>
|
||||
|
||||
<li> Pop it in a machine and boot up.
|
||||
|
||||
</ol>
|
||||
|
||||
<p> If you want to look at the contents of the initrd image, do this:
|
||||
|
||||
<pre>
|
||||
mount ./busybox.floppy.img /mnt -o loop -t msdos
|
||||
cp /mnt/initrd.gz /tmp
|
||||
umount /mnt
|
||||
gunzip /tmp/initrd.gz
|
||||
mount /tmp/initrd /mnt -o loop -t minix
|
||||
</pre>
|
||||
|
||||
|
||||
<li> <b>15 March 2001 -- BusyBox 0.50 released</b>
|
||||
<br>
|
||||
|
||||
This release adds several new applets including ifconfig, route, pivot_root, stty,
|
||||
and tftp, and also fixes tons of bugs. Tab completion in the
|
||||
shell is now working very well, and the shell's environment variable
|
||||
expansion was fixed. Tons of other things were fixed or made
|
||||
smaller. For a fairly complete overview, see the
|
||||
<a href="ftp://oss.lineo.com/busybox/Changelog">changelog</a>.
|
||||
<p>
|
||||
lash (the busybox shell) is still with us, fixed up a bit so it
|
||||
now behaves itself quite nicely. It really is quite usable as
|
||||
long as you don't expect it to provide Bourne shell grammer.
|
||||
Standard things like pipes, redirects, command line editing, and
|
||||
environment variable expansion work great. But we have found that
|
||||
this shell, while very usable, does not provide an extensible
|
||||
framework for adding in full Bourne shell behavior. So the first order of
|
||||
business as we begin working on the next BusyBox release will be to merge in the new shell
|
||||
currently in progress at
|
||||
<a href="http://doolittle.faludi.com/~larry/parser.html">Larry Doolittle's website</a>.
|
||||
<p>
|
||||
|
||||
|
||||
<li> <b>27 January 2001 -- BusyBox 0.49 released</b>
|
||||
<br>
|
||||
|
||||
Several new applets, lots of bug fixes, cleanups, and many smaller
|
||||
things made nicer. Several cleanups and improvements to the shell.
|
||||
For a list of the most interesting changes
|
||||
you might want to look at the <a href="ftp://oss.lineo.com/busybox/Changelog">changelog</a>.
|
||||
<p>
|
||||
Special thanks go out to Matt Kraai and Larry Doolittle for all their
|
||||
work on this release, and for keeping on top of things while I've been
|
||||
out of town.
|
||||
<p>
|
||||
<em>Special Note</em><br>
|
||||
|
||||
BusyBox 0.49 was supposed to have replaced lash, the BusyBox
|
||||
shell, with a new shell that understands full Bourne shell/Posix shell grammer.
|
||||
Well, that simply didn't happen in time for this release. A new
|
||||
shell that will eventually replace lash is already under
|
||||
construction. This new shell is being developed by Larry
|
||||
Doolittle, and could use all of our help. Please see the work in
|
||||
progress on <a href="http://doolittle.faludi.com/~larry/parser.html">Larry's website</a>
|
||||
and help out if you can. This shell will be included in the next
|
||||
release of BusyBox.
|
||||
<p>
|
||||
|
||||
<li> <b>13 December 2000 -- BusyBox 0.48 released</b>
|
||||
<br>
|
||||
|
||||
This release fixes lots and lots of bugs. This has had some very
|
||||
rigorous testing, and looks very, very clean. The usual tar
|
||||
update of course: tar no longer breaks hardlinks, tar -xzf is
|
||||
optionally supported, and the LRP folks will be pleased to know
|
||||
that 'tar -X' and 'tar --exclude' are both now in. Applets are
|
||||
now looked up using a binary search making lash (the busybox
|
||||
shell) much faster. For the new debian-installer (for Debian
|
||||
woody) a .udeb can now be generated.
|
||||
<p>
|
||||
The curious can get a list of some of the more interesting changes by reading
|
||||
the <a href="ftp://oss.lineo.com/busybox/Changelog">changelog</a>.
|
||||
<p>
|
||||
Many thanks go out to the many many people that have contributed to
|
||||
this release, especially Matt Kraai, Larry Doolittle, and Kent Robotti.
|
||||
<p>
|
||||
<p> <li> <b>26 September 2000 -- BusyBox 0.47 released</b>
|
||||
<br>
|
||||
|
||||
This release fixes lots of bugs (including an ugly bug in 0.46
|
||||
syslogd that could fork-bomb your system). Added several new
|
||||
apps: rdate, wget, getopt, dos2unix, unix2dos, reset, unrpm,
|
||||
renice, xargs, and expr. syslogd now supports network logging.
|
||||
There are the usual tar updates. Most apps now use getopt for
|
||||
more correct option parsing.
|
||||
See the <a href="ftp://oss.lineo.com/busybox/Changelog">changelog</a>
|
||||
for complete details.
|
||||
|
||||
|
||||
<p> <li> <b>11 July 2000 -- BusyBox 0.46 released</b>
|
||||
<br>
|
||||
|
||||
This release fixes several bugs (including a ugly bug in tar,
|
||||
and fixes for NFSv3 mount support). Added a dumpkmap to allow
|
||||
people to dump a binary keymaps for use with 'loadkmap', and a
|
||||
completely reworked 'grep' and 'sed' which should behave better.
|
||||
BusyBox shell can now also be used as a login shell.
|
||||
See the <a href="ftp://oss.lineo.com/busybox/Changelog">changelog</a>
|
||||
for complete details.
|
||||
|
||||
|
||||
<p> <li> <b>21 June 2000 -- BusyBox 0.45 released</b>
|
||||
<br>
|
||||
|
||||
This release has been slow in coming, but is very solid at this
|
||||
point. BusyBox now supports libc5 as well as GNU libc. This
|
||||
release provides the following new apps: cut, tr, insmod, ar,
|
||||
mktemp, setkeycodes, md5sum, uuencode, uudecode, which, and
|
||||
telnet. There are bug fixes for just about every app as well (see
|
||||
the <a href="ftp://oss.lineo.com/busybox/Changelog">changelog</a> for
|
||||
details).
|
||||
<p>
|
||||
Also, some exciting infrastructure news! Busybox now has its own
|
||||
<a href="http://opensource.lineo.com/lists/busybox/">mailing list</a>,
|
||||
publically browsable
|
||||
<a href="http://opensource.lineo.com/cgi-bin/cvsweb/busybox/">CVS tree</a>,
|
||||
anonymous
|
||||
<a href="http://opensource.lineo.com/cvs_anon.html">CVS access</a>, and
|
||||
for those that are actively contributing there is even
|
||||
<a href="http://opensource.lineo.com/cvs_write.html">CVS write access</a>.
|
||||
I think this will be a huge help to the ongoing development of BusyBox.
|
||||
<p>
|
||||
Also, for the curious, there is no 0.44 release. Somehow 0.44 got announced
|
||||
a few weeks ago prior to its actually being released. To avoid any confusion
|
||||
we are just skipping 0.44.
|
||||
<p>
|
||||
Many thanks go out to the many people that have contributed to this release
|
||||
of BusyBox (esp. Pavel Roskin)!
|
||||
|
||||
|
||||
<p> <li> <b>19 April 2000 -- syslogd bugfix</b>
|
||||
<br>
|
||||
Turns out that there was still a bug in busybox syslogd.
|
||||
For example, with the following test app:
|
||||
<pre>
|
||||
#include <syslog.h>
|
||||
|
||||
int do_log(char* msg, int delay)
|
||||
{
|
||||
openlog("testlog", LOG_PID, LOG_DAEMON);
|
||||
while(1) {
|
||||
syslog(LOG_ERR, "%s: testing one, two, three\n", msg);
|
||||
sleep(delay);
|
||||
}
|
||||
closelog();
|
||||
return(0);
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (fork()==0)
|
||||
do_log("A", 2);
|
||||
do_log("B", 3);
|
||||
}
|
||||
</pre>
|
||||
it should be logging stuff from both "A" and "B". As released in 0.43 only stuff
|
||||
from "A" would have been logged. This means that if init tries to log something
|
||||
while say ppp has the syslog open, init would block (which is bad, bad, bad).
|
||||
<p>
|
||||
Karl M. Hegbloom has created a
|
||||
<a href="ftp://ftp.lineo.com/pub/busybox/busybox-0.43-syslog_patch">fix for the problem</a>.
|
||||
Thanks Karl!
|
||||
|
||||
|
||||
<p> <li> <b>18 April 2000 -- BusyBox 0.43 released (finally!)</b>
|
||||
<br>
|
||||
I have finally gotten everything into a state where I feel pretty
|
||||
good about things. This is definitely the most stable, solid release
|
||||
so far. A lot of bugs have been fixed, and the following new apps
|
||||
have been added: sh, basename, dirname, killall, uptime,
|
||||
freeramdisk, tr, echo, test, and usleep. Tar has been completely
|
||||
rewritten from scratch. Bss size has also been greatly reduced.
|
||||
More details are available in the
|
||||
<a href="ftp://ftp.lineo.com/pub/busybox/Changelog">changelog</a>.
|
||||
Oh, and as a special bonus, I wrote some fairly comprehensive
|
||||
<em>documentation</em>, complete with examples and full usage information.
|
||||
|
||||
<p>
|
||||
Many thanks go out to the fine people that have helped by submitting patches
|
||||
and bug reports; particularly instrumental in helping for this release were
|
||||
Karl Hegbloom, Pavel Roskin, Friedrich Vedder, Emanuele Caratti,
|
||||
Bob Tinsley, Nicolas Pitre, Avery Pennarun, Arne Bernin, John Beppu, and Jim Gleason.
|
||||
There were others so if I somehow forgot to mention you, I'm very sorry.
|
||||
<p>
|
||||
|
||||
You can grab BusyBox 0.43 tarballs <a href="ftp://ftp.lineo.com/pub/busybox/">here</a>.
|
||||
|
||||
<p> <li> <b>9 April 2000 -- BusyBox 0.43 pre release</b>
|
||||
<br>
|
||||
Unfortunately, I have not yet finished all the things I want to
|
||||
do for BusyBox 0.43, so I am posting this pre-release for people
|
||||
to poke at. This contains my complete rewrite of tar, which now weighs in at
|
||||
5k (7k with all options turned on) and works for reading and writing
|
||||
tarballs (which it does correctly for everything I have been able to throw
|
||||
at it). Tar also (optionally) supports the "--exclude" option (mainly because
|
||||
the Linux Router Project folks asked for it). This also has a pre-release
|
||||
of the micro shell I have been writing. This pre-release should be stable
|
||||
enough for production use -- it just isn't a release since I have some structural
|
||||
changes I still want to make.
|
||||
<p>
|
||||
The pre-release can be found <a href="ftp://ftp.lineo.com/pub/busybox/">here</a>.
|
||||
Please let me know ASAP if you find <em>any</em> bugs.
|
||||
|
||||
<p> <li> <b>28 March 2000 -- Andersen Baby Boy release</b>
|
||||
<br>
|
||||
I am pleased to announce that on Tuesday March 28th at 5:48pm, weighing in at 7
|
||||
lbs. 12 oz, Micah Erik Andersen was born at LDS Hospital here in Salt Lake City.
|
||||
He was born in the emergency room less then 5 minutes after we arrived -- and
|
||||
it was such a relief that we even made it to the hospital at all. Despite the
|
||||
fact that I was driving at an amazingly unlawful speed and honking at everybody
|
||||
and thinking decidedly unkind thoughts about the people in our way, my wife
|
||||
(inconsiderate of my feelings and complete lack of medical training) was lying
|
||||
down in the back seat saying things like "I think I need to start pushing now"
|
||||
(which she then proceeded to do despite my best encouraging statements to the
|
||||
contrary).
|
||||
<p>
|
||||
Anyway, I'm glad to note that despite the much-faster-than-we-were-expecting
|
||||
labor, both Shaunalei and our new baby boy are doing wonderfully.
|
||||
<p>
|
||||
So now that I am done with my excuse for the slow release cycle...
|
||||
Progress on the next release of BusyBox has been slow but steady. I expect
|
||||
to have a release sometime during the first week of April. This release will
|
||||
include a number of important changes, including the addition of a shell, a
|
||||
re-write of tar (to accommodate the Linux Router Project), and syslogd can now
|
||||
accept multiple concurrent connections, fixing lots of unexpected blocking
|
||||
problems.
|
||||
|
||||
|
||||
<p> <li> <b>11 February 2000 -- BusyBox 0.42 released</b>
|
||||
<br>
|
||||
|
||||
This is the most solid BusyBox release so far. Many, many
|
||||
bugs have been fixed. See the
|
||||
<a href="ftp://ftp.lineo.com/pub/busybox/Changelog">changelog</a> for details.
|
||||
|
||||
Of particular interest, init will now cleanly unmount
|
||||
filesystems on reboot, cp and mv have been rewritten and
|
||||
behave much better, and mount and umount no longer leak
|
||||
loop devices. Many thanks go out to Randolph Chung,
|
||||
Karl M. Hegbloom, Taketoshi Sano, and Pavel Roskin for
|
||||
their hard work on this release of BusyBox. Please pound
|
||||
on it and let me know if you find any bugs.
|
||||
|
||||
<p> <li> <b>19 January 2000 -- BusyBox 0.41 released</b>
|
||||
<br>
|
||||
|
||||
This release includes bugfixes to cp, mv, logger, true, false,
|
||||
mkdir, syslogd, and init. New apps include wc, hostid,
|
||||
logname, tty, whoami, and yes. New features include loop device
|
||||
support in mount and umount, and better TERM handling by init.
|
||||
The changelog can be found <a href="ftp://ftp.lineo.com/pub/busybox/Changelog">here</a>.
|
||||
|
||||
<p> <li> <b>7 January 2000 -- BusyBox 0.40 released</b>
|
||||
<br>
|
||||
|
||||
This release includes bugfixes to init (now includes inittab support),
|
||||
syslogd, head, logger, du, grep, cp, mv, sed, dmesg, ls, kill, gunzip, and mknod.
|
||||
New apps include sort, uniq, lsmod, rmmod, fbset, and loadacm.
|
||||
In particular, this release fixes an important bug in tar which
|
||||
in some cases produced serious security problems.
|
||||
As always, the changelog can be found <a href="ftp://ftp.lineo.com/pub/busybox/Changelog">here</a>.
|
||||
|
||||
<p> <li> <b>11 December 1999 -- BusyBox Website</b>
|
||||
<br>
|
||||
I have received permission from Bruce Perens (the original author of BusyBox)
|
||||
to set up this site as the new primary website for BusyBox. This website
|
||||
will always contain pointers to the latest and greatest, and will also
|
||||
contain the latest documentation on how to use BusyBox, what it can do,
|
||||
what arguments its apps support, etc.
|
||||
|
||||
<p> <li> <b>10 December 1999 -- BusyBox 0.39 released</b>
|
||||
<br>
|
||||
This release includes fixes to init, reboot, halt, kill, and ls, and contains
|
||||
the new apps ping, hostname, mkfifo, free, tail, du, tee, and head. A full
|
||||
changelog can be found <a href="ftp://ftp.lineo.com/pub/busybox/Changelog">here</a>.
|
||||
<p> <li> <b>5 December 1999 -- BusyBox 0.38 released</b>
|
||||
<br>
|
||||
This release includes fixes to tar, cat, ls, dd, rm, umount, find, df,
|
||||
and make install, and includes new apps syslogd/klogd and logger.
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- Begin Links section -->
|
||||
|
||||
<TR><TD BGCOLOR="#ccccc0" ALIGN=center>
|
||||
<A NAME="links">
|
||||
<BIG><B>
|
||||
Important Links</A>
|
||||
</B></BIG>
|
||||
</A>
|
||||
</TD></TR>
|
||||
<TR><TD BGCOLOR="#eeeee0">
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <a href="http://busybox.lineo.com/">Take me back to http://busybox.lineo.com/</a>.
|
||||
<p>
|
||||
|
||||
<li> <A HREF="http://perens.com/FreeSoftware/">
|
||||
Free Software from Bruce Perens</A><br>
|
||||
The original idea for BusyBox, and all versions up to 0.26 were written
|
||||
by <A HREF="mailto:bruce@perens.com">Bruce Perens</a>. This is his BusyBox website.
|
||||
<p>
|
||||
|
||||
<li> <A HREF="http://freshmeat.net/appindex/1999/04/11/923859921.html">
|
||||
Freshmeat AppIndex record for BusyBox</A>
|
||||
<p>
|
||||
|
||||
<li> <a href="http://opensource.lineo.com/software.html">Other cool embedded software</a>.
|
||||
<p>
|
||||
|
||||
<li> <a href="http://opensource.lineo.com/">opensource.lineo.com</a>.
|
||||
<p>
|
||||
|
||||
<li> <A HREF="http://www.lineo.com/">Lineo</A> is sponsoring BusyBox development.
|
||||
<p>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- End of Table -->
|
||||
|
||||
</TD></TR>
|
||||
</TABLE>
|
||||
</P>
|
||||
|
||||
|
||||
|
||||
<!-- Footer -->
|
||||
<HR>
|
||||
<TABLE WIDTH="100%">
|
||||
<TR>
|
||||
<TD>
|
||||
<font size="-1" face="arial, helvetica, sans-serif">
|
||||
Mail all comments, insults, suggestions and bribes to
|
||||
<a href="mailto:andersen@lineo.com">Erik Andersen</a><BR>
|
||||
The Busybox logo is copyright 1999,2000, Erik Andersen.
|
||||
</font>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<a href="http://www.vim.org"><img border=0 width=88 height=32
|
||||
src="images/anim.written.in.vi.gif"
|
||||
alt="This site created with the vi editor"></a>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<a href="http://www.gimp.org/"><img border=0 width=88 height=38
|
||||
src="images/gfx_by_gimp.gif" alt="Graphics by GIMP"></a>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<a href="http://www.linuxtoday.com"><img width=90 height=36
|
||||
src="images/ltbutton2.jpg" alt="Linux Today"></a>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<p><a href="http://slashdot.org"><img width=90 height=36
|
||||
src="images/sdsmall.gif" alt="Slashdot"></a>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<a href="http://freshmeat.net"><img width=90 height=36
|
||||
src="images/fm.mini.jpg" alt="Freshmeat"></a>
|
||||
</TD>
|
||||
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
|
||||
<title> Busybox Screenshot! </title>
|
||||
|
||||
<meta name="Author" content="Mark Whitley">
|
||||
<meta name="Description" content="A screenshot of Busybox">
|
||||
|
||||
</head>
|
||||
|
||||
<body text="#000000" alink="#660000" link="#660000" bgcolor="#dee2de" vlink="#660000">
|
||||
|
||||
<h1> Busybox Screenshot! </h1>
|
||||
|
||||
<TABLE WIDTH="80%" CELLSPACING=1 CELLPADDING=4 BORDER=1>
|
||||
<TR><TD BGCOLOR="#000000">
|
||||
|
||||
|
||||
<pre style="background-color: black; color: lightgreen; padding: 5px;
|
||||
font-family: monospace; font-size: smaller;" width="80%">
|
||||
|
||||
|
||||
$ ./busybox
|
||||
BusyBox v0.49 (2001.01.30-17:35+0000) multi-call binary -- GPL2
|
||||
|
||||
Usage: busybox [function] [arguments]...
|
||||
or: [function] [arguments]...
|
||||
|
||||
BusyBox is a multi-call binary that combines many common Unix
|
||||
utilities into a single executable. Most people will create a
|
||||
link to busybox for each function they wish to use, and BusyBox
|
||||
will act like whatever it was invoked as.
|
||||
|
||||
Currently defined functions:
|
||||
basename, busybox, cat, chgrp, chmod, chown, chroot, chvt, clear,
|
||||
cp, cut, date, dd, df, dirname, dmesg, du, echo, false, find,
|
||||
free, grep, gunzip, gzip, halt, head, id, init, kill, killall,
|
||||
ln, logger, ls, lsmod, mkdir, mknod, mkswap, more, mount, mv,
|
||||
poweroff, ps, pwd, reboot, reset, rm, rmdir, sed, sh, sleep, sort,
|
||||
swapoff, swapon, sync, syslogd, tail, tar, touch, true, tty, umount,
|
||||
uname, uniq, uptime, wc, which, whoami, xargs, yes, zcat
|
||||
|
||||
$ <blink>_</blink>
|
||||
|
||||
</pre>
|
||||
|
||||
</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
* Without arguments it reverts the format (e.i. if source is in UNIX format,
|
||||
* output is in DOS format and vice versa).
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* See the COPYING file for license information.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include "busybox.h"
|
||||
|
||||
|
||||
/* We are making a lame pseudo-random string generator here. in
|
||||
* convert(), each pass through the while loop will add more and more
|
||||
* stuff into value, which is _supposed_ to wrap. We don't care about
|
||||
* it being accurate. We care about it being messy, since we then mod
|
||||
* it by the sizeof(letters) and then use that as an index into letters
|
||||
* to pick a random letter to add to out temporary file. */
|
||||
typedef unsigned long int bb_uint64_t;
|
||||
|
||||
static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
// if fn is NULL then input is stdin and output is stdout
|
||||
static int convert(char *fn, int ConvType)
|
||||
{
|
||||
int c, fd;
|
||||
struct timeval tv;
|
||||
char tempFn[BUFSIZ];
|
||||
static bb_uint64_t value=0;
|
||||
FILE *in = stdin, *out = stdout;
|
||||
|
||||
if (fn != NULL) {
|
||||
if ((in = wfopen(fn, "rw")) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
strcpy(tempFn, fn);
|
||||
c = strlen(tempFn);
|
||||
tempFn[c] = '.';
|
||||
while(1) {
|
||||
if (c >=BUFSIZ)
|
||||
error_msg_and_die("unique name not found");
|
||||
/* Get some semi random stuff to try and make a
|
||||
* random filename based (and in the same dir as)
|
||||
* the input file... */
|
||||
gettimeofday (&tv, NULL);
|
||||
value += ((bb_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid ();
|
||||
tempFn[++c] = letters[value % 62];
|
||||
tempFn[c+1] = '\0';
|
||||
value /= 62;
|
||||
|
||||
if ((fd = open(tempFn, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0 ) {
|
||||
continue;
|
||||
}
|
||||
out = fdopen(fd, "w+");
|
||||
if (!out) {
|
||||
close(fd);
|
||||
remove(tempFn);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while ((c = fgetc(in)) != EOF) {
|
||||
if (c == '\r') {
|
||||
if ((ConvType == CT_UNIX2DOS) && (fn != NULL)) {
|
||||
// file is alredy in DOS format so it is not necessery to touch it
|
||||
remove(tempFn);
|
||||
if (fclose(in) < 0 || fclose(out) < 0) {
|
||||
perror_msg(NULL);
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (!ConvType)
|
||||
ConvType = CT_DOS2UNIX;
|
||||
break;
|
||||
}
|
||||
if (c == '\n') {
|
||||
if ((ConvType == CT_DOS2UNIX) && (fn != NULL)) {
|
||||
// file is alredy in UNIX format so it is not necessery to touch it
|
||||
remove(tempFn);
|
||||
if ((fclose(in) < 0) || (fclose(out) < 0)) {
|
||||
perror_msg(NULL);
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (!ConvType) {
|
||||
ConvType = CT_UNIX2DOS;
|
||||
}
|
||||
if (ConvType == CT_UNIX2DOS) {
|
||||
fputc('\r', out);
|
||||
}
|
||||
fputc('\n', out);
|
||||
break;
|
||||
}
|
||||
fputc(c, out);
|
||||
}
|
||||
if (c != EOF)
|
||||
while ((c = fgetc(in)) != EOF) {
|
||||
if (c == '\r')
|
||||
continue;
|
||||
if (c == '\n') {
|
||||
if (ConvType == CT_UNIX2DOS)
|
||||
fputc('\r', out);
|
||||
fputc('\n', out);
|
||||
continue;
|
||||
}
|
||||
fputc(c, out);
|
||||
}
|
||||
|
||||
if (fn != NULL) {
|
||||
if (fclose(in) < 0 || fclose(out) < 0) {
|
||||
perror_msg(NULL);
|
||||
remove(tempFn);
|
||||
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(tempFn, fn) < 0) {
|
||||
perror_msg("unable to rename '%s' as '%s'", tempFn, fn);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dos2unix_main(int argc, char *argv[])
|
||||
{
|
||||
int ConvType = CT_AUTO;
|
||||
int o;
|
||||
|
||||
//See if we are supposed to be doing dos2unix or unix2dos
|
||||
if (argv[0][0]=='d') {
|
||||
ConvType = CT_DOS2UNIX;
|
||||
}
|
||||
if (argv[0][0]=='u') {
|
||||
ConvType = CT_UNIX2DOS;
|
||||
}
|
||||
|
||||
// process parameters
|
||||
while ((o = getopt(argc, argv, "du")) != EOF) {
|
||||
switch (o) {
|
||||
case 'd':
|
||||
ConvType = CT_UNIX2DOS;
|
||||
break;
|
||||
case 'u':
|
||||
ConvType = CT_DOS2UNIX;
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
while(optind < argc)
|
||||
if ((o = convert(argv[optind++], ConvType)) < 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
o = convert(NULL, ConvType);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
1445
busybox/dpkg.c
|
@ -1,130 +0,0 @@
|
|||
/*
|
||||
* 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 Library 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include "busybox.h"
|
||||
|
||||
extern int dpkg_deb_main(int argc, char **argv)
|
||||
{
|
||||
char *prefix = NULL;
|
||||
char *filename = NULL;
|
||||
char *output_buffer = NULL;
|
||||
int opt = 0;
|
||||
int arg_type = 0;
|
||||
int deb_extract_funct = extract_create_leading_dirs | extract_unconditional;
|
||||
|
||||
const int arg_type_prefix = 1;
|
||||
const int arg_type_field = 2;
|
||||
const int arg_type_filename = 4;
|
||||
// const int arg_type_un_ar_gz = 8;
|
||||
|
||||
while ((opt = getopt(argc, argv, "ceftXxI")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
deb_extract_funct |= extract_data_tar_gz;
|
||||
deb_extract_funct |= extract_verbose_list;
|
||||
break;
|
||||
case 'e':
|
||||
arg_type = arg_type_prefix;
|
||||
deb_extract_funct |= extract_control_tar_gz;
|
||||
deb_extract_funct |= extract_all_to_fs;
|
||||
break;
|
||||
case 'f':
|
||||
arg_type = arg_type_field;
|
||||
deb_extract_funct |= extract_control_tar_gz;
|
||||
deb_extract_funct |= extract_one_to_buffer;
|
||||
filename = xstrdup("./control");
|
||||
break;
|
||||
case 't': /* --fsys-tarfile, i just made up this short name */
|
||||
/* Integrate the functionality needed with some code from ar.c */
|
||||
error_msg_and_die("Option disabled");
|
||||
// arg_type = arg_type_un_ar_gz;
|
||||
break;
|
||||
case 'X':
|
||||
arg_type = arg_type_prefix;
|
||||
deb_extract_funct |= extract_data_tar_gz;
|
||||
deb_extract_funct |= extract_all_to_fs;
|
||||
deb_extract_funct |= extract_list;
|
||||
case 'x':
|
||||
arg_type = arg_type_prefix;
|
||||
deb_extract_funct |= extract_data_tar_gz;
|
||||
deb_extract_funct |= extract_all_to_fs;
|
||||
break;
|
||||
case 'I':
|
||||
arg_type = arg_type_filename;
|
||||
deb_extract_funct |= extract_control_tar_gz;
|
||||
deb_extract_funct |= extract_one_to_buffer;
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (optind == argc) {
|
||||
show_usage();
|
||||
}
|
||||
|
||||
/* Workout where to extract the files */
|
||||
if (arg_type == arg_type_prefix) {
|
||||
/* argument is a dir name */
|
||||
if ((optind + 1) == argc ) {
|
||||
prefix = xstrdup("./DEBIAN/");
|
||||
} else {
|
||||
prefix = (char *) xmalloc(strlen(argv[optind + 1]) + 2);
|
||||
strcpy(prefix, argv[optind + 1]);
|
||||
/* Make sure the directory has a trailing '/' */
|
||||
if (last_char_is(prefix, '/') == NULL) {
|
||||
strcat(prefix, "/");
|
||||
}
|
||||
}
|
||||
mkdir(prefix, 0777);
|
||||
}
|
||||
|
||||
if (arg_type == arg_type_filename) {
|
||||
if ((optind + 1) != argc) {
|
||||
filename = xstrdup(argv[optind + 1]);
|
||||
} else {
|
||||
error_msg_and_die("-I currently requires a filename to be specified");
|
||||
}
|
||||
}
|
||||
|
||||
output_buffer = deb_extract(argv[optind], stdout, deb_extract_funct, prefix, filename);
|
||||
|
||||
if ((arg_type == arg_type_filename) && (output_buffer != NULL)) {
|
||||
puts(output_buffer);
|
||||
}
|
||||
else if (arg_type == arg_type_field) {
|
||||
char *field = NULL;
|
||||
char *name;
|
||||
char *value;
|
||||
int field_start = 0;
|
||||
|
||||
while (1) {
|
||||
field_start += read_package_field(&output_buffer[field_start], &name, &value);
|
||||
if (name == NULL) {
|
||||
break;
|
||||
}
|
||||
if (strcmp(name, argv[optind + 1]) == 0) {
|
||||
puts(value);
|
||||
}
|
||||
free(field);
|
||||
}
|
||||
}
|
||||
|
||||
return(EXIT_SUCCESS);
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini dumpkmap implementation for busybox
|
||||
*
|
||||
* Copyright (C) Arne Bernin <arne@matrix.loopback.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 <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "busybox.h"
|
||||
|
||||
/* From <linux/kd.h> */
|
||||
struct kbentry {
|
||||
unsigned char kb_table;
|
||||
unsigned char kb_index;
|
||||
unsigned short kb_value;
|
||||
};
|
||||
static const int KDGKBENT = 0x4B46; /* gets one entry in translation table */
|
||||
|
||||
/* From <linux/keyboard.h> */
|
||||
static const int NR_KEYS = 128;
|
||||
static const int MAX_NR_KEYMAPS = 256;
|
||||
|
||||
int dumpkmap_main(int argc, char **argv)
|
||||
{
|
||||
struct kbentry ke;
|
||||
int i, j, fd;
|
||||
char flags[MAX_NR_KEYMAPS], magic[] = "bkeymap";
|
||||
|
||||
if (argc>=2 && *argv[1]=='-') {
|
||||
show_usage();
|
||||
}
|
||||
|
||||
fd = open(CURRENT_VC, O_RDWR);
|
||||
if (fd < 0) {
|
||||
perror_msg("Error opening " CURRENT_VC);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
write(1, magic, 7);
|
||||
|
||||
for (i=0; i < MAX_NR_KEYMAPS; i++) flags[i]=0;
|
||||
flags[0]=1;
|
||||
flags[1]=1;
|
||||
flags[2]=1;
|
||||
flags[4]=1;
|
||||
flags[5]=1;
|
||||
flags[6]=1;
|
||||
flags[8]=1;
|
||||
flags[9]=1;
|
||||
flags[10]=1;
|
||||
flags[12]=1;
|
||||
|
||||
/* dump flags */
|
||||
for (i=0; i < MAX_NR_KEYMAPS; i++) write(1,&flags[i],1);
|
||||
|
||||
for (i = 0; i < MAX_NR_KEYMAPS; i++) {
|
||||
if (flags[i] == 1) {
|
||||
for (j = 0; j < NR_KEYS; j++) {
|
||||
ke.kb_index = j;
|
||||
ke.kb_table = i;
|
||||
if (ioctl(fd, KDGKBENT, &ke) < 0) {
|
||||
|
||||
error_msg("ioctl returned: %s, %s, %s, %xqq", strerror(errno),(char *)&ke.kb_index,(char *)&ke.kb_table,(int)&ke.kb_value);
|
||||
}
|
||||
else {
|
||||
write(1,(void*)&ke.kb_value,2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
152
busybox/echo.c
|
@ -1,152 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* echo implementation for busybox
|
||||
*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Original copyright notice is retained at the end of this file.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "busybox.h"
|
||||
|
||||
extern int
|
||||
echo_main(int argc, char** argv)
|
||||
{
|
||||
int nflag = 0;
|
||||
int eflag = 0;
|
||||
|
||||
/* Skip argv[0]. */
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
while (argc > 0 && *argv[0] == '-')
|
||||
{
|
||||
register char *temp;
|
||||
register int ix;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
temp = argv[0] + 1;
|
||||
|
||||
for (ix = 0; temp[ix]; ix++)
|
||||
{
|
||||
if (strrchr("neE", temp[ix]) == 0)
|
||||
goto just_echo;
|
||||
}
|
||||
|
||||
if (!*temp)
|
||||
goto just_echo;
|
||||
|
||||
/*
|
||||
* All of the options in temp are valid options to echo.
|
||||
* Handle them.
|
||||
*/
|
||||
while (*temp)
|
||||
{
|
||||
if (*temp == 'n')
|
||||
nflag = 1;
|
||||
else if (*temp == 'e')
|
||||
eflag = 1;
|
||||
else if (*temp == 'E')
|
||||
eflag = 0;
|
||||
else
|
||||
goto just_echo;
|
||||
|
||||
temp++;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
just_echo:
|
||||
while (argc > 0) {
|
||||
const char *arg = argv[0];
|
||||
register int c;
|
||||
|
||||
while ((c = *arg++)) {
|
||||
|
||||
/* Check for escape sequence. */
|
||||
if (c == '\\' && eflag && *arg) {
|
||||
if (*arg == 'c') {
|
||||
/* '\c' means cancel newline. */
|
||||
nflag = 1;
|
||||
arg++;
|
||||
continue;
|
||||
} else {
|
||||
c = process_escape_sequence(&arg);
|
||||
}
|
||||
}
|
||||
|
||||
putchar(c);
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
if (argc > 0)
|
||||
putchar(' ');
|
||||
}
|
||||
if (!nflag)
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
|
||||
return 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
|
||||
*/
|
|
@ -1,850 +0,0 @@
|
|||
/*
|
||||
* sed.c - very minimalist version of sed
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Mark Whitley <markw@lineo.com>, <markw@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
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Supported features and commands in this version of sed:
|
||||
|
||||
- comments ('#')
|
||||
- address matching: num|/matchstr/[,num|/matchstr/|$]command
|
||||
- commands: (p)rint, (d)elete, (s)ubstitue (with g & I flags)
|
||||
- edit commands: (a)ppend, (i)nsert, (c)hange
|
||||
- file commands: (r)ead
|
||||
- backreferences in substitution expressions (\1, \2...\9)
|
||||
|
||||
(Note: Specifying an address (range) to match is *optional*; commands
|
||||
default to the whole pattern space if no specific address match was
|
||||
requested.)
|
||||
|
||||
Unsupported features:
|
||||
|
||||
- transliteration (y/source-chars/dest-chars/) (use 'tr')
|
||||
- no pattern space hold space storing / swapping (x, etc.)
|
||||
- no labels / branching (: label, b, t, and friends)
|
||||
- and lots, lots more.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h> /* for getopt() */
|
||||
#include <regex.h>
|
||||
#include <string.h> /* for strdup() */
|
||||
#include <errno.h>
|
||||
#include <ctype.h> /* for isspace() */
|
||||
#include <stdlib.h>
|
||||
#include "busybox.h"
|
||||
|
||||
/* externs */
|
||||
extern void xregcomp(regex_t *preg, const char *regex, int cflags);
|
||||
extern int optind; /* in unistd.h */
|
||||
extern char *optarg; /* ditto */
|
||||
|
||||
/* options */
|
||||
static int be_quiet = 0;
|
||||
|
||||
|
||||
struct sed_cmd {
|
||||
|
||||
|
||||
/* GENERAL FIELDS */
|
||||
char delimiter; /* The delimiter used to separate regexps */
|
||||
|
||||
/* address storage */
|
||||
int beg_line; /* 'sed 1p' 0 == no begining line, apply commands to all lines */
|
||||
int end_line; /* 'sed 1,3p' 0 == no end line, use only beginning. -1 == $ */
|
||||
regex_t *beg_match; /* sed -e '/match/cmd' */
|
||||
regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */
|
||||
|
||||
/* the command */
|
||||
char cmd; /* p,d,s (add more at your leisure :-) */
|
||||
|
||||
|
||||
/* SUBSTITUTION COMMAND SPECIFIC FIELDS */
|
||||
|
||||
/* sed -e 's/sub_match/replace/' */
|
||||
regex_t *sub_match;
|
||||
char *replace;
|
||||
unsigned int num_backrefs:4; /* how many back references (\1..\9) */
|
||||
/* Note: GNU/POSIX sed does not save more than nine backrefs, so
|
||||
* we only use 4 bits to hold the number */
|
||||
unsigned int sub_g:1; /* sed -e 's/foo/bar/g' (global) */
|
||||
unsigned int sub_p:2; /* sed -e 's/foo/bar/p' (print substitution) */
|
||||
|
||||
|
||||
/* EDIT COMMAND (a,i,c) SPEICIFIC FIELDS */
|
||||
|
||||
char *editline;
|
||||
|
||||
|
||||
/* FILE COMMAND (r) SPEICIFIC FIELDS */
|
||||
|
||||
char *filename;
|
||||
};
|
||||
|
||||
/* globals */
|
||||
static struct sed_cmd *sed_cmds = NULL; /* growable arrary holding a sequence of sed cmds */
|
||||
static int ncmds = 0; /* number of sed commands */
|
||||
|
||||
/*static char *cur_file = NULL;*/ /* file currently being processed XXX: do I need this? */
|
||||
|
||||
#ifdef BB_FEATURE_CLEAN_UP
|
||||
static void destroy_cmd_strs()
|
||||
{
|
||||
if (sed_cmds == NULL)
|
||||
return;
|
||||
|
||||
/* destroy all the elements in the array */
|
||||
while (--ncmds >= 0) {
|
||||
|
||||
if (sed_cmds[ncmds].beg_match) {
|
||||
regfree(sed_cmds[ncmds].beg_match);
|
||||
free(sed_cmds[ncmds].beg_match);
|
||||
}
|
||||
if (sed_cmds[ncmds].end_match) {
|
||||
regfree(sed_cmds[ncmds].end_match);
|
||||
free(sed_cmds[ncmds].end_match);
|
||||
}
|
||||
if (sed_cmds[ncmds].sub_match) {
|
||||
regfree(sed_cmds[ncmds].sub_match);
|
||||
free(sed_cmds[ncmds].sub_match);
|
||||
}
|
||||
if (sed_cmds[ncmds].replace)
|
||||
free(sed_cmds[ncmds].replace);
|
||||
}
|
||||
|
||||
/* destroy the array */
|
||||
free(sed_cmds);
|
||||
sed_cmds = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* index_of_next_unescaped_regexp_delim - walks left to right through a string
|
||||
* beginning at a specified index and returns the index of the next regular
|
||||
* expression delimiter (typically a forward * slash ('/')) not preceeded by
|
||||
* a backslash ('\').
|
||||
*/
|
||||
static int index_of_next_unescaped_regexp_delim(struct sed_cmd *sed_cmd, const char *str, int idx)
|
||||
{
|
||||
int bracket = -1;
|
||||
int escaped = 0;
|
||||
|
||||
for ( ; str[idx]; idx++) {
|
||||
if (bracket != -1) {
|
||||
if (str[idx] == ']' && !(bracket == idx - 1 ||
|
||||
(bracket == idx - 2 && str[idx-1] == '^')))
|
||||
bracket = -1;
|
||||
} else if (escaped)
|
||||
escaped = 0;
|
||||
else if (str[idx] == '\\')
|
||||
escaped = 1;
|
||||
else if (str[idx] == '[')
|
||||
bracket = idx;
|
||||
else if (str[idx] == sed_cmd->delimiter)
|
||||
return idx;
|
||||
}
|
||||
|
||||
/* if we make it to here, we've hit the end of the string */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the index in the string just past where the address ends.
|
||||
*/
|
||||
static int get_address(struct sed_cmd *sed_cmd, const char *str, int *linenum, regex_t **regex)
|
||||
{
|
||||
char *my_str = strdup(str);
|
||||
int idx = 0;
|
||||
char olddelimiter;
|
||||
olddelimiter = sed_cmd->delimiter;
|
||||
sed_cmd->delimiter = '/';
|
||||
|
||||
if (isdigit(my_str[idx])) {
|
||||
do {
|
||||
idx++;
|
||||
} while (isdigit(my_str[idx]));
|
||||
my_str[idx] = 0;
|
||||
*linenum = atoi(my_str);
|
||||
}
|
||||
else if (my_str[idx] == '$') {
|
||||
*linenum = -1;
|
||||
idx++;
|
||||
}
|
||||
else if (my_str[idx] == '/') {
|
||||
idx = index_of_next_unescaped_regexp_delim(sed_cmd, my_str, ++idx);
|
||||
if (idx == -1)
|
||||
error_msg_and_die("unterminated match expression");
|
||||
my_str[idx] = '\0';
|
||||
*regex = (regex_t *)xmalloc(sizeof(regex_t));
|
||||
xregcomp(*regex, my_str+1, REG_NEWLINE);
|
||||
idx++; /* so it points to the next character after the last '/' */
|
||||
}
|
||||
else {
|
||||
error_msg("get_address: no address found in string\n"
|
||||
"\t(you probably didn't check the string you passed me)");
|
||||
idx = -1;
|
||||
}
|
||||
|
||||
free(my_str);
|
||||
sed_cmd->delimiter = olddelimiter;
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int parse_subst_cmd(struct sed_cmd *sed_cmd, const char *substr)
|
||||
{
|
||||
int oldidx, cflags = REG_NEWLINE;
|
||||
char *match;
|
||||
int idx = 0;
|
||||
int j;
|
||||
|
||||
/*
|
||||
* the string that gets passed to this function should look like this:
|
||||
* s/match/replace/gIp
|
||||
* || | |||
|
||||
* mandatory optional
|
||||
*
|
||||
* (all three of the '/' slashes are mandatory)
|
||||
*/
|
||||
|
||||
/* verify that the 's' is followed by something. That something
|
||||
* (typically a 'slash') is now our regexp delimiter... */
|
||||
if (!substr[++idx])
|
||||
error_msg_and_die("bad format in substitution expression");
|
||||
else
|
||||
sed_cmd->delimiter=substr[idx];
|
||||
|
||||
/* save the match string */
|
||||
oldidx = idx+1;
|
||||
idx = index_of_next_unescaped_regexp_delim(sed_cmd, substr, ++idx);
|
||||
if (idx == -1)
|
||||
error_msg_and_die("bad format in substitution expression");
|
||||
match = xstrndup(substr + oldidx, idx - oldidx);
|
||||
|
||||
/* determine the number of back references in the match string */
|
||||
/* Note: we compute this here rather than in the do_subst_command()
|
||||
* function to save processor time, at the expense of a little more memory
|
||||
* (4 bits) per sed_cmd */
|
||||
|
||||
/* sed_cmd->num_backrefs = 0; */ /* XXX: not needed? --apparently not */
|
||||
for (j = 0; match[j]; j++) {
|
||||
/* GNU/POSIX sed does not save more than nine backrefs */
|
||||
if (match[j] == '\\' && match[j+1] == '(' && sed_cmd->num_backrefs <= 9)
|
||||
sed_cmd->num_backrefs++;
|
||||
}
|
||||
|
||||
/* save the replacement string */
|
||||
oldidx = idx+1;
|
||||
idx = index_of_next_unescaped_regexp_delim(sed_cmd, substr, ++idx);
|
||||
if (idx == -1)
|
||||
error_msg_and_die("bad format in substitution expression");
|
||||
sed_cmd->replace = xstrndup(substr + oldidx, idx - oldidx);
|
||||
|
||||
/* process the flags */
|
||||
while (substr[++idx]) {
|
||||
switch (substr[idx]) {
|
||||
case 'g':
|
||||
sed_cmd->sub_g = 1;
|
||||
break;
|
||||
case 'I':
|
||||
cflags |= REG_ICASE;
|
||||
break;
|
||||
case 'p':
|
||||
sed_cmd->sub_p = 1;
|
||||
break;
|
||||
default:
|
||||
/* any whitespace or semicolon trailing after a s/// is ok */
|
||||
if (strchr("; \t\v\n\r", substr[idx]))
|
||||
goto out;
|
||||
/* else */
|
||||
error_msg_and_die("bad option in substitution expression");
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
/* compile the match string into a regex */
|
||||
sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t));
|
||||
xregcomp(sed_cmd->sub_match, match, cflags);
|
||||
free(match);
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
|
||||
{
|
||||
int idx = 0;
|
||||
int slashes_eaten = 0;
|
||||
char *ptr; /* shorthand */
|
||||
|
||||
/*
|
||||
* the string that gets passed to this function should look like this:
|
||||
*
|
||||
* need one of these
|
||||
* |
|
||||
* | this backslash (immediately following the edit command) is mandatory
|
||||
* | |
|
||||
* [aic]\
|
||||
* TEXT1\
|
||||
* TEXT2\
|
||||
* TEXTN
|
||||
*
|
||||
* as soon as we hit a TEXT line that has no trailing '\', we're done.
|
||||
* this means a command like:
|
||||
*
|
||||
* i\
|
||||
* INSERTME
|
||||
*
|
||||
* is a-ok.
|
||||
*
|
||||
*/
|
||||
|
||||
if (editstr[1] != '\\' && (editstr[2] != '\n' || editstr[2] != '\r'))
|
||||
error_msg_and_die("bad format in edit expression");
|
||||
|
||||
/* store the edit line text */
|
||||
/* make editline big enough to accomodate the extra '\n' we will tack on
|
||||
* to the end */
|
||||
sed_cmd->editline = xmalloc(strlen(&editstr[3]) + 2);
|
||||
strcpy(sed_cmd->editline, &editstr[3]);
|
||||
ptr = sed_cmd->editline;
|
||||
|
||||
/* now we need to go through * and: s/\\[\r\n]$/\n/g on the edit line */
|
||||
while (ptr[idx]) {
|
||||
while (ptr[idx] != '\\' || (ptr[idx+1] != '\n' && ptr[idx+1] != '\r')) {
|
||||
idx++;
|
||||
if (!ptr[idx]) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* move the newline over the '\' before it (effectively eats the '\') */
|
||||
memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1]));
|
||||
ptr[strlen(ptr)-1] = 0;
|
||||
slashes_eaten++;
|
||||
/* substitue \r for \n if needed */
|
||||
if (ptr[idx] == '\r')
|
||||
ptr[idx] = '\n';
|
||||
}
|
||||
|
||||
out:
|
||||
/* this accounts for discrepancies between the modified string and the
|
||||
* original string passed in to this function */
|
||||
idx += slashes_eaten;
|
||||
|
||||
/* figure out if we need to add a newline */
|
||||
if (ptr[idx-1] != '\n') {
|
||||
ptr[idx] = '\n';
|
||||
idx++;
|
||||
}
|
||||
|
||||
/* terminate string */
|
||||
ptr[idx]= 0;
|
||||
/* adjust for opening 2 chars [aic]\ */
|
||||
idx += 2;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
static int parse_file_cmd(struct sed_cmd *sed_cmd, const char *filecmdstr)
|
||||
{
|
||||
int idx = 0;
|
||||
int filenamelen = 0;
|
||||
|
||||
/*
|
||||
* the string that gets passed to this function should look like this:
|
||||
* '[ ]filename'
|
||||
* | |
|
||||
* | a filename
|
||||
* |
|
||||
* optional whitespace
|
||||
|
||||
* re: the file to be read, the GNU manual says the following: "Note that
|
||||
* if filename cannot be read, it is treated as if it were an empty file,
|
||||
* without any error indication." Thus, all of the following commands are
|
||||
* perfectly leagal:
|
||||
*
|
||||
* sed -e '1r noexist'
|
||||
* sed -e '1r ;'
|
||||
* sed -e '1r'
|
||||
*/
|
||||
|
||||
/* the file command may be followed by whitespace; move past it. */
|
||||
while (isspace(filecmdstr[++idx]))
|
||||
{ ; }
|
||||
|
||||
/* the first non-whitespace we get is a filename. the filename ends when we
|
||||
* hit a normal sed command terminator or end of string */
|
||||
filenamelen = strcspn(&filecmdstr[idx], "; \n\r\t\v\0");
|
||||
sed_cmd->filename = xmalloc(filenamelen + 1);
|
||||
safe_strncpy(sed_cmd->filename, &filecmdstr[idx], filenamelen + 1);
|
||||
|
||||
return idx + filenamelen;
|
||||
}
|
||||
|
||||
|
||||
static char *parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
|
||||
{
|
||||
int idx = 0;
|
||||
|
||||
/* parse the command
|
||||
* format is: [addr][,addr]cmd
|
||||
* |----||-----||-|
|
||||
* part1 part2 part3
|
||||
*/
|
||||
|
||||
/* first part (if present) is an address: either a number or a /regex/ */
|
||||
if (isdigit(cmdstr[idx]) || cmdstr[idx] == '/')
|
||||
idx = get_address(sed_cmd, cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match);
|
||||
|
||||
/* second part (if present) will begin with a comma */
|
||||
if (cmdstr[idx] == ',')
|
||||
idx += get_address(sed_cmd, &cmdstr[++idx], &sed_cmd->end_line, &sed_cmd->end_match);
|
||||
|
||||
/* last part (mandatory) will be a command */
|
||||
if (cmdstr[idx] == '\0')
|
||||
error_msg_and_die("missing command");
|
||||
sed_cmd->cmd = cmdstr[idx];
|
||||
|
||||
/* if it was a single-letter command that takes no arguments (such as 'p'
|
||||
* or 'd') all we need to do is increment the index past that command */
|
||||
if (strchr("pd", cmdstr[idx])) {
|
||||
idx++;
|
||||
}
|
||||
/* handle (s)ubstitution command */
|
||||
else if (sed_cmd->cmd == 's') {
|
||||
idx += parse_subst_cmd(sed_cmd, &cmdstr[idx]);
|
||||
}
|
||||
/* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */
|
||||
else if (strchr("aic", sed_cmd->cmd)) {
|
||||
if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c')
|
||||
error_msg_and_die("only a beginning address can be specified for edit commands");
|
||||
idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]);
|
||||
}
|
||||
/* handle file cmds: (r)ead */
|
||||
else if (sed_cmd->cmd == 'r') {
|
||||
if (sed_cmd->end_line || sed_cmd->end_match)
|
||||
error_msg_and_die("Command only uses one address");
|
||||
idx += parse_file_cmd(sed_cmd, &cmdstr[idx]);
|
||||
}
|
||||
else {
|
||||
error_msg_and_die("invalid command");
|
||||
}
|
||||
|
||||
/* give back whatever's left over */
|
||||
return (char *)&cmdstr[idx];
|
||||
}
|
||||
|
||||
static void add_cmd_str(const char *cmdstr)
|
||||
{
|
||||
char *mystr = (char *)cmdstr;
|
||||
|
||||
do {
|
||||
|
||||
/* trim leading whitespace and semicolons */
|
||||
memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr));
|
||||
/* if we ate the whole thing, that means there was just trailing
|
||||
* whitespace or a final / no-op semicolon. either way, get out */
|
||||
if (strlen(mystr) == 0)
|
||||
return;
|
||||
/* if this is a comment, jump past it and keep going */
|
||||
if (mystr[0] == '#') {
|
||||
mystr = strpbrk(mystr, ";\n\r");
|
||||
continue;
|
||||
}
|
||||
/* grow the array */
|
||||
sed_cmds = xrealloc(sed_cmds, sizeof(struct sed_cmd) * (++ncmds));
|
||||
/* zero new element */
|
||||
memset(&sed_cmds[ncmds-1], 0, sizeof(struct sed_cmd));
|
||||
/* load command string into new array element, get remainder */
|
||||
mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr);
|
||||
|
||||
} while (mystr && strlen(mystr));
|
||||
}
|
||||
|
||||
|
||||
static void load_cmd_file(char *filename)
|
||||
{
|
||||
FILE *cmdfile;
|
||||
char *line;
|
||||
char *nextline;
|
||||
|
||||
cmdfile = xfopen(filename, "r");
|
||||
|
||||
while ((line = get_line_from_file(cmdfile)) != NULL) {
|
||||
/* if a line ends with '\' it needs the next line appended to it */
|
||||
while (line[strlen(line)-2] == '\\' &&
|
||||
(nextline = get_line_from_file(cmdfile)) != NULL) {
|
||||
line = xrealloc(line, strlen(line) + strlen(nextline) + 1);
|
||||
strcat(line, nextline);
|
||||
free(nextline);
|
||||
}
|
||||
/* eat trailing newline (if any) --if I don't do this, edit commands
|
||||
* (aic) will print an extra newline */
|
||||
chomp(line);
|
||||
add_cmd_str(line);
|
||||
free(line);
|
||||
}
|
||||
}
|
||||
|
||||
#define PIPE_MAGIC 0x7f
|
||||
#define PIPE_GROW 64
|
||||
#define pipeputc(c) \
|
||||
{ if (pipeline[pipeline_idx] == PIPE_MAGIC) { \
|
||||
pipeline = xrealloc(pipeline, pipeline_len+PIPE_GROW); \
|
||||
memset(pipeline+pipeline_len, 0, PIPE_GROW); \
|
||||
pipeline_len += PIPE_GROW; \
|
||||
pipeline[pipeline_len-1] = PIPE_MAGIC; } \
|
||||
pipeline[pipeline_idx++] = (c); }
|
||||
|
||||
static void print_subst_w_backrefs(const char *line, const char *replace,
|
||||
regmatch_t *regmatch, char **pipeline_p, int *pipeline_idx_p,
|
||||
int *pipeline_len_p, int matches)
|
||||
{
|
||||
char *pipeline = *pipeline_p;
|
||||
int pipeline_idx = *pipeline_idx_p;
|
||||
int pipeline_len = *pipeline_len_p;
|
||||
int i;
|
||||
|
||||
/* go through the replacement string */
|
||||
for (i = 0; replace[i]; i++) {
|
||||
/* if we find a backreference (\1, \2, etc.) print the backref'ed * text */
|
||||
if (replace[i] == '\\' && isdigit(replace[i+1])) {
|
||||
int j;
|
||||
char tmpstr[2];
|
||||
int backref;
|
||||
++i; /* i now indexes the backref number, instead of the leading slash */
|
||||
tmpstr[0] = replace[i];
|
||||
tmpstr[1] = 0;
|
||||
backref = atoi(tmpstr);
|
||||
/* print out the text held in regmatch[backref] */
|
||||
if (backref <= matches && regmatch[backref].rm_so != -1)
|
||||
for (j = regmatch[backref].rm_so; j < regmatch[backref].rm_eo; j++)
|
||||
pipeputc(line[j]);
|
||||
}
|
||||
|
||||
/* if we find a backslash escaped character, print the character */
|
||||
else if (replace[i] == '\\') {
|
||||
++i;
|
||||
pipeputc(replace[i]);
|
||||
}
|
||||
|
||||
/* if we find an unescaped '&' print out the whole matched text.
|
||||
* fortunately, regmatch[0] contains the indicies to the whole matched
|
||||
* expression (kinda seems like it was designed for just such a
|
||||
* purpose...) */
|
||||
else if (replace[i] == '&' && replace[i-1] != '\\') {
|
||||
int j;
|
||||
for (j = regmatch[0].rm_so; j < regmatch[0].rm_eo; j++)
|
||||
pipeputc(line[j]);
|
||||
}
|
||||
/* nothing special, just print this char of the replacement string to stdout */
|
||||
else
|
||||
pipeputc(replace[i]);
|
||||
}
|
||||
*pipeline_p = pipeline;
|
||||
*pipeline_idx_p = pipeline_idx;
|
||||
*pipeline_len_p = pipeline_len;
|
||||
}
|
||||
|
||||
static int do_subst_command(const struct sed_cmd *sed_cmd, char **line)
|
||||
{
|
||||
char *hackline = *line;
|
||||
char *pipeline = 0;
|
||||
int pipeline_idx = 0;
|
||||
int pipeline_len = 0;
|
||||
int altered = 0;
|
||||
regmatch_t *regmatch = NULL;
|
||||
|
||||
/* we only proceed if the substitution 'search' expression matches */
|
||||
if (regexec(sed_cmd->sub_match, hackline, 0, NULL, 0) == REG_NOMATCH)
|
||||
return 0;
|
||||
|
||||
/* whaddaya know, it matched. get the number of back references */
|
||||
regmatch = xmalloc(sizeof(regmatch_t) * (sed_cmd->num_backrefs+1));
|
||||
|
||||
/* allocate more PIPE_GROW bytes
|
||||
if replaced string is larger than original */
|
||||
pipeline_len = strlen(hackline)+PIPE_GROW;
|
||||
pipeline = xmalloc(pipeline_len);
|
||||
memset(pipeline, 0, pipeline_len);
|
||||
/* buffer magic */
|
||||
pipeline[pipeline_len-1] = PIPE_MAGIC;
|
||||
|
||||
/* and now, as long as we've got a line to try matching and if we can match
|
||||
* the search string, we make substitutions */
|
||||
while ((*hackline || !altered) && (regexec(sed_cmd->sub_match, hackline,
|
||||
sed_cmd->num_backrefs+1, regmatch, 0) != REG_NOMATCH) ) {
|
||||
int i;
|
||||
|
||||
/* print everything before the match */
|
||||
for (i = 0; i < regmatch[0].rm_so; i++)
|
||||
pipeputc(hackline[i]);
|
||||
|
||||
/* then print the substitution string */
|
||||
print_subst_w_backrefs(hackline, sed_cmd->replace, regmatch,
|
||||
&pipeline, &pipeline_idx, &pipeline_len,
|
||||
sed_cmd->num_backrefs);
|
||||
|
||||
/* advance past the match */
|
||||
hackline += regmatch[0].rm_eo;
|
||||
/* flag that something has changed */
|
||||
altered++;
|
||||
|
||||
/* if we're not doing this globally, get out now */
|
||||
if (!sed_cmd->sub_g)
|
||||
break;
|
||||
}
|
||||
|
||||
for (; *hackline; hackline++) pipeputc(*hackline);
|
||||
if (pipeline[pipeline_idx] == PIPE_MAGIC) pipeline[pipeline_idx] = 0;
|
||||
|
||||
/* cleanup */
|
||||
free(regmatch);
|
||||
|
||||
free(*line);
|
||||
*line = pipeline;
|
||||
return altered;
|
||||
}
|
||||
|
||||
|
||||
static void process_file(FILE *file)
|
||||
{
|
||||
char *line = NULL;
|
||||
static int linenum = 0; /* GNU sed does not restart counting lines at EOF */
|
||||
unsigned int still_in_range = 0;
|
||||
int altered;
|
||||
int i;
|
||||
|
||||
/* go through every line in the file */
|
||||
while ((line = get_line_from_file(file)) != NULL) {
|
||||
|
||||
chomp(line);
|
||||
linenum++;
|
||||
altered = 0;
|
||||
|
||||
/* for every line, go through all the commands */
|
||||
for (i = 0; i < ncmds; i++) {
|
||||
|
||||
|
||||
/*
|
||||
* entry point into sedding...
|
||||
*/
|
||||
if (
|
||||
/* no range necessary */
|
||||
(sed_cmds[i].beg_line == 0 && sed_cmds[i].end_line == 0 &&
|
||||
sed_cmds[i].beg_match == NULL &&
|
||||
sed_cmds[i].end_match == NULL) ||
|
||||
/* this line number is the first address we're looking for */
|
||||
(sed_cmds[i].beg_line && (sed_cmds[i].beg_line == linenum)) ||
|
||||
/* this line matches our first address regex */
|
||||
(sed_cmds[i].beg_match && (regexec(sed_cmds[i].beg_match, line, 0, NULL, 0) == 0)) ||
|
||||
/* we are currently within the beginning & ending address range */
|
||||
still_in_range
|
||||
) {
|
||||
|
||||
/*
|
||||
* actual sedding
|
||||
*/
|
||||
switch (sed_cmds[i].cmd) {
|
||||
|
||||
case 'p':
|
||||
puts(line);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
altered++;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
|
||||
/*
|
||||
* Some special cases for 's' printing to make it compliant with
|
||||
* GNU sed printing behavior (aka "The -n | s///p Matrix"):
|
||||
*
|
||||
* -n ONLY = never print anything regardless of any successful
|
||||
* substitution
|
||||
*
|
||||
* s///p ONLY = always print successful substitutions, even if
|
||||
* the line is going to be printed anyway (line will be printed
|
||||
* twice).
|
||||
*
|
||||
* -n AND s///p = print ONLY a successful substitution ONE TIME;
|
||||
* no other lines are printed - this is the reason why the 'p'
|
||||
* flag exists in the first place.
|
||||
*/
|
||||
|
||||
/* if the user specified that they didn't want anything printed (i.e., a -n
|
||||
* flag and no 'p' flag after the s///), then there's really no point doing
|
||||
* anything here. */
|
||||
if (be_quiet && !sed_cmds[i].sub_p)
|
||||
break;
|
||||
|
||||
/* we print the line once, unless we were told to be quiet */
|
||||
if (!be_quiet)
|
||||
altered |= do_subst_command(&sed_cmds[i], &line);
|
||||
|
||||
/* we also print the line if we were given the 'p' flag
|
||||
* (this is quite possibly the second printing) */
|
||||
if (sed_cmds[i].sub_p)
|
||||
altered |= do_subst_command(&sed_cmds[i], &line);
|
||||
if (altered && (i+1 >= ncmds || sed_cmds[i+1].cmd != 's'))
|
||||
puts(line);
|
||||
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
puts(line);
|
||||
fputs(sed_cmds[i].editline, stdout);
|
||||
altered++;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
fputs(sed_cmds[i].editline, stdout);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
/* single-address case */
|
||||
if (sed_cmds[i].end_match == NULL && sed_cmds[i].end_line == 0) {
|
||||
fputs(sed_cmds[i].editline, stdout);
|
||||
}
|
||||
/* multi-address case */
|
||||
else {
|
||||
/* matching text */
|
||||
if (sed_cmds[i].end_match && (regexec(sed_cmds[i].end_match, line, 0, NULL, 0) == 0))
|
||||
fputs(sed_cmds[i].editline, stdout);
|
||||
/* matching line numbers */
|
||||
if (sed_cmds[i].end_line > 0 && sed_cmds[i].end_line == linenum)
|
||||
fputs(sed_cmds[i].editline, stdout);
|
||||
}
|
||||
altered++;
|
||||
|
||||
break;
|
||||
|
||||
case 'r': {
|
||||
FILE *outfile;
|
||||
puts(line);
|
||||
outfile = fopen(sed_cmds[i].filename, "r");
|
||||
if (outfile)
|
||||
print_file(outfile);
|
||||
/* else if we couldn't open the output file,
|
||||
* no biggie, just don't print anything */
|
||||
altered++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* exit point from sedding...
|
||||
*/
|
||||
if (
|
||||
/* this is a single-address command or... */
|
||||
(sed_cmds[i].end_line == 0 && sed_cmds[i].end_match == NULL) || (
|
||||
/* we were in the middle of our address range (this
|
||||
* isn't the first time through) and.. */
|
||||
(still_in_range == 1) && (
|
||||
/* this line number is the last address we're looking for or... */
|
||||
(sed_cmds[i].end_line && (sed_cmds[i].end_line == linenum)) ||
|
||||
/* this line matches our last address regex */
|
||||
(sed_cmds[i].end_match && (regexec(sed_cmds[i].end_match, line, 0, NULL, 0) == 0))
|
||||
)
|
||||
)
|
||||
) {
|
||||
/* we're out of our address range */
|
||||
still_in_range = 0;
|
||||
}
|
||||
|
||||
/* didn't hit the exit? then we're still in the middle of an address range */
|
||||
else {
|
||||
still_in_range = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we will print the line unless we were told to be quiet or if the
|
||||
* line was altered (via a 'd'elete or 's'ubstitution), in which case
|
||||
* the altered line was already printed */
|
||||
if (!be_quiet && !altered)
|
||||
puts(line);
|
||||
|
||||
free(line);
|
||||
}
|
||||
}
|
||||
|
||||
extern int sed_main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
|
||||
#ifdef BB_FEATURE_CLEAN_UP
|
||||
/* destroy command strings on exit */
|
||||
if (atexit(destroy_cmd_strs) == -1)
|
||||
perror_msg_and_die("atexit");
|
||||
#endif
|
||||
|
||||
/* do normal option parsing */
|
||||
while ((opt = getopt(argc, argv, "ne:f:")) > 0) {
|
||||
switch (opt) {
|
||||
case 'n':
|
||||
be_quiet++;
|
||||
break;
|
||||
case 'e':
|
||||
add_cmd_str(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
load_cmd_file(optarg);
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
/* if we didn't get a pattern from a -e and no command file was specified,
|
||||
* argv[optind] should be the pattern. no pattern, no worky */
|
||||
if (ncmds == 0) {
|
||||
if (argv[optind] == NULL)
|
||||
show_usage();
|
||||
else {
|
||||
add_cmd_str(argv[optind]);
|
||||
optind++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* argv[(optind)..(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[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
|
||||
process_file(stdin);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
FILE *file;
|
||||
for (i = optind; i < argc; i++) {
|
||||
file = fopen(argv[i], "r");
|
||||
if (file == NULL) {
|
||||
perror_msg("%s", argv[i]);
|
||||
} else {
|
||||
process_file(file);
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,185 +0,0 @@
|
|||
Building a Busybox Boot Floppy
|
||||
==============================
|
||||
|
||||
This document describes how to buid a boot floppy using the following
|
||||
components:
|
||||
|
||||
- Linux Kernel (http://www.kernel.org)
|
||||
- uClibc: C library (http://cvs.uclinux.org/uClibc.html)
|
||||
- Busybox: Unix utilities (http://busybox.lineo.com)
|
||||
- Syslinux: bootloader (http://syslinux.zytor.com)
|
||||
|
||||
It is based heavily on a paper presented by Erik Andersen at the 2001 Embedded
|
||||
Systems Conference.
|
||||
|
||||
|
||||
|
||||
Building The Software Components
|
||||
--------------------------------
|
||||
|
||||
Detailed instructions on how to build Busybox, uClibc, or a working Linux
|
||||
kernel are beyond the scope of this document. The following guidelines will
|
||||
help though:
|
||||
|
||||
- Stock Busybox from CVS or a tarball will work with no modifications to
|
||||
any files. Just extract and go.
|
||||
- Ditto uClibc.
|
||||
- Your Linux kernel must include support for initrd or else the floppy
|
||||
won't be able to mount it's root file system.
|
||||
|
||||
If you require further information on building Busybox uClibc or Linux, please
|
||||
refer to the web pages and documentation for those individual programs.
|
||||
|
||||
|
||||
|
||||
Making a Root File System
|
||||
-------------------------
|
||||
|
||||
The following steps will create a root file system.
|
||||
|
||||
- Create an empty file that you can format as a filesystem:
|
||||
|
||||
dd if=/dev/zero of=rootfs bs=1k count=4000
|
||||
|
||||
- Set up the rootfs file we just created to be used as a loop device (may not
|
||||
be necessary)
|
||||
|
||||
losetup /dev/loop0 rootfs
|
||||
|
||||
- Format the rootfs file with a filesystem:
|
||||
|
||||
mkfs.ext2 -F -i 2000 rootfs
|
||||
|
||||
- Mount the file on a mountpoint so we can place files in it:
|
||||
|
||||
mkdir loop
|
||||
mount -o loop rootfs loop/
|
||||
|
||||
(you will probably need to be root to do this)
|
||||
|
||||
- Copy on the C library, the dynamic linking library, and other necessary
|
||||
libraries. For this example, we copy the following files from the uClibc
|
||||
tree:
|
||||
|
||||
mkdir loop/lib
|
||||
(chdir to uClibc directory)
|
||||
cp -a libc.so* uClibc*.so \
|
||||
ld.so-1/d-link/ld-linux-uclibc.so* \
|
||||
ld.so-1/libdl/libdl.so* \
|
||||
crypt/libcrypt.so* \
|
||||
(path to)loop/lib
|
||||
|
||||
- Install the Busybox binary and accompanying symlinks:
|
||||
|
||||
(chdir to busybox directory)
|
||||
make PREFIX=(path to)loop/ install
|
||||
|
||||
- Make device files in /dev:
|
||||
|
||||
This can be done by running the 'mkdevs.sh' script. If you want the gory
|
||||
details, you can read the script.
|
||||
|
||||
- Make necessary files in /etc:
|
||||
|
||||
For this, just cp -a the etc/ directory onto rootfs. Again, if you want
|
||||
all the details, you can just look at the files in the dir.
|
||||
|
||||
- Run ldconfig so busybox and other binaries can have access to the libraries
|
||||
that they need:
|
||||
|
||||
(path to)uClibc/ld.so-1/util/ldconfig -r loop/
|
||||
|
||||
- Unmount the rootfs from the mountpoint:
|
||||
|
||||
umount loop
|
||||
|
||||
- Compress it:
|
||||
|
||||
gzip -9 rootfs
|
||||
|
||||
|
||||
Making a SYSLINUX boot floppy
|
||||
-----------------------------
|
||||
|
||||
The following steps will create the boot floppy.
|
||||
|
||||
Note: You will need to have the mtools package installed beforehand.
|
||||
|
||||
- Insert a floppy in the drive and format it with an MSDOS filesystem:
|
||||
|
||||
mformat a:
|
||||
|
||||
(if the system doesn't know what device 'a:' is, look at /etc/mtools.conf)
|
||||
|
||||
- Run syslinux on the floppy:
|
||||
|
||||
syslinux -s /dev/fd0
|
||||
|
||||
(the -s stands for "safe, slow, and stupid" and should work better with
|
||||
buggy BIOSes; it can be omitted)
|
||||
|
||||
- Put on a syslinux.cfg file:
|
||||
|
||||
mcopy syslinux.cfg a:
|
||||
|
||||
(more on syslinux.cfg below)
|
||||
|
||||
- Copy the root file system you made onto the MSDOS formatted floppy
|
||||
|
||||
mcopy rootfs.gz a:
|
||||
|
||||
- Build a linux kernel and copy it onto the disk with the filename 'linux'
|
||||
|
||||
mcopy bzImage a:linux
|
||||
|
||||
|
||||
Sample syslinux.cfg
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The following simple syslinux.cfg file should work. You can tweak it if you
|
||||
like.
|
||||
|
||||
----begin-syslinux.cfg---------------
|
||||
DEFAULT linux
|
||||
APPEND initrd=rootfs.gz root=/dev/ram0
|
||||
TIMEOUT 10
|
||||
PROMPT 1
|
||||
----end-syslinux.cfg---------------
|
||||
|
||||
Some changes you could make to syslinux.cfg:
|
||||
|
||||
- This value is the number seconds it will wait before booting. You can set
|
||||
the timeout to 0 (or omit) to boot instantly, or you can set it as high as
|
||||
10 to wait awhile.
|
||||
|
||||
- PROMPT can be set to 0 to disable the 'boot:' prompt.
|
||||
|
||||
- you can add this line to display the contents of a file as a welcome
|
||||
message:
|
||||
|
||||
DISPLAY display.txt
|
||||
|
||||
|
||||
|
||||
Additional Resources
|
||||
--------------------
|
||||
|
||||
Other useful information on making a Linux bootfloppy is available at the
|
||||
following URLs:
|
||||
|
||||
http://www.linuxdoc.org/HOWTO/Bootdisk-HOWTO/index.html
|
||||
http://www.linux-embedded.com/howto/Embedded-Linux-Howto.html
|
||||
http://linux-embedded.org/howto/LFS-HOWTO.html
|
||||
http://linux-embedded.org/pmhowto.html
|
||||
http://recycle.lbl.gov/~ldoolitt/embedded/ (Larry Doolittle's stuff)
|
||||
|
||||
|
||||
|
||||
Possible TODOs
|
||||
--------------
|
||||
|
||||
The following features that we might want to add later:
|
||||
|
||||
- support for additional filesystems besides ext2, i.e. minix
|
||||
- different libc, static vs dynamic loading
|
||||
- maybe using an alternate bootloader
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
This boot floppy is made with Busybox, uClibc, and the Linux kernel.
|
||||
Hit RETURN to boot or enter boot parameters at the prompt below.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
proc /proc proc defaults 0 0
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#! /bin/sh
|
||||
|
||||
/bin/mount -a
|
|
@ -1,5 +0,0 @@
|
|||
::sysinit:/etc/init.d/rcS
|
||||
::respawn:-/bin/sh
|
||||
tty2::askfirst:-/bin/sh
|
||||
::ctrlaltdel:/bin/umount -a -r
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
# /etc/profile: system-wide .profile file for the Bourne shells
|
||||
|
||||
echo
|
||||
echo -n "Processing /etc/profile... "
|
||||
# no-op
|
||||
echo "Done"
|
||||
echo
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# makedev.sh - creates device files for a busybox boot floppy image
|
||||
|
||||
|
||||
# we do our work in the dev/ directory
|
||||
if [ -z "$1" ]; then
|
||||
echo "usage: `basename $0` path/to/dev/dir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $1
|
||||
|
||||
|
||||
# miscellaneous one-of-a-kind stuff
|
||||
mknod console c 5 1
|
||||
mknod full c 1 7
|
||||
mknod kmem c 1 2
|
||||
mknod mem c 1 1
|
||||
mknod null c 1 3
|
||||
mknod port c 1 4
|
||||
mknod random c 1 8
|
||||
mknod urandom c 1 9
|
||||
mknod zero c 1 5
|
||||
ln -s /proc/kcore core
|
||||
|
||||
# IDE HD devs
|
||||
# note: not going to bother creating all concievable partitions; you can do
|
||||
# that yourself as you need 'em.
|
||||
mknod hda b 3 0
|
||||
mknod hdb b 3 64
|
||||
mknod hdc b 22 0
|
||||
mknod hdd b 22 64
|
||||
|
||||
# loop devs
|
||||
for i in `seq 0 7`; do
|
||||
mknod loop$i b 7 $i
|
||||
done
|
||||
|
||||
# ram devs
|
||||
for i in `seq 0 9`; do
|
||||
mknod ram$i b 1 $i
|
||||
done
|
||||
ln -s ram1 ram
|
||||
|
||||
# ttys
|
||||
mknod tty c 5 0
|
||||
for i in `seq 0 9`; do
|
||||
mknod tty$i c 4 $i
|
||||
done
|
||||
|
||||
# virtual console screen devs
|
||||
for i in `seq 0 9`; do
|
||||
mknod vcs$i b 7 $i
|
||||
done
|
||||
ln -s vcs0 vcs
|
||||
|
||||
# virtual console screen w/ attributes devs
|
||||
for i in `seq 0 9`; do
|
||||
mknod vcsa$i b 7 $i
|
||||
done
|
||||
ln -s vcsa0 vcsa
|
|
@ -1,106 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# mkrootfs.sh - creates a root file system
|
||||
#
|
||||
|
||||
# TODO: need to add checks here to verify that busybox, uClibc and bzImage
|
||||
# exist
|
||||
|
||||
|
||||
# command-line settable variables
|
||||
BUSYBOX_DIR=..
|
||||
UCLIBC_DIR=../../uClibc
|
||||
TARGET_DIR=./loop
|
||||
FSSIZE=4000
|
||||
CLEANUP=1
|
||||
MKFS='mkfs.ext2 -F'
|
||||
|
||||
# don't-touch variables
|
||||
BASE_DIR=`pwd`
|
||||
|
||||
|
||||
while getopts 'b:u:s:t:Cm' opt
|
||||
do
|
||||
case $opt in
|
||||
b) BUSYBOX_DIR=$OPTARG ;;
|
||||
u) UCLIBC_DIR=$OPTARG ;;
|
||||
t) TARGET_DIR=$OPTARG ;;
|
||||
s) FSSIZE=$OPTARG ;;
|
||||
C) CLEANUP=0 ;;
|
||||
m) MKFS='mkfs.minix' ;;
|
||||
*)
|
||||
echo "usage: `basename $0` [-bu]"
|
||||
echo " -b DIR path to busybox direcory (default ..)"
|
||||
echo " -u DIR path to uClibc direcory (default ../../uClibc)"
|
||||
echo " -t DIR path to target direcory (default ./loop)"
|
||||
echo " -s SIZE size of root filesystem in Kbytes (default 4000)"
|
||||
echo " -C don't perform cleanup (umount target dir, gzip rootfs, etc.)"
|
||||
echo " (this allows you to 'chroot loop/ /bin/sh' to test it)"
|
||||
echo " -m use minix filesystem (default is ext2)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
|
||||
|
||||
# clean up from any previous work
|
||||
mount | grep -q loop
|
||||
[ $? -eq 0 ] && umount $TARGET_DIR
|
||||
[ -d $TARGET_DIR ] && rm -rf $TARGET_DIR/
|
||||
[ -f rootfs ] && rm -f rootfs
|
||||
[ -f rootfs.gz ] && rm -f rootfs.gz
|
||||
|
||||
|
||||
# prepare root file system and mount as loopback
|
||||
dd if=/dev/zero of=rootfs bs=1k count=$FSSIZE
|
||||
$MKFS -i 2000 rootfs
|
||||
mkdir $TARGET_DIR
|
||||
mount -o loop,exec rootfs $TARGET_DIR # must be root
|
||||
|
||||
|
||||
# install uClibc
|
||||
mkdir -p $TARGET_DIR/lib
|
||||
cd $UCLIBC_DIR
|
||||
make INSTALL_DIR=
|
||||
cp -a libc.so* $BASE_DIR/$TARGET_DIR/lib
|
||||
cp -a uClibc*.so $BASE_DIR/$TARGET_DIR/lib
|
||||
cp -a ld.so-1/d-link/ld-linux-uclibc.so* $BASE_DIR/$TARGET_DIR/lib
|
||||
cp -a ld.so-1/libdl/libdl.so* $BASE_DIR/$TARGET_DIR/lib
|
||||
cp -a crypt/libcrypt.so* $BASE_DIR/$TARGET_DIR/lib
|
||||
cd $BASE_DIR
|
||||
|
||||
|
||||
# install busybox and components
|
||||
cd $BUSYBOX_DIR
|
||||
make distclean
|
||||
make CC=$BASE_DIR/$UCLIBC_DIR/extra/gcc-uClibc/i386-uclibc-gcc
|
||||
make PREFIX=$BASE_DIR/$TARGET_DIR install
|
||||
cd $BASE_DIR
|
||||
|
||||
|
||||
# make files in /dev
|
||||
mkdir $TARGET_DIR/dev
|
||||
./mkdevs.sh $TARGET_DIR/dev
|
||||
|
||||
|
||||
# make files in /etc
|
||||
cp -a etc $TARGET_DIR
|
||||
ln -s /proc/mounts $TARGET_DIR/etc/mtab
|
||||
|
||||
|
||||
# other miscellaneous setup
|
||||
mkdir $TARGET_DIR/initrd
|
||||
mkdir $TARGET_DIR/proc
|
||||
$UCLIBC_DIR/ld.so-1/util/ldconfig -r $TARGET_DIR
|
||||
|
||||
|
||||
# Done. Maybe do cleanup.
|
||||
if [ $CLEANUP -eq 1 ]
|
||||
then
|
||||
umount $TARGET_DIR
|
||||
rmdir $TARGET_DIR
|
||||
gzip -9 rootfs
|
||||
fi
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Formats a floppy to use Syslinux
|
||||
|
||||
dummy=""
|
||||
|
||||
|
||||
# need to have mtools installed
|
||||
if [ -z `which mformat` -o -z `which mcopy` ]; then
|
||||
echo "You must have the mtools package installed to run this script"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# need an arg for the location of the kernel
|
||||
if [ -z "$1" ]; then
|
||||
echo "usage: `basename $0` path/to/linux/kernel"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# need to have a root file system built
|
||||
if [ ! -f rootfs.gz ]; then
|
||||
echo "You need to have a rootfs built first."
|
||||
echo "Hit RETURN to make one now or Control-C to quit."
|
||||
read dummy
|
||||
./mkrootfs.sh
|
||||
fi
|
||||
|
||||
|
||||
# prepare the floppy
|
||||
echo "Please insert a blank floppy in the drive and press RETURN to format"
|
||||
echo "(WARNING: All data will be erased! Hit Control-C to abort)"
|
||||
read dummy
|
||||
|
||||
echo "Formatting the floppy..."
|
||||
mformat a:
|
||||
echo "Making it bootable with Syslinux..."
|
||||
syslinux -s /dev/fd0
|
||||
echo "Copying Syslinux configuration files..."
|
||||
mcopy syslinux.cfg display.txt a:
|
||||
echo "Copying root filesystem file..."
|
||||
mcopy rootfs.gz a:
|
||||
# XXX: maybe check for "no space on device" errors here
|
||||
echo "Copying linux kernel..."
|
||||
mcopy $1 a:linux
|
||||
# XXX: maybe check for "no space on device" errors here too
|
||||
echo "Finished: boot floppy created"
|
|
@ -1,15 +0,0 @@
|
|||
Quickstart on making the Busybox boot-floppy:
|
||||
|
||||
1) Download Busybox and uClibc from CVS or tarballs. Make sure they share a
|
||||
common parent directory. (i.e. busybox/ and uclibc/ are both right off of
|
||||
/tmp, or wherever.)
|
||||
|
||||
2) Build a Linux kernel. Make sure you include support for initrd.
|
||||
|
||||
3) Put a floppy in the drive. Make sure it is a floppy you don't care about
|
||||
because the contents will be overwritten.
|
||||
|
||||
4) As root, type ./mksyslinux.sh path/to/linux/kernel from this directory.
|
||||
Wait patiently while the magic happens.
|
||||
|
||||
5) Boot up on the floppy.
|
|
@ -1,7 +0,0 @@
|
|||
display display.txt
|
||||
default linux
|
||||
timeout 10
|
||||
prompt 1
|
||||
label linux
|
||||
kernel linux
|
||||
append initrd=rootfs.gz root=/dev/ram0
|
|
@ -1,86 +0,0 @@
|
|||
# /etc/inittab init(8) configuration for BusyBox
|
||||
#
|
||||
# Copyright (C) 1999 by Lineo, inc. Written by Erik Andersen
|
||||
# <andersen@lineo.com>, <andersee@debian.org>
|
||||
#
|
||||
#
|
||||
# Note, BusyBox init doesn't support runlevels. The runlevels field is
|
||||
# completely ignored by BusyBox init. If you want runlevels, use sysvinit.
|
||||
#
|
||||
#
|
||||
# Format for each entry: <id>:<runlevels>:<action>:<process>
|
||||
#
|
||||
# <id>: WARNING: This field has a non-traditional meaning for BusyBox init!
|
||||
#
|
||||
# The id field is used by BusyBox init to specify the controlling tty for
|
||||
# the specified process to run on. The contents of this field are
|
||||
# appended to "/dev/" and used as-is. There is no need for this field to
|
||||
# be unique, although if it isn't you may have strange results. If this
|
||||
# field is left blank, it is completely ignored. Also note that if
|
||||
# BusyBox detects that a serial console is in use, then all entries
|
||||
# containing non-empty id fields will _not_ be run. BusyBox init does
|
||||
# nothing with utmp. We don't need no stinkin' utmp.
|
||||
#
|
||||
# <runlevels>: The runlevels field is completely ignored.
|
||||
#
|
||||
# <action>: Valid actions include: sysinit, respawn, askfirst, wait, once,
|
||||
# ctrlaltdel, and shutdown.
|
||||
#
|
||||
# Note: askfirst acts just like respawn, but before running the specified
|
||||
# process it displays the line "Please press Enter to activate this
|
||||
# console." and then waits for the user to press enter before starting
|
||||
# the specified process.
|
||||
#
|
||||
# Note: unrecognised actions (like initdefault) will cause init to emit
|
||||
# an error message, and then go along with its business.
|
||||
#
|
||||
# <process>: Specifies the process to be executed and it's command line.
|
||||
#
|
||||
# Note: BusyBox init works just fine without an inittab. If no inittab is
|
||||
# found, it has the following default behavior:
|
||||
# ::sysinit:/etc/init.d/rcS
|
||||
# ::askfirst:/bin/sh
|
||||
# ::ctrlaltdel:/sbin/reboot
|
||||
# ::shutdown:/sbin/swapoff -a
|
||||
# ::shutdown:/bin/umount -a -r
|
||||
# if it detects that /dev/console is _not_ a serial console, it will
|
||||
# also run:
|
||||
# tty2::askfirst:/bin/sh
|
||||
# tty3::askfirst:/bin/sh
|
||||
# tty4::askfirst:/bin/sh
|
||||
#
|
||||
# Boot-time system configuration/initialization script.
|
||||
# This is run first except when booting in single-user mode.
|
||||
#
|
||||
::sysinit:/etc/init.d/rcS
|
||||
|
||||
# /bin/sh invocations on selected ttys
|
||||
#
|
||||
# Note below that we prefix the shell commands with a "-" to indicate to the
|
||||
# shell that it is supposed to be a login shell. Normally this is handled by
|
||||
# login, but since we are bypassing login in this case, BusyBox lets you do
|
||||
# this yourself...
|
||||
#
|
||||
# Start an "askfirst" shell on the console (whatever that may be)
|
||||
::askfirst:-/bin/sh
|
||||
# Start an "askfirst" shell on /dev/tty2-4
|
||||
tty2::askfirst:-/bin/sh
|
||||
tty3::askfirst:-/bin/sh
|
||||
tty4::askfirst:-/bin/sh
|
||||
|
||||
# /sbin/getty invocations for selected ttys
|
||||
tty4::respawn:/sbin/getty 38400 tty5
|
||||
tty5::respawn:/sbin/getty 38400 tty6
|
||||
|
||||
# Example of how to put a getty on a serial line (for a terminal)
|
||||
#::respawn:/sbin/getty -L ttyS0 9600 vt100
|
||||
#::respawn:/sbin/getty -L ttyS1 9600 vt100
|
||||
#
|
||||
# Example how to put a getty on a modem line.
|
||||
#::respawn:/sbin/getty 57600 ttyS2
|
||||
|
||||
# Stuff to do before rebooting
|
||||
::ctrlaltdel:/sbin/reboot
|
||||
::shutdown:/bin/umount -a -r
|
||||
::shutdown:/sbin/swapoff -a
|
||||
|
535
busybox/expr.c
|
@ -1,535 +0,0 @@
|
|||
/* 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>.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/* This program evaluates expressions. Each token (operator, operand,
|
||||
* parenthesis) of the expression must be a seperate 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <regex.h>
|
||||
#include <sys/types.h>
|
||||
#include "busybox.h"
|
||||
|
||||
|
||||
/* The kinds of value we can have. */
|
||||
enum valtype {
|
||||
integer,
|
||||
string
|
||||
};
|
||||
typedef enum valtype TYPE;
|
||||
|
||||
/* A value is.... */
|
||||
struct valinfo {
|
||||
TYPE type; /* Which kind. */
|
||||
union { /* The value itself. */
|
||||
int 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 (int i);
|
||||
static VALUE *str_value (char *s);
|
||||
static int nextarg (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)
|
||||
{
|
||||
VALUE *v;
|
||||
|
||||
if (argc == 1) {
|
||||
error_msg_and_die("too few arguments");
|
||||
}
|
||||
|
||||
args = argv + 1;
|
||||
|
||||
v = eval ();
|
||||
if (*args)
|
||||
error_msg_and_die ("syntax error");
|
||||
|
||||
if (v->type == integer)
|
||||
printf ("%d\n", v->u.i);
|
||||
else
|
||||
puts (v->u.s);
|
||||
|
||||
exit (null (v));
|
||||
}
|
||||
|
||||
/* Return a VALUE for I. */
|
||||
|
||||
static VALUE *int_value (int 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 (char *s)
|
||||
{
|
||||
VALUE *v;
|
||||
|
||||
v = xmalloc (sizeof(VALUE));
|
||||
v->type = string;
|
||||
v->u.s = strdup (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)
|
||||
{
|
||||
switch (v->type) {
|
||||
case integer:
|
||||
return v->u.i == 0;
|
||||
case string:
|
||||
return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Coerce V to a string value (can't fail). */
|
||||
|
||||
static void tostring (VALUE *v)
|
||||
{
|
||||
char *temp;
|
||||
|
||||
if (v->type == integer) {
|
||||
temp = xmalloc (4 * (sizeof (int) / sizeof (char)));
|
||||
sprintf (temp, "%d", v->u.i);
|
||||
v->u.s = temp;
|
||||
v->type = string;
|
||||
}
|
||||
}
|
||||
|
||||
/* Coerce V to an integer value. Return 1 on success, 0 on failure. */
|
||||
|
||||
static int toarith (VALUE *v)
|
||||
{
|
||||
int i;
|
||||
|
||||
switch (v->type) {
|
||||
case integer:
|
||||
return 1;
|
||||
case string:
|
||||
i = 0;
|
||||
/* Don't interpret the empty string as an integer. */
|
||||
if (v->u.s == 0)
|
||||
return 0;
|
||||
i = atoi(v->u.s);
|
||||
free (v->u.s);
|
||||
v->u.i = i;
|
||||
v->type = integer;
|
||||
return 1;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Return nonzero if the next token matches STR exactly.
|
||||
STR must not be NULL. */
|
||||
|
||||
static int
|
||||
nextarg (char *str)
|
||||
{
|
||||
if (*args == NULL)
|
||||
return 0;
|
||||
return strcmp (*args, str) == 0;
|
||||
}
|
||||
|
||||
/* The comparison operator handling functions. */
|
||||
|
||||
#define cmpf(name, rel) \
|
||||
static int name (l, r) VALUE *l; VALUE *r; \
|
||||
{ \
|
||||
if (l->type == string || r->type == string) { \
|
||||
tostring (l); \
|
||||
tostring (r); \
|
||||
return strcmp (l->u.s, r->u.s) rel 0; \
|
||||
} \
|
||||
else \
|
||||
return l->u.i rel r->u.i; \
|
||||
}
|
||||
cmpf (less_than, <)
|
||||
cmpf (less_equal, <=)
|
||||
cmpf (equal, ==)
|
||||
cmpf (not_equal, !=)
|
||||
cmpf (greater_equal, >=)
|
||||
cmpf (greater_than, >)
|
||||
|
||||
#undef cmpf
|
||||
|
||||
/* The arithmetic operator handling functions. */
|
||||
|
||||
#define arithf(name, op) \
|
||||
static \
|
||||
int name (l, r) VALUE *l; VALUE *r; \
|
||||
{ \
|
||||
if (!toarith (l) || !toarith (r)) \
|
||||
error_msg_and_die ("non-numeric argument"); \
|
||||
return l->u.i op r->u.i; \
|
||||
}
|
||||
|
||||
#define arithdivf(name, op) \
|
||||
static int name (l, r) VALUE *l; VALUE *r; \
|
||||
{ \
|
||||
if (!toarith (l) || !toarith (r)) \
|
||||
error_msg_and_die ( "non-numeric argument"); \
|
||||
if (r->u.i == 0) \
|
||||
error_msg_and_die ( "division by zero"); \
|
||||
return l->u.i op r->u.i; \
|
||||
}
|
||||
|
||||
arithf (plus, +)
|
||||
arithf (minus, -)
|
||||
arithf (multiply, *)
|
||||
arithdivf (divide, /)
|
||||
arithdivf (mod, %)
|
||||
|
||||
#undef arithf
|
||||
#undef arithdivf
|
||||
|
||||
/* 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;
|
||||
const char *errmsg;
|
||||
struct re_pattern_buffer re_buffer;
|
||||
struct re_registers re_regs;
|
||||
int len;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
len = strlen (pv->u.s);
|
||||
memset (&re_buffer, 0, sizeof (re_buffer));
|
||||
memset (&re_regs, 0, sizeof (re_regs));
|
||||
re_buffer.allocated = 2 * len;
|
||||
re_buffer.buffer = (unsigned char *) xmalloc (re_buffer.allocated);
|
||||
re_buffer.translate = 0;
|
||||
re_syntax_options = RE_SYNTAX_POSIX_BASIC;
|
||||
errmsg = re_compile_pattern (pv->u.s, len, &re_buffer);
|
||||
if (errmsg) {
|
||||
error_msg_and_die("%s", errmsg);
|
||||
}
|
||||
|
||||
len = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs);
|
||||
if (len >= 0) {
|
||||
/* Were \(...\) used? */
|
||||
if (re_buffer.re_nsub > 0) { /* was (re_regs.start[1] >= 0) */
|
||||
sv->u.s[re_regs.end[1]] = '\0';
|
||||
v = str_value (sv->u.s + re_regs.start[1]);
|
||||
}
|
||||
else
|
||||
v = int_value (len);
|
||||
}
|
||||
else {
|
||||
/* Match failed -- return the right kind of null. */
|
||||
if (re_buffer.re_nsub > 0)
|
||||
v = str_value ("");
|
||||
else
|
||||
v = int_value (0);
|
||||
}
|
||||
free (re_buffer.buffer);
|
||||
return v;
|
||||
}
|
||||
|
||||
/* Handle bare operands and ( expr ) syntax. */
|
||||
|
||||
static VALUE *eval7 (void)
|
||||
{
|
||||
VALUE *v;
|
||||
|
||||
if (!*args)
|
||||
error_msg_and_die ( "syntax error");
|
||||
|
||||
if (nextarg ("(")) {
|
||||
args++;
|
||||
v = eval ();
|
||||
if (!nextarg (")"))
|
||||
error_msg_and_die ( "syntax error");
|
||||
args++;
|
||||
return v;
|
||||
}
|
||||
|
||||
if (nextarg (")"))
|
||||
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)
|
||||
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 == (int) 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 > (int) 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 = strncpy ((char *) xmalloc (i2->u.i + 1),
|
||||
l->u.s + i1->u.i - 1, i2->u.i);
|
||||
v->u.s[i2->u.i] = 0;
|
||||
}
|
||||
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 (*fxn) (), val;
|
||||
|
||||
l = eval5 ();
|
||||
while (1) {
|
||||
if (nextarg ("*"))
|
||||
fxn = multiply;
|
||||
else if (nextarg ("/"))
|
||||
fxn = divide;
|
||||
else if (nextarg ("%"))
|
||||
fxn = mod;
|
||||
else
|
||||
return l;
|
||||
args++;
|
||||
r = eval5 ();
|
||||
val = (*fxn) (l, r);
|
||||
freev (l);
|
||||
freev (r);
|
||||
l = int_value (val);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle +, - operators. */
|
||||
|
||||
static VALUE *eval3 (void)
|
||||
{
|
||||
VALUE *l, *r;
|
||||
int (*fxn) (), val;
|
||||
|
||||
l = eval4 ();
|
||||
while (1) {
|
||||
if (nextarg ("+"))
|
||||
fxn = plus;
|
||||
else if (nextarg ("-"))
|
||||
fxn = minus;
|
||||
else
|
||||
return l;
|
||||
args++;
|
||||
r = eval4 ();
|
||||
val = (*fxn) (l, r);
|
||||
freev (l);
|
||||
freev (r);
|
||||
l = int_value (val);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle comparisons. */
|
||||
|
||||
static VALUE *eval2 (void)
|
||||
{
|
||||
VALUE *l, *r;
|
||||
int (*fxn) (), val;
|
||||
|
||||
l = eval3 ();
|
||||
while (1) {
|
||||
if (nextarg ("<"))
|
||||
fxn = less_than;
|
||||
else if (nextarg ("<="))
|
||||
fxn = less_equal;
|
||||
else if (nextarg ("=") || nextarg ("=="))
|
||||
fxn = equal;
|
||||
else if (nextarg ("!="))
|
||||
fxn = not_equal;
|
||||
else if (nextarg (">="))
|
||||
fxn = greater_equal;
|
||||
else if (nextarg (">"))
|
||||
fxn = greater_than;
|
||||
else
|
||||
return l;
|
||||
args++;
|
||||
r = eval3 ();
|
||||
toarith (l);
|
||||
toarith (r);
|
||||
val = (*fxn) (l, r);
|
||||
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;
|
||||
}
|
|
@ -1,200 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini find implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
|
||||
* Reworked by David Douthitt <n9ubh@callsign.net> and
|
||||
* Matt Kraai <kraai@alumni.carnegiemellon.edu>.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fnmatch.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include "busybox.h"
|
||||
|
||||
|
||||
static char *pattern;
|
||||
|
||||
#ifdef BB_FEATURE_FIND_TYPE
|
||||
static int type_mask = 0;
|
||||
#endif
|
||||
|
||||
#ifdef BB_FEATURE_FIND_PERM
|
||||
static char perm_char = 0;
|
||||
static int perm_mask = 0;
|
||||
#endif
|
||||
|
||||
#ifdef BB_FEATURE_FIND_MTIME
|
||||
static char mtime_char;
|
||||
static int mtime_days;
|
||||
#endif
|
||||
|
||||
static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
|
||||
{
|
||||
if (pattern != NULL) {
|
||||
const char *tmp = strrchr(fileName, '/');
|
||||
|
||||
if (tmp == NULL)
|
||||
tmp = fileName;
|
||||
else
|
||||
tmp++;
|
||||
if (!(fnmatch(pattern, tmp, FNM_PERIOD) == 0))
|
||||
goto no_match;
|
||||
}
|
||||
#ifdef BB_FEATURE_FIND_TYPE
|
||||
if (type_mask != 0) {
|
||||
if (!((statbuf->st_mode & S_IFMT) == type_mask))
|
||||
goto no_match;
|
||||
}
|
||||
#endif
|
||||
#ifdef BB_FEATURE_FIND_PERM
|
||||
if (perm_mask != 0) {
|
||||
if (!((isdigit(perm_char) && (statbuf->st_mode & 07777) == perm_mask) ||
|
||||
(perm_char == '-' && (statbuf->st_mode & perm_mask) == perm_mask) ||
|
||||
(perm_char == '+' && (statbuf->st_mode & perm_mask) != 0)))
|
||||
goto no_match;
|
||||
}
|
||||
#endif
|
||||
#ifdef BB_FEATURE_FIND_MTIME
|
||||
if (mtime_days != 0) {
|
||||
time_t file_age = time(NULL) - statbuf->st_mtime;
|
||||
time_t mtime_secs = mtime_days * 24 * 60 * 60;
|
||||
if (!((isdigit(mtime_char) && mtime_secs >= file_age &&
|
||||
mtime_secs < file_age + 24 * 60 * 60) ||
|
||||
(mtime_char == '+' && mtime_secs >= file_age) ||
|
||||
(mtime_char == '-' && mtime_secs < file_age)))
|
||||
goto no_match;
|
||||
}
|
||||
#endif
|
||||
puts(fileName);
|
||||
no_match:
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
#ifdef BB_FEATURE_FIND_TYPE
|
||||
static int find_type(char *type)
|
||||
{
|
||||
int mask = 0;
|
||||
|
||||
switch (type[0]) {
|
||||
case 'b':
|
||||
mask = S_IFBLK;
|
||||
break;
|
||||
case 'c':
|
||||
mask = S_IFCHR;
|
||||
break;
|
||||
case 'd':
|
||||
mask = S_IFDIR;
|
||||
break;
|
||||
case 'p':
|
||||
mask = S_IFIFO;
|
||||
break;
|
||||
case 'f':
|
||||
mask = S_IFREG;
|
||||
break;
|
||||
case 'l':
|
||||
mask = S_IFLNK;
|
||||
break;
|
||||
case 's':
|
||||
mask = S_IFSOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mask == 0 || type[1] != '\0')
|
||||
error_msg_and_die("invalid argument `%s' to `-type'", type);
|
||||
|
||||
return mask;
|
||||
}
|
||||
#endif
|
||||
|
||||
int find_main(int argc, char **argv)
|
||||
{
|
||||
int dereference = FALSE;
|
||||
int i, firstopt, status = EXIT_SUCCESS;
|
||||
|
||||
for (firstopt = 1; firstopt < argc; firstopt++) {
|
||||
if (argv[firstopt][0] == '-')
|
||||
break;
|
||||
}
|
||||
|
||||
/* Parse any options */
|
||||
for (i = firstopt; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-follow") == 0)
|
||||
dereference = TRUE;
|
||||
else if (strcmp(argv[i], "-print") == 0) {
|
||||
;
|
||||
}
|
||||
else if (strcmp(argv[i], "-name") == 0) {
|
||||
if (++i == argc)
|
||||
error_msg_and_die("option `-name' requires an argument");
|
||||
pattern = argv[i];
|
||||
#ifdef BB_FEATURE_FIND_TYPE
|
||||
} else if (strcmp(argv[i], "-type") == 0) {
|
||||
if (++i == argc)
|
||||
error_msg_and_die("option `-type' requires an argument");
|
||||
type_mask = find_type(argv[i]);
|
||||
#endif
|
||||
#ifdef BB_FEATURE_FIND_PERM
|
||||
} else if (strcmp(argv[i], "-perm") == 0) {
|
||||
char *end;
|
||||
if (++i == argc)
|
||||
error_msg_and_die("option `-perm' requires an argument");
|
||||
perm_mask = strtol(argv[i], &end, 8);
|
||||
if (end[0] != '\0')
|
||||
error_msg_and_die("invalid argument `%s' to `-perm'", argv[i]);
|
||||
if (perm_mask > 07777)
|
||||
error_msg_and_die("invalid argument `%s' to `-perm'", argv[i]);
|
||||
if ((perm_char = argv[i][0]) == '-')
|
||||
perm_mask = -perm_mask;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_FIND_MTIME
|
||||
} else if (strcmp(argv[i], "-mtime") == 0) {
|
||||
char *end;
|
||||
if (++i == argc)
|
||||
error_msg_and_die("option `-mtime' requires an argument");
|
||||
mtime_days = strtol(argv[i], &end, 10);
|
||||
if (end[0] != '\0')
|
||||
error_msg_and_die("invalid argument `%s' to `-mtime'", argv[i]);
|
||||
if ((mtime_char = argv[i][0]) == '-')
|
||||
mtime_days = -mtime_days;
|
||||
#endif
|
||||
} else
|
||||
show_usage();
|
||||
}
|
||||
|
||||
if (firstopt == 1) {
|
||||
if (recursive_action(".", TRUE, dereference, FALSE, fileAction,
|
||||
fileAction, NULL) == FALSE)
|
||||
status = EXIT_FAILURE;
|
||||
} else {
|
||||
for (i = 1; i < firstopt; i++) {
|
||||
if (recursive_action(argv[i], TRUE, dereference, FALSE, fileAction,
|
||||
fileAction, NULL) == FALSE)
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
359
busybox/grep.c
|
@ -1,359 +0,0 @@
|
|||
/*
|
||||
* Mini grep implementation for busybox using libc regex.
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||
* Written by Mark Whitley <markw@lineo.com>, <markw@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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <regex.h>
|
||||
#include <string.h> /* for strerror() */
|
||||
#include <errno.h>
|
||||
#include "busybox.h"
|
||||
|
||||
|
||||
extern int optind; /* in unistd.h */
|
||||
extern int errno; /* for use with strerror() */
|
||||
extern void xregcomp(regex_t *preg, const char *regex, int cflags); /* in busybox.h */
|
||||
|
||||
/* options */
|
||||
static int reflags = REG_NOSUB;
|
||||
static int print_filename = 0;
|
||||
static int print_line_num = 0;
|
||||
static int print_match_counts = 0;
|
||||
static int be_quiet = 0;
|
||||
static int invert_search = 0;
|
||||
static int suppress_err_msgs = 0;
|
||||
static int print_files_with_matches = 0;
|
||||
|
||||
#ifdef BB_FEATURE_GREP_CONTEXT
|
||||
extern char *optarg; /* in getopt.h */
|
||||
static int lines_before = 0;
|
||||
static int lines_after = 0;
|
||||
static char **before_buf = NULL;
|
||||
static int last_line_printed = 0;
|
||||
#endif /* BB_FEATURE_GREP_CONTEXT */
|
||||
|
||||
/* globals used internally */
|
||||
static regex_t *regexes = NULL; /* growable array of compiled regular expressions */
|
||||
static int nregexes = 0; /* number of elements in above arrary */
|
||||
static int matched; /* keeps track of whether we ever matched */
|
||||
static char *cur_file = NULL; /* the current file we are reading */
|
||||
|
||||
|
||||
static void print_line(const char *line, int linenum, char decoration)
|
||||
{
|
||||
#ifdef BB_FEATURE_GREP_CONTEXT
|
||||
/* possibly print the little '--' seperator */
|
||||
if ((lines_before || lines_after) && last_line_printed &&
|
||||
last_line_printed < linenum - 1) {
|
||||
puts("--");
|
||||
}
|
||||
last_line_printed = linenum;
|
||||
#endif
|
||||
if (print_filename)
|
||||
printf("%s%c", cur_file, decoration);
|
||||
if (print_line_num)
|
||||
printf("%i%c", linenum, decoration);
|
||||
puts(line);
|
||||
}
|
||||
|
||||
|
||||
static void grep_file(FILE *file)
|
||||
{
|
||||
char *line = NULL;
|
||||
int ret;
|
||||
int linenum = 0;
|
||||
int nmatches = 0;
|
||||
int i;
|
||||
#ifdef BB_FEATURE_GREP_CONTEXT
|
||||
int print_n_lines_after = 0;
|
||||
int curpos = 0; /* track where we are in the circular 'before' buffer */
|
||||
int idx = 0; /* used for iteration through the circular buffer */
|
||||
#endif /* BB_FEATURE_GREP_CONTEXT */
|
||||
|
||||
while ((line = get_line_from_file(file)) != NULL) {
|
||||
chomp(line);
|
||||
linenum++;
|
||||
|
||||
for (i = 0; i < nregexes; i++) {
|
||||
/*
|
||||
* test for a postitive-assertion match (regexec returns success (0)
|
||||
* and the user did not specify invert search), or a negative-assertion
|
||||
* match (regexec returns failure (REG_NOMATCH) and the user specified
|
||||
* invert search)
|
||||
*/
|
||||
ret = regexec(®exes[i], line, 0, NULL, 0);
|
||||
if ((ret == 0 && !invert_search) || (ret == REG_NOMATCH && invert_search)) {
|
||||
|
||||
/* if we found a match but were told to be quiet, stop here and
|
||||
* return success */
|
||||
if (be_quiet)
|
||||
exit(0);
|
||||
|
||||
/* keep track of matches */
|
||||
nmatches++;
|
||||
|
||||
/* if we're just printing filenames, we stop after the first match */
|
||||
if (print_files_with_matches)
|
||||
break;
|
||||
|
||||
/* print the matched line */
|
||||
if (print_match_counts == 0) {
|
||||
#ifdef BB_FEATURE_GREP_CONTEXT
|
||||
int prevpos = (curpos == 0) ? lines_before - 1 : curpos - 1;
|
||||
|
||||
/* if we were told to print 'before' lines and there is at least
|
||||
* one line in the circular buffer, print them */
|
||||
if (lines_before && before_buf[prevpos] != NULL) {
|
||||
int first_buf_entry_line_num = linenum - lines_before;
|
||||
|
||||
/* advance to the first entry in the circular buffer, and
|
||||
* figure out the line number is of the first line in the
|
||||
* buffer */
|
||||
idx = curpos;
|
||||
while (before_buf[idx] == NULL) {
|
||||
idx = (idx + 1) % lines_before;
|
||||
first_buf_entry_line_num++;
|
||||
}
|
||||
|
||||
/* now print each line in the buffer, clearing them as we go */
|
||||
while (before_buf[idx] != NULL) {
|
||||
print_line(before_buf[idx], first_buf_entry_line_num, '-');
|
||||
free(before_buf[idx]);
|
||||
before_buf[idx] = NULL;
|
||||
idx = (idx + 1) % lines_before;
|
||||
first_buf_entry_line_num++;
|
||||
}
|
||||
}
|
||||
|
||||
/* make a note that we need to print 'after' lines */
|
||||
print_n_lines_after = lines_after;
|
||||
#endif /* BB_FEATURE_GREP_CONTEXT */
|
||||
print_line(line, linenum, ':');
|
||||
}
|
||||
}
|
||||
#ifdef BB_FEATURE_GREP_CONTEXT
|
||||
else { /* no match */
|
||||
/* Add the line to the circular 'before' buffer */
|
||||
if(lines_before) {
|
||||
if(before_buf[curpos])
|
||||
free(before_buf[curpos]);
|
||||
before_buf[curpos] = strdup(line);
|
||||
curpos = (curpos + 1) % lines_before;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we need to print some context lines after the last match, do so */
|
||||
if (print_n_lines_after && (last_line_printed != linenum)) {
|
||||
print_line(line, linenum, '-');
|
||||
print_n_lines_after--;
|
||||
}
|
||||
#endif /* BB_FEATURE_GREP_CONTEXT */
|
||||
} /* for */
|
||||
free(line);
|
||||
}
|
||||
|
||||
|
||||
/* special-case file post-processing for options where we don't print line
|
||||
* matches, just filenames and possibly match counts */
|
||||
|
||||
/* grep -c: print [filename:]count, even if count is zero */
|
||||
if (print_match_counts) {
|
||||
if (print_filename)
|
||||
printf("%s:", cur_file);
|
||||
if (print_files_with_matches && nmatches > 0)
|
||||
printf("1\n");
|
||||
else
|
||||
printf("%d\n", nmatches);
|
||||
}
|
||||
|
||||
/* grep -l: print just the filename, but only if we grepped the line in the file */
|
||||
if (print_files_with_matches && nmatches > 0) {
|
||||
puts(cur_file);
|
||||
}
|
||||
|
||||
|
||||
/* remember if we matched */
|
||||
if (nmatches != 0)
|
||||
matched = 1;
|
||||
}
|
||||
|
||||
|
||||
static void add_regex(const char *restr)
|
||||
{
|
||||
regexes = xrealloc(regexes, sizeof(regex_t) * (++nregexes));
|
||||
xregcomp(®exes[nregexes-1], restr, reflags);
|
||||
}
|
||||
|
||||
|
||||
static void load_regexes_from_file(const char *filename)
|
||||
{
|
||||
char *line;
|
||||
FILE *f = xfopen(filename, "r");
|
||||
while ((line = get_line_from_file(f)) != NULL) {
|
||||
chomp(line);
|
||||
add_regex(line);
|
||||
free(line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef BB_FEATURE_CLEAN_UP
|
||||
static void destroy_regexes()
|
||||
{
|
||||
if (regexes == NULL)
|
||||
return;
|
||||
|
||||
/* destroy all the elments in the array */
|
||||
while (--nregexes >= 0) {
|
||||
regfree(®exes[nregexes]);
|
||||
free(®exes[nregexes]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
extern int grep_main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
#ifdef BB_FEATURE_GREP_CONTEXT
|
||||
char *junk;
|
||||
#endif
|
||||
|
||||
#ifdef BB_FEATURE_CLEAN_UP
|
||||
/* destroy command strings on exit */
|
||||
if (atexit(destroy_regexes) == -1)
|
||||
perror_msg_and_die("atexit");
|
||||
#endif
|
||||
|
||||
/* do normal option parsing */
|
||||
while ((opt = getopt(argc, argv, "iHhlnqvsce:f:"
|
||||
#ifdef BB_FEATURE_GREP_CONTEXT
|
||||
"A:B:C:"
|
||||
#endif
|
||||
)) > 0) {
|
||||
switch (opt) {
|
||||
case 'i':
|
||||
reflags |= REG_ICASE;
|
||||
break;
|
||||
case 'l':
|
||||
print_files_with_matches++;
|
||||
break;
|
||||
case 'H':
|
||||
print_filename++;
|
||||
break;
|
||||
case 'h':
|
||||
print_filename--;
|
||||
break;
|
||||
case 'n':
|
||||
print_line_num++;
|
||||
break;
|
||||
case 'q':
|
||||
be_quiet++;
|
||||
break;
|
||||
case 'v':
|
||||
invert_search++;
|
||||
break;
|
||||
case 's':
|
||||
suppress_err_msgs++;
|
||||
break;
|
||||
case 'c':
|
||||
print_match_counts++;
|
||||
break;
|
||||
case 'e':
|
||||
add_regex(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
load_regexes_from_file(optarg);
|
||||
break;
|
||||
#ifdef BB_FEATURE_GREP_CONTEXT
|
||||
case 'A':
|
||||
lines_after = strtoul(optarg, &junk, 10);
|
||||
if(*junk != '\0')
|
||||
error_msg_and_die("invalid context length argument");
|
||||
break;
|
||||
case 'B':
|
||||
lines_before = strtoul(optarg, &junk, 10);
|
||||
if(*junk != '\0')
|
||||
error_msg_and_die("invalid context length argument");
|
||||
before_buf = (char **)calloc(lines_before, sizeof(char *));
|
||||
break;
|
||||
case 'C':
|
||||
lines_after = lines_before = strtoul(optarg, &junk, 10);
|
||||
if(*junk != '\0')
|
||||
error_msg_and_die("invalid context length argument");
|
||||
before_buf = (char **)calloc(lines_before, sizeof(char *));
|
||||
break;
|
||||
#endif /* BB_FEATURE_GREP_CONTEXT */
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
/* if we didn't get a pattern from a -e and no command file was specified,
|
||||
* argv[optind] should be the pattern. no pattern, no worky */
|
||||
if (nregexes == 0) {
|
||||
if (argv[optind] == NULL)
|
||||
show_usage();
|
||||
else {
|
||||
add_regex(argv[optind]);
|
||||
optind++;
|
||||
}
|
||||
}
|
||||
|
||||
/* sanity checks */
|
||||
if (print_match_counts || be_quiet || print_files_with_matches) {
|
||||
print_line_num = 0;
|
||||
#ifdef BB_FEATURE_GREP_CONTEXT
|
||||
lines_before = 0;
|
||||
lines_after = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* argv[(optind)..(argc-1)] should be names of file to grep through. If
|
||||
* there is more than one file to grep, we will print the filenames */
|
||||
if ((argc-1) - (optind) > 0)
|
||||
print_filename++;
|
||||
|
||||
/* If no files were specified, or '-' was specified, take input from
|
||||
* stdin. Otherwise, we grep through all the files specified. */
|
||||
if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
|
||||
grep_file(stdin);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
FILE *file;
|
||||
for (i = optind; i < argc; i++) {
|
||||
cur_file = argv[i];
|
||||
file = fopen(cur_file, "r");
|
||||
if (file == NULL) {
|
||||
if (!suppress_err_msgs)
|
||||
perror_msg("%s", cur_file);
|
||||
}
|
||||
else {
|
||||
grep_file(file);
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !matched; /* invert return value 0 = success, 1 = failed */
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini hostid implementation for busybox
|
||||
*
|
||||
* Copyright (C) 2000 Edward Betts <edward@debian.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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "busybox.h"
|
||||
|
||||
extern int hostid_main(int argc, char **argv)
|
||||
{
|
||||
printf("%lx\n", gethostid());
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* $Id: hostname.c,v 1.30 2001/06/26 02:06:08 bug1 Exp $
|
||||
* Mini hostname implementation for busybox
|
||||
*
|
||||
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
|
||||
*
|
||||
* adjusted by Erik Andersen <andersee@debian.org> to remove
|
||||
* use of long options and GNU getopt. Improved the usage info.
|
||||
*
|
||||
* 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 <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "busybox.h"
|
||||
|
||||
static void do_sethostname(char *s, int isfile)
|
||||
{
|
||||
FILE *f;
|
||||
char buf[255];
|
||||
|
||||
if (!s)
|
||||
return;
|
||||
if (!isfile) {
|
||||
if (sethostname(s, strlen(s)) < 0) {
|
||||
if (errno == EPERM)
|
||||
error_msg_and_die("you must be root to change the hostname");
|
||||
else
|
||||
perror_msg_and_die("sethostname");
|
||||
}
|
||||
} else {
|
||||
f = xfopen(s, "r");
|
||||
fgets(buf, 255, f);
|
||||
#ifdef BB_FEATURE_CLEAN_UP
|
||||
fclose(f);
|
||||
#endif
|
||||
chomp(buf);
|
||||
do_sethostname(buf, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int hostname_main(int argc, char **argv)
|
||||
{
|
||||
int opt_short = 0;
|
||||
int opt_domain = 0;
|
||||
int opt_ip = 0;
|
||||
struct hostent *h;
|
||||
char *filename = NULL;
|
||||
char buf[255];
|
||||
char *s = NULL;
|
||||
|
||||
if (argc < 1)
|
||||
show_usage();
|
||||
|
||||
while (--argc > 0 && **(++argv) == '-') {
|
||||
while (*(++(*argv))) {
|
||||
switch (**argv) {
|
||||
case 's':
|
||||
opt_short = 1;
|
||||
break;
|
||||
case 'i':
|
||||
opt_ip = 1;
|
||||
break;
|
||||
case 'd':
|
||||
opt_domain = 1;
|
||||
break;
|
||||
case 'F':
|
||||
if (--argc == 0) {
|
||||
show_usage();
|
||||
}
|
||||
filename = *(++argv);
|
||||
break;
|
||||
case '-':
|
||||
if (strcmp(++(*argv), "file") || --argc ==0 ) {
|
||||
show_usage();
|
||||
}
|
||||
filename = *(++argv);
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
if (filename != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc >= 1) {
|
||||
do_sethostname(*argv, 0);
|
||||
} else if (filename != NULL) {
|
||||
do_sethostname(filename, 1);
|
||||
} else {
|
||||
gethostname(buf, 255);
|
||||
if (opt_short) {
|
||||
s = strchr(buf, '.');
|
||||
if (!s)
|
||||
s = buf;
|
||||
*s = 0;
|
||||
puts(buf);
|
||||
} else if (opt_domain) {
|
||||
s = strchr(buf, '.');
|
||||
puts(s ? s + 1 : "");
|
||||
} else if (opt_ip) {
|
||||
h = xgethostbyname(buf);
|
||||
puts(inet_ntoa(*(struct in_addr *) (h->h_addr)));
|
||||
} else {
|
||||
puts(buf);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
2692
busybox/hush.c
97
busybox/id.c
|
@ -1,97 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini id implementation for busybox
|
||||
*
|
||||
* Copyright (C) 2000 by Randolph Chung <tausq@debian.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 "busybox.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
extern int id_main(int argc, char **argv)
|
||||
{
|
||||
int no_user = 0, no_group = 0, print_real = 0;
|
||||
int name_not_number = 0;
|
||||
char user[9], group[9];
|
||||
long gid;
|
||||
long pwnam, grnam;
|
||||
int opt;
|
||||
|
||||
gid = 0;
|
||||
|
||||
while ((opt = getopt(argc, argv, "ugrn")) > 0) {
|
||||
switch (opt) {
|
||||
case 'u':
|
||||
no_group++;
|
||||
break;
|
||||
case 'g':
|
||||
no_user++;
|
||||
break;
|
||||
case 'r':
|
||||
print_real++;
|
||||
break;
|
||||
case 'n':
|
||||
name_not_number++;
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (no_user && no_group) show_usage();
|
||||
|
||||
if (argv[optind] == NULL) {
|
||||
if (print_real) {
|
||||
my_getpwuid(user, getuid());
|
||||
my_getgrgid(group, getgid());
|
||||
} else {
|
||||
my_getpwuid(user, geteuid());
|
||||
my_getgrgid(group, getegid());
|
||||
}
|
||||
} else {
|
||||
strncpy(user, argv[optind], 8);
|
||||
user[8] = '\0';
|
||||
gid = my_getpwnamegid(user);
|
||||
my_getgrgid(group, gid);
|
||||
}
|
||||
|
||||
pwnam=my_getpwnam(user);
|
||||
grnam=my_getgrnam(group);
|
||||
|
||||
if (no_group) {
|
||||
if(name_not_number && user)
|
||||
puts(user);
|
||||
else
|
||||
printf("%ld\n", pwnam);
|
||||
} else if (no_user) {
|
||||
if(name_not_number && group)
|
||||
puts(group);
|
||||
else
|
||||
printf("%ld\n", grnam);
|
||||
} else {
|
||||
printf("uid=%ld(%s) gid=%ld(%s)\n", pwnam, user, grnam, group);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* END CODE */
|
|
@ -1,492 +0,0 @@
|
|||
/* ifconfig
|
||||
*
|
||||
* Similar to the standard Unix ifconfig, but with only the necessary
|
||||
* parts for AF_INET, and without any printing of if info (for now).
|
||||
*
|
||||
* Bjorn Wesen, Axis Communications AB
|
||||
*
|
||||
*
|
||||
* Authors of the original ifconfig was:
|
||||
* Fred N. van Kempen, <waltje@uwalt.nl.mugnet.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.
|
||||
*
|
||||
* $Id: ifconfig.c,v 1.11.2.1 2001/08/10 18:22:15 andersen Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Heavily modified by Manuel Novoa III Mar 6, 2001
|
||||
*
|
||||
* From initial port to busybox, removed most of the redundancy by
|
||||
* converting to a table-driven approach. Added several (optional)
|
||||
* args missing from initial port.
|
||||
*
|
||||
* Still missing: media, tunnel.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h> // strcmp and friends
|
||||
#include <ctype.h> // isdigit and friends
|
||||
#include <stddef.h> /* offsetof */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include "busybox.h"
|
||||
|
||||
#ifdef BB_FEATURE_IFCONFIG_SLIP
|
||||
#include <linux/if_slip.h>
|
||||
#endif
|
||||
|
||||
/* I don't know if this is needed for busybox or not. Anyone? */
|
||||
#define QUESTIONABLE_ALIAS_CASE
|
||||
|
||||
|
||||
/* Defines for glibc2.0 users. */
|
||||
#ifndef SIOCSIFTXQLEN
|
||||
#define SIOCSIFTXQLEN 0x8943
|
||||
#define SIOCGIFTXQLEN 0x8942
|
||||
#endif
|
||||
|
||||
/* ifr_qlen is ifru_ivalue, but it isn't present in 2.0 kernel headers */
|
||||
#ifndef ifr_qlen
|
||||
#define ifr_qlen ifr_ifru.ifru_mtu
|
||||
#endif
|
||||
|
||||
#ifndef IFF_DYNAMIC
|
||||
#define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Here are the bit masks for the "flags" member of struct options below.
|
||||
* N_ signifies no arg prefix; M_ signifies arg prefixed by '-'.
|
||||
* CLR clears the flag; SET sets the flag; ARG signifies (optional) arg.
|
||||
*/
|
||||
#define N_CLR 0x01
|
||||
#define M_CLR 0x02
|
||||
#define N_SET 0x04
|
||||
#define M_SET 0x08
|
||||
#define N_ARG 0x10
|
||||
#define M_ARG 0x20
|
||||
|
||||
#define M_MASK (M_CLR | M_SET | M_ARG)
|
||||
#define N_MASK (N_CLR | N_SET | N_ARG)
|
||||
#define SET_MASK (N_SET | M_SET)
|
||||
#define CLR_MASK (N_CLR | M_CLR)
|
||||
#define SET_CLR_MASK (SET_MASK | CLR_MASK)
|
||||
#define ARG_MASK (M_ARG | N_ARG)
|
||||
|
||||
/*
|
||||
* Here are the bit masks for the "arg_flags" member of struct options below.
|
||||
*/
|
||||
|
||||
/*
|
||||
* cast type:
|
||||
* 00 int
|
||||
* 01 char *
|
||||
* 02 HOST_COPY in_ether
|
||||
* 03 HOST_COPY INET_resolve
|
||||
*/
|
||||
#define A_CAST_TYPE 0x03
|
||||
/*
|
||||
* map type:
|
||||
* 00 not a map type (mem_start, io_addr, irq)
|
||||
* 04 memstart (unsigned long)
|
||||
* 08 io_addr (unsigned short)
|
||||
* 0C irq (unsigned char)
|
||||
*/
|
||||
#define A_MAP_TYPE 0x0C
|
||||
#define A_ARG_REQ 0x10 /* Set if an arg is required. */
|
||||
#define A_NETMASK 0x20 /* Set if netmask (check for multiple sets). */
|
||||
#define A_SET_AFTER 0x40 /* Set a flag at the end. */
|
||||
#define A_COLON_CHK 0x80 /* Is this needed? See below. */
|
||||
|
||||
/*
|
||||
* These defines are for dealing with the A_CAST_TYPE field.
|
||||
*/
|
||||
#define A_CAST_CHAR_PTR 0x01
|
||||
#define A_CAST_RESOLVE 0x01
|
||||
#define A_CAST_HOST_COPY 0x02
|
||||
#define A_CAST_HOST_COPY_IN_ETHER A_CAST_HOST_COPY
|
||||
#define A_CAST_HOST_COPY_RESOLVE (A_CAST_HOST_COPY | A_CAST_RESOLVE)
|
||||
|
||||
/*
|
||||
* These defines are for dealing with the A_MAP_TYPE field.
|
||||
*/
|
||||
#define A_MAP_ULONG 0x04 /* memstart */
|
||||
#define A_MAP_USHORT 0x08 /* io_addr */
|
||||
#define A_MAP_UCHAR 0x0C /* irq */
|
||||
|
||||
/*
|
||||
* Define the bit masks signifying which operations to perform for each arg.
|
||||
*/
|
||||
|
||||
#define ARG_METRIC (A_ARG_REQ /*| A_CAST_INT*/)
|
||||
#define ARG_MTU (A_ARG_REQ /*| A_CAST_INT*/)
|
||||
#define ARG_TXQUEUELEN (A_ARG_REQ /*| A_CAST_INT*/)
|
||||
#define ARG_MEM_START (A_ARG_REQ | A_MAP_ULONG)
|
||||
#define ARG_IO_ADDR (A_ARG_REQ | A_MAP_USHORT)
|
||||
#define ARG_IRQ (A_ARG_REQ | A_MAP_UCHAR)
|
||||
#define ARG_DSTADDR (A_ARG_REQ | A_CAST_HOST_COPY_RESOLVE)
|
||||
#define ARG_NETMASK (A_ARG_REQ | A_CAST_HOST_COPY_RESOLVE | A_NETMASK)
|
||||
#define ARG_BROADCAST (A_ARG_REQ | A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER)
|
||||
#define ARG_HW (A_ARG_REQ | A_CAST_HOST_COPY_IN_ETHER)
|
||||
#define ARG_POINTOPOINT (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER)
|
||||
#define ARG_KEEPALIVE (A_ARG_REQ | A_CAST_CHAR_PTR)
|
||||
#define ARG_OUTFILL (A_ARG_REQ | A_CAST_CHAR_PTR)
|
||||
#define ARG_HOSTNAME (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER | A_COLON_CHK)
|
||||
|
||||
|
||||
/*
|
||||
* Set up the tables. Warning! They must have corresponding order!
|
||||
*/
|
||||
|
||||
struct arg1opt {
|
||||
const char *name;
|
||||
unsigned short selector;
|
||||
unsigned short ifr_offset;
|
||||
};
|
||||
|
||||
struct options {
|
||||
const char *name;
|
||||
const unsigned char flags;
|
||||
const unsigned char arg_flags;
|
||||
const unsigned short selector;
|
||||
};
|
||||
|
||||
#define ifreq_offsetof(x) offsetof(struct ifreq, x)
|
||||
|
||||
static const struct arg1opt Arg1Opt[] = {
|
||||
{"SIOCSIFMETRIC", SIOCSIFMETRIC, ifreq_offsetof(ifr_metric)},
|
||||
{"SIOCSIFMTU", SIOCSIFMTU, ifreq_offsetof(ifr_mtu)},
|
||||
{"SIOCSIFTXQLEN", SIOCSIFTXQLEN, ifreq_offsetof(ifr_qlen)},
|
||||
{"SIOCSIFDSTADDR", SIOCSIFDSTADDR, ifreq_offsetof(ifr_dstaddr)},
|
||||
{"SIOCSIFNETMASK", SIOCSIFNETMASK, ifreq_offsetof(ifr_netmask)},
|
||||
{"SIOCSIFBRDADDR", SIOCSIFBRDADDR, ifreq_offsetof(ifr_broadaddr)},
|
||||
#ifdef BB_FEATURE_IFCONFIG_HW
|
||||
{"SIOCSIFHWADDR", SIOCSIFHWADDR, ifreq_offsetof(ifr_hwaddr)},
|
||||
#endif
|
||||
{"SIOCSIFDSTADDR", SIOCSIFDSTADDR, ifreq_offsetof(ifr_dstaddr)},
|
||||
#ifdef SIOCSKEEPALIVE
|
||||
{"SIOCSKEEPALIVE", SIOCSKEEPALIVE, ifreq_offsetof(ifr_data)},
|
||||
#endif
|
||||
#ifdef SIOCSOUTFILL
|
||||
{"SIOCSOUTFILL", SIOCSOUTFILL, ifreq_offsetof(ifr_data)},
|
||||
#endif
|
||||
#ifdef BB_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
|
||||
{"SIOCSIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.mem_start)},
|
||||
{"SIOCSIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.base_addr)},
|
||||
{"SIOCSIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.irq)},
|
||||
#endif
|
||||
/* Last entry if for unmatched (possibly hostname) arg. */
|
||||
{"SIOCSIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr)},
|
||||
};
|
||||
|
||||
static const struct options OptArray[] = {
|
||||
{"metric", N_ARG, ARG_METRIC, 0},
|
||||
{"mtu", N_ARG, ARG_MTU, 0},
|
||||
{"txqueuelen", N_ARG, ARG_TXQUEUELEN, 0},
|
||||
{"dstaddr", N_ARG, ARG_DSTADDR, 0},
|
||||
{"netmask", N_ARG, ARG_NETMASK, 0},
|
||||
{"broadcast", N_ARG | M_CLR, ARG_BROADCAST, IFF_BROADCAST},
|
||||
#ifdef BB_FEATURE_IFCONFIG_HW
|
||||
{"hw", N_ARG, ARG_HW, 0},
|
||||
#endif
|
||||
{"pointopoint", N_ARG | M_CLR, ARG_POINTOPOINT, IFF_POINTOPOINT},
|
||||
#ifdef SIOCSKEEPALIVE
|
||||
{"keepalive", N_ARG, ARG_KEEPALIVE, 0},
|
||||
#endif
|
||||
#ifdef SIOCSOUTFILL
|
||||
{"outfill", N_ARG, ARG_OUTFILL, 0},
|
||||
#endif
|
||||
#ifdef BB_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
|
||||
{"mem_start", N_ARG, ARG_MEM_START, 0},
|
||||
{"io_addr", N_ARG, ARG_IO_ADDR, 0},
|
||||
{"irq", N_ARG, ARG_IRQ, 0},
|
||||
#endif
|
||||
{"arp", N_CLR | M_SET, 0, IFF_NOARP},
|
||||
{"trailers", N_CLR | M_SET, 0, IFF_NOTRAILERS},
|
||||
{"promisc", N_SET | M_CLR, 0, IFF_PROMISC},
|
||||
{"multicast", N_SET | M_CLR, 0, IFF_MULTICAST},
|
||||
{"allmulti", N_SET | M_CLR, 0, IFF_ALLMULTI},
|
||||
{"dynamic", N_SET | M_CLR, 0, IFF_DYNAMIC},
|
||||
{"up", N_SET , 0, (IFF_UP | IFF_RUNNING)},
|
||||
{"down", N_CLR , 0, IFF_UP},
|
||||
{ NULL, 0, ARG_HOSTNAME, (IFF_UP | IFF_RUNNING)}
|
||||
};
|
||||
|
||||
/*
|
||||
* A couple of prototypes.
|
||||
*/
|
||||
|
||||
#ifdef BB_FEATURE_IFCONFIG_HW
|
||||
static int in_ether(char *bufp, struct sockaddr *sap);
|
||||
#endif
|
||||
|
||||
#ifdef BB_FEATURE_IFCONFIG_STATUS
|
||||
extern int interface_opt_a;
|
||||
extern int display_interfaces(char *ifname);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Our main function.
|
||||
*/
|
||||
|
||||
int ifconfig_main(int argc, char **argv)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_in sai;
|
||||
#ifdef BB_FEATURE_IFCONFIG_HW
|
||||
struct sockaddr sa;
|
||||
#endif
|
||||
const struct arg1opt *a1op;
|
||||
const struct options *op;
|
||||
int sockfd; /* socket fd we use to manipulate stuff with */
|
||||
int goterr;
|
||||
int selector;
|
||||
char *p;
|
||||
char host[128];
|
||||
unsigned char mask;
|
||||
unsigned char did_flags;
|
||||
|
||||
goterr = 0;
|
||||
did_flags = 0;
|
||||
|
||||
/* skip argv[0] */
|
||||
++argv;
|
||||
--argc;
|
||||
|
||||
#ifdef BB_FEATURE_IFCONFIG_STATUS
|
||||
if ((argc > 0) && (strcmp(*argv,"-a") == 0)) {
|
||||
interface_opt_a = 1;
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(argc <= 1) {
|
||||
#ifdef BB_FEATURE_IFCONFIG_STATUS
|
||||
return display_interfaces(argc ? *argv : NULL);
|
||||
#else
|
||||
error_msg_and_die( "ifconfig was not compiled with interface status display support.");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Create a channel to the NET kernel. */
|
||||
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
perror_msg_and_die("socket");
|
||||
}
|
||||
|
||||
/* get interface name */
|
||||
safe_strncpy(ifr.ifr_name, *argv, IFNAMSIZ);
|
||||
|
||||
/* Process the remaining arguments. */
|
||||
while (*++argv != (char *) NULL) {
|
||||
p = *argv;
|
||||
mask = N_MASK;
|
||||
if (*p == '-') { /* If the arg starts with '-'... */
|
||||
++p; /* advance past it and */
|
||||
mask = M_MASK; /* set the appropriate mask. */
|
||||
}
|
||||
for (op = OptArray ; op->name ; op++) { /* Find table entry. */
|
||||
if (strcmp(p,op->name) == 0) { /* If name matches... */
|
||||
if ((mask &= op->flags)) { /* set the mask and go. */
|
||||
goto FOUND_ARG;;
|
||||
}
|
||||
/* If we get here, there was a valid arg with an */
|
||||
/* invalid '-' prefix. */
|
||||
++goterr;
|
||||
goto LOOP;
|
||||
}
|
||||
}
|
||||
|
||||
/* We fell through, so treat as possible hostname. */
|
||||
a1op = Arg1Opt + (sizeof(Arg1Opt) / sizeof(Arg1Opt[0])) - 1;
|
||||
mask = op->arg_flags;
|
||||
goto HOSTNAME;
|
||||
|
||||
FOUND_ARG:
|
||||
if (mask & ARG_MASK) {
|
||||
mask = op->arg_flags;
|
||||
a1op = Arg1Opt + (op - OptArray);
|
||||
if (mask & A_NETMASK & did_flags) {
|
||||
show_usage();
|
||||
}
|
||||
if (*++argv == NULL) {
|
||||
if (mask & A_ARG_REQ) {
|
||||
show_usage();
|
||||
} else {
|
||||
--argv;
|
||||
mask &= A_SET_AFTER; /* just for broadcast */
|
||||
}
|
||||
} else { /* got an arg so process it */
|
||||
HOSTNAME:
|
||||
did_flags |= (mask & A_NETMASK);
|
||||
if (mask & A_CAST_HOST_COPY) {
|
||||
#ifdef BB_FEATURE_IFCONFIG_HW
|
||||
if (mask & A_CAST_RESOLVE) {
|
||||
#endif
|
||||
safe_strncpy(host, *argv, (sizeof host));
|
||||
sai.sin_family = AF_INET;
|
||||
sai.sin_port = 0;
|
||||
if (!strcmp(host, "default")) {
|
||||
/* Default is special, meaning 0.0.0.0. */
|
||||
sai.sin_addr.s_addr = INADDR_ANY;
|
||||
} else if (inet_aton(host, &sai.sin_addr) == 0) {
|
||||
/* It's not a dotted quad. */
|
||||
++goterr;
|
||||
continue;
|
||||
}
|
||||
p = (char *) &sai;
|
||||
#ifdef BB_FEATURE_IFCONFIG_HW
|
||||
} else { /* A_CAST_HOST_COPY_IN_ETHER */
|
||||
/* This is the "hw" arg case. */
|
||||
if (strcmp("ether", *argv) || (*++argv == NULL)) {
|
||||
show_usage();
|
||||
}
|
||||
safe_strncpy(host, *argv, (sizeof host));
|
||||
if (in_ether(host, &sa)) {
|
||||
fprintf(stderr, "invalid hw-addr %s\n", host);
|
||||
++goterr;
|
||||
continue;
|
||||
}
|
||||
p = (char *) &sa;
|
||||
}
|
||||
#endif
|
||||
memcpy((((char *)(&ifr)) + a1op->ifr_offset),
|
||||
p, sizeof(struct sockaddr));
|
||||
} else {
|
||||
unsigned int i = strtoul(*argv,NULL,0);
|
||||
p = ((char *)(&ifr)) + a1op->ifr_offset;
|
||||
#ifdef BB_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
|
||||
if (mask & A_MAP_TYPE) {
|
||||
if (ioctl(sockfd, SIOCGIFMAP, &ifr) < 0) {
|
||||
++goterr;
|
||||
continue;
|
||||
}
|
||||
if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR) {
|
||||
*((unsigned char *) p) = i;
|
||||
} else if (mask & A_MAP_USHORT) {
|
||||
*((unsigned short *) p) = i;
|
||||
} else {
|
||||
*((unsigned long *) p) = i;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (mask & A_CAST_CHAR_PTR) {
|
||||
*((caddr_t *) p) = (caddr_t) i;
|
||||
} else { /* A_CAST_INT */
|
||||
*((int *) p) = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (ioctl(sockfd, a1op->selector, &ifr) < 0) {
|
||||
perror(a1op->name);
|
||||
++goterr;
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef QUESTIONABLE_ALIAS_CASE
|
||||
if (mask & A_COLON_CHK) {
|
||||
/*
|
||||
* Don't do the set_flag() if the address is an alias with
|
||||
* a - at the end, since it's deleted already! - Roman
|
||||
*
|
||||
* Should really use regex.h here, not sure though how well
|
||||
* it'll go with the cross-platform support etc.
|
||||
*/
|
||||
char *ptr;
|
||||
short int found_colon = 0;
|
||||
for (ptr = ifr.ifr_name; *ptr; ptr++ ) {
|
||||
if (*ptr == ':') {
|
||||
found_colon++;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_colon && *(ptr - 1) == '-') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (!(mask & A_SET_AFTER)) {
|
||||
continue;
|
||||
}
|
||||
mask = N_SET;
|
||||
}
|
||||
|
||||
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
|
||||
perror("SIOCGIFFLAGS");
|
||||
++goterr;
|
||||
} else {
|
||||
selector = op->selector;
|
||||
if (mask & SET_MASK) {
|
||||
ifr.ifr_flags |= selector;
|
||||
} else {
|
||||
ifr.ifr_flags &= ~selector;
|
||||
}
|
||||
if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
|
||||
perror("SIOCSIFFLAGS");
|
||||
++goterr;
|
||||
}
|
||||
}
|
||||
LOOP:
|
||||
} /* end of while-loop */
|
||||
|
||||
return goterr;
|
||||
}
|
||||
|
||||
#ifdef BB_FEATURE_IFCONFIG_HW
|
||||
/* Input an Ethernet address and convert to binary. */
|
||||
static int
|
||||
in_ether(char *bufp, struct sockaddr *sap)
|
||||
{
|
||||
unsigned char *ptr;
|
||||
int i, j;
|
||||
unsigned char val;
|
||||
unsigned char c;
|
||||
|
||||
sap->sa_family = ARPHRD_ETHER;
|
||||
ptr = sap->sa_data;
|
||||
|
||||
for (i = 0 ; i < ETH_ALEN ; i++) {
|
||||
val = 0;
|
||||
|
||||
/* We might get a semicolon here - not required. */
|
||||
if (i && (*bufp == ':')) {
|
||||
bufp++;
|
||||
}
|
||||
|
||||
for (j=0 ; j<2 ; j++) {
|
||||
c = *bufp;
|
||||
if (c >= '0' && c <= '9') {
|
||||
c -= '0';
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
c -= ('a' - 10);
|
||||
} else if (c >= 'A' && c <= 'F') {
|
||||
c -= ('A' - 10);
|
||||
} else if (j && (c == ':' || c == 0)) {
|
||||
break;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
++bufp;
|
||||
val <<= 4;
|
||||
val += c;
|
||||
}
|
||||
*ptr++ = val;
|
||||
}
|
||||
|
||||
return (int) (*bufp); /* Error if we don't end at end of string. */
|
||||
}
|
||||
#endif
|
|
@ -1,478 +0,0 @@
|
|||
/*
|
||||
* applets.h - a listing of all busybox applets.
|
||||
*
|
||||
* If you write a new applet, you need to add an entry to this list to make
|
||||
* busybox aware of it.
|
||||
*
|
||||
* It is CRUCIAL that this listing be kept in ascii order, otherwise the binary
|
||||
* search lookup contributed by Gaute B Strokkenes stops working. If you value
|
||||
* your kneecaps, you'll be sure to *make sure* that any changes made to this
|
||||
* file result in the listing remaining in ascii order. You have been warned.
|
||||
*/
|
||||
|
||||
#undef APPLET
|
||||
#undef APPLET_ODDNAME
|
||||
#undef APPLET_NOUSAGE
|
||||
|
||||
|
||||
#if defined(PROTOTYPES)
|
||||
#define APPLET(a,b,c) extern int b(int argc, char **argv);
|
||||
#define APPLET_NOUSAGE(a,b,c) extern int b(int argc, char **argv);
|
||||
#define APPLET_ODDNAME(a,b,c,d) extern int b(int argc, char **argv);
|
||||
extern const char usage_messages[];
|
||||
#elif defined(MAKE_USAGE)
|
||||
#ifdef BB_FEATURE_VERBOSE_USAGE
|
||||
#define APPLET(a,b,c) a##_trivial_usage "\n\n" a##_full_usage "\0"
|
||||
#define APPLET_NOUSAGE(a,b,c) "\0"
|
||||
#define APPLET_ODDNAME(a,b,c,d) d##_trivial_usage "\n\n" d##_full_usage "\0"
|
||||
#else
|
||||
#define APPLET(a,b,c) a##_trivial_usage "\0"
|
||||
#define APPLET_NOUSAGE(a,b,c) "\0"
|
||||
#define APPLET_ODDNAME(a,b,c,d) d##_trivial_usage "\0"
|
||||
#endif
|
||||
#elif defined(MAKE_LINKS)
|
||||
# define APPLET(a,b,c) LINK c a
|
||||
# define APPLET_NOUSAGE(a,b,c) LINK c a
|
||||
# define APPLET_ODDNAME(a,b,c,d) LINK c a
|
||||
#else
|
||||
const struct BB_applet applets[] = {
|
||||
#define APPLET(a,b,c) {#a,b,c},
|
||||
#define APPLET_NOUSAGE(a,b,c) {a,b,c},
|
||||
#define APPLET_ODDNAME(a,b,c,d) {a,b,c},
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef BB_TEST
|
||||
APPLET_NOUSAGE("[", test_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_ADJTIMEX
|
||||
APPLET(adjtimex, adjtimex_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_AR
|
||||
APPLET(ar, ar_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_ASH
|
||||
APPLET_NOUSAGE("ash", ash_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_BASENAME
|
||||
APPLET(basename, basename_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
APPLET_NOUSAGE("busybox", busybox_main, _BB_DIR_BIN)
|
||||
#ifdef BB_CAT
|
||||
APPLET(cat, cat_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_CHGRP
|
||||
APPLET(chgrp, chgrp_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_CHMOD
|
||||
APPLET(chmod, chmod_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_CHOWN
|
||||
APPLET(chown, chown_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_CHROOT
|
||||
APPLET(chroot, chroot_main, _BB_DIR_USR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_CHVT
|
||||
APPLET(chvt, chvt_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_CLEAR
|
||||
APPLET(clear, clear_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_CMP
|
||||
APPLET(cmp, cmp_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_CP
|
||||
APPLET(cp, cp_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_CPIO
|
||||
APPLET(cpio, cpio_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_CUT
|
||||
APPLET(cut, cut_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DATE
|
||||
APPLET(date, date_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DC
|
||||
APPLET(dc, dc_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DD
|
||||
APPLET(dd, dd_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DEALLOCVT
|
||||
APPLET(deallocvt, deallocvt_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DF
|
||||
APPLET(df, df_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DIRNAME
|
||||
APPLET(dirname, dirname_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DMESG
|
||||
APPLET(dmesg, dmesg_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DOS2UNIX
|
||||
APPLET(dos2unix, dos2unix_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DPKG
|
||||
APPLET(dpkg, dpkg_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DPKG_DEB
|
||||
APPLET_ODDNAME("dpkg-deb", dpkg_deb_main, _BB_DIR_USR_BIN, dpkg_deb)
|
||||
#endif
|
||||
#ifdef BB_DU
|
||||
APPLET(du, du_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DUMPKMAP
|
||||
APPLET(dumpkmap, dumpkmap_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DUTMP
|
||||
APPLET(dutmp, dutmp_main, _BB_DIR_USR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_ECHO
|
||||
APPLET(echo, echo_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#if defined(BB_FEATURE_GREP_EGREP_ALIAS) && defined(BB_GREP)
|
||||
APPLET_NOUSAGE("egrep", grep_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_ENV
|
||||
APPLET(env, env_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_EXPR
|
||||
APPLET(expr, expr_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TRUE_FALSE
|
||||
APPLET(false, false_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_FBSET
|
||||
APPLET(fbset, fbset_main, _BB_DIR_USR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_FDFLUSH
|
||||
APPLET(fdflush, fdflush_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_FIND
|
||||
APPLET(find, find_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_FREE
|
||||
APPLET(free, free_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_FREERAMDISK
|
||||
APPLET(freeramdisk, freeramdisk_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_FSCK_MINIX
|
||||
APPLET_ODDNAME("fsck.minix", fsck_minix_main, _BB_DIR_SBIN, fsck_minix)
|
||||
#endif
|
||||
#ifdef BB_GETOPT
|
||||
APPLET(getopt, getopt_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_GREP
|
||||
APPLET(grep, grep_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_GUNZIP
|
||||
APPLET(gunzip, gunzip_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_GZIP
|
||||
APPLET(gzip, gzip_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_HALT
|
||||
APPLET(halt, halt_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_HEAD
|
||||
APPLET(head, head_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_HOSTID
|
||||
APPLET(hostid, hostid_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_HOSTNAME
|
||||
APPLET(hostname, hostname_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_HUSH
|
||||
APPLET_NOUSAGE("hush", hush_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_ID
|
||||
APPLET(id, id_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_IFCONFIG
|
||||
APPLET(ifconfig, ifconfig_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_INIT
|
||||
APPLET(init, init_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_INSMOD
|
||||
APPLET(insmod, insmod_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_KILL
|
||||
APPLET(kill, kill_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_KILLALL
|
||||
APPLET(killall, kill_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_KLOGD
|
||||
APPLET(klogd, klogd_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_LASH
|
||||
APPLET(lash, lash_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_LENGTH
|
||||
APPLET(length, length_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_FEATURE_LINUXRC
|
||||
APPLET_NOUSAGE("linuxrc", init_main, _BB_DIR_ROOT)
|
||||
#endif
|
||||
#ifdef BB_LN
|
||||
APPLET(ln, ln_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_LOADACM
|
||||
APPLET(loadacm, loadacm_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_LOADFONT
|
||||
APPLET(loadfont, loadfont_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_LOADKMAP
|
||||
APPLET(loadkmap, loadkmap_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_LOGGER
|
||||
APPLET(logger, logger_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_LOGNAME
|
||||
APPLET(logname, logname_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_LOGREAD
|
||||
APPLET(logread, logread_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_LS
|
||||
APPLET(ls, ls_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_LSMOD
|
||||
APPLET(lsmod, lsmod_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_MAKEDEVS
|
||||
APPLET(makedevs, makedevs_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_MD5SUM
|
||||
APPLET(md5sum, md5sum_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_MKDIR
|
||||
APPLET(mkdir, mkdir_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_MKFIFO
|
||||
APPLET(mkfifo, mkfifo_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_MKFS_MINIX
|
||||
APPLET_ODDNAME("mkfs.minix", mkfs_minix_main, _BB_DIR_SBIN, mkfs_minix)
|
||||
#endif
|
||||
#ifdef BB_MKNOD
|
||||
APPLET(mknod, mknod_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_MKSWAP
|
||||
APPLET(mkswap, mkswap_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_MKTEMP
|
||||
APPLET(mktemp, mktemp_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_MODPROBE
|
||||
APPLET(modprobe, modprobe_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_MORE
|
||||
APPLET(more, more_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_MOUNT
|
||||
APPLET(mount, mount_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_MSH
|
||||
APPLET_NOUSAGE("msh", msh_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_MT
|
||||
APPLET(mt, mt_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_MV
|
||||
APPLET(mv, mv_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_NC
|
||||
APPLET(nc, nc_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_NSLOOKUP
|
||||
APPLET(nslookup, nslookup_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_PIDOF
|
||||
APPLET(pidof, pidof_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_PING
|
||||
APPLET(ping, ping_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_PIVOT_ROOT
|
||||
APPLET(pivot_root, pivot_root_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_POWEROFF
|
||||
APPLET(poweroff, poweroff_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_PRINTF
|
||||
APPLET(printf, printf_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_PS
|
||||
APPLET(ps, ps_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_PWD
|
||||
APPLET(pwd, pwd_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_RDATE
|
||||
APPLET(rdate, rdate_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_READLINK
|
||||
APPLET(readlink, readlink_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_REBOOT
|
||||
APPLET(reboot, reboot_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_RENICE
|
||||
APPLET(renice, renice_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_RESET
|
||||
APPLET(reset, reset_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_RM
|
||||
APPLET(rm, rm_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_RMDIR
|
||||
APPLET(rmdir, rmdir_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_RMMOD
|
||||
APPLET(rmmod, rmmod_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_ROUTE
|
||||
APPLET(route, route_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_RPM2CPIO
|
||||
APPLET(rpm2cpio, rpm2cpio_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_SED
|
||||
APPLET(sed, sed_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_SETKEYCODES
|
||||
APPLET(setkeycodes, setkeycodes_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#if defined(BB_FEATURE_SH_IS_ASH) && defined(BB_ASH)
|
||||
APPLET_NOUSAGE("sh", ash_main, _BB_DIR_BIN)
|
||||
#elif defined(BB_FEATURE_SH_IS_HUSH) && defined(BB_HUSH)
|
||||
APPLET_NOUSAGE("sh", hush_main, _BB_DIR_BIN)
|
||||
#elif defined(BB_FEATURE_SH_IS_LASH) && defined(BB_LASH)
|
||||
APPLET_NOUSAGE("sh", lash_main, _BB_DIR_BIN)
|
||||
#elif defined(BB_FEATURE_SH_IS_MSH) && defined(BB_MSH)
|
||||
APPLET_NOUSAGE("sh", msh_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_SLEEP
|
||||
APPLET(sleep, sleep_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_SORT
|
||||
APPLET(sort, sort_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_STTY
|
||||
APPLET(stty, stty_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_SWAPONOFF
|
||||
APPLET(swapoff, swap_on_off_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_SWAPONOFF
|
||||
APPLET(swapon, swap_on_off_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_SYNC
|
||||
APPLET(sync, sync_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_SYSLOGD
|
||||
APPLET(syslogd, syslogd_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_TAIL
|
||||
APPLET(tail, tail_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TAR
|
||||
APPLET(tar, tar_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TEE
|
||||
APPLET(tee, tee_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TELNET
|
||||
APPLET(telnet, telnet_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TEST
|
||||
APPLET(test, test_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TFTP
|
||||
APPLET(tftp, tftp_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TOUCH
|
||||
APPLET(touch, touch_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TR
|
||||
APPLET(tr, tr_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TRACEROUTE
|
||||
APPLET(traceroute, traceroute_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TRUE_FALSE
|
||||
APPLET(true, true_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_TTY
|
||||
APPLET(tty, tty_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_UMOUNT
|
||||
APPLET(umount, umount_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_UNAME
|
||||
APPLET(uname, uname_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_UNIQ
|
||||
APPLET(uniq, uniq_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_UNIX2DOS
|
||||
APPLET(unix2dos, dos2unix_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_UPDATE
|
||||
APPLET(update, update_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_UPTIME
|
||||
APPLET(uptime, uptime_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_USLEEP
|
||||
APPLET(usleep, usleep_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_UUDECODE
|
||||
APPLET(uudecode, uudecode_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_UUENCODE
|
||||
APPLET(uuencode, uuencode_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_VI
|
||||
APPLET(vi, vi_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_WATCHDOG
|
||||
APPLET(watchdog, watchdog_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_WC
|
||||
APPLET(wc, wc_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_WGET
|
||||
APPLET(wget, wget_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_WHICH
|
||||
APPLET(which, which_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_WHOAMI
|
||||
APPLET(whoami, whoami_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_XARGS
|
||||
APPLET(xargs, xargs_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_YES
|
||||
APPLET(yes, yes_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_GUNZIP
|
||||
APPLET(zcat, gunzip_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
|
||||
#if !defined(PROTOTYPES) && !defined(MAKE_USAGE)
|
||||
{ 0,NULL,0 }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,106 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Busybox main internal header file
|
||||
*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Based in part on code from sash, Copyright (c) 1999 by David I. Bell
|
||||
* Permission has been granted to redistribute this code under the GPL.
|
||||
*
|
||||
*/
|
||||
#ifndef _BB_INTERNAL_H_
|
||||
#define _BB_INTERNAL_H_ 1
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define BB_BANNER "BusyBox v" BB_VER " (" BB_BT ")"
|
||||
|
||||
#ifdef DMALLOC
|
||||
#include "dmalloc.h"
|
||||
#endif
|
||||
|
||||
#include <features.h>
|
||||
|
||||
|
||||
enum Location {
|
||||
_BB_DIR_ROOT = 0,
|
||||
_BB_DIR_BIN,
|
||||
_BB_DIR_SBIN,
|
||||
_BB_DIR_USR_BIN,
|
||||
_BB_DIR_USR_SBIN
|
||||
};
|
||||
|
||||
struct BB_applet {
|
||||
const char* name;
|
||||
int (*main)(int argc, char** argv);
|
||||
enum Location location;
|
||||
};
|
||||
/* From busybox.c */
|
||||
extern const struct BB_applet applets[];
|
||||
|
||||
/* Automagically pull in all the applet function prototypes and
|
||||
* applet usage strings. These are all of the form:
|
||||
* extern int foo_main(int argc, char **argv);
|
||||
* extern const char foo_usage[];
|
||||
* These are all autogenerated from the set of currently defined applets.
|
||||
*/
|
||||
#define PROTOTYPES
|
||||
#include "applets.h"
|
||||
#undef PROTOTYPES
|
||||
|
||||
#ifdef BB_FEATURE_BUFFERS_GO_ON_STACK
|
||||
#define RESERVE_BB_BUFFER(buffer,len) char buffer[len]
|
||||
#define RESERVE_BB_UBUFFER(buffer,len) unsigned char buffer[len]
|
||||
#define RELEASE_BB_BUFFER(buffer) ((void)0)
|
||||
#else
|
||||
#ifdef BB_FEATURE_BUFFERS_GO_IN_BSS
|
||||
#define RESERVE_BB_BUFFER(buffer,len) static char buffer[len]
|
||||
#define RESERVE_BB_UBUFFER(buffer,len) static unsigned char buffer[len]
|
||||
#define RELEASE_BB_BUFFER(buffer) ((void)0)
|
||||
#else
|
||||
#define RESERVE_BB_BUFFER(buffer,len) char *buffer=xmalloc(len)
|
||||
#define RESERVE_BB_UBUFFER(buffer,len) unsigned char *buffer=xmalloc(len)
|
||||
#define RELEASE_BB_BUFFER(buffer) free (buffer)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Bit map related macros -- libc5 doens't provide these... sigh. */
|
||||
#ifndef setbit
|
||||
#define NBBY CHAR_BIT
|
||||
#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
|
||||
#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
|
||||
#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
|
||||
#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
|
||||
#endif
|
||||
|
||||
#ifndef RB_POWER_OFF
|
||||
/* Stop system and switch power off if possible. */
|
||||
#define RB_POWER_OFF 0x4321fedc
|
||||
#endif
|
||||
|
||||
|
||||
/* Pull in the utility routines from libbb */
|
||||
#include "libbb/libbb.h"
|
||||
|
||||
|
||||
|
||||
#endif /* _BB_INTERNAL_H_ */
|
|
@ -1,326 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Busybox main internal header file
|
||||
*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Based in part on code from sash, Copyright (c) 1999 by David I. Bell
|
||||
* Permission has been granted to redistribute this code under the GPL.
|
||||
*
|
||||
*/
|
||||
#ifndef __LIBBB_H__
|
||||
#define __LIBBB_H__ 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
#ifdef DMALLOC
|
||||
#include "dmalloc.h"
|
||||
#endif
|
||||
|
||||
#include <features.h>
|
||||
|
||||
#ifndef _BB_INTERNAL_H_
|
||||
#include "../busybox.h"
|
||||
#endif
|
||||
|
||||
#if (__GNU_LIBRARY__ < 5) && (!defined __dietlibc__)
|
||||
/* libc5 doesn't define socklen_t */
|
||||
typedef unsigned int socklen_t;
|
||||
/* libc5 doesn't implement BSD 4.4 daemon() */
|
||||
extern int daemon (int nochdir, int noclose);
|
||||
/* libc5 doesn't implement strtok_r */
|
||||
char *strtok_r(char *s, const char *delim, char **ptrptr);
|
||||
#endif
|
||||
|
||||
/* Some useful definitions */
|
||||
#define FALSE ((int) 0)
|
||||
#define TRUE ((int) 1)
|
||||
#define SKIP ((int) 2)
|
||||
|
||||
/* for mtab.c */
|
||||
#define MTAB_GETMOUNTPT '1'
|
||||
#define MTAB_GETDEVICE '2'
|
||||
|
||||
#define BUF_SIZE 8192
|
||||
#define EXPAND_ALLOC 1024
|
||||
|
||||
static inline int is_decimal(int ch) { return ((ch >= '0') && (ch <= '9')); }
|
||||
static inline int is_octal(int ch) { return ((ch >= '0') && (ch <= '7')); }
|
||||
|
||||
/* Macros for min/max. */
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
extern void show_usage(void) __attribute__ ((noreturn));
|
||||
extern void error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
extern void error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
|
||||
extern void perror_msg(const char *s, ...);
|
||||
extern void perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn));
|
||||
extern void vherror_msg(const char *s, va_list p);
|
||||
extern void herror_msg(const char *s, ...);
|
||||
extern void herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn));
|
||||
|
||||
/* These two are used internally -- you shouldn't need to use them */
|
||||
extern void verror_msg(const char *s, va_list p);
|
||||
extern void vperror_msg(const char *s, va_list p);
|
||||
|
||||
const char *mode_string(int mode);
|
||||
const char *time_string(time_t timeVal);
|
||||
int is_directory(const char *name, int followLinks, struct stat *statBuf);
|
||||
int isDevice(const char *name);
|
||||
|
||||
int remove_file(const char *path, int flags);
|
||||
int copy_file(const char *source, const char *dest, int flags);
|
||||
int copy_file_chunk(FILE *src_file, FILE *dst_file, unsigned long long chunksize);
|
||||
char *buildName(const char *dirName, const char *fileName);
|
||||
int makeString(int argc, const char **argv, char *buf, int bufLen);
|
||||
char *getChunk(int size);
|
||||
char *chunkstrdup(const char *str);
|
||||
void freeChunks(void);
|
||||
ssize_t safe_read(int fd, void *buf, size_t count);
|
||||
int full_write(int fd, const char *buf, int len);
|
||||
int full_read(int fd, char *buf, int len);
|
||||
int recursive_action(const char *fileName, int recurse, int followLinks, int depthFirst,
|
||||
int (*fileAction) (const char *fileName, struct stat* statbuf, void* userData),
|
||||
int (*dirAction) (const char *fileName, struct stat* statbuf, void* userData),
|
||||
void* userData);
|
||||
|
||||
extern int parse_mode( const char* s, mode_t* theMode);
|
||||
|
||||
extern int get_kernel_revision(void);
|
||||
|
||||
extern int get_console_fd(char* tty_name);
|
||||
extern struct mntent *find_mount_point(const char *name, const char *table);
|
||||
extern void write_mtab(char* blockDevice, char* directory,
|
||||
char* filesystemType, long flags, char* string_flags);
|
||||
extern void erase_mtab(const char * name);
|
||||
extern long atoi_w_units (const char *cp);
|
||||
extern pid_t* find_pid_by_name( char* pidName);
|
||||
extern char *find_real_root_device_name(const char* name);
|
||||
extern char *get_line_from_file(FILE *file);
|
||||
extern void print_file(FILE *file);
|
||||
extern int copyfd(int fd1, int fd2);
|
||||
extern int print_file_by_name(char *filename);
|
||||
extern char process_escape_sequence(const char **ptr);
|
||||
extern char *get_last_path_component(char *path);
|
||||
extern FILE *wfopen(const char *path, const char *mode);
|
||||
extern FILE *xfopen(const char *path, const char *mode);
|
||||
extern void chomp(char *s);
|
||||
extern void trim(char *s);
|
||||
extern struct BB_applet *find_applet_by_name(const char *name);
|
||||
void run_applet_by_name(const char *name, int argc, char **argv);
|
||||
|
||||
#ifndef DMALLOC
|
||||
extern void *xmalloc (size_t size);
|
||||
extern void *xrealloc(void *old, size_t size);
|
||||
extern void *xcalloc(size_t nmemb, size_t size);
|
||||
extern char *xstrdup (const char *s);
|
||||
#endif
|
||||
extern char *xstrndup (const char *s, int n);
|
||||
extern char * safe_strncpy(char *dst, const char *src, size_t size);
|
||||
|
||||
struct suffix_mult {
|
||||
const char *suffix;
|
||||
int mult;
|
||||
};
|
||||
|
||||
extern unsigned long parse_number(const char *numstr,
|
||||
const struct suffix_mult *suffixes);
|
||||
|
||||
|
||||
/* These parse entries in /etc/passwd and /etc/group. This is desirable
|
||||
* for BusyBox since we want to avoid using the glibc NSS stuff, which
|
||||
* increases target size and is often not needed embedded systems. */
|
||||
extern long my_getpwnam(const char *name);
|
||||
extern long my_getgrnam(const char *name);
|
||||
extern void my_getpwuid(char *name, long uid);
|
||||
extern void my_getgrgid(char *group, long gid);
|
||||
extern long my_getpwnamegid(const char *name);
|
||||
|
||||
extern int device_open(char *device, int mode);
|
||||
|
||||
extern int del_loop(const char *device);
|
||||
extern int set_loop(const char *device, const char *file, int offset, int *loopro);
|
||||
extern char *find_unused_loop_device (void);
|
||||
|
||||
|
||||
#if (__GLIBC__ < 2)
|
||||
extern int vdprintf(int d, const char *format, va_list ap);
|
||||
#endif
|
||||
|
||||
int nfsmount(const char *spec, const char *node, int *flags,
|
||||
char **extra_opts, char **mount_opts, int running_bg);
|
||||
|
||||
void syslog_msg_with_name(const char *name, int facility, int pri, const char *msg);
|
||||
void syslog_msg(int facility, int pri, const char *msg);
|
||||
|
||||
/* Include our own copy of struct sysinfo to avoid binary compatability
|
||||
* problems with Linux 2.4, which changed things. Grumble, grumble. */
|
||||
struct sysinfo {
|
||||
long uptime; /* Seconds since boot */
|
||||
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
|
||||
unsigned long totalram; /* Total usable main memory size */
|
||||
unsigned long freeram; /* Available memory size */
|
||||
unsigned long sharedram; /* Amount of shared memory */
|
||||
unsigned long bufferram; /* Memory used by buffers */
|
||||
unsigned long totalswap; /* Total swap space size */
|
||||
unsigned long freeswap; /* swap space still available */
|
||||
unsigned short procs; /* Number of current processes */
|
||||
unsigned short pad; /* Padding needed for m68k */
|
||||
unsigned long totalhigh; /* Total high memory size */
|
||||
unsigned long freehigh; /* Available high memory size */
|
||||
unsigned int mem_unit; /* Memory unit size in bytes */
|
||||
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
|
||||
};
|
||||
extern int sysinfo (struct sysinfo* info);
|
||||
|
||||
enum {
|
||||
KILOBYTE = 1024,
|
||||
MEGABYTE = (KILOBYTE*1024),
|
||||
GIGABYTE = (MEGABYTE*1024)
|
||||
};
|
||||
const char *make_human_readable_str(unsigned long size, unsigned long block_size, unsigned long display_unit);
|
||||
|
||||
int ask_confirmation(void);
|
||||
int klogctl(int type, char * b, int len);
|
||||
|
||||
char *xgetcwd(char *cwd);
|
||||
char *xreadlink(const char *path);
|
||||
char *concat_path_file(const char *path, const char *filename);
|
||||
char *last_char_is(const char *s, int c);
|
||||
|
||||
extern long arith (const char *startbuf, int *errcode);
|
||||
|
||||
typedef struct file_headers_s {
|
||||
char *name;
|
||||
char *link_name;
|
||||
off_t size;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
mode_t mode;
|
||||
time_t mtime;
|
||||
dev_t device;
|
||||
} file_header_t;
|
||||
file_header_t *get_header_ar(FILE *in_file);
|
||||
file_header_t *get_header_cpio(FILE *src_stream);
|
||||
file_header_t *get_header_tar(FILE *tar_stream);
|
||||
|
||||
enum extract_functions_e {
|
||||
extract_verbose_list = 1,
|
||||
extract_list = 2,
|
||||
extract_one_to_buffer = 4,
|
||||
extract_to_stdout = 8,
|
||||
extract_all_to_fs = 16,
|
||||
extract_preserve_date = 32,
|
||||
extract_data_tar_gz = 64,
|
||||
extract_control_tar_gz = 128,
|
||||
extract_unzip_only = 256,
|
||||
extract_unconditional = 512,
|
||||
extract_create_leading_dirs = 1024,
|
||||
extract_quiet = 2048,
|
||||
extract_exclude_list = 4096
|
||||
};
|
||||
char *unarchive(FILE *src_stream, FILE *out_stream, file_header_t *(*get_header)(FILE *),
|
||||
const int extract_function, const char *prefix, char **extract_names);
|
||||
char *deb_extract(const char *package_filename, FILE *out_stream, const int extract_function,
|
||||
const char *prefix, const char *filename);
|
||||
int read_package_field(const char *package_buffer, char **field_name, char **field_value);
|
||||
char *fgets_str(FILE *file, const char *terminating_string);
|
||||
|
||||
extern int unzip(FILE *l_in_file, FILE *l_out_file);
|
||||
extern void gz_close(int gunzip_pid);
|
||||
extern FILE *gz_open(FILE *compressed_file, int *pid);
|
||||
|
||||
extern struct hostent *xgethostbyname(const char *name);
|
||||
extern int create_icmp_socket(void);
|
||||
|
||||
char *dirname (char *path);
|
||||
|
||||
int make_directory (char *path, long mode, int flags);
|
||||
|
||||
const char *u_signal_names(const char *str_sig, int *signo, int startnum);
|
||||
char *simplify_path(const char *path);
|
||||
|
||||
#define CT_AUTO 0
|
||||
#define CT_UNIX2DOS 1
|
||||
#define CT_DOS2UNIX 2
|
||||
/* extern int convert(char *fn, int ConvType); */
|
||||
|
||||
enum {
|
||||
FILEUTILS_PRESERVE_STATUS = 1,
|
||||
FILEUTILS_PRESERVE_SYMLINKS = 2,
|
||||
FILEUTILS_RECUR = 4,
|
||||
FILEUTILS_FORCE = 8,
|
||||
FILEUTILS_INTERACTIVE = 16
|
||||
};
|
||||
|
||||
extern const char *applet_name;
|
||||
extern const char * const full_version;
|
||||
extern const char * const name_too_long;
|
||||
extern const char * const omitting_directory;
|
||||
extern const char * const not_a_directory;
|
||||
extern const char * const memory_exhausted;
|
||||
extern const char * const invalid_date;
|
||||
extern const char * const invalid_option;
|
||||
extern const char * const io_error;
|
||||
extern const char * const dash_dash_help;
|
||||
extern const char * const write_error;
|
||||
extern const char * const too_few_args;
|
||||
extern const char * const name_longer_than_foo;
|
||||
extern const char * const unknown;
|
||||
extern const char * const can_not_create_raw_socket;
|
||||
|
||||
#ifdef BB_FEATURE_DEVFS
|
||||
# define CURRENT_VC "/dev/vc/0"
|
||||
# define VC_1 "/dev/vc/1"
|
||||
# define VC_2 "/dev/vc/2"
|
||||
# define VC_3 "/dev/vc/3"
|
||||
# define VC_4 "/dev/vc/4"
|
||||
# define VC_5 "/dev/vc/5"
|
||||
# define SC_0 "/dev/tts/0"
|
||||
# define SC_1 "/dev/tts/1"
|
||||
# define VC_FORMAT "/dev/vc/%d"
|
||||
# define SC_FORMAT "/dev/tts/%d"
|
||||
#else
|
||||
# define CURRENT_VC "/dev/tty0"
|
||||
# define VC_1 "/dev/tty1"
|
||||
# define VC_2 "/dev/tty2"
|
||||
# define VC_3 "/dev/tty3"
|
||||
# define VC_4 "/dev/tty4"
|
||||
# define VC_5 "/dev/tty5"
|
||||
# define SC_0 "/dev/ttyS0"
|
||||
# define SC_1 "/dev/ttyS1"
|
||||
# define VC_FORMAT "/dev/tty%d"
|
||||
# define SC_FORMAT "/dev/ttyS%d"
|
||||
#endif
|
||||
|
||||
/* The following devices are the same on devfs and non-devfs systems. */
|
||||
#define CURRENT_TTY "/dev/tty"
|
||||
#define CONSOLE_DEV "/dev/console"
|
||||
|
||||
#endif /* __LIBBB_H__ */
|
|
@ -1,41 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini halt implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
|
||||
*
|
||||
* 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 "busybox.h"
|
||||
#include <signal.h>
|
||||
|
||||
extern int halt_main(int argc, char **argv)
|
||||
{
|
||||
#ifdef BB_FEATURE_LINUXRC
|
||||
/* don't assume init's pid == 1 */
|
||||
pid_t *pid = find_pid_by_name("init");
|
||||
if (!pid || *pid<=0) {
|
||||
pid = find_pid_by_name("linuxrc");
|
||||
if (!pid || *pid<=0)
|
||||
error_msg_and_die("no process killed");
|
||||
}
|
||||
return(kill(*pid, SIGUSR1));
|
||||
#else
|
||||
return(kill(1, SIGUSR1));
|
||||
#endif
|
||||
}
|
1031
busybox/init/init.c
|
@ -1,49 +0,0 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini reboot implementation for busybox
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
|
||||
*
|
||||
* 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 "busybox.h"
|
||||
#include <signal.h>
|
||||
|
||||
extern int reboot_main(int argc, char **argv)
|
||||
{
|
||||
#ifdef BB_FEATURE_LINUXRC
|
||||
/* don't assume init's pid == 1 */
|
||||
pid_t *pid = find_pid_by_name("init");
|
||||
if (!pid || *pid<=0) {
|
||||
pid = find_pid_by_name("linuxrc");
|
||||
if (!pid || *pid<=0)
|
||||
error_msg_and_die("no process killed");
|
||||
}
|
||||
return(kill(*pid, SIGTERM));
|
||||
#else
|
||||
return(kill(1, SIGTERM));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "linux"
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
End:
|
||||
*/
|