1 /* vi: set sw=4 ts=4: */
7 static int been_there_done_that = 0;
9 /* It has been alledged that doing such things can
10 * help reduce binary size when staticly linking,
11 * of course with glibc, this is unlikely as long
12 * as we use things like printf -- perhaps a printf
13 * replacement may be in order
16 void exit(int status) __attribute__ ((noreturn));
21 void abort(void) __attribute__ ((__noreturn__));
26 int atexit(void (*__func) (void))
30 void *__libc_stack_end;
33 const struct BB_applet applets[] = {
36 {"ar", ar_main, _BB_DIR_USR_BIN},
39 {"basename", basename_main, _BB_DIR_USR_BIN},
41 {"busybox", busybox_main, _BB_DIR_BIN},
43 {"cat", cat_main, _BB_DIR_BIN},
45 #ifdef BB_CHMOD_CHOWN_CHGRP
46 {"chgrp", chmod_chown_chgrp_main, _BB_DIR_BIN},
48 #ifdef BB_CHMOD_CHOWN_CHGRP
49 {"chmod", chmod_chown_chgrp_main, _BB_DIR_BIN},
51 #ifdef BB_CHMOD_CHOWN_CHGRP
52 {"chown", chmod_chown_chgrp_main, _BB_DIR_BIN},
55 {"chroot", chroot_main, _BB_DIR_SBIN},
58 {"clear", clear_main, _BB_DIR_USR_BIN},
61 {"chvt", chvt_main, _BB_DIR_USR_BIN},
64 {"cp", cp_mv_main, _BB_DIR_BIN},
67 {"cut", cut_main, _BB_DIR_USR_BIN},
70 {"date", date_main, _BB_DIR_BIN},
73 {"dc", dc_main, _BB_DIR_USR_BIN},
76 {"dd", dd_main, _BB_DIR_BIN},
79 {"df", df_main, _BB_DIR_BIN},
82 {"dirname", dirname_main, _BB_DIR_USR_BIN},
85 {"dmesg", dmesg_main, _BB_DIR_BIN},
88 {"du", du_main, _BB_DIR_BIN},
91 {"dumpkmap", dumpkmap_main, _BB_DIR_BIN},
94 {"dutmp", dutmp_main, _BB_DIR_USR_SBIN},
97 {"echo", echo_main, _BB_DIR_BIN},
100 {"false", false_main, _BB_DIR_BIN},
103 {"fbset", fbset_main, _BB_DIR_USR_SBIN},
106 {"fdflush", fdflush_main, _BB_DIR_BIN},
109 {"find", find_main, _BB_DIR_USR_BIN},
112 {"free", free_main, _BB_DIR_USR_BIN},
114 #ifdef BB_FREERAMDISK
115 {"freeramdisk", freeramdisk_main, _BB_DIR_SBIN},
118 {"deallocvt", deallocvt_main, _BB_DIR_USR_BIN},
121 {"fsck.minix", fsck_minix_main, _BB_DIR_SBIN},
124 {"grep", grep_main, _BB_DIR_BIN},
127 {"gunzip", gunzip_main, _BB_DIR_BIN},
130 {"gzip", gzip_main, _BB_DIR_BIN},
133 {"halt", halt_main, _BB_DIR_SBIN},
136 {"head", head_main, _BB_DIR_BIN},
139 {"hostid", hostid_main, _BB_DIR_USR_BIN},
142 {"hostname", hostname_main, _BB_DIR_BIN},
145 {"id", id_main, _BB_DIR_USR_BIN},
148 {"init", init_main, _BB_DIR_SBIN},
151 {"insmod", insmod_main, _BB_DIR_SBIN},
154 {"kill", kill_main, _BB_DIR_BIN},
157 {"killall", kill_main, _BB_DIR_USR_BIN},
160 {"length", length_main, _BB_DIR_USR_BIN},
163 {"linuxrc", init_main, _BB_DIR_ROOT},
166 {"ln", ln_main, _BB_DIR_BIN},
169 {"loadacm", loadacm_main, _BB_DIR_USR_BIN},
172 {"loadfont", loadfont_main, _BB_DIR_USR_BIN},
175 {"loadkmap", loadkmap_main, _BB_DIR_SBIN},
178 {"logger", logger_main, _BB_DIR_USR_BIN},
181 {"logname", logname_main, _BB_DIR_USR_BIN},
184 {"ls", ls_main, _BB_DIR_BIN},
187 {"lsmod", lsmod_main, _BB_DIR_SBIN},
190 {"makedevs", makedevs_main, _BB_DIR_SBIN},
193 {"md5sum", md5sum_main, _BB_DIR_USR_BIN},
196 {"mkdir", mkdir_main, _BB_DIR_BIN},
199 {"mkfifo", mkfifo_main, _BB_DIR_USR_BIN},
202 {"mkfs.minix", mkfs_minix_main, _BB_DIR_SBIN},
205 {"mknod", mknod_main, _BB_DIR_BIN},
208 {"mkswap", mkswap_main, _BB_DIR_SBIN},
211 {"mktemp", mktemp_main, _BB_DIR_BIN},
214 {"nc", nc_main, _BB_DIR_USR_BIN},
217 {"more", more_main, _BB_DIR_BIN},
220 {"mount", mount_main, _BB_DIR_BIN},
223 {"mt", mt_main, _BB_DIR_BIN},
226 {"mv", cp_mv_main, _BB_DIR_BIN},
229 {"nslookup", nslookup_main, _BB_DIR_USR_BIN},
232 {"ping", ping_main, _BB_DIR_BIN},
235 {"poweroff", poweroff_main, _BB_DIR_SBIN},
238 {"printf", printf_main, _BB_DIR_USR_BIN},
241 {"ps", ps_main, _BB_DIR_BIN},
244 {"pwd", pwd_main, _BB_DIR_BIN},
247 {"reboot", reboot_main, _BB_DIR_SBIN},
250 {"rm", rm_main, _BB_DIR_BIN},
253 {"rmdir", rmdir_main, _BB_DIR_BIN},
256 {"rmmod", rmmod_main, _BB_DIR_SBIN},
259 {"sed", sed_main, _BB_DIR_BIN},
261 #ifdef BB_SETKEYCODES
262 {"setkeycodes", setkeycodes_main, _BB_DIR_USR_BIN},
265 {"sh", shell_main, _BB_DIR_BIN},
268 {"sleep", sleep_main, _BB_DIR_BIN},
271 {"sort", sort_main, _BB_DIR_BIN},
274 {"sync", sync_main, _BB_DIR_BIN},
277 {"syslogd", syslogd_main, _BB_DIR_SBIN},
280 {"swapon", swap_on_off_main, _BB_DIR_SBIN},
283 {"swapoff", swap_on_off_main, _BB_DIR_SBIN},
286 {"tail", tail_main, _BB_DIR_USR_BIN},
289 {"tar", tar_main, _BB_DIR_BIN},
292 {"telnet", telnet_main, _BB_DIR_USR_BIN},
295 {"test", test_main, _BB_DIR_USR_BIN},
298 {"tee", tee_main, _BB_DIR_BIN},
301 {"touch", touch_main, _BB_DIR_USR_BIN},
304 {"tr", tr_main, _BB_DIR_USR_BIN},
307 {"true", true_main, _BB_DIR_BIN},
310 {"tty", tty_main, _BB_DIR_USR_BIN},
313 {"umount", umount_main, _BB_DIR_BIN},
316 {"uname", uname_main, _BB_DIR_BIN},
319 {"uniq", uniq_main, _BB_DIR_USR_BIN},
322 {"update", update_main, _BB_DIR_SBIN},
325 {"uptime", uptime_main, _BB_DIR_USR_BIN},
328 {"uuencode", uuencode_main, _BB_DIR_USR_BIN},
331 {"uudecode", uudecode_main, _BB_DIR_USR_BIN},
334 {"usleep", usleep_main, _BB_DIR_BIN},
337 {"wc", wc_main, _BB_DIR_USR_BIN},
340 {"which", which_main, _BB_DIR_USR_BIN},
343 {"whoami", whoami_main, _BB_DIR_USR_BIN},
346 {"yes", yes_main, _BB_DIR_USR_BIN},
349 {"zcat", gunzip_main, _BB_DIR_BIN},
352 {"[", test_main, _BB_DIR_USR_BIN},
359 #ifdef BB_FEATURE_INSTALLER
362 * this should be consistent w/ the enum, internal.h::Location,
365 static char* install_dir[] = {
373 /* abstract link() */
374 typedef int (*__link_f)(const char *, const char *);
377 * Where in the filesystem is this busybox?
379 * malloc'd string w/ full pathname of busybox's location
382 static char *busybox_fullpath()
390 sprintf(proc, "/proc/%d/exe", pid);
391 len = readlink(proc, path, 256);
395 errorMsg("%s: %s\n", proc, strerror(errno));
401 /* create (sym)links for each applet */
402 static int install_links(const char *busybox, int use_symbolic_links)
404 __link_f Link = link;
410 if (use_symbolic_links) Link = symlink;
412 for (i = 0; applets[i].name != NULL; i++) {
416 install_dir[applets[i].location],
420 rc |= Link(busybox, command);
425 errorMsg("%s: %s\n", command, strerror(errno));
432 int uninstall_links() ?
434 #endif /* BB_FEATURE_INSTALLER */
437 int main(int argc, char **argv)
440 const struct BB_applet *a = applets;
441 applet_name = "busybox";
443 #ifdef BB_FEATURE_INSTALLER
445 * This style of argument parsing doesn't scale well
446 * in the event that busybox starts wanting more --options.
447 * If someone has a cleaner approach, by all means implement it.
449 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
450 int use_symbolic_links = 0;
454 /* to use symlinks, or not to use symlinks... */
456 if ((strcmp(argv[2], "-s") == 0)) {
457 use_symbolic_links = 1;
462 busybox = busybox_fullpath();
464 install_links(busybox, use_symbolic_links);
471 #endif /* BB_FEATURE_INSTALLER */
473 for (s = applet_name = argv[0]; *s != '\0';) {
481 /* Add in a special case hack -- whenever **argv == '-'
482 * (i.e. '-su' or '-sh') always invoke the shell */
484 exit(((*(shell_main)) (argc, argv)));
487 while (a->name != 0) {
488 if (strcmp(applet_name, a->name) == 0) {
489 exit(((*(a->main)) (argc, argv)));
493 return(busybox_main(argc, argv));
497 int busybox_main(int argc, char **argv)
504 if (been_there_done_that == 1 || argc < 1) {
505 const struct BB_applet *a = applets;
507 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n"
508 "Usage: busybox [function] [arguments]...\n"
509 " or: [function] [arguments]...\n\n"
510 "\tBusyBox is a multi-call binary that combines many common Unix\n"
511 "\tutilities into a single executable. Most people will create a\n"
512 "\tlink to busybox for each function they wish to use, and BusyBox\n"
513 "\twill act like whatever it was invoked as.\n"
514 "\nCurrently defined functions:\n", BB_VER, BB_BT);
516 while (a->name != 0) {
518 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
520 if (col > 60 && a->name != 0) {
521 fprintf(stderr, ",\n");
525 fprintf(stderr, "\n\n");
528 /* If we've already been here once, exit now */
529 been_there_done_that = 1;
530 return (main(argc, argv));
535 c-file-style: "linux"