997c155142a14a45ae90c7615b11284bbdc533bf
[oweals/busybox.git] / busybox.c
1 /* vi: set sw=4 ts=4: */
2 #include <stdio.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <errno.h>
6 #include <stdlib.h>
7 #include "busybox.h"
8 #ifdef CONFIG_LOCALE_SUPPORT
9 #include <locale.h>
10 #endif
11
12 int been_there_done_that = 0; /* Also used in applets.c */
13 const char *bb_applet_name;
14
15 #ifdef CONFIG_FEATURE_INSTALLER
16 /* 
17  * directory table
18  *              this should be consistent w/ the enum, busybox.h::Location,
19  *              or else...
20  */
21 static const char usr_bin [] ="/usr/bin";
22 static const char usr_sbin[] ="/usr/sbin";
23
24 static const char* const install_dir[] = {
25         &usr_bin [8], /* "", equivalent to "/" for concat_path_file() */
26         &usr_bin [4], /* "/bin" */
27         &usr_sbin[4], /* "/sbin" */
28         usr_bin,
29         usr_sbin
30 };
31
32 /* abstract link() */
33 typedef int (*__link_f)(const char *, const char *);
34
35 /* 
36  * Where in the filesystem is this busybox?
37  * [return]
38  *              malloc'd string w/ full pathname of busybox's location
39  *              NULL on failure
40  */
41 static inline char *busybox_fullpath(void)
42 {
43         return xreadlink("/proc/self/exe");
44 }
45
46 /* create (sym)links for each applet */
47 static void install_links(const char *busybox, int use_symbolic_links)
48 {
49         __link_f Link = link;
50
51         char *fpc;
52         int i;
53         int rc;
54
55         if (use_symbolic_links) 
56                 Link = symlink;
57
58         for (i = 0; applets[i].name != NULL; i++) {
59                 fpc = concat_path_file(
60                         install_dir[applets[i].location], applets[i].name);
61                 rc = Link(busybox, fpc);
62                 if (rc!=0 && errno!=EEXIST) {
63                         bb_perror_msg("%s", fpc);
64                 }
65                 free(fpc);
66         }
67 }
68
69 #endif /* CONFIG_FEATURE_INSTALLER */
70
71 int main(int argc, char **argv)
72 {
73         const char *s;
74
75         bb_applet_name = argv[0];
76
77         if (bb_applet_name[0] == '-')
78                 bb_applet_name++;
79
80         for (s = bb_applet_name; *s != '\0';) {
81                 if (*s++ == '/')
82                         bb_applet_name = s;
83         }
84
85 #ifdef CONFIG_LOCALE_SUPPORT 
86 #ifdef CONFIG_INIT
87         if(getpid()!=1) /* Do not set locale for `init' */
88 #endif
89         {
90                 setlocale(LC_ALL, "");
91         }
92 #endif
93
94         run_applet_by_name(bb_applet_name, argc, argv);
95         bb_error_msg_and_die("applet not found");
96 }
97
98
99 int busybox_main(int argc, char **argv)
100 {
101         int col = 0, len, i;
102
103 #ifdef CONFIG_FEATURE_INSTALLER 
104         /* 
105          * This style of argument parsing doesn't scale well 
106          * in the event that busybox starts wanting more --options.
107          * If someone has a cleaner approach, by all means implement it.
108          */
109         if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
110                 int use_symbolic_links = 0;
111                 int rc = 0;
112                 char *busybox;
113
114                 /* to use symlinks, or not to use symlinks... */
115                 if (argc > 2) {
116                         if ((strcmp(argv[2], "-s") == 0)) { 
117                                 use_symbolic_links = 1; 
118                         }
119                 }
120
121                 /* link */
122                 busybox = busybox_fullpath();
123                 if (busybox) {
124                         install_links(busybox, use_symbolic_links);
125                         free(busybox);
126                 } else {
127                         rc = 1;
128                 }
129                 return rc;
130         }
131 #endif /* CONFIG_FEATURE_INSTALLER */
132
133         argc--;
134
135         /* If we've already been here once, exit now */
136         if (been_there_done_that == 1 || argc < 1) {
137                 const struct BB_applet *a = applets;
138
139                 fprintf(stderr, "%s\n\n"
140                                 "Usage: busybox [function] [arguments]...\n"
141                                 "   or: [function] [arguments]...\n\n"
142                                 "\tBusyBox is a multi-call binary that combines many common Unix\n"
143                                 "\tutilities into a single executable.  Most people will create a\n"
144                                 "\tlink to busybox for each function they wish to use, and BusyBox\n"
145                                 "\twill act like whatever it was invoked as.\n" 
146                                 "\nCurrently defined functions:\n", bb_msg_full_version);
147
148                 while (a->name != 0) {
149                         col +=
150                                 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
151                                                 (a++)->name);
152                         if (col > 60 && a->name != 0) {
153                                 fprintf(stderr, ",\n");
154                                 col = 0;
155                         }
156                 }
157                 fprintf(stderr, "\n\n");
158                 exit(0);
159         }
160
161         /* Flag that we've been here already */
162         been_there_done_that = 1;
163
164         /* Move the command line down a notch */
165         /* Preserve pointers so setproctitle() works consistently */
166         len = argv[argc] + strlen(argv[argc]) - argv[1];
167         memmove(argv[0], argv[1], len);
168         memset(argv[0] + len, 0, argv[1] - argv[0]);
169
170         /* Fix up the argv pointers */
171         len = argv[1] - argv[0];
172         memmove(argv, argv + 1, sizeof(char *) * (argc + 1));
173         for (i = 0; i < argc; i++)
174                 argv[i] -= len;
175
176         return (main(argc, argv));
177 }
178
179 /*
180 Local Variables:
181 c-file-style: "linux"
182 c-basic-offset: 4
183 tab-width: 4
184 End:
185 */