100 REM *****RIBBS - "Remote Iselin Bulletin Board System"***** 120 REM by Bruce R Ratoff 140 REM adapted from Xitan Basic SJBBS by Howard Moulton 160 REM Last change: 9/19/80 180 REM 200 REM 220 DEFINT A-Z 240 DIM A$(17),M(400,2) 260 POKE 0,&HCD 280 ON ERROR GOTO 13500 300 REM 320 REM SIGNON FUNCTIONS 340 REM 350 MSGS=1:CALLS=MSGS+1:MNUM=CALLS+1 360 BK=0:GOSUB 13000:A$="Iselin N.J. RIBBS ":GOSUB 13000 380 A$="Program exchange on request.":GOSUB 13000 400 OPEN "I",1,"A:INFO":BK=0:N=0 420 IF EOF(1) OR BK THEN 440 ELSE LINE INPUT#1,A$:GOSUB 13000:GOTO 420 440 CLOSE#1:OPEN "I",1,"A:BULLETIN":BK=0:N=0 460 IF EOF(1) OR BK THEN 480 ELSE LINE INPUT#1,A$:GOSUB 13000:GOTO 460 480 CLOSE#1:BK=0:A$="Prompting bell means system is ready for input.":GOSUB 13000 500 GOSUB 13000 520 A$="What is your FIRST name ?":GOSUB 13000:C=1:GOSUB 13200:C=0:N$=B$: IF N$="" THEN 520 530 IF N$<"A" THEN 520 540 A$="What is your LAST name ?":GOSUB 13000:C=1:GOSUB 13200:C=0:O$=B$: IF O$="" THEN 520 550 IF O$<"A" THEN 520 560 IF N$="SYSOP" AND O$="BRUCE" THEN O$="":GOTO 780 570 IF N$="SYSOP" THEN 520 580 V=0:OPEN "R",1,"A:USERS",62:FIELD#1,62 AS RR$:GET#1,1:NU=VAL(RR$): A$="Checking user file...":GOSUB 13000 600 FOR I=2 TO NU+1:GET#1,I: IF INSTR(RR$,N$)>0 AND INSTR(RR$,O$)>0 THEN MF$=LEFT$(RR$,1):CLOSE: GOSUB 13000:GOTO 780 620 NEXT I 640 V=1:A$="Where (City,State) are you calling from ?":GOSUB 13000: C=1:GOSUB 13200:C=0:ST$=B$:IF ST$="" THEN 540 660 A$="Hello "+N$+" "+O$+" from "+ST$:GOSUB 13000: A$="Did I misspell anything ?":GOSUB 13000:C=1:GOSUB 13200:C=0: IF LEFT$(B$,1)="Y" THEN 520 680 A$="This checking is only done the first time you call.":GOSUB 13000 700 S$=" "+N$+" "+O$+" "+ST$:RL=62:GOSUB 14000:NU=NU+1:PUT#1,NU+1: S$=STR$(NU):GOSUB 14000:PUT#1,1:CLOSE 720 GOSUB 13000:OPEN "I",1,"A:NEWCOM":BK=0 740 IF EOF(1) OR BK THEN 760 ELSE LINE INPUT#1,A$:GOSUB 13000:GOTO 740 760 CLOSE:GOSUB 13000:MF$=" " 780 A$="Logging name to disk...":N=1:GOSUB 13000:OPEN "R",1,"A:CALLERS",60: FIELD#1,60 AS RR$:GET#1,1 800 RE=VAL(RR$)+1:S$=STR$(RE):RL=60:GOSUB 14000:PUT#1,1:RE=RE+1 820 S$=N$+" "+O$+" "+ST$:GOSUB 14000:PUT#1,RE:CLOSE#1 840 BK=0:GOSUB 13000:A$="Active # of msg's ":N=1:GOSUB 13000: OPEN "R",1,"A:COUNTERS",5:FIELD#1,5 AS RR$:GET#1,MSGS:M=VAL(RR$) 860 A$=STR$(M)+".":GOSUB 13000 880 A$="You are caller # ":N=1:GOSUB 13000:GET#1,CALLS 900 A$=STR$(VAL(RR$)+1):LSET RR$=A$:GOSUB 13000:PUT#1,CALLS 920 A$="Next msg # will be ":N=1:GOSUB 13000:GET#1,MNUM:U=VAL(RR$) 940 A$=STR$(U+1):GOSUB 13000:CLOSE:GOSUB 13000 1000 REM 1020 REM LOOK FOR MSGS FOR THIS CALLER 1030 REM AND BUILD MESSAGE INDEX 1040 REM 1060 FT=1:MX=0:MZ=0:'FLAG FIRST TIME FOR PRINTING HEADING 1080 OPEN "R",1,"A:SUMMARY",30:RE=1:FIELD#1,28 AS RR$ 1100 BK=0:GET#1,RE:IF EOF(1) THEN 1220 1120 G=VAL(RR$):MZ=MZ+1:M(MZ,1)=G:IF G=0 THEN 1200 1130 IF G>9998 THEN MZ=MZ-1:GOTO 1220 1140 GET#1,RE+3:GOSUB 14100:IF INSTR(S$,N$)>0 AND INSTR(S$,O$)>0 THEN 1160 1145 IF N$<>"SYSOP" THEN 1200 1150 IF INSTR(S$,"BRUCE")=0 THEN 1200 1160 IF FT THEN A$="Please retrieve and kill the following message(s) left for you:":GOSUB 13000:FT=0 1180 A$=STR$(G):N=1:GOSUB 13000 1200 GET#1,RE+5:M(MZ,2)=VAL(RR$):MX=MX+M(MZ,2)+6:RE=RE+6:GOTO 1100 1220 CLOSE:GOSUB 13000:GOSUB 13000 2000 REM 2020 REM *** MAIN COMMAND ACCEPTOR/DISPATCHER *** 2040 REM 2060 A$="Function B,E,R,S,K,G,W,C,U (or '?' if not known)?":GOSUB 13000: C=1:GOSUB 13200:C=0 2080 IF B$="" THEN 2000 2100 FF=INSTR("BER?SKGWCU",B$) 2120 IF FF=0 THEN 2160 2140 ON FF GOTO 4000,7000,9000,6000,10000,12000,11000,5000,3000,12500 2160 A$="I don't understand '"+B$+"', "+N$+".":GOSUB 13000:GOSUB 13000:GOTO 2000 3000 REM 3020 REM ***EXIT TO CP/M*** 3040 REM 3050 IF MF$="*" THEN A$="You've lost that privelege, "+N$:GOSUB 13000:GOTO 2000 3060 'A$="Password ?":GOSUB 13000:C=1:GOSUB 13200:C=0 3080 'IF B$<>"THERAT" THEN A$="+++INVALID+++":GOSUB 13000:GOSUB 13000:GOTO 2000 3100 A$="Please remember to type BYE before hanging up the phone.":GOSUB 13000:GOSUB 13000 3120 A$="To re-enter RIBBS, type:":GOSUB 13000: A$="A>USER 3":GOSUB 13000: A$="A>RIBBS":GOSUB 13000:GOSUB 13000 3140 A$="For info on software exchange, type:":GOSUB 13000: A$="A>MLIST THIS-SYS.DOC":GOSUB 13000:GOSUB 13000 3160 A$="For general info, type:":GOSUB 13000: A$="A>HELP":GOSUB 13000:GOSUB 13000 3280 POKE 4,0:A$="Entering CP/M...":GOSUB 13000:POKE 0,&HC3:SYSTEM 4000 REM 4020 REM ***DISPLAY BULLETINS*** 4040 REM 4060 GOSUB 13000:A$="Use ctl-K to abort, ctl-S to pause.":GOSUB 13000 4080 OPEN "I",1,"A:BULLETIN" 4100 IF EOF(1) OR BK THEN 4120 ELSE LINE INPUT#1,A$:GOSUB 13000:GOTO 4100 4120 GOSUB 13000:CLOSE#1:GOTO 2000 5000 REM 5020 REM ***DISPLAY WELCOME MESSAGE*** 5040 REM 5060 GOSUB 13000:A$="Use ctl-K to abort, ctl-S to pause.":GOSUB 13000 5080 OPEN "I",1,"A:INFO" 5100 IF EOF(1) OR BK THEN 5120 ELSE LINE INPUT#1,A$:GOSUB 13000:B=0:GOTO 5100 5120 CLOSE#1:GOSUB 13000:GOTO 2000 6000 REM 6020 REM *** DISPLAY MENU OF FUNCTIONS *** 6040 REM 6060 GOSUB 13000:A$="Functions supported:":GOSUB 13000:IF BK THEN 2000 6080 A$="S--> Scan messages R--> Retrieve message":GOSUB 13000:IF BK THEN 2000 6100 A$="E--> Enter message K--> Kill message":GOSUB 13000:IF BK THEN 2000 6120 A$="B--> retype Bulletins W--> retype Welcome":GOSUB 13000:IF BK THEN 2000 6140 A$="C--> exit to CP/M U--> list User file":GOSUB 13000:IF BK THEN 2000 6160 A$="G--> Goodbye (signoff)":GOSUB 13000:IF BK THEN 2000 6180 GOSUB 13000:A$="Software exchange is done under CP/M using":GOSUB 13000: A$="the XMODEM program (for intelligent transfer)":GOSUB 13000: A$="or the MLIST program (simple ASCII listing).":GOSUB 13000 6190 IF BK THEN 2000 6200 GOSUB 13000:A$="BASIC programs are stored in binary and must":GOSUB 13000: A$="be listed using MBASIC instead of MLIST.":GOSUB 13000 6210 IF BK THEN 2000 6280 GOSUB 13000:GOTO 2000 7000 REM 7020 REM ***ENTER A NEW MESSAGE*** 7040 REM 7060 F=0:GOSUB 13000:OPEN "R",1,"A:COUNTERS",5:A$="Msg # will be ":N=1: GOSUB 13000:FIELD#1,5 AS RR$:GET#1,MNUM:V=VAL(RR$) 7080 A$=STR$(V+1):GOSUB 13000:CLOSE 7100 A$="To enter msg, type in lines.":GOSUB 13000:A$="To edit, hit blank C/R.":GOSUB 13000:GOSUB 13000:F=0 7120 IF F=16 THEN A$="Msg full.":GOSUB 13000:GOTO 7180 7140 F=F+1:A$=STR$(F)+" ":N=1:GOSUB 13000:GOSUB 13200:IF B$="" THEN F=F-1:GOTO 7180 7160 A$(F)=B$+" ":GOTO 7120 7180 GOSUB 13000:A$="(L)ist, (E)dit, (Q)uit, (C)ontinue, (S)ave; Select?":GOSUB 13000:C=1:GOSUB 13200:C=0 7200 IF B$<>"L" THEN 7280 ELSE A$="Use ctl-K to abort, ctl-S to pause.":GOSUB 13000 7220 GOSUB 13000:FOR L=1 TO F:A$=STR$(L)+" "+A$(L) 7240 IF BK THEN 7180 ELSE GOSUB 13000:NEXT L 7260 GOSUB 13000:GOTO 7180 7280 IF B$="Q" THEN A$="Aborted":GOSUB 13000:GOTO 2000 7300 IF B$="C" THEN 7120 7320 IF B$="E" THEN 7380 7340 IF B$="S" THEN 7460 7360 GOTO 7180 7380 GOSUB 13000:A$="Line #?":GOSUB 13000:GOSUB 13200:L=VAL(B$) 7400 IF L=0 OR L>F THEN 7180 ELSE A$="Was:":GOSUB 13000:A$=A$(L):GOSUB 13000 7420 A$="Enter new line (C/R for no change):":GOSUB 13000:GOSUB 13200 7440 IF B$="" THEN 7180 ELSE A$(L)=B$+" ":GOTO 7180 7460 GOSUB 13000:A$="Todays date (MM/DD/YY)?":GOSUB 13000:GOSUB 13200:D$=B$ 7480 A$="Who to (C/R for ALL)?":GOSUB 13000:C=1:GOSUB 13200:C=0:IF B$="" THEN T$="ALL" ELSE T$=B$ 7500 A$="Subject?":GOSUB 13000:C=1:GOSUB 13200:C=0:K$=B$: A$="Password ?":GOSUB 13000:C=1:GOSUB 13200:C=0:PW$=B$: A$="Want to make any changes (Y/N)?":GOSUB 13000:C=1:GOSUB 13200:C=0: IF LEFT$(B$,1)="Y" THEN 7180 7510 IF PW$<>"" THEN PW$=";"+PW$ 7520 A$="Updating summary file, ":N=1:GOSUB 13000 7540 OPEN "R",1,"A:SUMMARY",30:RE=1:FIELD#1,30 AS RR$:RL=30 7620 RE=MZ*6+1:S$=STR$(V+1)+PW$:GOSUB 14000:PUT#1,RE 7640 RE=RE+1:S$=D$:GOSUB 14000:PUT#1,RE 7660 RE=RE+1:S$=N$+" "+O$:GOSUB 14000:PUT#1,RE 7680 RE=RE+1:S$=T$:GOSUB 14000:PUT#1,RE 7700 RE=RE+1:S$=K$:GOSUB 14000:PUT#1,RE 7720 RE=RE+1:S$=STR$(F):GOSUB 14000:PUT#1,RE 7730 RE=RE+1:S$=" 9999":GOSUB 14000:PUT#1,RE 7740 CLOSE#1 7760 A$="next msg #, ":N=1:GOSUB 13000: OPEN "R",1,"A:COUNTERS",5:FIELD#1,5 AS RR$ 7780 GET#1,MNUM:LSET RR$=STR$(VAL(RR$)+1):PUT#1,MNUM 7800 A$="active msg's, ":N=1:GOSUB 13000 7820 GET#1,MSGS:LSET RR$=STR$(VAL(RR$)+1):PUT#1,MSGS:CLOSE#1 7840 A$="and msg file.":N=1:GOSUB 13000:OPEN "R",1,"A:MESSAGES",65:RL=65 7860 FIELD#1,65 AS RR$ 7880 RE=MX+1 7960 S$=STR$(V+1):GOSUB 14000:PUT#1,RE 7980 RE=RE+1:S$=D$:GOSUB 14000:PUT#1,RE 8000 RE=RE+1:S$=N$+" "+O$:GOSUB 14000:PUT#1,RE 8020 RE=RE+1:S$=T$:GOSUB 14000:PUT#1,RE 8040 RE=RE+1:S$=K$:GOSUB 14000:PUT#1,RE 8060 RE=RE+1:S$=STR$(F):GOSUB 14000:PUT#1,RE 8080 RE=RE+1 8100 FOR P=1 TO F:S$=A$(P):GOSUB 14000:PUT#1,RE:RE=RE+1:NEXT P: S$=" 9999":GOSUB 14000:PUT#1,RE:CLOSE#1:MX=MX+F+6:MZ=MZ+1: M(MZ,1)=V+1:M(MZ,2)=F 8120 GOSUB 13000:GOSUB 13000:U=U+1:GOTO 2000 9000 REM 9020 REM ***RETRIEVE MESSAGE*** 9040 REM 9060 GOSUB 13000:A$="Msg # to retrieve (C/R to end)?":GOSUB 13000:GOSUB 13200:GOSUB 13000 9080 IF LEN(B$)=0 THEN M=0 ELSE M=VAL(B$) 9100 IF M<1 THEN GOSUB 13000:GOTO 2000 9120 IF M>U THEN A$="There aren't that many msg's, "+N$+".":GOSUB 13000:GOTO 9060 9140 A$="Use ctl-K to abort, ctl-S to pause.":GOSUB 13000:GOSUB 13000 9160 OPEN "R",1,"A:MESSAGES",65:RE=1:FIELD#1,63 AS RR$:MI=0 9180 MI=MI+1:IF (MI>MZ) OR BK THEN 9540 ELSE G=M(MI,1) 9200 IF GM THEN 9460 9260 RE=RE+1:GET#1,RE:GOSUB 14100:D$=S$ 9280 RE=RE+1:GET#1,RE:GOSUB 14100:NO$=S$ 9300 RE=RE+1:GET#1,RE:GOSUB 14100:T$=S$ 9320 RE=RE+1:GET#1,RE:GOSUB 14100:K$=S$ 9340 RE=RE+1:GET#1,RE:J=VAL(RR$):GOSUB 13000 9360 A$="Msg #"+STR$(G)+" was entered on date "+D$+" from "+NO$:GOSUB 13000 9380 A$="To "+T$+" about "+K$:GOSUB 13000:GOSUB 13000 9400 RE=RE+1:FOR P=1 TO J:GET#1,RE:GOSUB 14100:A$=S$:GOSUB 13000 9420 IF BK THEN 9540 9440 RE=RE+1:NEXT P:GOSUB 13000 9460 IF INSTR(B$,";") THEN B$=MID$(B$,INSTR(B$,";")+1): M=VAL(B$):RE=1:IF M>0 THEN MI=0:GOTO 9180 9480 IF RIGHT$(B$,1)<>"+" THEN CLOSE:GOTO 9020 9500 M=M+1:MI=0:RE=1 9520 IF M<=U AND NOT BK THEN 9180 9540 CLOSE:A$="End of msg's.":GOSUB 13000:GOSUB 13000:D$="":NO$="":GOTO 2000 10000 REM 10020 REM ***SUMMARIZE MESSAGES*** 10040 REM 10060 A$="Selective scan ?":GOSUB 13000:C=1:GOSUB 13200:C=0:B$=LEFT$(B$,1): IF B$<>"Y" THEN ST=0:GOTO 10140 10080 A$="(F)rom, (T)o, or (S)ubject ?":GOSUB 13000:C=1:GOSUB 13200:C=0: B$=LEFT$(B$,1):ST=INSTR("FTS",B$):IF ST=0 THEN 2000 10100 A$="Search string ?":GOSUB 13000:C=1:GOSUB 13200:C=0:SV$=B$: IF SV$="" THEN 2000 10120 M=1:GOTO 10240 10140 GOSUB 13000:A$="Msg # to start (C/R to end)?":GOSUB 13000:GOSUB 13200:GOSUB 13000 10160 IF LEN(B$)=0 THEN M=0 ELSE M=VAL(B$) 10180 GOSUB 13160 10200 IF M<1 THEN 2000 10220 IF M>U THEN A$="There aren't that many msg's, "+N$+".":GOSUB 13000:GOTO 10020 10240 A$="Use ctl-K to abort, ctl-S to pause.":GOSUB 13000:GOSUB 13000 10260 OPEN "R",1,"A:SUMMARY",30:RE=1:FIELD#1,28 AS RR$ 10280 GET#1,RE 10300 IF EOF(1) OR BK THEN 10660 ELSE G=VAL(RR$) 10310 IF G>9998 THEN 10660 10320 IF G"Y" THEN 11240 11100 OPEN "R",1,"A:COMMENTS",65:FIELD#1,65 AS RR$:GET#1,1:RE=VAL(RR$)+1:RL=65 11110 IF RE=1 THEN RE=2 11120 S$="From: "+N$+" "+O$:GOSUB 14000 11140 PUT#1,RE 11160 A$="Enter comments; to end, hit C/R.":GOSUB 13000 11180 A$="Ok>":N=1:GOSUB 13000:GOSUB 13200 11200 IF B$="" THEN 11220 ELSE RE=RE+1:S$=B$:RL=65:GOSUB 14000:PUT#1,RE:GOTO 11180 11220 S$=STR$(RE):RL=65:GOSUB 14000:PUT#1,1:CLOSE 11240 GOSUB 13000: A$="Character count: "+STR$(A)+" typed by system - "+STR$(D)+ " typed by you.":GOSUB 13000: A$="From Bruce: thanks for calling, "+N$+".":GOSUB 13000 11260 A$="***** End of connection ******":GOSUB 13000:GOSUB 13000:SYSTEM 12000 REM 12020 REM ***KILL A MESSAGE*** 12040 REM 12060 GOSUB 13000:A$="Message # to kill?":GOSUB 13000:GOSUB 13200 12080 IF LEN(B$)=0 THEN M=0 ELSE M=VAL(B$) 12100 IF M<1 THEN GOSUB 13000:GOTO 2000 12120 IF M>U THEN A$="There aren't that many msg's, "+N$+".":GOSUB 13000:GOTO 12040 12140 A$="Scanning summary file...":GOSUB 13000: OPEN "R",1,"A:SUMMARY",30:RE=1:FIELD#1,30 AS RR$:RL=30 12160 GET#1,RE 12180 IF EOF(1) THEN 12420 ELSE G=VAL(RR$) 12190 IF G>9998 THEN 12420 12200 IF GM THEN 12420 ELSE GOSUB 14100:PW=INSTR(S$,";"):PW$="": IF PW=0 OR N$+O$="SYSOP" THEN 12230 ELSE PW$=MID$(S$,PW+1) 12225 A$="Password ?":GOSUB 13000:C=1:GOSUB 13200:C=0: IF B$<>PW$ THEN A$="Incorrect.":GOSUB 13000:GOSUB 13000:CLOSE:GOTO 2000 12230 S$=" 0":GOSUB 14000:PUT#1,RE:CLOSE 12240 A$="Updating message file...":GOSUB 13000 12260 OPEN "R",1,"A:MESSAGES",65:RE=1:FIELD#1,65 AS RR$:MI=0 12280 MI=MI+1:IF MI>MZ THEN 12420 ELSE G=M(MI,1) 12300 IF G"*" THEN GOSUB 14100:A$=S$:GOSUB 13000 12620 IF BK THEN 12660 12640 NEXT I 12660 CLOSE:GOSUB 13000:GOTO 2000 13000 REM 13020 REM ***PRINT STRING FROM A$ ON CONSOLE*** 13040 REM 13060 IF RIGHT$(A$,1)="?" OR N=1 THEN PRINT A$;:PP$=A$:GOTO 13140 13080 BI=ASC(INKEY$+" "):IF BI=19 THEN BI=ASC(INPUT$(1)) 13100 IF BI=11 THEN BK=-1:GOTO 13160 ELSE PRINT A$ 13140 A=A+LEN(A$) 13150 IF N$+O$="SYSOP" AND INP(255)=1 THEN LPRINT A$;: IF N=0 AND RIGHT$(A$,1)<>"?" THEN LPRINT 13160 A$="":N=0 13180 RETURN 13200 REM 13220 REM ***ACCEPT STRING INTO B$ FROM CONSOLE*** 13240 REM 13260 PRINT CHR$(7);:B$="":BK=0 13280 LINE INPUT B$:IF LEN(B$)=0 THEN RETURN 13300 IF C=0 THEN 13340 13320 FOR ZZ=1 TO LEN(B$):MID$(B$,ZZ,1)=CHR$(ASC(MID$(B$,ZZ,1))+32*(ASC(MID$(B$,ZZ,1))>96)):NEXT ZZ 13340 IF LEN(B$)<63 THEN 13440 13360 A$="Input line too long - would be truncated to:":GOSUB 13000 13380 B$=LEFT$(B$,62):PRINT B$ 13400 LINE INPUT "Retype line (Y/N)?";QQ$:QQ$=LEFT$(QQ$,1) 13420 IF QQ$="Y" OR QQ$="y" THEN PRINT PP$;:GOTO 13200 13440 D=D+LEN(B$):RETURN 13500 REM 13520 REM ***ON ERROR HANDLER*** 13540 REM 13560 IF ERL=400 THEN RESUME 440 13580 IF ERL=440 THEN RESUME 480 13600 IF ERL=720 THEN RESUME 760 13620 IF ERL=4080 THEN RESUME 4120 13640 IF ERL=5080 THEN RESUME 5120 13660 IF ERL=780 THEN RE=0:RESUME 800 13680 IF ERL=840 THEN M=0:RESUME 860 13700 IF ERL=880 THEN C=0:RESUME 900 13720 IF ERL=920 THEN U=0:RESUME 940 13740 IF ERL=7060 THEN V=0:RESUME 7080 13760 IF ERL=7760 THEN C=0:RESUME 7780 13780 IF ERL=7800 THEN C=0:RESUME 7820 13800 RESUME NEXT 14000 REM 14020 REM FILL AND STORE DISK RECORD 14040 REM 14060 LSET RR$=LEFT$(S$+SPACE$(RL-2),RL-2)+CHR$(13)+CHR$(10) 14080 RETURN 14100 REM 14120 REM UNPACK DISK RECORD 14140 REM 14160 ZZ=LEN(RR$)-2 14180 WHILE MID$(RR$,ZZ,1)=" " 14200 ZZ=ZZ-1:IF ZZ=1 THEN 14240 14220 WEND 14240 S$=LEFT$(RR$,ZZ) 14260 RETURN 14280 END