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},
358 #ifdef BB_FEATURE_INSTALLER
361 * this should be consistent w/ the enum, internal.h::Location,
364 static char* install_dir[] = {
372 /* abstract link() */
373 typedef int (*__link_f)(const char *, const char *);
376 * Where in the filesystem is this busybox?
378 * malloc'd string w/ full pathname of busybox's location
381 static char *busybox_fullpath()
389 sprintf(proc, "/proc/%d/exe", pid);
390 len = readlink(proc, path, 256);
394 fprintf(stderr, "busybox : %s : %s\n", proc, strerror(errno));
400 /* create (sym)links for each applet */
401 static int install_links(const char *busybox, int use_symbolic_links)
403 __link_f Link = link;
409 if (use_symbolic_links) Link = symlink;
411 for (i = 0; applets[i].name != NULL; i++) {
415 install_dir[applets[i].location],
419 rc |= Link(busybox, command);
424 fprintf(stderr,"busybox : %s : %s\n", command, strerror(errno));
431 int uninstall_links() ?
433 #endif /* BB_FEATURE_INSTALLER */
436 int main(int argc, char **argv)
440 const struct BB_applet *a = applets;
442 #ifdef BB_FEATURE_INSTALLER
444 * This style of argument parsing doesn't scale well
445 * in the event that busybox starts wanting more --options.
446 * If someone has a cleaner approach, by all means implement it.
448 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
449 int use_symbolic_links = 0;
453 /* to use symlinks, or not to use symlinks... */
455 if ((strcmp(argv[2], "-s") == 0)) {
456 use_symbolic_links = 1;
461 busybox = busybox_fullpath();
463 install_links(busybox, use_symbolic_links);
470 #endif /* BB_FEATURE_INSTALLER */
472 for (s = name = argv[0]; *s != '\0';) {
480 /* Add in a special case hack -- whenever **argv == '-'
481 * (i.e. '-su' or '-sh') always invoke the shell */
483 exit(((*(shell_main)) (argc, argv)));
486 while (a->name != 0) {
487 if (strcmp(name, a->name) == 0) {
488 exit(((*(a->main)) (argc, argv)));
492 return(busybox_main(argc, argv));
496 int busybox_main(int argc, char **argv)
503 if (been_there_done_that == 1 || argc < 1) {
504 const struct BB_applet *a = applets;
506 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n"
507 "Usage: busybox [function] [arguments]...\n"
508 " or: [function] [arguments]...\n\n"
509 "\tBusyBox is a multi-call binary that combines many common Unix\n"
510 "\tutilities into a single executable. Most people will create a\n"
511 "\tlink to busybox for each function they wish to use, and BusyBox\n"
512 "\twill act like whatever it was invoked as.\n"
513 "\nCurrently defined functions:\n", BB_VER, BB_BT);
515 while (a->name != 0) {
517 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
519 if (col > 60 && a->name != 0) {
520 fprintf(stderr, ",\n");
524 fprintf(stderr, "\n\n");
527 /* If we've already been here once, exit now */
528 been_there_done_that = 1;
529 return (main(argc, argv));
534 c-file-style: "linux"