diff options
Diffstat (limited to 'menudriver.c')
-rw-r--r-- | menudriver.c | 546 |
1 files changed, 344 insertions, 202 deletions
diff --git a/menudriver.c b/menudriver.c index 0a0847b..51a1ed9 100644 --- a/menudriver.c +++ b/menudriver.c @@ -21,13 +21,7 @@ typedef void (*sighandler)(); struct stat buf; char *menuviewer; -char *viewer="less"; -/* -#ifdef UWIN - "more -ne"; -#else - "more -d"; -#endif */ +char *viewer = "less"; #define VIEWERPAUSESATEND . /* this modifies default behaviour of menudriver to return straight to menu @@ -35,158 +29,264 @@ char *viewer="less"; choice can be overriden by environment variable RETURNTOMENU=YES/NO */ #ifdef VIEWERPAUSESATEND -int fastback=1; +int fastback = 1; #else -int fastback=0; +int fastback = 0; #endif void callshell(char[]); void clrscr(void); -void menudrive(char*); +void menudrive(char *); void pushlast(void); void poplast(void); void settings(void); -void singleton(char*); +void singleton(char *); int subdir(void); -char next[40]="",cmd[80],last[40]="."; -int val, ok=0; +char next[40] = "", cmd[80], last[40] = "."; +int val, ok = 0; #include <string.h> #define index(s,c) strchr(s,c) -int main(argc,argv) -int argc; -char *argv[]; -{ char *v=getenv("VIEWER"),*fb=getenv("RETURNTOMENU"); - menuviewer=getenv("MENUVIEWER"); - if(argc>2)fprintf(stderr,"menudriver: wrong number of args\n"),exit(1); -/* -#ifdef VIEWERPAUSESATEND */ - if(!menuviewer)menuviewer="cat"; -/* -#else - if(!menuviewer)menuviewer=viewer; -#endif */ - if(v)viewer=v; - if(fb)fastback=!(*fb=='N'||*fb=='n'); +int main(int argc, char *argv[]) +{ + char *v = getenv("VIEWER"); + char *fb = getenv("RETURNTOMENU"); + menuviewer = getenv("MENUVIEWER"); + + if (argc > 2) { + fprintf(stderr, "menudriver: wrong number of args\n"); + exit(1); + } + + if (!menuviewer) { + menuviewer = "cat"; + } + + if (v) { + viewer = v; + } + + if (fb) { + fastback = !(*fb == 'N' || *fb == 'n'); + } + #ifdef CURSES - setupterm(0,1,&ok); - if(ok!=1)fprintf(stderr,"warning: cannot find terminfo entry\n"); + setupterm(0, 1, &ok); + if (ok != 1) { + fprintf(stderr, "warning: cannot find terminfo entry\n"); + } #endif - menudrive(argc==1?".":argv[1]); } - -int lastval() /* checks if last is a number (and if so leaves value in val) */ -{ if(strcmp(last,".")==0&&subdir()) - /* special case, have just entered subdir */ - { poplast(); - if(sscanf(last,"%d",&val)==1) - { chdir(".."); return(1); } - pushlast(); return(0); } - return(sscanf(last,"%d",&val)==1); + + menudrive(argc == 1 ? "." : argv[1]); +} + +/* checks if last is a number (and if so leaves value in val) */ +int lastval(void) +{ + /* special case, have just entered subdir */ + if (strcmp(last, ".") == 0 && subdir()) { + poplast(); + + if (sscanf(last, "%d", &val) == 1) { + chdir(".."); + return (1); + } + + pushlast(); + return 0; + } + + return (sscanf(last, "%d", &val) == 1); } -void menudrive(dir) -char *dir; -{ char *np;int c,bad=0; - if(chdir(dir)==-1)singleton(dir); /* apparently not a directory */ - while(stat("contents",&buf)==0) - { if(next[0]=='\0'||bad) - { clrscr(); - /* invalid selection notified here, after clearing screen */ - if(bad) - { if(strcmp(next,".")==0) - printf("no previous selection to substitute for \".\"\n"); - else printf("selection \"%s\" not valid\n",next); - bad=0; } - strcpy(cmd,menuviewer); - strcat(cmd," "); - strcat(cmd,"contents"); - system(cmd); - printf("::please type selection number (or return to exit):"); - /* read remainder of line into next, less leading white space */ - np=next; c=getchar(); - while(c==' '||c=='\t')c=getchar(); - while(c!='\n'&&c!=EOF)*np++=c,c=getchar(); - if(c==EOF)exit(0); - /* remove trailing white space */ - if(next[0]!='!')while(np[-1]==' '||np[-1]=='\t')np--; - *np='\0'; } - if(next[0]=='\0'){ chdir(".."); poplast(); continue; } - if(strcmp(next,".")==0)strcpy(next,last); /* repeat last option */ - if(strcmp(next,"+")==0&&lastval())(void)sprintf(next,"%d",val+1); - if(strcmp(next,"-")==0&&lastval())(void)sprintf(next,"%d",val-1); - if(stat(next,&buf)==0) - { if(strcmp(next,".")==0||strcmp(next,"..")==0||index(next,'/')) - { bad=1; continue; } /* no pathnames - see below */ - if(S_ISDIR(buf.st_mode)) /* directory */ - { char hold[pnlim]; - if(!getcwd(hold,pnlim)) - fprintf(stderr,"panic: cwd too long\n"),exit(1); - if(chdir(next)==-1||stat("contents",&buf)) - bad=1,chdir(hold); - else strcpy(last,next),pushlast(),next[0]='\0'; } else - if(S_ISREG(buf.st_mode)) /* regular file */ - { clrscr(); +void menudrive(char *dir) +{ + char *np; + int c; + int bad = 0; + if (chdir(dir) == -1) { + singleton(dir); /* apparently not a directory */ + } + + while (stat("contents", &buf) == 0) { + if (next[0] == '\0' || bad) { + clrscr(); + + /* invalid selection notified here, after clearing screen */ + if (bad) { + if (strcmp(next, ".") == 0) { + printf("no previous selection to substitute for \".\"\n"); + } else { + printf("selection \"%s\" not valid\n", next); + } + bad = 0; + } + + strcpy(cmd, menuviewer); + strcat(cmd, " "); + strcat(cmd, "contents"); + system(cmd); + printf("::please type selection number (or return to exit):"); + + /* read remainder of line into next, less leading white space */ + np = next; + c = getchar(); + while (c == ' ' || c == '\t') { + c = getchar(); + } + + while (c != '\n' && c != EOF) { + *np++ = c, c = getchar(); + } + + if (c == EOF) { + exit(0); + } + + /* remove trailing white space */ + if (next[0] != '!') { + while (np[-1] == ' ' || np[-1] == '\t') { + np--; + } + } + *np = '\0'; + } + + if (next[0] == '\0') { + chdir(".."); + poplast(); + continue; + } + + if (strcmp(next, ".") == 0) { + strcpy(next, last); /* repeat last option */ + } + + if (strcmp(next, "+") == 0 && lastval()) { + (void)sprintf(next, "%d", val + 1); + } + + if (strcmp(next, "-") == 0 && lastval()) { + (void)sprintf(next, "%d", val - 1); + } + + if (stat(next, &buf) == 0) { + if (strcmp(next, ".") == 0 || strcmp(next, "..") == 0 || index(next, '/')) { + bad = 1; + continue; + } /* no pathnames - see below */ + + if (S_ISDIR(buf.st_mode)) { /* directory */ + char hold[pnlim]; + if (!getcwd(hold, pnlim)) { + fprintf(stderr, "panic: cwd too long\n"), exit(1); + } + + if (chdir(next) == -1 || stat("contents", &buf)) { + bad = 1, chdir(hold); + } else { + strcpy(last, next), pushlast(), next[0] = '\0'; + } + + } else if (S_ISREG(buf.st_mode)) { /* regular file */ + clrscr(); + #ifndef UWIN - if(buf.st_mode&S_IXUSR) /* executable (by owner) */ + if (buf.st_mode & S_IXUSR) /* executable (by owner) */ #else - if(strcmp(next,"99")==0) + if (strcmp(next, "99") == 0) #endif - { strcpy(cmd,"./"); - strcat(cmd,next); - system(cmd); - if(fastback) - { printf("[Hit return to continue]"); - while(getchar()!='\n'); - } - } else - { strcpy(cmd,viewer); - strcat(cmd," "); - strcat(cmd,next); - system(cmd); } - if(fastback) - { strcpy(last,next); - next[0]='\0'; - } - else - { printf( - "::next selection (or return to go back to menu, or q to quit):" - ); - /* read remainder of line into next, less leading white space */ - strcpy(last,next); - np=next; c=getchar(); - while(c==' '||c=='\t')c=getchar(); - while(c!='\n'&&c!=EOF)*np++=c,c=getchar(); - if(c==EOF)exit(0); - /* remove trailing white space */ - if(next[0]!='!')while(np[-1]==' '||np[-1]=='\t')np--; - *np='\0'; - } - } } else - if(strcmp(next,"???")==0) /* ask to see menudriver settings */ - { settings(); - printf("[Hit return to continue]"); - while(getchar()!='\n'); - next[0]='\0'; - } else - if(strcmp(next,"q")==0||strcmp(next,"/q")==0)exit(0); else - if(next[0]=='!') /* shell escape - handy for editing manual! */ - { static char syscm[80]; - if(next[1]=='\0'||next[1]=='!') - if(syscm[0]) - { if(next[1]=='!')strcat(syscm,next+2); - printf("!%s\n",syscm); } - else - printf("no previous shell command to substitute for \"!\"\n"); - else strcpy(syscm,next+1); - if(syscm[0])callshell(syscm); /* `system' always gets /bin/sh */ - printf("[Hit return to continue]"); - while(getchar()!='\n'); - next[0]='\0'; } - else bad=1; - } + { + strcpy(cmd, "./"); + strcat(cmd, next); + system(cmd); + if (fastback) { + printf("[Hit return to continue]"); + while (getchar() != '\n') ; + } + + } else { + strcpy(cmd, viewer); + strcat(cmd, " "); + strcat(cmd, next); + system(cmd); + } + + if (fastback) { + strcpy(last, next); + next[0] = '\0'; + } else { + printf("::next selection (or return to go back to menu, or q to quit):"); + /* read remainder of line into next, less leading white space */ + strcpy(last, next); + np = next; + + c = getchar(); + while (c == ' ' || c == '\t') { + c = getchar(); + } + + while (c != '\n' && c != EOF) { + *np++ = c, c = getchar(); + } + + if (c == EOF) { + exit(0); + } + + /* remove trailing white space */ + if (next[0] != '!') { + while (np[-1] == ' ' || np[-1] == '\t') { + np--; + } + } + *np = '\0'; + } + } + } else if (strcmp(next, "???") == 0) { /* ask to see menudriver settings */ + settings(); + printf("[Hit return to continue]"); + while (getchar() != '\n') { + /* keep reading until new-line */ + } + + next[0] = '\0'; + + } else if (strcmp(next, "q") == 0 || strcmp(next, "/q") == 0) { + exit(0); + + } else if (next[0] == '!') { + /* shell escape - handy for editing manual! */ + static char syscm[80]; + if (next[1] == '\0' || next[1] == '!') { + if (syscm[0]) { + if (next[1] == '!') { + strcat(syscm, next + 2); + } + printf("!%s\n", syscm); + } else { + printf("no previous shell command to substitute for \"!\"\n"); + } + } else { + strcpy(syscm, next + 1); + } + + if (syscm[0]) { + callshell(syscm); /* `system' always gets /bin/sh */ + } + + printf("[Hit return to continue]"); + while (getchar() != '\n') ; + next[0] = '\0'; + + } else { + bad = 1; + } + } } + /* possibly a bug - can retreat above original dir, if parent contains a "contents" file - difficult to detect this in a general way, however */ /* pathnames banned because @@ -198,52 +298,71 @@ char *dir; and exit by chdir(hold) instead of chdir("..") - will need to make this recursive, or else have stack of holdwd's */ -void singleton(fil) -char *fil; -{ if(stat(fil,&buf)==0 && S_ISREG(buf.st_mode)) /* regular file */ - { clrscr(); +void singleton(char *fil) +{ + if (stat(fil, &buf) == 0 && S_ISREG(buf.st_mode)) { /* regular file */ + clrscr(); + #ifndef UWIN - if(buf.st_mode&S_IXUSR) /* executable (by owner) */ - { strcpy(cmd,"./"); - strcat(cmd,fil); - system(cmd); - fastback=0; } else + if (buf.st_mode & S_IXUSR) { /* executable (by owner) */ + strcpy(cmd, "./"); + strcat(cmd, fil); + system(cmd); + fastback = 0; + } else #endif - { strcpy(cmd,viewer); - strcat(cmd," "); - strcat(cmd,fil); - system(cmd); } - if(!fastback) - { printf("[Hit return to continue]"); - while(getchar()!='\n'); } - exit(0); + { + strcpy(cmd, viewer); + strcat(cmd, " "); + strcat(cmd, fil); + system(cmd); + } + + if (!fastback) { + printf("[Hit return to continue]"); + while (getchar() != '\n') ; } - else fprintf(stderr,"menudriver: cannot access \"%s\"\n",fil), - exit(1); + + exit(0); + + } else { + fprintf(stderr, "menudriver: cannot access \"%s\"\n", fil), exit(1); + } } -void callshell(v) -char v[]; -{ static char *shell=NULL; - sighandler oldsig; int pid; - if(!shell) - { shell=getenv("SHELL"); - if(!shell)shell="/bin/sh"; } - oldsig= signal(SIGINT,SIG_IGN); - if(pid=fork()) - { /* parent */ - if(pid==-1) - perror("UNIX error - cannot create process"); - wait(0); - (void)signal(SIGINT,oldsig); } - else execl(shell,shell,"-c",v,(char *)0); +void callshell(char v[]) +{ + static char *shell = NULL; + sighandler oldsig; + int pid; + + if (!shell) { + shell = getenv("SHELL"); + if (!shell) { + shell = "/bin/sh"; + } + } + + oldsig = signal(SIGINT, SIG_IGN); + if ((pid = fork())) { /* parent */ + if (pid == -1) { + perror("UNIX error - cannot create process"); + } + + wait(0); + (void)signal(SIGINT, oldsig); + + } else { + execl(shell, shell, "-c", v, (char *)0); + } } -void settings() -{ printf("current values of menudriver internal variables are\n\n"); - printf(" VIEWER=%s\n",viewer); - printf(" MENUVIEWER=%s\n",menuviewer); - printf(" RETURNTOMENU=%s\n",fastback?"YES":"NO"); +void settings(void) +{ + printf("current values of menudriver internal variables are\n\n"); + printf(" VIEWER=%s\n", viewer); + printf(" MENUVIEWER=%s\n", menuviewer); + printf(" RETURNTOMENU=%s\n", fastback ? "YES" : "NO"); printf("\n\ These can be modified by setting environment variables of the same names\n\n\ VIEWER is the program used to display individual sections\n\n\ @@ -262,40 +381,59 @@ prompt at bottom of a manual section before getting back to the contents\n\ page - to cure this set RETURNTOMENU=YES;\n\n"); */ -char lastvec[100],*lastp=lastvec+1; -int giveup=0; +char lastvec[100], *lastp = lastvec + 1; +int giveup = 0; -int subdir() -{ return(lastp>lastvec+1); } +int subdir(void) +{ + return (lastp > lastvec + 1); +} -void pushlast() -{ int n=strlen(last); - if(last[0]=='.') +void pushlast(void) +{ + int n = strlen(last); + if (last[0] == '.') { /* pathological cases */ - if(last[1]=='\0')return; else - if(last[1]=='.'&&last[2]=='\0') - { poplast(); return; } - if(lastp+n>lastvec+100) /* overflow */ - { giveup=1; return; } - /*if(strcmp(lastp,last)==0) - lastp+=n+1,strcpy(last,lastp); else /* here we were */ - /* suppressed 'cos interferes with special case in lastval() */ - strcpy(lastp,last),lastp+=n+1,strcpy(last,"."); + if (last[1] == '\0') { + return; + } else if (last[1] == '.' && last[2] == '\0') { + poplast(); + return; + } + } + + if (lastp + n > lastvec + 100) { /* overflow */ + giveup = 1; + return; + } + + /* suppressed 'cos interferes with special case in lastval() */ + strcpy(lastp, last), lastp += n + 1, strcpy(last, "."); } -void poplast() -{ strcpy(lastp,last); /* just in case we come back immediately */ +void poplast(void) +{ + strcpy(lastp, last); /* just in case we come back immediately */ lastp--; - if(giveup||lastp<=lastvec)return; /* underflow */ - while(*--lastp); - strcpy(last,++lastp); + + if (giveup || lastp <= lastvec) { + return; /* underflow */ + } + + while (*--lastp) { + /* what does this empty loop do? */ + } + + strcpy(last, ++lastp); } #ifndef CURSES /* to clear screen */ -void clrscr() -{ printf("\x1b[2J\x1b[H"); fflush(stdout); +void clrscr(void) +{ + printf("\x1b[2J\x1b[H"); + fflush(stdout); } #else @@ -310,11 +448,15 @@ void clrscr() #include <term.h> #endif -void clrscr() -{ if(ok!=1)return; +void clrscr(void) +{ + if (ok != 1) { + return; + } + putp(clear_screen); fflush(stdout); } + /* end of clrscr method using curses */ #endif - |