aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Andersen <andersen@codepoet.org>2000-03-04 21:19:32 +0000
committerErik Andersen <andersen@codepoet.org>2000-03-04 21:19:32 +0000
commit029011b9eeaf491d00fda1d072c4c6094df96c3a (patch)
tree7c49f1fc1547a2f9cee812472f422a5c1a5c448b
parent7c4b2f3fe5cb6b9a5c6bd089c18279c5ce29dc21 (diff)
downloadbusybox-w32-029011b9eeaf491d00fda1d072c4c6094df96c3a.tar.gz
busybox-w32-029011b9eeaf491d00fda1d072c4c6094df96c3a.tar.bz2
busybox-w32-029011b9eeaf491d00fda1d072c4c6094df96c3a.zip
A few updates (including the cp fix the Craig has been looking for)
-Erik
-rw-r--r--AUTHORS3
-rw-r--r--Changelog14
-rw-r--r--TODO24
-rw-r--r--applets/busybox.c18
-rw-r--r--busybox.c18
-rw-r--r--busybox.def.h3
-rw-r--r--cat.c8
-rw-r--r--chmod_chown_chgrp.c8
-rw-r--r--chroot.c9
-rw-r--r--chvt.c9
-rw-r--r--console-tools/chvt.c9
-rw-r--r--coreutils/cat.c8
-rw-r--r--coreutils/chroot.c9
-rw-r--r--coreutils/df.c8
-rw-r--r--coreutils/du.c71
-rw-r--r--coreutils/ln.c8
-rw-r--r--coreutils/sort.c28
-rw-r--r--cp_mv.c279
-rw-r--r--df.c8
-rw-r--r--du.c71
-rw-r--r--init.c11
-rw-r--r--init/init.c11
-rw-r--r--init/reboot.c8
-rw-r--r--internal.h11
-rw-r--r--ln.c8
-rw-r--r--miscutils/update.c86
-rw-r--r--reboot.c8
-rw-r--r--sort.c28
-rw-r--r--tests/Makefile23
-rw-r--r--tests/cp_tests.mk170
-rw-r--r--tests/ln_tests.mk9
-rw-r--r--tests/mv_tests.mk41
-rw-r--r--update.c86
-rw-r--r--utility.c80
34 files changed, 817 insertions, 376 deletions
diff --git a/AUTHORS b/AUTHORS
index 7986afc94..526205b49 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -37,4 +37,5 @@ Charles P. Wright <cpwright@villagenet.com>
37Enrique Zanardi <ezanardi@ull.es> 37Enrique Zanardi <ezanardi@ull.es>
38 tarcat (since removed), loadkmap, various fixes, Debian maintenance 38 tarcat (since removed), loadkmap, various fixes, Debian maintenance
39 39
40 40Karl M. Hegbloom <karlheg@debian.org>
41 cp_mv.c, the test suite, various fixes to utility.c, &c.
diff --git a/Changelog b/Changelog
index 3c90ab97f..0398ce93e 100644
--- a/Changelog
+++ b/Changelog
@@ -18,6 +18,20 @@
18 free). Use of /proc (or not) is policy that should be set up in 18 free). Use of /proc (or not) is policy that should be set up in
19 /etc/fstab (or in hardcoded scripts), not in init. 19 /etc/fstab (or in hardcoded scripts), not in init.
20 * Fixed rebooting when init runs as an initrd. 20 * Fixed rebooting when init runs as an initrd.
21 * Fixes and updates from Karl M. Hegbloom <karlheg@debian.org>
22 - update.c rewritten to look more like update-2.11
23 - moveed the inode hash out of du.c and into utility.c to make
24 it a common resource that can be used by other apps.
25 - cp_mv.c now checks inodes to see if a source and dest are
26 the same, and prints an error (instead of endlessly looping).
27 - mv now attempts to do a rename, and will fall back to doing
28 a copy only if the rename fails.
29 * Several fixes from Pavel Roskin <pavel_roskin@geocities.com>:
30 - Fixes to sort. Removed "-g", fixed and added "-r"
31 - Fixes to the makefile for handling "strip"
32 * An initial telnet implementation was added by
33 Randolph Chung <tausq@debian.org>.
34
21 35
22 -Erik Andersen 36 -Erik Andersen
23 37
diff --git a/TODO b/TODO
index e05558b04..daa21cffd 100644
--- a/TODO
+++ b/TODO
@@ -53,12 +53,6 @@ Hmm. Needs to be carefully thought out.
53----------------------- 53-----------------------
54 54
55 55
56
57Some known bugs, todo items, etc...
58
59-----------------------
60
61
62-rw-r--r-- 1000/1000 4398 2000-01-06 21:55 uniq.c 56-rw-r--r-- 1000/1000 4398 2000-01-06 21:55 uniq.c
63-rw-r--r-- 1000/1000 1568 1999-10-20 18:08 update.c 57-rw-r--r-- 1000/1000 1568 1999-10-20 18:08 update.c
64-rw-r----- 0/1000 1168 2000-01-29 21:03 update.o 58-rw-r----- 0/1000 1168 2000-01-29 21:03 update.o
@@ -116,3 +110,21 @@ messages from the embedded box logged to a remote network
116syslog box, right? I can see that this would be useful. 110syslog box, right? I can see that this would be useful.
117I'll add this to the TODO list, 111I'll add this to the TODO list,
118 112
113
114-----------------------
115
116
117 In utility.c:copyFile: It uses followLinks for both source and
118 destination files... is that right for `mv'? Will need to revisit
119 the GNU, freeBSD, and MINIX versions for this... Should read the
120 Unix98 and POSIX specs also.
121
122-----------------------
123
124 I think that the add_inode &c in utility.c needs to also stow the
125 st_dev field, and that du.c should NOT call `reset_inode_list'
126 because there can be hard links from inside one argv/ to inside
127 another argv/. du.c probably ought to have an -x switch like GNU du
128 does also...
129
130
diff --git a/applets/busybox.c b/applets/busybox.c
index 13f8db909..a80a5678f 100644
--- a/applets/busybox.c
+++ b/applets/busybox.c
@@ -300,15 +300,17 @@ static const struct Applet applets[] = {
300 300
301int main(int argc, char **argv) 301int main(int argc, char **argv)
302{ 302{
303 char *s = argv[0]; 303 char *s = argv[0];
304 char *name = argv[0]; 304 char *name = argv[0];
305 const struct Applet *a = applets; 305 const struct Applet *a = applets;
306 306
307 while (*s != '\0') { 307 while (*s != '\0') {
308 if (*s++ == '/') 308 if (*s++ == '/')
309 name = s; 309 name = s;
310 } 310 }
311 311
312 *argv = name;
313
312 while (a->name != 0) { 314 while (a->name != 0) {
313 if (strcmp(name, a->name) == 0) { 315 if (strcmp(name, a->name) == 0) {
314 int status; 316 int status;
@@ -341,7 +343,7 @@ int busybox_main(int argc, char **argv)
341 fprintf(stderr, "Usage: busybox [function] [arguments]...\n"); 343 fprintf(stderr, "Usage: busybox [function] [arguments]...\n");
342 fprintf(stderr, " or: [function] [arguments]...\n\n"); 344 fprintf(stderr, " or: [function] [arguments]...\n\n");
343 fprintf(stderr, 345 fprintf(stderr,
344 "\tMost people will create a symlink to busybox for each\n" 346 "\tMost people will create a link to busybox for each\n"
345 "\tfunction name, and busybox will act like whatever you invoke it as.\n"); 347 "\tfunction name, and busybox will act like whatever you invoke it as.\n");
346 fprintf(stderr, "\nCurrently defined functions:\n"); 348 fprintf(stderr, "\nCurrently defined functions:\n");
347 349
@@ -362,3 +364,11 @@ int busybox_main(int argc, char **argv)
362 return (main(argc, argv)); 364 return (main(argc, argv));
363 } 365 }
364} 366}
367
368/*
369Local Variables:
370c-file-style: "linux"
371c-basic-offset: 4
372tab-width: 4
373End:
374*/
diff --git a/busybox.c b/busybox.c
index 13f8db909..a80a5678f 100644
--- a/busybox.c
+++ b/busybox.c
@@ -300,15 +300,17 @@ static const struct Applet applets[] = {
300 300
301int main(int argc, char **argv) 301int main(int argc, char **argv)
302{ 302{
303 char *s = argv[0]; 303 char *s = argv[0];
304 char *name = argv[0]; 304 char *name = argv[0];
305 const struct Applet *a = applets; 305 const struct Applet *a = applets;
306 306
307 while (*s != '\0') { 307 while (*s != '\0') {
308 if (*s++ == '/') 308 if (*s++ == '/')
309 name = s; 309 name = s;
310 } 310 }
311 311
312 *argv = name;
313
312 while (a->name != 0) { 314 while (a->name != 0) {
313 if (strcmp(name, a->name) == 0) { 315 if (strcmp(name, a->name) == 0) {
314 int status; 316 int status;
@@ -341,7 +343,7 @@ int busybox_main(int argc, char **argv)
341 fprintf(stderr, "Usage: busybox [function] [arguments]...\n"); 343 fprintf(stderr, "Usage: busybox [function] [arguments]...\n");
342 fprintf(stderr, " or: [function] [arguments]...\n\n"); 344 fprintf(stderr, " or: [function] [arguments]...\n\n");
343 fprintf(stderr, 345 fprintf(stderr,
344 "\tMost people will create a symlink to busybox for each\n" 346 "\tMost people will create a link to busybox for each\n"
345 "\tfunction name, and busybox will act like whatever you invoke it as.\n"); 347 "\tfunction name, and busybox will act like whatever you invoke it as.\n");
346 fprintf(stderr, "\nCurrently defined functions:\n"); 348 fprintf(stderr, "\nCurrently defined functions:\n");
347 349
@@ -362,3 +364,11 @@ int busybox_main(int argc, char **argv)
362 return (main(argc, argv)); 364 return (main(argc, argv));
363 } 365 }
364} 366}
367
368/*
369Local Variables:
370c-file-style: "linux"
371c-basic-offset: 4
372tab-width: 4
373End:
374*/
diff --git a/busybox.def.h b/busybox.def.h
index 8ed5a9c66..d42be4422 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -150,6 +150,9 @@
150// Enable support for creation of tar files. 150// Enable support for creation of tar files.
151//#define BB_FEATURE_TAR_CREATE 151//#define BB_FEATURE_TAR_CREATE
152// 152//
153//// Enable reverse sort
154//#define BB_FEATURE_SORT_REVERSE
155//
153// Allow init to permenently chroot, and umount the old root fs 156// Allow init to permenently chroot, and umount the old root fs
154// just like an initrd does. Requires a kernel patch by Werner Almesberger. 157// just like an initrd does. Requires a kernel patch by Werner Almesberger.
155// ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz 158// ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz
diff --git a/cat.c b/cat.c
index 86f85fe8e..58a1b0f54 100644
--- a/cat.c
+++ b/cat.c
@@ -59,3 +59,11 @@ extern int cat_main(int argc, char **argv)
59 } 59 }
60 exit(TRUE); 60 exit(TRUE);
61} 61}
62
63/*
64Local Variables:
65c-file-style: "linux"
66c-basic-offset: 4
67tab-width: 4
68End:
69*/
diff --git a/chmod_chown_chgrp.c b/chmod_chown_chgrp.c
index f037e9591..4e5e9b08e 100644
--- a/chmod_chown_chgrp.c
+++ b/chmod_chown_chgrp.c
@@ -181,3 +181,11 @@ int chmod_chown_chgrp_main(int argc, char **argv)
181 bad_group: 181 bad_group:
182 fatalError( "%s: unknown group name: %s\n", invocationName, groupName); 182 fatalError( "%s: unknown group name: %s\n", invocationName, groupName);
183} 183}
184
185/*
186Local Variables:
187c-file-style: "linux"
188c-basic-offset: 4
189tab-width: 4
190End:
191*/
diff --git a/chroot.c b/chroot.c
index 6a01be603..3622c26dc 100644
--- a/chroot.c
+++ b/chroot.c
@@ -65,3 +65,12 @@ int chroot_main(int argc, char **argv)
65 *argv, strerror(errno)); 65 *argv, strerror(errno));
66 exit(FALSE); 66 exit(FALSE);
67} 67}
68
69
70/*
71Local Variables:
72c-file-style: "linux"
73c-basic-offset: 4
74tab-width: 4
75End:
76*/
diff --git a/chvt.c b/chvt.c
index a32bd3e78..635022a57 100644
--- a/chvt.c
+++ b/chvt.c
@@ -34,3 +34,12 @@ int chvt_main(int argc, char **argv)
34 } 34 }
35 exit(TRUE); 35 exit(TRUE);
36} 36}
37
38
39/*
40Local Variables:
41c-file-style: "linux"
42c-basic-offset: 4
43tab-width: 4
44End:
45*/
diff --git a/console-tools/chvt.c b/console-tools/chvt.c
index a32bd3e78..635022a57 100644
--- a/console-tools/chvt.c
+++ b/console-tools/chvt.c
@@ -34,3 +34,12 @@ int chvt_main(int argc, char **argv)
34 } 34 }
35 exit(TRUE); 35 exit(TRUE);
36} 36}
37
38
39/*
40Local Variables:
41c-file-style: "linux"
42c-basic-offset: 4
43tab-width: 4
44End:
45*/
diff --git a/coreutils/cat.c b/coreutils/cat.c
index 86f85fe8e..58a1b0f54 100644
--- a/coreutils/cat.c
+++ b/coreutils/cat.c
@@ -59,3 +59,11 @@ extern int cat_main(int argc, char **argv)
59 } 59 }
60 exit(TRUE); 60 exit(TRUE);
61} 61}
62
63/*
64Local Variables:
65c-file-style: "linux"
66c-basic-offset: 4
67tab-width: 4
68End:
69*/
diff --git a/coreutils/chroot.c b/coreutils/chroot.c
index 6a01be603..3622c26dc 100644
--- a/coreutils/chroot.c
+++ b/coreutils/chroot.c
@@ -65,3 +65,12 @@ int chroot_main(int argc, char **argv)
65 *argv, strerror(errno)); 65 *argv, strerror(errno));
66 exit(FALSE); 66 exit(FALSE);
67} 67}
68
69
70/*
71Local Variables:
72c-file-style: "linux"
73c-basic-offset: 4
74tab-width: 4
75End:
76*/
diff --git a/coreutils/df.c b/coreutils/df.c
index 43d5d26e7..bc843f7a2 100644
--- a/coreutils/df.c
+++ b/coreutils/df.c
@@ -108,3 +108,11 @@ extern int df_main(int argc, char **argv)
108 108
109 exit(TRUE); 109 exit(TRUE);
110} 110}
111
112/*
113Local Variables:
114c-file-style: "linux"
115c-basic-offset: 4
116tab-width: 4
117End:
118*/
diff --git a/coreutils/du.c b/coreutils/du.c
index 4dc7ea13a..b6ebaca7a 100644
--- a/coreutils/du.c
+++ b/coreutils/du.c
@@ -36,16 +36,6 @@
36 36
37typedef void (Display) (long, char *); 37typedef void (Display) (long, char *);
38 38
39typedef struct inode_type {
40 struct inode_type *next;
41 ino_t ino;
42} INODETYPE;
43
44#define HASH_SIZE 311 /* Should be prime */
45#define hash_inode(i) ((i) % HASH_SIZE)
46
47static INODETYPE *inode_hash_list[HASH_SIZE];
48
49static const char du_usage[] = 39static const char du_usage[] =
50 "du [OPTION]... [FILE]...\n\n" 40 "du [OPTION]... [FILE]...\n\n"
51 "Summarize disk space used for each FILE and/or directory.\n" 41 "Summarize disk space used for each FILE and/or directory.\n"
@@ -71,52 +61,6 @@ static void print_summary(long size, char *filename)
71 } 61 }
72} 62}
73 63
74/* Return 1 if inode is in inode hash list, else return 0 */
75static int is_in_list(const ino_t ino)
76{
77 INODETYPE *inode;
78
79 inode = inode_hash_list[hash_inode(ino)];
80 while (inode != NULL) {
81 if (inode->ino == ino)
82 return 1;
83 inode = inode->next;
84 }
85
86 return 0;
87}
88
89/* Add inode to inode hash list */
90static void add_inode(const ino_t ino)
91{
92 int i;
93 INODETYPE *inode;
94
95 i = hash_inode(ino);
96 inode = malloc(sizeof(INODETYPE));
97 if (inode == NULL)
98 fatalError("du: Not enough memory.");
99
100 inode->ino = ino;
101 inode->next = inode_hash_list[i];
102 inode_hash_list[i] = inode;
103}
104
105/* Clear inode hash list */
106static void reset_inode_list(void)
107{
108 int i;
109 INODETYPE *inode;
110
111 for (i = 0; i < HASH_SIZE; i++) {
112 while (inode_hash_list[i] != NULL) {
113 inode = inode_hash_list[i]->next;
114 free(inode_hash_list[i]);
115 inode_hash_list[i] = inode;
116 }
117 }
118}
119
120/* tiny recursive du */ 64/* tiny recursive du */
121static long du(char *filename) 65static long du(char *filename)
122{ 66{
@@ -175,13 +119,13 @@ static long du(char *filename)
175 } 119 }
176 else if (statbuf.st_nlink > 1 && !count_hardlinks) { 120 else if (statbuf.st_nlink > 1 && !count_hardlinks) {
177 /* Add files with hard links only once */ 121 /* Add files with hard links only once */
178 if (is_in_list(statbuf.st_ino)) { 122 if (is_in_ino_dev_hashtable(&statbuf, NULL)) {
179 sum = 0L; 123 sum = 0L;
180 if (du_depth == 1) 124 if (du_depth == 1)
181 print(sum, filename); 125 print(sum, filename);
182 } 126 }
183 else { 127 else {
184 add_inode(statbuf.st_ino); 128 add_to_ino_dev_hashtable(&statbuf, NULL);
185 } 129 }
186 } 130 }
187 du_depth--; 131 du_depth--;
@@ -231,11 +175,18 @@ int du_main(int argc, char **argv)
231 if (sum && isDirectory(argv[i], FALSE, NULL)) { 175 if (sum && isDirectory(argv[i], FALSE, NULL)) {
232 print_normal(sum, argv[i]); 176 print_normal(sum, argv[i]);
233 } 177 }
234 reset_inode_list(); 178 reset_ino_dev_hashtable();
235 } 179 }
236 } 180 }
237 181
238 exit(0); 182 exit(0);
239} 183}
240 184
241/* $Id: du.c,v 1.15 2000/02/21 17:27:17 erik Exp $ */ 185/* $Id: du.c,v 1.16 2000/03/04 21:19:32 erik Exp $ */
186/*
187Local Variables:
188c-file-style: "linux"
189c-basic-offset: 4
190tab-width: 4
191End:
192*/
diff --git a/coreutils/ln.c b/coreutils/ln.c
index 0715bfaed..c54026c62 100644
--- a/coreutils/ln.c
+++ b/coreutils/ln.c
@@ -128,3 +128,11 @@ extern int ln_main(int argc, char **argv)
128 } 128 }
129 exit TRUE; 129 exit TRUE;
130} 130}
131
132/*
133Local Variables:
134c-file-style: "linux"
135c-basic-offset: 4
136tab-width: 4
137End:
138*/
diff --git a/coreutils/sort.c b/coreutils/sort.c
index 609c5e08c..e6894f6c3 100644
--- a/coreutils/sort.c
+++ b/coreutils/sort.c
@@ -29,7 +29,18 @@
29#include <stdio.h> 29#include <stdio.h>
30#include <errno.h> 30#include <errno.h>
31 31
32static const char sort_usage[] = "sort [OPTION]... [FILE]...\n\n"; 32static const char sort_usage[] = "sort [-n]"
33#ifdef BB_FEATURE_SORT_REVERSE
34" [-r]"
35#endif
36" [FILE]...\n\n";
37
38#ifdef BB_FEATURE_SORT_REVERSE
39#define APPLY_REVERSE(x) (reverse ? -(x) : (x))
40static int reverse = 0;
41#else
42#define APPLY_REVERSE(x) (x)
43#endif
33 44
34/* typedefs _______________________________________________________________ */ 45/* typedefs _______________________________________________________________ */
35 46
@@ -120,7 +131,7 @@ static int compare_ascii(const void *a, const void *b)
120 y = *doh; 131 y = *doh;
121 132
122 // fprintf(stdout, "> %p: %s< %p: %s", x, x->data, y, y->data); 133 // fprintf(stdout, "> %p: %s< %p: %s", x, x->data, y, y->data);
123 return strcmp(x->data, y->data); 134 return APPLY_REVERSE(strcmp(x->data, y->data));
124} 135}
125 136
126/* numeric order */ 137/* numeric order */
@@ -138,7 +149,7 @@ static int compare_numeric(const void *a, const void *b)
138 xint = strtoul(x->data, NULL, 10); 149 xint = strtoul(x->data, NULL, 10);
139 yint = strtoul(y->data, NULL, 10); 150 yint = strtoul(y->data, NULL, 10);
140 151
141 return (xint - yint); 152 return APPLY_REVERSE(xint - yint);
142} 153}
143 154
144 155
@@ -254,20 +265,19 @@ int sort_main(int argc, char **argv)
254 if (argv[i][0] == '-') { 265 if (argv[i][0] == '-') {
255 opt = argv[i][1]; 266 opt = argv[i][1];
256 switch (opt) { 267 switch (opt) {
257 case 'g':
258 /* what's the diff between -g && -n? */
259 compare = compare_numeric;
260 break;
261 case 'h': 268 case 'h':
262 usage(sort_usage); 269 usage(sort_usage);
263 break; 270 break;
264 case 'n': 271 case 'n':
265 /* what's the diff between -g && -n? */ 272 /* numeric comparison */
266 compare = compare_numeric; 273 compare = compare_numeric;
267 break; 274 break;
275#ifdef BB_FEATURE_SORT_REVERSE
268 case 'r': 276 case 'r':
269 /* reverse */ 277 /* reverse */
278 reverse = 1;
270 break; 279 break;
280#endif
271 default: 281 default:
272 fprintf(stderr, "sort: invalid option -- %c\n", opt); 282 fprintf(stderr, "sort: invalid option -- %c\n", opt);
273 usage(sort_usage); 283 usage(sort_usage);
@@ -310,4 +320,4 @@ int sort_main(int argc, char **argv)
310 exit(0); 320 exit(0);
311} 321}
312 322
313/* $Id: sort.c,v 1.11 2000/02/08 19:58:47 erik Exp $ */ 323/* $Id: sort.c,v 1.12 2000/03/04 21:19:32 erik Exp $ */
diff --git a/cp_mv.c b/cp_mv.c
index 4c55e62d0..8dbc4e8f1 100644
--- a/cp_mv.c
+++ b/cp_mv.c
@@ -37,11 +37,15 @@
37#include <utime.h> 37#include <utime.h>
38#include <dirent.h> 38#include <dirent.h>
39#include <sys/param.h> 39#include <sys/param.h>
40#include <setjmp.h> /* Ok to use this since `ash' does, therefore it's in the libc subset already. */
41#include <string.h>
42#include <unistd.h>
43#include <errno.h>
40 44
41#define is_cp 0 45#define is_cp 0
42#define is_mv 1 46#define is_mv 1
47static int dz_i; /* index into cp_mv_usage */
43static const char *dz; /* dollar zero, .bss */ 48static const char *dz; /* dollar zero, .bss */
44static int dz_i; /* index, .bss */
45static const char *cp_mv_usage[] = /* .rodata */ 49static const char *cp_mv_usage[] = /* .rodata */
46{ 50{
47 "cp [OPTION]... SOURCE DEST\n" 51 "cp [OPTION]... SOURCE DEST\n"
@@ -55,92 +59,131 @@ static const char *cp_mv_usage[] = /* .rodata */
55 "mv SOURCE DEST\n" 59 "mv SOURCE DEST\n"
56 " or: mv SOURCE... DIRECTORY\n\n" 60 " or: mv SOURCE... DIRECTORY\n\n"
57 "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n" 61 "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n"
58 "Warning!! This is not GNU `mv'. It does not preserve hard links.\n"
59}; 62};
60 63
61extern int cp_mv_main(int argc, char **argv) 64static int recursiveFlag;
65static int followLinks;
66static int preserveFlag;
67
68static const char *baseSrcName;
69static int srcDirFlag;
70static struct stat srcStatBuf;
71
72static char baseDestName[PATH_MAX + 1];
73static size_t baseDestLen;
74static int destDirFlag;
75static struct stat destStatBuf;
76
77static jmp_buf catch;
78static volatile int mv_Action_first_time;
79
80static void name_too_long__exit (void) __attribute__((noreturn));
81
82static
83void name_too_long__exit (void)
62{ 84{
63 __label__ name_too_long__exit; 85 fprintf(stderr, name_too_long, dz);
64 __label__ exit_false; 86 exit FALSE;
65 87}
66 int recursiveFlag; 88
67 int followLinks; 89static void
68 int preserveFlag; 90fill_baseDest_buf(char *_buf, size_t * _buflen) {
69 91 const char *srcBasename;
70 const char *baseSrcName; 92 if ((srcBasename = strrchr(baseSrcName, '/')) == NULL) {
71 int srcDirFlag; 93 srcBasename = baseSrcName;
72 struct stat srcStatBuf; 94 if (_buf[*_buflen - 1] != '/') {
73 95 if (++(*_buflen) > PATH_MAX)
74 char baseDestName[PATH_MAX + 1]; 96 name_too_long__exit();
75 size_t baseDestLen; 97 strcat(_buf, "/");
76 int destDirFlag;
77 struct stat destStatBuf;
78
79 void fill_baseDest_buf(char *_buf, size_t * _buflen) {
80 const char *srcBasename;
81 if ((srcBasename = strrchr(baseSrcName, '/')) == NULL) {
82 srcBasename = baseSrcName;
83 if (_buf[*_buflen - 1] != '/') {
84 if (++(*_buflen) > PATH_MAX)
85 goto name_too_long__exit;
86 strcat(_buf, "/");
87 }
88 } 98 }
89 if (*_buflen + strlen(srcBasename) > PATH_MAX)
90 goto name_too_long__exit;
91 strcat(_buf, srcBasename);
92 return;
93 } 99 }
100 if (*_buflen + strlen(srcBasename) > PATH_MAX)
101 name_too_long__exit();
102 strcat(_buf, srcBasename);
103 return;
104
105}
94 106
95 int fileAction(const char *fileName, struct stat *statbuf) { 107static int
96 char destName[PATH_MAX + 1]; 108cp_mv_Action(const char *fileName, struct stat *statbuf)
97 size_t destLen; 109{
98 const char *srcBasename; 110 char destName[PATH_MAX + 1];
111 size_t destLen;
112 const char *srcBasename;
113 char *name;
99 114
100 strcpy(destName, baseDestName); 115 strcpy(destName, baseDestName);
101 destLen = strlen(destName); 116 destLen = strlen(destName);
102 117
103 if (srcDirFlag == TRUE) { 118 if (srcDirFlag == TRUE) {
104 if (recursiveFlag == FALSE) { 119 if (recursiveFlag == FALSE) {
105 fprintf(stderr, omitting_directory, "cp", baseSrcName); 120 fprintf(stderr, omitting_directory, dz, baseSrcName);
106 return TRUE; 121 return TRUE;
107 } 122 }
108 srcBasename = (strstr(fileName, baseSrcName) 123 srcBasename = (strstr(fileName, baseSrcName)
109 + strlen(baseSrcName)); 124 + strlen(baseSrcName));
110 125
111 if (destLen + strlen(srcBasename) > PATH_MAX) { 126 if (destLen + strlen(srcBasename) > PATH_MAX) {
112 fprintf(stderr, name_too_long, "cp"); 127 fprintf(stderr, name_too_long, dz);
128 return FALSE;
129 }
130 strcat(destName, srcBasename);
131 }
132 else if (destDirFlag == TRUE) {
133 fill_baseDest_buf(&destName[0], &destLen);
134 }
135 else {
136 srcBasename = baseSrcName;
137 }
138 if (mv_Action_first_time && (dz_i == is_mv)) {
139 mv_Action_first_time = errno = 0;
140 if (rename(fileName, destName) < 0 && errno != EXDEV) {
141 fprintf(stderr, "%s: rename(%s, %s): %s\n",
142 dz, fileName, destName, strerror(errno));
143 goto do_copyFile; /* Try anyway... */
144 }
145 else if (errno == EXDEV)
146 goto do_copyFile;
147 else
148 longjmp(catch, 1); /* succeeded with rename() */
149 }
150 do_copyFile:
151 if (preserveFlag == TRUE && statbuf->st_nlink > 1) {
152 if (is_in_ino_dev_hashtable(statbuf, &name)) {
153 if (link(name, destName) < 0) {
154 fprintf(stderr, "%s: link(%s, %s): %s\n",
155 dz, name, destName, strerror(errno));
113 return FALSE; 156 return FALSE;
114 } 157 }
115 strcat(destName, srcBasename); 158 return TRUE;
116 } else if (destDirFlag == TRUE) {
117 fill_baseDest_buf(&destName[0], &destLen);
118 } else {
119 srcBasename = baseSrcName;
120 } 159 }
121 return copyFile(fileName, destName, preserveFlag, followLinks); 160 else {
122 } 161 add_to_ino_dev_hashtable(statbuf, destName);
123
124 int rmfileAction(const char *fileName, struct stat *statbuf) {
125 if (unlink(fileName) < 0) {
126 perror(fileName);
127 return FALSE;
128 } 162 }
129 return TRUE;
130 } 163 }
164 return copyFile(fileName, destName, preserveFlag, followLinks);
165}
166
167static int
168rm_Action(const char *fileName, struct stat *statbuf)
169{
170 int status = TRUE;
131 171
132 int rmdirAction(const char *fileName, struct stat *statbuf) { 172 if (S_ISDIR(statbuf->st_mode)) {
133 if (rmdir(fileName) < 0) { 173 if (rmdir(fileName) < 0) {
134 perror(fileName); 174 fprintf(stderr, "%s: rmdir(%s): %s\n", dz, fileName, strerror(errno));
135 return FALSE; 175 status = FALSE;
136 } 176 }
137 return TRUE; 177 } else if (unlink(fileName) < 0) {
178 fprintf(stderr, "%s: unlink(%s): %s\n", dz, fileName, strerror(errno));
179 status = FALSE;
138 } 180 }
181 return status;
182}
139 183
140 if ((dz = strrchr(*argv, '/')) == NULL) 184extern int cp_mv_main(int argc, char **argv)
141 dz = *argv; 185{
142 else 186 dz = *argv; /* already basename'd by busybox.c:main */
143 dz++;
144 if (*dz == 'c' && *(dz + 1) == 'p') 187 if (*dz == 'c' && *(dz + 1) == 'p')
145 dz_i = is_cp; 188 dz_i = is_cp;
146 else 189 else
@@ -199,53 +242,93 @@ extern int cp_mv_main(int argc, char **argv)
199 242
200 while (argc-- > 1) { 243 while (argc-- > 1) {
201 size_t srcLen; 244 size_t srcLen;
202 int flags_memo; 245 volatile int flags_memo;
246 int status;
203 247
204 baseSrcName = *(argv++); 248 baseSrcName = *(argv++);
205 249
206 if ((srcLen = strlen(baseSrcName)) > PATH_MAX) 250 if ((srcLen = strlen(baseSrcName)) > PATH_MAX)
207 goto name_too_long__exit; 251 name_too_long__exit();
208 252
209 if (srcLen == 0) 253 if (srcLen == 0) continue; /* "" */
210 continue;
211 254
212 srcDirFlag = isDirectory(baseSrcName, followLinks, &srcStatBuf); 255 srcDirFlag = isDirectory(baseSrcName, followLinks, &srcStatBuf);
213 256
214 if ((flags_memo = (recursiveFlag == TRUE && 257 if ((flags_memo = (recursiveFlag == TRUE &&
215 srcDirFlag == TRUE && destDirFlag == TRUE))) { 258 srcDirFlag == TRUE && destDirFlag == TRUE))) {
216 if ((destStatBuf.st_ino == srcStatBuf.st_ino) && 259
217 (destStatBuf.st_rdev == srcStatBuf.st_rdev)) { 260 struct stat sb;
218 fprintf(stderr, 261 int state = 0;
219 "%s: Cannot %s `%s' into a subdirectory of itself, `%s/%s'\n", 262 char *pushd, *d, *p;
220 dz, dz, baseSrcName, baseDestName, baseSrcName); 263
221 continue; 264 if ((pushd = getcwd(NULL, PATH_MAX + 1)) == NULL) {
265 fprintf(stderr, "%s: getcwd(): %s\n", dz, strerror(errno));
266 continue;
267 }
268 if (chdir(baseDestName) < 0) {
269 fprintf(stderr, "%s: chdir(%s): %s\n", dz, baseSrcName, strerror(errno));
270 continue;
271 }
272 if ((d = getcwd(NULL, PATH_MAX + 1)) == NULL) {
273 fprintf(stderr, "%s: getcwd(): %s\n", dz, strerror(errno));
274 continue;
275 }
276 while (!state && *d != '\0') {
277 if (stat(d, &sb) < 0) { /* stat not lstat - always dereference targets */
278 fprintf(stderr, "%s: stat(%s) :%s\n", dz, d, strerror(errno));
279 state = -1;
280 continue;
281 }
282 if ((sb.st_ino == srcStatBuf.st_ino) &&
283 (sb.st_dev == srcStatBuf.st_dev)) {
284 fprintf(stderr,
285 "%s: Cannot %s `%s' "
286 "into a subdirectory of itself, `%s/%s'\n",
287 dz, dz, baseSrcName, baseDestName, baseSrcName);
288 state = -1;
289 continue;
222 } 290 }
291 if ((p = strrchr(d, '/')) != NULL) {
292 *p = '\0';
293 }
294 }
295 if (chdir(pushd) < 0) {
296 fprintf(stderr, "%s: chdir(%s): %s\n", dz, pushd, strerror(errno));
297 free(pushd);
298 free(d);
299 continue;
300 }
301 free(pushd);
302 free(d);
303 if (state < 0)
304 continue;
305 else
223 fill_baseDest_buf(baseDestName, &baseDestLen); 306 fill_baseDest_buf(baseDestName, &baseDestLen);
224 } 307 }
225 if (recursiveAction(baseSrcName, 308 status = setjmp(catch);
226 recursiveFlag, followLinks, FALSE, 309 if (status == 0) {
227 fileAction, fileAction) == FALSE) 310 mv_Action_first_time = 1;
228 goto exit_false; 311 if (recursiveAction(baseSrcName,
229 312 recursiveFlag, followLinks, FALSE,
230 if (dz_i == is_mv && 313 cp_mv_Action, cp_mv_Action) == FALSE) goto exit_false;
231 recursiveAction(baseSrcName, 314 if (dz_i == is_mv &&
232 recursiveFlag, followLinks, TRUE, 315 recursiveAction(baseSrcName,
233 rmfileAction, rmdirAction) == FALSE) 316 recursiveFlag, followLinks, TRUE,
234 goto exit_false; 317 rm_Action, rm_Action) == FALSE) goto exit_false;
235 318 }
236 if (flags_memo) 319 if (flags_memo)
237 *(baseDestName + baseDestLen) = '\0'; 320 *(baseDestName + baseDestLen) = '\0';
238 } 321 }
239 322// exit_true:
240 exit TRUE; 323 exit TRUE;
241 324 exit_false:
242 name_too_long__exit:
243 fprintf(stderr, name_too_long, "cp");
244 exit_false:
245 exit FALSE; 325 exit FALSE;
246} 326}
247 327
248// Local Variables: 328/*
249// c-file-style: "linux" 329Local Variables:
250// tab-width: 4 330c-file-style: "linux"
251// End: 331c-basic-offset: 4
332tab-width: 4
333End:
334*/
diff --git a/df.c b/df.c
index 43d5d26e7..bc843f7a2 100644
--- a/df.c
+++ b/df.c
@@ -108,3 +108,11 @@ extern int df_main(int argc, char **argv)
108 108
109 exit(TRUE); 109 exit(TRUE);
110} 110}
111
112/*
113Local Variables:
114c-file-style: "linux"
115c-basic-offset: 4
116tab-width: 4
117End:
118*/
diff --git a/du.c b/du.c
index 4dc7ea13a..b6ebaca7a 100644
--- a/du.c
+++ b/du.c
@@ -36,16 +36,6 @@
36 36
37typedef void (Display) (long, char *); 37typedef void (Display) (long, char *);
38 38
39typedef struct inode_type {
40 struct inode_type *next;
41 ino_t ino;
42} INODETYPE;
43
44#define HASH_SIZE 311 /* Should be prime */
45#define hash_inode(i) ((i) % HASH_SIZE)
46
47static INODETYPE *inode_hash_list[HASH_SIZE];
48
49static const char du_usage[] = 39static const char du_usage[] =
50 "du [OPTION]... [FILE]...\n\n" 40 "du [OPTION]... [FILE]...\n\n"
51 "Summarize disk space used for each FILE and/or directory.\n" 41 "Summarize disk space used for each FILE and/or directory.\n"
@@ -71,52 +61,6 @@ static void print_summary(long size, char *filename)
71 } 61 }
72} 62}
73 63
74/* Return 1 if inode is in inode hash list, else return 0 */
75static int is_in_list(const ino_t ino)
76{
77 INODETYPE *inode;
78
79 inode = inode_hash_list[hash_inode(ino)];
80 while (inode != NULL) {
81 if (inode->ino == ino)
82 return 1;
83 inode = inode->next;
84 }
85
86 return 0;
87}
88
89/* Add inode to inode hash list */
90static void add_inode(const ino_t ino)
91{
92 int i;
93 INODETYPE *inode;
94
95 i = hash_inode(ino);
96 inode = malloc(sizeof(INODETYPE));
97 if (inode == NULL)
98 fatalError("du: Not enough memory.");
99
100 inode->ino = ino;
101 inode->next = inode_hash_list[i];
102 inode_hash_list[i] = inode;
103}
104
105/* Clear inode hash list */
106static void reset_inode_list(void)
107{
108 int i;
109 INODETYPE *inode;
110
111 for (i = 0; i < HASH_SIZE; i++) {
112 while (inode_hash_list[i] != NULL) {
113 inode = inode_hash_list[i]->next;
114 free(inode_hash_list[i]);
115 inode_hash_list[i] = inode;
116 }
117 }
118}
119
120/* tiny recursive du */ 64/* tiny recursive du */
121static long du(char *filename) 65static long du(char *filename)
122{ 66{
@@ -175,13 +119,13 @@ static long du(char *filename)
175 } 119 }
176 else if (statbuf.st_nlink > 1 && !count_hardlinks) { 120 else if (statbuf.st_nlink > 1 && !count_hardlinks) {
177 /* Add files with hard links only once */ 121 /* Add files with hard links only once */
178 if (is_in_list(statbuf.st_ino)) { 122 if (is_in_ino_dev_hashtable(&statbuf, NULL)) {
179 sum = 0L; 123 sum = 0L;
180 if (du_depth == 1) 124 if (du_depth == 1)
181 print(sum, filename); 125 print(sum, filename);
182 } 126 }
183 else { 127 else {
184 add_inode(statbuf.st_ino); 128 add_to_ino_dev_hashtable(&statbuf, NULL);
185 } 129 }
186 } 130 }
187 du_depth--; 131 du_depth--;
@@ -231,11 +175,18 @@ int du_main(int argc, char **argv)
231 if (sum && isDirectory(argv[i], FALSE, NULL)) { 175 if (sum && isDirectory(argv[i], FALSE, NULL)) {
232 print_normal(sum, argv[i]); 176 print_normal(sum, argv[i]);
233 } 177 }
234 reset_inode_list(); 178 reset_ino_dev_hashtable();
235 } 179 }
236 } 180 }
237 181
238 exit(0); 182 exit(0);
239} 183}
240 184
241/* $Id: du.c,v 1.15 2000/02/21 17:27:17 erik Exp $ */ 185/* $Id: du.c,v 1.16 2000/03/04 21:19:32 erik Exp $ */
186/*
187Local Variables:
188c-file-style: "linux"
189c-basic-offset: 4
190tab-width: 4
191End:
192*/
diff --git a/init.c b/init.c
index 183739180..350ea62a8 100644
--- a/init.c
+++ b/init.c
@@ -242,6 +242,7 @@ static void console_init()
242 int fd; 242 int fd;
243 int tried_devcons = 0; 243 int tried_devcons = 0;
244 int tried_vtprimary = 0; 244 int tried_vtprimary = 0;
245 struct vt_stat vt;
245 struct serial_struct sr; 246 struct serial_struct sr;
246 char *s; 247 char *s;
247 248
@@ -264,8 +265,6 @@ static void console_init()
264 } 265 }
265#endif 266#endif
266 else { 267 else {
267 struct vt_stat vt;
268
269 /* 2.2 kernels: identify the real console backend and try to use it */ 268 /* 2.2 kernels: identify the real console backend and try to use it */
270 if (ioctl(0, TIOCGSERIAL, &sr) == 0) { 269 if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
271 /* this is a serial console */ 270 /* this is a serial console */
@@ -951,3 +950,11 @@ extern int init_main(int argc, char **argv)
951 sleep(1); 950 sleep(1);
952 } 951 }
953} 952}
953
954/*
955Local Variables:
956c-file-style: "linux"
957c-basic-offset: 4
958tab-width: 4
959End:
960*/
diff --git a/init/init.c b/init/init.c
index 183739180..350ea62a8 100644
--- a/init/init.c
+++ b/init/init.c
@@ -242,6 +242,7 @@ static void console_init()
242 int fd; 242 int fd;
243 int tried_devcons = 0; 243 int tried_devcons = 0;
244 int tried_vtprimary = 0; 244 int tried_vtprimary = 0;
245 struct vt_stat vt;
245 struct serial_struct sr; 246 struct serial_struct sr;
246 char *s; 247 char *s;
247 248
@@ -264,8 +265,6 @@ static void console_init()
264 } 265 }
265#endif 266#endif
266 else { 267 else {
267 struct vt_stat vt;
268
269 /* 2.2 kernels: identify the real console backend and try to use it */ 268 /* 2.2 kernels: identify the real console backend and try to use it */
270 if (ioctl(0, TIOCGSERIAL, &sr) == 0) { 269 if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
271 /* this is a serial console */ 270 /* this is a serial console */
@@ -951,3 +950,11 @@ extern int init_main(int argc, char **argv)
951 sleep(1); 950 sleep(1);
952 } 951 }
953} 952}
953
954/*
955Local Variables:
956c-file-style: "linux"
957c-basic-offset: 4
958tab-width: 4
959End:
960*/
diff --git a/init/reboot.c b/init/reboot.c
index ef2a848ee..f782fa1e6 100644
--- a/init/reboot.c
+++ b/init/reboot.c
@@ -29,3 +29,11 @@ extern int reboot_main(int argc, char **argv)
29 /* don't assume init's pid == 1 */ 29 /* don't assume init's pid == 1 */
30 exit(kill(findInitPid(), SIGINT)); 30 exit(kill(findInitPid(), SIGINT));
31} 31}
32
33/*
34Local Variables:
35c-file-style: "linux"
36c-basic-offset: 4
37tab-width: 4
38End:
39*/
diff --git a/internal.h b/internal.h
index 4d035c962..4c7bd97ed 100644
--- a/internal.h
+++ b/internal.h
@@ -154,6 +154,17 @@ const char *modeString(int mode);
154const char *timeString(time_t timeVal); 154const char *timeString(time_t timeVal);
155int isDirectory(const char *name, const int followLinks, struct stat *statBuf); 155int isDirectory(const char *name, const int followLinks, struct stat *statBuf);
156int isDevice(const char *name); 156int isDevice(const char *name);
157
158typedef struct ino_dev_hash_bucket_struct {
159 struct ino_dev_hash_bucket_struct *next;
160 ino_t ino;
161 dev_t dev;
162 char name[1];
163} ino_dev_hashtable_bucket_t;
164int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name);
165void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name);
166void reset_ino_dev_hashtable(void);
167
157int copyFile(const char *srcName, const char *destName, int setModes, 168int copyFile(const char *srcName, const char *destName, int setModes,
158 int followLinks); 169 int followLinks);
159char *buildName(const char *dirName, const char *fileName); 170char *buildName(const char *dirName, const char *fileName);
diff --git a/ln.c b/ln.c
index 0715bfaed..c54026c62 100644
--- a/ln.c
+++ b/ln.c
@@ -128,3 +128,11 @@ extern int ln_main(int argc, char **argv)
128 } 128 }
129 exit TRUE; 129 exit TRUE;
130} 130}
131
132/*
133Local Variables:
134c-file-style: "linux"
135c-basic-offset: 4
136tab-width: 4
137End:
138*/
diff --git a/miscutils/update.c b/miscutils/update.c
index fef188bba..bb77c5f1f 100644
--- a/miscutils/update.c
+++ b/miscutils/update.c
@@ -1,9 +1,11 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/* 2/*
3 * Mini update implementation for busybox 3 * Mini update implementation for busybox; much pasted from update-2.11
4 * 4 *
5 * 5 *
6 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. 6 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
7 * Copyright (c) 1996, 1997, 1999 Torsten Poulin.
8 * Copyright (c) 2000 by Karl M. Hegbloom <karlheg@debian.org>
7 * 9 *
8 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -23,6 +25,8 @@
23 25
24#include "internal.h" 26#include "internal.h"
25#include <linux/unistd.h> 27#include <linux/unistd.h>
28#include <sys/param.h>
29#include <sys/syslog.h>
26 30
27#if defined(__GLIBC__) 31#if defined(__GLIBC__)
28#include <sys/kdaemon.h> 32#include <sys/kdaemon.h>
@@ -30,37 +34,79 @@
30_syscall2(int, bdflush, int, func, int, data); 34_syscall2(int, bdflush, int, func, int, data);
31#endif /* __GLIBC__ */ 35#endif /* __GLIBC__ */
32 36
37static char update_usage[] =
38 "update [options]\n"
39 " -S\tforce use of sync(2) instead of flushing\n"
40 " -s SECS\tcall sync this often (default 30)\n"
41 " -f SECS\tflush some buffers this often (default 5)\n";
42
43static unsigned int sync_duration = 30;
44static unsigned int flush_duration = 5;
45static int use_sync = 0;
46
33extern int update_main(int argc, char **argv) 47extern int update_main(int argc, char **argv)
34{ 48{
35 /*
36 * Update is actually two daemons, bdflush and update.
37 */
38 int pid; 49 int pid;
39 50
51 while (**argv == '-') {
52 while (*++(*argv)) {
53 switch (**argv) {
54 case 'S':
55 use_sync = 1;
56 break;
57 case 's':
58 if (--argc < 1) usage(update_usage);
59 sync_duration = atoi(*(++argv));
60 break;
61 case 'f':
62 if (--argc < 1) usage(update_usage);
63 flush_duration = atoi(*(++argv));
64 break;
65 }
66 }
67 argc--;
68 argv++;
69 }
70
40 pid = fork(); 71 pid = fork();
41 if (pid < 0) 72 if (pid < 0)
42 return pid; 73 exit(FALSE);
43 else if (pid == 0) { 74 else if (pid == 0) {
75 /* Become a proper daemon */
76 setsid();
77 chdir("/");
78 for (pid = 0; pid < OPEN_MAX; pid++) close(pid);
79
44 /* 80 /*
45 * This is no longer necessary since 1.3.5x, but it will harmlessly 81 * This is no longer necessary since 1.3.5x, but it will harmlessly
46 * exit if that is the case. 82 * exit if that is the case.
47 */ 83 */
48 strcpy(argv[0], "bdflush (update)"); 84 argv[0] = "bdflush (update)";
49 argv[1] = 0; 85 argv[1] = NULL;
50 argv[2] = 0; 86 argv[2] = NULL;
51 bdflush(1, 0);
52 _exit(0);
53 }
54 pid = fork();
55 if (pid < 0)
56 return pid;
57 else if (pid == 0) {
58 argv[0] = "update";
59 for (;;) { 87 for (;;) {
60 sync(); 88 if (use_sync) {
61 sleep(30); 89 sleep(sync_duration);
90 sync();
91 } else {
92 sleep(flush_duration);
93 if (bdflush(1, 0) < 0) {
94 openlog("update", LOG_CONS, LOG_DAEMON);
95 syslog(LOG_INFO,
96 "This kernel does not need update(8). Exiting.");
97 closelog();
98 exit(TRUE);
99 }
100 }
62 } 101 }
63 } 102 }
64 103 return TRUE;
65 return 0;
66} 104}
105
106/*
107Local Variables:
108c-file-style: "linux"
109c-basic-offset: 4
110tab-width: 4
111End:
112*/
diff --git a/reboot.c b/reboot.c
index ef2a848ee..f782fa1e6 100644
--- a/reboot.c
+++ b/reboot.c
@@ -29,3 +29,11 @@ extern int reboot_main(int argc, char **argv)
29 /* don't assume init's pid == 1 */ 29 /* don't assume init's pid == 1 */
30 exit(kill(findInitPid(), SIGINT)); 30 exit(kill(findInitPid(), SIGINT));
31} 31}
32
33/*
34Local Variables:
35c-file-style: "linux"
36c-basic-offset: 4
37tab-width: 4
38End:
39*/
diff --git a/sort.c b/sort.c
index 609c5e08c..e6894f6c3 100644
--- a/sort.c
+++ b/sort.c
@@ -29,7 +29,18 @@
29#include <stdio.h> 29#include <stdio.h>
30#include <errno.h> 30#include <errno.h>
31 31
32static const char sort_usage[] = "sort [OPTION]... [FILE]...\n\n"; 32static const char sort_usage[] = "sort [-n]"
33#ifdef BB_FEATURE_SORT_REVERSE
34" [-r]"
35#endif
36" [FILE]...\n\n";
37
38#ifdef BB_FEATURE_SORT_REVERSE
39#define APPLY_REVERSE(x) (reverse ? -(x) : (x))
40static int reverse = 0;
41#else
42#define APPLY_REVERSE(x) (x)
43#endif
33 44
34/* typedefs _______________________________________________________________ */ 45/* typedefs _______________________________________________________________ */
35 46
@@ -120,7 +131,7 @@ static int compare_ascii(const void *a, const void *b)
120 y = *doh; 131 y = *doh;
121 132
122 // fprintf(stdout, "> %p: %s< %p: %s", x, x->data, y, y->data); 133 // fprintf(stdout, "> %p: %s< %p: %s", x, x->data, y, y->data);
123 return strcmp(x->data, y->data); 134 return APPLY_REVERSE(strcmp(x->data, y->data));
124} 135}
125 136
126/* numeric order */ 137/* numeric order */
@@ -138,7 +149,7 @@ static int compare_numeric(const void *a, const void *b)
138 xint = strtoul(x->data, NULL, 10); 149 xint = strtoul(x->data, NULL, 10);
139 yint = strtoul(y->data, NULL, 10); 150 yint = strtoul(y->data, NULL, 10);
140 151
141 return (xint - yint); 152 return APPLY_REVERSE(xint - yint);
142} 153}
143 154
144 155
@@ -254,20 +265,19 @@ int sort_main(int argc, char **argv)
254 if (argv[i][0] == '-') { 265 if (argv[i][0] == '-') {
255 opt = argv[i][1]; 266 opt = argv[i][1];
256 switch (opt) { 267 switch (opt) {
257 case 'g':
258 /* what's the diff between -g && -n? */
259 compare = compare_numeric;
260 break;
261 case 'h': 268 case 'h':
262 usage(sort_usage); 269 usage(sort_usage);
263 break; 270 break;
264 case 'n': 271 case 'n':
265 /* what's the diff between -g && -n? */ 272 /* numeric comparison */
266 compare = compare_numeric; 273 compare = compare_numeric;
267 break; 274 break;
275#ifdef BB_FEATURE_SORT_REVERSE
268 case 'r': 276 case 'r':
269 /* reverse */ 277 /* reverse */
278 reverse = 1;
270 break; 279 break;
280#endif
271 default: 281 default:
272 fprintf(stderr, "sort: invalid option -- %c\n", opt); 282 fprintf(stderr, "sort: invalid option -- %c\n", opt);
273 usage(sort_usage); 283 usage(sort_usage);
@@ -310,4 +320,4 @@ int sort_main(int argc, char **argv)
310 exit(0); 320 exit(0);
311} 321}
312 322
313/* $Id: sort.c,v 1.11 2000/02/08 19:58:47 erik Exp $ */ 323/* $Id: sort.c,v 1.12 2000/03/04 21:19:32 erik Exp $ */
diff --git a/tests/Makefile b/tests/Makefile
index 015634460..c4fb0e911 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,16 +1,21 @@
1all test_all: message_header cp_tests mv_tests ln_tests 1# busybox/tests/Makefile - Run through all defined tests.
2# ------------------------
3# Copyright (C) 2000 Karl M. Hegbloom <karlheg@debian.org> GPL
2 4
3clean: cp_clean mv_clean ln_clean 5all:: message_header
4 6
5message_header: 7message_header:
6 @echo 8 @echo
7 @echo If tests faile due to differences in timestamps in commands that are not set 9 @echo BusyBox Test Suite.
8 @echo to preserve timestamps, just run the tests again.
9 @echo 10 @echo
10 11
11include cp_tests.mk 12clean::
12include mv_tests.mk 13
13include ln_tests.mk 14distclean: clean
15
16.PHONY: all clean distclean message_header
17
18include $(wildcard *_tests.mk)
14 19
15BBL := $(shell pushd .. >/dev/null && \ 20BBL := $(shell pushd .. >/dev/null && \
16 ${MAKE} busybox.links >/dev/null && \ 21 ${MAKE} busybox.links >/dev/null && \
@@ -21,8 +26,6 @@ BBL := $(shell pushd .. >/dev/null && \
21../busybox: 26../busybox:
22 cd .. && ${MAKE} busybox 27 cd .. && ${MAKE} busybox
23 28
24$(BBL): ../busybox 29${BBL}: ../busybox
25 rm -f $@ 30 rm -f $@
26 ln ../busybox $@ 31 ln ../busybox $@
27
28.PHONY: all test_all message_header
diff --git a/tests/cp_tests.mk b/tests/cp_tests.mk
index e14262ac1..e79f2b38b 100644
--- a/tests/cp_tests.mk
+++ b/tests/cp_tests.mk
@@ -1,18 +1,23 @@
1# This is a -*- makefile -*- 1# cp_tests.mk - Set of test cases for busybox cp
2# -------------
3# Copyright (C) 2000 Karl M. Hegbloom <karlheg@debian.org> GPL
4#
2 5
3# GNU `cp' 6# GNU `cp'
4GCP = /bin/cp 7GCP = /bin/cp
5# BusyBox `cp' 8# BusyBox `cp'
6BCP = $(shell pwd)/cp 9BCP = $(shell pwd)/cp
7 10
8.PHONY: cp_clean 11all:: cp_tests
12clean:: cp_clean
13
9cp_clean: 14cp_clean:
10 rm -rf cp_tests cp_*.{gnu,bb} cp 15 - rm -rf cp_tests cp_*.{gnu,bb} cp
11 16
12.PHONY: cp_tests
13cp_tests: cp_clean cp 17cp_tests: cp_clean cp
14 @echo; 18 @echo;
15 @echo "No output from diff means busybox cp is functioning properly."; 19 @echo "No output from diff means busybox cp is functioning properly.";
20 @echo "Some tests might show timestamp differences that are Ok.";
16 21
17 @echo; 22 @echo;
18 ${BCP} || true; 23 ${BCP} || true;
@@ -20,7 +25,8 @@ cp_tests: cp_clean cp
20 @echo; 25 @echo;
21 mkdir cp_tests; 26 mkdir cp_tests;
22 27
23 @echo; 28 # Copy a file to a copy of the file
29 @echo ------------------------------;
24 cd cp_tests; \ 30 cd cp_tests; \
25 echo A file > afile; \ 31 echo A file > afile; \
26 ls -l afile > ../cp_afile_afilecopy.gnu; \ 32 ls -l afile > ../cp_afile_afilecopy.gnu; \
@@ -28,7 +34,7 @@ cp_tests: cp_clean cp
28 ls -l afile afilecopy >> ../cp_afile_afilecopy.gnu; 34 ls -l afile afilecopy >> ../cp_afile_afilecopy.gnu;
29 35
30 @echo; 36 @echo;
31 rm -f cp_tests/afile*; 37 rm -rf cp_tests/*;
32 38
33 @echo; 39 @echo;
34 cd cp_tests; \ 40 cd cp_tests; \
@@ -38,118 +44,135 @@ cp_tests: cp_clean cp
38 ls -l afile afilecopy >> ../cp_afile_afilecopy.bb; 44 ls -l afile afilecopy >> ../cp_afile_afilecopy.bb;
39 45
40 @echo; 46 @echo;
41 diff -u cp_afile_afilecopy.gnu cp_afile_afilecopy.bb; 47 @echo Might show timestamp differences.
48 -diff -u cp_afile_afilecopy.gnu cp_afile_afilecopy.bb;
42 49
43 @echo; 50 @echo;
44 rm -f cp_tests/afile*; 51 rm -rf cp_tests/*;
45 52
46 @echo; echo; 53 # Copy a file pointed to by a symlink
54 @echo; echo ------------------------------;
47 cd cp_tests; \ 55 cd cp_tests; \
48 mkdir there there1; \ 56 mkdir here there; \
49 cd there; \ 57 echo A file > afile; \
50 ln -s ../afile .; 58 cd here; \
59 ln -s ../afile .; \
51 60
52 @echo; 61 @echo;
53 cd cp_tests; \ 62 cd cp_tests; \
54 echo A file > afile; \ 63 ls -lR . > ../cp_symlink.gnu; \
55 ls -l afile > ../cp_symlink.gnu; \ 64 ${GCP} here/afile there; \
56 ${GCP} there/afile there1/; \ 65 ls -lR . >> ../cp_symlink.gnu;
57 ls -l afile there/afile there1/afile >> ../cp_symlink.gnu;
58 66
59 @echo; 67 @echo;
60 rm -f cp_tests/afile cp_tests/there1/afile; 68 rm -rf cp_tests/there/*;
69
70 sleep 1;
61 71
62 @echo; 72 @echo;
63 cd cp_tests; \ 73 cd cp_tests; \
64 echo A file > afile; \ 74 ls -lR . > ../cp_symlink.bb; \
65 ls -l afile > ../cp_symlink.bb; \ 75 ${BCP} here/afile there; \
66 ${BCP} there/afile there1/; \ 76 ls -lR . >> ../cp_symlink.bb;
67 ls -l afile there/afile there1/afile >> ../cp_symlink.bb;
68 77
69 @echo; 78 @echo;
70 diff -u cp_symlink.gnu cp_symlink.bb; 79 @echo Will show timestamp difference.
80 -diff -u cp_symlink.gnu cp_symlink.bb;
71 81
72 @echo; 82 @echo;
73 rm -f cp_tests/afile cp_tests/there1/afile; 83 rm -rf cp_tests/*
74 84
75 @echo; echo; 85 # Copy a symlink, useing the -a switch.
86 @echo; echo ------------------------------;
76 cd cp_tests; \ 87 cd cp_tests; \
77 echo A file > afile; \ 88 echo A file > afile; \
78 ls -l afile > ../cp_a_symlink.gnu; \ 89 mkdir here there; \
79 ${GCP} -a there/afile there1/; \ 90 cd here; \
80 ls -l afile there/afile there1/afile >> ../cp_a_symlink.gnu; 91 ln -s ../afile .
92
93 cd cp_test; \
94 ls -lR . > ../cp_a_symlink.gnu; \
95 ${GCP} -a here/afile there; \
96 ls -lR . >> ../cp_a_symlink.gnu;
81 97
82 @echo; 98 @echo;
83 rm -f cp_tests/afile cp_tests/there1/afile; 99 rm -f cp_tests/there/*;
100
101 sleep 1;
84 102
85 @echo; 103 @echo;
86 cd cp_tests; \ 104 cd cp_tests; \
87 echo A file > afile; \ 105 echo A file > afile; \
88 ls -l afile > ../cp_a_symlink.bb; \ 106 ls -lR . > ../cp_a_symlink.bb; \
89 ${BCP} -a there/afile there1/; \ 107 ${BCP} -a here/afile there; \
90 ls -l afile there/afile there1/afile >> ../cp_a_symlink.bb; 108 ls -lR . >> ../cp_a_symlink.bb;
91 109
92 @echo; 110 @echo;
93 diff -u cp_a_symlink.gnu cp_a_symlink.bb; 111 diff -u cp_a_symlink.gnu cp_a_symlink.bb;
94 112
95 @echo; 113 @echo;
96 rm -f cp_tests/afile 114 rm -f cp_tests/*;
97 rm -rf cp_tests/there{,1};
98 115
99 @echo; echo; 116 # Copy a directory into another directory with the -a switch
117 @echo; echo ------------------------------;
100 cd cp_tests; \ 118 cd cp_tests; \
101 echo A file > there/afile; \ 119 mkdir here there; \
102 mkdir there/adir; \ 120 echo A file > here/afile; \
103 touch there/adir/afileinadir; \ 121 mkdir here/adir; \
104 ln -s $(shell pwd) there/alink; 122 touch here/adir/afileinadir; \
123 ln -s $$(pwd) here/alink;
105 124
106 @echo; 125 @echo;
107 cd cp_tests; \ 126 cd cp_tests; \
108 ${GCP} -a there/ there1/; \ 127 ls -lR . > ../cp_a_dir_dir.gnu; \
109 ls -lR there/ there1/ > ../cp_a_dir_dir.gnu; 128 ${GCP} -a here/ there/; \
129 ls -lR . >> ../cp_a_dir_dir.gnu;
110 130
111 @echo; 131 @echo;
112 rm -rf cp_tests/there1; 132 rm -rf cp_tests/there/*;
133
134 sleep 1;
113 135
114 @echo; 136 @echo;
115 cd cp_tests; \ 137 cd cp_tests; \
116 ${BCP} -a there/ there1/; \ 138 ls -lR . > ../cp_a_dir_dir.bb; \
117 ls -lR there/ there1/ > ../cp_a_dir_dir.bb; 139 ${BCP} -a here/ there/; \
140 ls -lR . >> ../cp_a_dir_dir.bb;
118 141
119 @echo; 142 @echo;
120 diff -u cp_a_dir_dir.gnu cp_a_dir_dir.bb; 143 diff -u cp_a_dir_dir.gnu cp_a_dir_dir.bb;
121 144
122 @echo; 145 @echo;
123 rm -rf cp_tests/there1/; 146 rm -rf cp_tests/*;
124 147
125 @echo; echo; 148 # Copy a set of files to a directory.
149 @echo; echo ------------------------------;
126 cd cp_tests; \ 150 cd cp_tests; \
127 echo A file number one > afile1; \ 151 echo A file number one > afile1; \
128 echo A file number two, blah. > afile2; \ 152 echo A file number two, blah. > afile2; \
129 ln -s afile1 symlink1; \ 153 ln -s afile1 symlink1; \
130 mkdir there1; \ 154 mkdir there;
131 ${GCP} afile1 afile2 symlink1 there1/; \ 155
156 cd cp_tests; \
157 ${GCP} afile1 afile2 symlink1 there/; \
132 ls -lR > ../cp_files_dir.gnu; 158 ls -lR > ../cp_files_dir.gnu;
133 159
134 @echo; 160 @echo;
135 rm -rf cp_tests/{afile{1,2},symlink1,there1}; 161 rm -rf cp_tests/there/*;
136 162
137 @echo; 163 @echo;
138 cd cp_tests; \ 164 cd cp_tests; \
139 echo A file number one > afile1; \ 165 ${BCP} afile1 afile2 symlink1 there/; \
140 echo A file number two, blah. > afile2; \
141 ln -s afile1 symlink1; \
142 mkdir there1; \
143 ${BCP} afile1 afile2 symlink1 there1/; \
144 ls -lR > ../cp_files_dir.bb; 166 ls -lR > ../cp_files_dir.bb;
145 167
146 @echo; 168 @echo;
147 diff -u cp_files_dir.gnu cp_files_dir.bb; 169 diff -u cp_files_dir.gnu cp_files_dir.bb;
148 170
149 @echo; 171 @echo;
150 rm -rf cp_tests/{afile{1,2},symlink1,there1}; 172 rm -rf cp_tests/*;
151 173
152 @echo; echo; 174 # Copy a set of files to a directory with the -d switch.
175 @echo; echo ------------------------------;
153 cd cp_tests; \ 176 cd cp_tests; \
154 echo A file number one > afile1; \ 177 echo A file number one > afile1; \
155 echo A file number two, blah. > afile2; \ 178 echo A file number two, blah. > afile2; \
@@ -176,7 +199,8 @@ cp_tests: cp_clean cp
176 @echo; 199 @echo;
177 rm -rf cp_tests/{afile{1,2},symlink1,there1}; 200 rm -rf cp_tests/{afile{1,2},symlink1,there1};
178 201
179 @echo; echo; 202 # Copy a set of files to a directory with the -p switch.
203 @echo; echo ------------------------------;
180 cd cp_tests; \ 204 cd cp_tests; \
181 echo A file number one > afile1; \ 205 echo A file number one > afile1; \
182 echo A file number two, blah. > afile2; \ 206 echo A file number two, blah. > afile2; \
@@ -205,7 +229,8 @@ cp_tests: cp_clean cp
205 @echo; 229 @echo;
206 rm -rf cp_tests/{afile{1,2},symlink1,there1}; 230 rm -rf cp_tests/{afile{1,2},symlink1,there1};
207 231
208 @echo; echo; 232 # Copy a set of files to a directory with -p and -d switches.
233 @echo; echo ------------------------------;
209 cd cp_tests; \ 234 cd cp_tests; \
210 echo A file number one > afile1; \ 235 echo A file number one > afile1; \
211 echo A file number two, blah. > afile2; \ 236 echo A file number two, blah. > afile2; \
@@ -234,7 +259,8 @@ cp_tests: cp_clean cp
234 @echo; 259 @echo;
235 rm -rf cp_tests/{afile{1,2},symlink1,there1}; 260 rm -rf cp_tests/{afile{1,2},symlink1,there1};
236 261
237 @echo; echo; 262 # Copy a directory into another directory with the -a switch.
263 @echo; echo ------------------------------;
238 cd cp_tests; \ 264 cd cp_tests; \
239 mkdir dir{a,b}; \ 265 mkdir dir{a,b}; \
240 echo A file > dira/afile; \ 266 echo A file > dira/afile; \
@@ -246,7 +272,6 @@ cp_tests: cp_clean cp
246 ${GCP} -a dira dirb; \ 272 ${GCP} -a dira dirb; \
247 ls -lR . >> ../cp_a_dira_dirb.gnu; 273 ls -lR . >> ../cp_a_dira_dirb.gnu;
248 274
249 # false;
250 @echo; 275 @echo;
251 rm -rf cp_tests/dir{a,b}; 276 rm -rf cp_tests/dir{a,b};
252 277
@@ -265,6 +290,31 @@ cp_tests: cp_clean cp
265 @echo; 290 @echo;
266 diff -u cp_a_dira_dirb.gnu cp_a_dira_dirb.bb; 291 diff -u cp_a_dira_dirb.gnu cp_a_dira_dirb.bb;
267 292
268 # false;
269 @echo; 293 @echo;
270 rm -rf cp_tests/dir{a,b}; 294 rm -rf cp_tests/dir{a,b};
295
296 # Copy a directory to another directory, without the -a switch.
297 @echo; echo ------------------------------;
298 @echo There should be an error message about cannot cp a dir to a subdir of itself.
299 cd cp_tests; \
300 touch a b c; \
301 mkdir adir; \
302 ls -lR . > ../cp_a_star_adir.gnu; \
303 ${GCP} -a * adir; \
304 ls -lR . >> ../cp_a_star_adir.gnu;
305
306 @echo
307 @echo There should be an error message about cannot cp a dir to a subdir of itself.
308 cd cp_tests; \
309 rm -rf adir; \
310 mkdir adir; \
311 ls -lR . > ../cp_a_star_adir.bb; \
312 ${BCP} -a * adir; \
313 ls -lR . >> ../cp_a_star_adir.bb;
314
315 @echo;
316 diff -u cp_a_star_adir.gnu cp_a_star_adir.bb;
317
318 @echo;
319 rm -rf cp_tests;
320 @echo; echo Done.
diff --git a/tests/ln_tests.mk b/tests/ln_tests.mk
index 5925edd4f..3110f8199 100644
--- a/tests/ln_tests.mk
+++ b/tests/ln_tests.mk
@@ -1,14 +1,19 @@
1# ln_tests.mk - Set of tests for busybox ln
2# -------------
3# Copyright (C) 2000 Karl M. Hegbloom <karlheg@debian.org> GPL
4#
1 5
2# GNU `ln' 6# GNU `ln'
3GLN = /bin/ln 7GLN = /bin/ln
4# BusyBox `ln' 8# BusyBox `ln'
5BLN = $(shell pwd)/ln 9BLN = $(shell pwd)/ln
6 10
7.PHONY: ln_clean 11all:: ln_tests
12clean:: ln_clean
13
8ln_clean: 14ln_clean:
9 rm -rf ln_tests ln_*.{gnu,bb} ln 15 rm -rf ln_tests ln_*.{gnu,bb} ln
10 16
11.PHONY: ln_tests
12ln_tests: ln_clean ln 17ln_tests: ln_clean ln
13 @echo; 18 @echo;
14 @echo "No output from diff means busybox ln is functioning properly."; 19 @echo "No output from diff means busybox ln is functioning properly.";
diff --git a/tests/mv_tests.mk b/tests/mv_tests.mk
index 3a9012538..81b8ffdec 100644
--- a/tests/mv_tests.mk
+++ b/tests/mv_tests.mk
@@ -1,14 +1,19 @@
1# mv_tests.mk - Set of tests cases for busybox mv
2# -------------
3# Copyright (C) 2000 Karl M. Hegbloom <karlheg@debian.org> GPL
4#
1 5
2# GNU `mv' 6# GNU `mv'
3GMV = /bin/mv 7GMV = /bin/mv
4# BusyBox `mv' 8# BusyBox `mv'
5BMV = $(shell pwd)/mv 9BMV = $(shell pwd)/mv
6 10
7.PHONY: mv_clean 11all:: mv_tests
12clean:: mv_clean
13
8mv_clean: 14mv_clean:
9 rm -rf mv_tests mv_*.{gnu,bb} mv 15 rm -rf mv_tests mv_*.{gnu,bb} mv
10 16
11.PHONY: mv_tests
12mv_tests: mv_clean mv 17mv_tests: mv_clean mv
13 @echo; 18 @echo;
14 @echo "No output from diff means busybox mv is functioning properly."; 19 @echo "No output from diff means busybox mv is functioning properly.";
@@ -45,7 +50,7 @@ mv_tests: mv_clean mv
45 @echo; 50 @echo;
46 rm -f mv_tests/{afile,newname}; 51 rm -f mv_tests/{afile,newname};
47 52
48 @echo; echo; 53 @echo; echo ------------------------------;
49 cd mv_tests; \ 54 cd mv_tests; \
50 echo A file > afile; \ 55 echo A file > afile; \
51 ln -s afile symlink; \ 56 ln -s afile symlink; \
@@ -72,7 +77,7 @@ mv_tests: mv_clean mv
72 @echo; 77 @echo;
73 rm -rf mv_tests/*; 78 rm -rf mv_tests/*;
74 79
75 @echo; echo; 80 @echo; echo ------------------------------;
76 cd mv_tests; \ 81 cd mv_tests; \
77 echo A file > afile; \ 82 echo A file > afile; \
78 ln -s afile symlink; \ 83 ln -s afile symlink; \
@@ -85,7 +90,7 @@ mv_tests: mv_clean mv
85 @echo; 90 @echo;
86 rm -rf mv_tests/* 91 rm -rf mv_tests/*
87 92
88 @echo; echo; 93 @echo; echo ------------------------------;
89 cd mv_tests; \ 94 cd mv_tests; \
90 echo A file > afile; \ 95 echo A file > afile; \
91 ln -s afile symlink; \ 96 ln -s afile symlink; \
@@ -101,7 +106,7 @@ mv_tests: mv_clean mv
101 @echo; 106 @echo;
102 rm -rf mv_tests/*; 107 rm -rf mv_tests/*;
103 108
104 @echo; echo; 109 @echo; echo ------------------------------;
105 cd mv_tests; \ 110 cd mv_tests; \
106 mkdir dir{a,b}; \ 111 mkdir dir{a,b}; \
107 echo A file > dira/afile; \ 112 echo A file > dira/afile; \
@@ -135,3 +140,27 @@ mv_tests: mv_clean mv
135 # false; 140 # false;
136 @echo; 141 @echo;
137 rm -rf mv_tests/dir{a,b}; 142 rm -rf mv_tests/dir{a,b};
143
144 @echo; echo ------------------------------;
145 @echo There should be an error message about cannot mv a dir to a subdir of itself.
146 cd mv_tests; \
147 touch a b c; \
148 mkdir adir; \
149 ls -lR . > ../mv_a_star_adir.gnu; \
150 ${GMV} * adir; \
151 ls -lR . >> ../mv_a_star_adir.gnu;
152
153 @echo
154 @echo There should be an error message about cannot mv a dir to a subdir of itself.
155 cd mv_tests; \
156 rm -rf adir; \
157 mkdir adir; \
158 ls -lR . > ../mv_a_star_adir.bb; \
159 ${BMV} * adir; \
160 ls -lR . >> ../mv_a_star_adir.bb;
161
162 @echo;
163 diff -u mv_a_star_adir.gnu mv_a_star_adir.bb;
164
165 @echo;
166 rm -rf mv_test/*;
diff --git a/update.c b/update.c
index fef188bba..bb77c5f1f 100644
--- a/update.c
+++ b/update.c
@@ -1,9 +1,11 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/* 2/*
3 * Mini update implementation for busybox 3 * Mini update implementation for busybox; much pasted from update-2.11
4 * 4 *
5 * 5 *
6 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. 6 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
7 * Copyright (c) 1996, 1997, 1999 Torsten Poulin.
8 * Copyright (c) 2000 by Karl M. Hegbloom <karlheg@debian.org>
7 * 9 *
8 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -23,6 +25,8 @@
23 25
24#include "internal.h" 26#include "internal.h"
25#include <linux/unistd.h> 27#include <linux/unistd.h>
28#include <sys/param.h>
29#include <sys/syslog.h>
26 30
27#if defined(__GLIBC__) 31#if defined(__GLIBC__)
28#include <sys/kdaemon.h> 32#include <sys/kdaemon.h>
@@ -30,37 +34,79 @@
30_syscall2(int, bdflush, int, func, int, data); 34_syscall2(int, bdflush, int, func, int, data);
31#endif /* __GLIBC__ */ 35#endif /* __GLIBC__ */
32 36
37static char update_usage[] =
38 "update [options]\n"
39 " -S\tforce use of sync(2) instead of flushing\n"
40 " -s SECS\tcall sync this often (default 30)\n"
41 " -f SECS\tflush some buffers this often (default 5)\n";
42
43static unsigned int sync_duration = 30;
44static unsigned int flush_duration = 5;
45static int use_sync = 0;
46
33extern int update_main(int argc, char **argv) 47extern int update_main(int argc, char **argv)
34{ 48{
35 /*
36 * Update is actually two daemons, bdflush and update.
37 */
38 int pid; 49 int pid;
39 50
51 while (**argv == '-') {
52 while (*++(*argv)) {
53 switch (**argv) {
54 case 'S':
55 use_sync = 1;
56 break;
57 case 's':
58 if (--argc < 1) usage(update_usage);
59 sync_duration = atoi(*(++argv));
60 break;
61 case 'f':
62 if (--argc < 1) usage(update_usage);
63 flush_duration = atoi(*(++argv));
64 break;
65 }
66 }
67 argc--;
68 argv++;
69 }
70
40 pid = fork(); 71 pid = fork();
41 if (pid < 0) 72 if (pid < 0)
42 return pid; 73 exit(FALSE);
43 else if (pid == 0) { 74 else if (pid == 0) {
75 /* Become a proper daemon */
76 setsid();
77 chdir("/");
78 for (pid = 0; pid < OPEN_MAX; pid++) close(pid);
79
44 /* 80 /*
45 * This is no longer necessary since 1.3.5x, but it will harmlessly 81 * This is no longer necessary since 1.3.5x, but it will harmlessly
46 * exit if that is the case. 82 * exit if that is the case.
47 */ 83 */
48 strcpy(argv[0], "bdflush (update)"); 84 argv[0] = "bdflush (update)";
49 argv[1] = 0; 85 argv[1] = NULL;
50 argv[2] = 0; 86 argv[2] = NULL;
51 bdflush(1, 0);
52 _exit(0);
53 }
54 pid = fork();
55 if (pid < 0)
56 return pid;
57 else if (pid == 0) {
58 argv[0] = "update";
59 for (;;) { 87 for (;;) {
60 sync(); 88 if (use_sync) {
61 sleep(30); 89 sleep(sync_duration);
90 sync();
91 } else {
92 sleep(flush_duration);
93 if (bdflush(1, 0) < 0) {
94 openlog("update", LOG_CONS, LOG_DAEMON);
95 syslog(LOG_INFO,
96 "This kernel does not need update(8). Exiting.");
97 closelog();
98 exit(TRUE);
99 }
100 }
62 } 101 }
63 } 102 }
64 103 return TRUE;
65 return 0;
66} 104}
105
106/*
107Local Variables:
108c-file-style: "linux"
109c-basic-offset: 4
110tab-width: 4
111End:
112*/
diff --git a/utility.c b/utility.c
index 0279cca56..c8ce3921a 100644
--- a/utility.c
+++ b/utility.c
@@ -122,7 +122,76 @@ int get_kernel_revision()
122} 122}
123#endif /* BB_INIT || BB_PS */ 123#endif /* BB_INIT || BB_PS */
124 124
125#if defined (BB_CP_MV) || defined (BB_DU)
125 126
127#define HASH_SIZE 311 /* Should be prime */
128#define hash_inode(i) ((i) % HASH_SIZE)
129
130static ino_dev_hashtable_bucket_t *ino_dev_hashtable[HASH_SIZE];
131
132/*
133 * Return 1 if statbuf->st_ino && statbuf->st_dev are recorded in
134 * `ino_dev_hashtable', else return 0
135 *
136 * If NAME is a non-NULL pointer to a character pointer, and there is
137 * a match, then set *NAME to the value of the name slot in that
138 * bucket.
139 */
140int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name)
141{
142 ino_dev_hashtable_bucket_t *bucket;
143
144 bucket = ino_dev_hashtable[hash_inode(statbuf->st_ino)];
145 while (bucket != NULL) {
146 if ((bucket->ino == statbuf->st_ino) &&
147 (bucket->dev == statbuf->st_dev))
148 {
149 if (name) *name = bucket->name;
150 return 1;
151 }
152 bucket = bucket->next;
153 }
154 return 0;
155}
156
157/* Add statbuf to statbuf hash table */
158void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name)
159{
160 int i;
161 size_t s;
162 ino_dev_hashtable_bucket_t *bucket;
163
164 i = hash_inode(statbuf->st_ino);
165 s = name ? strlen(name) : 0;
166 bucket = malloc(sizeof(ino_dev_hashtable_bucket_t) + s);
167 if (bucket == NULL)
168 fatalError("Not enough memory.");
169 bucket->ino = statbuf->st_ino;
170 bucket->dev = statbuf->st_dev;
171 if (name)
172 strcpy(bucket->name, name);
173 else
174 bucket->name[0] = '\0';
175 bucket->next = ino_dev_hashtable[i];
176 ino_dev_hashtable[i] = bucket;
177}
178
179/* Clear statbuf hash table */
180void reset_ino_dev_hashtable(void)
181{
182 int i;
183 ino_dev_hashtable_bucket_t *bucket;
184
185 for (i = 0; i < HASH_SIZE; i++) {
186 while (ino_dev_hashtable[i] != NULL) {
187 bucket = ino_dev_hashtable[i]->next;
188 free(ino_dev_hashtable[i]);
189 ino_dev_hashtable[i] = bucket;
190 }
191 }
192}
193
194#endif /* BB_CP_MV || BB_DU */
126 195
127#if defined (BB_CP_MV) || defined (BB_DU) || defined (BB_LN) 196#if defined (BB_CP_MV) || defined (BB_DU) || defined (BB_LN)
128/* 197/*
@@ -161,7 +230,7 @@ int isDirectory(const char *fileName, const int followLinks, struct stat *statBu
161/* 230/*
162 * Copy one file to another, while possibly preserving its modes, times, 231 * Copy one file to another, while possibly preserving its modes, times,
163 * and modes. Returns TRUE if successful, or FALSE on a failure with an 232 * and modes. Returns TRUE if successful, or FALSE on a failure with an
164 * error message output. (Failure is not indicted if the attributes cannot 233 * error message output. (Failure is not indicated if the attributes cannot
165 * be set.) 234 * be set.)
166 * -Erik Andersen 235 * -Erik Andersen
167 */ 236 */
@@ -1335,6 +1404,11 @@ extern void whine_if_fstab_is_missing()
1335} 1404}
1336#endif 1405#endif
1337 1406
1338
1339
1340/* END CODE */ 1407/* END CODE */
1408/*
1409Local Variables:
1410c-file-style: "linux"
1411c-basic-offset: 4
1412tab-width: 4
1413End:
1414*/