Exemplo n.º 1
0
Arquivo: main.c Projeto: shalvin/itsh
// Takes a tokenized command string and prepares a command structures which are
// then executed.
exec_error prepare_command(int argc, char **cmdTokens) {
    int pipeIndex, argSplit1Len, argSplit2Len;
    char **argSplit1;
    char **argSplit2;
    Command *cmd1;
    Command *cmd2;
    exec_error error = NONE;

    pipeIndex = index_of(cmdTokens, argc, "|");

    if (pipeIndex > 0) {
        // Split arguments into two for each side of the pipe.
        argSplit1Len = pipeIndex;
        argSplit1 = copy_token_array(cmdTokens, argSplit1Len);
        argSplit1[argSplit1Len] = '\0';
        argSplit2Len = argc - pipeIndex - 1;
        argSplit2 = copy_token_array(cmdTokens + pipeIndex + 1, argSplit2Len);
        argSplit2[argSplit2Len] = '\0';
        
        // Prepare input (left) side of pipe. First command will take
        // arguments from left of pipe. REDIRECT_TBA allows fd to be allocated
        // by command_redirect for possible input files. REDIRECT_NONE makes 
        // sure redirection is not done to the output as this will be piped 
        // later.
        cmd1 = new_command(argSplit1Len, argSplit1, REDIRECT_TBA, REDIRECT_NONE);
        error = command_redirect(&cmd1);
        if (error != NONE) {
            free(cmd1);
            return error;
        }

        // Prepare output (right) side of pipe taking the remaining arguments
        // on the RHS of the pipe. REDIRECT constants are switched as this 
        // will be executed on the other half of the pipe.
        cmd2 = new_command(argSplit2Len, argSplit2, REDIRECT_NONE, REDIRECT_TBA);
        error = command_redirect(&cmd2);
        if (error != NONE) {
            free(cmd1);
            free(cmd2);
            return error;
        }

        // Execute piped command
        error = execute_piped(cmd1, cmd2);
        
        free_token_array(&argSplit1, argSplit1Len);
        free_token_array(&argSplit2, argSplit2Len);
    
    } else {
        // No pipe found. Prepare any redirects.
        cmd1 = new_command(argc, cmdTokens, REDIRECT_TBA, REDIRECT_TBA);
        error = command_redirect(&cmd1);

        if (error != NONE) {
            free(cmd1);
            return error;
        }

        error = execute_unpiped(cmd1);
    }

    return error;
}
Exemplo n.º 2
0
int main(int argc, char **argv, char **envp) {
// the line they enter
	char line[BUFFER_LENGTH];

// the holder for search paths
	char search[MAX_PATHS][MAX_PATH_LEN];
	int path_len = 0;

	register struct passwd *pw;
	register uid_t uid;
	char **env;
	env = envp;

	int dirchange;

	char* pipeptr;
	char* inptr;
	char* outptr;
	char* user;
	Command* basic;
	Command* firstC;
	Command* SecondC;
	char *buffer;

	uid = geteuid();
	pw = getpwuid(uid);
	if (pw) {
		user = pw->pw_name;
	}

// get the host name and put it in a buffer
	char hostname[64];
	hostname[0] = '\0';
	gethostname(hostname, sizeof(hostname));

// retrieve our path and put it into an array of search paths
// not really needed if we're using execvp... oops
	/*char* path;
	 path = getenv("PATH");
	 char* pch = strtok(path, ":");
	 while (pch != NULL) {
	 strcpy(search[path_len], pch);
	 pch = strtok(NULL, ":");
	 path_len++;
	 }*/
	dirchange = -1;
	while (TRUE) {
		printf("%s@%s$ ", pw->pw_name, hostname);
		fflush(stdout);
		
		//Make sure our line/buffer is indeed empty
		memset(line, '\0', sizeof(line));
		
		//Set line to stuff from terminal
		//Also set buffer to alias line
		buffer = accept(line);
		
		//Check for various things in the line
		//to determine what combination of commands to run
		pipeptr = strpbrk(buffer, "|");
		inptr = strpbrk(buffer, "<");
		outptr = strpbrk(buffer, ">");

		//Handle exit command
		if (strncmp(buffer, "exit", 4) == 0
				|| strncmp(buffer, "quit", 4) == 0) {
			return EXIT_SUCCESS;
		}
		
		//Handle CD command
		if (strncmp(buffer, "cd", 2) == 0) {
			change_dir(buffer);
		} else {
			//If we have an inbound redirect, nothing else can happen.
			if (inptr != NULL ) {
				char* pch = strtok(buffer, "<\n");
				char first[256];
				strcpy(first, pch);
				char second[256];
				pch = strtok(NULL, "<\n");
				strcpy(second, pch);

				basic = build_regular_command(first, env);
				execute_redirect_in(&(basic->argv), basic->is_background,
						basic->envv, second);

				memset(first, '\0', sizeof(char) * 256);
				memset(second, '\0', sizeof(char) * 256);
				memset(buffer, '\0', sizeof(buffer));
				free(basic);
				basic = NULL;
			} else {
				//Otherwise, figure out what combo we have and run it.
				if (pipeptr != NULL && outptr != NULL ) {
					//Redirect out AND pipe
					
					//Tokenize once on pipe ( } )
					char* pch = strtok(buffer, "|\n");
					char first[256];
					strcpy(first, pch);
					char second[256];
					pch = strtok(NULL, "|\n");
					strcpy(second, pch);

					char third[256];
					
					//Tokenzie twice on >
					//Being sure to copy stuff to buffers
					//to avoid tampering with the pointer
					pch = strtok(second, ">\n");
					strcpy(third, pch);
					char fourth[256];
					pch = strtok(NULL, ">\n");
					strcpy(fourth, pch);
					
					
					//Build our commands
					firstC = build_regular_command(first, env);

					SecondC = build_regular_command(third, env);
					
					
					//Execute everything
					execute_piped_out_redir(&(firstC->argv),
							firstC->is_background, firstC->envv,
							&(SecondC->argv), SecondC->is_background,
							SecondC->envv, fourth);
							
					//Free and clear stuff
					free(firstC);
					free(SecondC);
					firstC = NULL;
					SecondC = NULL;
					memset(first, '\0', sizeof(char) * 256);
					memset(second, '\0', sizeof(char) * 256);
					memset(third, '\0', sizeof(char) * 256);
					memset(fourth, '\0', sizeof(char) * 256);
					memset(buffer, '\0', sizeof(buffer));
				} else if (pipeptr != NULL && outptr == NULL ) {
					//Just a pipe

					char* pch = strtok(buffer, "|\n");
					char first[256];
					strcpy(first, pch);
					char second[256];
					pch = strtok(NULL, "|\n");
					strcpy(second, pch);
					firstC = build_regular_command(first, env);

					SecondC = build_regular_command(second, env);

					execute_piped(&(firstC->argv), firstC->is_background,
							firstC->envv, &(SecondC->argv),
							SecondC->is_background, SecondC->envv);
					free(firstC);
					free(SecondC);
					firstC = NULL;
					SecondC = NULL;
					memset(first, '\0', sizeof(char) * 256);
					memset(second, '\0', sizeof(char) * 256);
					memset(buffer, '\0', sizeof(buffer));

				} else if (pipeptr == NULL && outptr != NULL ) {

					char* pch = strtok(buffer, ">\n");
					char first[256];
					strcpy(first, pch);
					char second[256];
					pch = strtok(NULL, ">\n");
					strcpy(second, pch);

					basic = build_regular_command(first, env);
					execute_redirect_out(&(basic->argv), basic->is_background,
							basic->envv, second);

					memset(first, '\0', sizeof(char) * 256);
					memset(second, '\0', sizeof(char) * 256);
					memset(buffer, '\0', sizeof(buffer));
					free(basic);
					basic = NULL;

					//Just an outbound redirect
				} else if (pipeptr == NULL && outptr == NULL ) {
					basic = build_regular_command(buffer, env);

					execute(&(basic->argv), basic->is_background, basic->envv);
					memset(basic, 0, sizeof(*basic));
					memset(buffer, '\0', sizeof(buffer));
					free(basic);
					basic = NULL;

				}
			}
		}
		
		//Clear buffer/line again. Just to be sure
		memset(buffer, '\0', sizeof(buffer));
		memset(line, '\0', sizeof(line));

	}
	return EXIT_SUCCESS;
}