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 const struct BB_applet applets[] = {
16 {"ar", ar_main, _BB_DIR_USR_BIN, ar_usage},
19 {"basename", basename_main, _BB_DIR_USR_BIN, basename_usage},
21 {"busybox", busybox_main, _BB_DIR_BIN, NULL},
23 {"cat", cat_main, _BB_DIR_BIN, cat_usage},
25 #ifdef BB_CHMOD_CHOWN_CHGRP
26 {"chgrp", chmod_chown_chgrp_main, _BB_DIR_BIN, chgrp_usage},
28 #ifdef BB_CHMOD_CHOWN_CHGRP
29 {"chmod", chmod_chown_chgrp_main, _BB_DIR_BIN, chmod_usage},
31 #ifdef BB_CHMOD_CHOWN_CHGRP
32 {"chown", chmod_chown_chgrp_main, _BB_DIR_BIN, chown_usage},
35 {"chroot", chroot_main, _BB_DIR_USR_SBIN, chroot_usage},
38 {"clear", clear_main, _BB_DIR_USR_BIN, clear_usage},
41 {"chvt", chvt_main, _BB_DIR_USR_BIN, chvt_usage},
44 {"cp", cp_mv_main, _BB_DIR_BIN, cp_usage},
47 {"cut", cut_main, _BB_DIR_USR_BIN, cut_usage},
50 {"date", date_main, _BB_DIR_BIN, date_usage},
53 {"dc", dc_main, _BB_DIR_USR_BIN, dc_usage},
56 {"dd", dd_main, _BB_DIR_BIN, dd_usage},
59 {"df", df_main, _BB_DIR_BIN, df_usage},
62 {"dirname", dirname_main, _BB_DIR_USR_BIN, dirname_usage},
65 {"dmesg", dmesg_main, _BB_DIR_BIN, dmesg_usage},
68 {"dos2unix", dos2unix_main, _BB_DIR_USR_BIN, dos2unix_usage},
71 {"du", du_main, _BB_DIR_USR_BIN, du_usage},
74 {"dumpkmap", dumpkmap_main, _BB_DIR_BIN, dumpkmap_usage},
77 {"dutmp", dutmp_main, _BB_DIR_USR_SBIN, dutmp_usage},
80 {"echo", echo_main, _BB_DIR_BIN, echo_usage},
83 {"expr", expr_main, _BB_DIR_USR_BIN, expr_usage},
86 {"false", false_main, _BB_DIR_BIN, false_usage},
89 {"fbset", fbset_main, _BB_DIR_USR_SBIN, NULL},
92 {"fdflush", fdflush_main, _BB_DIR_BIN, fdflush_usage},
95 {"find", find_main, _BB_DIR_USR_BIN, find_usage},
98 {"free", free_main, _BB_DIR_USR_BIN, free_usage},
100 #ifdef BB_FREERAMDISK
101 {"freeramdisk", freeramdisk_main, _BB_DIR_SBIN, freeramdisk_usage},
104 {"deallocvt", deallocvt_main, _BB_DIR_USR_BIN, deallocvt_usage},
107 {"fsck.minix", fsck_minix_main, _BB_DIR_SBIN, fsck_minix_usage},
110 {"getopt", getopt_main, _BB_DIR_BIN},
113 {"grep", grep_main, _BB_DIR_BIN, grep_usage},
116 {"gunzip", gunzip_main, _BB_DIR_BIN, gunzip_usage},
119 {"gzip", gzip_main, _BB_DIR_BIN, gzip_usage},
122 {"halt", halt_main, _BB_DIR_SBIN, halt_usage},
125 {"head", head_main, _BB_DIR_USR_BIN, head_usage},
128 {"hostid", hostid_main, _BB_DIR_USR_BIN, hostid_usage},
131 {"hostname", hostname_main, _BB_DIR_BIN, hostname_usage},
134 {"id", id_main, _BB_DIR_USR_BIN, id_usage},
137 {"init", init_main, _BB_DIR_SBIN, NULL},
140 {"insmod", insmod_main, _BB_DIR_SBIN, insmod_usage},
143 {"kill", kill_main, _BB_DIR_BIN, kill_usage},
146 {"killall", kill_main, _BB_DIR_USR_BIN, kill_usage},
149 {"length", length_main, _BB_DIR_USR_BIN, length_usage},
152 {"linuxrc", init_main, _BB_DIR_ROOT, NULL},
155 {"ln", ln_main, _BB_DIR_BIN, ln_usage},
158 {"loadacm", loadacm_main, _BB_DIR_USR_BIN, loadacm_usage},
161 {"loadfont", loadfont_main, _BB_DIR_USR_BIN, loadfont_usage},
164 {"loadkmap", loadkmap_main, _BB_DIR_SBIN, loadkmap_usage},
167 {"logger", logger_main, _BB_DIR_USR_BIN, logger_usage},
170 {"logname", logname_main, _BB_DIR_USR_BIN, logname_usage},
173 {"ls", ls_main, _BB_DIR_BIN, ls_usage},
176 {"lsmod", lsmod_main, _BB_DIR_SBIN, lsmod_usage},
179 {"makedevs", makedevs_main, _BB_DIR_SBIN, makedevs_usage},
182 {"md5sum", md5sum_main, _BB_DIR_USR_BIN, md5sum_usage},
185 {"mkdir", mkdir_main, _BB_DIR_BIN, mkdir_usage},
188 {"mkfifo", mkfifo_main, _BB_DIR_USR_BIN, mkfifo_usage},
191 {"mkfs.minix", mkfs_minix_main, _BB_DIR_SBIN, mkfs_minix_usage},
194 {"mknod", mknod_main, _BB_DIR_BIN, mknod_usage},
197 {"mkswap", mkswap_main, _BB_DIR_SBIN, mkswap_usage},
200 {"mktemp", mktemp_main, _BB_DIR_BIN, mktemp_usage},
203 {"nc", nc_main, _BB_DIR_USR_BIN, nc_usage},
206 {"more", more_main, _BB_DIR_BIN, more_usage},
209 {"mount", mount_main, _BB_DIR_BIN, mount_usage},
212 {"mt", mt_main, _BB_DIR_BIN, mt_usage},
215 {"mv", cp_mv_main, _BB_DIR_BIN, mv_usage},
218 {"nslookup", nslookup_main, _BB_DIR_USR_BIN, nslookup_usage},
221 {"ping", ping_main, _BB_DIR_BIN, ping_usage},
224 {"poweroff", poweroff_main, _BB_DIR_SBIN, poweroff_usage},
227 {"printf", printf_main, _BB_DIR_USR_BIN, printf_usage},
230 {"ps", ps_main, _BB_DIR_BIN, ps_usage},
233 {"pwd", pwd_main, _BB_DIR_BIN, pwd_usage},
236 {"rdate", rdate_main, _BB_DIR_USR_BIN, rdate_usage},
239 {"reboot", reboot_main, _BB_DIR_SBIN, reboot_usage},
242 {"renice", renice_main, _BB_DIR_USR_BIN},
245 {"reset", reset_main, _BB_DIR_USR_BIN, reset_usage},
248 {"rm", rm_main, _BB_DIR_BIN, rm_usage},
251 {"rmdir", rmdir_main, _BB_DIR_BIN, rmdir_usage},
254 {"rmmod", rmmod_main, _BB_DIR_SBIN, rmmod_usage},
257 {"sed", sed_main, _BB_DIR_BIN, sed_usage},
259 #ifdef BB_SETKEYCODES
260 {"setkeycodes", setkeycodes_main, _BB_DIR_USR_BIN, setkeycodes_usage},
263 {"sh", shell_main, _BB_DIR_BIN, shell_usage},
266 {"sleep", sleep_main, _BB_DIR_BIN, sleep_usage},
269 {"sort", sort_main, _BB_DIR_USR_BIN, sort_usage},
272 {"sync", sync_main, _BB_DIR_BIN, sync_usage},
275 {"syslogd", syslogd_main, _BB_DIR_SBIN, syslogd_usage},
278 {"swapon", swap_on_off_main, _BB_DIR_SBIN, swapon_usage},
281 {"swapoff", swap_on_off_main, _BB_DIR_SBIN, swapoff_usage},
284 {"tail", tail_main, _BB_DIR_USR_BIN, tail_usage},
287 {"tar", tar_main, _BB_DIR_BIN, tar_usage},
290 {"telnet", telnet_main, _BB_DIR_USR_BIN, telnet_usage},
293 {"test", test_main, _BB_DIR_USR_BIN, test_usage},
296 {"tee", tee_main, _BB_DIR_USR_BIN, tee_usage},
299 {"touch", touch_main, _BB_DIR_BIN, touch_usage},
302 {"tr", tr_main, _BB_DIR_USR_BIN, tr_usage},
305 {"true", true_main, _BB_DIR_BIN, true_usage},
308 {"tty", tty_main, _BB_DIR_USR_BIN, tty_usage},
311 {"umount", umount_main, _BB_DIR_BIN, umount_usage},
314 {"uname", uname_main, _BB_DIR_BIN, uname_usage},
317 {"uniq", uniq_main, _BB_DIR_USR_BIN, uniq_usage},
320 {"unix2dos", unix2dos_main, _BB_DIR_USR_BIN, unix2dos_usage},
323 {"unrpm", unrpm_main, _BB_DIR_USR_BIN, unrpm_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 {"wget", wget_main, _BB_DIR_USR_BIN, wget_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},
364 const char *applet_name;
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));
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';) {
482 *argv = (char*)applet_name;
485 /* Add in a special case hack -- whenever **argv == '-'
486 * (i.e. '-su' or '-sh') always invoke the shell */
487 if (**argv == '-' && *(*argv+1)!= '-') {
488 exit(((*(shell_main)) (argc, argv)));
492 while (a->name != 0) {
493 if (strcmp(applet_name, a->name) == 0) {
494 if (a->usage && argv[1] && strcmp(argv[1], "--help") == 0)
496 exit(((*(a->main)) (argc, argv)));
500 return(busybox_main(argc, argv));
504 int busybox_main(int argc, char **argv)
511 if (been_there_done_that == 1 || argc < 1) {
512 const struct BB_applet *a = applets;
514 fprintf(stderr, "%s\n\n"
515 "Usage: busybox [function] [arguments]...\n"
516 " or: [function] [arguments]...\n\n"
517 "\tBusyBox is a multi-call binary that combines many common Unix\n"
518 "\tutilities into a single executable. Most people will create a\n"
519 "\tlink to busybox for each function they wish to use, and BusyBox\n"
520 "\twill act like whatever it was invoked as.\n"
521 "\nCurrently defined functions:\n", full_version);
523 while (a->name != 0) {
525 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
527 if (col > 60 && a->name != 0) {
528 fprintf(stderr, ",\n");
532 fprintf(stderr, "\n\n");
535 /* If we've already been here once, exit now */
536 been_there_done_that = 1;
537 return (main(argc, argv));
542 c-file-style: "linux"