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 {"renice", renice_main, _BB_DIR_USR_BIN},
257 {"rm", rm_main, _BB_DIR_BIN, rm_usage},
260 {"rmdir", rmdir_main, _BB_DIR_BIN, rmdir_usage},
263 {"rmmod", rmmod_main, _BB_DIR_SBIN, rmmod_usage},
266 {"sed", sed_main, _BB_DIR_BIN, sed_usage},
268 #ifdef BB_SETKEYCODES
269 {"setkeycodes", setkeycodes_main, _BB_DIR_USR_BIN, setkeycodes_usage},
272 {"sh", shell_main, _BB_DIR_BIN, shell_usage},
275 {"sleep", sleep_main, _BB_DIR_BIN, sleep_usage},
278 {"sort", sort_main, _BB_DIR_BIN, sort_usage},
281 {"sync", sync_main, _BB_DIR_BIN, sync_usage},
284 {"syslogd", syslogd_main, _BB_DIR_SBIN, syslogd_usage},
287 {"swapon", swap_on_off_main, _BB_DIR_SBIN, swapon_usage},
290 {"swapoff", swap_on_off_main, _BB_DIR_SBIN, swapoff_usage},
293 {"tail", tail_main, _BB_DIR_USR_BIN, tail_usage},
296 {"tar", tar_main, _BB_DIR_BIN, tar_usage},
299 {"telnet", telnet_main, _BB_DIR_USR_BIN, telnet_usage},
302 {"test", test_main, _BB_DIR_USR_BIN, test_usage},
305 {"tee", tee_main, _BB_DIR_BIN, tee_usage},
308 {"touch", touch_main, _BB_DIR_USR_BIN, touch_usage},
311 {"tr", tr_main, _BB_DIR_USR_BIN, tr_usage},
314 {"true", true_main, _BB_DIR_BIN, true_usage},
317 {"tty", tty_main, _BB_DIR_USR_BIN, tty_usage},
320 {"umount", umount_main, _BB_DIR_BIN, umount_usage},
323 {"uname", uname_main, _BB_DIR_BIN, uname_usage},
326 {"uniq", uniq_main, _BB_DIR_USR_BIN, uniq_usage},
329 {"update", update_main, _BB_DIR_SBIN, update_usage},
332 {"uptime", uptime_main, _BB_DIR_USR_BIN, uptime_usage},
335 {"uuencode", uuencode_main, _BB_DIR_USR_BIN, uuencode_usage},
338 {"uudecode", uudecode_main, _BB_DIR_USR_BIN, uudecode_usage},
341 {"usleep", usleep_main, _BB_DIR_BIN, usleep_usage},
344 {"wc", wc_main, _BB_DIR_USR_BIN, wc_usage},
347 {"which", which_main, _BB_DIR_USR_BIN, which_usage},
350 {"whoami", whoami_main, _BB_DIR_USR_BIN, whoami_usage},
353 {"yes", yes_main, _BB_DIR_USR_BIN, yes_usage},
356 {"zcat", gunzip_main, _BB_DIR_BIN, gunzip_usage},
359 {"[", test_main, _BB_DIR_USR_BIN, test_usage},
366 #ifdef BB_FEATURE_INSTALLER
369 * this should be consistent w/ the enum, internal.h::Location,
372 static char* install_dir[] = {
380 /* abstract link() */
381 typedef int (*__link_f)(const char *, const char *);
384 * Where in the filesystem is this busybox?
386 * malloc'd string w/ full pathname of busybox's location
389 static char *busybox_fullpath()
397 sprintf(proc, "/proc/%d/exe", pid);
398 len = readlink(proc, path, 256);
402 errorMsg("%s: %s\n", proc, strerror(errno));
408 /* create (sym)links for each applet */
409 static int install_links(const char *busybox, int use_symbolic_links)
411 __link_f Link = link;
417 if (use_symbolic_links) Link = symlink;
419 for (i = 0; applets[i].name != NULL; i++) {
423 install_dir[applets[i].location],
427 rc |= Link(busybox, command);
432 errorMsg("%s: %s\n", command, strerror(errno));
439 int uninstall_links() ?
441 #endif /* BB_FEATURE_INSTALLER */
444 int main(int argc, char **argv)
447 const struct BB_applet *a = applets;
448 applet_name = "busybox";
450 #ifdef BB_FEATURE_INSTALLER
452 * This style of argument parsing doesn't scale well
453 * in the event that busybox starts wanting more --options.
454 * If someone has a cleaner approach, by all means implement it.
456 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
457 int use_symbolic_links = 0;
461 /* to use symlinks, or not to use symlinks... */
463 if ((strcmp(argv[2], "-s") == 0)) {
464 use_symbolic_links = 1;
469 busybox = busybox_fullpath();
471 install_links(busybox, use_symbolic_links);
478 #endif /* BB_FEATURE_INSTALLER */
480 for (s = applet_name = argv[0]; *s != '\0';) {
488 /* Add in a special case hack -- whenever **argv == '-'
489 * (i.e. '-su' or '-sh') always invoke the shell */
490 if (**argv == '-' && *(*argv+1)!= '-') {
491 exit(((*(shell_main)) (argc, argv)));
495 while (a->name != 0) {
496 if (strcmp(applet_name, a->name) == 0) {
497 if (a->usage && argv[1] && strcmp(argv[1], "--help") == 0)
499 exit(((*(a->main)) (argc, argv)));
503 return(busybox_main(argc, argv));
507 int busybox_main(int argc, char **argv)
514 if (been_there_done_that == 1 || argc < 1) {
515 const struct BB_applet *a = applets;
517 fprintf(stderr, "%s\n\n"
518 "Usage: busybox [function] [arguments]...\n"
519 " or: [function] [arguments]...\n\n"
520 "\tBusyBox is a multi-call binary that combines many common Unix\n"
521 "\tutilities into a single executable. Most people will create a\n"
522 "\tlink to busybox for each function they wish to use, and BusyBox\n"
523 "\twill act like whatever it was invoked as.\n"
524 "\nCurrently defined functions:\n", full_version);
526 while (a->name != 0) {
528 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
530 if (col > 60 && a->name != 0) {
531 fprintf(stderr, ",\n");
535 fprintf(stderr, "\n\n");
538 /* If we've already been here once, exit now */
539 been_there_done_that = 1;
540 return (main(argc, argv));
545 c-file-style: "linux"