blob: 0439fb566cb5892d8abed2a1ff784d6750ddecac [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 Andersen8c725e62000-11-30 00:27:06 +00006
7#undef APPLET
8#undef APPLET_NOUSAGE
9#undef PROTOTYPES
Mark Whitley130005c2000-10-25 00:28:27 +000010#include "applets.h"
Eric Andersencc8ed391999-10-05 16:24:54 +000011
Pavel Roskin9c5fcc32000-07-17 23:45:12 +000012#define bb_need_full_version
13#define BB_DECLARE_EXTERN
14#include "messages.c"
15
Eric Andersencc8ed391999-10-05 16:24:54 +000016static int been_there_done_that = 0;
17
Eric Andersencc8ed391999-10-05 16:24:54 +000018
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
72 if (use_symbolic_links) Link = symlink;
73
John Beppueb028332000-06-28 00:55:31 +000074 for (i = 0; applets[i].name != NULL; i++) {
Eric Andersenc5949f62000-09-25 20:35:54 +000075 sprintf ( command, "%s/%s",
76 install_dir[applets[i].location],
77 applets[i].name);
78 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 Kraaia0428ee2000-10-25 19:00:51 +000090 struct BB_applet search_applet, *applet;
Eric Andersen501c88b2000-07-28 15:14:45 +000091 const char *s;
Matt Kraaid537a952000-07-14 01:51:25 +000092 applet_name = "busybox";
Eric Andersencc8ed391999-10-05 16:24:54 +000093
John Beppu8f425db2000-06-27 04:50:02 +000094#ifdef BB_FEATURE_INSTALLER
John Beppu27b59242000-06-27 04:56:45 +000095 /*
96 * This style of argument parsing doesn't scale well
97 * in the event that busybox starts wanting more --options.
98 * If someone has a cleaner approach, by all means implement it.
99 */
John Beppu8f425db2000-06-27 04:50:02 +0000100 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
101 int use_symbolic_links = 0;
John Beppu7cdc76d2000-06-28 00:41:26 +0000102 int rc = 0;
103 char *busybox;
John Beppu8f425db2000-06-27 04:50:02 +0000104
John Beppu27b59242000-06-27 04:56:45 +0000105 /* to use symlinks, or not to use symlinks... */
John Beppu8f425db2000-06-27 04:50:02 +0000106 if (argc > 2) {
107 if ((strcmp(argv[2], "-s") == 0)) {
108 use_symbolic_links = 1;
109 }
110 }
John Beppu7cdc76d2000-06-28 00:41:26 +0000111
112 /* link */
113 busybox = busybox_fullpath();
114 if (busybox) {
115 install_links(busybox, use_symbolic_links);
116 free(busybox);
117 } else {
118 rc = 1;
119 }
120 return rc;
John Beppu8f425db2000-06-27 04:50:02 +0000121 }
122#endif /* BB_FEATURE_INSTALLER */
123
Matt Kraai77190082000-07-11 20:03:24 +0000124 for (s = applet_name = argv[0]; *s != '\0';) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000125 if (*s++ == '/')
Matt Kraai77190082000-07-11 20:03:24 +0000126 applet_name = s;
Eric Andersencc8ed391999-10-05 16:24:54 +0000127 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000128
Eric Andersen5d41d602000-06-29 20:20:14 +0000129#ifdef BB_SH
130 /* Add in a special case hack -- whenever **argv == '-'
131 * (i.e. '-su' or '-sh') always invoke the shell */
Eric Andersenbf960f52000-07-21 21:32:12 +0000132 if (**argv == '-' && *(*argv+1)!= '-') {
Eric Andersen5d41d602000-06-29 20:20:14 +0000133 exit(((*(shell_main)) (argc, argv)));
Eric Andersenbf960f52000-07-21 21:32:12 +0000134 }
Eric Andersen5d41d602000-06-29 20:20:14 +0000135#endif
136
Mark Whitley130005c2000-10-25 00:28:27 +0000137 /* Do a binary search to find the applet entry given the name. */
Matt Kraaia0428ee2000-10-25 19:00:51 +0000138 search_applet.name = applet_name;
139 applet = bsearch(&search_applet, applets, NUM_APPLETS,
140 sizeof(struct BB_applet), applet_name_compare);
Matt Kraai2dab1742000-10-25 19:05:38 +0000141 if (applet != NULL) {
142 if (applet->usage && argv[1] && strcmp(argv[1], "--help") == 0)
143 usage(applet->usage);
Matt Kraaia0428ee2000-10-25 19:00:51 +0000144 exit((*(applet->main)) (argc, argv));
Matt Kraai2dab1742000-10-25 19:05:38 +0000145 }
Mark Whitley130005c2000-10-25 00:28:27 +0000146
Eric Andersenb6106152000-06-19 17:25:40 +0000147 return(busybox_main(argc, argv));
Eric Andersencc8ed391999-10-05 16:24:54 +0000148}
149
150
151int busybox_main(int argc, char **argv)
152{
Matt Kraai8abc78a2000-12-15 00:35:22 +0000153 int col = 0, len, i;
Eric Andersencc8ed391999-10-05 16:24:54 +0000154
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*/