X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=main.c;h=0738a17820415fc14296031ee8b60043de8b516e;hb=d5258b43a2f6795cb49203d67deefd78588dedd7;hp=20ec5b102cadfb4153a36c0b023e1ea7bee52d1d;hpb=bb504f382dc6c596e6b2b9ce04931e7fbdd15bbe;p=platform%2Fupstream%2Ftoybox.git diff --git a/main.c b/main.c index 20ec5b1..0738a17 100644 --- a/main.c +++ b/main.c @@ -5,12 +5,17 @@ #include "toys.h" +#ifndef TOYBOX_VERSION +#define TOYBOX_VERSION "0.6.0" +#endif + // Populate toy_list[]. #undef NEWTOY #undef OLDTOY #define NEWTOY(name, opts, flags) {#name, name##_main, opts, flags}, -#define OLDTOY(name, oldname, opts, flags) {#name, oldname##_main, opts, flags}, +#define OLDTOY(name, oldname, flags) \ + {#name, oldname##_main, OPTSTR_##oldname, flags}, struct toy_list toy_list[] = { #include "generated/newtoys.h" @@ -20,12 +25,14 @@ struct toy_list toy_list[] = { struct toy_context toys; union global_union this; -char toybuf[4096]; +char toybuf[4096], libbuf[4096]; struct toy_list *toy_find(char *name) { int top, bottom, middle; + if (!CFG_TOYBOX) return 0; + // If the name starts with "toybox" accept that as a match. Otherwise // skip the first entry, which is out of order. @@ -55,7 +62,7 @@ struct toy_list *toy_find(char *name) #undef NEWTOY #undef OLDTOY #define NEWTOY(name, opts, flags) opts || -#define OLDTOY(name, oldname, opts, flags) opts || +#define OLDTOY(name, oldname, flags) OPTSTR_##oldname || static const int NEED_OPTIONS = #include "generated/newtoys.h" 0; // Ends the opts || opts || opts... @@ -66,7 +73,11 @@ static void toy_singleinit(struct toy_list *which, char *argv[]) toys.which = which; toys.argv = argv; + if (CFG_TOYBOX_I18N) setlocale(LC_ALL, "C"+!!(which->flags & TOYFLAG_LOCALE)); + if (CFG_TOYBOX_HELP_DASHDASH && argv[1] && !strcmp(argv[1], "--help")) { + if (CFG_TOYBOX && toys.which == toy_list && toys.argv[2]) + if (!(toys.which = toy_find(toys.argv[2]))) return; show_help(); xexit(); } @@ -78,6 +89,8 @@ static void toy_singleinit(struct toy_list *which, char *argv[]) } toys.old_umask = umask(0); if (!(which->flags & TOYFLAG_UMASK)) umask(toys.old_umask); + toys.signalfd--; + toys.toycount = ARRAY_LEN(toy_list); } // Setup toybox global state for this command. @@ -90,32 +103,47 @@ void toy_init(struct toy_list *which, char *argv[]) uid_t uid = getuid(), euid = geteuid(); if (!(which->flags & TOYFLAG_STAYROOT)) { - if (uid != euid) xsetuid(euid=uid); + if (uid != euid) { + if (!setuid(uid)) perror_exit("setuid %d->%d", euid, uid); // drop root + else euid = uid; + } } else if (CFG_TOYBOX_DEBUG && uid && which != toy_list) error_msg("Not installed suid root"); - if ((which->flags & TOYFLAG_NEEDROOT) && euid) error_exit("Not root"); + if ((which->flags & TOYFLAG_NEEDROOT) && euid) { + toys.exithelp++; + error_exit("Not root"); + } } // Free old toys contents (to be reentrant), but leave rebound if any if (toys.optargs != toys.argv+1) free(toys.optargs); memset(&toys, 0, offsetof(struct toy_context, rebound)); + if (toys.recursion > 1) memset(&this, 0, sizeof(this)); // Subset of init needed by singlemain. toy_singleinit(which, argv); } // Like exec() but runs an internal toybox command instead of another file. -// Only returns if it can't find the command, otherwise exit() when done. +// Only returns if it can't run command internally, otherwise exit() when done. void toy_exec(char *argv[]) { struct toy_list *which; + // Return if we can't find it, or need to re-exec to acquire root, + // or if stack depth is getting silly. if (!(which = toy_find(argv[0]))) return; + if (toys.recursion && (which->flags & TOYFLAG_ROOTONLY) && getuid()) return; + if (toys.recursion++ > 5) return; + + // don't blank old optargs if our new argc lives in the old optargs. + if (argv>=toys.optargs && argv<=toys.optargs+toys.optc) toys.optargs = 0; + + // Run command toy_init(which, argv); - toys.which->toy_main(); - if (fflush(NULL) || ferror(stdout)) perror_exit("write"); + if (toys.which) toys.which->toy_main(); xexit(); } @@ -129,21 +157,18 @@ void toybox_main(void) toys.which = toy_list; if (toys.argv[1]) { - if (CFG_TOYBOX_HELP_DASHDASH && !strcmp(toys.argv[1], "--help")) { - if (toys.argv[2]) toys.which = toy_find(toys.argv[2]); - if (toys.which) { - show_help(); - return; - } - } else { - toy_exec(toys.argv+1); - if (toys.argv[1][0] == '-') goto list; + toys.optc = toys.recursion = 0; + toy_exec(toys.argv+1); + if (!strcmp("--version", toys.argv[1])) { + xputs(TOYBOX_VERSION); + xexit(); + } + if (toys.argv[1][0] != '-') { + toys.exitval = 127; + error_exit("Unknown command %s", toys.argv[1]); } - - error_exit("Unknown command %s",toys.argv[1]); } -list: // Output list of command. for (i=1; i65) { - xputc('\n'); - len=0; - } + len += printf("%s",toy_list[i].name); + if (++len > 65) len = 0; + xputc(len ? ' ' : '\n'); } } xputc('\n'); @@ -165,9 +188,10 @@ list: int main(int argc, char *argv[]) { - if (CFG_TOYBOX_I18N) setlocale(LC_ALL, ""); + // We check our own stdout errors, disable sigpipe killer + signal(SIGPIPE, SIG_IGN); - if (!CFG_TOYBOX_SINGLE) { + if (CFG_TOYBOX) { // Trim path off of command name *argv = basename(*argv); @@ -179,8 +203,7 @@ int main(int argc, char *argv[]) // a single toybox command built standalone with no multiplexer toy_singleinit(toy_list, argv); toy_list->toy_main(); - if (fflush(NULL) || ferror(stdout)) perror_exit("write"); } - return toys.exitval; + xexit(); }