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