summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--menudriver.c546
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
-