#include "tcb.h" #include #include #include static struct { char str[N_line], argv[8][256]; LIST *bin; } Child; CHILD *save_child(CHILD *chp, char *cp0, int f_child)/*tcb*/ { if (chp == EOC) { Child.bin = free_list(Child.bin); return NULL; } if (!chp) { int i, j, k, n_str; char *p, *cp; PN pn; CHILD *chp2 = NULL; for (i = 0; cp0[i]; i++) if (cp0[i] == '\t') cp0[i] = ' '; cp = alloca(strlen(cp0) + 1); strcpy(cp, cp0); if ((p = strchr(cp, '|'))) { *p++ = '\0'; i = p - cp; p = cp; chp2 = save_child(NULL, p, 2); p = strchr(p, ' '); strcpy(p, &cp[i]); } chp = calloc(sizeof(CHILD), 1); for (n_str = 0; n_str >= 0; n_str++) { /* Child.argv[0] ==> chp->suffix, Child.argv[1..] ==> chp->argv[0..] */ if (f_child == 4 && (!n_str || n_str == 2)) { /* EDITOR (tcbrc) */ if (!n_str) strcpy(Child.str, s_P(P_mode)[M_edit]); /* mark of editor */ else if (n_str == 2) /* line-No. for editor */ strcpy(Child.str, "+??????????"); i = strlen(Child.str); } else if (f_child == 5 && n_str != 1) { /* SHELL (tcbrc) */ if (!n_str) strcpy(Child.str, s_P(P_mode)[M_shell]); /* mark for shell */ else if (n_str == 2) strcpy(Child.str, "-i"); i = (n_str == 3) ? 0 : strlen(Child.str); } else { while (*cp == ' ') cp++; if (!n_str && *cp != '.') { strcpy(Child.argv[0], "..."); continue; } if (*cp == '#') i = 0; /* comment line */ else /* string enclosed in ' or " */ if (*cp == '\047') { for (i = 0, cp++; *cp != '\047'; cp++, i++) if ((Child.str[i] = *cp) == 0) break; cp++; } else if (*cp == '\042') { for (i = 0, cp++; *cp != '\042'; cp++, i++) if ((Child.str[i] = *cp) == 0) break; cp++; } else for (i = 0; *cp != ' '; cp++, i++) if ((Child.str[i] = *cp) == 0) break; } if (!i) { /* no more string */ k = !strcmp(Child.argv[0], s_P(P_mode)[M_shell]); chp->f.argc = n_str - 1; /* chp->argv[chp->f.argc] <== filename */ chp->argv = calloc(sizeof(char*), chp->f.argc + 2 - k); if (is_fm() && !strcmp(s_S(S_du), Child.argv[1])) ; /* need no filename */ else if (chp2) chp->argv[chp->f.argc + 1] = (char*)chp2; else if (!k) /* allocate memory for argument */ chp->argv[chp->f.argc] = calloc(1, N_line); for (j = 0; j < chp->f.argc+1; j++) { if (j) chp->argv[j-1] = strdup(Child.argv[j]); else chp->suffix = strdup(Child.argv[j]); } if (!is_inst(s_S(S_path), *chp->argv)) { /* chp->argv[0] isn't installed */ if (!load_list(Child.bin, chp->argv[0], &pn)) { Child.bin = save_list(Child.bin, chp->argv[0], &pn); save_error("tcbrc: %s: %s.\n", *chp->argv, s_S(S_errc)); } for (i = 0; i < chp->f.argc + 1; i++) if (chp->argv[i]) free(chp->argv[i]); free(chp->argv); if (chp->suffix) free(chp->suffix); free(chp); chp = NULL; } else switch(f_child) { case 1: chp->f.chp = 1; break; case 2: chp->f.chp = is_chp(NULL, chp->argv[0]); break; case 3: chp->f.exec = 1; /* EXEC (tcbrc) */ break; } break; } else { Child.str[i] = 0; strcpy(Child.argv[n_str], Child.str); } } } else chp->next = save_child(chp->next, cp0, f_child); return chp; } CHILD *check_ext(char *name, u_char *split, int size)/*tcb*/ { /* check suffix to set program-name */ int i, len; CHILD *chp, *chp0 = NULL; char *cp; struct stat st; FILE *fp; if (name && *name == ' ') return NULL; len = 0; if (name) for (chp = get_child(NULL, NULL, s_S(S_gzip), NULL); chp; chp = chp->next){ if (!(cp = strstr(name, chp->suffix)) || !chp->argv[0]) continue; if (cp[strlen(chp->suffix)]) continue; if (strlen(chp->suffix) >= len) { chp0 = chp; len = strlen(chp->suffix); } } if (!(chp = chp0)) { /* read `N_man' bytes to check format of manual-page */ if (split) { /* read memory */ st.st_size = -1; if (size > N_man) size = N_man; } else /* read file */ if (stat(name, &st) < 0 || !st.st_size) split = NULL; else { size = N_man; split = calloc(1, size +3); /* for man[3] (is_man()) */ fp = fopen(name, "r"); size = fread(split, 1, size + 3, fp); fclose(fp); } if (split) { for (i = 0, cp = split; i < size; ) { if (is_man(cp)) break; while (i++ < size && *cp++ != '\n') ; } if (i < size) { cp = (st.st_size < 0) ? NULL : name; chp = get_child(NULL, NULL, s_S(S_groff), cp); } if (st.st_size >= 0 && split) free(split); } } return chp; } CHILD *init_child(void)/*tcb*/ { /* alloc builtin program */ int i; char **app; CHILD *chp; app = s_P(P_child); i = (is_fm()) ? 0 : S_egrep - S_ls; for (chp = NULL; app[i]; i++) chp = save_child(chp, app[i], 0); return chp; } CHILD *get_child(CHILD *chp0, char *suffix, char *bin, char *name)/*tcb*/ { static CHILD *child; CHILD *chp; if (!suffix && !bin && !name) { if (chp0) child = chp0; return child; } for (chp = (chp0) ? chp0 : child; chp; chp = chp->next) if (suffix && ((!strcmp(suffix, s_P(P_mode)[M_edit]) || !strcmp(suffix, s_P(P_mode)[M_shell])) && !strcmp(chp->suffix, suffix))) break; else if (!bin || (bin && !strcmp(*chp->argv, bin))) if (!suffix || !strcmp(chp->suffix, suffix)) break; if (chp && name) /* set argument */ strcpy(chp->argv[chp->f.argc], name); return chp; } int cat_child(CHILD *chp, char pathname[])/*tcb*/ { /* set `filename (program)' to FILE-list */ int i; if (!chp) return 0; i = strlen(pathname); if (pathname[0] == ' ' || pathname[i-1] == '/') return 0; strcat(pathname, " ("); strcat(pathname, *chp->argv); strcat(pathname, ")"); return i; } static void free_chp(CHILD *chp) { int argc, f_pipe; f_pipe = !chp->argv[chp->f.argc] && strcmp(chp->suffix, "...") && *chp->suffix != ' '; /* s_P(P_mode)[M_shell] */ for (argc = 0; chp->argv[argc]; argc++) free(chp->argv[argc]); if (f_pipe) free_chp((CHILD*)chp->argv[argc + 1]); if (chp->suffix) free(chp->suffix); free(chp->argv); free(chp); } void free_child(CHILD *chp0)/*tcb*/ { CHILD *chp, *chb; for (chb = chp = chp0; chp; chp = chb) { chb = chp->next; free_chp(chp); } } int is_child(char name[], CHILD *chp)/*tcb*/ { int f_M; if (strcmp(chp->argv[chp->f.argc - 1], "-")) strcpy(chp->argv[chp->f.argc], name); if (chp->f.exec) f_M = T_exec; else if (!strcmp(*chp->argv, s_S(S_groff))) f_M = T_roff; else if (!strcmp(*chp->argv, s_S(S_tar))) f_M = T_tar; else if (!strcmp(*chp->argv, s_S(S_lha))) f_M = T_lha; else if (!strcmp(*chp->argv, s_S(S_unzip))) f_M = T_unzip; else if (!strcmp(*chp->argv, s_S(S_gzip))) f_M = T_gz; else f_M = T_bin; return f_M; } CHILD *load_chp(char arg[])/*tcb*/ { CHILD *chp; char *cp, str[80]; if (*arg == K_z) chp = NULL; else if ((cp = strchr(arg, '('))) { strcpy(str, &cp[1]); *strchr(str, ')') = '\0'; chp = get_child(NULL, NULL, str, NULL); } else chp = NULL; return chp; } int is_chp(CHILD *chp, char *arg)/*tcb*/ { if (arg) { CHILD *chp1, *chp2; chp1 = get_child(NULL, NULL, NULL, NULL); while (chp1) { if (chp1->f.chp && (chp2 = (CHILD*)chp1->argv[chp1->f.argc + 1])) if (!strcmp(chp2->argv[0], arg)) return 1; chp1 = chp1->next; } return 0; } else { if (!chp->f.chp) return 0; if (!chp->argv[chp->f.argc]) return (!strcmp(((CHILD*)chp->argv[chp->f.argc + 1])->argv[0] , s_S(S_bzip2))) ? 7 : 6; if (!strcmp(chp->argv[0], s_S(S_tar))) return 5; if (!strcmp(chp->argv[0], s_S(S_lha))) return 4; if (!strcmp(chp->argv[0], s_S(S_unzip))) return 3; if (!strcmp(chp->argv[0], s_S(S_bzip2))) return 2; return chp->f.chp; } }