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