OSDN Git Service

New option parsing infrastructure (doesn't use getopt). Hook it up to
[android-x86/external-toybox.git] / main.c
1 /* vi: set ts=4 :*/
2 /* Toybox infrastructure.
3  *
4  * Copyright 2006 Rob Landley <rob@landley.net>
5  */
6
7 #include "toys.h"
8
9 // Populate toy_list[].
10
11 struct toy_list toy_list[] = {
12 #define FROM_MAIN
13 #include "toys/toylist.h"
14 };
15
16 #define TOY_LIST_LEN (sizeof(toy_list)/sizeof(struct toy_list))
17
18 // global context for this applet.
19
20 struct toy_context toys;
21
22 struct toy_list *toy_find(char *name)
23 {
24         int top, bottom, middle;
25
26         // If the name starts with "toybox", accept that as a match.  Otherwise
27         // skip the first entry, which is out of order.
28
29         if (!strncmp(name,"toybox",6)) return toy_list;
30         bottom = 1;
31
32         // Binary search to find this applet.
33
34         top = TOY_LIST_LEN-1;
35         for (;;) {
36                 int result;
37                 
38                 middle = (top+bottom)/2;
39                 if (middle<bottom || middle>top) return NULL;
40                 result = strcmp(name,toy_list[middle].name);
41                 if (!result) return toy_list+middle;
42                 if (result<0) top=--middle;
43                 else bottom = ++middle;
44         }
45 }
46
47 void toy_init(struct toy_list *which, char *argv[])
48 {
49         // Free old toys contents here?
50
51         toys.which = which;
52         toys.argv = argv;
53         toys.exitval = 1;
54         if (which->options) get_optflags();
55 }
56
57 // Run a toy.
58 void toy_exec(char *argv[])
59 {
60         struct toy_list *which;
61         
62         which = toy_find(argv[0]);
63         if (!which) return;
64
65         toy_init(which, argv);
66         
67         exit(toys.which->toy_main());
68 }
69
70 int toybox_main(void)
71 {
72         static char *toy_paths[]={"usr/","bin/","sbin/",0};
73         int i, len = 0;
74
75         if (toys.argv[1]) {
76                 if (toys.argv[1][0]!='-') {
77                         toy_exec(toys.argv+1);
78                         error_exit("No behavior for %s\n",toys.argv[1]);
79                 }
80         }
81
82         // Output list of applets.
83         for (i=1; i<TOY_LIST_LEN; i++) {
84                 int fl = toy_list[i].flags;
85                 if (fl & TOYMASK_LOCATION) {
86                         if (toys.argv[1]) {
87                                 int j;
88                                 for (j=0; toy_paths[j]; j++)
89                                         if (fl & (1<<j)) len += printf("%s", toy_paths[j]);
90                         }
91                         len += printf("%s ",toy_list[i].name);
92                         if (len>65) {
93                                 putchar('\n');
94                                 len=0;
95                         }
96                 }
97         }
98         putchar('\n');
99         return 0;
100 }
101
102 int main(int argc, char *argv[])
103 {
104         char *name;
105
106         // Figure out which applet to call.
107         name = rindex(argv[0], '/');
108         if (!name) name=argv[0];
109         else name++;
110         argv[0] = name;
111
112         toys.argv = argv-1;
113         return toybox_main();
114 }