aboutsummaryrefslogtreecommitdiff
path: root/busybox/applets/busybox.c
diff options
context:
space:
mode:
Diffstat (limited to 'busybox/applets/busybox.c')
-rw-r--r--busybox/applets/busybox.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/busybox/applets/busybox.c b/busybox/applets/busybox.c
new file mode 100644
index 000000000..dbb5e176b
--- /dev/null
+++ b/busybox/applets/busybox.c
@@ -0,0 +1,193 @@
1/* vi: set sw=4 ts=4: */
2#include <stdio.h>
3#include <string.h>
4#include <unistd.h>
5#include <errno.h>
6#include <stdlib.h>
7#include "busybox.h"
8#ifdef CONFIG_LOCALE_SUPPORT
9#include <locale.h>
10#endif
11
12int been_there_done_that = 0; /* Also used in applets.c */
13const char *bb_applet_name;
14
15#ifdef CONFIG_FEATURE_INSTALLER
16/*
17 * directory table
18 * this should be consistent w/ the enum, busybox.h::Location,
19 * or else...
20 */
21static const char usr_bin [] ="/usr/bin";
22static const char usr_sbin[] ="/usr/sbin";
23
24static const char* const install_dir[] = {
25 &usr_bin [8], /* "", equivalent to "/" for concat_path_file() */
26 &usr_bin [4], /* "/bin" */
27 &usr_sbin[4], /* "/sbin" */
28 usr_bin,
29 usr_sbin
30};
31
32/* abstract link() */
33typedef int (*__link_f)(const char *, const char *);
34
35/*
36 * Where in the filesystem is this busybox?
37 * [return]
38 * malloc'd string w/ full pathname of busybox's location
39 * NULL on failure
40 */
41static inline char *busybox_fullpath(void)
42{
43 return xreadlink("/proc/self/exe");
44}
45
46/* create (sym)links for each applet */
47static void install_links(const char *busybox, int use_symbolic_links)
48{
49 __link_f Link = link;
50
51 char *fpc;
52 int i;
53 int rc;
54
55 if (use_symbolic_links)
56 Link = symlink;
57
58 for (i = 0; applets[i].name != NULL; i++) {
59 fpc = concat_path_file(
60 install_dir[applets[i].location], applets[i].name);
61 rc = Link(busybox, fpc);
62 if (rc!=0 && errno!=EEXIST) {
63 bb_perror_msg("%s", fpc);
64 }
65 free(fpc);
66 }
67}
68
69#endif /* CONFIG_FEATURE_INSTALLER */
70
71int main(int argc, char **argv)
72{
73 const char *s;
74
75 bb_applet_name = argv[0];
76
77 if (bb_applet_name[0] == '-')
78 bb_applet_name++;
79
80 for (s = bb_applet_name; *s != '\0';) {
81 if (*s++ == '/')
82 bb_applet_name = s;
83 }
84
85#ifdef CONFIG_LOCALE_SUPPORT
86#ifdef CONFIG_INIT
87 if(getpid()!=1) /* Do not set locale for `init' */
88#endif
89 {
90 setlocale(LC_ALL, "");
91 }
92#endif
93
94 run_applet_by_name(bb_applet_name, argc, argv);
95 bb_error_msg_and_die("applet not found");
96}
97
98
99int busybox_main(int argc, char **argv)
100{
101 int col = 0, len, i;
102
103#ifdef CONFIG_FEATURE_INSTALLER
104 /*
105 * This style of argument parsing doesn't scale well
106 * in the event that busybox starts wanting more --options.
107 * If someone has a cleaner approach, by all means implement it.
108 */
109 if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
110 int use_symbolic_links = 0;
111 int rc = 0;
112 char *busybox;
113
114 /* to use symlinks, or not to use symlinks... */
115 if (argc > 2) {
116 if ((strcmp(argv[2], "-s") == 0)) {
117 use_symbolic_links = 1;
118 }
119 }
120
121 /* link */
122 busybox = busybox_fullpath();
123 if (busybox) {
124 install_links(busybox, use_symbolic_links);
125 free(busybox);
126 } else {
127 rc = 1;
128 }
129 return rc;
130 }
131#endif /* CONFIG_FEATURE_INSTALLER */
132
133 argc--;
134
135 /* If we've already been here once, exit now */
136 if (been_there_done_that == 1 || argc < 1) {
137 const struct BB_applet *a = applets;
138 int output_width = 60;
139
140#ifdef CONFIG_FEATURE_AUTOWIDTH
141 /* Obtain the terminal width. */
142 get_terminal_width_height(0, &output_width, NULL);
143 /* leading tab and room to wrap */
144 output_width -= 20;
145#endif
146
147 fprintf(stderr, "%s\n\n"
148 "Usage: busybox [function] [arguments]...\n"
149 " or: [function] [arguments]...\n\n"
150 "\tBusyBox is a multi-call binary that combines many common Unix\n"
151 "\tutilities into a single executable. Most people will create a\n"
152 "\tlink to busybox for each function they wish to use, and BusyBox\n"
153 "\twill act like whatever it was invoked as.\n"
154 "\nCurrently defined functions:\n", bb_msg_full_version);
155
156 while (a->name != 0) {
157 col +=
158 fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
159 (a++)->name);
160 if (col > output_width && a->name != 0) {
161 fprintf(stderr, ",\n");
162 col = 0;
163 }
164 }
165 fprintf(stderr, "\n\n");
166 exit(0);
167 }
168
169 /* Flag that we've been here already */
170 been_there_done_that = 1;
171
172 /* Move the command line down a notch */
173 /* Preserve pointers so setproctitle() works consistently */
174 len = argv[argc] + strlen(argv[argc]) - argv[1];
175 memmove(argv[0], argv[1], len);
176 memset(argv[0] + len, 0, argv[1] - argv[0]);
177
178 /* Fix up the argv pointers */
179 len = argv[1] - argv[0];
180 memmove(argv, argv + 1, sizeof(char *) * (argc + 1));
181 for (i = 0; i < argc; i++)
182 argv[i] -= len;
183
184 return (main(argc, argv));
185}
186
187/*
188Local Variables:
189c-file-style: "linux"
190c-basic-offset: 4
191tab-width: 4
192End:
193*/