summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoronefang2005-03-12 13:06:30 +0000
committeronefang2005-03-12 13:06:30 +0000
commit14ac0f3a54432f3fd0844a6561fe7755ae7bf056 (patch)
tree45a3da4888e4467d83f5e44f30970ce5305f646c
parentinitial checkin (diff)
downloadurunlevel-14ac0f3a54432f3fd0844a6561fe7755ae7bf056.zip
urunlevel-14ac0f3a54432f3fd0844a6561fe7755ae7bf056.tar.gz
urunlevel-14ac0f3a54432f3fd0844a6561fe7755ae7bf056.tar.bz2
urunlevel-14ac0f3a54432f3fd0844a6561fe7755ae7bf056.tar.xz
Initial import
Diffstat (limited to '')
-rw-r--r--urunlevel/archival/gzip.c2558
-rw-r--r--urunlevel/include/applets.h752
-rw-r--r--urunlevel/include/usage.h3077
-rw-r--r--urunlevel/my_linux/Config.in32
-rw-r--r--urunlevel/my_linux/Makefile32
-rw-r--r--urunlevel/my_linux/Makefile.in40
-rw-r--r--urunlevel/my_linux/Trinux/README346
-rwxr-xr-xurunlevel/my_linux/Trinux/chkfixed99
-rwxr-xr-xurunlevel/my_linux/Trinux/fmount2
-rwxr-xr-xurunlevel/my_linux/Trinux/fumount3
-rwxr-xr-xurunlevel/my_linux/Trinux/gethome61
-rwxr-xr-xurunlevel/my_linux/Trinux/getkpkg9
-rwxr-xr-xurunlevel/my_linux/Trinux/getpkg171
-rwxr-xr-xurunlevel/my_linux/Trinux/hwinfo23
-rwxr-xr-xurunlevel/my_linux/Trinux/killmod8
-rwxr-xr-xurunlevel/my_linux/Trinux/linuxrc1261
-rwxr-xr-xurunlevel/my_linux/Trinux/loadmodules30
-rwxr-xr-xurunlevel/my_linux/Trinux/net-config18
-rwxr-xr-xurunlevel/my_linux/Trinux/net-start141
-rwxr-xr-xurunlevel/my_linux/Trinux/net-stop11
-rwxr-xr-xurunlevel/my_linux/Trinux/pkgadd62
-rwxr-xr-xurunlevel/my_linux/Trinux/pkglist12
-rwxr-xr-xurunlevel/my_linux/Trinux/quit10
-rwxr-xr-xurunlevel/my_linux/Trinux/rmpkg24
-rwxr-xr-xurunlevel/my_linux/Trinux/save-config38
-rwxr-xr-xurunlevel/my_linux/Trinux/savecfg38
-rwxr-xr-xurunlevel/my_linux/Trinux/savehome79
-rwxr-xr-xurunlevel/my_linux/Trinux/update62
-rw-r--r--urunlevel/my_linux/bootrc0
-rw-r--r--urunlevel/my_linux/getpkg.c240
-rw-r--r--urunlevel/my_linux/inittab17
-rw-r--r--urunlevel/my_linux/lib_init_d.h183
-rw-r--r--urunlevel/my_linux/linuxrc.c829
-rw-r--r--urunlevel/my_linux/man.c41
-rw-r--r--urunlevel/my_linux/mkrootfs.c104
-rw-r--r--urunlevel/my_linux/my_linux.h27
-rwxr-xr-xurunlevel/my_linux/rcS2
-rw-r--r--urunlevel/my_linux/rcS.c47
-rwxr-xr-xurunlevel/my_linux/shownet8
-rwxr-xr-xurunlevel/my_linux/vt_manager22
-rw-r--r--urunlevel/networking/udhcp/dhcpc.h38
-rw-r--r--urunlevel/networking/udhcp/libbb_udhcp.h55
-rw-r--r--urunlevel/runlevel/Config.in110
-rw-r--r--urunlevel/runlevel/Makefile32
-rw-r--r--urunlevel/runlevel/Makefile.in75
-rw-r--r--urunlevel/runlevel/README3
-rw-r--r--urunlevel/runlevel/TODO55
-rw-r--r--urunlevel/runlevel/boot_named.c57
-rw-r--r--urunlevel/runlevel/boot_portmap.c78
-rw-r--r--urunlevel/runlevel/boot_syslog.c79
-rw-r--r--urunlevel/runlevel/boot_time.c88
-rwxr-xr-xurunlevel/runlevel/default.script2
-rw-r--r--urunlevel/runlevel/init-functions30
-rw-r--r--urunlevel/runlevel/inittab12
-rw-r--r--urunlevel/runlevel/install_initd.c48
-rw-r--r--urunlevel/runlevel/killproc.c162
-rw-r--r--urunlevel/runlevel/lib_init_d.c425
-rw-r--r--urunlevel/runlevel/lib_init_d.h202
-rw-r--r--urunlevel/runlevel/local_fs.c199
-rw-r--r--urunlevel/runlevel/log_failure_msg.c54
-rw-r--r--urunlevel/runlevel/log_success_msg.c54
-rw-r--r--urunlevel/runlevel/log_warning_msg.c54
-rw-r--r--urunlevel/runlevel/network.c146
-rw-r--r--urunlevel/runlevel/pidofproc.c192
-rw-r--r--urunlevel/runlevel/rc.c1271
-rw-r--r--urunlevel/runlevel/remote_fs.c83
-rw-r--r--urunlevel/runlevel/remove_initd.c38
-rwxr-xr-xurunlevel/runlevel/skeleton282
-rw-r--r--urunlevel/runlevel/start_daemon.c153
-rw-r--r--urunlevel/runlevel/udhcpc_script.c191
-rw-r--r--urunlevel/sysdeps/linux/Config.in296
71 files changed, 15083 insertions, 0 deletions
diff --git a/urunlevel/archival/gzip.c b/urunlevel/archival/gzip.c
new file mode 100644
index 0000000..1092480
--- /dev/null
+++ b/urunlevel/archival/gzip.c
@@ -0,0 +1,2558 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Gzip implementation for busybox
4 *
5 * Based on GNU gzip Copyright (C) 1992-1993 Jean-loup Gailly.
6 *
7 * Originally adjusted for busybox by Charles P. Wright <cpw@unix.asb.com>
8 * "this is a stripped down version of gzip I put into busybox, it does
9 * only standard in to standard out with -9 compression. It also requires
10 * the zcat module for some important functions."
11 *
12 * Adjusted further by Erik Andersen <andersen@codepoet.org> to support
13 * files as well as stdin/stdout, and to generally behave itself wrt
14 * command line handling.
15 *
16 * Adjusted further by David Seikel <won_fang@yahoo.cam.au> to support
17 * just storing the file.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 *
33 */
34
35/* These defines are very important for BusyBox. Without these,
36 * huge chunks of ram are pre-allocated making the BusyBox bss
37 * size Freaking Huge(tm), which is a bad thing.*/
38#define SMALL_MEM
39#define DYN_ALLOC
40
41#include <stdlib.h>
42#include <stdio.h>
43#include <string.h>
44#include <unistd.h>
45#include <errno.h>
46#include <sys/types.h>
47#include <signal.h>
48#include <utime.h>
49#include <ctype.h>
50#include <sys/types.h>
51#include <unistd.h>
52#include <dirent.h>
53#include <fcntl.h>
54#include <time.h>
55#include "busybox.h"
56
57#define memzero(s, n) memset ((void *)(s), 0, (n))
58
59#ifndef RETSIGTYPE
60# define RETSIGTYPE void
61#endif
62
63typedef unsigned char uch;
64typedef unsigned short ush;
65typedef unsigned long ulg;
66
67/* Return codes from gzip */
68#define OK 0
69#define ERROR 1
70#define WARNING 2
71
72/* Compression methods (see algorithm.doc) */
73/* Only STORED and DEFLATED are supported by this BusyBox module */
74#define STORED 0
75/* methods 4 to 7 reserved */
76#define DEFLATED 8
77
78int just_store = 0;
79
80/* To save memory for 16 bit systems, some arrays are overlaid between
81 * the various modules:
82 * deflate: prev+head window d_buf l_buf outbuf
83 * unlzw: tab_prefix tab_suffix stack inbuf outbuf
84 * For compression, input is done in window[]. For decompression, output
85 * is done in window except for unlzw.
86 */
87
88#ifndef INBUFSIZ
89# ifdef SMALL_MEM
90# define INBUFSIZ 0x2000 /* input buffer size */
91# else
92# define INBUFSIZ 0x8000 /* input buffer size */
93# endif
94#endif
95#define INBUF_EXTRA 64 /* required by unlzw() */
96
97#ifndef OUTBUFSIZ
98# ifdef SMALL_MEM
99# define OUTBUFSIZ 8192 /* output buffer size */
100# else
101# define OUTBUFSIZ 16384 /* output buffer size */
102# endif
103#endif
104#define OUTBUF_EXTRA 2048 /* required by unlzw() */
105
106#ifndef DIST_BUFSIZE
107# ifdef SMALL_MEM
108# define DIST_BUFSIZE 0x2000 /* buffer for distances, see trees.c */
109# else
110# define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */
111# endif
112#endif
113
114#ifdef DYN_ALLOC
115# define DECLARE(type, array, size) static type * array
116# define ALLOC(type, array, size) { \
117 array = (type*)xcalloc((size_t)(((size)+1L)/2), 2*sizeof(type)); \
118 }
119# define FREE(array) {free(array), array=NULL;}
120#else
121# define DECLARE(type, array, size) static type array[size]
122# define ALLOC(type, array, size)
123# define FREE(array)
124#endif
125
126#define tab_suffix window
127#define tab_prefix prev /* hash link (see deflate.c) */
128#define head (prev+WSIZE) /* hash head (see deflate.c) */
129
130static long bytes_in; /* number of input bytes */
131
132#define isize bytes_in
133/* for compatibility with old zip sources (to be cleaned) */
134
135typedef int file_t; /* Do not use stdio */
136
137#define NO_FILE (-1) /* in memory compression */
138
139
140#define PACK_MAGIC "\037\036" /* Magic header for packed files */
141#define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */
142#define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */
143#define LZH_MAGIC "\037\240" /* Magic header for SCO LZH Compress files */
144#define PKZIP_MAGIC "\120\113\003\004" /* Magic header for pkzip files */
145
146/* gzip flag byte */
147#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
148#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
149#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
150#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
151#define COMMENT 0x10 /* bit 4 set: file comment present */
152#define RESERVED 0xC0 /* bit 6,7: reserved */
153
154/* internal file attribute */
155#define UNKNOWN 0xffff
156#define BINARY 0
157#define ASCII 1
158
159#ifndef WSIZE
160# define WSIZE 0x8000 /* window size--must be a power of two, and */
161#endif /* at least 32K for zip's deflate method */
162
163#define MIN_MATCH 3
164#define MAX_MATCH 258
165/* The minimum and maximum match lengths */
166
167#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
168/* Minimum amount of lookahead, except at the end of the input file.
169 * See deflate.c for comments about the MIN_MATCH+1.
170 */
171
172#define MAX_DIST (WSIZE-MIN_LOOKAHEAD)
173/* In order to simplify the code, particularly on 16 bit machines, match
174 * distances are limited to MAX_DIST instead of WSIZE.
175 */
176
177/* put_byte is used for the compressed output */
178#define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\
179 flush_outbuf();}
180
181
182/* Output a 32 bit value to the bit stream, lsb first */
183#if 0
184#define put_long(n) { \
185 put_short((n) & 0xffff); \
186 put_short(((ulg)(n)) >> 16); \
187}
188#endif
189
190#define seekable() 0 /* force sequential output */
191#define translate_eol 0 /* no option -a yet */
192
193/* Diagnostic functions */
194#ifdef DEBUG
195# define Assert(cond,msg) {if(!(cond)) bb_error_msg(msg);}
196# define Trace(x) fprintf x
197# define Tracev(x) {if (verbose) fprintf x ;}
198# define Tracevv(x) {if (verbose>1) fprintf x ;}
199# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
200# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
201#else
202# define Assert(cond,msg)
203# define Trace(x)
204# define Tracev(x)
205# define Tracevv(x)
206# define Tracec(c,x)
207# define Tracecv(c,x)
208#endif
209
210#define WARN(msg) {if (!quiet) fprintf msg ; \
211 if (exit_code == OK) exit_code = WARNING;}
212
213#ifndef MAX_PATH_LEN
214# define MAX_PATH_LEN 1024 /* max pathname length */
215#endif
216
217
218 /* from zip.c: */
219static int zip(int in, int out);
220static int file_read(char *buf, unsigned size);
221
222 /* from gzip.c */
223static RETSIGTYPE abort_gzip(void);
224
225 /* from deflate.c */
226static void lm_init(ush * flags);
227static ulg deflate(void);
228
229 /* from trees.c */
230static void ct_init(ush * attr, int *methodp);
231static int ct_tally(int dist, int lc);
232static ulg flush_block(char *buf, ulg stored_len, int eof);
233
234 /* from bits.c */
235static void bi_init(file_t zipfile);
236static void send_bits(int value, int length);
237static unsigned bi_reverse(unsigned value, int length);
238static void bi_windup(void);
239static void copy_block(char *buf, unsigned len, int header);
240static int (*read_buf) (char *buf, unsigned size);
241
242 /* from util.c: */
243static void flush_outbuf(void);
244
245/* lzw.h -- define the lzw functions.
246 * Copyright (C) 1992-1993 Jean-loup Gailly.
247 * This is free software; you can redistribute it and/or modify it under the
248 * terms of the GNU General Public License, see the file COPYING.
249 */
250
251#if !defined(OF) && defined(lint)
252# include "gzip.h"
253#endif
254
255#ifndef BITS
256# define BITS 16
257#endif
258#define INIT_BITS 9 /* Initial number of bits per code */
259
260#define BIT_MASK 0x1f /* Mask for 'number of compression bits' */
261/* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free.
262 * It's a pity that old uncompress does not check bit 0x20. That makes
263 * extension of the format actually undesirable because old compress
264 * would just crash on the new format instead of giving a meaningful
265 * error message. It does check the number of bits, but it's more
266 * helpful to say "unsupported format, get a new version" than
267 * "can only handle 16 bits".
268 */
269
270/* tailor.h -- target dependent definitions
271 * Copyright (C) 1992-1993 Jean-loup Gailly.
272 * This is free software; you can redistribute it and/or modify it under the
273 * terms of the GNU General Public License, see the file COPYING.
274 */
275
276/* The target dependent definitions should be defined here only.
277 * The target dependent functions should be defined in tailor.c.
278 */
279
280
281 /* Common defaults */
282
283#ifndef OS_CODE
284# define OS_CODE 0x03 /* assume Unix */
285#endif
286
287#ifndef PATH_SEP
288# define PATH_SEP '/'
289#endif
290
291#ifndef OPTIONS_VAR
292# define OPTIONS_VAR "GZIP"
293#endif
294
295#ifndef Z_SUFFIX
296# define Z_SUFFIX ".gz"
297#endif
298
299#ifdef MAX_EXT_CHARS
300# define MAX_SUFFIX MAX_EXT_CHARS
301#else
302# define MAX_SUFFIX 30
303#endif
304
305 /* global buffers */
306
307DECLARE(uch, inbuf, INBUFSIZ + INBUF_EXTRA);
308DECLARE(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA);
309DECLARE(ush, d_buf, DIST_BUFSIZE);
310DECLARE(uch, window, 2L * WSIZE);
311DECLARE(ush, tab_prefix, 1L << BITS);
312
313static int foreground; /* set if program run in foreground */
314static int method = DEFLATED; /* compression method */
315static int exit_code = OK; /* program exit code */
316static int part_nb; /* number of parts in .gz file */
317static long time_stamp; /* original time stamp (modification time) */
318static long ifile_size; /* input file size, -1 for devices (debug only) */
319static char z_suffix[MAX_SUFFIX + 1]; /* default suffix (can be set with --suffix) */
320static int z_len; /* strlen(z_suffix) */
321
322static int ifd; /* input file descriptor */
323static int ofd; /* output file descriptor */
324static unsigned insize; /* valid bytes in inbuf */
325static unsigned outcnt; /* bytes in output buffer */
326
327
328/* Output a 16 bit value, lsb first */
329static void put_short(ush w)
330{
331 if (outcnt < OUTBUFSIZ - 2) {
332 outbuf[outcnt++] = (uch) ((w) & 0xff);
333 outbuf[outcnt++] = (uch) ((ush) (w) >> 8);
334 } else {
335 put_byte((uch) ((w) & 0xff));
336 put_byte((uch) ((ush) (w) >> 8));
337 }
338}
339
340/* ========================================================================
341 * Signal and error handler.
342 */
343static void abort_gzip()
344{
345 exit(ERROR);
346}
347
348/* ===========================================================================
349 * Clear input and output buffers
350 */
351static void clear_bufs(void)
352{
353 outcnt = 0;
354 insize = 0;
355 bytes_in = 0L;
356}
357
358static void write_bb_error_msg(void)
359{
360 fputc('\n', stderr);
361 bb_perror_nomsg();
362 abort_gzip();
363}
364
365/* ===========================================================================
366 * Does the same as write(), but also handles partial pipe writes and checks
367 * for error return.
368 */
369static void write_buf(int fd, void *buf, unsigned cnt)
370{
371 unsigned n;
372
373 while ((n = write(fd, buf, cnt)) != cnt) {
374 if (n == (unsigned) (-1)) {
375 write_bb_error_msg();
376 }
377 cnt -= n;
378 buf = (void *) ((char *) buf + n);
379 }
380}
381
382/* ===========================================================================
383 * Run a set of bytes through the crc shift register. If s is a NULL
384 * pointer, then initialize the crc shift register contents instead.
385 * Return the current crc in either case.
386 */
387static ulg updcrc(uch * s, unsigned n)
388{
389 static ulg crc = (ulg) 0xffffffffL; /* shift register contents */
390 register ulg c; /* temporary variable */
391 static unsigned long crc_32_tab[256];
392
393 if (crc_32_tab[1] == 0x00000000L) {
394 unsigned long csr; /* crc shift register */
395 const unsigned long e = 0xedb88320L; /* polynomial exclusive-or pattern */
396 int i; /* counter for all possible eight bit values */
397 int k; /* byte being shifted into crc apparatus */
398
399 /* Compute table of CRC's. */
400 for (i = 1; i < 256; i++) {
401 csr = i;
402 /* The idea to initialize the register with the byte instead of
403 * zero was stolen from Haruhiko Okumura's ar002
404 */
405 for (k = 8; k; k--)
406 csr = csr & 1 ? (csr >> 1) ^ e : csr >> 1;
407 crc_32_tab[i] = csr;
408 }
409 }
410
411 if (s == NULL) {
412 c = 0xffffffffL;
413 } else {
414 c = crc;
415 if (n)
416 do {
417 c = crc_32_tab[((int) c ^ (*s++)) & 0xff] ^ (c >> 8);
418 } while (--n);
419 }
420 crc = c;
421 return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
422}
423
424/* bits.c -- output variable-length bit strings
425 * Copyright (C) 1992-1993 Jean-loup Gailly
426 * This is free software; you can redistribute it and/or modify it under the
427 * terms of the GNU General Public License, see the file COPYING.
428 */
429
430
431/*
432 * PURPOSE
433 *
434 * Output variable-length bit strings. Compression can be done
435 * to a file or to memory. (The latter is not supported in this version.)
436 *
437 * DISCUSSION
438 *
439 * The PKZIP "deflate" file format interprets compressed file data
440 * as a sequence of bits. Multi-bit strings in the file may cross
441 * byte boundaries without restriction.
442 *
443 * The first bit of each byte is the low-order bit.
444 *
445 * The routines in this file allow a variable-length bit value to
446 * be output right-to-left (useful for literal values). For
447 * left-to-right output (useful for code strings from the tree routines),
448 * the bits must have been reversed first with bi_reverse().
449 *
450 * For in-memory compression, the compressed bit stream goes directly
451 * into the requested output buffer. The input data is read in blocks
452 * by the mem_read() function. The buffer is limited to 64K on 16 bit
453 * machines.
454 *
455 * INTERFACE
456 *
457 * void bi_init (FILE *zipfile)
458 * Initialize the bit string routines.
459 *
460 * void send_bits (int value, int length)
461 * Write out a bit string, taking the source bits right to
462 * left.
463 *
464 * int bi_reverse (int value, int length)
465 * Reverse the bits of a bit string, taking the source bits left to
466 * right and emitting them right to left.
467 *
468 * void bi_windup (void)
469 * Write out any remaining bits in an incomplete byte.
470 *
471 * void copy_block(char *buf, unsigned len, int header)
472 * Copy a stored block to the zip file, storing first the length and
473 * its one's complement if requested.
474 *
475 */
476
477/* ===========================================================================
478 * Local data used by the "bit string" routines.
479 */
480
481static file_t zfile; /* output gzip file */
482
483static unsigned short bi_buf;
484
485/* Output buffer. bits are inserted starting at the bottom (least significant
486 * bits).
487 */
488
489#define Buf_size (8 * 2*sizeof(char))
490/* Number of bits used within bi_buf. (bi_buf might be implemented on
491 * more than 16 bits on some systems.)
492 */
493
494static int bi_valid;
495
496/* Current input function. Set to mem_read for in-memory compression */
497
498#ifdef DEBUG
499ulg bits_sent; /* bit length of the compressed data */
500#endif
501
502/* ===========================================================================
503 * Initialize the bit string routines.
504 */
505static void bi_init(file_t zipfile)
506{
507 zfile = zipfile;
508 bi_buf = 0;
509 bi_valid = 0;
510#ifdef DEBUG
511 bits_sent = 0L;
512#endif
513
514 /* Set the defaults for file compression. They are set by memcompress
515 * for in-memory compression.
516 */
517 if (zfile != NO_FILE) {
518 read_buf = file_read;
519 }
520}
521
522/* ===========================================================================
523 * Send a value on a given number of bits.
524 * IN assertion: length <= 16 and value fits in length bits.
525 */
526static void send_bits(int value, int length)
527{
528#ifdef DEBUG
529 Tracev((stderr, " l %2d v %4x ", length, value));
530 Assert(length > 0 && length <= 15, "invalid length");
531 bits_sent += (ulg) length;
532#endif
533 /* If not enough room in bi_buf, use (valid) bits from bi_buf and
534 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
535 * unused bits in value.
536 */
537 if (bi_valid > (int) Buf_size - length) {
538 bi_buf |= (value << bi_valid);
539 put_short(bi_buf);
540 bi_buf = (ush) value >> (Buf_size - bi_valid);
541 bi_valid += length - Buf_size;
542 } else {
543 bi_buf |= value << bi_valid;
544 bi_valid += length;
545 }
546}
547
548/* ===========================================================================
549 * Reverse the first len bits of a code, using straightforward code (a faster
550 * method would use a table)
551 * IN assertion: 1 <= len <= 15
552 */
553static unsigned bi_reverse(unsigned code, int len)
554{
555 register unsigned res = 0;
556
557 do {
558 res |= code & 1;
559 code >>= 1, res <<= 1;
560 } while (--len > 0);
561 return res >> 1;
562}
563
564/* ===========================================================================
565 * Write out any remaining bits in an incomplete byte.
566 */
567static void bi_windup()
568{
569 if (bi_valid > 8) {
570 put_short(bi_buf);
571 } else if (bi_valid > 0) {
572 put_byte(bi_buf);
573 }
574 bi_buf = 0;
575 bi_valid = 0;
576#ifdef DEBUG
577 bits_sent = (bits_sent + 7) & ~7;
578#endif
579}
580
581/* ===========================================================================
582 * Copy a stored block to the zip file, storing first the length and its
583 * one's complement if requested.
584 */
585static void copy_block(char *buf, unsigned len, int header)
586{
587 bi_windup(); /* align on byte boundary */
588
589 if (header) {
590 put_short((ush) len);
591 put_short((ush) ~ len);
592#ifdef DEBUG
593 bits_sent += 2 * 16;
594#endif
595 }
596#ifdef DEBUG
597 bits_sent += (ulg) len << 3;
598#endif
599 while (len--) {
600 put_byte(*buf++);
601 }
602}
603
604/* deflate.c -- compress data using the deflation algorithm
605 * Copyright (C) 1992-1993 Jean-loup Gailly
606 * This is free software; you can redistribute it and/or modify it under the
607 * terms of the GNU General Public License, see the file COPYING.
608 */
609
610/*
611 * PURPOSE
612 *
613 * Identify new text as repetitions of old text within a fixed-
614 * length sliding window trailing behind the new text.
615 *
616 * DISCUSSION
617 *
618 * The "deflation" process depends on being able to identify portions
619 * of the input text which are identical to earlier input (within a
620 * sliding window trailing behind the input currently being processed).
621 *
622 * The most straightforward technique turns out to be the fastest for
623 * most input files: try all possible matches and select the longest.
624 * The key feature of this algorithm is that insertions into the string
625 * dictionary are very simple and thus fast, and deletions are avoided
626 * completely. Insertions are performed at each input character, whereas
627 * string matches are performed only when the previous match ends. So it
628 * is preferable to spend more time in matches to allow very fast string
629 * insertions and avoid deletions. The matching algorithm for small
630 * strings is inspired from that of Rabin & Karp. A brute force approach
631 * is used to find longer strings when a small match has been found.
632 * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
633 * (by Leonid Broukhis).
634 * A previous version of this file used a more sophisticated algorithm
635 * (by Fiala and Greene) which is guaranteed to run in linear amortized
636 * time, but has a larger average cost, uses more memory and is patented.
637 * However the F&G algorithm may be faster for some highly redundant
638 * files if the parameter max_chain_length (described below) is too large.
639 *
640 * ACKNOWLEDGMENTS
641 *
642 * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
643 * I found it in 'freeze' written by Leonid Broukhis.
644 * Thanks to many info-zippers for bug reports and testing.
645 *
646 * REFERENCES
647 *
648 * APPNOTE.TXT documentation file in PKZIP 1.93a distribution.
649 *
650 * A description of the Rabin and Karp algorithm is given in the book
651 * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
652 *
653 * Fiala,E.R., and Greene,D.H.
654 * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
655 *
656 * INTERFACE
657 *
658 * void lm_init (int pack_level, ush *flags)
659 * Initialize the "longest match" routines for a new file
660 *
661 * ulg deflate (void)
662 * Processes a new input file and return its compressed length. Sets
663 * the compressed length, crc, deflate flags and internal file
664 * attributes.
665 */
666
667
668/* ===========================================================================
669 * Configuration parameters
670 */
671
672/* Compile with MEDIUM_MEM to reduce the memory requirements or
673 * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the
674 * entire input file can be held in memory (not possible on 16 bit systems).
675 * Warning: defining these symbols affects HASH_BITS (see below) and thus
676 * affects the compression ratio. The compressed output
677 * is still correct, and might even be smaller in some cases.
678 */
679
680#ifdef SMALL_MEM
681# define HASH_BITS 13 /* Number of bits used to hash strings */
682#endif
683#ifdef MEDIUM_MEM
684# define HASH_BITS 14
685#endif
686#ifndef HASH_BITS
687# define HASH_BITS 15
688 /* For portability to 16 bit machines, do not use values above 15. */
689#endif
690
691/* To save space (see unlzw.c), we overlay prev+head with tab_prefix and
692 * window with tab_suffix. Check that we can do this:
693 */
694#if (WSIZE<<1) > (1<<BITS)
695# error cannot overlay window with tab_suffix and prev with tab_prefix0
696#endif
697#if HASH_BITS > BITS-1
698# error cannot overlay head with tab_prefix1
699#endif
700#define HASH_SIZE (unsigned)(1<<HASH_BITS)
701#define HASH_MASK (HASH_SIZE-1)
702#define WMASK (WSIZE-1)
703/* HASH_SIZE and WSIZE must be powers of two */
704#define NIL 0
705/* Tail of hash chains */
706#define FAST 4
707#define SLOW 2
708/* speed options for the general purpose bit flag */
709#ifndef TOO_FAR
710# define TOO_FAR 4096
711#endif
712/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
713/* ===========================================================================
714 * Local data used by the "longest match" routines.
715 */
716typedef ush Pos;
717typedef unsigned IPos;
718
719/* A Pos is an index in the character window. We use short instead of int to
720 * save space in the various tables. IPos is used only for parameter passing.
721 */
722
723/* DECLARE(uch, window, 2L*WSIZE); */
724/* Sliding window. Input bytes are read into the second half of the window,
725 * and move to the first half later to keep a dictionary of at least WSIZE
726 * bytes. With this organization, matches are limited to a distance of
727 * WSIZE-MAX_MATCH bytes, but this ensures that IO is always
728 * performed with a length multiple of the block size. Also, it limits
729 * the window size to 64K, which is quite useful on MSDOS.
730 * To do: limit the window size to WSIZE+BSZ if SMALL_MEM (the code would
731 * be less efficient).
732 */
733
734/* DECLARE(Pos, prev, WSIZE); */
735/* Link to older string with same hash index. To limit the size of this
736 * array to 64K, this link is maintained only for the last 32K strings.
737 * An index in this array is thus a window index modulo 32K.
738 */
739
740/* DECLARE(Pos, head, 1<<HASH_BITS); */
741/* Heads of the hash chains or NIL. */
742
743static const ulg window_size = (ulg) 2 * WSIZE;
744
745/* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the
746 * input file length plus MIN_LOOKAHEAD.
747 */
748
749static long block_start;
750
751/* window position at the beginning of the current output block. Gets
752 * negative when the window is moved backwards.
753 */
754
755static unsigned ins_h; /* hash index of string to be inserted */
756
757#define H_SHIFT ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH)
758/* Number of bits by which ins_h and del_h must be shifted at each
759 * input step. It must be such that after MIN_MATCH steps, the oldest
760 * byte no longer takes part in the hash key, that is:
761 * H_SHIFT * MIN_MATCH >= HASH_BITS
762 */
763
764static unsigned int prev_length;
765
766/* Length of the best match at previous step. Matches not greater than this
767 * are discarded. This is used in the lazy match evaluation.
768 */
769
770static unsigned strstart; /* start of string to insert */
771static unsigned match_start; /* start of matching string */
772static int eofile; /* flag set at end of input file */
773static unsigned lookahead; /* number of valid bytes ahead in window */
774
775static const unsigned max_chain_length = 4096;
776
777/* To speed up deflation, hash chains are never searched beyond this length.
778 * A higher limit improves compression ratio but degrades the speed.
779 */
780
781static const unsigned int max_lazy_match = 258;
782
783/* Attempt to find a better match only when the current match is strictly
784 * smaller than this value. This mechanism is used only for compression
785 * levels >= 4.
786 */
787#define max_insert_length max_lazy_match
788/* Insert new strings in the hash table only if the match length
789 * is not greater than this length. This saves time but degrades compression.
790 * max_insert_length is used only for compression levels <= 3.
791 */
792
793static const unsigned good_match = 32;
794
795/* Use a faster search when the previous match is longer than this */
796
797
798/* Values for max_lazy_match, good_match and max_chain_length, depending on
799 * the desired pack level (0..9). The values given below have been tuned to
800 * exclude worst case performance for pathological files. Better values may be
801 * found for specific files.
802 */
803
804static const int nice_match = 258; /* Stop searching when current match exceeds this */
805
806/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
807 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
808 * meaning.
809 */
810
811#define EQUAL 0
812/* result of memcmp for equal strings */
813
814/* ===========================================================================
815 * Prototypes for local functions.
816 */
817static void fill_window(void);
818
819static int longest_match(IPos cur_match);
820
821#ifdef DEBUG
822static void check_match(IPos start, IPos match, int length);
823#endif
824
825/* ===========================================================================
826 * Update a hash value with the given input byte
827 * IN assertion: all calls to to UPDATE_HASH are made with consecutive
828 * input characters, so that a running hash key can be computed from the
829 * previous key instead of complete recalculation each time.
830 */
831#define UPDATE_HASH(h,c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK)
832
833/* ===========================================================================
834 * Insert string s in the dictionary and set match_head to the previous head
835 * of the hash chain (the most recent string with same hash key). Return
836 * the previous length of the hash chain.
837 * IN assertion: all calls to to INSERT_STRING are made with consecutive
838 * input characters and the first MIN_MATCH bytes of s are valid
839 * (except for the last MIN_MATCH-1 bytes of the input file).
840 */
841#define INSERT_STRING(s, match_head) \
842 (UPDATE_HASH(ins_h, window[(s) + MIN_MATCH-1]), \
843 prev[(s) & WMASK] = match_head = head[ins_h], \
844 head[ins_h] = (s))
845
846/* ===========================================================================
847 * Initialize the "longest match" routines for a new file
848 */
849static void lm_init(ush * flags)
850{
851 register unsigned j;
852
853 /* Initialize the hash table. */
854 memzero((char *) head, HASH_SIZE * sizeof(*head));
855 /* prev will be initialized on the fly */
856
857 *flags |= SLOW;
858 /* ??? reduce max_chain_length for binary files */
859
860 strstart = 0;
861 block_start = 0L;
862
863 lookahead = read_buf((char *) window,
864 sizeof(int) <= 2 ? (unsigned) WSIZE : 2 * WSIZE);
865
866 if (lookahead == 0 || lookahead == (unsigned) EOF) {
867 eofile = 1, lookahead = 0;
868 return;
869 }
870 eofile = 0;
871 /* Make sure that we always have enough lookahead. This is important
872 * if input comes from a device such as a tty.
873 */
874 while (lookahead < MIN_LOOKAHEAD && !eofile)
875 fill_window();
876
877 ins_h = 0;
878 for (j = 0; j < MIN_MATCH - 1; j++)
879 UPDATE_HASH(ins_h, window[j]);
880 /* If lookahead < MIN_MATCH, ins_h is garbage, but this is
881 * not important since only literal bytes will be emitted.
882 */
883}
884
885/* ===========================================================================
886 * Set match_start to the longest match starting at the given string and
887 * return its length. Matches shorter or equal to prev_length are discarded,
888 * in which case the result is equal to prev_length and match_start is
889 * garbage.
890 * IN assertions: cur_match is the head of the hash chain for the current
891 * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
892 */
893
894/* For MSDOS, OS/2 and 386 Unix, an optimized version is in match.asm or
895 * match.s. The code is functionally equivalent, so you can use the C version
896 * if desired.
897 */
898static int longest_match(IPos cur_match)
899{
900 unsigned chain_length = max_chain_length; /* max hash chain length */
901 register uch *scan = window + strstart; /* current string */
902 register uch *match; /* matched string */
903 register int len; /* length of current match */
904 int best_len = prev_length; /* best match length so far */
905 IPos limit =
906 strstart > (IPos) MAX_DIST ? strstart - (IPos) MAX_DIST : NIL;
907 /* Stop when cur_match becomes <= limit. To simplify the code,
908 * we prevent matches with the string of window index 0.
909 */
910
911/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
912 * It is easy to get rid of this optimization if necessary.
913 */
914#if HASH_BITS < 8 || MAX_MATCH != 258
915# error Code too clever
916#endif
917 register uch *strend = window + strstart + MAX_MATCH;
918 register uch scan_end1 = scan[best_len - 1];
919 register uch scan_end = scan[best_len];
920
921 /* Do not waste too much time if we already have a good match: */
922 if (prev_length >= good_match) {
923 chain_length >>= 2;
924 }
925 Assert(strstart <= window_size - MIN_LOOKAHEAD, "insufficient lookahead");
926
927 do {
928 Assert(cur_match < strstart, "no future");
929 match = window + cur_match;
930
931 /* Skip to next match if the match length cannot increase
932 * or if the match length is less than 2:
933 */
934 if (match[best_len] != scan_end ||
935 match[best_len - 1] != scan_end1 ||
936 *match != *scan || *++match != scan[1])
937 continue;
938
939 /* The check at best_len-1 can be removed because it will be made
940 * again later. (This heuristic is not always a win.)
941 * It is not necessary to compare scan[2] and match[2] since they
942 * are always equal when the other bytes match, given that
943 * the hash keys are equal and that HASH_BITS >= 8.
944 */
945 scan += 2, match++;
946
947 /* We check for insufficient lookahead only every 8th comparison;
948 * the 256th check will be made at strstart+258.
949 */
950 do {
951 } while (*++scan == *++match && *++scan == *++match &&
952 *++scan == *++match && *++scan == *++match &&
953 *++scan == *++match && *++scan == *++match &&
954 *++scan == *++match && *++scan == *++match && scan < strend);
955
956 len = MAX_MATCH - (int) (strend - scan);
957 scan = strend - MAX_MATCH;
958
959 if (len > best_len) {
960 match_start = cur_match;
961 best_len = len;
962 if (len >= nice_match)
963 break;
964 scan_end1 = scan[best_len - 1];
965 scan_end = scan[best_len];
966 }
967 } while ((cur_match = prev[cur_match & WMASK]) > limit
968 && --chain_length != 0);
969
970 return best_len;
971}
972
973#ifdef DEBUG
974/* ===========================================================================
975 * Check that the match at match_start is indeed a match.
976 */
977static void check_match(IPos start, IPos match, int length)
978{
979 /* check that the match is indeed a match */
980 if (memcmp((char *) window + match,
981 (char *) window + start, length) != EQUAL) {
982 bb_error_msg(" start %d, match %d, length %d", start, match, length);
983 bb_error_msg("invalid match");
984 }
985 if (verbose > 1) {
986 bb_error_msg("\\[%d,%d]", start - match, length);
987 do {
988 putc(window[start++], stderr);
989 } while (--length != 0);
990 }
991}
992#else
993# define check_match(start, match, length)
994#endif
995
996/* ===========================================================================
997 * Fill the window when the lookahead becomes insufficient.
998 * Updates strstart and lookahead, and sets eofile if end of input file.
999 * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0
1000 * OUT assertions: at least one byte has been read, or eofile is set;
1001 * file reads are performed for at least two bytes (required for the
1002 * translate_eol option).
1003 */
1004static void fill_window()
1005{
1006 register unsigned n, m;
1007 unsigned more =
1008 (unsigned) (window_size - (ulg) lookahead - (ulg) strstart);
1009 /* Amount of free space at the end of the window. */
1010
1011 /* If the window is almost full and there is insufficient lookahead,
1012 * move the upper half to the lower one to make room in the upper half.
1013 */
1014 if (more == (unsigned) EOF) {
1015 /* Very unlikely, but possible on 16 bit machine if strstart == 0
1016 * and lookahead == 1 (input done one byte at time)
1017 */
1018 more--;
1019 } else if (strstart >= WSIZE + MAX_DIST) {
1020 /* By the IN assertion, the window is not empty so we can't confuse
1021 * more == 0 with more == 64K on a 16 bit machine.
1022 */
1023 Assert(window_size == (ulg) 2 * WSIZE, "no sliding with BIG_MEM");
1024
1025 memcpy((char *) window, (char *) window + WSIZE, (unsigned) WSIZE);
1026 match_start -= WSIZE;
1027 strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */
1028
1029 block_start -= (long) WSIZE;
1030
1031 for (n = 0; n < HASH_SIZE; n++) {
1032 m = head[n];
1033 head[n] = (Pos) (m >= WSIZE ? m - WSIZE : NIL);
1034 }
1035 for (n = 0; n < WSIZE; n++) {
1036 m = prev[n];
1037 prev[n] = (Pos) (m >= WSIZE ? m - WSIZE : NIL);
1038 /* If n is not on any hash chain, prev[n] is garbage but
1039 * its value will never be used.
1040 */
1041 }
1042 more += WSIZE;
1043 }
1044 /* At this point, more >= 2 */
1045 if (!eofile) {
1046 n = read_buf((char *) window + strstart + lookahead, more);
1047 if (n == 0 || n == (unsigned) EOF) {
1048 eofile = 1;
1049 } else {
1050 lookahead += n;
1051 }
1052 }
1053}
1054
1055/* ===========================================================================
1056 * Flush the current block, with given end-of-file flag.
1057 * IN assertion: strstart is set to the end of the current match.
1058 */
1059#define FLUSH_BLOCK(eof) \
1060 flush_block(block_start >= 0L ? (char*)&window[(unsigned)block_start] : \
1061 (char*)NULL, (long)strstart - block_start, (eof))
1062
1063/* ===========================================================================
1064 * Same as above, but achieves better compression. We use a lazy
1065 * evaluation for matches: a match is finally adopted only if there is
1066 * no better match at the next window position.
1067 */
1068static ulg deflate()
1069{
1070 IPos hash_head; /* head of hash chain */
1071 IPos prev_match; /* previous match */
1072 int flush; /* set if current block must be flushed */
1073 int match_available = 0; /* set if previous match exists */
1074 register unsigned match_length = MIN_MATCH - 1; /* length of best match */
1075
1076 /* Process the input block. */
1077 while (lookahead != 0) {
1078 /* Insert the string window[strstart .. strstart+2] in the
1079 * dictionary, and set hash_head to the head of the hash chain:
1080 */
1081 INSERT_STRING(strstart, hash_head);
1082
1083 /* Find the longest match, discarding those <= prev_length.
1084 */
1085 prev_length = match_length, prev_match = match_start;
1086 match_length = MIN_MATCH - 1;
1087
1088 if (hash_head != NIL && prev_length < max_lazy_match &&
1089 strstart - hash_head <= MAX_DIST) {
1090 /* To simplify the code, we prevent matches with the string
1091 * of window index 0 (in particular we have to avoid a match
1092 * of the string with itself at the start of the input file).
1093 */
1094 match_length = longest_match(hash_head);
1095 /* longest_match() sets match_start */
1096 if (match_length > lookahead)
1097 match_length = lookahead;
1098
1099 /* Ignore a length 3 match if it is too distant: */
1100 if (match_length == MIN_MATCH && strstart - match_start > TOO_FAR) {
1101 /* If prev_match is also MIN_MATCH, match_start is garbage
1102 * but we will ignore the current match anyway.
1103 */
1104 match_length--;
1105 }
1106 }
1107 /* If there was a match at the previous step and the current
1108 * match is not better, output the previous match:
1109 */
1110 if (prev_length >= MIN_MATCH && match_length <= prev_length) {
1111
1112 check_match(strstart - 1, prev_match, prev_length);
1113
1114 flush =
1115 ct_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
1116
1117 /* Insert in hash table all strings up to the end of the match.
1118 * strstart-1 and strstart are already inserted.
1119 */
1120 lookahead -= prev_length - 1;
1121 prev_length -= 2;
1122 do {
1123 strstart++;
1124 INSERT_STRING(strstart, hash_head);
1125 /* strstart never exceeds WSIZE-MAX_MATCH, so there are
1126 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
1127 * these bytes are garbage, but it does not matter since the
1128 * next lookahead bytes will always be emitted as literals.
1129 */
1130 } while (--prev_length != 0);
1131 match_available = 0;
1132 match_length = MIN_MATCH - 1;
1133 strstart++;
1134 if (flush)
1135 FLUSH_BLOCK(0), block_start = strstart;
1136
1137 } else if (match_available) {
1138 /* If there was no match at the previous position, output a
1139 * single literal. If there was a match but the current match
1140 * is longer, truncate the previous match to a single literal.
1141 */
1142 Tracevv((stderr, "%c", window[strstart - 1]));
1143 if (ct_tally(0, window[strstart - 1])) {
1144 FLUSH_BLOCK(0), block_start = strstart;
1145 }
1146 strstart++;
1147 lookahead--;
1148 } else {
1149 /* There is no previous match to compare with, wait for
1150 * the next step to decide.
1151 */
1152 match_available = 1;
1153 strstart++;
1154 lookahead--;
1155 }
1156 Assert(strstart <= isize && lookahead <= isize, "a bit too far");
1157
1158 /* Make sure that we always have enough lookahead, except
1159 * at the end of the input file. We need MAX_MATCH bytes
1160 * for the next match, plus MIN_MATCH bytes to insert the
1161 * string following the next match.
1162 */
1163 while (lookahead < MIN_LOOKAHEAD && !eofile)
1164 fill_window();
1165 }
1166 if (match_available)
1167 ct_tally(0, window[strstart - 1]);
1168
1169 return FLUSH_BLOCK(1); /* eof */
1170}
1171
1172/* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
1173 * Copyright (C) 1992-1993 Jean-loup Gailly
1174 * The unzip code was written and put in the public domain by Mark Adler.
1175 * Portions of the lzw code are derived from the public domain 'compress'
1176 * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
1177 * Ken Turkowski, Dave Mack and Peter Jannesen.
1178 *
1179 * See the license_msg below and the file COPYING for the software license.
1180 * See the file algorithm.doc for the compression algorithms and file formats.
1181 */
1182
1183/* Compress files with zip algorithm and 'compress' interface.
1184 * See usage() and help() functions below for all options.
1185 * Outputs:
1186 * file.gz: compressed file with same mode, owner, and utimes
1187 * or stdout with -c option or if stdin used as input.
1188 * If the output file name had to be truncated, the original name is kept
1189 * in the compressed file.
1190 */
1191
1192 /* configuration */
1193
1194typedef struct dirent dir_type;
1195
1196typedef RETSIGTYPE(*sig_type) (int);
1197
1198/* ======================================================================== */
1199int gzip_main(int argc, char **argv)
1200{
1201 int result;
1202 int inFileNum;
1203 int outFileNum;
1204 struct stat statBuf;
1205 char *delFileName;
1206 int tostdout = 0;
1207 int force = 0;
1208 int opt;
1209
1210 while ((opt = getopt(argc, argv, "cf0123456789dq")) != -1) {
1211 switch (opt) {
1212 case 'c':
1213 tostdout = 1;
1214 break;
1215 case 'f':
1216 force = 1;
1217 break;
1218
1219 case '0':
1220 just_store = 1;
1221 break;
1222
1223 /* Ignore 1-9 (compression level) options */
1224 case '1':
1225 case '2':
1226 case '3':
1227 case '4':
1228 case '5':
1229 case '6':
1230 case '7':
1231 case '8':
1232 case '9':
1233 break;
1234 case 'q':
1235 break;
1236#ifdef CONFIG_GUNZIP
1237 case 'd':
1238 optind = 1;
1239 return gunzip_main(argc, argv);
1240#endif
1241 default:
1242 bb_show_usage();
1243 }
1244 }
1245
1246 foreground = signal(SIGINT, SIG_IGN) != SIG_IGN;
1247 if (foreground) {
1248 (void) signal(SIGINT, (sig_type) abort_gzip);
1249 }
1250#ifdef SIGTERM
1251 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
1252 (void) signal(SIGTERM, (sig_type) abort_gzip);
1253 }
1254#endif
1255#ifdef SIGHUP
1256 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
1257 (void) signal(SIGHUP, (sig_type) abort_gzip);
1258 }
1259#endif
1260
1261 strncpy(z_suffix, Z_SUFFIX, sizeof(z_suffix) - 1);
1262 z_len = strlen(z_suffix);
1263
1264 /* Allocate all global buffers (for DYN_ALLOC option) */
1265 ALLOC(uch, inbuf, INBUFSIZ + INBUF_EXTRA);
1266 ALLOC(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA);
1267 ALLOC(ush, d_buf, DIST_BUFSIZE);
1268 ALLOC(uch, window, 2L * WSIZE);
1269 ALLOC(ush, tab_prefix, 1L << BITS);
1270
1271 clear_bufs();
1272 part_nb = 0;
1273
1274 if (optind == argc) {
1275 time_stamp = 0;
1276 ifile_size = -1L;
1277 zip(STDIN_FILENO, STDOUT_FILENO);
1278 } else {
1279 int i;
1280
1281 for (i = optind; i < argc; i++) {
1282 char *path = NULL;
1283
1284 if (strcmp(argv[i], "-") == 0) {
1285 time_stamp = 0;
1286 ifile_size = -1L;
1287 inFileNum = STDIN_FILENO;
1288 outFileNum = STDOUT_FILENO;
1289 } else {
1290 inFileNum = open(argv[i], O_RDONLY);
1291 if (inFileNum < 0 || fstat(inFileNum, &statBuf) < 0)
1292 bb_perror_msg_and_die("%s", argv[i]);
1293 time_stamp = statBuf.st_ctime;
1294 ifile_size = statBuf.st_size;
1295
1296 if (!tostdout) {
1297 path = xmalloc(strlen(argv[i]) + 4);
1298 strcpy(path, argv[i]);
1299 strcat(path, ".gz");
1300
1301 /* Open output file */
1302#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
1303 outFileNum =
1304 open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW);
1305#else
1306 outFileNum = open(path, O_RDWR | O_CREAT | O_EXCL);
1307#endif
1308 if (outFileNum < 0) {
1309 bb_perror_msg("%s", path);
1310 free(path);
1311 continue;
1312 }
1313
1314 /* Set permissions on the file */
1315 fchmod(outFileNum, statBuf.st_mode);
1316 } else
1317 outFileNum = STDOUT_FILENO;
1318 }
1319
1320 if (path == NULL && isatty(outFileNum) && force == 0) {
1321 bb_error_msg
1322 ("compressed data not written to a terminal. Use -f to force compression.");
1323 free(path);
1324 continue;
1325 }
1326
1327 result = zip(inFileNum, outFileNum);
1328
1329 if (path != NULL) {
1330 close(inFileNum);
1331 close(outFileNum);
1332
1333 /* Delete the original file */
1334 if (result == OK)
1335 delFileName = argv[i];
1336 else
1337 delFileName = path;
1338
1339 if (unlink(delFileName) < 0)
1340 bb_perror_msg("%s", delFileName);
1341 }
1342
1343 free(path);
1344 }
1345 }
1346
1347 return (exit_code);
1348}
1349
1350/* trees.c -- output deflated data using Huffman coding
1351 * Copyright (C) 1992-1993 Jean-loup Gailly
1352 * This is free software; you can redistribute it and/or modify it under the
1353 * terms of the GNU General Public License, see the file COPYING.
1354 */
1355
1356/*
1357 * PURPOSE
1358 *
1359 * Encode various sets of source values using variable-length
1360 * binary code trees.
1361 *
1362 * DISCUSSION
1363 *
1364 * The PKZIP "deflation" process uses several Huffman trees. The more
1365 * common source values are represented by shorter bit sequences.
1366 *
1367 * Each code tree is stored in the ZIP file in a compressed form
1368 * which is itself a Huffman encoding of the lengths of
1369 * all the code strings (in ascending order by source values).
1370 * The actual code strings are reconstructed from the lengths in
1371 * the UNZIP process, as described in the "application note"
1372 * (APPNOTE.TXT) distributed as part of PKWARE's PKZIP program.
1373 *
1374 * REFERENCES
1375 *
1376 * Lynch, Thomas J.
1377 * Data Compression: Techniques and Applications, pp. 53-55.
1378 * Lifetime Learning Publications, 1985. ISBN 0-534-03418-7.
1379 *
1380 * Storer, James A.
1381 * Data Compression: Methods and Theory, pp. 49-50.
1382 * Computer Science Press, 1988. ISBN 0-7167-8156-5.
1383 *
1384 * Sedgewick, R.
1385 * Algorithms, p290.
1386 * Addison-Wesley, 1983. ISBN 0-201-06672-6.
1387 *
1388 * INTERFACE
1389 *
1390 * void ct_init (ush *attr, int *methodp)
1391 * Allocate the match buffer, initialize the various tables and save
1392 * the location of the internal file attribute (ascii/binary) and
1393 * method (DEFLATE/STORE)
1394 *
1395 * void ct_tally (int dist, int lc);
1396 * Save the match info and tally the frequency counts.
1397 *
1398 * long flush_block (char *buf, ulg stored_len, int eof)
1399 * Determine the best encoding for the current block: dynamic trees,
1400 * static trees or store, and output the encoded block to the zip
1401 * file. Returns the total compressed length for the file so far.
1402 *
1403 */
1404
1405/* ===========================================================================
1406 * Constants
1407 */
1408
1409#define MAX_BITS 15
1410/* All codes must not exceed MAX_BITS bits */
1411
1412#define MAX_BL_BITS 7
1413/* Bit length codes must not exceed MAX_BL_BITS bits */
1414
1415#define LENGTH_CODES 29
1416/* number of length codes, not counting the special END_BLOCK code */
1417
1418#define LITERALS 256
1419/* number of literal bytes 0..255 */
1420
1421#define END_BLOCK 256
1422/* end of block literal code */
1423
1424#define L_CODES (LITERALS+1+LENGTH_CODES)
1425/* number of Literal or Length codes, including the END_BLOCK code */
1426
1427#define D_CODES 30
1428/* number of distance codes */
1429
1430#define BL_CODES 19
1431/* number of codes used to transfer the bit lengths */
1432
1433typedef uch extra_bits_t;
1434
1435/* extra bits for each length code */
1436static const extra_bits_t extra_lbits[LENGTH_CODES]
1437 = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
1438 4, 4, 5, 5, 5, 5, 0
1439};
1440
1441/* extra bits for each distance code */
1442static const extra_bits_t extra_dbits[D_CODES]
1443 = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
1444 10, 10, 11, 11, 12, 12, 13, 13
1445};
1446
1447/* extra bits for each bit length code */
1448static const extra_bits_t extra_blbits[BL_CODES]
1449= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 };
1450
1451#define STORED_BLOCK 0
1452#define STATIC_TREES 1
1453#define DYN_TREES 2
1454/* The three kinds of block type */
1455
1456#ifndef LIT_BUFSIZE
1457# ifdef SMALL_MEM
1458# define LIT_BUFSIZE 0x2000
1459# else
1460# ifdef MEDIUM_MEM
1461# define LIT_BUFSIZE 0x4000
1462# else
1463# define LIT_BUFSIZE 0x8000
1464# endif
1465# endif
1466#endif
1467#ifndef DIST_BUFSIZE
1468# define DIST_BUFSIZE LIT_BUFSIZE
1469#endif
1470/* Sizes of match buffers for literals/lengths and distances. There are
1471 * 4 reasons for limiting LIT_BUFSIZE to 64K:
1472 * - frequencies can be kept in 16 bit counters
1473 * - if compression is not successful for the first block, all input data is
1474 * still in the window so we can still emit a stored block even when input
1475 * comes from standard input. (This can also be done for all blocks if
1476 * LIT_BUFSIZE is not greater than 32K.)
1477 * - if compression is not successful for a file smaller than 64K, we can
1478 * even emit a stored file instead of a stored block (saving 5 bytes).
1479 * - creating new Huffman trees less frequently may not provide fast
1480 * adaptation to changes in the input data statistics. (Take for
1481 * example a binary file with poorly compressible code followed by
1482 * a highly compressible string table.) Smaller buffer sizes give
1483 * fast adaptation but have of course the overhead of transmitting trees
1484 * more frequently.
1485 * - I can't count above 4
1486 * The current code is general and allows DIST_BUFSIZE < LIT_BUFSIZE (to save
1487 * memory at the expense of compression). Some optimizations would be possible
1488 * if we rely on DIST_BUFSIZE == LIT_BUFSIZE.
1489 */
1490#if LIT_BUFSIZE > INBUFSIZ
1491#error cannot overlay l_buf and inbuf
1492#endif
1493#define REP_3_6 16
1494/* repeat previous bit length 3-6 times (2 bits of repeat count) */
1495#define REPZ_3_10 17
1496/* repeat a zero length 3-10 times (3 bits of repeat count) */
1497#define REPZ_11_138 18
1498/* repeat a zero length 11-138 times (7 bits of repeat count) */
1499
1500/* ===========================================================================
1501 * Local data
1502 */
1503
1504/* Data structure describing a single value and its code string. */
1505typedef struct ct_data {
1506 union {
1507 ush freq; /* frequency count */
1508 ush code; /* bit string */
1509 } fc;
1510 union {
1511 ush dad; /* father node in Huffman tree */
1512 ush len; /* length of bit string */
1513 } dl;
1514} ct_data;
1515
1516#define Freq fc.freq
1517#define Code fc.code
1518#define Dad dl.dad
1519#define Len dl.len
1520
1521#define HEAP_SIZE (2*L_CODES+1)
1522/* maximum heap size */
1523
1524static ct_data dyn_ltree[HEAP_SIZE]; /* literal and length tree */
1525static ct_data dyn_dtree[2 * D_CODES + 1]; /* distance tree */
1526
1527static ct_data static_ltree[L_CODES + 2];
1528
1529/* The static literal tree. Since the bit lengths are imposed, there is no
1530 * need for the L_CODES extra codes used during heap construction. However
1531 * The codes 286 and 287 are needed to build a canonical tree (see ct_init
1532 * below).
1533 */
1534
1535static ct_data static_dtree[D_CODES];
1536
1537/* The static distance tree. (Actually a trivial tree since all codes use
1538 * 5 bits.)
1539 */
1540
1541static ct_data bl_tree[2 * BL_CODES + 1];
1542
1543/* Huffman tree for the bit lengths */
1544
1545typedef struct tree_desc {
1546 ct_data *dyn_tree; /* the dynamic tree */
1547 ct_data *static_tree; /* corresponding static tree or NULL */
1548 const extra_bits_t *extra_bits; /* extra bits for each code or NULL */
1549 int extra_base; /* base index for extra_bits */
1550 int elems; /* max number of elements in the tree */
1551 int max_length; /* max bit length for the codes */
1552 int max_code; /* largest code with non zero frequency */
1553} tree_desc;
1554
1555static tree_desc l_desc =
1556 { dyn_ltree, static_ltree, extra_lbits, LITERALS + 1, L_CODES,
1557 MAX_BITS, 0
1558};
1559
1560static tree_desc d_desc =
1561 { dyn_dtree, static_dtree, extra_dbits, 0, D_CODES, MAX_BITS, 0 };
1562
1563static tree_desc bl_desc =
1564 { bl_tree, (ct_data *) 0, extra_blbits, 0, BL_CODES, MAX_BL_BITS,
1565 0
1566};
1567
1568
1569static ush bl_count[MAX_BITS + 1];
1570
1571/* number of codes at each bit length for an optimal tree */
1572
1573static const uch bl_order[BL_CODES]
1574= { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
1575
1576/* The lengths of the bit length codes are sent in order of decreasing
1577 * probability, to avoid transmitting the lengths for unused bit length codes.
1578 */
1579
1580static int heap[2 * L_CODES + 1]; /* heap used to build the Huffman trees */
1581static int heap_len; /* number of elements in the heap */
1582static int heap_max; /* element of largest frequency */
1583
1584/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
1585 * The same heap array is used to build all trees.
1586 */
1587
1588static uch depth[2 * L_CODES + 1];
1589
1590/* Depth of each subtree used as tie breaker for trees of equal frequency */
1591
1592static uch length_code[MAX_MATCH - MIN_MATCH + 1];
1593
1594/* length code for each normalized match length (0 == MIN_MATCH) */
1595
1596static uch dist_code[512];
1597
1598/* distance codes. The first 256 values correspond to the distances
1599 * 3 .. 258, the last 256 values correspond to the top 8 bits of
1600 * the 15 bit distances.
1601 */
1602
1603static int base_length[LENGTH_CODES];
1604
1605/* First normalized length for each code (0 = MIN_MATCH) */
1606
1607static int base_dist[D_CODES];
1608
1609/* First normalized distance for each code (0 = distance of 1) */
1610
1611#define l_buf inbuf
1612/* DECLARE(uch, l_buf, LIT_BUFSIZE); buffer for literals or lengths */
1613
1614/* DECLARE(ush, d_buf, DIST_BUFSIZE); buffer for distances */
1615
1616static uch flag_buf[(LIT_BUFSIZE / 8)];
1617
1618/* flag_buf is a bit array distinguishing literals from lengths in
1619 * l_buf, thus indicating the presence or absence of a distance.
1620 */
1621
1622static unsigned last_lit; /* running index in l_buf */
1623static unsigned last_dist; /* running index in d_buf */
1624static unsigned last_flags; /* running index in flag_buf */
1625static uch flags; /* current flags not yet saved in flag_buf */
1626static uch flag_bit; /* current bit used in flags */
1627
1628/* bits are filled in flags starting at bit 0 (least significant).
1629 * Note: these flags are overkill in the current code since we don't
1630 * take advantage of DIST_BUFSIZE == LIT_BUFSIZE.
1631 */
1632
1633static ulg opt_len; /* bit length of current block with optimal trees */
1634static ulg static_len; /* bit length of current block with static trees */
1635
1636static ulg compressed_len; /* total bit length of compressed file */
1637
1638
1639static ush *file_type; /* pointer to UNKNOWN, BINARY or ASCII */
1640static int *file_method; /* pointer to DEFLATE or STORE */
1641
1642/* ===========================================================================
1643 * Local (static) routines in this file.
1644 */
1645
1646static void init_block(void);
1647static void pqdownheap(ct_data * tree, int k);
1648static void gen_bitlen(tree_desc * desc);
1649static void gen_codes(ct_data * tree, int max_code);
1650static void build_tree(tree_desc * desc);
1651static void scan_tree(ct_data * tree, int max_code);
1652static void send_tree(ct_data * tree, int max_code);
1653static int build_bl_tree(void);
1654static void send_all_trees(int lcodes, int dcodes, int blcodes);
1655static void compress_block(ct_data * ltree, ct_data * dtree);
1656static void set_file_type(void);
1657
1658
1659#ifndef DEBUG
1660# define send_code(c, tree) send_bits(tree[c].Code, tree[c].Len)
1661 /* Send a code of the given tree. c and tree must not have side effects */
1662
1663#else /* DEBUG */
1664# define send_code(c, tree) \
1665 { if (verbose>1) bb_error_msg("\ncd %3d ",(c)); \
1666 send_bits(tree[c].Code, tree[c].Len); }
1667#endif
1668
1669#define d_code(dist) \
1670 ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)])
1671/* Mapping from a distance to a distance code. dist is the distance - 1 and
1672 * must not have side effects. dist_code[256] and dist_code[257] are never
1673 * used.
1674 */
1675
1676/* the arguments must not have side effects */
1677
1678/* ===========================================================================
1679 * Allocate the match buffer, initialize the various tables and save the
1680 * location of the internal file attribute (ascii/binary) and method
1681 * (DEFLATE/STORE).
1682 */
1683static void ct_init(ush * attr, int *methodp)
1684{
1685 int n; /* iterates over tree elements */
1686 int bits; /* bit counter */
1687 int length; /* length value */
1688 int code; /* code value */
1689 int dist; /* distance index */
1690
1691 file_type = attr;
1692 file_method = methodp;
1693 compressed_len = 0L;
1694
1695 if (static_dtree[0].Len != 0)
1696 return; /* ct_init already called */
1697
1698 /* Initialize the mapping length (0..255) -> length code (0..28) */
1699 length = 0;
1700 for (code = 0; code < LENGTH_CODES - 1; code++) {
1701 base_length[code] = length;
1702 for (n = 0; n < (1 << extra_lbits[code]); n++) {
1703 length_code[length++] = (uch) code;
1704 }
1705 }
1706 Assert(length == 256, "ct_init: length != 256");
1707 /* Note that the length 255 (match length 258) can be represented
1708 * in two different ways: code 284 + 5 bits or code 285, so we
1709 * overwrite length_code[255] to use the best encoding:
1710 */
1711 length_code[length - 1] = (uch) code;
1712
1713 /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
1714 dist = 0;
1715 for (code = 0; code < 16; code++) {
1716 base_dist[code] = dist;
1717 for (n = 0; n < (1 << extra_dbits[code]); n++) {
1718 dist_code[dist++] = (uch) code;
1719 }
1720 }
1721 Assert(dist == 256, "ct_init: dist != 256");
1722 dist >>= 7; /* from now on, all distances are divided by 128 */
1723 for (; code < D_CODES; code++) {
1724 base_dist[code] = dist << 7;
1725 for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
1726 dist_code[256 + dist++] = (uch) code;
1727 }
1728 }
1729 Assert(dist == 256, "ct_init: 256+dist != 512");
1730
1731 /* Construct the codes of the static literal tree */
1732 for (bits = 0; bits <= MAX_BITS; bits++)
1733 bl_count[bits] = 0;
1734 n = 0;
1735 while (n <= 143)
1736 static_ltree[n++].Len = 8, bl_count[8]++;
1737 while (n <= 255)
1738 static_ltree[n++].Len = 9, bl_count[9]++;
1739 while (n <= 279)
1740 static_ltree[n++].Len = 7, bl_count[7]++;
1741 while (n <= 287)
1742 static_ltree[n++].Len = 8, bl_count[8]++;
1743 /* Codes 286 and 287 do not exist, but we must include them in the
1744 * tree construction to get a canonical Huffman tree (longest code
1745 * all ones)
1746 */
1747 gen_codes((ct_data *) static_ltree, L_CODES + 1);
1748
1749 /* The static distance tree is trivial: */
1750 for (n = 0; n < D_CODES; n++) {
1751 static_dtree[n].Len = 5;
1752 static_dtree[n].Code = bi_reverse(n, 5);
1753 }
1754
1755 /* Initialize the first block of the first file: */
1756 init_block();
1757}
1758
1759/* ===========================================================================
1760 * Initialize a new block.
1761 */
1762static void init_block()
1763{
1764 int n; /* iterates over tree elements */
1765
1766 /* Initialize the trees. */
1767 for (n = 0; n < L_CODES; n++)
1768 dyn_ltree[n].Freq = 0;
1769 for (n = 0; n < D_CODES; n++)
1770 dyn_dtree[n].Freq = 0;
1771 for (n = 0; n < BL_CODES; n++)
1772 bl_tree[n].Freq = 0;
1773
1774 dyn_ltree[END_BLOCK].Freq = 1;
1775 opt_len = static_len = 0L;
1776 last_lit = last_dist = last_flags = 0;
1777 flags = 0;
1778 flag_bit = 1;
1779}
1780
1781#define SMALLEST 1
1782/* Index within the heap array of least frequent node in the Huffman tree */
1783
1784
1785/* ===========================================================================
1786 * Remove the smallest element from the heap and recreate the heap with
1787 * one less element. Updates heap and heap_len.
1788 */
1789#define pqremove(tree, top) \
1790{\
1791 top = heap[SMALLEST]; \
1792 heap[SMALLEST] = heap[heap_len--]; \
1793 pqdownheap(tree, SMALLEST); \
1794}
1795
1796/* ===========================================================================
1797 * Compares to subtrees, using the tree depth as tie breaker when
1798 * the subtrees have equal frequency. This minimizes the worst case length.
1799 */
1800#define smaller(tree, n, m) \
1801 (tree[n].Freq < tree[m].Freq || \
1802 (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
1803
1804/* ===========================================================================
1805 * Restore the heap property by moving down the tree starting at node k,
1806 * exchanging a node with the smallest of its two sons if necessary, stopping
1807 * when the heap property is re-established (each father smaller than its
1808 * two sons).
1809 */
1810static void pqdownheap(ct_data * tree, int k)
1811{
1812 int v = heap[k];
1813 int j = k << 1; /* left son of k */
1814
1815 while (j <= heap_len) {
1816 /* Set j to the smallest of the two sons: */
1817 if (j < heap_len && smaller(tree, heap[j + 1], heap[j]))
1818 j++;
1819
1820 /* Exit if v is smaller than both sons */
1821 if (smaller(tree, v, heap[j]))
1822 break;
1823
1824 /* Exchange v with the smallest son */
1825 heap[k] = heap[j];
1826 k = j;
1827
1828 /* And continue down the tree, setting j to the left son of k */
1829 j <<= 1;
1830 }
1831 heap[k] = v;
1832}
1833
1834/* ===========================================================================
1835 * Compute the optimal bit lengths for a tree and update the total bit length
1836 * for the current block.
1837 * IN assertion: the fields freq and dad are set, heap[heap_max] and
1838 * above are the tree nodes sorted by increasing frequency.
1839 * OUT assertions: the field len is set to the optimal bit length, the
1840 * array bl_count contains the frequencies for each bit length.
1841 * The length opt_len is updated; static_len is also updated if stree is
1842 * not null.
1843 */
1844static void gen_bitlen(tree_desc * desc)
1845{
1846 ct_data *tree = desc->dyn_tree;
1847 const extra_bits_t *extra = desc->extra_bits;
1848 int base = desc->extra_base;
1849 int max_code = desc->max_code;
1850 int max_length = desc->max_length;
1851 ct_data *stree = desc->static_tree;
1852 int h; /* heap index */
1853 int n, m; /* iterate over the tree elements */
1854 int bits; /* bit length */
1855 int xbits; /* extra bits */
1856 ush f; /* frequency */
1857 int overflow = 0; /* number of elements with bit length too large */
1858
1859 for (bits = 0; bits <= MAX_BITS; bits++)
1860 bl_count[bits] = 0;
1861
1862 /* In a first pass, compute the optimal bit lengths (which may
1863 * overflow in the case of the bit length tree).
1864 */
1865 tree[heap[heap_max]].Len = 0; /* root of the heap */
1866
1867 for (h = heap_max + 1; h < HEAP_SIZE; h++) {
1868 n = heap[h];
1869 bits = tree[tree[n].Dad].Len + 1;
1870 if (bits > max_length)
1871 bits = max_length, overflow++;
1872 tree[n].Len = (ush) bits;
1873 /* We overwrite tree[n].Dad which is no longer needed */
1874
1875 if (n > max_code)
1876 continue; /* not a leaf node */
1877
1878 bl_count[bits]++;
1879 xbits = 0;
1880 if (n >= base)
1881 xbits = extra[n - base];
1882 f = tree[n].Freq;
1883 opt_len += (ulg) f *(bits + xbits);
1884
1885 if (stree)
1886 static_len += (ulg) f *(stree[n].Len + xbits);
1887 }
1888 if (overflow == 0)
1889 return;
1890
1891 Trace((stderr, "\nbit length overflow\n"));
1892 /* This happens for example on obj2 and pic of the Calgary corpus */
1893
1894 /* Find the first bit length which could increase: */
1895 do {
1896 bits = max_length - 1;
1897 while (bl_count[bits] == 0)
1898 bits--;
1899 bl_count[bits]--; /* move one leaf down the tree */
1900 bl_count[bits + 1] += 2; /* move one overflow item as its brother */
1901 bl_count[max_length]--;
1902 /* The brother of the overflow item also moves one step up,
1903 * but this does not affect bl_count[max_length]
1904 */
1905 overflow -= 2;
1906 } while (overflow > 0);
1907
1908 /* Now recompute all bit lengths, scanning in increasing frequency.
1909 * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
1910 * lengths instead of fixing only the wrong ones. This idea is taken
1911 * from 'ar' written by Haruhiko Okumura.)
1912 */
1913 for (bits = max_length; bits != 0; bits--) {
1914 n = bl_count[bits];
1915 while (n != 0) {
1916 m = heap[--h];
1917 if (m > max_code)
1918 continue;
1919 if (tree[m].Len != (unsigned) bits) {
1920 Trace((stderr, "code %d bits %d->%d\n", m, tree[m].Len,
1921 bits));
1922 opt_len +=
1923 ((long) bits - (long) tree[m].Len) * (long) tree[m].Freq;
1924 tree[m].Len = (ush) bits;
1925 }
1926 n--;
1927 }
1928 }
1929}
1930
1931/* ===========================================================================
1932 * Generate the codes for a given tree and bit counts (which need not be
1933 * optimal).
1934 * IN assertion: the array bl_count contains the bit length statistics for
1935 * the given tree and the field len is set for all tree elements.
1936 * OUT assertion: the field code is set for all tree elements of non
1937 * zero code length.
1938 */
1939static void gen_codes(ct_data * tree, int max_code)
1940{
1941 ush next_code[MAX_BITS + 1]; /* next code value for each bit length */
1942 ush code = 0; /* running code value */
1943 int bits; /* bit index */
1944 int n; /* code index */
1945
1946 /* The distribution counts are first used to generate the code values
1947 * without bit reversal.
1948 */
1949 for (bits = 1; bits <= MAX_BITS; bits++) {
1950 next_code[bits] = code = (code + bl_count[bits - 1]) << 1;
1951 }
1952 /* Check that the bit counts in bl_count are consistent. The last code
1953 * must be all ones.
1954 */
1955 Assert(code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
1956 "inconsistent bit counts");
1957 Tracev((stderr, "\ngen_codes: max_code %d ", max_code));
1958
1959 for (n = 0; n <= max_code; n++) {
1960 int len = tree[n].Len;
1961
1962 if (len == 0)
1963 continue;
1964 /* Now reverse the bits */
1965 tree[n].Code = bi_reverse(next_code[len]++, len);
1966
1967 Tracec(tree != static_ltree,
1968 (stderr, "\nn %3d %c l %2d c %4x (%x) ", n,
1969 (isgraph(n) ? n : ' '), len, tree[n].Code,
1970 next_code[len] - 1));
1971 }
1972}
1973
1974/* ===========================================================================
1975 * Construct one Huffman tree and assigns the code bit strings and lengths.
1976 * Update the total bit length for the current block.
1977 * IN assertion: the field freq is set for all tree elements.
1978 * OUT assertions: the fields len and code are set to the optimal bit length
1979 * and corresponding code. The length opt_len is updated; static_len is
1980 * also updated if stree is not null. The field max_code is set.
1981 */
1982static void build_tree(tree_desc * desc)
1983{
1984 ct_data *tree = desc->dyn_tree;
1985 ct_data *stree = desc->static_tree;
1986 int elems = desc->elems;
1987 int n, m; /* iterate over heap elements */
1988 int max_code = -1; /* largest code with non zero frequency */
1989 int node = elems; /* next internal node of the tree */
1990
1991 /* Construct the initial heap, with least frequent element in
1992 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
1993 * heap[0] is not used.
1994 */
1995 heap_len = 0, heap_max = HEAP_SIZE;
1996
1997 for (n = 0; n < elems; n++) {
1998 if (tree[n].Freq != 0) {
1999 heap[++heap_len] = max_code = n;
2000 depth[n] = 0;
2001 } else {
2002 tree[n].Len = 0;
2003 }
2004 }
2005
2006 /* The pkzip format requires that at least one distance code exists,
2007 * and that at least one bit should be sent even if there is only one
2008 * possible code. So to avoid special checks later on we force at least
2009 * two codes of non zero frequency.
2010 */
2011 while (heap_len < 2) {
2012 int new = heap[++heap_len] = (max_code < 2 ? ++max_code : 0);
2013
2014 tree[new].Freq = 1;
2015 depth[new] = 0;
2016 opt_len--;
2017 if (stree)
2018 static_len -= stree[new].Len;
2019 /* new is 0 or 1 so it does not have extra bits */
2020 }
2021 desc->max_code = max_code;
2022
2023 /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
2024 * establish sub-heaps of increasing lengths:
2025 */
2026 for (n = heap_len / 2; n >= 1; n--)
2027 pqdownheap(tree, n);
2028
2029 /* Construct the Huffman tree by repeatedly combining the least two
2030 * frequent nodes.
2031 */
2032 do {
2033 pqremove(tree, n); /* n = node of least frequency */
2034 m = heap[SMALLEST]; /* m = node of next least frequency */
2035
2036 heap[--heap_max] = n; /* keep the nodes sorted by frequency */
2037 heap[--heap_max] = m;
2038
2039 /* Create a new node father of n and m */
2040 tree[node].Freq = tree[n].Freq + tree[m].Freq;
2041 depth[node] = (uch) (MAX(depth[n], depth[m]) + 1);
2042 tree[n].Dad = tree[m].Dad = (ush) node;
2043#ifdef DUMP_BL_TREE
2044 if (tree == bl_tree) {
2045 bb_error_msg("\nnode %d(%d), sons %d(%d) %d(%d)",
2046 node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
2047 }
2048#endif
2049 /* and insert the new node in the heap */
2050 heap[SMALLEST] = node++;
2051 pqdownheap(tree, SMALLEST);
2052
2053 } while (heap_len >= 2);
2054
2055 heap[--heap_max] = heap[SMALLEST];
2056
2057 /* At this point, the fields freq and dad are set. We can now
2058 * generate the bit lengths.
2059 */
2060 gen_bitlen((tree_desc *) desc);
2061
2062 /* The field len is now set, we can generate the bit codes */
2063 gen_codes((ct_data *) tree, max_code);
2064}
2065
2066/* ===========================================================================
2067 * Scan a literal or distance tree to determine the frequencies of the codes
2068 * in the bit length tree. Updates opt_len to take into account the repeat
2069 * counts. (The contribution of the bit length codes will be added later
2070 * during the construction of bl_tree.)
2071 */
2072static void scan_tree(ct_data * tree, int max_code)
2073{
2074 int n; /* iterates over all tree elements */
2075 int prevlen = -1; /* last emitted length */
2076 int curlen; /* length of current code */
2077 int nextlen = tree[0].Len; /* length of next code */
2078 int count = 0; /* repeat count of the current code */
2079 int max_count = 7; /* max repeat count */
2080 int min_count = 4; /* min repeat count */
2081
2082 if (nextlen == 0)
2083 max_count = 138, min_count = 3;
2084 tree[max_code + 1].Len = (ush) 0xffff; /* guard */
2085
2086 for (n = 0; n <= max_code; n++) {
2087 curlen = nextlen;
2088 nextlen = tree[n + 1].Len;
2089 if (++count < max_count && curlen == nextlen) {
2090 continue;
2091 } else if (count < min_count) {
2092 bl_tree[curlen].Freq += count;
2093 } else if (curlen != 0) {
2094 if (curlen != prevlen)
2095 bl_tree[curlen].Freq++;
2096 bl_tree[REP_3_6].Freq++;
2097 } else if (count <= 10) {
2098 bl_tree[REPZ_3_10].Freq++;
2099 } else {
2100 bl_tree[REPZ_11_138].Freq++;
2101 }
2102 count = 0;
2103 prevlen = curlen;
2104 if (nextlen == 0) {
2105 max_count = 138, min_count = 3;
2106 } else if (curlen == nextlen) {
2107 max_count = 6, min_count = 3;
2108 } else {
2109 max_count = 7, min_count = 4;
2110 }
2111 }
2112}
2113
2114/* ===========================================================================
2115 * Send a literal or distance tree in compressed form, using the codes in
2116 * bl_tree.
2117 */
2118static void send_tree(ct_data * tree, int max_code)
2119{
2120 int n; /* iterates over all tree elements */
2121 int prevlen = -1; /* last emitted length */
2122 int curlen; /* length of current code */
2123 int nextlen = tree[0].Len; /* length of next code */
2124 int count = 0; /* repeat count of the current code */
2125 int max_count = 7; /* max repeat count */
2126 int min_count = 4; /* min repeat count */
2127
2128/* tree[max_code+1].Len = -1; *//* guard already set */
2129 if (nextlen == 0)
2130 max_count = 138, min_count = 3;
2131
2132 for (n = 0; n <= max_code; n++) {
2133 curlen = nextlen;
2134 nextlen = tree[n + 1].Len;
2135 if (++count < max_count && curlen == nextlen) {
2136 continue;
2137 } else if (count < min_count) {
2138 do {
2139 send_code(curlen, bl_tree);
2140 } while (--count != 0);
2141
2142 } else if (curlen != 0) {
2143 if (curlen != prevlen) {
2144 send_code(curlen, bl_tree);
2145 count--;
2146 }
2147 Assert(count >= 3 && count <= 6, " 3_6?");
2148 send_code(REP_3_6, bl_tree);
2149 send_bits(count - 3, 2);
2150
2151 } else if (count <= 10) {
2152 send_code(REPZ_3_10, bl_tree);
2153 send_bits(count - 3, 3);
2154
2155 } else {
2156 send_code(REPZ_11_138, bl_tree);
2157 send_bits(count - 11, 7);
2158 }
2159 count = 0;
2160 prevlen = curlen;
2161 if (nextlen == 0) {
2162 max_count = 138, min_count = 3;
2163 } else if (curlen == nextlen) {
2164 max_count = 6, min_count = 3;
2165 } else {
2166 max_count = 7, min_count = 4;
2167 }
2168 }
2169}
2170
2171/* ===========================================================================
2172 * Construct the Huffman tree for the bit lengths and return the index in
2173 * bl_order of the last bit length code to send.
2174 */
2175static const int build_bl_tree()
2176{
2177 int max_blindex; /* index of last bit length code of non zero freq */
2178
2179 /* Determine the bit length frequencies for literal and distance trees */
2180 scan_tree((ct_data *) dyn_ltree, l_desc.max_code);
2181 scan_tree((ct_data *) dyn_dtree, d_desc.max_code);
2182
2183 /* Build the bit length tree: */
2184 build_tree((tree_desc *) (&bl_desc));
2185 /* opt_len now includes the length of the tree representations, except
2186 * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
2187 */
2188
2189 /* Determine the number of bit length codes to send. The pkzip format
2190 * requires that at least 4 bit length codes be sent. (appnote.txt says
2191 * 3 but the actual value used is 4.)
2192 */
2193 for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
2194 if (bl_tree[bl_order[max_blindex]].Len != 0)
2195 break;
2196 }
2197 /* Update opt_len to include the bit length tree and counts */
2198 opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
2199 Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", opt_len, static_len));
2200
2201 return max_blindex;
2202}
2203
2204/* ===========================================================================
2205 * Send the header for a block using dynamic Huffman trees: the counts, the
2206 * lengths of the bit length codes, the literal tree and the distance tree.
2207 * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
2208 */
2209static void send_all_trees(int lcodes, int dcodes, int blcodes)
2210{
2211 int rank; /* index in bl_order */
2212
2213 Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
2214 Assert(lcodes <= L_CODES && dcodes <= D_CODES
2215 && blcodes <= BL_CODES, "too many codes");
2216 Tracev((stderr, "\nbl counts: "));
2217 send_bits(lcodes - 257, 5); /* not +255 as stated in appnote.txt */
2218 send_bits(dcodes - 1, 5);
2219 send_bits(blcodes - 4, 4); /* not -3 as stated in appnote.txt */
2220 for (rank = 0; rank < blcodes; rank++) {
2221 Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
2222 send_bits(bl_tree[bl_order[rank]].Len, 3);
2223 }
2224 Tracev((stderr, "\nbl tree: sent %ld", bits_sent));
2225
2226 send_tree((ct_data *) dyn_ltree, lcodes - 1); /* send the literal tree */
2227 Tracev((stderr, "\nlit tree: sent %ld", bits_sent));
2228
2229 send_tree((ct_data *) dyn_dtree, dcodes - 1); /* send the distance tree */
2230 Tracev((stderr, "\ndist tree: sent %ld", bits_sent));
2231}
2232
2233/* ===========================================================================
2234 * Determine the best encoding for the current block: dynamic trees, static
2235 * trees or store, and output the encoded block to the zip file. This function
2236 * returns the total compressed length for the file so far.
2237 */
2238static ulg flush_block(char *buf, ulg stored_len, int eof)
2239{
2240 ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
2241 int max_blindex; /* index of last bit length code of non zero freq */
2242
2243 flag_buf[last_flags] = flags; /* Save the flags for the last 8 items */
2244
2245 /* Check if the file is ascii or binary */
2246 if (*file_type == (ush) UNKNOWN)
2247 set_file_type();
2248
2249 /* Construct the literal and distance trees */
2250 build_tree((tree_desc *) (&l_desc));
2251 Tracev((stderr, "\nlit data: dyn %ld, stat %ld", opt_len, static_len));
2252
2253 build_tree((tree_desc *) (&d_desc));
2254 Tracev((stderr, "\ndist data: dyn %ld, stat %ld", opt_len, static_len));
2255 /* At this point, opt_len and static_len are the total bit lengths of
2256 * the compressed block data, excluding the tree representations.
2257 */
2258
2259 /* Build the bit length tree for the above two trees, and get the index
2260 * in bl_order of the last bit length code to send.
2261 */
2262 max_blindex = build_bl_tree();
2263
2264 /* Determine the best encoding. Compute first the block length in bytes */
2265 opt_lenb = (opt_len + 3 + 7) >> 3;
2266 static_lenb = (static_len + 3 + 7) >> 3;
2267
2268 Trace((stderr,
2269 "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ",
2270 opt_lenb, opt_len, static_lenb, static_len, stored_len,
2271 last_lit, last_dist));
2272
2273 if (static_lenb <= opt_lenb)
2274 opt_lenb = static_lenb;
2275
2276 /* If compression failed and this is the first and last block,
2277 * and if the zip file can be seeked (to rewrite the local header),
2278 * the whole file is transformed into a stored file:
2279 */
2280 if ((just_store || (stored_len <= opt_lenb)) && eof && compressed_len == 0L && seekable()) {
2281 /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */
2282 if (buf == (char *) 0)
2283 bb_error_msg("block vanished");
2284
2285 copy_block(buf, (unsigned) stored_len, 0); /* without header */
2286 compressed_len = stored_len << 3;
2287 *file_method = STORED;
2288
2289 } else if ((just_store || (stored_len + 4 <= opt_lenb)) && buf != (char *) 0) {
2290 /* 4: two words for the lengths */
2291 /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
2292 * Otherwise we can't have processed more than WSIZE input bytes since
2293 * the last block flush, because compression would have been
2294 * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
2295 * transform a block into a stored block.
2296 */
2297 send_bits((STORED_BLOCK << 1) + eof, 3); /* send block type */
2298 compressed_len = (compressed_len + 3 + 7) & ~7L;
2299 compressed_len += (stored_len + 4) << 3;
2300
2301 copy_block(buf, (unsigned) stored_len, 1); /* with header */
2302
2303 } else if (static_lenb == opt_lenb) {
2304 send_bits((STATIC_TREES << 1) + eof, 3);
2305 compress_block((ct_data *) static_ltree, (ct_data *) static_dtree);
2306 compressed_len += 3 + static_len;
2307 } else {
2308 send_bits((DYN_TREES << 1) + eof, 3);
2309 send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1,
2310 max_blindex + 1);
2311 compress_block((ct_data *) dyn_ltree, (ct_data *) dyn_dtree);
2312 compressed_len += 3 + opt_len;
2313 }
2314 Assert(compressed_len == bits_sent, "bad compressed size");
2315 init_block();
2316
2317 if (eof) {
2318 bi_windup();
2319 compressed_len += 7; /* align on byte boundary */
2320 }
2321 Tracev((stderr, "\ncomprlen %lu(%lu) ", compressed_len >> 3,
2322 compressed_len - 7 * eof));
2323
2324 return compressed_len >> 3;
2325}
2326
2327/* ===========================================================================
2328 * Save the match info and tally the frequency counts. Return true if
2329 * the current block must be flushed.
2330 */
2331static int ct_tally(int dist, int lc)
2332{
2333 l_buf[last_lit++] = (uch) lc;
2334 if (dist == 0) {
2335 /* lc is the unmatched char */
2336 dyn_ltree[lc].Freq++;
2337 } else {
2338 /* Here, lc is the match length - MIN_MATCH */
2339 dist--; /* dist = match distance - 1 */
2340 Assert((ush) dist < (ush) MAX_DIST &&
2341 (ush) lc <= (ush) (MAX_MATCH - MIN_MATCH) &&
2342 (ush) d_code(dist) < (ush) D_CODES, "ct_tally: bad match");
2343
2344 dyn_ltree[length_code[lc] + LITERALS + 1].Freq++;
2345 dyn_dtree[d_code(dist)].Freq++;
2346
2347 d_buf[last_dist++] = (ush) dist;
2348 flags |= flag_bit;
2349 }
2350 flag_bit <<= 1;
2351
2352 /* Output the flags if they fill a byte: */
2353 if ((last_lit & 7) == 0) {
2354 flag_buf[last_flags++] = flags;
2355 flags = 0, flag_bit = 1;
2356 }
2357 /* Try to guess if it is profitable to stop the current block here */
2358 if ((last_lit & 0xfff) == 0) {
2359 /* Compute an upper bound for the compressed length */
2360 ulg out_length = (ulg) last_lit * 8L;
2361 ulg in_length = (ulg) strstart - block_start;
2362 int dcode;
2363
2364 for (dcode = 0; dcode < D_CODES; dcode++) {
2365 out_length +=
2366 (ulg) dyn_dtree[dcode].Freq * (5L + extra_dbits[dcode]);
2367 }
2368 out_length >>= 3;
2369 Trace((stderr,
2370 "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ",
2371 last_lit, last_dist, in_length, out_length,
2372 100L - out_length * 100L / in_length));
2373 if (last_dist < last_lit / 2 && out_length < in_length / 2)
2374 return 1;
2375 }
2376 return (last_lit == LIT_BUFSIZE - 1 || last_dist == DIST_BUFSIZE);
2377 /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K
2378 * on 16 bit machines and because stored blocks are restricted to
2379 * 64K-1 bytes.
2380 */
2381}
2382
2383/* ===========================================================================
2384 * Send the block data compressed using the given Huffman trees
2385 */
2386static void compress_block(ct_data * ltree, ct_data * dtree)
2387{
2388 unsigned dist; /* distance of matched string */
2389 int lc; /* match length or unmatched char (if dist == 0) */
2390 unsigned lx = 0; /* running index in l_buf */
2391 unsigned dx = 0; /* running index in d_buf */
2392 unsigned fx = 0; /* running index in flag_buf */
2393 uch flag = 0; /* current flags */
2394 unsigned code; /* the code to send */
2395 int extra; /* number of extra bits to send */
2396
2397 if (last_lit != 0)
2398 do {
2399 if ((lx & 7) == 0)
2400 flag = flag_buf[fx++];
2401 lc = l_buf[lx++];
2402 if ((flag & 1) == 0) {
2403 send_code(lc, ltree); /* send a literal byte */
2404 Tracecv(isgraph(lc), (stderr, " '%c' ", lc));
2405 } else {
2406 /* Here, lc is the match length - MIN_MATCH */
2407 code = length_code[lc];
2408 send_code(code + LITERALS + 1, ltree); /* send the length code */
2409 extra = extra_lbits[code];
2410 if (extra != 0) {
2411 lc -= base_length[code];
2412 send_bits(lc, extra); /* send the extra length bits */
2413 }
2414 dist = d_buf[dx++];
2415 /* Here, dist is the match distance - 1 */
2416 code = d_code(dist);
2417 Assert(code < D_CODES, "bad d_code");
2418
2419 send_code(code, dtree); /* send the distance code */
2420 extra = extra_dbits[code];
2421 if (extra != 0) {
2422 dist -= base_dist[code];
2423 send_bits(dist, extra); /* send the extra distance bits */
2424 }
2425 } /* literal or match pair ? */
2426 flag >>= 1;
2427 } while (lx < last_lit);
2428
2429 send_code(END_BLOCK, ltree);
2430}
2431
2432/* ===========================================================================
2433 * Set the file type to ASCII or BINARY, using a crude approximation:
2434 * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
2435 * IN assertion: the fields freq of dyn_ltree are set and the total of all
2436 * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
2437 */
2438static void set_file_type()
2439{
2440 int n = 0;
2441 unsigned ascii_freq = 0;
2442 unsigned bin_freq = 0;
2443
2444 while (n < 7)
2445 bin_freq += dyn_ltree[n++].Freq;
2446 while (n < 128)
2447 ascii_freq += dyn_ltree[n++].Freq;
2448 while (n < LITERALS)
2449 bin_freq += dyn_ltree[n++].Freq;
2450 *file_type = bin_freq > (ascii_freq >> 2) ? BINARY : ASCII;
2451 if (*file_type == BINARY && translate_eol) {
2452 bb_error_msg("-l used on binary file");
2453 }
2454}
2455
2456/* zip.c -- compress files to the gzip or pkzip format
2457 * Copyright (C) 1992-1993 Jean-loup Gailly
2458 * This is free software; you can redistribute it and/or modify it under the
2459 * terms of the GNU General Public License, see the file COPYING.
2460 */
2461
2462
2463static ulg crc; /* crc on uncompressed file data */
2464static long header_bytes; /* number of bytes in gzip header */
2465
2466static void put_long(ulg n)
2467{
2468 put_short((n) & 0xffff);
2469 put_short(((ulg) (n)) >> 16);
2470}
2471
2472/* put_header_byte is used for the compressed output
2473 * - for the initial 4 bytes that can't overflow the buffer.
2474 */
2475#define put_header_byte(c) {outbuf[outcnt++]=(uch)(c);}
2476
2477/* ===========================================================================
2478 * Deflate in to out.
2479 * IN assertions: the input and output buffers are cleared.
2480 * The variables time_stamp and save_orig_name are initialized.
2481 */
2482static int zip(int in, int out)
2483{
2484 uch my_flags = 0; /* general purpose bit flags */
2485 ush attr = 0; /* ascii/binary flag */
2486 ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */
2487
2488 ifd = in;
2489 ofd = out;
2490 outcnt = 0;
2491
2492 /* Write the header to the gzip file. See algorithm.doc for the format */
2493
2494
2495 method = DEFLATED;
2496 put_header_byte(GZIP_MAGIC[0]); /* magic header */
2497 put_header_byte(GZIP_MAGIC[1]);
2498 put_header_byte(DEFLATED); /* compression method */
2499
2500 put_header_byte(my_flags); /* general flags */
2501 put_long(time_stamp);
2502
2503 /* Write deflated file to zip file */
2504 crc = updcrc(0, 0);
2505
2506 bi_init(out);
2507 ct_init(&attr, &method);
2508 lm_init(&deflate_flags);
2509
2510 put_byte((uch) deflate_flags); /* extra flags */
2511 put_byte(OS_CODE); /* OS identifier */
2512
2513 header_bytes = (long) outcnt;
2514
2515 (void) deflate();
2516
2517 /* Write the crc and uncompressed size */
2518 put_long(crc);
2519 put_long(isize);
2520 header_bytes += 2 * sizeof(long);
2521
2522 flush_outbuf();
2523 return OK;
2524}
2525
2526
2527/* ===========================================================================
2528 * Read a new buffer from the current input file, perform end-of-line
2529 * translation, and update the crc and input file size.
2530 * IN assertion: size >= 2 (for end-of-line translation)
2531 */
2532static int file_read(char *buf, unsigned size)
2533{
2534 unsigned len;
2535
2536 Assert(insize == 0, "inbuf not empty");
2537
2538 len = read(ifd, buf, size);
2539 if (len == (unsigned) (-1) || len == 0)
2540 return (int) len;
2541
2542 crc = updcrc((uch *) buf, len);
2543 isize += (ulg) len;
2544 return (int) len;
2545}
2546
2547/* ===========================================================================
2548 * Write the output buffer outbuf[0..outcnt-1] and update bytes_out.
2549 * (used for the compressed data only)
2550 */
2551static void flush_outbuf()
2552{
2553 if (outcnt == 0)
2554 return;
2555
2556 write_buf(ofd, (char *) outbuf, outcnt);
2557 outcnt = 0;
2558}
diff --git a/urunlevel/include/applets.h b/urunlevel/include/applets.h
new file mode 100644
index 0000000..27fe124
--- /dev/null
+++ b/urunlevel/include/applets.h
@@ -0,0 +1,752 @@
1/*
2 * applets.h - a listing of all busybox applets.
3 *
4 * If you write a new applet, you need to add an entry to this list to make
5 * busybox aware of it.
6 *
7 * It is CRUCIAL that this listing be kept in ascii order, otherwise the binary
8 * search lookup contributed by Gaute B Strokkenes stops working. If you value
9 * your kneecaps, you'll be sure to *make sure* that any changes made to this
10 * file result in the listing remaining in ascii order. You have been warned.
11 */
12
13#undef APPLET
14#undef APPLET_ODDNAME
15#undef APPLET_NOUSAGE
16
17
18#if defined(PROTOTYPES)
19 #define APPLET(a,b,c,d) extern int b(int argc, char **argv);
20 #define APPLET_NOUSAGE(a,b,c,d) extern int b(int argc, char **argv);
21 #define APPLET_ODDNAME(a,b,c,d,e) extern int b(int argc, char **argv);
22 extern const char usage_messages[];
23#elif defined(MAKE_USAGE)
24 #ifdef CONFIG_FEATURE_VERBOSE_USAGE
25 #define APPLET(a,b,c,d) a##_trivial_usage "\n\n" a##_full_usage "\0"
26 #define APPLET_NOUSAGE(a,b,c,d) "\b\0"
27 #define APPLET_ODDNAME(a,b,c,d,e) e##_trivial_usage "\n\n" e##_full_usage "\0"
28 #else
29 #define APPLET(a,b,c,d) a##_trivial_usage "\0"
30 #define APPLET_NOUSAGE(a,b,c,d) "\b\0"
31 #define APPLET_ODDNAME(a,b,c,d,e) e##_trivial_usage "\0"
32 #endif
33#elif defined(MAKE_LINKS)
34# define APPLET(a,b,c,d) LINK c a
35# define APPLET_NOUSAGE(a,b,c,d) LINK c a
36# define APPLET_ODDNAME(a,b,c,d,e) LINK c a
37#else
38 const struct BB_applet applets[] = {
39 #define APPLET(a,b,c,d) {#a,b,c,d},
40 #define APPLET_NOUSAGE(a,b,c,d) {a,b,c,d},
41 #define APPLET_ODDNAME(a,b,c,d,e) {a,b,c,d},
42#endif
43
44#ifdef CONFIG_INSTALL_NO_USR
45#define _BB_DIR_USR_BIN _BB_DIR_BIN
46#define _BB_DIR_USR_SBIN _BB_DIR_SBIN
47#endif
48
49
50
51#ifdef CONFIG_TEST
52 APPLET_NOUSAGE("[", test_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
53#endif
54#ifdef CONFIG_ADDGROUP
55 APPLET(addgroup, addgroup_main, _BB_DIR_BIN, _BB_SUID_NEVER)
56#endif
57#ifdef CONFIG_ADDUSER
58 APPLET(adduser, adduser_main, _BB_DIR_BIN, _BB_SUID_NEVER)
59#endif
60#ifdef CONFIG_ADJTIMEX
61 APPLET(adjtimex, adjtimex_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
62#endif
63#ifdef CONFIG_AR
64 APPLET(ar, ar_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
65#endif
66#ifdef CONFIG_ARPING
67 APPLET(arping, arping_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
68#endif
69#ifdef CONFIG_ASH
70 APPLET_NOUSAGE("ash", ash_main, _BB_DIR_BIN, _BB_SUID_NEVER)
71#endif
72#ifdef CONFIG_AWK
73 APPLET(awk, awk_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
74#endif
75#ifdef CONFIG_BASENAME
76 APPLET(basename, basename_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
77#endif
78#ifdef CONFIG_BOOT_NAMED
79 APPLET(boot_named, boot_named_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
80#endif
81#ifdef CONFIG_BOOT_PORTMAP
82 APPLET(boot_portmap, boot_portmap_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
83#endif
84#ifdef CONFIG_BOOT_SYSLOG
85 APPLET(boot_syslog, boot_syslog_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
86#endif
87#ifdef CONFIG_BOOT_TIME
88 APPLET(boot_time, boot_time_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
89#endif
90#ifdef CONFIG_BUNZIP2
91 APPLET(bunzip2, bunzip2_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
92#endif
93 APPLET_NOUSAGE("busybox", busybox_main, _BB_DIR_BIN, _BB_SUID_MAYBE)
94#ifdef CONFIG_BUNZIP2
95 APPLET(bzcat, bunzip2_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
96#endif
97#ifdef CONFIG_CAL
98 APPLET(cal, cal_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
99#endif
100#ifdef CONFIG_CAT
101 APPLET(cat, cat_main, _BB_DIR_BIN, _BB_SUID_NEVER)
102#endif
103#ifdef CONFIG_CHGRP
104 APPLET(chgrp, chgrp_main, _BB_DIR_BIN, _BB_SUID_NEVER)
105#endif
106#ifdef CONFIG_CHMOD
107 APPLET(chmod, chmod_main, _BB_DIR_BIN, _BB_SUID_NEVER)
108#endif
109#ifdef CONFIG_CHOWN
110 APPLET(chown, chown_main, _BB_DIR_BIN, _BB_SUID_NEVER)
111#endif
112#ifdef CONFIG_CHROOT
113 APPLET(chroot, chroot_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
114#endif
115#ifdef CONFIG_CHVT
116 APPLET(chvt, chvt_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
117#endif
118#ifdef CONFIG_CLEAR
119 APPLET(clear, clear_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
120#endif
121#ifdef CONFIG_CMP
122 APPLET(cmp, cmp_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
123#endif
124#ifdef CONFIG_CP
125 APPLET(cp, cp_main, _BB_DIR_BIN, _BB_SUID_NEVER)
126#endif
127#ifdef CONFIG_CPIO
128 APPLET(cpio, cpio_main, _BB_DIR_BIN, _BB_SUID_NEVER)
129#endif
130#ifdef CONFIG_CROND
131 APPLET(crond, crond_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
132#endif
133#ifdef CONFIG_CRONTAB
134 APPLET(crontab, crontab_main, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)
135#endif
136#ifdef CONFIG_CUT
137 APPLET(cut, cut_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
138#endif
139#ifdef CONFIG_DATE
140 APPLET(date, date_main, _BB_DIR_BIN, _BB_SUID_NEVER)
141#endif
142#ifdef CONFIG_DC
143 APPLET(dc, dc_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
144#endif
145#ifdef CONFIG_DD
146 APPLET(dd, dd_main, _BB_DIR_BIN, _BB_SUID_NEVER)
147#endif
148#ifdef CONFIG_DEALLOCVT
149 APPLET(deallocvt, deallocvt_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
150#endif
151#ifdef CONFIG_DELGROUP
152 APPLET(delgroup, delgroup_main, _BB_DIR_BIN, _BB_SUID_NEVER)
153#endif
154#ifdef CONFIG_DELUSER
155 APPLET(deluser, deluser_main, _BB_DIR_BIN, _BB_SUID_NEVER)
156#endif
157#ifdef CONFIG_DEVFSD
158 APPLET(devfsd, devfsd_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
159#endif
160#ifdef CONFIG_DF
161 APPLET(df, df_main, _BB_DIR_BIN, _BB_SUID_NEVER)
162#endif
163#ifdef CONFIG_DIRNAME
164 APPLET(dirname, dirname_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
165#endif
166#ifdef CONFIG_DMESG
167 APPLET(dmesg, dmesg_main, _BB_DIR_BIN, _BB_SUID_NEVER)
168#endif
169#ifdef CONFIG_DOS2UNIX
170 APPLET(dos2unix, dos2unix_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
171#endif
172#ifdef CONFIG_DPKG
173 APPLET(dpkg, dpkg_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
174#endif
175#ifdef CONFIG_DPKG_DEB
176 APPLET_ODDNAME("dpkg-deb", dpkg_deb_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER, dpkg_deb)
177#endif
178#ifdef CONFIG_DU
179 APPLET(du, du_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
180#endif
181#ifdef CONFIG_DUMPKMAP
182 APPLET(dumpkmap, dumpkmap_main, _BB_DIR_BIN, _BB_SUID_NEVER)
183#endif
184#ifdef CONFIG_DUMPLEASES
185 APPLET(dumpleases, dumpleases_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
186#endif
187#ifdef CONFIG_ECHO
188 APPLET(echo, echo_main, _BB_DIR_BIN, _BB_SUID_NEVER)
189#endif
190#if defined(CONFIG_FEATURE_GREP_EGREP_ALIAS)
191 APPLET_NOUSAGE("egrep", grep_main, _BB_DIR_BIN, _BB_SUID_NEVER)
192#endif
193#ifdef CONFIG_ENV
194 APPLET(env, env_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
195#endif
196#ifdef CONFIG_EXPR
197 APPLET(expr, expr_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
198#endif
199#ifdef CONFIG_FALSE
200 APPLET(false, false_main, _BB_DIR_BIN, _BB_SUID_NEVER)
201#endif
202#ifdef CONFIG_FBSET
203 APPLET(fbset, fbset_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
204#endif
205#ifdef CONFIG_FDFLUSH
206 APPLET(fdflush, fdflush_main, _BB_DIR_BIN, _BB_SUID_NEVER)
207#endif
208#ifdef CONFIG_FDFORMAT
209 APPLET(fdformat, fdformat_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
210#endif
211#ifdef CONFIG_FDISK
212 APPLET(fdisk, fdisk_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
213#endif
214#if defined(CONFIG_FEATURE_GREP_FGREP_ALIAS)
215 APPLET_NOUSAGE("fgrep", grep_main, _BB_DIR_BIN, _BB_SUID_NEVER)
216#endif
217#ifdef CONFIG_FIND
218 APPLET(find, find_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
219#endif
220#ifdef CONFIG_FOLD
221 APPLET(fold, fold_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
222#endif
223#ifdef CONFIG_FREE
224 APPLET(free, free_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
225#endif
226#ifdef CONFIG_FREERAMDISK
227 APPLET(freeramdisk, freeramdisk_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
228#endif
229#ifdef CONFIG_FSCK_MINIX
230 APPLET_ODDNAME("fsck.minix", fsck_minix_main, _BB_DIR_SBIN, _BB_SUID_NEVER, fsck_minix)
231#endif
232#ifdef CONFIG_FTPGET
233 APPLET(ftpget, ftpgetput_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
234#endif
235#ifdef CONFIG_FTPPUT
236 APPLET(ftpput, ftpgetput_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
237#endif
238#ifdef CONFIG_GETOPT
239 APPLET(getopt, getopt_main, _BB_DIR_BIN, _BB_SUID_NEVER)
240#endif
241#ifdef CONFIG_GETPKG
242 APPLET(getpkg, getpkg_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
243#endif
244#ifdef CONFIG_GETTY
245 APPLET(getty, getty_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
246#endif
247#ifdef CONFIG_GREP
248 APPLET(grep, grep_main, _BB_DIR_BIN, _BB_SUID_NEVER)
249#endif
250#ifdef CONFIG_GUNZIP
251 APPLET(gunzip, gunzip_main, _BB_DIR_BIN, _BB_SUID_NEVER)
252#endif
253#ifdef CONFIG_GZIP
254 APPLET(gzip, gzip_main, _BB_DIR_BIN, _BB_SUID_NEVER)
255#endif
256#ifdef CONFIG_HALT
257 APPLET(halt, halt_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
258#endif
259#ifdef CONFIG_HDPARM
260 APPLET(hdparm, hdparm_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
261#endif
262#ifdef CONFIG_HEAD
263 APPLET(head, head_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
264#endif
265#ifdef CONFIG_HEXDUMP
266 APPLET(hexdump, hexdump_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
267#endif
268#ifdef CONFIG_HOSTID
269 APPLET(hostid, hostid_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
270#endif
271#ifdef CONFIG_HOSTNAME
272 APPLET(hostname, hostname_main, _BB_DIR_BIN, _BB_SUID_NEVER)
273#endif
274#ifdef CONFIG_HTTPD
275 APPLET(httpd, httpd_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
276#endif
277#ifdef CONFIG_HUSH
278 APPLET_NOUSAGE("hush", hush_main, _BB_DIR_BIN, _BB_SUID_NEVER)
279#endif
280#ifdef CONFIG_HWCLOCK
281 APPLET(hwclock, hwclock_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
282#endif
283#ifdef CONFIG_ID
284 APPLET(id, id_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
285#endif
286#ifdef CONFIG_IFCONFIG
287 APPLET(ifconfig, ifconfig_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
288#endif
289#ifdef CONFIG_IFUPDOWN
290 APPLET(ifdown, ifupdown_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
291#endif
292#ifdef CONFIG_IFUPDOWN
293 APPLET(ifup, ifupdown_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
294#endif
295#ifdef CONFIG_INETD
296 APPLET(inetd, inetd_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
297#endif
298#ifdef CONFIG_INIT
299 APPLET(init, init_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
300#endif
301#ifdef CONFIG_INSMOD
302 APPLET(insmod, insmod_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
303#endif
304#ifdef CONFIG_INSTALL
305 APPLET(install, install_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
306#endif
307#ifdef CONFIG_INSTALL_INITD
308 APPLET(install_initd, install_initd_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
309#endif
310#ifdef CONFIG_IP
311 APPLET(ip, ip_main, _BB_DIR_BIN, _BB_SUID_NEVER)
312#endif
313#ifdef CONFIG_IPADDR
314 APPLET(ipaddr, ipaddr_main, _BB_DIR_BIN, _BB_SUID_NEVER)
315#endif
316#ifdef CONFIG_IPCALC
317 APPLET(ipcalc, ipcalc_main, _BB_DIR_BIN, _BB_SUID_NEVER)
318#endif
319#ifdef CONFIG_IPLINK
320 APPLET(iplink, iplink_main, _BB_DIR_BIN, _BB_SUID_NEVER)
321#endif
322#ifdef CONFIG_IPROUTE
323 APPLET(iproute, iproute_main, _BB_DIR_BIN, _BB_SUID_NEVER)
324#endif
325#ifdef CONFIG_IPTUNNEL
326 APPLET(iptunnel, iptunnel_main, _BB_DIR_BIN, _BB_SUID_NEVER)
327#endif
328#ifdef CONFIG_KILL
329 APPLET(kill, kill_main, _BB_DIR_BIN, _BB_SUID_NEVER)
330#endif
331#ifdef CONFIG_KILLALL
332 APPLET(killall, kill_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
333#endif
334#ifdef CONFIG_KILLPROC
335 APPLET(killproc, killproc_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
336#endif
337#ifdef CONFIG_KLOGD
338 APPLET(klogd, klogd_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
339#endif
340#ifdef CONFIG_LASH
341 APPLET(lash, lash_main, _BB_DIR_BIN, _BB_SUID_NEVER)
342#endif
343#ifdef CONFIG_LAST
344 APPLET(last, last_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
345#endif
346#ifdef CONFIG_LENGTH
347 APPLET(length, length_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
348#endif
349#ifdef CONFIG_FEATURE_INITRD
350 APPLET_NOUSAGE("linuxrc", init_main, _BB_DIR_ROOT, _BB_SUID_NEVER)
351#endif
352#ifdef CONFIG_LINUXRC
353 APPLET(linuxrc, linuxrc_main, _BB_DIR_ROOT, _BB_SUID_NEVER)
354#endif
355#ifdef CONFIG_LN
356 APPLET(ln, ln_main, _BB_DIR_BIN, _BB_SUID_NEVER)
357#endif
358#ifdef CONFIG_LOADFONT
359 APPLET(loadfont, loadfont_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
360#endif
361#ifdef CONFIG_LOADKMAP
362 APPLET(loadkmap, loadkmap_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
363#endif
364#ifdef CONFIG_LOCAL_FS
365 APPLET(local_fs, local_fs_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
366#endif
367#ifdef CONFIG_LOG_FAILURE_MSG
368 APPLET(log_failure_msg, log_failure_msg_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
369#endif
370#ifdef CONFIG_LOG_SUCCESS_MSG
371 APPLET(log_success_msg, log_success_msg_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
372#endif
373#ifdef CONFIG_LOG_WARNING_MSG
374 APPLET(log_warning_msg, log_warning_msg_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
375#endif
376#ifdef CONFIG_LOGGER
377 APPLET(logger, logger_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
378#endif
379#ifdef CONFIG_LOGIN
380 APPLET(login, login_main, _BB_DIR_BIN, _BB_SUID_ALWAYS)
381#endif
382#ifdef CONFIG_LOGNAME
383 APPLET(logname, logname_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
384#endif
385#ifdef CONFIG_LOGREAD
386 APPLET(logread, logread_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
387#endif
388#ifdef CONFIG_LOSETUP
389 APPLET(losetup, losetup_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
390#endif
391#ifdef CONFIG_LS
392 APPLET(ls, ls_main, _BB_DIR_BIN, _BB_SUID_NEVER)
393#endif
394#ifdef CONFIG_LSMOD
395 APPLET(lsmod, lsmod_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
396#endif
397#ifdef CONFIG_MAKEDEVS
398 APPLET(makedevs, makedevs_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
399#endif
400#ifdef CONFIG_MAN
401 APPLET(man, man_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
402#endif
403#ifdef CONFIG_MD5SUM
404 APPLET(md5sum, md5sum_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
405#endif
406#ifdef CONFIG_MESG
407 APPLET(mesg, mesg_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
408#endif
409#ifdef CONFIG_MKDIR
410 APPLET(mkdir, mkdir_main, _BB_DIR_BIN, _BB_SUID_NEVER)
411#endif
412#ifdef CONFIG_MKFIFO
413 APPLET(mkfifo, mkfifo_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
414#endif
415#ifdef CONFIG_MKFS_MINIX
416 APPLET_ODDNAME("mkfs.minix", mkfs_minix_main, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_minix)
417#endif
418#ifdef CONFIG_MKNOD
419 APPLET(mknod, mknod_main, _BB_DIR_BIN, _BB_SUID_NEVER)
420#endif
421#ifdef CONFIG_MKSWAP
422 APPLET(mkswap, mkswap_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
423#endif
424#ifdef CONFIG_MKTEMP
425 APPLET(mktemp, mktemp_main, _BB_DIR_BIN, _BB_SUID_NEVER)
426#endif
427#ifdef CONFIG_MODPROBE
428 APPLET(modprobe, modprobe_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
429#endif
430#ifdef CONFIG_MORE
431 APPLET(more, more_main, _BB_DIR_BIN, _BB_SUID_NEVER)
432#endif
433#ifdef CONFIG_MOUNT
434 APPLET(mount, mount_main, _BB_DIR_BIN, _BB_SUID_NEVER)
435#endif
436#ifdef CONFIG_MSH
437 APPLET_NOUSAGE("msh", msh_main, _BB_DIR_BIN, _BB_SUID_NEVER)
438#endif
439#ifdef CONFIG_MT
440 APPLET(mt, mt_main, _BB_DIR_BIN, _BB_SUID_NEVER)
441#endif
442#ifdef CONFIG_MV
443 APPLET(mv, mv_main, _BB_DIR_BIN, _BB_SUID_NEVER)
444#endif
445#ifdef CONFIG_NAMEIF
446 APPLET(nameif, nameif_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
447#endif
448#ifdef CONFIG_NC
449 APPLET(nc, nc_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
450#endif
451#ifdef CONFIG_NETSTAT
452 APPLET(netstat, netstat_main, _BB_DIR_BIN, _BB_SUID_NEVER)
453#endif
454#ifdef CONFIG_NETWORK
455 APPLET(network, network_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
456#endif
457#ifdef CONFIG_NSLOOKUP
458 APPLET(nslookup, nslookup_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
459#endif
460#ifdef CONFIG_OD
461 APPLET(od, od_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
462#endif
463#ifdef CONFIG_OPENVT
464 APPLET(openvt, openvt_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
465#endif
466#ifdef CONFIG_PASSWD
467 APPLET(passwd, passwd_main, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)
468#endif
469#ifdef CONFIG_PATCH
470 APPLET(patch, patch_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
471#endif
472#ifdef CONFIG_PIDOF
473 APPLET(pidof, pidof_main, _BB_DIR_BIN, _BB_SUID_NEVER)
474#endif
475#ifdef CONFIG_PIDOFPROC
476 APPLET(pidofproc, pidofproc_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
477#endif
478#ifdef CONFIG_PING
479 APPLET(ping, ping_main, _BB_DIR_BIN, _BB_SUID_MAYBE)
480#endif
481#ifdef CONFIG_PING6
482 APPLET(ping6, ping6_main, _BB_DIR_BIN, _BB_SUID_NEVER)
483#endif
484#ifdef CONFIG_PIPE_PROGRESS
485 APPLET_NOUSAGE("pipe_progress", pipe_progress_main, _BB_DIR_BIN, _BB_SUID_NEVER)
486#endif
487#ifdef CONFIG_PIVOT_ROOT
488 APPLET(pivot_root, pivot_root_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
489#endif
490#ifdef CONFIG_POWEROFF
491 APPLET(poweroff, poweroff_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
492#endif
493#ifdef CONFIG_PRINTF
494 APPLET(printf, printf_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
495#endif
496#ifdef CONFIG_PS
497 APPLET(ps, ps_main, _BB_DIR_BIN, _BB_SUID_NEVER)
498#endif
499#ifdef CONFIG_PWD
500 APPLET(pwd, pwd_main, _BB_DIR_BIN, _BB_SUID_NEVER)
501#endif
502#ifdef CONFIG_RC
503 APPLET(rc, rc_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
504#endif
505#ifdef CONFIG_RCS
506 APPLET(rcS, rcS_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
507#endif
508#ifdef CONFIG_RDATE
509 APPLET(rdate, rdate_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
510#endif
511#ifdef CONFIG_READLINK
512 APPLET(readlink, readlink_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
513#endif
514#ifdef CONFIG_REALPATH
515 APPLET(realpath, realpath_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
516#endif
517#ifdef CONFIG_REBOOT
518 APPLET(reboot, reboot_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
519#endif
520#ifdef CONFIG_REMOTE_FS
521 APPLET(remote_fs, remote_fs_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
522#endif
523#ifdef CONFIG_REMOVE_INITD
524 APPLET(remove_initd, remove_initd_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
525#endif
526#ifdef CONFIG_RENICE
527 APPLET(renice, renice_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
528#endif
529#ifdef CONFIG_RESET
530 APPLET(reset, reset_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
531#endif
532#ifdef CONFIG_RM
533 APPLET(rm, rm_main, _BB_DIR_BIN, _BB_SUID_NEVER)
534#endif
535#ifdef CONFIG_RMDIR
536 APPLET(rmdir, rmdir_main, _BB_DIR_BIN, _BB_SUID_NEVER)
537#endif
538#ifdef CONFIG_RMMOD
539 APPLET(rmmod, rmmod_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
540#endif
541#ifdef CONFIG_ROUTE
542 APPLET(route, route_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
543#endif
544#ifdef CONFIG_RPM
545 APPLET(rpm, rpm_main, _BB_DIR_BIN, _BB_SUID_NEVER)
546#endif
547#ifdef CONFIG_RPM2CPIO
548 APPLET(rpm2cpio, rpm2cpio_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
549#endif
550#ifdef CONFIG_RUN_PARTS
551 APPLET_ODDNAME("run-parts", run_parts_main, _BB_DIR_BIN, _BB_SUID_NEVER, run_parts)
552#endif
553#ifdef CONFIG_RX
554 APPLET(rx, rx_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
555#endif
556#ifdef CONFIG_SED
557 APPLET(sed, sed_main, _BB_DIR_BIN, _BB_SUID_NEVER)
558#endif
559#ifdef CONFIG_SEQ
560 APPLET(seq, seq_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
561#endif
562#ifdef CONFIG_SETKEYCODES
563 APPLET(setkeycodes, setkeycodes_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
564#endif
565#if defined(CONFIG_FEATURE_SH_IS_ASH) && defined(CONFIG_ASH)
566 APPLET_NOUSAGE("sh", ash_main, _BB_DIR_BIN, _BB_SUID_NEVER)
567#elif defined(CONFIG_FEATURE_SH_IS_HUSH) && defined(CONFIG_HUSH)
568 APPLET_NOUSAGE("sh", hush_main, _BB_DIR_BIN, _BB_SUID_NEVER)
569#elif defined(CONFIG_FEATURE_SH_IS_LASH) && defined(CONFIG_LASH)
570 APPLET_NOUSAGE("sh", lash_main, _BB_DIR_BIN, _BB_SUID_NEVER)
571#elif defined(CONFIG_FEATURE_SH_IS_MSH) && defined(CONFIG_MSH)
572 APPLET_NOUSAGE("sh", msh_main, _BB_DIR_BIN, _BB_SUID_NEVER)
573#endif
574#ifdef CONFIG_SHA1SUM
575 APPLET(sha1sum, sha1sum_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
576#endif
577#ifdef CONFIG_SLEEP
578 APPLET(sleep, sleep_main, _BB_DIR_BIN, _BB_SUID_NEVER)
579#endif
580#ifdef CONFIG_SORT
581 APPLET(sort, sort_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
582#endif
583#ifdef CONFIG_START_STOP_DAEMON
584 APPLET_ODDNAME("start-stop-daemon", start_stop_daemon_main, _BB_DIR_SBIN, _BB_SUID_NEVER, start_stop_daemon)
585#endif
586#ifdef CONFIG_START_DAEMON
587 APPLET(start_daemon, start_daemon_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
588#endif
589#ifdef CONFIG_STRINGS
590 APPLET(strings, strings_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
591#endif
592#ifdef CONFIG_STTY
593 APPLET(stty, stty_main, _BB_DIR_BIN, _BB_SUID_NEVER)
594#endif
595#ifdef CONFIG_SU
596 APPLET(su, su_main, _BB_DIR_BIN, _BB_SUID_ALWAYS)
597#endif
598#ifdef CONFIG_SULOGIN
599 APPLET(sulogin, sulogin_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
600#endif
601#ifdef CONFIG_SWAPONOFF
602 APPLET(swapoff, swap_on_off_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
603#endif
604#ifdef CONFIG_SWAPONOFF
605 APPLET(swapon, swap_on_off_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
606#endif
607#ifdef CONFIG_SYNC
608 APPLET(sync, sync_main, _BB_DIR_BIN, _BB_SUID_NEVER)
609#endif
610#ifdef CONFIG_SYSCTL
611 APPLET(sysctl, sysctl_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
612#endif
613#ifdef CONFIG_SYSLOGD
614 APPLET(syslogd, syslogd_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
615#endif
616#ifdef CONFIG_TAIL
617 APPLET(tail, tail_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
618#endif
619#ifdef CONFIG_TAR
620 APPLET(tar, tar_main, _BB_DIR_BIN, _BB_SUID_NEVER)
621#endif
622#ifdef CONFIG_TEE
623 APPLET(tee, tee_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
624#endif
625#ifdef CONFIG_TELNET
626 APPLET(telnet, telnet_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
627#endif
628#ifdef CONFIG_TELNETD
629 APPLET(telnetd, telnetd_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
630#endif
631#ifdef CONFIG_TEST
632 APPLET(test, test_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
633#endif
634#ifdef CONFIG_TFTP
635 APPLET(tftp, tftp_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
636#endif
637#ifdef CONFIG_TIME
638 APPLET(time, time_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
639#endif
640#ifdef CONFIG_TOP
641 APPLET(top, top_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
642#endif
643#ifdef CONFIG_TOUCH
644 APPLET(touch, touch_main, _BB_DIR_BIN, _BB_SUID_NEVER)
645#endif
646#ifdef CONFIG_TR
647 APPLET(tr, tr_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
648#endif
649#ifdef CONFIG_TRACEROUTE
650 APPLET(traceroute, traceroute_main, _BB_DIR_USR_BIN, _BB_SUID_MAYBE)
651#endif
652#ifdef CONFIG_TRUE
653 APPLET(true, true_main, _BB_DIR_BIN, _BB_SUID_NEVER)
654#endif
655#ifdef CONFIG_TTY
656 APPLET(tty, tty_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
657#endif
658#ifdef CONFIG_UDHCPC
659 APPLET(udhcpc, udhcpc_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
660#endif
661#ifdef CONFIG_UDHCPC_SCRIPT
662 APPLET(udhcpc_script, udhcpc_script_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
663#endif
664#ifdef CONFIG_UDHCPD
665 APPLET(udhcpd, udhcpd_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
666#endif
667#ifdef CONFIG_UMOUNT
668 APPLET(umount, umount_main, _BB_DIR_BIN, _BB_SUID_NEVER)
669#endif
670#ifdef CONFIG_UNAME
671 APPLET(uname, uname_main, _BB_DIR_BIN, _BB_SUID_NEVER)
672#endif
673#ifdef CONFIG_UNCOMPRESS
674 APPLET(uncompress, uncompress_main, _BB_DIR_BIN, _BB_SUID_NEVER)
675#endif
676#ifdef CONFIG_UNIQ
677 APPLET(uniq, uniq_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
678#endif
679#ifdef CONFIG_UNIX2DOS
680 APPLET(unix2dos, dos2unix_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
681#endif
682#ifdef CONFIG_UNZIP
683 APPLET(unzip, unzip_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
684#endif
685#ifdef CONFIG_UPTIME
686 APPLET(uptime, uptime_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
687#endif
688#ifdef CONFIG_USLEEP
689 APPLET(usleep, usleep_main, _BB_DIR_BIN, _BB_SUID_NEVER)
690#endif
691#ifdef CONFIG_UUDECODE
692 APPLET(uudecode, uudecode_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
693#endif
694#ifdef CONFIG_UUENCODE
695 APPLET(uuencode, uuencode_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
696#endif
697#ifdef CONFIG_VCONFIG
698 APPLET(vconfig, vconfig_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
699#endif
700#ifdef CONFIG_VI
701 APPLET(vi, vi_main, _BB_DIR_BIN, _BB_SUID_NEVER)
702#endif
703#ifdef CONFIG_VLOCK
704 APPLET(vlock, vlock_main, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)
705#endif
706#ifdef CONFIG_WATCH
707 APPLET(watch, watch_main, _BB_DIR_BIN, _BB_SUID_NEVER)
708#endif
709#ifdef CONFIG_WATCHDOG
710 APPLET(watchdog, watchdog_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
711#endif
712#ifdef CONFIG_WC
713 APPLET(wc, wc_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
714#endif
715#ifdef CONFIG_WGET
716 APPLET(wget, wget_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
717#endif
718#ifdef CONFIG_WHICH
719 APPLET(which, which_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
720#endif
721#ifdef CONFIG_WHO
722 APPLET(who, who_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
723#endif
724#ifdef CONFIG_WHOAMI
725 APPLET(whoami, whoami_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
726#endif
727#ifdef CONFIG_XARGS
728 APPLET(xargs, xargs_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
729#endif
730#ifdef CONFIG_YES
731 APPLET(yes, yes_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
732#endif
733#ifdef CONFIG_GUNZIP
734 APPLET(zcat, gunzip_main, _BB_DIR_BIN, _BB_SUID_NEVER)
735#endif
736
737#if !defined(PROTOTYPES) && !defined(MAKE_USAGE)
738 { 0,NULL,0 }
739};
740
741#endif
742
743
744
745
746
747
748
749
750
751
752
diff --git a/urunlevel/include/usage.h b/urunlevel/include/usage.h
new file mode 100644
index 0000000..c18bb20
--- /dev/null
+++ b/urunlevel/include/usage.h
@@ -0,0 +1,3077 @@
1#ifndef __BB_USAGE_H__
2#define __BB_USAGE_H__
3
4#define addgroup_trivial_usage \
5 "[-g GID] group_name [user_name]"
6#define addgroup_full_usage \
7 "Adds a group to the system\n\n" \
8 "Options:\n" \
9 "\t-g GID\t\tspecify gid"
10
11#define adduser_trivial_usage \
12 "[OPTIONS] user_name"
13#define adduser_full_usage \
14 "Adds a user to the system\n\n" \
15 "Options:\n" \
16 "\t-h DIR\t\tAssign home directory DIR\n" \
17 "\t-g GECOS\tAssign gecos field GECOS\n" \
18 "\t-s SHELL\tAssign login shell SHELL\n" \
19 "\t-G\t\tAdd the user to existing group GROUP\n" \
20 "\t-S\t\tcreate a system user (ignored)\n" \
21 "\t-D\t\tDo not assign a password (logins still possible via ssh)\n" \
22 "\t-H\t\tDo not create the home directory"
23
24#define adjtimex_trivial_usage \
25 "[-q] [-o offset] [-f frequency] [-p timeconstant] [-t tick]"
26#define adjtimex_full_usage \
27 "Reads and optionally sets system timebase parameters.\n" \
28 "See adjtimex(2).\n\n" \
29 "Options:\n" \
30 "\t-q\t\tquiet mode - do not print\n" \
31 "\t-o offset\ttime offset, microseconds\n" \
32 "\t-f frequency\tfrequency adjust, integer kernel units (65536 is 1ppm)\n" \
33 "\t\t\t(positive values make the system clock run fast)\n" \
34 "\t-t tick\t\tmicroseconds per tick, usually 10000\n" \
35 "\t-p timeconstant"
36
37#define ar_trivial_usage \
38 "[-o] [-v] [-p] [-t] [-x] ARCHIVE FILES"
39#define ar_full_usage \
40 "Extract or list FILES from an ar archive.\n\n" \
41 "Options:\n" \
42 "\t-o\t\tpreserve original dates\n" \
43 "\t-p\t\textract to stdout\n" \
44 "\t-t\t\tlist\n" \
45 "\t-x\t\textract\n" \
46 "\t-v\t\tverbosely list files processed"
47
48#define arping_trivial_usage \
49 "[-fqbDUA] [-c count] [-w timeout] [-I device] [-s sender] target\n"
50#define arping_full_usage \
51 "Ping hosts by ARP requests/replies.\n\n" \
52 "Options:\n" \
53 "\t-f\t\tQuit on first ARP reply\n" \
54 "\t-q\t\tBe quiet\n" \
55 "\t-b\t\tKeep broadcasting, don't go unicast\n" \
56 "\t-D\t\tDuplicated address detection mode\n" \
57 "\t-U\t\tUnsolicited ARP mode, update your neighbours\n" \
58 "\t-A\t\tARP answer mode, update your neighbours\n" \
59 "\t-c count\tStop after sending count ARP request packets\n" \
60 "\t-w timeout\tTime to wait for ARP reply, in seconds\n" \
61 "\t-I device\tOutgoing interface name, default is eth0\n" \
62 "\t-s sender\tSet specific sender IP address\n" \
63 "\ttarget\t\tTarget IP address of ARP request"
64
65#define ash_trivial_usage \
66 "[FILE]...\n" \
67 "or: ash -c command [args]...\n"
68#define ash_full_usage \
69 "The ash shell (command interpreter)"
70
71#define awk_trivial_usage \
72 "[OPTION]... [program-text] [FILE ...]"
73#define awk_full_usage \
74 "Options:\n" \
75 "\t-v var=val\t\tassign value 'val' to variable 'var'\n" \
76 "\t-F sep\t\tuse 'sep' as field separator\n" \
77 "\t-f progname\t\tread program source from file 'progname'"
78
79#define basename_trivial_usage \
80 "FILE [SUFFIX]"
81#define basename_full_usage \
82 "Strips directory path and suffixes from FILE.\n" \
83 "If specified, also removes any trailing SUFFIX."
84#define basename_example_usage \
85 "$ basename /usr/local/bin/foo\n" \
86 "foo\n" \
87 "$ basename /usr/local/bin/\n" \
88 "bin\n" \
89 "$ basename /foo/bar.txt .txt\n" \
90 "bar"
91
92
93#define boot_named_trivial_usage \
94 ""
95#define boot_named_full_usage \
96 "LSB boot_named init system."
97#define boot_named_example_usage \
98 "$ boot_named start\n"
99
100
101#define boot_portmap_trivial_usage \
102 ""
103#define boot_portmap_full_usage \
104 "LSB boot_portmap init system."
105#define boot_portmap_example_usage \
106 "$ boot_portmap start\n"
107
108
109#define boot_syslog_trivial_usage \
110 ""
111#define boot_syslog_full_usage \
112 "LSB boot_syslog init system."
113#define boot_syslog_example_usage \
114 "$ boot_syslog start\n"
115
116
117#define boot_time_trivial_usage \
118 ""
119#define boot_time_full_usage \
120 "LSB boot_time init system."
121#define boot_time_example_usage \
122 "$ boot_time start\n"
123
124
125#define bunzip2_trivial_usage \
126 "[OPTION]... [FILE]"
127#define bunzip2_full_usage \
128 "Uncompress FILE (or standard input if FILE is '-' or omitted).\n\n" \
129 "Options:\n" \
130 "\t-c\tWrite output to standard output\n" \
131 "\t-f\tForce"
132
133#define bzcat_trivial_usage \
134 "FILE"
135#define bzcat_full_usage \
136 "Uncompress to stdout."
137
138#define cal_trivial_usage \
139 "[-jy] [[month] year]"
140#define cal_full_usage \
141 "Display a calendar.\n" \
142 "\nOptions:\n" \
143 "\t-j\tUse julian dates.\n" \
144 "\t-y\tDisplay the entire year."
145
146#define cat_trivial_usage \
147 "[-u] [FILE]..."
148#define cat_full_usage \
149 "Concatenates FILE(s) and prints them to stdout.\n\n" \
150 "Options:\n" \
151 "\t-u\tignored since unbuffered i/o is always used"
152#define cat_example_usage \
153 "$ cat /proc/uptime\n" \
154 "110716.72 17.67"
155
156#define chgrp_trivial_usage \
157 "[OPTION]... GROUP FILE..."
158#define chgrp_full_usage \
159 "Change the group membership of each FILE to GROUP.\n" \
160 "\nOptions:\n" \
161 "\t-R\tChanges files and directories recursively."
162#define chgrp_example_usage \
163 "$ ls -l /tmp/foo\n" \
164 "-r--r--r-- 1 andersen andersen 0 Apr 12 18:25 /tmp/foo\n" \
165 "$ chgrp root /tmp/foo\n" \
166 "$ ls -l /tmp/foo\n" \
167 "-r--r--r-- 1 andersen root 0 Apr 12 18:25 /tmp/foo\n"
168
169#define chmod_trivial_usage \
170 "[-R] MODE[,MODE]... FILE..."
171#define chmod_full_usage \
172 "Each MODE is one or more of the letters ugoa, one of the\n" \
173 "symbols +-= and one or more of the letters rwxst.\n\n" \
174 "Options:\n" \
175 "\t-R\tChanges files and directories recursively."
176#define chmod_example_usage \
177 "$ ls -l /tmp/foo\n" \
178 "-rw-rw-r-- 1 root root 0 Apr 12 18:25 /tmp/foo\n" \
179 "$ chmod u+x /tmp/foo\n" \
180 "$ ls -l /tmp/foo\n" \
181 "-rwxrw-r-- 1 root root 0 Apr 12 18:25 /tmp/foo*\n" \
182 "$ chmod 444 /tmp/foo\n" \
183 "$ ls -l /tmp/foo\n" \
184 "-r--r--r-- 1 root root 0 Apr 12 18:25 /tmp/foo\n"
185
186#define chown_trivial_usage \
187 "[ -Rh ]... OWNER[<.|:>[GROUP]] FILE..."
188#define chown_full_usage \
189 "Change the owner and/or group of each FILE to OWNER and/or GROUP.\n" \
190 "\nOptions:\n" \
191 "\t-R\tChanges files and directories recursively.\n" \
192 "\t-h\tDo not dereference symbolic links."
193#define chown_example_usage \
194 "$ ls -l /tmp/foo\n" \
195 "-r--r--r-- 1 andersen andersen 0 Apr 12 18:25 /tmp/foo\n" \
196 "$ chown root /tmp/foo\n" \
197 "$ ls -l /tmp/foo\n" \
198 "-r--r--r-- 1 root andersen 0 Apr 12 18:25 /tmp/foo\n" \
199 "$ chown root.root /tmp/foo\n" \
200 "ls -l /tmp/foo\n" \
201 "-r--r--r-- 1 root root 0 Apr 12 18:25 /tmp/foo\n"
202
203#define chroot_trivial_usage \
204 "NEWROOT [COMMAND...]"
205#define chroot_full_usage \
206 "Run COMMAND with root directory set to NEWROOT."
207#define chroot_example_usage \
208 "$ ls -l /bin/ls\n" \
209 "lrwxrwxrwx 1 root root 12 Apr 13 00:46 /bin/ls -> /BusyBox\n" \
210 "# mount /dev/hdc1 /mnt -t minix\n" \
211 "# chroot /mnt\n" \
212 "# ls -l /bin/ls\n" \
213 "-rwxr-xr-x 1 root root 40816 Feb 5 07:45 /bin/ls*\n"
214
215#define chvt_trivial_usage \
216 "N"
217#define chvt_full_usage \
218 "Changes the foreground virtual terminal to /dev/ttyN"
219
220#define clear_trivial_usage \
221 ""
222#define clear_full_usage \
223 "Clear screen."
224
225#define cmp_trivial_usage \
226 "[-l] [-s] FILE1 [FILE2]"
227#define cmp_full_usage \
228 "Compare files. Compares FILE1 vs stdin if FILE2 is not specified.\n\n" \
229 "Options:\n" \
230 "\t-l\tWrite the byte numbers (decimal) and values (octal)\n" \
231 "\t\t for all differing bytes.\n" \
232 "\t-s\tquiet mode - do not print"
233
234#define cp_trivial_usage \
235 "[OPTION]... SOURCE DEST"
236#define cp_full_usage \
237 "Copies SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n" \
238 "\n" \
239 "\t-a\tSame as -dpR\n" \
240 "\t-d\tPreserves links\n" \
241 "\t-p\tPreserves file attributes if possible\n" \
242 "\t-f\tforce (implied; ignored) - always set\n" \
243 "\t-i\tinteractive, prompt before overwrite\n" \
244 "\t-R,-r\tCopies directories recursively"
245
246#define cpio_trivial_usage \
247 "-[dimtuv][F cpiofile]"
248#define cpio_full_usage \
249 "Extract or list files from a cpio archive\n" \
250 "Main operation mode:\n" \
251 "\td\t\tmake leading directories\n" \
252 "\ti\t\textract\n" \
253 "\tm\t\tpreserve mtime\n" \
254 "\tt\t\tlist\n" \
255 "\tv\t\tverbose\n" \
256 "\tu\t\tunconditional overwrite\n" \
257 "\tF\t\tinput from file"
258
259#define crond_trivial_usage \
260 "-d[#] -c <crondir> -f -b"
261#define crond_full_usage \
262 "\t-d [#] -l [#] -S -L logfile -f -b -c dir\n" \
263 "\t-d num\tdebug level\n" \
264 "\t-l num\tlog level (8 - default)\n" \
265 "\t-S\tlog to syslogd (default)\n" \
266 "\t-L file\tlog to file\n" \
267 "\t-f\trun in fordeground\n" \
268 "\t-b\trun in background (default)\n" \
269 "\t-c dir\tworking dir"
270
271#define crontab_trivial_usage \
272 "[-c dir] {file|-}|[-u|-l|-e|-d user]"
273#define crontab_full_usage \
274 "\tfile <opts> replace crontab from file\n" \
275 "\t- <opts> replace crontab from stdin\n" \
276 "\t-u user specify user\n" \
277 "\t-l [user] list crontab for user\n" \
278 "\t-e [user] edit crontab for user\n" \
279 "\t-d [user] delete crontab for user\n" \
280 "\t-c dir specify crontab directory"
281
282
283#define cut_trivial_usage \
284 "[OPTION]... [FILE]..."
285#define cut_full_usage \
286 "Prints selected fields from each input FILE to standard output.\n\n" \
287 "Options:\n" \
288 "\t-b LIST\t\tOutput only bytes from LIST\n" \
289 "\t-c LIST\t\tOutput only characters from LIST\n" \
290 "\t-d CHAR\t\tUse CHAR instead of tab as the field delimiter\n" \
291 "\t-s\t\tOutput only the lines containing delimiter\n" \
292 "\t-f N\t\tPrint only these fields\n" \
293 "\t-n\t\tIgnored"
294#define cut_example_usage \
295 "$ echo "Hello world" | cut -f 1 -d ' '\n" \
296 "Hello\n" \
297 "$ echo "Hello world" | cut -f 2 -d ' '\n" \
298 "world\n"
299
300#ifdef CONFIG_FEATURE_DATE_ISOFMT
301#define USAGE_DATE_ISOFMT(a) a
302#else
303#define USAGE_DATE_ISOFMT(a)
304#endif
305
306#define date_trivial_usage \
307 "[OPTION]... [MMDDhhmm[[CC]YY][.ss]] [+FORMAT]"
308#define date_full_usage \
309 "Displays the current time in the given FORMAT, or sets the system date.\n" \
310 "\nOptions:\n" \
311 "\t-R\t\tOutputs RFC-822 compliant date string\n" \
312 "\t-d STRING\tDisplays time described by STRING, not `now'\n" \
313 USAGE_DATE_ISOFMT("\t-I[TIMESPEC]\tOutputs an ISO-8601 compliant date/time string.\n" \
314 "\t\t\tTIMESPEC=`date' (or missing) for date only,\n" \
315 "\t\t\t`hours', `minutes', or `seconds' for date and,\n" \
316 "\t\t\ttime to the indicated precision.\n") \
317 "\t-s\t\tSets time described by STRING\n" \
318 "\t-r FILE\t\tDisplays the last modification time of FILE\n" \
319 "\t-u\t\tPrints or sets Coordinated Universal Time"
320#define date_example_usage \
321 "$ date\n" \
322 "Wed Apr 12 18:52:41 MDT 2000\n"
323
324#define dc_trivial_usage \
325 "expression ..."
326#define dc_full_usage \
327 "This is a Tiny RPN calculator that understands the\n" \
328 "following operations: +, add, -, sub, *, mul, /, div, %, mod, "\
329 "**, exp, and, or, not, eor.\n" \
330 "For example: 'dc 2 2 add' -> 4, and 'dc 8 8 \\* 2 2 + /' -> 16.\n" \
331 "\nOptions:\n" \
332 "p - Prints the value on the top of the stack, without altering the stack.\n" \
333 "f - Prints the entire contents of the stack without altering anything.\n" \
334 "o - Pops the value off the top of the stack and uses it to set the output radix.\n" \
335 " Only 10 and 16 are supported."
336#define dc_example_usage \
337 "$ dc 2 2 + p\n" \
338 "4\n" \
339 "$ dc 8 8 \\* 2 2 + / p\n" \
340 "16\n" \
341 "$ dc 0 1 and p\n" \
342 "0\n" \
343 "$ dc 0 1 or p\n" \
344 "1\n" \
345 "$ echo 72 9 div 8 mul p | dc\n" \
346 "64\n"
347
348#define dd_trivial_usage \
349 "[if=FILE] [of=FILE] [bs=N] [count=N] [skip=N]\n" \
350 "\t [seek=N] [conv=notrunc|noerror|sync]"
351#define dd_full_usage \
352 "Copy a file, converting and formatting according to options\n\n" \
353 "\tif=FILE\t\tread from FILE instead of stdin\n" \
354 "\tof=FILE\t\twrite to FILE instead of stdout\n" \
355 "\tbs=N\t\tread and write N bytes at a time\n" \
356 "\tcount=N\t\tcopy only N input blocks\n" \
357 "\tskip=N\t\tskip N input blocks\n" \
358 "\tseek=N\t\tskip N output blocks\n" \
359 "\tconv=notrunc\tdon't truncate output file\n" \
360 "\tconv=noerror\tcontinue after read errors\n" \
361 "\tconv=sync\tpad blocks with zeros\n" \
362 "\n" \
363 "Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),\n" \
364 "MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)."
365#define dd_example_usage \
366 "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n" \
367 "4+0 records in\n" \
368 "4+0 records out\n"
369
370#define deallocvt_trivial_usage \
371 "[N]"
372#define deallocvt_full_usage \
373 "Deallocate unused virtual terminal /dev/ttyN"
374
375#define delgroup_trivial_usage \
376 "GROUP"
377#define delgroup_full_usage \
378 "Deletes group GROUP from the system"
379
380#define deluser_trivial_usage \
381 "USER"
382#define deluser_full_usage \
383 "Deletes user USER from the system"
384
385#ifdef CONFIG_DEVFSD_FG_NP
386 #define USAGE_DEVFSD_FG_NP(a) a
387#else
388 #define USAGE_DEVFSD_FG_NP(a)
389#endif
390
391#define devfsd_trivial_usage \
392 "mntpnt [-v]"\
393 USAGE_DEVFSD_FG_NP("[-fg][-np]" )
394#define devfsd_full_usage \
395 "Optional daemon for managing devfs permissions and old device name symlinks.\n" \
396 "\nOptions:\n" \
397 "\tmntpnt\tThe mount point where devfs is mounted.\n\n" \
398 "\t-v\tPrint the protocol version numbers for devfsd\n" \
399 "\t\tand the kernel-side protocol version and exits." \
400 USAGE_DEVFSD_FG_NP( "\n\n\t-fg\tRun the daemon in the foreground.\n\n" \
401 "\t-np\tExit after parsing the configuration file\n" \
402 "\t\tand processing synthetic REGISTER events.\n" \
403 "\t\tDo not poll for events.")
404
405#ifdef CONFIG_FEATURE_HUMAN_READABLE
406 #define USAGE_HUMAN_READABLE(a) a
407 #define USAGE_NOT_HUMAN_READABLE(a)
408#else
409 #define USAGE_HUMAN_READABLE(a)
410 #define USAGE_NOT_HUMAN_READABLE(a) a
411#endif
412#define df_trivial_usage \
413 "[-" USAGE_HUMAN_READABLE("hm") USAGE_NOT_HUMAN_READABLE("") "k] [FILESYSTEM ...]"
414#define df_full_usage \
415 "Print the filesystem space used and space available.\n\n" \
416 "Options:\n" \
417 USAGE_HUMAN_READABLE( \
418 "\n\t-h\tprint sizes in human readable format (e.g., 1K 243M 2G )\n" \
419 "\t-m\tprint sizes in megabytes\n" \
420 "\t-k\tprint sizes in kilobytes(default)") USAGE_NOT_HUMAN_READABLE( \
421 "\n\t-k\tprint sizes in kilobytes(compatibility)")
422#define df_example_usage \
423 "$ df\n" \
424 "Filesystem 1k-blocks Used Available Use% Mounted on\n" \
425 "/dev/sda3 8690864 8553540 137324 98% /\n" \
426 "/dev/sda1 64216 36364 27852 57% /boot\n" \
427 "$ df /dev/sda3\n" \
428 "Filesystem 1k-blocks Used Available Use% Mounted on\n" \
429 "/dev/sda3 8690864 8553540 137324 98% /\n"
430
431#define dirname_trivial_usage \
432 "FILENAME"
433#define dirname_full_usage \
434 "Strips non-directory suffix from FILENAME"
435#define dirname_example_usage \
436 "$ dirname /tmp/foo\n" \
437 "/tmp\n" \
438 "$ dirname /tmp/foo/\n" \
439 "/tmp\n"
440
441#define dmesg_trivial_usage \
442 "[-c] [-n LEVEL] [-s SIZE]"
443#define dmesg_full_usage \
444 "Prints or controls the kernel ring buffer\n\n" \
445 "Options:\n" \
446 "\t-c\t\tClears the ring buffer's contents after printing\n" \
447 "\t-n LEVEL\tSets console logging level\n" \
448 "\t-s SIZE\t\tUse a buffer of size SIZE"
449
450#define dos2unix_trivial_usage \
451 "[option] [FILE]"
452#define dos2unix_full_usage \
453 "Converts FILE from dos format to unix format. When no option\n" \
454 "is given, the input is converted to the opposite output format.\n" \
455 "When no file is given, uses stdin for input and stdout for output.\n\n" \
456 "Options:\n" \
457 "\t-u\toutput will be in UNIX format\n" \
458 "\t-d\toutput will be in DOS format"
459
460#define dpkg_trivial_usage \
461 "[-ilCPru] [-F option] package_name"
462#define dpkg_full_usage \
463 "dpkg is a utility to install, remove and manage Debian packages.\n\n" \
464 "Options:\n" \
465 "\t-i\t\tInstall the package\n" \
466 "\t-l\t\tList of installed packages\n" \
467 "\t-C\t\tConfigure an unpackaged package\n" \
468 "\t-F depends\tIgnore depency problems\n" \
469 "\t-P\t\tPurge all files of a package\n" \
470 "\t-r\t\tRemove all but the configuration files for a package\n" \
471 "\t-u\t\tUnpack a package, but don't configure it"
472
473#define dpkg_deb_trivial_usage \
474 "[-cefxX] FILE [argument]"
475#define dpkg_deb_full_usage \
476 "Perform actions on Debian packages (.debs)\n\n" \
477 "Options:\n" \
478 "\t-c\tList contents of filesystem tree\n" \
479 "\t-e\tExtract control files to [argument] directory\n" \
480 "\t-f\tDisplay control field name starting with [argument]\n" \
481 "\t-x\tExtract packages filesystem tree to directory\n" \
482 "\t-X\tVerbose extract"
483#define dpkg_deb_example_usage \
484 "$ dpkg-deb -X ./busybox_0.48-1_i386.deb /tmp\n"
485
486#ifdef CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K
487#define USAGE_DU_DEFALT_BLOCKSIZE_1k(a) a
488#define USAGE_NOT_DU_DEFALT_BLOCKSIZE_1k(a)
489#else
490#define USAGE_DU_DEFALT_BLOCKSIZE_1k(a)
491#define USAGE_NOT_DU_DEFALT_BLOCKSIZE_1k(a) a
492#endif
493
494#define du_trivial_usage \
495 "[-aHLdclsx" USAGE_HUMAN_READABLE("hm") "k] [FILE]..."
496#define du_full_usage \
497 "Summarizes disk space used for each FILE and/or directory.\n" \
498 "Disk space is printed in units of " \
499 USAGE_DU_DEFALT_BLOCKSIZE_1k("1024") USAGE_NOT_DU_DEFALT_BLOCKSIZE_1k("512") \
500 " bytes.\n\n" \
501 "Options:\n" \
502 "\t-a\tshow sizes of files in addition to directories\n" \
503 "\t-H\tfollow symbolic links that are FILE command line args\n" \
504 "\t-L\tfollow all symbolic links encountered\n" \
505 "\t-d N\tlimit output to directories (and files with -a) of depth < N\n" \
506 "\t-c\toutput a grand total\n" \
507 "\t-l\tcount sizes many times if hard linked\n" \
508 "\t-s\tdisplay only a total for each argument\n" \
509 "\t-x\tskip directories on different filesystems\n" \
510 USAGE_HUMAN_READABLE( \
511 "\t-h\tprint sizes in human readable format (e.g., 1K 243M 2G )\n" \
512 "\t-m\tprint sizes in megabytes\n" ) \
513 "\t-k\tprint sizes in kilobytes" USAGE_DU_DEFALT_BLOCKSIZE_1k("(default)")
514#define du_example_usage \
515 "$ du\n" \
516 "16 ./CVS\n" \
517 "12 ./kernel-patches/CVS\n" \
518 "80 ./kernel-patches\n" \
519 "12 ./tests/CVS\n" \
520 "36 ./tests\n" \
521 "12 ./scripts/CVS\n" \
522 "16 ./scripts\n" \
523 "12 ./docs/CVS\n" \
524 "104 ./docs\n" \
525 "2417 .\n"
526
527#define dumpkmap_trivial_usage \
528 "> keymap"
529#define dumpkmap_full_usage \
530 "Prints out a binary keyboard translation table to standard output."
531#define dumpkmap_example_usage \
532 "$ dumpkmap > keymap\n"
533
534#define dumpleases_trivial_usage \
535 "[-r|-a] [-f LEASEFILE]"
536#define dumpleases_full_usage \
537 "Displays the DHCP leases granted by udhcpd.\n\n" \
538 "Options:\n" \
539 "\t-f,\t--file=FILENAME\tLeases file to load\n" \
540 "\t-r,\t--remaining\tInterpret lease times as time remaing\n" \
541 "\t-a,\t--absolute\tInterpret lease times as expire time"
542
543#ifdef CONFIG_FEATURE_FANCY_ECHO
544 #define USAGE_FANCY_ECHO(a) a
545#else
546 #define USAGE_FANCY_ECHO(a)
547#endif
548
549#define echo_trivial_usage \
550 USAGE_FANCY_ECHO("[-neE] ") "[ARG ...]"
551#define echo_full_usage \
552 "Prints the specified ARGs to stdout\n\n" \
553 USAGE_FANCY_ECHO("Options:\n" \
554 "\t-n\tsuppress trailing newline\n" \
555 "\t-e\tinterpret backslash-escaped characters (i.e., \\t=tab)\n" \
556 "\t-E\tdisable interpretation of backslash-escaped characters")
557#define echo_example_usage \
558 "$ echo "Erik is cool"\n" \
559 "Erik is cool\n" \
560 USAGE_FANCY_ECHO("$ echo -e "Erik\\nis\\ncool"\n" \
561 "Erik\n" \
562 "is\n" \
563 "cool\n" \
564 "$ echo "Erik\\nis\\ncool"\n" \
565 "Erik\\nis\\ncool\n")
566
567#define env_trivial_usage \
568 "[-iu] [-] [name=value]... [command]"
569#define env_full_usage \
570 "Prints the current environment or runs a program after setting\n" \
571 "up the specified environment.\n\n" \
572 "Options:\n" \
573 "\t-, -i\tstart with an empty environment\n" \
574 "\t-u\tremove variable from the environment"
575
576#define expr_trivial_usage \
577 "EXPRESSION"
578#define expr_full_usage \
579 "Prints the value of EXPRESSION to standard output.\n\n" \
580 "EXPRESSION may be:\n" \
581 "\tARG1 | ARG2 ARG1 if it is neither null nor 0, otherwise ARG2\n" \
582 "\tARG1 & ARG2 ARG1 if neither argument is null or 0, otherwise 0\n" \
583 "\tARG1 < ARG2 ARG1 is less than ARG2\n" \
584 "\tARG1 <= ARG2 ARG1 is less than or equal to ARG2\n" \
585 "\tARG1 = ARG2 ARG1 is equal to ARG2\n" \
586 "\tARG1 != ARG2 ARG1 is unequal to ARG2\n" \
587 "\tARG1 >= ARG2 ARG1 is greater than or equal to ARG2\n" \
588 "\tARG1 > ARG2 ARG1 is greater than ARG2\n" \
589 "\tARG1 + ARG2 arithmetic sum of ARG1 and ARG2\n" \
590 "\tARG1 - ARG2 arithmetic difference of ARG1 and ARG2\n" \
591 "\tARG1 * ARG2 arithmetic product of ARG1 and ARG2\n" \
592 "\tARG1 / ARG2 arithmetic quotient of ARG1 divided by ARG2\n" \
593 "\tARG1 % ARG2 arithmetic remainder of ARG1 divided by ARG2\n" \
594 "\tSTRING : REGEXP anchored pattern match of REGEXP in STRING\n" \
595 "\tmatch STRING REGEXP same as STRING : REGEXP\n" \
596 "\tsubstr STRING POS LENGTH substring of STRING, POS counted from 1\n" \
597 "\tindex STRING CHARS index in STRING where any CHARS is found,\n" \
598 "\t or 0\n" \
599 "\tlength STRING length of STRING\n" \
600 "\tquote TOKEN interpret TOKEN as a string, even if\n" \
601 "\t it is a keyword like `match' or an\n" \
602 "\t operator like `/'\n" \
603 "\t( EXPRESSION ) value of EXPRESSION\n\n" \
604 "Beware that many operators need to be escaped or quoted for shells.\n" \
605 "Comparisons are arithmetic if both ARGs are numbers, else\n" \
606 "lexicographical. Pattern matches return the string matched between \n" \
607 "\\( and \\) or null; if \\( and \\) are not used, they return the number \n" \
608 "of characters matched or 0."
609
610#define false_trivial_usage \
611 ""
612#define false_full_usage \
613 "Return an exit code of FALSE (1)."
614#define false_example_usage \
615 "$ false\n" \
616 "$ echo $?\n" \
617 "1\n"
618
619#define fbset_trivial_usage \
620 "[options] [mode]"
621#define fbset_full_usage \
622 "Show and modify frame buffer settings"
623#define fbset_example_usage \
624 "$ fbset\n" \
625 "mode "1024x768-76"\n" \
626 "\t# D: 78.653 MHz, H: 59.949 kHz, V: 75.694 Hz\n" \
627 "\tgeometry 1024 768 1024 768 16\n" \
628 "\ttimings 12714 128 32 16 4 128 4\n" \
629 "\taccel false\n" \
630 "\trgba 5/11,6/5,5/0,0/0\n" \
631 "endmode\n"
632
633#define fdflush_trivial_usage \
634 "DEVICE"
635#define fdflush_full_usage \
636 "Forces floppy disk drive to detect disk change"
637
638#define fdformat_trivial_usage \
639 "[-n] DEVICE"
640#define fdformat_full_usage \
641 "Low-level formats a floppy disk\n\n" \
642 "Options:\n" \
643 "\t-n\tDon't verify after format"
644
645#define fdisk_trivial_usage \
646 "[-luv] [-C CYLINDERS] [-H HEADS] [-S SECTORS] [-b SSZ] DISK"
647#define fdisk_full_usage \
648 "Change partition table\n" \
649 "Options:\n" \
650 "\t-l List partition table(s)\n" \
651 "\t-u Give Start and End in sector (instead of cylinder) units\n" \
652 "\t-s PARTITION Give partition size(s) in blocks\n" \
653 "\t-b 2048: (for certain MO disks) use 2048-byte sectors\n" \
654 "\t-C CYLINDERS Set the number of cylinders\n" \
655 "\t-H HEADS Set the number of heads\n" \
656 "\t-S SECTORS Set the number of sectors\n" \
657 "\t-v Give fdisk version"
658
659#ifdef CONFIG_FEATURE_FIND_TYPE
660 #define USAGE_FIND_TYPE(a) a
661#else
662 #define USAGE_FIND_TYPE(a)
663#endif
664#ifdef CONFIG_FEATURE_FIND_PERM
665 #define USAGE_FIND_PERM(a) a
666#else
667 #define USAGE_FIND_PERM(a)
668#endif
669#ifdef CONFIG_FEATURE_FIND_MTIME
670 #define USAGE_FIND_MTIME(a) a
671#else
672 #define USAGE_FIND_MTIME(a)
673#endif
674#ifdef CONFIG_FEATURE_FIND_NEWER
675 #define USAGE_FIND_NEWER(a) a
676#else
677 #define USAGE_FIND_NEWER(a)
678#endif
679#ifdef CONFIG_FEATURE_FIND_INUM
680 #define USAGE_FIND_INUM(a) a
681#else
682 #define USAGE_FIND_INUM(a)
683#endif
684
685#define find_trivial_usage \
686 "[PATH...] [EXPRESSION]"
687#define find_full_usage \
688 "Search for files in a directory hierarchy. The default PATH is\n" \
689 "the current directory; default EXPRESSION is '-print'\n" \
690 "\nEXPRESSION may consist of:\n" \
691 "\t-follow\t\tDereference symbolic links.\n" \
692 "\t-name PATTERN\tFile name (leading directories removed) matches PATTERN.\n" \
693 "\t-print\t\tPrint (default and assumed).\n" \
694 USAGE_FIND_TYPE( \
695 "\n\t-type X\t\tFiletype matches X (where X is one of: f,d,l,b,c,...)" \
696) USAGE_FIND_PERM( \
697 "\n\t-perm PERMS\tPermissions match any of (+NNN); all of (-NNN);\n\t\t\tor exactly (NNN)" \
698) USAGE_FIND_MTIME( \
699 "\n\t-mtime TIME\tModified time is greater than (+N); less than (-N);\n\t\t\tor exactly (N) days" \
700) USAGE_FIND_NEWER( \
701 "\n\t-newer FILE\tModified time is more recent than FILE's" \
702) USAGE_FIND_INUM( \
703 "\n\t-inum N\t\tFile has inode number N")
704#define find_example_usage \
705 "$ find / -name passwd\n" \
706 "/etc/passwd\n"
707
708#define fold_trivial_usage \
709 "[-bsw] [FILE]"
710#define fold_full_usage \
711 "Wrap input lines in each FILE (standard input by default), writing to\n" \
712 "standard output.\n\n" \
713 "Options:\n" \
714 "\t-b\tcount bytes rather than columns\n" \
715 "\t-s\tbreak at spaces\n" \
716 "\t-w\tuse WIDTH columns instead of 80"
717
718#define free_trivial_usage \
719 ""
720#define free_full_usage \
721 "Displays the amount of free and used system memory"
722#define free_example_usage \
723 "$ free\n" \
724 " total used free shared buffers\n" \
725 " Mem: 257628 248724 8904 59644 93124\n" \
726 " Swap: 128516 8404 120112\n" \
727 "Total: 386144 257128 129016\n" \
728
729#define freeramdisk_trivial_usage \
730 "DEVICE"
731#define freeramdisk_full_usage \
732 "Frees all memory used by the specified ramdisk."
733#define freeramdisk_example_usage \
734 "$ freeramdisk /dev/ram2\n"
735
736#define fsck_minix_trivial_usage \
737 "[-larvsmf] /dev/name"
738#define fsck_minix_full_usage \
739 "Performs a consistency check for MINIX filesystems.\n\n" \
740 "Options:\n" \
741 "\t-l\tLists all filenames\n" \
742 "\t-r\tPerform interactive repairs\n" \
743 "\t-a\tPerform automatic repairs\n" \
744 "\t-v\tverbose\n" \
745 "\t-s\tOutputs super-block information\n" \
746 "\t-m\tActivates MINIX-like \"mode not cleared\" warnings\n" \
747 "\t-f\tForce file system check."
748
749#define ftpget_trivial_usage \
750 "[options] remote-host local-file remote-file"
751#define ftpget_full_usage \
752 "Retrieve a remote file via FTP.\n\n" \
753 "Options:\n" \
754 "\t-c, --continue Continue a previous transfer\n" \
755 "\t-v, --verbose Verbose\n" \
756 "\t-u, --username Username to be used\n" \
757 "\t-p, --password Password to be used\n" \
758 "\t-P, --port Port number to be used"
759
760#define ftpput_trivial_usage \
761 "[options] remote-host remote-file local-file"
762#define ftpput_full_usage \
763 "Store a local file on a remote machine via FTP.\n\n" \
764 "Options:\n" \
765 "\t-v, --verbose Verbose\n" \
766 "\t-u, --username Username to be used\n" \
767 "\t-p, --password Password to be used\n" \
768 "\t-P, --port Port number to be used"
769
770#define getopt_trivial_usage \
771 "[OPTIONS]..."
772#define getopt_full_usage \
773 "Parse command options\n" \
774 "\t-a, --alternative Allow long options starting with single -\n" \
775 "\t-l, --longoptions=longopts Long options to be recognized\n" \
776 "\t-n, --name=progname The name under which errors are reported\n" \
777 "\t-o, --options=optstring Short options to be recognized\n" \
778 "\t-q, --quiet Disable error reporting by getopt(3)\n" \
779 "\t-Q, --quiet-output No normal output\n" \
780 "\t-s, --shell=shell Set shell quoting conventions\n" \
781 "\t-T, --test Test for getopt(1) version\n" \
782 "\t-u, --unquoted Do not quote the output"
783#define getopt_example_usage \
784 "$ cat getopt.test\n" \
785 "#!/bin/sh\n" \
786 "GETOPT=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \\\n" \
787 " -n 'example.busybox' -- "$@"`\n" \
788 "if [ $? != 0 ] ; then exit 1 ; fi\n" \
789 "eval set -- "$GETOPT"\n" \
790 "while true ; do\n" \
791 " case $1 in\n" \
792 " -a|--a-long) echo \"Option a\" ; shift ;;\n" \
793 " -b|--b-long) echo \"Option b, argument `$2'\" ; shift 2 ;;\n" \
794 " -c|--c-long)\n" \
795 " case "$2" in\n" \
796 " \"\") echo \"Option c, no argument\"; shift 2 ;;\n" \
797 " *) echo \"Option c, argument `$2'\" ; shift 2 ;;\n" \
798 " esac ;;\n" \
799 " --) shift ; break ;;\n" \
800 " *) echo \"Internal error!\" ; exit 1 ;;\n" \
801 " esac\n" \
802 "done\n"
803
804
805#define getpkg_trivial_usage \
806 "[-afk] [PACKAGE] {[URL] | [DIR]}"
807#define getpkg_full_usage \
808 "Install a Trinux PACKAGE from a FILE or an URL ." \
809 "\t-a,\t\tget all packages\n" \
810 "\t-f,\t\tpackage file, no need to download\n" \
811 "\t-k,\t\tkernel package"
812#define getpkg_example_usage \
813 "$ getpkg\n" \
814 "$ getpkg -a\n" \
815 "$ getpkg -f name\n" \
816 "$ getpkg -fk name /media/cdrom/trinux/pkg\n" \
817 "$ getpkg -k name\n" \
818 "$ getpkg name http://www.trinux.org/pkg/\n"
819
820
821#define getty_trivial_usage \
822 "[OPTIONS]... baud_rate,... line [termtype]"
823#define getty_full_usage \
824 "Opens a tty, prompts for a login name, then invokes /bin/login\n\n" \
825 "Options:\n" \
826 "\t-h\t\tEnable hardware (RTS/CTS) flow control.\n" \
827 "\t-i\t\tDo not display /etc/issue before running login.\n" \
828 "\t-L\t\tLocal line, so do not do carrier detect.\n" \
829 "\t-m\t\tGet baud rate from modem's CONNECT status message.\n" \
830 "\t-w\t\tWait for a CR or LF before sending /etc/issue.\n" \
831 "\t-n\t\tDo not prompt the user for a login name.\n" \
832 "\t-f issue_file\tDisplay issue_file instead of /etc/issue.\n" \
833 "\t-l login_app\tInvoke login_app instead of /bin/login.\n" \
834 "\t-t timeout\tTerminate after timeout if no username is read.\n" \
835 "\t-I initstring\tSets the init string to send before anything else.\n" \
836 "\t-H login_host\tLog login_host into the utmp file as the hostname."
837
838
839#define grep_trivial_usage \
840 "[-ihHnqvs] PATTERN [FILEs...]"
841#define grep_full_usage \
842 "Search for PATTERN in each FILE or standard input.\n\n" \
843 "Options:\n" \
844 "\t-H\tprefix output lines with filename where match was found\n" \
845 "\t-h\tsuppress the prefixing filename on output\n" \
846 "\t-i\tignore case distinctions\n" \
847 "\t-l\tlist names of files that match\n" \
848 "\t-n\tprint line number with output lines\n" \
849 "\t-q\tbe quiet. Returns 0 if result was found, 1 otherwise\n" \
850 "\t-v\tselect non-matching lines\n" \
851 "\t-s\tsuppress file open/read error messages"
852#define grep_example_usage \
853 "$ grep root /etc/passwd\n" \
854 "root:x:0:0:root:/root:/bin/bash\n" \
855 "$ grep ^[rR]oo. /etc/passwd\n" \
856 "root:x:0:0:root:/root:/bin/bash\n"
857
858#define gunzip_trivial_usage \
859 "[OPTION]... FILE"
860#define gunzip_full_usage \
861 "Uncompress FILE (or standard input if FILE is '-').\n\n" \
862 "Options:\n" \
863 "\t-c\tWrite output to standard output\n" \
864 "\t-f\tForce read when source is a terminal\n" \
865 "\t-t\tTest compressed file integrity"
866#define gunzip_example_usage \
867 "$ ls -la /tmp/BusyBox*\n" \
868 "-rw-rw-r-- 1 andersen andersen 557009 Apr 11 10:55 /tmp/BusyBox-0.43.tar.gz\n" \
869 "$ gunzip /tmp/BusyBox-0.43.tar.gz\n" \
870 "$ ls -la /tmp/BusyBox*\n" \
871 "-rw-rw-r-- 1 andersen andersen 1761280 Apr 14 17:47 /tmp/BusyBox-0.43.tar\n"
872
873#define gzip_trivial_usage \
874 "[OPTION]... [FILE]..."
875#define gzip_full_usage \
876 "Compress FILE(s) with maximum compression.\n" \
877 "When FILE is '-' or unspecified, reads standard input. Implies -c.\n\n" \
878 "Options:\n" \
879 "\t-c\tWrite output to standard output instead of FILE.gz\n" \
880 "\t-d\tDecompress\n" \
881 "\t-f\tForce write when destination is a terminal"
882#define gzip_example_usage \
883 "$ ls -la /tmp/busybox*\n" \
884 "-rw-rw-r-- 1 andersen andersen 1761280 Apr 14 17:47 /tmp/busybox.tar\n" \
885 "$ gzip /tmp/busybox.tar\n" \
886 "$ ls -la /tmp/busybox*\n" \
887 "-rw-rw-r-- 1 andersen andersen 554058 Apr 14 17:49 /tmp/busybox.tar.gz\n"
888
889#define halt_trivial_usage \
890 "[-d<delay>]"
891#define halt_full_usage \
892 "Halt the system.\n" \
893 "Options:\n" \
894 "\t-d\t\tdelay interval for halting."
895
896#ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY
897#define USAGE_HDPARM_IDENT(a) a
898#else
899#define USAGE_HDPARM_IDENT(a)
900#endif
901
902#ifdef CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF
903#define USAGE_SCAN_HWIF(a) a
904#else
905#define USAGE_SCAN_HWIF(a)
906#endif
907
908#ifdef CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
909#define USAGE_UNREGISTER_HWIF(a) a
910#else
911#define USAGE_UNREGISTER_HWIF(a)
912#endif
913
914#ifdef CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET
915#define USAGE_DRIVE_RESET(a) a
916#else
917#define USAGE_DRIVE_RESET(a)
918#endif
919
920#ifdef CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
921#define USAGE_TRISTATE_HWIF(a) a
922#else
923#define USAGE_TRISTATE_HWIF(a)
924#endif
925
926#ifdef CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA
927#define USAGE_GETSET_DMA(a) a
928#else
929#define USAGE_GETSET_DMA(a)
930#endif
931
932#define hdparm_trivial_usage \
933 "[options] [device] .."
934#define hdparm_full_usage \
935 "Options:" \
936 "\t-a get/set fs readahead\n" \
937 "\t-A set drive read-lookahead flag (0/1)\n" \
938 "\t-b get/set bus state (0 == off, 1 == on, 2 == tristate)\n" \
939 "\t-B set Advanced Power Management setting (1-255)\n" \
940 "\t-c get/set IDE 32-bit IO setting\n" \
941 "\t-C check IDE power mode status\n" \
942 USAGE_GETSET_DMA("\t-d get/set using_dma flag\n") \
943 "\t-D enable/disable drive defect-mgmt\n" \
944 "\t-f flush buffer cache for device on exit\n" \
945 "\t-g display drive geometry\n" \
946 "\t-h display terse usage information\n" \
947 "\t-i display drive identification\n" \
948 USAGE_HDPARM_IDENT("\t-I detailed/current information directly from drive\n") \
949 USAGE_HDPARM_IDENT("\t-Istdin similar to -I, but wants /proc/ide/" "*" "/hd?/identify as input\n") \
950 "\t-k get/set keep_settings_over_reset flag (0/1)\n" \
951 "\t-K set drive keep_features_over_reset flag (0/1)\n" \
952 "\t-L set drive doorlock (0/1) (removable harddisks only)\n" \
953 "\t-m get/set multiple sector count\n" \
954 "\t-n get/set ignore-write-errors flag (0/1)\n" \
955 "\t-p set PIO mode on IDE interface chipset (0,1,2,3,4,...)\n" \
956 "\t-P set drive prefetch count\n" \
957 "\t-q change next setting quietly\n" \
958 "\t-Q get/set DMA tagged-queuing depth (if supported)\n" \
959 "\t-r get/set readonly flag (DANGEROUS to set)\n" \
960 USAGE_SCAN_HWIF("\t-R register an IDE interface (DANGEROUS)\n") \
961 "\t-S set standby (spindown) timeout\n" \
962 "\t-t perform device read timings\n" \
963 "\t-T perform cache read timings\n" \
964 "\t-u get/set unmaskirq flag (0/1)\n" \
965 USAGE_UNREGISTER_HWIF("\t-U un-register an IDE interface (DANGEROUS)\n") \
966 "\t-v defaults; same as -mcudkrag for IDE drives\n" \
967 "\t-V display program version and exit immediately\n" \
968 USAGE_DRIVE_RESET("\t-w perform device reset (DANGEROUS)\n") \
969 "\t-W set drive write-caching flag (0/1) (DANGEROUS)\n" \
970 USAGE_TRISTATE_HWIF("\t-x tristate device for hotswap (0/1) (DANGEROUS)\n") \
971 "\t-X set IDE xfer mode (DANGEROUS)\n" \
972 "\t-y put IDE drive in standby mode\n" \
973 "\t-Y put IDE drive to sleep\n" \
974 "\t-Z disable Seagate auto-powersaving mode\n" \
975 "\t-z re-read partition table"
976
977#ifdef CONFIG_FEATURE_FANCY_HEAD
978#define USAGE_FANCY_HEAD(a) a
979#else
980#define USAGE_FANCY_HEAD(a)
981#endif
982
983#define head_trivial_usage \
984 "[OPTION]... [FILE]..."
985#define head_full_usage \
986 "Print first 10 lines of each FILE to standard output.\n" \
987 "With more than one FILE, precede each with a header giving the\n" \
988 "file name. With no FILE, or when FILE is -, read standard input.\n\n" \
989 "Options:\n" \
990 "\t-n NUM\t\tPrint first NUM lines instead of first 10" \
991 USAGE_FANCY_HEAD( \
992 "\n\t-c NUM\t\toutput the first NUM bytes\n" \
993 "\t-q\t\tnever output headers giving file names\n" \
994 "\t-v\t\talways output headers giving file names" )
995#define head_example_usage \
996 "$ head -n 2 /etc/passwd\n" \
997 "root:x:0:0:root:/root:/bin/bash\n" \
998 "daemon:x:1:1:daemon:/usr/sbin:/bin/sh\n"
999
1000#define hexdump_trivial_usage \
1001 "[-[bcdefnosvx]] [OPTION] FILE"
1002#define hexdump_full_usage \
1003 "The hexdump utility is a filter which displays the specified files,\n" \
1004 "or the standard input, if no files are specified, in a user specified\n"\
1005 "format\n" \
1006 "\t-b\t\tOne-byte octal display\n" \
1007 "\t-c\t\tOne-byte character display\n" \
1008 "\t-d\t\tTwo-byte decimal display\n" \
1009 "\t-e FORMAT STRING\n" \
1010 "\t-f FORMAT FILE\n" \
1011 "\t-n LENGTH\tInterpret only length bytes of input\n" \
1012 "\t-o\t\tTwo-byte octal display\n" \
1013 "\t-s OFFSET\tSkip offset byte\n" \
1014 "\t-v\t\tdisplay all input data\n" \
1015 "\t-x\t\tTwo-byte hexadecimal display"
1016
1017#define hostid_trivial_usage \
1018 ""
1019#define hostid_full_usage \
1020 "Print out a unique 32-bit identifier for the machine."
1021
1022#define hostname_trivial_usage \
1023 "[OPTION] {hostname | -F FILE}"
1024#define hostname_full_usage \
1025 "Get or set the hostname or DNS domain name. If a hostname is given\n" \
1026 "(or FILE with the -F parameter), the host name will be set.\n\n" \
1027 "Options:\n" \
1028 "\t-s\tShort\n" \
1029 "\t-i\tAddresses for the hostname\n" \
1030 "\t-d\tDNS domain name\n" \
1031 "\t-f\tFully qualified domain name\n" \
1032 "\t-F FILE\tUse the contents of FILE to specify the hostname"
1033#define hostname_example_usage \
1034 "$ hostname\n" \
1035 "sage\n"
1036
1037#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
1038 #define USAGE_HTTPD_BASIC_AUTH(a) a
1039 #ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
1040 #define USAGE_HTTPD_AUTH_MD5(a) a
1041 #else
1042 #define USAGE_HTTPD_AUTH_MD5(a)
1043 #endif
1044#else
1045 #define USAGE_HTTPD_BASIC_AUTH(a)
1046 #define USAGE_HTTPD_AUTH_MD5(a)
1047#endif
1048#ifdef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
1049 #define USAGE_HTTPD_STANDALONE(a)
1050 #define USAGE_HTTPD_SETUID(a)
1051#else
1052 #define USAGE_HTTPD_STANDALONE(a) a
1053 #ifdef CONFIG_FEATURE_HTTPD_SETUID
1054 #define USAGE_HTTPD_SETUID(a) a
1055 #else
1056 #define USAGE_HTTPD_SETUID(a)
1057 #endif
1058#endif
1059#define httpd_trivial_usage \
1060 "[-c <conf file>]" \
1061 USAGE_HTTPD_STANDALONE(" [-p <port>]") \
1062 USAGE_HTTPD_SETUID(" [-u user]") \
1063 USAGE_HTTPD_BASIC_AUTH(" [-r <realm>]") \
1064 USAGE_HTTPD_AUTH_MD5(" [-m pass]") \
1065 " [-h home]" \
1066 " [-d/-e <string>]"
1067#define httpd_full_usage \
1068 "Listens for incoming http server requests.\n\n"\
1069 "Options:\n" \
1070 "\t-c FILE\t\tSpecifies configuration file. (default httpd.conf)\n" \
1071 USAGE_HTTPD_STANDALONE("\t-p PORT\tServer port (default 80)\n") \
1072 USAGE_HTTPD_SETUID("\t-u USER\tSet uid to USER after listening privileges port\n") \
1073 USAGE_HTTPD_BASIC_AUTH("\t-r REALM\tAuthentication Realm for Basic Authentication\n") \
1074 USAGE_HTTPD_AUTH_MD5("\t-m PASS\t\tCrypt PASS with md5 algorithm\n") \
1075 "\t-h HOME \tSpecifies http HOME directory (default ./)\n" \
1076 "\t-e STRING\tHtml encode STRING\n" \
1077 "\t-d STRING\tURL decode STRING"
1078
1079#define hwclock_trivial_usage \
1080 "[-r|--show] [-s|--hctosys] [-w|--systohc] [-l|--localtime] [-u|--utc]"
1081#define hwclock_full_usage \
1082 "Query and set the hardware clock (RTC)\n\n" \
1083 "Options:\n" \
1084 "\t-r\tread hardware clock and print result\n" \
1085 "\t-s\tset the system time from the hardware clock\n" \
1086 "\t-w\tset the hardware clock to the current system time\n" \
1087 "\t-u\tthe hardware clock is kept in coordinated universal time\n" \
1088 "\t-l\tthe hardware clock is kept in local time"
1089
1090#ifdef CONFIG_SELINUX
1091 #define USAGE_SELINUX(a) a
1092#else
1093 #define USAGE_SELINUX(a)
1094#endif
1095
1096#define id_trivial_usage \
1097 "[OPTIONS]... [USERNAME]"
1098#define id_full_usage \
1099 "Print information for USERNAME or the current user\n\n" \
1100 "Options:\n" \
1101 USAGE_SELINUX("\t-c\tprints only the security context\n") \
1102 "\t-g\tprints only the group ID\n" \
1103 "\t-u\tprints only the user ID\n" \
1104 "\t-n\tprint a name instead of a number\n" \
1105 "\t-r\tprints the real user ID instead of the effective ID"
1106#define id_example_usage \
1107 "$ id\n" \
1108 "uid=1000(andersen) gid=1000(andersen)\n"
1109
1110#ifdef CONFIG_FEATURE_IFCONFIG_SLIP
1111 #define USAGE_SIOCSKEEPALIVE(a) a
1112#else
1113 #define USAGE_SIOCSKEEPALIVE(a)
1114#endif
1115#ifdef CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
1116 #define USAGE_IFCONFIG_MII(a) a
1117#else
1118 #define USAGE_IFCONFIG_MII(a)
1119#endif
1120#ifdef CONFIG_FEATURE_IFCONFIG_HW
1121 #define USAGE_IFCONFIG_HW(a) a
1122#else
1123 #define USAGE_IFCONFIG_HW(a)
1124#endif
1125#ifdef CONFIG_FEATURE_IFCONFIG_STATUS
1126 #define USAGE_IFCONFIG_OPT_A(a) a
1127#else
1128 #define USAGE_IFCONFIG_OPT_A(a)
1129#endif
1130#ifdef CONFIG_FEATURE_IPV6
1131 #define USAGE_IPV6(a) a
1132#else
1133 #define USAGE_IPV6(a)
1134#endif
1135
1136#define ifconfig_trivial_usage \
1137 USAGE_IFCONFIG_OPT_A("[-a]") " <interface> [<address>]"
1138#define ifconfig_full_usage \
1139 "configure a network interface\n\n" \
1140 "Options:\n" \
1141 USAGE_IPV6("[add <address>[/<prefixlen>]]\n") \
1142 USAGE_IPV6("[del <address>[/<prefixlen>]]\n") \
1143 "\t[[-]broadcast [<address>]] [[-]pointopoint [<address>]]\n" \
1144 "\t[netmask <address>] [dstaddr <address>]\n" \
1145 USAGE_SIOCSKEEPALIVE("\t[outfill <NN>] [keepalive <NN>]\n") \
1146 "\t" USAGE_IFCONFIG_HW("[hw ether <address>] ") \
1147 "[metric <NN>] [mtu <NN>]\n" \
1148 "\t[[-]trailers] [[-]arp] [[-]allmulti]\n" \
1149 "\t[multicast] [[-]promisc] [txqueuelen <NN>] [[-]dynamic]\n" \
1150 USAGE_IFCONFIG_MII("\t[mem_start <NN>] [io_addr <NN>] [irq <NN>]\n") \
1151 "\t[up|down] ..."
1152
1153#define ifup_trivial_usage \
1154 "<-ahinv> <ifaces...>"
1155#define ifup_full_usage \
1156 "ifup <options> <ifaces...>\n\n" \
1157 "Options:\n" \
1158 "\t-h\tthis help\n" \
1159 "\t-a\tde/configure all interfaces automatically\n" \
1160 "\t-i FILE\tuse FILE for interface definitions\n" \
1161 "\t-n\tprint out what would happen, but don't do it\n" \
1162 "\t\t\t(note that this option doesn't disable mappings)\n" \
1163 "\t-v\tprint out what would happen before doing it\n" \
1164 "\t-m\tdon't run any mappings\n" \
1165 "\t-f\tforce de/configuration"
1166
1167#define ifdown_trivial_usage \
1168 "<-ahinv> <ifaces...>"
1169#define ifdown_full_usage \
1170 "ifdown <options> <ifaces...>\n\n" \
1171 "Options:\n" \
1172 "\t-h\tthis help\n" \
1173 "\t-a\tde/configure all interfaces automatically\n" \
1174 "\t-i FILE\tuse FILE for interface definitions\n" \
1175 "\t-n\tprint out what would happen, but don't do it\n" \
1176 "\t\t(note that this option doesn't disable mappings)\n" \
1177 "\t-v\tprint out what would happen before doing it\n" \
1178 "\t-m\tdon't run any mappings\n" \
1179 "\t-f\tforce de/configuration"
1180
1181#define inetd_trivial_usage \
1182 "[-q len] [conf]"
1183#define inetd_full_usage \
1184 "Listens for network connections and launches programs\n\n" \
1185 "Option:\n" \
1186 "\t-q\tSets the size of the socket listen queue to\n" \
1187 "\t\tthe specified value. Default is 128."
1188
1189#define init_trivial_usage \
1190 ""
1191#define init_full_usage \
1192 "Init is the parent of all processes."
1193#define init_notes_usage \
1194"This version of init is designed to be run only by the kernel.\n" \
1195"\n" \
1196"BusyBox init doesn't support multiple runlevels. The runlevels field of\n" \
1197"the /etc/inittab file is completely ignored by BusyBox init. If you want \n" \
1198"runlevels, use sysvinit.\n" \
1199"\n" \
1200"BusyBox init works just fine without an inittab. If no inittab is found, \n" \
1201"it has the following default behavior:\n" \
1202"\n" \
1203" ::sysinit:/etc/init.d/rcS\n" \
1204" ::askfirst:/bin/sh\n" \
1205" ::ctrlaltdel:/sbin/reboot\n" \
1206" ::shutdown:/sbin/swapoff -a\n" \
1207" ::shutdown:/bin/umount -a -r\n" \
1208" ::restart:/sbin/init\n" \
1209"\n" \
1210"if it detects that /dev/console is _not_ a serial console, it will also run:\n" \
1211"\n" \
1212" tty2::askfirst:/bin/sh\n" \
1213" tty3::askfirst:/bin/sh\n" \
1214" tty4::askfirst:/bin/sh\n" \
1215"\n" \
1216"If you choose to use an /etc/inittab file, the inittab entry format is as follows:\n" \
1217"\n" \
1218" <id>:<runlevels>:<action>:<process>\n" \
1219"\n" \
1220" <id>:\n" \
1221"\n" \
1222" WARNING: This field has a non-traditional meaning for BusyBox init!\n" \
1223" The id field is used by BusyBox init to specify the controlling tty for\n" \
1224" the specified process to run on. The contents of this field are\n" \
1225" appended to "/dev/" and used as-is. There is no need for this field to\n" \
1226" be unique, although if it isn't you may have strange results. If this\n" \
1227" field is left blank, the controlling tty is set to the console. Also\n" \
1228" note that if BusyBox detects that a serial console is in use, then only\n" \
1229" entries whose controlling tty is either the serial console or /dev/null\n" \
1230" will be run. BusyBox init does nothing with utmp. We don't need no\n" \
1231" stinkin' utmp.\n" \
1232"\n" \
1233" <runlevels>:\n" \
1234"\n" \
1235" The runlevels field is completely ignored.\n" \
1236"\n" \
1237" <action>:\n" \
1238"\n" \
1239" Valid actions include: sysinit, respawn, askfirst, wait,\n" \
1240" once, restart, ctrlaltdel, and shutdown.\n" \
1241"\n" \
1242" The available actions can be classified into two groups: actions\n" \
1243" that are run only once, and actions that are re-run when the specified\n" \
1244" process exits.\n" \
1245"\n" \
1246" Run only-once actions:\n" \
1247"\n" \
1248" 'sysinit' is the first item run on boot. init waits until all\n" \
1249" sysinit actions are completed before continuing. Following the\n" \
1250" completion of all sysinit actions, all 'wait' actions are run.\n" \
1251" 'wait' actions, like 'sysinit' actions, cause init to wait until\n" \
1252" the specified task completes. 'once' actions are asynchronous,\n" \
1253" therefore, init does not wait for them to complete. 'restart' is\n" \
1254" the action taken to restart the init process. By default this should\n" \
1255" simply run /sbin/init, but can be a script which runs pivot_root or it\n" \
1256" can do all sorts of other interesting things. The 'ctrlaltdel' init\n" \
1257" actions are run when the system detects that someone on the system\n" \
1258" console has pressed the CTRL-ALT-DEL key combination. Typically one\n" \
1259" wants to run 'reboot' at this point to cause the system to reboot.\n" \
1260" Finally the 'shutdown' action specifies the actions to taken when\n" \
1261" init is told to reboot. Unmounting filesystems and disabling swap\n" \
1262" is a very good here\n" \
1263"\n" \
1264" Run repeatedly actions:\n" \
1265"\n" \
1266" 'respawn' actions are run after the 'once' actions. When a process\n" \
1267" started with a 'respawn' action exits, init automatically restarts\n" \
1268" it. Unlike sysvinit, BusyBox init does not stop processes from\n" \
1269" respawning out of control. The 'askfirst' actions acts just like\n" \
1270" respawn, except that before running the specified process it\n" \
1271" displays the line "Please press Enter to activate this console."\n" \
1272" and then waits for the user to press enter before starting the\n" \
1273" specified process.\n" \
1274"\n" \
1275" Unrecognized actions (like initdefault) will cause init to emit an\n" \
1276" error message, and then go along with its business. All actions are\n" \
1277" run in the order they appear in /etc/inittab.\n" \
1278"\n" \
1279" <process>:\n" \
1280"\n" \
1281" Specifies the process to be executed and its command line.\n" \
1282"\n" \
1283"Example /etc/inittab file:\n" \
1284"\n" \
1285" # This is run first except when booting in single-user mode.\n" \
1286" #\n" \
1287" ::sysinit:/etc/init.d/rcS\n" \
1288" \n" \
1289" # /bin/sh invocations on selected ttys\n" \
1290" #\n" \
1291" # Start an "askfirst" shell on the console (whatever that may be)\n" \
1292" ::askfirst:-/bin/sh\n" \
1293" # Start an "askfirst" shell on /dev/tty2-4\n" \
1294" tty2::askfirst:-/bin/sh\n" \
1295" tty3::askfirst:-/bin/sh\n" \
1296" tty4::askfirst:-/bin/sh\n" \
1297" \n" \
1298" # /sbin/getty invocations for selected ttys\n" \
1299" #\n" \
1300" tty4::respawn:/sbin/getty 38400 tty4\n" \
1301" tty5::respawn:/sbin/getty 38400 tty5\n" \
1302" \n" \
1303" \n" \
1304" # Example of how to put a getty on a serial line (for a terminal)\n" \
1305" #\n" \
1306" #::respawn:/sbin/getty -L ttyS0 9600 vt100\n" \
1307" #::respawn:/sbin/getty -L ttyS1 9600 vt100\n" \
1308" #\n" \
1309" # Example how to put a getty on a modem line.\n" \
1310" #::respawn:/sbin/getty 57600 ttyS2\n" \
1311" \n" \
1312" # Stuff to do when restarting the init process\n" \
1313" ::restart:/sbin/init\n" \
1314" \n" \
1315" # Stuff to do before rebooting\n" \
1316" ::ctrlaltdel:/sbin/reboot\n" \
1317" ::shutdown:/bin/umount -a -r\n" \
1318" ::shutdown:/sbin/swapoff -a\n"
1319
1320#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
1321 #define USAGE_INSMOD_MAP(a) a
1322#else
1323 #define USAGE_INSMOD_MAP(a)
1324#endif
1325#define insmod_trivial_usage \
1326 "[OPTION]... MODULE [symbol=value]..."
1327#define insmod_full_usage \
1328 "Loads the specified kernel modules into the kernel.\n\n" \
1329 "Options:\n" \
1330 "\t-f\tForce module to load into the wrong kernel version.\n" \
1331 "\t-k\tMake module autoclean-able.\n" \
1332 "\t-v\tverbose output\n" \
1333 "\t-q\tquiet output\n" \
1334 "\t-L\tLock to prevent simultaneous loads of a module\n" \
1335 USAGE_INSMOD_MAP("\t-m\tOutput load map to stdout\n") \
1336 "\t-o NAME\tSet internal module name to NAME\n" \
1337 "\t-x\tdo not export externs"
1338
1339#define install_trivial_usage \
1340 "[-cgmops] [sources] <dest|directory>"
1341#define install_full_usage \
1342 "Copies files and set attributes\n\n" \
1343 "Options:\n" \
1344 "\t-c\tcopy the file, default\n" \
1345 "\t-d\tcreate directories\n" \
1346 "\t-g\tset group ownership\n" \
1347 "\t-m\tset permission modes\n" \
1348 "\t-o\tset ownership\n" \
1349 "\t-p\tpreserve date\n" \
1350 "\t-s\tstrip symbol tables"
1351
1352
1353#define install_initd_trivial_usage \
1354 ""
1355#define install_initd_full_usage \
1356 "LSB install_initd init system."
1357#define install_initd_example_usage \
1358 "$ install_initd start\n"
1359
1360
1361#define ip_trivial_usage \
1362 "[ OPTIONS ] { address | link | route | tunnel } { COMMAND | help }"
1363#define ip_full_usage \
1364 "ip [ OPTIONS ] OBJECT { COMMAND | help }\n" \
1365 "where OBJECT := { link | addr | route | tunnel }\n" \
1366 "OPTIONS := { -f[amily] { inet | inet6 | link } | -o[neline] }"
1367
1368#define ipaddr_trivial_usage \
1369 "{ {add|del} IFADDR dev STRING | {show|flush}\n" \
1370 "\t\t[ dev STRING ] [ to PREFIX ] }"
1371#define ipaddr_full_usage \
1372 "ipaddr {add|del} IFADDR dev STRING\n" \
1373 "ipaddr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n" \
1374 "\t\t\t[ to PREFIX ] [ label PATTERN ]\n" \
1375 "\t\t\tIFADDR := PREFIX | ADDR peer PREFIX\n" \
1376 "\t\t\t[ broadcast ADDR ] [ anycast ADDR ]\n" \
1377 "\t\t\t[ label STRING ] [ scope SCOPE-ID ]\n" \
1378 "\t\t\tSCOPE-ID := [ host | link | global | NUMBER ]"
1379
1380#ifdef CONFIG_FEATURE_IPCALC_FANCY
1381 #define XUSAGE_IPCALC_FANCY(a) a
1382#else
1383 #define XUSAGE_IPCALC_FANCY(a)
1384#endif
1385#define ipcalc_trivial_usage \
1386 "[OPTION]... <ADDRESS>[[/]<NETMASK>] [NETMASK]"
1387#define ipcalc_full_usage \
1388 "Calculate IP network settings from a IP address\n\n" \
1389 "Options:\n" \
1390 "\t-b\t--broadcast\tDisplay calculated broadcast address.\n" \
1391 "\t-n\t--network\tDisplay calculated network address.\n" \
1392 "\t-m\t--netmask\tDisplay default netmask for IP." \
1393 XUSAGE_IPCALC_FANCY(\
1394 "\n\t-p\t--prefix\tDisplay the prefix for IP/NETMASK." \
1395 "\t-h\t--hostname\tDisplay first resolved host name.\n" \
1396 "\t-s\t--silent\tDon't ever display error messages.")
1397
1398#define iplink_trivial_usage \
1399 "{ set DEVICE { up | down | arp { on | off } | show [ DEVICE ] }"
1400#define iplink_full_usage \
1401 "iplink set DEVICE { up | down | arp { on | off } |\n" \
1402 "\t\t\tdynamic { on | off } |\n" \
1403 "\t\t\tmtu MTU }\n" \
1404 "\tiplink show [ DEVICE ]"
1405
1406#define iproute_trivial_usage \
1407 "{ list | flush | { add | del | change | append |\n" \
1408 "\t\treplace | monitor } ROUTE }"
1409#define iproute_full_usage \
1410 "iproute { list | flush } SELECTOR\n" \
1411 "iproute get ADDRESS [ from ADDRESS iif STRING ]\n" \
1412 "\t\t\t[ oif STRING ] [ tos TOS ]\n" \
1413 "\tiproute { add | del | change | append | replace | monitor } ROUTE\n" \
1414 "\t\t\tSELECTOR := [ root PREFIX ] [ match PREFIX ] [ proto RTPROTO ]\n" \
1415 "\t\t\tROUTE := [ TYPE ] PREFIX [ tos TOS ] [ proto RTPROTO ]"
1416
1417#define iptunnel_trivial_usage \
1418 "{ add | change | del | show } [ NAME ]\n" \
1419 "\t\t[ mode { ipip | gre | sit } ]\n" \
1420 "\t\t[ remote ADDR ] [ local ADDR ] [ ttl TTL ]"
1421#define iptunnel_full_usage \
1422 "iptunnel { add | change | del | show } [ NAME ]\n" \
1423 "\t\t\t[ mode { ipip | gre | sit } ] [ remote ADDR ] [ local ADDR ]\n" \
1424 "\t\t\t[ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n" \
1425 "\t\t\t[ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]"
1426
1427#define kill_trivial_usage \
1428 "[-signal] process-id [process-id ...]"
1429#define kill_full_usage \
1430 "Send a signal (default is SIGTERM) to the specified process(es).\n\n"\
1431 "Options:\n" \
1432 "\t-l\tList all signal names and numbers."
1433#define kill_example_usage \
1434 "$ ps | grep apache\n" \
1435 "252 root root S [apache]\n" \
1436 "263 www-data www-data S [apache]\n" \
1437 "264 www-data www-data S [apache]\n" \
1438 "265 www-data www-data S [apache]\n" \
1439 "266 www-data www-data S [apache]\n" \
1440 "267 www-data www-data S [apache]\n" \
1441 "$ kill 252\n"
1442
1443#define killall_trivial_usage \
1444 "[-q] [-signal] process-name [process-name ...]"
1445#define killall_full_usage \
1446 "Send a signal (default is SIGTERM) to the specified process(es).\n\n"\
1447 "Options:\n" \
1448 "\t-l\tList all signal names and numbers.\n"\
1449 "\t-q\tDo not complain if no processes were killed."
1450#define killall_example_usage \
1451 "$ killall apache\n"
1452
1453#define killproc_trivial_usage \
1454 ""
1455#define killproc_full_usage \
1456 "LSB killproc."
1457#define killproc_example_usage \
1458 "$ killproc 5\n"
1459
1460
1461#define klogd_trivial_usage \
1462 "[-c n] [-n]"
1463#define klogd_full_usage \
1464 "Kernel logger.\n"\
1465 "Options:\n"\
1466 "\t-c n\tSets the default log level of console messages to n.\n"\
1467 "\t-n\tRun as a foreground process."
1468
1469#define length_trivial_usage \
1470 "STRING"
1471#define length_full_usage \
1472 "Prints out the length of the specified STRING."
1473#define length_example_usage \
1474 "$ length Hello\n" \
1475 "5\n"
1476
1477#define linuxrc_trivial_usage \
1478 ""
1479#define linuxrc_full_usage \
1480 "linuxrc pre boot."
1481#define linuxrc_example_usage \
1482 "$ linuxrc\n"
1483
1484
1485#define ln_trivial_usage \
1486 "[OPTION] TARGET... LINK_NAME|DIRECTORY"
1487#define ln_full_usage \
1488 "Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n"\
1489 "\nYou may use '--' to indicate that all following arguments are non-options.\n\n" \
1490 "Options:\n" \
1491 "\t-s\tmake symbolic links instead of hard links\n" \
1492 "\t-f\tremove existing destination files\n" \
1493 "\t-n\tno dereference symlinks - treat like normal file"
1494#define ln_example_usage \
1495 "$ ln -s BusyBox /tmp/ls\n" \
1496 "$ ls -l /tmp/ls\n" \
1497 "lrwxrwxrwx 1 root root 7 Apr 12 18:39 ls -> BusyBox*\n"
1498
1499#define loadfont_trivial_usage \
1500 "< font"
1501#define loadfont_full_usage \
1502 "Loads a console font from standard input."
1503#define loadfont_example_usage \
1504 "$ loadfont < /etc/i18n/fontname\n"
1505
1506#define loadkmap_trivial_usage \
1507 "< keymap"
1508#define loadkmap_full_usage \
1509 "Loads a binary keyboard translation table from standard input."
1510#define loadkmap_example_usage \
1511 "$ loadkmap < /etc/i18n/lang-keymap\n"
1512
1513#define local_fs_trivial_usage \
1514 ""
1515#define local_fs_full_usage \
1516 "LSB local_fs init system."
1517#define local_fs_example_usage \
1518 "$ local_fs start\n"
1519
1520
1521#define log_failure_msg_trivial_usage \
1522 ""
1523#define log_failure_msg_full_usage \
1524 "LSB log_failure_msg."
1525#define log_failure_msg_example_usage \
1526 "$ log_failure_msg ""\n"
1527
1528
1529#define log_success_msg_trivial_usage \
1530 ""
1531#define log_success_msg_full_usage \
1532 "LSB log_success_msg."
1533#define log_success_msg_example_usage \
1534 "$ log_success_msg ""\n"
1535
1536
1537#define log_warning_msg_trivial_usage \
1538 ""
1539#define log_warning_msg_full_usage \
1540 "LSB log_warning_msg."
1541#define log_warning_msg_example_usage \
1542 "$ log_warning_msg ""\n"
1543
1544
1545#define logger_trivial_usage \
1546 "[OPTION]... [MESSAGE]"
1547#define logger_full_usage \
1548 "Write MESSAGE to the system log. If MESSAGE is omitted, log stdin.\n\n" \
1549 "Options:\n" \
1550 "\t-s\tLog to stderr as well as the system log.\n" \
1551 "\t-t TAG\tLog using the specified tag (defaults to user name).\n" \
1552 "\t-p PRIORITY\tEnter the message with the specified priority.\n" \
1553 "\t\tThis may be numerical or a ``facility.level'' pair."
1554#define logger_example_usage \
1555 "$ logger "hello"\n"
1556
1557#define login_trivial_usage \
1558 "[OPTION]... [username] [ENV=VAR ...]"
1559#define login_full_usage \
1560 "Begin a new session on the system\n\n" \
1561 "Options:\n" \
1562 "\t-f\tDo not authenticate (user already authenticated)\n" \
1563 "\t-h\tName of the remote host for this login.\n" \
1564 "\t-p\tPreserve environment."
1565
1566#define logname_trivial_usage \
1567 ""
1568#define logname_full_usage \
1569 "Print the name of the current user."
1570#define logname_example_usage \
1571 "$ logname\n" \
1572 "root\n"
1573
1574#define logread_trivial_usage \
1575 "[OPTION]..."
1576#define logread_full_usage \
1577 "Shows the messages from syslogd (using circular buffer).\n\n" \
1578 "Options:\n" \
1579 "\t-f\t\toutput data as the log grows"
1580
1581#define losetup_trivial_usage \
1582 "[OPTION]... LOOPDEVICE FILE\n" \
1583 "or: losetup [OPTION]... -d LOOPDEVICE"
1584#define losetup_full_usage \
1585 "Associate LOOPDEVICE with FILE.\n\n" \
1586 "Options:\n" \
1587 "\t-d\t\tDisassociate LOOPDEVICE.\n" \
1588 "\t-o OFFSET\tStart OFFSET bytes into FILE."
1589
1590#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
1591 #define USAGE_LS_TIMESTAMPS(a) a
1592#else
1593 #define USAGE_LS_TIMESTAMPS(a)
1594#endif
1595#ifdef CONFIG_FEATURE_LS_FILETYPES
1596 #define USAGE_LS_FILETYPES(a) a
1597#else
1598 #define USAGE_LS_FILETYPES(a)
1599#endif
1600#ifdef CONFIG_FEATURE_LS_FOLLOWLINKS
1601 #define USAGE_LS_FOLLOWLINKS(a) a
1602#else
1603 #define USAGE_LS_FOLLOWLINKS(a)
1604#endif
1605#ifdef CONFIG_FEATURE_LS_RECURSIVE
1606 #define USAGE_LS_RECURSIVE(a) a
1607#else
1608 #define USAGE_LS_RECURSIVE(a)
1609#endif
1610#ifdef CONFIG_FEATURE_LS_SORTFILES
1611 #define USAGE_LS_SORTFILES(a) a
1612#else
1613 #define USAGE_LS_SORTFILES(a)
1614#endif
1615#ifdef CONFIG_FEATURE_AUTOWIDTH
1616 #define USAGE_AUTOWIDTH(a) a
1617#else
1618 #define USAGE_AUTOWIDTH(a)
1619#endif
1620
1621#define ls_trivial_usage \
1622 "[-1Aa" USAGE_LS_TIMESTAMPS("c") "Cd" USAGE_LS_TIMESTAMPS("e") USAGE_LS_FILETYPES("F") "iln" USAGE_LS_FILETYPES("p") USAGE_LS_FOLLOWLINKS("L") USAGE_LS_RECURSIVE("R") USAGE_LS_SORTFILES("rS") "s" USAGE_AUTOWIDTH("T") USAGE_LS_TIMESTAMPS("tu") USAGE_LS_SORTFILES("v") USAGE_AUTOWIDTH("w") "x" USAGE_LS_SORTFILES("X") USAGE_HUMAN_READABLE("h") USAGE_NOT_HUMAN_READABLE("") "k" USAGE_SELINUX("K") "] [filenames...]"
1623#define ls_full_usage \
1624 "List directory contents\n\n" \
1625 "Options:\n" \
1626 "\t-1\tlist files in a single column\n" \
1627 "\t-A\tdo not list implied . and ..\n" \
1628 "\t-a\tdo not hide entries starting with .\n" \
1629 "\t-C\tlist entries by columns\n" \
1630 USAGE_LS_TIMESTAMPS("\t-c\twith -l: show ctime\n") \
1631 "\t-d\tlist directory entries instead of contents\n" \
1632 USAGE_LS_TIMESTAMPS("\t-e\tlist both full date and full time\n") \
1633 USAGE_LS_FILETYPES("\t-F\tappend indicator (one of */=@|) to entries\n") \
1634 "\t-i\tlist the i-node for each file\n" \
1635 "\t-l\tuse a long listing format\n" \
1636 "\t-n\tlist numeric UIDs and GIDs instead of names\n" \
1637 USAGE_LS_FILETYPES("\t-p\tappend indicator (one of /=@|) to entries\n") \
1638 USAGE_LS_FOLLOWLINKS("\t-L\tlist entries pointed to by symbolic links\n") \
1639 USAGE_LS_RECURSIVE("\t-R\tlist subdirectories recursively\n") \
1640 USAGE_LS_SORTFILES("\t-r\tsort the listing in reverse order\n") \
1641 USAGE_LS_SORTFILES("\t-S\tsort the listing by file size\n") \
1642 "\t-s\tlist the size of each file, in blocks\n" \
1643 USAGE_AUTOWIDTH("\t-T NUM\tassume Tabstop every NUM columns\n") \
1644 USAGE_LS_TIMESTAMPS("\t-t\twith -l: show modification time\n") \
1645 USAGE_LS_TIMESTAMPS("\t-u\twith -l: show access time\n") \
1646 USAGE_LS_SORTFILES("\t-v\tsort the listing by version\n") \
1647 USAGE_AUTOWIDTH("\t-w NUM\tassume the terminal is NUM columns wide\n") \
1648 "\t-x\tlist entries by lines instead of by columns\n" \
1649 USAGE_LS_SORTFILES("\t-X\tsort the listing by extension\n") \
1650 USAGE_HUMAN_READABLE( \
1651 "\t-h\tprint sizes in human readable format (e.g., 1K 243M 2G )\n") \
1652 USAGE_SELINUX("\t-k\tprint security context\n") \
1653 USAGE_SELINUX("\t-K\tprint security context in long format\n")
1654
1655#define lsmod_trivial_usage \
1656 ""
1657#define lsmod_full_usage \
1658 "List the currently loaded kernel modules."
1659
1660#define makedevs_trivial_usage \
1661 "NAME TYPE MAJOR MINOR FIRST LAST [s]"
1662#define makedevs_full_usage \
1663 "Creates a range of block or character special files\n\n" \
1664 "TYPEs include:\n" \
1665 "\tb:\tMake a block (buffered) device.\n" \
1666 "\tc or u:\tMake a character (un-buffered) device.\n" \
1667 "\tp:\tMake a named pipe. MAJOR and MINOR are ignored for named pipes.\n\n" \
1668 "FIRST specifies the number appended to NAME to create the first device.\n" \
1669 "LAST specifies the number of the last item that should be created.\n" \
1670 "If 's' is the last argument, the base device is created as well.\n\n" \
1671 "For example:\n" \
1672 "\tmakedevs /dev/ttyS c 4 66 2 63 -> ttyS2-ttyS63\n" \
1673 "\tmakedevs /dev/hda b 3 0 0 8 s -> hda,hda1-hda8"
1674#define makedevs_example_usage \
1675 "# makedevs /dev/ttyS c 4 66 2 63\n" \
1676 "[creates ttyS2-ttyS63]\n" \
1677 "# makedevs /dev/hda b 3 0 0 8 s\n" \
1678 "[creates hda,hda1-hda8]\n"
1679
1680#define man_trivial_usage \
1681 "[NAME]"
1682#define man_full_usage \
1683 "Show documentation for Trinux software."
1684#define man_example_usage \
1685 "$ man basics\n"
1686
1687
1688#ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK
1689#define USAGE_MD5_SHA1_SUM_CHECK(a) a
1690#else
1691#define USAGE_MD5_SHA1_SUM_CHECK(a)
1692#endif
1693
1694#define md5sum_trivial_usage \
1695 "[OPTION] [FILEs...]" \
1696 USAGE_MD5_SHA1_SUM_CHECK("\n or: md5sum [OPTION] -c [FILE]")
1697#define md5sum_full_usage \
1698 "Print" USAGE_MD5_SHA1_SUM_CHECK(" or check") " MD5 checksums.\n\n" \
1699 "Options:\n" \
1700 "With no FILE, or when FILE is -, read standard input." \
1701 USAGE_MD5_SHA1_SUM_CHECK("\n\n" \
1702 "\t-c\tcheck MD5 sums against given list\n" \
1703 "\nThe following two options are useful only when verifying checksums:\n" \
1704 "\t-s\tdon't output anything, status code shows success\n" \
1705 "\t-w\twarn about improperly formated MD5 checksum lines")
1706#define md5sum_example_usage \
1707 "$ md5sum < busybox\n" \
1708 "6fd11e98b98a58f64ff3398d7b324003\n" \
1709 "$ md5sum busybox\n" \
1710 "6fd11e98b98a58f64ff3398d7b324003 busybox\n" \
1711 "$ md5sum -c -\n" \
1712 "6fd11e98b98a58f64ff3398d7b324003 busybox\n" \
1713 "busybox: OK\n" \
1714 "^D\n"
1715
1716#define mesg_trivial_usage \
1717 "[y|n]"
1718#define mesg_full_usage \
1719 "mesg controls write access to your terminal\n" \
1720 "\ty\tAllow write access to your terminal.\n" \
1721 "\tn\tDisallow write access to your terminal.\n"
1722
1723#define mkdir_trivial_usage \
1724 "[OPTION] DIRECTORY..."
1725#define mkdir_full_usage \
1726 "Create the DIRECTORY(ies) if they do not already exist\n\n" \
1727 "Options:\n" \
1728 "\t-m\tset permission mode (as in chmod), not rwxrwxrwx - umask\n" \
1729 "\t-p\tno error if existing, make parent directories as needed"
1730#define mkdir_example_usage \
1731 "$ mkdir /tmp/foo\n" \
1732 "$ mkdir /tmp/foo\n" \
1733 "/tmp/foo: File exists\n" \
1734 "$ mkdir /tmp/foo/bar/baz\n" \
1735 "/tmp/foo/bar/baz: No such file or directory\n" \
1736 "$ mkdir -p /tmp/foo/bar/baz\n"
1737
1738#define mkfifo_trivial_usage \
1739 "[OPTIONS] name"
1740#define mkfifo_full_usage \
1741 "Creates a named pipe (identical to 'mknod name p')\n\n" \
1742 "Options:\n" \
1743 "\t-m\tcreate the pipe using the specified mode (default a=rw)"
1744
1745#define mkfs_minix_trivial_usage \
1746 "[-c | -l filename] [-nXX] [-iXX] /dev/name [blocks]"
1747#define mkfs_minix_full_usage \
1748 "Make a MINIX filesystem.\n\n" \
1749 "Options:\n" \
1750 "\t-c\t\tCheck the device for bad blocks\n" \
1751 "\t-n [14|30]\tSpecify the maximum length of filenames\n" \
1752 "\t-i INODES\tSpecify the number of inodes for the filesystem\n" \
1753 "\t-l FILENAME\tRead the bad blocks list from FILENAME\n" \
1754 "\t-v\t\tMake a Minix version 2 filesystem"
1755
1756#define mknod_trivial_usage \
1757 "[OPTIONS] NAME TYPE MAJOR MINOR"
1758#define mknod_full_usage \
1759 "Create a special file (block, character, or pipe).\n\n" \
1760 "Options:\n" \
1761 "\t-m\tcreate the special file using the specified mode (default a=rw)\n\n" \
1762 "TYPEs include:\n" \
1763 "\tb:\tMake a block (buffered) device.\n" \
1764 "\tc or u:\tMake a character (un-buffered) device.\n" \
1765 "\tp:\tMake a named pipe. MAJOR and MINOR are ignored for named pipes."
1766#define mknod_example_usage \
1767 "$ mknod /dev/fd0 b 2 0\n" \
1768 "$ mknod -m 644 /tmp/pipe p\n"
1769
1770#define mkswap_trivial_usage \
1771 "[-c] [-v0|-v1] device [block-count]"
1772#define mkswap_full_usage \
1773 "Prepare a disk partition to be used as a swap partition.\n\n" \
1774 "Options:\n" \
1775 "\t-c\t\tCheck for read-ability.\n" \
1776 "\t-v0\t\tMake version 0 swap [max 128 Megs].\n" \
1777 "\t-v1\t\tMake version 1 swap [big!] (default for kernels >\n\t\t\t2.1.117).\n" \
1778 "\tblock-count\tNumber of block to use (default is entire partition)."
1779
1780#define mktemp_trivial_usage \
1781 "[-dq] TEMPLATE"
1782#define mktemp_full_usage \
1783 "Creates a temporary file with its name based on TEMPLATE.\n" \
1784 "TEMPLATE is any name with six `Xs' (i.e., /tmp/temp.XXXXXX).\n\n" \
1785 "Options:\n" \
1786 "\t-d\t\tMake a directory instead of a file\n" \
1787 "\t-q\t\tFail silently if an error occurs"
1788#define mktemp_example_usage \
1789 "$ mktemp /tmp/temp.XXXXXX\n" \
1790 "/tmp/temp.mWiLjM\n" \
1791 "$ ls -la /tmp/temp.mWiLjM\n" \
1792 "-rw------- 1 andersen andersen 0 Apr 25 17:10 /tmp/temp.mWiLjM\n"
1793
1794#define modprobe_trivial_usage \
1795 "[-knqrsv] [MODULE ...]"
1796#define modprobe_full_usage \
1797 "Used for high level module loading and unloading.\n\n" \
1798 "Options:\n" \
1799 "\t-k\tMake module autoclean-able.\n" \
1800 "\t-n\tJust show what would be done.\n" \
1801 "\t-q\tQuiet output.\n" \
1802 "\t-r\tRemove module (stacks) or do autoclean.\n" \
1803 "\t-s\tReport via syslog instead of stderr.\n" \
1804 "\t-v\tVerbose output."
1805#define modprobe_example_usage \
1806 "$ modprobe cdrom\n"
1807
1808#define more_trivial_usage \
1809 "[FILE ...]"
1810#define more_full_usage \
1811 "More is a filter for viewing FILE one screenful at a time."
1812#define more_example_usage \
1813 "$ dmesg | more\n"
1814
1815#ifdef CONFIG_FEATURE_MOUNT_LOOP
1816 #define USAGE_MOUNT_LOOP(a) a
1817#else
1818 #define USAGE_MOUNT_LOOP(a)
1819#endif
1820#ifdef CONFIG_FEATURE_MTAB_SUPPORT
1821 #define USAGE_MTAB(a) a
1822#else
1823 #define USAGE_MTAB(a)
1824#endif
1825#define mount_trivial_usage \
1826 "[flags] DEVICE NODE [-o options,more-options]"
1827#define mount_full_usage \
1828 "Mount a filesystem. Autodetection of filesystem type requires the\n" \
1829 "/proc filesystem be already mounted.\n\n" \
1830 "Flags:\n" \
1831 "\t-a:\t\tMount all filesystems in fstab.\n" \
1832 USAGE_MTAB( \
1833 "\t-f:\t\t\"Fake\" Add entry to mount table but don't mount it.\n" \
1834 "\t-n:\t\tDon't write a mount table entry.\n" \
1835 ) \
1836 "\t-o option:\tOne of many filesystem options, listed below.\n" \
1837 "\t-r:\t\tMount the filesystem read-only.\n" \
1838 "\t-t fs-type:\tSpecify the filesystem type.\n" \
1839 "\t-w:\t\tMount for reading and writing (default).\n" \
1840 "\n" \
1841 "Options for use with the \"-o\" flag:\n" \
1842 "\tasync/sync:\tWrites are asynchronous / synchronous.\n" \
1843 "\tatime/noatime:\tEnable / disable updates to inode access times.\n" \
1844 "\tdev/nodev:\tAllow use of special device files / disallow them.\n" \
1845 "\texec/noexec:\tAllow use of executable files / disallow them.\n" \
1846 USAGE_MOUNT_LOOP( \
1847 "\tloop:\t\tMounts a file via loop device.\n" \
1848 ) \
1849 "\tsuid/nosuid:\tAllow set-user-id-root programs / disallow them.\n" \
1850 "\tremount:\tRe-mount a mounted filesystem, changing its flags.\n" \
1851 "\tro/rw:\t\tMount for read-only / read-write.\n" \
1852 "\tbind:\t\tUse the linux 2.4.x \"bind\" feature.\n" \
1853 "\nThere are EVEN MORE flags that are specific to each filesystem.\n" \
1854 "You'll have to see the written documentation for those filesystems."
1855#define mount_example_usage \
1856 "$ mount\n" \
1857 "/dev/hda3 on / type minix (rw)\n" \
1858 "proc on /proc type proc (rw)\n" \
1859 "devpts on /dev/pts type devpts (rw)\n" \
1860 "$ mount /dev/fd0 /mnt -t msdos -o ro\n" \
1861 "$ mount /tmp/diskimage /opt -t ext2 -o loop\n"
1862
1863#define mt_trivial_usage \
1864 "[-f device] opcode value"
1865#define mt_full_usage \
1866 "Control magnetic tape drive operation\n" \
1867 "\nAvailable Opcodes:\n\n" \
1868 "bsf bsfm bsr bss datacompression drvbuffer eof eom erase\n" \
1869 "fsf fsfm fsr fss load lock mkpart nop offline ras1 ras2\n" \
1870 "ras3 reset retension rewind rewoffline seek setblk setdensity\n" \
1871 "setpart tell unload unlock weof wset"
1872
1873#define mv_trivial_usage \
1874 "[OPTION]... SOURCE DEST\n" \
1875 "or: mv [OPTION]... SOURCE... DIRECTORY"
1876#define mv_full_usage \
1877 "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n\n" \
1878 "Options:\n" \
1879 "\t-f\tdon't prompt before overwriting\n" \
1880 "\t-i\tinteractive, prompt before overwrite"
1881#define mv_example_usage \
1882 "$ mv /tmp/foo /bin/bar\n"
1883
1884#define nameif_trivial_usage \
1885 "[-s] [-c FILE] [{IFNAME MACADDR}]"
1886#define nameif_full_usage \
1887 "Nameif renaming network interface while it in the down state.\n\n" \
1888 "Options:\n" \
1889 "\t-c FILE\t\tUse configuration file (default is /etc/mactab)\n" \
1890 "\t-s\t\tUse syslog (LOCAL0 facility).\n" \
1891 "\tIFNAME MACADDR\tnew_interface_name interface_mac_address"
1892#define nameif_example_usage \
1893 "$ nameif -s dmz0 00:A0:C9:8C:F6:3F\n" \
1894 " or\n" \
1895 "$ nameif -c /etc/my_mactab_file\n" \
1896
1897#define nc_trivial_usage \
1898 "[OPTIONS] [IP] [port]"
1899#define nc_full_usage \
1900 "Netcat opens a pipe to IP:port\n\n" \
1901 "Options:\n" \
1902 "\t-l\t\tlisten mode, for inbound connects\n" \
1903 "\t-p PORT\t\tlocal port number\n" \
1904 "\t-i SECS\t\tdelay interval for lines sent\n" \
1905 "\t-e PROG\t\tprogram to exec after connect (dangerous!)"
1906#define nc_example_usage \
1907 "$ nc foobar.somedomain.com 25\n" \
1908 "220 foobar ESMTP Exim 3.12 #1 Sat, 15 Apr 2000 00:03:02 -0600\n" \
1909 "help\n" \
1910 "214-Commands supported:\n" \
1911 "214- HELO EHLO MAIL RCPT DATA AUTH\n" \
1912 "214 NOOP QUIT RSET HELP\n" \
1913 "quit\n" \
1914 "221 foobar closing connection\n"
1915
1916#define netstat_trivial_usage \
1917 "[-laenrtuwx]"
1918#define netstat_full_usage \
1919 "Netstat displays Linux networking information.\n\n" \
1920 "Options:\n" \
1921 "\t-l display listening server sockets\n" \
1922 "\t-a display all sockets (default: connected)\n" \
1923 "\t-e display other/more information\n" \
1924 "\t-n don't resolve names\n" \
1925 "\t-r display routing table\n" \
1926 "\t-t tcp sockets\n" \
1927 "\t-u udp sockets\n" \
1928 "\t-w raw sockets\n" \
1929 "\t-x unix sockets"
1930
1931
1932#define network_trivial_usage \
1933 ""
1934#define network_full_usage \
1935 "LSB network init system."
1936#define network_example_usage \
1937 "$ network start\n"
1938
1939
1940#define nslookup_trivial_usage \
1941 "[HOST] [SERVER]"
1942#define nslookup_full_usage \
1943 "Queries the nameserver for the IP address of the given HOST\n" \
1944 "optionally using a specified DNS server"
1945#define nslookup_example_usage \
1946 "$ nslookup localhost\n" \
1947 "Server: default\n" \
1948 "Address: default\n" \
1949 "\n" \
1950 "Name: debian\n" \
1951 "Address: 127.0.0.1\n"
1952
1953#define od_trivial_usage \
1954 "[-aBbcDdeFfHhIiLlOovXx] [FILE]"
1955#define od_full_usage \
1956 "Write an unambiguous representation, octal bytes by default, of FILE\n"\
1957 "to standard output. With no FILE, or when FILE is -, read standard input."
1958
1959#define openvt_trivial_usage \
1960 "<vtnum> <COMMAND> [ARGS...]"
1961#define openvt_full_usage \
1962 "Start a command on a new virtual terminal"
1963#define openvt_example_usage \
1964 "openvt 2 /bin/ash\n"
1965
1966#ifdef CONFIG_FEATURE_SHA1_PASSWORDS
1967 #define PASSWORD_ALG_TYPES(a) a
1968#else
1969 #define PASSWORD_ALG_TYPES(a)
1970#endif
1971#define passwd_trivial_usage \
1972 "[OPTION] [name]"
1973#define passwd_full_usage \
1974 "Change a user password. If no name is specified,\n" \
1975 "changes the password for the current user.\n" \
1976 "Options:\n" \
1977 "\t-a\tDefine which algorithm shall be used for the password.\n" \
1978 "\t\t\t(Choices: des, md5" \
1979 PASSWORD_ALG_TYPES(", sha1") \
1980 ")\n\t-d\tDelete the password for the specified user account.\n" \
1981 "\t-l\tLocks (disables) the specified user account.\n" \
1982 "\t-u\tUnlocks (re-enables) the specified user account."
1983
1984#define patch_trivial_usage \
1985 "[-p<num>]"
1986#define patch_full_usage \
1987 "[-p<num>]"
1988#define patch_example_usage \
1989 "$ patch -p1 <example.diff"
1990
1991#define pidof_trivial_usage \
1992 "process-name [OPTION] [process-name ...]"
1993#define pidof_full_usage \
1994 "Lists the PIDs of all processes with names that match the\n" \
1995 "names on the command line.\n" \
1996 "Options:\n" \
1997 "\t-s\t\tdisplay only a single PID."
1998#define pidof_example_usage \
1999 "$ pidof init\n" \
2000 "1\n"
2001
2002#define pidofproc_trivial_usage \
2003 ""
2004#define pidofproc_full_usage \
2005 "LSB pidofproc."
2006#define pidofproc_example_usage \
2007 "$ pidofproc 5\n"
2008
2009
2010#ifndef CONFIG_FEATURE_FANCY_PING
2011#define ping_trivial_usage "host"
2012#define ping_full_usage "Send ICMP ECHO_REQUEST packets to network hosts"
2013#else
2014#define ping_trivial_usage \
2015 "[OPTION]... host"
2016#define ping_full_usage \
2017 "Send ICMP ECHO_REQUEST packets to network hosts.\n\n" \
2018 "Options:\n" \
2019 "\t-c COUNT\tSend only COUNT pings.\n" \
2020 "\t-s SIZE\t\tSend SIZE data bytes in packets (default=56).\n" \
2021 "\t-q\t\tQuiet mode, only displays output at start\n" \
2022 "\t\t\tand when finished."
2023#endif
2024#define ping_example_usage \
2025 "$ ping localhost\n" \
2026 "PING slag (127.0.0.1): 56 data bytes\n" \
2027 "64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=20.1 ms\n" \
2028 "\n" \
2029 "--- debian ping statistics ---\n" \
2030 "1 packets transmitted, 1 packets received, 0% packet loss\n" \
2031 "round-trip min/avg/max = 20.1/20.1/20.1 ms\n"
2032
2033#ifndef CONFIG_FEATURE_FANCY_PING6
2034#define ping6_trivial_usage "host"
2035#define ping6_full_usage "Send ICMP ECHO_REQUEST packets to network hosts"
2036#else
2037#define ping6_trivial_usage \
2038 "[OPTION]... host"
2039#define ping6_full_usage \
2040 "Send ICMP ECHO_REQUEST packets to network hosts.\n\n" \
2041 "Options:\n" \
2042 "\t-c COUNT\tSend only COUNT pings.\n" \
2043 "\t-s SIZE\t\tSend SIZE data bytes in packets (default=56).\n" \
2044 "\t-q\t\tQuiet mode, only displays output at start\n" \
2045 "\t\t\tand when finished."
2046#endif
2047#define ping6_example_usage \
2048 "$ ping6 ip6-localhost\n" \
2049 "PING ip6-localhost (::1): 56 data bytes\n" \
2050 "64 bytes from ::1: icmp6_seq=0 ttl=64 time=20.1 ms\n" \
2051 "\n" \
2052 "--- ip6-localhost ping statistics ---\n" \
2053 "1 packets transmitted, 1 packets received, 0% packet loss\n" \
2054 "round-trip min/avg/max = 20.1/20.1/20.1 ms\n"
2055
2056#define pivot_root_trivial_usage \
2057 "NEW_ROOT PUT_OLD"
2058#define pivot_root_full_usage \
2059 "Move the current root file system to PUT_OLD and make NEW_ROOT\n" \
2060 "the new root file system."
2061
2062#define poweroff_trivial_usage \
2063 "[-d<delay>]"
2064#define poweroff_full_usage \
2065 "Halt the system and request that the kernel shut off the power.\n" \
2066 "Options:\n" \
2067 "\t-d\t\tdelay interval for shutting off."
2068
2069#define printf_trivial_usage \
2070 "FORMAT [ARGUMENT...]"
2071#define printf_full_usage \
2072 "Formats and prints ARGUMENT(s) according to FORMAT,\n" \
2073 "Where FORMAT controls the output exactly as in C printf."
2074#define printf_example_usage \
2075 "$ printf "Val=%d\\n" 5\n" \
2076 "Val=5\n"
2077
2078#ifdef CONFIG_SELINUX
2079#define USAGE_NONSELINUX(a)
2080#else
2081#define USAGE_NONSELINUX(a) a
2082#endif
2083
2084#define ps_trivial_usage \
2085 ""
2086#define ps_full_usage \
2087 "Report process status\n" \
2088 USAGE_NONSELINUX("\n\tThis version of ps accepts no options.") \
2089 USAGE_SELINUX("\nOptions:\n\t-c\tshow SE Linux context")
2090
2091#define ps_example_usage \
2092 "$ ps\n" \
2093 " PID Uid Gid State Command\n" \
2094 " 1 root root S init\n" \
2095 " 2 root root S [kflushd]\n" \
2096 " 3 root root S [kupdate]\n" \
2097 " 4 root root S [kpiod]\n" \
2098 " 5 root root S [kswapd]\n" \
2099 " 742 andersen andersen S [bash]\n" \
2100 " 743 andersen andersen S -bash\n" \
2101 " 745 root root S [getty]\n" \
2102 " 2990 andersen andersen R ps\n"
2103
2104#define pwd_trivial_usage \
2105 ""
2106#define pwd_full_usage \
2107 "Print the full filename of the current working directory."
2108#define pwd_example_usage \
2109 "$ pwd\n" \
2110 "/root\n"
2111
2112#define rc_trivial_usage \
2113 ""
2114#define rc_full_usage \
2115 "LSB rc init system."
2116#define rc_example_usage \
2117 "$ rc 5\n"
2118
2119
2120#define rcS_trivial_usage \
2121 ""
2122#define rcS_full_usage \
2123 "sysinit for inittab."
2124#define rcS_example_usage \
2125 "$ rcS\n"
2126
2127
2128#define rdate_trivial_usage \
2129 "[-sp] HOST"
2130#define rdate_full_usage \
2131 "Get and possibly set the system date and time from a remote HOST.\n\n" \
2132 "Options:\n" \
2133 "\t-s\tSet the system date and time (default).\n" \
2134 "\t-p\tPrint the date and time."
2135
2136#define readlink_trivial_usage \
2137 ""
2138#define readlink_full_usage \
2139 "Displays the value of a symbolic link."
2140
2141#define realpath_trivial_usage \
2142 "pathname ..."
2143#define realpath_full_usage \
2144 "Returns the absolute pathnames of given argument."
2145
2146#define reboot_trivial_usage \
2147 "[-d<delay>]"
2148#define reboot_full_usage \
2149 "Reboot the system.\n" \
2150 "Options:\n" \
2151 "\t-d\t\tdelay interval for rebooting."
2152
2153#define remote_fs_trivial_usage \
2154 ""
2155#define remote_fs_full_usage \
2156 "LSB remote_fs init system."
2157#define remote_fs_example_usage \
2158 "$ remote_fs start\n"
2159
2160
2161#define remove_initd_trivial_usage \
2162 ""
2163#define remove_initd_full_usage \
2164 "LSB remove_initd init system."
2165#define remove_initd_example_usage \
2166 "$ remove_initd start\n"
2167
2168
2169#define renice_trivial_usage \
2170 "priority pid [pid ...]"
2171#define renice_full_usage \
2172 "Changes priority of running processes. Allowed priorities range\n" \
2173 "from 20 (the process runs only when nothing else is running) to 0\n" \
2174 "(default priority) to -20 (almost nothing else ever gets to run)."
2175
2176#define reset_trivial_usage \
2177 ""
2178#define reset_full_usage \
2179 "Resets the screen."
2180
2181#define rm_trivial_usage \
2182 "[OPTION]... FILE..."
2183#define rm_full_usage \
2184 "Remove (unlink) the FILE(s). You may use '--' to\n" \
2185 "indicate that all following arguments are non-options.\n\n" \
2186 "Options:\n" \
2187 "\t-i\t\talways prompt before removing each destination\n" \
2188 "\t-f\t\tremove existing destinations, never prompt\n" \
2189 "\t-r or -R\tremove the contents of directories recursively"
2190#define rm_example_usage \
2191 "$ rm -rf /tmp/foo\n"
2192
2193#define rmdir_trivial_usage \
2194 "[OPTION]... DIRECTORY..."
2195#define rmdir_full_usage \
2196 "Remove the DIRECTORY(ies), if they are empty."
2197#define rmdir_example_usage \
2198 "# rmdir /tmp/foo\n"
2199
2200#define rmmod_trivial_usage \
2201 "[OPTION]... [MODULE]..."
2202#define rmmod_full_usage \
2203 "Unloads the specified kernel modules from the kernel.\n\n" \
2204 "Options:\n" \
2205 "\t-a\tRemove all unused modules (recursively)"
2206#define rmmod_example_usage \
2207 "$ rmmod tulip\n"
2208
2209#ifdef CONFIG_FEATURE_IPV6
2210 #define USAGE_ROUTE_IPV6(a) a
2211#else
2212 #define USAGE_ROUTE_IPV6(a) "\t"
2213#endif
2214
2215
2216#define route_trivial_usage \
2217 "[{add|del|delete}]"
2218#define route_full_usage \
2219 "Edit the kernel's routing tables.\n\n" \
2220 "Options:\n" \
2221 "\t-n\t\tDont resolve names.\n" \
2222 "\t-e\t\tDisplay other/more information.\n" \
2223 "\t-A inet" USAGE_ROUTE_IPV6("{6}") "\tSelect address family."
2224
2225#define rpm_trivial_usage \
2226 "-i -q[ildc]p package.rpm"
2227#define rpm_full_usage \
2228 "Manipulates RPM packages" \
2229 "\n\nOptions:" \
2230 "\n\t-i Install package" \
2231 "\n\t-q Query package" \
2232 "\n\t-p Query uninstalled package" \
2233 "\n\t-i Show information" \
2234 "\n\t-l List contents" \
2235 "\n\t-d List documents" \
2236 "\n\t-c List config files"
2237
2238#define rpm2cpio_trivial_usage \
2239 "package.rpm"
2240#define rpm2cpio_full_usage \
2241 "Outputs a cpio archive of the rpm file."
2242
2243#define run_parts_trivial_usage \
2244 "[-t] [-a ARG] [-u MASK] DIRECTORY"
2245#define run_parts_full_usage \
2246 "Run a bunch of scripts in a directory.\n\n" \
2247 "Options:\n" \
2248 "\t-t\tPrints what would be run, but does not actually run anything.\n" \
2249 "\t-a ARG\tPass ARG as an argument for every program invoked.\n" \
2250 "\t-u MASK\tSet the umask to MASK before executing every program."
2251
2252#define rx_trivial_usage \
2253 "FILE"
2254#define rx_full_usage \
2255 "Receive a file using the xmodem protocol."
2256#define rx_example_usage \
2257 "$ rx /tmp/foo\n"
2258
2259#define sed_trivial_usage \
2260 "[-efinr] pattern [files...]"
2261#define sed_full_usage \
2262 "Options:\n" \
2263 "\t-e script\tadd the script to the commands to be executed\n" \
2264 "\t-f scriptfile\tadd script-file contents to the\n" \
2265 "\t\t\tcommands to be executed\n" \
2266 "\t-i\t\tedit files in-place\n" \
2267 "\t-n\t\tsuppress automatic printing of pattern space\n" \
2268 "\t-r\t\tuse extended regular expression syntax\n" \
2269 "\n" \
2270 "If no -e or -f is given, the first non-option argument is taken as the sed\n"\
2271 "script to interpret. All remaining arguments are names of input files; if no\n"\
2272 "input files are specified, then the standard input is read. Source files\n" \
2273 "will not be modified unless -i option is given."
2274
2275#define sed_example_usage \
2276 "$ echo "foo" | sed -e 's/f[a-zA-Z]o/bar/g'\n" \
2277 "bar\n"
2278
2279#define seq_trivial_usage \
2280 "[first [increment]] last"
2281#define seq_full_usage \
2282 "Print numbers from FIRST to LAST, in steps of INCREMENT.\n" \
2283 "FIRST, INCREMENT default to 1\n" \
2284 "Arguments:\n" \
2285 "\tLAST\n" \
2286 "\tFIRST\tLAST\n" \
2287 "\tFIRST\tINCREMENT\tLAST"
2288
2289#define setkeycodes_trivial_usage \
2290 "SCANCODE KEYCODE ..."
2291#define setkeycodes_full_usage \
2292 "Set entries into the kernel's scancode-to-keycode map,\n" \
2293 "allowing unusual keyboards to generate usable keycodes.\n\n" \
2294 "SCANCODE may be either xx or e0xx (hexadecimal),\n" \
2295 "and KEYCODE is given in decimal"
2296#define setkeycodes_example_usage \
2297 "$ setkeycodes e030 127\n"
2298
2299#define lash_trivial_usage \
2300 "[FILE]...\n" \
2301 "or: sh -c command [args]..."
2302#define lash_full_usage \
2303 "The BusyBox LAme SHell (command interpreter)"
2304#define lash_notes_usage \
2305 "This command does not yet have proper documentation.\n\n" \
2306 "Use lash just as you would use any other shell. It properly handles pipes,\n" \
2307 "redirects, job control, can be used as the shell for scripts, and has a\n" \
2308 "sufficient set of builtins to do what is needed. It does not (yet) support\n" \
2309 "Bourne Shell syntax. If you need things like "if-then-else", "while", and such\n" \
2310 "use ash or bash. If you just need a very simple and extremely small shell,\n" \
2311 "this will do the job."
2312
2313#define last_trivial_usage \
2314 ""
2315#define last_full_usage \
2316 "Shows listing of the last users that logged into the system"
2317
2318#define sha1sum_trivial_usage \
2319 "[OPTION] [FILEs...]" \
2320 USAGE_MD5_SHA1_SUM_CHECK("\n or: sha1sum [OPTION] -c [FILE]")
2321#define sha1sum_full_usage \
2322 "Print" USAGE_MD5_SHA1_SUM_CHECK(" or check") " SHA1 checksums.\n\n" \
2323 "Options:\n" \
2324 "With no FILE, or when FILE is -, read standard input." \
2325 USAGE_MD5_SHA1_SUM_CHECK("\n\n" \
2326 "\t-c\tcheck SHA1 sums against given list\n" \
2327 "\nThe following two options are useful only when verifying checksums:\n" \
2328 "\t-s\tdon't output anything, status code shows success\n" \
2329 "\t-w\twarn about improperly formated SHA1 checksum lines")
2330
2331#ifdef CONFIG_FEATURE_FANCY_SLEEP
2332 #define USAGE_FANCY_SLEEP(a) a
2333 #define USAGE_NOT_FANCY_SLEEP(a)
2334#else
2335 #define USAGE_FANCY_SLEEP(a)
2336 #define USAGE_NOT_FANCY_SLEEP(a) a
2337#endif
2338
2339#define sleep_trivial_usage \
2340 USAGE_FANCY_SLEEP("[") "N" USAGE_FANCY_SLEEP("]...")
2341#define sleep_full_usage \
2342 USAGE_NOT_FANCY_SLEEP("Pause for N seconds.") \
2343 USAGE_FANCY_SLEEP( \
2344 "Pause for a time equal to the total of the args given, where each arg can\n" \
2345 "\t\thave an optional suffix of (s)econds, (m)inutes, (h)ours, or (d)ays.")
2346#define sleep_example_usage \
2347 "$ sleep 2\n" \
2348 "[2 second delay results]\n" \
2349 USAGE_FANCY_SLEEP("$ sleep 1d 3h 22m 8s\n" \
2350 "[98528 second delay results]\n")
2351
2352#ifdef CONFIG_FEATURE_SORT_UNIQUE
2353 #define USAGE_SORT_UNIQUE(a) a
2354#else
2355 #define USAGE_SORT_UNIQUE(a)
2356#endif
2357#ifdef CONFIG_FEATURE_SORT_REVERSE
2358 #define USAGE_SORT_REVERSE(a) a
2359#else
2360 #define USAGE_SORT_REVERSE(a)
2361#endif
2362#define sort_trivial_usage \
2363 "[-n" USAGE_SORT_REVERSE("r") USAGE_SORT_UNIQUE("u") "] [FILE]..."
2364#define sort_full_usage \
2365 "Sorts lines of text in the specified files\n\n"\
2366 "Options:\n" \
2367 USAGE_SORT_UNIQUE("\t-u\tsuppress duplicate lines\n") \
2368 USAGE_SORT_REVERSE("\t-r\tsort in reverse order\n") \
2369 "\t-n\tsort numerics"
2370#define sort_example_usage \
2371 "$ echo -e \"e\\nf\\nb\\nd\\nc\\na\" | sort\n" \
2372 "a\n" \
2373 "b\n" \
2374 "c\n" \
2375 "d\n" \
2376 "e\n" \
2377 "f\n"
2378
2379#define start_daemon_trivial_usage \
2380 ""
2381#define start_daemon_full_usage \
2382 "LSB start_daemon."
2383#define start_daemon_example_usage \
2384 "$ start_daemon 5\n"
2385
2386
2387#define start_stop_daemon_trivial_usage \
2388 "[OPTIONS] [--start|--stop] ... [-- arguments...]\n"
2389#define start_stop_daemon_full_usage \
2390 "Program to start and stop services."\
2391 "\n\nOptions:"\
2392 "\n\t-S|--start\t\t\tstart"\
2393 "\n\t-K|--stop\t\t\tstop"\
2394 "\n\t-a|--startas <pathname>\t\tstarts process specified by pathname"\
2395 "\n\t-b|--background\t\t\tforce process into background"\
2396 "\n\t-u|--user <username>|<uid>\tstop this user's processes"\
2397 "\n\t-x|--exec <executable>\t\tprogram to either start or check"\
2398 "\n\t-m|--make-pidfile <filename>\tcreate the -p file and enter pid in it"\
2399 "\n\t-n|--name <process-name>\tstop processes with this name"\
2400 "\n\t-p|--pidfile <pid-file>\t\tsave or load pid using a pid-file"\
2401 "\n\t-q|--quiet\t\t\tbe quiet" \
2402 "\n\t-s|--signal <signal>\t\tsignal to send (default TERM)"
2403
2404#define strings_trivial_usage \
2405 "[-afo] [-n length] [file ... ]"
2406#define strings_full_usage \
2407 "Display printable strings in a binary file." \
2408 "\n\nOptions:" \
2409 "\n\t-a\tScan the whole files (this is the default)."\
2410 "\n\t-f\tPrecede each string with the name of the file where it was found." \
2411 "\n\t-n N\tSpecifies that at least N characters forms a sequence (default 4)" \
2412 "\n\t-o\tEach string is preceded by its decimal offset in the file."
2413
2414#define stty_trivial_usage \
2415 "[-a|g] [-F DEVICE] [SETTING]..."
2416#define stty_full_usage \
2417 "Without arguments, prints baud rate, line discipline," \
2418 "\nand deviations from stty sane." \
2419 "\n\nOptions:" \
2420 "\n\t-F DEVICE\topen device instead of stdin" \
2421 "\n\t-a\t\tprint all current settings in human-readable form" \
2422 "\n\t-g\t\tprint in stty-readable form" \
2423 "\n\t[SETTING]\tsee manpage"
2424
2425#define su_trivial_usage \
2426 "[OPTION]... [-] [username]"
2427#define su_full_usage \
2428 "Change user id or become root.\n" \
2429 "Options:\n" \
2430 "\t-p\tPreserve environment"
2431
2432#define sulogin_trivial_usage \
2433 "[OPTION]... [tty-device]"
2434#define sulogin_full_usage \
2435 "Single user login\n" \
2436 "Options:\n" \
2437 "\t-f\tDo not authenticate (user already authenticated)\n" \
2438 "\t-h\tName of the remote host for this login.\n" \
2439 "\t-p\tPreserve environment."
2440
2441#define swapoff_trivial_usage \
2442 "[OPTION] [DEVICE]"
2443#define swapoff_full_usage \
2444 "Stop swapping virtual memory pages on DEVICE.\n\n" \
2445 "Options:\n" \
2446 "\t-a\tStop swapping on all swap devices"
2447
2448#define swapon_trivial_usage \
2449 "[OPTION] [DEVICE]"
2450#define swapon_full_usage \
2451 "Start swapping virtual memory pages on DEVICE.\n\n" \
2452 "Options:\n" \
2453 "\t-a\tStart swapping on all swap devices"
2454
2455#define sync_trivial_usage \
2456 ""
2457#define sync_full_usage \
2458 "Write all buffered filesystem blocks to disk."
2459
2460
2461#ifdef CONFIG_FEATURE_ROTATE_LOGFILE
2462 #define USAGE_ROTATE_LOGFILE(a) a
2463#else
2464 #define USAGE_ROTATE_LOGFILE(a)
2465#endif
2466#ifdef CONFIG_FEATURE_REMOTE_LOG
2467 #define USAGE_REMOTE_LOG(a) a
2468#else
2469 #define USAGE_REMOTE_LOG(a)
2470#endif
2471#ifdef CONFIG_FEATURE_IPC_SYSLOG
2472 #define USAGE_IPC_LOG(a) a
2473#else
2474 #define USAGE_IPC_LOG(a)
2475#endif
2476
2477#ifdef CONFIG_SYSCTL
2478#define sysctl_trivial_usage \
2479 "[OPTIONS]... [VALUE]...\n"
2480#define sysctl_full_usage
2481 "sysctl - configure kernel parameters at runtime\n\n" \
2482 "Options:\n" \
2483 "\t-n\tUse this option to disable printing of the key name when printing values.\n" \
2484 "\t-w\tUse this option when you want to change a sysctl setting.\n" \
2485 "\t-p\tLoad in sysctl settings from the file specified or /etc/sysctl.conf if none given.\n" \
2486 "\t-a\tDisplay all values currently available.\n" \
2487 "\t-A\tDisplay all values currently available in table form."
2488#define sysctl_example_usage
2489 "sysctl [-n] variable ...\n" \
2490 "sysctl [-n] -w variable=value ...\n" \
2491 "sysctl [-n] -a\n" \
2492 "sysctl [-n] -p <file>\t(default /etc/sysctl.conf)\n" \
2493 "sysctl [-n] -A\n"
2494#endif
2495
2496#define syslogd_trivial_usage \
2497 "[OPTION]..."
2498#define syslogd_full_usage \
2499 "Linux system and kernel logging utility.\n" \
2500 "Note that this version of syslogd ignores /etc/syslog.conf.\n\n" \
2501 "Options:\n" \
2502 "\t-m MIN\t\tMinutes between MARK lines (default=20, 0=off)\n" \
2503 "\t-n\t\tRun as a foreground process\n" \
2504 "\t-O FILE\t\tUse an alternate log file (default=/var/log/messages)\n" \
2505 "\t-S\t\tMake logging output smaller." \
2506 USAGE_ROTATE_LOGFILE( \
2507 "\n\t-s SIZE\t\tMax size (KB) before rotate (default=200KB, 0=off)\n" \
2508 "\t-b NUM\t\tNumber of rotated logs to keep (default=1, max=99, 0=purge)") \
2509 USAGE_REMOTE_LOG( \
2510 "\n\t-R HOST[:PORT]\tLog to IP or hostname on PORT (default PORT=514/UDP)\n" \
2511 "\t-L\t\tLog locally and via network logging (default is network only)") \
2512 USAGE_IPC_LOG( \
2513 "\n\t-C [size(KiB)]\tLog to a circular buffer (read the buffer using logread)")
2514#define syslogd_example_usage \
2515 "$ syslogd -R masterlog:514\n" \
2516 "$ syslogd -R 192.168.1.1:601\n"
2517
2518
2519#ifndef CONFIG_FEATURE_FANCY_TAIL
2520 #define USAGE_UNSIMPLE_TAIL(a)
2521#else
2522 #define USAGE_UNSIMPLE_TAIL(a) a
2523#endif
2524#define tail_trivial_usage \
2525 "[OPTION]... [FILE]..."
2526#define tail_full_usage \
2527 "Print last 10 lines of each FILE to standard output.\n" \
2528 "With more than one FILE, precede each with a header giving the\n" \
2529 "file name. With no FILE, or when FILE is -, read standard input.\n\n" \
2530 "Options:\n" \
2531 USAGE_UNSIMPLE_TAIL("\t-c N[kbm]\toutput the last N bytes\n") \
2532 "\t-n N[kbm]\tprint last N lines instead of last 10\n" \
2533 "\t-f\t\toutput data as the file grows" \
2534 USAGE_UNSIMPLE_TAIL( "\n\t-q\t\tnever output headers giving file names\n" \
2535 "\t-s SEC\t\twait SEC seconds between reads with -f\n" \
2536 "\t-v\t\talways output headers giving file names\n\n" \
2537 "If the first character of N (bytes or lines) is a '+', output begins with \n" \
2538 "the Nth item from the start of each file, otherwise, print the last N items\n" \
2539 "in the file. N bytes may be suffixed by k (x1024), b (x512), or m (1024^2)." )
2540#define tail_example_usage \
2541 "$ tail -n 1 /etc/resolv.conf\n" \
2542 "nameserver 10.0.0.1\n"
2543
2544#ifdef CONFIG_FEATURE_TAR_CREATE
2545 #define USAGE_TAR_CREATE(a) a
2546#else
2547 #define USAGE_TAR_CREATE(a)
2548#endif
2549#ifdef CONFIG_FEATURE_TAR_EXCLUDE
2550 #define USAGE_TAR_EXCLUDE(a) a
2551#else
2552 #define USAGE_TAR_EXCLUDE(a)
2553#endif
2554#ifdef CONFIG_FEATURE_TAR_GZIP
2555 #define USAGE_TAR_GZIP(a) a
2556#else
2557 #define USAGE_TAR_GZIP(a)
2558#endif
2559#ifdef CONFIG_FEATURE_TAR_BZIP2
2560 #define USAGE_TAR_BZIP2(a) a
2561#else
2562 #define USAGE_TAR_BZIP2(a)
2563#endif
2564#ifdef CONFIG_FEATURE_TAR_COMPRESS
2565 #define USAGE_TAR_COMPRESS(a) a
2566#else
2567 #define USAGE_TAR_COMPRESS(a)
2568#endif
2569
2570#define tar_trivial_usage \
2571 "-[" USAGE_TAR_CREATE("c") USAGE_TAR_GZIP("z") USAGE_TAR_BZIP2("j") USAGE_TAR_COMPRESS("Z") "xtvO] " \
2572 USAGE_TAR_EXCLUDE("[-X FILE]") \
2573 "[-f TARFILE] [-C DIR] [FILE(s)] ..."
2574#define tar_full_usage \
2575 "Create, extract, or list files from a tar file.\n\n" \
2576 "Options:\n" \
2577 USAGE_TAR_CREATE("\tc\t\tcreate\n") \
2578 "\tx\t\textract\n" \
2579 "\tt\t\tlist\n" \
2580 "\nArchive format selection:\n" \
2581 USAGE_TAR_GZIP("\tz\t\tFilter the archive through gzip\n") \
2582 USAGE_TAR_BZIP2("\tj\t\tFilter the archive through bzip2\n") \
2583 USAGE_TAR_COMPRESS("\tZ\t\tFilter the archive through compress\n") \
2584 "\nFile selection:\n" \
2585 "\tf\t\tname of TARFILE or \"-\" for stdin\n" \
2586 "\tO\t\textract to stdout\n" \
2587 USAGE_TAR_EXCLUDE( \
2588 "\texclude\t\tfile to exclude\n" \
2589 "\tX\t\tfile with names to exclude\n" \
2590 ) \
2591 "\tC\t\tchange to directory DIR before operation\n" \
2592 "\tv\t\tverbosely list files processed"
2593#define tar_example_usage \
2594 "$ zcat /tmp/tarball.tar.gz | tar -xf -\n" \
2595 "$ tar -cf /tmp/tarball.tar /usr/local\n"
2596
2597#define tee_trivial_usage \
2598 "[OPTION]... [FILE]..."
2599#define tee_full_usage \
2600 "Copy standard input to each FILE, and also to standard output.\n\n" \
2601 "Options:\n" \
2602 "\t-a\tappend to the given FILEs, do not overwrite\n" \
2603 "\t-i\tignore interrupt signals (SIGINT)"
2604#define tee_example_usage \
2605 "$ echo "Hello" | tee /tmp/foo\n" \
2606 "$ cat /tmp/foo\n" \
2607 "Hello\n"
2608
2609#ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN
2610#define telnet_trivial_usage \
2611 "[-a] [-l USER] HOST [PORT]"
2612#define telnet_full_usage \
2613 "Telnet is used to establish interactive communication with another\n" \
2614 "computer over a network using the TELNET protocol.\n\n" \
2615 "Options:\n" \
2616 "\t-a\t\tAttempt an automatic login with the USER variable.\n" \
2617 "\t-l USER\t\tAttempt an automatic login with the USER argument.\n" \
2618 "\tHOST\t\tThe official name, alias or the IP address of the\n" \
2619 "\t\t\tremote host.\n" \
2620 "\tPORT\t\tThe remote port number to connect to. If it is not\n" \
2621 "\t\t\tspecified, the default telnet (23) port is used."
2622#else
2623#define telnet_trivial_usage \
2624 "HOST [PORT]"
2625#define telnet_full_usage \
2626 "Telnet is used to establish interactive communication with another\n"\
2627 "computer over a network using the TELNET protocol."
2628#endif
2629
2630#ifdef CONFIG_FEATURE_TELNETD_INETD
2631#define telnetd_trivial_usage \
2632 "(inetd mode) [OPTION]"
2633#define telnetd_full_usage \
2634 "Telnetd uses incoming TELNET connections via inetd.\n"\
2635 "Options:\n" \
2636 "\t-l LOGIN\texec LOGIN on connect (default /bin/sh)\n" \
2637 "\t-f issue_file\tDisplay issue_file instead of /etc/issue."
2638#else
2639#define telnetd_trivial_usage \
2640 "[OPTION]"
2641#define telnetd_full_usage \
2642 "Telnetd listens for incoming TELNET connections on PORT.\n"\
2643 "Options:\n" \
2644 "\t-p PORT\tlisten for connections on PORT (default 23)\n"\
2645 "\t-l LOGIN\texec LOGIN on connect (default /bin/sh)\n"\
2646 "\t-f issue_file\tDisplay issue_file instead of /etc/issue."
2647#endif
2648
2649#define test_trivial_usage \
2650 "EXPRESSION\n or [ EXPRESSION ]"
2651#define test_full_usage \
2652 "Checks file types and compares values returning an exit\n" \
2653 "code determined by the value of EXPRESSION."
2654#define test_example_usage \
2655 "$ test 1 -eq 2\n" \
2656 "$ echo $?\n" \
2657 "1\n" \
2658 "$ test 1 -eq 1\n" \
2659 "$ echo $?\n" \
2660 "0\n" \
2661 "$ [ -d /etc ]\n" \
2662 "$ echo $?\n" \
2663 "0\n" \
2664 "$ [ -d /junk ]\n" \
2665 "$ echo $?\n" \
2666 "1\n"
2667
2668#ifdef CONFIG_FEATURE_TFTP_GET
2669 #define USAGE_TFTP_GET(a) a
2670#else
2671 #define USAGE_TFTP_GET(a)
2672#endif
2673#ifdef CONFIG_FEATURE_TFTP_PUT
2674 #define USAGE_TFTP_PUT(a) a
2675#else
2676 #define USAGE_TFTP_PUT(a)
2677#endif
2678#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE
2679 #define USAGE_TFTP_BS(a) a
2680#else
2681 #define USAGE_TFTP_BS(a)
2682#endif
2683
2684#define tftp_trivial_usage \
2685 "[OPTION]... HOST [PORT]"
2686#define tftp_full_usage \
2687 "Transfers a file from/to a tftp server using \"octet\" mode.\n\n" \
2688 "Options:\n" \
2689 "\t-l FILE\tLocal FILE.\n" \
2690 "\t-r FILE\tRemote FILE." \
2691 USAGE_TFTP_GET( \
2692 "\n\t-g\tGet file." \
2693 ) \
2694 USAGE_TFTP_PUT( \
2695 "\n\t-p\tPut file." \
2696 ) \
2697 USAGE_TFTP_BS( \
2698 "\n\t-b SIZE\tTransfer blocks of SIZE octets." \
2699 )
2700#define time_trivial_usage \
2701 "[OPTION]... COMMAND [ARGS...]"
2702#define time_full_usage \
2703 "Runs the program COMMAND with arguments ARGS. When COMMAND finishes,\n" \
2704 "COMMAND's resource usage information is displayed\n\n" \
2705 "Options:\n" \
2706 "\t-v\tDisplays verbose resource usage information."
2707
2708#define top_trivial_usage \
2709 "[-d <seconds>]"
2710#define top_full_usage \
2711 "top provides an view of processor activity in real time.\n" \
2712 "This utility reads the status for all processes in /proc each <seconds>\n" \
2713 "and shows the status for however many processes will fit on the screen.\n" \
2714 "This utility will not show processes that are started after program startup,\n" \
2715 "but it will show the EXIT status for and PIDs that exit while it is running."
2716
2717#define touch_trivial_usage \
2718 "[-c] FILE [FILE ...]"
2719#define touch_full_usage \
2720 "Update the last-modified date on the given FILE[s].\n\n" \
2721 "Options:\n" \
2722 "\t-c\tDo not create any files"
2723#define touch_example_usage \
2724 "$ ls -l /tmp/foo\n" \
2725 "/bin/ls: /tmp/foo: No such file or directory\n" \
2726 "$ touch /tmp/foo\n" \
2727 "$ ls -l /tmp/foo\n" \
2728 "-rw-rw-r-- 1 andersen andersen 0 Apr 15 01:11 /tmp/foo\n"
2729
2730#define tr_trivial_usage \
2731 "[-cds] STRING1 [STRING2]"
2732#define tr_full_usage \
2733 "Translate, squeeze, and/or delete characters from\n" \
2734 "standard input, writing to standard output.\n\n" \
2735 "Options:\n" \
2736 "\t-c\ttake complement of STRING1\n" \
2737 "\t-d\tdelete input characters coded STRING1\n" \
2738 "\t-s\tsqueeze multiple output characters of STRING2 into one character"
2739#define tr_example_usage \
2740 "$ echo "gdkkn vnqkc" | tr [a-y] [b-z]\n" \
2741 "hello world\n"
2742
2743#define traceroute_trivial_usage \
2744 "[-dnrv] [-m max_ttl] [-p port#] [-q nqueries]\n"\
2745 "\t[-s src_addr] [-t tos] [-w wait] host [data size]"
2746#define traceroute_full_usage \
2747 "trace the route ip packets follow going to \"host\"\n" \
2748 "Options:\n" \
2749 "\t-d\tset SO_DEBUG options to socket\n" \
2750 "\t-n\tPrint hop addresses numerically rather than symbolically\n" \
2751 "\t-r\tBypass the normal routing tables and send directly to a host\n" \
2752 "\t-v\tVerbose output\n" \
2753 "\t-m max_ttl\tSet the max time-to-live (max number of hops)\n" \
2754 "\t-p port#\tSet the base UDP port number used in probes\n" \
2755 "\t\t(default is 33434)\n" \
2756 "\t-q nqueries\tSet the number of probes per ``ttl'' to nqueries\n" \
2757 "\t\t(default is 3)\n" \
2758 "\t-s src_addr\tUse the following IP address as the source address\n" \
2759 "\t-t tos\tSet the type-of-service in probe packets to the following value\n" \
2760 "\t\t(default 0)\n" \
2761 "\t-w wait\tSet the time (in seconds) to wait for a response to a probe\n" \
2762 "\t\t(default 3 sec.)."
2763
2764
2765#define true_trivial_usage \
2766 ""
2767#define true_full_usage \
2768 "Return an exit code of TRUE (0)."
2769#define true_example_usage \
2770 "$ true\n" \
2771 "$ echo $?\n" \
2772 "0\n"
2773
2774#define tty_trivial_usage \
2775 ""
2776#define tty_full_usage \
2777 "Print the file name of the terminal connected to standard input.\n\n"\
2778 "Options:\n" \
2779 "\t-s\tprint nothing, only return an exit status"
2780#define tty_example_usage \
2781 "$ tty\n" \
2782 "/dev/tty2\n"
2783
2784#define udhcpc_trivial_usage \
2785 "[-fbnqv] [-c CLIENTID] [-H HOSTNAME] [-i INTERFACE]\n[-p pidfile] [-r IP] [-s script]"
2786#define udhcpc_full_usage \
2787 "\t-c,\t--clientid=CLIENTID\tClient identifier\n" \
2788 "\t-H,\t--hostname=HOSTNAME\tClient hostname\n" \
2789 "\t-h,\t \tAlias for -H\n" \
2790 "\t-f,\t--foreground\tDo not fork after getting lease\n" \
2791 "\t-b,\t--background\tFork to background if lease cannot be immediately negotiated.\n" \
2792 "\t-i,\t--interface=INTERFACE\tInterface to use (default: eth0)\n" \
2793 "\t-n,\t--now\tExit with failure if lease cannot be immediately negotiated.\n" \
2794 "\t-p,\t--pidfile=file\tStore process ID of daemon in file\n" \
2795 "\t-q,\t--quit\tQuit after obtaining lease\n" \
2796 "\t-r,\t--request=IP\tIP address to request (default: none)\n" \
2797 "\t-s,\t--script=file\tRun file at dhcp events (default: /usr/share/udhcpc/default.script)\n" \
2798 "\t-v,\t--version\tDisplay version"
2799
2800#define udhcpc_script_trivial_usage \
2801 "[ACTION]"
2802#define udhcpc_script_full_usage \
2803 "Should only be called by udhcpc."
2804
2805#define udhcpd_trivial_usage \
2806 "[configfile]\n" \
2807
2808#define udhcpd_full_usage \
2809 ""
2810
2811#ifdef CONFIG_FEATURE_MOUNT_FORCE
2812 #define USAGE_MOUNT_FORCE(a) a
2813#else
2814 #define USAGE_MOUNT_FORCE(a)
2815#endif
2816#define umount_trivial_usage \
2817 "[flags] FILESYSTEM|DIRECTORY"
2818#define umount_full_usage \
2819 "Unmount file systems\n" \
2820 "\nFlags:\n" "\t-a\tUnmount all file systems" \
2821 USAGE_MTAB(" in /etc/mtab\n\t-n\tDon't erase /etc/mtab entries") \
2822 "\n\t-r\tTry to remount devices as read-only if mount is busy" \
2823 USAGE_MOUNT_FORCE("\n\t-f\tForce umount (i.e., unreachable NFS server)") \
2824 USAGE_MOUNT_LOOP("\n\t-l\tDo not free loop device (if a loop device has been used)")
2825#define umount_example_usage \
2826 "$ umount /dev/hdc1 \n"
2827
2828#define uname_trivial_usage \
2829 "[OPTION]..."
2830#define uname_full_usage \
2831 "Print certain system information. With no OPTION, same as -s.\n\n" \
2832 "Options:\n" \
2833 "\t-a\tprint all information\n" \
2834 "\t-m\tthe machine (hardware) type\n" \
2835 "\t-n\tprint the machine's network node hostname\n" \
2836 "\t-r\tprint the operating system release\n" \
2837 "\t-s\tprint the operating system name\n" \
2838 "\t-p\tprint the host processor type\n" \
2839 "\t-v\tprint the operating system version"
2840#define uname_example_usage \
2841 "$ uname -a\n" \
2842 "Linux debian 2.4.23 #2 Tue Dec 23 17:09:10 MST 2003 i686 GNU/Linux\n"
2843
2844#define uncompress_trivial_usage \
2845 "[-c] [-f] [ name ... ]"
2846#define uncompress_full_usage \
2847 "Uncompress .Z file[s]\n" \
2848 "Options:\n" \
2849 "\t-c\textract to stdout\n" \
2850 "\t-f\tforce overwrite an existing file"
2851
2852#define uniq_trivial_usage \
2853 "[OPTION]... [INPUT [OUTPUT]]"
2854#define uniq_full_usage \
2855 "Discard all but one of successive identical lines from INPUT\n" \
2856 "(or standard input), writing to OUTPUT (or standard output).\n\n" \
2857 "Options:\n" \
2858 "\t-c\tprefix lines by the number of occurrences\n" \
2859 "\t-d\tonly print duplicate lines\n" \
2860 "\t-u\tonly print unique lines\n" \
2861 "\t-f N\tskip the first N fields\n" \
2862 "\t-s N\tskip the first N chars (after any skipped fields)"
2863#define uniq_example_usage \
2864 "$ echo -e \"a\\na\\nb\\nc\\nc\\na\" | sort | uniq\n" \
2865 "a\n" \
2866 "b\n" \
2867 "c\n"
2868
2869#define unix2dos_trivial_usage \
2870 "[option] [FILE]"
2871#define unix2dos_full_usage \
2872 "Converts FILE from unix format to dos format. When no option\n" \
2873 "is given, the input is converted to the opposite output format.\n" \
2874 "When no file is given, uses stdin for input and stdout for output.\n" \
2875 "Options:\n" \
2876 "\t-u\toutput will be in UNIX format\n" \
2877 "\t-d\toutput will be in DOS format"
2878
2879#define unzip_trivial_usage \
2880 "[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]"
2881#define unzip_full_usage \
2882 "Extracts files from ZIP archives.\n\n" \
2883 "Options:\n" \
2884 "\t-l\tlist archive contents (short form)\n" \
2885 "\t-n\tnever overwrite existing files (default)\n" \
2886 "\t-o\toverwrite files without prompting\n" \
2887 "\t-p\tsend output to stdout\n" \
2888 "\t-q\tbe quiet\n" \
2889 "\t-x\texclude these files\n" \
2890 "\t-d\textract files into this directory"
2891
2892#define uptime_trivial_usage \
2893 ""
2894#define uptime_full_usage \
2895 "Display the time since the last boot."
2896#define uptime_example_usage \
2897 "$ uptime\n" \
2898 " 1:55pm up 2:30, load average: 0.09, 0.04, 0.00\n"
2899
2900#define usleep_trivial_usage \
2901 "N"
2902#define usleep_full_usage \
2903 "Pause for N microseconds."
2904#define usleep_example_usage \
2905 "$ usleep 1000000\n" \
2906 "[pauses for 1 second]\n"
2907
2908#define uudecode_trivial_usage \
2909 "[FILE]..."
2910#define uudecode_full_usage \
2911 "Uudecode a file that is uuencoded.\n\n" \
2912 "Options:\n" \
2913 "\t-o FILE\tdirect output to FILE"
2914#define uudecode_example_usage \
2915 "$ uudecode -o busybox busybox.uu\n" \
2916 "$ ls -l busybox\n" \
2917 "-rwxr-xr-x 1 ams ams 245264 Jun 7 21:35 busybox\n"
2918
2919#define uuencode_trivial_usage \
2920 "[OPTION] [INFILE] REMOTEFILE"
2921#define uuencode_full_usage \
2922 "Uuencode a file.\n\n" \
2923 "Options:\n" \
2924 "\t-m\tuse base64 encoding per RFC1521"
2925#define uuencode_example_usage \
2926 "$ uuencode busybox busybox\n" \
2927 "begin 755 busybox\n" \
2928 "<encoded file snipped>\n" \
2929 "$ uudecode busybox busybox > busybox.uu\n" \
2930 "$\n"
2931
2932#define vconfig_trivial_usage \
2933 "COMMAND [OPTIONS] ..."
2934#define vconfig_full_usage \
2935 "vconfig lets you create and remove virtual ethernet devices.\n\n" \
2936 "Options:\n" \
2937 "\tadd [interface-name] [vlan_id]\n" \
2938 "\trem [vlan-name]\n" \
2939 "\tset_flag [interface-name] [flag-num] [0 | 1]\n" \
2940 "\tset_egress_map [vlan-name] [skb_priority] [vlan_qos]\n" \
2941 "\tset_ingress_map [vlan-name] [skb_priority] [vlan_qos]\n" \
2942 "\tset_name_type [name-type]"
2943
2944#define vi_trivial_usage \
2945 "[OPTION] [FILE]..."
2946#define vi_full_usage \
2947 "edit FILE.\n\n" \
2948 "Options:\n" \
2949 "\t-R\tRead-only- do not write to the file."
2950
2951#define vlock_trivial_usage \
2952 "[OPTIONS]"
2953#define vlock_full_usage \
2954 "Lock a virtual terminal. A password is required to unlock\n" \
2955 "Options:\n" \
2956 "\t-a\tLock all VTs"
2957
2958#define watch_trivial_usage \
2959 "[-n <seconds>] COMMAND..."
2960#define watch_full_usage \
2961 "Executes a program periodically.\n" \
2962 "Options:\n" \
2963 "\t-n\tLoop period in seconds - default is 2."
2964#define watch_example_usage \
2965 "$ watch date\n" \
2966 "Mon Dec 17 10:31:40 GMT 2000\n" \
2967 "Mon Dec 17 10:31:42 GMT 2000\n" \
2968 "Mon Dec 17 10:31:44 GMT 2000"
2969
2970#define watchdog_trivial_usage \
2971 "[-t <seconds>] DEV"
2972#define watchdog_full_usage \
2973 "Periodically write to watchdog device DEV.\n" \
2974 "Options:\n" \
2975 "\t-t\tTimer period in seconds - default is 30."
2976
2977#define wc_trivial_usage \
2978 "[OPTION]... [FILE]..."
2979#define wc_full_usage \
2980 "Print line, word, and byte counts for each FILE, and a total line if\n" \
2981 "more than one FILE is specified. With no FILE, read standard input.\n\n" \
2982 "Options:\n" \
2983 "\t-c\tprint the byte counts\n" \
2984 "\t-l\tprint the newline counts\n" \
2985 "\t-L\tprint the length of the longest line\n" \
2986 "\t-w\tprint the word counts"
2987#define wc_example_usage \
2988 "$ wc /etc/passwd\n" \
2989 " 31 46 1365 /etc/passwd\n"
2990
2991#define wget_trivial_usage \
2992 "[-c|--continue] [-q|--quiet] [-O|--output-document file]\n" \
2993 "\t\t[--header 'header: value'] [-Y|--proxy on/off] [-P DIR] url"
2994#define wget_full_usage \
2995 "wget retrieves files via HTTP or FTP\n\n" \
2996 "Options:\n" \
2997 "\t-c\tcontinue retrieval of aborted transfers\n" \
2998 "\t-q\tquiet mode - do not print\n" \
2999 "\t-P\tSet directory prefix to DIR\n" \
3000 "\t-O\tsave to filename ('-' for stdout)\n" \
3001 "\t-Y\tuse proxy ('on' or 'off')"
3002
3003#define which_trivial_usage \
3004 "[COMMAND ...]"
3005#define which_full_usage \
3006 "Locates a COMMAND."
3007#define which_example_usage \
3008 "$ which login\n" \
3009 "/bin/login\n"
3010
3011#define who_trivial_usage \
3012 " "
3013#define who_full_usage \
3014 "Prints the current user names and related information"
3015
3016#define whoami_trivial_usage \
3017 ""
3018#define whoami_full_usage \
3019 "Prints the user name associated with the current effective user id."
3020
3021#ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
3022#define USAGE_XARGS_CONFIRMATION(a) a
3023#else
3024#define USAGE_XARGS_CONFIRMATION(a)
3025#endif
3026#ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
3027#define USAGE_XARGS_TERMOPT(a) a
3028#else
3029#define USAGE_XARGS_TERMOPT(a)
3030#endif
3031#ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
3032#define USAGE_XARGS_ZERO_TERM(a) a
3033#else
3034#define USAGE_XARGS_ZERO_TERM(a)
3035#endif
3036
3037
3038#define xargs_trivial_usage \
3039 "[COMMAND] [OPTIONS] [ARGS...]"
3040#define xargs_full_usage \
3041 "Executes COMMAND on every item given by standard input.\n\n" \
3042 "Options:\n" \
3043 USAGE_XARGS_CONFIRMATION("\t-p\tPrompt the user about whether to run each command\n") \
3044 "\t-r\tDo not run command for empty readed lines\n" \
3045 USAGE_XARGS_TERMOPT("\t-x\tExit if the size is exceeded\n") \
3046 USAGE_XARGS_ZERO_TERM("\t-0\tInput filenames are terminated by a null character\n") \
3047 "\t-t\tPrint the command line on stderr before executing it."
3048#define xargs_example_usage \
3049 "$ ls | xargs gzip\n" \
3050 "$ find . -name '*.c' -print | xargs rm\n"
3051
3052#define yes_trivial_usage \
3053 "[OPTION]... [STRING]..."
3054#define yes_full_usage \
3055 "Repeatedly outputs a line with all specified STRING(s), or 'y'."
3056
3057#define zcat_trivial_usage \
3058 "FILE"
3059#define zcat_full_usage \
3060 "Uncompress to stdout."
3061
3062#endif /* __BB_USAGE_H__ */
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
diff --git a/urunlevel/my_linux/Config.in b/urunlevel/my_linux/Config.in
new file mode 100644
index 0000000..89f3c24
--- /dev/null
+++ b/urunlevel/my_linux/Config.in
@@ -0,0 +1,32 @@
1#
2# For a description of the syntax of this configuration file,
3# see scripts/kbuild/config-language.txt.
4#
5
6menu "My Linux Utilities"
7
8config CONFIG_GETPKG
9 bool "getpkg"
10 default y
11 help
12 An implementation of the My Linux getpkg script.
13
14config CONFIG_LINUXRC
15 bool "linuxrc"
16 default y
17 help
18 An implementation of the linuxrc boot script.
19
20config CONFIG_MAN
21 bool "man"
22 default y
23 help
24 An implementation of the My Linux man script.
25
26config CONFIG_RCS
27 bool "rcS"
28 default y
29 help
30 An implementation of rcS.
31
32endmenu
diff --git a/urunlevel/my_linux/Makefile b/urunlevel/my_linux/Makefile
new file mode 100644
index 0000000..5160a99
--- /dev/null
+++ b/urunlevel/my_linux/Makefile
@@ -0,0 +1,32 @@
1# Makefile for busybox
2#
3# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18#
19
20top_srcdir=..
21top_builddir=..
22srcdir=$(top_srcdir)/my_linux
23MY_LINUX_DIR:=./
24include $(top_builddir)/Rules.mak
25include $(top_builddir)/.config
26include $(srcdir)/Makefile.in
27all: $(libraries-y)
28-include $(top_builddir)/.depend
29
30clean:
31 rm -f *.o *.a $(AR_TARGET)
32
diff --git a/urunlevel/my_linux/Makefile.in b/urunlevel/my_linux/Makefile.in
new file mode 100644
index 0000000..db30a61
--- /dev/null
+++ b/urunlevel/my_linux/Makefile.in
@@ -0,0 +1,40 @@
1# Makefile for busybox
2#
3# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18#
19
20MY_LINUX_AR:=my_linux.a
21ifndef $(MY_LINUX_DIR)
22MY_LINUX_DIR:=$(top_builddir)/my_linux/
23endif
24srcdir=$(top_srcdir)/my_linux
25
26MY_LINUX-y:=
27MY_LINUX-$(CONFIG_GETPKG) += getpkg.o
28MY_LINUX-$(CONFIG_LINUXRC) += linuxrc.o
29MY_LINUX-$(CONFIG_MAN) += man.o
30MY_LINUX-$(CONFIG_MAN) += mkrootfs.o
31MY_LINUX-$(CONFIG_RCS) += rcS.o
32
33libraries-y+=$(MY_LINUX_DIR)$(MY_LINUX_AR)
34
35$(MY_LINUX_DIR)$(MY_LINUX_AR): $(patsubst %,$(MY_LINUX_DIR)%, $(MY_LINUX-y))
36 $(AR) -ro $@ $(patsubst %,$(MY_LINUX_DIR)%, $(MY_LINUX-y))
37
38$(MY_LINUX_DIR)%.o: $(srcdir)/%.c
39 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
40
diff --git a/urunlevel/my_linux/Trinux/README b/urunlevel/my_linux/Trinux/README
new file mode 100644
index 0000000..b07fa7f
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/README
@@ -0,0 +1,346 @@
1Trinux Documentation Matthew Franz <mfranz@cisco.com>
2http://trinux.sf.net/docs.txt 21 August 2003
3
40. Introduction
5
6 0.1 What is Trinux?
7
8 Trinux is a ramdisk-based Linux distribution that was first
9 released in April of 1998 and has been maintained on and off
10 since then. Like other Linux distributions it consists of a
11 Linux kernel, base utilities, and a variety of packages. Like
12 many embedded distributions, Trinux uses Busybox, which contains
13 small versions of common utilities. See http://www.busybox.net.
14
15 0.2 Where can I get the source?
16
17 Many of the standard utilities came from Slackware 7.1 or
18 when components needed to be upgraded, I pulled the source
19 from the Debian stable. The "original code" would be in the
20 /linuxrc script that is executed within
21
22 0.3 Installation
23
24 Trinux is released in either 1.4 meg floppy images or small ISO
25 images. For the floppy images use dd on unix boxes or rawrite
26 on Windows. Search the web for info.
27
28 0.4 If in doubt look at the /linuxrc script!
29
301. Boot Media
31
32 1.1 Common Format
33
34 * bzImage - compressed linux kernel
35 * tux - trinux configuration directory (like /etc on Unix) that
36 gets copied to /etc/tux when trinux boots
37 * bootpkg - packages that need to be loaded early
38 * kpkg - modular kernel packages
39 * initrd.gz - compressed initial ramdisk
40 * modules - raw (*.o) modules will be automatically loaded
41
42 1.2 Floppy Disks
43
44 Trinux uses MS-DOS (vfat actually) formatted disks and syslinux
45 as the bootloader. The files/directories described in 1.1 are
46 directly off the root of the drive.
47
48 * syslinux.cfg - bootloader configuration file
49 * ldlinux.sys - SYSLINUX bootloader (http://syslinux.zytor.com/)
50
51 1.3 CD-ROM
52
53 Bootable CD's are ISO9660 filesytem contain 2 directories:
54 * isolinux - bzImage, initrd.gz, isolinux.bin, isolinux.cfg
55 * trinux - bootpkg, kpkg, modules, tux
56
57 1.4 Fixed Partition (IDE Drive)
58
59 Trinux can also be booted from a Windows 95/98, MS-DOS, or
60 FreeDOS partition using loadlin.exe. This is an option for older
61 hardware that might not have a CD-ROM (or a bootable one) or
62 if you want to load packages from a compact Flash drive using an
63 IDE Compact-Flash Adapter.
64
65 1.4.1 Prepping the Drive
66
67 Use a Windows 95/98 or MS-DOS boot disk or the Trinux FreeDOS
68 Utility Disk (available on the downloads page) to create a FAT
69 partition. This involves running FDISK, FORMAT, and SYS. You
70 should copy loadlin.exe to the drive and it is also useful to have
71 a text editor (FreeDOS has TE) to edit batch files. You will
72 need to create trinux directory. My C:\ drive (mounted from
73 within Trinux as a vfat) looks like this:
74
75 trinux> ls -al
76 root root 16384 Jul 24 23:28 .
77 root root 832 Sep 3 2002 ..
78 root root 2048 Jul 20 18:51 .links
79 root root 50 Jul 20 17:35 autoexec.bat
80 root root 618999 Jul 20 18:11 bzimage
81 root root 86561 Aug 15 2001 command.com
82 root root 45836 Jul 20 17:35 fdisk.exe
83 root root 13741 Jul 20 17:35 format.exe
84 root root 600357 Jul 21 01:01 initrd.gz
85 root root 75663 Sep 3 2001 kernel.sys
86 root root 32177 Jul 20 17:35 loadlin.exe
87 root root 32719 Jul 20 17:35 loadlin.txt
88 root root 2048 Jul 20 18:33 old
89 root root 8634 Jul 20 17:36 sys.com
90 root root 44706 Jul 20 17:35 te.exe
91 root root 2048 Jul 21 12:31 trinux
92
93 TRINUX.BAT on the FreeDOS boot floppy contains the following
94 which I renamed to AUTOEXEC.BAT once I new it was stable.
95
96 loadlin bzimage initrd=initrd.gz root=/dev/ram0 rw
97
98 I have had mixed results with FreeDOS, so it might be best
99 to find a Windows 95/98/SE boot disk with fdisk and format.
100 I found a DOS 6.22 boot disk with the right tools from
101 http://www.bootdisk.com.
102
103 Copy a kernel that has IDE support (all the kernels on the
104 boot floppies after Trinux 0.890 should have the or a kernel
105 from the CD-ROM will work to) and an initrd.gz to the c:\
106 drive. You can do this from DOS or from Linux.
107
108 1.4.2 Copying necessary files to the DOS partition
109
110 Boot with a Trinux floppy (or CD-ROM) that has IDE support
111 and then mount the MS-DOS partition with the following
112 command
113
114 # mount -t vfat /dev/hda1 /mnt
115
116 This assumes the first IDE drive and should work for most
117 cases. Now create (or cd) the trinux directory on that
118 partition and create the subdirectories for packages
119
120 # cd /mnt/trinux
121 # mkdir bootpkg kpkg pkg modules
122 # mkdir -p tux/config
123 # mkdir tux/
124
125 Now you need to get a minimum set of packages into the bootpkg
126 directory. If you have network access you can download them with
127 links (getpkg links) or you can copy them to floppies. I have
128 the following in mine:
129
130 root root 245776 Jul 20 19:17 baselib.tgz
131 root root 15932 Jul 20 18:17 dhcpcd.tgz
132 root root 90312 Jul 20 18:17 dnslibs.tgz
133 root root 163951 Jul 21 12:28 iptables.tgz
134 root root 131200 Jul 21 12:28 netfilter.tgz
135 root root 77834 Jul 20 19:22 pthread.tgz
136 root root 378444 Jul 20 19:22 term.tgz
137
138 These will always get loaded. You can also put packages in the
139 pkg directory and these may/may not load depending on your
140 configuration.
141
142 Remember, after you are through modifying the partition, it
143 needs to be unmounted with:
144
145 #umount /dev/hda1
146 or
147 #umount /mnt
148
149 1.4.3 Configuarition
150
151
1522. Networking
153
154 2.1 Hardware Detection
155
156 In order for you to use networking your interface(s) must be
157 detected by the kernel. In order for this to occur you must either
158 have support for your NIC compiled into the kernel or use a kernel
159 module. Older versions of Trinux had support for the most common
160 NiCs built in, but that is no longer the case.
161
162 If your hardware was succuessfully found
163
164 # dmesg | grep eth0
165 eth0: OEM i82557/i82558 10/100 Ethernet, 00:03:47:B9:12:08, IRQ 11
166
167 2.2 Module Selection
168
1693. Kernel Modules
170
171 Raw (non-packaged kernel modules are available at:
172 http://trinux.sf.net/kernel/
173
174 Packaged kernel modules are available at http://trinux.sf.net/pkg/2.4.x/
175 and may be installed with the "getkpkg <name>"
176
177 Trinux puts all packages in /lib/modules or /usr/lib/modules instead
178 of the standard linux convention of /lib/modules/2.4.x/...
179
1804. Packages
181
182 4.1 Package Format
183
184 Packages are simply tarballs with an initialization script that
185 will be executed from within /etc/init.d/package_name or
186 /etc/init.m/kernel_package_name
187
188 4.2 Scripts
189
190 * pkgadd - loads a package from a local filesystem
191 * getpkg - loads the package from the network
192 * getkpkg - loads a kernel package from the network
193 * pkglist - lists available packages
194 * rmpkg - deletes package
195 * mypkg - shows packages currently installed
196
197 4.3 Building your own
198
199 All the Trinux packages are compiled with glibc 2.1.3 using
200 Slackware 7.1. I upgraded the compiler to gcc 2.95 and have upgraded
201 libraries as necessary.
202
203 4.4 Adding packages after bootup
204
205 You can either use the getpkg/getkpkg commands to load a package
206 from the network. If /etc/tux/config/localpkg is set
207 (added 0.891)
208
209 4.5 Configuration
210
211 Add list of package (in order) to /etc/tux/config/pkglist and these
212 will be loaded at boot
213
214 4.6 Miscellaneous
215
2165. Filesystems
217
218 5.1 Supported Filesytems
219
220 Trinux may only have support for a few filesystems such as minix
221 vfat (Windows) and ISO9660 (for CDROMs). To see which filesystems
222 are currently supported in the kernel:
223
224 # cat /proc/filesystems | grep -v nodev
225 minix
226 vfat
227 iso9660
228 reiserfs
229
230 In this case I installed the reiserfs module:
231
232 # lsmod
233 reiserfs 165600 1
234 3c59x 24560 1
235 8139too 13396 1
236 mii 2092 0 [8139too]
237
238
239 To mount a device you use the following command:
240
241 mount <device> -t <filesystem type> <mount point)
242
243 So to mount the floppy you would
244
245 You can determine the which IDE devices are present by the following
246 command:
247
248 # dmesg | grep hd
249 ide0: BM-DMA at 0x1850-0x1857, BIOS settings: hda:DMA, hdb:pio
250 ide1: BM-DMA at 0x1858-0x185f, BIOS settings: hdc:pio, hdd:pio
251 hda: IC25N040ATCS04-0, ATA DISK drive
252 hda: 78140160 sectors (40008 MB) w/1768KiB Cache, CHS=5168/240/63
253 hda: hda1 hda2 hda3 < hda5 hda6 > hda4
254 hde: LEXAR ATA FLASH, ATA DISK drive
255 hde: 96384 sectors (49 MB) w/1KiB Cache, CHS=753/4/32
256 hde: hde1
257
258 So assuming hde1 were a vfat partition, you would use:
259
260 # mount -t vfat /dev/hde1 /mnt
261 # mount
262 /dev/hda2 on / type ext3 (rw,errors=remount-ro)
263 proc on /proc type proc (rw)
264 devpts on /dev/pts type devpts (rw,gid=5,mode=620)
265 /dev/hda4 on /alt type reiserfs (rw)
266 /trinux/boot/trinux.img on /loop type vfat (rw,loop=/dev/loop0)
267 /dev/hde1 on /mnt type vfat (rw)
268
269 This was from my laptop. Within Trinux, the following is more
270 typical:
271
272 # mount
273 /dev/ram0 on / type minix (rw)
274 /proc on /proc type proc (rw)
275 /dev/null on /usr type tmpfs (rw)
276 /dev/null on /home type tmpfs (rw)
277 /dev/null on /var type tmpfs (rw)
278 /dev/hda2 on /hda2 type reiserfs (rw)
279
280
281 5.3 Swap
282
283 Usually, you probably have enough memory (otherwise you wouldn't
284 be running ramdisks) but if you want to set up a swap file or swap
285 filesystem, put the name of the file (within an existing filesytem)
286 the name of the partition (/dev/hda3) in /etc/tux/config/swap and
287 the linuxrc will automatically run mkswap and swapon. You may
288 want to make sure the swaputils.tgz package is included,
289 although it will be loaded automatically if /sbin/makeswap
290 isn't found.
291
292 5.4 Tmpfs
293
294 A neat feature that came out in 2.4 was the ability to use the
295 temporary or shared memory filesystem instead of ramdisks. The key
296 advantage is that ramdisks are completed allocated when the are
297 created, but tmpfs partitions only use RAM as they are filled.
298
299
300 Trinux only has support for a minimal set of filesystems
301
3026. Management and Monitoring
303
304 Although it is probably not the most common option, Trinux can be
305 used in a headless server capacity
306
307 6.1 Serial Console
308
309 6.2 SSH Remote Logins
310
311 6.3 Enabling Cisco Discovery Protocol (CDP)
312
313 6.4 Building a Local Package Server
314
3157. Miscellaneous
316
317 6.1 Troubleshooting
318
319 Recent versions of trinux have a /sbin/hwinfo script that gathers
320 hardware information about the system and saves it to the file
321 /tmp/hwinfo. It basically saves the output of the dmesg command
322 and copies the values of some /proc files that can be used to help
323 troubleshoot hardware problems. The following commands allow you to
324 save this file to the boot floppy (assuming you have enough room)
325
326 # fmount
327 # cp /tmp/hwinfo /floppy
328 # fumount
329
330 You can then post some or all of this file to the trinux-talk mailing
331 list when you have a problem.
332
333 6.2 Where to get help
334
335 You should subscribe to the trinux-talk mailing list
336
337 6.3 Floppy Errors
338
339 If you do not have a floppy drive or you floppy drive takes very
340 long to time out, append "nofloppy" to the kernel boot arguments.
341 CD-ROM booting automatically disables this checking. I had to do
342 this on an old Compaq 486-66 because it was taking several minutes
343 to complete the bootup:
344
345 loadlin bzimage initrd=initrd.gz root=/dev/ram0 rw nofloppy
346
diff --git a/urunlevel/my_linux/Trinux/chkfixed b/urunlevel/my_linux/Trinux/chkfixed
new file mode 100755
index 0000000..4cbb45b
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/chkfixed
@@ -0,0 +1,99 @@
1#!/bin/sh
2#
3# chkfixed - look for legitimate parititions and build mount points
4# and populate /etc/proc
5#
6
7rm /tmp/partitions 2> /dev/null
8
9
10[ -d /etc/proc ] || mkdir /etc/proc
11
12if [ -f /etc/tux/config/fstab ]
13then
14 echo "fstab found, exiting..."
15 exit 1
16fi
17
18for i in `grep -v nodev /proc/filesystems`
19do
20 echo "$i"
21done > /etc/proc/availfs
22
23echo "The following filesystems are supported:"
24cat /etc/proc/availfs
25echo
26
27cdpart=`dmesg | grep D-ROM | grep hd | cut -d: -f1`
28
29if [ "$cdpart" ]
30then
31 echo "A CD-ROM was found at $cdpart"
32 echo "$cdpart" > /tmp/partitions
33fi
34
35partitions=`dmesg | grep ' hd[abcdef]' | cut -d':' -f2`
36scsiparts=`dmesg | grep "^ sd[abcdef][12345]"`
37
38echo IDE Partitions: $partitions
39echo SCSI Partitions: $scsiparts
40
41for i in $partitions
42do
43
44 if echo "$partitions" | grep unknown > /dev/null
45 then
46 echo "Unkown partition"
47 else
48 echo $i >> /tmp/partitions
49 fi
50done
51
52for i in $partitions
53do
54
55 if echo "$partitions" | grep unknown > /dev/null
56 then
57 echo "Unkown partition"
58 else
59 echo $i >> /tmp/partitions
60 fi
61done
62
63
64for i in $scsiparts
65do
66 echo $i >> /tmp/partitions
67done
68
69if [ ! -f /tmp/partitions ]
70then
71 echo "No fixed partitions found!"
72 exit
73fi
74
75sort /tmp/partitions | uniq | grep "hd" > /etc/proc/partitions
76sort /tmp/partitions | uniq | grep "sd" >> /etc/proc/partitions
77
78echo "The following partitions were found: "
79cat /etc/proc/partitions
80echo
81
82##echo "The following filesystems were found: "
83for i in `cat /etc/proc/partitions`
84do
85 mkdir /$i 2> /dev/null
86
87 for j in `cat /etc/proc/availfs`
88 do
89 echo -n Checking $i:
90 if mount -o ro -t $j /dev/$i /$i 2> /dev/null > /dev/null
91 then
92 echo " found $j"
93 echo "$i:$j" >> /etc/tux/config/fstab
94 umount /dev/$i 2> /dev/null > /dev/null
95 else
96 echo
97 fi
98 done
99done
diff --git a/urunlevel/my_linux/Trinux/fmount b/urunlevel/my_linux/Trinux/fmount
new file mode 100755
index 0000000..db8595b
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/fmount
@@ -0,0 +1,2 @@
1#!/bin/sh
2mount -t vfat /dev/fd0 /floppy
diff --git a/urunlevel/my_linux/Trinux/fumount b/urunlevel/my_linux/Trinux/fumount
new file mode 100755
index 0000000..003ce14
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/fumount
@@ -0,0 +1,3 @@
1#!/bin/sh
2cd /
3umount /dev/fd0
diff --git a/urunlevel/my_linux/Trinux/gethome b/urunlevel/my_linux/Trinux/gethome
new file mode 100755
index 0000000..c47c238
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/gethome
@@ -0,0 +1,61 @@
1#!/bin/sh
2
3if [ "$1" ]
4then
5 home=$1
6else
7 home="home"
8fi
9
10homeline=`cat /etc/tux/config/home`
11
12if [ "$homeline" ]
13then
14 PROTO=`cut -d':' -f1 /etc/tux/config/home`
15 HOST=`cut -d':' -f2 /etc/tux/config/home`
16 USER=`cut -d':' -f3 /etc/tux/config/home`
17else
18 echo -n "ftp or ssh: "
19 read PROTO
20 echo -n "Host: "
21 read HOST
22 echo -n "User: "
23 read USER
24 echo $PROTO:$HOST:$USER > /etc/tux/config/home
25fi
26
27
28echo "Retrieving home directory from $USER@$HOST via $PROTO"
29
30if [ $PROTO = "ssh" ]
31then
32 scp $USER@$HOST:~/$home.tgz /
33fi
34
35if [ $PROTO = "ftp" ]
36then
37 echo "Using FTP to transfor $home.tgz -- your passwords are sniffable"
38
39 if [ -x /usr/bin/curl ]
40 then
41 curl -u $USER ftp://$HOST/$home.tgz > /$home.tgz
42
43 else
44 echo "Curl is not installed. You will have to login with your"
45 echo "username and upload $home.tgz manually"
46
47 ftp $HOST
48
49 fi
50fi
51
52cd /
53echo
54echo "Uncompressing archive..."
55gunzip -c $home.tgz | tar xvf -
56rm /$home.tgz 2> /dev/null
57
58
59
60
61
diff --git a/urunlevel/my_linux/Trinux/getkpkg b/urunlevel/my_linux/Trinux/getkpkg
new file mode 100755
index 0000000..ceab0ce
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/getkpkg
@@ -0,0 +1,9 @@
1#!/bin/sh
2
3if [ "$1" ]
4then
5 KERNEL=`uname -r`
6 getpkg $KERNEL/$1
7else
8 echo "No package specified!"
9fi
diff --git a/urunlevel/my_linux/Trinux/getpkg b/urunlevel/my_linux/Trinux/getpkg
new file mode 100755
index 0000000..adeab02
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/getpkg
@@ -0,0 +1,171 @@
1#!/bin/sh
2#
3# getpkg - retrieves a single package from package server
4#
5# Author: Matthew D. Franz <mdfranz@io.com>
6#
7# $1 - name of package
8# $2 - URL of server
9#
10############################################################################
11
12[ -d /var/pkg/contents ] || mkdir -p /var/pkg/contents
13
14# if in current directory, call pkgadd
15
16if [ -f "$1" ]
17then
18 pkgadd $i
19else
20 if [ -f /etc/tux/config/localpkg ]
21 then
22 print "Using local package repository"
23 if [ -f /etc/proc/fixed ]
24 then
25 print "Found /etc/proc/fixed"
26 fi
27 fi
28fi
29
30
31if [ -f /etc/tux/config/proxy ]
32then
33 SNARF_PROXY=`cat /etc/tux/config/proxy`
34 export SNARF_PROXY
35fi
36
37mkdir /etc/init.d/running 2> /dev/null
38
39if [ "$1" = "list" ]
40then
41 pkglist
42 exit
43fi
44
45if [ "$1" = "all" ]
46 then
47 echo "Downloading all packages..."
48
49 if [ ! -f /etc/tux/config/eth0 ]
50 then
51 echo "Network was not configured"
52 if dmesg | grep eth0 > /dev/null
53 then
54 echo -n "Attempting DHCP on eth0: "
55 if dhcpcd > /dev/null 2> /dev/null
56 then
57 echo "Successful"
58 else
59 echo "Failed"
60 exit
61 fi
62 else
63 echo "No ethernet interfaces were found"
64 exit
65 fi
66 fi
67
68 if [ -f /etc/tux/config/pkglist ]
69 then
70 pkglist=`cat /etc/tux/config/pkglist`
71 for i in $pkglist
72 do
73 getpkg $i
74 done
75 else
76 echo "No package list found, retrieving a minimal set"
77 getpkg baselib
78 getpkg term
79 getpkg vi
80 getpkg tcpdump
81 fi
82
83 exit
84fi
85
86if [ "$1" = "" ]
87then
88 echo; echo "You did not specify a package or server!"; echo
89 echo "getpkg all will load all the packages from /etc/tux/config/pkglist"
90 getpkg all
91else
92 if [ "$2" = "" ]
93 then
94 if [ "$URL" = "" ]
95 then
96 if [ -f /etc/tux/config/server ]
97 then
98 blah=1
99 else
100 echo -n "Enter URL for package retrieval: "
101 read URL
102 if [ "$URL" != "" ]
103 then
104 echo "Using $URL as your package server from now on..."
105 echo "$URL" > /etc/tux/config/server
106 fi
107 fi
108 fi
109 else
110 URL=$2
111 fi
112
113 if echo $1 | grep tgz > /dev/null
114 then
115 FILE=$1
116 else
117 FILE=$1.tgz
118 fi
119
120 cd /
121
122 PREFIX=`basename $FILE ".tgz"`
123
124 #echo $PREFIX
125
126 MODPKGNAME=`echo ${1} | cut -d'/' -f2`
127
128
129 if echo $MODPKGNAME | grep tgz > /dev/null
130 then
131 MODPKGNAME=`basename $MODPKGNAME ".tgz"`
132 fi
133
134 # Loop through servers listed in
135
136 for URL in `cat /etc/tux/config/server`
137 do
138 if snarf $URL - > /dev/null 2> /dev/null
139 then
140 echo "Retrieving ${URL}${FILE}"
141 output=`snarf ${URL}/${FILE} - | gunzip -c | tar xvf -`
142 fi
143
144 echo $output > /var/pkg/contents/$PREFIX
145
146 if [ -f /etc/init.d/${PREFIX} ]
147 then
148 chmod a+x /etc/init.d/${PREFIX} 2> /dev/null
149 echo; echo "Initializing ${PREFIX}"
150 /etc/init.d/${PREFIX} 2> /dev/null
151 fi
152
153
154 if [ "$MODPKGNAME" ]
155 then
156 chmod a+x /etc/init.m/${MODPKGNAME} 2> /dev/null
157 if [ -x /etc/init.m/$MODPKGNAME ]
158 then
159 /etc/init.m/$MODPKGNAME
160 echo "Initializing $1 modules"
161 fi
162 fi
163
164
165 break
166 done
167
168 [ $? -eq 0 ] || exit 1
169
170fi
171
diff --git a/urunlevel/my_linux/Trinux/hwinfo b/urunlevel/my_linux/Trinux/hwinfo
new file mode 100755
index 0000000..5e32126
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/hwinfo
@@ -0,0 +1,23 @@
1#!/bin/sh
2
3echo "Gathering hardware information, saving to /tmp/hwinfo"
4
5echo "[--- dmesg ---]" > /tmp/hwinfo
6dmesg >> /tmp/hwinfo
7echo "[--- /proc/devices ---]" >> /tmp/hwinfo
8cat /proc/devices >> /tmp/hwinfo
9echo "[--- /proc/iomem ---]" >> /tmp/hwinfo
10cat /proc/iomem >> /tmp/hwinfo
11echo "[--- /proc/ioports ---]" >> /tmp/hwinfo
12cat /proc/ioports >> /tmp/hwinfo
13echo "[--- /proc/interrupts ---]" >> /tmp/hwinfo
14cat /proc/interrupts >> /tmp/hwinfo
15echo "[--- /proc/pci ---]" >> /tmp/hwinfo
16cat /proc/pci >> /tmp/hwinfo
17echo "[--- /proc/meminfo ---]" >> /tmp/hwinfo
18cat /proc/meminfo >> /tmp/hwinfo
19echo "[--- /proc/partitions ---]" >> /tmp/hwinfo
20cat /proc/partitions >> /tmp/hwinfo
21echo "[--- /proc/modules ---]" >> /tmp/hwinfo
22cat /proc/modules >> /tmp/hwinfo
23
diff --git a/urunlevel/my_linux/Trinux/killmod b/urunlevel/my_linux/Trinux/killmod
new file mode 100755
index 0000000..7dc80b6
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/killmod
@@ -0,0 +1,8 @@
1#!/bin/sh
2
3echo "Unloading all kernel modules"
4for i in `lsmod`
5do
6 mod=`echo $i | cut -d' ' -f1`
7 rmmod $mod 2> /dev/null
8done
diff --git a/urunlevel/my_linux/Trinux/linuxrc b/urunlevel/my_linux/Trinux/linuxrc
new file mode 100755
index 0000000..4597234
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/linuxrc
@@ -0,0 +1,1261 @@
1#!/bin/sh
2#
3# linuxrc - main trinux initialization script
4#
5# Author: Matthew Franz <mfranz@cisco.com>
6# Bill Burdick for the User-Mode-Linux fixes
7########################################################################
8#
9# Attempts to do the following:
10#
11# - Determine where trinux booted from [ Floppy/CD-ROM/IDE/UML ]
12# - Mount boot device and copy configuration files to /etc/tux
13# - Initialize and create ramdisks/tmpfs or mount filesystems
14# - Determine where packages are located and to be loaded from
15# - Initialize kernel modules and detect hardware
16# - Configure and enable networking
17# - Load and initialize packages
18# - Initialize system daemons
19#
20########################################################################
21## Define stuff that is probably rejected by busybox
22########################################################################
23
24UMLROOT="/trinux-uml"
25PATH="/usr/bin:/usr/sbin:/bin:/sbin:/usr/local/bin:/usr/local/sbin"
26TERM=linux
27PS1="trinux> "
28PS2='>'
29
30export PATH TERM PS1 PS2 VERSION PKGSRC BOOT PKGSRC BOOTFS FLCFG FXCFG PKGLIST FIXED
31umask 022
32[ -d /etc/proc ] || mkdir -p /etc/proc
33mount -t proc proc /proc
34mkdir -p /lib/modules
35mkdir -p /etc/tux/config
36ln -sf /proc/self/fd/0 /dev/stdin
37ln -sf /proc/self/fd/2 /dev/stderr
38ln -sf /proc/self/fd/1 /dev/stdout
39
40chmod a+w /tmp
41chmod a+w /dev/null
42
43#####################################################################
44## Gather information about system
45#####################################################################
46
47MEMORY=`grep MemTotal /proc/meminfo | cut -d':' -f2 | cut -d'k' -f1`
48KERNEL=`cat /proc/version | cut -d' ' -f3`
49CDEV=`dmesg | grep D-ROM | grep hd | cut -d: -f1 | sort | uniq` # CD-ROM devices
50FDEV=`dmesg | grep -v LDM | grep -v "ldm_val" | grep "^ [sh]d[a-f]" | cut -d':' -f2 | sort | uniq` # FIXED
51
52echo "Checking for fixed disks"
53/sbin/chkfixed
54
55
56
57echo "FDEV: $FDEV"
58echo "CDEV: $CDEV"
59sleep 1
60
61echo "$FDEV" > /tmp/fixed
62
63
64for i in `cat /tmp/fixed`
65do
66 echo $i
67done > /etc/proc/fixed
68
69
70[ "$CDEV" ] && echo "$CDEV" >> /etc/proc/fixed
71
72
73#check initial filesytem support
74
75for i in `grep -v nodev /proc/filesystems`
76do
77 echo $i
78done > /etc/proc/filesystems
79
80
81######################################################################
82### Special Probing stuff
83######################################################################
84
85## Did we boot from UML?
86#if dmesg | grep 'User-mode Linux' > /dev/null
87
88if grep ' ubd' /proc/devices > /dev/null
89then
90 echo "Trinux booted via User Mode Linux (UML)"
91 sleep 3
92 UML="true"
93 BOOT="UML"
94fi
95
96## Did we boot from ms-dos loadlin
97
98echo "Checking all vfat partitions for loadlin.exe"
99
100for i in `cat /etc/proc/fixed 2> /dev/null`
101do
102# [ -d /${i} ] || mkdir /${i}
103# echo "Checking $i"
104
105 if mount -o ro -t vfat /dev/${i} /mnt 2> /dev/null
106 then
107 echo -n "VFAT found on $i"
108 if ls /mnt/loadlin.exe 2> /dev/null
109 then
110 echo -n " found loadlin.exe"
111 if [ -d /mnt/trinux ]
112 then
113 echo " found trinux"
114 BOOT="/dev/${i}"
115 BOOTFS="vfat"
116 echo "BOOT=$BOOT"
117 echo "$i" > /etc/proc/fixedpkg
118 LOADLIN="true"
119 cd /
120 umount /mnt 2> /dev/null
121 break
122 fi
123 fi
124
125 fi
126 umount /mnt 2> /dev/null
127done
128
129# Check to see if checking for floppy drive should be disabled
130
131if grep nofloppy /proc/cmdline > /dev/null
132then
133 NOFLOPPY="true"
134 echo "Disabling checks for floppy drive"
135fi
136
137########################################################################
138# Determine where Trinux booted from in order of likelihood
139#
140# /dev/fd0 - floppy (this is normally the case)
141# /dev/hd[alpha] - IDE CD-ROM (usually /dev/hdc)
142# /dev/hd[numeric] - IDE Hard Disk (including flash disk)
143#
144# We assume that if a floppy is present and no-›
145#
146########################################################################
147#
148# first check if CD-ROM is present
149
150if [ "$CDEV" ]
151then
152 echo -n "Attempting to mount CD-ROM at $CDEV:"
153
154 if mount -t iso9660 /dev/${CDEV} /mnt 2> /dev/null > /dev/null
155 then
156 echo "successful"
157 if [ -d /mnt/trinux ]
158 then
159 echo "/trinux found on $CDEV"
160 PKGSRC=$CDEV # we assume packages will be loaded from it
161
162 # Now check and see if we booted from CD-ROM
163
164 if [ -d /mnt/isolinux ]
165 then
166 BOOT=/dev/${CDEV}
167 BOOTFS="iso9660"
168 NOFLOPPY="true"
169 echo $CDEV > /etc/proc/fixedpkg
170 fi
171 cd /
172 umount /mnt 2> /dev/null
173 fi
174 else
175 echo "failed"
176 [ "$UML" ] || BOOT="/dev/fd0"
177 fi
178fi
179
180if [ ! "$NOFLOPPY" ]
181then
182 echo "Checking for floppy in /dev/fd0"
183 sleep 1
184
185 if mount -t vfat /dev/fd0 /boot 2> /dev/null
186 then
187 [ -d /boot/bootpkg ] && BOOT="/dev/fd0"
188 [ -d /boot/tux ] && FLCFG="true"
189 [ -f /boot/tux/options/floppy ] && PKGSRC="/dev/fd0"
190 umount /boot 2> /dev/null
191
192 [ "$BOOT" = "/dev/fd0" ] && echo "Trinux booted from a floppy."
193 [ "$PKGSRC" = "/dev/fd0" ] && echo "Trinux will load packages from one or more floppies."
194 else
195 echo "Unable to mount boot floppy"
196 fi
197else
198 echo "Floppy checking is disabled"
199fi
200
201echo $BOOT > /etc/proc/boot
202echo $BOOTFS > /etc/proc/bootfs
203
204echo
205echo "========================"
206echo "BOOT: $BOOT"
207echo "KERNEL: $KERNEL"
208echo -n "CDEV: "
209
210if [ $CDEV ]
211then
212 echo "$CDEV"
213else
214 echo "none"
215fi
216
217echo -n "FDEV: "
218
219if [ "$FDEV" ]
220then
221 echo $FDEV
222else
223 echo "none"
224fi
225
226
227## Determine boot filesystem type
228
229if [ "$BOOT" = "/dev/fd0" ]
230then
231 BOOTFS="vfat"
232elif [ "$UML" ]
233then
234 BOOTFS="ext2"
235elif [ "$BOOT" = "$CDEV" ]
236then
237 BOOTFS="iso9660"
238fi
239
240echo "BOOTFS: $BOOTFS"
241echo "========================"
242sleep 2
243
244####################################################################
245# Determine where packages should be loaded from. By default, Trinux
246# will look at /etc/tux/config/pkgsrc otherwise it will look at
247# parameters passed from syslinux.cfg (i.e. pkgsrc=/dev/hda1).
248# Otherwise Trinux will assume network package loading unlesss
249# the network is unable to be configured
250####################################################################
251
252if grep 'pkg=floppy' /proc/cmdline > /dev/null
253then
254 PKGSRC="/dev/fd0"
255fi
256
257PKGSRC="network" ## Assume network package loading unless...
258
259#####################################################################
260## Mount the boot filesystem
261## 1) copy config from tux over
262## 2) install kernel module pkgs from kpkg
263#####################################################################
264
265if [ "$UML" ]
266then
267 echo
268 # mount the host ext2 filesystem RO so initial packages can be installed
269 mount none /boot -t hostfs -o $UMLROOT,ro
270else
271 mount -o ro -t $BOOTFS $BOOT /boot
272 VERSION=`cat /boot/version 2> /dev/null`
273 PS1="Trinux $VERSION> "
274fi
275
276[ "$BOOT" != "/dev/fd0" ] && PREFIX="trinux/"
277
278cd /boot
279
280#pwd
281#ls -al
282
283echo "Copying /tux from boot filesystem..."
284cp -a ${PREFIX}tux /etc
285
286
287echo "Copying modules from boot filesystem..."
288
289# support either within /trinux/modules or /trinux/*.o
290
291cp ${PREFIX}*.o /lib/modules 2> /dev/null
292cp ${PREFIX}modules/*.o /lib/modules 2> /dev/null
293cp ${PREFIX}modules/*.gz /lib/modules 2> /dev/null
294
295cd /lib/modules
296
297for i in `ls *.gz`
298do
299 FNAME=`basename $i .gz`
300 echo "Uncompressing $i"
301 gunzip $i
302 mv $FNAME $FNAME.o
303done
304
305if [ -f /etc/tux/version ]
306then
307 VERSION=`cat /etc/tux/version 2> /dev/null`
308else
309 VERSION="unknown"
310fi
311
312cd /boot
313if cd ${PREFIX}kpkg 2> /dev/null
314then
315 echo "Installing kernel module packages from boot device"
316 for i in `ls`
317 do
318 pkgadd $i
319 echo $i >> /etc/proc/kpkg.installed
320 done
321fi
322
323######## Store temporary scripts in scripts directory ###########
324
325if [ -d ${PREFIX}scripts ]
326then
327 echo "Copying local scripts to /bin:"
328 cd ${PREFIX}scripts
329 for i in `ls`
330 do
331 cp $i /bin/
332 chmod u+x /bin/$i
333 done
334fi
335
336cd /
337umount /boot
338
339echo "Unmounting boot filesystem"
340
341# load in kernel modules
342
343#cd /lib/modules
344
345if [ -f /etc/tux/config/modules ]
346then
347 while read i
348 do
349 echo "Installing $i"
350 insmod /lib/modules/$i 2> /dev/null > /dev/null
351 done < /etc/tux/config/modules
352fi
353
354
355echo "Waiting for modules to settle..."
356
357sleep 3
358
359#### Since modules have already been loaded now is a good
360#### time to scour the partitions, checking for devices
361
362echo "Checking for fixed disks"
363
364/sbin/chkfixed
365
366#### Check for a saved fixedpkg to avoid checking all found partitions
367
368if [ -f /etc/tux/config/fixedpkg ]
369then
370 echo -n "Found previously saved fixed package source: "
371 FIXEDPKG=`cat /etc/tux/config/fixedpkg`
372 if [ "$FIXEDPKG" = "cdrom" -o "$FIXEDPKG" = "cd-rom" ]
373 then
374 FIXEDPKG=$CDEV
375 fi
376
377 echo $FIXEDPKG
378 echo $FIXEDPKG > /etc/proc/fixed
379fi
380
381for i in `cat /etc/proc/fixed` # loop through fixed devices
382do
383 [ -d /${i} ] || mkdir /${i} # create mount point
384
385 for j in `cat /etc/proc/filesystems` # loop through supported fstype
386 do
387 #echo -n "Checking $i:"
388 if mount -o ro -t $j /dev/$i /$i 2> /dev/null > /dev/null
389 then
390 #echo " found $j"
391 echo "$i:$j" >> /etc/tux/config/fstab
392 umount /dev/$i 2> /dev/null > /dev/null 2> /dev/null
393 else
394 echo
395 fi
396 done
397done
398
399if [ -f /etc/tux/config/fstab ]
400then
401 echo "The following partitions/filesytems were found:"
402 cat /etc/tux/config/fstab
403 cat /etc/tux/config/fstab | sort | uniq > /tmp/fstab
404 cat /tmp/fstab > /etc/tux/config/fstab
405fi
406
407#########
408# Search filesystems for /trinux directories
409
410if [ -f /etc/proc/fixedpkg ]
411then
412 fixedpkg=`cat /etc/proc/fixedpkg`
413 echo "/trinux already found on $fixedpkg, aborting search"
414 mount
415else
416 if [ -f /etc/tux/config/fstab ]
417 then
418 for i in `cat /etc/tux/config/fstab`
419 do
420 part=`cut -d: -f1 /etc/tux/config/fstab`
421 fstype=`cut -d: -f2 /etc/tux/config/fstab`
422
423 if mount -t $fstype /dev/${part} /mnt 2> /dev/null
424 then
425 echo -n "Checking $part for trinux directory: "
426
427 if [ -d /mnt/trinux/ ]
428 then
429 echo " found"
430 umount /mnt 2> /dev/null
431 echo $part > /etc/proc/fixedpkg
432 break
433 else
434 echo " not found"
435 fi
436
437 cd /; umount /mnt 2> /dev/null
438 else
439 echo -n "Failed to mount $part"
440 fi
441 done
442 fi
443fi
444
445chmod a+x /etc/tux/init/first 2> /dev/null
446if [ -x /etc/tux/init/first ]
447then
448 . /etc/tux/init/first
449fi
450
451#################################################################
452################### Ramdisk building stuff ######################
453#################################################################
454
455if grep ' 2.4' /proc/version 2> /dev/null
456then
457 echo "Found 2.4.x kernel: tmpfs capable"
458 if [ -f /etc/tux/config/tmpfs ]
459 then
460 echo "Using tmpfs"
461 TMPFS="true"
462 fi
463else
464 TMPFS="false"
465fi
466
467#### If /etc/tux/config/corefs is present we use that for
468#### partitions *other* than root. If fstab is blank then
469#### everything is mounted as root. Trinux will attempt to mount
470#### to filesystem and will *not* reformat
471####
472#### An additional file (/etc/tux/config/suppfs) will be mounted
473#### later so that nfs/smbfs can be mounted
474####
475#### corefs format
476#### partition:mount point:size in Kb:filesystem:options
477####
478#### /dev/sda1:/var:512:minix:keep,ro
479####
480####
481#### possible filesystems
482#### vfat, minix, tmpfs, ram (actually minix)
483####
484#### plus anything compiled in your kernel
485
486if [ -f /etc/tux/config/corefs ]
487then
488 for i in `cat /etc/tux/config/corefs`
489 do
490 DEV=`echo $i | cut -d: -f1`
491 MOUNT=`echo $i | cut -d: -f2`
492 SIZE=`echo $i | cut -d: -f3`
493 FSTYPE=`echo $i | cut -d: -f4`
494 OPTIONS=`echo $i | cut -d: -f5`
495
496 echo "[DEV: $DEV]"
497 echo "MOUNT: $MOUNT"
498 echo "SIZE: $SIZE"
499 echo "FSTYPE: $FSTYPE"
500 echo "OPTIONS: $OPTIONS"
501
502 if [ ! "$DEV" ]
503 then
504 # if no device is specified, assume tmpfs
505 mount -n -t tmpfs -o size=${SIZE}000 /dev/null $MOUNT
506 else
507 mkdir $MOUNT 2> /dev/null
508
509 if grep "$FSTYPE" /proc/filesystems > /dev/null
510 then
511 if [ ! "$SIZE" ]
512 then
513
514 # assume entire partition should formatted
515 if [ "$FSTYPE" = "minix" ]
516 then
517 mkfs.minix $DEV
518 mount -t minix $DEV $MOUNT
519 else
520 echo "Currently only minix is supported: skipping $$DEV"
521 fi
522
523 fi # not $SIZE
524 else
525 # if no FSTYPE is specified, assume minix
526 mkfs.minix $DEV # 2> /dev/null > /dev/null
527 mount -t minix $DEV $MOUNT
528 fi
529
530 fi # no $DEV
531 done # loop through each line of corefs
532else
533 #
534 # Autosize ramdisks based on amount of RAM discovered
535 #
536
537 LIB=""
538 VAR=""
539 USR=""
540 USRLOC=""
541 HOMEP=""
542
543 echo "RAM: $MEMORY MB"
544 echo -n "RAM is "
545
546 if [ $MEMORY -lt 16000 ]
547 then
548 echo "< 16MB, you may run into problems"
549 USR="2048"
550 HOMEP="128"
551 VAR="512"
552 PKGMEM="min"
553 # echo "USR: $USR USRLOC: $USRLOC HOME: $HOMEP"
554 elif [ $MEMORY -lt 24000 ]
555 then
556 echo "> 16MB"
557 USR="4096"
558 HOMEP="256"
559 VAR="512"
560 PKGMEM="16"
561 # echo "USR: $USR USRLOC: $USRLOC HOME: $HOMEP"
562 elif [ $MEMORY -lt 32000 ]
563 then
564 echo "> 24MB"
565 USR="8192"
566 HOMEP="512"
567 VAR="1024"
568 PKGMEM="24"
569 # echo "USR: $USR USRLOC: $USRLOC HOME: $HOMEP"
570 elif [ $MEMORY -lt 48000 ]
571 then
572 echo "> 32MB"
573 USR="16384"
574 HOMEP="1024"
575 VAR="1024"
576 LIB="4896"
577 PKGMEM="32"
578
579 # echo "USR: $USR USRLOC: $USRLOC HOME: $HOMEP"
580 elif [ $MEMORY -lt 64000 ]
581 then
582 echo "> 48MB"
583 USR="16384"
584 LIB="8192"
585 USRLOC="8192"
586 HOMEP="2048"
587 VAR="2048"
588 PKGMEM="48"
589 # echo "USR: $USR USRLOC: $USRLOC HOME: $HOMEP"
590 elif [ $MEMORY -lt 96000 ]
591 then
592 echo "> 64MB"
593
594 LIB="8192"
595 USR="16384"
596 USRLOC="16384"
597 HOMEP="4096"
598 VAR="2048"
599 PKGMEM="64"
600 # echo "USR: $USR USRLOC: $USRLOC HOME: $HOMEP"
601 elif [ $MEMORY -lt 128000 ]
602 then
603 echo "> 96MB"
604 LIB="16384"
605 USR="16384"
606 USRLOC="32768"
607 HOMEP="8192"
608 VAR="4192"
609 PKGMEM="96"
610 # echo "USR: $USR USRLOC: $USRLOC HOME: $HOMEP"
611 else
612 echo "> 128MB"
613 USR="16384"
614 USRLOC="16384"
615 HOMEP="16384"
616 VAR="4192"
617 PKGMEM="128"
618 # echo "USR: $USR USRLOC: $USRLOC HOME: $HOMEP"
619 fi
620
621 #if [ "$LIB" != "" ]
622 #then
623 # echo "Creating /lib"
624 # echo "USR: $USR USRLOC: $USRLOC HOME: $HOMEP"
625
626 # if [ "$TMPFS" = "true" ]
627 # then
628 # mount -n -t tmpfs -o size=${LIB}000 /dev/null /lib
629 # else
630 # mkdir /usr 2> /dev/null
631 # mkfs.minix /dev/ram3 $LIB 2> /dev/null > /dev/null
632 # mount -t minix /dev/ram7 /lib
633 # fi
634 #fi
635
636 if [ "$USR" != "" ]
637 then
638 echo "Creating /usr"
639 # echo "USR: $USR USRLOC: $USRLOC HOME: $HOMEP"
640
641 if [ "$TMPFS" = "true" ]
642 then
643 mount -n -t tmpfs -o size=${USR}000 /dev/null /usr
644 else
645 mkdir /usr 2> /dev/null
646 mkfs.minix /dev/ram3 $USR 2> /dev/null > /dev/null
647 mount -t minix /dev/ram3 /usr
648 fi
649 fi
650
651 if [ "$USRLOC" -gt 0 ]
652 then
653
654 echo "Creating /usr/local"
655 # echo "USR: $USR USRLOC: $USRLOC HOME: $HOMEP"
656 mkdir /usr/local 2> /dev/null
657
658 if [ "$TMPFS" = "true" ]
659 then
660 mount -n -t tmpfs -o size=${USRLOC}000 /dev/null /usr/local
661 else
662 mkfs.minix /dev/ram4 $USRLOC 2> /dev/null > /dev/null
663 mount -t minix /dev/ram4 /usr/local
664 fi
665 fi
666
667 if [ "$HOME" != "" ]
668 then
669 echo "Creating /home"
670 mkdir /home 2> /dev/null
671 if [ "$TMPFS" = "true" ]
672 then
673 mount -n -t tmpfs -o size=${HOMEP}000 /dev/null /home
674 else
675 mkfs.minix /dev/ram5 $HOMEP 2> /dev/null > /dev/null
676 mount -t minix /dev/ram5 /home
677 fi
678 fi
679
680 #
681 # Need to add a check for "physical" var
682 #
683
684 if [ "$VAR" != "" ]
685 then
686 echo "Creating /var"
687 mkdir /var 2> /dev/null
688 if [ "$TMPFS" = "true" ]
689 then
690 mount -n -t tmpfs -o size=${VAR}000 /dev/null /var
691 else
692 mkfs.minix /dev/ram5 $VAR 2> /dev/null > /dev/null
693 mount -t minix /dev/ram6 /var
694 fi
695 fi
696
697fi
698
699############################################################################
700#
701# handle /etc/tux/config/permfs
702#
703# mount "permanent filesystems" -- for now these should be umounted
704# manually to avoid corruption
705#
706# partition:mount point:filesystem:options
707#
708############################################################################
709
710
711
712
713if [ -f /etc/tux/config/permfs ]
714then
715 echo "Mounting permanent (non-ramdisk) filesystems based on /etc/tux/config/permfs"
716
717 for i in `/etc/tux/config/permfs`
718 do
719 DEV=`cat /etc/tux/config/permfs | cut -d":" -f1`
720 MOUNT=`cat /etc/tux/config/permfs | cut -d":" -f2`
721 FSTYPE=`cat /etc/tux/config/permfs | cut -d":" -f3`
722
723 if mount -t $FSTYPE $DEV $MOUNT
724 then
725 echo "-- $DEV ($FSTYPE) was mounted at $MOUNT"
726 else
727 echo "-- $DEV ($FSTYPE) failed to mount at $MOUNT!"
728 fi
729 done
730
731 echo "Remember, these must be manually umounted prior to reboot"
732fi
733
734echo "--------------------- FILESYSTEM CONFIGURATION ------------------------"
735df
736sleep 1
737echo "-----------------------------------------------------------------------"
738echo
739
740#################################################################
741#
742# Kludgy stuff to do after the filesystems have been created
743#
744################################################################
745
746echo "Creating misc links and directories..."
747
748mkdir -p /lib/modules/`uname -r`
749touch /lib/modules/`uname -r`/modules.dep
750mkdir /usr/lib/ 2> /dev/null
751ln -sf /lib/terminfo /usr/lib/terminfo
752mkdir /usr/home
753cd /var
754mkdir pkg log spool run 2> /dev/null
755cd log
756cp /dev/null mtp
757cd /
758echo
759
760if [ -f /etc/proc/fixedpkg -o "$UML" ]
761then
762 if [ -f /etc/proc/fixedpkg ]
763 then
764 part=`cat /etc/proc/fixedpkg 2> /dev/null`
765 echo "Trinux packages were found on $part"
766 PKGSRC=$part
767
768 cat /etc/tux/config/fstab | grep $part | cut -d: -f2 2> /dev/null
769
770 fstype=`cat /etc/tux/config/fstab | grep $part | cut -d: -f2 2> /dev/null`
771 fi
772
773 ##echo "[PKGSRC] = $PKGSRC"
774 ##echo "[fstype] = $fstype"
775
776 if [ "$fstype" ]
777 then
778 if mount -t $fstype /dev/${part} /mnt 2> /dev/null
779 then
780 mounted="true"
781 fi
782 fi
783
784
785
786 if [ "$UML" ]
787 then
788 echo -n "Attempting to mount UML host filesystem: "
789 if mount none /mnt -t hostfs -o $UMLROOT,ro
790 then
791 mounted="true"
792 echo "ok"
793 else
794 echo "failed"
795 fi
796 fi
797
798 echo "[mounted] = $mounted"
799
800 if [ "$mounted" ]
801 then
802 echo "Preparing to load base packages from $part"
803 if cd /mnt/trinux/bootpkg 2> /dev/null
804 then
805 for i in `ls *.tgz 2> /dev/null`
806 do
807 pkgadd $i
808 done
809 else
810 "No base packages found, hmmm..."
811 fi
812
813 echo "Preparing to load kernel packages from $part"
814 if cd /mnt/trinux/kpkg 2> /dev/null
815 then
816 if [ -f /etc/tux/conf/kpkglist ]
817 then
818 for i in `cat /etc/tux/conf/pkglist`
819 do
820 pkgadd $i
821 done
822 else
823 echo "No kpkglist found, loading everything"
824 for i in `ls *.tgz 2> /dev/null`
825 do
826 if grep $i /etc/proc/kpkg.installed > /dev/null
827 then
828 echo "$i is already installed."
829 else
830 pkgadd $i
831 fi
832 done
833
834 fi
835 else
836 echo "Kernel package directory not found on $part!"
837 fi
838
839 echo "Preparing to load packages from $part"
840
841 if cd /mnt/trinux/pkg 2> /dev/null
842 then
843 if [ -f /etc/tux/conf/pkglist ]
844 then
845 for i in `cat /etc/tux/conf/pkglist`
846 do
847 pkgadd $i
848 done
849
850 # NOTE: now the desired behavior is to put whatever
851 # you want to load into bootpkg
852 #
853 #else
854 # echo "No pkglist found, loading everything"
855 # for i in `ls *.tgz 2> /dev/null`
856 # do
857 # pkgadd $i
858 # done
859
860 fi
861 else
862 echo "Package directory not found on $part!"
863 fi
864
865 cd /
866 umount /mnt
867 else
868 echo -n "Failed to mount $part"
869 fi
870else
871 ### This should only go for a floppy
872 ### Load required packages from boot device
873 ### echo "For some reason we made it here"
874
875 sleep 1
876
877 if mount -t $BOOTFS $BOOT /boot 2> /dev/null
878 then
879 if [ "$PKGSRC" != "$CDEV" ]
880 then
881 if cd /boot/bootpkg
882 then
883 echo "Installing base packages from boot device"
884 for i in `ls`
885 do
886 pkgadd $i
887 done
888 echo
889 fi
890 fi
891 cd /
892 umount /boot
893 else
894 echo "Unable to mount $BOOT on $BOOTFS"
895 fi
896 cd /
897 umount /boot 2> /dev/null
898fi
899
900
901[ -x /etc/init.d/pcmcia ] && . /etc/init.d/pcmcia
902
903sleep 1
904
905
906
907
908############### Syslog Configuration ###################
909
910LOGHOST=`cat /etc/tux/options/loghost 2> /dev/null`
911if [ "$LOGHOST" ]
912then
913 if [ "$LOGHOST" = "prompt" ]
914 then
915 echo -n "Enter syslog server: "
916 read $LOGHOST
917 fi
918 $REMOTELOG="-R $LOGHOST"
919fi
920
921echo "Starting syslogd"
922[ -x /sbin/syslogd ] && syslogd $REMOTELOG
923
924#
925# At this point we have loaded all the packages if a CD-ROM
926# boot or package load from fixed partition
927# otherwise base packages have been loaded from the
928# floppy. We also have any saved config data. Now we attempt
929# to configure the network, then load packages from an HTTP/FTP server
930#
931
932chmod a+x /etc/tux/init/prenet 2> /dev/null
933if [ -x /etc/tux/init/prenet ]
934then
935 . /etc/tux/init/prenet
936fi
937
938
939##### Attempt to initialize networking #######################
940
941
942ifconfig lo 127.0.0.1 up
943
944
945
946# [ "$IPADDR" ] && echo "Network configured successfully"
947
948
949if [ -f /etc/tux/config/eth0 ]
950then
951 /sbin/net-start
952 IPADDR=`cat /etc/proc/ipaddr 2> /dev/null`
953else
954 echo 'No network configuration found. Type "net-config"'
955fi
956
957if [ -f /etc/tux/config/proxy ]
958then
959 SNARF_PROXY=`cat /etc/tux/config/proxy`
960 export SNARF_PROXY
961 echo "Found proxy: $SNARF_PROXY"
962 echo
963fi
964
965if [ "$PKGSRC" = "network" ]
966then
967
968 if [ "$IPADDR" != "" ]
969 then
970 echo "The network was succesfully configured"
971
972 [ -f /etc/tux/config/pkglist ] && PKGLIST=`cat /etc/tux/config/pkglist`
973
974 # attempt to connect to servers in /etc/tux/config/server
975
976 #snarf $server | grep tgz | cut -d">" -f3 | cut -d"<" -f1 > /tmp/packages
977
978 #echo "3" > /proc/sys/net/ipv4/tcp_syn_retries
979 #echo "3" > /proc/sys/net/ipv4/tcp_retries1
980 #echo "3" > /proc/sys/net/ipv4/tcp_retries2
981
982 if [ -f /etc/tux/config/server ]
983 then
984
985 for SERVER in `cat /etc/tux/config/server`
986 do
987 echo "Contacting $SERVER..."
988 if snarf $SERVER > /dev/null 2> /dev/null
989 then
990 getpkg all
991 # echo; echo "Retrieving base packages from $SERVER"
992 # for i in $PKGLIST
993 # do
994 # getpkg $i $SERVER
995 # done
996
997 if [ -f /etc/tux/config/kpkglist ]
998 then
999 KPKGLIST=`cat /etc/tux/config/kpkglist`
1000 echo "Retrieving Linux $KERNEL packages from $SERVER"
1001 for i in $KPKGLIST
1002 do
1003 getpkg $KERNEL/${i} $SERVER
1004 done
1005 fi
1006
1007 break
1008 fi
1009 done
1010 fi
1011 else
1012 PKGSRC="/dev/fd0"
1013 fi
1014fi
1015
1016if [ "$PKGSRC" = "/dev/fd0" ]
1017then
1018 echo -n "Do you have a package disk? "
1019 read response
1020
1021 until [ "$response" != "y" ]
1022 do
1023 if mount -t vfat -r /dev/fd0 /floppy 2> /dev/null
1024 then
1025 cd /floppy
1026
1027 if ls *.o > /dev/null 2> /dev/null
1028 then
1029 echo "Copying modules from package disk"
1030 cp *.o /lib/modules 2> /dev/null
1031 cp modules/*.o /lib/modules 2> /dev/null
1032 fi
1033
1034 for i in *.tgz
1035 do
1036 cd /floppy
1037 pkgadd $i
1038 done
1039 fi
1040
1041 cd /; umount /floppy
1042 echo -n "Do you have another floppy? "
1043 read response
1044 done
1045
1046
1047 #if ifconfig | grep eth0 /dev/null 2> /dev/null
1048 #then
1049 # echo "Network was sucessfully initialized"
1050 #else
1051 #net-start
1052 # fi
1053else
1054 if echo $PKGSRC | grep "/dev/[sh]d" > /dev/null
1055 then
1056 echo "Packages will be loaded from fixed disk: $PKGSRC"
1057 fi
1058fi
1059
1060
1061if [ -x /etc/tux/init/postnet ]
1062then
1063 chmod a+x /etc/tux/init/postnet 2> /dev/null
1064 . /etc/tux/init/postnet
1065fi
1066
1067# Install modules that end up in /lib/modules
1068# this will include any on the boot disk
1069#
1070# Consult /etc/tux/config/modules for any parameters
1071# (i.e. irq's io's for NIC modules
1072#
1073
1074# This should be moved to /etc/init.d/system
1075
1076echo "Enabling port scan (scanlogd)"
1077[ -x /sbin/scanlogd ] && scanlogd
1078
1079
1080### Fix the linker/library stuff
1081if [ -x /usr/sbin/ldconfig ]
1082then
1083 echo "Rebuilding ld.so.cache one last time"
1084 ldconfig -v 2> /dev/null > /dev/null
1085else
1086 echo "Unable to rebuild run-time link bindings"
1087fi
1088
1089
1090chmod a+x /etc/tux/init/prepkg 2> /dev/null
1091if [ -x /etc/tux/init/prepkg ]
1092then
1093 . /etc/tux/init/prepkg
1094fi
1095
1096[ -x /usr/bin/bash ] && ln -sf /usr/bin/bash /bin/sh
1097
1098
1099
1100## This needs to be fixed *bad*
1101
1102##/sbin/loadmodules # load any last minute kernel modules
1103
1104chmod a+x /etc/tux/init/last 2> /dev/null
1105if [ -x /etc/tux/init/last ]
1106then
1107 . /etc/tux/init/last
1108fi
1109
1110# Increasing syn_retries to something more reasonable
1111echo "7" > /proc/sys/net/ipv4/tcp_syn_retries
1112
1113######################################################################
1114# Set up swap space
1115######################################################################
1116
1117SWAPCONF=`cat /etc/tux/config/swap 2> /dev/null`
1118
1119if [ "$SWAPCONF" ]
1120then
1121 echo "Configuring swap space"
1122
1123 [ -x /sbin/mkswap ] || getpkg swaputil
1124
1125 SWAPFILE=`echo $SWAPCONF | cut -d: -f1`
1126 SWAPSIZE=`echo $SWAPCONF | cut -d: -f2`
1127
1128 [ "$SWAPSIZE" ] || SWAPSIZE=8192 # default to 8MB swap
1129
1130 if echo "$SWAPFILE" | grep "dev" > /dev/null
1131 then
1132 # user specified a partition
1133 echo "Attempting to use $SWAPFILE for swap partition"
1134 else
1135 echo "Using $SWAPFILE as your swap file"
1136 dd if=/dev/zero of=$SWAPFILE bs=512 count=$SWAPSIZE
1137 fi
1138
1139 mkswap $SWAPFILE
1140 swapon $SWAPFILE
1141 free
1142fi
1143
1144
1145####
1146
1147if [ -f /etc/tux/config/ipfwd ]
1148then
1149 echo "Enabling IP forwarding"
1150 echo "1" > /proc/sys/net/ipv4/ip_forward
1151fi
1152
1153if [ -f /etc/tux/config/noping ]
1154then
1155 echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all
1156fi
1157
1158
1159
1160#### This stuff should all get moved to the system direcotry ######
1161###
1162#### Notify any emails addr in /etc/tux/options/mailmon that you're up
1163
1164if [ -f /etc/tux/config/monitor/smtp ]
1165then
1166 for ADDR in `cat /etc/tux/config/emaildst`
1167 do
1168 echo | mail $ADDR UP
1169 done
1170fi
1171
1172if [ -f /etc/tux/config/monitor/http ]
1173then
1174 webmon
1175 # add to crontab
1176 echo '0,10,20,30,40,50 * * * * /usr/sbin/webmon' >> /etc/tux/config/crontab
1177fi
1178
1179if [ -f /etc/tux/config/monitor/cdp ]
1180then
1181 echo "Starting CDP (Cisco Discovery Protocol)"
1182 echo '* * * * * /usr/sbin/cdpdump' >> /etc/tux/config/crontab
1183fi
1184
1185
1186if [ -f /etc/tux/config/crontab ]
1187then
1188 if /usr/sbin/crond 2> /dev/null
1189 then
1190 echo "Starting crond"
1191 sort /etc/tux/config/crontab | uniq > /tmp/crontab 2> /dev/null
1192 cat /tmp/crontab > /etc/tux/config/crontab 2> /dev/null
1193 /usr/sbin/crontab /etc/tux/config/crontab 2> /dev/null
1194 crontab -l
1195 echo
1196 else
1197 echo "Unable to start crond"
1198 fi
1199else
1200 echo "No crontab config found, not starting"
1201fi
1202
1203### Erase /floppy/tux/options/console to disable console access
1204###
1205##if [ -f /etc/tux/options/console ]
1206##then
1207## [ -f /etc/tux/config/home ] && gethome
1208##else
1209## grep -v askfirst /etc/inittab > /etc/inittab.new
1210## rm /etc/inittab
1211## mv /etc/inittab.new /etc/inittab
1212##fi
1213
1214### Add a hack for dropbear with fixed partition
1215
1216
1217# check for custom /etc/inittab
1218
1219if [ -f /etc/tux/config/inittab ]
1220then
1221 echo "Found custom inittab"
1222 cp /etc/tux/config/inittab /etc/inittab
1223else
1224 echo "Using default inittab"
1225fi
1226
1227if [ -x /etc/init.d/dropbear ]
1228then
1229 killall dropbear >2
1230 echo "Restarting dropbear"
1231 /etc/init.d/dropbear
1232fi
1233
1234### This shouldn't be necessary, but just in case
1235
1236if [ -x /usr/local/sbin/sshd ]
1237then
1238 if ps | grep -v sshd > /dev/null
1239 then
1240 echo "SSH server failed to start, trying again"
1241 /etc/init.d/opensshd
1242 fi
1243fi
1244
1245cat /README | tr '\t' ' ' > /usr/doc/trinux
1246
1247#################################################################
1248
1249sleep 1
1250clear
1251echo -n "Welcome to Trinux: A Linux Security Toolkit"
1252if [ "$VERSION" ]
1253then
1254 echo -n " (version "
1255 echo -n $VERSION
1256 echo ")"
1257fi
1258echo
1259echo "Type 'man' for a list of help topics or 'man trinux' for docs."
1260echo "ALT-<Left/Right> allows you to view other virtual terminals. "
1261echo
diff --git a/urunlevel/my_linux/Trinux/loadmodules b/urunlevel/my_linux/Trinux/loadmodules
new file mode 100755
index 0000000..69c28ad
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/loadmodules
@@ -0,0 +1,30 @@
1#!/bin/sh
2
3ls /lib/modules/*.o > /tmp/modules.in 2> /dev/null
4ls /usr/local/lib/modules/*.o >> /tmp/modules.in 2> /dev/null
5
6sort /tmp/modules.in | uniq > /tmp/modules
7
8for module in `cat /tmp/modules`
9do
10 base=`basename $module`
11 naked=`basename $base .o`
12
13
14 #echo "base: $base"
15 #echo "naked: $naked"
16
17
18 if grep $naked /etc/tux/config/modules 2> /dev/null
19 then
20 param=`grep $naked /etc/tux/config/modules | cut -d' ' -f2- 2> /dev/null`
21 echo "Loading $module $param"
22 if insmod $module $param 2> /dev/null
23 then
24 echo $module >> /etc/proc/modules.in
25 else
26 echo $module >> /etc/proc/modules.out
27 fi
28 fi
29done
30
diff --git a/urunlevel/my_linux/Trinux/net-config b/urunlevel/my_linux/Trinux/net-config
new file mode 100755
index 0000000..2b85baa
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/net-config
@@ -0,0 +1,18 @@
1#!/bin/sh
2
3echo "By default Trinux configures eth0 via DHCP"
4found_faces=`dmesg | grep eth[0-9]: | cut -d: -f1`
5
6
7# Check for pcmcia
8if lsmod | grep pcmcia_core > /dev/null 2> /dev/null
9then
10 echo "PCMCIA modules running"
11 if ifconfig $face | grep UP > /dev/null 2> /dev/null
12 then
13 echo "PCMCIA interface already configured: exiting..."
14 exit
15 else
16 echo "PCMCIA interface was not configured: trying again"
17 fi
18fi
diff --git a/urunlevel/my_linux/Trinux/net-start b/urunlevel/my_linux/Trinux/net-start
new file mode 100755
index 0000000..a090d85
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/net-start
@@ -0,0 +1,141 @@
1#!/bin/sh
2# net-start
3#
4# can also be run via "start net" or "start network"
5#
6
7
8# find which dhcp client
9
10
11if [ -x /usr/sbin/dhcpcd ]
12then
13 DHCPCLIENT="/usr/sbin/dhcpcd"
14elif [ -x /sbin/udhcpc ]
15then
16 DHCPCLIENT="/sbin/udhcpc"
17else
18 echo "No DHCP client found!"
19fi
20
21/sbin/net-stop # bring down any interfaces and kill dhcp clients
22
23[ -d /etc/proc ] || mkdir /etc/proc
24
25probed=`dmesg | grep eth[0-9]: | cut -d: -f1`
26
27cd /etc/tux/config/
28found_faces=`ls eth*`
29
30echo "Found configs for: $found_faces"
31
32# first bring up interfaces
33
34for i in $found_faces
35do
36 echo -n "Configuring $i:"
37
38 if grep dhcp /etc/tux/config/$i > /dev/null 2> /dev/null
39 then
40 DHCP="true"
41 # things are really easy we just do dhcp
42 echo " using DHCP"
43 killall dhcpcd 2> /dev/null
44 sleep 1
45 if [ $DHCPCLIENT = "/usr/sbin/dhcpcd" ]
46 then
47 $DHCPCLIENT $i 2> /dev/null
48 else
49 $DHCPCLIENT -i $i 2> /dev/null
50 fi
51
52 else # static IP
53
54 if [ -f /etc/tux/config/$i ]
55 then
56 echo "settings found"
57 IP=`cut -d" " -f1 /etc/tux/config/$i`
58 MASK=`cut -d" " -f2 /etc/tux/config/$i`
59
60 if [ "$IP" ]
61 then
62 ifconfig $i $IP netmask $MASK up
63 fi
64
65 else
66 echo "no settings found, skipping..."
67 fi
68 fi
69
70
71 if [ "$i" = "eth0" ]
72 then
73 ifconfig $face | grep inet | cut -d":" -f2 | cut -d" " -f1 | grep -v 127.0.0.1 > /etc/proc/ipaddr
74 ln -sf /etc/proc/ipaddr /etc/proc/$i
75 nslookup `cat /etc/proc/ipaddr` | grep -v default | grep Name | cut -d":" -f2 | tr -d ' ' | tail -n 1 > /etc/proc/hostname
76 fi
77
78done
79
80if [ "$DHCP" ]
81then
82 echo "Skipping DNS and gateway config"
83else
84 echo -n "Adding default route: "
85
86 GW=`cat /etc/tux/config/gateway`
87
88 echo "$GW"
89 if [ "$GW" ]
90 then
91 route add default gw $GW
92 echo "done"
93 else
94 echo "failed"
95 fi
96
97 echo -n "Builing /etc/resolv.conf (DNS): "
98 # need to fix this for multiple DNS servers
99
100 DNS=`cat /etc/tux/config/dns 2>/dev/null`
101
102 if [ "$DNS" ]
103 then
104 echo "nameserver $DNS" > /etc/resolv.conf
105 else
106 echo "failed"
107 fi
108fi
109
110
111# update /etc/hosts and set HOSTNAME
112
113IPADDR=`cat /etc/proc/ipaddr`
114
115if [ -f /etc/tux/config/hostname ]
116then
117 HOSTNAME=`cat /etc/tux/config/hostname`
118else
119 HOSTNAME=`cat /etc/proc/hostname`
120 hlen=`length "$HOSTNAME"`
121
122 if [ "$hlen" -lt 1 ]
123 then
124 HOSTNAME='trinux'
125 fi
126fi
127
128echo "Setting hostname: $HOSTNAME"
129hostname $HOSTNAME
130
131echo "Building /etc/hosts"
132if [ -f /etc/tux/config/hosts ]
133then
134 cp /etc/tux/config/hosts /etc/hosts
135fi
136
137echo "127.0.0.1 localhost" >> /etc/hosts
138echo "$IPADDR $HOSTNAME" >> /etc/hosts
139
140sleep 3
141
diff --git a/urunlevel/my_linux/Trinux/net-stop b/urunlevel/my_linux/Trinux/net-stop
new file mode 100755
index 0000000..4b60457
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/net-stop
@@ -0,0 +1,11 @@
1#!/bin/sh
2
3killall udhcpcd 2> /dev/null
4killall dhcpcd 2> /dev/null
5killall pump 2> /dev/mull
6
7for i in `grep eth /proc/net/dev | cut -d: -f1`
8do
9 echo "Bringing down $i"
10 ifconfig $i down 2> /dev/null
11done
diff --git a/urunlevel/my_linux/Trinux/pkgadd b/urunlevel/my_linux/Trinux/pkgadd
new file mode 100755
index 0000000..f04834b
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/pkgadd
@@ -0,0 +1,62 @@
1#!/bin/sh
2#
3# pkgadd - adds trinux packages (c) 1999 OpenSEC under GPL
4#
5# Author: Matthew Franz <mfranz@cisco.com>
6#
7# $1 = name of package
8#
9##########################################################################
10
11if [ $# -ne 0 ]
12then
13 rm /*.tgz 2> /dev/null; rm /*.md5 2> /dev/null
14
15 # accepting package name with/without tarball extension
16
17 if echo $1 | grep -v tgz > /dev/null
18 then
19 FILE="$1.tgz"
20 else
21 FILE=$1
22 fi
23
24 PREFIX=`echo $FILE | cut -d"." -f1`
25
26 if [ -f $FILE ]
27 then
28 echo "Adding $FILE"
29 PF=`pwd`
30 #cp $FILE /; cd /
31 cd /
32 gunzip -c $PF/${FILE} | tar xf -
33
34 if [ -f /etc/init.d/${PREFIX} ]
35 then
36 chmod a+x /etc/init.d/${PREFIX} 2> /dev/null
37 echo; echo "Initializing package: $PREFIX"
38 /etc/init.d/${PREFIX} 2> /dev/null
39 elif [ -f /etc/init.m/${PREFIX} ]
40 then
41 chmod a+x /etc/init.m/${PREFIX} 2> /dev/null
42 echo; echo "Initializing module: $PREFIX"
43 /etc/init.m/${PREFIX} 2> /dev/null
44 fi
45
46# base=`echo $FILE | cut -d"." -f1`
47# tar xf $base.tar
48
49 #rm $FILE
50
51 [ -x /etc/pkg/$PREFIX ] && ./etc/pkg/$PREFIX
52 else
53 echo "$FILE not found"
54 fi
55
56else # no parameters !!
57 echo "Usage: "
58 echo ' pkgadd filename[.tgz] '
59 echo
60fi
61
62
diff --git a/urunlevel/my_linux/Trinux/pkglist b/urunlevel/my_linux/Trinux/pkglist
new file mode 100755
index 0000000..0fc82b0
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/pkglist
@@ -0,0 +1,12 @@
1#!/bin/sh
2
3if [ -f /etc/tux/config/server ]
4then
5 SERVER=`cat /etc/tux/config/server`
6else
7 SERVER="http://trinux.sf.net/pkg"
8fi
9
10snarf $SERVER - | cut -d'"' -f6 | grep "tgz" | sort | more
11
12
diff --git a/urunlevel/my_linux/Trinux/quit b/urunlevel/my_linux/Trinux/quit
new file mode 100755
index 0000000..555644b
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/quit
@@ -0,0 +1,10 @@
1#!/bin/sh
2
3echo "Preparing for reboot..."
4
5savehome
6savecfg
7sync
8sync
9sync
10reboot
diff --git a/urunlevel/my_linux/Trinux/rmpkg b/urunlevel/my_linux/Trinux/rmpkg
new file mode 100755
index 0000000..28e105a
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/rmpkg
@@ -0,0 +1,24 @@
1#!/bin/sh
2
3if [ ! "$1" ]
4then
5 echo "No package specified"; exit
6fi
7
8if [ -f /var/pkg/contents/$1 ]
9then
10
11 echo "Deleting $1:"
12
13 for i in `cat /var/pkg/contents/$1`
14 do
15 if echo $i | grep -v "\/$" 2> /dev/null
16 then
17 rm /${i} 2> /dev/null
18 fi
19 done
20
21 rm /var/pkg/contents/$1 2> /dev/null
22else
23 echo "/var/pkg/contents/$1 does not exist!"
24fi
diff --git a/urunlevel/my_linux/Trinux/save-config b/urunlevel/my_linux/Trinux/save-config
new file mode 100755
index 0000000..587728b
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/save-config
@@ -0,0 +1,38 @@
1#!/bin/sh
2
3echo
4echo "Trinux will save configuration information to the /tux directory"
5echo "on a DOS formatted floppy or to C:\trinux\tux\ if you booted "
6echo "from a fixed disk using loadlin"
7
8if [ -f /etc/proc/boot ]
9then
10 BOOT=`cat /etc/proc/boot`
11else
12 BOOT="/dev/fd0"
13fi
14
15echo
16echo "Boot device: $BOOT"
17
18if [ "$BOOT" = "/dev/fd0" ]
19then
20 echo -n "Please enter your boot/config floppy, then hit return: "
21 read blah
22else
23 PREFIX="/trinux"
24fi
25
26if mount -t vfat $BOOT /boot
27then
28 echo "Backing up old configuration"
29 cd /boot${PREFIX}
30 rm -r tux.bak 2> /dev/null
31 mv tux tux.bak
32 cp -a /etc/tux .
33
34 echo "Unmounting $BOOT"
35 cd /; umount /boot
36else
37 echo "Unable to mount boot device!"
38fi
diff --git a/urunlevel/my_linux/Trinux/savecfg b/urunlevel/my_linux/Trinux/savecfg
new file mode 100755
index 0000000..587728b
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/savecfg
@@ -0,0 +1,38 @@
1#!/bin/sh
2
3echo
4echo "Trinux will save configuration information to the /tux directory"
5echo "on a DOS formatted floppy or to C:\trinux\tux\ if you booted "
6echo "from a fixed disk using loadlin"
7
8if [ -f /etc/proc/boot ]
9then
10 BOOT=`cat /etc/proc/boot`
11else
12 BOOT="/dev/fd0"
13fi
14
15echo
16echo "Boot device: $BOOT"
17
18if [ "$BOOT" = "/dev/fd0" ]
19then
20 echo -n "Please enter your boot/config floppy, then hit return: "
21 read blah
22else
23 PREFIX="/trinux"
24fi
25
26if mount -t vfat $BOOT /boot
27then
28 echo "Backing up old configuration"
29 cd /boot${PREFIX}
30 rm -r tux.bak 2> /dev/null
31 mv tux tux.bak
32 cp -a /etc/tux .
33
34 echo "Unmounting $BOOT"
35 cd /; umount /boot
36else
37 echo "Unable to mount boot device!"
38fi
diff --git a/urunlevel/my_linux/Trinux/savehome b/urunlevel/my_linux/Trinux/savehome
new file mode 100755
index 0000000..837c639
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/savehome
@@ -0,0 +1,79 @@
1#!/bin/sh
2
3# savehome - saves home directory to
4
5if [ "$1" ]
6then
7 home=$1
8else
9 home="home"
10fi
11
12
13
14if [ -f /etc/tux/config/home ]
15then
16 PROTO=`cut -d':' -f1 /etc/tux/config/home`
17 HOST=`cut -d':' -f2 /etc/tux/config/home`
18 USER=`cut -d':' -f3 /etc/tux/config/home`
19else
20 echo -n "ftp or ssh: "
21 read PROTO
22 echo -n "Host: "
23 read HOST
24 echo -n "User: "
25 read USER
26 echo $PROTO:$HOST:$USER > /etc/tux/config/home
27fi
28
29[ -d /usr/local/tmp ] || mkdir -p /usr/local/tmp
30
31cd /
32tar cf - home | gzip -f > /usr/local/tmp/$home.tgz
33echo "Saving home directory to $USER@$HOST via $PROTO"
34
35cd /usr/local/tmp
36
37if [ "$PROTO" = "ssh" ]
38then
39 scp $home.tgz $USER@$HOST:~
40fi
41
42if [ "$PROTO" = "ftp" ]
43then
44 echo "Using FTP to transfor $home.tgz -- your passwords are sniffable"
45 if [ -x /usr/bin/curl ]
46 then
47 curl -u $USER -T $home.tgz ftp://$HOST
48
49 else
50 echo "Curl is not installed. You will have to login with your"
51 echo "username and upload $home.tgz manually"
52
53 ftp $HOST
54
55 fi
56fi
57
58if [ "$PROTO" = "fixed" ]
59then
60 if mount -t $PROTO $HOST /mnt
61 then
62 [ "$USER" ] && cd /mnt/$USER
63 cp /usr/local/tmp/$home.tgz .
64 cd /
65 umount /mnt
66 fi
67fi
68
69if [ "$PROTO" = "floppy" ]
70then
71 if mount -t vfat /dev/fd0 /mnt
72 then
73 cp /usr/local/tmp/$home.tgz /mnt
74 cd /
75 umount /mnt
76 else
77 echo "Unable to mount floppy"
78 fi
79fi
diff --git a/urunlevel/my_linux/Trinux/update b/urunlevel/my_linux/Trinux/update
new file mode 100755
index 0000000..ebeff6b
--- /dev/null
+++ b/urunlevel/my_linux/Trinux/update
@@ -0,0 +1,62 @@
1#!/bin/sh
2
3if [ ! "$*" ]
4then
5 echo
6 echo "Usage: "
7 echo " update [kernel|initrd|pkglist]"
8 exit
9fi
10
11
12if [ -f /etc/proc/boot ]
13then
14 BOOT=`cat /etc/proc/boot`
15else
16 BOOT="/dev/fd0"
17fi
18
19echo
20echo "Boot device: $BOOT"
21
22if [ "$BOOT" = "/dev/fd0" ]
23then
24 echo -n "Please enter your boot/config floppy, then hit return: "
25 read blah
26else
27 PREFIX="/trinux"
28fi
29
30if mount -t vfat $BOOT /boot
31then
32 if echo $* | grep "initrd"
33 then
34 INITRD=`cat /etc/tux/config/src/initrd`
35 if [ "$INITRD" ]
36 then
37 echo "Updating initrd from $INITRD"
38 cd /tmp
39 if snarf $INITRD
40 then
41 echo -n "Are you sure? "
42 read quest
43 if [ "$quest" != "n" ]
44 then
45 echo "Deleting existing initrd.gz"
46 cd /boot/$PREFIX
47 ls -al
48 rm initrd.gz
49 mv /tmp/initrd.gz .
50 fi
51 fi
52 else
53 echo "No initrd found"
54 fi
55 fi
56
57 sync
58 echo "Unmounting $BOOT"
59 cd /; umount /boot
60else
61 echo "Unable to mount boot device!"
62fi
diff --git a/urunlevel/my_linux/bootrc b/urunlevel/my_linux/bootrc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/urunlevel/my_linux/bootrc
diff --git a/urunlevel/my_linux/getpkg.c b/urunlevel/my_linux/getpkg.c
new file mode 100644
index 0000000..9127c45
--- /dev/null
+++ b/urunlevel/my_linux/getpkg.c
@@ -0,0 +1,240 @@
1/*
2 * Mini getpkg implementation for busybox.
3 *
4 * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <string.h>
24#include <errno.h>
25#include <unistd.h>
26#include <sys/utsname.h> /* for uname(2) */
27
28#include "busybox.h"
29#include "lib_init_d.h"
30#include "my_linux.h"
31
32
33#define GETPKG_OPT_ALL 1
34#define GETPKG_OPT_FILE 2
35#define GETPKG_OPT_KERNEL 4
36
37
38void init_package(char *temp)
39{
40 if (stat(temp, &path_stat) == 0)
41 {
42 doit(0, "chmod a+x %s 2> /dev/null", temp);
43 bb_printf("Initializing %s\n", temp);
44 doit(0, "%s 2> /dev/null", temp);
45 }
46}
47
48
49static char *DEFAULT_PACKAGES =
50"LIB\n"
51"system\n"
52"baselib\n"
53"term\n"
54"modutil\n"
55"swaputil\n"
56"bash2\n"
57"pthread\n"
58"mc\n"
59"ext2tools\n"
60"sysutil\n"
61"fileutil\n"
62"diskutil\n"
63"modutils\n"
64"portmap\n"
65"openssh\n"
66"links";
67
68static char *DEFAULT_SERVERS =
69"ftp://0.0.0.0/distros/Linux-on-net/Trinux/pkg/\n"
70"ftp://192.168.146.25/distros/Linux-on-net/Trinux/pkg/\n"
71"http://0.0.0.0/ftp/distros/Linux-on-net/Trinux/pkg/\n"
72"http://www.trinux.org/pkg/\n"
73"http://www.io.com/~mdfranz/trinux/pkg/";
74
75static char *DEFAULT_PATHS =
76"/trinux/pkg\n"
77"/trinux/bootpkg\n"
78"/trinux/kpkg\n"
79"/trinux\n"
80"/pkg";
81
82static llist_t *package_head = NULL; /* growable list of packages */
83static llist_t *source_head = NULL; /* growable list of sources */
84
85
86int get_package(int opt, char *source, char *package, const char *KERNEL)
87{
88 int result = 0;
89 int incomplete = 0;
90 char *PACKAGE = 0;
91 char *PRE = 0;
92 char *temp = "";
93
94 if (strcmp(&package[bb_strlen(package) - 4], ".tgz") != 0)
95 temp = ".tgz";
96
97 bb_xasprintf(&PACKAGE, "%s%s%s", KERNEL, package, temp);
98 bb_xasprintf(&PRE, "%s%s", KERNEL, package);
99
100 if (opt & GETPKG_OPT_FILE)
101 {
102 temp = concat_path_file(source, PACKAGE);
103 free(PACKAGE);
104 PACKAGE = temp;
105 bb_printf("Installing %s\n", PACKAGE);
106 }
107 else
108 {
109 char *URL;
110
111 temp = concat_path_file("/tmp", PACKAGE);
112 bb_xasprintf(&URL, "%s%s", source, PACKAGE);
113 free(PACKAGE);
114 PACKAGE = temp;
115
116//bb_printf("Retrieving %s\n", URL);
117 doit(0, "wget -O %s %s", PACKAGE, URL);
118 if (errno)
119 incomplete = 1;
120
121 free(URL);
122 }
123
124 temp = "";
125 if ((incomplete == 0) && (stat(PACKAGE, &path_stat) == 0))
126 {
127 bb_xasprintf(&temp, doit(0, "gunzip -c %s | tar xvf -", PACKAGE));
128 result = 1;
129 if (!(opt & GETPKG_OPT_FILE))
130 remove_file(PACKAGE, FILEUTILS_FORCE);
131 }
132 doit(0, "echo \"%s\" > /var/lib/my_linux/contents/%s", temp, PRE);
133
134 if (result)
135 {
136 free(temp);
137 bb_xasprintf(&temp, "/etc/init.d/%s", PRE);
138 init_package(temp);
139 temp[10] = 'm';
140 init_package(temp);
141 free(temp);
142 bb_xasprintf(&temp, "/etc/pkg/%s", PRE);
143 init_package(temp);
144 }
145
146 free(temp);
147 free(PACKAGE);
148 return result;
149}
150
151
152int getpkg_main(int argc, char **argv)
153{
154 int i;
155 unsigned long opt;
156 char *PACKAGE = 0;
157 char *KERNEL = "";
158 char *SRC = 0;
159 char *token;
160 char *strtok_temp;
161
162 opt = bb_getopt_ulflags(argc, argv, "afk");
163
164 if (argv[optind])
165 PACKAGE = argv[optind++];
166 if (argv[optind])
167 SRC = argv[optind++];
168 if (PACKAGE == 0)
169 opt |= GETPKG_OPT_ALL;
170 if (opt & GETPKG_OPT_KERNEL)
171 {
172 struct utsname name;
173
174 if (uname(&name) == -1)
175 bb_perror_msg_and_die("cannot get system information");
176 bb_xasprintf(&KERNEL, "%s/", name.release);
177 }
178
179 if (opt & GETPKG_OPT_ALL)
180 {
181 if (PACKAGE != 0)
182 {
183 SRC = PACKAGE;
184 PACKAGE = 0;
185 }
186 PACKAGE = quick_read("/var/lib/my_linux/config/pkglist");
187 if ((PACKAGE == 0) || (PACKAGE[0] == '\0'))
188 {
189 PACKAGE = (char *) xmalloc (sizeof (char) * bb_strlen(DEFAULT_PACKAGES) + 1);
190 strcpy(PACKAGE, DEFAULT_PACKAGES);
191 }
192 }
193
194 if (SRC == 0)
195 {
196 SRC = quick_read("/var/lib/my_linux/config/server");
197 if ((SRC == 0) || (SRC[0] == '\0'))
198 {
199 if (opt & GETPKG_OPT_FILE)
200 token = DEFAULT_PATHS;
201 else
202 token = DEFAULT_SERVERS;
203 SRC = (char *) xmalloc (sizeof (char) * bb_strlen(token) + 1);
204 strcpy(SRC, token);
205 }
206 }
207
208 token = strtok_r(PACKAGE, " \r\n", &strtok_temp);
209 for (i = 0; token != NULL; i++)
210 {
211 package_head = llist_add_to_end(package_head, token);
212 token = strtok_r(NULL, " \r\n", &strtok_temp);
213 }
214
215 token = strtok_r(SRC, " \r\n", &strtok_temp);
216 for (i = 0; token != NULL; i++)
217 {
218 source_head = llist_add_to_end(source_head, token);
219 token = strtok_r(NULL, " \r\n", &strtok_temp);
220 }
221
222
223 llist_t *package_current = package_head;
224 while (package_current)
225 {
226 int found = 0;
227 llist_t *source_current = source_head;
228
229 while (source_current)
230 {
231 if ((found = get_package(opt, source_current->data, package_current->data, KERNEL)))
232 break;
233 source_current = source_current->link;
234 }
235
236 package_current = package_current->link;
237 }
238
239 return EXIT_SUCCESS;
240}
diff --git a/urunlevel/my_linux/inittab b/urunlevel/my_linux/inittab
new file mode 100644
index 0000000..2f90616
--- /dev/null
+++ b/urunlevel/my_linux/inittab
@@ -0,0 +1,17 @@
1::sysinit:/sbin/rcS
2#tty1::respawn:/sbin/getty 38400 tty1
3#tty2::respawn:/sbin/getty 38400 tty2
4tty1::respawn:/sbin/getty -inl /usr/sbin/tw1 38400 tty1
5tty2::respawn:/sbin/getty -inl /usr/sbin/tw2 38400 tty2
6tty3::respawn:/sbin/getty -inl /usr/sbin/tw3 38400 tty3
7tty4::respawn:/sbin/getty -inl /usr/sbin/tw4 38400 tty4
8#tty5::respawn:/usr/X11R6/bin/X
9tty9::once:/sbin/rc
10tty10::respawn:/bin/tail -f /var/log/messages
11tty11::once:/bin/dmesg
12tty11::respawn:/sbin/klogd -n
13::ctrlaltdel:/sbin/reboot
14::shutdown:/sbin/rc 0
15::shutdown:/sbin/swapoff -a
16::shutdown:/bin/umount -a -r
17::restart:/sbin/init
diff --git a/urunlevel/my_linux/lib_init_d.h b/urunlevel/my_linux/lib_init_d.h
new file mode 100644
index 0000000..13253e9
--- /dev/null
+++ b/urunlevel/my_linux/lib_init_d.h
@@ -0,0 +1,183 @@
1/*
2 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 * 02111-1307 USA
18 *
19 */
20
21#ifndef _INIT_D_H
22#define _INIT_D_H
23
24
25/*
26 * init script defines
27 */
28
29#define INIT_D_COMMENT "\n#// "
30#define INIT_D_BEGIN "\n### BEGIN INIT INFO "
31#define INIT_D_PROV "\n# Provides: "
32#define INIT_D_RSTART "\n# Required-Start: "
33#define INIT_D_RSTOP "\n# Required-Stop: "
34#define INIT_D_SSTART "\n# Should-Start: "
35#define INIT_D_SSTOP "\n# Should-Stop: "
36#define INIT_D_DSTART "\n# Default-Start: "
37#define INIT_D_DSTOP "\n# Default-Stop: "
38#define INIT_D_SDESC "\n# Short-Description: "
39#define INIT_D_DESC "\n# Description: "
40#define INIT_D_CONT "\n#\t"
41#define INIT_D_CONT2 "\n# "
42#define INIT_D_END "\n### END INIT INFO\n"
43#define INIT_D_CUSTOM "\n# X-"
44
45
46/*
47 * init info
48 */
49
50typedef struct init_d_info_s {
51 char **provides;
52 char **reqstart;
53 char **reqstop;
54 char **shouldstart;
55 char **shouldstop;
56 int *defstart;
57 int *defstop;
58 char *shortdesc;
59 char *desc;
60 char *comment;
61 int sizes[11];
62 char *path;
63 llist_t *start;
64} init_d_info_t;
65
66
67/*
68 * init commands
69 */
70
71typedef struct init_d_handle_s {
72 int (*start)(struct init_d_handle_s *);
73 int (*stop)(struct init_d_handle_s *);
74 int (*restart)(struct init_d_handle_s *);
75 int (*try_restart)(struct init_d_handle_s *);
76 int (*reload)(struct init_d_handle_s *);
77 int (*force_reload)(struct init_d_handle_s *);
78 int (*status)(struct init_d_handle_s *, int);
79 int (*show_info)(struct init_d_handle_s *);
80 char *basename;
81 char *pathname;
82 char *args;
83 char *pidfile;
84 char *info;
85} init_d_handle_t;
86
87
88int do_init_from_main(int argc, char **argv, struct init_d_handle_s *init_d);
89int do_init(struct init_d_handle_s *init_d, const char *command);
90
91int default_start(struct init_d_handle_s *);
92int default_stop(struct init_d_handle_s *);
93int default_restart(struct init_d_handle_s *);
94int default_try_restart(struct init_d_handle_s *);
95int default_reload(struct init_d_handle_s *);
96int default_force_reload(struct init_d_handle_s *);
97int default_status(struct init_d_handle_s *, int);
98int default_show_info(struct init_d_handle_s *);
99
100int no_stop(struct init_d_handle_s *);
101int no_reload(struct init_d_handle_s *);
102int no_status(struct init_d_handle_s *, int);
103
104/*
105 * error codes
106 */
107
108#define INIT_D_OK 0
109#define INIT_D_ERROR_GENERIC 1
110#define INIT_D_ERROR_ARGS 2
111#define INIT_D_ERROR_NOT_IMPLEMENTED 3
112#define INIT_D_ERROR_SECURITY 4
113#define INIT_D_ERROR_NOT_INSTALLED 5
114#define INIT_D_ERROR_NOT_CONFIGURED 6
115#define INIT_D_ERROR_NOT_RUNNING 7
116
117
118/*
119 * status codes
120 */
121
122#define INIT_D_STATUS_OK 0
123#define INIT_D_STATUS_DEAD_PID 1
124#define INIT_D_STATUS_DEAD_LOCK 2
125#define INIT_D_STATUS_NOT_RUNNING 3
126#define INIT_D_STATUS_UNKNOWN 4
127
128
129/*
130 * /lib/lsb/init-functions
131 */
132int start_daemon(int force, int nice_level, char *pidfile, char *pathname, char *args);
133int killproc(char *pidfile, char *pathname, int my_signal);
134int checkpid(char *pid);
135int pidofproc(char *pidfile, char *pathname, char **pids);
136void log_success_msg(char *message);
137void log_failure_msg(char *message);
138void log_warning_msg(char *message);
139
140
141#define REDIR 1
142#define QUIET 2
143#define ERRONLY 4
144#define FORK 8
145#define NOFORK 16
146#define DAEMON 32
147
148extern struct stat path_stat;
149
150typedef struct nodes_s
151{
152 const char *name;
153 mode_t mode;
154 int major;
155 int minor;
156 int count;
157} nodes_t;
158
159
160char *argv_cat(int argc, char **argv);
161char *big_chomp(char *s);
162int checkpid(char *pid);
163char *doit(int mode, char *command, ...);
164
165#ifndef CONFIG_IFUPDOWN
166#define RUNLEVEL_LIST 1
167#endif
168#ifdef RUNLEVEL_LIST
169// From ifupdown, so it should probably be in libbb.
170llist_t *llist_add_to_end(llist_t *list_head, char *data);
171#else
172extern llist_t *llist_add_to_end(llist_t *list_head, char *data);
173#endif
174
175llist_t *llist_delete(llist_t **unsorted, llist_t *previous, llist_t *current);
176void make_disk(char *token, const nodes_t *nodes);
177void make_ram_disk(int size, int number, char *place, int TMPFS);
178void quick_mount(char *type, char *device, char *path, char *data, ...);
179char *quick_read(char *filename);
180void quick_write(const char *filename, const char *data, ...);
181
182
183#endif
diff --git a/urunlevel/my_linux/linuxrc.c b/urunlevel/my_linux/linuxrc.c
new file mode 100644
index 0000000..15fba1a
--- /dev/null
+++ b/urunlevel/my_linux/linuxrc.c
@@ -0,0 +1,829 @@
1/*
2 * Mini linuxrc implementation for busybox.
3 * An implementation of the linuxrc boot script.
4 *
5 * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 * 02111-1307 USA
21 *
22 */
23
24#include <dirent.h>
25#include <fcntl.h>
26#include <unistd.h>
27#include <errno.h>
28#include <signal.h>
29#include <string.h>
30#include <sys/poll.h>
31#include <sys/wait.h>
32#include <sys/utsname.h> /* for uname(2) */
33
34#include "busybox.h"
35#include "lib_init_d.h"
36#include "my_linux.h"
37
38
39const static char *directories[] =
40{
41 "boot",
42 "dev/pts",
43 "dev/input",
44 "lib",
45 "media/ROOT",
46 "media/cdrom",
47 "media/floppy",
48 "mnt",
49 "opt",
50 "proc",
51 "sbin",
52 "sys",
53 "udev",
54 "usr/bin",
55 "usr/etc/init.d",
56 "usr/lib",
57 "usr/sbin",
58 "var/cache",
59 "var/etc/network/if-down.d",
60 "var/etc/network/if-post-down.d",
61 "var/etc/network/if-pre-up.d",
62 "var/etc/network/if-up.d",
63 "var/etc/sysconfig",
64 "var/home/root",
65 "var/lib/misc",
66 "var/lib/network",
67 "var/lib/my_linux/init.m/done",
68 "var/lib/my_linux/pkg",
69 "var/lib/my_linux/config",
70 "var/lib/my_linux/contents",
71 "var/log",
72 "var/spool/cron/crontabs",
73 "var/temp",
74 "var/tmp",
75#ifdef CONFIG_FEATURE_FULL_LSB
76 "boot/grub",
77 "bin",
78 "dev/net",
79 "etc/X11",
80 "etc/cron.d",
81 "etc/cron.daily",
82 "etc/cron.fortnightly",
83 "etc/cron.hourly",
84 "etc/cron.monthly",
85 "etc/cron.weekly",
86 "etc/cups",
87 "etc/opt",
88 "etc/sgml",
89 "etc/udev",
90 "lib/lsb",
91 "lib/modules/2.6.9/kernel",
92 "opt/bin",
93 "opt/doc",
94 "opt/include",
95 "opt/info",
96 "opt/lib",
97 "opt/man",
98 "usr/X11R6",
99 "usr/X11R6/bin",
100 "usr/X11R6/include/X11",
101 "usr/X11R6/lib/X11",
102 "usr/X11R6/man/en/man8",
103 "usr/doc",
104 "usr/games",
105 "usr/i386-linux-uclibc/include",
106 "usr/i386-linux-uclibc/lib",
107 "usr/i386-linux-uclibc/games",
108 "usr/i386-linux-uclibc/lsb",
109 "usr/include/bsd",
110 "usr/local/bin",
111 "usr/local/games",
112 "usr/local/i386-linux-uclibc/include",
113 "usr/local/i386-linux-uclibc/lib",
114 "usr/local/include",
115 "usr/local/lib",
116 "usr/local/man/en/man8",
117 "usr/local/sbin",
118 "usr/local/share",
119 "usr/local/src",
120 "usr/share/dict",
121 "usr/share/doc",
122 "usr/share/games",
123 "usr/share/ghostscript",
124 "usr/share/groff",
125 "usr/share/info",
126 "usr/share/kbd",
127 "usr/share/locale",
128 "usr/share/man/en/man8",
129 "usr/share/misc/getopt",
130 "usr/share/nls",
131 "usr/share/perl",
132 "usr/share/sgml/docbook",
133 "usr/share/sgml/html/dtd",
134 "usr/share/sgml/tei",
135 "usr/share/terminfo",
136 "usr/share/texmf",
137 "usr/share/zoneinfo",
138 "usr/src/linux-2.6.9/include",
139 "usr/src/packages/BUILD",
140 "usr/src/packages/RPMS/athlon",
141 "usr/src/packages/RPMS/i386",
142 "usr/src/packages/RPMS/i486",
143 "usr/src/packages/RPMS/i586",
144 "usr/src/packages/RPMS/i686",
145 "usr/src/packages/RPMS/noarch",
146 "usr/src/packages/SOURCES",
147 "usr/src/packages/SPECS",
148 "usr/src/packages/SRPMS",
149 "var/account",
150 "var/backups",
151 "var/cache/fonts",
152 "var/cache/man/en/man8",
153 "var/cache/www",
154 "var/cron",
155 "var/games",
156 "var/lib/hwclock",
157 "var/lib/xdm",
158 "var/local",
159 "var/msgs",
160 "var/nis",
161 "var/opt",
162 "var/preserve",
163 "var/spool/lpd",
164 "var/spool/mail",
165 "var/spool/mqueue",
166 "var/spool/news",
167 "var/spool/rwho",
168 "var/spool/uucp",
169 "var/yp",
170#endif
171 NULL
172};
173
174
175const static nodes_t nodes[] =
176{
177 {"initctl", S_IFIFO, 0, 0, 0},
178 {"log", S_IFIFO, 0, 0, 0},
179 {"mem", S_IFCHR, 1, 1, 0},
180 {"kmem", S_IFCHR, 1, 2, 0},
181 {"port", S_IFCHR, 1, 4, 0},
182 {"zero", S_IFCHR, 1, 5, 0},
183 {"full", S_IFCHR, 1, 7, 0},
184 {"random", S_IFCHR, 1, 8, 0},
185 {"urandom", S_IFCHR, 1, 9, 0},
186 {"tty", S_IFCHR, 5, 0, 0},
187 {"psaux", S_IFCHR, 10, 1, 0},
188 {"hda", S_IFBLK, 3, 0, 0},
189 {"hdb", S_IFBLK, 3, 64, 0},
190 {"hdc", S_IFBLK, 22, 0, 0},
191 {"hdd", S_IFBLK, 22, 64, 0},
192 {"ram", S_IFBLK, 1, 0, 9},
193 {"fd", S_IFBLK, 2, 0, 1},
194 {"tty", S_IFCHR, 4, 0,12},
195 {"ttyS", S_IFCHR, 4, 64,47},
196 {"loop", S_IFBLK, 7, 0,63},
197 {"cloop", S_IFBLK, 240, 0, 7},
198 {"vcs", S_IFBLK, 7, 0, 9},
199 {"vcsa", S_IFBLK, 7, 0, 9},
200 {"input/keyboard", S_IFCHR, 10,150, 0},
201 {"input/js", S_IFCHR, 13, 0, 31},
202 {"input/mouse", S_IFCHR, 13, 32, 30},
203 {"input/mice", S_IFCHR, 13, 63, 0},
204 {"input/event", S_IFCHR, 13, 64, 63},
205#ifdef CONFIG_FEATURE_FULL_LSB
206 {"net/tun", S_IFCHR, 10,200, 0},
207 {"fb0", S_IFCHR, 29, 0, 0},
208 {"fb1", S_IFCHR, 29, 32, 0},
209 {"fb2", S_IFCHR, 29, 64, 0},
210 {"fb3", S_IFCHR, 29, 96, 0},
211#endif
212 {0, 0, 0, 0, 0}
213};
214
215
216const static char *files[][2] =
217{
218 {"/var/etc/crontab", ""},
219// {"/var/etc/fstab", "none\t/dev/shm\tshm\tdefaults\t0 0\n/\t/dev/ram0\tminix\tdefaults\t0 0\n"},
220 {"/var/etc/fstab", ""},
221 {"/var/etc/group", "root:x:0:\ndaemon:x:2:\nshadow:x:42:\nusers:x:100:\nnogroup:x:65534:\n"},
222 {"/var/etc/host.conf", "order hosts,bind\nmulti on\n"},
223 {"/var/etc/hosts", "127.0.0.1 localhost\n"},
224 {"/var/etc/inittab", "::sysinit:/sbin/rcS\ntty1::respawn:/bin/ash\ntty9::once:/sbin/rc 1\ntty11::once:/bin/dmesg\n::ctrlaltdel:/sbin/reboot\n::shutdown:/sbin/rc 0\n::shutdown:/sbin/swapoff -a\n::shutdown:/bin/umount -a -r\n::restart:/sbin/init\n"},
225 {"/var/etc/ld.so.conf", ""},
226 {"/var/etc/network/interfaces", "auto lo eth0\niface lo inet loopback\niface eth0 inet dhcp\n"},
227 {"/var/etc/passwd", "root::0:0:My Linux Root:/root:/bin/sh\nftp:x:40:2:ftp:/tmp:/bin/sh\nsshd:x:41:2:sshd:/tmp:/bin/sh\nnobody:x:65534:65534:nobody:/tmp:/bin/sh\n"},
228 {"/var/etc/resolv.conf", "search cluster.meeting.humbug.org.au\nnameserver 192.168.254.254\n"},
229 {"/var/etc/securetty", "tty1\n"},
230 {"/var/etc/shells", "/bin/ash\n/bin/hush\n/bin/lash\n/bin/msh\n/bin/sh\n"},
231#ifdef CONFIG_FEATURE_FULL_LSB
232 {"/boot/grub/device.map", "(hd0)\t/dev/hda\n(hd1)\t/dev/hdb\n(hd2)\t/dev/hdc\n(hd3)\t/dev/hdd\n(fd0)\t/dev/fd0\n"},
233#endif
234 {NULL, NULL}
235};
236
237
238const static char *scripts[][2] =
239{
240 {"/sbin/shownet", "#!/bin/sh\necho \"\"\nifconfig\nroute\nip addr list\nip link list\nip route list\necho \"\"\n"},
241 {"/var/etc/profile", "#!/bin/sh\nPATH=/usr/bin:/usr/sbin:/bin:/sbin\nexport PATH\n"},
242#ifdef CONFIG_FEATURE_FULL_LSB
243#endif
244 {NULL, NULL}
245};
246
247
248const static char *links[][2] =
249{
250 {"/proc/kcore", "/dev/core"},
251 {"/dev/ram1", "/dev/ram"},
252 {"/dev/vcs0", "/dev/vcs"},
253 {"/dev/vcsa0", "/dev/vcsa"},
254 {"/var/home", "/home"},
255 {"/home/root", "/root"},
256 {"/bin/busybox", "/sbin/init"},
257 {"/bin/busybox", "/sbin/local_fs"},
258 {"/bin/busybox", "/sbin/network"},
259 {"/var/temp", "/tmp"},
260 {"/sbin/local_fs", "/usr/etc/init.d/local_fs" },
261 {"/sbin/boot_named", "/usr/etc/init.d/boot_named"},
262 {"/sbin/network", "/usr/etc/init.d/network"},
263 {"/sbin/boot_portmap", "/usr/etc/init.d/boot_portmap"},
264 {"/sbin/remote_fs", "/usr/etc/init.d/remote_fs" },
265 {"/sbin/boot_syslog", "/usr/etc/init.d/boot_syslog"},
266 {"/sbin/boot_time", "/usr/etc/init.d/boot_time"},
267 {"/usr/sbin/install_initd", "/usr/lib/lsb/install_initd" },
268 {"/usr/sbin/remove_initd", "/usr/lib/lsb/remove_initd" },
269 {"/usr/etc/init.d", "/var/etc/init.d"},
270 {"/usr/etc/protocols", "/var/etc/protocols"},
271 {"/usr/etc/rpc", "/var/etc/rpc"},
272 {"/usr/etc/services", "/var/etc/services"},
273 {"/var/lib/my_linux", "/var/etc/tux"},
274 {"/.mc", "/var/home/root/.mc"},
275 {"/tmp", "/var/lock"},
276 {"/tmp", "/var/run"},
277#ifdef CONFIG_FEATURE_FULL_LSB
278#endif
279 {NULL, NULL}
280};
281
282
283const static char *modules[] =
284{
285// "af_packet",
286// Should try all NICS instead.
287// "mii",
288// "ne2k-pci",
289// "nfs",
290 NULL
291};
292
293
294llist_t *floppies_list = NULL;
295llist_t *cdroms_list = NULL;
296llist_t *hard_disks_list = NULL;
297static void find_all_drives(void)
298{
299 int count;
300 struct dirent **dir;
301
302 if ((floppies_list == NULL) && (cdroms_list == NULL) && (hard_disks_list == NULL))
303 {
304// This is hard coded for now.
305floppies_list = llist_add_to(floppies_list, "fd0");
306 if ((count = scandir("/proc/ide", &dir, 0, alphasort)))
307 {
308 int n;
309
310 for (n = 0; n < count; n++)
311 {
312 struct dirent *script = dir[n];
313 struct stat script_stat;
314 char *info_text = NULL;
315
316 bb_xasprintf(&info_text, "/proc/ide/%s", script->d_name);
317 if (stat(info_text, &script_stat) == 0)
318 {
319 if (strncmp(info_text, "/proc/ide/hd", 12) == 0)
320 {
321 char *text = NULL;
322 char *name = NULL;
323
324 bb_xasprintf(&text, "%s", doit(REDIR, "cat %s/media", info_text));
325 bb_xasprintf(&name, "%s", script->d_name);
326 if (strcmp(text, "disk") == 0)
327 {
328// Should add partitions instead.
329 hard_disks_list = llist_add_to(hard_disks_list, name);
330 }
331 else
332 cdroms_list = llist_add_to(cdroms_list, name);
333 }
334 free(info_text);
335 }
336 free(dir[n]);
337 }
338 free(dir);
339 }
340 }
341}
342
343
344static int is_boot_device(char *device, char *image, char **type);
345static int find_boot_device_in_list(llist_t *disks, char *image, char **device, char **type)
346{
347 int result = 0;
348 char *original = *device;
349 llist_t *current = disks;
350
351 while (current)
352 {
353 char *disc = current->data;
354
355bb_printf("Checking %s for %s\n", disc, image);
356 bb_xasprintf(device, "/dev/%s", disc);
357 if (is_boot_device(*device, image, type))
358 {
359 result = 1;
360 free(*device);
361 bb_xasprintf(device, "/dev/%s", disc);
362 *device = concat_path_file(*device, image);
363 break;
364 }
365 current = current->link;
366 free(*device);
367 *device = original;
368 }
369 return result;
370}
371
372
373static int is_boot_device(char *device, char *image, char **type)
374{
375 int result = 0;
376
377 if (*type == NULL)
378 {
379// Should try to detect it.
380*type = "auto";
381 }
382 quick_mount(*type, device, "/boot", "-o ro");
383 if (errno == 0)
384 {
385 char *dest = concat_path_file("/boot", image);
386
387 if (stat(dest, &path_stat) == 0)
388 {
389 if (stat("/boot/bootrc", &path_stat) == 0)
390 result = 1;
391 }
392 if (result == 0)
393 doit(QUIET, "umount /boot");
394 free(dest);
395 }
396
397 return result;
398}
399
400
401static void pivot_dir(char *place, const char *root)
402{
403 char *dest = concat_path_file(root, place);
404
405 remove_file(place, FILEUTILS_FORCE | FILEUTILS_RECUR);
406 symlink(dest, place);
407 free(dest);
408}
409
410
411static int rebuild_fs(char *root)
412{
413 int result = 0;
414 char *check = concat_path_file(root, "var/lib/distro");
415
416 if (stat(check, &path_stat) == 0)
417 {
418 free(check);
419 bb_printf("Rebuilding root fs from %s.\n", root);
420 check = concat_path_file(root, "bootrc");
421 copy_file(check, "/bootrc", FILEUTILS_FORCE | FILEUTILS_PRESERVE_STATUS);
422 free(check);
423 pivot_dir("/boot", root);
424 pivot_dir("/etc", root);
425 remove_file("/var/etc", FILEUTILS_FORCE | FILEUTILS_RECUR);
426 pivot_dir("/opt", root);
427 pivot_dir("/sbin", root);
428 pivot_dir("/usr", root);
429// Should pivot dev and var if root is writable.
430 check = concat_path_file(root, "dev");
431 copy_file(check, "/dev", FILEUTILS_FORCE | FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS);
432 free(check);
433 check = concat_path_file(root, "var");
434 copy_file(check, "/var", FILEUTILS_FORCE | FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS);
435// doit(QUIET, "ln -sf %s/lib/* /lib", root);
436 pivot_dir("/lib", root);
437 doit(0, "/sbin/ldconfig");
438 pivot_dir("/bin", root);
439 result = 1;
440 }
441
442 free(check);
443 return result;
444}
445
446
447void set_boot_env(char *token);
448void read_bootrc(void)
449{
450 if (stat("/bootrc", &path_stat) == 0)
451 {
452 char *line;
453 FILE *contents;
454
455 contents = fopen("/bootrc", "r");
456 if (contents != NULL)
457 {
458 char *buffer = (char *) xmalloc(sizeof (char) * 256);
459
460 bb_printf("Parsing configuration.\n");
461 do
462 {
463 line = fgets(buffer, 255, contents);
464 if (line != NULL)
465 set_boot_env(buffer);
466 } while (line != NULL);
467 }
468 }
469}
470
471
472void set_boot_env(char *token)
473{
474 int i;
475 char *eq = NULL;
476 char *ha = NULL;
477
478//bb_printf("$$ %s\n", token);
479 for(i = 0; token[i] != '\0'; i++)
480 {
481 switch (token[i])
482 {
483 case '=' : if (eq == NULL) eq = &token[i]; break;
484 case '#' : if (ha == NULL) ha = &token[i]; break;
485 }
486 }
487
488 if ((eq != token) && (ha != token))
489 {
490 char *name = (char *) xmalloc(sizeof (char) * (i + 5));
491
492 if (eq != NULL)
493 *eq = '\0';
494 if (ha != NULL)
495 *ha = '\0';
496 sprintf(name, "%s", token);
497 trim(name);
498 if (name[0] != '\0')
499 {
500 if (eq != NULL)
501 {
502 setenv(name, &eq[1], 1);
503//bb_printf(" SET %s=%s\n", name, &eq[1]);
504 }
505 else
506 {
507 setenv(name, "", 1);
508//bb_printf(" SET %s=\n", name);
509 }
510 }
511 free(name);
512 if (eq != NULL)
513 *eq = '=';
514 if (ha != NULL)
515 *ha = '#';
516 }
517}
518
519
520int linuxrc_main(int argc, char **argv)
521{
522 int i;
523 int root_write = 0;
524 long MEMORY = 0;
525 char *CMDLINE = 0;
526 char *BOOT = 0;
527 char *ROOT = 0;
528 char *ROOT_TYPE = "auto";
529 char *BOOTFS = 0;
530 char *ROOT_MOUNT = "/media/ROOT";
531// char *PKGSRC = "network";
532 int TMPFS = 0;
533 int USR = 0;
534 int VAR = 0;
535 char *NFSADDR = 0;
536 char temp[32];
537 char *token;
538 char *strtok_temp;
539 struct sysinfo info;
540 struct utsname name;
541
542 mkrootfs(directories, nodes, files, scripts, links);
543
544 for (i = 0; modules[i] != 0; i++)
545 {
546//bb_printf("\n\n modprobe %s\n\n\n", modules[i]);
547 doit(0, "modprobe %s", modules[i]);
548 }
549// quick_mount("usbfs", "usbfs", "/proc/bus/usb", "");
550
551
552 doit(0, "dmesg >/var/log/dmesg.txt");
553
554 sysinfo(&info);
555 /* Kernels prior to 2.4.x will return info.mem_unit==0, so cope... */
556 if (info.mem_unit==0) {
557 info.mem_unit=1;
558 }
559 if ( info.mem_unit == 1 ) {
560 info.mem_unit=1024;
561
562 /* TODO: Make all this stuff not overflow when mem >= 4 Gib */
563 info.totalram/=info.mem_unit;
564 } else {
565 info.mem_unit/=1024;
566 /* TODO: Make all this stuff not overflow when mem >= 4 Gib */
567 info.totalram*=info.mem_unit;
568 }
569 MEMORY = info.totalram;
570 USR = MEMORY / 2.5;
571 VAR = MEMORY / 16;
572
573 if (uname(&name) == -1)
574 bb_perror_msg_and_die("cannot get system information");
575 if (atof(name.release) > 2.4)
576 TMPFS = 1;
577
578 make_ram_disk(VAR, 2, "/var", TMPFS);
579
580 bb_xasprintf(&CMDLINE, "%s", doit(REDIR, "cat /proc/cmdline"));
581//bb_printf("%s\n", CMDLINE);
582 for (token = strtok_r(CMDLINE, " \t\n\r", &strtok_temp); token != NULL; token = strtok_r(NULL, " \t\n\r", &strtok_temp))
583 {
584 if (strcmp(token, "RW") == 0)
585 {
586 root_write = 1;
587 sprintf(temp, "ROOT_MODE=RW");
588 set_boot_env(temp);
589 }
590 else if (strcmp(token, "RO") == 0)
591 {
592 root_write = 0;
593 sprintf(temp, "ROOT_MODE=RO");
594 set_boot_env(temp);
595 }
596 }
597
598 BOOT = getenv("BOOT_IMAGE");
599 if (BOOT != NULL)
600 {
601#define CDROM 1
602#define FLOPPY 2
603#define HD 3
604#define NETWORK 4
605 int type = 0;
606 int disk = -1;
607 int part = -1;
608 char *image = BOOT;
609 char device[16];
610
611/*
612 * BOOT_IMAGE=(hd0,4)/boot/bzImage
613 * BOOT_IMAGE=(hd3)/boot/bzImage
614 * BOOT_IMAGE=(hdx,y)/boot/bzImage
615 * translate to /dev/hd(x+1)(y+1)
616 * BOOT_IMAGE=(cd)/boot/bzImage
617 * scan cd drives
618 * BOOT_IMAGE=/boot/bzImage
619 * try to avoid this, but scan all disks
620 * BOOT_IMAGE=bzImage
621 * probably syslinux, assume floppy boot (see next)
622 * BOOT_IMAGE=(fd0)/bzImage
623 * try to find bootrc on first floppy
624 * BOOT_IMAGE=(nd)/tftpboot/vmlinux
625 * try to tftp bootrc from network
626 */
627 if ((BOOT[0] == '(') && (BOOT[2] == 'd') ) /* This is a grub boot, based on my BOOT_IMAGE patch for grub1. */
628 {
629 while (image[0] != '\0')
630 {
631 if (image[0] == ')')
632 {
633 image++;
634 break;
635 }
636 image++;
637 }
638 switch (BOOT[1])
639 {
640 case 'c' : type = CDROM; break;
641 case 'f' : type = FLOPPY; break;
642 case 'h' : type = HD; break;
643 case 'n' : type = NETWORK; break;
644 }
645 if (BOOT[3] != ')')
646 {
647 disk = atoi(&BOOT[3]) + 1;
648 if (BOOT[4] == ',')
649 part = atoi(&BOOT[5]) + 1;
650 }
651 }
652
653 device[0] = '\0';
654 switch (type)
655 {
656 case FLOPPY :
657 sprintf(device, "/dev/fd%d", disk - 1);
658 break;
659
660 case HD :
661 sprintf(device, "/dev/hd%c%d", 'a' + disk, part);
662 break;
663
664 case NETWORK :
665 sprintf(device, "tftp:/");
666 break;
667 }
668
669 if (device[0] == '\0')
670 {
671 find_all_drives();
672 if (type == CDROM)
673 {
674 BOOTFS="iso9660";
675 bb_printf("Scanning all CD and DVD drives for %s.\n", image);
676 if (find_boot_device_in_list(cdroms_list, image, &BOOT, &BOOTFS) == 0)
677 BOOTFS=NULL;
678 }
679 else
680 {
681 BOOTFS="vfat";
682 bb_printf("Scanning all drives for %s.\n", image);
683 if (find_boot_device_in_list(floppies_list, image, &BOOT, &BOOTFS) == 0)
684 {
685 BOOTFS="iso9660";
686 if (find_boot_device_in_list(cdroms_list, image, &BOOT, &BOOTFS) == 0)
687 {
688 BOOTFS=NULL;
689 if (find_boot_device_in_list(hard_disks_list, image, &BOOT, &BOOTFS) == 0)
690 BOOTFS=NULL;
691 }
692 }
693 }
694 }
695 else
696 {
697 if (type == NETWORK)
698 {
699 bb_xasprintf(&BOOT, "%s%s", device, image);
700 BOOTFS="Network";
701 bb_printf("Kicking network into life.\n");
702 doit(0, "rc network start");
703 if (stat("/var/lib/network/tftpaddr", &path_stat) == 0)
704 {
705 bb_printf("\nDownloading configuration from network.\n");
706 doit(QUIET, "tftp -gr /tftpboot/bootrc -l /bootrc %s", quick_read("/var/lib/network/tftpaddr"));
707 }
708 else if (stat("/var/lib/network/nfsaddr", &path_stat) == 0)
709 {
710 bb_printf("\nDownloading configuration from network.\n");
711 doit(QUIET, "tftp -gr /tftpboot/bootrc -l /bootrc %s", quick_read("/var/lib/network/nfsaddr"));
712 }
713 }
714 else
715 {
716 bb_xasprintf(&BOOT, "%s%s", device, image);
717 if (is_boot_device(device, image, &BOOTFS))
718 BOOT=device;
719 }
720 }
721
722 if (BOOTFS == NULL)
723 BOOTFS = "Unknown";
724
725 if (stat("/boot/bootrc", &path_stat) == 0)
726 {
727 bb_printf("Copying configuration from boot filesystem.\n");
728 copy_file("/boot/bootrc", "/bootrc", FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS);
729 doit(QUIET, "umount /boot");
730 }
731 }
732 else
733 {
734 BOOT = "";
735 BOOTFS = "";
736 }
737
738 read_bootrc();
739
740 ROOT = getenv("ROOT");
741 if (ROOT == 0)
742 {
743 if (strncmp(BOOT, "/dev/", 5) == 0)
744 {
745 bb_xasprintf(&ROOT, "%s", BOOT);
746 for (i = 5; ROOT[i] != '\0'; i++)
747 {
748 if (ROOT[i] == '/')
749 {
750 ROOT[i] = '\0';
751 ROOT_TYPE = BOOTFS;
752 break;
753 }
754 }
755 }
756 }
757
758/*
759#VERSION=`cat /boot/version 2> /dev/null`
760#PS1="My Linux $VERSION> "
761*/
762
763 bb_printf("================================\n");
764 bb_printf("Kernel: %s %s\n", name.release, TMPFS ? "- tmpfs capable" : "");
765 bb_printf("RAM: %li MB %s\n", MEMORY / 1024, (MEMORY < (16 * 1024)) ? "< 16 MB, you may run into problems" : "" );
766 bb_printf("Boot: %s - %s\n", BOOT, BOOTFS);
767 bb_printf("Root: %s - %s\n", ROOT, root_write ? "read/write" : "read only");
768 bb_printf("================================\n");
769
770/*
771ROOT=/dev/hda6
772ROOT=nfs://REAL/MDS/TEST
773*/
774 if (ROOT == 0)
775 {
776 ;
777 }
778 else
779 {
780 if (strncmp(ROOT, "/dev/", 5) == 0)
781 {
782// PKGSRC=BOOT;
783// Should fsck this partition first.
784 bb_printf("Mounting %s \n on %s as type %s\n", ROOT, ROOT_MOUNT, ROOT_TYPE);
785 make_disk(&ROOT[5], nodes);
786 quick_mount(ROOT_TYPE, ROOT, ROOT_MOUNT, root_write ? "-o rw" : "-o ro");
787 }
788 else if (strncmp(ROOT, "nfs://", 5) == 0)
789 {
790 doit(0, "rc network start");
791 if (stat("/var/lib/network/ipaddr", &path_stat) == 0)
792 NFSADDR = quick_read("/var/lib/network/nfsaddr");
793 if ((NFSADDR != 0) && (NFSADDR[0] != '\0'))
794 {
795 char *NFSMOUNT = 0;
796
797 ROOT_TYPE = "nfs";
798 if (NFSMOUNT == 0)
799 bb_xasprintf(&NFSMOUNT, "%s:%s", NFSADDR, &ROOT[5]);
800 bb_printf("Mounting %s \n on %s as type %s\n", NFSMOUNT, ROOT_MOUNT, ROOT_TYPE);
801 quick_mount(ROOT_TYPE, NFSMOUNT, ROOT_MOUNT, root_write ? "-o nolock,rw" : "-o nolock,ro");
802
803 free(NFSMOUNT);
804 }
805 free(NFSADDR);
806 }
807 }
808
809if (root_write)
810 copy_file("/bin/busybox", "/media/ROOT/bin/busybox", FILEUTILS_FORCE | FILEUTILS_PRESERVE_STATUS);
811
812 if (!rebuild_fs(ROOT_MOUNT))
813 {
814// make_ram_disk(USR, 3, "/usr", TMPFS);
815// doit(0, "getpkg");
816 }
817 else
818 {
819 read_bootrc();
820 }
821
822 doit(0, "/sbin/ldconfig");
823
824 free(CMDLINE);
825
826 execl("/sbin/init", "/sbin/init");
827 return EXIT_FAILURE;
828}
829
diff --git a/urunlevel/my_linux/man.c b/urunlevel/my_linux/man.c
new file mode 100644
index 0000000..162cac8
--- /dev/null
+++ b/urunlevel/my_linux/man.c
@@ -0,0 +1,41 @@
1/*
2 * Mini man implementation for busybox.
3 *
4 * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27#include "my_linux.h"
28
29
30int man_main(int argc, char **argv)
31{
32 argv += optind;
33 if (!*argv)
34 {
35 bb_printf("\nThe following manual topics are available:\n");
36 doit(NOFORK, "ls -m /usr/doc");
37 }
38 else
39 doit(NOFORK, "less /usr/doc/%s", *argv);
40 return EXIT_SUCCESS;
41}
diff --git a/urunlevel/my_linux/mkrootfs.c b/urunlevel/my_linux/mkrootfs.c
new file mode 100644
index 0000000..9098be6
--- /dev/null
+++ b/urunlevel/my_linux/mkrootfs.c
@@ -0,0 +1,104 @@
1/*
2 * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 * 02111-1307 USA
18 *
19 */
20
21#include <dirent.h>
22#include <fcntl.h>
23#include <unistd.h>
24#include <errno.h>
25#include <signal.h>
26#include <string.h>
27#include <sys/poll.h>
28#include <sys/wait.h>
29#include <sys/utsname.h> /* for uname(2) */
30
31#include "busybox.h"
32#include "lib_init_d.h"
33
34
35void mkrootfs(const char *directories[], const nodes_t *nodes, const char *files[][2], const char *scripts[][2], const char *links[][2])
36{
37 int i;
38 char temp[64];
39
40 umask(022);
41 sprintf(temp, "/dev");
42 bb_make_directory(temp, -1l, FILEUTILS_RECUR);
43 mknod("/dev/console", S_IFCHR, makedev(4, 0));
44 chmod("/dev/console", S_IRUSR | S_IWUSR);
45 mknod("/dev/null", S_IFCHR, makedev(1, 3));
46 chmod("/dev/null", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
47 mknod("/dev/ptmx", S_IFCHR, makedev(5, 2));
48 chmod("/dev/ptmx", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
49 sprintf(temp, "/bin");
50 bb_make_directory(temp, -1l, FILEUTILS_RECUR);
51 symlink("/bin/busybox", "/bin/sh");
52
53 bb_printf("\n\nCreating directories, devices, files, and links.\n");
54 for (i = 0; directories[i] != 0; i++)
55 {
56 /* Can't use it directly, coz bb_make_directory segfaults. */
57 sprintf(temp, "/%s", directories[i]);
58 bb_make_directory(temp, -1l, FILEUTILS_RECUR);
59 }
60
61 symlink("/var/etc", "/etc");
62 symlink("/proc/mounts", "/var/etc/mtab");
63 quick_mount("proc", "proc", "/proc", "");
64 quick_mount("sysfs", "sysfs", "/sys", "");
65 for (i = 0; nodes[i].name != 0; i++)
66 {
67 if (nodes[i].count)
68 {
69 int j;
70 for (j = 0; j <= nodes[i].count; j++)
71 {
72 sprintf(temp, "/dev/%s%i", nodes[i].name, j);
73 mknod(temp, nodes[i].mode, makedev(nodes[i].major, nodes[i].minor + j));
74 }
75 }
76 else
77 {
78 sprintf(temp, "/dev/%s", nodes[i].name);
79 mknod(temp, nodes[i].mode, makedev(nodes[i].major, nodes[i].minor));
80 }
81 }
82
83 for (i = 0; files[i][0] != NULL; i++)
84 quick_write(files[i][0], files[i][1]);
85
86 for (i = 0; scripts[i][0] != NULL; i++)
87 {
88 quick_write(scripts[i][0], scripts[i][1]);
89 chmod(scripts[i][0], S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
90 }
91
92 for (i = 0; links[i][0] != NULL; i++)
93 symlink(links[i][0], links[i][1]);
94
95 quick_mount("devpts", "devpts", "/dev/pts", "");
96 doit(0, "busybox --install");
97
98 /* This must be last, as it currently defines a valid install. */
99 /* Can't use it directly, coz bb_make_directory segfaults. */
100 sprintf(temp, "/var/lib/distro");
101 bb_make_directory(temp, -1l, FILEUTILS_RECUR);
102
103 bb_printf("Created.\n");
104}
diff --git a/urunlevel/my_linux/my_linux.h b/urunlevel/my_linux/my_linux.h
new file mode 100644
index 0000000..7be8fe4
--- /dev/null
+++ b/urunlevel/my_linux/my_linux.h
@@ -0,0 +1,27 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307 USA
19 *
20 */
21
22#ifndef _MY_LINUX_H
23#define _MY_LINUX_H
24
25void mkrootfs(const char *directories[], const nodes_t *nodes, const char *files[][2], const char *scripts[][2], const char *links[][2]);
26
27#endif
diff --git a/urunlevel/my_linux/rcS b/urunlevel/my_linux/rcS
new file mode 100755
index 0000000..5d3785e
--- /dev/null
+++ b/urunlevel/my_linux/rcS
@@ -0,0 +1,2 @@
1#!/bin/sh
2/bin/busybox rcS
diff --git a/urunlevel/my_linux/rcS.c b/urunlevel/my_linux/rcS.c
new file mode 100644
index 0000000..6d1f64f
--- /dev/null
+++ b/urunlevel/my_linux/rcS.c
@@ -0,0 +1,47 @@
1/*
2 * Mini rcS implementation for busybox.
3 *
4 * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27#include "my_linux.h"
28
29
30int rcS_main(int argc, char **argv)
31{
32 doit(FORK | QUIET, "gpm -m /dev/input/mice -t exps2 -M -m /dev/ttyS0 -t ms");
33
34// doit(FORK | QUIET, "/usr/sbin/crond");
35// if (errno == 0)
36// {
37// bb_printf("Starting cron.\n");
38// doit(0, "sort /etc/crontab | uniq > /tmp/crontab 2> /dev/null");
39// copy_file("/tmp/crontab", "/etc/crontab", FILEUTILS_FORCE | FILEUTILS_PRESERVE_STATUS);
40// doit(0, "/usr/sbin/crontab /etc/crontab 2> /dev/null");
41// doit(0, "crontab -l");
42// }
43
44 bb_printf("\n\nALT-<Left/Right> allows you to view other virtual terminals.\n");
45
46 return EXIT_SUCCESS;
47}
diff --git a/urunlevel/my_linux/shownet b/urunlevel/my_linux/shownet
new file mode 100755
index 0000000..94f1172
--- /dev/null
+++ b/urunlevel/my_linux/shownet
@@ -0,0 +1,8 @@
1#!/bin/sh
2echo ""
3ifconfig
4route
5ip addr list
6ip link list
7ip route list
8echo ""
diff --git a/urunlevel/my_linux/vt_manager b/urunlevel/my_linux/vt_manager
new file mode 100755
index 0000000..978f2ec
--- /dev/null
+++ b/urunlevel/my_linux/vt_manager
@@ -0,0 +1,22 @@
1#!/bin/sh
2
3runlevel=`cat /etc/runlevel`
4
5if [ -f /var/lib/misc/runlevel ]
6then
7 runlevel=`/var/lib/misc/runlevel`
8fi
9
10if [ "$runlevel" = "3" ]
11then
12 /sbin/getty 38400 tty$1
13elif [ "$runlevel" = "4" ]
14then
15 sleep 1
16 /usr/bin/openvt $1 twdm --quiet --hw=tty@/dev/tty$1,stdout,TERM=linux
17 sleep 1d
18elif [ "$runlevel" = "5" ]
19then
20 /usr/bin/openvt $1 /usr/X11R6/bin/X
21 sleep 1d
22fi
diff --git a/urunlevel/networking/udhcp/dhcpc.h b/urunlevel/networking/udhcp/dhcpc.h
new file mode 100644
index 0000000..25252af
--- /dev/null
+++ b/urunlevel/networking/udhcp/dhcpc.h
@@ -0,0 +1,38 @@
1/* dhcpc.h */
2#ifndef _DHCPC_H
3#define _DHCPC_H
4
5//#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
6#define DEFAULT_SCRIPT "/sbin/udhcpc_script"
7
8/* allow libbb_udhcp.h to redefine DEFAULT_SCRIPT */
9#include "libbb_udhcp.h"
10
11#define INIT_SELECTING 0
12#define REQUESTING 1
13#define BOUND 2
14#define RENEWING 3
15#define REBINDING 4
16#define INIT_REBOOT 5
17#define RENEW_REQUESTED 6
18#define RELEASED 7
19
20
21struct client_config_t {
22 char foreground; /* Do not fork */
23 char quit_after_lease; /* Quit after obtaining lease */
24 char abort_if_no_lease; /* Abort if no lease */
25 char background_if_no_lease; /* Fork to background if no lease */
26 char *interface; /* The name of the interface to use */
27 char *pidfile; /* Optionally store the process ID */
28 char *script; /* User script to run at dhcp events */
29 uint8_t *clientid; /* Optional client id to use */
30 uint8_t *hostname; /* Optional hostname to use */
31 int ifindex; /* Index number of the interface to use */
32 uint8_t arp[6]; /* Our arp address */
33};
34
35extern struct client_config_t client_config;
36
37
38#endif
diff --git a/urunlevel/networking/udhcp/libbb_udhcp.h b/urunlevel/networking/udhcp/libbb_udhcp.h
new file mode 100644
index 0000000..3204be0
--- /dev/null
+++ b/urunlevel/networking/udhcp/libbb_udhcp.h
@@ -0,0 +1,55 @@
1/* libbb_udhcp.h - busybox compatability wrapper */
2
3/* bit of a hack, do this no matter what the order of the includes.
4 * (for busybox) */
5
6#ifdef CONFIG_INSTALL_NO_USR
7#undef DEFAULT_SCRIPT
8//#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
9#define DEFAULT_SCRIPT "/sbin/udhcpc_script"
10#endif
11
12#ifndef _LIBBB_UDHCP_H
13#define _LIBBB_UDHCP_H
14
15#ifdef IN_BUSYBOX
16#include "busybox.h"
17
18#ifdef CONFIG_FEATURE_UDHCP_SYSLOG
19#define UDHCP_SYSLOG
20#endif
21
22#ifdef CONFIG_FEATURE_UDHCP_DEBUG
23#define UDHCP_DEBUG
24#endif
25
26#define COMBINED_BINARY
27#include "version.h"
28
29#define xfopen bb_xfopen
30
31#else /* ! BB_VER */
32
33#include <stdlib.h>
34#include <stdio.h>
35#include <sys/sysinfo.h>
36
37#define TRUE 1
38#define FALSE 0
39
40#define xmalloc malloc
41#define xcalloc calloc
42
43static inline FILE *xfopen(const char *file, const char *mode)
44{
45 FILE *fp;
46 if (!(fp = fopen(file, mode))) {
47 perror("could not open input file");
48 exit(0);
49 }
50 return fp;
51}
52
53#endif /* BB_VER */
54
55#endif /* _LIBBB_UDHCP_H */
diff --git a/urunlevel/runlevel/Config.in b/urunlevel/runlevel/Config.in
new file mode 100644
index 0000000..36be84b
--- /dev/null
+++ b/urunlevel/runlevel/Config.in
@@ -0,0 +1,110 @@
1#
2# For a description of the syntax of this configuration file,
3# see scripts/kbuild/config-language.txt.
4#
5
6menu "Runlevel Utilities"
7
8config CONFIG_BOOT_NAMED
9 bool "boot_named"
10 default y
11 help
12 An implementation of LSB $named.
13
14config CONFIG_BOOT_PORTMAP
15 bool "boot_portmap"
16 default y
17 help
18 An implementation of LSB $.
19
20config CONFIG_BOOT_SYSLOG
21 bool "boot_syslog"
22 default y
23 help
24 An implementation of LSB $syslog.
25
26config CONFIG_BOOT_TIME
27 bool "boot_time"
28 default y
29 help
30 An implementation of LSB $time.
31
32config CONFIG_INSTALL_INITD
33 bool "install_initd"
34 default y
35 help
36 An implementation of install_initd.
37
38config CONFIG_KILLPROC
39 bool "killproc"
40 default y
41 help
42 An implementation of killproc.
43
44config CONFIG_LOCAL_FS
45 bool "local_fs"
46 default y
47 help
48 A $local_fs boot script.
49
50config CONFIG_LOG_FAILURE_MSG
51 bool "log_failure_msg"
52 default y
53 help
54 An implementation of log_failure_msg.
55
56config CONFIG_LOG_SUCCESS_MSG
57 bool "log_success_msg"
58 default y
59 help
60 An implementation of log_success_msg.
61
62config CONFIG_LOG_WARNING_MSG
63 bool "log_warning_msg"
64 default y
65 help
66 An implementation of log_warning_msg.
67
68config CONFIG_NETWORK
69 bool "network"
70 default y
71 help
72 A $network boot script.
73
74config CONFIG_PIDOFPROC
75 bool "pidofproc"
76 default y
77 help
78 An implementation of pidofproc.
79
80config CONFIG_RC
81 bool "rc"
82 default y
83 help
84 An implementation of rc.
85
86config CONFIG_REMOTE_FS
87 bool "remote_fs"
88 default y
89 help
90 A $remote_fs boot script.
91
92config CONFIG_REMOVE_INITD
93 bool "remove_initd"
94 default y
95 help
96 An implementation of remove_initd.
97
98config CONFIG_START_DAEMON
99 bool "start_daemon"
100 default y
101 help
102 An implementation of start_daemon.
103
104config CONFIG_UDHCPC_SCRIPT
105 bool "udhcpc_script"
106 default y
107 help
108 An implementation of udhcpc.script.
109
110endmenu
diff --git a/urunlevel/runlevel/Makefile b/urunlevel/runlevel/Makefile
new file mode 100644
index 0000000..e7e9466
--- /dev/null
+++ b/urunlevel/runlevel/Makefile
@@ -0,0 +1,32 @@
1# Makefile for busybox
2#
3# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18#
19
20top_srcdir=..
21top_builddir=..
22srcdir=$(top_srcdir)/runlevel
23RUNLEVEL_DIR:=./
24include $(top_builddir)/Rules.mak
25include $(top_builddir)/.config
26include $(srcdir)/Makefile.in
27all: $(libraries-y)
28-include $(top_builddir)/.depend
29
30clean:
31 rm -f *.o *.a $(AR_TARGET)
32
diff --git a/urunlevel/runlevel/Makefile.in b/urunlevel/runlevel/Makefile.in
new file mode 100644
index 0000000..787dd18
--- /dev/null
+++ b/urunlevel/runlevel/Makefile.in
@@ -0,0 +1,75 @@
1# Makefile for busybox
2#
3# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18#
19
20RUNLEVEL_AR:=runlevel.a
21ifndef $(RUNLEVEL_DIR)
22RUNLEVEL_DIR:=$(top_builddir)/runlevel/
23endif
24srcdir=$(top_srcdir)/runlevel
25
26RUNLEVEL-y:=
27RUNLEVEL-$(CONFIG_BOOT_NAMED) += boot_named.o
28RUNLEVEL-$(CONFIG_BOOT_PORTMAP) += boot_portmap.o
29RUNLEVEL-$(CONFIG_BOOT_SYSLOG) += boot_syslog.o
30RUNLEVEL-$(CONFIG_BOOT_TIME) += boot_time.o
31RUNLEVEL-$(CONFIG_INSTALL_INITD) += install_initd.o
32RUNLEVEL-$(CONFIG_KILLPROC) += killproc.o
33RUNLEVEL-$(CONFIG_LOCAL_FS) += local_fs.o
34RUNLEVEL-$(CONFIG_LOG_FAILURE_MSG) += log_failure_msg.o
35RUNLEVEL-$(CONFIG_LOG_SUCCESS_MSG) += log_success_msg.o
36RUNLEVEL-$(CONFIG_LOG_WARNING_MSG) += log_warning_msg.o
37RUNLEVEL-$(CONFIG_NETWORK) += network.o
38RUNLEVEL-$(CONFIG_PIDOFPROC) += pidofproc.o
39RUNLEVEL-$(CONFIG_RC) += rc.o
40RUNLEVEL-$(CONFIG_REMOTE_FS) += remote_fs.o
41RUNLEVEL-$(CONFIG_REMOVE_INITD) += remove_initd.o
42RUNLEVEL-$(CONFIG_START_DAEMON) += start_daemon.o
43RUNLEVEL-$(CONFIG_UDHCPC_SCRIPT) += udhcpc_script.o
44
45
46#ifeq ($(CONFIG_HALT), y)
47CONFIG_RUNLEVEL_SHARED=y
48#else
49#ifeq ($(CONFIG_INIT), y)
50#CONFIG_RUNLEVEL_SHARED=y
51#else
52#ifeq ($(CONFIG_POWEROFF), y)
53#CONFIG_RUNLEVEL_SHARED=y
54#else
55#ifeq ($(CONFIG_REBOOT), y)
56#CONFIG_RUNLEVEL_SHARED=y
57#else
58#CONFIG_RUNLEVEL_SHARED=n
59#endif
60#endif
61#endif
62#endif
63
64ifeq ($(CONFIG_RUNLEVEL_SHARED), y)
65RUNLEVEL-$(CONFIG_RUNLEVEL_SHARED) += lib_init_d.o
66endif
67
68libraries-y+=$(RUNLEVEL_DIR)$(RUNLEVEL_AR)
69
70$(RUNLEVEL_DIR)$(RUNLEVEL_AR): $(patsubst %,$(RUNLEVEL_DIR)%, $(RUNLEVEL-y))
71 $(AR) -ro $@ $(patsubst %,$(RUNLEVEL_DIR)%, $(RUNLEVEL-y))
72
73$(RUNLEVEL_DIR)%.o: $(srcdir)/%.c
74 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
75
diff --git a/urunlevel/runlevel/README b/urunlevel/runlevel/README
new file mode 100644
index 0000000..7c3e2ce
--- /dev/null
+++ b/urunlevel/runlevel/README
@@ -0,0 +1,3 @@
1Busybox does not include named and portmap applets, so boot_named.c and
2boot_portmap.c should be considered as examples. Skeleton is also an example.
3
diff --git a/urunlevel/runlevel/TODO b/urunlevel/runlevel/TODO
new file mode 100644
index 0000000..d522d93
--- /dev/null
+++ b/urunlevel/runlevel/TODO
@@ -0,0 +1,55 @@
1+ LSB niceness
2* LSB compliance
3! fix bug
4$ store config info in -
5 kernel command line
6 boot://bootrc
7 /etc/sysconfig/* syslog network/config network/routes
8
9 if (stat("/var/lib/my_linux/config/ipfwd", &path_stat) == 0)
10 if (stat("/var/lib/my_linux/config/noping", &path_stat) == 0)
11 /var/lib/my_linux/config/hostname - hostname
12 /var/lib/my_linux/config/loghost - syslogd remote host
13
14
15 review init.d script dependencies
16 local_fs -
17 time ? network?
18 syslog ? (local_fs? or network) and time
19 network - syslog
20 remote_fs - network
21 portmap - network
22 named - network and syslog
23
24$ write a proper network & friends
25 add fsck support to local_fs and linuxrc
26 local_fs should only umount things it mounted
27! try to detect ext3 before mount whinges
28! redirect console to some other VT
29
30* do something with info->shouldstart's in rc
31+ rc foo start - start dependencies of foo first
32+ rc foo stop - stop things dependent on foo first
33* add a database of runlevels per script
34* add database editing and reporting commands to rc
35
36* finish install_initd & remove_initd
37$ finish boot_syslog
38$ finish boot_time
39! double check status functions
40
41+ write init_d_from_script
42+ rewrite skeleton to use initd_from_script
43
44! pidofproc needs to check the name of the proc as well as the pid in /proc/$pid
45 remove start_daemon's reliance on start-stop-daemon
46! remove need for sleep(1) in start_daemon
47! fix forking, daemon begat's daemon, and daemonic hell breaks loose.
48 My doit() is probably to blame.
49
50 on boot - hard link /linuxrc to /bin/busybox
51 turn makefs into a full blown applet
52 CONFIG_FEATURE_FULL_LSB
53 permissions for files
54 move cron out of rcS
55
diff --git a/urunlevel/runlevel/boot_named.c b/urunlevel/runlevel/boot_named.c
new file mode 100644
index 0000000..fba83c7
--- /dev/null
+++ b/urunlevel/runlevel/boot_named.c
@@ -0,0 +1,57 @@
1/*
2 * Mini named boot implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27
28
29static init_d_handle_t my_commands =
30{
31 NULL,
32 NULL,
33 NULL,
34 NULL,
35 &sighup_reload,
36 NULL,
37 NULL,
38 NULL,
39 "boot_named",
40 "named",
41 NULL,
42 NULL,
43 INIT_D_BEGIN \
44 INIT_D_PROV "$named" \
45 INIT_D_RSTART "$network $syslog" \
46 INIT_D_DSTART "3 4 5" \
47 INIT_D_DSTOP "0 1 2 6" \
48 INIT_D_SDESC "Hostname resolution service." \
49 INIT_D_DESC "Hostname resolution service." \
50 INIT_D_END
51};
52
53
54int boot_named_main(int argc, char **argv)
55{
56 return do_init_from_main(argc, argv, &my_commands);
57}
diff --git a/urunlevel/runlevel/boot_portmap.c b/urunlevel/runlevel/boot_portmap.c
new file mode 100644
index 0000000..d354b3b
--- /dev/null
+++ b/urunlevel/runlevel/boot_portmap.c
@@ -0,0 +1,78 @@
1/*
2 * Mini portmap boot implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27
28static int restart(struct init_d_handle_s *init_d, int just_checking);
29
30
31static init_d_handle_t my_commands =
32{
33 NULL,
34 NULL,
35 &restart,
36 NULL,
37 NULL,
38 NULL,
39 NULL,
40 NULL,
41 "boot_portmap",
42 "/sbin/portmap",
43 NULL,
44 NULL,
45 INIT_D_BEGIN \
46 INIT_D_PROV "$portmap" \
47 INIT_D_RSTART "$network" \
48 INIT_D_DSTART "3 4 5" \
49 INIT_D_DSTOP "0 1 2 6" \
50 INIT_D_SDESC "RPC port mapper." \
51 INIT_D_DESC "The RPC port mapper provides SunPRC/ONCRPC portmapping" \
52 INIT_D_CONT "services." \
53 INIT_D_END
54};
55
56
57int boot_portmap_main(int argc, char **argv)
58{
59 return do_init_from_main(argc, argv, &my_commands);
60}
61
62
63static const char *state = "/var/run/portmap.state";
64static int restart(struct init_d_handle_s *init_d, int just_checking)
65{
66 int status = (init_d->status)(init_d, 0);
67
68 if (status == INIT_D_STATUS_OK)
69 {
70 doit(0, "pmap_dump > %s", state);
71 status = default_restart(init_d, 0);
72 doit(0, "pmap_set < %s", state);
73 remove_file(state, FILEUTILS_FORCE);
74 }
75 else
76 status = default_restart(init_d, 0);
77 return status;
78}
diff --git a/urunlevel/runlevel/boot_syslog.c b/urunlevel/runlevel/boot_syslog.c
new file mode 100644
index 0000000..dc7548a
--- /dev/null
+++ b/urunlevel/runlevel/boot_syslog.c
@@ -0,0 +1,79 @@
1/*
2 * Mini syslog boot implementation for busybox.
3 *
4 * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27
28
29static int start(struct init_d_handle_s *, int);
30
31
32static init_d_handle_t my_commands =
33{
34 &start,
35 NULL,
36 NULL,
37 NULL,
38 &no_reload,
39 NULL,
40 NULL,
41 NULL,
42 "boot_syslogd",
43 "/sbin/syslogd",
44 "-n",
45 NULL,
46 INIT_D_BEGIN \
47 INIT_D_PROV "$syslog" \
48 INIT_D_RSTART "$local_fs $time" \
49 INIT_D_SSTART "$network" \
50 INIT_D_DSTART "1 2 3 4 5" \
51 INIT_D_DSTOP "0 6" \
52 INIT_D_SDESC "System logger." \
53 INIT_D_DESC "System logger." \
54 INIT_D_END
55};
56
57
58int boot_syslog_main(int argc, char **argv)
59{
60 return do_init_from_main(argc, argv, &my_commands);
61}
62
63
64static int start(struct init_d_handle_s *init_d, int just_checking)
65{
66/*
67#LOGHOST=`cat /var/lib/my_linux/config/loghost 2> /dev/null`
68#if [ "$LOGHOST" ]
69#then
70# if [ "$LOGHOST" = "prompt" ]
71# then
72# echo -n "Enter syslog server: "
73# read $LOGHOST
74# fi
75# $REMOTELOG = "-R $LOGHOST"
76#fi
77*/
78 return default_start(init_d, 0);
79}
diff --git a/urunlevel/runlevel/boot_time.c b/urunlevel/runlevel/boot_time.c
new file mode 100644
index 0000000..aa1fde7
--- /dev/null
+++ b/urunlevel/runlevel/boot_time.c
@@ -0,0 +1,88 @@
1/*
2 * Mini time boot implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27
28
29static int start(struct init_d_handle_s *, int);
30static int status(struct init_d_handle_s *, int);
31static int stop(struct init_d_handle_s *, int);
32
33
34static init_d_handle_t my_commands =
35{
36 &start,
37 &stop,
38 NULL,
39 NULL,
40 &no_reload,
41 NULL,
42 &status,
43 NULL,
44 "boot_time",
45 NULL,
46 NULL,
47 NULL,
48 INIT_D_BEGIN \
49 INIT_D_PROV "$time" \
50 INIT_D_DSTART "1 2 3 4 5" \
51 INIT_D_DSTOP "0 6" \
52 INIT_D_SDESC "Set the system time." \
53 INIT_D_DESC "Set the system time, maybe from the hardware clock," \
54 INIT_D_CONT "maybe from the network via NTP or DATE." \
55 INIT_D_END
56};
57// INIT_D_SSTART "$network" \
58
59
60int boot_time_main(int argc, char **argv)
61{
62 return do_init_from_main(argc, argv, &my_commands);
63}
64
65
66static int start(struct init_d_handle_s *init_d, int just_checking)
67{
68// Should check if we need to NTP or whatever
69// Should check for -l/-u
70 doit(0, "/sbin/hwclock -su");
71// Should check errno and convert into INIT_D_ERROR_?
72 return INIT_D_OK;
73}
74
75
76static int status(struct init_d_handle_s *init_d, int quiet)
77{
78 return print_status(init_d, quiet, INIT_D_STATUS_OK);
79}
80
81
82static int stop(struct init_d_handle_s *init_d, int just_checking)
83{
84// Should check for -l/-u
85 doit(0, "/sbin/hwclock -wu");
86// Should check errno and convert into INIT_D_ERROR_?
87 return INIT_D_OK;
88}
diff --git a/urunlevel/runlevel/default.script b/urunlevel/runlevel/default.script
new file mode 100755
index 0000000..9b11c8a
--- /dev/null
+++ b/urunlevel/runlevel/default.script
@@ -0,0 +1,2 @@
1#!/bin/bash
2/bin/busybox udhcpc_script \ No newline at end of file
diff --git a/urunlevel/runlevel/init-functions b/urunlevel/runlevel/init-functions
new file mode 100644
index 0000000..8b2200c
--- /dev/null
+++ b/urunlevel/runlevel/init-functions
@@ -0,0 +1,30 @@
1function start_daemon ()
2{
3 /bin/busybox start_daemon ${1+"$@"}
4}
5
6function killproc ()
7{
8 /bin/busybox killproc ${1+"$@"}
9}
10
11function pidofproc ()
12{
13 /bin/busybox pidofproc ${1+"$@"}
14}
15
16function log_success_msg ()
17{
18 /bin/busybox log_success_msg ${1+"$@"}
19}
20
21function log_failure_msg ()
22{
23 /bin/busybox log_failure_msg ${1+"$@"}
24}
25
26function log_warning_msg ()
27{
28 /bin/busybox log_warning_msg ${1+"$@"}
29}
30
diff --git a/urunlevel/runlevel/inittab b/urunlevel/runlevel/inittab
new file mode 100644
index 0000000..f1e6c11
--- /dev/null
+++ b/urunlevel/runlevel/inittab
@@ -0,0 +1,12 @@
1::sysinit:/sbin/rcS
2tty1::respawn:/sbin/getty 38400 tty1
3tty2::respawn:/sbin/getty 38400 tty2
4tty9::once:/sbin/rc
5tty10::respawn:/bin/tail -f /var/log/messages
6tty11::once:/bin/dmesg
7tty11::respawn:/sbin/klogd -n
8::ctrlaltdel:/sbin/reboot
9::shutdown:/sbin/rc 0
10::shutdown:/sbin/swapoff -a
11::shutdown:/bin/umount -a -r
12::restart:/sbin/init
diff --git a/urunlevel/runlevel/install_initd.c b/urunlevel/runlevel/install_initd.c
new file mode 100644
index 0000000..4b9ab88
--- /dev/null
+++ b/urunlevel/runlevel/install_initd.c
@@ -0,0 +1,48 @@
1/*
2 * Mini install_initd implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27
28
29int install_initd_main(int argc, char **argv)
30{
31 llist_t *sorted = NULL;
32 llist_t *unsorted = get_scripts();
33// char *info_text = NULL;
34// char *pathname = NULL;
35// init_d_info_t *info = NULL;
36
37// bb_xasprintf(&pathname, "/etc/init.d/%s", script->d_name);
38// info_text = get_init_info(pathname);
39// info = parse_init_info(info_text, script->d_name);
40// if (info)
41// result = llist_add_to(result, (char *) info);
42
43 sorted = sort_scripts(unsorted);
44// Should return 1 if this script is in unsorted.
45
46// free(info_text);
47 return EXIT_SUCCESS;
48}
diff --git a/urunlevel/runlevel/killproc.c b/urunlevel/runlevel/killproc.c
new file mode 100644
index 0000000..fd91c10
--- /dev/null
+++ b/urunlevel/runlevel/killproc.c
@@ -0,0 +1,162 @@
1/*
2 * Mini killproc implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <ctype.h>
24#include <signal.h>
25#include <string.h>
26#include <unistd.h>
27
28#include "busybox.h"
29#include "lib_init_d.h"
30
31
32int killproc(char *pidfile, char *pathname, int my_signal)
33{
34 char *pids = NULL;
35 int status = pidofproc(pidfile, pathname, &pids);
36
37 if (status == INIT_D_STATUS_OK)
38 {
39 int i;
40 char *pid;
41 char *strtok_temp;
42
43 pid = strtok_r(pids, " ", &strtok_temp);
44 for (i = 0; pid != NULL; i++)
45 {
46 int pid_num;
47
48 if (!isdigit(*pid))
49 bb_error_msg( "Bad PID '%s'", pid);
50 pid_num = strtol(pid, NULL, 0);
51 if (my_signal != 0)
52 {
53 if (kill(pid_num, my_signal) != 0)
54 bb_perror_msg( "Could not kill pid '%d'", pid_num);
55 }
56 else
57 {
58 if (kill(pid_num, SIGTERM) != 0)
59 bb_perror_msg( "Could not kill pid '%d'", pid_num);
60 sleep(1);
61 status = pidofproc(pidfile, pathname, &pids);
62 if (status == INIT_D_STATUS_OK)
63 {
64 sleep(5);
65 status = pidofproc(pidfile, pathname, &pids);
66 if (status == INIT_D_STATUS_OK)
67 {
68 if (kill(pid_num, SIGKILL) != 0)
69 bb_perror_msg( "Could not kill pid '%d'", pid_num);
70 }
71 }
72 }
73
74 pid = strtok_r(NULL, " ", &strtok_temp);
75 }
76
77 status = pidofproc(pidfile, pathname, &pids);
78 if (status == INIT_D_STATUS_DEAD_PID)
79 {
80 if (pidfile != NULL)
81 remove_file(pidfile, FILEUTILS_FORCE);
82 status = INIT_D_STATUS_NOT_RUNNING;
83 }
84 if ((my_signal == 0) && (status == INIT_D_STATUS_NOT_RUNNING))
85 status = INIT_D_STATUS_OK;
86 }
87
88 return status;
89}
90
91
92/*
93killproc [-p pidfile] pathname [signal]
94 This stops the specified program. The program is
95 found using the algorithm given above. If a
96 signal is specified, using the
97 -signal_name or -signal_number syntaxes
98 as specified by the kill command,
99 the program is sent that signal.
100 Otherwise, a SIGTERM followed by a SIGKILL
101 after some number of seconds shall be sent.
102 If a program has been terminated, the pidfile should be removed if the
103 terminated process has not already done so.
104 Compliant applications may use the basename instead of the
105 pathname.
106
107 killproc should return the LSB defined exit status codes. If called
108 without a signal, it shall return 0 if the program has been stopped or
109 is not running and not 0 otherwise. If a signal is given, it shall return 0
110 only if the program is running.
111*/
112
113
114int killproc_main(int argc, char **argv)
115{
116 int i;
117 int my_signal = 0;
118 char *pidfile = NULL;
119 char *pathname = NULL;
120 char *signame = NULL;
121
122 for (i = 1; i < argc; i++)
123 {
124 char *p = argv[i];
125
126 if (*p == '-')
127 {
128 p++;
129 if (*p == 'p')
130 {
131 if ((i + 1) < argc)
132 pidfile = argv[++i];
133 else
134 bb_show_usage();
135 }
136 else
137 signame = &argv[i][1];
138 }
139 else if (pathname == NULL)
140 pathname = p;
141 else if (signame == NULL)
142 signame = p;
143 else
144 bb_show_usage();
145 }
146
147 if (pathname == NULL)
148 bb_show_usage();
149
150 if (signame != NULL)
151 {
152 u_signal_names(signame, &my_signal, 1);
153 if (my_signal == 0)
154 {
155 log_failure_msg("unknown signal.");
156 bb_show_usage();
157 }
158 }
159
160//bb_printf("ARGS - %s %s %d = %s\n", pidfile, pathname, my_signal, u_signal_names(NULL, &signal, 1));
161 return killproc(pidfile, pathname, my_signal);
162}
diff --git a/urunlevel/runlevel/lib_init_d.c b/urunlevel/runlevel/lib_init_d.c
new file mode 100644
index 0000000..866888c
--- /dev/null
+++ b/urunlevel/runlevel/lib_init_d.c
@@ -0,0 +1,425 @@
1/*
2 * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 * 02111-1307 USA
18 *
19 */
20
21#include <dirent.h>
22#include <fcntl.h>
23#include <unistd.h>
24#include <errno.h>
25#include <signal.h>
26#include <string.h>
27#include <sys/poll.h>
28#include <sys/wait.h>
29#include <sys/utsname.h> /* for uname(2) */
30
31#include "busybox.h"
32#include "lib_init_d.h"
33
34
35static char *shell = 0;
36struct stat path_stat;
37
38
39char *argv_cat(int argc, char **argv)
40{
41 int i;
42 int length = 1;
43 char *message = NULL;
44
45 for (i = 0; i < argc; i++)
46 length += strlen(argv[i]);
47 message = (char *) xmalloc(sizeof (char) * length);
48
49 if (message != NULL)
50 {
51 message[0] = '\0';
52 for (i = 1; i < argc; i++)
53 {
54 strcat(message, argv[i]);
55 if (i < (argc - 1))
56 strcat(message, " ");
57 }
58 }
59 return message;
60}
61
62
63char *big_chomp(char *s)
64{
65 char *lc = index(s, '\n');
66
67 if(lc)
68 *lc = '\0';
69 return s;
70}
71
72
73char *doit(int mode, char *command, ...)
74{
75 int buffsize = 63;
76 char *buffer = NULL;
77 int dataPipe[2] = { -1, -1 };
78 int statusPipe[2] = { -1, -1 };
79 int n;
80 pid_t pid = 0;
81 volatile int vfork_exec_errno = 0;
82 char **args;
83 char *commandBuffer;
84
85 if (mode & DAEMON)
86 mode |= FORK | QUIET;
87
88 va_list p;
89 int r;
90
91 va_start(p, command);
92 r = vasprintf(&commandBuffer, command, p);
93 va_end(p);
94
95 if (r < 0)
96 bb_perror_msg_and_die("doit");
97
98 if (shell == 0)
99 {
100 shell = getenv("SHELL");
101 if (shell == 0)
102 shell = "/bin/sh";
103 }
104
105 args = (char **) xmalloc (sizeof (char *) * 4);
106 n = 0;
107 args[n++] = shell;
108 args[n++] = "-c";
109 if (mode & QUIET)
110 bb_xasprintf(&(args[n++]), "%s 2>/dev/null", commandBuffer);
111 else
112 args[n++] = commandBuffer;
113 args[n++] = 0;
114
115 if (!(mode & NOFORK))
116 {
117 if (!(mode & DAEMON))
118 {
119 if (pipe(dataPipe) < 0 || pipe(statusPipe) < 0)
120 bb_perror_msg("Failed to create pipe");
121 signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */
122 }
123// pid = vfork();
124 pid = fork();
125 }
126 if (pid == 0) /* child */
127 {
128 if ((!(mode & NOFORK)) && (!(mode & NOFORK)))
129 {
130 close(STDIN_FILENO);
131 dup2(dataPipe[1], STDOUT_FILENO);
132 dup2(dataPipe[1], STDERR_FILENO);
133 close(dataPipe[0]);
134 close(statusPipe[0]);
135 fcntl(statusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows sucess */
136 }
137
138 if ((mode & DAEMON))
139 {
140 if (!(mode & NOFORK))
141 {
142 close(dataPipe[1]);
143 close(statusPipe[1]);
144 close(STDOUT_FILENO);
145 close(STDERR_FILENO);
146 }
147 daemon(1, 0);
148 }
149 errno = 0;
150 execvp(shell, (char **) args );
151
152 vfork_exec_errno = errno;
153 if (!(mode & NOFORK))
154 close(statusPipe[1]);
155 _exit(-1);
156 }
157 else if (pid > 0) /* parent */
158 {
159 close(dataPipe[1]);
160 close(statusPipe[1]);
161
162 while (1)
163 {
164 char buf;
165
166 n = read(statusPipe[0], &buf, 1);
167
168 if ((n < 0) && ((errno == EAGAIN) || (errno == EINTR)) && !(mode & FORK))
169 continue; /* try it again */
170 else if (n == 0 && vfork_exec_errno != 0)
171 {
172 errno = vfork_exec_errno;
173 bb_perror_msg("Could not exec process");
174 }
175 break;
176 }
177 close(statusPipe[0]);
178
179 if (buffer == NULL)
180 buffer = (char *) xcalloc(buffsize + 1, sizeof (char));
181
182 if ((mode & FORK) == 0)
183 {
184 ssize_t cc;
185 struct pollfd poller[1];
186
187 poller[0].fd = dataPipe[0];
188 poller[0].events = POLLIN | POLLPRI;
189 poller[0].revents = 0;
190
191 n = 0;
192 while (1)
193 {
194 if ((buffsize - n) <= 0)
195 {
196 int i;
197
198 buffsize += buffsize;
199 buffer = xrealloc(buffer, sizeof(char) * (buffsize + 1));
200 for (i = n; i <= buffsize; i++)
201 buffer[i] = '\0';
202 }
203
204 errno = 0;
205 cc = poll(poller, 1, 1010); /* network sleeps for 1000 between '.' outputs */
206 if (cc > 0)
207 cc = read(dataPipe[0], &buffer[n], buffsize - n);
208
209 if (cc < 0)
210 {
211 if (errno == EINTR)
212 continue;
213 if (errno == EAGAIN)
214 continue;
215 break;
216 }
217 else if (cc == 0)
218 break;
219
220 if ((mode & (QUIET | REDIR)) == 0)
221 bb_printf(&buffer[n]);
222 n += cc;
223 }
224 }
225
226 if (mode & REDIR)
227 chomp(buffer);
228 }
229 else
230 {
231 bb_perror_msg("Failed to fork process");
232 }
233
234 n = 0;
235 if (pid)
236 {
237 close(dataPipe[0]);
238
239 if ((mode & FORK) == 0)
240 {
241 if (waitpid(pid, &n, 0) == -1)
242 bb_printf("Couldn't wait?");
243 }
244 if (WIFEXITED(n))
245 n = WEXITSTATUS(n);
246 else
247 n = -1;
248 }
249
250 free(args);
251 free(commandBuffer);
252 errno = n;
253 return buffer;
254}
255
256
257#ifdef RUNLEVEL_LIST
258// From ifupdown, so it should probably be in libbb.
259llist_t *llist_add_to_end(llist_t *list_head, char *data)
260{
261 llist_t *new_item, *tmp, *prev;
262
263 new_item = xmalloc(sizeof(llist_t));
264 new_item->data = data;
265 new_item->link = NULL;
266
267 prev = NULL;
268 tmp = list_head;
269 while(tmp)
270 {
271 prev = tmp;
272 tmp = tmp->link;
273 }
274 if (prev)
275 prev->link = new_item;
276 else
277 list_head = new_item;
278
279 return(list_head);
280}
281#endif
282
283
284llist_t *llist_delete(llist_t **head, llist_t *previous, llist_t *current)
285{
286 if (previous == NULL)
287 {
288 *head = current->link;
289 free(current);
290 current = *head;
291 }
292 else
293 {
294 previous->link = current->link;
295 free(current);
296 current = previous->link;
297 }
298
299 return current;
300}
301
302
303void make_disk(char *token, const nodes_t *nodes)
304{
305 int i;
306 char temp[32];
307
308 for (i = 0; nodes[i].name != 0; i++)
309 {
310 if (strncmp(nodes[i].name, token, 3) == 0)
311 {
312 int m = atoi(&token[3]);
313 sprintf(temp, "/dev/%s", token);
314 mknod(temp, nodes[i].mode, makedev(nodes[i].major, nodes[i].minor + m));
315 break;
316 }
317 }
318 sprintf(temp, "/media/%s", token);
319 bb_make_directory(temp, -1l, FILEUTILS_RECUR);
320}
321
322
323void make_ram_disk(int size, int number, char *place, int TMPFS)
324{
325 if (size > 0)
326 {
327 char *place2;
328
329 bb_printf( "Creating ramdisk at %s\n", place);
330 bb_xasprintf(&place2, "%s2", place);
331 if (copy_file(place, place2, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS) >= 0)
332 remove_file(place, FILEUTILS_RECUR | FILEUTILS_FORCE);
333 bb_make_directory (place, -1l, 0);
334 if (TMPFS)
335 quick_mount("tmpfs", "/dev/null", place, "-n -o size=%i", size * 1024);
336 else
337 {
338 doit(QUIET, "mkfs.minix /dev/ram%i %i", number, size);
339 quick_mount("minix", "", "", "/dev/ram%i %s", number, place);
340 }
341 if (copy_file(place2, place, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS) >= 0)
342 remove_file(place2, FILEUTILS_RECUR | FILEUTILS_FORCE);
343 free(place2);
344 }
345}
346
347
348void quick_mount(char *type, char *device, char *path, char *data, ...)
349{
350 char *dataBuffer;
351 va_list p;
352 int r;
353
354 va_start(p, data);
355 r = vasprintf(&dataBuffer, data, p);
356 va_end(p);
357 if (r < 0)
358 bb_perror_msg("quick_mount");
359 else
360 {
361 doit(QUIET, "busybox mount -t %s %s %s %s", type, device, path, dataBuffer);
362 }
363
364 free(dataBuffer);
365}
366
367
368char *quick_read(char *filename)
369{
370 char *result = NULL;
371
372 if (stat(filename, &path_stat) == 0)
373 {
374// if (S_ISREG(path_stat.st_mode))
375 {
376 int ifd;
377 ssize_t size = path_stat.st_size;
378
379 if (size <= 0)
380 size = 1024;
381 result = (char *) xmalloc (sizeof (char) * size + 1);
382 if ((ifd = open(filename, O_RDONLY)) < 0)
383 bb_perror_msg("%s", filename);
384 else
385 {
386 ssize_t total = bb_full_read(ifd, result, size);
387// result[path_stat.st_size] = '\0';
388 result[total] = '\0';
389 if (close (ifd) < 0)
390 bb_perror_msg("%s", filename);
391 }
392 }
393 }
394
395 return result;
396}
397
398
399void quick_write(const char *filename, const char *data, ...)
400{
401 char *dataBuffer;
402 va_list p;
403 int r;
404
405 va_start(p, data);
406 r = vasprintf(&dataBuffer, data, p);
407 va_end(p);
408 if (r >= 0)
409 {
410 int ofd;
411
412 if ((ofd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
413 bb_perror_msg("%s", filename);
414 else
415 {
416 r = bb_full_write(ofd, dataBuffer, r);
417 if (close (ofd) < 0)
418 bb_perror_msg("%s", filename);
419 }
420 }
421 if (r < 0)
422 bb_perror_msg("quick_write");
423
424 free(dataBuffer);
425}
diff --git a/urunlevel/runlevel/lib_init_d.h b/urunlevel/runlevel/lib_init_d.h
new file mode 100644
index 0000000..a9179d5
--- /dev/null
+++ b/urunlevel/runlevel/lib_init_d.h
@@ -0,0 +1,202 @@
1/*
2 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 * 02111-1307 USA
18 *
19 */
20
21#ifndef _INIT_D_H
22#define _INIT_D_H
23
24
25/*
26 * init script defines
27 */
28
29#define INIT_D_COMMENT "\n#// "
30#define INIT_D_BEGIN "\n### BEGIN INIT INFO "
31#define INIT_D_PROV "\n# Provides: "
32#define INIT_D_RSTART "\n# Required-Start: "
33#define INIT_D_RSTOP "\n# Required-Stop: "
34#define INIT_D_SSTART "\n# Should-Start: "
35#define INIT_D_SSTOP "\n# Should-Stop: "
36#define INIT_D_DSTART "\n# Default-Start: "
37#define INIT_D_DSTOP "\n# Default-Stop: "
38#define INIT_D_SDESC "\n# Short-Description: "
39#define INIT_D_DESC "\n# Description: "
40#define INIT_D_CONT "\n#\t"
41#define INIT_D_CONT2 "\n# "
42#define INIT_D_END "\n### END INIT INFO\n"
43#define INIT_D_CUSTOM "\n# X-"
44
45
46/*
47 * init info
48 */
49
50typedef struct init_d_info_s {
51 char **provides;
52 char **reqstart;
53 char **reqstop;
54 char **shouldstart;
55 char **shouldstop;
56 int *defstart;
57 int *defstop;
58 char *shortdesc;
59 char *desc;
60 char *comment;
61 int sizes[11];
62 char *path;
63 llist_t *start;
64} init_d_info_t;
65
66
67/*
68 * init commands
69 */
70
71typedef struct init_d_handle_s {
72 int (*start)(struct init_d_handle_s *, int);
73 int (*stop)(struct init_d_handle_s *, int);
74 int (*restart)(struct init_d_handle_s *, int);
75 int (*try_restart)(struct init_d_handle_s *, int);
76 int (*reload)(struct init_d_handle_s *, int);
77 int (*force_reload)(struct init_d_handle_s *, int);
78 int (*status)(struct init_d_handle_s *, int);
79 int (*show_info)(struct init_d_handle_s *, int);
80 char *basename;
81 char *pathname;
82 char *args;
83 char *pidfile;
84 char *info;
85} init_d_handle_t;
86
87
88int do_init_from_main(int argc, char **argv, struct init_d_handle_s *init_d);
89int do_init(struct init_d_handle_s *init_d, const char *command);
90
91int default_start(struct init_d_handle_s *, int);
92int default_stop(struct init_d_handle_s *, int);
93int default_restart(struct init_d_handle_s *, int);
94int default_try_restart(struct init_d_handle_s *, int);
95int default_reload(struct init_d_handle_s *, int);
96int default_force_reload(struct init_d_handle_s *, int);
97int default_status(struct init_d_handle_s *, int);
98int default_show_info(struct init_d_handle_s *, int);
99
100int no_stop(struct init_d_handle_s *, int);
101int no_reload(struct init_d_handle_s *, int);
102int no_status(struct init_d_handle_s *, int);
103
104int sighup_reload(struct init_d_handle_s *, int);
105int print_status(struct init_d_handle_s *init_d, int quiet, int status);
106
107/*
108 * error codes
109 */
110
111#define INIT_D_OK 0
112#define INIT_D_ERROR_GENERIC 1
113#define INIT_D_ERROR_ARGS 2
114#define INIT_D_ERROR_NOT_IMPLEMENTED 3
115#define INIT_D_ERROR_SECURITY 4
116#define INIT_D_ERROR_NOT_INSTALLED 5
117#define INIT_D_ERROR_NOT_CONFIGURED 6
118#define INIT_D_ERROR_NOT_RUNNING 7
119
120
121/*
122 * internal error codes
123 *
124 * Only used internally to support just_checking.
125 */
126
127#define INIT_D_ERROR_JUST_RUNNING 150
128#define INIT_D_ERROR_JUST_NOT_RUNNING 151
129
130
131/*
132 * status codes
133 */
134
135#define INIT_D_STATUS_OK 0
136#define INIT_D_STATUS_DEAD_PID 1
137#define INIT_D_STATUS_DEAD_LOCK 2
138#define INIT_D_STATUS_NOT_RUNNING 3
139#define INIT_D_STATUS_UNKNOWN 4
140
141
142/*
143 * /lib/lsb/init-functions
144 */
145int start_daemon(int force, int nice_level, char *pidfile, char *pathname, char *args);
146int killproc(char *pidfile, char *pathname, int my_signal);
147int checkpid(char *pid);
148int pidofproc(char *pidfile, char *pathname, char **pids);
149void log_success_msg(char *message);
150void log_failure_msg(char *message);
151void log_warning_msg(char *message);
152
153
154init_d_info_t *parse_init_info(char *info_text, char *name);
155char *get_init_info(char *pathname);
156llist_t *get_scripts(void);
157llist_t *sort_scripts(llist_t *unsorted);
158
159
160#define REDIR 1
161#define QUIET 2
162#define ERRONLY 4
163#define FORK 8
164#define NOFORK 16
165#define DAEMON 32
166
167extern struct stat path_stat;
168
169typedef struct nodes_s
170{
171 const char *name;
172 mode_t mode;
173 int major;
174 int minor;
175 int count;
176} nodes_t;
177
178
179char *argv_cat(int argc, char **argv);
180char *big_chomp(char *s);
181int checkpid(char *pid);
182char *doit(int mode, char *command, ...);
183
184#ifndef CONFIG_IFUPDOWN
185#define RUNLEVEL_LIST 1
186#endif
187#ifdef RUNLEVEL_LIST
188// From ifupdown, so it should probably be in libbb.
189llist_t *llist_add_to_end(llist_t *list_head, char *data);
190#else
191extern llist_t *llist_add_to_end(llist_t *list_head, char *data);
192#endif
193
194llist_t *llist_delete(llist_t **unsorted, llist_t *previous, llist_t *current);
195void make_disk(char *token, const nodes_t *nodes);
196void make_ram_disk(int size, int number, char *place, int TMPFS);
197void quick_mount(char *type, char *device, char *path, char *data, ...);
198char *quick_read(char *filename);
199void quick_write(const char *filename, const char *data, ...);
200
201
202#endif
diff --git a/urunlevel/runlevel/local_fs.c b/urunlevel/runlevel/local_fs.c
new file mode 100644
index 0000000..17b45f6
--- /dev/null
+++ b/urunlevel/runlevel/local_fs.c
@@ -0,0 +1,199 @@
1/*
2 * Mini $local_fs boot implementation for busybox.
3 *
4 * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <string.h>
24#include <unistd.h>
25
26#include "busybox.h"
27#include "lib_init_d.h"
28
29
30const static nodes_t nodes[] =
31{
32 {"hda", S_IFBLK, 3, 0, 0},
33 {"hdb", S_IFBLK, 3, 64, 0},
34 {"hdc", S_IFBLK, 22, 0, 0},
35 {"hdd", S_IFBLK, 22, 64, 0},
36 {"ram", S_IFBLK, 1, 0, 9},
37 {"fd", S_IFBLK, 2, 0, 1},
38 {"loop", S_IFBLK, 7, 0,63},
39 {"cloop", S_IFBLK, 240, 0, 7},
40 {"vcs", S_IFBLK, 7, 0, 9},
41 {"vcsa", S_IFBLK, 7, 0, 9},
42 {0, 0, 0, 0, 0}
43};
44
45
46static int start(struct init_d_handle_s *, int);
47static int status(struct init_d_handle_s *, int);
48static int stop(struct init_d_handle_s *, int);
49
50
51static init_d_handle_t my_commands =
52{
53 &start,
54 &stop,
55 NULL,
56 NULL,
57 &no_reload,
58 NULL,
59 &status,
60 NULL,
61 "local_fs",
62 NULL,
63 NULL,
64 NULL,
65 INIT_D_BEGIN \
66 INIT_D_PROV "$local_fs" \
67 INIT_D_DSTART "1 2 3 4 5" \
68 INIT_D_DSTOP "0 6" \
69 INIT_D_SDESC "Mount all local file systems." \
70 INIT_D_DESC "Mount all local file systems." \
71 INIT_D_CONT "Including any left over partitions not otherwise mounted." \
72 INIT_D_END
73};
74
75
76static const char *i386_sys_types[] =
77{
78// " 0Empty",
79// " 1fat",
80// " 4fat",
81// " 6fat",
82// " bvfat",
83 " cvfat",
84// " evfat",
85// " fvfat",
86 "80minix",
87 "81minix",
88 "82swap",
89 "83ext2",
90 "85Linux extended",
91 0
92};
93
94
95int local_fs_main(int argc, char **argv)
96{
97 return do_init_from_main(argc, argv, &my_commands);
98}
99
100
101static int start(struct init_d_handle_s *init_d, int just_checking)
102{
103 int i;
104 char *CMDLINE = 0;
105 char *ROOT = 0;
106 char *CDEV = 0;
107 char *FDEV = 0;
108 char *token;
109 char *strtok_temp;
110
111sleep(5); // delay it for testing purposes
112// Should fsck all non root partitions first.
113 doit(0, "/bin/mount -a");
114 bb_xasprintf(&CMDLINE, "%s", doit(REDIR, "cat /proc/cmdline"));
115 for (token = strtok_r(CMDLINE, " \t\n\r", &strtok_temp); token != NULL; token = strtok_r(NULL, " \t\n\r", &strtok_temp))
116 {
117 if (strncmp(token, "ROOT=", 5) == 0)
118 ROOT = &token[5];
119 }
120
121 bb_xasprintf(&CDEV, "%s", doit(REDIR, "dmesg | grep D-ROM | grep hd | cut -d: -f1 | sort | uniq"));
122
123 bb_xasprintf(&FDEV, "%s %s", doit(REDIR, "dmesg | grep -v LDM | grep \"^ [sh]d[a-f]\" | cut -d':' -f2 | sort | uniq"), (CDEV != 0) ? CDEV : "");
124 token = strtok_r(FDEV, " \r\n", &strtok_temp);
125 for (i = 0; token != NULL; i++)
126 {
127 if (strlen(token) > 2)
128 make_disk(token, nodes);
129 token = strtok_r(NULL, " \r\n", &strtok_temp);
130 }
131
132 bb_xasprintf(&FDEV, "%s", doit(REDIR, "fdisk -l | grep \"^/dev/\" | cut -b6-10,52-55"));
133 token = strtok_r(FDEV, "\r\n", &strtok_temp);
134 for (i = 0; token != NULL; i++)
135 {
136 int j;
137 int found = 0;
138 char *type = &token[6];
139 token[4] = '\0';
140 for (j = 0; i386_sys_types[j] != 0; j++)
141 {
142 if (strncmp(i386_sys_types[j], type, 2) == 0)
143 {
144 char *DEV = 0;
145 char *MOUNT = 0;
146 char *TYPE = 0;
147
148 bb_xasprintf(&DEV, "/dev/%s", token);
149 bb_xasprintf(&MOUNT, "/media/%s", token);
150 bb_xasprintf(&TYPE, "%s", &i386_sys_types[j][2]);
151 found = 1;
152 if (strncmp(&i386_sys_types[j][2], "swap", 4) == 0)
153 {
154 doit(QUIET, "mkswap %s", DEV);
155 doit(QUIET, "swapon %s", DEV);
156 }
157 else
158 {
159// Should not mount it if it is already mounted.
160 if ((ROOT == 0) || strcmp(ROOT, DEV) != 0) /* Don't try to remount ROOT, */
161 {
162 make_disk(token, nodes);
163 quick_mount(TYPE, DEV, MOUNT, "-o ro");
164// quick_mount("auto", DEV, MOUNT, "-o ro");
165 }
166 }
167
168 break;
169 }
170 }
171// if (found == 0)
172// bb_printf(" %s - unknown\n", token);
173
174 token = strtok_r(NULL, "\r\n", &strtok_temp);
175 }
176
177 free(FDEV);
178 free(CDEV);
179 free(ROOT);
180 free(CMDLINE);
181
182 return INIT_D_OK;
183}
184
185
186static int status(struct init_d_handle_s *init_d, int quiet)
187{
188 return print_status(init_d, quiet, INIT_D_STATUS_OK);
189}
190
191
192static int stop(struct init_d_handle_s *init_d, int just_checking)
193{
194// Should only umount things we mounted in the first place.
195// Same for swap
196 doit(0, "/sbin/swapoff -a");
197 doit(0, "/bin/umount -a -r");
198 return INIT_D_OK;
199}
diff --git a/urunlevel/runlevel/log_failure_msg.c b/urunlevel/runlevel/log_failure_msg.c
new file mode 100644
index 0000000..47f43f7
--- /dev/null
+++ b/urunlevel/runlevel/log_failure_msg.c
@@ -0,0 +1,54 @@
1/*
2 * Mini log_failure_msg implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27
28
29void log_failure_msg(char *message)
30{
31 bb_perror_msg("Failure - %s\n", message);
32}
33
34
35/*
36log_failure_msg "message"
37 This requests the distribution to print a failure
38 message. The message should be relatively short; no
39 more than 60 characters is highly desirable.
40*/
41
42int log_failure_msg_main(int argc, char **argv)
43{
44 char *message = argv_cat(argc, argv);
45
46 if (message != NULL)
47 {
48 log_failure_msg(message);
49
50 free(message);
51 return EXIT_SUCCESS;
52 }
53 return EXIT_FAILURE;
54}
diff --git a/urunlevel/runlevel/log_success_msg.c b/urunlevel/runlevel/log_success_msg.c
new file mode 100644
index 0000000..caa1eed
--- /dev/null
+++ b/urunlevel/runlevel/log_success_msg.c
@@ -0,0 +1,54 @@
1/*
2 * Mini log_success_msg implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27
28
29void log_success_msg(char *message)
30{
31 bb_printf("Success - %s\n", message);
32}
33
34
35/*
36log_success_msg "message"
37 This requests the distribution to print a success
38 message. The message should be relatively short; no
39 more than 60 characters is highly desirable.
40*/
41
42int log_success_msg_main(int argc, char **argv)
43{
44 char *message = argv_cat(argc, argv);
45
46 if (message != NULL)
47 {
48 log_success_msg(message);
49
50 free(message);
51 return EXIT_SUCCESS;
52 }
53 return EXIT_FAILURE;
54}
diff --git a/urunlevel/runlevel/log_warning_msg.c b/urunlevel/runlevel/log_warning_msg.c
new file mode 100644
index 0000000..81ef204
--- /dev/null
+++ b/urunlevel/runlevel/log_warning_msg.c
@@ -0,0 +1,54 @@
1/*
2 * Mini log_warning_msg implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27
28
29void log_warning_msg(char *message)
30{
31 bb_perror_msg("Warning - %s\n", message);
32}
33
34
35/*
36log_warning_msg "message"
37 This requests the distribution to print a warning
38 message. The message should be relatively short; no
39 more than 60 characters is highly desirable.
40*/
41
42int log_warning_msg_main(int argc, char **argv)
43{
44 char *message = argv_cat(argc, argv);
45
46 if (message != NULL)
47 {
48 log_warning_msg(message);
49
50 free(message);
51 return EXIT_SUCCESS;
52 }
53 return EXIT_FAILURE;
54}
diff --git a/urunlevel/runlevel/network.c b/urunlevel/runlevel/network.c
new file mode 100644
index 0000000..dff5fc1
--- /dev/null
+++ b/urunlevel/runlevel/network.c
@@ -0,0 +1,146 @@
1/*
2 * Mini network boot implementation for busybox.
3 *
4 * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <string.h>
24#include <unistd.h>
25
26#include "busybox.h"
27#include "lib_init_d.h"
28
29
30static int start(struct init_d_handle_s *, int);
31static int status(struct init_d_handle_s *init_d, int);
32static int stop(struct init_d_handle_s *, int);
33
34
35static init_d_handle_t my_commands =
36{
37 &start,
38 &stop,
39 NULL,
40 NULL,
41 NULL,
42 NULL,
43 &status,
44 NULL,
45 "network",
46 NULL,
47 NULL,
48 NULL,
49 INIT_D_BEGIN \
50 INIT_D_PROV "$network" \
51 INIT_D_RSTART "$syslog" \
52 INIT_D_DSTART "3 4 5" \
53 INIT_D_DSTOP "0 1 2 6" \
54 INIT_D_SDESC "Basic network setup" \
55 INIT_D_DESC "Configures all your network interfaces," \
56 INIT_D_CONT "brings them all up and sets up routing." \
57 INIT_D_CONT "Also configures things like port forwarding," \
58 INIT_D_CONT "hostnames, etc." \
59 INIT_D_END
60};
61
62
63int network_main(int argc, char **argv)
64{
65 return do_init_from_main(argc, argv, &my_commands);
66}
67
68
69static int start(struct init_d_handle_s *init_d, int just_checking)
70{
71 int i;
72 int my_status = (init_d->status)(init_d, 0);
73 char *IPADDR = 0;
74
75 if (my_status == INIT_D_STATUS_NOT_RUNNING)
76 {
77 my_status = INIT_D_ERROR_NOT_RUNNING;
78// if (stat("/proc/net/pnp", &path_stat) == 0)
79// copy_file("/proc/net/pnp", "/etc/resolv.conf", FILEUTILS_FORCE | FILEUTILS_PRESERVE_STATUS);
80
81 fflush(stdout);
82 doit(QUIET, "ifup -af");
83 for (i = 20; stat("/var/lib/network/ipaddr", &path_stat) != 0; i--)
84 {
85 bb_printf(".");
86 fflush(stdout);
87 sleep(2);
88 if (i <= 0)
89 {
90 bb_printf(" timeout.");
91 break;
92 }
93 }
94
95 if (stat("/var/lib/network/ipaddr", &path_stat) == 0)
96 IPADDR = quick_read("/var/lib/network/ipaddr");
97
98 if ((IPADDR != 0) && (IPADDR[0] != '\0'))
99 {
100 if (stat("/proc/sys/net/ipv4/tcp_syn_retries", &path_stat) == 0)
101 quick_write("/proc/sys/net/ipv4/tcp_syn_retries", "7");
102 if (stat("/var/lib/my_linux/config/ipfwd", &path_stat) == 0)
103 {
104 bb_printf("Enabling IP forwarding\n");
105 quick_write("/proc/sys/net/ipv4/ip_forward", "1");
106 }
107 if (stat("/var/lib/my_linux/config/noping", &path_stat) == 0)
108 quick_write("/proc/sys/net/ipv4/icmp_echo_ignore_all", "1");
109 my_status = INIT_D_OK;
110 }
111 else
112 my_status = INIT_D_ERROR_GENERIC;
113
114 free(IPADDR);
115 }
116 else
117 my_status = INIT_D_OK;
118
119 return my_status;
120}
121
122
123static int status(struct init_d_handle_s *init_d, int quiet)
124{
125 int my_status = INIT_D_STATUS_NOT_RUNNING;
126 char *ip = NULL;
127
128 bb_xasprintf(&ip, "%s", doit(REDIR, "ip -o addr | grep lo: | cut -d\" \" -f3 | cut -d\",\" -f2"));
129 if ((ip != NULL) && (strncmp("UP", ip, 2) == 0))
130 my_status = INIT_D_STATUS_OK;
131
132 return print_status(init_d, quiet, my_status);
133}
134
135
136static int stop(struct init_d_handle_s *init_d, int just_checking)
137{
138 int my_status = default_stop(init_d, 1);
139
140 if (my_status == INIT_D_ERROR_JUST_RUNNING)
141 {
142 doit(QUIET, "ifdown -af");
143 my_status = INIT_D_OK;
144 }
145 return my_status;
146}
diff --git a/urunlevel/runlevel/pidofproc.c b/urunlevel/runlevel/pidofproc.c
new file mode 100644
index 0000000..6d03ae8
--- /dev/null
+++ b/urunlevel/runlevel/pidofproc.c
@@ -0,0 +1,192 @@
1/*
2 * Mini pidofproc implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <getopt.h>
24#include <string.h>
25#include <unistd.h>
26
27#include "busybox.h"
28#include "lib_init_d.h"
29
30
31int checkpid(char *pid)
32{
33 int found = 0;
34 char proc[132];
35
36 sprintf(proc, "/proc/%s", pid);
37 if (stat(proc, &path_stat) == 0)
38 {
39 char *state = NULL;
40
41 sprintf(proc, "/proc/%s/stat", pid);
42 state = quick_read(proc);
43 if (state != NULL)
44 {
45 /* Read and interpret the third space seperated field (State - DRSW = OK - ZX = DEAD_PID - T = STOPPED) */
46 if (state[0] != '\0')
47 {
48 while (*state != ' ') state++;
49 while (*state == ' ') state++;
50 while (*state != ' ') state++
51// Should compare the name while scanning this.
52 ;
53 while (*state == ' ') state++;
54 switch (*state)
55 {
56 case 'D' :
57 case 'R' :
58 case 'S' :
59 case 'W' :
60 case 'T' : /* Until proven otherwise, I'm assuming this means OK. */
61 found = 1;
62 }
63 }
64 }
65 else /* Paranoid fallbacks. */
66 {
67 sprintf(proc, "/proc/%s/exe", pid);
68 if (stat(proc, &path_stat) == 0)
69 {
70// Should check that it is a link to our executable.
71 found = 1;
72 }
73 else
74 {
75 sprintf(proc, "/proc/%s/cmdline", pid);
76 if (stat(proc, &path_stat) == 0)
77 {
78// Should compare the name.
79 found = 1;
80 }
81 }
82 }
83
84 }
85
86 return found;
87}
88
89
90int pidofproc(char *pidfile, char *pathname, char **pids)
91{
92 int status = INIT_D_STATUS_UNKNOWN;
93 char *our_pidfile = pidfile;
94 char *our_pids = NULL;
95
96 if (our_pidfile == NULL)
97 bb_xasprintf(&our_pidfile, "/var/run/%s.pid", bb_get_last_path_component(pathname));
98
99 our_pids = quick_read(our_pidfile);
100
101 if (our_pids != NULL)
102 {
103 int i;
104 char *pid;
105 char *strtok_temp;
106
107 status = INIT_D_STATUS_DEAD_PID;
108 if (pids != NULL)
109 {
110 (*pids) = (char *) xmalloc(sizeof (char) * strlen(our_pids) + 1);
111 (*pids)[0] = '\0';
112 }
113
114 pid = strtok_r(our_pids, " \n\r", &strtok_temp);
115 for (i = 0; pid != NULL; i++)
116 {
117 if (checkpid(pid))
118 {
119 if (pids != NULL)
120 {
121 strcat(*pids, pid);
122 strcat(*pids, " ");
123 }
124 status = INIT_D_STATUS_OK;
125 }
126
127 pid = strtok_r(NULL, " \n\r", &strtok_temp);
128 }
129
130 free(our_pids);
131 }
132 else
133 status = INIT_D_STATUS_NOT_RUNNING;
134
135 if (pidfile == NULL)
136 free(our_pidfile);
137
138 return status;
139}
140
141
142/*
143pidofproc [-p pidfile] pathname
144 This function returns one or more pid(s) for a particular
145 daemon using the algorithm given above. Only pids of running processes
146 should be returned.
147
148 Multiple pid(s) shall be separated by a single space in the pidfile
149 and in the output of pidofproc.
150
151 Compliant applications may use the basename instead of the pathname.
152 pidofproc should return the LSB defined exit status
153 codes for "status". It shall return 0 if the program is
154 running and not 0 otherwise.
155*/
156
157static const struct option long_options[] =
158{
159 { "pidfile", 1, NULL, 'p' },
160 { 0, 0, 0, 0 }
161};
162
163int pidofproc_main(int argc, char **argv)
164{
165 int result = EXIT_FAILURE;
166 char *pidfile = NULL;
167 char *pids = NULL;
168 int opt;
169
170 while ((opt = getopt_long (argc, argv, "p:", long_options, NULL)) > 0)
171 {
172 switch (opt)
173 {
174 case 'p':
175 pidfile = optarg;
176 break;
177
178 default:
179 bb_show_usage();
180 }
181 }
182
183 /* We require exactly one argument: the path name */
184 if (optind != (argc - 1))
185 bb_show_usage();
186
187 result = pidofproc(pidfile, argv[optind], &pids);
188 if (pids != NULL)
189 bb_printf("%s\n", pids);
190
191 return result;
192}
diff --git a/urunlevel/runlevel/rc.c b/urunlevel/runlevel/rc.c
new file mode 100644
index 0000000..9efe84d
--- /dev/null
+++ b/urunlevel/runlevel/rc.c
@@ -0,0 +1,1271 @@
1/*
2 * Mini rc implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <sys/types.h>
24#include <ctype.h>
25#include <dirent.h>
26#include <errno.h>
27#include <signal.h>
28#include <stdio.h>
29#include <string.h>
30#include <unistd.h>
31
32#include "busybox.h"
33#include "lib_init_d.h"
34
35
36const static char *commands[] =
37{
38 "start",
39 "stop",
40 "restart",
41 "try-restart",
42 "reload",
43 "force-reload",
44 "status",
45 "info",
46 NULL
47};
48
49
50const static char *INFOS[] =
51{
52 INIT_D_BEGIN,
53 INIT_D_PROV,
54 INIT_D_RSTART,
55 INIT_D_RSTOP,
56 INIT_D_SSTART,
57 INIT_D_SSTOP,
58 INIT_D_DSTART,
59 INIT_D_DSTOP,
60 INIT_D_SDESC,
61 INIT_D_DESC,
62 INIT_D_COMMENT,
63 INIT_D_CONT,
64 INIT_D_CONT2,
65 INIT_D_END,
66 NULL
67};
68
69
70int default_start(struct init_d_handle_s *init_d, int just_checking)
71{
72 int status = (init_d->status)(init_d, 0);
73
74 switch (status)
75 {
76 case INIT_D_STATUS_OK :
77 {
78 status = INIT_D_OK;
79 break;
80 }
81
82 case INIT_D_STATUS_DEAD_PID :
83 {
84 log_warning_msg("Stale pid file exists!");
85 status = INIT_D_ERROR_GENERIC; // LSB is not clear on what to return, but this is an error condition.
86 break;
87 }
88
89 case INIT_D_STATUS_DEAD_LOCK :
90 {
91 log_warning_msg("Stale lock file exists!");
92 status = INIT_D_ERROR_GENERIC; // LSB is not clear on what to return, but this is an error condition.
93 break;
94 }
95
96 case INIT_D_STATUS_NOT_RUNNING :
97 {
98 struct stat script_stat;
99
100 if (stat(init_d->pathname, &script_stat) == 0)
101 {
102 if (just_checking)
103 status = INIT_D_ERROR_JUST_NOT_RUNNING;
104 else
105 status = start_daemon(0, 0, init_d->pidfile, init_d->pathname, init_d->args);
106 }
107 else
108 status = INIT_D_ERROR_NOT_INSTALLED;
109 break;
110 }
111
112 default :
113 {
114 status = INIT_D_ERROR_GENERIC;
115 break;
116 }
117 }
118
119 return status;
120}
121
122
123int default_stop(struct init_d_handle_s *init_d, int just_checking)
124{
125 int status = (init_d->status)(init_d, 0);
126
127 switch (status)
128 {
129 case INIT_D_STATUS_OK :
130 {
131 if (just_checking)
132 status = INIT_D_ERROR_JUST_RUNNING;
133 else
134 status = killproc(init_d->pidfile, init_d->pathname, 0);
135 break;
136 }
137
138 case INIT_D_STATUS_DEAD_PID :
139 {
140 log_warning_msg("Stale pid file exists!");
141 status = INIT_D_ERROR_GENERIC; // LSB is not clear on what to return, but this is an error condition.
142 break;
143 }
144
145 case INIT_D_STATUS_DEAD_LOCK :
146 {
147 log_warning_msg("Stale lock file exists!");
148 status = INIT_D_ERROR_GENERIC; // LSB is not clear on what to return, but this is an error condition.
149 break;
150 }
151
152 case INIT_D_STATUS_NOT_RUNNING :
153 {
154 status = INIT_D_OK;
155 break;
156 }
157
158 default :
159 {
160 status = INIT_D_ERROR_GENERIC;
161 break;
162 }
163 }
164
165 return status;
166}
167
168
169int default_restart(struct init_d_handle_s *init_d, int just_checking)
170{
171 int status = (init_d->status)(init_d, 0);
172
173 switch (status)
174 {
175 case INIT_D_STATUS_OK :
176 {
177 status = (init_d->stop)(init_d, just_checking);
178 if ((status == INIT_D_OK) || (status == INIT_D_ERROR_NOT_RUNNING))
179 status = INIT_D_STATUS_NOT_RUNNING;
180 else
181 status = INIT_D_STATUS_UNKNOWN;
182 break;
183 }
184
185 case INIT_D_STATUS_DEAD_PID :
186 {
187 log_warning_msg("Stale pid file exists!");
188 break;
189 }
190
191 case INIT_D_STATUS_DEAD_LOCK :
192 {
193 log_warning_msg("Stale lock file exists!");
194 break;
195 }
196 }
197 if (status == INIT_D_STATUS_NOT_RUNNING)
198 status = (init_d->start)(init_d, just_checking);
199 else
200 status = INIT_D_ERROR_GENERIC;
201
202 return status;
203}
204
205
206int default_try_restart(struct init_d_handle_s *init_d, int just_checking)
207{
208 int status = (init_d->status)(init_d, 0);
209
210 switch (status)
211 {
212 case INIT_D_STATUS_OK :
213 {
214 status = (init_d->stop)(init_d, just_checking);
215 if (status == INIT_D_OK)
216 status = (init_d->start)(init_d, just_checking);
217 else if (status == INIT_D_ERROR_NOT_RUNNING) /* I think this is what LSB 8.2.61 means. LSB 8.2.59 means that this should never happen though. */
218 status = INIT_D_OK;
219 break;
220 }
221
222 case INIT_D_STATUS_NOT_RUNNING : /* I think this is what LSB 8.2.61 means. */
223 { /* If try-restart was meant to start a stopped service, then it would be no different from restart.
224 * LSB 8.2.42-44 may have some bearing on this, but the english is broken, rendering it unintelligable.
225 * OTH, try-restart is optional, so a broken implentation is no problem B-).
226 * OTGH, our force-reload uses this as it's fallback position.
227 */
228 status = INIT_D_OK;
229 break;
230 }
231
232 default :
233 {
234 status = INIT_D_ERROR_GENERIC;
235 }
236 }
237
238 return status;
239}
240
241
242int default_reload(struct init_d_handle_s *init_d, int just_checking)
243{
244 return INIT_D_ERROR_NOT_IMPLEMENTED;
245}
246
247
248int sighup_reload(struct init_d_handle_s *init_d, int just_checking)
249{
250 int status = (init_d->status)(init_d, 0);
251
252 switch (status)
253 {
254 case INIT_D_STATUS_OK :
255 {
256 if (just_checking)
257 status = INIT_D_ERROR_JUST_RUNNING;
258 else
259 status = killproc(init_d->pidfile, init_d->pathname, SIGHUP);
260 break;
261 }
262
263 case INIT_D_STATUS_NOT_RUNNING :
264 {
265 status = INIT_D_ERROR_NOT_RUNNING;
266 break;
267 }
268
269 default :
270 {
271 status = INIT_D_ERROR_GENERIC;
272 break;
273 }
274 }
275
276 return status;
277}
278
279
280int default_force_reload(struct init_d_handle_s *init_d, int just_checking)
281{
282 int status = (init_d->reload)(init_d, just_checking);
283
284 if (status == INIT_D_ERROR_NOT_IMPLEMENTED)
285 status = (init_d->try_restart)(init_d, just_checking);
286
287 return status;
288}
289
290
291int print_status(struct init_d_handle_s *init_d, int quiet, int status)
292{
293 if (quiet)
294 switch (status)
295 {
296 case INIT_D_STATUS_OK :
297 {
298 bb_printf("%s is running.\n", init_d->basename);
299 break;
300 }
301
302 case INIT_D_STATUS_DEAD_PID :
303 {
304 bb_printf("%s is not running, but there is a stale %s.\n", init_d->basename, init_d->pidfile);
305 break;
306 }
307
308 case INIT_D_STATUS_DEAD_LOCK :
309 {
310 bb_printf("%s is not running, but there is a stale lock file.\n", init_d->basename);
311 break;
312 }
313
314 case INIT_D_STATUS_NOT_RUNNING :
315 {
316 bb_printf("%s is not running.\n", init_d->basename);
317 break;
318 }
319
320 default :
321 {
322 bb_printf("The status of %s is not known.\n", init_d->basename);
323 break;
324 }
325 }
326
327 return status;
328}
329
330
331int default_status(struct init_d_handle_s *init_d, int quiet)
332{
333 return print_status(init_d, quiet, pidofproc(init_d->pidfile, init_d->pathname, NULL));
334}
335
336
337int default_show_info(struct init_d_handle_s *init_d, int just_checking)
338{
339 bb_printf("%s", init_d->info);
340 return INIT_D_OK;
341}
342
343
344int no_stop(struct init_d_handle_s *init_d, int just_checking)
345{
346 return INIT_D_ERROR_NOT_IMPLEMENTED;
347}
348
349
350int no_reload(struct init_d_handle_s *init_d, int just_checking)
351{
352 return INIT_D_ERROR_NOT_IMPLEMENTED;
353}
354
355
356int no_status(struct init_d_handle_s *init_d, int quiet)
357{
358 return INIT_D_ERROR_NOT_IMPLEMENTED;
359}
360
361
362int do_init_from_main(int argc, char **argv, struct init_d_handle_s *init_d)
363{
364 return do_init(init_d, (argc > 1) ? argv[1] : NULL);
365}
366
367
368int do_init(struct init_d_handle_s *init_d, const char *command)
369{
370 int i;
371 int status = INIT_D_ERROR_NOT_IMPLEMENTED;
372 char *original_pidfile = init_d->pidfile;
373
374 if (init_d->start == NULL) init_d->start = &default_start;
375 if (init_d->stop == NULL) init_d->stop = &default_stop;
376 if (init_d->restart == NULL) init_d->restart = &default_restart;
377 if (init_d->try_restart == NULL) init_d->try_restart = &default_try_restart;
378 if (init_d->reload == NULL) init_d->reload = &default_reload;
379 if (init_d->force_reload == NULL) init_d->force_reload = &default_force_reload;
380 if (init_d->status == NULL) init_d->status = &default_status;
381 if (init_d->show_info == NULL) init_d->show_info = &default_show_info;
382 if (init_d->basename == NULL) init_d->basename = bb_get_last_path_component(init_d->pathname);
383 if (init_d->pathname == NULL) init_d->pathname = init_d->basename;
384 if (init_d->args == NULL) init_d->args = "";
385 if (init_d->pidfile == NULL) bb_xasprintf(&(init_d->pidfile), "/var/run/%s.pid", init_d->basename);
386 if (init_d->info == NULL) init_d->info = "";
387
388 if (command == NULL)
389 command = commands[2]; // Default to restart.
390
391 for (i = 0; commands[i] != 0; i++)
392 {
393 if (strcmp(commands[i], command ) == 0)
394 {
395 switch (i)
396 {
397 case 0 : status = (init_d->start)(init_d, 0); break;
398 case 1 : status = (init_d->stop)(init_d, 0); break;
399 case 2 : status = (init_d->restart)(init_d, 0); break;
400 case 3 : status = (init_d->try_restart)(init_d, 0); break;
401 case 4 : status = (init_d->reload)(init_d, 0); break;
402 case 5 : status = (init_d->force_reload)(init_d, 0); break;
403 case 6 : status = (init_d->status)(init_d, 1); break;
404 case 7 : status = (init_d->show_info)(init_d, 0); break;
405 }
406 break;
407 }
408 }
409
410 if (original_pidfile == NULL)
411 free(init_d->pidfile);
412 return status;
413}
414
415
416static int init_script(char *script, char *command)
417{
418 int status = INIT_D_ERROR_NOT_IMPLEMENTED;
419
420 bb_printf("%c%s %s ... ", toupper(command[0]), &command[1], script);
421 fflush(stdout);
422 doit(0, "/etc/init.d/%s %s", script, command);
423 status = errno;
424 if (strcmp("status", command) != 0)
425 {
426 bb_printf("\t\t");
427 switch (status)
428 {
429 case INIT_D_OK : bb_printf("OK"); break;
430 case INIT_D_ERROR_NOT_IMPLEMENTED : bb_printf("not implemented"); break;
431 case INIT_D_ERROR_NOT_INSTALLED : bb_printf("not installed"); break;
432 case INIT_D_ERROR_NOT_CONFIGURED : bb_printf("not configured"); break;
433 case INIT_D_ERROR_NOT_RUNNING : bb_printf("not running"); break;
434 case INIT_D_ERROR_GENERIC : bb_printf("failed"); break;
435 case INIT_D_ERROR_ARGS : bb_printf("invalid arguments"); break;
436 case INIT_D_ERROR_SECURITY : bb_printf("security failure"); break;
437 default : bb_printf("Failed!"); break;
438 }
439 bb_printf("\n");
440 }
441 return status;
442}
443
444
445init_d_info_t *parse_init_info(char *info_text, char *name)
446{
447 init_d_info_t *info = NULL;
448
449 // if init info found
450 if ((info_text != NULL) && (strncmp(info_text, INIT_D_BEGIN, strlen(INIT_D_BEGIN) - 1) == 0))
451 {
452 if (strncmp(info_text, INIT_D_BEGIN, strlen(INIT_D_BEGIN) - 1) == 0)
453 {
454 int lastfound = -1;
455 char *strtok_line;
456 char *line;
457 char *linecopy;
458
459 info = (init_d_info_t *) xcalloc(1, sizeof(init_d_info_t));
460 bb_xasprintf(&info->path, "%s", name);
461
462//bb_printf("%s is an init script -%s", name, info_text);
463//bb_printf("%s is an init script\n", name);
464 // parse info into structure
465 for (line = strtok_r(info_text, "\n\r", &strtok_line); line != NULL; line = strtok_r(NULL, "\n\r", &strtok_line))
466 {
467 int count = 0;
468 int found = -1;
469 char *strtok_token;
470 char *token;
471
472 bb_xasprintf(&linecopy, "%s", line);
473 for (token = strtok_r(line, " \t", &strtok_token); token != NULL; token = strtok_r(NULL, " \t", &strtok_token))
474 {
475 switch (count++)
476 {
477 case 0 : break; /* Ignore the "#". */
478
479 case 1 :
480 {
481 int j;
482 for (j = 1; INFOS[j] != NULL; j++)
483 {
484//bb_printf("%s = %s %s\n", linecopy, &(INFOS[j][1]), token);
485 if (strncmp(&(INFOS[j][1]), linecopy, strlen(&(INFOS[j][1])) - 1) == 0)
486 {
487 found = j - 1;
488 break;
489 }
490 }
491 break;
492 }
493
494 default :
495 {
496 int multi = 1;
497 int string = 1;
498 void **kludge = (void **)info;
499
500 switch (found)
501 {
502 case 5 : /* INIT_D_DSTART */ string = 0; break;
503 case 6 : /* INIT_D_DSTOP */ string = 0; break;
504 case 7 : /* INIT_D_SDESC */ multi = 0; break;
505 case 8 : /* INIT_D_DESC */ multi = 0; break;
506 case 10 : /* INIT_D_CONT */
507 case 11 : /* INIT_D_CONT2 */ multi = 0; found = lastfound; break;
508 case 12 : /* INIT_D_END */ found = -1; break;
509 }
510
511 if (found != -1)
512 {
513 void *temp = kludge[found];
514
515 if (multi == 1)
516 {
517 int size = info->sizes[found];
518
519 info->sizes[found]++;
520// not LSB, but SuSE does it
521if (token[0] == '$')
522 token = &token[1];
523// not LSB, but SuSE does it
524if (strncmp(token, "boot.", 5) == 0)
525 token = &token[5];
526 if (temp != NULL)
527 kludge[found] = xrealloc(kludge[found], sizeof (char **) * (size + 1));
528 else
529 kludge[found] = xcalloc(1, sizeof (char **));
530 if (string == 1)
531 bb_xasprintf(&((char **) kludge[found])[size], "%s", token);
532 else
533 {
534// not LSB, but SuSE does it
535if (token[0] == 'B')
536{
537 token[0] = '5';
538 kludge[found] = xrealloc(kludge[found], sizeof (char **) * (10 + 1));
539 ((int *) kludge[found])[0] = 1;
540 ((int *) kludge[found])[1] = 2;
541 ((int *) kludge[found])[2] = 3;
542 ((int *) kludge[found])[3] = 4;
543 size = 4;
544 info->sizes[found] = 5;
545}
546// not LSB, but SuSE does it
547if (token[0] == 'S')
548 token[0] = '1';
549 ((int *) kludge[found])[size] = atoi(token);
550 }
551 temp = NULL;
552 }
553 else
554 {
555 if (string == 1)
556 {
557 if (kludge[found] == NULL)
558 bb_xasprintf((char **) &kludge[found], "%s", token);
559 else
560 bb_xasprintf((char **) &kludge[found], "%s %s", (char *) kludge[found], token);
561 }
562 else
563 {
564// Should never happen. int value = atoi(token);
565 temp = NULL;
566 }
567 }
568
569 if (temp != NULL)
570 free(temp);
571 }
572 lastfound = found;
573
574 break;
575 }
576 }
577 }
578 }
579
580
581#if 0
582{
583 int k;
584
585 bb_printf("SCRIPT %s path %s\n", name, info->path);
586// bb_printf("%s sizes ", name);
587// for(k = 0; k < 10; k++)
588// bb_printf("%d ", info->sizes[k]);
589// bb_printf("\n");
590 if (info->provides != NULL)
591 {
592 bb_printf("%s provides ", name);
593 for(k = 0; k < info->sizes[0]; k++)
594 bb_printf("%s ", info->provides[k]);
595 bb_printf("\n");
596 }
597 if (info->reqstart != NULL)
598 {
599 bb_printf("%s reqstart ", name);
600 for(k = 0; k < info->sizes[1]; k++)
601 bb_printf("%s ", info->reqstart[k]);
602 bb_printf("\n");
603 }
604 if (info->reqstop != NULL)
605 {
606 bb_printf("%s reqstop ", name);
607 for(k = 0; k < info->sizes[2]; k++)
608 bb_printf("%s ", info->reqstop[k]);
609 bb_printf("\n");
610 }
611
612 if (info->shouldstart != NULL)
613 {
614 bb_printf("%s shouldstart ", name);
615 for(k = 0; k < info->sizes[3]; k++)
616 bb_printf("%s ", info->shouldstart[k]);
617 bb_printf("\n");
618 }
619 if (info->shouldstop != NULL)
620 {
621 bb_printf("%s shouldstop ", name);
622 for(k = 0; k < info->sizes[4]; k++)
623 bb_printf("%s ", info->shouldstop[k]);
624 bb_printf("\n");
625 }
626
627 if (info->defstart != NULL)
628 {
629 bb_printf("%s defstart ", name);
630 for(k = 0; k < info->sizes[5]; k++)
631 bb_printf("%d ", info->defstart[k]);
632 bb_printf("\n");
633 }
634 if (info->defstop != NULL)
635 {
636 bb_printf("%s defstop ", name);
637 for(k = 0; k < info->sizes[6]; k++)
638 bb_printf("%d ", info->defstop[k]);
639 bb_printf("\n");
640 }
641 if (info->shortdesc != NULL)
642 bb_printf("%s shortdes %s\n", name, info->shortdesc);
643 if (info->desc != NULL)
644 bb_printf("%s descript %s\n", name, info->desc);
645 bb_printf("\n");
646}
647#endif
648
649 // if database of runlevels per script includes overrides
650 // change info structure accordingly
651 }
652 }
653
654 return info;
655}
656
657
658char *get_init_info(char *pathname)
659{
660 struct stat script_stat;
661 char *info_text = NULL;
662 char *base_name = bb_get_last_path_component(pathname);
663
664
665//bb_printf("CHECKING %s, ", pathname);
666 // ignore rc, rcS, directories, non executables
667 if ((strcmp(base_name, "rc") != 0) &&
668 (strcmp(base_name, "rcS") != 0) &&
669 (stat(pathname, &script_stat) == 0))
670 {
671 if ((!S_ISDIR(script_stat.st_mode)) &&
672 S_ISREG(script_stat.st_mode) &&
673 ((script_stat.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0 ))
674 {
675//bb_printf("maybe init script, ");
676 // script info
677 if ((info_text == NULL) || (strncmp(info_text, INIT_D_BEGIN, strlen(INIT_D_BEGIN) - 1) != 0))
678 bb_xasprintf(&info_text, "%s", doit(REDIR | QUIET, "%s info", pathname));
679//bb_printf("INFO = %s\n", info_text);
680
681 // if not proper response
682 if ((info_text == NULL) || (strncmp(info_text, INIT_D_BEGIN, strlen(INIT_D_BEGIN) - 1) != 0))
683 {
684 int count = 1;
685 int found = -1;
686 char *line;
687 FILE *contents;
688
689//bb_printf("search for INFO, ");
690 // search script for init info
691 info_text = (char *) xmalloc(sizeof (char) * 256 * 64);
692 info_text[0] = '\n';
693 info_text[1] = '\0';
694 contents = fopen(pathname, "r");
695 if (contents != NULL)
696 {
697 do
698 {
699 line = fgets(&info_text[count], 255, contents);
700 if (line != NULL)
701 {
702 line--;
703 if ((found == -1) && (strncmp(line, INIT_D_BEGIN, strlen(INIT_D_BEGIN) - 1) == 0))
704 found = 0;
705
706 if (found != -1)
707 {
708
709 if (strncmp(line, INIT_D_CUSTOM, strlen(INIT_D_CUSTOM)) != 0)
710 {
711 if (strncmp(line, INIT_D_END, strlen(INIT_D_END) - 1) == 0)
712 {
713//bb_printf("INFO found, ");
714 line = NULL;
715 found = 64 + 1;
716 }
717 else
718 {
719 int cont = 0;
720
721 if (strncmp(line, INIT_D_CONT, strlen(INIT_D_CONT)) == 0)
722 cont = 1;
723 if (strncmp(line, INIT_D_CONT2, strlen(INIT_D_CONT2)) == 0)
724 cont = 1;
725 if (cont == 1)
726 {
727//bb_printf("\n\n\nCONT found%s\n\n\n, ", line);
728 info_text[count - 1] = ' ';
729 info_text[count] = ' ';
730 }
731
732 found++;
733 count += strlen(line) - 1;
734 if (info_text[count - 1] != '\n')
735 {
736 info_text[count++] = '\n';
737// Should seek until the next \n,
738 }
739 }
740 info_text[count] = '\0';
741 }
742 }
743 }
744 } while ((line != NULL) && (found < 64));
745
746 fclose(contents);
747 }
748 }
749 }
750 }
751//bb_printf("\n");
752
753 return info_text;
754}
755
756
757llist_t *get_scripts(void)
758{
759 llist_t *result = NULL;
760 DIR *initd = opendir("/etc/init.d");
761
762 if (initd != NULL)
763 {
764 struct dirent *script;
765
766 // foreach ls /etc/init.d
767 while ((script = readdir(initd)) != NULL)
768 {
769 char *info_text = NULL;
770 char *pathname = NULL;
771 init_d_info_t *info = NULL;
772
773 bb_xasprintf(&pathname, "/etc/init.d/%s", script->d_name);
774 info_text = get_init_info(pathname);
775 info = parse_init_info(info_text, script->d_name);
776 if (info)
777 result = llist_add_to(result, (char *) info);
778
779 free(info_text);
780 }
781 closedir(initd);
782 }
783
784 return result;
785}
786
787
788llist_t *sort_scripts(llist_t *unsorted)
789{
790// Should do something with info->shouldstart's
791 int count_moves = 0;
792 // all scripts start in unsorted list
793 llist_t *sorted = NULL;
794 llist_t *current = unsorted;
795 llist_t *previous = NULL;
796
797 // pull out those with no deps and create a sorted list for each
798 while (current)
799 {
800 init_d_info_t *info = (init_d_info_t *) current->data;
801
802 if (info->reqstart == NULL)
803 {
804 llist_t *new_list = NULL;
805 new_list = llist_add_to_end(new_list, (char *) info);
806 sorted = llist_add_to_end(sorted, (char *) new_list);
807 current = llist_delete(&unsorted, previous, current);
808 }
809 else
810 {
811 previous = current;
812 current = current->link;
813 }
814 }
815
816 do
817 {
818 count_moves = 0;
819 current = unsorted;
820 previous = NULL;
821 // foreach in unsorted list
822 while (current)
823 {
824 int moved = 0;
825 init_d_info_t *info = (init_d_info_t *) current->data;
826
827 if (info->reqstart != NULL)
828 {
829 int k;
830 llist_t *current_sort = sorted;
831 short done[info->sizes[1]];
832
833 // foreach sorted list
834 while (current_sort)
835 {
836 llist_t *current_list = (llist_t *) current_sort->data;
837
838 // if ALL deps are in sorted list move script to end of sorted list
839 for(k = 0; k < info->sizes[1]; k++)
840 done[k] = 0;
841 while (current_list)
842 {
843 init_d_info_t *this_info = (init_d_info_t *) current_list->data;
844
845 for(k = 0; k < info->sizes[1]; k++)
846 {
847 int i;
848 char *needs = info->reqstart[k];
849
850 if (done[k] == 0)
851 {
852//bb_printf("%s NEEDS %s - ", info->path, needs);
853 for(i = 0; i < this_info->sizes[0]; i++)
854 {
855//bb_printf("%s ", this_info->provides[i]);
856 if (strcmp(this_info->provides[i], needs) == 0)
857 {
858 done[k] = 1;
859 break;
860 }
861 }
862//bb_printf("\n");
863 }
864 }
865 current_list = current_list->link;
866 }
867
868 moved = 1;
869 for(k = 0; k < info->sizes[1]; k++)
870 {
871 if (done[k] == 0)
872 {
873 moved = 0;
874 break;
875 }
876 }
877 if (moved == 1)
878 {
879 llist_t *list = (llist_t *) current_sort->data;
880 llist_add_to_end(list, (char *) info);
881 current = llist_delete(&unsorted, previous, current);
882 moved = 1;
883 count_moves++;
884 current_sort = NULL;
885 }
886 else
887 current_sort = current_sort->link;
888 }
889 }
890
891 if (moved == 0)
892 {
893 previous = current;
894 current = current->link;
895 }
896 }
897 } while (count_moves != 0);
898 // until no more moves happen
899
900
901 do
902 {
903 count_moves = 0;
904 current = unsorted;
905 previous = NULL;
906 // foreach in unsorted list
907 while (current)
908 {
909 int moved = 1;
910 init_d_info_t *info = (init_d_info_t *) current->data;
911 short done[info->sizes[1]];
912
913 if (info->reqstart != NULL)
914 {
915 int k;
916 llist_t *current_sortof = sorted;
917
918 // if ALL deps are in sorted lists
919 for(k = 0; k < info->sizes[1]; k++)
920 done[k] = 0;
921 while ((moved == 1) && (current_sortof != NULL))
922 {
923 llist_t *current_listof = (llist_t *) current_sortof->data;
924
925 while (current_listof)
926 {
927 init_d_info_t *this_info = (init_d_info_t *) current_listof->data;
928
929 for(k = 0; k < info->sizes[1]; k++)
930 {
931 int i;
932 char *needs = info->reqstart[k];
933
934 if (done[k] == 0)
935 {
936//bb_printf("%s NEEDS %s - ", info->path, needs);
937 for(i = 0; i < this_info->sizes[0]; i++)
938 {
939//bb_printf("%s ", this_info->provides[i]);
940 if (strcmp(this_info->provides[i], needs) == 0)
941 {
942 done[k] = 1;
943 break;
944 }
945 }
946//bb_printf("\n");
947 }
948 }
949 current_listof = current_listof->link;
950 }
951 current_sortof = current_sortof->link;
952 }
953
954 moved = 1;
955 for(k = 0; k < info->sizes[1]; k++)
956 {
957 if (done[k] == 0)
958 {
959 moved = 0;
960 break;
961 }
962 }
963
964 if (moved == 1)
965 {
966 // create a merged list for script
967 llist_t *current_sort = sorted;
968 llist_t *new_list = NULL;
969 new_list = llist_add_to_end(new_list, (char *) info);
970 count_moves++;
971
972 // foreach sorted | merged list
973 while (current_sort)
974 {
975 int found = 0;
976 llist_t *current_list = (llist_t *) current_sort->data;
977
978 // if A dep is in s|m add s|m to end of new merged list & continue with next s|m
979 while (current_list)
980 {
981 init_d_info_t *this_info = (init_d_info_t *) current_list->data;
982
983 for(k = 0; k < info->sizes[1]; k++)
984 {
985 int i;
986 char *needs = info->reqstart[k];
987
988 for(i = 0; i < this_info->sizes[0]; i++)
989 {
990 if (strcmp(this_info->provides[i], needs) == 0)
991 {
992 found = 1;
993 break;
994 }
995 }
996 if (found == 1)
997 break;
998 }
999 if (found == 1)
1000 {
1001 init_d_info_t *new_info = (init_d_info_t *) xcalloc(1, sizeof(init_d_info_t));
1002 new_info->start = current_sort;
1003 new_list = llist_add_to_end(new_list, (char *) new_info);
1004 current_list = NULL;
1005 }
1006 else
1007 current_list = current_list->link;
1008 }
1009
1010 current_sort = current_sort->link;
1011 }
1012
1013 sorted = llist_add_to_end(sorted, (char *) new_list);
1014 current = llist_delete(&unsorted, previous, current);
1015 }
1016 }
1017
1018 if (moved == 0)
1019 {
1020 previous = current;
1021 current = current->link;
1022 }
1023 }
1024 } while (count_moves != 0);
1025 // until no more creates happen
1026
1027
1028 // unsorted list now contains unsatisfied and circular dependencies
1029 // complain if not empty.
1030 if (unsorted != NULL)
1031 {
1032 bb_printf("\nWARNING, the following init scripts have unresolved or circular dependencies -\n");
1033 current = unsorted;
1034
1035 while (current)
1036 {
1037 init_d_info_t *info = (init_d_info_t *) current->data;
1038
1039 bb_printf("%s\n", info->path);
1040 current = current->link;
1041#if 0
1042{
1043 int k;
1044
1045 bb_printf("SCRIPT %s - ", info->path);
1046 if (info->defstart != NULL)
1047 {
1048 bb_printf("\t\t ");
1049 for(k = 0; k < info->sizes[5]; k++)
1050 bb_printf("%d ", info->defstart[k]);
1051// bb_printf("\n");
1052 }
1053 if (info->provides != NULL)
1054 {
1055 bb_printf("\t\t ");
1056 for(k = 0; k < info->sizes[0]; k++)
1057 bb_printf("%s ", info->provides[k]);
1058// bb_printf("\n");
1059 }
1060 if (info->reqstart != NULL)
1061 {
1062 bb_printf("\n\t ");
1063 for(k = 0; k < info->sizes[1]; k++)
1064 bb_printf("%s ", info->reqstart[k]);
1065// bb_printf("\n");
1066 }
1067 bb_printf("\n");
1068}
1069#endif
1070 }
1071 bb_printf("\n");
1072 }
1073
1074 return sorted;
1075}
1076
1077
1078static void call_scripts(llist_t *sorted, char *command, int oldlevel, int level)
1079{
1080 // call init_script(script, command) for each script in each list in created order
1081 llist_t *current_sort = sorted;
1082
1083 while (current_sort)
1084 {
1085 llist_t *current_list = (llist_t *) current_sort->data;
1086
1087//bb_printf("\nLIST\n");
1088 while (current_list)
1089 {
1090 init_d_info_t *info = (init_d_info_t *) current_list->data;
1091
1092 if (info->path != NULL)
1093 {
1094 if (info->defstart != NULL)
1095 {
1096 int k;
1097 int found = 0;
1098
1099 // if info->DefaultStart includes level
1100 for(k = 0; k < info->sizes[5]; k++)
1101 {
1102 if (info->defstart[k] == level)
1103 {
1104 found = 1;
1105 break;
1106 }
1107 }
1108 // if info->DefaultStart does not include previous level
1109 for(k = 0; k < info->sizes[5]; k++)
1110 {
1111 if (info->defstart[k] == oldlevel)
1112 {
1113 found = 0;
1114 break;
1115 }
1116 }
1117 // add info structure to list
1118 if (found == 1)
1119 init_script(info->path, command);
1120 }
1121
1122#if 0
1123{
1124 int k;
1125
1126 bb_printf("SCRIPT %s - ", info->path);
1127 if (info->defstart != NULL)
1128 {
1129 bb_printf("\t\t ");
1130 for(k = 0; k < info->sizes[5]; k++)
1131 bb_printf("%d ", info->defstart[k]);
1132// bb_printf("\n");
1133 }
1134 if (info->provides != NULL)
1135 {
1136 bb_printf("\t\t ");
1137 for(k = 0; k < info->sizes[0]; k++)
1138 bb_printf("%s ", info->provides[k]);
1139// bb_printf("\n");
1140 }
1141 if (info->reqstart != NULL)
1142 {
1143 bb_printf("\n\t ");
1144 for(k = 0; k < info->sizes[1]; k++)
1145 bb_printf("%s ", info->reqstart[k]);
1146// bb_printf("\n");
1147 }
1148 bb_printf("\n");
1149}
1150#endif
1151 }
1152 current_list = current_list->link;
1153 }
1154 current_sort = current_sort->link;
1155 }
1156}
1157
1158
1159int run_level(char *level)
1160{
1161 int oldlevel = 0;
1162 int newlevel = atoi(level);
1163 char *temp;
1164 llist_t *sorted = NULL;
1165 llist_t *reversed = NULL;
1166 llist_t *current_sort = NULL;
1167
1168 bb_printf("\n\nSwitching to run level %d", newlevel);
1169
1170 // get previous run level
1171 temp = quick_read("/var/lib/misc/runlevel");
1172 if (temp != NULL)
1173 {
1174 oldlevel = atoi(temp);
1175 if (oldlevel < 0)
1176 oldlevel = 1;
1177 if (oldlevel > 6)
1178 oldlevel = 5;
1179 bb_printf(" from run level %d", oldlevel);
1180 free(temp);
1181 }
1182 bb_printf(".\n\n");
1183
1184 // get scripts and sort dependencies, careful with circular dependencies
1185 sorted = sort_scripts(get_scripts());
1186
1187 // reverse
1188 current_sort = sorted;
1189 while (current_sort)
1190 {
1191 llist_t *current_list = (llist_t *) current_sort->data;
1192 llist_t *new_list = NULL;
1193
1194 while (current_list)
1195 {
1196 new_list = llist_add_to(new_list, current_list->data);
1197 current_list = current_list->link;
1198 }
1199 reversed = llist_add_to(reversed, (char *) new_list);
1200 current_sort = current_sort->link;
1201 }
1202
1203 // call "stop" for each script
1204 bb_printf("\n");
1205 call_scripts(reversed, "stop", newlevel, oldlevel);
1206
1207 // call "start" for each script
1208 bb_printf("\n");
1209 call_scripts(sorted, "start", oldlevel, newlevel);
1210// free all infos
1211
1212 // set previous run level to new run level
1213 quick_write("/var/lib/misc/runlevel", "%d", newlevel);
1214
1215
1216// Later, optionally call them in parallel when possible.
1217
1218
1219// Later, add a database of runlevels per script and allow editing them -
1220// rc network --runlevels 3 4 5
1221// cat /etc/runlevels.conf
1222// runlevel="3"
1223// runlevel3="multi user with network."
1224// runlevel4="multi user with network and twin."
1225// runlevel5="multi user with network and X."
1226// local_fs="1 2 3 4 5"
1227// network="3 4 5"
1228// script1="2 3 5"
1229// script1="3 5"
1230// rc network --runlevels
1231// 3 4 5
1232// rc network --runlevels -v
1233// The "network" service will be active during these run levels :
1234// 3 - multi user with network.
1235// 4 - multi user with network and twin.
1236// 5 - multi user with network and X.
1237
1238 return EXIT_SUCCESS;
1239}
1240
1241
1242/*
1243 * rc
1244 * rc 1
1245 * rc network start
1246 * rc network --runlevels
1247 * rc network --runlevels -v
1248 * rc network --runlevels 3 4 5
1249 */
1250
1251int rc_main(int argc, char **argv)
1252{
1253 switch (argc)
1254 {
1255 case 0 :
1256 case 1 :
1257 {
1258 return run_level(quick_read("/etc/runlevel"));
1259 }
1260 case 2 : return run_level(argv[1]);
1261 case 3 :
1262 {
1263// Should take care of dependencies for argv[1] script.
1264 return init_script(argv[1], argv[2]);
1265 }
1266 default :
1267 {
1268 return INIT_D_ERROR_NOT_IMPLEMENTED;
1269 }
1270 }
1271}
diff --git a/urunlevel/runlevel/remote_fs.c b/urunlevel/runlevel/remote_fs.c
new file mode 100644
index 0000000..6da11f5
--- /dev/null
+++ b/urunlevel/runlevel/remote_fs.c
@@ -0,0 +1,83 @@
1/*
2 * Mini remote_fs boot implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27
28
29static int start(struct init_d_handle_s *, int);
30static int status(struct init_d_handle_s *, int);
31static int stop(struct init_d_handle_s *, int);
32
33
34static init_d_handle_t my_commands =
35{
36 &start,
37 &stop,
38 NULL,
39 NULL,
40 &no_reload,
41 NULL,
42 &status,
43 NULL,
44 "remote_fs",
45 NULL,
46 NULL,
47 NULL,
48 INIT_D_BEGIN \
49 INIT_D_PROV "$remote_fs" \
50 INIT_D_RSTART "$network" \
51 INIT_D_SSTART "nfs smbfs codafs" \
52 INIT_D_DSTART "3 4 5" \
53 INIT_D_DSTOP "0 1 2 6" \
54 INIT_D_SDESC "Mount all remote file systems." \
55 INIT_D_DESC "Mount all remote file systems. Actually, this is just a" \
56 INIT_D_CONT "dummy that depends on all the init scripts that could" \
57 INIT_D_CONT "possibly mount remote file systems." \
58 INIT_D_END
59};
60
61
62int remote_fs_main(int argc, char **argv)
63{
64 return do_init_from_main(argc, argv, &my_commands);
65}
66
67
68static int start(struct init_d_handle_s *init_d, int just_checking)
69{
70 return INIT_D_OK;
71}
72
73
74static int status(struct init_d_handle_s *init_d, int quiet)
75{
76 return print_status(init_d, quiet, INIT_D_STATUS_OK);
77}
78
79
80static int stop(struct init_d_handle_s *init_d, int just_checking)
81{
82 return INIT_D_OK;
83}
diff --git a/urunlevel/runlevel/remove_initd.c b/urunlevel/runlevel/remove_initd.c
new file mode 100644
index 0000000..1224b03
--- /dev/null
+++ b/urunlevel/runlevel/remove_initd.c
@@ -0,0 +1,38 @@
1/*
2 * Mini remove_initd implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <unistd.h>
24
25#include "busybox.h"
26#include "lib_init_d.h"
27
28
29int remove_initd_main(int argc, char **argv)
30{
31 llist_t *sorted = NULL;
32 llist_t *unsorted = get_scripts();
33
34// Should remove this script from unsorted.
35 sorted = sort_scripts(unsorted);
36// Should return 1 if there are unsatisfied dependencies if this is removed.
37 return EXIT_SUCCESS;
38}
diff --git a/urunlevel/runlevel/skeleton b/urunlevel/runlevel/skeleton
new file mode 100755
index 0000000..cbd8b0e
--- /dev/null
+++ b/urunlevel/runlevel/skeleton
@@ -0,0 +1,282 @@
1#! /bin/sh
2# Copyright (c) 1995-2004 SUSE Linux AG, Nuernberg, Germany.
3# All rights reserved.
4#
5# Author: Kurt Garloff
6# Please send feedback to http://www.suse.de/feedback/
7#
8# /etc/init.d/FOO
9# and its symbolic link
10# /(usr/)sbin/rcFOO
11#
12# This program is free software; you can redistribute it and/or modify
13# it under the terms of the GNU General Public License as published by
14# the Free Software Foundation; either version 2 of the License, or
15# (at your option) any later version.
16#
17# This program is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20# GNU General Public License for more details.
21#
22# You should have received a copy of the GNU General Public License
23# along with this program; if not, write to the Free Software
24# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25#
26# Template system startup script for some example service/daemon FOO
27#
28# LSB compatible service control script; see http://www.linuxbase.org/spec/
29#
30# Note: This template uses functions rc_XXX defined in /etc/rc.status on
31# UnitedLinux (UL) based Linux distributions. If you want to base your
32# script on this template and ensure that it works on non UL based LSB
33# compliant Linux distributions, you either have to provide the rc.status
34# functions from UL or change the script to work without them.
35#
36### BEGIN INIT INFO
37# Provides: FOO
38# Required-Start: $syslog $remote_fs
39# Should-Start: $time ypbind sendmail
40# Required-Stop: $syslog $remote_fs
41# Should-Stop: $time ypbind sendmail
42# Default-Start: 3 5
43# Default-Stop: 0 1 2 6
44# Short-Description: FOO XYZ daemon providing ZYX
45# Description: Start FOO to allow XY and provide YZ
46# continued on second line by '#<TAB>'
47# should contain enough info for the runlevel editor
48# to give admin some idea what this service does and
49# what it's needed for ...
50# (The Short-Description should already be a good hint.)
51### END INIT INFO
52#
53# Any extensions to the keywords given above should be preceeded by
54# X-VendorTag- (X-UnitedLinux- X-SuSE- for us) according to LSB.
55#
56# Notes on Required-Start/Should-Start:
57# * There are two different issues that are solved by Required-Start
58# and Should-Start
59# (a) Hard dependencies: This is used by the runlevel editor to determine
60# which services absolutely need to be started to make the start of
61# this service make sense. Example: nfsserver should have
62# Required-Start: $portmap
63# Also, required services are started before the dependent ones.
64# The runlevel editor will warn about such missing hard dependencies
65# and suggest enabling. During system startup, you may expect an error,
66# if the dependency is not fulfilled.
67# (b) Specifying the init script ordering, not real (hard) dependencies.
68# This is needed by insserv to determine which service should be
69# started first (and at a later stage what services can be started
70# in parallel). The tag Should-Start: is used for this.
71# It tells, that if a service is available, it should be started
72# before. If not, never mind.
73# * When specifying hard dependencies or ordering requirements, you can
74# use names of services (contents of their Provides: section)
75# or pseudo names starting with a $. The following ones are available
76# according to LSB (1.1):
77# $local_fs all local file systems are mounted
78# (most services should need this!)
79# $remote_fs all remote file systems are mounted
80# (note that /usr may be remote, so
81# many services should Require this!)
82# $syslog system logging facility up
83# $network low level networking (eth card, ...)
84# $named hostname resolution available
85# $netdaemons all network daemons are running
86# The $netdaemons pseudo service has been removed in LSB 1.2.
87# For now, we still offer it for backward compatibility.
88# These are new (LSB 1.2):
89# $time the system time has been set correctly
90# $portmap SunRPC portmapping service available
91# UnitedLinux extensions:
92# $ALL indicates that a script should be inserted
93# at the end
94# * The services specified in the stop tags
95# (Required-Stop/Should-Stop)
96# specify which services need to be still running when this service
97# is shut down. Often the entries there are just copies or a subset
98# from the respective start tag.
99# * Should-Start/Stop are now part of LSB as of 2.0,
100# formerly SUSE/Unitedlinux used X-UnitedLinux-Should-Start/-Stop.
101# insserv does support both variants.
102# * X-UnitedLinux-Default-Enabled: yes/no is used at installation time
103# (%fillup_and_insserv macro in %post of many RPMs) to specify whether
104# a startup script should default to be enabled after installation.
105# It's not used by insserv.
106#
107# Note on runlevels:
108# 0 - halt/poweroff 6 - reboot
109# 1 - single user 2 - multiuser without network exported
110# 3 - multiuser w/ network (text mode) 5 - multiuser w/ network and X11 (xdm)
111#
112# Note on script names:
113# http://www.linuxbase.org/spec/refspecs/LSB_1.3.0/gLSB/gLSB/scrptnames.html
114# A registry has been set up to manage the init script namespace.
115# http://www.lanana.org/
116# Please use the names already registered or register one or use a
117# vendor prefix.
118
119
120# Check for missing binaries (stale symlinks should not happen)
121# Note: Special treatment of stop for LSB conformance
122FOO_BIN=/usr/sbin/FOO
123test -x $FOO_BIN || { echo "$FOO_BIN not installed";
124 if [ "$1" = "stop" ]; then exit 0;
125 else exit 5; fi; }
126
127# Check for existence of needed config file and read it
128FOO_CONFIG=/etc/sysconfig/FOO
129test -r $FOO_CONFIG || { echo "$FOO_CONFIG not existing";
130 if [ "$1" = "stop" ]; then exit 0;
131 else exit 6; fi; }
132
133# Read config
134. $FOO_CONFIG
135
136# Source LSB init functions
137# providing start_daemon, killproc, pidofproc,
138# log_success_msg, log_failure_msg and log_warning_msg.
139# This is currently not used by UnitedLinux based distributions and
140# not needed for init scripts for UnitedLinux only. If it is used,
141# the functions from rc.status should not be sourced or used.
142#. /lib/lsb/init-functions
143
144# Shell functions sourced from /etc/rc.status:
145# rc_check check and set local and overall rc status
146# rc_status check and set local and overall rc status
147# rc_status -v be verbose in local rc status and clear it afterwards
148# rc_status -v -r ditto and clear both the local and overall rc status
149# rc_status -s display "skipped" and exit with status 3
150# rc_status -u display "unused" and exit with status 3
151# rc_failed set local and overall rc status to failed
152# rc_failed <num> set local and overall rc status to <num>
153# rc_reset clear both the local and overall rc status
154# rc_exit exit appropriate to overall rc status
155# rc_active checks whether a service is activated by symlinks
156. /etc/rc.status
157
158# Reset status of this service
159rc_reset
160
161# Return values acc. to LSB for all commands but status:
162# 0 - success
163# 1 - generic or unspecified error
164# 2 - invalid or excess argument(s)
165# 3 - unimplemented feature (e.g. "reload")
166# 4 - user had insufficient privileges
167# 5 - program is not installed
168# 6 - program is not configured
169# 7 - program is not running
170# 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
171#
172# Note that starting an already running service, stopping
173# or restarting a not-running service as well as the restart
174# with force-reload (in case signaling is not supported) are
175# considered a success.
176
177case "$1" in
178 start)
179 echo -n "Starting FOO "
180 ## Start daemon with startproc(8). If this fails
181 ## the return value is set appropriately by startproc.
182 startproc $FOO_BIN
183
184 # Remember status and be verbose
185 rc_status -v
186 ;;
187 stop)
188 echo -n "Shutting down FOO "
189 ## Stop daemon with killproc(8) and if this fails
190 ## killproc sets the return value according to LSB.
191
192 killproc -TERM $FOO_BIN
193
194 # Remember status and be verbose
195 rc_status -v
196 ;;
197 try-restart|condrestart)
198 ## Do a restart only if the service was active before.
199 ## Note: try-restart is now part of LSB (as of 1.9).
200 ## RH has a similar command named condrestart.
201 if test "$1" = "condrestart"; then
202 echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
203 fi
204 $0 status
205 if test $? = 0; then
206 $0 restart
207 else
208 rc_reset # Not running is not a failure.
209 fi
210 # Remember status and be quiet
211 rc_status
212 ;;
213 restart)
214 ## Stop the service and regardless of whether it was
215 ## running or not, start it again.
216 $0 stop
217 $0 start
218
219 # Remember status and be quiet
220 rc_status
221 ;;
222 force-reload)
223 ## Signal the daemon to reload its config. Most daemons
224 ## do this on signal 1 (SIGHUP).
225 ## If it does not support it, restart.
226
227 echo -n "Reload service FOO "
228 ## if it supports it:
229 killproc -HUP $FOO_BIN
230 #touch /var/run/FOO.pid
231 rc_status -v
232
233 ## Otherwise:
234 #$0 try-restart
235 #rc_status
236 ;;
237 reload)
238 ## Like force-reload, but if daemon does not support
239 ## signaling, do nothing (!)
240
241 # If it supports signaling:
242 echo -n "Reload service FOO "
243 killproc -HUP $FOO_BIN
244 #touch /var/run/FOO.pid
245 rc_status -v
246
247 ## Otherwise if it does not support reload:
248 #rc_failed 3
249 #rc_status -v
250 ;;
251 status)
252 echo -n "Checking for service FOO "
253 ## Check status with checkproc(8), if process is running
254 ## checkproc will return with exit status 0.
255
256 # Return value is slightly different for the status command:
257 # 0 - service up and running
258 # 1 - service dead, but /var/run/ pid file exists
259 # 2 - service dead, but /var/lock/ lock file exists
260 # 3 - service not running (unused)
261 # 4 - service status unknown :-(
262 # 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
263
264 # NOTE: checkproc returns LSB compliant status values.
265 checkproc $FOO_BIN
266 # NOTE: rc_status knows that we called this init script with
267 # "status" option and adapts its messages accordingly.
268 rc_status -v
269 ;;
270 probe)
271 ## Optional: Probe for the necessity of a reload, print out the
272 ## argument to this init script which is required for a reload.
273 ## Note: probe is not (yet) part of LSB (as of 1.9)
274
275 test /etc/FOO/FOO.conf -nt /var/run/FOO.pid && echo reload
276 ;;
277 *)
278 echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
279 exit 1
280 ;;
281esac
282rc_exit
diff --git a/urunlevel/runlevel/start_daemon.c b/urunlevel/runlevel/start_daemon.c
new file mode 100644
index 0000000..ba922fa
--- /dev/null
+++ b/urunlevel/runlevel/start_daemon.c
@@ -0,0 +1,153 @@
1/*
2 * Mini start_daemon implementation for busybox.
3 *
4 * Copyright (C) 2005 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <errno.h>
24#include <getopt.h>
25#include <string.h>
26#include <sys/time.h>
27#include <sys/resource.h>
28#include <unistd.h>
29
30#include "busybox.h"
31#include "lib_init_d.h"
32
33
34int start_daemon(int force, int nice_level, char *pidfile, char *pathname, char *args)
35{
36 int status = 0;
37 status = pidofproc(pidfile, pathname, NULL);
38
39 if ((status != INIT_D_STATUS_OK) || (force))
40 {
41 char *pids = NULL;
42 char *strtok_temp;
43
44 doit(DAEMON, "start-stop-daemon -Sbmp %s -x %s -- %s", pidfile, pathname, args);
45sleep(1);
46 status = pidofproc(pidfile, pathname, &pids);
47 if ((status == INIT_D_STATUS_OK) && (nice_level))
48 {
49 int i;
50 char *pid;
51
52 pid = strtok_r(pids, " ", &strtok_temp);
53 for (i = 0; pid != NULL; i++)
54 {
55 int ps = atoi(pid);
56 int oldp;
57
58 errno = 0;
59 oldp = getpriority(PRIO_PROCESS, ps);
60 if (errno == 0)
61 setpriority(PRIO_PROCESS, ps, oldp + nice_level);
62 pid = strtok_r(NULL, " ", &strtok_temp);
63 }
64 }
65 }
66
67 return status;
68}
69
70
71/*
72start_daemon [-f] [-n nicelevel] [-p pidfile] pathname [args]
73 This runs the specified program as a daemon.
74 start_daemon shall check if the program is already running
75 using the algorithm given above. If so, it shall not
76 start another copy of the daemon unless the -f
77 option is given. The -n option specifies a nice
78 level. See nice(1).
79
80 start_daemon should return the LSB defined exit status codes. It
81 shall return 0 if the program has been successfully started or
82 is running and not 0 otherwise.
83*/
84
85
86int start_daemon_main(int argc, char **argv)
87{
88 int result = EXIT_FAILURE;
89 int force = 0;
90 int nice_level = 0;
91 char *pidfile = NULL;
92 char *pathname = NULL;
93 char *args = NULL;
94 int i;
95
96 for (i = 1; i < argc; i++)
97 {
98 char *p = argv[i];
99
100 if (*p == '-')
101 {
102 while (*(++p))
103 {
104 switch (*p)
105 {
106 case 'f' :
107 force = 1;
108 break;
109
110 case 'n' :
111 if ((++i) < argc)
112 nice_level = atoi(argv[i]);
113 else
114 bb_show_usage();
115 break;
116
117 case 'p' :
118 if ((++i) < argc)
119 pidfile = argv[i];
120 else
121 bb_show_usage();
122 break;
123
124 default:
125 bb_show_usage();
126 }
127 }
128 }
129 else if (pathname == NULL)
130 {
131 pathname = p;
132 break;
133 }
134 else
135 bb_show_usage();
136 }
137
138 if (pathname == NULL)
139 bb_show_usage();
140
141 if (i < argc)
142 args = argv_cat(argc - i, &argv[i]);
143
144//bb_printf("ARGS - |%s|%s|%d|%d|%s\n", pidfile, pathname, force, nice_level, args);
145 result = start_daemon(force, nice_level, pidfile, pathname, args);
146
147 if (args != NULL)
148 free(args);
149
150 return result;
151}
152
153
diff --git a/urunlevel/runlevel/udhcpc_script.c b/urunlevel/runlevel/udhcpc_script.c
new file mode 100644
index 0000000..5d5f592
--- /dev/null
+++ b/urunlevel/runlevel/udhcpc_script.c
@@ -0,0 +1,191 @@
1/*
2 * Mini udhcpc_script implementation for busybox.
3 *
4 * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 */
22
23#include <errno.h>
24#include <string.h>
25#include <unistd.h>
26
27#include "busybox.h"
28#include "lib_init_d.h"
29
30
31static void printit(char *name, char *description, char *value)
32{
33 if (value != NULL)
34 bb_printf("%s=%s\t\t- %s\n", name, value, description);
35}
36
37int udhcpc_script_main(int argc, char **argv)
38{
39 argv += optind;
40
41#if 0
42 printit("action", "What action the script should perform", *argv);
43 printit("HOME", "The set $HOME env or '/'", getenv("HOME"));
44 printit("PATH", "the set $PATH env or '/bin:/usr/bin:/sbin:/usr/sbin'", getenv("PATH"));
45 printit("interface", "The interface this was obtained on", getenv("interface"));
46 printit("ip", "The obtained IP", getenv("ip"));
47 printit("mask", "The number of bits in the netmask (ie: 24)", getenv("mask"));
48 printit("siaddr", "The bootp next server option", getenv("siaddr"));
49 printit("sname", "The bootp server name option", getenv("sname"));
50 printit("boot_file", "The bootp boot file option", getenv("boot_file"));
51 printit("subnet", "The assigend subnet mask", getenv("subnet"));
52 printit("timezone", "Offset in seconds from UTC", getenv("timezone"));
53 printit("router", "A list of routers", getenv("router"));
54 printit("timesvr", "A list of time servers", getenv("timesvr"));
55 printit("namesvr", "A list of IEN 116 name servers", getenv("namesvr"));
56 printit("dns", "A list of DNS server", getenv("dns"));
57 printit("logsvr", "A list of MIT-LCS UDP log servers", getenv("logsvr"));
58 printit("cookiesvr", "A list of RFC 865 cookie servers", getenv("cookiesvr"));
59 printit("lprsvr", "A list of LPR servers", getenv("lprsvr"));
60 printit("hostname", "The assigned hostname", getenv("hostname"));
61 printit("bootsize", "The length in 512 octect blocks of the bootfile", getenv("bootsize"));
62 printit("domain", "The domain name of the network", getenv("domain"));
63 printit("swapsvr", "The IP address of the client's swap server", getenv("swapsvr"));
64 printit("rootpath", "The path name of the client's root disk", getenv("rootpath"));
65 printit("ipttl", "The TTL to use for this network", getenv("ipttl"));
66 printit("mtu", "The MTU to use for this network", getenv("mtu"));
67 printit("broadcast", "The broadcast address for this network", getenv("broadcast"));
68 printit("ntpsrv", "A list of NTP servers", getenv("ntpsrv"));
69 printit("wins", "A list of WINS servers", getenv("wins"));
70 printit("lease", "The lease time, in seconds", getenv("lease"));
71 printit("dhcptype", "DHCP message type (safely ignored)", getenv("dhcptype"));
72 printit("serverid", "The IP of the server", getenv("serverid"));
73 printit("message", "Reason for a DHCPNAK", getenv("message"));
74 printit("tftp", "The TFTP server name", getenv("tftp"));
75 printit("bootfile", "The bootfile name", getenv("bootfile"));
76#endif
77
78 if (!*argv)
79 bb_printf("Error: should be called from udhcpc\n");
80 else
81 {
82 char *interface = getenv("interface");
83
84 if (strcmp(*argv, "deconfig") == 0)
85 {
86#ifdef CONFIG_FEATURE_IFUPDOWN_IP
87 doit(QUIET, "ip route flush dev %s", interface);
88 doit(QUIET, "ip addr flush dev %s", interface);
89 doit(QUIET, "ip link set %s up", interface);
90#else
91 errno = 0;
92 while (errno == 0)
93 doit(QUIET, "route del default gw 0.0.0.0 dev %s", interface);
94 doit(QUIET, "ifconfig %s 0.0.0.0", interface);
95#endif
96 }
97 else if (strcmp(*argv, "nak") == 0)
98 bb_printf("udhcpc received a NAK: %s\n", getenv("message"));
99 else if ((strcmp(*argv, "bound") == 0) || (strcmp(*argv, "renew") == 0))
100 {
101 const char *RESOLV_CONF = "/etc/resolv.conf";
102 char *broadcast = getenv("broadcast");
103 char *subnet = getenv("subnet");
104 char *mask = getenv("mask");
105 char *ip = getenv("ip");
106 char *hostname = getenv("hostname");
107 char *domain = getenv("domain");
108 char *router = getenv("router");
109 char *dns = getenv("dns");
110 char *siaddr = getenv("siaddr");
111 char *tftp = getenv("tftp");
112 char *BROADCAST = "";
113 char *NETMASK = "";
114 char *MASK = "";
115 char *HOSTNAME = 0;
116 int i, metric = 0;
117 char *token;
118 char *strtok_temp;
119
120 if (broadcast != 0)
121 bb_xasprintf(&BROADCAST, "broadcast %s", broadcast);
122 if (subnet != 0)
123 bb_xasprintf(&NETMASK, "netmask %s", subnet);
124 if (mask != 0)
125 bb_xasprintf(&MASK, "/%s", mask);
126 if (hostname != 0)
127 bb_xasprintf(&HOSTNAME, "/%s", hostname);
128#ifdef CONFIG_FEATURE_IFUPDOWN_IP
129 doit(0, "ip addr add %s%s %s dev %s", ip, MASK, BROADCAST, interface);
130 doit(0, "ip link set %s up", interface);
131#else
132 doit(0, "/sbin/ifconfig %s %s %s %s", interface, ip, BROADCAST, NETMASK);
133#endif
134 if (router != 0)
135 {
136 token = strtok_r(router, " ,\t\r\n", &strtok_temp);
137 for (i = 0; token != NULL; i++)
138 {
139#ifdef CONFIG_FEATURE_IFUPDOWN_IP
140 doit(0, "ip route add to default via %s dev %s", token, interface, metric++);
141#else
142 doit(0, "route add default gw %s dev %s metric %d", token, interface, metric++);
143#endif
144 token = strtok_r(NULL, " ,\t\r\n", &strtok_temp);
145 }
146 }
147
148 doit(0, "echo -n > %s", RESOLV_CONF);
149 if (domain != 0)
150 doit(0, "echo \"search %s\" > %s", domain, RESOLV_CONF);
151
152 token = strtok_r(dns, " \r\n", &strtok_temp);
153 for (i = 0; token != NULL; i++)
154 {
155 doit(0, "echo \"nameserver %s\" >> %s", token, RESOLV_CONF);
156
157 token = strtok_r(NULL, " \r\n", &strtok_temp);
158 }
159
160 if (HOSTNAME == 0)
161 {
162 bb_xasprintf(&HOSTNAME, doit(REDIR, "nslookup %s | grep -v default | grep Name | cut -d\":\" -f2 | tr -d ' ' | tail -n 1", ip));
163 if ((HOSTNAME == 0) && (stat("/var/lib/my_linux/config/hostname", &path_stat) == 0))
164 HOSTNAME = quick_read("/var/lib/my_linux/config/hostname");
165 if (HOSTNAME == 0)
166 HOSTNAME = "my_linux";
167 }
168 doit(0, "hostname %s", HOSTNAME);
169// Should remove old entry
170 doit(0, "echo \"%s %s\" >> /etc/hosts", ip, HOSTNAME);
171
172// Should dump these in a per interface file
173 if (siaddr != NULL)
174 quick_write("/var/lib/network/nfsaddr", siaddr);
175 if (tftp != NULL)
176 quick_write("/var/lib/network/tftpaddr", tftp);
177
178 /* This is what the network init script is waiting for. */
179 quick_write("/var/lib/network/ipaddr", ip);
180 bb_printf("IP %s HOSTNAME %s\n", ip, HOSTNAME);
181
182 free(HOSTNAME);
183 }
184 else
185 {
186 bb_printf("Huh?\n");
187 }
188 }
189
190 return EXIT_SUCCESS;
191}
diff --git a/urunlevel/sysdeps/linux/Config.in b/urunlevel/sysdeps/linux/Config.in
new file mode 100644
index 0000000..2e364f2
--- /dev/null
+++ b/urunlevel/sysdeps/linux/Config.in
@@ -0,0 +1,296 @@
1#
2# For a description of the syntax of this configuration file,
3# see scripts/kbuild/config-language.txt.
4#
5
6mainmenu "BusyBox Configuration"
7
8config HAVE_DOT_CONFIG
9 bool
10 default y
11
12menu "General Configuration"
13
14choice
15 prompt "Buffer allocation policy"
16 default CONFIG_FEATURE_BUFFERS_USE_MALLOC
17 help
18 There are 3 ways BusyBox can handle buffer allocations:
19 - Use malloc. This costs code size for the call to xmalloc.
20 - Put them on stack. For some very small machines with limited stack
21 space, this can be deadly. For most folks, this works just fine.
22 - Put them in BSS. This works beautifully for computers with a real
23 MMU (and OS support), but wastes runtime RAM for uCLinux. This
24 behavior was the only one available for BusyBox versions 0.48 and
25 earlier.
26
27config CONFIG_FEATURE_BUFFERS_USE_MALLOC
28 bool "Allocate with Malloc"
29
30config CONFIG_FEATURE_BUFFERS_GO_ON_STACK
31 bool "Allocate on the Stack"
32
33config CONFIG_FEATURE_BUFFERS_GO_IN_BSS
34 bool "Allocate in the .bss section"
35
36endchoice
37
38config CONFIG_FEATURE_VERBOSE_USAGE
39 bool "Show verbose applet usage messages"
40 default n
41 help
42 All BusyBox applets will show more verbose help messages when
43 busybox is invoked with --help. This will add a lot of text to the
44 busybox binary. In the default configuration, this will add about
45 13k, but it can add much more depending on your configuration.
46
47config CONFIG_FEATURE_INSTALLER
48 bool "Support --install [-s] to install applet links at runtime"
49 default n
50 help
51 Enable 'busybox --install [-s]' support. This will allow you to use
52 busybox at runtime to create hard links or symlinks for all the
53 applets that are compiled into busybox. This feature requires the
54 /proc filesystem.
55
56config CONFIG_LOCALE_SUPPORT
57 bool "Enable locale support (system needs locale for this to work)"
58 default n
59 help
60 Enable this if your system has locale support and you would like
61 busybox to support locale settings.
62
63config CONFIG_FEATURE_DEVFS
64 bool "Support for devfs"
65 default n
66 help
67 Enable if you want BusyBox to work with devfs.
68
69config CONFIG_FEATURE_DEVPTS
70 bool "Use the devpts filesystem for Unix98 PTYs"
71 default y if CONFIG_FEATURE_DEVFS
72 help
73 Enable if you want BusyBox to use Unix98 PTY support. If enabled,
74 busybox will use /dev/ptmx for the master side of the pseudoterminal
75 and /dev/pts/<number> for the slave side. Otherwise, BSD style
76 /dev/ttyp<number> will be used. To use this option, you should have
77 devpts or devfs mounted.
78
79config CONFIG_FEATURE_CLEAN_UP
80 bool "Clean up all memory before exiting (usually not needed)"
81 default n
82 help
83 As a size optimization, busybox by default does not cleanup memory
84 that is dynamically allocated or close files before exiting. This
85 saves space and is usually not needed since the OS will clean up for
86 us. Don't enable this unless you have a really good reason to clean
87 things up manually.
88
89config CONFIG_FEATURE_SUID
90 bool "Support for SUID/SGID handling"
91 default n
92 help
93 Support SUID and SGID binaries.
94
95config CONFIG_FEATURE_SUID_CONFIG
96 bool "Runtime SUID/SGID configuration via /etc/busybox.conf"
97 default y if CONFIG_FEATURE_SUID
98 depends on CONFIG_FEATURE_SUID
99 help
100 Allow the SUID / SGID state of an applet to be determined runtime by
101 checking /etc/busybox.conf. The format of this file is as follows:
102
103 <applet> = [Ssx-][Ssx-][x-] (<username>|<uid>).(<groupname>|<gid>)
104
105 An example might help:
106
107 [SUID]
108 su = ssx root.0 # applet su can be run by anyone and runs with euid=0/egid=0
109 su = ssx # exactly the same
110
111 mount = sx- root.disk # applet mount can be run by root and members of group disk
112 # and runs with euid=0
113
114 cp = --- # disable applet cp for everyone
115
116 Robert 'sandman' Griebl has more information here:
117 <url: http://www.softforge.de/bb/suid.html >.
118
119config CONFIG_FEATURE_SUID_CONFIG_QUIET
120 bool "Suppress warning message if /etc/busybox.conf is not readable"
121 default n
122 depends on CONFIG_FEATURE_SUID_CONFIG
123 help
124 /etc/busybox.conf should be readable by the user needing the SUID, check
125 this option to avoid users to be notified about missing permissions.
126
127config CONFIG_SELINUX
128 bool "Support NSA Security Enhanced Linux"
129 default n
130 help
131 Enable support for SE Linux in applets ls, ps, and id. Also provide
132 the option of compiling in SE Linux applets.
133
134 If you do not have a complete SE Linux Full Userland installed, this
135 stuff will not compile. Go visit
136 http://www.nsa.gov/selinux/index.html
137 to download the necessary stuff to allow busybox to compile with this
138 option enabled.
139
140 Most people will leave this set to 'N'.
141
142endmenu
143
144menu 'Build Options'
145
146config CONFIG_STATIC
147 bool "Build BusyBox as a static binary (no shared libs)"
148 default n
149 help
150 If you want to build a static BusyBox binary, which does not
151 use or require any shared libraries, then enable this option.
152 This can cause BusyBox to be considerably larger, so you should
153 leave this option false unless you have a good reason (i.e.
154 your target platform does not support shared libraries, or
155 you are building an initrd which doesn't need anything but
156 BusyBox, etc).
157
158 Most people will leave this set to 'N'.
159
160config CONFIG_LFS
161 bool "Build with Large File Support (for accessing files > 2 GB)"
162 default n
163 select FDISK_SUPPORT_LARGE_DISKS
164 help
165 If you want to build BusyBox with large file support, then enable
166 this option. This will have no effect if your kernel or your C
167 library lacks large file support for large files. Some of the
168 programs that can benefit from large file support include dd, gzip,
169 cp, mount, tar, and many others. If you want to access files larger
170 than 2 Gigabytes, enable this option. Otherwise, leave it set to 'N'.
171
172config USING_CROSS_COMPILER
173 bool "Do you want to build BusyBox with a Cross Compiler?"
174 default n
175 help
176 Do you want to build BusyBox with a Cross Compiler? If so,
177 then enable this option. Otherwise leave it set to 'N'.
178
179config CROSS_COMPILER_PREFIX
180 string "Cross Compiler prefix"
181 default "/usr/i386-linux-uclibc/bin/i386-uclibc-"
182 depends on USING_CROSS_COMPILER
183 help
184 If you want to build BusyBox with a cross compiler, then you
185 will need to set this to the cross-compiler prefix. For example,
186 if my cross-compiler is /usr/i386-linux-uclibc/bin/i386-uclibc-gcc
187 then I would enter '/usr/i386-linux-uclibc/bin/i386-uclibc-' here,
188 which will ensure the correct compiler is used.
189
190config EXTRA_CFLAGS_OPTIONS
191 string "Any extra CFLAGS options for the compiler?"
192 default ""
193 help
194 Do you want to pass any extra CFLAGS options to the compiler as
195 you build BusyBox? If so, this is the option for you... For example,
196 if you want to add some simple compiler switches (like -march=i686),
197 or check for warnings using -Werror, just those options here.
198
199endmenu
200
201menu 'Installation Options'
202
203config CONFIG_INSTALL_NO_USR
204 bool "Don't use /usr"
205 default n
206 help
207 Disable use of /usr. Don't activate this option if you don't know
208 that you really want this behaviour.
209
210config PREFIX
211 string "BusyBox installation prefix"
212 default "./_install"
213 help
214 Define your directory to install BusyBox files/subdirs in.
215
216
217
218endmenu
219
220source archival/Config.in
221source coreutils/Config.in
222source console-tools/Config.in
223source debianutils/Config.in
224source editors/Config.in
225source findutils/Config.in
226source my_linux/Config.in
227source runlevel/Config.in
228source init/Config.in
229source loginutils/Config.in
230source miscutils/Config.in
231source modutils/Config.in
232source networking/Config.in
233source procps/Config.in
234source shell/Config.in
235source sysklogd/Config.in
236source util-linux/Config.in
237
238menu 'Debugging Options'
239
240config CONFIG_DEBUG
241 bool "Build BusyBox with Debugging symbols"
242 default n
243 help
244 Say Y here if you wish to compile BusyBox with debugging symbols.
245 This will allow you to use a debugger to examine BusyBox internals
246 while applets are running. This increases the size of the binary
247 considerably and should only be used when doing development.
248 If you are doing development and want to debug BusyBox, answer Y.
249
250 Most people should answer N.
251
252choice
253 prompt "Additional debugging library"
254 default CONFIG_NO_DEBUG_LIB
255 depends on CONFIG_DEBUG
256 help
257 Using an additional debugging library will make BusyBox become
258 considerable larger and will cause it to run more slowly. You
259 should always leave this option disabled for production use.
260
261 dmalloc support:
262 ----------------
263 This enables compiling with dmalloc ( http://dmalloc.com/ )
264 which is an excellent public domain mem leak and malloc problem
265 detector. To enable dmalloc, before running busybox you will
266 want to properly set your environment, for example:
267 export DMALLOC_OPTIONS=debug=0x34f47d83,inter=100,log=logfile
268 The 'debug=' value is generated using the following command
269 dmalloc -p log-stats -p log-non-free -p log-bad-space -p log-elapsed-time \
270 -p check-fence -p check-heap -p check-lists -p check-blank \
271 -p check-funcs -p realloc-copy -p allow-free-null
272
273 Electric-fence support:
274 -----------------------
275 This enables compiling with Electric-fence support. Electric
276 fence is another very useful malloc debugging library which uses
277 your computer's virtual memory hardware to detect illegal memory
278 accesses. This support will make BusyBox be considerable larger
279 and run slower, so you should leave this option disabled unless
280 you are hunting a hard to find memory problem.
281
282
283config CONFIG_NO_DEBUG_LIB
284 bool "None"
285
286config CONFIG_DMALLOC
287 bool "Dmalloc"
288
289config CONFIG_EFENCE
290 bool "Electric-fence"
291
292endchoice
293
294
295endmenu
296