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 {"dutmp", dutmp_main, _BB_DIR_USR_SBIN},
94 {"echo", echo_main, _BB_DIR_BIN},
97 {"false", false_main, _BB_DIR_BIN},
100 {"fbset", fbset_main, _BB_DIR_USR_SBIN},
103 {"fdflush", fdflush_main, _BB_DIR_BIN},
106 {"find", find_main, _BB_DIR_USR_BIN},
109 {"free", free_main, _BB_DIR_USR_BIN},
111 #ifdef BB_FREERAMDISK
112 {"freeramdisk", freeramdisk_main, _BB_DIR_SBIN},
115 {"deallocvt", deallocvt_main, _BB_DIR_USR_BIN},
118 {"fsck.minix", fsck_minix_main, _BB_DIR_SBIN},
121 {"grep", grep_main, _BB_DIR_BIN},
124 {"gunzip", gunzip_main, _BB_DIR_BIN},
127 {"gzip", gzip_main, _BB_DIR_BIN},
130 {"halt", halt_main, _BB_DIR_SBIN},
133 {"head", head_main, _BB_DIR_BIN},
136 {"hostid", hostid_main, _BB_DIR_USR_BIN},
139 {"hostname", hostname_main, _BB_DIR_BIN},
142 {"id", id_main, _BB_DIR_USR_BIN},
145 {"init", init_main, _BB_DIR_SBIN},
148 {"insmod", insmod_main, _BB_DIR_SBIN},
151 {"kill", kill_main, _BB_DIR_BIN},
154 {"killall", kill_main, _BB_DIR_USR_BIN},
157 {"length", length_main, _BB_DIR_USR_BIN},
160 {"linuxrc", init_main, _BB_DIR_ROOT},
163 {"ln", ln_main, _BB_DIR_BIN},
166 {"loadacm", loadacm_main, _BB_DIR_USR_BIN},
169 {"loadfont", loadfont_main, _BB_DIR_USR_BIN},
172 {"loadkmap", loadkmap_main, _BB_DIR_SBIN},
175 {"logger", logger_main, _BB_DIR_USR_BIN},
178 {"logname", logname_main, _BB_DIR_USR_BIN},
181 {"ls", ls_main, _BB_DIR_BIN},
184 {"lsmod", lsmod_main, _BB_DIR_SBIN},
187 {"makedevs", makedevs_main, _BB_DIR_SBIN},
190 {"md5sum", md5sum_main, _BB_DIR_USR_BIN},
193 {"mkdir", mkdir_main, _BB_DIR_BIN},
196 {"mkfifo", mkfifo_main, _BB_DIR_USR_BIN},
199 {"mkfs.minix", mkfs_minix_main, _BB_DIR_SBIN},
202 {"mknod", mknod_main, _BB_DIR_BIN},
205 {"mkswap", mkswap_main, _BB_DIR_SBIN},
208 {"mktemp", mktemp_main, _BB_DIR_BIN},
211 {"nc", nc_main, _BB_DIR_USR_BIN},
214 {"more", more_main, _BB_DIR_BIN},
217 {"mount", mount_main, _BB_DIR_BIN},
220 {"mt", mt_main, _BB_DIR_BIN},
223 {"mv", cp_mv_main, _BB_DIR_BIN},
226 {"nslookup", nslookup_main, _BB_DIR_USR_BIN},
229 {"ping", ping_main, _BB_DIR_BIN},
232 {"poweroff", poweroff_main, _BB_DIR_SBIN},
235 {"printf", printf_main, _BB_DIR_USR_BIN},
238 {"ps", ps_main, _BB_DIR_BIN},
241 {"pwd", pwd_main, _BB_DIR_BIN},
244 {"reboot", reboot_main, _BB_DIR_SBIN},
247 {"rm", rm_main, _BB_DIR_BIN},
250 {"rmdir", rmdir_main, _BB_DIR_BIN},
253 {"rmmod", rmmod_main, _BB_DIR_SBIN},
256 {"sed", sed_main, _BB_DIR_BIN},
258 #ifdef BB_SETKEYCODES
259 {"setkeycodes", setkeycodes_main, _BB_DIR_USR_BIN},
262 {"sh", shell_main, _BB_DIR_BIN},
265 {"sleep", sleep_main, _BB_DIR_BIN},
268 {"sort", sort_main, _BB_DIR_BIN},
271 {"sync", sync_main, _BB_DIR_BIN},
274 {"syslogd", syslogd_main, _BB_DIR_SBIN},
277 {"swapon", swap_on_off_main, _BB_DIR_SBIN},
280 {"swapoff", swap_on_off_main, _BB_DIR_SBIN},
283 {"tail", tail_main, _BB_DIR_USR_BIN},
286 {"tar", tar_main, _BB_DIR_BIN},
289 {"telnet", telnet_main, _BB_DIR_USR_BIN},
292 {"test", test_main, _BB_DIR_USR_BIN},
295 {"tee", tee_main, _BB_DIR_BIN},
298 {"touch", touch_main, _BB_DIR_USR_BIN},
301 {"tr", tr_main, _BB_DIR_USR_BIN},
304 {"true", true_main, _BB_DIR_BIN},
307 {"tty", tty_main, _BB_DIR_USR_BIN},
310 {"umount", umount_main, _BB_DIR_BIN},
313 {"uname", uname_main, _BB_DIR_BIN},
316 {"uniq", uniq_main, _BB_DIR_USR_BIN},
319 {"update", update_main, _BB_DIR_SBIN},
322 {"uptime", uptime_main, _BB_DIR_USR_BIN},
325 {"uuencode", uuencode_main, _BB_DIR_USR_BIN},
328 {"uudecode", uudecode_main, _BB_DIR_USR_BIN},
331 {"usleep", usleep_main, _BB_DIR_BIN},
334 {"wc", wc_main, _BB_DIR_USR_BIN},
337 {"which", which_main, _BB_DIR_USR_BIN},
340 {"whoami", whoami_main, _BB_DIR_USR_BIN},
343 {"yes", yes_main, _BB_DIR_USR_BIN},
346 {"zcat", gunzip_main, _BB_DIR_BIN},
349 {"[", test_main, _BB_DIR_USR_BIN},
355 #ifdef BB_FEATURE_INSTALLER
358 * this should be consistent w/ the enum, internal.h::Location,
361 static char* install_dir[] = {
369 /* abstract link() */
370 typedef int (*__link_f)(const char *, const char *);
373 * Where in the filesystem is this busybox?
375 * malloc'd string w/ full pathname of busybox's location
378 static char *busybox_fullpath()
386 sprintf(proc, "/proc/%d/exe", pid);
387 len = readlink(proc, path, 256);
391 fprintf(stderr, "busybox : %s : %s\n", proc, strerror(errno));
397 /* create (sym)links for each applet */
398 static int install_links(const char *busybox, int use_symbolic_links)
400 __link_f Link = link;
406 if (use_symbolic_links) Link = symlink;
408 for (i = 0; applets[i].name != NULL; i++) {
412 install_dir[applets[i].location],
416 rc |= Link(busybox, command);
421 fprintf(stderr,"busybox : %s : %s\n", command, strerror(errno));
428 int uninstall_links() ?
430 #endif /* BB_FEATURE_INSTALLER */
433 int main(int argc, char **argv)
437 const struct BB_applet *a = applets;
439 #ifdef BB_FEATURE_INSTALLER
441 * This style of argument parsing doesn't scale well
442 * in the event that busybox starts wanting more --options.
443 * If someone has a cleaner approach, by all means implement it.
445 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
446 int use_symbolic_links = 0;
450 /* to use symlinks, or not to use symlinks... */
452 if ((strcmp(argv[2], "-s") == 0)) {
453 use_symbolic_links = 1;
458 busybox = busybox_fullpath();
460 install_links(busybox, use_symbolic_links);
467 #endif /* BB_FEATURE_INSTALLER */
469 for (s = name = argv[0]; *s != '\0';) {
477 /* Add in a special case hack -- whenever **argv == '-'
478 * (i.e. '-su' or '-sh') always invoke the shell */
480 exit(((*(shell_main)) (argc, argv)));
483 while (a->name != 0) {
484 if (strcmp(name, a->name) == 0) {
485 exit(((*(a->main)) (argc, argv)));
489 return(busybox_main(argc, argv));
493 int busybox_main(int argc, char **argv)
500 if (been_there_done_that == 1 || argc < 1) {
501 const struct BB_applet *a = applets;
503 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n"
504 "Usage: busybox [function] [arguments]...\n"
505 " or: [function] [arguments]...\n\n"
506 "\tBusyBox is a multi-call binary that combines many common Unix\n"
507 "\tutilities into a single executable. Most people will create a\n"
508 "\tlink to busybox for each function they wish to use, and BusyBox\n"
509 "\twill act like whatever it was invoked as.\n"
510 "\nCurrently defined functions:\n", BB_VER, BB_BT);
512 while (a->name != 0) {
514 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
516 if (col > 60 && a->name != 0) {
517 fprintf(stderr, ",\n");
521 fprintf(stderr, "\n\n");
524 /* If we've already been here once, exit now */
525 been_there_done_that = 1;
526 return (main(argc, argv));
531 c-file-style: "linux"