diff options
Diffstat (limited to 'busybox/patches')
-rw-r--r-- | busybox/patches/cmp_n.diff | 377 | ||||
-rw-r--r-- | busybox/patches/dd_ibs_and_obs.diff | 252 | ||||
-rw-r--r-- | busybox/patches/eject.diff | 164 | ||||
-rw-r--r-- | busybox/patches/makdevs_table.diff | 294 | ||||
-rw-r--r-- | busybox/patches/rpm2cpio_bzip2.patch | 63 | ||||
-rw-r--r-- | busybox/patches/tftp_timeout_multicast.diff | 1053 | ||||
-rw-r--r-- | busybox/patches/top_system_cpu.diff | 51 | ||||
-rw-r--r-- | busybox/patches/udhcp_additional_items.diff | 126 | ||||
-rw-r--r-- | busybox/patches/udhcp_config_paths.diff | 333 | ||||
-rw-r--r-- | busybox/patches/udhcpd_foreground.diff | 33 |
10 files changed, 2746 insertions, 0 deletions
diff --git a/busybox/patches/cmp_n.diff b/busybox/patches/cmp_n.diff new file mode 100644 index 0000000..fc4661c --- /dev/null +++ b/busybox/patches/cmp_n.diff @@ -0,0 +1,377 @@ +Index: coreutils/Config.in +=================================================================== +RCS file: /var/cvs/busybox/coreutils/Config.in,v +retrieving revision 1.24 +diff -u -r1.24 Config.in +--- a/coreutils/Config.in 15 Mar 2004 08:28:19 -0000 1.24 ++++ b/coreutils/Config.in 31 Mar 2004 11:51:17 -0000 +@@ -59,6 +59,21 @@ + cmp is used to compare two files and returns the result + to standard output. + ++config CONFIG_FEATURE_CMP_SKIP ++ bool " Enable optional arguments SKIP1 and SKIP2" ++ default n ++ depends on CONFIG_CMP ++ help ++ SKIP1 and SKIP2 specify how many bytes to ignore ++ at the start of each file. ++ ++config CONFIG_FEATURE_CMP_LIMIT ++ bool " Enable limit of inputs" ++ default n ++ depends on CONFIG_CMP ++ help ++ Enable cmp option (-n). ++ + config CONFIG_CP + bool "cp" + default n +Index: coreutils/cmp.c +=================================================================== +RCS file: /var/cvs/busybox/coreutils/cmp.c,v +retrieving revision 1.9 +diff -u -r1.9 cmp.c +--- a/coreutils/cmp.c 19 Mar 2003 09:11:32 -0000 1.9 ++++ b/coreutils/cmp.c 31 Mar 2004 11:51:17 -0000 +@@ -39,6 +39,12 @@ + #include <unistd.h> + #include "busybox.h" + ++#ifdef CONFIG_FEATURE_CMP_SKIP ++#define MAX_OPTIONAL_ARGS 3 ++#else ++#define MAX_OPTIONAL_ARGS 1 ++#endif ++ + static FILE *cmp_xfopen_input(const char *filename) + { + FILE *fp; +@@ -58,12 +64,57 @@ + static const char fmt_l_opt[] = "%.0s%.0s%d %3o %3o\n"; /* nicer gnu format */ + #endif + +-static const char opt_chars[] = "sl"; ++#ifdef CONFIG_FEATURE_CMP_LIMIT ++#define OPTCHR_LIMIT "n:" ++#define OPTARG_LIMIT ,&limit_str ++#else ++#define OPTCHR_LIMIT ++#define OPTARG_LIMIT ++#endif ++ ++static const char opt_chars[] = "sl" OPTCHR_LIMIT; + + enum { + OPT_s = 1, +- OPT_l = 2 ++ OPT_l = 2, ++ OPT_n = 4 ++}; ++ ++#ifdef CONFIG_LFS ++#define SUFFIX_STRUCT suffix_mult64 ++#define PARSE_FUNC bb_xgetllarg10_sfx ++#else ++#define SUFFIX_STRUCT suffix_mult ++#define PARSE_FUNC bb_xgetlarg10_sfx ++#endif ++ ++#if defined(CONFIG_FEATURE_CMP_SKIP) || defined(CONFIG_FEATURE_CMP_LIMIT) ++static const struct SUFFIX_STRUCT suffixes[] = { ++ { "k", 1UL << 10 }, ++ { "M", 1UL << 20 }, ++ { "G", 1UL << 30 }, ++#ifdef CONFIG_LFS ++ { "T", 1ULL << 40 }, ++ { "P", 1ULL << 50 }, ++ { "E", 1ULL << 60 }, ++#endif ++ { NULL, 0 } + }; ++#endif ++ ++#ifdef CONFIG_FEATURE_CMP_SKIP ++static void skip_input(FILE *fp, off_t skip, const char *filename) ++{ ++ if (skip > 0 && fseeko(fp, skip, SEEK_CUR) != 0) { ++ while (skip-- > 0) { ++ if (getc(fp) == EOF) { ++ bb_xferror(fp, filename); ++ break; ++ } ++ } ++ } ++} ++#endif + + int cmp_main(int argc, char **argv) + { +@@ -73,12 +124,26 @@ + int c1, c2, char_pos, line_pos; + int opt_flags; + int exit_val = 0; ++#ifdef CONFIG_FEATURE_CMP_SKIP ++ off_t skip1 = 0, skip2 = 0; ++#endif ++#ifdef CONFIG_FEATURE_CMP_LIMIT ++ off_t limit = -1; ++ char *limit_str; ++#endif + + bb_default_error_retval = 2; /* 1 is returned if files are different. */ + +- opt_flags = bb_getopt_ulflags(argc, argv, opt_chars); ++ opt_flags = bb_getopt_ulflags(argc, argv, opt_chars OPTARG_LIMIT); + +- if ((opt_flags == 3) || (((unsigned int)(--argc - optind)) > 1)) { ++#ifdef CONFIG_FEATURE_CMP_LIMIT ++ if (opt_flags & OPT_n) { ++ limit = PARSE_FUNC(limit_str, suffixes); ++ opt_flags &= 3; ++ } ++#endif ++ ++ if ((opt_flags == 3) || (((unsigned int)(--argc - optind)) > MAX_OPTIONAL_ARGS)) { + bb_show_usage(); + } + +@@ -87,6 +152,13 @@ + filename2 = "-"; + if (*++argv) { + filename2 = *argv; ++#ifdef CONFIG_FEATURE_CMP_SKIP ++ if (*++argv) { ++ skip1 = PARSE_FUNC(*argv, suffixes); ++ if (*++argv) ++ skip2 = PARSE_FUNC(*argv, suffixes); ++ } ++#endif + } + fp2 = cmp_xfopen_input(filename2); + +@@ -98,6 +170,11 @@ + return 0; + } + ++#ifdef CONFIG_FEATURE_CMP_SKIP ++ skip_input(fp1, skip1, filename1); ++ skip_input(fp2, skip2, filename2); ++#endif ++ + fmt = fmt_differ; + if (opt_flags == OPT_l) { + fmt = fmt_l_opt; +@@ -106,6 +183,10 @@ + char_pos = 0; + line_pos = 1; + do { ++#ifdef CONFIG_FEATURE_CMP_LIMIT ++ if (limit-- == 0) ++ break; ++#endif + c1 = getc(fp1); + c2 = getc(fp2); + ++char_pos; +Index: include/usage.h +=================================================================== +RCS file: /var/cvs/busybox/include/usage.h,v +retrieving revision 1.198 +diff -u -r1.198 usage.h +--- a/include/usage.h 29 Mar 2004 08:20:08 -0000 1.198 ++++ b/include/usage.h 31 Mar 2004 11:51:17 -0000 +@@ -186,14 +186,29 @@ + #define clear_full_usage \ + "Clear screen." + ++#ifdef CONFIG_FEATURE_CMP_SKIP ++#define USAGE_CMP_SKIP(a) a ++#else ++#define USAGE_CMP_SKIP(a) ++#endif ++ ++#ifdef CONFIG_FEATURE_CMP_LIMIT ++#define USAGE_CMP_LIMIT(a) a ++#else ++#define USAGE_CMP_LIMIT(a) ++#endif ++ + #define cmp_trivial_usage \ +- "[OPTION]... FILE1 [FILE2]" ++ "[OPTION]... FILE1 [FILE2" USAGE_CMP_SKIP(" [SKIP1 [SKIP2]]") "]" + #define cmp_full_usage \ +- "Compare files.\n\n" \ ++ "Compare files.\n" \ ++ USAGE_CMP_SKIP("SKIP1 and SKIP2 are the number of bytes to skip in each file.\n") \ ++ "\n" \ + "Options:\n" \ +- "\t-l\tWrite the byte numbers (decimal) and values (octal)\n" \ +- "\t\t for all differing bytes.\n" \ +- "\t-s\tquiet mode - do not print" ++ "\t-l\t\tWrite the byte numbers (decimal) and values (octal)\n" \ ++ "\t\t\t for all differing bytes.\n" \ ++ USAGE_CMP_LIMIT("\t-n LIMIT\tCompare at most LIMIT bytes.\n") \ ++ "\t-s\t\tquiet mode - do not print" + + #define cp_trivial_usage \ + "[OPTION]... SOURCE DEST" +Index: include/libbb.h +=================================================================== +RCS file: /var/cvs/busybox/include/libbb.h,v +retrieving revision 1.129 +diff -u -r1.129 libbb.h +--- a/include/libbb.h 15 Mar 2004 08:28:38 -0000 1.129 ++++ b/include/libbb.h 31 Mar 2004 11:51:17 -0000 +@@ -217,6 +217,21 @@ + const struct suffix_mult *suffixes); + extern long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes); + ++struct suffix_mult64 { ++ const char *suffix; ++ unsigned long long mult; ++}; ++ ++extern unsigned long long bb_xgetullarg_bnd_sfx(const char *arg, int base, ++ unsigned long long lower, ++ unsigned long long upper, ++ const struct suffix_mult64 *suffixes); ++ ++extern long long bb_xgetllarg_bnd_sfx(const char *arg, int base, ++ long long lower, ++ long long upper, ++ const struct suffix_mult64 *suffixes); ++extern long long bb_xgetllarg10_sfx(const char *arg, const struct suffix_mult64 *suffixes); + + //#warning pitchable now? + extern unsigned long bb_xparse_number(const char *numstr, +Index: libbb/Makefile.in +=================================================================== +RCS file: /var/cvs/busybox/libbb/Makefile.in,v +retrieving revision 1.34 +diff -u -r1.34 Makefile.in +--- a/libbb/Makefile.in 6 Mar 2004 22:11:45 -0000 1.34 ++++ b/libbb/Makefile.in 31 Mar 2004 11:51:17 -0000 +@@ -70,7 +70,8 @@ + + LIBBB_MSRC3:=$(LIBBB_DIR)xgetularg.c + LIBBB_MOBJ3:=xgetularg_bnd_sfx.o xgetlarg_bnd_sfx.o getlarg10_sfx.o \ +- xgetularg_bnd.o xgetularg10_bnd.o xgetularg10.o ++ xgetularg_bnd.o xgetularg10_bnd.o xgetularg10.o \ ++ xgetullarg_bnd_sfx.o xgetllarg_bnd_sfx.o xgetllarg10_sfx.o + + LIBBB_MSRC4:=$(LIBBB_DIR)/safe_strtol.c + LIBBB_MOBJ4:=safe_strtoi.o safe_strtod.o safe_strtol.o safe_strtoul.o +Index: libbb/xgetularg.c +=================================================================== +RCS file: /var/cvs/busybox/libbb/xgetularg.c,v +retrieving revision 1.2 +diff -u -r1.2 xgetularg.c +--- a/libbb/xgetularg.c 15 Mar 2004 08:28:44 -0000 1.2 ++++ b/libbb/xgetularg.c 31 Mar 2004 11:51:17 -0000 +@@ -158,3 +158,106 @@ + return bb_xgetularg10_bnd(arg, 0, ULONG_MAX); + } + #endif ++ ++#ifdef L_xgetullarg_bnd_sfx ++extern ++unsigned long long bb_xgetullarg_bnd_sfx(const char *arg, int base, ++ unsigned long long lower, ++ unsigned long long upper, ++ const struct suffix_mult64 *suffixes) ++{ ++ unsigned long long r; ++ int old_errno; ++ char *e; ++ ++ assert(arg); ++ ++ /* Disallow '-' and any leading whitespace. Speed isn't critical here ++ * since we're parsing commandline args. So make sure we get the ++ * actual isspace function rather than a larger macro implementaion. */ ++ if ((*arg == '-') || (isspace)(*arg)) { ++ bb_show_usage(); ++ } ++ ++ /* Since this is a lib function, we're not allowed to reset errno to 0. ++ * Doing so could break an app that is deferring checking of errno. ++ * So, save the old value so that we can restore it if successful. */ ++ old_errno = errno; ++ errno = 0; ++ r = strtoull(arg, &e, base); ++ /* Do the initial validity check. Note: The standards do not ++ * guarantee that errno is set if no digits were found. So we ++ * must test for this explicitly. */ ++ if (errno || (arg == e)) { /* error or no digits */ ++ bb_show_usage(); ++ } ++ errno = old_errno; /* Ok. So restore errno. */ ++ ++ /* Do optional suffix parsing. Allow 'empty' suffix tables. ++ * Note that we also all nul suffixes with associated multipliers, ++ * to allow for scaling of the arg by some default multiplier. */ ++ ++ if (suffixes) { ++ while (suffixes->suffix) { ++ if (strcmp(suffixes->suffix, e) == 0) { ++ if (ULONG_LONG_MAX / suffixes->mult < r) { /* Overflow! */ ++ bb_show_usage(); ++ } ++ ++e; ++ r *= suffixes->mult; ++ break; ++ } ++ ++suffixes; ++ } ++ } ++ ++ /* Finally, check for illegal trailing chars and range limits. */ ++ /* Note: although we allow leading space (via stroul), trailing space ++ * is an error. It would be easy enough to allow though if desired. */ ++ if (*e || (r < lower) || (r > upper)) { ++ bb_show_usage(); ++ } ++ ++ return r; ++} ++#endif ++ ++#ifdef L_xgetllarg_bnd_sfx ++extern ++long long bb_xgetllarg_bnd_sfx(const char *arg, int base, ++ long long lower, ++ long long upper, ++ const struct suffix_mult64 *suffixes) ++{ ++ unsigned long long u = LONG_LONG_MAX; ++ long long r; ++ const char *p = arg; ++ ++ if ((*p == '-') && (p[1] != '+')) { ++ ++p; ++#if LONG_LONG_MAX == (-(LONG_LONG_MIN + 1)) ++ ++u; /* two's complement */ ++#endif ++ } ++ ++ r = bb_xgetullarg_bnd_sfx(p, base, 0, u, suffixes); ++ ++ if (*arg == '-') { ++ r = -r; ++ } ++ ++ if ((r < lower) || (r > upper)) { ++ bb_show_usage(); ++ } ++ ++ return r; ++} ++#endif ++ ++#ifdef L_xgetllarg10_sfx ++extern ++long long bb_xgetllarg10_sfx(const char *arg, const struct suffix_mult64 *suffixes) ++{ ++ return bb_xgetllarg_bnd_sfx(arg, 10, LONG_LONG_MIN, LONG_LONG_MAX, suffixes); ++} ++#endif diff --git a/busybox/patches/dd_ibs_and_obs.diff b/busybox/patches/dd_ibs_and_obs.diff new file mode 100644 index 0000000..3bbf4b9 --- /dev/null +++ b/busybox/patches/dd_ibs_and_obs.diff @@ -0,0 +1,252 @@ +This patch adds support of ibs= and obs= to dd. +---- +Hideki IWAMOTO h-iwamoto@kit.hi-ho.ne.jp + + +--- a/include/usage.h 29 Mar 2004 08:20:08 -0000 1.198 ++++ b/include/usage.h 4 Apr 2004 07:15:21 -0000 +@@ -309,13 +309,15 @@ + "64\n" + + #define dd_trivial_usage \ +- "[if=FILE] [of=FILE] [bs=N] [count=N] [skip=N]\n" \ +- "\t [seek=N] [conv=notrunc|noerror|sync]" ++ "[if=FILE] [of=FILE] [ibs=N] [obs=N] [bs=N] [count=N]\n" \ ++ "\t [skip=N] [seek=N] [conv=notrunc|noerror|sync]" + #define dd_full_usage \ + "Copy a file, converting and formatting according to options\n\n" \ + "\tif=FILE\t\tread from FILE instead of stdin\n" \ + "\tof=FILE\t\twrite to FILE instead of stdout\n" \ +- "\tbs=N\t\tread and write N bytes at a time\n" \ ++ "\tibs=N\t\tread N bytes at a time\n" \ ++ "\tobs=N\t\twrite N bytes at a time\n" \ ++ "\tbs=N\t\tforce ibs=N and obs=N\n" \ + "\tcount=N\t\tcopy only N input blocks\n" \ + "\tskip=N\t\tskip N input blocks\n" \ + "\tseek=N\t\tskip N output blocks\n" \ +@@ -323,6 +325,8 @@ + "\tconv=noerror\tcontinue after read errors\n" \ + "\tconv=sync\tpad blocks with zeros\n" \ + "\n" \ ++ "If the bs= expr operand is not specified, the input is processed and collected\n" \ ++ "into full-sized output blocks until the end of the input is reached.\n" \ + "Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),\n" \ + "MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)." + #define dd_example_usage \ +--- a/coreutils/dd.c 30 Jan 2004 22:24:32 -0000 1.55 ++++ b/coreutils/dd.c 4 Apr 2004 07:15:21 -0000 +@@ -30,6 +30,10 @@ + #include <fcntl.h> + #include "busybox.h" + ++#define C_NOERROR 0x0001 ++#define C_TRUNC 0x0002 ++#define C_SYNC 0x0004 ++#define C_TWOBUFS 0x0008 + + static const struct suffix_mult dd_suffixes[] = { + { "c", 1 }, +@@ -51,13 +55,13 @@ + size_t in_full = 0; + size_t in_part = 0; + size_t count = -1; +- size_t bs = 512; ++ size_t ibs = 512; ++ size_t obs = 512; ++ size_t oc = 0; + ssize_t n; + off_t seek = 0; + off_t skip = 0; +- int sync_flag = FALSE; +- int noerror = FALSE; +- int trunc_flag = TRUE; ++ unsigned int dd_flags = C_TWOBUFS | C_TRUNC; + int oflag; + int ifd; + int ofd; +@@ -65,11 +69,18 @@ + const char *infile = NULL; + const char *outfile = NULL; + char *buf; ++ char *ibuf; ++ char *obuf; + + for (i = 1; i < argc; i++) { +- if (strncmp("bs=", argv[i], 3) == 0) +- bs = bb_xparse_number(argv[i]+3, dd_suffixes); +- else if (strncmp("count=", argv[i], 6) == 0) ++ if (strncmp("ibs=", argv[i], 4) == 0) ++ ibs = bb_xparse_number(argv[i]+4, dd_suffixes); ++ else if (strncmp("obs=", argv[i], 4) == 0) ++ obs = bb_xparse_number(argv[i]+4, dd_suffixes); ++ else if (strncmp("bs=", argv[i], 3) == 0) { ++ ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes); ++ dd_flags &= ~C_TWOBUFS; ++ } else if (strncmp("count=", argv[i], 6) == 0) + count = bb_xparse_number(argv[i]+6, dd_suffixes); + else if (strncmp("seek=", argv[i], 5) == 0) + seek = bb_xparse_number(argv[i]+5, dd_suffixes); +@@ -83,13 +94,13 @@ + buf = argv[i]+5; + while (1) { + if (strncmp("notrunc", buf, 7) == 0) { +- trunc_flag = FALSE; ++ dd_flags &= ~C_TRUNC; + buf += 7; + } else if (strncmp("sync", buf, 4) == 0) { +- sync_flag = TRUE; ++ dd_flags |= C_SYNC; + buf += 4; + } else if (strncmp("noerror", buf, 7) == 0) { +- noerror = TRUE; ++ dd_flags |= C_NOERROR; + buf += 7; + } else { + bb_error_msg_and_die("invalid conversion `%s'", argv[i]+5); +@@ -103,7 +114,12 @@ + bb_show_usage(); + } + +- buf = xmalloc(bs); ++ ibuf = xmalloc(ibs); ++ ++ if (dd_flags & C_TWOBUFS) ++ obuf = xmalloc(obs); ++ else ++ obuf = ibuf; + + if (infile != NULL) { + ifd = bb_xopen(infile, O_RDONLY); +@@ -115,7 +131,7 @@ + if (outfile != NULL) { + oflag = O_WRONLY | O_CREAT; + +- if (!seek && trunc_flag) { ++ if (!seek && (dd_flags & C_TRUNC)) { + oflag |= O_TRUNC; + } + +@@ -123,8 +139,8 @@ + bb_perror_msg_and_die("%s", outfile); + } + +- if (seek && trunc_flag) { +- if (ftruncate(ofd, seek * bs) < 0) { ++ if (seek && (dd_flags & C_TRUNC)) { ++ if (ftruncate(ofd, seek * obs) < 0) { + struct stat st; + + if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) || +@@ -139,52 +155,88 @@ + } + + if (skip) { +- if (lseek(ifd, skip * bs, SEEK_CUR) < 0) { +- bb_perror_msg_and_die("%s", infile); ++ if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) { ++ while (skip-- > 0) { ++ n = safe_read(ifd, ibuf, ibs); ++ if (n < 0) ++ bb_perror_msg_and_die("%s", infile); ++ if (n == 0) ++ break; ++ } + } + } + + if (seek) { +- if (lseek(ofd, seek * bs, SEEK_CUR) < 0) { ++ if (lseek(ofd, seek * obs, SEEK_CUR) < 0) { + bb_perror_msg_and_die("%s", outfile); + } + } + + while (in_full + in_part != count) { +- if (noerror) { ++ if (dd_flags & C_NOERROR) { + /* Pre-zero the buffer when doing the noerror thing */ +- memset(buf, '\0', bs); ++ memset(ibuf, '\0', ibs); ++ } ++ ++ n = safe_read(ifd, ibuf, ibs); ++ if (n == 0) { ++ break; + } +- n = safe_read(ifd, buf, bs); + if (n < 0) { +- if (noerror) { +- n = bs; ++ if (dd_flags & C_NOERROR) { ++ n = ibs; + bb_perror_msg("%s", infile); + } else { + bb_perror_msg_and_die("%s", infile); + } + } +- if (n == 0) { +- break; +- } +- if (n == bs) { ++ if (n == ibs) { + in_full++; + } else { + in_part++; ++ if (dd_flags & C_SYNC) { ++ memset(ibuf + n, '\0', ibs - n); ++ n = ibs; ++ } + } +- if (sync_flag) { +- memset(buf + n, '\0', bs - n); +- n = bs; ++ ++ if (dd_flags & C_TWOBUFS) { ++ size_t d; ++ char *tmp = ibuf; ++ ++ while (n) { ++ d = obs - oc; ++ if (d > n) ++ d = n; ++ memcpy(obuf + oc, tmp, d); ++ n -= d; ++ tmp += d; ++ oc += d; ++ if (oc == obs) { ++ if (bb_full_write(ofd, obuf, obs) < 0) { ++ bb_perror_msg_and_die("%s", outfile); ++ } ++ out_full++; ++ oc = 0; ++ } ++ } ++ } else { ++ if (bb_full_write(ofd, ibuf, n) < 0) { ++ bb_perror_msg_and_die("%s", outfile); ++ } ++ if (n == ibs) { ++ out_full++; ++ } else { ++ out_part++; ++ } + } +- n = bb_full_write(ofd, buf, n); +- if (n < 0) { ++ } ++ ++ if (oc) { ++ if (bb_full_write(ofd, obuf, oc) < 0) { + bb_perror_msg_and_die("%s", outfile); + } +- if (n == bs) { +- out_full++; +- } else { +- out_part++; +- } ++ out_part++; + } + + if (close (ifd) < 0) { + + diff --git a/busybox/patches/eject.diff b/busybox/patches/eject.diff new file mode 100644 index 0000000..fcc234d --- /dev/null +++ b/busybox/patches/eject.diff @@ -0,0 +1,164 @@ +Index: AUTHORS +=================================================================== +RCS file: /var/cvs/busybox/AUTHORS,v +retrieving revision 1.40 +diff -u -r1.40 AUTHORS +--- a/AUTHORS 9 Oct 2003 21:19:21 -0000 1.40 ++++ b/AUTHORS 5 Mar 2004 07:23:17 -0000 +@@ -8,6 +8,9 @@ + + ----------- + ++Peter Willis <psyphreak@phreaker.net> ++ eject ++ + Emanuele Aina <emanuele.aina@tiscali.it> + run-parts + +Index: coreutils/Config.in +=================================================================== +RCS file: /var/cvs/busybox/coreutils/Config.in,v +retrieving revision 1.23 +diff -u -r1.23 Config.in +--- a/coreutils/Config.in 5 Mar 2004 06:47:25 -0000 1.23 ++++ b/coreutils/Config.in 5 Mar 2004 07:23:18 -0000 +@@ -164,6 +164,13 @@ + a command; without options it displays the current + environment. + ++config CONFIG_EJECT ++ bool "eject" ++ default n ++ help ++ ejects a cdrom drive. ++ defaults to /dev/cdrom ++ + config CONFIG_EXPR + bool "expr" + default n +Index: coreutils/Makefile.in +=================================================================== +RCS file: /var/cvs/busybox/coreutils/Makefile.in,v +retrieving revision 1.8 +diff -u -r1.8 Makefile.in +--- a/coreutils/Makefile.in 27 Jan 2004 09:22:20 -0000 1.8 ++++ b/coreutils/Makefile.in 5 Mar 2004 07:23:18 -0000 +@@ -41,6 +41,7 @@ + COREUTILS-$(CONFIG_DU) += du.o + COREUTILS-$(CONFIG_ECHO) += echo.o + COREUTILS-$(CONFIG_ENV) += env.o ++COREUTILS-$(CONFIG_EJECT) += eject.o + COREUTILS-$(CONFIG_EXPR) += expr.o + COREUTILS-$(CONFIG_FALSE) += false.o + COREUTILS-$(CONFIG_FOLD) += fold.o +Index: coreutils/eject.c +=================================================================== +RCS file: coreutils/eject.c +diff -N coreutils/eject.c +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ b/coreutils/eject.c 5 Mar 2004 07:23:21 -0000 +@@ -0,0 +1,66 @@ ++/* ++ * eject implementation for busybox ++ * ++ * Copyright (C) 2004 Peter Willis <psyphreak@phreaker.net> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++/* ++ * This is a simple hack of eject based on something Erik posted in #uclibc. ++ * Most of the dirty work blatantly ripped off from cat.c =) ++ */ ++ ++#include <stdio.h> ++#include <string.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <fcntl.h> ++#include <sys/ioctl.h> ++#include "busybox.h" ++#include <linux/cdrom.h> // needs to be after busybox.h or compile problems arise ++ ++#define DEFAULT_CDROM "/dev/cdrom" ++ ++extern int eject_main(int argc, char **argv) ++{ ++ int fd; ++ int flag = CDROMEJECT; ++ int i = 1; ++ char *device = NULL; ++ ++ /* ++ * i'm too lazy to learn bb_getopt_ulflags and this is obscenely large ++ * for just some argument parsing so mjn3 can clean it up later. ++ * sorry, but PlumpOS 7.0-pre2 needs this asap :-/ ++ */ ++ while (++i <= argc) { ++ if ( (! strncmp(argv[i-1],"-t",2)) || (! strncmp(argv[i-1],"--trayclose",11)) ) { ++ flag = CDROMCLOSETRAY; ++ } else { ++ device = argv[i-1]; ++ } ++ } ++ if ( (fd = open(device == NULL ? DEFAULT_CDROM : device, O_RDONLY | O_NONBLOCK) ) < 0 ) { ++ perror("eject: Can't open device"); ++ return(EXIT_FAILURE); ++ } ++ if (ioctl(fd, flag)) { ++ perror("eject: Can't eject cdrom"); ++ return(EXIT_FAILURE); ++ } ++ return EXIT_SUCCESS; ++} +Index: include/applets.h +=================================================================== +RCS file: /var/cvs/busybox/include/applets.h,v +retrieving revision 1.111 +diff -u -r1.111 applets.h +--- a/include/applets.h 27 Jan 2004 09:22:20 -0000 1.111 ++++ b/include/applets.h 5 Mar 2004 07:23:21 -0000 +@@ -178,6 +178,9 @@ + #if defined(CONFIG_FEATURE_GREP_EGREP_ALIAS) + APPLET_NOUSAGE("egrep", grep_main, _BB_DIR_BIN, _BB_SUID_NEVER) + #endif ++#ifdef CONFIG_EJECT ++ APPLET(eject, eject_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) ++#endif + #ifdef CONFIG_ENV + APPLET(env, env_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) + #endif +Index: include/usage.h +=================================================================== +RCS file: /var/cvs/busybox/include/usage.h,v +retrieving revision 1.191 +diff -u -r1.191 usage.h +--- a/include/usage.h 25 Feb 2004 10:35:55 -0000 1.191 ++++ b/include/usage.h 5 Mar 2004 07:23:29 -0000 +@@ -537,6 +537,13 @@ + "\t-, -i\tstart with an empty environment\n" \ + "\t-u\tremove variable from the environment\n" + ++#define eject_trivial_usage \ ++ "[-t] [FILE]" ++#define eject_full_usage \ ++ "Ejects the specified FILE or /dev/cdrom if FILE is unspecified.\n\n" \ ++ "Options:\n" \ ++ "\t-t, --trayclose \tclose tray\n" ++ + #define expr_trivial_usage \ + "EXPRESSION" + #define expr_full_usage \ diff --git a/busybox/patches/makdevs_table.diff b/busybox/patches/makdevs_table.diff new file mode 100644 index 0000000..1041608 --- /dev/null +++ b/busybox/patches/makdevs_table.diff @@ -0,0 +1,294 @@ +Index: include/usage.h +=================================================================== +RCS file: /var/cvs/busybox/include/usage.h,v +retrieving revision 1.211 +diff -u -r1.211 usage.h +--- a/include/usage.h 26 May 2004 22:09:37 -0000 1.211 ++++ b/include/usage.h 5 Jun 2004 07:51:26 -0000 +@@ -1536,6 +1536,7 @@ + #define lsmod_full_usage \ + "List the currently loaded kernel modules." + ++#ifdef CONFIG_FEATURE_MAKEDEVS_LEAF + #define makedevs_trivial_usage \ + "NAME TYPE MAJOR MINOR FIRST LAST [s]" + #define makedevs_full_usage \ +@@ -1555,6 +1556,18 @@ + "[creates ttyS2-ttyS63]\n" \ + "# makedevs /dev/hda b 3 0 0 8 s\n" \ + "[creates hda,hda1-hda8]\n" ++#endif ++ ++#ifdef CONFIG_FEATURE_MAKEDEVS_TABLE ++#define makedevs_trivial_usage \ ++ "[-r rootdir] [device_table]" ++#define makedevs_full_usage \ ++ "Creates a batch of special files as specified in a device table\n" \ ++ "The device table has one line per device group, each group is of\n" \ ++ "the format\n" \ ++ "\ttype mode user group major minor start increment count\n" \ ++ "a '-' may be used for blank entries\n" ++#endif + + #ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK + #define USAGE_MD5_SHA1_SUM_CHECK(a) a +Index: miscutils/Config.in +=================================================================== +RCS file: /var/cvs/busybox/miscutils/Config.in,v +retrieving revision 1.14 +diff -u -r1.14 Config.in +--- a/miscutils/Config.in 15 Mar 2004 08:28:46 -0000 1.14 ++++ b/miscutils/Config.in 5 Jun 2004 07:51:26 -0000 +@@ -143,10 +143,32 @@ + bool "makedevs" + default n + help +- 'makedevs' is a utility used and created by the Linux Router Project. +- It creates a large number of device special files (/dev devices) +- rather quickly, and can be considerably faster then running mknod a +- zillion times. ++ 'makedevs' is a utility used to create a batch of devices with ++ one command. ++ . ++ There are two choices for command line behaviour, the interface ++ as used by LEAF/Linux Router Project, or a device table file. ++ . ++ 'leaf' is traditionally what busybox follows, it allows multiple ++ devices of a particluar type to be created per command. ++ e.g. /dev/hda[0-9] ++ Device properties are passed as command line arguments. ++ . ++ 'table' reads device properties from a file or stdin, allowing ++ a batch of unrelated devices to be makde with one command. ++ User/group names are allowed as an alternative to uid/gid. ++ ++choice ++ prompt "Choose makedevs behaviour" ++ default CONFIG_FEATURE_MAKDEVS_TABLE ++ ++config CONFIG_FEATURE_MAKEDEVS_LEAF ++ bool "leaf" ++ ++config CONFIG_FEATURE_MAKEDEVS_TABLE ++ bool "table" ++ ++endchoice + + config CONFIG_MT + bool "mt" +Index: miscutils/makedevs.c +=================================================================== +RCS file: /var/cvs/busybox/miscutils/makedevs.c,v +retrieving revision 1.16 +diff -u -r1.16 makedevs.c +--- a/miscutils/makedevs.c 15 Mar 2004 08:28:46 -0000 1.16 ++++ b/miscutils/makedevs.c 5 Jun 2004 07:51:26 -0000 +@@ -1,20 +1,27 @@ + /* vi: set sw=4 ts=4: */ +-/* +- * public domain -- Dave 'Kill a Cop' Cinege <dcinege@psychosis.com> +- * +- * makedevs +- * Make ranges of device files quickly. +- * known bugs: can't deal with alpha ranges +- */ + ++#include <sys/types.h> ++ ++#include <fcntl.h> ++#include <getopt.h> + #include <stdio.h> + #include <stdlib.h> + #include <string.h> +-#include <fcntl.h> ++#include <time.h> + #include <unistd.h> +-#include <sys/types.h> ++ + #include "busybox.h" + ++#ifdef CONFIG_FEATURE_MAKEDEVS_LEAF ++ ++/* ++ * public domain -- Dave 'Kill a Cop' Cinege <dcinege@psychosis.com> ++ * ++ * makedevs ++ * Make ranges of device files quickly. ++ * known bugs: can't deal with alpha ranges ++ */ ++ + int makedevs_main(int argc, char **argv) + { + mode_t mode; +@@ -69,24 +76,153 @@ + return 0; + } + ++#elif defined CONFIG_FEATURE_MAKEDEVS_TABLE ++ + /* +-And this is what this program replaces. The shell is too slow! ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU Library General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ */ ++ ++static const struct option makedevs_long_options[] = { ++ {"root", 1, NULL, 'r'}, ++ {0, 0, 0, 0} ++}; + +-makedev () { +-local basedev=$1; local S=$2; local E=$3 +-local major=$4; local Sminor=$5; local type=$6 +-local sbase=$7 +- +- if [ ! "$sbase" = "" ]; then +- mknod "$basedev" $type $major $Sminor +- S=`expr $S + 1` +- Sminor=`expr $Sminor + 1` +- fi +- +- while [ $S -le $E ]; do +- mknod "$basedev$S" $type $major $Sminor +- S=`expr $S + 1` +- Sminor=`expr $Sminor + 1` +- done ++extern int makedevs_main(int argc, char **argv) ++{ ++ FILE *table; ++ int opt; ++ char *rootdir = "./"; ++ char *line; ++ int ret = EXIT_SUCCESS; ++ ++ bb_opt_complementaly = "d~r"; ++ bb_applet_long_options = makedevs_long_options; ++ opt = bb_getopt_ulflags(argc, argv, "d:r:", &rootdir, &rootdir); ++ ++ if (optind + 1 == argc) { ++ table = bb_xfopen(argv[optind], "r"); ++ } else { ++ table = stdin; ++ } ++ ++ if (chdir(rootdir) == -1) { ++ bb_perror_msg_and_die("Couldnt chdor to %s", rootdir); ++ } ++ ++ umask(0); ++ ++ while ((line = bb_get_chomped_line_from_file(table))) { ++ char type; ++ unsigned int mode = 0755; ++ unsigned int major = 0; ++ unsigned int minor = 0; ++ unsigned int count = 0; ++ unsigned int increment = 0; ++ unsigned int start = 0; ++ char name[41]; ++ char user[41]; ++ char group[41]; ++ char *full_name; ++ uid_t uid; ++ gid_t gid; ++ ++ if ((2 > sscanf(line, "%40s %c %o %40s %40s %u %u %u %u %u", name, ++ &type, &mode, user, group, &major, ++ &minor, &start, &increment, &count)) || ++ ((major | minor | start | count | increment) > 255)) { ++ bb_error_msg("Ignoring invalid line\n%s\n", line); ++ ret = EXIT_FAILURE; ++ continue; ++ } ++ if (name[0] == '#') { ++ continue; ++ } ++ if (group) { ++ gid = get_ug_id(group, my_getgrnam); ++ } else { ++ gid = getgid(); ++ } ++ if (user) { ++ uid = get_ug_id(user, my_getpwnam); ++ } else { ++ uid = getuid(); ++ } ++ full_name = concat_path_file(rootdir, name); ++ ++ if (type == 'd') { ++ bb_make_directory(full_name, mode | S_IFDIR, 0); ++ if (chown(full_name, uid, gid) == -1) { ++ bb_perror_msg("chown failed for %s", full_name); ++ ret = EXIT_FAILURE; ++ goto loop; ++ } ++ } else { ++ dev_t rdev; ++ ++ if (type == 'p') { ++ mode |= S_IFIFO; ++ } ++ else if (type == 'c') { ++ mode |= S_IFCHR; ++ } ++ else if (type == 'b') { ++ mode |= S_IFBLK; ++ } else { ++ bb_error_msg("Unsupported file type %c", type); ++ ret = EXIT_FAILURE; ++ goto loop; ++ } ++ ++ if (count > 0) { ++ int i; ++ char *full_name_inc; ++ ++ full_name_inc = xmalloc(strlen(full_name) + 4); ++ for (i = start; i < count; i++) { ++ sprintf(full_name_inc, "%s%d", full_name, i); ++ rdev = (major << 8) + minor + (i * increment - start); ++ if (mknod(full_name_inc, mode, rdev) == -1) { ++ bb_perror_msg("Couldnt create node %s", full_name_inc); ++ ret = EXIT_FAILURE; ++ } ++ else if (chown(full_name_inc, uid, gid) == -1) { ++ bb_perror_msg("chown failed for %s", full_name_inc); ++ ret = EXIT_FAILURE; ++ } ++ } ++ free(full_name_inc); ++ } else { ++ rdev = (major << 8) + minor; ++ if (mknod(full_name, mode, rdev) == -1) { ++ bb_perror_msg("Couldnt create node %s", full_name); ++ ret = EXIT_FAILURE; ++ } ++ else if (chown(full_name, uid, gid) == -1) { ++ bb_perror_msg("chown failed for %s", full_name); ++ ret = EXIT_FAILURE; ++ } ++ } ++ } ++loop: ++ free(line); ++ free(full_name); ++ } ++ fclose(table); ++ ++ return 0; + } +-*/ ++#else ++# error makdedevs configuration error, either leaf or table must be selected ++#endif diff --git a/busybox/patches/rpm2cpio_bzip2.patch b/busybox/patches/rpm2cpio_bzip2.patch new file mode 100644 index 0000000..151dd9f --- /dev/null +++ b/busybox/patches/rpm2cpio_bzip2.patch @@ -0,0 +1,63 @@ +diff -ur busybox/archival/Config.in busybox/archival/Config.in +--- busybox/archival/Config.in Sun May 23 09:15:37 2004 ++++ busybox/archival/Config.in Sun May 23 09:15:58 2004 +@@ -127,6 +127,14 @@ + help + Converts an RPM file into a CPIO archive. + ++config CONFIG_FEATURE_RPM2CPIO_BZIP2 ++ bool " Support bzip2 decompression" ++ default n ++ depends on CONFIG_RPM2CPIO ++ help ++ If you enable this option you'll be able to extract ++ rpms compressed with bzip2. ++ + config CONFIG_RPM + bool "rpm" + default n +diff -ur busybox/archival/libunarchive/Makefile.in busybox/archival/libunarchive/Makefile.in +--- busybox/archival/libunarchive/Makefile.in Sun May 23 09:15:04 2004 ++++ busybox/archival/libunarchive/Makefile.in Sun May 23 09:16:42 2004 +@@ -65,6 +65,7 @@ + LIBUNARCHIVE-$(CONFIG_GUNZIP) += $(GUNZIP_FILES) + LIBUNARCHIVE-$(CONFIG_FEATURE_GUNZIP_UNCOMPRESS) += decompress_uncompress.o + LIBUNARCHIVE-$(CONFIG_RPM2CPIO) += $(GUNZIP_FILES) get_header_cpio.o ++LIBUNARCHIVE-$(CONFIG_FEATURE_RPM2CPIO_BZIP2) += decompress_bunzip2.o + LIBUNARCHIVE-$(CONFIG_RPM) += $(GUNZIP_FILES) get_header_cpio.o + LIBUNARCHIVE-$(CONFIG_TAR) += get_header_tar.o + LIBUNARCHIVE-$(CONFIG_FEATURE_TAR_BZIP2) += decompress_bunzip2.o get_header_tar_bz2.o +diff -ur busybox/archival/rpm2cpio.c busybox/archival/rpm2cpio.c +--- busybox/archival/rpm2cpio.c Sun May 23 09:15:04 2004 ++++ busybox/archival/rpm2cpio.c Sun May 23 09:19:03 2004 +@@ -91,14 +91,26 @@ + skip_header(rpm_fd); + + bb_xread_all(rpm_fd, &magic, 2); +- if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { +- bb_error_msg_and_die("Invalid gzip magic"); ++ if ((magic[0] == 0x1f) || (magic[1] == 0x8b)) { ++ check_header_gzip(rpm_fd); ++ if (inflate_gunzip(rpm_fd, fileno(stdout)) != 0) ++ bb_error_msg("Error inflating (gzip)"); + } + +- check_header_gzip(rpm_fd); +- if (inflate_gunzip(rpm_fd, STDOUT_FILENO) != 0) { +- bb_error_msg("Error inflating"); ++ if ((magic[0] == 'B') && (magic[1] == 'Z')) { ++#ifdef CONFIG_FEATURE_RPM2CPIO_BZIP2 ++ /* return to position before magic (eek..!) */ ++ lseek(rpm_fd, -2, SEEK_CUR); ++ if(uncompressStream(rpm_fd, fileno(stdout)) != 0) ++ bb_error_msg("Error inflating (bzip2)"); ++#else ++ bb_error_msg_and_die("bzip2 not supported"); ++#endif + } ++ ++ else ++ bb_error_msg_and_die("not gzip or bzip2 compressed"); ++ + + close(rpm_fd); diff --git a/busybox/patches/tftp_timeout_multicast.diff b/busybox/patches/tftp_timeout_multicast.diff new file mode 100644 index 0000000..ca431fc --- /dev/null +++ b/busybox/patches/tftp_timeout_multicast.diff @@ -0,0 +1,1053 @@ +Index: AUTHORS +=================================================================== +RCS file: /var/cvs/busybox/AUTHORS,v +retrieving revision 1.40 +diff -u -r1.40 AUTHORS +--- a/AUTHORS 9 Oct 2003 21:19:21 -0000 1.40 ++++ b/AUTHORS 5 Mar 2004 15:45:47 -0000 +@@ -92,6 +92,9 @@ + Original author of BusyBox in 1995, 1996. Some of his code can + still be found hiding here and there... + ++John Powers <jpp@ti.com> ++ Added multicast option (rfc2090) and timeout option (rfc2349) to tftp. ++ + Tim Riker <Tim@Rikers.org> + bug fixes, member of fan club + +Index: include/usage.h +=================================================================== +RCS file: /var/cvs/busybox/include/usage.h,v +retrieving revision 1.191 +diff -u -r1.191 usage.h +--- a/include/usage.h 25 Feb 2004 10:35:55 -0000 1.191 ++++ b/include/usage.h 5 Mar 2004 15:45:59 -0000 +@@ -2492,6 +2492,21 @@ + #else + #define USAGE_TFTP_BS(a) + #endif ++#ifdef CONFIG_FEATURE_TFTP_TIMEOUT ++ #define USAGE_TFTP_TIMEOUT(a) a ++#else ++ #define USAGE_TFTP_TIMEOUT(a) ++#endif ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ #define USAGE_TFTP_MULTICAST(a) a ++#else ++ #define USAGE_TFTP_MULTICAST(a) ++#endif ++#ifdef CONFIG_FEATURE_TFTP_DEBUG ++ #define USAGE_TFTP_DEBUG(a) a ++#else ++ #define USAGE_TFTP_DEBUG(a) ++#endif + + #define tftp_trivial_usage \ + "[OPTION]... HOST [PORT]" +@@ -2508,6 +2523,16 @@ + ) \ + USAGE_TFTP_BS( \ + "\t-b SIZE\tTransfer blocks of SIZE octets.\n" \ ++ ) \ ++ USAGE_TFTP_TIMEOUT( \ ++ "\t-T SEC\tClient timeout SEC seconds (default: 5).\n" \ ++ "\t-t SEC\tServer timeout SEC seconds\n" \ ++ ) \ ++ USAGE_TFTP_MULTICAST( \ ++ "\t-m\tMulticast get file.\n" \ ++ ) \ ++ USAGE_TFTP_DEBUG( \ ++ "\t-D\tPrint debug messages.\n" \ + ) + #define time_trivial_usage \ + "[OPTION]... COMMAND [ARGS...]" +Index: networking/Config.in +=================================================================== +RCS file: /var/cvs/busybox/networking/Config.in,v +retrieving revision 1.27 +diff -u -r1.27 Config.in +--- a/networking/Config.in 22 Feb 2004 12:25:47 -0000 1.27 ++++ b/networking/Config.in 5 Mar 2004 15:45:59 -0000 +@@ -522,6 +522,13 @@ + Add support for the GET command within the TFTP client. This allows + a client to retrieve a file from a TFTP server. + ++config CONFIG_FEATURE_TFTP_MULTICAST ++ bool " Enable \"multicast\" option" ++ default n ++ depends on CONFIG_FEATURE_TFTP_GET ++ help ++ Allow the client to receive multicast file transfers. ++ + config CONFIG_FEATURE_TFTP_PUT + bool " Enable \"put\" command" + default y +@@ -531,12 +538,19 @@ + a client to transfer a file to a TFTP server. + + config CONFIG_FEATURE_TFTP_BLOCKSIZE +- bool " Enable \"blocksize\" command" ++ bool " Enable \"blksize\" option" + default n + depends on CONFIG_TFTP + help + Allow the client to specify the desired block size for transfers. + ++config CONFIG_FEATURE_TFTP_TIMEOUT ++ bool " Enable \"timeout\" option" ++ default n ++ depends on CONFIG_TFTP ++ help ++ Allow the client to negotiate timeout option with server. ++ + config CONFIG_FEATURE_TFTP_DEBUG + bool " Enable debug" + default n +Index: networking/tftp.c +=================================================================== +RCS file: /var/cvs/busybox/networking/tftp.c,v +retrieving revision 1.25 +diff -u -r1.25 tftp.c +--- a/networking/tftp.c 5 Mar 2004 13:04:39 -0000 1.25 ++++ b/networking/tftp.c 5 Mar 2004 15:46:00 -0000 +@@ -1,11 +1,26 @@ ++/* vi: set sw=4 ts=4: */ + /* ------------------------------------------------------------------------- */ + /* tftp.c */ ++/* Copyright (c) 2003, 2004 Texas Instruments */ ++/* */ ++/* This package is free software; you can redistribute it and/or */ ++/* modify it under the terms of the license found in the file */ ++/* named COPYING that should have accompanied this file. */ ++/* */ ++/* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ ++/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ ++/* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ + /* */ + /* A simple tftp client for busybox. */ + /* Tries to follow RFC1350. */ + /* Only "octet" mode supported. */ + /* Optional blocksize negotiation (RFC2347 + RFC2348) */ + /* */ ++/* New features added at Texas Instruments, October 2003 */ ++/* Author: John Powers */ ++/* Multicast option: rfc2090 */ ++/* Timeout option: rfc2349 */ ++/* */ + /* Copyright (C) 2001 Magnus Damm <damm@opensource.se> */ + /* */ + /* Parts of the code based on: */ +@@ -46,8 +61,20 @@ + + #include "busybox.h" + ++#if defined(CONFIG_FEATURE_TFTP_BLOCKSIZE) || defined(CONFIG_FEATURE_TFTP_MULTICAST) || defined(CONFIG_FEATURE_TFTP_TIMEOUT) ++ #define TFTP_OPTIONS ++#endif ++ + //#define CONFIG_FEATURE_TFTP_DEBUG + ++#ifdef CONFIG_FEATURE_TFTP_DEBUG ++ static void printtime(void); ++ #define dprintf(fmt...) if (debug) {printtime(); printf(fmt);} ++ int debug = 0; ++#else ++ #define dprintf(fmt...) ++#endif ++ + #define TFTP_BLOCKSIZE_DEFAULT 512 /* according to RFC 1350, don't change */ + #define TFTP_TIMEOUT 5 /* seconds */ + +@@ -68,12 +95,24 @@ + "Illegal TFTP operation", + "Unknown transfer ID", + "File already exists", +- "No such user" ++ "No such user", ++#ifdef TFTP_OPTIONS ++ "Unsupported option", ++#endif + }; + + const int tftp_cmd_get = 1; + const int tftp_cmd_put = 2; + ++ ++struct tftp_option { ++ int multicast; ++ int blksize; ++ int client_timeout; ++ int server_timeout; ++}; ++ ++ + #ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE + + static int tftp_blocksize_check(int blocksize, int bufsize) +@@ -93,16 +132,158 @@ + return blocksize; + } + ++#endif ++ ++#ifdef CONFIG_FEATURE_TFTP_TIMEOUT ++ ++static int ++tftp_timeout_check(int timeout) ++{ ++ /* Check if timeout seconds is valid: ++ * RFC2349 says between 1 and 255. ++ */ ++ ++ if (timeout < 1 || timeout > 255) { ++ bb_error_msg("bad timeout value"); ++ return 0; ++ } ++ return timeout; ++} ++ ++#endif ++ ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++static int ++tftp_multicast_check(const char *opt, char **phost, unsigned short *pport, int *pactive) ++{ ++ /* Option string contains comma delimited addr,port,active. ++ * addr = multicast IP address ++ * port = port number ++ * active = 1 if active client ++ * 0 if passive client ++ * ++ * Addr and port will be empty fields when the server notifies a ++ * passive client that it is now the active client. ++ * ++ * The host address string must be freed by the caller. Neither host ++ * nor port will be set/changed if the input fields are empty. ++ * ++ * If any tokenization errors occur in the opt string, the host ++ * address string is automatically freed. ++ * ++ * Return 0 if any tokenization error, 1 if all parameters are good. ++ */ ++ ++ char *token = NULL; ++ char *parse_buf = NULL; ++ char *tokenv = NULL; ++ char *host = NULL; ++ int port; ++ int active; ++ ++ parse_buf = bb_xstrdup(opt); ++ ++ dprintf("multicast option=%s\n", opt); ++ ++ /* IP address */ ++ if ((token = strtok_r(parse_buf, ",", &tokenv)) == NULL) { ++ dprintf("tftp_multicast_check: cannot parse IP address from %s\n", parse_buf); ++ free(parse_buf); ++ return 0; ++ } ++ if (strlen(token) > 0) ++ *phost = host = bb_xstrdup(token); ++ ++ /* Port */ ++ if ((token = strtok_r(NULL, ",", &tokenv)) == NULL) { ++ dprintf("tftp_multicast_check: cannot parse port number from %s\n", tokenv); ++ goto token_error; ++ } ++ if (strlen(token) > 0) { ++ port = atoi(token); ++ if (port < 0 || port > 0xFFFF) { ++ dprintf("tftp_multicast_check: bad port number (%d)\n", port); ++ goto token_error; ++ } ++ *pport = htons(port); ++ } ++ ++ /* Active/passive */ ++ if ((token = strtok_r(NULL, ",", &tokenv)) == NULL) { ++ dprintf("tftp_multicast_check: cannot parse active/passive from %s\n", tokenv); ++ goto token_error; ++ } ++ active = atoi(token); ++ if (active != 0 && active != 1) { ++ dprintf("tftp_multicast_check: bad active/passive flag (%d)\n", active); ++ goto token_error; ++ } ++ *pactive = active; ++ ++ free(parse_buf); ++ return 1; ++ ++token_error: ++ free(parse_buf); ++ if (host != NULL) ++ free(host); ++ *phost = NULL; ++ return 0; ++ ++} ++ ++#define VECTOR_QUANTUM_WIDTH 8 ++#define VECTOR_QUANTUM_ALL_ONES ((1<<VECTOR_QUANTUM_WIDTH)-1) ++ ++static void inline ++bit_set(int bit, unsigned char *vector) ++{ ++ int offset = bit / VECTOR_QUANTUM_WIDTH; ++ int mask = 1 << (bit % VECTOR_QUANTUM_WIDTH); ++ vector[offset] |= mask; ++} ++ ++static int inline ++bit_isset(int bit, const unsigned char *vector) ++{ ++ int offset = bit / VECTOR_QUANTUM_WIDTH; ++ int mask = 1 << (bit % VECTOR_QUANTUM_WIDTH); ++ return vector[offset] & mask ? 1 : 0; ++} ++ ++static int inline ++bit_lmz(const unsigned char *vector) ++{ ++ /* Return number of left-most zero in bit vector */ ++ const unsigned char *vp = vector; ++ int i; ++ unsigned char velem; ++ ++ while (*vp == VECTOR_QUANTUM_ALL_ONES) ++ vp++; ++ velem = *vp; ++ for (i = 0; i < VECTOR_QUANTUM_WIDTH; i++) { ++ if ((velem & (1 << i)) == 0) ++ break; ++ } ++ dprintf("bit_lmz: block=%d\n", (vp - vector)*VECTOR_QUANTUM_WIDTH + i); ++ return (vp - vector)*VECTOR_QUANTUM_WIDTH + i; ++} ++ ++#endif ++ ++ ++ ++#ifdef TFTP_OPTIONS ++ + static char *tftp_option_get(char *buf, int len, char *option) + { +- int opt_val = 0; ++ int opt_val = 0; + int opt_found = 0; + int k; +- +- while (len > 0) { + ++ while (len > 0) { + /* Make sure the options are terminated correctly */ +- + for (k = 0; k < len; k++) { + if (buf[k] == '\0') { + break; +@@ -117,9 +298,8 @@ + if (strcasecmp(buf, option) == 0) { + opt_found = 1; + } +- } +- else { +- if (opt_found) { ++ } else { ++ if (opt_found) { + return buf; + } + } +@@ -138,7 +318,8 @@ + #endif + + static inline int tftp(const int cmd, const struct hostent *host, +- const char *remotefile, int localfd, const unsigned short port, int tftp_bufsize) ++ const char *remotefile, int localfd, const unsigned short port, ++ struct tftp_option *option) + { + const int cmd_get = cmd & tftp_cmd_get; + const int cmd_put = cmd & tftp_cmd_put; +@@ -155,18 +336,29 @@ + int len; + int opcode = 0; + int finished = 0; +- int timeout = bb_tftp_num_retries; ++ int retry = bb_tftp_num_retries; + unsigned short block_nr = 1; + +-#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE +- int want_option_ack = 0; ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ struct hostent *mchost; ++ struct sockaddr_in mcsa; ++ char *mchostname; ++ unsigned short mcport; ++ unsigned char *mcblockmap = NULL; ++ int master_client = 1; ++ int mcfd = -1; ++ int mcmaxblock = 0x10000; ++ int ack_oack = 0; ++#else ++ #define master_client 1 ++ #define ack_oack 0 + #endif + + /* Can't use RESERVE_CONFIG_BUFFER here since the allocation + * size varies meaning BUFFERS_GO_ON_STACK would fail */ +- char *buf=xmalloc(tftp_bufsize + 4); ++ char *buf=xmalloc(option->blksize + 4); + +- tftp_bufsize += 4; ++ int tftp_bufsize = option->blksize + 4; + + if ((socketfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + bb_perror_msg("socket"); +@@ -183,15 +375,21 @@ + memcpy(&sa.sin_addr, (struct in_addr *) host->h_addr, + sizeof(sa.sin_addr)); + +- /* build opcode */ +- +- if (cmd_get) { +- opcode = TFTP_RRQ; ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ if (option->multicast) { ++ const int bmsize = 0x10000 / VECTOR_QUANTUM_WIDTH; ++ if ((mcfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { ++ bb_perror_msg("multicast socket"); ++ return EXIT_FAILURE; ++ } ++ mcblockmap = xmalloc(bmsize+1); ++ memset(mcblockmap, 0, bmsize+1); + } ++#endif + +- if (cmd_put) { +- opcode = TFTP_WRQ; +- } ++ /* build opcode */ ++ ++ opcode = cmd_get ? TFTP_RRQ : TFTP_WRQ; + + while (1) { + +@@ -203,7 +401,7 @@ + + cp += 2; + +- /* add filename and mode */ ++ /* First packet of file transfer includes file name, mode, and options */ + + if ((cmd_get && (opcode == TFTP_RRQ)) || + (cmd_put && (opcode == TFTP_WRQ))) { +@@ -223,7 +421,7 @@ + } + + if (too_long || ((&buf[tftp_bufsize - 1] - cp) < 6)) { +- bb_error_msg("too long remote-filename"); ++ bb_error_msg("too long: remote filename"); + break; + } + +@@ -238,8 +436,8 @@ + + if (len != TFTP_BLOCKSIZE_DEFAULT) { + +- if ((&buf[tftp_bufsize - 1] - cp) < 15) { +- bb_error_msg("too long remote-filename"); ++ if ((&buf[tftp_bufsize - 1] - cp) < 15) { ++ bb_error_msg("buffer too small for blksize option"); + break; + } + +@@ -249,16 +447,65 @@ + cp += 8; + + cp += snprintf(cp, 6, "%d", len) + 1; ++ } ++#endif ++ ++ ++ ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ ++ if (option->multicast) { ++ if ((&buf[tftp_bufsize - 1] - cp) < 12) { ++ bb_error_msg("buffer too small for multicast option"); ++ break; ++ } ++ ++ /* add "multicast" option */ + +- want_option_ack = 1; ++ memcpy(cp, "multicast\0", 11); ++ cp += 11; ++ ++ option->multicast = 0; /* turn back on when server accepts option */ ++ ack_oack = 1; /* acknowledge OACK */ + } ++ + #endif ++ ++#ifdef CONFIG_FEATURE_TFTP_TIMEOUT ++ ++ if (option->server_timeout != TFTP_TIMEOUT) { ++ if ((&buf[tftp_bufsize - 1] - cp) < 12) { ++ bb_error_msg("buffer too small for timeout option"); ++ break; ++ } ++ ++ /* add "timeout" option */ ++ ++ memcpy(cp, "timeout", 8); ++ cp += 8; ++ ++ cp += snprintf(cp, 4, "%d", option->server_timeout) + 1; ++ } ++#endif ++ + } + + /* add ack and data */ + +- if ((cmd_get && (opcode == TFTP_ACK)) || +- (cmd_put && (opcode == TFTP_DATA))) { ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ else if (option->multicast && opcode == TFTP_ACK) { ++ if (master_client || ack_oack) { ++ int blocknum = bit_lmz(mcblockmap); ++ *((unsigned short *) cp) = htons(blocknum); ++ cp += 2; ++ if (blocknum >= mcmaxblock) ++ finished = 1; ++ dprintf("ack block %d/%d %s\n", blocknum, mcmaxblock, finished? "finished": ""); ++ } ++ } ++#endif ++ else if ((cmd_get && opcode == TFTP_ACK) || ++ (cmd_put && opcode == TFTP_DATA)) { + + *((unsigned short *) cp) = htons(block_nr); + +@@ -275,7 +522,7 @@ + } + + if (len != (tftp_bufsize - 4)) { +- finished++; ++ finished = 1; + } + + cp += len; +@@ -283,82 +530,119 @@ + } + + +- /* send packet */ ++ /* send packet and receive reply */ + + +- timeout = bb_tftp_num_retries; /* re-initialize */ ++ retry = bb_tftp_num_retries; /* re-initialize */ + do { +- ++ int selectrc; + len = cp - buf; + +-#ifdef CONFIG_FEATURE_TFTP_DEBUG +- fprintf(stderr, "sending %u bytes\n", len); +- for (cp = buf; cp < &buf[len]; cp++) +- fprintf(stderr, "%02x ", (unsigned char)*cp); +- fprintf(stderr, "\n"); +-#endif +- if (sendto(socketfd, buf, len, 0, +- (struct sockaddr *) &sa, sizeof(sa)) < 0) { +- bb_perror_msg("send"); +- len = -1; +- break; +- } +- ++ /* send packet */ ++ if ((len > 2) && (! option->multicast || master_client || ack_oack)) { + +- if (finished && (opcode == TFTP_ACK)) { +- break; ++#ifdef CONFIG_FEATURE_TFTP_DEBUG ++ dprintf("sending %u bytes\n", len); ++ for (cp = buf; cp < &buf[len]; cp++) ++ if (debug) ++ printf("%02x ", *(unsigned char *)cp); ++ if (debug) ++ printf("\n"); ++#endif ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ ack_oack = 0; ++#endif ++ if (sendto(socketfd, buf, len, 0, (struct sockaddr *) &sa, sizeof(sa)) < 0) { ++ bb_perror_msg("send"); ++ len = -1; ++ break; ++ } ++ if (finished && opcode == TFTP_ACK) { ++ break; ++ } + } + +- /* receive packet */ ++ /* receive reply packet */ + + memset(&from, 0, sizeof(from)); + fromlen = sizeof(from); + +- tv.tv_sec = TFTP_TIMEOUT; ++ tv.tv_sec = option->client_timeout; + tv.tv_usec = 0; + + FD_ZERO(&rfds); + FD_SET(socketfd, &rfds); ++ dprintf("set to receive from socketfd (%d)\n", socketfd); ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ if (option->multicast) { ++ FD_SET(mcfd, &rfds); ++ dprintf("set to receive from mcfd (%d)\n", mcfd); ++ } ++#endif + +- switch (select(FD_SETSIZE, &rfds, NULL, NULL, &tv)) { +- case 1: +- len = recvfrom(socketfd, buf, tftp_bufsize, 0, +- (struct sockaddr *) &from, &fromlen); +- +- if (len < 0) { +- bb_perror_msg("recvfrom"); +- break; ++ dprintf("select\n"); ++ selectrc = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); ++ if (selectrc > 0) { ++ /* A packet was received */ ++ if (FD_ISSET(socketfd, &rfds)) { /* Unicast packet */ ++ dprintf("from socketfd\n"); ++ len = recvfrom(socketfd, buf, tftp_bufsize, 0, (struct sockaddr *) &from, &fromlen); ++ ++ if (len < 0) { ++ bb_perror_msg("recvfrom"); ++ } else { ++ if (sa.sin_port == port) { ++ sa.sin_port = from.sin_port; ++ } ++ if (sa.sin_port == from.sin_port) { ++ retry = 0; ++ } else { ++ /* bad packet */ ++ /* discard the packet - treat as timeout */ ++ retry = bb_tftp_num_retries; ++ bb_error_msg("timeout"); ++ } ++ } + } + +- timeout = 0; +- +- if (sa.sin_port == port) { +- sa.sin_port = from.sin_port; ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ else if (option->multicast && FD_ISSET(mcfd, &rfds)) { /* Multicast packet */ ++ dprintf("from mcfd\n"); ++ len = recvfrom(mcfd, buf, tftp_bufsize, 0, (struct sockaddr *) &from, &fromlen); ++ if (len < 0) { ++ bb_perror_msg("multicast recvfrom"); ++ } else { ++ if (mcsa.sin_port == mcport) { ++ mcsa.sin_port = from.sin_port; ++ } ++ if (mcsa.sin_port == from.sin_port) { ++ retry = 0; ++ } else { ++ retry = bb_tftp_num_retries; ++ bb_error_msg("multicast timeout"); ++ } ++ } + } +- if (sa.sin_port == from.sin_port) { +- break; +- } +- +- /* fall-through for bad packets! */ +- /* discard the packet - treat as timeout */ +- timeout = bb_tftp_num_retries; ++#endif + +- case 0: ++ } else if (selectrc == 0) { ++ /* Time out */ ++ dprintf("timeout\n"); + bb_error_msg("timeout"); + +- timeout--; +- if (timeout == 0) { ++ retry--; ++ if (retry == 0) { + len = -1; + bb_error_msg("last timeout"); + } +- break; +- +- default: ++ } else { ++ /* Error condition */ ++ dprintf("error\n"); + bb_perror_msg("select"); + len = -1; + } + +- } while (timeout && (len >= 0)); ++ } while (retry && len >= 0); + + if ((finished) || (len < 0)) { + break; +@@ -370,9 +654,8 @@ + opcode = ntohs(*((unsigned short *) buf)); + tmp = ntohs(*((unsigned short *) &buf[2])); + +-#ifdef CONFIG_FEATURE_TFTP_DEBUG +- fprintf(stderr, "received %d bytes: %04x %04x\n", len, opcode, tmp); +-#endif ++ dprintf("received %d bytes: %04x %04x\n", len, opcode, tmp); ++ dprintf("master_client=%d\n", master_client); + + if (opcode == TFTP_ERROR) { + char *msg = NULL; +@@ -393,55 +676,116 @@ + break; + } + +-#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE +- if (want_option_ack) { ++#ifdef TFTP_OPTIONS + +- want_option_ack = 0; ++ if (opcode == TFTP_OACK) { + +- if (opcode == TFTP_OACK) { ++ /* server seems to support options */ + +- /* server seems to support options */ ++ char *res; ++ ++ block_nr = 0; /* acknowledge option packet with block number 0 */ ++ opcode = cmd_put ? TFTP_DATA : TFTP_ACK; + +- char *res; + +- res = tftp_option_get(&buf[2], len-2, +- "blksize"); ++#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE ++ res = tftp_option_get(&buf[2], len-2, "blksize"); + +- if (res) { +- int blksize = atoi(res); +- +- if (tftp_blocksize_check(blksize, +- tftp_bufsize - 4)) { ++ if (res) { ++ int blksize = atoi(res); + +- if (cmd_put) { +- opcode = TFTP_DATA; +- } +- else { +- opcode = TFTP_ACK; +- } +-#ifdef CONFIG_FEATURE_TFTP_DEBUG +- fprintf(stderr, "using blksize %u\n", blksize); ++ if (tftp_blocksize_check(blksize, tftp_bufsize - 4)) { ++ dprintf("using blksize %d\n", blksize); ++ tftp_bufsize = blksize + 4; ++ free(buf); ++ buf = xmalloc(tftp_bufsize); ++ } else { ++ bb_error_msg("bad blksize %d", blksize); ++ break; ++ } ++ } + #endif +- tftp_bufsize = blksize + 4; +- block_nr = 0; +- continue; +- } +- } +- /* FIXME: +- * we should send ERROR 8 */ +- bb_error_msg("bad server option"); +- break; +- } + +- bb_error_msg("warning: blksize not supported by server" +- " - reverting to 512"); + +- tftp_bufsize = TFTP_BLOCKSIZE_DEFAULT + 4; ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ res = tftp_option_get(&buf[2], len-2, "multicast"); ++ ++ if (res) { ++ ack_oack = 1; ++ if (tftp_multicast_check(res, &mchostname, &mcport, &master_client)) { ++ struct ip_mreq mreq; ++ struct in_addr mcaddr; ++ ++ dprintf("using multicast\n"); ++ ++ mchost = xgethostbyname(mchostname); ++ if (mchost) { ++ memcpy(&mcaddr, mchost->h_addr, mchost->h_length); ++ if (! IN_MULTICAST(ntohl(mcaddr.s_addr))) { ++ bb_error_msg("bad multicast address: %s", mchostname); ++ break; ++ } ++ } else { ++ bb_error_msg("bad multicast address: %s", mchostname); ++ break; ++ } ++ ++ memset(&mcsa, 0, sizeof(mcsa)); ++ mcsa.sin_family = AF_INET; ++ mcsa.sin_addr.s_addr = htonl(INADDR_ANY); ++ mcsa.sin_port = mcport; ++ ++ bind(mcfd, (struct sockaddr *)&mcsa, sizeof(mcsa)); ++ ++ mreq.imr_multiaddr.s_addr = mcaddr.s_addr; ++ mreq.imr_interface.s_addr = htonl(INADDR_ANY); ++ ++ if (setsockopt(mcfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) ++ { ++ bb_error_msg("setsockopt"); ++ break; ++ } ++ ++ option->multicast = 1; ++ } else { ++ bb_error_msg("bad multicast option value: %s", res); ++ break; ++ } ++ } ++#endif ++ + } ++ else + #endif + + if (cmd_get && (opcode == TFTP_DATA)) { + ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ if (option->multicast) { ++ int bn = tmp - 1; ++ /* Do I need this block? */ ++ if (! bit_isset(bn, mcblockmap)) { ++ lseek(localfd, bn*(tftp_bufsize-4), SEEK_SET); ++ len = write(localfd, &buf[4], len-4); ++ if (len < 0) { ++ bb_perror_msg("write"); ++ break; ++ } ++ bit_set(bn, mcblockmap); ++ if (len != (tftp_bufsize-4)) { ++ mcmaxblock = tmp; ++ dprintf("mcmaxblock=%d, (len(%d) != tftp_bufsize-4(%d))\n", mcmaxblock, len, tftp_bufsize-4); ++ } ++ opcode = TFTP_ACK; ++ } ++ /* Do not acknowledge block if I already have a copy of the block. A situation can arise when the server ++ * and client timeout nearly simultaneously. The server retransmits the block at the same time the client ++ * re-requests the block. From then on out, each block is transmitted twice--not a good use of bandwidth. ++ */ ++ } ++ else ++#endif ++ + if (tmp == block_nr) { + + len = write(localfd, &buf[4], len - 4); +@@ -452,15 +796,14 @@ + } + + if (len != (tftp_bufsize - 4)) { +- finished++; ++ finished = 1; + } + + opcode = TFTP_ACK; +- continue; + } + } + +- if (cmd_put && (opcode == TFTP_ACK)) { ++ else if (cmd_put && opcode == TFTP_ACK) { + + if (tmp == (unsigned short)(block_nr - 1)) { + if (finished) { +@@ -468,15 +811,19 @@ + } + + opcode = TFTP_DATA; +- continue; + } + } + } + + #ifdef CONFIG_FEATURE_CLEAN_UP + close(socketfd); ++ free(buf); ++ ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ if (mcblockmap != NULL) ++ free(mcblockmap); ++#endif + +- free(buf); + #endif + + return finished ? EXIT_SUCCESS : EXIT_FAILURE; +@@ -487,13 +834,18 @@ + struct hostent *host = NULL; + char *localfile = NULL; + char *remotefile = NULL; +- int port; ++ unsigned short port; + int cmd = 0; + int fd = -1; + int flags = 0; + int opt; + int result; +- int blocksize = TFTP_BLOCKSIZE_DEFAULT; ++ struct tftp_option option = { ++ .multicast = 0, ++ .blksize = TFTP_BLOCKSIZE_DEFAULT, ++ .client_timeout = TFTP_TIMEOUT, ++ .server_timeout = TFTP_TIMEOUT, ++ }; + + /* figure out what to pass to getopt */ + +@@ -515,13 +867,45 @@ + #define PUT + #endif + +- while ((opt = getopt(argc, argv, BS GET PUT "l:r:")) != -1) { ++#ifdef CONFIG_FEATURE_TFTP_TIMEOUT ++#define TO "T:t:" ++#else ++#define TO ++#endif ++ ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++#define MC "m" ++#else ++#define MC ++#endif ++ ++#ifdef CONFIG_FEATURE_TFTP_DEBUG ++#define DB "D" ++#else ++#define DB ++#endif ++ ++ while ((opt = getopt(argc, argv, BS GET PUT TO MC DB "l:r:")) != -1) { + switch (opt) { + #ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE + case 'b': +- blocksize = atoi(optarg); +- if (!tftp_blocksize_check(blocksize, 0)) { +- return EXIT_FAILURE; ++ option.blksize = atoi(optarg); ++ if (!tftp_blocksize_check(option.blksize, 0)) { ++ return EXIT_FAILURE; ++ } ++ break; ++#endif ++#ifdef CONFIG_FEATURE_TFTP_TIMEOUT ++ case 'T': ++ option.client_timeout = atoi(optarg); ++ if (!tftp_timeout_check(option.client_timeout)) { ++ return EXIT_FAILURE; ++ } ++ break; ++ case 't': ++ option.server_timeout = atoi(optarg); ++ if (!tftp_timeout_check(option.server_timeout)) { ++ return EXIT_FAILURE; + } + break; + #endif +@@ -537,18 +921,34 @@ + flags = O_RDONLY; + break; + #endif ++#ifdef CONFIG_FEATURE_TFTP_MULTICAST ++ case 'm': ++ option.multicast = 1; /* receive multicast file */ ++ break; ++#endif ++#ifdef CONFIG_FEATURE_TFTP_DEBUG ++ case 'D': ++ debug = 1; ++ break; ++#endif + case 'l': + localfile = bb_xstrdup(optarg); + break; + case 'r': + remotefile = bb_xstrdup(optarg); + break; ++ default: ++ bb_show_usage(); + } + } + + if ((cmd == 0) || (optind == argc)) { + bb_show_usage(); + } ++ if (cmd == tftp_cmd_put && option.multicast) { ++ fprintf(stderr, "Multicast (-m) invalid option with put (-p) command\n"); ++ exit(EXIT_FAILURE); ++ } + if(localfile && strcmp(localfile, "-") == 0) { + fd = fileno((cmd==tftp_cmd_get)? stdout : stdin); + } +@@ -566,14 +966,12 @@ + host = xgethostbyname(argv[optind]); + port = bb_lookup_port(argv[optind + 1], "udp", 69); + +-#ifdef CONFIG_FEATURE_TFTP_DEBUG +- fprintf(stderr, "using server \"%s\", remotefile \"%s\", " ++ dprintf("using server \"%s\", remotefile \"%s\", " + "localfile \"%s\".\n", + inet_ntoa(*((struct in_addr *) host->h_addr)), + remotefile, localfile); +-#endif + +- result = tftp(cmd, host, remotefile, fd, port, blocksize); ++ result = tftp(cmd, host, remotefile, fd, port, &option); + + #ifdef CONFIG_FEATURE_CLEAN_UP + if (!(fd == STDOUT_FILENO || fd == STDIN_FILENO)) { +@@ -582,3 +980,18 @@ + #endif + return(result); + } ++ ++ ++#ifdef CONFIG_FEATURE_TFTP_DEBUG ++ ++#include <sys/time.h> ++ ++static void ++printtime(void) ++{ ++ struct timeval tv; ++ gettimeofday(&tv, NULL); ++ printf("%11lu.%06lu ", tv.tv_sec, tv.tv_usec); ++} ++ ++#endif diff --git a/busybox/patches/top_system_cpu.diff b/busybox/patches/top_system_cpu.diff new file mode 100644 index 0000000..5d213e7 --- /dev/null +++ b/busybox/patches/top_system_cpu.diff @@ -0,0 +1,51 @@ +diff -purN busybox.ori/include/libbb.h busybox/include/libbb.h +--- busybox.ori/include/libbb.h 2004-03-21 14:39:35.000000000 +0100 ++++ busybox-1.0/include/libbb.h 2004-03-21 14:45:35.000000000 +0100 +@@ -447,6 +447,7 @@ typedef struct { + int ppid; + #ifdef FEATURE_CPU_USAGE_PERCENTAGE + unsigned pcpu; ++ unsigned pscpu; + unsigned long stime, utime; + #endif + char *cmd; +diff -purN busybox.ori/procps/top.c busybox/procps/top.c +--- busybox.ori/procps/top.c 2004-03-21 14:40:09.000000000 +0100 ++++ busybox-1.0/procps/top.c 2004-03-21 17:27:52.961951448 +0100 +@@ -289,6 +289,15 @@ static void do_stats(void) + i = 999; + cur->pcpu = i; + ++ /* ++ * Calculate percent of system time from cpu time ++ */ ++ if (systime != 0) { ++ cur->pscpu = 100 * total_time / systime; ++ } else { ++ cur->pscpu = 0; ++ } ++ + } + + /* +@@ -393,7 +402,7 @@ static void display_status(int count, in + + #ifdef FEATURE_CPU_USAGE_PERCENTAGE + /* what info of the processes is shown */ +- printf("\n\e[7m PID USER STATUS RSS PPID %%CPU %%MEM COMMAND\e[0m\n"); ++ printf("\n\e[7m PID USER STATUS RSS PPID %%CPU %%SCPU %%MEM COMMAND\e[0m\n"); + #else + printf("\n\e[7m PID USER STATUS RSS PPID %%MEM COMMAND\e[0m\n"); + #endif +@@ -410,9 +419,9 @@ static void display_status(int count, in + else + sprintf(rss_str_buf, "%7ld", s->rss); + #ifdef FEATURE_CPU_USAGE_PERCENTAGE +- printf("%5d %-8s %s %s %5d %2d.%d %2u.%u ", ++ printf("%5d %-8s %s %s %5d %2d.%d %2d.%d %2u.%u ", + s->pid, s->user, s->state, rss_str_buf, s->ppid, +- s->pcpu/10, s->pcpu%10, pmem/10, pmem%10); ++ s->pcpu/10, s->pcpu%10,s->pscpu/10, s->pscpu%10, pmem/10, pmem%10); + #else + printf("%5d %-8s %s %s %5d %2u.%u ", + s->pid, s->user, s->state, rss_str_buf, s->ppid, diff --git a/busybox/patches/udhcp_additional_items.diff b/busybox/patches/udhcp_additional_items.diff new file mode 100644 index 0000000..933be2a --- /dev/null +++ b/busybox/patches/udhcp_additional_items.diff @@ -0,0 +1,126 @@ +Index: include/usage.h +=================================================================== +RCS file: /var/cvs/busybox/include/usage.h,v +retrieving revision 1.191 +diff -u -r1.191 usage.h +--- a/include/usage.h 25 Feb 2004 10:35:55 -0000 1.191 ++++ b/include/usage.h 5 Mar 2004 14:32:45 -0000 +@@ -2606,6 +2606,7 @@ + "\t-p,\t--pidfile=file\tStore process ID of daemon in file\n" \ + "\t-q,\t--quit\tQuit after obtaining lease\n" \ + "\t-r,\t--request=IP\tIP address to request (default: none)\n" \ ++ "\t-R,\t--require=NAME\tAdd NAME to request\n" \ + "\t-s,\t--script=file\tRun file at dhcp events (default: /usr/share/udhcpc/default.script)\n" \ + "\t-v,\t--version\tDisplay version" + +Index: networking/udhcp/README.udhcpc +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/README.udhcpc,v +retrieving revision 1.3 +diff -u -r1.3 README.udhcpc +--- a/networking/udhcp/README.udhcpc 11 Dec 2002 21:12:44 -0000 1.3 ++++ b/networking/udhcp/README.udhcpc 5 Mar 2004 14:32:46 -0000 +@@ -22,6 +22,7 @@ + -p, --pidfile=file Store process ID of daemon in file + -q, --quit Quit after obtaining lease + -r, --request=IP IP address to request (default: none) ++-R, --require=NAME Add NAME to request + -s, --script=file Run file at dhcp events (default: + /usr/share/udhcpc/default.script) + -v, --version Display version +@@ -101,6 +102,8 @@ + + additional options are easily added in options.c. + ++By default, only a few basic items are requested. To request additional ++items use the -R option. Example: "-R rootpath" + + note on udhcpc's random seed + --------------------------- +Index: networking/udhcp/dhcpc.c +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/dhcpc.c,v +retrieving revision 1.16 +diff -u -r1.16 dhcpc.c +--- a/networking/udhcp/dhcpc.c 30 Jan 2004 23:45:12 -0000 1.16 ++++ b/networking/udhcp/dhcpc.c 5 Mar 2004 14:32:46 -0000 +@@ -88,6 +88,7 @@ + " -p, --pidfile=file Store process ID of daemon in file\n" + " -q, --quit Quit after obtaining lease\n" + " -r, --request=IP IP address to request (default: none)\n" ++" -R, --require=NAME Add NAME to the request\n" + " -s, --script=file Run file at dhcp events (default:\n" + " " DEFAULT_SCRIPT ")\n" + " -v, --version Display version\n" +@@ -203,6 +204,7 @@ + {"pidfile", required_argument, 0, 'p'}, + {"quit", no_argument, 0, 'q'}, + {"request", required_argument, 0, 'r'}, ++ {"require", required_argument, 0, 'R'}, + {"script", required_argument, 0, 's'}, + {"version", no_argument, 0, 'v'}, + {0, 0, 0, 0} +@@ -211,7 +213,7 @@ + /* get options */ + while (1) { + int option_index = 0; +- c = getopt_long(argc, argv, "c:fbH:h:i:np:qr:s:v", arg_options, &option_index); ++ c = getopt_long(argc, argv, "c:fbH:h:i:np:qr:R:s:v", arg_options, &option_index); + if (c == -1) break; + + switch (c) { +@@ -254,6 +256,11 @@ + case 'r': + requested_ip = inet_addr(optarg); + break; ++ case 'R': ++ if (require_option(optarg)) { ++ fprintf(stderr,"WARNING: %s unknown/not-supported (Ignored)\n", optarg ); ++ } ++ break; + case 's': + client_config.script = optarg; + break; +Index: networking/udhcp/options.c +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/options.c,v +retrieving revision 1.7 +diff -u -r1.7 options.c +--- a/networking/udhcp/options.c 30 Jan 2004 23:45:12 -0000 1.7 ++++ b/networking/udhcp/options.c 5 Mar 2004 14:32:46 -0000 +@@ -57,7 +57,19 @@ + [OPTION_S32] = 4 + }; + +- ++/* find and mark requested item as required */ ++int require_option(char *name) ++{ ++ int i; ++ for (i = 0; dhcp_options[i].code; i++) { ++ if (strcmp(name, dhcp_options[i].name) == 0 ){ ++ dhcp_options[i].flags |= OPTION_REQ; ++ return 0; ++ } ++ } ++ return 1; ++} ++ + /* get an option with bounds checking (warning, not aligned). */ + uint8_t *get_option(struct dhcpMessage *packet, int code) + { +Index: networking/udhcp/options.h +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/options.h,v +retrieving revision 1.5 +diff -u -r1.5 options.h +--- a/networking/udhcp/options.h 30 Jan 2004 23:45:12 -0000 1.5 ++++ b/networking/udhcp/options.h 5 Mar 2004 14:32:46 -0000 +@@ -30,6 +30,7 @@ + extern struct dhcp_option dhcp_options[]; + extern int option_lengths[]; + ++int require_option(char *name); + uint8_t *get_option(struct dhcpMessage *packet, int code); + int end_option(uint8_t *optionptr); + int add_option_string(uint8_t *optionptr, uint8_t *string); diff --git a/busybox/patches/udhcp_config_paths.diff b/busybox/patches/udhcp_config_paths.diff new file mode 100644 index 0000000..1d3a6b4 --- /dev/null +++ b/busybox/patches/udhcp_config_paths.diff @@ -0,0 +1,333 @@ +Index: include/usage.h +=================================================================== +RCS file: /var/cvs/busybox/include/usage.h,v +retrieving revision 1.191 +diff -u -r1.191 usage.h +--- a/include/usage.h 25 Feb 2004 10:35:55 -0000 1.191 ++++ b/include/usage.h 5 Mar 2004 13:20:11 -0000 +@@ -2606,7 +2606,8 @@ + "\t-p,\t--pidfile=file\tStore process ID of daemon in file\n" \ + "\t-q,\t--quit\tQuit after obtaining lease\n" \ + "\t-r,\t--request=IP\tIP address to request (default: none)\n" \ +- "\t-s,\t--script=file\tRun file at dhcp events (default: /usr/share/udhcpc/default.script)\n" \ ++ "\t-s,\t--script=file\tRun file at dhcp events (default: " \ ++ CONFIG_UDHCPC_SCRIPT_PATH ")\n" \ + "\t-v,\t--version\tDisplay version" + + #define udhcpd_trivial_usage \ +Index: networking/udhcp/AUTHORS +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/AUTHORS,v +retrieving revision 1.3 +diff -u -r1.3 AUTHORS +--- a/networking/udhcp/AUTHORS 18 Dec 2003 22:25:38 -0000 1.3 ++++ b/networking/udhcp/AUTHORS 5 Mar 2004 13:20:11 -0000 +@@ -10,5 +10,5 @@ + Moreton Bay (http://www.moretonbay.com/) + Vladimir Oleynik <dzo@simtrea.ru> Size optimizations + +- ++Tony J. White <tjw@tjw.org> additional busybox build options + +Index: networking/udhcp/Config.in +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/Config.in,v +retrieving revision 1.5 +diff -u -r1.5 Config.in +--- a/networking/udhcp/Config.in 22 Oct 2003 09:58:38 -0000 1.5 ++++ b/networking/udhcp/Config.in 5 Mar 2004 13:20:11 -0000 +@@ -58,5 +58,62 @@ + + See http://udhcp.busybox.net for further details. + ++menu "udhcpd Configuration Options" ++ depends on CONFIG_UDHCPD ++ ++config CONFIG_UDHCPD_CONF_PATH ++ string "Path to default udhcpd.conf" ++ default "/etc/udhcpd.conf" ++ depends on CONFIG_UDHCPD ++ help ++ The full path to udhcpd's default configuration file. ++ (default is: /etc/udhcpd.conf) ++ ++config CONFIG_UDHCPD_LEASE_PATH ++ string "Path to default udhcpd.leases" ++ default "/var/lib/misc/udhcpd.leases" ++ depends on CONFIG_UDHCPD ++ help ++ The full path to udhcpd's default leases file. ++ (default is: /var/lib/misc/udhcpd.leases) ++ ++config CONFIG_UDHCPD_PID_PATH ++ string "Path to default udhcpd PID file" ++ default "/var/run/udhcpd.pid" ++ depends on CONFIG_UDHCPD ++ help ++ The full path to udhcpd's default pid file. ++ (default is: /var/run/udhcpd.pid) ++ ++endmenu ++ ++menu "udhcpc Configuration Options" ++ depends on CONFIG_UDHCPC ++ ++config CONFIG_UDHCPC_SCRIPT_PATH ++ string "Path to default udhcpc event script" ++ depends on CONFIG_UDHCPC ++ help ++ The full path to udhcpc's default event script file. ++ (default is: /usr/share/udhcpc/default.script OR ++ /share/udhcpc/default.script if CONFIG_INSTALL_NO_USR is set) ++ ++ When udhcpc is started it executes this script to take care ++ of system tasks after it completes DHCP communication. Such ++ tasks include putting network interfaces up or down, setting ++ DNS info, adding routing information, etc. ++ ++if CONFIG_INSTALL_NO_USR ++config CONFIG_UDHCPC_SCRIPT_PATH ++ default "/share/udhcpc/default.script" ++endif ++ ++if !CONFIG_INSTALL_NO_USR ++config CONFIG_UDHCPC_SCRIPT_PATH ++ default "/usr/share/udhcpc/default.script" ++endif ++ ++endmenu ++ + endmenu + +Index: networking/udhcp/README +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/README,v +retrieving revision 1.3 +diff -u -r1.3 README +--- a/networking/udhcp/README 18 Dec 2003 22:25:38 -0000 1.3 ++++ b/networking/udhcp/README 5 Mar 2004 13:20:11 -0000 +@@ -9,27 +9,42 @@ + compile time options + ------------------- + +-The Makefile contains three of the compile time options: ++The following options can be adjusted when configuring busybox: + +- UDHCP_DEBUG: If UDHCP_DEBUG is defined, udhcpd will output extra +- debugging output, compile with -g, and not fork to the background when +- run. +- UDHCP_SYSLOG: If UDHCP_SYSLOG is defined, udhcpd will log all its +- messages syslog, otherwise, it will attempt to log them to stdout. +- +- COMBINED_BINARY: If COMBINED_BINARY is define, one binary, udhcpd, +- is created. If called as udhcpd, the dhcp server will be started. +- If called as udhcpc, the dhcp client will be started. +- +-dhcpd.h contains the other three compile time options: +- +- LEASE_TIME: The default lease time if not specified in the config +- file. ++ CONFIG_FEATURE_UDHCP_DEBUG: ++ If this is defined, udhcpd will output extra debugging output, ++ compile with -g, and not fork to the background when run. + +- LEASES_FILE: The default file for storing leases. +- +- DHCPD_CONFIG_FILE: The defualt config file to use. ++ CONFIG_FEATURE_UDHCP_SYSLOG: ++ If this is defined, udhcpd will log all its messages syslog, ++ otherwise, it will attempt to log them to stdout. ++ ++ CONFIG_UDHCPD_CONF_PATH: ++ The full path to udhcpd's default configuration file. ++ ++ CONFIG_UDHCPD_LEASE_PATH: ++ The full path to udhcpd's default leases file. ++ ++ CONFIG_UDHCPD_PID_PATH: ++ The full path to udhcpd's default pid file. ++ ++ CONFIG_UDHCPC_SCRIPT_PATH: ++ The full path to udhcpc's default event script file. ++ (default is: /usr/share/udhcpc/default.script) ++ ++ When udhcpc is started it executes this script to take care ++ of system tasks after it completes DHCP communication. Such ++ tasks include putting network interfaces up or down, setting ++ DNS info, adding routing information, etc. ++ ++ ++dhcpd.h contains the another compile time option: + ++ LEASE_TIME: ++ The default lease time if not specified in the config file. ++ This option can also be changed at runtime with the 'lease' ++ configuration option. ++ + options.c contains a set of dhcp options for the client: + + name[10]: The name of the option as it will appear in scripts +Index: networking/udhcp/README.udhcpc +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/README.udhcpc,v +retrieving revision 1.3 +diff -u -r1.3 README.udhcpc +--- a/networking/udhcp/README.udhcpc 11 Dec 2002 21:12:44 -0000 1.3 ++++ b/networking/udhcp/README.udhcpc 5 Mar 2004 13:20:11 -0000 +@@ -23,7 +23,8 @@ + -q, --quit Quit after obtaining lease + -r, --request=IP IP address to request (default: none) + -s, --script=file Run file at dhcp events (default: +- /usr/share/udhcpc/default.script) ++ /usr/share/udhcpc/default.script or ++ CONFIG_UDHCPC_SCRIPT_PATH at build time) + -v, --version Display version + + +Index: networking/udhcp/README.udhcpd +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/README.udhcpd,v +retrieving revision 1.1 +diff -u -r1.1 README.udhcpd +--- a/networking/udhcp/README.udhcpd 31 Oct 2002 19:21:27 -0000 1.1 ++++ b/networking/udhcp/README.udhcpd 5 Mar 2004 13:20:11 -0000 +@@ -50,10 +50,14 @@ + + compile time options + ------------------- ++ ++During busybox configuration, you can change the default paths for ++udhcpd.conf, udhcpd.leases, and udhcpd.pid files. See README for ++more details. + +-dhcpd.h contains the other two compile time options: ++dhcpd.h contains the compile time option: + + LEASE_TIME: The default lease time if not specified in the config + file. ++ + +- DHCPD_CONFIG_FILE: The defualt config file to use. +Index: networking/udhcp/dhcpc.h +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/dhcpc.h,v +retrieving revision 1.4 +diff -u -r1.4 dhcpc.h +--- a/networking/udhcp/dhcpc.h 30 Jan 2004 23:45:12 -0000 1.4 ++++ b/networking/udhcp/dhcpc.h 5 Mar 2004 13:20:11 -0000 +@@ -2,7 +2,11 @@ + #ifndef _DHCPC_H + #define _DHCPC_H + +-#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script" ++#ifdef CONFIG_UDHCPC_SCRIPT_PATH ++ #define DEFAULT_SCRIPT CONFIG_UDHCPC_SCRIPT_PATH ++#else ++ #define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script" ++#endif + + /* allow libbb_udhcp.h to redefine DEFAULT_SCRIPT */ + #include "libbb_udhcp.h" +Index: networking/udhcp/dhcpd.c +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/dhcpd.c,v +retrieving revision 1.5 +diff -u -r1.5 dhcpd.c +--- a/networking/udhcp/dhcpd.c 30 Jan 2004 23:45:12 -0000 1.5 ++++ b/networking/udhcp/dhcpd.c 5 Mar 2004 13:20:11 -0000 +@@ -70,6 +70,13 @@ + struct dhcpOfferedAddr *lease; + int max_sock; + unsigned long num_ips; ++ int daemonize = 1; ++ ++ while (strcmp(argv[1],"-f")==0 || strcmp(argv[1],"--foreground")==0) { ++ daemonize = 0; ++ argv++; ++ argc--; ++ } + + memset(&server_config, 0, sizeof(struct server_config_t)); + read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]); +@@ -99,9 +106,8 @@ + &server_config.server, server_config.arp) < 0) + return 1; + +-#ifndef UDHCP_DEBUG +- background(server_config.pidfile); /* hold lock during fork. */ +-#endif ++ if(daemonize) ++ background(server_config.pidfile); /* hold lock during fork. */ + + /* Setup the signal pipe */ + udhcp_sp_setup(); +Index: networking/udhcp/dhcpd.h +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/dhcpd.h,v +retrieving revision 1.5 +diff -u -r1.5 dhcpd.h +--- a/networking/udhcp/dhcpd.h 30 Jan 2004 23:45:12 -0000 1.5 ++++ b/networking/udhcp/dhcpd.h 5 Mar 2004 13:20:12 -0000 +@@ -15,11 +15,25 @@ + + /* the period of time the client is allowed to use that address */ + #define LEASE_TIME (60*60*24*10) /* 10 days of seconds */ +-#define LEASES_FILE "/var/lib/misc/udhcpd.leases" ++ ++#ifdef CONFIG_UDHCPD_LEASE_PATH ++ #define LEASES_FILE CONFIG_UDHCPD_LEASE_PATH ++#else ++ #define LEASES_FILE "/var/lib/misc/udhcpd.leases" ++#endif + + /* where to find the DHCP server configuration file */ +-#define DHCPD_CONF_FILE "/etc/udhcpd.conf" ++#ifdef CONFIG_UDHCPD_CONF_PATH ++ #define DHCPD_CONF_FILE CONFIG_UDHCPD_CONF_PATH ++#else ++ #define DHCPD_CONF_FILE "/etc/udhcpd.conf" ++#endif + ++#ifdef CONFIG_UDHCPD_PID_PATH ++ #define DHCPD_PID_FILE CONFIG_UDHCPD_PID_PATH ++#else ++ #define DHCPD_PID_FILE "/var/run/udhcpd.pid" ++#endif + /*****************************************************************/ + /* Do not modify below here unless you know what you are doing!! */ + /*****************************************************************/ +Index: networking/udhcp/files.c +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/files.c,v +retrieving revision 1.13 +diff -u -r1.13 files.c +--- a/networking/udhcp/files.c 30 Jan 2004 23:45:12 -0000 1.13 ++++ b/networking/udhcp/files.c 5 Mar 2004 13:20:13 -0000 +@@ -166,7 +166,7 @@ + {"offer_time", read_u32, &(server_config.offer_time), "60"}, + {"min_lease", read_u32, &(server_config.min_lease), "60"}, + {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE}, +- {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"}, ++ {"pidfile", read_str, &(server_config.pidfile), DHCPD_PID_FILE}, + {"notify_file", read_str, &(server_config.notify_file), ""}, + {"siaddr", read_ip, &(server_config.siaddr), "0.0.0.0"}, + {"sname", read_str, &(server_config.sname), ""}, +Index: networking/udhcp/libbb_udhcp.h +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/libbb_udhcp.h,v +retrieving revision 1.5 +diff -u -r1.5 libbb_udhcp.h +--- a/networking/udhcp/libbb_udhcp.h 18 Dec 2003 22:25:38 -0000 1.5 ++++ b/networking/udhcp/libbb_udhcp.h 5 Mar 2004 13:20:13 -0000 +@@ -3,11 +3,6 @@ + /* bit of a hack, do this no matter what the order of the includes. + * (for busybox) */ + +-#ifdef CONFIG_INSTALL_NO_USR +-#undef DEFUALT_SCRIPT +-#define DEFAULT_SCRIPT "/share/udhcpc/default.script" +-#endif +- + #ifndef _LIBBB_UDHCP_H + #define _LIBBB_UDHCP_H + diff --git a/busybox/patches/udhcpd_foreground.diff b/busybox/patches/udhcpd_foreground.diff new file mode 100644 index 0000000..3b8c7eb --- /dev/null +++ b/busybox/patches/udhcpd_foreground.diff @@ -0,0 +1,33 @@ +Index: ./networking/udhcp/dhcpd.c +=================================================================== +RCS file: /var/cvs/busybox/networking/udhcp/dhcpd.c,v +retrieving revision 1.5 +diff -u -r1.5 dhcpd.c +--- a/./networking/udhcp/dhcpd.c 30 Jan 2004 23:45:12 -0000 1.5 ++++ b/./networking/udhcp/dhcpd.c 5 Mar 2004 13:09:05 -0000 +@@ -70,6 +70,13 @@ + struct dhcpOfferedAddr *lease; + int max_sock; + unsigned long num_ips; ++ int daemonize = 1; ++ ++ while (strcmp(argv[1],"-f")==0 || strcmp(argv[1],"--foreground")==0) { ++ daemonize = 0; ++ argv++; ++ argc--; ++ } + + memset(&server_config, 0, sizeof(struct server_config_t)); + read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]); +@@ -99,9 +106,8 @@ + &server_config.server, server_config.arp) < 0) + return 1; + +-#ifndef UDHCP_DEBUG +- background(server_config.pidfile); /* hold lock during fork. */ +-#endif ++ if(daemonize) ++ background(server_config.pidfile); /* hold lock during fork. */ + + /* Setup the signal pipe */ + udhcp_sp_setup(); |