#include "tcb.h" #include #include #include #include static char *w_arg(char arg[], char argv[]) { /* filename for a program needs a specific suffix (dvi2tty etc.) */ static char wa[N_line]; char *cp, *dp; for (cp = dp = arg; (cp = strchr(cp, '/')); dp = ++cp) ; sprintf(wa, "%s.%s.%s", s_S(S_w), argv, dp); return wa; } u_char *fork_scan(int *sizep, int pid, int fd, int f_cr)/*tcb*/ { int kpid = 0; u_char *buff; if (f_cr >= 0 /* not file-selector */ && !(kpid = fork())) { while (!vt_getch(1)); if (pid > 0 && !kill(pid, 0)) kill(pid, SIGPIPE); save_intr(S_err0); exit(0); } if (kpid) echo_mess(2); buff = alloc_buff(sizep, fd, pid, f_cr); if (kpid && !kill(kpid, 0)) kill(kpid, SIGKILL); if (pid > 0 && !kill(pid, 0)) kill(pid, SIGKILL); return buff; } u_char *fork_key(int *sizep, int f_M)/*tcb*/ { int pid, pv[2]; u_char *buff; pipe(pv); if (!(pid = fork())) { close(1); dup2(pv[1], 1); close(pv[1]); close(pv[0]); conf_key(NULL, NULL, (f_M == M_key || f_M == T_key) ? EOP : NULL, EOP); exit(0); } close(pv[1]); buff = fork_scan(sizep, pid, pv[0], 0); close(pv[0]); return buff; } u_char *fork_bin(CHILD *chp, int *sizep, int f_M, int f_cr)/*tcb*/ { int pid, pv[2]; u_char *buff; pipe(pv); if (!(pid = fork())) { dup_error(); close(1); dup2(pv[1], 1); close(pv[1]); close(pv[0]); signal(SIGCHLD, SIG_DFL); /* avoid ECHILD (errno) */ signal(SIGPIPE, SIG_DFL); execvp(*chp->argv, chp->argv); } close(pv[1]); buff = fork_scan(sizep, pid, pv[0], f_cr); close(pv[0]); return buff; } void fork_exec(CHILD *chp, char arg[], u_char buff[], int size)/*tcb*/ { FILE *fp; char *cp; cp = w_arg(arg, chp->argv[0]); fp = fopen(cp, "w"); fwrite(buff, 1, size, fp); fclose(fp); do_exec(cp, chp); unlink(cp); } u_char *fork_chp(CHILD *chp, u_char *buff, int *sizep, char arg[])/*tcb*/ { CHILD *chp2 = NULL; int pid, pv[4], size = *sizep; u_char *buff2, *cp; FILE *fp; cp = w_arg(arg, chp->argv[0]); if (!chp->argv[chp->f.argc]) { chp2 = (CHILD*)chp->argv[chp->f.argc + 1]; strcpy(chp2->argv[chp2->f.argc], cp); } else strcpy(chp->argv[chp->f.argc], cp); fp = fopen(cp, "w"); fwrite(buff, 1, size, fp); fclose(fp); pipe(pv); if (!(pid = fork())) { signal(SIGPIPE, SIG_DFL); dup_error(); if (chp2) { pipe(&pv[2]); if (!fork()) { close(1); dup2(pv[3], 1); close(pv[3]); close(pv[2]); execvp(*chp2->argv, chp2->argv); } close(0); dup2(pv[2], 0); close(pv[2]); close(pv[3]); } close(1); dup2(pv[1], 1); close(pv[1]); close(pv[0]); execvp(*chp->argv, chp->argv); } close(pv[1]); buff2 = fork_scan(&size, pid, pv[0], 0); close(pv[0]); unlink(cp); *sizep = size; return buff2; } u_char *fork_arc(u_char name[], int f_M, CHILD *chp0, int *tmp_sizep, int *bp_sizep, BASE *bp)/*tcb*/ { CHILD *chp = NULL, *chp2 = NULL; int fd, n_error, pv[4], pid; char *tmp_buff; switch(f_M) { case T_tar: if (!chp0->argv[chp0->f.argc]) { chp2 = (CHILD*)chp0->argv[chp0->f.argc + 1]; chp2 = get_child(chp2, NULL, chp2->argv[0], name); pipe(pv); if (!(pid = fork())) { dup_error(); close(1); dup2(pv[1], 1); close(pv[0]); close(pv[1]); execvp(*chp2->argv, chp2->argv); } close(pv[1]); bp->buff = fork_scan(&bp->size, pid, pv[0], 0); close(pv[0]); if (!bp->buff) return NULL; *bp_sizep = bp->size; chp = chp0; } else { struct stat st; stat(name, &st); fd = open(name, O_RDONLY); bp->size = st.st_size; bp->buff = fork_scan(&bp->size, -1, fd, 0); close(fd); *bp_sizep = bp->size; chp = get_child(NULL, ".tar", s_S(S_tar), name); } break; case T_lha: chp = get_child(NULL, NULL, s_S(S_lha), name); /* `.lzh lha p' */ pipe(pv); if (!(pid = fork())) { signal(SIGPIPE, SIG_DFL); dup_error(); close(1); dup2(pv[1], 1); close(pv[0]); close(pv[1]); execvp(*chp->argv, chp->argv); } close(pv[1]); bp->buff = fork_scan(&bp->size, pid, pv[0], 0); close(pv[0]); if (!bp->buff) return NULL; *bp_sizep = bp->size; chp = get_child(chp->next, NULL, s_S(S_lha), name); /* `.lzh lha' */ break; case T_unzip: chp = get_child(NULL, NULL, s_S(S_unzip), name); /* `.zip unzip -p' */ pipe(pv); if (!(pid = fork())) { signal(SIGPIPE, SIG_DFL); dup_error(); close(1); dup2(pv[1], 1); close(pv[0]); close(pv[1]); execvp(*chp->argv, chp->argv); } close(pv[1]); bp->buff = fork_scan(&bp->size, pid, pv[0], 0); close(pv[0]); if (!bp->buff) return NULL; *bp_sizep = bp->size; chp = get_child(chp->next, NULL, s_S(S_unzip), name); /* `.zip unzip -l' */ break; } n_error = load_intr(); /* store n_error */ unlink(s_S(S_intr)); /* unlink s_S(S_intr) may interrupt fork_scan() */ pipe(pv); if (!(pid = fork())) { signal(SIGPIPE, SIG_DFL); if (chp2) { pipe(&pv[2]); if (!fork()) { close(1); dup2(pv[3], 1); close(pv[3]); close(pv[2]); execvp(*chp2->argv, chp2->argv); } close(pv[3]); close(0); dup2(pv[2], 0); close(pv[2]); } dup_error(); close(1); dup2(pv[1], 1); close(pv[1]); close(pv[0]); execvp(*chp->argv, chp->argv); } close(pv[1]); tmp_buff = fork_scan(tmp_sizep, pid, pv[0], 0); close(pv[0]); if (n_error) save_intr(n_error); /* restore n_error */ return tmp_buff; } u_char *fork_split(int *sizep, PP *pp, PP *ps)/*tcb*/ { int i, pid, pv[2]; u_char *cp; PP *pe; FILE *fp; if (!pp->prev) { for (i = 1, pe = ps; i < pp->tell; pe = pe->next, i++) ; i = 1; } else for (i = 1; i < pp->tell; ps = ps->next, i++) ; i = ((pp->next) ? pp->next->tell : pp->split) - i; for (pe = ps; i; pe = pe->next, i--) ; pipe(pv); if (!(pid = fork())) { close(pv[0]); fp = fdopen(pv[1], "w"); if (ps->f.code) for (; ps != pe; ps = ps->next) { for (i = pp->f.len, cp = ps->cs; i; i--, cp++) if (*cp < ' ' || *cp == K_dl) fputc(*cp + '@', fp); else if (*cp > K_dl) fputc(' ', fp); else fputc(*cp, fp); fputc('\n', fp); } else for (; ps != pe; ps = ps->next) { fwrite(ps->cs, 1, ps->f.len, fp); if (ps->f.nl) fputc('\n', fp); } fclose(fp); exit(0); } close(pv[1]); cp = fork_scan(sizep, pid, pv[0], 0); close(pv[0]); return cp; } u_char *fork_grep(int *sizep, u_char str[], PP *pp, int f_fgrep)/*tcb*/ { u_char *cp, *ce; int i, pid, pv[4], f_bs; CHILD *chp; FILE *fp; f_bs = strchr(str, K_h) != NULL; pipe(pv); if (!(pid = fork())) { signal(SIGPIPE, SIG_DFL); pipe(&pv[2]); if (!fork()) { close(pv[2]); fp = fdopen(pv[3], "w"); if (pp->f.code) for (; pp; pp = pp->next) { for (i = pp->f.len, cp = pp->cs; i; i--, cp++) if (*cp < ' ' || *cp == K_dl) fprintf(fp, "%c%c", K_a0, *cp+'@'); else if (*cp > K_dl) fputc('*', fp); else fputc(*cp, fp); fputc('\n', fp); } else for (; pp; pp = pp->next) { if (!pp->f.len) fputc(' ', fp); else if (!f_bs && pp->attr) /* bold or underline attribute */ for (ce = pp->cs + pp->f.len, cp = pp->cs; cp < ce; cp++) if (*cp == K_h) if (cp[1] == K_h) cp += 3; else if (cp[1] >= 0x80) cp += 2; else cp++; else if (*cp == '_') if (cp[1] == '_' && cp[2] == K_h && cp[3] == K_h) cp += 3; else if (cp[1] == K_h) cp++; else fputc(*cp, fp); else fputc(*cp, fp); else if (pp->f.nl && pp->f.str) fwrite(pp->cs, 1, strlen(pp->cs), fp); /* for complete filename */ else fwrite(pp->cs, 1, pp->f.len, fp); fputc('\n', fp); } fclose(fp); exit(0); } close(0); dup2(pv[2], 0); close(pv[2]); close(pv[3]); close(1); dup2(pv[1], 1); close(pv[1]); close(pv[0]); if (pp->f.code) print_ctrl(K_a0, str); chp = get_child(NULL, NULL , (f_fgrep) ? s_S(S_fgrep) : s_S(S_egrep), str); execvp(*chp->argv, chp->argv); } close(pv[1]); cp = fork_scan(sizep, pid, pv[0], 0); close(pv[0]); return cp; } u_char *fork_grep2(int *sizep, u_char str[], char name[])/*tcb*/ { u_char *buff; int pid, pv[2]; pipe(pv); if (!(pid = fork())) { signal(SIGPIPE, SIG_DFL); dup_error(); close(1); dup2(pv[1], 1); close(pv[1]); close(pv[0]); execlp(s_S(S_egrep), s_S(S_egrep), "-b", str, name, NULL); } close(pv[1]); buff = fork_scan(sizep, pid, pv[0], 0); close(pv[0]); return buff; } u_char *fork_grep3(int *sizep, u_char *buff, u_char str[], char name[])/*tcb*/ { int i, pid, pv[4]; FILE *fp; pipe(pv); if (!(pid = fork())) { signal(SIGPIPE, SIG_DFL); pipe(&pv[2]); if (!fork()) { close(pv[2]); fp = fdopen(pv[3], "w"); sscanf(name, "%d", &i); for (; i; i--) fputc(*buff++, fp); fclose(fp); exit(0); } dup_error(); close(0); dup2(pv[2], 0); close(pv[2]); close(pv[3]); close(1); dup2(pv[1], 1); close(pv[1]); close(pv[0]); execlp(s_S(S_egrep), s_S(S_egrep), "-b", str, NULL); } close(pv[1]); buff = fork_scan(sizep, pid, pv[0], 0); close(pv[0]); return buff; } FILE *fork_man(int *pidp, char str[])/*tcb*/ { int pid, argc; static int pv[2]; char *cp, **argv, env[N_char] = {'\0',}; CHILD *chp; pipe(pv); argv = alloc_arg(str, &argc); if (argc > 2) { CHILD child; char *p; if ((cp = strchr(argv[0], '='))) { strcpy(env, argv[0]); cp = &strchr(str, ' ')[1]; } else cp = str; p = alloca(strlen(s_S(S_man)) + 1 + strlen(cp) + 1); sprintf(p, "%s %s", s_S(S_man), cp); free_arg(argv); argv = alloc_arg(p, &argc); chp = &child; chp->argv = argv; } else chp = get_child(NULL, NULL, s_S(S_man), argv[0]); if (!(pid = fork())) { dup_error(); close(1); dup2(pv[1], 1); close(pv[1]); close(pv[0]); setenv("PAGER", "cat", 1); if (*env) { cp = strchr(env, '='); *cp = '\0'; setenv(env, &cp[1], 1); } signal(SIGCHLD, SIG_DFL); signal(SIGPIPE, SIG_DFL); execvp(*chp->argv, chp->argv); } free_arg(argv); close(pv[1]); *pidp = pid; return fdopen(pv[0], "r"); } FILE *fork_pipe(int f_chp, CHILD *chp, char name[], int *pidp)/*tcb*/ { int pid, pv[4]; CHILD *chp2; if (f_chp == 7 || f_chp == 6) { chp2 = (CHILD*)chp->argv[chp->f.argc + 1]; chp2 = get_child(chp2, NULL, chp2->argv[0], name); } else { strcpy(chp->argv[chp->f.argc], name); chp2 = NULL; } pipe(pv); if (!(pid = fork())) { signal(SIGPIPE, SIG_DFL); dup_error(); if (chp2) { pipe(&pv[2]); if (!fork()) { close(1); dup2(pv[3], 1); close(pv[3]); close(pv[2]); execvp(*chp2->argv, chp2->argv); } close(0); dup2(pv[2], 0); close(pv[2]); close(pv[3]); } close(1); dup2(pv[1], 1); close(pv[1]); close(pv[0]); execvp(*chp->argv, chp->argv); } close(pv[1]); *pidp = -pid; return fdopen(pv[0], "r"); }