int spawn_proc(int in,int out,pc node,int redirectFlag,char *homedir) { int no_of_tokens=0,std_out; pid_t pid; char **argv=malloc ( 100 * sizeof(char)); //Number of tokens there can be pid=fork(); if(pid<0) { fprintf(stderr, "Error in Piping!\n" ); } else if(pid==0) /* Child */ { infile=0; outfile=0; int random=isRedirect(node.argv); no_of_tokens=parseCommand(node.argv,argv,redirectFlag); if(in!=0) { dup2(in,0); close(in); } if(out!=1) { dup2(out,1); close(out); } if(outfile!=0) { int fd1; if(outfile==1) { fd1=open(output,O_CREAT|O_RDWR|O_TRUNC,00666); lseek(fd1, 0, SEEK_SET); } else if(outfile==2) { fd1=open(output,O_APPEND|O_CREAT|O_RDWR,00666); } if(fd1==-1) { fprintf(stderr, "Can't open file for output!\n"); memset(output, 0, 10); outfile=0; return; } int std_out=dup(1); dup2(fd1,STDOUT_FILENO); close(fd1); memset(output, 0, 10); outfile=0; //redirectFlag=0; } if(infile==3) { int fd2; fd2=open(inputfile,O_RDWR,00666); if(fd2==-1) { fprintf(stderr, "Can't open file for input! 2\n"); memset(inputfile, 0, 10); infile=0; return; } dup2(fd2,STDIN_FILENO); close(fd2); memset(inputfile, 0, 10); infile=0; //redirectFlag=0; } if(isBuiltInCommand(argv[0])==1) { job_no++; addJob(0,argv[0],0,job_no); executeBuiltInCommand(argv[0],argv,no_of_tokens,homedir); dup2(std_out,1); _exit(1); } else return (execvp(argv[0],argv)); } return pid; }
int main (int argc, char const *const *argv, char const *const *envp) { char const *def = 0 ; int insist = 0, chomp = 0 ; PROG = "backtick" ; { subgetopt_t l = SUBGETOPT_ZERO ; for (;;) { register int opt = subgetopt_r(argc, argv, "eniD:", &l) ; if (opt == -1) break ; switch (opt) { case 'e' : break ; /* compat */ case 'n' : chomp = 1 ; break ; case 'i' : insist = 1 ; break ; case 'D' : def = l.arg ; break ; default : dieusage() ; } } argc -= l.ind ; argv += l.ind ; } if (argc < 2) dieusage() ; if (!argv[0][0]) dieusage() ; if (!argv[1][0]) strerr_dief1x(100, "empty block") ; { unsigned int m = 0, i = 1 ; int fd = dup(0) ; char const *newargv[argc + 15] ; char fmt[UINT_FMT] ; if (fd < 0) { if (errno != EBADF) strerr_diefu1sys(111, "dup stdin") ; } else fmt[uint_fmt(fmt, (unsigned int)fd)] = 0 ; newargv[m++] = EXECLINE_BINPREFIX "pipeline" ; newargv[m++] = "--" ; while (argv[i] && argv[i][0] != EXECLINE_BLOCK_END_CHAR && (!EXECLINE_BLOCK_END_CHAR || (argv[i][0] && argv[i][1]))) newargv[m++] = argv[i++] ; if (!argv[i]) strerr_dief1x(100, "unterminated block") ; newargv[m++] = "" ; i++ ; newargv[m++] = EXECLINE_BINPREFIX "withstdinas" ; if (insist) newargv[m++] = "-i" ; if (chomp) newargv[m++] = "-n" ; if (def) { newargv[m++] = "-D" ; newargv[m++] = def ; } newargv[m++] = "-!" ; newargv[m++] = "--" ; newargv[m++] = argv[0] ; if (fd < 0) { newargv[m++] = EXECLINE_BINPREFIX "fdclose" ; newargv[m++] = "0" ; } else { newargv[m++] = EXECLINE_BINPREFIX "fdmove" ; newargv[m++] = "0" ; newargv[m++] = fmt ; } while (argv[i]) newargv[m++] = argv[i++] ; newargv[m++] = 0 ; pathexec_run(newargv[0], newargv, envp) ; strerr_dieexec(111, newargv[0]) ; } }
int exec_cmd_node(cmd_node_t* cmd_node, client_node_t* client) { int pipe_count = cmd_node->pipe_count; int pid = -1; int input_pipe_fd = -1; int output_pipe_fd = -1; if(strcmp(cmd_node->cmd, "printenv") == 0) { char* env_name = cmd_node->args[1]; if(env_name != NULL) { char* env_val = getenv(env_name); printf("%s=%s\n", env_name, env_val); fflush(stdout); } decrease_all_pipe_node(client->pipe_list); return 0; } else if(strcmp(cmd_node->cmd, "setenv") == 0) { char* env_name = cmd_node->args[1]; char* env_val = cmd_node->args[2]; set_env_to_client_node(client, env_name, env_val); setenv(env_name, env_val, 1); decrease_all_pipe_node(client->pipe_list); return 0; } else if(strcmp(cmd_node->cmd, "exit") == 0) { char exit_msg[64]; bzero(exit_msg, 64); sprintf(exit_msg, "*** User '%s' left. ***\n", client->name); broad_cast(client, exit_msg); // clean message queues mq_clean(client->id); // remove global pipes remove_global_pipe(client->id, client->id, 0); // remove client from client list remove_client_node(client); // return logout status return -4; } else if(strcmp(cmd_node->cmd, "who") == 0) { who(client); decrease_all_pipe_node(client->pipe_list); return 0; } else if(strcmp(cmd_node->cmd, "tell") == 0) { int r = tell(client, cmd_node->args[1], cmd_node->args[2]); if(r == -1) { printf("*** Error: user #%s does not exist yet. ***\n", cmd_node->args[1]); fflush(stdout); } else { decrease_all_pipe_node(client->pipe_list); } return 0; } else if(strcmp(cmd_node->cmd, "yell") == 0) { char message[11000]; sprintf(message, "*** %s yelled ***: %s\n", client->name, cmd_node->args[1]); bzero(message, 11000); broad_cast(client, message); decrease_all_pipe_node(client->pipe_list); return 0; } else if(strcmp(cmd_node->cmd, "name") == 0) { char* name = cmd_node->args[1]; if(check_name_exist(name) == 1) { printf("*** User '%s' already exists. ***\n", name); fflush(stdout); } else { set_client_name(client->id, name); strcpy(client->name, name); char msg[40]; bzero(msg, 40); sprintf(msg, "*** User from %s/%d is named '%s'. ***\n", client->ip, client->port, client->name); broad_cast(client, msg); fflush(stdout); } decrease_all_pipe_node(client->pipe_list); return 0; } decrease_all_pipe_node(client->pipe_list); // get this process input source pipe_node_t* in_pipe_node = find_pipe_node_by_count(client->pipe_list, 0); if(in_pipe_node != NULL) { input_pipe_fd = in_pipe_node->in_fd; if(fcntl(in_pipe_node->out_fd, F_GETFD) != -1) { close(in_pipe_node->out_fd); } in_pipe_node->count--; } if(cmd_node->pipe_from_user == 1) { char data[2048]; bzero(data, 2048); int r = pull_global_pipe_data(cmd_node->from_user_id, client->id, data); if(r == -1) { inscrease_all_pipe_node(client->pipe_list); return -2; } int g_pipe[2]; pipe(g_pipe); write(g_pipe[1], r.msg, strlen(r.msg)); close(g_pipe[1]); input_pipe_fd = g_pipe[0]; } int tmp_global_pipe[2]; // get this process output source pipe_node_t* out_pipe_node = find_pipe_node_by_count(client->pipe_list, pipe_count); if(out_pipe_node != NULL) { output_pipe_fd = out_pipe_node->out_fd; } else if(cmd_node->pipe_to_file == 1){ output_pipe_fd = get_file_fd(cmd_node->filename); } else if(cmd_node->pipe_to_user == 1) { if(is_client_available(cmd_node->to_user_id) != 1) { printf("*** Error: user #%d does not exist yet. ***\n", cmd_node->to_user_id); fflush(stdout); close_unused_fd(client); return 0; } else if(is_global_pipe_exist(client->id, cmd_node->to_user_id) == 1) { close_unused_fd(client); return -3; } // global pipe // create global pipe node pipe(tmp_global_pipe); output_pipe_fd = tmp_global_pipe[1]; // broad cast message // *** (name) (#<client id>) just piped '(command line)' to (receiver's name) (#<receiver's client_id>) *** char* msg_temp = "*** %s (#%d) just piped '%s' to %s (#%d) ***\n"; char msg[128]; bzero(msg, 128); char to_client_name[30]; get_client_name(cmd_node->to_user_id, to_client_name); sprintf(msg, msg_temp, client->name, client->id, last_line, to_client_name, cmd_node->to_user_id); broad_cast(client, msg); fflush(stdout); } else if(cmd_node->pipe_count != 0) { int new_pipe_fd[2]; pipe(new_pipe_fd); out_pipe_node = malloc(sizeof(pipe_node_t)); out_pipe_node->count = cmd_node->pipe_count; out_pipe_node->in_fd = new_pipe_fd[0]; out_pipe_node->out_fd = new_pipe_fd[1]; out_pipe_node->next_node = NULL; insert_pipe_node(&(client->pipe_list), out_pipe_node); output_pipe_fd = new_pipe_fd[1]; } pid = fork(); if(pid == 0) { if(input_pipe_fd != -1) { // not use stdin close(0); dup(input_pipe_fd); close(input_pipe_fd); } // out if(out_pipe_node != NULL) { close(1); dup(out_pipe_node->out_fd); close(out_pipe_node->out_fd); } else if(cmd_node->pipe_to_file == 1) { close(1); dup(output_pipe_fd); close(output_pipe_fd); } else if(cmd_node->pipe_to_user == 1) { close(1); close(2); dup(output_pipe_fd); dup(output_pipe_fd); close(output_pipe_fd); } else { dup2(client->client_sc_fd, 1); } execvp(cmd_node->cmd, cmd_node->args); exit(-1); } else if(pipe_count != 0) { int status; wait(&status); // waitpid(pid, &status, 0); if(WEXITSTATUS(status) != 0){ inscrease_all_pipe_node(client->pipe_list); return -1; } else { if(input_pipe_fd != -1) { close(input_pipe_fd); } } } else { int status; wait(&status); // waitpid(pid, &status, 0); if(WEXITSTATUS(status) != 0){ inscrease_all_pipe_node(client->pipe_list); return -1; } else { if(in_pipe_node != NULL) { close(in_pipe_node->out_fd); in_pipe_node->count--; } if(cmd_node->pipe_to_user == 1) { if(fcntl(output_pipe_fd, F_GETFD) != -1) { close(output_pipe_fd); } char buffer[2048]; bzero(buffer, 2048); read(tmp_global_pipe[0], buffer, 2048); //printf("[DBG] Buffer:\n"); //printf("%s\n", buffer); add_global_pipe(client->id, cmd_node->to_user_id, buffer); close(tmp_global_pipe[0]); } close_unused_fd(client); } } if(cmd_node->pipe_from_user == 1) { char* msg_tmp = "*** %s (#%d) just received from %s (#%d) by '%s' ***\n"; char msg[100]; bzero(msg, 100); char from_client_name[30]; get_client_name(cmd_node->from_user_id, from_client_name); sprintf(msg, msg_tmp, client->name, client->id, from_client_name, cmd_node->from_user_id, last_line); broad_cast(client, msg); remove_global_pipe(cmd_node->from_user_id, client->id, 1); } return 0; }
static int rlimit(int keep_open) { int *tmpfd; int nitems, i; int *memchunk = NULL; char *fmt; struct rlimit rl; char strbuff[256]; char strbuff1[81]; char fmt_u[] = "%u"; char fmt_lu[] = "%lu"; #ifdef HAVE_LONGLONG char fmt_llu[] = "%llu"; if (sizeof(rl.rlim_max) > sizeof(long)) fmt = fmt_llu; else #endif fmt = (sizeof(rl.rlim_max) < sizeof(long))?fmt_u:fmt_lu; /* get initial open file limits */ if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { store_errmsg("getrlimit() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); return -1; } /* show initial open file limits */ #ifdef RLIM_INFINITY if (rl.rlim_cur == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_cur); fprintf(stderr, "initial soft limit: %s\n", strbuff); #ifdef RLIM_INFINITY if (rl.rlim_max == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_max); fprintf(stderr, "initial hard limit: %s\n", strbuff); /* * if soft limit and hard limit are different we ask the * system to raise soft limit all the way up to the hard * limit. Due to some other system limit the soft limit * might not be raised up to the hard limit. So from this * point the resulting soft limit is our limit. Trying to * open more than soft limit file descriptors will fail. */ if (rl.rlim_cur != rl.rlim_max) { fprintf(stderr, "raising soft limit up to hard limit\n"); rl.rlim_cur = rl.rlim_max; if (setrlimit(RLIMIT_NOFILE, &rl) != 0) { store_errmsg("setrlimit() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); return -2; } /* get current open file limits */ if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { store_errmsg("getrlimit() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); return -3; } /* show current open file limits */ #ifdef RLIM_INFINITY if (rl.rlim_cur == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_cur); fprintf(stderr, "current soft limit: %s\n", strbuff); #ifdef RLIM_INFINITY if (rl.rlim_max == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_max); fprintf(stderr, "current hard limit: %s\n", strbuff); } /* (rl.rlim_cur != rl.rlim_max) */ /* * test 537 is all about testing libcurl functionality * when the system has nearly exhausted the number of * available file descriptors. Test 537 will try to run * with a very small number of file descriptors available. * This implies that any file descriptor which is open * when the test runs will have a number in the high range * of whatever the system supports. */ /* * reserve a chunk of memory before opening file descriptors to * avoid a low memory condition once the file descriptors are * open. System conditions that could make the test fail should * be addressed in the precheck phase. This chunk of memory shall * be always free()ed before exiting the rlimit() function so * that it becomes available to the test. */ for (nitems = i = 1; nitems <= i; i *= 2) nitems = i; if (nitems > 0x7fff) nitems = 0x40000; do { num_open.rlim_max = sizeof(*memchunk) * (size_t)nitems; sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "allocating memchunk %s byte array\n", strbuff); memchunk = malloc(sizeof(*memchunk) * (size_t)nitems); if (!memchunk) { fprintf(stderr, "memchunk, malloc() failed\n"); nitems /= 2; } } while (nitems && !memchunk); if (!memchunk) { store_errmsg("memchunk, malloc() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); return -4; } /* initialize it to fight lazy allocation */ fprintf(stderr, "initializing memchunk array\n"); for (i = 0; i < nitems; i++) memchunk[i] = -1; /* set the number of file descriptors we will try to open */ #ifdef RLIM_INFINITY if ((rl.rlim_cur > 0) && (rl.rlim_cur != RLIM_INFINITY)) { #else if (rl.rlim_cur > 0) { #endif /* soft limit minus SAFETY_MARGIN */ num_open.rlim_max = rl.rlim_cur - SAFETY_MARGIN; } else { /* a huge number of file descriptors */ for (nitems = i = 1; nitems <= i; i *= 2) nitems = i; if (nitems > 0x7fff) nitems = 0x40000; num_open.rlim_max = nitems; } /* verify that we won't overflow size_t in malloc() */ if ((size_t)(num_open.rlim_max) > ((size_t)-1) / sizeof(*fd)) { sprintf(strbuff1, fmt, num_open.rlim_max); sprintf(strbuff, "unable to allocate an array for %s " "file descriptors, would overflow size_t", strbuff1); store_errmsg(strbuff, 0); fprintf(stderr, "%s\n", msgbuff); free(memchunk); return -5; } /* allocate array for file descriptors */ do { sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "allocating array for %s file descriptors\n", strbuff); fd = malloc(sizeof(*fd) * (size_t)(num_open.rlim_max)); if (!fd) { fprintf(stderr, "fd, malloc() failed\n"); num_open.rlim_max /= 2; } } while (num_open.rlim_max && !fd); if (!fd) { store_errmsg("fd, malloc() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); free(memchunk); return -6; } /* initialize it to fight lazy allocation */ fprintf(stderr, "initializing fd array\n"); for (num_open.rlim_cur = 0; num_open.rlim_cur < num_open.rlim_max; num_open.rlim_cur++) fd[num_open.rlim_cur] = -1; sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "trying to open %s file descriptors\n", strbuff); /* open a dummy descriptor */ fd[0] = open(DEV_NULL, O_RDONLY); if (fd[0] < 0) { sprintf(strbuff, "opening of %s failed", DEV_NULL); store_errmsg(strbuff, ERRNO); fprintf(stderr, "%s\n", msgbuff); free(fd); fd = NULL; free(memchunk); return -7; } /* create a bunch of file descriptors */ for (num_open.rlim_cur = 1; num_open.rlim_cur < num_open.rlim_max; num_open.rlim_cur++) { fd[num_open.rlim_cur] = dup(fd[0]); if (fd[num_open.rlim_cur] < 0) { fd[num_open.rlim_cur] = -1; sprintf(strbuff1, fmt, num_open.rlim_cur); sprintf(strbuff, "dup() attempt %s failed", strbuff1); fprintf(stderr, "%s\n", strbuff); sprintf(strbuff1, fmt, num_open.rlim_cur); sprintf(strbuff, "fds system limit seems close to %s", strbuff1); fprintf(stderr, "%s\n", strbuff); num_open.rlim_max = num_open.rlim_cur - SAFETY_MARGIN; num_open.rlim_cur -= num_open.rlim_max; sprintf(strbuff1, fmt, num_open.rlim_cur); sprintf(strbuff, "closing %s file descriptors", strbuff1); fprintf(stderr, "%s\n", strbuff); for (num_open.rlim_cur = num_open.rlim_max; fd[num_open.rlim_cur] >= 0; num_open.rlim_cur++) { close(fd[num_open.rlim_cur]); fd[num_open.rlim_cur] = -1; } sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "shrinking array for %s file descriptors\n", strbuff); /* we don't care if we can't shrink it */ tmpfd = realloc(fd, sizeof(*fd) * (size_t)(num_open.rlim_max)); if (tmpfd) { fd = tmpfd; tmpfd = NULL; } break; } } sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "%s file descriptors open\n", strbuff); #if !defined(HAVE_POLL_FINE) && \ !defined(USE_WINSOCK) && \ !defined(TPF) /* * when using select() instead of poll() we cannot test * libcurl functionality with a socket number equal or * greater than FD_SETSIZE. In any case, macro VERIFY_SOCK * in lib/select.c enforces this check and protects libcurl * from a possible crash. The effect of this protection * is that test 537 will always fail, since the actual * call to select() never takes place. We skip test 537 * with an indication that select limit would be exceeded. */ num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; if (num_open.rlim_max > num_open.rlim_cur) { sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE); store_errmsg(strbuff, 0); fprintf(stderr, "%s\n", msgbuff); close_file_descriptors(); free(memchunk); return -8; } num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; for (rl.rlim_cur = 0; rl.rlim_cur < num_open.rlim_max; rl.rlim_cur++) { if (fd[rl.rlim_cur] > num_open.rlim_cur) { sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE); store_errmsg(strbuff, 0); fprintf(stderr, "%s\n", msgbuff); close_file_descriptors(); free(memchunk); return -9; } } #endif /* using a FD_SETSIZE bound select() */ /* * Old or 'backwards compatible' implementations of stdio do not allow * handling of streams with an underlying file descriptor number greater * than 255, even when allowing high numbered file descriptors for sockets. * At this point we have a big number of file descriptors which have been * opened using dup(), so lets test the stdio implementation and discover * if it is capable of fopen()ing some additional files. */ if (!fopen_works()) { sprintf(strbuff1, fmt, num_open.rlim_max); sprintf(strbuff, "stdio fopen() fails with %s fds open()", strbuff1); fprintf(stderr, "%s\n", msgbuff); sprintf(strbuff, "stdio fopen() fails with lots of fds open()"); store_errmsg(strbuff, 0); close_file_descriptors(); free(memchunk); return -10; } /* free the chunk of memory we were reserving so that it becomes becomes available to the test */ free(memchunk); /* close file descriptors unless instructed to keep them */ if (!keep_open) { close_file_descriptors(); } return 0; } int test(char *URL) { CURLcode res; CURL *curl; if(!strcmp(URL, "check")) { /* used by the test script to ask if we can run this test or not */ if(rlimit(FALSE)) { fprintf(stdout, "rlimit problem: %s\n", msgbuff); return 1; } return 0; /* sure, run this! */ } if (rlimit(TRUE)) { /* failure */ return TEST_ERR_MAJOR_BAD; } /* run the test with the bunch of open file descriptors and close them all once the test is over */ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { fprintf(stderr, "curl_global_init() failed\n"); close_file_descriptors(); return TEST_ERR_MAJOR_BAD; } if ((curl = curl_easy_init()) == NULL) { fprintf(stderr, "curl_easy_init() failed\n"); close_file_descriptors(); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } curl_easy_setopt(curl, CURLOPT_URL, URL); curl_easy_setopt(curl, CURLOPT_HEADER, TRUE); res = curl_easy_perform(curl); close_file_descriptors(); curl_easy_cleanup(curl); curl_global_cleanup(); return (int)res; }
int start_command(struct child_process *cmd) { int need_in, need_out, need_err; int fdin[2], fdout[2], fderr[2]; int failed_errno = failed_errno; /* * In case of errors we must keep the promise to close FDs * that have been passed in via ->in and ->out. */ need_in = !cmd->no_stdin && cmd->in < 0; if (need_in) { if (pipe(fdin) < 0) { failed_errno = errno; if (cmd->out > 0) close(cmd->out); goto fail_pipe; } cmd->in = fdin[1]; } need_out = !cmd->no_stdout && !cmd->stdout_to_stderr && cmd->out < 0; if (need_out) { if (pipe(fdout) < 0) { failed_errno = errno; if (need_in) close_pair(fdin); else if (cmd->in) close(cmd->in); goto fail_pipe; } cmd->out = fdout[0]; } need_err = !cmd->no_stderr && cmd->err < 0; if (need_err) { if (pipe(fderr) < 0) { failed_errno = errno; if (need_in) close_pair(fdin); else if (cmd->in) close(cmd->in); if (need_out) close_pair(fdout); else if (cmd->out) close(cmd->out); fail_pipe: error("cannot create pipe for %s: %s", cmd->argv[0], strerror(failed_errno)); errno = failed_errno; return -1; } cmd->err = fderr[0]; } trace_argv_printf(cmd->argv, "trace: run_command:"); #if !defined(WIN32) && !defined(AMIGA) { int notify_pipe[2]; if (pipe(notify_pipe)) notify_pipe[0] = notify_pipe[1] = -1; fflush(NULL); cmd->pid = fork(); if (!cmd->pid) { /* * Redirect the channel to write syscall error messages to * before redirecting the process's stderr so that all die() * in subsequent call paths use the parent's stderr. */ if (cmd->no_stderr || need_err) { child_err = dup(2); set_cloexec(child_err); } set_die_routine(die_child); close(notify_pipe[0]); set_cloexec(notify_pipe[1]); child_notifier = notify_pipe[1]; atexit(notify_parent); if (cmd->no_stdin) dup_devnull(0); else if (need_in) { dup2(fdin[0], 0); close_pair(fdin); } else if (cmd->in) { dup2(cmd->in, 0); close(cmd->in); } if (cmd->no_stderr) dup_devnull(2); else if (need_err) { dup2(fderr[1], 2); close_pair(fderr); } else if (cmd->err > 1) { dup2(cmd->err, 2); close(cmd->err); } if (cmd->no_stdout) dup_devnull(1); else if (cmd->stdout_to_stderr) dup2(2, 1); else if (need_out) { dup2(fdout[1], 1); close_pair(fdout); } else if (cmd->out > 1) { dup2(cmd->out, 1); close(cmd->out); } if (cmd->dir && chdir(cmd->dir)) die_errno("exec '%s': cd to '%s' failed", cmd->argv[0], cmd->dir); if (cmd->env) { for (; *cmd->env; cmd->env++) { if (strchr(*cmd->env, '=')) putenv((char *)*cmd->env); else unsetenv(*cmd->env); } } if (cmd->preexec_cb) { /* * We cannot predict what the pre-exec callback does. * Forgo parent notification. */ close(child_notifier); child_notifier = -1; cmd->preexec_cb(); } if (cmd->git_cmd) { execv_git_cmd(cmd->argv); } else if (cmd->use_shell) { execv_shell_cmd(cmd->argv); } else { execvp(cmd->argv[0], (char *const*) cmd->argv); } /* * Do not check for cmd->silent_exec_failure; the parent * process will check it when it sees this exit code. */ if (errno == ENOENT) exit(127); else die_errno("cannot exec '%s'", cmd->argv[0]); } if (cmd->pid < 0) error("cannot fork() for %s: %s", cmd->argv[0], strerror(failed_errno = errno)); /* * Wait for child's execvp. If the execvp succeeds (or if fork() * failed), EOF is seen immediately by the parent. Otherwise, the * child process sends a single byte. * Note that use of this infrastructure is completely advisory, * therefore, we keep error checks minimal. */ close(notify_pipe[1]); if (read(notify_pipe[0], ¬ify_pipe[1], 1) == 1) { /* * At this point we know that fork() succeeded, but execvp() * failed. Errors have been reported to our stderr. */ wait_or_whine(cmd->pid, cmd->argv[0], cmd->silent_exec_failure); failed_errno = errno; cmd->pid = -1; } close(notify_pipe[0]); } #else { int fhin = 0, fhout = 1, fherr = 2; const char **sargv = cmd->argv; char **env = environ; if (cmd->no_stdin) fhin = open("/dev/null", O_RDWR); else if (need_in) fhin = dup(fdin[0]); else if (cmd->in) fhin = dup(cmd->in); if (cmd->no_stderr) fherr = open("/dev/null", O_RDWR); else if (need_err) fherr = dup(fderr[1]); else if (cmd->err > 2) fherr = dup(cmd->err); if (cmd->no_stdout) fhout = open("/dev/null", O_RDWR); else if (cmd->stdout_to_stderr) fhout = dup(fherr); else if (need_out) fhout = dup(fdout[1]); else if (cmd->out > 1) fhout = dup(cmd->out); if (cmd->env) env = make_augmented_environ(cmd->env); if (cmd->git_cmd) { cmd->argv = prepare_git_cmd(cmd->argv); } else if (cmd->use_shell) { cmd->argv = prepare_shell_cmd(cmd->argv); } #ifdef WIN32 cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env, cmd->dir, fhin, fhout, fherr); #else cmd->pid = amiga_spawnvpe(cmd->argv[0], cmd->argv, env, cmd->dir, fhin, fhout, fherr); #endif failed_errno = errno; if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT)) error("cannot spawn %s: %s", cmd->argv[0], strerror(errno)); if (cmd->env) free_environ(env); if (cmd->git_cmd) free(cmd->argv); cmd->argv = sargv; if (fhin != 0) close(fhin); if (fhout != 1) close(fhout); if (fherr != 2) close(fherr); } #endif if (cmd->pid < 0) { if (need_in) close_pair(fdin); else if (cmd->in) close(cmd->in); if (need_out) close_pair(fdout); else if (cmd->out) close(cmd->out); if (need_err) close_pair(fderr); else if (cmd->err) close(cmd->err); errno = failed_errno; return -1; } if (need_in) close(fdin[0]); else if (cmd->in) close(cmd->in); if (need_out) close(fdout[1]); else if (cmd->out) close(cmd->out); if (need_err) close(fderr[1]); else if (cmd->err) close(cmd->err); return 0; }
static void run_file(const char *filename, uid_t uid, gid_t gid) { /* Run a file by spawning off a process which redirects I/O, * spawns a subshell, then waits for it to complete and sends * mail to the user. */ pid_t pid; int fd_out, fd_in; int queue; char mailbuf[MAXLOGNAME], fmt[49]; char *mailname = NULL; FILE *stream; int send_mail = 0; struct stat buf, lbuf; off_t size; struct passwd *pentry; int fflags; long nuid; long ngid; #ifdef PAM pam_handle_t *pamh = NULL; int pam_err; struct pam_conv pamc = { .conv = openpam_nullconv, .appdata_ptr = NULL }; #endif PRIV_START if (chmod(filename, S_IRUSR) != 0) { perr("cannot change file permissions"); } PRIV_END pid = fork(); if (pid == -1) perr("cannot fork"); else if (pid != 0) return; /* Let's see who we mail to. Hopefully, we can read it from * the command file; if not, send it to the owner, or, failing that, * to root. */ pentry = getpwuid(uid); if (pentry == NULL) perrx("Userid %lu not found - aborting job %s", (unsigned long) uid, filename); #ifdef PAM PRIV_START pam_err = pam_start(atrun, pentry->pw_name, &pamc, &pamh); if (pam_err != PAM_SUCCESS) perrx("cannot start PAM: %s", pam_strerror(pamh, pam_err)); pam_err = pam_acct_mgmt(pamh, PAM_SILENT); /* Expired password shouldn't prevent the job from running. */ if (pam_err != PAM_SUCCESS && pam_err != PAM_NEW_AUTHTOK_REQD) perrx("Account %s (userid %lu) unavailable for job %s: %s", pentry->pw_name, (unsigned long)uid, filename, pam_strerror(pamh, pam_err)); pam_end(pamh, pam_err); PRIV_END #endif /* PAM */ PRIV_START stream=fopen(filename, "r"); PRIV_END if (stream == NULL) perr("cannot open input file"); if ((fd_in = dup(fileno(stream))) <0) perr("error duplicating input file descriptor"); if (fstat(fd_in, &buf) == -1) perr("error in fstat of input file descriptor"); if (lstat(filename, &lbuf) == -1) perr("error in fstat of input file"); if (S_ISLNK(lbuf.st_mode)) perrx("Symbolic link encountered in job %s - aborting", filename); if ((lbuf.st_dev != buf.st_dev) || (lbuf.st_ino != buf.st_ino) || (lbuf.st_uid != buf.st_uid) || (lbuf.st_gid != buf.st_gid) || (lbuf.st_size!=buf.st_size)) perrx("Somebody changed files from under us for job %s - aborting", filename); if (buf.st_nlink > 1) perrx("Somebody is trying to run a linked script for job %s", filename); if ((fflags = fcntl(fd_in, F_GETFD)) <0) perr("error in fcntl"); fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC); snprintf(fmt, sizeof(fmt), "#!/bin/sh\n# atrun uid=%%ld gid=%%ld\n# mail %%%ds %%d", MAXLOGNAME - 1); if (fscanf(stream, fmt, &nuid, &ngid, mailbuf, &send_mail) != 4) perrx("File %s is in wrong format - aborting", filename); if (mailbuf[0] == '-') perrx("Illegal mail name %s in %s", mailbuf, filename); mailname = mailbuf; if (nuid != uid) perrx("Job %s - userid %ld does not match file uid %lu", filename, nuid, (unsigned long)uid); if (ngid != gid) perrx("Job %s - groupid %ld does not match file gid %lu", filename, ngid, (unsigned long)gid); fclose(stream); if (chdir(ATSPOOL_DIR) < 0) perr("cannot chdir to %s", ATSPOOL_DIR); /* Create a file to hold the output of the job we are about to run. * Write the mail header. */ if((fd_out=open(filename, O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR)) < 0) perr("cannot create output file"); write_string(fd_out, "Subject: Output from your job "); write_string(fd_out, filename); write_string(fd_out, "\n\n"); fstat(fd_out, &buf); size = buf.st_size; close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); pid = fork(); if (pid < 0) perr("error in fork"); else if (pid == 0) { char *nul = NULL; char **nenvp = &nul; /* Set up things for the child; we want standard input from the input file, * and standard output and error sent to our output file. */ if (lseek(fd_in, (off_t) 0, SEEK_SET) < 0) perr("error in lseek"); if (dup(fd_in) != STDIN_FILENO) perr("error in I/O redirection"); if (dup(fd_out) != STDOUT_FILENO) perr("error in I/O redirection"); if (dup(fd_out) != STDERR_FILENO) perr("error in I/O redirection"); close(fd_in); close(fd_out); if (chdir(ATJOB_DIR) < 0) perr("cannot chdir to %s", ATJOB_DIR); queue = *filename; PRIV_START nice(tolower(queue) - 'a'); #ifdef LOGIN_CAP /* * For simplicity and safety, set all aspects of the user context * except for a selected subset: Don't set priority, which was * set based on the queue file name according to the tradition. * Don't bother to set environment, including path vars, either * because it will be discarded anyway. Although the job file * should set umask, preset it here just in case. */ if (setusercontext(NULL, pentry, uid, LOGIN_SETALL & ~(LOGIN_SETPRIORITY | LOGIN_SETPATH | LOGIN_SETENV)) != 0) exit(EXIT_FAILURE); /* setusercontext() logged the error */ #else /* LOGIN_CAP */ if (initgroups(pentry->pw_name,pentry->pw_gid)) perr("cannot init group access list"); if (setgid(gid) < 0 || setegid(pentry->pw_gid) < 0) perr("cannot change group"); if (setlogin(pentry->pw_name)) perr("cannot set login name"); if (setuid(uid) < 0 || seteuid(uid) < 0) perr("cannot set user id"); #endif /* LOGIN_CAP */ if (chdir(pentry->pw_dir)) chdir("/"); if(execle("/bin/sh","sh",(char *) NULL, nenvp) != 0) perr("exec failed for /bin/sh"); PRIV_END }
void daemonize(const char *cmd) { struct rlimit rlim; int fd0, fd1, fd2; int i; pid_t pid; struct sigaction sa; if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { printf("%s: getrlimit error: %s", cmd, strerror(errno)); exit(1); } umask(0); if ((pid = fork()) < 0) { printf("%s: fork error: %s", cmd, strerror(errno)); exit(1); } else if (pid != 0) { /* parent */ exit(0); } setsid(); /* child */ sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGHUP, &sa, NULL) < 0) { printf("%s: sigaction SIGHUP error: %s", cmd, strerror(errno)); exit(1); } if ((pid = fork()) < 0) { printf("%s: fork error: %s", cmd, strerror(errno)); exit(1); } else if (pid != 0) { /* parent again */ exit(0); } if (chdir("/") < 0) { printf("%s: chdir to / error: %s", cmd, strerror(errno)); exit(1); } /* child */ if (rlim.rlim_max == RLIM_INFINITY) rlim.rlim_max = 1024; for (i = 0; i < rlim.rlim_max; ++i) close(i); fd0 = open("/dev/null", O_RDWR); fd1 = dup(0); fd2 = dup(0); openlog(cmd, LOG_CONS, LOG_DAEMON); if (fd0 != 0 || fd1 != 1 || fd2 != 2) { syslog(LOG_ERR, "unexpected file descriptors: %d, %d, %d", fd0, fd1, fd2); exit(1); } }
int gpgdecode(int in_fd, int out_fd) { char passfd_buf[NUMBUFSIZE]; FILE *fp=passphrasefp(); int in_dup, out_dup; FILE *in_fp, *out_fp; struct libmail_gpg_info gi; char *argvec[2]; int i; gpginiterr(); if ((in_dup=dup(in_fd)) < 0 || (in_fp=fdopen(in_dup, "r")) == NULL) { if (in_dup >= 0) close(in_dup); fclose(fp); enomem(); return 1; } if ((out_dup=dup(out_fd)) < 0 || (out_fp=fdopen(out_dup, "w")) == NULL) { if (out_dup >= 0) close(out_dup); fclose(in_fp); close(in_dup); fclose(fp); enomem(); return 1; } memset(&gi, 0, sizeof(gi)); gi.gnupghome=GPGDIR; if (fp) { gi.passphrase_fd=libmail_str_size_t(fileno(fp), passfd_buf); } gi.input_func= read_fd; gi.input_func_arg= in_fp; gi.output_func= write_fd; gi.output_func_arg= out_fp; gi.errhandler_func= gpg_error_save; gi.errhandler_arg= NULL; argvec[0] = "--no-tty"; argvec[1]=NULL; gi.argc=1; gi.argv=argvec; i=libmail_gpg_decode(LIBMAIL_GPG_UNENCRYPT|LIBMAIL_GPG_CHECKSIGN, &gi); fclose(out_fp); close(out_dup); fclose(in_fp); close(in_dup); if (fp) fclose(fp); if (i) { printf("<div class=\"indent\"><pre style=\"color: red;\">"); sent_gpgerrtxt(); printf("</pre></div>\n"); } return (i); }
/*** uxp_internal_LoadPrintQueue - load the information from the print queue *** into the print queue structures for further examination and reporting/ *** querying to the user. Takes path to the printer node as the parameter, *** and returns a pointer to the print queue structure. ***/ pLprPrintQueue uxp_internal_LoadPrintQueue(char* nodepath, pSnNode nodeinfo) { pLprPrintQueue pq; int pipefd[2]; pFile fd; char* lpname; char* spoolname; pLxSession lxs; int t; char* str; int childpid; char user[32]; char filename[128]; int rank,jobid; int cnt; pLprQueueEntry e; /** Find out if this print queue is already hashed. **/ pq = (pLprPrintQueue)xhLookup(&UXP_INF.PrintQueues, nodepath); /** If not, create new entry. **/ if (!pq) { pq = (pLprPrintQueue)nmMalloc(sizeof(LprPrintQueue)); xaInit(&pq->Entries, 16); strcpy(pq->Pathname, nodepath); xhAdd(&UXP_INF.PrintQueues, pq->Pathname, (void*)pq); } /** Determine printer's name, and centrallix spool dir. **/ stAttrValue(stLookup(nodeinfo->Data,"unix_name"), NULL, &lpname, 0); stAttrValue(stLookup(nodeinfo->Data,"spool_directory"), NULL, &spoolname, 0); /** Ok, now open a pipe from the 'lpq' command. **/ socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd); if ((childpid=fork())) { /** Close the child's end of the pipe, since we don't use it in the parent **/ close(pipefd[1]); /** Open an fd to the pipe **/ fd = fdOpenFD(pipefd[0],O_RDONLY); /** Open an mtlexer session **/ lxs = mlxOpenSession(fd, MLX_F_EOL | MLX_F_EOF | MLX_F_IFSONLY); /** Read until we get "Rank" at the beginning of a line. **/ while(1) { t = mlxNextToken(lxs); if (t != MLX_TOK_STRING) { kill(childpid,SIGKILL); wait(NULL); return pq; } str = mlxStringVal(lxs,0); while ((t=mlxNextToken(lxs) != MLX_TOK_EOL && t != MLX_TOK_ERROR)); if (!strcmp(str,"Rank")) break; } /** Clean out any existing entries from our internal queue list. **/ while(pq->Entries.nItems) { nmFree(pq->Entries.Items[0],sizeof(LprQueueEntry)); xaRemoveItem(&pq->Entries,0); } /** Ok, should be one line per print job now **/ for(cnt=0;;) { /** Get rank, owner, jobid, filename **/ if (mlxNextToken(lxs) != MLX_TOK_STRING) break; rank = strtoi(mlxStringVal(lxs,0),NULL,10); if (mlxNextToken(lxs) != MLX_TOK_STRING) break; mlxCopyToken(lxs,user,32); if (mlxNextToken(lxs) != MLX_TOK_STRING) break; jobid = strtoi(mlxStringVal(lxs,0),NULL,10); if (mlxNextToken(lxs) != MLX_TOK_STRING) break; mlxCopyToken(lxs,filename,128); /** If it isn't our file, skip to eol and continue looking **/ if (strncmp(filename, spoolname, strlen(spoolname))) { while ((t=mlxNextToken(lxs) != MLX_TOK_EOL && t != MLX_TOK_ERROR)); continue; } /** Create the queue entry structure **/ e = (pLprQueueEntry)nmMalloc(sizeof(LprQueueEntry)); e->JobID = jobid; strcpy(e->User,user); e->Percent = 0; if (cnt==0) strcpy(e->Status,"Printing"); else strcpy(e->Status,"Queued"); strcpy(e->Pathname, filename); strcpy(e->Name, strrchr(filename,'/')+1); /** Get the file's size and skip to eol. **/ if (mlxNextToken(lxs) != MLX_TOK_STRING) break; e->Size = strtoi(mlxStringVal(lxs,0),NULL,10); while ((t=mlxNextToken(lxs) != MLX_TOK_EOL && t != MLX_TOK_ERROR)); /** Add entry to our queue list **/ xaAddItem(&pq->Entries, (void*)e); cnt++; } /** Wait on lpq's completion. **/ wait(NULL); } else { /** Close the parent's end of the pipe, since we don't use it in the child **/ close(pipefd[0]); /** Make the pipe lpq's standard input and output **/ close(0); close(1); close(2); dup(pipefd[1]); dup(pipefd[1]); dup(pipefd[1]); /** Execute the lpq process, exit if failed. **/ execlp("lpq","lpq","-P",lpname,NULL); _exit(0); } return pq; }
static int setup_tty(struct launcher_direct *launcher, int tty) { struct wl_event_loop *loop; struct vt_mode mode = { 0 }; struct stat buf; char tty_device[32] ="<stdin>"; int ret, kd_mode; if (tty == 0) { launcher->tty = dup(tty); if (launcher->tty == -1) { weston_log("couldn't dup stdin: %m\n"); return -1; } } else { snprintf(tty_device, sizeof tty_device, "/dev/tty%d", tty); launcher->tty = open(tty_device, O_RDWR | O_CLOEXEC); if (launcher->tty == -1) { weston_log("couldn't open tty %s: %m\n", tty_device); return -1; } } if (fstat(launcher->tty, &buf) == -1 || major(buf.st_rdev) != TTY_MAJOR || minor(buf.st_rdev) == 0) { weston_log("%s not a vt\n", tty_device); weston_log("if running weston from ssh, " "use --tty to specify a tty\n"); goto err_close; } ret = ioctl(launcher->tty, KDGETMODE, &kd_mode); if (ret) { weston_log("failed to get VT mode: %m\n"); return -1; } if (kd_mode != KD_TEXT) { weston_log("%s is already in graphics mode, " "is another display server running?\n", tty_device); goto err_close; } ioctl(launcher->tty, VT_ACTIVATE, minor(buf.st_rdev)); ioctl(launcher->tty, VT_WAITACTIVE, minor(buf.st_rdev)); if (ioctl(launcher->tty, KDGKBMODE, &launcher->kb_mode)) { weston_log("failed to read keyboard mode: %m\n"); goto err_close; } if (ioctl(launcher->tty, KDSKBMUTE, 1) && ioctl(launcher->tty, KDSKBMODE, K_OFF)) { weston_log("failed to set K_OFF keyboard mode: %m\n"); goto err_close; } ret = ioctl(launcher->tty, KDSETMODE, KD_GRAPHICS); if (ret) { weston_log("failed to set KD_GRAPHICS mode on tty: %m\n"); goto err_close; } /* * SIGRTMIN is used as global VT-acquire+release signal. Note that * SIGRT* must be tested on runtime, as their exact values are not * known at compile-time. POSIX requires 32 of them to be available. */ if (SIGRTMIN > SIGRTMAX) { weston_log("not enough RT signals available: %u-%u\n", SIGRTMIN, SIGRTMAX); ret = -EINVAL; goto err_close; } mode.mode = VT_PROCESS; mode.relsig = SIGRTMIN; mode.acqsig = SIGRTMIN; if (ioctl(launcher->tty, VT_SETMODE, &mode) < 0) { weston_log("failed to take control of vt handling\n"); goto err_close; } loop = wl_display_get_event_loop(launcher->compositor->wl_display); launcher->vt_source = wl_event_loop_add_signal(loop, SIGRTMIN, vt_handler, launcher); if (!launcher->vt_source) goto err_close; return 0; err_close: close(launcher->tty); return -1; }
int gpgdomsg(int in_fd, int out_fd, const char *signkey, const char *encryptkeys) { char *k=strdup(encryptkeys ? encryptkeys:""); int n; int i; char *p; char **argvec; FILE *passfd=NULL; char passfd_buf[NUMBUFSIZE]; struct libmail_gpg_info gi; int in_dup, out_dup; FILE *in_fp, *out_fp; gpginiterr(); if (!k) { enomem(); return 1; } if ((in_dup=dup(in_fd)) < 0 || (in_fp=fdopen(in_dup, "r")) == NULL) { if (in_dup >= 0) close(in_dup); free(k); enomem(); return 1; } if ((out_dup=dup(out_fd)) < 0 || (out_fp=fdopen(out_dup, "w")) == NULL) { if (out_dup >= 0) close(out_dup); fclose(in_fp); close(in_dup); free(k); enomem(); return 1; } passfd=passphrasefp(); n=0; for (p=k; (p=strtok(p, " ")) != NULL; p=NULL) ++n; argvec=malloc((n * 2 + 22)*sizeof(char *)); if (!argvec) { fclose(out_fp); close(out_dup); fclose(in_fp); close(in_dup); free(k); enomem(); return 1; } memset(&gi, 0, sizeof(gi)); gi.gnupghome=GPGDIR; if (passfd) { gi.passphrase_fd=libmail_str_size_t(fileno(passfd), passfd_buf); } gi.input_func= read_fd; gi.input_func_arg= in_fp; gi.output_func= write_fd; gi.output_func_arg= out_fp; gi.errhandler_func= gpg_error_save; gi.errhandler_arg= NULL; i=0; argvec[i++] = "--no-tty"; if (signkey) { argvec[i++]="--default-key"; argvec[i++]=(char *)signkey; } argvec[i++]="--always-trust"; for (p=strcpy(k, encryptkeys ? encryptkeys:""); (p=strtok(p, " ")) != NULL; p=NULL) { argvec[i++]="-r"; argvec[i++]=p; } argvec[i]=0; gi.argc=i; gi.argv=argvec; i=libmail_gpg_signencode(signkey ? 1:0, n > 0 ? LIBMAIL_GPG_ENCAPSULATE:0, &gi); free(argvec); fclose(out_fp); close(out_dup); fclose(in_fp); close(in_dup); free(k); if (passfd) fclose(passfd); return i; }
/********************************************************************* * * Program to send email */ int main (int argc, char *argv[]) { char buf[1000]; struct sockaddr_in sin; struct hostent *hp; int i, ch; unsigned long maxlines, lines; #if defined(HAVE_WIN32) SOCKET s; #else int s, r; struct passwd *pwd; #endif char *cp, *p; setlocale(LC_ALL, "en_US"); bindtextdomain("bacula", LOCALEDIR); textdomain("bacula"); my_name_is(argc, argv, "bsmtp"); maxlines = 0; while ((ch = getopt(argc, argv, "8c:d:f:h:r:s:l:?")) != -1) { switch (ch) { case '8': content_utf8 = true; break; case 'c': Dmsg1(20, "cc=%s\n", optarg); cc_addr = optarg; break; case 'd': /* set debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } Dmsg1(20, "Debug level = %d\n", debug_level); break; case 'f': /* from */ from_addr = optarg; break; case 'h': /* smtp host */ Dmsg1(20, "host=%s\n", optarg); p = strchr(optarg, ':'); if (p) { *p++ = 0; mailport = atoi(p); } mailhost = optarg; break; case 's': /* subject */ Dmsg1(20, "subject=%s\n", optarg); subject = optarg; break; case 'r': /* reply address */ reply_addr = optarg; break; case 'l': Dmsg1(20, "maxlines=%s\n", optarg); maxlines = (unsigned long) atol(optarg); break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc < 1) { Pmsg0(0, _("Fatal error: no recipient given.\n")); usage(); exit(1); } /* * Determine SMTP server */ if (mailhost == NULL) { if ((cp = getenv("SMTPSERVER")) != NULL) { mailhost = cp; } else { mailhost = "localhost"; } } #if defined(HAVE_WIN32) WSADATA wsaData; _setmode(0, _O_BINARY); WSAStartup(MAKEWORD(2,2), &wsaData); #endif /* * Find out my own host name for HELO; * if possible, get the fully qualified domain name */ if (gethostname(my_hostname, sizeof(my_hostname) - 1) < 0) { Pmsg1(0, _("Fatal gethostname error: ERR=%s\n"), strerror(errno)); exit(1); } if ((hp = gethostbyname(my_hostname)) == NULL) { Pmsg2(0, _("Fatal gethostbyname for myself failed \"%s\": ERR=%s\n"), my_hostname, strerror(errno)); exit(1); } strcpy(my_hostname, hp->h_name); Dmsg1(20, "My hostname is: %s\n", my_hostname); /* * Determine from address. */ if (from_addr == NULL) { #if defined(HAVE_WIN32) DWORD dwSize = UNLEN + 1; LPSTR lpszBuffer = (LPSTR)alloca(dwSize); if (GetUserName(lpszBuffer, &dwSize)) { sprintf(buf, "%s@%s", lpszBuffer, my_hostname); } else { sprintf(buf, "unknown-user@%s", my_hostname); } #else if ((pwd = getpwuid(getuid())) == 0) { sprintf(buf, "userid-%d@%s", (int)getuid(), my_hostname); } else { sprintf(buf, "%s@%s", pwd->pw_name, my_hostname); } #endif from_addr = bstrdup(buf); } Dmsg1(20, "From addr=%s\n", from_addr); /* * Connect to smtp daemon on mailhost. */ hp: if ((hp = gethostbyname(mailhost)) == NULL) { Pmsg2(0, _("Error unknown mail host \"%s\": ERR=%s\n"), mailhost, strerror(errno)); if (strcasecmp(mailhost, "localhost") != 0) { Pmsg0(0, _("Retrying connection using \"localhost\".\n")); mailhost = "localhost"; goto hp; } exit(1); } if (hp->h_addrtype != AF_INET) { Pmsg1(0, _("Fatal error: Unknown address family for smtp host: %d\n"), hp->h_addrtype); exit(1); } memset((char *)&sin, 0, sizeof(sin)); memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length); sin.sin_family = hp->h_addrtype; sin.sin_port = htons(mailport); #if defined(HAVE_WIN32) if ((s = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0)) < 0) { Pmsg1(0, _("Fatal socket error: ERR=%s\n"), strerror(errno)); exit(1); } #else if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { Pmsg1(0, _("Fatal socket error: ERR=%s\n"), strerror(errno)); exit(1); } #endif if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { Pmsg2(0, _("Fatal connect error to %s: ERR=%s\n"), mailhost, strerror(errno)); exit(1); } Dmsg0(20, "Connected\n"); #if defined(HAVE_WIN32) int fdSocket = _open_osfhandle(s, _O_RDWR | _O_BINARY); if (fdSocket == -1) { Pmsg1(0, _("Fatal _open_osfhandle error: ERR=%s\n"), strerror(errno)); exit(1); } int fdSocket2 = dup(fdSocket); if ((sfp = fdopen(fdSocket, "wb")) == NULL) { Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno)); exit(1); } if ((rfp = fdopen(fdSocket2, "rb")) == NULL) { Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno)); exit(1); } #else if ((r = dup(s)) < 0) { Pmsg1(0, _("Fatal dup error: ERR=%s\n"), strerror(errno)); exit(1); } if ((sfp = fdopen(s, "w")) == 0) { Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno)); exit(1); } if ((rfp = fdopen(r, "r")) == 0) { Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno)); exit(1); } #endif /* * Send SMTP headers. Note, if any of the strings have a < * in them already, we do not enclose the string in < >, otherwise * we do. */ get_response(); /* banner */ chat("HELO %s\r\n", my_hostname); chat("MAIL FROM:%s\r\n", cleanup_addr(from_addr, buf, sizeof(buf))); for (i = 0; i < argc; i++) { Dmsg1(20, "rcpt to: %s\n", argv[i]); chat("RCPT TO:%s\r\n", cleanup_addr(argv[i], buf, sizeof(buf))); } if (cc_addr) { chat("RCPT TO:%s\r\n", cleanup_addr(cc_addr, buf, sizeof(buf))); } Dmsg0(20, "Data\n"); chat("DATA\r\n"); /* * Send message header */ fprintf(sfp, "From: %s\r\n", from_addr); Dmsg1(10, "From: %s\r\n", from_addr); if (subject) { fprintf(sfp, "Subject: %s\r\n", subject); Dmsg1(10, "Subject: %s\r\n", subject); } if (reply_addr) { fprintf(sfp, "Reply-To: %s\r\n", reply_addr); Dmsg1(10, "Reply-To: %s\r\n", reply_addr); } if (err_addr) { fprintf(sfp, "Errors-To: %s\r\n", err_addr); Dmsg1(10, "Errors-To: %s\r\n", err_addr); } #if defined(HAVE_WIN32) DWORD dwSize = UNLEN + 1; LPSTR lpszBuffer = (LPSTR)alloca(dwSize); if (GetUserName(lpszBuffer, &dwSize)) { fprintf(sfp, "Sender: %s@%s\r\n", lpszBuffer, my_hostname); Dmsg2(10, "Sender: %s@%s\r\n", lpszBuffer, my_hostname); } else { fprintf(sfp, "Sender: unknown-user@%s\r\n", my_hostname); Dmsg1(10, "Sender: unknown-user@%s\r\n", my_hostname); } #else if ((pwd = getpwuid(getuid())) == 0) { fprintf(sfp, "Sender: userid-%d@%s\r\n", (int)getuid(), my_hostname); Dmsg2(10, "Sender: userid-%d@%s\r\n", (int)getuid(), my_hostname); } else { fprintf(sfp, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname); Dmsg2(10, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname); } #endif fprintf(sfp, "To: %s", argv[0]); Dmsg1(10, "To: %s", argv[0]); for (i = 1; i < argc; i++) { fprintf(sfp, ",%s", argv[i]); Dmsg1(10, ",%s", argv[i]); } fprintf(sfp, "\r\n"); Dmsg0(10, "\r\n"); if (cc_addr) { fprintf(sfp, "Cc: %s\r\n", cc_addr); Dmsg1(10, "Cc: %s\r\n", cc_addr); } if (content_utf8) { fprintf(sfp, "Content-Type: text/plain; charset=UTF-8\r\n"); Dmsg0(10, "Content-Type: text/plain; charset=UTF-8\r\n"); } get_date_string(buf, sizeof(buf)); fprintf(sfp, "Date: %s\r\n", buf); Dmsg1(10, "Date: %s\r\n", buf); fprintf(sfp, "\r\n"); /* * Send message body */ lines = 0; while (fgets(buf, sizeof(buf), stdin)) { if (maxlines > 0 && ++lines > maxlines) { Dmsg1(20, "skip line because of maxlines limit: %lu\n", maxlines); while (fgets(buf, sizeof(buf), stdin)) { ++lines; } break; } buf[sizeof(buf)-1] = '\0'; buf[strlen(buf)-1] = '\0'; if (buf[0] == '.') { /* add extra . see RFC 2821 4.5.2 */ fputs(".", sfp); } fputs(buf, sfp); fputs("\r\n", sfp); } if (lines > maxlines) { Dmsg1(10, "hit maxlines limit: %lu\n", maxlines); fprintf(sfp, "\r\n\r\n[maximum of %lu lines exceeded, skipped %lu lines of output]\r\n", maxlines, lines-maxlines); } /* * Send SMTP quit command */ chat(".\r\n"); chat("QUIT\r\n"); /* * Go away gracefully ... */ exit(0); }
int main(int argc, char *argv[]) { initShell(); //signal(SIGCHLD, SIG_IGN); //Declarations int bytes_read,no_of_tokens,no_of_commands=0,redirectFlag=0; char uname[80],homedir[256],input[1024],hostname[80],tempstr[256],cwd[256]; char *cmdline, *sentence, *line, *token,**savedTokens, **command, *cmd, *mcptr, *com; size_t length,homedirlen; pid_t childPid; //Change Shell home dir to ~ getcwd(homedir , sizeof(homedir) ); getusername(uname); homedirlen=strlen(homedir); strcpy(cwd,homedir); /* int ptr=0; for(ptr=0;ptr<=1000;ptr++) { jobs[ptr]=NULL; }*/ int exit_flag=0; while (1) { sigset_t mask, prevmask; //Initialize mask with just the SIGCHLD signal sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, &prevmask); /*block SIGCHLD, get previous mask*/ no_of_tokens=0; command=malloc ( 200 * sizeof(char)); //Number of commands there can be will be stored in 2D Array cmdline = (char *) malloc (1025 * sizeof(char)); line = (char *) malloc (1025 * sizeof(char)); cmd = (char *) malloc (1025 * sizeof(char)); savedTokens=malloc ( 100 * sizeof(char)); //Number of tokens there can be strcpy(line,"\n"); gethostname(hostname, sizeof(hostname)); getcwd(cwd , sizeof(cwd) ); //printf("PRINT THIS : %s\n",cwd+homedirlen ); //printf("CWD: %d HOMEDIR: %d\n",strlen(cwd),strlen(homedir) ); if( strncmp( cwd, homedir, homedirlen-1) == 0) // && strncmp( cwd, homedir, homedirlen-1)!=0) //If the current working directory is not ~ { strcpy(tempstr,"~"); //printf("HOME DIR IS: %s\n",tempstr ); strcat(tempstr,cwd+homedirlen); strcpy(cwd, tempstr); } int jumper=setjmp(env); printf("<%s@%s:%s>",uname,hostname,cwd ); //PROMPT getline (&line, &length+1, stdin); //PARSING: //Stage 1: Handling multiple commands: int k=0; token = strtok (line, ";"); command[k]=token; while ( token!=NULL ) { command[k]=token; token = strtok (NULL,";"); k++; } no_of_commands=k-1; if(no_of_commands==-1) { printf("Exiting main shell!\n"); printf("\n"); return 0; } else if(command[no_of_commands]!=NULL) { int len=strlen(command[no_of_commands]); command[no_of_commands][len-1]=0; //Last token gets an extra \n .. therefore removed here. } //STAGE 2: for(k=0;k<=no_of_commands;k++) { /* sigset_t mask, prevmask; //Initialize mask with just the SIGCHLD signal sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, &prevmask); /*block SIGCHLD, get previous mask*/ cmdline = command[k]; com = (char *) malloc (1025 * sizeof(char)); if(command[k]!=NULL) strcpy(com,command[k]); //com stores the whole command to be executed else com=NULL; //Stage 3: Piping int no_of_pipes=0; if(com!=NULL) { redirectFlag=isRedirect(com); no_of_pipes=isPipeJob(com); } if(no_of_pipes!=0) { int status; pid_t procid=fork(); if(procid==0) { executePipe(no_of_pipes,com,redirectFlag,homedir); } else { sigprocmask(SIG_SETMASK, &prevmask, NULL); //Unblocking wait(&status); } } else { int i=0; token = strtok(cmdline,">"); token = strtok(cmdline,"<"); token = strtok(cmdline," \t\n"); if(token==NULL) { no_of_commands=-1; } while(token != NULL) { savedTokens[i]=token; i++; token = strtok (NULL, " \t\n"); } if(i!=0) { no_of_tokens=i-1; cmd=savedTokens[0]; } else { no_of_tokens=0; cmd=NULL; } int len=0; if(savedTokens[no_of_tokens]!=NULL) { len=strlen(savedTokens[no_of_tokens]); } //savedTokens[no_of_tokens][len-1]=0; //Last token gets an extra \n .. therefore removed here. //if ((cmd!=NULL) && ((strcmp("exit",cmd)==0) || (strcmp("Exit",cmd)==0) || (strcmp("exit ",cmd)==0) || (strcmp("Exit ",cmd)==0))) if ((cmd!=NULL) && ((strcmp("quit",cmd)==0) || (strcmp("quit ",cmd)==0) || (strcmp(" quit",cmd)==0))) { //exit(1); exit_flag=1; break; } /*int j=0; while(j<=no_of_tokens) { printf("TOKEN %d: %s\n",j,savedTokens[j]); j++; } */ //record command in history list (GNU readline history ?) int std_out; if(no_of_commands!=-1) { if ( (cmd!=NULL) && isBuiltInCommand(cmd)==1 ) { if(redirectFlag!=0) { executeRedirect(cmd,com,redirectFlag); } if(outfile!=0) { int fd1; if(outfile==1) { fd1=open(output,O_CREAT|O_RDWR|O_TRUNC,00666); lseek(fd1, 0, SEEK_SET); } else if(outfile==2) { fd1=open(output,O_APPEND|O_CREAT|O_RDWR,00666); } if(fd1==-1) { fprintf(stderr, "Can't open file %s for output!\n",output); memset(output, 0, 10); outfile=0; continue; } std_out=dup(1); dup2(fd1,STDOUT_FILENO); close(fd1); memset(output, 0, 10); outfile=0; } if(infile==3) { int fd2; fd2=open(inputfile,O_RDWR,00666); if(fd2==-1) { fprintf(stderr, "Can't open file for input! 4\n"); memset(inputfile, 0, 10); infile=0; continue; } dup2(fd2,STDIN_FILENO); close(fd2); memset(inputfile, 0, 10); infile=0; } job_no++; addJob(0,cmd,0,job_no); executeBuiltInCommand(cmd,savedTokens,no_of_tokens,homedir); dup2(std_out,1); } else { if((com!=NULL) && isBackgroundJob(com)==1) { savedTokens[no_of_tokens]=NULL; } int status; childPid = fork(); switch (childPid) { case 0: //Child Process //setpgid(0,0); //make the current process the group leader //tcsetpgrp(0,getpid()); if(redirectFlag!=0) { executeRedirect(cmd,com,redirectFlag); } if(outfile!=0) { int fd1; if(outfile==1) { fd1=open(output,O_CREAT|O_RDWR|O_TRUNC,00666); lseek(fd1, 0, SEEK_SET); } else if(outfile==2) { fd1=open(output,O_APPEND|O_CREAT|O_RDWR,00666); } if(fd1==-1) { fprintf(stderr, "Can't open file for output 6!\n"); memset(output, 0, 10); outfile=0; continue; } dup2(fd1,STDOUT_FILENO); close(fd1); memset(output, 0, 10); outfile=0; } if(infile==3) { int fd2; printf("%s\n",inputfile); fd2=open(inputfile,O_RDWR,00666); if(fd2==-1) { fprintf(stderr, "Can't open file for input! 5\n"); memset(inputfile, 0, 10); infile=0; continue; } dup2(fd2,STDIN_FILENO); close(fd2); memset(inputfile, 0, 10); infile=0; } executeCommand(cmd,savedTokens,no_of_tokens); //calls execvp /* if exec returns there was an error. */ perror(savedTokens[0]); exit(-1); case -1: perror("Fork"); return -1; default: //In Parent sigprocmask(SIG_SETMASK, &prevmask, NULL); //Unblocking //handler(childPid,cmd,job_no,jobs); //Check if any of the childs exited if (isBackgroundJob(com)==1) { setpgid(childPid,childPid); //added the background process to its own group //tcsetpgrp(0,childPid); savedTokens[no_of_tokens]=NULL; // add pid to some list to track jobs job_no++; printf("[%d][proc %d started]\n",job_no, childPid); addJob(childPid,cmd,1,job_no); // sigprocmask(SIG_SETMASK, &prevmask, NULL); //Unblocking } else { //Add foreground jobs to list: job_no++; //printf("Parent: Here total jobs are %d \n",job_no ); addJob(childPid,cmd,0,job_no); curpid=childPid; // printf("jobs[%d]->cmd: %s\n",job_no,jobs[job_no]->cmd); sigprocmask(SIG_SETMASK, &prevmask, NULL); //Unblocking pid_t wpid; do { wpid = waitpid(childPid, &status, WUNTRACED); //WUNTRACED->status of child processes will be reported here! } while (!WIFEXITED(status) && !WIFSIGNALED(status)); //WIFEXITED reports normal termination and //WIFSIGNALED not 0 status if child process stopped but wasnt caught! removeJob(wpid); curpid=getpid(); //printf("I am removing the fg job with pid %d\n",wpid ); //waitpid (childPid); //printf("HERE! 2\n" ); } } } } } }//end of k loop if(exit_flag==1) break; //free(line); // } //End of while loop return 0; }
int executePipe( int no_of_pipes, char *com, int redirectFlag,char *homedir) { pc *pcmd=malloc(100 * sizeof(pc)); int fd[2]; int isFirstPipe=1; int count = 0; char *commandline=malloc(1024*sizeof(char)); strcpy(commandline,com); char *command=malloc(1024*sizeof(char)); char **argv=malloc ( 100 * sizeof(char)); //Number of tokens there can be char *token=malloc(1024*sizeof(char)); int i=0,j=0; command = strtok ( com,"|"); //first command while( command!=NULL) { pcmd[i].argv=command; pcmd[i].redirectFlag=isRedirect(command); command = strtok (NULL, "|"); i++; } //Tokenise command for execution //parseCommand(pcmd[0].argv,argv); int in=0; for(i=0;i<no_of_pipes;i++) { pipe(fd); spawn_proc(in,fd[1],pcmd[i],pcmd[i].redirectFlag,homedir); close(fd[1]); in=fd[0]; } if(in!=0) dup2(in,0); //last command infile=0; outfile=0; int random=isRedirect(pcmd[i].argv); int no_of_tokens=parseCommand(pcmd[i].argv,argv,pcmd[i].redirectFlag); int std_out=dup(1); if(outfile!=0) { int fd1; if(outfile==1) { fd1=open(output,O_CREAT|O_RDWR|O_TRUNC,00666); lseek(fd1, 0, SEEK_SET); } else if(outfile==2) { fd1=open(output,O_APPEND|O_CREAT|O_RDWR,00666); } if(fd1==-1) { fprintf(stderr, "Can't open file for output 1!\n"); memset(output, 0, 10); outfile=0; return; } dup2(fd1,STDOUT_FILENO); close(fd1); memset(output, 0, 10); outfile=0; //redirectFlag=0; } if(infile==3) { int fd2; fd2=open(inputfile,O_RDWR,00666); if(fd2==-1) { fprintf(stderr, "Can't open file for input! 3\n"); memset(inputfile, 0, 10); infile=0; return; } dup2(fd2,STDIN_FILENO); close(fd2); memset(inputfile, 0, 10); infile=0; //redirectFlag=0; } if(isBuiltInCommand(argv[0])==1) { job_no++; addJob(0,argv[0],0,job_no); executeBuiltInCommand(argv[0],argv,no_of_tokens,homedir); _exit(1); dup2(std_out,1); return(0); } else return(execvp(argv[0],argv)); }
int sourceFile (char const *filename, char const *envProg, char const *envArg) /* 002 */ { extern char **globalArgv; if ('\0' == *filename) { return(0); } else { char script[512]; MYtmpFile(script, "sirea"); FILE *file = NULL; if (NULL == (file = fopen(script, "w"))) { return(-1); } else { static char buff[2048]; // Working space !! Fixed size space !! char *shell; // Name of the shell char *q; // Transient pointer char const *scriptText; // Right - First off lets try and figure out what kind of shell // we are using ! // Get the name of the shell executable buff[0] = '\0'; // Working space !! Fixed size space !! shell = buff; q = (char*)Tenv::appGet("SHELL"); if (NULL != q) { // Strip out the first space separated token from ${SHELL} while (isspace(*q)) q++; while (!isspace(*q) && ('\0' != *q)) *(shell++) = *(q++); *(shell++) = '\0'; // Strip out the program name (no suffix) shell = buff; if (NULL != (q = (char*)strrchr(shell, '\\'))) shell = q+1; if (NULL != (q = (char*)strrchr(shell, '/'))) shell = q+1; // Strip off the suffix if (NULL != (q = (char*)strchr(shell, '.'))) *q = '\0'; } // Get the script to run the correct shell fprintf(file, "#!%s\n\n", Tenv::appGet("SHELL")); if (NULL != (scriptText = findTempl(shell))) // 005 { //// Template shell script definition //// // Run the command fprintf(file, scriptText, filename, SIRE_ENV_TAG, envProg, envArg); } else if (!strncmp(shell, CSH_NAME, sizeof(CSH_NAME)-1)) { //// C shell script //// // Run the command fprintf(file, "source %s\n\n", filename); fprintf(file, "echo '%s'\n\n", SIRE_ENV_TAG); fprintf(file, "%s %s\n\n", envProg, envArg); } else if ((!strncmp(shell, SH_NAME, sizeof(SH_NAME)-1)) || (!strncmp(shell, KSH_NAME, sizeof(KSH_NAME)-1)) || (!strncmp(shell, RKSH_NAME, sizeof(RKSH_NAME)-1)) || (!strncmp(shell, BASH_NAME, sizeof(BASH_NAME)-1))) { //// Bourn/Korn shell script //// fprintf(file, ". %s\n", filename); fprintf(file, "echo '%s'\n\n", SIRE_ENV_TAG); fprintf(file, "%s %s\n\n", envProg, envArg); } else { // Unknown script type printE("Unsupported shell [%s]\n", shell); fclose(file); unlink (script); return(1); //// BAILING OUT //// } fclose(file); chmod (script, S_IRWXU | S_IRWXG); Tenv::appUnsetStd(); // Right I admit it this is cut and paste with a bit re-hacking // Run the script and capture the environment variable settings // that 'sirenv' passes back. { char buff[1024]; int pipes[2]; if (0 == pipe(pipes)) { char *p; FILE *fd; int tmpStd = -1; // Configure the pipes for the sub-process tmpStd = dup(1); // Take a copy of standard out dup2(pipes[1], 1); // Make the pipe standard out close(pipes[1]); // Spawn the sub process MYspawnve(MY_NOWAIT, script, (const char**)globalArgv, Tenv::appGetEnvp()); // Reset the pipes dup2(tmpStd, 1); // Put back standard out close(tmpStd); // Close the spare copy fd = fdopen(pipes[0], "r"); // Read the other end while (NULL != (p = fgets(buff, sizeof(buff), fd))) { while (isspace(*p)) p++; if ('\0' == *p) { // Pass through the blank lines printf("%s", buff); } else if (!strncmp(p, SIRE_ENV_TAG, sizeof(SIRE_ENV_TAG)-1)) { // Read the environment // The tag marks the start of the environment // Clear any output fflush(stdout); // Read the environment Tenv::setApp(fd); } else { // Pass through any other output printf("%s", buff); } } fclose(fd); } } unlink (script); } } return (0); }
//This is the main loop that runs the shell and takes in the commands int main(int argc, char const *argv[]) { char *input; pid_t childpid, pipeChild; int status, execStatus, commandTwo; int runInBG = 0, redirToFile = 0, pipefd[2]; struct sigaction childFinished; childFinished.sa_sigaction = endSignal; input = malloc(sizeof(char)*50); printf("Welcome to MaSh, enter a command.\n"); printf(">"); fgets(input,50,stdin); sigaction(SIGCHLD, &childFinished, NULL); while(strcmp(input,"exit\n") != 0) { runInBG = 0; redirToFile = 0; commandTwo = 0; char **args = calloc(10,sizeof(char*)); //parse user input into argument array status = parseInput(input,args); if (status > 1) runInBG = runInBackground(args,status); if (status > 2) redirToFile = redirectToFromFile(runInBG,args,status, &commandTwo); childpid = fork(); if (childpid >= 0) { //fork success if (childpid == 0) { if (redirToFile == 1) { execStatus = writeOptToFile(runInBG,args,status); } else if (redirToFile == 2) { execStatus = readIptFromFile(runInBG,args,status); } else if (redirToFile == 3) { //create pipe if (pipe(pipefd) == -1) { printf("Pipe failed.\n"); } pipeChild = fork(); if (pipeChild >= 0) { //read from the pipe if (pipeChild == 0) { close(1); dup(pipefd[1]); close(pipefd[0]); execStatus = execvp(*args,args); exit(0); } //write to the pipe else { close(0); dup(pipefd[0]); close(pipefd[1]); execStatus = execvp(args[commandTwo],args+commandTwo); } } else { perror("Fork failed."); exit(-1); } } else { //this is supposed to make the output of commands not appear on screen, it doesnt work though if (runInBG == 1) { setpgid(0,0); } execStatus = execvp(*args,args); } if (execStatus < 0) { printf("Command \"%s\" not found.\n", input); } exit(0); } else { //may not need to do this if (runInBG == 1) { waitpid(-1,&status,WNOHANG | WUNTRACED); runInBG = 0; } else waitpid(childpid,&status,0); } } else { printf("Fork failed.\n"); } printf(">"); fgets(input,50,stdin); free(args); } kill(childpid,SIGKILL); printf("logout\n"); printf("\n"); printf("[Process completed]\n"); exit(0); }
Tpipe::Tpipe(char const *comm, int read, Tenv *env) : Dnext(Dhead), Dscript("") { Dhead = this; Dpid = -1; Dfd = NULL; if (DsetClear) {DsetClear = FALSE; atexit(Tpipe::clear);} while (isspace(*comm)) comm++; int pipes[2]; Dscript = makeScript(comm); if ((0 != strlen(comm)) && (0 == pipe(pipes))) { char **localEnv; char *(argv[2]); int tmpStd = -1; if (read) { tmpStd = dup(1); // Take a copy of standard out dup2(pipes[1], 1); // Make the pipe standard out close(pipes[1]); } else { tmpStd = dup(1); // Take a copy of standard in dup2(pipes[0], 0); // Make the pipe standard in close(pipes[0]); } // Get the environment if (NULL == env) localEnv = Tenv::appGetEnvp(); else localEnv = env->getEnvp(); // Set up the arguments to the call argv[0] = (char*)malloc(strlen((char const*)Dscript)+1); strcpy(argv[0], (char const*)Dscript); argv[1] = NULL; // Spawn the sub process Dpid = MYspawnve(MY_NOWAIT, (char*)(char const*)Dscript, (const char**)argv, localEnv); // Free the allocated space free(argv[0]); if (read) { dup2(tmpStd, 1); // Put back standard out close(tmpStd); // Close the spare copy Dfd = fdopen(pipes[0], "r"); // Read the other end } else { dup2(tmpStd, 0); // Put back standard in close(tmpStd); // Close the spare copy Dfd = fdopen(pipes[1], "w"); // Write the other end } } }
static int do_test (void) { /* fdopendir takes over the descriptor, make a copy. */ int dupfd = dup (dir_fd); if (dupfd == -1) { puts ("dup failed"); return 1; } if (lseek (dupfd, 0, SEEK_SET) != 0) { puts ("1st lseek failed"); return 1; } /* The directory should be empty safe the . and .. files. */ DIR *dir = fdopendir (dupfd); if (dir == NULL) { puts ("fdopendir failed"); return 1; } struct dirent64 *d; while ((d = readdir64 (dir)) != NULL) if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0) { printf ("temp directory contains file \"%s\"\n", d->d_name); return 1; } closedir (dir); /* Try to create a file. */ int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666); if (fd == -1) { if (errno == ENOSYS) { puts ("*at functions not supported"); return 0; } puts ("file creation failed"); return 1; } write (fd, "hello", 5); puts ("file created"); struct stat64 st1; if (fstat64 (fd, &st1) != 0) { puts ("fstat64 failed"); return 1; } close (fd); struct timeval tv[2]; tv[0].tv_sec = st1.st_atime + 1; tv[0].tv_usec = 0; tv[1].tv_sec = st1.st_mtime + 1; tv[1].tv_usec = 0; if (futimesat (dir_fd, "some-file", tv) != 0) { puts ("futimesat failed"); return 1; } struct stat64 st2; if (fstatat64 (dir_fd, "some-file", &st2, 0) != 0) { puts ("fstatat64 failed"); return 1; } if (st2.st_mtime != tv[1].tv_sec #ifdef _STATBUF_ST_NSEC || st2.st_mtim.tv_nsec != 0 #endif ) { puts ("stat shows different mtime"); return 1; } if (unlinkat (dir_fd, "some-file", 0) != 0) { puts ("unlinkat failed"); return 1; } close (dir_fd); return 0; }
int main (int argc, char* argv[]) { int x; for(x=0; x<argc; x++) { printf("> %s", argv[x]); } int params_size = argc; if (strcmp(argv[argc - 2], ">") == 0 || strcmp(argv[argc - 2], "2>") == 0 || strcmp(argv[argc - 2], "<") == 0 || strcmp(argv[argc - 2], ">>") == 0) { params_size -= 2; } char ** params = malloc(sizeof(char *) * params_size); int i; if (argc < 2) { printf("Error! You didn't enter command!\n"); exit(2); } params[0] = argv[1]; for (i = 2; i < params_size; ++i) { params[i - 1] = argv[i]; } params[params_size - 1] = NULL; int status; printf("\nTerminal pid: %d\n", getppid()); printf("labbash pid: %d\tParent pid: %d\n\n", getpid(), getppid()); int pid = fork(); if (pid < 0) { perror("fork"); exit(1); } if (pid == 0) { printf("\nlabbash subprocess pid: %d\tParent pid: %d\n\n", getpid(), getppid()); int fd; if (strcmp(argv[argc - 2], ">") == 0) { close(1); fd = open(argv[argc -1], O_CREAT | O_RDWR, 0644); dup(fd); } else if (strcmp(argv[argc - 2], "2>") == 0) { close(2); fd = open(argv[argc -1], O_CREAT | O_RDWR, 0644); dup(fd); } else if (strcmp(argv[argc - 2], "<") == 0) { close(0); fd = open(argv[argc -1], O_RDONLY, 0644); dup(fd); } else if (strcmp(argv[argc - 2], ">>") == 0) { close(1); fd = open(argv[argc -1], O_APPEND | O_RDWR, 0644); dup(fd); } perror("Test error stream\n"); if (execvp(params[0], params) < 0) { perror("exec() error: "); } close(fd); } else { wait(&status); // while(1) // if(wait(&status)!=EINTR) break; } free(params); return 0; }
/*ARGSUSED*/ int main (int argc, char **argv) { #ifndef USE_PAM const char *env; #endif /* !USE_PAM */ char **envp = environ; TERMIO termio; int err = 0; #ifdef USE_TERMIO ioctl (0, TCGETA, &termio); termio.c_iflag |= (ICRNL | IXON); termio.c_oflag |= (OPOST | ONLCR); termio.c_cflag |= (CREAD); termio.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK); ioctl (0, TCSETAF, &termio); #endif #ifdef USE_TERMIOS tcgetattr (0, &termio); termio.c_iflag |= (ICRNL | IXON); termio.c_oflag |= (CREAD); termio.c_lflag |= (ECHO | ECHOE | ECHOK | ICANON | ISIG); tcsetattr (0, TCSANOW, &termio); #endif Prog = Basename (argv[0]); (void) setlocale (LC_ALL, ""); (void) bindtextdomain (PACKAGE, LOCALEDIR); (void) textdomain (PACKAGE); #ifdef USE_SYSLOG OPENLOG ("sulogin"); #endif initenv (); if (argc > 1) { close (0); close (1); close (2); if (open (argv[1], O_RDWR) >= 0) { dup (0); dup (0); } else { #ifdef USE_SYSLOG SYSLOG (LOG_WARN, "cannot open %s\n", argv[1]); closelog (); #endif exit (1); } } if (access (PASSWD_FILE, F_OK) == -1) { /* must be a password file! */ (void) puts (_("No password file")); #ifdef USE_SYSLOG SYSLOG (LOG_WARN, "No password file\n"); closelog (); #endif exit (1); } #if !defined(DEBUG) && defined(SULOGIN_ONLY_INIT) if (getppid () != 1) { /* parent must be INIT */ #ifdef USE_SYSLOG SYSLOG (LOG_WARN, "Pid == %d, not 1\n", getppid ()); closelog (); #endif exit (1); } #endif if ((isatty (0) == 0) || (isatty (1) == 0) || (isatty (2) == 0)) { #ifdef USE_SYSLOG closelog (); #endif exit (1); /* must be a terminal */ } /* If we were init, we need to start a new session */ if (getppid() == 1) { setsid(); if (ioctl(0, TIOCSCTTY, 1) != 0) { (void) fputs (_("TIOCSCTTY failed"), stderr); } } while (NULL != *envp) { /* add inherited environment, */ addenv (*envp, NULL); /* some variables change later */ envp++; } #ifndef USE_PAM env = getdef_str ("ENV_TZ"); if (NULL != env) { addenv (('/' == *env) ? tz (env) : env, NULL); } env = getdef_str ("ENV_HZ"); if (NULL != env) { addenv (env, NULL); /* set the default $HZ, if one */ } #endif /* !USE_PAM */ (void) strcpy (name, "root"); /* KLUDGE!!! */ (void) signal (SIGALRM, catch_signals); /* exit if the timer expires */ (void) alarm (ALARM); /* only wait so long ... */ while (true) { /* repeatedly get login/password pairs */ char *cp; pw_entry (name, &pwent); /* get entry from password file */ if (pwent.pw_name == (char *) 0) { /* * Fail secure */ (void) puts (_("No password entry for 'root'")); #ifdef USE_SYSLOG SYSLOG (LOG_WARN, "No password entry for 'root'\n"); closelog (); #endif exit (1); } /* * Here we prompt for the root password, or if no password * is given we just exit. */ /* get a password for root */ cp = getpass (_( "\n" "Type control-d to proceed with normal startup,\n" "(or give root password for system maintenance):")); /* * XXX - can't enter single user mode if root password is * empty. I think this doesn't happen very often :-). But * it will work with standard getpass() (no NULL on EOF). * --marekm */ if ((NULL == cp) || ('\0' == *cp)) { #ifdef USE_SYSLOG SYSLOG (LOG_INFO, "Normal startup\n"); closelog (); #endif (void) puts (""); #ifdef TELINIT execl (PATH_TELINIT, "telinit", RUNLEVEL, (char *) 0); #endif exit (0); } else { STRFCPY (pass, cp); strzero (cp); } if (valid (pass, &pwent)) { /* check encrypted passwords ... */ break; /* ... encrypted passwords matched */ } #ifdef USE_SYSLOG SYSLOG (LOG_WARN, "Incorrect root password\n"); #endif sleep (2); (void) puts (_("Login incorrect")); } strzero (pass); (void) alarm (0); (void) signal (SIGALRM, SIG_DFL); environ = newenvp; /* make new environment active */ (void) puts (_("Entering System Maintenance Mode")); #ifdef USE_SYSLOG SYSLOG (LOG_INFO, "System Maintenance Mode\n"); #endif #ifdef USE_SYSLOG closelog (); #endif /* exec the shell finally. */ err = shell (pwent.pw_shell, (char *) 0, environ); return ((err == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC); }
int main(int argc, char **argv) { int fpStdout; int fpStdin; char *cp; char c; int pos = -1; char *progname; int nBuf, p; char ca[1024]; char *title = ""; char *name = "iSelect"; int stripco = FALSE; int stripws = FALSE; int resultline = FALSE; int keyresultline = FALSE; int browsealways = FALSE; int allselectable = FALSE; int multiselect = FALSE; int exitnoselect = FALSE; int i; char *keystr; char *abortstr = NULL; char *tagbegin = "<"; char *tagend = ">"; /* * argument handling */ /* canonicalize program name */ if ((cp = strrchr(argv[0], '/')) != NULL) progname = cp+1; else progname = argv[0]; argv[0] = progname; /* parse the option arguments */ opterr = 0; while ((c = getopt_long(argc, argv, "d:cfaep:k:mn:t:SPKQ:Vh", options, NULL)) != (char)(-1)) { if (optarg == NULL) optarg = "(null)"; switch (c) { case 'd': tagbegin = strdup(optarg); if ((cp = strchr(tagbegin, ',')) == NULL) { fprintf(stderr, "iSelect: bad argument to option '%c'\n", optopt); fprintf(stderr, "Try `%s --help' for more information.\n", progname); exit(EX_USAGE); } *cp++ = NUL; tagend = cp; break; case 'c': stripco = TRUE; break; case 'f': browsealways = TRUE; break; case 'a': allselectable = TRUE; break; case 'e': exitnoselect = TRUE; break; case 'p': pos = atoi(optarg); break; case 'k': configure_custom_key(optarg); break; case 'm': multiselect = TRUE; break; case 'n': name = strdup(optarg); break; case 't': title = strdup(optarg); break; case 'S': stripws = TRUE; break; case 'P': resultline = TRUE; break; case 'K': keyresultline = TRUE; break; case 'Q': abortstr = strdup(optarg); break; case 'V': give_version(progname); exit(EX_OK); case 'h': give_usage(progname); exit(EX_OK); case '?': fprintf(stderr, "iSelect: invalid option: '%c'\n", optopt); fprintf(stderr, "Try `%s --help' for more information.\n", progname); exit(EX_USAGE); case ':': fprintf(stderr, "iSelect: missing argument to option '%c'\n", optopt); fprintf(stderr, "Try `%s --help' for more information.\n", progname); exit(EX_USAGE); } } /* * read input */ if (optind < argc) { /* browsing text is given as arguments */ nBuf = 0; for (; optind < argc; ++optind) { cp = (argv[optind] == NULL ? "" : argv[optind]); sprintf(caBuf+nBuf, "%s\n", cp); nBuf += strlen(cp)+1; } caBuf[nBuf++] = NUL; } else if (optind == argc && !feof(stdin)) { /* browsing text is given on stdin */ nBuf = 0; while ((c = fgetc(stdin)) != (char)(EOF)) { caBuf[nBuf++] = c; } caBuf[nBuf++] = NUL; /* save stdin filehandle and reconnect it to tty */ fpStdin = dup(0); close(0); open("/dev/tty", O_RDONLY); } else { give_usage(progname); exit(EX_USAGE); } /* * preserve stdout filehandle for result string, i.e. * use the terminal directly for output */ fpStdout = dup(1); close(1); open("/dev/tty", O_RDWR); pos = (pos < 1 ? 1 : pos); p = iSelect(caBuf, pos-1, title, name, tagbegin, tagend, stripco, stripws, browsealways, allselectable, multiselect, exitnoselect, &keystr); /* * give back the result string to the user via * the stdout file handle */ if (p != -1) { for (i = 0; i < nLines; i++) { if (spaLines[i]->fSelected) { if (resultline) { sprintf(ca, "%d:", i+1); write(fpStdout, ca, strlen(ca)); } if (keyresultline) { sprintf(ca, "%s:", keystr); write(fpStdout, ca, strlen(ca)); } write(fpStdout, spaLines[i]->cpResult, strlen(spaLines[i]->cpResult)); sprintf(ca, "\n"); write(fpStdout, ca, strlen(ca)); } } } else { if (abortstr != NULL) write(fpStdout, abortstr, strlen(abortstr)); } exit(0); }
int CoreAudio_init(output_CoreAudio *self, PyObject *args, PyObject *kwds) { long sample_rate; int channels; int channel_mask; int bits_per_sample; self->ao = NULL; self->closed = 1; if (!PyArg_ParseTuple(args, "liii", &sample_rate, &channels, &channel_mask, &bits_per_sample)) return -1; if ((bits_per_sample != 8) && (bits_per_sample != 16) && (bits_per_sample != 24)) { PyErr_SetString(PyExc_ValueError, "bits_per_sample must be 8, 16 or 24"); return -1; } self->ao = malloc(sizeof(audio_output_t)); if (init_coreaudio(self->ao, sample_rate, channels, bits_per_sample / 8, 1)) { PyErr_SetString(PyExc_ValueError, "error initializing CoreAudio"); return -1; } else { PyObject* os_module_obj; PyObject* devnull_obj; char* devnull; int current_stdout; int devnull_stdout; int returnval; /*because CoreAudio loves spewing text to stdout at init-time, we'll need to temporarily redirect stdout to /dev/null*/ /*first, determine the location of /dev/null from os.devnull*/ if ((os_module_obj = PyImport_ImportModule("os")) == NULL) { return -1; } if ((devnull_obj = PyObject_GetAttrString(os_module_obj, "devnull")) == NULL) { Py_DECREF(os_module_obj); return -1; } if ((devnull = PyString_AsString(devnull_obj)) == NULL) { Py_DECREF(os_module_obj); Py_DECREF(devnull_obj); return -1; } /*open /dev/null*/ if ((devnull_stdout = open(devnull, O_WRONLY | O_TRUNC)) == -1) { Py_DECREF(os_module_obj); Py_DECREF(devnull_obj); PyErr_SetFromErrno(PyExc_IOError); return -1; } else { /*close unneeded Python objects once descriptor is open*/ Py_DECREF(os_module_obj); Py_DECREF(devnull_obj); } /*swap file descriptors*/ current_stdout = dup(STDOUT_FILENO); dup2(devnull_stdout, STDOUT_FILENO); /*initialize CoreAudio itself*/ if (self->ao->open(self->ao)) { PyErr_SetString(PyExc_ValueError, "error opening CoreAudio"); returnval = -1; } else { self->closed = 0; returnval = 0; } /*close /dev/null and swap file descriptors back again*/ dup2(current_stdout, STDOUT_FILENO); close(current_stdout); close(devnull_stdout); return returnval; } }
int main(int argc, char **argv) { signal(SIGTSTP, sig_handler); signal(SIGINT, sig_handler); char command_line[50] = "NULL"; char command_line2[50] = "NULL"; char* args[99]; char* args2[99]; char* prompt = "Han-2.0-->"; int exitLoop = 0; int i = 0; int j = 1; int index = 0; int index2 = 0; int buildIn = 0; int runInBackGround = 0; int redirection = 0; int isPipe = 0; pid_t pid = 0; char fileName[20]; printf(" __ __ _ \n"); printf("/ / /\\ \\ \\___| | ___ ___ _ __ ___ ___\n"); printf("\\ \\/ \\/ / _ \\ |/ __/ _ \\| '_ ` _ \\ / _ \\\n"); printf(" \\ /\\ / __/ | (_| (_) | | | | | | __/\n"); printf(" \\/ \\/ \\___|_|\\___\\___/|_| |_| |_|\\___|\n"); printf(" __ __ __ __ __ __\n"); printf("/ _\\ /\\ /\\/ / / _\\ /\\ /\\/__\\/ / / /\n"); printf("\\ \\ / /_/ / / \\ \\ / /_/ /_\\ / / / /\n"); printf("_\\ \\/ __ / /___ _\\ \\/ __ //__/ /___/ /__\n"); printf("\\__/\\/ /_/\\____/ \\__/\\/ /_/\\__/\\____/\\____/\n"); printf("version 2.0\n"); while (exitLoop == 0) { for (i = 0; i < 50; i++) { command_line[i] = '\0'; command_line2[i] = '\0'; } for (i = 0; i < 99; i++) { args[i] = NULL; } for (i = 0; i < 20; i++) { fileName[i] = '\0'; } printf("%s ", prompt); fflush(stdout); fgets(command_line, 99, stdin); if (command_line[0] != '\n') { //remove enter key for (i = 0; i <= 99; i++) { //find a > need to redirection if (i > 0 && command_line[i - 1] == '>') { command_line[i - 1] = '\0'; printf("i find a > need to redirection\n"); redirection = 1; for (j = i+1; j <= 99; j++) { if (command_line[j] == '\n') { break; } fileName[index] = command_line[j]; index++; } break; } //find a | need to use pipe if (i > 0 && command_line[i - 1] == '|') { command_line[i - 1] = '\0'; printf("i find a | need to use pipe\n"); for (j = i + 1; j <= 99; j++) { if (command_line[j] == '\n' || command_line[j] == '>') { break; } command_line2[index2] = command_line[j]; index2++; } isPipe = 1; } //find a & need run in background if (command_line[i] == '\n') { command_line[i] = '\0'; if (i > 0 && command_line[i - 1] == '&') { command_line[i - 1] = '\0'; printf("i find a & need run in background\n"); runInBackGround = 1; } break; } } //if user use pipe print out the front and back of the pipe if (isPipe == 1) { printf("comand befor pipe: %s\n", command_line); printf("comand after pipe: %s\n", command_line2); } //parse the command if pipe parse the both part of command_line and command_lin2 if (isPipe == 1) { parse(command_line, args); parse(command_line2, args2); } else { parse(command_line, args); } //if user enter exit then exit the loop if (i > 1 && strcmp(args[0], "exit") == 0) { exitLoop = 1; buildIn = 1; pid = 1; } //if args = cd then its is not a build in command if (i > 1 && strcmp(args[0], "cd") == 0) { chdir(args[1]); system("pwd"); buildIn = 1; pid = 1; } //if it is not a buld in commands if (i > 1 && buildIn == 0) { pid = fork(); } // start to fork child and execute the command if (pid == 0) { //redirection if (redirection == 1) { printf("out put is redirection to file: %s\n", fileName); int file_id = open(fileName, O_CREAT | O_WRONLY, 0666); close(1); dup(file_id); close(file_id); } //is pipe if (isPipe == 1) { int fd[2]; pipe(fd); if (fork() == 0) { close(fd[0]); //child colses input end of pipe, closing the file close(1); dup(fd[1]); close(fd[1]); execvp(command_line, args); exit(1); } else { close(fd[1]); // parent closes output end of pipe close(0); dup(fd[0]); close(fd[0]); execvp(command_line2, args2); exit(1); } } else { //normal execvp(command_line, args); printf("error commands\n"); exit(1); } } else { //if there is a child Parent will wait if (buildIn == 0) { if (runInBackGround != 1) { wait(NULL); } } } //start reset buildIn = 0; runInBackGround = 0; j = 1; redirection = 0; isPipe = 0; index = 0; index2 = 0; // end of reset } } printf("exit sussce\n"); printf(" ______ ____ \n"); printf(" / ____/___ ____ ____/ / /_ __ _____\n"); printf(" / / __/ __ \\/ __ \\/ __ / __ \\/ / / / _ \\\n"); printf("/ /_/ / /_/ / /_/ / /_/ / /_/ / /_/ / __/\n"); printf("\\____/\\____/\\____/\\__,_/_.___/\\__, /\\___/\n"); printf(" /____/ \n"); return 0; }
int main(int argc, char **argv) { char *name; const char *lastlabel; int arg, holdfd[3], label; unsigned f; struct bundle *bundle; struct prompt *prompt; struct switches sw; probe_Init(); /* * We open 3 descriptors to ensure that STDIN_FILENO, STDOUT_FILENO and * STDERR_FILENO are always open. These are closed before DoLoop(), * but *after* we've avoided the possibility of erroneously closing * an important descriptor with close(STD{IN,OUT,ERR}_FILENO). */ if ((holdfd[0] = open(_PATH_DEVNULL, O_RDWR)) == -1) { fprintf(stderr, "Cannot open %s !\n", _PATH_DEVNULL); return 2; } for (f = 1; f < NELEM(holdfd); f++) holdfd[f] = dup(holdfd[0]); name = strrchr(argv[0], '/'); log_Open(name ? name + 1 : argv[0]); #ifndef NONAT PacketAliasInit(); #endif label = ProcessArgs(argc, argv, &sw); /* * A FreeBSD & OpenBSD hack to dodge a bug in the tty driver that drops * output occasionally.... I must find the real reason some time. To * display the dodgy behaviour, comment out this bit, make yourself a large * routing table and then run ppp in interactive mode. The `show route' * command will drop chunks of data !!! */ if (sw.mode == PHYS_INTERACTIVE) { close(STDIN_FILENO); if (open(_PATH_TTY, O_RDONLY) != STDIN_FILENO) { fprintf(stderr, "Cannot open %s for input !\n", _PATH_TTY); return 2; } } /* Allow output for the moment (except in direct mode) */ if (sw.mode == PHYS_DIRECT) prompt = NULL; else SignalPrompt = prompt = prompt_Create(NULL, NULL, PROMPT_STD); ID0init(); if (ID0realuid() != 0) { char conf[200], *ptr; snprintf(conf, sizeof conf, "%s/%s", PPP_CONFDIR, CONFFILE); do { struct stat sb; if (stat(conf, &sb) == 0 && sb.st_mode & S_IWOTH) { log_Printf(LogALERT, "ppp: Access violation: Please protect %s\n", conf); return -1; } ptr = conf + strlen(conf)-2; while (ptr > conf && *ptr != '/') *ptr-- = '\0'; } while (ptr >= conf); } if (label < argc) for (arg = label; arg < argc; arg++) CheckLabel(argv[arg], prompt, sw.mode); else CheckLabel("default", prompt, sw.mode); if (!sw.quiet) prompt_Printf(prompt, "Working in %s mode\n", mode2Nam(sw.mode)); if ((bundle = bundle_Create(TUN_PREFIX, sw.mode, sw.unit)) == NULL) return EX_START; /* NOTE: We may now have changed argv[1] via a ``set proctitle'' */ if (prompt) { prompt->bundle = bundle; /* couldn't do it earlier */ if (!sw.quiet) prompt_Printf(prompt, "Using interface: %s\n", bundle->iface->name); } SignalBundle = bundle; bundle->NatEnabled = sw.nat; if (sw.nat) bundle->cfg.opt |= OPT_IFACEALIAS; if (system_Select(bundle, "default", CONFFILE, prompt, NULL) < 0) prompt_Printf(prompt, "Warning: No default entry found in config file.\n"); sig_signal(SIGHUP, CloseSession); sig_signal(SIGTERM, CloseSession); sig_signal(SIGINT, CloseConnection); sig_signal(SIGQUIT, CloseSession); sig_signal(SIGALRM, SIG_IGN); signal(SIGPIPE, SIG_IGN); if (sw.mode == PHYS_INTERACTIVE) sig_signal(SIGTSTP, TerminalStop); sig_signal(SIGUSR1, RestartServer); sig_signal(SIGUSR2, BringDownServer); lastlabel = argv[argc - 1]; for (arg = label; arg < argc; arg++) { /* In case we use LABEL or ``set enddisc label'' */ bundle_SetLabel(bundle, lastlabel); system_Select(bundle, argv[arg], CONFFILE, prompt, NULL); } if (label < argc) /* In case the last label did a ``load'' */ bundle_SetLabel(bundle, lastlabel); if (sw.mode == PHYS_AUTO && ncprange_family(&bundle->ncp.ipcp.cfg.peer_range) == AF_UNSPEC) { prompt_Printf(prompt, "You must ``set ifaddr'' with a peer address " "in auto mode.\n"); AbortProgram(EX_START); } if (sw.mode != PHYS_INTERACTIVE) { if (sw.mode != PHYS_DIRECT) { if (!sw.fg) { int bgpipe[2]; pid_t bgpid; if (sw.mode == PHYS_BACKGROUND && pipe(bgpipe)) { log_Printf(LogERROR, "pipe: %s\n", strerror(errno)); AbortProgram(EX_SOCK); } bgpid = fork(); if (bgpid == -1) { log_Printf(LogERROR, "fork: %s\n", strerror(errno)); AbortProgram(EX_SOCK); } if (bgpid) { char c = EX_NORMAL; int ret; if (sw.mode == PHYS_BACKGROUND) { close(bgpipe[1]); BGPid = bgpid; /* If we get a signal, kill the child */ signal(SIGHUP, KillChild); signal(SIGTERM, KillChild); signal(SIGINT, KillChild); signal(SIGQUIT, KillChild); /* Wait for our child to close its pipe before we exit */ while ((ret = read(bgpipe[0], &c, 1)) == 1) { switch (c) { case EX_NORMAL: if (!sw.quiet) { prompt_Printf(prompt, "PPP enabled\n"); log_Printf(LogPHASE, "Parent: PPP enabled\n"); } break; case EX_REDIAL: if (!sw.quiet) prompt_Printf(prompt, "Attempting redial\n"); continue; case EX_RECONNECT: if (!sw.quiet) prompt_Printf(prompt, "Attempting reconnect\n"); continue; default: prompt_Printf(prompt, "Child failed (%s)\n", ex_desc((int)c)); log_Printf(LogPHASE, "Parent: Child failed (%s)\n", ex_desc((int) c)); } break; } if (ret != 1) { prompt_Printf(prompt, "Child exit, no status.\n"); log_Printf(LogPHASE, "Parent: Child exit, no status.\n"); } close(bgpipe[0]); } return c; } else if (sw.mode == PHYS_BACKGROUND) { close(bgpipe[0]); bundle->notify.fd = bgpipe[1]; } bundle_ChangedPID(bundle); bundle_LockTun(bundle); /* we have a new pid */ } /* -auto, -dedicated, -ddial, -foreground & -background */ prompt_Destroy(prompt, 0); close(STDOUT_FILENO); close(STDERR_FILENO); close(STDIN_FILENO); if (!sw.fg) setsid(); } else { /* -direct - STDIN_FILENO gets used by physical_Open */ prompt_TtyInit(NULL); close(STDOUT_FILENO); close(STDERR_FILENO); } } else { /* -interactive */ close(STDERR_FILENO); prompt_TtyInit(prompt); prompt_TtyCommandMode(prompt); prompt_Required(prompt); } /* We can get rid of these now */ for (f = 0; f < NELEM(holdfd); f++) close(holdfd[f]); log_Printf(LogPHASE, "PPP Started (%s mode).\n", mode2Nam(sw.mode)); DoLoop(bundle); AbortProgram(EX_NORMAL); return EX_NORMAL; }
/** * Main entry of the MobiCore Driver Daemon. */ int main( int argc, char *args[] ) { // Create the MobiCore Driver Singleton MobiCoreDriverDaemon *mobiCoreDriverDaemon = NULL; // Process signal action struct sigaction action; // Read the Command line options extern char *optarg; extern int optopt; int c, errFlag = 0; // Scheduler enabled by default int schedulerFlag = 1; // Mobicore loading disable by default int mobicoreFlag = 0; // Autoload driver at start-up int driverLoadFlag = 0; std::string mobicoreImage, driverPath; // Ram donation disabled by default int donationSize = 0; // By default don't fork bool forkDaemon = false; while ((c = getopt(argc, args, "m:d:r:sbh")) != -1) { switch(c) { case 'h': /* Help */ errFlag++; break; case 's': /* Disable Scheduler */ schedulerFlag = 0; break; case 'd': /* Ram Donation size */ donationSize = atoi(optarg); break; case 'm': /* Load mobicore image */ mobicoreFlag = 1; mobicoreImage = optarg; break; case 'b': /* Fork to background */ forkDaemon = true; break; case 'r': /* Load mobicore driver at start-up */ driverLoadFlag = 1; driverPath = optarg; break; case ':': /* -d or -m without operand */ fprintf(stderr, "Option -%c requires an operand\n", optopt); errFlag++; break; case '?': fprintf(stderr, "Unrecognized option: -%c\n", optopt); errFlag++; } } if (errFlag) { printUsage(argc, args); exit(2); } // We should fork the daemon to background if (forkDaemon == true) { int i = fork(); if (i < 0) { exit(1); } // Parent else if (i > 0) { exit(0); } // obtain a new process group */ setsid(); /* close all descriptors */ for (i = getdtablesize();i >= 0; --i) { close(i); } // STDIN, STDOUT and STDERR should all point to /dev/null */ i = open("/dev/null",O_RDWR); dup(i); dup(i); /* ignore tty signals */ signal(SIGTSTP,SIG_IGN); signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); } // Set up the structure to specify the new action. action.sa_handler = terminateDaemon; sigemptyset (&action.sa_mask); action.sa_flags = 0; sigaction (SIGINT, &action, NULL); sigaction (SIGHUP, &action, NULL); sigaction (SIGTERM, &action, NULL); signal(SIGPIPE, SIG_IGN); mobiCoreDriverDaemon = new MobiCoreDriverDaemon( /* Scheduler status */ schedulerFlag, /* Mobicore loading to DDR */ mobicoreFlag, mobicoreImage, /* Ram Donation */ donationSize, /* Auto Driver loading */ driverLoadFlag, driverPath); // Start the driver mobiCoreDriverDaemon->run(); delete mobiCoreDriverDaemon; // This should not happen LOG_E("Exiting MobiCoreDaemon"); return EXIT_FAILURE; }
static void ivshmem_read(void *opaque, const uint8_t * buf, int flags) { IVShmemState *s = opaque; int incoming_fd, tmp_fd; int guest_max_eventfd; long incoming_posn; memcpy(&incoming_posn, buf, sizeof(long)); /* pick off s->server_chr->msgfd and store it, posn should accompany msg */ tmp_fd = qemu_chr_fe_get_msgfd(s->server_chr); IVSHMEM_DPRINTF("posn is %ld, fd is %d\n", incoming_posn, tmp_fd); /* make sure we have enough space for this guest */ if (incoming_posn >= s->nb_peers) { increase_dynamic_storage(s, incoming_posn); } if (tmp_fd == -1) { /* if posn is positive and unseen before then this is our posn*/ if ((incoming_posn >= 0) && (s->peers[incoming_posn].eventfds == NULL)) { /* receive our posn */ s->vm_id = incoming_posn; return; } else { /* otherwise an fd == -1 means an existing guest has gone away */ IVSHMEM_DPRINTF("posn %ld has gone away\n", incoming_posn); close_guest_eventfds(s, incoming_posn); return; } } /* because of the implementation of get_msgfd, we need a dup */ incoming_fd = dup(tmp_fd); if (incoming_fd == -1) { fprintf(stderr, "could not allocate file descriptor %s\n", strerror(errno)); return; } /* if the position is -1, then it's shared memory region fd */ if (incoming_posn == -1) { void * map_ptr; s->max_peer = 0; if (check_shm_size(s, incoming_fd) == -1) { exit(-1); } /* mmap the region and map into the BAR2 */ map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, incoming_fd, 0); memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, "ivshmem.bar2", s->ivshmem_size, map_ptr); IVSHMEM_DPRINTF("guest h/w addr = %" PRIu64 ", size = %" PRIu64 "\n", s->ivshmem_offset, s->ivshmem_size); memory_region_add_subregion(&s->bar, 0, &s->ivshmem); /* only store the fd if it is successfully mapped */ s->shm_fd = incoming_fd; return; } /* each guest has an array of eventfds, and we keep track of how many * guests for each VM */ guest_max_eventfd = s->peers[incoming_posn].nb_eventfds; if (guest_max_eventfd == 0) { /* one eventfd per MSI vector */ s->peers[incoming_posn].eventfds = (int *) g_malloc(s->vectors * sizeof(int)); } /* this is an eventfd for a particular guest VM */ IVSHMEM_DPRINTF("eventfds[%ld][%d] = %d\n", incoming_posn, guest_max_eventfd, incoming_fd); s->peers[incoming_posn].eventfds[guest_max_eventfd] = incoming_fd; /* increment count for particular guest */ s->peers[incoming_posn].nb_eventfds++; /* keep track of the maximum VM ID */ if (incoming_posn > s->max_peer) { s->max_peer = incoming_posn; } if (incoming_posn == s->vm_id) { s->eventfd_chr[guest_max_eventfd] = create_eventfd_chr_device(s, s->peers[s->vm_id].eventfds[guest_max_eventfd], guest_max_eventfd); } if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { if (kvm_set_ioeventfd_mmio_long(incoming_fd, s->mmio_addr + DOORBELL, (incoming_posn << 16) | guest_max_eventfd, 1) < 0) { fprintf(stderr, "ivshmem: ioeventfd not available\n"); } } return; }
int sh( int argc, char **argv, char **envp ) { signal(SIGINT, sig_handle); signal(SIGTERM, SIG_IGN); signal(SIGTSTP, SIG_IGN); char *prompt = calloc(PROMPTMAX, sizeof(char)); char *commandline = calloc(MAX_CANON, sizeof(char)); char *command, *arg, *aliashelp, *commandpath, *p, *pwd, *owd; /* Use these two save chars for strtok_r on command and alias commands*/ char *command_save, *alias_save; char **args = calloc(MAXARGS, sizeof(char*)); int uid, i, status, argsct, a, go = 1; int background, bg_pid = 0; struct passwd *password_entry; char *homedir; struct pathelement *pathlist, *history; struct aliaselement *aliases; const char sp[2] = " "; extern char **environ; glob_t globbuf; size_t glc; char **gl; pthread_t pt_warnload, pt_watchuser; /* for use with warnload */ float load = 0.0; int load_thread = 1; /* for use with watchuser */ static pthread_mutex_t user_lock = PTHREAD_MUTEX_INITIALIZER; int user_thread = 1; struct userarg *userargs; /* for use with file redirection */ int fid; int file_redirect, error_redirect, input_redirect = 0; int noclobber = 0; /* for use with pipe */ int ipc = 0; int ipc_err = 0; int pipefd[2]; char **pipeargs = calloc(5, sizeof(char*)); uid = getuid(); password_entry = getpwuid(uid); /* get passwd info */ homedir = getenv("HOME"); /* get homedir */ if ( (pwd = getcwd(NULL, PATH_MAX+1)) == NULL ) { perror("getcwd"); exit(2); } owd = calloc(strlen(pwd) + 1, sizeof(char)); memcpy(owd, pwd, strlen(pwd)); prompt[0] = ' '; prompt[1] = '\0'; /* Put PATH into a linked list */ pathlist = get_path(); /* By default, we have no history or aliases or users */ history = NULL; aliases = NULL; userargs = NULL; while ( go ) { /* wait on background processes */ bg_pid = waitpid(-1, &status, WNOHANG); if(bg_pid > 0) { printf("Background child [%d] exited with status: %d\n", bg_pid, WEXITSTATUS(status)); } /* print prompt */ printf("\n"); printf(prompt); printf(" ["); printf(pwd); printf("]> "); i = 0; /* get command line and process */ while (fgets(commandline, MAX_CANON, stdin) != NULL) { /* wait on background processes */ bg_pid = waitpid(-1, &status, WNOHANG); if(bg_pid > 0) { printf("Background child [%d] exited with status: %d\n", bg_pid, WEXITSTATUS(status)); } if (commandline[strlen(commandline) - 1] == '\n') { commandline[strlen(commandline) - 1] = 0; } /* Add the command to history */ history = add_last(history, commandline); /* Get the command */ command = strtok_r(commandline, sp, &command_save); if(command == NULL) { break; } /* Search for aliases */ a = 0; struct aliaselement *alias = aliases; while(alias != NULL) { if(strcmp(command, alias->name) == 0) { a = 1; break; } alias = alias->next; } /* If we have an alias */ i = 0; if(a) { /* parse alias command */ arg = calloc(strlen(alias->command) + 1, sizeof(char)); strcpy(arg, alias->command); aliashelp = strtok_r(arg, sp, &alias_save); while(aliashelp != NULL) { if(i == MAXARGS) { strcpy(args[0], "maxargs"); break; } args[i] = calloc(strlen(aliashelp) + 1, sizeof(char)); strcpy(args[i], aliashelp); aliashelp = strtok_r(NULL, sp, &alias_save); i++; } command = strtok_r(NULL, sp, &command_save); free(arg); } /* parse command line or remainder of command line if we have an alias */ while (command != NULL) { if(i == MAXARGS) { strcpy(args[0], "maxargs"); break; } args[i] = calloc(strlen(command) + 1, sizeof(char)); strcpy(args[i], command); command = strtok_r(NULL, sp, &command_save); i++; } /* SANITY CHECK: make sure the user passed in something */ if(args[0] == NULL) { break; } /* Expand wildcard characters */ glob(args[0], GLOB_NOCHECK, NULL, &globbuf); i = 1; while(args[i] != NULL) { glob(args[i], GLOB_APPEND | GLOB_NOCHECK, NULL, &globbuf); i++; } /* gl becomes our arguments, it is the expanded version of args */ gl = globbuf.gl_pathv; /* glc is the number of arguments. Use it for checking built in commands */ glc = globbuf.gl_pathc; /* Check for background & at end of last argument */ char* last_arg = gl[glc - 1]; char last_char = last_arg[(strlen(last_arg) - 1)]; if(strcmp(&last_char, "&") == 0) { last_arg[(strlen(last_arg) - 1)] = '\0'; background = 1; } /* Check for file output redirection (without appending) */ if(glc > 2 && (strcmp(gl[glc-2], ">") == 0 || strcmp(gl[glc-2], ">&") == 0)) { /* Don't overwrite an existing file if noclobber is set */ if(noclobber) { if(access(gl[glc-1], F_OK) == 0) { fprintf(stderr, "%s: File exists.\n", gl[glc-1]); free_args(args); break; } } /* Redirect the output to given file */ fid = open(gl[glc-1], O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP); if(fid == -1) { perror(gl[glc-1]); free_args(args); break; } close(1); dup(fid); /* Redirect error output to the given file */ if(strcmp(gl[glc-2], ">&") == 0) { close(2); dup(fid); error_redirect = 1; } close(fid); file_redirect = 1; /* Hide redirection character and filename */ gl[glc-2] = '\0'; gl[glc-1] = '\0'; glc = glc - 2; } /* Check for file output redirection (with appending) */ if(glc > 2 && (strcmp(gl[glc-2], ">>") == 0 || strcmp(gl[glc-2], ">>&") == 0)) { /* Don't append to a file that doesn't exist */ if(noclobber) { if(access(gl[glc-1], F_OK) != 0) { fprintf(stderr, "%s: No such file or directory.\n", gl[glc-1]); free_args(args); break; } } /* Redirect the output to given file */ fid = open(gl[glc-1], O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP); if(fid == -1) { perror(gl[glc-1]); free_args(args); break; } close(1); dup(fid); /* Redirect error output to the given file */ if(strcmp(gl[glc-2], ">>&") == 0) { close(2); dup(fid); error_redirect = 1; } close(fid); file_redirect = 1; /* Hide redirection character and filename */ gl[glc-2] = '\0'; gl[glc-1] = '\0'; glc = glc - 2; } /* Check for file input redirection */ if(glc > 2 && strcmp(gl[glc-2], "<") == 0) { /* Can't take input from a nonexisistent file */ if(access(gl[glc-1], F_OK) != 0) { fprintf(stderr, "%s: No such file or directory.\n", gl[glc-1]); free_args(args); break; } /* Open the file to read from */ fid = open(gl[glc-1], O_RDONLY); if(fid == -1) { perror(gl[glc-1]); free_args(args); break; } close(0); dup(fid); close(fid); input_redirect = 1; /* Hide redirection character and filename */ gl[glc-2] = '\0'; gl[glc-1] = '\0'; glc = glc - 2; } /* Check for inter-process communication */ if(glc > 2 && (strcmp(gl[1], "|") == 0 || strcmp(gl[1], "|&") == 0)) { ipc = 1; if(strcmp(gl[1], "|&") == 0) { ipc_err = 1; } /* Create our pipe */ if(pipe(pipefd) == -1) { perror("pipe"); free_args(args); break; } /* Put the command to the right of the pipe in a second arguments list */ i = 2; int p = 0; while(gl[i] != NULL) { pipeargs[p] = malloc(strlen(gl[i]) + 1 * sizeof(char)); pipeargs[p] = gl[i]; i++; p++; } gl[1] = '\0'; glc = 1; } /* check for each built in command and implement */ /* Built in warnload */ if(strcmp(gl[0], "warnload") == 0) { printf("Executing built-in [%s]\n", gl[0]); char *end; if(glc != 2) { printf("Usage: warnload LOAD\n"); } else if (strcmp(gl[1], "0.0") != 0 && (strtof(gl[1], &end) == 0 || strtof(gl[1], &end) < 0)) { printf("LOAD must be a positive floating point number\n"); } else if (strcmp(gl[1], "0.0") == 0) { load = 0.0; load_thread = 1; } else { load = strtof(gl[1], &end); if(load_thread != 0) { load_thread = 0; pthread_create(&pt_warnload, NULL, warnload, &load); } } } /* Built in watchuser */ else if(strcmp(gl[0], "watchuser") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { fprintf(stderr, "watchuser: Too few arguements.\n"); } else if(glc > 3) { fprintf(stderr, "watchuser: Too many arguments.\n"); } else if (glc == 3 && strcmp(gl[2], "off") != 0) { printf("Usage: watchuser USERNAME [off]\n"); } else if (glc == 3 && strcmp(gl[2], "off") == 0 ){ /* remove the given username from watched users list */ if(user_thread == 0) { pthread_mutex_lock(&user_lock); userargs->users = remove_user(userargs->users, gl[1]); pthread_mutex_unlock(&user_lock); } else { printf("No watched users have been added yet\n"); } } else { /* Add the user to the list. Create the watchuser thread if it isn't already created */ if(user_thread == 1) { user_thread = 0; userargs = calloc(1, sizeof(struct userarg)); userargs->lock = user_lock; userargs->users = add_user(NULL, gl[1]); pthread_create(&pt_watchuser, NULL, watchuser, userargs); } else { pthread_mutex_lock(&user_lock); userargs->users = add_user(userargs->users, gl[1]); pthread_mutex_unlock(&user_lock); } } } /* WATCHMAIL NOT IMPLEMENTED */ else if(strcmp(gl[0], "watchmail") == 0) { printf("We were not able to implement watchmail as we could not figure out\nhow to correctly use pthread_cancel(3) to cancel threads\n"); } /* Build in fg */ else if(strcmp(gl[0], "fg") == 0) { printf("Executing build-in [%s]\n", gl[0]); /* No arguments, bring a default process into foreground */ if(glc == 1) { kill(0, SIGCONT); wait(NULL); } /* One argument, bring the process with pid into foreground */ else if(glc == 2) { if(atoi(gl[1])) { kill(atoi(gl[1]), SIGCONT); waitpid(atoi(gl[1]), NULL, 0); } else { fprintf(stderr, "pid must be an integer\n"); } } else { fprintf(stderr, "Usage: fg [pid]\n"); } } /* Built in list */ else if(strcmp(gl[0], "list") == 0) { printf("Executing built-in [%s]\n", gl[0]); i = 1; /* No arguments, print the current working directory */ if(glc < 2) { list(pwd); } else { /* list each of the arguments passed in */ while(i < glc) { list(gl[i]); printf("\n"); i++; } } } /* Built in exit */ else if (strcmp(gl[0], "exit") == 0) { printf("Executing built-in [%s]\n", gl[0]); go = 0; break; } /* Built in prompt */ else if (strcmp(gl[0], "prompt") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { /* user didn't enter a prompt so request one */ printf("input prompt prefix:"); fgets(prompt, PROMPTMAX, stdin); if(prompt[strlen(prompt) - 1] == '\n') { prompt[strlen(prompt) - 1] = 0; } } else { /* set the prompt to be the first argument */ strncpy(prompt, gl[1], PROMPTMAX); } } /* Built in pwd */ else if (strcmp(gl[0], "pwd") == 0) { printf("Executing built-in [%s]\n", gl[0]); printf(pwd); printf("\n"); } /* Built in noclobber */ else if (strcmp(gl[0], "noclobber") == 0){ if(noclobber == 0) { noclobber = 1; } else { noclobber = 0; } printf("noclobber is set to %d\n", noclobber); } /* Built in pid */ else if (strcmp(gl[0], "pid") == 0) { printf("Executing built-in [%s]\n", gl[0]); printf("%d\n", getpid()); } /* Built in which */ else if (strcmp(gl[0], "which") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { fprintf(stderr, "which: Too few arguments.\n"); } else { i = 1; while(i < glc) { char *wh; /* call the which function which will check for the command in the path */ wh = which(gl[i], pathlist); if(wh == NULL) { fprintf(stderr, "%s: Command not found.\n", gl[i]); } else { printf("%s\n", wh); } free(wh); i++; } } } /* Built in where */ else if (strcmp(gl[0], "where") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { fprintf(stderr, "where: Too few arguments.\n"); } else { i = 1; while(i < glc) { where(gl[i], pathlist); i++; } } } /* Built in cd */ else if (strcmp(gl[0], "cd") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc > 2) { printf("cd: Too many arguments.\n"); } else { char *tmp; /* tmp will be the new directory or NULL on failure */ tmp = cd(gl[1], homedir, owd); if(tmp == NULL) { break; } else { free(owd); /* set owd to be the old (previous) working directory */ owd = pwd; /* set the new working directory */ pwd = tmp; } tmp = NULL; } } /* Built in printenv */ else if (strcmp(gl[0], "printenv") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc > 2) { fprintf(stderr, "%s: Too many arguments.\n", gl[0]); } else if (glc > 1) { /* print a particular environmental variable */ char *tmp; tmp = getenv(gl[1]); if(tmp == NULL) { fprintf(stderr, "%s: Environmental variable not found.\n", gl[1]); } else { printf("%s\n", tmp); } tmp = NULL; } else { /* print all environmental variables */ i = 0; while(environ[i] != NULL) { printf("%s\n", environ[i]); i++; } } } /* Built in setenv */ else if (strcmp(gl[0], "setenv") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc > 3) { fprintf(stderr, "%s: Too many arguments.\n", gl[0]); } else if (glc > 2) { /* set an environmental variable to the given value */ setenv(gl[1], gl[2], 1); } else if (glc > 1) { /* set an environmental variable to an empty value */ setenv(gl[1], "", 1); } else { /* print all environmental variables */ i = 0; while(environ[i] != NULL) { printf("%s\n", environ[i]); i++; } } /* in case we update the home directory */ homedir = getenv("HOME"); } /* Built in history */ else if (strcmp(gl[0], "history") == 0) { printf("Executing built-in [%s]\n", gl[0]); int n = 10; /* set how many history records to print */ if(glc > 1 && atoi(gl[1]) != 0) { n = atoi(gl[1]); } struct pathelement *curr = history; /* loop and print past commands */ while(curr != NULL && n > 0) { printf("%s\n", curr->element); curr = curr->next; n--; } } /* Built in alias */ else if (strcmp(gl[0], "alias") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { /* list all aliases */ struct aliaselement *curr = aliases; while(curr != NULL) { printf("%s %s\n", curr->name, curr->command); curr = curr->next; } } else if(glc < 3) { /* list a specific alias */ struct aliaselement *curr = aliases; while(curr != NULL) { if(strcmp(gl[1], curr->name) == 0) { printf("%s\n", curr->command); } curr = curr->next; } } else { /* add an alias */ char buf[MAX_CANON]; snprintf(buf, MAX_CANON, "%s", gl[2]); i = 3; while(gl[i] != NULL && i < MAXARGS) { strcat(buf, " "); strcat(buf, gl[i]); i++; } aliases = add_alias(aliases, gl[1], buf); } } /* Built in kill */ else if (strcmp(gl[0], "kill") == 0) { printf("Executing built-in [%s]\n", gl[0]); if(glc < 2) { fprintf(stderr, "kill: Too few arguments.\n"); } else if(glc < 3 || strchr(gl[1], '-') == NULL) { /* default kill with SIGINT */ i = 1; while(gl[i] != NULL) { kill_process(gl[i]); i++; } } else { /* kill with the given signal number */ char *signal; signal = strtok(gl[1], "-"); i = 2; while(gl[i] != NULL) { kill_process_signal(gl[i], signal); i++; } } } /* MAXARGS handler */ else if (strcmp(gl[0], "maxargs") == 0) { fprintf(stderr, "Error: Too many arguments.\n"); } /* Absolute/Relative paths */ else if (strncmp(gl[0], "/", 1) == 0 || strncmp(gl[0], "./", 2) == 0 || strncmp(gl[0], "../", 3) == 0) { if(access(gl[0], X_OK) == 0) { pid_t pid = fork(); if(pid == -1) { perror("fork"); } else if(pid == 0) { /* print what child is executing and execve it */ printf("Executing [%s]\n", gl[0]); /* If we are piping this is the command on the left, set standard output to the pipe output */ if(ipc) { close(1); dup(pipefd[1]); if(ipc_err) { close(2); dup(pipefd[1]); } close(pipefd[0]); close(pipefd[1]); } execve(gl[0], gl, environ); /* on exec error */ perror(gl[0]); exit(127); } else { /* if not a background process, wait */ if(!background) { /* If we are piping this is the command on the right. Wait for the first command to finish */ if(ipc) { waitpid(pid, &status, 0); pid_t pid2 = fork(); if(pid2 == -1) { perror("fork"); } else if (pid2 == 0) { /* Set stdin to be the pipe input */ close(0); dup(pipefd[0]); close(pipefd[1]); close(pipefd[0]); /* Which command should we run */ char* wh; wh = which(pipeargs[0], pathlist); if(wh == NULL) { fprintf(stderr, "%s: Command not found", pipeargs[0]); } else { execve(wh, pipeargs, environ); } } else { close(pipefd[0]); close(pipefd[1]); } } else { /* wait for chil process */ waitpid(pid, &status, 0); /* if child exits with non-zero status print it */ if(WEXITSTATUS(status) != 0) { printf("Exit: %d\n", WEXITSTATUS(status)); } } } } } else { /* path doens't exist */ fprintf(stderr,"%s: Command not found.\n", gl[0]); } } /* Executable */ else { char* wh; char* wh2; /* figure out which executable to execute */ wh = which(gl[0], pathlist); if(wh == NULL) { fprintf(stderr, "%s: Command not found.\n", gl[0]); } else { pid_t pid = fork(); if(pid == -1) { perror("fork"); } else if (pid == 0) { /* what we are executing */ printf("Executing [%s]\n", wh); /* If we are piping this is the command on the left, set standard output to be the pipe output*/ if(ipc) { close(1); dup(pipefd[1]); if(ipc_err) { close(2); dup(pipefd[1]); } close(pipefd[0]); close(pipefd[1]); } execve(wh, gl, environ); /* on execve error */ perror(wh); exit(127); } else { /* if not a background process, wait */ if(!background) { /* If we are piping this is the command on the right, wait for command on left to finish */ if(ipc) { waitpid(pid, &status, 0); pid_t pid2 = fork(); if(pid2 == -1) { perror("fork"); } else if (pid2 == 0) { /* Set standard input to be pipe input */ close(0); dup(pipefd[0]); close(pipefd[1]); close(pipefd[0]); /* Which command should we run */ wh2 = which(pipeargs[0], pathlist); if(wh2 == NULL) { fprintf(stderr, "%s: Command not found", pipeargs[0]); } else { execve(wh2, pipeargs, environ); } } else { close(pipefd[0]); close(pipefd[1]); } } else { /* wait for child */ waitpid(pid, &status, 0); /* if child exits with nonzero value print it */ if(WEXITSTATUS(status) != 0){ printf("Exit: %d\n", WEXITSTATUS(status)); } } } } free(wh); } } /* reset background */ background = 0; /* reset glob */ globfree(&globbuf); /* reset args */ free_args(args); free_args(pipeargs); /* if we redirected file output, reset it to the screen */ if(file_redirect == 1) { file_redirect = 0; fid = open("/dev/tty", O_WRONLY); close(1); dup(fid); if(error_redirect == 1) { error_redirect = 0; close(2); dup(fid); } close(fid); } /* if we redirected file input, reset it to the keyboard */ if(input_redirect == 1) { input_redirect = 0; fid = open("/dev/tty", O_RDONLY); close(0); dup(fid); close(fid); } ipc = 0; ipc_err = 0; sleep(1); /* Print prompt again */ printf(prompt); printf(" ["); printf(pwd); printf("]> "); } } /* free allocated memory */ free(prompt); free(commandline); free_args(args); free_args(pipeargs); free(args); free(pipeargs); free(owd); free(pwd); struct pathelement *tmp; while(pathlist != NULL) { tmp = pathlist->next; free(pathlist); pathlist = tmp; } while(history != NULL) { tmp = history->next; free(history->element); free(history); history = tmp; } struct aliaselement *temp; while(aliases != NULL) { temp = aliases->next; free(aliases->name); free(aliases->command); free(aliases); aliases = temp; } struct userelement *tem; while(userargs != NULL && userargs->users != NULL) { tem = userargs->users->next; free(userargs->users->username); free(userargs->users); userargs->users = tem; } if(userargs != NULL) { pthread_mutex_destroy(&userargs->lock); free(userargs); } globfree(&globbuf); return 0; } /* sh() */
void service_start(struct service *svc, const char *dynamic_args) { struct stat s; pid_t pid; int needs_console; char *scon = NULL; int rc; /* starting a service removes it from the disabled or reset * state and immediately takes it out of the restarting * state if it was in there */ svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START)); svc->time_started = 0; /* running processes require no additional work -- if * they're in the process of exiting, we've ensured * that they will immediately restart on exit, unless * they are ONESHOT */ if (svc->flags & SVC_RUNNING) { return; } needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0; if (needs_console && (!have_console)) { ERROR("service '%s' requires console\n", svc->name); svc->flags |= SVC_DISABLED; return; } if (stat(svc->args[0], &s) != 0) { ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name); svc->flags |= SVC_DISABLED; return; } if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) { ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", svc->args[0]); svc->flags |= SVC_DISABLED; return; } if (is_selinux_enabled() > 0) { if (svc->seclabel) { scon = strdup(svc->seclabel); if (!scon) { ERROR("Out of memory while starting '%s'\n", svc->name); return; } } else { char *mycon = NULL, *fcon = NULL; INFO("computing context for service '%s'\n", svc->args[0]); rc = getcon(&mycon); if (rc < 0) { ERROR("could not get context while starting '%s'\n", svc->name); return; } rc = getfilecon(svc->args[0], &fcon); if (rc < 0) { ERROR("could not get context while starting '%s'\n", svc->name); freecon(mycon); return; } rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &scon); if (rc == 0 && !strcmp(scon, mycon)) { ERROR("Warning! Service %s needs a SELinux domain defined; please fix!\n", svc->name); } freecon(mycon); freecon(fcon); if (rc < 0) { ERROR("could not get context while starting '%s'\n", svc->name); return; } } } NOTICE("starting '%s'\n", svc->name); pid = fork(); if (pid == 0) { struct socketinfo *si; struct svcenvinfo *ei; char tmp[32]; int fd, sz; umask(077); if (properties_inited()) { get_property_workspace(&fd, &sz); sprintf(tmp, "%d,%d", dup(fd), sz); add_environment("ANDROID_PROPERTY_WORKSPACE", tmp); } for (ei = svc->envvars; ei; ei = ei->next) add_environment(ei->name, ei->value); for (si = svc->sockets; si; si = si->next) { int socket_type = ( !strcmp(si->type, "stream") ? SOCK_STREAM : (!strcmp(si->type, "dgram") ? SOCK_DGRAM : SOCK_SEQPACKET)); int s = create_socket(si->name, socket_type, si->perm, si->uid, si->gid, si->socketcon ?: scon); if (s >= 0) { publish_socket(si->name, s); } } freecon(scon); scon = NULL; if (svc->ioprio_class != IoSchedClass_NONE) { if (android_set_ioprio(getpid(), svc->ioprio_class, svc->ioprio_pri)) { ERROR("Failed to set pid %d ioprio = %d,%d: %s\n", getpid(), svc->ioprio_class, svc->ioprio_pri, strerror(errno)); } } if (needs_console) { setsid(); open_console(); } else { zap_stdio(); } #if 0 for (n = 0; svc->args[n]; n++) { INFO("args[%d] = '%s'\n", n, svc->args[n]); } for (n = 0; ENV[n]; n++) { INFO("env[%d] = '%s'\n", n, ENV[n]); } #endif setpgid(0, getpid()); /* as requested, set our gid, supplemental gids, and uid */ if (svc->gid) { if (setgid(svc->gid) != 0) { ERROR("setgid failed: %s\n", strerror(errno)); _exit(127); } } if (svc->nr_supp_gids) { if (setgroups(svc->nr_supp_gids, svc->supp_gids) != 0) { ERROR("setgroups failed: %s\n", strerror(errno)); _exit(127); } } if (svc->uid) { if (setuid(svc->uid) != 0) { ERROR("setuid failed: %s\n", strerror(errno)); _exit(127); } } if (svc->seclabel) { if (is_selinux_enabled() > 0 && setexeccon(svc->seclabel) < 0) { ERROR("cannot setexeccon('%s'): %s\n", svc->seclabel, strerror(errno)); _exit(127); } } if (!dynamic_args) { if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) { ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno)); } } else { char *arg_ptrs[INIT_PARSER_MAXARGS+1]; int arg_idx = svc->nargs; char *tmp = strdup(dynamic_args); char *next = tmp; char *bword; /* Copy the static arguments */ memcpy(arg_ptrs, svc->args, (svc->nargs * sizeof(char *))); while((bword = strsep(&next, " "))) { arg_ptrs[arg_idx++] = bword; if (arg_idx == INIT_PARSER_MAXARGS) break; } arg_ptrs[arg_idx] = '\0'; execve(svc->args[0], (char**) arg_ptrs, (char**) ENV); } _exit(127); } freecon(scon); if (pid < 0) { ERROR("failed to start '%s'\n", svc->name); svc->pid = 0; return; } svc->time_started = gettime(); svc->pid = pid; svc->flags |= SVC_RUNNING; if (properties_inited()) notify_service_state(svc->name, "running"); }
/* Called under table_lock */ static void bo_del(struct fd_bo *bo) { if (bo->map) drm_munmap(bo->map, bo->size); /* TODO probably bo's in bucket list get removed from * handle table?? */ if (bo->handle) { struct drm_gem_close req = { .handle = bo->handle, }; drmHashDelete(bo->dev->handle_table, bo->handle); if (bo->name) drmHashDelete(bo->dev->name_table, bo->name); drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req); } bo->funcs->destroy(bo); } drm_public int fd_bo_get_name(struct fd_bo *bo, uint32_t *name) { if (!bo->name) { struct drm_gem_flink req = { .handle = bo->handle, }; int ret; ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req); if (ret) { return ret; } pthread_mutex_lock(&table_lock); set_name(bo, req.name); pthread_mutex_unlock(&table_lock); } *name = bo->name; return 0; } drm_public uint32_t fd_bo_handle(struct fd_bo *bo) { return bo->handle; } drm_public int fd_bo_dmabuf(struct fd_bo *bo) { if (!bo->fd) { struct drm_prime_handle req = { .handle = bo->handle, .flags = DRM_CLOEXEC, }; int ret; ret = drmIoctl(bo->dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req); if (ret) { return ret; } bo->fd = req.fd; } return dup(bo->fd); } drm_public uint32_t fd_bo_size(struct fd_bo *bo) { return bo->size; } drm_public void * fd_bo_map(struct fd_bo *bo) { if (!bo->map) { uint64_t offset; int ret; ret = bo->funcs->offset(bo, &offset); if (ret) { return NULL; } bo->map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->dev->fd, offset); if (bo->map == MAP_FAILED) { ERROR_MSG("mmap failed: %s", strerror(errno)); bo->map = NULL; } } return bo->map; } /* a bit odd to take the pipe as an arg, but it's a, umm, quirk of kgsl.. */ drm_public int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op) { return bo->funcs->cpu_prep(bo, pipe, op); } drm_public void fd_bo_cpu_fini(struct fd_bo *bo) { bo->funcs->cpu_fini(bo); }
int main(int argc, char *argv[]) { //Initialize the shell init_shell(); int numofpipes[MAXCMD]; //Initialize jobs array init_jobsarray(); //Holds the command char wholecommand[MAXNUM]; char dupwholecommand[MAXNUM]; char *cmdarr[MAXCMD][MAXOP]; //The rows hold commands separated by ; //while the columns hold the command and its options separated by " " or \t char *pipecmdarr[MAXCMD][MAXCMD][MAXOP]; char maincmd[MAXNUM]; //For prompt char username[MAXNUM],sysname[MAXNUM],cwdir[MAXNUM]; char homedir[MAXNUM]; getcwd(homedir,MAXNUM); char duphomedir[MAXNUM]; duphomedir[0] = '\0'; strcat(duphomedir,homedir); //For tokenizing char *str1 = NULL; char *token = NULL; //Counters int i; //Initializing background process array for(i=0; i<(MAXNUM*MAXOP); i++) { bgrounds[i].used = 0; } //Initializing ends //Initialize to NULL initarray(cmdarr); char *hdir[MAXNUM]; //Tokenize home directory tokenize(str1,hdir,token,duphomedir); //Tokenize home directory done while(1) { if(signal(SIGINT,signal_handler)==SIG_ERR) perror("Signal not caught!!"); if(signal(SIGCHLD,signal_handler)==SIG_ERR) perror("Signal not caught!!"); for(i=0; i<MAXCMD; i++) numofpipes[i] = 0; rectifyjobsarray(); //Printing message on background process completion for(i=0; i<(MAXNUM*MAXOP); i++) { if(bgrounds[i].used == 0) continue; bgrounds[i].used = 0; if(bgrounds[i].status == 1) { //printf("Process %s with pid %d terminated normally\n",bgrounds[i].name,bgrounds[i].pid); } else { //printf("Process %s with pid %d terminated with status %d\n",bgrounds[i].name,bgrounds[i].pid,bgrounds[i].status); } } //Renitializing background process array for(i=0; i<(MAXNUM*MAXOP); i++) { bgrounds[i].used = 0; } //Renitializing ends //Initialize to NULL initarray(cmdarr); initpipecmd(pipecmdarr); //For prompt username[0] = '\0'; cwdir[0] = '\0'; strcat(username,getlogin()); gethostname(sysname,MAXNUM); getcwd(cwdir,MAXNUM); char dupcwdir[MAXNUM]; dupcwdir[0] = '\0'; strcat(dupcwdir,cwdir); directorysettings(cwdir,homedir,dupcwdir,hdir); //Prompt settings done //Take commands printf("<%s@%s:%s>",username,sysname,cwdir); wholecommand[0] = '\0'; dupwholecommand[0] = '\0'; readLine(wholecommand); wholecommand[strlen(wholecommand)-1]='\0'; strcpy(dupwholecommand,wholecommand); //Done taking commands //Tokenize maintokenize(cmdarr,dupwholecommand); //tokentest(cmdarr); pipetokenize(cmdarr,pipecmdarr,numofpipes); //pipetokenizetest(cmdarr,pipecmdarr,numofpipes); //exit(EXIT_SUCCESS); //continue; //Tokenize done //Executing each ; separated command for(i = 0; i< MAXCMD; i++) { if(cmdarr[i][0] == NULL) continue; maincmd[0] = '\0'; strcat(maincmd,cmdarr[i][0]); strcpy(infile,"\0"); strcpy(outfile,"\0"); if(numofpipes[i] != 0) { //Execute piped commands pipesexecute(cmdarr, pipecmdarr, numofpipes, i); continue; } if((strcmp(maincmd,"echo") == 0) || (strcmp(maincmd,"pwd") == 0) || (strcmp(maincmd,"cd") == 0)\ || (strcmp(maincmd,"clear") == 0) || (strcmp(maincmd,"quit") == 0) || (strcmp(maincmd,"pinfo") == 0) || strcmp(maincmd,"jobs") == 0 || strcmp(maincmd,"overkill") == 0 || strcmp(maincmd,"kjob") == 0 || strcmp(maincmd,"fg") == 0 ) { int dupstdout = dup(1); int dupstdin = dup(0); if(checkinfile(cmdarr,i) == 1) { if(strcmp(infile,"\0") != 0) { int in=open(infile,O_RDONLY); dup2(in,0); close(in); } } int outretval = checkoutfile(cmdarr,i); if(outretval == 1 || outretval == 2) { if(strcmp(outfile,"\0") != 0) { if(outretval == 1) { int out=open(outfile,O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR); dup2(out,1); close(out); } else { if(fopen(outfile,"r") == NULL) { int out=open(outfile,O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR); dup2(out,1); close(out); } else { int out=open(outfile,O_WRONLY | O_APPEND, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR); dup2(out,1); close(out); } } } } //echo execution if(strcmp (maincmd,"echo") == 0) { exececho(wholecommand,cmdarr,i); } //echo done //pwd execution if(strcmp (maincmd,"pwd") == 0) { execpwd(); } //pwd done //chdir execution if(strcmp (maincmd,"cd") == 0) { execcd(cmdarr,homedir,i); } //chdir done //clear execution if(strcmp (maincmd,"clear") == 0) { printf("\e[1;1H\e[2J"); } //clear done //terminal quit if(strcmp (maincmd,"quit") == 0) { exit(EXIT_SUCCESS); } //terminal quit done //jobs if(strcmp (maincmd,"jobs") == 0) { execjobs(); } //jobs done //overkill if(strcmp (maincmd,"overkill") == 0) { execoverkill(); } //overkill done //kjob if(strcmp (maincmd,"kjob") == 0) { execkjob(cmdarr,i); } //kjob done //fg if(strcmp (maincmd,"fg") == 0) { execfg(cmdarr,i); } //fg done //pinfo if(strcmp (maincmd,"pinfo") == 0) { pid_t proid; int flag = 0; if(cmdarr[i][1] == NULL) //pinfo of shell proid = getpid(); else { //pinfo of given pid char temps[MAXNUM]; strcpy(temps,cmdarr[i][1]); proid = atoi(temps); if(kill(proid,0) == (-1)) { printf("No such process exists\n"); continue; } flag = 1; } getpinfo(proid, flag, homedir); } //pinfo done dup2(dupstdin,0); dup2(dupstdout,1); } else {