blob: d356e4caea4924bca476ae9a65194a0d1dacb94c [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
Matt Kraaia0428ee2000-10-25 19:00:51 +000084static int applet_name_compare(const void *x, const void *y)
85{
86 const struct BB_applet *applet1 = x;
87 const struct BB_applet *applet2 = y;
88
89 return strcmp(applet1->name, applet2->name);
90}
Erik Andersen05df2392000-01-13 04:43:48 +000091
Eric Andersencc8ed391999-10-05 16:24:54 +000092int main(int argc, char **argv)
93{
Matt Kraaia0428ee2000-10-25 19:00:51 +000094 struct BB_applet search_applet, *applet;
Eric Andersen501c88b2000-07-28 15:14:45 +000095 const char *s;
Matt Kraaid537a952000-07-14 01:51:25 +000096 applet_name = "busybox";
Eric Andersencc8ed391999-10-05 16:24:54 +000097
John Beppu8f425db2000-06-27 04:50:02 +000098#ifdef BB_FEATURE_INSTALLER
John Beppu27b59242000-06-27 04:56:45 +000099 /*
100 * This style of argument parsing doesn't scale well
101 * in the event that busybox starts wanting more --options.
102 * If someone has a cleaner approach, by all means implement it.
103 */
John Beppu8f425db2000-06-27 04:50:02 +0000104 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
105 int use_symbolic_links = 0;
John Beppu7cdc76d2000-06-28 00:41:26 +0000106 int rc = 0;
107 char *busybox;
John Beppu8f425db2000-06-27 04:50:02 +0000108
John Beppu27b59242000-06-27 04:56:45 +0000109 /* to use symlinks, or not to use symlinks... */
John Beppu8f425db2000-06-27 04:50:02 +0000110 if (argc > 2) {
111 if ((strcmp(argv[2], "-s") == 0)) {
112 use_symbolic_links = 1;
113 }
114 }
John Beppu7cdc76d2000-06-28 00:41:26 +0000115
116 /* link */
117 busybox = busybox_fullpath();
118 if (busybox) {
119 install_links(busybox, use_symbolic_links);
120 free(busybox);
121 } else {
122 rc = 1;
123 }
124 return rc;
John Beppu8f425db2000-06-27 04:50:02 +0000125 }
126#endif /* BB_FEATURE_INSTALLER */
127
Matt Kraai77190082000-07-11 20:03:24 +0000128 for (s = applet_name = argv[0]; *s != '\0';) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000129 if (*s++ == '/')
Matt Kraai77190082000-07-11 20:03:24 +0000130 applet_name = s;
Eric Andersencc8ed391999-10-05 16:24:54 +0000131 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000132
Eric Andersen501c88b2000-07-28 15:14:45 +0000133 *argv = (char*)applet_name;
Erik Andersen029011b2000-03-04 21:19:32 +0000134
Eric Andersen5d41d602000-06-29 20:20:14 +0000135#ifdef BB_SH
136 /* Add in a special case hack -- whenever **argv == '-'
137 * (i.e. '-su' or '-sh') always invoke the shell */
Eric Andersenbf960f52000-07-21 21:32:12 +0000138 if (**argv == '-' && *(*argv+1)!= '-') {
Eric Andersen5d41d602000-06-29 20:20:14 +0000139 exit(((*(shell_main)) (argc, argv)));
Eric Andersenbf960f52000-07-21 21:32:12 +0000140 }
Eric Andersen5d41d602000-06-29 20:20:14 +0000141#endif
142
Mark Whitley130005c2000-10-25 00:28:27 +0000143 /* Do a binary search to find the applet entry given the name. */
Matt Kraaia0428ee2000-10-25 19:00:51 +0000144 search_applet.name = applet_name;
145 applet = bsearch(&search_applet, applets, NUM_APPLETS,
146 sizeof(struct BB_applet), applet_name_compare);
Matt Kraai2dab1742000-10-25 19:05:38 +0000147 if (applet != NULL) {
148 if (applet->usage && argv[1] && strcmp(argv[1], "--help") == 0)
149 usage(applet->usage);
Matt Kraaia0428ee2000-10-25 19:00:51 +0000150 exit((*(applet->main)) (argc, argv));
Matt Kraai2dab1742000-10-25 19:05:38 +0000151 }
Mark Whitley130005c2000-10-25 00:28:27 +0000152
Eric Andersenb6106152000-06-19 17:25:40 +0000153 return(busybox_main(argc, argv));
Eric Andersencc8ed391999-10-05 16:24:54 +0000154}
155
156
157int busybox_main(int argc, char **argv)
158{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000159 int col = 0;
Eric Andersencc8ed391999-10-05 16:24:54 +0000160
Erik Andersene49d5ec2000-02-08 19:58:47 +0000161 argc--;
162 argv++;
Eric Andersencc8ed391999-10-05 16:24:54 +0000163
Erik Andersene49d5ec2000-02-08 19:58:47 +0000164 if (been_there_done_that == 1 || argc < 1) {
Erik Andersenbcd61772000-05-13 06:33:19 +0000165 const struct BB_applet *a = applets;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000166
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000167 fprintf(stderr, "%s\n\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000168 "Usage: busybox [function] [arguments]...\n"
169 " or: [function] [arguments]...\n\n"
John Beppub4f86062000-04-13 03:36:01 +0000170 "\tBusyBox is a multi-call binary that combines many common Unix\n"
171 "\tutilities into a single executable. Most people will create a\n"
172 "\tlink to busybox for each function they wish to use, and BusyBox\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000173 "\twill act like whatever it was invoked as.\n"
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000174 "\nCurrently defined functions:\n", full_version);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000175
176 while (a->name != 0) {
177 col +=
178 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
179 (a++)->name);
180 if (col > 60 && a->name != 0) {
181 fprintf(stderr, ",\n");
182 col = 0;
183 }
184 }
185 fprintf(stderr, "\n\n");
186 exit(-1);
Eric Andersencc8ed391999-10-05 16:24:54 +0000187 }
Eric Andersenb6106152000-06-19 17:25:40 +0000188 /* If we've already been here once, exit now */
189 been_there_done_that = 1;
190 return (main(argc, argv));
Eric Andersencc8ed391999-10-05 16:24:54 +0000191}
Erik Andersen029011b2000-03-04 21:19:32 +0000192
193/*
194Local Variables:
195c-file-style: "linux"
196c-basic-offset: 4
197tab-width: 4
198End:
199*/