ARG stdname(MTNJOB *job) { ARG std = newarg(3); if(ctx->stdin){ std[0] = convarg(newstr(ctx->stdin), job); }else{ std[0] = newstr("/dev/null"); } if(ctx->stdout){ std[1] = convarg(newstr(ctx->stdout), job); }else{ std[1] = newstr(""); } if(ctx->stderr){ std[2] = convarg(newstr(ctx->stderr), job); }else{ std[2] = newstr(""); } std[3] = NULL; return(std); }
ARG cpconvarg(ARG a, MTNJOB *j) { int i; ARG r = newarg(0); if(!a){ return(r); } for(i=0;a[i];i++){ r = addarg(r, a[i]); r[i] = convarg(r[i], j); } return(r); }
static int getid(int ac, char **av, struct trace_ids *tp) { static int index = 1; /* * if inside of standard input scan take arguments from there. */ retry: if (infile) { tp->ti_mid = convarg(getarg()); tp->ti_sid = convarg(getarg()); tp->ti_level = convarg(getarg()); if (errflg) return (0); /* * if the previous operations encountered EOF, infile * will be set to zero. The trace_ids structure must * then be loaded from the command line arguments. * Otherwise, the structure is now valid and should * be returned. */ if (infile) return (1); } /* * if we get here we are either taking arguments from the * command line argument list or we hit end of file on standard * input and should return to finish off the command line arguments */ if (index >= ac) return (0); /* * if a '-' is present, start parsing from standard input */ if (strcmp(av[index], "-") == 0) { infile = 1; index++; goto retry; } /* * Parsing from command line, make sure there are * at least 3 arguments remaining. */ if ((index+2) >= ac) return (0); tp->ti_mid = convarg(av[index++]); tp->ti_sid = convarg(av[index++]); tp->ti_level = convarg(av[index++]); if (errflg) return (0); return (1); }
ARG cmdargs(MTNJOB *job) { int i; ARG cmd = newarg(0); if(job->args){ for(i=0;job->args[i];i++){ if(job->conv){ cmd = addarg(cmd, convarg(newstr(job->args[i]), job)); }else{ cmd = addarg(cmd, newstr(job->args[i])); } } } if(!job->conv && job->argl){ for(i=0;job->argl[i];i++){ cmd = addarg(cmd, job->argl[i]); } } return(cmd); }
int mtnexec_fork(MTNSVR *svr, ARG arg) { int f; int pp[3][2]; MTNJOB *job; struct epoll_event ev; if(!(job = mtnexec_wait())){ return(-1); } mtnexec_initjob(job, arg); job->svr = svr; job->argc = cmdargs(job); job->cmd = joinarg(job->argc, " "); job->std = stdname(job); job->echo = (ctx->echo) ? convarg(newstr(ctx->echo), job) : NULL; job->putarg = cpconvarg(ctx->putarg, ctx->conv ? job : NULL); job->getarg = cpconvarg(ctx->getarg, ctx->conv ? job : NULL); if(is_empty(job->cmd)){ jclose(job); return(-1); } if(ctx->dryrun){ mtnexec_dryrun(job); jclose(job); return(0); } if(ctx->verbose){ mtnexec_verbose(job); } pipe(pp[0]); pipe(pp[1]); pipe(pp[2]); gettimeofday(&(job->start), NULL); job->pid = fork(); if(job->pid == -1){ job->pid = 0; close(pp[0][0]); close(pp[0][1]); close(pp[1][0]); close(pp[1][1]); close(pp[2][0]); close(pp[2][1]); mtnlogger(mtn, 0, "[error] %s: %s\n", __func__, strerror(errno)); return(-1); } if(job->pid){ close(pp[0][1]); close(pp[1][1]); close(pp[2][1]); job->ctl = pp[0][0]; job->out = pp[1][0]; job->err = pp[2][0]; job->cct = 1; job->pstat = calloc(1, sizeof(MTNPROCSTAT)); job->pstat[0].pid = job->pid; fcntl(job->ctl, F_SETFD, FD_CLOEXEC); fcntl(job->out, F_SETFD, FD_CLOEXEC); fcntl(job->err, F_SETFD, FD_CLOEXEC); fcntl(job->out, F_SETFL, O_NONBLOCK); fcntl(job->err, F_SETFL, O_NONBLOCK); ev.data.ptr = job; ev.events = EPOLLIN; if(epoll_ctl(ctx->efd, EPOLL_CTL_ADD, job->out, &ev) == -1){ mtnlogger(mtn, 0, "[error] %s: epoll_ctl %s stdout fd=%d\n", __func__, strerror(errno), job->out); } if(epoll_ctl(ctx->efd, EPOLL_CTL_ADD, job->err, &ev) == -1){ mtnlogger(mtn, 0, "[error] %s: epoll_ctl %s stderr fd=%d\n", __func__, strerror(errno), job->err); } char d; while(read(job->ctl,&d,1)); close(job->ctl); job->ctl = 0; return(0); } //===== execute process ===== setpgid(0,0); close(pp[0][0]); close(pp[1][0]); close(pp[2][0]); if(strlen(job->std[0])){ f = open(job->std[0], O_RDONLY); if(f == -1){ mtnlogger(mtn, 0, "[error] %s: %s %s\n", __func__, strerror(errno), job->std[0]); _exit(1); } close(0); dup2(f, 0); close(f); } if(strlen(job->std[1])){ f = open(job->std[1], O_WRONLY | O_TRUNC | O_CREAT, 0660); if(f == -1){ mtnlogger(mtn, 0, "[error] %s: %s %s\n", __func__, strerror(errno), job->std[1]); _exit(1); } close(1); if(dup2(f, 1) == -1){ mtnlogger(mtn, 0, "[error] %s: %s\n", __func__, strerror(errno)); _exit(1); } close(f); }else{ close(1); dup2(pp[1][1], 1); } if(strlen(job->std[2])){ f = open(job->std[2], O_WRONLY | O_TRUNC | O_CREAT, 0660); if(f == -1){ mtnlogger(mtn, 0, "[error] %s: %s %s\n", __func__, strerror(errno), job->std[2]); _exit(1); } close(2); dup2(f, 2); close(f); }else{ close(2); dup2(pp[2][1], 2); } close(pp[1][1]); close(pp[2][1]); job->ctl = pp[0][1]; if(job->svr){ /*===== remote execute process =====*/ mtn_exec(mtn, job); mtnlogger(mtn, 0, "[error] %s: host=%s addr=%s %s '%s'\n", __func__, job->svr->host, inet_ntoa(job->svr->addr.addr.in.sin_addr), strerror(errno), job->cmd); }else{ /*===== local exec process =====*/ close(job->ctl); job->ctl = 0; execl("/bin/sh", "/bin/sh", "-c", job->cmd, NULL); mtnlogger(mtn, 0, "[error] %s: %s '%s'\n", __func__, strerror(errno), job->cmd); } _exit(127); }