All pastes #1470643 Raw Edit

Mine

public c v1 · immutable
#1470643 ·published 2009-06-23 02:21 UTC
rendered paste body
// author OBLiQUE// copyleft 2009// simple unix shell skeleton// p0wnbox.com#include <stdio.h>#include <stdlib.h>#include <string.h>#include <limits.h>#include <unistd.h>#include <signal.h>#include <sys/utsname.h>#include <sys/wait.h>#define MAX_STRING 0xfff#define MAX_ARGS 30const char *shell_commands[] = {"cd","exit","\0"};void print_prompt();int chk_sh_cmds(char *str, char **tok);void sig_int(const int sig_num);int main(int argc, char *arg[]){    char *tok, buf[MAX_STRING], *args[MAX_ARGS+1];    int readlen, sh_cmd_num, arg_num, status;    pid_t pid;    // register SIGINT signal handler to disable ctrl+c    if (signal(SIGINT,sig_int)==SIG_ERR)        fprintf(stderr,"Error! cannot register signal handler!\n");    print_prompt();    while (readlen=read(STDIN_FILENO,buf,MAX_STRING)) { // read the line and return the length        buf[readlen-1]='\0'; // remove \n from the end        if (sh_cmd_num=chk_sh_cmds(buf,&tok)) { // check if its a shell command            switch (sh_cmd_num) {                case 1: // cd                    chdir(tok); // change directory                    break;                case 2: // exit                    printf("exit\n");                    exit(EXIT_SUCCESS);            }        } else { // if it's not a shell command            tok=strtok(buf," "); // replace the first space with '\0' and take the tokken            arg_num=0; // initiliaze the arg_num            while (tok!=NULL && arg_num<MAX_ARGS) { // repeat until the end of string or until the MAX_ARGS                args[arg_num]=tok; // put the tokken to the array                arg_num++; // increase the arg_num                tok=strtok(NULL," "); // replace the next space with '\0' and take the tokken            }            args[arg_num]=NULL; // fill with NULL the last empty argument                        if (args[0]!=NULL) { // i there is a command to execute                if ((pid=fork())<0) { // fork a child and check if it's forked                    fprintf(stderr,"Error! cannot fork child!\n");                    exit(EXIT_FAILURE);                } else if (pid==0) { // if i'm the child                    execvp(args[0],args); // execute the command                    // the exec replace its memory with command that executes                    // so if i get this error means that exec failed                    fprintf(stderr,"Error! cannot execvp command: %s\n",args[0]);                    exit(EXIT_FAILURE); // child exit                }                // i'm the parent                if ((pid=waitpid(pid,&status,0)<0)) // wait the child to exit                    fprintf(stderr,"Error! cannot wait for child!\n");            }        }        print_prompt();    } // end of while}void sig_int(const int sig_num){    printf("\n");    print_prompt();}void print_prompt(){    struct utsname s_uname; // uname structure    char path[PATH_MAX], symbol, *login_name, *dir_name;    if (getuid()) symbol='$'; // if uid!=0 the symbol is $    else symbol='#'; // otherwise is #    uname(&s_uname); // retrieve system information    login_name=getlogin(); // retrieve login username    getcwd(path,PATH_MAX); // retrieve path    dir_name=strrchr(path,'/'); // find the directory name    printf("%s@%s %s/ %c ",login_name,s_uname.nodename,++dir_name,symbol);    fflush(stdout); // force to write the buffered data to stdout}// this function returns 0 if the command is not a shell command// otherwise returns the index of the shell commandint chk_sh_cmds(char *str, char **tok){    if (str[0]=='\0') return 0; // if the string is null return 0    strtok_r(str," ",tok); // find the first space and replace it with '\0'    int i;    for (i=0; shell_commands[i][0]!='\0'; i++) // loop until the end of array        if (!strcmp(str,shell_commands[i])) return i+1; // i is a shell command return i+1    if (*((*tok)-1)=='\0') *((*tok)-1)=' '; // restore the space    return 0;}