Example #1
0
int main(int argc, char *const argv[])
{
	int       opt      = 0, long_index = 0, status = 0;
	FILE     *lf       = stderr; /**< Default logfile. */
	char     *lfpath   = NULL;
	cli_code  cli_stat = CLI_PRE_INIT;

	/* Parse command-line arguments. */
	while ((opt = getopt_long(argc, argv,
					g_short_opts, g_long_opts, &long_index)) != -1) {
		switch (opt) {
			case 'l':
				if (!optarg) {
					fputs("The logfile option requires a valid argument.\n",
							stderr);
					status = 1;
					goto exit;
				}
				if (!(lf = freopen(optarg, "a+", stderr))) {
					fprintf(stderr, "Could not open logfile '%s'!\n", optarg);
					perror("logfile");
					status = 2;
					goto exit;
				}
				if (!(lfpath = strndup(optarg, strlen(optarg) + 1))) {
					perror("logfile path strndup");
					status = 3;
					goto exit;
				}
				fprintf(stderr, "\t*** Logfile: '%s' ***\n", lfpath);
				break;
			case 'h':
				usage();
				goto exit;
			default:
				break;
		}
	}

	if (!lfpath) {
		char *tmpname = strdup("/tmp/chemtk_dbg_XXXXXX");
		assert(tmpname);
		int tmpfile = mkstemp(tmpname);
		lfpath = tmpname;
		if (tmpfile == -1) {
			perror("mkstemp");
			goto exit;
		}
		if (!(lf = freopen(tmpname, "a+", stderr))) {
			fprintf(stderr, "Could not open logfile '%s'!\n", tmpname);
			perror("logfile");
			status = 2;
			goto exit;
		}
	}

	cli_stat = run_cli(stderr);
	printf("CLI exited: %s\n", cli_statuses[cli_stat]);
	if (cli_stat != CLI_OK)
		status = 100 + cli_stat;

exit:
	if (lf != stderr && lf != NULL)
		fclose(lf);
	if (lfpath) {
		if (unlink(lfpath) == -1) {
			fprintf(stderr, "Could not unlink '%s'.\n", lfpath);
			perror("unlink");
		}
	}
	free(lfpath);
	delete_sc_stack(g_stack, free);
	free_command_info();

	return status;
}
Example #2
0
// parse command to run
// parse tokens from head (include) to tail (*exclude*)
PARSE_STATUS parse_command(TOKEN_LIST_NODE *head, TOKEN_LIST_NODE *tail)
{
    COMMAND_INFO info;
    char *temp, *pwd;
    int i;

    init_command_info(&info);

    while (head != tail)
    {
        switch (head->tok->type)
        {
        case TOKEN_TYPE_IN:
            // move to next token
            head = head->next;

            // must be a string after the < operator
            if (head->tok->type != TOKEN_TYPE_STRING)
            {
                free_command_info(info);
                return PARSE_STATUS_FILENAME_EXPECTED;
            }

            // check if file not exist
            pwd = calloc(sizeof(char *), STRING_MAX_LENGTH);
            getcwd(pwd, STRING_MAX_LENGTH);
            temp = connect_dir(pwd, head->tok->t_string.str);
            free(pwd);
            if (access(temp, 0) == -1)
            {
                free_command_info(info);
                return PARSE_STATUS_FILE_NOT_EXIST;
            }
            free(temp);

            info.input_file = head->tok->t_string.str;

            break;

        case TOKEN_TYPE_OUT:
            // move to next token
            head = head->next;

            // must be a string after the < operator
            if (head->tok->type != TOKEN_TYPE_STRING)
            {
                free_command_info(info);
                return PARSE_STATUS_FILENAME_EXPECTED;
            }

            // if file not exist, create it, or clear it
            close(open(head->tok->t_string.str, O_WRONLY | O_CREAT, 0644));

            info.output_file = head->tok->t_string.str;
            info.append_mode = 0;

            break;

        case TOKEN_TYPE_APPEND:
            // move to next token
            head = head->next;

            // must be a string after the < operator
            if (head->tok->type != TOKEN_TYPE_STRING)
            {
                free_command_info(info);
                return PARSE_STATUS_FILENAME_EXPECTED;
            }

            // if file not exist, create it, or do nothing
            close(open(head->tok->t_string.str, O_WRONLY | O_CREAT | O_APPEND, 0644));

            info.output_file = head->tok->t_string.str;
            info.append_mode = 1;

            break;

        case TOKEN_TYPE_STRING:
            // the first string is always command
            if (info.command == NULL)
            {
                info.command = head->tok->t_string.str;
            }
            // add this string to parameters
            ++info.parameters_len;
            info.parameters = realloc(info.parameters, sizeof(char *) * info.parameters_len);
            info.parameters[info.parameters_len - 1] = head->tok->t_string.str;

            break;

        case TOKEN_TYPE_BG:
            info.background_mode = 1;

            break;

        case TOKEN_TYPE_PIPE:
            info.output_to_pipe = 1;

            break;

        case TOKEN_TYPE_NEXT:
            info.wait_processes = 1;

        // other tokens
        default:
            // do nothing
            break;
        }
        head = head->next;
    }

    // If command equals to NULL... Hey, you are kidding.
    // No commands here, what should I run instead?
    if (info.command == NULL)
    {
        free_command_info(info);
        return PARSE_STATUS_COMMAND_EXPECTED;
    }
    else
    {
#ifdef DEBUG
        fprintf(stderr, "[parser.c] will run command %s!\n", info.command);
#endif
        run_command(&info);
        if (info.wait_processes)
        {
            for (i = 0; i != pid_list_len; ++i)
            {
                waitpid(pid_list[i]);
            }
            free(pid_list);
            pid_list = NULL;
            pid_list_len = 0;
        }
        free_command_info(info);
        return PARSE_STATUS_NORMAL;
    }
}