blob: 47a8b40970397da43bbaeff1cfd3aab45c483600 [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Bernhard Reutner-Fischerb1629b12006-05-19 19:29:19 +00002/*
Bernhard Reutner-Fischere15d7572006-06-02 20:56:16 +00003 * BusyBox' main applet dispatcher.
4 *
Rob Landleyeb84a422006-09-20 21:41:13 +00005 * Licensed under GPLv2, see file LICENSE in this tarball for details.
Bernhard Reutner-Fischerb1629b12006-05-19 19:29:19 +00006 */
Bernhard Reutner-Fischere15d7572006-06-02 20:56:16 +00007#include "busybox.h"
Eric Andersene5dfced2001-04-09 22:48:12 +00008
Denis Vlasenko8f8f2682006-10-03 21:00:43 +00009const char *applet_name ATTRIBUTE_EXTERNALLY_VISIBLE;
Denis Vlasenko8a503be2007-03-24 16:13:33 +000010#ifdef BB_NOMMU
Denis Vlasenko9067f132007-03-24 12:11:17 +000011smallint re_execed;
Denis Vlasenko8a503be2007-03-24 16:13:33 +000012#endif
Erik Andersen05df2392000-01-13 04:43:48 +000013
Eric Andersenbdfd0d72001-10-24 05:00:29 +000014#ifdef CONFIG_FEATURE_INSTALLER
Eric Andersenc7bda1c2004-03-15 08:29:22 +000015/*
John Beppu8f425db2000-06-27 04:50:02 +000016 * directory table
Eric Andersen3570a342000-09-25 21:45:58 +000017 * this should be consistent w/ the enum, busybox.h::Location,
John Beppueb028332000-06-28 00:55:31 +000018 * or else...
John Beppu8f425db2000-06-27 04:50:02 +000019 */
Denis Vlasenko0ee39992006-12-24 15:23:28 +000020static const char usr_bin [] = "/usr/bin";
21static const char usr_sbin[] = "/usr/sbin";
Eric Andersenfcffa2c2002-04-06 05:17:57 +000022
23static const char* const install_dir[] = {
24 &usr_bin [8], /* "", equivalent to "/" for concat_path_file() */
25 &usr_bin [4], /* "/bin" */
26 &usr_sbin[4], /* "/sbin" */
27 usr_bin,
28 usr_sbin
John Beppu8f425db2000-06-27 04:50:02 +000029};
30
31/* abstract link() */
Denis Vlasenko0ee39992006-12-24 15:23:28 +000032typedef int (*link_func)(const char *, const char *);
John Beppu8f425db2000-06-27 04:50:02 +000033
34/* create (sym)links for each applet */
Eric Andersenc5949f62000-09-25 20:35:54 +000035static void install_links(const char *busybox, int use_symbolic_links)
John Beppu8f425db2000-06-27 04:50:02 +000036{
Denis Vlasenko0ee39992006-12-24 15:23:28 +000037 link_func lf = link;
Eric Andersene5dfced2001-04-09 22:48:12 +000038 char *fpc;
John Beppueb028332000-06-28 00:55:31 +000039 int i;
Eric Andersenc5949f62000-09-25 20:35:54 +000040 int rc;
John Beppu8f425db2000-06-27 04:50:02 +000041
Eric Andersenc7bda1c2004-03-15 08:29:22 +000042 if (use_symbolic_links)
Denis Vlasenko0ee39992006-12-24 15:23:28 +000043 lf = symlink;
John Beppu8f425db2000-06-27 04:50:02 +000044
John Beppueb028332000-06-28 00:55:31 +000045 for (i = 0; applets[i].name != NULL; i++) {
Eric Andersene5dfced2001-04-09 22:48:12 +000046 fpc = concat_path_file(
Denis Vlasenko0ee39992006-12-24 15:23:28 +000047 install_dir[applets[i].location],
48 applets[i].name);
49 rc = lf(busybox, fpc);
50 if (rc != 0 && errno != EEXIST) {
Manuel Novoa III cad53642003-03-19 09:13:01 +000051 bb_perror_msg("%s", fpc);
John Beppu8f425db2000-06-27 04:50:02 +000052 }
Eric Andersene5dfced2001-04-09 22:48:12 +000053 free(fpc);
John Beppueb028332000-06-28 00:55:31 +000054 }
John Beppu8f425db2000-06-27 04:50:02 +000055}
56
Rob Landley8a7a6782005-09-05 04:13:33 +000057#else
58#define install_links(x,y)
Eric Andersenbdfd0d72001-10-24 05:00:29 +000059#endif /* CONFIG_FEATURE_INSTALLER */
John Beppu8f425db2000-06-27 04:50:02 +000060
Eric Andersencc8ed391999-10-05 16:24:54 +000061int main(int argc, char **argv)
62{
Matt Kraaif2cc2762001-02-01 19:21:20 +000063 const char *s;
Eric Andersenf5d5e772001-01-24 23:34:48 +000064
Denis Vlasenko8a503be2007-03-24 16:13:33 +000065#ifdef BB_NOMMU
Denis Vlasenko9067f132007-03-24 12:11:17 +000066 /* NOMMU re-exec trick sets high-order bit in first byte of name */
67 if (argv[0][0] & 0x80) {
68 re_execed = 1;
69 argv[0][0] &= 0x7f;
70 }
Denis Vlasenko8a503be2007-03-24 16:13:33 +000071#endif
Denis Vlasenko9067f132007-03-24 12:11:17 +000072
Denis Vlasenko0ee39992006-12-24 15:23:28 +000073 applet_name = argv[0];
74 if (*applet_name == '-')
75 applet_name++;
76 while ((s = strchr(applet_name, '/')))
77 applet_name = s + 1;
Matt Kraai449377a2001-08-27 15:02:32 +000078
Denis Vlasenkofcdb00f2006-11-21 00:09:37 +000079 /* Set locale for everybody except 'init' */
80 if (ENABLE_LOCALE_SUPPORT && getpid() != 1)
Eric Andersene5dfced2001-04-09 22:48:12 +000081 setlocale(LC_ALL, "");
Eric Andersene5dfced2001-04-09 22:48:12 +000082
Denis Vlasenko8f8f2682006-10-03 21:00:43 +000083 run_applet_by_name(applet_name, argc, argv);
Manuel Novoa III cad53642003-03-19 09:13:01 +000084 bb_error_msg_and_die("applet not found");
Eric Andersenf5d5e772001-01-24 23:34:48 +000085}
86
Denis Vlasenko06af2162007-02-03 17:28:39 +000087int busybox_main(int argc, char **argv);
Eric Andersenf5d5e772001-01-24 23:34:48 +000088int busybox_main(int argc, char **argv)
89{
Eric Andersenc7bda1c2004-03-15 08:29:22 +000090 /*
91 * This style of argument parsing doesn't scale well
John Beppu27b59242000-06-27 04:56:45 +000092 * in the event that busybox starts wanting more --options.
93 * If someone has a cleaner approach, by all means implement it.
94 */
Rob Landleyb766c392005-09-04 11:10:37 +000095 if (ENABLE_FEATURE_INSTALLER && argc > 1 && !strcmp(argv[1], "--install")) {
John Beppu8f425db2000-06-27 04:50:02 +000096 int use_symbolic_links = 0;
John Beppu7cdc76d2000-06-28 00:41:26 +000097 char *busybox;
John Beppu8f425db2000-06-27 04:50:02 +000098
John Beppu27b59242000-06-27 04:56:45 +000099 /* to use symlinks, or not to use symlinks... */
Denis Vlasenko0ee39992006-12-24 15:23:28 +0000100 if (argc > 2)
101 if (strcmp(argv[2], "-s") == 0)
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000102 use_symbolic_links = 1;
John Beppu7cdc76d2000-06-28 00:41:26 +0000103
104 /* link */
Bernhard Reutner-Fischerb40bdb32006-11-22 18:40:06 +0000105// XXX: FIXME: this is broken. Why not just use argv[0] ?
Denis Vlasenko6ca04442007-02-11 16:19:28 +0000106 busybox = xmalloc_readlink_or_warn("/proc/self/exe");
Denis Vlasenko0ee39992006-12-24 15:23:28 +0000107 if (!busybox)
108 return 1;
109 install_links(busybox, use_symbolic_links);
110 if (ENABLE_FEATURE_CLEAN_UP)
John Beppu7cdc76d2000-06-28 00:41:26 +0000111 free(busybox);
Denis Vlasenko0ee39992006-12-24 15:23:28 +0000112 return 0;
John Beppu8f425db2000-06-27 04:50:02 +0000113 }
John Beppu8f425db2000-06-27 04:50:02 +0000114
Rob Landleyb766c392005-09-04 11:10:37 +0000115 /* Deal with --help. (Also print help when called with no arguments) */
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000116
Denis Vlasenko0ee39992006-12-24 15:23:28 +0000117 if (argc == 1 || !strcmp(argv[1], "--help") ) {
118 if (argc > 2) {
Denis Vlasenko8f8f2682006-10-03 21:00:43 +0000119 applet_name = argv[2];
120 run_applet_by_name(applet_name, 2, argv);
"Vladimir N. Oleynik"10a1fe62005-09-05 11:25:27 +0000121 } else {
Rob Landleyb766c392005-09-04 11:10:37 +0000122 const struct BB_applet *a;
123 int col, output_width;
Eric Andersencc8ed391999-10-05 16:24:54 +0000124
Denis Vlasenko0ee39992006-12-24 15:23:28 +0000125 output_width = 80 - sizeof("start-stop-daemon, ") - 8;
Rob Landleyb766c392005-09-04 11:10:37 +0000126 if (ENABLE_FEATURE_AUTOWIDTH) {
127 /* Obtain the terminal width. */
128 get_terminal_width_height(0, &output_width, NULL);
129 /* leading tab and room to wrap */
Denis Vlasenko01c27fc2006-10-05 21:10:53 +0000130 output_width -= sizeof("start-stop-daemon, ") + 8;
Denis Vlasenko0ee39992006-12-24 15:23:28 +0000131 }
Tim Rikerb1ffba02003-11-07 19:37:20 +0000132
Rob Landleyeb84a422006-09-20 21:41:13 +0000133 printf("%s\n"
Denis Vlasenko01c27fc2006-10-05 21:10:53 +0000134 "Copyright (C) 1998-2006  Erik Andersen, Rob Landley, and others.\n"
135 "Licensed under GPLv2.  See source distribution for full notice.\n\n"
Rob Landleyb766c392005-09-04 11:10:37 +0000136 "Usage: busybox [function] [arguments]...\n"
137 " or: [function] [arguments]...\n\n"
138 "\tBusyBox is a multi-call binary that combines many common Unix\n"
139 "\tutilities into a single executable. Most people will create a\n"
140 "\tlink to busybox for each function they wish to use and BusyBox\n"
141 "\twill act like whatever it was invoked as!\n"
142 "\nCurrently defined functions:\n", bb_msg_full_version);
Denis Vlasenko0ee39992006-12-24 15:23:28 +0000143 col = 0;
Denis Vlasenkobf0a2012006-12-26 10:42:51 +0000144 for (a = applets; a->name;) {
Denis Vlasenko0ee39992006-12-24 15:23:28 +0000145 col += printf("%s%s", (col ? ", " : "\t"), a->name);
146 a++;
Rob Landleyb766c392005-09-04 11:10:37 +0000147 if (col > output_width && a->name) {
Denis Vlasenko0ee39992006-12-24 15:23:28 +0000148 puts(",");
Rob Landleyb766c392005-09-04 11:10:37 +0000149 col = 0;
150 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000151 }
Denis Vlasenko0ee39992006-12-24 15:23:28 +0000152 puts("\n");
153 return 0;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000154 }
Denis Vlasenko0ee39992006-12-24 15:23:28 +0000155 } else run_applet_by_name(argv[1], argc - 1, argv + 1);
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000156
Rob Landleyb766c392005-09-04 11:10:37 +0000157 bb_error_msg_and_die("applet not found");
Eric Andersencc8ed391999-10-05 16:24:54 +0000158}