Example #1
0
File: main.c Project: taysom/tau
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);
}
Example #2
0
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;
}
Example #3
0
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);
	}
}
Example #4
0
/*
 * 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;
    }