blob: 696dd4262559bf46a30f6c1b48e25e081a34daea [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersen3570a342000-09-25 21:45:58 +00002#include "busybox.h"
Eric Andersencc8ed391999-10-05 16:24:54 +00003#include <stdio.h>
4#include <string.h>
5#include <errno.h>
Mark Whitley130005c2000-10-25 00:28:27 +00006#include "applets.h"
Eric Andersencc8ed391999-10-05 16:24:54 +00007
Pavel Roskin9c5fcc32000-07-17 23:45:12 +00008#define bb_need_full_version
9#define BB_DECLARE_EXTERN
10#include "messages.c"
11
Eric Andersencc8ed391999-10-05 16:24:54 +000012static int been_there_done_that = 0;
13
Eric Andersencc8ed391999-10-05 16:24:54 +000014
Eric Andersen501c88b2000-07-28 15:14:45 +000015const char *applet_name;
Erik Andersen05df2392000-01-13 04:43:48 +000016
John Beppu8f425db2000-06-27 04:50:02 +000017#ifdef BB_FEATURE_INSTALLER
18/*
19 * directory table
Eric Andersen3570a342000-09-25 21:45:58 +000020 * this should be consistent w/ the enum, busybox.h::Location,
John Beppueb028332000-06-28 00:55:31 +000021 * or else...
John Beppu8f425db2000-06-27 04:50:02 +000022 */
23static char* install_dir[] = {
John Beppueb028332000-06-28 00:55:31 +000024 "/",
25 "/bin",
26 "/sbin",
27 "/usr/bin",
28 "/usr/sbin",
John Beppu8f425db2000-06-27 04:50:02 +000029};
30
31/* abstract link() */
32typedef int (*__link_f)(const char *, const char *);
33
John Beppu7cdc76d2000-06-28 00:41:26 +000034/*
35 * Where in the filesystem is this busybox?
36 * [return]
37 * malloc'd string w/ full pathname of busybox's location
38 * NULL on failure
39 */
40static char *busybox_fullpath()
41{
John Beppueb028332000-06-28 00:55:31 +000042 pid_t pid;
43 char path[256];
44 char proc[256];
45 int len;
John Beppu7cdc76d2000-06-28 00:41:26 +000046
47 pid = getpid();
48 sprintf(proc, "/proc/%d/exe", pid);
49 len = readlink(proc, path, 256);
50 if (len != -1) {
51 path[len] = 0;
52 } else {
Matt Kraaid537a952000-07-14 01:51:25 +000053 errorMsg("%s: %s\n", proc, strerror(errno));
John Beppu7cdc76d2000-06-28 00:41:26 +000054 return NULL;
55 }
56 return strdup(path);
57}
58
John Beppu8f425db2000-06-27 04:50:02 +000059/* create (sym)links for each applet */
Eric Andersenc5949f62000-09-25 20:35:54 +000060static void install_links(const char *busybox, int use_symbolic_links)
John Beppu8f425db2000-06-27 04:50:02 +000061{
John Beppueb028332000-06-28 00:55:31 +000062 __link_f Link = link;
John Beppu8f425db2000-06-27 04:50:02 +000063
John Beppueb028332000-06-28 00:55:31 +000064 char command[256];
65 int i;
Eric Andersenc5949f62000-09-25 20:35:54 +000066 int rc;
John Beppu8f425db2000-06-27 04:50:02 +000067
68 if (use_symbolic_links) Link = symlink;
69
John Beppueb028332000-06-28 00:55:31 +000070 for (i = 0; applets[i].name != NULL; i++) {
Eric Andersenc5949f62000-09-25 20:35:54 +000071 sprintf ( command, "%s/%s",
72 install_dir[applets[i].location],
73 applets[i].name);
74 rc = Link(busybox, command);
75
John Beppu8f425db2000-06-27 04:50:02 +000076 if (rc) {
Matt Kraaid537a952000-07-14 01:51:25 +000077 errorMsg("%s: %s\n", command, strerror(errno));
John Beppu8f425db2000-06-27 04:50:02 +000078 }
John Beppueb028332000-06-28 00:55:31 +000079 }
John Beppu8f425db2000-06-27 04:50:02 +000080}
81
John Beppu8f425db2000-06-27 04:50:02 +000082#endif /* BB_FEATURE_INSTALLER */
83
Erik Andersen05df2392000-01-13 04:43:48 +000084
Eric Andersencc8ed391999-10-05 16:24:54 +000085int main(int argc, char **argv)
86{
Eric Andersen501c88b2000-07-28 15:14:45 +000087 const char *s;
Mark Whitley130005c2000-10-25 00:28:27 +000088 int u, l; /* Lower and upper bounds for the binary search. */
Matt Kraaid537a952000-07-14 01:51:25 +000089 applet_name = "busybox";
Eric Andersencc8ed391999-10-05 16:24:54 +000090
John Beppu8f425db2000-06-27 04:50:02 +000091#ifdef BB_FEATURE_INSTALLER
John Beppu27b59242000-06-27 04:56:45 +000092 /*
93 * This style of argument parsing doesn't scale well
94 * in the event that busybox starts wanting more --options.
95 * If someone has a cleaner approach, by all means implement it.
96 */
John Beppu8f425db2000-06-27 04:50:02 +000097 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
98 int use_symbolic_links = 0;
John Beppu7cdc76d2000-06-28 00:41:26 +000099 int rc = 0;
100 char *busybox;
John Beppu8f425db2000-06-27 04:50:02 +0000101
John Beppu27b59242000-06-27 04:56:45 +0000102 /* to use symlinks, or not to use symlinks... */
John Beppu8f425db2000-06-27 04:50:02 +0000103 if (argc > 2) {
104 if ((strcmp(argv[2], "-s") == 0)) {
105 use_symbolic_links = 1;
106 }
107 }
John Beppu7cdc76d2000-06-28 00:41:26 +0000108
109 /* link */
110 busybox = busybox_fullpath();
111 if (busybox) {
112 install_links(busybox, use_symbolic_links);
113 free(busybox);
114 } else {
115 rc = 1;
116 }
117 return rc;
John Beppu8f425db2000-06-27 04:50:02 +0000118 }
119#endif /* BB_FEATURE_INSTALLER */
120
Matt Kraai77190082000-07-11 20:03:24 +0000121 for (s = applet_name = argv[0]; *s != '\0';) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000122 if (*s++ == '/')
Matt Kraai77190082000-07-11 20:03:24 +0000123 applet_name = s;
Eric Andersencc8ed391999-10-05 16:24:54 +0000124 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000125
Eric Andersen501c88b2000-07-28 15:14:45 +0000126 *argv = (char*)applet_name;
Erik Andersen029011b2000-03-04 21:19:32 +0000127
Eric Andersen5d41d602000-06-29 20:20:14 +0000128#ifdef BB_SH
129 /* Add in a special case hack -- whenever **argv == '-'
130 * (i.e. '-su' or '-sh') always invoke the shell */
Eric Andersenbf960f52000-07-21 21:32:12 +0000131 if (**argv == '-' && *(*argv+1)!= '-') {
Eric Andersen5d41d602000-06-29 20:20:14 +0000132 exit(((*(shell_main)) (argc, argv)));
Eric Andersenbf960f52000-07-21 21:32:12 +0000133 }
Eric Andersen5d41d602000-06-29 20:20:14 +0000134#endif
135
Mark Whitley130005c2000-10-25 00:28:27 +0000136 /* Do a binary search to find the applet entry given the name. */
137
138 u = NUM_APPLETS - 1;
139 l = 0;
140
141 for (;;) {
142 int i = l + (u - l) / 2;
143 int j = strcmp(applet_name, applets[i].name);
144
145 if (j == 0) {
146 if (applets[i].usage && argv[1] && strcmp(argv[1], "--help") == 0)
147 usage(applets[i].usage);
148 exit(((*(applets[i].main)) (argc, argv)));
Erik Andersene49d5ec2000-02-08 19:58:47 +0000149 }
Mark Whitley130005c2000-10-25 00:28:27 +0000150
151 if (u == l)
152 break;
153
154 if (j < 0)
155 u = i - 1;
156 else
157 l = i + 1;
158
159 if (u < l)
160 break;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000161 }
Mark Whitley130005c2000-10-25 00:28:27 +0000162
Eric Andersenb6106152000-06-19 17:25:40 +0000163 return(busybox_main(argc, argv));
Eric Andersencc8ed391999-10-05 16:24:54 +0000164}
165
166
167int busybox_main(int argc, char **argv)
168{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000169 int col = 0;
Eric Andersencc8ed391999-10-05 16:24:54 +0000170
Erik Andersene49d5ec2000-02-08 19:58:47 +0000171 argc--;
172 argv++;
Eric Andersencc8ed391999-10-05 16:24:54 +0000173
Erik Andersene49d5ec2000-02-08 19:58:47 +0000174 if (been_there_done_that == 1 || argc < 1) {
Erik Andersenbcd61772000-05-13 06:33:19 +0000175 const struct BB_applet *a = applets;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000176
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000177 fprintf(stderr, "%s\n\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000178 "Usage: busybox [function] [arguments]...\n"
179 " or: [function] [arguments]...\n\n"
John Beppub4f86062000-04-13 03:36:01 +0000180 "\tBusyBox is a multi-call binary that combines many common Unix\n"
181 "\tutilities into a single executable. Most people will create a\n"
182 "\tlink to busybox for each function they wish to use, and BusyBox\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000183 "\twill act like whatever it was invoked as.\n"
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000184 "\nCurrently defined functions:\n", full_version);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000185
186 while (a->name != 0) {
187 col +=
188 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
189 (a++)->name);
190 if (col > 60 && a->name != 0) {
191 fprintf(stderr, ",\n");
192 col = 0;
193 }
194 }
195 fprintf(stderr, "\n\n");
196 exit(-1);
Eric Andersencc8ed391999-10-05 16:24:54 +0000197 }
Eric Andersenb6106152000-06-19 17:25:40 +0000198 /* If we've already been here once, exit now */
199 been_there_done_that = 1;
200 return (main(argc, argv));
Eric Andersencc8ed391999-10-05 16:24:54 +0000201}
Erik Andersen029011b2000-03-04 21:19:32 +0000202
203/*
204Local Variables:
205c-file-style: "linux"
206c-basic-offset: 4
207tab-width: 4
208End:
209*/