blob: ee74b4c188f9b49af8e335201490762da3df6f10 [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersencc8ed391999-10-05 16:24:54 +00002#include <stdio.h>
3#include <string.h>
Eric Andersen90ca2842001-01-27 08:32:57 +00004#include <unistd.h>
Eric Andersencc8ed391999-10-05 16:24:54 +00005#include <errno.h>
Eric Andersened3ef502001-01-27 08:24:39 +00006#include <stdlib.h>
Eric Andersencbe31da2001-02-20 06:14:08 +00007#include "busybox.h"
Eric Andersenbdfd0d72001-10-24 05:00:29 +00008#ifdef CONFIG_LOCALE_SUPPORT
Eric Andersene5dfced2001-04-09 22:48:12 +00009#include <locale.h>
10#endif
11
Eric Andersen0f0c0b42001-04-03 17:05:01 +000012int been_there_done_that = 0; /* Also used in applets.c */
Manuel Novoa III cad53642003-03-19 09:13:01 +000013const char *bb_applet_name;
Erik Andersen05df2392000-01-13 04:43:48 +000014
Eric Andersenbdfd0d72001-10-24 05:00:29 +000015#ifdef CONFIG_FEATURE_INSTALLER
Eric Andersenc7bda1c2004-03-15 08:29:22 +000016/*
John Beppu8f425db2000-06-27 04:50:02 +000017 * directory table
Eric Andersen3570a342000-09-25 21:45:58 +000018 * this should be consistent w/ the enum, busybox.h::Location,
John Beppueb028332000-06-28 00:55:31 +000019 * or else...
John Beppu8f425db2000-06-27 04:50:02 +000020 */
Eric Andersenfcffa2c2002-04-06 05:17:57 +000021static const char usr_bin [] ="/usr/bin";
22static const char usr_sbin[] ="/usr/sbin";
23
24static const char* const install_dir[] = {
25 &usr_bin [8], /* "", equivalent to "/" for concat_path_file() */
26 &usr_bin [4], /* "/bin" */
27 &usr_sbin[4], /* "/sbin" */
28 usr_bin,
29 usr_sbin
John Beppu8f425db2000-06-27 04:50:02 +000030};
31
32/* abstract link() */
33typedef int (*__link_f)(const char *, const char *);
34
Eric Andersenc7bda1c2004-03-15 08:29:22 +000035/*
John Beppu7cdc76d2000-06-28 00:41:26 +000036 * Where in the filesystem is this busybox?
37 * [return]
38 * malloc'd string w/ full pathname of busybox's location
39 * NULL on failure
40 */
Eric Andersenfcffa2c2002-04-06 05:17:57 +000041static inline char *busybox_fullpath(void)
John Beppu7cdc76d2000-06-28 00:41:26 +000042{
Eric Andersen28355a32001-05-07 17:48:28 +000043 return xreadlink("/proc/self/exe");
John Beppu7cdc76d2000-06-28 00:41:26 +000044}
45
John Beppu8f425db2000-06-27 04:50:02 +000046/* create (sym)links for each applet */
Eric Andersenc5949f62000-09-25 20:35:54 +000047static void install_links(const char *busybox, int use_symbolic_links)
John Beppu8f425db2000-06-27 04:50:02 +000048{
John Beppueb028332000-06-28 00:55:31 +000049 __link_f Link = link;
John Beppu8f425db2000-06-27 04:50:02 +000050
Eric Andersene5dfced2001-04-09 22:48:12 +000051 char *fpc;
John Beppueb028332000-06-28 00:55:31 +000052 int i;
Eric Andersenc5949f62000-09-25 20:35:54 +000053 int rc;
John Beppu8f425db2000-06-27 04:50:02 +000054
Eric Andersenc7bda1c2004-03-15 08:29:22 +000055 if (use_symbolic_links)
Eric Andersen90ca2842001-01-27 08:32:57 +000056 Link = symlink;
John Beppu8f425db2000-06-27 04:50:02 +000057
John Beppueb028332000-06-28 00:55:31 +000058 for (i = 0; applets[i].name != NULL; i++) {
Eric Andersene5dfced2001-04-09 22:48:12 +000059 fpc = concat_path_file(
60 install_dir[applets[i].location], applets[i].name);
61 rc = Link(busybox, fpc);
62 if (rc!=0 && errno!=EEXIST) {
Manuel Novoa III cad53642003-03-19 09:13:01 +000063 bb_perror_msg("%s", fpc);
John Beppu8f425db2000-06-27 04:50:02 +000064 }
Eric Andersene5dfced2001-04-09 22:48:12 +000065 free(fpc);
John Beppueb028332000-06-28 00:55:31 +000066 }
John Beppu8f425db2000-06-27 04:50:02 +000067}
68
Eric Andersenbdfd0d72001-10-24 05:00:29 +000069#endif /* CONFIG_FEATURE_INSTALLER */
John Beppu8f425db2000-06-27 04:50:02 +000070
Eric Andersencc8ed391999-10-05 16:24:54 +000071int main(int argc, char **argv)
72{
Matt Kraaif2cc2762001-02-01 19:21:20 +000073 const char *s;
Eric Andersenf5d5e772001-01-24 23:34:48 +000074
Manuel Novoa III cad53642003-03-19 09:13:01 +000075 bb_applet_name = argv[0];
Matt Kraai449377a2001-08-27 15:02:32 +000076
Manuel Novoa III cad53642003-03-19 09:13:01 +000077 if (bb_applet_name[0] == '-')
78 bb_applet_name++;
Matt Kraai449377a2001-08-27 15:02:32 +000079
Manuel Novoa III cad53642003-03-19 09:13:01 +000080 for (s = bb_applet_name; *s != '\0';) {
Eric Andersenf5d5e772001-01-24 23:34:48 +000081 if (*s++ == '/')
Manuel Novoa III cad53642003-03-19 09:13:01 +000082 bb_applet_name = s;
Eric Andersenf5d5e772001-01-24 23:34:48 +000083 }
84
Eric Andersenc7bda1c2004-03-15 08:29:22 +000085#ifdef CONFIG_LOCALE_SUPPORT
Eric Andersenbdfd0d72001-10-24 05:00:29 +000086#ifdef CONFIG_INIT
Eric Andersene5dfced2001-04-09 22:48:12 +000087 if(getpid()!=1) /* Do not set locale for `init' */
Eric Andersen4819c3d2001-05-13 00:33:16 +000088#endif
89 {
Eric Andersene5dfced2001-04-09 22:48:12 +000090 setlocale(LC_ALL, "");
Eric Andersen4819c3d2001-05-13 00:33:16 +000091 }
Eric Andersene5dfced2001-04-09 22:48:12 +000092#endif
93
Manuel Novoa III cad53642003-03-19 09:13:01 +000094 run_applet_by_name(bb_applet_name, argc, argv);
95 bb_error_msg_and_die("applet not found");
Eric Andersenf5d5e772001-01-24 23:34:48 +000096}
97
98
99int busybox_main(int argc, char **argv)
100{
Glenn L McGrathfd7bc132003-10-04 00:05:47 +0000101 int col = 0, len, i;
Eric Andersencc8ed391999-10-05 16:24:54 +0000102
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000103#ifdef CONFIG_FEATURE_INSTALLER
104 /*
105 * This style of argument parsing doesn't scale well
John Beppu27b59242000-06-27 04:56:45 +0000106 * in the event that busybox starts wanting more --options.
107 * If someone has a cleaner approach, by all means implement it.
108 */
John Beppu8f425db2000-06-27 04:50:02 +0000109 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
110 int use_symbolic_links = 0;
John Beppu7cdc76d2000-06-28 00:41:26 +0000111 int rc = 0;
112 char *busybox;
John Beppu8f425db2000-06-27 04:50:02 +0000113
John Beppu27b59242000-06-27 04:56:45 +0000114 /* to use symlinks, or not to use symlinks... */
John Beppu8f425db2000-06-27 04:50:02 +0000115 if (argc > 2) {
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000116 if ((strcmp(argv[2], "-s") == 0)) {
117 use_symbolic_links = 1;
John Beppu8f425db2000-06-27 04:50:02 +0000118 }
119 }
John Beppu7cdc76d2000-06-28 00:41:26 +0000120
121 /* link */
122 busybox = busybox_fullpath();
123 if (busybox) {
124 install_links(busybox, use_symbolic_links);
125 free(busybox);
126 } else {
127 rc = 1;
128 }
129 return rc;
John Beppu8f425db2000-06-27 04:50:02 +0000130 }
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000131#endif /* CONFIG_FEATURE_INSTALLER */
John Beppu8f425db2000-06-27 04:50:02 +0000132
Erik Andersene49d5ec2000-02-08 19:58:47 +0000133 argc--;
Eric Andersencc8ed391999-10-05 16:24:54 +0000134
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000135 /* If we've already been here once, exit now */
Erik Andersene49d5ec2000-02-08 19:58:47 +0000136 if (been_there_done_that == 1 || argc < 1) {
Erik Andersenbcd61772000-05-13 06:33:19 +0000137 const struct BB_applet *a = applets;
Tim Rikerb1ffba02003-11-07 19:37:20 +0000138 int output_width = 60;
139
140#ifdef CONFIG_FEATURE_AUTOWIDTH
141 /* Obtain the terminal width. */
142 get_terminal_width_height(0, &output_width, NULL);
143 /* leading tab and room to wrap */
144 output_width -= 20;
145#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000146
Mike Frysinger2c12d432005-04-22 02:19:01 +0000147 printf("%s\n\n"
148 "Usage: busybox [function] [arguments]...\n"
149 " or: [function] [arguments]...\n\n"
150 "\tBusyBox is a multi-call binary that combines many common Unix\n"
151 "\tutilities into a single executable. Most people will create a\n"
152 "\tlink to busybox for each function they wish to use and BusyBox\n"
153 "\twill act like whatever it was invoked as!\n"
154 "\nCurrently defined functions:\n", bb_msg_full_version);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000155
156 while (a->name != 0) {
157 col +=
Mike Frysinger2c12d432005-04-22 02:19:01 +0000158 printf("%s%s", ((col == 0) ? "\t" : ", "),
159 (a++)->name);
Tim Rikerb1ffba02003-11-07 19:37:20 +0000160 if (col > output_width && a->name != 0) {
Mike Frysinger2c12d432005-04-22 02:19:01 +0000161 printf(",\n");
Erik Andersene49d5ec2000-02-08 19:58:47 +0000162 col = 0;
163 }
164 }
Mike Frysinger2c12d432005-04-22 02:19:01 +0000165 printf("\n\n");
Mark Whitley01677182001-03-02 17:47:17 +0000166 exit(0);
Eric Andersencc8ed391999-10-05 16:24:54 +0000167 }
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000168
169 /* Flag that we've been here already */
Eric Andersenb6106152000-06-19 17:25:40 +0000170 been_there_done_that = 1;
Glenn L McGrath4a77c782003-10-03 07:51:30 +0000171
172 /* Move the command line down a notch */
Glenn L McGrathf86bd9f2003-10-03 13:21:10 +0000173 /* Preserve pointers so setproctitle() works consistently */
174 len = argv[argc] + strlen(argv[argc]) - argv[1];
175 memmove(argv[0], argv[1], len);
176 memset(argv[0] + len, 0, argv[1] - argv[0]);
177
178 /* Fix up the argv pointers */
179 len = argv[1] - argv[0];
180 memmove(argv, argv + 1, sizeof(char *) * (argc + 1));
181 for (i = 0; i < argc; i++)
182 argv[i] -= len;
183
184 return (main(argc, argv));
Eric Andersencc8ed391999-10-05 16:24:54 +0000185}
Erik Andersen029011b2000-03-04 21:19:32 +0000186
187/*
188Local Variables:
189c-file-style: "linux"
190c-basic-offset: 4
191tab-width: 4
192End:
193*/