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},
42 #ifdef BB_BLOCK_DEVICE
43 {"block_device", block_device_main, _BB_DIR_SBIN},
46 {"cat", cat_main, _BB_DIR_BIN},
48 #ifdef BB_CHMOD_CHOWN_CHGRP
49 {"chgrp", chmod_chown_chgrp_main, _BB_DIR_BIN},
51 #ifdef BB_CHMOD_CHOWN_CHGRP
52 {"chmod", chmod_chown_chgrp_main, _BB_DIR_BIN},
54 #ifdef BB_CHMOD_CHOWN_CHGRP
55 {"chown", chmod_chown_chgrp_main, _BB_DIR_BIN},
58 {"chroot", chroot_main, _BB_DIR_SBIN},
61 {"clear", clear_main, _BB_DIR_USR_BIN},
64 {"chvt", chvt_main, _BB_DIR_USR_BIN},
67 {"cp", cp_mv_main, _BB_DIR_BIN},
70 {"cut", cut_main, _BB_DIR_USR_BIN},
73 {"date", date_main, _BB_DIR_BIN},
76 {"dc", dc_main, _BB_DIR_USR_BIN},
79 {"dd", dd_main, _BB_DIR_BIN},
82 {"df", df_main, _BB_DIR_BIN},
85 {"dirname", dirname_main, _BB_DIR_USR_BIN},
88 {"dmesg", dmesg_main, _BB_DIR_BIN},
91 {"du", du_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 {"sfdisk", sfdisk_main, _BB_DIR_SBIN},
268 {"sh", shell_main, _BB_DIR_BIN},
271 {"sleep", sleep_main, _BB_DIR_BIN},
274 {"sort", sort_main, _BB_DIR_BIN},
277 {"sync", sync_main, _BB_DIR_BIN},
280 {"syslogd", syslogd_main, _BB_DIR_SBIN},
283 {"swapon", swap_on_off_main, _BB_DIR_SBIN},
286 {"swapoff", swap_on_off_main, _BB_DIR_SBIN},
289 {"tail", tail_main, _BB_DIR_USR_BIN},
292 {"tar", tar_main, _BB_DIR_BIN},
295 {"telnet", telnet_main, _BB_DIR_USR_BIN},
298 {"test", test_main, _BB_DIR_USR_BIN},
301 {"tee", tee_main, _BB_DIR_BIN},
304 {"touch", touch_main, _BB_DIR_USR_BIN},
307 {"tr", tr_main, _BB_DIR_USR_BIN},
310 {"true", true_main, _BB_DIR_BIN},
313 {"tty", tty_main, _BB_DIR_USR_BIN},
316 {"umount", umount_main, _BB_DIR_BIN},
319 {"uname", uname_main, _BB_DIR_BIN},
322 {"uniq", uniq_main, _BB_DIR_USR_BIN},
325 {"update", update_main, _BB_DIR_SBIN},
328 {"uptime", uptime_main, _BB_DIR_USR_BIN},
331 {"uuencode", uuencode_main, _BB_DIR_USR_BIN},
334 {"uudecode", uudecode_main, _BB_DIR_USR_BIN},
337 {"usleep", usleep_main, _BB_DIR_BIN},
340 {"wc", wc_main, _BB_DIR_USR_BIN},
343 {"which", which_main, _BB_DIR_USR_BIN},
346 {"whoami", whoami_main, _BB_DIR_USR_BIN},
349 {"yes", yes_main, _BB_DIR_USR_BIN},
352 {"zcat", gunzip_main, _BB_DIR_BIN},
355 {"[", test_main, _BB_DIR_USR_BIN},
361 #ifdef BB_FEATURE_INSTALLER
364 * this should be consistent w/ the enum, internal.h::Location,
367 static char* install_dir[] = {
375 /* abstract link() */
376 typedef int (*__link_f)(const char *, const char *);
379 * Where in the filesystem is this busybox?
381 * malloc'd string w/ full pathname of busybox's location
384 static char *busybox_fullpath()
392 sprintf(proc, "/proc/%d/exe", pid);
393 len = readlink(proc, path, 256);
397 fprintf(stderr, "busybox : %s : %s\n", proc, strerror(errno));
403 /* create (sym)links for each applet */
404 static int install_links(const char *busybox, int use_symbolic_links)
406 __link_f Link = link;
412 if (use_symbolic_links) Link = symlink;
414 for (i = 0; applets[i].name != NULL; i++) {
418 install_dir[applets[i].location],
422 rc |= Link(busybox, command);
427 fprintf(stderr,"busybox : %s : %s\n", command, strerror(errno));
434 int uninstall_links() ?
436 #endif /* BB_FEATURE_INSTALLER */
439 int main(int argc, char **argv)
443 const struct BB_applet *a = applets;
445 #ifdef BB_FEATURE_INSTALLER
447 * This style of argument parsing doesn't scale well
448 * in the event that busybox starts wanting more --options.
449 * If someone has a cleaner approach, by all means implement it.
451 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
452 int use_symbolic_links = 0;
456 /* to use symlinks, or not to use symlinks... */
458 if ((strcmp(argv[2], "-s") == 0)) {
459 use_symbolic_links = 1;
464 busybox = busybox_fullpath();
466 install_links(busybox, use_symbolic_links);
473 #endif /* BB_FEATURE_INSTALLER */
475 for (s = name = argv[0]; *s != '\0';) {
483 /* Add in a special case hack -- whenever **argv == '-'
484 * (i.e. '-su' or '-sh') always invoke the shell */
486 exit(((*(shell_main)) (argc, argv)));
489 while (a->name != 0) {
490 if (strcmp(name, a->name) == 0) {
491 exit(((*(a->main)) (argc, argv)));
495 return(busybox_main(argc, argv));
499 int busybox_main(int argc, char **argv)
506 if (been_there_done_that == 1 || argc < 1) {
507 const struct BB_applet *a = applets;
509 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n"
510 "Usage: busybox [function] [arguments]...\n"
511 " or: [function] [arguments]...\n\n"
512 "\tBusyBox is a multi-call binary that combines many common Unix\n"
513 "\tutilities into a single executable. Most people will create a\n"
514 "\tlink to busybox for each function they wish to use, and BusyBox\n"
515 "\twill act like whatever it was invoked as.\n"
516 "\nCurrently defined functions:\n", BB_VER, BB_BT);
518 while (a->name != 0) {
520 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
522 if (col > 60 && a->name != 0) {
523 fprintf(stderr, ",\n");
527 fprintf(stderr, "\n\n");
530 /* If we've already been here once, exit now */
531 been_there_done_that = 1;
532 return (main(argc, argv));
537 c-file-style: "linux"