ee745e73e1753e98f560f199241a507e31e07706
[oweals/busybox.git] / applets / busybox.c
1 /* vi: set sw=4 ts=4: */
2 #include "internal.h"
3 #include <stdio.h>
4 #include <string.h>
5 #include <errno.h>
6
7 static int been_there_done_that = 0;
8
9 /* It has been alledged that doing such things can
10  * help reduce binary size when staticly linking,
11  * of course with glibc, this is unlikely as long
12  * as we use things like printf -- perhaps a printf
13  * replacement may be in order 
14  */
15 #if 0
16 void exit(int status) __attribute__ ((noreturn));
17 void exit(int status)
18 {
19         _exit(status);
20 };
21 void abort(void) __attribute__ ((__noreturn__));
22 void abort(void)
23 {
24         _exit(0);
25 };
26 int atexit(void (*__func) (void))
27 {
28         _exit(0);
29 };
30 void *__libc_stack_end;
31 #endif
32
33 static const struct Applet applets[] = {
34
35 #ifdef BB_BASENAME                              //usr/bin/basename
36         {"basename", basename_main, _BB_DIR_USR_BIN},
37 #endif
38 #ifdef BB_BUSYBOX                               //bin
39         {"busybox", busybox_main, _BB_DIR_BIN},
40 #endif
41 #ifdef BB_BLOCK_DEVICE                  //sbin
42         {"block_device", block_device_main, _BB_DIR_SBIN},
43 #endif
44 #ifdef BB_CAT                                   //bin
45         {"cat", cat_main, _BB_DIR_BIN},
46 #endif
47 #ifdef BB_CHMOD_CHOWN_CHGRP             //bin
48         {"chmod", chmod_chown_chgrp_main, _BB_DIR_BIN},
49 #endif
50 #ifdef BB_CHMOD_CHOWN_CHGRP             //bin
51         {"chown", chmod_chown_chgrp_main, _BB_DIR_BIN},
52 #endif
53 #ifdef BB_CHMOD_CHOWN_CHGRP             //bin
54         {"chgrp", chmod_chown_chgrp_main, _BB_DIR_BIN},
55 #endif
56 #ifdef BB_CHROOT                                //sbin
57         {"chroot", chroot_main, _BB_DIR_SBIN},
58 #endif
59 #ifdef BB_CLEAR                                 //usr/bin
60         {"clear", clear_main, _BB_DIR_USR_BIN},
61 #endif
62 #ifdef BB_CHVT                                  //usr/bin
63         {"chvt", chvt_main, _BB_DIR_USR_BIN},
64 #endif
65 #ifdef BB_CP_MV                                 //bin
66         {"cp", cp_mv_main, _BB_DIR_BIN},
67 #endif
68 #ifdef BB_CP_MV                                 //bin
69         {"mv", cp_mv_main, _BB_DIR_BIN},
70 #endif
71 #ifdef BB_DATE                                  //bin
72         {"date", date_main, _BB_DIR_BIN},
73 #endif
74 #ifdef BB_DD                                    //bin
75         {"dd", dd_main, _BB_DIR_BIN},
76 #endif
77 #ifdef BB_DF                                    //bin
78         {"df", df_main, _BB_DIR_BIN},
79 #endif
80 #ifdef BB_DIRNAME                               //usr/bin
81         {"dirname", dirname_main, _BB_DIR_USR_BIN},
82 #endif
83 #ifdef BB_DMESG                                 //bin
84         {"dmesg", dmesg_main, _BB_DIR_BIN},
85 #endif
86 #ifdef BB_DU                                    //bin
87         {"du", du_main, _BB_DIR_BIN},
88 #endif
89 #ifdef BB_DUTMP                                 //usr/sbin
90         {"dutmp", dutmp_main, _BB_DIR_USR_SBIN},
91 #endif
92 #ifdef BB_ECHO                                  //bin
93         {"echo", echo_main, _BB_DIR_BIN},
94 #endif
95 #ifdef BB_FBSET                                 //usr/sbin
96         {"fbset", fbset_main, _BB_DIR_USR_SBIN},
97 #endif
98 #ifdef BB_FDFLUSH                               //bin
99         {"fdflush", fdflush_main, _BB_DIR_BIN},
100 #endif
101 #ifdef BB_FIND                                  //usr/bin
102         {"find", find_main, _BB_DIR_USR_BIN},
103 #endif
104 #ifdef BB_FREE                                  //usr/bin
105         {"free", free_main, _BB_DIR_USR_BIN},
106 #endif
107 #ifdef BB_FREERAMDISK                   //sbin
108         {"freeramdisk", freeramdisk_main, _BB_DIR_SBIN},
109 #endif
110 #ifdef BB_DEALLOCVT                             //usr/bin
111         {"deallocvt", deallocvt_main, _BB_DIR_USR_BIN},
112 #endif
113 #ifdef BB_FSCK_MINIX                    //sbin
114         {"fsck.minix", fsck_minix_main, _BB_DIR_SBIN},
115 #endif
116 #ifdef BB_MKFS_MINIX                    //sbin
117         {"mkfs.minix", mkfs_minix_main, _BB_DIR_SBIN},
118 #endif
119 #ifdef BB_GREP                                  //bin
120         {"grep", grep_main, _BB_DIR_BIN},
121 #endif
122 #ifdef BB_HALT                                  //sbin
123         {"halt", halt_main, _BB_DIR_SBIN},
124 #endif
125 #ifdef BB_HEAD                                  //bin
126         {"head", head_main, _BB_DIR_BIN},
127 #endif
128 #ifdef BB_HOSTID                                //usr/bin
129         {"hostid", hostid_main, _BB_DIR_USR_BIN},
130 #endif
131 #ifdef BB_HOSTNAME                              //bin
132         {"hostname", hostname_main, _BB_DIR_BIN},
133 #endif
134 #ifdef BB_INIT                                  //sbin
135         {"init", init_main, _BB_DIR_SBIN},
136 #endif
137 #ifdef BB_INSMOD                                //sbin
138         {"insmod", insmod_main, _BB_DIR_SBIN},
139 #endif
140 #ifdef BB_FEATURE_LINUXRC               //
141         {"linuxrc", init_main, _BB_DIR_ROOT},
142 #endif
143 #ifdef BB_KILL                                  //bin
144         {"kill", kill_main, _BB_DIR_BIN},
145 #endif
146 #ifdef BB_KILLALL                               //usr/bin
147         {"killall", kill_main, _BB_DIR_USR_BIN},
148 #endif
149 #ifdef BB_LENGTH                                //usr/bin
150         {"length", length_main, _BB_DIR_USR_BIN},
151 #endif
152 #ifdef BB_LN                                    //bin
153         {"ln", ln_main, _BB_DIR_BIN},
154 #endif
155 #ifdef BB_LOADACM                               //usr/bin
156         {"loadacm", loadacm_main, _BB_DIR_USR_BIN},
157 #endif
158 #ifdef BB_LOADFONT                              //usr/bin
159         {"loadfont", loadfont_main, _BB_DIR_USR_BIN},
160 #endif
161 #ifdef BB_LOADKMAP                              //sbin
162         {"loadkmap", loadkmap_main, _BB_DIR_SBIN},
163 #endif
164 #ifdef BB_LS                                    //bin
165         {"ls", ls_main, _BB_DIR_BIN},
166 #endif
167 #ifdef BB_LSMOD                                 //sbin
168         {"lsmod", lsmod_main, _BB_DIR_SBIN},
169 #endif
170 #ifdef BB_MAKEDEVS                              //sbin
171         {"makedevs", makedevs_main, _BB_DIR_SBIN},
172 #endif
173 #ifdef BB_MATH                                  //usr/bin
174         {"math", math_main, _BB_DIR_USR_BIN},
175 #endif
176 #ifdef BB_MKDIR                                 //bin
177         {"mkdir", mkdir_main, _BB_DIR_BIN},
178 #endif
179 #ifdef BB_MKFIFO                                //usr/bin
180         {"mkfifo", mkfifo_main, _BB_DIR_USR_BIN},
181 #endif
182 #ifdef BB_MKNOD                                 //bin
183         {"mknod", mknod_main, _BB_DIR_BIN},
184 #endif
185 #ifdef BB_MKSWAP                                //sbin
186         {"mkswap", mkswap_main, _BB_DIR_SBIN},
187 #endif
188 #ifdef BB_MNC                                   //usr/bin
189         {"mnc", mnc_main, _BB_DIR_USR_BIN},
190 #endif
191 #ifdef BB_MORE                                  //bin
192         {"more", more_main, _BB_DIR_BIN},
193 #endif
194 #ifdef BB_MOUNT                                 //bin
195         {"mount", mount_main, _BB_DIR_BIN},
196 #endif
197 #ifdef BB_MT                                    //bin
198         {"mt", mt_main, _BB_DIR_BIN},
199 #endif
200 #ifdef BB_NSLOOKUP                              //usr/bin
201         {"nslookup", nslookup_main, _BB_DIR_USR_BIN},
202 #endif
203 #ifdef BB_PING                                  //bin
204         {"ping", ping_main, _BB_DIR_BIN},
205 #endif
206 #ifdef BB_POWEROFF                              //sbin
207         {"poweroff", poweroff_main, _BB_DIR_SBIN},
208 #endif
209 #ifdef BB_PRINTF                                //usr/bin
210         {"printf", printf_main, _BB_DIR_USR_BIN},
211 #endif
212 #ifdef BB_PS                                    //bin
213         {"ps", ps_main, _BB_DIR_BIN},
214 #endif
215 #ifdef BB_PWD                                   //bin
216         {"pwd", pwd_main, _BB_DIR_BIN},
217 #endif
218 #ifdef BB_REBOOT                                //sbin
219         {"reboot", reboot_main, _BB_DIR_SBIN},
220 #endif
221 #ifdef BB_RM                                    //bin
222         {"rm", rm_main, _BB_DIR_BIN},
223 #endif
224 #ifdef BB_RMDIR                                 //bin
225         {"rmdir", rmdir_main, _BB_DIR_BIN},
226 #endif
227 #ifdef BB_RMMOD                                 //sbin
228         {"rmmod", rmmod_main, _BB_DIR_SBIN},
229 #endif
230 #ifdef BB_SED                                   //bin
231         {"sed", sed_main, _BB_DIR_BIN},
232 #endif
233 #ifdef BB_SH                                    //bin
234         {"sh", shell_main, _BB_DIR_BIN},
235 #endif
236 #ifdef BB_SFDISK                                //sbin
237         {"fdisk", sfdisk_main, _BB_DIR_SBIN},
238 #ifdef BB_SFDISK                                //sbin
239 #endif
240         {"sfdisk", sfdisk_main, _BB_DIR_SBIN},
241 #endif
242 #ifdef BB_SLEEP                                 //bin
243         {"sleep", sleep_main, _BB_DIR_BIN},
244 #endif
245 #ifdef BB_SORT                                  //bin
246         {"sort", sort_main, _BB_DIR_BIN},
247 #endif
248 #ifdef BB_SYNC                                  //bin
249         {"sync", sync_main, _BB_DIR_BIN},
250 #endif
251 #ifdef BB_SYSLOGD                               //sbin
252         {"syslogd", syslogd_main, _BB_DIR_SBIN},
253 #endif
254 #ifdef BB_LOGGER                                //usr/bin
255         {"logger", logger_main, _BB_DIR_USR_BIN},
256 #endif
257 #ifdef BB_LOGNAME                               //usr/bin
258         {"logname", logname_main, _BB_DIR_USR_BIN},
259 #endif
260 #ifdef BB_SWAPONOFF                             //sbin
261         {"swapon", swap_on_off_main, _BB_DIR_SBIN},
262 #endif
263 #ifdef BB_SWAPONOFF                             //sbin
264         {"swapoff", swap_on_off_main, _BB_DIR_SBIN},
265 #endif
266 #ifdef BB_TAIL                                  //usr/bin
267         {"tail", tail_main, _BB_DIR_USR_BIN},
268 #endif
269 #ifdef BB_TAR                                   //bin
270         {"tar", tar_main, _BB_DIR_BIN},
271 #endif
272 #ifdef BB_TELNET                                //usr/bin
273         {"telnet", telnet_main, _BB_DIR_USR_BIN},
274 #endif
275 #ifdef BB_TEST                                  //usr/bin
276         {"[", test_main, _BB_DIR_USR_BIN},
277 #endif
278 #ifdef BB_TEST                                  //usr/bin
279         {"test", test_main, _BB_DIR_USR_BIN},
280 #endif
281 #ifdef BB_TEE                                   //bin
282         {"tee", tee_main, _BB_DIR_BIN},
283 #endif
284 #ifdef BB_TOUCH                                 //usr/bin
285         {"touch", touch_main, _BB_DIR_USR_BIN},
286 #endif
287 #ifdef BB_TR                                    //usr/bin
288         {"tr", tr_main, _BB_DIR_USR_BIN},
289 #endif
290 #ifdef BB_TRUE_FALSE                    //bin
291         {"true", true_main, _BB_DIR_BIN},
292 #endif
293 #ifdef BB_TRUE_FALSE                    //bin
294         {"false", false_main, _BB_DIR_BIN},
295 #endif
296 #ifdef BB_TTY                                   //usr/bin
297         {"tty", tty_main, _BB_DIR_USR_BIN},
298 #endif
299 #ifdef BB_UMOUNT                                //bin
300         {"umount", umount_main, _BB_DIR_BIN},
301 #endif
302 #ifdef BB_UNAME                                 //bin
303         {"uname", uname_main, _BB_DIR_BIN},
304 #endif
305 #ifdef BB_UPTIME                                //usr/bin
306         {"uptime", uptime_main, _BB_DIR_USR_BIN},
307 #endif
308 #ifdef BB_UNIQ                                  //bin
309         {"uniq", uniq_main, _BB_DIR_BIN},
310 #endif
311 #ifdef BB_UPDATE                                //sbin
312         {"update", update_main, _BB_DIR_SBIN},
313 #endif
314 #ifdef BB_WC                                    //usr/bin
315         {"wc", wc_main, _BB_DIR_USR_BIN},
316 #endif
317 #ifdef BB_WHOAMI                                //usr/bin
318         {"whoami", whoami_main, _BB_DIR_USR_BIN},
319 #endif
320 #ifdef BB_YES                                   //usr/bin
321         {"yes", yes_main, _BB_DIR_USR_BIN},
322 #endif
323 #ifdef BB_GUNZIP                                //bin
324         {"zcat", gunzip_main, _BB_DIR_BIN},
325 #endif
326 #ifdef BB_GUNZIP                                //bin
327         {"gunzip", gunzip_main, _BB_DIR_BIN},
328 #endif
329 #ifdef BB_GZIP                                  //bin
330         {"gzip", gzip_main, _BB_DIR_BIN},
331 #endif
332         {0}
333 };
334
335
336
337 int main(int argc, char **argv)
338 {
339         char                            *s;
340         char                            *name;
341         const struct Applet     *a              = applets;
342
343         for (s = name = argv[0]; *s != '\0';) {
344                 if (*s++ == '/')
345                         name = s;
346         }
347
348         *argv = name;
349
350         while (a->name != 0) {
351                 if (strcmp(name, a->name) == 0) {
352                         int status;
353
354                         status = ((*(a->main)) (argc, argv));
355                         if (status < 0) {
356                                 fprintf(stderr, "%s: %s\n", a->name, strerror(errno));
357                         }
358                         fprintf(stderr, "\n");
359                         exit(status);
360                 }
361                 a++;
362         }
363         exit(busybox_main(argc, argv));
364 }
365
366
367 int busybox_main(int argc, char **argv)
368 {
369         int col = 0;
370
371         argc--;
372         argv++;
373
374         if (been_there_done_that == 1 || argc < 1) {
375                 const struct Applet *a = applets;
376
377                 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
378                                 BB_VER, BB_BT);
379                 fprintf(stderr, "Usage: busybox [function] [arguments]...\n");
380                 fprintf(stderr, "   or: [function] [arguments]...\n\n");
381                 fprintf(stderr,
382                                 "\tMost people will create a link to busybox for each\n"
383                                 "\tfunction name, and busybox will act like whatever you invoke it as.\n");
384                 fprintf(stderr, "\nCurrently defined functions:\n");
385
386                 while (a->name != 0) {
387                         col +=
388                                 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
389                                                 (a++)->name);
390                         if (col > 60 && a->name != 0) {
391                                 fprintf(stderr, ",\n");
392                                 col = 0;
393                         }
394                 }
395                 fprintf(stderr, "\n\n");
396                 exit(-1);
397         } else {
398                 /* If we've already been here once, exit now */
399                 been_there_done_that = 1;
400                 return (main(argc, argv));
401         }
402 }
403
404 /*
405 Local Variables:
406 c-file-style: "linux"
407 c-basic-offset: 4
408 tab-width: 4
409 End:
410 */