blob: 6c1070fc866b936d47342de81cae6417e8806bbc [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>
Eric Andersen90ca2842001-01-27 08:32:57 +00005#include <unistd.h>
Eric Andersencc8ed391999-10-05 16:24:54 +00006#include <errno.h>
Eric Andersened3ef502001-01-27 08:24:39 +00007#include <stdlib.h>
Eric Andersen8c725e62000-11-30 00:27:06 +00008
9#undef APPLET
10#undef APPLET_NOUSAGE
11#undef PROTOTYPES
Mark Whitley130005c2000-10-25 00:28:27 +000012#include "applets.h"
Eric Andersencc8ed391999-10-05 16:24:54 +000013
Pavel Roskin9c5fcc32000-07-17 23:45:12 +000014#define bb_need_full_version
15#define BB_DECLARE_EXTERN
16#include "messages.c"
17
Eric Andersencc8ed391999-10-05 16:24:54 +000018static int been_there_done_that = 0;
Eric Andersen501c88b2000-07-28 15:14:45 +000019const char *applet_name;
Erik Andersen05df2392000-01-13 04:43:48 +000020
John Beppu8f425db2000-06-27 04:50:02 +000021#ifdef BB_FEATURE_INSTALLER
22/*
23 * directory table
Eric Andersen3570a342000-09-25 21:45:58 +000024 * this should be consistent w/ the enum, busybox.h::Location,
John Beppueb028332000-06-28 00:55:31 +000025 * or else...
John Beppu8f425db2000-06-27 04:50:02 +000026 */
27static char* install_dir[] = {
John Beppueb028332000-06-28 00:55:31 +000028 "/",
29 "/bin",
30 "/sbin",
31 "/usr/bin",
32 "/usr/sbin",
John Beppu8f425db2000-06-27 04:50:02 +000033};
34
35/* abstract link() */
36typedef int (*__link_f)(const char *, const char *);
37
John Beppu7cdc76d2000-06-28 00:41:26 +000038/*
39 * Where in the filesystem is this busybox?
40 * [return]
41 * malloc'd string w/ full pathname of busybox's location
42 * NULL on failure
43 */
44static char *busybox_fullpath()
45{
John Beppueb028332000-06-28 00:55:31 +000046 pid_t pid;
47 char path[256];
48 char proc[256];
49 int len;
John Beppu7cdc76d2000-06-28 00:41:26 +000050
51 pid = getpid();
52 sprintf(proc, "/proc/%d/exe", pid);
53 len = readlink(proc, path, 256);
54 if (len != -1) {
55 path[len] = 0;
56 } else {
Matt Kraai1fa1ade2000-12-18 03:57:16 +000057 perror_msg("%s", proc);
John Beppu7cdc76d2000-06-28 00:41:26 +000058 return NULL;
59 }
60 return strdup(path);
61}
62
John Beppu8f425db2000-06-27 04:50:02 +000063/* create (sym)links for each applet */
Eric Andersenc5949f62000-09-25 20:35:54 +000064static void install_links(const char *busybox, int use_symbolic_links)
John Beppu8f425db2000-06-27 04:50:02 +000065{
John Beppueb028332000-06-28 00:55:31 +000066 __link_f Link = link;
John Beppu8f425db2000-06-27 04:50:02 +000067
John Beppueb028332000-06-28 00:55:31 +000068 char command[256];
69 int i;
Eric Andersenc5949f62000-09-25 20:35:54 +000070 int rc;
John Beppu8f425db2000-06-27 04:50:02 +000071
Eric Andersen90ca2842001-01-27 08:32:57 +000072 if (use_symbolic_links)
73 Link = symlink;
John Beppu8f425db2000-06-27 04:50:02 +000074
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",
Eric Andersen90ca2842001-01-27 08:32:57 +000077 install_dir[applets[i].location], applets[i].name);
Eric Andersenc5949f62000-09-25 20:35:54 +000078 rc = Link(busybox, command);
79
John Beppu8f425db2000-06-27 04:50:02 +000080 if (rc) {
Matt Kraai1fa1ade2000-12-18 03:57:16 +000081 perror_msg("%s", command);
John Beppu8f425db2000-06-27 04:50:02 +000082 }
John Beppueb028332000-06-28 00:55:31 +000083 }
John Beppu8f425db2000-06-27 04:50:02 +000084}
85
John Beppu8f425db2000-06-27 04:50:02 +000086#endif /* BB_FEATURE_INSTALLER */
87
Eric Andersencc8ed391999-10-05 16:24:54 +000088int main(int argc, char **argv)
89{
Matt Kraaif2cc2762001-02-01 19:21:20 +000090 const char *s;
Eric Andersenf5d5e772001-01-24 23:34:48 +000091
92 for (s = applet_name = argv[0]; *s != '\0';) {
93 if (*s++ == '/')
94 applet_name = s;
95 }
96
97#ifdef BB_SH
98 /* Add in a special case hack -- whenever **argv == '-'
99 * (i.e. '-su' or '-sh') always invoke the shell */
100 if (**argv == '-' && *(*argv+1)!= '-') {
101 exit(((*(shell_main)) (argc, argv)));
102 }
103#endif
104
Eric Andersen67991cf2001-02-14 21:23:06 +0000105 run_applet_by_name(applet_name, argc, argv);
Matt Kraaidd19c692001-01-31 19:00:21 +0000106 error_msg_and_die("applet not found");
Eric Andersenf5d5e772001-01-24 23:34:48 +0000107}
108
109
110int busybox_main(int argc, char **argv)
111{
112 int col = 0, len, i;
Eric Andersencc8ed391999-10-05 16:24:54 +0000113
John Beppu8f425db2000-06-27 04:50:02 +0000114#ifdef BB_FEATURE_INSTALLER
John Beppu27b59242000-06-27 04:56:45 +0000115 /*
116 * This style of argument parsing doesn't scale well
117 * in the event that busybox starts wanting more --options.
118 * If someone has a cleaner approach, by all means implement it.
119 */
John Beppu8f425db2000-06-27 04:50:02 +0000120 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
121 int use_symbolic_links = 0;
John Beppu7cdc76d2000-06-28 00:41:26 +0000122 int rc = 0;
123 char *busybox;
John Beppu8f425db2000-06-27 04:50:02 +0000124
John Beppu27b59242000-06-27 04:56:45 +0000125 /* to use symlinks, or not to use symlinks... */
John Beppu8f425db2000-06-27 04:50:02 +0000126 if (argc > 2) {
127 if ((strcmp(argv[2], "-s") == 0)) {
128 use_symbolic_links = 1;
129 }
130 }
John Beppu7cdc76d2000-06-28 00:41:26 +0000131
132 /* link */
133 busybox = busybox_fullpath();
134 if (busybox) {
135 install_links(busybox, use_symbolic_links);
136 free(busybox);
137 } else {
138 rc = 1;
139 }
140 return rc;
John Beppu8f425db2000-06-27 04:50:02 +0000141 }
142#endif /* BB_FEATURE_INSTALLER */
143
Erik Andersene49d5ec2000-02-08 19:58:47 +0000144 argc--;
Eric Andersencc8ed391999-10-05 16:24:54 +0000145
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000146 /* If we've already been here once, exit now */
Erik Andersene49d5ec2000-02-08 19:58:47 +0000147 if (been_there_done_that == 1 || argc < 1) {
Erik Andersenbcd61772000-05-13 06:33:19 +0000148 const struct BB_applet *a = applets;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000149
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000150 fprintf(stderr, "%s\n\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000151 "Usage: busybox [function] [arguments]...\n"
152 " or: [function] [arguments]...\n\n"
John Beppub4f86062000-04-13 03:36:01 +0000153 "\tBusyBox is a multi-call binary that combines many common Unix\n"
154 "\tutilities into a single executable. Most people will create a\n"
155 "\tlink to busybox for each function they wish to use, and BusyBox\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000156 "\twill act like whatever it was invoked as.\n"
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000157 "\nCurrently defined functions:\n", full_version);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000158
159 while (a->name != 0) {
160 col +=
161 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
162 (a++)->name);
163 if (col > 60 && a->name != 0) {
164 fprintf(stderr, ",\n");
165 col = 0;
166 }
167 }
168 fprintf(stderr, "\n\n");
169 exit(-1);
Eric Andersencc8ed391999-10-05 16:24:54 +0000170 }
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000171
172 /* Flag that we've been here already */
Eric Andersenb6106152000-06-19 17:25:40 +0000173 been_there_done_that = 1;
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000174
Matt Kraai8abc78a2000-12-15 00:35:22 +0000175 /* Move the command line down a notch */
176 len = argv[argc] + strlen(argv[argc]) - argv[1];
177 memmove(argv[0], argv[1], len);
178 memset(argv[0] + len, 0, argv[1] - argv[0]);
179
180 /* Fix up the argv pointers */
181 len = argv[1] - argv[0];
Eric Andersen90ca2842001-01-27 08:32:57 +0000182 memmove(argv, argv + 1, sizeof(char *) * (argc + 1));
Matt Kraai8abc78a2000-12-15 00:35:22 +0000183 for (i = 0; i < argc; i++)
184 argv[i] -= len;
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000185
Eric Andersenb6106152000-06-19 17:25:40 +0000186 return (main(argc, argv));
Eric Andersencc8ed391999-10-05 16:24:54 +0000187}
Erik Andersen029011b2000-03-04 21:19:32 +0000188
189/*
190Local Variables:
191c-file-style: "linux"
192c-basic-offset: 4
193tab-width: 4
194End:
195*/