blob: 8f27dfb8eace2121ff20e40235f1624423cf8b4c [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 {
Mark Whitleyf57c9442000-12-07 19:56:48 +000057 error_msg("%s: %s\n", proc, strerror(errno));
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) {
Mark Whitleyf57c9442000-12-07 19:56:48 +000081 error_msg("%s: %s\n", command, strerror(errno));
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{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000153 int col = 0;
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000154 int ps_index;
155 char *index, *index2;
Eric Andersencc8ed391999-10-05 16:24:54 +0000156
Erik Andersene49d5ec2000-02-08 19:58:47 +0000157 argc--;
Eric Andersencc8ed391999-10-05 16:24:54 +0000158
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000159 /* If we've already been here once, exit now */
Erik Andersene49d5ec2000-02-08 19:58:47 +0000160 if (been_there_done_that == 1 || argc < 1) {
Erik Andersenbcd61772000-05-13 06:33:19 +0000161 const struct BB_applet *a = applets;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000162
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000163 fprintf(stderr, "%s\n\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000164 "Usage: busybox [function] [arguments]...\n"
165 " or: [function] [arguments]...\n\n"
John Beppub4f86062000-04-13 03:36:01 +0000166 "\tBusyBox is a multi-call binary that combines many common Unix\n"
167 "\tutilities into a single executable. Most people will create a\n"
168 "\tlink to busybox for each function they wish to use, and BusyBox\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000169 "\twill act like whatever it was invoked as.\n"
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000170 "\nCurrently defined functions:\n", full_version);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000171
172 while (a->name != 0) {
173 col +=
174 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
175 (a++)->name);
176 if (col > 60 && a->name != 0) {
177 fprintf(stderr, ",\n");
178 col = 0;
179 }
180 }
181 fprintf(stderr, "\n\n");
182 exit(-1);
Eric Andersencc8ed391999-10-05 16:24:54 +0000183 }
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000184
185 /* Flag that we've been here already */
Eric Andersenb6106152000-06-19 17:25:40 +0000186 been_there_done_that = 1;
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000187
188 /* We do not want the word "busybox" to show up in ps, so we move
189 * everything in argv around to fake ps into showing what we want it to
190 * show. Since we are only shrinking the string, we don't need to move
191 * __environ or any of that tedious stuff... */
192 ps_index = 0;
193 index=*argv;
194 index2=argv[argc];
195 index2+=strlen(argv[argc]);
196 while(ps_index < argc) {
197 argv[ps_index]=index;
198 memmove(index, argv[ps_index+1], strlen(argv[ps_index+1])+1);
199 index+=(strlen(index));
200 *index='\0';
201 index++;
202 ps_index++;
203 }
204 while(index<=index2)
205 *index++='\0';
Eric Andersen8c28fd72000-12-09 00:19:30 +0000206 argv[ps_index]=NULL;
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000207
Eric Andersenb6106152000-06-19 17:25:40 +0000208 return (main(argc, argv));
Eric Andersencc8ed391999-10-05 16:24:54 +0000209}
Erik Andersen029011b2000-03-04 21:19:32 +0000210
211/*
212Local Variables:
213c-file-style: "linux"
214c-basic-offset: 4
215tab-width: 4
216End:
217*/