void process_command (char *line) { int argc; char **argv; if (setjmp(Err_jmp)) return; argc = line2argv(line, &argv); execute(argc, argv); if (debug_is_on()) dump_args(argc, argv); }
int shell_exec(char *line) { char *argv[ARGC_MAX + 1]; int argc; int module = default_module; int err; shell_cmd_function_t cb; argc = line2argv(line, argv, ARRAY_SIZE(argv)); if (!argc) { return -EINVAL; } err = argc; cb = get_cb(&argc, argv, &module); if (!cb) { if (app_cmd_handler != NULL) { cb = app_cmd_handler; } else { print_cmd_unknown(argv[0]); return -EINVAL; } } /* Execute callback with arguments */ if (module != -1 && module != default_module) { /* Ajust parameters to point to the actual command */ err = cb(argc - 1, &argv[1]); } else { err = cb(argc, argv); } if (err < 0) { show_cmd_help(argv); } return err; }
static void shell(int arg1, int arg2) { char *argv[ARGC_MAX + 1]; size_t argc; while (1) { struct uart_console_input *cmd; shell_cmd_function_t cb; printk("%s", get_prompt()); cmd = nano_fiber_fifo_get(&cmds_queue, TICKS_UNLIMITED); argc = line2argv(cmd->line, argv, ARRAY_SIZE(argv)); if (!argc) { nano_fiber_fifo_put(&avail_queue, cmd); continue; } cb = get_cb(argv[0]); if (!cb) { if (app_cmd_handler != NULL) { cb = app_cmd_handler; } else { printk("Unrecognized command: %s\n", argv[0]); printk("Type 'help' for list of available commands\n"); nano_fiber_fifo_put(&avail_queue, cmd); continue; } } /* Execute callback with arguments */ if (cb(argc, argv) < 0) { show_cmd_help(argc, argv); } nano_fiber_fifo_put(&avail_queue, cmd); } }
/* * This is the recursive function that processes a module name. * It calls back the passed routine for each directory of a module * It runs the post checkout or post tag proc from the modules file */ int my_module (DBM *db, char *mname, enum mtype m_type, char *msg, CALLBACKPROC callback_proc, char *where, int shorten, int local_specified, int run_module_prog, int build_dirs, char *extra_arg, List *stack) { char *checkout_prog = NULL; char *export_prog = NULL; char *tag_prog = NULL; struct saved_cwd cwd; int cwd_saved = 0; char *line; int modargc; int xmodargc; char **modargv = NULL; char **xmodargv = NULL; /* Found entry from modules file, including options and such. */ char *value = NULL; char *mwhere = NULL; char *mfile = NULL; char *spec_opt = NULL; char *xvalue = NULL; int alias = 0; datum key, val; char *cp; int c, err = 0; int nonalias_opt = 0; #ifdef SERVER_SUPPORT int restore_server_dir = 0; char *server_dir_to_restore = NULL; #endif TRACE (TRACE_FUNCTION, "my_module (%s, %s, %s, %s)", mname ? mname : "(null)", msg ? msg : "(null)", where ? where : "NULL", extra_arg ? extra_arg : "NULL"); /* Don't process absolute directories. Anything else could be a security * problem. Before this check was put in place: * * $ cvs -d:fork:/cvsroot co /foo * cvs server: warning: cannot make directory CVS in /: Permission denied * cvs [server aborted]: cannot make directory /foo: Permission denied * $ */ if (ISABSOLUTE (mname)) error (1, 0, "Absolute module reference invalid: `%s'", mname); /* Similarly for directories that attempt to step above the root of the * repository. */ if (pathname_levels (mname) > 0) error (1, 0, "up-level in module reference (`..') invalid: `%s'.", mname); /* if this is a directory to ignore, add it to that list */ if (mname[0] == '!' && mname[1] != '\0') { ign_dir_add (mname+1); goto do_module_return; } /* strip extra stuff from the module name */ strip_trailing_slashes (mname); /* * Look up the module using the following scheme: * 1) look for mname as a module name * 2) look for mname as a directory * 3) look for mname as a file * 4) take mname up to the first slash and look it up as a module name * (this is for checking out only part of a module) */ /* look it up as a module name */ key.dptr = mname; key.dsize = strlen (key.dptr); if (db != NULL) val = dbm_fetch (db, key); else val.dptr = NULL; if (val.dptr != NULL) { /* copy and null terminate the value */ value = xmalloc (val.dsize + 1); memcpy (value, val.dptr, val.dsize); value[val.dsize] = '\0'; /* If the line ends in a comment, strip it off */ if ((cp = strchr (value, '#')) != NULL) *cp = '\0'; else cp = value + val.dsize; /* Always strip trailing spaces */ while (cp > value && isspace ((unsigned char) *--cp)) *cp = '\0'; mwhere = xstrdup (mname); goto found; } else { char *file; char *attic_file; char *acp; int is_found = 0; /* check to see if mname is a directory or file */ file = xmalloc (strlen (current_parsed_root->directory) + strlen (mname) + sizeof(RCSEXT) + 2); (void) sprintf (file, "%s/%s", current_parsed_root->directory, mname); attic_file = xmalloc (strlen (current_parsed_root->directory) + strlen (mname) + sizeof (CVSATTIC) + sizeof (RCSEXT) + 3); if ((acp = strrchr (mname, '/')) != NULL) { *acp = '\0'; (void) sprintf (attic_file, "%s/%s/%s/%s%s", current_parsed_root->directory, mname, CVSATTIC, acp + 1, RCSEXT); *acp = '/'; } else (void) sprintf (attic_file, "%s/%s/%s%s", current_parsed_root->directory, CVSATTIC, mname, RCSEXT); if (isdir (file)) { modargv = xmalloc (sizeof (*modargv)); modargv[0] = xstrdup (mname); modargc = 1; is_found = 1; } else { (void) strcat (file, RCSEXT); if (isfile (file) || isfile (attic_file)) { /* if mname was a file, we have to split it into "dir file" */ if ((cp = strrchr (mname, '/')) != NULL && cp != mname) { modargv = xnmalloc (2, sizeof (*modargv)); modargv[0] = xmalloc (strlen (mname) + 2); strncpy (modargv[0], mname, cp - mname); modargv[0][cp - mname] = '\0'; modargv[1] = xstrdup (cp + 1); modargc = 2; } else { /* * the only '/' at the beginning or no '/' at all * means the file we are interested in is in CVSROOT * itself so the directory should be '.' */ if (cp == mname) { /* drop the leading / if specified */ modargv = xnmalloc (2, sizeof (*modargv)); modargv[0] = xstrdup ("."); modargv[1] = xstrdup (mname + 1); modargc = 2; } else { /* otherwise just copy it */ modargv = xnmalloc (2, sizeof (*modargv)); modargv[0] = xstrdup ("."); modargv[1] = xstrdup (mname); modargc = 2; } } is_found = 1; } } free (attic_file); free (file); if (is_found) { assert (value == NULL); /* OK, we have now set up modargv with the actual file/directory we want to work on. We duplicate a small amount of code here because the vast majority of the code after the "found" label does not pertain to the case where we found a file/directory rather than finding an entry in the modules file. */ if (save_cwd (&cwd)) error (1, errno, "Failed to save current directory."); cwd_saved = 1; err += callback_proc (modargc, modargv, where, mwhere, mfile, shorten, local_specified, mname, msg); free_names (&modargc, modargv); /* cd back to where we started. */ if (restore_cwd (&cwd)) error (1, errno, "Failed to restore current directory, `%s'.", cwd.name); free_cwd (&cwd); cwd_saved = 0; goto do_module_return; } } /* look up everything to the first / as a module */ if (mname[0] != '/' && (cp = strchr (mname, '/')) != NULL) { /* Make the slash the new end of the string temporarily */ *cp = '\0'; key.dptr = mname; key.dsize = strlen (key.dptr); /* do the lookup */ if (db != NULL) val = dbm_fetch (db, key); else val.dptr = NULL; /* if we found it, clean up the value and life is good */ if (val.dptr != NULL) { char *cp2; /* copy and null terminate the value */ value = xmalloc (val.dsize + 1); memcpy (value, val.dptr, val.dsize); value[val.dsize] = '\0'; /* If the line ends in a comment, strip it off */ if ((cp2 = strchr (value, '#')) != NULL) *cp2 = '\0'; else cp2 = value + val.dsize; /* Always strip trailing spaces */ while (cp2 > value && isspace ((unsigned char) *--cp2)) *cp2 = '\0'; /* mwhere gets just the module name */ mwhere = xstrdup (mname); mfile = cp + 1; assert (strlen (mfile)); /* put the / back in mname */ *cp = '/'; goto found; } /* put the / back in mname */ *cp = '/'; } /* if we got here, we couldn't find it using our search, so give up */ error (0, 0, "cannot find module `%s' - ignored", mname); err++; goto do_module_return; /* * At this point, we found what we were looking for in one * of the many different forms. */ found: /* remember where we start */ if (save_cwd (&cwd)) error (1, errno, "Failed to save current directory."); cwd_saved = 1; assert (value != NULL); /* search the value for the special delimiter and save for later */ if ((cp = strchr (value, CVSMODULE_SPEC)) != NULL) { *cp = '\0'; /* null out the special char */ spec_opt = cp + 1; /* save the options for later */ /* strip whitespace if necessary */ while (cp > value && isspace ((unsigned char) *--cp)) *cp = '\0'; } /* don't do special options only part of a module was specified */ if (mfile != NULL) spec_opt = NULL; /* * value now contains one of the following: * 1) dir * 2) dir file * 3) the value from modules without any special args * [ args ] dir [file] [file] ... * or -a module [ module ] ... */ /* Put the value on a line with XXX prepended for getopt to eat */ line = Xasprintf ("XXX %s", value); /* turn the line into an argv[] array */ line2argv (&xmodargc, &xmodargv, line, " \t"); free (line); modargc = xmodargc; modargv = xmodargv; /* parse the args */ getoptreset (); while ((c = getopt (modargc, modargv, CVSMODULE_OPTS)) != -1) { switch (c) { case 'a': alias = 1; break; case 'd': if (mwhere) free (mwhere); mwhere = xstrdup (optarg); nonalias_opt = 1; break; case 'l': local_specified = 1; nonalias_opt = 1; break; case 'o': if (checkout_prog) free (checkout_prog); checkout_prog = xstrdup (optarg); nonalias_opt = 1; break; case 'e': if (export_prog) free (export_prog); export_prog = xstrdup (optarg); nonalias_opt = 1; break; case 't': if (tag_prog) free (tag_prog); tag_prog = xstrdup (optarg); nonalias_opt = 1; break; case '?': error (0, 0, "modules file has invalid option for key %s value %s", key.dptr, value); err++; goto do_module_return; } } modargc -= optind; modargv += optind; if (modargc == 0 && spec_opt == NULL) { error (0, 0, "modules file missing directory for module %s", mname); ++err; goto do_module_return; } if (alias && nonalias_opt) { /* The documentation has never said it is valid to specify -a along with another option. And I believe that in the past CVS has ignored the options other than -a, more or less, in this situation. */ error (0, 0, "\ -a cannot be specified in the modules file along with other options"); ++err; goto do_module_return; }