jay@gdx.UUCP (Jay A. Snyder) (01/17/91)
GDXBBS V1.0 (beta) (C) 1990 Jay A. Snyder Well, it is only 9 months later than I expected. I promised to post this about nine months ago, but I got very busy with other projects. Here it is, finally, an easy to use, easy to administrate, highly configurable BBS for the unix world. I will be doing a port to MSDOS, in the near future. This main entails writing terminal handling and communication routines. I plan to make this version DesqView aware for ease of a multi-line system, and also so you can have your full CPU under DesqView when no users are logged in. Please feel free to port this to other systems (please port the termio stuff to a BSD system), Amigas, Macs, etc. When making ports to other systems please try to just replease term.c, and make minimal changes to main.c for startup. Then PLEASE send me either diffs, or the modified code. (diffs are probably better). If a clean port is made (as I just described), I can support it in future releases. echo `flames` >/dev/null Report bugs, problems and suggestions to: Jay Snyder ....uunet!wa3wbu!gdx!jay wa3wbu!gdx!jay@uunet.uu.net or feel free to call my board to sample GDX: ______ _____ / / | | / / 717-737-3249 / ____ / / |/ / 2400/1200/300bd / / / / /| / 24 Hrs. /______/ _/____/ / | o GDX-BBS Version 1 Supporting both MSDOS and Unix users. SCO Xenix binaries online. Unix source code file areas USENET Access FIDONET Access in the works Online Games (NetHack -- exellent D&D game) MSDOS, Unix, HAM discussion Groups This is the board for you if you are looking for unix software. Lots of unix source code. Submitted-by: root@gdx Archive-name: gdxbbs/part01 ---- Cut Here and unpack ---- #!/bin/sh # This is gdxbbs, a shell archive (shar 3.21) # made 01/17/1991 04:29 UTC by root@gdx # Source directory /bbs # # existing files WILL be overwritten # # This is part 1 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 1700 -rw-r--r-- RELEASE.NOTES # 2123 -rw-r--r-- GDXBBS.DOC # 5645 -rw-r--r-- .emacsmail # 5039 -rw-r--r-- main.c # 9026 -rw-r--r-- menu.c # 5459 -rw-r--r-- misc.c # 1506 -rw-r--r-- error.c # 5842 -rw-r--r-- cle.c # 4139 -rw-r--r-- parse.c # 5277 -rw-r--r-- funcs.c # 178 -rw-r--r-- chat.c # 1832 -rw-r--r-- spawn.c # 10647 -rw-r--r-- users.c # 233 -rw-r--r-- bulletin.c # 6459 -rw-r--r-- config.c # 6091 -rw-r--r-- file.c # 3831 -rw-r--r-- who.c # 1945 -rw-r--r-- quest.c # 1155 -rw-r--r-- script.c # 20376 -rw-r--r-- mail.c # 1355 -rw-r--r-- packmsg.c # 3833 -rw-r--r-- atout.c # 7639 -rw-r--r-- term.c # 2171 -rw-r--r-- env.c # 6355 -rw-r--r-- areas.c # 871 -rw-r--r-- sig.c # 1013 -rw-r--r-- priv.c # 1455 -rw------- config.h # 492 -rw------- defs2.h # 611 -rw-r--r-- inc.h # 853 -rw------- termdefs.h # 1327 -rw------- defs.h # 2245 -rw------- global.h # 1576 -rw------- structs.h # 3129 -rw------- Makefile # 2331 -rw------- answer.bbs # 3968 -rw-r--r-- areas.bbs # 990 -rw------- config.bbs # 183 -rw-r--r-- filelibs.bbs # 497 -rw-r--r-- msgareas.bbs # 546 -rw------- question.bbs # 625 -rw------- userpriv.bbs # 87 -rw------- users.bbs # 82 -rw------- welcome.bbs # 32 -rwx------ sysop # 451 -rw------- sysop.cfg # 3074 -rw-r--r-- menu.mcl # 1871 -rw------- sysop.mcl # 856 -rw-r--r-- csee.src # 141 -rw------- newuser.src # 91 -rw------- startup.src # 123 -rw------- sysop.src # 113 -rw-r--r-- files.help # 668 -rw-r--r-- mail.help # 924 -rw-r--r-- main.help # 1447 -rw-r--r-- packmain.c # if touch 2>&1 | fgrep '[-amc]' > /dev/null then TOUCH=touch else TOUCH=true fi if test -r @shar_seq_.tmp; then echo "Must unpack archives in sequence!" next=`cat @shar_seq_.tmp`; echo "Please unpack part $next next" exit 1 fi # ============= RELEASE.NOTES ============== echo "x - extracting RELEASE.NOTES (Text)" sed 's/^X//' << 'SHAR_EOF' > RELEASE.NOTES && XGDXBBS V1.0 (beta) X(C) 1990 XJay A. Snyder X XWell, it is only 9 months later than I expected. I promised to post Xthis about nine months ago, but I got very busy with other projects. X XHere it is, finally, an easy to use, easy to administrate, highly Xconfigurable BBS for the unix world. X XI will be doing a port to MSDOS, in the near future. This main Xentails writing terminal handling and communication routines. I plan Xto make this version DesqView aware for ease of a multi-line system, Xand also so you can have your full CPU under DesqView when no users Xare logged in. X XPlease feel free to port this to other systems (please port the termio Xstuff to a BSD system), Amigas, Macs, etc. X XWhen making ports to other systems please try to just replease term.c, Xand make minimal changes to main.c for startup. Then PLEASE send me Xeither diffs, or the modified code. (diffs are probably better). If Xa clean port is made (as I just described), I can support it in future Xreleases. X Xecho `flames` >/dev/null X XReport bugs, problems and suggestions to: XJay Snyder X....uunet!wa3wbu!gdx!jay Xwa3wbu!gdx!jay@uunet.uu.net X Xor feel free to call my board to sample GDX: X ______ _____ X / / | | / / 717-737-3249 X / ____ / / |/ / 2400/1200/300bd X / / / / /| / 24 Hrs. X/______/ _/____/ / | o GDX-BBS Version 1 X X Supporting both MSDOS and Unix users. X SCO Xenix binaries online. X Unix source code file areas X USENET Access X FIDONET Access in the works X Online Games (NetHack -- exellent D&D game) X MSDOS, Unix, HAM discussion Groups X XThis is the board for you if you are looking for unix software. XLots of unix source code. X X SHAR_EOF $TOUCH -am 0116232191 RELEASE.NOTES && chmod 0644 RELEASE.NOTES || echo "restore of RELEASE.NOTES failed" set `wc -c RELEASE.NOTES`;Wc_c=$1 if test "$Wc_c" != "1700"; then echo original size 1700, current size $Wc_c fi # ============= GDXBBS.DOC ============== echo "x - extracting GDXBBS.DOC (Text)" sed 's/^X//' << 'SHAR_EOF' > GDXBBS.DOC && XSorry if the documentation is sparse -- this IS a pre-release X XGDXBBS V1.0 (beta) X(C) 1990 XJay A. Snyder X======== XMany of the functions are not yet written. I'll will post new Xversions as these are completed. X======== Xusers file: Xthe file under files -> users token in config.bbs Xcontains username, password, and user level information. Xformat ala unix passwd file: X Xname:encrypted-password:user-level: X Xuser-levels are 32bit fields. For a user to have access to a command, Xmenu entry, file or message area; either the required level must be Xzero, or a the user must have a common bit set. Each of the 32 bits Xrepresents a privledge. X XUser levels will be done with keywords in the final release, but this Xis at least functional. X XExample: X1 = access to message area A X2 = access to message area B X Xa user with user level of 1 has access to area A Xa user with user level of 2 has access to area B Xa user with user level of 3 has access to both X X X======== Xconfig.bbs --> this file contains most of the configuration information, X user access levels to various commands, filenames and location, X idle - timeout, command line to run full screen editor, X maximum number of attempts at password, default terminal type, X prompt, and sysop's login name X XUse the included config.bbs, and menu.mcl as examples. As is, they Xshould both server you're needes. X XNote: if defterm isn't defined, then the value is taken from /etc/ttytypes X======== XMenus --> see comments in menu.c for format of menu file. (menu.mcl) X======== XMessage Areas: X X Access: X A user can access a message area if his priviledge level shares X an access bit with the message area, or if the level of that area is zero. X======== Xareas.bbs, msgareas.bbs X XThese should both serve as examples. (they are what I use on my system). X======== XThings to do: X XI'm in the process of writing USENET support into the message areas. X XFIDONET support should be added to the final release, or possibly a Xsubsequent release. Any information on FIDONET protocol, and mail Xfile formats would be appreciated. X XJay Snyder X....uunet!wa3wbu!gdx!jay Xwa3wbu!gdx!jay@uunet.uu.net SHAR_EOF $TOUCH -am 0116231591 GDXBBS.DOC && chmod 0644 GDXBBS.DOC || echo "restore of GDXBBS.DOC failed" set `wc -c GDXBBS.DOC`;Wc_c=$1 if test "$Wc_c" != "2123"; then echo original size 2123, current size $Wc_c fi # ============= .emacsmail ============== echo "x - extracting .emacsmail (Text)" sed 's/^X//' << 'SHAR_EOF' > .emacsmail && X; EMACS.RC: Standard micro Startup program X; for MicroEMACS 3.9d and above X; (C)opyright 1987 by Daniel M Lawrence X; Last Update: 10/20/87 X Xset $discmd FALSE Xwrite-message "[Setting up....]" X X; If you screen "SNOWS", comment this line X set $flicker "FALSE" X X; To use an IBM-PC EGA card, uncomment the following line X; set $sres "EGA" X X; Set Default Global modes X;add-global-mode "blue" X;bind-to-key next-page FN< X;bind-to-key previous-page FNC X;bind-to-key meta-prefix ` X X X; Toggle function key window display X X1 store-macro X !if %rcfkeys X !goto rcfoff X !endif X X; toggle function key window on X save-window X 1 next-window X !if &sequal $cbufname "emacs.hlp" X delete-window X !endif X !if ¬ &sequal $cbufname "Function Keys" X 1 split-current-window X 1 select-buffer "Function Keys" X add-mode "red" X !force 5 resize-window X 1 goto-line X !endif X set %rcfkeys TRUE X !force restore-window X !if &sequal $cbufname "Function Keys" X next-window X !endif X write-message "[Function key window ON]" X !return X X ;Toggle the function key window off X*rcfoff X save-window X 1 next-window X !if &sequal "Function Keys" $cbufname X delete-window X !endif X !force restore-window X write-message "[Function key window OFF]" X set %rcfkeys FALSE X!endm X X; Toggle HELP file onscreen X X2 store-macro X 1 next-window X X ;Make sure the function key window isn't up! X !if &sequal $cbufname "Function Keys" X delete-window X !endif X set %rcfkeys FALSE X X ;Bring up page 1 X !if ¬ &seq $cbufname "emacs.hlp" X; split-current-window X; view-file /usr/local/uemacs/emacs.hlp X help X 8 resize-window X add-mode "red" X beginning-of-file X 2 forward-character X !endif X X*rchelp X X write-message "[n] Next Page [p] Previous Page [^Z] EXIT HELP" X update-screen X set %rctmp >cmd X !if &seq %rctmp p X beginning-of-line X !force search-reverse "=>" X 1 redraw-display X !goto rchelp X !endif X !if &seq %rctmp ^P X beginning-of-line X !force search-reverse "=>" X 1 redraw-display X !goto rchelp X !endif X !if &seq %rctmp n X beginning-of-line X 2 forward-character X !force search-forward "=>" X 1 redraw-display X !goto rchelp X !endif X !if &seq %rctmp ^N X beginning-of-line X 2 forward-character X !force search-forward "=>" X 1 redraw-display X !goto rchelp X !endif X !if &seq %rctmp ^Z X delete-window X !if &seq %rcfkeys TRUE X set %rcfkeys FALSE X execute-macro-1 X !endif X write-message "[Help Exited]" X !return X !endif X !goto rchelp X!endm X X; Load a new page X X3 store-macro X !if &seq &find newpage.cmd "" X write-message "[Can not find NEWPAGE.CMD]" X !return X !endif X execute-file newpage.cmd X!endm X X;procedure to clean out the current page (which is nothing right now) X Xstore-procedure clean X ; nothing by default X!endm X X; Set up auto CMODE X X20 store-macro X set %rctmp &sin $cfname "." X !if &equ %rctmp 0 X !return X !endif X set %rctmp &mid $cfname &add %rctmp 1 5 X !if &or &seq %rctmp "c" &seq %rctmp "h" X add-mode "cmode" X !endif X !if &seq %rctmp "mss" X add-mode "wrap" X !endif X!endm Xset $readhook execute-macro-20 X X; This function activates the function key window as X; a legitimate place to call up function keys X X21 store-macro X X ;remember where we started, and do the mouse movement X save-window X mouse-move-down X X ;If not in the function key window... leave X !if ¬ &sequal $cbufname "Function Keys" X !return X !endif X X ;Find out what function key were gonna do X add-mode magic X 2 forward-character X set %rctmp $search X !force search-reverse "[fF][0-9]" X !if &seq $status FALSE X delete-mode magic X set $search %rctmp X !return X !endif X X ;we are on the "f" or "F". Get the function key type and number now X set $search %rctmp X set %fcase lower X !if &equ $curchar 70 X set %fcase upper X !endif X 1 forward-character X set %fnum &chr $curchar X 1 forward-character X set %fnum &cat %fnum &chr $curchar X set %fnum &add %fnum 0 X !if &equ %fnum 10 X set %fnum "0" X !endif X set %fname &cat "FN" %fnum X !if &seq %fcase upper X set %fname &cat "S-" %fname X !endif X X ;save the function X set %rccmd &bind %fname X delete-mode MAGIC X X ;swallow the up-button X set %rctmp >c X X ;restore the window and exit X restore-window X X ;and then execute it X execute-named-command &ind %rccmd X!endm Xbind-to-key execute-macro-21 MSa X X X33 store-macro X X unmark-buffer X next-window X unmark-buffer X next-window X unmark-buffer X exit-emacs X!endm X X32 store-macro X X save-file X exit-emacs X!endm X X23 store-macro X next-window X delete-window X execute-macro-2 X split-current-window X !force 4 resize-window X select-buffer "GDXBBS-Mail" X 1 goto-line X next-window X!endm X Xbind-to-key execute-macro-23 M-? Xbind-to-key execute-macro-32 ^Z Xbind-to-key execute-macro-33 M-q Xbind-to-key incremental-search ^S Xunbind-key ^Xo Xunbind-key ^X1 Xunbind-key ^XP Xunbind-key ^X^ Xunbind-key M-^L Xunbind-key ^X^F Xunbind-key ^X^R Xunbind-key ^X^V Xunbind-key ^X^W Xunbind-key ^XN X; don't let the user muck up the windows Xunbind-key ^X^Z Xunbind-key ^XZ Xunbind-key M-^Z Xunbind-key M-^V X;don't let the user delete current window - he'll get confused Xunbind-key ^X0 Xunbind-key ^XB Xunbind-key ^X^B Xunbind-key ^XK Xunbind-key ^X$ Xunbind-key ^X@ Xunbind-key ^X! X X X split-current-window X !force 4 resize-window X select-buffer "UBBS-Mail" X beginning-of-file X insert-string "^P -- Previos Line [ ^Z exit and send message~n" X insert-string "^N -- Next Line [ Escape-Q Quit without sending message~n" X insert-string "^F -- Forward Character [ Escape-? Help with MicroEMACS~n" X insert-string "^B -- Backward Character [ ^D -- Delete charcter to right.~n" X unmark-buffer X beginning-of-file X next-window X set %rcfkeys FALSE X set $discmd TRUE X add-global-mode "wrap" X end-of-file SHAR_EOF $TOUCH -am 0115115391 .emacsmail && chmod 0644 .emacsmail || echo "restore of .emacsmail failed" set `wc -c .emacsmail`;Wc_c=$1 if test "$Wc_c" != "5645"; then echo original size 5645, current size $Wc_c fi # ============= main.c ============== echo "x - extracting main.c (Text)" sed 's/^X//' << 'SHAR_EOF' > main.c && X/* X GDX-BBS V1.0 Beta X (C) 1990 X Jay A. Snyder X*/ X X#define MAIN 1 X#include "inc.h" X Xlogout1(); Xtoggle_monitor(); X Xinit_vars() X{ X idletime=0; X alarm_interval=ALARM_INTERVAL; X idlewarn=DEF_IDLEWARN; X idleout=DEF_IDLEOUT; X maxtime=DEF_MAXTIME; X user_is_logged=0; X ctrlc_stat=0; X kbd_pid=0; X msg_ptrs=NULL; X defterm[0]=0; X fsedit[0]=0; X cur_forecolor=7; X cur_backcolor=0; X curses_init=0; X terminfo_mode=0; X termset=0; X CO=80; X who_switch=0; X LI=24; X expert_mode=0; X sysop=0; X sysop_login=0; X doing_source=0; X pagemode=1; X debug=0; X ansi=0; X monitor_on=FALSE; X cur_msg_area=NULL; X cur_file_area=NULL; X cur_file_lib=NULL; X first_msg_area=NULL; X first_file_area=NULL; X strcpy(prompt,DEF_PROMPT); X strcpy(mondev,DEF_MONDEV); X strcpy(mail_dir,DEF_MAIL_DIR); X strcpy(home_dir,DEF_HOME_DIR); X strcpy(CONFIG_FILE,DEF_CONFIG_FILE); X strcpy(MENU_FILE,DEF_MENU_FILE); X strcpy(ERRORLOG_FILE,DEF_ERRORLOG_FILE); X strcpy(USER_FILE,DEF_USER_FILE); X strcpy(UTMP_FILE,DEF_UTMP_FILE); X strcpy(LOG_FILE,DEF_LOG_FILE); X strcpy(AREAS_FILE,DEF_AREAS_FILE); X strcpy(FILELIBS_FILE,DEF_FILELIBS_FILE); X strcpy(MSGAREAS_FILE,DEF_MSGAREAS_FILE); X strcpy(QUEST_FILE,DEF_QUEST_FILE); X strcpy(QUEST_OUT_FILE,DEF_QUEST_OUT_FILE); X strcpy(sysop_name,SYSOP); X strcpy(def_ul_path,DEF_UL_PATH); X dl_exe[0]=0; X ul_exe[0]=0; X maxtry=MAXTRY; X} X Xexitprog(exitcode) Xint exitcode; X{ Xnormattr(); X#ifdef USECURSES Xif (curses_init) endwin(); X#endif Xif (terminfo_mode) exit_terminfo(); Xunsetraw(); Xcurses_init=0; Xif (kbd_pid!=0) X kill(kbd_pid,SIGTERM); Xexit(exitcode); X} X X Xquit() X{ Xexitprog(0); X} X Xset_switches(argc,argv) Xint argc; Xchar **argv; X{ Xextern char *optarg; Xint i; Xwhile ((i=getopt(argc,argv, "cx:C:tSs:wi")) != EOF) X { X switch (i) X { X case 'c' : /* attempt to use as shell */ X case 'i' : /* attempt to use as shell */ X exit(0); X break; X case 'C' : /* alternate config file */ X strcpy(config_file,optarg); X break; X case 't' : /* don't ask for terminal type */ X termset=1; X break; X case 'x' : /* debug mode */ X debug=atoi(optarg); X break; X case 'S' : /* login as sysop */ X if (getuid()!=0) X { X portsout("Sorry, must be root to use -S\n"); X exitprog(1); X } X sysop_login=1; X sysop=1; X break; X case 's' : /* set command stack size */ X cmd_stack_size=atoi(optarg); X rprintf("\nCommand stack size set to %s.\n",optarg); X break; X case 'w' : /* just do a who */ X who_switch=1; X break; X default : X break; X } /* end case */ X } X} X Xmain(argc,argv,envp) Xint argc; Xchar **argv,**envp; X{ Xint err,i,c; Xchar **v,*cptr,*s; Xenviron=envp; Xgetcwd(sys_home_dir,80); Xthistty[0]=0; Xs=strrchr(ttyname(0),'/'); Xif (*s=='/') ++s; Xstrcpy(thistty,s); Xinit_vars(); Xset_switches(argc,argv); Xinit_env(); Xdef_cmds(); Xchkpriv=0; Xload_config(); Xload_areas(); Xset_ctrl_chars(); Xsetraw(); Xif (who_switch) X { X who(0); X exitprog(0); X } Xctrlc_on(); Xalarm_off(); Xsignal(SIGIOT,SIG_IGN); X#ifdef DEBUG Xsignal(SIGQUIT,SIG_DFL); X#else Xsignal(SIGQUIT,SIG_IGN); X#endif Xsignal(SIGTERM,logout1); Xsignal(SIGHUP,logout1); Xsignal(SIGUSR1,toggle_monitor); Xmalloc(sizeof(USER)); Xload_users(); Xif (defterm[0]==0 || termset) X strcpy(term,(char *) getenv("TERM")); Xelse strcpy(term,defterm); Xver(); Xif (sysop_login) X { X if ((tmp_user=chk_name(sysop_name))==NULL) X { X errorsout("No sysop login present!\n"); X exitprog(0xffff); X } X load_userrec(tmp_user->name,&logged_user); X user_is_logged=1; X } Xelse if (login()) /* return non-zero indicates unsucessful login */ X { X sprintf(str,"Login as %s failed\n",logged_user.name); X errorsout(str); X logsout(str); X exitprog(0xffff); X } Xsprintf(str,"%-20s logged in at %s\n",logged_user.name,timestr()); Xlogsout(str); Xportsout(str); Xlogin_utmp(); Xload_menu(); Xif ((mail_menu_ptr=(m_header_ptr) chk_menu_tag("mail"))== (m_header_ptr) NULL) X { X errorsout("! No mail menu !"); X } Xif ((pubmsg_menu_ptr=(m_header_ptr) chk_menu_tag("pubmsg"))== (m_header_ptr) NULL) X { X errorsout("! No pubmsg menu !"); X } Xif ((proto_menu_ptr=(m_header_ptr) chk_menu_tag("proto"))== (m_header_ptr) NULL) X { X errorsout("! No proto menu !"); X } Xcurrent_menu=first_menu_ptr; Xif (!ncstrcmp(sysop_name,logged_user.name)) sysop=1; Xsprintf(str,"MYNAME=%s",MYNAME); Xsetenv(str); Xchkpriv=0; Xuser_home_dir(str); Xsprintf(str1,"%s/%s",sys_home_dir,str); X /* set env var HOME to user's home directory */ Xsprintf(buf,"set HOME=%s",(str[0]=='/') ? str : str1); Xchkpriv=1; /* enable user to run set command */ Xrun_line(buf); Xload_setup(); Xsprintf(buf,"source %s -s",STARTUP_FILE); Xchkpriv=1; /* enable user to source startup file */ Xrun_line(buf); X/* forkkbd(); */ Xwhile (1) X { X portout('\n'); X print_menu(current_menu); X input[0]=0; X i=3; X while (i==3) X { X setcolor(BRWHITE,BLACK); X portsout(prompt); X setcolor(YELLOW,BLACK); X boldon(); X i=getline(input,79); X boldoff(); X setcolor(LTGREEN,BLACK); X } X portout('\n'); X/* if (strlen(input)>3 && line_change) X push_line(input); */ X run_line(input); X } X} X X X SHAR_EOF $TOUCH -am 1231004490 main.c && chmod 0644 main.c || echo "restore of main.c failed" set `wc -c main.c`;Wc_c=$1 if test "$Wc_c" != "5039"; then echo original size 5039, current size $Wc_c fi # ============= menu.c ============== echo "x - extracting menu.c (Text)" sed 's/^X//' << 'SHAR_EOF' > menu.c && X/* X GDX-BBS V1.0 Beta X (C) 1990 X Jay A. Snyder X*/ X X/* menu.c X routines to print menus, and interpret MCL X (Menu Control Language) code X Xmenu entries: XEntry Text, command X Xpreceed character to use as activation key with a ^ X>menu Xinternal command X! system command, terminal in native mode X% system command, output redirected, and paged with cat X-s means one shot menu (used for transfer protocall menus) X* in priviledge field signifies special menu used by the system (i.e. mail) Xexample menu syntax: Xmenu, menu title [-s],0 X{ X^Messages, >messages,0 X^Files, >files, 1 X^System Info, % view ~/systeminfo,0 X^Who\'s On, % who,0 X^Yell at sysop, % chat console,0 X^Chat, % chat,0 X^Goodbye, % goodbye,0 X^Play Games, >games,2 XSystem ^Load, ! w -t,0 X} X*/ X X#include "inc.h" X X/* return NULL if none exist */ Xm_header_ptr last_menu_ptr() X{ Xm_header_ptr ptr; Xint db; Xdb=0; Xptr=first_menu_ptr; Xif (ptr==NULL) return (NULL); Xif (ptr==NULL) return ptr; Xwhile (ptr->next!=NULL) X { X ptr=ptr->next; X } Xreturn ptr; X} X Xm_header_ptr new_menu_ptr() X{ Xm_header_ptr ptr; Xint db; Xdb=0; Xptr=last_menu_ptr(); Xif (ptr==NULL) X { X if ((ptr=(m_header_ptr) malloc(sizeof(struct m_header)))==NULL) X { X error_message(MALLOC_ERROR); X assert(0); X quit(); X } X } Xelse X { X if ((ptr->next=(m_header_ptr) malloc(sizeof(struct m_header)))==NULL) X { X error_message(MALLOC_ERROR); X assert(0); X quit(); X } X ptr=ptr->next; X } Xptr->next=NULL; /* set next to NULL */ Xreturn ptr; X} X Xm_entry_ptr new_entry_ptr() X{ Xm_entry_ptr ptr; Xif ((ptr=(m_entry_ptr) malloc(sizeof(struct m_entry)))==NULL) X { X error_message(MALLOC_ERROR); X assert(0); X quit(); X } Xptr->next=NULL; Xreturn ptr; X} X X X/* X load_menu() X load in menus from file X*/ Xload_menu() X{ XFILE *fp; Xchar *cptr,xx,cc,db; Xm_header_ptr current_menu_ptr; Xm_entry_ptr current_entry_ptr; Xfp=fopen(MENU_FILE, "r"); Xif (fp==NULL) X { X fatal_error(MENU_FILE_ERROR); X } Xfirst_menu_ptr=new_menu_ptr(); Xcurrent_menu_ptr=first_menu_ptr; Xxx=0;db=0; Xwhile (!feof(fp)) X{ Xfscanf(fp, "%[\n ]",str); Xfscanf(fp, "%[^\n,-]",str); Xif (strlen(str)==0) break; Xstrip_space(str); Xif (xx) current_menu_ptr=new_menu_ptr(); Xxx=1; Xif (strlen(str)>12) X { X portsout("Warning: menu tag name too long, truncated to "); X str[12]=0; X atout(str); X portsout("\n"); X } Xstrcpy(current_menu_ptr->tag,str); Xfscanf(fp, "%[\n,-]",str); Xcurrent_menu_ptr->one_shot=0; Xif (str[0]=='-') /* is a switch specified? */ X { X fscanf(fp, "%[^\n,]", str); X if (str[0]='s') current_menu_ptr->one_shot=1; X } Xfscanf(fp, "%[\n, ]",str); /* skip white space */ Xif (strchr(str,'\n')!=NULL) X { X portsout("Warning: No menu title specified for menu "); X atout(current_menu_ptr->tag); X portsout("\n"); X current_menu_ptr->name[0]=0; X } Xelse { X fscanf(fp, "%[^\n,]", str); X if (strlen(str)>39) X { X portsout("Warning: menu title too long, truncated to "); X str[39]=0; X atout(str); X portsout("\n"); X } X strcpy(current_menu_ptr->name, str); X fscanf(fp, "%[ ,\n]",str); /* skip spaces and ,'s */ X fscanf(fp, "%[^,\n]",str); X if (str[0]=='*') current_menu_ptr->priv=-1; X else current_menu_ptr->priv=strtol(str,NULL,16); X } Xif (debug>2) X { X printf("tag=[%s]\ntitle=[%s]\none_shot=%d\npriv=%lu\n", X current_menu_ptr->tag, X current_menu_ptr->name, X current_menu_ptr->one_shot, X current_menu_ptr->priv); X } Xcurrent_entry_ptr=new_entry_ptr(); Xcurrent_menu_ptr->first_entry=current_entry_ptr; Xfscanf(fp,"%[^{]",str); /* seek { */ Xfscanf(fp,"%[{ \n\r]",str); /* skip white space */ Xcurrent_menu_ptr->count=0; Xif (debug>2) printf("[begin menu]\n"); Xwhile (1 && !feof(fp)) X { X ++(current_menu_ptr->count); X fscanf(fp, "%[^,\n]", str); X if (strchr(str,'}')!=NULL) X { X if (debug>2) X { X printf("[end menu %d entries]\n", X current_menu_ptr->count); X printf("[**]\n"); X } X break; /* from while (1) loop */ X } X if (strlen(str)>18) X { X portsout("Warning: menu entry name too long, trucated to "); X str[18]=0; X atout(str); X portsout("\n"); X } X strcpy(current_entry_ptr->name, str); X if ((cptr=strchr(str, '^'))==NULL) X { X atprintf( X "Warning: no activation key specified for menu:%s, entry:%s\n", X current_menu_ptr->tag, X current_entry_ptr->name); X } X else { X ++cptr; X current_entry_ptr->actkey=*cptr; X } X fscanf(fp, "%[} ,\n]",str); X if (strchr(str,',')==NULL) X { X atprintf("Warning: no command for menu:%s, entry:%s\n", X current_menu_ptr->tag, X current_entry_ptr->name); X if (strchr(str,'}')!=NULL) X { X if (debug>2) X { X printf("[end menu %d entries]\n", X current_menu_ptr->count); X printf("[**]\n"); X } X break; /* from while (1) loop */ X } X } X else { X fscanf(fp, "%[^},\n]", str); X if (strlen(str)>59) X { X portsout("Warning: command entry truncated to ["); X str[59]=0; X atout(str); X portsout("]\n"); X } X strcpy(current_entry_ptr->cmd,str); X current_entry_ptr->priv=0; X cc=fgetc(fp); X if (cc==',') X { X fscanf(fp, "%[^},\n]",str); X current_entry_ptr->priv=strtol(str,NULL,16); X } X } X if (debug>2) X { X printf("entry:%20.20s actkey=%c command=%s priv=%lu\n", X current_entry_ptr->name, X current_entry_ptr->actkey, X current_entry_ptr->cmd, X current_entry_ptr->priv); X } X fscanf(fp, "%[}\n]", str); X if (strchr(str,'}')!=NULL) X { X if (debug>2) X { X printf("[end menu %d entries]\n", X current_menu_ptr->count); X printf("[**]\n"); X } X break; /* from while (1) loop */ X } X else { /* get next entry */ X if ((current_entry_ptr->next=new_entry_ptr())==NULL) X { X error_message(MALLOC_ERROR); X assert(0); X quit(); X } X current_entry_ptr=current_entry_ptr->next; X } X } /* inner while (1) loop */ X} Xfclose(fp); X} X Xprint_entry(ptr) Xm_entry_ptr ptr; X{ Xchar *s; Xint count; Xs=ptr->name; Xcount=0; Xwhile (*s) X { X if (*s=='^') X { X if (terminfo_mode) X { X setcolor(WHITE,BLACK); X boldon(); X } X else portout('['); X ++s; X portout(*s++); X if (terminfo_mode) X { X boldoff(); X setcolor(LTGREEN,BLACK); X } X else portout(']'); X } X else portout(*s++); X ++count; X } Xwhile (count++<17) portout(' '); X} X Xprint_menu(menu_ptr) Xm_header_ptr menu_ptr; X{ Xint i,ii,db; Xm_entry_ptr ptr; Xdb=0; Xif (terminfo_mode) X { X setcolor(YELLOW,BLACK); X boldon(); X } Xatout(menu_ptr->name); Xportout('\n'); Xif (terminfo_mode) X { X boldoff(); X setcolor(LTGREEN,BLACK); X } Xptr=menu_ptr->first_entry; Xswitch (expert_mode) X { X case 0: X ii=0; X for (i=0;i<menu_ptr->count;++i) X { X if (chk_menu_priv(ptr)) X { X print_entry(ptr); X if (ii-3-(ii/4)*4==0) portout('\n'); X ++ii; X } X ptr=ptr->next; X } X portout('\n'); X break; X case 1: X if (chk_menu_priv(ptr)) X portout(ptr->actkey); X ptr=ptr->next; X for (i=1;i<menu_ptr->count;++i) X { X if (chk_menu_priv(ptr)) X { X portout(','); X portout(ptr->actkey); X } X ptr=ptr->next; X } X portout(' '); X break; X default: X break; X } /* end switch */ X} X Xm_header_ptr chk_menu_tag(s) Xchar *s; X{ Xm_header_ptr header; Xheader=first_menu_ptr; Xwhile (header!=NULL) X { X if (!strcmp(s,header->tag)) return(header); X header=header->next; X } Xreturn(NULL); X} X Xm_entry_ptr chk_entry(c,mptr) Xchar c; Xm_header_ptr mptr; X{ Xm_entry_ptr entry; Xint i; Xc=toupper(c); Xentry=mptr->first_entry; Xfor (i=0;i<mptr->count;++i) X { X if (c==toupper(entry->actkey)) return (entry); X entry=entry->next; X } Xreturn(NULL); X} X Xmexec_line(argc,argv) Xint argc; Xchar **argv; X{ Xint c,i; Xchar **v; Xchar tmpstr[80]; Xm_entry_ptr entry; Xm_header_ptr header; Xc=argc; Xv=argv; Xif (strlen(v[0])==1) X if ((entry=chk_entry(v[0][0],current_menu))!=NULL) X /* process menu selection */ X { X v[0]=entry->cmd; X chkpriv=chk_menu_priv(entry); X if (chkpriv || doing_source) X { X unparse_line(c,v,input); X parse_line(&c,v,input); X return(mexec_line(c,v)); X } X else X { X error_message(PRIV_ERROR); X return(-1); X } X } Xif (c) X { X if (v[0][0]=='>') /* select new menu */ X { X if ((header=chk_menu_tag(&v[0][1]))==NULL) X { X portout('\n'); X error_message(BAD_MENU_TAG); X } X else if (header->priv==(PRIV)-1) X { X portsout("Sorry, special menu entry, not directly executable.\n"); X return(0); X } X else if (chk_menu_header_priv(header)) X { X current_menu=header; X chkpriv=0; X if (c>1) return(mexec_line(c-1,&v[1])); X return(0); X } X else X { X error_message(PRIV_ERROR); X return(-1); X } X } /* if (v.. */ X } /* if (c) */ Xif (v[0][0]=='!' && (chkpriv || sysop || doing_source)) X { X /* put system command code here */ X unparse_line(c,v,input); X systemx(&input[1]); X pause(); X chkpriv=0; X } Xelse if (v[0][0]=='%' && (chkpriv || sysop || doing_source)) X { X /* put system command code here */ X unparse_line(c,v,input); X strcpy(buf,&input[1]); X sprintf(tmpstr,"/tmp/.tmp.ubbs.%s",thistty); X#ifdef F_SYSV X unlink(tmpstr); X#else X remove(tmpstr); X#endif X strcat(buf," >"); X strcat(buf,tmpstr); X system(buf); X sprintf(buf,"cat %s",tmpstr); X run_line(buf); X#ifdef F_SYSV X unlink(tmpstr); X#else X remove(tmpstr); X#endif X chkpriv=0; X } Xelse X exec_line(c,v); Xchkpriv=0; X} SHAR_EOF $TOUCH -am 1231001390 menu.c && chmod 0644 menu.c || echo "restore of menu.c failed" set `wc -c menu.c`;Wc_c=$1 if test "$Wc_c" != "9026"; then echo original size 9026, current size $Wc_c fi # ============= misc.c ============== echo "x - extracting misc.c (Text)" sed 's/^X//' << 'SHAR_EOF' > misc.c && X/* X GDX-BBS V1.0 Beta X (C) 1990 X Jay A. Snyder X*/ X X#include "inc.h" X#include <varargs.h> X Xchar *eatnl(s) /* kill the new-line character on the end of string */ X char *s; X{ X int l; X if ((l=strlen(s))==0) return; X if (s[l-1]=='\n') s[l-1]=0; X return(s); X} X X Xchar *stripquote(s) X char *s; X{ X int i; X if (s==NULL) return(NULL); X if ((i=strlen(s))==0) return(s); X if (s[i-1]=='\"' && s[0]=='\"') X { X s[i-1]=0; X delchr(s,0); X } X return(s); X} X Xchar *myfgets(s,maxnum,fp) X char *s; X int maxnum; X FILE *fp; X{ X char *err; X if (s==NULL) X { X fprintf(stderr,"s=NULL\n"); X return(NULL); X } X if (fp==NULL) X { X fprintf(stderr,"fp=NULL\n"); X return(NULL); X } X s[0]=0; X err=fgets(s,maxnum,fp); X eatnl(s); X return(err); X} X Xstrdncase(s) Xchar *s; X{ Xwhile (*s) X { X *s=tolower(*s); X ++s; X } X} X Xchar *timestr() X{ Xchar *s; Xtime_t t; Xt=time((time_t *) 0); Xs=ctime(&t); Xeatnl(s); Xreturn(s); X} X X Xdelchr(s,p) Xchar *s; Xint p; X{ Xs=&s[p]; Xwhile (*s) X *s=*(++s); X} X Xinschr(s,p) Xchar *s; Xint p; X{ Xint pp; Xpp=strlen(s)+1; Xwhile (pp>p+1) X s[pp]=s[pp-1]; X} X Xstrip_space(s) Xchar *s; X{ Xint i; Xi=0; Xwhile(isspace(s[i])) X ++i; Xstrcpy(s,&s[i]); Xi=0; Xwhile (!(isspace(s[i])) && s[i]!=0) X ++i; Xs[i]=0; X} X Xlogsout(s) /* append text to log file */ Xchar *s; X{ X FILE *fp; X if ((fp=fopen(LOG_FILE,"a"))==NULL) X { X printf("logfile=%s\n",LOG_FILE); X error_message(LOG_FILE_ERROR); X/* exitprog(LOG_FILE_ERROR); */ X return(1); X } X fprintf(fp,"%s",s); X fclose(fp); X} X Xpause() X{ X if (color_mode) _setcolor(BRWHITE,BLUE); X else reverseon(); X portsout("\r[Press any key to continue]"); X if (color_mode) fixcolor(); X else reverseoff(); X portin(); X portsout("\r \r"); X} X Xyesno(yn) X int yn; X{ X char c; X c=0; X if (yn>=0) X portsout((yn) ? "(Y or n): " : "(n or Y): "); X else portsout("(Y or N): "); X while (c!='y' && c!='n' && (!(c==0x0d && yn>=0))) X { X c=portin(); X c=tolower(c); X } X portout(c); X switch(c) X { X case 'y': return(1); X break; X case 'n': return(0); X break; X case 0x0d: return(yn); X break; X } X} X X X/* X colors: 0-7 black,red,green,yellow/brown,blue,magenta,cyan,white X for ansi terminals only. X X*/ X X X Xmore_prompt() X{ X char c; X if (color_mode) _setcolor(BRWHITE,BLUE); X else reverseon(); X portsout(" More? (Y,n,non-Stop) "); X if (color_mode) fixcolor(); X else reverseoff(); X c=0; X while (c!='y' && c!='n' && c!='s' && c!=CR) X { X c=portin(c); X c=tolower(c); X if (c==' ') c='y'; X } X portsout("\r \r"); X return(c); X} X X Xstr_cmp(p1,p2) X char **p1,**p2; X{ X return(strcmp(*p1,*p2)); X} X Xprint_args(argc,argv) X int argc; X char **argv; X{ X int i; X printf("argc=%d ", argc); X for (i=0;i<argc;++i) X printf("[%s]\n",argv[i]); X portout('\n'); X} X X/* X insert_chr --> insert character 'c' in string 's' X*/ Xinsert_chr(s,c) X char *s,c; X{ X int i; X i=strlen(s); X s[i+1]=0; X while (i) X { X s[i]=s[i-1]; X --i; X } X s[0]=c; X} X X Xappend_file(file1,file2) /* use only for TEXT files !! */ X char *file1,*file2; X{ X char s[255]; X FILE *fp1,*fp2; X if ((fp1=fopen(file1,"r"))==NULL) X { X portsout("append_file(): error openning input file: "); X portsout(file1); X portout('\n'); X return(-1); X } X if ((fp2=fopen(file2,"a"))==NULL) X { X portsout("append_file(): error openning input file: "); X portsout(file2); X portout('\n'); X return(-2); X } X while (!feof(fp1)) X { X s[0]=0; X fgets(s,254,fp1); X if (!feof(fp1)) X fputs(s,fp2); X } X fclose(fp1); X fclose(fp2); X} X X#ifdef F_SYSV Xrename(oldname,newname) X char *oldname,*newname; X{ X int err; X if ((err=link(oldname,newname))!=0) return(err); X return(unlink(oldname)); X} X#endif X Xcreate_file(filename) X char *filename; X{ X FILE *fp; X if ((fp=fopen(filename,"w"))==NULL) return(-1); X fclose(fp); X return(0); X} X Xncstrcmp(s1,s2) /* case insensitive string compare */ Xchar *s1,*s2; X{ Xint i; Xwhile(!(i=toupper(*s1) - toupper(*s2)) && *s1 && *s2) {++s1;++s2;} Xreturn(i); X} X Xchar *basename(pathname) X char *pathname; X{ X char *p; X if ((p=strrchr(pathname,'/'))==NULL) X return(pathname); X ++p; X return(p); X} X Xchar *dirname(pathname,s) X char *pathname,*s; X{ X char *p; X strcpy(s,pathname); X if ((p=strrchr(s,'/'))==NULL) X s[0]=0; X else *p=0; X return(s); X} X Xkill_trailing_space(s) X char *s; X{ X int i; X if (s==NULL) return; X if (s[0]==0) return; X i=strlen(s)-1; X while (i>=0 && isspace(s[i])) X { X --i; X } X if (isspace(s[i+1])) s[i+1]=0; X} X Xrprintf(va_alist) X va_dcl X{ X va_list vlist; X char *fmt; X char buf[BUFSIZE]; X X va_start(vlist); X fmt=va_arg(vlist, char *); X vsprintf(buf,fmt,vlist); X portsout(buf); X va_end(vlist); X return; X} X Xatprintf(va_alist) X va_dcl X{ X va_list vlist; X char *fmt; X char buf[BUFSIZE]; X X va_start(vlist); X fmt=va_arg(vlist, char *); X vsprintf(buf,fmt,vlist); X atout(buf); X va_end(vlist); X return; X} X Xtoggle_monitor() X{ X#ifdef DEBUG Xif (debug) X fprintf(stderr,"monitor\n"); X#endif X if (monitor_on) X { X#ifdef DEBUG Xif (debug) X fprintf(stderr,"monitor off\n"); X#endif X fclose(monfp); X monitor_on=FALSE; X } X else X { X if ((monfp=fopen(mondev,"w"))) X { X monitor_on=TRUE; X#ifdef DEBUG Xif (debug) X fprintf(stderr,"monitor on\n"); X#endif X } X } X signal(SIGUSR1,toggle_monitor); X} SHAR_EOF $TOUCH -am 1226003290 misc.c && chmod 0644 misc.c || echo "restore of misc.c failed" set `wc -c misc.c`;Wc_c=$1 if test "$Wc_c" != "5459"; then echo original size 5459, current size $Wc_c fi # ============= error.c ============== echo "x - extracting error.c (Text)" sed 's/^X//' << 'SHAR_EOF' > error.c && X/* X GDX-BBS V1.0 Beta X (C) 1990 X Jay A. Snyder X*/ X X#include "inc.h" X#include <varargs.h> X Xchar *err_msg[]={ X "No error!\n", X "! Cannot open menu file\n", /* 1 */ X "! Cannot open utmp file\n", /* 2 */ X "! memory allocation error\n", /* 3 */ X "unsupported terminal type\n", /* 4 */ X "! invalid menu tag\n", /* 5 */ X "! Cannot open error log!\n", /* 6 */ X "! Cannot open user file\n", /* 7 */ X "! Cannot open log file\n", /* 8 */ X "! Cannot open config file\n", /* 9 */ X "Insufficient priviledge!\n", /* 10 */ X "! Cannot open questionaire file\n", /* 11 */ X "! Cannot open temporary user file!\n", /* 12 */ X "invalid username\n", /* 13 */ X "! Could not fork()!\n", /* 14 */ X "! exec() error!\n", /* 15 */ X "! Cannot open message area file!\n", /* 16 */ X "! Cannot open file area file!\n", /* 17 */ X "! Cannot open file lib file!\n", /* 18 */ X "" X }; X X Xerror_message(errno) Xint errno; X{ Xif (errno>=sizeof(err_msg)/sizeof(char *)) X errorsout("! Invalid error number!\n"); Xelse errorsout(err_msg[errno]); X} X X/* Xfatal_error(errno) Xint errno; X{ Xportsout("FATAL: "); Xerror_message(errno); Xexitprog(errno); X} X*/ X Xerrorsout(va_alist) X va_dcl X{ X va_list vlist; X char *fmt; X char buf[BUFSIZE]; X FILE *fp; X va_start(vlist); X fmt=va_arg(vlist, char *); X vsprintf(buf,fmt,vlist); X portsout(buf); X if (buf[0]=='!') X { X if ((fp=fopen(ERRORLOG_FILE,"a"))==NULL) X { X portsout(ERRORLOG_ERROR); X exitprog(ERRORLOG_ERROR); X } X fprintf(fp,"%s",buf); X fclose(fp); X } X va_end(vlist); X} SHAR_EOF $TOUCH -am 0507212690 error.c && chmod 0644 error.c || echo "restore of error.c failed" set `wc -c error.c`;Wc_c=$1 if test "$Wc_c" != "1506"; then echo original size 1506, current size $Wc_c fi # ============= cle.c ============== echo "x - extracting cle.c (Text)" sed 's/^X//' << 'SHAR_EOF' > cle.c && X/* X GDX-BBS V1.0 Beta X (C) 1990 X Jay A. Snyder X*/ X X#include "inc.h" X X rawportout(); X Xgetline(s,maxlen) X char *s; X int maxlen; X{ X char q,c,buf[80],insert_mode; X int p,l,i,x,y; X ctrlc_off(); X idletime=0; X if (maxlen>79) X { X maxlen=79; X s[maxlen]=0; X } X strcpy(buf,s); X q=0;p=0;l=strlen(buf);insert_mode=1; X portsout(buf); X for(i=0;i<l;++i) portout(8); X while(!q) X { X c=portin(); X switch (c) X { X case 9 : /* ^I, TAB */ X insert_mode=!insert_mode; X break; X case CR : X case NL : X q=1; X break; X case BS : X case DEL : X if ((p==l) && (p>0)) /* at end of line */ X { X portsout("\b \b"); /* backup and kill character */ X --p;--l; X buf[p]=0; X } X else if (p>0) X { X line_change=1; X --p; X portout('\b'); X delchr(buf,p); X --l; X if (terminfo_mode && DC!=NULL) X tputs(DC,1,rawportout); X else X { X portsout(&buf[p]); X portout(' '); X for (i=p;i<l+1;++i) portout(8); X } X } X break; X case 1: /* ^A, beginning of line */ X while (p>0) X { X portout(8); /* backup one character */ X --p; X } X break; X case 2: /* ^B, backward character */ X if (p>0) X { X portout(8); /* backup one character */ X --p; X } X break; X case 3: /* ^C */ X q=1; X buf[0]=0; X portout('\n'); X if (color_mode) _setcolor(BRWHITE,BLUE); X else reverseon(); X portsout(" CANCEL "); X if (color_mode) fixcolor(); X else reverseoff(); X portout('\n'); X line_change=0;break; X case 4: /* ^D, delete character to right of cursor */ X if (l>p) X { X line_change=1; X delchr(buf,p); X --l; X if (terminfo_mode && DC!=NULL) X tputs(DC,1,rawportout); X else X { X portsout(&buf[p]); X portout(' '); X for (i=p;i<l+1;++i) portout(8); X } X } X break; X case 5: /* ^E, end of line */ X while (p<l) X { X portout(buf[p++]); X } X break; X case 6: /* ^F, forward characer */ X if (p<l) X { X portout(buf[p++]); X } X break; X case 11: /* ^K, kill rest of line */ X line_change=1; X if (terminfo_mode) X { X clreol(); X } X else X { X for (i=p;i<l;++i) portout(' '); X for (i=p;i<l;++i) portout(8); X } X l=p;buf[p]=0; X break; X case 21: /* ^U, kill all of line */ X line_change=1; X if (terminfo_mode) X { X for (i=p;i>0;--i) portout('\b'); X clreol(); X } X else X { X for (i=p;i>0;--i) portout('\b'); X for (i=0;i<l;++i) portout(' '); X for (i=0;i<l;++i) portout('\b'); X } X l=0;p=0;buf[0]=0; X break; X case 18: /* ^R, redisplay line */ X for (i=p;i>0;--i) portout('\b'); X if (terminfo_mode) X { X clreol(); X } X else X { X for (i=0;i<l;++i) portout(' '); X for (i=0;i<l;++i) portout('\b'); X } X buf[l]=0; X portsout(buf); X p=l; X break; X case 16: /* ^P, previous line */ X break; X dec_rcmdptr();line_change=0; X for (i=0;i<p;++i) portout(8); X for (i=0;i<l;++i) portout(' '); X for (i=0;i<l;++i) portout(8); X pop_line(buf); X p=strlen(buf); X l=p; X printf("%s",buf); X break; X case 14: /* ^N, next line */ X break; X inc_rcmdptr();line_change=0; X pop_line(buf); X for (i=0;i<p;++i) portout(8); X for (i=0;i<l;++i) portout(' '); X for (i=0;i<l;++i) portout(8); X pop_line(buf); X p=strlen(buf); X l=p; X printf("%s",buf); X break; X default: X if ((isprint(c) || isspace(c)) && c>31 && X !((insert_mode || p==l) && l>maxlen-1)) X { X line_change=1; X if (insert_mode && p<l) X { X insert_chr(&buf[p],c); X ++l; X if (terminfo_mode && IC!=NULL) X { X tputs(IC,1,rawportout); X portout(c); X } X else X { X portsout(&buf[p]); X for (i=p+1;i<l;++i) portout('\b'); X } X ++p; X } X else X { X if (p==l) buf[p+1]=0; X portout(c); X buf[p]=c; X ++p; X if (p>l) ++l; X } X } X break; X } /* end switch */ X }/* end while(!q) */ X strcpy(s,buf); X ctrlc_on(); X return(c); X} X X Xinc_rcmdptr() X{ X while(*(++rcmdptr)) X if (rcmdptr>=cmd_stack+cmd_stack_size) rcmdptr=cmd_stack; X /* ++rcmdptr; */ X if (!(*rcmdptr)) X { X while(!(*(++rcmdptr))) X if (rcmdptr>=cmd_stack+cmd_stack_size) rcmdptr=cmd_stack; X } X if (rcmdptr>=cmd_stack+cmd_stack_size) rcmdptr=cmd_stack; X} X X Xdec_rcmdptr() X{ X --rcmdptr; X if (rcmdptr<cmd_stack) X rcmdptr=cmd_stack+cmd_stack_size; X while(*(--rcmdptr)) X if (rcmdptr<cmd_stack) X { X rcmdptr=cmd_stack; X return(0); X } X if (!(rcmdptr[-1])) X { X while(!(*(--rcmdptr))) X if (rcmdptr<=cmd_stack) rcmdptr=cmd_stack+cmd_stack_size; X while(*(--rcmdptr)) X if (rcmdptr<=cmd_stack) rcmdptr=cmd_stack+cmd_stack_size; X } X ++rcmdptr; X} X Xhome_rcmdptr() X{ X rcmdptr=cmdptr; X inc_rcmdptr(); X} X Xhistory(argc,argv) X int argc; X char **argv; X{ X char *sto_rcmdptr,*p,q; X int i; X if (!argc) X { X printf("history -- print command history\n"); X printf("Syntax:\n hist [command]\n"); X printf("when command is specified, then history of that command's\n"); X printf("is listed.\n\n"); X printf("Typing !# where # is a number associated with a particular\n"); X printf("line in the history will get that line and put it in the\n"); X printf("current line buffer\n"); X return(0); X } X sto_rcmdptr=rcmdptr; X home_rcmdptr(); X p=rcmdptr; X q=1;i=0; X while(q) X { X ++i; X if (argc<2 || !strncmp(argv[1],rcmdptr,strlen(argv[1]))) X printf("%3d: %s\n",i,rcmdptr); X inc_rcmdptr(); X if (rcmdptr==p) q=0; X } X rcmdptr=sto_rcmdptr; X return(0); X} X X Xpush_line(str) X char *str; X{ X while (*str) *cmdptr++=*str++; X *cmdptr++=0;*cmdptr=0; X if (strlen(str)>= ((int) cmd_stack) + cmd_stack_size - (int) cmdptr) X cmdptr=cmd_stack; X rcmdptr=cmdptr; X} X Xpop_line(str) X char *str; X{ X strcpy(str,rcmdptr); X} SHAR_EOF $TOUCH -am 0507213490 cle.c && chmod 0644 cle.c || echo "restore of cle.c failed" set `wc -c cle.c`;Wc_c=$1 if test "$Wc_c" != "5842"; then echo original size 5842, current size $Wc_c fi # ============= parse.c ============== echo "x - extracting parse.c (Text)" sed 's/^X//' << 'SHAR_EOF' > parse.c && X/* X GDX-BBS V1.0 Beta X (C) 1990 X Jay A. Snyder X*/ X X#include "inc.h" X X Xchar *cmds[]={ X "bulletin","cat","chat","chfa","chfal","chma","dl","echo", X "expert","find","help","history","logout","ls","mail", X "mscan","passwd","pause","pwd","quest","set","setpage", X "setproto","setterm","source","ul","users","ver","who","\377\377" X }; X#define CMDCOUNT (int) sizeof(cmds)/sizeof(char *) XCOMMAND *com[CMDCOUNT]; X Xint cat(),chfa(),chfal(),chma(),help(),history(),ls(),pwd(),ver(),logout(), X expert(),who(),chat(),setpage(),mscan(),bulletin(), X passwd(),doquest(),findfile(),uploadfile(),dnloadfile(),doscript(), X echo(),pause(),mail(),list_users(),set(),setterm(),setproto(); X Xdef_cmds() X{ Xint i; Xcmdcount=CMDCOUNT; Xfor (i=0;i<CMDCOUNT;++i) X { X com[i]=(COMMAND *) malloc(sizeof(COMMAND)); X if (com[i]==NULL) X { X error_message(MALLOC_ERROR); X assert(0); X quit(); X } X } Xi=0; Xcom[i]->priv=0;com[i++]->func=bulletin; Xcom[i]->priv=SYSOP_PRIV;com[i++]->func=cat; Xcom[i]->priv=1;com[i++]->func=chat; Xcom[i]->priv=1;com[i++]->func=chfa; Xcom[i]->priv=1;com[i++]->func=chfal; Xcom[i]->priv=1;com[i++]->func=chma; Xcom[i]->priv=1;com[i++]->func=dnloadfile; /* dl */ Xcom[i]->priv=0;com[i++]->func=echo; Xcom[i]->priv=1;com[i++]->func=expert; Xcom[i]->priv=1;com[i++]->func=findfile; Xcom[i]->priv=0;com[i++]->func=help; Xcom[i]->priv=0;com[i++]->func=history; Xcom[i]->priv=0;com[i++]->func=logout; Xcom[i]->priv=1;com[i++]->func=ls; Xcom[i]->priv=0;com[i++]->func=mail; Xcom[i]->priv=1;com[i++]->func=mscan; Xcom[i]->priv=1;com[i++]->func=passwd; Xcom[i]->priv=1;com[i++]->func=pause; Xcom[i]->priv=1;com[i++]->func=pwd; Xcom[i]->priv=0;com[i++]->func=doquest; Xcom[i]->priv=0x100;com[i++]->func=set; Xcom[i]->priv=0;com[i++]->func=setpage; Xcom[i]->priv=0;com[i++]->func=setproto; Xcom[i]->priv=0;com[i++]->func=setterm; Xcom[i]->priv=0x100;com[i++]->func=doscript; /* source */ Xcom[i]->priv=1;com[i++]->func=uploadfile; Xcom[i]->priv=0;com[i++]->func=list_users; Xcom[i]->priv=0;com[i++]->func=ver; Xcom[i]->priv=1;com[i++]->func=who; Xfor (i=0;i<CMDCOUNT;++i) X { X com[i]->name=cmds[i]; X com[i]->fnum=i; X } X} X X X Xunparse_line(argc,argv,s) Xint argc; Xchar **argv,*s; X{ Xchar temp[160],*t,*t1; Xint i; Xtemp[0]=0; Xt=temp; Xfor (i=0;i<argc;++i) X { X t1=argv[i]; X while (*t1) X *t++=*t1++; X *t++=' '; X } X *(--t)=0; Xstrcpy(s,temp); X} X X Xparse_line(argc,argv,str) Xint *argc; Xchar **argv,*str; X{ Xchar *s,quote; Xint index; Xs=str;index=1; Xsub_env(str,str); Xwhile ((*s) && isspace(*s)) ++s; Xif (!*s) X { X *argc=0;return(0); X } Xargv[0]=s; Xquote=0; Xwhile(*s) X { X if (isspace(*s) && !quote) X { X *s++=0; X while ((*s) && (isspace(*s))) ++s; X if (*s) X { X argv[index]=s; X ++index; X } X } X if (*s=='\"') X { X quote=~quote; X if (quote) ++s; X } X if (*s=='\\') X { X delchr(s,0); X } X ++s; X } X*argc=index; Xif (debug) X print_args(*argc,argv); X} X X Xcmd_cmp(p1,p2) XCOMMAND **p1,**p2; X{ Xreturn(strcmp((**p1).name,(**p2).name)); X} X Xint chk_cmd(str) Xchar *str; X{ XCOMMAND *s,s1,**p; Xs1.name=str; Xs1.func=NULL; Xs1.fnum=3; Xs=&s1; Xp=(COMMAND **) X bsearch((char *) &s,(char *) com,CMDCOUNT,sizeof(COMMAND *),cmd_cmp); Xif (p==NULL) return(0xffff); Xreturn((**p).fnum); X} X Xexec_line(argc,argv) Xint argc; Xchar **argv; X{ Xint i,er; Xfptr func; Xint fnum; Xchar pathname[64]; Xif (argc==0) {return(0);} Xargv[argc]=NULL; Xif (argv[0][0]=='#') return(0); Xif (debug>3) X { X for (i=0;i<argc;++i) X { X printf("%s ",argv[i]); X } X printf("\n"); X } Xfnum=chk_cmd(argv[0]); Xif (fnum!=0xffff) X{ X func=com[fnum]->func; X if (!doing_source && !chkpriv && !chk_cmd_priv(com[fnum]) && !sysop) X { X sprintf(buf,"Sorry, you are not authorized to use %s\n", X com[fnum]->name); X portsout(buf); X } Xelse return((*func)(argc,argv)); X} Xelse X { X sprintf(buf,"Invalid command: %s\n",argv[0]); X portsout(buf); X return(0xffff); X } X} X Xrun_line(str) X char *str; X{ X int c; X char *v[20],s[LINE_SIZE]; X strcpy(s,str); /* destroying the string */ X if (echo_mode) X { X portsout(s); X portout('\n'); X } /* make copy so args can be null terminated w/o */ X parse_line(&c,v,s); X if (c) X mexec_line(c,v); X} SHAR_EOF $TOUCH -am 1230232990 parse.c && chmod 0644 parse.c || echo "restore of parse.c failed" set `wc -c parse.c`;Wc_c=$1 if test "$Wc_c" != "4139"; then echo original size 4139, current size $Wc_c fi # ============= funcs.c ============== echo "x - extracting funcs.c (Text)" sed 's/^X//' << 'SHAR_EOF' > funcs.c && X/* X GDX-BBS V1.0 Beta X (C) 1990 X Jay A. Snyder X*/ X X#include "inc.h" X XUSER *chk_name(); Xchar portin(); X Xint cat(argc,argv) Xint argc; Xchar **argv; X{ Xextern char *optarg; Xextern optind; Xint i,page_lines; Xchar rawtype,nopage,silent,*filename,c,q,s[255],noat; XFILE *fp; Xoptind=1; Xnopage=0;rawtype=0;silent=0;noat=0; Xwhile ((i=getopt(argc,argv, "anrs")) != EOF) X { X switch (i) X { X case 'a' : /* no at commands */ X noat=1; X case 's' : /* silent, no error for file not found */ X silent=1; X break; X case 'r' : /* raw type of file (no filtering) */ X rawtype=1; X break; X case 'n' : /* no page */ X nopage=1; X break; X default: break; X } X } Xi=1; Xwhile (i<argc && argv[i][0]=='-') ++i; Xif (i<argc) filename=argv[i]; Xelse { X errorsout("\ncat: no filename specified\n"); X return(-1); X } Xif ((fp=fopen(filename,"r"))==NULL) X { X if (!silent) X { X sprintf(str,"\nError opening %s!\n",filename); X errorsout(str); X } X return(0xffff); X } Xpage_lines=0;q=0; Xif (rawtype) X while (!feof(fp) && !q && !ctrlc()) X { X c=fgetc(fp); X portout(c); X } Xelse while (!feof(fp) && !q && !ctrlc()) X { X s[0]=0; X if (!feof(fp)) X fscanf(fp,"%[^\n]",s); X if (!feof(fp)) X fgetc(fp); X if (noat) portsout(s); X else atout(s); X portsout("\n\r"); X if (!nopage && pagemode && ++page_lines>LI-2) X { X c=more_prompt(); X switch (c) X { X case CR: X case 'y': X page_lines=0; X break; X case 'n': X q=1; X break; X case 's': X nopage=1; X break; X } X } X } Xfclose(fp); Xif (!nopage && pagemode && ++page_lines>LI-8) X { X if (color_mode) _setcolor(BRWHITE,BLUE); X else reverseon(); X portsout(" End of File -- Press any key to continue"); X if (color_mode) fixcolor(); X else reverseoff(); X portin(); X portsout("\r \r"); X } Xreturn(0); X} X Xint echo(argc,argv) Xint argc; Xchar **argv; X{ X int i; X for (i=1;i<argc;++i) X { X atout(argv[i]); X portout(' '); X } SHAR_EOF echo "End of gdxbbs part 1" echo "File funcs.c is continued in part 2" echo "2" > @shar_seq_.tmp exit 0