1 /* vi: set sw=4 ts=4: */
8 #define bb_need_full_version
9 #define BB_DECLARE_EXTERN
12 static int been_there_done_that = 0;
15 const char *applet_name;
17 #ifdef BB_FEATURE_INSTALLER
20 * this should be consistent w/ the enum, busybox.h::Location,
23 static char* install_dir[] = {
32 typedef int (*__link_f)(const char *, const char *);
35 * Where in the filesystem is this busybox?
37 * malloc'd string w/ full pathname of busybox's location
40 static char *busybox_fullpath()
48 sprintf(proc, "/proc/%d/exe", pid);
49 len = readlink(proc, path, 256);
53 errorMsg("%s: %s\n", proc, strerror(errno));
59 /* create (sym)links for each applet */
60 static void install_links(const char *busybox, int use_symbolic_links)
68 if (use_symbolic_links) Link = symlink;
70 for (i = 0; applets[i].name != NULL; i++) {
71 sprintf ( command, "%s/%s",
72 install_dir[applets[i].location],
74 rc = Link(busybox, command);
77 errorMsg("%s: %s\n", command, strerror(errno));
82 #endif /* BB_FEATURE_INSTALLER */
84 static int applet_name_compare(const void *x, const void *y)
86 const struct BB_applet *applet1 = x;
87 const struct BB_applet *applet2 = y;
89 return strcmp(applet1->name, applet2->name);
92 int main(int argc, char **argv)
94 struct BB_applet search_applet, *applet;
96 applet_name = "busybox";
98 #ifdef BB_FEATURE_INSTALLER
100 * This style of argument parsing doesn't scale well
101 * in the event that busybox starts wanting more --options.
102 * If someone has a cleaner approach, by all means implement it.
104 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
105 int use_symbolic_links = 0;
109 /* to use symlinks, or not to use symlinks... */
111 if ((strcmp(argv[2], "-s") == 0)) {
112 use_symbolic_links = 1;
117 busybox = busybox_fullpath();
119 install_links(busybox, use_symbolic_links);
126 #endif /* BB_FEATURE_INSTALLER */
128 for (s = applet_name = argv[0]; *s != '\0';) {
133 *argv = (char*)applet_name;
136 /* Add in a special case hack -- whenever **argv == '-'
137 * (i.e. '-su' or '-sh') always invoke the shell */
138 if (**argv == '-' && *(*argv+1)!= '-') {
139 exit(((*(shell_main)) (argc, argv)));
143 /* Do a binary search to find the applet entry given the name. */
144 search_applet.name = applet_name;
145 applet = bsearch(&search_applet, applets, NUM_APPLETS,
146 sizeof(struct BB_applet), applet_name_compare);
147 if (applet != NULL) {
148 if (applet->usage && argv[1] && strcmp(argv[1], "--help") == 0)
149 usage(applet->usage);
150 exit((*(applet->main)) (argc, argv));
153 return(busybox_main(argc, argv));
157 int busybox_main(int argc, char **argv)
164 if (been_there_done_that == 1 || argc < 1) {
165 const struct BB_applet *a = applets;
167 fprintf(stderr, "%s\n\n"
168 "Usage: busybox [function] [arguments]...\n"
169 " or: [function] [arguments]...\n\n"
170 "\tBusyBox is a multi-call binary that combines many common Unix\n"
171 "\tutilities into a single executable. Most people will create a\n"
172 "\tlink to busybox for each function they wish to use, and BusyBox\n"
173 "\twill act like whatever it was invoked as.\n"
174 "\nCurrently defined functions:\n", full_version);
176 while (a->name != 0) {
178 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
180 if (col > 60 && a->name != 0) {
181 fprintf(stderr, ",\n");
185 fprintf(stderr, "\n\n");
188 /* If we've already been here once, exit now */
189 been_there_done_that = 1;
190 return (main(argc, argv));
195 c-file-style: "linux"