Add in xargs
[platform/upstream/busybox.git] / busybox.c
1 /* vi: set sw=4 ts=4: */
2 #include "internal.h"
3 #include <stdio.h>
4 #include <string.h>
5 #include <errno.h>
6
7 #define bb_need_full_version
8 #define BB_DECLARE_EXTERN
9 #include "messages.c"
10
11 static int been_there_done_that = 0;
12
13 const struct BB_applet applets[] = {
14
15 #ifdef BB_AR
16         {"ar", ar_main, _BB_DIR_USR_BIN, ar_usage},
17 #endif
18 #ifdef BB_BASENAME
19         {"basename", basename_main, _BB_DIR_USR_BIN, basename_usage},
20 #endif
21         {"busybox", busybox_main, _BB_DIR_BIN, NULL},
22 #ifdef BB_CAT
23         {"cat", cat_main, _BB_DIR_BIN, cat_usage},
24 #endif
25 #ifdef BB_CHMOD_CHOWN_CHGRP
26         {"chgrp", chmod_chown_chgrp_main, _BB_DIR_BIN, chgrp_usage},
27 #endif
28 #ifdef BB_CHMOD_CHOWN_CHGRP
29         {"chmod", chmod_chown_chgrp_main, _BB_DIR_BIN, chmod_usage},
30 #endif
31 #ifdef BB_CHMOD_CHOWN_CHGRP
32         {"chown", chmod_chown_chgrp_main, _BB_DIR_BIN, chown_usage},
33 #endif
34 #ifdef BB_CHROOT
35         {"chroot", chroot_main, _BB_DIR_USR_SBIN, chroot_usage},
36 #endif
37 #ifdef BB_CLEAR
38         {"clear", clear_main, _BB_DIR_USR_BIN, clear_usage},
39 #endif
40 #ifdef BB_CHVT
41         {"chvt", chvt_main, _BB_DIR_USR_BIN, chvt_usage},
42 #endif
43 #ifdef BB_CP_MV
44         {"cp", cp_mv_main, _BB_DIR_BIN, cp_usage},
45 #endif
46 #ifdef BB_CUT
47         {"cut", cut_main, _BB_DIR_USR_BIN, cut_usage},
48 #endif
49 #ifdef BB_DATE
50         {"date", date_main, _BB_DIR_BIN, date_usage},
51 #endif
52 #ifdef BB_DC
53         {"dc", dc_main, _BB_DIR_USR_BIN, dc_usage},
54 #endif
55 #ifdef BB_DD
56         {"dd", dd_main, _BB_DIR_BIN, dd_usage},
57 #endif
58 #ifdef BB_DF
59         {"df", df_main, _BB_DIR_BIN, df_usage},
60 #endif
61 #ifdef BB_DIRNAME
62         {"dirname", dirname_main, _BB_DIR_USR_BIN, dirname_usage},
63 #endif
64 #ifdef BB_DMESG
65         {"dmesg", dmesg_main, _BB_DIR_BIN, dmesg_usage},
66 #endif
67 #ifdef BB_DOS2UNIX
68         {"dos2unix", dos2unix_main, _BB_DIR_USR_BIN, dos2unix_usage},
69 #endif
70 #ifdef BB_DU
71         {"du", du_main, _BB_DIR_USR_BIN, du_usage},
72 #endif
73 #ifdef BB_DUMPKMAP
74         {"dumpkmap", dumpkmap_main, _BB_DIR_BIN, dumpkmap_usage},
75 #endif
76 #ifdef BB_DUTMP
77         {"dutmp", dutmp_main, _BB_DIR_USR_SBIN, dutmp_usage},
78 #endif
79 #ifdef BB_ECHO
80         {"echo", echo_main, _BB_DIR_BIN, echo_usage},
81 #endif
82 #ifdef BB_EXPR
83         {"expr", expr_main, _BB_DIR_USR_BIN, expr_usage},
84 #endif
85 #ifdef BB_TRUE_FALSE
86         {"false", false_main, _BB_DIR_BIN, false_usage},
87 #endif
88 #ifdef BB_FBSET
89         {"fbset", fbset_main, _BB_DIR_USR_SBIN, NULL},
90 #endif
91 #ifdef BB_FDFLUSH
92         {"fdflush", fdflush_main, _BB_DIR_BIN, fdflush_usage},
93 #endif
94 #ifdef BB_FIND
95         {"find", find_main, _BB_DIR_USR_BIN, find_usage},
96 #endif
97 #ifdef BB_FREE
98         {"free", free_main, _BB_DIR_USR_BIN, free_usage},
99 #endif
100 #ifdef BB_FREERAMDISK
101         {"freeramdisk", freeramdisk_main, _BB_DIR_SBIN, freeramdisk_usage},
102 #endif
103 #ifdef BB_DEALLOCVT
104         {"deallocvt", deallocvt_main, _BB_DIR_USR_BIN, deallocvt_usage},
105 #endif
106 #ifdef BB_FSCK_MINIX
107         {"fsck.minix", fsck_minix_main, _BB_DIR_SBIN, fsck_minix_usage},
108 #endif
109 #ifdef BB_GETOPT
110         {"getopt", getopt_main, _BB_DIR_BIN},
111 #endif
112 #ifdef BB_GREP
113         {"grep", grep_main, _BB_DIR_BIN, grep_usage},
114 #endif
115 #ifdef BB_GUNZIP
116         {"gunzip", gunzip_main, _BB_DIR_BIN, gunzip_usage},
117 #endif
118 #ifdef BB_GZIP
119         {"gzip", gzip_main, _BB_DIR_BIN, gzip_usage},
120 #endif
121 #ifdef BB_HALT
122         {"halt", halt_main, _BB_DIR_SBIN, halt_usage},
123 #endif
124 #ifdef BB_HEAD
125         {"head", head_main, _BB_DIR_USR_BIN, head_usage},
126 #endif
127 #ifdef BB_HOSTID
128         {"hostid", hostid_main, _BB_DIR_USR_BIN, hostid_usage},
129 #endif
130 #ifdef BB_HOSTNAME
131         {"hostname", hostname_main, _BB_DIR_BIN, hostname_usage},
132 #endif
133 #ifdef BB_ID
134         {"id", id_main, _BB_DIR_USR_BIN, id_usage},
135 #endif
136 #ifdef BB_INIT
137         {"init", init_main, _BB_DIR_SBIN, NULL},
138 #endif
139 #ifdef BB_INSMOD
140         {"insmod", insmod_main, _BB_DIR_SBIN, insmod_usage},
141 #endif
142 #ifdef BB_KILL
143         {"kill", kill_main, _BB_DIR_BIN, kill_usage},
144 #endif
145 #ifdef BB_KILLALL
146         {"killall", kill_main, _BB_DIR_USR_BIN, kill_usage},
147 #endif
148 #ifdef BB_LENGTH
149         {"length", length_main, _BB_DIR_USR_BIN, length_usage},
150 #endif
151 #ifdef BB_LINUXRC
152         {"linuxrc", init_main, _BB_DIR_ROOT, NULL},
153 #endif
154 #ifdef BB_LN
155         {"ln", ln_main, _BB_DIR_BIN, ln_usage},
156 #endif
157 #ifdef BB_LOADACM
158         {"loadacm", loadacm_main, _BB_DIR_USR_BIN, loadacm_usage},
159 #endif
160 #ifdef BB_LOADFONT
161         {"loadfont", loadfont_main, _BB_DIR_USR_BIN, loadfont_usage},
162 #endif
163 #ifdef BB_LOADKMAP
164         {"loadkmap", loadkmap_main, _BB_DIR_SBIN, loadkmap_usage},
165 #endif
166 #ifdef BB_LOGGER
167         {"logger", logger_main, _BB_DIR_USR_BIN, logger_usage},
168 #endif
169 #ifdef BB_LOGNAME
170         {"logname", logname_main, _BB_DIR_USR_BIN, logname_usage},
171 #endif
172 #ifdef BB_LS
173         {"ls", ls_main, _BB_DIR_BIN, ls_usage},
174 #endif
175 #ifdef BB_LSMOD
176         {"lsmod", lsmod_main, _BB_DIR_SBIN, lsmod_usage},
177 #endif
178 #ifdef BB_MAKEDEVS
179         {"makedevs", makedevs_main, _BB_DIR_SBIN, makedevs_usage},
180 #endif
181 #ifdef BB_MD5SUM
182         {"md5sum", md5sum_main, _BB_DIR_USR_BIN, md5sum_usage},
183 #endif
184 #ifdef BB_MKDIR
185         {"mkdir", mkdir_main, _BB_DIR_BIN, mkdir_usage},
186 #endif
187 #ifdef BB_MKFIFO
188         {"mkfifo", mkfifo_main, _BB_DIR_USR_BIN, mkfifo_usage},
189 #endif
190 #ifdef BB_MKFS_MINIX
191         {"mkfs.minix", mkfs_minix_main, _BB_DIR_SBIN, mkfs_minix_usage},
192 #endif
193 #ifdef BB_MKNOD
194         {"mknod", mknod_main, _BB_DIR_BIN, mknod_usage},
195 #endif
196 #ifdef BB_MKSWAP
197         {"mkswap", mkswap_main, _BB_DIR_SBIN, mkswap_usage},
198 #endif
199 #ifdef BB_MKTEMP
200         {"mktemp", mktemp_main, _BB_DIR_BIN, mktemp_usage},
201 #endif
202 #ifdef BB_NC
203         {"nc", nc_main, _BB_DIR_USR_BIN, nc_usage},
204 #endif
205 #ifdef BB_MORE
206         {"more", more_main, _BB_DIR_BIN, more_usage},
207 #endif
208 #ifdef BB_MOUNT
209         {"mount", mount_main, _BB_DIR_BIN, mount_usage},
210 #endif
211 #ifdef BB_MT
212         {"mt", mt_main, _BB_DIR_BIN, mt_usage},
213 #endif
214 #ifdef BB_CP_MV
215         {"mv", cp_mv_main, _BB_DIR_BIN, mv_usage},
216 #endif
217 #ifdef BB_NSLOOKUP
218         {"nslookup", nslookup_main, _BB_DIR_USR_BIN, nslookup_usage},
219 #endif
220 #ifdef BB_PING
221         {"ping", ping_main, _BB_DIR_BIN, ping_usage},
222 #endif
223 #ifdef BB_POWEROFF
224         {"poweroff", poweroff_main, _BB_DIR_SBIN, poweroff_usage},
225 #endif
226 #ifdef BB_PRINTF
227         {"printf", printf_main, _BB_DIR_USR_BIN, printf_usage},
228 #endif
229 #ifdef BB_PS
230         {"ps", ps_main, _BB_DIR_BIN, ps_usage},
231 #endif
232 #ifdef BB_PWD
233         {"pwd", pwd_main, _BB_DIR_BIN, pwd_usage},
234 #endif
235 #ifdef BB_RDATE
236         {"rdate", rdate_main, _BB_DIR_USR_BIN, rdate_usage},
237 #endif
238 #ifdef BB_REBOOT
239         {"reboot", reboot_main, _BB_DIR_SBIN, reboot_usage},
240 #endif
241 #ifdef BB_RENICE
242         {"renice", renice_main, _BB_DIR_USR_BIN},
243 #endif
244 #ifdef BB_RESET
245         {"reset", reset_main, _BB_DIR_USR_BIN, reset_usage},
246 #endif
247 #ifdef BB_RM
248         {"rm", rm_main, _BB_DIR_BIN, rm_usage},
249 #endif
250 #ifdef BB_RMDIR
251         {"rmdir", rmdir_main, _BB_DIR_BIN, rmdir_usage},
252 #endif
253 #ifdef BB_RMMOD
254         {"rmmod", rmmod_main, _BB_DIR_SBIN, rmmod_usage},
255 #endif
256 #ifdef BB_SED
257         {"sed", sed_main, _BB_DIR_BIN, sed_usage},
258 #endif
259 #ifdef BB_SETKEYCODES
260         {"setkeycodes", setkeycodes_main, _BB_DIR_USR_BIN, setkeycodes_usage},
261 #endif
262 #ifdef BB_SH
263         {"sh", shell_main, _BB_DIR_BIN, shell_usage},
264 #endif
265 #ifdef BB_SLEEP
266         {"sleep", sleep_main, _BB_DIR_BIN, sleep_usage},
267 #endif
268 #ifdef BB_SORT
269         {"sort", sort_main, _BB_DIR_USR_BIN, sort_usage},
270 #endif
271 #ifdef BB_SYNC
272         {"sync", sync_main, _BB_DIR_BIN, sync_usage},
273 #endif
274 #ifdef BB_SYSLOGD
275         {"syslogd", syslogd_main, _BB_DIR_SBIN, syslogd_usage},
276 #endif
277 #ifdef BB_SWAPONOFF
278         {"swapon", swap_on_off_main, _BB_DIR_SBIN, swapon_usage},
279 #endif
280 #ifdef BB_SWAPONOFF
281         {"swapoff", swap_on_off_main, _BB_DIR_SBIN, swapoff_usage},
282 #endif
283 #ifdef BB_TAIL
284         {"tail", tail_main, _BB_DIR_USR_BIN, tail_usage},
285 #endif
286 #ifdef BB_TAR
287         {"tar", tar_main, _BB_DIR_BIN, tar_usage},
288 #endif
289 #ifdef BB_TELNET
290         {"telnet", telnet_main, _BB_DIR_USR_BIN, telnet_usage},
291 #endif
292 #ifdef BB_TEST
293         {"test", test_main, _BB_DIR_USR_BIN, test_usage},
294 #endif
295 #ifdef BB_TEE
296         {"tee", tee_main, _BB_DIR_USR_BIN, tee_usage},
297 #endif
298 #ifdef BB_TOUCH
299         {"touch", touch_main, _BB_DIR_BIN, touch_usage},
300 #endif
301 #ifdef BB_TR
302         {"tr", tr_main, _BB_DIR_USR_BIN, tr_usage},
303 #endif
304 #ifdef BB_TRUE_FALSE
305         {"true", true_main, _BB_DIR_BIN, true_usage},
306 #endif
307 #ifdef BB_TTY
308         {"tty", tty_main, _BB_DIR_USR_BIN, tty_usage},
309 #endif
310 #ifdef BB_UMOUNT
311         {"umount", umount_main, _BB_DIR_BIN, umount_usage},
312 #endif
313 #ifdef BB_UNAME
314         {"uname", uname_main, _BB_DIR_BIN, uname_usage},
315 #endif
316 #ifdef BB_UNIQ
317         {"uniq", uniq_main, _BB_DIR_USR_BIN, uniq_usage},
318 #endif
319 #ifdef BB_UNIX2DOS
320         {"unix2dos", unix2dos_main, _BB_DIR_USR_BIN, unix2dos_usage},
321 #endif
322 #ifdef BB_UNRPM
323         {"unrpm", unrpm_main, _BB_DIR_USR_BIN, unrpm_usage},
324 #endif
325 #ifdef BB_UPDATE
326         {"update", update_main, _BB_DIR_SBIN, update_usage},
327 #endif
328 #ifdef BB_UPTIME
329         {"uptime", uptime_main, _BB_DIR_USR_BIN, uptime_usage},
330 #endif
331 #ifdef BB_UUENCODE
332         {"uuencode", uuencode_main, _BB_DIR_USR_BIN, uuencode_usage},
333 #endif
334 #ifdef BB_UUDECODE
335         {"uudecode", uudecode_main, _BB_DIR_USR_BIN, uudecode_usage},
336 #endif
337 #ifdef BB_USLEEP
338         {"usleep", usleep_main, _BB_DIR_BIN, usleep_usage},
339 #endif
340 #ifdef BB_WC
341         {"wc", wc_main, _BB_DIR_USR_BIN, wc_usage},
342 #endif
343 #ifdef BB_WGET
344         {"wget", wget_main, _BB_DIR_USR_BIN, wget_usage},
345 #endif
346 #ifdef BB_WHICH
347         {"which", which_main, _BB_DIR_USR_BIN, which_usage},
348 #endif
349 #ifdef BB_WHOAMI
350         {"whoami", whoami_main, _BB_DIR_USR_BIN, whoami_usage},
351 #endif
352 #ifdef BB_XARGS
353         {"xargs", xargs_main, _BB_DIR_USR_BIN, xargs_usage},
354 #endif
355 #ifdef BB_YES
356         {"yes", yes_main, _BB_DIR_USR_BIN, yes_usage},
357 #endif
358 #ifdef BB_GUNZIP
359         {"zcat", gunzip_main, _BB_DIR_BIN, gunzip_usage},
360 #endif
361 #ifdef BB_TEST
362         {"[", test_main, _BB_DIR_USR_BIN, test_usage},
363 #endif
364         {0,NULL,0,NULL}
365 };
366
367 const char *applet_name;
368
369 #ifdef BB_FEATURE_INSTALLER
370 /* 
371  * directory table
372  *              this should be consistent w/ the enum, internal.h::Location,
373  *              or else...
374  */
375 static char* install_dir[] = {
376         "/",
377         "/bin",
378         "/sbin",
379         "/usr/bin",
380         "/usr/sbin",
381 };
382
383 /* abstract link() */
384 typedef int (*__link_f)(const char *, const char *);
385
386 /* 
387  * Where in the filesystem is this busybox?
388  * [return]
389  *              malloc'd string w/ full pathname of busybox's location
390  *              NULL on failure
391  */
392 static char *busybox_fullpath()
393 {
394         pid_t pid;
395         char path[256];
396         char proc[256];
397         int len;
398
399         pid = getpid();
400         sprintf(proc, "/proc/%d/exe", pid);
401         len = readlink(proc, path, 256);
402         if (len != -1) {
403                 path[len] = 0;
404         } else {
405                 errorMsg("%s: %s\n", proc, strerror(errno));
406                 return NULL;
407         }
408         return strdup(path);
409 }
410
411 /* create (sym)links for each applet */
412 static int install_links(const char *busybox, int use_symbolic_links)
413 {
414         __link_f Link = link;
415
416         char command[256];
417         int i;
418         int rc = 0;
419
420         if (use_symbolic_links) Link = symlink;
421
422         for (i = 0; applets[i].name != NULL; i++) {
423                 sprintf (
424                         command, 
425                         "%s/%s", 
426                         install_dir[applets[i].location], 
427                         applets[i].name
428                 );
429 #if 1
430                 rc |= Link(busybox, command);
431 #else
432                 puts(command);
433 #endif
434                 if (rc) {
435                         errorMsg("%s: %s\n", command, strerror(errno));
436                 }
437         }
438         return rc;
439 }
440
441 #endif /* BB_FEATURE_INSTALLER */
442
443
444 int main(int argc, char **argv)
445 {
446         const char                              *s;
447         const struct BB_applet  *a              = applets;
448         applet_name = "busybox";
449
450 #ifdef BB_FEATURE_INSTALLER     
451         /* 
452          * This style of argument parsing doesn't scale well 
453          * in the event that busybox starts wanting more --options.
454          * If someone has a cleaner approach, by all means implement it.
455          */
456         if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
457                 int use_symbolic_links = 0;
458                 int rc = 0;
459                 char *busybox;
460
461                 /* to use symlinks, or not to use symlinks... */
462                 if (argc > 2) {
463                         if ((strcmp(argv[2], "-s") == 0)) { 
464                                 use_symbolic_links = 1; 
465                         }
466                 }
467
468                 /* link */
469                 busybox = busybox_fullpath();
470                 if (busybox) {
471                         install_links(busybox, use_symbolic_links);
472                         free(busybox);
473                 } else {
474                         rc = 1;
475                 }
476                 return rc;
477         }
478 #endif /* BB_FEATURE_INSTALLER */
479
480         for (s = applet_name = argv[0]; *s != '\0';) {
481                 if (*s++ == '/')
482                         applet_name = s;
483         }
484
485         *argv = (char*)applet_name;
486
487 #ifdef BB_SH
488         /* Add in a special case hack -- whenever **argv == '-'
489          * (i.e. '-su' or '-sh') always invoke the shell */
490         if (**argv == '-' && *(*argv+1)!= '-') {
491                 exit(((*(shell_main)) (argc, argv)));
492         }
493 #endif
494
495         while (a->name != 0) {
496                 if (strcmp(applet_name, a->name) == 0) {
497                         if (a->usage && argv[1] && strcmp(argv[1], "--help") == 0)
498                                 usage(a->usage);
499                         exit(((*(a->main)) (argc, argv)));
500                 }
501                 a++;
502         }
503         return(busybox_main(argc, argv));
504 }
505
506
507 int busybox_main(int argc, char **argv)
508 {
509         int col = 0;
510
511         argc--;
512         argv++;
513
514         if (been_there_done_that == 1 || argc < 1) {
515                 const struct BB_applet *a = applets;
516
517                 fprintf(stderr, "%s\n\n"
518                                 "Usage: busybox [function] [arguments]...\n"
519                                 "   or: [function] [arguments]...\n\n"
520                                 "\tBusyBox is a multi-call binary that combines many common Unix\n"
521                                 "\tutilities into a single executable.  Most people will create a\n"
522                                 "\tlink to busybox for each function they wish to use, and BusyBox\n"
523                                 "\twill act like whatever it was invoked as.\n" 
524                                 "\nCurrently defined functions:\n", full_version);
525
526                 while (a->name != 0) {
527                         col +=
528                                 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
529                                                 (a++)->name);
530                         if (col > 60 && a->name != 0) {
531                                 fprintf(stderr, ",\n");
532                                 col = 0;
533                         }
534                 }
535                 fprintf(stderr, "\n\n");
536                 exit(-1);
537         }
538         /* If we've already been here once, exit now */
539         been_there_done_that = 1;
540         return (main(argc, argv));
541 }
542
543 /*
544 Local Variables:
545 c-file-style: "linux"
546 c-basic-offset: 4
547 tab-width: 4
548 End:
549 */