diff options
Diffstat (limited to 'applets/busybox.c')
-rw-r--r-- | applets/busybox.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/applets/busybox.c b/applets/busybox.c new file mode 100644 index 000000000..bb9eb3af7 --- /dev/null +++ b/applets/busybox.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * BusyBox' main applet dispatcher. | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this tarball for details. | ||
6 | */ | ||
7 | #include "busybox.h" | ||
8 | |||
9 | const char *applet_name ATTRIBUTE_EXTERNALLY_VISIBLE; | ||
10 | |||
11 | #ifdef CONFIG_FEATURE_INSTALLER | ||
12 | /* | ||
13 | * directory table | ||
14 | * this should be consistent w/ the enum, busybox.h::Location, | ||
15 | * or else... | ||
16 | */ | ||
17 | static const char usr_bin [] ="/usr/bin"; | ||
18 | static const char usr_sbin[] ="/usr/sbin"; | ||
19 | |||
20 | static const char* const install_dir[] = { | ||
21 | &usr_bin [8], /* "", equivalent to "/" for concat_path_file() */ | ||
22 | &usr_bin [4], /* "/bin" */ | ||
23 | &usr_sbin[4], /* "/sbin" */ | ||
24 | usr_bin, | ||
25 | usr_sbin | ||
26 | }; | ||
27 | |||
28 | /* abstract link() */ | ||
29 | typedef int (*__link_f)(const char *, const char *); | ||
30 | |||
31 | /* create (sym)links for each applet */ | ||
32 | static void install_links(const char *busybox, int use_symbolic_links) | ||
33 | { | ||
34 | __link_f Link = link; | ||
35 | |||
36 | char *fpc; | ||
37 | int i; | ||
38 | int rc; | ||
39 | |||
40 | if (use_symbolic_links) | ||
41 | Link = symlink; | ||
42 | |||
43 | for (i = 0; applets[i].name != NULL; i++) { | ||
44 | fpc = concat_path_file( | ||
45 | install_dir[applets[i].location], applets[i].name); | ||
46 | rc = Link(busybox, fpc); | ||
47 | if (rc!=0 && errno!=EEXIST) { | ||
48 | bb_perror_msg("%s", fpc); | ||
49 | } | ||
50 | free(fpc); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | #else | ||
55 | #define install_links(x,y) | ||
56 | #endif /* CONFIG_FEATURE_INSTALLER */ | ||
57 | |||
58 | int main(int argc, char **argv) | ||
59 | { | ||
60 | const char *s; | ||
61 | |||
62 | applet_name=argv[0]; | ||
63 | if (*applet_name == '-') applet_name++; | ||
64 | for (s = applet_name; *s ;) | ||
65 | if (*(s++) == '/') applet_name = s; | ||
66 | |||
67 | /* Set locale for everybody except 'init' */ | ||
68 | if (ENABLE_LOCALE_SUPPORT && getpid() != 1) | ||
69 | setlocale(LC_ALL, ""); | ||
70 | |||
71 | run_applet_by_name(applet_name, argc, argv); | ||
72 | bb_error_msg_and_die("applet not found"); | ||
73 | } | ||
74 | |||
75 | int busybox_main(int argc, char **argv) | ||
76 | { | ||
77 | /* | ||
78 | * This style of argument parsing doesn't scale well | ||
79 | * in the event that busybox starts wanting more --options. | ||
80 | * If someone has a cleaner approach, by all means implement it. | ||
81 | */ | ||
82 | if (ENABLE_FEATURE_INSTALLER && argc > 1 && !strcmp(argv[1], "--install")) { | ||
83 | int use_symbolic_links = 0; | ||
84 | int rc = 0; | ||
85 | char *busybox; | ||
86 | |||
87 | /* to use symlinks, or not to use symlinks... */ | ||
88 | if (argc > 2) { | ||
89 | if ((strcmp(argv[2], "-s") == 0)) { | ||
90 | use_symbolic_links = 1; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | /* link */ | ||
95 | // XXX: FIXME: this is broken. Why not just use argv[0] ? | ||
96 | busybox = xreadlink("/proc/self/exe"); | ||
97 | if (busybox) { | ||
98 | install_links(busybox, use_symbolic_links); | ||
99 | free(busybox); | ||
100 | } else { | ||
101 | rc = 1; | ||
102 | } | ||
103 | return rc; | ||
104 | } | ||
105 | |||
106 | /* Deal with --help. (Also print help when called with no arguments) */ | ||
107 | |||
108 | if (argc==1 || !strcmp(argv[1],"--help") ) { | ||
109 | if (argc>2) { | ||
110 | applet_name = argv[2]; | ||
111 | run_applet_by_name(applet_name, 2, argv); | ||
112 | } else { | ||
113 | const struct BB_applet *a; | ||
114 | int col, output_width; | ||
115 | |||
116 | if (ENABLE_FEATURE_AUTOWIDTH) { | ||
117 | /* Obtain the terminal width. */ | ||
118 | get_terminal_width_height(0, &output_width, NULL); | ||
119 | /* leading tab and room to wrap */ | ||
120 | output_width -= sizeof("start-stop-daemon, ") + 8; | ||
121 | } else output_width = 80 - sizeof("start-stop-daemon, ") - 8; | ||
122 | |||
123 | printf("%s\n" | ||
124 | "Copyright (C) 1998-2006 Erik Andersen, Rob Landley, and others.\n" | ||
125 | "Licensed under GPLv2. See source distribution for full notice.\n\n" | ||
126 | "Usage: busybox [function] [arguments]...\n" | ||
127 | " or: [function] [arguments]...\n\n" | ||
128 | "\tBusyBox is a multi-call binary that combines many common Unix\n" | ||
129 | "\tutilities into a single executable. Most people will create a\n" | ||
130 | "\tlink to busybox for each function they wish to use and BusyBox\n" | ||
131 | "\twill act like whatever it was invoked as!\n" | ||
132 | "\nCurrently defined functions:\n", bb_msg_full_version); | ||
133 | |||
134 | col=0; | ||
135 | for(a = applets; a->name;) { | ||
136 | col += printf("%s%s", (col ? ", " : "\t"), (a++)->name); | ||
137 | if (col > output_width && a->name) { | ||
138 | printf(",\n"); | ||
139 | col = 0; | ||
140 | } | ||
141 | } | ||
142 | printf("\n\n"); | ||
143 | exit(0); | ||
144 | } | ||
145 | } else run_applet_by_name(argv[1], argc-1, argv+1); | ||
146 | |||
147 | bb_error_msg_and_die("applet not found"); | ||
148 | } | ||