Added support for ignoring '-g' per GNU ls, thanks to David Vrabel
[oweals/busybox.git] / busybox.c
index bf0591d662c44020f13980ef0bb5daa3c438925e..486ef4d77b0fad777455cd7d1e973e31ba9e8ed7 100644 (file)
--- a/busybox.c
+++ b/busybox.c
@@ -32,6 +32,9 @@ void *__libc_stack_end;
 
 const struct BB_applet applets[] = {
 
+#ifdef BB_AR
+       {"ar", ar_main, _BB_DIR_USR_BIN},
+#endif
 #ifdef BB_BASENAME
        {"basename", basename_main, _BB_DIR_USR_BIN},
 #endif
@@ -69,6 +72,9 @@ const struct BB_applet applets[] = {
 #ifdef BB_DATE
        {"date", date_main, _BB_DIR_BIN},
 #endif
+#ifdef BB_DC
+       {"dc", dc_main, _BB_DIR_USR_BIN},
+#endif
 #ifdef BB_DD
        {"dd", dd_main, _BB_DIR_BIN},
 #endif
@@ -183,8 +189,8 @@ const struct BB_applet applets[] = {
 #ifdef BB_MAKEDEVS
        {"makedevs", makedevs_main, _BB_DIR_SBIN},
 #endif
-#ifdef BB_MATH
-       {"math", math_main, _BB_DIR_USR_BIN},
+#ifdef BB_MD5SUM
+       {"md5sum", md5sum_main, _BB_DIR_USR_BIN},
 #endif
 #ifdef BB_MKDIR
        {"mkdir", mkdir_main, _BB_DIR_BIN},
@@ -321,6 +327,12 @@ const struct BB_applet applets[] = {
 #ifdef BB_UPTIME
        {"uptime", uptime_main, _BB_DIR_USR_BIN},
 #endif
+#ifdef BB_UUENCODE
+       {"uuencode", uuencode_main, _BB_DIR_USR_BIN},
+#endif
+#ifdef BB_UUDECODE
+       {"uudecode", uudecode_main, _BB_DIR_USR_BIN},
+#endif
 #ifdef BB_USLEEP
        {"usleep", usleep_main, _BB_DIR_BIN},
 #endif
@@ -346,6 +358,83 @@ const struct BB_applet applets[] = {
 };
 
 
+#ifdef BB_FEATURE_INSTALLER
+/* 
+ * directory table
+ *             this should be consistent w/ the enum, internal.h::Location,
+ *             or else...
+ */
+static char* install_dir[] = {
+       "/",
+       "/bin",
+       "/sbin",
+       "/usr/bin",
+       "/usr/sbin",
+};
+
+/* abstract link() */
+typedef int (*__link_f)(const char *, const char *);
+
+/* 
+ * Where in the filesystem is this busybox?
+ * [return]
+ *             malloc'd string w/ full pathname of busybox's location
+ *             NULL on failure
+ */
+static char *busybox_fullpath()
+{
+       pid_t pid;
+       char path[256];
+       char proc[256];
+       int len;
+
+       pid = getpid();
+       sprintf(proc, "/proc/%d/exe", pid);
+       len = readlink(proc, path, 256);
+       if (len != -1) {
+               path[len] = 0;
+       } else {
+               fprintf(stderr, "busybox : %s : %s\n", proc, strerror(errno));
+               return NULL;
+       }
+       return strdup(path);
+}
+
+/* create (sym)links for each applet */
+static int install_links(const char *busybox, int use_symbolic_links)
+{
+       __link_f Link = link;
+
+       char command[256];
+       int i;
+       int rc = 0;
+
+       if (use_symbolic_links) Link = symlink;
+
+       for (i = 0; applets[i].name != NULL; i++) {
+               sprintf (
+                       command, 
+                       "%s/%s", 
+                       install_dir[applets[i].location], 
+                       applets[i].name
+               );
+#if 1
+               rc |= Link(busybox, command);
+#else
+               puts(command);
+#endif
+               if (rc) {
+                       fprintf(stderr,"busybox : %s : %s\n", command, strerror(errno));
+               }
+       }
+       return rc;
+}
+
+#if 0
+int uninstall_links() ?
+#endif
+#endif /* BB_FEATURE_INSTALLER */
+
 
 int main(int argc, char **argv)
 {
@@ -353,6 +442,36 @@ int main(int argc, char **argv)
        char                            *name;
        const struct BB_applet  *a              = applets;
 
+#ifdef BB_FEATURE_INSTALLER    
+       /* 
+        * This style of argument parsing doesn't scale well 
+        * in the event that busybox starts wanting more --options.
+        * If someone has a cleaner approach, by all means implement it.
+        */
+       if (argc > 1 && (strcmp(argv[1], "--install") == 0)) {
+               int use_symbolic_links = 0;
+               int rc = 0;
+               char *busybox;
+
+               /* to use symlinks, or not to use symlinks... */
+               if (argc > 2) {
+                       if ((strcmp(argv[2], "-s") == 0)) { 
+                               use_symbolic_links = 1; 
+                       }
+               }
+
+               /* link */
+               busybox = busybox_fullpath();
+               if (busybox) {
+                       install_links(busybox, use_symbolic_links);
+                       free(busybox);
+               } else {
+                       rc = 1;
+               }
+               return rc;
+       }
+#endif /* BB_FEATURE_INSTALLER */
+
        for (s = name = argv[0]; *s != '\0';) {
                if (*s++ == '/')
                        name = s;
@@ -360,20 +479,20 @@ int main(int argc, char **argv)
 
        *argv = name;
 
+#ifdef BB_SH
+       /* Add in a special case hack -- whenever **argv == '-'
+        * (i.e. '-su' or '-sh') always invoke the shell */
+       if (**argv == '-')
+               exit(((*(shell_main)) (argc, argv)));
+#endif
+
        while (a->name != 0) {
                if (strcmp(name, a->name) == 0) {
-                       int status;
-
-                       status = ((*(a->main)) (argc, argv));
-                       if (status < 0) {
-                               fprintf(stderr, "%s: %s\n", a->name, strerror(errno));
-                       }
-                       fprintf(stderr, "\n");
-                       exit(status);
+                       exit(((*(a->main)) (argc, argv)));
                }
                a++;
        }
-       exit(busybox_main(argc, argv));
+       return(busybox_main(argc, argv));
 }
 
 
@@ -407,11 +526,10 @@ int busybox_main(int argc, char **argv)
                }
                fprintf(stderr, "\n\n");
                exit(-1);
-       } else {
-               /* If we've already been here once, exit now */
-               been_there_done_that = 1;
-               return (main(argc, argv));
        }
+       /* If we've already been here once, exit now */
+       been_there_done_that = 1;
+       return (main(argc, argv));
 }
 
 /*