blob: 4d59b45181b63acb0bc5c4c75af5beb6d9998ecf [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;
Erik Andersen05df2392000-01-13 04:43:48 +000010
Eric Andersenbdfd0d72001-10-24 05:00:29 +000011#ifdef CONFIG_FEATURE_INSTALLER
Eric Andersenc7bda1c2004-03-15 08:29:22 +000012/*
John Beppu8f425db2000-06-27 04:50:02 +000013 * directory table
Eric Andersen3570a342000-09-25 21:45:58 +000014 * this should be consistent w/ the enum, busybox.h::Location,
John Beppueb028332000-06-28 00:55:31 +000015 * or else...
John Beppu8f425db2000-06-27 04:50:02 +000016 */
Eric Andersenfcffa2c2002-04-06 05:17:57 +000017static const char usr_bin [] ="/usr/bin";
18static const char usr_sbin[] ="/usr/sbin";
19
20static const char* const install_dir[] = {
21 &usr_bin [8], /* "", equivalent to "/" for concat_path_file() */
22 &usr_bin [4], /* "/bin" */
23 &usr_sbin[4], /* "/sbin" */
24 usr_bin,
25 usr_sbin
John Beppu8f425db2000-06-27 04:50:02 +000026};
27
28/* abstract link() */
29typedef int (*__link_f)(const char *, const char *);
30
31/* create (sym)links for each applet */
Eric Andersenc5949f62000-09-25 20:35:54 +000032static void install_links(const char *busybox, int use_symbolic_links)
John Beppu8f425db2000-06-27 04:50:02 +000033{
John Beppueb028332000-06-28 00:55:31 +000034 __link_f Link = link;
John Beppu8f425db2000-06-27 04:50:02 +000035
Eric Andersene5dfced2001-04-09 22:48:12 +000036 char *fpc;
John Beppueb028332000-06-28 00:55:31 +000037 int i;
Eric Andersenc5949f62000-09-25 20:35:54 +000038 int rc;
John Beppu8f425db2000-06-27 04:50:02 +000039
Eric Andersenc7bda1c2004-03-15 08:29:22 +000040 if (use_symbolic_links)
Eric Andersen90ca2842001-01-27 08:32:57 +000041 Link = symlink;
John Beppu8f425db2000-06-27 04:50:02 +000042
John Beppueb028332000-06-28 00:55:31 +000043 for (i = 0; applets[i].name != NULL; i++) {
Eric Andersene5dfced2001-04-09 22:48:12 +000044 fpc = concat_path_file(
45 install_dir[applets[i].location], applets[i].name);
46 rc = Link(busybox, fpc);
47 if (rc!=0 && errno!=EEXIST) {
Manuel Novoa III cad53642003-03-19 09:13:01 +000048 bb_perror_msg("%s", fpc);
John Beppu8f425db2000-06-27 04:50:02 +000049 }
Eric Andersene5dfced2001-04-09 22:48:12 +000050 free(fpc);
John Beppueb028332000-06-28 00:55:31 +000051 }
John Beppu8f425db2000-06-27 04:50:02 +000052}
53
Rob Landley8a7a6782005-09-05 04:13:33 +000054#else
55#define install_links(x,y)
Eric Andersenbdfd0d72001-10-24 05:00:29 +000056#endif /* CONFIG_FEATURE_INSTALLER */
John Beppu8f425db2000-06-27 04:50:02 +000057
Eric Andersencc8ed391999-10-05 16:24:54 +000058int main(int argc, char **argv)
59{
Matt Kraaif2cc2762001-02-01 19:21:20 +000060 const char *s;
Eric Andersenf5d5e772001-01-24 23:34:48 +000061
Denis Vlasenko8f8f2682006-10-03 21:00:43 +000062 applet_name=argv[0];
63 if (*applet_name == '-') applet_name++;
64 for (s = applet_name; *s ;)
65 if (*(s++) == '/') applet_name = s;
Matt Kraai449377a2001-08-27 15:02:32 +000066
Denis Vlasenkofcdb00f2006-11-21 00:09:37 +000067 /* Set locale for everybody except 'init' */
68 if (ENABLE_LOCALE_SUPPORT && getpid() != 1)
Eric Andersene5dfced2001-04-09 22:48:12 +000069 setlocale(LC_ALL, "");
Eric Andersene5dfced2001-04-09 22:48:12 +000070
Denis Vlasenko8f8f2682006-10-03 21:00:43 +000071 run_applet_by_name(applet_name, argc, argv);
Manuel Novoa III cad53642003-03-19 09:13:01 +000072 bb_error_msg_and_die("applet not found");
Eric Andersenf5d5e772001-01-24 23:34:48 +000073}
74
Eric Andersenf5d5e772001-01-24 23:34:48 +000075int busybox_main(int argc, char **argv)
76{
Eric Andersenc7bda1c2004-03-15 08:29:22 +000077 /*
78 * This style of argument parsing doesn't scale well
John Beppu27b59242000-06-27 04:56:45 +000079 * in the event that busybox starts wanting more --options.
80 * If someone has a cleaner approach, by all means implement it.
81 */
Rob Landleyb766c392005-09-04 11:10:37 +000082 if (ENABLE_FEATURE_INSTALLER && argc > 1 && !strcmp(argv[1], "--install")) {
John Beppu8f425db2000-06-27 04:50:02 +000083 int use_symbolic_links = 0;
John Beppu7cdc76d2000-06-28 00:41:26 +000084 int rc = 0;
85 char *busybox;
John Beppu8f425db2000-06-27 04:50:02 +000086
John Beppu27b59242000-06-27 04:56:45 +000087 /* to use symlinks, or not to use symlinks... */
John Beppu8f425db2000-06-27 04:50:02 +000088 if (argc > 2) {
Eric Andersenc7bda1c2004-03-15 08:29:22 +000089 if ((strcmp(argv[2], "-s") == 0)) {
90 use_symbolic_links = 1;
John Beppu8f425db2000-06-27 04:50:02 +000091 }
92 }
John Beppu7cdc76d2000-06-28 00:41:26 +000093
94 /* link */
Rob Landleyb766c392005-09-04 11:10:37 +000095 busybox = xreadlink("/proc/self/exe");
John Beppu7cdc76d2000-06-28 00:41:26 +000096 if (busybox) {
97 install_links(busybox, use_symbolic_links);
98 free(busybox);
99 } else {
100 rc = 1;
101 }
102 return rc;
John Beppu8f425db2000-06-27 04:50:02 +0000103 }
John Beppu8f425db2000-06-27 04:50:02 +0000104
Rob Landleyb766c392005-09-04 11:10:37 +0000105 /* Deal with --help. (Also print help when called with no arguments) */
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000106
Rob Landleyb766c392005-09-04 11:10:37 +0000107 if (argc==1 || !strcmp(argv[1],"--help") ) {
"Vladimir N. Oleynik"10a1fe62005-09-05 11:25:27 +0000108 if (argc>2) {
Denis Vlasenko8f8f2682006-10-03 21:00:43 +0000109 applet_name = argv[2];
110 run_applet_by_name(applet_name, 2, argv);
"Vladimir N. Oleynik"10a1fe62005-09-05 11:25:27 +0000111 } else {
Rob Landleyb766c392005-09-04 11:10:37 +0000112 const struct BB_applet *a;
113 int col, output_width;
Eric Andersencc8ed391999-10-05 16:24:54 +0000114
Rob Landleyb766c392005-09-04 11:10:37 +0000115 if (ENABLE_FEATURE_AUTOWIDTH) {
116 /* Obtain the terminal width. */
117 get_terminal_width_height(0, &output_width, NULL);
118 /* leading tab and room to wrap */
Denis Vlasenko01c27fc2006-10-05 21:10:53 +0000119 output_width -= sizeof("start-stop-daemon, ") + 8;
120 } else output_width = 80 - sizeof("start-stop-daemon, ") - 8;
Tim Rikerb1ffba02003-11-07 19:37:20 +0000121
Rob Landleyeb84a422006-09-20 21:41:13 +0000122 printf("%s\n"
Denis Vlasenko01c27fc2006-10-05 21:10:53 +0000123 "Copyright (C) 1998-2006  Erik Andersen, Rob Landley, and others.\n"
124 "Licensed under GPLv2.  See source distribution for full notice.\n\n"
Rob Landleyb766c392005-09-04 11:10:37 +0000125 "Usage: busybox [function] [arguments]...\n"
126 " or: [function] [arguments]...\n\n"
127 "\tBusyBox is a multi-call binary that combines many common Unix\n"
128 "\tutilities into a single executable. Most people will create a\n"
129 "\tlink to busybox for each function they wish to use and BusyBox\n"
130 "\twill act like whatever it was invoked as!\n"
131 "\nCurrently defined functions:\n", bb_msg_full_version);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000132
Rob Landleyb766c392005-09-04 11:10:37 +0000133 col=0;
134 for(a = applets; a->name;) {
135 col += printf("%s%s", (col ? ", " : "\t"), (a++)->name);
136 if (col > output_width && a->name) {
137 printf(",\n");
138 col = 0;
139 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000140 }
Rob Landleyb766c392005-09-04 11:10:37 +0000141 printf("\n\n");
142 exit(0);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000143 }
Rob Landley9fb272a2006-05-07 01:44:23 +0000144 } else run_applet_by_name(argv[1], argc-1, argv+1);
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000145
Rob Landleyb766c392005-09-04 11:10:37 +0000146 bb_error_msg_and_die("applet not found");
Eric Andersencc8ed391999-10-05 16:24:54 +0000147}