blob: ab3762eb875d6565ade15630f80570cd9e265b29 [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>
Eric Andersened3ef502001-01-27 08:24:39 +00006#include <stdlib.h>
Eric Andersen8c725e62000-11-30 00:27:06 +00007
8#undef APPLET
9#undef APPLET_NOUSAGE
10#undef PROTOTYPES
Mark Whitley130005c2000-10-25 00:28:27 +000011#include "applets.h"
Eric Andersencc8ed391999-10-05 16:24:54 +000012
Pavel Roskin9c5fcc32000-07-17 23:45:12 +000013#define bb_need_full_version
14#define BB_DECLARE_EXTERN
15#include "messages.c"
16
Eric Andersencc8ed391999-10-05 16:24:54 +000017static int been_there_done_that = 0;
18
Eric Andersencc8ed391999-10-05 16:24:54 +000019
Eric Andersen501c88b2000-07-28 15:14:45 +000020const char *applet_name;
Erik Andersen05df2392000-01-13 04:43:48 +000021
John Beppu8f425db2000-06-27 04:50:02 +000022#ifdef BB_FEATURE_INSTALLER
23/*
24 * directory table
Eric Andersen3570a342000-09-25 21:45:58 +000025 * this should be consistent w/ the enum, busybox.h::Location,
John Beppueb028332000-06-28 00:55:31 +000026 * or else...
John Beppu8f425db2000-06-27 04:50:02 +000027 */
28static char* install_dir[] = {
John Beppueb028332000-06-28 00:55:31 +000029 "/",
30 "/bin",
31 "/sbin",
32 "/usr/bin",
33 "/usr/sbin",
John Beppu8f425db2000-06-27 04:50:02 +000034};
35
36/* abstract link() */
37typedef int (*__link_f)(const char *, const char *);
38
John Beppu7cdc76d2000-06-28 00:41:26 +000039/*
40 * Where in the filesystem is this busybox?
41 * [return]
42 * malloc'd string w/ full pathname of busybox's location
43 * NULL on failure
44 */
45static char *busybox_fullpath()
46{
John Beppueb028332000-06-28 00:55:31 +000047 pid_t pid;
48 char path[256];
49 char proc[256];
50 int len;
John Beppu7cdc76d2000-06-28 00:41:26 +000051
52 pid = getpid();
53 sprintf(proc, "/proc/%d/exe", pid);
54 len = readlink(proc, path, 256);
55 if (len != -1) {
56 path[len] = 0;
57 } else {
Matt Kraai1fa1ade2000-12-18 03:57:16 +000058 perror_msg("%s", proc);
John Beppu7cdc76d2000-06-28 00:41:26 +000059 return NULL;
60 }
61 return strdup(path);
62}
63
John Beppu8f425db2000-06-27 04:50:02 +000064/* create (sym)links for each applet */
Eric Andersenc5949f62000-09-25 20:35:54 +000065static void install_links(const char *busybox, int use_symbolic_links)
John Beppu8f425db2000-06-27 04:50:02 +000066{
John Beppueb028332000-06-28 00:55:31 +000067 __link_f Link = link;
John Beppu8f425db2000-06-27 04:50:02 +000068
John Beppueb028332000-06-28 00:55:31 +000069 char command[256];
70 int i;
Eric Andersenc5949f62000-09-25 20:35:54 +000071 int rc;
John Beppu8f425db2000-06-27 04:50:02 +000072
73 if (use_symbolic_links) Link = symlink;
74
John Beppueb028332000-06-28 00:55:31 +000075 for (i = 0; applets[i].name != NULL; i++) {
Eric Andersenc5949f62000-09-25 20:35:54 +000076 sprintf ( command, "%s/%s",
77 install_dir[applets[i].location],
78 applets[i].name);
79 rc = Link(busybox, command);
80
John Beppu8f425db2000-06-27 04:50:02 +000081 if (rc) {
Matt Kraai1fa1ade2000-12-18 03:57:16 +000082 perror_msg("%s", command);
John Beppu8f425db2000-06-27 04:50:02 +000083 }
John Beppueb028332000-06-28 00:55:31 +000084 }
John Beppu8f425db2000-06-27 04:50:02 +000085}
86
John Beppu8f425db2000-06-27 04:50:02 +000087#endif /* BB_FEATURE_INSTALLER */
88
Eric Andersencc8ed391999-10-05 16:24:54 +000089int main(int argc, char **argv)
90{
Matt Kraaia0428ee2000-10-25 19:00:51 +000091 struct BB_applet search_applet, *applet;
Eric Andersen501c88b2000-07-28 15:14:45 +000092 const char *s;
Eric Andersenf5d5e772001-01-24 23:34:48 +000093
94 for (s = applet_name = argv[0]; *s != '\0';) {
95 if (*s++ == '/')
96 applet_name = s;
97 }
98
99#ifdef BB_SH
100 /* Add in a special case hack -- whenever **argv == '-'
101 * (i.e. '-su' or '-sh') always invoke the shell */
102 if (**argv == '-' && *(*argv+1)!= '-') {
103 exit(((*(shell_main)) (argc, argv)));
104 }
105#endif
106
107 /* Do a binary search to find the applet entry given the name. */
108 search_applet.name = applet_name;
109 applet = bsearch(&search_applet, applets, NUM_APPLETS,
110 sizeof(struct BB_applet), applet_name_compare);
111 if (applet != NULL) {
112 if (applet->usage && argv[1] && strcmp(argv[1], "--help") == 0)
113 usage(applet->usage);
114 exit((*(applet->main)) (argc, argv));
115 }
116
117 error_msg_and_die("applet not found\n");
118}
119
120
121int busybox_main(int argc, char **argv)
122{
123 int col = 0, len, i;
Eric Andersencc8ed391999-10-05 16:24:54 +0000124
John Beppu8f425db2000-06-27 04:50:02 +0000125#ifdef BB_FEATURE_INSTALLER
John Beppu27b59242000-06-27 04:56:45 +0000126 /*
127 * This style of argument parsing doesn't scale well
128 * in the event that busybox starts wanting more --options.
129 * If someone has a cleaner approach, by all means implement it.
130 */
John Beppu8f425db2000-06-27 04:50:02 +0000131 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
132 int use_symbolic_links = 0;
John Beppu7cdc76d2000-06-28 00:41:26 +0000133 int rc = 0;
134 char *busybox;
John Beppu8f425db2000-06-27 04:50:02 +0000135
John Beppu27b59242000-06-27 04:56:45 +0000136 /* to use symlinks, or not to use symlinks... */
John Beppu8f425db2000-06-27 04:50:02 +0000137 if (argc > 2) {
138 if ((strcmp(argv[2], "-s") == 0)) {
139 use_symbolic_links = 1;
140 }
141 }
John Beppu7cdc76d2000-06-28 00:41:26 +0000142
143 /* link */
144 busybox = busybox_fullpath();
145 if (busybox) {
146 install_links(busybox, use_symbolic_links);
147 free(busybox);
148 } else {
149 rc = 1;
150 }
151 return rc;
John Beppu8f425db2000-06-27 04:50:02 +0000152 }
153#endif /* BB_FEATURE_INSTALLER */
154
Erik Andersene49d5ec2000-02-08 19:58:47 +0000155 argc--;
Eric Andersencc8ed391999-10-05 16:24:54 +0000156
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000157 /* If we've already been here once, exit now */
Erik Andersene49d5ec2000-02-08 19:58:47 +0000158 if (been_there_done_that == 1 || argc < 1) {
Erik Andersenbcd61772000-05-13 06:33:19 +0000159 const struct BB_applet *a = applets;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000160
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000161 fprintf(stderr, "%s\n\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000162 "Usage: busybox [function] [arguments]...\n"
163 " or: [function] [arguments]...\n\n"
John Beppub4f86062000-04-13 03:36:01 +0000164 "\tBusyBox is a multi-call binary that combines many common Unix\n"
165 "\tutilities into a single executable. Most people will create a\n"
166 "\tlink to busybox for each function they wish to use, and BusyBox\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000167 "\twill act like whatever it was invoked as.\n"
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000168 "\nCurrently defined functions:\n", full_version);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000169
170 while (a->name != 0) {
171 col +=
172 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
173 (a++)->name);
174 if (col > 60 && a->name != 0) {
175 fprintf(stderr, ",\n");
176 col = 0;
177 }
178 }
179 fprintf(stderr, "\n\n");
180 exit(-1);
Eric Andersencc8ed391999-10-05 16:24:54 +0000181 }
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000182
183 /* Flag that we've been here already */
Eric Andersenb6106152000-06-19 17:25:40 +0000184 been_there_done_that = 1;
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000185
Matt Kraai8abc78a2000-12-15 00:35:22 +0000186 /* Move the command line down a notch */
187 len = argv[argc] + strlen(argv[argc]) - argv[1];
188 memmove(argv[0], argv[1], len);
189 memset(argv[0] + len, 0, argv[1] - argv[0]);
190
191 /* Fix up the argv pointers */
192 len = argv[1] - argv[0];
193 memmove(argv, argv+1, sizeof(char *) * (argc + 1));
194 for (i = 0; i < argc; i++)
195 argv[i] -= len;
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000196
Eric Andersenb6106152000-06-19 17:25:40 +0000197 return (main(argc, argv));
Eric Andersencc8ed391999-10-05 16:24:54 +0000198}
Erik Andersen029011b2000-03-04 21:19:32 +0000199
200/*
201Local Variables:
202c-file-style: "linux"
203c-basic-offset: 4
204tab-width: 4
205End:
206*/