blob: 7a220f7b04dc96c0c6c3ff864c85b3bb07ac3dff [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersencc8ed391999-10-05 16:24:54 +00002#include <stdio.h>
3#include <string.h>
Eric Andersen90ca2842001-01-27 08:32:57 +00004#include <unistd.h>
Eric Andersencc8ed391999-10-05 16:24:54 +00005#include <errno.h>
Eric Andersened3ef502001-01-27 08:24:39 +00006#include <stdlib.h>
Eric Andersencbe31da2001-02-20 06:14:08 +00007#include "busybox.h"
Eric Andersene5dfced2001-04-09 22:48:12 +00008#ifdef BB_LOCALE_SUPPORT
9#include <locale.h>
10#endif
11
Eric Andersen0f0c0b42001-04-03 17:05:01 +000012int been_there_done_that = 0; /* Also used in applets.c */
Eric Andersen501c88b2000-07-28 15:14:45 +000013const char *applet_name;
Erik Andersen05df2392000-01-13 04:43:48 +000014
John Beppu8f425db2000-06-27 04:50:02 +000015#ifdef BB_FEATURE_INSTALLER
16/*
17 * directory table
Eric Andersen3570a342000-09-25 21:45:58 +000018 * this should be consistent w/ the enum, busybox.h::Location,
John Beppueb028332000-06-28 00:55:31 +000019 * or else...
John Beppu8f425db2000-06-27 04:50:02 +000020 */
21static char* install_dir[] = {
John Beppueb028332000-06-28 00:55:31 +000022 "/",
23 "/bin",
24 "/sbin",
25 "/usr/bin",
26 "/usr/sbin",
John Beppu8f425db2000-06-27 04:50:02 +000027};
28
29/* abstract link() */
30typedef int (*__link_f)(const char *, const char *);
31
John Beppu7cdc76d2000-06-28 00:41:26 +000032/*
33 * Where in the filesystem is this busybox?
34 * [return]
35 * malloc'd string w/ full pathname of busybox's location
36 * NULL on failure
37 */
38static char *busybox_fullpath()
39{
Eric Andersen28355a32001-05-07 17:48:28 +000040 return xreadlink("/proc/self/exe");
John Beppu7cdc76d2000-06-28 00:41:26 +000041}
42
John Beppu8f425db2000-06-27 04:50:02 +000043/* create (sym)links for each applet */
Eric Andersenc5949f62000-09-25 20:35:54 +000044static void install_links(const char *busybox, int use_symbolic_links)
John Beppu8f425db2000-06-27 04:50:02 +000045{
John Beppueb028332000-06-28 00:55:31 +000046 __link_f Link = link;
John Beppu8f425db2000-06-27 04:50:02 +000047
Eric Andersene5dfced2001-04-09 22:48:12 +000048 char *fpc;
John Beppueb028332000-06-28 00:55:31 +000049 int i;
Eric Andersenc5949f62000-09-25 20:35:54 +000050 int rc;
John Beppu8f425db2000-06-27 04:50:02 +000051
Eric Andersen90ca2842001-01-27 08:32:57 +000052 if (use_symbolic_links)
53 Link = symlink;
John Beppu8f425db2000-06-27 04:50:02 +000054
John Beppueb028332000-06-28 00:55:31 +000055 for (i = 0; applets[i].name != NULL; i++) {
Eric Andersene5dfced2001-04-09 22:48:12 +000056 fpc = concat_path_file(
57 install_dir[applets[i].location], applets[i].name);
58 rc = Link(busybox, fpc);
59 if (rc!=0 && errno!=EEXIST) {
60 perror_msg("%s", fpc);
John Beppu8f425db2000-06-27 04:50:02 +000061 }
Eric Andersene5dfced2001-04-09 22:48:12 +000062 free(fpc);
John Beppueb028332000-06-28 00:55:31 +000063 }
John Beppu8f425db2000-06-27 04:50:02 +000064}
65
John Beppu8f425db2000-06-27 04:50:02 +000066#endif /* BB_FEATURE_INSTALLER */
67
Eric Andersencc8ed391999-10-05 16:24:54 +000068int main(int argc, char **argv)
69{
Matt Kraaif2cc2762001-02-01 19:21:20 +000070 const char *s;
Eric Andersenf5d5e772001-01-24 23:34:48 +000071
72 for (s = applet_name = argv[0]; *s != '\0';) {
73 if (*s++ == '/')
74 applet_name = s;
75 }
76
Eric Andersenfa2661f2001-06-21 04:56:24 +000077 /* Add in a special case hack for a leading hyphen */
Eric Andersenf5d5e772001-01-24 23:34:48 +000078 if (**argv == '-' && *(*argv+1)!= '-') {
Eric Andersenfa2661f2001-06-21 04:56:24 +000079 applet_name = (*argv+1);
Eric Andersenf5d5e772001-01-24 23:34:48 +000080 }
Eric Andersenf5d5e772001-01-24 23:34:48 +000081
Eric Andersen4819c3d2001-05-13 00:33:16 +000082#ifdef BB_LOCALE_SUPPORT
83#ifdef BB_INIT
Eric Andersene5dfced2001-04-09 22:48:12 +000084 if(getpid()!=1) /* Do not set locale for `init' */
Eric Andersen4819c3d2001-05-13 00:33:16 +000085#endif
86 {
Eric Andersene5dfced2001-04-09 22:48:12 +000087 setlocale(LC_ALL, "");
Eric Andersen4819c3d2001-05-13 00:33:16 +000088 }
Eric Andersene5dfced2001-04-09 22:48:12 +000089#endif
90
Eric Andersen67991cf2001-02-14 21:23:06 +000091 run_applet_by_name(applet_name, argc, argv);
Matt Kraaidd19c692001-01-31 19:00:21 +000092 error_msg_and_die("applet not found");
Eric Andersenf5d5e772001-01-24 23:34:48 +000093}
94
95
96int busybox_main(int argc, char **argv)
97{
98 int col = 0, len, i;
Eric Andersencc8ed391999-10-05 16:24:54 +000099
John Beppu8f425db2000-06-27 04:50:02 +0000100#ifdef BB_FEATURE_INSTALLER
John Beppu27b59242000-06-27 04:56:45 +0000101 /*
102 * This style of argument parsing doesn't scale well
103 * in the event that busybox starts wanting more --options.
104 * If someone has a cleaner approach, by all means implement it.
105 */
John Beppu8f425db2000-06-27 04:50:02 +0000106 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
107 int use_symbolic_links = 0;
John Beppu7cdc76d2000-06-28 00:41:26 +0000108 int rc = 0;
109 char *busybox;
John Beppu8f425db2000-06-27 04:50:02 +0000110
John Beppu27b59242000-06-27 04:56:45 +0000111 /* to use symlinks, or not to use symlinks... */
John Beppu8f425db2000-06-27 04:50:02 +0000112 if (argc > 2) {
113 if ((strcmp(argv[2], "-s") == 0)) {
114 use_symbolic_links = 1;
115 }
116 }
John Beppu7cdc76d2000-06-28 00:41:26 +0000117
118 /* link */
119 busybox = busybox_fullpath();
120 if (busybox) {
121 install_links(busybox, use_symbolic_links);
122 free(busybox);
123 } else {
124 rc = 1;
125 }
126 return rc;
John Beppu8f425db2000-06-27 04:50:02 +0000127 }
128#endif /* BB_FEATURE_INSTALLER */
129
Erik Andersene49d5ec2000-02-08 19:58:47 +0000130 argc--;
Eric Andersencc8ed391999-10-05 16:24:54 +0000131
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000132 /* If we've already been here once, exit now */
Erik Andersene49d5ec2000-02-08 19:58:47 +0000133 if (been_there_done_that == 1 || argc < 1) {
Erik Andersenbcd61772000-05-13 06:33:19 +0000134 const struct BB_applet *a = applets;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000135
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000136 fprintf(stderr, "%s\n\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000137 "Usage: busybox [function] [arguments]...\n"
138 " or: [function] [arguments]...\n\n"
John Beppub4f86062000-04-13 03:36:01 +0000139 "\tBusyBox is a multi-call binary that combines many common Unix\n"
140 "\tutilities into a single executable. Most people will create a\n"
141 "\tlink to busybox for each function they wish to use, and BusyBox\n"
Erik Andersen330fd2b2000-05-19 05:35:19 +0000142 "\twill act like whatever it was invoked as.\n"
Pavel Roskin9c5fcc32000-07-17 23:45:12 +0000143 "\nCurrently defined functions:\n", full_version);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000144
145 while (a->name != 0) {
146 col +=
147 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
148 (a++)->name);
149 if (col > 60 && a->name != 0) {
150 fprintf(stderr, ",\n");
151 col = 0;
152 }
153 }
154 fprintf(stderr, "\n\n");
Mark Whitley01677182001-03-02 17:47:17 +0000155 exit(0);
Eric Andersencc8ed391999-10-05 16:24:54 +0000156 }
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000157
158 /* Flag that we've been here already */
Eric Andersenb6106152000-06-19 17:25:40 +0000159 been_there_done_that = 1;
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000160
Matt Kraai8abc78a2000-12-15 00:35:22 +0000161 /* Move the command line down a notch */
162 len = argv[argc] + strlen(argv[argc]) - argv[1];
163 memmove(argv[0], argv[1], len);
164 memset(argv[0] + len, 0, argv[1] - argv[0]);
165
166 /* Fix up the argv pointers */
167 len = argv[1] - argv[0];
Eric Andersen90ca2842001-01-27 08:32:57 +0000168 memmove(argv, argv + 1, sizeof(char *) * (argc + 1));
Matt Kraai8abc78a2000-12-15 00:35:22 +0000169 for (i = 0; i < argc; i++)
170 argv[i] -= len;
Eric Andersen5e09b6e2000-12-08 19:03:12 +0000171
Eric Andersenb6106152000-06-19 17:25:40 +0000172 return (main(argc, argv));
Eric Andersencc8ed391999-10-05 16:24:54 +0000173}
Erik Andersen029011b2000-03-04 21:19:32 +0000174
175/*
176Local Variables:
177c-file-style: "linux"
178c-basic-offset: 4
179tab-width: 4
180End:
181*/