ted@oz.plymouth.edu (Ted Wisniewski) (02/11/91)
Submitted-by: Ted Wisniewski <ted@oz.plymouth.edu> Posting-number: Volume 16, Issue 99 Archive-name: pscmenu/part01 PSCMenu is a menu system that is capable of doing any unix command from the "menu". The individual menus are read from menu files that are located in a "menu" directory. The menu files are simple text files that may be edited with any editor. The "menu" is flexable, the only command line argument that is accepted is the name of a directory in which the menu files are located. A default directory is specified in the menu header file. Developed and tested on Ultrix based systems. Ted ---------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # MENU # This archive created: Mon Dec 17 14:49:00 1990 # By: The Wiz () export PATH; PATH=/bin:/usr/bin:$PATH if test ! -d 'MENU' then mkdir 'MENU' fi cd 'MENU' if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else cat << \SHAR_EOF > 'Makefile' CC = /bin/cc CFLAGS = -O LIBS = -ltermcap DEFS = TARGET = menu HDRS = menu.h utils.h SRCS = menu.c appl.c utils.c files.c signals.c OBJS = menu.o appl.o utils.o files.o signals.o $(TARGET): $(OBJS) $(SRCS) $(HDRS) $(CC) $(CFLAGS) $(DEFS) $(OBJS) -o $(TARGET) $(LIBS) strip $(TARGET) chmod 711 $(TARGET) menu.o : menu.c menu.h $(CC) $(CFLAGS) $(DEFS) -c menu.c appl.o : appl.c $(CC) $(CFLAGS) $(DEFS) -c appl.c utils.o : utils.c utils.h $(CC) $(CFLAGS) $(DEFS) -c utils.c files.o : files.c menu.h $(CC) $(CFLAGS) $(DEFS) -c files.c signals.o : signals.c $(CC) $(CFLAGS) $(DEFS) -c signals.c install: /bin/cp $(TARGET) /usr/local/bin chmod 711 /usr/local/bin/$(TARGET) clean: rm -f $(OBJS) lint: lint $(SRCS) > LINT.OUT SHAR_EOF fi if test -f 'appl.c' then echo shar: "will not over-write existing file 'appl.c'" else cat << \SHAR_EOF > 'appl.c' # include <ctype.h> # include "menu.h" # include "utils.h" /* PSC MENU COPYRIGHT NOTICE Part of PSCMenu This software is to be considered to be public domain, it may be copied, modified and parts of it may be used in other programs as long as this copyright notice remains intact. Copyright() PSC - Plymouth State College Written by: Ted Wisniewski 12-9-1990 */ box_screen() /* Draw a box around the screen. */ { int i; char buf[256]; (void) sprintf(buf,"%80s"," "); start_rev(); move_csr(0,FIRST_LINE); print_str(buf); move_csr(0,STATUS_LINE); print_str(buf); for(i=1;i<22;i++){ move_csr(0,i); outc(' '); move_csr(79,i); outc(' '); } end_rev(); } disp_menu(menu,n_ent) menu_ent *menu; int n_ent; /* Display the menu. */ { int ind = 0; char tmp[5]; while(ind < n_ent){ if(ind == 0){ move_csr((CENTER-(strlen(menu[0].desc)/2)),(ind*2) + 3); }else{ if(ind > 0){ move_csr(NUMCOL,(ind*2) + 4); (void) sprintf(tmp,"%d",ind); print_str(tmp); } move_csr(DESCOL,(ind*2) + 4); } hi_lite(menu[ind].desc); ind++; } } do_menu(menu,n_ent) menu_ent *menu; int n_ent; { char inp = NULL,save = NULL; int tmp; move_csr(4,20); while(inp != 'q') { switch (inp) { case 'c': erase_menu(n_ent); change(); disp_menu(menu,n_ent); break; case 'x': erase_menu(n_ent); exec_it(); disp_menu(menu,n_ent); break; case 'd': erase_menu(n_ent); exec_cshell("ls"); disp_menu(menu,n_ent); break; case 'l': erase_menu(n_ent); exec_pipe("ls -l"); disp_menu(menu,n_ent); break; case RE_DRAW: clr_scr(); setup_screen(); disp_menu(menu,n_ent); (void) fflush(stdin); break; case LF: case CR: if(m_flag != TRUE) inp = n_ent-1 + '0'; default: tmp = inp - '0'; if((tmp >= 1) && (tmp < n_ent)){ switch(menu[tmp].key){ case '+': erase_menu(n_ent); exec_pipe(menu[tmp].cmd); disp_menu(menu,n_ent); break; case '*': exec_cshell(menu[tmp].cmd); disp_menu(menu,n_ent); break; case '@': menu->key = '@'; case '&': erase_menu(n_ent); (void) read_menu(menu,menu[tmp].cmd,&n_ent); disp_menu(menu,n_ent); break; case '1': erase_menu(n_ent); One_fname(buffer,2); (void) sprintf(string,"%s %s",menu[tmp].cmd,buffer); exec_cshell(string); clear_array(string); disp_menu(menu,n_ent); break; case '2': erase_menu(n_ent); One_fname(buffer,2); (void) sprintf(string,"%s %s ",menu[tmp].cmd,buffer); Two_fname(buffer,3); if(!isprint(buffer[strlen(buffer)])) rm_lf(buffer); (void) strcat(string,buffer); exec_cshell(string); clear_array(string); disp_menu(menu,n_ent); break; case '3': erase_menu(n_ent); ask_who(buffer,2); (void) sprintf(string,"%s %s",menu[tmp].cmd,buffer); exec_cshell(string); clear_array(buffer); clear_array(string); disp_menu(menu,n_ent); break; case '4': erase_menu(n_ent); ask_what(buffer,2); (void) sprintf(string,"%s %s",menu[tmp].cmd,buffer); exec_cshell(string); clear_array(buffer); clear_array(string); disp_menu(menu,n_ent); break; default: break; } } } move_csr(0,23); inp = getchar(); if(inp == 'h'){ inp = disp_help(n_ent); if(inp != 'x' && inp!= 'd' && inp != 'c' && inp!=RE_DRAW) disp_menu(menu,n_ent); } } quit(); } erase_menu(num) int num; { int ind = 0; char buffer[50]; (void) sprintf(buffer,"%40s"," "); move_csr(20,3); print_str(buffer); for(ind=0;ind<num;ind++){ move_csr(NUMCOL,(ind*2) + 4); print_str(buffer); } } disp_help(num) int num; { char buffer[40]; int i; char Key; (void) sprintf(buffer,"%30s"," "); move_csr(25,7); print_str(buffer); move_csr(25,7); hi_lite(buffer); for(i=8;i<=18;i++){ move_csr(25,i); print_str(buffer); start_rev(); move_csr(25,i); outc(' '); move_csr(54,i); outc(' '); end_rev(); } move_csr(25,18); print_str(buffer); move_csr(25,18); hi_lite(buffer); move_csr(27,9); print_str("Command Summary:"); move_csr(27,11); print_str("(q) Quit Menu"); move_csr(27,12); print_str("(x) Execute Command"); move_csr(27,13); print_str("(c) Change Directory"); move_csr(27,14); print_str("(d) Show Directory"); move_csr(27,15); print_str("(l) Long Directory"); move_csr(27,16); print_str("(ctrl-R) Redraw Screen."); move_csr(27,17); Key = getchar(); erase_help(); return(Key); } erase_help() { char buffer[40]; int i; (void) sprintf(buffer,"%30s"," "); for(i=7;i<=18;i++){ move_csr(25,i); print_str(buffer); } } One_fname(name,y) char *name; int y; { move_csr(2,y); clear_array(name); print_str("Filename: "); read_str(name); } Two_fname(name,y) char *name; int y; { move_csr(2,y); clear_array(name); print_str("New File: "); read_str(name); } change() { move_csr(2,2); clear_array(buffer); print_str("Directory: "); read_str(buffer); rm_lf(buffer); chdir(buffer); erase_line(2,2,60); prt_curdir(); clear_array(buffer); } exec_it() { move_csr(2,2); print_str("Command: "); clear_array(buffer); read_str(buffer); exec_cshell(buffer); } ask_who(name,y) char *name; int y; { move_csr(2,y); clear_array(name); print_str("To Whom: "); read_str(name); move_csr(2,3); (void) fflush(stdout); } ask_what(name,y) char *name; int y; { move_csr(2,y); clear_array(name); print_str("Topic: "); read_str(name); } SHAR_EOF fi if test -f '.v' then echo shar: "will not over-write existing file '.v'" else cat << \SHAR_EOF > '.v' game.c shell.c appl.c SHAR_EOF fi if test -f 'files.c' then echo shar: "will not over-write existing file 'files.c'" else cat << \SHAR_EOF > 'files.c' # include <stdio.h> # include <unistd.h> # include "menu.h" /* PSC MENU COPYRIGHT NOTICE Part of PSCMenu This software is to be considered to be public domain, it may be copied, modified and parts of it may be used in other programs as long as this copyright notice remains intact. Copyright() PSC - Plymouth State College Written by: Ted Wisniewski 12-9-1990 */ read_menu(menu,file_name,num) menu_ent *menu; char *file_name; int *num; { FILE *fp; int index = 0; char buffer[256]; if(menu->key == '@') m_flag = TRUE; else m_flag = FALSE; (void) sprintf(buffer,"%s%s",menu_dir,file_name); if((access(buffer,R_OK|F_OK)) == -1){ move_csr(26,11); hi_lite("Menu file cannot be accessed."); continue_it(20); erase_line(26,11,30); }else{ fp = fopen(buffer,"r"); while(!feof(fp)){ (void) fgets(buffer,256,fp); rm_lf(buffer); if(!feof(fp) && (index <= 7)){ switch (buffer[0]){ case '$': menu[index].key = buffer[0]; (void) strcpy(menu[index].desc,buffer+2); index++; break; case '?': (void) strcpy(menu[index].desc,buffer+2); index++; break; case '+': menu[index].key = buffer[0]; (void) strcpy(menu[index].cmd,buffer+2); break; case '*': menu[index].key = buffer[0]; (void) strcpy(menu[index].cmd,buffer+2); break; case '@': case '&': menu[index].key = buffer[0]; (void) strcpy(menu[index].cmd,buffer+2); break; case '1': menu[index].key = buffer[0]; (void) strcpy(menu[index].cmd,buffer+2); break; case '2': menu[index].key = buffer[0]; (void) strcpy(menu[index].cmd,buffer+2); break; case '3': menu[index].key = buffer[0]; (void) strcpy(menu[index].cmd,buffer+2); break; case '4': menu[index].key = buffer[0]; (void) strcpy(menu[index].cmd,buffer+2); break; } } } fclose(fp); *num = index; } } SHAR_EOF fi if test -f 'menu.c' then echo shar: "will not over-write existing file 'menu.c'" else cat << \SHAR_EOF > 'menu.c' # include <stdio.h> # include <sys/file.h> # include <sys/ioctl.h> # include "menu.h" /* PSC MENU COPYRIGHT NOTICE Part of PSCMenu This software is to be considered to be public domain, it may be copied, modified and parts of it may be used in other programs as long as this copyright notice remains intact. Copyright() PSC - Plymouth State College Written by: Ted Wisniewski 12-9-1990 */ /***************************************************************************** Execute a process and have the output read into a buffer and then print it to the screen. *****************************************************************************/ exec_pipe(comline) char *comline; { char inbuf[LINESZ], list[FOURK][80]; FILE *f, *popen(), *pclose(); int num = 1, len = 0; if((f = popen(comline,"r")) == NULL){ strcpy(list[0],"command not found"); (void) fprintf(fprintf,"Command not Found.\n"); }else while(fgets(inbuf,LINESZ,f) != NULL){ rm_lf(inbuf); (void) strcpy(list[num],inbuf); if(strlen(inbuf) > len) len = strlen(inbuf); num++; } print_output(list,num,len); pclose(f); } /************************************************************************** Print output to the Menu Window, when done clear the Window. **************************************************************************/ print_output(output,number,len) char output[FOURK][80]; int number, len; { int i, k = 4; for(i=1;i<number;++i){ move_csr(5,k); print_str(output[i]); k++; if(i%15 == 14){ if(cont_it() == 1){ clr_area(5,4,(k-4),len+2); return; } clr_area(5,4,(k-4),len+2); move_csr(5,4); k = 4; } (void) fflush(stdout); } continue_it(CONT_LINE); clr_area(5,4,(k-4),len+2); } /************************************************************************** Request input from the user as to whether he/she wishes to continue. This routine gives the option to stop seeing output. **************************************************************************/ cont_it() { char c; move_csr(20,CONT_LINE); hi_lite("Press space to continue or \'q\' to stop."); c = getchar(); while(c != 'q' && c != ' ') c = getchar(); erase_line(20,CONT_LINE,45); if(c == 'q') return 1; else return 0; } /************************************************************************** Request input from the user as to whether he/she wishes to continue. **************************************************************************/ continue_it(line) int line; { move_csr(27,line); hi_lite("Press a space to Continue."); while(getchar() != SPACE); erase_line(27,line,45); } /***************************************************************************** Print The current working directory at the bottom of the screen. *****************************************************************************/ prt_curdir() { char direct[BUF_SIZ]; int i; move_csr(0,STATUS_LINE); hi_lite("Directory:"); getwd(direct); if(strlen(direct) < 40) for(i=strlen(direct);i<=40;i++) (void) strcat(direct," "); else for(i=40;i<=80;i++) direct[i] = NULL; move_csr(12,STATUS_LINE); hi_lite(direct); } /***************************************************************************** Clear an Area in the Menu Window. *****************************************************************************/ clr_area(st_y,st_x,n_line,len) int st_y,st_x,n_line,len; { int i; for(i=0;i<=len;i++) line[i] = ' '; line[i+1] = NULL; for(i=(st_y-1);i<(n_line+st_y);i++){ move_csr(st_x,i); print_str(line); } } /***************************************************************************** Erase a line within the Menu Window. *****************************************************************************/ erase_line(x,y,length) int x,y,length; { int i; for(i=0;i<=length;i++) line[i] = ' '; line[i+1] = NULL; move_csr(x,y); print_str(line); } /***************************************************************************** Execute a shell command. Output does not come to back to the window. *****************************************************************************/ exec_cshell(command) char *command; { clr_scr(); (void) fflush(stdout); reset_tty(); if(fork() == 0) execl("/bin/csh","csh","-c",command,0); else wait((int *)0); setup_tty(); continue_it(LAST_LINE); setup_screen(); } /***************************************************************************** Draw borders and print Header on the screen. *****************************************************************************/ setup_screen() { clr_scr(); /* Clear screen routine */ box_screen(); move_csr((CENTER-strlen(HEADER)/2),FIRST_LINE); hi_lite(HEADER); move_csr(68,STATUS_LINE); hi_lite(CMD_LIN); prt_curdir(); } /***************************************************************************** Make sure The user does not try to run menu in the background. *****************************************************************************/ check_run() { int tpgrp; /* terminal control process group */ if (ioctl(2, TIOCGPGRP, &tpgrp) != 0) { /* hope stderr open */ exit(1); } if(getpgrp(0) != tpgrp){ (void) fprintf(stderr,"\nSorry, Cannot run in background.\n"); exit(0); } } /***************************************************************************** Make sure Output goes to the screen and terminal is capable of running menu. *****************************************************************************/ initialize() { int term; if(!isatty(1)){ (void) fprintf(stderr,"Sorry, Cannot output to the screen (exiting).\n"); exit(4); } if((term = get_term()) == -1){ (void) fprintf(stderr,"Sorry, Bad termcap entry (exiting).\n"); exit(4); } save_tty(); /* Save tty states */ setup_tty(); } /***************************************************************************** Prepare for Quit Menu, and exit (restore original settings). *****************************************************************************/ quit() /* Reset the terminal to the same as before it was run. */ { clr_scr(); /* Clear screen routine */ move_csr(0,LAST_LINE); reset_tty(); exit(0); } /***************************************************************************** Set proper terminal settings for use while within menu. *****************************************************************************/ setup_tty() { no_echo(); cbreak(); crmode(); } main(argc,argv) int argc; char *argv[]; { int *num; /************************************************************ If More than two arguments are supplied print the Usage statement. ************************************************************/ if(argc > 2){ (void) fprintf(stderr,"Usage: menu\n"); (void) fprintf(stderr,"Usage: menu [menu_directory]\n"); exit(0); }else{ /************************************************************ If there are no additional arguments Use the default Menu directory. ************************************************************/ if(argc == 1) (void) strcpy(menu_dir,MENU_DIR); else /************************************************************ See if the directory name ends in a '/' if not add one. ************************************************************/ if(argc == 2){ (void) strcpy(menu_dir,argv[1]); if(menu_dir[strlen(menu_dir)-1] != '/') (void) strcat(menu_dir,"/"); } (void) sprintf(buffer,"%s%s",menu_dir,"menu.1"); /************************************************************ Check to make sure the menu directory is Read-able and executeable ************************************************************/ if(access(menu_dir,R_OK|X_OK)){ (void) fprintf(stderr,"Directory :%s: is not accessable ",menu_dir); (void) fprintf(stderr,"or does not exist.\n"); exit(1); } /************************************************************ Check to see if the main menu file exists, if it does not exist, exit the program. ************************************************************/ if(access(buffer,F_OK)){ (void) fprintf(stderr,"Menu files do not exist in %s.\n",menu_dir); exit(2); } } check_run(); initialize(); setup_screen(); setup_sigs(); main_menu->key = '@'; /* We start in main menu */ (void) read_menu(main_menu,MAIN_MENU,&num); disp_menu(main_menu,num); (void) fflush(stdin); do_menu(main_menu,num); } SHAR_EOF fi if test -f 'menu.h' then echo shar: "will not over-write existing file 'menu.h'" else cat << \SHAR_EOF > 'menu.h' /* PSC MENU COPYRIGHT NOTICE Part of PSCMenu This software is to be considered to be public domain, it may be copied, modified and parts of it may be used in other programs as long as this copyright notice remains intact. Copyright() PSC - Plymouth State College Written by: Ted Wisniewski 12-9-1990 */ # define FOURK 4096 # define ONEK 1024 # define BUF_SIZ 256 # define LINESZ 80 # define FIRST_LINE 0 # define STATUS_LINE 22 # define NUMCOL 22 # define DESCOL 25 # define LAST_LINE 23 # define CONT_LINE 21 # define N_ENTRIES 9 # define RE_DRAW ('r' & 037) # define MAIN_MENU "menu.1" # define MENU_DIR "/usr/local/lib/menus/" # define CR 0x0d # define LF 0x0a # define SPACE 0x20 # define TRUE 1 # define FALSE 0 # define CENTER 40 # define HEADER "Plymouth State College Menu System" # define CMD_LIN "h)elp q)uit" int catch(); typedef struct { char key; char desc[LINESZ]; /* description of cmd */ char cmd[LINESZ]; /* The Command */ /* char help_fil[LINESZ]; Name of the Help file for option. */ }menu_ent; menu_ent main_menu[N_ENTRIES]; typedef int FLAG; FLAG m_flag; char line[BUF_SIZ], buffer[BUF_SIZ], string[BUF_SIZ]; char menu_dir[BUF_SIZ]; int len; int get_term(); SHAR_EOF fi if test -f 'menu.man' then echo shar: "will not over-write existing file 'menu.man'" else cat << \SHAR_EOF > 'menu.man' .TH MENU 1 "June 1990" "Newwords+ Manual" \.@(#)menu.1 1.1 90/06/31 SMI; .SH NAME menu \- Runs the PSC Menu System. .SH SYNOPSIS menu [ menu_directory ] .SH DESCRIPTION Menu is a menu system that is capable of doing any unix command from the "menu". The individual menus are read from menu files that are located in a "menu" directory. The menu files are simple text files that may be edited with any editor. The "menu" is flexable, the only command line argument that is accepted is the name of a directory in which the menu files are located. A default directory is specified in the menu header file. .SH SELECTING ITEMS & USING BUILTIN COMMANDS An item is selected from the menu simply by entering the corresponding number that is displayed for the item. It is important to know that you should not enter the selection and then press return. The return key has a special function. The return key tells the menu to back up one menu unless you are in the main menu, where it haas no effect. The PSC menu system contains built in commands that allow you to: change directory, execute a shell command, do directory listings, quit menu, help and re-draw the screen. See the section on the "Built in Menu" for more details. .SH BUILT IN MENU The Built in menu is a pop-up window that displays a list of builtin commands accessable. This menu is accessed by entering the letter 'h' from any menu accept the builtin menu. Options in this menu are: 'q','d','l','x','c' and <ctrl-R>. These characters cause the following affects: .PP \'h' - Use the builtin help menu. .PP \'d' - Get a short directory listing of the current directory. .PP \'l' - Get a long directory listing of the current directory. .PP \'x' - Execute a shell command. .PP \'c' - Change to a new working directory. .PP \'q' - Quit the Menu. .PP \<ctrl-R> Re-draw the screen in cases where you get garbled. (control key and 'R' are pressed at the same time). .SH MENU FILES The Menu files have a specific format that must be followed. The first character in each line must be '$', '+', '*', '&', '?', '1', '2', '3', '4'. These are "key" characters that tell "menu" what kind of operation is to be performed. .PP \'$' This character means that this line is the menu header for this menu, this must be the first character in the line. This must always be the first line in the "menu" file. The second character in this line is skipped anything after the second column is interpreted as the menu heading. .PP \'+' This character means that output from the name program be output to the "menu" window. It is best if the output is 70 columns wide or less. Some good examples are ls and ls -l. Any program which actually does screen manipulation cannot use the '+' option (It Will really get messed up). .PP \'@' This character specifies that the menu to be loaded is to be considered the main menu so that pressing return will not do anything. .PP \'&' This character specifies a menu to be loaded. The path to the menu file is the default or the specified one given in the command argument. .PP \'*' This character means that the invoked program will interfere with the "menu" window. Such programs include more, less and any games. .PP \'1' This character specifies that one file name is expected as an argument for the program to be run. A good example would be: vi <filename>. .PP \'2' This character specifies that two file names are expected as arguments for the program to be run. A good exmample would be: cp <file1> <file2>. .PP \'3' This character specifies that a user name is expected as an argument for the program to be run. A good exapmple would be: mail <user>. .PP \'4' This character specifies a topic to be used as an argument to the program to be run. A good example would be: man <topic>. .SH DEFAULTS The menu program looks for a file called "menu.1" in the default or specified directory. If the Directory does not exist or is not accessable the program will tell you of the condition and quietly exit. If the file "menu.1" does not exist in the named directory the program will notify you that it could not find any menu files and quietly exits. The return key if pressed will do the last thing in the menu, unless that menu is defined to be the main menu (this is done to make it easy to back out of menus assuming of course that return to previous menu is that last option in that menu). .SH EXAMPLE MENU FILE .nf $ File Management Menu 2 /bin/mv -i ? Rename a file. 2 /bin/cp -i ? Copy a file. 1 rm -i ? Remove a single file. * rm -i * ? Cleanup your files. + /bin/ls ? List your Files. & menu.1 ? Return to main Menu. .fi .SH CAUTIONS If you use the '+' menu command that tells the menu program to send output to the menu window with a command that uses cursor addressing or requires user input you may get some rather interesting results. SHAR_EOF fi if test -f 'signals.c' then echo shar: "will not over-write existing file 'signals.c'" else cat << \SHAR_EOF > 'signals.c' # include <signal.h> # include "menu.h" /* PSC MENU COPYRIGHT NOTICE Part of PSCMenu This software is to be considered to be public domain, it may be copied, modified and parts of it may be used in other programs as long as this copyright notice remains intact. Copyright() PSC - Plymouth State College Written by: Ted Wisniewski 12-9-1990 */ setup_sigs() { (void) signal(SIGSEGV,catch); (void) signal(SIGBUS,catch); (void) signal(SIGINT,SIG_IGN); (void) signal(SIGTSTP,SIG_IGN); (void) signal(SIGQUIT,SIG_IGN); } catch(signo) int signo; { switch (signo){ case SIGSEGV: case SIGBUS: clr_scr(); reset_tty(); end_rev(); perror(" "); exit(1); break; } } SHAR_EOF fi if test -f 'utils.c' then echo shar: "will not over-write existing file 'utils.c'" else cat << \SHAR_EOF > 'utils.c' # include "utils.h" # include <ctype.h> # include <sys/ioctl.h> /* PSC MENU COPYRIGHT NOTICE Part of PSCMenu This software is to be considered to be public domain, it may be copied, modified and parts of it may be used in other programs as long as this copyright notice remains intact. Copyright() PSC - Plymouth State College Written by: Ted Wisniewski 12-9-1990 */ /* This file contains basic low level utilities. */ int get_term() /* This routine gets the terminal specific escape sequences and saves them in the appropriate variable for use by tputs() and tgoto() */ { char bp[1024], termtype[MAXL]; static char buf[100]; char *buf_ptr = buf; if(getenv("TERM") != NULL) (void) strcpy(termtype, getenv("TERM")); if(tgetent(bp,termtype) != 1) return(-1); if((CL = tgetstr("cl",&buf_ptr)) == (char *)NULL) return(-1); if((CM = tgetstr("cm",&buf_ptr)) == (char *)NULL) return(-1); if((CE = tgetstr("ce",&buf_ptr)) == (char *)NULL) return(-1); if((SO = tgetstr("so",&buf_ptr)) == (char *)NULL) return(-1); if((SE = tgetstr("se",&buf_ptr)) == (char *)NULL) return(-1); } outc(c) int c; /* This routine puts a single character out to the screen at the current location. */ { (void) fputc(c,stdout); } move_csr(x,y) int x,y; /* This routine is used to move the cursor to a new position on the screen. */ { tputs(tgoto(CM,x,y),1,outc); } clr_scr() /* This routine clears the screen and leaves the cursor in the upper left corner of the screen. */ { tputs(CL,1,outc); } clr_line() /* This routine clears from the current cursor position to the end of the line. */ { tputs(CE,1,outc); } start_rev() /* Start the reverse video mode. */ { tputs(SO,1,outc); } end_rev() /* End the reverse video mode. */ { tputs(SE,1,outc); } print_str(string) char *string; /* Print an entire string to the screen. */ { (void) fputs(string,stdout); } hi_lite(string) char *string; /* Hi-lite a string that will be printed. */ { start_rev(); print_str(string); end_rev(); } save_tty() /* Save Terminal characteristics Reset by call to reset_tty(). */ { (void) ioctl(0, TCGETA, &ter_old); } reset_tty() /* This routine returns the terminal to the same state it had before this program was invoked. */ { (void) ioctl(0, TCSETA, &ter_old) ; } crmode() /* Turn on CRmode. */ { (void) ioctl(0,TCGETA,&ter_des); ter_des.c_lflag |= CRMOD; (void) ioctl(0,TCSETA,&ter_des); } no_crmode() /* Turn off CRmode. */ { (void) ioctl(0,TCGETA,&ter_des); ter_des.c_lflag &= ~CRMOD; (void) ioctl(0,TCSETA,&ter_des); } echo() /* Turn echo back on. */ { (void) ioctl(0,TCGETA,&ter_des); ter_des.c_lflag |= ECHO; (void) ioctl(0,TCSETA,&ter_des); } no_echo() /* Turn off echo. */ { struct termio ter_des; (void) ioctl(0,TCGETA,&ter_des); ter_des.c_lflag &= ~ECHO; (void) ioctl(0,TCSETA,&ter_des); } no_cbreak() /* Take the terminal out of cbreak mode. */ { (void) ioctl(0,TCGETA,&ter_des); ter_des.c_lflag |= CBREAK; (void) ioctl(0,TCSETA,&ter_des); } cbreak() /* Place the Terminal in Cbreak mode. */ { (void) ioctl(0,TCGETA,&ter_des); ter_des.c_lflag &= ~CBREAK; (void) ioctl(0,TCSETA,&ter_des); } rm_lf(array) char *array; /* Remove Trailing line feed from a line. */ { array[strlen(array)-1] = NULL; } read_str(string) char *string; { char *str; str = string; while((*str = getchar()) != LF && *str != CR){ if(*str == DEL || *str == BS) if(*str != *string){ outc(DEL); outc(SPACE); outc(DEL); *str--; }else continue; else{ outc(*str); *str++; } } *str = LF; } clear_array(array) char *array; { for(;*array != NULL;*array++) *array = NULL; } SHAR_EOF fi if test -f 'utils.h' then echo shar: "will not over-write existing file 'utils.h'" else cat << \SHAR_EOF > 'utils.h' # include <stdio.h> # include <termio.h> /* PSC MENU COPYRIGHT NOTICE Part of PSCMenu This software is to be considered to be public domain, it may be copied, modified and parts of it may be used in other programs as long as this copyright notice remains intact. Copyright() PSC - Plymouth State College Written by: Ted Wisniewski 12-9-1990 */ # define MAXL 80 # define THIS_TTY 0 # define DEL 0x08 # define BS 0x7f # define SPACE 0x20 # define LF 0x0a # define CR 0x0d char *SO, *SE, *CE, *CM, *CL; char *getenv(), *tgetstr(), *tgoto(); int outc(); struct termio ter_old, ter_des; SHAR_EOF fi if test -f 'README' then echo shar: "will not over-write existing file 'README'" else cat << \SHAR_EOF > 'README' Install Notes for Menu1.1 This Menu system should compile on just about any machine. Since I have only one type to work with I cannot be absolutely sure of this. I have successfully compiled and run it in and Ultrix environment (the compiler is really picky). To compile: unshar the shell archive via: % sh menu.shar then edit the header file "menu.h" and the Makefile to set appropriate paths for your system. then do: % make To Test: do: % ./menu ./demos This should show you a working example of how this menu works, the demo is set up for what this site is using so the applications called may not be on your system. To install: do: % make install Problems or Questions: Send E-Mail to: ted@oz.plymouth.edu or uunet!unhd!oz!ted Please do not post questions directed to me to the net, we have some problems with our news feed. Generally we somtimes get the news 2 weeks late or not at all due to something down the line from us. Present & Future: At the present time menu has proved to be bug free, but there is a possibility there are bugs. Menu has been Beta-tested for 4 months and has been used by hundreds of users successfully. In the future I plan to implement a help file to be associated with each menu option. The help file will allow the "menu" administrator to specify help files for the menu options within the menu definition file to aid users unfamiliar with the specific application. SHAR_EOF fi if test ! -d 'demos' then mkdir 'demos' fi cd 'demos' if test -f 'menu.1' then echo shar: "will not over-write existing file 'menu.1'" else cat << \SHAR_EOF > 'menu.1' $ PSC Menu Executive & menu.4 ? Use the Help Menu. & menu.5 ? Word processing & editing. & menu.7 ? File Management Menu. & menu.8 ? Misc Menu. & menu.3 ? Communications Menu. & menu.2 ? The Math Menu. & games/menu.1 ? Recreation Menu. SHAR_EOF fi if test -f 'menu.2' then echo shar: "will not over-write existing file 'menu.2'" else cat << \SHAR_EOF > 'menu.2' $ Math Menu * /usr/psc/min ? Minitab statisical program. * /usr/psc/finite ? Use the finite math menu. * /usr/psc/amortf ? Amort: full report. * /usr/psc/amort ? Amort: short report. * /usr/psc/calc ? Desk Calculator. @ menu.1 ? Return to Main Menu. SHAR_EOF fi if test -f 'menu.4' then echo shar: "will not over-write existing file 'menu.4'" else cat << \SHAR_EOF > 'menu.4' $ Help Menu * cat /usr/tmp/menus/help ? Get help on this menu System. * /usr/psc/help ? Use the online help facility. * /usr/psc/tutorial ? Use the unix tutorial. 4 apropos ? Lookup system commands. 4 /usr/ucb/man ? Read the manual. @ menu.1 ? Return to main Menu. SHAR_EOF fi if test -f 'menu.5' then echo shar: "will not over-write existing file 'menu.5'" else cat << \SHAR_EOF > 'menu.5' $ Wordprocessing Menu * /usr/psc/uniplex ? Uniplex office automation. 1 /usr/psc/pfs ? Use the "pfs" look-alike. 1 /usr/psc/nws ? Use the Word Star look-alike. 1 /usr/ucb/vi ? Use the "vi" Editor. 1 /usr/psc/gemacs ? Use The Gemacs Editor. + /bin/ls ? List your files. @ menu.1 ? Return to main menu. SHAR_EOF fi if test -f 'menu.6' then echo shar: "will not over-write existing file 'menu.6'" else cat << \SHAR_EOF > 'menu.6' $ File & disk Information. + /bin/ls ? A short listing of your files. + /bin/ls -l ? A long listing of your files. * /usr/ucb/quota -v ? Check your disk quota. & menu.7 ? Return to main menu. SHAR_EOF fi if test -f 'menu.7' then echo shar: "will not over-write existing file 'menu.7'" else cat << \SHAR_EOF > 'menu.7' $ File Management Menu 2 /bin/mv -i ? Rename a file. 2 /bin/cp -i ? Copy a file. 1 rm -i ? Remove a single file. * rm -i * ? Cleanup your files. + /bin/ls ? List your Files. & menu.6 ? File & Disk Infromation. @ menu.1 ? Return to main Menu. SHAR_EOF fi if test -f 'menu.8' then echo shar: "will not over-write existing file 'menu.8'" else cat << \SHAR_EOF > 'menu.8' $ Miscellaneous Menu + /bin/who ? Who is logged on. + /usr/ucb/w -s ? What's up? 3 /usr/ucb/last ? Checks last log on's. @ menu.1 ? Return to main Menu. SHAR_EOF fi if test -f 'help' then echo shar: "will not over-write existing file 'help'" else cat << \SHAR_EOF > 'help' Menu Help: To select an item: Just enter the apropriate number for your request no <Return> needed. To change Directory: Enter the letter 'c' from any menu. You will be prompted for the new directory. To execute a Unix Command: Enter the letter 'x' from any menu. You will be prompted to enter a Unix Command. To Quit: Enter the letter 'q' from any menu. To Re-Draw the screen: Hit The <ctrl> and 'r' keys at the same time. SHAR_EOF fi if test ! -d 'games' then mkdir 'games' fi cd 'games' if test -f 'menu.1' then echo shar: "will not over-write existing file 'menu.1'" else cat << \SHAR_EOF > 'menu.1' $ PSC Recreation Menu + cat /usr/tmp/games/info ? Get some Information. & games/menu.3 ? Arcade Games & games/menu.5 ? Casino & games/menu.2 ? Dungeon Games & games/menu.4 ? Other Games @ menu.1 ? Return Original Menu SHAR_EOF fi if test -f 'menu.2' then echo shar: "will not over-write existing file 'menu.2'" else cat << \SHAR_EOF > 'menu.2' $ Role Playing & Adventure * /usr/games/moria ? Moria: 2-D Dungeon Game. * /usr/games/castle ? Castle: 3-D Dungeon Game. * /usr/games/Ularn ? Ularn: 2-D Dungeon Game. * /usr/games/rogue ? Rogue: 2-D Dungeon Game. & games/menu.1 ? Return to the Main Menu. SHAR_EOF fi if test -f 'menu.3' then echo shar: "will not over-write existing file 'menu.3'" else cat << \SHAR_EOF > 'menu.3' $ Arcade Games * /usr/games/tt ? Play Tetris. * /usr/games/snake ? Snake: Avoid the Snake. * /usr/tmp/wanderer ? Wanderer: Solve a puzzle. * usr/games/worm ? Worm: & games/menu.1 ? Return to the Main Menu. SHAR_EOF fi if test -f 'info' then echo shar: "will not over-write existing file 'info'" else cat << \SHAR_EOF > 'info' Games Information: Many of the games have restricted hours during the semester. SHAR_EOF fi if test -f 'menu.4' then echo shar: "will not over-write existing file 'menu.4'" else cat << \SHAR_EOF > 'menu.4' $ Other Games. * /usr/games/fish ? Fish: Card Game. * /usr/games/ttt ? ttt: Tic-Tac-Toe. * /usr/tmp/othello ? Othello * /usr/games/hangman ? Hangman & games/menu.1 ? Return to Main Menu. SHAR_EOF fi if test -f 'Idea' then echo shar: "will not over-write existing file 'Idea'" else cat << \SHAR_EOF > 'Idea' >From pyr203 Tue Jun 5 15:08:56 1990 Received: by psc90.UUCP (5.51/smail2.5/06-02-89) id AA13720; Tue, 5 Jun 90 15:08:52 EDT Date: Tue, 5 Jun 90 15:08:52 EDT >From: pyr203 (Dragonsbane) Message-Id: <9006051908.AA13720@psc90.UUCP> To: ted Status: O Okay, here's my suggestion for a Games menu: Main menu: Arcade Casino Dungeon Other Arcade: Snake Tetris Wanderer Worm Casino: Blackjack Craps Yahtzee Dungeon: Castle Moria Rogue Ularn Other: Fish Hangman Othello Tic-Tac-Toe Also, I was thinking that you might consider putting the random maze generator under Dungeon games, but you would have to include the commands to redirect it to another file. Otherwise, you don't get the entire maze. Besides that, all you do get is a maze printout to "solve at home", rather than try to solve it on the computer. Although that wuldn't be a bad idea... JEV SHAR_EOF fi if test -f 'menu.5' then echo shar: "will not over-write existing file 'menu.5'" else cat << \SHAR_EOF > 'menu.5' $ Casino Games * /usr/games/blackjack ? Blackjack. * /usr/games/craps ? Craps. * /usr/games/yahtzee ? Yahtzee. & games/menu.1 ? Return to Main Menu. SHAR_EOF fi cd .. if test -f 'menu.3.bup' then echo shar: "will not over-write existing file 'menu.3.bup'" else cat << \SHAR_EOF > 'menu.3.bup' $ Communications Menu * /usr/psc/elm ? Use the "elm" mailer. 3 /usr/ucb/mail ? Send mail to another user. 3 /usr/ucb/talk ? Talk to another user. * /usr/psc/rn ? Read News. * /usr/psc/kermit ? Use Kermit @ menu.1 ? Return to main Menu. SHAR_EOF fi cd .. cd .. exit 0 # End of shell archive exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.