#include "tcb.h" #include #include #include #include #include #include static struct { int abort; jmp_buf jb; } Sub; static void sub_clear(int dummy) { Sub.abort = 1; longjmp(Sub.jb, 0); } static void sspc(u_char *cp, u_char *np) { /* convert space character for sscanf() */ if (np) do { if (*cp && *cp < ' ') { *np++ = K_o; *np++ = *cp++ + '@'; } else if (*cp == ' ') { *np++ = K_a; cp++; } else *np++ = *cp++; } while (np[-1]); else for (; (cp = strchr(cp, ' ')); *cp = K_a) ; } void rspc(u_char *cp, u_char *np)/*tcb*/ { /* convert space character for sscanf() */ if (np) do { if (*cp == K_o) { *np++ = *++cp - '@'; cp++; } else if (*cp == K_a) { *np++ = ' '; cp++; } else *np++ = *cp++; } while (np[-1]); else for (; (cp = strchr(cp, K_a)); *cp = ' ') ; } static char *read_str(FILE *fp, u_char str[], STR **spp, LIST **lpp, int f, int m) { char tmp[N_line], name[N_line], *cp; PN pn; if (*str != K_l || !is_name(&str[1], m)) return NULL; if (!fgets(str, N_line, fp)) return NULL; cp = name; if (*str == K_l) return cp; do { if (*str == K_z) { cp = EOP; break; } if (f) { pn.row = pn.nrow = pn.top = 0; while (1) { if ((cp = strchr(str, '\n'))) *cp = '\0'; if (strlen(str)) break; if (!fgets(str, N_line, fp)) return NULL; } memcpy(tmp, str, N_line-1); tmp[N_line-1] = '\0'; } else { sscanf(str, "%s %d %d %d %d", tmp, &pn.row, &pn.nrow, &pn.top, &pn.line); if (pn.row < 0) pn.row = 0; if (pn.top < 0) pn.top = 0; if (pn.nrow < 0) pn.nrow = 0; if (!pn.line) pn.line = -1; } rspc(tmp, name); if (lpp) { if (spp) *spp = save_str(*spp, name, &pn); *lpp = save_list(*lpp, name, &pn); } else *spp = save_history(*spp, name, 0); } while ((cp = fgets(str, N_line, fp)) && *str != K_l); return cp; } static void delete_str(STR *sp, char name[]) { while (sp) { if (sp->name && !strcmp(sp->name, name)) { free(sp->name); sp->name = NULL; break; } sp = sp->next; } } static void get_par(char *dir) { /* set parent directory name to dir[] */ if (!strcmp(dir, "/")) return; for (dir = &strchr(dir, '\0')[-2]; *dir != '/'; dir--) ; dir[1] = '\0'; } static void get_time(char str[]) { struct tm tt; time_t ll; time(&ll); memcpy(&tt, localtime(&ll), sizeof(struct tm)); strcpy(str, asctime(&tt)); *strchr(str, '\n') = '\0'; } static void print_list(LIST *lp, FILE *fp) { if (lp) { print_list(lp->left, fp); fprintf(fp, "%s\n", lp->name); print_list(lp->right, fp); } } static void write_str(FILE *fp, STR *sp, LIST *lp, int f, int m) { /* save strings to ~/.tcb/history in STR-list sequence */ char name[N_line]; fprintf(fp, "%c%s\n", K_l, s_P(P_mode)[m]); if (sp) { for (; sp; sp = sp->next) if (sp->name) { if (lp) load_list(lp, sp->name, &sp->pn); sspc(sp->name, name); if (f) fprintf(fp, "%s\n", name); else fprintf(fp,"%s %d %d %d %d\n" , name, sp->pn.row, sp->pn.nrow, sp->pn.top, sp->pn.line); } } else print_list(lp, fp); } int find_prog(LIST *prog, u_char buff[])/*tcb*/ { /* search for buff[] in the program-list of PROGRAM */ if (prog) { int i; char *cp; if (find_prog(prog->left, buff)) return 1; if ((cp = strchr(prog->name, ' '))) *cp = '\0'; i = strncmp(buff, prog->name, strlen(prog->name)); if (cp) *cp = ' '; if (!i) return 1; if (find_prog(prog->right, buff)) return 1; } return 0; } GREP *load_grep(GREP *grep)/*tcb*/ { GREP *gp; if (!grep) return grep; gp = grep->prev; free(grep); return gp; } GREP *save_grep(GREP *grep)/*tcb*/ { GREP *gp; gp = calloc(sizeof(GREP), 1); gp->prev = grep; return gp; } int find_grep(GREP *grep, BASE *bp)/*tcb*/ { GREP *gp; if (!grep) return 0; do { gp = grep->prev; if (grep->bp == bp) return 1; } while ((grep = gp)); return 0; } LIST *delete_name(LIST *lp, STR *sp, STR *rsp, FILE *fp)/*tcb*/ { char *cp, str[N_line]; int i; for (i = 0; fgets(str, N_line, fp); i++) { if ((cp = strchr(str, '\n'))) *cp = '\0'; delete_str(sp, str); } if (i) { lp = free_list(lp); while (rsp) { /* build-in */ if (rsp->name) lp = save_list(lp, rsp->name, &rsp->pn); rsp = rsp->next; } while (sp) { if (sp->name) lp = save_list(lp, sp->name, &sp->pn); sp = sp->next; } } return lp; } static STR *save_hist(STR *hist, char name[], PN pn) { if (!hist) { hist = calloc(sizeof(STR), 1); hist->name = strdup(name); memcpy(&hist->pn, &pn, sizeof(PN)); } else hist->next = save_hist(hist->next, name, pn); return hist; } static int find_hist(STR *hist, char *name, int *countp) { int count; if (!hist) count = 0; else for (count = 1; hist->next; hist = hist->next) count++; *countp = count; if (!hist || name == EOE || strcmp(name, hist->name)) return 0; return 1; } STR *save_history(STR *hist, char name[], int f_find)/*tcb*/ { static int n_history; static PN pn; int count; STR *sp; if (hist == EOP) { sscanf(name, "%d", &n_history); return NULL; } else if (hist == EOE) { sprintf(name, "%d", n_history); return NULL; } else if (f_find < 0) { find_hist(hist, EOE, &count); sprintf(name, "%d", count); return NULL; } count = strlen(name) - 1; if (name[count] == '\r') /* '\r' SHELL-prompt */ name[count] = '\0'; if (f_find && find_hist(hist, name, &count)) return hist; if (hist && count == n_history) { sp = save_hist(hist->next, name, pn); free(hist->name); free(hist); } else sp = save_hist(hist, name, pn); return sp; } STR *free_history(STR *hist, char tmp[], int n_hist)/*tcb*/ { int count; STR *sp; sscanf(tmp, "%d", &count); if ((count -= n_hist) <= 0) return hist; for (; count; count--) { sp = hist; hist = hist->next; free(sp->name); free(sp); } find_hist(hist, EOE, &count); return hist; } void find_list(LIST *lp, char name[], int *ip)/*tcb*/ { if (lp && !*ip) { find_list(lp->left, name, ip); if (!strcmp(lp->name, name)) *ip = 1; find_list(lp->right, name, ip); } } STR *save_str(STR *sp, char name[], PN *pnp)/*tcb*/ { if (!sp) { sp = calloc(sizeof(STR), 1); sp->name = strdup(name); memcpy(&sp->pn, pnp, sizeof(PN)); } else if (!sp->name || strcmp(sp->name, name)) sp->next = save_str(sp->next, name, pnp); return sp; } STACK *read_stack(STACK *sp, void *p, int f_read)/*tcb*/ { while (sp) { switch(f_read) { case 0: if (p == sp->bp) goto jump; break; default: break; } sp = sp->next; } jump: return sp; } STACK *load_stack(STACK *sp, LINE *lp, int *f_Mp, char *name, BASE **bpp, BASE base[])/*tcb*/ { STACK *s0, *sb = NULL; if (!sp) return sp; s0 = sp; while (sp->next) { sb = sp; sp = sp->next; } if (sp->f.bp) { if ((*bpp && *bpp < &base[0]) || *bpp > &base[N_base-1]) { free_bp(*bpp); free(*bpp); } } *bpp = sp->bp; if (name) strcpy(name, sp->name); strcpy(lp->prev, sp->prev); strcpy(lp->dir, sp->dir); strcpy(lp->old, sp->old); strcpy(lp->arg, sp->arg); free(sp->prev); free(sp->name); free(sp->dir); free(sp->old); free(sp->arg); *f_Mp = sp->f.M; free(sp); if (sb) { sb->next = NULL; return s0; } else return NULL; } STACK *save_stack(STACK *sp, LINE *lp, int f_M, char name[], BASE *bp, int f_bp)/*tcb*/ { if (!sp) { sp = calloc(sizeof(STACK), 1); sp->bp = bp; sp->prev = strdup(lp->prev); sp->name = strdup(name); sp->dir = strdup(lp->dir); sp->old = strdup(lp->old); sp->arg = strdup(lp->arg); sp->f.M = f_M; sp->f.bp = f_bp; } else sp->next = save_stack(sp->next, lp, f_M, name, bp, f_bp); return sp; } STACK *save_stack_dir(STACK *sp, char dir[], char old[], BASE *bp)/*tcb*/ { /* save current directory (bottom of the stack) */ char str[3]; sprintf(str, "%c%c", K_z, 0); sp = calloc(sizeof(STACK), 1); sp->bp = bp; sp->prev = strdup(str); sp->name = strdup(dir); sp->dir = strdup(dir); sp->old = strdup(old); sp->arg = strdup(str); sp->f.M = T_dir; sp->f.bp = 1; return sp; } void get_name(char *pathname)/*tcb*/ { /* set regular filename to pathname */ char *cp, *cp0 = pathname; while ((cp = strchr(pathname, '/'))) pathname = &cp[1]; if (cp0 != pathname) strcpy(cp0, pathname); } int get_dir(char *pathname)/*tcb*/ { /* set current directory name to pathname */ char *cp; if (!strchr(pathname, '/') || !strcmp(pathname, "/")) return 0; while ((cp = strchr(pathname, '/'))) pathname = &cp[1]; *pathname = 0; return 1; } void erase_dot(char name[])/*tcb*/ { /* rid name[] of current ("./") or parent ("../") directory name */ int i, j; char *cp, tmp[N_line]; for (cp = name; *cp && (cp = strstr(cp, "./")); ) if (cp > name && cp[-1] == '.') { /* skip "../" */ cp++; continue; } else if (cp[2]) strcpy(cp, &cp[2]); /* erase "./" */ else *cp = '\0'; if ((cp = strstr(name, "../"))) { strcpy(tmp, cp); *cp = '\0'; while (strlen(tmp) && (cp = strstr(tmp, "../"))) if (cp == tmp) { get_par(name); strcpy(tmp, &cp[3]); } else { i = strlen(name); j = cp - tmp; memcpy(&name[i], tmp, j); name[i + j] = '\0'; strcpy(tmp, cp); } } else *tmp = '\0'; if (strlen(tmp)) strcat(name, tmp); } int read_list(LL *llp, SS *ssp, LINE *lp, char name[], CUT *cutp)/*tcb*/ { char *cp, str[N_line], str1[N_line]; int f; static FILE *fp; static char argv0[256], s_hist[256]; if (!s_S(S_hist)) return 0; signal(SIGSEGV, sub_clear); setjmp(Sub.jb); if (Sub.abort) { fclose(fp); unlink(s_S(S_hist)); /* rm ~/.tcb/history */ *lp->dir = '\0'; return 0; } strcpy(s_hist, s_S(S_hist)); strcat(s_hist, ".old"); if (!(fp = fopen(s_S(S_hist), "r"))) { /* ~/.tcb/history */ if (!(fp = fopen(s_hist, "r"))) /* ~/.tcb/history.old */ return 0; } else { memset(str, 0, 9); fseek(fp, -8, 2); fread(str, 1, 8, fp); if (!strchr(str, K_z)) { /* ~/.tcb/history doesn't contain EOF (^Z) */ fclose(fp); rename(s_hist, s_S(S_hist)); if (!(fp = fopen(s_S(S_hist), "r"))) return 0; } else { while (!fseek(fp, -2, 1) && fgetc(fp) != K_l) ; memset(str, 0, 9); fread(str, 1, 8, fp); if (!strncmp(&str[1], "TCB", 3)) { save_stderr("%s: %s.\n", s_S(S_hist), s_S(S_errj)); fclose(fp); return -1; } fseek(fp, 0, 0); } } if (!fgets(str, N_line, fp)) return 0; do { cp = fgets(str, N_line, fp); } while (*str == '\n' || *str == K_l || *str == '#'); *str1 = '\0'; sscanf(str, "%s %s %s %s %s %d %s %s" , lp->old, lp->dir, lp->arg, lp->prev, name, &f, str1, argv0); if (*name == '/' && access(name, F_OK) < 0) { save_error("%s: %s: %s.\n", s_S(S_hist), name, strerror(ENOENT)); *lp->old = '.'; if (*str1) *str1 = '\0'; } if (*lp->old == '.') { /* mode-line: ./ (ls) */ getcwd(str, N_line); if (strchr(str, '\0')[-1] != '/') strcat(str, "/"); strcpy(lp->old, str); strcpy(lp->dir, str); strcpy(name, str); *lp->prev = K_z; } else if (*argv0) cutp->chp = get_child(NULL, NULL, argv0, NULL); rspc(lp->arg, NULL); rspc(name, NULL); rspc(str1, cutp->str); fgets(str, N_line, fp); f = 0; do { if (!read_str(fp, str, &ssp->p.file, &llp->p.file, 0, M_lfile)) continue; if (!read_str(fp, str, &ssp->p.dir, &llp->p.dir, 0, M_ldir)) continue; if (!read_str(fp, str, &ssp->p.man, &llp->p.man, 0, M_man)) continue;; if (!read_str(fp, str, &ssp->p.grep, &llp->p.grep, 1, M_cut)) continue; if (!read_str(fp, str, &ssp->p.cmd, &llp->p.cmd, 1, M_cmd)) continue; if (!read_str(fp, str, &ssp->p.hist, NULL, 0, M_hist)) continue; if (!read_str(fp, str, &ssp->p.hfile, NULL, 0, T_hfile)) continue; if (!read_str(fp, str, &ssp->p.hdir, NULL, 0, T_hdir)) continue; if (!read_str(fp, str, &ssp->p.hman, NULL, 0, T_hman)) continue; if (!read_str(fp, str, &ssp->p.hlocate, NULL, 0, T_hlocate)) continue; if (!read_str(fp, str, &ssp->p.hfgrep, NULL, 0, T_hfgrep)) continue; if (!read_str(fp, str, &ssp->p.hegrep, NULL, 0, T_hegrep)) continue; if (!read_str(fp, str, &ssp->p.mode, &llp->p.mode, 0, T_mode)) continue; f = 1; } while (0); if (!f) { /* broken file or old format */ save_error("%s: %s: %s.\n", s_S(S_tcb), s_S(S_hist), s_S(S_errm)); kill(getpid(), SIGSEGV); } fclose(fp); return 0; } void write_list(LL ll, SS ss, LINE *lp, char name[], CUT cut)/*tcb*/ { FILE *fp; char str[N_line], str1[N_line]; if (!s_S(S_hist)) return; strcpy(str, s_S(S_hist)); strcat(str, ".old"); rename(s_S(S_hist), str); /* backup */ if (!(fp = fopen(s_S(S_hist), "w"))) return; get_time(str); fprintf(fp, "# ~/.%s/history: %s\n", s_S(S_tcb), getenv("TCB")); fprintf(fp, "# E\010EX\010XI\010IT\010T: %s\n", str); fprintf(fp, "# Note: The lines begin with the character \014 or \032 mustn't be deleted.\n\n"); fprintf(fp, "%c Current buffer\n", K_l); sspc(lp->arg, NULL); sspc(name, NULL); sspc(cut.str, str1); cut.chp = (*cut.str) ? check_ext(name, NULL, 0) : NULL; fprintf(fp,"%s %s %s %s %s %d %s %s\n" , lp->old, lp->dir, lp->arg, lp->prev, name, 0 , str1, (cut.chp) ? cut.chp->argv[0] : ""); write_str(fp, ss.p.file, ll.p.file, 0, M_lfile); write_str(fp, ss.p.dir, ll.p.dir, 0, M_ldir); write_str(fp, ss.p.man, ll.p.man, 0, M_man); write_str(fp, ss.p.grep, NULL, 1, M_cut); write_str(fp, ss.p.cmd, NULL, 1, M_cmd); write_str(fp, ss.p.hist, NULL, 1, M_hist); write_str(fp, ss.p.hfile, NULL, 1, T_hfile); write_str(fp, ss.p.hdir, NULL, 1, T_hdir); write_str(fp, ss.p.hman, NULL, 1, T_hman); write_str(fp, ss.p.hlocate, NULL, 1, T_hlocate); write_str(fp, ss.p.hfgrep, NULL, 1, T_hfgrep); write_str(fp, ss.p.hegrep, NULL, 1, T_hegrep); write_str(fp, ss.p.mode, ll.p.mode, 0, T_mode); fprintf(fp, "%c\n", K_z); fclose(fp); } LIST *free_list(LIST *list)/*tcb*/ { if (list) { free_list(list->left); if (list->name) free(list->name); free_list(list->right); free(list); } return NULL; } void free_str(STR *sp)/*tcb*/ { STR *sb; while (sp) { if (sp->name) free(sp->name); sb = sp->next; free(sp); sp = sb; } } BASE *init_str(int f_M, BASE *bp, STR s0[], char name[])/*tcb*/ { int f_grep = 0, f_kana = 0; switch(f_M) { case T_hfgrep: case T_hegrep: f_grep = 1; case T_hfile: case T_hdir: if (!f_grep) f_kana = 1; case M_hist: case T_hist: case T_hman: case T_hlocate: case M_key: free_bp(bp); default: bp->pp = alloc_str(s0, &bp->nrow, f_grep, f_kana); if (!bp->nrow) make_bp(bp, s_S(S_err2), name, NULL); break; } return bp; } BASE *init_list(int f_M, BASE *bp, LIST *lp, char name[])/*tcb*/ { int f_grep = 0, f_kana = 0; switch(f_M) { case M_egrep: case M_cut: f_grep = 1; case M_lfile: case M_ldir: case M_list: case T_list: if (!f_grep) f_kana = 1; case M_man: case M_prog: case M_cmd: case T_cmd: free_bp(bp); default: if (!bp->pp) bp->pp = alloc_list(lp, &bp->nrow, f_grep, f_kana); if (!bp->nrow) make_bp(bp, s_S(S_err2), name, NULL); } return bp; } int load_list(LIST *list, char name[], PN *pn)/*tcb*/ { if (list) { if (load_list(list->left, name, pn)) return 1; if (!strcmp(list->name, name)) { if (pn) memcpy(pn, &list->pn, sizeof(PN)); return 1; } if (load_list(list->right, name, pn)) return 1; } return 0; } LIST *save_list(LIST *list, char name[], PN *pnp)/*tcb*/ { int i; if (!list) { list = calloc(sizeof(LIST), 1); list->name = strdup(name); memcpy(&list->pn, pnp, sizeof(PN)); } else if ((i = strcmp(list->name, name)) > 0) list->left = save_list(list->left, name, pnp); else if (i < 0) list->right = save_list(list->right, name, pnp); else memcpy(&list->pn, pnp, sizeof(PN)); return list; } char *utoa(u_int u)/*tcb*/ { /* convert unsigned-int to string */ char tmp[32]; static char str[32]; int i; i = 0; do { tmp[i++] = u % 10 + '0'; u /= 10; } while (u); tmp[i] = '\0'; for (u = 0, i = strlen(tmp); i; u++, i--) str[u] = tmp[i-1]; str[u] = '\0'; return (char*)str; } char *tobo(char str[], int f_nl)/*tcb*/ { /* convert str[] to bold attribute */ static char tmp[N_line]; int i, j; for (i = j = 0; str[i] && j < N_line - 4; i++, j += 3) { tmp[j] = str[i]; tmp[j+1] = K_h; tmp[j+2] = str[i]; } if (f_nl && str[i-1] != '\n') tmp[j++] = '\n'; tmp[j] = 0; return tmp; } char *toul(char str[], int f_nl)/*tcb*/ { /* convert str[] to underline attribute */ static char tmp[N_line]; int i, j; for (i = j = 0; str[i] && j < N_line - 4; i++, j += 3) { tmp[j] = '_'; tmp[j+1] = K_h; tmp[j+2] = str[i]; } if (f_nl && str[i-1] != '\n') tmp[j++] = '\n'; tmp[j] = 0; return tmp; } char *tome(char str[], int f_nl)/*tcb*/ { static char tmp[N_line]; int i, j; for (i = j = 0; str[i] && str[i] != '\n' && j < N_line - 2; i++, j++) { if (str[i] == K_h) i += 2; tmp[j] = str[i]; } if (f_nl && str[i-1] != '\n') tmp[j++] = '\n'; tmp[j] = 0; return tmp; } int ichrstr(char str0[], char c, char *str)/*tcb*/ { char *cp; if ((str && (cp = strstr(str0, str))) || (!str && (cp = strchr(str0, c)))) return (int)cp - (int)str0 + 1; else return 0; } void print_arg(char arg[], int size, u_char *buff, CHILD *chp, int f_M)/*tcb*/ { *arg = K_z; /* doesn't display mode-line[4] */ if (chp) if (size >= 0 && s_S(S_sh) && f_M != T_pipe5) sprintf(arg, " %d (%s)", size, *chp->argv); else sprintf(arg, " (%s)", *chp->argv); else switch(f_M) { case T_dir: sprintf(&arg[1], "(%s)", s_S(S_ls)); break; case T_du: sprintf(&arg[1], "(%s)", s_S(S_du)); break; case T_man: sprintf(&arg[1], "(%s)", s_S(S_man)); break; case T_pipe4: case T_pipe5: break; default: if (f_M != M_help && buff && size >= 0) sprintf(&arg[1], "%d", size); else arg[1] = '\0'; break; } } void dup_error()/*tcb*/ { int fd; if (!s_S(S_error)) return; fd = fileno(fopen(s_S(S_error), "a")); dup2(fd, 2); close(fd); } void save_error(char *fmt, ...)/*tcb*/ { FILE *fp; va_list ap; if (!s_S(S_error)) return; fp = fopen(s_S(S_error), "a"); va_start(ap, fmt); vfprintf(fp, fmt, ap); va_end(ap); fclose(fp); } void save_stderr(char *fmt, ...)/*tcb*/ { /* print to `stderr' after reset terminal */ static char *err; FILE *fp; va_list ap; if (!err) err = print_stderr(EOP); fp = fopen(err, "a"); va_start(ap, fmt); vfprintf(fp, fmt, ap); va_end(ap); fclose(fp); } void save_intr(int n_error)/*tcb*/ { FILE *fp; if (!n_error) return; fp = fopen(s_S(S_intr), "w"); fprintf(fp, "%d\n", n_error); fclose(fp); } int load_intr(void)/*tcb*/ { FILE *fp; int n_error; if (access(s_S(S_intr), F_OK) < 0) return 0; fp = fopen(s_S(S_intr), "r"); fscanf(fp, "%d", &n_error); fclose(fp); if (n_error == S_erre) unlink(s_S(S_intr)); return n_error; } char *is_inst(char *path, char *prog)/*tcb*/ { /* check whether `prog' exists on `path' or not */ int i; char *cp; static char str[N_line]; for (; (cp = strchr(path, ':')); ) { if (!prog) return cp; *cp = '\0'; strcpy(str, path); *cp++ = ':'; path = cp; strcat(str, "/"); strcat(str, prog); if ((i = ichrstr(str, ' ', NULL))) str[i-1] = '\0'; if (!access(str, X_OK|F_OK)) { if (i) str[i-1] = ' '; return str; } } return NULL; } int is_access(char name[], BASE *bp)/*tcb*/ { struct stat st; if (access(name, R_OK|F_OK) < 0) { /* No such file or directory */ make_bp(bp, strerror(errno), name, NULL); return -1; } else { stat(name, &st); if (!st.st_size) { /* No size */ make_bp(bp, s_S(S_err1), name, NULL); return -1; } } return 0; } int is_str(int f_M, int *n_bp)/*tcb*/ { int n_ll; do { switch(f_M) { case M_hist: case T_hist: n_ll = 6; break; case T_hfile: n_ll = 9; break; case T_hdir: n_ll = 10; break; case T_hman: n_ll = 11; break; case T_hlocate: n_ll = 12; break; case T_hfgrep: /* ^X^F ==> ^R (T_hfile:6) ==> ^S ==> ^R (T_hfgrep:11) */ /* ^I (M_list:8) ==> ^S ==> ^R (T_hfgrep:11) */ *n_bp = 11; n_ll = 13; continue; case T_hegrep: *n_bp = 11; n_ll = 14; continue; default: *n_bp = n_ll = 0; continue; } *n_bp = 6; } while (0); return n_ll; } int is_list(int f_M, int *n_bp)/*tcb*/ { int n_ll; *n_bp = 0; switch(f_M) { case M_egrep: n_ll = 5; *n_bp = 3; break; case M_lfile: n_ll = 1; break; case M_ldir: n_ll = 2; break; case M_prog: n_ll = 3; break; case M_man: n_ll = 4; break; case M_cut: n_ll = 5; break; case M_cmd: case T_cmd: *n_bp = 6; n_ll = 6; break; case M_list: case T_list: n_ll = 7; *n_bp = 8; /* ^R (T_hist:6) ==> ^I (T_list:8) */ break; default: n_ll = 0; break; } return n_ll; } int open_pty(char str[], int f_open)/*tcb*/ { char *cp, *np; int tfd, i; for (cp = "pqrs", np = NULL; *cp; cp++) for (np = "0123456789abcdef"; *np; np++) { sprintf(str, "/dev/pty%c%c", *cp, *np); if ((tfd = open(str, O_RDWR)) >= 0) { str[5] = 't'; if ((i = open(str, O_RDWR)) >= 0) { str[5] = 'p'; close(i); if (f_open) return tfd; else close(tfd); return 1; } str[5] = 'p'; close(tfd); } } return -1; } u_char *mtoa(int f_M)/*tcb*/ { /* exchange order of m.i */ union { u_char c[4]; int i; } m; int i, j; static u_char cstr[5]; conf_key(EOP, NULL, (int**)&f_M, (int**)&m.i); for (j = 0, i = 3; i >= 0; i--) if (m.c[i]) cstr[j++] = m.c[i]; cstr[j] = '\0'; return cstr; } void print_buff(u_char buff[])/*tcb*/ { /* display control character with reverse attribute */ int c, i, len; len = strlen(buff); for (i = 0; i < len; i++) if ((c = buff[i]) && (c < ' ' || c == K_dl || c == K_at)) { if (c == K_dl) c -= 0x80; else if (c == K_at) c = 0; vt_stand(); vt_putchar(c + '@'); vt_endstand(); } else vt_putchar(buff[i]); } void print_ctrl(int cc, u_char str[])/*tcb*/ { int c, i, j; u_char *p; p = alloca(strlen(str) * 2 + 1); for (i = j = 0; (c = str[i]); i++, j++) if (c < ' ' || c == K_dl) sprintf(&p[j++], "%c%c", cc, c + '@'); else if (c == K_at) sprintf(&p[j++], "%c@", cc); else p[j] = c; p[j] = '\0'; strcpy(str, p); } void unlink_file()/*tcb*/ { unlink(s_S(S_w)); unlink(s_S(S_mess)); unlink(s_S(S_intr)); if (s_S(S_pid)) unlink(s_S(S_pid)); else if (s_S(S_error)) { unlink(s_S(S_error)); unlink(s_S(S_log)); } } void print_pid(int pid)/*tcb*/ { FILE *fp = fopen(s_S(S_pid), "w"); fprintf(fp, "%d\n", pid); fclose(fp); } int strint(int tab[], int u)/*tcb*/ { int i; for (i = 0; tab[i]; i++) if (tab[i] == u) break; return tab[i]; } int is_comm(int f_M, int f_comm)/*tcb*/ { switch(f_comm) { case 0: switch(f_M) { case M_cp: f_M = T_cp; break; case M_rm: f_M = T_rm; break; case M_mv: f_M = T_mv; break; case M_arc: f_M = T_arc; break; case T_arc2: f_M = T_arc3; break; default: f_M = 0; break; } break; case 1: case 2: switch(f_M) { case T_cp: f_M = M_cp; break; case T_rm: f_M = M_rm; break; case T_mv: f_M = M_mv; break; case T_arc: f_M = M_arc; break; case T_arc3: if (f_comm == 1) { f_M = T_arc2; break; } default: f_M = 0; break; } break; case 3: switch(f_M) { case M_cp2: f_M = M_cp; break; case M_rm2: f_M = M_rm; break; case M_mv2: f_M = M_mv; break; default: f_M = 0; break; } break; } return f_M; } CHILD *check_chp(int s_i)/*tcb*/ { CHILD *chp; if (!(chp = get_child(NULL, NULL, s_S(s_i), NULL))) { char *p = alloca(strlen(s_S(s_i)) + 5); sprintf(p, " `%s\047.", s_S(s_i)); save_intr(S_errc); print_intr(NULL, p); return NULL; } return chp; } char *print_stderr(char *err0)/*tcb*/ { static char err[N_line]; int c; FILE *fp; if (err0 == EOP) return err; else if (err0) { strcpy(err, err0); return NULL; } else if (!*err) return NULL; if (access(err, F_OK) < 0) return NULL; fp = fopen(err, "r"); while ((c = fgetc(fp)) != EOF) fputc(c, stderr); fclose(fp); unlink(err); return NULL; } int conv_ls(u_char *buff)/*tcb*/ { int i, len; static char n[4] = {0,}; u_char *cp; i = strlen(buff); if (!strchr(buff, '\\')) return i; cp = buff; for (len = 0; i > 0; i--, cp++, len++) { if (*cp == '\\' && cp[1] != ' ') { memcpy(n, &cp[1], 3); *cp = (u_char)strtol(n, NULL, 8); strcpy(&cp[1], &cp[4]); i -= 3; } } return len; } int is_file(int f_M)/*tcb*/ { switch(f_M) { case T_dir: case T_du: case M_du: case M_lfile: case M_ldir: case T_hfile: case T_hdir: return 1; default: break; } return 0; }