blob: dfcf400e0aa803d24a53fbd1d24d4bb1d805e89e [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
John Beppu8f425db2000-06-27 04:50:02 +000016/*
17 * 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
John Beppu7cdc76d2000-06-28 00:41:26 +000035/*
36 * 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 Andersen90ca2842001-01-27 08:32:57 +000055 if (use_symbolic_links)
56 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 Andersenbdfd0d72001-10-24 05:00:29 +000085#ifdef CONFIG_LOCALE_SUPPORT
86#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 Andersenbdfd0d72001-10-24 05:00:29 +0000103#ifdef CONFIG_FEATURE_INSTALLER
John Beppu27b59242000-06-27 04:56:45 +0000104 /*
105 * This style of argument parsing doesn't scale well
106 * 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) {
116 if ((strcmp(argv[2], "-s") == 0)) {
117 use_symbolic_links = 1;
118 }
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
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000147 fprintf(stderr, "%s\n\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000148 "Usage: busybox [function] [arguments]...\n"
149 " or: [function] [arguments]...\n\n"
John Beppub4f86062000-04-13 03:36:01 +0000150 "\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"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000153 "\twill act like whatever it was invoked as.\n"
Manuel Novoa III cad53642003-03-19 09:13:01 +0000154 "\nCurrently defined functions:\n", bb_msg_full_version);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000155
156 while (a->name != 0) {
157 col +=
158 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
159 (a++)->name);
Tim Rikerb1ffba02003-11-07 19:37:20 +0000160 if (col > output_width && a->name != 0) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000161 fprintf(stderr, ",\n");
162 col = 0;
163 }
164 }
165 fprintf(stderr, "\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*/