1 /* vi: set sw=4 ts=4: */
7 #define bb_need_full_version
8 #define BB_DECLARE_EXTERN
11 static int been_there_done_that = 0;
13 /* It has been alledged that doing such things can
14 * help reduce binary size when staticly linking,
15 * of course with glibc, this is unlikely as long
16 * as we use things like printf -- perhaps a printf
17 * replacement may be in order
20 void exit(int status) __attribute__ ((noreturn));
25 void abort(void) __attribute__ ((__noreturn__));
30 int atexit(void (*__func) (void))
34 void *__libc_stack_end;
37 const struct BB_applet applets[] = {
40 {"ar", ar_main, _BB_DIR_USR_BIN, ar_usage},
43 {"basename", basename_main, _BB_DIR_USR_BIN, basename_usage},
45 {"busybox", busybox_main, _BB_DIR_BIN, NULL},
47 {"cat", cat_main, _BB_DIR_BIN, cat_usage},
49 #ifdef BB_CHMOD_CHOWN_CHGRP
50 {"chgrp", chmod_chown_chgrp_main, _BB_DIR_BIN, chgrp_usage},
52 #ifdef BB_CHMOD_CHOWN_CHGRP
53 {"chmod", chmod_chown_chgrp_main, _BB_DIR_BIN, chmod_usage},
55 #ifdef BB_CHMOD_CHOWN_CHGRP
56 {"chown", chmod_chown_chgrp_main, _BB_DIR_BIN, chown_usage},
59 {"chroot", chroot_main, _BB_DIR_SBIN, chroot_usage},
62 {"clear", clear_main, _BB_DIR_USR_BIN, clear_usage},
65 {"chvt", chvt_main, _BB_DIR_USR_BIN, chvt_usage},
68 {"cp", cp_mv_main, _BB_DIR_BIN, cp_usage},
71 {"cut", cut_main, _BB_DIR_USR_BIN, cut_usage},
74 {"date", date_main, _BB_DIR_BIN, date_usage},
77 {"dc", dc_main, _BB_DIR_USR_BIN, dc_usage},
80 {"dd", dd_main, _BB_DIR_BIN, dd_usage},
83 {"df", df_main, _BB_DIR_BIN, df_usage},
86 {"dirname", dirname_main, _BB_DIR_USR_BIN, dirname_usage},
89 {"dmesg", dmesg_main, _BB_DIR_BIN, dmesg_usage},
92 {"du", du_main, _BB_DIR_BIN, du_usage},
95 {"dumpkmap", dumpkmap_main, _BB_DIR_BIN, dumpkmap_usage},
98 {"dutmp", dutmp_main, _BB_DIR_USR_SBIN, dutmp_usage},
101 {"echo", echo_main, _BB_DIR_BIN, echo_usage},
104 {"false", false_main, _BB_DIR_BIN, false_usage},
107 {"fbset", fbset_main, _BB_DIR_USR_SBIN, NULL},
110 {"fdflush", fdflush_main, _BB_DIR_BIN, fdflush_usage},
113 {"find", find_main, _BB_DIR_USR_BIN, find_usage},
116 {"free", free_main, _BB_DIR_USR_BIN, free_usage},
118 #ifdef BB_FREERAMDISK
119 {"freeramdisk", freeramdisk_main, _BB_DIR_SBIN, freeramdisk_usage},
122 {"deallocvt", deallocvt_main, _BB_DIR_USR_BIN, deallocvt_usage},
125 {"fsck.minix", fsck_minix_main, _BB_DIR_SBIN, fsck_minix_usage},
128 {"grep", grep_main, _BB_DIR_BIN, grep_usage},
131 {"gunzip", gunzip_main, _BB_DIR_BIN, gunzip_usage},
134 {"gzip", gzip_main, _BB_DIR_BIN, gzip_usage},
137 {"halt", halt_main, _BB_DIR_SBIN, halt_usage},
140 {"head", head_main, _BB_DIR_USR_BIN, head_usage},
143 {"hostid", hostid_main, _BB_DIR_USR_BIN, hostid_usage},
146 {"hostname", hostname_main, _BB_DIR_BIN, hostname_usage},
149 {"id", id_main, _BB_DIR_USR_BIN, id_usage},
152 {"init", init_main, _BB_DIR_SBIN, NULL},
155 {"insmod", insmod_main, _BB_DIR_SBIN, insmod_usage},
158 {"kill", kill_main, _BB_DIR_BIN, kill_usage},
161 {"killall", kill_main, _BB_DIR_USR_BIN, kill_usage},
164 {"length", length_main, _BB_DIR_USR_BIN, length_usage},
167 {"linuxrc", init_main, _BB_DIR_ROOT, init_usage},
170 {"ln", ln_main, _BB_DIR_BIN, ln_usage},
173 {"loadacm", loadacm_main, _BB_DIR_USR_BIN, loadacm_usage},
176 {"loadfont", loadfont_main, _BB_DIR_USR_BIN, loadfont_usage},
179 {"loadkmap", loadkmap_main, _BB_DIR_SBIN, loadkmap_usage},
182 {"logger", logger_main, _BB_DIR_USR_BIN, logger_usage},
185 {"logname", logname_main, _BB_DIR_USR_BIN, logname_usage},
188 {"ls", ls_main, _BB_DIR_BIN, ls_usage},
191 {"lsmod", lsmod_main, _BB_DIR_SBIN, lsmod_usage},
194 {"makedevs", makedevs_main, _BB_DIR_SBIN, makedevs_usage},
197 {"md5sum", md5sum_main, _BB_DIR_USR_BIN, md5sum_usage},
200 {"mkdir", mkdir_main, _BB_DIR_BIN, mkdir_usage},
203 {"mkfifo", mkfifo_main, _BB_DIR_USR_BIN, mkfifo_usage},
206 {"mkfs.minix", mkfs_minix_main, _BB_DIR_SBIN, mkfs_minix_usage},
209 {"mknod", mknod_main, _BB_DIR_BIN, mknod_usage},
212 {"mkswap", mkswap_main, _BB_DIR_SBIN, mkswap_usage},
215 {"mktemp", mktemp_main, _BB_DIR_BIN, mktemp_usage},
218 {"nc", nc_main, _BB_DIR_USR_BIN, nc_usage},
221 {"more", more_main, _BB_DIR_BIN, more_usage},
224 {"mount", mount_main, _BB_DIR_BIN, mount_usage},
227 {"mt", mt_main, _BB_DIR_BIN, mt_usage},
230 {"mv", cp_mv_main, _BB_DIR_BIN, mv_usage},
233 {"nslookup", nslookup_main, _BB_DIR_USR_BIN, nslookup_usage},
236 {"ping", ping_main, _BB_DIR_BIN, ping_usage},
239 {"poweroff", poweroff_main, _BB_DIR_SBIN, poweroff_usage},
242 {"printf", printf_main, _BB_DIR_USR_BIN, printf_usage},
245 {"ps", ps_main, _BB_DIR_BIN, ps_usage},
248 {"pwd", pwd_main, _BB_DIR_BIN, pwd_usage},
251 {"reboot", reboot_main, _BB_DIR_SBIN, reboot_usage},
254 {"rm", rm_main, _BB_DIR_BIN, rm_usage},
257 {"rmdir", rmdir_main, _BB_DIR_BIN, rmdir_usage},
260 {"rmmod", rmmod_main, _BB_DIR_SBIN, rmmod_usage},
263 {"sed", sed_main, _BB_DIR_BIN, sed_usage},
265 #ifdef BB_SETKEYCODES
266 {"setkeycodes", setkeycodes_main, _BB_DIR_USR_BIN, setkeycodes_usage},
269 {"sh", shell_main, _BB_DIR_BIN, shell_usage},
272 {"sleep", sleep_main, _BB_DIR_BIN, sleep_usage},
275 {"sort", sort_main, _BB_DIR_BIN, sort_usage},
278 {"sync", sync_main, _BB_DIR_BIN, sync_usage},
281 {"syslogd", syslogd_main, _BB_DIR_SBIN, syslogd_usage},
284 {"swapon", swap_on_off_main, _BB_DIR_SBIN, swapon_usage},
287 {"swapoff", swap_on_off_main, _BB_DIR_SBIN, swapoff_usage},
290 {"tail", tail_main, _BB_DIR_USR_BIN, tail_usage},
293 {"tar", tar_main, _BB_DIR_BIN, tar_usage},
296 {"telnet", telnet_main, _BB_DIR_USR_BIN, telnet_usage},
299 {"test", test_main, _BB_DIR_USR_BIN, test_usage},
302 {"tee", tee_main, _BB_DIR_BIN, tee_usage},
305 {"touch", touch_main, _BB_DIR_USR_BIN, touch_usage},
308 {"tr", tr_main, _BB_DIR_USR_BIN, tr_usage},
311 {"true", true_main, _BB_DIR_BIN, true_usage},
314 {"tty", tty_main, _BB_DIR_USR_BIN, tty_usage},
317 {"umount", umount_main, _BB_DIR_BIN, umount_usage},
320 {"uname", uname_main, _BB_DIR_BIN, uname_usage},
323 {"uniq", uniq_main, _BB_DIR_USR_BIN, uniq_usage},
326 {"update", update_main, _BB_DIR_SBIN, update_usage},
329 {"uptime", uptime_main, _BB_DIR_USR_BIN, uptime_usage},
332 {"uuencode", uuencode_main, _BB_DIR_USR_BIN, uuencode_usage},
335 {"uudecode", uudecode_main, _BB_DIR_USR_BIN, uudecode_usage},
338 {"usleep", usleep_main, _BB_DIR_BIN, usleep_usage},
341 {"wc", wc_main, _BB_DIR_USR_BIN, wc_usage},
344 {"which", which_main, _BB_DIR_USR_BIN, which_usage},
347 {"whoami", whoami_main, _BB_DIR_USR_BIN, whoami_usage},
350 {"yes", yes_main, _BB_DIR_USR_BIN, yes_usage},
353 {"zcat", gunzip_main, _BB_DIR_BIN, gunzip_usage},
356 {"[", test_main, _BB_DIR_USR_BIN, test_usage},
363 #ifdef BB_FEATURE_INSTALLER
366 * this should be consistent w/ the enum, internal.h::Location,
369 static char* install_dir[] = {
377 /* abstract link() */
378 typedef int (*__link_f)(const char *, const char *);
381 * Where in the filesystem is this busybox?
383 * malloc'd string w/ full pathname of busybox's location
386 static char *busybox_fullpath()
394 sprintf(proc, "/proc/%d/exe", pid);
395 len = readlink(proc, path, 256);
399 errorMsg("%s: %s\n", proc, strerror(errno));
405 /* create (sym)links for each applet */
406 static int install_links(const char *busybox, int use_symbolic_links)
408 __link_f Link = link;
414 if (use_symbolic_links) Link = symlink;
416 for (i = 0; applets[i].name != NULL; i++) {
420 install_dir[applets[i].location],
424 rc |= Link(busybox, command);
429 errorMsg("%s: %s\n", command, strerror(errno));
436 int uninstall_links() ?
438 #endif /* BB_FEATURE_INSTALLER */
441 int main(int argc, char **argv)
444 const struct BB_applet *a = applets;
445 applet_name = "busybox";
447 #ifdef BB_FEATURE_INSTALLER
449 * This style of argument parsing doesn't scale well
450 * in the event that busybox starts wanting more --options.
451 * If someone has a cleaner approach, by all means implement it.
453 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
454 int use_symbolic_links = 0;
458 /* to use symlinks, or not to use symlinks... */
460 if ((strcmp(argv[2], "-s") == 0)) {
461 use_symbolic_links = 1;
466 busybox = busybox_fullpath();
468 install_links(busybox, use_symbolic_links);
475 #endif /* BB_FEATURE_INSTALLER */
477 for (s = applet_name = argv[0]; *s != '\0';) {
485 /* Add in a special case hack -- whenever **argv == '-'
486 * (i.e. '-su' or '-sh') always invoke the shell */
488 exit(((*(shell_main)) (argc, argv)));
491 while (a->name != 0) {
492 if (strcmp(applet_name, a->name) == 0) {
493 if (a->usage && argv[1] && strcmp(argv[1], "--help") == 0)
495 exit(((*(a->main)) (argc, argv)));
499 return(busybox_main(argc, argv));
503 int busybox_main(int argc, char **argv)
510 if (been_there_done_that == 1 || argc < 1) {
511 const struct BB_applet *a = applets;
513 fprintf(stderr, "%s\n\n"
514 "Usage: busybox [function] [arguments]...\n"
515 " or: [function] [arguments]...\n\n"
516 "\tBusyBox is a multi-call binary that combines many common Unix\n"
517 "\tutilities into a single executable. Most people will create a\n"
518 "\tlink to busybox for each function they wish to use, and BusyBox\n"
519 "\twill act like whatever it was invoked as.\n"
520 "\nCurrently defined functions:\n", full_version);
522 while (a->name != 0) {
524 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
526 if (col > 60 && a->name != 0) {
527 fprintf(stderr, ",\n");
531 fprintf(stderr, "\n\n");
534 /* If we've already been here once, exit now */
535 been_there_done_that = 1;
536 return (main(argc, argv));
541 c-file-style: "linux"