/* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */ #if defined(ANDROID) #include #define index(s,c) strchr(s,c) #define rindex(s,c) strrchr(s,c) #endif #ifndef lint static char rcsid[]= "$Header: fep_com.c,v 4.9 91/05/29 14:30:43 utashiro Exp $ (SRA)"; #endif /* lint */ #include #include #include #include #ifdef TERMIOS #include #if defined(__linux__) || defined(__CYGWIN__) #ifndef _POSIX_VDISABLE #define _POSIX_VDISABLE '\0' #endif #endif #else #include #endif #include #include #include #include #include #if defined(sun) #include #endif #include "fep_defs.h" #include "fep_glob.h" #include "fep_funcs.h" int tty_fix_bell = OFF; /* ring bell if the tty mode is changed */ typedef struct { int cur_line; int max_line; } MORE; MORE *create_more(); #if defined(ANDROID) #define S_IREAD S_IRUSR #define S_IWRITE S_IWUSR #define S_IEXEC S_IXUSR #endif /* * Check command line if it call built-in function or not and execute it */ executeBuiltInFunction (comline, more) char *comline, **more; { register FunctionTableEnt *ftp; char linebuf[MAXCMDLEN], *line; char *search_string(); int argc; /* * Skip white space. */ while (isspace (*comline)) comline++; line = linebuf; strcpy (line, comline); if (more) { if (*more = search_string (comline, ";")) { *(line + (*more - comline)) = '\0'; do { *more += 1; } while (**more == ';'); } else { *more = (char*) 0; } } /* * Skip comment and blank line */ if (*line == '#' || *line == '\0') return (IGNORED); /* * All built-in command should be prefixed by 'fep-' */ if (strncmp (line, "fep-", 4) != 0) return (NOT_PROCESSED); for (ftp = BuiltinFuncTable; ftp->name; ftp++) { if (is_same_command (line, ftp->name)) { if (debug) showArgs (line); if ( condition() /* control structure should be processed on any condition */ || strncmp (line + 4, "if", 2) == 0 || strncmp (line + 4, "endif", 5) == 0 || strncmp (line + 4, "elseif", 6) == 0 || strncmp (line + 4, "else", 4) == 0 ) (*ftp->func)(line); return (PROCESSED); } } return (NOT_PROCESSED); } is_same_command (a, b) register char *a, *b; { while (*a && *b && *a == *b) ++a, ++b; if ((*a == '\0' || isspace ((unsigned char)*a)) && (*b == '\0' || isspace ((unsigned char)*b))) return 1; else return 0; } /* * Process 'fep-if' and 'fep-elseif' */ fep_if (comline) char *comline; { char *argv[MAXARGS]; int argc; char *err; int cond; int i; argc = mkargv (comline, argv, MAXARGS); if (argc != 2 && argc != 4) { printf ("%s: Illegal number of arguments\n", argv[0]); return; } /* * In case of only one argument, * treat as true if the variable is set. */ if (argc == 2) { char *cp; if (argv[1][0] == '$') cp = &argv[1][1]; else cp = &argv[1][0]; cond = look_var (cp) ? 1 : 0; } else { int value; /* * Substitute variable prefixed by '$' mark. */ for (i = 0; i < argc; i++) { if (argv[i][0] == '$') { char *v; if (v = look_var (&argv[i][1])) argv[i] = v; else argv[i] = ""; } } if (debug) { int i; char **argp; for (i = 0, argp = argv; *argp; argp++, i++) printf ("argv[%d] = \"%s\"\n", i, *argp); } /* * Check operator. */ if (eq (argv[2], "==") || eq (argv[2], "=")) value = 1; else if (eq (argv[2], "!=")) value = 0; else { printf ("%s: Unknown opperator \"%s\"", argv[0], argv[2]); return; } if (eq (argv[1], argv[3])) cond = value; else cond = !value; } if (eq (argv[0], "fep-elseif")) err = change_condition (cond); else err = push_condition (cond); if (err) printf ("%s: %s", argv[0], err); else if (debug) printf ("%s: %s\n", comline, cond ? "TRUE" : "FALSE"); return; } fep_else () { char *err; if (err = change_condition (1)) printf ("fep-else: %s", err); return; } fep_endif () { char *err; if (err = pop_condition ()) printf ("fep-endif: %s", err); return; } bind_to_key (comline) char *comline; { register FunctionTableEnt *fnte; char *argv[MAXARGS]; int argc; argc = mkargv (comline, argv, MAXARGS); /* * Something error occured. Print message and return */ if (argc < 0) { printf ("%s\n", argv[0]); return; } /* * Number of arguments should be three. */ if (argc != 3) { printf ("Invalid number of arguments\n"); return; } /* * Find the function name from function name table. */ for (fnte = FunctionNameTable; fnte->func; fnte++) { if (strcmp (fnte->name, argv[1]) == 0) { bind_key (curFuncTab, fnte->func, argv[2], fep_abort); break; } } /* * Couldn't find such a function */ if (fnte->func == NULL) printf ("%s: no such built-in command\n", argv[1]); } alias(comline) char *comline; { char *argv[MAXARGS]; int argc; argc = mkargv (comline, argv, MAXARGS); switch (argc) { case 1: show_aliaslist (NULL); break; case 2: show_aliaslist (argv[1]); break; case 3: set_alias (argv[1], argv[2]); break; default: printf ("%s: Illegal number of arguments.\n", argv[0]); } return; } unalias (comline) char *comline; { char *argv[MAXARGS]; int argc; int i; argc = mkargv (comline, argv, MAXARGS); for (i=1; ifunc; fnte++) { if (ft[i] == fnte->func) { if (!more(m)) return (0); /* * Show binding */ printf ("%s%s%c\t%s\n", prefix, i == 0 || isctlchar(i) ? "^" : "", unctl(i), fnte->name ); break; } } /* * Can't find such a function */ if (fnte->func == NULL) printf ( "%s%c\tunknown function (0x%x)\n", i == 0 || isctlchar(i) ? "^" : "", unctl(i), ft[i] ); } return (1); } show_help () { MORE *m; m = create_more(lines); if (m == 0) { errorBell (); return; } clear_edit_line (); more(m) && (printf ("Functions:\n") || 1) && showTable (m, FunctionNameTable) && more(m) && (printf ("Commands:\n") || 1) && showTable (m, BuiltinFuncTable) && more(m) && (printf ("Variables:\n") || 1) && showVariables (m); recover_edit_line (1); } showTable (m, fnte) MORE *m; FunctionTableEnt *fnte; { int i; /* * Search function name table */ for (; fnte->func; fnte++) { if (!more(m)) return (0); printf ("\t%-30s %s\n", fnte->name, fnte->help); } return (1); } showVariables (m) MORE *m; { extern VAR default_set_vars[], default_unset_vars[]; VAR *vp; for (vp = default_set_vars; vp->v_name; ++vp) { if (!vp->v_help) continue; if (!more(m)) return (0); printf ("\t%-30s %s\n", vp->v_name, vp->v_help); } for (vp = default_unset_vars; vp->v_name; ++vp) { if (!vp->v_help) continue; if (!more(m)) return (0); printf ("\t%-30s %s\n", vp->v_name, vp->v_help); } return (1); } MORE *create_more(maxline) int maxline; { MORE *mp; mp = (MORE *) malloc (sizeof (MORE)); if (mp == 0) return ((MORE*)0); else { mp->cur_line = 0; mp->max_line = maxline; return (mp); } } destroy_more(mp) MORE *mp; { if (mp) free (mp); } more (mp) MORE *mp; { /* * Print more message */ # define PUTMORE printf ( "--More--"); # define DELMORE printf ("\r \r"); if (mp->max_line && ++mp->cur_line >= mp->max_line) { PUTMORE; fflush (stdout); switch (getcharacter()) { case '\n': case '\r': case 'j': --mp->cur_line; break; case 'd': case ctrl('D'): mp->cur_line /= 2; break; case 'q': case 'Q': case ctrl('C'): DELMORE; return (0); default: mp->cur_line = 1; break; } DELMORE; } if (mp->cur_line == 1 && look_var ("clear-repaint") && term_clear) tputs (term_clear, 1, putch); return (1); } /* * Change directory */ fep_chdir (line) char *line; { char *argv[MAXARGS]; int argc; switch (mkargv (line, argv, MAXARGS)) { /* * Change directory with no arguments cause to chdir to home directory */ case 1: { char *home, *getenv(); if (home = getenv ("HOME")) argv[1] = home; else { printf ("Where is your home directory?\n"); return; } break; } /* * Change directory command with argument */ case 2: break; /* * Something error occured in mkargv. */ case -1: printf ("%s\n", argv[0]); return; default: printf ("fep-chdir: Invalid number of arguments.\n"); return; } /* * Chane directory. * Keep in mind that end process still in old directory */ if (chdir (argv[1]) < 0) { perror (argv[1]); return; } } fep_pwd (line) char *line; { char cwd[MAXPATHLEN]; (void) getcwd (cwd, sizeof(cwd)); printf ("%s\n", cwd); } fep_echo (comline) char *comline; { char *argv[MAXARGS]; int argc; char **argp; int putnewline = 1, first; argc = mkargv (comline, argv, MAXARGS); argp = &argv[1]; if (*argp && strcmp (*argp, "-n") == 0) { putnewline = 0; ++argp; } for (first = 1; *argp; argp++) { char *cp; /* * Put space */ if (! first) printf ("%s", " "); /* * Print argument */ if (**argp == '$' && (cp = look_var (*argp + 1))) printf ("%s", cp); else printf ("%s", *argp); first = 0; } if (putnewline) printf ("%c", '\n'); } fep_command (comline) char *comline; { char *argv[MAXARGS]; int argc; int i; char **argp; char buf[256]; argc = mkargv (comline, argv, MAXARGS); if (argc == 1) { printf ("Invalid number of arguments.\n"); return; } strcpy (buf, ""); for (i=1; i= 0 && (stb_home.st_mode&S_IREAD)) source_file (filename); /* * Source .feprc in current directory. */ if ((stat (".feprc", &stb_cur) >= 0 && stb_cur.st_ino != stb_home.st_ino)) source_file (".feprc"); return; } source_file (file) char *file; { FILE *fp; char line[512], line2[512]; int i = 0; if ((fp = fopen (file, "r")) == NULL) { perror (file); return; } while (fgets (line, 256, fp)) { i++; if (executeBuiltInFunction (line, 0) == NOT_PROCESSED) { char *cp = line; while (isspace (*cp)) cp++; strcpy (line2, "fep-"); strcat (line2, cp); if (executeBuiltInFunction (line2, 0) == NOT_PROCESSED) { printf ("\"%s\", line %d: cannot be executed\n", file, i); printf (">>> %s", line); } } } fclose (fp); return; } #define MAX_IF_NEST 10 #define CONDITION_MASK 0x00ff #define HAS_BEEN_TRUE 0x0100 int condition_stack [MAX_IF_NEST] = {1}; int current_if_stack = 0; condition () { int cond = 1, i; if (current_if_stack == 0) return (1); for (i = 1; i <= current_if_stack; i++) cond &= condition_stack [i]; return (cond & CONDITION_MASK); } char * change_condition (cond) int cond; { if (debug) printf ("old=0x%x, new=0x%x\n", condition_stack [current_if_stack], cond); if (current_if_stack > 0) { if (condition_stack [current_if_stack] & HAS_BEEN_TRUE) cond = 0; else if (cond != 0) condition_stack [current_if_stack] |= HAS_BEEN_TRUE; condition_stack [current_if_stack] &= ~CONDITION_MASK; condition_stack [current_if_stack] |= cond; return ((char *)0); } else return ("Not in if close\n"); } char * push_condition (cond) int cond; { if (current_if_stack < MAX_IF_NEST){ ++current_if_stack; condition_stack [current_if_stack] = cond; if (cond == 1) condition_stack [current_if_stack] |= HAS_BEEN_TRUE; return ((char*)0); } else return ("If stack over flow\n"); } char * pop_condition () { if (current_if_stack > 0) { --current_if_stack; return ((char*)0); } else return ("No more if stack\n"); } invoke_shell () { char *shell = "/bin/sh"; if (look_var ("shell")) shell = look_var ("shell"); invoke_command (shell); } invoke_command (cmd) char *cmd; { int catchsig(); int (*func)(); clear_edit_line (); if (look_var ("verbose")) printf ("Invoke %s\n", cmd); fflush (stdout); recover_tty(); recover_signal (); system (cmd); fix_signal (); fix_tty(); if (look_var ("verbose")) printf ("Return to fep\n"); recover_edit_line (1); } FILE *redirect_fp = NULL; int redirect_line = 0; fep_read_from_file (comline) char *comline; { FILE *fp; static char *argv[MAXARGS]; char file [MAXPATHLEN]; int argc; argc = mkargv (comline, argv, MAXARGS); if (argc != 2) { printf ("Invalid number of arguments.\n"); return; } if (redirect_fp) { fclose (redirect_fp); redirect_fp = NULL; } redirect_fp = fopen (argv[1], "r"); if (redirect_fp = fopen (argv[1], "r")) { if (look_var ("verbose")) printf ("Input redirected from %s\n", argv[1]); errorBell (); redirect_line = 0; } else perror (argv[0]); return; } /* * Process ID of the process redirecting from. */ int redirect_pid = 0; fep_read_from_command (comline) char *comline; { static char *argv[MAXARGS]; char buf[256]; int argc; int i; FILE *popen(); argc = mkargv (comline, argv, MAXARGS); if (argc == 1) { printf ("Invalid number of arguments.\n"); return; } if (redirect_fp) { fclose (redirect_fp); redirect_fp = NULL; } strcpy (buf, ""); for (i=1; iinfo_name; sp++) { printf ("\t%s: %d\n", sp->info_name, *(sp->info_valp)); } printf ("\nI/O Buffer:\n"); printf ("\tMax : %d\n", bp->b_max); printf ("\tHiWtr: %d\n", bp->b_hiwater); printf ("\tCount: %d\n", bp->b_count); printf ("\tNext : %d\n", bp->b_next); } #endif