source: trunk/mindi-busybox/changelog @ 954

Last change on this file since 954 was 904, checked in by bruno, 13 years ago

merge -r890:902 $SVN_M/branches/stable

File size: 60.7 KB
Line 
1Various bug fixes that apply to busybox 1.2.1, cherry-picked from the
2ongoing development branch.  This will form the basis for busybox 1.2.2.
3
4I'll append fixes to this as they come up.  (Check the file date, or the bug
5list below.)  This file is basically a concatenation of the following:
6
7http://busybox.net/downloads/patches/svn-15746.patch
8http://busybox.net/downloads/patches/svn-15751.patch
9http://busybox.net/downloads/patches/svn-15753.patch
10http://busybox.net/downloads/patches/svn-15769.patch
11http://busybox.net/downloads/patches/svn-15745.patch
12http://busybox.net/downloads/patches/svn-15765.patch
13http://busybox.net/downloads/patches/svn-15766.patch
14http://busybox.net/downloads/patches/svn-15772.patch
15http://busybox.net/downloads/patches/svn-15773.patch
16http://busybox.net/downloads/patches/svn-15782.patch
17http://busybox.net/downloads/patches/svn-15787.patch
18http://busybox.net/downloads/patches/svn-15788.patch
19http://busybox.net/downloads/patches/svn-15795.patch
20http://busybox.net/downloads/patches/svn-15800.patch
21http://busybox.net/downloads/patches/svn-15806.patch
22http://busybox.net/downloads/patches/svn-15826.patch
23http://busybox.net/downloads/patches/svn-15855.patch
24http://busybox.net/downloads/patches/svn-15890.patch
25http://busybox.net/downloads/patches/svn-15905.patch
26http://busybox.net/downloads/patches/svn-15906.patch
27http://busybox.net/downloads/patches/svn-15984.patch
28http://busybox.net/downloads/patches/svn-16004.patch
29http://busybox.net/downloads/patches/svn-16008.patch
30http://busybox.net/downloads/patches/svn-16026.patch
31http://busybox.net/downloads/patches/svn-16032.patch
32http://busybox.net/downloads/patches/svn-16033.patch
33http://busybox.net/downloads/patches/svn-16045.patch
34http://busybox.net/downloads/patches/svn-16056.patch
35http://busybox.net/downloads/patches/svn-16057.patch
36http://busybox.net/downloads/patches/svn-16062.patch
37http://busybox.net/downloads/patches/svn-16067.patch
38http://busybox.net/downloads/patches/svn-16109.patch
39And an otherwise unmerged patch to dnsd (at the very end).
40
41That's a bugfix to sed, two fixes to documentation generation (BusyBox.html
42shouldn't have USE() macros showing up in it anymore), fix umount to report
43the right errno on failure and to handle umount block devices by name with
44newer kernels, fix mount to handle symlinks properly, make mdev delete
45device nodes when called for hotplug remove, a segfault in traceroute, a minor
46portability fix to md5sum option parsing, a build fix for httpd with old gccs,
47an options parsing tweak to hdparm, make test fail gracefully when getgroups()
48returns -1, fix a race condition in modprobe when two instances run at once
49(hotplug does this), make "tar xf foo.tar dir/dir" extract all subdirectories,
50make our getty initialize the terminal more like mingetty, an selinux build
51fix, endianness issue in ping6, fix for zcip defending addresses, clean up some
52global variables in gzip to save memory, fix sulogin -tNNN, a help text tweak,
53several warning fixes and build fixes, the dnsd fix, and a partridge in a pear
54tree.
55
56It might have been nice to include 16042 and 16044, but they don't apply and
57I'm not fixing them up right now.  16081 mixes unrelated changes in
58with a bug fix, and thus disqualifies itself.
59
60This is the last release of BusyBox under the old "GPLv2 or later" dual
61license.  Future versions (containing changes after svn 16112) will just be
62GPLv2 only, without the "or later".  If this makes you mad enough to fork the
63project, this release or svn-16112 are what to fork from.
64
65See http://busybox.net/license.html for details.
66
67It was fun, guys.  Later...
68
69 ------------------------------------------------------------------------
70r15745 | landley | 2006-07-26 12:10:39 -0400 (Wed, 26 Jul 2006) | 2 lines
71Changed paths:
72   M /trunk/busybox/coreutils/md5_sha1_sum.c
73
74Patch from Shaun Jackman, set optind by hand if we don't call getopt.
75
76 ------------------------------------------------------------------------
77Index: coreutils/md5_sha1_sum.c
78===================================================================
79--- coreutils/md5_sha1_sum.c    (revision 15744)
80+++ coreutils/md5_sha1_sum.c    (revision 15745)
81@@ -98,6 +98,7 @@
82 
83    if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK)
84        flags = bb_getopt_ulflags(argc, argv, "scw");
85+   else optind = 1;
86 
87    if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) {
88        if (flags & FLAG_SILENT) {
89 ------------------------------------------------------------------------
90r15746 | landley | 2006-07-26 13:25:08 -0400 (Wed, 26 Jul 2006) | 5 lines
91Changed paths:
92   M /trunk/busybox/editors/sed.c
93   M /trunk/busybox/testsuite/sed.tests
94
95Rich Filker spotted that sed -e 's/xxx/[/' didn't work right.  Did a smaller
96fix than his, and shrank the code a bit on top of that so the net size is
97smaller, and added a test to the test suite for this case.  Plus I cleaned up
98the #includes and removed unnecessary "const"s while I was there.
99
100 ------------------------------------------------------------------------
101Index: testsuite/sed.tests
102===================================================================
103--- testsuite/sed.tests (revision 15745)
104+++ testsuite/sed.tests (revision 15746)
105@@ -174,6 +174,8 @@
106    "yes\n" "" ""
107 rm ./-     # Clean up
108 
109+testing "sed s/xxx/[/" "sed -e 's/xxx/[/'" "[\n" "" "xxx\n"
110+
111 # Ponder this a bit more, why "woo not found" from gnu version?
112 #testing "sed doesn't substitute in deleted line" \
113 #  "sed -e '/ook/d;s/ook//;t woo;a bang;'" "bang" "" "ook\n"
114Index: editors/sed.c
115===================================================================
116--- editors/sed.c   (revision 15745)
117+++ editors/sed.c   (revision 15746)
118@@ -58,12 +58,6 @@
119    Reference http://www.opengroup.org/onlinepubs/007904975/utilities/sed.html
120 */
121 
122-#include <stdio.h>
123-#include <unistd.h>        /* for getopt() */
124-#include <errno.h>
125-#include <ctype.h>     /* for isspace() */
126-#include <stdlib.h>
127-#include <string.h>
128 #include "busybox.h"
129 #include "xregex.h"
130 
131@@ -94,8 +88,6 @@
132     struct sed_cmd_s *next;    /* Next command (linked list, NULL terminated) */
133 } sed_cmd_t;
134 
135-static const char bad_format_in_subst[] =
136-   "bad format in substitution expression";
137 static const char *const semicolon_whitespace = "; \n\r\t\v";
138 
139 struct sed_globals
140@@ -175,7 +167,7 @@
141 
142 /* strdup, replacing "\n" with '\n', and "\delimiter" with 'delimiter' */
143 
144-static void parse_escapes(char *dest, const char *string, int len, char from, char to)
145+static void parse_escapes(char *dest, char *string, int len, char from, char to)
146 {
147    int i=0;
148 
149@@ -192,7 +184,7 @@
150    *dest=0;
151 }
152 
153-static char *copy_parsing_escapes(const char *string, int len)
154+static char *copy_parsing_escapes(char *string, int len)
155 {
156    char *dest=xmalloc(len+1);
157 
158@@ -205,18 +197,22 @@
159  * index_of_next_unescaped_regexp_delim - walks left to right through a string
160  * beginning at a specified index and returns the index of the next regular
161  * expression delimiter (typically a forward * slash ('/')) not preceded by
162- * a backslash ('\').
163+ * a backslash ('\').  A negative delimiter disables square bracket checking.
164  */
165-static int index_of_next_unescaped_regexp_delim(const char delimiter,
166-   const char *str)
167+static int index_of_next_unescaped_regexp_delim(int delimiter, char *str)
168 {
169    int bracket = -1;
170    int escaped = 0;
171    int idx = 0;
172    char ch;
173 
174+   if (delimiter < 0) {
175+       bracket--;
176+       delimiter *= -1;
177+   }
178+
179    for (; (ch = str[idx]); idx++) {
180-       if (bracket != -1) {
181+       if (bracket >= 0) {
182            if (ch == ']' && !(bracket == idx - 1 || (bracket == idx - 2
183                    && str[idx - 1] == '^')))
184                bracket = -1;
185@@ -224,43 +220,38 @@
186            escaped = 0;
187        else if (ch == '\\')
188            escaped = 1;
189-       else if (ch == '[')
190+       else if (bracket == -1 && ch == '[')
191            bracket = idx;
192        else if (ch == delimiter)
193            return idx;
194    }
195 
196    /* if we make it to here, we've hit the end of the string */
197-   return -1;
198+   bb_error_msg_and_die("unmatched '%c'",delimiter);
199 }
200 
201 /*
202  *  Returns the index of the third delimiter
203  */
204-static int parse_regex_delim(const char *cmdstr, char **match, char **replace)
205+static int parse_regex_delim(char *cmdstr, char **match, char **replace)
206 {
207-   const char *cmdstr_ptr = cmdstr;
208+   char *cmdstr_ptr = cmdstr;
209    char delimiter;
210    int idx = 0;
211 
212    /* verify that the 's' or 'y' is followed by something.  That something
213     * (typically a 'slash') is now our regexp delimiter... */
214-   if (*cmdstr == '\0') bb_error_msg_and_die(bad_format_in_subst);
215+   if (*cmdstr == '\0')
216+       bb_error_msg_and_die("bad format in substitution expression");
217    delimiter = *(cmdstr_ptr++);
218 
219    /* save the match string */
220    idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr);
221-   if (idx == -1) {
222-       bb_error_msg_and_die(bad_format_in_subst);
223-   }
224    *match = copy_parsing_escapes(cmdstr_ptr, idx);
225 
226    /* save the replacement string */
227    cmdstr_ptr += idx + 1;
228-   idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr);
229-   if (idx == -1) {
230-       bb_error_msg_and_die(bad_format_in_subst);
231-   }
232+   idx = index_of_next_unescaped_regexp_delim(-delimiter, cmdstr_ptr);
233    *replace = copy_parsing_escapes(cmdstr_ptr, idx);
234 
235    return ((cmdstr_ptr - cmdstr) + idx);
236@@ -287,21 +278,18 @@
237        if (*my_str == '\\') delimiter = *(++pos);
238        else delimiter = '/';
239        next = index_of_next_unescaped_regexp_delim(delimiter, ++pos);
240-       if (next == -1)
241-           bb_error_msg_and_die("unterminated match expression");
242-
243-       temp=copy_parsing_escapes(pos,next);
244+       temp = copy_parsing_escapes(pos,next);
245        *regex = (regex_t *) xmalloc(sizeof(regex_t));
246        xregcomp(*regex, temp, bbg.regex_type|REG_NEWLINE);
247        free(temp);
248        /* Move position to next character after last delimiter */
249-       pos+=(next+1);
250+       pos += (next+1);
251    }
252    return pos - my_str;
253 }
254 
255 /* Grab a filename.  Whitespace at start is skipped, then goes to EOL. */
256-static int parse_file_cmd(sed_cmd_t *sed_cmd, const char *filecmdstr, char **retval)
257+static int parse_file_cmd(sed_cmd_t *sed_cmd, char *filecmdstr, char **retval)
258 {
259    int start = 0, idx, hack=0;
260 
261@@ -318,7 +306,7 @@
262    return idx;
263 }
264 
265-static int parse_subst_cmd(sed_cmd_t *const sed_cmd, char *substr)
266+static int parse_subst_cmd(sed_cmd_t *sed_cmd, char *substr)
267 {
268    int cflags = bbg.regex_type;
269    char *match;
270@@ -569,7 +557,7 @@
271    bbg.pipeline.buf[bbg.pipeline.idx++] = c;
272 }
273 
274-static void do_subst_w_backrefs(const char *line, const char *replace)
275+static void do_subst_w_backrefs(char *line, char *replace)
276 {
277    int i,j;
278 
279@@ -669,7 +657,7 @@
280 }
281 
282 /* Set command pointer to point to this label.  (Does not handle null label.) */
283-static sed_cmd_t *branch_to(const char *label)
284+static sed_cmd_t *branch_to(char *label)
285 {
286    sed_cmd_t *sed_cmd;
287 
288 ------------------------------------------------------------------------
289r15751 | landley | 2006-07-27 10:59:36 -0400 (Thu, 27 Jul 2006) | 7 lines
290Changed paths:
291   M /trunk/busybox/docs/autodocifier.pl
292
293I touched perl.  I feel dirty.
294
295Make autodocifier suck less.  It still doesn't handle nested USE( USE() ) case
296(the inner USE() winds up in the output), but making it recursive involves
297getting perl to accept a "for" loop and it's telling me that "break" is an
298unrecognized bareword and I hate perl.  This is at least an improvement.
299
300 ------------------------------------------------------------------------
301Index: docs/autodocifier.pl
302===================================================================
303--- docs/autodocifier.pl    (revision 15750)
304+++ docs/autodocifier.pl    (revision 15751)
305@@ -21,8 +21,8 @@
306 # regex && eval away unwanted strings from documentation
307 sub beautify {
308    my $text = shift;
309-   $text =~ s/USAGE_NOT\w+\(.*?"\s*\)//sxg;
310-   $text =~ s/USAGE_\w+\(\s*?(.*?)"\s*\)/$1"/sxg;
311+   $text =~ s/SKIP_\w+\(.*?"\s*\)//sxg;
312+   $text =~ s/USE_\w+\(\s*?(.*?)"\s*\)/$1"/sxg;
313    $text =~ s/"\s*"//sg;
314    my @line = split("\n", $text);
315    $text = join('',
316 ------------------------------------------------------------------------
317r15753 | landley | 2006-07-27 11:12:21 -0400 (Thu, 27 Jul 2006) | 2 lines
318Changed paths:
319   M /trunk/busybox/docs/autodocifier.pl
320
321And now, with a for loop, so it can handle the nested USE() case.
322
323 ------------------------------------------------------------------------
324Index: docs/autodocifier.pl
325===================================================================
326--- docs/autodocifier.pl    (revision 15752)
327+++ docs/autodocifier.pl    (revision 15753)
328@@ -21,8 +21,12 @@
329 # regex && eval away unwanted strings from documentation
330 sub beautify {
331    my $text = shift;
332-   $text =~ s/SKIP_\w+\(.*?"\s*\)//sxg;
333-   $text =~ s/USE_\w+\(\s*?(.*?)"\s*\)/$1"/sxg;
334+   for (;;) {
335+       my $text2 = $text;
336+       $text =~ s/SKIP_\w+\(.*?"\s*\)//sxg;
337+       $text =~ s/USE_\w+\(\s*?(.*?)"\s*\)/$1"/sxg;
338+       last if ( $text2 eq $text );
339+   }
340    $text =~ s/"\s*"//sg;
341    my @line = split("\n", $text);
342    $text = join('',
343 ------------------------------------------------------------------------
344r15765 | rpjday | 2006-08-03 06:50:39 -0400 (Thu, 03 Aug 2006) | 2 lines
345Changed paths:
346   M /trunk/busybox/networking/httpd.c
347
348Move declaration to be compatible with older gcc's.
349
350 ------------------------------------------------------------------------
351Index: networking/httpd.c
352===================================================================
353--- networking/httpd.c  (revision 15764)
354+++ networking/httpd.c  (revision 15765)
355@@ -863,6 +863,7 @@
356 {
357   struct sockaddr_in lsocket;
358   int fd;
359+  int on = 1;
360 
361   /* create the socket right now */
362   /* inet_addr() returns a value that is already in network order */
363@@ -873,7 +874,6 @@
364   fd = bb_xsocket(AF_INET, SOCK_STREAM, 0);
365   /* tell the OS it's OK to reuse a previous address even though */
366   /* it may still be in a close down state.  Allows bind to succeed. */
367-  int on = 1;
368 #ifdef SO_REUSEPORT
369   setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (void *)&on, sizeof(on)) ;
370 #else
371 ------------------------------------------------------------------------
372r15766 | rpjday | 2006-08-03 07:28:36 -0400 (Thu, 03 Aug 2006) | 2 lines
373Changed paths:
374   M /trunk/busybox/loginutils/Config.in
375
376Remove apparent typo in "bool" line.
377
378 ------------------------------------------------------------------------
379Index: loginutils/Config.in
380===================================================================
381--- loginutils/Config.in    (revision 15765)
382+++ loginutils/Config.in    (revision 15766)
383@@ -14,7 +14,7 @@
384      publicly readable.
385 
386 config CONFIG_USE_BB_SHADOW
387-   bool #"  Use busybox shadow password functions"
388+   bool "  Use busybox shadow password functions"
389    default y
390    depends on CONFIG_USE_BB_PWD_GRP && CONFIG_FEATURE_SHADOWPASSWDS
391    help
392 ------------------------------------------------------------------------
393r15769 | landley | 2006-08-03 13:54:45 -0400 (Thu, 03 Aug 2006) | 5 lines
394Changed paths:
395   M /trunk/busybox/util-linux/umount.c
396
397Fix umount so loop device disassociation hopefully doesn't screw up errno on
398a failed mount.  And while I'm at it, legacy mdev removal was only being done
399in the _failure_ case?  That can't be right.  Plus minor header cleanups
400and an option parsing tweak.
401
402 ------------------------------------------------------------------------
403Index: util-linux/umount.c
404===================================================================
405--- util-linux/umount.c (revision 15768)
406+++ util-linux/umount.c (revision 15769)
407@@ -13,17 +13,15 @@
408 #include "busybox.h"
409 #include <mntent.h>
410 #include <errno.h>
411-#include <string.h>
412 #include <getopt.h>
413 
414-#define OPTION_STRING      "flDnrvad"
415+#define OPTION_STRING      "flDnravd"
416 #define OPT_FORCE          1
417 #define OPT_LAZY           2
418 #define OPT_DONTFREELOOP   4
419 #define OPT_NO_MTAB            8
420 #define OPT_REMOUNT            16
421-#define OPT_IGNORED            32  // -v is ignored
422-#define OPT_ALL                (ENABLE_FEATURE_UMOUNT_ALL ? 64 : 0)
423+#define OPT_ALL                (ENABLE_FEATURE_UMOUNT_ALL ? 32 : 0)
424 
425 int umount_main(int argc, char **argv)
426 {
427@@ -77,8 +74,6 @@
428        m = 0;
429        if (!argc) bb_show_usage();
430    }
431-
432-
433   
434    // Loop through everything we're supposed to umount, and do so.
435    for (;;) {
436@@ -114,19 +109,20 @@
437                         "%s busy - remounted read-only", m->device);
438        }
439 
440-       /* De-allocate the loop device.  This ioctl should be ignored on any
441-        * non-loop block devices. */
442-       if (ENABLE_FEATURE_MOUNT_LOOP && !(opt & OPT_DONTFREELOOP) && m)
443-           del_loop(m->device);
444-
445        if (curstat) {
446-           /* Yes, the ENABLE is redundant here, but the optimizer for ARM
447-            * can't do simple constant propagation in local variables... */
448-           if(ENABLE_FEATURE_MTAB_SUPPORT && !(opt & OPT_NO_MTAB) && m)
449-               erase_mtab(m->dir);
450            status = EXIT_FAILURE;
451            bb_perror_msg("Couldn't umount %s", path);
452+       } else {
453+           /* De-allocate the loop device.  This ioctl should be ignored on
454+            * any non-loop block devices. */
455+           if (ENABLE_FEATURE_MOUNT_LOOP && !(opt & OPT_DONTFREELOOP) && m)
456+               del_loop(m->device);
457+           if (ENABLE_FEATURE_MTAB_SUPPORT && !(opt & OPT_NO_MTAB) && m)
458+               erase_mtab(m->dir);
459        }
460+
461+
462+
463        // Find next matching mtab entry for -a or umount /dev
464        while (m && (m = m->next))
465            if ((opt & OPT_ALL) || !strcmp(path,m->device))
466 ------------------------------------------------------------------------
467r15772 | landley | 2006-08-03 16:22:37 -0400 (Thu, 03 Aug 2006) | 2 lines
468Changed paths:
469   M /trunk/busybox/miscutils/hdparm.c
470
471Patch from tito to improve options parsing.
472
473 ------------------------------------------------------------------------
474Index: miscutils/hdparm.c
475===================================================================
476--- miscutils/hdparm.c  (revision 15771)
477+++ miscutils/hdparm.c  (revision 15772)
478@@ -1481,7 +1481,7 @@
479 {
480    unsigned int t;
481 
482-
483+   printf(" (");
484    if (standby == 0)
485        printf("off");
486    else if (standby == 252)
487@@ -2082,7 +2082,7 @@
488    USE_FEATURE_HDPARM_GET_IDENTITY("iI")
489    USE_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
490 #ifdef HDIO_DRIVE_CMD
491-                                   "S::D::P::X::K::A::L::W::CyYzZ"
492+                                   "S:D:P:X:K:A:L:W:CyYzZ"
493 #endif
494    USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
495 #ifdef HDIO_GET_QDMA
496 ------------------------------------------------------------------------
497r15773 | landley | 2006-08-03 16:39:59 -0400 (Thu, 03 Aug 2006) | 3 lines
498Changed paths:
499   M /trunk/busybox/modutils/lsmod.c
500
501Try to make a "type-punned pointer" warning go away for somebody on the
502buildroot list.
503
504 ------------------------------------------------------------------------
505Index: modutils/lsmod.c
506===================================================================
507--- modutils/lsmod.c    (revision 15772)
508+++ modutils/lsmod.c    (revision 15773)
509@@ -93,8 +93,7 @@
510    size_t bufsize, depsize, nmod, count, i, j;
511 
512    module_names = xmalloc(bufsize = 256);
513-   if (my_query_module(NULL, QM_MODULES, (void **)&module_names, &bufsize,
514-               &nmod)) {
515+   if (my_query_module(NULL, QM_MODULES, &module_names, &bufsize, &nmod)) {
516        bb_perror_msg_and_die("QM_MODULES");
517    }
518 
519@@ -111,7 +110,7 @@
520            /* else choke */
521            bb_perror_msg_and_die("module %s: QM_INFO", mn);
522        }
523-       if (my_query_module(mn, QM_REFS, (void **)&deps, &depsize, &count)) {
524+       if (my_query_module(mn, QM_REFS, &deps, &depsize, &count)) {
525            if (errno == ENOENT) {
526                /* The module was removed out from underneath us. */
527                continue;
528 ------------------------------------------------------------------------
529r15782 | landley | 2006-08-04 17:12:14 -0400 (Fri, 04 Aug 2006) | 2 lines
530Changed paths:
531   M /trunk/busybox/archival/Makefile.in
532
533We haven't got a CONFIG_APT_GET.
534
535 ------------------------------------------------------------------------
536Index: archival/Makefile.in
537===================================================================
538--- archival/Makefile.in    (revision 15781)
539+++ archival/Makefile.in    (revision 15782)
540@@ -11,7 +11,6 @@
541 srcdir=$(top_srcdir)/archival
542 
543 ARCHIVAL-y:=
544-ARCHIVAL-$(CONFIG_APT_GET) +=
545 ARCHIVAL-$(CONFIG_AR)      += ar.o
546 ARCHIVAL-$(CONFIG_BUNZIP2) += bunzip2.o
547 ARCHIVAL-$(CONFIG_UNLZMA)  += unlzma.o
548 ------------------------------------------------------------------------
549r15787 | landley | 2006-08-06 16:41:11 -0400 (Sun, 06 Aug 2006) | 2 lines
550Changed paths:
551   M /trunk/busybox/util-linux/readprofile.c
552
553Make a warning go away on 64-bit systems.
554
555 ------------------------------------------------------------------------
556Index: util-linux/readprofile.c
557===================================================================
558--- util-linux/readprofile.c    (revision 15786)
559+++ util-linux/readprofile.c    (revision 15787)
560@@ -47,7 +47,7 @@
561    int proFd;
562    const char *mapFile, *proFile, *mult=0;
563    unsigned long len=0, indx=1;
564-   unsigned long long add0=0;
565+   uint64_t add0=0;
566    unsigned int step;
567    unsigned int *buf, total, fn_len;
568    unsigned long long fn_add, next_add;          /* current and next address */
569@@ -223,7 +223,7 @@
570                    printf ("%s:\n", fn_name);
571                    header_printed = 1;
572                }
573-               printf ("\t%llx\t%u\n", (indx - 1)*step + add0, buf[indx]);
574+               printf ("\t%"PRIx64"\t%u\n", (indx - 1)*step + add0, buf[indx]);
575            }
576            this += buf[indx++];
577        }
578 ------------------------------------------------------------------------
579r15788 | landley | 2006-08-07 20:47:17 -0400 (Mon, 07 Aug 2006) | 3 lines
580Changed paths:
581   M /trunk/busybox/util-linux/mount.c
582
583Using lstat() instead of stat() means that attempting to loopback mount
584a symlink doesn't work.
585
586 ------------------------------------------------------------------------
587Index: util-linux/mount.c
588===================================================================
589--- util-linux/mount.c  (revision 15787)
590+++ util-linux/mount.c  (revision 15788)
591@@ -285,7 +285,7 @@
592    // Look at the file.  (Not found isn't a failure for remount, or for
593    // a synthetic filesystem like proc or sysfs.)
594 
595-   if (lstat(mp->mnt_fsname, &st));
596+   if (stat(mp->mnt_fsname, &st));
597    else if (!(vfsflags & (MS_REMOUNT | MS_BIND | MS_MOVE))) {
598        // Do we need to allocate a loopback device for it?
599 
600 ------------------------------------------------------------------------
601r15795 | landley | 2006-08-09 21:09:37 -0400 (Wed, 09 Aug 2006) | 2 lines
602Changed paths:
603   M /trunk/busybox/util-linux/mdev.c
604
605Patch from Chris Steel to fix mdev deleting device nodes.
606
607 ------------------------------------------------------------------------
608Index: util-linux/mdev.c
609===================================================================
610--- util-linux/mdev.c   (revision 15794)
611+++ util-linux/mdev.c   (revision 15795)
612@@ -37,18 +37,19 @@
613     * because sscanf() will stop at the first nondigit, which \n is.  We
614     * also depend on path having writeable space after it. */
615 
616-   strcat(path, "/dev");
617-   fd = open(path, O_RDONLY);
618-   len = read(fd, temp + 1, 64);
619-   *temp++ = 0;
620-   close(fd);
621-   if (len < 1) return;
622+   if (!delete) {
623+       strcat(path, "/dev");
624+       fd = open(path, O_RDONLY);
625+       len = read(fd, temp + 1, 64);
626+       *temp++ = 0;
627+       close(fd);
628+       if (len < 1) return;
629+   }
630 
631    /* Determine device name, type, major and minor */
632 
633    device_name = strrchr(path, '/') + 1;
634    type = path[5]=='c' ? S_IFCHR : S_IFBLK;
635-   if (sscanf(temp, "%d:%d", &major, &minor) != 2) return;
636 
637    /* If we have a config file, look up permissions for this device */
638 
639@@ -164,6 +165,7 @@
640 
641    umask(0);
642    if (!delete) {
643+       if (sscanf(temp, "%d:%d", &major, &minor) != 2) return;
644        if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST)
645            bb_perror_msg_and_die("mknod %s failed", device_name);
646 
647 ------------------------------------------------------------------------
648r15800 | landley | 2006-08-10 17:46:43 -0400 (Thu, 10 Aug 2006) | 2 lines
649Changed paths:
650   M /trunk/busybox/shell/msh.c
651
652Make a warning go away when standalone shell is disabled.
653
654 ------------------------------------------------------------------------
655Index: shell/msh.c
656===================================================================
657--- shell/msh.c (revision 15799)
658+++ shell/msh.c (revision 15800)
659@@ -3126,18 +3126,17 @@
660    int i;
661    char *sp, *tp;
662    int eacces = 0, asis = 0;
663-
664-#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
665    char *name = c;
666 
667-   optind = 1;
668-   if (find_applet_by_name(name)) {
669-       /* We have to exec here since we vforked.  Running
670-        * run_applet_by_name() won't work and bad things
671-        * will happen. */
672-       execve(CONFIG_BUSYBOX_EXEC_PATH, v, envp);
673+   if (ENABLE_FEATURE_SH_STANDALONE_SHELL) {
674+       optind = 1;
675+       if (find_applet_by_name(name)) {
676+           /* We have to exec here since we vforked.  Running
677+            * run_applet_by_name() won't work and bad things
678+            * will happen. */
679+           execve(CONFIG_BUSYBOX_EXEC_PATH, v, envp);
680+       }
681    }
682-#endif
683 
684    DBGPRINTF(("REXECVE: c=%p, v=%p, envp=%p\n", c, v, envp));
685 
686 ------------------------------------------------------------------------
687r15806 | landley | 2006-08-17 15:07:20 -0400 (Thu, 17 Aug 2006) | 13 lines
688Changed paths:
689   M /trunk/busybox/util-linux/umount.c
690
691The kernel can't handle umount /dev/hdc, we have to do it through mtab,
692except that we still have to work when there is no mtab.
693
694Oh, and while we're at it, take advantage of the fact that modern processors
695avoid branches via conditional assignment where possible.  ("x = a ? b : c;"
696turns into "x = c; if (a) x = b;" because that way there's no branch to
697potentially mispredict and thus never a bubble in the pipeline.  The if(a)
698turns into an assembly test followed by a conditional assignment (rather
699than a conditional jump).)  So since the compiler is going to do that _anyway_,
700we might as well take advantage of it to produce a slightly smaller binary.
701
702So there.
703
704 ------------------------------------------------------------------------
705Index: util-linux/umount.c
706===================================================================
707--- util-linux/umount.c (revision 15805)
708+++ util-linux/umount.c (revision 15806)
709@@ -78,6 +78,7 @@
710    // Loop through everything we're supposed to umount, and do so.
711    for (;;) {
712        int curstat;
713+       char *zapit = *argv;
714 
715        // Do we already know what to umount this time through the loop?
716        if (m) safe_strncpy(path, m->dir, PATH_MAX);
717@@ -86,32 +87,37 @@
718        // Get next command line argument (and look it up in mtab list)
719        else if (!argc--) break;
720        else {
721-           realpath(*argv++, path);
722+           argv++;
723+           realpath(zapit, path);
724            for (m = mtl; m; m = m->next)
725                if (!strcmp(path, m->dir) || !strcmp(path, m->device))
726                    break;
727        }
728+       // If we couldn't find this sucker in /etc/mtab, punt by passing our
729+       // command line argument straight to the umount syscall.  Otherwise,
730+       // umount the directory even if we were given the block device.
731+       if (m) zapit = m->dir;
732 
733        // Let's ask the thing nicely to unmount.
734-       curstat = umount(path);
735+       curstat = umount(zapit);
736 
737        // Force the unmount, if necessary.
738        if (curstat && doForce) {
739-           curstat = umount2(path, doForce);
740+           curstat = umount2(zapit, doForce);
741            if (curstat)
742-               bb_error_msg_and_die("forced umount of %s failed!", path);
743+               bb_error_msg_and_die("forced umount of %s failed!", zapit);
744        }
745 
746        // If still can't umount, maybe remount read-only?
747        if (curstat && (opt & OPT_REMOUNT) && errno == EBUSY && m) {
748-           curstat = mount(m->device, path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
749+           curstat = mount(m->device, zapit, NULL, MS_REMOUNT|MS_RDONLY, NULL);
750            bb_error_msg(curstat ? "Cannot remount %s read-only" :
751                         "%s busy - remounted read-only", m->device);
752        }
753 
754        if (curstat) {
755            status = EXIT_FAILURE;
756-           bb_perror_msg("Couldn't umount %s", path);
757+           bb_perror_msg("Couldn't umount %s", zapit);
758        } else {
759            /* De-allocate the loop device.  This ioctl should be ignored on
760             * any non-loop block devices. */
761@@ -121,9 +127,9 @@
762                erase_mtab(m->dir);
763        }
764 
765-
766-
767        // Find next matching mtab entry for -a or umount /dev
768+       // Note this means that "umount /dev/blah" will unmount all instances
769+       // of /dev/blah, not just the most recent.
770        while (m && (m = m->next))
771            if ((opt & OPT_ALL) || !strcmp(path,m->device))
772                break;
773 ------------------------------------------------------------------------
774r15826 | aldot | 2006-08-18 14:29:40 -0400 (Fri, 18 Aug 2006) | 2 lines
775Changed paths:
776   M /trunk/busybox/networking/traceroute.c
777
778- typo: s/optarg/nprobes_str; fixes segfault as reported by Raphael HUCK
779
780 ------------------------------------------------------------------------
781Index: networking/traceroute.c
782===================================================================
783--- networking/traceroute.c (revision 15825)
784+++ networking/traceroute.c (revision 15826)
785@@ -1003,7 +1003,7 @@
786    if(port_str)
787        port = (u_short)str2val(port_str, "port", 1, (1 << 16) - 1);
788    if(nprobes_str)
789-       nprobes = str2val(optarg, "nprobes", 1, -1);
790+       nprobes = str2val(nprobes_str, "nprobes", 1, -1);
791    if(source) {
792        /*
793         * set the ip source address of the outbound
794 ------------------------------------------------------------------------
795r15855 | landley | 2006-08-20 19:13:33 -0400 (Sun, 20 Aug 2006) | 2 lines
796Changed paths:
797   M /trunk/busybox/Rules.mak
798
799Yann E. Morin spotted a broken check_ld macro.
800
801 ------------------------------------------------------------------------
802Index: Rules.mak
803===================================================================
804--- Rules.mak   (revision 15854)
805+++ Rules.mak   (revision 15855)
806@@ -267,7 +267,7 @@
807 else
808     CFLAGS +=-DNDEBUG
809     CHECKED_LDFLAGS += $(call check_ld,$(LD),--sort-common,)
810-    CHECKED_LDFLAGS += $(call check_ld,--gc-sections,)
811+    CHECKED_LDFLAGS += $(call check_ld,$(LD),--gc-sections,)
812 endif
813 
814 ifneq ($(strip $(CONFIG_DEBUG_PESSIMIZE)),y)
815 ------------------------------------------------------------------------
816r15890 | landley | 2006-08-21 13:42:03 -0400 (Mon, 21 Aug 2006) | 2 lines
817Changed paths:
818   M /trunk/busybox/miscutils/Makefile.in
819
820Michael Opdenacker spotted that makefile should use () instead of {}.
821
822 ------------------------------------------------------------------------
823Index: miscutils/Makefile.in
824===================================================================
825--- miscutils/Makefile.in   (revision 15889)
826+++ miscutils/Makefile.in   (revision 15890)
827@@ -20,7 +20,7 @@
828 MISCUTILS-$(CONFIG_EJECT)       += eject.o
829 MISCUTILS-$(CONFIG_HDPARM)      += hdparm.o
830 MISCUTILS-$(CONFIG_LAST)        += last.o
831-MISCUTILS-${CONFIG_LESS}        += less.o
832+MISCUTILS-$(CONFIG_LESS)        += less.o
833 MISCUTILS-$(CONFIG_MAKEDEVS)    += makedevs.o
834 MISCUTILS-$(CONFIG_MOUNTPOINT)  += mountpoint.o
835 MISCUTILS-$(CONFIG_MT)          += mt.o
836 ------------------------------------------------------------------------
837r15905 | landley | 2006-08-22 19:40:28 -0400 (Tue, 22 Aug 2006) | 9 lines
838Changed paths:
839   M /trunk/busybox/coreutils/test.c
840
841"Jordan Crouse" <jordan.crouse@amd.com> says:
842The following patch makes coreutils/test.c act fail gracefully if getgroups()
843returns a -1.  This fixes a problem on the One Laptop Per Child ROM image
844whereby we were getting odd Memory exhausted messages for '[' and 'test'.
845
846Found by Mitch Bradley <wmb@firmworks.com>
847(Tweaked by Rob: no need to initialize a static to NULL, or realloc something
848that's only allocated when it's NULL.)
849
850 ------------------------------------------------------------------------
851Index: coreutils/test.c
852===================================================================
853--- coreutils/test.c    (revision 15904)
854+++ coreutils/test.c    (revision 15905)
855@@ -151,7 +151,7 @@
856 
857 static char **t_wp;
858 static struct t_op const *t_wp_op;
859-static gid_t *group_array = NULL;
860+static gid_t *group_array;
861 static int ngroups;
862 
863 static enum token t_lex(char *s);
864@@ -547,8 +547,10 @@
865 static void initialize_group_array(void)
866 {
867    ngroups = getgroups(0, NULL);
868-   group_array = xrealloc(group_array, ngroups * sizeof(gid_t));
869-   getgroups(ngroups, group_array);
870+   if (ngroups > 0) {
871+       group_array = xmalloc(ngroups * sizeof(gid_t));
872+       getgroups(ngroups, group_array);
873+   }
874 }
875 
876 /* Return non-zero if GID is one that we have in our groups list. */
877 ------------------------------------------------------------------------
878r15906 | landley | 2006-08-22 19:50:11 -0400 (Tue, 22 Aug 2006) | 3 lines
879Changed paths:
880   M /trunk/busybox/modutils/modprobe.c
881
882Patch from Yann Morin so modprobe won't return failure if the module gets
883loaded while it's running (ala multi-device hotplug).
884
885 ------------------------------------------------------------------------
886Index: modutils/modprobe.c
887===================================================================
888--- modutils/modprobe.c (revision 15905)
889+++ modutils/modprobe.c (revision 15906)
890@@ -679,7 +679,7 @@
891            }
892            if (!show_only) {
893                int rc2 = wait4pid(bb_spawn(argv));
894-               
895+
896                if (do_insert) {
897                    rc = rc2; /* only last module matters */
898                }
899@@ -859,7 +859,16 @@
900        }
901 
902        // process tail ---> head
903-       rc = mod_process ( tail, 1 );
904+       if ((rc = mod_process ( tail, 1 )) != 0) {
905+           /*
906+            * In case of using udev, multiple instances of modprobe can be
907+            * spawned to load the same module (think of two same usb devices,
908+            * for example; or cold-plugging at boot time). Thus we shouldn't
909+            * fail if the module was loaded, and not by us.
910+            */
911+           if (already_loaded (mod) )
912+               rc = 0;
913+       }
914    }
915    else
916        rc = 1;
917 ------------------------------------------------------------------------
918r15984 | landley | 2006-08-24 16:00:44 -0400 (Thu, 24 Aug 2006) | 6 lines
919Changed paths:
920   M /trunk/busybox/loginutils/getty.c
921
922Antti Seppala (with dots over the last two a's) wants our getty to initialize
923the terminal the way mingetty does instead of the way agetty does.  It's
924a bit ugly for somebody else to be writing to a console sitting at a
925login: prompt, but it's uglier when newline doesn't work as expected if
926they do.
927
928 ------------------------------------------------------------------------
929Index: loginutils/getty.c
930===================================================================
931--- loginutils/getty.c  (revision 15983)
932+++ loginutils/getty.c  (revision 15984)
933@@ -474,7 +474,8 @@
934        tp->c_cflag |= CLOCAL;
935    }
936 
937-   tp->c_iflag = tp->c_lflag = tp->c_oflag = tp->c_line = 0;
938+   tp->c_iflag = tp->c_lflag = tp->c_line = 0;
939+   tp->c_oflag = OPOST | ONLCR;
940    tp->c_cc[VMIN] = 1;
941    tp->c_cc[VTIME] = 0;
942 
943 ------------------------------------------------------------------------
944r16004 | landley | 2006-08-28 16:04:46 -0400 (Mon, 28 Aug 2006) | 3 lines
945Changed paths:
946   M /trunk/busybox/libbb/Makefile.in
947
948Jordan Crouse submitted a patch to only include xregcomp.c when we actually
949use it, thus fixing building against uClibc with regex support disabled.
950
951 ------------------------------------------------------------------------
952Index: libbb/Makefile.in
953===================================================================
954--- libbb/Makefile.in   (revision 16003)
955+++ libbb/Makefile.in   (revision 16004)
956@@ -29,7 +29,7 @@
957    safe_strncpy.c setup_environment.c sha1.c simplify_path.c \
958    trim.c u_signal_names.c vdprintf.c verror_msg.c \
959    vherror_msg.c vperror_msg.c wfopen.c xconnect.c xgetcwd.c xstat.c \
960-   xgethostbyname.c xgethostbyname2.c xreadlink.c xregcomp.c xgetlarg.c \
961+   xgethostbyname.c xgethostbyname2.c xreadlink.c xgetlarg.c \
962    bb_xsocket.c bb_xdaemon.c bb_xbind.c bb_xlisten.c bb_xchdir.c \
963    get_terminal_width_height.c fclose_nonstdin.c fflush_stdout_and_exit.c \
964    getopt_ulflags.c default_error_retval.c wfopen_input.c speed_table.c \
965@@ -49,6 +49,20 @@
966 LIBBB-$(CONFIG_DF)+= find_mount_point.c
967 LIBBB-$(CONFIG_EJECT)+= find_mount_point.c
968 
969+# We shouldn't build xregcomp.c if we don't need it - this ensures we don't
970+# require regex.h to be in the include dir even if we don't need it thereby
971+# allowing us to build busybox even if uclibc regex support is disabled.
972+
973+regex-y:=
974+
975+regex-$(CONFIG_AWK) += xregcomp.c
976+regex-$(CONFIG_SED) += xregcomp.c
977+regex-$(CONFIG_LESS) += xregcomp.c
978+regex-$(CONFIG_DEVFSD) += xregcomp.c
979+
980+# Sort has the happy side efect of returning a unique list
981+LIBBB-y += $(sort $(regex-y))
982+
983 LIBBB-y:=$(patsubst %,$(srcdir)/%,$(LIBBB-y))
984 
985 get-file-subparts = $(addsuffix .o,$(shell sed -n -e "s/^\#ifdef L_//p" ${1}))
986 ------------------------------------------------------------------------
987r16008 | vapier | 2006-08-28 19:24:38 -0400 (Mon, 28 Aug 2006) | 1 line
988Changed paths:
989   M /trunk/busybox/Rules.mak
990
991need libsepol in addtion to libselinux
992 ------------------------------------------------------------------------
993Index: Rules.mak
994===================================================================
995--- Rules.mak   (revision 16007)
996+++ Rules.mak   (revision 16008)
997@@ -298,7 +298,7 @@
998 endif
999 
1000 ifeq ($(strip $(CONFIG_SELINUX)),y)
1001-    LIBRARIES += -lselinux
1002+    LIBRARIES += -lselinux -lsepol
1003 endif
1004 
1005 ifeq ($(strip $(PREFIX)),)
1006 ------------------------------------------------------------------------
1007r16026 | vda | 2006-09-02 12:11:44 -0400 (Sat, 02 Sep 2006) | 2 lines
1008Changed paths:
1009   M /trunk/busybox/networking/ping6.c
1010
1011Fix endianness issue in ping6
1012
1013 ------------------------------------------------------------------------
1014Index: networking/ping6.c
1015===================================================================
1016--- networking/ping6.c  (revision 16025)
1017+++ networking/ping6.c  (revision 16026)
1018@@ -198,7 +198,7 @@
1019    pkt->icmp6_type = ICMP6_ECHO_REQUEST;
1020    pkt->icmp6_code = 0;
1021    pkt->icmp6_cksum = 0;
1022-   pkt->icmp6_seq = ntransmitted++;
1023+   pkt->icmp6_seq = SWAP_BE16(ntransmitted++);
1024    pkt->icmp6_id = myid;
1025    CLR(pkt->icmp6_seq % MAX_DUP_CHK);
1026 
1027 ------------------------------------------------------------------------
1028r16032 | vda | 2006-09-02 14:40:10 -0400 (Sat, 02 Sep 2006) | 4 lines
1029Changed paths:
1030   M /trunk/busybox/archival/libunarchive/find_list_entry.c
1031   M /trunk/busybox/testsuite/README
1032   A /trunk/busybox/testsuite/tar/tar-extracts-all-subdirs
1033
1034tar: tar xf foo.tar dir/dir did not extract all subdirs.
1035Added testsuite entry for this
1036
1037
1038 ------------------------------------------------------------------------
1039Index: archival/libunarchive/find_list_entry.c
1040===================================================================
1041--- archival/libunarchive/find_list_entry.c (revision 16031)
1042+++ archival/libunarchive/find_list_entry.c (revision 16032)
1043@@ -13,7 +13,7 @@
1044 const llist_t *find_list_entry(const llist_t *list, const char *filename)
1045 {
1046    while (list) {
1047-       if (fnmatch(list->data, filename, 0) == 0) {
1048+       if (fnmatch(list->data, filename, FNM_LEADING_DIR) == 0) {
1049            return (list);
1050        }
1051        list = list->link;
1052Index: testsuite/tar/tar-extracts-all-subdirs
1053===================================================================
1054--- testsuite/tar/tar-extracts-all-subdirs  (revision 0)
1055+++ testsuite/tar/tar-extracts-all-subdirs  (revision 16032)
1056@@ -0,0 +1,12 @@
1057+# FEATURE: CONFIG_FEATURE_TAR_CREATE
1058+mkdir -p foo/{1,2,3}
1059+mkdir -p foo/1/{10,11}
1060+mkdir -p foo/1/10/{100,101,102}
1061+tar cf foo.tar -C foo .
1062+rm -rf foo/*
1063+busybox tar xf foo.tar -C foo ./1/10
1064+find foo | sort >logfile.bb
1065+rm -rf foo/*
1066+tar xf foo.tar -C foo ./1/10
1067+find foo | sort >logfile.gnu
1068+cmp logfile.gnu logfile.bb
1069Index: testsuite/README
1070===================================================================
1071--- testsuite/README    (revision 16031)
1072+++ testsuite/README    (revision 16032)
1073@@ -1,3 +1,6 @@
1074+Update: doesn't work as described. Try "make check" from parent dir...
1075+* * *
1076+
1077 To run the test suite, change to this directory and run "./runtest".  It will
1078 run all of the test cases, and list those with unexpected outcomes.  Adding the
1079 -v option will cause it to show expected outcomes as well.  To only run the test
1080 ------------------------------------------------------------------------
1081r16033 | vda | 2006-09-03 08:20:36 -0400 (Sun, 03 Sep 2006) | 5 lines
1082Changed paths:
1083   M /trunk/busybox/networking/zcip.c
1084
1085zcip: apply patch from
1086      http://bugs.busybox.net/view.php?id=1005
1087      zcip does not claim another IP after defending
1088
1089
1090 ------------------------------------------------------------------------
1091Index: networking/zcip.c
1092===================================================================
1093--- networking/zcip.c   (revision 16032)
1094+++ networking/zcip.c   (revision 16033)
1095@@ -15,7 +15,7 @@
1096  * certainly be used.  Its naming is built over multicast DNS.
1097  */
1098 
1099-// #define      DEBUG
1100+//#define DEBUG
1101 
1102 // TODO:
1103 // - more real-world usage/testing, especially daemon mode
1104@@ -43,12 +43,7 @@
1105 
1106 struct arp_packet {
1107    struct ether_header hdr;
1108-   // FIXME this part is netinet/if_ether.h "struct ether_arp"
1109-   struct arphdr arp;
1110-   struct ether_addr source_addr;
1111-   struct in_addr source_ip;
1112-   struct ether_addr target_addr;
1113-   struct in_addr target_ip;
1114+   struct ether_arp arp;
1115 } ATTRIBUTE_PACKED;
1116 
1117 enum {
1118@@ -68,10 +63,19 @@
1119    DEFEND_INTERVAL = 10
1120 };
1121 
1122-static const struct in_addr null_ip = { 0 };
1123-static const struct ether_addr null_addr = { {0, 0, 0, 0, 0, 0} };
1124+/* States during the configuration process. */
1125+enum {
1126+   PROBE = 0,
1127+   RATE_LIMIT_PROBE,
1128+   ANNOUNCE,
1129+   MONITOR,
1130+   DEFEND
1131+};
1132 
1133-static int verbose = 0;
1134+/* Implicitly zero-initialized */
1135+static const struct in_addr null_ip;
1136+static const struct ether_addr null_addr;
1137+static int verbose;
1138 
1139 #define DBG(fmt,args...) \
1140    do { } while (0)
1141@@ -100,6 +104,7 @@
1142    const struct ether_addr *target_addr, struct in_addr target_ip)
1143 {
1144    struct arp_packet p;
1145+   memset(&p, 0, sizeof(p));
1146 
1147    // ether header
1148    p.hdr.ether_type = htons(ETHERTYPE_ARP);
1149@@ -107,15 +112,15 @@
1150    memset(p.hdr.ether_dhost, 0xff, ETH_ALEN);
1151 
1152    // arp request
1153-   p.arp.ar_hrd = htons(ARPHRD_ETHER);
1154-   p.arp.ar_pro = htons(ETHERTYPE_IP);
1155-   p.arp.ar_hln = ETH_ALEN;
1156-   p.arp.ar_pln = 4;
1157-   p.arp.ar_op = htons(op);
1158-   memcpy(&p.source_addr, source_addr, ETH_ALEN);
1159-   memcpy(&p.source_ip, &source_ip, sizeof (p.source_ip));
1160-   memcpy(&p.target_addr, target_addr, ETH_ALEN);
1161-   memcpy(&p.target_ip, &target_ip, sizeof (p.target_ip));
1162+   p.arp.arp_hrd = htons(ARPHRD_ETHER);
1163+   p.arp.arp_pro = htons(ETHERTYPE_IP);
1164+   p.arp.arp_hln = ETH_ALEN;
1165+   p.arp.arp_pln = 4;
1166+   p.arp.arp_op = htons(op);
1167+   memcpy(&p.arp.arp_sha, source_addr, ETH_ALEN);
1168+   memcpy(&p.arp.arp_spa, &source_ip, sizeof (p.arp.arp_spa));
1169+   memcpy(&p.arp.arp_tha, target_addr, ETH_ALEN);
1170+   memcpy(&p.arp.arp_tpa, &target_ip, sizeof (p.arp.arp_tpa));
1171 
1172    // send it
1173    if (sendto(fd, &p, sizeof (p), 0, saddr, sizeof (*saddr)) < 0) {
1174@@ -196,11 +201,11 @@
1175    int fd;
1176    int ready = 0;
1177    suseconds_t timeout = 0;    // milliseconds
1178-   time_t defend = 0;
1179    unsigned conflicts = 0;
1180    unsigned nprobes = 0;
1181    unsigned nclaims = 0;
1182    int t;
1183+   int state = PROBE;
1184 
1185    // parse commandline: prog [options] ifname script
1186    while ((t = getopt(argc, argv, "fqr:v")) != EOF) {
1187@@ -307,6 +312,9 @@
1188        fds[0].events = POLLIN;
1189        fds[0].revents = 0;
1190 
1191+       int source_ip_conflict = 0;
1192+       int target_ip_conflict = 0;
1193+
1194        // poll, being ready to adjust current timeout
1195        if (!timeout) {
1196            timeout = ms_rdelay(PROBE_WAIT);
1197@@ -314,6 +322,7 @@
1198            // make the kernel filter out all packets except
1199            // ones we'd care about.
1200        }
1201+       // set tv1 to the point in time when we timeout
1202        gettimeofday(&tv1, NULL);
1203        tv1.tv_usec += (timeout % 1000) * 1000;
1204        while (tv1.tv_usec > 1000000) {
1205@@ -326,64 +335,113 @@
1206                timeout, intf, nprobes, nclaims);
1207        switch (poll(fds, 1, timeout)) {
1208 
1209-       // timeouts trigger protocol transitions
1210+       // timeout
1211        case 0:
1212-           // probes
1213-           if (nprobes < PROBE_NUM) {
1214-               nprobes++;
1215-               VDBG("probe/%d %s@%s\n",
1216-                       nprobes, intf, inet_ntoa(ip));
1217-               (void)arp(fd, &saddr, ARPOP_REQUEST,
1218-                       &addr, null_ip,
1219-                       &null_addr, ip);
1220+           VDBG("state = %d\n", state);
1221+           switch (state) {
1222+           case PROBE:
1223+               // timeouts in the PROBE state means no conflicting ARP packets
1224+               // have been received, so we can progress through the states
1225                if (nprobes < PROBE_NUM) {
1226+                   nprobes++;
1227+                   VDBG("probe/%d %s@%s\n",
1228+                           nprobes, intf, inet_ntoa(ip));
1229+                   (void)arp(fd, &saddr, ARPOP_REQUEST,
1230+                           &addr, null_ip,
1231+                           &null_addr, ip);
1232                    timeout = PROBE_MIN * 1000;
1233                    timeout += ms_rdelay(PROBE_MAX
1234                            - PROBE_MIN);
1235-               } else
1236-                   timeout = ANNOUNCE_WAIT * 1000;
1237-           }
1238-           // then announcements
1239-           else if (nclaims < ANNOUNCE_NUM) {
1240-               nclaims++;
1241+               }
1242+               else {
1243+                   // Switch to announce state.
1244+                   state = ANNOUNCE;
1245+                   nclaims = 0;
1246+                   VDBG("announce/%d %s@%s\n",
1247+                           nclaims, intf, inet_ntoa(ip));
1248+                   (void)arp(fd, &saddr, ARPOP_REQUEST,
1249+                           &addr, ip,
1250+                           &addr, ip);
1251+                   timeout = ANNOUNCE_INTERVAL * 1000;
1252+               }
1253+               break;
1254+           case RATE_LIMIT_PROBE:
1255+               // timeouts in the RATE_LIMIT_PROBE state means no conflicting ARP packets
1256+               // have been received, so we can move immediately to the announce state
1257+               state = ANNOUNCE;
1258+               nclaims = 0;
1259                VDBG("announce/%d %s@%s\n",
1260                        nclaims, intf, inet_ntoa(ip));
1261                (void)arp(fd, &saddr, ARPOP_REQUEST,
1262                        &addr, ip,
1263                        &addr, ip);
1264+               timeout = ANNOUNCE_INTERVAL * 1000;
1265+               break;
1266+           case ANNOUNCE:
1267+               // timeouts in the ANNOUNCE state means no conflicting ARP packets
1268+               // have been received, so we can progress through the states
1269                if (nclaims < ANNOUNCE_NUM) {
1270+                   nclaims++;
1271+                   VDBG("announce/%d %s@%s\n",
1272+                           nclaims, intf, inet_ntoa(ip));
1273+                   (void)arp(fd, &saddr, ARPOP_REQUEST,
1274+                           &addr, ip,
1275+                           &addr, ip);
1276                    timeout = ANNOUNCE_INTERVAL * 1000;
1277-               } else {
1278+               }
1279+               else {
1280+                   // Switch to monitor state.
1281+                   state = MONITOR;
1282                    // link is ok to use earlier
1283+                   // FIXME update filters
1284                    run(script, "config", intf, &ip);
1285                    ready = 1;
1286                    conflicts = 0;
1287-                   timeout = -1;
1288+                   timeout = -1; // Never timeout in the monitor state.
1289 
1290                    // NOTE:  all other exit paths
1291                    // should deconfig ...
1292                    if (quit)
1293                        return EXIT_SUCCESS;
1294-                   // FIXME update filters
1295                }
1296-           }
1297-           break;
1298-
1299+               break;
1300+           case DEFEND:
1301+               // We won!  No ARP replies, so just go back to monitor.
1302+               state = MONITOR;
1303+               timeout = -1;
1304+               conflicts = 0;
1305+               break;
1306+           default:
1307+               // Invalid, should never happen.  Restart the whole protocol.
1308+               state = PROBE;
1309+               pick(&ip);
1310+               timeout = 0;
1311+               nprobes = 0;
1312+               nclaims = 0;
1313+               break;
1314+           } // switch (state)
1315+           break; // case 0 (timeout)
1316        // packets arriving
1317        case 1:
1318-           // maybe adjust timeout
1319+           // We need to adjust the timeout in case we didn't receive
1320+           // a conflicting packet.
1321            if (timeout > 0) {
1322                struct timeval tv2;
1323 
1324                gettimeofday(&tv2, NULL);
1325                if (timercmp(&tv1, &tv2, <)) {
1326+                   // Current time is greater than the expected timeout time.
1327+                   // Should never happen.
1328+                   VDBG("missed an expected timeout\n");
1329                    timeout = 0;
1330                } else {
1331+                   VDBG("adjusting timeout\n");
1332                    timersub(&tv1, &tv2, &tv1);
1333                    timeout = 1000 * tv1.tv_sec
1334                            + tv1.tv_usec / 1000;
1335                }
1336            }
1337+
1338            if ((fds[0].revents & POLLIN) == 0) {
1339                if (fds[0].revents & POLLERR) {
1340                    // FIXME: links routinely go down;
1341@@ -397,6 +455,7 @@
1342                }
1343                continue;
1344            }
1345+
1346            // read ARP packet
1347            if (recv(fd, &p, sizeof (p), 0) < 0) {
1348                why = "recv";
1349@@ -405,71 +464,102 @@
1350            if (p.hdr.ether_type != htons(ETHERTYPE_ARP))
1351                continue;
1352 
1353-           VDBG("%s recv arp type=%d, op=%d,\n",
1354+#ifdef DEBUG
1355+           {
1356+               struct ether_addr * sha = (struct ether_addr *) p.arp.arp_sha;
1357+               struct ether_addr * tha = (struct ether_addr *) p.arp.arp_tha;
1358+               struct in_addr * spa = (struct in_addr *) p.arp.arp_spa;
1359+               struct in_addr * tpa = (struct in_addr *) p.arp.arp_tpa;
1360+               VDBG("%s recv arp type=%d, op=%d,\n",
1361                    intf, ntohs(p.hdr.ether_type),
1362-                   ntohs(p.arp.ar_op));
1363-           VDBG("\tsource=%s %s\n",
1364-                   ether_ntoa(&p.source_addr),
1365-                   inet_ntoa(p.source_ip));
1366-           VDBG("\ttarget=%s %s\n",
1367-                   ether_ntoa(&p.target_addr),
1368-                   inet_ntoa(p.target_ip));
1369-           if (p.arp.ar_op != htons(ARPOP_REQUEST)
1370-                   && p.arp.ar_op != htons(ARPOP_REPLY))
1371+                   ntohs(p.arp.arp_op));
1372+               VDBG("\tsource=%s %s\n",
1373+                   ether_ntoa(sha),
1374+                   inet_ntoa(*spa));
1375+               VDBG("\ttarget=%s %s\n",
1376+                   ether_ntoa(tha),
1377+                   inet_ntoa(*tpa));
1378+           }
1379+#endif
1380+           if (p.arp.arp_op != htons(ARPOP_REQUEST)
1381+                   && p.arp.arp_op != htons(ARPOP_REPLY))
1382                continue;
1383 
1384-           // some cases are always conflicts
1385-           if ((p.source_ip.s_addr == ip.s_addr)
1386-                   && (memcmp(&addr, &p.source_addr,
1387-                           ETH_ALEN) != 0)) {
1388-collision:
1389-               VDBG("%s ARP conflict from %s\n", intf,
1390-                       ether_ntoa(&p.source_addr));
1391-               if (ready) {
1392-                   time_t now = time(0);
1393+           if (memcmp(p.arp.arp_spa, &ip.s_addr, sizeof(struct in_addr)) == 0 &&
1394+               memcmp(&addr, &p.arp.arp_sha, ETH_ALEN) != 0) {
1395+               source_ip_conflict = 1;
1396+           }
1397+           if (memcmp(p.arp.arp_tpa, &ip.s_addr, sizeof(struct in_addr)) == 0 &&
1398+               p.arp.arp_op == htons(ARPOP_REQUEST) &&
1399+               memcmp(&addr, &p.arp.arp_tha, ETH_ALEN) != 0) {
1400+               target_ip_conflict = 1;
1401+           }
1402 
1403-                   if ((defend + DEFEND_INTERVAL)
1404-                           < now) {
1405-                       defend = now;
1406-                       (void)arp(fd, &saddr,
1407-                               ARPOP_REQUEST,
1408-                               &addr, ip,
1409-                               &addr, ip);
1410-                       VDBG("%s defend\n", intf);
1411-                       timeout = -1;
1412-                       continue;
1413+           VDBG("state = %d, source ip conflict = %d, target ip conflict = %d\n",
1414+               state, source_ip_conflict, target_ip_conflict);
1415+           switch (state) {
1416+           case PROBE:
1417+           case ANNOUNCE:
1418+               // When probing or announcing, check for source IP conflicts
1419+               // and other hosts doing ARP probes (target IP conflicts).
1420+               if (source_ip_conflict || target_ip_conflict) {
1421+                   conflicts++;
1422+                   if (conflicts >= MAX_CONFLICTS) {
1423+                       VDBG("%s ratelimit\n", intf);
1424+                       timeout = RATE_LIMIT_INTERVAL * 1000;
1425+                       state = RATE_LIMIT_PROBE;
1426                    }
1427-                   defend = now;
1428+
1429+                   // restart the whole protocol
1430+                   pick(&ip);
1431+                   timeout = 0;
1432+                   nprobes = 0;
1433+                   nclaims = 0;
1434+               }
1435+               break;
1436+           case MONITOR:
1437+               // If a conflict, we try to defend with a single ARP probe.
1438+               if (source_ip_conflict) {
1439+                   VDBG("monitor conflict -- defending\n");
1440+                   state = DEFEND;
1441+                   timeout = DEFEND_INTERVAL * 1000;
1442+                   (void)arp(fd, &saddr,
1443+                           ARPOP_REQUEST,
1444+                           &addr, ip,
1445+                           &addr, ip);
1446+               }
1447+               break;
1448+           case DEFEND:
1449+               // Well, we tried.  Start over (on conflict).
1450+               if (source_ip_conflict) {
1451+                   state = PROBE;
1452+                   VDBG("defend conflict -- starting over\n");
1453                    ready = 0;
1454                    run(script, "deconfig", intf, &ip);
1455-                   // FIXME rm filters: setsockopt(fd,
1456-                   // SO_DETACH_FILTER, ...)
1457+
1458+                   // restart the whole protocol
1459+                   pick(&ip);
1460+                   timeout = 0;
1461+                   nprobes = 0;
1462+                   nclaims = 0;
1463                }
1464-               conflicts++;
1465-               if (conflicts >= MAX_CONFLICTS) {
1466-                   VDBG("%s ratelimit\n", intf);
1467-                   sleep(RATE_LIMIT_INTERVAL);
1468-               }
1469-               // restart the whole protocol
1470+               break;
1471+           default:
1472+               // Invalid, should never happen.  Restart the whole protocol.
1473+               VDBG("invalid state -- starting over\n");
1474+               state = PROBE;
1475                pick(&ip);
1476                timeout = 0;
1477                nprobes = 0;
1478                nclaims = 0;
1479-           }
1480-           // two hosts probing one address is a collision too
1481-           else if (p.target_ip.s_addr == ip.s_addr
1482-                   && nclaims == 0
1483-                   && p.arp.ar_op == htons(ARPOP_REQUEST)
1484-                   && memcmp(&addr, &p.target_addr,
1485-                           ETH_ALEN) != 0) {
1486-               goto collision;
1487-           }
1488-           break;
1489+               break;
1490+           } // switch state
1491 
1492+           break; // case 1 (packets arriving)
1493        default:
1494            why = "poll";
1495            goto bad;
1496-       }
1497+       } // switch poll
1498    }
1499 bad:
1500    if (foreground)
1501 ------------------------------------------------------------------------
1502r16045 | vda | 2006-09-03 13:11:34 -0400 (Sun, 03 Sep 2006) | 3 lines
1503Changed paths:
1504   M /trunk/busybox/loginutils/sulogin.c
1505
1506sulogin: fix bug: -tNNN didn't work
1507
1508
1509 ------------------------------------------------------------------------
1510Index: loginutils/sulogin.c
1511===================================================================
1512--- loginutils/sulogin.c    (revision 16044)
1513+++ loginutils/sulogin.c    (revision 16045)
1514@@ -52,7 +52,7 @@
1515 int sulogin_main(int argc, char **argv)
1516 {
1517    char *cp;
1518-   char *device = (char *) 0;
1519+   char *device = NULL;
1520    const char *name = "root";
1521    int timeout = 0;
1522 
1523@@ -68,14 +68,15 @@
1524    openlog("sulogin", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
1525    if (argc > 1) {
1526        if (strncmp(argv[1], "-t", 2) == 0) {
1527-           if (strcmp(argv[1], "-t") == 0) {
1528+           if (argv[1][2] == '\0') { /* -t NN */
1529                if (argc > 2) {
1530                    timeout = atoi(argv[2]);
1531                    if (argc > 3) {
1532                        device = argv[3];
1533                    }
1534                }
1535-           } else {
1536+           } else { /* -tNNN */
1537+               timeout = atoi(&argv[1][2]);
1538                if (argc > 2) {
1539                    device = argv[2];
1540                }
1541@@ -87,7 +88,7 @@
1542            close(0);
1543            close(1);
1544            close(2);
1545-           if (open(device, O_RDWR) >= 0) {
1546+           if (open(device, O_RDWR) == 0) {
1547                dup(0);
1548                dup(0);
1549            } else {
1550 ------------------------------------------------------------------------
1551r16056 | aldot | 2006-09-06 09:24:39 -0400 (Wed, 06 Sep 2006) | 2 lines
1552Changed paths:
1553   M /trunk/busybox/libbb/Makefile.in
1554
1555- mdev and grep use xregcomp. Closes bug #1021
1556
1557 ------------------------------------------------------------------------
1558Index: libbb/Makefile.in
1559===================================================================
1560--- libbb/Makefile.in   (revision 16055)
1561+++ libbb/Makefile.in   (revision 16056)
1562@@ -56,11 +56,12 @@
1563 # allowing us to build busybox even if uclibc regex support is disabled.
1564 
1565 regex-y:=
1566-
1567 regex-$(CONFIG_AWK) += xregcomp.c
1568 regex-$(CONFIG_SED) += xregcomp.c
1569 regex-$(CONFIG_LESS) += xregcomp.c
1570 regex-$(CONFIG_DEVFSD) += xregcomp.c
1571+regex-$(CONFIG_MDEV) += xregcomp.c
1572+regex-$(CONFIG_GREP) += xregcomp.c
1573 
1574 # Sort has the happy side efect of returning a unique list
1575 LIBBB-y += $(sort $(regex-y))
1576 ------------------------------------------------------------------------
1577r16057 | aldot | 2006-09-06 11:28:32 -0400 (Wed, 06 Sep 2006) | 16 lines
1578Changed paths:
1579   M /trunk/busybox/archival/libunarchive/decompress_uncompress.c
1580
1581- strip 399424 off the bss by making decompress_uncompress buffers config buffers.
1582  Compile tested (too lazy to look for a small .Z on the net).
1583$ size busybox.old busybox
1584   text    data     bss     dec     hex filename
1585 859555   10232  645732 1515519  171fff busybox.old
1586 859683   10232  246308 1116223  11083f busybox
1587$ make bloatcheck
1588function                                             old     new   delta
1589uncompress                                          1036    1160    +124
1590inbuf                                               2116       4   -2112
1591outbuf                                              4100       4   -4096
1592htab                                              131072       - -131072
1593codetab                                           262144       - -262144
1594 ------------------------------------------------------------------------------
1595(add/remove: 0/2 grow/shrink: 1/2 up/down: 124/-399424)   Total: -399300 bytes
1596
1597 ------------------------------------------------------------------------
1598Index: archival/libunarchive/decompress_uncompress.c
1599===================================================================
1600--- archival/libunarchive/decompress_uncompress.c   (revision 16056)
1601+++ archival/libunarchive/decompress_uncompress.c   (revision 16057)
1602@@ -70,22 +70,12 @@
1603 /* user settable max # bits/code */
1604 static int maxbits = BITS;
1605 
1606-/* Input buffer */
1607-static unsigned char inbuf[IBUFSIZ + 64];
1608-
1609-/* Output buffer */
1610-static unsigned char outbuf[OBUFSIZ + 2048];
1611-
1612-
1613-static unsigned char htab[HSIZE];
1614-static unsigned short codetab[HSIZE];
1615-
1616 #define    htabof(i)               htab[i]
1617 #define    codetabof(i)            codetab[i]
1618 #define    tab_prefixof(i)         codetabof(i)
1619 #define    tab_suffixof(i)         ((unsigned char *)(htab))[i]
1620 #define    de_stack                ((unsigned char *)&(htab[HSIZE-1]))
1621-#define    clear_htab()            memset(htab, -1, sizeof(htab))
1622+#define    clear_htab()            memset(htab, -1, HSIZE)
1623 #define    clear_tab_prefixof()    memset(codetab, 0, 256);
1624 
1625 
1626@@ -113,6 +103,12 @@
1627    long int maxmaxcode;
1628    int n_bits;
1629    int rsize = 0;
1630+   RESERVE_CONFIG_UBUFFER(inbuf, IBUFSIZ + 64);
1631+   RESERVE_CONFIG_UBUFFER(outbuf, OBUFSIZ + 2048);
1632+   unsigned char htab[HSIZE];
1633+   unsigned short codetab[HSIZE];
1634+   memset(inbuf, 0, IBUFSIZ + 64);
1635+   memset(outbuf, 0, OBUFSIZ + 2048);
1636 
1637    insize = 0;
1638 
1639@@ -160,7 +156,7 @@
1640            posbits = 0;
1641        }
1642 
1643-       if (insize < (int) sizeof(inbuf) - IBUFSIZ) {
1644+       if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
1645            rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ);
1646            insize += rsize;
1647        }
1648@@ -286,5 +282,7 @@
1649        write(fd_out, outbuf, outpos);
1650    }
1651 
1652+   RELEASE_CONFIG_BUFFER(inbuf);
1653+   RELEASE_CONFIG_BUFFER(outbuf);
1654    return 0;
1655 }
1656 ------------------------------------------------------------------------
1657r16062 | vda | 2006-09-07 01:43:38 -0400 (Thu, 07 Sep 2006) | 4 lines
1658Changed paths:
1659   M /trunk/busybox/Config.in
1660
1661CONFIG_FEATURE_COMPRESS_USAGE was impossible to turn on
1662if !CONFIG_NITPICK
1663
1664
1665 ------------------------------------------------------------------------
1666Index: Config.in
1667===================================================================
1668--- Config.in   (revision 16061)
1669+++ Config.in   (revision 16062)
1670@@ -76,7 +76,7 @@
1671 config CONFIG_FEATURE_COMPRESS_USAGE
1672    bool "Store applet usage messages in compressed form"
1673    default y
1674-   depends on CONFIG_SHOW_USAGE && CONFIG_NITPICK
1675+   depends on CONFIG_SHOW_USAGE
1676    help
1677      Store usage messages in compressed form, uncompress them on-the-fly
1678      when <applet> --help is called.
1679 ------------------------------------------------------------------------
1680r16067 | landley | 2006-09-07 20:01:02 -0400 (Thu, 07 Sep 2006) | 2 lines
1681Changed paths:
1682   M /trunk/busybox/editors/sed.c
1683
1684Bugfix for: echo '123456789' | sed 's/./|&/5'
1685
1686 ------------------------------------------------------------------------
1687Index: editors/sed.c
1688===================================================================
1689--- editors/sed.c   (revision 16066)
1690+++ editors/sed.c   (revision 16067)
1691@@ -627,7 +627,7 @@
1692           end of match and continue */
1693        if(sed_cmd->which_match && sed_cmd->which_match!=match_count) {
1694            for(i=0;i<bbg.regmatch[0].rm_eo;i++)
1695-               pipe_putc(oldline[i]);
1696+               pipe_putc(*(oldline++));
1697            continue;
1698        }
1699 
1700 ------------------------------------------------------------------------
1701r16109 | landley | 2006-09-12 16:29:22 -0400 (Tue, 12 Sep 2006) | 2 lines
1702Changed paths:
1703   M /trunk/busybox/include/platform.h
1704
1705Fix from Bernhard for somebody trying to limp along with gcc 2.95.4.
1706
1707 ------------------------------------------------------------------------
1708Index: include/platform.h
1709===================================================================
1710--- include/platform.h  (revision 16108)
1711+++ include/platform.h  (revision 16109)
1712@@ -83,6 +83,14 @@
1713 # endif
1714 #endif
1715 
1716+/* gcc-2.95 had no va_copy but only __va_copy. */
1717+#if !__GNUC_PREREQ (3,0)
1718+# include <stdarg.h>
1719+# if !defined va_copy && defined __va_copy
1720+#  define va_copy(d,s) __va_copy((d),(s))
1721+# endif
1722+#endif
1723+
1724 /* ---- Endian Detection ------------------------------------ */
1725 
1726 #if (defined __digital__ && defined __unix__)
1727
1728 ------------------------------------------------------------------------
1729Patch from Roberto Foglietta to fix various things in dnsd (for example,
1730don't segfault if dnsd.conf doesn't exist).
1731
1732--- networking/dnsd.c   2006-07-01 00:42:02.000000000 +0200
1733+++ networking/dnsd.c   2006-10-17 18:11:22.000000000 +0200
1734@@ -29,6 +29,11 @@ static char *fileconf = "/etc/dnsd.conf"
1735 #define LOCK_FILE       "/var/run/dnsd.lock"
1736 #define LOG_FILE        "/var/log/dnsd.log"
1737 
1738+#define is_daemon()  (flags&16)
1739+#define is_verbose() (flags&32)
1740+//#define DEBUG
1741+
1742+
1743 enum {
1744    MAX_HOST_LEN = 16,      // longest host name allowed is 15
1745    IP_STRING_LEN = 18,     // .xxx.xxx.xxx.xxx\0
1746@@ -223,29 +228,35 @@ static int listen_socket(char *iface_add
1747 static int table_lookup(uint16_t type, uint8_t * as, uint8_t * qs)
1748 {
1749    int i;
1750-   struct dns_entry *d=dnsentry;
1751+   struct dns_entry *d = dnsentry;
1752 
1753-   do {
1754+   if(d) do {
1755 #ifdef DEBUG
1756-       char *p,*q;
1757-       q = (char *)&(qs[1]);
1758-       p = &(d->name[1]);
1759-       fprintf(stderr, "\ntest: %d <%s> <%s> %d", strlen(p), p, q, strlen(q));
1760+       if(qs && d) {
1761+           char *p,*q;
1762+           q = (char *)&(qs[1]);
1763+           p = &(d->name[1]);
1764+           fprintf(stderr, "\n%s: %d/%d p:%s q:%s %d",
1765+               __FUNCTION__, strlen(p), (int)(d->name[0]),
1766+               p, q, strlen(q));
1767+       }
1768 #endif
1769-       if (type == REQ_A) { /* search by host name */
1770+       if (type == REQ_A) {            /* search by host name */
1771            for(i = 1; i <= (int)(d->name[0]); i++)
1772                if(tolower(qs[i]) != d->name[i])
1773-                   continue;
1774+                   break;
1775+           if(i > (int)(d->name[0])) {
1776 #ifdef DEBUG
1777-           fprintf(stderr, " OK");
1778+               fprintf(stderr, " OK");
1779 #endif
1780-           strcpy((char *)as, d->ip);
1781+               strcpy((char *)as, d->ip);
1782 #ifdef DEBUG
1783-           fprintf(stderr, " %s ", as);
1784+               fprintf(stderr, " as:%s\n", as);
1785 #endif
1786-                   return 0;
1787-               }
1788-       else if (type == REQ_PTR) { /* search by IP-address */
1789+               return 0;
1790+           }
1791+       } else
1792+       if (type == REQ_PTR) {          /* search by IP-address */
1793            if (!strncmp((char*)&d->rip[1], (char*)&qs[1], strlen(d->rip)-1)) {
1794                strcpy((char *)as, d->name);
1795                return 0;
1796@@ -281,7 +292,7 @@ static int process_packet(uint8_t * buf)
1797        eret("ignoring response packet");
1798 
1799    from = (void *)&head[1];    //  start of query string
1800-   next = answb = from + strlen((char *)&head[1]) + 1 + sizeof(struct dns_prop);   // where to append answer block
1801+   next = answb = from + strlen((char *)from) + 1 + sizeof(struct dns_prop);   // where to append answer block
1802 
1803    outr.rlen = 0;          // may change later
1804    outr.r = NULL;
1805@@ -305,9 +316,8 @@ static int process_packet(uint8_t * buf)
1806        goto empty_packet;
1807 
1808    // We have a standard query
1809-
1810-   log_message(LOG_FILE, (char *)head);
1811-   lookup_result = table_lookup(type, answstr, (uint8_t*)(&head[1]));
1812+   log_message(LOG_FILE, (char *)from);
1813+   lookup_result = table_lookup(type, answstr, (uint8_t*)from);
1814    if (lookup_result != 0) {
1815        outr.flags = 3 | 0x0400;    //name do not exist and auth
1816        goto empty_packet;
1817@@ -341,8 +351,7 @@ static int process_packet(uint8_t * buf)
1818    memcpy(next, (void *)answstr, outr.rlen);
1819    next += outr.rlen;
1820 
1821-      empty_packet:
1822-
1823+empty_packet:
1824    flags = ntohs(head->flags);
1825    // clear rcode and RA, set responsebit and our new flags
1826    flags |= (outr.flags & 0xff80) | 0x8000;
1827@@ -364,9 +373,6 @@ static void interrupt(int x)
1828    exit(2);
1829 }
1830 
1831-#define is_daemon()  (flags&16)
1832-#define is_verbose() (flags&32)
1833-//#define DEBUG 1
1834 
1835 int dnsd_main(int argc, char **argv)
1836 {
1837@@ -437,8 +443,8 @@ int dnsd_main(int argc, char **argv)
1838                     (struct sockaddr *)&from,
1839                     (void *)&fromlen);
1840            if(is_verbose())
1841-               fprintf(stderr, "\n--- Got UDP  ");
1842-           log_message(LOG_FILE, "\n--- Got UDP  ");
1843+               fprintf(stderr, "\n--- Got UDP size=%d ", r);
1844+           log_message(LOG_FILE, "\n--- Got UDP ");
1845 
1846            if (r < 12 || r > 512) {
1847                bb_error_msg("invalid packet size");
Note: See TracBrowser for help on using the repository browser.