From 1d848aed9812455c89898dfe79a3d8d4645b2f78 Mon Sep 17 00:00:00 2001 From: "R. Eric Wheeler" Date: Tue, 21 Jun 2022 17:11:35 -0700 Subject: [PATCH] Reset --- .gitignore | 2 + BPC.CFG | 27 + BUILDBP.CMD | 48 + BUILDVP.CMD | 48 + COMPILE.TXT | 55 + COPYEXEBP.CMD | 7 + COPYEXEVP.CMD | 6 + README.md | 29 +- SOURCE/ARCHIVE1.PAS | 723 +++++ SOURCE/ARCHIVE2.PAS | 919 ++++++ SOURCE/ARCHIVE3.PAS | 244 ++ SOURCE/ARCVIEW.PAS | 852 ++++++ SOURCE/AUTOMSG.PAS | 163 ++ SOURCE/BBSLIST.PAS | 779 +++++ SOURCE/BOOT.PAS | 1078 +++++++ SOURCE/BULLETIN.PAS | 592 ++++ SOURCE/COMMON.PAS | 5076 +++++++++++++++++++++++++++++++++ SOURCE/COMMON1.PAS | 414 +++ SOURCE/COMMON2.PAS | 1313 +++++++++ SOURCE/COMMON3.PAS | 545 ++++ SOURCE/COMMON4.PAS | 1051 +++++++ SOURCE/COMMON5.PAS | 533 ++++ SOURCE/CUSER.PAS | 1029 +++++++ SOURCE/DOORS.PAS | 772 +++++ SOURCE/ELECOM/BUFUNIT.PAS | 140 + SOURCE/ELECOM/COMBASE.PAS | 309 ++ SOURCE/ELECOM/ELECOM13.PAS | 350 +++ SOURCE/ELECOM/ELEDEF.PAS | 101 + SOURCE/ELECOM/ELENORM.PAS | 376 +++ SOURCE/ELECOM/EXAM2.PAS | 150 + SOURCE/ELECOM/FOS_COM.PAS | 550 ++++ SOURCE/ELECOM/HISTORY.102 | 19 + SOURCE/ELECOM/HISTORY.103 | 24 + SOURCE/ELECOM/IBMSO32.PAS | 113 + SOURCE/ELECOM/IBMTCP32.PAS | 53 + SOURCE/ELECOM/OS2COM.PAS | 786 +++++ SOURCE/ELECOM/PROCS.TXT | 109 + SOURCE/ELECOM/README.TXT | 17 + SOURCE/ELECOM/SOCKDEF.PAS | 606 ++++ SOURCE/ELECOM/SOCKFUNC.PAS | 831 ++++++ SOURCE/ELECOM/SOCKFUNC.RC | 92 + SOURCE/ELECOM/SOCKFUNC.RES | Bin 0 -> 2392 bytes SOURCE/ELECOM/TELNET.PAS | 863 ++++++ SOURCE/ELECOM/THREADS.PAS | 421 +++ SOURCE/ELECOM/W32SNGL.PAS | 824 ++++++ SOURCE/ELECOM/W32SOCK.PAS | 205 ++ SOURCE/ELECOM/WIN32COM.PAS | 790 +++++ SOURCE/ELECOM/WINDEF.FPC | 79 + SOURCE/ELECOM/dllexam.pas | 86 + SOURCE/ELECOM/example.pas | 181 ++ SOURCE/EMAIL.PAS | 1109 +++++++ SOURCE/EVENTS.PAS | 258 ++ SOURCE/EXECBAT.PAS | 229 ++ SOURCE/FILE0.PAS | 609 ++++ SOURCE/FILE1.PAS | 1588 +++++++++++ SOURCE/FILE10.PAS | 910 ++++++ SOURCE/FILE11.PAS | 1249 ++++++++ SOURCE/FILE12.PAS | 963 +++++++ SOURCE/FILE13.PAS | 128 + SOURCE/FILE14.PAS | 190 ++ SOURCE/FILE2.PAS | 125 + SOURCE/FILE3.PAS | 115 + SOURCE/FILE4.PAS | 251 ++ SOURCE/FILE5.PAS | 804 ++++++ SOURCE/FILE6.PAS | 995 +++++++ SOURCE/FILE7.PAS | 199 ++ SOURCE/FILE8.PAS | 607 ++++ SOURCE/FILE9.PAS | 420 +++ SOURCE/LINECHAT.PAS | 454 +++ SOURCE/LOGON.PAS | 1194 ++++++++ SOURCE/MAIL0.PAS | 895 ++++++ SOURCE/MAIL1.PAS | 2408 ++++++++++++++++ SOURCE/MAIL2.PAS | 1403 +++++++++ SOURCE/MAIL3.PAS | 477 ++++ SOURCE/MAIL4.PAS | 485 ++++ SOURCE/MAINT.PAS | 973 +++++++ SOURCE/MENUS.PAS | 1071 +++++++ SOURCE/MENUS2.PAS | 518 ++++ SOURCE/MENUS3.PAS | 97 + SOURCE/MISC/ONELE.ANS | 1 + SOURCE/MISC/ONELE.ASC | 1 + SOURCE/MISC/ONELH.ANS | 7 + SOURCE/MISC/ONELH.ASC | 12 + SOURCE/MISC/ONELM.ASC | 1 + SOURCE/MISCUSER.PAS | 266 ++ SOURCE/MSGPACK.PAS | 242 ++ SOURCE/MULTNODE.PAS | 1321 +++++++++ SOURCE/MYIO.PAS | 708 +++++ SOURCE/NEWUSERS.PAS | 284 ++ SOURCE/NODELIST.PAS | 652 +++++ SOURCE/OFFLINE.PAS | 1225 ++++++++ SOURCE/ONELINER.PAS | 320 +++ SOURCE/RECORDS.PAS | 1012 +++++++ SOURCE/RENEGADE.PAS | 578 ++++ SOURCE/RENEMAIL.PAS | 2218 ++++++++++++++ SOURCE/RGLNG.PAS | 927 ++++++ SOURCE/RGQUOTE.PAS | 103 + SOURCE/RPSCREEN.PAS | 157 + SOURCE/SCRIPT.PAS | 431 +++ SOURCE/SHORTMSG.PAS | 79 + SOURCE/SPAWNO.PAS | 59 + SOURCE/SPLITCHA.PAS | 1421 +++++++++ SOURCE/STATS.PAS | 457 +++ SOURCE/SYSOP1.PAS | 831 ++++++ SOURCE/SYSOP10.PAS | 746 +++++ SOURCE/SYSOP11.PAS | 77 + SOURCE/SYSOP12.PAS | 566 ++++ SOURCE/SYSOP2.PAS | 95 + SOURCE/SYSOP2A.PAS | 427 +++ SOURCE/SYSOP2B.PAS | 230 ++ SOURCE/SYSOP2C.PAS | 124 + SOURCE/SYSOP2D.PAS | 348 +++ SOURCE/SYSOP2E.PAS | 159 ++ SOURCE/SYSOP2F.PAS | 78 + SOURCE/SYSOP2G.PAS | 884 ++++++ SOURCE/SYSOP2H.PAS | 135 + SOURCE/SYSOP2I.PAS | 61 + SOURCE/SYSOP2J.PAS | 823 ++++++ SOURCE/SYSOP2K.PAS | 363 +++ SOURCE/SYSOP2L.PAS | 48 + SOURCE/SYSOP2M.PAS | 134 + SOURCE/SYSOP2O.PAS | 98 + SOURCE/SYSOP3.PAS | 1416 +++++++++ SOURCE/SYSOP4.PAS | 563 ++++ SOURCE/SYSOP5.PAS | 553 ++++ SOURCE/SYSOP6.PAS | 1001 +++++++ SOURCE/SYSOP7.PAS | 665 +++++ SOURCE/SYSOP7M.PAS | 488 ++++ SOURCE/SYSOP8.PAS | 1135 ++++++++ SOURCE/SYSOP9.PAS | 1266 ++++++++ SOURCE/TAGLINE.PAS | 105 + SOURCE/TIMEBANK.PAS | 215 ++ SOURCE/TIMEFUNC.PAS | 393 +++ SOURCE/UNUSED/ACFLAGS.ASC | 14 + SOURCE/UNUSED/ARCHIVE1.TPU | Bin 0 -> 24832 bytes SOURCE/UNUSED/ARCHIVE2.TPU | Bin 0 -> 29792 bytes SOURCE/UNUSED/ARCHIVE3.TPU | Bin 0 -> 6880 bytes SOURCE/UNUSED/ARCVIEW.TPU | Bin 0 -> 23456 bytes SOURCE/UNUSED/AUTOMSG.TPU | Bin 0 -> 5840 bytes SOURCE/UNUSED/BATCH6.LST | 1 + SOURCE/UNUSED/BBSLIST.TPU | Bin 0 -> 12576 bytes SOURCE/UNUSED/BOOT.TPU | Bin 0 -> 34208 bytes SOURCE/UNUSED/BULLETIN.TPU | Bin 0 -> 15232 bytes SOURCE/UNUSED/CHAIN.TXT | 32 + SOURCE/UNUSED/CHAINT~1.TXT | 33 + SOURCE/UNUSED/CHANGE.TXT | 212 ++ SOURCE/UNUSED/CHANGE1.TXT | 27 + SOURCE/UNUSED/CHANGE10.TXT | 53 + SOURCE/UNUSED/CHANGE11.TXT | 28 + SOURCE/UNUSED/CHANGE12.TXT | 28 + SOURCE/UNUSED/CHANGE13.TXT | 5 + SOURCE/UNUSED/CHANGE14.TXT | 29 + SOURCE/UNUSED/CHANGE2.TXT | 8 + SOURCE/UNUSED/CHANGE3.TXT | 7 + SOURCE/UNUSED/CHANGE4.TXT | 70 + SOURCE/UNUSED/CHANGE5.TXT | 42 + SOURCE/UNUSED/CHANGE6.TXT | 70 + SOURCE/UNUSED/CHANGE7.TXT | 75 + SOURCE/UNUSED/CHANGE8.TXT | 25 + SOURCE/UNUSED/CHANGE9.TXT | 33 + SOURCE/UNUSED/CHANGES.TXT | 38 + SOURCE/UNUSED/CHANGES1.TXT | 44 + SOURCE/UNUSED/CHANGES2.TXT | 57 + SOURCE/UNUSED/CHANGES3.TXT | 18 + SOURCE/UNUSED/CHANGES4.TXT | 133 + SOURCE/UNUSED/CHANGES7.TXT | 42 + SOURCE/UNUSED/CHANGES8.TXT | 35 + SOURCE/UNUSED/CHANGES9.TXT | 29 + SOURCE/UNUSED/CHNAGE2.TXT | 27 + SOURCE/UNUSED/COMMON.TPU | Bin 0 -> 125632 bytes SOURCE/UNUSED/COMMON1.TPU | Bin 0 -> 10976 bytes SOURCE/UNUSED/COMMON2.TPU | Bin 0 -> 36976 bytes SOURCE/UNUSED/COMMON3.TPU | Bin 0 -> 17152 bytes SOURCE/UNUSED/COMMON4.TPU | Bin 0 -> 4656 bytes SOURCE/UNUSED/COMMON5.TPU | Bin 0 -> 15808 bytes SOURCE/UNUSED/CRC32.ASM | 193 ++ SOURCE/UNUSED/CRC32A.PAS | 132 + SOURCE/UNUSED/CUSER.TPU | Bin 0 -> 30704 bytes SOURCE/UNUSED/DEZIP.PAS | 1192 ++++++++ SOURCE/UNUSED/DOOR.SYS | 52 + SOURCE/UNUSED/DOOR32.SYS | 11 + SOURCE/UNUSED/DOOR32~1.TXT | 121 + SOURCE/UNUSED/DOORS.TPU | Bin 0 -> 29264 bytes SOURCE/UNUSED/DOORSY~1.DOC | Bin 0 -> 3551 bytes SOURCE/UNUSED/DORINFO1.DEF | 13 + SOURCE/UNUSED/DORINF~1.TXT | 29 + SOURCE/UNUSED/DRAG_010.PAS | 1333 +++++++++ SOURCE/UNUSED/EC.PAS | 55 + SOURCE/UNUSED/EC.TXT | 2 + SOURCE/UNUSED/EMAIL.TPU | Bin 0 -> 33248 bytes SOURCE/UNUSED/ERROR.LOG | 33 + SOURCE/UNUSED/EVENT.PAS | 248 ++ SOURCE/UNUSED/EVENT.TPU | Bin 0 -> 4448 bytes SOURCE/UNUSED/EVENTS.TPU | Bin 0 -> 4224 bytes SOURCE/UNUSED/EXECBAT.TPU | Bin 0 -> 6048 bytes SOURCE/UNUSED/FAELNG.EXE | Bin 0 -> 23184 bytes SOURCE/UNUSED/FAELNG.PAS | 267 ++ SOURCE/UNUSED/FAELNG.TXT | 312 ++ SOURCE/UNUSED/FAEPR.DAT | Bin 0 -> 568 bytes SOURCE/UNUSED/FAETX.DAT | 1 + SOURCE/UNUSED/FILE0.TPU | Bin 0 -> 21504 bytes SOURCE/UNUSED/FILE1.TPU | Bin 0 -> 46448 bytes SOURCE/UNUSED/FILE10.LEE | 835 ++++++ SOURCE/UNUSED/FILE10.TPU | Bin 0 -> 29008 bytes SOURCE/UNUSED/FILE11.TPU | Bin 0 -> 35776 bytes SOURCE/UNUSED/FILE12.TPU | Bin 0 -> 35120 bytes SOURCE/UNUSED/FILE13.TPU | Bin 0 -> 4016 bytes SOURCE/UNUSED/FILE14.TPU | Bin 0 -> 7728 bytes SOURCE/UNUSED/FILE2.TPU | Bin 0 -> 4048 bytes SOURCE/UNUSED/FILE3.TPU | Bin 0 -> 3456 bytes SOURCE/UNUSED/FILE4.TPU | Bin 0 -> 6928 bytes SOURCE/UNUSED/FILE5.TPU | Bin 0 -> 25728 bytes SOURCE/UNUSED/FILE6.TPU | Bin 0 -> 38384 bytes SOURCE/UNUSED/FILE7.TPU | Bin 0 -> 5968 bytes SOURCE/UNUSED/FILE8.TPU | Bin 0 -> 21904 bytes SOURCE/UNUSED/FILE9.TPU | Bin 0 -> 12368 bytes SOURCE/UNUSED/FILES.BBS | 63 + SOURCE/UNUSED/FSHELP.ASC | 10 + SOURCE/UNUSED/FSTR.PAS | 136 + SOURCE/UNUSED/FTS-0001.016 | 1239 ++++++++ SOURCE/UNUSED/GREP.COM | Bin 0 -> 7023 bytes SOURCE/UNUSED/INSTALL.EXE | Bin 0 -> 10304 bytes SOURCE/UNUSED/INSTALL.PAS | 201 ++ SOURCE/UNUSED/IS286.PAS | 33 + SOURCE/UNUSED/LEE.EXE | Bin 0 -> 2976 bytes SOURCE/UNUSED/LEE.PAS | 17 + SOURCE/UNUSED/LEE.TXT | 35 + SOURCE/UNUSED/LGNQUOTE.DAT | 5 + SOURCE/UNUSED/LGNQUOTE.PTR | Bin 0 -> 1448 bytes SOURCE/UNUSED/LGNQUOTE.TXT | 1205 ++++++++ SOURCE/UNUSED/LINECHAT.TPU | Bin 0 -> 11632 bytes SOURCE/UNUSED/LOGON.BAT | 18 + SOURCE/UNUSED/LOGON.TPU | Bin 0 -> 31952 bytes SOURCE/UNUSED/MAIL0.TPU | Bin 0 -> 34000 bytes SOURCE/UNUSED/MAIL1.LEE | 2345 +++++++++++++++ SOURCE/UNUSED/MAIL1.TPU | Bin 0 -> 62864 bytes SOURCE/UNUSED/MAIL2.TPU | Bin 0 -> 37328 bytes SOURCE/UNUSED/MAIL3.TPU | Bin 0 -> 14672 bytes SOURCE/UNUSED/MAIL4.TPU | Bin 0 -> 9936 bytes SOURCE/UNUSED/MAIL5.PAS | 1160 ++++++++ SOURCE/UNUSED/MAIL5.TPU | Bin 0 -> 35536 bytes SOURCE/UNUSED/MAIL6.PAS | 583 ++++ SOURCE/UNUSED/MAIL6.TPU | Bin 0 -> 15488 bytes SOURCE/UNUSED/MAIL7.PAS | 165 ++ SOURCE/UNUSED/MAIL7.TPU | Bin 0 -> 4160 bytes SOURCE/UNUSED/MAINT.TPU | Bin 0 -> 31680 bytes SOURCE/UNUSED/MARRIAGE.DAT | Bin 0 -> 6974 bytes SOURCE/UNUSED/MARRIAGE.PTR | Bin 0 -> 336 bytes SOURCE/UNUSED/MARRIAGE.TXT | 364 +++ SOURCE/UNUSED/MENUS.TPU | Bin 0 -> 26032 bytes SOURCE/UNUSED/MENUS2.TPU | Bin 0 -> 17584 bytes SOURCE/UNUSED/MENUS3.TPU | Bin 0 -> 2352 bytes SOURCE/UNUSED/MENUS4.PAS | 50 + SOURCE/UNUSED/MENUS4.TPU | Bin 0 -> 1504 bytes SOURCE/UNUSED/MISCCHAT.PAS | 184 ++ SOURCE/UNUSED/MISCUSER.TPU | Bin 0 -> 7184 bytes SOURCE/UNUSED/MSGPACK.TPU | Bin 0 -> 4528 bytes SOURCE/UNUSED/MSGQUOTE.DAT | 1 + SOURCE/UNUSED/MSGQUOTE.PTR | Bin 0 -> 72 bytes SOURCE/UNUSED/MSGQUOTE.TXT | 37 + SOURCE/UNUSED/MULT.PAS | 73 + SOURCE/UNUSED/MULTNODE.TPU | Bin 0 -> 31744 bytes SOURCE/UNUSED/MYIO.TPU | Bin 0 -> 14784 bytes SOURCE/UNUSED/NEWMCI.TXT | 40 + SOURCE/UNUSED/NEWUSERS.TPU | Bin 0 -> 7328 bytes SOURCE/UNUSED/NODELIST.TPU | Bin 0 -> 12448 bytes SOURCE/UNUSED/NONAME00.EXE | Bin 0 -> 16000 bytes SOURCE/UNUSED/OFFLINE.TPU | Bin 0 -> 37856 bytes SOURCE/UNUSED/OVRUMB.DOC | 220 ++ SOURCE/UNUSED/OVRUMB.PAS | 224 ++ SOURCE/UNUSED/OVRUMB.TPU | Bin 0 -> 2704 bytes SOURCE/UNUSED/PCBOAR~1.TXT | 57 + SOURCE/UNUSED/PKUNZIP.EXE | Bin 0 -> 34583 bytes SOURCE/UNUSED/PKZIP.EXE | Bin 0 -> 42166 bytes SOURCE/UNUSED/PRHELP.ASC | 14 + SOURCE/UNUSED/RENEGADE.DAT | Bin 0 -> 11392 bytes SOURCE/UNUSED/RENEGADE.EXE | Bin 0 -> 114784 bytes SOURCE/UNUSED/RENEGADE.LNG | 283 ++ SOURCE/UNUSED/RENEGADE.OVR | Bin 0 -> 743276 bytes SOURCE/UNUSED/RENEGADE.PIF | Bin 0 -> 2405 bytes SOURCE/UNUSED/RENEGADE.TPH | Bin 0 -> 150106 bytes SOURCE/UNUSED/RENEMAIL.EXE | Bin 0 -> 47456 bytes SOURCE/UNUSED/RENEMAIL.TPH | Bin 0 -> 2324 bytes SOURCE/UNUSED/REUPDATE.PAS | 1 + SOURCE/UNUSED/RGAPI.PAS | 1335 +++++++++ SOURCE/UNUSED/RGFLIST.PAS | 55 + SOURCE/UNUSED/RGINTRO.ANS | 19 + SOURCE/UNUSED/RGLNG.EXE | Bin 0 -> 28272 bytes SOURCE/UNUSED/RGLNG.TXT | 424 +++ SOURCE/UNUSED/RGLNGNEW.TXT | 288 ++ SOURCE/UNUSED/RGLNGPR.DAT | Bin 0 -> 760 bytes SOURCE/UNUSED/RGLNGTX.DAT | Bin 0 -> 6167 bytes SOURCE/UNUSED/RGMAIN.EXE | Bin 0 -> 7424 bytes SOURCE/UNUSED/RGMAIN.PAS | 122 + SOURCE/UNUSED/RGMAIN.TXT | 46 + SOURCE/UNUSED/RGMAINPR.DAT | Bin 0 -> 88 bytes SOURCE/UNUSED/RGMAINT.EXE | Bin 0 -> 14688 bytes SOURCE/UNUSED/RGMAINT.PAS | 1566 ++++++++++ SOURCE/UNUSED/RGMAINT1.PAS | 1584 ++++++++++ SOURCE/UNUSED/RGMAINT2.PAS | 1584 ++++++++++ SOURCE/UNUSED/RGMAINTX.DAT | Bin 0 -> 461 bytes SOURCE/UNUSED/RGNOTE.EXE | Bin 0 -> 9552 bytes SOURCE/UNUSED/RGNOTE.PAS | 190 ++ SOURCE/UNUSED/RGNOTE.TXT | 181 ++ SOURCE/UNUSED/RGNOTEPR.DAT | Bin 0 -> 352 bytes SOURCE/UNUSED/RGNOTETX.DAT | Bin 0 -> 1604 bytes SOURCE/UNUSED/RGQUOTE.EXE | Bin 0 -> 7344 bytes SOURCE/UNUSED/RGSCFG.EXE | Bin 0 -> 9424 bytes SOURCE/UNUSED/RGSCFG.PAS | 169 ++ SOURCE/UNUSED/RGSCFG.TXT | 187 ++ SOURCE/UNUSED/RGSCFGPR.DAT | Bin 0 -> 272 bytes SOURCE/UNUSED/RGSCFGTX.DAT | Bin 0 -> 3551 bytes SOURCE/UNUSED/RGSTAT.PAS | 1419 +++++++++ SOURCE/UNUSED/RGUPDATE.EXE | Bin 0 -> 12912 bytes SOURCE/UNUSED/RGUPDATE.PAS | 843 ++++++ SOURCE/UNUSED/RGUPDT1.EXE | Bin 0 -> 13008 bytes SOURCE/UNUSED/RGUPDT1.PAS | 776 +++++ SOURCE/UNUSED/RGUPDT2.EXE | Bin 0 -> 7216 bytes SOURCE/UNUSED/RGUPDT2.PAS | 161 ++ SOURCE/UNUSED/RGUPDT3.EXE | Bin 0 -> 8512 bytes SOURCE/UNUSED/RGUPDT3.PAS | 222 ++ SOURCE/UNUSED/RGUPDT4.PAS | 126 + SOURCE/UNUSED/RGV118.EXE | Bin 0 -> 12912 bytes SOURCE/UNUSED/RGV118.PAS | 843 ++++++ SOURCE/UNUSED/RGVER.EXE | Bin 0 -> 17744 bytes SOURCE/UNUSED/RGVER.PAS | 95 + SOURCE/UNUSED/RGVERUDT.EXE | Bin 0 -> 18624 bytes SOURCE/UNUSED/RGVERUDT.PAS | 94 + SOURCE/UNUSED/RMAILWKS.PAS | 953 +++++++ SOURCE/UNUSED/RMCHANGE.DOC | 3 + SOURCE/UNUSED/RMUPDATE.DOC | 13 + SOURCE/UNUSED/SCRIPT.TPU | Bin 0 -> 11248 bytes SOURCE/UNUSED/SHORTMSG.TPU | Bin 0 -> 2272 bytes SOURCE/UNUSED/SORTING.PAS | 157 + SOURCE/UNUSED/SPAWNO.TPU | Bin 0 -> 8096 bytes SOURCE/UNUSED/SPLITCHA.TPU | Bin 0 -> 10080 bytes SOURCE/UNUSED/STATS.TPU | Bin 0 -> 14560 bytes SOURCE/UNUSED/SYSCHAT.PAS | 664 +++++ SOURCE/UNUSED/SYSCHAT.TPU | Bin 0 -> 15152 bytes SOURCE/UNUSED/SYSOP1.TPU | Bin 0 -> 32608 bytes SOURCE/UNUSED/SYSOP10.TPU | Bin 0 -> 29440 bytes SOURCE/UNUSED/SYSOP11.TPU | Bin 0 -> 2928 bytes SOURCE/UNUSED/SYSOP12.TPU | Bin 0 -> 19824 bytes SOURCE/UNUSED/SYSOP2.TPU | Bin 0 -> 1680 bytes SOURCE/UNUSED/SYSOP2A.TPU | Bin 0 -> 7056 bytes SOURCE/UNUSED/SYSOP2B.TPU | Bin 0 -> 12592 bytes SOURCE/UNUSED/SYSOP2C.TPU | Bin 0 -> 5520 bytes SOURCE/UNUSED/SYSOP2D.TPU | Bin 0 -> 8720 bytes SOURCE/UNUSED/SYSOP2E.TPU | Bin 0 -> 6080 bytes SOURCE/UNUSED/SYSOP2F.TPU | Bin 0 -> 5024 bytes SOURCE/UNUSED/SYSOP2G.TPU | Bin 0 -> 37248 bytes SOURCE/UNUSED/SYSOP2H.TPU | Bin 0 -> 7216 bytes SOURCE/UNUSED/SYSOP2I.TPU | Bin 0 -> 2768 bytes SOURCE/UNUSED/SYSOP2J.TPU | Bin 0 -> 32400 bytes SOURCE/UNUSED/SYSOP2K.TPU | Bin 0 -> 14624 bytes SOURCE/UNUSED/SYSOP2L.TPU | Bin 0 -> 1936 bytes SOURCE/UNUSED/SYSOP2M.TPU | Bin 0 -> 4736 bytes SOURCE/UNUSED/SYSOP2O.TPU | Bin 0 -> 2272 bytes SOURCE/UNUSED/SYSOP3.TPU | Bin 0 -> 59264 bytes SOURCE/UNUSED/SYSOP4.TPU | Bin 0 -> 8160 bytes SOURCE/UNUSED/SYSOP5.TPU | Bin 0 -> 23728 bytes SOURCE/UNUSED/SYSOP6.TPU | Bin 0 -> 36352 bytes SOURCE/UNUSED/SYSOP6~1.PAS | 738 +++++ SOURCE/UNUSED/SYSOP7.TPU | Bin 0 -> 25616 bytes SOURCE/UNUSED/SYSOP7M.TPU | Bin 0 -> 19104 bytes SOURCE/UNUSED/SYSOP8.TPU | Bin 0 -> 46752 bytes SOURCE/UNUSED/SYSOP9.TPU | Bin 0 -> 34256 bytes SOURCE/UNUSED/TAGLINE.DAT | 1 + SOURCE/UNUSED/TAGLINE.EXE | Bin 0 -> 7424 bytes SOURCE/UNUSED/TAGLINE.PTR | Bin 0 -> 17472 bytes SOURCE/UNUSED/TAGLINE.TXT | 2184 ++++++++++++++ SOURCE/UNUSED/TAGSTAT.PAS | 1722 +++++++++++ SOURCE/UNUSED/TEMP6.BAT | 8 + SOURCE/UNUSED/TIMEBANK.TPU | Bin 0 -> 4672 bytes SOURCE/UNUSED/TIMEFUNC.TPU | Bin 0 -> 8048 bytes SOURCE/UNUSED/TPX.DSK | Bin 0 -> 1060 bytes SOURCE/UNUSED/TPX.TP | Bin 0 -> 4069 bytes SOURCE/UNUSED/TURBO.DSK | Bin 0 -> 1842 bytes SOURCE/UNUSED/USER.PAS | 328 +++ SOURCE/UNUSED/VOTE.TPU | Bin 0 -> 17616 bytes SOURCE/UNUSED/WD110107.TXT | 50 + SOURCE/UNUSED/WD110207.TXT | 6 + SOURCE/UNUSED/WD110307.TXT | 48 + SOURCE/UNUSED/WFCMENU.TPU | Bin 0 -> 34528 bytes SOURCE/UNUSED/WFCNEW1.ANS | 25 + SOURCE/UNUSED/WFC_COM.ANS | 25 + SOURCE/UNUSED/WFC_NODE.ANS | 25 + SOURCE/UNUSED/bootoldback.pas | 1034 +++++++ SOURCE/UNUSED/m.cmd | 1 + SOURCE/UPGRADE/BBSLEDT.ASC | 4 + SOURCE/UPGRADE/BBSLEH.ASC | 4 + SOURCE/UPGRADE/BBSLEM.ASC | 2 + SOURCE/UPGRADE/BBSLIST.SCR | 66 + SOURCE/UPGRADE/FIXBBSL.PAS | 217 ++ SOURCE/VOTE.PAS | 548 ++++ SOURCE/WFCMENU.PAS | 1364 +++++++++ SOURCE/WIN32/defines.inc | 7 + SOURCE/WIN32/overlay.pas | 9 + SOURCE/crc32.obj | Bin 0 -> 1259 bytes SOURCE/execwin.obj | Bin 0 -> 698 bytes SOURCE/spawntp.obj | Bin 0 -> 6308 bytes VPC.CFG | 25 + 402 files changed, 108979 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 BPC.CFG create mode 100644 BUILDBP.CMD create mode 100644 BUILDVP.CMD create mode 100644 COMPILE.TXT create mode 100644 COPYEXEBP.CMD create mode 100644 COPYEXEVP.CMD create mode 100644 SOURCE/ARCHIVE1.PAS create mode 100644 SOURCE/ARCHIVE2.PAS create mode 100644 SOURCE/ARCHIVE3.PAS create mode 100644 SOURCE/ARCVIEW.PAS create mode 100644 SOURCE/AUTOMSG.PAS create mode 100644 SOURCE/BBSLIST.PAS create mode 100644 SOURCE/BOOT.PAS create mode 100644 SOURCE/BULLETIN.PAS create mode 100644 SOURCE/COMMON.PAS create mode 100644 SOURCE/COMMON1.PAS create mode 100644 SOURCE/COMMON2.PAS create mode 100644 SOURCE/COMMON3.PAS create mode 100644 SOURCE/COMMON4.PAS create mode 100644 SOURCE/COMMON5.PAS create mode 100644 SOURCE/CUSER.PAS create mode 100644 SOURCE/DOORS.PAS create mode 100644 SOURCE/ELECOM/BUFUNIT.PAS create mode 100644 SOURCE/ELECOM/COMBASE.PAS create mode 100644 SOURCE/ELECOM/ELECOM13.PAS create mode 100644 SOURCE/ELECOM/ELEDEF.PAS create mode 100644 SOURCE/ELECOM/ELENORM.PAS create mode 100644 SOURCE/ELECOM/EXAM2.PAS create mode 100644 SOURCE/ELECOM/FOS_COM.PAS create mode 100644 SOURCE/ELECOM/HISTORY.102 create mode 100644 SOURCE/ELECOM/HISTORY.103 create mode 100644 SOURCE/ELECOM/IBMSO32.PAS create mode 100644 SOURCE/ELECOM/IBMTCP32.PAS create mode 100644 SOURCE/ELECOM/OS2COM.PAS create mode 100644 SOURCE/ELECOM/PROCS.TXT create mode 100644 SOURCE/ELECOM/README.TXT create mode 100644 SOURCE/ELECOM/SOCKDEF.PAS create mode 100644 SOURCE/ELECOM/SOCKFUNC.PAS create mode 100644 SOURCE/ELECOM/SOCKFUNC.RC create mode 100644 SOURCE/ELECOM/SOCKFUNC.RES create mode 100644 SOURCE/ELECOM/TELNET.PAS create mode 100644 SOURCE/ELECOM/THREADS.PAS create mode 100644 SOURCE/ELECOM/W32SNGL.PAS create mode 100644 SOURCE/ELECOM/W32SOCK.PAS create mode 100644 SOURCE/ELECOM/WIN32COM.PAS create mode 100644 SOURCE/ELECOM/WINDEF.FPC create mode 100644 SOURCE/ELECOM/dllexam.pas create mode 100644 SOURCE/ELECOM/example.pas create mode 100644 SOURCE/EMAIL.PAS create mode 100644 SOURCE/EVENTS.PAS create mode 100644 SOURCE/EXECBAT.PAS create mode 100644 SOURCE/FILE0.PAS create mode 100644 SOURCE/FILE1.PAS create mode 100644 SOURCE/FILE10.PAS create mode 100644 SOURCE/FILE11.PAS create mode 100644 SOURCE/FILE12.PAS create mode 100644 SOURCE/FILE13.PAS create mode 100644 SOURCE/FILE14.PAS create mode 100644 SOURCE/FILE2.PAS create mode 100644 SOURCE/FILE3.PAS create mode 100644 SOURCE/FILE4.PAS create mode 100644 SOURCE/FILE5.PAS create mode 100644 SOURCE/FILE6.PAS create mode 100644 SOURCE/FILE7.PAS create mode 100644 SOURCE/FILE8.PAS create mode 100644 SOURCE/FILE9.PAS create mode 100644 SOURCE/LINECHAT.PAS create mode 100644 SOURCE/LOGON.PAS create mode 100644 SOURCE/MAIL0.PAS create mode 100644 SOURCE/MAIL1.PAS create mode 100644 SOURCE/MAIL2.PAS create mode 100644 SOURCE/MAIL3.PAS create mode 100644 SOURCE/MAIL4.PAS create mode 100644 SOURCE/MAINT.PAS create mode 100644 SOURCE/MENUS.PAS create mode 100644 SOURCE/MENUS2.PAS create mode 100644 SOURCE/MENUS3.PAS create mode 100644 SOURCE/MISC/ONELE.ANS create mode 100644 SOURCE/MISC/ONELE.ASC create mode 100644 SOURCE/MISC/ONELH.ANS create mode 100644 SOURCE/MISC/ONELH.ASC create mode 100644 SOURCE/MISC/ONELM.ASC create mode 100644 SOURCE/MISCUSER.PAS create mode 100644 SOURCE/MSGPACK.PAS create mode 100644 SOURCE/MULTNODE.PAS create mode 100644 SOURCE/MYIO.PAS create mode 100644 SOURCE/NEWUSERS.PAS create mode 100644 SOURCE/NODELIST.PAS create mode 100644 SOURCE/OFFLINE.PAS create mode 100644 SOURCE/ONELINER.PAS create mode 100644 SOURCE/RECORDS.PAS create mode 100644 SOURCE/RENEGADE.PAS create mode 100644 SOURCE/RENEMAIL.PAS create mode 100644 SOURCE/RGLNG.PAS create mode 100644 SOURCE/RGQUOTE.PAS create mode 100644 SOURCE/RPSCREEN.PAS create mode 100644 SOURCE/SCRIPT.PAS create mode 100644 SOURCE/SHORTMSG.PAS create mode 100644 SOURCE/SPAWNO.PAS create mode 100644 SOURCE/SPLITCHA.PAS create mode 100644 SOURCE/STATS.PAS create mode 100644 SOURCE/SYSOP1.PAS create mode 100644 SOURCE/SYSOP10.PAS create mode 100644 SOURCE/SYSOP11.PAS create mode 100644 SOURCE/SYSOP12.PAS create mode 100644 SOURCE/SYSOP2.PAS create mode 100644 SOURCE/SYSOP2A.PAS create mode 100644 SOURCE/SYSOP2B.PAS create mode 100644 SOURCE/SYSOP2C.PAS create mode 100644 SOURCE/SYSOP2D.PAS create mode 100644 SOURCE/SYSOP2E.PAS create mode 100644 SOURCE/SYSOP2F.PAS create mode 100644 SOURCE/SYSOP2G.PAS create mode 100644 SOURCE/SYSOP2H.PAS create mode 100644 SOURCE/SYSOP2I.PAS create mode 100644 SOURCE/SYSOP2J.PAS create mode 100644 SOURCE/SYSOP2K.PAS create mode 100644 SOURCE/SYSOP2L.PAS create mode 100644 SOURCE/SYSOP2M.PAS create mode 100644 SOURCE/SYSOP2O.PAS create mode 100644 SOURCE/SYSOP3.PAS create mode 100644 SOURCE/SYSOP4.PAS create mode 100644 SOURCE/SYSOP5.PAS create mode 100644 SOURCE/SYSOP6.PAS create mode 100644 SOURCE/SYSOP7.PAS create mode 100644 SOURCE/SYSOP7M.PAS create mode 100644 SOURCE/SYSOP8.PAS create mode 100644 SOURCE/SYSOP9.PAS create mode 100644 SOURCE/TAGLINE.PAS create mode 100644 SOURCE/TIMEBANK.PAS create mode 100644 SOURCE/TIMEFUNC.PAS create mode 100644 SOURCE/UNUSED/ACFLAGS.ASC create mode 100644 SOURCE/UNUSED/ARCHIVE1.TPU create mode 100644 SOURCE/UNUSED/ARCHIVE2.TPU create mode 100644 SOURCE/UNUSED/ARCHIVE3.TPU create mode 100644 SOURCE/UNUSED/ARCVIEW.TPU create mode 100644 SOURCE/UNUSED/AUTOMSG.TPU create mode 100644 SOURCE/UNUSED/BATCH6.LST create mode 100644 SOURCE/UNUSED/BBSLIST.TPU create mode 100644 SOURCE/UNUSED/BOOT.TPU create mode 100644 SOURCE/UNUSED/BULLETIN.TPU create mode 100644 SOURCE/UNUSED/CHAIN.TXT create mode 100644 SOURCE/UNUSED/CHAINT~1.TXT create mode 100644 SOURCE/UNUSED/CHANGE.TXT create mode 100644 SOURCE/UNUSED/CHANGE1.TXT create mode 100644 SOURCE/UNUSED/CHANGE10.TXT create mode 100644 SOURCE/UNUSED/CHANGE11.TXT create mode 100644 SOURCE/UNUSED/CHANGE12.TXT create mode 100644 SOURCE/UNUSED/CHANGE13.TXT create mode 100644 SOURCE/UNUSED/CHANGE14.TXT create mode 100644 SOURCE/UNUSED/CHANGE2.TXT create mode 100644 SOURCE/UNUSED/CHANGE3.TXT create mode 100644 SOURCE/UNUSED/CHANGE4.TXT create mode 100644 SOURCE/UNUSED/CHANGE5.TXT create mode 100644 SOURCE/UNUSED/CHANGE6.TXT create mode 100644 SOURCE/UNUSED/CHANGE7.TXT create mode 100644 SOURCE/UNUSED/CHANGE8.TXT create mode 100644 SOURCE/UNUSED/CHANGE9.TXT create mode 100644 SOURCE/UNUSED/CHANGES.TXT create mode 100644 SOURCE/UNUSED/CHANGES1.TXT create mode 100644 SOURCE/UNUSED/CHANGES2.TXT create mode 100644 SOURCE/UNUSED/CHANGES3.TXT create mode 100644 SOURCE/UNUSED/CHANGES4.TXT create mode 100644 SOURCE/UNUSED/CHANGES7.TXT create mode 100644 SOURCE/UNUSED/CHANGES8.TXT create mode 100644 SOURCE/UNUSED/CHANGES9.TXT create mode 100644 SOURCE/UNUSED/CHNAGE2.TXT create mode 100644 SOURCE/UNUSED/COMMON.TPU create mode 100644 SOURCE/UNUSED/COMMON1.TPU create mode 100644 SOURCE/UNUSED/COMMON2.TPU create mode 100644 SOURCE/UNUSED/COMMON3.TPU create mode 100644 SOURCE/UNUSED/COMMON4.TPU create mode 100644 SOURCE/UNUSED/COMMON5.TPU create mode 100644 SOURCE/UNUSED/CRC32.ASM create mode 100644 SOURCE/UNUSED/CRC32A.PAS create mode 100644 SOURCE/UNUSED/CUSER.TPU create mode 100644 SOURCE/UNUSED/DEZIP.PAS create mode 100644 SOURCE/UNUSED/DOOR.SYS create mode 100644 SOURCE/UNUSED/DOOR32.SYS create mode 100644 SOURCE/UNUSED/DOOR32~1.TXT create mode 100644 SOURCE/UNUSED/DOORS.TPU create mode 100644 SOURCE/UNUSED/DOORSY~1.DOC create mode 100644 SOURCE/UNUSED/DORINFO1.DEF create mode 100644 SOURCE/UNUSED/DORINF~1.TXT create mode 100644 SOURCE/UNUSED/DRAG_010.PAS create mode 100644 SOURCE/UNUSED/EC.PAS create mode 100644 SOURCE/UNUSED/EC.TXT create mode 100644 SOURCE/UNUSED/EMAIL.TPU create mode 100644 SOURCE/UNUSED/ERROR.LOG create mode 100644 SOURCE/UNUSED/EVENT.PAS create mode 100644 SOURCE/UNUSED/EVENT.TPU create mode 100644 SOURCE/UNUSED/EVENTS.TPU create mode 100644 SOURCE/UNUSED/EXECBAT.TPU create mode 100644 SOURCE/UNUSED/FAELNG.EXE create mode 100644 SOURCE/UNUSED/FAELNG.PAS create mode 100644 SOURCE/UNUSED/FAELNG.TXT create mode 100644 SOURCE/UNUSED/FAEPR.DAT create mode 100644 SOURCE/UNUSED/FAETX.DAT create mode 100644 SOURCE/UNUSED/FILE0.TPU create mode 100644 SOURCE/UNUSED/FILE1.TPU create mode 100644 SOURCE/UNUSED/FILE10.LEE create mode 100644 SOURCE/UNUSED/FILE10.TPU create mode 100644 SOURCE/UNUSED/FILE11.TPU create mode 100644 SOURCE/UNUSED/FILE12.TPU create mode 100644 SOURCE/UNUSED/FILE13.TPU create mode 100644 SOURCE/UNUSED/FILE14.TPU create mode 100644 SOURCE/UNUSED/FILE2.TPU create mode 100644 SOURCE/UNUSED/FILE3.TPU create mode 100644 SOURCE/UNUSED/FILE4.TPU create mode 100644 SOURCE/UNUSED/FILE5.TPU create mode 100644 SOURCE/UNUSED/FILE6.TPU create mode 100644 SOURCE/UNUSED/FILE7.TPU create mode 100644 SOURCE/UNUSED/FILE8.TPU create mode 100644 SOURCE/UNUSED/FILE9.TPU create mode 100644 SOURCE/UNUSED/FILES.BBS create mode 100644 SOURCE/UNUSED/FSHELP.ASC create mode 100644 SOURCE/UNUSED/FSTR.PAS create mode 100644 SOURCE/UNUSED/FTS-0001.016 create mode 100644 SOURCE/UNUSED/GREP.COM create mode 100644 SOURCE/UNUSED/INSTALL.EXE create mode 100644 SOURCE/UNUSED/INSTALL.PAS create mode 100644 SOURCE/UNUSED/IS286.PAS create mode 100644 SOURCE/UNUSED/LEE.EXE create mode 100644 SOURCE/UNUSED/LEE.PAS create mode 100644 SOURCE/UNUSED/LEE.TXT create mode 100644 SOURCE/UNUSED/LGNQUOTE.DAT create mode 100644 SOURCE/UNUSED/LGNQUOTE.PTR create mode 100644 SOURCE/UNUSED/LGNQUOTE.TXT create mode 100644 SOURCE/UNUSED/LINECHAT.TPU create mode 100644 SOURCE/UNUSED/LOGON.BAT create mode 100644 SOURCE/UNUSED/LOGON.TPU create mode 100644 SOURCE/UNUSED/MAIL0.TPU create mode 100644 SOURCE/UNUSED/MAIL1.LEE create mode 100644 SOURCE/UNUSED/MAIL1.TPU create mode 100644 SOURCE/UNUSED/MAIL2.TPU create mode 100644 SOURCE/UNUSED/MAIL3.TPU create mode 100644 SOURCE/UNUSED/MAIL4.TPU create mode 100644 SOURCE/UNUSED/MAIL5.PAS create mode 100644 SOURCE/UNUSED/MAIL5.TPU create mode 100644 SOURCE/UNUSED/MAIL6.PAS create mode 100644 SOURCE/UNUSED/MAIL6.TPU create mode 100644 SOURCE/UNUSED/MAIL7.PAS create mode 100644 SOURCE/UNUSED/MAIL7.TPU create mode 100644 SOURCE/UNUSED/MAINT.TPU create mode 100644 SOURCE/UNUSED/MARRIAGE.DAT create mode 100644 SOURCE/UNUSED/MARRIAGE.PTR create mode 100644 SOURCE/UNUSED/MARRIAGE.TXT create mode 100644 SOURCE/UNUSED/MENUS.TPU create mode 100644 SOURCE/UNUSED/MENUS2.TPU create mode 100644 SOURCE/UNUSED/MENUS3.TPU create mode 100644 SOURCE/UNUSED/MENUS4.PAS create mode 100644 SOURCE/UNUSED/MENUS4.TPU create mode 100644 SOURCE/UNUSED/MISCCHAT.PAS create mode 100644 SOURCE/UNUSED/MISCUSER.TPU create mode 100644 SOURCE/UNUSED/MSGPACK.TPU create mode 100644 SOURCE/UNUSED/MSGQUOTE.DAT create mode 100644 SOURCE/UNUSED/MSGQUOTE.PTR create mode 100644 SOURCE/UNUSED/MSGQUOTE.TXT create mode 100644 SOURCE/UNUSED/MULT.PAS create mode 100644 SOURCE/UNUSED/MULTNODE.TPU create mode 100644 SOURCE/UNUSED/MYIO.TPU create mode 100644 SOURCE/UNUSED/NEWMCI.TXT create mode 100644 SOURCE/UNUSED/NEWUSERS.TPU create mode 100644 SOURCE/UNUSED/NODELIST.TPU create mode 100644 SOURCE/UNUSED/NONAME00.EXE create mode 100644 SOURCE/UNUSED/OFFLINE.TPU create mode 100644 SOURCE/UNUSED/OVRUMB.DOC create mode 100644 SOURCE/UNUSED/OVRUMB.PAS create mode 100644 SOURCE/UNUSED/OVRUMB.TPU create mode 100644 SOURCE/UNUSED/PCBOAR~1.TXT create mode 100644 SOURCE/UNUSED/PKUNZIP.EXE create mode 100644 SOURCE/UNUSED/PKZIP.EXE create mode 100644 SOURCE/UNUSED/PRHELP.ASC create mode 100644 SOURCE/UNUSED/RENEGADE.DAT create mode 100644 SOURCE/UNUSED/RENEGADE.EXE create mode 100644 SOURCE/UNUSED/RENEGADE.LNG create mode 100644 SOURCE/UNUSED/RENEGADE.OVR create mode 100644 SOURCE/UNUSED/RENEGADE.PIF create mode 100644 SOURCE/UNUSED/RENEGADE.TPH create mode 100644 SOURCE/UNUSED/RENEMAIL.EXE create mode 100644 SOURCE/UNUSED/RENEMAIL.TPH create mode 100644 SOURCE/UNUSED/REUPDATE.PAS create mode 100644 SOURCE/UNUSED/RGAPI.PAS create mode 100644 SOURCE/UNUSED/RGFLIST.PAS create mode 100644 SOURCE/UNUSED/RGINTRO.ANS create mode 100644 SOURCE/UNUSED/RGLNG.EXE create mode 100644 SOURCE/UNUSED/RGLNG.TXT create mode 100644 SOURCE/UNUSED/RGLNGNEW.TXT create mode 100644 SOURCE/UNUSED/RGLNGPR.DAT create mode 100644 SOURCE/UNUSED/RGLNGTX.DAT create mode 100644 SOURCE/UNUSED/RGMAIN.EXE create mode 100644 SOURCE/UNUSED/RGMAIN.PAS create mode 100644 SOURCE/UNUSED/RGMAIN.TXT create mode 100644 SOURCE/UNUSED/RGMAINPR.DAT create mode 100644 SOURCE/UNUSED/RGMAINT.EXE create mode 100644 SOURCE/UNUSED/RGMAINT.PAS create mode 100644 SOURCE/UNUSED/RGMAINT1.PAS create mode 100644 SOURCE/UNUSED/RGMAINT2.PAS create mode 100644 SOURCE/UNUSED/RGMAINTX.DAT create mode 100644 SOURCE/UNUSED/RGNOTE.EXE create mode 100644 SOURCE/UNUSED/RGNOTE.PAS create mode 100644 SOURCE/UNUSED/RGNOTE.TXT create mode 100644 SOURCE/UNUSED/RGNOTEPR.DAT create mode 100644 SOURCE/UNUSED/RGNOTETX.DAT create mode 100644 SOURCE/UNUSED/RGQUOTE.EXE create mode 100644 SOURCE/UNUSED/RGSCFG.EXE create mode 100644 SOURCE/UNUSED/RGSCFG.PAS create mode 100644 SOURCE/UNUSED/RGSCFG.TXT create mode 100644 SOURCE/UNUSED/RGSCFGPR.DAT create mode 100644 SOURCE/UNUSED/RGSCFGTX.DAT create mode 100644 SOURCE/UNUSED/RGSTAT.PAS create mode 100644 SOURCE/UNUSED/RGUPDATE.EXE create mode 100644 SOURCE/UNUSED/RGUPDATE.PAS create mode 100644 SOURCE/UNUSED/RGUPDT1.EXE create mode 100644 SOURCE/UNUSED/RGUPDT1.PAS create mode 100644 SOURCE/UNUSED/RGUPDT2.EXE create mode 100644 SOURCE/UNUSED/RGUPDT2.PAS create mode 100644 SOURCE/UNUSED/RGUPDT3.EXE create mode 100644 SOURCE/UNUSED/RGUPDT3.PAS create mode 100644 SOURCE/UNUSED/RGUPDT4.PAS create mode 100644 SOURCE/UNUSED/RGV118.EXE create mode 100644 SOURCE/UNUSED/RGV118.PAS create mode 100644 SOURCE/UNUSED/RGVER.EXE create mode 100644 SOURCE/UNUSED/RGVER.PAS create mode 100644 SOURCE/UNUSED/RGVERUDT.EXE create mode 100644 SOURCE/UNUSED/RGVERUDT.PAS create mode 100644 SOURCE/UNUSED/RMAILWKS.PAS create mode 100644 SOURCE/UNUSED/RMCHANGE.DOC create mode 100644 SOURCE/UNUSED/RMUPDATE.DOC create mode 100644 SOURCE/UNUSED/SCRIPT.TPU create mode 100644 SOURCE/UNUSED/SHORTMSG.TPU create mode 100644 SOURCE/UNUSED/SORTING.PAS create mode 100644 SOURCE/UNUSED/SPAWNO.TPU create mode 100644 SOURCE/UNUSED/SPLITCHA.TPU create mode 100644 SOURCE/UNUSED/STATS.TPU create mode 100644 SOURCE/UNUSED/SYSCHAT.PAS create mode 100644 SOURCE/UNUSED/SYSCHAT.TPU create mode 100644 SOURCE/UNUSED/SYSOP1.TPU create mode 100644 SOURCE/UNUSED/SYSOP10.TPU create mode 100644 SOURCE/UNUSED/SYSOP11.TPU create mode 100644 SOURCE/UNUSED/SYSOP12.TPU create mode 100644 SOURCE/UNUSED/SYSOP2.TPU create mode 100644 SOURCE/UNUSED/SYSOP2A.TPU create mode 100644 SOURCE/UNUSED/SYSOP2B.TPU create mode 100644 SOURCE/UNUSED/SYSOP2C.TPU create mode 100644 SOURCE/UNUSED/SYSOP2D.TPU create mode 100644 SOURCE/UNUSED/SYSOP2E.TPU create mode 100644 SOURCE/UNUSED/SYSOP2F.TPU create mode 100644 SOURCE/UNUSED/SYSOP2G.TPU create mode 100644 SOURCE/UNUSED/SYSOP2H.TPU create mode 100644 SOURCE/UNUSED/SYSOP2I.TPU create mode 100644 SOURCE/UNUSED/SYSOP2J.TPU create mode 100644 SOURCE/UNUSED/SYSOP2K.TPU create mode 100644 SOURCE/UNUSED/SYSOP2L.TPU create mode 100644 SOURCE/UNUSED/SYSOP2M.TPU create mode 100644 SOURCE/UNUSED/SYSOP2O.TPU create mode 100644 SOURCE/UNUSED/SYSOP3.TPU create mode 100644 SOURCE/UNUSED/SYSOP4.TPU create mode 100644 SOURCE/UNUSED/SYSOP5.TPU create mode 100644 SOURCE/UNUSED/SYSOP6.TPU create mode 100644 SOURCE/UNUSED/SYSOP6~1.PAS create mode 100644 SOURCE/UNUSED/SYSOP7.TPU create mode 100644 SOURCE/UNUSED/SYSOP7M.TPU create mode 100644 SOURCE/UNUSED/SYSOP8.TPU create mode 100644 SOURCE/UNUSED/SYSOP9.TPU create mode 100644 SOURCE/UNUSED/TAGLINE.DAT create mode 100644 SOURCE/UNUSED/TAGLINE.EXE create mode 100644 SOURCE/UNUSED/TAGLINE.PTR create mode 100644 SOURCE/UNUSED/TAGLINE.TXT create mode 100644 SOURCE/UNUSED/TAGSTAT.PAS create mode 100644 SOURCE/UNUSED/TEMP6.BAT create mode 100644 SOURCE/UNUSED/TIMEBANK.TPU create mode 100644 SOURCE/UNUSED/TIMEFUNC.TPU create mode 100644 SOURCE/UNUSED/TPX.DSK create mode 100644 SOURCE/UNUSED/TPX.TP create mode 100644 SOURCE/UNUSED/TURBO.DSK create mode 100644 SOURCE/UNUSED/USER.PAS create mode 100644 SOURCE/UNUSED/VOTE.TPU create mode 100644 SOURCE/UNUSED/WD110107.TXT create mode 100644 SOURCE/UNUSED/WD110207.TXT create mode 100644 SOURCE/UNUSED/WD110307.TXT create mode 100644 SOURCE/UNUSED/WFCMENU.TPU create mode 100644 SOURCE/UNUSED/WFCNEW1.ANS create mode 100644 SOURCE/UNUSED/WFC_COM.ANS create mode 100644 SOURCE/UNUSED/WFC_NODE.ANS create mode 100644 SOURCE/UNUSED/bootoldback.pas create mode 100644 SOURCE/UNUSED/m.cmd create mode 100644 SOURCE/UPGRADE/BBSLEDT.ASC create mode 100644 SOURCE/UPGRADE/BBSLEH.ASC create mode 100644 SOURCE/UPGRADE/BBSLEM.ASC create mode 100644 SOURCE/UPGRADE/BBSLIST.SCR create mode 100644 SOURCE/UPGRADE/FIXBBSL.PAS create mode 100644 SOURCE/VOTE.PAS create mode 100644 SOURCE/WFCMENU.PAS create mode 100644 SOURCE/WIN32/defines.inc create mode 100644 SOURCE/WIN32/overlay.pas create mode 100644 SOURCE/crc32.obj create mode 100644 SOURCE/execwin.obj create mode 100644 SOURCE/spawntp.obj create mode 100644 VPC.CFG diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..08dc0bf --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +EXE/ +ORIGINAL ARCHIVES/ \ No newline at end of file diff --git a/BPC.CFG b/BPC.CFG new file mode 100644 index 0000000..0d1172d --- /dev/null +++ b/BPC.CFG @@ -0,0 +1,27 @@ +/EZ:\PROGRA~1\RG119SRC\EXE\BP +/IZ:\BP\UNITS; +/OZ:\BP\UNITS; +/UZ:\BP\UNITS; +/R +/$MD64000,0,655360 +/$MP64000 +/$A+ +/$B- +/$D+ +/$E+ +/$F+ +/$G+ +/$I- +/$L+ +/$N- +/$O+ +/$P- +/$Q- +/$R- +/$S- +/$T- +/$V- +/$X+ +/$Y+ +/B +/GD diff --git a/BUILDBP.CMD b/BUILDBP.CMD new file mode 100644 index 0000000..5dccab0 --- /dev/null +++ b/BUILDBP.CMD @@ -0,0 +1,48 @@ +@ECHO OFF + +Z: + +ECHO CLEAING UP OUTPUT DIRECTORY +DEL /Q Z:\PROGRAMMING\RG119SRC\EXE\BP\*.* + +ECHO COPYING BPC.CFG TO BP DIRECTORY +COPY Z:\PROGRAMMING\RG119SRC\BPC.CFG Z:\BP\BIN + +CD Z:\PROGRAMMING\RG119SRC\SOURCE + +ECHO. +ECHO COMPILING RENEGADE.EXE +Z:\BP\BIN\BPC.EXE RENEGADE.PAS +IF NOT %ERRORLEVEL% == 0 GOTO END + +ECHO. +ECHO COMPILING RENEMAIL.EXE +Z:\BP\BIN\BPC.EXE RENEMAIL.PAS +IF NOT %ERRORLEVEL% == 0 GOTO END + +ECHO. +ECHO COMPILING RGLNG.EXE +Z:\BP\BIN\BPC.EXE RGLNG.PAS +IF NOT %ERRORLEVEL% == 0 GOTO END + +ECHO. +ECHO COMPILING RGQUOTE.EXE +Z:\BP\BIN\BPC.EXE RGQUOTE.PAS +IF NOT %ERRORLEVEL% == 0 GOTO END + +ECHO. +ECHO COMPILING TAGLINE.EXE +Z:\BP\BIN\BPC.EXE TAGLINE.PAS +IF NOT %ERRORLEVEL% == 0 GOTO END + +:COPY +ECHO. +ECHO BUILD COMPLETE! HIT A KEY TO COPY EXE FILES OR CTRL-C TO SKIP +PAUSE + +CD Z:\PROGRAMMING\RG119SRC +CALL COPYEXEBP +GOTO END + +:END +PAUSE \ No newline at end of file diff --git a/BUILDVP.CMD b/BUILDVP.CMD new file mode 100644 index 0000000..636c97e --- /dev/null +++ b/BUILDVP.CMD @@ -0,0 +1,48 @@ +@ECHO OFF + +Z: + +ECHO CLEAING UP OUTPUT DIRECTORY +DEL /Q Z:\PROGRAMMING\RG119SRC\EXE\VP\*.* + +ECHO COPYING VPC.CFG TO VP21 DIRECTORY +COPY Z:\PROGRAMMING\RG119SRC\VPC.CFG Z:\VP21\BIN.W32 + +CD Z:\PROGRAMMING\RG119SRC\SOURCE + +ECHO. +ECHO COMPILING RENEGADE.EXE +Z:\VP21\BIN.W32\VPC RENEGADE.PAS +IF NOT %ERRORLEVEL% == 0 GOTO END + +ECHO. +ECHO COMPILING RENEMAIL.EXE +Z:\VP21\BIN.W32\VPC RENEMAIL.PAS +IF NOT %ERRORLEVEL% == 0 GOTO END + +ECHO. +ECHO COMPILING RGLNG.EXE +Z:\VP21\BIN.W32\VPC RGLNG.PAS +IF NOT %ERRORLEVEL% == 0 GOTO END + +ECHO. +ECHO COMPILING RGQUOTE.EXE +Z:\VP21\BIN.W32\VPC RGQUOTE.PAS +IF NOT %ERRORLEVEL% == 0 GOTO END + +ECHO. +ECHO COMPILING TAGLINE.EXE +Z:\VP21\BIN.W32\VPC TAGLINE.PAS +IF NOT %ERRORLEVEL% == 0 GOTO END + +:COPY +ECHO. +ECHO BUILD COMPLETE! HIT A KEY TO COPY EXE FILES OR CTRL-C TO SKIP +PAUSE + +CD Z:\PROGRAMMING\RG119SRC +CALL COPYEXEVP +GOTO END + +:END +PAUSE \ No newline at end of file diff --git a/COMPILE.TXT b/COMPILE.TXT new file mode 100644 index 0000000..d69d5f5 --- /dev/null +++ b/COMPILE.TXT @@ -0,0 +1,55 @@ +Step 0) Assumptions: + + The first assumption is that you have Borland Pascal installed in Z:\BP. + If you don't, you'll have to update the BUILDBP.CMD file + + The second assumption is that you have Virtual Pascal installed in Z:\vp21. + If you don't, you'll have to update the BUILDVP.CMD file + + *NOTE* The BUILD*.CMD files will copy a BPC.CFG or VPC.CFG into the relevant bin directory, meaning + if you have cusomized the .CFG file in the bin directory, it will be lost. Make a backup! + +Step 1) Create directories to hold everything: + + Z:\RG119 + Z:\Programming\RG119SRC + Z:\Programming\RG119SRC\EXE\BP + Z:\Programming\RG119SRC\EXE\VP + + If you don't have a Z: drive, you can use SUBST or map a network drive to fake one + You can also put the files in an alternate location if you want, you'll just have to update the BUILD*.CMD scripts + +Step 2) Get the source + + Check out the GIT contents into Z:\Programming\RG119SRC + +Step 3) Edit Z:\vp21\source\rtl\vpsysw32.pas + + For some reason the cursor position isn't always updated in the background thread in the Win32 version. I'm guessing + it's a race condition with the CurXPos and CurYPos variables, so the thread doesn't think an update is needed when + one really is. So I've updated my copy of CursorThreadFunc to take the return value of the SemWaitEvent() call into + account, so the update will also happen if the event is signaled. Can't think of a reason why they wouldn't have done + this in the first place. Here's the entire function to copy/paste into place: + + function CursorThreadFunc(P: Pointer): Longint; + var + LastX, LastY: Longint; + begin + LastX := -1; + LastY := -1; + repeat + if SemWaitEvent(semCursor, 300) or (CurXPos <> LastX) or (CurYPos <> LastY) then + begin + DoSetCursorPosition; + LastX := CurXPos; + LastY := CurYPos; + end; + until tidCursor = -2; + tidCursor := -1; + end; + +Step 4) Build new EXEs + + Run BUILDBP.CMD to build the DOS EXEs and have them copied to Z:\RG119 + + Run BUILDVP.CMD to build the WIN32 EXEs and have them copied to Z:\RG119 \ No newline at end of file diff --git a/COPYEXEBP.CMD b/COPYEXEBP.CMD new file mode 100644 index 0000000..1844aac --- /dev/null +++ b/COPYEXEBP.CMD @@ -0,0 +1,7 @@ +@ECHO OFF +COPY Z:\PROGRAMMING\RG119SRC\EXE\BP\RENEGADE.EXE Z:\RG119\ +COPY Z:\PROGRAMMING\RG119SRC\EXE\BP\RENEGADE.OVR Z:\RG119\ +COPY Z:\PROGRAMMING\RG119SRC\EXE\BP\RENEMAIL.EXE Z:\RG119\ +COPY Z:\PROGRAMMING\RG119SRC\EXE\BP\RGLNG.EXE Z:\RG119\DATA\ +COPY Z:\PROGRAMMING\RG119SRC\EXE\BP\RGQUOTE.EXE Z:\RG119\DATA\ +COPY Z:\PROGRAMMING\RG119SRC\EXE\BP\TAGLINE.EXE Z:\RG119\DATA\ diff --git a/COPYEXEVP.CMD b/COPYEXEVP.CMD new file mode 100644 index 0000000..9c22858 --- /dev/null +++ b/COPYEXEVP.CMD @@ -0,0 +1,6 @@ +@ECHO OFF +COPY Z:\PROGRAMMING\RG119SRC\EXE\VP\RENEGADE.EXE Z:\RG119\RENEGADE32.EXE +COPY Z:\PROGRAMMING\RG119SRC\EXE\VP\RENEMAIL.EXE Z:\RG119\RENEMAIL32.EXE +COPY Z:\PROGRAMMING\RG119SRC\EXE\VP\RGLNG.EXE Z:\RG119\DATA\RGLNG32.EXE +COPY Z:\PROGRAMMING\RG119SRC\EXE\VP\RGQUOTE.EXE Z:\RG119\DATA\RGQUOTE32.EXE +COPY Z:\PROGRAMMING\RG119SRC\EXE\VP\TAGLINE.EXE Z:\RG119\DATA\TAGLINE32.EXE diff --git a/README.md b/README.md index 1e644b7..02af095 100644 --- a/README.md +++ b/README.md @@ -1 +1,28 @@ -Renegade BBS Source Code For v1.19/DOS was removed. This code is MANY years out of date, plus it can more than likely be found on countless forks. No one seemed interested in more than forking a copy over, so it was worthless to leave on here. - Please see the current non-source builds are located @ http://www.rgbbs.info and happy BBSing! +Renegade BBS Source Code http://rgbbs.info +============== + +============================== + +Copyright Cott Lang, Patrick Spence, Gary Hall, Jeff Herrings, T.J. McMillen, Chris Hoppman, and Lee Palmer
+Ported to Win32 by Rick Parrish
+ +
+ +TODO list:
+ + +Completed list
+ diff --git a/SOURCE/ARCHIVE1.PAS b/SOURCE/ARCHIVE1.PAS new file mode 100644 index 0000000..94cf95d --- /dev/null +++ b/SOURCE/ARCHIVE1.PAS @@ -0,0 +1,723 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Archive1; + +INTERFACE + +USES + Common; + +PROCEDURE ArcDeComp(VAR Ok: Boolean; AType: Byte; CONST FileName,FSpec: AStr); +PROCEDURE ArcComp(VAR Ok: Boolean; AType: Byte; CONST FileName,FSpec: AStr); +PROCEDURE ArcComment(VAR Ok: Boolean; AType: Byte; CommentNum: Byte; CONST FileName: AStr); +PROCEDURE ArcIntegrityTest(VAR Ok: Boolean; AType: Byte; CONST FileName: AStr); +PROCEDURE ConvA(VAR Ok: Boolean; OldAType,NewAType: Byte; CONST OldFN,NewFN: AStr); +FUNCTION ArcType(FileName: AStr): Byte; +PROCEDURE ListArcTypes; +PROCEDURE InvArc; +PROCEDURE ExtractToTemp; +PROCEDURE UserArchive; + +IMPLEMENTATION + +USES + Dos, + ArcView, + ExecBat, + File0, + File1, + File2, + File9, + TimeFunc; + +PROCEDURE ArcDeComp(VAR Ok: Boolean; AType: Byte; CONST FileName,FSpec: AStr); +VAR + ResultCode: Integer; +BEGIN + PurgeDir(TempDir+'ARC\',FALSE); + ExecBatch(Ok,TempDir+'ARC\',General.ArcsPath+ + FunctionalMCI(General.FileArcInfo[AType].UnArcLine,FileName,FSpec), + General.FileArcInfo[AType].SuccLevel,ResultCode,FALSE); + IF (NOT Ok) AND (Pos('.DIZ',FSpec) = 0) THEN + SysOpLog(FileName+': errors during de-compression'); +END; + +PROCEDURE ArcComp(VAR Ok: Boolean; AType: Byte; CONST FileName,FSpec: AStr); +VAR + ResultCode: Integer; +BEGIN + IF (General.FileArcInfo[AType].ArcLine = '') THEN + Ok := TRUE + ELSE + ExecBatch(Ok,TempDir+'ARC\',General.ArcsPath+ + FunctionalMCI(General.FileArcInfo[AType].ArcLine,FileName,FSpec), + General.FileArcInfo[AType].SuccLevel,ResultCode,FALSE); + IF (NOT Ok) THEN + SysOpLog(FileName+': errors during compression'); +END; + +PROCEDURE ArcComment(VAR Ok: Boolean; AType: Byte; CommentNum: Byte; CONST FileName: AStr); +VAR + TempStr: AStr; + ResultCode: Integer; + SaveSwapShell: Boolean; +BEGIN + IF (CommentNum > 0) AND (General.FileArcComment[CommentNum] <> '') THEN + BEGIN + SaveSwapShell := General.SwapShell; + General.SwapShell := FALSE; + TempStr := Substitute(General.FileArcInfo[AType].CmtLine,'%C',General.FileArcComment[CommentNum]); + TempStr := Substitute(TempStr,'%C',General.FileArcComment[CommentNum]); + ExecBatch(Ok,TempDir+'ARC\',General.ArcsPath+FunctionalMCI(TempStr,FileName,''), + General.FileArcInfo[AType].SuccLevel,ResultCode,FALSE); + General.SwapShell := SaveSwapShell; + END; +END; + +PROCEDURE ArcIntegrityTest(VAR Ok: Boolean; AType: Byte; CONST FileName: AStr); +VAR + ResultCode: Integer; +BEGIN + IF (General.FileArcInfo[AType].TestLine <> '') THEN + ExecBatch(Ok,TempDir+'ARC\',General.ArcsPath+ + FunctionalMCI(General.FileArcInfo[AType].TestLine,FileName,''), + General.FileArcInfo[AType].SuccLevel,ResultCode,FALSE); +END; + +PROCEDURE ConvA(VAR Ok: Boolean; OldAType,NewAType: Byte; CONST OldFN,NewFN: AStr); +VAR + NoFN: AStr; + PS: PathStr; + NS: NameStr; + ES: ExtStr; + FileTime: LongInt; + Match: Boolean; +BEGIN + Star('Converting archive - stage one.'); + + Match := (OldAType = NewAType); + IF (Match) THEN + BEGIN + FSplit(OldFN,PS,NS,ES); + NoFN := PS+NS+'.#$%'; + END; + + GetFileDateTime(OldFN,FileTime); + + ArcDeComp(Ok,OldAType,OldFN,'*.*'); + IF (NOT Ok) THEN + Star('Errors in decompression!') + ELSE + BEGIN + Star('Converting archive - stage two.'); + + IF (Match) THEN + RenameFile('',OldFN,NoFN,Ok); + + ArcComp(Ok,NewAType,NewFN,'*.*'); + IF (NOT Ok) THEN + BEGIN + Star('Errors in compression!'); + IF (Match) THEN + RenameFile('',NoFN,OldFN,Ok); + END + ELSE + + SetFileDateTime(NewFN,FileTime); + + IF (NOT Exist(SQOutSp(NewFN))) THEN + Ok := FALSE; + END; + IF (Exist(NoFN)) THEN + Kill(NoFN); +END; + +FUNCTION ArcType(FileName: AStr): Byte; +VAR + AType, + Counter: Byte; +BEGIN + AType := 0; + Counter := 1; + WHILE (Counter <= MaxArcs) AND (AType = 0) DO + BEGIN + IF (General.FileArcInfo[Counter].Active) THEN + IF (General.FileArcInfo[Counter].Ext <> '') THEN + IF (General.FileArcInfo[Counter].Ext = Copy(FileName,(Length(FileName) - 2),3)) THEN + AType := Counter; + Inc(Counter); + END; + ArcType := AType; +END; + +PROCEDURE ListArcTypes; +VAR + RecNum, + RecNum1: Byte; +BEGIN + RecNum1 := 0; + RecNum := 1; + WHILE (RecNum <= MaxArcs) AND (General.FileArcInfo[RecNum].Ext <> '') DO + BEGIN + IF (General.FileArcInfo[RecNum].Active) THEN + BEGIN + Inc(RecNum1); + IF (RecNum1 = 1) THEN + Prompt('^1Available archive formats: ') + ELSE + Prompt('^1,'); + Prompt('^5'+General.FileArcInfo[RecNum].Ext+'^1'); + END; + Inc(RecNum); + END; + IF (RecNum1 = 0) THEN + Prompt('No archive formats available.'); + NL; +END; + +PROCEDURE InvArc; +BEGIN + NL; + Print('Unsupported archive format.'); + NL; + ListArcTypes; +END; + +PROCEDURE ExtractToTemp; +TYPE + TotalsRecordType = RECORD + TotalFiles: SmallInt; + TotalSize: LongInt; + END; +VAR + Totals: TotalsRecordType; + FileName, + ArcFileName: AStr; + (* + DirInfo: SearchRec; + *) + DS: DirStr; + NS: NameStr; + ES: ExtStr; + Cmd: Char; + AType: Byte; + ReturnCode, + DirFileRecNum: Integer; + DidSomething, + Ok: Boolean; +BEGIN + NL; + Print('Extract to temporary directory -'); + NL; + Prompt('^1Already in TEMP: '); + + FillChar(Totals,SizeOf(Totals),0); + FindFirst(TempDir+'ARC\*.*',AnyFile - Directory - VolumeID - Hidden - SysFile,DirInfo); + WHILE (DOSError = 0) DO + BEGIN + Inc(Totals.TotalFiles); + Inc(Totals.TotalSize,DirInfo.Size); + FindNext(DirInfo); + END; + + IF (Totals.TotalFiles = 0) THEN + Print('^5Nothing.^1') + ELSE + Print('^5'+FormatNumber(Totals.TotalFiles)+ + ' '+Plural('file',Totals.TotalFiles)+ + ', '+ConvertBytes(Totals.TotalSize,FALSE)+'.^1'); + + IF (NOT FileSysOp) THEN + BEGIN + NL; + Print('The limit is '+FormatNumber(General.MaxInTemp)+'k bytes.'); + IF (Totals.TotalSize > (General.MaxInTemp * 1024)) THEN + BEGIN + NL; + Print('You have exceeded this limit.'); + NL; + Print('Please remove some files with the user-archive command.'); + Exit; + END; + END; + + NL; + Prt('File name: '); + IF (FileSysOp) THEN + BEGIN + MPL(52); + Input(FileName,52); + END + ELSE + BEGIN + MPL(12); + Input(FileName,12); + END; + + FileName := SQOutSp(FileName); + + IF (FileName = '') THEN + BEGIN + NL; + Print('Aborted!'); + Exit; + END; + + IF (IsUL(FileName)) AND (NOT FileSysOp) THEN + BEGIN + NL; + Print('^7Invalid file name!^1'); + Exit; + END; + + IF (Pos('.',FileName) = 0) THEN + FileName := FileName + '*.*'; + + Ok := TRUE; + + IF (NOT IsUL(FileName)) THEN + BEGIN + RecNo(FileInfo,FileName,DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + IF (NOT AACS(MemFileArea.DLACS)) THEN + BEGIN + NL; + Print('^7You do not have access to manipulate that file!^1'); + Exit; + END + ELSE IF (DirFileRecNum = -1) THEN + BEGIN + NL; + Print('^7File not found!^1'); + Exit; + END + ELSE + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + IF Exist(MemFileArea.DLPath+FileInfo.FileName) THEN + ArcFileName := MemFileArea.DLPath+SQOutSp(FileInfo.FileName) + ELSE + ArcFileName := MemFileArea.ULPath+SQOutSp(FileInfo.FileName); + END; + + END + ELSE + BEGIN + ArcFileName := FExpand(FileName); + IF (NOT Exist(ArcFileName)) THEN + BEGIN + NL; + Print('^7File not found!^1'); + Exit; + END + ELSE + BEGIN + FillChar(FileInfo,SizeOf(FileInfo),0); + WITH FileInfo DO + BEGIN + FileName := Align(StripName(ArcFileName)); + Description := 'Unlisted file'; + FilePoints := 0; + Downloaded := 0; + FileSize := GetFileSize(ArcFileName); + OwnerNum := UserNum; + OwnerName := Caps(ThisUser.Name); + FileDate := Date2PD(DateStr); + VPointer := -1; + VTextSize := 0; + FIFlags := []; + END; + END; + END; + IF (Ok) THEN + BEGIN + DidSomething := FALSE; + Abort := FALSE; + Next := FALSE; + AType := ArcType(ArcFileName); + IF (AType = 0) THEN + InvArc; + NL; + Print('You can (^5C^1)opy this file into the TEMP Directory,'); + IF (AType <> 0) THEN + Print('or (^5E^1)xtract files from it into the TEMP Directory.') + ELSE + Print('but you can''t extract files from it.'); + NL; + Prt('Which? (^5C^4=^5Copy'+AOnOff((AType <> 0),'^4,^5E^4=^5Extract','')+'^4,^5Q^4=^5Quit^4): '); + OneK(Cmd,'QC'+AOnOff((AType <> 0),'E',''),TRUE,TRUE); + CASE Cmd OF + 'C' : BEGIN + FSplit(ArcFileName,DS,NS,ES); + NL; + IF CopyMoveFile(TRUE,'^5Progress: ',ArcFileName,TempDir+'ARC\'+NS+ES,TRUE) THEN + DidSomething := TRUE; + END; + 'E' : BEGIN + NL; + DisplayFileInfo(FileInfo,TRUE); + REPEAT + NL; + Prt('Extract files (^5E^4=^5Extract^4,^5V^4=^5View^4,^5Q^4=^5Quit^4): '); + OneK(Cmd,'QEV',TRUE,TRUE); + CASE Cmd OF + 'E' : BEGIN + NL; + IF PYNQ('Extract all files? ',0,FALSE) THEN + FileName := '*.*' + ELSE + BEGIN + NL; + Prt('File name: '); + MPL(12); + Input(FileName,12); + FileName := SQOutSp(FileName); + IF (FileName = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE IF IsUL(FileName) THEN + BEGIN + NL; + Print('^7Illegal filespec!^1'); + FileName := ''; + END; + END; + IF (FileName <> '') THEN + BEGIN + Ok := FALSE; + ExecBatch(Ok,TempDir+'ARC\',General.ArcsPath+ + FunctionalMCI(General.FileArcInfo[AType].UnArcLine,ArcFileName,FileName), + General.FileArcInfo[AType].SuccLevel,ReturnCode,FALSE); + IF (Ok) THEN + BEGIN + NL; + Star('Decompressed '+FileName+' into TEMP from '+StripName(ArcFileName)); + SysOpLog('Decompressed '+FileName+' into '+TempDir+'ARC\ from '+StripName(ArcFileName)); + DidSomething := TRUE; + END + ELSE + BEGIN + NL; + Star('Error decompressing '+FileName+' into TEMP from '+StripName(ArcFileName)); + SysOpLog('Error decompressing '+FileName+' into '+TempDir+'ARC\ from '+StripName(ArcFileName)); + END; + END; + END; + 'V' : IF (IsUL(ArcFileName)) THEN + ViewInternalArchive(ArcFileName) + ELSE + BEGIN + IF Exist(MemFileArea.DLPath+FileInfo.FileName) THEN + ViewInternalArchive(MemFileArea.DLPath+FileInfo.FileName) + ELSE + ViewInternalArchive(MemFileArea.ULPath+FileInfo.FileName); + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); + END; + END; + IF (DidSomething) THEN + BEGIN + NL; + Print('^5NOTE: ^1Use the user archive menu command to access'); + Print(' files in the TEMP directory.^1'); + END; + END; + LastError := IOResult; +END; + +PROCEDURE UserArchive; +VAR + User: UserRecordType; + (* + DirInfo: SearchRec; + *) + TransferFlags: TransferFlagSet; + ArcFileName, + FName: Str12; + Cmd: Char; + AType, + SaveNumBatchDLFiles: Byte; + ReturnCode, + GotPts, + SaveFileArea: Integer; + Ok, + SaveFileCreditRatio: Boolean; + + FUNCTION OkName(FileName1: AStr): Boolean; + BEGIN + OkName := TRUE; + OkName := NOT IsWildCard(FileName1); + IF (IsUL(FileName1)) THEN + OkName := FALSE; + END; + +BEGIN + REPEAT + NL; + Prt('Temp archive menu [^5?^4=^5Help^4]: '); + OneK(Cmd,'QADLRVT?',TRUE,TRUE); + CASE Cmd OF + 'A' : BEGIN + NL; + Prt('Archive name: '); + MPL(12); + Input(ArcFileName,12); + IF (ArcFileName = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE + BEGIN + + LoadFileArea(FileArea); + + IF (Pos('.',ArcFileName) = 0) AND (MemFileArea.ArcType <> 0) THEN + ArcFileName := ArcFileName+'.'+General.FileArcInfo[MemFileArea.ArcType].Ext; + + AType := ArcType(ArcFileName); + IF (AType = 0) THEN + InvArc + ELSE + BEGIN + NL; + Prt('File name: '); + MPL(12); + Input(FName,12); + IF (FName = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE IF (IsUL(FName)) OR (Pos('@',FName) > 0) THEN + BEGIN + NL; + Print('^7Illegal file name!^1'); + END + ELSE IF (NOT Exist(TempDir+'ARC\'+FName)) THEN + BEGIN + NL; + Print('^7File not found!^1'); + END + ELSE + BEGIN + Ok := FALSE; + ExecBatch(Ok,TempDir+'ARC\',General.ArcsPath+ + FunctionalMCI(General.FileArcInfo[AType].ArcLine,TempDir+'ARC\'+ArcFileName,FName), + General.FileArcInfo[AType].SuccLevel,ReturnCode,FALSE); + IF (Ok) THEN + BEGIN + NL; + Star('Compressed "^5'+FName+'^3" into "^5'+ArcFileName+'^3"'); + SysOpLog('Compressed "^5'+FName+'^1" into "^5'+TempDir+'ARC\'+ArcFileName+'^1"') + END + ELSE + BEGIN + NL; + Star('Error compressing "^5'+FName+'^3" into "^5'+ArcFileName+'^3"'); + SysOpLog('Error compressing "^5'+FName+'^1" into "^5'+TempDir+'ARC\'+ArcFileName+'^1"'); + END; + END; + END; + END; + END; + 'D' : BEGIN + NL; + Prt('File name: '); + MPL(12); + Input(FName,12); + IF (FName = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE IF (NOT OkName(FName)) THEN + BEGIN + NL; + Print('^7Illegal file name!^1'); + END + ELSE + BEGIN + FindFirst(TempDir+'ARC\'+FName,AnyFile - Directory - VolumeID - Hidden - SysFile,DirInfo); + IF (DOSError <> 0) THEN + BEGIN + NL; + Print('^7File not found!^1'); + END + ELSE + BEGIN + SaveFileArea := FileArea; + FileArea := -1; + WITH MemFileArea DO + BEGIN + AreaName := 'Temp Archive'; + DLPath := TempDir+'ARC\'; + ULPath := TempDir+'ARC\'; + FAFlags := []; + END; + (* Consider charging points, ext. *) + LoadURec(User,1); + WITH FileInfo DO + BEGIN + FileName := Align(FName); + Description := 'Temporary Archive'; + FilePoints := 0; + Downloaded := 0; + FileSize := GetFileSize(TempDir+'ARC\'+FileName);; + OwnerNum := 1; + OwnerName := Caps(User.Name); + FileDate := Date2PD(DateStr); + VPointer := -1; + VTextSize := 0; + FIFlags := []; + END; + TransferFlags := [IsTempArc,IsCheckRatio]; + SaveNumBatchDLFiles := NumBatchDLFiles; + DLX(FileInfo,-1,TransferFlags); + FileArea := SaveFileArea; + LoadFileArea(FileArea); + IF (NumBatchDLFiles <> SaveNumBatchDLFiles) THEN + BEGIN + NL; + Print('^5REMEMBER: ^1If you delete this file from the temporary directory,'); + Print(' you will not be able to download it in your batch queue.'); + END; + END; + END; + END; + 'L' : BEGIN + AllowContinue := TRUE; + NL; + DosDir(TempDir+'ARC\','*.*',TRUE); + AllowContinue := FALSE; + SysOpLog('Listed temporary directory: "^5'+TempDir+'ARC\*.*^1"'); + END; + 'R' : BEGIN + NL; + Prt('File mask: '); + MPL(12); + Input(FName,12); + IF (FName = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE IF (IsUL(FName)) THEN + BEGIN + NL; + Print('^7Illegal file name!^1'); + END + ELSE + BEGIN + FindFirst(TempDir+'ARC\'+FName,AnyFile - Directory - VolumeID - Hidden - SysFile,DirInfo); + IF (DOSError <> 0) THEN + BEGIN + NL; + Print('^7File not found!^1'); + END + ELSE + BEGIN + NL; + REPEAT + Kill(TempDir+'ARC\'+DirInfo.Name); + Star('Removed temporary archive file: "^5'+DirInfo.Name+'^3"'); + SysOpLog('^1Removed temp arc file: "^5'+TempDir+'ARC\'+DirInfo.Name+'^1"'); + FindNext(DirInfo); + UNTIL (DOSError <> 0) OR (HangUp); + END; + END; + END; + 'T' : BEGIN + NL; + Prt('File name: '); + MPL(12); + Input(FName,12); + IF (FName = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE IF (NOT OkName(FName)) THEN + BEGIN + NL; + Print('^7Illegal file name!^1'); + END + ELSE + BEGIN + FindFirst(TempDir+'ARC\'+FName,AnyFile - Directory - VolumeID - Hidden - SysFile,DirInfo); + IF (DOSError <> 0) THEN + BEGIN + NL; + Print('^7File not found!^1'); + END + ELSE + BEGIN + NL; + PrintF(TempDir+'ARC\'+DirInfo.Name); + SysOpLog('Displayed temp arc file: "^5'+TempDir+'ARC\'+DirInfo.Name+'^1"'); + END; + END; + END; + 'V' : BEGIN + NL; + Prt('File mask: '); + MPL(12); + Input(FName,12); + IF (FName = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE IF (NOT ValidIntArcType(FName)) THEN + BEGIN + NL; + Print('^7Not a valid archive type or not supported!^1') + END + ELSE + BEGIN + FindFirst(TempDir+'ARC\'+FName,AnyFile - Directory - VolumeID - Hidden - SysFile,DirInfo); + IF (DOSError <> 0) THEN + BEGIN + NL; + Print('^7File not found!^1'); + END + ELSE + BEGIN + Abort := FALSE; + Next := FALSE; + REPEAT + ViewInternalArchive(TempDir+'ARC\'+DirInfo.Name); + SysOpLog('Viewed temp arc file: "^5'+TempDir+'ARC\'+DirInfo.Name+'^1"'); + FindNext(DirInfo); + UNTIL (DOSError <> 0) OR (Abort) OR (HangUp); + END; + END; + END; + '?' : BEGIN + NL; + ListArcTypes; + NL; + LCmds(30,3,'Add to archive',''); + LCmds(30,3,'Download files',''); + LCmds(30,3,'List files in directory',''); + LCmds(30,3,'Remove files',''); + LCmds(30,3,'Text view file',''); + LCmds(30,3,'View archive',''); + LCmds(30,3,'Quit',''); + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); + LastCommandOvr := TRUE; + LastError := IOResult; +END; + +END. diff --git a/SOURCE/ARCHIVE2.PAS b/SOURCE/ARCHIVE2.PAS new file mode 100644 index 0000000..70b8d25 --- /dev/null +++ b/SOURCE/ARCHIVE2.PAS @@ -0,0 +1,919 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Archive2; + +INTERFACE + +PROCEDURE DOArcCommand(Cmd: Char); + +IMPLEMENTATION + +USES + Dos, + Archive1, + Archive3, + Arcview, + Common, + ExecBat, + File0, + File1, + File9, + File11, + TimeFunc; + +CONST + MaxDOSChrLine = 127; + +PROCEDURE DOArcCommand(Cmd: Char); +CONST + MaxFiles = 100; +VAR + FI: FILE OF Byte; + FileListArray: ARRAY [1..MaxFiles] OF AStr; + F: FileInfoRecordType; + (* + DirInfo: SearchRec; + *) + FileName, + S, + S1, + S2, + OS1: AStr; + DS: DirStr; + NS: NameStr; + ES: ExtStr; + AType, + BB, + NumExtDesc, + NumFiles, + RecNum, + Counter: Byte; + Junk, + RN, + FArea, + SaveFileArea, + C_Files: Integer; + C_OldSiz, + C_NewSiz, + OldSiz, + NewSiz: LongInt; + Ok, + Ok1, + FNX, + WentToSysOp, + DelBad: Boolean; + + PROCEDURE AddFL(F1: FileInfoRecordType; FN1: AStr; VAR NumFiles1: Byte; b: Boolean); + VAR + DirInfo1: SearchRec; + DS1: DirStr; + NS1: NameStr; + ES1: ExtStr; + SaveNumFiles: Byte; + RN1: Integer; + BEGIN + SaveNumFiles := NumFiles1; + IF (NOT b) THEN + BEGIN + RecNo(F1,FN1,RN1); + IF (BadDownloadPath) THEN + Exit; + WHILE (RN1 <> -1) AND (NumFiles1 < MaxFiles) DO + BEGIN + Seek(FileInfoFile,RN1); + Read(FileInfoFile,F1); + Inc(NumFiles1); + FileListArray[NumFiles1] := F1.FileName; + NRecNo(F1,RN1); + END; + END + ELSE + BEGIN + FSplit(FN1,DS1,NS1,ES1); + ChDir(BSlash(DS1,FALSE)); + IF (IOResult <> 0) THEN + Print('Path not found.') + ELSE + BEGIN + FindFirst(FN1,AnyFile - Directory - VolumeID - Dos.Hidden - SysFile,DirInfo1); + WHILE (DOSError = 0) AND (NumFiles1 < MaxFiles) DO + BEGIN + Inc(NumFiles1); + FileListArray[NumFiles1] := FExpand(DS1+DirInfo1.Name); + FindNext(DirInfo1); + END; + END; + ChDir(StartDir); + END; + IF (NumFiles1 = SaveNumFiles) THEN + Print('No matching files.') + ELSE IF (NumFiles1 >= MaxFiles) THEN + Print('File records filled.'); + END; + + PROCEDURE TestFiles(F1: FileInfoRecordType; FArea1: Integer; FN1: AStr; DelBad1: Boolean); + VAR + AType1: Byte; + RN1: Integer; + Ok2: Boolean; + BEGIN + IF (FileArea <> FArea1) THEN + ChangeFileArea(FArea1); + IF (FileArea = FArea1) THEN + BEGIN + RecNo(F1,FN1,RN1); + IF (BadDownloadPath) THEN + Exit; + WHILE (RN1 <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,RN1); + Read(FileInfoFile,F1); + IF Exist(MemFileArea.DLPath+F1.FileName) THEN + FN1 := MemFileArea.DLPath+F1.FileName + ELSE + FN1 := MemFileArea.ULPath+F1.FileName; + AType1 := ArcType(FN1); + IF (AType1 <> 0) THEN + BEGIN + DisplayFileAreaHeader; + Star('Testing "'+SQOutSP(FN1)+'"'); + IF (NOT Exist(FN1)) THEN + Star('File "'+SQOutSP(FN1)+'" does not exist.') + ELSE + BEGIN + Ok2 := TRUE; + ArcIntegrityTest(Ok2,AType1,SQOutSP(FN1)); + IF (NOT Ok2) THEN + BEGIN + Star('File "'+SQOutSP(FN1)+'" did not pass integrity test.'); + IF (DelBad1) THEN + BEGIN + DeleteFF(F1,RN1); + Kill(FN1); + END; + END; + END; + END; + WKey; + NRecNo(F1,RN1); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; + LastError := IOResult; + END; + + PROCEDURE CmtFiles(F1: FileInfoRecordType; FArea1: Integer; FN1: AStr); + VAR + AType1: Byte; + RN1: Integer; + Ok2: Boolean; + BEGIN + IF (FileArea <> FArea1) THEN + ChangeFileArea(FArea1); + IF (FileArea = FArea1) THEN + BEGIN + RecNo(F1,FN1,RN1); + IF (BadDownloadPath) THEN + Exit; + WHILE (RN1 <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,RN1); + Read(FileInfoFile,F1); + IF Exist(MemFileArea.DLPath+F1.FileName) THEN + FN1 := MemFileArea.DLPath+F1.FileName + ELSE + FN1 := MemFileArea.ULPath+F1.FileName; + AType1 := ArcType(FN1); + IF (AType1 <> 0) THEN + BEGIN + DisplayFileAreaHeader; + NL; + Star('Commenting "'+SQOutSP(FN1)+'"'); + IF (NOT Exist(FN1)) THEN + Star('File "'+SQOutSP(FN1)+'" does not exist.') + ELSE + BEGIN + Ok2 := TRUE; + ArcComment(Ok2,AType1,MemFileArea.CmtType,SQOutSP(FN1)); + (* If NOT Ok *) + + END; + END; + WKey; + NRecNo(F1,RN1); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; + LastError := IOResult; + END; + + PROCEDURE CvtFiles(F1: FileInfoRecordType; + FArea1: Integer; + FN1: AStr; + Toa: Integer; + VAR C_Files1: Integer; + VAR C_OldSiz1, + C_NewSiz1: LongInt); + VAR + FI: FILE OF Byte; + S3: AStr; + AType1: Byte; + RN1: Integer; + Ok2: Boolean; + BEGIN + IF (FileArea <> FArea1) THEN + ChangeFileArea(FArea1); + IF (FileArea = FArea1) THEN + BEGIN + RecNo(F1,FN1,RN1); + IF (BadDownloadPath) THEN + Exit; + WHILE (RN1 <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,RN1); + Read(FileInfoFile,F1); + IF Exist(MemFileArea.DLPath+F1.FileName) THEN + FN1 := MemFileArea.DLPath+F1.FileName + ELSE + FN1 := MemFileArea.ULPath+F1.FileName; + AType1 := ArcType(FN1); + IF (AType1 <> 0) AND (AType1 <> Toa) THEN + BEGIN + DisplayFileAreaHeader; + NL; + Star('Converting "'+SQOutSP(FN1)+'"'); + Ok2 := FALSE; + IF (NOT Exist(FN1)) THEN + BEGIN + Star('File "'+SQOutSP(FN1)+'" does not exist - changing extension.'); + S3 := Copy(FN1,1,Pos('.',FN1))+General.FileArcInfo[Toa].Ext; + F1.FileName := Align(StripName(SQOutSP(S3))); + Seek(FileInfoFile,RN1); + Write(FileInfoFile,F1); + END + ELSE + BEGIN + Ok2 := TRUE; + S3 := Copy(FN1,1,Pos('.',FN1))+General.FileArcInfo[Toa].Ext; + ConvA(Ok2,AType1,BB,SQOutSP(FN1),SQOutSP(S3)); + IF (Ok2) THEN + BEGIN + + Assign(FI,SQOutSP(FN1)); + Reset(FI); + Ok2 := (IOResult = 0); + IF (Ok2) THEN + BEGIN + OldSiz := FileSize(FI); + Close(FI); + END + ELSE + Star('Unable to access "'+SQOutSP(FN1)+'"'); + + IF (Ok2) THEN + IF (NOT Exist(SQOutSP(S3))) THEN + BEGIN + Star('Unable to access "'+SQOutSP(S3)+'"'); + SysOpLog('Unable to access '+SQOutSP(S3)); + Ok2 := FALSE; + END; + END; + + IF (Ok2) THEN + BEGIN + F1.FileName := Align(StripName(SQOutSP(S3))); + Seek(FileInfoFile,RN1); + Write(FileInfoFile,F1); + + Kill(SQOutSP(FN1)); + + Assign(FI,SQOutSP(S3)); + Reset(FI); + Ok2 := (IOResult = 0); + IF (NOT Ok2) THEN + BEGIN + Star('Unable to access '+SQOutSP(S3)); + SysOpLog('Unable to access '+SQOutSP(S3)); + END + ELSE + BEGIN + NewSiz := FileSize(FI); + F1.FileSize := NewSiz; + Close(FI); + Seek(FileInfoFile,RN1); + Write(FileInfoFile,F1); + END; + + IF (Ok2) THEN + BEGIN + Inc(C_OldSiz1,OldSiz); + Inc(C_NewSiz1,NewSiz); + Inc(C_Files1); + Star('Old total space took up : '+ConvertBytes(OldSiz,FALSE)); + Star('New total space taken up : '+ConvertBytes(NewSiz,FALSE)); + IF (OldSiz - NewSiz > 0) THEN + Star('Space saved : '+ConvertBytes(OldSiz-NewSiz,FALSE)) + ELSE + Star('Space wasted : '+ConvertBytes(NewSiz-OldSiz,FALSE)); + END; + END + ELSE + BEGIN + SysOpLog('Unable to convert '+SQOutSP(FN1)); + Star('Unable to convert '+SQOutSP(FN1)); + END; + END; + END; + WKey; + NRecNo(F,RN1); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; + LastError := IOResult; + END; + +BEGIN + TempPause := FALSE; + SaveFileArea := FileArea; + InitFileArea(FileArea); + IF (BadDownloadPath) THEN + Exit; + CASE Cmd OF + 'A' : BEGIN + NL; + Print('Add file(s) to archive (up to '+IntToStr(MaxFiles)+') -'); + NL; + Print('Archive file name: '); + Prt(':'); + MPL(78); + Input(FileName,78); + + IF IsUL(FileName) AND (NOT FileSysOp) THEN + FileName := ''; + + IF (FileName = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE + BEGIN + NumFiles := 0; + IF (Pos('.',FileName) = 0) AND (MemFileArea.ArcType <> 0) THEN + FileName := FileName+'.'+General.FileArcInfo[MemFileArea.ArcType].Ext; + FNX := ISUL(FileName); + IF (NOT FNX) THEN + BEGIN + IF Exist(MemFileArea.DLPath+FileName) THEN + FileName := MemFileArea.DLPath+FileName + ELSE + FileName := MemFileArea.ULPath+FileName + END; + FileName := FExpand(FileName); + AType := ArcType(FileName); + IF (AType = 0) THEN + InvArc + ELSE + BEGIN + Cmd := 'A'; + REPEAT + IF (Cmd = 'A') THEN + REPEAT + NL; + Print('Add files to list - to end'); + Prt(IntToStr(NumFiles + 1)+':'); + MPL(70); + Input(S,70); + IF (S <> '') AND (NOT IsUL(S) OR FileSysOp) THEN + BEGIN + IF (Pos('.',S) = 0) THEN + S := S + '*.*'; + AddFL(F,S,NumFiles,IsUL(S)); + END; + UNTIL (S = '') OR (NumFiles >= MaxFiles) OR (HangUp); + NL; + Prt('Add files to list [^5?^4=^5Help^4]: '); + OneK(Cmd,'QADLR?',TRUE,TRUE); + NL; + CASE Cmd OF + '?' : BEGIN + LCmds(19,3,'Add more to list','Do it!'); + LCmds(19,3,'List files in list','Remove files from list'); + LCmds(19,3,'Quit',''); + END; + 'D' : BEGIN + RecNum := 0; + REPEAT + Inc(RecNum); + Counter := 1; + S2 := SQOutSP(FileListArray[RecNum]); + IF (NOT IsUL(S2)) THEN + S2 := MemFileArea.DLPath+S2; + S1 := FunctionalMCI(General.FileArcInfo[AType].ArcLine,FileName,S2); + OS1 := S1; + WHILE (Length(S1) <= MaxDOSChrLine) AND (RecNum < NumFiles) DO + BEGIN + Inc(RecNum); + Inc(Counter); + S2 := SQOutSP(FileListArray[RecNum]); + IF (NOT IsUL(S2)) THEN + S2 := MemFileArea.DLPath+S2; + OS1 := S1; + S1 := S1+' '+S2; + END; + IF (Length(S1) > MaxDOSChrLine) THEN + BEGIN + Dec(RecNum); + Dec(Counter); + S1 := OS1; + END; + Ok := TRUE; + Star('Adding '+IntToStr(Counter)+' files to archive...'); + ExecBatch(Ok, + TempDir+'UP\',General.ArcsPath+S1, + General.FileArcInfo[AType].SuccLevel,Junk,FALSE); + IF (NOT Ok) THEN + BEGIN + Star('errors in adding files'); + Ok := PYNQ('Continue anyway? ',0,FALSE); + IF (HangUp) THEN + Ok := FALSE; + END; + UNTIL (RecNum >= NumFiles) OR (NOT Ok); + ArcComment(Ok,AType,MemFileArea.CmtType,FileName); + NL; + IF (NOT FNX) THEN + BEGIN + S1 := StripName(FileName); + RecNo(F,S1,RN); + IF (BadDownloadPath) THEN + Exit; + IF (RN <> -1) THEN + Print('^5NOTE: File already exists in listing!'); + IF PYNQ('Add archive to listing? ',0,FALSE) THEN + BEGIN + + Assign(FI,FileName); + Reset(FI); + IF (IOResult = 0) THEN + BEGIN + F.fileSize := FileSize(FI); + Close(FI); + END; + + F.FileName := Align(S1); + Ok1 := TRUE; + IF PYNQ('Replace a file in directory? ',0,FALSE) THEN + BEGIN + REPEAT + NL; + Prt('Enter file name: '); + MPL(12); + Input(S2,12); + IF (S2 = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE + BEGIN + RecNo(F,S2,RN); + IF (BadDownloadPath) THEN + Exit; + IF (RN = -1) THEN + Print('File not found!'); + END; + UNTIL (RN <> -1) OR (S2 = '') OR (HangUp); + IF (S2 <> '') THEN + BEGIN + Seek(FileInfoFile,RN); + Read(FileInfoFile,F); + Kill(MemFileArea.ULPath+SQOutSP(F.FileName)); + F.FileName := Align(S1); + Seek(FileInfoFile,RN); + Write(FileInfoFile,F); + END + ELSE + Ok1 := FALSE; + END + ELSE + Ok1 := FALSE; + IF (NOT Ok1) THEN + BEGIN + WentToSysOp := FALSE; + GetFileDescription(F,ExtendedArray,NumExtDesc,WentToSysOp); + F.FilePoints := 0; + F.Downloaded := 0; + F.OwnerNum := UserNum; + F.OwnerName := AllCaps(ThisUser.Name); + F.FileDate := Date2PD(DateStr); + F.VPointer := -1; + F.VTextSize := 0; + END; + F.FIFlags := []; + + IF (NOT AACS(General.ULValReq)) AND (NOT General.ValidateAllFiles) THEN + Include(F.FIFlags,FINotVal); + + IF (NOT General.FileCreditRatio) THEN + F.FilePoints := 0 + ELSE + F.FilePoints := ((F.FileSize DIV 1024) DIV General.FileCreditCompBaseSize); + + IF (RN = -1) THEN + WriteFV(F,FileSize(FileInfoFile),ExtendedArray) + ELSE + WriteFV(F,RN,ExtendedArray); + END; + END; + IF PYNQ('Delete original files? ',0,FALSE) THEN + FOR RecNum := 1 TO NumFiles DO + BEGIN + S2 := SQOutSP(FileListArray[RecNum]); + IF (NOT IsUL(FileListArray[RecNum])) THEN + BEGIN + RecNo(F,S2,RN); + IF (BadDownloadPath) THEN + Exit; + IF (RN <> -1) THEN + DeleteFF(F,RN); + S2 := MemFileArea.DLPath+S2; + END; + Kill(S2); + END; + IF (Ok) THEN + Cmd := 'Q'; + END; + 'L' : IF (NumFiles = 0) THEN + Print('No files in list!') + ELSE + BEGIN + Abort := FALSE; + Next := FALSE; + S := ''; + Counter := 0; + RecNum := 0; + REPEAT + Inc(RecNum); + IF IsUL(FileListArray[RecNum]) THEN + S := S + '^3' + ELSE + S := S + '^1'; + S := S + Align(StripName(FileListArray[RecNum])); + Inc(Counter); + IF (Counter < 5) THEN + S := S + ' ' + ELSE + BEGIN + PrintACR(S); + S := ''; + Counter := 0; + END; + UNTIL (RecNum = NumFiles) OR (Abort) OR (HangUp); + IF (Counter in [1..4]) AND (NOT Abort) THEN + PrintACR(S); + END; + 'R' : IF (NumFiles = 0) THEN + Print('No files in list!') + ELSE + BEGIN + Prt('Remove file name: '); + MPL(12); + Input(S,12); + IF (S = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE + BEGIN + RecNum := 0; + REPEAT + Inc(RecNum); + IF Align(StripName(FileListArray[RecNum])) = Align(S) THEN + BEGIN + Prompt('^3'+SQOutSP(FileListArray[RecNum])); + IF PYNQ(' Remove it? ',0,FALSE) THEN + BEGIN + FOR Counter := RecNum TO (NumFiles - 1) DO + FileListArray[Counter] := FileListArray[Counter + 1]; + Dec(NumFiles); + Dec(RecNum); + END; + END; + UNTIL (RecNum >= NumFiles); + END; + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); + Cmd := #0; + END; + END; + END; + 'C' : BEGIN + NL; + Print('Convert archive formats -'); + NL; + Print('Filespec:'); + Prt(':'); + MPL(78); + Input(FileName,78); + IF (FileName = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE + BEGIN + + NL; + REPEAT + Prt('Archive type to use? (?=List): '); + MPL(3); + Input(S,3); + IF (S = '?') THEN + BEGIN + NL; + ListArcTypes; + NL; + END; + UNTIL (S <> '?'); + + IF (StrToInt(S) <> 0) THEN + BB := StrToInt(S) + ELSE + BB := ArcType('F.'+S); + + IF (BB <> 0) THEN + BEGIN + C_Files := 0; + C_OldSiz := 0; + C_NewSiz := 0; + Abort := FALSE; + Next := FALSE; + SysOpLog('Conversion process initiated at '+DateStr+' '+TimeStr+'.'); + IF (IsUL(FileName)) THEN + BEGIN + FSplit(FileName,DS,NS,ES); + FindFirst(FileName,AnyFile - Directory - VolumeID - Dos.Hidden - SysFile,DirInfo); + WHILE (DOSError = 0) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + FileName := FExpand(SQOutSP(DS+DirInfo.Name)); + AType := ArcType(FileName); + IF (AType <> 0) AND (AType <> BB) THEN + BEGIN + Star('Converting "'+FileName+'"'); + Ok := TRUE; + S := Copy(FileName,1,Pos('.',FileName))+General.FileArcInfo[BB].Ext; + ConvA(Ok,AType,BB,FileName,S); + IF (Ok) THEN + BEGIN + + Assign(FI,SQOutSP(FileName)); + Reset(FI); + Ok := (IOResult = 0); + IF (Ok) THEN + BEGIN + OldSiz := FileSize(FI); + Close(FI); + END + ELSE + Star('Unable to access '+SQOutSP(FileName)); + + IF (Ok) THEN + IF (NOT Exist(SQOutSP(S))) THEN + BEGIN + Star('Unable to access '+SQOutSP(S)); + SysOpLog('Unable to access '+SQOutSP(S)); + Ok := FALSE; + END; + END; + IF (Ok) THEN + BEGIN + Kill(SQOutSP(FileName)); + + Assign(FI,SQOutSP(S)); + Reset(FI); + Ok := (IOResult = 0); + IF (Ok) THEN + BEGIN + NewSiz := FileSize(FI); + Close(FI); + END + ELSE + Star('Unable to access "'+SQOutSP(S)+'"'); + + IF (Ok) THEN + BEGIN + Inc(C_OldSiz,OldSiz); + Inc(C_NewSiz,NewSiz); + Inc(C_Files); + Star('Old total space took up : '+ConvertBytes(OldSiz,FALSE)); + Star('New total space taken up : '+ConvertBytes(NewSiz,FALSE)); + IF (OldSiz - NewSiz > 0) THEN + Star('Space saved : '+ConvertBytes(OldSiz-NewSiz,FALSE)) + ELSE + Star('Space wasted : '+ConvertBytes(NewSiz-OldSiz,FALSE)); + END; + END + ELSE + BEGIN + SysOpLog('Unable to convert '+SQOutSP(FileName)); + Star('Unable to convert '+SQOutSP(FileName)); + END; + END; + WKey; + FindNext(DirInfo); + END; + END + ELSE + BEGIN + NL; + IF (NOT PYNQ('Search all file areas? ',0,FALSE)) THEN + CvtFiles(F,FileArea,FileName,BB,C_Files,C_OldSiz,C_NewSiz) + ELSE + BEGIN + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + CvtFiles(F,FArea,FileName,BB,C_Files,C_OldSiz,C_NewSiz); + WKey; + Inc(FArea); + END; + END; + END; + SysOpLog('Conversion process completed at '+DateStr+' '+TimeStr+'.'); + NL; + Star('Total archives converted : '+IntToStr(C_Files)); + Star('Old total space took up : '+ConvertBytes(C_OldSiz,FALSE)); + Star('New total space taken up : '+ConvertBytes(C_NewSiz,FALSE)); + IF ((C_OldSiz - C_NewSiz) > 0) THEN + Star('Space saved : '+ConvertBytes((C_OldSiz - C_NewSiz),FALSE)) + ELSE + Star('Space wasted : '+ConvertBytes((C_NewSiz - C_OldSiz),FALSE)); + SysOpLog('Converted '+IntToStr(C_Files)+' archives; old size='+ + ConvertBytes(C_OldSiz,FALSE)+' , new size='+ConvertBytes(C_NewSiz,FALSE)); + END; + END; + END; + 'M' : BEGIN + Ok := FALSE; + FOR Counter := 1 TO 3 DO + IF (General.FileArcComment[Counter] <> '') THEN + Ok := TRUE; + + IF (NOT Ok) THEN + BEGIN + NL; + Print('No comment''s are available.'); + PauseScr(FALSE); + Exit; + END; + + NL; + Print('Comment field update -'); + NL; + Print('Filespec:'); + Prt(':'); + MPL(78); + Input(FileName,78); + IF (FileName = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE + BEGIN + Abort := FALSE; + Next := FALSE; + IF (IsUL(FileName)) THEN + BEGIN + + S := ''; + NL; + FOR Counter := 1 TO 3 DO + IF (General.FileArcComment[Counter] <> '') THEN + BEGIN + S := S + IntToStr(Counter); + Print('^1'+IntToStr(Counter)+'. Archive comment file: ^5'+General.FileArcComment[Counter]); + END; + NL; + Prt('Comment to use [0=Quit]: '); + OneK(Cmd,'0'+S,TRUE,TRUE); + + IF (Cmd IN ['1'..'3']) THEN + BEGIN + FSplit(FileName,DS,NS,ES); + FindFirst(FileName,AnyFile - Directory - VolumeID - Dos.Hidden - SysFile,DirInfo); + WHILE (DOSError = 0) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + FileName := FExpand(SQOutSP(DS+DirInfo.Name)); + AType := ArcType(FileName); + IF (AType <> 0) THEN + BEGIN + Star('Commenting "'+FileName+'"'); + Ok := TRUE; + ArcComment(Ok,AType,(Ord(Cmd) - 48),FileName); + END; + WKey; + FindNext(DirInfo); + END; + END; + END + ELSE + BEGIN + NL; + IF (NOT PYNQ('Search all file areas? ',0,FALSE)) THEN + CmtFiles(F,FileArea,FileName) + ELSE + BEGIN + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + CmtFiles(F,FArea,FileName); + WKey; + Inc(FArea); + END; + END; + END; + END; + Cmd := #0; + END; + 'T' : BEGIN + NL; + Print('File integrity testing -'); + NL; + Print('Filespec:'); + Prt(':'); + MPL(78); + Input(FileName,78); + IF (FileName = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE + BEGIN + NL; + DelBad := PYNQ('Delete files that don''t pass the test? ',0,FALSE); + NL; + Abort := FALSE; + Next := FALSE; + IF (IsUL(FileName)) THEN + BEGIN + FSplit(FileName,DS,NS,ES); + FindFirst(FileName,AnyFile - Directory - VolumeID - DOS.Hidden - SysFile,DirInfo); + WHILE (DOSError = 0) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + FileName := FExpand(SQOutSP(DS+DirInfo.Name)); + AType := ArcType(FileName); + IF (AType <> 0) THEN + BEGIN + Star('Testing "'+FileName+'"'); + Ok := TRUE; + ArcIntegrityTest(Ok,AType,FileName); + IF (Ok) THEN + Star('Passed integrity test.') + ELSE + BEGIN + Star('File "'+FileName+'" didn''t pass integrity test.'); + IF (DelBad) THEN + Kill(FileName); + END; + END; + WKey; + FindNext(DirInfo); + END; + END + ELSE + BEGIN + NL; + IF (NOT PYNQ('Search all file areas? ',0,FALSE)) THEN + TestFiles(F,FileArea,FileName,DelBad) + ELSE + BEGIN + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + TestFiles(F,FArea,FileName,DelBad); + WKey; + Inc(FArea); + END; + END; + END; + END; + END; + END; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + LastError := IOResult; +END; + +END. diff --git a/SOURCE/ARCHIVE3.PAS b/SOURCE/ARCHIVE3.PAS new file mode 100644 index 0000000..7c9d304 --- /dev/null +++ b/SOURCE/ARCHIVE3.PAS @@ -0,0 +1,244 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT Archive3; + +INTERFACE + +PROCEDURE ReZipStuff; + +IMPLEMENTATION + +USES + Dos, + Archive1, + Common, + Execbat, + File0, + File11, + TimeFunc; + +PROCEDURE CvtFiles(FArea: Integer; FileName,ReZipCmd: AStr; VAR TotalFiles: SmallInt; VAR TotalOldSize,TotalNewSize: LongInt); +VAR + S: AStr; + DS: DirStr; + NS: NameStr; + ES: ExtStr; + AType: Byte; + ReturnCode, + DirFileRecNum: Integer; + OldSiz, + NewSiz: LongInt; + Ok: Boolean; +BEGIN + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) AND (NOT (FACDROM IN MemFileArea.FAFlags)) THEN + BEGIN + RecNo(FileInfo,FileName,DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + + IF Exist(MemFileArea.DLPath+FileInfo.FileName) THEN + FileName := MemFileArea.DLPath+FileInfo.FileName + ELSE + FileName := MemFileArea.ULPath+FileInfo.FileName; + + AType := ArcType(FileName); + IF (AType <> 0) THEN + BEGIN + DisplayFileAreaHeader; + NL; + Star('Converting "'+SQOutSp(FileName)+'"'); + Ok := FALSE; + IF (NOT Exist(FileName)) THEN + Star('File "'+SQOutSp(FileName)+'" doesn''t exist.') + ELSE + BEGIN + + IF (ReZipCmd <> '') THEN + BEGIN + OldSiz := GetFileSize(FileName); + + ExecBatch(Ok,TempDir+'ARC\',ReZipCmd+' '+SQOutSp(FileName),-1,ReturnCode,FALSE); + + NewSiz := GetFileSize(FileName); + + FileInfo.FileSize := NewSiz; + + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,FileInfo); + + END + ELSE + BEGIN + Ok := TRUE; + S := FileName; + + OldSiz := GetFileSize(FileName); + + ConvA(Ok,AType,AType,SQOutSp(FileName),SQOutSp(S)); + + IF (Ok) THEN + IF (NOT Exist(SQOutSp(S))) THEN + BEGIN + Star('Unable to access "'+SQOutSp(S)+'"'); + SysOpLog('Unable to access '+SQOutSp(S)); + Ok := FALSE; + END; + + IF (Ok) THEN + BEGIN + + FileInfo.FileName := Align(StripName(SQOutSp(S))); + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,FileInfo); + + FSplit(FileName,DS,NS,ES); + FileName := DS+NS+'.#$%'; + Kill(FileName); + IF (IOResult <> 0) THEN + BEGIN + Star('Unable to erase '+SQOutSp(FileName)); + SysOpLog('Unable to erase '+SQOutSp(FileName)); + END; + + Ok := Exist(SQOutSp(S)); + IF (NOT Ok) THEN + BEGIN + Star('Unable to access '+SQOutSp(S)); + SysOpLog('Unable to access '+SQOutSp(S)); + END + ELSE + BEGIN + NewSiz := GetFileSize(S); + + FileInfo.FileSize := NewSiz; + + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,FileInfo); + ArcComment(Ok,AType,MemFileArea.CmtType,SQOutSp(S)); + END; + END + ELSE + BEGIN + SysOpLog('Unable to convert '+SQOutSp(FileName)); + Star('Unable to convert '+SQOutSp(FileName)); + END; + END; + + IF (Ok) THEN + BEGIN + Inc(TotalOldSize,OldSiz); + Inc(TotalNewSize,NewSiz); + Inc(TotalFiles); + Star('Old total space took up : '+ConvertBytes(OldSiz,FALSE)); + Star('New total space taken up : '+ConvertBytes(NewSiz,FALSE)); + IF ((OldSiz - NewSiz) > 0) THEN + Star('Space saved : '+ConvertBytes(OldSiz - NewSiz,FALSE)) + ELSE + Star('Space wasted : '+ConvertBytes(NewSiz - OldSiz,FALSE)); + END; + + END; + END; + WKey; + NRecNo(FileInfo,DirFileRecNum); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; + LastError := IOResult; +END; + +PROCEDURE ReZipStuff; +TYPE + TotalsRecordType = RECORD + TotalFiles: SmallInt; + TotalOldSize, + TotalNewSize: LongInt + END; +VAR + TotalsRecord: TotalsRecordType; + FileName: Str12; + ReZipCmd: Str78; + FArea, + SaveFileArea: Integer; +BEGIN + FillChar(TotalsRecord,SizeOf(TotalsRecord),0); + NL; + Print('Re-compress archives -'); + NL; + Print('Filespec:'); + Prt(':'); + MPL(12); + Input(FileName,12); + IF (FileName = '') THEN + BEGIN + NL; + Print('Aborted!'); + Exit; + END; + ReZipCmd := ''; + NL; + Print('^7Do you wish to use a REZIP external utility?'); + IF PYNQ('(such as REZIP.EXE)? (Y/N): ',0,FALSE) THEN + BEGIN + NL; + Print('Enter commandline (example: "REZIP"): '); + Prt(':'); + Input(ReZipCmd,78); + IF (ReZipCmd = '') THEN + BEGIN + NL; + Print('Aborted.'); + Exit; + END; + END; + NL; + Print('Conversion process initiated: '+DateStr+' '+TimeStr+'.'); + SysOpLog('Conversion process initiated: '+DateStr+' '+TimeStr+'.'); + NL; + Abort := FALSE; + Next := FALSE; + IF NOT PYNQ('Search all file areas? ',0,FALSE) THEN + CvtFiles(FileArea,FileName,ReZipCmd,TotalsRecord.TotalFiles,TotalsRecord.TotalOldSize,TotalsRecord.TotalNewSize) + ELSE + BEGIN + SaveFileArea := FileArea; + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + CvtFiles(FArea,FileName,ReZipCmd,TotalsRecord.TotalFiles,TotalsRecord.TotalOldSize,TotalsRecord.TotalNewSize); + WKey; + Inc(FArea); + END; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; + NL; + Print('Conversion process complete at '+DateStr+' '+TimeStr+'.'); + SysOpLog('Conversion process complete at '+DateStr+' '+TimeStr+'.'); + NL; + Star('Total archives converted : '+IntToStr(TotalsRecord.TotalFiles)); + Star('Old total space took up : '+ConvertBytes(TotalsRecord.TotalOldSize,FALSE)); + Star('New total space taken up : '+ConvertBytes(TotalsRecord.TotalNewSize,FALSE)); + + IF ((TotalsRecord.TotalOldSize - TotalsRecord.TotalNewSize) > 0) THEN + Star('Space saved : '+ConvertBytes(TotalsRecord.TotalOldSize - TotalsRecord.TotalNewSize,FALSE)) + ELSE + Star('Space wasted : '+ConvertBytes(TotalsRecord.TotalNewSize - TotalsRecord.TotalOldSize,FALSE)); + + + SysOpLog('Converted '+IntToStr(TotalsRecord.TotalFiles)+' archives; old size='+ + ConvertBytes(TotalsRecord.TotalOldSize,FALSE)+' , new size='+ConvertBytes(TotalsRecord.TotalNewSize,FALSE)); +END; + +END. diff --git a/SOURCE/ARCVIEW.PAS b/SOURCE/ARCVIEW.PAS new file mode 100644 index 0000000..d02c5c6 --- /dev/null +++ b/SOURCE/ARCVIEW.PAS @@ -0,0 +1,852 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT ArcView; + +INTERFACE + +USES + Common; + +FUNCTION ValidIntArcType(FileName: Str12): Boolean; +PROCEDURE ViewInternalArchive(FileName: AStr); +PROCEDURE ViewDirInternalArchive; + +IMPLEMENTATION + +USES + Dos, + File0, + File14, + TimeFunc; + +CONST + MethodType: ARRAY [0..21] OF STRING[10] = + ('Directory ', {* Directory marker *} + 'Unknown! ', {* Unknown compression type *} + 'Stored ', {* No compression *} + 'Packed ', {* Repeat-Byte compression *} + 'Squeezed ', {* Huffman with repeat-Byte compression *} + 'crunched ', {* Obsolete LZW compression *} + 'Crunched ', {* LZW 9-12 bit with repeat-Byte compression *} + 'Squashed ', {* LZW 9-13 bit compression *} + 'Crushed ', {* LZW 2-13 bit compression *} + 'Shrunk ', {* LZW 9-13 bit compression *} + 'Reduced 1 ', {* Probabilistic factor 1 compression *} + 'Reduced 2 ', {* Probabilistic factor 2 compression *} + 'Reduced 3 ', {* Probabilistic factor 3 compression *} + 'Reduced 4 ', {* Probabilistic factor 4 compression *} + 'Frozen ', {* Modified LZW/Huffman compression *} + 'Imploded ', {* Shannon-Fano tree compression *} + 'Compressed', + 'Method 1 ', + 'Method 2 ', + 'Method 3 ', + 'Method 4 ', + 'Deflated '); + +TYPE + ArcRecordType = RECORD {* structure of ARC archive file header *} + FileName: ARRAY [0..12] OF Char; {* FileName *} + C_Size: LongInt; {* compressed size *} + Mod_Date: SmallInt; {* last mod file Date *} + Mod_Time: SmallInt; {* last mod file Time *} + CRC: SmallInt; {* CRC *} + U_Size: LongInt; {* uncompressed size *} + END; + + ZipRecordType = RECORD {* structure of ZIP archive file header *} + Version: SmallInt; {* Version needed to extract *} + Bit_Flag: SmallInt; {* General purpose bit flag *} + Method: SmallInt; {* compression Method *} + Mod_Time: SmallInt; {* last mod file Time *} + Mod_Date: SmallInt; {* last mod file Date *} + CRC: LongInt; {* CRC-32 *} + C_Size: LongInt; {* compressed size *} + U_Size: LongInt; {* uncompressed size *} + F_Length: SmallInt; {* FileName Length *} + E_Length: SmallInt; {* extra field Length *} + END; + + ZooRecordType = RECORD {* structure of ZOO archive file header *} + Tag: LongInt; {* Tag -- redundancy check *} + Typ: Byte; {* TYPE of directory entry (always 1 for now) *} + Method: Byte; {* 0 = Stored, 1 = Crunched *} + Next: LongInt; {* position of Next directory entry *} + Offset: LongInt; {* position of this file *} + Mod_Date: SmallWord; {* modification Date (DOS format) *} + Mod_Time: SmallWord; {* modification Time (DOS format) *} + CRC: SmallWord; {* CRC *} + U_Size: LongInt; {* uncompressed size *} + C_Size: LongInt; {* compressed size *} + Major_V: Char; {* major Version number *} + Minor_V: Char; {* minor Version number *} + Deleted: Byte; {* 0 = active, 1 = Deleted *} + Struc: Char; {* file structure if any *} + Comment: LongInt; {* location of file Comment (0 = none) *} + Cmt_Size: SmallWord; {* Length of Comment (0 = none) *} + FName: ARRAY [0..12] OF Char; {* FileName *} + Var_DirLen: SmallInt; {* Length of variable part of dir entry *} + TZ: Char; {* timezone where file was archived *} + Dir_Crc: SmallWord; {* CRC of directory entry *} + END; + + LZHRecordType = RECORD {* structure of LZH archive file header *} + H_Length: Byte; {* Length of header *} + H_Cksum: Byte; {* checksum of header bytes *} + Method: ARRAY [1..5] OF Char; {* compression TYPE "-lh#-" *} + C_Size: LongInt; {* compressed size *} + U_Size: LongInt; {* uncompressed size *} + Mod_Time: SmallInt;{* last mod file Time *} + Mod_Date: SmallInt;{* last mod file Date *} + Attrib: SmallInt; {* file attributes *} + F_Length: Byte; {* Length of FileName *} + CRC: SmallInt; {* CRC *} + END; + + ARJRecordType = RECORD + FirstHdrSize: Byte; + ARJVersion: Byte; + ARJRequired: Byte; + HostOS: Byte; + Flags: Byte; + Method: Byte; + FileType: Byte; + GarbleMod: Byte; + Time, + Date: SmallInt; + CompSize: LongInt; + OrigSize: LongInt; + OrigCRC: ARRAY[1..4] OF Byte; + EntryName: SmallWord; + AccessMode: SmallWord; + HostData: SmallWord; + END; + + OutRec = RECORD {* output information structure *} + FileName: AStr; {* output file name *} + Date, {* output Date *} + Time, {* output Time *} + Method: SmallInt; {* output storage type *} + CSize, {* output compressed size *} + USize: LongInt; {* output uncompressed size *} + END; + +PROCEDURE AbEnd(VAR Aborted: Boolean); +BEGIN + NL; + Print('^7** ^5Error processing archive^7 **'); + Aborted := TRUE; + Abort := TRUE; + Next := TRUE; +END; + +PROCEDURE Details(Out: OutRec; + VAR Level, + NumFiles: Integer; + VAR TotalCompSize, + TotalUnCompSize: LongInt); +VAR + OutP: AStr; + AMPM: Str2; + DT: DateTime; + Ratio: LongInt; +BEGIN + Out.FileName := AllCaps(Out.FileName); + DT.Day := Out.Date AND $1f; {* Day = bits 4-0 *} + DT.Month := (Out.Date SHR 5) AND $0f; {* Month = bits 8-5 *} + DT.Year := ((Out.Date SHR 9) AND $7f) + 80; {* Year = bits 15-9 *} + DT.Min := (Out.Time SHR 5) AND $3f; {* Minute = bits 10-5 *} + DT.Hour := (Out.Time SHR 11) AND $1f; {* Hour = bits 15-11 *} + + IF (DT.Month > 12) THEN + Dec(DT.Month,12); {* adjust for Month > 12 *} + IF (DT.Year > 99) THEN + Dec(DT.Year,100); {* adjust for Year > 1999 *} + IF (DT.Hour > 23) THEN + Dec(DT.Hour,24); {* adjust for Hour > 23 *} + IF (DT.Min > 59) THEN + Dec(DT.Min,60); {* adjust for Minute > 59 *} + + ConvertAmPm(DT.Hour,AmPm); + + IF (Out.USize = 0) THEN + Ratio := 0 + ELSE {* Ratio is 0% for null-Length file *} + Ratio := (100 - ((Out.CSize * 100) DIV Out.USize)); + IF (Ratio > 99) THEN + Ratio := 99; + + OutP := '^4'+PadRightStr(FormatNumber(Out.USize),13)+ + ' '+PadRightStr(FormatNumber(Out.CSize),13)+ + ' '+PadRightInt(Ratio,2)+'%'+ + ' ^9'+MethodType[Out.Method]+ + ' ^7'+ZeroPad(IntToStr(DT.Month))+ + '/'+ZeroPad(IntToStr(DT.Day))+ + '/'+ZeroPad(IntToStr(DT.Year))+ + ' '+ZeroPad(IntToStr(DT.Hour))+ + ':'+ZeroPad(IntToStr(DT.Min))+ + AMPM[1]+' ^5'; + + IF (Level > 0) THEN + OutP := OutP + PadRightStr('',Level); {* spaces for dirs (ARC only)*} + + OutP := OutP + Out.FileName; + + PrintACR(OutP); + + IF (Out.Method = 0) THEN + Inc(Level) {* bump dir Level (ARC only) *} + ELSE + BEGIN + Inc(TotalCompSize,Out.CSize); {* adjust accumulators and counter *} + Inc(TotalUnCompSize,Out.USize); + Inc(NumFiles); + END; +END; + +PROCEDURE Final(NumFiles: Integer; + TotalCompSize, + TotalUnCompSize: LongInt); +VAR + OutP: AStr; + Ratio: LongInt; +BEGIN + IF (TotalUnCompSize = 0) THEN + Ratio := 0 + ELSE + Ratio := (100 - ((TotalCompSize * 100) DIV TotalUnCompSize)); + IF (Ratio > 99) THEN + Ratio := 99; + + OutP := '^4'+PadRightStr(FormatNumber(TotalUnCompSize),13)+ + ' '+PadRightStr(FormatNumber(TotalCompSize),13)+ + ' '+PadRightInt(Ratio,2)+ + '% ^5'+IntToStr(NumFiles)+' '+Plural('file',NumFiles); + PrintACR('^4------------- ------------- --- ------------'); + PrintACR(OutP); +END; + +FUNCTION GetByte(VAR F: FILE; VAR Aborted: Boolean): Char; +VAR + C: Char; + NumRead: Word; +BEGIN + IF (NOT Aborted) THEN + BEGIN + BlockRead(F,C,1,NumRead); + IF (NumRead = 0) THEN + BEGIN + Close(F); + AbEnd(Aborted); + END; + GetByte := C; + END; +END; + +PROCEDURE ZIP_Proc(VAR F: FILE; + VAR Out: OutRec; + VAR Level, + NumFiles: Integer; + VAR TotalCompSize, + TotalUnCompSize: LongInt; + VAR Aborted: Boolean); +VAR + ZIP: ZipRecordType; + C: Char; + Counter: Integer; + NumRead: Word; + Signature: LongInt; +BEGIN + WHILE (NOT Aborted) DO + BEGIN + BlockRead(F,Signature,4,NumRead); + IF (Signature = $02014b50) OR (Signature = $06054b50) THEN + Exit; + IF (NumRead <> 4) OR (Signature <> $04034b50) THEN + BEGIN + AbEnd(Aborted); + Exit; + END; + BlockRead(F,ZIP,26,NumRead); + IF (NumRead <> 26) THEN + BEGIN + AbEnd(Aborted); + Exit; + END; + FOR Counter := 1 TO ZIP.F_Length DO + Out.FileName[Counter] := GetByte(F,Aborted); + Out.FileName[0] := Chr(ZIP.F_Length); + FOR Counter := 1 TO ZIP.E_Length DO + C := GetByte(F,Aborted); + Out.Date := ZIP.Mod_Date; + Out.Time := ZIP.Mod_Time; + Out.CSize := ZIP.C_Size; + Out.USize := ZIP.U_Size; + CASE ZIP.Method OF + 0 : Out.Method := 2; + 1 : Out.Method := 9; + 2,3,4,5 : + Out.Method := (ZIP.Method + 8); + 6 : Out.Method := 15; + 8 : Out.Method := 21; + ELSE + Out.Method := 1; + END; + Details(Out,Level,NumFiles,TotalCompSize,TotalUnCompSize); + IF (Abort) THEN + Exit; + Seek(F,(FilePos(F) + ZIP.C_Size)); + IF (IOResult <> 0) THEN + AbEnd(Aborted); + IF (Abort) THEN + Exit; + END; +END; + +PROCEDURE ARJ_Proc(VAR ArjFile: FILE; + VAR Out: OutRec; + VAR Level, + NumFiles: Integer; + VAR TotalCompSize, + TotalUnCompSize: LongInt; + VAR Aborted: Boolean); +TYPE + ARJSignature = RECORD + MagicNumber: SmallWord; + BasicHdrSiz: SmallWord; + END; +VAR + Hdr: ARJRecordType; + Sig: ARJSignature; + FileName, + FileTitle: AStr; + JunkByte: Byte; + Counter: Integer; + NumRead, + ExtSize: Word; + HeaderCrc: LongInt; +BEGIN + BlockRead(ArjFile,Sig,SizeOf(Sig)); + IF (IOResult <> 0) OR (Sig.MagicNumber <> $EA60) THEN + Exit + ELSE + BEGIN + BlockRead(ArjFile,Hdr,SizeOf(Hdr),NumRead); + Counter := 0; + REPEAT + Inc(Counter); + BlockRead(ArjFile,FileName[Counter],1); + UNTIL (FileName[Counter] = #0); + FileName[0] := Chr(Counter - 1); + REPEAT + BlockRead(ArjFile,JunkByte,1); + UNTIL (JunkByte = 0); + BlockRead(ArjFile,HeaderCRC,4); + BlockRead(ArjFile,ExtSize,2); + IF (ExtSize > 0) THEN + Seek(ArjFile,FilePos(ArjFile) + ExtSize + 4); + BlockRead(ArjFile,Sig,SizeOf(Sig)); + WHILE (Sig.BasicHdrSiz > 0) AND (NOT Abort) AND (IOResult = 0) DO + BEGIN + BlockRead(ArjFile,Hdr,SizeOf(Hdr),NumRead); + Counter := 0; + REPEAT + Inc(Counter); + BlockRead(ArjFile,FileName[Counter],1); + UNTIL (FileName[Counter] = #0); + FileName[0] := Chr(Counter - 1); + Out.FileName := FileName; + Out.Date := Hdr.Date; + Out.Time := Hdr.Time; + IF (Hdr.Method = 0) THEN + Out.Method := 2 + ELSE + Out.Method := (Hdr.Method + 16); + Out.CSize := Hdr.CompSize; + Out.USize := Hdr.OrigSize; + Details(Out,Level,NumFiles,TotalCompSize,TotalUnCompSize); + IF (Abort) THEN + Exit; + REPEAT + BlockRead(ArjFile,JunkByte,1); + UNTIL (JunkByte = 0); + BlockRead(ArjFile,HeaderCRC,4); + BlockRead(ArjFile,ExtSize,2); + Seek(ArjFile,(FilePos(ArjFile) + Hdr.CompSize)); + BlockRead(ArjFile,Sig,SizeOf(Sig)); + END; + END; +END; + +PROCEDURE ARC_Proc(VAR F: FILE; + VAR Out: OutRec; + VAR Level, + NumFiles: Integer; + VAR TotalCompSize, + TotalUnCompSize: LongInt; + VAR Aborted: Boolean); +VAR + Arc: ArcRecordType; + C: Char; + Counter, + Method: Integer; + NumRead: Word; +BEGIN + REPEAT + C := GetByte(F,Aborted); + Method := Ord(GetByte(F,Aborted)); + CASE Method OF + 0 : Exit; + 1,2 : + Out.Method := 2; + 3,4,5,6,7 : + Out.Method := Method; + 8,9,10 : + Out.Method := (Method - 2); + 30 : Out.Method := 0; + 31 : Dec(Level); + ELSE + Out.Method := 1; + END; + IF (Method <> 31) THEN + BEGIN + BlockRead(F,Arc,23,NumRead); + IF (NumRead <> 23) THEN + BEGIN + AbEnd(Aborted); + Exit; + END; + IF (Method = 1) THEN + Arc.U_Size := Arc.C_Size + ELSE + BEGIN + BlockRead(F,Arc.U_Size,4,NumRead); + IF (NumRead <> 4) THEN + BEGIN + AbEnd(Aborted); + Exit; + END; + END; + Counter := 0; + REPEAT + Inc(Counter); + Out.FileName[Counter] := Arc.FileName[Counter - 1]; + UNTIL (Arc.FileName[Counter] = #0) OR (Counter = 13); + Out.FileName[0] := Chr(Counter); + Out.Date := Arc.Mod_Date; + Out.Time := Arc.Mod_Time; + IF (Method = 30) THEN + BEGIN + Arc.C_Size := 0; + Arc.U_Size := 0; + END; + Out.CSize := Arc.C_Size; + Out.USize := Arc.U_Size; + Details(Out,Level,NumFiles,TotalCompSize,TotalUnCompSize); + IF (Abort) THEN + Exit; + IF (Method <> 30) THEN + BEGIN + Seek(F,(FilePos(F) + Arc.C_Size)); + IF (IOResult <> 0) THEN + BEGIN + AbEnd(Aborted); + Exit; + END; + END; + END; + UNTIL (C <> #$1a) OR (Aborted); + IF (NOT Aborted) THEN + AbEnd(Aborted); +END; + +PROCEDURE ZOO_Proc(VAR F: FILE; + VAR Out: OutRec; + VAR Level, + NumFiles: Integer; + VAR TotalCompSize, + TotalUnCompSize: LongInt; + VAR Aborted: Boolean); +VAR + ZOO: ZooRecordType; + ZOO_LongName, + ZOO_DirName: AStr; + C: Char; + NamLen, + DirLen: Byte; + Counter, + Method: Integer; + NumRead: Word; + ZOO_Temp, + ZOO_Tag: LongInt; +BEGIN + + FOR Counter := 0 TO 19 DO + C := GetByte(F,Aborted); + BlockRead(F,ZOO_Tag,4,NumRead); + IF (NumRead <> 4) THEN + AbEnd(Aborted); + IF (ZOO_Tag <> $fdc4a7dc) THEN + AbEnd(Aborted); + BlockRead(F,ZOO_Temp,4,NumRead); + IF (NumRead <> 4) THEN + AbEnd(Aborted); + Seek(F,ZOO_Temp); + IF (IOResult <> 0) THEN + AbEnd(Aborted); + + WHILE (NOT Aborted) DO + BEGIN + BlockRead(F,ZOO,56,NumRead); + IF (NumRead <> 56) THEN + BEGIN + AbEnd(Aborted); + Exit; + END; + IF (ZOO.Tag <> $fdc4a7dc) THEN + AbEnd(Aborted); + IF (Abort) OR (ZOO.Next = 0) THEN + Exit; + NamLen := Ord(GetByte(F,Aborted)); + DirLen := Ord(GetByte(F,Aborted)); + ZOO_LongName := ''; + ZOO_DirName := ''; + + IF (NamLen > 0) THEN + FOR Counter := 1 TO NamLen DO + ZOO_LongName := ZOO_LongName + GetByte(F,Aborted); + + IF (DirLen > 0) THEN + BEGIN + FOR Counter := 1 TO DirLen DO + ZOO_DirName := ZOO_DirName + GetByte(F,Aborted); + IF (ZOO_DirName[Length(ZOO_DirName)] <> '/') THEN + ZOO_DirName := ZOO_DirName + '/'; + END; + IF (ZOO_LongName <> '') THEN + Out.FileName := ZOO_LongName + ELSE + BEGIN + Counter := 0; + REPEAT + Inc(Counter); + Out.FileName[Counter] := ZOO.FName[Counter - 1]; + UNTIL (ZOO.FName[Counter] = #0) OR (Counter = 13); + Out.FileName[0] := Chr(Counter); + Out.FileName := ZOO_DirName+Out.FileName; + END; + Out.Date := ZOO.Mod_Date; + Out.Time := ZOO.Mod_Time; + Out.CSize := ZOO.C_Size; + Out.USize := ZOO.U_Size; + Method := ZOO.Method; + CASE Method OF + 0 : Out.Method := 2; + 1 : Out.Method := 6; + ELSE + Out.Method := 1; + END; + IF NOT (ZOO.Deleted = 1) THEN + Details(Out,Level,NumFiles,TotalCompSize,TotalUnCompSize); + IF (Abort) THEN + Exit; + Seek(F,ZOO.Next); + IF (IOResult <> 0) THEN + BEGIN + AbEnd(Aborted); + Exit; + END; + END; +END; + +PROCEDURE LZH_Proc(VAR F: FILE; + VAR Out: OutRec; + VAR Level, + NumFiles: Integer; + VAR TotalCompSize, + TotalUnCompSize: LongInt; + VAR Aborted: Boolean); +VAR + LZH: LZHRecordType; + C, + Method: Char; + Counter: Integer; + NumRead: Word; +BEGIN + WHILE (NOT Aborted) DO + BEGIN + C := GetByte(F,Aborted); + IF (C = #0) THEN + Exit + ELSE + LZH.H_Length := Ord(C); + C := GetByte(F,Aborted); + LZH.H_Cksum := Ord(C); + BlockRead(F,LZH.Method,5,NumRead); + IF (NumRead <> 5) THEN + BEGIN + AbEnd(Aborted); + Exit; + END; + IF ((LZH.Method[1] <> '-') OR (LZH.Method[2] <> 'l') OR (LZH.Method[3] <> 'h')) THEN + BEGIN + AbEnd(Aborted); + Exit; + END; + BlockRead(F,LZH.C_Size,15,NumRead); + IF (NumRead <> 15) THEN + BEGIN + AbEnd(Aborted); + Exit; + END; + FOR Counter := 1 TO LZH.F_Length DO + Out.FileName[Counter] := GetByte(F,Aborted); + Out.FileName[0] := Chr(LZH.F_Length); + IF ((LZH.H_Length - LZH.F_Length) = 22) THEN + BEGIN + BlockRead(F,LZH.CRC,2,NumRead); + IF (NumRead <> 2) THEN + BEGIN + AbEnd(Aborted); + Exit; + END; + END; + Out.Date := LZH.Mod_Date; + Out.Time := LZH.Mod_Time; + Out.CSize := LZH.C_Size; + Out.USize := LZH.U_Size; + Method := LZH.Method[4]; + CASE Method OF + '0' : Out.Method := 2; + '1' : Out.Method := 14; + ELSE + Out.Method := 1; + END; + Details(Out,Level,NumFiles,TotalCompSize,TotalUnCompSize); + Seek(F,(FilePos(F) + LZH.C_Size)); + IF (IOResult <> 0) THEN + AbEnd(Aborted); + IF (Abort) THEN + Exit; + END; +END; + +FUNCTION ValidIntArcType(FileName: Str12): Boolean; +CONST + ArcTypes: ARRAY [1..7] OF Str3 = ('ZIP','ARC','PAK','ZOO','LZH','ARK','ARJ'); +VAR + Counter: Byte; +BEGIN + ValidIntArcType := FALSE; + FOR Counter := 1 TO 7 DO + IF (ArcTypes[Counter] = AllCaps(Copy(FileName,(Pos('.',FileName) + 1),3))) THEN + ValidIntArcType := TRUE; +END; + +PROCEDURE ViewInternalArchive(FileName: AStr); +VAR + LZH_Method: ARRAY [1..5] OF Char; + F: FILE; + (* + DirInfo: SearchRec; + *) + Out: OutRec; + C: Char; + LZH_H_Length, + Counter, + ArcType: Byte; + RCode, + FileType, + Level, + NumFiles: Integer; + NumRead: Word; + TotalUnCompSize, + TotalCompSize: LongInt; + Aborted: Boolean; +BEGIN + FileName := SQOutSp(FileName); + + IF (Pos('*',FileName) <> 0) OR (Pos('?',FileName) <> 0) THEN + BEGIN + FindFirst(FileName,AnyFile - Directory - VolumeID - Hidden - SysFile,DirInfo); + IF (DOSError = 0) THEN + FileName := DirInfo.Name; + END; + + IF ((Exist(FileName)) AND (NOT Abort) AND (NOT HangUp)) THEN + BEGIN + + ArcType := 1; + WHILE (General.FileArcInfo[ArcType].Ext <> '') AND + (General.FileArcInfo[ArcType].Ext <> Copy(FileName,(Length(FileName) - 2),3)) AND + (ArcType < MaxArcs + 1) DO + Inc(ArcType); + + IF NOT ((General.FileArcInfo[ArcType].Ext = '') OR (ArcType = 7)) THEN + BEGIN + IF (General.FileArcInfo[ArcType].ListLine[1] = '/') AND + (General.FileArcInfo[ArcType].ListLine[2] IN ['1'..'5']) AND + (Length(General.FileArcInfo[ArcType].ListLine) = 2) THEN + BEGIN + Aborted := FALSE; + Abort := FALSE; + Next := FALSE; + NL; + PrintACR('^3'+StripName(FileName)+':'); + NL; + IF (NOT Abort) THEN + BEGIN + Assign(F,FileName); + Reset(F,1); + C := GetByte(F,Aborted); + CASE C OF + #$1a : FileType := 1; + 'P' : BEGIN + IF (GetByte(F,Aborted) <> 'K') THEN + AbEnd(Aborted); + FileType := 2; + END; + 'Z' : BEGIN + FOR Counter := 0 TO 1 DO + IF (GetByte(F,Aborted) <> 'O') THEN + AbEnd(Aborted); + FileType := 3; + END; + #96 : BEGIN + IF (GetByte(F,Aborted) <> #234) THEN + AbEnd(Aborted); + FileType := 5; + END; + ELSE + BEGIN + LZH_H_Length := Ord(C); + C := GetByte(F,Aborted); + FOR Counter := 1 TO 5 DO + LZH_Method[Counter] := GetByte(F,Aborted); + IF ((LZH_Method[1] = '-') AND (LZH_Method[2] = 'l') AND (LZH_Method[3] = 'h')) THEN + FileType := 4 + ELSE + AbEnd(Aborted); + END; + END; + Reset(F,1); + Level := 0; + NumFiles := 0; + TotalCompSize := 0; + TotalUnCompSize := 0; + AllowContinue := TRUE; + PrintACR('^3 Length Size Now % Method Date Time FileName'); + PrintACR('^4------------- ------------- --- ---------- -------- ------ ------------'); + CASE FileType OF + 1 : ARC_Proc(F,Out,Level,NumFiles,TotalCompSize,TotalUnCompSize,Aborted); + 2 : ZIP_Proc(F,Out,Level,NumFiles,TotalCompSize,TotalUnCompSize,Aborted); + 3 : ZOO_Proc(F,Out,Level,NumFiles,TotalCompSize,TotalUnCompSize,Aborted); + 4 : LZH_Proc(F,Out,Level,NumFiles,TotalCompSize,TotalUnCompSize,Aborted); + 5 : ARJ_Proc(F,Out,Level,NumFiles,TotalCompSize,TotalUnCompSize,Aborted); + END; + Final(NumFiles,TotalCompSize,TotalUnCompSize); + Close(F); + AllowContinue := FALSE; + END; + END + ELSE + BEGIN + NL; + Prompt('^3Archive '+FileName+': ^4Please wait....'); + ShellDOS(FALSE,FunctionalMCI(General.FileArcInfo[ArcType].ListLine,FileName,'')+' >shell.$$$',RCode); + BackErase(15); + PFL('SHELL.$$$'); + Kill('SHELL.$$$'); + END; + END; + END; +END; + +PROCEDURE ViewDirInternalArchive; +VAR + FileName: Str12; + DirFileRecNum: Integer; + Found, + LastArc, + LastGif: Boolean; +BEGIN + { + NL; + Print('^9Enter the name of the archive(s) you would like to view:'); + } + lRGLngStr(25,FALSE); + FileName := ''; + { Print(FString.lGFNLine1); } + lRGLngStr(28,FALSE); + { Prt(FString.GFNLine2); } + lRGLngStr(29,FALSE); + GetFileName(FileName); + LastArc := FALSE; + LastGif := FALSE; + AllowContinue := TRUE; + Found := FALSE; + Abort := FALSE; + Next := FALSE; + RecNo(FileInfo,FileName,DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + IF IsGIFExt(FileInfo.FileName) THEN + BEGIN + LastArc := FALSE; + IF (NOT LastGif) THEN + BEGIN + LastGif := TRUE; + NL; + PrintACR('^3Filename.Ext^4:^3Resolution ^4:^3Num Colors^4:^3Signature'); + PrintACR('^4============:===========:==========:==============='); + END; + IF Exist(MemFileArea.DLPath+FileInfo.FileName) THEN + BEGIN + PrintACR(GetGIFSpecs(MemFileArea.DLPath+SQOutSp(FileInfo.FileName),FileInfo.Description,1)); + Found := TRUE; + END + ELSE + BEGIN + PrintACR(GetGIFSpecs(MemFileArea.ULPath+SQOutSp(FileInfo.FileName),FileInfo.Description,1)); + Found := TRUE; + END; + END + ELSE IF ValidIntArcType(FileInfo.FileName) THEN + BEGIN + LastGif := FALSE; + IF (NOT LastArc) THEN + LastArc := TRUE; + IF Exist(MemFileArea.DLPath+FileInfo.FileName) THEN + BEGIN + ViewInternalArchive(MemFileArea.DLPath+FileInfo.FileName); + Found := TRUE; + END + ELSE + BEGIN + ViewInternalArchive(MemFileArea.ULPath+FileInfo.FileName); + Found := TRUE; + END; + END; + WKey; + NRecNo(FileInfo,DirFileRecNum); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + AllowContinue := FALSE; + IF (NOT Found) THEN + BEGIN + NL; + Print('File not found.'); + END; + LastError := IOResult; +END; + +END. \ No newline at end of file diff --git a/SOURCE/AUTOMSG.PAS b/SOURCE/AUTOMSG.PAS new file mode 100644 index 0000000..f53fe7c --- /dev/null +++ b/SOURCE/AUTOMSG.PAS @@ -0,0 +1,163 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT AutoMsg; + +INTERFACE + +PROCEDURE ReadAutoMsg; +PROCEDURE WriteAutoMsg; +PROCEDURE ReplyAutoMsg; + +IMPLEMENTATION + +USES + Common, + Email, + Mail0, + Mail1; + +PROCEDURE ReadAutoMsg; +VAR + AutoMsgFile: Text; + TempStr: AStr; + Counter, + LenTempStr: Byte; +BEGIN + Assign(AutoMsgFile,General.MiscPath+'AUTO.ASC'); + Reset(AutoMsgFile); + IF (IOResult <> 0) THEN + Print('%LFNo auto-message available.') + ELSE + BEGIN + ReadLn(AutoMsgFile,TempStr); + CASE TempStr[1] OF + '@' : IF (AACS(General.AnonPubRead)) THEN + TempStr := Copy(TempStr,2,Length(TempStr))+' (Posted Anonymously)' + ELSE + TempStr := 'Anonymous'; + '!' : IF (CoSysOp) THEN + TempStr := Copy(TempStr,2,Length(TempStr))+' (Posted Anonymously)' + ELSE + TempStr := 'Anonymous'; + END; + NL; + Print(lRGLngStr(10,TRUE){FString.AutoMsgT}+TempStr); + LenTempStr := 0; + REPEAT + ReadLn(AutoMsgFile,TempStr); + IF (LennMCI(TempStr) > LenTempStr) THEN + LenTempStr := LennMCI(TempStr); + UNTIL (EOF(AutoMsgFile)); + IF (LenTempStr >= ThisUser.LineLen) THEN + LenTempStr := (ThisUser.LineLen - 1); + Reset(AutoMsgFile); + ReadLn(AutoMsgFile,TempStr); + TempStr := lRGLngStr(11,TRUE); + UserColor(0); + IF ((NOT OkANSI) AND (NOT OkAvatar) AND (Ord(TempStr[1]{FString.AutoM}) > 128) OR (TempStr[1]{FString.AutoM} = #32)) THEN + NL + ELSE + BEGIN + FOR Counter := 1 TO LenTempStr DO + OutKey(TempStr[1]{FString.AutoM}); + NL; + END; + REPEAT + ReadLn(AutoMsgFile,TempStr); + PrintACR('^3'+TempStr); + UNTIL EOF(AutoMsgFile) OR (Abort) OR (HangUp); + Close(AutoMsgFile); + TempStr := lRGLngStr(11,TRUE); + UserColor(0); + IF ((NOT OkANSI) AND (NOT OkAvatar) AND (Ord(TempStr[1]{FString.AutoM}) > 128) OR (TempStr[1]{FString.AutoM} = #32)) THEN + NL + ELSE + BEGIN + FOR Counter := 1 TO LenTempStr DO + OutKey(TempStr[1]{FString.AutoM}); + NL; + END; + PauseScr(FALSE); + END; + LastError := IOResult; +END; + +PROCEDURE WriteAutoMsg; +VAR + AutoMsgFile1, + AutoMsgFile2: Text; + MHeader: MHeaderRec; + TempStr: AStr; +BEGIN + IF (RAMsg IN ThisUser.Flags) THEN + Print('%LFYou are restricted from writing auto-messages.') + ELSE + BEGIN + InResponseTo := ''; + MHeader.Status := []; + IF (InputMessage(TRUE,FALSE,'Auto-Message',MHeader,General.MiscPath+'AUTO'+IntToStr(ThisNode)+'.TMP',78,500)) THEN + IF Exist(General.MiscPath+'AUTO'+IntToStr(ThisNode)+'.TMP') THEN + BEGIN + Assign(AutoMsgFile1,General.MiscPath+'AUTO.ASC'); + ReWrite(AutoMsgFile1); + Assign(AutoMsgFile2,General.MiscPath+'AUTO'+IntToStr(ThisNode)+'.TMP'); + Reset(AutoMsgFile2); + IF (IOResult <> 0) THEN + Exit; + IF (AACS(General.AnonPubPost)) AND PYNQ('Post Anonymously? ',0,FALSE) THEN + IF (CoSysOp) THEN + WriteLn(AutoMsgFile1,'!'+Caps(ThisUser.Name)) + ELSE + WriteLn(AutoMsgFile1,'@'+Caps(ThisUser.Name)) + ELSE + WriteLn(AutoMsgFile1,Caps(ThisUser.Name)); + WHILE (NOT EOF(AutoMsgFile2)) DO + BEGIN + ReadLn(AutoMsgFile2,TempStr); + WriteLn(AutoMsgFile1,TempStr); + END; + Close(AutoMsgFile1); + Close(AutoMsgFile2); + Kill(General.MiscPath+'AUTO'+IntToStr(ThisNode)+'.TMP'); + END; + END; +END; + +PROCEDURE ReplyAutoMsg; +VAR + AutoMsgFile: Text; + MHeader: MHeaderRec; + TempStr: AStr; +BEGIN + Assign(AutoMsgFile,General.MiscPath+'AUTO.ASC'); + Reset(AutoMsgFile); + IF (IOResult <> 0) THEN + Print('%LFNo auto-message to reply to.') + ELSE + BEGIN + ReadLn(AutoMsgFile,TempStr); + Close(AutoMsgFile); + IF (TempStr[1] IN ['!','@']) THEN + BEGIN + LastAuthor := SearchUser(Copy(TempStr,2,Length(TempStr)),CoSysOp); + IF (NOT AACS(General.AnonPrivRead)) THEN + LastAuthor := 0; + END + ELSE + LastAuthor := SearchUser(TempStr,CoSysOp); + IF (LastAuthor = 0) THEN + Print('%LFUnable to reply to an anonymous message!') + ELSE + BEGIN + InResponseTo := 'Your auto-message'; + MHeader.Status := []; + AutoReply(MHeader); + END; + END; +END; + +END. diff --git a/SOURCE/BBSLIST.PAS b/SOURCE/BBSLIST.PAS new file mode 100644 index 0000000..522c49a --- /dev/null +++ b/SOURCE/BBSLIST.PAS @@ -0,0 +1,779 @@ +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + + +UNIT BBSList; + +INTERFACE + +PROCEDURE BBSList_Add; +PROCEDURE BBSList_Delete; +PROCEDURE BBSList_Edit; +PROCEDURE BBSList_View; +PROCEDURE BBSList_xView; + +IMPLEMENTATION + +USES + Common, + TimeFunc; + +FUNCTION BBSListMCI(CONST S: ASTR; Data1,Data2: Pointer): STRING; +VAR + BBSListPtr: ^BBSListRecordType; + User: UserRecordType; + TmpStr : String; +BEGIN + BBSListPtr := Data1; + BBSListMCI := S; + CASE S[1] OF + 'X' : CASE S[2] OF + 'A' : BBSListMCI := BBSListPtr^.SDA; + 'B' : BBSListMCI := BBSListPtr^.SDB; + 'C' : BBSListMCI := BBSListPtr^.SDC; + 'D' : BBSListMCI := BBSListPtr^.SDD; + 'E' : BBSListMCI := BBSListPtr^.SDE; + 'F' : BBSListMCI := BBSListPtr^.SDF; + END; + 'A' : CASE S[2] OF + 'C' : + Begin + If (Length(BBSListPtr^.PhoneNumber) > 0) Then + Begin + TmpStr := BBSListPtr^.PhoneNumber; + Delete(TmpStr,4,Length(TmpStr)); + BBSListMCI := TmpStr; + End + Else + Begin + BBSListMCI := 'N/A'; + End; + End; + END; + 'B' : CASE S[2] OF + 'N' : BBSListMCI := BBSListPtr^.BBSName; + 'P' : BBSListMCI := IntToStr(BBSListPtr^.Port); + END; + 'D' : CASE S[2] OF + 'A' : BBSListMCI := Pd2Date(BBSListPtr^.DateAdded); + 'E' : BBSListMCI := Pd2Date(BBSListPtr^.DateEdited); + 'S' : BBSListMCI := BBSListPtr^.Description; + '2' : BBSListMCI := BBSListPtr^.Description2 + END; + 'L' : CASE S[2] OF + 'O' : BBSListMCI := BBSListPtr^.Location; + END; + 'H' : CASE S[2] OF + 'R' : BBSListMCI := BBSListPtr^.Hours; + END; + 'M' : CASE S[2] OF + 'N' : BBSListMCI := IntToStr(BBSListPtr^.MaxNodes); + END; + 'O' : CASE S[2] OF + 'S' : Begin + If (Length(BBSListPtr^.OS) > 0) Then + BBSListMCI := BBSListPtr^.OS + Else + BBSListMCI := 'Unknown'; + End; + END; + 'P' : CASE S[2] OF + 'N' : Begin + If (Length(BBSListPtr^.PhoneNumber) > 0) Then + BBSListMCI := BBSListPtr^.PhoneNumber + Else + BBSListMCI := 'None'; + End; + END; + 'R' : CASE S[2] OF + 'N' : BBSListMCI := IntToStr(BBSListPtr^.RecordNum); + END; + 'S' : CASE S[2] OF + 'A' : BBSListMCI := BBSListPtr^.SDA; + 'B' : BBSListMCI := BBSListPtr^.SDB; + 'C' : BBSListMCI := BBSListPtr^.SDC; + 'D' : BBSListMCI := BBSListPtr^.SDD; + 'E' : BBSListMCI := BBSListPtr^.SDE; + 'F' : BBSListMCI := BBSListPtr^.SDF; + 'G' : BBSListMCI := IntToStr(BBSListPtr^.SDG); + 'H' : BBSListMCI := ShowYesNo(BBSListPtr^.SDH); + 'I' : BBSListMCI := ShowYesNo(BBSListPtr^.SDI); + 'N' : BBSListMCI := BBSListPtr^.SysOpName; + 'P' : BBSListMCI := BBSListPtr^.Speed; + 'T' : Begin + IF (Length(BBSListPtr^.Birth) > 0) THEN + BBSListMCI := BBSListPtr^.Birth + ELSE + BBSListMCI := 'Unknown'; + End; + 'V' : Begin + If (Length(BBSListPtr^.SoftwareVersion) > 0) Then + Begin + BBSListMCI := BBSListPtr^.SoftwareVersion; + End + Else + Begin + BBSListMCI := 'Unknown'; + End; + End; + 'W' : BBSListMCI := BBSListPtr^.Software; + END; + 'T' : CASE S[2] OF + 'N' : BBSListMCI := BBSListPtr^.TelnetUrl; + END; + 'U' : CASE S[2] OF + 'N' : BEGIN + LoadURec(User,BBSListPtr^.UserID); + BBSListMCI := User.Name; + END; + END; + 'W' : CASE S[2] OF + 'S' : BBSListMCI := BBSListPtr^.WebSiteUrl; + END; + END; +END; + +PROCEDURE BBSListScriptFile(VAR BBSList: BBSListRecordType); +VAR + BBSScriptText: TEXT; + Question: STRING; + WhichOne: String; + TmpBirth: String[10]; +BEGIN + Assign(BBSScriptText,General.MiscPath+'BBSLIST.SCR'); + Reset(BBSScriptText); + WHILE NOT EOF(BBSScriptText) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + ReadLn(BBSScriptText,Question); + IF (Question[1] = '[') THEN + BEGIN + WhichOne := AllCaps(Copy(Question, Pos('[',Question)+1, Pos(']',Question)-2)); + Question := Copy(Question,(Pos(':',Question) + 1),Length(Question)); + + IF (WhichOne = 'BBSNAME') THEN + BEGIN + NL; + PRT(Question+' '); + MPL(SizeOf(BBSList.BBSName) - 1); + InputMain(BBSList.BBSName,(SizeOf(BBSList.BBSName) - 1),[InterActiveEdit,ColorsAllowed]); + Abort := (BBSList.BBSName = ''); + END + ELSE IF WhichOne = 'SYSOPNAME' THEN + BEGIN + PRT(Question+' '); + MPL(SizeOf(BBSList.SysOpName) - 1); + InputMain(BBSList.SysOpName,(SizeOf(BBSList.SysOpName) - 1),[ColorsAllowed,InterActiveEdit]); + Abort := (BBSList.SysOpName = ''); + END + ELSE IF WhichOne = 'TELNETURL' THEN + BEGIN + Prt(Question+' '); + MPL(SizeOf(BBSList.TelnetUrl) - 1); + InputMain(BBSList.TelnetUrl,(SizeOf(BBSList.TelnetUrl) - 1),[ColorsAllowed,InterActiveEdit]); + Abort := (BBSList.TelnetUrl = ''); + END + ELSE IF WhichOne = 'WEBSITEURL' THEN + BEGIN + Prt(Question+' '); + MPL(SizeOf(BBSList.WebSiteUrl) - 1); + InputMain(BBSList.WebSiteUrl,(SizeOf(BBSList.WebSiteUrl) - 1),[ColorsAllowed,InterActiveEdit]); + {Abort := (BBSList.WebSiteUrl = '');} + END + ELSE IF WhichOne = 'PHONENUMBER' THEN + BEGIN + PRT(Question+' '); + MPL(SizeOf(BBSList.PhoneNumber) - 1); + InputMain(BBSList.PhoneNumber,(SizeOf(BBSList.PhoneNumber) - 1),[ColorsAllowed,InterActiveEdit]); + {Abort := (BBSList.PhoneNumber = '');} + END + ELSE IF WhichOne = 'SOFTWARE' THEN + BEGIN + PRT(Question+' '); + MPL(SizeOf(BBSList.Software) - 1); + InputMain(BBSList.Software,(SizeOf(BBSList.Software) - 1),[ColorsAllowed,InterActiveEdit]); + {Abort := (BBSList.Software = '');} + END + ELSE IF WhichOne = 'SOFTWAREVERSION' THEN + BEGIN + Prt(Question+' '); + MPL(SizeOf(BBSList.SoftwareVersion) - 1); + InputMain(BBSList.SoftwareVersion,(SizeOf(BBSList.SoftwareVersion) - 1),[ColorsAllowed,InterActiveEdit]); + END + ELSE IF WhichOne = 'OS' THEN + BEGIN + Prt(Question+' '); + MPL(SizeOf(BBSList.OS) - 1); + InputMain(BBSList.OS,(SizeOf(BBSList.OS) - 1),[ColorsAllowed,InterActiveEdit]); + END + ELSE IF WhichOne = 'SPEED' THEN + BEGIN + PRT(Question+' '); + MPL(SizeOf(BBSList.Speed) - 1); + InputMain(BBSList.Speed,(SizeOf(BBSList.Speed) - 1),[ColorsAllowed,InterActiveEdit]); + {Abort := (BBSList.Speed = '');} + END + ELSE IF WhichOne = 'HOURS' THEN + BEGIN + PRT(Question+' '); + MPL(SizeOf(BBSList.Hours) - 1); + InputMain(BBSList.Hours,(SizeOf(BBSList.Hours) - 1),[ColorsAllowed,InterActiveEdit]); + {Abort := (BBSList.Speed = '');} + END + ELSE IF WhichOne = 'DESCRIPTION' THEN + BEGIN + Prt(Question); + MPL(SizeOf(BBSList.Description) - 1); + InputMain(BBSList.Description,(SizeOf(BBSList.Description) - 1),[ColorsAllowed,InterActiveEdit]); + {Abort := (BBSList.Description = '');} + END + ELSE IF WhichOne = 'DESCRIPTION2' THEN + BEGIN + Prt(Question); + MPL(SizeOf(BBSList.Description2) - 1); + InputMain(BBSList.Description2,(SizeOf(BBSList.Description2) - 1),[ColorsAllowed,InterActiveEdit]); + {Abort := (BBSList.Description2 = '');} + END + ELSE IF WhichOne = 'MAXNODES' THEN + BEGIN + + MPL(SizeOf(BBSList.MaxNodes) - 1); + IF (BBSList.MaxNodes = 0) THEN + BBSList.MaxNodes := 5; + InputLongIntWoc(Question,BBSList.MaxNodes,[NumbersOnly,InteractiveEdit],1,1000); + + END + ELSE IF WhichOne = 'PORT' THEN + BEGIN + IF (BBSList.Port = 0) THEN + BBSList.Port := 23; + MPL(SizeOf(BBSList.Port) - 1); + + InputWordWoc(Question,BBSList.Port,[NumbersOnly,InterActiveEdit],1,65535); + END + ELSE IF WhichOne = 'LOCATION' THEN + BEGIN + Prt(Question+' '); + MPL(SizeOf(BBSList.Location) - 1); + InputMain(BBSList.Location,(SizeOf(BBSList.Location) - 1),[ColorsAllowed,InterActiveEdit]); + END + ELSE IF WhichOne = 'BIRTH' THEN + BEGIN + TmpBirth := BBSList.Birth; + IF (Length(TmpBirth) < 10) THEN + TmpBirth := '12/31/1969'; + MPL(10); + InputFormatted(Question+' |08(|07'+TmpBirth+'|08) |15: ',BBSList.Birth,'##/##/####',TRUE); + IF (Length(BBSList.Birth) <= 0) THEN + BBSList.Birth := TmpBirth; + + END + ELSE IF WhichOne = 'SDA' THEN + BEGIN + Prt(Question+' '); + MPL(SizeOf(BBSList.SDA) - 1); + InputMain(BBSList.SDA,(SizeOf(BBSList.SDA) - 1),[ColorsAllowed,InterActiveEdit]); + {Abort := (BBSList.xA = '');} + END + ELSE IF WhichOne = 'SDB' THEN + BEGIN + Prt(Question+' '); + MPL(SizeOf(BBSList.SDB) - 1); + InputMain(BBSList.SDB,(SizeOf(BBSList.SDB) - 1),[ColorsAllowed,InterActiveEdit]); + {Abort := (BBSList.xB = '');} + END + ELSE IF WhichOne = 'SDC' THEN + BEGIN + Prt(Question+' '); + MPL(SizeOf(BBSList.SDC) - 1); + InputMain(BBSList.SDC,(SizeOf(BBSList.SDC) - 1),[ColorsAllowed,InterActiveEdit]); + { Abort := (BBSList.xC = ''); } + END + ELSE IF WhichOne = 'SDD' THEN BEGIN + Prt(Question+' '); + MPL(SizeOf(BBSList.SDD) - 1); + InputMain(BBSList.SDD,(SizeOf(BBSList.SDD) - 1),[ColorsAllowed,InterActiveEdit]); + { Abort := (BBSList.xD = '');} + END + ELSE IF WhichOne = 'SDE' THEN + BEGIN + Print(Question); + MPL(SizeOf(BBSList.SDE) - 1); + InputMain(BBSList.SDE,(SizeOf(BBSList.SDE) - 1),[ColorsAllowed,InterActiveEdit]); + {Abort := (BBSList.xE = '');} + END + ELSE IF WhichOne = 'SDF' THEN + BEGIN + Print(Question); + MPL(SizeOf(BBSList.SDF) - 1); + InputMain(BBSList.SDF,(SizeOf(BBSList.SDF) - 1),[ColorsAllowed,InterActiveEdit]); + {Abort := (BBSList.xF = '');} + END + ELSE IF WhichOne = 'SDG' THEN + BEGIN + + MPL(SizeOf(BBSList.SDG) - 1); + InputWordWoc(Question,BBSList.SDG,[NumbersOnly,InterActiveEdit],1,65535); + {Abort := (BBSList.xE = '');} + END + ELSE IF WhichOne = 'SDH' THEN + BEGIN + BBSList.SDH := PYNQ(Question+' ',0,TRUE); + END + ELSE IF WhichOne = 'SDI' THEN + BEGIN + BBSList.SDI := PYNQ(Question+' ',6,FALSE); + END; + END; + END; + Close(BBSScriptText); + LastError := IOResult; +END; + +FUNCTION BBSList_Exists: Boolean; +VAR + BBSListFile: FILE OF BBSListRecordType; + FSize: Longint; + FExist: Boolean; +BEGIN + FSize := 0; + FExist := Exist(General.DataPath+'BBSLIST.DAT'); + IF (FExist) THEN + BEGIN + Assign(BBSListFile,General.DataPath+'BBSLIST.DAT'); + Reset(BBSListFile); + FSize := FileSize(BBSListFile); + Close(BBSListFile); + END; + IF (NOT FExist) OR (FSize = 0) THEN + BEGIN + NL; + Print('There are currently no entries in the BBS List.'); + SysOpLog('The BBSLIST.DAT file is missing.'); + END; + BBSList_Exists := (FExist) AND (FSize <> 0); +END; + +PROCEDURE DisplayError(FName: ASTR; VAR FExists: Boolean); +BEGIN + NL; + PrintACR('|12 |09The '+FName+'.* File is missing.'); + PrintACR('|12 |09Please, inform the Sysop!'); + SysOpLog('The '+FName+'.* file is missing.'); + FExists := FALSE; +END; + +FUNCTION BBSListScript_Exists: Boolean; +VAR + FExists: Boolean; +BEGIN + FExists := Exist(General.MiscPath+'BBSLIST.SCR'); + IF (NOT FExists) THEN + DisplayError('BBSLIST.SCR',FExists); + BBSListScript_Exists := FExists; +END; + +FUNCTION BBSListAddScreens_Exists: Boolean; +VAR + FExistsH, + FExistsN, + FExistsT: Boolean; +BEGIN + FExistsH := TRUE; + FExistsN := TRUE; + FExistsT := TRUE; + IF (NOT ReadBuffer('BBSNH')) THEN + DisplayError('BBSNH',FExistsH); + IF (NOT ReadBuffer('BBSMN')) THEN + DisplayError('BBSMN',FExistsN); + IF (NOT ReadBuffer('BBSNT')) THEN + DisplayError('BBSNT',FExistsT); + BBSListAddScreens_Exists := (FExistsH) AND (FExistsN) AND (FExistsT); +END; + +FUNCTION BBSListEditScreens_Exists: Boolean; +VAR + FExistsT, + FExistsM: Boolean; +BEGIN + FExistsT := TRUE; + FExistsM := TRUE; + IF (NOT ReadBuffer('BBSLET')) THEN + DisplayError('BBSLET',FExistsT); + IF (NOT ReadBuffer('BBSLEM')) THEN + DisplayError('BBSLEM',FExistsM); + BBSListEditScreens_Exists := (FExistsT) AND (FExistsM); +END; + +PROCEDURE BBSList_Renumber; +VAR + BBSListFile: FILE OF BBSListRecordType; + BBSList: BBSListRecordType; + OnRec: Longint; +BEGIN + Assign(BBSListFile,General.DataPath+'BBSLIST.DAT'); + Reset(BBSListFile); + Abort := FALSE; + OnRec := 1; + WHILE (OnRec <= FileSize(BBSListFile)) DO + BEGIN + Seek(BBSListFile,(OnRec - 1)); + Read(BBSListFile,BBSList); + BBSList.RecordNum := OnRec; + Seek(BBSListFile,(OnRec - 1)); + Write(BBSListFile,BBSList); + Inc(OnRec); + END; + Close(BBSListFile); + LastError := IOResult; +END; + +PROCEDURE BBSList_Sort; +VAR + BBSListFile: FILE OF BBSListRecordType; + BBSList1, + BBSList2: BBSListRecordType; + S, + I, + J, + pl, + Gap: INTEGER; +BEGIN + IF (BBSList_Exists) THEN + BEGIN + Assign(BBSListFile,General.DataPath+'BBSLIST.DAT'); + Reset(BBSListFile); + pl := FileSize(BBSListFile); + Gap := pl; + REPEAT; + Gap := (Gap DIV 2); + IF (Gap = 0) THEN + Gap := 1; + s := 0; + FOR I := 1 TO (pl - Gap) DO + BEGIN + J := (I + Gap); + Seek(BBSListFile,(i - 1)); + Read(BBSListFile,BBSList1); + Seek(BBSListFile,(j - 1)); + Read(BBSListFile,BBSList2); + IF (BBSList1.BBSName > BBSList2.BBSName) THEN + BEGIN + Seek(BBSListFile,(i - 1)); + Write(BBSListFile,BBSList2); + Seek(BBSListFile,(j - 1)); + Write(BBSListFile,BBSList1); + Inc(s); + END; + END; + UNTIL (s = 0) AND (Gap = 1); + Close(BBSListFile); + LastError := IOResult; + IF (PL > 0) THEN + BEGIN + NL; + Print('Sorted '+IntToStr(pl)+' BBS List entries.'); + SysOpLog('Sorted the BBS Listing'); + END; + END; +END; + +PROCEDURE BBSList_Add; +VAR + Data2: Pointer; + BBSList: BBSListRecordType; +BEGIN + IF (BBSListScript_Exists) AND (BBSListAddScreens_Exists) THEN + BEGIN + NL; + IF PYNQ(' Add an entry to the BBS list? ',0,FALSE) THEN + BEGIN + FillChar(BBSList,SizeOf(BBSList),0); + BBSListScriptFile(BBSList); + IF (NOT Abort) THEN + BEGIN + PrintF('BBSNH'); + ReadBuffer('BBSMN'); + DisplayBuffer(BBSListMCI,@BBSList,Data2); + PrintF('BBSNT'); + NL; + IF (PYNQ(' Save '+BBSList.BBSName+'? ',0,TRUE)) THEN + BEGIN + Assign(BBSListFile,General.DataPath+'BBSLIST.DAT'); + IF (Exist(General.DataPath+'BBSLIST.DAT')) THEN + Reset(BBSListFile) + ELSE + Rewrite(BBSListFile); + Seek(BBSListFile,FileSize(BBSListFile)); + BBSList.UserID := UserNum; + BBSList.DateAdded := GetPackDateTime; + BBSList.DateEdited := BBSList.DateAdded; + BBSList.RecordNum := (FileSize(BBSListFile) + 1); + Write(BBSListFile,BBSList); + Close(BBSListFile); + LastError := IOResult; + BBSList_Sort; + BBSList_Renumber; + SysOpLog('Added BBS Listing: '+BBSList.BBSName+'.'); + END; + END; + END; + END; +END; + +PROCEDURE BBSList_Delete; +VAR + Data2: Pointer; + BBSList: BBSListRecordType; + OnRec, + RecNum: Longint; + Found: Boolean; +BEGIN + IF (BBSList_Exists) AND (BBSListEditScreens_Exists) THEN + BEGIN + AllowContinue := FALSE; + Found := FALSE; + Abort := FALSE; + Assign(BBSListFile,General.DataPath+'BBSLIST.DAT'); + Reset(BBSListFile); + OnRec := 1; + WHILE (OnRec <= FileSize(BBSListFile)) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(BBSListFile,(OnRec - 1)); + Read(BBSListFile,BBSList); + IF (BBSList.UserID = UserNum) OR (CoSysOp) THEN + BEGIN + PrintF('BBSLDT'); + ReadBuffer('BBSLEM'); + DisplayBuffer(BBSListMCI,@BBSList,Data2); + NL; + IF (PYNQ(' Delete '+BBSLIST.BBSName+'? ',0,FALSE)) THEN + BEGIN + SysOpLog('Deleted BBS Listing: '+BBSList.BBSName+'.'); + IF ((OnRec - 1) <= (FileSize(BBSListFile) - 2)) THEN + FOR RecNum := (OnRec - 1) TO (FileSize(BBSListFile) - 2) DO + BEGIN + Seek(BBSListFile,(RecNum + 1)); + Read(BBSListFile,BBSList); + Seek(BBSListFile,RecNum); + Write(BBSListFile,BBSList); + END; + Seek(BBSListFile,(FileSize(BBSListFile) - 1)); + Truncate(BBSListFile); + Dec(OnRec); + END; + Found := TRUE; + END; + Inc(OnRec); + END; + Close(BBSListFile); + LastError := IOResult; + BBSList_ReNumber; + IF (NOT Found) THEN + BEGIN + NL; + Print(' You may only delete BBS Listing''s that you have entered.'); + SysOpLog('Tried to delete a BBS Listing.'); + END; + END; +END; + +PROCEDURE BBSList_Edit; +VAR + Data2: Pointer; + BBSList: BBSListRecordType; + OnRec: Longint; + Found: Boolean; + Edit : LongInt; +BEGIN + IF (BBSList_Exists) AND (BBSListEditScreens_Exists) AND (BBSListAddScreens_Exists) THEN + BEGIN + Assign(BBSListFile,General.DataPath+'BBSLIST.DAT'); + Reset(BBSListFile); + AllowContinue := FALSE; + Found := FALSE; + Abort := FALSE; + OnRec := 1; + WHILE (NOT Abort) AND (NOT HangUp) DO + BEGIN + + PrintF('BBSLEDT'); + ReadBuffer('BBSLEM'); + While OnRec <= FileSize(BBSListFile) Do + Begin + Seek(BBSListFile, OnRec -1); + Read(BBSListFile,BBSList); + DisplayBuffer(BBSListMCI,@BBSList,Data2); + Inc(OnRec); + End; + + NL; + MPL(FileSize(BBSListFile)); + InputLongIntWOC(' Edit which BBS? :',Edit,[],1,FileSize(BBSListFile)); + + Abort := (Edit <> 0 ); + + IF (Edit <= FileSize(BBSListFile)) AND (Edit > 0) THEN + BEGIN + Seek(BBSListFile,(Edit -1)) + END + ELSE + BEGIN + Close(BBSListFile); + Exit; + END; + Read(BBSListFile,BBSList); + IF (BBSList.UserID = UserNum) OR (CoSysOp) OR (BBSList.SysopName = ThisUser.Name) THEN + BEGIN + PrintF('BBSLEH'); + ReadBuffer('BBSLEM'); + DisplayBuffer(BBSListMCI,@BBSList,Data2); + NL; + IF (PYNQ(' Would you like to edit this BBS Listing? ',0,TRUE)) THEN + + BEGIN + BBSListScriptFile(BBSList); + IF (NOT Abort) THEN + BEGIN + PrintF('BBSNH'); + ReadBuffer('BBSMN'); + DisplayBuffer(BBSListMCI,@BBSList,Data2); + PrintF('BBSNT'); + NL; + IF (PYNQ(' Would you like to save this BBS Listing? ',0,TRUE)) THEN + BEGIN + Seek(BBSListFile,(Edit -1)); + BBSList.DateEdited := GetPackDateTime; + Write(BBSListFile,BBSList); + SysOpLog('Edited BBS Listing: '+BBSList.BBSName+'.'); + END; + END; + END; + Found := TRUE; + END; + {Inc(OnRec);} + Exit; + END; + Close(BBSListFile); + LastError := IOResult; + IF (NOT Found) THEN + BEGIN + NL; + Print(' You may only edit BBS Listing''s that you have entered.'); + SysOpLog('Tried to edit a BBS Listing.'); + END; + END + ELSE + BEGIN + NL; + Print('There was an error displaying an ASCII file. Let the sysop know so they can investigate.'); + SysOpLog('Some ASCII Files are missing for editing the bbslist. Investigate ...'); + END; +END; + +PROCEDURE BBSList_View; +VAR + Data2: Pointer; + BBSList: BBSListRecordType; + OnRec: Longint; + Cnt : Byte; +BEGIN + + IF (BBSList_Exists) AND (BBSListAddScreens_Exists) THEN + BEGIN + Assign(BBSListFile,General.DataPath+'BBSLIST.DAT'); + Reset(BBSListFile); + ReadBuffer('BBSMN'); + AllowContinue := TRUE; + Abort := FALSE; + PrintF('BBSNH'); + OnRec := 1; + Cnt := 1; + WHILE (OnRec <= FileSize(BBSListFile)) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(BBSListFile,(OnRec - 1)); + Read(BBSListFile,BBSList); + DisplayBuffer(BBSListMCI,@BBSList,Data2); + Inc(OnRec); + Inc(Cnt); + If Cnt = (23 - 4) Then + Begin + PauseScr(True); + Cnt := 1; + End + Else + Begin + Cnt := Cnt; + End; + END; + Close(BBSListFile); + LastError := IOResult; + IF (NOT Abort) THEN + PrintF('BBSNT'); + AllowContinue := FALSE; + SysOpLog('Viewed the BBS Listing.'); + END; +END; + +PROCEDURE BBSList_xView; (* Do we need xview *) {Yes -sk} +VAR + Data2: Pointer; + BBSList: BBSListRecordType; + OnRec: Longint; + Edit : Longint; +BEGIN + IF (BBSList_Exists) THEN (* Add BBSME & BBSEH exist checking here *) + BEGIN + Assign(BBSListFile,General.DataPath+'BBSLIST.DAT'); + Reset(BBSListFile); + + PrintF('BBSLEH'); + ReadBuffer('BBSLEM'); + OnRec := 1; + While OnRec <= FileSize(BBSListFile) Do + Begin + Seek(BBSListFile, OnRec -1); + Read(BBSListFile,BBSList); + DisplayBuffer(BBSListMCI,@BBSList,Data2); + Inc(OnRec); + End; + PrintF('BBSLET'); + NL; + MPL(FileSize(BBSListFile)); + InputLongIntWOC(' View which BBS? ',Edit,[],1,FileSize(BBSListFile)); + + Abort := (Edit <> 0 ); + + IF (Edit <= FileSize(BBSListFile)) AND (Edit > 0) THEN + BEGIN + Seek(BBSListFile,(Edit -1)); + Read(BBSListFile,BBSList); + Close(BBSListFile); + END + ELSE + BEGIN + Close(BBSListFile); + Exit; + END; + + IF (ReadBuffer('BBSME')) THEN + BEGIN + AllowContinue := TRUE; + Abort := FALSE; + PrintF('BBSEH'); + WHILE (NOT Abort) AND (NOT HangUp) DO + BEGIN + DisplayBuffer(BBSListMCI,@BBSList,Data2); + PrintF('BBSET'); + AllowContinue := FALSE; + {PauseScr(FALSE);} + SysOpLog('Viewed Extended BBS Listing of '+BBSList.BBSName+'.'); + Exit; + END; + + + END; + {Close(BBSListFile);} + LastError := IOResult; + END; +END; + +END. diff --git a/SOURCE/BOOT.PAS b/SOURCE/BOOT.PAS new file mode 100644 index 0000000..2d6d3be --- /dev/null +++ b/SOURCE/BOOT.PAS @@ -0,0 +1,1078 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Boot; + +INTERFACE + +PROCEDURE initp1; +PROCEDURE init; + +IMPLEMENTATION + +USES + Crt, + Dos, + Common, + MyIo, + MiscUser, + TimeFunc; + +PROCEDURE initp1; +VAR + LineFile: FILE OF LineRec; + F: FILE OF Byte; + User: UserRecordType; + X: Byte; + Counter: Integer; + + PROCEDURE FindBadPaths; + CONST + AnyDone: Boolean = FALSE; + VAR + BootFile: Text; + DirName, + DirDesc, + S2: AStr; + Counter: Byte; + BEGIN + InField_Out_FGrd := 7; + Infield_Out_BkGd := 0; + Infield_Inp_FGrd := 7; + Infield_Inp_BkGd := 0; + IF Exist('1STBOOT') THEN + BEGIN + General.DataPath := StartDir+'\DATA\'; + General.MiscPath := StartDir+'\MISC\'; + General.LogsPath := StartDir+'\LOGS\'; + General.MsgPath := StartDir+'\MSGS\'; + General.NodePath := ''; + General.TempPath := StartDir+'\TEMP\'; + General.ProtPath := StartDir+'\PROT\'; + General.ArcsPath := StartDir+'\ARCS\'; + General.FileAttachPath := StartDir+'\FATTACH\'; + General.lMultPath := StartDir+'\STRING\'; + SaveGeneral(FALSE); + Assign(BootFile,StartDir+'1STBOOT'); + Erase(BootFile); + END; + FOR Counter := 1 TO 8 DO + BEGIN + CASE Counter OF + 1 : BEGIN + DirDesc := 'DATA'; + DirName := General.DataPath; + END; + 2 : BEGIN + DirDesc := 'MSGS'; + DirName := General.MsgPath; + END; + 3 : BEGIN + DirDesc := 'FATTACH'; + DirName := General.FileAttachPath; + END; + 4 : BEGIN + DirDesc := 'MISC'; + DirName := General.MiscPath; + END; + 5 : BEGIN + DirDesc := 'LOGS'; + DirName := General.LogsPath; + END; + 6 : BEGIN + DirDesc := 'ARC'; + DirName := General.ArcsPath; + END; + 7 : BEGIN + DirDesc := 'PROT'; + DirName := General.ProtPath; + END; + 8 : BEGIN + DirDesc := 'STRING'; + DirName := General.lMultPath; + END; + END; + IF (NOT ExistDir(DirName)) THEN + BEGIN + AnyDone := TRUE; + WriteLn(DirDesc+' path is currently '+DirName); + WriteLn('This path is bad or missing.'); + REPEAT + WriteLn; + S2 := DirName; + Write('New '+DirDesc+' path: '); + InField(S2,40); + S2 := AllCaps(SQOutSp(S2)); + IF (DirName = S2) OR (S2 = '') THEN + BEGIN + NL; + WriteLn('Illegal pathname error'); + Halt(ExitErrors); + END + ELSE + BEGIN + IF (S2 <> '') THEN + S2 := BSlash(S2,TRUE); + IF (ExistDir(S2)) THEN + CASE Counter OF + 1 : General.DataPath := S2; + 2 : General.MsgPath := S2; + 3 : General.FileAttachPath := S2; + 4 : General.MiscPath := S2; + 5 : General.LogsPath := S2; + 6 : General.ArcsPath := S2; + 7 : General.ProtPath := S2; + 8 : General.lMultPath := S2; + END + ELSE + BEGIN + WriteLn; + WriteLn('That path does not exist!'); + END; + END; + UNTIL (ExistDir(S2)); + END; + END; + IF (AnyDone) THEN + SaveGeneral(FALSE); + END; + +BEGIN + FindBadPaths; + + TextColor(Yellow); + Write('Opening and checking NODE'+IntToStr(ThisNode)+'.DAT ... '); + Assign(LineFile,General.DataPath+'NODE'+IntToStr(ThisNode)+'.DAT'); + Reset(LineFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(LineFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file NODE'+IntToStr(ThisNode)+'.DAT ... '); + ReWrite(LineFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing NODE'+IntToStr(ThisNode)+'.DAT records ... '); + END; + FillChar(Liner,SizeOf(Liner),0); + WITH Liner DO + BEGIN + InitBaud := 19200; + Comport := 1; + MFlags := [CTSRTS]; + Init := 'ATV1S0=0M0E0H0|'; + Answer := 'ATA|'; + HangUp := '^ATH0|'; + Offhook := 'ATH1|'; + DoorPath := ''; + TeleConfNormal := '^4[%UN] ^9'; + TeleConfAnon := '^4[^9??^4] ^9'; + TeleConfGlobal := '^4[%UN ^0GLOBAL^4] ^9'; + TeleConfPrivate := '^4[%UN ^0PRIVATE^4] ^9'; + Ok := 'OK'; + Ring := 'RING'; + Reliable := '/ARQ'; + CallerID := 'NMBR = '; + NoCarrier := 'NO CARRIER'; + Connect[1] := 'CONNECT'; + Connect[2] := 'CONNECT 600'; + Connect[3] := 'CONNECT 1200'; + Connect[4] := 'CONNECT 2400'; + Connect[5] := 'CONNECT 4800'; + Connect[6] := 'CONNECT 7200'; + Connect[7] := 'CONNECT 9600'; + Connect[8] := 'CONNECT 12000'; + Connect[9] := 'CONNECT 14400'; + Connect[10] := 'CONNECT 16800'; + Connect[11] := 'CONNECT 19200'; + Connect[12] := 'CONNECT 21600'; + Connect[13] := 'CONNECT 24000'; + Connect[14] := 'CONNECT 26400'; + Connect[15] := 'CONNECT 28800'; + Connect[16] := 'CONNECT 31200'; + Connect[17] := 'CONNECT 33600'; + Connect[18] := 'CONNECT 38400'; + Connect[19] := 'CONNECT 57600'; + Connect[20] := 'CONNECT 115200'; + Connect[21] := ''; + Connect[22] := ''; + UseCallerID := FALSE; + LogonACS := ''; + IRQ := '4'; + Address := '3F8'; + AnswerOnRing := 1; + MultiRing := FALSE; + NodeTelnetUrl := ''; + END; + Write(LineFile,Liner); + END; + Close(LineFile); + LastError := IOResult; + WriteLn('Done.'); + + Assign(F,General.DataPath+'NODE'+IntToStr(ThisNode)+'.DAT'); + Reset(F); + X := 0; + Seek(F,FileSize(F)); + WHILE (FileSize(F) < SizeOf(LineRec)) DO + Write(F,X); + Close(F); + Reset(LineFile); + Read(LineFile,Liner); + Close(LineFile); + + IF (Liner.Comport = 0) THEN + LocalIOOnly := TRUE; + + TempDir := Copy(General.TempPath,1,Length(General.TempPath) - 1)+IntToStr(ThisNode)+'\'; + IF (NOT ExistDir(TempDir)) THEN + MkDir(Copy(TempDir,1,Length(TempDir) - 1)); + IF (NOT ExistDir(TempDir+'QWK\')) THEN + MkDir(TempDir+'QWK'); + IF (NOT ExistDir(TempDir+'ARC\')) THEN + MkDir(TempDir+'ARC'); + IF (NOT ExistDir(TempDir+'UP\')) THEN + MkDir(TempDir+'UP'); + IF (NOT ExistDir(TempDir+'CD\')) THEN + MkDir(TempDir+'CD'); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + WriteLn('Error creating directories: '+TempDir); + Delay(1000); + END; + + Assign(SysOpLogFile,General.LogsPath+'SYSOP.LOG'); + Append(SysOpLogFile); + LastError := IOResult; + IF (LastError = 2) THEN + ReWrite(SysOpLogFile); + Close(SysOpLogFile); + + Assign(NodeFile,General.DataPath+'MULTNODE.DAT'); + IF (General.MultiNode) THEN + BEGIN + Reset(NodeFile); + LastError := IOResult; + IF (LastError = 2) THEN + ReWrite(NodeFile); + IF (FileSize(NodeFile) < ThisNode) THEN + BEGIN + Seek(NodeFile,FileSize(NodeFile)); + WITH NodeR DO + BEGIN + User := 0; + UserName := ''; + CityState := ''; + Sex := 'M'; + Age := 0; + LogonTime := 0; + GroupChat := FALSE; + ActivityDesc := ''; + Status := [NActive]; + Room := 0; + Channel := 0; + FillChar(Invited,SizeOf(Invited),0); + FillChar(Booted,SizeOf(Booted),0); + FillChar(Forget,SizeOf(Forget),0); + END; + WHILE (FileSize(NodeFile) < ThisNode) DO + Write(NodeFile,NodeR); + END; + Close(NodeFile); + Assign(SysOpLogFile,TempDir+'TEMPLOG.'+IntToStr(ThisNode)) + END + ELSE + Assign(SysOpLogFile,General.LogsPath+'SYSOP.LOG'); + + Append(SysOpLogFile); + LastError := IOResult; + IF (LastError = 2) THEN + ReWrite(SysOpLogFile); + Close(SysOpLogFile); + + Assign(SysOpLogFile1,General.LogsPath+'SLOGXXXX.LOG'); + SL1(''); + SL1(''); + SL1('^7--> ^5Renegade '+General.Version+' Node '+IntToStr(ThisNode)+' Loaded on '+dat+'^7 <--'); + + Assign(UserFile,General.DataPath+'USERS.DAT'); + + IF ((MaxUsers - 1) >= 1) THEN + LoadURec(ThisUser,1) + ELSE + Exclude(ThisUser.SFLags,SLogSeparate); + + Assign(UserIDXFile,General.DataPath+'USERS.IDX'); + Reset(UserIDXFile); + LastError := IOResult; + IF (LastError = 2) OR (MaxIDXRec = -1) THEN + BEGIN + IF (LastError = 0) THEN + Close(UserIDXFile); + Write('Regenerating corrupted User index: 0%'); + kill(General.DataPath+'USERS.IDX'); + General.NumUsers := 0; + ReWrite(UserIDXFile); + Reset(UserFile); + FOR Counter := 1 TO (MaxUsers - 1) DO + BEGIN + LoadURec(User,Counter); + IF (Counter MOD 25 = 0) THEN + Write(^H^H^H^H,(Counter / FileSize(UserFile) * 100):3:0,'%'); + IF (NOT (Deleted IN User.SFLags)) THEN + Inc(lTodayNumUsers); + InsertIndex(User.Name,Counter,FALSE,(Deleted IN User.SFLags)); + InsertIndex(User.realname,Counter,TRUE,(Deleted IN User.SFLags)); + END; + Close(UserFile); + Close(UserIDXFile); + WriteLn; + SaveGeneral(FALSE); + LastError := IOResult; + END + ELSE + Close(UserIDXFile); + + Assign(EventFile,General.DataPath+'EVENTS.DAT'); + Reset(EventFile); + LastError := IOResult; + IF (LastError = 2) THEN + BEGIN + WriteLn('Bad or missing EVENTS.DAT - creating...'); + ReWrite(EventFile); + NumEvents := 1; + New(MemEventArray[1]); + WITH MemEventArray[1]^ DO + BEGIN + EventDescription := '<< New Event >>'; + EventDayOfMonth := 0; + EventDays := []; + EventStartTime := 0; + EventFinishTime := 0; + EventQualMsg := ''; + EventNotQualMsg := ''; + EventPreTime := 0; + EventNode := 0; + EventLastDate := 0; + EventErrorLevel := 0; + EventShellPath := ''; + LoBaud := 300; + HiBaud := 115200; + EventACS := 's10'; + MaxTimeAllowed := 60; + SetARflag := '@'; + ClearARflag := '@'; + EFlags := [EventIsExternal,EventIsShell]; + END; + Write(EventFile,MemEventArray[1]^); + END + ELSE + BEGIN + NumEvents := 0; + IF NOT EOF(EventFile) THEN + REPEAT + Inc(NumEvents); + New(MemEventArray[NumEvents]); + Read(EventFile,MemEventArray[NumEvents]^); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Warning: Bad events file format.'); + Break; + END; + UNTIL (EOF(EventFile)); + END; + Close(EventFile); + LastError := IOResult; + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking MEMAIL.DAT ... '); + Assign(EmailFile,General.DataPath+'MEMAIL.DAT'); + Reset(EmailFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(EmailFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file MEMAIL.DAT ... '); + ReWrite(EmailFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing MEMAIL.DAT records ... '); + END; + FillChar(MemMsgArea,SizeOf(MemMsgArea),0); + WITH MemMsgArea DO + BEGIN + Name := 'Private Messages'; + FileName := 'EMAIL'; + MsgPath := ''; + ACS := '^'; + PostACS := ''; + MCIACS := ''; + SysOpACS := General.MSoP; + MaxMsgs := 65535; + Anonymous := ATNo; + Password := ''; + MAFlags := []; + MAType := 0; + Origin := ''; + Text_Color := General.Text_Color; + Quote_Color := General.Quote_Color; + Tear_Color := General.Tear_Color; + Origin_Color := General.Origin_Color; + MessageReadMenu := 0; + QuoteStart := '|03Quoting message from |11@F |03to |11@T'; + QuoteEnd := '|03on |11@D|03.'; + PrePostFile := ''; + AKA := 0; + QWKIndex := 0; + END; + Write(EmailFile,MemMsgArea); + END; + Close(EmailFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking MBASES.DAT ... '); + Assign(MsgAreaFile,General.DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(MsgAreaFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file MBASES.DAT ... '); + ReWrite(MsgAreaFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing MBASES.DAT records ... '); + END; + FillChar(MemMsgArea,SizeOf(MemMsgArea),0); + WITH MemMsgArea DO + BEGIN + Name := '<< New Message Area >>'; + FileName := 'NEWBOARD'; + MsgPath := ''; + ACS := ''; + PostACS := ''; + MCIACS := ''; + SysOpACS := ''; + MaxMsgs := 100; + Anonymous := ATNo; + Password := ''; + MAFlags := []; + MAType := 0; + Origin := ''; + Text_Color := General.Text_Color; + Quote_Color := General.Quote_Color; + Tear_Color := General.Tear_Color; + Origin_Color := General.Origin_Color; + MessageReadMenu := 0; + QuoteStart := '|03Quoting message from |11@F |03to |11@T'; + QuoteEnd := '|03on |11@D|03.'; + PrePostFile := ''; + AKA := 0; + QWKIndex := (FileSize(MsgAreaFile) + 1); + END; + Write(MsgAreaFile,MemMsgArea); + END; + NumMsgAreas := FileSize(MsgAreaFile); + Close(MsgAreaFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 08/11/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking CONFRENC.DAT ... '); + Assign(ConferenceFile,General.DataPath+'CONFRENC.DAT'); + Reset(ConferenceFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(ConferenceFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file CONFRENC.DAT ... '); + ReWrite(ConferenceFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing CONFRENC.DAT records ... '); + END; + FillChar(Conference,SizeOf(Conference),0); + WITH Conference DO + BEGIN + Key := '@'; + Name := 'General'; + ACS := ''; + END; + Write(ConferenceFile,Conference); + END; + NumConfKeys := FileSize(ConferenceFile); + ConfKeys := []; + Counter := 1; + WHILE (Counter <= NumConfKeys) DO + BEGIN + Seek(ConferenceFile,(Counter - 1)); + Read(ConferenceFile,Conference); + Include(ConfKeys,Conference.Key); + Inc(Counter); + END; + Close(ConferenceFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking FBASES.DAT ... '); + Assign(FileAreaFile,General.DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(FileAreaFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file FBASES.DAT ... '); + ReWrite(FileAreaFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing FBASES.DAT records ... '); + END; + FillChar(MemFileArea,SizeOf(MemFileArea),0); + WITH MemFileArea DO + BEGIN + AreaName := '<< New File Area >>'; + FileName := 'NEWDIR'; + DLPath := StartDir[1]+':\'; + ULPath := DLPath; + MaxFiles := 2000; + Password := ''; + ArcType := 0; + CmtType := 0; + ACS := ''; + ULACS := ''; + DLACS := ''; + FAFlags := []; + END; + Write(FileAreaFile,MemFileArea); + END; + NumFileAreas := FileSize(FileAreaFile); + Close(FileAreaFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking PROTOCOL.DAT ... '); + Assign(ProtocolFile,General.DataPath+'PROTOCOL.DAT'); + Reset(ProtocolFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(ProtocolFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file PROTOCOL.DAT ... '); + ReWrite(ProtocolFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing PROTOCOL.DAT records ... '); + END; + FillChar(Protocol,SizeOf(Protocol),0); + WITH Protocol DO + BEGIN + PRFlags := [ProtXferOkCode]; + CKeys := '!'; + Description := '<< New Protocol >>'; + ACS := ''; + TempLog := ''; + DLoadLog := ''; + ULoadLog := ''; + DLCmd := ''; + ULCmd := ''; + FOR Counter := 1 TO 6 DO + BEGIN + DLCode[Counter] := ''; + ULCode[Counter] := ''; + END; + EnvCmd := ''; + DLFList := ''; + MaxChrs := 127; + TempLogPF := 0; + TempLogPS := 0; + END; + Write(ProtocolFile,Protocol); + END; + NumProtocols := FileSize(ProtocolFile); + Close(ProtocolFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking SCHEME.DAT ... '); + Assign(SchemeFile,General.DataPath+'SCHEME.DAT'); + Reset(SchemeFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(SchemeFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file SCHEME.DAT ... '); + ReWrite(SchemeFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing SCHEME.DAT records ... '); + END; + FillChar(Scheme,SizeOf(Scheme),0); + WITH Scheme DO + BEGIN + Description := 'Default Color Scheme'; + FillChar(Color,SizeOf(Color),7); + Color[1] := 15; + Color[2] := 7; + Color[3] := 13; + Color[4] := 11; + Color[5] := 9; + Color[6] := 14; + Color[7] := 31; + Color[8] := 12; + Color[9] := 142; + Color[10] := 10; + END; + Write(SchemeFile,Scheme); + END; + NumSchemes := FileSize(SchemeFile); + Close(SchemeFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking VOTING.DAT ... '); + Assign(VotingFile,General.DataPath+'VOTING.DAT'); + Reset(VotingFile); + LastError := IOResult; + IF (LastError = 2) THEN + BEGIN + TextColor(Red); + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file VOTING.DAT ... '); + ReWrite(VotingFile); + END; + NumVotes := FileSize(VotingFile); + Close(VotingFile); + LastError := IOResult; + WriteLn('Done.'); + + TextColor(Yellow); + Write('Opening and checking VALIDATE.DAT ... '); + Assign(ValidationFile,General.DataPath+'VALIDATE.DAT'); + Reset(ValidationFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(ValidationFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file VALIDATE.DAT ... '); + ReWrite(ValidationFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing VALIDATE.DAT records ... '); + END; + LoadURec(User,0); + FillChar(Validation,SizeOf(Validation),0); + WITH Validation DO + BEGIN + Key := '!'; + ExpireTo := ' '; + Description := 'New user validation'; + UserMsg := 'You have been validated, enjoy the system!'; + NewSL := User.SL; + NewDSL := User.DSL; + NewMenu := 0; + Expiration := 0; + NewFP := 0; + NewCredit := 0; + SoftAR := TRUE; + SoftAC := TRUE; + NewAR := []; + NewAC := []; + END; + Write(ValidationFile,Validation); + END; + NumValKeys := FileSize(ValidationFile); + ValKeys := []; + Counter := 1; + WHILE (Counter <= NumValKeys) DO + BEGIN + Seek(ValidationFile,(Counter - 1)); + Read(ValidationFile,Validation); + Include(ValKeys,Validation.Key); + Inc(Counter); + END; + Close(ValidationFile); + LastError := IOResult; + WriteLn('Done.'); + + NumArcs := 1; + WHILE (NumArcs <= MaxArcs) AND (General.FileArcInfo[NumArcs].Ext <> '') DO + Inc(NumArcs); + Dec(NumArcs); + + FOR Counter := 1 TO MaxMenus DO + MenuRecNumArray[Counter] := 0; + FOR Counter := 1 TO MaxMenus DO + CmdNumArray[Counter] := 0; + NumMenus := 0; + NumCmds := 0; + Assign(MenuFile,General.DataPath+'MENUS.DAT'); + Reset(MenuFile); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + Print('System Error: MENUS.DAT file is missing!'); + Halt; + END + ELSE + BEGIN + Counter := 0; + WHILE NOT EOF(MenuFile) DO + BEGIN + Read(MenuFile,MenuR); + IF (MenuR.Menu = TRUE) THEN + BEGIN + Inc(NumMenus); + MenuRecNumArray[NumMenus] := Counter; + IF (NumMenus > 1) THEN + CmdNumArray[NumMenus - 1] := NumCmds; + NumCmds := 0; + END + ELSE + Inc(NumCmds); + Inc(Counter); + END; + CmdNumArray[NumMenus] := NumCmds; + Close(MenuFile); + END; + + CFO := FALSE; + +END; + +FUNCTION SchareLoaded: Boolean; +VAR + T_Al: Byte; +BEGIN +{$IFDEF MSDOS} + ASM + Mov Ah,10h + Mov Al,0h + Int 2fh + Mov T_Al,Al + END; +{$ENDIF} +{$IFDEF WIN32} + T_Al := $FF; +{$ENDIF} + SchareLoaded := (T_Al = $FF); +END; + +PROCEDURE FindTaskerType; +VAR + D5, + DOS_Major, + DOS_Minor, + Os2Vers: Word; + DVOk, + OS2Ok, + WinOk, + WinNTOk: Boolean; + +{$IFDEF MSDOS} + FUNCTION TrueDosVer(VAR WinNTOk: Boolean): Word; + VAR + Regs: Registers; + BEGIN + WITH Regs DO + BEGIN + Ax := $3306; + MsDos(Regs); + IF (Bx = $3205) THEN + WinNTOk := TRUE + ELSE + WinNTOk := FALSE; + TrueDosVer := Bl; + END; + END; +{$ENDIF} +{$IFDEF WIN32} + FUNCTION TrueDosVer(VAR WinNTOk: Boolean): Word; + BEGIN + WinNtOK := TRUE; + TrueDosVer := 5; + END; +{$ENDIF} + +{$IFDEF MSDOS} + FUNCTION DosVer(VAR Minor,OS2Ver: Word): Word; + VAR + Regs: Registers; + BEGIN + OS2Ver := 0; + WITH Regs DO + BEGIN + Ax := $3000; + MsDos(Regs); + DosVer := Al; + Minor := Ah; + IF (Al = $0A) THEN + OS2Ver := 1 + ELSE IF (Al = $14) THEN + OS2Ver := 2; + END; + END; +{$ENDIF} +{$IFDEF WIN32} + FUNCTION DosVer(VAR Minor,OS2Ver: Word): Word; + BEGIN + Minor := 0; + OS2Ver := 0; + DosVer := 5; + END; +{$ENDIF} + +{$IFDEF MSDOS} + FUNCTION Win3_Check_On: Boolean; + VAR + Regs: Registers; + BEGIN + WITH Regs DO + BEGIN + AX := $1600; + Intr($2F,Regs); { $00 no Win 2.x or 3.x } + IF (AL IN [$00,$01,$80,$FF]) THEN { $01 Win/386 2.x running } + Win3_Check_On := FALSE { $80 obsolete XMS installed } + ELSE { $FF Win/386 2.x running } + Win3_Check_On := TRUE; + END; + END; +{$ENDIF} +{$IFDEF WIN32} + FUNCTION Win3_Check_On: Boolean; + BEGIN + Win3_Check_On := FALSE; + END; +{$ENDIF} + +{$IFDEF MSDOS} + FUNCTION DV_Check_On: Boolean; + VAR + Regs: Registers; + BEGIN + DV_Check_On := FALSE; + WITH Regs DO + BEGIN + Ax := $2B01; + Cx := $4445; + Dx := $5351; + Intr($21,Regs); + END; + IF (Regs.AL = $FF) THEN + DV_Check_On := FALSE + ELSE + DV_Check_On := TRUE; + END; +{$ENDIF} +{$IFDEF WIN32} + FUNCTION DV_Check_On: Boolean; + BEGIN + DV_Check_On := FALSE; + END; +{$ENDIF} + +BEGIN + D5 := 0; + Tasker := None; + DVOk := FALSE; + OS2Ok := FALSE; + WinOk := FALSE; + WinNTOk := FALSE; { This could also be just plain old Dos 5.0+ } + DOS_Major := DosVer(DOS_Minor,Os2Vers); + IF (Os2Vers IN [1,2]) THEN + OS2Ok := TRUE + ELSE + DVOk := DV_Check_On; + IF (NOT DVOk) AND (NOT OS2Ok) THEN + BEGIN + WinOk := Win3_Check_On; + IF (NOT WinOk) THEN + CASE Dos_Major of + 5..9 : D5 := TrueDosVer(WinNTOk); + END; + END; + IF (DVOk) THEN + Tasker := DV + ELSE IF (WinOk) THEN + Tasker := Win + ELSE IF (OS2Ok) THEN + Tasker := OS2 + ELSE IF (WinNTOk) THEN + Tasker := Win32 + ELSE IF (D5 >= 5) THEN + Tasker := Dos5N; +END; + +PROCEDURE init; +VAR + Node: Byte; +BEGIN + IF (DateStr = '01-01-1980') THEN + BEGIN + ClrScr; + TextColor(Yellow); + WriteLn('Please set the operating system date & time.'); + Halt(ExitErrors); + END; + + FindTaskerType; + + IF (General.MultiNode) AND (NOT SchareLoaded) THEN + BEGIN + ClrScr; + TextColor(Yellow); + WriteLn('WARNING: SHARE.EXE should be loaded for MultiNode operation.'); + Delay(1000); + END; + + HangUp := FALSE; + InCom := FALSE; + OutCom := FALSE; + Echo := TRUE; + DoneDay := FALSE; + CheckBreak := FALSE; + SLogging := TRUE; + Trapping := FALSE; + ReadingMail := FALSE; + SysOpOn := FALSE; + BeepEnd := FALSE; + WantOut := TRUE; + InChat := FALSE; + LIL := 0; + + ThisUser.PageLen := 24; (* Is this needed ??? *) + + Buf := ''; + ChatCall := FALSE; + LastAuthor := 0; + LastLineStr := ''; + ChatReason := ''; + + DirectVideo := NOT General.UseBIOS; + + IF (General.NetworkMode) AND (ThisNode = 0) THEN + BEGIN + LocalIOOnly := TRUE; + Node := 1; + WHILE (Node <= MaxNodes) AND (ThisNode = 0) DO + BEGIN + LoadNode(Node); + IF (NOT (NActive IN NodeR.Status)) THEN + ThisNode := Node; + Inc(Node); + END; + IF (ThisNode = 0) THEN + ThisNode := Node; + END; + + IF (ThisNode > 255) THEN + ThisNode := 1; + + IF (General.MultiNode) AND (ThisNode = 0) THEN + BEGIN + ClrScr; + WriteLn('WARNING: No node number specified. Defaulting to node 1.'); + ThisNode := 1; + Delay(1000); + END + ELSE IF (ThisNode = 0) THEN + ThisNode := 1; + + initp1; + + LoadNode(ThisNode); + WITH NodeR DO + BEGIN + User := 0; + UserName := ''; + CityState := ''; + Sex := 'M'; + Age := 0; + LogonTime := 0; + GroupChat := FALSE; + ActivityDesc := ''; + Status := [NActive]; + Room := 0; + Channel := 0; + FillChar(Invited,SizeOf(Invited),0); + FillChar(Booted,SizeOf(Booted),0); + FillChar(Forget,SizeOf(Forget),0); + END; + SaveNode(ThisNode); + +END; + +END. diff --git a/SOURCE/BULLETIN.PAS b/SOURCE/BULLETIN.PAS new file mode 100644 index 0000000..7d91889 --- /dev/null +++ b/SOURCE/BULLETIN.PAS @@ -0,0 +1,592 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} +UNIT Bulletin; + +INTERFACE + +USES + Common; + +FUNCTION FindOnlyOnce: Boolean; +FUNCTION NewBulletins: Boolean; +PROCEDURE Bulletins(MenuOption: Str50); +PROCEDURE UList(MenuOption: Str50); +PROCEDURE TodaysCallers(x: Byte; MenuOptions: Str50); +PROCEDURE RGQuote(MenuOption: Str50); + +IMPLEMENTATION + +USES + Dos, + Common5, + Mail1, + ShortMsg, + TimeFunc; + +TYPE + LastCallerPtrType = ^LastCallerRec; + UserPtrType = ^UserRecordType; + +PROCEDURE Bulletins(MenuOption: Str50); +VAR + Main, + Subs, + InputStr: ASTR; +BEGIN + NL; + IF (MenuOption = '') THEN + IF (General.BulletPrefix = '') THEN + MenuOption := 'BULLETIN;BULLET' + ELSE + MenuOption := 'BULLETIN;'+General.BulletPrefix; + IF (Pos(';',MenuOption) <> 0) THEN + BEGIN + Main := Copy(MenuOption,1,(Pos(';',MenuOption) - 1)); + Subs := Copy(MenuOption,(Pos(';',MenuOption) + 1),(Length(MenuOption) - Pos(';',MenuOption))); + END + ELSE + BEGIN + Main := MenuOption; + Subs := MenuOption; + END; + PrintF(Main); + IF (NOT NoFile) THEN + REPEAT + NL; + { Prt(FString.BulletinLine); } + lRGLngStr(16,FALSE); + ScanInput(InputStr,'ABCDEFGHIJKLMNOPQRSTUVWXYZ?'); + IF (NOT HangUp) THEN + BEGIN + IF (InputStr = '?') THEN + PrintF(Main); + IF (InputStr <> '') AND NOT (InputStr[1] IN ['Q','?']) THEN + PrintF(Subs+InputStr); + END; + UNTIL (InputStr = 'Q') OR (HangUp); +END; + +FUNCTION FindOnlyOnce: Boolean; +VAR + (* + DirInfo: SearchRec; + *) + DT: DateTime; +BEGIN + FindOnlyOnce := FALSE; + FindFirst(General.MiscPath+'ONLYONCE.*',AnyFile - Directory - VolumeID- DOS.Hidden,DirInfo); + IF (DosError = 0) THEN + BEGIN + UnPackTime(DirInfo.Time,DT); + IF (DateToPack(DT) > ThisUser.LastOn) THEN + FindOnlyOnce := TRUE; + END; +END; + +FUNCTION NewBulletins: Boolean; +TYPE + BulletinType = ARRAY [0..255] OF Byte; +VAR + BulletinArray: ^BulletinType; + DT: DateTime; + (* + DirInfo: SearchRec; + *) + BullCount, + Biggest, + LenOfBullPrefix, + LenToCopy: Byte; + Found: Boolean; + + PROCEDURE ShowBulls; + VAR + Counter, + Counter1, + Counter2: Byte; + BEGIN + FOR Counter := 0 TO BullCount DO + BEGIN + FOR Counter1 := 0 TO BullCount DO + IF (BulletinArray^[Counter] < BulletinArray^[Counter1]) THEN + BEGIN + Counter2 := BulletinArray^[Counter]; + BulletinArray^[Counter] := BulletinArray^[Counter1]; + BulletinArray^[Counter1] := Counter2; + END; + END; + Counter1 := 1; + Prt('|01[ |11'); + FOR Counter2 := 0 TO (BullCount) DO + BEGIN + IF (Counter1 = 15) THEN + BEGIN + Prt(PadRightInt(BulletinArray^[Counter2],2)); + IF (Counter2 < BullCount) THEN + Prt(' |01]'+^M^J+'|01[ |11') + ELSE + Prt(' |01]'); + Counter1 := 0; + END + ELSE + BEGIN + Prt(PadRightInt(BulletinArray^[Counter2],2)); + IF (Counter2 < BullCount) THEN + Prt('|07,|11 ') + ELSE + Prt(' |01]'); + END; + Inc(Counter1); + END; + NL; + END; + +BEGIN + New(BulletinArray); + FOR BullCount := 0 TO 255 DO + BulletinArray^[BullCount] := 0; + Found := FALSE; + Biggest := 0; + BullCount := 0; + LenOfBullPrefix := (Length(General.BulletPrefix) + 1); + FindFirst(General.MiscPath+General.BulletPrefix+'*.ASC',AnyFile - Directory - VolumeID - DOS.Hidden,DirInfo); + WHILE (DosError = 0) DO + BEGIN + IF (((Pos(General.BulletPrefix,General.MiscPath+General.BulletPrefix+'*.ASC') > 0) AND + (Pos('BULLETIN',AllCaps(DirInfo.Name)) = 0)) AND + (Pos('~',DirInfo.Name) = 0)) THEN + BEGIN + UnPackTime(DirInfo.Time,DT); + IF (DateToPack(DT) > ThisUser.LastOn) THEN + BEGIN + Found := TRUE; + LenToCopy := (Pos('.',DirInfo.Name) - 1) - Length(General.BulletPrefix); + BulletinArray^[BullCount] := StrToInt(Copy(DirInfo.Name,LenOfBullPrefix,LenToCopy)); + IF (BulletinArray^[BullCount] > Biggest) THEN + Biggest := BulletinArray^[BullCount]; + Inc(BullCount); + END; + END; + IF (BullCount > 254) THEN + Exit; + FindNext(DirInfo); + END; + IF (Found) THEN + BEGIN + Dec(BullCount); + ShowBulls; + END; + Dispose(BulletinArray); + NewBulletins := Found; +END; + +FUNCTION UlistMCI(CONST S: ASTR; Data1,Data2: Pointer): STRING; +VAR + UserPtr: UserPtrType; +BEGIN + UlistMCI := S; + UserPtr := Data1; + CASE S[1] OF + 'A' : CASE S[2] OF + 'G' : UListMCI := IntToStr(AgeUser(UserPtr^.BirthDate)); + END; + 'D' : CASE S[2] OF + 'K' : UListMCI := IntToStr(UserPtr^.DK); + 'L' : UListMCI := IntToStr(UserPtr^.Downloads); + END; + 'L' : CASE S[2] OF + 'C' : UListMCI := UserPtr^.CityState; + 'O' : UListMCI := ToDate8(PD2Date(UserPtr^.LastOn)); + END; + 'M' : CASE S[2] OF + 'P' : UListMCI := IntToStr(UserPtr^.MsgPost); + END; + 'N' : CASE S[2] OF + 'O' : UListMCI := Userptr^.Note; + END; + 'R' : CASE S[2] OF + 'N' : UListMCI := UserPtr^.RealName; + END; + 'S' : CASE S[2] OF + 'X' : UListMCI := UserPtr^.Sex; + END; + 'U' : CASE S[2] OF + 'K' : UListMCI := IntToStr(UserPtr^.UK); + 'L' : UListMCI := IntToStr(UserPtr^.Uploads); + 'N' : UListMCI := Caps(UserPtr^.Name); + '1' : UListMCI := UserPtr^.UsrDefStr[1]; + '2' : UListMCI := UserPtr^.UsrDefStr[2]; + '3' : UListMCI := UserPtr^.UsrDefStr[3]; + END; + END; +END; + +PROCEDURE UList(MenuOption: Str50); +VAR + Junk: Pointer; + User: UserRecordType; + Cmd: Char; + TempStr: ASTR; + Gender: Str1; + State, + UState: Str2; + Age: Str3; + DateLastOn: Str8; + City, + UCity: Str30; + RName, + UName: Str36; + FN: Str50; + RecNum: Integer; + + PROCEDURE Option(c1: Char; s1,s2: Str160); + BEGIN + Prompt('^4<^5'+c1+'^4>'+s1+': '); + IF (s2 <> '') THEN + Print('^5"^4'+s2+'^5"^1') + ELSE + Print('^5<>^1'); + END; + +BEGIN + IF (RUserList IN ThisUser.Flags) THEN + BEGIN + Print('You are restricted from listing users.'); + Exit; + END; + Age := ''; + City := ''; + DateLastOn := ''; + Gender := ''; + RName := ''; + State := ''; + UName := ''; + REPEAT + NL; + Print('^5User lister search options:'); + NL; + Option('A','ge match string ',Age); + Option('C','ity match string ',City); + Option('D','ate last online match string',DateLastOn); + Option('G','ender match string ',Gender); + Option('R','eal name match string ',RName); + Option('S','tate match string ',State); + Option('U','ser name match string ',UName); + NL; + Prompt('^4Enter choice (^5A^4,^5C^4,^5D^4,^5G^4,^5R^4,^5S^4,^5U^4) [^5L^4]ist [^5Q^4]uit: '); + OneK(Cmd,'QACDGLRSU'^M,TRUE,TRUE); + NL; + IF (Cmd IN ['A','C','D','G','R','S','U']) THEN + BEGIN + TempStr := 'Enter new match string for the '; + CASE Cmd OF + 'A' : TempStr := TempStr + 'age'; + 'C' : TempStr := TempStr + 'city'; + 'D' : TempStr := TempStr + 'date last online'; + 'G' : TempStr := TempStr + 'gender'; + 'R' : TempStr := TempStr + 'real name'; + 'S' : TempStr := TempStr + 'state'; + 'U' : TempStr := TempStr + 'user name'; + END; + TempStr := TempStr + ' (=Make INACTIVE)'; + Print('^4'+TempStr); + Prompt('^4: '); + END; + CASE Cmd OF + 'A' : BEGIN + Mpl(3); + Input(Age,3); + END; + 'C' : BEGIN + Mpl(30); + Input(City,30); + END; + 'D' : BEGIN + Mpl(8); + InputFormatted('',DateLastOn,'##/##/##',TRUE); + IF (DayNum(DateLastOn) <> 0) AND (DayNum(DateLastOn) <= DayNum(DateStr)) THEN + BEGIN + Delete(DateLastOn,3,1); + Insert('-',DateLastOn,3); + Delete(DateLastOn,6,1); + Insert('-',DateLastOn,6); + END; + END; + 'G' : BEGIN + Mpl(1); + Input(Gender,1); + END; + 'R' : BEGIN + Mpl(36); + Input(RName,36); + END; + 'S' : BEGIN + Mpl(2); + Input(State,2); + END; + 'U' : BEGIN + Mpl(36); + Input(UName,36); + END; + END; + UNTIL (Cmd IN ['L','Q',^M]) OR (HangUp); + IF (Cmd IN ['L',^M]) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + AllowContinue := TRUE; + IF (Pos(';',MenuOption) > 0) THEN + BEGIN + FN := Copy(MenuOption,(Pos(';',MenuOption) + 1),255); + MenuOption := Copy(MenuOption,1,(Pos(';',MenuOption) - 1)); + END + ELSE + FN := 'USER'; + IF (NOT ReadBuffer(FN+'M')) THEN + Exit; + PrintF(FN+'H'); + Reset(UserFile); + RecNum := 1; + WHILE (RecNum <= (FileSize(UserFile) - 1)) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + LoadURec(User,RecNum); + UCity := (Copy(User.CityState,1,(Pos(',',User.CityState) - 1))); + UState := SQOutSP((Copy(User.CityState,(Pos(',',User.CityState) + 2),(Length(User.CityState))))); + IF (AACS1(User,RecNum,MenuOption)) AND NOT (Deleted IN User.SFlags) THEN + IF (Age = '') OR (Pos(Age,IntToStr(AgeUser(User.BirthDate))) > 0) THEN + IF (City = '') OR (Pos(City,AllCaps(UCity)) > 0) THEN + IF (DateLastOn = '') OR (Pos(DateLastOn,ToDate8(PD2Date(User.LastOn))) > 0) THEN + IF (Gender = '') OR (Pos(Gender,User.Sex) > 0) THEN + IF (RName = '') OR (Pos(RName,AllCaps(User.RealName)) > 0) THEN + IF (State = '') OR (Pos(State,AllCaps(UState)) > 0) THEN + IF (UName = '') OR (Pos(UName,User.Name) > 0) THEN + DisplayBuffer(UlistMCI,@User,Junk); + Inc(RecNum); + END; + Close(UserFile); + IF (NOT Abort) AND (NOT HangUp) THEN + PrintF(FN+'T'); + AllowContinue := FALSE; + END; + SysOpLog('Viewed User Listing.'); + LastError := IOResult; +END; + +FUNCTION TodaysCallerMCI(CONST S: ASTR; Data1,Data2: Pointer): STRING; +VAR + LastCallerPtr: LastCallerPtrType; + s1: STRING[100]; +BEGIN + LastCallerPtr := Data1; + TodaysCallerMCI := S; + CASE S[1] OF + 'C' : CASE S[2] OF + 'A' : TodaysCallerMCI := FormatNumber(LastCallerPtr^.Caller); + END; + 'D' : CASE S[2] OF + 'K' : TodaysCallerMCI := IntToStr(LastCallerPtr^.DK); + 'L' : TodaysCallerMCI := IntToStr(LastCallerPtr^.Downloads); + END; + 'E' : CASE S[2] OF + 'S' : TodaysCallerMCI := IntToStr(LastCallerPtr^.EmailSent); + END; + 'F' : CASE S[2] OF + 'S' : TodaysCallerMCI := IntToStr(LastCallerPtr^.FeedbackSent); + END; + 'L' : CASE S[2] OF + 'C' : TodaysCallerMCI := LastCallerPtr^.Location; + 'O' : BEGIN + s1 := PDT2Dat(LastCallerPtr^.LogonTime,0); + s1[0] := Char(Pos('m',s1) - 2); + s1[Length(s1)] := s1[Length(s1) + 1]; + TodaysCallerMCI := s1; + END; + 'T' : BEGIN + IF (LastCallerPtr^.LogoffTime = 0) THEN + S1 := 'Online' + ELSE + BEGIN + s1 := PDT2Dat(LastCallerPtr^.LogoffTime,0); + s1[0] := Char(Pos('m',s1) - 2); + s1[Length(s1)] := s1[Length(s1) + 1]; + END; + TodaysCallerMCI := s1; + END; + END; + 'M' : CASE S[2] OF + 'P' : TodaysCallerMCI := IntToStr(LastCallerPtr^.MsgPost); + 'R' : TodaysCallerMCI := IntToStr(LastCallerPtr^.MsgRead); + END; + 'N' : CASE S[2] OF + 'D' : TodaysCallerMCI := IntToStr(LastCallerPtr^.Node); + 'U' : IF (LastCallerPtr^.NewUser) THEN + TodaysCallerMCI := '*' + ELSE + TodaysCallerMCI := ' '; + END; + 'S' : CASE S[2] OF + 'P' : IF (LastCallerPtr^.Speed = 0) THEN + TodaysCallerMCI := 'Local' + ELSE IF (Telnet) THEN + TodaysCallerMCI := 'Telnet' + ELSE + TodaysCallerMCI := IntToStr(LastCallerPtr^.Speed); + END; + 'T' : CASE S[2] OF + 'O' : WITH LastCallerPtr^ DO + TodaysCallerMCI := IntToStr((LogoffTime - LogonTime) DIV 60); + END; + 'U' : CASE S[2] OF + 'K' : TodaysCallerMCI := IntToStr(LastCallerPtr^.UK); + 'L' : TodaysCallerMCI := IntToStr(LastCallerPtr^.Uploads); + 'N' : TodaysCallerMCI := LastCallerPtr^.UserName; + END; + END; +END; + +PROCEDURE TodaysCallers(x: Byte; MenuOptions: Str50); +VAR + Junk: Pointer; + LastCallerFile: FILE OF LastCallerRec; + LastCaller: LastCallerRec; + RecNum: Integer; +BEGIN + Abort := FALSE; + Next := FALSE; + AllowContinue := TRUE; + IF (MenuOptions = '') THEN + MenuOptions := 'LAST'; + IF (NOT ReadBuffer(MenuOptions+'M')) THEN + Exit; + Assign(LastCallerFile,General.DataPath+'LASTON.DAT'); + Reset(LastCallerFile); + IF (IOResult <> 0) THEN + Exit; + RecNum := 0; + IF (x > 0) AND (x <= FileSize(LastCallerFile)) THEN + RecNum := (FileSize(LastCallerFile) - x); + PrintF(MenuOptions+'H'); + Seek(LastCallerFile,RecNum); + WHILE (NOT EOF(LastCallerFile)) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Read(LastCallerFile,LastCaller); + IF (((LastCaller.LogonTime DIV 86400) <> (GetPackDateTime DIV 86400)) AND (x > 0)) OR + (((LastCaller.LogonTime DIV 86400) = (GetPackDateTime DIV 86400))) AND (NOT LastCaller.Invisible) THEN + DisplayBuffer(TodaysCallerMCI,@LastCaller,Junk); + END; + Close(LastCallerFile); + IF (NOT Abort) THEN + PrintF(MenuOptions+'T'); + AllowContinue := FALSE; + SysOpLog('Viewed Todays Callers.'); + LastError := IOResult; +END; + +PROCEDURE RGQuote(MenuOption: Str50); +VAR + StrPointerFile: FILE OF StrPointerRec; + StrPointer: StrPointerRec; + RGStrFile: FILE; + F, + F1: Text; + MHeader: MHeaderRec; + S: STRING; + StrNum: Word; + TotLoad: LongInt; +BEGIN + IF (MenuOption = '') THEN + Exit; + Assign(StrPointerFile,General.LMultPath+MenuOption+'.PTR'); + Reset(StrPointerFile); + TotLoad := FileSize(StrPointerFile); + IF (TotLoad < 1) THEN + Exit; + IF (TotLoad > 65535) THEN + Totload := 65535 + ELSE + Dec(TotLoad); + Randomize; + StrNum := Random(Totload); + Seek(StrPointerFile,StrNum); + Read(StrPointerFile,StrPointer); + Close(StrPointerFile); + LastError := IOResult; + IF (Exist(General.MiscPath+'QUOTEHDR.*')) THEN + PrintF('QUOTEHDR') + ELSE + BEGIN + NL; + Print('|03[[ |11And Now |03... |11A Quote For You! |03]]'); + NL; + END; + TotLoad := 0; + Assign(RGStrFile,General.LMultPath+MenuOption+'.DAT'); + Reset(RGStrFile,1); + Seek(RGStrFile,(StrPointer.Pointer - 1)); + REPEAT + BlockRead(RGStrFile,S[0],1); + BlockRead(RGStrFile,S[1],Ord(S[0])); + Inc(TotLoad,(Length(S) + 1)); + IF (S[Length(S)] = '@') THEN + BEGIN + Dec(S[0]); + Prt(Centre(S)); + END + ELSE + PrintACR(Centre(S)); + UNTIL (TotLoad >= StrPointer.TextSize) OR EOF(RGStrFile); + Close(RGStrFile); + LastError := IOResult; + IF (Exist(General.MiscPath+'QUOTEFTR.*')) THEN + PrintF('QUOTEFTR') + ELSE + BEGIN + NL; + Print('|03[]'); + NL; + END; + IF (NOT General.UserAddQuote) THEN + PauseScr(FALSE) + ELSE IF (PYNQ('Would you like to add a quote? ',0,FALSE)) THEN + BEGIN + PrintF('QUOTE'); + InResponseTo := ''; + MHeader.Status := []; + IF (InputMessage(TRUE,FALSE,'New Quote',MHeader,General.LMultPath+MenuOption+'.TMP',78,500)) then + IF Exist(General.LMultPath+MenuOption+'.TMP') THEN + BEGIN + Assign(F,General.LMultPath+MenuOption+'.NEW'); + Reset(F); + IF (IOResult <> 0) THEN + ReWrite(F) + ELSE + Append(F); + Assign(F1,General.LMultPath+MenuOption+'.TMP'); + Reset(F1); + IF (IOResult <> 0) THEN + Exit; + WriteLn(F,'New quote from: '+Caps(ThisUser.Name)+' #'+IntToStr(UserNum)+'.'); + WriteLn(F,''); + WriteLn(F,'$'); + WHILE (NOT EOF(F1)) DO + BEGIN + ReadLn(F1,S); + WriteLn(F,S); + END; + WriteLn(F,'$'); + WriteLn(F,''); + WriteLn(F); + Close(F); + Close(F1); + Kill(General.LMultPath+MenuOption+'.TMP'); + NL; + Print('^7Your new quote was saved.'); + PauseScr(FALSE); + SendShortMessage(1,Caps(ThisUser.Name)+' added a new quote to "'+MenuOption+'.NEW".'); + END; + END; +END; + +END. diff --git a/SOURCE/COMMON.PAS b/SOURCE/COMMON.PAS new file mode 100644 index 0000000..e49a2e1 --- /dev/null +++ b/SOURCE/COMMON.PAS @@ -0,0 +1,5076 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N+,O-,R-,S-,V-} + +UNIT Common; + +INTERFACE + +USES + Crt, + Dos, + MyIO, + TimeFunc; + +{$I RECORDS.PAS} + +CONST + StrLen = 119; + +TYPE + MCIFunctionType = FUNCTION(CONST s: AStr; Data1, Data2: Pointer): STRING; + + MemMenuRec = RECORD { Menu Record } + LDesc: ARRAY[1..3] OF STRING[100]; { menu name } + ACS: ACString; { access requirements } + NodeActivityDesc: STRING[50]; + MenuFlags: MenuFlagSet; { menu status variables } + LongMenu: STRING[12]; { displayed IN place OF long menu } + MenuNum: Byte; { menu number } + MenuPrompt: STRING[120]; { menu Prompt } + Password: STRING[20]; { password required } + FallBack: Byte; { fallback menu } + Directive: STRING[12]; + ForceHelpLevel: Byte; { forced help Level FOR menu } + GenCols: Byte; { generic menus: # OF columns } + GCol: ARRAY[1..3] OF Byte; { generic menus: colors } + END; + + MemCmdRec = RECORD { Command records } + LDesc: STRING[100]; { long command description } + ACS: ACString; { access requirements } + NodeActivityDesc: STRING[50]; + CmdFlags: CmdFlagSet; { command status variables } + SDesc: STRING[35]; { short command description } + CKeys: STRING[14]; { command-execution keys } + CmdKeys: STRING[2]; { command keys: type OF command } + Options: STRING[50]; { MString: command data } + END; + + LightBarRecordType = RECORD + XPos, + YPos: Byte; + CmdToExec: SmallInt; + CmdToShow: STRING[40]; + END; + + States = + (Waiting, + Bracket, + Get_Args, + Get_Param, + Eat_Semi, + In_Param, + GetAvCmd, + GetAvAttr, + GetAvRLE1, + GetAvRLE2, + GetAvX, + GetAvY); + + StorageType = + (Disk, + CD, + Copied); + + TransferFlagType = + (lIsAddDLBatch, + IsFileAttach, + IsUnlisted, + IsTempArc, + IsQWK, + IsNoFilePoints, + IsNoRatio, + IsCheckRatio, + IsCDRom, + IsPaused, + IsAutoLogOff, + IsKeyboardAbort, + IsTransferOk); + + TransferFlagSet = SET OF TransferFlagType; + + BatchDLRecordType = RECORD + BDLFileName: Str52; + BDLOwnerName: Str36; + BDLStorage: StorageType; + BDLUserNum, + BDLSection, + BDLPoints, + BDLUploader: SmallInt; + BDLFSize, + BDLTime: LongInt; + BDLFlags: TransferFlagSet; + END; + + BatchULRecordType = RECORD + BULFileName: Str12; + BULUserNum, + BULSection: SmallInt; + BULDescription: Str50; + BULVPointer: LongInt; + BULVTextSize: SmallInt; + END; + + ExtendedDescriptionArray = ARRAY [1..99] OF Str50; + + IEMSIRecord = RECORD + UserName, + Handle: STRING[36]; + CityState: STRING[30]; + Ph: STRING[12]; + PW: STRING[20]; + BDate: STRING[10]; + END; + + StrPointerRec = RECORD + Pointer, + TextSize: LongInt; + END; + + MemCmdPointer = ^MemCmdArray; + MemCmdArray = ARRAY [1..MaxCmds] OF MemCmdRec; + + MCIBufferType = ARRAY [1..MaxConfigurable] OF Char; + MCIBufferPtr = ^MCIBufferType; + + Multitasker = + (None, (* Dos 5 thu 9 *) + DV, + Win, + OS2, + Win32, + DOS5N); + + InputFlagType = + (UpperOnly, { Uppercase only } + ColorsAllowed, { Colors allowed } + NoLineFeed, { Linefeeds OFF - no linefeed after pressed } + ReDisplay, { Display old IF no change } + CapWords, { Capitalize characters } + InterActiveEdit, { Interactive editing } + NumbersOnly, + DisplayValue, + NegativeAllowed); { Numbers only } + + InputFlagSet = SET OF InputFlagType; + + ValidationKeyType = SET OF '!'..'~'; (* Remove q and Q *) + + ConferenceKeyType = SET OF '@'..'Z'; + + CompArrayType = ARRAY[0..1] OF SMALLINT; + +CONST + MCIBuffer: MCIBufferPtr = NIL; + DieLater: Boolean = FALSE; { IF TRUE, Renegade locks up } + F_HOME = 18176; { 256 * Scan Code } + F_UP = 18432; + F_PGUP = 18688; + F_LEFT = 19200; + F_RIGHT = 19712; + F_END = 20224; + F_DOWN = 20480; + F_PGDN = 20736; + F_INS = 20992; + F_DEL = 21248; + F_CTRLLEFT = 29440; + F_CTRLRIGHT = 29696; + NoCallInitTime = (30 * 60); { thirty minutes between modem inits } + Tasker: Multitasker = None; + LastScreenSwap: LongInt = 0; + ParamArr: ARRAY [1..5] OF Word = (0,0,0,0,0); + Params: Word = 0; { number OF parameters } + NextState: States = Waiting; { Next state FOR the parser } + TempSysOp: Boolean = FALSE; { is temporary sysop? } + Reverse: Boolean = FALSE; { TRUE IF Text attributes are reversed } + TimeLock: Boolean = FALSE; { IF TRUE, DO NOT HangUp due TO time! } + SaveX: Byte = 0; { FOR ANSI driver} + SaveY: Byte = 0; { FOR ANSI driver} + TempPause: Boolean = TRUE; { is Pause on OR off? Set at prompts, OneK, used everywhere } + OfflineMail: Boolean = FALSE; { are we IN the offline mail system? } + MultiNodeChat: Boolean = FALSE; { are we IN MultiNode chat?} + ChatChannel: Integer = 0; { What chat channel are we IN? } + DisplayingMenu: Boolean = FALSE; { are we displaying a menu? } + InVisEdit: Boolean = FALSE; { are we IN the visual editor? } + MenuAborted: Boolean = FALSE; { was the menu Aborted? } + AllowAbort: Boolean = TRUE; { are Aborts allowed? } + MCIAllowed: Boolean = TRUE; { is mci allowed? } + ColorAllowed: Boolean = TRUE; { is color allowed? } + Echo: Boolean = TRUE; { is Text being echoed? (FALSE=use echo Chr)} + HangUp: Boolean = TRUE; { is User offline now? } + TimedOut: Boolean = FALSE; { has he timed out? } + NoFile: Boolean = TRUE; { did last pfl() FILE NOT Exist? } + SLogging: Boolean = TRUE; { are we outputting TO the SysOp log? } + SysOpOn: Boolean = TRUE; { is SysOp logged onto the WFC menu? } + WantOut: Boolean = TRUE; { output Text locally? } + WColor: Boolean = TRUE; { IN chat: was last key pressed by SysOp? } + BadDLPath: Boolean = FALSE; { is the current DL path BAD? } + BadUlPath: Boolean = FALSE; { is the current UL path BAD? } + BeepEnd: Boolean = FALSE; { whether TO beep after caller logs off } + FileAreaNameDisplayed: Boolean = FALSE; { was FILE area name printed yet? } + CFO: Boolean = FALSE; { is chat FILE open? } + InChat: Boolean = FALSE; { are we IN chat Mode? } + ChatCall: Boolean = FALSE; { is the chat call "noise" on? } + ContList: Boolean = FALSE; { continuous message listing Mode on? } + CROff: Boolean = FALSE; { are CRs turned off? } + CtrlJOff: Boolean = FALSE; { turn color TO #1 after ^Js?? } + DoneAfterNext: Boolean = FALSE; { offhook AND Exit after Next logoff? } + DoneDay: Boolean = FALSE; { are we done now? ready TO drop TO DOS?} + DOSANSIOn: Boolean = FALSE; { output chrs TO DOS FOR ANSI codes?!!? } + FastLogon: Boolean = FALSE; { IF a FAST LOGON is requested } + HungUp: Boolean = FALSE; { did User drop carrier? } + InCom: Boolean = FALSE; { accepting input from com? } + InWFCMenu: Boolean = FALSE; { are we IN the WFC menu? } + LastCommandGood: Boolean = FALSE;{ was last command a REAL command? } + LastCommandOvr: Boolean = FALSE; { override Pause? (NO Pause?) } + LocalIOOnly: Boolean = FALSE; { local I/O ONLY? } + MakeQWKFor: Integer = 0; { make a qwk packet ONLY? } + UpQWKFor: Integer = 0; { upload a qwk packet ONLY? } + RoomNumber: Integer = 0; { Room OF teleconference } + PackBasesOnly: Boolean = FALSE; { pack message bases ONLY? } + SortFilesOnly: Boolean = FALSE; { sort FILE bases ONLY? } + FileBBSOnly: Boolean = FALSE; + NewMenuToLoad: Boolean = FALSE; { menu command returns TRUE IF new menu TO load } + OvrUseEMS: Boolean = TRUE; + OverLayLocation: Byte = 0; { 0=Normal, 1=EMS, 2=XMS } + OutCom: Boolean = FALSE; { outputting TO com? } + DirFileopen1: Boolean = TRUE; { whether DirFile has been opened before } + ExtFileOpen1: Boolean = TRUE; + PrintingFile: Boolean = FALSE; { are we printing a FILE? } + AllowContinue: Boolean = FALSE; { Allow Continue prompts? } + QuitAfterDone: Boolean = FALSE; { quit after Next User logs off? } + Reading_A_Msg: Boolean = FALSE; { is User reading a message? } + ReadingMail: Boolean = FALSE; { reading private mail? } + ShutUpChatCall: Boolean = FALSE; { was chat call "SHUT UP" FOR this call? } + Trapping: Boolean = FALSE; { are we Trapping users Text? } + UserOn: Boolean = FALSE; { is there a User on right now? } + WasNewUser: Boolean = FALSE; { did a NEW User log on? } + Write_Msg: Boolean = FALSE; { is User writing a message? } + NewEchoMail: Boolean = FALSE; { has new echomail been entered? } + TimeWarn: Boolean = FALSE; { has User been warned OF time shortage? } + TellUserEvent: Byte = 0; { has User been told about the up-coming event? } + ExitErrors: Byte = 1; { errorLEVEL FOR Critical error Exit } + ExitNormal: Byte = 0; { errorLEVEL FOR Normal Exit } + TodayCallers: Integer = 0; { new system callers } + lTodaynumUsers: Integer = 0; { new number OF users } + ThisNode: Byte = 0; { node number } + AnswerBaud: LongInt = 0; { baud rate TO answer the phone at } + ExtEventTime: Word = 0; { # minutes before External event } + IsInvisible: Boolean = FALSE; { Run IN invisible Mode? } + SaveNDescription: STRING[50] = 'Miscellaneous'; + SaveNAvail: Boolean = FALSE; + LastWFCX: Byte = 1; + LastWFCY: Byte = 1; + ANSIDetected: Boolean = FALSE; +{ Added June 21, 2013 //sk5 } + PauseIsNull : Boolean = FALSE; { Added for null pause } + BuildDate : Array [1..5] of Word = ( 5, 27, 2013, 9, 19 ); { Build date MM, DD, YYYY, HR, MIN } + +VAR + LightBarArray: ARRAY[1..50] OF LightBarRecordType; + LightBarCmd, + LightBarCounter: Byte; + LightBarFirstCmd: Boolean; + + Telnet: Boolean; + HangUpTelnet: Boolean; + + DatFilePath: STRING[40]; + Interrupt14: Pointer; { far ptr TO interrupt 14 } +{$IFDEF MSDOS} + Ticks: LongInt ABSOLUTE $0040:$006C; +{$ENDIF} + IEMSIRec: IEMSIRecord; + FossilPort: Word; + SockHandle: STRING; { Telnet Handle } + CallerIDNumber: STRING[40]; { Caller ID STRING obtained from modem } + ActualSpeed: LongInt; { Actual connect rate } + Reliable: Boolean; { error correcting connection? } + ComPortSpeed: LongInt; { com port rate } + LastError: Integer; { Results from last IOResult, when needed } + + General: GeneralRecordType; { configuration information } + + DirInfo: SearchRec; + + { LastCallers } + LastCallerFile : FILE OF LastCallerRec; + LastCallers : LastCallerRec; + + { Today's History } + HistoryFile : FILE OF HistoryRecordType; + HistoryRec : HistoryRecordType; + + { Voting Variables } + VotingFile: FILE OF VotingRecordType; + Topic: VotingRecordType; + NumVotes: Byte; + + BBSListFile: FILE OF BBSListRecordType; { bbslist.dat } + + { Conference Variables } + ConferenceFile: FILE OF ConferenceRecordType; { CONFRENC.DAT } + Conference: ConferenceRecordType; { Conferences } + ConfKeys: ConferenceKeyType; + NumConfKeys: Integer; + CurrentConf: Char; { Current conference tag } + ConfSystem: Boolean; { is the conference system enabled? } + + { Validation Variables } + ValidationFile: FILE OF ValidationRecordType; + Validation: ValidationRecordType; + NumValKeys: Byte; + ValKeys: ValidationKeyType; + + NumArcs: Byte; + + NodeFile: FILE OF NodeRecordType; { multi node FILE } + NodeR: NodeRecordType; + NodeChatLastRec: LongInt; { last record IN group chat FILE Read } + + Liner: LineRec; + + SysOpLogFile, { SYSOP.LOG } + SysOpLogFile1, { SLOGxxxx.LOG } + TrapFile, { TRAP*.MSG } + ChatFile: Text; { CHAT*.MSG } + + + { User Variables } + UserFile: FILE OF UserRecordType; { User.LST } + UserIDXFile: FILE OF UserIDXRec; { User.IDX } + ThisUser: UserRecordType; { User's account records } + + { Color Scheme Variables } + SchemeFile: FILE OF SchemeRec; { SCHEME.DAT } + Scheme: SchemeRec; + NumSchemes: Integer; + + { Event Variables } + EventFile: FILE OF EventRecordType; + MemEventArray: ARRAY [1..MaxEvents] OF ^EventRecordType; + Event: EventRecordType; + NumEvents: Integer; { # OF events } + + { Protocol Variables } + ProtocolFile: FILE OF ProtocolRecordType; { PROTOCOL.DAT } + Protocol: ProtocolRecordType; { protocol IN memory } + NumProtocols: Integer; + + { File Variables } + FileAreaFile: FILE OF FileAreaRecordType; { FBASES.DAT } + MemFileArea, + TempMemFileArea: FileAreaRecordType; { File area and temporary file area in memory } + FileInfoFile: FILE OF FileInfoRecordType; { *.DIR } + ExtInfoFile: FILE; { *.EXT } + FileInfo: FileInfoRecordType; + ExtendedArray: ExtendedDescriptionArray; + NewFilesF: Text; { For NEWFILES.DAT in the qwk system } + FileArea, { File base User is in } + NumFileAreas, { Max number OF FILE bases } + ReadFileArea, { current uboard # IN memory } + LowFileArea, + HighFileArea: Integer; + NewScanFileArea: Boolean; { New scan this base? } + + { Batch Download Variables } + BatchDLFile: FILE OF BatchDLRecordType; + BatchDL: BatchDLRecordType; + NumBatchDLFiles: Byte; { # files IN DL batch queue } + BatchDLSize, + BatchDLPoints, + BatchDLTime: LongInt; { } + + { Batch Upload Variables } + BatchULFile: FILE OF BatchULRecordType; + BatchULF: FILE; + BatchUL: BatchULRecordType; + NumBatchULFiles: Byte; { # files IN UL batch queue } + + { Message Variables } + EmailFile: FILE OF MessageAreaRecordType; + MsgAreaFile: FILE OF MessageAreaRecordType; { MBASES.DAT } + MemMsgArea: MessageAreaRecordType; { MsgArea IN memory } + MsgHdrF: FILE OF MHeaderRec; { *.HDR } + MsgTxtF: FILE; { *.DAT } + LastReadRecord: ScanRec; + LastAuthor, { Author # OF the last message } + NumMsgAreas, { Max number OF msg bases } + MsgArea, + ReadMsgArea, + LowMsgArea, + HighMsgArea: Integer; + Msg_On: Word; { current message being Read } + + { Menu Variables } + MenuFile: FILE OF MenuRec; + MenuR: MenuRec; + MemMenu: MemMenuRec; { menu information } + MemCmd: MemCmdPointer; { Command information } + MenuRecNumArray: ARRAY [1..MaxMenus] OF Integer; + CmdNumArray: ARRAY [1..MaxMenus] OF Byte; + MenuStack: ARRAY [1..MaxMenus] OF Byte; { menu stack } + MenuKeys: AStr; { keys TO Abort menu display WITH } + NumMenus, + NumCmds, + GlobalCmds, + MenuStackPtr, + FallBackMenu, + CurMenu, + CurHelpLevel: Byte; + + Buf: STRING[255]; { macro buffer } + MLC: STRING[255]; { multiline FOR chat } + + ChatReason, { last chat reason } + LastLineStr, { "last-line" STRING FOR Word-wrapping } + StartDir: AStr; { Directory BBS was executed from } + + TempDir, { Temporary Directory base name } + InResponseTo: STRING[40]; { reason FOR reply } + + LastDIRFileName: Str12; { last filename FOR recno/nrecno } + + CurrentColor, { current ANSI color } + ExiterrorLevel, { errorLEVEL TO Exit WITH } + TShuttleLogon, { type OF special Shuttle Logon command } + TFilePrompt, { type OF special FILE Prompt command } + TReadPrompt, { type OF special Read Prompt command } + + PublicPostsToday, { posts made by User this call } + FeedBackPostsToday, { feedback sent by User this call } + PrivatePostsToday: Byte; { E-mail sent by User this call } + + LastDIRRecNum, { last record # FOR recno/nrecno } + ChatAttempts, { number chat attempts made by User } + LIL, { lines on screen since last PauseScr() } + + PublicReadThisCall, { # public messages has Read this call } + + UserNum: Integer; { User's User number } + + Rate: Word; { cps FOR FILE transfers } + + NewFileDate, { NewScan Pointer date } + + DownloadsToday, { download sent TO User this call } + UploadsToday, { uploads sent by User this call } + DownloadKBytesToday, { download k by User this call } + UploadKBytesToday, { upload k by User this call } + + CreditsLastUpdated, { Time Credits last updated } + TimeOn, { time User logged on } + LastBeep, + LastKeyHit, + ChopTime, { time TO chop off FOR system events } + ExtraTime, { extra time - given by F7/F8, etc } + CreditTime, { credit time adjustment } + FreeTime: LongInt; { free time } + + BlankMenuNow, { is the wfcmenu blanked out? } + Abort, + Next, { global Abort AND Next } + RQArea, + FQArea, + MQArea, + VQArea: Boolean; + +{$IFDEF WIN32} +procedure Sound(hz: Word; duration: Word); +function Ticks: LongInt; +{$ENDIF} +FUNCTION GetC(c: Byte): STRING; +PROCEDURE ShowColors; +FUNCTION CheckDriveSpace(S,Path: AStr; MinSpace: Integer): Boolean; +FUNCTION StripLeadSpace(S: STRING): STRING; +FUNCTION StripTrailSpace(S: STRING): STRING; +FUNCTION SemiCmd(S: AStr; B: Byte): STRING; +FUNCTION ExistDrive(Drive: Char): Boolean; +PROCEDURE RenameFile(DisplayStr: AStr; OldFileName,NewFileName: AStr; VAR ReNameOk: Boolean); +FUNCTION GetFileSize(FileName: AStr): LongInt; +PROCEDURE GetFileDateTime(CONST FileName: AStr; VAR FileTime: LongInt); +PROCEDURE SetFileDateTime(CONST FileName: AStr; FileTime: LongInt); +FUNCTION PHours(CONST DisplayStr: AStr; LoTime,HiTime: Integer): AStr; +FUNCTION RGSysCfgStr(StrNum: LongInt; PassValue: Boolean): AStr; +FUNCTION RGNoteStr(StrNum: LongInt; PassValue: Boolean): AStr; +FUNCTION RGMainStr(StrNum: LongInt; PassValue: Boolean): AStr; +FUNCTION lRGLNGStr(StrNum: LongInt; PassValue: Boolean): AStr; +PROCEDURE GetPassword(VAR PW: AStr; Len: Byte); +PROCEDURE MakeDir(VAR Path: PathStr; AskMakeDir: Boolean); +PROCEDURE Messages(Msg,MaxRecs: Integer; AreaName: AStr); +PROCEDURE DisplayBuffer(MCIFunction: MCIFunctionType; Data1, Data2:Pointer); +FUNCTION ReadBuffer(FileName: AStr): Boolean; +FUNCTION chinkey: Char; +FUNCTION FormatNumber(L: LongInt): STRING; +FUNCTION ConvertBytes(BytesToConvert: LongInt; OneChar: Boolean): STRING; +FUNCTION ConvertKB(KBToConvert: LongInt; OneChar: Boolean): STRING; +PROCEDURE WriteWFC(c: Char); +FUNCTION AccountBalance: LongInt; +PROCEDURE AdjustBalance(Adjustment: LongInt); +PROCEDURE BackErase(Len: Byte); +FUNCTION UpdateCRC32(CRC: LongInt; VAR Buffer; Len: Word): LongInt; +FUNCTION CRC32(s: AStr): LongInt; +FUNCTION FunctionalMCI(CONST s: AStr; FileName,InternalFileName: AStr): STRING; +FUNCTION MCI(CONST s: STRING): STRING; +FUNCTION Plural(InString: STRING; Number: Byte): STRING; +FUNCTION FormattedTime(TimeUsed: LongInt): STRING; +FUNCTION SearchUser(Uname: Str36; RealNameOK: Boolean): Integer; +PROCEDURE PauseScr(IsCont: Boolean); +PROCEDURE Com_Send_Str(CONST InString: AStr); +PROCEDURE dophoneHangup(ShowIt: Boolean); +PROCEDURE DoTelnetHangUp(ShowIt: Boolean); +PROCEDURE DoPhoneOffHook(ShowIt: Boolean); +PROCEDURE InputPath(CONST DisplayStr: AStr; VAR DirPath: Str40; CreateDir,AllowExit: Boolean; VAR Changed: Boolean); +FUNCTION StripName(InString: STRING): STRING; +PROCEDURE PurgeDir(s: AStr; SubDirs: Boolean); +PROCEDURE DOSANSI(CONST c: Char); +FUNCTION HiMsg: Word; +FUNCTION OnNode(UserNumber: Integer): Byte; +FUNCTION MaxUsers: Integer; +PROCEDURE Kill(CONST FileName: AStr); +PROCEDURE ScreenDump(CONST FileName: AStr); +PROCEDURE ScanInput(VAR s: AStr; CONST Allowed: AStr); +PROCEDURE Com_Flush_Recv; +PROCEDURE Com_Flush_Send; +PROCEDURE Com_Purge_Send; +FUNCTION Com_Carrier: Boolean; +FUNCTION Com_Recv: Char; +FUNCTION Com_IsRecv_Empty: Boolean; +FUNCTION Com_IsSend_Empty: Boolean; +PROCEDURE Com_Send(c: Char); +PROCEDURE Com_Set_Speed(Speed: LongInt); +PROCEDURE Com_DeInstall; +PROCEDURE Com_Install; +PROCEDURE CheckHangup; +PROCEDURE SerialOut(s: STRING); +FUNCTION Empty:Boolean; +PROCEDURE DTR(Status: Boolean); +PROCEDURE BackSpace; +PROCEDURE DoBackSpace(Start,Finish: Byte); +FUNCTION LennMCI(CONST InString: STRING): Integer; +FUNCTION MsgSysOp: Boolean; +FUNCTION FileSysOp: Boolean; +FUNCTION CoSysOp: Boolean; +FUNCTION SysOp: Boolean; +FUNCTION Timer: LongInt; +PROCEDURE TeleConfCheck; +FUNCTION Substitute(Src: STRING; CONST old,New: STRING): STRING; +PROCEDURE NewCompTables; +FUNCTION OkANSI: Boolean; +FUNCTION OkAvatar: Boolean; +FUNCTION OkRIP: Boolean; +FUNCTION OkVT100: Boolean; +FUNCTION NSL: LongInt; +FUNCTION AgeUser(CONST BirthDate: LongInt): Word; +FUNCTION AllCaps(Instring: STRING): STRING; +FUNCTION Caps(Instring: STRING): STRING; +PROCEDURE Update_Screen; +FUNCTION PageLength: Word; +PROCEDURE lStatus_Screen(WhichScreen: Byte; Message: AStr; OneKey: Boolean; VAR Answer: AStr); +FUNCTION CInKey: Char; +FUNCTION CheckPW: Boolean; +FUNCTION StripColor(CONST InString: STRING): STRING; +PROCEDURE sl1(s: AStr); +PROCEDURE SysOpLog(s: AStr); +FUNCTION StrToInt(S: Str11): LongInt; +FUNCTION RealToStr(R: Real; W,D: Byte): STRING; +FUNCTION ValueR(S: AStr): REAL; +PROCEDURE ShellDos(MakeBatch: Boolean; CONST Command: AStr; VAR ResultCode: Integer); +PROCEDURE SysOpShell; +PROCEDURE RedrawForANSI; +PROCEDURE Star(InString: AStr); +FUNCTION GetKey: Word; +PROCEDURE SetC(C: Byte); +PROCEDURE UserColor(Color: Byte); +PROCEDURE Prompt(CONST InString: STRING); +FUNCTION SQOutSp(InString: STRING): STRING; +FUNCTION ExtractDriveNumber(s: AStr): Byte; +FUNCTION PadLeftStr(InString: STRING; MaxLen: Byte): STRING; +FUNCTION PadRightStr(InString: STRING; MaxLen: Byte): STRING; +FUNCTION PadLeftInt(L: LongInt; MaxLen: Byte): STRING; +FUNCTION PadRightInt(L: LongInt; MaxLen: Byte): STRING; +PROCEDURE Print(CONST InString: STRING); +PROCEDURE NL; +PROCEDURE Prt(CONST Instring: STRING); +PROCEDURE MPL(MaxLen: Byte); +FUNCTION CTP(t,b: LongInt): STRING; +PROCEDURE TLeft; +PROCEDURE LoadNode(NodeNumber: Byte); +PROCEDURE Update_Node(NActivityDesc: AStr; SaveVars: Boolean); +FUNCTION MaxNodes: Byte; +FUNCTION MaxChatRec: LongInt; +PROCEDURE SaveNode(NodeNumber: Byte); +PROCEDURE LoadURec(VAR User: UserRecordType; UserNumber: Integer); +PROCEDURE SaveURec(User: UserRecordType; UserNumber:Integer); +FUNCTION MaxIDXRec: Integer; +FUNCTION InKey: Word; +PROCEDURE OutKey(c: Char); +PROCEDURE CLS; +PROCEDURE Wait(b: Boolean); +FUNCTION DisplayARFlags(AR: ARFlagSet; C1,C2: Char): AStr; +PROCEDURE ToggleARFlag(Flag: Char; VAR AR: ARFlagSet; VAR Changed: Boolean); +FUNCTION DisplayACFlags(Flags: FlagSet; C1,C2: Char): AStr; +PROCEDURE ToggleACFlag(Flag: FlagType; VAR Flags: FlagSet); +PROCEDURE ToggleACFlags(Flag: Char; VAR Flags: FlagSet; VAR Changed: Boolean); +PROCEDURE ToggleStatusFlag(Flag: StatusFlagType; VAR SUFlags: StatusFlagSet); +PROCEDURE ToggleStatusFlags(Flag: Char; VAR SUFlags: StatusFlagSet); +FUNCTION TACCH(Flag: Char): FlagType; +PROCEDURE LCmds(Len,c: Byte; c1,c2: AStr); +PROCEDURE LCmds3(Len,c: Byte; c1,c2,c3: AStr); +PROCEDURE InitTrapFile; +FUNCTION AOnOff(b: Boolean; CONST s1,s2: AStr): STRING; +FUNCTION ShowOnOff(b: Boolean): STRING; +FUNCTION ShowYesNo(b: Boolean): STRING; +FUNCTION YN(Len: Byte; DYNY: Boolean): Boolean; +FUNCTION PYNQ(CONST InString: AStr; MaxLen: Byte; DYNY: Boolean): Boolean; +PROCEDURE InputLongIntWC(S: AStr; VAR L: LongInt; InputFlags: InputFlagSet; LowNum,HighNum: LongInt; VAR Changed: Boolean); +PROCEDURE InputLongIntWOC(S: AStr; VAR L: LongInt; InputFlags: InputFlagSet; LowNum,HighNum: LongInt); +PROCEDURE InputWordWC(S: AStr; VAR W: SmallWord; InputFlags: InputFlagSet; LowNum,HighNum: Word; VAR Changed: Boolean); +PROCEDURE InputWordWOC(S: AStr; VAR W: SmallWord; InputFlags: InputFlagSet; LowNum,HighNum: Word); +PROCEDURE InputIntegerWC(S: AStr; VAR I: SmallInt; InputFlags: InputFlagSet; LowNum,HighNum: Integer; VAR Changed: Boolean); +PROCEDURE InputIntegerWOC(S: AStr; VAR I: SmallInt; InputFlags: InputFlagSet; LowNum,HighNum: Integer); +PROCEDURE InputByteWC(S: AStr; VAR B: Byte; InputFlags: InputFlagSet; LowNum,HighNum: Byte; VAR Changed: Boolean); +PROCEDURE InputByteWOC(S: AStr; VAR B: Byte; InputFlags: InputFlagSet; LowNum,HighNum: Byte); +PROCEDURE InputDefault(VAR S: STRING; v: STRING; MaxLen: Byte; InputFlags: InputFlagSet; LineFeed: Boolean); +PROCEDURE InputFormatted(DisplayStr: AStr; VAR InputStr: STRING; v: STRING; Abortable: Boolean); +PROCEDURE InputWN1(DisplayStr: AStr; VAR InputStr: AStr; MaxLen: Byte; InputFlags: InputFlagSet; VAR Changed: Boolean); +PROCEDURE InputWNWC(DisplayStr: AStr; VAR InputStr: AStr; MaxLen: Byte; VAR Changed: Boolean); +PROCEDURE InputMain(VAR s: STRING; MaxLen: Byte; InputFlags: InputFlagSet); +PROCEDURE InputWC(VAR s: STRING; MaxLen: Byte); +PROCEDURE Input(VAR s: STRING; MaxLen: Byte); +PROCEDURE InputL(VAR s: STRING; MaxLen: Byte); +PROCEDURE InputCaps(VAR s: STRING; MaxLen: Byte); +PROCEDURE OneK(VAR C: Char; ValidKeys: AStr; DisplayKey,LineFeed: Boolean); +PROCEDURE OneK1(VAR C: Char; ValidKeys: AStr; DisplayKey,LineFeed: Boolean); +PROCEDURE LOneK(DisplayStr: AStr; VAR C: Char; ValidKeys: AStr; DisplayKey,LineFeed: Boolean); +PROCEDURE Local_Input1(VAR S: STRING; MaxLen: Byte; LowerCase: Boolean); +PROCEDURE Local_Input(VAR S: STRING; MaxLen: Byte); +PROCEDURE Local_InputL(VAR S: STRING; MaxLen: Byte); +PROCEDURE Local_OneK(VAR C: Char; S: STRING); +FUNCTION Centre(InString: AStr): STRING; +PROCEDURE WKey; +PROCEDURE PrintMain(CONST ss: STRING); +PROCEDURE PrintACR(InString: STRING); +PROCEDURE SaveGeneral(X: Boolean); +PROCEDURE pfl(FN: AStr); +PROCEDURE PrintFile(FileName: AStr); +FUNCTION BSlash(InString: AStr; b: Boolean): AStr; +FUNCTION Exist(FileName: AStr): Boolean; +FUNCTION ExistDir(Path: PathStr): Boolean; +PROCEDURE PrintF(FileName: AStr); +PROCEDURE SKey1(VAR c: Char); +FUNCTION VerLine(B: Byte): STRING; +FUNCTION AACS1(User: UserRecordType; UNum: Integer; S: ACString): Boolean; +FUNCTION AACS(s: ACString): Boolean; +FUNCTION DiskKBFree(DrivePath: AStr): LongInt; +FUNCTION IntToStr(L: LongInt): STRING; + +IMPLEMENTATION + +USES + Common1, + Common2, + Common3, + Common4, + Events, + File0, + File11, + Mail0, + MultNode, +{$IFDEF MSDOS} + SpawnO, +{$ENDIF} + SysOp12, + Vote +{$IFDEF WIN32} + ,VPSysLow + ,VPUtils + ,Windows +{$ENDIF} + ; + +{$IFDEF WIN32} +procedure Sound(hz: Word; duration: Word); +begin + Windows.Beep(hz, duration); +end; + +function Ticks: LongInt; +begin + Ticks := GetTimeMSec div 55; +end; +{$ENDIF} + +{$IFDEF MSDOS} +FUNCTION UpdateCRC32(CRC: LongInt; VAR Buffer; Len: Word): LongInt; EXTERNAL; +{$L CRC32.OBJ } +{$ENDIF} +{$IFDEF WIN32} +CONST + CRC_32_TAB : array[0..255] of LongInt = ( + $00000000, $77073096, $ee0e612c, $990951ba, $076dc419, + $706af48f, $e963a535, $9e6495a3, $0edb8832, $79dcb8a4, + $e0d5e91e, $97d2d988, $09b64c2b, $7eb17cbd, $e7b82d07, + $90bf1d91, $1db71064, $6ab020f2, $f3b97148, $84be41de, + $1adad47d, $6ddde4eb, $f4d4b551, $83d385c7, $136c9856, + $646ba8c0, $fd62f97a, $8a65c9ec, $14015c4f, $63066cd9, + $fa0f3d63, $8d080df5, $3b6e20c8, $4c69105e, $d56041e4, + $a2677172, $3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b, + $35b5a8fa, $42b2986c, $dbbbc9d6, $acbcf940, $32d86ce3, + $45df5c75, $dcd60dcf, $abd13d59, $26d930ac, $51de003a, + $c8d75180, $bfd06116, $21b4f4b5, $56b3c423, $cfba9599, + $b8bda50f, $2802b89e, $5f058808, $c60cd9b2, $b10be924, + $2f6f7c87, $58684c11, $c1611dab, $b6662d3d, $76dc4190, + $01db7106, $98d220bc, $efd5102a, $71b18589, $06b6b51f, + $9fbfe4a5, $e8b8d433, $7807c9a2, $0f00f934, $9609a88e, + $e10e9818, $7f6a0dbb, $086d3d2d, $91646c97, $e6635c01, + $6b6b51f4, $1c6c6162, $856530d8, $f262004e, $6c0695ed, + $1b01a57b, $8208f4c1, $f50fc457, $65b0d9c6, $12b7e950, + $8bbeb8ea, $fcb9887c, $62dd1ddf, $15da2d49, $8cd37cf3, + $fbd44c65, $4db26158, $3ab551ce, $a3bc0074, $d4bb30e2, + $4adfa541, $3dd895d7, $a4d1c46d, $d3d6f4fb, $4369e96a, + $346ed9fc, $ad678846, $da60b8d0, $44042d73, $33031de5, + $aa0a4c5f, $dd0d7cc9, $5005713c, $270241aa, $be0b1010, + $c90c2086, $5768b525, $206f85b3, $b966d409, $ce61e49f, + $5edef90e, $29d9c998, $b0d09822, $c7d7a8b4, $59b33d17, + $2eb40d81, $b7bd5c3b, $c0ba6cad, $edb88320, $9abfb3b6, + $03b6e20c, $74b1d29a, $ead54739, $9dd277af, $04db2615, + $73dc1683, $e3630b12, $94643b84, $0d6d6a3e, $7a6a5aa8, + $e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1, $f00f9344, + $8708a3d2, $1e01f268, $6906c2fe, $f762575d, $806567cb, + $196c3671, $6e6b06e7, $fed41b76, $89d32be0, $10da7a5a, + $67dd4acc, $f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5, + $d6d6a3e8, $a1d1937e, $38d8c2c4, $4fdff252, $d1bb67f1, + $a6bc5767, $3fb506dd, $48b2364b, $d80d2bda, $af0a1b4c, + $36034af6, $41047a60, $df60efc3, $a867df55, $316e8eef, + $4669be79, $cb61b38c, $bc66831a, $256fd2a0, $5268e236, + $cc0c7795, $bb0b4703, $220216b9, $5505262f, $c5ba3bbe, + $b2bd0b28, $2bb45a92, $5cb36a04, $c2d7ffa7, $b5d0cf31, + $2cd99e8b, $5bdeae1d, $9b64c2b0, $ec63f226, $756aa39c, + $026d930a, $9c0906a9, $eb0e363f, $72076785, $05005713, + $95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38, $92d28e9b, + $e5d5be0d, $7cdcefb7, $0bdbdf21, $86d3d2d4, $f1d4e242, + $68ddb3f8, $1fda836e, $81be16cd, $f6b9265b, $6fb077e1, + $18b74777, $88085ae6, $ff0f6a70, $66063bca, $11010b5c, + $8f659eff, $f862ae69, $616bffd3, $166ccf45, $a00ae278, + $d70dd2ee, $4e048354, $3903b3c2, $a7672661, $d06016f7, + $4969474d, $3e6e77db, $aed16a4a, $d9d65adc, $40df0b66, + $37d83bf0, $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9, + $bdbdf21c, $cabac28a, $53b39330, $24b4a3a6, $bad03605, + $cdd70693, $54de5729, $23d967bf, $b3667a2e, $c4614ab8, + $5d681b02, $2a6f2b94, $b40bbe37, $c30c8ea1, $5a05df1b, + $2d02ef8d); +FUNCTION UpdateCRC32(CRC: LongInt; VAR Buffer; Len: Word): LongInt; +VAR + i: Integer; + Octet: ^Byte; +BEGIN + Octet := @buffer; + for i := 1 to Len do + begin + CRC := CRC_32_TAB[Byte(Crc XOR LongInt(Octet^))] XOR ((Crc SHR 8) AND $00FFFFFF); + Inc(Octet); + end; + UpdateCRC32 := CRC; +END; +{$ENDIF} + +FUNCTION CheckPW: Boolean; +BEGIN + CheckPW := Common1.CheckPW; +END; + +PROCEDURE NewCompTables; +BEGIN + Common1.NewCompTables; +END; + +PROCEDURE Wait(B: Boolean); +BEGIN + Common1.Wait(B); +END; + +PROCEDURE InitTrapFile; +BEGIN + Common1.InitTrapFile; +END; + +PROCEDURE Local_Input1(VAR S: STRING; MaxLen: Byte; LowerCase: Boolean); +BEGIN + Common1.Local_Input1(S,MaxLen,LowerCase); +END; + +PROCEDURE Local_Input(VAR S: STRING; MaxLen: Byte); +BEGIN + Common1.Local_Input(S,MaxLen); +END; + +PROCEDURE Local_InputL(VAR S: STRING; MaxLen: Byte); +BEGIN + Common1.Local_InputL(S,MaxLen); +END; + +PROCEDURE Local_OneK(VAR C: Char; S: STRING); +BEGIN + Common1.Local_OneK(C,S); +END; + +PROCEDURE SysOpShell; +BEGIN + Common1.SysOpShell; +END; + +PROCEDURE RedrawForANSI; +BEGIN + Common1.RedrawForANSI; +END; + +PROCEDURE SKey1(VAR C: Char); +BEGIN + Common2.SKey1(C); +END; + +PROCEDURE SaveGeneral(X: Boolean); +BEGIN + Common2.SaveGeneral(X); +END; + +PROCEDURE Update_Screen; +BEGIN + Common2.Update_Screen; +END; + +PROCEDURE lStatus_Screen(WhichScreen: Byte; Message: AStr; OneKey: Boolean; VAR Answer:AStr); +BEGIN + Common2.lStatus_Screen(WhichScreen,Message,OneKey,Answer); +END; + +PROCEDURE TLeft; +BEGIN + Common2.TLeft; +END; + +PROCEDURE InputLongIntWC(S: AStr; VAR L: LongInt; InputFlags: InputFlagSet; LowNum,HighNum: LongInt; VAR Changed: Boolean); +BEGIN + Common3.InputLongIntWC(S,L,InputFlags,LowNum,HighNum,Changed); +END; + +PROCEDURE InputLongIntWOC(S: AStr; VAR L: LongInt; InputFlags: InputFlagSet; LowNum,HighNum: LongInt); +BEGIN + Common3.InputLongIntWOC(S,L,InputFlags,LowNum,HighNum); +END; + +PROCEDURE InputWordWC(S: AStr; VAR W: SmallWord; InputFlags: InputFlagSet; LowNum,HighNum: Word; VAR Changed: Boolean); +BEGIN + Common3.InputWordWC(S,W,InputFlags,LowNum,HighNum,Changed); +END; + +PROCEDURE InputWordWOC(S: AStr; VAR W: SmallWord; InputFlags: InputFlagSet; LowNum,HighNum: Word); +BEGIN + Common3.InputWordWOC(S,W,InputFlags,LowNum,HighNum); +END; + +PROCEDURE InputIntegerWC(S: AStr; VAR I: SmallInt; InputFlags: InputFlagSet; LowNum,HighNum: Integer; VAR Changed: Boolean); +BEGIN + Common3.InputIntegerWC(S,I,InputFlags,LowNum,HighNum,Changed); +END; + +PROCEDURE InputIntegerWOC(S: AStr; VAR I: SmallInt; InputFlags: InputFlagSet; LowNum,HighNum: Integer); +BEGIN + Common3.InputIntegerWOC(S,I,Inputflags,LowNum,HighNum); +END; + +PROCEDURE InputByteWC(S: AStr; VAR B: Byte; InputFlags: InputFlagSet; LowNum,HighNum: Byte; VAR Changed: Boolean); +BEGIN + Common3.InputByteWC(S,B,InputFlags,LowNum,HighNum,Changed); +END; + +PROCEDURE InputByteWOC(S: AStr; VAR B: Byte; InputFlags: InputFlagSet; LowNum,HighNum: Byte); +BEGIN + Common3.InputByteWOC(S,B,InputFlags,LowNum,HighNum) +END; + +PROCEDURE InputDefault(VAR S: STRING; v: STRING; MaxLen: Byte; InputFlags: InputFlagSet; LineFeed: Boolean); +BEGIN + Common3.InputDefault(S,v,MaxLen,InputFlags,LineFeed); +END; + +PROCEDURE InputFormatted(DisplayStr: AStr; VAR InputStr: STRING; v: STRING; Abortable: Boolean); +BEGIN + Common3.InputFormatted(DisplayStr,InputStr,v,Abortable); +END; + +PROCEDURE InputWN1(DisplayStr: AStr; VAR InputStr: AStr; MaxLen: Byte; InputFlags: InputFlagSet; VAR Changed: Boolean); +BEGIN + Common3.InputWN1(DisplayStr,InputStr,MaxLen,InputFlags,Changed); +END; + +PROCEDURE InputWNWC(DisplayStr: AStr; VAR InputStr: AStr; MaxLen: Byte; VAR Changed: Boolean); +BEGIN + Common3.InputWNWC(DisplayStr,InputStr,MaxLen,Changed); +END; + +PROCEDURE InputMain(VAR s: STRING; MaxLen: Byte; InputFlags: InputFlagSet); +BEGIN + Common3.InputMain(s,MaxLen,InputFlags); +END; + +PROCEDURE InputWC(VAR s: STRING; MaxLen: Byte); +BEGIN + Common3.InputWC(s,MaxLen); +END; + +PROCEDURE Input(VAR s: STRING; MaxLen: Byte); +BEGIN + Common3.Input(s,MaxLen); +END; + +PROCEDURE InputL(VAR s: STRING; MaxLen: Byte); +BEGIN + Common3.InputL(s,MaxLen); +END; + +PROCEDURE InputCaps(VAR s: STRING; MaxLen: Byte); +BEGIN + Common3.InputCaps(s,MaxLen); +END; + +PROCEDURE Com_Flush_Recv; +BEGIN + Common4.Com_Flush_Recv; +END; + +PROCEDURE Com_Flush_Send; +BEGIN + Common4.Com_Flush_Send; +END; + +PROCEDURE Com_Purge_Send; +BEGIN + Common4.Com_Purge_Send; +END; + +FUNCTION Com_Carrier: Boolean; +BEGIN + Com_Carrier := Common4.Com_Carrier; +END; + +FUNCTION Com_Recv: Char; +BEGIN + Com_Recv := Common4.Com_Recv; +END; + +FUNCTION Com_IsRecv_Empty: Boolean; +BEGIN + Com_IsRecv_Empty := Common4.Com_IsRecv_Empty; +END; + +FUNCTION Com_IsSend_Empty: Boolean; +BEGIN + Com_IsSend_Empty := Common4.Com_IsSend_Empty; +END; + +PROCEDURE Com_Send(c: Char); +BEGIN + Common4.Com_Send(c); +END; + +PROCEDURE Com_Set_Speed(Speed: LongInt); +BEGIN + Common4.Com_Set_Speed(Speed); +END; + +PROCEDURE Com_DeInstall; +BEGIN + Common4.Com_DeInstall; +END; + +PROCEDURE Com_Install; +BEGIN + Common4.Com_Install; +END; + +PROCEDURE CheckHangup; +BEGIN + Common4.checkhangup; +END; + +PROCEDURE SerialOut(s: STRING); +BEGIN + Common4.SerialOut(s); +END; + +FUNCTION Empty: Boolean; BEGIN + Empty := Common4.Empty; +END; + +PROCEDURE DTR(Status: Boolean); +BEGIN + Common4.DTR(Status); +END; + +PROCEDURE ShowColors; +VAR + Counter: Byte; +BEGIN + FOR Counter := 1 TO 10 DO + BEGIN + SetC(Scheme.Color[Counter]); + Prompt(IntToStr(Counter - 1)); + SetC(7); + Prompt(' '); + END; + NL; +END; + +FUNCTION CheckDriveSpace(S,Path: AStr; MinSpace: Integer): Boolean; +VAR + Drive: Char; + MinSpaceOk: Boolean; +BEGIN + MinSpaceOk := TRUE; + IF (DiskKBFree(Path) <= MinSpace) THEN + BEGIN + NL; + Star('Insufficient disk space.'); + Drive := Chr(ExtractDriveNumber(Path) + 64); + IF (Drive = '@') THEN + SysOpLog('^8--->^3 '+S+' failure: Main BBS drive full.') + ELSE + SysOpLog('^8--->^3 '+S+' failure: '+Drive+' Drive full.'); + MinSpaceOk := FALSE; + END; + CheckDriveSpace := MinSpaceOk; +END; + + +FUNCTION StripLeadSpace(S: STRING): STRING; +BEGIN + WHILE (S[1] = ' ') DO + Delete(S,1,1); + StripLeadSpace := S; +END; + +FUNCTION StripTrailSpace(S: STRING): STRING; +BEGIN + WHILE (S[1] = ' ') DO + Delete(S,1,1); + StripTrailSpace := S; +END; + +FUNCTION SemiCmd(S: AStr; B: Byte): STRING; +VAR + i, + p: Byte; +BEGIN + i := 1; + WHILE (i < B) AND (s <> '') DO + BEGIN + p := Pos(';',s); + IF (p <> 0) THEN + s := Copy(s,(p + 1),(Length(s) - p)) + ELSE + s := ''; + Inc(i); + END; + WHILE (Pos(';',s) <> 0) DO + s := Copy(s,1,(Pos(';',s) - 1)); + SemiCmd := s; +END; + +FUNCTION ExistDrive(Drive: Char): Boolean; +VAR + Found: Boolean; +BEGIN + ChDir(Drive+':'); + IF (IOResult <> 0) THEN + Found := FALSE + ELSE + BEGIN + ChDir(StartDir); + Found := TRUE; + END; + ExistDrive := Found; +END; + +PROCEDURE RenameFile(DisplayStr: AStr; OldFileName,NewFileName: AStr; VAR RenameOk: Boolean); +VAR + F: FILE; +BEGIN + Print(DisplayStr); + IF (NOT Exist(OldFileName)) THEN + BEGIN + NL; + Print('"'+OldFileName+'" does not exist, can not rename file.'); + ReNameOk := FALSE; + END + ELSE IF (Exist(NewFileName)) THEN + BEGIN + NL; + Print('"'+NewFileName+'" exists, file can not be renamed to "'+OldFileName+'".'); + ReNameOk := FALSE; + END + ELSE + BEGIN + Assign(F,OldFileName); + ReName(F,NewFileName); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error renaming file '+OldFileName+'.'); + ReNameOK := FALSE; + END; + END; +END; + +FUNCTION GetFileSize(FileName: AStr): LongInt; +VAR + DirInfo1: SearchRec; + FSize: LongInt; +BEGIN + FindFirst(FileName,AnyFile - Directory - VolumeID - DOS.Hidden - SysFile,DirInfo1); + IF (DosError <> 0) THEN + FSize := -1 + ELSE + FSize := DirInfo1.Size; + GetFileSize := FSize; +END; + +PROCEDURE GetFileDateTime(CONST FileName: AStr; VAR FileTime: LongInt); +VAR + F: FILE; +BEGIN + FileTime := 0; + IF Exist(SQOutSp(FileName)) THEN + BEGIN + Assign(F,SQOutSp(FileName)); + Reset(F); + GetFTime(F,FileTime); + Close(F); + LastError := IOResult; + END; +END; + +PROCEDURE SetFileDateTime(CONST FileName: AStr; FileTime: LongInt); +VAR + F: FILE; +BEGIN + IF Exist(SQOutSp(FileName)) THEN + BEGIN + Assign(F,SQOutSp(FileName)); + Reset(F); + SetFTime(F,FileTime); + Close(F); + LastError := IOResult; + END; +END; + +FUNCTION PHours(CONST DisplayStr: AStr; LoTime,HiTime: Integer): AStr; +BEGIN + IF (LoTime <> HiTime) THEN + PHours := ZeroPad(IntToStr(LoTime DIV 60))+':'+ZeroPad(IntToStr(LoTime MOD 60))+'....'+ + ZeroPad(IntToStr(HiTime DIV 60))+':'+ZeroPad(IntToStr(HiTime MOD 60)) + ELSE + PHours := DisplayStr; +END; + +FUNCTION RGSysCfgStr(StrNum: LongInt; PassValue: Boolean): AStr; +VAR + StrPointerFile: FILE OF StrPointerRec; + StrPointer: StrPointerRec; + RGStrFile: FILE; + S: STRING; + TotLoad: LongInt; +BEGIN + Assign(StrPointerFile,General.LMultPath+'RGSCFGPR.DAT'); + Reset(StrPointerFile); + Seek(StrPointerFile,StrNum); + Read(StrPointerFile,StrPointer); + Close(StrPointerFile); + LastError := IOResult; + TotLoad := 0; + Assign(RGStrFile,General.LMultPath+'RGSCFGTX.DAT'); + Reset(RGStrFile,1); + Seek(RGStrFile,(StrPointer.Pointer - 1)); + REPEAT + BlockRead(RGStrFile,S[0],1); + BlockRead(RGStrFile,S[1],Ord(S[0])); + Inc(TotLoad,(Length(S) + 1)); + IF (PassValue) THEN + BEGIN + IF (S[Length(s)] = '@') THEN + Dec(S[0]); + END + ELSE + BEGIN + IF (S[Length(S)] = '@') THEN + BEGIN + Dec(S[0]); + Prt(S); + END + ELSE + PrintACR(S); + END; + UNTIL (TotLoad >= StrPointer.TextSize) OR (Abort) OR (HangUp); + Close(RGStrFile); + LastError := IOResult; + RGSysCfgStr := S; +END; + +FUNCTION RGNoteStr(StrNum: LongInt; PassValue: Boolean): AStr; +VAR + StrPointerFile: FILE OF StrPointerRec; + StrPointer: StrPointerRec; + RGStrFile: FILE; + S: STRING; + TotLoad: LongInt; +BEGIN + Assign(StrPointerFile,General.LMultPath+'RGNOTEPR.DAT'); + Reset(StrPointerFile); + Seek(StrPointerFile,StrNum); + Read(StrPointerFile,StrPointer); + Close(StrPointerFile); + LastError := IOResult; + TotLoad := 0; + Assign(RGStrFile,General.LMultPath+'RGNOTETX.DAT'); + Reset(RGStrFile,1); + Seek(RGStrFile,(StrPointer.Pointer - 1)); + REPEAT + BlockRead(RGStrFile,S[0],1); + BlockRead(RGStrFile,S[1],Ord(S[0])); + Inc(TotLoad,(Length(S) + 1)); + IF (PassValue) THEN + BEGIN + IF (S[Length(s)] = '@') THEN + Dec(S[0]); + END + ELSE + BEGIN + IF (S[Length(S)] = '@') THEN + BEGIN + Dec(S[0]); + Prt(S); + END + ELSE + PrintACR(S); + END; + UNTIL (TotLoad >= StrPointer.TextSize) OR (Abort) OR (HangUp); + Close(RGStrFile); + LastError := IOResult; + RGNoteStr := S; +END; + +FUNCTION RGMainStr(StrNum: LongInt; PassValue: Boolean): AStr; +VAR + StrPointerFile: FILE OF StrPointerRec; + StrPointer: StrPointerRec; + RGStrFile: FILE; + S: STRING; + TotLoad: LongInt; +BEGIN + Assign(StrPointerFile,General.LMultPath+'RGMAINPR.DAT'); + Reset(StrPointerFile); + Seek(StrPointerFile,StrNum); + Read(StrPointerFile,StrPointer); + Close(StrPointerFile); + LastError := IOResult; + TotLoad := 0; + Assign(RGStrFile,General.LMultPath+'RGMAINTX.DAT'); + Reset(RGStrFile,1); + Seek(RGStrFile,(StrPointer.Pointer - 1)); + REPEAT + BlockRead(RGStrFile,S[0],1); + BlockRead(RGStrFile,S[1],Ord(S[0])); + Inc(TotLoad,(Length(S) + 1)); + IF (PassValue) THEN + BEGIN + IF (S[Length(s)] = '@') THEN + Dec(S[0]); + END + ELSE + BEGIN + IF (S[Length(S)] = '@') THEN + BEGIN + Dec(S[0]); + Prt(S); + END + ELSE + PrintACR(S); + END; + UNTIL (TotLoad >= StrPointer.TextSize) OR (Abort) OR (HangUp); + Close(RGStrFile); + LastError := IOResult; + RGMainStr := S; +END; + +FUNCTION lRGLngStr(StrNum: LongInt; PassValue: Boolean): AStr; +VAR + StrPointerFile: FILE OF StrPointerRec; + StrPointer: StrPointerRec; + RGStrFile: FILE; + S: STRING; + TotLoad: LongInt; +BEGIN + Assign(StrPointerFile,General.LMultPath+'RGLNGPR.DAT'); + Reset(StrPointerFile); + Seek(StrPointerFile,StrNum); + Read(StrPointerFile,StrPointer); + Close(StrPointerFile); + LastError := IOResult; + TotLoad := 0; + Assign(RGStrFile,General.LMultPath+'RGLNGTX.DAT'); + Reset(RGStrFile,1); + Seek(RGStrFile,(StrPointer.Pointer - 1)); + REPEAT + BlockRead(RGStrFile,S[0],1); + BlockRead(RGStrFile,S[1],Ord(S[0])); + Inc(TotLoad,(Length(S) + 1)); + IF (PassValue) THEN + BEGIN + IF (S[Length(s)] = '@') THEN + Dec(S[0]); + END + ELSE + BEGIN + IF (S[Length(S)] = '@') THEN + BEGIN + Dec(S[0]); + Prt(S); + END + ELSE + PrintACR(S); + END; + UNTIL (TotLoad >= StrPointer.TextSize) OR (Abort) OR (HangUp); + Close(RGStrFile); + LastError := IOResult; + lRGLNGStr := S; +END; + +PROCEDURE GetPassword(VAR PW: AStr; Len: Byte); +BEGIN + PW := ''; + Echo := FALSE; + Input(PW,Len); + Echo := TRUE; +END; + +PROCEDURE MakeDir(VAR Path: PathStr; AskMakeDir: Boolean); +VAR + CurDir: PathStr; + Counter: Byte; +BEGIN + IF (Path = '') THEN + BEGIN + NL; + Print('^7A valid path must be specified!^1'); + END + ELSE IF (NOT (Path[1] IN ['A'..'Z'])) OR (Length(Path) < 3) OR + (NOT (Path[2] = ':')) OR (NOT (Path[3] = '\')) THEN + BEGIN + NL; + Print('^7Invalid drive specification: "'+Path+'"^1'); + END + ELSE + BEGIN + GetDir(0,CurDir); + ChDir(Path[1]+':'); + IF (IOResult <> 0) THEN + BEGIN + NL; + Print('^7Drive does not exist: "'+Path[1]+'"^1'); + END + ELSE + ChDir(CurDir); + END; + + Path := BSlash(Path,TRUE); + IF (Length(Path) > 3) AND (NOT ExistDir(Path)) THEN + BEGIN + NL; + IF (NOT AskMakeDir) OR PYNQ('Directory does not exist, create it? ',0,FALSE) THEN + BEGIN + Counter := 2; + WHILE (Counter <= Length(Path)) DO + BEGIN + IF (Path[Counter] = '\') THEN + BEGIN + IF (Path[Counter - 1] <> ':') THEN + BEGIN + IF (NOT ExistDir(Copy(Path,1,(Counter - 1)))) THEN + BEGIN + MkDir(Copy(Path,1,(Counter - 1))); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('^7Error creating directory!^1'); + SysOpLog('^7Error creating directory: '+Copy(Path,1,(Counter - 1))); + PauseScr(FALSE); + END; + END; + END; + END; + Inc(Counter); + END; + END; + END; + +END; + +PROCEDURE Messages(Msg,MaxRecs: Integer; AreaName: AStr); +VAR + MsgStr: AStr; +BEGIN + MsgStr := ''; + NL; + CASE Msg OF + 1 : MsgStr := '^7Invalid record number!^1'; + 2 : MsgStr := '^7You are at the first valid record!^1'; + 3 : MsgStr := '^7You are at the last valid record!^1'; + 4 : MsgStr := '^7No '+AreaName+' exist!^1'; + 5 : MsgStr := '^7No more then '+IntToStr(MaxRecs)+' '+AreaName+' can exist!^1'; + 6 : MsgStr := '^7No '+AreaName+' to position!^1'; + 7 : MsgStr := '^7Invalid drive!^1'; + 8 : MsgStr := '^7Invalid record number order!^1'; + END; + PrintACR('^1'+MsgStr); + PauseScr(FALSE); +END; + + +FUNCTION ReadBuffer(FileName: AStr): Boolean; +VAR + BufferFile: FILE; + MCIBufferSize, + NumRead: Integer; +BEGIN + IF (MCIBuffer = NIL) THEN + New(MCIBuffer); + + ReadBuffer := FALSE; + + IF ((Pos('\',FileName) = 0) AND (Pos(':', FileName) = 0)) THEN + FileName := General.MiscPath+FileName; + + IF (Pos('.',FileName) = 0) THEN + BEGIN + IF (OkRIP) AND Exist(FileName+'.RIP') THEN + FileName := FileName+'.RIP' + ELSE IF (OkAvatar) AND Exist(FileName+'.AVT') THEN + FileName := FileName+'.AVT' + ELSE IF (OkANSI) AND Exist(FileName+'.ANS') THEN + FileName := FileName+'.ANS' + ELSE IF (Exist(FileName+'.ASC')) THEN + FileName := FileName+'.ASC'; + END; + + IF (NOT Exist(FileName)) THEN + Exit; + + Assign(BufferFile,FileName); + Reset(BufferFile,1); + + IF (IOResult <> 0) THEN + Exit; + + IF (FileSize(BufferFile) < MaxConfigurable) THEN + MCIBufferSize := FileSize(BufferFile) + ELSE + MCIBufferSize := MaxConfigurable; + + FillChar(MCIBuffer^,SizeOf(MCIBuffer^),0); + + BlockRead(BufferFile,MCIBuffer^,MCIBufferSize,NumRead); + + IF (NumRead <> MCIBufferSize) THEN + Exit; + + Close(BufferFile); + ReadBuffer := TRUE; +END; + +PROCEDURE DisplayBuffer(MCIFunction: MCIFunctionType; Data1,Data2: Pointer); +VAR + TempStr: STRING; + cs: AStr; + Justify: Byte; {0=Right, 1=Left, 2=Center} + Counter, + X2: Integer; +BEGIN + Counter := 1; + WHILE (Counter <= MaxConfigurable) AND (MCIBuffer^[Counter] <> #0) DO + BEGIN + TempStr := ''; + WHILE (Counter <= MaxConfigurable) AND (MCIBuffer^[Counter] <> #13) DO + IF (MCIBuffer^[Counter] = '~') AND (Counter + 2 <= MaxConfigurable) THEN + BEGIN + cs := MCIFunction(MCIBuffer^[Counter + 1] + MCIBuffer^[Counter + 2],Data1,Data2); + IF (cs = MCIBuffer^[Counter + 1] + MCIBuffer^[Counter + 2]) THEN + BEGIN + TempStr := TempStr + '~'; + Inc(Counter); + Continue; + END; + Inc(Counter,3); + IF ((Counter + 1) <= MaxConfigurable) AND (MCIBuffer^[Counter] IN ['#','{','}']) THEN + BEGIN + IF (MCIBuffer^[Counter] = '}') THEN + Justify := 0 + ELSE IF (MCIBuffer^[Counter] = '{') THEN + Justify := 1 + ELSE + Justify := 2; + IF (MCIBuffer^[Counter + 1] IN ['0'..'9']) THEN + BEGIN + X2 := Ord(MCIBuffer^[Counter + 1]) - 48; + Inc(Counter, 2); + IF (MCIBuffer^[Counter] IN ['0'..'9']) THEN + BEGIN + X2 := X2 * 10 + Ord(MCIBuffer^[Counter]) - 48; + Inc(Counter,1); + END; + IF (X2 > 0) THEN + CASE Justify OF + 0 : cs := PadRightStr(cs,X2); + 1 : cs := PadLeftStr(cs,X2); + 2 : WHILE (Length(cs) < X2) DO + BEGIN + cs := ' ' + cs; + IF (Length(cs) < X2) THEN + cs := cs + ' '; + END; + END; + END; + END; + IF ((Length(cs) + Length(TempStr)) <= 255) THEN + BEGIN + Move(cs[1],TempStr[Length(TempStr)+1],Length(cs)); + Inc(TempStr[0],Length(cs)); + END + ELSE + IF (Length(TempStr) < 255) THEN + BEGIN + Move(cs[1],TempStr[Length(TempStr) + 1],(255 - Length(TempStr))); + TempStr[0] := #255; + END; + END + ELSE + BEGIN + Inc(TempStr[0]); + TempStr[Length(TempStr)] := MCIBuffer^[Counter]; + Inc(Counter); + END; + + IF (Counter <= MaxConfigurable) AND (MCIBuffer^[Counter] = #13) THEN + Inc(Counter,2); + CROff := TRUE; + PrintACR(TempStr); + END; +END; + +FUNCTION Chinkey: Char; +VAR + C: Char; +BEGIN + C := #0; + Chinkey := #0; + IF (KeyPressed) THEN + BEGIN + C := ReadKey; + IF (NOT WColor) THEN + UserColor(General.SysOpColor); + WColor := TRUE; + IF (C = #0) THEN + IF (KeyPressed) THEN + BEGIN + C := ReadKey; + SKey1(C); + IF (C = #31) OR (C = #46) THEN + C := #1 + ELSE IF (Buf <> '') THEN + BEGIN + C := Buf[1]; + Buf := Copy(Buf,2,(Length(Buf) - 1)); + END + ELSE + C := #0 + END; + Chinkey := C; + END + ELSE IF ((NOT Com_IsRecv_Empty) AND (InCom)) THEN + BEGIN + C := CInKey; + IF (WColor) THEN + UserColor(General.UserColor); + WColor := FALSE; + Chinkey := C; + END; +END; + +FUNCTION FormatNumber(L: LongInt): STRING; +VAR + S: STRING; + StrLen, + Counter: Byte; +BEGIN + S := ''; + Str(L,S); + StrLen := Length(S); + Counter := 0; + WHILE (StrLen > 1) DO + BEGIN + Inc(Counter); + IF (Counter = 3) THEN + BEGIN + Insert(',',S,StrLen); + Counter := 0; + END; + Dec(StrLen); + END; + FormatNumber := S; +END; + +FUNCTION ConvertBytes(BytesToConvert: LongInt; OneChar: Boolean): STRING; +CONST + InByte = 1; + InKilo = 1024; + InMega = 1048576; + InGiga = 1073741824; +VAR + InSize, + InMod: LongInt; + InTypes: Str5; +BEGIN + InMod := 0; + InTypes := ''; + IF (BytesToConvert < 0) THEN + Exit; + IF (BytesToConvert < InKilo) THEN {Bytes Convertion} + BEGIN + InSize := BytesToConvert; + InTypes := 'Bytes'; + END + ELSE IF (BytesToConvert < InMega) THEN {Kilo Convertion} + BEGIN + InSize := (BytesToConvert DIV InKilo); + InMod := Trunc(((BytesToConvert Mod InKilo) / InKilo) * 10.0); + InTypes := 'KB'; + END + ELSE IF (BytesToConvert < InGiga) THEN {Mega Convertion} + BEGIN + InSize := (BytesToConvert DIV InMega); + InMod := Trunc(((BytesToConvert Mod InMega) / InMega) * 10.0); + InTypes := 'MB'; + END + ELSE IF ((BytesToConvert - 1) > InGiga) THEN {GigaByte Conversion} + BEGIN + InSize := (BytesToConvert DIV InGiga); + InMod := Trunc(((BytesToConvert Mod InGiga) / InGiga) * 10.0); + InTypes := 'GB'; + END; + IF (InMod = 0) THEN + ConvertBytes := AOnOff(OneChar,IntToStr(InSize),FormatNumber(InSize)+' ') + +AOnOff(OneChar,Char(Ord(InTypes[1]) + 32),InTypes) + ELSE + ConvertBytes := AOnOff(OneChar,IntToStr(InSize),FormatNumber(InSize))+'.' + +AOnOff(OneChar,IntToStr(InMod),IntToStr(InMod)+' ') + +AOnOff(OneChar,Char(Ord(InTypes[1]) + 32),InTypes); +END; + +FUNCTION ConvertKB(KBToConvert: LongInt; OneChar: Boolean): STRING; +CONST + InKilo = 1; + InMega = 1024; + InGiga = 1048576; + InTera = 1073741824; +VAR + InSize, + InMod: LongInt; + InTypes: Str5; +BEGIN + InMod := 0; + InTypes := ''; + IF (KBToConvert < 0) THEN + Exit; + IF (KBToConvert < InMega) THEN {KILO Convertion} + BEGIN + InSize := KBToConvert; + InTypes := 'KB'; + END + ELSE IF (KBToConvert < InGiga) THEN {MEGA Convertion} + BEGIN + InSize := (KBToConvert DIV InMega); + InMod := Trunc(((KBToConvert Mod InMega) / InMega) * 10.0); + InTypes := 'MB'; + END + ELSE IF (KBToConvert < InTera) THEN {Giga Convertion} + BEGIN + InSize := (KBToConvert DIV InGiga); + InMod := Trunc(((KBToConvert Mod InGiga) / InGiga) * 10.0); + InTypes := 'GB'; + END + ELSE IF ((KBToConvert - 1) > InTera) THEN {TeraByte Conversion} + BEGIN + InSize := (KBToConvert DIV InTera); + InMod := Trunc(((KBToConvert Mod InTera) / InTera) * 10.0); + InTypes := 'TB'; + END; + IF (InMod = 0) THEN + ConvertKB := AOnOff(OneChar,IntToStr(InSize),FormatNumber(InSize)+' ') + +AOnOff(OneChar,Char(Ord(InTypes[1]) + 32),InTypes) + ELSE + ConvertKB := AOnOff(OneChar,IntToStr(InSize),FormatNumber(InSize))+'.' + +AOnOff(OneChar,IntToStr(InMod),IntToStr(InMod)+' ') + +AOnOff(OneChar,Char(Ord(InTypes[1]) + 32),InTypes); +END; + +PROCEDURE WriteWFC(c: Char); +VAR + LastAttr: Byte; +BEGIN + IF (BlankMenuNow) THEN + Exit; + Window(23,11,78,15); + GotoXY(LastWFCX,LastWFCY); + LastAttr := TextAttr; + TextAttr := 7; + Write(c); + TextAttr := LastAttr; + LastWFCX := WhereX; + LastWFCY := WhereY; + Window(1,1,MaxDisplayCols,MaxDisplayRows); +END; + +FUNCTION AccountBalance: LongInt; +BEGIN + AccountBalance := (ThisUser.lCredit - ThisUser.Debit); +END; + +PROCEDURE AdjustBalance(Adjustment: LongInt); +BEGIN + IF (Adjustment > 0) THEN + Inc(ThisUser.Debit,Adjustment) { Add TO debits } + ELSE + Dec(ThisUser.lCredit,Adjustment); { Add TO credits } +END; + +FUNCTION CRC32(S: AStr): LongInt; +BEGIN + CRC32 := NOT (UpdateCRC32($FFFFFFFF,S[1],Length(S))); +END; + +PROCEDURE Kill(CONST FileName: AStr); +VAR + F: FILE; +BEGIN + Assign(F,FileName); + Erase(F); + LastError := IOResult; +END; + +PROCEDURE BackSpace; +BEGIN + IF (OutCom) THEN + SerialOut(^H' '^H); + IF (WantOut) THEN + Write(^H' '^H); +END; + +PROCEDURE DoBackSpace(Start,Finish: Byte); +VAR + Counter: Byte; +BEGIN + FOR Counter := Start TO Finish DO + BEGIN + IF (OutCom) THEN + SerialOut(^H' '^H); + IF (WantOut) THEN + Write(^H' '^H); + END; +END; + +FUNCTION Substitute(Src: STRING; CONST old,New: STRING): STRING; +VAR + p, + Diff, + LastP: Integer; +BEGIN + IF (old <> New) THEN + BEGIN + LastP := 0; + Diff := Length(New) - Length(old); + REPEAT + p := Pos(old,Copy(Src,LastP,255)); + IF (p > 0) THEN + BEGIN + IF (Diff <> 0) THEN + BEGIN + Move(Src[p + Length(old)],Src[p + Length(New)],(Length(Src) - p)); + Inc(Src[0],Diff); + END; + Move(New[1],Src[p],Length(New)); + LastP := p + Length(New); + END; + UNTIL (p = 0); + END; + Substitute := Src; +END; + +PROCEDURE DOSANSI(CONST c:Char); +VAR + i:Word; +label Command; + +BEGIN + IF (c = #27) AND (NextState IN [Waiting..In_Param]) THEN + BEGIN + NextState := Bracket; + Exit; + END; + + IF (c = ^V) AND (NextState = Waiting) THEN + BEGIN + NextState := GetAvCmd; + Exit; + END; + + IF (c = ^y) AND (NextState = Waiting) THEN + BEGIN + NextState := GetAvRLE1; + Exit; + END; + + CASE NextState OF + Waiting : IF (c = #9) THEN + GotoXY((WhereX + 8),WhereY) + ELSE + Write(c); + GetAvRLE1: + BEGIN + ParamArr[1] := Ord(c); + NextState := GetAvRLE2; + END; + GetAvRLE2: + BEGIN + FOR i := 1 TO Ord(c) DO + Write(Chr(ParamArr[1])); + NextState := Waiting; + END; + GetAvAttr: + BEGIN + TextAttr := Ord(c) AND $7f; + NextState := Waiting; + END; + GetAvY: + BEGIN + ParamArr[1] := Ord(c); + NextState := GetAvX; + END; + GetAvX: + BEGIN + GotoXY(Ord(c),ParamArr[1]); + NextState := Waiting; + END; + GetAvCmd: CASE c OF + ^A : NextState := GetAvAttr; + ^B : BEGIN + TextAttr := TextAttr OR $80; + NextState := Waiting; + END; + ^C : BEGIN + GotoXY(WhereX,(WhereY - 1)); + NextState := Waiting; + END; + ^d : BEGIN + GotoXY(WhereX,(WhereY + 1)); + NextState := Waiting; + END; + ^E : BEGIN + GotoXY((WhereX - 1),WhereY); + NextState := Waiting; + END; + ^F : + BEGIN + GotoXY((WhereX + 1),WhereY); + NextState := Waiting; + END; + ^G : + BEGIN + ClrEOL; + NextState := Waiting; + END; + ^H : NextState := GetAvY; + ELSE + NextState := Waiting; + END; + Bracket : + BEGIN + IF c <> '[' THEN + BEGIN + NextState := Waiting; + Write(c); + END + ELSE + BEGIN + Params := 1; + FillChar(ParamArr,5,0); + NextState := Get_Args; + END; + END; + Get_Args,Get_Param,Eat_Semi : + BEGIN + IF (NextState = Eat_Semi) AND (c = ';') THEN + BEGIN + IF (Params < 5) THEN + Inc(Params); + NextState := Get_Param; + Exit; + END; + CASE c OF + '0'..'9' : + BEGIN + ParamArr[Params] := Ord(c) - 48; + NextState := In_Param; + END; + ';' : + BEGIN + IF (Params < 5) THEN + Inc(Params); + NextState := Get_Param; + END; + ELSE + goto Command; + END {CASE c} ; + END; + In_Param : { last Char was a digit } + BEGIN + { looking FOR more digits, a semicolon, OR a command Char } + CASE c OF + '0'..'9' : + BEGIN + ParamArr[Params] := ParamArr[Params] * 10 + Ord(c) - 48; + NextState := In_Param; + Exit; + END; + ';' : + BEGIN + IF (Params < 5) THEN + Inc(Params); + NextState := Eat_Semi; + Exit; + END; + END {CASE c} ; + Command: + NextState := Waiting; + CASE c OF + { Note: the order OF commands is optimized FOR execution speed } + 'm' : {sgr} + BEGIN + FOR i := 1 TO Params DO + BEGIN + IF (Reverse) THEN + TextAttr := TextAttr SHR 4 + TextAttr SHL 4; + CASE ParamArr[i] OF + 0 : + BEGIN + Reverse := FALSE; + TextAttr := 7; + END; + 1 : TextAttr := TextAttr AND $FF OR $08; + 2 : TextAttr := TextAttr AND $F7 OR $00; + 4 : TextAttr := TextAttr AND $F8 OR $01; + 5 : TextAttr := TextAttr OR $80; + 7 : IF NOT Reverse THEN + BEGIN + { + TextAttr := TextAttr SHR 4 + TextAttr SHL 4; + } + Reverse := TRUE; + END; + 22 : TextAttr := TextAttr AND $F7 OR $00; + 24 : TextAttr := TextAttr AND $F8 OR $04; + 25 : TextAttr := TextAttr AND $7F OR $00; + 27 : IF Reverse THEN + BEGIN + Reverse := FALSE; + { + TextAttr := TextAttr SHR 4 + TextAttr SHL 4; + } + END; + 30 : TextAttr := TextAttr AND $F8 OR $00; + 31 : TextAttr := TextAttr AND $F8 OR $04; + 32 : TextAttr := TextAttr AND $F8 OR $02; + 33 : TextAttr := TextAttr AND $F8 OR $06; + 34 : TextAttr := TextAttr AND $F8 OR $01; + 35 : TextAttr := TextAttr AND $F8 OR $05; + 36 : TextAttr := TextAttr AND $F8 OR $03; + 37 : TextAttr := TextAttr AND $F8 OR $07; + 40 : TextAttr := TextAttr AND $8F OR $00; + 41 : TextAttr := TextAttr AND $8F OR $40; + 42 : TextAttr := TextAttr AND $8F OR $20; + 43 : TextAttr := TextAttr AND $8F OR $60; + 44 : TextAttr := TextAttr AND $8F OR $10; + 45 : TextAttr := TextAttr AND $8F OR $50; + 46 : TextAttr := TextAttr AND $8F OR $30; + 47 : TextAttr := TextAttr AND $8F OR $70; + END {CASE} ; + { fixup FOR reverse } + IF (Reverse) THEN + TextAttr := TextAttr SHR 4 + TextAttr SHL 4; + END; + END; + 'A' : {cuu} + BEGIN + IF (ParamArr[1] = 0) THEN + ParamArr[1] := 1; + {IF (WhereY - ParamArr[1] >= 1) + THEN} GotoXY(WhereX,(WhereY - ParamArr[1])) + {ELSE GotoXY(WhereX, 1);} + END; + 'B' : {cud} + BEGIN + IF ParamArr[1] = 0 THEN ParamArr[1] := 1; + {IF (WhereY + ParamArr[1] <= Hi(WindMax) - Hi(WindMin) + 1) + THEN }GotoXY(WhereX, WhereY + ParamArr[1]) + {ELSE GotoXY(WhereX, Hi(WindMax) - Hi(WindMin) + 1);} + END; + 'C' : {cuf} + BEGIN + IF ParamArr[1] = 0 THEN ParamArr[1] := 1; + {IF (WhereX + ParamArr[1] <= Lo(WindMax) - Lo(WindMin) + 1) + THEN} GotoXY(WhereX + ParamArr[1], WhereY) + {ELSE GotoXY(Lo(WindMax) - Lo(WindMin) + 1, WhereY);} + END; + 'D' : {cub} + BEGIN + IF (ParamArr[1] = 0) THEN ParamArr[1] := 1; + {IF (WhereX - ParamArr[1] >= 1) + THEN} GotoXY(WhereX - ParamArr[1], WhereY) + {ELSE GotoXY(1, WhereY);} + END; + 'H', 'f' : {cup,hvp} + BEGIN + IF (ParamArr[1] = 0) THEN ParamArr[1] := 1; + IF (ParamArr[2] = 0) THEN ParamArr[2] := 1; + + {IF (ParamArr[2] > Lo(WindMax) + 1) + THEN ParamArr[2] := Lo(WindMax) - Lo(WindMin) + 1; + IF (ParamArr[1] > Hi(WindMax) + 1) + THEN ParamArr[1] := Hi(WindMax) - Hi(WindMin) + 1;} + GotoXY(ParamArr[2], ParamArr[1]) ; + END; + 'J' : IF (ParamArr[1] = 2) THEN ClrScr + ELSE + FOR i := WhereY TO 25 DO delline; { some terms use others! } + 'K' : ClrEOL; + 'L' : IF (ParamArr[1] = 0) THEN + insline + ELSE + FOR i := 1 TO ParamArr[1] DO insline; { must NOT Move cursor } + 'M' : IF (ParamArr[1] = 0) THEN + delline + ELSE + FOR i := 1 TO ParamArr[1] DO delline; { must NOT Move cursor } + 'P' : {dc } + BEGIN + END; + 's' : {scp} + BEGIN + SaveX := WhereX; + SaveY := WhereY; + END; + 'u' : {rcp} GotoXY(SaveX,SaveY); + '@':; { Some unknown code appears TO DO nothing } + ELSE + Write(c); + END {CASE c} ; + END; + END {CASE NextState} ; +END {AnsiWrite} ; + +PROCEDURE ShellDos(MakeBatch: Boolean; CONST Command: AStr; VAR ResultCode: Integer); +VAR + BatFile: Text; + FName, + s: AStr; +BEGIN + IF (NOT MakeBatch) THEN + FName := Command + ELSE + BEGIN + FName := 'TEMP'+IntToStr(ThisNode)+'.BAT'; + Assign(BatFile,FName); + ReWrite(BatFile); + WriteLn(BatFile,Command); + Close(BatFile); + LastError := IOResult; + END; + + IF (FName <> '') THEN + FName := ' /c '+FName; + + Com_Flush_Send; + + Com_DeInstall; + + CursorOn(TRUE); + + SwapVectors; + +{$IFDEF MSDOS} + IF (General.SwapShell) THEN + BEGIN + s := GetEnv('TEMP'); + IF (s = '') THEN + s := StartDir; + Init_SpawNo(s,General.SwapTo,20,10); + ResultCode := Spawn(GetEnv('COMSPEC'),FName,0); + END; +{$ENDIF} +{$IFDEF WIN32} + ResultCode := -1; +{$ENDIF} + + IF (NOT General.SwapShell) OR (ResultCode = -1) THEN + BEGIN + Exec(GetEnv('COMSPEC'),FName); + ResultCode := Lo(DOSExitCode); + LastError := IOResult; + END; + + SwapVectors; + + IF (MakeBatch) THEN + Kill(FName); + + Com_Install; + + IF (NOT LocalIOOnly) AND NOT (lockedport IN Liner.mflags) THEN + Com_Set_Speed(ComPortSpeed); + + Update_Screen; + + TextAttr := CurrentColor; + + LastKeyHit := Timer; +END; + +FUNCTION LennMCI(CONST InString: STRING): Integer; +VAR + TempStr: STRING; + Counter, + StrLen: Byte; +BEGIN + StrLen := Length(InString); + Counter := 0; + WHILE (Counter < Length(InString)) DO + BEGIN + Inc(Counter); + CASE InString[Counter] OF + ^S : BEGIN + Dec(StrLen,2); + Inc(Counter); + END; + '^' : IF (Length(InString) > Counter) AND (InString[Counter + 1] IN ['0'..'9']) THEN + BEGIN + Dec(StrLen,2); + Inc(Counter); + END; + '|' : IF (Length(InString) > (Counter + 1)) AND (InString[Counter + 1] IN ['0'..'9']) AND + (Instring[Counter + 2] IN ['0'..'9']) THEN + BEGIN + Dec(StrLen,3); + Inc(Counter); + END; + '%' : IF (MCIAllowed) AND (Length(InString) > (Counter + 1)) THEN + BEGIN + TempStr := AllCaps(MCI('%' + InString[Counter + 1] + InString[Counter + 2])); + IF (Copy(TempStr,1,3) <> '%' + UpCase(InString[Counter + 1]) + UpCase(InString[Counter + 2])) THEN + Inc(StrLen,Length(TempStr) - 3); + END; + END; + END; + LennMCI := StrLen; +END; + +{$V-} +PROCEDURE LCmds3(Len,c: Byte; c1,c2,c3: AStr); +VAR + s: AStr; +BEGIN + s := ''; + s := s+'^1(^'+Chr(c + Ord('0'))+c1[1]+'^1)'+PadLeftStr(Copy(c1,2,LennMCI(c1)-1),Len-1); + IF (c2 <> '') THEN + s := s+'^1(^'+Chr(c + Ord('0')) + c2[1]+'^1)'+PadLeftStr(Copy(c2,2,LennMCI(c2)-1),Len-1); + IF (c3 <> '') THEN + s := s+'^1(^'+Chr(c + Ord('0')) + c3[1]+'^1)'+Copy(c3,2,LennMCI(c3)-1); + PrintACR(s); +END; + +PROCEDURE LCmds(Len,c: Byte; c1,c2: AStr); +VAR + s: AStr; +BEGIN + s := Copy(c1,2,LennMCI(c1) - 1); + IF (c2 <> '') THEN + s := PadLeftStr(s,Len - 1); + Prompt('^1(^' + IntToStr(c) + c1[1] + '^1)' + s); + IF (c2 <> '') THEN + Prompt('^1(^' + IntToStr(c) + c2[1] + '^1)' + Copy(c2,2,LennMCI(c2) - 1)); + NL; +END; + +FUNCTION MsgSysOp: Boolean; +BEGIN + MsgSysOp := (CoSysOp) OR (AACS(General.MSOP)) OR (AACS(MemMsgArea.SysOpACS)); +END; + +FUNCTION FileSysOp: Boolean; +BEGIN + FileSysOp := ((CoSysOp) OR (AACS(General.FSOP))); +END; + +FUNCTION CoSysOp: Boolean; +BEGIN + CoSysOp := ((SysOp) OR (AACS(General.CSOP))); +END; + +FUNCTION SysOp: Boolean; +BEGIN + SysOp := (AACS(General.SOP)); +END; + +FUNCTION Timer: LongInt; +BEGIN + Timer := ((Ticks * 5) DIV 91); { 2.5 times faster than Ticks DIV 18.2 } +END; + +FUNCTION OkVT100: Boolean; +BEGIN + OkVT100 := (VT100 IN ThisUser.Flags); +END; + +FUNCTION OkANSI: Boolean; +BEGIN + OkANSI := (ANSI IN ThisUser.Flags); +END; + +FUNCTION OkRIP: Boolean; +BEGIN + OkRIP := (RIP IN ThisUser.SFlags); +END; + +FUNCTION OkAvatar: Boolean; +BEGIN + OkAvatar := (Avatar IN ThisUser.Flags); +END; + +FUNCTION NSL: LongInt; +VAR + BeenOn: LongInt; +BEGIN + IF ((UserOn) OR (NOT InWFCMenu)) THEN + BEGIN + BeenOn := (GetPackDateTime - TimeOn); + NSL := ((LongInt(ThisUser.TLToday) * 60 + ExtraTime + FreeTime) - (BeenOn + ChopTime + CreditTime)); + END + ELSE + NSL := 3600; +END; + +FUNCTION StripColor(CONST InString: STRING): STRING; +VAR + TempStr: STRING; + Counter: Byte; +BEGIN + TempStr := ''; + Counter := 0; + WHILE (Counter < Length(InString)) DO + BEGIN + Inc(Counter); + CASE InString[Counter] OF + ^S : Inc(Counter); + '^' : IF (InString[Counter + 1] IN ['0'..'9']) THEN + Inc(Counter) + ELSE + TempStr := TempStr + '^'; + '|' : IF (InString[Counter + 1] IN ['0'..'9']) AND (InString[Counter + 2] IN ['0'..'9']) THEN + Inc(Counter,2) + ELSE + TempStr := TempStr + '|'; + ELSE + TempStr := TempStr + InString[Counter]; + END; + END; + StripColor := TempStr; +END; + +PROCEDURE sl1(s: AStr); +BEGIN + IF (SLogging) THEN + BEGIN + S := S + '^1'; + + IF (General.StripCLog) THEN + s := StripColor(s); + + Append(SysOpLogFile); + IF (IOResult = 0) THEN + BEGIN + WriteLn(SysOpLogFile,s); + Close(SysOpLogFile); + LastError := IOResult; + END; + + IF (SLogSeparate IN ThisUser.SFlags) THEN + BEGIN + Append(SysOpLogFile1); + IF (IOResult = 0) THEN + BEGIN + WriteLn(SysOpLogFile1,s); + Close(SysOpLogFile1); + LastError := IOResult; + END; + END; + + END; +END; + +PROCEDURE SysOpLog(s:AStr); +BEGIN + sl1(' '+s); +END; + +FUNCTION StrToInt(S: Str11): LongInt; +VAR + I: Integer; + L: LongInt; +BEGIN + Val(S,L,I); + IF (I > 0) THEN + BEGIN + S[0] := Chr(I - 1); + Val(S,L,I) + END; + IF (S = '') THEN + StrToInt := 0 + ELSE + StrToInt := L; +END; + +FUNCTION RealToStr(R: Real; W,D: Byte): STRING; +VAR + S: STRING[11]; +BEGIN + Str(R:W:D,S); + RealToStr := S; +END; + +FUNCTION ValueR(S: AStr): REAL; +VAR + Code: Integer; + R: REAL; +BEGIN + Val(S,R,Code); + IF (Code <> 0) THEN + BEGIN + S := Copy(S,1,(Code - 1)); + Val(S,R,Code) + END; + ValueR := R; + IF (S = '') THEN + ValueR := 0; +END; + +FUNCTION AgeUser(CONST BirthDate: LongInt): Word; +VAR + DT1, + DT2: DateTime; + Year: Word; +BEGIN + PackToDate(DT1,BirthDate); + GetDateTime(DT2); + Year := (DT2.Year - DT1.Year); + IF (DT2.Month < DT1.Month) THEN + Dec(Year); + IF (DT2.Month = DT1.Month) AND (DT2.Day < DT1.Day) THEN + Dec(Year); + AgeUser := Year; +END; + +FUNCTION AllCaps(InString: STRING): STRING; +VAR + Counter: Byte; +BEGIN + FOR Counter := 1 TO Length(InString) DO + IF (InString[Counter] IN ['a'..'z']) THEN + InString[Counter] := Chr(Ord(InString[Counter]) - Ord('a')+Ord('A')); + AllCaps := InString; +END; + +FUNCTION Caps(Instring: STRING): STRING; +VAR + Counter: Integer; { must be Integer } +BEGIN + IF (InString[1] IN ['a'..'z']) THEN + Dec(InString[1],32); + FOR Counter := 2 TO Length(Instring) DO + IF (InString[Counter - 1] IN ['a'..'z','A'..'Z']) THEN + IF (InString[Counter] IN ['A'..'Z']) THEN + Inc(InString[Counter],32) + ELSE + ELSE + IF (InString[Counter] IN ['a'..'z']) THEN + Dec(InString[Counter],32); + Caps := InString; +END; + +FUNCTION GetC(c: Byte): STRING; +CONST + xclr: ARRAY [0..7] OF Char = ('0','4','2','6','1','5','3','7'); +VAR + s: STRING[10]; + b: Boolean; + + PROCEDURE adto(ss: str8); + BEGIN + IF (s[Length(s)] <> ';') AND (s[Length(s)] <> '[') THEN + s := s + ';'; + s := s + ss; + b := TRUE; + END; + +BEGIN + b := FALSE; + IF ((CurrentColor AND (NOT c)) AND $88) <> 0 THEN + BEGIN + s := #27+'[0'; + CurrentColor := $07; + END + ELSE + s := #27+'['; + IF (c AND 7 <> CurrentColor AND 7) THEN + adto('3'+xclr[c AND 7]); + IF (c AND $70 <> CurrentColor AND $70) THEN + adto('4'+xclr[(c SHR 4) AND 7]); + IF (c AND 128 <> 0) THEN + adto('5'); + IF (c AND 8 <> 0) THEN + adto('1'); + IF (NOT b) THEN + adto('3'+xclr[c AND 7]); + s := s + 'm'; + GetC := s; +END; + +PROCEDURE SetC(C: Byte); +BEGIN + IF (NOT (OkANSI OR OkAvatar)) THEN + BEGIN + TextAttr := 7; + Exit; + END; + IF (C <> CurrentColor) THEN + BEGIN + IF (NOT (Color IN ThisUser.Flags)) THEN + IF ((C AND 8) = 8) THEN + C := 15 + ELSE + C := 7; + IF (OutCom) THEN + IF (OkAvatar) THEN + SerialOut(^V^A+Chr(C AND $7f)) + ELSE + SerialOut(GetC(C)); + TextAttr := C; + CurrentColor := C; + END; +END; + +PROCEDURE UserColor(Color: Byte); +BEGIN + IF (Color IN [0..9]) THEN + IF (OkANSI OR OkAvatar) THEN + SetC(Scheme.Color[Color + 1]); +END; + +FUNCTION SQOutSp(InString: STRING): STRING; +BEGIN + WHILE (Pos(' ',InString) > 0) DO + Delete(InString,Pos(' ',InString),1); + SQOutSp := InString; +END; + +FUNCTION ExtractDriveNumber(s: AStr): Byte; +BEGIN + s := FExpand(s); + ExtractDriveNumber := (Ord(s[1]) - 64); +END; + +FUNCTION PadLeftStr(InString: STRING; MaxLen: Byte): STRING; +VAR + StrLen, + Counter: Byte; +BEGIN + StrLen := LennMCI(InString); + IF (StrLen > MaxLen) THEN + WHILE (StrLen > MaxLen) DO + BEGIN + InString[0] := Chr(MaxLen + (Length(InString) - StrLen)); + StrLen := LennMCI(InString); + END + ELSE + FOR Counter := StrLen TO (MaxLen - 1) DO + InString := InString + ' '; + PadLeftStr := Instring; +END; + +FUNCTION PadRightStr(InString: STRING; MaxLen: Byte): STRING; +VAR + StrLen, + Counter: Byte; +BEGIN + StrLen := LennMCI(InString); + FOR Counter := StrLen TO (MaxLen - 1) DO + InString := ' ' + InString; + IF (StrLen > MaxLen) THEN + InString[0] := Chr(MaxLen + (Length(InString) - StrLen)); + PadRightStr := Instring; +END; + +FUNCTION PadLeftInt(L: LongInt; MaxLen: Byte): STRING; +BEGIN + PadLeftInt := PadLeftStr(IntToStr(L),MaxLen); +END; + +FUNCTION PadRightInt(L: LongInt; MaxLen: Byte): STRING; +BEGIN + PadRightInt := PadRightStr(IntToStr(L),MaxLen); +END; + +PROCEDURE Prompt(CONST InString: STRING); +VAR + SaveAllowAbort: Boolean; +BEGIN + SaveAllowAbort := AllowAbort; + AllowAbort := FALSE; + PrintMain(InString); + AllowAbort := SaveAllowAbort; +END; + +PROCEDURE Print(CONST Instring: STRING); +BEGIN + Prompt(InString+^M^J); +END; + +PROCEDURE NL; +BEGIN + Prompt(^M^J); +END; + +PROCEDURE Prt(CONST Instring: STRING); +BEGIN + UserColor(4); + Prompt(Instring); + UserColor(3); +END; + +PROCEDURE MPL(MaxLen: Byte); +VAR + Counter, + SaveWhereX : Byte; +BEGIN + IF (OkANSI OR OkAvatar) THEN + BEGIN + UserColor(6); + SaveWhereX := WhereX; + IF (OutCom) THEN + FOR Counter := 1 TO MaxLen DO + Com_Send(' '); + IF (WantOut) THEN + FOR Counter := 1 TO MaxLen DO + Write(' '); + GotoXY(SaveWhereX,WhereY); + IF (OutCom) THEN + IF (OkAvatar) THEN + SerialOut(^y+^H+Chr(MaxLen)) + ELSE + SerialOut(#27+'['+IntToStr(MaxLen)+'D'); + END; +END; + +FUNCTION InKey: Word; +VAR + c: Char; + l: LongInt; +BEGIN + c := #0; + InKey := 0; + CheckHangup; + IF (KeyPressed) THEN + BEGIN + c := ReadKey; + IF (c = #0) AND (KeyPressed) THEN + BEGIN + c := ReadKey; + SKey1(c); + IF (c = #31) OR (C = #46) THEN + c := #1 + ELSE + BEGIN + InKey := (Ord(c) * 256); { Return scan code IN MSB } + Exit; + END; + END; + IF (Buf <> '') THEN + BEGIN + c := Buf[1]; + Buf := Copy(Buf,2,255); + END; + InKey := Ord(c); + END + ELSE IF (InCom) THEN + BEGIN + c := CInKey; + IF (c = #27) THEN + BEGIN + IF (Empty) THEN + Delay(100); + IF (c = #27) AND (NOT Empty) THEN + BEGIN + c := CInKey; + IF (c = '[') OR (c = 'O') THEN + BEGIN + l := (Ticks + 4); + c := #0; + WHILE (l > Ticks) AND (c = #0) DO + c := CInKey; + END; + CASE Char(c) OF + 'A' : InKey := F_UP; {UpArrow} + 'B' : InKey := F_DOWN; {DownArrow} + 'C' : InKey := F_RIGHT; {RightArrow} + 'D' : InKey := F_LEFT; {LeftArrow} + 'H' : InKey := F_HOME; {Home} + 'K' : InKey := F_END; {END - PROCOMM+} + 'R' : InKey := F_END; {END - GT} + '4' : BEGIN + InKey := F_END; + c := CInKey; + END; + 'r' : InKey := F_PGUP; {PgUp} + 'q' : InKey := F_PGDN; {PgDn} + 'n' : InKey := F_INS; {Ins} + END; + Exit; + END; + END; + IF (c = #127) THEN + InKey := F_DEL + ELSE + InKey := Ord(c); + END; +END; + +PROCEDURE OutTrap(c: Char); +BEGIN + IF (c <> ^G) THEN + Write(TrapFile,c); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Error writing to trap file.'); + Trapping := FALSE; + END; +END; + +PROCEDURE OutKey(c: Char); +VAR + S: Str1; +BEGIN + IF (NOT Echo) THEN + IF (General.LocalSec) AND (c IN [#32..#255]) THEN + BEGIN + s := lRGLNGStr(1,TRUE); {FString.EchoC;} + c := s[1]; + END; + IF (c IN [#27,^V,^y]) THEN + DOSANSIOn := TRUE; + IF (WantOut) AND (DOSANSIOn) AND (NextState <> Waiting) THEN + BEGIN + DOSANSI(c); + IF (OutCom) THEN + Com_Send(c); + Exit; + END + ELSE IF (c <> ^J) AND (c <> ^L) THEN + IF (WantOut) AND (NOT DOSANSIOn) AND NOT ((c = ^G) AND InCom) THEN + Write(c) + ELSE IF (WantOut) AND NOT ((c = ^G) AND InCom) THEN + DOSANSI(c); + + IF (NOT Echo) AND (c IN [#32..#255]) THEN + BEGIN + S := lRGLNGStr(1,TRUE); {FString.EchoC;} + c := S[1]; + END; + + CASE c OF + ^J : BEGIN + IF (NOT InChat) AND (NOT Write_Msg) AND (NOT CtrlJOff) AND (NOT DOSANSIOn) THEN + BEGIN + IF (((CurrentColor SHR 4) AND 7) > 0) OR (CurrentColor AND 128 = 128) THEN + SetC(Scheme.Color[1]) + END + ELSE + LIL := 1; + IF (Trapping) THEN + OutTrap(c); + IF (WantOut) THEN + Write(^J); + IF (OutCom) THEN + Com_Send(^J); + Inc(LIL); + IF (LIL >= PageLength) THEN + BEGIN + LIL := 1; + IF (TempPause) THEN + PauseScr(TRUE); + END; + END; + ^L : BEGIN + IF (WantOut) THEN + ClrScr; + IF (OutCom) THEN + Com_Send(^L); + LIL := 1; + END; + ELSE + BEGIN + IF (OutCom) THEN + Com_Send(c); + IF (Trapping) THEN + OutTrap(c); + END; + END; +END; + +FUNCTION PageLength: Word; +BEGIN + IF (InCom) THEN + PageLength := ThisUser.PageLen + ELSE IF (General.WindowOn) AND NOT (InWFCMenu) THEN + PageLength := (MaxDisplayRows - 2) + ELSE + PageLength := MaxDisplayRows; +END; + +PROCEDURE TeleConfCheck; +VAR + f: FILE; + s: STRING; + Counter: Byte; + SaveMCIAlllowed: Boolean; + { Only check IF we're bored AND NOT slicing } +BEGIN + IF (MaxChatRec > NodeChatLastRec) THEN + BEGIN + FOR Counter := 1 TO (LennMCI(MLC) + 5) DO + BackSpace; + Assign(f,General.TempPath+'MSG'+IntToStr(ThisNode)+'.TMP'); + Reset(f,1); + Seek(f,NodeChatLastRec); + WHILE NOT EOF(f) DO + BEGIN + BlockRead(f,s[0],1); + BlockRead(f,s[1],Ord(s[0])); + MultiNodeChat := FALSE; {avoid recursive calls during Pause!} + SaveMCIAlllowed := MCIAllowed; + MCIAllowed := FALSE; + Print(s); + MCIAllowed := SaveMCIAlllowed; + MultiNodeChat := TRUE; + END; + Close(f); + LastError := IOResult; + NodeChatLastRec := MaxChatRec; + Prompt('^3'+MLC); + END; +END; + +FUNCTION GetKey: Word; +CONST + LastTimeSlice: LongInt = 0; + LastCheckTimeSlice: LongInt = 0; +VAR +{$IFDEF MSDOS} + Killme: Pointer ABSOLUTE $0040 :$F000; +{$ENDIF} + Tf: Boolean; + I: Integer; + C: Word; + TempTimer: LongInt; +BEGIN + IF (DieLater) THEN +{$IFDEF MSDOS} + ASM + Call Killme + END; +{$ENDIF} +{$IFDEF WIN32} + Halt; +{$ENDIF} + LIL := 1; + IF (Buf <> '') THEN + BEGIN + C := Ord(Buf[1]); + Buf := Copy(Buf,2,255); + END + ELSE + BEGIN + IF (NOT Empty) THEN + BEGIN + IF (InChat) THEN + C := Ord(Chinkey) + ELSE + C := InKey; + END + ELSE + BEGIN + Tf := FALSE; + LastKeyHit := Timer; + C := 0; + WHILE ((C = 0) AND (NOT HangUp)) DO + BEGIN + TempTimer := Timer; + IF (LastScreenSwap > 0) THEN + BEGIN + IF ((TempTimer - LastScreenSwap) < 0) THEN + LastScreenSwap := ((Timer - LastScreenSwap) + 86400); + IF ((TempTimer - LastScreenSwap) > 10) THEN + Update_Screen; + END; + IF (Alert IN ThisUser.Flags) OR ((NOT ShutUpChatCall) AND (General.ChatCall) AND (ChatReason <> '')) THEN + BEGIN + IF ((TempTimer - LastBeep) < 0) THEN + LastBeep := ((TempTimer - LastBeep) + 86400); + IF ((Alert IN ThisUser.Flags) AND ((TempTimer - LastBeep) >= General.Alertbeep)) OR + ((ChatReason <> '') AND (SysOpAvailable) AND ((TempTimer - LastBeep) >= 5)) THEN + BEGIN + FOR I := 1 TO 100 DO + BEGIN +{$IFDEF MSDOS} + Sound(500 + (I * 10)); + Delay(2); + Sound(100 + (I * 10)); + Delay(2); + NoSound; +{$ENDIF} +{$IFDEF WIN32} + Sound(500, 200); + Sound(1500, 200); +{$ENDIF} + END; + LastBeep := TempTimer; + END; + END; + IF ((TempTimer - LastKeyHit) < 0) THEN + LastKeyHit := ((TempTimer - LastKeyHit) + 86400); + IF (General.TimeOut <> - 1) AND ((TempTimer - LastKeyHit) > (General.TimeOut * 60)) AND (NOT TimedOut) + AND (ComPortSpeed <> 0) THEN + BEGIN + TimedOut := TRUE; + PrintF('TIMEOUT'); + IF (NoFile) THEN + Print(^M^J^M^J'Time out - disconnecting.'^M^J^M^J); + HangUp := TRUE; + SysOpLog('Inactivity timeout at '+TimeStr); + END; + IF (General.TimeOutBell <> - 1) AND ((TempTimer - LastKeyHit) > (General.TimeOutBell * 60)) AND + (NOT Tf) THEN + BEGIN + Tf := TRUE; + OutKey(^G); + Delay(100); + OutKey(^G); + END; + IF (Empty) THEN + BEGIN + IF (ABS((Ticks - LastTimeSlice)) >= General.Slicetimer) THEN + BEGIN +{$IFDEF MSDOS} + CASE Tasker OF + None : ASM + int 28h + END; + DV : ASM + Mov ax, 1000h + int 15h + END; + Win,Win32,DOS5N : ASM (* Added Win32 & DOS5N *) + Mov ax, 1680h + int 2Fh + END; + Os2 : ASM + Push dx + XOR dx, dx + Mov ax, 0 + Sti + Hlt + Db 035h, 0Cah + Pop dx + END; + END; +{$ENDIF} +{$IFDEF WIN32} + Sleep(1); +{$ENDIF} + LastTimeSlice := Ticks; + END + ELSE IF (MultiNodeChat) AND (NOT InChat) AND (ABS(Ticks - LastCheckTimeSlice) > 9) THEN + BEGIN + LastCheckTimeSlice := Ticks; + TeleConfCheck; + LIL := 1; + END; + END; + IF (InChat) THEN + C := Ord(Chinkey) + ELSE + C := InKey; + END; + IF (UserOn) AND ((GetPackDateTime - CreditsLastUpdated) > 60) AND NOT (FNoCredits IN ThisUser.Flags) THEN + BEGIN + Inc(ThisUser.Debit,General.Creditminute * ((GetPackDateTime - CreditsLastUpdated) DIV 60)); + CreditsLastUpdated := GetPackDateTime; + END; + END; + END; + GetKey := C; +END; + +PROCEDURE CLS; +BEGIN + IF (OkANSI OR OkVT100) THEN + SerialOut(^[+'[1;1H'+^[+'[2J') + ELSE + OutKey(^L); + IF (WantOut) THEN + ClrScr; + IF (Trapping) THEN + OutTrap(^L); + UserColor(1); + LIL := 1; +END; + +FUNCTION DisplayARFlags(AR: ARFlagSet; C1,C2: Char): AStr; +VAR + Flag: Char; + TempStr: AStr; +BEGIN + TempStr := ''; + FOR Flag := 'A' TO 'Z' DO + IF Flag IN AR THEN + TempStr := TempStr + '^'+C1+Flag + ELSE + TempStr := TempStr + '^'+C2+'-'; + DisplayArFlags := TempStr; +END; + +PROCEDURE ToggleARFlag(Flag: Char; VAR AR: ARFlagSet; VAR Changed: Boolean); +VAR + SaveAR: ARFlagSet; +BEGIN + SaveAR := AR; + IF (Flag IN ['A'..'Z']) THEN + IF (Flag IN AR) THEN + Exclude(AR,Flag) + ELSE + Include(AR,Flag); + IF (SaveAR <> AR) THEN + Changed := TRUE; +END; + +FUNCTION DisplayACFlags(Flags: FlagSet; C1,C2: Char): AStr; +VAR + Flag: FlagType; + TempS: AStr; +BEGIN + TempS := ''; + FOR Flag := RLogon TO RMsg DO + IF (Flag IN Flags) THEN + TempS := TempS + '^'+C1+Copy('LCVUA*PEKM',(Ord(Flag) + 1),1) + ELSE + TempS := TempS + '^'+C2+'-'; + TempS := TempS + '^'+C2+'/'; + FOR Flag := FNoDLRatio TO FNoDeletion DO + IF (Flag IN Flags) THEN + TempS := TempS + '^'+C1+Copy('1234',(Ord(Flag) - 19),1) + ELSE + TempS := TempS + '^'+C2+'-'; + DisplayACFlags := TempS; +END; + +PROCEDURE ToggleACFlag(Flag: FlagType; VAR Flags: FlagSet); +BEGIN + IF (Flag IN Flags) THEN + Exclude(Flags,Flag) + ELSE + Include(Flags,Flag); +END; + +PROCEDURE ToggleACFlags(Flag: Char; VAR Flags: FlagSet; VAR Changed: Boolean); +VAR + SaveFlags: FlagSet; +BEGIN + SaveFlags := Flags; + CASE Flag OF + 'L' : ToggleACFlag(RLogon,Flags); + 'C' : ToggleACFlag(RChat,Flags); + 'V' : ToggleACFlag(RValidate,Flags); + 'U' : ToggleACFlag(RUserList,Flags); + 'A' : ToggleACFlag(RAMsg,Flags); + '*' : ToggleACFlag(RPostAn,Flags); + 'P' : ToggleACFlag(RPost,Flags); + 'E' : ToggleACFlag(REmail,Flags); + 'K' : ToggleACFlag(RVoting,Flags); + 'M' : ToggleACFlag(RMsg,Flags); + '1' : ToggleACFlag(FNoDLRatio,Flags); + '2' : ToggleACFlag(FNoPostRatio,Flags); + '3' : ToggleACFlag(FNoCredits,Flags); + '4' : ToggleACFlag(FNoDeletion,Flags); + END; + IF (SaveFlags <> Flags) THEN + Changed := TRUE; +END; + +PROCEDURE ToggleStatusFlag(Flag: StatusFlagType; VAR SUFlags: StatusFlagSet); +BEGIN + IF (Flag IN SUFlags) THEN + Exclude(SUFlags,Flag) + ELSE + Include(SUFlags,Flag); +END; + +PROCEDURE ToggleStatusFlags(Flag: Char; VAR SUFlags: StatusFlagSet); +BEGIN + CASE Flag OF + 'A' : ToggleStatusFlag(LockedOut,SUFlags); + 'B' : ToggleStatusFlag(Deleted,SUFlags); + 'C' : ToggleStatusFlag(TrapActivity,SUFlags); + 'D' : ToggleStatusFlag(TrapSeparate,SUFlags); + 'E' : ToggleStatusFlag(ChatAuto,SUFlags); + 'F' : ToggleStatusFlag(ChatSeparate,SUFlags); + 'G' : ToggleStatusFlag(SLogSeparate,SUFlags); + 'H' : ToggleStatusFlag(CLSMsg,SUFlags); + 'I' : ToggleStatusFlag(RIP,SUFlags); + 'J' : ToggleStatusFlag(FSEditor,SUFlags); + 'K' : ToggleStatusFlag(AutoDetect,SUFlags); + END; +END; + +FUNCTION TACCH(Flag: Char): FlagType; +BEGIN + CASE Flag OF + 'L': TACCH := RLogon; + 'C': TACCH := RChat; + 'V': TACCH := RValidate; + 'U': TACCH := RUserList; + 'A': TACCH := RAMsg; + '*': TACCH := RPostAN; + 'P': TACCH := RPost; + 'E': TACCH := REmail; + 'K': TACCH := RVoting; + 'M': TACCH := RMsg; + '1': TACCH := FNoDLRatio; + '2': TACCH := FNoPostRatio; + '3': TACCH := FNoCredits; + '4': TACCH := FNoDeletion; + END; +END; + +{$IFDEF MSDOS} +FUNCTION AOnOff(b: Boolean; CONST s1,s2:AStr): STRING; ASSEMBLER; +ASM + PUSH ds + Test b, 1 + JZ @@1 + LDS si, s1 + JMP @@2 + @@1: LDS si, s2 + @@2: LES di, @Result + XOR Ch, Ch + MOV cl, Byte ptr ds:[si] + MOV Byte ptr es:[di], cl + Inc di + Inc si + CLD + REP MOVSB + POP ds +END; +{$ENDIF} +{$IFDEF WIN32} +FUNCTION AOnOff(b: Boolean; CONST s1,s2:AStr): STRING; +BEGIN + if (b) then + AOnOff := s1 + else + AOnOff := s2; +END; +{$ENDIF} + +FUNCTION ShowOnOff(b: Boolean): STRING; +BEGIN + IF (b) THEN + ShowOnOff := 'On ' + ELSE + ShowOnOff := 'Off'; +END; + +FUNCTION ShowYesNo(b: Boolean): STRING; +BEGIN + IF (b) THEN + ShowYesNo := 'Yes' + ELSE + ShowYesNo := 'No '; +END; + +FUNCTION YN(Len: Byte; DYNY: Boolean): Boolean; +VAR + Cmd: Char; +BEGIN + IF (NOT HangUp) THEN + BEGIN + UserColor(3); + Prompt(SQOutSp(ShowYesNo(DYNY))); + REPEAT + Cmd := UpCase(Char(GetKey)); + UNTIL (Cmd IN ['Y','N',^M]) OR (HangUp); + IF (DYNY) AND (Cmd <> 'N') THEN + Cmd := 'Y'; + IF (DYNY) AND (Cmd = 'N') THEN + Prompt(#8#8#8'^3No ') + ELSE IF (NOT DYNY) AND (Cmd = 'Y') THEN + Prompt(#8#8'^3Yes'); + IF (Cmd = 'N') AND (Len <> 0) THEN + DoBackSpace(1,Len) + ELSE + NL; + UserColor(1); + YN := (Cmd = 'Y') AND (NOT HangUp); + END; +END; + +FUNCTION PYNQ(CONST InString: AStr; MaxLen: Byte; DYNY: Boolean): Boolean; +BEGIN + UserColor(7); + Prompt(InString); + PYNQ := YN(MaxLen,DYNY); +END; + +PROCEDURE OneK(VAR C: Char; ValidKeys: AStr; DisplayKey,LineFeed: Boolean); +BEGIN + MPL(1); + TempPause := (Pause IN ThisUser.Flags); + REPEAT + C := UpCase(Char(GetKey)); + UNTIL (Pos(C,ValidKeys) > 0) OR (HangUp); + IF (HangUp) THEN + C := ValidKeys[1]; + IF (DisplayKey) THEN + OutKey(C); + IF (Trapping) THEN + OutTrap(C); + UserColor(1); + IF (LineFeed) THEN + NL; +END; + +PROCEDURE OneK1(VAR C: Char; ValidKeys: AStr; DisplayKey,LineFeed: Boolean); +BEGIN + MPL(1); + TempPause := (Pause IN ThisUser.Flags); + REPEAT + C := Char(GetKey); + IF (C = 'q') THEN + C := UpCase(C); + UNTIL (Pos(C,ValidKeys) > 0) OR (HangUp); + IF (HangUp) THEN + C := ValidKeys[1]; + IF (DisplayKey) THEN + OutKey(C); + IF (Trapping) THEN + OutTrap(C); + UserColor(1); + IF (LineFeed) THEN + NL; +END; + +PROCEDURE LOneK(DisplayStr: AStr; VAR C: Char; ValidKeys: AStr; DisplayKey,LineFeed: Boolean); +BEGIN + Prt(DisplayStr); + MPL(1); + TempPause := (Pause IN ThisUser.Flags); + REPEAT + C := UpCase(Char(GetKey)); + UNTIL (Pos(C,ValidKeys) > 0) OR (HangUp); + IF (HangUp) THEN + C := ValidKeys[1]; + IF (DisplayKey) THEN + OutKey(C); + IF (Trapping) THEN + OutTrap(C); + UserColor(1); + IF (LineFeed) THEN + NL; +END; + +FUNCTION Centre(InString: AStr): STRING; +VAR + StrLen, + Counter: Integer; +BEGIN + StrLen := LennMCI(Instring); + IF (StrLen < ThisUser.LineLen) THEN + BEGIN + Counter := ((ThisUser.LineLen - StrLen) DIV 2); + Move(Instring[1],Instring[Counter + 1],Length(Instring)); + Inc(Instring[0],Counter); + FillChar(InString[1],Counter,#32); + END; + Centre := InString; +END; + +PROCEDURE WKey; +VAR + Cmd: Char; +BEGIN + IF (NOT AllowAbort) OR (Abort) OR (HangUp) OR (Empty) THEN + Exit; + Cmd := Char(GetKey); + IF (DisplayingMenu) AND (Pos(UpCase(Cmd),MenuKeys) > 0) THEN + BEGIN + MenuAborted := TRUE; + Abort := TRUE; + Buf := Buf + UpCase(Cmd); + END + ELSE + CASE UpCase(Cmd) OF + ' ',^C,^X,^K : + Abort := TRUE; + 'N',^N : + IF (Reading_A_Msg) THEN + BEGIN + Abort := TRUE; + Next := TRUE; + END; + 'P',^S : + Cmd := Char(GetKey); + ELSE IF (Reading_A_Msg) OR (PrintingFile) THEN + IF (Cmd <> #0) THEN + Buf := Buf + Cmd; + END; + IF (Abort) THEN + BEGIN + Com_Purge_Send; + NL; + END; +END; + +PROCEDURE PrintMain(CONST ss:STRING); +VAR + i, + X: Word; + X2: Byte; + c: Char; + cs: STRING; + s: STRING; + Justify: Byte; +BEGIN + IF (Abort) AND (AllowAbort) THEN + Exit; + IF (HangUp) THEN + BEGIN + Abort := TRUE; + Exit; + END; + + IF (NOT MCIAllowed) THEN + s := ss + ELSE + BEGIN + s := ''; + FOR i := 1 TO Length(ss) DO + IF (ss[i] = '%') AND (i + 2 <= Length(ss)) THEN + BEGIN + cs := MCI(Copy(ss,i,3)); { faster than adding } + IF (cs = Copy(ss,i,3)) THEN + BEGIN + s := s + '%'; + Continue; + END; + Inc(i,2); + IF (Length(ss) >= i + 2) AND (ss[i + 1] IN ['#','{','}']) THEN + BEGIN + IF (ss[i + 1] = '}') THEN + Justify := 0 + ELSE IF (ss[i + 1] = '{') THEN + Justify := 1 + ELSE + Justify := 2; + IF (ss[i + 2] IN ['0'..'9']) THEN + BEGIN + X2 := Ord(ss[i + 2]) - 48; + Inc(i, 2); + IF (ss[i + 1] IN ['0'..'9']) THEN + BEGIN + X2 := X2 * 10 + Ord(ss[i + 1]) - 48; + Inc(i, 1); + END; + IF (X2 > 0) THEN + CASE Justify OF + 0 : cs := PadRightStr(cs,X2); + 1 : cs := PadLeftStr(cs,X2); + 2 : WHILE (Length(cs) < X2) DO + BEGIN + cs := ' ' + cs; + IF (Length(cs) < X2) THEN + cs := cs + ' '; + END; + END; + END; + END; + { s := s + cs; } + IF (Length(cs) + Length(s) <= 255) THEN + BEGIN + Move(cs[1],s[Length(s)+1],Length(cs)); + Inc(s[0],Length(cs)); + END + ELSE + IF (Length(s) < 255) THEN + BEGIN + Move(cs[1],s[Length(s)+1],(255 - Length(s))); + s[0] := #255; + END; + END + ELSE + IF (Length(s) < 255) THEN { s := s + ss[i]; } + BEGIN + Inc(s[0]); + s[Length(s)] := ss[i]; + END; + END; + + IF NOT (OkANSI OR OkAvatar) THEN + s := StripColor(s); + + i := 1; + IF ((NOT Abort) OR (NOT AllowAbort)) AND (NOT HangUp) THEN { can't change IN loop } + WHILE (i <= Length(s)) DO + BEGIN + CASE s[i] OF + '%' : IF MCIAllowed AND (i + 1 < Length(s)) THEN + BEGIN + IF (UpCase(s[i + 1]) = 'P') AND (UpCase(s[i + 2]) = 'A') THEN { %PA Pause } + BEGIN + Inc(i,2); + PauseScr(FALSE) + END + ELSE IF (UpCase(s[i + 1]) = 'P') AND (UpCase(s[i + 2]) = 'E') THEN { %PE Null Pause } + BEGIN + Inc(i,2); + PauseIsNull := TRUE; + PauseScr(FALSE); + PauseIsNull := FALSE; + END + ELSE IF (UpCase(s[i + 1]) = 'D') THEN + IF (UpCase(s[i + 2]) = 'E') THEN { %DE Delay } + BEGIN + Inc(i,2); + OutKey(' '); OutKey(#8); { guard against +++ } + Delay(800); + END + ELSE IF ((UpCase(s[i + 2]) = 'F') AND (NOT PrintingFile)) THEN { %DF File Include } + BEGIN + cs := ''; Inc(i, 3); + WHILE (i < Length(s)) AND (s[i] <> '%') DO + BEGIN + cs := cs + s[i]; + Inc(i); + END; + PrintF(StripName(cs)); + END + ELSE + ELSE + OutKey('%'); + END + ELSE + OutKey('%'); + ^S:IF (i < Length(s)) AND (NextState = Waiting) THEN BEGIN + IF (Ord(s[i + 1]) <= 200) THEN SetC(Scheme.Color[Ord(s[i + 1])]); Inc(i); + END + ELSE OutKey(''); + '|':IF (ColorAllowed) AND (i + 1 < Length(s)) AND + (s[i + 1] IN ['0'..'9']) AND (s[i + 2] IN ['0'..'9']) + THEN + BEGIN + X := StrToInt(Copy(s,i + 1,2)); + CASE X OF + 0..15:SetC(CurrentColor - (CurrentColor MOD 16) + X); + 16..23:SetC(((X - 16) * 16) + (CurrentColor MOD 16)); + END; + Inc(i,2); + END + ELSE + OutKey('|'); + #9:FOR X := 1 TO 5 DO + OutKey(' '); + '^':IF (ColorAllowed) AND (i < Length(s)) AND (s[i+1] IN ['0'..'9']) THEN + BEGIN + Inc(i); + UserColor(Ord(s[i]) - 48); + END + ELSE + OutKey('^'); + ELSE + OutKey(s[i]); + END; + Inc(i); + X2 := i; + WHILE (X2 < Length(s)) AND + NOT (s[X2] IN [^S,'^','|','%',^G,^L,^V,^y,^J,^[]) + DO + Inc(X2); + + IF (X2 > i) THEN + BEGIN + cs[0] := Chr(X2 - i); + Move(s[i], cs[1], X2 - i); { twice as fast as Copy(s,i,x2-i); } + i := X2; + + IF (Trapping) THEN + Write(TrapFile,cs); + + IF (WantOut) THEN + IF (NOT DOSANSIOn) THEN + Write(cs) + ELSE + FOR X2 := 1 TO Length(cs) DO + DOSANSI(cs[X2]); + + SerialOut(cs); + END; + END; + WKey; +END; + +PROCEDURE PrintACR(InString: STRING); +VAR + TurnOff: Boolean; +BEGIN + IF (AllowAbort) AND (Abort) THEN + Exit; + Abort := FALSE; + TurnOff := (InString[Length(Instring)] = #29); + IF (TurnOff) THEN + Dec(InString[0]); + CheckHangup; + IF (NOT CROff) AND NOT (TurnOff) THEN + InString := InString + ^M^J; + PrintMain(InString); + IF (Abort) THEN + BEGIN + CurrentColor := (255 - CurrentColor); + UserColor(1); + END; + CROff := FALSE; +END; + +PROCEDURE pfl(FN: AStr); +VAR + fil: Text; + ls: STRING[255]; + ps: Byte; + c: Char; + SaveTempPause, + ToggleBack, + SaveAllowAbort: Boolean; +BEGIN + PrintingFile := TRUE; + SaveAllowAbort := AllowAbort; + AllowAbort := TRUE; + Abort := FALSE; + Next := FALSE; + ToggleBack := FALSE; + SaveTempPause := TempPause; + FN := AllCaps(FN); + IF (General.WindowOn) AND (Pos('.AN',FN) > 0) OR (Pos('.AV',FN) > 0) THEN + BEGIN + TempPause := FALSE; + ToggleBack := TRUE; + ToggleWindow(FALSE); + IF (OkRIP) THEN + SerialOut('!|*|'); + END; + IF (Pos('.RI',FN) > 0) THEN + TempPause := FALSE; + IF (NOT HangUp) THEN + BEGIN + Assign(fil,SQOutSp(FN)); + Reset(fil); + IF (IOResult <> 0) THEN + NoFile := TRUE + ELSE + BEGIN + Abort := FALSE; + Next := FALSE; + WHILE (NOT EOF(fil)) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + ps := 0; + REPEAT + Inc(ps); + Read(fil,ls[ps]); + IF EOF(fil) THEN {check again incase avatar parameter} + BEGIN + Inc(ps); + Read(fil,ls[ps]); + IF EOF(fil) THEN + Dec(ps); + END; + UNTIL ((ls[ps] = ^J) AND (NextState IN [Waiting..In_Param])) OR (ps = 255) OR EOF(fil); + ls[0] := Chr(ps); + CROff := TRUE; + CtrlJOff := ToggleBack; + PrintACR(ls); + END; + Close(fil); + END; + NoFile := FALSE; + END; + AllowAbort := SaveAllowAbort; + PrintingFile := FALSE; + CtrlJOff := FALSE; + IF (ToggleBack) THEN + ToggleWindow(TRUE); + RedrawForANSI; + IF (NOT TempPause) THEN + LIL := 0; + TempPause := SaveTempPause; +END; + +FUNCTION BSlash(InString: AStr; b: Boolean): AStr; +BEGIN + IF (b) THEN + BEGIN + WHILE (Copy(InString,(Length(InString) - 1),2) = '\\') DO + InString := Copy(Instring,1,(Length(InString) - 2)); + IF (Copy(InString,Length(InString),1) <> '\') THEN + InString := InString + '\'; + END + ELSE + WHILE (InString[Length(InString)] = '\') DO + Dec(InString[0]); + BSlash := Instring; +END; + +FUNCTION Exist(FileName: AStr): Boolean; +VAR + DirInfo1: SearchRec; +BEGIN + FindFirst(SQOutSp(FileName),AnyFile,DirInfo1); + Exist := (DOSError = 0); +END; + +FUNCTION ExistDir(Path: PathStr): Boolean; +VAR + DirInfo1: SearchRec; +BEGIN + Path := AllCaps(BSlash(Path,FALSE)); + FindFirst(Path,AnyFile,DirInfo1); + ExistDir := (DOSError = 0) AND (DirInfo1.Attr AND $10 = $10); +END; + +PROCEDURE PrintFile(FileName: AStr); +VAR + s: AStr; + dayofweek: Byte; + i: Integer; +BEGIN + FileName := AllCaps(FileName); + s := FileName; + IF (Copy(FileName,Length(FileName) - 3,4) = '.ANS') THEN + BEGIN + IF (Exist(Copy(FileName,1,Length(FileName) - 4)+'.AN1')) THEN + REPEAT + i := Random(10); + IF (i = 0) THEN + FileName := Copy(FileName,1,Length(FileName) - 4)+'.ANS' + ELSE + FileName := Copy(FileName,1,Length(FileName) - 4)+'.AN'+IntToStr(i); + UNTIL (Exist(FileName)); + END + ELSE IF (Copy(FileName,Length(FileName) - 3,4) = '.AVT') THEN + BEGIN + IF (Exist(Copy(FileName,1,Length(FileName) - 4)+'.AV1')) THEN + REPEAT + i := Random(10); + IF (i = 0) THEN + FileName := Copy(FileName,1,Length(FileName) - 4)+'.AVT' + ELSE + FileName := Copy(FileName,1,Length(FileName) - 4)+'.AV'+IntToStr(i); + UNTIL (Exist(FileName)); + END + ELSE IF (Copy(FileName,Length(FileName) - 3,4) = '.RIP') THEN + BEGIN + IF (Exist(Copy(FileName,1,Length(FileName) - 4)+'.RI1')) THEN + REPEAT + i := Random(10); + IF (i = 0) THEN + FileName := Copy(FileName,1,Length(FileName) - 4)+'.RIP' + ELSE + FileName := Copy(FileName,1,Length(FileName) - 4)+'.RI'+IntToStr(i); + UNTIL (Exist(FileName)); + END; + GetDayOfWeek(DayOfWeek); + s := FileName; + s[Length(s) - 1] := Chr(DayOfWeek + 48); + IF (Exist(s)) THEN + FileName := s; + pfl(FileName); +END; + +PROCEDURE PrintF(FileName: AStr); +VAR + FFN, + Path: PathStr; + Name: NameStr; + Ext: ExtStr; + + j: Integer; (* doesn't seem to do anything *) + +BEGIN + NoFile := TRUE; + FileName := SQOutSp(FileName); + IF (FileName = '') THEN + Exit; + + IF (Pos('\',FileName) <> 0) THEN (* ??? *) + j := 1 + ELSE + BEGIN + j := 2; + FSplit(FExpand(FileName),Path,Name,Ext); + IF (NOT Exist(General.MiscPath+Name+'.*')) THEN + Exit; + END; + + FFN := FileName; + IF ((Pos('\',FileName) = 0) AND (Pos(':',FileName) = 0)) THEN + FFN := General.MiscPath+FFN; + FFN := FExpand(FFN); + IF (Pos('.',FileName) <> 0) THEN + PrintFile(FFN) + ELSE + BEGIN + IF (OkRIP) AND Exist(FFN+'.RIP') THEN + PrintFile(FFN+'.RIP'); + IF (NoFile) AND (OkAvatar) AND Exist(FFN+'.AVT') THEN + PrintFile(FFN+'.AVT'); + IF (NoFile) AND (OkANSI) AND Exist(FFN+'.ANS') THEN + PrintFile(FFN+'.ANS'); + IF (NoFile) AND (Exist(FFN+'.ASC')) THEN + PrintFile(FFN+'.ASC'); + END; +END; + +FUNCTION VerLine(B: Byte): STRING; +BEGIN + CASE B OF + 1 : VerLine := '|09The |14Renegade Bulletin Board System|09, Version |15'+General.Version; + 2 : VerLine := '|09Brought to you by |10The Renegade Development Team|09.'; + 3 : VerLine := '|09Copyright (c) |151991-2009|09'; + END; +END; + +FUNCTION AACS1(User: UserRecordType; UNum: Integer; s: ACString): Boolean; +VAR + s1, + s2: AStr; + c, + c1, + c2: Char; + i, + p1, + p2, + j: Integer; + b: Boolean; + + PROCEDURE GetRest; + VAR + incre: Byte; + BEGIN + s1 := c; + p1 := i; + incre := 0; + IF ((i <> 1) AND (s[i - 1] = '!')) THEN + BEGIN + s1 := '!' + s1; + Dec(p1); + END; + IF (c IN ['N','C','E','F','G','I','J','M','O','R','V','Z']) THEN + BEGIN + s1 := s1 + s[i + 1]; + Inc(i); + IF c IN ['N'] THEN + WHILE s[i + 1 + incre] IN ['0'..'9'] DO + BEGIN + Inc (incre); + s1 := s1 + s[i +1 +incre]; + END; + END + ELSE + BEGIN + j := i + 1; + WHILE (j <= Length(s)) AND (s[j] IN ['0'..'9']) DO + BEGIN + s1 := s1 + s[j]; + Inc(j); + END; + i := (j - 1); + END; + p2 := i; + END; + + FUNCTION ArgStat(s: AStr): Boolean; + VAR + VS: AStr; + c: Char; + DayOfWeek: Byte; + RecNum1, + RecNum, + VSI: Integer; + Hour, + Minute, + Second, + Sec100: Word; + BoolState, + ACS: Boolean; + BEGIN + BoolState := (s[1] <> '!'); + IF (NOT BoolState) THEN + s := Copy(s,2,(Length(s) - 1)); + VS := Copy(s,2,(Length(s) - 1)); + VSI := StrToInt(VS); + CASE s[1] OF + 'A' : ACS := (AgeUser(User.BirthDate) >= VSI); + 'B' : ACS := ((ActualSpeed >= (VSI * 100)) AND (VSI > 0)) OR (ComPortSpeed = 0); + 'C' : BEGIN + ACS := (CurrentConf = VS); + C := VS[1]; + IF (NOT ConfSystem) AND (C IN ConfKeys) THEN + BEGIN + IF FindConference(C,Conference) THEN + ACS := AACS1(ThisUser,UserNum,Conference.ACS) + ELSE + ACS := FALSE; + END; + END; + 'D' : ACS := (User.DSL >= VSI) OR (TempSysOp); + 'E' : CASE UpCase(VS[1]) OF + 'A' : ACS := OkANSI; + 'N' : ACS := NOT (OkANSI OR OkAvatar OR OkVT100); + 'V' : ACS := OkAvatar; + 'R' : ACS := OkRIP; + '1' : ACS := OkVT100; + END; + 'F' : ACS := (UpCase(VS[1]) IN User.AR); + 'G' : ACS := (User.Sex = UpCase(VS[1])); + 'H' : BEGIN + GetTime(Hour,Minute,Second,Sec100); + ACS := (Hour = VSI); + END; + 'I' : ACS := IsInvisible; + 'J' : ACS := (Novice IN User.Flags); + 'K' : ACS := (ReadMsgArea = VSI); + 'L' : ACS := (ReadFileArea = VSI); + 'M' : ACS := (UnVotedTopics = 0); + 'N' : ACS := (ThisNode = VSI); + 'O' : ACS := SysOpAvailable; + 'P' : ACS := ((User.lCredit - User.Debit) >= VSI); + 'R' : ACS := (TACCH(UpCase(VS[1])) IN User.Flags); + 'S' : ACS := (User.SL >= VSI) OR (TempSysOp); + 'T' : ACS := (NSL DIV 60 >= VSI); + 'U' : ACS := (UNum = VSI); + 'V' : BEGIN + Reset(ValidationFile); + RecNum1 := -1; + RecNum := 1; + WHILE (RecNum <= NumValKeys) AND (RecNum1 = -1) DO + BEGIN + Seek(ValidationFile,(RecNum - 1)); + Read(ValidationFile,Validation); + IF (Validation.Key = '!') THEN + RecNum1 := RecNum; + Inc(RecNum); + END; + Close(ValidationFile); + ACS := (RecNum1 <> -1) AND (User.SL > Validation.NewSL); + END; + 'W' : BEGIN + GetDayOfWeek(DayOfWeek); + ACS := (DayOfWeek = Ord(s[2]) - 48); + END; + 'X' : ACS := (((User.Expiration DIV 86400) - (GetPackDateTime DIV 86400)) <= VSI) AND (User.Expiration > 0); + 'Y' : ACS := (Timer DIV 60 >= VSI); + 'Z' : IF (FNoPostRatio IN User.Flags) THEN + ACS := TRUE + ELSE IF (General.PostRatio[User.SL] > 0) AND (User.LoggedOn > 100 / General.PostRatio[User.SL]) THEN + ACS := ((User.MsgPost / User.LoggedOn * 100) >= General.PostRatio[User.SL]) + ELSE + ACS := TRUE; + END; + IF (NOT BoolState) THEN + ACS := NOT ACS; + ArgStat := ACS; + END; + +BEGIN + i := 0; + s := AllCaps(s); + WHILE (i < Length(s)) DO + BEGIN + Inc(i); + c := s[i]; + IF (c IN ['A'..'Z']) AND (i <> Length(s)) THEN + BEGIN + GetRest; + b := ArgStat(s1); + Delete(s,p1,Length(s1)); + IF (b) THEN + s2 := '^' + ELSE + s2 := '%'; + Insert(s2,s,p1); + Dec(i,(Length(s1) - 1)); + END; + END; + s := '(' + s + ')'; + WHILE (Pos('&', s) <> 0) DO + Delete(s,Pos('&',s),1); + WHILE (Pos('^^', s) <> 0) DO + Delete(s,Pos('^^',s),1); + WHILE (Pos('(', s) <> 0) DO + BEGIN + i := 1; + WHILE ((s[i] <> ')') AND (i <= Length(s))) DO + BEGIN + IF (s[i] = '(') THEN + p1 := i; + Inc(i); + END; + p2 := i; + s1 := Copy(s,(p1 + 1),((p2 - p1) - 1)); + WHILE (Pos('|',s1) <> 0) DO + BEGIN + i := Pos('|',s1); + c1 := s1[i - 1]; + c2 := s1[i + 1]; + s2 := '%'; + IF ((c1 IN ['%','^']) AND (c2 IN ['%','^'])) THEN + BEGIN + IF ((c1 = '^') OR (c2 = '^')) THEN + s2 := '^'; + Delete(s1,(i - 1),3); + Insert(s2,s1,(i - 1)); + END + ELSE + Delete(s1,i,1); + END; + WHILE (Pos('%%',s1) <> 0) DO + Delete(s1,Pos('%%',s1),1); {leave only "%"} + WHILE (Pos('^^', s1) <> 0) DO + Delete(s1,Pos('^^',s1),1); {leave only "^"} + WHILE (Pos('%^', s1) <> 0) DO + Delete(s1,Pos('%^',s1)+1,1); {leave only "%"} + WHILE (Pos('^%', s1) <> 0) DO + Delete(s1,Pos('^%',s1),1); {leave only "%"} + Delete(s,p1,((p2 - p1) + 1)); + Insert(s1,s,p1); + END; + AACS1 := (Pos('%',s) = 0); +END; + +FUNCTION AACS(s: ACString): Boolean; +BEGIN + AACS := AACS1(ThisUser,UserNum,s); +END; + +PROCEDURE LoadNode(NodeNumber: Byte); +BEGIN + IF (General.MultiNode) THEN + BEGIN + Reset(NodeFile); + IF (NodeNumber >= 1) AND (NodeNumber <= FileSize(NodeFile)) AND (IOResult = 0) THEN + BEGIN + Seek(NodeFile,(NodeNumber - 1)); + Read(NodeFile,NodeR); + END; + Close(NodeFile); + LastError := IOResult; + END; +END; + +PROCEDURE Update_Node(NActivityDesc: AStr; SaveVars: Boolean); +BEGIN + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + IF (SaveVars) THEN + BEGIN + SaveNDescription := NodeR.ActivityDesc; + NodeR.ActivityDesc := NActivityDesc + END + ELSE + NodeR.ActivityDesc := SaveNDescription; + (* + IF (UserOn) THEN + BEGIN + *) + NodeR.User := UserNum; + NodeR.UserName := ThisUser.Name; + NodeR.Sex := ThisUser.Sex; + NodeR.Age := AgeUser(ThisUser.BirthDate); + NodeR.CityState := ThisUser.CityState; + NodeR.LogonTime := TimeOn; + NodeR.Channel := ChatChannel; + (* + END; + *) + SaveNode(ThisNode); + END; +END; + +FUNCTION MaxChatRec: LongInt; +VAR + DirInfo1: SearchRec; +BEGIN + FindFirst(General.TempPath+'MSG'+IntToStr(ThisNode)+'.TMP',AnyFile,DirInfo1); + IF (DOSError = 0) THEN + MaxChatRec := DirInfo1.Size + ELSE + MaxChatRec := 0; +END; + +FUNCTION MaxNodes: Byte; +VAR + DirInfo1: SearchRec; +BEGIN + FindFirst(General.DataPath+'MULTNODE.DAT',AnyFile,DirInfo1); + IF (DOSError = 0) THEN + MaxNodes := (DirInfo1.Size DIV SizeOf(NodeRecordType)) + ELSE + MaxNodes := 0; +END; + +PROCEDURE SaveNode(NodeNumber: Byte); +BEGIN + IF (General.MultiNode) THEN + BEGIN + Reset(NodeFile); + IF (NodeNumber >= 1) AND (NodeNumber <= FileSize(NodeFile)) AND (IOResult = 0) THEN + BEGIN + Seek(NodeFile,(NodeNumber - 1)); + Write(NodeFile,NodeR); + END; + Close(NodeFile); + LastError := IOResult; + END; +END; + +PROCEDURE LoadURec(VAR User: UserRecordType; UserNumber: Integer); +VAR + FO: Boolean; +BEGIN + FO := (FileRec(UserFile).Mode <> FMClosed); + IF (NOT FO) THEN + BEGIN + Reset(UserFile); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Error opening USERS.DAT.'); + Exit; + END; + END; + + IF (UserNumber <> UserNum) OR (NOT UserOn) THEN + BEGIN + Seek(UserFile,UserNumber); + Read(UserFile,User); + END + ELSE + User := ThisUser; + + IF (NOT FO) THEN + Close(UserFile); + + LastError := IOResult; +END; + +PROCEDURE SaveURec(User: UserRecordType; UserNumber: Integer); +VAR + FO: Boolean; + NodeNumber: Byte; +BEGIN + FO := (FileRec(UserFile).Mode <> FMClosed); + IF (NOT FO) THEN + BEGIN + Reset(UserFile); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Error opening USERS.DAT.'); + Exit; + END; + END; + + Seek(UserFile,UserNumber); + Write(UserFile,User); + + IF (NOT FO) THEN + Close(UserFile); + + IF (UserNumber = UserNum) THEN + ThisUser := User + ELSE + BEGIN + IF (General.MultiNode) THEN + BEGIN + NodeNumber := OnNode(UserNumber); + IF (NodeNumber > 0) THEN + BEGIN + LoadNode(NodeNumber); + Include(NodeR.Status,NUpdate); + SaveNode(NodeNumber); + END; + END; + END; + LastError := IOResult; +END; + +FUNCTION MaxUsers: Integer; +VAR + DirInfo1: SearchRec; +BEGIN + FindFirst(General.DataPath+'USERS.DAT',AnyFile,DirInfo1); + IF (DOSError = 0) THEN + MaxUsers := (DirInfo1.Size DIV SizeOf(UserRecordType)) + ELSE + MaxUsers := 0; +END; + +FUNCTION MaxIDXRec: Integer; +VAR + DirInfo1: SearchRec; +BEGIN + FindFirst(General.DataPath+'USERS.IDX',AnyFile,DirInfo1); + IF (DOSError = 0) THEN + MaxIDXRec := (DirInfo1.Size DIV SizeOf(UserIDXRec)) + ELSE + MaxIDXRec := 0; + IF (NOT UserOn) AND (DirInfo1.Size MOD SizeOf(UserIDXRec) <> 0) THEN + MaxIDXRec := -1; { UserOn is so it'll only show during boot up } +END; + +FUNCTION HiMsg: Word; +VAR + DirInfo1: SearchRec; +BEGIN + FindFirst(General.MsgPath+MemMsgArea.FileName+'.HDR',AnyFile,DirInfo1); + IF (DOSError = 0) THEN + HiMsg := (DirInfo1.Size DIV SizeOf(MHeaderRec)) + ELSE + HiMsg := 0; +END; + +PROCEDURE ScanInput(VAR S: AStr; CONST Allowed: AStr); +VAR + SaveS: AStr; + c: Char; + Counter: Byte; + GotCmd: Boolean; +BEGIN + GotCmd := FALSE; + s := ''; + REPEAT + c := UpCase(Char(GetKey)); + SaveS := s; + IF ((Pos(c,Allowed) <> 0) AND (s = '')) THEN + BEGIN + GotCmd := TRUE; + s := c; + END + ELSE IF (Pos(c,'0123456789') > 0) OR (c = '-') THEN + BEGIN + IF ((Length(s) < 6) OR ((Pos('-',s) > 0) AND (Length(s) < 11))) THEN + s := s + c; + END + ELSE IF ((s <> '') AND (c = ^H)) THEN + Dec(s[0]) + ELSE IF (c = ^X) THEN + BEGIN + FOR Counter := 1 TO Length(s) DO + BackSpace; + s := ''; + SaveS := ''; + END + ELSE IF (c = #13) THEN + GotCmd := TRUE; + IF (Length(s) < Length(SaveS)) THEN + BackSpace; + IF (Length(s) > Length(SaveS)) THEN + Prompt(s[Length(s)]); + UNTIL (GotCmd) OR (HangUp); + UserColor(1); + NL; +END; + +PROCEDURE ScreenDump(CONST FileName: AStr); +VAR + ScreenFile: Text; + TempStr: AStr; + c: Char; + XPos, + YPos: Byte; + VidSeg: Word; +BEGIN + Assign(ScreenFile,FileName); + Append(ScreenFile); + IF (IOResult = 2) THEN + ReWrite(ScreenFile); + IF (MonitorType = 7) THEN + VidSeg := $B000 + ELSE + VidSeg := $B800; + FOR YPos := 1 TO MaxDisplayRows DO + BEGIN + TempStr := ''; + FOR XPos := 1 TO MaxDisplayCols DO + BEGIN +{$IFDEF MSDOS} + c := Chr(Mem[VidSeg:(160 * (YPos - 1) + 2 * (XPos - 1))]); +{$ENDIF} +{$IFDEF WIN32} + c := SysReadCharAt(XPos - 1, YPos - 1); +{$ENDIF} + IF (c = #0) THEN + c := #32; + IF ((XPos = WhereX) AND (YPos = WhereY)) THEN + c := #178; + TempStr := TempStr + c; + END; + WHILE (TempStr[Length(TempStr)] = ' ') DO + Dec(TempStr[0]); + WriteLn(ScreenFile,TempStr); + END; + Close(ScreenFile); + LastError := IOResult; +END; + +PROCEDURE InputPath(CONST DisplayStr: AStr; VAR DirPath: Str40; CreateDir,AllowExit: Boolean; VAR Changed: Boolean); +VAR + TempDirPath: Str40; + CurDir: PathStr; + Counter: Byte; +BEGIN + REPEAT + TempDirPath := DirPath; + Changed := FALSE; + InputWN1(DisplayStr,TempDirPath,39,[UpperOnly,InterActiveEdit],Changed); + TempDirPath := SQOutSp(TempDirPath); + + IF (Length(TempDirPath) = 1) THEN + TempDirPath := TempDirPath + ':\' + ELSE IF (Length(TempDirPath) = 2) AND (TempDirPath[2] = ':') THEN + TempDirPath := TempDirPath + '\'; + + IF (AllowExit) AND (TempDirPath = '') THEN + BEGIN + NL; + Print('Aborted!'); + END + ELSE IF (TempDirPath = '') THEN + BEGIN + NL; + Print('^7A valid path must be specified!^1'); + END + ELSE IF (NOT (TempDirPath[1] IN ['A'..'Z'])) OR (Length(TempDirPath) < 3) OR + (NOT (TempDirPath[2] = ':')) OR (NOT (TempDirPath[3] = '\')) THEN + BEGIN + NL; + Print('^7Invalid drive specification: "'+Copy(TempDirPath,1,3)+'"^1'); + TempDirPath := ''; + END + ELSE + BEGIN + GetDir(0,CurDir); + ChDir(TempDirPath[1]+':'); + IF (IOResult <> 0) THEN + BEGIN + NL; + Print('^7Drive does not exist: "'+Copy(TempDirPath,1,3)+'"^1'); + TempDirPath := ''; + END + ELSE + BEGIN + ChDir(CurDir); + IF (CreateDir) THEN + BEGIN + TempDirPath := BSlash(TempDirPath,TRUE); + IF (Length(TempDirPath) > 3) AND (NOT ExistDir(TempDirPath)) THEN + BEGIN + NL; + IF PYNQ('Directory does not exist, create it? ',0,FALSE) THEN + BEGIN + Counter := 2; + WHILE (Counter <= Length(TempDirPath)) DO + BEGIN + IF (TempDirPath[Counter] = '\') THEN + BEGIN + IF (TempDirPath[Counter - 1] <> ':') THEN + BEGIN + IF (NOT ExistDir(Copy(TempDirPath,1,(Counter - 1)))) THEN + BEGIN + MkDir(Copy(TempDirPath,1,(Counter - 1))); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error creating directory: '+Copy(TempDirPath,1,(Counter - 1))); + SysOpLog('^7Error creating directory: '+Copy(TempDirPath,1,(Counter - 1))); + TempDirPath := ''; + END; + END; + END; + END; + Inc(Counter); + END; + END; + END; + END; + END; + END; + UNTIL (TempDirPath <> '') OR (AllowExit) OR (HangUp); + IF (TempDirPath <> '') THEN + TempDirPath := BSlash(TempDirPath,TRUE); + IF (TempDirPath <> DirPath) THEN + Changed := TRUE; + DirPath := TempDirPath; +END; + +FUNCTION OnNode(UserNumber: Integer): Byte; +VAR + NodeNumber: Byte; +BEGIN + OnNode := 0; + IF (General.MultiNode) AND (UserNumber > 0) THEN + FOR NodeNumber := 1 TO MaxNodes DO + BEGIN + LoadNode(NodeNumber); + IF (NodeR.User = UserNumber) THEN + BEGIN + OnNode := NodeNumber; + Exit; + END; + END; +END; + +PROCEDURE PurgeDir(s: AStr; SubDirs: Boolean); +VAR + (* + DirInfo1: SearchRec; + *) + odir: STRING[80]; +BEGIN + s := FExpand(s); + WHILE (s[Length(s)] = '\') DO + Dec(s[0]); + GetDir(ExtractDriveNumber(s),odir); + ChDir(s); + IF (IOResult <> 0) THEN + BEGIN + ChDir(odir); + Exit; + END; + FindFirst('*.*',AnyFile - Directory - VolumeID,DirInfo); (* Directory & VolumnID added *) + WHILE (DOSError = 0) DO + BEGIN + Kill(FExpand(DirInfo.Name)); + FindNext(DirInfo); + END; + ChDir(odir); + IF (SubDirs) THEN + RmDir(s); + LastError := IOResult; + ChDir(StartDir); +END; + +FUNCTION StripName(InString: STRING): STRING; +VAR + StrLen: Byte; +BEGIN + StrLen := Length(InString); + WHILE (StrLen > 0) AND (Pos(InString[StrLen],':\/') = 0) DO + Dec(StrLen); + Delete(InString,1,StrLen); + StripName := InString; +END; + +PROCEDURE Star(InString: AStr); +BEGIN + IF (OkANSI OR OkAvatar) THEN + Prompt('^4 ') + ELSE + Prompt('* '); + IF (InString[Length(InString)] = #29) THEN + Dec(InString[0]) + ELSE + InString := InString + ^M^J; + Prompt('^3'+InString+'^1'); +END; + +FUNCTION ctp(t,b: LongInt): STRING; +VAR + s: AStr; + n: LongInt; +BEGIN + IF ((t = 0) OR (b = 0)) THEN + n := 0 + ELSE + n := (t * 100) DIV b; + Str(n:6,s); + ctp := s; +END; + +FUNCTION CInKey: Char; +BEGIN + IF (NOT LocalIOOnly) AND (NOT Com_IsRecv_Empty) THEN + CInKey := Com_Recv + ELSE + CInKey := #0; +END; + +PROCEDURE Com_Send_Str(CONST InString: AStr); +VAR + Counter: Byte; +BEGIN + FOR Counter := 1 TO Length(InString) DO + CASE InString[Counter] OF + '~' : Delay(250); + '|' : BEGIN + Com_Send(^M); + IF (InWFCMenu) THEN + WriteWFC(^M); + END; + '^' : BEGIN + DTR(FALSE); + Delay(250); + DTR(TRUE); + END; + ELSE + BEGIN + Com_Send(InString[Counter]); + Delay(2); + IF (InWFCMenu) THEN + WriteWFC(InString[Counter]); + END; + END; +END; + +PROCEDURE DoTelnetHangUp(ShowIt: Boolean); +BEGIN + IF (NOT LocalIOOnly) THEN + BEGIN + IF (ShowIt) AND (NOT BlankMenuNow) THEN + BEGIN + TextColor(15); + TextBackGround(1); + GotoXY(32,17); + Prt('Hanging up node..'); + END; + Com_Flush_Recv; + DTR(FALSE); + END; + IF (ShowIt) AND (SysOpOn) AND (NOT BlankMenuNow) THEN + BEGIN + TextColor(15); + TextBackGround(1); + GotoXY(1,17); + ClrEOL; + END; +END; + +PROCEDURE dophoneHangup(ShowIt: Boolean); +VAR + c: Char; + Try: Integer; + SaveTimer: LongInt; +BEGIN + IF (NOT LocalIOOnly) THEN + BEGIN + IF (ShowIt) AND (NOT BlankMenuNow) THEN + BEGIN + TextColor(15); + TextBackGround(1); + GotoXY(32,17); + Write('Hanging up phone...'); + END; + Try := 0; + WHILE (Try < 3) AND (NOT KeyPressed) DO + BEGIN + Com_Flush_Recv; + Com_Send_Str(Liner.HangUp); + SaveTimer := Timer; + WHILE (ABS(Timer - SaveTimer) <= 2) AND (Com_Carrier) DO + BEGIN + c := CInKey; + IF (c > #0) AND (InWFCMenu) THEN + WriteWFC(c); + END; + Inc(Try); + END; + END; + IF (ShowIt) AND (SysOpOn) AND (NOT BlankMenuNow) THEN + BEGIN + TextColor(15); + TextBackGround(1); + GotoXY(1,17); + ClrEOL; + END; +END; + +PROCEDURE DoPhoneOffHook(ShowIt: Boolean); +VAR + TempStr: AStr; + c: Char; + Done: Boolean; + SaveTimer: LongInt; +BEGIN + IF (ShowIt) AND (NOT BlankMenuNow) AND (SysOpOn) THEN + BEGIN + TextColor(15); + TextBackGround(1); + GotoXY(33,17); + Write('Phone off hook'); + END; + Com_Flush_Recv; + Com_Send_Str(Liner.OffHook); + SaveTimer := Timer; + REPEAT + c := CInKey; + IF (c > #0) THEN + BEGIN + IF (InWFCMenu) THEN + WriteWFC(c); + IF (Length(TempStr) >= 160) THEN + Delete(TempStr,1,120); + TempStr := TempStr + c; + IF (Pos(Liner.OK,TempStr) > 0) THEN + Done := TRUE; + END; + UNTIL (ABS(Timer - SaveTimer) > 2) OR (Done) OR (KeyPressed); + Com_Flush_Recv; +END; + +PROCEDURE PauseScr(IsCont: Boolean); +VAR + Cmd: Char; + SaveCurCo, + Counter: Byte; + SaveMCIAllowed: Boolean; +BEGIN + SaveCurCo := CurrentColor; + SaveMCIAllowed := MCIAllowed; + MCIAllowed := TRUE; +{$IFDEF MSDOS} + NoSound; +{$ENDIF} + IF (NOT AllowContinue) AND NOT (PrintingFile AND AllowAbort) THEN + IsCont := FALSE; + IF (IsCont) THEN + { Prompt(FString.Continue) } + lRGLngStr(44,FALSE) + ELSE + BEGIN + IF NOT (PauseIsNull) THEN + { Prompt({FString.lPause); } + lRGLngStr(5,FALSE); + END; + LIL := 1; + IF (IsCont) THEN + BEGIN + REPEAT + Cmd := UpCase(Char(GetKey)); + CASE Cmd OF + 'C' : IF (IsCont) THEN + TempPause := FALSE; + 'N' : Abort := TRUE; + END; + UNTIL (Cmd IN ['Y','N','Q','C',^M]) OR (HangUp); + END + ELSE + Cmd := Char(GetKey); + IF (IsCont) THEN + FOR Counter := 1 TO LennMCI(lRGLngStr(44,TRUE){FString.Continue}) DO + BackSpace + ELSE + FOR Counter := 1 TO LennMCI(lRGLNGStr(5,TRUE){FString.lPause}) DO + BackSpace; + IF (Abort) THEN + NL; + IF (NOT HangUp) THEN + SetC(SaveCurCo); + MCIAllowed := SaveMCIAllowed; +END; + +FUNCTION SearchUser(Uname: Str36; RealNameOK: Boolean): Integer; +VAR + UserIDX: UserIDXRec; + Current: Integer; + Done: Boolean; +BEGIN + SearchUser := 0; + Reset(UserIDXFile); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Error opening USERS.IDX.'); + Exit; + END; + + WHILE (Uname[Length(Uname)] = ' ') DO + Dec(Uname[0]); + + Uname := AllCaps(Uname); + + Current := 0; + Done := FALSE; + + IF (FileSize(UserIDXFile) > 0) THEN + REPEAT + Seek(UserIDXFile,Current); + Read(UserIDXFile,UserIDX); + IF (Uname < UserIDX.Name) THEN + Current := UserIDX.Left + ELSE IF (Uname > UserIDX.Name) THEN + Current := UserIDX.Right + ELSE + Done := TRUE; + UNTIL (Current = -1) OR (Done); + Close(UserIDXFile); + + IF (Done) AND (RealNameOK OR NOT UserIDX.RealName) AND (NOT UserIDX.Deleted) THEN + SearchUser := UserIDX.Number; + + LastError := IOResult; +END; + +FUNCTION Plural(InString: STRING; Number: Byte): STRING; +BEGIN + IF (Number <> 1) THEN + Plural := InString + 's' + ELSE + Plural := InString; +END; + +FUNCTION FormattedTime(TimeUsed: LongInt): STRING; +VAR + s: AStr; +BEGIN + s := ''; + IF (TimeUsed > 3600) THEN + BEGIN + s := IntToStr(TimeUsed DIV 3600)+' '+Plural('Hour',TimeUsed DIV 3600) + ' '; + TimeUsed := (TimeUsed MOD 3600); + END; + IF (TimeUsed > 60) THEN + BEGIN + s := s + IntToStr(TimeUsed DIV 60)+' '+Plural('Minute',TimeUsed DIV 60) + ' '; + TimeUsed := (TimeUsed MOD 60); + END; + IF (TimeUsed > 0) THEN + s := s + IntToStr(TimeUsed)+' '+Plural('Second',TimeUsed); + IF (s = '') THEN + s := 'no time'; + WHILE (s[Length(s)] = ' ') DO + Dec(s[0]); + FormattedTime := s; +END; + +FUNCTION FunctionalMCI(CONST S: AStr; FileName,InternalFileName: AStr): STRING; +VAR + Temp: STRING; + Add: AStr; + Index: Byte; +BEGIN + Temp := ''; + FOR Index := 1 TO Length(S) DO + IF (S[Index] = '%') THEN + BEGIN + CASE UpCase(S[Index + 1]) OF + 'A' : Add := AOnOff(LocalIOOnly,'0',IntToStr(ActualSpeed)); + 'B' : Add := IntToStr(ComPortSpeed); + 'C' : Add := Liner.Address; + 'D' : Add := FunctionalMCI(Protocol.DLFList,'',''); + 'E' : Add := Liner.IRQ; + 'F' : Add := SQOutSp(FileName); + 'G' : Add := AOnOff((OkAvatar OR OkANSI),'1','0'); + 'H' : Add := SockHandle; + 'I' : BEGIN + IF (S[Index + 2] = 'P') THEN + BEGIN + Add := ThisUser.CallerID; + Inc(Index,1); + END + ELSE + BEGIN + Add := InternalFileName; + END; + END; + 'K' : BEGIN + LoadFileArea(FileArea); + IF (FADirDLPath IN MemFileArea.FAFlags) THEN + Add := MemFileArea.DLPath+MemFileArea.FileName+'.DIR' + ELSE + Add := General.DataPath+MemFileArea.FileName+'.DIR'; + END; + 'L' : Add := FunctionalMCI(Protocol.TempLog,'',''); + 'M' : Add := StartDir; + 'N' : Add := IntToStr(ThisNode); + 'O' : Add := Liner.DoorPath; + 'P' : Add := IntToStr(Liner.ComPort); + 'R' : Add := ThisUser.RealName; + 'T' : Add := IntToStr(NSL DIV 60); + 'U' : Add := ThisUser.Name; + '#' : Add := IntToStr(UserNum); + '1' : Add := Copy(Caps(ThisUser.RealName),1,Pos(' ',ThisUser.RealName) - 1); + '2' : IF (Pos(' ', ThisUser.RealName) = 0) THEN + Add := Caps(ThisUser.RealName) + ELSE + Add := Copy(Caps(ThisUser.RealName),Pos(' ',ThisUser.RealName) + 1,255); + ELSE + Add := '%' + S[Index + 1]; + END; + Temp := Temp + Add; + Inc(Index); + END + ELSE + Temp := Temp + S[Index]; + FunctionalMCI := Temp; +END; + +FUNCTION MCI(CONST S: STRING): STRING; +VAR + Temp: STRING; + Add: AStr; + Index: Byte; + I: Integer; +BEGIN + Temp := ''; + FOR Index := 1 TO Length(S) DO + IF (S[Index] = '%') AND (Index + 1 < Length(S)) THEN + BEGIN + Add := '%' + S[Index + 1] + S[Index + 2]; + WITH ThisUser DO + CASE UpCase(S[Index + 1]) OF + 'A' : CASE UpCase(S[Index + 2]) OF + '1' : Add := IntToStr(LowFileArea); + '2' : Add := IntToStr(HighFileArea); + '3' : Add := IntToStr(LowMsgArea); + '4' : Add := IntToStr(HighMsgArea); + 'B' : Add := FormatNumber(lCredit - Debit); + 'C' : Add := Copy(Ph,1,3); + 'D' : Add := Street; + 'O' : BEGIN + IF (PrintingFile) OR (Reading_A_Msg) THEN + AllowAbort := FALSE; + Add := ''; + END; + END; + 'B' : CASE UpCase(S[Index + 2]) OF + 'D' : Add := IntToStr(ActualSpeed); + 'L' : Add := PHours('Always allowed',General.MinBaudLowTime,General.MinBaudHiTime); + 'M' : Add := PHours('Always allowed',General.MinBaudDLLowTime,General.MinBaudDLHiTime); + 'N' : Add := General.BBSName; + 'P' : Add := General.BBSPhone; + END; + 'C' : CASE UpCase(S[Index + 2]) OF + 'A' : Add := FormatNumber(General.CallAllow[SL]); + 'D' : Add := AOnOff(General.PerCall,'call','day '); + 'L' : Add := ^L; + 'M' : Add := IntToStr(Msg_On); + 'N' : IF FindConference(CurrentConf,Conference) THEN + Add := Conference.Name + ELSE + Add:= ''; + 'R' : Add := FormatNumber(lCredit); + 'S' : Add := PHours('Always allowed',General.lLowTime,General.HiTime); + 'T' : Add := CurrentConf; + '+' : BEGIN + Add := ''; + CursorOn(TRUE); + END; + '-' : BEGIN + Add := ''; + CursorOn(FALSE); + END; + END; + 'D' : CASE UpCase(S[Index + 2]) OF + '1'..'3' : + Add := UsrDefStr[Ord(S[Index + 2]) - 48]; + 'A' : Add := DateStr; + 'B' : Add := FormatNumber(Debit); + 'D' : Add := FormatNumber(General.DlOneDay[SL]); + 'H' : Add := PHours('Always allowed',General.DLLowTime,General.DLHiTime); + 'K' : Add := FormatNumber(DK); + 'L' : Add := FormatNumber(Downloads); + 'S' : Add := IntToStr(DSL); + 'T' : BEGIN + IF (Timer > 64800) THEN + Add := 'evening' + ELSE IF (Timer > 43200) THEN + Add := 'afternoon' + ELSE + Add := 'morning' + END; + END; + 'E' : CASE UpCase(S[Index + 2]) OF + 'D' : Add := AOnOff((Expiration = 0),'Never',ToDate8(PD2Date(Expiration))); + 'S' : Add := FormatNumber(EmailSent); + 'T' : Add := IntToStr(General.EventWarningTime); + 'W' : Add := FormatNumber(Waiting); + 'X' : IF (Expiration > 0) THEN + Add := IntToStr((Expiration DIV 86400) - (GetPackDateTime DIV 86400)) + ELSE + Add := 'Never'; + END; + 'F' : CASE UpCase(S[Index + 2]) OF + '#' : Add := IntToStr(CompFileArea(FileArea,0)); + 'B' : BEGIN + LoadFileArea(FileArea); + Add := MemFileArea.AreaName; + END; + 'D' : Add := ToDate8(PD2Date(FirstOn)); + 'K' : Add := FormatNumber(DiskFree(ExtractDriveNumber(MemFileArea.ULPath)) DIV 1024); + 'N' : Add := Copy(RealName,1,(Pos(' ', RealName) - 1)); + 'P' : Add := FormatNumber(FilePoints); + 'S' : Add := AOnOff(NewScanFileArea,'','not '); + 'T' : Add := IntToStr(NumFileAreas); + END; + 'G' : CASE UpCase(S[Index + 2]) OF + 'N' : AOnOff((Sex = 'M'),'Mr.','Ms.'); + END; + 'H' : CASE UpCase(S[Index + 2]) OF + '1' : Add := CTim(General.lLowTime); (* Verify All CTim *) + '2' : Add := CTim(General.HiTime); + '3' : Add := CTim(General.MinBaudLowTime); + '4' : Add := CTim(General.MinBaudHiTime); + '5' : Add := CTim(General.DLLowTime); + '6' : Add := CTim(General.DLHiTime); + '7' : Add := CTim(General.MinBaudDLLowTime); + '8' : add := CTim(General.MinBaudDLHiTime); + 'M' : Add := IntToStr(HiMsg); + END; + 'I' : CASE UpCase(S[Index + 2]) OF + 'L' : Add := IntToStr(Illegal); + 'P' : Add := ThisUser.CallerID; + END; + 'K' : CASE UpCase(S[Index + 2]) OF + 'D' : Add := FormatNumber(General.DLKOneday[SL]); + 'R' : IF (DK > 0) THEN + Str((UK / DK):3:3,Add) + ELSE + Add := '0'; + END; + 'L' : CASE UpCase(S[Index + 2]) OF + 'C' : Add := ToDate8(PD2Date(LastOn)); + 'F' : Add := ^M^J; + 'N' : BEGIN + I := Length(RealName); + WHILE ((RealName[i] <> ' ') AND (i > 1)) DO + Dec(i); + Add := Copy(Caps(RealName),(i + 1),255); + END; + 'O' : Add := CityState; + END; + 'M' : CASE UpCase(S[Index + 2]) OF + '#' : Add := IntToStr(CompMsgArea(MsgArea,0)); + '1' : Add := IntToStr(General.GlobalMenu); + '2' : Add := IntToStr(General.AllStartMenu); + '3' : Add := IntToStr(General.ShuttleLogonMenu); + '4' : Add := IntToStr(General.NewUserInformationMenu); + '5' : Add := IntToStr(General.MessageReadMenu); + '6' : Add := IntToStr(General.FileListingMenu); + '7' : Add := IntToStr(General.MinimumBaud); + 'B' : BEGIN + i := ReadMsgArea; + IF (i <> MsgArea) THEN + LoadMsgArea(MsgArea); + Add := MemMsgArea.Name; + END; + 'L' : Add := IntToStr(NSL DIV 60); + 'N' : Add := ShowOnOff(General.MultiNode); + 'O' : Add := IntToStr((GetPackDateTime - TimeOn) DIV 60); + 'R' : Add := IntToStr(HiMsg - Msg_On); + 'S' : Add := AOnOff(LastReadRecord.NewScan,'','not '); + 'T' : Add := IntToStr(NumMsgAreas); + END; + 'N' : CASE UpCase(S[Index + 2]) OF + 'D' : Add := IntToStr(ThisNode); + 'L' : Add := ''; + 'M' : Add := ShowOnOff(General.NetworkMode); + 'R' : IF (Downloads > 0) THEN + Str((Uploads / Downloads):3:3,Add) + ELSE + Add := '0'; + END; + 'O' : CASE UpCase(S[Index + 2]) OF + '1' : IF (RIP IN SFlags) THEN + Add := 'RIP' + ELSE IF (Avatar IN Flags) THEN + Add := 'Avatar' + ELSE IF (ANSI IN Flags) THEN + Add := 'ANSI' + ELSE IF (VT100 IN Flags) THEN + Add := 'VT-100' + ELSE + Add := 'None'; + '2' : Add := IntToStr(LineLen)+'x'+IntToStr(PageLen); + '3' : Add := ShowOnOff(ClsMsg IN SFlags); + '4' : Add := ShowOnOff(FSEditor IN SFlags); + '5' : Add := ShowOnOff(Pause IN Flags); + '6' : Add := ShowOnOff(HotKey IN Flags); + '7' : Add := ShowOnOff(NOT (Novice IN Flags)); + '8' : IF (ForUsr > 0) THEN + Add := 'Forwarded - '+IntToStr(ForUsr) + ELSE IF (Nomail IN Flags) THEN + Add := 'Closed' + ELSE + Add := 'Open'; + '9' : Add := ShowOnOff(Color IN Flags); + 'S' : BEGIN + CASE Tasker OF + None : Add := 'DOS'; + DV : Add := 'DV'; + Win : Add := 'Windows'; + OS2 : Add := 'OS/2'; + Win32 : Add := 'Windows 32bit'; + Dos5N : Add := 'DOS/N'; + END; + END; + END; + 'P' : CASE UpCase(S[Index + 2]) OF + '1' : Add := General.MsgPath; + '2' : Add := General.NodePath; + '3' : Add := General.LMultPath; + '4' : Add := General.SysOpPW; + '5' : Add := General.NewUserPW; + '6' : Add := General.MinBaudOverride; + '7' : Add := General.ArcsPath; + 'B' : Add := General.BulletPrefix; + 'C' : IF (LoggedOn > 0) THEN + Str((MsgPost / LoggedOn) * 100:3:2,Add) + ELSE + Add := '0'; + 'D' : Add := General.DataPath; + 'F' : Add := General.FileAttachPath; + 'L' : Add := General.LogsPath; + 'M' : Add := General.MiscPath; + 'N' : Add := Ph; + 'O' : BEGIN + IF (PrintingFile) OR (Reading_A_Msg) THEN + TempPause := FALSE; + Add := ''; + END; + 'P' : Add := General.ProtPath; + 'S' : Add := FormatNumber(MsgPost); + 'T' : Add := General.TempPath; + END; + 'Q' : CASE UpCase(S[Index + 2]) OF + 'D' : Add := IntToStr(NumBatchDLFiles); + 'U' : Add := IntToStr(NumBatchULFiles); + END; + 'R' : CASE UpCase(S[Index + 2]) OF + 'N' : Add := Caps(RealName); + END; + 'S' : CASE UpCase(S[Index + 2]) OF + '1' : Add := lRGLngStr(41,TRUE); {FString.UserDefEd[Ord(S[Index + 2]) - 48]; } + '2' : Add := lRGLngStr(42,TRUE); {FString.UserDefEd[Ord(S[Index + 2]) - 48]; } + '3' : Add := lRGLngStr(43,TRUE); {FString.UserDefEd[Ord(S[Index + 2]) - 48]; } + 'A' : Add := AOnOff((SysOpAvailable), 'available','unavailable' ); + 'C' : Add := FormatNumber(General.CallerNum); + 'D' : Add := IntToStr(General.TotalDloads); + 'L' : Add := IntToStr(SL); + 'M' : Add := IntToStr(General.TotalUsage); + 'N' : Add := General.SysopName; + 'P' : Add := IntToStr(General.TotalPosts); + 'U' : Add := IntToStr(General.TotalUloads); + 'X' : Add := AOnOff((Sex = 'M'),'Male','Female'); + END; + 'T' : CASE UpCase(S[Index + 2]) OF + '1' : Add := FormatNumber(General.TimeAllow[SL]); + 'A' : Add := FormatNumber(TimeBankAdd); + 'B' : Add := FormatNumber(TimeBank); + 'C' : Add := FormatNumber(LoggedOn); + 'D' : Add := FormatNumber(DLToday); + 'G' : Add := GetTagLine; + 'I' : Add := TimeStr; + 'K' : Add := ConvertBytes(DLKToday * 1024,FALSE); + 'L' : Add := CTim(NSL); + 'N' : Add := Liner.NodeTelnetURL; + 'O' : Add := IntToStr(General.TimeAllow[SL] - TLToday); + 'S' : BEGIN + Assign(HistoryFile, General.DataPath+'HISTORY.DAT'); + {$I-} Reset(HistoryFile); {$I+} + IF (IOResult <> 0) THEN + BEGIN + Add := 'Error With HISTORY.DAT, Inform ' + General.SysOpName + '!'; + END + ELSE + BEGIN + Seek(HistoryFile, (FileSize(HistoryFile)-1)); + Read(HistoryFile, HistoryRec); + Add := IntToStr(HistoryRec.Callers); + Close(HistoryFile); + END; + END; + 'T' : Add := FormatNumber(TTimeOn); + 'U' : Add := IntToStr(General.NumUsers); + END; + 'U' : CASE UpCase(S[Index + 2]) OF + 'A' : Add := IntToStr(AgeUser(BirthDate)); + 'B' : Add := ToDate8(PD2Date(BirthDate)); + 'C' : Add := IntToStr(OnToday); + 'F' : Add := FormatNumber(Feedback); + 'K' : Add := FormatNumber(UK); + 'L' : Add := FormatNumber(Uploads); + 'M' : Add := IntToStr(MaxUsers - 1); + 'N' : Add := Caps(Name); + 'U' : Add := IntToStr(UserNum); + END; + 'V' : CASE UpCase(S[Index + 2]) OF + 'R' : Add := General.Version; + END; + 'Z' : CASE UpCase(S[Index + 2]) OF + 'P' : Add := ZipCode; + END; + END; + Temp := Temp + Add; + Inc(Index,2); + END + ELSE + Temp := Temp + S[Index]; + MCI := Temp; +END; + +PROCEDURE BackErase(Len: Byte); +VAR + Counter: Byte; +BEGIN + IF (OkANSI) OR (OkVT100) THEN + SerialOut(^[+'['+IntToStr(Len)+'D'+^[+'[K') + ELSE IF (OkAvatar) THEN + BEGIN + FOR Counter := 1 TO Len DO + Com_Send(^H); + SerialOut(^V^G); + END + ELSE + FOR Counter := 1 TO Len DO + BEGIN + Com_Send(^H); + Com_Send(' '); + Com_Send(^H); + END; + GotoXY((WhereX - Len),WhereY); + ClrEOL; +END; + +FUNCTION DiskKBFree(DrivePath: AStr): LongInt; +VAR + F: TEXT; +{$IFDEF MSDOS} + Regs: Registers; +{$ENDIF} + S, + S1: STRING; + Counter: Integer; + C, + C1, + C2: Comp; +BEGIN + C2 := 0.0; (* RGCMD *) + SwapVectors; + Exec(GetEnv('RGCMD'),' /C DIR '+DrivePath[1]+': > FREE.TXT'); + SwapVectors; + IF (EXIST('FREE.TXT')) THEN + BEGIN + Assign(F,'FREE.TXT'); + Reset(F); + WHILE NOT EOF(F) DO + BEGIN + ReadLn(F,S); + IF (Pos('bytes free',s) <> 0) THEN + BEGIN + WHILE (S[1] = ' ') DO + Delete(S,1,1); + Delete(S,1,Pos(')',s)); + WHILE (S[1] = ' ') DO + Delete(S,1,1); + S := COPY(S,1,Pos(' ',S) - 1); + S1 := ''; + FOR Counter := 1 TO Length(S) DO + IF (S[Counter] <> ',') THEN + S1 := S1 + S[Counter]; + END; + END; + Close(F); + Erase(F); + Val(S1,C2,Counter); + END + ELSE + BEGIN +{$IFDEF MSDOS} + FillChar(Regs,SizeOf(Regs),#0); + Regs.Ah := $36; + Regs.Dl := ExtractDriveNumber(DrivePath); + Intr($21,Regs); + C := (1.0 * Regs.Ax); + C1 := ((1.0 * Regs.Cx) * C); + C2 := ((1.0 * Regs.Bx) * C1); +{$ENDIF} +{$IFDEF WIN32} + C2 := DiskFree(ExtractDriveNumber(DrivePath)); +{$ENDIF} + END; + DiskKBFree := Round(C2 / 1024.0); +END; + +FUNCTION IntToStr(L: LongInt): STRING; +VAR + S: STRING[11]; +BEGIN + Str(L,S); + IntToStr := S; +END; + +PROCEDURE MyDelay(WaitFor: LongInt); +VAR + CheckMS: LongInt; +BEGIN + CheckMS := (Ticks + WaitFor); + REPEAT + UNTIL (Ticks > CheckMS); +END; + +END. diff --git a/SOURCE/COMMON1.PAS b/SOURCE/COMMON1.PAS new file mode 100644 index 0000000..845c220 --- /dev/null +++ b/SOURCE/COMMON1.PAS @@ -0,0 +1,414 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S-,V-} + +UNIT Common1; + +INTERFACE + +FUNCTION CheckPW: Boolean; +PROCEDURE NewCompTables; +PROCEDURE Wait(b: Boolean); +PROCEDURE InitTrapFile; +PROCEDURE Local_Input1(VAR S: STRING; MaxLen: Byte; LowerCase: Boolean); +PROCEDURE Local_Input(VAR S: STRING; MaxLen: Byte); +PROCEDURE Local_InputL(VAR S: STRING; MaxLen: Byte); +PROCEDURE Local_OneK(VAR C: Char; S: STRING); +PROCEDURE SysOpShell; +PROCEDURE ReDrawForANSI; + +IMPLEMENTATION + +USES + Crt, + Common, + File0, + Mail0, + TimeFunc; + +FUNCTION CheckPW: Boolean; +VAR + Password: STR20; +BEGIN + IF (NOT General.SysOpPWord) OR (InWFCMenu) THEN + BEGIN + CheckPW := TRUE; + Exit; + END; + CheckPW := FALSE; + { Prompt(FString.SysOpPrompt); } + lRGLngStr(33,FALSE); + GetPassword(Password,20); + IF (Password = General.SysOpPW) THEN + CheckPW := TRUE + ELSE IF (InCom) AND (Password <> '') THEN + SysOpLog('--> SysOp Password Failure = '+Password+' ***'); +END; + +PROCEDURE NewCompTables; +VAR + FileCompArrayFile: FILE OF CompArrayType; + MsgCompArrayFile: FILE OF CompArrayType; + CompFileArray: CompArrayType; + CompMsgArray: CompArrayType; + Counter, + Counter1, + Counter2, + SaveReadMsgArea, + SaveReadFileArea: Integer; +BEGIN + SaveReadMsgArea := ReadMsgArea; + SaveReadFileArea := ReadFileArea; + Reset(FileAreaFile); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Error opening FBASES.DAT (Procedure: NewCompTables)'); + Exit; + END; + NumFileAreas := FileSize(FileAreaFile); + Assign(FileCompArrayFile,TempDir+'FACT'+IntToStr(ThisNode)+'.DAT'); + ReWrite(FileCompArrayFile); + CompFileArray[0] := 0; + CompFileArray[1] := 0; + FOR Counter := 1 TO FileSize(FileAreaFile) DO + Write(FileCompArrayFile,CompFileArray); + Reset(FileCompArrayFile); + IF (NOT General.CompressBases) THEN + BEGIN + FOR Counter := 1 TO FileSize(FileAreaFile) DO + BEGIN + Seek(FileAreaFile,(Counter - 1)); + Read(FileAreaFile,MemFileArea); + IF (NOT AACS(MemFileArea.ACS)) THEN + BEGIN + CompFileArray[0] := 0; + CompFileArray[1] := 0; + END + ELSE + BEGIN + CompFileArray[0] := Counter; + CompFileArray[1] := Counter; + END; + Seek(FileCompArrayFile,(Counter - 1)); + Write(FileCompArrayFile,CompFileArray); + END; + END + ELSE + BEGIN + Counter2 := 0; + Counter1 := 0; + FOR Counter := 1 TO FileSize(FileAreaFile) DO + BEGIN + Seek(FileAreaFile,(Counter - 1)); + Read(FileAreaFile,MemFileArea); + Inc(Counter1); + IF (NOT AACS(MemFileArea.ACS)) THEN + BEGIN + Dec(Counter1); + CompFileArray[0] := 0; + END + ELSE + BEGIN + CompFileArray[0] := Counter1; + Seek(FileCompArrayFile,(Counter - 1)); + Write(FileCompArrayFile,CompFileArray); + Inc(Counter2); + Seek(FileCompArrayFile,(Counter2 - 1)); + Read(FileCompArrayFile,CompFileArray); + CompFileArray[1] := Counter; + Seek(FileCompArrayFile,(Counter2 - 1)); + Write(FileCompArrayFile,CompFileArray); + END; + END; + END; + Close(FileAreaFile); + LastError := IOResult; + LowFileArea := 0; + Counter1 := 0; + Counter := 1; + WHILE (Counter <= FileSize(FileCompArrayFile)) AND (Counter1 = 0) DO + BEGIN + Seek(FileCompArrayFile,(Counter - 1)); + Read(FileCompArrayFile,CompFileArray); + IF (CompFileArray[0] <> 0) THEN + Counter1 := CompFileArray[0]; + Inc(Counter); + END; + LowFileArea := Counter1; + HighFileArea := 0; + Counter1 := 0; + Counter := 1; + WHILE (Counter <= FileSize(FileCompArrayFile)) DO + BEGIN + Seek(FileCompArrayFile,(Counter - 1)); + Read(FileCompArrayFile,CompFileArray); + IF (CompFileArray[0] <> 0) THEN + Counter1 := CompFileArray[0]; + Inc(Counter); + END; + HighFileArea := Counter1; + Close(FileCompArrayFile); + LastError := IOResult; + Reset(MsgAreaFile); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Error opening MBASES.DAT (Procedure: NewCompTables)'); + Exit; + END; + NumMsgAreas := FileSize(MsgAreaFile); + Assign(MsgCompArrayFile,TempDir+'MACT'+IntToStr(ThisNode)+'.DAT'); + ReWrite(MsgCompArrayFile); + CompMsgArray[0] := 0; + CompMsgArray[1] := 0; + FOR Counter := 1 TO FileSize(MsgAreaFile) DO + Write(MsgCompArrayFile,CompMsgArray); + Reset(MsgCompArrayFile); + IF (NOT General.CompressBases) THEN + BEGIN + FOR Counter := 1 TO FileSize(MsgAreaFile) DO + BEGIN + Seek(MsgAreaFile,(Counter - 1)); + Read(MsgAreaFile,MemMsgArea); + IF (NOT AACS(MemMsgArea.ACS)) THEN + BEGIN + CompMsgArray[0] := 0; + CompMsgArray[1] := 0; + END + ELSE + BEGIN + CompMsgArray[0] := Counter; + CompMsgArray[1] := Counter; + END; + Seek(MsgCompArrayFile,(Counter - 1)); + Write(MsgCompArrayFile,CompMsgArray); + END; + END + ELSE + BEGIN + Counter2 := 0; + Counter1 := 0; + FOR Counter := 1 TO FileSize(MsgAreaFile) DO + BEGIN + Seek(MsgAreaFile,(Counter - 1)); + Read(MsgAreaFile,MemMsgArea); + Inc(Counter1); + IF (NOT AACS(MemMsgArea.ACS)) THEN + BEGIN + Dec(Counter1); + CompMsgArray[0] := 0; + END + ELSE + BEGIN + CompMsgArray[0] := Counter1; + Seek(MsgCompArrayFile,(Counter - 1)); + Write(MsgCompArrayFile,CompMsgArray); + Inc(Counter2); + Seek(MsgCompArrayFile,(Counter2 - 1)); + Read(MsgCompArrayFile,CompMsgArray); + CompMsgArray[1] := Counter; + Seek(MsgCompArrayFile,(Counter2 - 1)); + Write(MsgCompArrayFile,CompMsgArray); + END; + END; + END; + Close(MsgAreaFile); + LastError := IOResult; + LowMsgArea := 0; + Counter1 := 0; + Counter := 1; + WHILE (Counter <= FileSize(MsgCompArrayFile)) AND (Counter1 = 0) DO + BEGIN + Seek(MsgCompArrayFile,(Counter - 1)); + Read(MsgCompArrayFile,CompMsgArray); + IF (CompMsgArray[0] <> 0) THEN + Counter1 := CompMsgArray[0]; + Inc(Counter); + END; + LowMsgArea := Counter1; + HighMsgArea := 0; + Counter1 := 0; + Counter := 1; + WHILE (Counter <= FileSize(MsgCompArrayFile)) DO + BEGIN + Seek(MsgCompArrayFile,(Counter - 1)); + Read(MsgCompArrayFile,CompMsgArray); + IF (CompMsgArray[0] <> 0) THEN + Counter1 := CompMsgArray[0]; + Inc(Counter); + END; + HighMsgArea := Counter1; + Close(MsgCompArrayFile); + LastError := IOResult; + ReadMsgArea := -1; + ReadFileArea := -1; + IF (NOT FileAreaAC(FileArea)) THEN + ChangeFileArea(CompFileArea(1,1)); + IF (NOT MsgAreaAC(MsgArea)) THEN + ChangeMsgArea(CompMsgArea(1,1)); + LoadMsgArea(SaveReadMsgArea); + LoadFileArea(SaveReadFileArea); +END; + +PROCEDURE Wait(b: Boolean); +CONST + SaveCurrentColor: Byte = 0; +BEGIN + IF (B) THEN + BEGIN + SaveCurrentColor := CurrentColor; + { Prompt(FString.lWait); } + lRGLngStr(4,FALSE); + END + ELSE + BEGIN + BackErase(LennMCI(lRGLngStr(4,TRUE){FString.lWait})); + SetC(SaveCurrentColor); + END; +END; + +PROCEDURE InitTrapFile; +BEGIN + Trapping := FALSE; + IF (General.GlobalTrap) OR (TrapActivity IN ThisUser.SFlags) THEN + Trapping := TRUE; + IF (Trapping) THEN + BEGIN + IF (TrapSeparate IN ThisUser.SFlags) THEN + Assign(TrapFile,General.LogsPath+'TRAP'+IntToStr(UserNum)+'.LOG') + ELSE + Assign(TrapFile,General.LogsPath+'TRAP.LOG'); + Append(TrapFile); + IF (IOResult = 2) THEN + BEGIN + ReWrite(TrapFile); + WriteLn(TrapFile); + END; + WriteLn(TrapFile,'***** Renegade User Audit - '+Caps(ThisUser.Name)+' on at '+DateStr+' '+TimeStr+' *****'); + END; +END; + +PROCEDURE Local_Input1(VAR S: STRING; MaxLen: Byte; LowerCase: Boolean); +VAR + C: Char; + B: Byte; +BEGIN + B := 1; + REPEAT + C := ReadKey; + IF (NOT LowerCase) THEN + C := UpCase(C); + IF (C IN [#32..#255]) THEN + IF (B <= MaxLen) THEN + BEGIN + S[B] := C; + Inc(B); + Write(C); + END + ELSE + ELSE + CASE C of + ^H : IF (B > 1) THEN + BEGIN + Write(^H' '^H); + C := ^H; + Dec(B); + END; + ^U,^X : WHILE (B <> 1) DO + BEGIN + Write(^H' '^H); + Dec(B); + END; + END; + UNTIL (C IN [^M,^N]); + S[0] := Chr(B - 1); + IF (WhereY <= Hi(WindMax) - Hi(WindMin)) THEN + WriteLn; +END; + +PROCEDURE Local_Input(VAR S: STRING; MaxLen: Byte); +BEGIN + Local_Input1(S,MaxLen,FALSE); +END; + +PROCEDURE Local_InputL(VAR S: STRING; MaxLen: Byte); +BEGIN + Local_Input1(S,MaxLen,TRUE); +END; + +PROCEDURE Local_OneK(VAR C: Char; S: STRING); +BEGIN + REPEAT + C := UpCase(ReadKey) + UNTIL (Pos(C,S) > 0); + WriteLn(C); +END; + +PROCEDURE SysOpShell; +VAR + SavePath: STRING; + SaveWhereX, + SaveWhereY, + SaveCurCo: Byte; + ReturnCode: Integer; + SaveTimer: LongInt; +BEGIN + SaveCurCo := CurrentColor; + GetDir(0,SavePath); + SaveTimer := Timer; + IF (UserOn) THEN + BEGIN + { Prompt(FString.ShellDOS1); } + lRGLngStr(12,FALSE); + Com_Flush_Send; + Delay(100); + END; + SaveWhereX := WhereX; + SaveWhereY := WhereY; + Window(1,1,80,25); + TextBackGround(Black); + TextColor(LightGray); + ClrScr; + TextColor(LightCyan); + WriteLn('Type "EXIT" to return to Renegade.'); + WriteLn; + TimeLock := TRUE; + ShellDOS(FALSE,'',ReturnCode); + TimeLock := FALSE; + IF (UserOn) THEN + Com_Flush_Recv; + ChDir(SavePath); + TextBackGround(Black); + TextColor(LightGray); + ClrScr; + TextAttr := SaveCurCo; + GoToXY(SaveWhereX,SaveWhereY); + IF (UserOn) THEN + BEGIN + IF (NOT InChat) THEN + FreeTime := ((FreeTime + Timer) - SaveTimer); + Update_Screen; + FOR SaveCurCo := 1 TO LennMCI(lRGLngStr(12,TRUE){FString.ShellDOS1}) DO + BackSpace; + END; +END; + +PROCEDURE ReDrawForANSI; +BEGIN + IF (DOSANSIOn) THEN + BEGIN + DOSANSIOn := FALSE; + Update_Screen; + END; + TextAttr := 7; + CurrentColor := 7; + IF (OutCom) THEN + IF (OKAvatar) THEN + SerialOut(^V^A^G) + ELSE IF (OkANSI) THEN + SerialOut(#27+'[0m'); +END; + +END. + diff --git a/SOURCE/COMMON2.PAS b/SOURCE/COMMON2.PAS new file mode 100644 index 0000000..76f78f6 --- /dev/null +++ b/SOURCE/COMMON2.PAS @@ -0,0 +1,1313 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S-,V-} + +UNIT Common2; + +INTERFACE + +USES + Common, + MyIO; + +PROCEDURE SKey1(VAR C: Char); +PROCEDURE SaveGeneral(x: Boolean); +PROCEDURE TLeft; +PROCEDURE ChangeUserDataWindow; +PROCEDURE lStatus_Screen(WhichScreen: Byte; CONST Message: AStr; OneKey: Boolean; VAR Answer: AStr); +PROCEDURE Update_Screen; +PROCEDURE ToggleWindow(ShowIt: Boolean); + +IMPLEMENTATION + +USES + Crt, + Dos, + TimeFunc, + LineChat, + SysOp2G, + SysOp3, + SplitCha +{$IFDEF WIN32} + ,VPSysLow + ,Windows +{$ENDIF} + ; + +CONST + SYSKEY_LENGTH = 1269; + + SYSKEY: ARRAY [1..1269] OF Char = ( + #3 ,#16,'',#26,'M','','',#24,'',#17,#25,#23,#11,'R','e','n','e', + 'g','a','d','e',' ','B','u','l','l','e','t','i','n',' ','B','o','a', + 'r','d',' ','S','y','s','t','e','m',#25,#23,#3 ,#16,'',#24,'',#26, + '%','','',#26,'&','','',#24,'',' ',#14,'A','L','T','+','B',' ', + #15,':',' ',#7 ,'T','o','g','g','l','e',' ','"','B','e','e','p','-', + 'a','f','t','e','r','-','e','n','d','"',#25,#5 ,#3 ,'',' ',#14,'A', + 'L','T','+','N',' ',#15,':',' ',#7 ,'S','w','i','t','c','h',' ','t', + 'o',' ','n','e','x','t',' ','S','y','s','O','p',' ','w','i','n','d', + 'o','w',#25,#2 ,#3 ,'',#24,'',' ',#14,'A','L','T','+','C',' ',#15, + ':',' ',#7 ,'E','n','t','e','r','/','E','x','i','t',' ','c','h','a', + 't',' ','m','o','d','e',#25,#8 ,#3 ,'',' ',#14,'A','L','T','+','O', + ' ',#15,':',' ',#7 ,'C','o','n','f','e','r','e','n','c','e',' ','S', + 'y','s','t','e','m',' ','t','o','g','g','l','e',#25,#5 ,#3 ,'',#24, + '',' ',#14,'A','L','T','+','D',' ',#15,':',' ',#7 ,'D','u','m','p', + ' ','s','c','r','e','e','n',' ','t','o',' ','f','i','l','e',#25,#9 , + #3 ,'',' ',#14,'A','L','T','+','P',' ',#15,':',' ',#7 ,'P','r','i', + 'n','t',' ','f','i','l','e',' ','t','o',' ','t','h','e',' ','u','s', + 'e','r',#25,#7 ,#3 ,'',#24,'',' ',#14,'A','L','T','+','E',' ',#15, + ':',' ',#7 ,'E','d','i','t',' ','C','u','r','r','e','n','t',' ','U', + 's','e','r',#25,#11,#3 ,'',' ',#14,'A','L','T','+','Q',' ',#15,':', + ' ',#7 ,'T','u','r','n',' ','o','f','f',' ','c','h','a','t',' ','p', + 'a','g','i','n','g',#25,#9 ,#3 ,'',#24,'',' ',#14,'A','L','T','+', + 'F',' ',#15,':',' ',#7 ,'G','e','n','e','r','a','t','e',' ','f','a', + 'k','e',' ','l','i','n','e',' ','n','o','i','s','e',#25,#4 ,#3 ,'', + ' ',#14,'A','L','T','+','R',' ',#15,':',' ',#7 ,'S','h','o','w',' ', + 'c','h','a','t',' ','r','e','q','u','e','s','t',' ','r','e','a','s', + 'o','n',#25,#5 ,#3 ,'',#24,'',' ',#14,'A','L','T','+','G',' ',#15, + ':',' ',#7 ,'T','r','a','p','/','c','h','a','t','-','c','a','p','t', + 'u','r','i','n','g',' ','t','o','g','g','l','e','s',' ',' ',#3 ,'', + ' ',#14,'A','L','T','+','S',' ',#15,':',' ',#7 ,'S','y','s','O','p', + ' ','W','i','n','d','o','w',' ','o','n','/','o','f','f',#25,#10,#3 , + '',#24,'',' ',#14,'A','L','T','+','H',' ',#15,':',' ',#7 ,'H','a', + 'n','g','u','p',' ','u','s','e','r',' ','i','m','m','e','d','i','a', + 't','e','l','y',#25,#5 ,#3 ,'',' ',#14,'A','L','T','+','T',' ',#15, + ':',' ',#7 ,'T','o','p','/','B','o','t','t','o','m',' ','S','y','s', + 'O','p',' ','w','i','n','d','o','w',#25,#6 ,#3 ,'',#24,'',' ',#14, + 'A','L','T','+','I',' ',#15,':',' ',#7 ,'T','o','g','g','l','e',' ', + 'u','s','e','r',' ','i','n','p','u','t',#25,#11,#3 ,'',' ',#14,'A', + 'L','T','+','U',' ',#15,':',' ',#7 ,'T','o','g','g','l','e',' ','u', + 's','e','r',' ','s','c','r','e','e','n',#25,#11,#3 ,'',#24,'',' ', + #14,'A','L','T','+','J',' ',#15,':',' ',#7 ,'J','u','m','p',' ','t', + 'o',' ','t','h','e',' ','O','S',#25,#14,#3 ,'',' ',#14,'A','L','T', + '+','V',' ',#15,':',' ',#7 ,'A','u','t','o','-','v','a','l','i','d', + 'a','t','e',' ','u','s','e','r',#25,#11,#3 ,'',#24,'',' ',#14,'A', + 'L','T','+','K',' ',#15,':',' ',#7 ,'K','i','l','l',' ','u','s','e', + 'r',' ','w','/','H','A','N','G','U','P','#',' ','f','i','l','e',#25, + #4 ,#3 ,'',' ',#14,'A','L','T','+','W',' ',#15,':',' ',#7 ,'E','d', + 'i','t',' ','U','s','e','r',' ','w','i','t','h','o','u','t',' ','n', + 'o','t','i','c','e',#25,#5 ,#3 ,'',#24,'',' ',#14,'A','L','T','+', + 'L',' ',#15,':',' ',#7 ,'T','o','g','g','l','e',' ','l','o','c','a', + 'l',' ','s','c','r','e','e','n',' ','d','i','s','p','l','a','y',' ', + ' ',#3 ,'',' ',#14,'A','L','T','+','Z',' ',#15,':',' ',#7 ,'W','a', + 'k','e',' ','u','p',' ','a',' ','s','l','e','e','p','i','n','g',' ', + 'u','s','e','r',#25,#6 ,#3 ,'',#24,'',' ',#14,'A','L','T','+','M', + ' ',#15,':',' ',#7 ,'M','a','k','e','/','T','a','k','e',' ','T','e', + 'm','p',' ','S','y','s','O','p',' ','A','c','c','e','s','s',' ',' ', + #3 ,'',' ',#14,'A','L','T','-','#',' ',#15,':',' ',#7 ,'E','x','e', + 'c','u','t','e',' ','G','L','O','B','A','T','#','.','B','A','T',#25, + #10,#3 ,'',#24,'',' ',#14,'A','L','T','+','+',' ',#15,':',' ',#7 , + 'G','i','v','e',' ','5',' ','m','i','n','u','t','e','s',' ','t','o', + ' ','u','s','e','r',#25,#6 ,#3 ,'',' ',#14,'A','L','T','+','-',' ', + #15,':',' ',#7 ,'T','a','k','e',' ','5',' ','m','i','n','u','t','e', + 's',' ','f','r','o','m',' ','u','s','e','r',#25,#5 ,#3 ,'',#24,'', + #26,'%','','',#26,'&','','',#24,'',' ',#14,'C','T','R','L','+', + 'H','O','M','E',' ',#15,':',' ',#7 ,'T','h','i','s',' ','h','e','l', + 'p',' ','s','c','r','e','e','n',#25,#10,#14,'C','T','R','L','+','S', + 'Y','S','R','Q',' ',#15,':',' ',#7 ,'F','a','k','e',' ','s','y','s', + 't','e','m',' ','e','r','r','o','r',#25,#7 ,#3 ,'',#24,'',' ',#14, + 'S','C','R','L','C','K',#25,#3 ,#15,':',' ',#7 ,'T','o','g','g','l', + 'e',' ','c','h','a','t',' ','a','v','a','i','l','a','b','i','l','i', + 't','y',#25,#2 ,#14,'A','L','T','+','F','1','-','F','5',' ',' ',#15, + ':',' ',#7 ,'S','y','s','O','p',' ','W','i','n','d','o','w',' ','1', + ' ','-',' ','5',#25,#6 ,#3 ,'',#24,'',#26,'M','','',#24,#24,#24, + #24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24, + #24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24); + + WIN1_LENGTH = 51; + + WIN1: ARRAY [1..51] OF Char = ( + #15,#23,#25,#27,'A','R',':',#25,#27,'N','S','L',':',#25,#4 ,'T','i', + 'm','e',':',#25,#6 ,#24,#25,#27,'A','C',':',#25,#15,'B','a','u','d', + ':',#25,#6 ,'D','S','L',':',#25,#4 ,'N','o','d','e',':',#25,#6 ,#24); + + WIN2_LENGTH = 42; + + WIN2: ARRAY [1..42] OF Char = ( + #15,#23,#25,#27,'P','H',':',#25,#18,'F','O',':',#25,#10,'T','e','r', + 'm',':',#25,#10,#24,#25,#27,'B','D',':',#25,#18,'L','O',':',#25,#10, + 'E','d','i','t',':',#25,#10,#24); + + WIN3_LENGTH = 80; + + WIN3: ARRAY [1..80] OF Char = ( + #15,#23,' ','T','C',':',#25, #6,'C','T',':',#25, #6,'P','P',':',#25, + #6,'F','S',':',#25, #6,'D','L',':',#25,#14,'F','R',':',#25, #5,'T', + 'i','m','e',':',#25, #6,#24,' ','T','T',':',#25, #6,'B','L',':',#25, + #6,'E','S',':',#25, #6,'T','B',':',#25, #6,'U','L',':',#25,#14,'P', + 'R',':',#25, #5,'N','o','d','e',':',#25, #6,#24); + + WIN4_LENGTH = 96; + + WIN4: ARRAY [1..96] OF Char = ( + #8 ,#23,' ',#15,'T','o','d','a','y',#39,'s',' ',#8 ,'',' ',' ',#15, + 'C','a','l','l','s',':',#25,#7 ,'E','m','a','i','l',':',#25,#7 ,'D', + 'L',':',#25,#17,'N','e','w','u','s','e','r','s',':',#25,#9 ,#24,#25, + #2 ,'S','t','a','t','s',' ',#8 ,'',' ',' ',#15,'P','o','s','t','s', + ':',#25,#7 ,'F','e','e','d','b',':',#25,#7 ,'U','L',':',#25,#17,'A', + 'c','t','i','v','i','t','y',':',#25,#9 ,#24); + + WIN5_LENGTH = 113; + + WIN5: ARRAY [1..113] OF Char = ( + #8 ,#23,' ',#15,'S','y','s','t','e','m',' ',' ',#8 ,'',' ',' ',#15, + 'C','a','l','l','s',':',#25,#7 ,'D','L',':',#25,#7 ,'D','a','y','s', + ' ',':',#25,#6 ,'U','s','e','r','s',':',#25,#6 ,'D','i','s','k','f', + 'r','e','e',':',#25,#7 ,#24,' ',' ','S','t','a','t','s',' ',' ',#8 , + '',' ',' ',#15,'P','o','s','t','s',':',#25,#7 ,'U','L',':',#25,#7 , + 'H','o','u','r','s',':',#25,#6 ,'M','a','i','l',' ',':',#25,#6 ,'O', + 'v','e','r','l','a','y','s',':',#25,#7 ,#24); + +{$IFDEF MSDOS} +PROCEDURE BiosScroll(up: Boolean); ASSEMBLER; +ASM + Mov cx,0 + Mov dh,MaxDisplayRows + Mov dl,MaxDisplayCols + Mov bh,7 + Mov al,2 + Cmp up,1 + Je @Up + Mov ah,7 + Jmp @go + @up: + Mov ah,6 + @Go: + Int 10h +END; +{$ENDIF} +{$IFDEF WIN32} +PROCEDURE BiosScroll(up: Boolean); +BEGIN + if (up) then + begin + SysScrollUp(0, 0, MaxDisplayCols-1, MaxDisplayRows-1, 2, 7); + end else + begin + SysScrollDn(0, 0, MaxDisplayCols-1, MaxDisplayRows-1, 2, 7); + end; +END; +{$ENDIF} + +PROCEDURE CPR(c1,c2: Byte); +VAR + Flag: FlagType; +BEGIN + FOR Flag := RLogon TO RMsg DO + BEGIN + IF (Flag IN ThisUser.Flags) THEN + TextAttr := c1 + ELSE + TextAttr := c2; + Write(Copy('LCVUA*PEKM',(Ord(Flag) + 1),1)); + END; + FOR Flag := FNoDLRatio TO FNoDeletion DO + BEGIN + IF (Flag IN ThisUser.Flags) THEN + TextAttr := c1 + ELSE + TextAttr := c2; + Write(Copy('1234',(Ord(Flag) - 19),1)); + END; +END; + +PROCEDURE Clear_Status_Box; +BEGIN + IF (General.IsTopWindow) THEN + Window(1,1,MaxDisplayCols,2) + ELSE + Window(1,(MaxDisplayRows - 1),MaxDisplayCols,MaxDisplayRows); + ClrScr; + Window(1,1,MaxDisplayCols,MaxDisplayRows); +END; + +PROCEDURE ToggleWindow(ShowIt: Boolean); +VAR + SaveWhereX, + SaveWhereY, + SaveTextAttr: Byte; +BEGIN + SaveWhereX := WhereX; + SaveWhereY := WhereY; + SaveTextattr := TextAttr; + TextAttr := 7; + IF (General.WindowOn) THEN + BEGIN + Clear_Status_Box; + IF (General.IsTopWindow) THEN + BEGIN + GoToXY(1, MaxDisplayRows); + Write(^J^J); + END; + END + ELSE + BEGIN + IF (General.IsTopWindow AND (SaveWhereY <= (MaxDisplayRows - 2))) THEN + BiosScroll(FALSE) + ELSE IF (NOT General.IsTopWindow AND (SaveWhereY > (MaxDisplayRows - 2))) THEN + BEGIN + BiosScroll(TRUE); + Dec(SaveWhereY,2) + END + ELSE IF (General.IsTopWindow) THEN + Dec(SaveWhereY,2); + END; + General.WindowOn := NOT General.WindowOn; + IF (ShowIt) THEN + Update_Screen; + GoToXY(SaveWhereX,SaveWhereY); + TextAttr := SaveTextAttr; +END; + +PROCEDURE lStatus_Screen(WhichScreen: Byte; CONST Message: AStr; OneKey: Boolean; VAR Answer: AStr); +VAR + HistoryFile: FILE OF HistoryRecordType; + History: HistoryRecordType; + User: UserRecordType; + C: Char; + FirstRow, + SecondRow, + SaveWhereX, + SaveWhereY, + SaveTextAttr: Byte; + SaveWindowOn: Boolean; +BEGIN + IF ((InWFCMenu OR (NOT General.WindowOn)) AND (WhichScreen < 99)) OR + (General.NetworkMode AND NOT CoSysOp) THEN + Exit; + SaveWindowOn := General.WindowOn; + IF (NOT General.WindowOn) THEN + ToggleWindow(FALSE); + TLeft; + SaveWhereX := WhereX; + SaveWhereY := WhereY; + SaveTextAttr := TextAttr; + Window(1,1,MaxDisplayCols,MaxDisplayRows); + IF (General.IsTopWindow) THEN + FirstRow := 1 + ELSE + FirstRow := (MaxDisplayRows - 1); + SecondRow := (FirstRow + 1); + TextAttr := 120; + LastScreenSwap := 0; + CursorOn(FALSE); + Clear_Status_Box; + IF (WhichScreen < 99) THEN + General.CurWindow := WhichScreen; + CASE WhichScreen OF + 1 : WITH ThisUser DO + BEGIN +{$IFDEF MSDOS} + Update_Logo(Win1,ScreenAddr[(FirstRow - 1) * 160],WIN1_LENGTH); +{$ENDIF} +{$IFDEF WIN32} + Update_Logo(Win1, 1, FirstRow, WIN1_LENGTH); +{$ENDIF} + GoToXY(02,FirstRow); + Write(Caps(Name)); + GoToXY(33,FirstRow); + FOR C := 'A' TO 'Z' DO + BEGIN + IF (C IN AR) THEN + TextAttr := 116 + ELSE + TextAttr := 120; + Write(C); + END; + TextAttr := 120; + GoToXY(65,FirstRow); + IF (TempSysOp) THEN + BEGIN + TextAttr := 244; + Write(255); + TextAttr := 120; + END + ELSE + Write(SL); + GoToXY(75,FirstRow); + Write(NSL DIV 60); + GoToXY(02,SecondRow); + Write(RealName+' #'+IntToStr(UserNum)); + GoToXY(33,SecondRow); + CPR(116,120); + TextAttr := 120; + GoToXY(54,SecondRow); + Write(ActualSpeed); + GoToXY(65,SecondRow); + IF (TempSysOp) THEN + BEGIN + TextAttr := 244; + Write(255); + TextAttr := 120; + END + ELSE + Write(DSL); + GoToXY(75,SecondRow); + Write(ThisNode); + END; + 2 : WITH ThisUser DO + BEGIN +{$IFDEF MSDOS} + Update_Logo(Win2,ScreenAddr[(FirstRow - 1) * 160],WIN2_LENGTH); +{$ENDIF} +{$IFDEF WIN32} + Update_Logo(Win2, 1, FirstRow, WIN2_LENGTH); +{$ENDIF} + GoToXY(02,FirstRow); + Write(Street); + GoToXY(33,FirstRow); + Write(Ph); + GoToXY(55,FirstRow); + Write(ToDate8(PD2Date(Firston))); + GoToXY(71,FirstRow); + IF (OKRIP) THEN + Write('RIP') + ELSE IF (OKAvatar) THEN + Write('AVATAR') + ELSE IF (OkANSI) THEN + Write('ANSI') + ELSE IF (OkVT100) THEN + Write('VT-100') + ELSE + Write('NONE'); + GoToXY(02,SecondRow); + Write(PadLeftStr(Citystate+' '+Zipcode,26)); + GoToXY(33,SecondRow); + Write(ToDate8(PD2Date(BirthDate)),', '); + Write(Sex+' ',AgeUser(ThisUser.BirthDate)); + GoToXY(55,SecondRow); + Write(ToDate8(PD2Date(Laston))); + GoToXY(71,SecondRow); + IF (FSEditor IN SFlags) THEN + Write('FullScrn') + ELSE + Write('Regular'); + END; + 3 : WITH ThisUser DO + BEGIN +{$IFDEF MSDOS} + Update_Logo(Win3,ScreenAddr[(FirstRow - 1) * 160],WIN3_LENGTH); +{$ENDIF} +{$IFDEF WIN32} + Update_Logo(Win3, 1, FirstRow, WIN3_LENGTH); +{$ENDIF} + GoToXY(06,FirstRow); + Write(Loggedon); + GoToXY(16,FirstRow); + Write(OnToday); + GoToXY(26,FirstRow); + Write(MsgPost); + GoToXY(36,FirstRow); + Write(Feedback); + GoToXY(46,FirstRow); + Write(IntToStr(Downloads)+'/'+ConvertKB(DK,FALSE)); + GoToXY(64,FirstRow); + IF (Downloads > 0) THEN + Write((Uploads / Downloads) * 100:3:0,'%') + ELSE + Write(0); + GoToXY(75,FirstRow); + Write(NSL DIV 60); + GoToXY(06,SecondRow); + Write(TTimeon); + GoToXY(16,SecondRow); + Write(ThisUser.lCredit - ThisUser.Debit); + GoToXY(26,SecondRow); + Write(EmailSent); + GoToXY(36,SecondRow); + Write(TimeBank); + GoToXY(46,SecondRow); + Write(IntToStr(Uploads)+'/'+ConvertKB(UK,FALSE)); + GoToXY(64,SecondRow); + IF (Loggedon > 0) THEN + Write((Msgpost / Loggedon) * 100:3:0,'%') + ELSE + Write(0); + GoToXY(75,SecondRow); + Write(ThisNode); + END; + 4 : BEGIN + Assign(HistoryFile,General.DataPath+'HISTORY.DAT'); + Reset(HistoryFile); + IF (IOResult = 2) THEN + ReWrite(HistoryFile) + ELSE + BEGIN + Seek(HistoryFile,FileSize(HistoryFile) - 1); + Read(HistoryFile,History); + END; + Close(HistoryFile); + WITH History DO + BEGIN +{$IFDEF MSDOS} + Update_Logo(Win4,ScreenAddr[(FirstRow - 1) * 160],WIN4_LENGTH); +{$ENDIF} +{$IFDEF WIN32} + Update_Logo(Win4, 1, FirstRow, WIN4_LENGTH); +{$ENDIF} + GoToXY(20,FirstRow); + Write(Callers); + GoToXY(34,FirstRow); + Write(Email); + GoToXY(45,FirstRow); + Write(IntToStr(Downloads)+'/'+ConvertKB(DK,FALSE)); + GoToXY(72,FirstRow); + Write(NewUsers); + GoToXY(20,SecondRow); + Write(Posts); + GoToXY(34,SecondRow); + Write(Feedback); + GoToXY(45,SecondRow); + Write(IntToStr(Uploads)+'/'+ConvertKB(UK,FALSE)); + IF (Active > 9999) THEN + Active := 9999; + GoToXY(72,SecondRow); + Write(Active,' min'); + END; + END; + 5 : WITH History DO + BEGIN +{$IFDEF MSDOS} + Update_Logo(Win5,ScreenAddr[(FirstRow - 1) * 160],WIN5_LENGTH); +{$ENDIF} +{$IFDEF WIN32} + Update_Logo(Win5, 1, FirstRow, WIN5_LENGTH); +{$ENDIF} + GoToXY(20,FirstRow); + Write(General.CallerNum); + GoToXY(31,FirstRow); + Write(General.TotalDloads + Downloads); + GoToXY(45,FirstRow); + Write(General.DaysOnline + 1); + GoToXY(58,FirstRow); + Write(General.NumUsers); + GoToXY(74,FirstRow); + Write(ConvertKB(DiskKbFree(StartDir),FALSE)); + GoToXY(20,SecondRow); + Write(General.TotalPosts + Posts); + GoToXY(31,SecondRow); + Write(General.TotalUloads + Uploads); + GoToXY(45,SecondRow); + Write((General.TotalUsage + Active) DIV 60); + LoadURec(User,1); + GoToXY(58,SecondRow); + IF (User.Waiting > 0) THEN + TextAttr := 244; + Write(User.Waiting); + TextAttr := 120; + GoToXY(74,SecondRow); + CASE OverlayLocation OF + 0 : Write('Disk'); + 1 : Write('EMS'); + 2 : Write('XMS'); + END; + END; + 100 : + BEGIN + GoToXY((MaxDisplayCols - Length(Message)) DIV 2,FirstRow); + Write(Message); + LastScreenSwap := Timer; + END; + 99 : + BEGIN + GoToXY(1,FirstRow); + Write(Message); + IF (OneKey) THEN + Answer := UpCase(ReadKey) + ELSE + BEGIN + GoToXY(2,(FirstRow + 1)); + Write('> '); + Local_Input1(Answer,MaxDisplayCols - 4,FALSE); + END; + END; + END; + IF (General.IsTopWindow) THEN + Window(1,3,MaxDisplayCols,MaxDisplayRows) + ELSE + Window(1,1,MaxDisplayCols,MaxDisplayRows - 2); + CursorOn(TRUE); + IF (NOT SaveWindowOn) THEN + ToggleWindow(FALSE); + GoToXY(SaveWhereX,SaveWhereY); + TextAttr := SaveTextAttr; +END; + +PROCEDURE Update_Screen; +VAR + Answer: AStr; +BEGIN + lStatus_Screen(General.CurWindow,'',FALSE,Answer); +END; + +PROCEDURE SKey1(VAR C: Char); +VAR + S: AStr; + C1: Char; + SaveWhereX, + SaveWhereY, + SaveTextAttr: Byte; + RetCode, + i: Integer; + SaveTimer: LongInt; + SaveInChat: Boolean; +BEGIN + IF (General.NetworkMode AND (NOT CoSysOp OR InWFCMenu)) THEN + Exit; + SaveWhereX := WhereX; + SaveWhereY := WhereY; + SaveTextAttr := TextAttr; + CASE Ord(C) OF + 120..129 : + BEGIN {ALT-1 TO ALT-0} + GetDir(0,S); + ChDir(StartDir); + SaveScreen(Wind); + ClrScr; + SaveTimer := Timer; + i := (Ord(C) - 119); + IF (i = 10) THEN + i := 0; + ShellDOS(FALSE,'GLOBAT'+Chr(i + 48),RetCode); + Com_Flush_Recv; + FreeTime := ((FreeTime + Timer) - SaveTimer); + RemoveWindow(Wind); + GoToXY(SaveWhereX,SaveWhereY); + ChDir(S); + END; + 104..108 : + lStatus_Screen(((Ord(C) - 104) + 1),'',FALSE,S); { ALT F1-F5 } + 114 : RunError(255); { CTRL-PRTSC } + 36 : BEGIN + SaveScreen(Wind); + SysOpShell; { ALT-J } + RemoveWindow(Wind); + END; + 32 : BEGIN { ALT-D } + lStatus_Screen(99,'Dump screen to what file: ',FALSE,S); + IF (S <> '') THEN + ScreenDump(S); + Update_Screen; + END; + 59..68 : + Buf := General.Macro[Ord(C) - 59]; { F1 - F10 } + END; + IF (NOT InWFCMenu) THEN + BEGIN + CASE Ord(C) OF + 119 : BEGIN { CTRL-HOME } + SaveScreen(Wind); +{$IFDEF MSDOS} + Update_Logo(SYSKEY,ScreenAddr[0],SYSKEY_LENGTH); +{$ENDIF} +{$IFDEF WIN32} + Update_Logo(SYSKEY, 1, 1, SYSKEY_LENGTH); +{$ENDIF} + CursorOn(FALSE); + C := ReadKey; + IF (C = #0) THEN + C := ReadKey; + CursorOn(TRUE); + RemoveWindow(Wind); + GoToXY(SaveWhereX,SaveWhereY); + Update_Screen; + END; + 34 : BEGIN { ALT-G } + lStatus_Screen(99,'Log options - [T]rap activity [C]hat buffering',TRUE,S); + C1 := S[1]; + WITH ThisUser DO + CASE C1 OF + 'C' : BEGIN + lStatus_Screen(99,'Auto Chat buffering - [O]ff [S]eparate [M]ain (Chat.LOG)',TRUE,S); + C1 := S[1]; + IF (C1 IN ['O','S','M']) THEN + ChatFileLog(FALSE); + CASE C1 OF + 'O' : BEGIN + Exclude(ThisUser.SFlags,ChatAuto); + Exclude(ThisUser.SFlags,ChatSeparate); + END; + 'S' : BEGIN + Include(ThisUser.SFlags,ChatAuto); + Include(ThisUser.SFlags,ChatSeparate); + END; + 'M' : BEGIN + Include(ThisUser.SFlags,ChatAuto); + Exclude(ThisUser.SFlags,ChatSeparate); + END; + END; + IF (C1 IN ['S','M']) THEN + ChatFileLog(TRUE); + END; + 'T' : BEGIN + lStatus_Screen(99,'Activity Trapping - [O]ff [S]eperate [M]ain (TRAP.LOG)',TRUE,S); + C1 := S[1]; + IF (C1 IN ['O','S','M']) THEN + IF (Trapping) THEN + BEGIN + Close(TrapFile); + Trapping := FALSE; + END; + CASE C1 OF + 'O' : BEGIN + Exclude(ThisUser.SFlags,TrapActivity); + Exclude(ThisUser.SFlags,TrapSeparate); + END; + 'S' : BEGIN + Include(ThisUser.SFlags,TrapActivity); + Include(ThisUser.SFlags,TrapSeparate); + END; + 'M' : BEGIN + Include(ThisUser.SFlags,TrapActivity); + Exclude(ThisUser.SFlags,TrapSeparate); + END; + END; + IF (C1 IN ['S','M']) THEN + InitTrapFile; + END; + END; + Update_Screen; + END; + 20 : BEGIN { ALT-T } + IF (General.WindowOn) THEN + BiosScroll(General.IsTopWindow); + General.IsTopWindow := NOT General.IsTopWindow; + Update_Screen; + END; + 31 : IF (NOT InChat) THEN { ALT-S } { ALT-A } + SysOpSplitChat + ELSE + BEGIN + InChat := FALSE; + ChatReason := ''; + END; + + 47 : IF (UserOn) THEN + BEGIN { ALT-V } + S[1] := #0; + lStatus_Screen(99,'Enter the validation level (!-~) for this user.',TRUE,S); + IF (S[1] IN ['!'..'~']) THEN + BEGIN + AutoValidate(ThisUser,UserNum,S[1]); + lStatus_Screen(100,'This user has been validated.',FALSE,S); + END + ELSE + Update_Screen; + END; + 18 : IF (UserOn) THEN + BEGIN { ALT-E } + Wait(TRUE); + SaveScreen(Wind); + ChangeUserDataWindow; + RemoveWindow(Wind); + Update_Screen; + Wait(FALSE); + END; + 17 : IF (UserOn) THEN + BEGIN + SaveScreen(Wind); + ChangeUserDataWindow; { ALT-W } + RemoveWindow(Wind); + Update_Screen; + END; + 49 : IF (UserOn) THEN { ALT-N } + BEGIN + i := ((General.CurWindow MOD 5) + 1); + lStatus_Screen(i,'',FALSE,S); + END; + 23 : IF (ComPortSpeed > 0) AND (NOT Com_Carrier) THEN { ALT-I } + lStatus_Screen(100,'No carrier detected!',FALSE,S) + ELSE IF (ComPortSpeed > 0) THEN + BEGIN + IF (OutCom) THEN + IF (InCom) THEN + InCom := FALSE + ELSE IF (Com_Carrier) THEN + InCom := TRUE; + IF (InCom) THEN + lStatus_Screen(100,'User keyboard ON.',FALSE,S) + ELSE + lStatus_Screen(100,'User keyboard OFF.',FALSE,S); + Com_Flush_Recv; + END; + 16 : BEGIN { ALT-Q } + ChatCall := FALSE; + ChatReason := ''; + Exclude(ThisUser.Flags,Alert); + Update_Screen; + END; + 35 : HangUp := TRUE; { ALT-H } + 24 : BEGIN { ALT-O } + ConfSystem := (NOT ConfSystem); + IF (ConfSystem) THEN + lStatus_Screen(100,'The conference system has been turned ON.',FALSE,S) + ELSE + lStatus_Screen(100,'The conference system has been turned OFF.',FALSE,S); + NewCompTables; + END; + 130 : BEGIN { ALT-MINUS } + SaveInChat := InChat; + InChat := TRUE; + Dec(ThisUser.TLToday,5); + TLeft; + InChat := SaveInChat; + END; + 131 : BEGIN { ALT-PLUS } + SaveInChat := InChat; + InChat := TRUE; + Inc(ThisUser.TLToday,5); + TimeWarn := FALSE; + TLeft; + InChat := SaveInChat; + END; + 50 : IF (UserOn) THEN { ALT-M } + BEGIN + TempSysOp := NOT TempSysOp; + IF (TempSysOp) THEN + lStatus_Screen(100,'Temporary SysOp access granted.',FALSE,S) + ELSE + lStatus_Screen(100,'Normal access restored',FALSE,S); + NewCompTables; + END; + + 30 : ToggleWindow(TRUE); { ALT-A } + + 46 : IF (NOT InChat) THEN { ALT-C } + SysOpLineChat + ELSE + BEGIN + InChat := FALSE; + ChatReason := ''; + END; + + 72, { Arrow up } + 75, { Arrow left } + 77, { Arrow Right } + 80 : IF ((InChat) OR (Write_Msg)) THEN { Arrow Down } + BEGIN + IF (OKAvatar) THEN + Buf := Buf + ^V + ELSE + Buf := Buf + ^[+'['; + CASE Ord(C) OF + 72 : IF (OKAvatar) THEN + Buf := Buf + ^C + ELSE + Buf := Buf + 'A'; + 75 : IF (OKAvatar) THEN + Buf := Buf + ^E + ELSE + Buf := Buf + 'D'; + 77 : IF (OKAvatar) THEN + Buf := Buf + ^F + ELSE + Buf := Buf + 'C'; + 80 : IF (OKAvatar) THEN + Buf := Buf + ^D + ELSE + Buf := Buf + 'B'; + END; + END; + 22 : IF (ComPortSpeed > 0) AND (OutCom) THEN { ALT-U } + BEGIN + lStatus_Screen(100,'User screen and keyboard OFF',FALSE,S); + OutCom := FALSE; + InCom := FALSE; + END + ELSE IF (ComPortSpeed > 0) AND (Com_Carrier) THEN + BEGIN + lStatus_Screen(100,'User screen and keyboard ON',FALSE,S); + OutCom := TRUE; + InCom := TRUE; + END; + 37 : BEGIN { ALT-K } + lStatus_Screen(99,'Display what HangUp file (HANGUPxx) :',FALSE,S); + IF (S <> '') THEN + BEGIN + NL; + NL; + InCom := FALSE; + PrintF('HangUp'+S); + SysOpLog('Displayed HangUp file HangUp'+S); + HangUp := TRUE; + END; + Update_Screen; + END; + 48 : BEGIN { ALT-B } + BeepEnd := NOT BeepEnd; + lStatus_Screen(100,'SysOp next '+ShowOnOff(BeepEnd),FALSE,S); + SaveInChat := InChat; + InChat := TRUE; + TLeft; + InChat := SaveInChat; + END; + 38 : IF (WantOut) THEN { ALT-L } + BEGIN + TextColor(11); + TextBackGround(0); + Window(1,1,MaxDisplayCols,MaxDisplayRows); + ClrScr; + WantOut := FALSE; + CursorOn(FALSE); + END + ELSE + BEGIN + WantOut := TRUE; + CursorOn(TRUE); + WriteLn('Local display on.'); + Update_Screen; + END; + 44 : BEGIN { ALT-Z } + lStatus_Screen(100,'Waking up user ...',FALSE,S); + REPEAT + OutKey(^G); + Delay(500); +{$IFDEF MSDOS} + ASM + Int 28h + END; +{$ENDIF} +{$IFDEF WIN32} + Sleep(1); +{$ENDIF} + CheckHangUp; + UNTIL ((NOT Empty) OR (HangUp)); + Update_Screen; + END; + 19 : lStatus_Screen(100,'Chat request: '+ChatReason,FALSE,S);{ ALT-R } + 25 : BEGIN { ALT-P } + lStatus_Screen(99,'Print what file: ',FALSE,S); + IF (S <> '') THEN + BEGIN + NL; + NL; + PrintF(S); + SysOpLog('Displayed file '+S); + END; + Update_Screen; + END; + 33 : BEGIN { ALT-F } + Randomize; + S := ''; + FOR i := 1 TO Random(50) DO + BEGIN + C1 := Chr(Random(255)); + IF NOT (C1 IN [#3,'^','@']) THEN + S := S + C1; + END; + Prompt(S); + END; + END; + END; + { any processed keys no longer used should be here } + IF (Ord(C) IN [16..20,22..25,30,32..38,44,47..50,104..108,114,119..131]) THEN + C := #0; + TextAttr := SaveTextAttr; +END; + +PROCEDURE SaveGeneral(x: Boolean); +VAR + GeneralF: FILE OF GeneralRecordType; + SaveCurWindow: Byte; + SaveWindowOn, + SaveIsTopWindow: Boolean; +BEGIN + Assign(GeneralF,DatFilePath+'RENEGADE.DAT'); + Reset(GeneralF); + IF (x) THEN + BEGIN + SaveWindowOn := General.WindowOn; + SaveIsTopWindow := General.IsTopWindow; + SaveCurWindow := General.CurWindow; + Read(GeneralF,General); + General.WindowOn := SaveWindowOn; + General.IsTopWindow := SaveIsTopWindow; + General.CurWindow := SaveCurWindow; + Inc(General.CallerNum,TodayCallers); + TodayCallers := 0; + Inc(General.NumUsers,lTodayNumUsers); + lTodayNumUsers := 0; + Seek(GeneralF,0); + END; + Write(GeneralF,General); + Close(GeneralF); + LastError := IOResult; +END; + +PROCEDURE TLeft; +VAR + SaveWhereX, + SaveWhereY, + SaveCurrentColor: Integer; +BEGIN + IF (TimedOut) OR (TimeLock) THEN + Exit; + SaveCurrentColor := CurrentColor; + IF ((NSL <= 0) AND (ChopTime <> 0)) THEN + BEGIN + SysOpLog('Logged user off for system event'); + NL; + NL; + Print('^G^7Shutting down for System Event.'^G); + NL; + HangUp := TRUE; + END; + IF (NOT InChat) AND NOT (FNoCredits IN ThisUser.Flags) AND (General.CreditMinute > 0) AND (UserOn) AND (CreditTime > 0) AND + (AccountBalance > ((NSL DIV 60) + 1) * General.CreditMinute) AND (NOT HangUp) THEN + BEGIN + CreditTime := 0; + IF (AccountBalance < ((NSL DIV 60) + 1) * General.CreditMinute) THEN + Inc(CreditTime, NSL - (AccountBalance DIV General.CreditMinute) * 60); + END; + IF (NOT InChat) AND NOT (FNoCredits IN ThisUser.Flags) AND (General.CreditMinute > 0) AND (UserOn) AND + (AccountBalance < (NSL DIV 60) * General.CreditMinute) AND + (NOT InVisEdit) AND (NOT HangUp) THEN + BEGIN + Print(^M^J^G^G'^8Note: ^9Your online time has been adjusted due to insufficient account balance.'); + Inc(CreditTime, NSL - (AccountBalance DIV General.CreditMinute) * 60); + END; + IF (NOT TimeWarn) AND (NOT InChat) AND (NSL < 180) AND (UserOn) AND (NOT InVisEdit) AND (NOT HangUp) THEN + BEGIN + Print(^M^J^G^G'^8Warning: ^9You have less than '+IntToStr(NSL DIV 60 + 1)+' '+ + Plural('minute',NSL DIV 60 + 1)+' remaining online!'^M^J); + SetC(SaveCurrentColor); + TimeWarn := TRUE; + END; + IF (NOT InChat) AND (NSL <= 0) AND (UserOn) AND (NOT HangUp) THEN + BEGIN + NL; + TimedOut := TRUE; + PrintF('NOTLEFT'); + IF (NoFile) THEN + Print('^7You have used up all of your time.'); + NL; + HangUp := TRUE; + END; + CheckHangUp; + IF (WantOut) AND (General.WindowOn) AND (General.CurWindow = 1) AND (NOT InWFCMenu) AND NOT + (General.NetworkMode AND NOT CoSysOp) AND (LastScreenSwap = 0) THEN + BEGIN + TextAttr := 120; + SaveWhereX := WhereX; + SaveWhereY := WhereY; + Window(1,1,MaxDisplayCols,MaxDisplayRows); + IF (General.IsTopWindow) THEN + GoToXY(75, 1) + ELSE + GoToXY(75,(MaxDisplayRows - 1)); + Write(NSL DIV 60,' '); + IF (General.IsTopWindow) THEN + Window(1,3,MaxDisplayCols,MaxDisplayRows) + ELSE + Window(1,1,MaxDisplayCols,(MaxDisplayRows - 2)); + GoToXY(SaveWhereX,SaveWhereY); + TextAttr := SaveCurrentColor; + END; +END; + +PROCEDURE gp(i,j: Integer); +VAR + x: Byte; +BEGIN + CASE j OF + 0 : GoToXY(58,8); + 1 : GoToXY(20,7); + 2 : GoToXY(20,8); + 3 : GoToXY(20,9); + 4 : GoToXY(20,10); + 5 : GoToXY(36,7); + 6 : GoToXY(36,8); + END; + IF (j IN [1..4]) THEN + x := 5 + ELSE + x := 3; + IF (i = 2) THEN + Inc(x); + IF (i > 0) THEN + GoToXY((WhereX + x),WhereY); +END; + +PROCEDURE ChangeUserDataWindow; +VAR + S: STRING[39]; + C: Char; + SaveWhereX, + SaveWhereY, + SaveTextAttr: Byte; + oo, + i: Integer; + Changed, + Done, + Done1: Boolean; + + PROCEDURE Shd(i: Integer; b: Boolean); + VAR + C1: Char; + Counter: Byte; + BEGIN + gp(0,i); + IF (b) THEN + TextColor(14) + ELSE + TextColor(9); + CASE i OF + 1 : Write('SL :'); + 2 : Write('DSL :'); + 3 : Write('BL :'); + 4 : Write('Note:'); + 5 : Write('AR:'); + 6 : Write('AC:'); + END; + IF (b) THEN + BEGIN + TextColor(0); + TextBackGround(7); + END + ELSE + TextColor(14); + Write(' '); + WITH ThisUser DO + CASE i OF + 0 : IF (b) THEN + Write('Done') + ELSE + BEGIN + TextColor(9); + Write(''); + TextColor(11); + Write('Done'); + TextColor(9); + Write(''); + END; + 1 : Write(PadLeftInt(SL,3)); + 2 : Write(PadLeftInt(DSL,3)); + 3 : Write(PadLeftInt(AccountBalance,5)); + 4 : Write(PadLeftStr(Note,39)); + 5 : FOR C1 := 'A' TO 'Z' DO + BEGIN + IF (C1 IN AR) THEN + TextColor(4) + ELSE IF (b) THEN + TextColor(0) + ELSE + TextColor(7); + Write(C1); + END; + 6 : IF (b) THEN + CPR($07,$70) + ELSE + CPR($70,$07); + END; + Write(' '); + TextBackGround(0); + CursorOn(i IN [1..4]); + IF (b) THEN + BEGIN + GoToXY(26,12); + TextColor(14); + FOR Counter := 1 TO 41 DO + Write(' '); + GoToXY(26,12); + CASE i OF + 0 : Write('Done'); + 1 : Write('Security Level (0-255)'); + 2 : Write('Download Security Level (0-255)'); + 3 : Write('Account balance'); + 4 : Write('SysOp Note for this user'); + 5 : Write('Access flags ("!" to toggle all)'); + 6 : Write('Restrictions & special ("!" to clear)'); + END; + END; + END; + + PROCEDURE ddwind; + VAR + Counter: Byte; + BEGIN + CursorOn(FALSE); + TextColor(9); + Box(1,18,6,68,13); + Window(19,7,67,12); + ClrScr; + Box(1,18,6,68,11); + Window(19,7,67,10); + Window(1,1,MaxDisplayCols,MaxDisplayRows); + GoToXY(20,12); + TextColor(9); + Write('Desc:'); + FOR Counter := 0 TO 6 DO + Shd(Counter,FALSE); + Shd(oo,TRUE); + END; + +BEGIN + SaveURec(ThisUser,UserNum); + Infield_Out_Fgrd := 0; + Infield_Out_Bkgd := 7; + InField_Inp_Fgrd := 0; + InField_Inp_Bkgd := 7; + Infield_Arrow_Exit := TRUE; + Infield_Arrow_Exited := FALSE; + SaveWhereX := WhereX; + SaveWhereY := WhereY; + SaveTextAttr := TextAttr; + TextAttr := 7; + oo := 1; + ddwind; + Done := FALSE; + REPEAT + Infield_Arrow_Exited := FALSE; + CASE oo OF + 0 : BEGIN + Done1 := FALSE; + Shd(oo,TRUE); + REPEAT + C := ReadKey; + CASE UpCase(C) OF + ^M : BEGIN + Done := TRUE; + Done1 := TRUE; + END; + #0 : BEGIN + C := ReadKey; + CASE Ord(C) OF + 80,72 : {arrow down, up} + BEGIN + Infield_Arrow_Exited := TRUE; + Infield_Last_Arrow := Ord(C); + Done1 := TRUE; + END; + END; + END; + END; + UNTIL (Done1); + END; + 1 : BEGIN + S := IntToStr(ThisUser.SL); + InField1(26,7,S,3); + IF (StrToInt(S) <> ThisUser.SL) THEN + IF (StrToInt(S) >= 0) AND (StrToInt(S) <= 255) THEN + BEGIN + ThisUser.SL := StrToInt(S); + Inc(ThisUser.TLToday,General.TimeAllow[ThisUser.SL] - General.TimeAllow[ThisUser.SL]); + END; + END; + 2 : BEGIN + S := IntToStr(ThisUser.DSL); + InField1(26,8,S,3); + IF (StrToInt(S) <> ThisUser.DSL) THEN + IF (StrToInt(S) >= 0) AND (StrToInt(S) <= 255) THEN + ThisUser.DSL := StrToInt(S); + END; + 3 : BEGIN + S := IntToStr(AccountBalance); + InField1(26,9,S,5); + AdjustBalance(AccountBalance - StrToInt(S)); + END; + 4 : BEGIN + S := ThisUser.Note; + InField1(26,10,S,39); + ThisUser.Note := S; + END; + 5 : BEGIN + Done1 := FALSE; + REPEAT + C := UpCase(ReadKey); + CASE C OF + #13 : Done1 := TRUE; + #0 : BEGIN + C := ReadKey; + CASE Ord(C) OF + 80,72: {arrow down,up} + BEGIN + Infield_Arrow_Exited := TRUE; + Infield_Last_Arrow := Ord(C); + Done1 := TRUE; + END; + END; + END; + '!' : BEGIN + FOR C := 'A' TO 'Z' DO + ToggleARFlag(C,ThisUser.AR,Changed); + Shd(oo,TRUE); + END; + 'A'..'Z' : + BEGIN + ToggleARFlag(C,ThisUser.AR,Changed); + Shd(oo,TRUE); + END; + END; + UNTIL (Done1); + END; + 6 : BEGIN + S := 'LCVUA*PEKM1234'; + Done1 := FALSE; + REPEAT + C := UpCase(ReadKey); + IF (C = #13) THEN + Done1 := TRUE + ELSE IF (C = #0) THEN + BEGIN + C := ReadKey; + CASE Ord(C) OF + 80,72: {arrow down,up} + BEGIN + Infield_Arrow_Exited := TRUE; + Infield_Last_Arrow := Ord(C); + Done1 := TRUE; + END; + END; + END + ELSE IF (Pos(C,S) <> 0) THEN + BEGIN + ToggleACFlags(C,ThisUser.Flags,Changed); + Shd(oo,TRUE); + END + ELSE + BEGIN + IF (C = '!') THEN + FOR i := 1 TO Length(S) DO + ToggleACFlags(S[i],ThisUser.Flags,Changed); + Shd(oo,TRUE); + END; + UNTIL (Done1); + END; + END; + IF (NOT Infield_Arrow_Exited) THEN + BEGIN + Infield_Arrow_Exited := TRUE; + Infield_Last_Arrow := 80; {arrow down} + END; + IF (Infield_Arrow_Exited) THEN + CASE Infield_Last_Arrow OF + 80,72 : + BEGIN {arrow down,up} + Shd(oo,FALSE); + IF (Infield_Last_Arrow = 80) THEN + BEGIN {arrow down} + Inc(oo); + IF (oo > 6) THEN + oo := 0; + END + ELSE + BEGIN + Dec(oo); + IF (oo < 0) THEN + oo := 6; + END; + Shd(oo,TRUE); + END; + END; + UNTIL (Done); + GoToXY(SaveWhereX,SaveWhereY); + TextAttr := SaveTextAttr; + CursorOn(TRUE); + NewCompTables; + SaveURec(ThisUser,UserNum); +END; + +END. + diff --git a/SOURCE/COMMON3.PAS b/SOURCE/COMMON3.PAS new file mode 100644 index 0000000..538f76c --- /dev/null +++ b/SOURCE/COMMON3.PAS @@ -0,0 +1,545 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S-,V-,X-} + +UNIT Common3; + +INTERFACE + +USES + Common; + +PROCEDURE InputDefault(VAR S: STRING; v: STRING; MaxLen: Byte; InputFlags: InputFlagSet; LineFeed: Boolean); +PROCEDURE InputFormatted(DisplayStr: AStr; VAR InputStr: STRING; Format: STRING; Abortable: Boolean); +PROCEDURE InputLongIntWC(S: AStr; VAR L: LongInt; InputFlags: InputFlagSet; LowNum,HighNum: LongInt; VAR Changed: Boolean); +PROCEDURE InputLongIntWOC(S: AStr; VAR L: LongInt; InputFlags: InputFlagSet; LowNum,HighNum: LongInt); +PROCEDURE InputWordWC(S: AStr; VAR W: SmallWord; InputFlags: InputFlagSet; LowNum,HighNum: Word; VAR Changed: Boolean); +PROCEDURE InputWordWOC(S: AStr; VAR W: SmallWord; InputFlags: InputFlagSet; LowNum,HighNum: Word); +PROCEDURE InputIntegerWC(S: AStr; VAR I: SmallInt; InputFlags: InputFlagSet; LowNum,HighNum: Integer; VAR Changed: Boolean); +PROCEDURE InputIntegerWOC(S: AStr; VAR I: SmallInt; InputFlags: InputFlagSet; LowNum,HighNum: Integer); +PROCEDURE InputByteWC(S: AStr; VAR B: Byte; InputFlags: InputFlagSet; LowNum,HighNum: Byte; VAR Changed: Boolean); +PROCEDURE InputByteWOC(S: AStr; VAR B: Byte; InputFlags: InputFlagSet; LowNum,HighNum: Byte); +PROCEDURE InputWN1(DisplayStr: AStr; VAR InputStr: AStr; MaxLen: Byte; InputFlags: InputFlagSet; VAR Changed: Boolean); +PROCEDURE InputWNWC(DisplayStr: AStr; VAR InputStr: AStr; MaxLen: Byte; VAR Changed: Boolean); +PROCEDURE InputMain(VAR S: STRING; MaxLen: Byte; InputFlags: InputFlagSet); +PROCEDURE InputWC(VAR S: STRING; MaxLen: Byte); +PROCEDURE Input(VAR S: STRING; MaxLen: Byte); +PROCEDURE InputL(VAR S: STRING; MaxLen: Byte); +PROCEDURE InputCaps(VAR S: STRING; MaxLen: Byte); + +IMPLEMENTATION + +USES + Crt +{$IFDEF WIN32} + ,RPScreen +{$ENDIF} + ; + +PROCEDURE InputDefault(VAR S: STRING; v: STRING; MaxLen: Byte; InputFlags: InputFlagSet; LineFeed: Boolean); +VAR + C: Char; + Counter: Byte; +BEGIN + MPL(MaxLen); + MCIAllowed := FALSE; + ColorAllowed := FALSE; + Prompt(v); + ColorAllowed := TRUE; + MCIAllowed := TRUE; + C := Char(GetKey); + IF (C <> #13) THEN + BEGIN + FOR Counter := 1 TO Length(v) DO + BackSpace; + Buf := C + Buf; + InputMain(S,MaxLen,InputFlags); + IF (S = '') THEN + BEGIN + S := v; + MPL(MaxLen); + Prompt(S); + END + ELSE IF (S = ' ') THEN + S := ''; + END + ELSE + BEGIN + S := v; + IF NOT (NolineFeed IN InputFlags) THEN + NL; + END; + UserColor(1); + IF (LineFeed) THEN + NL; +END; + + +PROCEDURE InputFormatted(DisplayStr: AStr; VAR InputStr: STRING; Format: STRING; Abortable: Boolean); +VAR + c: Char; + i, + FarBack: Byte; + + PROCEDURE UpdateString; + BEGIN + WHILE (NOT (Format[i] IN ['#','@']) AND (i <= Length(Format))) DO + BEGIN + OutKey(Format[i]); + InputStr := InputStr + Format[i]; + Inc(i); + END; + END; + +BEGIN + InputStr := ''; + Prt(DisplayStr); + MPL(Length(Format)); + i := 1; + UpdateString; + FarBack := i; + REPEAT + c := Char(GetKey); + IF (i <= Length(Format)) THEN + IF ((Format[i] = '@') AND (c IN ['a'..'z','A'..'Z'])) OR ((Format[i] = '#') AND (c IN ['0'..'9'])) THEN + BEGIN + c := UpCase(c); + OutKey(c); + InputStr := InputStr + c; + Inc(i); + UpdateString; + END; + IF (c = ^H) THEN + BEGIN + WHILE ((i > FarBack) AND NOT (Format[i - 1] IN ['#','@'])) DO + BEGIN + BackSpace; + Dec(InputStr[0]); + Dec(i); + END; + IF (i > FarBack) THEN + BEGIN + BackSpace; + Dec(InputStr[0]); + Dec(i); + END; + END; + UNTIL (HangUp) OR ((i > Length(Format)) OR (Abortable)) AND (c = #13); + UserColor(1); + NL; +END; + +PROCEDURE InputLongIntWC(S: AStr; VAR L: LongInt; InputFlags: InputFlagSet; LowNum,HighNum: LongInt; VAR Changed: Boolean); +VAR + TempStr: Str10; + SaveL: LongInt; + TempL: Real; +BEGIN + SaveL := L; + IF (NOT (DisplayValue IN InputFlags)) THEN + Prt(S+' (^5'+IntToStr(LowNum)+'^4-^5'+IntToStr(HighNum)+'^4): ') + ELSE + Prt(S+' (^5'+IntToStr(LowNum)+'^4-^5'+IntToStr(HighNum)+'^4) [^5'+IntToStr(L)+'^4]: '); + MPL(Length(IntToStr(HighNum))); + TempStr := IntToStr(L); + InputMain(TempStr,Length(IntToStr(HighNum)),InputFlags); + IF (TempStr <> '') THEN + BEGIN + TempL := ValueR(TempStr); + IF ((Trunc(TempL) >= LowNum) AND (Trunc(TempL) <= HighNum)) THEN + L := Trunc(TempL) + ELSE + BEGIN + NL; + Print('^7The range must be from '+IntToStr(LowNum)+' to '+IntToStr(HighNum)+'!^1'); + PauseScr(FALSE); + END; + END; + IF (SaveL <> L) THEN + Changed := TRUE; +END; + +PROCEDURE InputLongIntWOC(S: AStr; VAR L: LongInt; InputFlags: InputFlagSet; LowNum,HighNum: LongInt); +VAR + Changed: Boolean; +BEGIN + Changed := FALSE; + InputLongIntWC(S,L,InputFlags,LowNum,HighNum,Changed); +END; + +PROCEDURE InputWordWC(S: AStr; VAR W: SmallWord; InputFlags: InputFlagSet; LowNum,HighNum: Word; VAR Changed: Boolean); +VAR + TempStr: Str5; + SaveW: Word; + TempW: Longint; +BEGIN + SaveW := W; + IF (NOT (DisplayValue IN InputFlags)) THEN + Prt(S+' (^5'+IntToStr(LowNum)+'^4-^5'+IntToStr(HighNum)+'^4): ') + ELSE + Prt(S+' (^5'+IntToStr(LowNum)+'^4-^5'+IntToStr(HighNum)+'^4) [^5'+IntToStr(W)+'^4]: '); + MPL(Length(IntToStr(HighNum))); + TempStr := IntToStr(W); + InputMain(TempStr,Length(IntToStr(HighNum)),InputFlags); + IF (TempStr <> '') THEN + BEGIN + TempW := StrToInt(TempStr); + IF ((TempW >= LowNum) AND (TempW <= HighNum)) THEN + W := TempW + ELSE + BEGIN + NL; + Print('^7The range must be from '+IntToStr(LowNum)+' to '+IntToStr(HighNum)+'!^1'); + PauseScr(FALSE); + END; + END; + IF (SaveW <> W) THEN + Changed := TRUE; +END; + +PROCEDURE InputWordWOC(S: AStr; VAR W: SmallWord; InputFlags: InputFlagSet; LowNum,HighNum: Word); +VAR + Changed: Boolean; +BEGIN + Changed := FALSE; + InputWordWC(S,W,InputFlags,LowNum,HighNum,Changed); +END; + +PROCEDURE InputIntegerWC(S: AStr; VAR I: SmallInt; InputFlags: InputFlagSet; LowNum,HighNum: Integer; VAR Changed: Boolean); +VAR + TempStr: Str5; + SaveI: Integer; + TempI: Longint; +BEGIN + SaveI := I; + IF (NOT (DisplayValue IN InputFlags)) THEN + Prt(S+' (^5'+IntToStr(LowNum)+'^4-^5'+IntToStr(HighNum)+'^4): ') + ELSE + Prt(S+' (^5'+IntToStr(LowNum)+'^4-^5'+IntToStr(HighNum)+'^4) [^5'+IntToStr(I)+'^4]: '); + MPL(Length(IntToStr(HighNum))); + TempStr := IntToStr(I); + InputMain(TempStr,Length(IntToStr(HighNum)),InputFlags); + IF (TempStr <> '') THEN + BEGIN + TempI := StrToInt(TempStr); + IF ((TempI >= LowNum) AND (TempI <= HighNum)) THEN + I := TempI + ELSE + BEGIN + NL; + Print('^7The range must be from '+IntToStr(LowNum)+' to '+IntToStr(HighNum)+'!^1'); + PauseScr(FALSE); + END; + END; + IF (SaveI <> I) THEN + Changed := TRUE; +END; + +PROCEDURE InputIntegerWOC(S: AStr; VAR I: SmallInt; InputFlags: InputFlagSet; LowNum,HighNum: Integer); +VAR + Changed: Boolean; +BEGIN + Changed := FALSE; + InputIntegerWC(S,I,InputFlags,LowNum,HighNum,Changed); +END; + +PROCEDURE InputByteWC(S: AStr; VAR B: Byte; InputFlags: InputFlagSet; LowNum,HighNum: Byte; VAR Changed: Boolean); +VAR + TempStr: Str3; + SaveB: Byte; + TempB: Integer; +BEGIN + SaveB := B; + IF (NOT (DisplayValue IN InputFlags)) THEN + Prt(S+' (^5'+IntToStr(LowNum)+'^4-^5'+IntToStr(HighNum)+'^4): ') + ELSE + Prt(S+' (^5'+IntToStr(LowNum)+'^4-^5'+IntToStr(HighNum)+'^4) [^5'+IntToStr(B)+'^4]: '); + MPL(Length(IntToStr(HighNum))); + TempStr := IntToStr(B); + InputMain(TempStr,Length(IntToStr(HighNum)),InputFlags); + IF (TempStr <> '') THEN + BEGIN + TempB := StrToInt(TempStr); + IF ((TempB >= LowNum) AND (TempB <= HighNum)) THEN + B := TempB + ELSE + BEGIN + NL; + Print('^7The range must be from '+IntToStr(LowNum)+' to '+IntToStr(HighNum)+'!^1'); + PauseScr(FALSE); + END; + END; + IF (SaveB <> B) THEN + Changed := TRUE; +END; + +PROCEDURE InputByteWOC(S: AStr; VAR B: Byte; InputFlags: InputFlagSet; LowNum,HighNum: Byte); +VAR + Changed: Boolean; +BEGIN + Changed := FALSE; + InputByteWC(S,B,InputFlags,LowNum,HighNum,Changed); +END; + +PROCEDURE InputWN1(DisplayStr: AStr; VAR InputStr: AStr; MaxLen: Byte; InputFlags: InputFlagSet; VAR Changed: Boolean); +VAR + SaveInputStr: AStr; +BEGIN + Prt(DisplayStr); + IF (NOT (ColorsAllowed IN InputFlags)) THEN + MPL(MaxLen); + SaveInputStr := InputStr; + InputMain(SaveInputStr,MaxLen,InputFlags); + IF (SaveInputStr = '') THEN + SaveInputStr := InputStr; + IF (SaveInputStr = ' ') THEN + IF PYNQ('Blank String? ',0,FALSE) THEN + SaveInputStr := '' + ELSE + SaveInputStr := InputStr; + IF (SaveInputStr <> InputStr) THEN + Changed := TRUE; + InputStr := SaveInputStr; +END; + +PROCEDURE InputWNWC(DisplayStr: AStr; VAR InputStr: AStr; MaxLen: Byte; VAR Changed: Boolean); +BEGIN + InputWN1(DisplayStr,InputStr,MaxLen,[ColorsAllowed,InterActiveEdit],Changed); +END; + +PROCEDURE InputMain(VAR S: STRING; MaxLen: Byte; InputFlags: InputFlagSet); +VAR + SaveS: STRING; + Is: STRING[2]; + Cp, + Cl, + Counter: Byte; + c, + C1: Word; + InsertMode, + FirstKey: Boolean; + + PROCEDURE MPrompt(S: STRING); + BEGIN + SerialOut(S); + IF (WantOut) THEN + Write(S); + END; + + PROCEDURE Cursor_Left; + BEGIN + IF (NOT OkAvatar) THEN + SerialOut(#27'[D') + ELSE + SerialOut(^V^E); + IF (WantOut) THEN + GotoXY((WhereX - 1),WhereY); + END; + + PROCEDURE Cursor_Right; + BEGIN + OutKey(S[Cp]); + Inc(Cp); + END; + +{$IFDEF MSDOS} + PROCEDURE SetCursor(InsertMode: Boolean); ASSEMBLER; + ASM + cmp InsertMode,0 + je @turnon + mov ch,0 + mov Cl,7 + jmp @goforit + @turnon: + mov ch,6 + mov Cl,7 + @goforit: + mov ah,1 + int 10h + END; +{$ENDIF} +{$IFDEF WIN32} + PROCEDURE SetCursor(InsertMode: Boolean); + BEGIN + if (InsertMode) then + begin + RPInsertCursor; + end else + begin + RPBlockCursor; + end; + END; +{$ENDIF} + +BEGIN + FirstKey := FALSE; + + IF (NOT (InterActiveEdit IN InputFlags)) OR NOT (Okansi OR OkAvatar) THEN + BEGIN + S := ''; + Cp := 1; + Cl := 0; + END + ELSE + BEGIN + Cp := Length(S); + Cl := Length(S); + IF (Cp = 0) THEN + Cp := 1; + MPrompt(S); + IF (Length(S) > 0) THEN + BEGIN + Cursor_Left; + IF (Cp <= MaxLen) THEN (* Was Cp < MaxLen *) + Cursor_Right; + END; + FirstKey := TRUE; + END; + + SaveS := S; + InsertMode := FALSE; + + REPEAT + MLC := S; + SetCursor(InsertMode); + c := GetKey; + + IF (FirstKey) AND (C = 32) THEN + C := 24; + + FirstKey := FALSE; + + CASE c OF + 8 : IF (Cp > 1) THEN + BEGIN + Dec(Cl); + Dec(Cp); + Delete(S,Cp,1); + BackSpace; + IF (Cp < Cl) THEN + BEGIN + MPrompt(Copy(S,Cp,255)+' '); + FOR Counter := Cp TO (Cl + 1) DO + Cursor_Left; + END; + END; + 24 : BEGIN + FOR Counter := Cp TO Cl DO + OutKey(' '); + FOR Counter := 1 TO Cl DO + BackSpace; + Cl := 0; + Cp := 1; + END; + 32..255: + BEGIN + IF (NOT (NumbersOnly IN InputFlags)) THEN + BEGIN + IF (UpperOnly IN InputFlags) THEN + c := Ord(UpCase(Char(c))); + IF (CapWords IN InputFlags) THEN + IF (Cp > 1) THEN + BEGIN + IF (S[Cp - 1] IN [#32..#64]) THEN + c := Ord(UpCase(Char(c))) + ELSE IF (c IN [Ord('A')..Ord('Z')]) THEN + Inc(c,32); + END + ELSE + c := Ord(UpCase(Char(c))); + END; + IF (NOT (NumbersOnly IN InputFlags)) OR (c IN [45,48..57]) THEN + BEGIN + IF ((InsertMode) AND (Cl < MaxLen)) OR ((NOT InsertMode) AND (Cp <= MaxLen)) THEN + BEGIN + OutKey(Char(c)); + IF (InsertMode) THEN + BEGIN + Is := Char(c); + MPrompt(Copy(S,Cp,255)); + Insert(Is,S,Cp); + FOR Counter := Cp TO Cl DO + Cursor_Left; + END + ELSE + S[Cp]:= Char(c); + IF (InsertMode) OR ((Cp - 1) = Cl) THEN + Inc(Cl); + Inc(Cp); + IF (Trapping) THEN + Write(TrapFile,Char(c)); + END; + END; + END; + F_END : + WHILE (Cp < (Cl + 1)) AND (Cp <= MaxLen) DO + Cursor_Right; + F_HOME : + WHILE (Cp > 1) DO + BEGIN + Cursor_Left; + Dec(Cp); + END; + F_LEFT : + IF (Cp > 1) THEN + BEGIN + Cursor_Left; + Dec(Cp); + END; + F_RIGHT : + IF (Cp <= Cl) THEN + Cursor_Right; + F_INS : + BEGIN + InsertMode := (NOT InsertMode); + SetCursor(InsertMode); + END; + F_DEL : + IF (Cp > 0) AND (Cp <= Cl) THEN + BEGIN + Dec(Cl); + Delete(S,Cp,1); + MPrompt(Copy(S,Cp,255)+' '); + FOR Counter := Cp TO (Cl + 1) DO + Cursor_Left; + END; + END; + S[0] := Chr(Cl); + UNTIL (c = 13) OR (HangUp); + IF ((Redisplay IN InputFlags) AND (S = '')) THEN + BEGIN + S := SaveS; + MPrompt(S); + END; + + UserColor(1); + + IF (NOT (NoLineFeed IN InputFlags)) THEN + NL; + MLC := ''; + SetCursor(FALSE); +END; + +PROCEDURE InputWC(VAR S: STRING; MaxLen: Byte); +BEGIN + InputMain(S,MaxLen,[ColorsAllowed]); +END; + +PROCEDURE Input(VAR S: STRING; MaxLen: Byte); +BEGIN + InputMain(S,MaxLen,[UpperOnly]); +END; + +PROCEDURE InputL(VAR S: STRING; MaxLen: Byte); +BEGIN + InputMain(S,MaxLen,[]); +END; + +PROCEDURE InputCaps(VAR S: STRING; MaxLen: Byte); +BEGIN + InputMain(S,MaxLen,[CapWords]); +END; + +END. diff --git a/SOURCE/COMMON4.PAS b/SOURCE/COMMON4.PAS new file mode 100644 index 0000000..7abe0e2 --- /dev/null +++ b/SOURCE/COMMON4.PAS @@ -0,0 +1,1051 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S-,V-} + +(* +AH = 01h Transmit character with wait +Parameters: +Entry: AL = Character +DX = Port number +Exit: AX = Port status (see function 03h) +AL contains the character to be sent. If there is room in the transmit +buffer the return will be immediate, otherwise it will wait until there +is room to store the character in the transmit buffer. On return, AX is +set as in a status request (see function 03h). + +AH = 04h Initialize driver +Parameters: +Entry: DX = port number +( BX = 4F50h +| ES:CX = ^C flag address --- optional ) +Exit: AX = 1954h if successful +| BL = maximum function number supported +| (not counting functions 7Eh and above) +| BH = rev of FOSSIL doc supported +This is used to tell the driver to begin operations, and to check that +the driver is installed. This function should be called before any other +communications calls are made. At this point all interrupts involved in +supporting the comm port (specified in DX) should be set up for handling +by the FOSSIL, then enabled. If BX contains 4F50h, then the address +specified in ES:CX is that of a ^C flag byte in the application program, +to be incremented when ^C is detected in the keyboard service routines. +This is an optional service and only need be supported on machines where +the keyboard service can't (or won't) perform an INT 1Bh or INT 23h when +| a Control-C is entered. DTR is raised by this call. The baud rate must +| NOT be changed by this call. +NOTE: Should an additional call to this service occur (2 Inits or Init, +Read,Init, etc.) the driver should reset all buffers, flow control, etc. +to the INIT state and return SUCCESS. + +AH = 07h Return timer tick parameters +Parameters: +Entry: None +Exit: AL = Timer tick interrupt number +AH = Ticks per second on interrupt number in AL +DX = Approximate number of milliseconds per tick +This is used to determine the parameters of the timer tick on any given +machine. Three numbers are returned: +AL = Timer tick interrupt number +AH = Ticks per second on interrupt number shown in AL +DX = Milliseconds per tick (approximate) +Applications can use this for critical timing (granularity of less than +one second) or to set up code (such as a watchdog) that is executed on +every timer tick. See function 16h (add/delete function from timer tick) +for the preferred way of actually installing such code. + +AH = 08h Flush output buffer +Parameters: +Entry: DX = Port number +Exit: None +This is used to force any pending output. It does not return until all +pending output has been sent. You should use this call with care. Flow +control (documented below) can make your system hang on this call in a +tight uninterruptible loop under the right circumstances. + +AH = 0Dh Keyboard read without wait +Parameters: +Entry: None +Exit: AX = IBM-style scan code (Character available) += FFFFh (Character not available) +Return in AX the next character (non-destructive read ahead) from the +keyboard; if nothing is currently in the keyboard buffer, return FFFFh in +AX. Use IBM-style function key mapping in the high order byte. Scan +codes for non-"function" keys are not specifically required, but may be +included. Function keys return 00h in AL and the "scan code" in AH. + +AH = 0Eh Keyboard read with wait +Parameters: +Entry: None +Exit: AX = IBM-style scan codeReturn in AX the next character from the keyboard; wait if no character +is available. Keyboard mapping should be the same as function 0Dh. + +AH = 0Fh Enable or disable flow control +Parameters: +Entry: AL = Bit mask describing requested flow control +DX = Port number +Exit: None +TRANSMIT flow control allows the "other end" to restrain the transmitter +when you are over-running it. RECEIVE flow control tells the FOSSIL to +attempt to DO just that if it is being overwhelmed. +Two kinds of basic flow control are supported: +Bit 0 = 1 Xon/Xoff on transmit +Bit 1 = 1 CTS/RTS (CTS on transmit, RTS on receive) +Bit 2 Reserved +| Bit 3 = 1 Xon/Xoff on Receive +Flow control is enabled, or disabled, by setting the appropriate bits in +AL for the types of flow control we want to ENABLE (value = 1), and/or +DISABLE (value = 0), and calling this function. Bit 2 is reserved for +DSR/DTR, but is not currently supported in any implementation. +Enabling transmit Xon/Xoff will cause the FOSSIL to stop transmitting +upon receiving an Xoff. The FOSSIL will resume transmitting when an Xon +is received. +Enabling CTS/RTS will cause the FOSSIL to cease transmitting when CTS is +lowered. Transmission will resume when CTS is raised. The FOSSIL will +drop RTS when the receive buffer reaches a predetermined percentage full +The FOSSIL will raise RTS when the receive buffer empties below the +predetermined percentage full. The point(s) at which this occurs is +left to the individual FOSSIL implementor. +| Enabling receive Xon/Xoff will cause the FOSSIL to send a Xoff when the +| receive buffer reaches a pre-determined percentage full. An Xon will be +| sent when the receive buffer empties below the pre-determined percentage +| full. The point(s) at which this occurs is left to the individual FOSSIL +| implementor. +Applications using this function should set all bits ON in the high +nibble of AL as well. There is a compatible (but not identical) FOSSIL +driver implementation that uses the high nibble as a control mask. If +your application sets the high nibble to all ones, it will always work, +regardless of the method used by any given driver. + +AH = 10h Extended Control-C / Control-K checking and transmit on/off +Parameters: +Entry: AL = Bit mask (see below) +DX = Port number +Exit: AX = 0001h - Control-C/K has been received += 0000h - Control-C/K has not been received +This is used for BBS operation, primarily. A bit mask is passed in AL +with the following flags: +Bit 0 Enable/disable Control-C / Control-K checking +Bit 1 Disable/enable the transmitter +The Enable (bit 0 = 1) and Disable (Bit 0 = 0) Control-C/Control-K check +function is meant primarily for BBS use. When the checking is enabled, a +Control-C or Control-K received from the communications port will set a +flag internal to the FOSSIL driver, but will not be stored in the input +buffer. The next use of this function will return the value of this flag +in register AX then clear the flag for the next occurrence. The returned +value is used by the BBS software to determine whether output should be +halted or not. +The Disable (Bit 1 = 1) and Enable (Bit 1 = 0) Transmitter function lets +the application restrain the asynchronous driver from output in much the +same way as XON/XOFF would. + +AH = 11h Set current cursor location. +Parameters: +Entry: DH = Row (line) +DL = Column +Exit: None +This function looks exactly like like INT 10h, subfunction 2, on the IBM +PC. The cursor location is passed in DX: row in DH and column in DL. The +function treats the screen as a coordinate system whose origin (0,0) is +the upper left hand corner of the screen. + +AH = 12h Read current cursor location. +Parameters: +Entry: None +Exit: DH = Row (line) +DL = Column +Looks exactly like INT 10h, subfunction 3, on the IBM PC. The current +cursor location (using the same coordinate system as function 16h) is +passed back in DX. + +AH = 13h Single character ANSI write to screen. +Parameters: +Entry: AL = Character to display +Exit: None +The character in AL is sent to the screen by the fastest method possible +that allows ANSI processing to occur (if available). This routine should +not be used in such a way that DOS output (which is not re-entrant) can +not be employed by some FOSSIL driver to perform the function (in fact, +on the IBM PC that is likely to be how it's done). On some systems such +as the DEC Rainbow this will be a very fast method of screen writing. + +AH = 14h Enable or disable watchdog processing +Parameters: +Entry: AL = 01h - Enable watchdog += 00h - Disable watchdog +DX = Port number +Exit: None +When watchdog is enabled, the state of the carrier detect (CD) line on +the comm port specified in DX should be constantly monitored. Should the +state of that line become FALSE (carrier lost), the system should be re- +booted, to enable the BBS (or other application) to start up again. This +monitor is not affected by Init/Uninit etc. + +AH = 15h Write character to screen using BIOS support routines +Parameters: +Entry: AL = Character to display +Exit: None +The character in AL is sent to the screen using BIOS-level Input/Output +routines. This differs from function 13h in that DOS I/O CAN NOT be used, +as this function might be called from driver level. + +AH = 16h Insert or delete a function from the timer tick chain +Parameter: +Entry: AL = 01h - Add a function += 00h - Delete a function +| ES = Segment of function +DX = Offset of function +Exit: AX = 0000h - Operation successful += FFFFh - Operation unsuccessful +This function is used to allow a central authority to manage the timer +interrupts, so that as code is loaded and unloaded, the integrity of the +"chain" is not compromised. Rather than using the traditional method of +saving the old contents of the timer vector, storing the address of your +routine there, and executing a far call to the "old" routine when yours +is done, instead you call this function. It manages a list of such entry +points and calls them on a timer tick (interrupt) using a FAR call. All +the usual cautions about making DOS calls apply (that is, DON'T!). +This makes it possible for a program to get in and out of the tick chain +without having to know whether another program has also done so since it +first insinuated itself. At least 4 entries should be available in the +driver's table (including one to be used by Watchdog if implemented that +way). + +AH = 17h Reboot system +Parameters: +Entry: AL = 00h - "Cold boot" += 01h - "Warm boot" +Perform the old 3-finger salute. Used in extreme emergency by code that +can't seem to find a "clean" way out of the trouble it has gotten itself +into. Hopefully it won't happen while you're computing something in the +other half of a DoubleDOS system. If your machine can make a distinction +between a "cold" (power-up, self-test and boot) and a "warm" (just boot) +bootstrap, your FOSSIL should support the flag in AL. Otherwise just DO +whatever bootstrap is possible. + +| AH = 18h Read block (transfer from FOSSIL to user buffer) +| Parameters: +| Entry: CX = Maximum number of characters to transfer +| DX = Port number +| ES = Segment of user buffer +| DI = Offset into ES of user buffer +| Exit: AX = Number of characters actually transferred +| A "no-wait" block read of 0 to FFFFh characters from the FOSSIL inbound +| ring buffer to the calling routine's buffer. ES:DI are left unchanged by +| the call; the count of bytes actually transferred will be returned in AX. + +| AH = 1Ah Break begin or end +| Parameters: +| Entry: AL = 01h - Start sending 'break' += 00h - Stop sending 'break' +| DX = port number +| Exit: None +| Send a break signal to the modem. If AL=01h the driver will commence the +| transmission of a break. If AL=00h the driver will end the break. This +| is useful for communications with devices that can only go into 'command +| mode' when a BREAK is received. Note: the application is responsible for +| the timing of the BREAK. Also, if the FOSSIL has been restrained by an +| Xoff received from the modem, the flag will be cleared. An Init or Un- +| Init will stop an in-progress BREAK. + +| AH = 1Bh Return information about the driver +| Parameters: +| Entry: CX = Size of user info buffer in bytes +| DX = Port number +| ES = Segment of user info buffer +| DI = Offset into ES of user info buffer +| Exit: AX = Number of bytes actually transferred +| Transfer information about the driver and its current status to the user +| for use in determining, at the application level, limits of the driver. +| Designed to assist "generic" applications to adjust to "foreign" gear. +| The data structure currently returned by the driver is as follows (sorry +| but you'll have to live with assembly syntax): +| info equ $ ; define begin of structure +| strsiz dw info_size ; size of the structure in bytes +| majver db curr_fossil ; FOSSIL spec driver conforms to +| minver db curr_rev ; rev level of this specific driver +| ident dd id_string ; "FAR" pointer to ASCII ID string +| ibufr dw ibsize ; size of the input buffer (bytes) +| ifree dw ? ; number of bytes left in buffer +| obufr dw obsize ; size of the output buffer (bytes) +| ofree dw ? ; number of bytes left in the buffer +| swidth db screen_width ; width of screen on this adapter +| sheight db screen_height ; height of screen " " +| baud db ? ; ACTUAL baud rate, computer to modem +| info_size equ $-info +| The ident string should be null-terminated, and NOT contain a newline. +| The baud rate byte contains the bits that Function 00h would use to set +| the port to that speed. +| The fields related to a particular port (buffer size, space left in the +| buffer, baud rate) will be undefined if port FFh or an invalid port is +| contained in DX.| Additional information will always be passed after these, so that, for +| example, offset "sheight" will never change with FOSSIL revision changes. + +| The functions below are not necessarily FOSSIL related. However, because +| dispatchers that support them are hooked on Interrupt 14H, it behooves +| the FOSSIL developer to support them as well to avoid fragmenting memory +| with several dispatchers. + +| AH = 7Eh Install an "external application" function +| Parameters: +| Entry: AL = Code assigned to external application +| DX = Offset of application entry point +| ES = Segment of application entry point +| Exit: AX = 1954h +| BL = Code assigned to application (same as input AL) +| BH = 01h - Installation was successful +| = 00h - Installation failed +| This call is used by external application code (special screen drivers, +| modem code, database code, etc) to link into the INT 14h service for use +| by multiple applications. The "error return" (BH=0 with AX=1954h) should +| mean that another application layer has already been installed at that +| particular code. Codes 80h through BFh should be supported. +| External application codes 80h-83h are reserved by FOSSIL developers for +| re-organizing FOSSIL services by type (comm, screen, keyboard, system). +| Installed application code will be entered, via a FAR call, from the INT +| 14H dispatcher whenever it is entered with AH=(application code). +| If the value returned in AX from this function is not 1954h, the service +| code that is trying to be installed should bring up its own INT 14h code +| that can service INT 14h functions 7h-BFh (80h-BFh are "applications"). + +| AH = 7Fh Remove an "external application" function +| Parameters: +| Entry: AL = Code assigned to external application +| DX = Offset of application entry point +| ES = Segment of application entry point +| Exit: AX = 1954h +| BL = Code assigned to application (same as input AL) +| BH = 01h - Removal was successful +| = 00h - Removal failed +| Removes an application's entry into the table. Usually so it can remove +| itself from memory. Error return means ES:DX did not match or that there +| is no entry at the slot described by AL. +| An application that wants to remove itself from memory can issue the 7F +| function to remove itself from the table, then, if it is successful, get +| out of memory. If it had to install itself with an INT 14h dispatcher it +| may back itself out, provided no other applications have been installed +| on top of it (using its dispatcher). +*) + +UNIT Common4; + +INTERFACE + +PROCEDURE Com_Flush_Recv; +PROCEDURE Com_Flush_Send; +PROCEDURE Com_Purge_Send; +FUNCTION Com_Carrier: Boolean; +FUNCTION Com_Recv: Char; +FUNCTION Com_IsRecv_Empty: Boolean; +FUNCTION Com_IsSend_Empty: Boolean; +PROCEDURE Com_Send(c: Char); +PROCEDURE Com_Set_Speed(Speed: LongInt); +PROCEDURE Com_DeInstall; +PROCEDURE Com_Install; +PROCEDURE CheckHangup; +PROCEDURE SerialOut(S: STRING); +FUNCTION Empty: Boolean; +PROCEDURE DTR(Status: Boolean); + +IMPLEMENTATION + +USES + Crt, + Common +{$IFDEF WIN32} + ,EleNorm +{$ENDIF} + ; + +{$IFDEF WIN32} +VAR + DidClose: Boolean = false; + DidInit: Boolean = false; +{$ENDIF} + +(* +AH = 0Ah Purge input buffer +Parameters: + Entry: DX = Port number + Exit: None +This is used to purge any pending input. Any input data which is still +in the buffer is discarded. +*) + +PROCEDURE Com_Flush_Recv; +BEGIN + IF (NOT LocalIOOnly) THEN + BEGIN +{$IFDEF MSDOS} + ASM + Cmp InWfcMenu,1 + Je @TheEnd + Mov AH,0Ah + Mov DX,FossilPort + Int 14h + @TheEnd: + END; +{$ENDIF} +{$IFDEF WIN32} + if (InWfcMenu) then Exit; + if Not(DidInit) then Exit; + if (DidClose) then Exit; + if Not(EleNorm.Com_Carrier) then Exit; + EleNorm.Com_PurgeInBuffer; // REENOTE Is this right? Function says flush not purge +{$ENDIF} + END + ELSE WHILE NOT (Com_IsRecv_Empty) DO + WriteWFC(CInKey); +END; + +PROCEDURE Com_Flush_Send; +VAR + SaveTimer: LongInt; +BEGIN + SaveTimer := (Timer + 5); + WHILE (SaveTimer > Timer) AND (OutCom AND Com_Carrier) AND (NOT Com_IsSend_Empty) DO; +END; + +(* +AH = 09h Purge output buffer +Parameters: + Entry: DX = Port number + Exit: None +This is used to purge any pending output. Any output data remaining in +the output buffer (not transmitted yet) is discarded. +*) + +PROCEDURE Com_Purge_Send; +BEGIN +{$IFDEF MSDOS} + ASM + Cmp LocalIOOnly,1 + Je @TheEnd + Mov AH,09h + Mov DX,FossilPort + Int 14h + @TheEnd: + END; +{$ENDIF} +{$IFDEF WIN32} + if (LocalIOOnly) then Exit; + if Not(DidInit) then Exit; + if (DidClose) then Exit; + if Not(EleNorm.Com_Carrier) then Exit; + EleNorm.Com_PurgeOutBuffer; +{$ENDIF} +END; + +(* +AH = 03h Request status +Parameters: + Entry: DX = Port number + Exit: AX = Status bit mask (see below) +Returns with the line and modem status in AX. Status bits returned are: +In AH: +Bit 0 = RDA - input data is available in buffer +Bit 1 = OVRN - the input buffer has been overrun. All characters received + after the buffer is full should be discarded. +Bit 5 = THRE - room is available in output buffer +Bit 6 = TSRE - output buffer is empty +In AL: +Bit 3 = Always 1 (always return with this bit set to 1) +Bit 7 = DCD - carrier detect +This can be used by the application to determine whether carrier detect +(CD) is set, signifying the presence/absence of a remote connection, as +well as monitoring both the input and output buffer status. Bit 3 of AL +is always returned set to enable programs to use it as a carrier detect +bit on hardwired (null modem) links. +*) + +FUNCTION Com_Carrier: Boolean; +VAR + Dummy: Byte; +BEGIN + Dummy := 0; (* New *) +{$IFDEF MSDOS} + ASM + Cmp LocalIOOnly,1 + Je @TheEnd + Mov AH,03h + Mov DX,FossilPort + Int 14h + Mov Dummy,AL + @TheEnd: + END; + Com_Carrier := (Dummy AND $80) = $80; +{$ENDIF} +{$IFDEF WIN32} + Com_Carrier := false; + if (LocalIOOnly) then Exit; + if Not(DidInit) then Exit; + if (DidClose) then Exit; + Com_Carrier := EleNorm.Com_Carrier; +{$ENDIF} +END; + +(* +AH = 0Ch Non-destructive read-ahead +Parameters: + Entry: DX = Port number + Exit: AH = 00h - Character is +AL = Next character available +AX = FFFFh - Character is not available +Return in AL the next character in the receive buffer. If the receive +buffer is empty, return FFFFh. The character returned remains in +the receive buffer. Some applications call this "peek". + +AH = 02h Receive character with wait +Parameters: + Entry: DX = Port number + Exit: AH = 00h +AL = Input character +If there is a character available in the receive buffer, returns with +the next character in AL. It will wait until a character is received if +none is available. +*) + +FUNCTION Com_Recv: Char; +CONST + NotAvil = $FFFF; +VAR + Dummy: Byte; + T_RecvChar: Boolean; +{$IFDEF WIN32} + Ch: Char; +{$ENDIF} +BEGIN + Com_Recv := #0; + T_RecvChar := FALSE; +{$IFDEF MSDOS} + ASM + Cmp LocalIOOnly,1 + Je @TheEnd + Mov AH,0ch + Mov DX,FossilPort + Int 14h + Cmp AX,NotAvil + Je @TheEnd + Mov AH,02h + Mov DX,FossilPort + Int 14h + Mov Dummy,AL + Mov T_RecvChar,1 + @TheEnd: + END; + IF (T_RecvChar) THEN + Com_Recv := Char(Dummy); +{$ENDIF} +{$IFDEF WIN32} + if (LocalIOOnly) then Exit; + if Not(DidInit) then Exit; + if (DidClose) then Exit; + if Not(EleNorm.Com_Carrier) then Exit; + if Not(EleNorm.Com_CharAvail) then Exit; + + // Get character from buffer + Ch := EleNorm.Com_GetChar; + if (Ch = #10) then + begin + // Translate bare LF to CR + Com_Recv := #13; + end else + begin + Com_Recv := Ch; + end; + + // If this char is CR, check if the next char is LF (so we can discard it) + if (Ch = #13) and (EleNorm.Com_CharAvail) then + begin + Ch := EleNorm.Com_PeekChar; + if (Ch = #10) then EleNorm.Com_GetChar; // Discard that LF + end; +{$ENDIF} +END; + +(* +AH = 03h Request status +Parameters: + Entry: DX = Port number + Exit: AX = Status bit mask (see below) +Returns with the line and modem status in AX. Status bits returned are: +In AH: +Bit 0 = RDA - input data is available in buffer +Bit 1 = OVRN - the input buffer has been overrun. All characters received + after the buffer is full should be discarded. +Bit 5 = THRE - room is available in output buffer +Bit 6 = TSRE - output buffer is empty +In AL: +Bit 3 = Always 1 (always return with this bit set to 1) +Bit 7 = DCD - carrier detect +This can be used by the application to determine whether carrier detect +(CD) is set, signifying the presence/absence of a remote connection, as +well as monitoring both the input and output buffer status. Bit 3 of AL +is always returned set to enable programs to use it as a carrier detect +bit on hardwired (null modem) links. +*) + +FUNCTION Com_IsRecv_Empty: Boolean; +VAR + Dummy: Byte; +BEGIN + Dummy := 0; (* New *) +{$IFDEF MSDOS} + ASM + Cmp LocalIOOnly,1 + Je @TheEnd + Mov AH,03h + Mov DX,FossilPort + Int 14h + Mov Dummy,AH + @TheEnd: + END; + Com_IsRecv_Empty := NOT ((Dummy AND $01) = $01); +{$ENDIF} +{$IFDEF WIN32} + Com_IsRecv_Empty := true; + if (LocalIOOnly) then Exit; + if Not(DidInit) then Exit; + if (DidClose) then Exit; + if Not(EleNorm.Com_Carrier) then Exit; + Com_IsRecv_Empty := Not(EleNorm.Com_CharAvail); +{$ENDIF} +END; + +(* +AH = 03h Request status +Parameters: + Entry: DX = Port number + Exit: AX = Status bit mask (see below) +Returns with the line and modem status in AX. Status bits returned are: +In AH: +Bit 0 = RDA - input data is available in buffer +Bit 1 = OVRN - the input buffer has been overrun. All characters received + after the buffer is full should be discarded. +Bit 5 = THRE - room is available in output buffer +Bit 6 = TSRE - output buffer is empty +In AL: +Bit 3 = Always 1 (always return with this bit set to 1) +Bit 7 = DCD - carrier detect +This can be used by the application to determine whether carrier detect +(CD) is set, signifying the presence/absence of a remote connection, as +well as monitoring both the input and output buffer status. Bit 3 of AL +is always returned set to enable programs to use it as a carrier detect +bit on hardwired (null modem) links. +*) + +FUNCTION Com_IsSend_Empty: Boolean; +VAR + Dummy: Byte; +{$IFDEF WIN32} + InFree, OutFree, InUsed, OutUsed: LongInt; +{$ENDIF} +BEGIN + Dummy := 0; (* New *) +{$IFDEF MSDOS} + ASM + Cmp LocalIOOnly,1 + Je @TheEnd + Mov AH,03h + Mov DX,FossilPort + Int 14h + Mov Dummy,AH + @TheEnd: + END; + Com_IsSend_Empty := ((Dummy AND $40) = $40); +{$ENDIF} +{$IFDEF WIN32} + Com_IsSend_Empty := false; + if (LocalIOOnly) then Exit; + if Not(DidInit) then Exit; + if (DidClose) then Exit; + if Not(EleNorm.Com_Carrier) then Exit; + EleNorm.Com_GetBufferStatus(InFree, OutFree, InUsed, OutUsed); + Com_IsSend_Empty := (OutUsed = 0); +{$ENDIF} +END; + +(* +AH = 0Bh Transmit no wait +Parameters: + Entry: DX = Port number + Exit: AX = 0001h - Character was accepted + = 0000h - Character was not accepted +This is exactly the same as the "regular" transmit call, except that if +the driver is unable to buffer the character (the buffer is full), a +value of 0000h is returned in AX. If the driver accepts the character +(room is available), 0001h is returned in AX. +*) + +PROCEDURE Com_Send(C: Char); +BEGIN +{$IFDEF MSDOS} + ASM + Cmp LocalIOOnly,1 + Je @TheEnd + Mov AH,0Bh + Mov DX,FossilPort + Mov AL,C (* Should this be Byte(C) *) + Int 14h + @TheEnd: + END; +{$ENDIF} +{$IFDEF WIN32} + if (LocalIOOnly) then Exit; + if Not(DidInit) then Exit; + if (DidClose) then Exit; + if Not(EleNorm.Com_Carrier) then Exit; + EleNorm.Com_SendChar(C); +{$ENDIF} +END; + +(* +AH = 00h Set baud rate +Parameters: + Entry: AL = Baud rate code + DX = Port number + Exit: AX = Port status (see function 03h) This works the same as + the equivalent IBM PC BIOS call, except that it ONLY + selects a baud rate. This is passed in the high order + 3 bits of AL as follows: + 010 = 300 baud + 011 = 600 '' + 100 = 1200 '' + 101 = 2400 '' + 110 = 4800 '' + 111 = 9600 '' + 000 = 19200 '' (Replaces old 110 baud mask) + 001 = 38400 '' (Replaces old 150 baud mask) +The low order 5 bits can be implemented or not by the FOSSIL, but in all +cases, if the low order bits of AL are 00011, the result should be that +the communications device should be set to eight data bits, one stop bit +and no parity. This setting is a MINIMUM REQUIREMENT of Fido, Opus and +SEAdog. For purposes of completeness, here are the IBM PC "compatible" +bit settings: + +Bits 4-3 define parity: 0 0 no parity +1 0 no parity +0 1 odd parity +1 1 even parity +Bit 2 defines stop bits: 0 1 stop bit; +1 1.5 bits for 5-bit char; +2 for othersBits 1-0 character length: 0 0 5 bits +0 1 6 bits +1 0 7 bits +1 1 8 bits +*) +(* + If n > 76800 then {115200 } + regs.al:=regs.al or $80 + else + If n > 57600 then { 76800 } + regs.al:=regs.al or $60 + else + case w of + 300 : regs.al:=regs.al or $40; + 600 : regs.al:=regs.al or $60; + 1200 : regs.al:=regs.al or $80; + 2400 : regs.al:=regs.al or $A0; + 4800 : regs.al:=regs.al or $C0; + 9600 : regs.al:=regs.al or $E0; + 9601..19200: regs.al:=regs.al or $00; + 19201..38400: regs.al:=regs.al or $20; + 38401..57600: regs.al:=regs.al or $40; + end; +*) + +PROCEDURE Com_Set_Speed(Speed: LongInt); +VAR + T_AL: Byte; +BEGIN + IF (NOT LocalIOOnly) THEN + BEGIN + CASE Speed OF + 300 : T_AL := 64; + 600 : T_AL := 96; + 1200 : T_AL := 128; + 2400 : T_AL := 160; + 4800 : T_AL := 192; + 9600 : T_AL := 224; + 19200 : T_AL := 0; + ELSE + T_AL := 32; + END; + Inc(T_AL,3); +{$IFDEF MSDOS} + ASM + Mov AH,00h + Mov AL,T_AL + Mov DX,FossilPort + Int 14h + END; +{$ENDIF} +{$IFDEF WIN32} + // REENOTE Telnet can't set speed +{$ENDIF} + END; +END; + +(* +AH = 05h Deinitialize driver +Parameters: + Entry: DX = Port number + Exit: None +This is used to tell the driver that comm port operations are ended. The +function should be called when no more comm port functions will be used +on the port specified in DX. DTR is NOT affected by this call. +*) + +PROCEDURE Com_DeInstall; +BEGIN + IF (NOT LocalIOOnly) THEN + BEGIN +{$IFDEF MSDOS} + ASM + Mov AH,05h + Mov DX,FossilPort + Int 14h + END; +{$ENDIF} +{$IFDEF WIN32} + if Not(DidInit) then Exit; + if Not(DidClose) then + begin + EleNorm.Com_Close; + DidClose := true; + end; + EleNorm.Com_ShutDown; +{$ENDIF} + END; +END; + +PROCEDURE Com_Install; + +{$IFDEF MSDOS} + FUNCTION DriverInstalled: Word; ASSEMBLER; + ASM + Mov AH,5 + Mov DX,FossilPort + PushF + Call Interrupt14 + Mov AH,4 + PushF + Call Interrupt14 + END; +{$ENDIF} +{$IFDEF WIN32} + FUNCTION DriverInstalled: Word; + BEGIN + // REENOTE Never gets called in Win32 + END; +{$ENDIF} + +BEGIN + FossilPort := (Liner.Comport - 1); + IF (LocalIOOnly) THEN + Exit; +{$IFDEF MSDOS} + IF (DriverInstalled <> $1954) THEN + BEGIN + ClrScr; + WriteLn('Renegade requires a FOSSIL driver.'); + Halt; + END + ELSE + ASM + Xor AL,AL + Mov BL,Liner.MFlags + And BL,00000100b + Jz @Label1 + Mov AL,2 + @Label1: + And BL,00000010b + Jz @Label2 + Add AL,9 + @Label2: + Mov DX,FossilPort + Mov AH,$F + PushF + Call Interrupt14 + END; +{$ENDIF} +{$IFDEF WIN32} + if (DidInit) then Exit; + if (DidClose) then Exit; + DidInit := true; + EleNorm.Com_StartUp(2); + EleNorm.Com_SetDontClose(false); + EleNorm.Com_OpenQuick(answerbaud); // REENOTE Should come up with a better solution, this works for now though +{$ENDIF} + Com_Set_Speed(Liner.InitBaud); +END; + +{$IFDEF MSDOS} +PROCEDURE CheckHangup; ASSEMBLER; +ASM + Cmp LocalIOOnly,1 + Je @GetOut + Cmp OutCom,1 (* Should this be 0 *) + Jne @GetOut + Mov DX,FossilPort + Mov AH,3 + PushF + Call Interrupt14 + And AL,10000000b {test} + Jnz @GetOut + Mov HangUp,1 + @GetOut: +END; +{$ENDIF} +{$IFDEF WIN32} +PROCEDURE CheckHangup; +BEGIN + if (LocalIOOnly) then Exit; + if Not(OutCom) then Exit; + + if Not(Com_Carrier) then + begin + HangUp := true; + HungUp := true; + end; +END; +{$ENDIF} + +(* +AH = 19h Write block (transfer from user buffer to FOSSIL) +Parameters: + Entry: CX = Maximum number of characters to transfer + DX = Port number + ES = Segment of user buffer + DI = Offset into ES of user buffer + Exit: AX = Number of characters actually transferred + A "no-wait" block move of 0 to FFFFh characters from the calling + program's buffer into the FOSSIL outbound ring buffer. ES:DI are left + unchanged by the call; the count of bytes actually transferred will be + returned in AX. +*) + +PROCEDURE SerialOut(S: STRING); +VAR + T_DI, + T_CX, + T_ES, + T_AX: Word; +BEGIN + IF (OutCom) THEN + BEGIN +{$IFDEF MSDOS} + REPEAT + T_DI := OFS(S[1]); + T_CX := Length(S); + T_ES := Seg(S[1]); + ASM + Mov AH,19h + Mov DI,T_DI + Mov CX,T_CX + Mov DX,FossilPort + Mov ES,T_ES + Int 14h + Mov T_AX,AX + END; + Move(S[T_AX + 1],S[1],Length(S) - T_AX); + Dec(S[0],T_AX); + UNTIL (S = ''); +{$ENDIF} +{$IFDEF WIN32} + if Not(DidInit) then Exit; + if (DidClose) then Exit; + if Not(EleNorm.Com_Carrier) then Exit; + EleNorm.Com_SendString(S); +{$ENDIF} + END; +END; + +(* +AH = 03h Request status +Parameters: + Entry: DX = Port number + Exit: AX = Status bit mask (see below) +Returns with the line and modem status in AX. Status bits returned are: +In AH: +Bit 0 = RDA - input data is available in buffer +Bit 1 = OVRN - the input buffer has been overrun. All characters received + after the buffer is full should be discarded. +Bit 5 = THRE - room is available in output buffer +Bit 6 = TSRE - output buffer is empty +In AL: +Bit 3 = Always 1 (always return with this bit set to 1) +Bit 7 = DCD - carrier detect +This can be used by the application to determine whether carrier detect +(CD) is set, signifying the presence/absence of a remote connection, as +well as monitoring both the input and output buffer status. Bit 3 of AL +is always returned set to enable programs to use it as a carrier detect +bit on hardwired (null modem) links. +*) + +FUNCTION Empty: Boolean; +VAR + T_AH: Byte; +BEGIN + Empty := NOT KeyPressed; + IF (InCom) AND (NOT KeyPressed) THEN + BEGIN +{$IFDEF MSDOS} + ASM + Mov DX,FossilPort + Mov AH,03h + Int 14h + Mov T_AH,AH + END; + Empty := NOT (T_AH AND 1 = 1); +{$ENDIF} +{$IFDEF WIN32} + if Not(DidInit) then Exit; + if (DidClose) then Exit; + if Not(EleNorm.Com_Carrier) then Exit; + Empty := Not(EleNorm.Com_CharAvail); +{$ENDIF} + END; +END; + +(* +AH = 06h Raise/lower DTR +Parameters: + Entry: DX = Port number + AL = DTR state to be set (01h = Raise, 00h = Lower) + Exit: None +This function is used to control the DTR line to the modem. AL = 00h means +lower DTR (disable the modem), and AL = 01h means to raise DTR (enable the +modem). No other function (except Init) should alter DTR. +*) + +PROCEDURE DTR(Status: Boolean); +VAR + T_AL: Byte; +BEGIN + IF (NOT LocalIOOnly) THEN + BEGIN + T_AL := Byte(Status); +{$IFDEF MSDOS} + ASM + Mov AH,06h + Mov DX,FossilPort + Mov AL,T_AL + Int 14h + END; +{$ENDIF} +{$IFDEF WIN32} + if Not(DidInit) then Exit; + if (DidClose) then Exit; + if Not(EleNorm.Com_Carrier) then Exit; + if Not(Status) then + begin + EleNorm.Com_Close; + DidClose := true; + end; +{$ENDIF} + END; +END; + +END. diff --git a/SOURCE/COMMON5.PAS b/SOURCE/COMMON5.PAS new file mode 100644 index 0000000..2126279 --- /dev/null +++ b/SOURCE/COMMON5.PAS @@ -0,0 +1,533 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S-,V-} + +UNIT Common5; + +INTERFACE + +USES + Common; + +PROCEDURE FileAreaScanInput(DisplayStr: AStr; MaxLen: Byte; VAR S: AStr; CONST Allowed: AStr; MinNum,MaxNum: Integer); +PROCEDURE MsgAreaScanInput(DisplayStr: AStr; MaxLen: Byte; VAR S: AStr; CONST Allowed: AStr; MinNum,MaxNum: Integer); + +IMPLEMENTATION + +USES + Crt; + +PROCEDURE ANSIG(X,Y: Byte); +BEGIN + IF (ComPortSpeed > 0) THEN + IF (OkAvatar) THEN + SerialOut(^V^H+Chr(Y)+Chr(X)) + ELSE + SerialOut(#27+'['+IntToStr(Y)+';'+IntToStr(X)+'H'); + IF (WantOut) THEN + GoToXY(X,Y); +END; + +FUNCTION CmdExists(Num: Integer): Boolean; +VAR + Counter: Byte; + Found: Boolean; +BEGIN + Found := FALSE; + FOR Counter := 1 TO LightBarCounter DO + IF (LightBarArray[Counter].CmdToExec = Num) THEN + BEGIN + Found := TRUE; + Break; + END; + CmdExists := Found; +END; + +PROCEDURE FileAreaScanInput(DisplayStr: AStr; MaxLen: Byte; VAR S: AStr; CONST Allowed: AStr; MinNum,MaxNum: Integer); +VAR + SaveS: AStr; + C: Char; + Counter, + SaveX, + SaveY: Byte; + W: Word; + GotCmd: Boolean; +BEGIN + Prt(DisplayStr); + MPL(MaxLen); + + IF (LightBarFirstCmd) THEN + LightBarCmd := 1 + ELSE + LightBarCmd := LightBarCounter; + + IF (General.UseFileAreaLightBar) AND (FileAreaLightBar IN ThisUser.SFlags) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END; + + GotCmd := FALSE; + + s := ''; + + REPEAT + + W := GetKey; + + IF (General.UseFileAreaLightBar) AND (FileAreaLightBar IN ThisUser.SFlags) THEN + BEGIN + IF (W = 13) AND (S = '') THEN + BEGIN + S := IntToStr(LightBarArray[LightBarCmd].CmdToExec); + GotCmd := TRUE; + END + ELSE IF (W = 91) THEN + BEGIN + IF (CmdExists(MinNum)) THEN + W := 0 + ELSE + BEGIN + S := '['; + LightBarFirstCmd := FALSE; + GotCmd := TRUE + END; + END + ELSE IF (W = 93) THEN + BEGIN + IF (CmdExists(MaxNum)) THEN + W := 0 + ELSE + BEGIN + S := ']'; + LightBarFirstCmd := TRUE; + GotCmd := TRUE + END + END + ELSE IF (W = F_Home) AND (LightBarCmd <> 1) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + LightBarCmd := 1; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END + ELSE IF (W = F_End) AND (LightBarCmd <> LightBarCounter) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + LightBarCmd := LightBarCounter; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END + ELSE IF (W = F_Left) THEN + BEGIN + IF (LightBarCmd = 1) AND (LightBarArray[LightBarCmd].CmdToExec <> MinNum) THEN + BEGIN + S := '['; + LightBarFirstCmd := FALSE; + GotCmd := TRUE + END + ELSE IF (LightBarCmd > 1) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + Dec(LightBarCmd); + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END; + END + ELSE IF (W = F_Right) THEN + BEGIN + IF (LightBarCmd = LightBarCounter) AND (LightBarArray[LightBarCmd].CmdToExec <> MaxNum) THEN + BEGIN + S := ']'; + LightBarFirstCmd := TRUE; + GotCmd := TRUE + END + ELSE IF (LightBarCmd < LightBarCounter) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + Inc(LightBarCmd); + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END; + END + ELSE IF (W = F_Up) THEN + BEGIN + IF (LightBarCmd = 1) AND (LightBarArray[LightBarCmd].CmdToExec <> MinNum) THEN + BEGIN + S := '['; + LightBarFirstCmd := FALSE; + GotCmd := TRUE + END + ELSE IF ((LightBarCmd - 2) >= 1) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + Dec(LightBarCmd,2); + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END + END + ELSE IF (W = F_Down) THEN + BEGIN + IF (LightBarCmd = LightBarCounter) AND (LightBarArray[LightBarCmd].CmdToExec <> MaxNum) THEN + BEGIN + S := ']'; + LightBarFirstCmd := TRUE; + GotCmd := TRUE + END + ELSE IF ((LightBarCmd + 2) <= LightBarCounter) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + Inc(LightBarCmd,2); + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END; + END; + END; + + C := UpCase(Char(W)); + + SaveS := s; + + IF ((Pos(c,Allowed) <> 0) AND (s = '')) THEN + BEGIN + GotCmd := TRUE; + s := c; + END + ELSE IF (Pos(c,'0123456789') > 0) OR (c = '-') THEN + BEGIN + IF ((Length(s) < 6) OR ((Pos('-',s) > 0) AND (Length(s) < 11))) THEN + s := s + c; + END + ELSE IF ((s <> '') AND (c = ^H)) THEN + Dec(s[0]) + ELSE IF (c = ^X) THEN + BEGIN + FOR Counter := 1 TO Length(s) DO + BackSpace; + s := ''; + SaveS := ''; + END + ELSE IF (c = #13) AND (S <> '') THEN + BEGIN + IF (S = '-') THEN + BEGIN + BackSpace; + S := ''; + SaveS := ''; + END + ELSE + GotCmd := TRUE; + END; + IF (Length(s) < Length(SaveS)) THEN + BackSpace; + IF (Length(s) > Length(SaveS)) THEN + Prompt(s[Length(s)]); + UNTIL (GotCmd) OR (HangUp); + + IF (General.UseFileAreaLightBar) AND (FileAreaLightBar IN ThisUser.SFlags) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + END; + + UserColor(1); + NL; +END; + +PROCEDURE MsgAreaScanInput(DisplayStr: AStr; MaxLen: Byte; VAR S: AStr; CONST Allowed: AStr; MinNum,MaxNum: Integer); +VAR + SaveS: AStr; + C: Char; + Counter, + SaveX, + SaveY: Byte; + W: Word; + GotCmd: Boolean; +BEGIN + Prt(DisplayStr); + MPL(MaxLen); + + IF (LightBarFirstCmd) THEN + LightBarCmd := 1 + ELSE + LightBarCmd := LightBarCounter; + + IF (General.UseMsgAreaLightBar) AND (MsgAreaLightBar IN ThisUser.SFlags) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END; + + GotCmd := FALSE; + + s := ''; + + REPEAT + + W := GetKey; + + IF (General.UseMsgAreaLightBar) AND (MsgAreaLightBar IN ThisUser.SFlags) THEN + BEGIN + IF (W = 13) AND (S = '') THEN + BEGIN + S := IntToStr(LightBarArray[LightBarCmd].CmdToExec); + GotCmd := TRUE; + END + ELSE IF (W = 91) THEN + BEGIN + IF (CmdExists(MinNum)) THEN + W := 0 + ELSE + BEGIN + S := '['; + LightBarFirstCmd := FALSE; + GotCmd := TRUE + END; + END + ELSE IF (W = 93) THEN + BEGIN + IF (CmdExists(MaxNum)) THEN + W := 0 + ELSE + BEGIN + S := ']'; + LightBarFirstCmd := TRUE; + GotCmd := TRUE + END + END + ELSE IF (W = F_Home) AND (LightBarCmd <> 1) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + LightBarCmd := 1; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END + ELSE IF (W = F_End) AND (LightBarCmd <> LightBarCounter) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + LightBarCmd := LightBarCounter; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END + ELSE IF (W = F_Left) THEN + BEGIN + IF (LightBarCmd = 1) AND (LightBarArray[LightBarCmd].CmdToExec <> MinNum) THEN + BEGIN + S := '['; + LightBarFirstCmd := FALSE; + GotCmd := TRUE + END + ELSE IF (LightBarCmd > 1) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + Dec(LightBarCmd); + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END; + END + ELSE IF (W = F_Right) THEN + BEGIN + IF (LightBarCmd = LightBarCounter) AND (LightBarArray[LightBarCmd].CmdToExec <> MaxNum) THEN + BEGIN + S := ']'; + LightBarFirstCmd := TRUE; + GotCmd := TRUE + END + ELSE IF (LightBarCmd < LightBarCounter) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + Inc(LightBarCmd); + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END; + END + ELSE IF (W = F_Up) THEN + BEGIN + IF (LightBarCmd = 1) AND (LightBarArray[LightBarCmd].CmdToExec <> MinNum) THEN + BEGIN + S := '['; + LightBarFirstCmd := FALSE; + GotCmd := TRUE + END + ELSE IF ((LightBarCmd - 2) >= 1) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + Dec(LightBarCmd,2); + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END + END + ELSE IF (W = F_Down) THEN + BEGIN + IF (LightBarCmd = LightBarCounter) AND (LightBarArray[LightBarCmd].CmdToExec <> MaxNum) THEN + BEGIN + S := ']'; + LightBarFirstCmd := TRUE; + GotCmd := TRUE + END + ELSE IF ((LightBarCmd + 2) <= LightBarCounter) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + Inc(LightBarCmd,2); + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(114); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + SetC(31); + END; + END; + END; + + C := UpCase(Char(W)); + + SaveS := s; + + IF ((Pos(c,Allowed) <> 0) AND (s = '')) THEN + BEGIN + GotCmd := TRUE; + s := c; + END + ELSE IF (Pos(c,'0123456789') > 0) OR (c = '-') THEN + BEGIN + IF ((Length(s) < 6) OR ((Pos('-',s) > 0) AND (Length(s) < 11))) THEN + s := s + c; + END + ELSE IF ((s <> '') AND (c = ^H)) THEN + Dec(s[0]) + ELSE IF (c = ^X) THEN + BEGIN + FOR Counter := 1 TO Length(s) DO + BackSpace; + s := ''; + SaveS := ''; + END + ELSE IF (c = #13) AND (S <> '') THEN + BEGIN + IF (S = '-') THEN + BEGIN + BackSpace; + S := ''; + SaveS := ''; + END + ELSE + GotCmd := TRUE; + END; + IF (Length(s) < Length(SaveS)) THEN + BackSpace; + IF (Length(s) > Length(SaveS)) THEN + Prompt(s[Length(s)]); + UNTIL (GotCmd) OR (HangUp); + + IF (General.UseMsgAreaLightBar) AND (MsgAreaLightBar IN ThisUser.SFlags) THEN + BEGIN + SaveX := WhereX; + SaveY := WhereY; + ANSIG(LightBarArray[LightBarCmd].XPos,LightBarArray[LightBarCmd].YPos); + SetC(10); + Prompt(PadLeftStr(LightBarArray[LightBarCmd].CmdToShow,32)); + ANSIG(SaveX,SaveY); + END; + + UserColor(1); + NL; +END; + +END. + diff --git a/SOURCE/CUSER.PAS b/SOURCE/CUSER.PAS new file mode 100644 index 0000000..a7f1ab4 --- /dev/null +++ b/SOURCE/CUSER.PAS @@ -0,0 +1,1029 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT CUser; + +INTERFACE + +USES + Common; + +PROCEDURE CStuff(Which,How: Byte; VAR User: UserRecordType); + +IMPLEMENTATION + +USES + Dos, + Archive1, + TimeFunc, + MiscUser; + +VAR + CallFromArea: Integer; + +PROCEDURE CStuff(Which,How: Byte; VAR User: UserRecordType); +VAR + Try: Byte; + Done, + Done1: Boolean; + + PROCEDURE FindArea; + VAR + Cmd: Char; + BEGIN + Print('Are you calling from:'); + NL; + Print('(1) United States'); + Print('(2) Canada'); + Print('(3) Other country'); + NL; + Prt('Select (1-3): '); + OneK(Cmd,'123',TRUE,TRUE); + CallFromArea := (Ord(Cmd) - 48); + Done1 := TRUE; + END; + + PROCEDURE ConfigureQWK; + VAR + ArcExt: Str3; + AType: Byte; + BEGIN + IF (User.DefArcType < 1) OR (User.DefArcType > MaxArcs) THEN + User.DefArcType := 1; + Print('Current archive type: ^5'+General.FileArcInfo[User.DefArcType].Ext); + NL; + REPEAT + Prt('Archive type to use? (?=List): '); + MPL(3); + Input(ArcExt,3); + IF (ArcExt = '?') THEN + BEGIN + NL; + ListArcTypes; + NL; + END; + UNTIL (ArcExt <> '?') OR (HangUp); + IF (StrToInt(ArcExt) <> 0) THEN + AType := StrToInt(ArcExt) + ELSE + AType := ArcType('F.'+ArcExt); + IF (AType > 0) AND (AType < MaxArcs) THEN + User.DefArcType := AType; + Done1 := TRUE; + NL; + User.GetOwnQWK := PYNQ('Do you want your own replies in your QWK packet? ',0,FALSE); + NL; + User.ScanFilesQWK := PYNQ('Would you like a new files listing in your QWK packet? ',0,FALSE); + NL; + User.PrivateQWK := PYNQ('Do you want your private mail in your QWK packet? ',0,FALSE); + NL; + END; + + PROCEDURE DoAddress; + VAR + TempStreet: Str30; + BEGIN + Print('Enter your street address:'); + Prt(': '); + MPL((SizeOf(User.Street) - 1)); + IF (How = 3) THEN + InputL(TempStreet,(SizeOf(User.Street) - 1)) + ELSE + InputCaps(TempStreet,(SizeOf(User.Street) - 1)); + IF (TempStreet <> '') THEN + BEGIN + IF (How = 2) THEN + SysOpLog('Changed address from '+User.Street+' to '+TempStreet); + User.Street := TempStreet; + Done1 := TRUE; + END; + END; + + PROCEDURE DoAge; + VAR + TempDate: Str10; + TempDay, + TempMonth, + TempYear, + CurYear: Word; + Redo: Boolean; + BEGIN + GetYear(CurYear); + IF (How = 1) AND (IEMSIRec.BDate <> '') THEN + BEGIN + Buf := IEMSIRec.BDate; + IEMSIRec.BDate := ''; + END; + REPEAT + Redo := False; + Print('Enter your date of birth (mm/dd/yyyy):'); + Prt(': '); + InputFormatted('',TempDate,'##/##/####',(How = 3)); + IF (TempDate <> '') THEN + BEGIN + TempMonth := StrToInt(Copy(TempDate,1,2)); + TempDay := StrToInt(Copy(TempDate,4,2)); + TempYear := StrToInt(Copy(TempDate,7,4)); + IF (TempMonth = 0) OR (TempDay = 0) OR (TempYear = 0) THEN + ReDo := TRUE; + IF (TempMonth > 12) THEN + Redo := TRUE; + IF (TempMonth IN [1,3,5,7,8,10,12]) AND (TempDay > 31) THEN + Redo := TRUE; + IF (TempMonth IN [4,6,9,11]) AND (TempDay > 30) THEN + Redo := TRUE; + IF (TempMonth = 2) AND ((TempYear MOD 4) <> 0) AND (TempDay > 28) THEN + Redo := TRUE; + IF (TempMonth = 2) AND ((TempYear MOD 4) = 0) AND (TempDay > 29) THEN + Redo := TRUE; + IF (TempYear >= CurYear) THEN + Redo := TRUE; + IF (TempYear < (CurYear - 100)) THEN + Redo := TRUE; + IF (Redo) THEN + BEGIN + NL; + Print('^7You entered an invalid date of birth!^1'); + NL; + END; + END; + UNTIL (NOT Redo) OR (HangUp); + IF (TempDate <> '') THEN + BEGIN + IF (How = 2) THEN + SysOpLog('Changed birthdate from '+PD2Date(User.BirthDate)+' to '+TempDate); + User.BirthDate := Date2PD(TempDate); + END; + Done1 := TRUE; + END; + + PROCEDURE DoCityState; + VAR + s, + s1, + s2: AStr; + BEGIN + CASE How OF + 2 : FindArea; + 3 : CallFromArea := 1; + END; + IF (CallFromArea <> 3) THEN + BEGIN + IF (How = 3) THEN + BEGIN + Print('Enter new city & state abbreviation:'); + Prt(': '); + MPL((SizeOf(User.CityState) - 1)); + InputL(s,(SizeOf(User.CityState) - 1)); + IF (s <> '') THEN + User.CityState := s; + Done1 := TRUE; + Exit; + END; + + Print('Enter only your city:'); + Prt(': '); + MPL(((SizeOf(User.CityState) - 1) - 4)); + InputCaps(s,((SizeOf(User.CityState) - 1) - 4)); + IF (Pos(',',s) <> 0) THEN + BEGIN + NL; + Print('^7Enter only your city name.^1'); + Exit; + END; + NL; + IF (Length(s) < 3) THEN + Exit; + Prompt('Enter your '+AOnOff((CallFromArea = 1),'state','province')+' abbreviation: '); + MPL(2); + Input(s1,2); + User.CityState := s+', '+s1; + Done1 := TRUE; + END + ELSE + BEGIN + Print('First enter your city name only:'); + Prt(': '); + MPL(26); + InputCaps(s1,26); + IF (Length(s1) < 2) THEN + Exit; + NL; + Print('Now enter your country name:'); + Prt(': '); + MPL(26); + InputCaps(s2,26); + IF (Length(s2) < 2) THEN + Exit; + s := s1+', '+s2; + IF (Length(s) > 30) THEN + BEGIN + Print('^7Max total Length is 30 characters!^1'); + Exit; + END; + IF (How = 2) AND (User.CityState <> s) THEN + SysOpLog('Changed city/state from '+User.CityState+' to '+s); + User.CityState := s; + Done1 := TRUE; + END; + END; + + PROCEDURE DoUserDef(QuestionNum: Byte); + VAR + UserDefQues: STRING[80]; + s: Str35; + BEGIN + CASE QuestionNum OF + 1 : UserDefQues := lRGLngStr(38,TRUE); {'Is ALL of your information REAL & CORRECT? (Yes/No)'} + 2 : UserDefQues := lRGLngStr(39,TRUE); {'Do you run a Telnet BBS? (If so, type in address below)'} + 3 : UserDefQues := lRGLngStr(40,TRUE); {'What BBS or Web Site did you hear about this BBS? (Specific Please)'} + END; + IF (UserDefQues = '') THEN + BEGIN + User.UsrDefStr[QuestionNum] := ''; + Done1 := TRUE; + Exit; + END; + Print(UserDefQues); + Prt(': '); + MPL((SizeOf(User.UsrDefStr[QuestionNum]) - 1)); + InputL(s,(SizeOf(User.UsrDefStr[QuestionNum]) - 1)); + IF (s <> '') THEN + BEGIN + User.UsrDefStr[QuestionNum] := s; + Done1 := TRUE; + END; + END; + + PROCEDURE DoName; + VAR + TextFile: Text; + s, + s1, + s2: AStr; + UNum: Integer; + BEGIN + IF (How = 1) THEN + IF (General.AllowAlias) AND (IEMSIRec.Handle <> '') THEN + BEGIN + Buf := IEMSIRec.Handle; + IEMSIRec.Handle := ''; + END + ELSE IF (IEMSIRec.UserName <> '') THEN + BEGIN + Buf := IEMSIRec.UserName; + IEMSIRec.UserName := ''; + END; + IF (General.AllowAlias) THEN + BEGIN + Print('Enter your handle, or your real first & last'); + Print('names if you don''t want to use one.') + END + ELSE + BEGIN + Print('Enter your first & last Name.'); + Print('Handles are not allowed.'); + END; + Prt(': '); + MPL((SizeOf(User.Name) - 1)); + Input(s,(SizeOf(User.Name) -1)); + Done1 := FALSE; + WHILE (s[1] IN [' ','0'..'9']) AND (Length(s) > 0) do + Delete(s,1,1); + WHILE (s[Length(s)] = ' ') do + Dec(s[0]); + IF ((Pos(' ',s) = 0) AND (How <> 3) AND NOT (General.AllowAlias)) THEN + BEGIN + NL; + Print('Enter your first and last Name!'); + s := ''; + END; + IF (s <> '') THEN + BEGIN + Done1 := TRUE; + UNum := SearchUser(s,TRUE); + IF (UNum > 0) AND (UNum <> UserNum) THEN + BEGIN + Done1 := FALSE; + NL; + Print('^7That name is in use.^1'); + END; + END; + Assign(TextFile,General.MiscPath+'TRASHCAN.TXT'); + Reset(TextFile); + IF (IOResult = 0) THEN + BEGIN + s2 := ' '+s+' '; + WHILE NOT EOF(TextFile) do + BEGIN + ReadLn(TextFile,s1); + IF (s1[Length(s1)] = #1) THEN + s1[Length(s1)] := ' ' + ELSE + s1 := s1 + ' '; + s1 := ' ' + s1; + S1 := AllCaps(S1); + IF (Pos(s1,s2) <> 0) THEN + Done1 := FALSE; + END; + Close(TextFile); + LastError := IOResult; + END; + IF (NOT Done1) AND (NOT HangUp) THEN + BEGIN + NL; + Print(^G'^7Sorry, can''t use that name.^1'); + Inc(Try); + sl1('Unacceptable Name : '+s); + END; + IF (Try >= 3) AND (How = 1) THEN + HangUp := TRUE; + + IF ((Done) AND (How = 1) AND (NOT General.AllowAlias)) THEN + User.RealName := Caps(s); + + IF (Done1) THEN + BEGIN + IF (How = 2) AND (UserNum > -1) THEN { Don't do index on unregged users! } + BEGIN + SysOpLog('Changed name from '+User.Name+' to '+s); + InsertIndex(User.Name,UserNum,FALSE,TRUE); + User.Name := s; + InsertIndex(User.Name,UserNum,FALSE,FALSE); + END + ELSE + User.Name := s; + END; + END; + + PROCEDURE DoPhone; + VAR + TempPhone: AStr; + BEGIN + CASE How OF + 1 : BEGIN + IF (IEMSIRec.Ph <> '') THEN + BEGIN + Buf := IEMSIRec.Ph; + IEMSIRec.Ph := ''; + END; + END; + 2 : FindArea; + 3 : CallFromArea := 1; + END; + Print('Enter your phone number:'); + Prt(': '); + IF (((How = 1) AND (CallFromArea = 3)) OR (How = 3)) THEN + BEGIN + MPL(12); + Input(TempPhone,12); + IF (Length(TempPhone) > 5) THEN + BEGIN + User.Ph := TempPhone; + Done1 := TRUE; + END; + END + ELSE + BEGIN + InputFormatted('',TempPhone,'(###)###-####',FALSE); + TempPhone[5] := '-'; + TempPhone := Copy(TempPhone,2,(Length(TempPhone) - 1)); + IF (How = 2) AND (User.Ph <> TempPhone) THEN + SysOpLog('Changed phone from '+User.Ph+' to '+TempPhone); + User.Ph := TempPhone; + Done1 := TRUE; + END; + END; + + PROCEDURE DoPW; + VAR + s, + s2: STRING[20]; + SavePW: LongInt; + BEGIN + IF (How = 1) AND (IEMSIRec.PW <> '') THEN + BEGIN + Buf := IEMSIRec.PW; + IEMSIRec.PW := ''; + END; + SavePW := User.PW; + IF (How = 2) THEN + BEGIN + Print('^5Enter your current password:'); + NL; + Prompt('Password: ^5'); + GetPassword(s,20); + IF (CRC32(s) <> User.PW) THEN + BEGIN + NL; + Print('Wrong!'); + NL; + Exit; + END; + END; + REPEAT + REPEAT + Print('Enter your desired password for future access.'); + Print('It should be 4 to 20 characters in length.'); + NL; + Prompt('Password: '); + MPL(20); + GetPassword(s,20); + NL; + IF (Length(s) < 4) THEN + BEGIN + Print('^7Must be at least 4 characters long!^1'); + NL; + END + ELSE IF (Length(s) > 20) THEN + BEGIN + Print('^7Must be no more than 20 characters long.^1'); + NL; + END + ELSE IF (How = 3) AND (CRC32(s) = SavePW) THEN + BEGIN + Print('^7Must be different from your old password!^1'); + NL; + s := ''; + END + ELSE IF (s = ThisUser.Name) OR (s = ThisUser.RealName) THEN + BEGIN + Print('^7You cannot use that password!^1'); + NL; + s := ''; + END; + UNTIL (((Length(s) > 3) AND (Length(s) < 21)) OR (HangUp)); + Print('Enter your password again for verification:'); + NL; + Prompt('Password: '); + MPL(20); + GetPassword(s2,20); + IF (s2 <> s) THEN + BEGIN + NL; + Print('^7Passwords do not match!^1'); + NL; + END; + UNTIL ((s2 = s) OR (HangUp)); + IF (HangUp) AND (How = 3) THEN + User.PW := SavePW + ELSE + User.PW := CRC32(s); + User.PasswordChanged := DayNum(DateStr); + IF (How = 2) THEN + BEGIN + NL; + Print('Password changed.'); + SysOpLog('Changed password.'); + END; + Done1 := TRUE; + END; + + PROCEDURE DoForgotPW; + VAR + s: AStr; + BEGIN + IF (How IN [1..2]) THEN + BEGIN + REPEAT + s := ''; + Print('This question will be asked should you ever forget your password.'); + NL; + Print(General.forgotpwquestion); + Prt(': '); + MPL(40); + Input(s,40); + UNTIL (s <> '') OR (HangUp); + User.ForgotPWAnswer := s; + Done1 := TRUE; + END; + END; + + PROCEDURE DoRealName; + VAR + TempRealName: AStr; + UNum: Integer; + BEGIN + IF (How = 1) THEN + IF (NOT General.AllowAlias) THEN + BEGIN + User.RealName := Caps(User.Name); + Done1 := TRUE; + Exit; + END + ELSE IF (IEMSIRec.UserName <> '') THEN + BEGIN + Buf := IEMSIRec.UserName; + IEMSIRec.UserName := ''; + END; + Print('Enter your real first & last name:'); + Prt(': '); + MPL((SizeOf(User.RealName) - 1)); + IF (How = 3) THEN + InputL(TempRealName,(SizeOf(User.RealName) - 1)) + ELSE + InputCaps(TempRealName,(SizeOf(User.RealName) - 1)); + WHILE (TempRealName[1] IN [' ','0'..'9']) AND (Length(TempRealName) > 0) do + Delete(TempRealName,1,1); + WHILE (TempRealName[Length(TempRealName)] = ' ') do + Dec(TempRealName[0]); + IF (Pos(' ',TempRealName) = 0) AND (How <> 3) THEN + BEGIN + NL; + Print('Enter your first and last name!'); + TempRealName := ''; + END; + IF (TempRealName <> '') THEN + BEGIN + Done1 := TRUE; + UNum := SearchUser(TempRealName,TRUE); + IF (UNum > 0) AND (UNum <> UserNum) THEN + BEGIN + Done1 := FALSE; + NL; + Print('^7That name is in use.^1'); + END; + END; + IF (Done1) THEN + BEGIN + IF (How = 2) AND (UserNum > -1) THEN { don't do index on unregged users! } + BEGIN + SysOpLog('Changed real name from '+User.RealName+' to '+TempRealName); + InsertIndex(User.RealName,UserNum,TRUE,TRUE); + User.RealName := TempRealName; + InsertIndex(User.RealName,UserNum,TRUE,FALSE); + END + ELSE + User.RealName := TempRealName; + Done1 := TRUE; + END; + END; + + PROCEDURE DoScreen; + BEGIN + InputByteWOC('How wide is your screen',User.LineLen,[DisplayValue,NumbersOnly],32,132); + InputByteWOC('%LFHow many lines per page',User.PageLen,[DisplayValue,NumbersOnly],4,50); + Done1 := TRUE; + END; + + PROCEDURE DoSex; + VAR + Cmd: Char; + BEGIN + IF (How = 3) THEN + BEGIN + Prt('New gender (M,F): '); + OneK(Cmd,'MF '^M,TRUE,TRUE); + IF (Cmd IN ['M','F']) THEN + User.Sex := Cmd; + END + ELSE + BEGIN + User.Sex := #0; + Prt('Your gender (M,F)? '); + OneK(User.Sex,'MF',TRUE,TRUE); + END; + Done1 := TRUE; + END; + + PROCEDURE DoZIPCode; + VAR + TempZipCode: Str10; + BEGIN + IF (How = 3) THEN + BEGIN + FindArea; + NL; + END; + CASE CallFromArea OF + 1 : BEGIN + Print('Enter your zipcode (#####-####):'); + Prt(': '); + InputFormatted('',TempZipCode,'#####-####',(How = 3)); + IF (TempZipCode <> '') THEN + User.ZipCode := TempZipCode; + Done1 := TRUE; + END; + 2 : BEGIN + Print('Enter your postal code (LNLNLN format)'); + Prt(': '); + InputFormatted('',TempZipCode,'@#@#@#',(How = 3)); + IF (TempZipCode <> '') THEN + User.ZipCode := TempZipCode; + Done1 := TRUE + END; + 3 : BEGIN + Print('Enter your postal code:'); + Prt(': '); + MPL((SizeOf(User.ZipCode) - 1)); + Input(TempZipCode,(SizeOf(User.ZipCode) - 1)); + IF (Length(TempZipCode) > 2) THEN + BEGIN + User.ZipCode := TempZipCode; + Done1 := TRUE; + END; + END; + END; + END; + + PROCEDURE ForwardMail; + VAR + User1: UserRecordType; + Unum: Integer; + BEGIN + NL; + Print('^5If you forward your mail, all email sent to your account^1'); + Print('^5will be redirected to that person.^1'); + NL; + Print('Enter User Number, Name, or Partial Search String.'); + Prt(': '); + lFindUserWS(UNum); + IF (UNum < 1) OR (UNum > (MaxUsers - 1)) THEN + User.ForUsr := 0 + ELSE + BEGIN + LoadURec(User1,UNum); + IF (User.Name = User1.Name) OR (LockedOut IN User1.SFlags) OR + (Deleted IN User1.SFlags) OR (NoMail IN User1.Flags) THEN + BEGIN + NL; + Print('^7You can not forward mail to that user!^1'); + END + ELSE + BEGIN + User.ForUsr := UNum; + NL; + Print('Forwarding mail to: ^5'+Caps(User1.Name)+' #'+IntToStr(UNum)+'^1'); + SysOpLog('Forwarding mail to: ^5'+Caps(User1.Name)+' #'+IntToStr(UNum)); + END; + END; + IF (How = 3) THEN + PauseSCr(FALSE); + END; + + PROCEDURE MailBox; + BEGIN + IF (NoMail IN User.Flags) THEN + BEGIN + Exclude(User.Flags,NoMail); + Print('Mail box is now open.'); + IF (How = 3) THEN + PauseScr(FALSE); + SysOpLog('Mail box is now open.'); + END + ELSE IF (User.ForUsr <> 0) THEN + BEGIN + User.ForUsr := 0; + Print('Mail is no longer being forwarded.'); + IF (How = 3) THEN + PauseSCr(FALSE); + SysOpLog('Mail forwarding ended.'); + END + ELSE + BEGIN + IF PYNQ('Do you want to close your mail box? ',0,FALSE) THEN + BEGIN + Include(User.Flags,NoMail); + NL; + Print('Mail box is now closed.'); + IF (How = 3) THEN + PauseSCr(FALSE); + SysOpLog('Mail box is now closed.'); + END + ELSE + BEGIN + NL; + IF PYNQ('Do you want to forward your mail? ',0,FALSE) THEN + ForwardMail; + END; + END; + Done1 := TRUE; + END; + + PROCEDURE Toggle_ANSI; + VAR + Cmd: Char; + BEGIN + PrintF('TERMINAL'); + Print('Which terminal emulation do you support?'); + NL; + Print('(1) None'); + Print('(2) ANSI'); + Print('(3) Avatar'); + Print('(4) VT-100'); + Print('(5) RIP Graphics'); + NL; + Prt('Select (1-5): '); + OneK(Cmd,'12345',TRUE,TRUE); + Exclude(User.Flags,ANSI); + Exclude(User.Flags,Avatar); + Exclude(User.Flags,VT100); + Exclude(User.SFlags,RIP); + CASE Cmd OF + '2' : Include(User.Flags,ANSI); + '3' : BEGIN + Include(User.Flags,Avatar); + NL; + IF PYNQ('Does your terminal program support ANSI fallback? ',0,TRUE) THEN + Include(User.Flags,ANSI); + END; + '4' : Include(User.Flags,VT100); + '5' : BEGIN + Include(User.Flags,ANSI); + Include(User.SFlags,RIP); + END; + END; + IF (ANSI IN User.Flags) OR (Avatar IN User.Flags) OR (VT100 IN User.Flags) THEN + Include(User.SFlags,FSEditor) + ELSE + Exclude(User.SFlags,FSEditor); + NL; + IF (PYNQ('Would you like this to be auto-detected in the future? ',0,TRUE)) THEN + Include(User.SFlags,AutoDetect) + ELSE + Exclude(User.SFlags,AutoDetect); + Done1 := TRUE; + END; + + PROCEDURE Toggle_Color; + BEGIN + IF (Color IN User.Flags) THEN + BEGIN + Exclude(User.Flags,Color); + Print('ANSI Color disabled.'); + END + ELSE + BEGIN + Include(User.Flags,Color); + Print('ANSI Color enabled.'); + END; + Done1 := TRUE; + END; + + PROCEDURE Toggle_Pause; + BEGIN + IF (Pause IN User.Flags) THEN + BEGIN + Exclude(User.Flags,Pause); + Print('Pause on screen disabled'); + END + ELSE + BEGIN + Include(User.Flags,Pause); + Print('Pause on screen enabled'); + END; + Done1 := TRUE; + END; + + PROCEDURE Toggle_Editor; + BEGIN + Done1 := TRUE; + IF (NOT (ANSI IN User.Flags)) AND (NOT (Avatar IN User.Flags)) THEN + BEGIN + Print('You must use ANSI to use the full screen editor.'); + Exclude(User.SFlags,FSEditor); + Exit; + END; + IF (FSEditor IN User.SFlags) THEN + BEGIN + Exclude(User.SFlags,FSEditor); + Print('Full screen editor disabled.'); + END + ELSE + BEGIN + Include(User.SFlags,FSEditor); + Print('Full screen editor enabled.'); + END; + END; + + PROCEDURE Toggle_Input; + BEGIN + IF (HotKey IN User.Flags) THEN + BEGIN + Exclude(User.Flags,HotKey); + Print('Full line input.'); + END + ELSE + BEGIN + Include(User.Flags,HotKey); + Print('Hot key input.'); + END; + Done1 := TRUE; + END; + + PROCEDURE Toggle_CLSMsg; + BEGIN + IF (CLSMsg IN User.SFlags) THEN + BEGIN + Exclude(User.SFlags,CLSMsg); + Print('Screen clearing off.'); + END + ELSE + BEGIN + Include(User.SFlags,CLSMsg); + Print('Screen clearing on.'); + END; + Done1 := TRUE; + END; + + PROCEDURE Toggle_Expert; + BEGIN + IF (Novice IN User.Flags) THEN + BEGIN + Exclude(User.Flags,Novice); + CurHelpLevel := 1; + Print('Expert mode on.'); + END + ELSE + BEGIN + Include(User.Flags,Novice); + CurHelpLevel := 2; + Print('Expert mode off.'); + END; + Done1 := TRUE; + END; + + PROCEDURE Toggle_File_Area_LightBar; + BEGIN + IF (NOT General.UseFileAreaLightBar) THEN + BEGIN + NL; + Print('File area lightbar support is not available.'); + END + ELSE + BEGIN + IF (FileAreaLightBar IN ThisUser.SFlags) THEN + BEGIN + Exclude(ThisUser.SFlags,FileAreaLightBar); + Print('File area lightbar support is now off.'); + END + ELSE + BEGIN + Include(ThisUser.SFlags,FileAreaLightBar); + Print('File area lightbar support is now on.'); + END; + END; + Done1 := TRUE; + END; + + PROCEDURE Toggle_Message_Area_LightBar; + BEGIN + IF (NOT General.UseMsgAreaLightBar) THEN + BEGIN + NL; + Print('Message area lightbar support is not available.'); + END + ELSE + BEGIN + IF (MsgAreaLightBar IN ThisUser.SFlags) THEN + BEGIN + Exclude(ThisUser.SFlags,MsgAreaLightBar); + Print('Message area lightbar support is now off.'); + END + ELSE + BEGIN + Include(ThisUser.SFlags,MsgAreaLightBar); + Print('Message area lightbar support is now on.'); + END; + END; + Done1 := TRUE; + END; + + PROCEDURE CHColors; + VAR + AScheme: SchemeRec; + i, + Onlin: SmallInt; + BEGIN + Reset(SchemeFile); + CLS; + Abort := FALSE; + Next := FALSE; + PrintACR('Available Color schemes:'); + NL; + i := 1; + Onlin := 0; + Seek(SchemeFile,0); + WHILE (FilePos(SchemeFile) < FileSize(SchemeFile)) AND (NOT Abort) AND (NOT HangUp) do + BEGIN + Read(SchemeFile,AScheme); + Inc(Onlin); + Prompt(PadLeftInt(i,2)+'. ^3'+PadLeftStr(AScheme.Description,35)); + IF (OnLin = 2) THEN + BEGIN + NL; + Onlin := 0; + END; + WKey; + Inc(i); + END; + Abort := FALSE; + Next := FALSE; + NL; + InputIntegerWOC('%LFSelect a color scheme',i,[NumbersOnly],1,FileSize(SchemeFile)); + IF (i >= 1) AND (i <= FileSize(SchemeFile)) THEN + BEGIN + ThisUser.ColorScheme := i; + Seek(SchemeFile,(i - 1)); + Read(SchemeFile,Scheme); + Done1 := TRUE; + END; + Close(SchemeFile); + LastError := IOResult; + END; + + PROCEDURE CheckWantPause; + BEGIN + IF PYNQ('Pause after each screen? ',0,TRUE) THEN + Include(User.Flags,Pause) + ELSE + Exclude(User.Flags,Pause); + Done1 := TRUE; + END; + + PROCEDURE CheckWantInput; + BEGIN + IF PYNQ('Do you want to use Hot Keys? ',0,TRUE) THEN + Include(User.Flags,HotKey) + ELSE + Exclude(User.Flags,HotKey); + Done1 := TRUE; + END; + + PROCEDURE CheckWantExpert; + BEGIN + IF PYNQ('Do you want to be in expert mode? ',0,FALSE) THEN + Exclude(User.Flags,Novice) + ELSE + Include(User.Flags,Novice); + Done1 := TRUE; + END; + + PROCEDURE CheckWantCLSMsg; + BEGIN + IF PYNQ('Clear screen before each message read? ',0,TRUE) THEN + Include(User.SFlags,CLSMsg) + ELSE + Exclude(User.SFlags,CLSMsg); + Done1 := TRUE; + END; + + PROCEDURE WW(www: Byte); + BEGIN + NL; + CASE www OF + 1 : DoAddress; + 2 : DoAge; + 3 : Toggle_ANSI; + 4 : DoCityState; + 5 : DoUserDef(1); + 6 : DoUserDef(2); + 7 : DoName; + 8 : DoPhone; + 9 : DoPW; + 10 : DoRealName; + 11 : DoScreen; + 12 : DoSex; + 13 : DoUserDef(3); + 14 : DoZIPCode; + 15 : MailBox; + 16 : Toggle_ANSI; + 17 : Toggle_Color; + 18 : Toggle_Pause; + 19 : Toggle_Input; + 20 : Toggle_CLSMsg; + 21 : CHColors; + 22 : Toggle_Expert; + 23 : FindArea; + 24 : CheckWantPause; + 25 : CheckWantInput; + 26 : Toggle_Editor; + 27 : ConfigureQWK; + 28 : CheckWantExpert; + 29 : CheckWantCLSMsg; + 30 : DoForgotPW; + 31 : Toggle_File_Area_LightBar; + 32 : Toggle_Message_Area_LightBar; + END; + END; + +BEGIN + Try := 0; + Done1 := FALSE; + CASE How OF + 1 : REPEAT + WW(Which) + UNTIL (Done1) OR (HangUp); + 2,3 : + BEGIN + WW(Which); + IF (NOT Done1) THEN + Print('Function aborted!'); + END; + END; +END; + +END. diff --git a/SOURCE/DOORS.PAS b/SOURCE/DOORS.PAS new file mode 100644 index 0000000..cade80b --- /dev/null +++ b/SOURCE/DOORS.PAS @@ -0,0 +1,772 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} +UNIT Doors; + +INTERFACE + +USES + Common; + +PROCEDURE DoDoorFunc(DropFileType: Char; MenuOption: Str50); + +IMPLEMENTATION + +USES + ExecBat, + Events, + File0, + Mail0, + SysOp12, + TimeFunc; + +PROCEDURE ShowUserName(RName: Boolean; VAR First,Last: AStr); +BEGIN + First := ''; + Last := ''; + IF (RName) THEN + BEGIN + IF (Pos(' ',ThisUser.RealName) = 0) THEN + BEGIN + First := ThisUser.RealName; + Last := ''; + END + ELSE + BEGIN + First := Copy(ThisUser.RealName,1,(Pos(' ',ThisUser.RealName) - 1)); + Last := Copy(ThisUser.RealName,(Length(First) + 2),Length(ThisUser.RealName)); + END; + END + ELSE + BEGIN + IF (Pos(' ',ThisUser.Name) = 0) THEN + BEGIN + First := ThisUser.Name; + Last := ''; + END + ELSE + BEGIN + First := Copy(ThisUser.Name,1,(Pos(' ',ThisUser.Name) - 1)); + Last := Copy(ThisUser.Name,(Length(First) + 2),Length(ThisUser.Name)); + END; + END; +END; + +(* +START POS SAVED +& LENGTH AS DESCRIPTION OF DATA +--------- ------ -------------------------------------------- +1, 2 ASCII "-1" always used by FeatherNet PRO! +3, 2 ASCII " 0" always used By FeatherNet PRO! +5, 2 ASCII "-1" if page allowed or 0 if not. +7, 2 ASCII User Number in Users file +9, 1 ASCII "Y" if Expert or "N"if Not +10, 2 ASCII "-1" if Error Correcting modem, "0" if not +12, 1 ASCII "Y" if Graphics Mode or "N" if Not +13, 1 ASCII "A" is always placed here by FeatherNet PRO! +14, 5 ASCII The DTE speed or PC to Modem baud rate +19, 5 ASCII The connect baud rate:"300-38400" or "Local" +24, 2 MKI$ User's Record # in "USERS" file +26, 15 ASCII User's FIRST Name padded with spaces +41, 12 ASCII User's Password +53, 2 MKI$ Time user logged on in Mins: (60 x Hr)+Mins +55, 2 MKI$ User's Time on today in minutes +57, 5 ASCII Time user logged on in HH:MM format. Ex: "12:30" +62, 2 MKI$ Time user allowed today in minutes +64, 2 ASCII Daily D/L Limit from pwrd file +66, 1 Chr$ Conference the user has last joined +67, 5 Bitmap Areas user has been in +72, 5 Bitmap Areas user has scanned +77, 2 MKI$i An mki$(0) used by FeatherNet PRO! +79, 2 MKI$ Currently a value of 0 is here (MKI$(0)) +81, 4 ASCII 4 Spaces are placed here +85, 25 ASCII User's Full name placed here. +110, 2 MKI$ Number of minutes user has left today +112, 1 chr$ Node user is on (actual character) +113, 5 ASCII Scheduled EVENT time +118, 2 ASCII A "-1" if EVENT is active or a " 0" +120, 2 ASCII " 0" is Placed here by FeatherNet PRO! +122, 4 MKS$ Time of day in secs format when user is on +126, 1 ASCII The Com port this node uses (0 - 8) +127, 2 ASCII Flag to let FNET PRO! know type of file xfer +129, 1 CHAR Ansi Detected Flag - Char[0] or Char[1] +130, 13 ASCII Unused by FeatherNet PRO! - SPACE filled +143, 2 MKI$ Last Area User was in (0 - 32766 possible) +145 BITMAP Not Currently Used by FeatherNet PRO! + +-------------------------------------------------------------------------------- +Some BASIC functions: +CHR$ +Writes a character (8 bit value). One byte. +MKI$ +Writes a short integer (16 bit value). Low byte then high byte. +MKS$ +I didn't want to research this, and am writing four zeroes. Anyone know? +-------------------------------------------------------------------------------- +*) + +PROCEDURE Write_PCBoard_Sys(RName: Boolean); +VAR + DoorFile: FILE; + S, + UN: STRING[50]; + i: Integer; + + PROCEDURE Dump(x: STRING); + BEGIN + BlockWrite(DoorFile,x[1],Length(x)); + END; + +BEGIN + UN := AOnOff(RName,ThisUser.RealName,ThisUser.Name); + + Assign(DoorFile,Liner.DoorPath+'PCBOARD.SYS'); + ReWrite(DoorFile,1); + Dump(AOnOff(WantOut,'-1',' 0')); + Dump(AOnOff(FALSE,'-1',' 0')); + Dump(AOnOff(SysOpAvailable,'-1',' 0')); + Dump(' 0 '); + Dump(AOnOff(Reliable,'-1',' 0')); + Dump(Copy(ShowYesNo(OkANSI OR OKAvatar),1,1)); + Dump('A'); + Dump(PadLeftInt(ComPortSpeed,5)); + Dump(AOnOff((ComPortSpeed = 0),'Local',PadLeftInt(ComPortSpeed,5))); + BlockWrite(DoorFile,UserNum,2); + Dump(PadLeftStr(Copy(UN,1,Pos(' ',UN) - 1),15)); + Dump(PadLeftStr('PASSWORD',12)); + i := 0; + BlockWrite(DoorFile,i,2); + BlockWrite(DoorFile,i,2); + Dump('00:00'); + i := General.TimeAllow[ThisUser.SL]; + BlockWrite(DoorFile,i,2); + i := General.DLKOneDay[ThisUser.SL]; + BlockWrite(DoorFile,i,2); + Dump(#0#0#0#0#0#0); + Dump(Copy(S,1,5)); + i := 0; + BlockWrite(DoorFile,i,2); + BlockWrite(DoorFile,i,2); + Dump(' '); + Dump(PadLeftStr(UN,25)); + i := (NSL DIV 60); + BlockWrite(DoorFile,i,2); + Dump(Chr(ThisNode)+'00:00'); + Dump(AOnOff(FALSE,'-1',' 0')); + Dump(AOnOff(FALSE,'-1',' 0')); + Dump(#0#0#0#0); + S := AOnOff((ComPortSpeed = 0),'0',IntToStr(Liner.Comport)); + S := S[1]+#0#0; + IF (OkANSI OR OKAvatar) THEN + S := S + #1 + ELSE + S := S + #0; + Dump(S); + Dump(DateStr); + i := 0; + BlockWrite(DoorFile,i,2); + Dump(#0#0#0#0#0#0#0#0#0#0); + Close(DoorFile); + LastError := IOResult; +END; + +(* +Node name The name of the system. +Sysop f.name The sysop's name up to the first space. +Sysop l.name The sysop's name following the first space. +Com port The serial port the modem is connected to, or 0 if logged in on console. +Baud rate The current port (DTE) rate. +Networked The number "0" +User's first name The current user's name, up to the first space. +User's last name The current user's name, following the first space. +City Where the user lives, or a blank line if unknown. +Terminal type The number "0" if TTY, or "1" if ANSI. +Security level The number 5 for problem users, 30 for regular users, 80 for Aides, and 100 for Sysops. +Minutes remaining The number of minutes left in the current user's account, limited to 546 to keep from + overflowing other software. +FOSSIL The number "-1" if using an external serial driver or "0" if using internal serial routines. +*) + +PROCEDURE Write_DorInfo1_Def(RName: Boolean); +VAR + DoorFile: Text; + First, + Last: AStr; +BEGIN + Assign(DoorFile,Liner.DoorPath+'DORINFO1.DEF'); + ReWrite(DoorFile); + WriteLn(DoorFile,StripColor(General.BBSName)); + + First := Copy(General.SysOpName,1,(Pos(' ',General.SysOpName) - 1)); + Last := SQOutSp(Copy(General.SysOpName,(Length(First) + 1),Length(General.SysOpName))); + WriteLn(DoorFile,First); + WriteLn(DoorFile,Last); + + WriteLn(DoorFile,'COM'+AOnOff((ComPortSpeed = 0),'0',IntToStr(Liner.Comport))); + WriteLn(DoorFile,IntToStr(ComPortSpeed)+' BAUD,N,8,1'); + WriteLn(DoorFile,'0'); + + ShowUserName(RName,First,Last); + + WriteLn(DoorFile,AllCaps(First)); + WriteLn(DoorFile,AllCaps(Last)); + + WriteLn(DoorFile,ThisUser.CityState); + WriteLn(DoorFile,AOnOff((OkANSI OR OKAvatar),'1','0')); + WriteLn(DoorFile,ThisUser.SL); + WriteLn(DoorFile,(NSL DIV 60)); + + WriteLn(DoorFile,'0'); + + Close(DoorFile); + LastError := IOResult; +END; + +(* +0 Line 1 : Comm type (0=local, 1=serial, 2=telnet) +0 Line 2 : Comm or socket handle +38400 Line 3 : Baud rate +Mystic 1.07 Line 4 : BBSID (software name and version) +1 Line 5 : User record position (1-based) +James Coyle Line 6 : User's real name +g00r00 Line 7 : User's handle/alias +255 Line 8 : User's security level +58 Line 9 : User's time left (in minutes) +1 Line 10: Emulation *See Below +1 Line 11: Current node number + + * The following are values we've predefined for the emulation: + + 0 = Ascii + 1 = Ansi + 2 = Avatar + 3 = RIP + 4 = Max Graphics { Not Used by RG } +*) + +PROCEDURE Write_Door32_Sys(RName: Boolean); +VAR + DoorFile: Text; + + FUNCTION ShowSpeed: AStr; + BEGIN + IF (TelNet) THEN + ShowSpeed := '2' + ELSE IF (ComportSpeed <> 0) THEN + ShowSpeed := '1' + ELSE + ShowSpeed := '0' + END; + + FUNCTION ShowEmulation: AStr; + BEGIN + IF (OkRIP) THEN + ShowEmulation := '3' + ELSE IF (OKAvatar) THEN + ShowEmulation := '2' + ELSE IF (OkANSI) THEN + ShowEmulation := '1' + ELSE + ShowEmulation := '0'; + END; + +BEGIN + Assign(DoorFile,Liner.DoorPath+'DOOR32.SYS'); + ReWrite(DoorFile); + WriteLn(DoorFile,ShowSpeed); + WriteLn(DoorFile,SockHandle); + WriteLn(DoorFile,ComPortSpeed); + WriteLn(DoorFile,'Renegade BBS '+General.Version); (* Was General.BBSName *) + WriteLn(DoorFile,UserNum); + WriteLn(DoorFile,ThisUser.RealName); + WriteLn(DoorFile,AOnOff(RName,ThisUser.RealName,Caps(ThisUser.Name))); (* Was AllCaps Name and force real name missing *) + WriteLn(DoorFile,ThisUser.SL); + WriteLn(DoorFile,(NSL DIV 60)); + WriteLn(DoorFile,ShowEmulation); (* Was "1" *) + WriteLn(DoorFile,ThisNode); + Close(DoorFile); +END; + +(* +COM1: <-- Comm Port - COM0: = LOCAL MODE +2400 <-- Baud Rate - 300 to 38400 +8 <-- Parity - 7 or 8 +1 <-- Node Number - 1 to 99 (Default to 1) +19200 <-- DTE Rate. Actual BPS rate to use. (kg) +Y <-- Screen Display - Y=On N=Off (Default to Y) +Y <-- Printer Toggle - Y=On N=Off (Default to Y) +Y <-- Page Bell - Y=On N=Off (Default to Y) +Y <-- Caller Alarm - Y=On N=Off (Default to Y) +Rick Greer <-- User Full Name +Lewisville, Tx. <-- Calling From +214 221-7814 <-- Home Phone +214 221-7814 <-- Work/Data Phone +PASSWORD <-- Password +110 *<-- Security Level +1456 <-- Total Times On +03/14/88 <-- Last Date Called +7560 <-- Seconds Remaining THIS call (for those that particular) +126 <-- Minutes Remaining THIS call +GR <-- Graphics Mode - GR=Graph, NG=Non-Graph, 7E=7,E Caller +23 <-- Page Length +Y <-- User Mode - Y = Expert, N = Novice +1,2,3,4,5,6,7 <-- Conferences/Forums Registered In (ABCDEFG) +7 <-- Conference Exited To \cf1\f1 DOOR\cf0 From (G) +01/01/99 <-- User Expiration Date (mm/dd/yy) +1 <-- User File's Record Number +Y <-- Default Protocol - X, C, Y, G, I, N, Etc. +0 *<-- Total Uploads +0 *<-- Total Downloads +0 *<-- Daily Download "K" Total +999999 <-- Daily Download Max. "K" Limit +10/22/88 <-- Caller's Birthdate (kg) +G:\\GAP\\MAIN <-- Path to the MAIN directory (where User File is) (kg) +G:\\GAP\\GEN <-- Path to the GEN directory (kg) +Michael <-- Sysop's Name (name \cf1 BBS\cf0 refers to Sysop as) (kg) +Stud <-- Alias name (rc) +00:05 <-- Event time (hh:mm) (rc) +Y <-- If its an error correcting connection (Y/N) (rc) +N <-- ANSI supported & caller using NG mode (Y/N) (rc) +Y <-- Use Record Locking (Y/N) (rc) +14 <-- \cf1 BBS\cf0 Default Color (Standard IBM color code, ie, 1-15) (rc) +10 *<-- Time Credits In Minutes (positive/negative) (rc) +07/07/90 <-- Last New \cf1 Files\cf0 Scan Date (mm/dd/yy) (rc) +14:32 <-- Time of This Call (hh:mm) (rc) +07:30 <-- Time of Last Call (hh:mm) (rc) +6 <-- Maximum daily \cf1 files\cf0 available (rc) +3 *<-- \cf1 Files\cf0 d/led so far today (rc) +23456 *<-- Total "K" Bytes Uploaded (rc) +76329 *<-- Total "K" Bytes Downloaded (rc) +A File Sucker <-- User Comment (rc) +10 <-- Total Doors Opened (rc) +10283 <-- Total Messages Left (rc) +*) + +PROCEDURE Write_Door_Sys(RName: Boolean); +VAR + DoorFile: Text; + + FUNCTION ShowEmulation: AStr; + BEGIN + IF (OkRIP) THEN + ShowEmulation := 'RIP' + ELSE IF (OkANSI OR OKAvatar) THEN + ShowEmulation := 'GR' + ELSE + ShowEmulation := 'NG'; + END; + +BEGIN + Assign(DoorFile,Liner.DoorPath+'DOOR.SYS'); + ReWrite(DoorFile); + WriteLn(DoorFile,'COM'+AOnOff((ComPortSpeed = 0),'0',IntToStr(Liner.Comport))+':'); + WriteLn(DoorFile,ActualSpeed); + WriteLn(DoorFile,'8'); + WriteLn(DoorFile,ThisNode); + WriteLn(DoorFile,ComPortSpeed); + WriteLn(DoorFile,Copy(ShowYesNo(WantOut),1,1)); + WriteLn(DoorFile,'N'); + WriteLn(DoorFile,Copy(ShowYesNo(SysOpAvailable),1,1)); + WriteLn(DoorFile,Copy(ShowYesNo(Alert IN ThisUser.Flags),1,1)); + WriteLn(DoorFile,AOnOff(RName,ThisUser.RealName,Caps(ThisUser.Name))); (* ThisUser.Name Was All Caps *) + WriteLn(DoorFile,ThisUser.CityState); + WriteLn(DoorFile,Copy(ThisUser.Ph,1,3)+' '+Copy(ThisUser.Ph,5,8)); + WriteLn(DoorFile,Copy(ThisUser.Ph,1,3)+' '+Copy(ThisUser.Ph,5,8)); + WriteLn(DoorFile,'PASSWORD'); + WriteLn(DoorFile,ThisUser.SL); + WriteLn(DoorFile,ThisUser.LoggedOn); + WriteLn(DoorFile,DoorToDate8(PD2Date(ThisUser.LastOn))); (* Used - vice / for separator *) + WriteLn(DoorFile,NSL); + WriteLn(DoorFile,(NSL DIV 60)); + WriteLn(DoorFile,ShowEmulation); + WriteLn(DoorFile,ThisUser.PageLen); + WriteLn(DoorFile,Copy(ShowYesNo(Novice IN ThisUser.Flags),1,1)); + WriteLn(DoorFile,ShowConferences); (* Was AR Flags *) + WriteLn(DoorFile,ThisUser.LastConf); (* Was 7 *) + WriteLn(DoorFile,DoorToDate8(PD2Date(ThisUser.Expiration))); (* Was 12/31/99 *) + WriteLn(DoorFile,UserNum); + WriteLn(DoorFile,'Z'); + WriteLn(DoorFile,ThisUser.Uploads); + WriteLn(DoorFile,ThisUser.Downloads); + WriteLn(DoorFile,ThisUser.DLKToday); + WriteLn(DoorFile,General.DLKOneDay[ThisUser.SL]); (* Was 999999 *) + WriteLn(DoorFile,DoorToDate8(PD2Date(ThisUser.BirthDate))); (* Used - vice / for separator *) + WriteLn(DoorFile,General.DataPath); (* Was "\" *) + WriteLn(DoorFile,General.DataPath); (* Was "\" *) + WriteLn(DoorFile,General.SysOpName); + WriteLn(DoorFile,Caps(ThisUser.Name)); + + (* Fix - Event Time *) + WriteLn(DoorFile,'00:00'); + + WriteLn(DoorFile,Copy(ShowYesNo(Reliable),1,1)); + WriteLn(DoorFile,Copy(ShowYesNo(ANSIDetected AND (ShowEmulation = 'NG')),1,1)); (* Was 'N'*) + WriteLn(DoorFile,Copy(ShowYesNo(General.MultiNode),1,1)); + + (* Fix - Default User Color *) + WriteLn(DoorFile,'3'); + + (* Fix - Time Credits In Minutes (Positive/Negative *) + WriteLn(DoorFile,'0'); + + WriteLn(DoorFile,DoorToDate8(PD2Date(NewFileDate))); (* Used - vice / for separator *) + WriteLn(DoorFile,PD2Time24(TimeOn)); (* Was TimeStr *) + WriteLn(DoorFile,PD2Time24(ThisUser.LastOn)); (* Was 00:00 *) + WriteLn(DoorFile,General.DLOneDay[ThisUser.SL]); + WriteLn(DoorFile,ThisUser.DLToday); + WriteLn(DoorFile,ThisUser.UK); + WriteLn(DoorFile,ThisUser.DK); + WriteLn(DoorFile,ThisUser.Note); + + (* Fix - Total Doors Opened *) + WriteLn(DoorFile,'0'); + + (* Fix - Total Messages Left *) + WriteLn(DoorFile,'0'); (* Was 10 *) + + Close(DoorFile); + LastError := IOResult; +END; + +(* +1 User number +MRBILL User alias +Bill User real name + User callsign (HAM radio) +21 User age +M User sex + 16097.00 User gold +05/19/89 User last logon date +80 User colums +25 User width +255 User security level (0-255) +1 1 if Co-SysOp, 0 if not +1 1 if SysOp, 0 if not +1 1 if ANSI, 0 if not +0 1 if at remote, 0 if local console + 2225.78 User number of seconds left till logoff +F:\WWIV\GFILES\ System GFILES directory (gen. txt files) +F:\WWIV\DATA\ System DATA directory +890519.LOG System log of the day +2400 User baud rate +2 System com port +MrBill's Abode (the original) System name +The incredible inedible MrBill System SysOp +83680 Time user logged on/# of secs. from midn. +554 User number of seconds on system so far +5050 User number of uploaded k +22 User number of uploads +42 User amount of downloaded k +1 User number of downloads +8N1 User parity +2400 Com port baud rate +7400 WWIVnet node number +*) + +PROCEDURE Write_Chain_Txt(RName: Boolean); +VAR + DoorFile: Text; + TUsed: LongInt; +BEGIN + Assign(DoorFile,Liner.DoorPath+'CHAIN.TXT'); + ReWrite(DoorFile); + WriteLn(DoorFile,UserNum); + WriteLn(DoorFile,AOnOff(RName,ThisUser.RealName,Caps(ThisUser.Name))); (* Was AllCaps Name and force real name missing *) + WriteLn(DoorFile,ThisUser.RealName); + WriteLn(DoorFile,''); + WriteLn(DoorFile,AgeUser(ThisUser.BirthDate)); + WriteLn(DoorFile,ThisUser.Sex); + + (* What is gold ??? *) + WriteLn(DoorFile,'00.00'); + + WriteLn(DoorFile,DoorToDate8(PD2Date(ThisUser.LastOn))); (* Used "-" vice "/" *) + WriteLn(DoorFile,ThisUser.LineLen); + WriteLn(DoorFile,ThisUser.PageLen); + WriteLn(DoorFile,ThisUser.SL); + WriteLn(DoorFile,AOnOff(CoSysOp,'1','0')); (* Was Sysop *) + WriteLn(DoorFile,AOnOff(SysOp,'1','0')); (* Was CoSysOp *) + WriteLn(DoorFile,AOnOff((OkANSI OR OKAvatar),'1','0')); + WriteLn(DoorFile,AOnOff(InCom,'1','0')); + WriteLn(DoorFile,NSL); + WriteLn(DoorFile,General.DataPath); + WriteLn(DoorFile,General.DataPath); + WriteLn(DoorFile,General.LogsPath+'SYSOP.LOG'); (* Was missing path to the LOG *) + WriteLn(DoorFile,ComPortSpeed); + WriteLn(DoorFile,AOnOff((ComportSpeed = 0),'0',IntToStr(Liner.ComPort))); (* Was Liner.ComPort *) + WriteLn(DoorFile,StripColor(General.BBSName)); + WriteLn(DoorFile,General.SysOpName); + + (* Fix - Time user logged on/# of secs. from midnight *) + WriteLn(DoorFile,(GetPackDateTime - TimeOn)); + + (* Fix - User number of seconds on system so far *) + WriteLn(DoorFile,TUsed); + + WriteLn(DoorFile,ThisUser.UK); + WriteLn(DoorFile,ThisUser.Uploads); + WriteLn(DoorFile,ThisUser.DK); + WriteLn(DoorFile,ThisUser.Downloads); + WriteLn(DoorFile,'8N1'); + + (* Fix - Com port baud rate *) + WriteLn(DoorFile,''); (* Line was missing *) + + WriteLn(DoorFile,'0'); (* Line was missing *) + Close(DoorFile); + LastError := IOResult; +END; + +(* + +User's Name The name of the currently logged in user, with all color codes removed. +Speed The number 0 for 2400 baud, 1 for 300 baud, 2 for 1200 baud, 3 for 9600 baud, or 5 for console or + other speed. +City The last line of the user's mailing address that has data in it, or blank if no lines have data. +Security Level The number 5 for problem users, 30 for normal users, 80 for Aides, and 100 for Sysops. +Time left The time left in the user's accounts, in minutes. In an attempt to keep from overflowing other + software's limits, no value larger than 546 minutes is written. +ANSI Color The word "COLOR" if the current user has ANSI color enabled or "MONO" if he does not. +Password The current user's password (but not initials). +Userlog Number The current user's slot in LOG.DAT. (Not that this means anything to Citadel.) +Time used The number of minutes this call has lasted. If there is no user logged in, the number 0. +Unknown Citadel writes nothing out. Our information lists this field as being "01:23". +Unknown Citadel writes nothing out. Our information lists this field as being "01:23 01/02/90". +Unknown Citadel writes nothing out. Our information lists this field as being "ABCDEFGH". +Unknown Citadel writes nothing out. Our information lists this field as being "0". +Unknown Citadel writes nothing out. Our information lists this field as being "99". +Unknown Citadel writes nothing out. Our information lists this field as being "0". +Unknown Citadel writes nothing out. Our information lists this field as being "9999". +Phone number The current user's phone number. +Unknown Citadel writes nothing out. Our information lists this field as being "01/01/90 02:34". +Expert The word "EXPERT" if helpful hints are turned off or "NOVICE" if they are on. +File transfer protocol The name of the user's default file transfer protocol, or a blank line if none is specified. +Unknown Citadel writes nothing out. Our information lists this field as being "01/01/90". +Times on The number of times the current user has logged onto the system. +Lines per screen The number of lines per screen, or 0 if the current user has screen pause turned off. +Last message read The new message pointer for the current room. +Total uploads The total number of files the user has uploaded. +Total downloads The total number of files the user has downloaded. +Excessively Stupid!!! The text "8 { Databits }". (There are two spaces between the "8" and the "{".) +User's location The text "LOCAL if logged in on console, or "REMOTE" if logged in over the modem. +Port The text "COM" followed by the serial port number of the modem. (For example, "COM1" if the modem is + on the first serial port.) +Speed The number 0 for 2400 baud, 1 for 300 baud, 2 for 1200 baud, 3 for 9600 baud, or 5 for other speed. + No attention is paid to whether the user is on console or not. +Unknown Citadel writes nothing out. Our information lists this field as being "FALSE". +Another stupid thing The text "Normal Connection". +Unknown Citadel writes nothing out. Our information lists this field as being "01/02/94 01:20". +Task number Citadel writes the number 0. +Door number Citadel writes the number 1. +*) + +PROCEDURE Write_CallInfo_BBS(RName: Boolean); +VAR + DoorFile: Text; + + FUNCTION ShowSpeed: AStr; + BEGIN + IF (ComPortSpeed = 300) THEN + ShowSpeed := '1' + ELSE IF (ComPortSpeed = 1200) THEN + ShowSpeed := '2' + ELSE IF (ComPortSpeed = 2400) THEN + ShowSpeed := '0' + ELSE IF (ComPortSpeed = 9600) THEN + ShowSpeed := '3' + ELSE IF (ComPortSpeed = 0) THEN + ShowSpeed := '5' + ELSE + ShowSpeed := '4'; + END; + +BEGIN + Assign(DoorFile,Liner.DoorPath+'CALLINFO.BBS'); + ReWrite(DoorFile); + WITH ThisUser DO + BEGIN + WriteLn(DoorFile,AOnOff(RName,AllCaps(ThisUser.RealName),AllCaps(ThisUser.Name))); + WriteLn(DoorFile,ShowSpeed); + WriteLn(DoorFile,AllCaps(ThisUser.CityState)); + WriteLn(DoorFile,ThisUser.SL); + WriteLn(DoorFile,NSL DIV 60); + WriteLn(DoorFile,AOnOff((OkANSI OR OKAvatar),'COLOR','MONO')); + WriteLn(DoorFile,'PASSWORD'); + WriteLn(DoorFile,UserNum); + WriteLn(DoorFile,'0'); + WriteLn(DoorFile,Copy(TimeStr,1,5)); + WriteLn(DoorFile,Copy(TimeStr,1,5)+' '+DateStr); + WriteLn(DoorFile,'A'); + WriteLn(DoorFile,'0'); + WriteLn(DoorFile,'999999'); + WriteLn(DoorFile,'0'); + WriteLn(DoorFile,'999999'); + WriteLn(DoorFile,ThisUser.Ph); + WriteLn(DoorFile,ToDate8(PD2Date(ThisUser.LastOn))+' 00:00'); + WriteLn(DoorFile,AOnOff((Novice IN ThisUser.Flags),'NOVICE','EXPERT')); + WriteLn(DoorFile,'All'); + WriteLn(DoorFile,'01/01/80'); + WriteLn(DoorFile,ThisUser.LoggedOn); + WriteLn(DoorFile,ThisUser.PageLen); + WriteLn(DoorFile,'0'); + WriteLn(DoorFile,ThisUser.Uploads); + WriteLn(DoorFile,ThisUser.Downloads); + WriteLn(DoorFile,'8 { Databits }'); + WriteLn(DoorFile,AOnOff((InCom OR OutCom),'REMOTE','LOCAL')); + WriteLn(DoorFile,'COM'+AOnOff((InCom OR OutCom),IntToStr(Liner.Comport),'0')); + WriteLn(DoorFile,PD2Date(ThisUser.BirthDate)); + WriteLn(DoorFile,ComPortSpeed); + WriteLn(DoorFile,AOnOff((InCom OR OutCom),'TRUE','FALSE')); + WriteLn(DoorFile,AOnOff(Reliable,'MNP/ARQ','Normal')+' Connection'); + WriteLn(DoorFile,'12/31/99 23:59'); + WriteLn(DoorFile,ThisNode); + WriteLn(DoorFile,'1'); + END; + Close(DoorFile); + LastError := IOResult; +END; + +PROCEDURE Write_SFDoors_Dat(RName: Boolean); +VAR + DoorFile: Text; + S: AStr; +BEGIN + Assign(DoorFile,Liner.DoorPath+'SFDOORS.DAT'); + ReWrite(DoorFile); + WriteLn(DoorFile,UserNum); + WriteLn(DoorFile,AOnOff(RName,AllCaps(ThisUser.RealName),AllCaps(ThisUser.Name))); + WriteLn(DoorFile,'PASSWORD'); + IF (RName) THEN + BEGIN + IF (Pos(' ',ThisUser.RealName) = 0) THEN + S := ThisUser.RealName + ELSE + S := Copy(ThisUser.RealName,1,(Pos(' ',ThisUser.RealName) - 1)); + END + ELSE + BEGIN + IF (Pos(' ',ThisUser.Name) = 0) THEN + S := ThisUser.Name + ELSE + S := Copy(ThisUser.Name,1,(Pos(' ',ThisUser.Name) - 1)); + END; + WriteLn(DoorFile,S); + WriteLn(DoorFile,ComPortSpeed); + WriteLn(DoorFile,AOnOff((ComPortSpeed = 0),'0',IntToStr(Liner.Comport))); + WriteLn(DoorFile,NSL DIV 60); + WriteLn(DoorFile,Timer); { seconds since midnight } + WriteLn(DoorFile,StartDir); + WriteLn(DoorFile,AOnOff((OkANSI OR OKAvatar),'TRUE','FALSE')); + WriteLn(DoorFile,ThisUser.SL); + WriteLn(DoorFile,ThisUser.Uploads); + WriteLn(DoorFile,ThisUser.Downloads); + WriteLn(DoorFile,General.TimeAllow[ThisUser.SL]); + WriteLn(DoorFile,'0'); { time on (seconds) } + WriteLn(DoorFile,'0'); { extra time (seconds) } + WriteLn(DoorFile,'FALSE'); + WriteLn(DoorFile,'FALSE'); + WriteLn(DoorFile,'FALSE'); + WriteLn(DoorFile,Liner.InitBaud); + WriteLn(DoorFile,AOnOff(Reliable,'TRUE','FALSE')); + WriteLn(DoorFile,'A'); + WriteLn(DoorFile,'A'); + WriteLn(DoorFile,ThisNode); + WriteLn(DoorFile,General.DLOneDay[ThisUser.SL]); + WriteLn(DoorFile,ThisUser.DLToday); + WriteLn(DoorFile,General.DLKOneDay[ThisUser.SL]); + WriteLn(DoorFile,ThisUser.DLKToday); + WriteLn(DoorFile,ThisUser.UK); + WriteLn(DoorFile,ThisUser.DK); + WriteLn(DoorFile,ThisUser.Ph); + WriteLn(DoorFile,ThisUser.CityState); + WriteLn(DoorFile,General.TimeAllow[ThisUser.SL]); + Close(DoorFile); + LastError := IOResult; +END; + +PROCEDURE DoDoorFunc(DropFileType: Char; MenuOption: Str50); +VAR + Answer: AStr; + ReturnCode: Integer; + DoorTime: LongInt; + UseRealName: Boolean; +BEGIN + IF (MenuOption = '') AND (InCom) THEN + Exit; + SaveURec(ThisUser,UserNum); + UseRealName := FALSE; + IF (Copy(AllCaps(MenuOption),1,2) = 'R;') THEN + BEGIN + UseRealName := TRUE; + MenuOption := Copy(MenuOption,3,(Length(MenuOption) - 2)); + END; + Answer := FunctionalMCI(MenuOption,'',''); + CASE DropFileType OF + '3' : BEGIN + lStatus_Screen(100,'Outputting DOOR32.SYS ...',FALSE,Answer); + Write_Door32_Sys(UseRealName); + END; + 'P' : BEGIN + lStatus_Screen(100,'Outputting PCBOARD.SYS ...',FALSE,Answer); + Write_PCBoard_Sys(UseRealName); + END; + 'C' : BEGIN + lStatus_Screen(100,'Outputting CHAIN.TXT ...',FALSE,Answer); + Write_Chain_Txt(UseRealName); + END; + 'D' : BEGIN + lStatus_Screen(100,'Outputting DORINFO1.DEF ...',FALSE,Answer); + Write_DorInfo1_Def(UseRealName); + END; + 'G' : BEGIN + lStatus_Screen(100,'Outputting DOOR.SYS ...',FALSE,Answer); + Write_Door_Sys(UseRealName); + END; + 'S' : BEGIN + lStatus_Screen(100,'Outputting SFDOORS.DAT ...',FALSE,Answer); + Write_SFDoors_Dat(UseRealName); + END; + 'W' : BEGIN + lStatus_Screen(100,'Outputting CALLINFO.BBS ...',FALSE,Answer); + Write_CallInfo_BBS(UseRealName); + END; + END; + IF (Answer = '') THEN + Exit; + Shel('Running "'+Answer+'"'); + SysOpLog('Opened door '+Answer+' on '+DateStr+' at '+TimeStr); + + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + SaveNAvail := (NAvail IN NodeR.Status); + Exclude(NodeR.Status,NAvail); + SaveNode(ThisNode); + END; + + DoorTime := GetPackDateTime; + ShellDos(FALSE,Answer,ReturnCode); + DoorTime := (GetPackDateTime - DoorTime); + Shel2(FALSE); + + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + IF (SaveNAvail) THEN + Include(NodeR.Status,NAvail); + SaveNode(ThisNode); + END; + + NewCompTables; + SaveGeneral(TRUE); + LoadURec(ThisUser,UserNum); + LoadFileArea(FileArea); + LoadMsgArea(MsgArea); + ChDir(StartDir); + Com_Flush_Recv; + SysOpLog('Returned on '+DateStr+' at '+TimeStr+'. Spent '+FormattedTime(DoorTime)); +END; + +END. diff --git a/SOURCE/ELECOM/BUFUNIT.PAS b/SOURCE/ELECOM/BUFUNIT.PAS new file mode 100644 index 0000000..6f16c24 --- /dev/null +++ b/SOURCE/ELECOM/BUFUNIT.PAS @@ -0,0 +1,140 @@ +unit BufUnit; +{$I-,R-,S-,Q-} +(* +** +** Large char-buffer handling routines for EleCOM +** +** Copyright (c) 1998-2002 by Maarten Bekers +** +** Version : 1.03 +** Created : 05-Jan-1999 +** Last update : 12-Jan-2003 +** +** +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +Type CharBufType = Array[0..65520] of Char; + +type BufArrayObj = Object + TxtArr : CharBufType; + TxtMaxLen : Longint; + TxtStartPtr: Longint; { Start of buffer ptr } + CurTxtPtr : Longint; { Maximum data entered yet } + TmpBuf : CharBufType; + + constructor Init(TxtSize: Longint); + destructor Done; + + function BufRoom: Longint; + function BufUsed: Longint; + function Put(var Buf; Size: Longint): Longint; + function Get(var Buf; Size: Longint; Remove: Boolean): Longint; + + procedure Clear; + end; { BufArrayObj } + + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +constructor BufArrayObj.Init(TxtSize: Longint); +begin + TxtMaxLen := TxtSize; + CurTxtPtr := -1; + TxtStartPtr := 0; + + FillChar(TxtArr, TxtMaxLen, #00); + FillChar(TmpBuf, TxtMaxLen, #00); +end; { constructor Init } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +destructor BufArrayObj.Done; +begin +end; { destructor Done } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function BufArrayObj.BufRoom: Longint; +begin + BufRoom := (TxtMaxLen - (CurTxtPtr + 1)); +end; { func. BufRoom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function BufArrayObj.BufUsed: Longint; +begin + BufUsed := (CurTxtPtr + 01); +end; { func. BufUsed } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function BufArrayObj.Put(var Buf; Size: Longint): Longint; +var RetSize: Longint; +begin + Put := 0; + if Size < 0 then EXIT; + + if TxtStartPtr > 0 then + if (CurTxtPtr + TxtStartPtr) > TxtMaxLen then + begin + Move(TxtArr[TxtStartPtr], TxtArr[0], Succ(CurTxtPtr)); + TxtStartPtr := 0; + end; { if } + + if Size > BufRoom then RetSize := BufRoom + else RetSize := Size; + + Move(Buf, TxtArr[TxtStartPtr + BufUsed], RetSize); + + Inc(CurTxtPtr, RetSize); + TxtArr[TxtStartPtr + BufUsed + 1] := #0; + Put := RetSize; +end; { func. Put } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function BufArrayObj.Get(var Buf; Size: Longint; Remove: Boolean): Longint; +var RetSize: Longint; +begin + Get := 0; + if Size < 0 then EXIT; + + if Size > BufUsed then RetSize := BufUsed + else RetSize := Size; + + Move(TxtArr[TxtStartPtr], Buf, RetSize); + + Get := RetSize; + + if Remove then + begin + if RetSize = BufUsed then + begin + CurTxtPtr := -1; + TxtStartPtr := 0; + TxtArr[0] := #0; + end + else begin + Inc(TxtStartPtr, RetSize); + Dec(CurTxtPtr, RetSize); + TxtArr[CurTxtPtr + TxtStartPtr + 1] := #0; + end; { if } + end; { if } +end; { func. Get } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure BufArrayObj.Clear; +begin + CurTxtPtr := -1; +end; { proc. Clear } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +end. diff --git a/SOURCE/ELECOM/COMBASE.PAS b/SOURCE/ELECOM/COMBASE.PAS new file mode 100644 index 0000000..dd72401 --- /dev/null +++ b/SOURCE/ELECOM/COMBASE.PAS @@ -0,0 +1,309 @@ +unit ComBase; +(* +** +** Serial and TCP/IP communication routines for DOS, OS/2 and Win9x/NT. +** Tested with: TurboPascal v7.0, (DOS) +** VirtualPascal v2.1, (OS/2, Win32) +** FreePascal v0.99.12 (DOS, Win32) +** Delphi v4.0. (Win32) +** +** Version : 1.01 +** Created : 21-May-1998 +** Last update : 14-May-1999 +** +** Note: (c)1998-2003 by Maarten Bekers +** +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +{$IFDEF VirtualPascal} +uses Use32; +{$ENDIF} + +{$IFDEF MSDOS} + Type ShortString = String; +{$ENDIF} + +type SliceProc = procedure; + +type TCommObj = Object + DontClose : Boolean; + InitFailed : Boolean; + ErrorStr : ShortString; + BlockAll : Boolean; + + constructor Init; + destructor Done; + + procedure Com_OpenQuick(Handle: Longint); virtual; + function Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; virtual; + function Com_OpenKeep(Comport: Byte): Boolean; virtual; + procedure Com_GetModemStatus(var LineStatus, ModemStatus: Byte); virtual; + + procedure Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); virtual; + function Com_GetBPSrate: Longint; virtual; + + procedure Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); virtual; + procedure Com_SetDtr(State: Boolean); virtual; + + function Com_CharAvail: Boolean; virtual; + function Com_Carrier: Boolean; virtual; + function Com_ReadyToSend(BlockLen: Longint): Boolean; virtual; + + function Com_GetChar: Char; virtual; + function Com_PeekChar: Char; virtual; + function Com_SendChar(C: Char): Boolean; virtual; + function Com_GetDriverInfo: String; virtual; + function Com_GetHandle: Longint; virtual; + function Com_InitSucceeded: Boolean; virtual; + + procedure Com_Close; virtual; + procedure Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); virtual; + procedure Com_SendWait(var Block; BlockLen: Longint; var Written: Longint; Slice: SliceProc); virtual; + procedure Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); virtual; + procedure Com_PurgeOutBuffer; virtual; + procedure Com_PurgeInBuffer; virtual; + procedure Com_PauseCom(CloseCom: Boolean); virtual; + procedure Com_ResumeCom(OpenCom: Boolean); virtual; + procedure Com_FlushOutBuffer(Slice: SliceProc); virtual; + procedure Com_SendString(Temp: ShortString); virtual; + procedure Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); virtual; + + procedure Com_SetDataProc(ReadPtr, WritePtr: Pointer); virtual; + + end; { object TCommObj } + +Type PCommObj = ^TCommObj; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +{-- We disable warnings as this is just an abstract -} + +constructor TCommObj.Init; +begin + DontClose := false; + InitFailed := false; + BlockAll := false; + ErrorStr := ''; +end; { constructor Init } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +destructor TCommObj.Done; +begin +end; { destructor Done } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; +begin + Com_Open := FALSE; +end; { func. Com_Open } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_OpenQuick(Handle: Longint); +begin +end; { proc. TCommObj.Com_OpenQuick } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_Close; +begin +end; { proc. TCommObj.Com_Close } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_GetChar: Char; +begin + Com_GetChar := #0; +end; { func. TCommObj.Com_GetChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_PeekChar: Char; +begin + Com_PeekChar := #0; +end; { func. TCommObj.Com_GetChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_SendChar(C: Char): Boolean; +begin + Com_SendChar := FALSE; +end; { proc. TCommObj.Com_SendChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); +begin +end; { proc. TCommObj.Com_SendBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); +begin +end; { proc. TCommObj.Com_ReadBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_CharAvail: Boolean; +begin + Com_CharAvail := FALSE; +end; { func. TCommObj.Com_CharAvail } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_Carrier: Boolean; +begin + Com_Carrier := FALSE; +end; { func. Comm_Carrier } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_SetDtr(State: Boolean); +begin +end; { proc. TCommObj.Com_SetDtr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_OpenKeep(Comport: Byte): Boolean; +begin + Com_OpenKeep := FALSE; +end; { func. TCommObj.Com_OpenKeep } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_ReadyToSend(BlockLen: Longint): Boolean; +begin + Com_ReadyToSend := FALSE; +end; { func. TCommObj.Com_ReadyToSend } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_GetModemStatus(var LineStatus, ModemStatus: Byte); +begin +end; { proc. TCommObj.Com_GetModemStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_GetBPSrate: Longint; +begin + Com_GetBpsRate := -1; +end; { func. TCommObj.Com_GetBPSrate } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); +begin +end; { proc. TCommObj.Com_SetLine } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); +begin +end; { proc. TCommObj.Com_GetBufferStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_PurgeInBuffer; +begin +end; { proc. TCommObj.Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_PurgeOutBuffer; +begin +end; { proc. TCommObj.Com_PurgeOutBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_GetDriverInfo: String; +begin + Com_GetDriverInfo := ''; +end; { func. Com_GetDriverInfo } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_GetHandle: Longint; +begin + Com_GetHandle := -1; +end; { func. Com_GetHandle } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_PauseCom(CloseCom: Boolean); +begin +end; { proc. Com_PauseCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_ResumeCom(OpenCom: Boolean); +begin +end; { proc. Com_ResumeCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TCommObj.Com_InitSucceeded: Boolean; +begin + Com_InitSucceeded := NOT InitFailed; +end; { func. Com_InitFailed } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_FlushOutBuffer(Slice: SliceProc); +var InFree, + OutFree, + InUsed, + OutUsed : Longint; +begin + Com_GetBufferStatus(InFree, OutFree, InUsed, OutUsed); + + while (OutUsed > 1) AND (Com_Carrier) do + { X00 (fossil) will never go below 1 ! } + begin + Com_GetBufferStatus(InFree, OutFree, InUsed, OutUsed); + + if @Slice <> nil then + begin + Slice; + Slice; + end; { if } + end; { while } +end; { proc. Com_FlushOutBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_SendWait(var Block; BlockLen: Longint; var Written: Longint; Slice: SliceProc); +begin + Com_SendBlock(Block, BlockLen, Written); +end; { proc. Com_SendWait } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_SendString(Temp: ShortString); +var Written: Longint; +begin + Com_SendBlock(Temp[1], Length(Temp), Written); +end; { proc. Com_SendString } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); +begin +end; { proc. Com_Setflow } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TCommObj.Com_SetDataProc(ReadPtr, WritePtr: Pointer); +begin +end; { Com_SetDataProc } + +end. diff --git a/SOURCE/ELECOM/ELECOM13.PAS b/SOURCE/ELECOM/ELECOM13.PAS new file mode 100644 index 0000000..0e2dc44 --- /dev/null +++ b/SOURCE/ELECOM/ELECOM13.PAS @@ -0,0 +1,350 @@ +library ELECOM13; +{$H-} { important, turn off Ansi-Strings } +(* +** +** Serial and TCP/IP communication routines for DOS, OS/2 and Win9x/NT. +** Tested with: TurboPascal v7.0, (DOS) +** VirtualPascal v2.1, (OS/2, Win32) +** FreePascal v0.99.12 (DOS, Win32) +** Delphi v4.0. (Win32) +** +** Version : 1.02 +** Created : 13-Jun-1999 +** Last update : 28-Jun-2000 +** +** Note: (c)1998-1999 by Maarten Bekers. +** If you have any suggestions, please let me know. +** +*) +uses ComBase, + {$IFDEF WIN32} + W32SNGL, + {$ENDIF} + + {$IFDEF OS2} + Os2Com, + {$ENDIF} + + Telnet; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + var ComObj : pCommObj; + ComSystem: Longint; +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Int_ComReadProc(var TempPtr: Pointer); stdcall; +begin + {$IFDEF WIN32} + Case ComSystem of + 1 : PWin32Obj(ComObj)^.Com_DataProc(TempPtr); + 2 : PTelnetObj(ComObj)^.Com_ReadProc(TempPtr); + end; { case } + {$ENDIF} + + {$IFDEF OS2} + Case ComSystem of + 1 : POs2Obj(ComObj)^.Com_ReadProc(TempPtr); + 2 : PTelnetObj(ComObj)^.Com_ReadProc(TempPtr); + end; { case } + {$ENDIF} +end; { proc. Int_ComReadProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Int_ComWriteProc(var TempPtr: Pointer); stdcall; +begin + {$IFDEF WIN32} + Case ComSystem of + 1 : PWin32Obj(ComObj)^.Com_DataProc(TempPtr); + 2 : PTelnetObj(ComObj)^.Com_WriteProc(TempPtr); + end; { case } + {$ENDIF} + + {$IFDEF OS2} + Case ComSystem of + 1 : POs2Obj(ComObj)^.Com_WriteProc(TempPtr); + 2 : PTelnetObj(ComObj)^.Com_WriteProc(TempPtr); + end; { case } + {$ENDIF} +end; { proc. Int_ComWriteProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_Startup(ObjectType: Longint); stdcall; +begin + ComSystem := ObjectType; + + Case Objecttype of + {$IFDEF WIN32} + 01 : ComObj := New(pWin32Obj, Init); + {$ENDIF} + + {$IFDEF OS2} + 01 : ComObj := New(pOs2Obj, Init); + {$ENDIF} + + 02 : ComObj := New(pTelnetObj, Init); + end; { case } + + ComObj^.Com_SetDataProc(@Int_ComReadProc, @Int_ComWriteProc); +end; { proc. Com_Startup } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_OpenQuick(Handle: Longint); stdcall; +begin + ComObj^.Com_OpenQuick(Handle); +end; { proc. Com_OpenQuick } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; stdcall; +begin + Result := ComObj^.Com_Open(Comport, BaudRate, DataBits, Parity, StopBits); +end; { func. Com_Open } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_OpenKeep(Comport: Byte): Boolean; stdcall; +begin + Result := ComObj^.Com_OpenKeep(Comport); +end; { func. Com_OpenKeep } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_GetModemStatus(var LineStatus, ModemStatus: Byte); stdcall; +begin + ComObj^.Com_GetModemStatus(LineStatus, ModemStatus); +end; { proc. Com_GetModemStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); stdcall; +begin + ComObj^.Com_SetLine(BpsRate, Parity, DataBits, StopBits); +end; { proc. Com_SetLine } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_GetBPSrate: Longint; stdcall; +begin + Result := ComObj^.Com_GetBpsRate; +end; { func. Com_GetBpsRate } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); stdcall; +begin + ComObj^.Com_GetBufferStatus(InFree, OutFree, InUsed, OutUsed); +end; { proc. Com_GetBufferStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SetDtr(State: Boolean); stdcall; +begin + ComObj^.Com_SetDtr(State); +end; { proc. Com_SetDtr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_CharAvail: Boolean; stdcall; +begin + Result := ComObj^.Com_CharAvail; +end; { func. Com_CharAvail } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_Carrier: Boolean; stdcall; +begin + Result := ComObj^.Com_Carrier; +end; { func. Com_Carrier } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_ReadyToSend(BlockLen: Longint): Boolean; stdcall; +begin + Result := ComObj^.Com_ReadyToSend(BlockLen); +end; { func. Com_ReadyToSend } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_GetChar: Char; stdcall; +begin + Result := ComObj^.Com_GetChar; +end; { func. Com_GetChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_SendChar(C: Char): Boolean; stdcall; +begin + Result := ComObj^.Com_SendChar(C); +end; { func. Com_SendChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_GetDriverInfo: String; stdcall; +begin + Result := ComObj^.Com_GetDriverInfo; +end; { func. Com_GetDriverInfo } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_GetHandle: Longint; stdcall; +begin + Result := ComObj^.Com_GetHandle; +end; { func. Com_GetHandle } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_InitSucceeded: Boolean; stdcall; +begin + Result := ComObj^.Com_InitSucceeded; +end; { func. Com_InitSucceeded } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_Close; stdcall; +begin + ComObj^.Com_Close; +end; { proc. Com_Close } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); stdcall; +begin + ComObj^.Com_SendBlock(Block, BlockLen, Written); +end; { proc. Com_SendBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SendWait(var Block; BlockLen: Longint; var Written: Longint; Slice: SliceProc); stdcall; +begin + ComObj^.Com_SendWait(Block, BlockLen, Written, Slice); +end; { proc. Com_SendWait } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); stdcall; +begin + ComObj^.Com_ReadBlock(Block, BlockLen, Reads); +end; { proc. Com_ReadBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_PurgeOutBuffer; stdcall; +begin + ComObj^.Com_PurgeOutBuffer; +end; { proc. Com_PurgeOutBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_PurgeInBuffer; stdcall; +begin + ComObj^.Com_PurgeInBuffer; +end; { proc. Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_PauseCom(CloseCom: Boolean); stdcall; +begin + ComObj^.Com_PauseCom(CloseCom); +end; { proc. Com_PauseCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_ResumeCom(OpenCom: Boolean); stdcall; +begin + ComObj^.Com_ResumeCom(OpenCom); +end; { proc. Com_ResumeCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_FlushOutBuffer(Slice: SliceProc); stdcall; +begin + ComObj^.Com_FlushOutBuffer(Slice); +end; { proc. Com_FlushOutBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SendString(Temp: String); stdcall; +begin + ComObj^.Com_SendString(Temp); +end; { Com_SendString } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SetDontClose(Value: Boolean); stdcall; +begin + ComObj^.DontClose := Value; +end; { proc. Com_SetDontClose } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); stdcall; +begin + ComObj^.Com_SetFlow(SoftTX, SoftRX, Hard); +end; { proc. Com_Setflow } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_ShutDown; stdcall; +begin + Dispose(ComObj, Done); +end; { proc. Com_ShutDown } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_InitFailed: Boolean; stdcall; +begin + Result := ComObj^.InitFailed; +end; { func. Com_Initfailed } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_ErrorStr: String; stdcall; +begin + Result := ComObj^.ErrorStr; +end; { func. Com_ErrorStr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +exports + Com_Startup index 1 name 'Com_Startup', + Com_Open index 2 name 'Com_Open', + Com_OpenQuick index 3 name 'Com_OpenQuick', + Com_OpenKeep index 4 name 'Com_OpenKeep', + Com_GetModemStatus index 5 name 'Com_GetModemStatus', + Com_SetLine index 6 name 'Com_SetLine', + Com_GetBPSrate index 7 name 'Com_GetBPSrate', + Com_GetBufferStatus index 8 name 'Com_GetBufferStatus', + Com_SetDtr index 09 name 'Com_SetDtr', + Com_CharAvail index 10 name 'Com_CharAvail', + Com_Carrier index 11 name 'Com_Carrier', + Com_ReadyToSend index 12 name 'Com_ReadyToSend', + Com_GetChar index 13 name 'Com_GetChar', + Com_SendChar index 14 name 'Com_SendChar', + Com_GetDriverInfo index 15 name 'Com_GetDriverInfo', + Com_GetHandle index 16 name 'Com_GetHandle', + Com_InitSucceeded index 17 name 'Com_InitSucceeded', + Com_Close index 18 name 'Com_Close', + Com_SendBlock index 19 name 'Com_SendBlock', + Com_SendWait index 20 name 'Com_SendWait', + Com_ReadBlock index 21 name 'Com_ReadBlock', + Com_PurgeOutBuffer index 22 name 'Com_PurgeOutBuffer', + Com_PurgeInBuffer index 23 name 'Com_PurgeInBuffer', + Com_PauseCom index 24 name 'Com_PauseCom', + Com_ResumeCom index 25 name 'Com_ResumeCom', + Com_FlushOutBuffer index 26 name 'Com_FlushOutBuffer', + Com_SendString index 27 name 'Com_SendString', + Com_ShutDown index 28 name 'Com_ShutDown', + Com_SetDontClose index 29 name 'Com_SetDontClose', + Com_SetFlow index 30 name 'Com_SetFlow', + Com_InitFailed index 31 name 'Com_InitFailed', + Com_ErrorStr index 32 name 'Com_ErrorStr'; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +begin + ComObj := nil; +end. diff --git a/SOURCE/ELECOM/ELEDEF.PAS b/SOURCE/ELECOM/ELEDEF.PAS new file mode 100644 index 0000000..d7d88a5 --- /dev/null +++ b/SOURCE/ELECOM/ELEDEF.PAS @@ -0,0 +1,101 @@ +unit ELEDEF; +(* +** +** Serial and TCP/IP communication routines for DOS, OS/2 and Win9x/NT. +** Tested with: TurboPascal v7.0, (DOS) +** VirtualPascal v2.1, (OS/2, Win32) +** FreePascal v0.99.12 (DOS, Win32) +** Delphi v4.0. (Win32) +** +** Version : 1.03 +** Created : 13-Jun-1999 +** Last update : 05-Aug-2000 +** +** Note: (c)1998-1999 by Maarten Bekers. +** If you have any suggestions, please let me know. +** +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +Const + ComNameDLL = 'elecom13.dll'; + +type SliceProc = procedure; + +procedure Com_Startup(ObjectType: Longint); stdcall; +function Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; stdcall; +procedure Com_OpenQuick(Handle: Longint); stdcall; +function Com_OpenKeep(Comport: Byte): Boolean; stdcall; +procedure Com_GetModemStatus(var LineStatus, ModemStatus: Byte); stdcall; +procedure Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); stdcall; +function Com_GetBPSrate: Longint; stdcall; +procedure Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); stdcall; +procedure Com_SetDtr(State: Boolean); stdcall; +function Com_CharAvail: Boolean; stdcall; +function Com_Carrier: Boolean; stdcall; +function Com_ReadyToSend(BlockLen: Longint): Boolean; +function Com_GetChar: Char; stdcall; +function Com_SendChar(C: Char): Boolean; stdcall; +function Com_GetDriverInfo: String; stdcall; +function Com_GetHandle: Longint; stdcall; +function Com_InitSucceeded: Boolean; stdcall; +procedure Com_Close; stdcall; +procedure Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); stdcall; +procedure Com_SendWait(var Block; BlockLen: Longint; var Written: Longint; Slice: SliceProc); stdcall; +procedure Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); stdcall; +procedure Com_PurgeOutBuffer; stdcall; +procedure Com_PurgeInBuffer; stdcall; +procedure Com_PauseCom(CloseCom: Boolean); stdcall; +procedure Com_ResumeCom(OpenCom: Boolean); stdcall; +procedure Com_FlushOutBuffer(Slice: SliceProc); stdcall; +procedure Com_SendString(Temp: String); stdcall; +procedure Com_ShutDown; stdcall; +procedure Com_SetDontClose(Value: Boolean); stdcall; +procedure Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); stdcall; +function Com_InitFailed: Boolean; stdcall; +function Com_ErrorStr: String; stdcall; + + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_Startup(ObjectType: Longint); external ComNameDLL index 1; +function Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; external ComNameDLL index 2; +procedure Com_OpenQuick(Handle: Longint); external ComNameDLL index 3; +function Com_OpenKeep(Comport: Byte): Boolean; external ComNameDLL index 4; +procedure Com_GetModemStatus(var LineStatus, ModemStatus: Byte); external ComNameDLL index 5; +procedure Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); external ComNameDLL index 6; +function Com_GetBPSrate: Longint; external ComNameDLL index 7; +procedure Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); external ComNameDLL index 8; +procedure Com_SetDtr(State: Boolean); external ComNameDLL index 9; +function Com_CharAvail: Boolean; external ComNameDLL index 10; +function Com_Carrier: Boolean; external ComNameDLL index 11; +function Com_ReadyToSend(BlockLen: Longint): Boolean; external ComNameDLL index 12; +function Com_GetChar: Char; external ComNameDLL index 13; +function Com_SendChar(C: Char): Boolean; external ComNameDLL index 14; +function Com_GetDriverInfo: String; external ComNameDLL index 15; +function Com_GetHandle: Longint; external ComNameDLL index 16; +function Com_InitSucceeded: Boolean; external ComNameDLL index 17; +procedure Com_Close; external ComNameDLL index 18; +procedure Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); external ComNameDLL index 19; +procedure Com_SendWait(var Block; BlockLen: Longint; var Written: Longint; Slice: SliceProc); external ComNameDLL index 20; +procedure Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); external ComNameDLL index 21; +procedure Com_PurgeOutBuffer; external ComNameDLL index 22; +procedure Com_PurgeInBuffer; external ComNameDLL index 23; +procedure Com_PauseCom(CloseCom: Boolean); external ComNameDLL index 24; +procedure Com_ResumeCom(OpenCom: Boolean); external ComNameDLL index 25; +procedure Com_FlushOutBuffer(Slice: SliceProc); external ComNameDLL index 26; +procedure Com_SendString(Temp: String); external ComNameDLL index 27; +procedure Com_ShutDown; external ComNameDLL index 28; +procedure Com_SetDontClose(Value: Boolean); external ComNameDLL index 29; +procedure Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); external ComNameDLL index 30; +function Com_InitFailed: Boolean; external ComNameDLL index 31; +function Com_ErrorStr: String; external ComNameDLL index 32; + +end. diff --git a/SOURCE/ELECOM/ELENORM.PAS b/SOURCE/ELECOM/ELENORM.PAS new file mode 100644 index 0000000..d6b2bc2 --- /dev/null +++ b/SOURCE/ELECOM/ELENORM.PAS @@ -0,0 +1,376 @@ +unit EleNORM; +(* +** +** Serial and TCP/IP communication routines for DOS, OS/2 and Win9x/NT. +** Tested with: TurboPascal v7.0, (DOS) +** VirtualPascal v2.1, (OS/2, Win32) +** FreePascal v0.99.12 (DOS, Win32) +** Delphi v4.0. (Win32) +** +** Version : 1.01 +** Created : 13-Jun-1999 +** Last update : 28-Jun-2000 +** +** Note: (c)1998 - 2000 by Maarten Bekers. This unit tries to make it easier +** to use EleCOM. +** +** Usage: +** Before calling any of these routines, first call Com_StartUp: +** Pass the following number to it: +** 01 - Use the "modem" communications (OS/2, Win32 or FOSSIL) +** 02 - Use the TELNET type (OS/2 or Win32 only). +** +*) +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses ComBase + {$IFDEF WIN32} + , W32SNGL + , Telnet + {$ENDIF} + + {$IFDEF OS2} + , Telnet + , Os2com + {$ENDIF} + + {$IFDEF GO32V2} + , Fos_Com + {$ENDIF} + + {$IFDEF MSDOS} + , Fos_com + {$ENDIF} ; + + +function Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; +function Com_OpenKeep(Comport: Byte): Boolean; +function Com_CharAvail: Boolean; +function Com_Carrier: Boolean; +function Com_ReadyToSend(BlockLen: Longint): Boolean; +function Com_GetChar: Char; +function Com_PeekChar: Char; +function Com_SendChar(C: Char): Boolean; +function Com_GetDriverInfo: String; +function Com_GetHandle: Longint; +function Com_InitSucceeded: Boolean; +procedure Com_Startup(ObjectType: Longint); +procedure Com_OpenQuick(Handle: Longint); +procedure Com_GetModemStatus(var LineStatus, ModemStatus: Byte); +procedure Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); +procedure Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); +procedure Com_SetDtr(State: Boolean); +procedure Com_Close; +procedure Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); +procedure Com_SendWait(var Block; BlockLen: Longint; var Written: Longint; Slice: SliceProc); +procedure Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); +procedure Com_PurgeOutBuffer; +procedure Com_PurgeInBuffer; +procedure Com_PauseCom(CloseCom: Boolean); +procedure Com_ResumeCom(OpenCom: Boolean); +procedure Com_FlushOutBuffer(Slice: SliceProc); +procedure Com_SendString(Temp: String); +procedure Com_SetDontClose(Value: Boolean); +procedure Com_ShutDown; +procedure Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); + + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + var ComObj : pCommObj; + ComSystem: Longint; +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Int_ComReadProc(var TempPtr: Pointer); +begin + {$IFDEF WIN32} + Case ComSystem of + 1 : PWin32Obj(ComObj)^.Com_DataProc(TempPtr); + 2 : PTelnetObj(ComObj)^.Com_ReadProc(TempPtr); + end; { case } + {$ENDIF} + + {$IFDEF OS2} + Case ComSystem of + 1 : POs2Obj(ComObj)^.Com_ReadProc(TempPtr); + 2 : PTelnetObj(ComObj)^.Com_ReadProc(TempPtr); + end; { case } + {$ENDIF} +end; { proc. Int_ComReadProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Int_ComWriteProc(var TempPtr: Pointer); +begin + {$IFDEF WIN32} + Case ComSystem of + 1 : PWin32Obj(ComObj)^.Com_DataProc(TempPtr); + 2 : PTelnetObj(ComObj)^.Com_WriteProc(TempPtr); + end; { case } + {$ENDIF} + + {$IFDEF OS2} + Case ComSystem of + 1 : POs2Obj(ComObj)^.Com_WriteProc(TempPtr); + 2 : PTelnetObj(ComObj)^.Com_WriteProc(TempPtr); + end; { case } + {$ENDIF} +end; { proc. Int_ComWriteProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_Startup(ObjectType: Longint); +begin + ComSystem := ObjectType; + + Case Objecttype of + {$IFDEF WIN32} + 01 : ComObj := New(pWin32Obj, Init); + 02 : ComObj := New(pTelnetObj, Init); + {$ENDIF} + + {$IFDEF OS2} + 01 : ComObj := New(pOs2Obj, Init); + 02 : ComObj := New(pTelnetObj, Init); + {$ENDIF} + + {$IFDEF MSDOS} + 01 : ComObj := New(pFossilObj, Init); + {$ENDIF} + + {$IFDEF GO32V2} + 01 : ComObj := New(pFossilObj, Init); + {$ENDIF} + end; { case } + + {$IFDEF WIN32} + ComObj^.Com_SetDataProc(@Int_ComReadProc, @Int_ComWriteProc); + {$ENDIF} + + {$IFDEF OS2} + ComObj^.Com_SetDataProc(@Int_ComReadProc, @Int_ComWriteProc); + {$ENDIF} +end; { proc. Com_Startup } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_OpenQuick(Handle: Longint); +begin + ComObj^.Com_OpenQuick(Handle); +end; { proc. Com_OpenQuick } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; +begin + Com_Open := ComObj^.Com_Open(Comport, BaudRate, DataBits, Parity, StopBits); +end; { func. Com_Open } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_OpenKeep(Comport: Byte): Boolean; +begin + Com_OpenKeep := ComObj^.Com_OpenKeep(Comport); +end; { func. Com_OpenKeep } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_GetModemStatus(var LineStatus, ModemStatus: Byte); +begin + ComObj^.Com_GetModemStatus(LineStatus, ModemStatus); +end; { proc. Com_GetModemStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); +begin + ComObj^.Com_SetLine(BpsRate, Parity, DataBits, StopBits); +end; { proc. Com_SetLine } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_GetBPSrate: Longint; +begin + Com_GetBpsRate := ComObj^.Com_GetBpsRate; +end; { func. Com_GetBpsRate } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); +begin + ComObj^.Com_GetBufferStatus(InFree, OutFree, InUsed, OutUsed); +end; { proc. Com_GetBufferStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SetDtr(State: Boolean); +begin + ComObj^.Com_SetDtr(State); +end; { proc. Com_SetDtr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_CharAvail: Boolean; +begin + Com_CharAvail := ComObj^.Com_CharAvail; +end; { func. Com_CharAvail } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_Carrier: Boolean; +begin + Com_Carrier := ComObj^.Com_Carrier; +end; { func. Com_Carrier } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_ReadyToSend(BlockLen: Longint): Boolean; +begin + Com_ReadyToSend := ComObj^.Com_ReadyToSend(BlockLen); +end; { func. Com_ReadyToSend } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_GetChar: Char; +begin + Com_GetChar := ComObj^.Com_GetChar; +end; { func. Com_GetChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_PeekChar: Char; +begin + Com_PeekChar := ComObj^.Com_PeekChar; +end; { func. Com_GetChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_SendChar(C: Char): Boolean; +begin + Com_SendChar := ComObj^.Com_SendChar(C); +end; { func. Com_SendChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_GetDriverInfo: String; +begin + Com_GetDriverInfo := ComObj^.Com_GetDriverInfo; +end; { func. Com_GetDriverInfo } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_GetHandle: Longint; +begin + Com_GetHandle := ComObj^.Com_GetHandle; +end; { func. Com_GetHandle } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function Com_InitSucceeded: Boolean; +begin + Com_InitSucceeded := ComObj^.Com_InitSucceeded; +end; { func. Com_InitSucceeded } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_Close; +begin + ComObj^.Com_Close; +end; { proc. Com_Close } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); +begin + ComObj^.Com_SendBlock(Block, BlockLen, Written); +end; { proc. Com_SendBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SendWait(var Block; BlockLen: Longint; var Written: Longint; Slice: SliceProc); +begin + ComObj^.Com_SendWait(Block, BlockLen, Written, Slice); +end; { proc. Com_SendWait } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); +begin + ComObj^.Com_ReadBlock(Block, BlockLen, Reads); +end; { proc. Com_ReadBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_PurgeOutBuffer; +begin + ComObj^.Com_PurgeOutBuffer; +end; { proc. Com_PurgeOutBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_PurgeInBuffer; +begin + ComObj^.Com_PurgeInBuffer; +end; { proc. Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_PauseCom(CloseCom: Boolean); +begin + ComObj^.Com_PauseCom(CloseCom); +end; { proc. Com_PauseCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_ResumeCom(OpenCom: Boolean); +begin + ComObj^.Com_ResumeCom(OpenCom); +end; { proc. Com_ResumeCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_FlushOutBuffer(Slice: SliceProc); +begin + ComObj^.Com_FlushOutBuffer(Slice); +end; { proc. Com_FlushOutBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SendString(Temp: String); +begin + ComObj^.Com_SendString(Temp); +end; { Com_SendString } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SetDontClose(Value: Boolean); +begin + ComObj^.DontClose := Value; +end; { proc. Com_SetDontClose } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_ShutDown; +begin + Dispose(ComObj, Done); +end; { proc. Com_ShutDown } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); +begin + ComObj^.Com_SetFlow(SoftTX, SoftRX, Hard); +end; { proc. Com_SetFlow } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +begin + ComObj := nil; +end. diff --git a/SOURCE/ELECOM/EXAM2.PAS b/SOURCE/ELECOM/EXAM2.PAS new file mode 100644 index 0000000..da00107 --- /dev/null +++ b/SOURCE/ELECOM/EXAM2.PAS @@ -0,0 +1,150 @@ +program Exam2; +(* +** +** EXAMPLE how to use communications +** This is only an example of how to use EleCOM independently of a BBS program, +** to see an example how to use EleCOM as a door from a BBS program, see +** EXAMPLE.PAS +** TELNET is not supported as we dont have a telnet server +** +** version: 1.01 +** Created: 30-Sep-1999 +** +** Fire up line: EXAM2.EXE -C +** eg: EXAM2.EXE -C4 +** +*) + +{.DEFINE FOSSIL} +{.DEFINE OS2COM} +{$DEFINE W32COM} + +{$IFNDEF FOSSIL} + {$IFNDEF OS2COM} + {$IFNDEF W32COM} + You need to define one of these.. + {$ENDIF} + {$ENDIF} +{$ENDIF} + +uses Combase, + {$IFDEF FOSSIL} + Fos_Com + {$ENDIF} + + {$IFDEF OS2COM} + Os2Com + {$ENDIF} + + {$IFDEF W32COM} + W32SNGL + {$ENDIF} ; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +var ComObj : PCommObj; + ComPort : Longint; + ReadCH : Char; + IsTelnet : Boolean; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Int_ComReadProc(var TempPtr: Pointer); +begin + {$IFDEF WIN32} + Case IsTelnet of + FALSE : PWin32Obj(ComObj)^.Com_DataProc(TempPtr); + end; { case } + {$ENDIF} + + {$IFDEF OS2} + Case IsTelnet of + FALSE : POs2Obj(ComObj)^.Com_ReadProc(TempPtr); + end; { case } + {$ENDIF} +end; { proc. Int_ComReadProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Int_ComWriteProc(var TempPtr: Pointer); +begin + {$IFDEF WIN32} + Case IsTelnet of + FALSE : PWin32Obj(ComObj)^.Com_DataProc(TempPtr); + end; { case } + {$ENDIF} + + {$IFDEF OS2} + Case IsTelnet of + FALSE : POs2Obj(ComObj)^.Com_WriteProc(TempPtr); + end; { case } + {$ENDIF} +end; { proc. Int_ComWriteProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure ParseCommandLine; +var Counter: Longint; + TempStr: String; + {$IFDEF MSDOS} + Code : Integer; + {$ELSE} + Code : Longint; + {$ENDIF} +begin + for Counter := 01 to ParamCount do + begin + TempStr := ParamStr(Counter); + + if TempStr[1] in ['/', '-'] then + Case UpCase(TempStr[2]) of + 'C' : begin + + TempStr := Copy(TempStr, 3, Length(TempStr) - 2); + Val(TempStr, ComPort, Code); + + end; { 'C' } + end; { case } + + end; { for } +end; { proc. ParseCommandLine } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + + +begin + IsTelnet := false; + ParseCommandLine; + + {$IFDEF W32COM} + ComObj := New(PWin32Obj, Init); + {$ENDIF} + + {$IFDEF FOSSIL} + ComObj := New(PFossilObj, Init); + {$ENDIF} + + {$IFDEF OS2COM} + ComObj := New(POs2Obj, Init); + {$ENDIF} + + {$IFDEF WIN32} + ComObj^.Com_SetDataProc(@Int_ComReadProc, @Int_ComWriteProc); + {$ENDIF} + + {$IFDEF OS2} + ComObj^.Com_SetDataProc(@Int_ComReadProc, @Int_ComWriteProc); + {$ENDIF} + + ComObj^.Com_OpenKeep(Comport); { Dont change any comport settings } + ComObj^.Com_SendString('Hello there!' + #13#10); + + repeat + ReadCH := ComObj^.Com_GetChar; + + if ReadCH <> #13 then + Writeln('Other..'); + until (ReadCH = #13) OR (NOT ComObj^.Com_Carrier); + + Dispose(ComObj, Done); { Dispose the communications object } +end. diff --git a/SOURCE/ELECOM/FOS_COM.PAS b/SOURCE/ELECOM/FOS_COM.PAS new file mode 100644 index 0000000..92d0a4a --- /dev/null +++ b/SOURCE/ELECOM/FOS_COM.PAS @@ -0,0 +1,550 @@ +unit FOS_COM; +(* +** +** Serial and TCP/IP communication routines for DOS, OS/2 and Win9x/NT. +** Tested with: TurboPascal v7.0, (DOS) +** VirtualPascal v2.1, (OS/2, Win32) +** FreePascal v0.99.12 (DOS, Win32) +** Delphi v4.0. (Win32) +** +** Version : 1.01 +** Created : 21-May-1998 +** Last update : 07-Apr-1999 +** +** Note: (c) 1998-1999 by Maarten Bekers +** +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses Dos, Combase; + +type TFossilObj = Object(TCommObj) + Regs : Registers; + FosPort: Byte; + + constructor Init; + destructor Done; + + function Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; virtual; + function Com_OpenKeep(Comport: Byte): Boolean; virtual; + function Com_GetChar: Char; virtual; + function Com_CharAvail: Boolean; virtual; + function Com_Carrier: Boolean; virtual; + function Com_SendChar(C: Char): Boolean; virtual; + function Com_ReadyToSend(BlockLen: Longint): Boolean; virtual; + function Com_GetBPSrate: Longint; virtual; + function Com_GetDriverInfo: String; virtual; + function Com_GetHandle: longint; virtual; + + procedure Com_OpenQuick(Handle: Longint); virtual; + procedure Com_Close; virtual; + procedure Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); virtual; + procedure Com_SendWait(var Block; BlockLen: Longint; var Written: Longint; Slice: SliceProc); virtual; + procedure Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); virtual; + procedure Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); virtual; + procedure Com_SetDtr(State: Boolean); virtual; + procedure Com_GetModemStatus(var LineStatus, ModemStatus: Byte); virtual; + procedure Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); virtual; + procedure Com_PurgeInBuffer; virtual; + procedure Com_PurgeOutBuffer; virtual; + procedure Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); virtual; + end; { object TFossilObj } + +Type PFossilObj = ^TFossilObj; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses Strings + {$IFDEF GO32V2} + ,Go32 + {$ENDIF} ; + + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure DosAlloc(var Selector: Word; var SegMent: Word; Size: Longint); +var Res: Longint; +begin + {$IFDEF GO32V2} + Res := Global_DOS_Alloc(Size); + Selector := Word(Res); + + Segment := Word(RES SHR 16); + {$ENDIF} +end; { proc. DosAlloc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure DosFree(Selector: Word); +begin + {$IFDEF GO32V2} + Global_DOS_Free(Selector); + {$ENDIF} +end; { proc. DosFree } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +constructor TFossilObj.Init; +begin + inherited Init; +end; { constructor Init } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +destructor TFossilObj.Done; +begin + inherited Done; +end; { destructor Done } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure FossilIntr(var Regs: Registers); +begin + Intr($14, Regs); +end; { proc. FossilIntr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TFossilObj.Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; +begin + {-------------------------- Open the comport -----------------------------} + FosPort := (ComPort - 01); + + Regs.AH := $04; + Regs.DX := FosPort; + Regs.BX := $4F50; + + FossilIntr(Regs); + + Com_Open := (Regs.AX = $1954); + InitFailed := (Regs.AX <> $1954); + Com_SetLine(BaudRate, Parity, DataBits, StopBits); +end; { func. TFossilObj.Com_OpenCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TFossilObj.Com_OpenKeep(Comport: Byte): Boolean; +begin + FosPort := (ComPort - 01); + + Regs.AH := $04; + Regs.DX := FosPort; + Regs.BX := $4F50; + + FossilIntr(Regs); + + Com_OpenKeep := (Regs.AX = $1954); + InitFailed := (Regs.AX <> $1954); +end; { func. Com_OpenKeep } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_OpenQuick(Handle: Longint); +begin + {-------------------------- Open the comport -----------------------------} + FosPort := (Handle - 01); + + Regs.AH := $04; + Regs.DX := FosPort; + Regs.BX := $4F50; + + FossilIntr(Regs); + InitFailed := (Regs.AX <> $1954); +end; { proc. Com_OpenQuick } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); +var BPS: Byte; +begin + if BpsRate > 65534 then + BpsRate := 65534; + + Case Word(BpsRate) of { have to typecast to word, else will rte201 in dos } + 1200 : BPS := 128; + 2400 : BPS := 160; + 4800 : BPS := 192; + 9600 : BPS := 224; + 19200 : BPS := 0 + else BPS := 32; + end; { case } + + if DataBits in [6..8] then + BPS := BPS + (DataBits - 5); + + if Parity = 'O' then BPS := BPS + 8 else + If Parity = 'E' then BPS := BPS + 24; + + if StopBits = 2 then BPS := BPS + 04; + + Regs.AH := $00; + Regs.AL := BPS; + Regs.DX := FosPort; + FossilIntr(Regs); +end; { proc. TFossilObj.Com_SetLine } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TFossilObj.Com_GetBPSrate: Longint; +begin + Com_GetBpsRate := 115200; +end; { func. TFossilObj.Com_GetBpsRate } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_Close; +begin + if Dontclose then EXIT; + + Regs.AH := $05; + Regs.DX := FosPort; + FossilIntr(Regs); +end; { proc. TFossilObj.Com_Close } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TFossilObj.Com_SendChar(C: Char): Boolean; +var Written: Longint; +begin + Com_SendWait(C, SizeOf(c), Written, nil); + + Com_SendChar := (Written >= SizeOf(c)); +end; { proc. TFossilObj.Com_SendChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TFossilObj.Com_GetChar: Char; +begin + Regs.AH := $02; + Regs.DX := FosPort; + FossilIntr(Regs); + + Com_GetChar := Chr(Regs.AL); +end; { proc. TFossilObj.Com_ReadChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); +{$IFDEF GO32V2} +var Selector, + Segment : Word; +{$ENDIF} +begin + {$IFDEF MSDOS} + Regs.AH := $18; + Regs.DX := FosPort; + Regs.CX := Blocklen; + Regs.ES := Seg(Block); + Regs.DI := Ofs(Block); + FossilIntr(Regs); + + Reads := Regs.AX; + {$ENDIF} + + {$IFDEF GO32V2} + DosAlloc(Selector, Segment, BlockLen); + + if Int31Error <> 0 then EXIT; + DosmemPut(Segment, 0, Block, BlockLen); + + Regs.AH := $18; + Regs.DX := FosPort; + Regs.CX := Blocklen; + Regs.ES := Segment; + Regs.DI := 0; + FossilIntr(Regs); + + Reads := Regs.AX; + + DosMemGet(Segment, 0, Block, BlockLen); + DosFree(Selector); + {$ENDIF} +end; { proc. TFossilObj.Com_ReadBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); +{$IFDEF GO32V2} +var Selector, + Segment : Word; +{$ENDIF} +begin + {$IFDEF MSDOS} + Regs.AH := $19; + Regs.DX := FosPort; + Regs.CX := Blocklen; + Regs.ES := Seg(Block); + Regs.DI := Ofs(Block); + FossilIntr(Regs); + + Written := Regs.AX; + {$ENDIF} + + {$IFDEF GO32V2} + DosAlloc(Selector, Segment, BlockLen); + + if Int31Error <> 0 then EXIT; + DosmemPut(Segment, 0, Block, BlockLen); + + Regs.AH := $19; + Regs.DX := FosPort; + Regs.CX := Blocklen; + Regs.ES := Segment; + Regs.DI := 0; + FossilIntr(Regs); + + Written := Regs.AX; + + DosMemGet(Segment, 0, Block, BlockLen); + DosFree(Selector); + {$ENDIF} +end; { proc. TFossilObj.Com_SendBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TFossilObj.Com_CharAvail: Boolean; +begin + Regs.AH := $03; + Regs.DX := FosPort; + FossilIntr(Regs); + + Com_CharAvail := (Regs.AH AND 01) <> 00; +end; { func. TFossilObj.Com_CharAvail } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TFossilObj.Com_ReadyToSend(BlockLen: Longint): Boolean; +begin + Regs.AH := $03; + Regs.DX := FosPort; + FossilIntr(Regs); + + Com_ReadyToSend := (Regs.AH AND $20) = $20; +end; { func. TFossilObj.Com_ReadyToSend } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TFossilObj.Com_Carrier: Boolean; +begin + Regs.AH := $03; + Regs.DX := FosPort; + FossilIntr(Regs); + + Com_Carrier := (Regs.AL AND 128) <> 00; +end; { func. TFossilObj.Com_Carrier } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_SetDtr(State: Boolean); +begin + Regs.AH := $06; + Regs.AL := Byte(State); + Regs.DX := Fosport; + FossilIntr(Regs); +end; { proc. TFossilObj.Com_SetDtr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_GetModemStatus(var LineStatus, ModemStatus: Byte); +begin + Regs.AH := $03; + Regs.DX := FosPort; + FossilIntr(Regs); + + ModemStatus := Regs.AL; + LineStatus := Regs.AH; +end; { proc. TFossilObj.Com_GetModemStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); +type + FosRec = record + Size : Word; + Spec : Byte; + Rev : Byte; + ID : Pointer; + InSize : Word; + InFree : Word; + OutSize : Word; + OutFree : Word; + SWidth : Byte; + SHeight : Byte; + BaudMask : Byte; + Junk : Word; + end; + +var Com_Info: FosRec; + + Selector, + Segment : Word; +begin + {$IFDEF MSDOS} + Regs.AH := $1B; + Regs.DX := FosPort; + Regs.ES := Seg(Com_Info); + Regs.DI := Ofs(Com_Info); + Regs.CX := SizeOf(Com_Info); + {$ENDIF} + + {$IFDEF GO32V2} + DosAlloc(Selector, Segment, SizeOf(Com_Info)); + if Int31Error <> 0 then EXIT; + + DosmemPut(Segment, 0, Com_Info, SizeOf(Com_Info)); + + Regs.AH := $1B; + Regs.DX := FosPort; + Regs.ES := Segment; + Regs.DI := 0; + Regs.CX := SizeOf(Com_Info); + FossilIntr(Regs); + + DosMemGet(Segment, 0, Com_Info, SizeOf(Com_Info)); + DosFree(Selector); + {$ENDIF} + + FossilIntr(Regs); + + InFree := Com_Info.InFree; + InUsed := Com_Info.InSize - Com_Info.InFree; + + OutFree := Com_Info.OutFree; + OutUsed := Com_Info.OutSize - Com_Info.OutFree; +end; { proc. TFossilObj.Com_GetBufferStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TFossilObj.Com_GetDriverInfo: String; +type + FosRec = record + Size : Word; + Spec : Byte; + Rev : Byte; + ID : PChar; + InSize : Word; + InFree : Word; + OutSize : Word; + OutFree : Word; + SWidth : Byte; + SHeight : Byte; + BaudMask : Byte; + Junk : Word; + end; + +var Com_Info: FosRec; + Segment, + Selector: Word; +begin + FillChar(Com_Info, SizeOf(FosRec), #00); + + {$IFDEF MSDOS} + Regs.AH := $1B; + Regs.DX := FosPort; + Regs.ES := Seg(Com_Info); + Regs.DI := Ofs(Com_Info); + Regs.CX := SizeOf(Com_Info); + {$ENDIF} + + {$IFDEF GO32V2} + DosAlloc(Selector, Segment, SizeOf(Com_Info)); + if Int31Error <> 0 then EXIT; + + DosmemPut(Segment, 0, Com_Info, SizeOf(Com_Info)); + + Regs.AH := $1B; + Regs.DX := FosPort; + Regs.ES := Segment; + Regs.DI := 0; + Regs.CX := SizeOf(Com_Info); + FossilIntr(Regs); + + DosMemGet(Segment, 0, Com_Info, SizeOf(Com_Info)); + DosFree(Selector); + {$ENDIF} + + FossilIntr(Regs); + Com_GetDriverInfo := StrPas(Com_Info.ID); +end; { proc. TFossilObj.Com_GetDriverInfo } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_PurgeInBuffer; +begin + Regs.AH := $0A; + Regs.DX := FosPort; + + FossilIntr(Regs); +end; { proc. TFossilObj.Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_PurgeOutBuffer; +begin + Regs.AH := $09; + Regs.DX := FosPort; + + FossilIntr(Regs); +end; { proc. TFossilObj.Com_PurgeOutBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TFossilObj.Com_GetHandle: longint; +begin + Com_GetHandle := FosPort; +end; { func. Com_GetHandle } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_SendWait(var Block; BlockLen: Longint; var Written: Longint; Slice: SliceProc); +var RestLen : Longint; + Temp : Array[0..(1024 * 50)] of Char ABSOLUTE Block; + MaxTries: Longint; +begin + RestLen := BlockLen; + MaxTries := (Com_GetBpsRate div 8); + + repeat + Com_SendBlock(Temp[BlockLen - RestLen], RestLen, Written); + + Dec(RestLen, Written); + Dec(MaxTries); + + if RestLen <> 0 then + if @Slice <> nil then + Slice; + until (RestLen <= 0) OR (NOT COM_Carrier) OR (MaxTries < 0); + + Written := (BlockLen - RestLen); +end; { proc. Com_SendWait } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TFossilObj.Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); +begin + Regs.AH := $0F; + + if SoftTX then + Regs.AL := $01 + else Regs.AL := $00; + + if SoftRX then + Regs.AL := Regs.AL OR $08; + + if Hard then + Regs.AL := Regs.AL OR $02; + + Regs.DX := FosPort; + FossilIntr(Regs); +end; { proc. Com_SetFlow } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +end. diff --git a/SOURCE/ELECOM/HISTORY.102 b/SOURCE/ELECOM/HISTORY.102 new file mode 100644 index 0000000..a8b34f6 --- /dev/null +++ b/SOURCE/ELECOM/HISTORY.102 @@ -0,0 +1,19 @@ +WHATSNEW +======== + +30 July 2000 : Initial DoRxEvent and DoTxEvent were set in true state + which could cause initial very high CPU usage. +18 June 2000 : Changed the way EleCOM calls it threaded functions, making + EleCOM useful for applications where more than one comport + has to be controlled at a time. +20 February 2000 : W32SNGL.PAS or WIN32COM.PAS now include WINDEF.FPC if + compiled with the FPC compiler. This include file redefines + (some) of the Win32 API calls to make sure they are the + correct calling format for us (= the same as with Delphi + and VirtualPascal) +09 September 1999: W32SNGL.PAS - Reduced the number of threads used by this + engine. This one works better on Win9x systems. +05 September 1999: TELNET.PAS added some extra error information to make sure + errors can be more easily diagnosed. +29 August 1999 : ELENORM.PAS - "Plain, vanilly" Pascal version you can use + as a wrapper around the OOP code. diff --git a/SOURCE/ELECOM/HISTORY.103 b/SOURCE/ELECOM/HISTORY.103 new file mode 100644 index 0000000..c9a944f --- /dev/null +++ b/SOURCE/ELECOM/HISTORY.103 @@ -0,0 +1,24 @@ +WHATSNEW +======== + +16 June 2002 : Added a very small state machine to the IAC parser of the + telnet code, to prevent misses of IAC's on the last + character of the buffer. +23 December 2000 : Increased buffersizes that Win32 allocates for in/out + communications. It now uses 3k, instead of 256 bytes. +30 July 2000 : Initial DoRxEvent and DoTxEvent were set in true state + which could cause initial very high CPU usage. +18 June 2000 : Changed the way EleCOM calls it threaded functions, making + EleCOM useful for applications where more than one comport + has to be controlled at a time. +20 February 2000 : W32SNGL.PAS or WIN32COM.PAS now include WINDEF.FPC if + compiled with the FPC compiler. This include file redefines + (some) of the Win32 API calls to make sure they are the + correct calling format for us (= the same as with Delphi + and VirtualPascal) +09 September 1999: W32SNGL.PAS - Reduced the number of threads used by this + engine. This one works better on Win9x systems. +05 September 1999: TELNET.PAS added some extra error information to make sure + errors can be more easily diagnosed. +29 August 1999 : ELENORM.PAS - "Plain, vanilly" Pascal version you can use + as a wrapper around the OOP code. diff --git a/SOURCE/ELECOM/IBMSO32.PAS b/SOURCE/ELECOM/IBMSO32.PAS new file mode 100644 index 0000000..583e395 --- /dev/null +++ b/SOURCE/ELECOM/IBMSO32.PAS @@ -0,0 +1,113 @@ +unit IBMSO32; + +{$OrgName+ } + +interface + +uses OS2Def; + +{$CDECL+} + (****************************************************************************) + function IBM_accept(SFamily: ULong; + SAddr: pointer; + SAddrL: pointer): APIRET; + (****************************************************************************) + function IBM_bind(SSocket: ULong; + SAddr: pointer; + SAddrLen: ULong): APIRET; + (****************************************************************************) + function IBM_connect(SSocket: ULong; + SAddr: pointer; + SAddrLen:ULong): APIRET; + (****************************************************************************) + function IBM_gethostid: APIRET; + (****************************************************************************) + function IBM_select( Sockets: pointer; + noreads, nowrites, noexcepts: longint; + timeout: longint ): ApiRet; + (****************************************************************************) + function IBM_getsockname(SSocket: ULong; + SName: pointer; + SLength: pointer): APIRET; + (****************************************************************************) + function IBM_ioctl(SSocket: ULong; + SRequest: longint; + SArgp: pointer; + ArgSize: longint): APIRET; + (****************************************************************************) + function IBM_listen(SSocket: ULong; + SQueue: ULong): APIRET; + (****************************************************************************) + function IBM_getsockopt(SSocket: uLong; + sLevel: LongInt; + sOptname: LongInt; + sOptVal: pchar; + var sOptLen: LongInt ): ApiRet; + (****************************************************************************) + FUNCTION IBM_setsockopt(sSocket: ulong; + sLevel: uLong; + sOptName: uLong; + sOptVal: pointer; + sOptLen: uLong ): ApiRet; + (****************************************************************************) + function IBM_recv(SSocket: ULong; + SBuffer: pointer; + SLength: ULong; + SFlags: ULong): APIRET; + (****************************************************************************) + function IBM_send(SSocket: ULong; + SBuffer: pointer; + SLength: ULong; + SFlags: ULong): APIRET; + (****************************************************************************) + function IBM_socket(SDomain: ULong; + SType: ULong; + SProtocol: ULong): APIRET; + (****************************************************************************) + function IBM_soclose(SProtocol: ULong): APIRET; + (****************************************************************************) + function IBM_sock_errno: APIRET; + (****************************************************************************) + function IBM_shutdown(SSocket: ULong; + SFlags: ULong): APIRET; + (****************************************************************************) + function IBM_sock_init: APIRET; + (****************************************************************************) + function IBM_so_cancel(SProtocol: ULong): APIRET; + (****************************************************************************) +{$CDECL-} + +implementation + +const + Version = '00.90'; + UseString: string = '@(#)import interface unit for IBM TCP/IP so32dll.dll'+#0; + CopyRight1: string = '@(#)ibmso32dll Version '+Version+' - 10.10.96'+#0; + CopyRight2: string = '@(#)(C) Chr.Hohmann BfS ST2.2 1996'+#0; + +const + sockets = 'SO32DLL'; + network = 'TCP32DLL'; + +{$CDECL+} + function IBM_accept; external sockets index 1; + function IBM_bind; external sockets index 2; + function IBM_connect; external sockets index 3; + function IBM_gethostid; external sockets index 4; + function IBM_getsockname; external sockets index 6; + function IBM_ioctl; external sockets index 8; + function IBM_listen; external sockets index 9; + function IBM_recv; external sockets index 10; + function IBM_send; external sockets index 13; + function IBM_socket; external sockets index 16; + function IBM_soclose; external sockets index 17; + function IBM_sock_errno; external sockets index 20; + function IBM_shutdown; external sockets index 25; + function IBM_sock_init; external sockets index 26; + function IBM_so_cancel; external sockets index 18; + function IBM_getsockopt; external sockets index 7; + function IBM_setsockopt; external sockets index 15; + function IBM_select; external sockets index 12; +{$CDECL-} + +end. diff --git a/SOURCE/ELECOM/IBMTCP32.PAS b/SOURCE/ELECOM/IBMTCP32.PAS new file mode 100644 index 0000000..4b97627 --- /dev/null +++ b/SOURCE/ELECOM/IBMTCP32.PAS @@ -0,0 +1,53 @@ +unit IBMTCP32; + +{$OrgName+ } + +interface + +uses OS2Def, SockDef; + +{$CDECL+} + (****************************************************************************) + function IBM_gethostbyname(HName: pointer): pointer; + (****************************************************************************) + function IBM_gethostbyaddr(HAddr: pointer; + HAddrLen: longint; + HAddrType: ULong): pointer; + (****************************************************************************) + function IBM_gethostname(HName: pointer; + HLength:ULong): APIRET; + (****************************************************************************) + function IBM_getservbyname(_Name, _Proto: pChar): pServEnt; + function inet_addr(_s: pChar): ULONG; + + function getprotobyname(_Name: pChar): pProtoEnt; + + function htonl(_a: LongInt): LongInt; + function ntohl(_a: LongInt): LongInt; +{ function htons(_a: LongInt): LongInt; } +{ function ntohs(_a: SmallInt): SmallInt; } +{$CDECL-} + +implementation + +const + Version = '00.90'; + UseString: string = '@(#)import interface unit for IBM TCP/IP tcp32dll.dll'+#0; + CopyRight1: string = '@(#)ibmTCP32 Version '+Version+' - 10.10.96'+#0; + CopyRight2: string = '@(#)(C) Chr.Hohmann BfS ST2.2 1996'+#0; + +const + sockets = 'SO32DLL'; + network = 'TCP32DLL'; + +{$CDECL+} + function inet_addr; external network index 5; + function IBM_gethostbyname; external network index 11; + function IBM_gethostbyaddr; external network index 12; + function IBM_gethostname; external network index 44; + function getprotobyname; external network index 21; + function IBM_getservbyname; external network index 24; + function htonl; external network index 3; + function ntohl; external network index 3; +{$CDECL-} +end. diff --git a/SOURCE/ELECOM/OS2COM.PAS b/SOURCE/ELECOM/OS2COM.PAS new file mode 100644 index 0000000..57f620f --- /dev/null +++ b/SOURCE/ELECOM/OS2COM.PAS @@ -0,0 +1,786 @@ +unit OS2COM; +(* +** +** Serial and TCP/IP communication routines for DOS, OS/2 and Win9x/NT. +** Tested with: TurboPascal v7.0, (DOS) +** VirtualPascal v2.1, (OS/2, Win32) +** FreePascal v0.99.12 (DOS, Win32) +** Delphi v4.0. (Win32) +** +** Version : 1.01 +** Created : 21-May-1998 +** Last update : 12-May-1999 +** +** Note: (c) 1998-1999 by Maarten Bekers +** +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses Combase, BufUnit, Threads, + {$IFDEF OS2} + Os2Base + {$ENDIF} + + {$IFDEF VirtualPascal} + ,Use32 + {$ENDIF}; + +Const WriteTimeout = 20000; { Wait max. 20 secs } + ReadTimeOut = 5000; { General event, 5 secs max } + + InBufSize = 1024 * 32; + OutBufSize = 1024 * 32; + +type TOs2Obj = Object(TCommObj) + ReadProcPtr: Pointer; { Pointer to TX/RX handler (thread) } + WriteProcPtr: Pointer; { Pointer to TX/RX handler (thread) } + ThreadsInitted: Boolean; { Are the thread(s) up and running? } + + ClientHandle : Longint; + + InBuffer : ^BufArrayObj; { Buffer system internally used } + OutBuffer : ^BufArrayObj; + + DoTxEvent : PSysEventObj; { Event manually set when we have to transmit } + DoRxEvent : PSysEventObj; { Event manually set when we need data } + + TxClosedEvent : PSysEventObj; { Event set when the Tx thread is closed } + RxClosedEvent : PSysEventObj; { Event set when the Rx thread is closed } + + CriticalTx : PExclusiveObj; { Critical sections } + CriticalRx : PExclusiveObj; + + TxThread : PThreadsObj; { The Transmit and Receive threads } + RxThread : PThreadsObj; + + EndThreads : Boolean; { Set to true when we have to end the threads } + + constructor Init; + destructor Done; + + function Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; virtual; + function Com_OpenKeep(Comport: Byte): Boolean; virtual; + function Com_GetChar: Char; virtual; + function Com_CharAvail: Boolean; virtual; + function Com_Carrier: Boolean; virtual; + function Com_SendChar(C: Char): Boolean; virtual; + function Com_ReadyToSend(BlockLen: Longint): Boolean; virtual; + function Com_GetBPSrate: Longint; virtual; + function Com_GetHandle: Longint; virtual; + + procedure Com_OpenQuick(Handle: Longint); virtual; + procedure Com_Close; virtual; + procedure Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); virtual; + procedure Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); virtual; + procedure Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); virtual; + procedure Com_SetDtr(State: Boolean); virtual; + procedure Com_GetModemStatus(var LineStatus, ModemStatus: Byte); virtual; + procedure Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); virtual; + procedure Com_PurgeInBuffer; virtual; + procedure Com_PurgeOutBuffer; virtual; + procedure Com_FlushOutBuffer(Slice: SliceProc); virtual; + + procedure Com_PauseCom(CloseCom: Boolean); virtual; + procedure Com_ResumeCom(OpenCom: Boolean); virtual; + procedure Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); virtual; + + procedure Com_SetDataProc(ReadPtr, WritePtr: Pointer); virtual; + + procedure Com_ReadProc(var TempPtr: Pointer); + procedure Com_WriteProc(var TempPtr: Pointer); + + function Com_StartThread: Boolean; + procedure Com_InitVars; + procedure Com_StopThread; + end; { object TOs2Obj } + +Type POs2Obj = ^TOs2Obj; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses SysUtils; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +constructor TOs2Obj.Init; +begin + inherited Init; + + Com_InitVars; + ThreadsInitted := FALSE; +end; { constructor Init } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +destructor TOs2Obj.Done; +begin + inherited done; +end; { destructor Done } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_ReadProc(var TempPtr: Pointer); +Type TBuffRec = Record + BytesIn : SmallWord; { Number of bytes in the buffer } + MaxSize : SmallWord; { Full size of the buffer } + end; { TBuffRec } + +var Available : Boolean; + BytesRead : Longint; + BlockLen : Longint; + ReturnCode: Longint; + BufferRec : TBuffRec; +begin + repeat + if DoRxEvent.WaitForEvent(ReadTimeOut) then + if NOT EndThreads then + begin + CriticalRx.EnterExclusive; + ReturnCode := 0; + DosDevIoCtl(ClientHandle, { File-handle } + ioctl_Async, { Category } + async_GetInQueCount, { Function } + nil, { Params } + ReturnCode, { Max param length } + @ReturnCode, { Param Length } + @BufferRec, { Returned data } + SizeOf(TBuffRec), { Max data length } + @ReturnCode); { Data length } + + Available := (BufferRec.BytesIn > 00); + + DoRxEvent.ResetEvent; + + if Available then + begin + {----------- Start reading the gathered date -------------------} + + if InBuffer^.BufRoom > 0 then + begin + BlockLen := BufferRec.BytesIn; + if BlockLen > InBuffer^.BufRoom then + BlockLen := InBuffer^.BufRoom; + if BlockLen > 1024 then + BlockLen := 1024; + + if BlockLen > 00 then + begin + DosRead(ClientHandle, + InBuffer^.TmpBuf, + BlockLen, + BytesRead); + + InBuffer^.Put(InBuffer^.TmpBuf, BytesRead); + end; { if } + + end; { if } + end; { if available } + + CriticalRx.LeaveExclusive; + end; { if RxEvent } + until EndThreads; + + RxClosedEvent.SignalEvent; + ExitThisThread; +end; { proc. ComReadProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_WriteProc(var TempPtr: Pointer); +var BlockLen : Longint; + Written : Longint; + ReturnCode : Longint; + TempBuf : ^CharBufType; +begin + New(TempBuf); + + repeat + if DoTxEvent.WaitForEvent(WriteTimeOut) then + if NOT EndThreads then + begin + CriticalTx.EnterExclusive; + DoTxEvent.ResetEvent; + + if OutBuffer^.BufUsed > 00 then + begin + Written := 00; + BlockLen := OutBuffer^.Get(OutBuffer^.TmpBuf, OutBuffer^.BufUsed, false); + + DosWrite(ClientHandle, + OutBuffer^.TmpBuf, + BlockLen, + Written); + + ReturnCode := OutBuffer^.Get(OutBuffer^.TmpBuf, Written, true); + if Written <> BlockLen then + DoTxEvent.SignalEvent; + end; { if } + + CriticalTx.LeaveExclusive; + end; { if } + + until EndThreads; + + Dispose(TempBuf); + TxClosedEvent.SignalEvent; + ExitThisThread; +end; { proc. ComWriteProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TOs2Obj.Com_StartThread: Boolean; +begin + Result := false; + EndThreads := false; + if ThreadsInitted then EXIT; + ThreadsInitted := true; + + {----------------------- Create all the events ----------------------------} + New(DoTxEvent, Init); + if NOT DoTxEvent.CreateEvent(false) then EXIT; + + New(DoRxEvent, Init); + if NOT DoRxEvent.CreateEvent(false) then EXIT; + + New(RxClosedEvent, Init); + if NOT RxClosedEvent.CreateEvent(false) then EXIT; + + New(TxClosedEvent, Init); + if NOT TxClosedEvent.CreateEvent(false) then EXIT; + + + {-------------- Startup the buffers and overlapped events -----------------} + New(InBuffer, Init(InBufSize)); + New(OutBuffer, Init(OutBufSize)); + + {-------------------- Startup a seperate write thread ---------------------} + New(CriticalTx, Init); + CriticalTx.CreateExclusive; + + New(TxThread, Init); + if NOT TxThread.CreateThread(16384, { Stack size } + WriteProcPtr, { Actual procedure } + nil, { Parameters } + 0) { Creation flags } + then EXIT; + + {-------------------- Startup a seperate read thread ----------------------} + New(CriticalRx, Init); + CriticalRx.CreateExclusive; + + New(RxThread, Init); + if NOT RxThread.CreateThread(16384, { Stack size } + ReadProcPtr, { Actual procedure } + nil, { Parameters } + 0) { Creation flags } + then EXIT; + + Result := true; +end; { proc. Com_StartThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_InitVars; +begin + DoTxEvent := nil; + DoRxEvent := nil; + RxClosedEvent := nil; + TxClosedEvent := nil; + TxThread := nil; + RxThread := nil; + + InBuffer := nil; + OutBuffer := nil; + CriticalRx := nil; + CriticalTx := nil; +end; { proc. Com_InitVars } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_StopThread; +begin + EndThreads := true; + ThreadsInitted := false; + + if DoTxEvent <> nil then DoTxEvent.SignalEvent; + if DoTxEvent <> nil then DoRxEvent.SignalEvent; + + + if TxThread <> nil then TxThread.CloseThread; + if RxThread <> nil then RxThread.CloseThread; + + if TxClosedEvent <> nil then + if NOT TxClosedEvent^.WaitForEvent(1000) then + TxThread.TerminateThread(0); + + if RxClosedEvent <> nil then + if NOT RxClosedEvent^.WaitForEvent(1000) then + RxThread.TerminateThread(0); + + if TxThread <> nil then TxThread.Done; + if RxThread <> nil then RxThread.Done; + + if DoTxEvent <> nil then Dispose(DoTxEvent, Done); + if DoRxEvent <> nil then Dispose(DoRxEvent, Done); + if RxClosedEvent <> nil then Dispose(RxClosedEvent, Done); + if TxClosedEvent <> nil then Dispose(TxClosedEvent, Done); + + if CriticalTx <> nil then Dispose(CriticalTx, Done); + if CriticalRx <> nil then Dispose(CriticalRx, Done); + + if InBuffer <> nil then Dispose(InBuffer, Done); + if OutBuffer <> nil then Dispose(OutBuffer, Done); + + Com_InitVars; +end; { proc. Com_StopThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TOs2Obj.Com_GetHandle: Longint; +begin + Result := ClientHandle; +end; { func. Com_GetHandle } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_OpenQuick(Handle: Longint); +begin + ClientHandle := Handle; + + InitFailed := NOT Com_StartThread; +end; { proc. TOs2Obj.Com_OpenQuick } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TOs2Obj.Com_OpenKeep(Comport: Byte): Boolean; +var ReturnCode: Longint; + OpenAction: Longint; + Temp : Array[0..15] of Char; +begin + InitFailed := NOT Com_StartThread; + + if NOT InitFailed then + begin + OpenAction := file_Open; + StrpCopy(Temp, 'COM' + IntToStr(ComPort)); + + ReturnCode := + DosOpen(Temp, { Filename, eg: COM2 } + ClientHandle, + OpenAction, + 0, { Filesize } + 0, { Attributes } + FILE_OPEN or OPEN_ACTION_OPEN_IF_EXISTS, { Open flags } + OPEN_ACCESS_READWRITE or OPEN_SHARE_DENYNONE or { OpenMode } + OPEN_FLAGS_FAIL_ON_ERROR, + nil); { Extended attributes } + + InitFailed := (ReturnCode <> 0); + end; { if } + + Com_OpenKeep := NOT InitFailed; +end; { func. Com_OpenKeep } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TOs2Obj.Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; +begin + InitFailed := true; + + if Com_OpenKeep(Comport) then + begin + Com_SetLine(BaudRate, Parity, DataBits, StopBits); + + InitFailed := false; + end; { if } + + Com_Open := NOT InitFailed; +end; { func. TOs2Obj.Com_OpenCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); +type TBpsRec = Record + Rate : Longint; + Frac : Byte; + end; { record } + +var TempRec : Array[1..3] of Byte; + BpsRec : TBpsRec; + RetLength : Longint; + Temp_Parity : Byte; + Temp_StopBits: Byte; +begin + if NOT (DataBits in [5,7,8]) then DataBits := 8; + if NOT (Parity in ['O', 'E', 'N', 'M', 'S']) then Parity := 'N'; + if NOT (StopBits in [0..2]) then StopBits := 1; + + Temp_Parity := 00; + Case Parity of + 'N' : Temp_Parity := 00; + 'O' : Temp_Parity := 01; + 'E' : Temp_Parity := 02; + 'M' : Temp_Parity := 03; + 'S' : Temp_Parity := 04; + end; { case } + + Temp_Stopbits := 00; + Case StopBits of + 1 : StopBits := 0; + 2 : StopBits := 2; + end; { case } + + Fillchar(TempRec, SizeOf(TempRec), 00); + TempRec[01] := DataBits; + TempRec[02] := Temp_Parity; + TempRec[03] := Temp_StopBits; + + {------------------------- Set line parameters ----------------------------} + DosDevIoCtl(ClientHandle, { File-handle } + ioctl_Async, { Category } + async_SetLineCtrl, { Function } + @TempRec, { Params } + SizeOf(TempRec), { Max param length } + @RetLength, { Param Length } + @TempRec, { Returned data } + SizeOf(TempRec), { Max data length } + @RetLength); { Data length } + + {------------------------- Set speed parameters ---------------------------} + BpsRec.Rate := BpsRate; + BpsRec.Frac := 00; + DosDevIoCtl(ClientHandle, { File-handle } + ioctl_Async, { Category } + async_ExtSetBaudRate, { Function } + @BpsRec, { Params } + SizeOf(BpsRec), { Max param length } + @RetLength, { Param Length } + @BpsRec, { Returned data } + SizeOf(BpsRec), { Max data length } + @RetLength); { Data length } +end; { proc. TOs2Obj.Com_SetLine } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_Close; +begin + if DontClose then EXIT; + + if ClientHandle <> -1 then + begin + Com_StopThread; + DosClose(ClientHandle); + + ClientHandle := -1; + end; { if } + +end; { func. TOs2Obj.Com_CloseCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TOs2Obj.Com_SendChar(C: Char): Boolean; +var Written: Longint; +begin + Com_SendBlock(C, SizeOf(C), Written); + Com_SendChar := (Written = SizeOf(c)); +end; { proc. TOs2Obj.Com_SendChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TOs2Obj.Com_GetChar: Char; +var Reads: Longint; +begin + Com_ReadBlock(Result, SizeOf(Result), Reads); +end; { func. TOs2Obj.Com_GetChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); +begin + if OutBuffer^.BufRoom < BlockLen then + repeat + {$IFDEF OS2} + DosSleep(1); + {$ENDIF} + until (OutBuffer^.BufRoom >= BlockLen) OR (NOT Com_Carrier); + + CriticalTx.EnterExclusive; + Written := OutBuffer^.Put(Block, BlockLen); + CriticalTx.LeaveExclusive; + + DoTxEvent.SignalEvent; +end; { proc. TOs2Obj.Com_SendBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); +begin + if InBuffer^.BufUsed < BlockLen then + begin + repeat + if Com_CharAvail then + DoRxEvent.SignalEvent; + + DosSleep(1); + until (InBuffer^.BufUsed >= BlockLen) OR (NOT Com_Carrier); + end; { if } + + CriticalRx.EnterExclusive; + Reads := InBuffer^.Get(Block, BlockLen, true); + CriticalRx.LeaveExclusive; +end; { proc. TOs2Obj.Com_ReadBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TOs2Obj.Com_CharAvail: Boolean; + +Type TBuffRec = Record + BytesIn : SmallWord; { Number of bytes in the buffer } + MaxSize : SmallWord; { Full size of the buffer } + end; { TBuffRec } + +var ReturnCode: Longint; + BufferRec : TBuffRec; +begin + if InBuffer^.BufUsed < 1 then + begin + ReturnCode := 0; + DosDevIoCtl(ClientHandle, { File-handle } + ioctl_Async, { Category } + async_GetInQueCount, { Function } + nil, { Params } + ReturnCode, { Max param length } + @ReturnCode, { Param Length } + @BufferRec, { Returned data } + SizeOf(TBuffRec), { Max data length } + @ReturnCode); { Data length } + + if (BufferRec.BytesIn > 0) then + DoRxEvent.SignalEvent; + end; { if } + + Result := (InBuffer^.BufUsed > 0); +end; { func. TOs2Obj.Com_CharAvail } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TOs2Obj.Com_Carrier: Boolean; +var Status : Byte; + RetLength : Longint; +begin + DosDevIoCtl(ClientHandle, { File-handle } + ioctl_Async, { Category } + async_GetModemInput, { Function } + nil, { Params } + 00, { Max param length } + @RetLength, { Param Length } + @Status, { Returned data } + SizeOf(Status), { Max data length } + @RetLength); { Data length } + + Com_Carrier := Status AND 128 <> 00; +end; { func. TOs2Obj.Com_Carrier } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_GetModemStatus(var LineStatus, ModemStatus: Byte); +begin + LineStatus := 00; + ModemStatus := 08; + + if Com_Carrier then ModemStatus := ModemStatus OR (1 SHL 7); +end; { proc. TOs2Obj.Com_GetModemStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_SetDtr(State: Boolean); +type + TRtsDtrRec = record + Onmask, + Offmask : Byte; + end; { record } + +var MaskRec : TRtsDtrRec; + RetLength : Longint; +begin + if State then + begin + MaskRec.OnMask := $01; + MaskRec.OffMask := $FF; + end + else begin + MaskRec.OnMask := $00; + MaskRec.OffMask := $FE; + end; { if } + + DosDevIoCtl(ClientHandle, { File-handle } + ioctl_Async, { Category } + async_SetModemCtrl, { Function } + @MaskRec, { Params } + SizeOf(MaskRec), { Max param length } + @RetLength, { Param Length } + @MaskRec, { Returned data } + SizeOf(MaskRec), { Max data length } + @RetLength); { Data length } +end; { proc. TOs2Obj.Com_SetDtr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TOs2Obj.Com_GetBpsRate: Longint; +type + TBpsRec = record + CurBaud : Longint; { Current BaudRate } + CurFrac : Byte; { Current Fraction } + MinBaud : Longint; { Minimum BaudRate } + MinFrac : Byte; { Minimum Fraction } + MaxBaud : Longint; { Maximum BaudRate } + MaxFrac : Byte; { Maximum Fraction } + end; { TBpsRec } + +var BpsRec : TBpsRec; + Status : Byte; + RetLength: Longint; +begin + DosDevIoCtl(ClientHandle, { File-handle } + ioctl_Async, { Category } + async_ExtGetBaudRate, { Function } + nil, { Params } + 00, { Max param length } + @RetLength, { Param Length } + @BpsRec, { Returned data } + SizeOf(BpsRec), { Max data length } + @RetLength); { Data length } + + Com_GetBpsRate := BpsRec.CurBaud; +end; { func. TOs2Obj.Com_GetBpsRate } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); +begin + DoRxEvent.SignalEvent; + DoTxEvent.SignalEvent; + + InFree := InBuffer^.BufRoom; + OutFree := OutBuffer^.BufRoom; + InUsed := InBuffer^.BufUsed; + OutUsed := OutBuffer^.BufUsed; +end; { proc. TOs2Obj.Com_GetBufferStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_PurgeInBuffer; +begin + CriticalRx.EnterExclusive; + + InBuffer^.Clear; + + CriticalRx.LeaveExclusive; +end; { proc. TOs2Obj.Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_PurgeOutBuffer; +begin + CriticalTx.EnterExclusive; + + OutBuffer^.Clear; + + CriticalTx.LeaveExclusive; +end; { proc. TOs2Obj.Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_FlushOutBuffer(Slice: SliceProc); +begin + DosResetBuffer(ClientHandle); + + inherited Com_FlushOutBuffer(Slice); +end; { proc. Com_FlushOutBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + + +function TOs2Obj.Com_ReadyToSend(BlockLen: Longint): Boolean; +begin + Result := OutBuffer^.BufRoom >= BlockLen; +end; { func. ReadyToSend } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_PauseCom(CloseCom: Boolean); +begin + if CloseCom then Com_Close + else Com_StopThread; +end; { proc. Com_PauseCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_ResumeCom(OpenCom: Boolean); +begin + if OpenCom then Com_OpenKeep(0) + else Com_StartThread; +end; { proc. Com_ResumeCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); +var Dcb : DCBINFO; + RetLength: Longint; +begin + FillChar(Dcb, SizeOF(Dcb), 0); + + DosDevIoCtl(ClientHandle, { File-handle } + ioctl_Async, { Category } + async_GetDcbInfo, { Function } + nil, { Params } + 00, { Max param length } + @RetLength, { Param Length } + @Dcb, { Returned data } + SizeOf(DcbInfo), { Max data length } + @RetLength); { Data length } + + if (SoftTX) or (SoftRX) then + begin + dcb.fbFlowReplace := dcb.fbFlowReplace + MODE_AUTO_RECEIVE + MODE_AUTO_TRANSMIT; + end + else begin + dcb.fbFlowReplace := MODE_RTS_HANDSHAKE; + dcb.fbCtlHndShake := dcb.fbCtlHndShake + MODE_CTS_HANDSHAKE; + end; { if } + + dcb.fbTimeout := MODE_NO_WRITE_TIMEOUT + MODE_WAIT_READ_TIMEOUT; + dcb.bXONChar := $11; + dcb.bXOFFChar := $13; + + RetLength := SizeOf(DcbInfo); + DosDevIoCtl(ClientHandle, { File-handle } + ioctl_Async, { Category } + async_SetDcbInfo, { Function } + @Dcb, { Params } + SizeOf(DcbInfo), { Max param length } + @RetLength, { Param Length } + nil, { Returned data } + RetLength, { Max data length } + @RetLength); { Data length } + +end; { proc. Com_SetFlow } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TOs2Obj.Com_SetDataProc(ReadPtr, WritePtr: Pointer); +begin + ReadProcPtr := ReadPtr; + WriteProcPtr := WritePtr; +end; { proc. Com_SetDataProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +end. diff --git a/SOURCE/ELECOM/PROCS.TXT b/SOURCE/ELECOM/PROCS.TXT new file mode 100644 index 0000000..c745fc8 --- /dev/null +++ b/SOURCE/ELECOM/PROCS.TXT @@ -0,0 +1,109 @@ +Procedure overview +================== + ++---------------------+---------------+----------------------------------------+ +| Name | Parameters | Explanation | ++---------------------+---------------+----------------------------------------+ +| Com_OpenQuick | | Open the comport without init. | +| | Handle | Use these two handles for quickinit | ++------------------------------------------------------------------------------+ +| Com_Open | | Opens the connection and set params | +| | Comport | Comport to open (COM1 = 1) | +| | BaudRate | | +| | DataBits, | | +| | Parity | | +| | StopBits | | ++------------------------------------------------------------------------------+ +| Com_Openkeep | | Open the comport without setting params| +| | Comport | | ++------------------------------------------------------------------------------+ +| Com_GetModemStatus | | Get the line/modem parameters | +| | LineStatus | | +| | ModemStatus | | ++------------------------------------------------------------------------------+ +| Com_SetLine | | Set the comm. parameters | +| | BPSrate | | +| | Parity | | +| | DataBits | | +| | StopBits | | ++------------------------------------------------------------------------------+ +| Com_GetBPSrate | | Returns the current line-speed | +| | | | ++------------------------------------------------------------------------------+ +| Com_GetBufferStatus | | Get the current buffer statusses | +| | InFree | Bytes free in input buffer | +| | OutFree | Bytes free in output buffer | +| | InUsed | Bytes currently used in input buffer | +| | OutUsed | Bytes currently used in output buffer | ++------------------------------------------------------------------------------+ +| Com_SetDTR | | Set DTR setting | +| | State | ++------------------------------------------------------------------------------+ +| Com_CharAvail | | Returns TRUE if there's a char avail. | +| | | | ++------------------------------------------------------------------------------+ +| Com_Carrier | | Returns TRUE if the DTR signal is high | +| | | | ++------------------------------------------------------------------------------+ +| Com_ReadyToSend | | Room enough for this block? | +| | Blocklen | Number of bytes we want to send | ++------------------------------------------------------------------------------+ +| Com_GetChar | | Get one character from the input buffer| +| | | | ++------------------------------------------------------------------------------+ +| Com_SendChar | | Send one character to the remote | +| | | | ++------------------------------------------------------------------------------+ +| Com_GetDriverInfo | | Returns the driver info (FOSSIL only) | +| | | | ++------------------------------------------------------------------------------+ +| Com_GetHandle | | Get the current used handle | +| | | | ++------------------------------------------------------------------------------+ +| Com_InitSucceeded | | Returns TRUE if the initialization | +| | | succeeded | ++------------------------------------------------------------------------------+ +| Com_Close | | Closes the comport and stop the | +| | | threads | ++------------------------------------------------------------------------------+ +| Com_SendBlock | | Sends a block to the remote. | +| | Block | Warning: Make sure that the block you | +| | BlockLen | send isn't larger than the | +| | Written | available buffer size, else | +| | | this routine will block | +| | | indefinitaly | ++------------------------------------------------------------------------------+ +| Com_SendWait | | Sends a block to the remote, this | +| | Block | routine will wait till all the size is | +| | BlockLen | sent under FOSSIL, else it's the same | +| | Written | as Com_SendBlock. | +| | Slice | Slice is called when waiting for all to| +| | | get out. | ++------------------------------------------------------------------------------+ +| Com_ReadBlock | | Gets a block from the remote | +| | Block | Block to read into | +| | BlockLen | Amount of bytes we want (will block!) | +| | Reads | Amount of bytes we actually gotten | ++------------------------------------------------------------------------------+ +| Com_PurgeOutBuffer | | Kill all the pending output | +| | | | ++------------------------------------------------------------------------------+ +| Com_PurgeInBuffer | | Kill all the pending input | +| | | | ++------------------------------------------------------------------------------+ +| Com_PauseCom | | Pause the communications. Stop threads | +| | CloseCom | ++------------------------------------------------------------------------------+ +| Com_ResumeCom | | Resums communications. Start threads | +| | CloseCom | | ++------------------------------------------------------------------------------+ +| Com_FlushOutBuffer | | Wait till all pending output is done | +| | SliceProc | Procedure is called while waiting.. | ++------------------------------------------------------------------------------+ +| Com_SendString | | Send this string to the remote | +| | Temp | String to send | ++------------------------------------------------------------------------------+ +| Com_SetDataProc | | Set read/write thread handlers | +| | ReadPtr | Pointer to read thread procedure | +| | WritePtr | Pointer to write thread procedure | ++----------------------------------------------------(c)2000 by Maarten Bekers-+ diff --git a/SOURCE/ELECOM/README.TXT b/SOURCE/ELECOM/README.TXT new file mode 100644 index 0000000..4b4ae4f --- /dev/null +++ b/SOURCE/ELECOM/README.TXT @@ -0,0 +1,17 @@ +ELECOM v1.03 - release notes +============================ + +These communication routines are released as freeware. You are free to do with +these routines whatever you want, but please give me proper credit when you do +use them (a small email to me mentioning that you are using them would be +great as well). + +When you make any changes, enhancements or additions, please send me a copy +of the changes so I can include them in the next release. + +Have fun, + +groeten, Maarten Bekers + +website: www.elebbs.com +email : maarten@elebbs.com diff --git a/SOURCE/ELECOM/SOCKDEF.PAS b/SOURCE/ELECOM/SOCKDEF.PAS new file mode 100644 index 0000000..fa52e1a --- /dev/null +++ b/SOURCE/ELECOM/SOCKDEF.PAS @@ -0,0 +1,606 @@ +unit SockDef; +(* +** +** SOCKDEF routines +** +** Copyright (c) 1998 by Thomas W. Mueller +** +** Created : 24-Oct-1998 +** Last update : 24-Oct-1998 +** +** +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses + Sysutils, +{$IFDEF OS2} + Os2def; +{$ENDIF} +{$IFDEF LINUX} + Linux; +{$ENDIF} +{$IFDEF WIN32} + Windows; +{$ENDIF} + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +{$IFDEF VER0_99_13} +type pInteger = ^Integer; + tFarProc = pointer; + SmallInt = System.Integer; +{$ENDIF} + +{$IFDEF LINUX} +type ULONG = longint; +{$ENDIF} + +type + tSockDesc = LongInt; + SmallWord = System.Word; + +type + eSocketErr = class(Exception); + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +const + MaxHostNameLen = 120; + +(* +** Option flags per-socket. +*) +{$IFNDEF LINUX} +(* +** Level number for (get/set)sockopt() to apply to socket itself. +*) + SOL_SOCKET =$ffff; // options for socket level + + SO_DEBUG =$0001; // turn on debugging info recording + SO_ACCEPTCONN =$0002; // socket has had listen() + SO_REUSEADDR =$0004; // allow local address reuse + SO_KEEPALIVE =$0008; // keep connections alive + SO_DONTROUTE =$0010; // just use interface addresses + SO_BROADCAST =$0020; // permit sending of broadcast msgs + SO_USELOOPBACK =$0040; // bypass hardware when possible + SO_LINGER =$0080; // linger on close if data present + SO_OOBINLINE =$0100; // leave received OOB data in line + +(* +** Additional options, not kept in so_options. +*) + SO_SNDBUF =$1001; // send buffer size + SO_RCVBUF =$1002; // receive buffer size + SO_SNDLOWAT =$1003; // send low-water mark + SO_RCVLOWAT =$1004; // receive low-water mark + SO_SNDTIMEO =$1005; // send timeout + SO_RCVTIMEO =$1006; // receive timeout + SO_ERROR =$1007; // get error status and clear + SO_TYPE =$1008; // get socket type + +{$ELSE} + SOL_SOCKET = 1; + + SO_DEBUG = 1; + SO_REUSEADDR = 2; + SO_TYPE = 3; + SO_ERROR = 4; + SO_DONTROUTE = 5; + SO_BROADCAST = 6; + SO_SNDBUF = 7; + SO_RCVBUF = 8; + SO_KEEPALIVE = 9; + SO_OOBINLINE = 10; + SO_NO_CHECK = 11; + SO_PRIORITY = 12; + SO_LINGER = 13; + SO_BSDCOMPAT = 14; +{$ENDIF} + + +(* +** Address families. +*) + AF_UNSPEC = 0; // unspecified + AF_UNIX = 1; // local to host (pipes, portals) + AF_INET = 2; // internetwork: UDP, TCP, etc. + AF_IMPLINK = 3; // arpanet imp addresses + AF_PUP = 4; // pup protocols: e.g. BSP + AF_CHAOS = 5; // mit CHAOS protocols + AF_NS = 6; // XEROX NS protocols + AF_NBS = 7; // nbs protocols + AF_ECMA = 8; // european computer manufacturers + AF_DATAKIT = 9; // datakit protocols + AF_CCITT = 10; // CCITT protocols, X.25 etc + AF_SNA = 11; // IBM SNA + AF_DECnet = 12; // DECnet + AF_DLI = 13; // Direct data link interface + AF_LAT = 14; // LAT + AF_HYLINK = 15; // NSC Hyperchannel + AF_APPLETALK = 16; // Apple Talk + + AF_OS2 = AF_UNIX; + + AF_NB = 17; // Netbios + AF_NETBIOS = AF_NB; + + AF_MAX = 18; + +(* +** Protocol families, same as address families for now. +*) + PF_UNSPEC = AF_UNSPEC; + PF_UNIX = AF_UNIX; + PF_INET = AF_INET; + PF_IMPLINK = AF_IMPLINK; + PF_PUP = AF_PUP; + PF_CHAOS = AF_CHAOS; + PF_NS = AF_NS; + PF_NBS = AF_NBS; + PF_ECMA = AF_ECMA; + PF_DATAKIT = AF_DATAKIT; + PF_CCITT = AF_CCITT; + PF_SNA = AF_SNA; + PF_DECnet = AF_DECnet; + PF_DLI = AF_DLI; + PF_LAT = AF_LAT; + PF_HYLINK = AF_HYLINK; + PF_APPLETALK = AF_APPLETALK; + PF_NETBIOS = AF_NB; + PF_NB = AF_NB; + PF_OS2 = PF_UNIX; + PF_MAX = AF_MAX; + +(* +** Maximum queue length specifiable by listen. +*) + + SOMAXCONN = 5; + + FREAD =1; + FWRITE =2; + + MSG_OOB =$1; // process out-of-band data + MSG_PEEK =$2; // peek at incoming message + MSG_DONTROUTE =$4; // send without using routing tables + MSG_FULLREAD =$8; // send without using routing tables + + MSG_MAXIOVLEN =16; + +const +{ All Windows Sockets error constants are biased by WSABASEERR from the "normal" } + + WSABASEERR = 10000; + +{ Windows Sockets definitions of regular Microsoft C error constants } + + WSAEINTR = (WSABASEERR+4); + WSAEBADF = (WSABASEERR+9); + WSAEACCES = (WSABASEERR+13); + WSAEFAULT = (WSABASEERR+14); + WSAEINVAL = (WSABASEERR+22); + WSAEMFILE = (WSABASEERR+24); + +{ Windows Sockets definitions of regular Berkeley error constants } + +{$IFNDEF LINUX} + WSAEWOULDBLOCK = (WSABASEERR+35); + WSAEINPROGRESS = (WSABASEERR+36); + WSAEALREADY = (WSABASEERR+37); + WSAENOTSOCK = (WSABASEERR+38); + WSAEDESTADDRREQ = (WSABASEERR+39); + WSAEMSGSIZE = (WSABASEERR+40); + WSAEPROTOTYPE = (WSABASEERR+41); + WSAENOPROTOOPT = (WSABASEERR+42); + WSAEPROTONOSUPPORT = (WSABASEERR+43); + WSAESOCKTNOSUPPORT = (WSABASEERR+44); + WSAEOPNOTSUPP = (WSABASEERR+45); + WSAEPFNOSUPPORT = (WSABASEERR+46); + WSAEAFNOSUPPORT = (WSABASEERR+47); + WSAEADDRINUSE = (WSABASEERR+48); + WSAEADDRNOTAVAIL = (WSABASEERR+49); + WSAENETDOWN = (WSABASEERR+50); + WSAENETUNREACH = (WSABASEERR+51); + WSAENETRESET = (WSABASEERR+52); + WSAECONNABORTED = (WSABASEERR+53); + WSAECONNRESET = (WSABASEERR+54); + WSAENOBUFS = (WSABASEERR+55); + WSAEISCONN = (WSABASEERR+56); + WSAENOTCONN = (WSABASEERR+57); + WSAESHUTDOWN = (WSABASEERR+58); + WSAETOOMANYREFS = (WSABASEERR+59); + WSAETIMEDOUT = (WSABASEERR+60); + WSAECONNREFUSED = (WSABASEERR+61); + WSAELOOP = (WSABASEERR+62); + WSAENAMETOOLONG = (WSABASEERR+63); + WSAEHOSTDOWN = (WSABASEERR+64); + WSAEHOSTUNREACH = (WSABASEERR+65); + WSAENOTEMPTY = (WSABASEERR+66); + WSAEPROCLIM = (WSABASEERR+67); + WSAEUSERS = (WSABASEERR+68); + WSAEDQUOT = (WSABASEERR+69); + WSAESTALE = (WSABASEERR+70); + WSAEREMOTE = (WSABASEERR+71); + + WSAEDISCON = (WSABASEERR+101); +{$ENDIF} + +{$IFDEF LINUX} + WSAEWOULDBLOCK = 11; + WSAEINPROGRESS = 115; + WSAEALREADY = 114; + WSAENOTSOCK = 88; + WSAEDESTADDRREQ = 89; + WSAEMSGSIZE = 90; + WSAEPROTOTYPE = 91; + WSAENOPROTOOPT = 92; + WSAEPROTONOSUPPORT = 93; + WSAESOCKTNOSUPPORT = 94; + WSAEOPNOTSUPP = 95; + WSAEPFNOSUPPORT = 96; + WSAEAFNOSUPPORT = 97; + WSAEADDRINUSE = 98; + WSAEADDRNOTAVAIL = 99; + WSAENETDOWN = 100; + WSAENETUNREACH = 101; + WSAENETRESET = 102; + WSAECONNABORTED = 103; + WSAECONNRESET = 104; + WSAENOBUFS = 105; + WSAEISCONN = 106; + WSAENOTCONN = 107; + WSAESHUTDOWN = 108; + WSAETOOMANYREFS = 109; + WSAETIMEDOUT = 110; + WSAECONNREFUSED = 111; + WSAELOOP = 40; + WSAENAMETOOLONG = 36; + WSAEHOSTDOWN = 112; + WSAEHOSTUNREACH = 113; + WSAENOTEMPTY = 39; + WSAEPROCLIM = 00; + WSAEUSERS = 87; + WSAEDQUOT = 122; + WSAESTALE = 116; + WSAEREMOTE = 66; +{$ENDIF} + +{ Extended Windows Sockets error constant definitions } + + WSASYSNOTREADY = (WSABASEERR+91); + WSAVERNOTSUPPORTED = (WSABASEERR+92); + WSANOTINITIALISED = (WSABASEERR+93); + +{ Error return codes from gethostbyname() and gethostbyaddr() + (when using the resolver). Note that these errors are + retrieved via WSAGetLastError() and must therefore follow + the rules for avoiding clashes with error numbers from + specific implementations or language run-time systems. + For this reason the codes are based at WSABASEERR+1001. + Note also that [WSA]NO_ADDRESS is defined only for + compatibility purposes. } + +{ Authoritative Answer: Host not found } + + WSAHOST_NOT_FOUND = (WSABASEERR+1001); + HOST_NOT_FOUND = WSAHOST_NOT_FOUND; + +{ Non-Authoritative: Host not found, or SERVERFAIL } + + WSATRY_AGAIN = (WSABASEERR+1002); + TRY_AGAIN = WSATRY_AGAIN; + +{ Non recoverable errors, FORMERR, REFUSED, NOTIMP } + + WSANO_RECOVERY = (WSABASEERR+1003); + NO_RECOVERY = WSANO_RECOVERY; + +{ Valid name, no data record of requested type } + + WSANO_DATA = (WSABASEERR+1004); + NO_DATA = WSANO_DATA; + +{ no address, look for MX record } + + WSANO_ADDRESS = WSANO_DATA; + NO_ADDRESS = WSANO_ADDRESS; + +{ Windows Sockets errors redefined as regular Berkeley error constants. + These are commented out in Windows NT to avoid conflicts with errno.h. + Use the WSA constants instead. } + + EWOULDBLOCK = WSAEWOULDBLOCK; + EINPROGRESS = WSAEINPROGRESS; + EALREADY = WSAEALREADY; + ENOTSOCK = WSAENOTSOCK; + EDESTADDRREQ = WSAEDESTADDRREQ; + EMSGSIZE = WSAEMSGSIZE; + EPROTOTYPE = WSAEPROTOTYPE; + ENOPROTOOPT = WSAENOPROTOOPT; + EPROTONOSUPPORT = WSAEPROTONOSUPPORT; + ESOCKTNOSUPPORT = WSAESOCKTNOSUPPORT; + EOPNOTSUPP = WSAEOPNOTSUPP; + EPFNOSUPPORT = WSAEPFNOSUPPORT; + EAFNOSUPPORT = WSAEAFNOSUPPORT; + EADDRINUSE = WSAEADDRINUSE; + EADDRNOTAVAIL = WSAEADDRNOTAVAIL; + ENETDOWN = WSAENETDOWN; + ENETUNREACH = WSAENETUNREACH; + ENETRESET = WSAENETRESET; + ECONNABORTED = WSAECONNABORTED; + ECONNRESET = WSAECONNRESET; + ENOBUFS = WSAENOBUFS; + EISCONN = WSAEISCONN; + ENOTCONN = WSAENOTCONN; + ESHUTDOWN = WSAESHUTDOWN; + ETOOMANYREFS = WSAETOOMANYREFS; + ETIMEDOUT = WSAETIMEDOUT; + ECONNREFUSED = WSAECONNREFUSED; + ELOOP = WSAELOOP; + ENAMETOOLONG = WSAENAMETOOLONG; + EHOSTDOWN = WSAEHOSTDOWN; + EHOSTUNREACH = WSAEHOSTUNREACH; + ENOTEMPTY = WSAENOTEMPTY; + EPROCLIM = WSAEPROCLIM; + EUSERS = WSAEUSERS; + EDQUOT = WSAEDQUOT; + ESTALE = WSAESTALE; + EREMOTE = WSAEREMOTE; + + SockAddr_Len = 16; + In_Addr_Len = 4; + InAddr_Any = 0; + InAddr_Loopback = $7F000001; + InAddr_Broadcast = $FFFFFFFF; + InAddr_None = $FFFFFFFF; + + SOCK_NULL = 0; + SOCK_STREAM = 1; // stream socket + SOCK_DGRAM = 2; // datagram socket + SOCK_RAW = 3; // raw-protocol interface + SOCK_RDM = 4; // reliably-delivered message + SOCK_SEQPACKET = 5; // sequenced packet stream + + IPPROTO_NULL = 0; + IPPROTO_UDP = 17; + IPPROTO_TCP = 6; + + +const + IOCPARM_MASK = $7f; + IOC_VOID = $20000000; + IOC_OUT = $40000000; + IOC_IN = $80000000; + IOC_INOUT = (IOC_IN or IOC_OUT); + +{$IFNDEF LINUX} + FIONREAD = IOC_OUT or { get # bytes to read } + ((Longint(SizeOf(Longint)) and IOCPARM_MASK) shl 16) or + (Longint(Byte('f')) shl 8) or 127; + FIONBIO = IOC_IN or { set/clear non-blocking i/o } + ((Longint(SizeOf(Longint)) and IOCPARM_MASK) shl 16) or + (Longint(Byte('f')) shl 8) or 126; + FIOASYNC = IOC_IN or { set/clear async i/o } + ((Longint(SizeOf(Longint)) and IOCPARM_MASK) shl 16) or + (Longint(Byte('f')) shl 8) or 125; +{$ENDIF} + +type + pLongInt = ^LongInt; + + pIoVec = ^tIoVec; + tIoVec = packed record + iov_base: POINTER; + iov_len: LongInt; + end; + +(* +** Structure used for manipulating linger option. +*) + tLinger = packed record + l_onoff: LongInt; // option on/off + l_linger: LongInt; // linger time + END; + +(* +** Structure used by kernel to pass protocol +** information in raw sockets. +*) + + tSockProto = packed record + sp_family: WORD; // address family + sp_protocol: WORD; // protocol + END; + + off_t = LongInt; + + tuio = packed record + uio_iov: pIoVec; + uio_iovcnt: LongInt; + uio_offset: off_t; + uio_segflg: LongInt; + uio_resid: LongInt; + END; + + pIn_Addr = ^tIn_Addr; + tIn_Addr = packed record + case integer of + 0: (IPAddr: ULong); + 1: (ClassA: byte; + ClassB: byte; + ClassC: byte; + ClassD: byte) + end; + +(* +** Structure used by kernel to store most +** addresses. +*) + pSockAddr=^tSockAddr; + tSockAddr=packed record + case integer of + 0: (Sin_Family: SmallWord; + Sin_Port: SmallWord; + Sin_Addr: tIn_Addr; + Sin_Zero: array[1.. 8] of byte); + 1: (Sa_Family: SmallWord; + Sa_Addr: array[1..14] of byte); + end; + +(* +** Message header for recvmsg and sendmsg calls. +*) + pMsgHdr = ^tMsgHdr; + tMsgHdr = packed record + msg_name: pChar; // optional address + msg_namelen: LongInt; // size of address + msg_iov: pIoVec; // scatter/gather array + msg_iovlen: LongInt; // # elements in msg_iov + msg_accrights: pChar; // access rights sent/received + msg_accrightslen: LongInt; + END; + + uio_rw = ( UIO_READ, UIO_WRITE ); + + pHostEnt = ^tHostEnt; + tHostEnt = packed record + H_Name: ^string; + H_Alias: pointer; +{$IFNDEF WIN32} + H_AddrType: longint; + H_Length: longint; +{$ELSE} + h_addrtype: Smallint; + h_length: Smallint; +{$ENDIF} + H_Addr_List: ^pIn_Addr; + END; + + pProtoEnt = ^tProtoEnt; + TProtoEnt = packed record + p_name: pChar; (* official protocol name *) + p_aliases: ^pChar; (* alias list *) + p_proto: SmallInt; (* protocol # *) + end; + + pServEnt = ^tServEnt; + tServEnt = packed record + s_name: pChar; // official service name + s_aliases: ^pChar; // alias list + s_port: SmallInt; // port # + s_proto: pChar; // protocol to use + END; + +// these types are only used in windows version +const + FD_SETSIZE = 64; + +type + PFDSet = ^TFDSet; + TFDSet = packed record + fd_count: ULONG; + fd_array: array[0..FD_SETSIZE-1] of ULONG; + end; + + PTimeVal = ^TTimeVal; + TTimeVal = packed record + tv_sec: Longint; + tv_usec: Longint; + end; + +const + WSADESCRIPTION_LEN = 256; + WSASYS_STATUS_LEN = 128; + +type + PWSAData = ^TWSAData; + TWSAData = packed record + wVersion: Word; + wHighVersion: Word; + szDescription: array[0..WSADESCRIPTION_LEN] of Char; + szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char; + iMaxSockets: Word; + iMaxUdpDg: Word; + lpVendorInfo: PChar; + end; + +(* +** The re-defination of error constants are necessary to avoid conflict with +** standard IBM C Set/2 V1.0 error constants. +** +** All OS/2 SOCKET API error constants are biased by SOCBASEERR from the "normal" +** +*) + +const + SOCBASEERR = 10000; + +(* +** OS/2 SOCKET API definitions of regular Microsoft C 6.0 error constants +*) + +const + SOCEPERM = (SOCBASEERR+1); (* Not owner *) + SOCESRCH = (SOCBASEERR+3); (* No such process *) + SOCEINTR = (SOCBASEERR+4); (* Interrupted system call *) + SOCENXIO = (SOCBASEERR+6); (* No such device or address *) + SOCEBADF = (SOCBASEERR+9); (* Bad file number *) + SOCEACCES = (SOCBASEERR+13); (* Permission denied *) + SOCEFAULT = (SOCBASEERR+14); (* Bad address *) + SOCEINVAL = (SOCBASEERR+22); (* Invalid argument *) + SOCEMFILE = (SOCBASEERR+24); (* Too many open files *) + SOCEPIPE = (SOCBASEERR+32); (* Broken pipe *) + + SOCEOS2ERR = (SOCBASEERR+100); (* OS/2 Error *) + +(* +** OS/2 SOCKET API definitions of regular BSD error constants +*) + +const + SOCEWOULDBLOCK = (SOCBASEERR+35); (* Operation would block *) + SOCEINPROGRESS = (SOCBASEERR+36); (* Operation now in progress *) + SOCEALREADY = (SOCBASEERR+37); (* Operation already in progress *) + SOCENOTSOCK = (SOCBASEERR+38); (* Socket operation on non-socket *) + SOCEDESTADDRREQ = (SOCBASEERR+39); (* Destination address required *) + SOCEMSGSIZE = (SOCBASEERR+40); (* Message too long *) + SOCEPROTOTYPE = (SOCBASEERR+41); (* Protocol wrong type for socket *) + SOCENOPROTOOPT = (SOCBASEERR+42); (* Protocol not available *) + SOCEPROTONOSUPPORT = (SOCBASEERR+43); (* Protocol not supported *) + SOCESOCKTNOSUPPORT = (SOCBASEERR+44); (* Socket type not supported *) + SOCEOPNOTSUPP = (SOCBASEERR+45); (* Operation not supported on socket *) + SOCEPFNOSUPPORT = (SOCBASEERR+46); (* Protocol family not supported *) + SOCEAFNOSUPPORT = (SOCBASEERR+47); (* Address family not supported by protocol family *) + SOCEADDRINUSE = (SOCBASEERR+48); (* Address already in use *) + SOCEADDRNOTAVAIL = (SOCBASEERR+49); (* Can't assign requested address *) + SOCENETDOWN = (SOCBASEERR+50); (* Network is down *) + SOCENETUNREACH = (SOCBASEERR+51); (* Network is unreachable *) + SOCENETRESET = (SOCBASEERR+52); (* Network dropped connection on reset *) + SOCECONNABORTED = (SOCBASEERR+53); (* Software caused connection abort *) + SOCECONNRESET = (SOCBASEERR+54); (* Connection reset by peer *) + SOCENOBUFS = (SOCBASEERR+55); (* No buffer space available *) + SOCEISCONN = (SOCBASEERR+56); (* Socket is already connected *) + SOCENOTCONN = (SOCBASEERR+57); (* Socket is not connected *) + SOCESHUTDOWN = (SOCBASEERR+58); (* Can't send after socket shutdown *) + SOCETOOMANYREFS = (SOCBASEERR+59); (* Too many references: can't splice *) + SOCETIMEDOUT = (SOCBASEERR+60); (* Connection timed out *) + SOCECONNREFUSED = (SOCBASEERR+61); (* Connection refused *) + SOCELOOP = (SOCBASEERR+62); (* Too many levels of symbolic links *) + SOCENAMETOOLONG = (SOCBASEERR+63); (* File name too long *) + SOCEHOSTDOWN = (SOCBASEERR+64); (* Host is down *) + SOCEHOSTUNREACH = (SOCBASEERR+65); (* No route to host *) + SOCENOTEMPTY = (SOCBASEERR+66); (* Directory not empty *) + +(* +** OS/2 SOCKET API errors redefined as regular BSD error constants +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +end. { unit SockDef } diff --git a/SOURCE/ELECOM/SOCKFUNC.PAS b/SOURCE/ELECOM/SOCKFUNC.PAS new file mode 100644 index 0000000..af25063 --- /dev/null +++ b/SOURCE/ELECOM/SOCKFUNC.PAS @@ -0,0 +1,831 @@ +unit SockFunc; +(* +** +** SOCKFUNC routines +** +** Copyright (c) 1998 by Thomas W. Mueller +** Linux additions (c)1999 by Maarten Bekers +** +** Created : 24-Oct-1998 +** Last update : 24-Oct-1998 +** +** +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*- +** Copyright (c) 1982, 1985, 1986 Regents of the University of California. +** All rights reserved. +** +** Redistribution and use in source and binary forms are permitted +** provided that this notice is preserved and that due credit is given +** to the University of California at Berkeley. The name of the University +** may not be used to endorse or promote products derived from this +** software without specific prior written permission. This software +** is provided ``as is'' without express or implied warranty. +s** +** @(#)socket.h 7.2 (Berkeley) 12/30/87 +-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses +{$IFDEF OS2} + OS2Def, + IBMSO32, + IBMTCP32, +{$ENDIF} + +{$IFDEF WIN32} + windows, + W32Sock, +{$ENDIF} + +{$IFDEF LINUX} + linux, + Linsock, +{$ENDIF} + + Sysutils, + SockDef; + +Const SockInitted : Boolean = false; + +function SockErrorNo: Longint; +function SockGetErrStr(_ErrNo: integer): ShortString; +procedure SockRaiseError(const _prefix: String; _ErrNo: integer); +procedure SockRaiseLastError(const _prefix: String); + +function SockAccept(_SockDesc: tSockDesc; _SockAddr: pSockAddr; + var _SockAddrLen: Longint): tSockDesc; +function SockBind(_SockDesc: tSockDesc; var _SockAddr: tSockAddr): Longint; +function SockCancel(_SockDesc: tSockDesc): Longint; +function SockConnect(_SockDesc: tSockDesc; var _SockAddr: tSockAddr): Longint; +function SockGetHostByName(Hostname: ShortString): phostent; +function SockShutdown(_SockDesc: tSockDesc; _how: ULong): Longint; +function SockGetSockAddr(_SockDesc: tSockDesc; var _SockAddr: tSockAddr): Longint; +function SockGetSockOpt(_SockDesc: tSockDesc; _Level, _OptName: Integer; + _OptVal: PChar; var _OptLen: Integer): Longint; +function SockSetSockOpt(_SockDesc: tSockDesc; _Level: uLong; _OptName: Ulong; + _OptVal: pChar; _OptLen: uLong ): Longint; +function SockSetBlockingIO(_SockDesc: tSockDesc; _BlockingIO: boolean): Longint; +function SockIoCtlSocket(_SockDesc: tSockDesc; Func: Longint): Longint; +function SockListen(_SockDesc: tSockDesc; _SockQueue: ULong): Longint; +function SockRecv(_SockDesc: tSockDesc; _SockBuffer: pointer; + _SockBufLen: ULong; _SockFlags: ULong): Longint; +function SockSend(_SockDesc: tSockDesc; _SockBuffer: pointer; + _SockBufLen: ULong; _SockFlags: ULong ): Longint; +function SockSocket(_SockFamily: word; _SockType: word; + _SockProtocol: word ): tSockDesc; +function SockClose(_SockDesc: tSockDesc): Longint; +function SockInit: Longint; +function SockClientAlive(_SockDesc: tSockDesc): Boolean; + +function SockGetHostAddrByName(_HostName: ShortString): ULONG; +function SockGetHostNameByAddr(_HostAddr: pIn_Addr): ShortString; +function SockGetHostname: ShortString; + +function SockGetServByName(_Name, _Proto: ShortString): pServEnt; +function SockGetServPortByName(_Name, _Proto: ShortString): Longint; + +function SockHtonl(_Input: LongInt): longint; +function SockHtons(_Input: SmallWord): SmallWord; + +function SockNtohl(_Input: LongInt): longint; +function SockNtohs(_Input: SmallWord): longint; +function SockDataAvail(_SockDesc: tSockDesc): Boolean; +function SockSelect(_SockDesc: tSockDesc): Longint; +function SockInetAddr(_s: ShortString):tIn_Addr; + +{$IFNDEF LINUX} + {$IFNDEF FPC} + {$R SOCKFUNC.RES} + {$ENDIF} +{$ENDIF} + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +Const + Version = '1.00'; + UseString: ShortString = '@(#)socket interface unit for IBM TCP/IP and WinSock'#0; + CopyRight1: ShortString = '@(#)socket Version '+Version+' - 26.08.1998'#0; + CopyRight2: ShortString = '@(#}(C) Thomas Mueller 1998'#0; + CopyRight3: ShortString = '@(#)(C) Chr.Hohmann BfS ST2.2 1996'#0; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + + +function SockErrorNo: Longint; +begin + {$IFDEF OS2} + Result := IBM_sock_errno; + {$ENDIF} + + {$IFDEF WIN32} + Result := WsaGetLastError; + {$ENDIF} + + {$IFDEF LINUX} + Result := SocketError; + {$ENDIF} +end; { func. SockErrorNo } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockGetErrStr(_ErrNo: integer): ShortString; +begin + Result:=LoadStr(_ErrNo); +end; { func. SockGetErrStr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure SockRaiseError(const _prefix: String; _ErrNo: integer); +begin + raise eSocketErr.CreateFmt('%s: %s (%d)', + [_prefix, SockGetErrStr(_ErrNo), _ErrNo]); +end; { proc. SockRaiseError } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure SockRaiseLastError(const _prefix: String); +begin + SockRaiseError(_Prefix, SockErrorNo); +end; { proc. SockRaiseLastError } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + + +function SockGetServByName(_Name, _Proto: ShortString): pServEnt; +begin + _Name := _Name + #00; + _Proto := _Proto + #00; + + {$IFDEF WIN32} + Result := getservbyname(@_Name[01], @_Proto[01]); + {$ENDIF} + + {$IFDEF OS2} + Result := ibm_getservbyname(@_Name[01], @_Proto[01]); + {$ENDIF} + + {$IFDEF LINUX} + Result := getservbyname(@_Name[1], @_Proto[01]); + {$ENDIF} +end; { func. SockGetServByName } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockGetServPortByName(_Name, _Proto: ShortString): longint; +var ServEnt: pServEnt; +begin + ServEnt := SockGetServByName(_Name, _Proto); + + if Assigned(ServEnt) then + Result := ServEnt^.s_Port + else Result := -01; +end; { func. SockGetServPortByName } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockHtonl( _Input: longint): longint; +type SwapLong = packed record + case integer of + 0: (SLong: longint); + 1: (SArray: packed array[1..4] of byte); + end; +var Inp, + Tmp: SwapLong; +begin + Inp.SLong := _Input; + Tmp.SArray[1] := Inp.SArray[4]; + Tmp.SArray[2] := Inp.SArray[3]; + Tmp.SArray[3] := Inp.SArray[2]; + Tmp.SArray[4] := Inp.SArray[1]; + result := Tmp.SLong; +end; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockHtons( _Input: SmallWord): SmallWord; +type SwapWord = packed record + case integer of + 0: (SWord: SmallWord); + 1: (SArray: packed array[1..2] of byte); + end; +var Inp,Tmp: SwapWord; +begin + Inp.SWord := _Input; + Tmp.SArray[1] := Inp.SArray[2]; + Tmp.SArray[2] := Inp.SArray[1]; + Result := Tmp.SWord; +end; { func. SockhToNl } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockNtohl( _Input: longint): longint; +begin + {$IFNDEF LINUX} + Result:=ntohl(_Input); + {$ELSE} + {!!!!!!!!!!!!!!!!!!!!!!!} + Result := _Input; + {$ENDIF} +end; { func. sockNToHl } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockNtohs( _Input: SmallWord): longint; +begin + {$IFDEF WIN32} + Result := ntohs( _input); + {$ENDIF} + + {$IFDEF OS2} +{!!!!! Result := ntohs( _input);} + Result := Lo(_Input) * 256 + Hi(_Input); + {$ENDIF} + + {$IFDEF LINUX} + Result := ntohs(_input); + {$ENDIF} +end; { func. SockNToHs } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockAccept(_SockDesc: tSockDesc; + _SockAddr: pSockAddr; + var _SockAddrLen: Longint): longint; +begin + {$IFDEF WIN32} + Result := Accept(_SockDesc, _SockAddr, @_SockAddrLen); + {$ENDIF} + + {$IFDEF OS2} + Result := IBM_Accept(_SockDesc, _SockAddr, @_SockAddrLen); + {$ENDIF} + + {$IFDEF LINUX} + Result := Accept(_SockDesc, _SockAddr^, _SockAddrLen); + {$ENDIF} +end; { func. SockAccept } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockBind(_SockDesc: tSockDesc; + var _SockAddr: tSockAddr ): Longint; +begin + {$IFDEF WIN32} + SockBind := Bind(_SockDesc, @_SockAddr, SockAddr_Len); + {$ENDIF} + + {$IFDEF OS2} + SockBind := IBM_Bind(_SockDesc, @_SockAddr, SockAddr_Len); + {$ENDIF} + + {$IFDEF LINUX} + SockBind := Longint(Bind(_SockDesc, _SockAddr, SockAddr_Len)); + {$ENDIF} +end; { func. SockBind } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockConnect(_SockDesc: tSockDesc; + var _SockAddr: tSockAddr): Longint; +begin + {$IFDEF WIN32} + SockConnect := connect(_SockDesc, @_SockAddr, SockAddr_Len); + {$ENDIF} + + {$IFDEF OS2} + SockConnect := ibm_connect(_SockDesc, @_SockAddr, SockAddr_Len); + {$ENDIF} + + {$IFDEF LINUX} + SockConnect := connect(_SockDesc, _SockAddr, sockAddr_Len); + {$ENDIF} +end; { func. SockConnect } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockCancel(_SockDesc: tSockDesc): Longint; +begin + {$IFDEF WIN32} + Result := SockCancel(_SockDesc); + {$ENDIF} + + {$IFDEF OS2} + Result := IBM_So_Cancel(_SockDesc); + {$ENDIF} + + {$IFDEF LINUX} + Result := longint(true); + if _SockDesc=0 then ; + + {$WARNING SockCancel function not implemented } + {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!} + {$ENDIF} +end; { func. SockCancel } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockShutdown(_SockDesc: tSockDesc; + _how: ULong): Longint; +begin + {$IFDEF WIN32} + SockShutdown := ShutDown(_SockDesc, _How); + {$ENDIF} + + {$IFDEF OS2} + SockShutDown := IBM_ShutDown(_SockDesc, _How); + {$ENDIF} + + {$IFDEF LINUX} + SockShutDown := ShutDown(_SockDesc, _How); + {$ENDIF} +end; { func. SockShutDown } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockGetSockAddr(_SockDesc: tSockDesc; var _SockAddr: tSockAddr): Longint; +var sLength: Integer; +begin + FillChar(_SockAddr, SizeOf(_SockAddr), #00); + sLength := SizeOf(_SockAddr); + + {$IFDEF WIN32} + Result := GetSockName(_SockDesc, @_SockAddr, sLength); + {$ENDIF} + + {$IFDEF OS2} + Result := IBM_GetSockName(_SockDesc, @_SockAddr, @sLength); + {$ENDIF} + + {$IFDEF LINUX} + Result := GetSocketName(_SockDesc, _SockAddr, sLength); + {$ENDIF} +end; { func. sockGetSockAddr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockSetBlockingIO(_SockDesc: tSockDesc; + _BlockingIO: boolean): Longint; +var Arg: ULONG; +begin + {$IFDEF OS2} + if _BlockingIO then Arg := 00 + else Arg := 01; + + Result := IBM_IOCtl(_SockDesc, FIONBIO, @Arg, SizeOf(Arg)); + {$ENDIF} + + {$IFDEF WIN32} + if _BlockingIO then Arg := 00 + else Arg := 01; + + Result := IOCtlSocket(_SockDesc, FIONBIO, Arg); + {$ENDIF} + + {$IFDEF LINUX} + if _BlockingIO then Arg := 00 + else Arg := 01; + + Result := Longint(ioctl(_SockDesc, Linux.FIONBIO, @Arg)); + {$ENDIF} +end; { func. SockSetBlockingIO } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockIoCtlSocket(_SockDesc: tSockDesc; Func: Longint): Longint; +var Arg: ULONG; +begin + Arg := 0; + + {$IFDEF OS2} + Result := IBM_IOCtl(_SockDesc, FUNC, @Arg, SizeOf(Arg)); + {$ENDIF} + + {$IFDEF WIN32} + Result := IOCtlSocket(_SockDesc, FUNC, Arg); + {$ENDIF} + + {$IFDEF LINUX} + Result := Longint(IoCtl(_SockDesc, Func, @Arg)); + {$ENDIF} +end; { func. SockIoCtlSocket } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockGetSockOpt(_SockDesc: tSockDesc; _Level, _OptName: Integer; + _OptVal: PChar; var _OptLen: Integer): Longint; +begin + {$IFDEF WIN32} + Result := GetSockOpt(_SockDesc, _Level, _OptName, _OptVal, _OptLen); + {$ENDIF} + + {$IFDEF OS2} + Result := IBM_GetSockOpt(_SockDesc, _Level, _OptName, _OptVal, _OptLen); + {$ENDIF} + + {$IFDEF LINUX} + Result := SetSocketOptions(_SockDesc, _Level, _OptName, _OptVal, _OptLen); + {$ENDIF} +end; { func. SockGetSockOpt } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockSetSockOpt(_SockDesc: tSockDesc; _Level: uLong; _OptName: Ulong; + _OptVal: pChar; _OptLen: uLong ): Longint; +begin + {$IFDEF WIN32} + Result := SetSockOpt(_SockDesc, _Level, _OptName, _OptVal, _OptLen); + {$ENDIF} + + {$IFDEF OS2} + Result := IBM_SetSockOpt(_SockDesc, _Level, _OptName, _OptVal, _OptLen); + {$ENDIF} + + {$IFDEF LINUX} + Result := SetSocketOptions(_SockDesc, _Level, _OptName, _OptVal, _OptLen); + {$ENDIF} +end; { func. SockSetSockOpt } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockDataAvail(_SockDesc: tSockDesc): Boolean; +{$IFDEF LINUX} + var ReadFDS : FDSet; + Temp : Longint; +{$ENDIF} +begin + {$IFNDEF LINUX} + Result := (SockSelect(_SockDesc) > 00); + {$ELSE} + fd_Zero(ReadFDS); + fd_Set(_SockDesc, ReadFDS); + + Temp := Select(_SockDesc + 01, @ReadFDS, nil, nil, 0); + if (Temp > 0) then + begin + SockDataAvail := FD_ISSET(_SockDesc, ReadFDS); + end { if } + else SockDataAvail := false; + {$ENDIF} +(* + {$IFDEF OS2} + Arg := 00; + Result := IBM_IOCTL(_SockDesc, FIONREAD, @Arg, SizeOf(Arg)); + + if Arg > 00 then Result := Arg + else Result := $FFFFFFFF; + {$ENDIF} + + {$IFDEF WIN32} + Result := IOCtlSocket(_SockDesc, FIONREAD, Arg); + if Arg > 00 then Result := Arg + else Result := $FFFFFFFF; + {$ENDIF} +*) +end; { func. SockDataAvail } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockListen(_SockDesc: tSockDesc; + _SockQueue: ULong): Longint; +begin + {$IFDEF WIN32} + SockListen := listen(_SockDesc, _SockQueue); + {$ENDIF} + + {$IFDEF OS2} + SockListen := ibm_listen(_SockDesc, _SockQueue); + {$ENDIF} + + {$IFDEF LINUX} + SockListen := Longint(Listen(_SockDesc, _SockQueue)); + {$ENDIF} +end; { func. SockListen } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockSelect(_SockDesc: tSockDesc ): Longint; +{$IFDEF OS2} +var SockCopy: ULONG; +{$ENDIF} + +{$IFDEF WIN32} +var SockArr : TFDSet; + Timeout : TTimeVal; +{$ENDIF} + +{$IFDEF LINUX} +var ReadFDS : FDSet; +{$ENDIF} +begin + {$IFDEF OS2} + SockCopy := _SockDesc; + Result := IBM_Select(@SockCopy, 1, 0, 0, 0); + {$ENDIF} + + {$IFDEF WIN32} + SockArr.fd_Count := 01; + SockArr.fd_Array[00] := _SockDesc; + Timeout.tv_sec := 00; + Timeout.tv_usec := 00; + + Result := Select(00, @SockArr, NIL, NIL, @Timeout); + {$ENDIF} + + {$IFDEF LINUX} + fd_Zero(ReadFDS); + fd_Set(_SockDesc, ReadFDS); + + SockSelect := Select(_SockDesc + 01, @ReadFDS, nil, nil, 0); + {$ENDIF} +end; { func. SockSelect } + +(*-+-*-+-*-+-*-+-*-+-*-+ -*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockRecv(_SockDesc: tSockDesc; + _SockBuffer: pointer; + _SockBufLen: ULong; + _SockFlags: ULong): Longint; +var Counter: Longint; +begin + {$IFDEF WIN32} + SockRecv := recv(_SockDesc, + _SockBuffer, + _SockBufLen, + _SockFlags); + {$ENDIF} + + {$IFDEF OS2} + SockRecv := ibm_recv(_SockDesc, + _SockBuffer, + _SockBufLen, + _SockFlags); + {$ENDIF} + + {$IFDEF LINUX} + SockRecv := Recv(_SockDesc, + _SockBuffer^, + _SockBufLen, + _SockFlags); + {$ENDIF} +end; { func. SockRecv } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockSend(_SockDesc: tSockDesc; + _SockBuffer: pointer; + _SockBufLen: ULong; + _SockFlags: ULong): Longint; +begin + {$IFDEF WIN32} + SockSend := Send(_SockDesc, + _SockBuffer, + _SockBufLen, + _SockFlags); + {$ENDIF} + + {$IFDEF OS2} + SockSend := IBM_Send(_SockDesc, + _SockBuffer, + _SockBufLen, + _SockFlags); + {$ENDIF} + + {$IFDEF LINUX} + SockSend := Send(_SockDesc, + _SockBuffer^, + _SockBufLen, + _SockFlags); + {$ENDIF} +end; { func. SockSend } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockSocket(_SockFamily: word; + _SockType: word; + _SockProtocol: word): tSockDesc; +begin + {$IFDEF WIN32} + SockSocket := Socket(_SockFamily, _SockType, _SockProtocol); + {$ENDIF} + + {$IFDEF OS2} + SockSocket := ibm_Socket(_SockFamily, _SockType, _SockProtocol); + {$ENDIF} + + {$IFDEF LINUX} + SockSocket := Socket(_SockFamily, _SockType, _SockProtocol); + {$ENDIF} +end; { func. SockSocket } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockClose(_SockDesc: tSockDesc): Longint; +begin + {$IFDEF OS2} + Result := IBM_soclose(_SockDesc); + {$ENDIF} + + {$IFDEF WIN32} + Result := Closesocket(_SockDesc); + {$ENDIF} + + {$IFDEF LINUX} + Result := Longint(fdClose(_SockDesc)); + {$ENDIF} +end; { func. SockClose } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockInit: Longint; +{$IFDEF WIN32} +var Data: TWSAData; +{$ENDIF} +begin + if SockInitted then EXIT; + SockInitted := true; + + {$IFDEF OS2} + SockInit := IBM_Sock_Init; + {$ENDIF} + + {$IFDEF WIN32} + SockInit := WsaStartup($0101, Data); + {$ENDIF} + + {$IFDEF LINUX} + SockInit := 0; + {$ENDIF} +end; { func. SockInit } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockGetHostByName(Hostname: ShortString): phostent; +begin + HostName := HostName + #00; + {$IFDEF WIN32} + Result := GetHostByName(@HostName[01]); + {$ENDIF} + + {$IFDEF OS2} + Result := IBM_GetHostByName(@HostName[01]); + {$ENDIF} + + {$IFDEF LINUX} + Result := GetHostByName(@HostName[1]); + {$ENDIF} +end; { func. SockGetHostByName } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockGetHostAddrByName(_HostName: ShortString): ULong; +var ReturnCode: pHostEnt; + InAddr : tIn_Addr; +begin + ReturnCode := SockGetHostbyName(_HostName); + if Assigned(ReturnCode) then + begin + InAddr := ReturnCode^.H_Addr_List^^; + Result := InAddr.IpAddr; + end + else Result:=$FFFFFFFF; +end; { func. SockGetHostAddrByName } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockGetHostByAddr(HostAddr: pIn_Addr; + HostAddrLen: ULong; + HostAddrType: ULong): pointer; +begin + {$IFDEF WIN32} + SockGetHostByAddr := GetHostbyAddr(HostAddr, + HostAddrLen, + HostAddrType); + {$ENDIF} + + {$IFDEF OS2} + SockGetHostByAddr := IBM_GetHostbyAddr(HostAddr, + HostAddrLen, + HostAddrType); + {$ENDIF} + + {$IFDEF LINUX} + Result := GetHostByAddr(HostAddr, HostAddrLen, HostAddrtype); + {$ENDIF} +end; { func. SockGetHostbyAddr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockGetHostNameByAddr(_HostAddr: pIn_Addr): ShortString; +var Counter : Integer; + ReturnCode: pHostEnt; + HName : ShortString; +begin + ReturnCode := SockGetHostByAddr(_HostAddr, + In_Addr_Len, + AF_INET); + + if (ULong(ReturnCode) <> 00) then + begin + HName := ''; + Counter := 00; + + While ReturnCode^.H_Name^[Counter] <> #00 do + begin + HName := HName + ReturnCode^.H_Name^[Counter]; + Inc(Counter); + end; { while } + end + else HName := 'Hostname not found'; + + SockGetHostNameByAddr := HName; +end; { func. SockGetHostNameByAddr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockGetHostname: ShortString; +var Counter : Longint; + sResult : Longint; + HostName : ShortString; + InAddr : TIn_Addr; +begin + FillChar(HostName, SizeOf(HostName), #00); + + {$IFDEF WIN32} + sResult := GetHostName(@HostName[01], SizeOf(HostName)); + {$ENDIF} + + {$IFDEF OS2} + sResult := IBM_GetHostName(@HostName[01], SizeOf(HostName)); + {$ENDIF} + + {$IFDEF LINUX} + {!!!!!!!!!!!!!!!!!!!} + InAddr.ClassA := 127; + InAddr.ClassB := 0; + InAddr.ClassC := 0; + InAddr.ClassD := 1; + + HostName := SockGetHostNameByAddr(@InAddr) + #00; + sResult := Length(HostName); + {$ENDIF} + + Counter := 01; + While (Counter < SizeOf(HostName)) AND (HostName[Counter] <> #00) do + Inc(Counter); + + if (Counter > 01) then + SetLength(HostName, Counter) + else HostName := 'amnesiac'; + + SockGetHostname := HostName; +end; { func. SockGetHostName } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockInetAddr(_s: ShortString): tIn_Addr; +begin + _s := _s + #00; + + {$IFNDEF LINUX} + Result.IpAddr := INet_Addr(@_S[01]); + {$ELSE} + {$WARNING SockInetAddr function not implemented! } + Result.IpAddr := INADDR_NONE; + {$ENDIF} +end; { func. SockInetAddr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function SockClientAlive(_SockDesc: tSockDesc): Boolean; +var TempCH : Char; + Returncode : Longint; + TempError : Longint; + TempStr : String; +begin + Result := true; + + ReturnCode := SockRecv(_SockDesc, @TempCH, SizeOf(TempCH), MSG_PEEK); + TempError := SockErrorNo; + + TempStr := SockGetErrStr(TempError); + + if ReturnCode = 0 then Result := false; { was: = 0 } + if (TempError <> WSAEWOULDBLOCK) AND (TempError <> 00) then + Result := false; +end; { func. SockClientAlive } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +initialization + {!! SockInit; } + +finalization + {$IFDEF WIN32} + //WsaCleanUp; + {$ENDIF} +end. { unit SockFunc } diff --git a/SOURCE/ELECOM/SOCKFUNC.RC b/SOURCE/ELECOM/SOCKFUNC.RC new file mode 100644 index 0000000..7123018 --- /dev/null +++ b/SOURCE/ELECOM/SOCKFUNC.RC @@ -0,0 +1,92 @@ +#define SOCEPERM 10001 +#define SOCESRCH 10003 +#define SOCEINTR 10004 +#define SOCENXIO 10006 +#define SOCEBADF 10009 +#define SOCEACCES 10013 +#define SOCEFAULT 10014 +#define SOCEINVAL 10022 +#define SOCEMFILE 10024 +#define SOCEPIPE 10032 +#define SOCEOS2ERR 10100 +#define SOCEWOULDBLOCK 10035 +#define SOCEINPROGRESS 10036 +#define SOCEALREADY 10037 +#define SOCENOTSOCK 10038 +#define SOCEDESTADDRREQ 10039 +#define SOCEMSGSIZE 10040 +#define SOCEPROTOTYPE 10041 +#define SOCENOPROTOOPT 10042 +#define SOCEPROTONOSUPPORT 10043 +#define SOCESOCKTNOSUPPORT 10044 +#define SOCEOPNOTSUPP 10045 +#define SOCEPFNOSUPPORT 10046 +#define SOCEAFNOSUPPORT 10047 +#define SOCEADDRINUSE 10048 +#define SOCEADDRNOTAVAIL 10049 +#define SOCENETDOWN 10050 +#define SOCENETUNREACH 10051 +#define SOCENETRESET 10052 +#define SOCECONNABORTED 10053 +#define SOCECONNRESET 10054 +#define SOCENOBUFS 10055 +#define SOCEISCONN 10056 +#define SOCENOTCONN 10057 +#define SOCESHUTDOWN 10058 +#define SOCETOOMANYREFS 10059 +#define SOCETIMEDOUT 10060 +#define SOCECONNREFUSED 10061 +#define SOCELOOP 10062 +#define SOCENAMETOOLONG 10063 +#define SOCEHOSTDOWN 10064 +#define SOCEHOSTUNREACH 10065 +#define SOCENOTEMPTY 10066 + + +STRINGTABLE +{ + SOCEPERM, "Not owner" + SOCESRCH, "No such process" + SOCEINTR, "Interrupted system call" + SOCENXIO, "No such device or address" + SOCEBADF, "Bad file number" + SOCEACCES, "Permission denied" + SOCEFAULT, "Bad address" + SOCEINVAL, "Invalid argument" + SOCEMFILE, "Too many open files" + SOCEPIPE, "Broken pipe" + SOCEOS2ERR, "OS/2 Error" + SOCEWOULDBLOCK, "Operation would block" + SOCEINPROGRESS, "Operation now in progress" + SOCEALREADY, "Operation already in progress" + SOCENOTSOCK, "Socket operation on non-socket" + SOCEDESTADDRREQ, "Destination address required" + SOCEMSGSIZE, "Message too long" + SOCEPROTOTYPE, "Protocol wrong type for socket" + SOCENOPROTOOPT, "Protocol not available" + SOCEPROTONOSUPPORT, "Protocol not supported" + SOCESOCKTNOSUPPORT, "Socket type not supported" + SOCEOPNOTSUPP, "Operation not supported on socket" + SOCEPFNOSUPPORT, "Protocol family not supported" + SOCEAFNOSUPPORT, "Address family not supported by protocol family" + SOCEADDRINUSE, "Address already in use" + SOCEADDRNOTAVAIL, "Can't assign requested address" + SOCENETDOWN, "Network is down" + SOCENETUNREACH, "Network is unreachable" + SOCENETRESET, "Network dropped connection on reset" + SOCECONNABORTED, "Software caused connection abort" + SOCECONNRESET, "Connection reset by peer" + SOCENOBUFS, "No buffer space available" + SOCEISCONN, "Socket is already connected" + SOCENOTCONN, "Socket is not connected" + SOCESHUTDOWN, "Can't send after socket shutdown" + SOCETOOMANYREFS, "Too many references: can't splice" + SOCETIMEDOUT, "Connection timed out" + SOCECONNREFUSED, "Connection refused" + SOCELOOP, "Too many levels of symbolic links" + SOCENAMETOOLONG, "File name too long" + SOCEHOSTDOWN, "Host is down" + SOCEHOSTUNREACH, "No route to host" + SOCENOTEMPTY, "Directory not empty" +} + diff --git a/SOURCE/ELECOM/SOCKFUNC.RES b/SOURCE/ELECOM/SOCKFUNC.RES new file mode 100644 index 0000000000000000000000000000000000000000..272dc2da319249f1f519c69647b61b4ef61d1a0c GIT binary patch literal 2392 zcma)8OK;Oa5FS9P#6xPJkb&JhX2Pc@~`1Veu7Xc6%qOt7Qrq z24lNrobo`NK&-BT^L^z!n?o+G&Sd6nqP7BjNAeREEJ0gQLaxg67a0u3aRAZxTq2}&C#Z1!@zEOKp#iQ?h!0W z@MPp;`4=}UEyYb8teyxMwPRLW;x%;loCPuJ=O+@ZlcrB60iUMufwh%5jQi!C%Ntl; zS1_aYe><6-%pc9VCK^o%KU(!scIso;(I3vw5+29E{vE8d@~py3JIBmLggMPj(!3)c z``w8>lG(`$%TQCy{T$B--|VEr9(oCyRt!6<&yA-YZbp$kgY`}A%ub6t#;mSy#ZNn? z))up7>g-})V$QP*tH=FvXou$BLqsK{sj0(b6+?cu>+NG`nd0Ueb1H>io*1E8c)XY0 z8oPb8+CDQ5$H9F*BfI>jg)vdL6_$*Vx3umxwEGf%6gwQx0==BEP(LY8PsP_&qiwRW62}GT#D#sjkb6Cxs?nnuvWXpLg^{={WDe+Q%#)IRjg}bqw#e2Tnm%I9 zpQx;WE4 r{zLH3Vgv2{*DH_=hT8YLW1ru73%&6|&gCVzKR^?$^8XK>$G`sqgb$tE literal 0 HcmV?d00001 diff --git a/SOURCE/ELECOM/TELNET.PAS b/SOURCE/ELECOM/TELNET.PAS new file mode 100644 index 0000000..dcf5485 --- /dev/null +++ b/SOURCE/ELECOM/TELNET.PAS @@ -0,0 +1,863 @@ +unit TELNET; +{$h-} +(* +** +** Serial and TCP/IP communication routines for DOS, OS/2 and Win9x/NT. +** Tested with: TurboPascal v7.0, (DOS) +** VirtualPascal v2.1, (OS/2, Win32) +** FreePascal v0.99.12 (DOS, Win32) +** Delphi v4.0. (Win32) +** +** Version : 1.01 +** Created : 21-May-1998 +** Last update : 04-Apr-1999 +** +** Note: (c) 1998-1999 by Maarten Bekers +** +** Note: Same story of what we said in Win32, only we have here 2 seperate +** threads. The Write-thread has no problems, the read-thread is run +** max every 5 seconds, or whenever a carrier-check is performed. This +** carrier check is run on most BBS programs each second. You can +** optimize this by making the ReadThread a blocking select() call on +** the fd_read socket, but this can have other issues. A better approach +** on Win32 would be to call the WsaAsyncSelect() call, but this is +** non portable. +** +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses SockFunc, SockDef, Combase, BufUnit, Threads + + {$IFDEF WIN32} + ,Windows + {$ENDIF} + + {$IFDEF OS2} + ,Os2Base + {$ENDIF} + + {$IFDEF VirtualPascal} + ,Use32 + {$ENDIF}; + +Const WriteTimeout = 5000; { Wait max. 5 secs } + ReadTimeOut = 5000; { General event, 5 secs max } + + InBufSize = 1024 * 32; + OutBufSize = 1024 * 32; + + +type TTelnetObj = Object(TCommObj) + ReadProcPtr: Pointer; { Pointer to TX/RX handler (thread) } + WriteProcPtr: Pointer; { Pointer to TX/RX handler (thread) } + ThreadsInitted : Boolean; + NeedNewCarrier : Boolean; + TelnetCarrier : Boolean; + + IacDontDo : Longint; { ugly hack to prevent missed IACs } + IacState : Longint; { 0 = nothing } + { 1 = received IAC } + { 2 = handing the IAC } + ClientRC : Longint; + + InBuffer : ^BufArrayObj; { Buffer system internally used } + OutBuffer : ^BufArrayObj; + + DoTxEvent : PSysEventObj; { Event manually set when we have to transmit } + DoRxEvent : PSysEventObj; { Event manually set when we need data } + + TxClosedEvent : PSysEventObj; { Event set when the Tx thread is closed } + RxClosedEvent : PSysEventObj; { Event set when the Rx thread is closed } + + CriticalTx : PExclusiveObj; { Critical sections } + CriticalRx : PExclusiveObj; + + TxThread : PThreadsObj; { The Transmit and Receive threads } + RxThread : PThreadsObj; + + EndThreads : Boolean; { Set to true when we have to end the threads } + + constructor Init; + destructor Done; + + function Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; virtual; + function Com_OpenKeep(Comport: Byte): Boolean; virtual; + function Com_GetChar: Char; virtual; + function Com_PeekChar: Char; virtual; + function Com_CharAvail: Boolean; virtual; + function Com_Carrier: Boolean; virtual; + function Com_SendChar(C: Char): Boolean; virtual; + function Com_ReadyToSend(BlockLen: Longint): Boolean; virtual; + function Com_GetBPSrate: Longint; virtual; + function Com_GetHandle: Longint; virtual; + + procedure Com_OpenQuick(Handle: Longint); virtual; + procedure Com_Close; virtual; + procedure Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); virtual; + procedure Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); virtual; + procedure Com_PeekBlock(var Block; BlockLen: Longint; var Reads: Longint); virtual; + procedure Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); virtual; + procedure Com_SetDtr(State: Boolean); virtual; + procedure Com_GetModemStatus(var LineStatus, ModemStatus: Byte); virtual; + procedure Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); virtual; + procedure Com_PurgeInBuffer; virtual; + procedure Com_PurgeOutBuffer; virtual; + + procedure Com_PauseCom(CloseCom: Boolean); virtual; + procedure Com_ResumeCom(OpenCom: Boolean); virtual; + + procedure Com_ReadProc(var TempPtr: Pointer); + procedure Com_WriteProc(var TempPtr: Pointer); + + procedure Com_SetDataProc(ReadPtr, WritePtr: Pointer); virtual; + + function Com_StartThread: Boolean; + procedure Com_InitVars; + procedure Com_StopThread; + + function Com_SendWill(Option: Char): String; + function Com_SendWont(Option: Char): String; + function Com_SendDo(Option: Char): String; + procedure Com_SendRawStr(TempStr: String); + procedure Com_PrepareBufferRead(var CurBuffer: CharBufType; var TempOut: BufArrayObj; BlockLen: Longint); + procedure Com_PrepareBufferWrite(var CurBuffer, TmpOutBuffer: CharBufType; var BlockLen: Longint); + end; { object TTelnetObj } + +Type PTelnetObj = ^TTelnetObj; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses SysUtils; + +{$IFDEF FPC} + {$I WINDEF.FPC} +{$ENDIF} + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + + +Const + { Telnet Options } + TELNET_IAC = #255; { Interpret as Command } + TELNET_DONT = #254; { Stop performing, or not expecting him to perform } + TELNET_DO = #253; { Perform, or expect him to perform } + TELNET_WONT = #252; { Refusal to perform } + TELNET_WILL = #251; { Desire to perform } + + TELNET_SB = #250; { What follow is sub-negotiation of indicated option } + TELNET_GA = #249; { Go ahead signal } + TELNET_EL = #248; { Erase Line function } + TELNET_EC = #247; { Erase Character function } + TELNET_AYT = #246; { Are You There function } + TELNET_AO = #245; { Abort Output function } + TELNET_IP = #244; { Interrupt Process function } + TELNET_BRK = #243; { NVT break character } + TELNET_DM = #242; { Data stream portion of a Synch } + TELNET_NOP = #241; { No operation } + TELNET_SE = #240; { End of sub-negotiation parameters } + TELNET_EOR = #239; { End of record } + TELNET_ABORT = #238; { Abort process } + TELNET_SUSP = #237; { Suspend current process } + TELNET_EOF = #236; { End of file } + + TELNETOPT_BINARY = #0; { Transmit binary } + TELNETOPT_ECHO = #1; { Echo mode } + TELNETOPT_SUPGA = #3; { Suppress Go-Ahead } + TELNETOPT_TERM = #24; { Terminal Type } + TELNETOPT_SPEED = #32; { Terminal Speed } + TELNETOPT_FLOWCNT= #33; { Toggle flow-control } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +constructor TTelnetObj.Init; +begin + inherited Init; + + ThreadsInitted := false; + NeedNewCarrier := true; + TelnetCarrier := TRUE; + IacState := 0; { default to none } + Com_InitVars; +end; { constructor Init } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +destructor TTelnetObj.Done; +begin + inherited done; +end; { destructor Done } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_SendRawStr(TempStr: String); +var BytesSnt: Longint; + TmpByte : Longint; + BufFlag : Longint; + TmpError: Longint; +begin + BufFlag := 00; + TmpByte := 01; + + REPEAT + BytesSnt := SockSend(ClientRC, + @TempStr[TmpByte], + Length(TempStr), + BufFlag); + + if BytesSnt > 0 then + Inc(TmpByte, BytesSnt) + else begin + TmpError := SockErrorNo; + if TmpError <> WSAEWOULDBLOCK then EXIT; + end; { else } + + UNTIL (TmpByte > Length(TempStr)); +end; { proc. Com_SendRawStr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_SendWill(Option: Char): String; +begin + Result[1] := TELNET_IAC; + Result[2] := TELNET_WILL; + Result[3] := Option; + SetLength(Result, 3); +end; { func. Com_SendWill } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_SendWont(Option: Char): String; +begin + Result[1] := TELNET_IAC; + Result[2] := TELNET_WONT; + Result[3] := Option; + SetLength(Result, 3); +end; { func. Com_SendWont } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_SendDo(Option: Char): String; +begin + Result[1] := TELNET_IAC; + Result[2] := TELNET_DO; + Result[3] := Option; + SetLength(Result, 3); +end; { func. Com_SendDo } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_PrepareBufferRead(var CurBuffer: CharBufType; var TempOut: BufArrayObj; BlockLen: Longint); +var Counter : Longint; +begin + Counter := 00; + if BlockLen = 0 then EXIT; + + While Counter <= (Blocklen - 01) do + begin + {-- and now handle the IAC state ---------------------------------------} + Case IacState of + 1 : begin { DO / DONT } + {-- we received an IAC, and this is the next char --------------} + if CurBuffer[Counter] = TELNET_IAC then + begin + TempOut.Put(CurBuffer[Counter], 1); + IacState := 0; { reset parser state } + end + else begin + IacState := 2; + + Case CurBuffer[Counter] of + TELNET_DONT, + TELNET_DO : IacDontDo := 1; + else IacDontDo := 0; + end; { case } + end; { else } + end; { DO/DONT } + 2 : begin { WHAT } +{ if IacDontDo = 1 then } + begin + Case CurBuffer[Counter] of + TELNETOPT_BINARY, + TELNETOPT_SUPGA, + TELNETOPT_ECHO : begin + Com_SendRawStr(Com_SendWill(CurBuffer[Counter])); + end + else begin + Com_SendRawStr(Com_SendWont(CurBuffer[Counter])); + end; { if } + end; { case } + end; { if this is a state we will reply to } + + IacState := 0; { reset IAC state machine } + end; { WHAT } + else begin + if CurBuffer[Counter] = TELNET_IAC then + begin + IacState := 1 + end + else TempOut.Put(CurBuffer[Counter], 1); + end; { else } + end; { case } + + {-- and loop through the buffer ----------------------------------------} + Inc(Counter); + end; { while } + +end; { proc. Com_PrepareBufferRead } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_PrepareBufferWrite(var CurBuffer, TmpOutBuffer: CharBufType; var BlockLen: Longint); +var Counter : Longint; + NewCounter: Longint; +begin + Counter := 00; + NewCounter := 00; + if BlockLen = 0 then EXIT; + + While Counter <= Blocklen do + begin + Case CurBuffer[Counter] of + TELNET_IAC : begin { Escape command character } + TmpOutBuffer[NewCounter] := TELNET_IAC; + Inc(NewCounter); + TmpOutBuffer[NewCounter] := TELNET_IAC; + Inc(NewCounter); + end; { if } + else begin + TmpOutBuffer[NewCounter] := CurBuffer[Counter]; + Inc(NewCounter); + end; { if } + end; { case } + + Inc(Counter); + end; { while } + + BlockLen := NewCounter - 1; +end; { proc. Com_PrepareBufferWrite } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_ReadProc(var TempPtr: Pointer); +var Available : Boolean; + BytesRead : Longint; + BlockLen : Longint; + ReturnCode: Longint; +begin + repeat + if DoRxEvent^.WaitForEvent(ReadTimeOut) then + if NOT EndThreads then + begin + CriticalRx^.EnterExclusive; + Available := (SockSelect(ClientRC) > 00); + + DoRxEvent^.ResetEvent; + + if (Available) OR (NeedNewCarrier) then + begin + {----------- Start reading the gathered date -------------------} + NeedNewCarrier := false; + + if InBuffer^.BufRoom > 0 then + begin + BlockLen := InBuffer^.BufRoom; + if BlockLen > 1024 then + BlockLen := 1024; + + if BlockLen > 00 then + begin + BytesRead := SockRecv(ClientRC, + @InBuffer^.TmpBuf, + BlockLen, + 0); + + if BytesRead = 0 then + begin + TelnetCarrier := false; + + ReturnCode := SockErrorNo; + + ErrorStr := 'Error in communications(1), #'+IntToStr(Returncode)+ ' / '+SysErrorMessage(Returncode); + end; { if } + + if BytesRead = -1 then + begin + ReturnCode := SockErrorNo; + + if ReturnCode <> WSAEWOULDBLOCK then + begin + TelnetCarrier := false; + + ErrorStr := 'Error in communications(2), #'+IntToStr(ReturnCode)+ ' / '+SysErrorMessage(ReturnCode); + EndThreads := true; + end; { if } + end; { error } + + if BytesRead > 00 then + begin + Com_PrepareBufferRead(InBuffer^.TmpBuf, InBuffer^, BytesRead); + end; { if } + end; { if } + end; { if } + end; { if available } + + CriticalRx^.LeaveExclusive; + end; { if RxEvent } + until EndThreads; + + RxClosedEvent^.SignalEvent; + ExitThisThread; +end; { proc. Com_ReadProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_WriteProc(var TempPtr: Pointer); +var BlockLen : Longint; + Written : Longint; + ReturnCode : Longint; + TempBuf : ^CharBufType; +begin + New(TempBuf); + + repeat + if DoTxEvent^.WaitForEvent(WriteTimeOut) then + if NOT EndThreads then + begin + CriticalTx^.EnterExclusive; + DoTxEvent^.ResetEvent; + + if OutBuffer^.BufUsed > 00 then + begin + BlockLen := OutBuffer^.Get(OutBuffer^.TmpBuf, OutBuffer^.BufUsed, false); + + Com_PrepareBufferWrite(OutBuffer^.TmpBuf, TempBuf^, BlockLen); + Written := SockSend(ClientRC, + TempBuf, + BlockLen, + 0); + {-- remove the data from the buffer, but only remove the data ---} + {-- thats actually written --------------------------------------} + ReturnCode := OutBuffer^.Get(OutBuffer^.TmpBuf, Written, true); + + if ReturnCode <> Longint(Written) then + begin + { not everything is removed! } + end; { if } + + {-- if theres data in the buffer left, run this event again -----} + if Written <> BlockLen then + begin + DoTxEvent^.SignalEvent; + end; { if } + end; { if } + + CriticalTx^.LeaveExclusive; + end; { if } + + until EndThreads; + + Dispose(TempBuf); + + TxClosedEvent^.SignalEvent; + ExitThisThread; +end; { proc. Com_WriteProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_StartThread: Boolean; +begin + Result := false; + EndThreads := false; + if ThreadsInitted then EXIT; + ThreadsInitted := true; + + {----------------------- Create all the events ----------------------------} + New(DoTxEvent, Init); + if NOT DoTxEvent^.CreateEvent(false) then EXIT; + + New(DoRxEvent, Init); + if NOT DoRxEvent^.CreateEvent(false) then EXIT; + + New(RxClosedEvent, Init); + if NOT RxClosedEvent^.CreateEvent(false) then EXIT; + + New(TxClosedEvent, Init); + if NOT TxClosedEvent^.CreateEvent(false) then EXIT; + + {-------------- Startup the buffers and overlapped events -----------------} + New(InBuffer, Init(InBufSize)); + New(OutBuffer, Init(OutBufSize)); + + {-------------------- Startup a seperate write thread ---------------------} + New(CriticalTx, Init); + CriticalTx^.CreateExclusive; + + New(TxThread, Init); + if NOT TxThread^.CreateThread(16384, { Stack size } + WriteProcPtr, { Actual procedure } + nil, { Parameters } + 0) { Creation flags } + then EXIT; + + {-------------------- Startup a seperate read thread ----------------------} + New(CriticalRx, Init); + CriticalRx^.CreateExclusive; + + New(RxThread, Init); + if NOT RxThread^.CreateThread(16384, { Stack size } + ReadProcPtr, { Actual procedure } + nil, { Parameters } + 0) { Creation flags } + then EXIT; + + Result := true; +end; { proc. Com_StartThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_InitVars; +begin + DoTxEvent := nil; + DoRxEvent := nil; + RxClosedEvent := nil; + TxClosedEvent := nil; + TxThread := nil; + RxThread := nil; + + InBuffer := nil; + OutBuffer := nil; + CriticalRx := nil; + CriticalTx := nil; +end; { proc. Com_InitVars } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_StopThread; +begin + EndThreads := true; + ThreadsInitted := false; + + if DoTxEvent <> nil then DoTxEvent^.SignalEvent; + if DoTxEvent <> nil then DoRxEvent^.SignalEvent; + + if TxThread <> nil then TxThread^.CloseThread; + if RxThread <> nil then RxThread^.CloseThread; + + if TxClosedEvent <> nil then + if NOT TxClosedEvent^.WaitForEvent(1000) then + TxThread^.TerminateThread(0); + + if RxClosedEvent <> nil then + if NOT RxClosedEvent^.WaitForEvent(1000) then + RxThread^.TerminateThread(0); + + if TxThread <> nil then Dispose(TxThread, Done); + if RxThread <> nil then Dispose(RxThread, Done); + + if DoTxEvent <> nil then Dispose(DoTxEvent, Done); + if DoRxEvent <> nil then Dispose(DoRxEvent, Done); + if RxClosedEvent <> nil then Dispose(RxClosedEvent, Done); + if TxClosedEvent <> nil then Dispose(TxClosedEvent, Done); + + if CriticalTx <> nil then Dispose(CriticalTx, Done); + if CriticalRx <> nil then Dispose(CriticalRx, Done); + + if InBuffer <> nil then Dispose(InBuffer, Done); + if OutBuffer <> nil then Dispose(OutBuffer, Done); + + Com_InitVars; +end; { proc. Com_StopThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_GetHandle: Longint; +begin + Result := ClientRC; +end; { func. Com_GetHandle } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_OpenQuick(Handle: Longint); +var ReturnCode: Longint; +begin + ClientRC := Handle; + + if (NOT (SockInit=0)) then + begin + ReturnCode := SockErrorNo; + + ErrorStr := 'Error in initializing socket, #'+IntToStr(Returncode)+ ' / '+SysErrorMessage(Returncode); + InitFailed := true; + end + else InitFailed := NOT Com_StartThread; + + { Set the telnet to binary transmission } + Com_SendRawStr(Com_SendWill(TELNETOPT_ECHO)); + Com_SendRawStr(Com_SendWill(TELNETOPT_BINARY)); +end; { proc. TTelnetObj.Com_OpenQuick } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_OpenKeep(Comport: Byte): Boolean; +begin + InitFailed := NOT Com_StartThread; + Com_OpenKeep := InitFailed; +end; { func. Com_OpenKeep } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; +begin + Com_Open := true; +end; { func. TTelnetObj.Com_OpenCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); +begin + // Duhhh ;) +end; { proc. TTelnetObj.Com_SetLine } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_Close; +begin + if DontClose then EXIT; + + if ClientRC <> -1 then + begin + Com_StopThread; + SockShutdown(ClientRC, 02); + SockClose(ClientRC); + + ClientRC := -1; + end; { if } + +end; { func. TTelnetObj.Com_CloseCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_SendChar(C: Char): Boolean; +var Written: Longint; +begin + Com_SendBlock(C, SizeOf(C), Written); + Com_SendChar := (Written = SizeOf(c)); +end; { proc. TTelnetObj.Com_SendChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_GetChar: Char; +var Reads: Longint; +begin + Com_ReadBlock(Result, SizeOf(Result), Reads); +end; { func. TTelnetObj.Com_GetChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_PeekChar: Char; +var Reads: Longint; +begin + Com_PeekBlock(Result, SizeOf(Result), Reads); +end; { func. TTelnetObj.Com_GetChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); +begin + if OutBuffer^.BufRoom < BlockLen then + repeat + {$IFDEF WIN32} + Sleep(1); + {$ENDIF} + + {$IFDEF OS2} + DosSleep(1); + {$ENDIF} + until (OutBuffer^.BufRoom >= BlockLen) OR (NOT Com_Carrier); + + CriticalTx^.EnterExclusive; + Written := OutBuffer^.Put(Block, BlockLen); + CriticalTx^.LeaveExclusive; + + DoTxEvent^.SignalEvent; +end; { proc. TTelnetObj.Com_SendBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); +begin + if InBuffer^.BufUsed < BlockLen then + begin + DoRxEvent^.SignalEvent; + + repeat + {$IFDEF OS2} + DosSleep(1); + {$ENDIF} + + {$IFDEF WIN32} + Sleep(1); + {$ENDIF} + + if Com_CharAvail then + DoRxEvent^.SignalEvent; + until (InBuffer^.BufUsed >= BlockLen) OR (NOT Com_Carrier); + end; { if } + + Reads := InBuffer^.Get(Block, BlockLen, true); +end; { proc. TTelnetObj.Com_ReadBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_PeekBlock(var Block; BlockLen: Longint; var Reads: Longint); +begin + if InBuffer^.BufUsed < BlockLen then + begin + DoRxEvent^.SignalEvent; + + repeat + {$IFDEF OS2} + DosSleep(1); + {$ENDIF} + + {$IFDEF WIN32} + Sleep(1); + {$ENDIF} + + if Com_CharAvail then + DoRxEvent^.SignalEvent; + until (InBuffer^.BufUsed >= BlockLen) OR (NOT Com_Carrier); + end; { if } + + Reads := InBuffer^.Get(Block, BlockLen, false); +end; { proc. TTelnetObj.Com_PeekBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_CharAvail: Boolean; +begin + if InBuffer^.BufUsed < 1 then + begin + if (SockSelect(ClientRC) > 0) then + DoRxEvent^.SignalEvent; + end; { if } + + Result := (InBuffer^.BufUsed > 0); +end; { func. TTelnetObj.Com_CharAvail } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_Carrier: Boolean; +begin + if TelnetCarrier then { Carrier is only lost in 'read' sections } + begin + DoRxEvent^.SignalEvent; + NeedNewCarrier := true; + end; { if } + + Result := TelnetCarrier; +end; { func. TTelnetObj.Com_Carrier } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_GetModemStatus(var LineStatus, ModemStatus: Byte); +begin + LineStatus := 00; + ModemStatus := 08; + + if Com_Carrier then ModemStatus := ModemStatus OR (1 SHL 7); +end; { proc. TTelnetObj.Com_GetModemStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_SetDtr(State: Boolean); +begin + if NOT State then + begin + Com_Close; + end; { if } +end; { proc. TTelnetObj.Com_SetDtr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_GetBpsRate: Longint; +begin + Com_GetBpsRate := 115200; +end; { func. TTelnetObj.Com_GetBpsRate } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); +begin + DoRxEvent^.SignalEvent; + DoTxEvent^.SignalEvent; + + InFree := InBuffer^.BufRoom; + OutFree := OutBuffer^.BufRoom; + InUsed := InBuffer^.BufUsed; + OutUsed := OutBuffer^.BufUsed; +end; { proc. TTelnetObj.Com_GetBufferStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_PurgeInBuffer; +begin + CriticalRx^.EnterExclusive; + + InBuffer^.Clear; + + CriticalRx^.LeaveExclusive; +end; { proc. TTelnetObj.Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_PurgeOutBuffer; +begin + CriticalTx^.EnterExclusive; + + OutBuffer^.Clear; + + CriticalTx^.LeaveExclusive; +end; { proc. TTelnetObj.Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TTelnetObj.Com_ReadyToSend(BlockLen: Longint): Boolean; +begin + Result := OutBuffer^.BufRoom >= BlockLen; +end; { func. ReadyToSend } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_PauseCom(CloseCom: Boolean); +begin + if CloseCom then Com_Close + else Com_StopThread; +end; { proc. Com_PauseCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_ResumeCom(OpenCom: Boolean); +begin + if OpenCom then Com_OpenKeep(0) + else Com_StartThread; +end; { proc. Com_ResumeCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TTelnetObj.Com_SetDataProc(ReadPtr, WritePtr: Pointer); +begin + ReadProcPtr := ReadPtr; + WriteProcPtr := WritePtr; +end; { proc. Com_SetDataProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +end. diff --git a/SOURCE/ELECOM/THREADS.PAS b/SOURCE/ELECOM/THREADS.PAS new file mode 100644 index 0000000..2928452 --- /dev/null +++ b/SOURCE/ELECOM/THREADS.PAS @@ -0,0 +1,421 @@ +unit THREADS; +(* +** +** Serial and TCP/IP communication routines for DOS, OS/2 and Win9x/NT. +** Tested with: TurboPascal v7.0, (DOS) +** VirtualPascal v2.1, (OS/2, Win32) +** FreePascal v0.99.12 (DOS, Win32) +** Delphi v4.0. (Win32) +** +** Version : 1.01 +** Created : 07-Mar-1999 +** Last update : 26-Sep-1999 +** +** Note: (c) 1998-1999 by Maarten Bekers +** +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +{$IFDEF OS2} + uses Os2Base; +{$ENDIF} + +{$IFDEF WIN32} + uses Windows; +{$ENDIF} + +{$IFDEF OS2} + Type THandle = Longint; + DWORD = Longint; +{$ENDIF} + +{$IFDEF WIN32} + {$IFDEF FPC} + Type THandle = Handle; + {$ENDIF} +{$ENDIF} + +type TSysEventObj = Object + {$IFDEF OS2} + SemHandle: HEV; + {$ENDIF} + + {$IFDEF WIN32} + SemHandle: THandle; + {$ENDIF} + + constructor init; + destructor done; + + procedure DisposeEvent; + procedure SignalEvent; + procedure ResetEvent; + function CreateEvent(InitialState: Boolean): Boolean; + function WaitForEvent(TimeOut: Longint): Boolean; + end; { TSysEventObj } + +Type PSysEventObj = ^TSysEventObj; + +type TExclusiveObj = Object + {$IFDEF OS2} + Exclusive: PHMtx; + {$ENDIF} + + {$IFDEF WIN32} + Exclusive: PRTLCriticalSection; + {$ENDIF} + + constructor Init; + destructor Done; + + procedure CreateExclusive; + procedure DisposeExclusive; + + procedure EnterExclusive; + procedure LeaveExclusive; + end; { TExclusiveObj } + +Type PExclusiveObj = ^TExclusiveObj; + + +type TThreadsObj = Object + ThreadHandle : THandle; + ThreadID : DWORD; + ThreadClosed : Boolean; + + constructor Init; + destructor Done; + + function CreateThread(StackSize : Longint; + CallProc, + Parameters : Pointer; + CreationFlags: Longint): Boolean; + procedure CloseThread; + procedure TerminateThread(ExitCode: Longint); + end; { TThreadsObj } + +Type PThreadsObj = ^TThreadsObj; + +procedure ExitThisThread; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +constructor TSysEventObj.Init; +begin + SemHandle := 0; +end; { constructor Init } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +destructor TSysEventObj.Done; +begin + if Longint(SemHandle) <> -1 then + begin + SignalEvent; + DisposeEvent; + end; { if } +end; { destructor Done } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TSysEventObj.CreateEvent(InitialState: Boolean): Boolean; +{$IFDEF OS2} +var Returncode: longint; +{$ENDIF} +begin + CreateEvent := true; + + {$IFDEF WIN32} + SemHandle := Windows.CreateEvent(nil, true, InitialState, nil); + if Longint(SemHandle) = -1 then CreateEvent := false; + {$ENDIF} + + {$IFDEF OS2} + returncode := DosCreateEventSem(nil, SemHandle, 0, InitialState); + CreateEvent := (returncode=0); + {$ENDIF} +end; { func. CreateEvent } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TSysEventObj.SignalEvent; +{$IFDEF OS2} +var RC: Longint; +{$ENDIF} +begin + {$IFDEF WIN32} + if Longint(SemHandle) <> -1 then + SetEvent(SemHandle); + {$ENDIF} + + {$IFDEF OS2} + if SemHandle <> -1 then + RC := DosPostEventSem(SemHandle); + {$ENDIF} +end; { proc. SignalEvent } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TSysEventObj.ResetEvent; +{$IFDEF OS2} +var Flag: Longint; + RC : Longint; +{$ENDIF} +begin + {$IFDEF WIN32} + if SemHandle <> THandle(-1) then + Windows.ResetEvent(SemHandle); + {$ENDIF} + + {$IFDEF OS2} + Flag := 0; + if SemHandle <> -1 then + RC := DosResetEventSem(SemHandle, Flag); + {$ENDIF} +end; { proc. ResetEvent } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TSysEventObj.WaitForEvent(TimeOut: Longint): Boolean; +var ReturnCode: Longint; +{$IFDEF OS2} + Flag : Longint; +{$ENDIF} +begin + {$IFDEF WIN32} + if SemHandle <> THandle(-1) then + ReturnCode := WaitForSingleObject(SemHandle, Timeout) + else ReturnCode := 0; + + WaitForEvent := (ReturnCode = WAIT_OBJECT_0); + {$ENDIF} + + {$IFDEF OS2} + if SemHandle <> -1 then + ReturnCode := DosWaitEventSem(SemHandle, TimeOut); + + Flag := 0; + DosResetEventSem(SemHandle, Flag); + WaitForEvent := (ReturnCode = 0); +{$ENDIF} +end; { func. WaitForEvent } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TSysEventObj.DisposeEvent; +{$IFDEF OS2} +var Flag: Longint; +{$ENDIF} +begin + {$IFDEF WIN32} + if SemHandle <> THandle(-1) then CloseHandle(SemHandle); + SemHandle := 0; + {$ENDIF} + + {$IFDEF OS2} + Flag := 0; + if SemHandle <> -1 then DosCloseEventSem(SemHandle); + SemHandle := -1; + {$ENDIF} +end; { proc. DisposeEvent } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +constructor TExclusiveObj.Init; +begin + Exclusive := nil; +end; { constructor Init } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +destructor TExclusiveObj.Done; +begin + if Exclusive <> nil then + DisposeExclusive; +end; { destructor Done } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TExclusiveObj.CreateExclusive; +begin + {$IFDEF WIN32} + New(Exclusive); + InitializeCriticalSection(Exclusive^); + {$ENDIF} + + {$IFDEF OS2} + New(Exclusive); + DosCreateMutexSem(nil, Exclusive^, dcmw_Wait_All, false); + {$ENDIF} +end; { proc. CreateExclusive } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TExclusiveObj.DisposeExclusive; +begin + {$IFDEF WIN32} + if Exclusive <> nil then + begin + DeleteCriticalSection(Exclusive^); + Dispose(Exclusive); + end; { if } + + Exclusive := nil; + {$ENDIF} + + {$IFDEF OS2} + if Exclusive <> nil then + begin + DosCloseMutexSem(Exclusive^); + Dispose(Exclusive); + end; { if } + + Exclusive := nil; + {$ENDIF} +end; { proc. DisposeExclusive } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TExclusiveObj.EnterExclusive; +begin + {$IFDEF WIN32} + EnterCriticalSection(Exclusive^); + {$ENDIF} + + {$IFDEF OS2} + DosRequestMutexSem(Exclusive^, sem_Indefinite_Wait); + {$ENDIF} +end; { proc. EnterExclusive } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TExclusiveObj.LeaveExclusive; +begin + {$IFDEF WIN32} + LeaveCriticalSection(Exclusive^); + {$ENDIF} + + {$IFDEF OS2} + DosReleaseMutexSem(Exclusive^); + {$ENDIF} +end; { proc. LeaveExclusive } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +constructor TThreadsObj.Init; +begin + ThreadHandle := 0; + ThreadId := 0; +end; { constructor Init } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +destructor TThreadsObj.Done; +begin + CloseThread; + ThreadHandle := 0; +end; { destructor Done } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TThreadsObj.CreateThread(StackSize : Longint; + CallProc, + Parameters : Pointer; + CreationFlags: Longint): Boolean; +var ReturnCode: Longint; +begin + ThreadClosed := FALSE; + + {$IFNDEF VirtualPascal} + {$IFDEF WIN32} + ThreadHandle := Windows.CreateThread(nil, { Security attrs } + StackSize, { Stack size } + CallProc, { Actual procedure } + Parameters, { Parameters } + CreationFlags, { Creation flags } + ThreadID); { Thread ID ?? } + + CreateThread := (ThreadHandle <> THandle(-1)); + {$ENDIF} + + {$IFDEF OS2} + ReturnCode := + DosCreateThread(ThreadHandle, { ThreadHandle } + CallProc, { Actual procedure } + Longint(Parameters), { Parameters } + CreationFlags, { Creation flags } + StackSize); { Stacksize } + + CreateThread := (ReturnCode = 0); + if ReturnCode <> 0 then ThreadHandle := -1; + {$ENDIF} + + {$IFDEF LINUX} + + {$ENDIF} + + + {$ELSE} + ThreadHandle := BeginThread(nil, StackSize, CallProc, Parameters, 0, ReturnCode); + CreateThread := (ThreadHandle > THandle(-1)); + {$ENDIF} +end; { proc. CreateThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TThreadsObj.CloseThread; +begin + ThreadClosed := TRUE; + + {$IFDEF WIN32} + if ThreadHandle <> Thandle(-1) then CloseHandle(ThreadHandle); + ThreadHandle := 0; + {$ENDIF} + + {$IFDEF OS2} + {!! DosClose() on a ThreadHandle doesn't work - will eventually close } + {!! other handles ... } + { if ThreadHandle <> -1 then DosClose(ThreadHandle); } + ThreadHandle := -1; + {$ENDIF} +end; { proc. CloseThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TThreadsObj.TerminateThread(ExitCode: Longint); +begin + ThreadClosed := TRUE; + + {$IFDEF WIN32} + if ThreadHandle <> Thandle(-1) then + Windows.TerminateThread(ThreadHandle, ExitCode); + ThreadHandle := 00; + {$ENDIF} + + {$IFDEF OS2} + if ThreadHandle <> -1 then DosKillThread(ThreadHandle); + ThreadHandle := -1; + {$ENDIF} +end; { proc. TerminateThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure ExitThisThread; +begin + {$IFDEF WIN32} + Windows.ExitThread(0); + {$ENDIF} + + {$IFDEF OS2} + Os2Base.DosExit(exit_Thread, 0); + {$ENDIF} +end; { proc. ExitThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +end. diff --git a/SOURCE/ELECOM/W32SNGL.PAS b/SOURCE/ELECOM/W32SNGL.PAS new file mode 100644 index 0000000..c1afec6 --- /dev/null +++ b/SOURCE/ELECOM/W32SNGL.PAS @@ -0,0 +1,824 @@ +unit W32SNGL; +(* +** +** Serial and TCP/IP communication routines for DOS, OS/2 and Win9x/NT. +** Tested with: TurboPascal v7.0, (DOS) +** VirtualPascal v2.1, (OS/2, Win32) +** FreePascal v0.99.15 (DOS, Win32) +** Delphi v4.0. (Win32) +** +** Version : 1.02 +** Created : 09-Sep-1999 +** Last update : 21-Jul-2001 +** +** Note: (c) 1998-2000 by Maarten Bekers +** +** Note2: The problem with this approach that we only retrieve the data when +** we want to. If data arrives and we dont call either Com_ReadBlock(), +** Com_CharAvail or Com_GetBufferStatus() we dont receive the data. +** Therefore, we rely on Windows to actually buffer the data. We do this +** by calling SetupComm() with the buffer-sizes as defined by +** Win32OutBufSize and Win32InBufSize. +** If you want to avoid this, you can implement another mutex that you +** let set by Win32's API calls SetEventMask() and WaitCommEvent(). +** That way, you can also monitor other events which would eliminate +** some overhead. In general, this approach will suffice. +** +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses Windows, Combase, BufUnit, Threads + {$IFDEF VirtualPascal} + ,Use32 + {$ENDIF}; + +Const DataTimeout = 20000; { Wait max. 20 secs } + + InBufSize = 1024 * 32; + OutBufSize = 1024 * 32; + Win32OutBufSize = 1024 * 3; + Win32InBufSize = 1024 * 3; + + +type TWin32Obj = Object(TCommObj) + DataProcPtr: Pointer; { Pointer to TX/RX handler (thread) } + ThreadsInitted: Boolean; { Are the thread(s) up and running? } + + SaveHandle : THandle; + + InitPortNr : Longint; + InitHandle : Longint; + + ReadOL : TOverLapped; { Overlapped structure for ReadFile } + WriteOL : TOverLapped; { Overlapped structure for WriteFile } + + InBuffer : ^BufArrayObj; { Buffer system internally used } + OutBuffer : ^BufArrayObj; + + ReadEvent : PSysEventObj; { Event set by ReadFile overlapped routine } + WriteEvent : PSysEventObj; { Event set by WriteFile overlapped routine } + + DoTxEvent : PSysEventObj;{ Event manually set when we have to transmit } + DoRxEvent : PSysEventObj; { Event manually set when we want data } + + DataClosedEvent: PSysEventObj; { Event set when the Tx thread is closed } + + CriticalTx : PExclusiveObj; { Critical sections } + CriticalRx : PExclusiveObj; + + DataThread : PThreadsObj; + EndThreads : Boolean; { Set to true when we have to end the threads } + + + constructor Init; + destructor Done; + + function Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; virtual; + function Com_OpenKeep(Comport: Byte): Boolean; virtual; + function Com_GetChar: Char; virtual; + function Com_CharAvail: Boolean; virtual; + function Com_Carrier: Boolean; virtual; + function Com_SendChar(C: Char): Boolean; virtual; + function Com_ReadyToSend(BlockLen: Longint): Boolean; virtual; + function Com_GetBPSrate: Longint; virtual; + function Com_GetHandle: Longint; virtual; + + procedure Com_OpenQuick(Handle: Longint); virtual; + procedure Com_Close; virtual; + procedure Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); virtual; + procedure Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); virtual; + procedure Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); virtual; + procedure Com_SetDtr(State: Boolean); virtual; + procedure Com_GetModemStatus(var LineStatus, ModemStatus: Byte); virtual; + procedure Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); virtual; + procedure Com_PurgeInBuffer; virtual; + procedure Com_PurgeOutBuffer; virtual; + procedure Com_FlushOutBuffer(Slice: SliceProc); virtual; + + procedure Com_PauseCom(CloseCom: Boolean); virtual; + procedure Com_ResumeCom(OpenCom: Boolean); virtual; + procedure Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); virtual; + + procedure Com_SetDataProc(ReadPtr, WritePtr: Pointer); virtual; + procedure Com_DataProc(var TempPtr: Pointer); virtual; + + function Com_StartThread: Boolean; + procedure Com_InitVars; + procedure Com_StopThread; + procedure Com_InitDelayTimes; + end; { object TWin32Obj } + +type PWin32Obj = ^TWin32Obj; + + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses SysUtils; + +{$IFDEF FPC} + {$I WINDEF.FPC} +{$ENDIF} + +const + dcb_Binary = $00000001; + dcb_ParityCheck = $00000002; + dcb_OutxCtsFlow = $00000004; + dcb_OutxDsrFlow = $00000008; + dcb_DtrControlMask = $00000030; + dcb_DtrControlDisable = $00000000; + dcb_DtrControlEnable = $00000010; + dcb_DtrControlHandshake = $00000020; + dcb_DsrSensivity = $00000040; + dcb_TXContinueOnXoff = $00000080; + dcb_OutX = $00000100; + dcb_InX = $00000200; + dcb_ErrorChar = $00000400; + dcb_NullStrip = $00000800; + dcb_RtsControlMask = $00003000; + dcb_RtsControlDisable = $00000000; + dcb_RtsControlEnable = $00001000; + dcb_RtsControlHandshake = $00002000; + dcb_RtsControlToggle = $00003000; + dcb_AbortOnError = $00004000; + dcb_Reserveds = $FFFF8000; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +constructor TWin32Obj.Init; +begin + inherited Init; + + InitPortNr := -1; + InitHandle := -1; + ThreadsInitted := false; + Com_Initvars; +end; { constructor Init } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +destructor TWin32Obj.Done; +begin + inherited done; +end; { destructor Done } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_DataProc(var TempPtr: Pointer); +var Success : Boolean; + Props : TCommProp; + ObjectCode : Longint; + ReturnCode : Longint; + DidRead : DWORD; + Written : DWORD; + BlockLen : DWORD; + ObjectArray : Array[0..1] of THandle; + TryReading : Boolean; + Stats : TComStat; + ErrMask : DWORD; +begin + ObjectArray[0] := DoTxEvent^.SemHandle; + ObjectArray[1] := DoRxEvent^.SemHandle; + + repeat + ObjectCode := WaitForMultipleObjects(2, + @ObjectArray, + false, + DataTimeOut); + if EndThreads then EXIT; + + {-----------------------------------------------------------------------} + {-------------------------- Receive signalled --------------------------} + {-----------------------------------------------------------------------} + if (ObjectCode - WAIT_OBJECT_0) = 1 then { DoReceive } + begin + DidRead := 00; + if (EndThreads) then EXIT; + + {-- Make sure there is something to be read ------------------------} + ErrMask := 0; + TryReading := FALSE; + + if ClearCommError(SaveHandle, ErrMask, @Stats) then + if Stats.cbInQue > 0 then + TryReading := TRUE; + + + {----------------- Start reading the gathered date -----------------} + if TryReading then + begin + CriticalRx^.EnterExclusive; + + FillChar(Props, SizeOf(TCommProp), 0); + if GetCommProperties(SaveHandle, Props) then + if InBuffer^.BufRoom > 0 then + begin + BlockLen := Props.dwCurrentRxQueue; + { We want the complete BUFFER size, and not } + { the actual queue size. The queue may have } + { grown since last query, and we always } + { want as much data as possible } + + if Longint(BlockLen) > InBuffer^.BufRoom then + BlockLen := InBuffer^.BufRoom; + + Success := ReadFile(SaveHandle, + InBuffer^.TmpBuf, + BlockLen, + DidRead, + @ReadOL); + + if NOT Success then + begin + ReturnCode := GetLastError; + + if ReturnCode = ERROR_IO_PENDING then + begin + ReturnCode := WaitForSingleObject(ReadOL.hEvent, DataTimeOut); + + if ReturnCode = WAIT_OBJECT_0 then + begin + GetOverLappedResult(SaveHandle, ReadOL, DidRead, false); + end; { if } + end; { if } + end + else GetOverlappedResult(SaveHandle, ReadOL, DidRead, false); + + if DidRead > 00 then + begin + InBuffer^.Put(InBuffer^.TmpBuf, DidRead); + DoRxEvent^.ResetEvent; + end; { if } + end; { if } + + CriticalRx^.LeaveExclusive; + end; { try reading } + end; { DoReceive call } + + {-----------------------------------------------------------------------} + {-------------------------- Transmit signalled -------------------------} + {-----------------------------------------------------------------------} + if (ObjectCode - WAIT_OBJECT_0) = 0 then { DoTransmit } + begin + CriticalTx^.EnterExclusive; + DoTxEvent^.ResetEvent; + + if OutBuffer^.BufUsed > 00 then + begin + Written := 00; + BlockLen := OutBuffer^.Get(OutBuffer^.TmpBuf, OutBuffer^.BufUsed, false); + + Success := WriteFile(SaveHandle, + OutBuffer^.TmpBuf, + BlockLen, + Written, + @WriteOL); + if NOT Success then + begin + ReturnCode := GetLastError; + + if ReturnCode = ERROR_IO_PENDING then + begin + ReturnCode := WaitForSingleObject(WriteOL.hEvent, DataTimeOut); + + if ReturnCode = WAIT_OBJECT_0 then + begin + if GetOverLappedResult(SaveHandle, WriteOL, Written, false) then + begin + ResetEvent(WriteOL.hEvent); + end; { if } + end; { if } + end; { result is pending } + end { if } + else begin + + if GetOverLappedResult(SaveHandle, WriteOL, Written, false) then + begin + ResetEvent(WriteOL.hEvent); + end; { if } + end; { if (did succeed) } + + {-- remove the data from the buffer, but only remove the data ---} + {-- thats actually written --------------------------------------} + ReturnCode := OutBuffer^.Get(OutBuffer^.TmpBuf, Written, true); + if ReturnCode <> Longint(Written) then + begin + { not everything is removed! } + end; { if } + + {-- if theres data in the buffer left, run this event again -----} + if Written <> BlockLen then + DoTxEvent^.SignalEvent; + end; { if } + + CriticalTx^.LeaveExclusive; + end; { DoTransmit call } + + + until EndThreads; + + DataClosedEvent^.SignalEvent; + ExitThisThread; +end; { proc. ComDataProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_StartThread: Boolean; +begin + Result := false; + EndThreads := false; + if ThreadsInitted then EXIT; + ThreadsInitted := true; + + {----------------------- Create all the events ----------------------------} + New(ReadEvent, Init); + if NOT ReadEvent^.CreateEvent(true) then EXIT; + + New(WriteEvent, Init); + if NOT WriteEvent^.CreateEvent(true) then EXIT; + + New(DoTxEvent, Init); + if NOT DoTxEvent^.CreateEvent(false) then EXIT; + + New(DoRxEvent, Init); + if NOT DoRxEvent^.CreateEvent(false) then EXIT; + + New(DataClosedEvent, Init); + if NOT DataClosedEvent^.CreateEvent(false) then EXIT; + + {-------------- Startup the buffers and overlapped events -----------------} + FillChar(WriteOL, SizeOf(tOverLapped), 0); + FillChar(ReadOL, SizeOf(tOverLapped), 0); + WriteOl.hEvent := WriteEvent^.SemHandle; + ReadOl.hEvent := ReadEvent^.SemHandle; + + New(InBuffer, Init(InBufSize)); + New(OutBuffer, Init(OutBufSize)); + + {-------------------- Startup the critical section objects ----------------} + New(CriticalTx, Init); + CriticalTx^.CreateExclusive; + + New(CriticalRx, Init); + CriticalRx^.CreateExclusive; + + {-------------------- Startup a seperate tx / rx thread -------------------} + New(DataThread, Init); + if NOT DataThread^.CreateThread(16384, { Stack size } + DataProcPtr, { Actual procedure } + nil, { Parameters } + 0) { Creation flags } + then EXIT; + + Result := true; +end; { proc. Com_StartThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_InitVars; +begin + DoTxEvent := nil; + DoRxEvent := nil; + DataClosedEvent := nil; + DataThread := nil; + ReadEvent := nil; + WriteEvent := nil; + + InBuffer := nil; + OutBuffer := nil; + CriticalRx := nil; + CriticalTx := nil; +end; { proc. Com_InitVars } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_StopThread; +begin + EndThreads := true; + ThreadsInitted := false; + + if DoTxEvent <> nil then DoTxEvent^.SignalEvent; + if DoTxEvent <> nil then DoRxEvent^.SignalEvent; + if DataThread <> nil then DataThread^.CloseThread; + + if DataClosedEvent <> nil then + if NOT DataClosedEvent^.WaitForEvent(1000) then + DataThread^.TerminateThread(0); + + if DataThread <> nil then Dispose(DataThread, Done); + if DoTxEvent <> nil then Dispose(DoTxEvent, Done); + if DoRxEvent <> nil then Dispose(DoRxEvent, Done); + if DataClosedEvent <> nil then Dispose(DataClosedEvent, Done); + if ReadEvent <> nil then Dispose(ReadEvent, Done); + if WriteEvent <> nil then Dispose(WriteEvent, Done); + + if CriticalTx <> nil then Dispose(CriticalTx, Done); + if CriticalRx <> nil then Dispose(CriticalRx, Done); + + if InBuffer <> nil then Dispose(InBuffer, Done); + if OutBuffer <> nil then Dispose(OutBuffer, Done); + + Com_InitVars; +end; { proc. Com_StopThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_InitDelayTimes; +var CommTimeOut: TCommTimeouts; + RC : Longint; +begin + FillChar(CommTimeOut, SizeOf(TCommTimeOuts), 00); + CommTimeOut.ReadIntervalTimeout := MAXDWORD; + + if NOT SetCommTimeOuts(SaveHandle, CommTimeOut) then + begin + RC := GetLastError; + ErrorStr := 'Error setting communications timeout: #'+IntToStr(RC) + ' / ' + SysErrorMessage(rc); + end; { if } + +end; { proc. InitDelayTimes } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_GetHandle: Longint; +begin + Result := SaveHandle; +end; { func. Com_GetHandle } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_OpenQuick(Handle: Longint); +var LastError: Longint; +begin + SaveHandle := Handle; + InitHandle := Handle; + + FillChar(ReadOl, SizeOf(ReadOl), 00); + FillChar(WriteOl, SizeOf(WriteOl), 00); + + if NOT SetupComm(Com_GetHandle, Win32InBufSize, Win32OutBufSize) then + begin + LastError := GetLastError; + + ErrorStr := 'Error setting up communications buffer: #'+IntToStr(LastError) + ' / '+SysErrorMessage(LastError); + end; { if } + + Com_InitDelayTimes; + InitFailed := NOT Com_StartThread; + Com_SetLine(-1, 'N', 8, 1); +end; { proc. TWin32Obj.Com_OpenQuick } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_OpenKeep(Comport: Byte): Boolean; +var TempSave : THandle; + Security : TSECURITYATTRIBUTES; + LastError : Longint; +begin + InitPortNr := Comport; + + FillChar(ReadOl, SizeOf(ReadOl), 00); + FillChar(WriteOl, SizeOf(WriteOl), 00); + + FillChar(Security, SizeOf(TSECURITYATTRIBUTES), 0); + Security.nLength := SizeOf(TSECURITYATTRIBUTES); + Security.lpSecurityDescriptor := nil; + Security.bInheritHandle := true; + + TempSave := CreateFile(PChar('\\.\COM' + IntToStr(ComPort)), + GENERIC_READ or GENERIC_WRITE, + 0, + @Security, { No Security } + OPEN_EXISTING, { Creation action } + FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED, + 0); { No template } + LastError := GetLastError; + if LastError <> 0 then + ErrorStr := 'Unable to open communications port'; + + SaveHandle := TempSave; + Result := (TempSave <> INVALID_HANDLE_VALUE); + + if Result then { Make sure that "CharAvail" isn't going to wait } + begin + Com_InitDelayTimes; + end; { if } + + if NOT SetupComm(Com_GetHandle, Win32InBufSize, Win32OutBufSize) then + begin + LastError := GetLastError; + + ErrorStr := 'Error setting up communications buffer: #'+IntToStr(LastError) + ' / '+SysErrorMessage(LastError); + end; { if } + + InitFailed := NOT Com_StartThread; +end; { func. Com_OpenKeep } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; +begin + Com_Open := Com_OpenKeep(Comport); + Com_SetLine(Baudrate, Parity, DataBits, StopBits); +end; { func. TWin32Obj.Com_OpenCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); +var DCB : TDCB; + BPSID : Longint; +begin + if BpsRate = 11520 then { small fix for EleBBS inability to store the bps } + BpsRate := 115200; { rate in anything larger than a 16-bit integer } + + GetCommState(Com_GetHandle, DCB); + + if NOT (Parity in ['N', 'E', 'O', 'M']) then Parity := 'N'; + if BpsRate >= 0 then dcb.BaudRate := BpsRate; + dcb.StopBits := ONESTOPBIT; + + Case Parity of + 'N' : dcb.Parity := NOPARITY; + 'E' : dcb.Parity := EVENPARITY; + 'O' : dcb.Parity := ODDPARITY; + 'M' : dcb.Parity := MARKPARITY; + end; { case } + + Case StopBits of + 1 : dcb.StopBits := ONESTOPBIT; + 2 : dcb.StopBits := TWOSTOPBITS; + 3 : dcb.StopBits := ONE5STOPBITS; + end; { case } + + dcb.ByteSize := DataBits; + dcb.Flags := dcb.Flags OR dcb_Binary OR Dcb_DtrControlEnable; + + if not SetCommState (Com_GetHandle, DCB) then + begin + BPSId := GetLastError; + + ErrorStr := 'Error setting up communications parameters: #'+IntToStr(BpsId) + ' / '+SysErrorMessage(BpsId); + end; { if } +end; { proc. TWin32Obj.Com_SetLine } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_Close; +begin + if DontClose then EXIT; + + if DWORD(Com_GetHandle) <> INVALID_HANDLE_VALUE then + begin + Com_StopThread; + CloseHandle(Com_GetHandle); + + SaveHandle := INVALID_HANDLE_VALUE; + end; + +end; { func. TWin32Obj.Com_CloseCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_SendChar(C: Char): Boolean; +var Written: Longint; +begin + Com_SendBlock(C, SizeOf(C), Written); + Com_SendChar := (Written = SizeOf(c)); +end; { proc. TWin32Obj.Com_SendChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_GetChar: Char; +var Reads: Longint; +begin + Com_ReadBlock(Result, SizeOf(Result), Reads); +end; { func. TWin32Obj.Com_GetChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); +begin + if OutBuffer^.BufRoom < BlockLen then + repeat + {$IFDEF WIN32} + Sleep(1); + {$ENDIF} + until (OutBuffer^.BufRoom >= BlockLen) OR (NOT Com_Carrier); + + CriticalTx^.EnterExclusive; + Written := OutBuffer^.Put(Block, BlockLen); + CriticalTx^.LeaveExclusive; + + DoTxEvent^.SignalEvent; +end; { proc. TWin32Obj.Com_SendBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); +begin + if InBuffer^.BufUsed < BlockLen then + begin + DoRxEvent^.SignalEvent; + + while (InBuffer^.BufUsed < BlockLen) AND (Com_Carrier) do + begin + Sleep(1); + + if Com_CharAvail then + DoRxEvent^.SignalEvent; + end; { while } + end; { if } + + CriticalRx^.EnterExclusive; + Reads := InBuffer^.Get(Block, BlockLen, true); + CriticalRx^.LeaveExclusive; +end; { proc. TWin32Obj.Com_ReadBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_CharAvail: Boolean; +var Props : TComStat; + ErrMask : DWORD; +begin + if InBuffer^.BufUsed < 1 then + begin + ErrMask := 0; + + if ClearCommError(Com_GetHandle, ErrMask, @Props) then + if Props.cbInQue > 0 then + DoRxEvent^.SignalEvent; + end; { if } + + Result := (InBuffer^.BufUsed > 0); +end; { func. TWin32Obj.Com_CharAvail } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_Carrier: Boolean; +var Status: DWORD; +begin + if Com_GetHandle <> INVALID_HANDLE_VALUE then + begin + GetCommModemStatus(Com_GetHandle, + Status); + + Result := (Status AND MS_RLSD_ON) <> 00; + end + else Result := FALSE; +end; { func. TWin32Obj.Com_Carrier } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_GetModemStatus(var LineStatus, ModemStatus: Byte); +var Data: DWORD; +begin + GetCommModemStatus(Com_GetHandle, Data); + + ModemStatus := ModemStatus and $0F; + ModemStatus := ModemStatus or Byte(Data); +end; { proc. TWin32Obj.Com_GetModemStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_SetDtr(State: Boolean); +begin + if State then + EscapeCommFunction(Com_GetHandle, SETDTR) + else EscapeCommFunction(Com_GetHandle, CLRDTR); +end; { proc. TWin32Obj.Com_SetDtr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_GetBpsRate: Longint; +var DCB : TDCB; +begin + GetCommState(Com_GetHandle, DCB); + + Com_GetBpsRate := dcb.Baudrate; +end; { func. TWin32Obj.Com_GetBpsRate } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); +var Stats : TComStat; + ErrMask : DWORD; +begin + if ClearCommError(Com_GetHandle, ErrMask, @Stats) then + begin + if Stats.cbInQue > 0 then + begin + DoRxEvent^.SignalEvent; + Sleep(1); + end; { if } + end; { if } + + + InFree := InBuffer^.BufRoom; + OutFree := OutBuffer^.BufRoom; + InUsed := InBuffer^.BufUsed; + OutUsed := OutBuffer^.BufUsed; +end; { proc. TWin32Obj.Com_GetBufferStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_PurgeInBuffer; +begin + CriticalRx^.EnterExclusive; + + InBuffer^.Clear; + PurgeComm(Com_GetHandle, PURGE_RXCLEAR); + + CriticalRx^.LeaveExclusive; +end; { proc. TWin32Obj.Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_PurgeOutBuffer; +begin + CriticalTx^.EnterExclusive; + + OutBuffer^.Clear; + PurgeComm(Com_GetHandle, PURGE_TXCLEAR); + + CriticalTx^.LeaveExclusive; +end; { proc. TWin32Obj.Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_ReadyToSend(BlockLen: Longint): Boolean; +begin + Result := OutBuffer^.BufRoom >= BlockLen; +end; { func. ReadyToSend } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_PauseCom(CloseCom: Boolean); +begin + if CloseCom then Com_Close + else Com_StopThread; +end; { proc. Com_PauseCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_ResumeCom(OpenCom: Boolean); +begin + if OpenCom then + begin + if InitPortNr <> -1 then Com_OpenKeep(InitPortNr) + else Com_OpenQuick(InitHandle); + end + else InitFailed := NOT Com_StartThread; +end; { proc. Com_ResumeCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_FlushOutBuffer(Slice: SliceProc); +begin + Windows.FlushFileBuffers(Com_GetHandle); + + inherited Com_FlushOutBuffer(Slice); +end; { proc. Com_FlushOutBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); +var DCB : TDCB; + BPSID : Longint; +begin + GetCommState(Com_GetHandle, DCB); + + if Hard then + dcb.Flags := dcb.Flags OR NOT dcb_OutxCtsFlow OR NOT dcb_RtsControlHandshake; + + if SoftTX then + dcb.Flags := dcb.Flags OR NOT dcb_OutX; + + if SoftRX then + dcb.Flags := dcb.Flags OR NOT dcb_InX; + + if not SetCommState(Com_GetHandle, DCB) then + begin + BPSId := GetLastError; + + ErrorStr := 'Error setting up communications parameters: #'+IntToStr(BpsId) + ' / '+SysErrorMessage(BpsId); + end; { if } + + Com_InitDelayTimes; +end; { proc. Com_SetFlow } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_SetDataProc(ReadPtr, WritePtr: Pointer); +begin + DataProcPtr := ReadPtr; +end; { proc. Com_SetDataProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +end. diff --git a/SOURCE/ELECOM/W32SOCK.PAS b/SOURCE/ELECOM/W32SOCK.PAS new file mode 100644 index 0000000..7885dbb --- /dev/null +++ b/SOURCE/ELECOM/W32SOCK.PAS @@ -0,0 +1,205 @@ +unit W32sock; +{&Orgname+} +(* +** +** WINDOWS TCP/IP routines +** +** Copyright (c) 1998 by Thomas W. Mueller +** +** Created : 24-Oct-1998 +** Last update : 20-Feb-2000 +** +** +*) + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses + Windows, + SockDef; + +type + u_char = Char; + u_short = Word; + u_int = Integer; + u_long = Longint; + +{$IFDEF FPC} + type pInteger = ^Integer; +{$ENDIF} + + +{ Socket function prototypes } + +function accept(_s: ULONG; _addr: pSockAddr; _addrlen: PInteger): ULONG; {$IFNDEF FPC} stdcall; {$ENDIF} +function bind(_s: ULONG; _addr: pSockAddr; _namelen: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function connect(_s: ULONG; _name: pSockAddr; _namelen: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function closesocket(s: ULONG): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function select(nfds: Integer; readfds, writefds, exceptfds: PFDSet; + timeout: PTimeVal): Longint; {$IFNDEF FPC} stdcall; {$ENDIF} +function ioctlsocket(_s: ULONG; _cmd: Longint; var _arg: ULONG): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function getpeername(_s: ULONG; _name: pSockAddr; var _namelen: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function getsockname(_s: ULONG; _name: pSockAddr; var _namelen: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function getsockopt(_s: ULONG; _level, _optname: Integer; _optval: PChar; var _optlen: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function htonl(_hostlong: ULONG): ULONG; {$IFNDEF FPC} stdcall; {$ENDIF} +function htons(_hostshort: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function inet_addr(_cp: PChar): ULONG; {$IFNDEF FPC} stdcall; {$ENDIF} +function inet_ntoa(_inaddr: tIn_Addr): PChar; {$IFNDEF FPC} stdcall; {$ENDIF} +function listen(_s: ULONG; _backlog: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function ntohl(_netlong: ULONG): ULONG; {$IFNDEF FPC} stdcall; {$ENDIF} +function ntohs(_netshort: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function recv(_s: ULONG; _Buf: pointer; _len, _flags: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} + +function recvfrom(s: ULONG; _Buf: pointer; _len, _flags: Integer; + var _from: TSockAddr; var _fromlen: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function send(_s: ULONG; _Buf: pointer; _len, _flags: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function sendto(_s: ULONG; _Buf: pointer; _len, _flags: Integer; var _addrto: TSockAddr; + _tolen: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function setsockopt(_s: ULONG; _level, _optname: Integer; _optval: PChar; + _optlen: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function shutdown(_s: ULONG; _how: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function socket(_af, _struct, _protocol: Integer): ULONG; {$IFNDEF FPC} stdcall; {$ENDIF} + +function gethostbyaddr(_addr: Pointer; _len, _struct: Integer): PHostEnt; {$IFNDEF FPC} stdcall; {$ENDIF} +function gethostbyname(_name: PChar): PHostEnt; {$IFNDEF FPC} stdcall; {$ENDIF} +function gethostname(_name: PChar; _len: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function getservbyport(_port: Integer; _proto: PChar): PServEnt; {$IFNDEF FPC} stdcall; {$ENDIF} +function getservbyname(_name, _proto: PChar): PServEnt; {$IFNDEF FPC} stdcall; {$ENDIF} +function getprotobynumber(_proto: Integer): PProtoEnt; {$IFNDEF FPC} stdcall; {$ENDIF} +function getprotobyname(_name: PChar): PProtoEnt; {$IFNDEF FPC} stdcall; {$ENDIF} + +function WSAStartup(wVersionRequired: word; var WSData: TWSAData): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSACleanup: Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +procedure WSASetLastError(iError: Integer); {$IFNDEF FPC} stdcall; {$ENDIF} +function WSAGetLastError: Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSAIsBlocking: BOOL; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSAUnhookBlockingHook: Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSASetBlockingHook(lpBlockFunc: TFarProc): TFarProc; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSACancelBlockingCall: Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSAAsyncGetServByName(HWindow: HWND; wMsg: u_int; + name, proto, buf: PChar; buflen: Integer): THandle; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSAAsyncGetServByPort( HWindow: HWND; wMsg, port: u_int; + proto, buf: PChar; buflen: Integer): THandle; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSAAsyncGetProtoByName(HWindow: HWND; wMsg: u_int; + name, buf: PChar; buflen: Integer): THandle; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSAAsyncGetProtoByNumber(HWindow: HWND; wMsg: u_int; number: Integer; + buf: PChar; buflen: Integer): THandle; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSAAsyncGetHostByName(HWindow: HWND; wMsg: u_int; + name, buf: PChar; buflen: Integer): THandle; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSAAsyncGetHostByAddr(HWindow: HWND; wMsg: u_int; addr: PChar; + len, struct: Integer; buf: PChar; buflen: Integer): THandle; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSACancelAsyncRequest(hAsyncTaskHandle: THandle): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSAAsyncSelect(s: ULONG; HWindow: HWND; wMsg: u_int; lEvent: Longint): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} +function WSARecvEx(s: ULONG; var buf; len: Integer; var flags: Integer): Integer; {$IFNDEF FPC} stdcall; {$ENDIF} + +function WSAMakeSyncReply(Buflen, Error: Word): Longint; +function WSAMakeSelectReply(Event, Error: Word): Longint; +function WSAGetAsyncBuflen(Param: Longint): Word; +function WSAGetAsyncError(Param: Longint): Word; +function WSAGetSelectEvent(Param: Longint): Word; +function WSAGetSelectError(Param: Longint): Word; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +const + winsocket = 'wsock32.dll'; + +function WSAMakeSyncReply(Buflen, Error: Word): Longint; +begin + WSAMakeSyncReply:= MakeLong(Buflen, Error); +end; + +function WSAMakeSelectReply(Event, Error: Word): Longint; +begin + WSAMakeSelectReply:= MakeLong(Event, Error); +end; + +function WSAGetAsyncBuflen(Param: Longint): Word; +begin + WSAGetAsyncBuflen:= LOWORD(Param); +end; + +function WSAGetAsyncError(Param: Longint): Word; +begin + WSAGetAsyncError:= HIWORD(Param); +end; + +function WSAGetSelectEvent(Param: Longint): Word; +begin + WSAGetSelectEvent:= LOWORD(Param); +end; + +function WSAGetSelectError(Param: Longint): Word; +begin + WSAGetSelectError:= HIWORD(Param); +end; + +function accept(_s: ULONG; _addr: pSockAddr; _addrlen: PInteger): ULONG; external winsocket name 'accept'; +function bind(_s: ULONG; _addr: pSockAddr; _namelen: Integer): Integer; external winsocket name 'bind'; +function connect(_s: ULONG; _name: pSockAddr; _namelen: Integer): Integer; external winsocket name 'connect'; +function closesocket(s: ULONG): Integer; external winsocket name 'closesocket'; +function select(nfds: Integer; readfds, writefds, exceptfds: PFDSet; + timeout: PTimeVal): Longint; external winsocket name 'select'; +function ioctlsocket(_s: ULONG; _cmd: Longint; var _arg: ULONG): Integer; external winsocket name 'ioctlsocket'; +function getpeername(_s: ULONG; _name: pSockAddr; var _namelen: Integer): Integer; external winsocket name 'getpeername'; +function getsockname(_s: ULONG; _name: pSockAddr; var _namelen: Integer): Integer; external winsocket name 'getsockname'; +function getsockopt(_s: ULONG; _level, _optname: Integer; _optval: PChar; var _optlen: Integer): Integer; external winsocket name 'getsockopt'; +function htonl(_hostlong: ULONG): ULONG; external winsocket name 'htonl'; +function htons(_hostshort: Integer): Integer; external winsocket name 'htons'; +function inet_addr(_cp: PChar): ULONG; external winsocket name 'inet_addr'; +function inet_ntoa(_inaddr: tIn_Addr): PChar; external winsocket name 'inet_ntoa'; +function listen(_s: ULONG; _backlog: Integer): Integer; external winsocket name 'listen'; +function ntohl(_netlong: ULONG): ULONG; external winsocket name 'ntohl'; +function ntohs(_netshort: Integer): Integer; external winsocket name 'ntohs'; +function recv(_s: ULONG; _Buf: pointer; _len, _flags: Integer): Integer; external winsocket name 'recv'; + + +function recvfrom(s: ULONG; _Buf: pointer; _len, _flags: Integer; + var _from: TSockAddr; var _fromlen: Integer): Integer; external winsocket name 'recvfrom'; +function send(_s: ULONG; _Buf: pointer; _len, _flags: Integer): Integer; external winsocket name 'send'; +function sendto(_s: ULONG; _Buf: pointer; _len, _flags: Integer; var _addrto: TSockAddr; + _tolen: Integer): Integer; external winsocket name 'sendto'; +function setsockopt(_s: ULONG; _level, _optname: Integer; _optval: PChar; + _optlen: Integer): Integer; external winsocket name 'setsockopt'; +function shutdown(_s: ULONG; _how: Integer): Integer; external winsocket name 'shutdown'; +function socket(_af, _struct, _protocol: Integer): ULONG; external winsocket name 'socket'; + + +function gethostbyaddr(_addr: Pointer; _len, _struct: Integer): PHostEnt; external winsocket name 'gethostbyaddr'; +function gethostbyname(_name: PChar): PHostEnt; external winsocket name 'gethostbyname'; +function gethostname(_name: PChar; _len: Integer): Integer; external winsocket name 'gethostname'; +function getservbyport(_port: Integer; _proto: PChar): PServEnt; external winsocket name 'getservbyport'; +function getservbyname(_name, _proto: PChar): PServEnt; external winsocket name 'getservbyname'; +function getprotobynumber(_proto: Integer): PProtoEnt; external winsocket name 'getprotobynumber'; +function getprotobyname(_name: PChar): PProtoEnt; external winsocket name 'getprotobyname'; + + +function WSAStartup(wVersionRequired: word; var WSData: TWSAData): Integer; external winsocket name 'WSAStartup'; +function WSACleanup: Integer; external winsocket name 'WSACleanup'; +procedure WSASetLastError(iError: Integer); external winsocket name 'WSASetLastError'; +function WSAGetLastError: Integer; external winsocket name 'WSAGetLastError'; +function WSAIsBlocking: BOOL; external winsocket name 'WSAIsBlocking'; +function WSAUnhookBlockingHook: Integer; external winsocket name 'WSAUnhookBlockingHook'; +function WSASetBlockingHook(lpBlockFunc: TFarProc): TFarProc; external winsocket name 'WSASetBlockingHook'; +function WSACancelBlockingCall: Integer; external winsocket name 'WSACancelBlockingCall'; +function WSAAsyncGetServByName(HWindow: HWND; wMsg: u_int; + name, proto, buf: PChar; buflen: Integer): THandle; external winsocket name 'WSAAsyncGetServByName'; +function WSAAsyncGetServByPort( HWindow: HWND; wMsg, port: u_int; + proto, buf: PChar; buflen: Integer): THandle; external winsocket name 'WSAAsyncGetServByPort'; +function WSAAsyncGetProtoByName(HWindow: HWND; wMsg: u_int; + name, buf: PChar; buflen: Integer): THandle; external winsocket name 'WSAAsyncGetProtoByName'; +function WSAAsyncGetProtoByNumber(HWindow: HWND; wMsg: u_int; number: Integer; + buf: PChar; buflen: Integer): THandle; external winsocket name 'WSAAsyncGetProtoByNumber'; +function WSAAsyncGetHostByName(HWindow: HWND; wMsg: u_int; + name, buf: PChar; buflen: Integer): THandle; external winsocket name 'WSAAsyncGetHostByName'; +function WSAAsyncGetHostByAddr(HWindow: HWND; wMsg: u_int; addr: PChar; + len, struct: Integer; buf: PChar; buflen: Integer): THandle; external winsocket name 'WSAAsyncGetHostByAddr'; +function WSACancelAsyncRequest(hAsyncTaskHandle: THandle): Integer; external winsocket name 'WSACancelAsyncRequest'; +function WSAAsyncSelect(s: ULONG; HWindow: HWND; wMsg: u_int; lEvent: Longint): Integer; external winsocket name 'WSAAsyncSelect'; +function WSARecvEx(s: ULONG; var buf; len: Integer; var flags: Integer): Integer; external winsocket name 'WSARecvEx'; + +end. { unit. W32SOCK } diff --git a/SOURCE/ELECOM/WIN32COM.PAS b/SOURCE/ELECOM/WIN32COM.PAS new file mode 100644 index 0000000..008434b --- /dev/null +++ b/SOURCE/ELECOM/WIN32COM.PAS @@ -0,0 +1,790 @@ +unit WIN32COM; +(* +** +** Serial and TCP/IP communication routines for DOS, OS/2 and Win9x/NT. +** Tested with: TurboPascal v7.0, (DOS) +** VirtualPascal v2.0, (OS/2, Win32) +** FreePascal v0.99.15 (DOS, Win32) +** Delphi v4.0. (Win32) +** +** Version : 1.01 +** Created : 21-May-1998 +** Last update : 20-Feb-2000 +** +** Note: (c) 1998-2000 by Maarten Bekers +** +*) + +This unit is not supported anymore. +Remove this in order to be compiled anyway. The next release of EleCOM will +not include WIN32COM.PAS anymore. W32SNGL.PAS is the replacement unit. + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + INTERFACE +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses Windows, Combase, BufUnit, Threads + {$IFDEF VirtualPascal} + ,Use32 + {$ENDIF}; + +Const WriteTimeout = 20000; { Wait max. 20 secs } + ReadTimeOut = 20000; { General event, 20 secs max } + + InBufSize = 1024 * 32; + OutBufSize = 1024 * 32; + + +type TWin32Obj = Object(TCommObj) + ReadProcPtr: Pointer; { Pointer to TX/RX handler (thread) } + WriteProcPtr: Pointer; { Pointer to TX/RX handler (thread) } + ThreadsInitted: Boolean; { Are the thread(s) up and running? } + + SaveHandle : THandle; + + InitPortNr : Longint; + InitHandle : Longint; + + ReadOL : TOverLapped; { Overlapped structure for ReadFile } + WriteOL : TOverLapped; { Overlapped structure for WriteFile } + + InBuffer : ^BufArrayObj; { Buffer system internally used } + OutBuffer : ^BufArrayObj; + + ReadEvent : PSysEventObj; { Event set by ReadFile overlapped routine } + WriteEvent : PSysEventObj; { Event set by WriteFile overlapped routine } + RecvEvent : PSysEventObj; + + DoTxEvent : PSysEventObj;{ Event manually set when we have to transmit } + + TxClosedEvent : PSysEventObj; { Event set when the Tx thread is closed } + RxClosedEvent : PSysEventObj; { Event set when the Rx thread is closed } + + CriticalTx : PExclusiveObj; { Critical sections } + CriticalRx : PExclusiveObj; + + TxThread : PThreadsObj; { The Transmit and Receive threads } + RxThread : PThreadsObj; + + EndThreads : Boolean; { Set to true when we have to end the threads } + + constructor Init; + destructor Done; + + function Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; virtual; + function Com_OpenKeep(Comport: Byte): Boolean; virtual; + function Com_GetChar: Char; virtual; + function Com_CharAvail: Boolean; virtual; + function Com_Carrier: Boolean; virtual; + function Com_SendChar(C: Char): Boolean; virtual; + function Com_ReadyToSend(BlockLen: Longint): Boolean; virtual; + function Com_GetBPSrate: Longint; virtual; + function Com_GetHandle: Longint; virtual; + + procedure Com_OpenQuick(Handle: Longint); virtual; + procedure Com_Close; virtual; + procedure Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); virtual; + procedure Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); virtual; + procedure Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); virtual; + procedure Com_SetDtr(State: Boolean); virtual; + procedure Com_GetModemStatus(var LineStatus, ModemStatus: Byte); virtual; + procedure Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); virtual; + procedure Com_PurgeInBuffer; virtual; + procedure Com_PurgeOutBuffer; virtual; + + procedure Com_PauseCom(CloseCom: Boolean); virtual; + procedure Com_ResumeCom(OpenCom: Boolean); virtual; + procedure Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); virtual; + + procedure Com_SetDataProc(ReadPtr, WritePtr: Pointer); virtual; + + procedure Com_ReadProc(var TempPtr: Pointer); + procedure Com_WriteProc(var TempPtr: Pointer); + + function Com_StartThread: Boolean; + procedure Com_InitVars; + procedure Com_StopThread; + procedure Com_InitDelayTimes; + end; { object TWin32Obj } + +type PWin32Obj = ^TWin32Obj; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + IMPLEMENTATION +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +uses SysUtils; + +{$IFDEF FPC} + {$I WINDEF.FPC} +{$ENDIF} + +const + dcb_Binary = $00000001; + dcb_ParityCheck = $00000002; + dcb_OutxCtsFlow = $00000004; + dcb_OutxDsrFlow = $00000008; + dcb_DtrControlMask = $00000030; + dcb_DtrControlDisable = $00000000; + dcb_DtrControlEnable = $00000010; + dcb_DtrControlHandshake = $00000020; + dcb_DsrSensivity = $00000040; + dcb_TXContinueOnXoff = $00000080; + dcb_OutX = $00000100; + dcb_InX = $00000200; + dcb_ErrorChar = $00000400; + dcb_NullStrip = $00000800; + dcb_RtsControlMask = $00003000; + dcb_RtsControlDisable = $00000000; + dcb_RtsControlEnable = $00001000; + dcb_RtsControlHandshake = $00002000; + dcb_RtsControlToggle = $00003000; + dcb_AbortOnError = $00004000; + dcb_Reserveds = $FFFF8000; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +constructor TWin32Obj.Init; +begin + inherited Init; + + InitPortNr := -1; + InitHandle := -1; + ThreadsInitted := false; + Com_InitVars; +end; { constructor Init } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +destructor TWin32Obj.Done; +begin + inherited done; +end; { destructor Done } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_ReadProc(var TempPtr: Pointer); +var EventMask : DWORD; + Success : Boolean; + Props : TCommProp; + ReturnCode: Longint; + DidRead : DWORD; + BlockLen : Longint; + + RecvOL : tOverlapped; +begin + New(RecvEvent, Init); + if NOT RecvEvent^.CreateEvent(true) then EXIT; + + FillChar(RecvOL, SizeOf(tOverLapped), 0); + RecvOL.hEvent := RecvEvent^.SemHandle; + + EventMask := EV_RXCHAR; + SetCommMask(SaveHandle, EventMask); { Signal us if anything is received } + + repeat + WaitCommEvent(SaveHandle, EventMask, @RecvOL); + if EndThreads then EXIT; + + repeat + ReturnCode := WaitForSingleObject(RecvOL.hEvent, 500); + if ReturnCode = WAIT_OBJECT_0 then + begin + Success := true + end { if } + else Success := false; + + if EndThreads then BREAK; + until (Success); + + DidRead := 00; + + if (NOT Success) OR (EventMask = 0) then EXIT; + if (EndThreads) then EXIT; + + {----------------- Start reading the gathered date ---------------------} + CriticalRx^.EnterExclusive; + + FillChar(Props, SizeOf(TCommProp), 0); + + if GetCommProperties(SaveHandle, Props) then + if InBuffer^.BufRoom > 0 then + begin + BlockLen := Props.dwCurrentRxQueue; + + if BlockLen > InBuffer^.BufRoom then + BlockLen := InBuffer^.BufRoom; + + Success := ReadFile(SaveHandle, + InBuffer^.TmpBuf^, + BlockLen, + DidRead, + @ReadOL); + + if NOT Success then + begin + ReturnCode := GetLastError; + + if ReturnCode = ERROR_IO_PENDING then + begin + ReturnCode := WaitForSingleObject(ReadOL.hEvent, ReadTimeOut); + + if ReturnCode = WAIT_OBJECT_0 then + begin + GetOverLappedResult(SaveHandle, ReadOL, DidRead, false); + end; { if } + end; { if } + end + else GetOverlappedResult(SaveHandle, ReadOL, DidRead, false); + + if DidRead > 00 then + InBuffer^.Put(InBuffer^.TmpBuf^, DidRead); + end; { if } + + CriticalRx^.LeaveExclusive; + until EndThreads; + + RxClosedEvent^.SignalEvent; + ExitThisThread; +end; { proc. ComReadProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_WriteProc(var TempPtr: Pointer); +var BlockLen : Longint; + Written : DWORD; + ReturnCode: Longint; + Success : Boolean; +begin + repeat + if DoTxEvent^.WaitForEvent(WriteTimeOut) then + if NOT EndThreads then + begin + CriticalTx^.EnterExclusive; + DoTxEvent^.ResetEvent; + + if OutBuffer^.BufUsed > 00 then + begin + Written := 00; + BlockLen := OutBuffer^.Get(OutBuffer^.TmpBuf^, OutBuffer^.BufUsed, false); + + Success := WriteFile(SaveHandle, + OutBuffer^.TmpBuf^, + BlockLen, + Written, + @WriteOL); + if NOT Success then + begin + ReturnCode := GetLastError; + + if ReturnCode = ERROR_IO_PENDING then + begin + ReturnCode := WaitForSingleObject(WriteOL.hEvent, WriteTimeOut); + + if ReturnCode = WAIT_OBJECT_0 then + begin + if GetOverLappedResult(SaveHandle, WriteOL, Written, false) then + begin + ResetEvent(WriteOL.hEvent); + end; { if } + end; { if } + end; { result is pending } + end { if } + else begin + + if GetOverLappedResult(SaveHandle, WriteOL, Written, false) then + begin + ResetEvent(WriteOL.hEvent); + end; { if } + end; { if (did succeed) } + + ReturnCode := OutBuffer^.Get(OutBuffer^.TmpBuf^, Written, true); + if Written <> BlockLen then + DoTxEvent^.SignalEvent; + end; { if } + + CriticalTx^.LeaveExclusive; + end; { if } + + until EndThreads; + + TxClosedEvent^.SignalEvent; + ExitThisThread; +end; { proc. ComWriteProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_StartThread: Boolean; +begin + Result := false; + EndThreads := false; + if ThreadsInitted then EXIT; + ThreadsInitted := true; + + {----------------------- Create all the events ----------------------------} + New(ReadEvent, Init); + if NOT ReadEvent^.CreateEvent(true) then EXIT; + + New(WriteEvent, Init); + if NOT WriteEvent^.CreateEvent(true) then EXIT; + + New(DoTxEvent, Init); + if NOT DoTxEvent^.CreateEvent(false) then EXIT; + + New(RxClosedEvent, Init); + if NOT RxClosedEvent^.CreateEvent(false) then EXIT; + + New(TxClosedEvent, Init); + if NOT TxClosedEvent^.CreateEvent(false) then EXIT; + + {-------------- Startup the buffers and overlapped events -----------------} + FillChar(WriteOL, SizeOf(tOverLapped), 0); + FillChar(ReadOL, SizeOf(tOverLapped), 0); + WriteOl.hEvent := WriteEvent^.SemHandle; + ReadOl.hEvent := ReadEvent^.SemHandle; + + New(InBuffer, Init(InBufSize)); + New(OutBuffer, Init(OutBufSize)); + + if (InBuffer^.TxtArr=nil) OR (InBuffer^.TmpBuf=nil) then EXIT; + if (OutBuffer^.TxtArr=nil) OR (OutBuffer^.TmpBuf=nil) then EXIT; + + {-------------------- Startup a seperate write thread ---------------------} + New(CriticalTx, Init); + CriticalTx^.CreateExclusive; + + New(TxThread, Init); + if NOT TxThread^.CreateThread(16384, { Stack size } + @WriteProcPtr, { Actual procedure } + nil, { Parameters } + 0) { Creation flags } + then EXIT; + + {-------------------- Startup a seperate read thread ----------------------} + New(CriticalRx, Init); + CriticalRx^.CreateExclusive; + + New(RxThread, Init); + if NOT RxThread^.CreateThread(16384, { Stack size } + @ReadProcPtr, { Actual procedure } + nil, { Parameters } + 0) { Creation flags } + then EXIT; + + Result := true; +end; { proc. Com_StartThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_InitVars; +begin + DoTxEvent := nil; + RxClosedEvent := nil; + TxClosedEvent := nil; + RecvEvent := nil; + ReadEvent := nil; + WriteEvent := nil; + TxThread := nil; + RxThread := nil; + + InBuffer := nil; + OutBuffer := nil; + CriticalRx := nil; + CriticalTx := nil; +end; { proc. Com_InitVars } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_StopThread; +begin + EndThreads := true; + ThreadsInitted := false; + + if DoTxEvent <> nil then DoTxEvent^.SignalEvent; + + if TxThread <> nil then TxThread^.CloseThread; + if RxThread <> nil then RxThread^.CloseThread; + + if TxClosedEvent <> nil then + if NOT TxClosedEvent^.WaitForEvent(1000) then + TxThread^.TerminateThread(0); + + if RxClosedEvent <> nil then + if NOT RxClosedEvent^.WaitForEvent(1000) then + RxThread^.TerminateThread(0); + + if TxThread <> nil then Dispose(TxThread, Done); + if RxThread <> nil then Dispose(RxThread, Done); + if DoTxEvent <> nil then Dispose(DoTxEvent, Done); + if RxClosedEvent <> nil then Dispose(RxClosedEvent, Done); + if TxClosedEvent <> nil then Dispose(TxClosedEvent, Done); + + if CriticalTx <> nil then Dispose(CriticalTx, Done); + if CriticalRx <> nil then Dispose(CriticalRx, Done); + + if InBuffer <> nil then Dispose(InBuffer, Done); + if OutBuffer <> nil then Dispose(OutBuffer, Done); + + if RecvEvent <> nil then Dispose(RecvEvent, Done); + if ReadEvent <> nil then Dispose(ReadEvent, Done); + if WriteEvent <> nil then Dispose(WriteEvent, Done); + + Com_InitVars; +end; { proc. Com_StopThread } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_InitDelayTimes; +var CommTimeOut: TCommTimeouts; + RC : Longint; +begin + FillChar(CommTimeOut, SizeOf(TCommTimeOuts), 00); + CommTimeOut.ReadIntervalTimeout := MAXDWORD; + + if NOT SetCommTimeOuts(SaveHandle, CommTimeOut) then + begin + RC := GetLastError; + { ErrorStr := 'Error setting communications timeout: #'+IntToStr(RC) + ' / ' + SysErrorMessage(rc)); } + end; { if } + +end; { proc. InitDelayTimes } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_GetHandle: Longint; +begin + Result := SaveHandle; +end; { func. Com_GetHandle } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_OpenQuick(Handle: Longint); +var LastError: Longint; +begin + SaveHandle := Handle; + InitHandle := Handle; + + FillChar(ReadOl, SizeOf(ReadOl), 00); + FillChar(WriteOl, SizeOf(WriteOl), 00); + + Com_InitDelayTimes; + + if NOT SetupComm(Com_GetHandle, 1024, 1024) then + begin + LastError := GetLastError; + + { ErrorStr := 'Error setting up communications buffer: #'+IntToStr(LastError) + ' / '+SysErrorMessage(LastError); } + end; { if } + + InitFailed := NOT Com_StartThread; + Com_SetLine(-1, 'N', 8, 1); +end; { proc. TWin32Obj.Com_OpenQuick } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_OpenKeep(Comport: Byte): Boolean; +var TempSave : THandle; + Security : TSECURITYATTRIBUTES; + LastError : Longint; +begin + InitPortNr := Comport; + + FillChar(ReadOl, SizeOf(ReadOl), 00); + FillChar(WriteOl, SizeOf(WriteOl), 00); + + FillChar(Security, SizeOf(TSECURITYATTRIBUTES), 0); + Security.nLength := SizeOf(TSECURITYATTRIBUTES); + Security.lpSecurityDescriptor := nil; + Security.bInheritHandle := true; + + TempSave := CreateFile(PChar('\\.\COM' + IntToStr(ComPort)), + GENERIC_READ or GENERIC_WRITE, + 0, + @Security, { No Security } + OPEN_EXISTING, { Creation action } + FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED, + 0); { No template } + LastError := GetLastError; + if LastError <> 0 then + ErrorStr := 'Unable to open communications port'; + + SaveHandle := TempSave; + Result := (TempSave <> INVALID_HANDLE_VALUE); + + if Result then { Make sure that "CharAvail" isn't going to wait } + begin + Com_InitDelayTimes; + end; { if } + + if NOT SetupComm(Com_GetHandle, 1024, 1024) then + begin + LastError := GetLastError; + + { ErrorStr := 'Error setting up communications buffer: #'+IntToStr(LastError) + ' / '+SysErrorMessage(LastError); } + end; { if } + + InitFailed := NOT Com_StartThread; +end; { func. Com_OpenKeep } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte; + Parity: Char; StopBits: Byte): Boolean; +begin + Com_Open := Com_OpenKeep(Comport); + Com_SetLine(Baudrate, Parity, DataBits, StopBits); +end; { func. TWin32Obj.Com_OpenCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte); +var DCB : TDCB; + BPSID : Longint; +begin + if BpsRate = 11520 then + BpsRate := 115200; + + GetCommState(Com_GetHandle, DCB); + + if NOT (Parity in ['N', 'E', 'O', 'M']) then Parity := 'N'; + if BpsRate >= 0 then dcb.BaudRate := BpsRate; + dcb.StopBits := ONESTOPBIT; + + Case Parity of + 'N' : dcb.Parity := NOPARITY; + 'E' : dcb.Parity := EVENPARITY; + 'O' : dcb.Parity := ODDPARITY; + 'M' : dcb.Parity := MARKPARITY; + end; { case } + + if StopBits = 1 then + dcb.StopBits := ONESTOPBIT; + dcb.ByteSize := DataBits; + dcb.Flags := dcb.Flags OR dcb_Binary or Dcb_DtrControlEnable; + + if not SetCommState (Com_GetHandle, DCB) then + begin + BPSId := GetLastError; + + { ErrorStr := 'Error setting up communications parameters: #'+IntToStr(BpsId) + ' / '+SysErrorMessage(BpsId); } + end; { if } +end; { proc. TWin32Obj.Com_SetLine } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_Close; +begin + if DontClose then EXIT; + + if Com_GetHandle <> INVALID_HANDLE_VALUE then + begin + Com_StopThread; + CloseHandle(Com_GetHandle); + + SaveHandle := INVALID_HANDLE_VALUE; + end; + +end; { func. TWin32Obj.Com_CloseCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_SendChar(C: Char): Boolean; +var Written: Longint; +begin + Com_SendBlock(C, SizeOf(C), Written); + Com_SendChar := (Written = SizeOf(c)); +end; { proc. TWin32Obj.Com_SendChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_GetChar: Char; +var Reads: Longint; +begin + Com_ReadBlock(Result, SizeOf(Result), Reads); +end; { func. TWin32Obj.Com_GetChar } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint); +begin + if OutBuffer^.BufRoom < BlockLen then + repeat + {$IFDEF WIN32} + Sleep(1); + {$ENDIF} + + {$IFDEF OS2} + DosSleep(1); + {$ENDIF} + until (OutBuffer^.BufRoom >= BlockLen) OR (NOT Com_Carrier); + + CriticalTx^.EnterExclusive; + Written := OutBuffer^.Put(Block, BlockLen); + CriticalTx^.LeaveExclusive; + + DoTxEvent^.SignalEvent; +end; { proc. TWin32Obj.Com_SendBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint); +begin + if InBuffer^.BufUsed < BlockLen then + begin + repeat + Sleep(1); + until (InBuffer^.BufUsed >= BlockLen) OR (NOT Com_Carrier); + end; { if } + + CriticalRx^.EnterExclusive; + Reads := InBuffer^.Get(Block, BlockLen, true); + CriticalRx^.LeaveExclusive; +end; { proc. TWin32Obj.Com_ReadBlock } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_CharAvail: Boolean; +begin + Result := (InBuffer^.BufUsed > 0); +end; { func. TWin32Obj.Com_CharAvail } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_Carrier: Boolean; +var Status: DWORD; +begin + GetCommModemStatus(Com_GetHandle, + Status); + + Result := (Status AND MS_RLSD_ON) <> 00; +end; { func. TWin32Obj.Com_Carrier } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_GetModemStatus(var LineStatus, ModemStatus: Byte); +var Data: DWORD; +begin + GetCommModemStatus(Com_GetHandle, Data); + + ModemStatus := ModemStatus and $0F; + ModemStatus := ModemStatus or Byte(Data); +end; { proc. TWin32Obj.Com_GetModemStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_SetDtr(State: Boolean); +begin + if State then + EscapeCommFunction(Com_GetHandle, SETDTR) + else EscapeCommFunction(Com_GetHandle, CLRDTR); +end; { proc. TWin32Obj.Com_SetDtr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_GetBpsRate: Longint; +var DCB : TDCB; + BPSID : Longint; +begin + GetCommState(Com_GetHandle, DCB); + + Com_GetBpsRate := dcb.Baudrate; +end; { func. TWin32Obj.Com_GetBpsRate } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint); +begin + InFree := InBuffer^.BufRoom; + OutFree := OutBuffer^.BufRoom; + InUsed := InBuffer^.BufUsed; + OutUsed := OutBuffer^.BufUsed; +end; { proc. TWin32Obj.Com_GetBufferStatus } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_PurgeInBuffer; +begin + CriticalRx^.EnterExclusive; + + InBuffer^.Clear; + PurgeComm(Com_GetHandle, PURGE_RXCLEAR); + + CriticalRx^.LeaveExclusive; +end; { proc. TWin32Obj.Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_PurgeOutBuffer; +begin + CriticalTx^.EnterExclusive; + + OutBuffer^.Clear; + PurgeComm(Com_GetHandle, PURGE_TXCLEAR); + + CriticalTx^.LeaveExclusive; +end; { proc. TWin32Obj.Com_PurgeInBuffer } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +function TWin32Obj.Com_ReadyToSend(BlockLen: Longint): Boolean; +begin + Result := OutBuffer^.BufRoom >= BlockLen; +end; { func. ReadyToSend } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_PauseCom(CloseCom: Boolean); +begin + if CloseCom then Com_Close + else Com_StopThread; +end; { proc. Com_PauseCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_ResumeCom(OpenCom: Boolean); +begin + if OpenCom then + begin + if InitPortNr <> -1 then Com_OpenKeep(InitPortNr) + else Com_OpenQuick(InitHandle); + end + else InitFailed := NOT Com_StartThread; +end; { proc. Com_ResumeCom } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_SetFlow(SoftTX, SoftRX, Hard: Boolean); +var DCB : TDCB; + BPSID : Longint; +begin + GetCommState(Com_GetHandle, DCB); + + if Hard then + dcb.Flags := dcb.Flags OR dcb_OutxCtsFlow OR dcb_RtsControlHandshake; + + if SoftTX then + dcb.Flags := dcb.Flags OR dcb_OutX; + + if SoftRX then + dcb.Flags := dcb.Flags OR dcb_InX; + + if not SetCommState (Com_GetHandle, DCB) then + begin + BPSId := GetLastError; + + { ErrorStr := 'Error setting up communications parameters: #'+IntToStr(BpsId) + ' / '+SysErrorMessage(BpsId); } + end; { if } +end; { proc. Com_SetFlow } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure TWin32Obj.Com_SetDataProc(ReadPtr, WritePtr: Pointer); +begin + ReadProcPtr := ReadPtr; + WriteProcPtr := WritePtr; +end; { proc. Com_SetDataProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +end. diff --git a/SOURCE/ELECOM/WINDEF.FPC b/SOURCE/ELECOM/WINDEF.FPC new file mode 100644 index 0000000..c8b4756 --- /dev/null +++ b/SOURCE/ELECOM/WINDEF.FPC @@ -0,0 +1,79 @@ +(* +** +** Include file to make FPC more Delphi compatible +** +*) + +{$IFDEF FPC} +type DCB = record + DCBlength : DWORD; + BaudRate : DWORD; + flags : longint; + wReserved : WORD; + XonLim : WORD; + XoffLim : WORD; + ByteSize : BYTE; + Parity : BYTE; + StopBits : BYTE; + XonChar : char; + XoffChar : char; + ErrorChar : char; + EofChar : char; + EvtChar : char; + wReserved1 : WORD; + end; + + TDcb = DCB; + pInteger = ^Integer; + + PSecurityAttributes = ^TSecurityAttributes; + TSecurityAttributes = record + nLength: Longint; + lpSecurityDescriptor: Pointer; + bInheritHandle: Bool; + end; + + function GetCommState(hFile:HANDLE; var lpDCB:TDCB):WINBOOL; external 'kernel32' name 'GetCommState'; + function SetCommState(hFile:HANDLE; var lpDCB:TDCB):WINBOOL; external 'kernel32' name 'SetCommState'; + function WaitForMultipleObjects(nCount:DWORD; lpHandles:Pointer; bWaitAll:WINBOOL; dwMilliseconds:DWORD):DWORD; external 'kernel32' name 'WaitForMultipleObjects'; + + +{-- Apparently, FPC 1.0 doesnt have the "SysErrorMessage" defined in its ------} +{-- SYSUTILS unit. We create this function here. ------------------------------} +function FormatMessageA(dwFlags : DWORD; + lpSource : Pointer; + dwMessageId : DWORD; + dwLanguageId: DWORD; + lpBuffer : PCHAR; + nSize : DWORD; + Arguments : Pointer): DWORD; external 'kernel32' name 'FormatMessageA'; + + +function SysErrorMessage(ErrorCode: Integer): String; +const + MaxMsgSize = Format_Message_Max_Width_Mask; + +var MsgBuffer: pChar; +begin + {-- Allocate memory for error message ---------------------------------------} + GetMem(MsgBuffer, MaxMsgSize); + FillChar(MsgBuffer^, MaxMsgSize, #0); + + {-- Retrieve the message ----------------------------------------------------} + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, + nil, + ErrorCode, + MakeLangId(LANG_NEUTRAL, SUBLANG_DEFAULT), + MsgBuffer, { This function allocs the memory } + MaxMsgSize, { Maximum message size } + nil); + + {-- Return the string and release the memory --------------------------------} + SysErrorMessage := StrPas(MsgBuffer); + + FreeMem(MsgBuffer, MaxMsgSize); +end; { func. SysErrorMessage } + +{$ENDIF} + + diff --git a/SOURCE/ELECOM/dllexam.pas b/SOURCE/ELECOM/dllexam.pas new file mode 100644 index 0000000..0ef7dc2 --- /dev/null +++ b/SOURCE/ELECOM/dllexam.pas @@ -0,0 +1,86 @@ +program DLLEXAM; +{$H-} { important, turn off Ansi-Strings } +(* +** +** Example how to use communications with the DLL file +** You can install this program from within EleBBS and test how it works :) +** +** version: 1.02 +** Created: 13-Jun-1999 +** +** EleBBS install lines: +** +** DOS install line: DLLEXAM.EXE -H*P +** Win32 install line: DLLEXAM.EXE -H*W +** Win32 (telnet) install line: DLLEXAM.EXE -H*W -XT +** OS/2 install line: DLLEXAM.EXE -H*W +** OS/2 (telnet) install line: DLLEXAM.EXE -H*W -XT +** +*) + +uses EleDEF; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +var IsTelnet : Boolean; + ComHandle : Longint; + ReadCH : Char; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure ParseCommandLine; +var Counter: Longint; + TempStr: String; + {$IFDEF MSDOS} + Code : Integer; + {$ELSE} + Code : Longint; + {$ENDIF} +begin + for Counter := 01 to ParamCount do + begin + TempStr := ParamStr(Counter); + + if TempStr[1] in ['/', '-'] then + Case UpCase(TempStr[2]) of + 'H' : begin + + TempStr := Copy(TempStr, 3, Length(TempStr) - 2); + Val(TempStr, ComHandle, Code); + + + end; { 'H' } + 'X' : begin + + if UpCase(TempStr[3]) = 'T' then { XT } + IsTelnet := true; + + end; { 'X' } + end; { case } + + end; { for } +end; { proc. ParseCommandLine } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +begin + IsTelnet := false; + ParseCommandLine; + + Case IsTelnet of + FALSE : Com_StartUp(1); + TRUE : Com_StartUp(2); + end; { case } + + Com_SetDontClose(true); { We use an inherited handle, never close it! } + Com_OpenQuick(ComHandle); { Open the comport using the handle } + + Com_SendString('Hello there!' + #13#10); + Com_SendString('Press [ENTER]'); + + repeat + ReadCH := Com_GetChar; + until (ReadCH = #13) OR (NOT Com_Carrier); + + Com_ShutDown; +end. diff --git a/SOURCE/ELECOM/example.pas b/SOURCE/ELECOM/example.pas new file mode 100644 index 0000000..159cfd4 --- /dev/null +++ b/SOURCE/ELECOM/example.pas @@ -0,0 +1,181 @@ +program Example; +(* +** +** EXAMPLE how to use communications +** You can install this program from within EleBBS and test how it works :) +** This is only an example of how to use EleCOM for writing so-called "doors", +** to see an example how to use EleCOM independent off a BBS program, see +** EXAM2.PAS +** +** version: 1.01 +** Created: 08-Apr-1999 +** +** EleBBS install lines: +** +** DOS install line: EXAMPLE.EXE -H*P +** Win32 install line: EXAMPLE.EXE -H*W +** Win32 (telnet) install line: EXAMPLE.EXE -H*W -XT +** OS/2 install line: EXAMPLE.EXE -H*W +** OS/2 (telnet) install line: EXAMPLE.EXE -H*W -XT +** +*) + +{.DEFINE FOSSIL} +{.DEFINE OS2COM} +{$DEFINE W32COM} + +{$IFNDEF FOSSIL} + {$IFNDEF OS2COM} + {$IFNDEF W32COM} + You need to define one of these.. + {$ENDIF} + {$ENDIF} +{$ENDIF} + +uses Combase, + {$IFDEF FOSSIL} + Fos_Com + {$ENDIF} + + {$IFDEF OS2COM} + Os2Com, + Telnet + {$ENDIF} + + {$IFDEF W32COM} + W32SNGL, + Telnet + {$ENDIF} ; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +var ComObj : PCommObj; + IsTelnet : Boolean; + ComHandle : Longint; + ReadCH : Char; + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Int_ComReadProc(var TempPtr: Pointer); +begin + {$IFDEF WIN32} + Case IsTelnet of + FALSE : PWin32Obj(ComObj)^.Com_DataProc(TempPtr); + TRUE : PTelnetObj(ComObj)^.Com_ReadProc(TempPtr); + end; { case } + {$ENDIF} + + {$IFDEF OS2} + Case IsTelnet of + FALSE : POs2Obj(ComObj)^.Com_ReadProc(TempPtr); + TRUE : PTelnetObj(ComObj)^.Com_ReadProc(TempPtr); + end; { case } + {$ENDIF} +end; { proc. Int_ComReadProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure Int_ComWriteProc(var TempPtr: Pointer); +begin + {$IFDEF WIN32} + Case IsTelnet of + FALSE : PWin32Obj(ComObj)^.Com_DataProc(TempPtr); + TRUE : PTelnetObj(ComObj)^.Com_WriteProc(TempPtr); + end; { case } + {$ENDIF} + + {$IFDEF OS2} + Case IsTelnet of + FALSE : POs2Obj(ComObj)^.Com_WriteProc(TempPtr); + TRUE : PTelnetObj(ComObj)^.Com_WriteProc(TempPtr); + end; { case } + {$ENDIF} +end; { proc. Int_ComWriteProc } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +procedure ParseCommandLine; +var Counter: Longint; + TempStr: String; + {$IFDEF MSDOS} + Code : Integer; + {$ELSE} + Code : Longint; + {$ENDIF} +begin + for Counter := 01 to ParamCount do + begin + TempStr := ParamStr(Counter); + + if TempStr[1] in ['/', '-'] then + Case UpCase(TempStr[2]) of + 'H' : begin + + TempStr := Copy(TempStr, 3, Length(TempStr) - 2); + Val(TempStr, ComHandle, Code); + + + end; { 'H' } + 'X' : begin + + if UpCase(TempStr[3]) = 'T' then { XT } + IsTelnet := true; + + end; { 'X' } + end; { case } + + end; { for } +end; { proc. ParseCommandLine } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +Function FStr (N : LongInt) : String; { Convert integer to string } +var Temp: String; +begin + Str(n,temp); + FStr:=Temp; +end; { func. FStr } + +(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*) + +begin + IsTelnet := false; + ParseCommandLine; + + {$IFDEF W32COM} + if IsTelnet then ComObj := New(PTelnetObj, Init) + else ComObj := New(PWin32Obj, Init); + {$ENDIF} + + {$IFDEF FOSSIL} + ComObj := New(PFossilObj, Init); + {$ENDIF} + + {$IFDEF OS2COM} + if IsTelnet then ComObj := New(PTelnetObj, Init) + else ComObj := New(POs2Obj, Init); + {$ENDIF} + + {$IFDEF WIN32} + ComObj^.Com_SetDataProc(@Int_ComReadProc, @Int_ComWriteProc); + {$ENDIF} + + {$IFDEF OS2} + ComObj^.Com_SetDataProc(@Int_ComReadProc, @Int_ComWriteProc); + {$ENDIF} + + ComObj^.DontClose := true; { We use an inherited handle, never close it! } + ComObj^.Com_OpenQuick(ComHandle); { Open the comport using the handle } + ComObj^.Com_SendString('Hello there!' + #13#10); + ComObj^.Com_SendString('We are using handle #' + FStr(ComHandle) + #13#10); + + + repeat + ReadCH := ComObj^.Com_GetChar; + + if ReadCH <> #13 then + Writeln('Other..'); + until (ReadCH = #13) OR (NOT ComObj^.Com_Carrier); + + Dispose(ComObj, Done); { Dispose the communications object } +end. diff --git a/SOURCE/EMAIL.PAS b/SOURCE/EMAIL.PAS new file mode 100644 index 0000000..0d835ec --- /dev/null +++ b/SOURCE/EMAIL.PAS @@ -0,0 +1,1109 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT EMail; + +INTERFACE + +USES + Common; + +PROCEDURE SSMail(MenuOption: Str50); +PROCEDURE SMail(MassMail: Boolean); +PROCEDURE SEMail(UNum: Integer; ReplyHeader: MHeaderRec); +PROCEDURE AutoReply(ReplyHeader: MHeaderRec); +PROCEDURE ReadMail; +PROCEDURE ShowEmail; + +IMPLEMENTATION + +USES + Dos, + Common5, + File6, + Mail0, + Mail1, + Mail3, + SysOp2G, + SysOp3, + ShortMsg, + TimeFunc, + NodeList, + MiscUser; + +PROCEDURE SSMail(MenuOption: Str50); +VAR + MHeader: MHeaderRec; +BEGIN + InResponseTo := ''; + IF (Pos(';',MenuOption) = 0) AND (MenuOption <> '') THEN + InResponseTo := #1'FeedBack' + ELSE IF (MenuOption <> '') THEN + IF (MenuOption[Pos(';', MenuOption) + 1] = '\') THEN + InResponseTo := '\'+#1+Copy(MenuOption,(Pos(';',MenuOption) + 2),255) + ELSE + InResponseTo := #1+Copy(MenuOption,(Pos(';',MenuOption) + 1),255); + IF (StrToInt(MenuOption) < 1) THEN + SMail(FALSE) + ELSE + BEGIN + MHeader.Status := []; + SEMail(StrToInt(MenuOption),MHeader); + END; +END; + +PROCEDURE SMail(MassMail: Boolean); +VAR + MaxMailListArray: ARRAY [1..255] OF Integer; + User: UserRecordType; + MHeader: MHeaderRec; + SysOpName: STRING[36]; + MassACS: ACString; + Cmd: Char; + Counter, + NumMassMailList: Byte; + UNum: Integer; + SaveEmailSent, + Fee: Word; + EmailOK: Boolean; + + PROCEDURE CheckItOut(VAR UNum1: Integer; ShowIt: Boolean); + VAR + User1: UserRecordType; + ForUsrUNum, + SaveUNum1, + UNum2: Integer; + BEGIN + SaveUnum1 := UNum1; + IF ((UNum1 < 1) OR (UNum1 > (MaxUsers - 1))) THEN + BEGIN + UNum1 := 0; + Exit; + END; + LoadURec(User,UNum1); + IF (User.Waiting >= General.MaxWaiting) OR (NoMail IN User.Flags) AND (NOT CoSysOp) THEN + BEGIN + UNum1 := 0; + { Print(FString.CantEmail); } + lRGLngStr(46,FALSE); + Exit; + END; + ForUsrUNum := User.ForUsr; + IF (ForUsrUNum < 1) OR (ForUsrUNum > (MaxUsers - 1)) THEN + ForUsrUNum := 0; + IF (ForUsrUNum <> 0) THEN + BEGIN + LoadURec(User1,ForUsrUNum); + IF (ShowIt) THEN + Print('[> '+Caps(User.Name)+' #'+IntToStr(UNum1)+': message forwarded to '+Caps(User1.Name)+'.'); + UNum1 := ForUsrUNum; + END; + IF (ShowIt) THEN + FOR UNum2 := 1 TO NumMassMailList DO + IF (MaxMailListArray[UNum2] = UNum1) THEN + BEGIN + IF (ShowIt) THEN + Print('[> '+Caps(User.Name)+' #'+IntToStr(UNum1)+': Can''t send more than once.'); + UNum1 := 0; + Exit; + END; + IF (SaveUNum1 <> UNum1) THEN + IF ((SaveUNum1 >= 1) AND (SaveUNum1 <= (MaxUsers - 1))) THEN + LoadURec(User,SaveUNum1); + END; + + PROCEDURE SendIt(UNum1: Integer); + BEGIN + CheckItOut(UNum1,FALSE); + IF (UNum1 = 0) OR (UNum1 = UserNum) THEN + Exit; + IF ((UNum1 >= 1) AND (UNum1 <= (MaxUsers - 1))) THEN + BEGIN + LoadURec(User,UNum1); + IF (UNum1 = 1) THEN + BEGIN + Inc(ThisUser.FeedBack); + + IF (FeedBackPostsToday < 255) THEN + Inc(FeedBackPostsToday); + + END + ELSE + BEGIN + Inc(ThisUser.EmailSent); + AdjustBalance(General.CreditEmail); + + IF (PrivatePostsToday < 255) THEN + Inc(PrivatePostsToday); + + END; + Inc(User.Waiting); + SaveURec(User,UNum1); + END; + WITH MHeader.MTO DO + BEGIN + UserNum := UNum1; + A1S := AllCaps(User.Name); + Real := AllCaps(User.RealName); + Name := AllCaps(User.Name); + END; + SaveHeader((HiMsg + 1),MHeader); + END; + + PROCEDURE DoIt(Cmd1: Char); + VAR + UNum1: Integer; + BEGIN + InitMsgArea(-1); + FillChar(MHeader,SizeOf(MHeader),0); + MHeader.MTO.A1S := 'Mass private message'; + MHeader.MTO.Real := MHeader.MTO.A1S; + IF (NOT InputMessage(FALSE,TRUE,'',MHeader,'',78,500)) THEN + Exit; + CASE Cmd1 OF + '1' : BEGIN + { Print(FString.MassEmail); } + lRGLngStr(48,FALSE); + SysOpLog('Mass-private message sent to: (by ACS "'+MassACS+'")'); + FOR UNum1 := 1 TO (MaxUsers - 1) DO + BEGIN + LoadURec(User,UNum1); + IF (AACS1(User,UNum1,MassACS)) AND (UNum1 <> UserNum) AND (NOT (Deleted IN User.SFlags)) + AND (NOT (LockedOut IN User.SFlags)) THEN + BEGIN + SendIt(UNum1); + SysOpLog(' '+Caps(User.Name)); + Print(' '+Caps(User.Name)); + END; + END; + END; + '2' : BEGIN + { Print(FString.MassEmailAll); } + lRGLngStr(49,FALSE); + SysOpLog('Mass-private message sent to ALL USERS.'); + FOR UNum1 := 1 TO (MaxUsers - 1) DO + BEGIN + LoadURec(User,UNum1); + IF (UNum1 <> UserNum) AND (NOT (Deleted IN User.SFlags)) + AND (NOT (LockedOut IN User.SFlags)) THEN + SendIt(UNum1); + END; + END; + '3' : BEGIN + { Print(FString.MassEmail); } + lRGLngStr(48,FALSE); + SysOpLog('Mass-private message sent to:'); + FOR UNum1 := 1 TO NumMassMailList DO + BEGIN + SendIt(MaxMailListArray[UNum1]); + SysOpLog(' '+Caps(User.Name)); + Print(' '+Caps(User.Name)); + END; + END; + END; + END; + +BEGIN + EmailOK := TRUE; + + IF ((REmail IN ThisUser.Flags) OR (NOT AACS(General.NormPrivPost))) AND (NOT CoSysOp) THEN + BEGIN + NL; + Print('^7Your access privledges do not include sending private messages!^1'); + EmailOk := FALSE; + END + ELSE IF ((PrivatePostsToday >= General.MaxPrivPost) AND (NOT CoSysOp)) THEN + BEGIN + NL; + Print('^7You have already sent the maximum private messages allowed per day!^1'); + EmailOk := FALSE; + END + ELSE IF (AccountBalance < General.CreditEmail) AND (General.CreditEmail > 0) AND (NOT (FNoCredits IN ThisUser.Flags)) THEN + BEGIN + NL; + Print('^7Insufficient account balance to send private messages!^1'); + EmailOk := FALSE; + END; + + IF (NOT EmailOk) THEN + BEGIN + IF (InWFCMenu) THEN + PauseScr(FALSE); + Exit; + END; + + IF (NOT MassMail) THEN + BEGIN + IF (AACS(General.NetMailACS)) AND PYNQ(lRGLngStr(51,TRUE){FString.IsNetMail},0,FALSE) THEN + BEGIN + + PrintF('NETMHELP'); + + SysOpName := ''; + + WITH MHeader.From DO + GetNetAddress(SysOpName,Zone,Net,Node,Point,Fee,FALSE); + + IF (SysOpName = '') THEN + Exit; + + MHeader.From.Name := SysOpName; + + MHeader.Status := [NetMail]; + + SaveEmailSent := ThisUser.EmailSent; + + SEMail(0,MHeader); + + IF (ThisUser.EmailSent > SaveEmailSent) THEN + Inc(ThisUser.Debit,Fee); + + END + ELSE + BEGIN + + { Print(FString.SendEMail); } + lRGLngStr(47,FALSE); + NL; + Print('Enter User Number, Name, or Partial Search String.'); + Prt(': '); + lFindUserWS(UNum); + IF (UNum < 1) THEN + BEGIN + NL; + PauseScr(FALSE); + END + ELSE + BEGIN + MHeader.Status := []; + SEMail(UNum,MHeader); + END; + END; + END + ELSE + BEGIN + InResponseTo := ''; + NumMassMailList := 0; + FillChar(MaxMailListArray,SizeOf(MaxMailListArray),0); + NL; + Print('Mass private message: Send message to multiple users.'); + IF (NOT CoSysOp) THEN + Cmd := '3' + ELSE + BEGIN + NL; + Print('(1) Send to users with a certain ACS.'); + Print('(2) Send to all system users.'); + Print('(3) Send private messages to a list of users.'); + NL; + Prt('Your choice [^51^4-^53^4,^5Q^4=^5Quit^4]: '); + OneK(Cmd,'Q123',TRUE,TRUE); + END; + CASE Cmd OF + '1' : BEGIN + NL; + Prt('Enter ACS: '); + MPL((SizeOf(ACString) - 1)); + InputL(MassACS,(SizeOf(ACString) - 1)); + IF (MassACS <> '') THEN + BEGIN + NL; + Print('Users marked by ACS "'+MassACS+'":'); + Abort := FALSE; + Next := FALSE; + Reset(UserFile); + UNum := 1; + WHILE (UNum <= (MaxUsers - 1)) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + LoadURec(User,UNum); + IF (AACS1(User,UNum,MassACS)) AND (UNum <> UserNum) AND (NOT (Deleted IN User.SFlags)) + AND (NOT (LockedOut IN User.SFlags)) THEN + BEGIN + PrintACR(' '+Caps(User.Name)); + Inc(NumMassMailList); + END; + Inc(UNum); + WKey; + END; + Close(UserFile); + END; + END; + '2' : BEGIN + NL; + Print('All users marked for mass-private messages.'); + Abort := FALSE; + Next := FALSE; + Reset(UserFile); + UNum := 1; + WHILE (UNum <= (MaxUsers - 1)) AND (NOT Abort) AND (NOT HangUp) DO (* Was X - 1 *) + BEGIN + LoadURec(User,UNum); + IF (UNum <> UserNum) AND (NOT (Deleted IN User.SFlags)) AND (NOT (LockedOut IN User.SFlags)) THEN + BEGIN + PrintACR(' '+Caps(User.Name)); + Inc(NumMassMailList); + END; + Inc(UNum); + WKey; + END; + Close(UserFile); + END; + '3' : BEGIN + NL; + Print('You can send mass private messages to ' + +AOnOff(CoSysOp,'255',IntToStr(General.MaxMassMailList))+' user''s'); + Print('Enter a blank line to stop entering names.'); + UNum := 1; + WHILE (UNum <> 0) AND (NumMassMailList < General.MaxMassMailList) OR (UNum <> 0) AND (NumMassMailList < 255) + AND (CoSysOp) DO + BEGIN + NL; + Print('Enter User Number, Name, or Partial Search String.'); + Prt(': '); + lFindUserWS(UNum); + FOR Counter := 1 TO NumMassMailList DO + IF (MaxMailListArray[Counter] = UNum) THEN + UNum := 0; + IF (UNum = UserNum) THEN + UNum := 0; + IF (UNum > 0) THEN + BEGIN + LoadURec(User,UNum); + IF (LockedOut IN User.SFlags) OR (Deleted IN User.SFlags) THEN + UNum := 0 + ELSE + BEGIN + Inc(NumMassMailList); + MaxMailListArray[NumMassMailList] := UNum; + END; + END; + END; + IF (NumMassMailList > 0) THEN + BEGIN + NL; + Print('Users marked:'); + Abort := FALSE; + Next := FALSE; + Reset(UserFile); + UNum := 1; + WHILE (UNum <= NumMassMailList) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + LoadURec(User,MaxMailListArray[UNum]); + PrintACR(' '+Caps(User.Name)); + Inc(UNum); + WKey; + END; + Close(UserFile); + END; + END; + END; + IF (Cmd <> 'Q') THEN + BEGIN + NL; + Print('Total users listed: '+IntToStr(NumMassMailList)); + IF (NumMassMailList > 0) THEN + BEGIN + NL; + IF PYNQ('Send mass-private messages to the above list? ',0,FALSE) THEN + DoIt(Cmd); + END; + END; + END; + SaveURec(ThisUser,UserNum); +END; + +PROCEDURE SEMail(UNum: Integer; ReplyHeader: MHeaderRec); +VAR + User: UserRecordType; + MHeader: MHeaderRec; + Counter, + Counter1: Byte; + SaveReadMsgArea: Integer; + EmailOk: Boolean; +BEGIN + + IF (NOT (NetMail IN ReplyHeader.Status)) THEN + BEGIN + + IF (UNum < 1) OR (UNum > (MaxUsers - 1)) THEN + Exit; + + LoadURec(User,UNum); + + MHeader.Status := []; + + EmailOk := TRUE; + + IF ((REmail IN ThisUser.Flags) OR (NOT AACS(General.NormPrivPost))) AND (NOT CoSysOp) THEN + BEGIN + NL; + Print('^7Your access privledges do not include sending private messages!^1'); + EmailOk := FALSE; + END + ELSE IF (AccountBalance < General.CreditEmail) AND (General.CreditEmail > 0) AND (NOT (FNoCredits IN ThisUser.Flags)) THEN + BEGIN + NL; + Print('^7Insufficient account balance to send private messages!^1'); + EmailOk := FALSE; + END + ELSE IF (PrivatePostsToday >= General.MaxPrivPost) AND (NOT CoSysOp) THEN + BEGIN + NL; + Print('^7You have already sent the maximum private messages allowed per day!^1'); + EmailOk := FALSE; + END + ELSE IF ((UNum = 1) AND (FeedbackPostsToday >= General.MaxFBack) AND (NOT CoSysOp)) THEN + BEGIN + NL; + Print('^7You have already sent the maximum allowed feedback per day!^1'); + EmailOk := FALSE; + END + ELSE IF (User.Waiting >= General.MaxWaiting) AND (NOT CoSysOp) THEN + BEGIN + NL; + Print('^7The mailbox for this user is full!^1'); + EmailOk := FALSE; + END + ELSE IF (NoMail IN User.Flags) AND (NOT CoSysOp) THEN + BEGIN + NL; + Print('^7The mailbox for this user is closed!^1'); + EmailOk := FALSE; + END; + + IF (NOT EmailOk) THEN + BEGIN + IF (INWFCMenu) THEN + PauseScr(FALSE); + Exit; + END; + + IF ((User.ForUsr < 1) OR (User.ForUsr > (MaxUsers - 1))) THEN + User.ForUsr := 0; + + IF (User.ForUsr > 0) THEN + BEGIN + UNum := User.ForUsr; + LoadURec(User,UNum); + IF (CoSysOp) THEN + BEGIN + NL; + IF (NOT PYNQ('Send private message to '+Caps(User.Name)+'? ',0,FALSE)) THEN + Exit; + END; + END; + END + ELSE + BEGIN + + IF (NOT AACS(General.NetMailACS)) THEN + BEGIN + { Print(FString.NoNetMail); } + lRGLngStr(50,FALSE); + PauseScr(FALSE); + Exit; + END; + + User.Name := ReplyHeader.From.Name; + User.RealName := ReplyHeader.From.Name; + UNum := 0; + MHeader.Status := [NetMail]; + + END; + + SaveReadMsgArea := ReadMsgArea; + + InitMsgArea(-1); + + WITH MHeader.MTO DO + BEGIN + UserNum := UNum; + A1S := AllCaps(User.Name); + Real := AllCaps(User.RealName); + Name := AllCaps(User.Name); + END; + + IF (InputMessage(FALSE,TRUE,'',MHeader,'',78,500)) THEN + BEGIN + + IF (NetMail IN ReplyHeader.Status) THEN + BEGIN + Include(MHeader.Status,NetMail); + + MHeader.NetAttribute := General.NetAttribute * [Intransit,Private,Crash,KillSent,Hold,Local]; + + ChangeFlags(MHeader); + + Counter1 := 0; + Counter := 0; + WHILE (Counter <= 19) AND (Counter1 = 0) DO + BEGIN + IF (General.AKA[Counter].Zone = ReplyHeader.From.Zone) AND (General.AKA[Counter].Zone <> 0) THEN + Counter1 := Counter; + Inc(Counter); + END; + + IF (CoSysop) AND (General.AKA[Counter1].Zone <> ReplyHeader.From.Zone) THEN + BEGIN + FOR Counter := 0 TO 19 DO + IF (General.AKA[Counter].Net > 0) THEN + BEGIN + PrintACR(PadLeftInt((Counter + 1),2)+'. '+ + IntToStr(General.AKA[Counter].Zone)+':'+ + IntToStr(General.AKA[Counter].Net)+'/'+ + IntToStr(General.AKA[Counter].Node)+ + AOnOff((General.AKA[Counter].Point > 0),'.'+IntToStr(General.AKA[Counter].Point),'')); + END; + InputByteWOC('%LFUse which AKA',Counter,[NumbersOnly],1,20); + IF (Counter >= 1) OR (Counter <= 20) THEN + Counter1 := (Counter - 1); + END; + + WITH MHeader.From DO + BEGIN + Zone := General.AKA[Counter1].Zone; + Net := General.AKA[Counter1].Net; + Node := General.AKA[Counter1].Node; + Point := General.AKA[Counter1].Point; + END; + + WITH MHeader.MTO DO + BEGIN + Zone := ReplyHeader.From.Zone; + Net := ReplyHeader.From.Net; + Node := ReplyHeader.From.Node; + Point := ReplyHeader.From.Point; + END; + + END; + + IF (UNum = 1) THEN + BEGIN + Inc(ThisUser.FeedBack); + + IF (FeedBackPostsToday < 255) THEN + Inc(FeedbackPostsToday); + + END + ELSE + BEGIN + Inc(ThisUser.EmailSent); + AdjustBalance(General.CreditEmail); + + IF (PrivatePostsToday < 255) THEN + Inc(PrivatePostsToday); + END; + + IF (UNum >= 1) AND (UNum <= (MaxUsers - 1)) THEN + BEGIN + LoadURec(User,UNum); + Inc(User.Waiting); + SaveURec(User,UNum); + END; + + SaveHeader((HiMsg + 1),MHeader); + + IF (UserOn) THEN + SysOpLog(AOnOff((NetMail IN MHeader.Status),'Netmail','Private message')+' sent to ^5'+Caps(User.Name)+'.'); + + Print('^1'+AOnOff((NetMail IN MHeader.Status),'Netmail','Private message')+' sent to ^5'+Caps(User.Name)+'^1.'); + + Update_Screen; + END; + + InitMsgArea(SaveReadMsgArea); + + SaveURec(ThisUser,UserNum); +END; + +PROCEDURE AutoReply(ReplyHeader: MHeaderRec); +VAR + SysOpName: Str36; + Fee: Word; + TotPrivMsg: LongInt; +BEGIN + + IF AACS(General.NetMailACS) AND (NOT (NetMail IN ReplyHeader.Status)) AND + PYNQ(lRGLngStr(51,TRUE){FString.IsNetMail},0,FALSE) THEN + BEGIN + ReplyHeader.Status := [NetMail]; + LastAuthor := 0; + SysOpName := UseName(ReplyHeader.From.Anon, + AOnOff(MARealName IN MemMsgArea.MAFlags, + ReplyHeader.From.Real, + ReplyHeader.From.A1S)); + WITH ReplyHeader.From DO + GetNetAddress(SysOpName,Zone,Net,Node,Point,Fee,FALSE); + IF (SysOpName = '') THEN + Exit; + ReplyHeader.From.Name := SysOpName; + END; + + TotPrivMsg := (ThisUser.EmailSent + ThisUser.FeedBack); + + IF (LastAuthor = 0) AND (NOT (NetMail IN ReplyHeader.Status)) THEN + BEGIN + LastAuthor := SearchUser(ReplyHeader.From.A1S,TRUE); + IF (LastAuthor = 0) THEN + Print('^7That user does not have an account on this BBS!^1') + ELSE + SEMail(LastAuthor,ReplyHeader); + END + ELSE + BEGIN + SEMail(LastAuthor,ReplyHeader); + IF ((ThisUser.EmailSent + ThisUser.FeedBack) > TotPrivMsg) THEN + IF (NetMail IN ReplyHeader.Status) THEN + BEGIN + WITH ReplyHeader.From DO + GetNetAddress(SysOpName,Zone,Net,Node,Point,Fee,TRUE); + Inc(ThisUser.Debit,Fee) + END + ELSE + SendShortMessage(ReplyHeader.From.UserNum, + Caps(ThisUser.Name)+' replied to "'+AOnOff((ReplyHeader.FileAttached > 0), + StripName(ReplyHeader.Subject),ReplyHeader.Subject)+'" on '+DateStr+' '+TimeStr+'.'); + END; +END; + +PROCEDURE ReadMail; +TYPE + MessageArrayType = ARRAY [1..255] OF SmallWord; +VAR + MessageArray: MessageArrayType; + User: UserRecordType; + MHeader: MHeaderRec; + InputStr: AStr; + Cmd: Char; + SNum, + MNum: Byte; + UNum, + SaveReadMsgArea: Integer; + DeleteOk, + ReplyOk: Boolean; + + PROCEDURE RemoveCurrent(VAR SNum1,MNum1: Byte; VAR MessageArray1: MessageArrayType); + VAR + MsgNum: Byte; + BEGIN + Dec(MNum1); + FOR MsgNum := SNum1 TO MNum1 DO + MessageArray1[MsgNum] := MessageArray1[MsgNum + 1]; + IF (SNum1 > MNum1) THEN + SNum1 := MNum1; + END; + + PROCEDURE ReScan(VAR MNum1: Byte; VAR MessageArray1: MessageArrayType); + VAR + MsgNum: Word; + BEGIN + FillChar(MessageArray1,SizeOf(MessageArray1),0); + MNum1 := 0; + MsgNum := 1; + WHILE (MsgNum <= HiMsg) DO + BEGIN + LoadHeader(MsgNum,MHeader); + IF (MHeader.MTO.UserNum = UserNum) AND (NOT (MDeleted IN MHeader.Status)) THEN + BEGIN + Inc(MNum1); + MessageArray1[MNum1] := MsgNum; + END; + Inc(MsgNum); + END; + ThisUser.Waiting := 0; + SaveURec(ThisUser,UserNum); + END; + + PROCEDURE ListYourEmail(VAR SNum1: Byte; MNum1: Byte; MessageArray1: MessageArrayType); + VAR + DT: DateTime; + TempStr: AStr; + j, + NumDone: Byte; + BEGIN + IF (SNum1 < 1) OR (SNum1 > MNum1) THEN + SNum1 := 1; + Abort := FALSE; + Next := FALSE; + (* + CLS; + PrintACR('Ŀ'); + PrintACR(' Num  Date/Time  Sender  Subject '); + PrintACR(''); + *) + lRGLngStr(60,FALSE); + NumDone := 1; + WHILE (NumDone < (PageLength - 5)) AND (SNum1 >= 1) AND (SNum1 <= MNum) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + LoadHeader(MessageArray1[SNum1],MHeader); + TempStr := ''+PadRightInt(SNum1,5); + IF (MHeader.From.Anon IN [1,2]) THEN + TempStr := TempStr + ' [Unknown] ' + ELSE + BEGIN + PackToDate(DT,MHeader.Date); + j := DT.Hour; + IF (j > 12) THEN + Dec(j,12); + IF (j = 0) THEN + j := 12; + TempStr := TempStr + ' '+ZeroPad(IntToStr(DT.Day))+ + ' '+Copy(MonthString[DT.Month],1,3)+ + ' '+IntToStr(DT.Year)+ + ' '+ZeroPad(IntToStr(j))+ + ':'+ZeroPad(IntToStr(DT.Min))+ + AOnOff((DT.Hour >= 12),'p','a'); + END; + TempStr := TempStr + ' '+PadLeftStr(UseName(MHeader.From.Anon,MHeader.From.A1S),23); + IF (MHeader.FileAttached = 0) THEN + TempStr := TempStr + ' '+Copy(MHeader.Subject,1,25) + ELSE + TempStr := TempStr + ' '+StripName(Copy(MHeader.Subject,1,25)); + PrintACR(TempStr); + WKey; + Inc(SNum1); + Inc(NumDone); + END; + END; + +BEGIN + ReadingMail := TRUE; + SaveReadMsgArea := ReadMsgArea; + InitMsgArea(-1); + ReScan(MNum,MessageArray); + IF (MNum = 0) THEN + lRGLngStr(52,FALSE) { Print(FString.NoMailWaiting); } + ELSE + BEGIN + Abort := FALSE; + Next := FALSE; + SNum := 1; + Cmd := 'L'; + REPEAT + + REPEAT + IF (Cmd = 'L') THEN + ListYourEmail(SNum,MNum,MessageArray); + NL; + Prt('Select message (^51^4-^5'+IntToStr(MNum)+'^4) [^5?^4=^5First^4,^5^4=^5Next^4,^5Q^4=^5Quit^4)]: '); + MPL(Length(IntToStr(MNum))); + ScanInput(InputStr,'Q?'^M); + Cmd := InputStr[1]; + IF (Cmd = 'Q') THEN + SNum := 0 + ELSE + BEGIN + IF (Cmd IN ['-',^M]) THEN + Cmd := 'L' + ELSE IF (Cmd = '?') THEN + BEGIN + SNum := 1; + Cmd := 'L'; + END + ELSE + BEGIN + SNum := StrToInt(InputStr); + IF (SNum >= 1) AND (SNum <= MNum) THEN + Cmd := 'Q' + ELSE + BEGIN + NL; + Print('^7The range must be from 1 to '+IntToStr(MNum)+'^1'); + PauseScr(FALSE); + SNum := 1; + Cmd := 'L'; + END; + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); + + IF (SNum >= 1) AND (SNum <= MNum) AND (NOT HangUp) THEN + BEGIN + Cmd := #0; + REPEAT + LoadHeader(MessageArray[SNum],MHeader); + IF (Cmd <> '?') THEN + BEGIN + CLS; + ReadMsg(MessageArray[SNum],SNum,MNum); + END; + { Prt(FString.ReadingEmail); } + LOneK(lRGLngStr(13,TRUE),Cmd,'Q-ADFGLNRSUVXZM?'^M,TRUE,TRUE); + CASE Cmd OF + '-' : IF (SNum > 1) THEN + Dec(SNum) + ELSE + SNum := MNum; + 'A' : ; + 'D' : BEGIN + DeleteOk := TRUE; + IF (MHeader.FileAttached > 0) THEN + IF (CheckBatchDL(MHeader.Subject)) THEN + BEGIN + NL; + Print('If you delete this message, you will not be able to download'); + Print('the attached file currently in your batch queue.'); + NL; + IF NOT PYNQ('Continue with deletion? ',0,FALSE) THEN + DeleteOk := FALSE; + END; + IF (DeleteOk) THEN + BEGIN + Include(MHeader.Status,MDeleted); + SaveHeader(MessageArray[SNum],MHeader); + IF (MHeader.FileAttached = 1) THEN + Kill(MHeader.Subject); + + IF (NOT (NetMail IN Mheader.Status)) AND + (MHeader.From.UserNum >= 1) AND + (MHeader.From.UserNum >= (MaxUsers - 1)) THEN + SendShortMessage(MHeader.From.UserNum,Caps(ThisUser.Name)+' read "'+StripName(MHeader.Subject)+ + '" on '+DateStr+' '+TimeStr+'.'); + RemoveCurrent(SNum,MNum,MessageArray); + END; + END; + 'F' : ForwardMessage(MessageArray[SNum]); + 'G' : InputByteWOC('%LFGoto message',SNum,[NumbersOnly],1,MNum); + 'M' : IF (NOT MsgSysOp) THEN + Print('%LF^7You do not have the required access level for this option!^1%LF%PA') + ELSE + BEGIN + MoveMsg(MessageArray[SNum]); + LoadHeader(MessageArray[SNum],MHeader); + IF (MDeleted IN MHeader.Status) THEN + RemoveCurrent(SNum,MNum,MessageArray); + END; + 'R' : BEGIN + ReplyOk := TRUE; + IF (MHeader.From.Anon IN [1,2]) THEN + CASE MHeader.From.Anon OF + 1 : ReplyOk := AACS(General.AnonPrivRead); + 2 : ReplyOk := AACS(General.CSOP); + END; + IF (NOT ReplyOk) THEN + Print('%LF^7You can not reply to an anonymous message!^1%LF%PA') + ELSE + BEGIN + DumpQuote(MHeader); + AutoReply(MHeader); + DeleteOk := TRUE; + NL; + IF (NOT PYNQ('Delete original message? ',0,TRUE)) THEN + DeleteOk := FALSE; + IF (DeleteOk) AND (MHeader.FileAttached > 0) THEN + IF (CheckBatchDL(MHeader.Subject)) THEN + BEGIN + NL; + Print('If you delete this message, you will not be able to download the attached'); + Print('file currently in your batch queue.'); + NL; + IF NOT PYNQ('Continue with deletion? ',0,FALSE) THEN + DeleteOk := FALSE; + END; + IF (DeleteOk) THEN + BEGIN + Include(MHeader.Status,MDeleted); + IF (MHeader.FileAttached = 1) THEN + Kill(MHeader.Subject); + SaveHeader(MessageArray[SNum],MHeader); + RemoveCurrent(SNum,MNum,MessageArray); + END; + END; + END; + 'S' : IF (NOT CoSysOp) THEN + Print('%LF^7You do not have the required access level for this option!^1%LF%PA') + ELSE IF (LastAuthor < 1) OR (LastAuthor > (MaxUsers - 1)) THEN + Print('%LF^7The sender of this message does not have an account on this BBS!^1%LF%PA') + ELSE + BEGIN + LoadURec(User,LastAuthor); + ShowUserInfo(1,LastAuthor,User); + NL; + PauseScr(FALSE); + END; + 'U' : IF (NOT CoSysOp) THEN + Print('%LF^7You do not have the required access level for this option!^1%LF%PA') + ELSE IF (LastAuthor < 1) OR (LastAuthor > (MaxUsers - 1)) THEN + Print('%LF^7The sender of this message does not have an account on this BBS!^1%LF%PA') + ELSE IF (CheckPW) THEN + UserEditor(LastAuthor); + 'V' : IF (NOT CoSysOp) THEN + Print('%LF^7You do not have the required access level for this option!^1%LF%PA') + ELSE IF (LastAuthor < 1) OR (LastAuthor > (MaxUsers - 1)) THEN + Print('%LF^7The sender of this message does not have an account on this BBS!^1%LF%PA') + ELSE + BEGIN + LoadURec(User,LastAuthor); + AutoVal(User,LastAuthor); + END; + 'X' : IF (NOT CoSysOp) THEN + Print('%LF^7You do not have the required access level for this option!^1%LF%PA') + ELSE + ExtractMsgToFile(MessageArray[SNum],MHeader); + 'Z' : IF (NOT MsgSysOp) THEN + Print('%LF^7You do not have the required access level for this option!^1%LF%PA') + ELSE + BEGIN + DeleteOk := TRUE; + IF (MHeader.FileAttached > 0) THEN + IF CheckBatchDL(MHeader.Subject) THEN + BEGIN + NL; + Print('If you zap this message, you will not be able to download the attached'); + Print('file currently in your batch queue.'); + NL; + IF NOT PYNQ('Continue with zapping? ',0,FALSE) THEN + DeleteOk := FALSE; + END; + IF (DeleteOk) THEN + BEGIN + Include(MHeader.Status,MDeleted); + SaveHeader(MessageArray[SNum],MHeader); + IF (MHeader.FileAttached = 1) THEN + Kill(MHeader.Subject); + RemoveCurrent(SNum,MNum,MessageArray); + END; + END; + '?' : BEGIN + NL; + LCmds(17,3,'-Read previous','Again'); + LCmds(17,3,'Delete message','Forward messages'); + LCmds(17,3,'Goto message','List messages'); + LCmds(17,3,'Move message','Next message'); + LCmds(17,3,'Reply to message','Show user'); + LCmds(17,3,'User editor','Validate user'); + LCmds(17,3,'Xtract to file','Zap (Delete w/o reciept)'); + LCmds(17,3,'Quit',''); + END; + ELSE + IF (SNum < MNum) THEN + Inc(SNum) + ELSE + SNum := 1; + END; + IF (MNum = 0) THEN + Cmd := 'Q'; + UNTIL (Cmd IN ['L','Q']) OR (HangUp); + END; + IF (Cmd = 'Q') THEN + IF (RMsg IN ThisUser.Flags) AND (NOT CoSysOp) AND (MNum > 0) AND (NOT InWFCMenu) THEN + BEGIN + { Print(FString.SorryReply); } + lRGLngStr(53,FALSE); + SNum := 1; + Cmd := 'L'; + END; + UNTIL (Cmd = 'Q') OR (HangUp); + END; + Inc(ThisUser.Waiting,MNum); + SaveURec(ThisUser,UserNum); + LoadMsgArea(SaveReadMsgArea); + ReadingMail := FALSE; +END; + +PROCEDURE ShowEmail; +VAR + User: UserRecordType; + MHeader: MHeaderRec; + Cmd: Char; + SaveReadMsgArea: Integer; + MsgNum, + PreviousMsgNum, + MaxMsgs: Word; + AnyFound: Boolean; +BEGIN + ReadingMail := TRUE; + SaveReadMsgArea := ReadMsgArea; + InitMsgArea(-1); + Abort := FALSE; + Next := FALSE; + AnyFound := FALSE; + Cmd := #0; + MaxMsgs := HiMsg; + MsgNum := 1; + WHILE ((MsgNum <= MaxMsgs) AND (Cmd <> 'Q') AND (NOT HangUp)) DO + BEGIN + LoadHeader(MsgNum,MHeader); + IF (MHeader.From.UserNum <> UserNum) THEN + Inc(MsgNum) + ELSE + BEGIN + AnyFound := TRUE; + IF (Cmd <> '?') THEN + BEGIN + CLS; + ReadMsg(MsgNum,MsgNum,MaxMsgs); + END; + NL; + Prt('Private messages sent [^5?^4=^5Help^4]: '); + IF (CoSysOp) THEN + OneK(Cmd,'Q-ADENX?'^M,TRUE,TRUE) + ELSE + OneK(Cmd,'Q-ADEN?'^M,TRUE,TRUE); + CASE Cmd OF + '-' : BEGIN + PreviousMsgNum := (MsgNum - 1); + WHILE (PreviousMsgNum >= 1) AND (PreviousMsgNum <> MsgNum) DO + BEGIN + LoadHeader(PreviousMsgNum,MHeader); + IF (MHeader.From.UserNum <> UserNum) THEN + Dec(PreviousMsgNum) + ELSE + MsgNum := PreviousMsgNum; + END; + END; + 'A' : ; + 'D' : IF (NOT (MDeleted IN MHeader.Status)) THEN + BEGIN + Include(MHeader.Status,MDeleted); + SaveHeader(MsgNum,MHeader); + LoadURec(User,MHeader.MTO.UserNum); + IF (User.Waiting > 0) THEN + Dec(User.Waiting); + SaveURec(User,MHeader.MTO.UserNum); + Print('%LFPrivate message deleted.'); + SysOpLog('* Deleted private message to '+Caps(MHeader.From.A1S)); + END + ELSE + BEGIN + Exclude(MHeader.Status,MDeleted); + SaveHeader(MsgNum,MHeader); + LoadURec(User,MHeader.MTO.UserNum); + IF (User.Waiting < 255) THEN + Inc(User.Waiting); + SaveURec(User,MHeader.MTO.UserNum); + Print('%LFPrivate message undeleted.'); + SysOpLog('* Undeleted private message to '+Caps(MHeader.From.A1S)); + END; + 'E' : EditMessageText(MsgNum); + 'X' : IF (NOT CoSysOp) THEN + Print('%LF^7You do not have the required access level for this option!^1%LF%PA') + ELSE + ExtractMsgToFile(MsgNum,MHeader); + '?' : BEGIN + Print('%LF<^3CR^1>Next message'); + LCmds(20,3,'Again','Edit message'); + LCmds(20,3,'Delete message','-Previous message'); + IF (CoSysOp) THEN + LCmds(20,3,'Xtract to file','Quit') + ELSE + LCmds(20,3,'Quit',''); + END; + ELSE + Inc(MsgNum); + END; + END; + END; + IF (NOT AnyFound) THEN + BEGIN + NL; + Print('^3No private messages sent.'); + END; + LoadMsgArea(SaveReadMsgArea); + ReadingMail := FALSE; +END; + +END. diff --git a/SOURCE/EVENTS.PAS b/SOURCE/EVENTS.PAS new file mode 100644 index 0000000..24ed03e --- /dev/null +++ b/SOURCE/EVENTS.PAS @@ -0,0 +1,258 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Events; + +INTERFACE + +FUNCTION InTime(Tim,Tim1,Tim2: LongInt): Boolean; +FUNCTION CheckPreEventTime(EventNum: Integer; T: LongInt): Boolean; +FUNCTION CheckEventTime(EventNum: Integer; T: LongInt): Boolean; +FUNCTION CheckEvents(T: LongInt): Integer; +FUNCTION SysOpAvailable: Boolean; + +IMPLEMENTATION + +USES + Dos, + Common, + TimeFunc +{$IFDEF WIN32} + ,Windows +{$ENDIF} + ; + +FUNCTION InTime(Tim,Tim1,Tim2: LongInt): Boolean; +BEGIN + InTime := TRUE; + WHILE (Tim >= 86400) DO + Dec(Tim,86400); + IF (Tim1 <> Tim2) THEN + IF (Tim2 > Tim1) THEN + IF (Tim <= (Tim1 * 60)) OR (Tim >= (Tim2 * 60)) THEN + InTime := FALSE + ELSE + ELSE + IF (Tim <= (Tim1 * 60)) AND (Tim >= (Tim2 * 60)) THEN + InTime := FALSE; +END; + +(* +function checkeventday(i:integer; t:longint):boolean; +var + year,month,day,dayofweek:word; + e:integer; +begin + e := 0; + checkeventday := FALSE; + if not events[i]^.active then + exit; + with events[i]^ do + begin + getdate(year,month,day,dayofweek); + if (timer + t >= 86400.0) then + begin + inc(dayofweek); + e := 1; + if (dayofweek > 6) then + dayofweek := 0; + end; + if (monthly) then + begin + if (value(copy(date,4,2)) + e = execdays) then + checkeventday := TRUE; + end + else + begin + e := 1 shl (dayofweek + 1); + if (execdays and e = e) then + checkeventday:=TRUE; + end; + end; +end; +*) + +FUNCTION lCheckEventDay(EventNum: Integer; T: LongInt): Boolean; +VAR + DayOfWeek, + Day: Byte; +BEGIN + + lCheckEventDay := FALSE; + WITH MemEventArray[EventNum]^ DO + BEGIN + IF (NOT (EventIsActive IN EFlags)) THEN + Exit; + Day := 0; + GetDayOfWeek(DayOfWeek); + IF ((Timer + T) >= 86400) THEN + BEGIN + Inc(DayOfWeek); + IF (DayOfWeek > 6) THEN + DayOfWeek := 0; + Day := 1; + END; + IF (EventIsMonthly IN EFlags) THEN + BEGIN + IF ((StrToInt(Copy(DateStr,4,2)) + Day) = MemEventArray[EventNum]^.EventDayOfMonth) THEN + lCheckEventDay := TRUE; + END + ELSE IF (DayOfWeek IN EventDays) THEN + lCheckEventDay := TRUE; + END; +END; + +(* +function checkpreeventtime(i:integer; t:longint):boolean; +begin + with events[i]^ do + if (offhooktime = 0) or + (durationorlastday=daynum(date)) or + ((Enode > 0) and (Enode <> node)) or + (not events[i]^.active) or not + (checkeventday(i,t)) then + checkpreeventtime:=FALSE + else + checkpreeventtime:=intime(timer+t,exectime-offhooktime,exectime); +end; +*) + +FUNCTION CheckPreEventTime(EventNum: Integer; T: LongInt): Boolean; + +BEGIN + WITH MemEventArray[EventNum]^ DO + IF (NOT (EventIsActive IN EFlags)) OR + (EventPreTime = 0) OR + (PD2Date(EventLastDate) = DateStr) OR + ((EventNode > 0) AND (EventNode <> ThisNode)) OR + NOT (lCheckEventDay(EventNum,T)) THEN + CheckPreEventTime := FALSE + ELSE + CheckPreEventTime := InTime((Timer + T),(EventStartTime - EventPreTime),EventStartTime); + (* + checkpreeventtime := intime(timer + t,exectime-offhooktime,exectime); + *) +END; + +(* +function checkeventtime(i:integer; t:longint):boolean; +begin + with events[i]^ do + if (durationorlastday=daynum(date)) or + ((Enode > 0) and (Enode <> node)) or + (not events[i]^.active) or not + (checkeventday(i,t)) then + checkeventtime:=FALSE + else + if (etype in ['A','C']) then + checkeventtime:=intime(timer+t,exectime,exectime+durationorlastday) + else + if (missed) then + checkeventtime := (((timer + t) div 60) > exectime) + else + checkeventtime := (((timer + t) div 60) = exectime); +end; +*) + +FUNCTION CheckEventTime(EventNum: Integer; T: LongInt): Boolean; +BEGIN + WITH MemEventArray[EventNum]^ DO + IF (PD2Date(EventLastDate) = DateStr) OR + ((EventNode > 0) AND (EventNode <> ThisNode)) OR + (NOT (EventIsActive IN EFlags)) OR + NOT (lCheckEventDay(EventNum,T)) THEN + CheckEventTime := FALSE + ELSE + IF (EventIsLogon IN EFlags) OR (EventIsChat IN EFlags) THEN + CheckEventTime := InTime((Timer + T),EventStartTime,(EventStartTime + EventFinishTime)) + (* + checkeventtime := intime(timer + t,exectime,exectime+durationorlastday) + *) + ELSE + IF (EventIsMissed IN EFlags) THEN + CheckEventTime := (((Timer + T) DIV 60) > EventStartTime) + ELSE + CheckEventTime := (((Timer + T) DIV 60) = EventStartTime); +END; + +(* +function checkevents(t:longint):integer; +var i:integer; +begin + for i := 1 to numevents do + with events[i]^ do + if (active) and ((Enode = 0) or (Enode = node)) then + if (checkeventday(i,t)) then begin + if (softevent) and (not inwfcmenu) then + checkevents:=0 + else + checkevents:=i; + if (checkpreeventtime(i,t)) or (checkeventtime(i,t)) then begin + if (etype in ['D','E','P']) then exit; + if ((etype='A') and (not aacs(execdata)) and (useron)) then exit; + end; + end; + checkevents:=0; +end; +*) + +FUNCTION CheckEvents(T: LongInt): Integer; +VAR + EventNum: Integer; +BEGIN + FOR EventNum := 1 TO NumEvents DO + WITH MemEventArray[EventNum]^ DO + IF (EventIsActive IN EFlags) AND ((EventNode = 0) OR (EventNode = ThisNode)) THEN + IF (lCheckEventDay(EventNum,T)) THEN + BEGIN + IF (EventIsSoft IN EFlags) AND (NOT InWFCMenu) THEN + CheckEvents := 0 + ELSE + CheckEvents := EventNum; + IF (CheckPreEventTime(EventNum,T)) OR (CheckEventTime(EventNum,T)) THEN + BEGIN + IF (EventIsExternal IN EFlags) THEN + IF (EventIsShell IN EFlags) OR + (EventIsErrorLevel IN EFlags) OR + (EventIsPackMsgAreas IN EFlags) OR + (EventIsSortFiles IN EFlags) OR + (EventIsFilesBBS IN EFlags) THEN + Exit; + IF ((EventIsLogon IN EFlags) AND (NOT AACS(EventACS)) AND (UserOn)) THEN + Exit; + END; + END; + CheckEvents := 0; +END; + +FUNCTION SysOpAvailable: Boolean; +VAR +{$IFDEF MSDOS} + A: Byte ABSOLUTE $0000:$0417; +{$ENDIF} + EventNum: Integer; + ChatOk: Boolean; +BEGIN +{$IFDEF MSDOS} + ChatOk := ((A AND 16) = 0); +{$ENDIF} +{$IFDEF WIN32} + // Availability is togged with scroll lock key + ChatOk := (GetKeyState($91) and $ffff) <> 0; +{$ENDIF} + + IF (RChat IN ThisUser.Flags) THEN + ChatOk := FALSE; + + FOR EventNum := 1 TO NumEvents DO + WITH MemEventArray[EventNum]^ DO + IF (EventIsActive IN EFlags) AND (EventIsChat IN EFlags) AND (CheckEventTime(EventNum,0)) THEN + ChatOk := TRUE; + + SysOpAvailable := ChatOk; +END; + +END. diff --git a/SOURCE/EXECBAT.PAS b/SOURCE/EXECBAT.PAS new file mode 100644 index 0000000..fa586db --- /dev/null +++ b/SOURCE/EXECBAT.PAS @@ -0,0 +1,229 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT ExecBat; + +INTERFACE + +USES + Common, + MyIO; + +PROCEDURE ExecWindow(VAR Ok: Boolean; + CONST Dir, + BatLine: AStr; + OkLevel: Integer; + VAR RCode: Integer); +PROCEDURE ExecBatch(VAR Ok: Boolean; + Dir, + BatLine: AStr; + OkLevel: Integer; + VAR RCode: Integer; + Windowed: Boolean); +PROCEDURE Shel(CONST s: AStr); +PROCEDURE Shel2(x: Boolean); + +IMPLEMENTATION + +USES + Crt, + Dos; + +VAR + CurInt21: Pointer; + WindPos, + WindLo, + WindHi: Word; + WindAttr: Byte; + + SaveX, + SaveY: Byte; + SavCurWind: Integer; + +{$IFDEF MSDOS} +{$L EXECWIN} + +PROCEDURE SetCsInts; EXTERNAL; +PROCEDURE NewInt21; EXTERNAL; +{$ENDIF} + +PROCEDURE ExecWindow(VAR Ok: Boolean; + CONST Dir, + BatLine: AStr; + OkLevel: Integer; + VAR RCode: Integer); +VAR + SaveWindowOn: Boolean; + SaveCurWindow: Byte; + s: AStr; + +{-Exec a program in a Window} + +{$IFDEF Ver70} + VAR + TmpInt21 : Pointer; +{$ENDIF} + +BEGIN + SaveCurWindow := General.CurWindow; + SaveWindowOn := General.WindowOn; + General.WindowOn := TRUE; + + SaveX := WhereX; + SaveY := WhereY; + SaveScreen(Wind); + + ClrScr; + + lStatus_Screen(1,'',FALSE,s); + + {Store global copies of Window data for interrupt handler} + WindAttr := 7; + WindLo := WindMin; + WindHi := WindMax; + +{$IFDEF MSDOS} + {Assure cursor is in Window} + INLINE + ( + {;get cursor pos} + $B4/$03/ { mov ah,3} + $30/$FF/ { xor bh,bh} + $CD/$10/ { int $10} + {;assure it's within Window} + $8B/$0E/>WindLo/ { mov cx,[>windlo]} + $38/$EE/ { cmp dh,ch ;row above minimum?} + $73/$02/ { jae okxlo ;jump IF so} + $88/$EE/ { mov dh,ch} + {okxlo:} + $38/$CA/ { cmp dl,cl ;col above minimum?} + $73/$02/ { jae okylo ;jump IF so} + $88/$CA/ { mov dl,cl} + {okylo:} + $8B/$0E/>WindHi/ { mov cx,[>windhi]} + $38/$EE/ { cmp dh,ch ;row below maximum?} + $76/$02/ { jbe okxhi ;jump IF so} + $88/$EE/ { mov dh,ch} + {okxhi:} + $38/$CA/ { cmp dl,cl ;col below maximum?} + $76/$02/ { jbe okyhi ;jump IF so} + $88/$CA/ { mov dl,cl} + {okyhi:} + $89/$16/>WindPos/ { mov [>windpos],dx ;save current position} + {;position cursor} + $B4/$02/ { mov ah,2} + $30/$FF/ { xor bh,bh} + $CD/$10); { int $10} + + {Take over interrupt} + GetIntVec($21,CurInt21); + SetCsInts; + SetIntVec($21,@NewInt21); +{$ENDIF} + + {$IFDEF Ver70} + {Prevent SwapVectors from undoing our int21 change} + TmpInt21 := SaveInt21; + SaveInt21 := @NewInt21; + {$ENDIF} + + {Exec the program} + ExecBatch(Ok,Dir,BatLine,OkLevel,RCode,TRUE); + + {$IFDEF Ver70} + SaveInt21 := TmpInt21; + {$ENDIF} + + Window(1,1,MaxDisplayCols,MaxDisplayRows); + RemoveWindow(Wind); + +{$IFDEF MSDOS} + {Restore interrupt} + SetIntVec($21,CurInt21); +{$ENDIF} + General.CurWindow := SaveCurWindow; + General.WindowOn := SaveWindowOn; + LastScreenSwap := (Timer - 5); + lStatus_Screen(General.CurWindow,'',FALSE,s); + + GoToXY(SaveX,SaveY); +END; + +PROCEDURE ExecBatch(VAR Ok: Boolean; { result } + Dir: AStr; { directory takes place in } + BatLine: AStr; { .BAT file line to execute } + OkLevel: Integer; { DOS errorlevel for success } + VAR RCode: Integer; { errorlevel returned } + Windowed: Boolean); { Windowed? } +VAR + BatchFile: Text; + SaveDir: AStr; + BName: STRING[20]; +BEGIN + BName := 'TEMP'+IntToStr(ThisNode)+'.BAT'; + GetDir(0,SaveDir); + Dir := BSlash(FExpand(Dir),FALSE); + Assign(BatchFile,BName); + ReWrite(BatchFile); + WriteLn(BatchFile,'@ECHO OFF'); + WriteLn(BatchFile,Chr(ExtractDriveNumber(Dir) + 64)+':'); + IF (Dir <> '') THEN + WriteLn(BatchFile,'CD '+Dir); + IF (NOT WantOut) THEN + BatLine := BatLine + ' > NUL'; + WriteLn(BatchFile,BatLine); + WriteLn(BatchFile,':DONE'); + WriteLn(BatchFile,Chr(ExtractDriveNumber(SaveDir) + 64)+':'); + WriteLn(BatchFile,'CD '+SaveDir); + WriteLn(BatchFile,'Exit'); + Close(BatchFile); + + IF (WantOut) AND (NOT Windowed) THEN + Shel(BatLine); + + IF (NOT WantOut) THEN + BName := BName + ' > NUL'; + + ShellDOS(FALSE,BName,RCode); + + Shel2(Windowed); + + ChDir(SaveDir); + Kill(BName); + IF (OkLevel <> -1) THEN + Ok := (RCode = OkLevel) + ELSE + Ok := TRUE; + LastError := IOResult; +END; + +PROCEDURE Shel(CONST s: AStr); +BEGIN + SavCurWind := General.CurWindow; + SaveX := WhereX; + SaveY := WhereY; + SetWindow(Wind,1,1,80,25,7,0,0); + ClrScr; + TextBackGround(1); + TextColor(15); + ClrEOL; + Write(s); + TextBackGround(0); + TextColor(7); + WriteLn; +END; + +PROCEDURE Shel2(x: Boolean); +BEGIN + ClrScr; + RemoveWindow(Wind); + IF (x) THEN + Exit; + GoToXY(SaveX,SaveY); + LastScreenSwap := (Timer - 5); +END; + +END. diff --git a/SOURCE/FILE0.PAS b/SOURCE/FILE0.PAS new file mode 100644 index 0000000..2487204 --- /dev/null +++ b/SOURCE/FILE0.PAS @@ -0,0 +1,609 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File0; + +INTERFACE + +USES + Common; + +FUNCTION CompFileArea(FArea,ArrayNum: Integer): Integer; +FUNCTION GetCPS(TotalBytes,TransferTime: LongInt): LongInt; +PROCEDURE CountDown; +FUNCTION Align(CONST FName: Str12): Str12; +FUNCTION BadDownloadPath: Boolean; +FUNCTION BadUploadPath: Boolean; +PROCEDURE DisplayFileInfo(VAR F: FileInfoRecordType; Editing: Boolean); +FUNCTION FileAreaAC(FArea: Integer): Boolean; +PROCEDURE ChangeFileArea(FArea: Integer); +PROCEDURE LoadFileArea(FArea: Integer); +FUNCTION GetDirPath(MemFileArea: FileAreaRecordType): ASTR; +PROCEDURE LoadNewScanFile(VAR NewScanFile: Boolean); +PROCEDURE SaveNewScanFile(NewScanFile: Boolean); +PROCEDURE InitFileArea(FArea: Integer); +FUNCTION Fit(CONST FileName1,FileName2: Str12): Boolean; +PROCEDURE GetFileName(VAR FileName: Str12); +FUNCTION ISUL(CONST s: AStr): Boolean; +FUNCTION IsWildCard(CONST s: AStr): Boolean; +PROCEDURE NRecNo(FileInfo: FileInfoRecordType; VAR RN: Integer); +PROCEDURE LRecNo(Fileinfo: FileInfoRecordType; VAR RN: Integer); +PROCEDURE RecNo(FileInfo: FileInfoRecordType; FileName: Str12; VAR RN: Integer); +PROCEDURE LoadVerbArray(F: FileInfoRecordType; VAR ExtArray: ExtendedDescriptionArray; VAR NumExtDesc: Byte); +PROCEDURE SaveVerbArray(VAR F: FileInfoRecordType; ExtArray: ExtendedDescriptionArray; NumExtDesc: Byte); + +IMPLEMENTATION + +USES + Dos, + File1, + ShortMsg, + TimeFunc +{$IFDEF WIN32} + ,Windows +{$ENDIF} + ; + +FUNCTION CompFileArea(FArea,ArrayNum: Integer): Integer; +VAR + FileCompArrayFile: FILE OF CompArrayType; + CompFileArray: CompArrayType; +BEGIN + Assign(FileCompArrayFile,TempDir+'FACT'+IntToStr(ThisNode)+'.DAT'); + Reset(FileCompArrayFile); + Seek(FileCompArrayFile,(FArea - 1)); + Read(FileCompArrayFile,CompFileArray); + Close(FileCompArrayFile); + CompFileArea := CompFileArray[ArrayNum]; +END; + +FUNCTION GetCPS(TotalBytes,TransferTime: LongInt): LongInt; +BEGIN + IF (TransferTime > 0) THEN + GetCPS := (TotalBytes DIV TransferTime) + ELSE + GetCPS := 0; +END; + +(* Done - 01/01/07 Lee Palmer *) +FUNCTION Align(CONST FName: Str12): Str12; +VAR + F: Str8; + E: Str3; + Counter, + Counter1: Byte; +BEGIN + Counter := Pos('.',FName); + IF (Counter = 0) THEN + BEGIN + F := FName; + E := ' '; + END + ELSE + BEGIN + F := Copy(FName,1,(Counter - 1)); + E := Copy(FName,(Counter + 1),3); + END; + F := PadLeftStr(F,8); + E := PadLeftStr(E,3); + Counter := Pos('*',F); + IF (Counter <> 0) THEN + FOR Counter1 := Counter TO 8 DO + F[Counter1] := '?'; + Counter := Pos('*',E); + IF (Counter <> 0) THEN + FOR Counter1 := Counter TO 3 DO + E[Counter1] := '?'; + Counter := Pos(' ',F); + IF (Counter <> 0) THEN + FOR Counter1 := Counter TO 8 DO + F[Counter1] := ' '; + Counter := Pos(' ',E); + IF (Counter <> 0) THEN + FOR Counter1 := Counter TO 3 DO + E[Counter1] := ' '; + Align := F+'.'+E; +END; + +FUNCTION BadDownloadPath: Boolean; +BEGIN + IF (BadDLPath) THEN + BEGIN + NL; + Print('^7File area #'+IntToStr(FileArea)+': Unable to perform command.'); + SysOpLog('^5Bad DL file path: "'+MemFileArea.DLPath+'".'); + Print('^5Please inform the SysOp.'); + SysOpLog('Invalid DL path (File Area #'+IntToStr(FileArea)+'): "'+MemFileArea.DLPath+'"'); + END; + BadDownloadPath := BadDLPath; +END; + +FUNCTION BadUploadPath: Boolean; +BEGIN + IF (BadULPath) THEN + BEGIN + NL; + Print('^7File area #'+IntToStr(FileArea)+': Unable to perform command.'); + SysOpLog('^5Bad UL file path: "'+MemFileArea.Ulpath+'".'); + Print('^5Please inform the SysOp.'); + SysOpLog('Invalid UL path (File Area #'+IntToStr(FileArea)+'): "'+MemFileArea.Ulpath+'"'); + END; + BadUploadPath := BadULPath; +END; + +FUNCTION FileAreaAC(FArea: Integer): Boolean; +BEGIN + FileAreaAC := FALSE; + IF (FArea < 1) OR (FArea > NumFileAreas) THEN + Exit; + LoadFileArea(FArea); + FileAreaAC := AACS(MemFileArea.ACS); +END; + +PROCEDURE ChangeFileArea(FArea: Integer); +VAR + PW: Str20; +BEGIN + IF (FArea < 1) OR (FArea > NumFileAreas) OR (NOT FileAreaAC(FArea)) THEN + Exit; + IF (MemFileArea.Password <> '') AND (NOT SortFilesOnly) THEN + BEGIN + NL; + Print('File area: ^5'+MemFileArea.AreaName+' #'+IntToStr(CompFileArea(FArea,0))+'^1'); + NL; + Prt('Password: '); + GetPassword(PW,20); + IF (PW <> MemFileArea.Password) THEN + BEGIN + NL; + Print('^7Incorrect password!^1'); + Exit; + END; + END; + FileArea := FArea; + ThisUser.LastFileArea := FileArea; +END; + +PROCEDURE LoadFileArea(FArea: Integer); +VAR + FO: Boolean; +BEGIN + IF (ReadFileArea = FArea) THEN + Exit; + IF (FArea < 1) THEN + Exit; + IF (FArea > NumFileAreas) THEN + BEGIN + MemFileArea := TempMemFileArea; + ReadFileArea := FArea; + Exit; + END; + FO := (FileRec(FileAreaFile).Mode <> FMClosed); + IF (NOT FO) THEN + BEGIN + Reset(FileAreaFile); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('FBASES.DAT/Open Error - '+IntToStr(LastError)+' (Procedure: LoadFileArea - '+IntToStr(FArea)+')'); + Exit; + END; + END; + Seek(FileAreaFile,(FArea - 1)); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('FBASES.DAT/Seek Error - '+IntToStr(LastError)+' (Procedure: LoadFileArea - '+IntToStr(FArea)+')'); + Exit; + END; + Read(FileAreaFile,MemFileArea); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('FBASES.DAT/Read Error - '+IntToStr(LastError)+' (Procedure: LoadFileArea - '+IntToStr(FArea)+')'); + Exit; + END + ELSE + ReadFileArea := FArea; + IF (NOT FO) THEN + BEGIN + Close(FileAreaFile); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('FBASES.DAT/Close Error - '+IntToStr(LastError)+' (Procedure: LoadFileArea - '+IntToStr(FArea)+')'); + Exit; + END; + END; + LastError := IOResult; +END; + +FUNCTION GetDirPath(MemFileArea: FileAreaRecordType): AStr; +BEGIN + IF (FADirDLPath IN MemFileArea.FAFlags) THEN + GetDirPath := MemFileArea.DLPath+MemFileArea.FileName + ELSE + GetDirPath := General.DataPath+MemFileArea.FileName; +END; + +PROCEDURE LoadNewScanFile(VAR NewScanFile: Boolean); +VAR + FileAreaScanFile: FILE OF Boolean; + Counter: Integer; +BEGIN + Assign(FileAreaScanFile,GetDirPath(MemFileArea)+'.SCN'); + Reset(FileAreaScanFile); + IF (IOResult = 2) THEN + ReWrite(FileAreaScanFile); + IF (UserNum > FileSize(FileAreaScanFile)) THEN + BEGIN + NewScanFile := TRUE; + Seek(FileAreaScanFile,FileSize(FileAreaScanFile)); + FOR Counter := FileSize(FileAreaScanFile) TO (UserNum - 1) DO + Write(FileAreaScanFile,NewScanFile); + END + ELSE + BEGIN + Seek(FileAreaScanFile,(UserNum - 1)); + Read(FileAreaScanFile,NewScanFile); + END; + Close(FileAreaScanFile); + LastError := IOResult; +END; + +PROCEDURE SaveNewScanFile(NewScanFile: Boolean); +VAR + FileAreaScanFile: FILE OF Boolean; +BEGIN + Assign(FileAreaScanFile,GetDirPath(MemFileArea)+'.SCN'); + Reset(FileAreaScanFile); + Seek(FileAreaScanFile,(UserNum - 1)); + Write(FileAreaScanFile,NewScanFile); + Close(FileAreaScanFile); + LastError := IOResult; +END; + +PROCEDURE InitFileArea(FArea: Integer); +BEGIN + LoadFileArea(FArea); + + IF ((Length(MemFileArea.DLPath) = 3) AND (MemFileArea.DLPath[2] = ':') AND (MemFileArea.DLPath[3] = '\')) THEN + BadDLPath := NOT ExistDrive(MemFileArea.DLPath[1]) + ELSE IF NOT (FACDRom IN MemFileArea.FAFlags) THEN + BadDLPath := NOT ExistDir(MemFileArea.DLPath) + ELSE + BadDLPath := FALSE; + + IF ((Length(MemFileArea.ULPath) = 3) AND (MemFileArea.ULPath[2] = ':') AND (MemFileArea.DLPath[3] = '\')) THEN + BadULPath := NOT ExistDrive(MemFileArea.ULPath[1]) + ELSE IF NOT (FACDRom IN MemFileArea.FAFlags) THEN + BadULPath := NOT ExistDir(MemFileArea.ULPath) + ELSE + BadULPath := FALSE; + + IF (NOT DirFileOpen1) THEN + IF (FileRec(FileInfoFile).Mode <> FMClosed) THEN + Close(FileInfoFile); + DirFileOpen1 := FALSE; + + Assign(FileInfoFile,GetDirPath(MemFileArea)+'.DIR'); + Reset(FileInfoFile); + IF (IOResult = 2) THEN + ReWrite(FileInfoFile); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Error opening file: '+GetDirPath(MemFileArea)+'.DIR'); + Exit; + END; + + IF (NOT ExtFileOpen1) THEN + IF (FileRec(ExtInfoFile).Mode <> FMClosed) THEN + Close(ExtInfoFile); + ExtFileOpen1 := FALSE; + + Assign(ExtInfoFile,GetDirPath(MemFileArea)+'.EXT'); + Reset(ExtInfoFile,1); + IF (IOResult = 2) THEN + ReWrite(ExtInfoFile,1); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Error opening file: '+GetDirPath(MemFileArea)+'.EXT'); + Exit; + END; + + LoadNewScanFile(NewScanFileArea); + + FileAreaNameDisplayed := FALSE; +END; + +PROCEDURE DisplayFileInfo(VAR F: FileInfoRecordType; Editing: Boolean); +VAR + TempStr: AStr; + Counter, + NumLine, + NumExtDesc: Byte; + + FUNCTION DisplayFIStr(FIFlags: FIFlagSet): AStr; + VAR + TempStr1: AStr; + BEGIN + TempStr1 := ''; + IF (FINotVal IN FIFlags) THEN + TempStr1 := TempStr1 + ' ^8'+''; + IF (FIIsRequest IN FIFlags) THEN + TempStr1 := TempStr1 + ' ^9'+'Ask (Request File)'; + IF (FIResumeLater IN FIFlags) THEN + TempStr1 := TempStr1 + ' ^7'+'Resume later'; + IF (FIHatched IN FIFlags) THEN + TempStr1 := TempStr1 + ' ^7'+'Hatched'; + DisplayFIStr := TempStr1; + END; + +BEGIN + Counter := 1; + WHILE (Counter <= 7) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + WITH F DO + BEGIN + IF (Editing) THEN + TempStr := IntToStr(Counter)+'. ' + ELSE + TempStr := ''; + CASE Counter OF + 1 : TempStr := TempStr + 'Filename : ^0'+SQOutSp(FileName); + 2 : IF (NOT General.FileCreditRatio) THEN + TempStr := TempStr + 'File size : ^2'+ConvertBytes(FileSize,FALSE) + ELSE + TempStr := TempStr + 'File size : ^2'+ConvertKB(FileSize DIV 1024,FALSE); + 3 : BEGIN + TempStr := TempStr + 'Description : ^9'+Description; + PrintACR('^1'+TempStr); + IF (F.VPointer <> -1) THEN + BEGIN + LoadVerbArray(F,ExtendedArray,NumExtDesc); + NumLine := 1; + WHILE (NumLine <= NumExtDesc) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + PrintACR('^1'+AOnOff(Editing,PadLeftStr('',3),'') + +AOnOff(Editing AND (NumLine = 1),PadLeftStr('Extended',13),PadLeftStr('',13)) + +AOnOff(Editing,PadRightInt(NumLine,3),PadRightStr('',3)) + +' : ^9'+ExtendedArray[NumLine]); + Inc(NumLine); + END; + END; + IF (Editing) THEN + IF (F.VPointer = -1) THEN + PrintACR('^5 No extended description.'); + END; + 4 : TempStr := TempStr + 'Uploaded by : ^4'+Caps(OwnerName); + 5 : TempStr := TempStr + 'Uploaded on : ^5'+PD2Date(FileDate); + 6 : BEGIN + TempStr := TempStr + 'Times downloaded : ^5'+FormatNumber(Downloaded); + PrintACR('^1'+TempStr); + IF (NOT Editing) THEN + BEGIN + TempStr := 'Block size : 128-"^5'+IntToStr(FileSize DIV 128)+ + '^1" / 1024-"^5'+IntToStr(FileSize DIV 1024)+'^1"'; + PrintACR('^1'+TempStr); + TempStr := 'Time to download : ^5'+CTim(FileSize DIV Rate); + PrintACR('^1'+TempStr); + END; + END; + 7 : TempStr := TempStr + 'File point cost : ^4'+AOnOff((FilePoints > 0),FormatNumber(FilePoints),'FREE')+ + DisplayFIStr(FIFlags); + END; + IF (NOT (Counter IN [3,6])) THEN + PrintACR('^1'+TempStr+'^1'); + END; + Inc(Counter); + END; +END; + +FUNCTION Fit(CONST FileName1,FileName2: Str12): Boolean; +VAR + Counter: Byte; + Match: Boolean; +BEGIN + Match := TRUE; + FOR Counter := 1 TO 12 DO + IF (FileName1[Counter] <> FileName2[Counter]) AND (FileName1[Counter] <> '?') THEN + Match := FALSE; + IF (FileName2 = '') THEN + Match := FALSE; + Fit := Match; +END; + +PROCEDURE GetFileName(VAR FileName: Str12); +BEGIN + MPL(12); + InputMain(FileName,12,[NoLineFeed,UpperOnly]); + IF (FileName <> '') THEN + NL + ELSE + BEGIN + MPL(12); + FileName := '*.*'; + Print(FileName); + END; + FileName := Align(FileName); +END; + +FUNCTION ISUL(CONST s: AStr): Boolean; +BEGIN + ISUL := ((Pos('/',s) <> 0) OR (Pos('\',s) <> 0) OR (Pos(':',s) <> 0) OR (Pos('|',s) <> 0)); +END; + +FUNCTION IsWildCard(CONST S: AStr): Boolean; +BEGIN + IsWildCard := ((Pos('*',S) <> 0) OR (Pos('?',S) <> 0)); +END; + +PROCEDURE LRecNo(FileInfo: FileInfoRecordType; VAR RN: Integer); +VAR + DirFileRecNum: Integer; +BEGIN + RN := 0; + IF (LastDIRRecNum <= FileSize(FileInfoFile)) AND (LastDIRRecNum >= 0) THEN + BEGIN + DirFileRecNum := (LastDIRRecNum - 1); + WHILE (DirFileRecNum >= 0) AND (RN = 0) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + IF Fit(LastDIRFileName,FileInfo.FileName) THEN + RN := DirFileRecNum; + Dec(DirFileRecNum); + END; + LastDIRRecNum := RN; + END + ELSE + RN := -1; + LastError := IOResult; +END; + +PROCEDURE NRecNo(FileInfo: FileInfoRecordType; VAR RN: Integer); +VAR + DirFileRecNum: Integer; +BEGIN + RN := 0; + IF (LastDIRRecNum < FileSize(FileInfoFile)) AND (LastDIRRecNum >= -1) THEN + BEGIN + DirFileRecNum := (LastDIRRecNum + 1); + WHILE (DirFileRecNum < FileSize(FileInfoFile)) AND (RN = 0) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + IF Fit(LastDIRFileName,FileInfo.FileName) THEN + RN := (DirFileRecNum + 1); + Inc(DirFileRecNum); + END; + Dec(RN); + LastDIRRecNum := RN; + END + ELSE + RN := -1; + LastError := IOResult; +END; + +PROCEDURE RecNo(FileInfo: FileInfoRecordType; FileName: Str12; VAR RN: Integer); +VAR + DirFileRecNum: Integer; +BEGIN + InitFileArea(FileArea); + FileName := Align(FileName); + RN := 0; + DirFileRecNum := 0; + WHILE (DirFileRecNum < FileSize(FileInfoFile)) AND (RN = 0) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + IF Fit(FileName,FileInfo.FileName) THEN + RN := (DirFileRecNum + 1); + Inc(DirFileRecNum); + END; + Dec(RN); + LastDIRRecNum := RN; + LastDIRFileName := FileName; + LastError := IOResult; +END; + +PROCEDURE LoadVerbArray(F: FileInfoRecordType; VAR ExtArray: ExtendedDescriptionArray; VAR NumExtDesc: Byte); +VAR + VerbStr: AStr; + TotLoad: Integer; + VFO: Boolean; +BEGIN + FillChar(ExtArray,SizeOf(ExtArray),0); + NumExtDesc := 1; + VFO := (FileRec(ExtInfoFile).Mode <> FMClosed); + IF (NOT VFO) THEN + Reset(ExtInfoFile,1); + IF (IOResult = 0) THEN + BEGIN + TotLoad := 0; + Seek(ExtInfoFile,(F.VPointer - 1)); + REPEAT + BlockRead(ExtInfoFile,VerbStr[0],1); + BlockRead(ExtInfoFile,VerbStr[1],Ord(VerbStr[0])); + Inc(TotLoad,(Length(VerbStr) + 1)); + ExtArray[NumExtDesc] := VerbStr; + Inc(NumExtDesc); + UNTIL (TotLoad >= F.VTextSize); + IF (NOT VFO) THEN + Close(ExtInfoFile); + END; + Dec(NumExtDesc); + LastError := IOResult; +END; + +PROCEDURE SaveVerbArray(VAR F: FileInfoRecordType; ExtArray: ExtendedDescriptionArray; NumExtDesc: Byte); +VAR + LineNum: Byte; + VFO: Boolean; +BEGIN + VFO := (FileRec(ExtInfoFile).Mode <> FMClosed); + IF (NOT VFO) THEN + Reset(ExtInfoFile,1); + IF (IOResult = 0) THEN + BEGIN + F.VPointer := (FileSize(ExtInfoFile) + 1); + F.VTextSize := 0; + Seek(ExtInfoFile,FileSize(ExtInfoFile)); + FOR LineNum := 1 TO NumExtDesc DO + IF (ExtArray[LineNum] <> '') THEN + BEGIN + Inc(F.VTextSize,(Length(ExtArray[LineNum]) + 1)); + BlockWrite(ExtInfoFile,ExtArray[LineNum],(Length(ExtArray[LineNum]) + 1)); + END; + IF (NOT VFO) THEN + Close(ExtInfoFile); + END; + LastError := IOResult; +END; + +PROCEDURE CountDown; +VAR + Cmd: Char; + Counter: Byte; + SaveTimer: LongInt; +BEGIN + NL; + Print('Press <^5CR^1> to logoff now.'); + Print('Press <^5Esc^1> to abort logoff.'); + NL; + Prompt('|12Hanging up in: ^99'); + SaveTimer := Timer; + Cmd := #0; + Counter := 9; + WHILE (Counter > 0) AND NOT (Cmd IN [#13,#27]) AND (NOT HangUp) DO + BEGIN + IF (NOT Empty) THEN + Cmd := Char(InKey); + IF (Timer <> SaveTimer) THEN + BEGIN + Dec(Counter); + Prompt(^H+IntToStr(Counter)); + SaveTimer := Timer; + END + ELSE +{$IFDEF MSDOS} + ASM + Int 28h + END; +{$ENDIF} +{$IFDEF WIN32} + Sleep(1); +{$ENDIF} + END; + IF (Cmd <> #27) THEN + BEGIN + HangUp := TRUE; + OutCom := FALSE; + END; + UserColor(1); +END; + +END. diff --git a/SOURCE/FILE1.PAS b/SOURCE/FILE1.PAS new file mode 100644 index 0000000..473e66d --- /dev/null +++ b/SOURCE/FILE1.PAS @@ -0,0 +1,1588 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File1; + +INTERFACE + +USES + Common; + +FUNCTION ChargeFilePoints(FArea: Integer): Boolean; +FUNCTION ChargeFileRatio(FArea: Integer): Boolean; +PROCEDURE CreditUploader(FileInfo: FileInfoRecordType); +FUNCTION SearchForDups(CONST CompleteFN: Str12): Boolean; +FUNCTION DizExists(CONST FN: AStr): Boolean; +PROCEDURE GetDiz(VAR FileInfo: FileInfoRecordType; VAR ExtendedArray: ExtendedDescriptionArray; VAR NumExtDesc: Byte); +PROCEDURE DLX(FileInfo: FileInfoRecordType; + DirFileRecNum: Integer; + VAR TransferFlags: TransferFlagSet); +FUNCTION DLInTime: BOOLEAN; +FUNCTION BatchDLQueuedFiles(TransferFlags: TransferFlagSet): BOOLEAN; +PROCEDURE DL(CONST FileName: Str12; TransferFlags: TransferFlagSet); +PROCEDURE GetFileDescription(VAR FileInfo: FileInfoRecordType; VAR ExtendedArray: ExtendedDescriptionArray; + VAR NumExtDesc: Byte; VAR ToSysOp: Boolean); +PROCEDURE WriteFV(FileInfo: FileInfoRecordType;DirFileRecNum: Integer; ExtendedArray: ExtendedDescriptionArray); +PROCEDURE UpdateFileInfo(VAR FileInfo: FileInfoRecordType; CONST FN: Str12; VAR GotPts: Integer); +PROCEDURE ArcStuff(VAR Ok,Convt: Boolean; VAR FSize,ConvTime: LongInt; + ITest: Boolean; CONST FilePath: AStr; VAR FileName: Str12; VAR Descr: AStr); +PROCEDURE DownloadFile(FileName: Str12; TransferFlags: TransferFlagSet); +PROCEDURE UploadFile; +PROCEDURE LFileAreaList(VAR FArea,NumFAreas: Integer; AdjPageLen: Byte; ShowScan: Boolean); +PROCEDURE UnlistedDownload(FileName: AStr); +PROCEDURE Do_Unlisted_Download; + +IMPLEMENTATION + +USES + Dos, + Crt, + Archive1, + Email, + Events, + File0, + File2, + File6, + File8, + File11, + File12, + File14, + MultNode, + ShortMsg, + TimeFunc; + +FUNCTION ChargeFilePoints(FArea: Integer): Boolean; +VAR + ChargePoints: Boolean; +BEGIN + ChargePoints := FALSE; + IF (FArea <> -1) AND + (NOT (FANoRatio IN MemFileArea.FAFlags)) AND + (NOT AACS(General.NoFileCredits)) AND + (NOT (FNoCredits IN ThisUser.Flags)) AND + (General.FileCreditRatio) THEN + ChargePoints := TRUE; + ChargeFilePoints := ChargePoints; +END; + +FUNCTION ChargeFileRatio(FArea: Integer): Boolean; +VAR + ChargeRatio: Boolean; +BEGIN + ChargeRatio := FALSE; + IF (FArea <> -1) AND + (NOT (FANoRatio IN MemFileArea.FAFlags)) AND + (NOT AACS(General.NoDLRatio)) AND + (NOT (FNoDLRatio IN ThisUser.Flags)) AND + (General.ULDLRatio) THEN + ChargeRatio := TRUE; + ChargeFileRatio := ChargeRatio; +END; + +PROCEDURE CreditUploader(FileInfo: FileInfoRecordType); +VAR + User: UserRecordType; + FilePointCredit: LongInt; +BEGIN + IF (General.RewardSystem) AND (FileInfo.OwnerNum >= 1) AND (FileInfo.OwnerNum <= (MaxUsers - 1)) AND + (FileInfo.OwnerNum <> UserNum) THEN + BEGIN + LoadURec(User,FileInfo.OwnerNum); + FilePointCredit := Trunc(FileInfo.FilePoints * (General.RewardRatio DIV 100)); + IF (CRC32(FileInfo.OwnerName) = CRC32(User.Name)) AND (FilePointCredit > 0) THEN + BEGIN + IF ((User.FilePoints + FilePointCredit) < 2147483647) THEN + Inc(User.FilePoints,FilePointCredit) + ELSE + User.FilePoints := 2147483647; + SaveURec(User,FileInfo.OwnerNum); + SysOpLog('^3 - Credits: '+FormatNumber(FilePointCredit)+' fp to "^5'+Caps(User.Name)+'^3".'); + SendShortMessage(FileInfo.OwnerNum,'You received '+FormatNumber(FilePointCredit)+ + ' '+Plural('file point',FilePointCredit)+' for the download of ' + +SQOutSp(FileInfo.FileName)); + END; + END; +END; + +FUNCTION OKDL(CONST FileInfo: FileInfoRecordType): Boolean; +VAR + MHeader: MHeaderRec; + Counter: Byte; +BEGIN + OKDL := TRUE; + IF (FIIsRequest IN FileInfo.FIFlags) THEN + BEGIN + PrintF('REQFILE'); + IF (NoFile) THEN + BEGIN + NL; + Print('^5You must request this from '+General.SysOpName+'!^1'); + END; + NL; + IF (PYNQ('Request this file now? ',0,FALSE)) THEN + BEGIN + InResponseTo := #1'Request "'+SQOutSp(FileInfo.FileName)+'" from area #'+IntToStr(CompFileArea(FileArea,0)); + MHeader.Status := []; + SEMail(1,MHeader); + END; + OKDL := FALSE; + END + ELSE IF (FIResumeLater IN FileInfo.FIFlags) AND (NOT FileSysOp) THEN + BEGIN + NL; + Print('^7You are not the uploader of this file!^1'); + OKDL := FALSE; + END + ELSE IF (FINotVal IN FileInfo.FIFlags) AND (NOT AACS(General.DLUNVal)) THEN + BEGIN + NL; + Print('^7Your access level does not permit downloading unvalidated files!^1'); + OKDL := FALSE; + END + ELSE IF (FileInfo.FilePoints > 0) AND (ThisUser.FilePoints < FileInfo.FilePoints) AND + ChargeFilePoints(FileArea) THEN + BEGIN + NL; + Print('^7'+lRGLngStr(26,TRUE)+'^1'{FString.NoFileCredits}); + OKDL := FALSE; + END + ELSE IF ((FileInfo.FileSize DIV Rate) > NSL) THEN + BEGIN + NL; + Print('^7Insufficient time left online to download this file!^1'); + Print(Ctim(NSL)); + OKDL := FALSE; + END; +END; + +PROCEDURE DLX(FileInfo: FileInfoRecordType; + DirFileRecNum: Integer; + VAR TransferFlags: TransferFlagSet); +VAR + DownloadPath: Str52; + CopyPath: Str40; + Cmd: Char; + Changed: Boolean; +BEGIN + Abort := FALSE; + Next := FALSE; + IF (IsFileAttach IN TransferFlags) THEN + BEGIN + NL; + Print('^4The following has been attached:^1'); + END; + NL; + DisplayFileInfo(FileInfo,FALSE); + IF (IsFileAttach IN TransferFlags) THEN + IF (InCom) THEN + BEGIN + NL; + IF (NOT PYNQ('Download file now? ',0,FALSE)) THEN + Exit; + END + ELSE IF (NOT CoSysOp) THEN + Exit + ELSE + BEGIN + NL; + IF (NOT PYNQ('Move file now? ',0,FALSE)) THEN + Exit; + END; + + IF (NOT OKDL(FileInfo)) THEN + Include(TransferFlags,IsPaused) + ELSE + BEGIN + + DownloadPath := ''; + + IF (Exist(MemFileArea.DLPath+FileInfo.FileName)) THEN + BEGIN + DownloadPath := MemFileArea.DLPath; + IF (FACDRom IN MemFileArea.FAFlags) THEN + InClude(TransferFLags,IsCDRom); + END + ELSE IF (Exist(MemFileArea.ULPath+FileInfo.FileName)) THEN + DownloadPath := MemFileArea.ULPath; + + IF (DownloadPath = '') THEN + BEGIN + NL; + Print('^7File does not actually exist.^1'); + SysOpLog('File missing: '+SQOutSp(DownloadPath+FileInfo.FileName)); + Exit; + END; + IF (InCom) THEN + Send(FileInfo,DirFileRecNum,DownloadPath,TransferFlags) + ELSE IF (NOT CoSysOp) THEN + Include(TransferFlags,IsPaused) + ELSE + BEGIN + CopyPath := ''; + InputPath('%LF^4Enter the destination path (^5End with a ^4"^5\^4"):%LF^4:',CopyPath,FALSE,TRUE,Changed); + IF (CopyPath = '') THEN + Include(TransferFlags,IsPaused) + ELSE + BEGIN + NL; + IF (NOT CopyMoveFile(NOT (IsFileAttach IN TransferFlags), + +AOnOff(IsFileAttach IN TransferFlags,'^1Moving ... ','^1Copying ... '), + DownloadPath+SQOutSp(FileInfo.FileName), + CopyPath+SQOutSp(FileInfo.FileName),TRUE)) THEN + Include(TransferFlags,IsPaused); + END; + END; + END; + IF (IsPaused IN TransferFlags) AND (NOT (IsFileAttach IN TransferFlags)) THEN + BEGIN + NL; + Prompt('^1Press [^5Enter^1] to Continue or [^5Q^1]uit: '); + Onek(Cmd,'Q'^M,TRUE,TRUE); + IF (Cmd = 'Q') THEN + BEGIN + Include(TransferFlags,IsKeyboardAbort); + Abort := TRUE; + END; + END; + IF (IsPaused IN TransferFLags) THEN + Exclude(TransferFlags,IsPaused); +END; + +PROCEDURE DL(CONST FileName: Str12; TransferFlags: TransferFlagSet); +VAR + SaveFileArea, + FArea: Integer; + GotAny, + Junk: Boolean; + + FUNCTION ScanBase(FileName1: Str12; VAR GotAny1: Boolean): Boolean; + VAR + DirFileRecNum: Integer; + BEGIN + ScanBase := FALSE; + RecNo(FileInfo,FileName1,DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + BackErase(13); + IF (NOT (FINotVal IN FileInfo.FIFlags)) OR (AACS(General.DLUnVal)) THEN + IF AACS(MemFileArea.DLACS) THEN + BEGIN + DLX(FileInfo,DirFileRecNum,TransferFlags); + ScanBase := TRUE; + IF (IsKeyboardAbort IN TransferFlags) THEN + Abort := TRUE; + IF (NOT (IsWildCard(FileName1))) THEN + Abort := TRUE; + END + ELSE + BEGIN + NL; + Print('Your access level does not permit downloading this file.'); + END; + GotAny1 := TRUE; + WKey; + NRecNo(FileInfo,DirFileRecNum); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + LastError := IOResult; + END; + +BEGIN + GotAny := FALSE; + Abort := FALSE; + Next := FALSE; + + Include(TransferFlags,IsCheckRatio); + + NL; + Prompt('Searching ...'); + + IF (NOT ScanBase(FileName,GotAny)) THEN + BEGIN + SaveFileArea := FileArea; + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (FArea <> SaveFileArea) THEN + BEGIN + LoadFileArea(FArea); + IF (MemFileArea.Password = '') THEN (* Doesn't scan areas with a Password ??? *) + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + Junk := ScanBase(FileName,GotAny); + END; + WKey; + Inc(FArea); + END; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; + IF (NOT GotAny) THEN + BEGIN + BackErase(13); + NL; + Print('File not found.'); + END; +END; + +FUNCTION DLInTime: BOOLEAN; +VAR + DLAllowed: BOOLEAN; +BEGIN + DLAllowed := TRUE; + + IF (NOT InTime(Timer,General.DLLowTime,General.DLHiTime)) THEN + DLAllowed := FALSE; + + IF (ComPortSpeed < General.MinimumDLBaud) THEN + IF (NOT InTime(Timer,General.MinBaudDLLowTime,General.MinBaudDLHiTime)) THEN + DLAllowed := FALSE; + + IF (NOT DLAllowed) THEN + BEGIN + NL; + PrintF('DLHOURS'); + IF (NoFile) THEN + Print('File downloading is not allowed at this time.'); + END; + DLInTime := DLAllowed; +END; + +FUNCTION BatchDLQueuedFiles(TransferFlags: TransferFlagSet): BOOLEAN; +VAR + DLBatch: BOOLEAN; +BEGIN + DLBatch := FALSE; + IF (NOT (lIsAddDLBatch IN TransferFLags)) AND (NumBatchDLFiles > 0) THEN + BEGIN + NL; + IF (PYNQ('Batch download queued files? ',0,FALSE)) THEN + BEGIN + BatchDownload; + DLBatch := TRUE; + END; + END; + BatchDLQueuedFiles := DLBatch; +END; + +PROCEDURE DownloadFile(FileName: Str12; TransferFlags: TransferFlagSet); +BEGIN + IF (DLInTime) THEN + IF (NOT BatchDLQueuedFiles(TransferFlags)) THEN + BEGIN + IF (FileName = '') THEN + BEGIN + PrintF('DLOAD'); + IF (NOT (lIsAddDLBatch IN TransferFlags)) THEN + { + NL; + Print(FString.downloadline) + NL; + Prt('File name: '); + } + lRGLngStr(23,FALSE) + ELSE + { + NL; + Print(FString.AddDLBatch); + NL; + Prt('File name: '); + } + lRGLngStr(31,FALSE); + MPL(12); + Input(FileName,12); + IF (FileName = '') THEN + BEGIN + NL; + Print('Aborted.'); + END; + END; + IF (FileName <> '') THEN + BEGIN + IF (Pos('.',FileName) = 0) THEN + FileName := FileName+'.*'; + DL(FileName,TransferFlags); + END + END; +END; + +PROCEDURE GetFileDescription(VAR FileInfo: FileInfoRecordType; VAR ExtendedArray: ExtendedDescriptionArray; + VAR NumExtDesc: Byte; VAR ToSysOp: Boolean); +VAR + MaxLen: Byte; +BEGIN + NL; + IF ((ToSysOp) AND (General.ToSysOpDir >= 1) AND (General.ToSysOpDir <= NumFileAreas)) THEN + Print('Begin description with (/) to make upload "Private".') + ELSE + ToSysOp := FALSE; + LoadFileArea(FileArea); + IF ((FAUseGIFSpecs IN MemFileArea.FAFlags) AND ISGifExt(FileInfo.FileName)) THEN + BEGIN + Print('Enter your text. Press <^5Enter^1> alone to end. (31 chars/line 1, 50 chars/line 2-'+IntToStr(MaxExtDesc + 1)+')'); + MaxLen := 31; + END + ELSE + BEGIN + Print('Enter your text. Press <^5Enter^1> alone to end. (50 chars/line 1-'+IntToStr(MaxExtDesc + 1)+')'); + MaxLen := 50; + END; + REPEAT + Prt(': '); + MPL(MaxLen); + InputWC(FileInfo.Description,MaxLen); + IF ((FileInfo.Description[1] = '/') OR (RValidate IN ThisUser.Flags)) AND (ToSysOp) THEN + BEGIN + IF (General.ToSysOpDir >= 1) AND (General.ToSysOpDir <= NumFileAreas) THEN + FileArea := General.ToSysOpDir; + InitFileArea(FileArea); + ToSysOp := TRUE; + END + ELSE + ToSysOp := FALSE; + IF (FileInfo.Description[1] = '/') THEN + Delete(FileInfo.Description,1,1); + UNTIL ((FileInfo.Description <> '') OR (FileSysOp) OR (HangUp)); + FillChar(ExtendedArray,SizeOf(ExtendedArray),0); + NumExtDesc := 0; + REPEAT + Inc(NumExtDesc); + Prt(': '); + MPL(50); + InputL(ExtendedArray[NumExtDesc],50); + UNTIL (ExtendedArray[NumExtDesc] = '') OR (NumExtDesc = MaxExtDesc) OR (HangUp); +END; + +FUNCTION DizExists(CONST FN: AStr): Boolean; +VAR + Ok: Boolean; +BEGIN + DizExists := FALSE; + IF (ArcType(FN) > 0) THEN + BEGIN + Star('Checking for description...'#29); + ArcDecomp(Ok,ArcType(FN),FN,'FILE_ID.DIZ DESC.SDI'); + IF (Ok) AND (Exist(TempDir+'ARC\FILE_ID.DIZ') OR (Exist(TempDir+'ARC\DESC.SDI'))) THEN + DizExists := TRUE; + NL; + END; +END; + +PROCEDURE GetDiz(VAR FileInfo: FileInfoRecordType; VAR ExtendedArray: ExtendedDescriptionArray; VAR NumExtDesc: Byte); +VAR + DizFile: Text; + TempStr: Str50; + Counter: Byte; +BEGIN + IF (Exist(TempDir+'ARC\FILE_ID.DIZ')) THEN + Assign(DizFile,TempDir+'ARC\FILE_ID.DIZ') + ELSE + Assign(DizFile,TempDir+'ARC\DESC.SDI'); + Reset(DizFile); + IF (IOResult <> 0) THEN + Exit; + Star('Importing description.'); + FillChar(ExtendedArray,SizeOf(ExtendedArray),0); + Counter := 1; + WHILE NOT EOF(DizFile) AND (Counter <= (MaxExtDesc + 1)) DO + BEGIN + ReadLn(DizFile,TempStr); + IF (TempStr = '') THEN + TempStr := ' '; + IF (Counter = 1) THEN + FileInfo.Description := TempStr + ELSE + ExtendedArray[Counter - 1] := TempStr; + Inc(Counter); + END; + NumExtDesc := MaxExtDesc; + WHILE (NumExtDesc >= 1) AND ((ExtendedArray[NumExtDesc] = ' ') OR (ExtendedArray[NumExtDesc] = '')) DO + BEGIN + ExtendedArray[NumExtDesc] := ''; + Dec(NumExtDesc); + END; + Close(DizFile); + Erase(DizFile); + LastError := IOResult; +END; + +PROCEDURE WriteFV(FileInfo: FileInfoRecordType; DirFileRecNum: Integer; ExtendedArray: ExtendedDescriptionArray); +VAR + LineNum: Byte; + VFO: Boolean; +BEGIN + FileInfo.VTextSize := 0; + IF (ExtendedArray[1] = '') THEN + FileInfo.VPointer := -1 + ELSE + BEGIN + VFO := (FileRec(ExtInfoFile).Mode <> FMClosed); + IF (NOT VFO) THEN + Reset(ExtInfoFile,1); + IF (IOResult = 0) THEN + BEGIN + FileInfo.VPointer := (FileSize(ExtInfoFile) + 1); + Seek(ExtInfoFile,FileSize(ExtInfoFile)); + FOR LineNum := 1 TO MaxExtDesc DO + IF (ExtendedArray[LineNum] <> '') THEN + BEGIN + Inc(FileInfo.VTextSize,(Length(ExtendedArray[LineNum]) + 1)); + BlockWrite(ExtInfoFile,ExtendedArray[LineNum],(Length(ExtendedArray[LineNum]) + 1)); + END; + IF (NOT VFO) THEN + Close(ExtInfoFile); + END; + END; + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,FileInfo); + LastError := IOResult; +END; + +PROCEDURE UpdateFileInfo(VAR FileInfo: FileInfoRecordType; CONST FN: Str12; VAR GotPts: Integer); +BEGIN + WITH FileInfo DO + BEGIN + FileName := Align(FN); + Downloaded := 0; + OwnerNum := UserNum; + OwnerName := AllCaps(ThisUser.Name); + FileDate := Date2PD(DateStr); + IF (NOT General.FileCreditRatio) THEN + BEGIN + FilePoints := 0; + GotPts := 0; + END + ELSE + BEGIN + FilePoints := 0; + IF (General.FileCreditCompBaseSize > 0) THEN + FilePoints := ((FileSize DIV 1024) DIV General.FileCreditCompBaseSize); + GotPts := (FilePoints * General.FileCreditComp); + IF (GotPts < 1) THEN + GotPts := 1; + END; + FIFlags := []; + + IF (NOT AACS(General.ULValReq)) AND (NOT General.ValidateAllFiles) THEN + Include(FIFlags,FINotVal); + + END; +END; + +(* +OldArcType : current archive format, 0 IF none +NewArcType : desired archive format, 0 IF none +OldFileName : current FileName +NewFileName : desired archive format FileName +*) + +PROCEDURE ArcStuff(VAR Ok, + Convt: Boolean; { IF Ok - IF converted } + VAR FSize, { file size } + ConvTime: LongInt; { convert time } + ITest: Boolean; { whether to test integrity } + CONST FilePath: AStr; { filepath } + VAR FileName: Str12; { FileName } + VAR Descr: AStr); { Description } +VAR + OldFileName, + NewFileName: AStr; + OldArcType, + NewArcType: Byte; +BEGIN + Ok := TRUE; + + ConvTime := 0; + + FSize := GetFileSize(FilePath+FileName); + + IF (NOT General.TestUploads) THEN + Exit; + + OldFileName := SQOutSp(FilePath+FileName); + + OldArcType := ArcType(OldFileName); + + NewArcType := MemFileArea.ArcType; + + IF (NOT General.FileArcInfo[NewArcType].Active) OR + (General.FileArcInfo[NewArcType].Ext = '') THEN + BEGIN + NewArcType := 0; + NewArcType := OldArcType; + END; + + + IF ((OldArcType <> 0) AND (NewArcType <> 0)) THEN + BEGIN + + + NewFileName := FileName; + + IF (Pos('.',NewFileName) <> 0) THEN + NewFileName := Copy(NewFileName,1,(Pos('.',NewFileName) - 1)); + + NewFileName := SQOutSp(FilePath+NewFileName+'.'+General.FileArcInfo[NewArcType].Ext); + + IF ((ITest) AND (General.FileArcInfo[OldArcType].TestLine <> '')) THEN + BEGIN + NL; + Star('Testing file integrity ... '#29); + ArcIntegrityTest(Ok,OldArcType,OldFileName); + IF (NOT Ok) THEN + BEGIN + SysOpLog('^5 '+OldFileName+' on #'+IntToStr(FileArea)+': errors in integrity test'); + Print('^3failed.'); + END + ELSE + Print('^3passed.'); + END; + + IF (Ok) AND ((OldArcType <> NewArcType) OR General.Recompress) AND (NewArcType <> 0) THEN + BEGIN + Convt := InCom; {* don't convert IF local AND non-file-SysOp *} + + IF (FileSysOp) THEN + BEGIN + IF (OldArcType = NewArcType) THEN + Convt := PYNQ('Recompress this file? ',0,TRUE) + ELSE + Convt := PYNQ('Convert archive to .'+General.FileArcInfo[NewArcType].Ext+' format? ',0,TRUE); + END; + + IF (Convt) THEN + BEGIN + NL; + + ConvTime := GetPackDateTime; + + ConvA(Ok,OldArcType,NewArcType,OldFileName,NewFileName); + + ConvTime := (GetPackDateTime - ConvTime); + + IF (Ok) THEN + BEGIN + + IF (OldArcType <> NewArcType) THEN + Kill(FilePath+FileName); + + FSize := GetFileSize(NewFileName); + + IF (FSize = -1) OR (FSize = 0) THEN + Ok := FALSE; + + FileName := Align(StripName(NewFileName)); + Star('No errors in conversion, file passed.'); + END + ELSE + BEGIN + IF (OldArcType <> NewArcType) THEN + Kill(NewFileName); + SysOpLog('^5 '+OldFileName+' on #'+IntToStr(FileArea)+': Conversion unsuccessful'); + Star('errors in conversion! Original format retained.'); + NewArcType := OldArcType; + END; + Ok := TRUE; + END + ELSE + NewArcType := OldArcType; + END; + + IF (Ok) AND (General.FileArcInfo[NewArcType].CmtLine <> '') THEN + BEGIN + ArcComment(Ok,NewArcType,MemFileArea.CmtType,SQOutSp(FilePath+FileName)); + Ok := TRUE; + END; + + END; + + FileName := SQOutSp(FileName); + + IF (FAUseGIFSpecs IN MemFileArea.FAFlags) AND (IsGifExt(FileName)) THEN + Descr := GetGIFSpecs(FilePath+FileName,Descr,2); + +END; + +FUNCTION SearchForDups(CONST CompleteFN: Str12): Boolean; +VAR + WildFN, + NearFN: Str12; + SaveFileArea, + FArea, + FArrayRecNum: Integer; + AnyFound, + HadACC, + Thisboard, + CompleteMatch, + NearMatch: Boolean; + + PROCEDURE SearchB(FArea1: Integer; VAR FArrayRecNum: Integer; CONST FN: Str12; VAR HadACC: Boolean); + VAR + DirFileRecNum: Integer; + BEGIN + HadACC := FileAreaAC(FArea1); + IF (NOT HadACC) OR (FANoDupeCheck IN MemFileArea.FAFlags) AND (NOT (FileArea = FArea1)) THEN + Exit; + FileArea := FArea1; + RecNo(FileInfo,FN,DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + WHILE (DirFileRecNum <> -1) DO + BEGIN + IF (NOT AnyFound) THEN + BEGIN + NL; + NL; + AnyFound := TRUE; + END; + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + IF (CanSee(FileInfo)) THEN + BEGIN + WITH FArray[FArrayRecNum] DO + BEGIN + FArrayFileArea := FileArea; + FArrayDirFileRecNum := DirFileRecNum; + END; + LDisplay_File(FileInfo,FArrayRecNum,'',TRUE); + Inc(FArrayRecNum); + IF (FArrayRecNum = 100) THEN + FArrayRecNum := 0; + END; + IF (Align(FileInfo.FileName) = Align(CompleteFN)) THEN + BEGIN + CompleteMatch := TRUE; + ThisBoard := TRUE; + END + ELSE + BEGIN + NearFN := Align(FileInfo.FileName); + NearMatch := TRUE; + ThisBoard := TRUE; + END; + NRecNo(FileInfo,DirFileRecNum); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + FileArea := SaveFileArea; + InitFileArea(FileArea); + LastError := IOResult; + END; + +BEGIN + SaveFileArea := FileArea; + InitFArray(FArray); + FArrayRecNum := 0; + AnyFound := FALSE; + Prompt('^5Searching for possible duplicates ... '); + SearchForDups := TRUE; + IF (Pos('.',CompleteFN) > 0) THEN + WildFN := Copy(CompleteFN,1,Pos('.',CompleteFN) - 1) + ELSE + WildFN := CompleteFN; + WildFn := SQOutSp(WildFN); + WHILE (WildFN[Length(WildFN)] IN ['0'..'9']) AND (Length(WildFN) > 2) DO + Dec(WildFN[0]); + WHILE (Length(WildFN) < 8) DO + WildFN := WildFN + '?'; + WildFN := WildFN + '.???'; + CompleteMatch := FALSE; + NearMatch := FALSE; + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT HangUp) DO + BEGIN + Thisboard := FALSE; + SearchB(FArea,FArrayRecNum,WildFN,HadACC); + LoadFileArea(FArea); + IF (CompleteMatch) THEN + BEGIN + SysOpLog('User tried to upload '+SQOutSp(CompleteFN)+' to #'+IntToStr(SaveFileArea)+ + '; existed in #'+IntToStr(FArea)+AOnOff(NOT HadACC,' - no access','')); + NL; + NL; + IF (HadACC) THEN + Print('^5File "'+SQOutSp(CompleteFN)+'" already exists in "'+MemFileArea.AreaName+'^5 #'+IntToStr(FArea)+'".') + ELSE + Print('^5File "'+SQOutSp(CompleteFN)+ 'cannot be accepted by the system at this time.'); + Print('^7Illegal File Name.'); + Exit; + END + ELSE IF (NearMatch) AND (Thisboard) THEN + BEGIN + SysOpLog('User entered upload file name "'+SQOutSp(CompleteFN)+'" in #'+ + IntToStr(FileArea)+'; was warned that "'+SQOutSp(NearFN)+ + '" existed in #'+IntToStr(FArea)+AOnOff(NOT HadACC,' - no access to','')); + END; + Inc(FArea); + END; + FileArea := SaveFileArea; + InitFileArea(FileArea); + IF (NOT AnyFound) THEN + Print('No duplicates found.'); + NL; + SearchForDups := FALSE; +END; + +(* +AExists : if file already exists in dir +DirFileRecNum : rec-num of file if already exists in file listing +ResumeFile : IF user is going to RESUME THE UPLOAD +ULS : whether file is to be actually UPLOADED +OffLine : IF uploaded a file to be OffLine automatically.. +*) + +PROCEDURE UL(FileName: Str12; LocBatUp: Boolean; VAR AddULBatch: Boolean); +VAR + fi: FILE OF Byte; + Cmd: Char; + Counter, + LineNum, + NumExtDesc: Byte; + DirFileRecNum, + SaveFileArea, + GotPts: Integer; + TransferTime, + RefundTime, + ConversionTime: LongInt; + ULS, + UploadOk, + KeyboardAbort, + Convt, + AExists, + ResumeFile, + WentToSysOp, + OffLine: Boolean; +BEGIN + SaveFileArea := FileArea; + InitFileArea(FileArea); + IF (BadUploadPath) THEN + Exit; + + UploadOk := TRUE; + + IF (FileName[1] = ' ') OR (FileName[10] = ' ') THEN + UploadOk := FALSE; + + FOR Counter := 1 TO Length(FileName) DO + IF (Pos(FileName[Counter],'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.-!#$%^&''~()_') = 0) THEN + BEGIN + UploadOk := FALSE; + Break; + END; + + IF (NOT UploadOk) THEN + BEGIN + NL; + Print('^7Illegal file name specified!^1'); + PauseScr(FALSE); + Exit; + END; + + Abort := FALSE; + Next := FALSE; + + ResumeFile := FALSE; + + ULS := TRUE; + + OffLine := FALSE; + + AExists := Exist(MemFileArea.ULPath+FileName); + + FileName := Align(FileName); + + RecNo(FileInfo,FileName,DirFileRecNum); + IF (DirFileRecNum <> -1) THEN + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + ResumeFile := (FIResumeLater IN FileInfo.FIFlags); + IF (ResumeFile) THEN + BEGIN + NL; + Print('^5Note: ^1This is a resume-later file.^1'); + ResumeFile := (CRC32(FileInfo.OwnerName) = CRC32(ThisUser.Name)) OR (FileSysOp); + IF (ResumeFile) THEN + BEGIN + IF (NOT InCom) THEN + BEGIN + NL; + Print('^7File upload can not be resumed locally!^1'); + PauseScr(FALSE); + Exit; + END; + NL; + ResumeFile := PYNQ('Resume upload of "'+SQOutSp(FileName)+'"? ',0,TRUE); + IF (NOT ResumeFile) THEN + Exit; + END + ELSE + BEGIN + NL; + Print('^7You are not the uploader of this file!^1'); + PauseScr(FALSE); + Exit; + END; + END; + END; + + IF (NOT AExists) AND (FileSysOp) AND (NOT InCom) THEN + BEGIN + ULS := FALSE; + OffLine := TRUE; + NL; + Print('File does not exist in upload path: ^5'+MemFileArea.ULPath+SQOutSp(FileName)+'^1'); + IF (DirFileRecNum <> -1) THEN + BEGIN + NL; + Print('^5Note: ^1File exists in listing.^1'); + END; + NL; + IF NOT PYNQ('Do you want to create an offline entry? ',0,FALSE) THEN + Exit; + END; + + IF (NOT ResumeFile) THEN + BEGIN + + IF (((AExists) OR (DirFileRecNum <> -1)) AND (NOT FileSysOp)) THEN + BEGIN + NL; + Print('^7File already exists!^1'); + Exit; + END; + IF (FileSize(FileInfoFile) >= MemFileArea.MaxFiles) THEN + BEGIN + NL; + Star('^7This file area is full!^1'); + Exit; + END; + + IF (NOT AExists) AND (NOT OffLine) THEN + IF (NOT CheckDriveSpace('Upload',MemFileArea.ULPath,General.MinSpaceForUpload)) THEN + Exit; + + IF (AExists) THEN + BEGIN + ULS := FALSE; + NL; + Print('^1File exists in upload path: ^5'+MemFileArea.ULPath+SQOutSp(FileName)); + IF (DirFileRecNum <> -1) THEN + BEGIN + NL; + Print('^5Note: ^1File exists in listing.^1'); + END; + + IF (LocBatUp) THEN + BEGIN + NL; + Prompt('^7[Q]uit or Upload this? (Y/N) ['+SQOutSp(ShowYesNo(DirFileRecNum = -1))+']: '); + OneK(Cmd,'QYN'^M,FALSE,FALSE); + IF (DirFileRecNum <> -1) THEN + UploadOk := (Cmd = 'Y') + ELSE + UploadOk := (Cmd IN ['Y',^M]); + Abort := (Cmd = 'Q'); + IF (Abort) THEN + Print('^3Quit') + ELSE IF (NOT UploadOk) THEN + Print('^3No') + ELSE + Print('^3Yes'); + UserColor(1); + END + ELSE + BEGIN + NL; + UploadOk := PYNQ('Upload this? (Y/N) ['+SQOutSp(ShowYesNo(DirFileRecNum = -1))+']: ',0,(DirFileRecNum = -1)); + END; + DirFileRecNum := 0; + END; + + IF (General.SearchDup) AND (UploadOk) AND (NOT Abort) AND (InCom) THEN + IF (NOT FileSysOp) OR (PYNQ('Search for duplicates? ',0,FALSE)) THEN + IF (SearchForDups(FileName)) THEN + Exit; + + IF (ULS) THEN + BEGIN + NL; + UploadOk := PYNQ('Upload "^5'+SQOutSp(FileName)+'^7" to ^5'+MemFileArea.AreaName+'^7? ',0,TRUE); + END; + + IF ((UploadOk) AND (ULS) AND (NOT ResumeFile)) THEN + BEGIN + + Assign(fi,MemFileArea.ULPath+FileName); + ReWrite(fi); + IF (IOResult <> 0) THEN + UploadOk := FALSE + ELSE + BEGIN + Close(fi); + Erase(fi); + IF (IOResult <> 0) THEN + UploadOk := FALSE; + END; + + IF (NOT UploadOk) THEN + BEGIN + NL; + Print('^7Unable to upload that file name!^1'); + Exit; + END; + END; + + END; + + IF (NOT UploadOk) THEN + Exit; + + WentToSysOp := TRUE; + + IF (NOT ResumeFile) THEN + BEGIN + FileInfo.FileName := Align(FileName); + GetFileDescription(FileInfo,ExtendedArray,NumExtDesc,WentToSysOp); + END; + + UploadOk := TRUE; + + IF (ULS) THEN + BEGIN + Receive(FileName,MemFileArea.ULPath,ResumeFile,UploadOk,KeyboardAbort,AddULBatch,TransferTime); + + IF (AddULBatch) THEN + BEGIN + IF CheckBatchUL(FileName) THEN + BEGIN + NL; + Print('^7This file is already in the batch upload queue!^1'); + END + ELSE IF (NumBatchULFiles = General.MaxBatchULFiles) THEN + BEGIN + NL; + Print('^7The batch upload queue is full!^1'); + END + ELSE + BEGIN + Assign(BatchULFile,General.DataPath+'BATCHUL.DAT'); + IF (NOT Exist(General.DataPath+'BATCHUL.DAT')) THEN + ReWrite(BatchULFile) + ELSE + Reset(BatchULFile); + WITH BatchUL DO + BEGIN + BULFileName := SQOutSp(FileName); + BULUserNum := UserNum; + + BULSection := FileArea; (* Should this be CompFileArea ??? *) + + BULDescription := FileInfo.Description; + + IF (ExtendedArray[1] = '') THEN + BEGIN + BULVPointer := -1; + BULVTextSize := 0; + END + ELSE + BEGIN + Assign(BatchULF,General.DataPath+'BATCHUL.EXT'); + IF (NOT Exist(General.DataPath+'BATCHUL.EXT')) THEN + ReWrite(BatchULF,1) + ELSE + Reset(BatchULF,1); + BULVPointer := (FileSize(BatchULF) + 1); + BULVTextSize := 0; + Seek(BatchULF,FileSize(BatchULF)); + FOR LineNum := 1 TO NumExtDesc DO + IF (ExtendedArray[LineNum] <> '') THEN + BEGIN + Inc(BULVTextSize,(Length(ExtendedArray[LineNum]) + 1)); + BlockWrite(BatchULF,ExtendedArray[LineNum],(Length(ExtendedArray[LineNum]) + 1)); + END; + Close(BatchULF); + LastError := IOResult; + END; + + Seek(BatchULFile,FileSize(BatchULFile)); + Write(BatchULFile,BatchUL); + Close(BatchULFile); + LastError := IOResult; + + Inc(NumBatchULFiles); + NL; + Print('^5File added to the batch upload queue.^1'); + NL; + Star('^1Batch upload queue: ^5'+IntToStr(NumBatchULFiles)+' '+Plural('file',NumBatchULFiles)); + SysOpLog('Batch UL Add: "^5'+BatchUL.BULFileName+'^1" to ^5'+MemFileArea.AreaName); + END; + END; + NL; + Star('^1Press <^5Enter^1> to stop adding to the batch upload queue.^1'); + NL; + FileArea := SaveFileArea; + Exit; + END; + + IF (KeyboardAbort) THEN + BEGIN + FileArea := SaveFileArea; + Exit; + END; + + RefundTime := (TransferTime * (General.ULRefund DIV 100)); + + Inc(FreeTime,RefundTime); + + NL; + + END; + + NL; + + Convt := FALSE; + + IF (NOT OffLine) THEN + BEGIN + + Assign(fi,MemFileArea.ULPath+FileName); + Reset(fi); + IF (IOResult <> 0) THEN + UploadOk := FALSE + ELSE + BEGIN + FileInfo.FileSize := FileSize(fi); + IF (FileSize(fi) = 0) THEN + UploadOk := FALSE; + Close(fi); + + END; + + END; + + IF ((UploadOk) AND (NOT OffLine)) THEN + BEGIN + + ArcStuff(UploadOk,Convt,FileInfo.FileSize,ConversionTime,ULS,MemFileArea.ULPath,FileName,FileInfo.Description); + + UpdateFileInfo(FileInfo,FileName,GotPts); + + IF (General.FileDiz) AND (DizExists(MemFileArea.ULPath+FileName)) THEN + GetDiz(FileInfo,ExtendedArray,NumExtDesc); + + IF (UploadOk) THEN + BEGIN + + IF (AACS(General.ULValReq)) OR (General.ValidateAllFiles) THEN + Include(FileInfo.FIFlags,FIOwnerCredited); + + IF (NOT ResumeFile) OR (DirFileRecNum = -1) THEN + WriteFV(FileInfo,FileSize(FileInfoFile),ExtendedArray) + ELSE + WriteFV(FileInfo,DirFileRecNum,ExtendedArray); + + IF (ULS) THEN + BEGIN + + IF (UploadsToday < 2147483647) THEN + Inc(UploadsToday); + + IF ((UploadKBytesToday + (FileInfo.FileSize DIV 1024)) < 2147483647) THEN + Inc(UploadKBytesToday,(FileInfo.FileSize DIV 1024)) + ELSE + UploadKBytesToday := 2147483647; + + END; + + SysOpLog('^3Uploaded: "^5'+SQOutSp(FileName)+'^3" on ^5'+MemFileArea.AreaName); + + IF (ULS) THEN + + + SysOpLog('^3 ('+ConvertBytes(FileInfo.FileSize,FALSE)+', '+FormattedTime(TransferTime)+ + ', '+FormatNumber(GetCPS(FileInfo.FileSize,Transfertime))+' cps)'); + + IF ((InCom) AND (ULS)) THEN + BEGIN + + Star('File size : ^5'+ConvertBytes(FileInfo.FileSize,FALSE)); + + Star('Upload time : ^5'+FormattedTime(TransferTime)); + + IF (Convt) THEN + Star('Convert time : ^5'+FormattedTime(ConversionTime)); + + Star('Transfer rate: ^5'+FormatNumber(GetCPS(FileInfo.FileSize,TransferTime))+' cps'); + + Star('Time refund : ^5'+FormattedTime(RefundTime)); + + IF (GotPts <> 0) THEN + Star('File Points : ^5'+FormatNumber(GotPts)+' pts'); + + IF (ChopTime > 0) THEN + BEGIN + Inc(ChopTime,RefundTime); + Dec(FreeTime,RefundTime); + NL; + Star('Sorry, no upload time refund may be given at this time.'); + Star('You will get your refund after the event.'); + NL; + END; + + IF (NOT AACS(General.ULValReq)) AND (NOT General.ValidateAllFiles) THEN + BEGIN + IF (General.ULDLRatio) THEN + BEGIN + NL; + Print('^5You will receive file credit as soon as the SysOp validates the file!') + END + ELSE + BEGIN + NL; + Print('^5You will receive credit as soon as the SysOp validates the file!'); + END; + END + ELSE + BEGIN + + IF ((NOT General.ULDLRatio) AND (NOT General.FileCreditRatio) AND (GotPts = 0)) THEN + BEGIN + NL; + Print('^5You will receive credit as soon as the Sysop validates the file!') + END + ELSE + BEGIN + + IF (ThisUser.Uploads < 2147483647) THEN + Inc(ThisUser.Uploads); + + IF ((ThisUser.UK + (FileInfo.FileSize DIV 1024)) < 2147483647) THEN + Inc(ThisUser.UK,(FileInfo.FileSize DIV 1024)) + ELSE + ThisUser.UK := 2147483647; + + IF ((ThisUser.FilePoints + GotPts) < 2147483647) THEN + Inc(ThisUser.FilePoints,GotPts) + ELSE + ThisUser.FilePoints := 2147483647; + + END; + END; + + + NL; + Print('^5Thanks for the file, '+Caps(ThisUser.Name)+'!'); + PauseScr(FALSE); + + END + ELSE + Star('Entry added.'); + END; + END; + + IF (NOT UploadOk) AND (NOT OffLine) THEN + BEGIN + + IF (Exist(MemFileArea.ULPath+FileName)) THEN + BEGIN + + Star('Upload not received.'); + + IF ((FileInfo.FileSize DIV 1024) >= General.MinResume) THEN + BEGIN + NL; + IF PYNQ('Save file for a later resume? ',0,TRUE) THEN + BEGIN + + UpdateFileInfo(FileInfo,FileName,GotPts); + + Include(FileInfo.FIFlags,FIResumeLater); + + IF (NOT AExists) OR (DirFileRecNum = -1) THEN + WriteFV(FileInfo,FileSize(FileInfoFile),ExtendedArray) + ELSE + WriteFV(FileInfo,DirFileRecNum,ExtendedArray); + + END; + END; + + IF (NOT (FIResumeLater IN FileInfo.FIFlags)) AND (Exist(MemFileArea.ULPath+FileName)) THEN + Kill(MemFileArea.ULPath+FileName); + + SysOpLog('^3Error uploading '+SQOutSp(FileName)+ + ' - '+AOnOff(FIResumeLater IN FileInfo.FIFlags,'file saved for later resume','file deleted')); + END; + + Star('Removing time refund of '+FormattedTime(RefundTime)); + + Dec(FreeTime,RefundTime); + END; + + IF (OffLine) THEN + BEGIN + FileInfo.FileSize := 0; + UpdateFileInfo(FileInfo,FileName,GotPts); + Include(FileInfo.FIFlags,FIIsRequest); + WriteFV(FileInfo,FileSize(FileInfoFile),ExtendedArray); + END; + + Close(FileInfoFile); + Close(ExtInfoFile); + + FileArea := SaveFileArea; + InitFileArea(FileArea); + + SaveURec(ThisUser,UserNum); +END; + +PROCEDURE UploadFile; +VAR + FileName: Str12; + AddULBatch: Boolean; +BEGIN + InitFileArea(FileArea); + IF (BadUploadPath) THEN + Exit; + IF (NOT AACS(MemFileArea.ULACS)) THEN + BEGIN + NL; + Star('Your access level does not permit uploading to this file area.'); + Exit; + END; + PrintF('UPLOAD'); + IF (NumBatchULFiles > 0) THEN + BEGIN + NL; + IF PYNQ('Upload queued files? ',0,FALSE) THEN + BEGIN + BatchUpload(FALSE,0); + Exit; + END; + END; + REPEAT + AddULBatch := FALSE; + { + NL; + Print(FString.UploadLine); + NL; + Prt('File name: '); + } + lRGLngStr(24,FALSE); + MPL(12); + Input(FileName,12); + FileName := SQOutSp(FileName); + IF (FileName = '') THEN + BEGIN + NL; + Print('Aborted.'); + END + ELSE + BEGIN + IF (NOT FileSysOp) THEN + UL(FileName,FALSE,AddULBatch) + ELSE + BEGIN + IF (NOT IsWildCard(FileName)) THEN + UL(FileName,FALSE,AddULBatch) + ELSE + BEGIN + FindFirst(MemFileArea.ULPath+FileName,AnyFile - Directory - VolumeID - Hidden - SysFile,DirInfo); + IF (DOSError <> 0) THEN + BEGIN + NL; + Print('No files found.'); + END + ELSE + REPEAT + UL(DirInfo.Name,TRUE,AddULBatch); + FindNext(DirInfo); + UNTIL (DOSError <> 0) OR (Abort) OR (HangUp); + END; + END; + END; + UNTIL (NOT AddUlBatch) OR (HangUp); +END; + +PROCEDURE LFileAreaList(VAR FArea,NumFAreas: Integer; AdjPageLen: Byte; ShowScan: Boolean); +VAR + ScanChar: Str1; + TempStr: AStr; + NumOnline, + NumDone: Byte; + SaveFileArea: Integer; +BEGIN + SaveFileArea := FileArea; + Abort := FALSE; + Next := FALSE; + NumOnline := 0; + TempStr := ''; + + FillChar(LightBarArray,SizeOf(LightBarArray),0); + LightBarCounter := 0; + + { + $New_Scan_Char_File + + $ + } + IF (ShowScan) THEN + ScanChar := lRGLngStr(55,TRUE); + { + %CL-Ŀ + -. Num -/ Name -. Num -/ Name - + - + } + lRGLngStr(59,FALSE); + Reset(FileAreaFile); + NumDone := 0; + WHILE (NumDone < (PageLength - AdjPageLen)) AND (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + LoadFileArea(FArea); + IF (ShowScan) THEN + LoadNewScanFile(NewScanFileArea); + IF AACS(MemFileArea.ACS) OR (FAUnHidden IN MemFileArea.FAFlags) THEN + BEGIN + + IF (General.UseFileAreaLightBar) AND (FileAreaLightBar IN ThisUser.SFlags) THEN + BEGIN + Inc(LightBarCounter); + LightBarArray[LightBarCounter].CmdToExec := CompFileArea(FArea,0); + LightBarArray[LightBarCounter].CmdToShow := MemFileArea.AreaName; + IF (NumOnline = 0) THEN + BEGIN + LightBarArray[LightBarCounter].Xpos := 8; + LightBarArray[LightBarCounter].YPos := WhereY; + END + ELSE + BEGIN + LightBarArray[LightBarCounter].Xpos := 47; + LightBarArray[LightBarCounter].YPos := WhereY; + END; + END; + + TempStr := TempStr + AOnOff(ShowScan AND NewScanFileArea,'0'+ScanChar[1],' ')+ + PadLeftStr(PadRightStr('1'+IntToStr(CompFileArea(FArea,0)),5)+ + +'2 '+MemFileArea.AreaName,37)+' '; + Inc(NumOnline); + IF (NumOnLine = 2) THEN + BEGIN + PrintACR(TempStr); + NumOnline := 0; + Inc(NumDone); + TempStr := ''; + END; + Inc(NumFAreas); + END; + WKey; + Inc(FArea); + END; + Close(FileAreaFile); + LastError := IOResult; + IF (NumOnline = 1) AND (NOT Abort) AND (NOT HangUp) THEN + PrintACR(TempStr) + ELSE IF (NumFAreas = 0) AND (NOT Abort) AND (NOT HangUp) THEN + LRGLngStr(67,FALSE); + { + %LF^7No file areas!^1 + } + FileArea := SaveFileArea; + LoadFileArea(FileArea); +END; + +PROCEDURE UnlistedDownload(FileName: AStr); +VAR + User: UserRecordType; + TransferFlags: TransferFlagSet; + DS: DirStr; + NS: NameStr; + ES: ExtStr; + SaveFileArea: Integer; +BEGIN + IF (FileName <> '') THEN + IF (NOT Exist(FileName)) THEN + BEGIN + NL; + Print('File not found.'); + END + ELSE + BEGIN + SaveFileArea := FileArea; + FileArea := -1; + Abort := FALSE; + Next := FALSE; + LoadURec(User,1); + FSplit(FileName,DS,NS,ES); + FindFirst(SQOutSp(FileName),AnyFile - Directory - VolumeID - Hidden - SysFile,DirInfo); + WHILE (DOSError = 0) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + WITH MemFileArea DO + BEGIN + AreaName := 'Unlisted Download'; + DLPath := DS; + ULPath := DS; + FAFlags := [FANoRatio]; + END; + WITH FileInfo DO + BEGIN + FileName := Align(DirInfo.Name); + Description := 'Unlisted Download'; + FilePoints := 0; + Downloaded := 0; + FileSize := DirInfo.Size; + OwnerNum := 1; + OwnerName := Caps(User.Name); + FileDate := Date2PD(DateStr); + VPointer := -1; + VTextSize := 0; + FIFlags := []; + END; + TransferFlags := [IsUnlisted]; + IF (InCom) THEN + BEGIN + NL; + IF (PYNQ('Is this file located on a CDRom? ',0,FALSE)) THEN + Include(MemFileArea.FAFlags,FACDROm); + END; + DLX(FileInfo,-1,TransferFlags); + IF (IsKeyboardAbort IN Transferflags) THEN + Abort := TRUE; + FindNext(DirInfo); + END; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; +END; + +PROCEDURE Do_Unlisted_Download; +VAR + PathFileName: Str52; +BEGIN + NL; + Print('Enter file name to download (d:path\filename.ext)'); + Prt(': '); + MPL(52); + Input(PathFileName,52); + IF (PathFileName = '') THEN + BEGIN + NL; + Print('Aborted.'); + END + ELSE IF (NOT IsUL(PathFileName)) THEN + BEGIN + NL; + Print('You must specify the complete path to the file.'); + END + ELSE + UnlistedDownload(PathFileName) +END; + +END. diff --git a/SOURCE/FILE10.PAS b/SOURCE/FILE10.PAS new file mode 100644 index 0000000..916a0e0 --- /dev/null +++ b/SOURCE/FILE10.PAS @@ -0,0 +1,910 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File10; + +INTERFACE + +USES + Common; + +PROCEDURE CreditFileOwner(VAR User: UserRecordType; VAR FileInfo: FileInfoRecordType; Credit: Boolean; GotPts: Integer); +PROCEDURE EditFile(DirFileRecNum: Integer; VAR Cmd: Char; NoPrompt,IsPoints: Boolean); +PROCEDURE EditFiles; +PROCEDURE ValidateFiles; + +IMPLEMENTATION + +USES + Dos, + ArcView, + Common5, + File0, + File1, + File2, + File9, + Mail1, + SysOp3, + TimeFunc, + MiscUser; + +PROCEDURE CreditFileOwner(VAR User: UserRecordType; VAR FileInfo: FileInfoRecordType; Credit: Boolean; GotPts: Integer); +VAR + FilePointsReceived: Integer; +BEGIN + IF (AllCaps(FileInfo.OwnerName) <> AllCaps(User.Name)) THEN + BEGIN + NL; + Print('^7File owner name does not match user name!^1'); + Exit; + END; + IF (NOT General.FileCreditRatio) THEN + GotPts := 0 + ELSE IF (GotPts = 0) THEN + BEGIN + FilePointsReceived := 0; + IF (General.FileCreditCompBaseSize <> 0) THEN + FilePointsReceived := ((FileInfo.FileSize DIV 1024) DIV General.FileCreditCompBaseSize); + GotPts := (FilePointsReceived * General.FileCreditComp); + IF (GotPts < 1) THEN + GotPts := 1; + END; + NL; + Print(AOnOff(Credit,'^1Awarding upload','^1Removing upload')+' credits:'+ + ' ^51 file'+ + ', '+ConvertKB(FileInfo.FileSize DIV 1024,FALSE)+ + ', '+IntToStr(GotPts)+' file points.^1'); + SysOpLog(AOnOff(Credit,'^1Awarding upload','^1Removing upload')+' credits:'+ + ' ^51 file'+ + ', '+ConvertKB(FileInfo.FileSize DIV 1024,FALSE)+ + ', '+IntToStr(GotPts)+' file points.^1'); + IF (Credit) THEN + BEGIN + IF (User.Uploads < 2147483647) THEN + Inc(User.Uploads); + IF ((User.UK + (FileInfo.FileSize DIV 1024)) < 2147483647) THEN + Inc(User.UK,(FileInfo.FileSize DIV 1024)) + ELSE + User.UK := 2147483647; + IF ((User.FilePoints + GotPts) < 2147483647) THEN + Inc(User.FilePoints,GotPts) + ELSE + User.FilePoints := 2147483647; + Include(FileInfo.FIFlags,FIOwnerCredited); + END + ELSE + BEGIN + IF (User.Uploads > 0) THEN + Dec(User.Uploads); + IF ((User.UK - (FileInfo.FileSize DIV 1024)) > 0) THEN + Dec(User.UK,(FileInfo.FileSize DIV 1024)) + ELSE + User.UK := 0; + IF ((User.FilePoints - GotPts) > 0) THEN + Dec(User.FilePoints,GotPts) + ELSE + User.FilePoints := 0; + Exclude(FileInfo.FIFlags,FIOwnerCredited); + END; + SaveURec(User,FileInfo.OwnerNum); +END; + +PROCEDURE EditFile(DirFileRecNum: Integer; VAR Cmd: Char; NoPrompt,IsPoints: Boolean); +VAR + FF: FILE; + ExtText: Text; + User: UserRecordType; + Mheader: MheaderRec; + InputStr, + MoveFromDir, + MoveToDir: AStr; + LineNum, + NumExtDesc: Byte; + UNum, + NewFileArea, + SaveFileArea, + FArea, + NumFAreas, + Totload, + SaveFArea: Integer; + FSize: Longint; + SaveConfSystem, + SaveTempPause, + DontShowList, + Ok: Boolean; + + PROCEDURE ToggleFIFlag(FIFlagT: FileInfoFlagType; VAR FIFlagS: FIFlagSet); + BEGIN + IF (FIFlagT IN FIFlagS) THEN + Exclude(FIFlagS,FIFlagT) + ELSE + Include(FIFlagS,FIFlagT); + END; + + PROCEDURE ToggleFIFlags(C: Char; VAR FIFlagS: FIFlagSet); + BEGIN + CASE C OF + 'V' : ToggleFIFlag(FiNotVal,FIFlagS); + 'T' : ToggleFIFlag(FiIsRequest,FIFlagS); + 'R' : ToggleFIFlag(FIResumeLater,FIFlagS); + 'H' : ToggleFIFlag(FIHatched,FIFlagS); + END; + END; + +BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + IF (IOResult <> 0) THEN + Exit; + + IF (FileInfo.OwnerNum < 1) OR (FileInfo.OwnerNum > (MaxUsers - 1)) THEN + FileInfo.OwnerNum := 1; + LoadURec(User,FileInfo.OwnerNum); + + IF (IsPoints) THEN + BEGIN + NL; + DisplayFileInfo(FileInfo,TRUE); + NL; + Prt('File points for file (^50^4-^5999^4,^5^4=^5Skip^4,^5Q^4=^5Quit^4): '); + MPL(3); + Input(InputStr,3); + IF (InputStr <> '') THEN + BEGIN + IF (InputStr = 'Q') THEN + BEGIN + NL; + Print('Aborted.'); + Abort := TRUE + END + ELSE IF (StrToInt(InputStr) >= 0) AND (StrToInt(InputStr) <= 999) THEN + BEGIN + FileInfo.FilePoints := StrToInt(InputStr); + Exclude(FileInfo.FIFlags,FINotVal); + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,FileInfo); + + CreditFileOwner(User,FileInfo,TRUE,FileInfo.FilePoints); + + IF (FileInfo.OwnerNum = UserNum) THEN + User.FilePoints := ThisUser.FilePoints; + + NL; + Prt('File points for user (^5-'+IntToStr(User.FilePoints)+'^4 to ^5999^4): '); + MPL(4); + Input(InputStr,4); + IF (InputStr <> '') AND (StrToInt(InputStr) >= -User.FilePoints) AND (StrToInt(InputStr) <= 999) THEN + BEGIN + + Inc(User.FilePoints,StrToInt(InputStr)); + + IF (FileInfo.OwnerNum = UserNum) THEN + ThisUser.FilePoints := User.FilePoints; + + SaveURec(User,FileInfo.OwnerNum); + END; + END; + END; + Exit; + END; + IF (NoPrompt) THEN + BEGIN + Exclude(FileInfo.FIFlags,FINotVal); + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,FileInfo); + CreditFileOwner(User,FileInfo,TRUE,0); + Exit; + END; + DontShowList := FALSE; + REPEAT + Abort := FALSE; + Next := FALSE; + IF (NOT DontShowList) THEN + BEGIN + NL; + DisplayFileInfo(FileInfo,TRUE); + Abort := FALSE; + END + ELSE + DontShowList := FALSE; + NL; + Abort := FALSE; + IF (Next) THEN + Cmd := 'N' + ELSE + BEGIN + Prt('Edit files (^5?^4=^5Help^4): '); + OneK(Cmd,'Q1234567DEGHIMNPRTUVW?'^M,TRUE,TRUE); + END; + CASE Cmd OF + '1' : BEGIN + NL; + Prt('New file name: '); + MPL((SizeOf(FileInfo.FileName) - 1)); + Input(InputStr,(SizeOf(FileInfo.FileName) - 1)); + IF (InputStr = '') THEN + BEGIN + NL; + Print('Aborted.'); + END + ELSE IF (SQOutSp(InputStr) = SQOutSp(FileInfo.FileName)) THEN + BEGIN + NL; + Print('^7You must specify a different file name!^1'); + END + ELSE IF (Exist(MemFileArea.DLPath+InputStr) OR Exist(MemFileArea.ULPath+InputStr)) THEN + BEGIN + NL; + Print('^7That file name exists in the download or upload path!^1'); + END + ELSE + BEGIN + IF (NOT Exist(MemFileArea.DLPath+FileInfo.FileName)) OR + (NOT Exist(MemFileArea.ULPath+FileInfo.FileName)) THEN + BEGIN + NL; + Print('That file name does not exist in the download or upload path.'); + Ok := FALSE; + IF (CoSysOp) THEN + BEGIN + IF (NOT (FIIsRequest IN FileInfo.FIFlagS)) THEN + BEGIN + NL; + IF (PYNQ('Do you want to set this file to offline? ',0,FALSE)) THEN + BEGIN + FileInfo.FileSize := 0; + Include(FileInfo.FIFlagS,FIIsRequest); + END; + END; + NL; + IF (PYNQ('Do you want to rename the file anyway? ', 0,FALSE)) THEN + Ok := TRUE; + END; + END; + + IF (Ok) THEN + BEGIN + IF (Exist(MemFileArea.DLPath+FileInfo.FileName)) THEN + BEGIN + Assign(FF,MemFileArea.DLPath+FileInfo.FileName); + ReName(FF,MemFileArea.DLPath+InputStr); + END + ELSE IF (Exist(MemFileArea.ULPath+FileInfo.FileName)) THEN + BEGIN + Assign(FF,MemFileArea.ULPath+FileInfo.FileName); + ReName(FF,MemFileArea.ULPath+InputStr); + END; + LastError := IOResult; + FileInfo.FileName := Align(InputStr); + END; + + END; + END; + '2' : BEGIN + NL; + Print('Limit on file size restricted to 1.9 Gig.'); + OK := TRUE; + IF (NOT Exist(MemFileArea.DLPath+FileInfo.FileName)) OR (NOT Exist(MemFileArea.ULPath+FileInfo.FileName)) THEN + BEGIN + NL; + IF (PYNQ('File does not exist, set to offline? ',0,FALSE)) THEN + BEGIN + FSize := 0; + Include(FileInfo.FIFlags,FiIsRequest); + OK := FALSE; + END; + END; + IF (Ok) THEN + BEGIN + NL; + IF PYNQ('Update with actual file size? ', 0,FALSE) THEN + BEGIN + FSize := 0; + IF (Exist(MemFileArea.DLPath+FileInfo.FileName)) THEN + FSize := GetFileSize(MemFileArea.DLPath+SQOutSp(FileInfo.FileName)) + ELSE IF (Exist(MemFileArea.ULPath+FileInfo.FileName)) THEN + FSize := GetFileSize(MemFileArea.ULPath+SqOutSp(FileInfo.FileName)); + END + ELSE + BEGIN + FSize := FileInfo.FileSize; + InputLongIntWOC('%LFNew file size in bytes',FSize,[DisplayValue,NumbersOnly],0,2147483647); + END; + END; + IF (FSize >= 0) AND (FSize <= 2147483647) THEN + FileInfo.FileSize := FSize; + END; + '3' : BEGIN + NL; + Print('New description: '); + Prt(': '); + MPL((SizeOf(FileInfo.Description) - 1)); + InputMain(FileInfo.Description,(SizeOf(FileInfo.Description) - 1),[InteractiveEdit]); + END; + '4' : BEGIN + LoadURec(User,FileInfo.OwnerNum); + IF (AllCaps(FileInfo.OwnerName) <> AllCaps(User.Name)) THEN + BEGIN + NL; + Print('Previous owner was '+Caps(FileInfo.OwnerName)+' #'+IntToStr(FileInfo.OwnerNum)); + NL; + LoadURec(User,1); + FileInfo.OwnerNum := 1; + FileInfo.OwnerName := AllCaps(User.Name); + END; + NL; + Print('New owner user number or name ('+Caps(FileInfo.OwnerName)+' #'+IntToStr(FileInfo.OwnerNum)+'): '); + Prt(': '); + MPL((SizeOf(FileInfo.OwnerName) - 1)); + FindUser(UNum); + IF (UNum <= 0) THEN + BEGIN + NL; + Print('User not found.'); + END + ELSE + BEGIN + LoadURec(User,UNum); + FileInfo.OwnerNum := UNum; + FileInfo.OwnerName := AllCaps(User.Name); + END; + END; + '5' : BEGIN + NL; + Prt('New upload file date ('+PD2Date(FileInfo.FileDate)+'): '); + InputFormatted('',InputStr,'##-##-####',TRUE); + IF (InputStr = '') THEN + BEGIN + NL; + Print('Aborted.'); + END + ELSE + BEGIN + IF (DayNum(InputStr) = 0) OR (DayNum(InputStr) > DayNum(DateStr)) THEN + BEGIN + NL; + Print('^7Invalid date entered!^1'); + END + ELSE + FileInfo.FileDate := Date2PD(InputStr); + END; + END; + '6' : InputLongIntWOC('%LFNew number of downloads',FileInfo.DownLoaded,[DisplayValue,NumbersOnly],0,2147483647); + '7' : InputIntegerWOC('%LFNew amount of file points',FileInfo.FilePoints,[NumbersOnly],0,999); + 'D' : IF PYNQ('%LFAre you sure? ',0,FALSE) THEN + BEGIN + Deleteff(FileInfo,DirFileRecNum); + InitFileArea(FileArea); + Dec(LastDIRRecNum); + InputStr := 'Removed "'+SQOutSp(FileInfo.FileName)+'" from '+MemFileArea.AreaName; + IF (Exist(MemFileArea.DLPath+FileInfo.FileName) OR Exist(MemFileArea.ULPath+FileInfo.FileName)) THEN + BEGIN + NL; + IF PYNQ('Erase file also? ',0,FALSE) THEN + BEGIN + Kill(MemFileArea.DLPath+FileInfo.FileName); + Kill(MemFileArea.ULPath+FileInfo.FileName); + InputStr := InputStr+' [FILE DELETED]' + END; + END; + + IF (NOT (FIOwnerCredited IN FileInfo.FIFlags)) THEN + Print('%LF^7Owner did not receive upload credit for this file!^1') + ELSE IF PYNQ('%LFRemove from ^5'+Caps(User.Name)+' #'+IntToStr(FileInfo.OwnerNum)+'^7''s ratio? ',0,FALSE) THEN + CreditFileOwner(User,FileInfo,FALSE,FileInfo.FilePoints); + + SysOpLog(InputStr); + Cmd := 'N'; + END; + 'E' : BEGIN + OK := TRUE; + IF (FileInfo.VPointer <> -1) THEN + BEGIN + IF (NOT PYNQ('%LFDelete the extended description for this file? ',0,FALSE)) THEN + LoadVerbArray(FileInfo,ExtendedArray,NumExtDesc) + ELSE + BEGIN + FileInfo.VPointer := -1; + FileInfo.VTextSize := 0; + OK := FALSE; + END; + END + ELSE + BEGIN + IF (NOT PYNQ('%LFCreate an extended description for this file? ',0,FALSE)) THEN + BEGIN + FileInfo.VPointer := -1; + FileInfo.VTextSize := 0; + OK := FALSE + END + ELSE + BEGIN + FillChar(ExtendedArray,SizeOf(ExtendedArray),0); + NumExtDesc := 1; + END; + END; + IF (Ok) THEN + BEGIN + Assign(ExtText,TempDir+MemFileArea.FileName+'.TMP'); + ReWrite(ExtText); + LineNum := 0; + REPEAT + Inc(LineNum); + IF (ExtendedArray[LineNum] <> '') THEN + WriteLn(ExtText,ExtendedArray[LineNum]); + UNTIL (LineNum = NumExtDesc); + Close(ExtText); + MHeader.Status := []; + InResponseTo := ''; + IF (InputMessage(TRUE,FALSE,'Extended Description', + MHeader,TempDir+MemFileArea.FileName+'.TMP',50,99)) then + IF Exist(TempDir+MemFileArea.FileName+'.TMP') THEN + BEGIN + FillChar(ExtendedArray,SizeOf(ExtendedArray),0); + Assign(ExtText,TempDir+MemFileArea.FileName+'.TMP'); + Reset(ExtText); + NumExtDesc := 0; + REPEAT + ReadLn(ExtText,InputStr); + IF (InputStr <> '') THEN + BEGIN + Inc(NumExtDesc); + ExtendedArray[NumExtDesc] := InputStr; + END; + UNTIL (NumExtDesc = MaxExtDesc) OR EOF(ExtText); + Close(ExtText); + IF (ExtendedArray[1] <> '') THEN + SaveVerbArray(FileInfo,ExtendedArray,NumExtDesc); + END; + Kill(TempDir+MemFileArea.FileName+'.TMP'); + END; + Cmd := #0; + END; + 'G' : IF (NOT General.FileDiz) THEN + Print('%LF^7This option is not active in the System Configuration!^1') + ELSE + BEGIN + IF (Exist(MemFileArea.ULPath+FileInfo.FileName)) THEN + InputStr := MemFileArea.ULPath+SQOutSp(FileInfo.FileName) + ELSE + InputStr := MemFileArea.DLPath+SQOutSp(FileInfo.FileName); + IF (NOT DizExists(InputStr)) THEN + Print('%LFFile has no internal description.') + ELSE + BEGIN + GetDiz(FileInfo,ExtendedArray,NumExtDesc); + IF (ExtendedArray[1] <> '') THEN + SaveVerbArray(FileInfo,ExtendedArray,NumExtDesc) + ELSE + BEGIN + FileInfo.VPointer := -1; + FileInfo.VTextSize := 0; + END; + END; + END; + 'H' : ToggleFIFlags('H',FileInfo.FIFlagS); + 'I' : IF (NOT ValidIntArcType(FileInfo.FileName)) THEN + BEGIN + NL; + Print('^7Not a valid archive type or not supported!^1') + END + ELSE + BEGIN + OK := FALSE; + IF Exist(MemFileArea.DLPath+FileInfo.FileName) THEN + BEGIN + ViewInternalArchive(MemFileArea.DLPath+SQOutSp(FileInfo.FileName)); + OK := TRUE; + END + ELSE IF Exist(MemFileArea.ULPath+FileInfo.FileName) THEN + BEGIN + ViewInternalArchive(MemFileArea.ULPath+SQOutSp(FileInfo.FileName)); + OK := TRUE; + END; + IF (NOT Ok) THEN + BEGIN + NL; + IF (PYNQ('File does not exist, set to offline? ',0,FALSE)) THEN + BEGIN + FileInfo.FileSize := 0; + ToggleFIFlags('T',FileInfo.FIFlagS); + END; + END; + Abort := FALSE; + END; + 'M' : BEGIN + SaveFileArea := FileArea; + SaveConfSystem := ConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + SaveTempPause := TempPause; + TempPause := FALSE; + FArea := 1; + NumFAreas := 0; + LightBarCmd := 1; + LightBarFirstCmd := TRUE; + InputStr := '?'; + REPEAT + SaveFArea := FArea; + IF (InputStr = '?') THEN + LFileAreaList(FArea,NumFAreas,5,FALSE); + { + %LFMove to which file area? (^5'+IntToStr(LowFileArea)+'^4-^5'+IntToStr(HighFileArea)+'^4) + [^5#^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ + } + FileAreaScanInput(LRGLngStr(76,TRUE),Length(IntToStr(HighFileArea)),InputStr,'Q[]?',LowFileArea,HighFileArea); + IF (InputStr <> 'Q') THEN + BEGIN + IF (InputStr = '[') THEN + BEGIN + Farea := (SaveFArea - ((PageLength - 5) * 2)); + IF (FArea < 1) THEN + FArea := 1; + InputStr := '?'; + END + ELSE IF (InputStr = ']') THEN + BEGIN + IF (FArea > NumFileAreas) THEN + FArea := SaveFArea; + InputStr := '?'; + END + ELSE IF (InputStr = '?') THEN + BEGIN + { + $File_Message_Area_List_Help + %LF^1(^3###^1)Manual entry selection ^1(^3^1)Select current entry + ^1(^3^1)First entry on page ^1(^3^1)Last entry on page + ^1(^3Left Arrow^1)Previous entry ^1(^3Right Arrow^1)Next entry + ^1(^3Up Arrow^1)Move up ^1(^3Down Arrow^1)Move down + ^1(^3[^1)Previous page ^1(^3]^1)Next page + %PA + } + LRGLngStr(71,FALSE); + FArea := SaveFArea; + END + ELSE IF (StrToInt(InputStr) < LowFileArea) OR (StrToInt(InputStr) > HighFileArea) THEN + BEGIN + NL; + Print('^7The range must be from '+IntToStr(LowFileArea)+' to '+IntToStr(HighFileArea)+'!^1'); + PauseScr(FALSE); + InputStr := '?'; + FArea := SaveFArea; + END + ELSE IF (StrToInt(InputStr) = FileArea) THEN + BEGIN + NL; + Print('^7You can not move a file to the same file area.^1'); + PauseScr(FALSE); + InputStr := '?'; + FArea := SaveFArea; + END + ELSE + BEGIN + NewFileArea := CompFileArea(StrToInt(InputStr),1); + IF (FileArea <> NewFileArea) THEN + ChangeFileArea(NewFileArea); + IF (FileArea <> NewFileArea) THEN + BEGIN + NL; + Print('^7You do not have access to this file area!^1'); + PauseScr(FALSE); + InputStr := '?'; + FArea := SaveFArea; + END + ELSE + BEGIN + FileArea := SaveFileArea; + LoadFileArea(FileArea); + IF Exist(MemFileArea.DLPath+FileInfo.FileName) THEN + MoveFromDir := MemFileArea.DLPath + ELSE + MoveFromDir := MemFileArea.ULPath; + LoadFileArea(NewFileArea); + MoveToDir := MemFileArea.ULPath; + NL; + IF (NOT PYNQ('Move file to '+MemFileArea.AreaName+'? ',0,FALSE)) THEN + BEGIN + InputStr := '?'; + FArea := SaveFArea; + END + ELSE + BEGIN + OK := TRUE; + IF Exist(MoveToDir+SQoutSp(FileInfo.FileName)) THEN + BEGIN + NL; + Print('^7The file exists in the upload path!^1'); + OK := FALSE; + END + ELSE IF (NOT Exist(MoveFromDir+SQOutSp(FileInfo.FileName))) THEN + BEGIN + NL; + Print('^7The file does not exist in the download path!^1'); + OK := FALSE; + END; + IF (Ok) THEN + BEGIN + NL; + CopyMoveFile(FALSE,'^5Moving file: ', + MoveFromDir+SQOutSp(FileInfo.FileName), + MoveToDir+SQOutSp(FileInfo.FileName), + TRUE); + END; + NL; + Prompt('^5Moving records: '); + FileArea := SaveFileArea; + InitFileArea(FileArea); + IF (BadDownloadPath) THEN + Exit; + IF (FileInfo.VPointer <> -1) THEN + LoadVerbArray(FileInfo,ExtendedArray,NumExtDesc); + Deleteff(FileInfo,DirFileRecNum); + FileArea := NewFileArea; + InitFileArea(FileArea); + IF (BadDownloadPath) THEN + Exit; + IF (FileInfo.VPointer <> - 1) THEN + SaveVerbArray(FileInfo,ExtendedArray,NumExtDesc); + Seek(FileInfoFile,FileSize(FileInfoFile)); + Write(FileInfoFile,FileInfo); + FileArea := SaveFileArea; + InitFileArea(FileArea); + Dec(LastDIRRecNum); + Print('Done!^1'); + Cmd := 'N'; + END; + END; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; + END; + IF (InputStr = 'Q') THEN + Cmd := 'N'; + UNTIL (Cmd = 'N') OR (HangUp); + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + TempPause := SaveTempPause; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; + 'P' : ; + 'Q' : Abort := TRUE; + 'R' : ToggleFIFlags('R',FileInfo.FIFlagS); + 'T' : ToggleFIFlags('T',FileInfo.FIFlagS); + 'U' : IF (NOT CoSysOp) THEN + BEGIN + NL; + Print('^7You do not have the required access level for this option!^1') + END + ELSE + BEGIN + IF (FileInfo.OwnerNum < 1) OR (FileInfo.OwnerNum > (MaxUsers - 1)) THEN + BEGIN + LoadURec(User,1); + FileInfo.OwnerNum := 1; + FileInfo.OwnerName := AllCaps(User.Name); + END; + UserEditor(FileInfo.OwnerNum); + END; + + 'V' : BEGIN + ToggleFIFlags('V',FileInfo.FIFlagS); + + IF (FINotVal IN FileInfo.FIFlags) THEN + BEGIN + IF (NOT (FIOwnerCredited IN FileInfo.FIFlags)) THEN + Print('%LF^7Owner did not receive upload credit for this file!^1') + ELSE + CreditFileOwner(User,FileInfo,FALSE,FileInfo.FilePoints); + END + ELSE + CreditFileOwner(User,FileInfo,TRUE,0); + END; + + 'W' : IF (NOT (FIOwnerCredited IN FileInfo.FIFlags)) THEN + Print('%LF^7Owner did not receive upload credit for this file!^1') + ELSE IF PYNQ('%LFWithdraw credit? ',0,FALSE) THEN + CreditFileOwner(User,FileInfo,FALSE,FileInfo.FilePoints); + + '?' : BEGIN + NL; + Print('^31-7^1:Modify item'); + LCmds(18,3,'Move file','Delete file'); + LCmds(18,3,'Extended edit','Hatched toggle'); + LCmds(18,3,'Previous file','Next file'); + LCmds(18,3,'Resume toggle','Toggle availability'); + LCmds(18,3,'Validation toggle','Withdraw credit'); + LCmds(18,3,'Internal listing','Get Description'); + LCmds(18,3,'Uploader','Quit'); + DontShowList := TRUE; + END; + ^M : Cmd := 'N'; + ELSE + Next := TRUE; + END; + IF (NOT (Cmd IN ['P','N','Q'])) THEN + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,FileInfo); + END; + UNTIL (Cmd IN ['P','N','Q']) OR (Abort) OR (Next) OR (HangUp); +END; + +PROCEDURE EditFiles; +VAR + FileName, + SaveLastDirFileName: Str12; + Cmd: Char; + DirFileRecNum, + SaveLastDirFileRecNum: Integer; + FO: Boolean; +BEGIN + NL; + Print('File editor:'); + { Print(FString.lGFNLine1); } + lRGLngStr(28,FALSE); + { Prt(FString.GFNLine2); } + lRGLngStr(29,FALSE); + GetFileName(FileName); + IF (FileName = '') OR (Pos('.',FileName) = 0) THEN + BEGIN + NL; + Print('Aborted.'); + END + ELSE + BEGIN + SaveLastDirFileRecNum := LastDIRRecNum; + SaveLastDirFileName := LastDIRFileName; + FO := (FileRec(FileInfoFile).Mode <> FMClosed); + IF (FO) THEN + BEGIN + Close(FileInfoFile); + Close(ExtInfoFile); + END; + RecNo(FileInfo,FileName,DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + IF (DirFileRecNum = -1) THEN + BEGIN + NL; + Print('No matching files.'); + END + ELSE + BEGIN + Abort := FALSE; + Next := FALSE; + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + EditFile(DirFileRecNum,Cmd,FALSE,FALSE); + IF (Cmd = 'Q') THEN + Abort := TRUE + ELSE + BEGIN + IF (Cmd = 'P') THEN + LRecNo(FileInfo,DirFileRecNum) + ELSE + NRecNo(FileInfo,DirFileRecNum); + END; + WKey; + END; + END; + Close(FileInfoFile); + Close(ExtInfoFile); + IF (FO) THEN + InitFileArea(FileArea); + LastDIRRecNum := SaveLastDirFileRecNum; + LastDIRFileName := SaveLastDirFileName; + LastCommandOvr := TRUE; + END; + LastError := IOResult; +END; + +PROCEDURE ValidateFiles; +VAR + Cmd: Char; + FArea, + SaveFileArea: Integer; + SaveConfSystem: Boolean; + + PROCEDURE ValFiles(FArea: Integer; Cmd1: Char; NoPrompt,IsPoints: Boolean); + VAR + DirFileRecNum: Integer; + Found, + FirstOne: Boolean; + BEGIN + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + BEGIN + RecNo(FileInfo,'*.*',DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + LIL := 0; + CLS; + Cmd1 := #0; + Found := FALSE; + FirstOne := TRUE; + Prompt('^1Scanning ^5'+MemFileArea.AreaName+' #'+IntToStr(CompFileArea(FileArea,0))+'^1 ...'); + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + IF (FINotVal IN FileInfo.FIFlagS) AND (NOT (FIResumeLater IN FileInfo.FIFlagS)) THEN + BEGIN + IF (FirstOne) THEN + BEGIN + NL; + FirstOne := FALSE; + END; + EditFile(DirFileRecNum,Cmd1,NoPrompt,IsPoints); + Found := TRUE; + END; + IF (Cmd1 = 'P') THEN + BEGIN + REPEAT + LRecNo(FileInfo,DirFileRecNum); + UNTIL (DirFileRecNum = -1) OR ((FINotVal IN FileInfo.FIFlags) AND NOT (FIResumeLater IN FileInfo.FIFlags)); + END + ELSE + NRecNo(FileInfo,DirFileRecNum); + WKey; + END; + IF (NOT Found) THEN + BEGIN + LIL := 0; + BackErase(15 + LennMCI(MemFileArea.AreaName) + Length(IntToStr(CompFileArea(FileArea,0)))); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; + LastError := IOResult; + END; + +BEGIN + NL; + Print('^4[^5M^4]anual, [^5A^4]utomatic, [^5P^4]oint entry, [^5Q^4]uit'); + NL; + Prt('File validation: '); + OneK(Cmd,'QMAP',TRUE,TRUE); + IF (Cmd <> 'Q') THEN + BEGIN + SaveFileArea := FileArea; + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + TempPause := (Cmd <> 'A'); + Abort := FALSE; + Next := FALSE; + NL; + IF (NOT InWFCMenu) AND (NOT PYNQ('Search all file areas? ',0,TRUE)) THEN + ValFiles(FileArea,Cmd,(Cmd = 'A'),(Cmd = 'P')) + ELSE + BEGIN + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + ValFiles(FArea,Cmd,(Cmd = 'A'),(Cmd = 'P')); + WKey; + IF (Next) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + END; + Inc(FArea); + END; + END; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; + LastError := IOResult; +END; + +END. diff --git a/SOURCE/FILE11.PAS b/SOURCE/FILE11.PAS new file mode 100644 index 0000000..43e08b0 --- /dev/null +++ b/SOURCE/FILE11.PAS @@ -0,0 +1,1249 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File11; + +INTERFACE + +USES + Common; + +TYPE + FileRecType = RECORD + FArrayFileArea, + FArrayDirFileRecNum: SmallInt; + END; + + FileArrayType = ARRAY [0..99] OF FileRecType; + +VAR + FArray: FileArrayType; + +FUNCTION CanSee(CONST FileInfo: FileInfoRecordType): Boolean; +FUNCTION GetFileStats(FileInfo: FileInfoRecordType): AStr; +PROCEDURE InitFArray(VAR F: FileArrayType); +PROCEDURE DisplayFileAreaHeader; +PROCEDURE lDisplay_File(FileInfo: FileInfoRecordType; FArrayRecNum: Byte; SearchString: Str20; + NormalPause: Boolean); +PROCEDURE SearchFileSpec; +PROCEDURE ListFileSpec(FName: Str12); +PROCEDURE SearchFileDescriptions; +PROCEDURE GlobalNewFileScan(VAR FArrayRecNum: Byte); +PROCEDURE NewFilesScanSearchType(CONST MenuOption: Str50); +PROCEDURE FileAreaChange(VAR Done: Boolean; CONST MenuOption: Str50); +PROCEDURE CreateTempDir; + +IMPLEMENTATION + +USES + Dos, + Crt, + ArcView, + Common5, + File0, + File1, + File10, + Menus, + TimeFunc; + +TYPE + DownLoadArrayType = ARRAY [0..99] OF SmallInt; + +VAR + DLArray: DownloadArrayType; + Lines, + FileRedisplayLines: Byte; + +PROCEDURE InitFArray(VAR F: FileArrayType); +VAR + Counter: Byte; +BEGIN + FOR Counter := 0 TO 99 DO + WITH F[Counter] DO + BEGIN + FArrayFileArea := -1; + FArrayDirFileRecNum := -1; + END; +END; + +FUNCTION GetDlArray(VAR DLArray: DownLoadArrayType; CmdLen: Byte): Boolean; +VAR + s, + s1, + s2: Str160; + Counter, + Counter1, + Counter2, + Counter3: Byte; + Ok: Boolean; +BEGIN + Ok := TRUE; + FOR Counter := 1 TO (((LennMCI(MemMenu.MenuPrompt) + CmdLen) + 1)) DO + BackSpace; + FOR Counter := 0 TO 99 DO + DLArray[Counter] := -1; + Prt('Enter file number or range (##,##-##): '); + s := ''; + MPL(20); + InputMain(s,20,[NoLineFeed]); + IF (SqOutSp(S) = '') THEN + OK := FALSE + ELSE + BEGIN + FOR Counter := 1 TO Length(S) DO + IF (NOT (S[Counter] IN ['0'..'9','-'])) THEN + Ok := FALSE; + IF (S = '-') OR (S[1] = '-') OR (S[Length(s)] = '-') THEN + OK := FALSE; + IF (Ok) THEN + BEGIN + NL; + s1 := ''; + s2 := ''; + Counter1 := 0; + FOR Counter := 1 TO Length(s) DO + BEGIN + IF s[Counter] IN ['0'..'9'] THEN + s1 := s1 + s[Counter] + ELSE + BEGIN + IF (s[Counter] = '-') THEN + BEGIN + s2 := ''; + FOR Counter2 := (Counter + 1) TO Length(s) DO + BEGIN + IF (s[counter2] IN ['0'..'9']) THEN + s2 := s2 + s[counter2] + ELSE + BEGIN + IF (s1 <> '') AND (StrToInt(s1) >= 0) AND (StrToInt(s1) <= 99) AND + (S2 <> '') AND (StrToInt(s2) >= 0) AND (StrToInt(s2) <= 99) THEN + FOR Counter3 := StrToInt(s1) TO StrToInt(s2) DO + BEGIN + DLArray[Counter1] := Counter3; + Inc(Counter1); + END; + s1 := ''; + Counter := Counter + Length(s2); + s2 := ''; + Counter2 := Length(s); + END; + END; + Counter := Counter + Length(s2); + END + ELSE IF (StrToInt(s1) >= 0) AND (StrToInt(s1) <= 99) THEN + BEGIN + DLArray[Counter1] := StrToInt(s1); + Inc(Counter1); + s1 := ''; + s2 := ''; + END; + END; + END; + IF (Length(s1) <> 0) AND (StrToInt(s1) >= 0) AND (StrToInt(s1) <= 99) THEN + DLArray[Counter1] := StrToInt(s1); + IF (s1 <> '') AND (StrToInt(s1) >= 0) AND (StrToInt(s1) <= 99) AND + (S2 <> '') AND (StrToInt(s2) >= 0) AND (StrToInt(s2) <= 99) THEN + FOR Counter3 := StrToInt(s1) TO StrToInt(s2) DO + BEGIN + DLArray[Counter1] := Counter3; + Inc(Counter1) + END; + END; + END; + IF (NOT OK) THEN + BEGIN + FOR Counter := 1 TO 20 DO + OutKey(' '); + UserColor(1); + FOR Counter := 1 TO (LennMCI(MemMenu.MenuPrompt) + 21) DO + BackSpace; + END; + + GetDLArray := OK; +END; + +PROCEDURE Pause_Files; +VAR + TransferFlags: TransferFlagSet; + CmdStr, + NewMenuCmd: AStr; + SaveLastDirFileName: Str12; + Cmd: Char; + SaveMenu, + Counter, + CmdToExec: Byte; + Counter1, + SaveFileArea, + SaveLastDirFileRecNum: Integer; + Done, + CmdNotHid, + CmdExists, + FO: Boolean; +BEGIN + LIL := 0; + IF (Lines < PageLength) OR (HangUp) THEN + Exit; + Lines := 0; + FileRedisplayLines := 0; + FileAreaNameDisplayed := FALSE; + + SaveMenu := CurMenu; + CurMenu := General.FileListingMenu; + IF (NOT NewMenuToLoad) THEN + LoadMenuPW; + AutoExecCmd('FIRSTCMD'); + REPEAT + MainMenuHandle(CmdStr); + NewMenuCmd := ''; + CmdToExec := 0; + TFilePrompt := 0; + Done := FALSE; + REPEAT + FCmd(CmdStr,CmdToExec,CmdExists,CmdNotHid); + IF (CmdToExec <> 0) AND (MemCmd^[CmdToExec].CmdKeys <> '-^') AND + (MemCmd^[CmdToExec].CmdKeys <> '-/') AND (MemCmd^[CmdToExec].CmdKeys <> '-\') THEN + BEGIN + IF (CmdStr <> '') AND (CmdStr <> 'ENTER') AND (MemCmd^[CmdToExec].CmdKeys <> 'L5') AND + (MemCmd^[CmdToExec].CmdKeys <> 'L6') AND (MemCmd^[CmdToExec].CmdKeys <> 'L7') AND + (MemCmd^[CmdToExec].CmdKeys <> 'L8') THEN + NL; + DoMenuCommand(Done, + MemCmd^[CmdToExec].CmdKeys, + MemCmd^[CmdToExec].Options, + NewMenuCmd, + MemCmd^[CmdToExec].NodeActivityDesc); + END; + UNTIL (CmdToExec = 0) OR (Done) OR (HangUp); + Abort := FALSE; + Next := FALSE; + CASE TFilePrompt OF + 1 : ; + 2 : BEGIN + Print('%LFListing aborted.'); + Abort := TRUE; + END; + 3 : BEGIN + Print('%LFFile area skipped.'); + Next := TRUE; + END; + 4 : BEGIN + Print('%LF^5'+MemFileArea.AreaName+'^3 '+AOnOff(NewScanFileArea,'will NOT','WILL')+ + ' be scanned.'); + LoadNewScanFile(NewScanFileArea); + NewScanFileArea := (NOT NewScanFileArea); + SaveNewScanFile(NewScanFileArea); + END; + 5 : BEGIN + IF GetDLArray(DLArray,Length(CmdStr)) THEN + IF (DLInTime) THEN + IF (NOT BatchDLQueuedFiles([])) THEN + BEGIN + Counter := 0; + WHILE (Counter <= 99) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (DLArray[Counter] <> -1) THEN + IF (FArray[DLArray[Counter]].FArrayDirFileRecNum = -1) THEN + Print('%LF^7Invalid file number selected: "^9'+IntToStr(DLArray[Counter])+'^7".') + ELSE + BEGIN + SaveLastDirFileRecNum := LastDIRRecNum; + SaveLastDirFileName := LastDIRFileName; + FO := (FileRec(FileInfoFile).Mode <> FMClosed); + IF (FO) THEN + BEGIN + Close(FileInfoFile); + Close(ExtInfoFile); + END; + SaveFileArea := FileArea; + FileArea := FArray[DLArray[Counter]].FArrayFileArea; + InitFileArea(FileArea); + Seek(FileInfoFile,FArray[DLArray[Counter]].FArrayDirFileRecNum); + Read(FileInfoFile,FileInfo); + TransferFlags := [IsCheckRatio]; + DLX(FileInfo,FArray[DLArray[Counter]].FArrayDirFileRecNum,TransferFlags); + IF (IsKeyboardAbort IN TransferFlags) THEN + Abort := TRUE; + Close(FileInfoFile); + Close(ExtInfoFile); + FileArea := SaveFileArea; + IF (FO) THEN + InitFileArea(FileArea); + LastDIRRecNum := SaveLastDirFileRecNum; + LastDIRFileName := SaveLastDirFileName; + END; + Inc(Counter); + END; + IF (Abort) THEN + Abort := FALSE; + NL; + END; + END; + 6 : BEGIN + IF GetDLArray(DLArray,Length(CmdStr)) THEN + IF (DLInTime) THEN + BEGIN + Counter := 0; + WHILE (Counter <= 99) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (DLArray[Counter] <> -1) THEN + IF (FArray[DLArray[Counter]].FArrayDirFileRecNum = -1) THEN + Print('%LF^7Invalid file number selected: "^9'+IntToStr(DLArray[Counter])+'^7".') + ELSE + BEGIN + SaveLastDirFileRecNum := LastDIRRecNum; + SaveLastDirFileName := LastDIRFileName; + FO := (FileRec(FileInfoFile).Mode <> FMClosed); + IF (FO) THEN + BEGIN + Close(FileInfoFile); + Close(ExtInfoFile); + END; + SaveFileArea := FileArea; + FileArea := FArray[DLArray[Counter]].FArrayFileArea; + InitFileArea(FileArea); + Seek(FileInfoFile,FArray[DLArray[Counter]].FArrayDirFileRecNum); + Read(FileInfoFile,FileInfo); + TransferFlags := [IsCheckRatio,lIsAddDLBatch]; + DLX(FileInfo,FArray[DLArray[Counter]].FArrayDirFileRecNum,TransferFlags); + IF (IsKeyboardAbort IN TransferFlags) THEN + Abort := TRUE; + Close(FileInfoFile); + Close(ExtInfoFile); + FileArea := SaveFileArea; + IF (FO) THEN + InitFileArea(FileArea); + LastDIRRecNum := SaveLastDirFileRecNum; + LastDIRFileName := SaveLastDirFileName; + END; + Inc(Counter); + END; + IF (Abort) THEN + Abort := FALSE; + NL; + END; + END; + 7 : BEGIN + IF GetDLArray(DLArray,Length(CmdStr)) THEN + BEGIN + Counter := 0; + WHILE (Counter <= 99) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (DLArray[Counter] <> -1) THEN + IF (FArray[DLArray[Counter]].FArrayDirFileRecNum = -1) THEN + Print('%LF^7Invalid file number selected: "^9'+IntToStr(DLArray[Counter])+'^7".') + ELSE + BEGIN + SaveLastDirFileRecNum := LastDIRRecNum; + SaveLastDirFileName := LastDIRFileName; + FO := (FileRec(FileInfoFile).Mode <> FMClosed); + IF (FO) THEN + BEGIN + Close(FileInfoFile); + Close(ExtInfoFile); + END; + SaveFileArea := FileArea; + FileArea := FArray[DLArray[Counter]].FArrayFileArea; + InitFileArea(FileArea); + Seek(FileInfoFile,FArray[DLArray[Counter]].FArrayDirFileRecNum); + Read(FileInfoFile,FileInfo); + IF (NOT ValidIntArcType(FileInfo.FileName)) THEN + Print('%LF'+SQOutSp(FileInfo.FileName)+' is not a valid archive type or not supported.') + ELSE + BEGIN + IF Exist(MemFileArea.DLPath+FileInfo.FileName) THEN + ViewInternalArchive(MemFileArea.DLPath+SQOutSp(FileInfo.FileName)) + ELSE IF Exist(MemFileArea.ULPath+FileInfo.FileName) THEN + ViewInternalArchive(MemFileArea.ULPath+SQOutSp(FileInfo.FileName)); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + FileArea := SaveFileArea; + IF (FO) THEN + InitFileArea(FileArea); + LastDIRRecNum := SaveLastDirFileRecNum; + LastDIRFileName := SaveLastDirFileName; + END; + Inc(Counter); + END; + IF (Abort) THEN + Abort := FALSE; + NL; + END; + END; + 8 : IF (NOT FileSysop) THEN + BEGIN + NL; + Print('%LFYou do not have the required access level for this option.'); + NL; + END + ELSE + BEGIN + IF GetDLArray(DLArray,Length(CmdStr)) THEN + BEGIN + Counter := 0; + WHILE (Counter <= 99) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (DLArray[Counter] <> -1) THEN + IF (FArray[DLArray[Counter]].FArrayDirFileRecNum = -1) THEN + Print('%LF^7Invalid file number selected: "^9'+IntToStr(DLArray[Counter])+'^7".') + ELSE + BEGIN + SaveLastDirFileRecNum := LastDIRRecNum; + SaveLastDirFileName := LastDIRFileName; + FO := (FileRec(FileInfoFile).Mode <> FMClosed); + IF (FO) THEN + BEGIN + Close(FileInfoFile); + Close(ExtInfoFile); + END; + SaveFileArea := FileArea; + FileArea := FArray[DLArray[Counter]].FArrayFileArea; + InitFileArea(FileArea); + Seek(FileInfoFile,FArray[DLArray[Counter]].FArrayDirFileRecNum); + Read(FileInfoFile,FileInfo); + EditFile(FArray[DLArray[Counter]].FArrayDirFileRecNum,Cmd,FALSE,FALSE); + IF (Cmd = 'Q') THEN + Abort := TRUE + ELSE IF (Cmd = 'P') THEN + BEGIN + Counter1 := Counter; + IF (Counter1 > 0) THEN + BEGIN + IF (DLArray[Counter1] <> -1) THEN + IF (FArray[DLArray[Counter1]].FArrayDirFileRecNum <> -1) THEN + Counter := (Counter1 - 1); + Dec(Counter1); + END; + Dec(Counter); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + FileArea := SaveFileArea; + IF (FO) THEN + InitFileArea(FileArea); + LastDIRRecNum := SaveLastDirFileRecNum; + LastDIRFileName := SaveLastDirFileName; + END; + Inc(Counter); + END; + IF (Abort) THEN + Abort := FALSE; + IF (Next) THEN + Next := FALSE; + IF (Cmd <> 'Q') THEN + NL; + END; + END; + END; + UNTIL (TFilePrompt = 1) OR (Abort) OR (Next) OR (HangUp); + IF (TFilePrompt = 1) AND (NOT Abort) AND (NOT Next) AND (NOT HangUp) THEN + NL; + CurMenu := SaveMenu; + NewMenuToLoad := TRUE; +END; + +FUNCTION CanSee(CONST FileInfo: FileInfoRecordType): Boolean; +BEGIN + CanSee := (NOT (FINotVal IN FileInfo.FIFlags)) OR (UserNum = FileInfo.OwnerNum) OR (AACS(General.SeeUnVal)); +END; + +PROCEDURE Output_File_Stuff(CONST s: AStr); +BEGIN + IF (TextRec(NewFilesF).Mode = FMOutPut)THEN + BEGIN + WriteLn(NewFilesF,StripColor(s)); + Lines := 0; + END + ELSE + PrintACR(s+'^1'); +END; + +PROCEDURE DisplayFileAreaHeader; +BEGIN + IF (FileAreaNameDisplayed) THEN + Exit; + Lil := 0; + Lines := 0; + FileRedisplayLines := 0; + (* + CLS; + IF (NOT General.FileCreditRatio) THEN + BEGIN + Output_File_Stuff(' Ŀ'); + Output_File_Stuff('  ##  File Name   Size   Description '+PadLeftStr(s,34)+'  '); + Output_File_Stuff(' '); + END + ELSE + BEGIN + Output_File_Stuff(' Ŀ'); + Output_File_Stuff('  ##  File Name  Pts  Size   Description '+PadLeftStr(s,34)+'  '); + Output_File_Stuff(' '); + END; + *) + + IF (NOT General.FileCreditRatio) THEN + lRGLngStr(63,FALSE) + ELSE + lRGLngStr(64,FALSE); + Inc(Lines,LIL); + Inc(FileRedisplayLines,LIL); + + FileAreaNameDisplayed := TRUE; +END; + +FUNCTION GetFileStats(FileInfo: FileInfoRecordType): AStr; +BEGIN + IF (FIIsRequest IN FileInfo.FIFlags) THEN + GetFileStats := ' Offline' + ELSE IF (FIResumeLater IN FileInfo.FIFlags) THEN + GetFileStats := ' ResLatr' + ELSE IF (FINotVal IN FileInfo.FIFlags) THEN + GetFileStats := ' Unvalid' + ELSE IF (NOT General.FileCreditRatio) THEN + GetFileStats := ''+PadRightStr(ConvertBytes(FileInfo.FileSize,TRUE),10) + ELSE + GetFileStats := ''+PadRightInt(FileInfo.FilePoints,3)+' '+PadRightStr(ConvertKB(FileInfo.FileSize DIV 1024,TRUE),6); +END; + +PROCEDURE lDisplay_File(FileInfo: FileInfoRecordType; FArrayRecNum: Byte; SearchString: Str20; + NormalPause: Boolean); +VAR + TempStr, + TempStr1, + TempStr2: AStr; + LineNum, + NumExtDesc: Byte; + + FUNCTION SubStone(SrcStr,OldStr,NewStr: AStr; IsCaps: Boolean): AStr; + VAR + StrPos: Byte; + BEGIN + IF (OldStr <> '') THEN + BEGIN + IF (IsCaps) THEN + NewStr := AllCaps(NewStr); + StrPos := Pos(AllCaps(OldStr),AllCaps(SrcStr)); + IF (StrPos > 0) THEN + BEGIN + Insert(NewStr,SrcStr,(StrPos + Length(OldStr))); + Delete(SrcStr,StrPos,Length(OldStr)); + END; + END; + SubStone := SrcStr; + END; + +BEGIN + TempStr := AOnOff(DayNum(PD2Date(FileInfo.FileDate)) >= DayNum(PD2Date(NewFileDate)),'*',' ')+ + ''+PadRightInt(FArrayRecNum,2); + + TempStr1 := FileInfo.FileName; + IF (SearchString <> '') THEN + TempStr1 := SubStone(TempStr1,SearchString,''+AllCaps(SearchString)+'',TRUE); + TempStr := TempStr + ' '+TempStr1+' '+GetFileStats(FileInfo)+''; + + TempStr2 := TempStr; + + TempStr1 := FileInfo.Description; + IF (SearchString <> '') THEN + TempStr1 := SubStone(TempStr1,SearchString,''+AllCaps(SearchString)+'',TRUE); + IF (LennMCI(TempStr1) > 50) THEN + TempStr1 := Copy(TempStr1,1,Length(TempStr1) - (LennMCI(TempStr1) - 50)); + TempStr := TempStr + ' '+TempStr1; + + + IF (NOT NormalPause) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + DisplayFileAreaHeader; + + Inc(Lines); + + IF (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + Output_File_Stuff(TempStr); + IF (NOT NormalPause) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + Pause_Files; + + IF (FileInfo.VPointer <> -1) THEN + BEGIN + LoadVerbArray(FileInfo,ExtendedArray,NumExtDesc); + LineNum := 1; + WHILE (LineNum <= NumExtDesc) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + TempStr1 := ExtendedArray[LineNum]; + IF (SearchString <> '') THEN + TempStr1 := SubStone(TempStr1,SearchString,''+AllCaps(SearchString)+'',TRUE); + + IF (Lines = FileRedisplayLines) THEN + TempStr := TempStr2 + ' '+TempStr1+'' + ELSE + TempStr := PadLeftStr('',28)+''+TempStr1+''; + + IF (NOT NormalPause) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + DisplayFileAreaHeader; + + Inc(Lines); + + IF (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + Output_File_Stuff(TempStr); + + IF (NOT NormalPause) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + Pause_Files; + Inc(LineNum); + END; + END; + + TempStr := ''; + IF (FAShowName IN MemFileArea.FAFlags) THEN + IF (Lines = FileRedisplayLines) THEN + TempStr := TempStr2 + ' Uploaded by '+Caps(FileInfo.OwnerName) + ELSE + TempStr := TempStr + PadLeftStr('',28)+'Uploaded by '+Caps(FileInfo.OwnerName); + + IF (FAShowDate IN MemFileArea.FAFlags) THEN + BEGIN + IF (TempStr = '') THEN + IF (Lines = FileRedisplayLines) THEN + TempStr := TempStr2 + ' Uploaded' + ELSE + TempStr := PadLeftStr('',28)+'Uploaded'; + TempStr := TempStr +' on '+PD2Date(FileInfo.FileDate); + IF (Length(TempStr) > 78) THEN + TempStr := Copy(TempStr,1,78); + END; + + IF (FAShowName IN MemFileArea.FAFlags) OR (FAShowDate IN MemFileArea.FAFlags) THEN + BEGIN + + IF (NOT NormalPause) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + DisplayFileAreaHeader; + + Inc(Lines); + + IF (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + Output_File_Stuff(TempStr); + IF (NOT NormalPause) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + Pause_Files; + END; + + IF (FIResumeLater IN FileInfo.FIFlags) AND (FileInfo.OwnerNum = UserNum) AND NOT (TextRec(NewFilesF).Mode = FMOutPut) THEN + BEGIN + IF (Lines = FileRedisplayLines) THEN + TempStr := TempStr2 + ' ^8>^7'+'>> ^3'+'You ^5'+'MUST RESUME^3'+' this file to receive credit' + ELSE + TempStr := PadLeftStr('',28)+'^8>^7'+'>> ^3'+'You ^5'+'MUST RESUME^3'+' this file to receive credit'; + + IF (NOT NormalPause) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + DisplayFileAreaHeader; + + Inc(Lines); + + IF (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + Output_File_Stuff(TempStr); + IF (NOT NormalPause) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) THEN + Pause_Files; + END; +END; + +PROCEDURE SearchFileAreaSpec(FArea: Integer; FName: Str12; VAR FArrayRecNum: Byte); +VAR + DirFileRecNum: Integer; + Found: Boolean; +BEGIN + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + BEGIN + RecNo(FileInfo,FName,DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + Found := FALSE; + LIL := 0; + CLS; + Prompt('^1Scanning ^5'+MemFileArea.AreaName+' #'+IntToStr(CompFileArea(FArea,0))+'^1 ...'); + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + IF (CanSee(FileInfo)) THEN + BEGIN + + WITH FArray[FArrayRecNum] DO + BEGIN + FArrayFileArea := FileArea; + FArrayDirFileRecNum := DirFileRecNum; + END; + + DisplayFileAreaHeader; + lDisplay_File(FileInfo,FArrayRecNum,'',FALSE); + + Inc(FArrayRecNum); + IF (FArrayRecNum = 100) THEN + FArrayRecNum := 0; + + Found := TRUE; + END; + NRecNo(FileInfo,DirFileRecNum); + IF (DirFileRecNum = -1) AND (Found) AND (Lines > FileRedisplayLines) AND (NOT Abort) AND (NOT HangUp) THEN + BEGIN + Lines := PageLength; + Pause_Files; + END; + END; + IF (NOT Found) THEN + BEGIN + LIL := 0; + BackErase(15 + LennMCI(MemFileArea.AreaName) + Length(IntToStr(CompFileArea(FArea,0)))); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; +END; + +PROCEDURE SearchFileSpec; +VAR + FName: Str12; + FArrayRecNum: Byte; + FArea, + SaveFileArea: Integer; + SaveConfSystem: Boolean; +BEGIN + NL; + { Print(FString.SearchLine); } + lRGLngStr(20,FALSE); + { Print(FString.lGFNLine1); } + lRGLngStr(28,FALSE); + { Prt(FString.GFNLine2); } + lRGLngStr(29,FALSE); + FName := ''; + GetFileName(FName); + IF (FName = '') THEN + BEGIN + Print('%LFAborted.'); + Exit; + END; + SaveFileArea := FileArea; + Abort := FALSE; + Next := FALSE; + InitFArray(FArray); + FArrayRecNum := 0; + SaveConfSystem := ConfSystem; + ConfSystem := NOT PYNQ('%LFSearch all conferences? ',0,TRUE); + IF (ConfSystem <> SaveConfSystem) THEN + NewCompTables; + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + SearchFileAreaSpec(FArea,FName,FArrayRecNum); + WKey; + Inc(FArea); + END; + IF (ConfSystem <> SaveConfSystem) THEN + BEGIN + ConfSystem := SaveConfSystem; + NewCompTables; + END; + FileArea := SaveFileArea; + LoadFileArea(FileArea); +END; + +PROCEDURE ListFileSpec(FName: Str12); +VAR + FArrayRecNum: Byte; +BEGIN + Abort := FALSE; + Next := FALSE; + InitFArray(FArray); + FArrayRecNum := 0; + IF (FName = '') THEN + BEGIN + NL; + { Print(FString.ListLine); } + lRGLngStr(18,FALSE); + { Print(FString.lGFNLine1); } + lRGLngStr(28,FALSE); + { Prt(FString.GFNLine2); } + lRGLngStr(29,FALSE); + GetFileName(FName); + END + ELSE + FName := Align(FName); + SearchFileAreaSpec(FileArea,FName,FArrayRecNum); +END; + +PROCEDURE SearchFileAreaDescription(FArea: Integer; SearchString: Str20; VAR FArrayRecNum: Byte); +VAR + LineNum, + NumExtDesc: Byte; + DirFileRecNum: Integer; + SearchStringFound, + Found: Boolean; +BEGIN + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + BEGIN + RecNo(FileInfo,'*.*',DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + Found := FALSE; + LIL := 0; + CLS; + Prompt('^1Scanning ^5'+MemFileArea.AreaName+' #'+IntToStr(CompFileArea(FArea,0))+'^1 ...'); + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + IF (CanSee(FileInfo)) THEN + BEGIN + SearchStringFound := ((Pos(SearchString,AllCaps(FileInfo.Description)) <> 0) OR + (Pos(SearchString,AllCaps(FileInfo.FileName)) <> 0)); + IF (NOT SearchStringFound) AND (FileInfo.VPointer <> -1) THEN + BEGIN + LoadVerbArray(FileInfo,ExtendedArray,NumExtDesc); + LineNum := 1; + WHILE (LineNum <= NumExtDesc) AND (NOT SearchStringFound) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (Pos(SearchString,AllCaps(ExtendedArray[LineNum])) <> 0) THEN + SearchStringFound := TRUE; + Inc(LineNum); + END; + END; + IF (SearchStringFound) THEN + BEGIN + + WITH FArray[FArrayRecNum] DO + BEGIN + FArrayFileArea := FileArea; + FArrayDirFileRecNum := DirFileRecNum; + END; + + DisplayFileAreaHeader; + + lDisplay_File(FileInfo,FArrayRecNum,SearchString,FALSE); + + Inc(FArrayRecNum); + IF (FArrayRecNum = 100) THEN + FArrayRecNum := 0; + + Found := TRUE; + END; + END; + NRecNo(FileInfo,DirFileRecNum); + IF (DirFileRecNum = -1) AND (Found) AND (Lines > FileRedisplayLines) AND (NOT Abort) AND (NOT HangUp) THEN + BEGIN + Lines := PageLength; + Pause_Files; + END; + END; + IF (NOT Found) THEN + BEGIN + LIL := 0; + BackErase(15 + LennMCI(MemFileArea.AreaName) + Length(IntToStr(CompFileArea(FArea,0)))); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; +END; + +PROCEDURE SearchFileDescriptions; +VAR + SearchString: Str20; + FArrayRecNum: Byte; + FArea, + SaveFileArea: Integer; + SaveConfSystem: Boolean; +BEGIN + NL; + { Print(FString.FindLine1); } + lRGLngStr(21,FALSE); + NL; + { Print(FString.FindLine2); } + lRGLngStr(22,FALSE); + Prt(': '); + MPL(20); + Input(SearchString,20); + IF (SearchString = '') THEN + BEGIN + Print('%LFAborted.'); + Exit; + END; + Abort := FALSE; + Next := FALSE; + InitFArray(FArray); + FArrayRecNum := 0; + Print('%LFSearching for "'+SearchString+'"'); + IF (NOT PYNQ('%LFSearch all file areas? ',0,FALSE)) THEN + SearchFileAreaDescription(FileArea,SearchString,FArrayRecNum) + ELSE + BEGIN + SaveFileArea := FileArea; + SaveConfSystem := ConfSystem; + ConfSystem := NOT PYNQ('%LFSearch all conferences? ',0,TRUE); + IF (ConfSystem <> SaveConfSystem) THEN + NewCompTables; + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + SearchFileAreaDescription(FArea,SearchString,FArrayRecNum); + WKey; + Inc(FArea); + END; + IF (ConfSystem <> SaveConfSystem) THEN + BEGIN + ConfSystem := SaveConfSystem; + NewCompTables; + END; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; +END; + +PROCEDURE NewFileScan(FArea: Integer; Global: Boolean; VAR FArrayRecNum: Byte); +VAR + DirFileRecNum: Integer; + Found: Boolean; +BEGIN + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + BEGIN + RecNo(FileInfo,'*.*',DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + IF (NOT Global) OR (NewScanFileArea) THEN + BEGIN + Found := FALSE; + LIL := 0; + CLS; + Prompt('^1Scanning ^5'+MemFileArea.AreaName+' #'+IntToStr(CompFileArea(FileArea,0))+'^1 ...'); + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + + IF ((CanSee(FileInfo)) AND (DayNum(PD2Date(FileInfo.FileDate)) >= DayNum(PD2Date(NewFileDate)))) + OR (CanSee(FileInfo) AND (FINotVal IN FileInfo.FIFlags)) THEN + BEGIN + + WITH FArray[FArrayRecNum] DO + BEGIN + FArrayFileArea := FileArea; + FArrayDirFileRecNum := DirFileRecNum; + END; + + DisplayFileAreaHeader; + lDisplay_File(FileInfo,FArrayRecNum,'',FALSE); + + Inc(FArrayRecNum); + IF (FArrayRecNum = 100) THEN + FArrayRecNum := 0; + + Found := TRUE; + END; + NRecNo(FileInfo,DirFileRecNum); + IF (DirFileRecNum = -1) AND (Found) AND (Lines > FileRedisplayLines) AND (NOT Abort) AND (NOT HangUp) THEN + BEGIN + Lines := PageLength; + Pause_Files; + END; + END; + IF (NOT Found) THEN + BEGIN + LIL := 0; + BackErase(15 + LennMCI(MemFileArea.AreaName) + Length(IntToStr(CompFileArea(FArea,0)))); + END; + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; +END; + +PROCEDURE GlobalNewFileScan(VAR FArrayRecNum: Byte); +VAR + FArea: Integer; +BEGIN + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + NewFileScan(FArea,TRUE,FArrayRecNum); + IF (TextRec(NewFilesF).Mode = FMOutPut) THEN + Output_File_Stuff(''); + WKey; + Inc(FArea); + END; +END; + +PROCEDURE NewFilesScanSearchType(CONST MenuOption: Str50); +VAR + FArrayRecNum: Byte; + SaveFileArea: Integer; +BEGIN + SaveFileArea := FileArea; + Abort := FALSE; + Next := FALSE; + InitFArray(FArray); + FArrayRecNum := 0; + IF (UpCase(MenuOption[1]) = 'C') THEN + NewFileScan(FileArea,FALSE,FArrayRecNum) + ELSE IF (UpCase(MenuOption[1]) = 'G') THEN + GlobalNewFileScan(FArrayRecNum) + ELSE IF (StrToInt(MenuOption) <> 0) THEN + NewFileScan(StrToInt(MenuOption),FALSE,FArrayRecNum) + ELSE + BEGIN + { + NL; + Print('|03List Files - |11P |03to Pause'); + NL; + } + lRGLngStr(19,FALSE); + + IF PYNQ('%LFSearch all file areas? ',0,FALSE) THEN + GlobalNewFileScan(FArrayRecNum) + ELSE + NewFileScan(FileArea,FALSE,FArrayRecNum); + END; + FileArea := SaveFileArea; + LoadFileArea(FileArea); +END; + +PROCEDURE FileAreaChange(VAR Done: Boolean; CONST MenuOption: Str50); +VAR + InputStr: Str5; + Cmd: Char; + FArea, + SaveFArea, + NumFAreas: Integer; + SaveTempPause: Boolean; +BEGIN + IF (MenuOption <> '') THEN + CASE Upcase(MenuOption[1]) OF + '+' : BEGIN + FArea := FileArea; + IF (FileArea >= NumFileAreas) THEN + FArea := 0 + ELSE + REPEAT + Inc(FArea); + ChangeFileArea(FArea); + UNTIL ((FileArea = FArea) OR (FArea >= NumFileAreas)); + IF (FileArea <> FArea) THEN + BEGIN + { + %LFHighest accessible file area. + %PA + } + LRGLngStr(83,FALSE); + END + ELSE + LastCommandOvr := TRUE; + END; + '-' : BEGIN + FArea := FileArea; + IF (FileArea <= 0) THEN + FArea := 0 + ELSE + REPEAT + Dec(FArea); + ChangeFileArea(FArea); + UNTIL ((FileArea = FArea) OR (FArea <= 0)); + IF (FileArea <> FArea) THEN + BEGIN + { + %LFLowest accessible file area. + %PA + } + LRGLngStr(82,FALSE); + END + ELSE + LastCommandOvr := TRUE; + END; + 'L' : BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + FArea := 1; + NumFAreas := 0; + Cmd := '?'; + REPEAT + SaveFArea := FArea; + IF (Cmd = '?') THEN + LFileAreaList(FArea,NumFAreas,5,FALSE); + { + %LFFile area list? [^5#^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ + } + LOneK(LRGLngStr(70,TRUE),Cmd,'Q[]?',TRUE,TRUE); + TempPause := FALSE; + IF (Cmd <> 'Q') THEN + BEGIN + IF (Cmd = '[') THEN + BEGIN + Farea := (SaveFArea - ((PageLength - 5) * 2)); + IF (FArea < 1) THEN + FArea := 1; + Cmd := '?'; + END + ELSE IF (Cmd = ']') THEN + BEGIN + IF (FArea > NumFileAreas) THEN + FArea := SaveFArea; + Cmd := '?'; + END + ELSE IF (Cmd = '?') THEN + BEGIN + { + $File_Message_Area_List_Help + %LF^1(^3###^1)Manual entry selection ^1(^3^1)Select current entry + ^1(^3^1)First entry on page ^1(^3^1)Last entry on page + ^1(^3Left Arrow^1)Previous entry ^1(^3Right Arrow^1)Next entry + ^1(^3Up Arrow^1)Move up ^1(^3Down Arrow^1)Move down + ^1(^3[^1)Previous page ^1(^3]^1)Next page + %PA + } + LRGLngStr(71,FALSE); + FArea := SaveFArea; + END + END; + UNTIL (Cmd = 'Q') OR (HangUp); + TempPause := SaveTempPause; + LastCommandOvr := TRUE; + END; + ELSE + BEGIN + IF (StrToInt(MenuOption) > 0) THEN + BEGIN + FArea := StrToInt(MenuOption); + IF (FArea <> FileArea) THEN + ChangeFileArea(FArea); + IF (Pos(';',MenuOption) > 0) THEN + BEGIN + CurMenu := StrToInt(Copy(MenuOption,(Pos(';',MenuOption) + 1),Length(MenuOption))); + NewMenuToLoad := TRUE; + Done := TRUE; + END; + LastCommandOvr := TRUE; + END; + END; + END + ELSE + BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + FArea := 1; + NumFAreas := 0; + + LightBarCmd := 1; + LightBarFirstCmd := TRUE; + + InputStr := '?'; + REPEAT + SaveFArea := FArea; + IF (InputStr = '?') THEN + lFileAreaList(FArea,NumFAreas,5,FALSE); + { + %LFChange file area? [^5#^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ + } + FileAreaScanInput(LRGLngStr(72,TRUE),Length(IntToStr(HighFileArea)),InputStr,'Q[]?',LowFileArea,HighFileArea); + IF (InputStr <> 'Q') THEN + BEGIN + IF (InputStr = '[') THEN + BEGIN + Farea := (SaveFArea - ((PageLength - 5) * 2)); + IF (FArea < 1) THEN + FArea := 1; + InputStr := '?'; + END + ELSE IF (InputStr = ']') THEN + BEGIN + IF (FArea > NumFileAreas) THEN + FArea := SaveFArea; + InputStr := '?'; + END + ELSE IF (InputStr = '?') THEN + BEGIN + { + $File_Message_Area_List_Help + %LF^1(^3###^1)Manual entry selection ^1(^3^1)Select current entry + ^1(^3^1)First entry on page ^1(^3^1)Last entry on page + ^1(^3Left Arrow^1)Previous entry ^1(^3Right Arrow^1)Next entry + ^1(^3Up Arrow^1)Move up ^1(^3Down Arrow^1)Move down + ^1(^3[^1)Previous page ^1(^3]^1)Next page + %PA + } + LRGLngStr(71,FALSE); + FArea := SaveFArea; + END + ELSE IF (StrToInt(InputStr) < LowFileArea) OR (StrToInt(InputStr) > HighFileArea) THEN + BEGIN + { + %LF^7The range must be from %A1 to %A2!^1 + } + LRGLngStr(78,FALSE); + FArea := SaveFArea; + InputStr := '?'; + END + ELSE + BEGIN + FArea := CompFileArea(StrToInt(InputStr),1); + IF (FArea <> FileArea) THEN + ChangeFileArea(FArea); + IF (FArea = FileArea) THEN + InputStr := 'Q' + ELSE + BEGIN + { + %LF^7You do not have access to this file area!^1 + } + LRGLngStr(80,FALSE); + FArea := SaveFArea; + InputStr := '?'; + END; + END; + END; + UNTIL (InputStr = 'Q') OR (HangUp); + TempPause := SaveTempPause; + LastCommandOvr := TRUE; + END; +END; + +PROCEDURE CreateTempDir; +VAR + TempPath: Str40; + Changed: Boolean; +BEGIN + TempPath := ''; + InputPath('%LF^4Enter file path for temporary directory (^5End with a ^4"^5\^4"):%LF^4:',TempPath,TRUE,TRUE,Changed); + IF (TempPath = '') THEN + BEGIN + Print('%LFAborted.'); + Exit; + END; + IF (NOT ExistDir(TempPath)) THEN + BEGIN + Print('%LFThat directory does not exist.'); + Exit; + END; + FillChar(TempMemFileArea,SizeOf(TempMemFileArea),0); + WITH TempMemFileArea DO + BEGIN + AreaName := '<< Temporary >>'; + FileName := 'TEMPFILE'; + DLPath := TempPath; + ULPath := TempPath; + MaxFiles := 2000; + Password := ''; + ArcType := 1; + CmtType := 1; + ACS := 's'+IntToStr(ThisUser.SL)+'d'+IntToStr(ThisUser.DSL); + ULACS := ACS; + DLACS := ACS; + FAFlags := []; + END; + FileArea := (NumFileAreas + 1); + LoadFileArea(FileArea); + SysOpLog('Created temporary directory #'+IntToStr(FileArea)+' in "'+TempPath+'"'); +END; + +END. diff --git a/SOURCE/FILE12.PAS b/SOURCE/FILE12.PAS new file mode 100644 index 0000000..85009d5 --- /dev/null +++ b/SOURCE/FILE12.PAS @@ -0,0 +1,963 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File12; + +INTERFACE + +USES + Common; + +FUNCTION CheckBatchUL(FileName: Str12): Boolean; +PROCEDURE EditBatchULQueue; +PROCEDURE ListBatchULFiles; +PROCEDURE RemoveBatchULFiles; +PROCEDURE ClearBatchULQueue; +PROCEDURE BatchUpload(BiCleanUp: Boolean; TransferTime: LongInt); +PROCEDURE BatchDLULInfo; + +IMPLEMENTATION + +USES + Dos, + Common5, + ExecBat, + File0, + File1, + File2, + File4, + TimeFunc; + +FUNCTION CheckBatchUL(FileName: Str12): Boolean; +VAR + RecNum: LongInt; + FileFound: Boolean; +BEGIN + FileFound := FALSE; + IF (NumBatchULFiles > 0) THEN + BEGIN + Assign(BatchULFile,General.DataPath+'BATCHUL.DAT'); + Reset(BatchULFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchULFile)) AND (NOT FileFound) DO + BEGIN + Seek(BatchULFile,(RecNum - 1)); + Read(BatchULFile,BatchUL); + IF (BatchUL.BULUserNum = UserNum) AND (BatchUL.BULFileName = SQOutSp(FileName)) THEN + FileFound := TRUE; + Inc(RecNum); + END; + Close(BatchULFile); + LastError := IOResult; + END; + CheckBatchUL := FileFound; +END; + +PROCEDURE EditBatchULQueue; +VAR + Cmd: Char; +BEGIN + IF (NumBatchULFiles = 0) THEN + BEGIN + NL; + Print('The batch upload queue is empty.'); + Exit; + END; + REPEAT + NL; + Prt('Batch upoad queue [^5C^4]lear, [^5L^4]ist batch, [^5R^4]emove a file, [^5Q^4]uit: '); + OneK(Cmd,'QCLR',TRUE,TRUE); + CASE Cmd OF + 'C' : ClearBatchULQueue; + 'L' : ListBatchULFiles; + 'R' : RemoveBatchULFiles; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +PROCEDURE ListBatchULFiles; +VAR + TempStr: STRING; + FileNumToList: Byte; + TempBULVTextSize: Integer; + RecNum: LongInt; +BEGIN + IF (NumBatchULFiles = 0) THEN + BEGIN + NL; + Print('The batch upload queue is empty.'); + Exit; + END; + Abort := FALSE; + Next := FALSE; + NL; + PrintACR('^4###:Filename.Ext Area Description^1'); + PrintACR('^4===:============:=====:==================================================^1'); + Assign(BatchULFile,General.DataPath+'BATCHUL.DAT'); + Reset(BatchULFile); + Assign(BatchULF,General.DataPath+'BATCHUL.EXT'); + Reset(BatchULF,1); + FileNumToList := 1; + RecNum := 1; + WHILE (RecNum <= FileSize(BatchULFile)) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(BatchULFile,(RecNum - 1)); + Read(BatchULFile,BatchUL); + IF (BatchUL.BULUserNum = UserNum) THEN + BEGIN + PrintACR('^3'+PadRightInt(FileNumToList,3)+ + '^4:^5'+Align(BatchUL.BULFileName)+ + ' '+AOnOff((BatchUL.BULSection = General.ToSysOpDir),'^7SysOp',PadRightInt(BatchUL.BULSection,5))+ + ' ^3'+BatchUL.BULDescription); + IF (BatchUL.BULVPointer <> -1) THEN + BEGIN + TempBULVTextSize := 0; + Seek(BatchULF,(BatchUL.BULVPointer - 1)); + REPEAT + BlockRead(BatchULF,TempStr[0],1); + BlockRead(BatchULF,TempStr[1],Ord(TempStr[0])); + Inc(TempBULVTextSize,(Length(TempStr) + 1)); + PrintACR('^3'+PadRightStr(TempStr,24)+'^1'); + UNTIL (TempBULVTextSize >= BatchUL.BULVTextSize); + END; + Inc(FileNumToList); + END; + WKey; + Inc(RecNum); + END; + Close(BatchULFile); + Close(BatchULF); + LastError := IOResult; + PrintACR('^4===:============:=====:==================================================^1'); + SysOpLog('Viewed the batch upload queue.'); +END; + +PROCEDURE RemoveBatchULFiles; +VAR + BatchULF1: FILE; + BatchUL1: BatchULRecordType; + TempStr: STRING; + InputStr: Str3; + Counter, + FileNumToRemove: Byte; + TotLoad: Integer; + TempVPointer, + RecNum, + RecNum1: LongInt; +BEGIN + IF (NumBatchULFiles = 0) THEN + BEGIN + NL; + Print('The batch upload queue is empty.'); + Exit; + END; + InputStr := '?'; + REPEAT + IF (InputStr = '?') THEN + ListBatchULFiles; + NL; + Prt('File to remove? (^51^4-^5'+IntToStr(NumBatchULFiles)+'^4) [^5?^4=^5List^4,^5^4=^5Quit^4]: '); + MPL(Length(IntToStr(NumBatchULFiles))); + ScanInput(InputStr,^M'?'); + FileNumToRemove := StrToInt(InputStr); + IF (NOT (InputStr[1] IN ['?','-',^M])) THEN + IF (FileNumToRemove < 1) OR (FileNumToRemove > NumBatchULFiles) THEN + BEGIN + NL; + Print('^7The range must be from 1 to '+IntToStr(NumBatchULFiles)+'!^1'); + InputStr := '?'; + END + ELSE + BEGIN + Counter := 0; + Assign(BatchULFile,General.DataPath+'BATCHUL.DAT'); + Reset(BatchULFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchULFile)) DO + BEGIN + Seek(BatchULFile,(RecNum - 1)); + Read(BatchULFile,BatchUL); + IF (BatchUL.BULUserNum = UserNum) THEN + BEGIN + Inc(Counter); + IF (Counter = FileNumToRemove) THEN + BEGIN + BatchUL.BULVPointer := -1; + BatchUL.BULVTextSize := 0; + Seek(BatchULFile,(RecNum - 1)); + Write(BatchULFile,BatchUL); + Dec(NumBatchULFiles); + NL; + Print('Removed from batch upload queue: "^5'+BatchUL.BULFileName+'^1".'); + SysOpLog('Batch UL Remove: "^5'+BatchUL.BULFileName+'^1".'); + + Assign(BatchULF,General.DataPath+'BATCHUL.EXT'); + Reset(BatchULF,1); + Assign(BatchULF1,General.DataPath+'BATCHUL.EX1'); + ReWrite(BatchULF1,1); + FOR RecNum1 := 0 TO (FileSize(BatchULFile) - 1) DO + BEGIN + Seek(BatchULFile,RecNum1); + Read(BatchULFile,BatchUL1); + IF (BatchUL1.BULVPointer <> -1) THEN + BEGIN + TempVPointer := (FileSize(BatchULF1) + 1); + Seek(BatchULF1,FileSize(BatchULF1)); + TotLoad := 0; + Seek(BatchULF,(BatchUL1.BULVPointer - 1)); + REPEAT + BlockRead(BatchULF,TempStr[0],1); + BlockRead(BatchULF,TempStr[1],Ord(TempStr[0])); + Inc(TotLoad,(Length(TempStr) + 1)); + BlockWrite(BatchULF1,TempStr,(Length(TempStr) + 1)); + UNTIL (TotLoad >= BatchUL1.BULVTextSize); + BatchUL1.BULVPointer := TempVPointer; + Seek(BatchULFile,RecNum1); + Write(BatchULFile,BatchUL1); + END; + END; + Close(BatchULF); + Erase(BatchULF); + Close(BatchULF1); + ReName(BatchULF1,General.DataPath+'BATCHUL.EXT'); + + Dec(RecNum); + FOR RecNum1 := RecNum TO (FileSize(BatchULFile) - 2) DO + BEGIN + Seek(BatchULFile,(RecNum1 + 1)); + Read(BatchULFile,BatchUL); + Seek(BatchULFile,RecNum1); + Write(BatchULFile,BatchUL); + END; + Seek(BatchULFile,(FileSize(BatchULFile) - 1)); + Truncate(BatchULFile); + END; + END; + Inc(RecNum); + END; + Close(BatchULFile); + LastError := IOResult; + IF (NumBatchULFiles <> 0) THEN + BEGIN + NL; + Print('^1Batch upload queue: ^5'+IntToStr(NumBatchULFiles)+' '+Plural('file',NumBatchULFiles)); + END + ELSE + BEGIN + NL; + Print('The batch upload queue is now empty.'); + SysOpLog('Cleared the batch upload queue.'); + END; + END; + UNTIL (InputStr <> '?') OR (HangUp); +END; + +PROCEDURE ClearBatchULQueue; +VAR + BatchULF1: FILE; + BatchUL1: BatchULRecordType; + TempStr: STRING; + TotLoad: Integer; + TempVPointer, + RecNum, + RecNum1: LongInt; +BEGIN + IF (NumBatchULFiles = 0) THEN + BEGIN + NL; + Print('The batch upload queue is empty.'); + Exit; + END; + NL; + IF PYNQ('Clear batch upload queue? ',0,FALSE) THEN + BEGIN + NL; + Assign(BatchULFile,General.DataPath+'BATCHUL.DAT'); + Reset(BatchULFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchULFile)) DO + BEGIN + Seek(BatchULFile,(RecNum - 1)); + Read(BatchULFile,BatchUL); + IF (BatchUL.BULUserNum = UserNum) THEN + BEGIN + BatchUL.BULVPointer := -1; + BatchUL.BULVTextSize := 0; + Seek(BatchULFile,(RecNum - 1)); + Write(BatchULFile,BatchUL); + Dec(NumBatchULFiles); + + Assign(BatchULF,General.DataPath+'BATCHUL.EXT'); + Reset(BatchULF,1); + Assign(BatchULF1,General.DataPath+'BATCHUL.EX1'); + ReWrite(BatchULF1,1); + FOR RecNum1 := 0 TO (FileSize(BatchULFile) - 1) DO + BEGIN + Seek(BatchULFile,RecNum1); + Read(BatchULFile,BatchUL1); + IF (BatchUL1.BULVPointer <> -1) THEN + BEGIN + TempVPointer := (FileSize(BatchULF1) + 1); + Seek(BatchULF1,FileSize(BatchULF1)); + TotLoad := 0; + Seek(BatchULF,(BatchUL1.BULVPointer - 1)); + REPEAT + BlockRead(BatchULF,TempStr[0],1); + BlockRead(BatchULF,TempStr[1],Ord(TempStr[0])); + Inc(TotLoad,(Length(TempStr) + 1)); + BlockWrite(BatchULF1,TempStr,(Length(TempStr) + 1)); + UNTIL (TotLoad >= BatchUL1.BULVTextSize); + BatchUL1.BULVPointer := TempVPointer; + Seek(BatchULFile,RecNum1); + Write(BatchULFile,BatchUL1); + END; + END; + Close(BatchULF); + Erase(BatchULF); + Close(BatchULF1); + ReName(BatchULF1,General.DataPath+'BATCHUL.EXT'); + + Print('Removed from batch upload queue: "^5'+BatchUL.BULFileName+'^1".'); + SysOpLog('Batch UL Remove: "^5'+BatchUL.BULFileName+'^1".'); + + Dec(RecNum); + FOR RecNum1 := RecNum TO (FileSize(BatchULFile) - 2) DO + BEGIN + Seek(BatchULFile,(RecNum1 + 1)); + Read(BatchULFile,BatchUL); + Seek(BatchULFile,RecNum1); + Write(BatchULFile,BatchUL); + END; + Seek(BatchULFile,(FileSize(BatchULFile) - 1)); + Truncate(BatchULFile); + END; + Inc(RecNum); + END; + Close(BatchULFile); + LastError := IOResult; + NL; + Print('The batch upload queue is now empty.'); + SysOpLog('Cleared the batch upload queue.'); + END; +END; + +PROCEDURE BatchUpload(BiCleanUp: Boolean; TransferTime: LongInt); +TYPE + TotalsRecordType = RECORD + FilesUL, + FilesULCredit: Byte; + BytesUL, + BytesULCredit, + PointsULCredit: LongInt; + END; +VAR + Totals: TotalsRecordType; + BatchUL1: BatchULRecordType; + BatchULF1: FILE; + (* + DirInfo: SearchRec; + *) + TempStr: STRING; + InputStr: AStr; + LineNum, + FileNumToList, + NumExtDesc: Byte; + TotLoad, + ReturnCode, + ProtocolNumber, + SaveFArea, + SaveFileArea, + NumFAreas, + FArea, + TempBULVTextSize: Integer; + TempVPointer, + RecNum, + RecNum1, + RefundTime, + TakeAwayRefundTime, + TotConversionTime: LongInt; + AutoLogOff, + AHangUp, + WentToSysOp, + SaveTempPause, + SaveConfSystem: Boolean; + + PROCEDURE UpFile; + VAR + GotPts: Integer; + ConversionTime: LongInt; + ArcOk, + Convt: Boolean; + BEGIN + InitFileArea(FileArea); + + ArcStuff(ArcOk,Convt,FileInfo.FileSize,ConversionTime,TRUE,TempDir+'UP\',FileInfo.FileName,FileInfo.Description); + + Inc(TotConversionTime,ConversionTime); + + UpdateFileInfo(FileInfo,FileInfo.FileName,GotPts); + + IF (ArcOk) THEN + BEGIN + + NL; + Star('Moving file to ^5'+MemFileArea.AreaName); + NL; + IF CopyMoveFile(FALSE,'',SQOutSp(TempDir+'UP\'+FileInfo.FileName), + SQOutSp(MemFileArea.ULPath+FileInfo.FileName),FALSE) THEN + BEGIN + + IF (Totals.FilesULCredit < 255) THEN + Inc(Totals.FilesULCredit); + + IF ((Totals.BytesULCredit + FileInfo.FileSize) < 2147483647) THEN + Inc(Totals.BytesULCredit,FileInfo.FileSize) + ELSE + Totals.BytesULCredit := 2147483647; + + IF ((Totals.PointsULCredit + GotPts) < 2147483647) THEN + Inc(Totals.PointsULCredit,GotPts) + ELSE + Totals.PointsULCredit := 2147483647; + + IF (AACS(General.ULValReq)) OR (General.ValidateAllFiles) THEN + Include(FileInfo.FIFlags,FIOwnerCredited); + + WriteFV(FileInfo,FileSize(FileInfoFile),ExtendedArray); + + Star(SQOutSp(FileInfo.FileName)+' successfully uploaded.'); + + SysOpLog('^3Batch uploaded: "^5'+SQOutSp(FileInfo.FileName)+'^3" to ^5'+MemFileArea.AreaName+'.'); + + END; + + END + ELSE + BEGIN + Star('Upload not received.'); + + IF ((FileInfo.FileSize DIV 1024) >= General.MinResume) THEN + BEGIN + NL; + IF PYNQ('Save file for a later resume? ',0,TRUE) THEN + BEGIN + NL; + IF CopyMoveFile(FALSE,'^5Progress: ',TempDir+'UP\'+FileInfo.FileName,MemFileArea.ULPath+FileInfo.FileName,TRUE) THEN + BEGIN + Include(FileInfo.FIFlags,FIResumeLater); + WriteFV(FileInfo,FileSize(FileInfoFile),ExtendedArray); + END; + + END; + END; + + IF (NOT (FIResumeLater IN FileInfo.FIFlags)) THEN + Kill(TempDir+'UP\'+FileInfo.FileName); + + SysOpLog('^3Errors batch uploading '+SQOutSp(FileInfo.FileName)+' - '+ + AOnOff(FIResumeLater IN FileInfo.FIFlags,'file saved for resume','file deleted')); + END; + + IF (NOT ArcOk) AND (NOT BiCleanUp) THEN + BEGIN + + Inc(TakeAwayRefundTime,(FileInfo.FileSize DIV Rate)); + + Star('Time refund of '+FormattedTime(FileInfo.FileSize DIV Rate)+' will be taken away.'); + + END; + END; + +BEGIN + + IF (NOT CheckDriveSpace('Batch upload',MemFileArea.ULPath,General.MinSpaceForUpload)) THEN + Exit; + + SaveFileArea := FileArea; + + AutoLogOff := FALSE; + + IF (BiCleanUp) THEN + RefundTime := 0 + ELSE + BEGIN + + NL; + Print('^5Batch upload (Statistics):^1'); + NL; + Star('^1Total file(s) : ^5'+FormatNumber(NumBatchULFiles)+'^1'); + + IF (NumBatchULFiles = 0) THEN + BEGIN + PrintF('BATCHUL0'); + IF (NoFile) THEN + BEGIN + NL; + Print('Warning! No upload batch files specified yet.'); + Print('If you continue, and batch upload files, you will have to'); + Print('enter file descriptions for each file after the batch upload'); + Print('is complete.'); + END; + END + ELSE + BEGIN + PrintF('BATCHUL'); + IF (NoFile) THEN + BEGIN + NL; + Print('^1If you batch upload files IN ADDITION to the files already'); + Print('specified in your upload batch queue, you must enter file'); + Print('descriptions for them after the batch upload is complete.'); + END; + END; + + ProtocolNumber := DoProtocol(Protocol,TRUE,FALSE,TRUE,FALSE); + CASE ProtocolNumber OF + -1 : ; + -2 : Exit; + -3 : ; + -4 : ; + -5 : EditBatchULQueue; + ELSE + IF (InCom) THEN + BEGIN + PurgeDir(TempDir+'UP\',FALSE); + + NL; + AutoLogOff := PYNQ('Auto-logoff after file transfer? ',0,FALSE); + + NL; + Star('Ready to receive batch upload transfer.'); + + TimeLock := TRUE; + + ExecProtocol('', + TempDir+'UP\', + FunctionalMCI(Protocol.EnvCmd,'','') + +#13#10+ + General.ProtPath+FunctionalMCI(Protocol.ULCmd,'',''), + -1, + ReturnCode, + TransferTime); + + TimeLock := FALSE; + + NL; + Star('Batch upload transfer complete.'); + + RefundTime := (TransferTime * (General.ULRefund DIV 100)); + + Inc(FreeTime,RefundTime); + END; + END; + + END; + + Assign(BatchULFile,General.DataPath+'BATCHUL.DAT'); + Reset(BatchULFile); + + FillChar(Totals,SizeOf(Totals),0); + + FindFirst(TempDir+'UP\*.*',AnyFile - Directory - VolumeID - Dos.Hidden - SysFile ,DirInfo); + WHILE (DosError = 0) DO + BEGIN + Inc(Totals.FilesUL); + Inc(Totals.BytesUL,DirInfo.Size); + FindNext(DirInfo); + END; + + IF (Totals.FilesUL = 0) THEN + BEGIN + NL; + Print('No uploads detected!^1'); + Exit; + END; + + AHangUp := FALSE; + + IF (HangUp) THEN + BEGIN + IF (ComPortSpeed > 0) THEN + BEGIN + lStatus_Screen(100,'Hanging up and taking phone off hook...',FALSE,InputStr); + DoPhoneHangUp(FALSE); + DoPhoneOffHook(FALSE); + ComPortSpeed := 0; + END; + HangUp := FALSE; + AHangUp := TRUE; + END; + + IF (NOT AHangUp) THEN + BEGIN + NL; + Print('^5Batch upload (Totals):^1'); + NL; + Star('^1Total file(s) : ^5'+FormatNumber(Totals.FilesUL)+'^1'); + Star('^1Total size : ^5'+ConvertBytes(Totals.BytesUL,FALSE)+'^1'); + Star('^1Upload time : ^5'+FormattedTime(TransferTime)+'^1'); + Star('^1Transfer rate : ^5'+FormatNumber(GetCPS(Totals.BytesUL,TransferTime))+' cps^1'); + Star('^1Time refund : ^5'+FormattedTime(RefundTime)+'^1'); + IF (AutoLogOff) THEN + CountDown; + END; + + TotConversionTime := 0; + TakeAwayRefundTime := 0; + + RecNum := 1; + WHILE (RecNum <= FileSize(BatchULFile)) DO + BEGIN + Seek(BatchULFile,(RecNum - 1)); + Read(BatchULFile,BatchUL); + IF (BatchUL.BULUserNum = UserNum) AND Exist(TempDir+'UP\'+BatchUL.BULFileName) THEN + BEGIN + FileInfo.FileName := BatchUL.BULFileName; + FileArea := BatchUL.BULSection; + NL; + Star('Found: "^5'+FileInfo.FileName+'^1"'); + IF (General.FileDiz) AND (DizExists(TempDir+'UP\'+FileInfo.FileName)) THEN + GetDiz(FileInfo,ExtendedArray,NumExtDesc) + ELSE + BEGIN + FileInfo.Description := BatchUL.BULDescription; + FillChar(ExtendedArray,SizeOf(ExtendedArray),#0); + IF (BatchUL.BULVPointer <> 0) THEN + BEGIN + Assign(BatchULF,General.DataPath+'BATCHUL.EXT'); + Reset(BatchULF,1); + LineNum := 1; + TempBULVTextSize := 0; + Seek(BatchULF,(BatchUL.BULVPointer - 1)); + REPEAT + BlockRead(BatchULF,TempStr[0],1); + BlockRead(BatchULF,TempStr[1],Ord(TempStr[0])); + Inc(TempBULVTextSize,(Length(TempStr) + 1)); + ExtendedArray[LineNum] := TempStr; + Inc(LineNum); + UNTIL (TempBULVTextSize >= BatchUL.BULVTextSize); + BatchUL.BULVPointer := -1; + BatchUL.BULVTextSize := 0; + Seek(BatchULFile,(RecNum - 1)); + Write(BatchULFile,BatchUL); + END; + END; + UpFile; + Reset(BatchULF,1); + Assign(BatchULF1,General.DataPath+'BATCHUL.EX1'); + ReWrite(BatchULF1,1); + FOR RecNum1 := 0 TO (FileSize(BatchULFile) - 1) DO + BEGIN + Seek(BatchULFile,RecNum1); + Read(BatchULFile,BatchUL1); + IF (BatchUL1.BULVPointer <> -1) THEN + BEGIN + TempVPointer := (FileSize(BatchULF1) + 1); + Seek(BatchULF1,FileSize(BatchULF1)); + TotLoad := 0; + Seek(BatchULF,(BatchUL1.BULVPointer - 1)); + REPEAT + BlockRead(BatchULF,TempStr[0],1); + BlockRead(BatchULF,TempStr[1],Ord(TempStr[0])); + Inc(TotLoad,(Length(TempStr) + 1)); + BlockWrite(BatchULF1,TempStr,(Length(TempStr) + 1)); + UNTIL (TotLoad >= BatchUL1.BULVTextSize); + BatchUL1.BULVPointer := TempVPointer; + Seek(BatchULFile,RecNum1); + Write(BatchULFile,BatchUL1); + END; + END; + Close(BatchULF); + Erase(BatchULF); + Close(BatchULF1); + ReName(BatchULF1,General.DataPath+'BATCHUL.EXT'); + Dec(RecNum); + IF (RecNum >= 0) AND (RecNum <= (FileSize(BatchULFile) - 2)) THEN + FOR RecNum1 := RecNum TO (FileSize(BatchULFile) - 2) DO + BEGIN + Seek(BatchULFile,(RecNum1 + 1)); + Read(BatchULFile,BatchUL); + Seek(BatchULFile,RecNum1); + Write(BatchULFile,BatchUL); + END; + Seek(BatchULFile,(FileSize(BatchULFile) - 1)); + Truncate(BatchULFile); + Dec(NumBatchULFiles); + END; + Inc(RecNum); + END; + + FindFirst(TempDir+'UP\*.*',AnyFile - Directory - VolumeID - Dos.Hidden - SysFile,DirInfo); + WHILE (DosError = 0) DO + BEGIN + FileInfo.FileName := DirInfo.Name; + NL; + Star('Found: "^5'+FileInfo.FileName+'^1"'); + + IF (General.SearchDup) THEN + IF (NOT FileSysOp) OR (PYNQ('Search for duplicates? ',0,FALSE)) THEN + IF (SearchForDups(FileInfo.FileName)) THEN + Exit; + + IF (General.SearchDup) AND (SearchForDups(FileInfo.FileName)) THEN + BEGIN + Star('Deleting duplicate file: "^5'+FileInfo.FileName+'^1"'); + Kill(TempDir+'UP\'+FileInfo.FileName); + END + ELSE + BEGIN + WentToSysOp := FALSE; + IF (General.FileDiz) AND (DizExists(TempDir+'UP\'+FileInfo.FileName)) THEN + GetDiz(FileInfo,ExtendedArray,NumExtDesc) + ELSE + BEGIN + GetFileDescription(FileInfo,ExtendedArray,NumExtDesc,WentToSysOp); + IF (AHangUp) THEN + BEGIN + FileInfo.Description := 'Not in upload batch queue - hungup after transfer'; + FillChar(ExtendedArray,SizeOf(ExtendedArray),#0); + END; + END; + + IF (WentToSysOp) THEN + FileArea := General.ToSysOpDir + ELSE + BEGIN + IF (AHangUp) THEN + FArea := SaveFileArea + ELSE + BEGIN + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + SaveTempPause := TempPause; + TempPause := FALSE; + FArea := 1; + NumFAreas := 0; + LightBarCmd := 1; + LightBarFirstCmd := TRUE; + InputStr := '?'; + REPEAT + SaveFArea := FArea; + IF (InputStr = '?') THEN + LFileAreaList(FArea,NumFAreas,5,FALSE); + + FileAreaScanInput('%LFMove to which file area? (^5'+IntToStr(LowFileArea)+'^4-^5'+IntToStr(HighFileArea)+'^4)'+ + ' [^5?^4=^5First^4,^5^4=^5Next^4]: ',Length(IntToStr(HighFileArea)),InputStr,'[]?', + LowFileArea,HighFileArea); + + IF (InputStr = '[') THEN + BEGIN + FArea := (SaveFArea - ((PageLength - 5) * 2)); + IF (FArea < 1) THEN + FArea := 1; + InputStr := '?'; + END + ELSE IF (InputStr = ']') THEN + BEGIN + IF (FArea > NumFileAreas) THEN + FArea := SaveFArea; + InputStr := '?'; + END + ELSE IF (InputStr = '?') THEN + BEGIN + NL; + Print('^1(^3###^1)Manual entry selection ^1(^3^1)Select current entry'); + Print('^1(^3^1)First entry on page ^1(^3^1)Last entry on page'); + Print('^1(^3Left Arrow^1)Previous entry ^1(^3Right Arrow^1)Next entry'); + Print('^1(^3Up Arrow^1)Move up ^1(^3Down Arrow^1)Move down'); + Print('^1(^3[^1)Previous page ^1(^3]^1)Next page'); + PauseScr(FALSE); + FArea := SaveFArea; + END + ELSE IF (StrToInt(InputStr) < LowFileArea) OR (StrToInt(InputStr) > HighFileArea) THEN + BEGIN + NL; + Print('^7The range must be from '+IntToStr(LowFileArea)+' to '+IntToStr(HighFileArea)+'!^1'); + InputStr := '?'; + FArea := 1 + END + ELSE + BEGIN + FArea := CompFileArea(StrToInt(InPutStr),1); + IF (FArea <> FileArea) THEN + ChangeFileArea(FArea); + IF (FArea <> FileArea) THEN + BEGIN + NL; + Print('^7You do not have access to this file area.^1'); + InputStr := '?'; + FArea := 1 + END + ELSE + BEGIN + InitFileArea(FArea); + IF (NOT AACS(MemFileArea.ULACS)) THEN + BEGIN + NL; + Print('^7You do not have the required upload access for this file area.^1'); + InputStr := '?'; + FArea := 1 + END + ELSE IF ((NOT FileSysOp) AND (Exist(MemFileArea.ULPath+FileInfo.FileName)) OR + (Exist(MemFileArea.DLPath+FileInfo.FileName))) THEN + BEGIN + NL; + Print('^7The file already exists in the upload or download path.^1'); + InputStr := '?'; + FArea := 1 + END + ELSE IF (FileSize(FileInfoFile) >= MemFileArea.MaxFiles) THEN + BEGIN + NL; + Print('^7This file area is full.^1'); + InputStr := '?'; + FArea := 1 + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; + END; + UNTIL (NOT (InputStr[1] IN [^M,'?'])) OR (HangUp); + TempPause := SaveTempPause; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + END; + FileArea := FArea; + END; + UpFile; + END; + FindNext(DirInfo); + END; + + lil := 0; + + Dec(RefundTime,TakeAwayRefundTime); + + Dec(FreeTime,TakeAwayRefundTime); + + SysOpLog('^3 - Totals:'+ + ' '+FormatNumber(Totals.FilesUL)+' '+Plural('file',Totals.FilesUL)+ + ', '+ConvertBytes(Totals.BytesUL,FALSE)+ + ', '+FormattedTime(TransferTime)+' tt'+ + ', '+FormatNumber(GetCPS(Totals.BytesUL,Transfertime))+' cps'+ + ', '+FormattedTime(RefundTime)+' rt'); + + IF ((UploadsToday + Totals.FilesULCredit) < 2147483647) THEN + Inc(UploadsToday,Totals.FilesULCredit) + ELSE + UploadsToday := 2147483647; + + IF ((UploadKBytesToday + (Totals.BytesULCredit DIV 1024)) < 2147483647) THEN + Inc(UploadKBytesToday,(Totals.BytesULCredit DIV 1024)) + ELSE + UploadKBytesToday := 2147483647; + + LIL := 0; + + NL; + Print('^5Batch upload (Credits):^1'); + NL; + Star('^1Total file(s) : ^5'+FormatNumber(Totals.FilesULCredit)); + Star('^1Total size : ^5'+ConvertBytes(Totals.BytesULCredit,FALSE)); + Star('^1Total file points : ^5'+FormatNumber(Totals.PointsULCredit)); + Star('^1Time refund : ^5'+FormattedTime(RefundTime)+'^1'); + + IF (AACS(General.ULValReq)) OR (General.ValidateAllFiles) THEN + BEGIN + + IF ((ThisUser.Uploads + Totals.FilesULCredit) < 2147483647) THEN + Inc(ThisUser.Uploads,Totals.FilesULCredit) + ELSE + ThisUser.Uploads := 2147483647; + + IF (ThisUser.UK + (Totals.BytesULCredit DIV 1024) < 2147483647) THEN + Inc(ThisUser.UK,(Totals.BytesULCredit DIV 1024)) + ELSE + ThisUser.UK := 2147483647; + + IF ((ThisUser.FilePoints + Totals.PointsULCredit) < 2147483647) THEN + Inc(ThisUser.FilePoints,Totals.PointsULCredit) + ELSE + ThisUser.FilePoints := 2147483647; + + END + ELSE + BEGIN + NL; + Print('^5You will receive upload credit after the SysOp validates the '+Plural('file',Totals.FilesULCredit)+'!'); + Totals.FilesULCredit := 0; + Totals.BytesULCredit := 0; + Totals.PointsULCredit := 0; + END; + + IF (ChopTime <> 0) THEN + BEGIN + ChopTime := ((ChopTime + RefundTime) - TakeAwayRefundTime); + FreeTime := ((FreeTime - RefundTime) + TakeAwayRefundTime); + NL; + Star('You will receive your time refund after the event.'); + RefundTime := 0; + END; + + SysOpLog('^3 - Credits:'+ + ' '+FormatNumber(Totals.FilesULCredit)+' '+Plural('file',Totals.FilesULCredit)+ + ', '+ConvertBytes(Totals.BytesULCredit,FALSE)+ + ', '+FormatNumber(Totals.PointsULCredit)+' fp'+ + ', '+FormattedTime(RefundTime)+' rt'); + + IF (NumBatchULFiles > 0) THEN + BEGIN + LIL := 0; + NL; + Print('^5Batch upload (Not Transferred):^1'); + NL; + Star('^1Total file(s) : ^5'+FormatNumber(NumBatchULFiles)); + SysOpLog('^3 - Not uploaded:'+ + ' '+FormatNumber(NumBatchULFiles)+' '+Plural('file',NumBatchULFiles)); + END; + + LIL := 0; + + NL; + Star('Thanks for the '+Plural('file',Totals.FilesULCredit)+', '+Caps(ThisUser.Name)+'!'); + PauseScr(False); + + SaveURec(ThisUser,UserNum); + + Close(BatchULFile); + + IF (AHangUp) THEN + BEGIN + lStatus_Screen(100,'Hanging up phone again...',FALSE,InputStr); + DoPhoneHangUp(FALSE); + HangUp := TRUE; + END; + + FileArea := SaveFileArea; + InitFileArea(FileArea); +END; + +PROCEDURE BatchDLULInfo; +BEGIN + IF (NumBatchDLFiles <> 0) THEN + BEGIN + NL; + Print('^9>> ^3You have ^5'+FormatNumber(NumBatchDLFiles)+'^3 '+Plural('file',NumBatchDLFiles)+ + ' left in your batch download queue.^1'); + END; + IF (NumBatchULFiles <> 0) THEN + BEGIN + NL; + Print('^9>> ^3You have ^5'+FormatNumber(NumBatchULFiles)+'^3 '+Plural('file',NumBatchULFiles)+ + ' left in your batch upload queue.^1'); + END; +END; + +END. + diff --git a/SOURCE/FILE13.PAS b/SOURCE/FILE13.PAS new file mode 100644 index 0000000..afb2f13 --- /dev/null +++ b/SOURCE/FILE13.PAS @@ -0,0 +1,128 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File13; + +INTERFACE + +PROCEDURE Sort; + +IMPLEMENTATION + +USES + Common, + File0; + +PROCEDURE SortDir(NumFiles: Word); +VAR + FileInfo1: FileInfoRecordType; + NumSorted, + RecNum, + RecNum1, + Gap: Word; +BEGIN + Gap := NumFiles; + REPEAT; + Gap := (Gap DIV 2); + IF (Gap = 0) THEN + Gap := 1; + NumSorted := 0; + FOR RecNum := 1 TO (NumFiles - Gap) DO + BEGIN + RecNum1 := (RecNum + Gap); + Seek(FileInfoFile,(RecNum - 1)); + Read(FileInfoFile,FileInfo); + Seek(FileInfoFile,(RecNum1 - 1)); + Read(FileInfoFile,FileInfo1); + IF (FileInfo.FileName > FileInfo1.FileName) THEN + BEGIN + Seek(FileInfoFile,(RecNum - 1)); + Write(FileInfoFile,FileInfo1); + Seek(FileInfoFile,(RecNum1 - 1)); + Write(FileInfoFile,FileInfo); + Inc(NumSorted); + END; + END; + UNTIL (NumSorted = 0) AND (Gap = 1); + IF (IOResult <> 0) THEN + SysOpLog('Error sorting files!'); +END; + +PROCEDURE SortFiles(FArea: Integer; VAR TotFiles: LongInt; VAR TotAreas: Integer); +VAR + NumFiles: Word; +BEGIN + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + BEGIN + InitFileArea(FileArea); + NumFiles := FileSize(FileInfoFile); + Prompt('^1Sorting ^5'+MemFileArea.AreaName+' #'+IntToStr(FileArea)+'^1 ('+FormatNumber(NumFiles)+ + ' '+Plural('file',NumFiles)+')'); + IF (NumFiles <> 0) THEN + SortDir(NumFiles); + Close(FileInfoFile); + Close(ExtInfoFile); + Inc(TotAreas); + Inc(TotFiles,NumFiles); + NL; + END; +END; + +PROCEDURE Sort; +VAR + FArea, + TotAreas, + SaveFileArea: Integer; + TotFiles: LongInt; + Global, + SaveConfSystem: Boolean; +BEGIN + NL; + IF (NOT SortFilesOnly) THEN + Global := PYNQ('Sort all file areas? ',0,FALSE) + ELSE + BEGIN + Global := TRUE; + CLS; + END; + NL; + TotFiles := 0; + TotAreas := 0; + IF (NOT Global) THEN + SortFiles(FileArea,TotFiles,TotAreas) + ELSE + BEGIN + SaveFileArea := FileArea; + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + Abort := FALSE; + Next := FALSE; + TempPause := FALSE; + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF FileAreaAC(FArea) OR (SortFilesOnly) THEN + SortFiles(FArea,TotFiles,TotAreas); + WKey; + Inc(FArea); + END; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; + NL; + Print('Sorted '+FormatNumber(TotFiles)+' '+Plural('file',TotFiles)+ + ' in '+FormatNumber(TotAreas)+' '+Plural('area',TotAreas)); + SysOpLog('Sorted file areas'); +END; + +END. diff --git a/SOURCE/FILE14.PAS b/SOURCE/FILE14.PAS new file mode 100644 index 0000000..4f383df --- /dev/null +++ b/SOURCE/FILE14.PAS @@ -0,0 +1,190 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File14; + +INTERFACE + +USES + Common; + +FUNCTION IsGIFExt(CONST FileName: AStr): Boolean; +FUNCTION IsGIFDesc(CONST Description: AStr): Boolean; +FUNCTION GetGIFSpecs(CONST FileName: AStr; Description: AStr; Which: Byte): AStr; +PROCEDURE AddGIFSpecs; + +IMPLEMENTATION + +USES + File0, + File11; + +FUNCTION IsGIFExt(CONST FileName: AStr): Boolean; +VAR + TempFN: AStr; +BEGIN + TempFN := AllCaps(SQOutSp(StripName(FileName))); + IsGIFExt := (Copy(TempFN,(Length(TempFN) - 2),3) = 'GIF'); +END; + +FUNCTION IsGIFDesc(CONST Description: AStr): Boolean; +BEGIN + IsGIFDesc := (Pos('< Bad GIF >',Description) <> 0) OR + (Pos('< Missing GIF >',Description) <> 0) OR + ((Description[1] = '(') AND (Pos('x',Description) IN [1..7]) AND (Pos('c)',Description) <> 0)); +END; + +FUNCTION GetGIFSpecs(CONST FileName: AStr; Description: AStr; Which: Byte): AStr; +VAR + F: FILE; + Buf: ARRAY [1..11] OF Byte; + Sig: AStr; + X, + Y, + C, + C1, + Counter, + NumRead: Word; +BEGIN + FillChar(Buf,SizeOf(Buf),0); + Sig := ''; + X := 0; + Y := 0; + C := 0; + NumRead := 0; + Assign(F,FileName); + Reset(F,1); + IF (IOResult <> 0) THEN + Sig := '< Missing GIF >' + ELSE + BEGIN + BlockRead(F,Buf,SizeOf(Buf),NumRead); + Close(F); + IF (NumRead <> 11) THEN + Sig := '< Bad GIF >' + ELSE IF (Buf[1] <> Ord('G')) OR (Buf[2] <> Ord('I')) OR (Buf[3] <> Ord('F')) THEN + Sig := '< Missing GIF >'; + END; + IF (Sig <> '< Bad GIF >') AND (Sig <> '< Missing GIF >') THEN + BEGIN + FOR Counter := 1 TO 6 DO + Sig := Sig + Chr(Buf[Counter]); + X := ((Buf[7] + Buf[8]) * 256); + Y := ((Buf[9] + Buf[10]) * 256); + C1 := ((Buf[11] AND 7) + 1); + C := 1; + FOR Counter := 1 TO C1 DO + C := (C * 2); + END; + IF (Which = 1) THEN + GetGIFSpecs := '^3'+Align(StripName(FileName))+ + ' ^5'+PadLeftStr(IntToStr(X)+'x'+IntToStr(Y),11)+ + ' '+PadLeftStr(IntToStr(C)+' colors',10)+ + ' '+AOnOff((Sig = '< Missing GIF >') OR (Sig = '< Bad GIF >'),'^8'+Sig+'^1','^7'+Sig+'^1') + ELSE IF (Which IN [2,3]) THEN + BEGIN + IF (Sig = '< Missing GIF >') THEN + GetGifSpecs := Copy('^8< Missing GIF > ^9'+Description,1,50) + ELSE IF (Sig = '< Bad GIF >') THEN + GetGIFSpecs := Copy('^8< Bad GIF > ^9'+Description,1,50) + ELSE + GetGIFSPecs := Copy('('+IntToStr(X)+'x'+IntToStr(Y)+','+IntToStr(C)+'c) '+Description,1,50); + END; + IF (Sig = '< Missing GIF >') OR (Sig = '< Bad GIF >') THEN + SysOpLog('^7Bad or missing GIF: "^5'+StripName(FileName)+'^7" in ^5'+MemFileArea.AreaName); +END; + +PROCEDURE AddGIFSpecs; +VAR + FArrayRecNum: Byte; + FArea, + SaveFileArea: Integer; + TotalFiles: LongInt; + + PROCEDURE AddFileAreaGIFSpecs(FArea: Integer; VAR FArrayRecNum1: Byte; VAR TotalFiles1: LongInt); + VAR + DirFileRecNum: Integer; + Found: Boolean; + BEGIN + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + BEGIN + RecNo(FileInfo,'*.*',DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + IF (FAUseGifSpecs IN MemFileArea.FAFlags) THEN + BEGIN + LIL := 0; + CLS; + Found := FALSE; + Prompt('^1Scanning ^5'+MemFileArea.AreaName+' #'+IntToStr(CompFileArea(FArea,0))+'^1 ...'); + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + IF (IsGIFExt(FileInfo.FileName) AND (NOT IsGIFDesc(FileInfo.Description))) THEN + BEGIN + FileInfo.Description := GetGIFSpecs(MemFileArea.DLPath+SQOutSp(FileInfo.FileName),FileInfo.Description,3); + WITH FArray[FArrayRecNum1] DO + BEGIN + FArrayFileArea := FileArea; + FArrayDirFileRecNum := DirFileRecNum; + END; + lDisplay_File(FileInfo,FArrayRecNum1,'',FALSE); + Inc(FArrayRecNum1); + IF (FArrayRecNum1 = 100) THEN + FArrayRecNum1 := 0; + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,FileInfo); + Inc(TotalFiles1); + Found := TRUE; + END; + Wkey; + NRecNo(FileInfo,DirFileRecNum); + END; + IF (NOT Found) THEN + BEGIN + LIL := 0; + BackErase(15 + LennMCI(MemFileArea.AreaName) + Length(IntToStr(CompFileArea(FArea,0)))); + END; + END; + Close(FileInfoFile); + Close(ExtInfoFile); + LastError := IOResult; + END; + END; + +BEGIN + NL; + Print('Adding GIF Resolution to file descriptions -'); + InitFArray(FArray); + FArrayRecNum := 0; + TotalFiles := 0; + Abort := FALSE; + Next := FALSE; + NL; + IF (NOT PYNQ('Search all file areas? ',0,FALSE)) THEN + AddFileAreaGIFSpecs(FileArea,FArrayRecNum,TotalFiles) + ELSE + BEGIN + SaveFileArea := FileArea; + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + AddFileAreaGIFSpecs(FArea,FArrayRecNum,TotalFiles); + WKey; + Inc(FArea); + END; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; + NL; + Print('Added GIF specifications to '+FormatNumber(TotalFiles)+' '+Plural('file',Totalfiles)+'.'); + SysOpLog('Added GIF specifications to '+FormatNumber(TotalFiles)+' '+Plural('file',Totalfiles)+'.'); +END; + +END. diff --git a/SOURCE/FILE2.PAS b/SOURCE/FILE2.PAS new file mode 100644 index 0000000..3d2d1ef --- /dev/null +++ b/SOURCE/FILE2.PAS @@ -0,0 +1,125 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File2; + +INTERFACE + +USES + Common; + +FUNCTION CopyMoveFile(CopyFile: Boolean; DisplayStr: AStr; CONST SrcName,DestName: AStr; CONST ShowProg: Boolean): Boolean; + +IMPLEMENTATION + +USES + Dos; + +FUNCTION CopyMoveFile(CopyFile: Boolean; DisplayStr: AStr; CONST SrcName,DestName: AStr; CONST ShowProg: Boolean): Boolean; +VAR + Buffer: ARRAY [1..8192] OF Byte; + FromF, + ToF: FILE; + CurDir: AStr; + ProgressStr: Str3; + NumRead: Word; + TotalNumRead, + FileDate: LongInt; + OK, + Nospace: Boolean; +BEGIN + OK := TRUE; + NoSpace := FALSE; + GetDir(0,CurDir); + IF (ShowProg) THEN + Prompt(DisplayStr); + IF (NOT CopyFile) THEN + BEGIN + Assign(FromF,SrcName); + ReName(FromF,DestName); + LastError := IOResult; + IF (LastError <> 0) THEN + OK := FALSE + ELSE IF (ShowProg) THEN + Print('^5100%^1') + END; + IF (NOT OK) OR (CopyFile) THEN + BEGIN + OK := TRUE; + IF (SrcName = DestName) THEN + OK := FALSE + ELSE + BEGIN + Assign(FromF,SrcName); + Reset(FromF,1); + LastError := IOResult; + IF (LastError <> 0) THEN + OK := FALSE + ELSE + BEGIN + GetFTime(FromF,FileDate); + IF ((FileSize(FromF) DIV 1024) >= DiskKBFree(DestName)) THEN + BEGIN + Close(FromF); + NoSpace := TRUE; + OK := FALSE; + END + ELSE + BEGIN + Assign(ToF,DestName); + ReWrite(ToF,1); + LastError := IOResult; + IF (LastError <> 0) THEN + OK := FALSE + ELSE + BEGIN + SetFTime(ToF,FileDate); + IF (ShowProg) THEN + Prompt('^5 0%^1'); + TotalNumRead := 0; + REPEAT + BlockRead(FromF,Buffer,SizeOf(Buffer),NumRead); + BlockWrite(ToF,Buffer,NumRead); + Inc(TotalNumRead,NumRead); + IF (ShowProg) AND (FileSize(FromF) > 0) THEN + BEGIN + Str(Trunc(TotalNumRead / FileSize(FromF) * 100):3,ProgressStr); + Prompt(^H^H^H^H+'^5'+ProgressStr+'%^1'); + END; + UNTIL (NumRead < SizeOf(Buffer)); + IF (ShowProg) THEN + BEGIN + UserColor(1); + NL; + END; + Close(ToF); + Close(FromF); + IF (NOT CopyFile) AND (OK) AND (NOT NoSpace) THEN + Kill(SrcName); + END; + END; + END; + END; + END; + ChDir(CurDir); + IF (NoSpace) THEN + BEGIN + IF (ShowProg) THEN + Print('^7destination drive full!^1'); + SysOpLog('^7Error '+AOnOff(CopyFile,'copying','moving')+' (No-Space): "'+SrcName+'" to "'+DestName+'"!'); + END + ELSE IF (NOT Ok) THEN + BEGIN + IF (ShowProg) THEN + Print('^7failed!^1'); + SysOpLog('^7Error '+AOnOff(CopyFile,'copying','moving')+' (I/O): "'+SrcName+'" to "'+DestName+'"!'); + END + ELSE + SysOpLog('^1'+AOnOff(CopyFile,'Copied','Moved')+' file: "^5'+SrcName+'^1" to "^5'+DestName+'^1".'); + CopyMoveFile := (OK) AND (NOT NoSpace); +END; + +END. diff --git a/SOURCE/FILE3.PAS b/SOURCE/FILE3.PAS new file mode 100644 index 0000000..b456986 --- /dev/null +++ b/SOURCE/FILE3.PAS @@ -0,0 +1,115 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File3; + +INTERFACE + +PROCEDURE ReCheck; + +IMPLEMENTATION + +USES + Dos, + Common, + File0, + File1; + +PROCEDURE CheckFiles(FArea: Integer; CheckDiz: Boolean); +VAR + FN: AStr; + NumExtDesc: Byte; + DirFileRecNum: Integer; + FSize: LongInt; +BEGIN + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + BEGIN + RecNo(FileInfo,'*.*',DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + NL; + Print('^1Checking ^5'+MemFileArea.AreaName+' #'+IntToStr(CompFileArea(FArea,0))+'^1 ...'); + WHILE (DirFileRecNum <> - 1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + + IF Exist(MemFileArea.DLPath+FileInfo.FileName) THEN + FN := MemFileArea.DLPath+SQOutSp(FileInfo.FileName) + ELSE + FN := MemFileArea.ULPath+SQOutSp(FileInfo.FileName); + + FSize := GetFileSize(FN); + IF (FSize = 0) THEN + BEGIN + FileInfo.FileSize := 0; + Include(FileInfo.FIFlags,FIIsRequest); + END + ELSE + BEGIN + FileInfo.FileSize := FSize; + Exclude(FileInfo.FIFlags,FIIsRequest); + END; + + IF (CheckDiz) AND (DizExists(FN)) THEN + BEGIN + FillChar(ExtendedArray,SizeOf(ExtendedArray),0); + GetDiz(FileInfo,ExtendedArray,NumExtDesc); + WriteFV(FileInfo,DirFileRecNum,ExtendedArray); + END; + + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,FileInfo); + + NRecNo(FileInfo,DirFileRecNum); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; + LastError := IOResult; +END; + +PROCEDURE ReCheck; +VAR + SaveFileArea, + FArea: Integer; + CheckDiz, + SaveConfSystem, + SaveTempPause: Boolean; +BEGIN + CheckDiz := PYNQ('%LFReimport descriptions? ',0,FALSE); + SaveTempPause := TempPause; + TempPause := FALSE; + Abort := FALSE; + Next := FALSE; + NL; + IF (NOT PYNQ('Recheck all file areas? ',0,FALSE)) THEN + CheckFiles(FileArea,CheckDiz) + ELSE + BEGIN + SaveFileArea := FileArea; + SaveConfSystem := ConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Checkfiles(FArea,CheckDiz); + WKey; + Inc(FArea); + END; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; + TempPause := SaveTempPause; +END; + +END. diff --git a/SOURCE/FILE4.PAS b/SOURCE/FILE4.PAS new file mode 100644 index 0000000..7f84b2a --- /dev/null +++ b/SOURCE/FILE4.PAS @@ -0,0 +1,251 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File4; + +INTERFACE + +USES + Common; + +PROCEDURE ExecProtocol(TextFN, + Dir, + BatLine: AStr; + OKLevel: Integer; + VAR ReturnCode: Integer; + VAR TransferTime: LongInt); +FUNCTION FindReturnCode(ProtCode: ProtocolCodeType; XBStat: PRFlagSet; ReturnCode: AStr): Boolean; +FUNCTION DoProtocol(VAR Protocol: ProtocolRecordType; UL,DL,Batch,Resume: Boolean): Integer; + +IMPLEMENTATION + +USES + ExecBat, + TimeFunc; + +FUNCTION FindReturnCode(ProtCode: ProtocolCodeType; XBStat: PRFlagSet; ReturnCode: AStr): Boolean; +VAR + Counter: Byte; + Found: Boolean; +BEGIN + FindReturnCode := FALSE; + Found := FALSE; + FOR Counter := 1 TO 6 DO + IF (ProtCode[Counter] <> '') THEN + IF (Pos(ProtCode[Counter],Copy(ReturnCode,1,Length(ProtCode[Counter]))) <> 0) THEN + Found := TRUE; + IF (Found) AND (NOT (ProtXferOkCode IN Protocol.PRFlags)) THEN + Exit; + IF (NOT Found) AND (ProtXferOkCode IN Protocol.PRFlags) THEN + Exit; + FindReturnCode := Found; +END; + +PROCEDURE ExecProtocol(TextFN, + Dir, + BatLine: AStr; + OKLevel: Integer; + VAR ReturnCode: Integer; + VAR TransferTime: LongInt); +VAR + SaveSwapShell, + ResultOk: Boolean; +BEGIN + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + SaveNAvail := (NAvail IN NodeR.Status); + Exclude(NodeR.Status,NAvail); + SaveNode(ThisNode); + END; + + TransferTime := GetPackDateTime; + + IF (TextFN <> '') THEN + BEGIN + AllowContinue := TRUE; + Abort := FALSE; + Next := FALSE; + CLS; + UserColor(1); + ReturnCode := 0; + PrintF(TextFN); + IF (NoFile) THEN + ReturnCode := 2; + NL; + PauseScr(FALSE); + UserColor(1); + AllowContinue := FALSE; + END + ELSE + BEGIN + SaveSwapShell := General.SwapShell; + General.SwapShell := FALSE; + ExecWindow(ResultOK, + Dir, + BatLine, + OKLevel, + ReturnCode); + General.SwapShell := SaveSwapShell; + END; + + TransferTime := (GetPackDateTime - TransferTime); + + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + IF (SaveNAvail) THEN + Include(NodeR.Status,NAvail); + SaveNode(ThisNode); + END; +END; + +FUNCTION OkProt(Protocol: ProtocolRecordType; UL,DL,Batch,Resume: Boolean): Boolean; +VAR + ULDLCmdStr: AStr; +BEGIN + OkProt := FALSE; + WITH Protocol DO + BEGIN + IF (UL) THEN + ULDLCmdStr := ULCmd + ELSE IF (DL) THEN + ULDLCmdStr := DLCmd + ELSE + ULDLCmdStr := ''; + IF (ULDLCmdStr = '') THEN + Exit; + IF (ULDLCmdStr = 'NEXT') AND ((UL) OR (Batch) OR (Resume)) THEN + Exit; + IF (ULDLCmdStr = 'ASCII') AND ((UL) OR (Batch) OR (Resume)) THEN + Exit; + IF (ULDLCmdStr = 'BATCH') AND ((Batch) OR (Resume)) AND (NOT Write_Msg) THEN + Exit; + IF (Batch <> (ProtIsBatch in PRFlags)) THEN + Exit; + IF (Resume <> (ProtIsResume in PRFlags)) THEN + Exit; + IF (ProtReliable in PRFlags) AND (NOT Reliable) THEN + Exit; + IF (NOT (ProtActive in PRFlags)) THEN + Exit; + IF (NOT AACS(ACS)) THEN + Exit; + END; + OkProt := TRUE; +END; + +PROCEDURE ShowProts(VAR CmdStr: AStr; UL,DL,Batch,Resume: Boolean); +VAR + RecNum: Integer; +BEGIN + NoFile := TRUE; + IF (Resume) THEN + PrintF('PROTRES') + ELSE + BEGIN + IF (Batch) THEN + IF (UL) THEN + PrintF('PROTBUL') + ELSE + PrintF('PROTBDL') + ELSE IF (UL) THEN + PrintF('PROTSUL') + ELSE + PrintF('PROTSDL'); + END; + Abort := FALSE; + Next := FALSE; + CmdStr := ''; + RecNum := 1; + WHILE (RecNum <= NumProtocols) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(ProtocolFile,(RecNum - 1)); + Read(ProtocolFile,Protocol); + IF (OkProt(Protocol,UL,DL,Batch,Resume)) THEN + BEGIN + IF (NoFile) AND (Protocol.Description <> '') THEN + Print(Protocol.Description); + IF (Protocol.CKeys = 'ENTER') then + CmdStr := CmdStr + ^M + ELSE + CmdStr := CmdStr + Protocol.CKeys[1]; + END; + Inc(RecNum); + END; + IF (NoFile) THEN + NL; +END; + +FUNCTION FindProt(Cmd: Char; UL,DL,Batch,Resume: Boolean): Integer; +VAR + ULDLCmdStr: AStr; + RecNum, + RecNum1: Integer; +BEGIN + RecNum1 := -99; + RecNum := 1; + WHILE (RecNum <= NumProtocols) AND (RecNum1 = -99) DO + BEGIN + Seek(ProtocolFile,(RecNum - 1)); + Read(ProtocolFile,Protocol); + IF (Cmd = Protocol.Ckeys[1]) OR ((Cmd = ^M) AND (Protocol.Ckeys = 'ENTER')) THEN + IF (OkProt(Protocol,UL,DL,Batch,Resume)) THEN + BEGIN + IF (UL) THEN + ULDLCmdStr := Protocol.ULCmd + ELSE IF (DL) THEN + ULDLCmdStr := Protocol.DLCmd + ELSE + ULDLCmdStr := ''; + IF (ULDLCmdStr = 'ASCII') THEN + RecNum1 := -1 + ELSE IF (ULDLCmdStr = 'QUIT') THEN + RecNum1 := -2 + ELSE IF (ULDLCmdStr = 'NEXT') THEN + RecNum1 := -3 + ELSE IF (ULDLCmdStr = 'BATCH') THEN + RecNum1 := -4 + ELSE IF (ULDLCmdStr = 'EDIT') THEN + RecNum1 := -5 + ELSE IF (ULDLCmdStr <> '') THEN + RecNum1 := RecNum; + END; + Inc(RecNum); + END; + FindProt := RecNum1; +END; + +FUNCTION DoProtocol(VAR Protocol: ProtocolRecordType; UL,DL,Batch,Resume: Boolean): Integer; +VAR + CmdStr: AStr; + Cmd: Char; + RecNum: Integer; +BEGIN + Reset(ProtocolFile); + REPEAT + ShowProts(CmdStr,UL,DL,Batch,Resume); + { Prompt('%DFPROTLIST%^4Selection^2: ');} + lRGLngStr(17,FALSE);; + OneK(Cmd,CmdStr,TRUE,TRUE); + RecNum := FindProt(Cmd,UL,DL,Batch,Resume); + IF (RecNum = -99) THEN + BEGIN + NL; + Print('Invalid option.'); + END + ELSE IF (RecNum >= 1) AND (RecNum <= NumProtocols) THEN + BEGIN + Seek(ProtocolFile,(RecNum - 1)); + Read(ProtocolFile,Protocol); + END + UNTIL (RecNum <> -99) OR (HangUp); + Close(ProtocolFile); + LastError := IOResult; + DoProtocol := RecNum; +END; + +END. \ No newline at end of file diff --git a/SOURCE/FILE5.PAS b/SOURCE/FILE5.PAS new file mode 100644 index 0000000..6ded087 --- /dev/null +++ b/SOURCE/FILE5.PAS @@ -0,0 +1,804 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File5; + +INTERFACE + +PROCEDURE MiniDOS; +PROCEDURE UploadAll; + +IMPLEMENTATION + +USES + Dos, + Common, + Arcview, + Archive1, + ExecBat, + File0, + File1, + File2, + File8, + File9, + File11, + MultNode, + Sysop4; + +PROCEDURE MiniDOS; +VAR + XWord: ARRAY [1..9] OF AStr; + (* + DirInfo: SearchRec; + *) + CurDir, + s, + s1: AStr; + Done, + NoCmd, + NoSpace, + Junk, + junk2, + junk3, + Found: Boolean; + TransferTime: LongInt; + + PROCEDURE Parse(CONST s: AStr); + VAR + i, + j, + k: Integer; + BEGIN + FOR i := 1 TO 9 DO + XWord[i] := ''; + i := 1; + j := 1; + k := 1; + IF (Length(s) = 1) THEN + XWord[1] := s; + WHILE (i < Length(s)) DO + BEGIN + Inc(i); + IF ((s[i] = ' ') OR (Length(s) = i)) THEN + BEGIN + IF (Length(s) = i) THEN + Inc(i); + XWord[k] := AllCaps(Copy(s,j,(i - j))); + j := (i + 1); + Inc(k); + END; + END; + END; + + PROCEDURE VersionInfo; + BEGIN + NL; + Print('Renegade''s internal DOS emulator. Supported commands are limited.'); + NL; + NL; + END; + + FUNCTION DOSErrorMsg(ErrorNum: Byte): AStr; + VAR + S: AStr; + BEGIN + CASE ErrorNum OF + 1 : S := 'The snytax of the command is incorrect.'; + END; + DOSErrorMsg := S; + END; + + PROCEDURE DoCmd(CONST Cmd: AStr); + VAR + F: FILE; + ps, + ns, + es, + op, + np, + s1, + s2, + s3: AStr; + NumFiles, + TSiz: LongInt; + i, + j: Byte; + RetLevel: Integer; + b, + Ok: Boolean; + BEGIN + Abort := FALSE; + Next := FALSE; + NoCmd := FALSE; + s := XWord[1]; + IF (s = '?') OR (s = 'HELP') THEN + PrintF('DOSHELP') + ELSE IF (s = 'EDIT') THEN + BEGIN + IF ((Exist(XWord[2])) AND (XWord[2] <> '')) THEN + TEdit(XWord[2]) + ELSE IF (XWord[2] = '') THEN + TEdit1 + ELSE + TEdit(XWord[2]); + END + ELSE IF (s = 'EXIT') THEN + Done := TRUE + ELSE IF (s = 'DEL') THEN + BEGIN + IF ((NOT Exist(XWord[2])) AND (NOT IsWildCard(XWord[2]))) OR (XWord[2] = '') THEN + Print('File not found.') + ELSE + BEGIN + XWord[2] := FExpand(XWord[2]); + FindFirst(XWord[2],AnyFile - VolumeID - Directory,DirInfo); + IF (NOT IsWildCard(XWord[2])) OR (PYNQ('Are you sure? ',0,FALSE)) THEN + REPEAT + Kill(DirInfo.Name); + FindNext(DirInfo); + UNTIL (DOSError <> 0) OR (HangUp); + END; + END + ELSE IF (s = 'TYPE') THEN + BEGIN + PrintF(FExpand(XWord[2])); + IF (NoFile) THEN + Print('File not found.'); + END + ELSE IF (Copy(s,1,3) = 'REN') THEN + BEGIN + IF ((NOT Exist(XWord[2])) AND (XWord[2] <> '')) THEN + Print('File not found.') + ELSE + BEGIN + XWord[2] := FExpand(XWord[2]); + Assign(F,XWord[2]); + ReName(F,XWord[3]); + IF (IOResult <> 0) THEN + Print('File not found.'); + END + END + ELSE IF (s = 'DIR') THEN + BEGIN + b := TRUE; + FOR i := 2 TO 9 DO + IF (XWord[i] = '/W') THEN + BEGIN + b := FALSE; + XWord[i] := ''; + END; + IF (XWord[2] = '') THEN + XWord[2] := '*.*'; + s1 := CurDir; + XWord[2] := FExpand(XWord[2]); + FSplit(XWord[2],ps,ns,es); + s1 := ps; + s2 := ns + es; + IF (s2[1] = '.') THEN + s2 := '*' + s2; + IF (s2 = '') THEN + s2 := '*.*'; + IF (Pos('.', s2) = 0) THEN + s2 := s2 + '.*'; + IF (NOT IsWildCard(XWord[2])) THEN + BEGIN + FindFirst(XWord[2],AnyFile,DirInfo); + IF ((DOSError = 0) AND (DirInfo.Attr = Directory)) OR ((Length(s1) = 3) AND (s1[3] = '\')) THEN + BEGIN + s1 := BSlash(XWord[2],TRUE); + s2 := '*.*'; + END; + END; + NL; + DosDir(s1,s2,b); + NL; + END + ELSE IF ((s = 'CD') OR (s = 'CHDIR')) AND (XWord[2] <> '') OR (Copy(s,1,3) = 'CD\') THEN + BEGIN + IF (Copy(s,1,3) = 'CD\') THEN + XWord[2] := Copy(s,3,Length(s)-2); + XWord[2] := FExpand(XWord[2]); + ChDir(XWord[2]); + IF (IOResult <> 0) THEN + Print('Invalid pathname.'); + END + (* Done - Lee Palmer - 01/09/08 *) + ELSE IF (s = 'MD') OR (s = 'MKDIR') THEN + BEGIN + IF (XWord[2] = '') THEN + Print(DOSErrorMsg(1)) + ELSE + BEGIN + FindFirst(XWord[2],AnyFile,DirInfo); + IF (DosError = 0) THEN + Print('A subdirectory or file '+XWord[2]+' already exists.') + ELSE + BEGIN + MkDir(XWord[2]); + IF (IOResult <> 0) THEN + Print('Access is denied.'); + END; + END; + + END + ELSE IF ((s = 'RD') OR (s = 'RMDIR')) THEN + BEGIN + (* Finish Me *) + IF (XWord[2] = '') THEN + Print(DOSErrorMsg(1)) + ELSE + BEGIN + FindFirst(XWord[2],AnyFile,DirInfo); + IF (DosError <> 0) THEN + Print('The system cannot find the file specified.') + ELSE + BEGIN + Abort := FALSE; + Found := FALSE; + FindFirst(BSlash(XWord[2],TRUE)+'*.*',AnyFile,DirInfo); + WHILE (DosError = 0) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (DirInfo.Name <> '.') AND (DirInfo.Name <> '..') THEN + BEGIN + Abort := TRUE; + Found := TRUE; + END; + FindNext(DirInfo); + END; + Abort := FALSE; + IF (Found) THEN + Print('The directory is not empty.') + ELSE + BEGIN + RmDir(XWord[2]); + IF (IOResult <> 0) THEN + Print('Access is denied.'); + END; + END; + END; + + END + ELSE IF (s = 'COPY') THEN + BEGIN + IF (XWord[2] <> '') THEN + BEGIN + IF (IsWildCard(XWord[3])) THEN + Print('Wildcards not allowed in destination parameter!') + ELSE + BEGIN + IF (XWord[3] = '') THEN + XWord[3] := CurDir; + XWord[2] := BSlash(FExpand(XWord[2]),FALSE); + XWord[3] := FExpand(XWord[3]); + FindFirst(XWord[3],AnyFile,DirInfo); + b := ((DOSError = 0) AND (DirInfo.Attr AND Directory = Directory)); + IF ((NOT b) AND (Copy(XWord[3],2,2) = ':\') AND (Length(XWord[3]) = 3)) THEN + b := TRUE; + FSplit(XWord[2],op,ns,es); + op := BSlash(OP,TRUE); + IF (b) THEN + np := BSlash(XWord[3],TRUE) + ELSE + BEGIN + FSplit(XWord[3],np,ns,es); + np := BSlash(np,TRUE); + END; + + j := 0; + Abort := FALSE; + Next := FALSE; + FindFirst(XWord[2],AnyFile - Directory - VolumeID,DirInfo); + WHILE (DOSError = 0) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + s1 := op + DirInfo.Name; + IF (b) THEN + s2 := np + DirInfo.Name + ELSE + s2 := np + ns + es; + + IF CopyMoveFile(TRUE,s1+' -> '+s2+' :',s1,s2,TRUE) THEN + BEGIN + Inc(j); + NL; + END; + + NL; + IF (NOT Empty) THEN + WKey; + FindNext(DirInfo); + END; + Print(' '+IntToStr(j)+' file(s) copied.'); + END; + END; + END + ELSE IF (s = 'MOVE') THEN + BEGIN + IF (XWord[2] <> '') THEN + BEGIN + IF (IsWildCard(XWord[3])) THEN + Print('Wildcards not allowed in destination parameter!') + ELSE + BEGIN + IF (XWord[3] = '') THEN + XWord[3] := CurDir; + XWord[2] := BSlash(FExpand(XWord[2]),FALSE); + XWord[3] := FExpand(XWord[3]); + FindFirst(XWord[3],AnyFile,DirInfo); + b := ((DOSError = 0) AND (DirInfo.Attr AND Directory = Directory)); + IF ((NOT b) AND (Copy(XWord[3],2,2) = ':\') AND (Length(XWord[3]) = 3)) THEN + b := TRUE; + FSplit(XWord[2],op,ns,es); + op := BSlash(op,TRUE); + IF (b) THEN + np := BSlash(XWord[3],TRUE) + ELSE + BEGIN + FSplit(XWord[3],np,ns,es); + np := BSlash(np,TRUE); + END; + j := 0; + Abort := FALSE; + Next := FALSE; + FindFirst(XWord[2],AnyFile - Directory - VolumeID,DirInfo); + WHILE (DOSError = 0) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + s1 := op + DirInfo.Name; + IF (b) THEN + s2 := np + DirInfo.Name + ELSE + s2 := np + ns + es; + CopyMoveFile(FALSE,s1+' -> '+s2+' :',s1,s2,TRUE); + BEGIN + Inc(j); + NL; + END; + IF (NOT Empty) THEN + WKey; + FindNext(DirInfo); + END; + Print(' '+IntToStr(j)+' file(s) moved.'); + END; + END; + END + ELSE IF (s = 'CLS') THEN + CLS + ELSE IF (Length(s) = 2) AND (s[1] >= 'A') AND (s[1] <= 'Z') AND (s[2] = ':') THEN + BEGIN + GetDir(Ord(s[1]) - 64,s1); + IF (IOResult <> 0) THEN + Print('Invalid drive.') + ELSE + BEGIN + ChDir(s1); + IF (IOResult <> 0) THEN + BEGIN + Print('Invalid drive.'); + ChDir(CurDir); + END; + END; + END + ELSE IF (s = 'VIEW') THEN + BEGIN + IF (XWord[2] = '') THEN + Print('Syntax is: "VIEW filename"') + ELSE + BEGIN + s1 := XWord[2]; + IF (Pos('.',s1) = 0) THEN + s1 := s1 + '*.*'; + ViewInternalArchive(s1); + END; + END + ELSE IF (s = 'SEND') AND (XWord[2] <> '') THEN + BEGIN + IF Exist(XWord[2]) THEN + UnlistedDownload(FExpand(XWord[2])) + ELSE + Print('File not found.'); + END + ELSE IF (s = 'RECEIVE') THEN + BEGIN + Prt('File Name: '); + MPL(12); + Input(s,12); + s := StripName(s); + Receive(s,'',FALSE,Junk,junk2,junk3,TransferTime); + IF (Junk) THEN + SysOpLog('DOS emulator upload of: '+s); + END + ELSE IF (s = 'VER') THEN + VersionInfo + ELSE IF (s = 'DIRSIZE') THEN + BEGIN + NL; + IF (XWord[2] = '') THEN + Print('Needs a parameter.') + ELSE + BEGIN + NumFiles := 0; + TSiz := 0; + FindFirst(XWord[2],AnyFile,DirInfo); + WHILE (DOSError = 0) DO + BEGIN + Inc(TSiz,DirInfo.Size); + Inc(NumFiles); + FindNext(DirInfo); + END; + IF (NumFiles = 0) THEN + Print('No files found!') + ELSE + Print('"'+AllCaps(XWord[2])+'": '+IntToStr(NumFiles)+' files, '+ConvertBytes(TSiz,FALSE)); + END; + NL; + END + ELSE IF (s = 'DISKFREE') THEN + BEGIN + IF (XWord[2] = '') THEN + j := ExtractDriveNumber(CurDir) + ELSE + j := ExtractDriveNumber(XWord[2]); + IF (DiskFree(j) = -1) THEN + Print('Invalid drive specification'^M^J) + ELSE + Print(^M^J + ConvertBytes(DiskFree(j),FALSE)+' free on '+Chr(j + 64)+':'^M^J); + END + ELSE IF (s = 'EXT') THEN + BEGIN + s1 := Cmd; + j := Pos('EXT',AllCaps(s1)) + 3; + s1 := Copy(s1,j,Length(s1) - (j - 1)); + WHILE (s1[1] = ' ') AND (Length(s1) > 0) DO + Delete(s1,1,1); + IF (s1 <> '') THEN + BEGIN + Shel('Running "'+s1+'"'); + ShellDOS(FALSE,s1,RetLevel); + Shel2(FALSE); + END; + END + ELSE IF (s = 'CONVERT') OR (s = 'CVT') THEN + BEGIN + IF (XWord[2] = '') THEN + BEGIN + NL; + Print(s+' - Renegade archive conversion command.'); + NL; + Print('Syntax is: "'+s+' "'); + NL; + Print('Renegade will convert from the one archive format to the other.'); + Print('You only need to specify the 3-letter extension of the new format.'); + NL; + END + ELSE + BEGIN + IF (NOT Exist(XWord[2])) OR (XWord[2] = '') THEN + Print('File not found.') + ELSE + BEGIN + i := ArcType(XWord[2]); + IF (i = 0) THEN + InvArc + ELSE + BEGIN + s3 := XWord[3]; + s3 := Copy(s3,(Length(s3) - 2),3); + j := ArcType('FILENAME.'+s3); + FSplit(XWord[2],ps,ns,es); + IF (Length(XWord[3]) <= 3) AND (j <> 0) THEN + s3 := ps+ns+'.'+General.FileArcInfo[j].ext + ELSE + s3 := XWord[3]; + IF (j = 0) THEN + InvArc + ELSE + BEGIN + Ok := TRUE; + ConvA(Ok,i,j,SQOutSp(FExpand(XWord[2])),SQOutSp(FExpand(s3))); + IF (Ok) THEN + Kill(SQOutSp(FExpand(XWord[2]))) + ELSE + Star('Conversion unsuccessful.'); + END; + END; + END; + END; + END ELSE IF (s = 'UNARC') OR (s = 'UNZIP') THEN + BEGIN + IF (XWord[2] = '') THEN + BEGIN + NL; + Print(s+' - Renegade archive de-compression command.'); + NL; + Print('Syntax: '+s+' [FILESPECS]'); + NL; + Print('The archive type can be any archive format which has been'); + Print('configured into Renegade via System Configuration.'); + NL; + END + ELSE + BEGIN + i := ArcType(XWord[2]); + IF (NOT Exist(XWord[2])) THEN + Print('File not found.') + ELSE IF (i = 0) THEN + InvArc + ELSE + BEGIN + s3 := ''; + IF (XWord[3] = '') THEN + s3 := ' *.*' + ELSE FOR j := 3 TO 9 DO + IF (XWord[j] <> '') THEN + s3 := s3 + ' '+XWord[j]; + s3 := Copy(s3,2,Length(s3)-1); + ExecBatch(Junk,BSlash(CurDir,TRUE),General.ArcsPath+ + FunctionalMCI(General.FileArcInfo[i].UnArcLine,XWord[2],s3), + 0, + RetLevel, + FALSE); + END; + END; + END + ELSE IF ((s = 'ARC') OR (s = 'ZIP') OR (s = 'PKARC') OR (s = 'PKPAK') OR (s = 'PKZIP')) THEN + BEGIN + IF (XWord[2] = '') THEN + BEGIN + NL; + Print(s+' - Renegade archive compression command.'); + NL; + Print('Syntax is: "'+s+' Archive filespecs..."'); + NL; + Print('The archive type can be ANY archive format which has been'); + Print('configured into Renegade via System Configuration.'); + NL; + END + ELSE + BEGIN + i := ArcType(XWord[2]); + IF (i = 0) THEN + InvArc + ELSE + BEGIN + s3 := ''; + IF (XWord[3] = '') THEN + s3 := ' *.*' + ELSE FOR j := 3 TO 9 DO + IF (XWord[j] <> '') THEN + s3 := s3 + ' '+FExpand(XWord[j]); + s3 := Copy(s3,2,(Length(s3) - 1)); + ExecBatch(Junk, + BSlash(CurDir,TRUE), + General.ArcsPath+FunctionalMCI(General.FileArcInfo[i].ArcLine,FExpand(XWord[2]),s3), + 0, + RetLevel, + FALSE); + END; + END; + END + ELSE + BEGIN + NoCmd := TRUE; + IF (s <> '') THEN + Print('Bad command or file name.') + END; + END; + +BEGIN + Done := FALSE; + NL; + Print('Type "EXIT" to return to Renegade'); + NL; + VersionInfo; + REPEAT + GetDir(0,CurDir); + Prompt('^1'+CurDir+'>'); + InputL(s1,128); + Parse(s1); + Check_Status; + DoCmd(s1); + IF (NOT NoCmd) THEN + SysOpLog('> '+s1); + UNTIL (Done) OR (HangUp); + ChDir(StartDir); +END; + +PROCEDURE UploadAll; +VAR + FileName: Str12; + FArrayRecNum: Byte; + FArea, + SaveFileArea: Integer; + SearchAllFileAreas: Boolean; + + PROCEDURE UploadFiles(FArea: Integer; FileName1: Str12; VAR FArrayRecNum1: Byte); + VAR + (* + DirInfo: SearchRec; + *) + Cmd: Char; + NumExtDesc: Byte; + DirFileRecNum, + GotPts, + Counter: Integer; + FSize: LongInt; + FlagAll, + Ok, + FirstOne, + GotDesc, + Found: Boolean; + BEGIN + FirstOne := TRUE; + FlagAll := FALSE; + + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + BEGIN + LoadFileArea(FileArea); + + LIL := 0; + CLS; + Found := FALSE; + Prompt('^1Scanning ^5'+MemFileArea.AreaName+' #'+IntToStr(CompFileArea(FArea,0))+'^1 ...'); + + FindFirst(MemFileArea.DLPath+FileName1,AnyFile - VolumeID - Directory - DOS.Hidden,DirInfo); + WHILE (DOSError = 0) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + DirInfo.Name := Align(DirInfo.Name); + RecNo(FileInfo,DirInfo.Name,DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + + IF (DirFileRecNum = -1) THEN + BEGIN + + FSize := GetFileSize(MemFileArea.DLPath+DirInfo.Name); + IF (FSize = 0) THEN + BEGIN + FileInfo.FileSize := 0; + Include(FileInfo.FIFlags,FIIsRequest); + END + ELSE + BEGIN + FileInfo.FileSize := FSize; + Exclude(FileInfo.FIFlags,FIIsRequest); + END; + + UpdateFileInfo(FileInfo,DirInfo.Name,GotPts); + + IF (FirstOne) THEN + BEGIN + DisplayFileAreaHeader; + FirstOne := FALSE; + END; + + GotDesc := FALSE; + + IF (General.FileDiz) AND (DizExists(MemFileArea.DLPath+DirInfo.Name)) THEN + BEGIN + GetDiz(FileInfo,ExtendedArray,NumExtDesc); + Star('Complete.'); + Prompt(' ^9'+PadRightInt(FArrayRecNum1,2)+' ^5'+DirInfo.Name+' ^4'+GetFileStats(FileInfo)+' '); + IF (FlagAll) THEN + Ok := TRUE + ELSE + BEGIN + Prt('Upload? (Yes,No,All,Quit): '); + OneK(Cmd,'QYNA',TRUE,TRUE); + Ok := (Cmd = 'Y') OR (Cmd = 'A'); + FlagAll := (Cmd = 'A'); + Abort := (Cmd = 'Q'); + END; + GotDesc := TRUE; + END + ELSE + BEGIN + Prompt(' ^9'+PadRightInt(FArrayRecNum1,2)+' ^5'+DirInfo.Name+' ^4'+GetFileStats(FileInfo)+' '); + MPL(50); + InputL(FileInfo.Description,50); + Ok := TRUE; + IF (FileInfo.Description <> '') AND (FileInfo.Description[1] = '.') THEN + BEGIN + IF (Length(FileInfo.Description) = 1) THEN + BEGIN + Abort := TRUE; + Exit; + END; + Cmd := UpCase(FileInfo.Description[2]); + CASE Cmd OF + 'D' : BEGIN + Kill(MemFileArea.DLPath+DirInfo.Name); + Ok := FALSE; + END; + 'N' : BEGIN + Next := TRUE; + Exit; + END; + 'S' : Ok := FALSE; + END; + END; + END; + + Inc(FArrayRecNum1); + IF (FArrayRecNum1 = 100) THEN + FArrayRecNum1 := 0; + + IF (Ok) THEN + BEGIN + IF (NOT GotDesc) THEN + BEGIN + FillChar(ExtendedArray,SizeOf(ExtendedArray),0); + Counter := 0; + REPEAT + Inc(Counter); + Prt(PadLeftStr('',28)); + MPL(50); + InputL(ExtendedArray[Counter],50); + IF (ExtendedArray[Counter] = '') THEN + Counter := MaxExtDesc; + UNTIL (Counter = MaxExtDesc) OR (HangUp); + NL; + END; + WriteFV(FileInfo,FileSize(FileInfoFile),ExtendedArray); + SysOpLog('^3Uploaded "^5'+SQOutSp(DirInfo.Name)+'^3" to ^5'+MemFileArea.AreaName); + Found := TRUE; + END; + END; + Close(FileInfoFile); + Close(ExtInfoFile); + WKey; + FindNext(DirInfo); + END; + IF (NOT Found) THEN + BEGIN + LIL := 0; + BackErase(15 + LennMCI(MemFileArea.AreaName) + Length(IntToStr(CompFileArea(FArea,0)))); + END; + END; + END; + +BEGIN + NL; + Print('Upload files into file areas -'); + NL; + SearchAllFileAreas := PYNQ('Search all file areas? ',0,FALSE); + NL; + IF NOT PYNQ('Search by file spec? ',0,FALSE) THEN + FileName := '*.*' + ELSE + BEGIN + NL; + Prompt('File name (^5^1=^5All^1): '); + GetFileName(FileName); + END; + NL; + Print('^1Enter . to end processing, .S to skip the file, .N to skip to'); + Print('^1the next directory, and .D to delete the file.'); + NL; + PauseScr(FALSE); + InitFArray(FArray); + FArrayRecNum := 0; + Abort := FALSE; + Next := FALSE; + IF (NOT SearchAllFileAreas) THEN + UploadFiles(FileArea,FileName,FArrayRecNum) + ELSE + BEGIN + SaveFileArea := FileArea; + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + UploadFiles(FArea,FileName,FArrayRecNum); + WKey; + Inc(FArea); + END; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; +END; + +END. + diff --git a/SOURCE/FILE6.PAS b/SOURCE/FILE6.PAS new file mode 100644 index 0000000..15ef0b2 --- /dev/null +++ b/SOURCE/FILE6.PAS @@ -0,0 +1,995 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File6; + +INTERFACE + +USES + Common; + +FUNCTION CheckBatchDL(FileName: Str52): Boolean; +PROCEDURE EditBatchDLQueue; +PROCEDURE BatchDownload; +PROCEDURE ListBatchDLFiles; +PROCEDURE RemoveBatchDLFiles; +PROCEDURE ClearBatchDlQueue; + +IMPLEMENTATION + +USES + Dos, + Common5, + ExecBat, + File0, + File1, + File2, + File4, + File12, + MultNode, + ShortMsg, + TimeFunc; + +FUNCTION CheckBatchDL(FileName: Str52): Boolean; +VAR + RecNum: LongInt; + FileFound: Boolean; +BEGIN + FileFound := FALSE; + IF (NumBatchDLFiles > 0) THEN + BEGIN + Assign(BatchDLFile,General.DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) AND (NOT FileFound) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) AND (BatchDL.BDLFileName = FileName) THEN + FileFound := TRUE; + Inc(RecNum); + END; + Close(BatchDLFile); + LastError := IOResult; + END; + CheckBatchDL := FileFound; +END; + +PROCEDURE EditBatchDLQueue; +VAR + Cmd: CHAR; +BEGIN + IF (NumBatchDLFiles = 0) THEN + BEGIN + NL; + Print('The batch download queue is empty'); + Exit; + END; + REPEAT + NL; + Prt('Batch download queue [^5C^4=^5Clear Batch^4,^5L^4=^5List Batch^4,^5R^4=^5Remove a file^4,^5Q^4=^5Quit^4]: '); + OneK(Cmd,'QCLR',TRUE,TRUE); + CASE Cmd OF + 'C' : ClearBatchDlQueue; + 'L' : ListBatchDLFiles; + 'R' : RemoveBatchDLFiles; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +PROCEDURE BatchDownload; +TYPE + TotalsRecordType = RECORD + FilesDL, + FilesDLRatio: Byte; + BytesDL, + BytesDLRatio, + PointsDL, + PointsDLRatio: LongInt; + END; +VAR + Totals: TotalsRecordType; + FileListTxt, + DLFListTxt: Text; + NewFileName: AStr; + SaveLastDirFileName: Str12; + NumExtDesc, + Counter, + Counter1: BYTE; + ReturnCode, + SaveFileArea, + DirFileRecNum, + ProtocolNumber, + SaveLastDirFileRecNum, + ToXfer: Integer; + RecNum, + RecNum1, + TransferTime: LongInt; + AutoLogOff, + FO: Boolean; + + PROCEDURE AddNacc(BatchDL: BatchDLRecordType); + BEGIN + IF (BatchDL.BDLSection = -1) THEN + BEGIN + IF (IsFileAttach IN BatchDL.BDLFlags) THEN + MemFileArea.AreaName := 'File Attach' + ELSE IF (IsUnlisted IN BatchDL.BDLFlags) THEN + MemFileArea.AreaName := 'Unlisted Download' + ELSE IF (IsTempArc IN BatchDL.BDLFlags) THEN + MemFileArea.AreaName := 'Temporary Archive' + ELSE IF (IsQWK IN BatchDL.BDLFlags) THEN + MemFileArea.AreaName := 'QWK Download'; + END + ELSE + BEGIN + SaveLastDirFileRecNum := LastDIRRecNum; + SaveLastDirFileName := LastDIRFileName; + FO := (FileRec(FileInfoFile).Mode <> FMClosed); + IF (FO) THEN + BEGIN + Close(FileInfoFile); + Close(ExtInfoFile); + END; + SaveFileArea := FileArea; + FileArea := BatchDL.BDLSection; + RecNo(FileInfo,StripName(BatchDL.BDLFileName),DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + IF (DirFileRecNum <> -1) THEN + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + Inc(FileInfo.Downloaded); + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,FileInfo); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + FileArea := SaveFileArea; + IF (FO) THEN + InitFileArea(FileArea); + LastDIRRecNum := SaveLastDirFileRecNum; + LastDIRFileName := SaveLastDirFileName; + END; + NL; + Star(StripName(BatchDL.BDLFileName)+' successfully downloaded.'); + SysOpLog('^3Batch downloaded: "^5'+StripName(BatchDL.BDLFileName)+'^3" from ^5'+ + MemFileArea.AreaName+'.'); + LastError := IOResult; + END; + + FUNCTION ReverseSlash(S: AStr): AStr; + VAR + Counter: Byte; + BEGIN + FOR Counter := 1 TO Length(S) DO + IF (S[Counter] = '/') THEN + S[Counter] := '\'; + ReverseSlash := S; + END; + + PROCEDURE UpdateSatistics(BatchDL: BatchDLRecordType); + BEGIN + + IF (Totals.FilesDL < 255) THEN + Inc(Totals.FilesDL); + + IF ((Totals.BytesDL + BatchDL.BDLFSize) < 2147483647) THEN + Inc(Totals.BytesDL,BatchDL.BDLFSize) + ELSE + Totals.BytesDL := 2147483647; + + IF ((Totals.PointsDL + BatchDL.BDLPoints) < 2147483647) THEN + Inc(Totals.PointsDL,BatchDL.BDLPoints) + ELSE + Totals.PointsDL := 2147483647; + + IF (NOT (IsNoRatio IN BatchDL.BDLFlags)) THEN + BEGIN + IF (Totals.FilesDLRatio < 255) THEN + Inc(Totals.FilesDLRatio); + + IF ((Totals.BytesDLRatio + BatchDL.BDLFSize) < 2147483647) THEN + Inc(Totals.BytesDLRatio,BatchDL.BDLFSize) + ELSE + Totals.BytesDLRatio := 2147483647; + END; + + IF (NOT (IsNoFilePoints IN BatchDL.BDLFlags)) THEN + IF ((Totals.PointsDLRatio + BatchDL.BDLPoints) < 2147483647) THEN + Inc(Totals.PointsDLRatio,BatchDL.BDLPoints) + ELSE + Totals.PointsDLRatio := 2147483647; + + AddNacc(BatchDL); + + WITH FileInfo DO + BEGIN + FileName := StripName(BatchDL.BDLFileName); + Description := ''; + FilePoints := BatchDL.BDLPoints; + Downloaded := 0; + FileSize := 0; + OwnerNum := BatchDL.BDLUploader; + OwnerName := BatchDL.BDLOwnerName; + FileDate := 0; + VPointer := 0; + VTextSize := 0; + FIFlags := []; + END; + + CreditUploader(FileInfo); + + Dec(NumBatchDLFiles); + Dec(BatchDLTime,BatchDL.BDLTime); + Dec(BatchDLSize,BatchDL.BDLFSize); + Dec(BatchDLPoints,BatchDL.BDLPoints); + IF (BatchDL.BDLStorage = Copied) THEN + Kill(BatchDL.BDLFileName); + + END; + + PROCEDURE ChopOfSpace(VAR S: AStr); + BEGIN + WHILE (S[1] = ' ') DO + S := Copy(S,2,(Length(S) - 1)); + IF (Pos(' ',S) <> 0) THEN + S := Copy(S,1,(Pos(' ',S) - 1)); + END; + + PROCEDURE FigureSucc; + VAR + TempLogTxt, + DLoadLogTxt: Text; + LogStr, + FileStr, + StatStr: AStr; + RecNum, + RecNum1: LongInt; + ToFile, + ReadLog, + FoundFile, + FoundReturnCode: Boolean; + BEGIN + + ReadLog := FALSE; + ToFile := FALSE; + IF (Protocol.TempLog <> '') THEN + BEGIN + Assign(TempLogTxt,FunctionalMCI(Protocol.TempLog,'','')); + Reset(TempLogTxt); + IF (IOResult = 0) THEN + BEGIN + ReadLog := TRUE; + IF (FunctionalMCI(Protocol.DLoadLog,'','') <> '') THEN + BEGIN + Assign(DLoadLogTxt,FunctionalMCI(Protocol.DLoadLog,'','')); + Append(DLoadLogTxt); + IF (IOResult = 2) THEN + ReWrite(DLoadLogTxt); + ToFile := TRUE; + END; + + SysOpLog('Start scan of: "^0'+AllCaps(FunctionalMCI(Protocol.TempLog,'',''))+'^1".'); + + WHILE (NOT EOF(TempLogTxt)) DO + BEGIN + ReadLn(TempLogTxt,LogStr); + IF (ToFile) THEN + WriteLn(DLoadLogTxt,LogStr); + FileStr := Copy(LogStr,Protocol.TempLogPF,((Length(LogStr) - Protocol.TempLogPF) - 1)); + StatStr := Copy(LogStr,Protocol.TempLogPS,((Length(LogStr) - Protocol.TempLogPS) - 1)); + + FileStr := ReverseSlash(FileStr); + + ChopOfSpace(FileStr); + + FoundReturnCode := FALSE; + FoundFile := FALSE; + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) AND (NOT FoundFile) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) AND (Pos(AllCaps(BatchDL.BDLFileName),AllCaps(FileStr)) <> 0) THEN + BEGIN + FoundFile := TRUE; + IF (FindReturnCode(Protocol.DLCode,Protocol.PRFlags,StatStr)) THEN + BEGIN + FoundReturnCode := TRUE; + UpdateSatistics(BatchDL); + Dec(RecNum); + IF (RecNum >= 0) AND (RecNum <= (FileSize(BatchDLFile) - 2)) THEN + FOR RecNum1 := RecNum TO (FileSize(BatchDLFile) - 2) DO + BEGIN + Seek(BatchDLFile,(RecNum1 + 1)); + Read(BatchDLFile,BatchDL); + Seek(BatchDLFile,RecNum1); + Write(BatchDLFile,BatchDL); + END; + Seek(BatchDLFile,(FileSize(BatchDLFile) - 1)); + Truncate(BatchDLFile); + END; + END; + Inc(RecNum); + END; + + IF (NOT FoundFile) THEN + SysOpLog('^7File not found: "^5'+BatchDL.BDLFileName+'^7"') + ELSE IF (NOT FoundReturnCode) THEN + SysOpLog('^7Return code not found: "^5'+BatchDL.BDLFileName+'^7"'); + END; + SysOpLog('End scan of: "^0'+AllCaps(FunctionalMCI(Protocol.TempLog,'',''))+'^1".'); + + Close(TempLogTxt); + IF (ToFile) THEN + Close(DLoadLogTxt); + END; + END; + + IF (NOT ReadLog) THEN + BEGIN + SysOpLog('Start scan of: "^0BATCHDL.DAT^1"'); + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) THEN + BEGIN + UpdateSatistics(BatchDL); + Dec(RecNum); + IF (RecNum >= 0) AND (RecNum <= (FileSize(BatchDLFile) - 2)) THEN + FOR RecNum1 := RecNum TO (FileSize(BatchDLFile) - 2) DO + BEGIN + Seek(BatchDLFile,(RecNum1 + 1)); + Read(BatchDLFile,BatchDL); + Seek(BatchDLFile,RecNum1); + Write(BatchDLFile,BatchDL); + END; + Seek(BatchDLFile,(FileSize(BatchDLFile) - 1)); + Truncate(BatchDLFile); + END; + Inc(RecNum); + END; + SysOpLog('End scan of: "^0BATCHDL.DAT^1"'); + END; + END; + +BEGIN + IF (NumBatchDLFiles = 0) THEN + BEGIN + NL; + Print('The batch download queue is empty.'); + Exit; + END; + + NL; + Print('^5Batch download (Statistics):^1'); + NL; + Star('^1Total file(s) : ^5'+FormatNumber(NumBatchDLFiles)+'^1'); + Star('^1Total size : ^5'+ConvertBytes(BatchDLSize,FALSE)+'^1'); + Star('^1Total file points : ^5'+FormatNumber(BatchDLPoints)+'^1'); + Star('^1Download time : ^5'+CTim(BatchDLTime)+'^1'); + Star('^1Time left online : ^5'+CTim(NSL)+'^1'); + + IF (BatchDLPoints > ThisUser.FilePoints) THEN + BEGIN + NL; + Print('^7Insufficient file points, remove file(s) from your batch queue!^1'); + NL; + Print('^1Chargeable : ^5'+FormatNumber(BatchDLPoints)+'^1'); + Print('^1Your account : ^5'+FormatNumber(ThisUser.FilePoints)+'^1'); + NL; + EditBatchDLQueue; + Exit; + END; + + IF (BatchDLTime > NSL) THEN + BEGIN + NL; + Print('^7Insufficient time left online, remove file(s) from your batch queue!^1'); + NL; + EditBatchDLQueue; + Exit; + END; + + ProtocolNumber := DoProtocol(Protocol,FALSE,TRUE,TRUE,FALSE); + + CASE ProtocolNumber OF + -1 : ; + -2 : Exit; + -3 : ; + -4 : ; + -5 : EditBatchDLQueue; + ELSE + IF (InCom) THEN + BEGIN + + Assign(BatchDLFile,General.DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + + FillChar(Totals,SizeOf(Totals),0); + + PurgeDir(TempDir+'UP\',FALSE); + + IF Exist(FunctionalMCI(Protocol.TempLog,'','')) THEN + Kill(FunctionalMCI(Protocol.TempLog,'','')); + + IF Exist(TempDir+'ARC\FILES.BBS') THEN + Kill(TempDir+'ARC\FILES.BBS'); + + IF Exist(FunctionalMCI(Protocol.DLFList,'','')) THEN + Kill(FunctionalMCI(Protocol.DLFList,'','')); + + NL; + AutoLogOff := PYNQ('Auto-logoff after file transfer? ',0,FALSE); + + NL; + IF PYNQ('Download file descriptions? ',0,FALSE) THEN + BEGIN + Assign(FileListTxt,TempDir+'ARC\FILES.BBS'); + ReWrite(FileListTxt); + Writeln(FileListTxt,StripColor(General.BBSName)+' Batch Download File Listing'); + WriteLn(FileListTxt); + + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) THEN + BEGIN + IF (BatchDL.BDLSection = -1) THEN + WriteLn(FileListTxt,PadLeftStr(Align(StripName(BatchDL.BDLFileName)),14)+' [No Description Available]') + ELSE + BEGIN + + SaveLastDirFileRecNum := LastDIRRecNum; + SaveLastDirFileName := LastDIRFileName; + FO := (FileRec(FileInfoFile).Mode <> FMClosed); + IF (FO) THEN + BEGIN + Close(FileInfoFile); + Close(ExtInfoFile); + END; + SaveFileArea := FileArea; + FileArea := BatchDL.BDLSection; + RecNo(FileInfo,StripName(BatchDL.BDLFileName),DirFileRecNum); + IF (BadDownloadPath) THEN + WriteLn(FileListTxt,PadLeftStr(Align(StripName(BatchDL.BDLFileName)),14)+' [Bad Download Path]') + ELSE IF (DirFileRecNum = -1) THEN + WriteLn(FileListTxt,PadLeftStr(Align(StripName(BatchDL.BDLFileName)),14)+' [File Not Found]') + ELSE + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,FileInfo); + WriteLn(FileListTxt,PadLeftStr(Align(StripName(BatchDL.BDLFileName)),14)+FileInfo.Description); + IF (FileInfo.VPointer <> -1) THEN + BEGIN + LoadVerbArray(FileInfo,ExtendedArray,NumExtDesc); + FOR Counter1 := 1 TO NumExtDesc DO + IF (ExtendedArray[Counter1] <> '') THEN + WriteLn(FileListTxt,PadLeftStr('',14)+ExtendedArray[Counter1]); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + FileArea := SaveFileArea; + IF (FO) THEN + InitFileArea(FileArea); + LastDIRRecNum := SaveLastDirFileRecNum; + LastDIRFileName := SaveLastDirFileName; + LastError := IOResult; + END; + WriteLn(FileListTxt); + END; + END; + Inc(RecNum); + END; + Close(FileListTxt); + + WITH BatchDL DO + BEGIN + BDLFileName := TempDir+'ARC\FILES.BBS'; + BDLOwnerName := Caps(ThisUser.Name); + BDLStorage := Disk; + BDLUserNum := UserNum; + BDLSection := -1; + BDLPoints := 0; + BDLUploader := UserNum; + BDLFSize := GetFileSize(TempDir+'ARC\FILES.BBS'); + BDLTime := (BDLFSize DIV Rate); + BDLFlags := []; + END; + + Seek(BatchDLFile,FileSize(BatchDLFILE)); + Write(BatchDLFile,BatchDL); + + Inc(NumBatchDLFiles); + Inc(BatchDLTime,BatchDL.BDLTime); + Inc(BatchDLSize,BatchDL.BDLFSize); + Inc(BatchDLPoints,BatchDL.BDLPoints); + + NL; + Print('^1File : ^5FILES.BBS^1'); + Print('^1Size : ^5'+ConvertBytes(BatchDL.BDLFSize,FALSE)+'^1'); + Print('^1File points : ^5'+FormatNumber(BatchDL.BDLPoints)+'^1'); + Print('^1Download time : ^5'+CTim(BatchDL.BDLTime)+'^1'); + NL; + Print('^1New download time : ^5'+CTim(BatchDLTime)+'^1'); + LastError := IOResult; + END; + + Reset(BatchDLFile); + Counter1 := 0; + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) AND (Counter1 = 0) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) AND (BatchDL.BDLStorage = CD) THEN + Inc(Counter1); + Inc(RecNum); + END; + + IF (Counter1 <> 0) THEN + BEGIN + NL; + Print('Please wait, copying files from CD-ROM ... '); + + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) AND (BatchDL.BDLStorage = CD) THEN + IF CopyMoveFile(TRUE,'',BatchDL.BDLFileName, + TempDir+'CD\'+StripName(BatchDL.BDLFileName),FALSE) THEN + BEGIN + BatchDL.BDLStorage := Copied; + BatchDL.BDLFileName := TempDir+'CD\'+StripName(BatchDL.BDLFileName); + Seek(BatchDLFile,(RecNum - 1)); + Write(BatchDLFile,BatchDL); + END; + Inc(RecNum); + END; + END; + + + NewFileName := General.ProtPath+FunctionalMCI(Protocol.DLCmd,'',''); + + ToXfer := 0; + + IF (Pos('%F',Protocol.DLCmd) <> 0) THEN + BEGIN + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) THEN + BEGIN + Inc(ToXFer); + NewFileName := FunctionalMCI(NewFileName,BatchDL.BDLFileName,''); + IF (Length(NewFileName) > Protocol.MaxChrs) THEN + BEGIN + SysOpLog('^7Exceeds maximum DOS char length: "^5'+NewFileName+'^1"'); + RecNum := FileSize(BatchDLFile); + END; + END; + Inc(RecNum); + END; + END; + + IF (Protocol.DLFList <> '') THEN + BEGIN + Assign(DLFListTxt,FunctionalMCI(Protocol.DLFList,'','')); + ReWrite(DLFListTxt); + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) THEN + BEGIN + WriteLn(DLFListTxt,BatchDL.BDLFileName); + Inc(ToXfer); + END; + Inc(RecNum); + END; + Close(DLFListTxt); + LastError := IOResult; + END; + + NL; + Star('Ready to send batch download transfer.'); + + ExecProtocol('', + TempDir+'UP\', + FunctionalMCI(Protocol.EnvCmd,'','') + +#13#10+ + NewFileName, + -1, + ReturnCode, + TransferTime); + + NL; + Star('Batch download transfer complete.'); + + IF Exist(FunctionalMCI(Protocol.DLFList,'','')) THEN + Kill(FunctionalMCI(Protocol.DLFList,'','')); + + IF Exist(TempDir+'ARC\FILES.BBS') THEN + BEGIN + Reset(BatchDLFile); + RecNum1 := -1; + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) AND (RecNum1 = -1) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF ((BatchDL.BDLUserNum = UserNum) AND (BatchDL.BDLFileName = TempDir+'ARC\FILES.BBS')) THEN + BEGIN + Dec(NumBatchDLFiles); + Dec(BatchDLTime,BatchDL.BDLTime); + Dec(BatchDLSize,BatchDL.BDLFSize); + Dec(BatchDLPoints,BatchDL.BDLPoints); + IF (BatchDL.BDLStorage = Copied) THEN + Kill(BatchDL.BDLFileName); + RecNum1 := RecNum; + END; + Inc(RecNum); + END; + IF (RecNum1 <> -1) THEN + BEGIN + Dec(RecNum1); + FOR RecNum := RecNum1 TO (FileSize(BatchDLFile) - 2) DO + BEGIN + Seek(BatchDLFile,(RecNum + 1)); + Read(BatchDLFile,BatchDL); + Seek(BatchDLFile,RecNum); + Write(BatchDLFile,BatchDL); + END; + Seek(BatchDLFile,(FileSize(BatchDLFile) - 1)); + Truncate(BatchDLFile); + END; + Kill(TempDir+'ARC\FILES.BBS'); + END; + + FigureSucc; + + IF Exist(FunctionalMCI(Protocol.TempLog,'','')) THEN + Kill(FunctionalMCI(Protocol.TempLog,'','')); + + IF ((DownloadsToday + Totals.FilesDL) < 2147483647) THEN + Inc(DownloadsToday,Totals.FilesDL) + ELSE + DownloadsToday := 2147483647; + + IF ((DownloadKBytesToday + (Totals.BytesDL DIV 1024)) < 2147483647) THEN + Inc(DownloadKBytesToday,(Totals.BytesDL DIV 1024)) + ELSE + DownloadKBytesToday := 2147483647; + + IF ((ThisUser.Downloads + Totals.FilesDLRatio) < 2147483647) THEN + Inc(ThisUser.Downloads,Totals.FilesDLRatio) + ELSE + ThisUser.Downloads := 2147483647; + + IF ((ThisUser.DLToday + Totals.FilesDLRatio) < 2147483647) THEN + Inc(ThisUser.DLToday,Totals.FilesDLRatio) + ELSE + ThisUser.DLToday := 2147483647; + + IF ((ThisUser.DK + (Totals.BytesDLRatio DIV 1024)) < 2147483647) THEN + Inc(ThisUser.DK,(Totals.BytesDLRatio DIV 1024)) + ELSE + ThisUser.DK := 2147483647; + + IF ((ThisUser.DLKToday + (Totals.BytesDLRatio DIV 1024)) < 2147483647) THEN + Inc(ThisUser.DLKToday,(Totals.BytesDLRatio DIV 1024)) + ELSE + ThisUser.DLKToday := 2147483647; + + IF ((ThisUser.FilePoints - Totals.PointsDLRatio) > 0) THEN + Dec(ThisUser.FilePoints,Totals.PointsDLRatio) + ELSE + ThisUser.FilePoints := 0; + + LIL := 0; + + NL; + Print('^5Batch download (Totals):^1'); + NL; + Star('^1Total file(s) : ^5'+FormatNumber(Totals.FilesDL)); + Star('^1Total size : ^5'+ConvertBytes(Totals.BytesDL,FALSE)); + Star('^1Total file points : ^5'+FormatNumber(Totals.PointsDL)); + Star('^1Download time : ^5'+FormattedTime(TransferTime)); + Star('^1Transfer rate : ^5'+FormatNumber(GetCPS(Totals.BytesDL,TransferTime))+' cps'); + + SysOpLog('^3 - Totals:'+ + ' '+FormatNumber(Totals.FilesDL)+' '+Plural('file',Totals.FilesDL)+ + ', '+ConvertBytes(Totals.BytesDL,FALSE)+ + ', '+FormatNumber(Totals.PointsDL)+' fp'+ + ', '+FormattedTime(TransferTime)+' tt'+ + ', '+FormatNumber(GetCPS(Totals.BytesDL,Transfertime))+' cps.'); + + IF (Totals.FilesDL < Totals.FilesDLRatio) THEN + Totals.FilesDLRatio := Totals.FilesDL; + + LIL := 0; + + NL; + Print('^5Batch download (Charges):^1'); + NL; + Star('^1Total file(s) : ^5'+FormatNumber(Totals.FilesDLRatio)); + Star('^1Total size : ^5'+ConvertBytes(Totals.BytesDLRatio,FALSE)); + Star('^1Total file points : ^5'+FormatNumber(Totals.PointsDLRatio)); + + SysOpLog('^3 - Charges:'+ + ' '+FormatNumber(Totals.FilesDLRatio)+' '+Plural('file',Totals.FilesDLRatio)+ + ', '+ConvertBytes(Totals.BytesDLRatio,FALSE)+ + ', '+FormatNumber(Totals.PointsDLRatio)+' fp.'); + + IF (NumBatchDLFiles > 0) THEN + BEGIN + + Totals.BytesDL := 0; + Totals.PointsDL := 0; + + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) THEN + BEGIN + Inc(Totals.BytesDL,BatchDL.BDLFSize); + Inc(Totals.PointsDL,BatchDL.BDLPoints); + END; + Inc(RecNum); + END; + + LIL := 0; + + NL; + Print('^5Batch download (Not Transferred):^1'); + NL; + Star('^1Total file(s) : ^5'+FormatNumber(NumBatchDLFiles)); + Star('^1Total size : ^5'+ConvertBytes(Totals.BytesDL,FALSE)); + Star('^1Total file points : ^5'+FormatNumber(Totals.PointsDL)); + + SysOpLog('^3 - Not downloaded:'+ + ' '+FormatNumber(NumBatchDLFiles)+' '+Plural('file',NumBatchDLFiles)+ + ', '+ConvertBytes(Totals.BytesDL,FALSE)+ + ', '+FormatNumber(Totals.PointsDL)+' fp.'); + END; + + Close(BatchDLFile); + + LIL := 0; + + NL; + Print('^5Enjoy the file(s), '+Caps(ThisUser.Name)+'!^1'); + PauseScr(FALSE); + + SaveURec(ThisUser,UserNum); + + IF (ProtBiDirectional IN Protocol.PRFlags) THEN + BatchUpload(TRUE,TransferTime); + + IF (AutoLogOff) THEN + CountDown + END; + END; +END; + +PROCEDURE ListBatchDLFiles; +VAR + FileNumToList: Byte; + RecNum: LongInt; +BEGIN + IF (NumBatchDLFiles = 0) THEN + BEGIN + NL; + Print('The batch download queue is empty.'); + Exit; + END; + Abort := FALSE; + Next := FALSE; + NL; + PrintACR('^4###:FileName.Ext Area Pts Bytes hh:mm:ss^1'); + PrintACR('^4===:============:=====:======:=============:========^1'); + Assign(BatchDLFile,General.DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + FileNumToList := 1; + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) THEN + BEGIN + PrintACR('^3'+PadRightInt(FileNumToList,3)+ + '^4:^5'+Align(StripName(BatchDL.BDLFileName))+ + ' '+AOnOff((BatchDL.BDLSection = -1),'^7 --- ','^5'+PadRightInt(CompFileArea(BatchDL.BDLSection,0),5))+ + ' ^4'+PadRightStr(FormatNumber(BatchDL.BDLPoints),6)+ + ' ^4'+PadRightStr(FormatNumber(BatchDL.BDLFSize),13)+ + ' ^7'+CTim(BatchDL.BDLTime)+ + AOnOff(IsNoRatio IN BatchDL.BDLFlags,'^5 [No-Ratio]','')+ + AOnOff(IsNoFilePoints IN BatchDL.BDLFlags,'^5 [No-Points]','')+'^1'); + Inc(FileNumToList); + END; + WKey; + Inc(RecNum); + END; + Close(BatchDLFile); + LastError := IOResult; + PrintACR('^4===:============:=====:======:=============:========^1'); + PrintACR('^3'+PadLeftStr('Totals:',22)+ + ' ^4'+PadRightStr(FormatNumber(BatchDLPoints),6)+ + ' '+PadRightStr(FormatNumber(BatchDLSize),13)+ + ' ^7'+CTim(BatchDLTime)+'^1'); + SysOpLog('Viewed the batch download queue.'); +END; + +PROCEDURE RemoveBatchDLFiles; +VAR + InputStr: Str3; + Counter, + FileNumToRemove: Byte; + RecNum, + RecNum1: LongInt; +BEGIN + IF (NumBatchDLFiles = 0) THEN + BEGIN + NL; + Print('The batch download queue is empty.'); + Exit; + END; + InputStr := '?'; + REPEAT + IF (InputStr = '?') THEN + ListBatchDLFiles; + NL; + Prt('File to remove? (^51^4-^5'+IntToStr(NumBatchDLFiles)+'^4) [^5?^4=^5List^4,^5^4=^5Quit^4]: '); + MPL(Length(IntToStr(NumBatchDLFiles))); + ScanInput(InputStr,^M'?'); + FileNumToRemove := StrToInt(InputStr); + IF (NOT (InputStr[1] IN ['?','-',^M])) THEN + IF (FileNumToRemove < 1) OR (FileNumToRemove > NumBatchDLFiles) THEN + BEGIN + NL; + Print('^7The range must be from 1 to '+IntToStr(NumBatchDLFiles)+'!^1'); + InputStr := '?'; + END + ELSE + BEGIN + Counter := 0; + Assign(BatchDLFile,General.DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) THEN + BEGIN + Inc(Counter); + IF (Counter = FileNumToRemove) THEN + BEGIN + Dec(NumBatchDLFiles); + Dec(BatchDLTime,BatchDL.BDLTime); + Dec(BatchDLSize,BatchDL.BDLFSize); + Dec(BatchDLPoints,BatchDL.BDLPoints); + IF (BatchDL.BDLStorage = Copied) THEN + Kill(BatchDL.BDLFileName); + NL; + Print('Removed from batch download queue: "^5'+StripName(BatchDL.BDLFileName)+'^1".'); + SysOpLog('Batch DL Remove: "^5'+StripName(BatchDL.BDLFileName)+'^1".'); + Dec(RecNum); + FOR RecNum1 := RecNum TO (FileSize(BatchDLFile) - 2) DO + BEGIN + Seek(BatchDLFile,(RecNum1 + 1)); + Read(BatchDLFile,BatchDL); + Seek(BatchDLFile,RecNum1); + Write(BatchDLFile,BatchDL); + END; + Seek(BatchDLFile,(FileSize(BatchDLFile) - 1)); + Truncate(BatchDLFile); + RecNum := FileSize(BatchDLFile); + END; + END; + Inc(RecNum); + END; + Close(BatchDLFile); + LastError := IOResult; + IF (NumBatchDLFiles <> 0) THEN + BEGIN + NL; + Print('^1Batch download queue: ^5'+IntToStr(NumBatchDLFiles)+' '+Plural('file',NumBatchDLFiles)+ + ', '+ConvertBytes(BatchDLSize,FALSE)+ + ', '+FormatNumber(BatchDLPoints)+ + ' '+Plural('file point',BatchDLPoints)+', '+FormattedTime(BatchDLTime)); + END + ELSE + BEGIN + BatchDLTime := 0; + BatchDLSize := 0; + BatchDLPoints := 0; + NL; + Print('The batch download queue is now empty.'); + SysOpLog('Cleared the batch download queue.'); + END; + END; + UNTIL (InputStr <> '?') OR (HangUp); +END; + +PROCEDURE ClearBatchDLQueue; +VAR + RecNum, + RecNum1: LongInt; +BEGIN + IF (NumBatchDLFiles = 0) THEN + BEGIN + NL; + Print('The batch download queue is empty.'); + Exit; + END; + NL; + IF PYNQ('Clear batch download queue? ',0,FALSE) THEN + BEGIN + NL; + Assign(BatchDLFile,General.DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) THEN + BEGIN + Dec(NumBatchDLFiles); + Dec(BatchDLTime,BatchDL.BDLTime); + Dec(BatchDLSize,BatchDL.BDLFSize); + Dec(BatchDLPoints,BatchDL.BDLPoints); + IF (BatchDL.BDLStorage = Copied) THEN + Kill(BatchDL.BDLFileName); + Print('Removed from batch download queue: "^5'+StripName(BatchDL.BDLFileName)+'^1".'); + SysOpLog('Batch DL Remove: "^5'+StripName(BatchDL.BDLFileName)+'^1".'); + Dec(RecNum); + FOR RecNum1 := RecNum TO (FileSize(BatchDLFile) - 2) DO + BEGIN + Seek(BatchDLFile,(RecNum1 + 1)); + Read(BatchDLFile,BatchDL); + Seek(BatchDLFile,RecNum1); + Write(BatchDLFile,BatchDL); + END; + Seek(BatchDLFile,(FileSize(BatchDLFile) - 1)); + Truncate(BatchDLFile); + END; + Inc(RecNum); + END; + Close(BatchDLFile); + LastError := IOResult; + BatchDLTime := 0; + BatchDLSize := 0; + BatchDLPoints := 0; + NL; + Print('The batch download queue is now empty.'); + SysOpLog('Cleared the batch download queue.'); + END; +END; + +END. diff --git a/SOURCE/FILE7.PAS b/SOURCE/FILE7.PAS new file mode 100644 index 0000000..b2ea1b3 --- /dev/null +++ b/SOURCE/FILE7.PAS @@ -0,0 +1,199 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File7; + +INTERFACE + +PROCEDURE CheckFilesBBS; + +IMPLEMENTATION + +USES + DOS, + Common, + File0, + File1, + File10, + TimeFunc; + +PROCEDURE AddToDirFile(FileInfo: FileInfoRecordType); +VAR + User: UserRecordType; + NumExtDesc: Byte; +BEGIN + LoadURec(User,1); + + WITH FileInfo DO + BEGIN + (* + FileName := ''; Value Passed + Description := ''; Value Passed + *) + FilePoints := 0; + Downloaded := 0; + (* + FileSize := 0; Value Passed + *) + OwnerNum := 1; + OwnerName := AllCaps(User.Name); + FileDate := Date2PD(DateStr); + VPointer := -1; + VTextSize := 0; + FIFlags := [FIHatched]; + END; + + IF (NOT General.FileCreditRatio) THEN + FileInfo.FilePoints := 0 + ELSE + BEGIN + FileInfo.FilePoints := 0; + IF (General.FileCreditCompBaseSize > 0) THEN + FileInfo.FilePoints := ((FileInfo.FileSize DIV 1024) DIV General.FileCreditCompBaseSize); + END; + + FillChar(ExtendedArray,SizeOf(ExtendedArray),0); + + IF (General.FileDiz) AND (DizExists(MemFileArea.DLPath+SQOutSp(FileInfo.FileName))) THEN + GetDiz(FileInfo,ExtendedArray,NumExtDesc); + + WriteFV(FileInfo,FileSize(FileInfoFile),ExtendedArray); + + IF (UploadsToday < 2147483647) THEN + Inc(UploadsToday); + + IF ((UploadKBytesToday + (FileInfo.FileSize DIV 1024)) < 2147483647) THEN + Inc(UploadKBytesToday,(FileInfo.FileSize DIV 1024)) + ELSE + UploadKBytesToday := 2147483647; + + SaveGeneral(FALSE); + + Print('^1hatched!'); + + SysOpLog(' Hatched: "^5'+SQOutSp(FileInfo.FileName)+'^1" to "^5'+MemFileArea.AreaName+'^1"'); + + LastError := IOResult; +END; + +(* Sample FILES.BBS +TDRAW463.ZIP THEDRAW SCREEN EDITOR VERSION 4.63 - (10/93) A text-orient +ZEJNGAME.LST [4777] 12-30-01 ZeNet Games list, Updated December 29th, 2 +*) + +PROCEDURE CheckFilesBBS; +VAR + BBSTxtFile: Text; + TempStr: AStr; + FArea, + SaveFileArea, + DirFileRecNum: Integer; + Found, + FirstTime, + SaveTempPause: Boolean; +BEGIN + SysOpLog('Scanning for FILES.BBS ...'); + SaveFileArea := FileArea; + SaveTempPause := TempPause; + TempPause := FALSE; + Abort := FALSE; + Next := FALSE; + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + + LoadFileArea(FArea); + + FirstTime := TRUE; + Found := FALSE; + LIL := 0; + CLS; + Prompt('^1Checking ^5'+MemFileArea.AreaName+' #'+IntToStr(CompFileArea(FArea,0))+'^1 ...'); + + IF (Exist(MemFileArea.DLPath+'FILES.BBS')) THEN + BEGIN + + Assign(BBSTxtFile,MemFileArea.DLPath+'FILES.BBS'); + Reset(BBSTxtFile); + WHILE NOT EOF(BBSTxtFile) DO + BEGIN + ReadLn(BBSTxtFile,TempStr); + TempStr := StripLeadSpace(TempStr); + IF (TempStr <> '') THEN + BEGIN + + FileInfo.FileName := Align(AllCaps(Copy(TempStr,1,(Pos(' ',TempStr) - 1)))); + + IF (FirstTime) THEN + BEGIN + NL; + NL; + FirstTime := FALSE; + END; + + Prompt('^1Processing "^5'+SQOutSp(FileInfo.FileName)+'^1" ... '); + + IF (NOT Exist(MemFileArea.DLPath+SQOutSp(FileInfo.FileName))) THEN + BEGIN + Print('^7missing!^1'); + SysOpLog(' ^7Missing: "^5'+SQOutSp(FileInfo.FileName)+'^7" from "^5'+MemFileArea.AreaName+'^7"'); + END + ELSE + BEGIN + FileArea := FArea; + RecNo(FileInfo,FileInfo.FileName,DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + IF (DirFileRecNum <> -1) THEN + BEGIN + Print('^7duplicate!^1'); + SysOpLog(' ^7Duplicate: "^5'+SQOutSp(FileInfo.FileName)+'^7" from "^5'+MemFileArea.AreaName+'^7"'); + END + ELSE + BEGIN + + TempStr := StripLeadSpace(Copy(TempStr,Pos(' ',TempStr),Length(TempStr))); + IF (TempStr[1] <> '[') THEN + FileInfo.Description := Copy(TempStr,1,50) + ELSE + BEGIN + TempStr := StripLeadSpace(Copy(TempStr,(Pos(']',TempStr) + 1),Length(TempStr))); + FileInfo.Description := StripLeadSpace(Copy(TempStr,(Pos(' ',TempStr) + 1),50)); + END; + + FileInfo.FileSize := GetFileSize(MemFileArea.DLPath+SQOutSp(FileInfo.FileName)); + + AddToDirFile(FileInfo); + + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; + Found := TRUE; + END; + END; + Close(BBSTxtFile); + + IF (NOT (FACDROM IN MemFileArea.FAFlags)) THEN + Erase(BBSTxtFile); + END; + + IF (NOT Found) THEN + BEGIN + LIL := 0; + BackErase(15 + LennMCI(MemFileArea.AreaName) + Length(IntToStr(CompFileArea(FArea,0)))); + END; + + Inc(FArea); + + END; + TempPause := SaveTempPause; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + LastError := IOResult; +END; + +END. \ No newline at end of file diff --git a/SOURCE/FILE8.PAS b/SOURCE/FILE8.PAS new file mode 100644 index 0000000..818404b --- /dev/null +++ b/SOURCE/FILE8.PAS @@ -0,0 +1,607 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File8; + +INTERFACE + +USES + Dos, + Common; + +PROCEDURE Send(FileInfo: FileInfoRecordType; + DirFileRecNum: Integer; + DownloadPath: PathStr; + VAR TransferFlags: TransferFlagSet); +PROCEDURE Receive(FileName: Str12; + UploadPath: PathStr; + ResumeFile: Boolean; + VAR UploadOk, + KeyboardAbort, + AddULBatch: Boolean; + VAR TransferTime: LongInt); + +IMPLEMENTATION + +USES + Crt, + ExecBat, + File0, + File1, + File2, + File4, + File6, + File12, + TimeFunc; + +{ CheckFileRatio + 1 - File bad + 2 - File + Batch bad + 3 - File Bad - Daily + 4 - File + Batch bad - Daily +} + +PROCEDURE CheckFileRatio(FileInfo: FileInfoRecordType; VAR ProtocolNumber: Integer); +VAR + Counter: Byte; + RecNum: LongInt; + FileKBSize: LongInt; + Ratio: Real; + BadRatio, + DailyLimits: Boolean; +BEGIN + FileKbSize := (FileInfo.FileSize DIV 1024); + + IF (NumBatchDLFiles > 0) THEN + BEGIN + Assign(BatchDLFile,General.DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) AND (BatchDL.BDLFileName = FileInfo.FileName) THEN + IF (NOT (IsNoRatio IN BatchDL.BDLFlags)) THEN + Inc(FileKBSize,(BatchDL.BDLFSize DIV 1024)); + Inc(RecNum); + END; + Close(BatchDLFile); + LastError := IOResult; + END; + + BadRatio := FALSE; + + IF (ThisUser.UK > 0) THEN + Ratio := ((FileKbSize + ThisUser.DK) / ThisUser.UK) + ELSE + Ratio := (FileKBSize + ThisUser.DK); + + IF (General.DLKRatio[ThisUser.SL] > 0) AND (Ratio > General.DLKRatio[ThisUser.SL]) THEN + BadRatio := TRUE; + + IF (ThisUser.Uploads > 0) THEN + Ratio := (((ThisUser.Downloads + NumBatchDLFiles) + 1) / ThisUser.Uploads) + ELSE + Ratio := ((ThisUser.Downloads + NumBatchDLFiles) + 1); + + IF (General.DLRatio[ThisUser.SL] > 0) AND (Ratio > General.DLRatio[ThisUser.SL]) THEN + BadRatio := TRUE; + + IF (NOT General.ULDLRatio) THEN + BadRatio := FALSE; + + DailyLimits := FALSE; + IF (General.DailyLimits) THEN + IF ((ThisUser.DLKToday + FileKbSize) > General.DLKOneDay[ThisUser.SL]) OR + (((ThisUser.DLToday + NumBatchDLFiles) + 1) > General.DLOneDay[ThisUser.SL]) THEN + BEGIN + BadRatio := TRUE; + DailyLimits := TRUE; + END; + + IF (AACS(General.NoDLRatio)) OR (FNoDLRatio IN ThisUser.Flags) THEN + BadRatio := FALSE; + + LoadFileArea(FileArea); + IF (FANoRatio IN MemFileArea.FAFlags) THEN + BadRatio := FALSE; + + Counter := 0; + + IF (BadRatio) THEN + IF (NumBatchDLFiles = 0) THEN + Counter := 1 + ELSE + Counter := 2; + + IF (DailyLimits) AND (Counter > 0) THEN + Inc(Counter,2); + + CASE Counter OF + 1,3 : BEGIN + IF (Counter = 3) THEN + BEGIN + PrintF('DLTMAX'); + IF (NoFile) THEN + BEGIN + { + NL; + Print('^5Your upload/download ratio is too poor to download this.'); + } + NL; + lRGLngStr(27,FALSE); + NL; + Print('^1Today you have downloaded '+FormatNumber(ThisUser.DLToday)+' '+Plural('file',ThisUser.DLToday)+ + '^1 totaling '+FormatNumber(ThisUser.DLKToday)+'k'); + NL; + Print('^1The maximum you can download in one day is '+FormatNumber(General.DLOneDay[ThisUser.SL])+ + ' '+Plural('file',General.DLOneDay[ThisUser.SL])+ + '^1 totaling '+FormatNumber(General.DLKOneDay[ThisUser.SL])+'k'); + END; + END + ELSE + BEGIN + PrintF('DLMAX'); + IF (NoFile) THEN + BEGIN + { + NL; + Print('^5Your upload/download ratio is too poor to download this.'); + } + NL; + lRGLngStr(27,FALSE); + NL; + Print('^5You have downloaded: '+FormatNumber(ThisUser.DK)+'k in '+FormatNumber(ThisUser.Downloads)+ + ' '+Plural('file',ThisUser.Downloads)); + Print('^5You have uploaded : '+FormatNumber(ThisUser.UK)+'k in '+FormatNumber(ThisUser.Uploads)+ + ' '+Plural('file',ThisUser.Uploads)); + NL; + Print('^5 1 upload for every '+FormatNumber(General.DLRatio[ThisUser.SL])+ + ' downloads must be maintained.'); + Print('^5 1k must be uploaded for every '+FormatNumber(General.DLKRatio[ThisUser.SL])+'k downloaded.'); + END; + END; + END; + 2,4 : BEGIN + IF (Counter = 4) THEN + PrintF('DLBTMAX') + ELSE + PrintF('DLBMAX'); + IF (NoFile) THEN + BEGIN + { + NL; + Print('^5Your upload/download ratio is too poor to download this.'); + } + NL; + lRGLngStr(27,FALSE); + NL; + Print('^5Assuming you download the files already in the batch queue,'); + IF (Counter = 2) THEN + Print('^5your upload/download ratio would be out of balance.') + ELSE + Print('^5you would exceed the maximum download limits for one day.'); + END; + END; + END; + IF (Counter IN [1..4]) THEN + BEGIN + SysOpLog('Download refused: Ratio out of balance: '+SQOutSp(FileInfo.FileName)); + SysOpLog(' ULs: '+FormatNumber(ThisUser.UK)+'k in '+FormatNumber(ThisUser.Uploads)+ + ' '+Plural('file',ThisUser.Uploads)+ + ' - DLs: '+FormatNumber(ThisUser.DK)+'k in '+FormatNumber(ThisUser.Downloads)+ + ' '+Plural('file',ThisUser.Downloads)); + ProtocolNumber := -2; + END; + +END; + +PROCEDURE BatchDLAdd(FileInfo: FileInfoRecordType; DownloadPath: Str40; TransferFlags: TransferFlagSet); +VAR + User: UserRecordType; +BEGIN + IF CheckBatchDL(DownloadPath+FileInfo.FileName) THEN + BEGIN + NL; + Print('^7This file is already in the batch download queue!^1'); + END + ELSE IF (NumBatchDLFiles = General.MaxBatchDLFiles) THEN + BEGIN + NL; + Print('^7The batch download queue is full!^1'); + END + ELSE IF ((BatchDLTime + (FileInfo.FileSize DIV Rate)) > NSL) THEN + BEGIN + NL; + Print('^7Insufficient time left online to add to the batch download queue!^1'); + END + ELSE + BEGIN + + Assign(BatchDLFile,General.DataPath+'BATCHDL.DAT'); + IF (NOT Exist(General.DataPath+'BATCHDL.DAT')) THEN + ReWrite(BatchDLFile) + ELSE + Reset(BatchDLFile); + + WITH BatchDL DO + BEGIN + + BDLFileName := SQOutSp(DownloadPath+FileInfo.FileName); + + IF (FileArea <> -1) THEN + BDLOwnerName := AllCaps(FileInfo.OwnerName) + ELSE + BEGIN + LoadURec(User,1); + BDLOwnerName := AllCaps(User.Name); + END; + + IF (IsCDRom IN TransferFlags) THEN + BDLStorage := CD + ELSE + BDLStorage := Disk; + + BDLUserNum := UserNum; + + BDLSection := FileArea; + + IF (FileArea <> -1) THEN + BDLPoints := FileInfo.FilePoints + ELSE + BDLPoints := 0; + + IF (FileArea <> -1) THEN + BDLUploader := FileInfo.OwnerNum + ELSE + BDLUploader := 1; + + BDLFSize := FileInfo.FileSize; + + BDLTime := (FileInfo.FileSize DIV Rate); + + IF (IsFileAttach IN TransferFlags) THEN + Include(BDLFlags,IsFileAttach) + ELSE IF (IsUnlisted IN TransferFlags) THEN + Include(BDLFlags,IsUnlisted) + ELSE IF (IsTempArc IN TransferFlags) THEN + Include(BDLFlags,IsTempArc) + ELSE IF (IsQWK IN TransferFlags) THEN + Include(BDLFlags,IsQWK); + + IF (NOT ChargeFilePoints(FileArea)) THEN + Include(BDLFlags,IsNoFilePoints); + + IF (NOT ChargeFileRatio(FileArea)) THEN + Include(BDLFlags,IsNoRatio); + + END; + Seek(BatchDLFile,FileSize(BatchDLFile)); + Write(BatchDLFile,BatchDL); + Close(BatchDLFile); + + Inc(NumBatchDLFiles); + + Inc(BatchDLSize,BatchDL.BDLFSize); + + Inc(BatchDLTime,BatchDL.BDLTime); + + Inc(BatchDLPoints,BatchDL.BDLPoints); + + { + NL; + Print('^5File added to batch download queue.'); + } + lRGLngStr(30,FALSE); + NL; + Print('^1Batch download queue:'+ + ' ^5'+IntToStr(NumBatchDLFiles)+' '+Plural('file',NumBatchDLFiles)+ + ', '+ConvertBytes(BatchDLSize,FALSE)+ + ', '+FormatNumber(BatchDLPoints)+' '+Plural('file point',BatchDLPoints)+ + ', '+FormattedTime(BatchDLTime)+'^1'); + + IF (IsFileAttach IN BatchDL.BDLFlags) THEN + MemFileArea.AreaName := 'File Attach' + ELSE IF (IsUnlisted IN BatchDL.BDLFlags) THEN + MemFileArea.AreaName := 'Unlisted Download' + ELSE IF (IsTempArc IN BatchDL.BDLFlags) THEN + MemFileArea.AreaName := 'Temporary Archive' + ELSE IF (IsQWK IN BatchDL.BDLFlags) THEN + MemFileArea.AreaName := 'QWK Download'; + + SysOpLog('Batch DL Add: "^5'+StripName(BatchDL.BDLFileName)+ + '^1" from ^5'+MemFileArea.AreaName); + END; +END; + +PROCEDURE Send(FileInfo: FileInfoRecordType; + DirFileRecNum: Integer; + DownloadPath: PathStr; + VAR TransferFlags: TransferFlagSet); +TYPE + TotalsRecordType = RECORD + FilesDL, + FilesDLRatio: Byte; + BytesDL, + BytesDLRatio, + PointsDL, + PointsDLRatio: LongInt; + END; +VAR + Totals: TotalsRecordType; + ReturnCode, + ProtocolNumber: Integer; + TransferTime: LongInt; +BEGIN + Exclude(TransferFlags,IsKeyboardAbort); + + Exclude(TransferFlags,IsTransferOk); + + IF (lIsAddDLBatch IN TransferFlags) THEN + ProtocolNumber := -4 + ELSE + ProtocolNumber := DoProtocol(Protocol,FALSE,TRUE,FALSE,FALSE); + + IF (IsCheckRatio IN TransferFlags) THEN + IF (-ProtocolNumber IN [1,4]) OR (NOT (-ProtocolNumber IN [2..3,5])) THEN + CheckFileRatio(FileInfo,ProtocolNumber); + + CASE ProtocolNumber OF + -2 : BEGIN + NL; + Print('^1Aborted!'); + Include(TransferFlags,IsKeyboardAbort); + END; + -3 : BEGIN + NL; + Print('^1Skipped!'); + END; + -4 : BatchDLAdd(FileInfo,DownloadPath,TransferFlags); + -5 : ; + ELSE + IF (InCom) OR (ProtocolNumber = -1) THEN + BEGIN + IF (ProtocolNumber = -1) THEN + BEGIN + NL; + Print('^5Caution: ^1No check is made to ensure the file you selected for viewing^1'); + Print('^1 is an ascii text file!'); + NL; + IF (NOT PYNQ('Continue to view selected file? ',0,FALSE)) THEN + BEGIN + Include(TransferFlags,IsKeyboardAbort); + Exit; + END; + END; + + IF (IsCDRom IN TransferFlags) THEN + BEGIN + NL; + Print('Please wait, copying file from CD-ROM ... '); + IF CopyMoveFile(TRUE,'',DownloadPath+SQOutSp(FileInfo.FileName),TempDir+'CD\'+SQOutSp(FileInfo.FileName),FALSE) THEN + DownloadPath := TempDir+'CD\'; + END; + + NL; + IF PYNQ('Auto-logoff after '+AOnOff(ProtocolNumber = -1,'viewing file','file transfer')+'? ',0,FALSE) THEN + Include(TransferFlags,IsAutoLogOff); + + NL; + Star('Ready to '+AOnOff(ProtocolNumber = -1,'view','send')+': ^5'+SQOutSp(FileInfo.FileName)+'.'); + + ExecProtocol(AOnOff(ProtocolNumber = -1,DownloadPath+SQOutSp(FileInfo.FileName),''), + TempDir+'UP\', + FunctionalMCI(Protocol.EnvCmd,'','')+ + #13#10 + +General.ProtPath+FunctionalMCI(Protocol.DLCmd,DownloadPath+SQOutSp(FileInfo.FileName),''), + 0, + ReturnCode, + TransferTime); + + NL; + Star('File '+AOnOff(ProtocolNumber = -1,'viewing','download')+' complete.'); + + IF (ProtocolNumber = -1) THEN + BEGIN + IF (ReturnCode = 0) THEN + Include(TransferFlags,IsTransferOk); + END + ELSE + BEGIN + IF FindReturnCode(Protocol.DLCode,Protocol.PRFlags,IntToStr(ReturnCode)) THEN + Include(TransferFlags,IsTransferOk); + END; + + IF (NOT (IsTransferOk IN TransferFlags)) THEN + BEGIN + NL; + Star(AOnOff(ProtocolNumber = -1,'Text view','Download')+' unsuccessful.'); + SysOpLog('^7'+AOnOff(ProtocolNumber = -1,'Text view','Download')+' failed: "^5'+SQOutSp(FileInfo.FileName)+ + '^7" from ^5'+MemFileArea.AreaName); + Include(TransferFlags,isPaused); + END + ELSE + BEGIN + LIL := 0; + + SysOpLog('^3'+AOnOff(ProtocolNumber = -1,'Viewed','Downloaded')+' "^5'+SQOutSp(FileInfo.FileName)+ + '^3" from ^5'+MemFileArea.AreaName+'.'); + + FillChar(Totals,SizeOf(Totals),0); + + Inc(Totals.FilesDL); + Inc(Totals.BytesDL,FileInfo.FileSize); + Inc(Totals.PointsDL,FileInfo.FilePoints); + + IF (ChargeFileRatio(FileArea)) THEN + BEGIN + Inc(Totals.FilesDLRatio); + Inc(Totals.BytesDLRatio,FileInfo.FileSize); + END; + + IF (ChargeFilePoints(FileArea)) THEN + Inc(Totals.PointsDLRatio,FileInfo.FilePoints); + + IF ((ThisUser.Downloads + Totals.FilesDLRatio) < 2147483647) THEN + Inc(ThisUser.Downloads,Totals.FilesDLRatio) + ELSE + ThisUser.Downloads := 2147483647; + + IF ((ThisUser.DLToday + Totals.FilesDLRatio) < 2147483647) THEN + Inc(ThisUser.DLToday,Totals.FilesDLRatio) + ELSE + ThisUser.DLToday := 2147483647; + + IF ((ThisUser.DK + (Totals.BytesDLRatio DIV 1024)) < 2147483647) THEN + Inc(ThisUser.DK,(Totals.BytesDLRatio DIV 1024)) + ELSE + ThisUser.DK := 2147483647; + + IF ((ThisUser.DLKToday + (Totals.BytesDLRatio DIV 1024)) < 2147483647) THEN + Inc(ThisUser.DLKToday,(Totals.BytesDLRatio DIV 1024)) + ELSE + ThisUser.DLKToday := 2147483647; + + IF ((ThisUser.FilePoints - Totals.PointsDLRatio) > 0) THEN + Dec(ThisUser.FilePoints,Totals.PointsDLRatio) + ELSE + ThisUser.FilePoints := 0; + + IF ((DownloadsToday + Totals.FilesDL) < 2147483647) THEN + Inc(DownloadsToday,Totals.FilesDL) + ELSE + DownloadsToday := 2147483647; + + IF ((DownloadKBytesToday + (Totals.BytesDL DIV 1024)) < 2147483647) THEN + Inc(DownloadKBytesToday,(Totals.BytesDL DIV 1024)) + ELSE + DownloadKBytesToday := 2147483647; + + SaveURec(ThisUser,UserNum); + + LIL := 0; + + NL; + Print('^5Download statistics (Totals):^1'); + NL; + Star('File name : ^5'+SQOutSp(FileInfo.FileName)); + Star('File size : ^5'+ConvertBytes(Totals.BytesDL,FALSE)); + Star('File point(s) : ^5'+FormatNumber(Totals.PointsDL)); + Star(AOnOff(ProtocolNumber = -1,'View time ','Download time ')+': ^5'+FormattedTime(TransferTime)); + Star('Transfer rate : ^5'+FormatNumber(GetCPS(FileInfo.FileSize,Transfertime))+' cps'); + + SysOpLog('^3 - Totals:'+ + ' '+FormatNumber(Totals.FilesDL)+' '+Plural('file',Totals.FilesDL)+ + ', '+ConvertBytes(Totals.BytesDL,FALSE)+ + ', '+FormatNumber(Totals.PointsDL)+' fp'+ + ', '+FormattedTime(TransferTime)+ + ', '+FormatNumber(GetCPS(Totals.BytesDL,Transfertime))+' cps.'); + LIL := 0; + + NL; + Print('^5Download statistics (Charges):^1'); + NL; + Star('File(s) : ^5'+FormatNumber(Totals.FilesDLRatio)); + Star('File size : ^5'+ConvertBytes(Totals.BytesDLRatio,FALSE)); + Star('File point(s) : ^5'+FormatNumber(Totals.PointsDLRatio)); + + SysOpLog('^3 - Charges:'+ + ' '+FormatNumber(Totals.FilesDLRatio)+' '+Plural('file',Totals.FilesDLRatio)+ + ', '+ConvertBytes(Totals.BytesDLRatio,FALSE)+ + ', '+FormatNumber(Totals.PointsDLRatio)+' fp.'); + + CreditUploader(FileInfo); + + IF (DirFileRecNum <> -1) THEN + BEGIN + Inc(FileInfo.Downloaded); + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,FileInfo); + LastError := IOResult; + END; + + LIL := 0; + + NL; + Print('^5Enjoy the file, '+Caps(ThisUser.Name)+'!^1'); + PauseScr(FALSE); + + END; + + IF (ProtBiDirectional IN Protocol.PRFlags) AND (NOT OfflineMail) THEN + BatchUpload(TRUE,0); + + IF (IsAutoLogoff IN TransferFlags) THEN + CountDown + END; + END; +END; + +PROCEDURE Receive(FileName: Str12; + UploadPath: PathStr; + ResumeFile: Boolean; + VAR UploadOk, + KeyboardAbort, + AddULBatch: Boolean; + VAR TransferTime: LongInt); +VAR + ReturnCode, + ProtocolNumber: Integer; +BEGIN + UploadOk := TRUE; + + KeyboardAbort := FALSE; + + TransferTime := 0; + + ProtocolNumber := DoProtocol(Protocol,TRUE,FALSE,FALSE,ResumeFile); + + CASE ProtocolNumber OF + -1 : UploadOk := FALSE; + -2 : BEGIN + UploadOk := FALSE; + KeyboardAbort := TRUE; + END; + -3 : BEGIN + UploadOk := FALSE; + KeyboardAbort := TRUE; + END; + -4 : AddULBatch := TRUE; + -5 : UploadOk := FALSE; + ELSE + IF (NOT InCom) THEN + UploadOk := FALSE + ELSE + BEGIN + + PurgeDir(TempDir+'UP\',FALSE); + + NL; + Star('Ready to receive: ^5'+SQOutSp(FileName)+'.'); + + TimeLock := TRUE; + + ExecProtocol('', + UploadPath, + FunctionalMCI(Protocol.EnvCmd,'','')+ + #13#10+ + General.ProtPath+FunctionalMCI(Protocol.ULCmd,SQOutSp(FileName),''), + 0, + ReturnCode, + TransferTime); + + TimeLock := FALSE; + + NL; + Star('File upload complete.'); + + UploadOk := FindReturnCode(Protocol.ULCode,Protocol.PRFlags,IntToStr(ReturnCode)); + END; + END; +END; + +END. diff --git a/SOURCE/FILE9.PAS b/SOURCE/FILE9.PAS new file mode 100644 index 0000000..beeeac2 --- /dev/null +++ b/SOURCE/FILE9.PAS @@ -0,0 +1,420 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT File9; + +INTERFACE + +USES + Common; + +PROCEDURE DosDir(CurDir: ASTR; CONST FSpec: Str12; Expanded: Boolean); +PROCEDURE DirF(Expanded: Boolean); +PROCEDURE DeleteFF(F: FileInfoRecordType; RN: Integer); +PROCEDURE ToggleFileAreaScanFlags; +PROCEDURE SetFileAreaNewScanDate; + +IMPLEMENTATION + +USES + Dos, + Common5, + File0, + File1, + TimeFunc; + +PROCEDURE DosDir(CurDir: ASTR; CONST FSpec: Str12; Expanded: Boolean); +VAR + (* + DirInfo: SearchRec; + *) + DT: DateTime; + TempStr: ASTR; + AmPm: Str2; + Online: Byte; + NumFiles, + NumDirs, + BytesUsed: LongInt; +BEGIN + CurDir := BSlash(CurDir,TRUE); + Abort := FALSE; + Next := FALSE; + FindFirst(CurDir[1]+':\*.*',VolumeID,DirInfo); + IF (DOSError <> 0) THEN + TempStr := 'has no label.' + ELSE + TempStr := 'is '+DirInfo.Name; + PrintACR(' Volume in drive '+UpCase(CurDir[1])+' '+TempStr); + + (* Add Serial Number if possible *) + + NL; + PrintACR(' Directory of '+CurDir); + NL; + TempStr := ''; + Online := 0; + NumFiles := 0; + NumDirs := 0; + BytesUsed := 0; + CurDir := CurDir + FSpec; + FindFirst(CurDir,AnyFile,DirInfo); + WHILE (DOSError = 0) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (NOT (DirInfo.Attr AND Directory = Directory)) OR (FileSysOp) THEN + IF (NOT (DirInfo.Attr AND VolumeID = VolumeID)) THEN + IF ((NOT (DirInfo.Attr AND DOS.Hidden = DOS.Hidden)) OR (UserNum = 1)) THEN + IF ((DirInfo.Attr AND DOS.Hidden = DOS.Hidden) AND + (NOT (DirInfo.Attr AND Directory = Directory))) OR + (NOT (DirInfo.Attr AND DOS.Hidden = DOS.Hidden)) THEN + BEGIN + IF (Expanded) THEN + BEGIN + UnPackTime(DirInfo.Time,DT); + ConvertAmPm(DT.Hour,AmPm); + TempStr := ZeroPad(IntToStr(DT.Month))+ + '/'+ZeroPad(IntToStr(DT.Day))+ + '/'+IntToStr(DT.Year)+ + ' '+ZeroPad(IntToStr(DT.Hour))+ + ':'+ZeroPad(IntToStr(DT.Min))+ + AmPm[1]; + END; + IF ((DirInfo.Attr AND Directory) = Directory) THEN + BEGIN + TempStr := TempStr+PadRightStr('',11); + TempStr := TempStr+PadRightStr('',14); + TempStr := TempStr+' '+DirInfo.Name; + Inc(NumDirs); + END + ELSE + BEGIN + TempStr := TempStr+' '+PadRightStr(FormatNumber(DirInfo.Size),23); + TempStr := TempStr+' '+DirInfo.Name; + Inc(NumFiles); + Inc(BytesUsed,DirInfo.Size); + END; + PrintACR(TempStr) + END + ELSE + BEGIN + Inc(Online); + IF ((DirInfo.Attr AND Directory) = Directory) THEN + BEGIN + TempStr := TempStr+PadLeftStr('['+DirInfo.Name+']',15); + Inc(NumDirs); + END + ELSE + BEGIN + TempStr := TempStr+PadLeftStr(DirInfo.Name,15); + Inc(NumFiles); + Inc(BytesUsed,DirInfo.Size); + END; + IF (Online = 5) THEN + BEGIN + PrintACR(TempStr); + TempStr := ''; + Online := 0; + END; + END; + FindNext(DirInfo); + END; + IF (DOSError <> 0) AND (Online IN [1..5]) THEN + PrintACR(TempStr); + IF (NumFiles = 0) THEN + PrintACR('File Not Found') + ELSE + BEGIN + PrintACR(PadRightStr(FormatNumber(NumFiles),16)+' File(s)'+ + PadRightStr(FormatNumber(BytesUsed),15)+' bytes'); + PrintACR(PadRightStr(FormatNumber(NumDirs),16)+' Dir(s)'+ + PadRightStr(FormatNumber(DiskFree(ExtractDriveNumber(CurDir))),16)+' bytes free'); + END; +END; + +PROCEDURE DirF(Expanded: Boolean); +VAR + FSpec: Str12; +BEGIN + NL; + Print('Raw directory.'); + { Print(FString.lGFNLine1); } + lRGLngStr(28,FALSE); + { Prt(FString.GFNLine2); } + lRGLngStr(29,FALSE); + GetFileName(FSpec); + NL; + LoadFileArea(FileArea); + DosDir(MemFileArea.DLPath,FSpec,Expanded); +END; + +PROCEDURE DeleteFF(F: FileInfoRecordType; RN: Integer); +VAR + ExtFile1: FILE; + S, + FN: STRING; + TotLoad, + DirFileRecNum: Integer; + TempVPointer: LongInt; +BEGIN + IF (RN <= FileSize(FileInfoFile)) AND (RN > -1) THEN + BEGIN + Seek(FileInfoFile,RN); + Read(FileInfoFile,F); + + F.VPointer := -1; + F.VTextSize := 0; + + Seek(FileInfoFile,RN); + Write(FileInfoFile,F); + + Reset(ExtInfoFile,1); + IF (FADirDLPath IN MemFileArea.FAFlags) THEN + FN := MemFileArea.DLPath+MemFileArea.FileName + ELSE + FN := General.Datapath+MemFileArea.FileName; + Assign(ExtFile1,FN+'.EX1'); + ReWrite(ExtFile1,1); + FOR DirFileRecNum := 0 TO (FileSize(FileInfoFile) - 1) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,F); + IF (F.VPointer <> -1) THEN + BEGIN + TempVPointer := (FileSize(ExtFile1) + 1); + Seek(ExtFile1,FileSize(ExtFile1)); + TotLoad := 0; + Seek(ExtInfoFile,(F.VPointer - 1)); + REPEAT + BlockRead(ExtInfoFile,S[0],1); + BlockRead(ExtInfoFile,S[1],Ord(S[0])); + Inc(TotLoad,(Length(S) + 1)); + BlockWrite(ExtFile1,S,(Length(S) + 1)); + UNTIL (TotLoad >= F.VTextSize); + F.VPointer := TempVPointer; + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,F); + END; + END; + Close(ExtInfoFile); + Erase(ExtInfoFile); + Close(ExtFile1); + ReName(ExtFile1,FN+'.EXT'); + + IF (RN <> (FileSize(FileInfoFile) - 1)) THEN + FOR DirFileRecNum := RN TO (FileSize(FileInfoFile) - 2) DO + BEGIN + Seek(FileInfoFile,(DirFileRecNum + 1)); + Read(FileInfoFile,F); + Seek(FileInfoFile,DirFileRecNum); + Write(FileInfoFile,F); + END; + Seek(FileInfoFile,(FileSize(FileInfoFile) - 1)); + Truncate(FileInfoFile); + END; + LastError := IOResult; +END; + +(* 1. Verify if CDROM's can have new files in them *) +PROCEDURE ToggleFileAreaScanFlags; +VAR + InputStr: Str11; + FirstFArea, + LastFArea, + FArea, + NumFAreas, + SaveFArea, + SaveFileArea: Integer; + SaveConfSystem, + SaveTempPause: Boolean; + + PROCEDURE ToggleScanFlags(FArea1: Integer; ScanType: Byte); + BEGIN + IF (FileArea <> FArea1) THEN + ChangeFileArea(FArea1); + IF (FileArea = FArea1) THEN + BEGIN + LoadNewScanFile(NewScanFileArea); + IF (ScanType = 1) THEN + NewScanFileArea := TRUE + ELSE IF (ScanType = 2) THEN + NewScanFileArea := FALSE + ELSE IF (ScanType = 3) THEN + NewScanFileArea := (NOT NewScanFileArea); + SaveNewScanFile(NewScanFileArea); + END; + END; + +BEGIN + SaveFileArea := FileArea; + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + SaveTempPause := TempPause; + TempPause := FALSE; + FArea := 1; + NumFAreas := 0; + LightBarCmd := 1; + LightBarFirstCmd := TRUE; + InputStr := '?'; + REPEAT + SaveFArea := FArea; + IF (InputStr = '?') THEN + LFileAreaList(FArea,NumFAreas,5,TRUE); + { + %LFToggle new scan? [^5#^4,^5#^4-^5#^4,^5F^4=^5Flag ^4or ^5U^4=^5Unflag All^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ + } + FileAreaScanInput(LRGLngStr(74,TRUE),((Length(IntToStr(HighFileArea)) * 2) + 1),InputStr,'QFU[]?',LowFileArea, + HighFileArea); + IF (InputStr <> 'Q') THEN + BEGIN + IF (InputStr = '[') THEN + BEGIN + FArea := (SaveFArea - ((PageLength - 5) * 2)); + IF (FArea < 1) THEN + FArea := 1; + InputStr := '?'; + END + ELSE IF (InputStr = ']') THEN + BEGIN + IF (FArea > NumFileAreas) THEN + FArea := SaveFArea; + InputStr := '?'; + END + ELSE IF (InputStr = '?') THEN + BEGIN + { + $File_Message_Area_List_Help + %LF^1(^3###^1)Manual entry selection ^1(^3^1)Select current entry + ^1(^3^1)First entry on page ^1(^3^1)Last entry on page + ^1(^3Left Arrow^1)Previous entry ^1(^3Right Arrow^1)Next entry + ^1(^3Up Arrow^1)Move up ^1(^3Down Arrow^1)Move down + ^1(^3[^1)Previous page ^1(^3]^1)Next page + %PA + } + LRGLngStr(71,FALSE); + FArea := SaveFArea; + END + ELSE + BEGIN + FileArea := 0; + IF (InputStr = 'F') THEN + BEGIN + FOR FArea := 1 TO NumFileAreas DO + ToggleScanFlags(FArea,1); + { + %LFYou are now scanning all file areas. + } + LRGLngStr(86,FALSE); + Farea := 1; + InputStr := '?'; + END + ELSE IF (InputStr = 'U') THEN + BEGIN + FOR FArea := 1 TO NumFileAreas DO + ToggleScanFlags(FArea,2); + { + %LFYou are now not scanning any file areas. + } + LRGLngStr(88,FALSE); + Farea := 1; + InputStr := '?'; + END + ELSE + BEGIN + FirstFArea := StrToInt(InputStr); + IF (Pos('-',InputStr) = 0) THEN + LastFArea := FirstFArea + ELSE + BEGIN + LastFArea := StrToInt(Copy(InputStr,(Pos('-',InputStr) + 1),(Length(InputStr) - Pos('-',InputStr)))); + IF (FirstFArea > LastFArea) THEN + BEGIN + FArea := FirstFArea; + FirstFArea := LastFArea; + LastFArea := FArea; + END; + END; + IF (FirstFArea < LowFileArea) OR (LastFArea > HighFileArea) THEN + BEGIN + { + %LF^7The range must be from %A1 to %A2!^1 + } + LRGLngStr(90,FALSE); + Farea := SavefArea; + InputStr := '?'; + END + ELSE + BEGIN + FirstFArea := CompFileArea(FirstFArea,1); + LastFArea := CompFileArea(LastFArea,1); + FOR FArea := FirstFArea TO LastFArea DO + ToggleScanFlags(FArea,3); + IF (FirstFArea = LastFArea) THEN + BEGIN + { + %LF^5%FB^3 will %FSbe scanned. + } + LRGLngStr(92,FALSE); + END; + Farea := SaveFArea; + InputStr := '?'; + END; + END; + FileArea := SaveFileArea; + END; + END; + UNTIL (InputStr = 'Q') OR (HangUp); + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + TempPause := SaveTempPause; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + LastCommandOvr := TRUE; +END; + +(* Done - Lee Palmer 06/18/06 *) +PROCEDURE SetFileAreaNewScanDate; +VAR + TempDate: Str10; + Key: CHAR; +BEGIN + { + NL; + Prt(FString.FileNewScan); + } + lRGLngStr(54,FALSE); + MPL(10); + Prompt(PD2Date(NewFileDate)); + Key := Char(GetKey); + IF (Key = #13) THEN + BEGIN + NL; + TempDate := PD2Date(NewFileDate); + END + ELSE + BEGIN + Buf := Key; + DOBackSpace(1,10); + InputFormatted('',TempDate,'##/##/####',TRUE); + IF (TempDate = '') THEN + TempDate := PD2Date(NewFileDate); + END; + IF (DayNum(TempDate) = 0) OR (DayNum(TempDate) > DayNum(DateStr)) THEN + BEGIN + NL; + Print('^7Invalid date entered!^1'); + END + ELSE + BEGIN + NL; + Print('New file scan date set to: ^5'+TempDate+'^1'); + NewFileDate := Date2PD(TempDate); + SL1('Reset file new scan date to: ^5'+TempDate+'.'); + END; +END; + +END. diff --git a/SOURCE/LINECHAT.PAS b/SOURCE/LINECHAT.PAS new file mode 100644 index 0000000..0a4e0a3 --- /dev/null +++ b/SOURCE/LINECHAT.PAS @@ -0,0 +1,454 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT LineChat; + +INTERFACE + +USES + Common; + +PROCEDURE RequestSysOpChat(CONST MenuOption: Str50); +PROCEDURE ChatFileLog(b: Boolean); +PROCEDURE SysOpLineChat; + +IMPLEMENTATION + +USES + Crt, + Dos, + Email, + Events, + TimeFunc; + +PROCEDURE RequestSysOpChat(CONST MenuOption: Str50); +VAR + User: UserRecordType; + MHeader: MHeaderRec; + Reason: AStr; + Cmd: Char; + Counter: Byte; + UNum, + Counter1: Integer; + Chatted: Boolean; +BEGIN + IF (ChatAttempts < General.MaxChat) OR (CoSysOp) THEN + BEGIN + NL; + IF (Pos(';',MenuOption) <> 0) THEN + Print(Copy(MenuOption,(Pos(';',MenuOption) + 1),Length(MenuOption))) + ELSE + lRGLngStr(37,FALSE); { FString.ChatReason; } + Chatted := FALSE; + Prt(': '); + MPL(60); + InputL(Reason,60); + IF (Reason <> '') THEN + BEGIN + Inc(ChatAttempts); + SysOpLog('^4Chat attempt:'); + SL1(Reason); + IF (NOT SysOpAvailable) AND AACS(General.OverRideChat) THEN + PrintF('CHATOVR'); + IF (SysOpAvailable) OR (AACS(General.OverRideChat) AND PYNQ(^M^J'SysOp is not available. Override? ',0,FALSE)) THEN + BEGIN + lStatus_Screen(100,'Press [SPACE] to chat or [ENTER] for silence.',FALSE,Reason); + { Print(FString.ChatCall1); } + lRGLngStr(14,FALSE); + Counter := 0; + Abort := FALSE; + NL; + REPEAT + Inc(Counter); + WKey; + IF (OutCom) THEN + Com_Send(^G); + { Prompt(FString.ChatCall2); } + lRGLngStr(15,FALSE); + IF (OutCom) THEN + Com_Send(^G); + IF (ShutUpChatCall) THEN + Delay(600) + ELSE + BEGIN +{$IFDEF MSDOS} + FOR Counter1 := 300 DOWNTO 2 DO + BEGIN + Delay(1); + Sound(Counter1 * 10); + END; + FOR Counter1 := 2 TO 300 DO + BEGIN + Delay(1); + Sound(Counter1 * 10); + END; + NoSound; +{$ENDIF} +{$IFDEF WIN32} + Sound(3000, 200); + Sound(1000, 200); + Sound(3000, 200); +{$ENDIF} + END; + IF (KeyPressed) THEN + BEGIN + Cmd := ReadKey; + CASE Cmd OF + #0 : BEGIN + Cmd := ReadKey; + SKey1(Cmd); + END; + #32 : BEGIN + Chatted := TRUE; + ChatAttempts := 0; + SysOpLineChat; + END; + ^M : ShutUpChatCall := TRUE; + END; + END; + UNTIL (Counter = 9) OR (Chatted) OR (Abort) OR (HangUp); + NL; + END; + lStatus_Screen(100,'Chat Request: '+Reason,FALSE,Reason); + IF (Chatted) THEN + ChatReason := '' + ELSE + BEGIN + ChatReason := Reason; + PrintF('NOSYSOP'); + UNum := StrToInt(MenuOption); + IF (UNum > 0) THEN + BEGIN + InResponseTo := #1'Tried chatting'; + LoadURec(User,UNum); + NL; + IF PYNQ('Send mail to '+Caps(User.Name)+'? ',0,FALSE) THEN + BEGIN + MHeader.Status := []; + SEmail(UNum,MHeader); + END; + END; + END; + TLeft; + END; + END + ELSE + BEGIN + PrintF('GOAWAY'); + UNum := StrToInt(MenuOption); + IF (UNum > 0) THEN + BEGIN + InResponseTo := 'Tried chatting (more than '+IntToStr(General.MaxChat)+' times!)'; + SysOpLog(InResponseTo); + MHeader.Status := []; + SEmail(UNum,MHeader); + END; + END; +END; + +PROCEDURE ChatFileLog(b: Boolean); +VAR + s: AStr; +BEGIN + s := 'Chat'; + IF (ChatSeparate IN ThisUser.SFlags) THEN + s := s + IntToStr(UserNum); + s := General.LogsPath+s+'.LOG'; + IF (NOT b) THEN + BEGIN + IF (CFO) THEN + BEGIN + lStatus_Screen(100,'Chat recorded to '+s,FALSE,s); + CFO := FALSE; + IF (TextRec(ChatFile).Mode <> FMClosed) THEN + Close(ChatFile); + END; + END + ELSE + BEGIN + CFO := TRUE; + IF (TextRec(ChatFile).Mode = FMOutPut) THEN + Close(ChatFile); + Assign(ChatFile,s); + Append(ChatFile); + IF (IOResult = 2) THEN + ReWrite(ChatFile); + IF (IOResult <> 0) THEN + SysOpLog('Cannot open chat log file: '+s); + lStatus_Screen(100,'Recording chat to '+s,FALSE,s); + WriteLn(ChatFile); + WriteLn(ChatFile); + WriteLn(ChatFile,Dat); + WriteLn(ChatFile); + Writeln(ChatFile,'Recorded with user: '+Caps(ThisUser.Name)); + WriteLn(ChatFile); + WriteLn(ChatFile,'Chat reason: '+AOnOff(ChatReason = '','None',ChatReason)); + WriteLn(ChatFile); + WriteLn(ChatFile); + WriteLn(ChatFile,'------------------------------------'); + WriteLn(ChatFile); + END; +END; + +PROCEDURE InLi1(VAR S: STRING); +VAR + C, + C1: Char; + Counter, + Counter1, + CPos: Byte; +BEGIN + CPos := 1; + S := ''; + IF (LastLineStr <> '') THEN + BEGIN + Prompt(LastLineStr); + S := LastLineStr; + LastLineStr := ''; + CPos := (Length(S) + 1); + END; + + REPEAT + C := Char(GetKey); + CheckHangUp; + CASE Ord(C) OF + 32..255 : + IF (CPos < 79) THEN + BEGIN + S[CPos] := C; + Inc(CPos); + OutKey(C); + IF (Trapping) THEN + Write(TrapFile,C); + END; + 16 : IF (OkANSI OR OkAvatar) THEN + BEGIN + C1 := Char(GetKey); + UserColor(Ord(C1) - 48); + END; + 27 : IF (CPos < 79) THEN + BEGIN + S[CPos] := C; + Inc(CPos); + OutKey(C); + IF (Trapping) THEN + Write(TrapFile,C); + END; + 8 : IF (CPos > 1) THEN + BEGIN + Dec(CPos); + BackSpace; + END; + 24 : BEGIN + FOR Counter := 1 TO (CPos - 1) DO + BackSpace; + CPos := 1; + END; + 7 : IF (OutCom) THEN + Com_Send(^G); + 23 : IF (CPos > 1) THEN + REPEAT + Dec(CPos); + BackSpace; + UNTIL (CPos = 1) OR (S[CPos] = ' '); + 9 : BEGIN + Counter := (5 - (CPos MOD 5)); + IF ((CPos + Counter) < 79) THEN + FOR Counter1 := 1 TO Counter DO + BEGIN + S[CPos] := ' '; + Inc(CPos); + Prompt(' '); + END; + END; + END; + UNTIL ((C = ^M) OR (CPos = 79) OR (HangUp) OR (NOT InChat)); + IF (NOT InChat) THEN + BEGIN + C := #13; + InChat := FALSE; + END; + S[0] := Chr(CPos - 1); + IF (C <> ^M) THEN + BEGIN + Counter := (CPos - 1); + WHILE (Counter > 0) AND (S[Counter] <> ' ') AND (S[Counter] <> ^H) DO + Dec(Counter); + IF (Counter > (CPos DIV 2)) AND (Counter <> (CPos - 1)) THEN + BEGIN + LastLineStr := Copy(S,(Counter + 1),(CPos - Counter)); + FOR Counter1 := (CPos - 2) DOWNTO Counter DO + Prompt(^H); + FOR Counter1 := (CPos - 2) DOWNTO Counter DO + Prompt(' '); + S[0] := Chr(Counter - 1); + END; + END; + NL; +END; + +PROCEDURE SysOpLineChat; +VAR + S: AStr; + Counter: Integer; + ChatTime: LongInt; + SaveEcho, + SavePrintingFile, + SaveMCIAllowed: Boolean; +BEGIN + UserColor(1); + SaveMCIAllowed := MCIAllowed; + MCIAllowed := TRUE; + ChatTime := GetPackDateTime; + DOSANSIOn := FALSE; + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + SaveNAvail := (NAvail IN Noder.Status); + Exclude(Noder.Status,NAvail); + SaveNode(ThisNode); + END; + SavePrintingFile := PrintingFile; + InChat := TRUE; + ChatCall := FALSE; + SaveEcho := Echo; + Echo := TRUE; + IF (General.AutoChatOpen) THEN + ChatFileLog(TRUE) + ELSE IF (ChatAuto IN ThisUser.SFlags) THEN + ChatFileLog(TRUE); + NL; + Exclude(ThisUser.Flags,Alert); + PrintF('CHATINIT'); + IF (NoFile) THEN + (* + Prompt('^5'+FString.EnGage); + *) + lRGLNGStr(2,FALSE); + + UserColor(General.SysOpColor); + WColor := TRUE; + + IF (ChatReason <> '') THEN + BEGIN + lStatus_Screen(100,ChatReason,FALSE,S); + ChatReason := ''; + END; + + REPEAT + + InLi1(S); + + IF (S[1] = '/') THEN + S := AllCaps(S); + + IF (Copy(S,1,6) = '/TYPE ') AND (SysOp) THEN + BEGIN + S := Copy(S,7,(Length(S) - 6)); + IF (S <> '') THEN + BEGIN + PrintFile(S); + IF (NoFile) THEN + Print('*File not found*'); + END; + END + ELSE IF ((S = '/HELP') OR (S = '/?')) THEN + BEGIN + IF (SysOp) THEN + Print('^5/TYPE d:\path\filename.ext^3: Type a file'); + (* + Print('^5/BYE^3: Hang up'); + Print('^5/CLS^3: Clear the screen'); + Print('^5/PAGE^3: Page the SysOp and User'); + Print('^5/Q^3: Exit chat mode'^M^J); + *) + lRGLngStr(65,FALSE); + END + ELSE IF (S = '/CLS') THEN + CLS + ELSE IF (S = '/PAGE') THEN + BEGIN +{$IFDEF MSDOS} + FOR Counter := 650 TO 700 DO + BEGIN + Sound(Counter); + Delay(4); + NoSound; + END; + REPEAT + Dec(Counter); + Sound(Counter); + Delay(2); + NoSound; + UNTIL (Counter = 200); +{$ENDIF} +{$IFDEF WIN32} + Sound(650, 200); + Sound(700, 200); + Sound(600, 200); + Sound(500, 200); + Sound(400, 200); + Sound(300, 200); +{$ENDIF} + Prompt(^G^G); + END + ELSE IF (S = '/BYE') THEN + BEGIN + Print('Hanging up ...'); + HangUp := TRUE; + END + ELSE IF (S = '/Q') THEN + BEGIN + InChat := FALSE; + Print('Chat Aborted ...'); + END; + IF (CFO) THEN + WriteLn(ChatFile,S); + UNTIL ((NOT InChat) OR (HangUp)); + + PrintF('CHATEND'); + IF (NoFile) THEN + (* + Print('^5'+FString.lEndChat); + *) + lRGLngStr(3,FALSE); + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + IF (SaveNAvail) THEN + Include(Noder.Status,NAvail); + SaveNode(ThisNode); + END; + ChatTime := (GetPackDateTime - ChatTime); + IF (ChopTime = 0) THEN + Inc(FreeTime,ChatTime); + TLeft; + S := 'Chatted for '+FormattedTime(ChatTime); + IF (CFO) THEN + BEGIN + S := S+' -{ Recorded in Chat'; + IF (ChatSeparate IN ThisUser.SFlags) THEN + S := S + IntToStr(UserNum); + S := S+'.LOG }-'; + END; + SysOpLog(S); + InChat := FALSE; + Echo := SaveEcho; + IF ((HangUp) AND (CFO)) THEN + BEGIN + WriteLn(ChatFile); + WriteLn(ChatFile,'=> User disconnected'); + WriteLn(ChatFile); + END; + PrintingFile := SavePrintingFile; + IF (CFO) THEN + ChatFileLog(FALSE); + IF (InVisEdit) THEN + Buf := ^L; + MCIAllowed := SaveMCIAllowed; +END; + +END. diff --git a/SOURCE/LOGON.PAS b/SOURCE/LOGON.PAS new file mode 100644 index 0000000..8581121 --- /dev/null +++ b/SOURCE/LOGON.PAS @@ -0,0 +1,1194 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Logon; + +INTERFACE + +FUNCTION GetUser: Boolean; + +IMPLEMENTATION + +USES + Crt, + Common, + Archive1, + CUser, + Doors, + Email, + Events, + Mail0, + Mail1, + Maint, + Menus, + Menus2, + NewUsers, + ShortMsg, + SysOp2G, + TimeFunc, + MiscUser; + +VAR + GotName: Boolean; + OldUser: UserRecordType; + +FUNCTION Hex(i: LongInt; j: Byte): STRING; +CONST + hc : ARRAY [0..15] OF Char = '0123456789ABCDEF'; +VAR + One, + Two, + Three, + Four: Byte; +BEGIN + One := (i AND $000000FF); + Two := (i AND $0000FF00) SHR 8; + Three := (i AND $00FF0000) SHR 16; + Four := (i AND $FF000000) SHR 24; + Hex[0] := chr(j); { Length of STRING = 4 or 8} + IF (j = 4) THEN + BEGIN + Hex[1] := hc[Two SHR 4]; + Hex[2] := hc[Two AND $F]; + Hex[3] := hc[One SHR 4]; + Hex[4] := hc[One AND $F]; + END + ELSE + BEGIN + Hex[8] := hc[One AND $F]; + Hex[7] := hc[One SHR 4]; + Hex[6] := hc[Two AND $F]; + Hex[5] := hc[Two SHR 4]; + Hex[4] := hc[Three AND $F]; + Hex[3] := hc[Three SHR 4]; + Hex[2] := hc[Four AND $F]; + Hex[1] := hc[Four SHR 4]; + END; +END; + +PROCEDURE IEMSI; +VAR + Tries: Byte; + T1,T2: LongInt; + Emsi_Irq: STRING[20]; + Done,Success: Boolean; + S,Isi: STRING; + C: Char; + I: Integer; + Buffer: ARRAY [1..2048] OF Char; + Buffptr: Integer; + User: UserRecordType; + NextItemPointer: Integer; + + FUNCTION NextItem: STRING; + VAR + S: AStr; + BEGIN + S := ''; + WHILE (NextItemPointer < 2048) AND (Buffer[NextItemPointer] <> #0) AND (Buffer [NextItemPointer] <> '{') DO + Inc(NextItemPointer); + IF (Buffer[NextItemPointer] = '{') THEN + Inc(NextItemPointer); + WHILE (NextItemPointer < 2048) AND (Buffer[NextItemPointer] <> #0) AND (Buffer [NextItemPointer] <> '}') DO + BEGIN + S := S + Buffer[NextItemPointer]; + Inc(NextItemPointer); + END; + IF (Buffer[NextItemPointer] = '}') THEN + Inc(NextItemPointer); + NextItem := S; + END; + +BEGIN + FillChar(IEMSIRec,SizeOf(IEMSIRec),0); + IF (ComPortSpeed = 0) OR (NOT General.UseIEMSI) THEN + Exit; + (* Should this be Prompt ??? + Write('Attempting IEMSI negotiation ... '); + *) + Write(RGNoteStr(21,TRUE)); + FillChar(Buffer,SizeOf(Buffer),0); + T1 := Timer; + T2 := Timer; + Tries := 0; + Done := FALSE; + Success := FALSE; + Emsi_Irq := '**EMSI_IRQ8E08'^M^L; + Com_Flush_Recv; + SerialOut(Emsi_Irq); + S := ''; + REPEAT + HangUp := NOT Com_Carrier; + IF (ABS(T1 - Timer) > 2) THEN + BEGIN + T1 := Timer; + Inc(Tries); + IF (Tries >= 2) THEN + Done := TRUE + ELSE + BEGIN + Com_Flush_Recv; + SerialOut(Emsi_Irq); + END; + END; + IF (ABS(T2 - Timer) >= 8) THEN + Done := TRUE; + C := Cinkey; + IF (C > #0) THEN + BEGIN + IF (Length(S) >= 160) THEN + Delete(S, 1, 120); + S := S + C; + IF (Pos('**EMSI_ICI', S) > 0) THEN + BEGIN + Delete(S,1,Pos('EMSI_ICI',S) - 1); + Move(S[1],Buffer[1],Length(S)); + Buffptr := Length(S); + T1 := Timer; + REPEAT + C := Cinkey; + IF NOT (C IN [#0, #13]) THEN + BEGIN + Inc(Buffptr); + Buffer[Buffptr] := C; + END; + UNTIL (HangUp) OR (ABS(Timer - T1) > 4) OR (C = ^M) OR (Buffptr = 2048); + S [0] := #8; + Move(Buffer[Buffptr - 7],S[1],8); + Dec(Buffptr,8); + IF (S = Hex(UpdateCRC32($Ffffffff,Buffer[1],Buffptr),8)) THEN + BEGIN + LoadURec(User,1); + Isi := '{Renegade,'+General.Version+'}{'+General.BBSName+'}{'+User.CityState+ + '}{'+General.SysOpName+'}{'+Hex(GetPackDateTime,8)+ + '}{Live free or die!}{}{Everything!}'; + Isi := 'EMSI_ISI'+ Hex(Length(Isi),4) + Isi; + Isi := Isi + Hex(UpdateCRC32($Ffffffff,Isi[1],Length(Isi)),8); + Isi := '**' + Isi + ^M; + Com_Flush_Recv; + SerialOut(Isi); + Tries := 0; + T1 := Timer; + S := ''; + REPEAT + IF (ABS(Timer - T1) >= 3) THEN + BEGIN + T1 := Timer; + Inc(Tries); + Com_Flush_Recv; + SerialOut(Isi); + END; + C := Cinkey; + IF (C > #0) THEN + BEGIN + IF (Length(S) >= 160) THEN + Delete(S,1,120); + S := S + C; + IF (Pos('**EMSI_ACK', S) > 0) THEN + BEGIN + Com_Flush_Recv; + Com_Purge_Send; + Done := TRUE; + Success := TRUE; + END + ELSE IF (Pos('**EMSI_NAKEEC3',S) > 0) THEN + BEGIN + Com_Flush_Recv; + SerialOut(Isi); + Inc(Tries); + END; + END; + UNTIL (Tries >= 3) OR (Done); + END + ELSE + BEGIN + SerialOut('**EMSI_NAKEEC3'); + T1 := Timer; + END; + END; + END; + UNTIL (Done) OR (HangUp); + IF (Success) THEN + BEGIN + (* Should this be print ??? + WriteLn('success.'); + *) + Writeln(RGNOteStr(22,TRUE)); + SL1('IEMSI negotiation Suceeded.'); + END + ELSE + BEGIN + (* Should this be print ??? + WriteLn('failure.'); + *) + WriteLn(RGNoteStr(23,TRUE)); + SL1('IEMSI negotiation failed.'); + END; + NextItemPointer := 1; + WITH IEMSIRec DO + BEGIN + UserName := NextItem; + Handle := NextItem; + CityState := NextItem; + Ph := NextItem; + S := NextItem; + Pw := AllCaps(NextItem); + I := StrToInt('$'+NextItem); + IF (I > 0) THEN + Bdate := Pd2Date(I); + END; + Com_Flush_Recv; +END; + +PROCEDURE Check_Ansi; +VAR + L: LongInt; + C: Char; + Ox,x,y: Byte; + S: AStr; + + PROCEDURE ANSIResponse(VAR x,y: Byte); + VAR + Xs, + Ys: STRING[4]; + BEGIN + L := (Timer + 2); + C := #0; + Xs := ''; + Ys := ''; + x := 0; + y := 0; + WHILE (L > Timer) AND (C <> ^[) AND (NOT HangUp) DO + IF (NOT Empty) THEN + C := Com_Recv; { must be low level to avoid ansi-eater } + IF (C = ^[) THEN + BEGIN + L := (Timer + 1); + WHILE (L > Timer) AND (C <> ';') AND (NOT HangUp) DO + IF (NOT Empty) THEN + BEGIN + C := Com_Recv; + IF (C IN ['0'..'9']) AND (Length(Ys) < 4) THEN + Ys := Ys + C; + END; + L := (Timer + 1); + WHILE (L > Timer) AND (C <> 'R') AND (NOT HangUp) DO + IF (NOT Empty) THEN + BEGIN + C := Com_Recv; + IF (C IN ['0'..'9']) AND (Length(Xs) < 4) THEN + Xs := Xs + C; + END; + x := StrToInt(Xs); + y := StrToInt(Ys); + END; + END; + +BEGIN + TextAttr := 10; + (* Should this be Prompt ??? + Write('Attempting to detect emulation ... '); + *) + Write(RGNoteStr(24,TRUE)); + Exclude(ThisUser.Flags,Avatar); + Exclude(ThisUser.Flags,Ansi); + Exclude(ThisUser.Flags,Vt100); + Exclude(ThisUser.SFlags,Rip); + IF (ComPortSpeed = 0) THEN + BEGIN + Include(ThisUser.Flags,Ansi); + Exit; + END; + Com_Flush_Recv; + SerialOut(^M^M^['[!'#8#8#8); + L := (Timer + 2); + C := #0; + S := ''; + WHILE (L > Timer) AND (C <> 'R') AND (NOT HangUp) DO IF (NOT Empty) THEN + C := Com_Recv; + IF (C = 'R') THEN + BEGIN + L := (Ticks + 3); + WHILE (NOT Empty) AND (Ticks < L) DO; + C := Com_Recv; + IF (C = 'I') THEN + BEGIN + L := (Ticks + 3); + WHILE (NOT Empty) AND (Ticks < L) DO; + C := Com_Recv; + IF (C = 'P') THEN + BEGIN + Include(ThisUser.SFlags,Rip); + S := RGNoteStr(25,TRUE); {'RIP'} + END; + END; + Com_Flush_Recv; + END; + SerialOut(^M^M^['[6n'#8#8#8#8); + ANSIResponse(x,y); + IF (x + y > 0) THEN + BEGIN + Include(ThisUser.Flags,Ansi); + ANSIDetected := TRUE; + IF (S <> '') THEN + S := S + RGNoteStr(26,TRUE) {'/Ansi'} + ELSE + S := RGNoteStr(27,TRUE); {'Ansi'} + SerialOut(^V^F); + SerialOut(^['[6n'#8#8); + Ox := x; + ANSIResponse(x,y); + IF (x = Ox + 1) THEN + BEGIN + Include(ThisUser.Flags,Avatar); + IF (S <> '') THEN + S := S + RGNoteStr(28,TRUE) {'/Avatar'} + ELSE + S := RGNoteStr(29,TRUE); {'Avatar'} + END + ELSE + SerialOut(#8#8); + END; + IF (S <> '') THEN + Print('|10'+S+RGNoteStr(30,TRUE)) {' detected.'} + ELSE + BEGIN + TextAttr := 7; + { Should this be Print ??? } + WriteLn; + END; +END; + +PROCEDURE GetPWS(VAR Ok: Boolean; VAR Tries: Integer); (* Tries should be Byte *) +VAR + MHeader: MHeaderRec; + S: AStr; + PhonePW: STR4; + Birthday: Str10; + UserPW, + SysOpPW: Str20; + ForgotPW: Str40; +BEGIN + Ok := TRUE; + IF (NOT (FastLogon AND (NOT General.LocalSec))) THEN + BEGIN + IF (IEMSIRec.Pw = '') THEN + BEGIN + (* + Prompt(FString.Yourpassword); + *) + RGMainStr(3,FALSE); + GetPassword(UserPw,20); + END + ELSE + BEGIN + UserPW := IEMSIRec.Pw; + IEMSIRec.Pw := ''; + END; + IF (General.Phonepw) THEN + IF (IEMSIRec.Ph = '') THEN + BEGIN + (* + Prompt(FString.YourPhoneNumber); + *) + RGMainStr(4,FALSE); + GetPassword(PhonePW,4); + END + ELSE + BEGIN + PhonePW := Copy(IEMSIRec.Ph,Length(IEMSIRec.Ph) - 3,4); + IEMSIRec.Ph := ''; + END + ELSE + PhonePW := Copy(ThisUser.Ph,Length(ThisUser.Ph) - 3,4); + END; + IF (NOT (FastLogon AND (NOT General.LocalSec))) AND ((ThisUser.Pw <> Crc32(UserPW)) OR + (Copy(ThisUser.Ph,Length(ThisUser.Ph) - 3,4) <> PhonePW)) THEN + BEGIN + ok := FALSE; + (* + Prompt(FString.ILogon); + *) + RGNoteStr(9,FALSE); + IF (NOT HangUp) AND (UserNum <> 0) THEN + BEGIN + S := '* Illegal logon attempt! Tried: '+Caps(ThisUser.Name)+' #'+IntToStr(UserNum)+' PW='+UserPw; + IF (General.Phonepw) THEN + S := S + ', PH#='+PhonePW; + SendShortMessage(1,S); + SL1(S); + END; + Inc(ThisUser.Illegal); + IF (UserNum <> - 1) THEN + SaveURec(ThisUser,UserNum); + Inc(Tries); + IF (Tries >= General.MaxLogonTries) THEN + BEGIN + IF (General.NewUserToggles[20] = 0) OR (RGMainStr(6, TRUE) = '') + {(General.ForgotPWQuestion = '')} OR (ThisUser.ForgotPWAnswer = '') THEN + HangUp := TRUE + ELSE + BEGIN + (* + Print('|03Please answer the following question to logon to the BBS.'); + Print('|03'+General.ForgotPWQuestion); + Prt(': '); + *) + RGMainStr(6,FALSE); + MPL(40); + Input(ForgotPW,40); + IF (ForgotPW <> ThisUser.ForgotPWAnswer) THEN + BEGIN + S := '* Invalid forgot password response: '+ForgotPW; + SL1(S); + SendShortMessage(1,S); + HangUp := TRUE + END + ELSE + BEGIN + S := '* Entered correct forgot password response.'; + SL1(S); + SendShortMessage(1,S); + CStuff(9,1,ThisUser); + ok := TRUE; + Tries := 0; + END; + END; + END; + END; + IF (Ok) THEN + lStatus_Screen(General.Curwindow,'',FALSE,S); + IF ((AACS(General.Spw)) AND (Ok) AND (InCom) AND (NOT HangUp)) THEN + BEGIN + (* + Prompt(FString.SysOpPrompt); + *) + RGMainStr(5,FALSE); + GetPassword(SysOpPW,20); + IF (SysOpPW <> General.SysOpPW) THEN + BEGIN + (* + Prompt(FString.ILogon); + *) + RGNoteStr(9,FALSE); + SL1('* Illegal System password: '+SysOpPw); + Inc(Tries); + IF (Tries >= General.MaxLogonTries) THEN + HangUp := TRUE; + Ok := FALSE; + END; + END; + IF (Ok) AND NOT (AACS(Liner.LogonACS)) THEN + BEGIN + PrintF('NONODE'); + IF (NoFile) THEN + (* + Print('You don''t have the required ACS to logon to this node!'); + *) + RGNoteStr(10,FALSE); + SysOpLog(ThisUser.Name+': Attempt to logon node '+IntToStr(ThisNode)+' without access.'); + HangUp := TRUE; + END; + IF ((Ok) AND (General.ShuttleLog) AND (LockedOut IN ThisUser.SFlags)) THEN + BEGIN + PrintF(ThisUser.LockedFile); + IF (NoFile) THEN + (* + Print('You have been locked out of the BBS by the SysOp.'); + *) + RGNoteStr(11,FALSE); + SysOpLog(ThisUser.Name+': Attempt to access system when locked out^7 <--'); + HangUp := TRUE; + END; + IF (UserNum > 0) AND (Onnode(UserNum) > 0) AND NOT (Cosysop) THEN + BEGIN + PrintF('MULTILOG'); + IF (NoFile) THEN + (* + Print('You are already logged in on another node!'); + *) + RGNoteStr(12,FALSE); + HangUp := TRUE; + END; + IF (NOT FastLogon) AND (Ok) AND (NOT HangUp) AND (General.Birthdatecheck > 0) AND + (ThisUser.LoggedOn MOD General.Birthdatecheck = 0) THEN + BEGIN + (* + Prt('Please verify your date of birth (mm/dd/yyyy): '); + *) + RGMainStr(7,FALSE); + Inputformatted('',Birthday,'##/##/####',FALSE); + IF (Date2Pd(Birthday) <> ThisUser.Birthdate) THEN + BEGIN + Dec(ThisUser.LoggedOn); + PrintF('WRNGBDAY'); + IF (NoFile) THEN + (* + Print('You entered an incorrect birthdate.'); + *) + RGNoteStr(13,FALSE); + SL1('*'+ThisUser.Name+' Failed birthday verification. Tried = '+Birthday+' Actual = '+Pd2Date(ThisUser.Birthdate)); + SendShortMessage(1,ThisUser.Name+' failed birthday verification on '+DateStr); + InResponseTo := '\'#1'Failed birthdate check'; + MHeader.Status := []; + SeMail(1,MHeader); + HangUp := TRUE; + END; + END; + UserOn := Ok; +END; + +PROCEDURE TryIEMSILogon; +VAR + I, Zz: Integer; + Ok: Boolean; +BEGIN + IF (IEMSIRec.UserName <> '') THEN + BEGIN + I := SearchUser(IEMSIRec.UserName,TRUE); + IF (I = 0) AND (IEMSIRec.Handle <> '') THEN + I := SearchUser(IEMSIRec.Handle,TRUE); + IF (I > 0) THEN + BEGIN + Zz := UserNum; + UserNum := 0; + OldUser := ThisUser; + LoadURec(ThisUser,I); + UserNum := Zz; + GetPWS(Ok,Zz); + GotName := Ok; + IF (NOT GotName) THEN + BEGIN + ThisUser := OldUser; + Update_Screen; + END + ELSE + BEGIN + UserNum := I; + IF (Pd2Date(ThisUser.LastOn) <> DateStr) THEN + WITH ThisUser DO + BEGIN + OnToday := 0; + TLToday := General.TimeAllow[SL]; + TimeBankAdd := 0; + DLToday := 0; + DLKToday := 0; + TimeBankWith := 0; + END; + UserOn := TRUE; + Update_Screen; + SysOpLog('Logged in IEMSI as '+Caps(ThisUser.Name)); + END; + END + ELSE + (* + Print(FString.NameNotFound); + *) + RGNoteStr(8,FALSE); + + END; +END; + +PROCEDURE Doshuttle; +VAR + Cmd,NewMenuCmd: AStr; + SaveMenu, + CmdToExec: Byte; + Tries, + RecNum, + RecNum1, + I: Integer; + Done,Loggedon,Ok,CmdNotHid,CmdExists: Boolean; +BEGIN + PrintF('PRESHUTL'); + GotName := FALSE; + Loggedon := FALSE; + TryIEMSILogon; + SaveMenu := CurMenu; + CurMenu := General.ShuttleLogonMenu; + LoadMenu; + AutoExecCmd('FIRSTCMD'); + Tries := 0; + Curhelplevel := 2; + REPEAT + TSHuttleLogon := 0; + MainMenuHandle(Cmd); + NewMenuCmd:= ''; + CmdToExec := 0; + Done := FALSE; + REPEAT + FCmd(Cmd,CmdToExec,CmdExists,CmdNotHid); + IF (CmdToExec <> 0) THEN + IF (MemCmd^[CmdToExec].Cmdkeys <> 'OP') AND (MemCmd^[CmdToExec].Cmdkeys <> 'O2') AND + (MemCmd^[CmdToExec].Cmdkeys[1] <> 'H') AND (MemCmd^[CmdToExec].Cmdkeys[1] <> '-') AND + (NOT GotName) THEN + BEGIN + (* + Prompt(FString.Shuttleprompt); + *) + RGMainStr(9,FALSE); + FindUser(UserNum); + IF (UserNum >= 1) THEN + BEGIN + I := UserNum; + UserNum := 0; + OldUser := ThisUser; + LoadURec(ThisUser,I); + UserNum := I; + GetPWS(Ok,Tries); + GotName := Ok; + IF (NOT GotName) THEN + BEGIN + ThisUser := OldUser; + Update_Screen; + END + ELSE + BEGIN + IF (Pd2Date(ThisUser.LastOn) <> DateStr) THEN + WITH ThisUser DO + BEGIN + OnToday := 0; + TLToday := General.TimeAllow[SL]; + TimeBankAdd := 0; + DLToday := 0; + DLKToday := 0; + TimeBankWith := 0; + END; + UserOn := TRUE; + Update_Screen; + SysOpLog('Logged on to Shuttle Menu as '+Caps(ThisUser.Name)); + DoMenuCommand(Done, + MemCmd^[CmdToExec].Cmdkeys, + MemCmd^[CmdToExec].Options, + NewMenuCmd, + MemCmd^[CmdToExec].NodeActivityDesc); + END; + END + ELSE + BEGIN + (* + Print(FString.ILogon); + *) + RGNoteStr(9,FALSE); + Inc(Tries); + END; + END + ELSE + DoMenuCommand(Done, + MemCmd^[CmdToExec].Cmdkeys, + MemCmd^[CmdToExec].Options, + NewMenuCmd, + MemCmd^[CmdToExec].NodeActivityDesc); + UNTIL (CmdToExec = 0) OR (Done); + CASE TSHuttleLogon OF + 1 : BEGIN + + Reset(ValidationFile); + RecNum1 := -1; + RecNum := 1; + WHILE (RecNum <= NumValKeys) AND (RecNum1 = -1) DO + BEGIN + Seek(ValidationFile,(RecNum - 1)); + Read(ValidationFile,Validation); + IF (Validation.Key = '!') THEN + RecNum1 := RecNum; + Inc(RecNum); + END; + Close(ValidationFile); + + IF (RecNum1 <> -1) AND (ThisUser.SL > Validation.NewSL) THEN + Loggedon := TRUE + ELSE + BEGIN + PrintF('NOSHUTT'); + IF (NoFile) THEN + (* + Print('You have not been validated yet.'); + *) + RGNoteStr(31,FALSE); + SL1('* Illegal Shuttle Logon attempt'); + Inc(Tries); + END; + + END; + 2 : BEGIN + IF (NOT General.ClosedSystem) AND PYNQ(RGMainStr(2,TRUE){FString.LogonAsNew},0,FALSE) THEN + BEGIN + NewUserInit; + NewUser; + IF (UserNum > 0) AND (NOT HangUp) THEN + BEGIN + GotName := TRUE; + UserOn := TRUE; + DailyMaint; + END; + CurMenu := General.ShuttleLogonMenu; + LoadMenu; + END; + END; + END; + IF (Tries >= General.MaxLogonTries) THEN + HangUp := TRUE; + UNTIL (Loggedon) OR (HangUp); + CurMenu := SaveMenu; + NewMenuToLoad := TRUE; +END; + +FUNCTION GetUser: Boolean; +VAR + User: UserRecordType; + MHeader: MHeaderRec; + Pw, + S, + ACSReq: AStr; + OverridePW: Str20; + Lng: SmallInt; + Tries, + I, + TTimes, + Zz, + EventNum: Integer; (* Tries/TTimes should be Byte, may NOT need TTimes *) + Done, + Nu, + Ok, + TooMuch, + ACSUser: Boolean; +BEGIN + WasNewUser := FALSE; + UserNum := -1; + LoadURec(ThisUser,0); + TimeOn := GetPackDateTime; + ChatChannel := 0; + Update_Node(RGNoteStr(35,TRUE){ Logging on },TRUE); (* New *) + + LoadNode(ThisNode); (* New *) + NodeR.GroupChat := FALSE; + SaveNode(ThisNode); + + CreditsLastUpdated := GetPackDateTime; + + PublicReadThisCall := 0; + + ExtraTime := 0; + FreeTime := 0; + ChopTime := 0; + CreditTime := 0; + + SL1(''); + + S := '^3Logon node '+IntToStr(ThisNode)+'^5 ['+Dat+']^4 ('; + IF (ComPortSpeed > 0) THEN + BEGIN + S := S + IntToStr(ActualSpeed)+' baud'; + IF (Reliable) THEN + S := S + '/Reliable)' + ELSE + S := S + ')'; + IF (CallerIDNumber > '') THEN + BEGIN + IF (NOT Telnet) THEN + S := S + ' Number: '+CallerIDNumber + ELSE + S := S + ' IP Number: '+CallerIDNumber; + END; + END + ELSE + S := S + 'Keyboard)'; + SL1(S); + + Nu := FALSE; + Pw := ''; + + IF (ActualSpeed < General.MinimumBaud) AND (ComPortSpeed > 0) THEN + BEGIN + IF ((General.MinBaudHiTime - General.MinBaudLowTime) > 1430) THEN + BEGIN + IF (General.MinBaudOverride <> '') THEN + BEGIN + (* + Prt('Baud rate override password: '); + *) + RGMainStr(0,FALSE); + GetPassword(OverridePW,20); + END; + IF (General.MinBaudOverride = '') OR (OverRidePW <> General.MinBaudOverride) THEN + BEGIN + PrintF('NOBAUD.ASC'); + IF (NoFile) THEN + RGNoteStr(3,FALSE); + (* + Print('You must be using at least '+IntToStr(General.MinimumBaud)+' baud to call this BBS.'); + *) + HangUp := TRUE; + Exit; + END; + END + ELSE IF (NOT InTime(Timer,General.MinBaudLowTime,General.MinBaudHiTime)) THEN + BEGIN + IF (General.MinBaudOverride <> '') THEN + BEGIN + (* + Prt('Baud rate override password: '); + *) + RGMainStr(0,FALSE); + GetPassword(OverridePW,20); + END; + IF (General.MinBaudOverride = '') OR (OverridePW <> General.MinBaudOverride) THEN + BEGIN + PrintF('NOBAUDH.ASC'); + IF (NoFile) THEN + (* + Print('Hours for those using less than '+IntToStr(General.MinimumBaud)+' baud are from '+ + Ctim(General.MinBaudLowTime)+' to '+Ctim(General.MinBaudHiTime)); + *) + RGNoteStr(4,FALSE); + HangUp := TRUE; + Exit; + END; + END + ELSE + BEGIN + IF (NOT HangUp) THEN + IF ((General.MinBaudLowTime <> 0) OR (General.MinBaudHiTime <> 0)) THEN + BEGIN + PrintF('YESBAUDH.ASC'); + IF (NoFile) THEN + (* + Print('NOTE: Callers at less than '+IntToStr(General.MinimumBaud)+' baud are'); + Print('restricted to the following hours ONLY:'); + Print(' '+Ctim(General.MinBaudLowTime)+' to '+Ctim(General.MinBaudHiTime)); + *) + RGNoteStr(5,FALSE); + END; + END; + END; + + ACSUser := FALSE; + FOR I := 1 TO NumEvents DO + WITH MemEventArray[I]^ DO + IF ((EventIsActive IN EFlags) AND (EventIsLogon IN EFlags) AND (CheckEventTime(I,0))) THEN + BEGIN + ACSUser := TRUE; + ACSReq := MemEventArray[I]^.EventACS; + EventNum := I; + END; + + Check_Ansi; + IEMSI; + GotName := FALSE; + IF ((General.ShuttleLog) AND (NOT FastLogon) AND (NOT HangUp)) THEN + Doshuttle; + Setc(7); + CLS; + Print(Centre(VerLine(1))); + Print(Centre(VerLine(2))); + Print(Centre(VerLine(3))); + PrintF('PRELOGON'); + IF (ACSUser) THEN + BEGIN + PrintF('ACSEA'+IntToStr(EventNum)); + IF (NoFile) THEN + (* + Print('Restricted: Only certain users allowed online at this time.'); + *) + RGNoteStr(6,FALSE); + END; + IF (NOT GotName) THEN + TryIEMSILogon; + TTimes := 0; + Tries := 0; + REPEAT + REPEAT + IF (UserNum <> - 1) AND (TTimes >= General.MaxLogonTries) THEN + HangUp := TRUE; + OldUser := ThisUser; + IF (NOT GotName) THEN + BEGIN + (* + IF (FString.Note[1] <> '') THEN + Print(FString.Note[1]); + IF (FString.Note[2] <> '') THEN + Print(FString.Note[2]); + IF (FString.Lprompt <> '') THEN + Prompt(FString.Lprompt); + *) + RGMainStr(1,FALSE); + FindUser(UserNum); + Inc(TTimes); + IF (ACSUser) AND (UserNum = -1) THEN + BEGIN + PrintF('ACSEB'+IntToStr(EventNum)); + IF (NoFile) THEN + (* + Print('This time window allows certain other users to get online.'); + Print('Please call back later, after it has ended.'); + *) + RGNoteStr(7,FALSE); + HangUp := TRUE; + END; + IF (NOT HangUp) AND (UserNum = 0) THEN + BEGIN + PrintF('LOGERR'); + IF (NoFile) THEN + (* + Print('Name not found in user list.'); + *) + RGNoteStr(8,FALSE); + IF NOT (General.ShuttleLog) AND (NOT General.ClosedSystem) THEN + IF PYNQ(RGMainStr(2,TRUE){FString.LogonAsNew},0,FALSE) THEN + UserNum := -1; + END; + END; + UNTIL (UserNum <> 0) OR (HangUp); + IF (ACSUser) AND (UserNum = -1) THEN + BEGIN + PrintF('ACSEB'+IntToStr(EventNum)); + IF (NoFile) THEN + (* + Print('This time window allows certain other users to get online.'); + Print('Please call back later, after it has ended.'); + *) + RGNoteStr(7,FALSE); + HangUp := TRUE; + END; + Ok := TRUE; + Done := FALSE; + IF (NOT HangUp) THEN + BEGIN + IF (UserNum = -1) THEN + BEGIN + NewUserInit; + Nu := TRUE; + Done := TRUE; + Ok := FALSE; + END + ELSE + BEGIN + I := UserNum; + UserNum := 0; + LoadURec(ThisUser,I); + UserNum := I; + TempPause := (Pause IN ThisUser.Flags); + NewFileDate := ThisUser.LastOn; + MsgArea := ThisUser.LastMsgArea; + FileArea := ThisUser.LastFileArea; + IF (AutoDetect IN ThisUser.SFlags) THEN + BEGIN + IF (Rip IN OldUser.SFlags) THEN + Include(ThisUser.SFlags,Rip) + ELSE + Exclude(ThisUser.SFlags,Rip); + IF (Ansi IN OldUser.Flags) THEN + Include(ThisUser.Flags,Ansi) + ELSE + Exclude(ThisUser.Flags,Ansi); + IF (Avatar IN OldUser.Flags) THEN + Include(ThisUser.Flags,Avatar) + ELSE + Exclude(ThisUser.Flags,Avatar); + END; + IF (Pd2Date(ThisUser.LastOn) <> DateStr) THEN + WITH ThisUser DO + BEGIN + OnToday := 0; + TLToday := General.TimeAllow[SL]; + TimeBankAdd := 0; + DLToday := 0; + DLKToday := 0; + TimeBankWith := 0; + END + ELSE IF (General.PerCall) THEN + ThisUser.TLToday := General.TimeAllow[ThisUser.SL]; + + IF (ThisUser.Expiration > 0) AND + (ThisUser.Expiration <= GetPackDateTime) AND + (ThisUser.ExpireTo IN ['!'..'~']) THEN + BEGIN + SysOpLog('Subscription expired to level: "'+ThisUser.ExpireTo+'".'); + AutoValidate(ThisUser,UserNum,ThisUser.ExpireTo); + END; + + IF (CallerIDNumber <> '') THEN + ThisUser.CallerID := CallerIDNumber; + SaveURec(ThisUser,UserNum); + IF (NOT GotName) THEN + GetPWS(Ok,Tries); + IF (Ok) THEN + Done := TRUE; + IF (NOT Done) THEN + BEGIN + ThisUser := OldUser; + UserNum := 0; + Update_Screen; + END; + END; + END; + UNTIL ((Done) OR (HangUp)); + Reset(SchemeFile); + IF (ThisUser.ColorScheme > 0) AND (ThisUser.ColorScheme <= FileSize(SchemeFile) ) THEN + Seek(SchemeFile,ThisUser.ColorScheme - 1) + ELSE + ThisUser.ColorScheme := 1; + Read(SchemeFile,Scheme); + Close(SchemeFile); + IF (ACSUser) AND NOT (AACS(ACSReq)) THEN + BEGIN + PrintF('ACSEB'+IntToStr(EventNum)); + IF (NoFile) THEN + (* + Print('This time window allows certain other users to get online.'); + Print('Please call back later, after it has ended.'); + *) + RGNoteStr(7,FALSE); + HangUp := TRUE; + END; + IF NOT (AACS(Liner.LogonACS)) AND (NOT HangUp) THEN + BEGIN + PrintF('NONODE'); + IF (NoFile) THEN + (* + Print('You don''t have the required ACS to logon to this node!'); + *) + RGNoteStr(10,FALSE); + SysOpLog(ThisUser.Name+': Attempt to logon node '+IntToStr(ThisNode)+' without access.'); + HangUp := TRUE; + END; + IF ((LockedOut IN ThisUser.SFlags) AND (NOT HangUp)) THEN + BEGIN + PrintF(ThisUser.LockedFile); + IF (NoFile) THEN + (* + Print('You have been locked out of the BBS by the SysOp.'); + *) + RGNoteStr(11,FALSE); + SysOpLog(ThisUser.Name+': Attempt to access system when locked out^7 <--'); + HangUp := TRUE; + END; + IF ((NOT Nu) AND (NOT HangUp)) THEN + BEGIN + TooMuch := FALSE; + IF (Accountbalance < General.Creditminute) AND (General.Creditminute > 0) AND + NOT (FNoCredits IN ThisUser.Flags) THEN + BEGIN + PrintF('NOCREDTS'); + IF (NoFile) THEN + (* + Print('You have insufficient credits for online time.'); + *) + RGNoteStr(14,FALSE); + SysOpLog(ThisUser.Name+': insufficient credits for logon.'); + IF (General.CreditFreeTime < 1) THEN + HangUp := TRUE + ELSE + BEGIN + ThisUser.TLToday := General.CreditFreeTime DIV General.Creditminute; + Inc(ThisUser.lCredit,General.CreditFreeTime); + END; + END + ELSE IF (((Rlogon IN ThisUser.Flags) OR (General.CallAllow[ThisUser.SL] = 1)) AND + (ThisUser.OnToday >= 1) AND (Pd2Date(ThisUser.LastOn) = DateStr)) THEN + BEGIN + PrintF('2MANYCAL'); + IF (NoFile) THEN + (* + Print('You can only log on once per day.'); + *) + RGNoteStr(15,FALSE); + TooMuch := TRUE; + END + ELSE IF ((ThisUser.OnToday >= General.CallAllow[ThisUser.SL]) AND + (Pd2Date(ThisUser.LastOn) = DateStr)) THEN + BEGIN + PrintF('2MANYCAL'); + IF (NoFile) THEN + (* + Print('You can only log on '+IntToStr(General.CallAllow[ThisUser.SL])+' times per day.'); + *) + RGNoteStr(16,FALSE); + TooMuch := TRUE; + END + ELSE IF (ThisUser.TLToday <= 0) AND NOT (General.PerCall) THEN + BEGIN + PrintF('NOTLEFTA'); + IF (NoFile) THEN + (* + Prompt('You can only log on for '+IntToStr(General.TimeAllow[ThisUser.SL])+' minutes per day.'); + *) + RGNoteStr(17,FALSE); + TooMuch := TRUE; + IF (ThisUser.TimeBank > 0) THEN + BEGIN + (* + Print('^5However, you have '+IntToStr(ThisUser.TimeBank)+' minutes left in your Time Bank.'); + *) + RGNoteStr(18,FALSE); + IF PYNQ(RGMainStr(8,TRUE){'Withdraw from Time Bank? '},0,TRUE) THEN + BEGIN + InputIntegerWOC('Withdraw how many minutes',Lng,[NumbersOnly],1,32767); + BEGIN + IF (Lng > ThisUser.TimeBank) THEN + Lng := ThisUser.TimeBank; + Dec(ThisUser.TimeBankAdd,Lng); + IF (ThisUser.TimeBankAdd < 0) THEN + ThisUser.TimeBankAdd := 0; + Dec(ThisUser.TimeBank,Lng); + Inc(ThisUser.TLToday,Lng); + (* + Print('^5In your account: ^3'+IntToStr(ThisUser.TimeBank)+'^5 Time left online: ^3'+Formattedtime(NSL)); + *) + RGNoteStr(19,FALSE); + SysOpLog('TimeBank: Withdrew '+ IntToStr(Lng)+' minutes at logon.'); + END; + END; + IF (NSL >= 0) THEN + TooMuch := FALSE + ELSE + (* + Print('Hanging up.'); + *) + RGNoteStr(20,FALSE); + END; + END; + IF (TooMuch) THEN + BEGIN + SL1(ThisUser.Name+' attempt to exceed time/call limits.'); + HangUp := TRUE; + END; + IF (Tries >= General.MaxLogonTries) THEN + HangUp := TRUE; + IF (NOT HangUp) THEN + Inc(ThisUser.OnToday); + END; + IF (UserNum > 0) AND (NOT HangUp) THEN + BEGIN + GetUser := Nu; + IF (NOT FastLogon) THEN + BEGIN + PrintF('WELCOME'); + IF (NOT NoFile) THEN + PauseScr(FALSE); + I := 0; + REPEAT + Inc(I); + PrintF('WELCOME'+IntToStr(I)); + IF (NOT NoFile) THEN + PauseScr(FALSE); + UNTIL (I = 9) OR (NoFile) OR (HangUp); + END; + UserOn := TRUE; + Update_Screen; + (* + Update_Node('Logged on',TRUE); + *) + InitTrapFile; + UserOn := FALSE; + CLS; + END; + IF (HangUp) THEN + GetUser := FALSE; +END; + +END. diff --git a/SOURCE/MAIL0.PAS b/SOURCE/MAIL0.PAS new file mode 100644 index 0000000..788e826 --- /dev/null +++ b/SOURCE/MAIL0.PAS @@ -0,0 +1,895 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Mail0; + +INTERFACE + +USES + Common; + +FUNCTION CompMsgArea(MArea: Integer; ArrayNum: Byte): Integer; +FUNCTION UseName(AnonNum: Byte; NameToUse: Str36): Str36; +PROCEDURE UpdateBoard; +PROCEDURE ExtractMsgToFile(MsgNum: Word; MHeader: MheaderRec); +PROCEDURE DumpQuote(MHeader: MHeaderRec); +PROCEDURE LoadHeader(MsgNum: Word; VAR MHeader: MHeaderRec); +PROCEDURE SaveHeader(MsgNum: Word; MHeader: MHeaderRec); +FUNCTION MsgAreaAC(MArea: Integer): Boolean; +PROCEDURE ChangeMsgArea(MArea: Integer); +PROCEDURE LoadMsgArea(MArea: Integer); +PROCEDURE LoadLastReadRecord(VAR LastReadRec: ScanRec); +PROCEDURE SaveLastReadRecord(LastReadRec: ScanRec); +PROCEDURE InitMsgArea(MArea: Integer); +PROCEDURE ReadMsg(Anum,MNum,TNum: Word); +FUNCTION HeaderLine(MHeader: MHeaderRec; MNum,TNum: Word; Line: byte; VAR FileOwner: Str36): STRING; +FUNCTION ToYou(MessageHeader: MHeaderRec): Boolean; +FUNCTION FromYou(MessageHeader: MHeaderRec): Boolean; +FUNCTION GetTagLine: Str74; + +IMPLEMENTATION + +USES + Dos, + File0, + File1, + Shortmsg, + TimeFunc; + +TYPE + MHeaderRecPtrType = ^MHeaderRec; + +FUNCTION CompMsgArea(MArea: Integer; ArrayNum: Byte): Integer; +VAR + MsgCompArrayFile: FILE OF CompArrayType; + CompMsgArray: CompArrayType; +BEGIN + Assign(MsgCompArrayFile,TempDir+'MACT'+IntToStr(ThisNode)+'.DAT'); + Reset(MsgCompArrayFile); + Seek(MsgCompArrayFile,(MArea - 1)); + Read(MsgCompArrayFile,CompMsgArray); + Close(MsgCompArrayFile); + CompMsgArea := CompMsgArray[ArrayNum]; +END; + +FUNCTION UseName(AnonNum: Byte; NameToUse: Str36): Str36; +BEGIN + CASE AnonNum OF + 1,2 : + NameToUse := lRGLNGStr(0,TRUE); {FString.Anonymous;} + 3 : NameToUse := 'Abby'; + 4 : NameToUse := 'Problemed Person'; + ELSE + NameToUse := Caps(NameToUse); + END; + UseName := NameToUse; +END; + +FUNCTION FromYou(MessageHeader: MHeaderRec): Boolean; +BEGIN + FromYou := FALSE; + IF (MessageHeader.From.UserNum = UserNum) OR + (AllCaps(MessageHeader.From.A1S) = ThisUser.Name) OR + (AllCaps(MessageHeader.From.Name) = ThisUser.Name) OR + (AllCaps(MessageHeader.From.A1S) = AllCaps(ThisUser.RealName)) THEN + FromYou := TRUE; +END; + +FUNCTION ToYou(MessageHeader: MHeaderRec): Boolean; +BEGIN + ToYou := FALSE; + IF (MessageHeader.MTO.UserNum = UserNum) OR + (AllCaps(MessageHeader.MTO.A1S) = ThisUser.Name) OR + (AllCaps(MessageHeader.MTO.Name) = ThisUser.Name) OR + (AllCaps(MessageHeader.MTO.A1S) = AllCaps(ThisUser.RealName)) THEN + ToYou := TRUE; +END; + +PROCEDURE UpdateBoard; +VAR + FO: Boolean; +BEGIN + IF (ReadMsgArea < 1) OR (ReadMsgArea > NumMsgAreas) THEN + Exit; + FO := (FileRec(MsgAreaFile).Mode <> FMClosed); + IF (NOT FO) THEN + BEGIN + Reset(MsgAreaFile); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('MBASES.DAT/Open Error - '+IntToStr(LastError)+' (Procedure: UpDateBoard - '+IntToStr(ReadMsgArea)+')'); + Exit; + END; + END; + Seek(MsgAreaFile,(ReadMsgArea - 1)); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('MBASES.DAT/Seek Error - '+IntToStr(LastError)+' (Procedure: UpDateBoard - '+IntToStr(ReadMsgArea)+')'); + Exit; + END; + Read(MsgAreaFile,MemMsgArea); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('MBASES.DAT/Read Error - '+IntToStr(LastError)+' (Procedure: UpDateBoard - '+IntToStr(ReadMsgArea)+')'); + Exit; + END; + Include(MemMsgArea.MAFlags,MAScanOut); + Seek(MsgAreaFile,(ReadMsgArea - 1)); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('MBASES.DAT/Seek Error - '+IntToStr(LastError)+' (Procedure: UpDateBoard - '+IntToStr(ReadMsgArea)+')'); + Exit; + END; + Write(MsgAreaFile,MemMsgArea); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('MBASES.DAT/Write Error - '+IntToStr(LastError)+' (Procedure: UpDateBoard - '+IntToStr(ReadMsgArea)+')'); + Exit; + END; + IF (NOT FO) THEN + BEGIN + Close(MsgAreaFile); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('MBASES.DAT/Close Error - '+IntToStr(LastError)+' (Procedure: UpDateBoard - '+IntToStr(ReadMsgArea)+')'); + Exit; + END; + END; +END; + +PROCEDURE LoadHeader(MsgNum: Word; VAR MHeader: MHeaderRec); +VAR + FO: Boolean; +BEGIN + FO := FileRec(MsgHdrF).Mode <> FMClosed; + IF (NOT FO) THEN + BEGIN + Reset(MsgHdrF); + IF (IOResult = 2) THEN + BEGIN + ReWrite(MsgHdrF); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog(MemMsgArea.FileName+'/ReWrite Error - '+IntToStr(LastError)+' (Procedure: LoadHeader - '+IntToStr(MsgNum)+')'); + Exit; + END; + END; + END; + Seek(MsgHdrF,(MsgNum - 1)); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog(MemMsgArea.FileName+'/Seek Error - '+IntToStr(LastError)+' (Procedure: LoadHeader - '+IntToStr(MsgNum)+')'); + Exit; + END; + Read(MsgHdrF,MHeader); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog(MemMsgArea.FileName+'/Read Error - '+IntToStr(LastError)+' (Procedure: LoadHeader - '+IntToStr(MsgNum)+')'); + Exit; + END; + IF (NOT FO) THEN + BEGIN + Close(MsgHdrF); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog(MemMsgArea.FileName+'/Close Error - '+IntToStr(LastError)+' (Procedure: LoadHeader - '+IntToStr(MsgNum)+')'); + Exit; + END; + END; + LastError := IOResult; +END; + +PROCEDURE SaveHeader(MsgNum: Word; MHeader: MHeaderRec); +VAR + FO: Boolean; +BEGIN + FO := FileRec(MsgHdrF).Mode <> FMClosed; + IF (NOT FO) THEN + BEGIN + Reset(MsgHdrF); + IF (IOResult = 2) THEN + BEGIN + ReWrite(MsgHdrF); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog(MemMsgArea.FileName+'/ReWrite Error - '+IntToStr(LastError)+ + '(Procedure: SaveHeader - '+IntToStr(MsgNum)+')'); + Exit; + END; + END; + END; + Seek(MsgHdrF,(MsgNum - 1)); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog(MemMsgArea.FileName+'/Seek Error - '+IntToStr(LastError)+' (Procedure: SaveHeader - '+IntToStr(MsgNum)+')'); + Exit; + END; + Write(MsgHdrF,MHeader); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog(MemMsgArea.FileName+'/Write Error - '+IntToStr(LastError)+' (Procedure: SaveHeader - '+IntToStr(MsgNum)+')'); + Exit; + END; + IF (NOT FO) THEN + BEGIN + Close(MsgHdrF); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog(MemMsgArea.FileName+'/Close Error - '+IntToStr(LastError)+' (Procedure: SaveHeader - '+IntToStr(MsgNum)+')'); + Exit; + END; + END; + LastError := IOResult; +END; + +FUNCTION MsgAreaAC(MArea: Integer): Boolean; +BEGIN + MsgAreaAC := FALSE; + IF (MArea <> -1) THEN + IF (MArea < 1) OR (MArea > NumMsgAreas) THEN + Exit; + LoadMsgArea(MArea); + MsgAreaAC := AACS(MemMsgArea.ACS); +END; + +PROCEDURE ChangeMsgArea(MArea: Integer); +VAR + TempPassword: Str20; +BEGIN + IF (MArea < 1) OR (MArea > NumMsgAreas) OR (NOT MsgAreaAC(MArea)) THEN + Exit; + IF (MemMsgArea.Password <> '') THEN + BEGIN + NL; + Print('Message area: ^5'+MemMsgArea.Name+' #'+IntToStr(CompMsgArea(MArea,0))+'^1'); + NL; + Prt('Password: '); + GetPassword(TempPassword,20); + IF (TempPassword <> MemMsgArea.Password) THEN + BEGIN + NL; + Print('^7Incorrect password!^1'); + Exit; + END; + END; + MsgArea := MArea; + ThisUser.LastMsgArea := MsgArea; +END; + +PROCEDURE LoadMsgArea(MArea: Integer); +VAR + FO: Boolean; +BEGIN + IF (MArea = -1) THEN + BEGIN + Assign(EmailFile,General.DataPath+'MEMAIL.DAT'); + Reset(EmailFile); + Read(EmailFile,MemMsgArea); + Close(EmailFile); + ReadMsgArea := -1; + WITH LastReadRecord DO + BEGIN + LastRead := 0; + NewScan := TRUE; + END; + END; + IF (MArea < 1) OR (MArea > NumMsgAreas) OR (ReadMsgArea = MArea) THEN + Exit; + FO := (FileRec(MsgAreaFile).Mode <> FMClosed); + IF (NOT FO) THEN + BEGIN + Reset(MsgAreaFile); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('MBASES.DAT/Open Error - '+IntToStr(LastError)+' (Procedure: LoadMsgArea - '+IntToStr(MArea)+')'); + Exit; + END; + END; + Seek(MsgAreaFile,(MArea - 1)); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('MBASES.DAT/Seek Error - '+IntToStr(LastError)+' (Procedure: LoadMsgArea - '+IntToStr(MArea)+')'); + Exit; + END; + Read(MsgAreaFile,MemMsgArea); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('MBASES.DAT/Read Error - '+IntToStr(LastError)+' (Procedure: LoadMsgArea - '+IntToStr(MArea)+')'); + Exit; + END + ELSE + ReadMsgArea := MArea; + IF (NOT FO) THEN + BEGIN + Close(MsgAreaFile); + LastError := IOResult; + IF (LastError > 0) THEN + BEGIN + SysOpLog('MBASES.DAT/Close Error - '+IntToStr(LastError)+' (Procedure: LoadMsgArea - '+IntToStr(MArea)+')'); + Exit; + END; + END; + LastError := IOResult; +END; + +PROCEDURE LoadLastReadRecord(VAR LastReadRec: ScanRec); +VAR + MsgAreaScanFile: FILE OF ScanRec; + Counter: Integer; +BEGIN + Assign(MsgAreaScanFile,General.MsgPath+MemMsgArea.FileName+'.SCN'); + Reset(MsgAreaScanFile); + IF (IOResult = 2) THEN + ReWrite(MsgAreaScanFile); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Error opening file: '+General.MsgPath+MemMsgArea.FileName+'.SCN'); + Exit; + END; + IF (UserNum > FileSize(MsgAreaScanFile)) THEN + BEGIN + WITH LastReadRec DO + BEGIN + LastRead := 0; + NewScan := TRUE; + END; + Seek(MsgAreaScanFile,FileSize(MsgAreaScanFile)); + FOR Counter := FileSize(MsgAreaScanFile) TO (UserNum - 1) DO + Write(MsgAreaScanFile,LastReadRec); + END + ELSE + BEGIN + Seek(MsgAreaScanFile,(UserNum - 1)); + Read(MsgAreaScanFile,LastReadRec); + END; + Close(MsgAreaScanFile); + LastError := IOResult; +END; + +PROCEDURE SaveLastReadRecord(LastReadRec: ScanRec); +VAR + MsgAreaScanFile: FILE OF ScanRec; +BEGIN + Assign(MsgAreaScanFile,General.MsgPath+MemMsgArea.FileName+'.SCN'); + Reset(MsgAreaScanFile); + Seek(MsgAreaScanFile,(UserNum - 1)); + Write(MsgAreaScanFile,LastReadRec); + Close(MsgAreaScanFile); + LastError := IOResult; +END; + +PROCEDURE InitMsgArea(MArea: Integer); +BEGIN + LoadMsgArea(MArea); + Assign(MsgHdrF,General.MsgPath+MemMsgArea.FileName+'.HDR'); + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + Close(MsgHdrF); + Assign(MsgTxtF,General.MsgPath+MemMsgArea.FileName+'.DAT'); + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + Close(MsgTxtF); + IF (MArea = -1) THEN + Exit; + LoadLastReadRecord(LastReadRecord); +END; + +PROCEDURE DumpQuote(MHeader: MHeaderRec); +VAR + QuoteFile: Text; + DT: DateTime; + S: STRING; + S1: STRING[80]; + Counter: Byte; + TempTextSize: Word; +BEGIN + IF (MHeader.TextSize < 1) THEN + Exit; + + Assign(QuoteFile,'TEMPQ'+IntToStr(ThisNode)); + ReWrite(QuoteFile); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('^7Error creating file: ^5TEMPQ'+IntToStr(ThisNode)+'^1!'); + Exit; + END; + + S := AOnOff(MARealName IN MemMsgArea.MAFlags,MHeader.From.Real,MHeader.From.A1S); + + FOR Counter := 1 TO 2 DO + BEGIN + + IF (Counter = 1) THEN + S1 := MemMsgArea.QuoteStart + ELSE + S1 := MemMsgArea.QuoteEnd; + + S1 := Substitute(S1,'@F',UseName(MHeader.From.Anon,S)); + + S1 := Substitute(S1,'@T',UseName(MHeader.MTO.Anon, + AOnOff(MARealName IN MemMsgArea.MAFlags, + Caps(MHeader.MTO.Real), + Caps(MHeader.MTO.A1S)))); + + + IF (MHeader.Origindate <> '') THEN + S1 := Substitute(S1,'@D',MHeader.Origindate) + ELSE + BEGIN + Packtodate(DT,MHeader.Date); + S1 := Substitute(S1,'@D',IntToStr(DT.Day)+ + ' '+Copy(MonthString[DT.Month],1,3)+ + ' '+Copy(IntToStr(DT.Year),3,2)+ + ' '+Zeropad(IntToStr(DT.Hour))+ + ':'+Zeropad(IntToStr(DT.Min))); + END; + + S1 := Substitute(S1,'@S',AOnOff(MHeader.FileAttached = 0, + Substitute(S1,'@S',MHeader.Subject), + Substitute(S1,'@S',StripName(MHeader.Subject)))); + + S1 := Substitute(S1,'@B',MemMsgArea.Name); + + IF (S1 <> '') THEN + WriteLn(QuoteFile,S1); + END; + + WriteLn(QuoteFile); + + S1 := S[1]; + IF (Pos(' ',S) > 0) AND (Length(S) > Pos(' ',S)) THEN + S1 := S1 + S[Pos(' ',S) + 1] + ELSE IF (Length(S1) > 1) THEN + S1 := S1 + S[2]; + IF (MHeader.From.Anon <> 0) THEN + S1 := ''; + S1 := Copy(S1,1,2); + + Reset(MsgTxtF,1); + Seek(MsgTxtF,(MHeader.Pointer - 1)); + TempTextSize := 0; + REPEAT + BlockRead(MsgTxtF,S[0],1); + BlockRead(MsgTxtF,S[1],Ord(S[0])); + LastError := IOResult; + Inc(TempTextSize,Length(S) + 1); + IF (Pos('> ',Copy(S,1,4)) > 0) THEN + S := Copy(StripColor(S),1,78) + ELSE + S := Copy(S1+'> '+StripColor(S),1,78); + WriteLn(QuoteFile,S); + UNTIL (TempTextSize >= MHeader.TextSize); + Close(QuoteFile); + Close(MsgTxtF); + LastError := IOResult; +END; + +PROCEDURE ExtractMsgToFile(MsgNum: Word; MHeader: MHeaderRec); +VAR + ExtTxtFile: Text; + FileOwner: Str36; + FileName: Str52; + MsgTxtStr: STRING; + Counter: Byte; + TempTextSize: Word; + StripColors: Boolean; +BEGIN + NL; + Print('Extract message to file:'); + Prt(': '); + InputDefault(FileName,'MSG'+IntToStr(ThisNode)+'.TXT',52,[UpperOnly,NoLineFeed],TRUE); + IF (FileName = '') THEN + BEGIN + NL; + Print('Aborted!'); + Exit; + END; + NL; + IF PYNQ('Are you sure? ',0,FALSE) THEN + BEGIN + NL; + StripColors := PYNQ('Strip color codes from output? ',0,FALSE); + + Assign(ExtTxtFile,FileName); + Append(ExtTxtFile); + IF (IOResult = 2) THEN + BEGIN + ReWrite(ExtTxtFile); + IF (IOResult <> 0) THEN + BEGIN + Print('^7Unable to create file: ^5'+FileName+'!^1'); + Exit; + END; + END; + + LoadHeader(MsgNum,MHeader); + + FOR Counter := 1 TO 6 DO + BEGIN + MsgTxtStr := HeaderLine(MHeader,MsgNum,HiMsg,Counter,FileOwner); + IF (MsgTxtStr <> '') THEN + IF (StripColors) THEN + WriteLn(ExtTxtFile,StripColor(MsgTxtStr)) + ELSE + WriteLn(ExtTxtFile,MsgTxtStr); + END; + + WriteLn(ExtTxtFile); + + Reset(MsgTxtF,1); + Seek(MsgTxtF,(MHeader.Pointer - 1)); + TempTextSize := 0; + REPEAT + BlockRead(MsgTxtF,MsgTxtStr[0],1); + BlockRead(MsgTxtF,MsgTxtStr[1],Ord(MsgTxtStr[0])); + LastError := IOResult; + Inc(TempTextSize,(Length(MsgTxtStr) + 1)); + IF (StripColors) THEN + MsgTxtStr := StripColor(MsgTxtStr); + IF (MsgTxtStr[Length(MsgTxtStr)] = #29) THEN + BEGIN + Dec(MsgTxtStr[0]); + Write(ExtTxtFile,MsgTxtStr); + END + ELSE + WriteLn(ExtTxtFile,MsgTxtStr); + UNTIL (TempTextSize >= MHeader.TextSize); + WriteLn(ExtTxtFile); + Close(ExtTxtFile); + Close(MsgTxtF); + NL; + Print('Message extracted.'); + END; + LastError := IOResult; +END; + +FUNCTION MHeaderRecMCI(CONST S: ASTR; Data1,Data2: Pointer): STRING; +VAR + MHeaderPtr: MHeaderRecPtrType; + S1: STRING; +BEGIN + MheaderPtr := Data1; + MHeaderRecMCI := S; + CASE S[1] OF + 'C' : CASE S[2] OF + 'A' : ;{TodaysCallerMCI := FormatNumber(LastCallerPtr^.Caller);} + END; + END; +END; + +FUNCTION HeaderLine(MHeader: MHeaderRec; MNum,TNum: Word; Line: byte; VAR FileOwner: Str36): STRING; +VAR + S, + S1: STRING; + Pub, + SeeAnon: Boolean; +BEGIN + Pub := (ReadMsgArea <> -1); + + IF (Pub) THEN + SeeAnon := (AACS(General.AnonPubRead) OR MsgSysOp) + ELSE + SeeAnon := AACS(General.AnonPrivRead); + + IF (MHeader.From.Anon = 2) THEN + SeeAnon := CoSysOp; + + S := ''; + + CASE Line OF + 1 : BEGIN + + IF (MHeader.FileAttached > 0) THEN + InResponseTo := StripName(MHeader.Subject) + ELSE + InResponseTo := Mheader.Subject; + + IF ((MHeader.From.Anon = 0) OR (SeeAnon)) THEN + LastAuthor := MHeader.From.UserNum + ELSE + LastAuthor := 0; + + IF ((MHeader.From.Anon = 0) OR (SeeAnon)) THEN + S := PDT2Dat(MHeader.Date,MHeader.DayOfWeek) + ELSE + S := '[Unknown]'; + + S := '^1Date: ^9'+S; + + S := PadLeftStr(S,39)+'^1Number : ^9'+IntToStr(MNum)+'^1 of ^9'+IntToStr(TNum); + END; + 2 : BEGIN + IF (Pub) AND (MARealName IN MemMsgArea.MAFlags) THEN + S1 := MHeader.From.Real + ELSE + S1 := MHeader.From.A1S; + S := '^1From: ^5'+Caps(UseName(MHeader.From.Anon,S1)); + + FileOwner := Caps(UseName(MHeader.From.Anon,S1)); + + IF (NOT Pub) AND (Netmail IN MHeader.Status) THEN + BEGIN + S := S + '^2 ('+IntToStr(MHeader.From.Zone)+':'+IntToStr(MHeader.From.Net)+'/'+IntToStr(MHeader.From.Node); + IF (MHeader.From.Point > 0) THEN + S := S + '.'+IntToStr(MHeader.From.Point); + S := S + ')'; + END; + S := PadLeftStr(S,38)+'^1 Area : ^5'; + + IF (LennMCI(MemMsgArea.Name) > 30) THEN + S := S + PadLeftStr(MemMsgArea.Name,30) + ELSE + S := S + MemMsgArea.Name; + END; + 3 : BEGIN + IF (Pub) AND (MARealName IN MemMsgArea.MAFlags) THEN + S1 := Caps(MHeader.MTO.Real) + ELSE + S1 := Caps(MHeader.MTO.A1S); + S := '^1To : ^5'+UseName(MHeader.MTO.Anon,S1); + IF (NOT Pub) AND (Netmail IN MHeader.Status) THEN + BEGIN + S := S + '^2 ('+IntToStr(MHeader.MTO.Zone)+':'+IntToStr(MHeader.MTO.Net)+'/'+IntToStr(MHeader.MTO.Node); + IF (MHeader.MTO.Point > 0) THEN + S := S + '.'+IntToStr(MHeader.MTO.Point); + S := S + ')'; + END; + S := PadLeftStr(S,38)+'^1 Refer #: ^5'; + IF (MHeader.Replyto > 0) AND (MHeader.Replyto < MNum) THEN + S := S + IntToStr(MNum - MHeader.Replyto) + ELSE + S := S + 'None'; + END; + 4 : BEGIN + S := '^1Subj: '; + IF (MHeader.FileAttached = 0) THEN + S := S + '^5'+MHeader.Subject + ELSE + S := S + '^8'+StripName(MHeader.Subject); + S := PadLeftStr(S,38)+'^1 Replies: ^5'; + IF (MHeader.Replies <> 0) THEN + S := S + IntToStr(MHeader.Replies) + ELSE + S := S + 'None'; + END; + 5 : BEGIN + S := '^1Stat: ^'; + IF (MDeleted IN MHeader.Status) THEN + S := S + '8Deleted' + ELSE IF (Prvt IN MHeader.Status) THEN + S := S + '8Private' + ELSE IF (Pub) AND (UnValidated IN MHeader.Status) THEN + S := S + '8Unvalidated' + ELSE IF (Pub) AND (Permanent IN MHeader.Status) THEN + S := S + '5Permanent' + ELSE IF (MemMsgArea.MAType <> 0) THEN + IF (Sent IN MHeader.Status) THEN + S := S + '5Sent' + ELSE + S := S + '5Unsent' + ELSE + S := S + '5Normal'; + IF (NOT Pub) AND (Netmail IN MHeader.Status) THEN + S := S + ' Netmail'; + S := PadLeftStr(S,39) + '^1Origin : ^5'; + IF (MHeader.Origindate <> '') THEN + S := S + MHeader.Origindate + ELSE + S := S + 'Local'; + END; + 6 : IF ((SeeAnon) AND ((MHeader.MTO.Anon + MHeader.From.Anon) > 0) AND (MemMsgArea.MAType = 0)) THEN + BEGIN + S := '^1Real: ^5'; + IF (MARealName IN MemMsgArea.MAFlags) THEN + S := S + Caps(Mheader.From.Real) + ELSE + S := S + Caps(MHeader.From.Name); + S := S + '^1 to ^5'; + IF (MARealName IN MemMsgArea.MAFlags) THEN + S := S + Caps(MHeader.MTO.Real) + ELSE + S := S + Caps(MHeader.MTO.Name); + END; + END; + HeaderLine := S; +END; + +{ anum=actual, MNum=M#/t# <-displayed, TNum=m#/T# <- max? } + +PROCEDURE ReadMsg(Anum,MNum,TNum: Word); +VAR + MHeader: MHeaderRec; + FileInfo: FileInfoRecordType; + TransferFlags: TransferFlagSet; + MsgTxtStr: AStr; + FileOwner: Str36; + DS: DirStr; + NS: NameStr; + ES: ExtStr; + SaveFileArea: Integer; + TempTextSize: Word; +BEGIN + AllowAbort := (CoSysOp) OR (NOT (MAForceRead IN MemMsgArea.MAFlags)); + AllowContinue := TRUE; + LoadHeader(Anum,MHeader); + IF ((MDeleted IN Mheader.Status) OR (UnValidated IN MHeader.Status)) AND + NOT (CoSysOp OR FromYou(MHeader) OR ToYou(MHeader)) THEN + Exit; + Abort := FALSE; + Next := FALSE; + + FOR TempTextSize := 1 TO 6 DO + BEGIN + MsgTxtStr := HeaderLine(MHeader,MNum,TNum,TempTextSize,FileOwner); + IF (TempTextSize <> 2) THEN + MCIAllowed := (AllowMCI IN MHeader.Status); + IF (MsgTxtStr <> '') THEN + PrintACR(MsgTxtStr); + MCIAllowed := TRUE; + END; + + NL; + + Reset(MsgTxtF,1); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Error accessing message text.'); + AllowAbort := TRUE; + Exit; + END; + IF (NOT Abort) THEN + BEGIN + Reading_A_Msg := TRUE; + MCIAllowed := (AllowMCI IN Mheader.Status); + TempTextSize := 0; + Abort := FALSE; + Next := FALSE; + UserColor(MemMsgArea.Text_Color); + IF (MHeader.TextSize > 0) THEN + IF (((MHeader.Pointer - 1) + MHeader.TextSize) <= FileSize(MsgTxtF)) AND (MHeader.Pointer > 0) THEN + BEGIN + Seek(MsgTxtF,(MHeader.Pointer - 1)); + REPEAT + BlockRead(MsgTxtF,MsgTxtStr[0],1); + BlockRead(MsgTxtF,MsgTxtStr[1],Ord(MsgTxtStr[0])); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + SysOpLog('Error loading message text.'); + TempTextSize := MHeader.TextSize; + END; + Inc(TempTextSize,(Length(MsgTxtStr) + 1)); + IF (' * Origin: ' = Copy(MsgTxtStr,1,11)) THEN + MsgTxtStr := '^'+IntToStr(MemMsgArea.Origin_Color) + MsgTxtStr + ELSE IF ('---'= Copy(MsgTxtStr,1,3)) AND ((Length(MsgTxtStr) = 3) OR (MsgTxtStr[4] <> '-')) THEN + MsgTxtStr := '^'+IntToStr(MemMsgArea.Tear_Color) + MsgTxtStr + ELSE IF (Pos('> ',Copy(MsgTxtStr,1,5)) > 0) THEN + MsgTxtStr := '^'+IntToStr(MemMsgArea.Quote_Color)+ MsgTxtStr +'^'+IntToStr(MemMsgArea.Text_Color) + ELSE IF (Pos(#254,Copy(MsgTxtStr,1,5)) > 0) THEN + MsgTxtStr := '^'+IntToStr(MemMsgArea.Tear_Color) + MsgTxtStr; + PrintACR('^1'+MsgTxtStr); + UNTIL (TempTextSize >= MHeader.TextSize) OR (Abort) OR (HangUp); + END; + MCIAllowed := TRUE; + Reading_A_Msg := FALSE; + IF (DOSANSIOn) THEN + ReDrawForANSI; + END; + Close(MsgTxtF); + LastError := IOResult; + IF (MHeader.FileAttached > 0) THEN + IF (NOT Exist(MHeader.Subject)) THEN + BEGIN + NL; + Print('^7The attached file does not actually exist!^1'); + END + ELSE + BEGIN + SaveFileArea := FileArea; + FileArea := -1; + FSplit(MHeader.Subject,DS,NS,ES); + WITH MemFileArea DO + BEGIN + AreaName := 'File Attach'; + DLPath := DS; + ULPath := DS; + FAFlags := [FANoRatio]; + END; + WITH FileInfo DO + BEGIN + FileName := Align(NS+ES); + Description := 'File Attach'; + FilePoints := 0; + Downloaded := 0; + FileSize := GetFileSize(MHeader.Subject); + OwnerNum := SearchUser(StripColor(FileOwner),FALSE); + OwnerName := StripColor(FileOwner); + FileDate := MHeader.Date; + VPointer := -1; + VTextSize := 0; + FIFlags := []; + END; + TransferFlags := [IsFileAttach]; + DLX(FileInfo,-1,TransferFlags); + IF (IsTransferOk IN TransferFLags) AND (NOT (IsKeyboardAbort IN TransferFlags)) THEN + SendShortMessage(MHeader.From.UserNum,Caps(ThisUser.Name)+' downloaded "^5'+StripName(MHeader.Subject)+ + '^1" from ^5File Attach'); + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; + AllowAbort := TRUE; + TempPause := (Pause IN ThisUser.Flags); +END; + +(* Done: Lee Palmer 10/23/09 *) +FUNCTION GetTagLine: Str74; +VAR + StrPointerFile: FILE OF StrPointerRec; + RGStrFile: FILE; + StrPointer: StrPointerRec; + TagLine: Str74; + TempTextSize: Word; + StrNum: Word; + FSize: LongInt; +BEGIN + TagLine := ''; + IF (NOT Exist(General.lMultPath+'TAGLINE.PTR')) OR (NOT Exist(General.LMultPath+'TAGLINE.DAT')) THEN + SL1('* TAGLINE.PTR or TAGLINE.DAT file(s) do not exist!') + ELSE + BEGIN + Assign(StrPointerFile,General.LMultPath+'TAGLINE.PTR'); + Reset(StrPointerFile); + FSize := FileSize(StrPointerFile); + IF (FSize < 1) THEN + BEGIN + SL1('* TAGLINE.PTR does not contain any TagLines!'); + Exit; + END; + IF (FSize > 65535) THEN + FSize := 65535 + ELSE + Dec(FSize); + Randomize; + StrNum := Random(FSize); + Seek(StrPointerFile,StrNum); + Read(StrPointerFile,StrPointer); + Close(StrPointerFile); + LastError := IOResult; + Assign(RGStrFile,General.LMultPath+'TAGLINE.DAT'); + Reset(RGStrFile,1); + Seek(RGStrFile,(StrPointer.Pointer - 1)); + TempTextSize := 0; + REPEAT + BlockRead(RGStrFile,TagLine[0],1); + BlockRead(RGStrFile,TagLine[1],Ord(TagLine[0])); + Inc(TempTextSize,(Length(TagLine) + 1)); + UNTIL (TempTextSize >= StrPointer.TextSize); + Close(RGStrFile); + LastError := IOResult; + END; + GetTagLine := TagLine; +END; + +END. diff --git a/SOURCE/MAIL1.PAS b/SOURCE/MAIL1.PAS new file mode 100644 index 0000000..0584a25 --- /dev/null +++ b/SOURCE/MAIL1.PAS @@ -0,0 +1,2408 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Mail1; + +INTERFACE + +USES + Common; + +FUNCTION Inputmessage(Pub, + IsReply: Boolean; + CONST MsgTitle: Str40; + VAR MHeader: MHeaderRec; + CONST ReadInMsg: AStr; + MaxLineLen: Byte; + MaxMsgLines: Integer): Boolean; +PROCEDURE Anonymous(Offline: Boolean; VAR MHeader: MHeaderRec); + +IMPLEMENTATION + +USES + Crt, + Common5, + File8, + File0, + Mail0, + TimeFunc; + +VAR + InportFile: Text; + InportFileOpen: Boolean; + Escp: Boolean; + +PROCEDURE Anonymous(Offline: Boolean; VAR MHeader: MHeaderRec); +VAR + An: Anontyp; + HeaderL: AStr; + UName, + Junk: Str36; + Cmd: Char; + Counter: Byte; +BEGIN + IF (ReadMsgArea <> -1) THEN + BEGIN + An := MemMsgArea.Anonymous; + IF (An = ATNo) AND (AACS(General.AnonPubPost) AND (NOT Offline)) THEN + An := ATYes; + IF (RPostAn IN ThisUser.Flags) THEN + An := ATNo; + END + ELSE IF (AACS(General.AnonPrivPost)) THEN + An := ATYes + ELSE + An := ATNo; + IF (Offline) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + IF (An = ATNo) THEN + FOR Counter := 1 TO 5 DO + BEGIN + HeaderL := Headerline(MHeader,FileSize(MsgHdrF),FileSize(MsgHdrF),Counter,Junk); + IF (HeaderL <> '') THEN + PrintACR(HeaderL); + END + ELSE + BEGIN + ReadMsg(FileSize(MsgHdrF),FileSize(MsgHdrF),FileSize(MsgHdrF)); + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + IF (IOResult <> 0) THEN + SysOpLog('Anon: error opening message areas.'); + END; + END; + CASE An OF + ATNo : ; + ATForced : IF (CoSysOp) THEN + MHeader.From.Anon := 2 + ELSE + MHeader.From.Anon := 1; + ATYes : BEGIN + NL; + IF PYNQ(AOnOff(ReadMsgArea <> - 1,'Post anonymously? ','Send anonymously? '),0,FALSE) THEN + IF (CoSysOp) THEN + MHeader.From.Anon := 2 + ELSE + MHeader.From.Anon := 1; + END; + ATDearAbby : BEGIN + NL; + Print(AOnOff(ReadMsgArea <> - 1,'Post as:','Send as:')); + NL; + Print('1. Abby'); + Print('2. Problemed Person'); + Print('3. '+Caps(ThisUser.Name)); + NL; + Prt('Which? '); + OneK(Cmd,'123'^M,TRUE,TRUE); + CASE Cmd OF + '1' : MHeader.From.Anon := 3; + '2' : MHeader.From.Anon := 4; + END; + END; + ATAnyName : BEGIN + NL; + Print('You can post under any name in this area.'); + NL; + Prt('Name: '); + InputDefault(UName,MHeader.From.A1S,36,[InterActiveEdit],TRUE); + IF (UName <> MHeader.From.A1S) THEN + BEGIN + MHeader.From.Anon := 5; + MHeader.From.A1S := Caps(UName); + END; + END; + END; +END; + +PROCEDURE InputLine(VAR S: AStr; MaxLineLen: Byte); +VAR + CKeyPos, + RP, + Counter, + Counter1: Integer; + CKey, + ccc: Char; + HitCmdKey, + HitBkSpc, + DoThisChar: Boolean; + + PROCEDURE BkSpc; + BEGIN + IF (CKeyPos > 1) THEN + BEGIN + IF (S[CKeyPos - 2] = '^') AND (S[CKeyPos - 1] IN [#0..#9]) THEN + BEGIN + Dec(CKeyPos); + UserColor(1); + END + ELSE + BEGIN + BackSpace; + Dec(RP); + END; + Dec(CKeyPos); + END; + END; + +BEGIN + Write_Msg := TRUE; + HitCmdKey := FALSE; + HitBkSpc := FALSE; + ccc := '1'; + RP := 1; + CKeyPos := 1; + S := ''; + IF (LastLineStr <> '') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + AllowAbort := FALSE; + Reading_A_Msg := TRUE; + PrintMain(LastLineStr); + Reading_A_Msg := FALSE; + AllowAbort := TRUE; + S := LastLineStr; + LastLineStr := ''; + IF (Pos(^[,S) > 0) THEN + Escp := TRUE; + CKeyPos := (Length(S) + 1); + RP := CKeyPos; + END; + REPEAT + IF ((InportFileOpen) AND (Buf = '')) THEN + IF (NOT EOF(InportFile)) THEN + BEGIN + Counter1 := 0; + REPEAT + Inc(Counter1); + Read(InportFile,Buf[Counter1]); + IF (Buf[Counter1] = ^J) THEN + Dec(Counter1); + UNTIL (Counter1 >= 255) OR (Buf[Counter1] = ^M) OR (EOF(InportFile)); + Buf[0] := Chr(Counter1); + END + ELSE + BEGIN + Close(InportFile); + InportFileOpen := FALSE; + DOSANSIOn := FALSE; + Buf := ^P+'1'; + END; + CKey := Char(GetKey); + DoThisChar := FALSE; + IF ((CKey >= #32) AND (CKey <= #255)) THEN + BEGIN + IF (CKey = '/') AND (CKeyPos = 1) THEN + HitCmdKey := TRUE + ELSE + DoThisChar := TRUE; + END + ELSE + CASE CKey OF + ^[ : DoThisChar := TRUE; + ^H : IF (CKeyPos = 1) THEN + BEGIN + HitCmdKey := TRUE; + HitBkSpc := TRUE; + END + ELSE + BkSpc; + ^I : BEGIN + Counter := (5 - (CKeyPos MOD 5)); + IF ((CKeyPos + Counter) < StrLen) AND ((RP + Counter) < ThisUser.LineLen) THEN + FOR Counter1 := 1 TO Counter DO + BEGIN + OutKey(' '); + IF (Trapping) THEN + Write(TrapFile,' '); + S[CKeyPos] := ' '; + Inc(RP); + Inc(CKeyPos); + END; + END; + ^J : BEGIN + OutKey(CKey); + S[CKeyPos] := CKey; + IF (Trapping) THEN + Write(TrapFile,^J); + Inc(CKeyPos); + END; + ^N : BEGIN + OutKey(^H); + S[CKeyPos] := ^H; + IF (Trapping) THEN + Write(TrapFile,^H); + Inc(CKeyPos); + Dec(RP); + END; + ^P : IF (OkANSI OR OkAvatar) AND (CKeyPos < (StrLen - 1)) THEN + BEGIN + CKey := Char(GetKey); + IF (CKey IN ['0'..'9']) THEN + BEGIN + ccc := CKey; + S[CKeyPos] := '^'; + Inc(CKeyPos); + S[CKeyPos] := CKey; + Inc(CKeyPos); + UserColor(Ord(CKey) - Ord('0')); + END; + CKey := #0; + END; + ^W : IF (CKeyPos = 1) THEN + BEGIN + HitCmdKey := TRUE; + HitBkSpc := TRUE; + END + ELSE + REPEAT + BkSpc + UNTIL (CKeyPos = 1) OR (S[CKeyPos] = ' ') OR ((S[CKeyPos] = ^H) AND (S[CKeyPos - 1] <> '^')); + ^X,^Y : BEGIN + CKeyPos := 1; + FOR Counter := 1 TO (RP - 1) DO + BackSpace; + RP := 1; + IF (ccc <> '1') THEN + BEGIN + CKey := ccc; + S[CKeyPos] := '^'; + Inc(CKeyPos); + S[CKeyPos] := CKey; + Inc(CKeyPos); + UserColor(Ord(CKey) - Ord('0')); + END; + CKey := #0; + END; + END; + IF (DoThisChar) AND ((CKey <> ^G) AND (CKey <> ^M)) THEN + IF ((CKeyPos < StrLen) AND (Escp)) OR ((RP < ThisUser.LineLen) AND (NOT Escp)) THEN + BEGIN + IF (CKey = ^[) THEN + Escp := TRUE; + S[CKeyPos] := CKey; + Inc(CKeyPos); + Inc(RP); + OutKey(CKey); + IF (Trapping) THEN + Write(TrapFile,CKey); + END; + UNTIL (((RP - 1) = MaxLineLen) AND (NOT Escp)) OR (CKeyPos = StrLen) OR (CKey = ^M) OR (HitCmdKey) OR (HangUp); + IF (HitCmdKey) THEN + BEGIN + IF (HitBkSpc) THEN + S := '/'^H + ELSE + S := '/'; + END + ELSE + BEGIN + S[0] := Chr(CKeyPos - 1); + IF (CKey <> ^M) AND (CKeyPos <> StrLen) AND (NOT Escp) THEN + BEGIN + Counter := (CKeyPos - 1); + WHILE (Counter > 1) AND (S[Counter] <> ' ') AND ((S[Counter] <> ^H) OR (S[Counter - 1] = '^')) DO + Dec(Counter); + IF (Counter > (RP DIV 2)) AND (Counter <> (CKeyPos - 1)) THEN + BEGIN + LastLineStr := Copy(S,(Counter + 1),(CKeyPos - Counter)); + FOR Counter1 := (CKeyPos - 2) DOWNTO Counter DO + BackSpace; + S[0] := Chr(Counter - 1); + END; + END; + IF (Escp) AND (RP = ThisUser.LineLen) THEN + CKeyPos := StrLen; + IF (CKeyPos <> StrLen) THEN + NL + ELSE + BEGIN + RP := 1; + CKeyPos := 1; + S := S + #29; + END; + END; + Write_Msg := FALSE; +END; + +FUNCTION Inputmessage(Pub, + IsReply: Boolean; + CONST MsgTitle: Str40; + VAR MHeader: MHeaderRec; + CONST ReadInMsg: AStr; + MaxLineLen: Byte; + MaxMsgLines: Integer): Boolean; +CONST + TopScreen = 3; {first screen line for Text entry} + ScrollSize = 5; {number OF lines to scroll by} +TYPE + LinePointer = ^LineArray; + LineArray = ARRAY [1..500] OF STRING[120]; +VAR + LinePtr: LinePointer; + PhyLine: ARRAY [1..20] OF STRING[78]; + TotalLines: 1..500; + + MsgSubj: Str40; + + MsgTo: Str36; + + ScreenLines, + MaxLines, + LastQuoteLine, + MaxQuoteLines, + CurrentLine, + TopLine, + CCol: Integer; + + DisableMCI, + CantAbort, + Insert_Mode, + SaveMsg: Boolean; + + PROCEDURE DoLines; + BEGIN + IF (OkANSI OR OkAvatar) THEN + Print('^4::::::::::::::Ŀ^1') + ELSE + Print('[---:----:----:----:----:----:----:----|----:----:----:----:----:----:----:---]'); + END; + + PROCEDURE ANSIG(X,Y: Byte); + BEGIN + IF (ComPortSpeed > 0) THEN + IF (OkAvatar) THEN + SerialOut(^V^H+Chr(Y)+Chr(X)) + ELSE + SerialOut(#27+'['+IntToStr(Y)+';'+IntToStr(X)+'H'); + IF (WantOut) THEN + GoToXY(X,Y); + END; + + PROCEDURE Count_Lines; + BEGIN + TotalLines := MaxLines; + WHILE (TotalLines > 0) AND (Length(LinePtr^[TotalLines]) = 0) DO + Dec(TotalLines); + END; + + PROCEDURE Append_Space; + BEGIN + LinePtr^[CurrentLine] := LinePtr^[CurrentLine]+' '; + END; + + FUNCTION CurLength: Integer; + BEGIN + CurLength := Length(LinePtr^[CurrentLine]); + END; + + FUNCTION Line_Boundry: Boolean; + {is the cursor at either the start OF the END OF a line?} + BEGIN + Line_Boundry := (CCol = 1) OR (CCol > CurLength); + END; + + FUNCTION CurChar: Char; + {return the character under the cursor} + BEGIN + IF (CCol <= CurLength) THEN + CurChar := LinePtr^[CurrentLine][CCol] + ELSE + CurChar := ' '; + END; + + FUNCTION LastChar: Char; + {return the last character on the current line} + BEGIN + IF (CurLength = 0) THEN + LastChar := ' ' + ELSE + LastChar := LinePtr^[CurrentLine][CurLength]; + END; + + PROCEDURE Remove_Trailing; + BEGIN + WHILE (Length(LinePtr^[CurrentLine]) > 0) AND (LinePtr^[CurrentLine][Length(LinePtr^[CurrentLine])] <= ' ') DO + Dec(LinePtr^[CurrentLine][0]); + END; + + FUNCTION Delimiter: Boolean; + {return TRUE IF the current character is a Delimiter FOR words} + BEGIN + CASE CurChar OF + '0'..'9', 'a'..'z', 'A'..'Z', '_': + Delimiter := FALSE; + ELSE + Delimiter := TRUE; + END; + END; + + PROCEDURE Reposition(x: Boolean); + VAR + Eol: Integer; + BEGIN + IF (x) THEN + BEGIN + Eol := (CurLength + 1); + IF (CCol > Eol) THEN + CCol := Eol; + END; + Count_Lines; + ANSIG(CCol,((CurrentLine - TopLine) + TopScreen)); + IF (Pos('>',Copy(LinePtr^[CurrentLine],1,4)) > 0) THEN + Usercolor(3) + ELSE + Usercolor(1); + END; + + PROCEDURE Set_PhyLine; + {set physical line to match logical line (indicates display update)} + BEGIN + PhyLine[((CurrentLine - TopLine) + 1)] := LinePtr^[CurrentLine]; + END; + + PROCEDURE Clear_Eol; + BEGIN + IF (NOT OkAvatar) THEN + SerialOut(#27'[K') + ELSE + SerialOut(^V^G); + IF (WantOut) THEN + ClrEOL; + END; + + PROCEDURE Truncate_Line; + {update screen after changing END-OF-line} + BEGIN + IF (CCol > 0) THEN + LinePtr^[CurrentLine][0] := Chr(CCol - 1); + Reposition(TRUE); + Clear_Eol; + {Set_PhyLine; don't understand this} + END; + + PROCEDURE Refresh_Screen; + VAR + PLine, + PCol, + Phline, + Junk: Integer; + BEGIN + IF (CurrentLine >= MaxLines) THEN + CurrentLine := MaxLines; + PLine := CurrentLine; + CurrentLine := TopLine; + PCol := CCol; + CCol := 1; + FOR Junk := TopLine TO ((TopLine + ScreenLines) - 1) DO + BEGIN + CurrentLine:= Junk; + Phline := ((CurrentLine - TopLine) + 1); + IF (CurrentLine > MaxLines) THEN + BEGIN + Reposition (TRUE); + Prompt('^9--'); + PhyLine[Phline] := '--'; + Clear_Eol; + END + ELSE + BEGIN + IF (LinePtr^[CurrentLine] <> PhyLine[Phline]) THEN + BEGIN + Reposition (TRUE); + MCIAllowed := FALSE; + ColorAllowed := FALSE; + AllowAbort := FALSE; + PrintMain(Copy(LinePtr^[CurrentLine],1,MaxLineLen)); + MCIAllowed := TRUE; + ColorAllowed := TRUE; + AllowAbort := TRUE; + IF (CurLength < Length(PhyLine[Phline])) THEN + Clear_Eol; + Set_PhyLine; + END; + END; + END; + Tleft; + CCol := PCol; + CurrentLine := PLine; + Reposition(TRUE); + END; + + PROCEDURE Scroll_Screen(Lines: Integer); + BEGIN + Inc(TopLine,Lines); + IF (CurrentLine < TopLine) OR (CurrentLine >= (TopLine + ScreenLines)) THEN + TopLine := ((CurrentLine - ScreenLines) DIV 2); + IF (TopLine < 1) THEN + TopLine := 1 + ELSE IF (TopLine >= MaxLines) THEN + Dec(TopLine,ScrollSize DIV 2); + Refresh_Screen; + END; + + PROCEDURE Cursor_Up; + BEGIN + IF (CurrentLine > 1) THEN + Dec(CurrentLine); + IF (CurrentLine < TopLine) THEN + Scroll_Screen(-ScrollSize) + ELSE + Reposition(FALSE); + END; + + PROCEDURE Cursor_Down; + BEGIN + Inc(CurrentLine); + IF (CurrentLine >= MaxLines) THEN + BEGIN + CurrentLine := MaxLines; + IF (InportFileOpen) THEN + BEGIN + InportFileOpen := FALSE; + Close(InportFile); + END; + END; + IF ((CurrentLine - TopLine) >= ScreenLines) THEN + Scroll_Screen(ScrollSize) + ELSE + Reposition(FALSE); + END; + + PROCEDURE Cursor_EndLine; + BEGIN + CCol := (MaxLineLen + 1); (* 78 or 79 chars, Test This *) + Reposition(TRUE); + END; + + PROCEDURE Cursor_StartLine; + BEGIN + CCol := 1; + Reposition(TRUE); + END; + + PROCEDURE Cursor_Left; + BEGIN + IF (CCol = 1) THEN + BEGIN + Cursor_Up; + Cursor_EndLine; + END + ELSE + BEGIN + Dec(CCol); + IF (NOT OkAvatar) THEN + SerialOut(#27'[D') + ELSE + SerialOut(^V^E); + GoToXY((WhereX - 1),WhereY); + END; + END; + + PROCEDURE Cursor_Right; + BEGIN + IF (CCol > CurLength) THEN + BEGIN + CCol := 1; + Cursor_Down; + END + ELSE + BEGIN + OutKey(CurChar); + Inc(CCol); + END; + END; + + PROCEDURE Cursor_WordRight; + BEGIN + IF (Delimiter) THEN + BEGIN + {skip blanks right} + REPEAT + Cursor_Right; + IF (Line_Boundry) THEN + Exit; + UNTIL (NOT Delimiter); + END + ELSE + BEGIN + {find Next blank right} + REPEAT + Cursor_Right; + IF (Line_Boundry) THEN + Exit; + UNTIL (Delimiter); + {THEN move to a Word start (recursive)} + Cursor_WordRight; + END; + END; + + PROCEDURE Cursor_WordLeft; + BEGIN + IF (Delimiter) THEN + BEGIN + {skip blanks left} + REPEAT + Cursor_Left; + IF (Line_Boundry) THEN + Exit; + UNTIL (NOT Delimiter); + {find Next blank left} + REPEAT + Cursor_Left; + IF (Line_Boundry) THEN + Exit; + UNTIL (Delimiter); + {move to start OF the Word} + Cursor_Right; + END + ELSE + BEGIN + {find Next blank left} + REPEAT + Cursor_Left; + IF (Line_Boundry) THEN + Exit; + UNTIL (Delimiter); + {AND THEN move a Word left (recursive)} + Cursor_WordLeft; + END; + END; + + PROCEDURE Delete_Line; + {Delete the line at the cursor} + VAR + LineNum1: Integer; + BEGIN + FOR LineNum1 := CurrentLine TO (MaxLines - 1) DO + LinePtr^[LineNum1] := LinePtr^[LineNum1 + 1]; + LinePtr^[MaxLines] := ''; + IF (CurrentLine <= TotalLines) AND (TotalLines > 1) THEN + Dec(TotalLines); + END; + + PROCEDURE Insert_Line(CONST Contents: AStr); + {open a new line at the cursor} + VAR + LineNum1: Integer; + BEGIN + FOR LineNum1 := MaxLines DOWNTO (CurrentLine + 1) DO + LinePtr^[LineNum1] := LinePtr^[LineNum1 - 1]; + LinePtr^[CurrentLine] := Contents; + IF (CurrentLine < TotalLines) THEN + Inc(TotalLines); + IF (CurrentLine > TotalLines) THEN + TotalLines := CurrentLine; + END; + + PROCEDURE Reformat_Paragraph; + BEGIN + Remove_Trailing; + CCol := CurLength; + {FOR each line OF the paragraph} + WHILE (CurChar <> ' ') DO + BEGIN + {FOR each Word OF the current line} + REPEAT + {determine Length OF first Word on the following line} + Inc(CurrentLine); + Remove_Trailing; + CCol := 1; + WHILE (CurChar <> ' ') DO + Inc(CCol); + Dec(CurrentLine); + {hoist a Word From the following line IF it will fit} + IF (CCol > 1) AND ((CCol + CurLength) < MaxLineLen) THEN + BEGIN + IF (CurLength > 0) THEN + BEGIN + {add a second space after sentences} + CASE LastChar OF + '.', '?', '!': + Append_Space; + END; + Append_Space; + END; + LinePtr^[CurrentLine] := LinePtr^[CurrentLine] + Copy(LinePtr^[CurrentLine + 1],1,(CCol - 1)); + {remove the hoisted Word} + Inc(CurrentLine); + WHILE (CurChar = ' ') AND (CCol <= CurLength) DO + Inc(CCol); + Delete(LinePtr^[CurrentLine],1,(CCol - 1)); + IF (CurLength = 0) THEN + Delete_Line; + Dec(CurrentLine); + END + ELSE + CCol := 0; {END OF line} + UNTIL (CCol = 0); + {no more lines will fit - either time FOR Next line, OR END OF paragraph} + Inc(CurrentLine); + CCol := 1; + Remove_Trailing; + END; + END; + + PROCEDURE Word_Wrap; + {line is full AND a character must be inserted. perform Word-wrap, + updating screen AND leave ready FOR the insertion} + VAR + TempStr1: AStr; + PCol, + PLine: Integer; + BEGIN + Remove_Trailing; + PLine := CurrentLine; + PCol := CCol; + {find start OF Word to wrap} + CCol := CurLength; + WHILE (CCol > 0) AND (CurChar <> ' ') DO + Dec(CCol); + {cancel wrap IF no spaces IN whole line} + IF (CCol = 0) THEN + BEGIN + CCol := 1; + Cursor_Down; + Exit; + END; + {get the portion to be moved down} + Inc(CCol); + TempStr1 := Copy(LinePtr^[CurrentLine],CCol,MaxLineLen); + {remove it From current line AND refresh screen} + Truncate_Line; + {place Text on open a new line following the cursor} + Inc(CurrentLine); + Insert_Line(TempStr1); + {join the wrapped Text WITH the following lines OF Text} + Reformat_Paragraph; + {restore cursor to proper position after the wrap} + CurrentLine := PLine; + IF (PCol > CurLength) THEN + BEGIN + CCol := (PCol - CurLength); {position cursor after wrapped Word} + Inc(CurrentLine); {Cursor_Down;} + END + ELSE + CCol := PCol; {restore original cursor position} + IF ((CurrentLine - TopLine) >= ScreenLines) THEN + Scroll_Screen(ScrollSize) + ELSE + Refresh_Screen; + END; + + PROCEDURE Join_Lines; + {join the current line WITH the following line, IF possible} + BEGIN + Inc(CurrentLine); + Remove_Trailing; + Dec(CurrentLine); + Remove_Trailing; + IF ((CurLength + Length(LinePtr^[CurrentLine + 1])) >= MaxLineLen) THEN + Exit; + IF (LastChar <> ' ') THEN + Append_Space; + LinePtr^[CurrentLine] := LinePtr^[CurrentLine]+LinePtr^[CurrentLine + 1]; + Inc(CurrentLine); + Delete_Line; + Dec(CurrentLine); + Refresh_Screen; + END; + + PROCEDURE Split_Line; + {splits the current line at the cursor, leaves cursor IN original position} + VAR + TempStr1: AStr; + PCol: Integer; + BEGIN + PCol := CCol; + Remove_Trailing; {get the portion FOR the Next line} + TempStr1 := Copy(LinePtr^[CurrentLine],CCol,MaxLineLen); + Truncate_Line; + CCol := 1; {open a blank line} + Inc(CurrentLine); + Insert_Line(TempStr1); + IF ((CurrentLine - TopLine) > (ScreenLines - 2)) THEN + Scroll_Screen(ScrollSize) + ELSE + Refresh_Screen; + Dec(CurrentLine); + CCol := PCol; + END; + + PROCEDURE Cursor_NewLine; + BEGIN + IF (Insert_Mode) THEN + Split_Line; + CCol := 1; + Cursor_Down; + END; + + PROCEDURE Reformat; + {reformat paragraph, update display} + VAR + PLine: Integer; + BEGIN + PLine := CurrentLine; + Reformat_Paragraph; + {find start OF Next paragraph} + WHILE (CurLength = 0) AND (CurrentLine <= TotalLines) DO + Inc(CurrentLine); + {find top OF screen FOR Redisplay} + WHILE ((CurrentLine - TopLine) > (ScreenLines - 2)) DO + BEGIN + Inc(TopLine,ScrollSize); + PLine := TopLine; + END; + Refresh_Screen; + END; + + PROCEDURE Insert_Char(C1: Char); + BEGIN + IF (CCol < CurLength) THEN + BEGIN + Remove_Trailing; + IF (CCol > CurLength) THEN + Reposition(TRUE); + END; + IF (Insert_Mode AND (CurLength >= MaxLineLen)) OR (CCol > MaxLineLen) THEN + BEGIN + IF (CCol <= MaxLineLen) THEN + Word_Wrap + ELSE IF (C1 = ' ') THEN + BEGIN + Cursor_NewLine; + Exit; + END + ELSE IF (LastChar = ' ') THEN + Cursor_NewLine {nonspace w/space at END-line is newline} + ELSE + Word_Wrap; {otherwise wrap Word down AND continue} + END; + {Insert character into the middle OF a line} + IF (Insert_Mode) AND (CCol <= CurLength) THEN + BEGIN + Insert(C1,LinePtr^[CurrentLine],CCol); + {update display line following cursor} + MCIAllowed := FALSE; + ColorAllowed := FALSE; + AllowAbort := FALSE; + PrintMain(Copy(LinePtr^[CurrentLine],CCol,MaxLineLen)); + MCIAllowed := TRUE; + ColorAllowed := TRUE; + AllowAbort := TRUE; + {position cursor FOR Next insertion} + Inc(CCol); + Reposition(TRUE); + END + ELSE + BEGIN {append a character to the END OF a line} + WHILE (CurLength < CCol) DO + Append_Space; + LinePtr^[CurrentLine][CCol] := C1; + {advance the cursor, updating the display} + Cursor_Right; + END; + Set_PhyLine; + END; + + PROCEDURE Delete_Char; + BEGIN + {Delete whole line IF it is empty} + IF (CCol > CurLength) AND (CurLength > 0) THEN + Join_Lines + ELSE IF (CCol <= CurLength) THEN + BEGIN {Delete IN the middle OF a line} + Delete(LinePtr^[CurrentLine],CCol,1); + MCIAllowed := FALSE; + ColorAllowed := FALSE; + AllowAbort := FALSE; + PrintMain(Copy(LinePtr^[CurrentLine],CCol,MaxLineLen)+' '); + MCIAllowed := TRUE; + ColorAllowed := TRUE; + AllowAbort := TRUE; + Reposition(TRUE); + Set_PhyLine; + END; + END; + + PROCEDURE Delete_WordRight; + BEGIN + IF (CurChar = ' ') THEN + REPEAT {skip blanks right} + Delete_Char; + UNTIL (CurChar <> ' ') OR (CCol > CurLength) + ELSE + BEGIN + REPEAT {find Next blank right} + Delete_Char; + UNTIL (Delimiter); + Delete_Char; + END; + END; + + PROCEDURE Page_Down; + BEGIN + IF ((TopLine + ScreenLines) < MaxLines) THEN + BEGIN + Inc(CurrentLine,ScrollSize); + Scroll_Screen(ScrollSize); + END; + END; + + PROCEDURE Page_Up; + BEGIN + IF (TopLine > 1) THEN + BEGIN + Dec(CurrentLine,ScrollSize); + IF (CurrentLine < 1) THEN + CurrentLine := 1; + Scroll_Screen(-ScrollSize); + END + ELSE + BEGIN + CurrentLine := 1; + CCol := 1; + Scroll_Screen(0); + END; + END; + + PROCEDURE FS_Delete_Line; + {Delete the line at the cursor, update display} + BEGIN + Delete_Line; + Refresh_Screen; + END; + + PROCEDURE Display_Insert_Status; + BEGIN + ANSIG(69,1); + Prompt('^1(Mode: '); + IF (Insert_Mode) THEN + Prompt('INS)') + ELSE + Prompt('OVR)'); + END; + + PROCEDURE Prepare_Screen; + VAR + Counter: Integer; + BEGIN + CLS; + ANSIG(1,1); + IF (TimeWarn) THEN + Prompt(^G^G' |12Warning: |10You have less than '+IntToStr(NSL DIV 60 + 1)+' '+ + Plural('minute',NSL DIV 60 + 1)+' remaining online!') + ELSE + BEGIN + Prompt('^1(Ctrl-Z = Help) ^5To:^1 '+PadLeftStr(MsgTo,20)+' ^5Subj: ^1'); + IF (MHeader.FileAttached = 0) THEN + Print(PadLeftStr(MsgSubj,20)) + ELSE + Print(PadLeftStr(StripName(MsgSubj),20)); + Display_Insert_Status; + END; + ANSIG(1,2); + DoLines; + FOR Counter := 1 TO ScreenLines DO {physical lines are now invalid} + PhyLine[Counter] := ''; + Scroll_Screen(0); {causes Redisplay} + END; + + PROCEDURE Redisplay; + BEGIN + TopLine := ((CurrentLine - ScreenLines) DIV 2); + Prepare_Screen; + END; + + PROCEDURE FS_Help; + BEGIN + CLS; + PrintF('FSHELP'); + PauseScr(FALSE); + Prepare_Screen; + END; + + PROCEDURE DoQuote(RedrawScreen: Boolean); + VAR + QuoteFile: Text; + TempStr1: AStr; + Fline, + Nline, + QuoteLi: Integer; + Done: Boolean; + + PROCEDURE GetOut(x: Boolean); + BEGIN + IF (x) THEN + Close(QuoteFile); + IF (InvisEdit) AND (RedrawScreen) THEN + Prepare_Screen; + MCIAllowed := TRUE; + END; + + BEGIN + Assign(QuoteFile,'TEMPQ'+IntToStr(ThisNode)); + Reset(QuoteFile); + IF (IOResult <> 0) THEN + Exit; + IF (MaxQuoteLines = 0) THEN + BEGIN + WHILE NOT EOF(QuoteFile) DO + BEGIN + ReadLn(QuoteFile,TempStr1); + Inc(MaxQuoteLines); + END; + Close(QuoteFile); + Reset(QuoteFile); + END; + + MCIAllowed := FALSE; + Done := FALSE; + + REPEAT + Abort := FALSE; + Next := FALSE; + CLS; + QuoteLi := 0; + IF (LastQuoteLine > 0) THEN + WHILE NOT EOF(QuoteFile) AND (QuoteLi < LastQuoteLine) DO + BEGIN + ReadLn(QuoteFile,TempStr1); + Inc(QuoteLi); + END; + IF EOF(QuoteFile) THEN + BEGIN + LastQuoteLine := 0; + QuoteLi := 0; + Reset(QuoteFile); + END; + WHILE (NOT EOF(QuoteFile)) AND ((QuoteLi - LastQuoteLine) < (PageLength - 4)) DO + BEGIN + ReadLn(QuoteFile,TempStr1); + Inc(QuoteLi); + TempStr1 := Copy(PadRightInt(QuoteLi,Length(IntToStr(MaxQuoteLines)))+':'+TempStr1,1,MaxLineLen); + PrintACR('^3'+TempStr1); + END; + Close(QuoteFile); + Reset(QuoteFile); + REPEAT + NL; + Prt('First line to quote [^5?^4=^5Help^4]: '); + Scaninput(TempStr1,'HQ?'^M); + IF (TempStr1 = '?') THEN + BEGIN + NL; + Print('^1<^3Q^1>uit, <^3H^1>eader, <^3?^1>Help, or first line to quote.'); + END + ELSE IF (TempStr1 = 'H') THEN + BEGIN + WHILE (TempStr1 > '') AND (NOT EOF(QuoteFile)) AND (CurrentLine <= MaxLines) DO + BEGIN + ReadLn(QuoteFile,TempStr1); + IF (InvisEdit) THEN + Insert_Line(TempStr1) + ELSE + BEGIN + LinePtr^[TotalLines] := TempStr1; + Inc(TotalLines); + END; + Inc(CurrentLine); + END; + Close(QuoteFile); + Reset(QuoteFile); + TempStr1 := 'H'; + END; + UNTIL ((TempStr1 <> '?') AND (TempStr1 <> 'H')) OR (HangUp); + Fline := StrToInt(TempStr1); + IF (Fline <= 0) THEN + LastQuoteLine := QuoteLi; + IF (TempStr1 = 'Q') THEN + Done := TRUE; + IF (Fline > MaxQuoteLines) OR (HangUp) THEN + BEGIN + GetOut(TRUE); + Exit; + END; + IF (Fline > 0) THEN + BEGIN + Prt('Last line to quote: '); + Scaninput(TempStr1,'Q'^M); + IF (TempStr1 <> #13) THEN + Nline := StrToInt(TempStr1) + ELSE + Nline := Fline; + IF (Nline < Fline) OR (Nline > MaxQuoteLines) THEN + BEGIN + GetOut(TRUE); + Exit; + END; + Nline := ((Nline - Fline) + 1); + WHILE (NOT EOF(QuoteFile)) AND (Fline > 1) DO + BEGIN + Dec(Fline); + ReadLn(QuoteFile,TempStr1); + END; + IF (NOT InvisEdit) THEN + CurrentLine := TotalLines; + WHILE (NOT EOF(QuoteFile)) AND (Nline > 0) AND (CurrentLine <= MaxLines) DO + BEGIN + Dec(Nline); + ReadLn(QuoteFile,TempStr1); + IF (InvisEdit) THEN + Insert_Line(TempStr1) + ELSE + BEGIN + LinePtr^[TotalLines] := TempStr1; + Inc(TotalLines); + END; + Inc(CurrentLine); + END; + Done := TRUE; + END; + UNTIL (Done) OR (HangUp); + GetOut(TRUE); + LastError := IOResult; + END; + + PROCEDURE FS_Editor; + VAR + GKey: Word; + SaveTimeWarn: Boolean; + BEGIN + InvisEdit := TRUE; + Insert_Mode := TRUE; + SaveTimeWarn := TimeWarn; + Count_Lines; + IF (TotalLines > 0) THEN + CurrentLine := (TotalLines + 1) + ELSE + CurrentLine := 1; + CCol := 1; + TopLine := 1; + ScreenLines := (PageLength - 4); + IF (ScreenLines > 20) THEN + ScreenLines := 20; + WHILE (CurrentLine - TopLine) > (ScrollSize + 3) DO + Inc(TopLine,ScrollSize); + Prepare_Screen; + REPEAT + IF ((InportFileOpen) AND (Buf = '')) THEN + IF (NOT EOF(InportFile)) THEN + BEGIN + ReadLn(InportFile,Buf); + Buf := Buf + ^M + END + ELSE + BEGIN + Close(InportFile); + InportFileOpen := FALSE; + END; + IF (TimeWarn) AND (NOT SaveTimeWarn) THEN + BEGIN + ANSIG(1,1); + Prompt(^G^G' |12Warning: |10You have '+IntToStr(NSL DIV 60)+' minute(s) remaining online!'); + ANSIG(CCol,((CurrentLine - TopLine) + TopScreen)); + SaveTimeWarn := TRUE; + END; + GKey := GetKey; + CASE GKey OF + 47 : + IF (CCol = 1) AND (NOT InportFileOpen) THEN + GKey := 27 + ELSE + Insert_Char(Char(GKey)); + 127 : + Delete_Char; + 32..46, 48..126, 128..254 : + Insert_Char(Char(GKey)); + 8 : BEGIN + IF (CCol = 1) THEN + BEGIN + Cursor_Left; + Join_Lines; + END + ELSE + BEGIN + Cursor_Left; + Delete_Char; + END; + END; + F_CTRLLEFT,1 : + Cursor_WordLeft; { ^A } + 2 : Reformat; { ^B } + F_PGDN,3 : + Page_Down; { ^C } + F_RIGHT,4 : + Cursor_Right; { ^D } + F_UP,5 : + Cursor_Up; { ^E } + F_CTRLRIGHT,6 : + Cursor_WordRight; { ^F } + F_DEL,7 : + Delete_Char; { ^G } + 9 : REPEAT + Insert_Char(' '); + UNTIL ((CCol MOD 5) = 0); { ^I } + 10 : + Join_Lines; { ^J } + F_END,11 : + Cursor_EndLine; { ^K } + 12 : + Redisplay; { ^L } + 13 : + Cursor_NewLine; { ^M } + 14 : + BEGIN + Split_Line; + Reposition(TRUE); + END; { ^N } + 16 : + BEGIN { ^P } + GKey := GetKey; + IF (GKey IN [0..9,Ord('0')..Ord('9')]) THEN + BEGIN + Insert_Char('^'); + Insert_Char(Char(GKey)); + END + ELSE + Buf := Char(GKey); + GKey := 0; + END; + 17 : + DoQuote(TRUE); { ^Q } + F_PGUP,18 : + Page_Up; { ^R } + F_LEFT,19 : + Cursor_Left; { ^S } + 20 : + Delete_WordRight;{ ^T } + F_INS,22 : + BEGIN { ^V } + Insert_Mode := NOT Insert_Mode; + Display_Insert_Status; + Reposition(TRUE); + END; + F_HOME,23 : + Cursor_StartLine; { ^W } + F_DOWN,24 : + Cursor_Down; { ^X } + 25 : + FS_Delete_Line; { ^Y } + 26 : + FS_Help; { ^Z } + END; + UNTIL ((GKey = 27) AND (NOT InportFileOpen)) OR (HangUp); + IF (InportFileOpen) THEN + BEGIN + Close(InportFile); + InportFileOpen := FALSE; + END; + Count_Lines; + InvisEdit := FALSE; + END; + + PROCEDURE PrintMsgTitle; + BEGIN + NL; + (* + Print(FString.lentermsg1); + *) + lRGLngStr(6,FALSE); + (* + Print(FString.lentermsg2); + *) + lRGLNGStr(7,FALSE); + DoLines; + END; + + PROCEDURE InputTheMessage(CantAbort1: Boolean; VAR DisableMCI1,SaveMsg1: Boolean); + VAR + LineStr, + TempStr1, + TempStr2, + TempStr3: AStr; + SaveMsgSubj: Str40; + Cmd, + Drive: Char; + SaveFileAttached, + HelpCounter: Byte; + Counter, + LineNum1, + LineNum2: SmallInt; + ShowCont, + ExitMsg, + SaveLine, + AbortMsg: Boolean; + + PROCEDURE EditMsgTo(VAR MsgTo1: Str36); + VAR + User: UserRecordType; + TempMsgTo: Str36; + UNum: Integer; + BEGIN + { Print(FString.default + ^M^J); } + lRGLngStr(34,FALSE); + IF (Pub) AND (NOT (MAInternet IN MemMsgArea.MAFlags)) THEN + BEGIN + Prt('To: '); + IF (MsgTo1 <> '') THEN + InputDefault(TempMsgTo,MsgTo1,36,[NoLineFeed,CapWords],FALSE) + ELSE + BEGIN + MPL(36); + InputMain(TempMsgTo,36,[NoLineFeed,CapWords]); + END; + MsgTo1 := TempMsgTo; + UserColor(6); + FOR UNum := 1 TO LennMCI(MsgTo1) DO + BackSpace; + UNum := StrToInt(MsgTo1); + IF (UNum >= 1) AND (UNum <= (MaxUsers - 1)) AND NOT (NetMail IN MHeader.Status) THEN + BEGIN + LoadURec(User,UNum); + MsgTo1 := Caps(User.Name); + MHeader.MTO.UserNum := UNum; + MHeader.MTO.Real := User.RealName; + IF (Pub) AND (MARealName IN MemMsgArea.MAFlags) THEN + MsgTo1 := Caps(User.RealName) + ELSE + MsgTo1 := Caps(User.Name); + END; + IF (SQOutSp(MsgTo1) = '') THEN + MsgTo1 := 'All'; + IF (MsgTo1 <> '') THEN + BEGIN + Prompt(MsgTo1); + UserColor(1); + NL; + END; + END + ELSE IF (NOT (MAInternet IN MemMsgArea.MAFlags)) THEN + Print(PadLeftStr('^4To: ^6'+Caps(MsgTo1),40)); + END; + + PROCEDURE EditMsgSubj(VAR MsgSubj1: Str40; CantAbort2: Boolean); + VAR + TempMsgSubj: Str40; + BEGIN + IF (MHeader.FileAttached = 0) AND (NOT CantAbort2) THEN + BEGIN + Prt('Subject: '); + IF (MsgSubj1 <> '') THEN + InputDefault(TempMsgSubj,MsgSubj1,40,[NoLineFeed],FALSE) + ELSE + BEGIN + MPL(40); + InputMain(TempMsgSubj,40,[NoLineFeed]); + END; + IF (TempMsgSubj <> '') THEN + MsgSubj1 := TempMsgSubj + ELSE + BEGIN + IF (MsgSubj1 <> '') THEN + Prompt('^6'+MsgSubj1+'^1'); + END; + NL; + END + ELSE + MsgSubj1 := MHeader.Subject; + UserColor(1); + END; + + PROCEDURE FileAttach(VAR ExitMsg1: Boolean); + VAR + FileName: Str40; + DOk, + KAbort, + AddBatch: Boolean; + TransferTime: LongInt; + BEGIN + NL; + Prt('File name: '); + MPL(40); + Input(FileName,40); + NL; + IF (NOT CoSysOp) OR (NOT IsUL(FileName)) THEN + FileName := General.FileAttachPath+StripName(FileName); + IF (NOT Exist(FileName)) AND (NOT InCom) AND (NOT Exist(FileName)) AND (FileName <> '') THEN + BEGIN + Print('^7That file does not exist!^1'); + ExitMsg1 := FALSE; + END + ELSE + BEGIN + IF Exist(FileName) AND (NOT CoSysOp) THEN + BEGIN + Print('^7You cannot use that file name!^1'); + ExitMsg1 := FALSE; + END + ELSE + BEGIN + IF (NOT Exist(FileName)) AND (InCom) THEN + BEGIN + Receive(FileName,TempDir+'\UP',FALSE,DOk,KAbort,AddBatch,TransferTime); + MHeader.FileAttached := 1; + END + ELSE IF Exist(FileName) THEN + BEGIN + DOk := TRUE; + MHeader.FileAttached := 2; + END; + IF (DOk) THEN + BEGIN + MsgSubj := FileName; + IF (CoSysOp) AND (NOT (NetMail IN MHeader.Status)) THEN + BEGIN + IF PYNQ('Delete file upon receipt? ',0,FALSE) THEN + MHeader.FileAttached := 1 + ELSE + MHeader.FileAttached := 2 + END + ELSE + MHeader.FileAttached := 1; + END + ELSE + MHeader.FileAttached := 0; + END; + END; + UserColor(1); + END; + + PROCEDURE ListMsg(LineNum1: Integer; DisplayLineNum: Boolean; VAR SaveLine: Boolean); + BEGIN + MCIAllowed := FALSE; + AllowContinue := TRUE; + DOSANSIOn := FALSE; + Abort := FALSE; + Next := FALSE; + NL; + WHILE ((LineNum1 <= (TotalLines - 1)) AND (NOT Abort) AND (NOT HangUp)) DO + BEGIN + IF (DisplayLineNum) THEN + Print('^3'+IntToStr(LineNum1)+':'); + Reading_A_Msg := TRUE; + IF (NOT DOSANSIOn) THEN + IF (Pos('>',Copy(LinePtr^[LineNum1],1,4)) > 0) THEN + UserColor(3) + ELSE + UserColor(1); + PrintACR(LinePtr^[LineNum1]); + Reading_A_Msg := FALSE; + Inc(LineNum1); + END; + IF (DisplayLineNum) THEN + BEGIN + NL; + Print(' ^7** ^3'+IntToStr(TotalLines - 1)+' '+(Plural('line',(TotalLines - 1))+' ^7**')); + END; + MCIAllowed := TRUE; + AllowContinue := FALSE; + DOSANSIOn := FALSE; + SaveLine := FALSE; + UserColor(1); + END; + + PROCEDURE UploadFile; + VAR + TempStr1: AStr; + DOk, + KAbort, + AddBatch: Boolean; + TransferTime: LongInt; + BEGIN + NL; + TempStr1 := ''; + IF (CoSysOp) THEN + BEGIN + Prt('Enter file to import [Enter=Upload]: '); + MPL(40); + Input(TempStr1,40); + END; + IF (TempStr1 = '') THEN + BEGIN + TempStr1 := 'TEMPMSG.'+IntToStr(ThisNode); + IF Exist(TempStr1) THEN + Kill(TempStr1); + END; + IF (NOT Exist(TempStr1)) AND (InCom) THEN + BEGIN + Receive(TempStr1,TempDir+'UP\',FALSE,DOk,KAbort,AddBatch,TransferTime); + TempStr1 := TempDir+'UP\'+TempStr1; + END; + IF ((TempStr1 <> '') AND (NOT HangUp)) THEN + BEGIN + Assign(InportFile,TempStr1); + Reset(InportFile); + IF (IOResult = 0) THEN + InportFileOpen := TRUE; + END; + UserColor(1); + END; + + BEGIN + FillChar(LinePtr^,(MaxLines * 121),0); + Abort := FALSE; + Next := FALSE; + AbortMsg := FALSE; + SaveMsg1 := FALSE; + DisableMCI1 := FALSE; + TotalLines := 1; + LastLineStr := ''; + + IF (NOT CheckDriveSpace('Message posting',General.MsgPath,General.MinSpaceForPost)) THEN + MsgSubj := '' + ELSE + BEGIN + IF (ReadInMsg <> '') THEN + BEGIN + Assign(InportFile,ReadInMsg); + Reset(InportFile); + IF (IOResult = 0) THEN + BEGIN + WHILE (NOT EOF(InportFile)) AND ((TotalLines - 1) <= MaxLines) DO + BEGIN + ReadLn(InportFile,LinePtr^[TotalLines]); + Inc(TotalLines); + END; + Close(InportFile); + END; + END + ELSE + BEGIN + EditMsgTo(MsgTo); + NL; + EditMsgSubj(MsgSubj,CantAbort1); + END; + END; + + IF (MsgSubj = '') THEN + IF (NOT CantAbort1) THEN + BEGIN + SaveMsg1 := FALSE; + NL; + Print('Aborted!'); + Exit; + END; + + IF (FSEditor IN ThisUser.SFlags) THEN + BEGIN + REPEAT + FS_Editor; + REPEAT + ExitMsg := TRUE; + NL; + Prt('Full screen editor (^5?^4=^5Help^4): '); + OneK(Cmd,^M'ACFMQSTU?',TRUE,TRUE); + NL; + CASE Cmd OF + 'A' : IF (CantAbort1) THEN + BEGIN + Print('^7You can not abort this message!^1'); + ExitMsg := FALSE; + END + ELSE IF PYNQ('Abort message? ',0,FALSE) THEN + BEGIN + AbortMsg := TRUE; + SaveMsg1 := FALSE; + NL; + Print('Aborted!'); + END; + 'C' : IF (TotalLines = 0) THEN + BEGIN + Print('^7Nothing to clear!^1'); + ExitMsg := FALSE; + END + ELSE IF PYNQ('Clear message? ',0,FALSE) THEN + FOR LineNum1 := 1 TO TotalLines DO + LinePtr^[LineNum1][0] := #0; + 'F' : IF (NOT AACS(General.FileAttachACS)) THEN + BEGIN + Print('^7You do not have access to this command!^1'); + ExitMsg := FALSE; + END + ELSE IF (CantAbort1) THEN + BEGIN + Print('^7You can not attach a file to this message!^1'); + ExitMsg := FALSE; + END + ELSE IF (MHeader.FileAttached > 0) THEN + BEGIN + Print('File attached: ^5'+StripName(MsgSubj)); + NL; + IF (PYNQ('Replace the attached file? ',0,FALSE)) THEN + FileAttach(ExitMsg) + ELSE + BEGIN + NL; + IF (PYNQ('Remove the attached file? ',0,FALSE)) THEN + BEGIN + SaveFileAttached := MHeader.FileAttached; + SaveMsgSubj := MsgSubj; + MHeader.FileAttached := 0; + MsgSubj := ''; + NL; + EditMsgSubj(MsgSubj,CantAbort1); + IF (MsgSubj = '') THEN + BEGIN + MsgSubj := SaveMsgSubj; + MHeader.FileAttached := SaveFileAttached; + NL; + Print('Aborted!'); + END; + END; + END; + END + ELSE IF PYNQ('Attach a file to this message? ',0,FALSE) THEN + FileAttach(ExitMsg); + 'M' : IF (NOT AACS(MemMsgArea.MCIACS)) THEN + BEGIN + Print('^7You do not have access to this command!^1'); + ExitMsg := FALSE; + END + ELSE + DisableMCI1 := PYNQ('Disable MCI Codes for this message ['+SQOutSp(ShowYesNo(DisableMCI1))+']? ',0,FALSE); + 'Q' : IF (NOT Exist('TEMPQ'+IntToStr(ThisNode))) THEN + BEGIN + Print('^7You are not replying to a message!^1'); + ExitMsg := FALSE; + END + ELSE IF ((TotalLines + 1) = MaxLines) THEN + BEGIN + Print('^7You have reached the maximum line limit!^1'); + ExitMsg := FALSE; + END + ELSE + BEGIN + InvisEdit := TRUE; + DoQuote(FALSE); + InvisEdit := FALSE; + END; + 'S' : BEGIN + FOR Counter := TotalLines DOWNTO 1 DO + BEGIN + LineNum2 := 0; + FOR LineNum1 := 1 TO Length(LinePtr^[Counter]) DO + IF (LinePtr^[Counter][LineNum1] <> ' ') THEN + Inc(LineNum2); + IF (LineNum2 = 0) THEN + BEGIN + LinePtr^[Counter][0] := #0; + Dec(TotalLines) + END + ELSE + Counter := 1; + END; + IF (CantAbort1) AND (TotalLines = 0) THEN + BEGIN + Print('^7You must complete this message!^1'); + ExitMsg := FALSE; + END + ELSE IF (TotalLines = 0) THEN + BEGIN + Print('^7Nothing to save!^1'); + ExitMsg := FALSE; + END + ELSE + BEGIN + SaveMsg1 := TRUE; + AbortMsg := FALSE; + Inc(TotalLines); + END; + END; + 'T' : IF (CantAbort1) THEN + BEGIN + Print('^7The receiver and subject can not be changed!^1'); + ExitMsg := FALSE; + END + ELSE + BEGIN + IF (NOT Pub) OR (MAInternet IN MemMsgArea.MAFlags) THEN + BEGIN + Print('^7The receiver of this message can not be changed!'); + ExitMsg := FALSE; + END + ELSE + EditMsgTo(MsgTo); + NL; + IF (MHeader.FileAttached > 0) THEN + BEGIN + Print('^7The subject of this message can not be changed!'); + ExitMsg := FALSE; + END + ELSE + EditMsgSubj(MsgSubj,CantAbort1); + END; + 'U' : IF ((TotalLines + 1) = MaxLines) THEN + BEGIN + Print('^7You have reached the maximum line limit!^1'); + ExitMsg := FALSE; + END + ELSE IF PYNQ('Import a file to this message? ',0,FALSE) THEN + UploadFile; + ^M : ExitMsg := TRUE; + '?' : BEGIN + PrintF('FSHELP'); + ExitMsg := FALSE; + END; + END; + UNTIL (AbortMsg) OR (ExitMsg) OR (SaveMsg1) OR (HangUp); + UNTIL ((AbortMsg) OR (SaveMsg1) OR (HangUp)); + END + ELSE + BEGIN + PrintMsgTitle; + HelpCounter := 1; + REPEAT + SaveLine := TRUE; + ExitMsg := TRUE; + InputLine(LineStr,MaxLineLen); + REPEAT + IF (LineStr = '/'^H) THEN + BEGIN + SaveLine := FALSE; + IF ((TotalLines - 1) >= 1) THEN + BEGIN + Dec(TotalLines); + LastLineStr := LinePtr^[TotalLines]; + IF (LastLineStr[Length(LastLineStr)] = #1) THEN + LastLineStr := Copy(LastLineStr,1,(Length(LastLineStr) - 1)); + NL; + Print('^3Backed up to line '+IntToStr(TotalLines)+':^1'); + END; + END; + IF (LineStr = '/') AND (NOT (InportFileOpen)) THEN + BEGIN + SaveLine := FALSE; + ShowCont := TRUE; + NL; + Prt('Line editor (^5?^4=^5Help^4): '); + OneK(Cmd,^M'ACDFILMOPQRSTUZ?',TRUE,TRUE); + IF (Cmd <> ^M) THEN + NL; + CASE Cmd OF + 'A' : IF (CantAbort1) THEN + Print('^7You can not abort this message!^1') + ELSE IF PYNQ('Abort message? ',0,FALSE) THEN + BEGIN + AbortMsg := TRUE; + SaveMsg1 := FALSE; + ShowCont := FALSE; + NL; + Print('Aborted!'); + END; + 'C' : IF ((TotalLines - 1) < 1) THEN + Print('^7Nothing to clear!^1') + ELSE IF PYNQ('Clear message? ',0,FALSE) THEN + BEGIN + IF ((TotalLines - 1) = MaxLines) THEN + ExitMsg := TRUE; + FOR LineNum1 := 1 TO (TotalLines - 1) DO + LinePtr^[LineNum1][0] := #0; + TotalLines := 1; + Escp := FALSE; + ShowCont := FALSE; + NL; + Print('^0Message cleared ... Start over ...^1'); + NL; + END; + 'D' : IF ((TotalLines - 1) < 1) THEN + Print('^7No lines to delete!^1') + ELSE + BEGIN + LineNum1 := -1; + InputIntegerWOC('Delete which line',LineNum1,[NumbersOnly],1,(TotalLines - 1)); + IF (LineNum1 >= 1) AND (LineNum1 <= (TotalLines - 1)) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + NL; + Print('^3Line '+IntToStr(LineNum1)+':'); + MCIAllowed := FALSE; + PrintAcr('^1'+LinePtr^[LineNum1]); + MCIAllowed := TRUE; + NL; + IF (PYNQ('Delete this line? ',0,FALSE)) THEN + BEGIN + IF ((TotalLines - 1) = MaxLines) THEN + ExitMsg := TRUE; + FOR LineNum2 := LineNum1 TO (TotalLines - 2) DO + LinePtr^[LineNum2] := LinePtr^[LineNum2 + 1]; + Dec(TotalLines); + NL; + Print('^0Line '+IntToStr(LineNum1)+' deleted.^1'); + END; + END; + END; + 'F' : IF (NOT AACS(General.FileAttachACS)) THEN + Print('^7You do not have access to this command!^1') + ELSE IF (CantAbort1) THEN + Print('^7You can not attach a file to this message!^1') + ELSE IF (MHeader.FileAttached > 0) THEN + BEGIN + Print('File attached: ^5'+StripName(MsgSubj)); + NL; + IF (PYNQ('Replace the attached file? ',0,FALSE)) THEN + BEGIN + FileAttach(ExitMsg); + ExitMsg := TRUE; + END + ELSE + BEGIN + NL; + IF (PYNQ('Remove the attached file? ',0,FALSE)) THEN + BEGIN + SaveFileAttached := MHeader.FileAttached; + SaveMsgSubj := MsgSubj; + MHeader.FileAttached := 0; + MsgSubj := ''; + NL; + EditMsgSubj(MsgSubj,CantAbort1); + IF (MsgSubj = '') THEN + BEGIN + MsgSubj := SaveMsgSubj; + MHeader.FileAttached := SaveFileAttached; + NL; + Print('Aborted!'); + END; + END; + END; + END + ELSE IF PYNQ('Attach a file to this message? ',0,FALSE) THEN + BEGIN + FileAttach(ExitMsg); + ExitMsg := TRUE; + END; + 'I' : IF ((TotalLines - 1) < 1) THEN + Print('^7No lines to insert before!^1') + ELSE IF ((TotalLines - 1) >= MaxLines) THEN + Print('^7You have reached the maximum line limit!^1') + ELSE + BEGIN + LineNum1 := -1; + InputIntegerWOC('Insert before which line',LineNum1,[NumbersOnly],1,TotalLines); + IF (LineNum1 >= 1) AND (LineNum1 <= TotalLines) THEN + BEGIN + NL; + Print('^3Line '+IntToStr(LineNum1)+':'); + UserColor(1); + InputLine(TempStr1,MaxLineLen); + NL; + IF (PYNQ('Insert this line? ',0,FALSE)) THEN + BEGIN + FOR LineNum2 := TotalLines DOWNTO (LineNum1 + 1) DO + LinePtr^[LineNum2] := LinePtr^[LineNum2 - 1]; + LinePtr^[LineNum1] := TempStr1; + Inc(TotalLines); + IF ((TotalLines - 1) = MaxLines) THEN + ExitMsg := FALSE; + NL; + Print('^0Line '+IntToStr(LineNum1)+' inserted.^1'); + END; + END; + END; + 'L' : IF ((TotalLines - 1) < 1) THEN + Print('^7Nothing to list!^1') + ELSE + BEGIN + IF (PYNQ('List entire message? ',0,TRUE)) THEN + BEGIN + NL; + ListMsg(1,PYNQ('List message with line numbers? ',0,FALSE),SaveLine); + END + ELSE + BEGIN + LineNum1 := -1; + InputIntegerWOC('%LFStaring line number',LineNum1,[NumbersOnly],1,(TotalLines - 1)); + IF (LineNum1 >= 1) AND (LineNum1 <= (TotalLines - 1)) THEN + BEGIN + NL; + ListMsg(LineNum1,PYNQ('List message with line numbers? ',0,FALSE),SaveLine); + END; + END; + ShowCont := FALSE; + END; + 'M' : IF (NOT AACS(MemMsgArea.MCIACS)) THEN + Print('^7You do not have access to this command!^1') + ELSE + DisableMCI1 := PYNQ('Disable MCI Codes for this message ['+SQOutSp(ShowYesNo(DisableMCI1))+']? ',0,FALSE); + 'O' : PrintF('COLOR'); + 'P' : IF ((TotalLines - 1) < 1) THEN + Print('^7No lines to replace a string!^1') + ELSE + BEGIN + LineNum1 := -1; + InputIntegerWOC('Line to replace string',LineNum1,[NumbersOnly],1,(TotalLines - 1)); + IF (LineNum1 >= 1) AND (LineNum1 <= (TotalLines - 1)) THEN + BEGIN + TempStr3 := LinePtr^[LineNum1]; + Abort := FALSE; + Next := FALSE; + NL; + Print('^3Old line '+IntToStr(LineNum1)+':'); + MCIAllowed := FALSE; + PrintACR('^1'+TempStr3); + MCIAllowed := TRUE; + NL; + Print('^4Enter string to replace:'); + Prt(': '); + InputL(TempStr1,MaxLineLen); + IF (TempStr1 <> '') THEN + IF (Pos(TempStr1,LinePtr^[LineNum1]) = 0) THEN + BEGIN + NL; + Print('^7String not found.^1'); + END + ELSE + BEGIN + NL; + Print('^4Enter replacement string:'); + Prt(': '); + InputL(TempStr2,MaxLineLen); + IF (TempStr2 <> '') THEN + BEGIN + IF (Pos(TempStr1,TempStr3) > 0) THEN + BEGIN + Insert(TempStr2,TempStr3,(Pos(TempStr1,TempStr3) + Length(TempStr1))); + Delete(TempStr3,Pos(TempStr1,TempStr3),Length(TempStr1)); + END; + NL; + Print('^3New line '+IntToStr(LineNum1)+':'); + MCIAllowed := FALSE; + PrintACR('^1'+TempStr3); + MCIAllowed := TRUE; + NL; + IF (PYNQ('Save this line? ',0,FALSE)) THEN + BEGIN + Insert(TempStr2,LinePtr^[LineNum1],(Pos(TempStr1,LinePtr^[LineNum1]) + Length(TempStr1))); + Delete(LinePtr^[LineNum1],Pos(TempStr1,LinePtr^[LineNum1]),Length(TempStr1)); + NL; + Print('^0Line '+IntToStr(LineNum1)+' saved.^1'); + END; + END; + END; + END; + END; + 'Q' : IF (NOT Exist('TEMPQ'+IntToStr(ThisNode))) THEN + Print('^7You are not replying to a message!^1') + ELSE IF ((TotalLines - 1) >= MaxLines) THEN + Print('^7You have reached the maximum line limit!^1') + ELSE + BEGIN + DoQuote(FALSE); + NL; + CLS; + PrintMsgTitle; + Print('^0Quoting complete ... Continue ...^1'); + NL; + IF ((TotalLines - 1) >= 1) THEN + IF ((TotalLines - 1) > 10) THEN + ListMsg(((TotalLines - 1) - 10),FALSE,SaveLine) + ELSE + ListMsg(1,FALSE,SaveLine); + ShowCont := FALSE; + END; + 'R' : IF ((TotalLines - 1) < 1) THEN + Print('^7No last line to delete!^1') + ELSE + BEGIN + LineNum1 := (TotalLines - 1); + Print('^3Line '+IntToStr(LineNum1)+':'); + MCIAllowed := FALSE; + PrintAcr('^1'+LinePtr^[(LineNum1)]); + MCIAllowed := TRUE; + NL; + IF (PYNQ('Delete the last line? ',0,FALSE)) THEN + BEGIN + IF ((TotalLines - 1) = MaxLines) THEN + ExitMsg := TRUE; + Dec(TotalLines); + NL; + Print('^0Line '+IntToStr(LineNum1)+' deleted.^1'); + END; + END; + 'S' : BEGIN + WHILE (((TotalLines - 1) >= 1) AND ((LinePtr^[TotalLines - 1] = '') OR + (LinePtr^[TotalLines - 1] = ^J))) DO + Dec(TotalLines); + FOR Counter := (TotalLines - 1) DOWNTO 1 DO + BEGIN + LineNum2 := 0; + FOR LineNum1 := 1 TO Length(LinePtr^[Counter]) DO + IF (LinePtr^[Counter][LineNum1] <> ' ') THEN + Inc(LineNum2); + IF (LineNum2 = 0) THEN + BEGIN + LinePtr^[Counter][0] := #0; + Dec(TotalLines) + END + ELSE + Counter := 1; + END; + IF (CantAbort1) AND ((TotalLines - 1) < 1) THEN + Print('^7You must complete this message!^1') + ELSE IF ((TotalLines - 1) < 1) THEN + Print('^7Nothing to save!^1') + ELSE + BEGIN + SaveMsg1 := TRUE; + AbortMsg := FALSE; + ShowCont := FALSE; + END; + END; + 'T' : IF (CantAbort1) THEN + Print('^7The receiver and subject can not be changed!^1') + ELSE + BEGIN + IF (NOT Pub) OR (MAInternet IN MemMsgArea.MAFlags) THEN + Print('^7The receiver of this message can not be changed!') + ELSE + EditMsgTo(MsgTo); + NL; + IF (MHeader.FileAttached > 0) THEN + Print('^7The subject of this message can not be changed!') + ELSE + EditMsgSubj(MsgSubj,CantAbort1); + END; + 'U' : IF ((TotalLines - 1) >= MaxLines) THEN + Print('^7You have reached the maximum line limit!^1') + ELSE IF PYNQ('Import a file to this message? ',0,FALSE) THEN + UploadFile; + 'Z' : IF ((TotalLines - 1) < 1) THEN + Print('^7No lines to replace!') + ELSE + BEGIN + LineNum1 := -1; + InputIntegerWOC('Line number to replace',LineNum1,[NumbersOnly],1,(TotalLines - 1)); + IF ((LineNum1 >= 1) AND (LineNum1 <= (TotalLines - 1))) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + NL; + Print('^3Old line '+IntToStr(LineNum1)+':'); + MCIAllowed := FALSE; + PrintACR('^1'+LinePtr^[LineNum1]); + MCIAllowed := TRUE; + Print('^3New line '+IntToStr(LineNum1)+':'); + UserColor(1); + InputLine(TempStr1,MaxLineLen); + NL; + IF PYNQ('Replace this line? ',0,FALSE) THEN + BEGIN + IF (LinePtr^[LineNum1][Length(LinePtr^[LineNum1])] = #1) AND (TempStr1[Length(TempStr1)]<>#1) THEN + LinePtr^[LineNum1] := TempStr1 + #1 + ELSE + LinePtr^[LineNum1] := TempStr1; + NL; + Print('^0Line '+IntToStr(LineNum1)+' replaced.^1'); + END; + END; + END; + ^M : BEGIN + IF (HelpCounter = 5) THEN + BEGIN + NL; + PrintF('PRHELP'); + HelpCounter := 0; + END; + Inc(HelpCounter); + END; + '?' : PrintF('PRHELP'); + END; + IF (ShowCont) AND (ExitMsg) THEN + BEGIN + NL; + Print('^0Continue...^1'); + NL; + END; + END; + IF (SaveLine) THEN + BEGIN + LinePtr^[TotalLines] := LineStr; + Inc(TotalLines); + IF (LineStr <> '') THEN + HelpCounter := 1 + ELSE + BEGIN + IF (HelpCounter = 5) THEN + BEGIN + Print('^0Enter "/?" on a blank line for help.^1'); + Dec(TotalLines,5); + HelpCounter := 0; + END; + Inc(HelpCounter); + END; + IF ((TotalLines - 1) >= MaxLines) THEN + BEGIN + NL; + Print('^7You have reached the maximum line limit!'); + IF (InportFileOpen) THEN + BEGIN + InportFileOpen := FALSE; + Close(InportFile); + END; + HelpCounter := 1; + ExitMsg := FALSE; + LineStr := '/'; + END; + END; + UNTIL (AbortMsg) OR (ExitMsg) OR (SaveMsg1) OR (HangUp); + UNTIL ((AbortMsg) OR (SaveMsg1) OR (HangUp)); + END; + END; + + PROCEDURE SaveIt(DisableMCI1: Boolean); + VAR + LineStr: AStr; + UserName: Str36; + C: Char; + LineNum1, + Counter: Integer; + AddTagLine: Boolean; + BEGIN + + IF (ReadInMsg <> '') THEN + BEGIN + + Assign(InportFile,ReadInMsg); + ReWrite(InportFile); + IF (IOResult = 0) THEN + BEGIN + FOR LineNum1 := 1 TO (TotalLines - 1) DO + WriteLn(InportFile,LinePtr^[LineNum1]); + Close(InportFile); + END; + + END + ELSE + BEGIN + + AddTagLine := FALSE; + IF (MAQuote IN MemMsgArea.MAFlags) THEN + AddTagLine := PYNQ('Add a tagline to your message? ',0,TRUE); + + MHeader.Subject := MsgSubj; + MHeader.OriginDate := ''; + MHeader.From.Anon := 0; + MHeader.MTO.Anon := 0; + MHeader.Replies := 0; + MHeader.ReplyTo := 0; + MHeader.Date := GetPackDateTime; + GetDayOfWeek(MHeader.DayOfWeek); + + IF (Pub AND (MemMsgArea.MAType IN [1,2])) OR (NOT Pub AND (NetMail IN MHeader.Status)) THEN + BEGIN + NewEchoMail := TRUE; + IF (NOT (MAScanOut IN MemMsgArea.MAFlags)) THEN + UpdateBoard; + END; + + MHeader.From.UserNum := UserNum; + + UserName := AllCaps(ThisUser.Name); + + IF (NOT Pub) AND (NetMail IN MHeader.Status) AND (ThisUser.Name <> AllCaps(ThisUser.RealName)) THEN + IF (General.AllowAlias) THEN + BEGIN + NL; + IF PYNQ('Send this with your real name? ',0,TRUE) THEN + UserName := AllCaps(ThisUser.RealName); + END; + + MHeader.From.A1S := UserName; + MHeader.From.Real := AllCaps(ThisUser.RealName); + MHeader.From.Name := AllCaps(ThisUser.Name); + + MHeader.Status := [] + (MHeader.Status * [NetMail]); + + IF (Pub) AND (RValidate IN ThisUser.Flags) THEN + Include(MHeader.Status,Unvalidated); + + IF (AACS(MemMsgArea.MCIACS)) THEN + BEGIN + Include(MHeader.Status,AllowMCI); + IF (DisableMCI1) THEN + Exclude(MHeader.Status,AllowMCI); + END; + + IF (Pub) THEN + BEGIN + MHeader.MTO.Name := MsgTo; + MHeader.MTO.Real := MsgTo; + MHeader.MTO.A1S := MsgTo; + END; + + IF (NOT (NetMail IN MHeader.Status)) THEN + Anonymous(FALSE,MHeader); + + NL; + Prompt('^5Saving...'); + + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + MHeader.TextSize := 0; + MHeader.Pointer := (FileSize(MsgTxtF) + 1); + Seek(MsgTxtF,FileSize(MsgTxtF)); + + IF (NetMail IN MHeader.Status) AND (Pos('@',MHeader.MTO.A1S) > 0) THEN + BEGIN + + FOR Counter := 1 TO Length(MHeader.MTO.A1S) DO + IF (MHeader.MTO.A1S[Counter] IN ['A'..'Z']) THEN + Inc(MHeader.MTO.A1S[Counter],32); + + LineStr := 'To: '+MsgTo; + BlockWrite(MsgTxtF,LineStr,Length(LineStr) + 1); + Inc(MHeader.TextSize,Length(LineStr) + 1); + + MHeader.MTO.A1S := 'UUCP'; + END; + + IF ((Pub) AND (MAFilter IN MemMsgArea.MAFlags)) THEN + FOR LineNum1 := 1 TO (TotalLines - 1) DO + IF (Length(LinePtr^[LineNum1]) > 0) THEN + BEGIN + LinePtr^[LineNum1] := StripColor(LinePtr^[LineNum1]); + FOR Counter := 1 TO Length(LinePtr^[LineNum1]) DO + BEGIN + C := LinePtr^[LineNum1][Counter]; + IF (C IN [#0..#1,#3..#31,#127..#255]) THEN + C := '*'; + LinePtr^[LineNum1][Counter] := C; + END; + END; + + FOR LineNum1 := 1 TO (TotalLines - 1) DO + BEGIN + LineStr := LinePtr^[LineNum1]; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,(Length(LineStr) + 1)); + END; + + IF (AddTagLine) THEN + BEGIN + LineStr := ''; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,(Length(LineStr) + 1)); + LineStr := '... '+GetTagLine; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,(Length(LineStr) + 1)); + END; + + IF (MemMsgArea.MAType IN [1,2]) AND (MAAddTear IN MemMsgarea.MAFlags) THEN + BEGIN + LineStr := ''; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,1); + + LineStr := '--- Renegade v'+General.Version; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,(Length(LineStr) + 1)); + + IF (MemMsgArea.AKA > 19) THEN + MemMsgArea.AKA := 0; + + LineStr := ' * Origin: '; + IF (MemMsgArea.Origin <> '') THEN + LineStr := LineStr + MemMsgArea.Origin + ELSE + LineStr := LineStr + General.Origin; + + LineStr := LineStr + ' ('; + + LineStr := LineStr + IntToStr(General.AKA[MemMsgArea.AKA].Zone)+':'+ + IntToStr(General.AKA[MemMsgArea.AKA].Net)+'/'+ + IntToStr(General.AKA[MemMsgArea.AKA].Node); + + IF (General.AKA[MemMsgArea.AKA].Point > 0) THEN + LineStr := LineStr + '.'+IntToStr(General.AKA[MemMsgArea.AKA].Point); + + LineStr := LineStr + ')'; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,(Length(LineStr) + 1)); + + END; + + Close(MsgTxtF); + LastError := IOResult; + + BackErase(9); + + END; + + InputMessage := TRUE; + + END; + +BEGIN + CLS; + InputMessage := FALSE; + + MaxLines := ((MaxAvail DIV 120) - 20); + IF (MaxLines > MaxMsgLines) THEN + MaxLines := MaxMsgLines; + GetMem(LinePtr,(MaxLines * 120)); + + InportFileOpen := FALSE; + Escp := FALSE; + MaxQuoteLines := 0; + LastQuoteLine := 0; + + IF (NOT IsReply) THEN + MsgTo := '' + ELSE + BEGIN + IF (MARealName IN MemMsgArea.MAFlags) THEN + MsgTo := Caps(MHeader.MTO.Real) + ELSE + MsgTo := Caps(MHeader.MTO.A1S) + END; + + IF (InResponseTo <> '') THEN + MsgSubj := InResponseTo + ELSE + MsgSubj := MsgTitle; + + IF (MsgSubj[1] <> '\') THEN + CantAbort := FALSE + ELSE + BEGIN + MsgSubj := Copy(MsgSubj,2,(Length(MsgSubj) - 1)); + MHeader.Subject := MsgSubj; + CantAbort := TRUE; + END; + + IF (MsgSubj[1] = #1) THEN + BEGIN + MsgSubj := Copy(MsgSubj,2,(Length(MsgSubj) - 1)); + IF (MHeader.Subject[1] = #1) THEN + MHeader.Subject := Copy(MHeader.Subject,2,(Length(MHeader.Subject) - 1)); + END + ELSE IF (MsgSubj <> '') AND (Copy(MsgSubj,1,3) <> 'Re:') THEN + MsgSubj := 'Re: '+Copy(MsgSubj,1,36); + + MHeader.FileAttached := 0; + + InputTheMessage(CantAbort,DisableMCI,SaveMsg); + + IF (SaveMsg) THEN + SaveIt(DisableMCI); + + Kill('TEMPQ'+IntToStr(ThisNode)); + + DOSANSIOn := FALSE; + + FreeMem(LinePtr,(MaxLines * 120)); +END; + +END. diff --git a/SOURCE/MAIL2.PAS b/SOURCE/MAIL2.PAS new file mode 100644 index 0000000..f45e300 --- /dev/null +++ b/SOURCE/MAIL2.PAS @@ -0,0 +1,1403 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Mail2; + +INTERFACE + +USES + Common; + +PROCEDURE Post(ReplyTo: LongInt; VAR TToI: FromToInfo; PvtMsg: Boolean); +PROCEDURE ReadAllMessages(MenuOption: Str50); +PROCEDURE ScanMessages(MArea: Integer; AskUpDate: Boolean; MenuOption: Str50); +PROCEDURE StartNewScan(MenuOption: Str50); +PROCEDURE ScanYours; +FUNCTION FirstNew: Word; + +IMPLEMENTATION + +USES + Dos, + Common5, + Mail0, + Mail1, + EMail, + Mail3, + Menus, + ShortMsg, + SysOp2G, + SysOp3, + TimeFunc; + +VAR + TempLastRead: LongInt; + +PROCEDURE Post(ReplyTo: LongInt; VAR TToI: FromToInfo; PvtMsg: Boolean); +VAR + MHeader: MHeaderRec; + PostOk: Boolean; +BEGIN + + LoadMsgArea(MsgArea); + + PostOk := TRUE; + + IF (NOT AACS(MemMsgArea.PostACS)) THEN + BEGIN + NL; + Print('^7Your access level does not permit you to post in this message area!^1'); + PostOk := FALSE; + END + ELSE IF (AccountBalance < General.CreditPost) AND (NOT (FNoCredits IN ThisUser.Flags)) THEN + BEGIN + NL; + Print('^7Insufficient account balance to post a public message!^1'); + PostOk := FALSE; + END + ELSE IF (RPost IN ThisUser.Flags) OR (NOT AACS(General.NormPubPost)) THEN + BEGIN + NL; + Print('^7Your access priviledges do not include posting a public messages!^1'); + PostOk := FALSE; + END + ELSE IF (PublicPostsToday >= General.MaxPubPost) AND (NOT MsgSysOp) THEN + BEGIN + NL; + Print('^7You have already sent the maximum public messages allowed per day!^1'); + PostOk := FALSE; + END; + + IF (NOT PostOk) THEN + Exit; + + InitMsgArea(MsgArea); + + MHeader.Status := []; + + MHeader.FileAttached := 0; + + IF (ReplyTo <> -1) THEN + BEGIN + MHeader.MTo := TToI; + IF (MHeader.MTo.Anon > 0) THEN + MHeader.MTo.A1S := UseName(MHeader.MTo.Anon,MHeader.MTo.A1S); + END + ELSE + BEGIN + FillChar(MHeader.MTo,SizeOf(MHeader.MTo),0); + InResponseTo := ''; + END; + + IF (MemMsgArea.PrePostFile <> '') THEN + BEGIN + PrintF(MemMsgArea.PrePostFile); + PauseScr(FALSE); + END; + + IF (InputMessage(TRUE,(ReplyTo <> -1),'',MHeader,'',78,500)) THEN + BEGIN + + IF (ReplyTo <> -1) THEN + MHeader.ReplyTo := ((HiMsg + 1) - ReplyTo); + + IF (PvtMsg) THEN + Include(MHeader.Status,Prvt); + + SaveHeader((HiMsg + 1),MHeader); + + Print('^1Message posted on ^5'+MemMsgArea.Name+'^1.'); + + SysOpLog(MHeader.Subject+' posted on ^5'+MemMsgArea.Name); + + IF (MHeader.MTo.A1S <> '') THEN + SysOpLog(' To: "'+MHeader.MTo.A1S+'"'); + + IF (ReplyTo <> -1) THEN + BEGIN + LoadHeader(ReplyTo,MHeader); + Inc(MHeader.Replies); + SaveHeader(ReplyTo,MHeader); + END; + + IF (ThisUser.MsgPost < 2147483647) THEN + Inc(ThisUser.MsgPost); + + IF (PublicPostsToday < 255) THEN + Inc(PublicPostsToday); + + IF (NOT (FNoCredits IN ThisUser.Flags)) THEN + AdjustBalance(General.CreditPost); + + SaveURec(ThisUser,UserNum); + + Update_Screen; + + END; +END; + +PROCEDURE ListMessages(Pub: Boolean); +VAR + MHeader: MHeaderRec; + S, + S1: STRING; + TempHiMsg: Word; + ADate: DateTime; + NumDone: Byte; +BEGIN + TempHiMsg := HiMsg; + IF ((Msg_On < 1) OR (Msg_On > TempHiMsg)) THEN + Exit; + Abort := FALSE; + Next := FALSE; + CLS; + PrintACR('Ŀ'); + PrintACR(' Msg#  Sender  Receiver  '+'Subject ! Posted '); + PrintACR(''); + Dec(Msg_On); + NumDone := 0; + WHILE ((NumDone < (PageLength - 7)) AND (Msg_On >= 0) AND (Msg_On < TempHiMsg) AND (NOT Abort) AND (NOT HangUp)) DO + BEGIN + Inc(Msg_On); + + LoadHeader(Msg_On,MHeader); + + IF ((NOT (UnValidated IN MHeader.Status)) AND (NOT (MDeleted IN MHeader.Status))) OR (MsgSysOp) THEN + BEGIN + + IF (MDeleted IN MHeader.Status) THEN + S := '''D' + ELSE IF (UnValidated IN MHeader.Status) THEN + S := '''U' + ELSE IF ToYou(MHeader) OR FromYou(MHeader) THEN + S := '''>' + ELSE IF (Pub) AND (TempLastRead < MHeader.Date) THEN + S := '''*' + ELSE + S := ' '; + + S := S + ' "'+PadLeftInt(Msg_On,5)+' #'; + + IF (MARealName IN MemMsgArea.MAFlags) THEN + S1 := UseName(MHeader.From.Anon,MHeader.From.Real) + ELSE + S1 := UseName(MHeader.From.Anon,MHeader.From.A1S); + + S := S + PadLeftStr(S1,18)+' $'; + + IF ((MARealName IN MemMsgArea.MAFlags) AND (MHeader.MTo.Real <> '')) THEN + S1 := UseName(MHeader.MTo.Anon,MHeader.MTo.Real) + ELSE + S1 := UseName(MHeader.MTo.Anon,MHeader.MTo.A1S); + + S := S + PadLeftStr(S1,19)+' % '; + + IF (MHeader.FileAttached = 0) THEN + S := S + PadLeftStr(MHeader.Subject,18) + ELSE + S := S + PadLeftStr(Stripname(MHeader.Subject),18); + + PackToDate(ADate,MHeader.Date); + + S := S + ' &'+ZeroPad(IntToStr(ADate.Month))+'/'+ ZeroPad(IntToStr(ADate.Day))+'/'+ZeroPad(IntToStr(ADate.Year)); + + IF (AllowMCI IN MHeader.Status) THEN + PrintACR(S) + ELSE + Print(S); + + Inc(NumDone); + END; + Wkey; + END; +END; + +PROCEDURE MainRead(OncOnly,AskUpdate,Pub: Boolean); +VAR + User: UserRecordType; + MHeader: MHeaderRec; + Cmd, + NewMenuCmd: AStr; + Junk: Str36; + Cmd1: Char; + SaveMenu, + CmdToExec, + Counter: Byte; + MsgNum, + ThreadStart: Word; + Done, + CmdNotHid, + CmdExists, + AskPost, + Contlist, + DoneScan, + HadUnVal: Boolean; + + FUNCTION CantBeSeen: Boolean; + BEGIN + CantBeSeen := (NOT MsgSysOp) AND ((UnValidated IN MHeader.Status) OR (MDeleted IN MHeader.Status) OR + ((Prvt IN MHeader.Status) AND NOT (ToYou(MHeader) OR FromYou(MHeader)))); + END; + +BEGIN + AskPost := FALSE; + Contlist := FALSE; + DoneScan := FALSE; + HadUnVal := FALSE; + AllowContinue := TRUE; + ThreadStart := 0; + TReadPrompt := 0; + Abort := FALSE; + Next := FALSE; + SaveMenu := CurMenu; + + IF (MemMsgArea.MessageReadMenu <> 0) THEN + CurMenu := MemMsgArea.MessageReadMenu + ELSE + CurMenu := General.MessageReadMenu; + + IF (NOT NewMenuToLoad) THEN + LoadMenuPW; + + AutoExecCmd('FIRSTCMD'); + + REPEAT + + IF (Contlist) AND (Abort) THEN + BEGIN + Contlist := FALSE; + NL; + Print('Continuous message listing off.'); + TReadPrompt := 255; + END; + + IF (Msg_On < 1) OR (Msg_On > HiMsg) THEN + BEGIN + IF (NOT Contlist) THEN + BEGIN + DoneScan := TRUE; + IF (Pub) THEN + AskPost := TRUE; + END + ELSE + BEGIN + Contlist := FALSE; + Msg_On := HiMsg; + NL; + Print('Continuous message listing off.'); + TReadPrompt := 255; + END; + END; + + IF (NOT DoneScan) AND (TReadPrompt IN [0..2,8..10,18]) THEN + BEGIN + IF (Contlist) THEN + Next := TRUE; + LoadHeader(Msg_On,MHeader); + IF (Pub) AND (UnValidated IN MHeader.Status) THEN + HadUnVal := TRUE; + WHILE (((Msg_On < HiMsg) AND (TReadPrompt <> 2)) OR ((Msg_On > 1) AND (TReadPrompt = 2))) AND + (CantBeSeen) DO + BEGIN + IF (TReadPrompt = 2) THEN + Dec(Msg_On) + ELSE + Inc(Msg_On); + LoadHeader(Msg_On,MHeader); + END; + IF ((Msg_On = 1) OR (Msg_On = HiMsg)) AND (CantBeSeen) THEN + BEGIN + DoneScan := TRUE; + IF (Pub) THEN + AskPost := TRUE; + END + ELSE + BEGIN + IF ((CLSMsg IN ThisUser.SFlags) AND (NOT Contlist)) THEN + Cls + ELSE + NL; + ReadMsg(Msg_On,Msg_On,HiMsg); + IF (Pub) AND (TempLastRead < MHeader.Date) AND (MHeader.Date <= GetPackDateTime) THEN + TempLastRead := MHeader.Date; + IF (Pub) THEN + IF (PublicReadThisCall < 32767) THEN + Inc(PublicReadThisCall); + END; + END; + IF (NOT Contlist) AND (NOT DoneScan) THEN + REPEAT + TReadPrompt := 0; + MainMenuHandle(Cmd); + NewMenuCmd := ''; + CmdToExec := 0; + Done := FALSE; + REPEAT + FCmd(Cmd,CmdToExec,CmdExists,CmdNotHid); + IF (CmdToExec <> 0) AND (MemCmd^[CmdToExec].CmdKeys <> '-^') AND + (MemCmd^[CmdToExec].CmdKeys <> '-/') AND (MemCmd^[CmdToExec].CmdKeys <> '-\') THEN + DoMenuCommand(Done, + MemCmd^[CmdToExec].CmdKeys, + MemCmd^[CmdToExec].Options, + NewMenuCmd, + MemCmd^[CmdToExec].NodeActivityDesc); + UNTIL (CmdToExec = 0) OR (Done) OR (HangUp); + Abort := FALSE; + Next := FALSE; + CASE TReadPrompt OF + 1 : ; { Read Again } + 2 : Dec(Msg_On); { Previous Message } + + 3 : IF (NOT MsgSysOp) THEN + Print('^7You do not have the required access level for this option!^1') + ELSE + MoveMsg(Msg_On); + + 4 : IF (NOT CoSysOp) THEN + Print('^7You do not have the required access level for this option!^1') + ELSE + ExtractMsgToFile(Msg_On,Mheader); + + 5 : IF (NOT FromYou(MHeader)) AND (NOT MsgSysOp) THEN + BEGIN + NL; + Print('^7You can only edit messages that you have sent!^1'); + END + ELSE + BEGIN + REPEAT + NL; + Prt('Message editing [^5?^4=^5Help^4]: '); + IF (MsgSysOp) THEN + Onek(Cmd1,'QADEFOPRSTV?'^M,TRUE,TRUE) + ELSE + Onek(Cmd1,'QDEFOST?'^M,TRUE,TRUE); + CASE Cmd1 OF + (* + 'D' : FOR Counter := 1 TO 6 DO + IF (HeaderLine(MHeader,Msg_On,HiMsg,Counter,Junk) <> '') THEN + PrintACR(Headerline(MHeader,Msg_On,HiMsg,Counter,Junk)); + 'O' : IF PYNQ('Reload old information? ',0,FALSE) THEN + LoadHeader(Msg_On,MHeader); + 'E' : BEGIN + EditMessageText(Msg_On); + LoadHeader(Msg_On,MHeader); + END; + 'S' : IF (MHeader.FileAttached = 0) OR (MsgSysOp) THEN + BEGIN + Prt('Subj: '); + InputDefault(MHeader.Subject,MHeader.Subject,40,[ColorsAllowed],FALSE) + END + ELSE + Print('Sorry, you can''t edit that.'); + 'T' : BEGIN + Print('^11. Posted to : ^5'+MHeader.MTo.A1S); + Print('^12. Real name : ^5'+MHeader.MTo.Real); + Print('^13. System name: ^5'+MHeader.MTo.Name); + NL; + Prt('Edit name (^51^4-^53^4) [^5Q^4]uit: '); + Onek(Cmd1,'Q123'^M,TRUE,TRUE); + IF (NOT (Cmd1 IN ['Q',^M])) THEN + NL; + CASE Cmd1 OF + '1' : BEGIN + Prt('Posted to: '); + InputDefault(MHeader.MTo.A1S,MHeader.MTo.A1S,36,[],FALSE); + END; + '2' : BEGIN + Prt('Real name: '); + InputDefault(MHeader.MTo.Real,MHeader.MTo.Real,36,[],FALSE); + END; + '3' : BEGIN + Prt('System name: '); + InputDefault(MHeader.MTo.Name,MHeader.MTo.Name,36,[],FALSE); + END; + END; + Cmd1 := #0; + END; + 'F' : IF (MHeader.From.Anon > 0) OR (MsgSysOp) THEN + BEGIN + Print('^11. Posted to : ^5'+MHeader.From.A1S); + Print('^12. Real name : ^5'+MHeader.From.Real); + Print('^13. System name: ^5'+MHeader.From.Name); + NL; + Prt('Edit name (^51^4-^53^4) [^5Q^4]uit: '); + Onek(Cmd1,'Q123'^M,TRUE,TRUE); + IF (NOT (Cmd1 IN ['Q',^M])) THEN + NL; + CASE Cmd1 OF + '1' : BEGIN + Prt('Posted to: '); + InputDefault(MHeader.From.A1S,MHeader.From.A1S,36,[],FALSE); + END; + '2' : BEGIN + Prt('Real name: '); + InputDefault(MHeader.From.Real,MHeader.From.Real,36,[],FALSE); + END; + '3' : BEGIN + Prt('System name: '); + InputDefault(MHeader.From.Name,MHeader.From.Name,36,[],FALSE); + END; + END; + Cmd1 := #0; + END + ELSE + Print('Sorry, you can''t edit that.'); + + 'A' : IF (MsgSysOp) THEN + BEGIN + IF (MHeader.From.Anon IN [1,2]) THEN + MHeader.From.Anon := 0 + ELSE + BEGIN + Loadurec(User,MHeader.From.UserNum); + IF AACS1(User,MHeader.From.UserNum,General.CSOP) THEN + MHeader.From.Anon := 2 + ELSE + MHeader.From.Anon := 1; + END; + Print('Message is '+AOnOff((MHeader.From.Anon = 0),'not ','')+'anonymous'); + SysOpLog('Message is '+AOnOff((MHeader.From.Anon = 0),'not ','')+'anonymous'); + END; + *) + 'A' : IF (NOT MsgSysOp) THEN + BEGIN + NL; + Print('^7You do not have the required access level for this option!^1') + END + ELSE + BEGIN + IF (MHeader.From.Anon IN [1,2]) THEN + BEGIN + MHeader.From.Anon := 0; + NL; + Print('Message status is not anonymous.'); + SysOpLog('Message status is not anonymous.'); + END + ELSE + BEGIN + LoadURec(User,MHeader.From.UserNum); + IF AACS1(User,MHeader.From.UserNum,General.CSOP) THEN + MHeader.From.Anon := 2 + ELSE + MHeader.From.Anon := 1; + NL; + Print('Message status is anonymous.'); + SysOpLog('Message status is anonymous.'); + END; + END; + + 'D' : BEGIN + NL; + FOR Counter := 1 TO 6 DO + IF (HeaderLine(MHeader,Msg_On,HiMsg,Counter,Junk) <> '') THEN + PrintACR(Headerline(MHeader,Msg_On,HiMsg,Counter,Junk)); + END; + + 'E' : BEGIN + EditMessageText(Msg_On); + LoadHeader(Msg_On,MHeader); + END; + + 'F' : IF (MHeader.From.Anon > 0) OR (MsgSysOp) THEN + BEGIN + NL; + Print('^11. Posted from: ^5'+MHeader.From.A1S); + Print('^12. Real name : ^5'+MHeader.From.Real); + Print('^13. System name: ^5'+MHeader.From.Name); + NL; + Prt('Edit name [^51^4-^53^4,^5^4=^5Quit^4]: '); + Onek(Cmd1,^M'123',TRUE,TRUE); + CASE Cmd1 OF + '1' : BEGIN + NL; + Prt('Posted from: '); + InputDefault(MHeader.From.A1S,MHeader.From.A1S,36,[],FALSE); + END; + '2' : BEGIN + NL; + Prt('Real name: '); + InputDefault(MHeader.From.Real,MHeader.From.Real,36,[],FALSE); + END; + '3' : BEGIN + NL; + Prt('System name: '); + InputDefault(MHeader.From.Name,MHeader.From.Name,36,[],FALSE); + END; + END; + Cmd1 := #0; + END; + + 'O' : BEGIN + NL; + IF PYNQ('Reload old information? ',0,FALSE) THEN + LoadHeader(Msg_On,MHeader); + END; + 'P' : IF (NOT Pub) THEN + BEGIN + NL; + Print('^7This option is not available when reading private messages!^1'); + END + ELSE IF (NOT MsgSysOp) THEN + BEGIN + NL; + Print('^7You do not have the required access level for this option!^1') + END + ELSE + BEGIN + IF (Permanent IN MHeader.Status) THEN + BEGIN + Exclude(MHeader.Status,Permanent); + NL; + Print('Message status is not permanent.'); + SysOpLog('Message status is not permanent.'); + END + ELSE + BEGIN + Include(MHeader.Status,Permanent); + NL; + Print('Message status is permanent.'); + SysOpLog('Message status is permanent.'); + END; + END; + + + 'R' : IF (NOT MsgSysOp) THEN + BEGIN + NL; + Print('^7You do not have the required access level for this option!^1') + END + ELSE + BEGIN + IF (Sent IN MHeader.Status) THEN + BEGIN + Exclude(MHeader.Status,Sent); + IF (PUB) AND (MemMsgArea.MAType IN [1..2]) AND (NOT (MAScanOut IN MemMsgArea.MAFlags)) THEN + UpdateBoard; + NL; + Print('Message status is not sent.'); + SysOpLog('Message status is not sent.'); + END + ELSE + BEGIN + Include(MHeader.Status,Sent); + NL; + Print('Message status is sent.'); + SysOpLog('Message status is sent.'); + END; + END; + + 'S' : IF (NOT MsgSysOp) THEN + BEGIN + NL; + Print('^7You do not have the required access level for this option!^1') + END + ELSE IF (MHeader.FileAttached > 0) THEN + BEGIN + NL; + Print('^7There is no file attached to this message!^1'); + END + ELSE + BEGIN + NL; + Prt('Subj: '); + InputDefault(MHeader.Subject,MHeader.Subject,40,[ColorsAllowed],FALSE); + SysOpLog('Message subject has been modified.'); + END; + + 'T' : BEGIN + NL; + Print('^11. Posted to : ^5'+MHeader.MTo.A1S); + Print('^12. Real name : ^5'+MHeader.MTo.Real); + Print('^13. System name: ^5'+MHeader.MTo.Name); + NL; + Prt('Edit name [^51^4-^53^4,^5^4=^5Quit^4]: '); + Onek(Cmd1,^M'123',TRUE,TRUE); + CASE Cmd1 OF + '1' : BEGIN + NL; + Prt('Posted to: '); + InputDefault(MHeader.MTo.A1S,MHeader.MTo.A1S,36,[],FALSE); + END; + '2' : BEGIN + NL; + Prt('Real name: '); + InputDefault(MHeader.MTo.Real,MHeader.MTo.Real,36,[],FALSE); + END; + '3' : BEGIN + NL; + Prt('System name: '); + InputDefault(MHeader.MTo.Name,MHeader.MTo.Name,36,[],FALSE); + END; + END; + Cmd1 := #0; + END; + + 'V' : IF (NOT Pub) THEN + BEGIN + NL; + Print('^7This option is not available when reading private messages!^1'); + END + ELSE IF (NOT MsgSysOp) THEN + BEGIN + NL; + Print('^7You do not have the required access level for this option!^1') + END + ELSE + BEGIN + IF (UnValidated IN MHeader.Status) THEN + BEGIN + Exclude(MHeader.Status,UnValidated); + NL; + Print('Message status is validated.'); + SysOpLog('Message status is validated.'); + END + ELSE + BEGIN + Include(MHeader.Status,UnValidated); + NL; + Print('Message status is unvalidated.'); + SysOpLog('Message status is unvalidated.'); + END; + END; + + '?' : BEGIN + NL; + LCmds(15,3,'From','To'); + LCmds(15,3,'Subject','Edit text'); + LCmds(15,3,'Oops','Display header'); + IF (MsgSysOp) THEN + BEGIN + LCmds(15,5,'Permanent','Validation'); + LCmds(15,5,'Rescan','Anonymous'); + END; + LCmds(15,3,'Quit',''); + END; + END; + UNTIL (Cmd1 IN ['Q',^M]) OR (HangUp); + Cmd1 := #0; + SaveHeader(Msg_On,MHeader); + END; + 6 : BEGIN + DumpQuote(MHeader); + IF (NOT Pub) THEN + AutoReply(MHeader) + ELSE + BEGIN + NL; + IF (MHeader.From.Anon = 0) OR (AACS(General.AnonPubRead)) THEN + IF PYNQ('Is this to be a private reply? ',0,Prvt IN MHeader.Status) THEN + IF (MAPrivate IN MemMsgArea.MAFlags) THEN + IF PYNQ('Reply in Email? ',0,FALSE) THEN + AutoReply(MHeader) + ELSE + Post(Msg_On,MHeader.From,TRUE) + ELSE + AutoReply(MHeader) + ELSE + Post(Msg_On,MHeader.From,FALSE) + ELSE + Post(Msg_On,MHeader.From,FALSE); + END; + END; + 7 : BEGIN + Msg_On := (HiMsg + 1); + IF (Pub) THEN + BEGIN + LoadHeader(HiMsg,MHeader); + IF (MHeader.Date <= GetPackDateTime) THEN + TempLastRead := MHeader.Date; + END; + Next := FALSE; + END; + + 8 : IF (Pub) AND ((Msg_On - MHeader.ReplyTo) > 0) AND (MHeader.ReplyTo > 0) THEN + BEGIN + IF (ThreadStart = 0) THEN + ThreadStart := Msg_On; + Dec(Msg_On,MHeader.ReplyTo); + END; + + 9 : IF (Pub) AND ((ThreadStart >= 1) AND (ThreadStart <= HiMsg)) THEN + BEGIN + Msg_On := ThreadStart; + ThreadStart := 0; + END; + + 10 : BEGIN + Contlist := TRUE; + Abort := FALSE; + NL; + Print('Continuous message listing on.'); + END; + 11 : IF (Pub) THEN + BEGIN + IF (Permanent IN MHeader.Status) THEN + BEGIN + NL; + Print('^7This is a permanent public message!^1'); + END + ELSE + BEGIN + IF (Msg_On >= 1) AND (Msg_On <= HiMsg) AND (MsgSysOp OR FromYou(MHeader)) THEN + BEGIN + LoadHeader(Msg_On,MHeader); + IF (MDeleted IN MHeader.Status) THEN + Exclude(MHeader.Status,MDeleted) + ELSE + Include(MHeader.Status,MDeleted); + SaveHeader(Msg_On,MHeader); + IF (NOT (MDeleted IN MHeader.Status)) THEN + BEGIN + IF FromYou(MHeader) THEN + BEGIN + IF (ThisUser.MsgPost < 2147483647) THEN + Inc(ThisUser.MsgPost); + AdjustBalance(General.Creditpost); + END; + NL; + Print('Public message undeleted.'); + SysOpLog('* Undeleted public message: ^5'+MHeader.Subject); + END + ELSE + BEGIN + IF FromYou(MHeader) THEN + BEGIN + IF (ThisUser.MsgPost > 0) THEN + Dec(ThisUser.MsgPost); + AdjustBalance(-General.Creditpost); + END; + NL; + Print('Public message deleted.'); + SysOpLog('* Deleted public message: ^5'+MHeader.Subject); + END; + END + ELSE + BEGIN + NL; + Print('^7You can only delete public messages from you!^1'); + END; + END; + END + ELSE + BEGIN + IF (Msg_On >= 1) AND (Msg_On <= HiMsg) AND (MsgSysOp OR FromYou(MHeader) OR ToYou(MHeader)) THEN + BEGIN + LoadHeader(Msg_On,MHeader); + IF (MDeleted IN MHeader.Status) THEN + Exclude(MHeader.Status,MDeleted) + ELSE + Include(MHeader.Status,MDeleted); + SaveHeader(Msg_On,MHeader); + IF (NOT (MDeleted IN MHeader.Status)) THEN + BEGIN + LoadURec(User,MHeader.MTo.UserNum); + IF (User.Waiting < 255) THEN + Inc(User.Waiting); + SaveURec(User,MHeader.MTo.UserNum); + NL; + Print('Private message undeleted.'); + IF FromYou(MHeader) OR (MsgSysOp) THEN + SysOpLog('* Undeleted private message from: ^5'+Caps(MHeader.From.A1S)) + ELSE IF ToYou(MHeader) OR (MsgSysOp) THEN + SysOpLog('* Undeleted private message to: ^5'+Caps(MHeader.MTo.A1S)); + END + ELSE + BEGIN + LoadURec(User,MHeader.MTo.UserNum); + IF (User.Waiting > 0) THEN + Dec(User.Waiting); + SaveURec(User,MHeader.MTo.UserNum); + NL; + Print('Private message deleted.'); + IF FromYou(MHeader) OR (MsgSysOp) THEN + SysOpLog('* Deleted private message from: ^5'+Caps(MHeader.From.A1S)) + ELSE IF ToYou(MHeader) OR (MsgSysOp) THEN + SysOpLog('* Deleted private message to: ^5'+Caps(MHeader.MTo.A1S)); + END; + END + ELSE + BEGIN + NL; + Print('^7You can only delete private messages from or to you!^1'); + END; + END; + 12 : IF (NOT Pub) THEN + BEGIN + NL; + Print('^7This option is not available when reading private messages!^1'); + END + ELSE + BEGIN + NL; + Print('Highest-read pointer for this area set to message #'+IntToStr(Msg_On)+'.'); + IF (MHeader.Date <= GetPackDateTime) THEN + TempLastRead := MHeader.Date; + END; + 13 : BEGIN + IF (Pub) AND (AskUpdate) THEN + BEGIN + NL; + IF PYNQ('Update message read pointers for this area? ',0,FALSE) THEN + BEGIN + LoadLastReadRecord(LastReadRecord); + LastReadRecord.LastRead := GetPackDateTime; + SaveLastReadRecord(LastReadRecord); + END; + END; + DoneScan := TRUE; + Next := TRUE; + END; + 14 : BEGIN + DoneScan := TRUE; + Abort := TRUE; + END; + 15 : ListMessages(Pub); + 16 : IF (NOT CoSysOp) THEN + Print('^7You do not have the required access level for this option!^1') + ELSE IF (LastAuthor < 1) OR (LastAuthor > (MaxUsers - 1)) THEN + Print('^7The sender of this message does not have an account on this BBS!^1') + ELSE IF (CheckPW) THEN + UserEditor(LastAuthor); + 17 : IF (NOT PUB) THEN + BEGIN + NL; + Print('^7This option is not available when reading private messages!^1'); + END + ELSE + BEGIN + IF (MAForceRead IN MemMsgArea.MAFlags) THEN + BEGIN + NL; + Print('^7This message area can not be removed from your new scan!^1') + END + ELSE + BEGIN + + NL; + Print('^5'+MemMsgArea.Name+'^3 '+AOnOff(LastReadRecord.NewScan,'will NOT','WILL')+ + ' be scanned in future new scans.'); + SysOpLog('* Toggled ^5'+MemMsgArea.Name+ '^1 '+AOnOff(LastReadRecord.NewScan,'out of','back in')+ + ' new scan.'); + + LoadLastReadRecord(LastReadRecord); + LastReadRecord.NewScan := (NOT LastReadRecord.NewScan); + SaveLastReadRecord(LastReadRecord); + END; + END; + 18 : Inc(Msg_On); + 19 : IF (NOT CoSysOp) THEN + Print('^7You do not have the required access level for this option!^1') + ELSE IF (LastAuthor < 1) OR (LastAuthor > (MaxUsers - 1)) THEN + Print('^7The sender of this message does not have an account on this BBS!^1.') + ELSE + BEGIN + LoadURec(User,LastAuthor); + ShowUserInfo(1,LastAuthor,User); + END; + 20 : IF (NOT CoSysOp) THEN + Print('^7You do not have the required access level for this option!^1') + ELSE IF (LastAuthor < 1) OR (LastAuthor > (MaxUsers - 1)) THEN + Print('^7The sender of this message does not have an account on this BBS!^1') + ELSE + BEGIN + LoadURec(User,LastAuthor); + AutoVal(User,LastAuthor); + END; + 21 : ForwardMessage(Msg_On); + END; + UNTIL (TReadPrompt IN [1..2,7..10,13..15,18]) OR (Abort) OR (Next) OR (HangUp) + ELSE + Inc(Msg_On); + + IF (OncOnly) AND (TReadPrompt IN [13,14,18]) THEN + DoneScan := TRUE; + + UNTIL (DoneScan) OR (HangUp); + + CurMenu := SaveMenu; + + NewMenuToLoad := TRUE; + + AllowContinue := FALSE; + + IF ((Pub) AND (HadUnVal) AND (MsgSysOp)) THEN + IF PYNQ('%LFValidate all messages here? ',0,FALSE) THEN + BEGIN + FOR MsgNum := 1 TO HiMsg DO + BEGIN + LoadHeader(MsgNum,MHeader); + IF (UnValidated IN MHeader.Status) THEN + Exclude(MHeader.Status,UnValidated); + SaveHeader(MsgNum,MHeader); + END; + END; + + IF ((Pub) AND (AskPost) AND (AACS(MemMsgArea.PostACS)) AND + (NOT (RPost IN ThisUser.Flags)) AND (PublicPostsToday < General.MaxPubPost)) THEN + IF (TReadPrompt <> 7) THEN + IF PYNQ('%LFPost on ^5'+MemMsgArea.Name+'^7? ',0,FALSE) THEN + IF (MAPrivate IN MemMsgArea.MAFlags) THEN + Post(-1,MHeader.From,PYNQ('%LFIs this to be a private message? ',0,FALSE)) + ELSE + Post(-1,MHeader.From,FALSE); +END; + +PROCEDURE ReadAllMessages(MenuOption: Str50); +VAR + InputStr: AStr; + SaveReadMsgArea: Integer; +BEGIN + SaveReadMsgArea := ReadMsgArea; + Abort := FALSE; + Next := FALSE; + IF (MenuOption = '') THEN + MsgArea := -1; + InitMsgArea(MsgArea); + IF (HiMsg = 0) THEN + BEGIN + Print('%LFNo messages on ^5'+MemMsgArea.Name+'^1.'); + IF (Novice IN ThisUser.Flags) THEN + PauseScr(FALSE); + END + ELSE + BEGIN + + Msg_On := 1; + Inputstr := '?'; + REPEAT + IF (InputStr = '?') THEN + ListMessages(MsgArea <> -1); + NL; + { Prompt(FString.ReadQ); } + Prt('Select message (^51^4-^5'+IntToStr(HiMsg)+'^4) [^5?^4=^5First^4,^5^4=^5Next^4,^5Q^4=^5Quit^4)]: '); + (* + lRGLngStr(32,FALSE); + *) + ScanInput(InputStr,'Q?'^M); + + IF (InputStr = 'Q') THEN + Msg_On := 0 + ELSE + BEGIN + + IF (InputStr = ^M) THEN + BEGIN + InputStr := '?'; + IF (Msg_On >= HiMsg) THEN + Msg_On := 1; + END + ELSE IF (InputStr = '?') THEN + BEGIN + Msg_On := 1; + InputStr := '?'; + END + ELSE + BEGIN + Msg_On := StrToInt(InputStr); + IF (Msg_On >= 1) AND (Msg_On <= HIMsg) THEN + InputStr := 'Q' + ELSE + BEGIN + NL; + Print('^7The range must be from 1 to '+IntToStr(HiMsg)+'^1'); + PauseScr(FALSE); + Msg_On := 1; + InputStr := '?'; + END; + END; + END; + UNTIL (InputStr = 'Q') OR (HangUp); + + IF (Msg_On >= 1) AND (Msg_On <= HiMsg) AND (NOT HangUp) THEN + BEGIN + IF (MsgArea <> -1) THEN + BEGIN + LoadLastReadRecord(LastReadRecord); + TempLastRead := LastReadRecord.LastRead; + END; + MainRead(FALSE,FALSE,(MsgArea <> -1)); + IF (MsgArea <> -1) THEN + BEGIN + LastReadRecord.LastRead := TempLastRead; + SaveLastReadRecord(LastReadRecord); + END; + END; + + END; + MsgArea := SaveReadMsgArea; + LoadMsgArea(MsgArea); +END; + +FUNCTION FirstNew: Word; +VAR + MHeader: MHeaderRec; + MaxMsgs, + MsgNum: Word; + Done: Boolean; +BEGIN + MaxMsgs := HiMsg; + MsgNum := 0; + IF (MaxMsgs > 0) THEN + BEGIN + Done := FALSE; + MsgNum := 1; + WHILE (MsgNum <= MaxMsgs) AND (NOT Done) DO + BEGIN + LoadHeader(MsgNum,MHeader); + IF (LastReadRecord.LastRead < MHeader.Date) THEN + Done := TRUE + ELSE + BEGIN + IF (MsgNum < MaxMsgs) THEN + Inc(MsgNum,1) + ELSE + BEGIN + MsgNum := 0; + Done := TRUE; + END; + END; + END; + END; + FirstNew := MsgNum; +END; + +PROCEDURE ScanMessages(MArea: Integer; AskUpdate: Boolean; MenuOption: Str50); +VAR + ScanFor: STRING[40]; + Cmd: Char; + SaveMsgArea, + MsgNum: Word; + ScanNew, + ScanGlobal: Boolean; + + PROCEDURE Searchboard(MArea1: Integer; Cmd1: Char); + VAR + MsgHeader: MHeaderRec; + Searched: STRING; + TotLoad: Word; + Match, + AnyShown: Boolean; + BEGIN + IF (MsgArea <> MArea1) THEN + ChangeMsgArea(MArea1); + IF (MsgArea = MArea1) THEN + BEGIN + InitMsgArea(MsgArea); + AnyShown := FALSE; + LIL := 0; + CLS; + Prompt('^1Scanning ^5'+MemMsgArea.Name+' #'+IntToStr(CompMsgArea(MsgArea,0))+' ^1...'); + Reset(MsgHdrF); + Reset(MsgTxtF,1); + IF (IOResult <> 0) THEN + Exit; + IF (ScanNew) THEN + MsgNum := FirstNew + ELSE + MsgNum := 1; + IF (MsgNum > 0) AND (FileSize(MsgHdrF) > 0) THEN + WHILE (MsgNum <= FileSize(MsgHdrF)) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + LoadHeader(MsgNum,MsgHeader); + Match := FALSE; + IF (Cmd1 IN ['Y',^M]) THEN + IF ToYou(MsgHeader) THEN + Match := TRUE; + IF (Cmd1 IN ['F','A']) THEN + BEGIN + IF (MARealName IN MemMsgArea.MAFlags) THEN + Searched := MsgHeader.From.Real + ELSE + Searched := MsgHeader.From.A1S; + IF (MemMsgArea.MAtype = 0) THEN + Searched := Searched; + Searched := AllCaps(UseName(MsgHeader.From.Anon,Searched)); + IF (Pos(ScanFor,Searched) > 0) THEN + Match := TRUE; + END; + IF (Cmd1 IN ['T','A'] ) THEN + BEGIN + IF (MARealName IN MemMsgArea.MAFlags) THEN + Searched := MsgHeader.MTo.Real + ELSE + Searched := MsgHeader.MTo.A1S; + IF (MemMsgArea.MAtype = 0) THEN + Searched := Searched; + Searched := AllCaps(UseName(MsgHeader.MTo.Anon,Searched)); + IF (Pos(ScanFor,Searched) > 0) THEN + Match := TRUE; + END; + IF (Cmd1 IN ['S','A'] ) THEN + IF (Pos(ScanFor,AllCaps(MsgHeader.Subject)) > 0) THEN + Match := TRUE; + IF (Cmd1 = 'A') AND (NOT Match) AND (MsgHeader.TextSize > 0) AND + (((MsgHeader.Pointer - 1) + MsgHeader.TextSize) <= FileSize(MsgTxtF)) AND + (MsgHeader.Pointer > 0) THEN + WITH MsgHeader DO + BEGIN + Seek(MsgTxtF,(Pointer - 1)); + TotLoad := 0; + REPEAT + BlockRead(MsgTxtF,Searched[0],1); + BlockRead(MsgTxtF,Searched[1],Ord(Searched[0])); + LastError := IOResult; + Inc(TotLoad,Length(Searched) + 1); + IF (Pos(ScanFor,AllCaps(Searched)) > 0) THEN + Match := TRUE; + UNTIL (TotLoad >= TextSize) OR (Match); + END; + IF (Match) THEN + BEGIN + Close(MsgHdrF); + Close(MsgTxtF); + Msg_On := MsgNum; + NL; + MainRead(TRUE,AskUpdate,(MsgArea <> -1)); + NL; + Reset(MsgHdrF); + Reset(MsgTxtF,1); + AnyShown := TRUE; + END; + Wkey; + IF (Next) THEN + Abort := TRUE; + Inc(MsgNum); + END; + Close(MsgHdrF); + Close(MsgTxtF); + IF (NOT AnyShown) THEN + BackErase(14 + Lennmci(MemMsgArea.Name) + Length(IntToStr(CompMsgArea(MsgArea,0)))); + END; + END; + +BEGIN + SaveMsgArea := MsgArea; + ScanNew := FALSE; + ScanGlobal := FALSE; + MenuOption := AllCaps(MenuOption); + IF (MenuOption <> '') THEN + Cmd := 'Y' + ELSE + Cmd := #0; + IF (Pos('N',MenuOption) > 0) THEN + ScanNew := TRUE; + IF (Pos('G',MenuOption) > 0) THEN + ScanGlobal := TRUE; + IF (Cmd = #0) THEN + REPEAT + NL; + Prt('Scan method (^5?^4=^5Help^4): '); + Onek(Cmd,'QFTSAY?'^M,TRUE,TRUE); + IF (Cmd = '?') THEN + BEGIN + NL; + LCmds(15,5,'From field','To field'); + LCmds(15,5,'Subject field','All text'); + LCmds(15,5,'Your messages','Quit'); + END; + UNTIL (Cmd <> '?') OR (HangUp); + NL; + IF (NOT (Cmd IN ['Q',^M])) THEN + BEGIN + IF (Cmd <> 'Y') THEN + BEGIN + Prt('Text to scan for: '); + Input(ScanFor,40); + IF (ScanFor = '') THEN + Exit; + NL; + END; + IF (MenuOption = '') THEN + ScanNew := PYNQ('Scan new messages only? ',0,TRUE); + IF (ScanGlobal) OR ((MenuOption = '') AND PYNQ('Global scan? ',0,FALSE)) THEN + BEGIN + MArea := 1; + WHILE (MArea >= 1) AND (MArea <= NumMsgAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Searchboard(MArea,Cmd); + Wkey; + Inc(MArea); + END; + END + ELSE + Searchboard(MArea,Cmd); + END; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); +END; + +PROCEDURE ScanYours; +VAR + ScanAllPublicMsgFile: FILE OF Boolean; + MsgHeader: MHeaderRec; + MArea, + SaveMsgArea: Integer; + MsgNum, + PubMsgsFound: Word; + SaveConfSystem, + AnyFound, + FirstTime, + MsgsFound: Boolean; +BEGIN + SaveMsgArea := MsgArea; + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + Assign(ScanAllPublicMsgFile,TempDir+'SAPM'+IntToStr(ThisNode)+'.DAT'); + ReWrite(ScanAllPublicMsgFile); + FOR MArea := 1 TO NumMsgAreas DO + BEGIN + MsgsFound := FALSE; + Write(ScanAllPublicMsgFile,MsgsFound); + END; + Prompt('%LF^5Scanning for your new public messages ... ^1'); + FirstTime := TRUE; + AnyFound := FALSE; + MArea := 1; + WHILE (MArea >= 1) AND (MArea <= NumMsgAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (MsgArea <> MArea) THEN + ChangeMsgArea(MArea); + IF (MsgArea = MArea) THEN + BEGIN + InitMsgArea(MsgArea); + IF (LastReadRecord.NewScan) THEN + BEGIN + Reset(MsgHdrF); + Reset(MsgTxtF,1); + IF (IOResult = 0) THEN + BEGIN + PubMsgsFound := 0; + MsgNum := FirstNew; + IF (MsgNum > 0) AND (FileSize(MsgHdrF) > 0) THEN + WHILE (MsgNum <= FileSize(MsgHdrF)) AND (NOT HangUp) DO + BEGIN + LoadHeader(MsgNum,MsgHeader); + IF (ToYou(MsgHeader)) THEN + BEGIN + Seek(ScanAllPublicMsgFile,(MArea - 1)); + MsgsFound := TRUE; + Write(ScanAllPublicMsgFile,MsgsFound); + Inc(PubMsgsFound); + END; + Inc(MsgNum); + END; + Close(MsgHdrF); + Close(MsgTxtF); + IF (PubMsgsFound > 0) THEN + BEGIN + IF (FirstTime) THEN + BEGIN + NL; + NL; + FirstTime := FALSE; + END; + Print('^5'+PadLeftStr(MemMsgArea.Name,30)+' ^1'+IntToStr(PubMsgsFound)); + AnyFound := TRUE; + END; + END; + END; + END; + Inc(MArea); + END; + Close(ScanAllPublicMsgFile); + IF (NOT AnyFound) THEN + Print('^5No messages found.^1') + ELSE + BEGIN + Abort := FALSE; + Next := FALSE; + NL; + IF PYNQ('Read your new public messages now? ',0,FALSE) THEN + BEGIN + Assign(ScanAllPublicMsgFile,TempDir+'SAPM'+IntToStr(ThisNode)+'.DAT'); + Reset(ScanAllPublicMsgFile); + MArea := 1; + WHILE (MArea >= 1) AND (MArea <= NumMsgAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(ScanAllPublicMsgFile,(MArea - 1)); + Read(ScanAllPublicMsgFile,MsgsFound); + IF (MsgsFound) THEN + ScanMessages(MArea,TRUE,'N'); + WKey; + Inc(MArea); + END; + Close(ScanAllPublicMsgFile); + END; + END; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); + LastError := IOResult; +END; + +PROCEDURE StartNewScan(MenuOption: Str50); +VAR + MArea, + SaveMsgArea: Integer; + Global: Boolean; + + PROCEDURE NewScan(MArea1: Integer); + BEGIN + IF (MsgArea <> MArea1) THEN + ChangeMsgArea(MArea1); + IF (MsgArea = MArea1) THEN + BEGIN + InitMsgArea(MsgArea); + IF (LastReadRecord.NewScan) OR ((MAForceRead IN MemMsgArea.MAFlags) AND (NOT CoSysOp)) THEN + BEGIN + TempLastRead := LastReadRecord.LastRead; + Lil := 0; + { Prompt('^3'+FString.NewScan1);} + lRGLngStr(8,FALSE); + Msg_On := FirstNew; + IF (Msg_On > 0) THEN + MainRead(FALSE,FALSE,(MsgArea <> -1)); + + LastReadRecord.LastRead := TempLastRead; + SaveLastReadRecord(LastReadRecord); + + (* Add backarase *) + END; + END; + END; + +BEGIN + SaveMsgArea := MsgArea; + MArea := MsgArea; + Global := FALSE; + Abort := FALSE; + Next := FALSE; + IF (UpCase(MenuOption[1]) = 'C') THEN + MArea := MsgArea + ELSE IF (UpCase(MenuOption[1]) = 'G') THEN + Global := TRUE + ELSE IF (StrToInt(MenuOption) <> 0) THEN + MArea := StrToInt(MenuOption) + ELSE IF (MenuOption = '') THEN + Global := PYNQ('%LFScan all message areas? ',0,FALSE); + IF (NOT Global) THEN + NewScan(MArea) + ELSE + BEGIN + MArea := 1; + WHILE (MArea >= 1) AND (MArea <= NumMsgAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + NewScan(MArea); + WKey; + Inc(MArea); + END; + SysOpLog('Global new scan of message areas'); + END; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); +END; + +END. diff --git a/SOURCE/MAIL3.PAS b/SOURCE/MAIL3.PAS new file mode 100644 index 0000000..299c1bc --- /dev/null +++ b/SOURCE/MAIL3.PAS @@ -0,0 +1,477 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Mail3; + +INTERFACE + +PROCEDURE EditMessageText(MsgNum: Word); +PROCEDURE ForwardMessage(MsgNum: Word); +PROCEDURE MoveMsg(MsgNum: Word); + +IMPLEMENTATION + +USES + Dos, + Common, + Common5, + Mail0, + Mail1, + Mail4, + MsgPack, + MiscUser, + TimeFunc; + +PROCEDURE EditMessageText(MsgNum: Word); +VAR + TempQuoteFile: Text; + MHeader: MHeaderRec; + MsgTempStr: STRING; + SaveFileAttached: Byte; + TempTextSize: Word; + FileDateTime1, + FileDateTime2: LongInt; +BEGIN + SysOpLog('Edited message #'+IntToStr(MsgNum)+' on '+MemMsgArea.Name); + Assign(TempQuoteFile,'TEMPQ'+IntToStr(ThisNode)+'.MSG'); + ReWrite(TempQuoteFile); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error creating TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + SysOpLog('Error creating TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + Exit; + END; + LoadHeader(MsgNum,MHeader); + Reset(MsgTxtF,1); + Seek(MsgTxtF,(MHeader.Pointer - 1)); + TempTextSize := 0; + REPEAT + BlockRead(MsgTxtF,MsgTempStr[0],1); + BlockRead(MsgTxtF,MsgTempStr[1],Ord(MsgTempStr[0])); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error reading from '+MemMsgArea.FileName+'.DAT file.'); + SysOpLog('Error reading from '+MemMsgArea.FileName+'.DAT file.'); + TempTextSize := MHeader.TextSize; + END; + Inc(TempTextSize,(Length(MsgTempStr) + 1)); + WriteLn(TempQuoteFile,MsgTempStr); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error writting to TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + SysOpLog('Error writting to TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + TempTextSize := MHeader.TextSize; + END; + UNTIL (TempTextSize >= MHeader.TextSize); + Close(MsgTxtF); + Close(TempQuoteFile); + GetFileDateTime('TEMPQ'+IntToStr(ThisNode)+'.MSG',FileDateTime1); + SaveFileAttached := MHeader.FileAttached; + IF NOT (InputMessage((ReadMsgArea <> -1),FALSE,'',MHeader,'TEMPQ'+IntToStr(ThisNode)+'.MSG',78,500)) THEN + BEGIN + Kill('TEMPQ'+IntToStr(ThisNode)+'.MSG'); + Exit; + END; + MHeader.FileAttached := SaveFileAttached; + GetFileDateTime('TEMPQ'+IntToStr(ThisNode)+'.MSG',FileDateTime2); + IF (FileDateTime1 <> FileDateTime2) THEN + BEGIN + Assign(TempQuoteFile,'TEMPQ'+IntToStr(ThisNode)+'.MSG'); + Reset(TempQuoteFile); + MHeader.TextSize := 0; + Reset(MsgTxtF,1); + MHeader.Pointer := (FileSize(MsgTxtF) + 1); + Seek(MsgTxtF,(MHeader.Pointer - 1)); + REPEAT + ReadLn(TempQuoteFile,MsgTempStr); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error reading from TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + SysOpLog('Error reading from TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + END; + Inc(MHeader.TextSize,(Length(MsgTempStr) + 1)); + BlockWrite(MsgTxtF,MsgTempStr,(Length(MsgTempStr) + 1)); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error writting to '+MemMsgArea.FileName+'.DAT file.'); + SysOpLog('Error writting to '+MemMsgArea.FileName+'.DAT file.'); + END; + UNTIL (EOF(TempQuoteFile)); + Close(MsgTxtF); + Close(TempQuoteFile); + SaveHeader(MsgNum,MHeader); + LastError := IOResult; + END; + Kill('TEMPQ'+IntToStr(ThisNode)+'.MSG'); +END; + +PROCEDURE ForwardMessage(MsgNum: Word); +VAR + MsgHdrF1: FILE OF MHeaderRec; + MsgTxtF1: FILE; + User: UserRecordType; + MHeader: MHeaderRec; + MsgTempStr: STRING; + SaveReadMsgArea, + Unum: Integer; + TempTextSize: Word; + TempPtr, + TempPtr1: LongInt; + ForwardOk, + SaveConfSystem: Boolean; +BEGIN + SaveReadMsgArea := ReadMsgArea; + + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + + NL; + Print('^5Forward message to which user (1-'+(IntToStr(MaxUsers - 1))+')?^1'); + NL; + Print('Enter User Number, Name, or Partial Search String.'); + Prt(': '); + lFindUserWS(UNum); + IF (UNum < 1) THEN + PauseScr(FALSE) + ELSE + BEGIN + LoadURec(User,UNum); + + ForwardOk := TRUE; + + IF (User.Name = ThisUser.Name) THEN + BEGIN + NL; + Print('^7You can not forward messages to yourself!^1'); + ForwardOk := FALSE; + END + ELSE IF (NoMail IN User.Flags) AND (NOT CoSysOp) THEN + BEGIN + NL; + Print('^7The mailbox for this user is closed!^1'); + ForwardOk := FALSE; + END + ELSE IF (User.Waiting >= General.MaxWaiting) AND (NOT CoSysOp) THEN + BEGIN + NL; + Print('^7The mailbox for this user is full!^1'); + ForwardOk := FALSE; + END; + + IF (NOT ForwardOk) THEN + PauseScr(FALSE) + ELSE + BEGIN + + InitMsgArea(SaveReadMsgArea); + + LoadHeader(MsgNum,MHeader); + + Mheader.MTO.UserNum := UNum; + + MHeader.MTO.A1S := User.Name; + + MHeader.MTO.Name := User.Name; + + MHeader.MTO.Real := User.RealName; + + TempPtr := (MHeader.Pointer - 1); + + Reset(MsgTxtF,1); + + MHeader.Pointer := (FileSize(MsgTxtF) + 1); + + Seek(MsgTxtF,FileSize(MsgTxtF)); + + IF (SaveReadMsgArea <> -1) THEN + BEGIN + + LoadMsgArea(-1); + + Assign(MsgHdrF1,General.MsgPath+MemMsgArea.FIleName+'.HDR'); + Reset(MsgHdrF1); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF1); + + Assign(MsgTxtF1,General.MsgPath+MemMsgArea.FIleName+'.DAT'); + Reset(MsgTxtF1,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF1,1); + + TempPtr1 := (FileSize(MsgTxtF1) + 1); + + Seek(MsgTxtF1,FileSize(MsgTxtF1)); + END; + + UNum := 0; + + MsgTempStr := 'Message forwarded from '+Caps(ThisUser.Name); + Inc(UNum,(Length(MsgTempStr) + 1)); + IF (SaveReadMsgArea <> -1) THEN + BlockWrite(MsgTxtF1,MsgTempStr,(Length(MsgTempStr) + 1)) + ELSE + BlockWrite(MsgTxtF,MsgTempStr,(Length(MsgTempStr) + 1)); + + MsgTempStr := 'Message forwarded on '+DateStr+' at '+TimeStr; + Inc(UNum,(Length(MsgTempStr) + 1)); + IF (SaveReadMsgArea <> -1) THEN + BlockWrite(MsgTxtF1,MsgTempStr,(Length(MsgTempStr) + 1)) + ELSE + BlockWrite(MsgTxtF,MsgTempStr,(Length(MsgTempStr) + 1)); + + MsgTempStr := ''; + Inc(UNum,(Length(MsgTempStr) + 1)); + IF (SaveReadMsgArea <> -1) THEN + BlockWrite(MsgTxtF1,MsgTempStr,(Length(MsgTempStr) + 1)) + ELSE + BlockWrite(MsgTxtF,MsgTempStr,(Length(MsgTempStr) + 1)); + + TempTextSize := 0; + + REPEAT + Seek(MsgTxtF,(TempPtr + TempTextSize)); + + BlockRead(MsgTxtF,MsgTempStr[0],1); + + BlockRead(MsgTxtF,MsgTempStr[1],Ord(MsgTempStr[0])); + + LastError := IOResult; + + Inc(TempTextSize,(Length(MsgTempStr) + 1)); + + IF (SaveReadMsgArea <> - 1) THEN + BEGIN + Seek(MsgTxtF1,FileSize(MsgTxtF1)); + BlockWrite(MsgTxtF1,MsgTempStr,(Length(MsgTempStr) + 1)); + END + ELSE + BEGIN + Seek(MsgTxtF,FileSize(MsgTxtF)); + BlockWrite(MsgTxtF,MsgTempStr,(Length(MsgTempStr) + 1)); + END; + + UNTIL (TempTextSize >= MHeader.TextSize); + + Close(MsgTxtF); + IF (SaveReadMsgArea <> -1) THEN + BEGIN + Close(MsgTxtF1); + Close(MsgHdrF1); + END; + + Inc(MHeader.TextSize,UNum); + + IF (SaveReadMsgArea <> -1) THEN + BEGIN + InitMsgArea(-1); + MHeader.Pointer := TempPtr1; + END; + + SaveHeader((HiMsg + 1),MHeader); + + LoadURec(User,MHeader.MTO.UserNum); + Inc(User.Waiting); + SaveURec(User,MHeader.MTO.UserNum); + + NL; + Print('Message forwarded to: ^5'+Caps(User.Name)+'^1'); + PauseScr(FALSE); + + SysOpLog('Message forwarded to: ^5'+Caps(User.Name)); + + END; + + END; + + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + + InitMsgArea(SaveReadMsgArea); +END; + +PROCEDURE MoveMsg(MsgNum: Word); +VAR + MsgHdrF1: FILE OF MHeaderRec; + MsgTxtF1: FILE; + MHeader: MHeaderRec; + MsgTxtStr: STRING; + InputStr: Str5; + MArea, + NumMAreas, + SaveMArea, + NewMsgArea, + SaveReadMsgArea: Integer; + TempTextSize: Word; + SaveConfSystem: Boolean; +BEGIN + SaveReadMsgArea := ReadMsgArea; + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + MArea := 1; + NumMAreas := 0; + NewMsgArea := 0; + LightBarCmd := 1; + LightBarFirstCmd := TRUE; + InputStr := '?'; + REPEAT + SaveMArea := MArea; + IF (InputStr = '?') THEN + MessageAreaList(MArea,NumMAreas,5,FALSE); + { + %LFMove to which area? (^50^4=^5Private^4,^5'+IntToStr(LowMsgArea)+'^4-^5'+IntToStr(HighMsgArea)+'^4) + [^5#^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ + } + MsgAreaScanInput(LRGLngStr(77,TRUE),Length(IntToStr(HighMsgArea)),InputStr,'Q[]?',LowMsgArea,HighMsgArea); + IF (InputStr <> 'Q') THEN + BEGIN + IF (InputStr = '[') THEN + BEGIN + MArea := (SaveMArea - ((PageLength - 5) * 2)); + IF (MArea < 1) THEN + MArea := 1; + InputStr := '?'; + END + ELSE IF (InputStr = ']') THEN + BEGIN + IF (MArea > NumMsgAreas) THEN + MArea := SaveMArea; + InputStr := '?'; + END + ELSE IF (InputStr = '?') THEN + BEGIN + { + $File_Message_Area_List_Help + %LF^1(^3###^1)Manual entry selection ^1(^3^1)Select current entry + ^1(^3^1)First entry on page ^1(^3^1)Last entry on page + ^1(^3Left Arrow^1)Previous entry ^1(^3Right Arrow^1)Next entry + ^1(^3Up Arrow^1)Move up ^1(^3Down Arrow^1)Move down + ^1(^3[^1)Previous page ^1(^3]^1)Next page + %PA + } + LRGLngStr(71,FALSE); + MArea := SaveMArea; + END + ELSE IF (StrToInt(InputStr) < 0) OR (StrToInt(InputStr) > HighMsgArea) THEN + BEGIN + NL; + Print('^7The range must be from 0 to '+IntToStr(HighMsgArea)+'!^1'); + NL; + PauseScr(FALSE); + MArea := SaveMArea; + InputStr := '?'; + END + ELSE + BEGIN + IF (InputStr = '0') THEN + NewMsgArea := -1 + ELSE + NewMsgArea := CompMsgArea(StrToInt(InputStr),1); + IF (NewMsgArea = ReadMsgArea) THEN + BEGIN + NL; + Print('^7You can not move a message to the same area!^1'); + NL; + PauseScr(FALSE); + MArea := SaveMArea; + InputStr := '?'; + END + ELSE + BEGIN + InitMsgArea(NewMsgArea); + IF (NOT MsgAreaAC(NewMsgArea)) THEN + BEGIN + NL; + Print('^7You do not have access to this message area!^1'); + NL; + PauseScr(FALSE); + MArea := SaveMArea; + InputStr := '?'; + END + ELSE IF (NOT AACS(MemMsgArea.PostAcs)) THEN + BEGIN + NL; + Print('^7You do not have posting access to this message area!^1'); + NL; + PauseScr(FALSE); + MArea := SaveMArea; + InputStr := '?'; + END + ELSE + BEGIN + NL; + IF (NOT PYNQ('Move message to '+MemMsgArea.Name+'? ',0,FALSE)) THEN + BEGIN + MArea := SaveMArea; + InputStr := '?'; + END + ELSE + BEGIN + InitMsgArea(SaveReadMsgArea); + LoadHeader(MsgNum,MHeader); + IF (NOT (MDeleted IN MHeader.Status)) THEN + Include(MHeader.Status,MDeleted); + SaveHeader(MsgNum,MHeader); + LoadMsgArea(NewMsgArea); + Assign(MsgHdrF1,General.MsgPath+MemMsgArea.FileName+'.HDR'); + Reset(MsgHdrF1); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF1); + Seek(MsgHdrF1,FileSize(MsgHdrF1)); + Assign(MsgTxtF1,General.MsgPath+MemMsgArea.FileName+'.DAT'); + Reset(MsgTxtF1,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF1,1); + Reset(MsgTxtF,1); + Seek(MsgTxtF,(MHeader.Pointer - 1)); + MHeader.Pointer := (FileSize(MsgTxtF1) + 1); + Seek(MsgTxtF1,FileSize(MsgTxtF1)); + IF (MDeleted IN MHeader.Status) THEN + Exclude(MHeader.Status,MDeleted); + Write(MsgHdrF1,MHeader); + Close(MsgHdrF1); + TempTextSize := 0; + REPEAT + BlockRead(MsgTxtF,MsgTxtStr[0],1); + BlockRead(MsgTxtF,MsgTxtStr[1],Ord(MsgTxtStr[0])); + LastError := IOResult; + Inc(TempTextSize,(Length(MsgTxtStr) + 1)); + BlockWrite(MsgTxtF1,MsgTxtStr,(Length(MsgTxtStr) + 1)); + LastError := IOResult; + UNTIL (TempTextSize >= MHeader.TextSize); + Close(MsgTxtF1); + Close(MsgTxtF); + NL; + Print('The message was moved successfully.'); + InputStr := 'Q'; + END; + END; + ReadMsgArea := SaveReadMsgArea; + END; + END; + END; + UNTIL (InputStr = 'Q') OR (HangUp); + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + InitMsgArea(SaveReadMsgArea); +END; + +END. diff --git a/SOURCE/MAIL4.PAS b/SOURCE/MAIL4.PAS new file mode 100644 index 0000000..6203d12 --- /dev/null +++ b/SOURCE/MAIL4.PAS @@ -0,0 +1,485 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Mail4; + +INTERFACE + +USES + Common; + +PROCEDURE MessageAreaList(VAR MArea,NumMAreas: Integer; AdjPageLen: Byte; ShowScan: Boolean); +PROCEDURE MessageAreaChange(VAR Done: Boolean; CONST MenuOption: Str50); +PROCEDURE ToggleMsgAreaScanFlags; + +IMPLEMENTATION + +USES + Crt, + Common5, + Mail0; + +PROCEDURE MessageAreaList(VAR MArea,NumMAreas: Integer; AdjPageLen: Byte; ShowScan: Boolean); +VAR + ScanChar: Str1; + TempStr: AStr; + NumOnline, + NumDone: Byte; + SaveMsgArea: Integer; +BEGIN + SaveMsgArea := MsgArea; + Abort := FALSE; + Next := FALSE; + NumOnline := 0; + TempStr := ''; + + FillChar(LightBarArray,SizeOf(LightBarArray),0); + LightBarCounter := 0; + + { + $New_Scan_Char_Message + + $ + } + IF (ShowScan) THEN + ScanChar := lRGLngStr(66,TRUE); + { + $Message_Area_Select_Header + %CL7Ŀ + 78 Num 79 Name 78 Num 79 Name 7 + 7 + $ + } + lRGLngStr(58,FALSE); + Reset(MsgAreaFile); + NumDone := 0; + WHILE (NumDone < (PageLength - AdjPageLen)) AND (MArea >= 1) AND (MArea <= NumMsgAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + LoadMsgArea(MArea); + IF (ShowScan) THEN + LoadLastReadRecord(LastReadRecord); + IF (AACS(MemMsgArea.ACS)) OR (MAUnHidden IN MemMsgArea.MAFlags) THEN + BEGIN + + IF (General.UseMsgAreaLightBar) AND (MsgAreaLightBar IN ThisUser.SFlags) THEN + BEGIN + Inc(LightBarCounter); + LightBarArray[LightBarCounter].CmdToExec := CompMsgArea(MArea,0); + LightBarArray[LightBarCounter].CmdToShow := MemMsgArea.Name; + IF (NumOnline = 0) THEN + BEGIN + LightBarArray[LightBarCounter].Xpos := 8; + LightBarArray[LightBarCounter].YPos := WhereY; + END + ELSE + BEGIN + LightBarArray[LightBarCounter].Xpos := 47; + LightBarArray[LightBarCounter].YPos := WhereY; + END; + END; + + TempStr := TempStr + AOnOff(ShowScan AND LastReadRecord.NewScan,':'+ScanChar[1],' ')+ + PadLeftStr(PadRightStr(';'+IntToStr(CompMsgArea(MArea,0)),5)+ + +'< '+MemMsgArea.Name,37)+' '; + Inc(NumOnline); + IF (NumOnline = 2) THEN + BEGIN + PrintaCR(TempStr); + NumOnline := 0; + Inc(NumDone); + TempStr := ''; + END; + Inc(NumMAreas); + END; + WKey; + Inc(MArea); + END; + Close(MsgAreaFile); + LastError := IOResult; + IF (NumOnline = 1) AND (NOT Abort) AND (NOT HangUp) THEN + PrintACR(TempStr) + ELSE IF (NumMAreas = 0) AND (NOT Abort) AND (NOT HangUp) THEN + LRGLngStr(68,FALSE); + { + %LF^7No message areas!^1' + } + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); +END; + +PROCEDURE MessageAreaChange(VAR Done: Boolean; CONST MenuOption: Str50); +VAR + InputStr: Str5; + Cmd: Char; + MArea, + NumMAreas, + SaveMArea: Integer; + SaveTempPause: Boolean; +BEGIN + IF (MenuOption <> '') THEN + CASE UpCase(MenuOption[1]) OF + '+' : BEGIN + MArea := MsgArea; + IF (MsgArea >= NumMsgAreas) THEN + MArea := 0 + ELSE + REPEAT + Inc(MArea); + ChangeMsgArea(MArea); + UNTIL (MsgArea = MArea) OR (MArea >= NumMsgAreas); + IF (MsgArea <> MArea) THEN + BEGIN + { + %LFHighest accessible message area. + %PA + } + LRGLngStr(85,FALSE); + END + ELSE + LastCommandOvr := TRUE; + END; + '-' : BEGIN + MArea := MsgArea; + IF (MsgArea <= 0) THEN + MArea := 0 + ELSE + REPEAT + Dec(MArea); + ChangeMsgArea(MArea); + UNTIL (MsgArea = MArea) OR (MArea <= 0); + IF (MsgArea <> MArea) THEN + BEGIN + { + %LFLowest accessible message area. + %PA + } + LRGLngStr(84,FALSE); + END + ELSE + LastCommandOvr := TRUE; + END; + 'L' : BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + MArea := 1; + NumMAreas := 0; + Cmd := '?'; + REPEAT + SaveMArea := MArea; + IF (Cmd = '?') THEN + MessageAreaList(MArea,NumMAreas,5,FALSE); + { + %LFMessage area list? [^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ + } + LOneK(LRGLngStr(69,TRUE),Cmd,'Q?[]',TRUE,TRUE); + TempPause := FALSE; + IF (Cmd <> 'Q') THEN + BEGIN + IF (Cmd = '[') THEN + BEGIN + MArea := (SaveMArea - ((PageLength - 5) * 2)); + IF (MArea < 1) THEN + MArea := 1; + Cmd := '?'; + END + ELSE IF (Cmd = ']') THEN + BEGIN + IF (MArea > NumMsgAreas) THEN + MArea := SaveMArea; + Cmd := '?'; + END + END + ELSE IF (Cmd = '?') THEN + BEGIN + { + $File_Message_Area_List_Help + %LF^1(^3###^1)Manual entry selection ^1(^3^1)Select current entry + ^1(^3^1)First entry on page ^1(^3^1)Last entry on page + ^1(^3Left Arrow^1)Previous entry ^1(^3Right Arrow^1)Next entry + ^1(^3Up Arrow^1)Move up ^1(^3Down Arrow^1)Move down + ^1(^3[^1)Previous page ^1(^3]^1)Next page + %PA + } + LRGLngStr(71,FALSE); + MArea := SaveMArea; + END + UNTIL (Cmd = 'Q') OR (HangUp); + TempPause := SaveTempPause; + LastCommandOvr := TRUE; + END; + ELSE + BEGIN + IF (StrToInt(MenuOption) > 0) THEN + BEGIN + MArea := StrToInt(MenuOption); + IF (MArea <> MsgArea) THEN + ChangeMsgArea(MArea); + IF (Pos(';',MenuOption) > 0) THEN + BEGIN + CurMenu := StrToInt(Copy(MenuOption,(Pos(';',MenuOption) + 1),Length(MenuOption))); + NewMenuToLoad := TRUE; + Done := TRUE; + END; + LastCommandOvr := TRUE; + END; + END; + END + ELSE + BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + MArea := 1; + NumMAreas := 0; + LightBarCmd := 1; + LightBarFirstCmd := TRUE; + InputStr := '?'; + REPEAT + SaveMArea := MArea; + IF (InputStr = '?') THEN + MessageAreaList(MArea,NumMAreas,5,FALSE); + { + %LFChange message area? [^5#^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ + } + MsgAreaScanInput(LRGLngStr(73,TRUE),Length(IntToStr(HighMsgArea)),InputStr,'Q[]?',LowMsgarea,HighMsgArea); + IF (InputStr <> 'Q') THEN + BEGIN + IF (InputStr = '[') THEN + BEGIN + MArea := (SaveMArea - ((PageLength - 5) * 2)); + IF (MArea < 1) THEN + MArea := 1; + InputStr := '?'; + END + ELSE IF (InputStr = ']') THEN + BEGIN + IF (MArea > NumMsgAreas) THEN + MArea := SaveMArea; + InputStr := '?'; + END + ELSE IF (InputStr = '?') THEN + BEGIN + { + $File_Message_Area_List_Help + %LF^1(^3###^1)Manual entry selection ^1(^3^1)Select current entry + ^1(^3^1)First entry on page ^1(^3^1)Last entry on page + ^1(^3Left Arrow^1)Previous entry ^1(^3Right Arrow^1)Next entry + ^1(^3Up Arrow^1)Move up ^1(^3Down Arrow^1)Move down + ^1(^3[^1)Previous page ^1(^3]^1)Next page + %PA + } + LRGLngStr(71,FALSE); + MArea := SaveMArea; + END + ELSE IF (StrToInt(InputStr) < LowMsgArea) OR (StrToInt(InputStr) > HighMsgArea) THEN + BEGIN + { + %LF^7The range must be from %A3 to %A4!^1 + } + LRGLngStr(79,FALSE); + MArea := SaveMArea; + InputStr := '?'; + END + ELSE + BEGIN + MArea := CompMsgArea(StrToInt(InputStr),1); + IF (MArea <> MsgArea) THEN + ChangeMsgArea(MArea); + IF (MArea = MsgArea) THEN + InputStr := 'Q' + ELSE + BEGIN + { + %LF^7You do not have access to this message area!^1 + } + LRGLngStr(81,FALSE); + MArea := SaveMArea; + InputStr := '?'; + END; + END; + END; + UNTIL (InputStr = 'Q') OR (HangUp); + TempPause := SaveTempPause; + LastCommandOvr := TRUE; + END; +END; + +PROCEDURE ToggleMsgAreaScanFlags; +VAR + InputStr: Str11; + FirstMArea, + LastMArea, + MArea, + NumMAreas, + SaveMArea, + SaveMsgArea: Integer; + SaveConfSystem, + SaveTempPause: Boolean; + + PROCEDURE ToggleScanFlags(MArea1: Integer; ScanType: Byte); + BEGIN + IF (MsgArea <> MArea1) THEN + ChangeMsgArea(MArea1); + IF (MsgArea = MArea1) THEN + BEGIN + LoadLastReadRecord(LastReadRecord); + IF (ScanType = 1) THEN + LastReadRecord.NewScan := TRUE + ELSE IF (ScanType = 2) THEN + BEGIN + IF (NOT (MAForceRead IN MemMsgArea.MAFlags)) THEN + LastReadRecord.NewScan := FALSE + ELSE + LastReadRecord.NewScan := TRUE; + END + ELSE IF (ScanType = 3) THEN + BEGIN + IF (NOT (MAForceRead IN MemMsgArea.MAFlags)) THEN + LastReadRecord.NewScan := (NOT LastReadRecord.NewScan) + ELSE + LastReadRecord.NewScan := TRUE; + END; + SaveLastReadRecord(LastReadRecord); + END; + END; + +BEGIN + SaveMsgArea := MsgArea; + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + SaveTempPause := TempPause; + TempPause := FALSE; + MArea := 1; + NumMAreas := 0; + LightBarCmd := 1; + LightBarFirstCmd := TRUE; + InputStr := '?'; + REPEAT + SaveMArea := MArea; + IF (InputStr = '?') THEN + MessageAreaList(MArea,NumMAreas,5,TRUE); + { + %LFToggle new scan? [^5#^4,^5#^4-^5#^4,^5F^4=^5Flag ^4or ^5U^4=^5Unflag All^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ + } + MsgAreaScanInput(LRGLngStr(75,TRUE),((Length(IntToStr(HighMsgArea)) * 2) + 1),InputStr,'QFU[]?',LowMsgArea,HighMsgArea); + IF (InputStr <> 'Q') THEN + BEGIN + IF (InputStr = '[') THEN + BEGIN + MArea := (SaveMArea - ((PageLength - 5) * 2)); + IF (MArea < 1) THEN + MArea := 1; + InputStr := '?'; + END + ELSE IF (InputStr = ']') THEN + BEGIN + IF (MArea > NumMsgAreas) THEN + MArea := SaveMArea; + InputStr := '?'; + END + ELSE IF (InputStr = '?') THEN + BEGIN + { + $File_Message_Area_List_Help + %LF^1(^3###^1)Manual entry selection ^1(^3^1)Select current entry + ^1(^3^1)First entry on page ^1(^3^1)Last entry on page + ^1(^3Left Arrow^1)Previous entry ^1(^3Right Arrow^1)Next entry + ^1(^3Up Arrow^1)Move up ^1(^3Down Arrow^1)Move down + ^1(^3[^1)Previous page ^1(^3]^1)Next page + %PA + } + LRGLngStr(71,FALSE); + MArea := SaveMArea; + END + ELSE + BEGIN + MsgArea := 0; + IF (InputStr = 'F') THEN + BEGIN + FOR MArea := 1 TO NumMsgAreas DO + ToggleScanFlags(MArea,1); + { + %LFYou are now reading all message areas. + } + LRGLngStr(87,FALSE); + MArea := 1; + InputStr := '?'; + END + ELSE IF (InputStr = 'U') THEN + BEGIN + FOR MArea := 1 TO NumMsgAreas DO + ToggleScanFlags(MArea,2); + { + %LFYou are now not reading any message areas. + } + LRGLngStr(89,FALSE); + MArea := 1; + InputStr := '?'; + END + ELSE IF (StrToInt(InputStr) > 0) THEN + BEGIN + FirstMArea := StrToInt(InputStr); + IF (Pos('-',InputStr) = 0) THEN + LastMArea := FirstMArea + ELSE + BEGIN + LastMArea := StrToInt(Copy(InputStr,(Pos('-',InputStr) + 1),(Length(InputStr) - Pos('-',InputStr)))); + IF (FirstMArea > LastMArea) THEN + BEGIN + MArea := FirstMArea; + FirstMArea := LastMArea; + LastMArea := MArea; + END; + END; + IF (FirstMArea < LowMsgArea) OR (LastMArea > HighMsgArea) THEN + BEGIN + { + %LF^7The range must be from %A3 to %A4!^1 + } + LRGLngStr(91,FALSE); + MArea := SaveMArea; + InputStr := '?'; + END + ELSE + BEGIN + FirstMArea := CompMsgArea(FirstMArea,1); + LastMArea := CompMsgArea(LastMArea,1); + FOR MArea := FirstMArea TO LastMArea DO + ToggleScanFlags(MArea,3); + IF (FirstMArea = LastMArea) THEN + IF (NOT (MAForceRead IN MemMsgArea.MAFlags)) THEN + BEGIN + { + %LF^5%MB^3 will %MSbe scanned. + } + LRGLngStr(93,FALSE); + END + ELSE + BEGIN + { + %LF^5%MB^3 cannot be removed from your newscan. + } + LRGLngStr(94,FALSE); + END; + MArea := SaveMArea; + InputStr := '?'; + END; + END; + MsgArea := SaveMsgArea; + END; + END; + UNTIL (InputStr = 'Q') OR (HangUp); + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + TempPause := SaveTempPause; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); + LastCommandOvr := TRUE; +END; + +END. diff --git a/SOURCE/MAINT.PAS b/SOURCE/MAINT.PAS new file mode 100644 index 0000000..69cbd4c --- /dev/null +++ b/SOURCE/MAINT.PAS @@ -0,0 +1,973 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Maint; + +INTERFACE + +PROCEDURE LogonMaint; +PROCEDURE LogoffMaint; +PROCEDURE DailyMaint; +PROCEDURE UpdateGeneral; + +IMPLEMENTATION + +USES + Automsg, + Bulletin, + Common, + CUser, + Email, + Events, + File6, + File12, + Mail1, + Mail4, + ShortMsg, + TimeFunc, + Vote; + +PROCEDURE LogonMaint; +VAR + LastCallerFile: FILE OF LastCallerRec; + LastCaller: LastCallerRec; + TempStr, + TempStr1: AStr; + Cmd: Char; + Counter, + Counter1: Integer; + RecNum: LongInt; + BSince: Boolean; + + PROCEDURE UpdateUserInformation; + VAR + UpdateArray: ARRAY [0..10] OF Integer; + Counter, + Counter1: Integer; + BEGIN + FOR Counter := 0 TO 10 DO + UpdateArray[Counter] := 0; + Counter := 0; + IF (ThisUser.RealName = User_String_Ask) THEN + BEGIN + UpdateArray[1] := 10; + Inc(Counter); + END; + IF (ThisUser.Street = User_String_Ask) THEN + BEGIN + UpdateArray[2] := 1; + Inc(Counter); + END; + IF (ThisUser.CityState = User_String_Ask) THEN + BEGIN + UpdateArray[0] := 23; + UpdateArray[3] := 4; + Inc(Counter); + END; + IF (ThisUser.ZipCode = User_String_Ask) THEN + BEGIN + UpdateArray[0] := 23; + UpdateArray[4] := 14; + Inc(Counter); + END; + IF (ThisUser.BirthDate = User_Date_Ask) THEN + BEGIN + UpdateArray[5] := 2; + Inc(Counter); + END; + IF (ThisUser.Ph = User_Phone_Ask) THEN + BEGIN + UpdateArray[6] := 8; + Inc(Counter); + END; + IF (ThisUser.UsrDefStr[1] = User_String_Ask) THEN + BEGIN + UpdateArray[7] := 5; + Inc(Counter); + END; + IF (ThisUser.UsrDefStr[2] = User_String_Ask) THEN + BEGIN + UpdateArray[8] := 6; + Inc(Counter); + END; + IF (ThisUser.UsrDefStr[3] = User_String_Ask) THEN + BEGIN + UpdateArray[9] := 13; + Inc(Counter); + END; + IF (ThisUser.ForgotPWAnswer = User_String_Ask) THEN + BEGIN + UpdateArray[10] := 30; + Inc(Counter); + END; + IF (Counter <> 0) THEN + BEGIN + CLS; + NL; + Print('Please update the following information:'); + Counter := 0; + WHILE (Counter <= 10) AND (NOT HangUp) DO + BEGIN + IF (UpDateArray[Counter] <> 0) THEN + BEGIN + Update_Screen; + CStuff(UpdateArray[Counter],1,ThisUser); + END; + Inc(Counter); + END; + NL; + Print('Thank you!'); + NL; + PauseScr(FALSE); + END; + END; + + FUNCTION CheckBirthday: Boolean; + VAR + BDate: LongInt; + BEGIN + BSince := FALSE; + BDate := Date2PD(Copy(PD2Date(ThisUser.BirthDate),1,6) + Copy(DateStr,7,4)); + IF (BDate > ThisUser.LastOn) AND (BDate <= Date2PD(DateStr)) THEN + BEGIN + CheckBirthday := TRUE; + BSince := (BDate < Date2PD(DateStr)); + END + ELSE + CheckBirthday := FALSE; + END; + + PROCEDURE ShowBDay(CONST UserNumber: AStr); + BEGIN + IF (BSince) THEN + PrintF('BDYS'+UserNumber); + IF (NoFile) THEN + PrintF('BDAY'+UserNumber); + END; + + PROCEDURE FindChopTime; + VAR + LNG, + LNG2, + LNG3: LongInt; + EventNum: Byte; + + PROCEDURE OnlineTime; + BEGIN + PrintF('REVENT'+IntToStr(EventNum)); + IF (NoFile) THEN + BEGIN + Print(^G); + NL; + Print('^8Note: ^5System event approaching.'); + Print('System will be shut down in '+FormattedTime(NSL)); + NL; + Print(^G); + PauseScr(FALSE); + END; + END; + + BEGIN + IF (ExtEventTime <> 0) THEN + BEGIN + LNG := ExtEventTime; + IF (LNG < (NSL DIV 60)) THEN + BEGIN + ChopTime := (NSL - (LNG * 60)) + 120; + OnlineTime; + Exit; + END; + END; + + LNG := 1; + LNG2 := (NSL DIV 60); + IF (LNG2 > 180) THEN + LNG2 := 180; + WHILE (LNG <= LNG2) DO + BEGIN + LNG3 := (LNG * 60); + EventNum := CheckEvents(LNG3); + IF (EventNum <> 0) THEN + BEGIN + ChopTime := (NSL - (LNG * 60)) + 60; + OnlineTime; + Exit; + END; + Inc(LNG,2); + END; + END; + +BEGIN + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + IF AACS(General.Invisible) AND PYNQ(lRGLngStr(45,TRUE){FString.AskInvisibleLoginStr},0,FALSE) THEN + BEGIN + IsInvisible := TRUE; + Include(NodeR.Status,NInvisible); + SysOpLog('Selected invisible mode.'); + END + ELSE + IsInvisible := FALSE; + FillChar(NodeR.Invited,SizeOf(NodeR.Invited),0); + FillChar(NodeR.Booted,SizeOf(NodeR.Booted),0); + FillChar(NodeR.Forget,SizeOf(NodeR.Forget),0); + Include(NodeR.Status,NAvail); + SaveNode(ThisNode); + Update_Node(RGNoteStr(37,TRUE),TRUE); + FOR Counter := 1 TO MaxNodes DO + BEGIN + LoadNode(Counter); + NodeR.Forget[ThisNode DIV 8] := NodeR.Forget[ThisNode DIV 8] - [ThisNode MOD 8]; + SaveNode(Counter); + END; + END; + + ConfSystem := TRUE; + + IF (ThisUser.LastConf IN ConfKeys) THEN + CurrentConf := ThisUser.LastConf + ELSE + BEGIN + CurrentConf := '@'; + ThisUser.LastConf := CurrentConf; + END; + + PublicReadThisCall := 0; + ExtraTime := 0; + FreeTime := 0; + CreditTime := 0; + TimeOn := GetPackDateTime; + UserOn := TRUE; + + Com_Flush_Recv; + + lStatus_Screen(100,'Cleaning up work areas...',FALSE,TempStr); + PurgeDir(TempDir+'ARC\',FALSE); + PurgeDir(TempDir+'QWK\',FALSE); + PurgeDir(TempDir+'UP\',FALSE); + PurgeDir(TempDir+'CD\',FALSE); + + DailyMaint; + + IF (ComPortSpeed > 0) AND (NOT LocalIOOnly) THEN + Inc(TodayCallers); + + IF (SLogSeparate IN ThisUser.SFlags) THEN + BEGIN + Assign(SysOpLogFile1,General.LogsPath+'SLOG'+IntToStr(UserNum)+'.LOG'); + Append(SysOpLogFile1); + IF (IOResult = 2) THEN + BEGIN + ReWrite(SysOpLogFile1); + Append(SysOpLogFile1); + TempStr := ''; + TempStr1 := ''; + FOR Counter := 1 TO (26 + Length(ThisUser.Name)) DO + BEGIN + TempStr := TempStr + '_'; + TempStr1 := TempStr1 + ' '; + END; + WriteLn(SysOpLogFile1,''); + WriteLn(SysOpLogFile1,' '+TempStr); + WriteLn(SysOpLogFile1,'>>'+TempStr1+'<<'); + WriteLn(SysOpLogFile1,'>> Renegade SysOp Log for '+Caps(ThisUser.Name)+': <<'); + WriteLn(SysOpLogFile1,'>>'+TempStr+'<<'); + WriteLn(SysOpLogFile1,''); + END; + WriteLn(SysOpLogFile1); + + TempStr := '^3Logon ^5['+Dat+']^4 ('; + + IF (ComPortSpeed > 0) THEN + BEGIN + TempStr := TempStr + IntToStr(ActualSpeed)+' baud'; + + IF (Reliable) THEN + TempStr := TempStr + '/Reliable)' + ELSE + TempStr := TempStr + ')'; + + IF (CallerIDNumber > '') THEN + BEGIN + IF (NOT Telnet) THEN + TempStr := TempStr + ' Number: '+CallerIDNumber + ELSE + TempStr := TempStr + ' IP Number: '+CallerIDNumber; + END; + END + ELSE + TempStr := TempStr + 'Keyboard)'; + + IF (General.StripCLog) THEN + TempStr := StripColor(TempStr); + + WriteLn(SysOpLogFile1,TempStr); + + Close(SysOpLogFile1); + END; + + TempStr := '^3'+IntToStr(General.CallerNum)+'^4 -- ^0'+Caps(ThisUser.Name)+'^4 -- ^3'+'Today '+IntToStr(ThisUser.OnToday); + IF (Trapping) THEN + TempStr := TempStr + '^0*'; + SL1(TempStr); + SaveGeneral(FALSE); + LastError := IOResult; + + IF ((CoSysOp) AND (NOT FastLogon) AND (ComPortSpeed > 0)) THEN + BEGIN + IF PYNQ(lRGLngStr(57,TRUE){FString.QuickLogon},0,FALSE) THEN + FastLogon := TRUE; + NL; + END; + + Assign(LastCallerFile,General.DataPath+'LASTON.DAT'); + IF Exist(General.DataPath+'LASTON.DAT') THEN + Reset(LastCallerFile) + ELSE + ReWrite(LastCallerFile); + FillChar(LastCaller,SizeOf(LastCaller),#0); + WITH LastCaller DO + BEGIN + Node := ThisNode; + Caller := General.CallerNum; + UserName := Caps(ThisUser.Name); + UserID := UserNum; + Location := ThisUser.CityState; + IF (ComPortSpeed <> 0) THEN + Speed := ActualSpeed + ELSE + Speed := 0; + LogonTime := TimeOn; + LogoffTime := 0; + NewUser := WasNewUser; + Invisible := IsInvisible; + END; + IF AACS(General.LastOnDatACS) THEN + BEGIN + Seek(LastCallerFile,FileSize(LastCallerFile)); + Write(LastCallerFile,LastCaller); + END; + Close(LastCallerFile); + LastError := IOResult; + + SaveGeneral(TRUE); + + IF (NOT FastLogon) AND (NOT HangUp) THEN + BEGIN + + PrintF('LOGON'); + Counter := 0; + REPEAT + Inc(Counter); + PrintF('LOGON'+IntToStr(Counter)); + UNTIL (Counter = 9) OR (NoFile) OR (HangUp); + + PrintF('SL'+IntToStr(ThisUser.SL)); + + PrintF('DSL'+IntToStr(ThisUser.DSL)); + + FOR Cmd := 'A' TO 'Z' DO + IF (Cmd IN ThisUser.AR) THEN + PrintF('ARLEVEL'+Cmd); + + PrintF('USER'+IntToStr(UserNum)); + + IF (FindOnlyOnce) THEN + PrintF('ONCEONLY'); + + UpdateUserInformation; + + IF (General.LogonQuote) THEN + RGQuote('LGNQUOTE'); + + IF (CheckBirthday) THEN + BEGIN + ShowBDay(IntToStr(UserNum)); + IF (NoFile) THEN + ShowBDay(''); + IF (NoFile) THEN + IF (BSince) THEN + BEGIN + NL; + Print('^3Happy Birthday, '+Caps(ThisUser.Name)+' !!!'); + Print('^3(a little late, but it''s the thought that counts!)'); + NL; + END + ELSE + BEGIN + NL; + Print('^3Happy Birthday, '+Caps(ThisUser.Name)+' !!!'); + Print('^3You turned '+IntToStr(AgeUser(ThisUser.BirthDate))+' today!!'); + NL; + END; + PauseScr(FALSE); + CLS; + END; + + NL; + IF (General.AutoMInLogon) THEN + ReadAutoMsg; + NL; + + IF (General.YourInfoInLogon) THEN + BEGIN + PrintF('YOURINFO'); + NL; + END; + + LIL := 0; + + IF (General.BullInLogon) AND (NewBulletins) THEN + BEGIN + NL; + IF PYNQ(lRGLngStr(56,TRUE){FString.ShowBulletins},0,FALSE) THEN + Bulletins('') + ELSE + NL; + END; + + IF (NOT (RVoting IN ThisUser.Flags)) THEN + BEGIN + Counter := UnVotedTopics; + IF (Counter > 0) THEN + BEGIN + NL; + Prompt('^5You have not voted on ^9'+IntToStr(Counter)+'^5 voting '+Plural('question',Counter)); + NL; + END; + END; + + IF Exist(General.DataPath+'BATCHDL.DAT') THEN + BEGIN + Assign(BatchDLFile,General.DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchDLFile)) DO + BEGIN + Seek(BatchDLFile,(RecNum - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = UserNum) THEN + BEGIN + Inc(NumBatchDLFiles); + Inc(BatchDLTime,BatchDL.BDLTime); + Inc(BatchDLSize,BatchDL.BDLFSize); + Inc(BatchDLPoints,BatchDL.BDLPoints); + END; + Inc(RecNum); + END; + Close(BatchDLFile); + LastError := IOResult; + END; + + IF Exist(General.DataPath+'BATCHUL.DAT') THEN + BEGIN + Assign(BatchULFile,General.DataPath+'BATCHUL.DAT'); + Reset(BatchULFile); + RecNum := 1; + WHILE (RecNum <= FileSize(BatchULFile)) DO + BEGIN + Seek(BatchULFile,(RecNum - 1)); + Read(BatchULFile,BatchUL); + IF (BatchUL.BULUserNum = UserNum) THEN + Inc(NumBatchULFiles); + Inc(RecNum); + END; + Close(BatchULFile); + LastError := IOResult; + END; + + IF (NumBatchDLFiles > 0) AND (General.ForceBatchDL) THEN + REPEAT + NL; + Print('^4You must (^5D^4)ownload, (^5R^4)emove or (^5C^4)lear your batch queued files.'); + NL; + Prt('Select option: '); + OneK(Cmd,'DRC',TRUE,TRUE); + CASE Cmd OF + 'D' : BatchDownload; + 'R' : RemoveBatchDLFiles; + 'C' : ClearBatchDLQueue; + END; + UNTIL (NumBatchDLFiles = 0) OR (FileSysOp) OR (HangUp); + + IF (NumBatchULFiles > 0) AND (General.ForceBatchUL) THEN + REPEAT + NL; + Print('^4You must (^5U^4)pload, (^5R^4)emove or (^5C^4)lear your batch queued files.'); + NL; + Prt('Select option: '); + OneK(Cmd,'URC',TRUE,TRUE); + CASE Cmd OF + 'U' : BatchUpload(FALSE,0); + 'R' : RemoveBatchULFiles; + 'C' : ClearBatchULQueue; + END; + UNTIL (NumBatchULFiles = 0) OR (FileSysOp) OR (HangUp); + + BatchDLULInfo; + + IF (LIL <> 0) THEN + PauseScr(FALSE); + + NL; + Update_Screen; + END; + + FindChopTime; + + + IF (SMW IN ThisUser.Flags) THEN + BEGIN + ReadShortMessage; + NL; + PauseScr(FALSE); + END; + + IF ((Alert IN ThisUser.Flags) AND (SysOpAvailable)) THEN + ChatCall := TRUE; + + IF (ThisUser.Waiting > 0) THEN + IF (RMsg IN ThisUser.Flags) THEN + ReadMail + ELSE + BEGIN + IF PYNQ('Read your private messages? ',0,TRUE) THEN + ReadMail; + END; + + IF (General.PasswordChange > 0) THEN + IF ((DayNum(DateStr) - ThisUser.PasswordChanged) >= General.PasswordChange) THEN + BEGIN + PrintF('PWCHANGE'); + IF (NoFile) THEN + BEGIN + NL; + Print('You must select a new password every '+IntToStr(General.PasswordChange)+' days.'); + NL; + END; + CStuff(9,3,ThisUser); + END; + + FastLogon := FALSE; +END; + +PROCEDURE LogoffMaint; +VAR + HistoryFile: FILE OF HistoryRecordType; + LastCallerFile: FILE OF LastCallerRec; + History: HistoryRecordType; + LastCaller: LastCallerRec; + Counter: Integer; + TotTimeOn: LongInt; +BEGIN + Com_Flush_Send; + + LoadNode(ThisNode); + WITH NodeR DO + BEGIN + User := 0; + UserName := ''; + CityState := ''; + Sex := 'M'; + Age := 0; + LogonTime := 0; + GroupChat := FALSE; + ActivityDesc := ''; + Status := [NActive]; + Room := 0; + Channel := 0; + FillChar(Invited,SizeOf(Invited),0); + FillChar(Booted,SizeOf(Booted),0); + FillChar(Forget,SizeOf(Forget),0); + END; + SaveNode(ThisNode); + + IF (UserNum > 0) THEN + BEGIN + PurgeDir(TempDir+'ARC\',FALSE); + PurgeDir(TempDir+'QWK\',FALSE); + PurgeDir(TempDir+'UP\',FALSE); + PurgeDir(TempDir+'CD\',FALSE); + + SLogging := TRUE; + + IF (Trapping) THEN + BEGIN + IF (HungUp) THEN + BEGIN + WriteLn(TrapFile); + WriteLn(TrapFile,'NO CARRIER'); + END; + Close(TrapFile); + Trapping := FALSE; + END; + + TotTimeOn := ((GetPackDateTime - TimeOn) DIV 60); + + ThisUser.LastOn := GetPackDateTime; + Inc(ThisUser.LoggedOn); + + ThisUser.Illegal := 0; + ThisUser.TTimeOn := (ThisUser.TTimeOn + TotTimeOn); + ThisUser.TLToday := (NSL DIV 60); + + IF (ChopTime <> 0) THEN + Inc(ThisUser.TLToday,(ChopTime DIV 60)); + + ThisUser.LastMsgArea := MsgArea; + ThisUser.LastFileArea := FileArea; + + IF ((UserNum >= 1) AND (UserNum <= (MaxUsers - 1))) THEN + SaveURec(ThisUser,UserNum); + + IF (HungUp) THEN + SL1('^7-= Hung Up =-'); + + SL1('^4Read: ^3'+IntToStr(PublicReadThisCall)+'^4 / Time on: ^3'+IntToStr(TotTimeOn)); + + END; + LastError := IOResult; + + SL1('^3Logoff node '+IntToStr(ThisNode)+' ^5'+'['+Dat+']'); + + Assign(HistoryFile,General.DataPath+'HISTORY.DAT'); + Reset(HistoryFile); + IF (IOResult = 2) THEN + BEGIN + ReWrite(HistoryFile); + FillChar(History,SizeOf(History),0); + History.Date := Date2PD(DateStr); + END + ELSE + BEGIN + Seek(HistoryFile,(FileSize(HistoryFile) - 1)); + Read(HistoryFile,History); + END; + Inc(History.Active,(GetPackDateTime - TimeOn) DIV 60); + IF (NOT LocalIOOnly) THEN + Inc(History.Callers); + IF (WasNewUser) THEN + Inc(History.NewUsers); + + IF ((History.Posts + PublicPostsToday) < 2147483647) THEN + Inc(History.Posts,PublicPostsToday) + ELSE + History.Posts := 2147483647; + + IF ((History.Email + PrivatePostsToday) < 2147483647) THEN + Inc(History.Email,PrivatePostsToday) + ELSE + History.Email := 2147483647; + + IF ((History.FeedBack + FeedbackPostsToday) < 2147483647) THEN + Inc(History.FeedBack,FeedbackPostsToday) + ELSE + History.FeedBack := 2147483647; + + IF ((History.Uploads + UploadsToday) < 2147483647) THEN + Inc(History.Uploads,UploadsToday) + ELSE + History.Uploads := 2147483647; + + IF ((History.Downloads + DownloadsToday) < 2147483647) THEN + Inc(History.Downloads,DownloadsToday) + ELSE + History.Downloads := 2147483647; + + IF ((History.UK + UploadKBytesToday) < 2147483647) THEN + Inc(History.UK,UploadKBytesToday) + ELSE + History.UK := 2147483647; + + IF ((History.DK + DownloadKBytesToday) < 2147483647) THEN + Inc(History.DK,DownloadKBytesToday) + ELSE + History.DK := 2147483647; + + IF (Exist(StartDir+'\CRITICAL.ERR')) THEN + BEGIN + Inc(History.Errors); + Kill(StartDir+'\CRITICAL.ERR'); + END; + + IF (ComPortSpeed <> 0) THEN + BEGIN + IF (ComportSpeed = 300) THEN + Inc(History.UserBaud[1]) + ELSE IF (ComportSpeed = 600) THEN + Inc(History.UserBaud[2]) + ELSE IF (ComportSpeed = 1200) THEN + Inc(History.UserBaud[3]) + ELSE IF (ComportSpeed = 2400) THEN + Inc(History.UserBaud[4]) + ELSE IF (ComportSpeed = 4800) THEN + Inc(History.UserBaud[5]) + ELSE IF (ComportSpeed = 7200) THEN + Inc(History.UserBaud[6]) + ELSE IF (ComportSpeed = 9600) THEN + Inc(History.UserBaud[7]) + ELSE IF (ComportSpeed = 12000) THEN + Inc(History.UserBaud[8]) + ELSE IF (ComportSpeed = 14400) THEN + Inc(History.UserBaud[9]) + ELSE IF (ComportSpeed = 16800) THEN + Inc(History.UserBaud[10]) + ELSE IF (ComportSpeed = 19200) THEN + Inc(History.UserBaud[11]) + ELSE IF (ComportSpeed = 21600) THEN + Inc(History.UserBaud[12]) + ELSE IF (ComportSpeed = 24000) THEN + Inc(History.UserBaud[13]) + ELSE IF (ComportSpeed = 26400) THEN + Inc(History.UserBaud[14]) + ELSE IF (ComportSpeed = 28800) THEN + Inc(History.UserBaud[15]) + ELSE IF (ComportSpeed = 31200) THEN + Inc(History.UserBaud[16]) + ELSE IF (ComportSpeed = 33600) THEN + Inc(History.UserBaud[17]) + ELSE IF (ComportSpeed = 38400) THEN + Inc(History.UserBaud[18]) + ELSE IF (ComportSpeed = 57600) THEN + Inc(History.UserBaud[19]) + ELSE IF (ComportSpeed = 115200) THEN + Inc(History.UserBaud[20]) + ELSE + Inc(History.UserBaud[0]); + END; + Seek(HistoryFile,(FileSize(HistoryFile) - 1)); + Write(Historyfile,History); + Close(HistoryFile); + LastError := IOResult; + + Assign(LastCallerFile,General.DataPath+'LASTON.DAT'); + Reset(LastCallerFile); + IF (IOResult = 2) THEN + ReWrite(LastCallerFile); + FOR Counter := (FileSize(LastCallerFile) - 1) DOWNTO 0 DO + BEGIN + Seek(LastCallerFile,Counter); + Read(LastCallerFile,LastCaller); + IF (LastCaller.Node = ThisNode) AND (LastCaller.UserID = UserNum) THEN + WITH LastCaller DO + BEGIN + LogOffTime := GetPackDateTime; + Uploads := UploadsToday; + Downloads := DownloadsToday; + UK := UploadKBytesToday; + DK := DownloadKBytesToday; + MsgRead := PublicReadThisCall; + MsgPost := PublicPostsToday; + EmailSent := PrivatePostsToday; + FeedbackSent := FeedbackPostsToday; + Seek(LastCallerFile,Counter); + Write(LastCallerFile,LastCaller); + Break; + END; + END; + Close(LastCallerFile); + LastError := IOResult; +END; + +PROCEDURE DailyMaint; +VAR + LastCallerFile: FILE OF LastCallerRec; + HistoryFile: FILE OF HistoryRecordType; + ShortMsgFile: FILE OF ShortMessageRecordType; + F: Text; + History: HistoryRecordType; + ShortMsg: ShortMessageRecordType; + TempStr: AStr; + Counter, + Counter1: Integer; +BEGIN + + IF (Date2PD(General.LastDate) <> Date2PD(DateStr)) THEN + BEGIN + + General.LastDate := DateStr; + + SaveGeneral(FALSE); + + (* Test code only *) + IF (NOT InWFCMenu) THEN + SysOpLog('Daily maintenance ran from Caller Logon.') + ELSE + SysOpLog('Daily maintenance ran from Waiting For Caller.'); + (* End test code *) + + IF (NOT InWFCMenu) THEN + lStatus_Screen(100,'Updating data files ...',FALSE,TempStr); + + (* Test *) + IF Exist(General.DataPath+'LASTON.DAT') THEN + Kill(General.DataPath+'LASTON.DAT'); + + Assign(LastCallerFile,General.DataPath+'LASTON.DAT'); + ReWrite(LastCallerFile); + Close(LastCallerFile); + + Assign(ShortMsgFile,General.DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + IF (IOResult = 0) THEN + BEGIN + IF (FileSize(ShortMsgFile) >= 1) THEN + BEGIN + Counter := 0; + Counter1 := 0; + WHILE (Counter <= (FileSize(ShortMsgFile) - 1)) DO + BEGIN + Seek(ShortMsgFile,Counter); + Read(ShortMsgFile,ShortMsg); + IF (ShortMsg.Destin <> -1) THEN + IF (Counter = Counter1) THEN + Inc(Counter1) + ELSE + BEGIN + Seek(ShortMsgFile,Counter1); + Write(ShortMsgFile,ShortMsg); + Inc(Counter1); + END; + Inc(Counter); + END; + Seek(ShortMsgFile,Counter1); + Truncate(ShortMsgFile); + END; + Close(ShortMsgFile); + END; + LastError := IOResult; + + Assign(HistoryFile,General.DataPath+'HISTORY.DAT'); + IF NOT Exist(General.DataPath+'HISTORY.DAT') THEN + ReWrite(HistoryFile) + ELSE + BEGIN + Reset(HistoryFile); + Seek(HistoryFile,(FileSize(HistoryFile) - 1)); + Read(HistoryFile,History); + Inc(General.DaysOnline); + Inc(General.TotalCalls,History.Callers); + Inc(General.TotalUsage,History.Active); + Inc(General.TotalPosts,History.Posts); + Inc(General.TotalDloads,History.Downloads); + Inc(General.TotalUloads,History.Uploads); + END; + + IF (History.Date <> Date2PD(DateStr)) THEN + BEGIN + IF Exist(General.LogsPath+'SYSOP'+IntToStr(General.BackSysOpLogs)+'.LOG') THEN + Kill(General.LogsPath+'SYSOP'+IntToStr(General.BackSysOpLogs)+'.LOG'); + + FOR Counter := (General.BackSysOpLogs - 1) DOWNTO 1 DO + IF (Exist(General.LogsPath+'SYSOP'+IntToStr(Counter)+'.LOG')) THEN + BEGIN + Assign(F,General.LogsPath+'SYSOP'+IntToStr(Counter)+'.LOG'); + Rename(F,General.LogsPath+'SYSOP'+IntToStr(Counter + 1)+'.LOG'); + END; + + SL1(''); + SL1('Total mins active..: '+IntToStr(History.Active)); + SL1('Percent of activity: '+SQOutSp(CTP(History.Active,1440))+' ('+IntToStr(History.Callers)+' calls)'); + SL1('New users..........: '+IntToStr(History.NewUsers)); + SL1('Public posts.......: '+IntToStr(History.Posts)); + SL1('Private mail sent..: '+IntToStr(History.Email)); + SL1('FeedBack sent......: '+IntToStr(History.FeedBack)); + SL1('Critical errors....: '+IntToStr(History.Errors)); + SL1('Downloads today....: '+IntToStr(History.Downloads)+'-'+ConvertKB(History.DK,FALSE)); + SL1('Uploads today......: '+IntToStr(History.Uploads)+'-'+ConvertKB(History.UK,FALSE)); + + FillChar(History,SizeOf(History),0); + History.Date := Date2PD(DateStr); + + Seek(HistoryFile,FileSize(HistoryFile)); + Write(HistoryFile,History); + Close(HistoryFile); + + IF (General.MultiNode) AND Exist(TempDir+'TEMPLOG.'+IntToStr(ThisNode)) THEN + BEGIN + Assign(F,General.LogsPath+'SYSOP.LOG'); + Append(F); + IF (IOResult = 2) THEN + ReWrite(F); + Reset(SysOpLogFile); + WHILE NOT EOF(SysOpLogFile) DO + BEGIN + ReadLn(SysOpLogFile,TempStr); + WriteLn(F,TempStr); + END; + Close(SysOpLogFile); + Close(F); + Erase(SysOpLogFile); + END; + + Assign(SysOpLogFile,General.LogsPath+'SYSOP.LOG'); + Rename(SysOpLogFile,General.LogsPath+'SYSOP1.LOG'); + + Assign(SysOpLogFile,General.LogsPath+'SYSOP.LOG'); + ReWrite(SysOpLogFile); + Close(SysOpLogFile); + + SL1(^M^J' Renegade SysOp Log for '+DateStr+^M^J); + + IF (General.MultiNode) THEN + Assign(SysOpLogFile,TempDir+'TEMPLOG.'+IntToStr(ThisNode)) + ELSE + Assign(SysOpLogFile,General.LogsPath+'SYSOP.LOG'); + Append(SysOpLogFile); + IF (IOResult = 2) THEN + ReWrite(SysOpLogFile); + Close(SysOpLogFile); + END + ELSE + Close(HistoryFile); + END; +END; + +PROCEDURE UpdateGeneral; +VAR + HistoryFile: FILE OF HistoryRecordType; + History: HistoryRecordType; + Counter: LongInt; +BEGIN + Assign(HistoryFile,General.DataPath+'HISTORY.DAT'); + Reset(HistoryFile); + IF (IOResult = 2) THEN + ReWrite(HistoryFile); + WITH General DO + BEGIN + DaysOnline := FileSize(HistoryFile); + TotalCalls := 0; + TotalUsage := 0; + TotalPosts := 0; + TotalDloads := 0; + TotalUloads := 0; + FOR Counter := 1 TO (FileSize(HistoryFile) - 1) DO + BEGIN + Read(HistoryFile,History); + Inc(TotalCalls,History.Callers); + Inc(TotalUsage,History.Active); + Inc(TotalPosts,History.Posts); + Inc(TotalDloads,History.Downloads); + Inc(TotalUloads,History.Uploads); + END; + IF (TotalUsage < 1) THEN + TotalUsage := 1; + IF (DaysOnline < 1) THEN + DaysOnline := 1; + END; + Close(HistoryFile); + LastError := IOResult; + SaveGeneral(FALSE); + IF (NOT InWFCMenu) THEN + BEGIN + NL; + Print('System averages have been updated.'); + PauseScr(FALSE); + END; +END; + +END. diff --git a/SOURCE/MENUS.PAS b/SOURCE/MENUS.PAS new file mode 100644 index 0000000..dee28e5 --- /dev/null +++ b/SOURCE/MENUS.PAS @@ -0,0 +1,1071 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O-,R-,S+,V-} + +UNIT Menus; + +INTERFACE + +USES + Common, + MyIO; + +PROCEDURE AutoExecCmd(AutoCmd: AStr); +PROCEDURE MenuExec; +PROCEDURE LoadMenuPW; +PROCEDURE MainMenuHandle(VAR Cmd: AStr); +PROCEDURE FCmd(CONST Cmd: AStr; VAR CmdToExec: Byte; VAR CmdExists,CmdNotHid: Boolean); +PROCEDURE DoMenuExec(Cmd: AStr; VAR NewMenuCmd: AStr); +PROCEDURE DoMenuCommand(VAR Done: Boolean; + Cmd, + MenuOption: AStr; + VAR NewMenuCmd: AStr; + NodeActivityDesc: AStr); + +IMPLEMENTATION + +USES + Arcview, + Archive1, + Archive2, + Archive3, + Automsg, + BBSList, + Boot, + Bulletin, + CUser, + Doors, + Email, + Events, + File0, + File1, + File2, + File3, + File5, + File6, + File7, + File8, + File9, + File10, + File11, + File12, + File13, + File14, + Mail0, + Mail1, + Mail2, + Mail3, + Mail4, + Menus2, + Menus3, + MiscUser, + MsgPack, + Multnode, + OffLine, + Script, + Stats, + LineChat, + Sysop1, + Sysop2, + SysOp2G, + Sysop3, + Sysop4, + SysOp5, + Sysop6, + Sysop7, + Sysop8, + Sysop9, + Sysop10, + Sysop11, + SysOp12, + TimeBank, + TimeFunc, + Vote, + OneLiner; + + + (* + I := 1; + Newmenucmd := ''; + while ((I <= Noc) and (Newmenucmd = '') ) do + begin + if (Menucommand^[I].Ckeys = 'FIRSTCMD') then + begin + if (Aacs(Menucommand^[I].Acs)) then + begin + Newmenucmd := 'FIRSTCMD'; + Domenuexec(Cmd,Newmenucmd); + end; + end; + inc(I); + end; + *) +PROCEDURE AutoExecCmd(AutoCmd: AStr); +VAR + NewMenuCmd: AStr; + Counter: Byte; + Done: Boolean; +BEGIN + NewMenuCmd := ''; + Done := FALSE; + Counter := 1; + WHILE (Counter <= NumCmds) AND (NewMenuCmd = '') AND (NOT Done) AND (NOT HangUp) DO + BEGIN + IF (MemCmd^[Counter].Ckeys = AutoCmd) then + IF (AACS(MemCmd^[Counter].ACS)) THEN + BEGIN + NewMenuCmd := AutoCmd; + DoMenuCommand(Done, + MemCmd^[Counter].CmdKeys, + MemCmd^[Counter].Options, + NewMenuCmd, + MemCmd^[Counter].NodeActivityDesc); + END; + Inc(Counter); + END; +END; + +PROCEDURE MenuExec; +VAR + Cmd, + NewMenuCmd: AStr; + Done: Boolean; +BEGIN + MainMenuHandle(Cmd); + IF ((Copy(Cmd,1,2) = '\\') AND (SysOp)) THEN + BEGIN + DoMenuCommand(Done,Copy(Cmd,1,2),Copy(Cmd,3,Length(Cmd) - 2),NewMenuCmd,'Activating SysOp Cmd'); + IF (NewMenuCmd <> '') THEN + Cmd := NewMenuCmd + ELSE + Cmd := ''; + END; + NewMenuCmd := ''; + REPEAT + DoMenuExec(Cmd,NewMenuCmd) + UNTIL (NewMenuCmd = '') OR (HangUp); +END; + +PROCEDURE CheckHelpLevel; +BEGIN + IF (MemMenu.ForceHelpLevel <> 0) THEN + CurHelpLevel := MemMenu.ForceHelpLevel + ELSE IF (Novice IN ThisUser.Flags) OR (OkRIP) THEN + CurHelpLevel := 2 + ELSE + CurHelpLevel := 1; +END; + +PROCEDURE LoadMenuPW; +VAR + s: Str20; + NACC: Boolean; +BEGIN + LoadMenu; + NACC := FALSE; + IF (NOT AACS(MemMenu.ACS)) OR (MemMenu.Password <> '') THEN + BEGIN + NACC := TRUE; + IF (MemMenu.Password <> '') THEN + BEGIN + NL; + Prt('Password: '); + GetPassword(s,20); + IF (s = MemMenu.Password) THEN + NACC := FALSE; + END; + IF (NACC) THEN + BEGIN + PrintF('NOACCESS'); + IF (NoFile) THEN + BEGIN + NL; + Print('Access denied.'); + PauseScr(FALSE); + END; + CurMenu := FallBackMenu; + LoadMenu; + END; + END; + IF (NOT NACC) THEN + CheckHelpLevel; +END; + +PROCEDURE CheckForceLevel; +BEGIN + IF (CurHelpLevel < MemMenu.ForceHelpLevel) THEN + CurHelpLevel := MemMenu.ForceHelpLevel; +END; + +PROCEDURE GetCmd(VAR Cmd: AStr); +VAR + S1, + SS, + SaveSS, + SHas0, + SHas1: AStr; + C: Char; + CmdToExec, + Counter, + SaveCurrentColor: Byte; + Key: Word; + GotCmd, + Has0, + Has1, + Has2: Boolean; +BEGIN + Cmd := ''; + IF (Buf <> '') THEN + IF (Buf[1] = '`') THEN + BEGIN + Buf := Copy(Buf,2,(Length(Buf) - 1)); + Counter := Pos('`',Buf); + IF (Counter <> 0) THEN + BEGIN + Cmd := AllCaps(Copy(Buf,1,(Counter - 1))); + Buf := Copy(Buf,(Counter + 1),(Length(Buf) - Counter)); + NL; + Exit; + END; + END; + + SHas0 := '?'; + SHas1 := ''; + Has0 := FALSE; + Has1 := FALSE; + Has2 := FALSE; + + + FOR CmdToExec := 1 TO NumCmds DO + IF ((CmdToExec <= (NumCmds - GlobalCmds)) OR NOT (NoGlobalUsed IN MemMenu.MenuFlags)) THEN + IF (AACS(MemCmd^[CmdToExec].ACS)) THEN + IF (MemCmd^[CmdToExec].CKeys[0] = #1) THEN + BEGIN + Has0 := TRUE; + SHas0 := SHas0 + MemCmd^[CmdToExec].CKeys; + END + ELSE IF ((MemCmd^[CmdToExec].CKeys[1] = '/') AND (MemCmd^[CmdToExec].CKeys[0] = #2)) THEN + BEGIN + Has1 := TRUE; + SHas1 := SHas1 + MemCmd^[CmdToExec].CKeys[2]; + END + ELSE + Has2 := TRUE; + + SaveCurrentColor := CurrentColor; + + GotCmd := FALSE; + SS := ''; + + IF (Trapping) THEN + Flush(TrapFile); + + IF (NOT (HotKey IN ThisUser.Flags)) OR (ForceLine IN MemMenu.MenuFlags) THEN + InputMain(Cmd,60,[UpperOnly,NoLineFeed]) + ELSE + BEGIN + + REPEAT + + Key := GetKey; + IF (Key = F_UP) OR (Key = F_DOWN) OR (Key = F_LEFT) OR (Key = F_RIGHT) THEN + BEGIN + CASE Key OF + F_UP : IF (Pos(#255,MenuKeys) > 0) THEN + BEGIN + Cmd := 'UP_ARROW'; + GotCmd := TRUE; + Exit; + END; + F_DOWN : + IF (Pos(#254,MenuKeys) > 0) THEN + BEGIN + Cmd := 'DOWN_ARROW'; + GotCmd := TRUE; + Exit; + END; + F_LEFT : + IF (Pos(#253,MenuKeys) > 0) THEN + BEGIN + Cmd := 'LEFT_ARROW'; + GotCmd := TRUE; + Exit; + END; + F_RIGHT : + IF (Pos(#252,MenuKeys) > 0) THEN + BEGIN + Cmd := 'RIGHT_ARROW'; + GotCmd := TRUE; + Exit; + END; + END; + END; + + C := UpCase(Char(Key)); + SaveSS := SS; + IF (SS = '') THEN + BEGIN + IF (C = #13) THEN + GotCmd := TRUE; + IF ((C = '/') AND ((Has1) OR (Has2) OR (SysOp))) THEN + SS := '/'; + IF (((FQArea) OR (RQArea) OR (MQArea) OR (VQArea)) AND (C IN ['0'..'9'])) THEN + BEGIN + SS := C; + IF (RQArea) AND (HiMsg <= 9) THEN + GotCmd := TRUE + ELSE IF (FQArea) AND (NumFileAreas <= 9) THEN + GotCmd := TRUE + ELSE IF (MQArea) AND (NumMsgAreas <= 9) THEN + GotCmd := TRUE + ELSE IF (VQArea) AND (GetTopics <= 9) THEN + GotCmd := TRUE; + END + ELSE IF (Pos(C,SHas0) <> 0) THEN + BEGIN + GotCmd := TRUE; + SS := C; + END; + END + ELSE IF (SS = '/') THEN + BEGIN + IF (C = ^H) THEN + SS := ''; + IF ((C = '/') AND ((Has2) OR (SysOp))) THEN + SS := SS + '/'; + IF ((Pos(C,SHas1) <> 0) AND (Has1)) THEN + BEGIN + GotCmd := TRUE; + SS := SS + C; + END; + END + ELSE IF (Copy(SS,1,2) = '//') THEN + BEGIN + IF (C = #13) THEN + GotCmd := TRUE + ELSE IF (C = ^H) THEN + Dec(SS[0]) + ELSE IF (C = ^X) THEN + BEGIN + FOR Counter := 1 TO (Length(SS) - 2) DO + BackSpace; + SS := '//'; + SaveSS := SS; + END + ELSE IF ((Length(SS) < 62) AND (C >= #32) AND (C <= #127)) THEN + SS := SS + C; + END + ELSE IF ((Length(SS) >= 1) AND (SS[1] IN ['0'..'9']) AND ((FQArea) OR (RQArea) OR (MQArea) OR (VQArea))) THEN + BEGIN + IF (C = ^H) THEN + Dec(SS[0]); + IF (C = #13) THEN + GotCmd := TRUE; + IF (C IN ['0'..'9']) THEN + BEGIN + SS := SS + C; + IF (VQArea) AND (Length(SS) = Length(IntToStr(GetTopics))) THEN + GotCmd := TRUE + ELSE IF (RQArea) AND (Length(SS) = Length(IntToStr(HiMsg))) THEN + GotCmd := TRUE + ELSE IF (MQArea) AND (Length(SS) = Length(IntToStr(NumMsgAreas))) THEN + GotCmd := TRUE + ELSE IF (FQArea) AND (Length(SS) = Length(IntToStr(NumFileAreas))) THEN + GotCmd := TRUE; + END; + END; + + IF ((Length(SS) = 1) AND (Length(SaveSS) = 2)) THEN + SetC(SaveCurrentColor); + + IF (SaveSS <> SS) AND (NOT (NoMenuPrompt IN MemMenu.MenuFlags)) THEN + BEGIN + IF (Length(SS) > Length(SaveSS)) THEN + Prompt(SS[Length(SS)]); + IF (Length(SS) < Length(SaveSS)) THEN + BackSpace; + END; + + IF ((NOT (SS[1] IN ['0'..'9'])) AND ((Length(SS) = 2) AND (Length(SaveSS) = 1))) THEN + UserColor(6); + + UNTIL ((GotCmd) OR (HangUp)); + + CursorOn(TRUE); + + UserColor(1); + + IF (Copy(SS,1,2) = '//') THEN + SS := Copy(SS,3,(Length(SS) - 2)); + + Cmd := SS; + END; + + (* Test *) + IF (CurMenu <> General.FileListingMenu) THEN + NL; + + IF (Pos(';',Cmd) <> 0) THEN + IF (Copy(Cmd,1,2) <> '\\') THEN + BEGIN + IF (HotKey IN ThisUser.Flags) THEN + BEGIN + S1 := Copy(Cmd,2,(Length(Cmd) - 1)); + IF (Copy(S1,1,1) = '/') THEN + Cmd := Copy(S1,1,2) + ELSE + Cmd := S1[1]; + S1 := Copy(S1,(Length(Cmd) + 1),(Length(S1) - Length(Cmd))); + END + ELSE + BEGIN + S1 := Copy(Cmd,(Pos(';',Cmd) + 1),(Length(Cmd) - Pos(';',Cmd))); + Cmd := Copy(Cmd,1,(Pos(';',Cmd) - 1)); + END; + WHILE (Pos(';',S1) <> 0) DO + S1[Pos(';',S1)] := ^M; + Buf := S1; + END; +END; + +PROCEDURE MainMenuHandle(VAR Cmd: AStr); +VAR + NewArea: Integer; +BEGIN + TLeft; + + CheckForceLevel; + + IF ((ForcePause IN MemMenu.MenuFlags) AND (CurHelpLevel > 1) AND (LastCommandGood)) THEN + PauseScr(FALSE); + LastCommandGood := FALSE; + MenuAborted := FALSE; + Abort := FALSE; + + ShowThisMenu; + + AutoExecCmd('EVERYTIME'); + + IF (General.MultiNode) THEN + Check_Status; + + IF ((NOT (NoMenuPrompt IN MemMenu.MenuFlags)) AND (NOT MenuAborted)) AND NOT + (OKAnsi AND (NoGenericAnsi IN MemMenu.MenuFlags) AND NOT (OkAvatar OR OKRIP)) AND NOT + (OkAvatar AND (NoGenericAvatar IN MemMenu.MenuFlags) AND NOT OkRIP) AND NOT + (OkRIP AND (NoGenericRIP IN MemMenu.MenuFlags)) THEN + BEGIN + + IF (CurMenu <> General.FileListingMenu) THEN + NL; + + IF (AutoTime IN MemMenu.MenuFlags) THEN + Print('^3[Time Left:'+CTim(NSL)+']'); + Prompt(MemMenu.MenuPrompt); + END; + + TempPause := (Pause IN ThisUser.Flags); + + GetCmd(Cmd); + + IF (Cmd = '') AND (Pos(#13,MenuKeys) > 0) THEN + Cmd := 'ENTER'; + + IF (Cmd = '?') THEN + BEGIN + Cmd := ''; + Inc(CurHelpLevel); + IF (CurHelpLevel > 3) THEN + CurHelpLevel := 3; + END + ELSE + CheckHelpLevel; + + CheckForceLevel; + + IF (FQArea) OR (MQArea) OR (VQArea) OR (RQArea) THEN + BEGIN + NewArea := StrToInt(Cmd); + IF ((NewArea <> 0) OR (Cmd[1] = '0')) THEN + BEGIN + IF (FQArea) AND (NewArea >= 1) AND (NewArea <= NumFileAreas) THEN + ChangeFileArea(CompFileArea(NewArea,1)) + ELSE IF (MQArea) AND (NewArea >= 1) AND (NewArea <= NumMsgAreas) THEN + ChangeMsgArea(CompMsgArea(NewArea,1)) + ELSE IF (VQArea) AND (NewArea >= 1) AND (NewArea <= NumVotes) THEN + VoteOne(NewArea) + ELSE IF (RQArea) AND (NewArea >= 1) AND (NewArea <= HiMsg) THEN + IF NOT (MAForceRead IN MemMsgArea.MAFlags) OR (NewArea <= Msg_On) THEN + BEGIN + Msg_On := (NewArea - 1); + TReadPrompt := 18; + END + ELSE + Print('You must read all of the messages in this area.'); + Cmd := ''; + END; + END; +END; + +PROCEDURE FCmd(CONST Cmd: AStr; VAR CmdToExec: Byte; VAR CmdExists,CmdNotHid: Boolean); +VAR + Done: Boolean; +BEGIN + Done := FALSE; + REPEAT + Inc(CmdToExec); + IF (CmdToExec <= NumCmds) AND (Cmd = MemCmd^[CmdToExec].CKeys) THEN + BEGIN + CmdExists := TRUE; + IF (OkSecurity(CmdToExec,CmdNotHid)) THEN + Done := TRUE; + END; + IF ((CmdToExec > (NumCmds - GlobalCmds)) AND (NoGlobalUsed IN MemMenu.MenuFlags)) THEN + BEGIN + CmdToExec := 0; + CmdExists := FALSE; + Done := TRUE; + END; + UNTIL (CmdToExec > NumCmds) OR (Done) OR (HangUp); + IF (CmdToExec > NumCmds) THEN + CmdToExec := 0; +END; + +PROCEDURE DoMenuExec(Cmd: AStr; VAR NewMenuCmd: AStr); +VAR + CmdToExec: Byte; + CmdACS, + CmdNotHid, + CmdExists, + Done: Boolean; +BEGIN + IF (NewMenuCmd <> '') THEN + BEGIN + Cmd := NewMenuCmd; + NewMenuCmd := ''; + END; + CmdACS := FALSE; + CmdExists := FALSE; + CmdNotHid := FALSE; + Done := FALSE; + CmdToExec := 0; + REPEAT + FCmd(Cmd,CmdToExec,CmdExists,CmdNotHid); + IF (CmdToExec <> 0) THEN + BEGIN + CmdACS := TRUE; + DoMenuCommand(Done, + MemCmd^[CmdToExec].CmdKeys, + MemCmd^[CmdToExec].Options, + NewMenuCmd, + MemCmd^[CmdToExec].NodeActivityDesc); + END; + UNTIL ((CmdToExec = 0) OR (Done) OR (HangUp)); + IF (NOT Done) AND (Cmd <> '') THEN + IF ((NOT CmdACS) AND (Cmd <> '')) THEN + BEGIN + NL; + IF ((CmdNotHid) AND (CmdExists)) THEN + Print('Insufficient clearence for this command.') + ELSE + Print('Invalid command.'); + END; +END; + +PROCEDURE DoMenuCommand(VAR Done: Boolean; + Cmd, + MenuOption: AStr; + VAR NewMenuCmd: AStr; + NodeActivityDesc: AStr); +VAR + MHeader: MHeaderRec; + TempStr: AStr; + SaveMenu: Byte; + NoCmd: Boolean; +BEGIN + NewMenuToLoad := FALSE; + NewMenuCmd := ''; + NoCmd := FALSE; + Abort := FALSE; + LastCommandOvr := FALSE; + + IF ((Cmd[1] + Cmd[2]) <> 'NW') THEN + Update_Node(NodeActivityDesc,TRUE); + + CASE Cmd[1] OF + '$' : CASE Cmd[2] OF + 'D' : Deposit; + 'W' : Withdraw; + '+' : Inc(ThisUser.lCredit,StrToInt(MenuOption)); + '-' : Inc(ThisUser.Debit,StrToInt(MenuOption)); + ELSE + NoCmd := TRUE; + END; + '/' : CASE Cmd[2] OF + 'F': BEGIN + MCIAllowed := FALSE; + PrintF(MCI(MenuOption)); + MCIAllowed := TRUE; + END; + ELSE + NoCmd := TRUE; + END; + '-' : CASE Cmd[2] OF + 'C' : lStatus_Screen(100,MenuOption,FALSE,MenuOption); + 'F' : PrintF(MCI(MenuOption)); + 'L' : Prompt(MenuOption); + 'Q' : ReadQ(General.MiscPath+MenuOption); + 'R' : ReadASW1(MenuOption); + 'S' : SysOpLog(MCI(MenuOption)); + ';' : BEGIN + TempStr := MenuOption; + WHILE (Pos(';',TempStr) > 0) DO + TempStr[Pos(';',TempStr)] := ^M; + Buf := TempStr; + END; + '$' : IF (SemiCmd(MenuOption,1) <> '') THEN + BEGIN + IF (SemiCmd(MenuOption,2) = '') THEN + Prt(': ') + ELSE + Prt(SemiCmd(MenuOption,2)); + GetPassword(TempStr,20); + IF (TempStr <> SemiCmd(MenuOption,1)) THEN + BEGIN + Done := TRUE; + IF (SemiCmd(MenuOption,3) <> '') THEN + Print(SemiCmd(MenuOption,3)); + END; + END; + 'Y' : IF (SemiCmd(MenuOption,1) <> '') AND NOT (PYNQ(SemiCmd(MenuOption,1),0,FALSE)) THEN + BEGIN + Done := TRUE; + IF (SemiCmd(MenuOption,2) <> '') THEN + Print(SemiCmd(MenuOption,2)); + END; + 'N' : IF (SemiCmd(MenuOption,1) <> '') AND (PYNQ(SemiCmd(MenuOption,1),0,FALSE)) THEN + BEGIN + Done := TRUE; + IF (SemiCmd(MenuOption,2) <> '') THEN + Print(SemiCmd(MenuOption,2)); + END; + '^','/','\' : + DoChangeMenu(Done,NewMenuCmd,Cmd[2],MenuOption); + ELSE + NoCmd := TRUE; + END; + '1' : CASE Cmd[2] OF + 'L' : DoOneLiners; + END; + 'A' : CASE Cmd[2] OF + 'A','C','M','T' : + DoArcCommand(Cmd[2]); + 'E' : ExtractToTemp; + 'G' : UserArchive; + 'R' : ReZipStuff; + ELSE + NoCmd := TRUE; + END; + 'B' : CASE Cmd[2] OF + '?' : BatchDLULInfo; + + 'C' : IF (UpCase(MenuOption[1]) = 'U') THEN + ClearBatchULQueue + ELSE + ClearBatchDLQueue; + 'D' : BatchDownload; + 'L' : IF (UpCase(MenuOption[1]) = 'U') THEN + ListBatchULFiles + ELSE + ListBatchDLFiles; + 'R' : IF (UpCase(MenuOption[1]) = 'U') THEN + RemoveBatchULFiles + ELSE + RemoveBatchDLFiles; + + 'U' : BatchUpload(FALSE,0); + ELSE + NoCmd := TRUE; + END; + 'D' : CASE Cmd[2] OF + 'P','C','D','G','S','W','-','3' : + DoDoorFunc(Cmd[2],MenuOption); + ELSE + NoCmd := TRUE; + END; + 'F' : CASE Cmd[2] OF + 'A' : FileAreaChange(Done,MenuOption); + 'B' : DownloadFile(MenuOption,[lIsAddDLBatch]); + 'C' : CheckFilesBBS; + 'D' : DownloadFile(MenuOption,[]); + 'F' : SearchFileDescriptions; + 'L' : ListFileSpec(MenuOption); + 'N' : NewFilesScanSearchType(MenuOption); + 'P' : SetFileAreaNewScanDate; + 'S' : SearchFileSpec; + 'U' : UploadFile; + 'V' : ViewDirInternalArchive; + 'Z' : ToggleFileAreaScanFlags; + '@' : CreateTempDir; + '#' : BEGIN + NL; + Print('Enter the number of a file area to change to.'); + IF (Novice IN ThisUser.Flags) THEN + PauseScr(FALSE); + END; + ELSE + NoCmd := TRUE; + END; + 'H' : CASE Cmd[2] OF + 'C' : IF PYNQ(MenuOption,0,FALSE) THEN + BEGIN + CLS; + PrintF('LOGOFF'); + HangUp := TRUE; + HungUp := FALSE; + END; + 'I' : HangUp := TRUE; + 'M' : BEGIN + NL; + Print(MenuOption); + HangUp := TRUE; + END; + ELSE + NoCmd := TRUE; + END; + 'L' : CASE Cmd[2] OF + '1' : TFilePrompt := 1; + '2' : TFilePrompt := 2; + '3' : TFilePrompt := 3; + '4' : TFilePrompt := 4; + '5' : TFilePrompt := 5; + '6' : TFilePrompt := 6; + '7' : TFilePrompt := 7; + '8' : TFilePrompt := 8; + ELSE + NoCmd := TRUE; + END; + 'M' : CASE Cmd[2] OF + 'A' : MessageAreaChange(Done,MenuOption); + 'E' : SSMail(MenuOption); + 'K' : ShowEMail; + 'L' : SMail(TRUE); + 'M' : ReadMail; + 'N' : StartNewScan(MenuOption); + 'P' : IF (ReadMsgArea = -1) THEN + BEGIN + NL; + Print('^7This option is not available when reading private messages!^1'); + END + ELSE + BEGIN + IF (MAPrivate IN MemMsgArea.MAFlags) THEN + BEGIN + NL; + Post(-1,MHeader.From,PYNQ('Is this to be a private message? ',0,FALSE)) + END + ELSE + Post(-1,MHeader.From,FALSE); + END; + 'R' : ReadAllMessages(MenuOption); + 'S' : BEGIN + Abort := FALSE; + Next := FALSE; + ScanMessages(MsgArea,FALSE,MenuOption); + END; + 'U' : BEGIN + LoadMsgArea(MsgArea); + UList(MemMsgArea.ACS); + END; + 'Y' : ScanYours; + 'Z' : ToggleMsgAreaScanFlags; + '#' : BEGIN + NL; + Print('Enter the number of a message area to change to.'); + IF (Novice IN ThisUser.Flags) THEN + PauseScr(FALSE); + END; + ELSE + NoCmd := TRUE; + END; + 'N' : CASE Cmd[2] OF + 'A' : ToggleChatAvailability; + 'D' : Dump_Node; + 'O' : BEGIN + LListNodes; + IF (Novice IN ThisUser.Flags) THEN + PauseScr(FALSE); + END; + 'P' : Page_User; + 'G' : MultiLine_Chat; + 'S' : LSend_Message(MenuOption); + 'T' : IF AACS(General.Invisible) THEN + BEGIN + IsInvisible := NOT IsInvisible; + LoadNode(ThisNode); + IF (IsInvisible) THEN + Include(NodeR.Status,NInvisible) + ELSE + Exclude(NodeR.Status,NInvisible); + SaveNode(ThisNode); + NL; + Print('Invisible mode is now '+ShowOnOff(IsInvisible)); + END; + (* Consider deleting this cmd *) + 'W' : BEGIN + LoadNode(ThisNode); + NodeR.ActivityDesc := MenuOption; + SaveNode(ThisNode); + END; + ELSE + NoCmd := TRUE; + END; + 'O' : CASE Cmd[2] OF + '1','2' : + TShuttleLogon := Ord(Cmd[2]) - 48; + 'A' : AutoValidationCmd(MenuOption); + 'B' : GetUserStats(MenuOption); + 'C' : RequestSysOpChat(MenuOption); + 'F' : ChangeARFlags(MenuOption); + 'G' : ChangeACFlags(MenuOption); + 'L' : BEGIN + IF (Pos(';',MenuOption) > 0) THEN + BEGIN + MenuOption := Copy(MenuOption,Pos(';',MenuOption) + 1,(Length(MenuOption)) - (Pos(';',MenuOption))); + TempStr := Copy(MenuOption,1,(Pos(';',MenuOption) - 1)); + END + ELSE + TempStr := '0'; + TodaysCallers(StrToInt(TempStr),MenuOption); + END; + 'P' : CStuff(StrToInt(MenuOption),2,ThisUser); + 'R' : ChangeConference(MenuOption); + 'S' : Bulletins(MenuOption); + 'U' : UList(MenuOption); + ELSE + NoCmd := TRUE; + END; + 'Q' : CASE Cmd[2] OF + 'Q' : RGQuote(MenuOption); + ELSE + NoCmd := TRUE; + END; + 'R' : CASE Cmd[2] OF + '#' : BEGIN + NL; + Print('Enter the number of a message to read it.'); + END; + 'A' : TReadPrompt := 1; + '-' : IF (Msg_On > 1) THEN + TReadPrompt := 2 + ELSE + BEGIN + NL; + Print('You are already at the first message.'); + END; + 'M' : TReadPrompt := 3; + 'X' : TReadPrompt := 4; + 'E' : TReadPrompt := 5; + 'R' : TReadPrompt := 6; + 'I' : IF (NOT (MAForceRead IN MemMsgArea.MAFlags)) OR (CoSysOp) THEN + TReadPrompt := 7 + ELSE + Print('You must read all of the messages in this area.'); + 'B' : TReadPrompt := 8; + 'F' : TReadPrompt := 9; + 'C' : TReadPrompt := 10; + 'D' : TReadPrompt := 11; + 'H' : TReadPrompt := 12; + 'G' : IF (NOT (MAForceRead IN MemMsgArea.MAFlags)) OR (CoSysOp) THEN + TReadPrompt := 13 + ELSE + Print('^7You must read all of the messages in this area!^1'); + 'Q' : IF (NOT (MAForceRead IN MemMsgArea.MAFlags)) OR (CoSysOp) THEN + TReadPrompt := 14 + ELSE + Print('^7You must read all of the messages in this area!^1'); + 'L' : TReadPrompt := 15; + 'U' : TReadPrompt := 16; + 'T' : TReadPrompt := 17; + 'N' : TReadPrompt := 18; + 'S' : TReadPrompt := 19; + 'V' : TReadPrompt := 20; + 'J' : TReadPrompt := 21; + ELSE + NoCmd := TRUE; + END; + 'U' : CASE Cmd[2] OF + 'A' : ReplyAutoMsg; + 'R' : ReadAutoMsg; + 'W' : WriteAutoMsg; + ELSE + NoCmd := TRUE; + END; + 'V' : CASE Cmd[2] OF + '#' : BEGIN + NL; + Print('Enter the number of the topic to vote on.'); + IF (Novice IN ThisUser.Flags) THEN + PauseScr(FALSE); + END; + 'A' : AddTopic; + 'L' : ListTopics(TRUE); + 'R' : Results(FALSE); + 'T' : TrackUser; + 'U' : Results(TRUE); + 'V' : VoteAll; + ELSE + NoCmd := TRUE; + END; + 'T' : CASE Cmd[2] OF + 'A' : BBSList_Add; + 'E' : BBSList_Edit; + 'D' : BBSList_Delete; + 'V' : BBSList_View; + 'X' : BBSList_xView; + ELSE + NoCmd := TRUE; + END; + '!' : CASE Cmd[2] OF + 'P' : SetMessageAreaNewScanDate; + 'D' : DownloadPacket; + 'U' : UploadPacket(FALSE); + ELSE + NoCmd := TRUE; + END; + '*' : CASE Cmd[2] OF + '=' : ShowCmds(MenuOption); + 'B' : IF (CheckPW) THEN + BEGIN + SysOpLog('* Message Area Editor'); + MessageAreaEditor; + END; + 'C' : IF (CheckPW) THEN + ChangeUser; + 'D' : IF (CheckPW) THEN + BEGIN + SysOpLog('* Entered Dos Emulator'); + MiniDOS; + END; + 'E' : IF (CheckPW) THEN + BEGIN + SysOpLog('* Event Editor'); + EventEditor; + END; + 'F' : IF (CheckPW) THEN + BEGIN + SysOpLog('* File Area Editor'); + FileAreaEditor; + END; + 'V' : IF (CheckPW) THEN + BEGIN + SysOpLog('* Vote Editor'); + VotingEditor; + END; + 'L' : IF (CheckPW) THEN + ShowLogs; + 'N' : TEdit1; + 'P' : IF (CheckPW) THEN + BEGIN + SysOpLog('* System Configuration Editor'); + SystemConfigurationEditor; + END; + 'R' : IF (CheckPW) THEN + BEGIN + SysOpLog('* Conference Editor'); + ConferenceEditor; + END; + 'T' : IF (CheckPW) THEN + BEGIN + mem[Seg0040:$0017] := mem[Seg0040:$0017] XOR 16; + IF (SysOpAvailable) THEN + BEGIN + SysOpLog('* Turned on chat availablity'); + END + ELSE + BEGIN + SysOpLog('* Turned off chat availablity'); + END; + END; + 'U' : IF (CheckPW) THEN + BEGIN + SysOpLog('* User Editor'); + UserEditor(UserNum); + END; + 'X' : IF (CheckPW) THEN + BEGIN + SysOpLog('* Protocol Editor'); + ProtocolEditor; + END; + 'Z' : BEGIN + SysOpLog('* History Editor'); + HistoryEditor; + END; + '1' : BEGIN + SysOpLog('* Edited Files'); + EditFiles; + END; + '2' : BEGIN + SysOpLog('* Sorted Files'); + Sort; + END; + '3' : IF (CheckPW) THEN + BEGIN + SysOpLog('* Read Private Messages'); + ReadAllMessages(''); + END; + '4' : IF (MenuOption = '') THEN + Do_Unlisted_Download + ELSE + UnlistedDownload(MenuOption); + '5' : BEGIN + SysOpLog('* Rechecked files'); + ReCheck; + END; + '6' : IF (CheckPW) THEN + UploadAll; + '7' : ValidateFiles; + '8' : AddGIFSpecs; + '9' : PackMessageAreas; + '#' : IF (CheckPW) THEN + BEGIN + SysOpLog('* Menu Editor'); + SaveMenu := CurMenu; + MenuEditor; + CurMenu := SaveMenu; + LoadMenu; + END; + '$' : DirF(TRUE); + '%' : DirF(FALSE); + ELSE + NoCmd := TRUE; + END; + ELSE + NoCmd := TRUE; + END; + LastCommandGood := NOT NoCmd; + IF (LastCommandOvr) THEN + LastCommandGood := FALSE; + IF (NoCmd) THEN + IF (CoSysOp) THEN + BEGIN + TempStr := 'Invalid command keys: '+Cmd[1]+Cmd[2]+' '+Cmd; + NL; + Print(TempStr); + SysOpLog(TempStr); + END; + + IF ((Cmd[1] + Cmd[2]) <> 'NW') THEN + Update_Node('',FALSE); + + IF (NewMenuToLoad) THEN + BEGIN + LoadMenuPW; + LastCommandGood := FALSE; + IF (NewMenuCmd = '') THEN + AutoExecCmd('FIRSTCMD'); + END; +END; + +END. diff --git a/SOURCE/MENUS2.PAS b/SOURCE/MENUS2.PAS new file mode 100644 index 0000000..4b483f4 --- /dev/null +++ b/SOURCE/MENUS2.PAS @@ -0,0 +1,518 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Menus2; + +INTERFACE + +USES + Common; + +PROCEDURE LoadMenu; +PROCEDURE ShowCmds(MenuOption: Str50); +FUNCTION OkSecurity(CmdToExec: Byte; VAR CmdNotHid: Boolean): Boolean; +PROCEDURE GenericMenu(ListType: Byte); +PROCEDURE ShowThisMenu; + +IMPLEMENTATION + +PROCEDURE LoadMenu; +VAR + Counter, + MenuNum: Integer; + TempCkeys: CHAR; + FoundMenu: Boolean; +BEGIN + IF (GlobalCmds > 0) THEN + Move(MemCmd^[((NumCmds - GlobalCmds) + 1)],MemCmd^[((MaxCmds - GlobalCmds) + 1)],(GlobalCmds * Sizeof(MemCmdRec))); + NumCmds := 0; + FoundMenu := FALSE; + Reset(MenuFile); + MenuNum := 1; + WHILE (MenuNum <= NumMenus) AND (NOT FoundMenu) DO + BEGIN + Seek(MenuFile,MenuRecNumArray[MenuNum]); + Read(MenuFile,MenuR); + IF (MenuR.MenuNum = CurMenu) THEN + BEGIN + FallBackMenu := MenuR.FallBack; + FoundMenu := TRUE; + END; + Inc(MenuNum); + END; + Dec(MenuNum); + IF (NOT FoundMenu) THEN + BEGIN + NL; + Print('That menu is missing, dropping to fallback ...'); + SysOpLog('Menu #'+IntToStr(CurMenu)+' is missing - Dropping to FallBack #'+IntToStr(FallBackMenu)); + IF (FallBackMenu > 0) THEN + BEGIN + FoundMenu := FALSE; + MenuNum := 1; + WHILE (MenuNum <= NumMenus) AND (NOT FoundMenu) DO + BEGIN + Seek(MenuFile,MenuRecNumArray[MenuNum]); + Read(MenuFile,MenuR); + IF (MenuR.MenuNum = FallBackMenu) THEN + BEGIN + CurMenu := FallBackMenu; + FallBackMenu := MenuR.FallBack; + FoundMenu := TRUE; + END; + Inc(MenuNum); + END; + Dec(MenuNum); + END; + IF (FallBackMenu = 0) OR (NOT FoundMenu) THEN + BEGIN + NL; + Print('Emergency System shutdown. Please call back later.'); + NL; + Print('Critical error; hanging up.'); + IF (FallBackMenu = 0) THEN + SysOpLog('FallBack menu is set to ZERO - Hung user up.') + ELSE + SysOpLog('FallBack #'+IntToStr(FallBackMenu)+' is MISSING - Hung user up.'); + HangUp := TRUE; + END; + END; + IF (FoundMenu) THEN + BEGIN + Seek(MenuFile,MenuRecNumArray[MenuNum]); + Read(MenuFile,MenuR); + WITH MemMenu DO + BEGIN + FOR Counter := 1 TO 3 DO + LDesc[Counter] := MenuR.LDesc[Counter]; + ACS := MenuR.ACS; + NodeActivityDesc := MenuR.NodeActivityDesc; + MenuFlags := MenuR.MenuFlags; + LongMenu := MenuR.LongMenu; + MenuNum := MenuR.MenuNum; + MenuPrompt := MenuR.MenuPrompt; + Password := MenuR.Password; + FallBack := MenuR.FallBack; + Directive := MenuR.Directive; + ForceHelpLevel := MenuR.ForceHelpLevel; + GenCols := MenuR.GenCols; + FOR Counter := 1 TO 3 DO + GCol[Counter] := MenuR.GCol[Counter]; + END; + + Update_Node(MemMenu.NodeActivityDesc,TRUE); + + MQArea := FALSE; + FQArea := FALSE; + VQArea := FALSE; + RQArea := FALSE; + MenuKeys := ''; + NumCmds := 1; + WHILE (NumCmds <= CmdNumArray[MenuNum]) DO + BEGIN + Read(MenuFile,MenuR); + WITH MemCmd^[NumCmds] DO + BEGIN + LDesc := MenuR.LDesc[1]; + ACS := MenuR.ACS; + NodeActivityDesc := MenuR.NodeActivityDesc; + CmdFlags := MenuR.CmdFlags; + SDesc := MenuR.SDesc; + CKeys := MenuR.CKeys; + IF (CKeys = 'ENTER') THEN + TempCkeys := #13 + ELSE IF (CKeys = 'UP_ARROW') THEN + TempCkeys := #255 + ELSE IF (CKeys = 'DOWN_ARROW') THEN + TempCkeys := #254 + ELSE IF (CKeys = 'LEFT_ARROW') THEN + TempCkeys := #253 + ELSE IF (CKeys = 'RIGHT_ARROW') THEN + TempCkeys := #252 + ELSE IF (Length(CKeys) > 1) THEN + TempCkeys := '/' + ELSE + TempCkeys := UpCase(CKeys[1]); + IF (Pos(TempCkeys,MenuKeys) = 0) THEN + MenuKeys := MenuKeys + TempCkeys; + CmdKeys := MenuR.CmdKeys; + IF (CmdKeys = 'M#') THEN + MQArea := TRUE + ELSE IF (CmdKeys = 'F#') THEN + FQArea := TRUE + ELSE IF (CmdKeys = 'V#') THEN + VQArea := TRUE + ELSE IF (CmdKeys = 'R#') THEN + RQArea := TRUE; + Options := MenuR.Options; + END; + Inc(NumCmds); + END; + END; + Dec(NumCmds); + Close(MenuFile); + LastError := IOResult; + IF (GlobalCmds > 0) THEN + BEGIN + Move(MemCmd^[((MaxCmds - GlobalCmds) + 1)],MemCmd^[(NumCmds + 1)],(GlobalCmds * Sizeof(MemCmdRec))); + Inc(NumCmds,GlobalCmds); + END; +END; + +PROCEDURE ShowCmds(MenuOption: Str50); +VAR + TempStr, + TempStr1: AStr; + CmdToList, + Counter, + NumRows: Byte; + + FUNCTION Type1(CTL: Byte): AStr; + BEGIN + Type1 := '^0'+PadRightInt(CTL,3)+ + ' ^3'+PadLeftStr(MemCmd^[CTL].CKeys,2)+ + ' ^3'+PadLeftStr(MemCmd^[CTL].CmdKeys,2)+ + ' '+PadLeftStr(MemCmd^[CTL].Options,15); + END; + +BEGIN + IF (MenuOption = '') THEN + Exit; + IF (NumCmds = 0) THEN + Print('*** No commands on this menu ***') + ELSE + BEGIN + AllowAbort := TRUE; + MCIAllowed := FALSE; + Abort := FALSE; + Next := FALSE; + CLS; + NL; + CASE MenuOption[1] OF + '1' : BEGIN + PrintACR('^0###^4:^3KK ^4:^3CF^4:^3ACS ^4:^3CK^4:^3Options'); + PrintACR('^4===:==============:==:==========:==:========================================'); + CmdToList := 1; + WHILE (CmdToList <= NumCmds) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + PrintACR('^0'+PadRightInt(CmdToList,3)+ + ' ^3'+PadLeftStr(MemCmd^[CmdToList].CKeys,14)+ + ' '+AOnOff(Hidden IN MemCmd^[CmdToList].CmdFlags,'H','-')+ + AOnOff(UnHidden IN MemCmd^[CmdToList].CmdFlags,'U','-')+ + ' ^9'+PadLeftStr(MemCmd^[CmdToList].ACS,10)+ + ' ^3'+PadLeftStr(MemCmd^[CmdToList].CmdKeys,2)+ + ' '+PadLeftStr(MemCmd^[CmdToList].Options,40)); + Inc(CmdToList); + END; + END; + '2' : BEGIN + NumRows := ((NumCmds + 2) DIV 3); + TempStr := '^0###^4:^3KK^4:^3CK^4:^3Options '; + TempStr1 := '^4===:==:==:==============='; + CmdToList := 1; + WHILE (CmdToList <= NumRows) AND (CmdToList < 3) DO + BEGIN + TempStr := TempStr+' ^0###^4:^3KK^4:^3CK^4:^3Options '; + TempStr1 := TempStr1 + ' ^4===:==:==:==============='; + Inc(CmdToList); + END; + PrintACR(TempStr); + PrintACR(TempStr1); + CmdToList := 0; + REPEAT + Inc(CmdToList); + TempStr := Type1(CmdToList); + FOR Counter := 1 TO 2 DO + IF ((CmdToList + (Counter * NumRows)) <= NumCmds) THEN + TempStr := TempStr + ' '+Type1(CmdToList + (Counter * NumRows)); + PrintACR('^1'+TempStr); + UNTIL ((CmdToList >= NumRows) OR (Abort) OR (HangUp)); + END; + END; + AllowAbort := FALSE; + MCIAllowed := TRUE; + END; +END; + +FUNCTION OkSecurity(CmdToExec: Byte; VAR CmdNotHid: Boolean): Boolean; +BEGIN + OkSecurity := FALSE; + IF (UnHidden IN MemCmd^[CmdToExec].CmdFlags) THEN + CmdNotHid := TRUE; + IF (NOT AACS(MemCmd^[CmdToExec].ACS)) THEN + EXIT; + OkSecurity := TRUE; +END; + +PROCEDURE GenericMenu(ListType: Byte); +VAR + GColors: ARRAY [1..3] OF Byte; + Counter, + ColSiz, + NumCols: Byte; + + FUNCTION GenColored(CONST Keys: AStr; Desc: AStr; Acc: Boolean): AStr; + VAR + j: Byte; + BEGIN + j := Pos(AllCaps(Keys),AllCaps(Desc)); + IF (j <> 0) AND (Pos('^',Desc) = 0) THEN + BEGIN + Insert('^'+IntToStr(GColors[3]),Desc,((j + Length(Keys) + 1))); + Insert('^'+IntToStr(GColors[1]),Desc,j + Length(Keys)); + IF (acc) THEN + Insert('^'+IntToStr(GColors[2]),Desc,j); + IF (j <> 1) THEN + Insert('^'+IntToStr(GColors[1]),Desc,j - 1); + END; + GenColored := '^'+IntToStr(GColors[3])+Desc; + END; + + FUNCTION TCentered(c: Integer; CONST s: AStr): AStr; + CONST + SpaceStr = ' '; + BEGIN + c := (c DIV 2) - (LennMCI(s) DIV 2); + IF (c < 1) THEN + c := 0; + TCentered := Copy(SpaceStr,1,c) + s; + END; + + PROCEDURE NewGColors(CONST S: STRING); + VAR + TempStr: STRING; + BEGIN + TempStr := SemiCmd(s,1); + IF (TempStr <> '') THEN + GColors[1] := StrToInt(TempStr); + TempStr := SemiCmd(s,2); + IF (TempStr <> '') THEN + GColors[2] := StrToInt(TempStr); + TempStr := SemiCmd(s,3); + IF (TempStr <> '') THEN + GColors[3] := StrToInt(TempStr); + END; + + PROCEDURE GetMaxRight(VAR MaxRight: Byte); + VAR + CmdToList, + Len, + Onlin: Byte; + TempStr: AStr; + BEGIN + MaxRight := 0; + OnLin := 0; + TempStr := ''; + FOR CmdToList := 1 TO NumCmds DO + IF (MemCmd^[CmdToList].CKeys <> 'GTITLE') THEN + BEGIN + Inc(OnLin); + IF (OnLin <> NumCols) THEN + TempStr := TempStr + PadLeftStr(MemCmd^[CmdToList].SDesc,ColSiz) + ELSE + BEGIN + TempStr := TempStr + MemCmd^[CmdToList].SDesc; + OnLin := 0; + Len := LennMCI(TempStr); + IF (Len > MaxRight) THEN + MaxRight := Len; + TempStr := ''; + END; + END + ELSE + BEGIN + TempStr := ''; + OnLin := 0; + END; + END; + + PROCEDURE DoMenuTitles(MaxRight: Byte); + VAR + Counter1: Byte; + ShownAlready: Boolean; + BEGIN + IF (ClrScrBefore IN MemMenu.MenuFlags) THEN + BEGIN + CLS; + NL; + NL; + END; + IF (NOT (NoMenuTitle IN MemMenu.MenuFlags)) THEN + BEGIN + ShownAlready := FALSE; + FOR Counter1 := 1 TO 3 DO + IF (MemMenu.LDesc[Counter1] <> '') THEN + BEGIN + IF (NOT ShownAlready) THEN + BEGIN + NL; + ShownAlready := TRUE; + END; + IF (DontCenter IN MemMenu.MenuFlags) THEN + PrintACR(MemMenu.LDesc[Counter1]) + ELSE + PrintACR(TCentered(MaxRight,MemMenu.LDesc[Counter1])); + END; + END; + NL; + END; + + PROCEDURE GenTuto; + VAR + CmdToList, + MaxRight: Byte; + Acc, + CmdNotHid: Boolean; + BEGIN + Abort := FALSE; + Next := FALSE; + GetMaxRight(MaxRight); + DoMenuTitles(MaxRight); + IF (NoGlobalDisplayed IN MemMenu.MenuFlags) OR (NoGlobalUsed IN MemMenu.MenuFlags) THEN + Dec(NumCmds,GlobalCmds); + CmdToList := 0; + WHILE (CmdToList < NumCmds) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Inc(CmdToList); + CmdNotHid := FALSE; + Acc := OkSecurity(CmdToList,CmdNotHid); + IF (((Acc) OR (UnHidden IN MemCmd^[CmdToList].CmdFlags)) AND (NOT (Hidden IN MemCmd^[CmdToList].CmdFlags))) THEN + IF (MemCmd^[CmdToList].CKeys = 'GTITLE') THEN + BEGIN + PrintACR(MemCmd^[CmdToList].LDesc); + IF (MemCmd^[CmdToList].Options <> '') THEN + NewGColors(MemCmd^[CmdToList].Options); + END + ELSE IF (MemCmd^[CmdToList].LDesc <> '') THEN + PrintACR(GenColored(MemCmd^[CmdToList].CKeys,MemCmd^[CmdToList].LDesc,Acc)); + END; + IF (NoGlobalDisplayed IN MemMenu.MenuFlags) OR (NoGlobalUsed IN MemMenu.MenuFlags) THEN + Inc(NumCmds,GlobalCmds); + END; + + PROCEDURE GenNorm; + VAR + TempStr, + TempStr1: AStr; + CmdToList, + Onlin, + MaxRight: Byte; + Acc, + CmdNotHid: Boolean; + BEGIN + TempStr1 := ''; + OnLin := 0; + TempStr := ''; + Abort := FALSE; + Next := FALSE; + GetMaxRight(MaxRight); + DoMenuTitles(MaxRight); + IF (NoGlobalDisplayed IN MemMenu.MenuFlags) OR (NoGlobalUsed IN MemMenu.MenuFlags) THEN + Dec(NumCmds,GlobalCmds); + CmdToList := 0; + WHILE (CmdToList < NumCmds) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Inc(CmdToList); + CmdNotHid := FALSE; + Acc := OkSecurity(CmdToList,CmdNotHid); + IF (((Acc) OR (UnHidden IN MemCmd^[CmdToList].CmdFlags)) AND (NOT (Hidden IN MemCmd^[CmdToList].CmdFlags))) THEN + BEGIN + IF (MemCmd^[CmdToList].CKeys = 'GTITLE') THEN + BEGIN + IF (OnLin <> 0) THEN + PrintACR(TempStr); + PrintACR(TCentered(MaxRight,MemCmd^[CmdToList].LDesc)); + TempStr := ''; + OnLin := 0; + IF (MemCmd^[CmdToList].Options <> '') THEN + NewGColors(MemCmd^[CmdToList].Options); + END + ELSE + BEGIN + IF (MemCmd^[CmdToList].SDesc <> '') THEN + BEGIN + Inc(OnLin); + TempStr1 := GenColored(MemCmd^[CmdToList].CKeys,MemCmd^[CmdToList].SDesc,Acc); + IF (OnLin <> NumCols) THEN + TempStr1 := PadLeftStr(TempStr1,ColSiz); + TempStr := TempStr + TempStr1; + END; + IF (OnLin = NumCols) THEN + BEGIN + OnLin := 0; + PrintACR(TempStr); + TempStr := ''; + END; + END; + END; + END; + IF (NoGlobalDisplayed IN MemMenu.MenuFlags) OR (NoGlobalUsed IN MemMenu.MenuFlags) THEN + Inc(NumCmds,GlobalCmds); + IF (OnLin > 0) THEN + PrintACR(TempStr); + END; + +BEGIN + FOR Counter := 1 TO 3 DO + GColors[Counter] := MemMenu.GCol[Counter]; + NumCols := MemMenu.GenCols; + CASE NumCols OF + 2 : ColSiz := 39; + 3 : ColSiz := 25; + 4 : ColSiz := 19; + 5 : ColSiz := 16; + 6 : ColSiz := 12; + 7 : ColSiz := 11; + END; + IF ((NumCols * ColSiz) >= ThisUser.LineLen) THEN + NumCols := (ThisUser.LineLen DIV ColSiz); + DisplayingMenu := TRUE; + IF (ListType = 2) THEN + GenNorm + ELSE + GenTuto; + DisplayingMenu := FALSE; +END; + +PROCEDURE ShowThisMenu; +VAR + TempStr: AStr; +BEGIN + CASE CurHelpLevel OF + 2 : BEGIN + DisplayingMenu := TRUE; + NoFile := TRUE; + TempStr := MemMenu.Directive; + IF (TempStr <> '') THEN + BEGIN + IF (Pos('@S',TempStr) > 0) THEN + PrintF(Substitute(TempStr,'@S',IntToStr(ThisUser.SL))); + IF (NoFile) THEN + PrintF(Substitute(TempStr,'@S','')); + END; + DisplayingMenu := FALSE; + END; + 3 : BEGIN + DisplayingMenu := TRUE; + NoFile := TRUE; + TempStr := MemMenu.LongMenu; + IF (TempStr <> '') THEN + BEGIN + IF (Pos('@C',TempStr) <> 0) THEN + PrintF(Substitute(TempStr,'@C',CurrentConf)); + IF (NoFile) AND (Pos('@S',TempStr) <> 0) THEN + PrintF(Substitute(TempStr,'@S',IntToStr(ThisUser.SL))); + IF (NoFile) THEN + PrintF(Substitute(TempStr,'@S','')); + END; + DisplayingMenu := FALSE; + END; + END; + IF ((NoFile) AND (CurHelpLevel IN [2,3])) THEN + GenericMenu(CurHelpLevel); +END; + +END. diff --git a/SOURCE/MENUS3.PAS b/SOURCE/MENUS3.PAS new file mode 100644 index 0000000..e2f22c5 --- /dev/null +++ b/SOURCE/MENUS3.PAS @@ -0,0 +1,97 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT Menus3; + +INTERFACE + +USES + Common; + +PROCEDURE DoChangeMenu(VAR Done: BOOLEAN; VAR NewMenuCmd: ASTR; Cmd: CHAR; CONST MenuOption: Str50); + +IMPLEMENTATION + +PROCEDURE DoChangeMenu(VAR Done: BOOLEAN; VAR NewMenuCmd: ASTR; Cmd: CHAR; CONST MenuOption: Str50); +VAR + TempStr, + TempStr1: ASTR; +BEGIN + CASE Cmd OF + '^' : BEGIN + TempStr1 := MenuOption; + IF (Pos(';',TempStr1) <> 0) THEN + TempStr1 := Copy(TempStr1,1,(Pos(';',TempStr1) - 1)); + IF (MenuOption <> '') THEN + BEGIN + TempStr := MenuOption; + IF (Pos(';',TempStr) <> 0) THEN + TempStr := Copy(TempStr,(Pos(';',TempStr) + 1),Length(TempStr)); + IF (UpCase(TempStr[1]) = 'C') THEN + MenuStackPtr := 0; + IF (Pos(';',TempStr) = 0) OR (Length(TempStr) = 1) THEN + TempStr := '' + ELSE + TempStr := Copy(TempStr,(Pos(';',TempStr) + 1),Length(TempStr)); + END; + IF (TempStr1 <> '') THEN + BEGIN + CurMenu := StrToInt(TempStr1); + IF (TempStr <> '') THEN + NewMenuCmd := AllCaps(TempStr); + Done := TRUE; + NewMenuToLoad := TRUE; + END; + END; + '/' : BEGIN + TempStr1 := MenuOption; + IF (Pos(';',TempStr1) <> 0) THEN + TempStr1 := Copy(TempStr1,1,Pos(';',TempStr1) - 1); + IF ((MenuOption <> '') AND (MenuStackPtr <> MaxMenus)) THEN + BEGIN + TempStr := MenuOption; + IF (Pos(';',TempStr) <> 0) THEN + TempStr := Copy(TempStr,(Pos(';',TempStr) + 1),Length(TempStr)); + IF (UpCase(TempStr[1]) = 'C') THEN + MenuStackPtr := 0; + IF (Pos(';',TempStr) = 0) OR (Length(TempStr) = 1) THEN + TempStr := '' + ELSE + TempStr := Copy(TempStr,(Pos(';',TempStr) + 1),Length(TempStr)); + IF (CurMenu <> StrToInt(TempStr1)) THEN + BEGIN + Inc(MenuStackPtr); + MenuStack[MenuStackPtr] := CurMenu; + END + ELSE + TempStr1 := ''; + END; + IF (TempStr1 <> '') THEN + BEGIN + CurMenu := StrToInt(TempStr1); + IF (TempStr <> '') THEN + NewMenuCmd := AllCaps(TempStr); + Done := TRUE; + NewMenuToLoad := TRUE; + END; + END; + '\' : BEGIN + IF (MenuStackPtr <> 0) THEN + BEGIN + CurMenu := MenuStack[MenuStackPtr]; + Dec(MenuStackPtr); + END; + IF (UpCase(MenuOption[1]) = 'C') THEN + MenuStackPtr := 0; + IF (Pos(';',MenuOption) <> 0) THEN + NewMenuCmd := AllCaps(Copy(MenuOption,(Pos(';',MenuOption) + 1),Length(MenuOption))); + Done := TRUE; + NewMenuToLoad := TRUE; + END; + END; +END; + +END. diff --git a/SOURCE/MISC/ONELE.ANS b/SOURCE/MISC/ONELE.ANS new file mode 100644 index 0000000..dc8cad2 --- /dev/null +++ b/SOURCE/MISC/ONELE.ANS @@ -0,0 +1 @@ +%LF   %LF \ No newline at end of file diff --git a/SOURCE/MISC/ONELE.ASC b/SOURCE/MISC/ONELE.ASC new file mode 100644 index 0000000..258bb4f --- /dev/null +++ b/SOURCE/MISC/ONELE.ASC @@ -0,0 +1 @@ +%LF |15 |07 |08 |03 |11 |03 |08 |07 |15 %LF diff --git a/SOURCE/MISC/ONELH.ANS b/SOURCE/MISC/ONELH.ANS new file mode 100644 index 0000000..5601d68 --- /dev/null +++ b/SOURCE/MISC/ONELH.ANS @@ -0,0 +1,7 @@ +[?7h   +   +   +   +   + ۲ ۲ ۲ ۲ ۲ ۲ ۲ ۰  +   %LF diff --git a/SOURCE/MISC/ONELH.ASC b/SOURCE/MISC/ONELH.ASC new file mode 100644 index 0000000..59d3f03 --- /dev/null +++ b/SOURCE/MISC/ONELH.ASC @@ -0,0 +1,12 @@ + + + + + + ۰ ۰ ۰ ۰ ۰ ۰ ۰ + ۰ ۰ ۰ ۰ ۰ ۰ ۰ + ޲ ޱ ޱ ޲ ۰ ޱ ޲ ۰ rl + ܲ ܲ v! + + + diff --git a/SOURCE/MISC/ONELM.ASC b/SOURCE/MISC/ONELM.ASC new file mode 100644 index 0000000..529bf3b --- /dev/null +++ b/SOURCE/MISC/ONELM.ASC @@ -0,0 +1 @@ + |03~OL |11 ... |15~UN{16%LF diff --git a/SOURCE/MISCUSER.PAS b/SOURCE/MISCUSER.PAS new file mode 100644 index 0000000..bc6ca04 --- /dev/null +++ b/SOURCE/MISCUSER.PAS @@ -0,0 +1,266 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT MiscUser; + +INTERFACE + +USES + Common; + +PROCEDURE lFindUserWS(VAR UserNum: Integer); +PROCEDURE ChangeARFlags(MenuOption: Str50); +PROCEDURE ChangeACFlags(MenuOption: Str50); +PROCEDURE FindUser(VAR UserNum: Integer); +PROCEDURE InsertIndex(uname: AStr; UserNum: Integer; IsReal,IsDeleted: Boolean); + +IMPLEMENTATION + +USES + Dos; + +PROCEDURE lFindUserWS(VAR UserNum: Integer); +VAR + User: UserRecordType; + UserIDX: UserIDXRec; + UserName: AStr; + Cmd: Char; + Counter, + NumIDX: Integer; + Done, + Asked: Boolean; +BEGIN + MPL(36); + Input(UserName,36); + IF (UserName = 'SYSOP') THEN + UserName := '1'; + UserNum := StrToInt(UserName); + IF (UserNum > 0) THEN + BEGIN + IF (UserNum > (MaxUsers - 1)) THEN + BEGIN + NL; + Print('Unknown user.'); + UserNum := 0 + END + ELSE + LoadURec(User,UserNum); + END + ELSE IF (UserName = '') THEN + BEGIN + NL; + Print('Aborted.'); + END + ELSE + BEGIN + Done := FALSE; + Asked := FALSE; + UserNum := SearchUser(UserName,CoSysOp); + IF (UserNum > 0) THEN + Exit; + Reset(UserIDXFile); + Counter := 0; + NumIDX := FileSize(UserIDXFile); + WHILE (Counter < NumIDX) AND (NOT Done) DO + BEGIN + Read(UserIDXFile,UserIDX); + Inc(Counter); + IF NOT (UserIDX.Deleted) AND (Pos(UserName,UserIDX.Name) <> 0) AND ((NOT UserIDX.RealName) OR (CoSysOp)) THEN + IF ((UserIDX.Name = UserName) OR (CoSysOp AND (UserIDX.Name = UserName))) AND (UserIDX.number <= (MaxUsers - 1)) THEN + UserNum := UserIDX.Number + ELSE + BEGIN + IF (NOT Asked) THEN + BEGIN + NL; + Asked := TRUE; + END; + Prompt('^1Did you mean ^3'+Caps(UserIDX.Name)+'^1? '); + OneK(Cmd,'QYN'^M,TRUE,TRUE); + Done := TRUE; + CASE Cmd OF + 'Q' : UserNum := -1; + 'Y' : UserNum := UserIDX.Number; + ELSE + Done := FALSE; + END; + END; + END; + Close(UserIDXFile); + IF (UserNum = 0) THEN + BEGIN + NL; + Print('User not found.'); + END; + IF (UserNum = -1) THEN + UserNum := 0; + END; + LastError := IOResult; +END; + +PROCEDURE ChangeARFlags(MenuOption: Str50); +VAR + Counter: Byte; + Changed: Boolean; +BEGIN + MenuOption := AllCaps(MenuOption); + FOR Counter := 1 TO (Length(MenuOption) - 1) DO + CASE MenuOption[Counter] OF + '+' : IF (MenuOption[Counter + 1] IN ['A'..'Z']) THEN + Include(ThisUser.AR,MenuOption[Counter + 1]); + '-' : IF (MenuOption[Counter + 1] IN ['A'..'Z']) THEN + Exclude(ThisUser.AR,MenuOption[Counter + 1]); + '!' : IF (MenuOption[Counter + 1] IN ['A'..'Z']) THEN + ToggleARFlag((MenuOption[Counter + 1]),ThisUser.AR,Changed); + END; + NewCompTables; + Update_Screen; +END; + +PROCEDURE ChangeACFlags(MenuOption: Str50); +VAR + Counter: Byte; + Changed: Boolean; +BEGIN + MenuOption := AllCaps(MenuOption); + FOR Counter := 1 TO (Length(MenuOption) - 1) DO + CASE MenuOption[Counter] OF + '+' : Include(ThisUser.Flags,TACCH(MenuOption[Counter + 1])); + '-' : Exclude(ThisUser.Flags,TACCH(MenuOption[Counter + 1])); + '!' : ToggleACFlags(MenuOption[Counter + 1],ThisUser.Flags,Changed); + END; + NewCompTables; + Update_Screen; +END; + +PROCEDURE FindUser(VAR UserNum: Integer); +VAR + User: UserRecordType; + TempUserName: Str36; + TempUserNum: Integer; +BEGIN + UserNum := 0; + TempUserName := ''; + Input(TempUserName,36); + IF (TempUserName = 'NEW') THEN + BEGIN + UserNum := -1; + Exit; + END; + IF (TempUserName = '?') THEN + Exit; + WHILE (Pos(' ',TempUserName) <> 0) DO + Delete(TempUserName,Pos(' ',TempUserName),1); + WHILE (TempUserName[1] = ' ') AND (Length(TempUserName) > 0) DO + Delete(TempUserName,1,1); + IF (TempUserName = '') OR (HangUp) THEN + Exit; + UserNum := StrToInt(TempUserName); + IF (UserNum <> 0) THEN + BEGIN + IF (UserNum < 0) OR (UserNum > (MaxUsers - 1)) THEN + UserNum := 0 + ELSE + BEGIN + LoadURec(User,UserNum); + IF (Deleted IN User.SFlags) THEN + UserNum := 0; + END; + END + ELSE IF (TempUserName <> '') THEN + BEGIN + TempUserNum := SearchUser(TempUserName,TRUE); + IF (TempUserNum <> 0) THEN + BEGIN + LoadURec(User,TempUserNum); + IF (NOT (Deleted IN User.SFlags)) THEN + UserNum := TempUserNum + ELSE + UserNum := 0; + END; + END; +END; + +PROCEDURE InsertIndex(Uname: AStr; UserNum: Integer; IsReal,IsDeleted: Boolean); +VAR + UserIDX: UserIDXRec; + Current, + InsertAt: Integer; + SFO, + Done: Boolean; + + PROCEDURE WriteIndex; + BEGIN + WITH UserIDX DO + BEGIN + FillChar(UserIDX,SizeOf(UserIDX),0); + Name := Uname; + Number := UserNum; + RealName := IsReal; + Deleted := IsDeleted; + Left := -1; + Right := -1; + Write(UserIDXFile,UserIDX); + END + END; + +BEGIN + Done := FALSE; + Uname := AllCaps(Uname); + Current := 0; + SFO := (FileRec(UserIDXFile).Mode <> FMClosed); + IF (NOT SFO) THEN + Reset(UserIDXFile); + IF (FileSize(UserIDXFile) = 0) THEN + WriteIndex + ELSE + REPEAT + Seek(UserIDXFile,Current); + InsertAt := Current; + Read(UserIDXFile,UserIDX); + IF (Uname < UserIDX.Name) THEN + Current := UserIDX.Left + ELSE IF (Uname > UserIDX.Name) THEN + Current := UserIDX.Right + ELSE IF (UserIDX.Deleted <> IsDeleted) THEN + BEGIN + Done := TRUE; + UserIDX.Deleted := IsDeleted; + UserIDX.RealName := IsReal; + UserIDX.Number := UserNum; + Seek(UserIDXFile,Current); + Write(UserIDXFile,UserIDX); + END + ELSE + BEGIN + IF (UserNum <> UserIDX.Number) THEN + SysOpLog('Note: Duplicate user '+UName+' #'+IntToStr(UserIDX.Number)+' and '+UName+' #'+IntToStr(UserNum)) + ELSE + BEGIN + UserIDX.RealName := FALSE; + Seek(UserIDXFile,Current); { Make it be his handle IF it's BOTH } + Write(UserIDXFile,UserIDX); + END; + Done := TRUE; + END; + UNTIL (Current = -1) OR (Done); + IF (Current = -1) THEN + BEGIN + IF (Uname < UserIDX.Name) THEN + UserIDX.Left := FileSize(UserIDXFile) + ELSE + UserIDX.Right := FileSize(UserIDXFile); + Seek(UserIDXFile,InsertAt); + Write(UserIDXFile,UserIDX); + Seek(UserIDXFile,FileSize(UserIDXFile)); + WriteIndex; + END; + IF (NOT SFO) THEN + Close(UserIDXFile); + LastError := IOResult; +END; + +END. diff --git a/SOURCE/MSGPACK.PAS b/SOURCE/MSGPACK.PAS new file mode 100644 index 0000000..8652eaf --- /dev/null +++ b/SOURCE/MSGPACK.PAS @@ -0,0 +1,242 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT MsgPack; + +INTERFACE + +USES + Common; + +PROCEDURE DoShowPackMessageAreas; +PROCEDURE PackMessageAreas; + +IMPLEMENTATION + +USES + Mail0; + +PROCEDURE PackMessageArea(FN: Astr; MaxM: LongInt); + +VAR + Buffer: ARRAY [1..4096] OF Char; + MsgHdrF1, + MsgHdrF2: FILE OF MheaderRec; + BrdF1, + BrdF2: FILE; + MHeader: MheaderRec; + Numm, + i, + IDX, + TotLoad, + Buffered: Word; + NeedPack: Boolean; + + PROCEDURE OhShit; + BEGIN + SysOpLog('Error renaming temp files while packing.'); + END; + +BEGIN + NeedPack := FALSE; + FN := AllCaps(FN); + FN := General.MsgPath + FN; + + Assign(BrdF1,FN+'.DAT'); + Reset(BrdF1,1); + IF (IOResult <> 0) THEN + Exit; + + Assign(MsgHdrF1,FN+'.HDR'); + Reset(MsgHdrF1); + + IF (IOResult <> 0) THEN + BEGIN + Close(BrdF1); + Exit + END; + + IF (MaxM <> 0) AND (FileSize(MsgHdrF1) > MaxM) THEN + BEGIN + Numm := 0; + IDX := FileSize(MsgHdrF1); + WHILE (IDX > 0) DO + BEGIN + Seek(MsgHdrF1,(IDX - 1)); + Read(MsgHdrF1,MHeader); + IF NOT (MDeleted IN MHeader.Status) THEN + Inc(Numm); + IF (Numm > MaxM) AND NOT (Permanent IN MHeader.Status) THEN + BEGIN + MHeader.Status := [MDeleted]; + Seek(MsgHdrF1,(IDX - 1)); + Write(MsgHdrF1,MHeader); + END; + Dec(IDX); + END; + END + ELSE + BEGIN + + WHILE (FilePos(MsgHdrF1) < FileSize(MsgHdrF1)) AND (NOT NeedPack) DO + BEGIN + Read(MsgHdrF1,MHeader); + IF (MDeleted IN MHeader.Status) THEN + NeedPack := TRUE; + END; + + IF (NOT NeedPack) THEN + BEGIN + Close(MsgHdrF1); + Close(BrdF1); + Exit; + END; + END; + + LastError := IOResult; + + Assign(BrdF2,FN+'.DA1'); + ReWrite(BrdF2,1); + + Assign(MsgHdrF2,FN+'.HD2'); + ReWrite(MsgHdrF2); + + Kill(FN+'.HD3'); + Kill(FN+'.DA3'); + + LastError := IOResult; + + IDX := 1; + i := 0; + + WHILE (i <= FileSize(MsgHdrF1) - 1) DO + BEGIN + Seek(MsgHdrF1,i); + Read(MsgHdrF1,MHeader); + + IF (MHeader.Pointer - 1 + MHeader.TextSize > FileSize(BrdF1)) OR + (MHeader.Pointer < 1) THEN + MHeader.Status := [MDeleted]; + + IF NOT (MDeleted IN MHeader.Status) THEN + BEGIN + Inc(IDX); + Seek(BrdF1,MHeader.Pointer - 1); + MHeader.Pointer := (FileSize(BrdF2) + 1); + Write(MsgHdrF2,MHeader); + + TotLoad := 0; + IF (MHeader.TextSize > 0) THEN + WHILE (MHeader.TextSize > 0) DO + BEGIN + Buffered := MHeader.TextSize; + IF (Buffered > 4096) THEN + Buffered := 4096; + Dec(MHeader.TextSize,Buffered); + BlockRead(BrdF1,Buffer[1],Buffered); + BlockWrite(BrdF2,Buffer[1],Buffered); + LastError := IOResult; + END; + END; + Inc(i); + END; + + LastError := IOResult; + Close(BrdF1); + Close(BrdF2); + Close(MsgHdrF1); + Close(MsgHdrF2); + + ReName(BrdF1,FN+'.DA3'); { ReName .DAT to .DA3 } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + OhShit; + Exit; + END; + + ReName(BrdF2,FN+'.DAT'); { ReName .DA2 to .DAT } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + OhShit; + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + Exit; + END; + + ReName(MsgHdrF1,FN+'.HD3'); { ReName .HDR to .HD3 } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + OhShit; + Erase(BrdF2); { Erase .DA2 } + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + Exit; + END; + + ReName(MsgHdrF2,FN+'.HDR'); { ReName .HD2 to .HDR } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + OhShit; + Erase(BrdF2); { Erase .DAT (new) } + Erase(MsgHdrF2); { Erase .HD2 (new) } + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + ReName(MsgHdrF1,FN+'.HDR'); { ReName .HD3 to .HDR } + Exit; + END; + + Erase(MsgHdrF1); + Erase(BrdF1); + LastError := IOResult; +END; + +PROCEDURE DoShowPackMessageAreas; +VAR + TempBoard: MessageAreaRecordType; + MArea: Integer; +BEGIN + TempPause := FALSE; + SysOpLog('Packed all message areas'); + NL; + Star('Packing all message areas'); + NL; + Print('^1Packing ^5Private Mail'); + PackMessageArea('EMAIL',0); + Reset(MsgAreaFile); + IF (IOResult <> 0) THEN + Exit; + Abort := FALSE; + FOR MArea := 0 TO (FileSize(MsgAreaFile) - 1) DO + BEGIN + Seek(MsgAreaFile,MArea); + Read(MsgAreaFile,TempBoard); + Print('^1Packing ^5'+TempBoard.Name+'^5 #'+IntToStr(MArea + 1)); + PackMessageArea(TempBoard.FIleName,TempBoard.MaxMsgs); + WKey; + IF (Abort) THEN + Break; + END; + Close(MsgAreaFile); + lil := 0; +END; + +PROCEDURE PackMessageAreas; +BEGIN + NL; + IF PYNQ('Pack all message areas? ',0,FALSE) THEN + DoShowPackMessageAreas + ELSE + BEGIN + InitMsgArea(MsgArea); + SysOpLog('Packed message area ^5'+MemMsgArea.Name); + NL; + Print('^1Packing ^5'+MemMsgArea.Name+'^5 #'+IntToStr(CompMsgArea(MsgArea,0))); + PackMessageArea(MemMsgArea.FIleName,MemMsgArea.MaxMsgs); + END; +END; + +END. diff --git a/SOURCE/MULTNODE.PAS b/SOURCE/MULTNODE.PAS new file mode 100644 index 0000000..e64a6a4 --- /dev/null +++ b/SOURCE/MULTNODE.PAS @@ -0,0 +1,1321 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT Multnode; + +INTERFACE + +USES + Common; + +PROCEDURE lListNodes; +PROCEDURE ToggleChatAvailability; +PROCEDURE page_user; +PROCEDURE check_status; +PROCEDURE multiline_chat; +PROCEDURE dump_node; +PROCEDURE lsend_message(CONST b: ASTR); + +IMPLEMENTATION + +USES + Doors, + Menus, + Script, + ShortMsg, + TimeFunc; + +PROCEDURE pick_node(VAR NodeNum: Byte; IsChat: BOOLEAN); +BEGIN + lListNodes; + InputByteWOC('Which node',NodeNum,[NumbersOnly],1,MaxNodes); + IF (NodeNum >= 1) AND (NodeNum <= MaxNodes) AND (NodeNum <> ThisNode) THEN + BEGIN + LoadNode(NodeNum); + IF (NOT (NActive IN NodeR.Status) OR (NOT (NAvail IN NodeR.Status) AND IsChat)) AND NOT + ((NInvisible IN NodeR.Status) AND NOT CoSysOp) THEN + BEGIN + NL; + Print('That node is unavailable.'); + NodeNum := 0; + END; + IF (NodeR.User = 0) OR NOT (NAvail IN NodeR.Status) OR ((NInvisible IN NodeR.Status) AND NOT CoSysOp) THEN + NodeNum := 0; + END + ELSE + NodeNum := 0; +END; + +PROCEDURE dump_node; +VAR + NodeNum: Byte; +BEGIN + pick_node(NodeNum,FALSE); + IF (NodeNum > 0) THEN + IF PYNQ('Hang up user on node '+IntToStr(NodeNum)+'? ',0,FALSE) THEN + BEGIN + LoadNode(NodeNum); + Include(NodeR.Status,NHangup); + IF PYNQ('Recycle node '+IntToStr(NodeNum)+' after logoff? ',0,FALSE) THEN + Include(NodeR.Status,NRecycle); + SaveNode(NodeNum); + END; +END; + +PROCEDURE page_user; +VAR + NodeNum: Byte; +BEGIN + NL; + IF (NOT General.MultiNode) THEN + BEGIN + Print('This BBS is currently not operating in Multi-Node.'); + Exit; + END; + pick_node(NodeNum,TRUE); + IF (NodeNum > 0) AND (NodeNum <> ThisNode) THEN + lsend_message(IntToStr(NodeNum)+';^8'+Caps(ThisUser.Name)+' on node '+IntToStr(ThisNode)+' has paged you for chat.'^M^J); +END; + +PROCEDURE check_status; +VAR + f: FILE; + s: STRING; + j: BYTE; +BEGIN + LoadNode(ThisNode); + WITH NodeR DO + BEGIN + IF (NUpdate IN Status) THEN + BEGIN + j := ThisUser.Waiting; + Reset(UserFile); + Seek(UserFile,UserNum); + Read(UserFile,ThisUser); + Close(UserFile); + LastError := IOResult; + update_screen; + IF (ThisUser.Waiting > j) THEN + BEGIN + NL; + Print('^8You have new private mail waiting.'); + NL; + END; + Exclude(Status,NUpdate); + SaveNode(ThisNode); + IF (SMW IN ThisUser.flags) THEN + BEGIN + ReadShortMessage; + NL; + END; + END; + IF (NHangup IN Status) OR (NRecycle IN Status) THEN + BEGIN + HangUp := TRUE; + IF (NRecycle IN Status) THEN + QuitAfterDone := TRUE; + END; + IF (NOT MultiNodeChat) AND (MaxChatRec > NodeChatLastRec) THEN + BEGIN + Assign(f,General.TempPath+'MSG'+IntToStr(ThisNode)+'.TMP'); + Reset(f,1); + Seek(f,NodeChatLastRec); + WHILE NOT EOF(f) DO + BEGIN + BlockRead(f,s[0],1); + BlockRead(f,s[1],Ord(s[0])); + Print(s); + END; + Close(f); + LastError := IOResult; + NodeChatLastRec := MaxChatRec; + PauseScr(FALSE); + END; + END; +END; + +PROCEDURE LowLevelSend(s: STRING; Node: Byte); +VAR + F: FILE; +BEGIN + IF (Node < 0) THEN + Exit; + Assign(f,General.TempPath+'MSG'+IntToStr(Node)+'.TMP'); + Reset(f,1); + IF (IOResult = 2) THEN + ReWrite(f,1); + Seek(f,FileSize(f)); + BlockWrite(f,s[0],(Length(s) + 1)); + Close(f); + LastError := IOResult; +END; + +PROCEDURE multiline_chat; +type + WhyNot = (NotModerator,NotOnline,NotRoom,NotInRoom,NotValid); +VAR + RoomFile: FILE OF RoomRec; + ActionsFile: TEXT; + Room: RoomRec; + User: UserRecordType; + s: STRING; + s2, + s3, + execs: ASTR; + SaveName: STRING[36]; + Cmd: CHAR; + i, + j, + SaveTimeOut, + SaveTimeOutBell: INTEGER; + Done, + ChannelOnly: BOOLEAN; + + FUNCTION ActionMCI(s: ASTR): STRING; + VAR + Temp: ASTR; + Index: INTEGER; + BEGIN + Temp := ''; + FOR Index := 1 TO Length(s) DO + IF (s[Index] = '%') THEN + CASE (UpCase(s[Index + 1])) OF + 'S' : BEGIN + Temp := Temp + Caps(ThisUser.Name); + Inc(Index); + END; + 'R' : BEGIN + Temp := Temp + Caps(SaveName); + Inc(Index); + END; + 'G' : BEGIN + Temp := Temp + AOnOff((ThisUser.sex = 'M'),'his','her'); + Inc(Index); + END; + 'H' : BEGIN + Temp := Temp + AOnOff((ThisUser.sex = 'M'),'him','her'); + Inc(Index); + END; + END + ELSE + Temp := Temp + s[Index]; + ActionMCI := Temp; + END; + + PROCEDURE LoadRoom(VAR Chan: INTEGER); + BEGIN + Reset(RoomFile); + Seek(RoomFile,(Chan - 1)); + Read(RoomFile,Room); + Close(RoomFile); + LastError := IOResult; + END; + + PROCEDURE SaveRoom(VAR Chan: INTEGER); + BEGIN + Reset(RoomFile); + Seek(RoomFile,(Chan - 1)); + Write(RoomFile,Room); + Close(RoomFile); + LastError := IOResult; + END; + + PROCEDURE SendMessage(s: STRING; showhere: BOOLEAN); + VAR + i: WORD; + Trap: TEXT; + BEGIN + IF (General.TrapTeleConf) THEN + BEGIN + Assign(Trap,General.LogsPath+'ROOM'+IntToStr(RoomNumber)+'.TRP'); + Append(Trap); + IF (IOResult = 2) THEN + ReWrite(Trap); + WriteLn(Trap,StripColor(s)); + Close(Trap); + END; + WITH NodeR DO + FOR i := 1 TO MaxNodes DO + BEGIN + LoadNode(i); + IF (i <> ThisNode) AND ((NOT ((ThisNode MOD 8) IN Forget[ThisNode DIV 8])) AND + ((NOT ChannelOnly) AND (MultiNodeChat) AND (Room = RoomNumber)) OR + ((NodeR.Channel = ChatChannel) AND (ChatChannel > 0) AND ChannelOnly)) THEN + LowLevelSend(s,i); + END; + IF (ShowHere) THEN + BEGIN + IF (MultiNodeChat) AND NOT AACS(General.TeleConfMCI) THEN + MCIAllowed := FALSE; + Print(s); + MCIAllowed := TRUE; + END; + END; + + PROCEDURE AddToRoom(VAR Chan: INTEGER); + VAR + People: WORD; + i: WORD; + BEGIN + IF (NOT IsInvisible) AND NOT ((Chan MOD 8) IN NodeR.Booted[Chan DIV 8]) THEN + SendMessage('^0[^9'+Caps(ThisUser.Name)+' ^0has entered the room. ]',FALSE); + NL; + Print('^1You are now in conference room ^3'+IntToStr(Chan)); + LoadRoom(Chan); + IF (NOT Room.Occupied) THEN + BEGIN + Room.Occupied := TRUE; + SaveRoom(Chan); + END; + People := 0; + FOR i := 1 TO MaxNodes DO + BEGIN + IF (i = ThisNode) THEN + Continue; + LoadNode(i); + IF (NodeR.Room = Chan) AND (NodeR.GroupChat) THEN + Inc(People); + END; + WITH Room DO + BEGIN + IF (Chan = 1) THEN + Topic := 'Main'; + IF (Topic <> '') THEN + Print('^1The Current Topic is: ^3'+Topic); + IF (People = 0) THEN + Print('^1You are the only one present.') + ELSE + Print('^1There '+AOnOff(People = 1,'is','are')+' '+IntToStr(People)+ + ' other '+AOnOff(People = 1,'person','people')+' present.'); + END; + LoadNode(ThisNode); + NodeR.Room := Chan; + SaveNode(ThisNode); + END; + + PROCEDURE RemoveFromRoom(VAR Chan: INTEGER); + VAR + People: WORD; + i: WORD; + BEGIN + IF (NOT IsInvisible) AND NOT ((Chan MOD 8) IN NodeR.Booted[Chan DIV 8]) THEN + SendMessage('^0[^9 '+Caps(ThisUser.Name)+'^0 has left the room. ]', FALSE); + LoadRoom(Chan); + WITH Room DO + IF (Moderator = UserNum) THEN + Moderator := 0; + People := 0; + FOR i := 1 TO MaxNodes DO + BEGIN + IF (i = ThisNode) THEN + Continue; + LoadNode(i); + IF (NodeR.Room = Chan) AND (NodeR.GroupChat) THEN + Inc(People); + END; + IF (People = 1) THEN + Room.Occupied := FALSE; + IF (NOT IsInvisible) THEN + SaveRoom(Chan); + END; + + FUNCTION Name2Number(VAR s,sname: ASTR): INTEGER; + VAR + i: INTEGER; + Temp: STRING; + BEGIN + Name2Number := 0; + IF (Pos(' ',s) > 0) THEN + Sname := Copy(s,1,Pos(' ',s)) + ELSE + Sname := s; + i := StrToInt(SQOutSp(Sname)); + IF (SQOutSp(Sname) = IntToStr(i)) AND ((i > 0) AND (i <= MaxNodes)) THEN + BEGIN + LoadNode(i); + WITH NodeR DO + IF (User > 0) THEN + BEGIN + IF ((NOT (NInvisible IN Status)) OR (CoSysOp)) THEN + Name2Number := i + ELSE + Name2Number := 0; + s := Copy(s,(Length(Sname) + 1),255); + Sname := Caps(UserName); + Exit; + END; + END; + i := 1; + Sname := ''; + IF (Pos(' ',s) > 0) THEN + Temp := AllCaps(Copy(s,1,(Pos(' ',s) - 1))) + ELSE + Temp := AllCaps(s); + WHILE (i <= MaxNodes) DO + BEGIN + LoadNode(i); + WITH NodeR DO + IF (User > 0) THEN + BEGIN + IF ((UserName = AllCaps(Copy(s,1,Length(UserName)))) OR (Pos(Temp,UserName) > 0)) THEN + BEGIN + Name2Number := i; + IF (UserName = AllCaps(Copy(s,1,Length(UserName)))) THEN + s := Copy(s,(Length(UserName) + 2), 255) + ELSE + s := Copy(s,(Length(temp) + 2), 255); + sname := Caps(UserName); + Break; + END; + END; + Inc(i); + END; + END; + + PROCEDURE Nope(Reason: WhyNot); + BEGIN + NL; + CASE Reason OF + NotModerator : Print('|10You are not the moderator.'); + NotOnline : Print('|10That user is not logged on.'); + NotRoom : Print('|10Invalid room number.'); + NotInRoom : Print('|10That user is not in this room.'); + NotValid : Print('|10Invalid option - Enter "/?" for help'); + END; + NL; + END; + + PROCEDURE ShowRoom(Chan: INTEGER); + VAR + People: WORD; + i: WORD; + BEGIN + LoadRoom(Chan); + IF (NOT Room.Occupied) THEN + Exit; + People := 0; + FOR i := 1 TO MaxNodes DO + BEGIN + IF (i = ThisNode) THEN + Continue; + LoadNode(i); + IF (NodeR.Room = Chan) AND (NodeR.GroupChat) THEN + Inc(People); + END; + IF (People = 0) THEN + BEGIN + NL; + IF (Room.Moderator >= 0) THEN + LoadURec(User,Room.Moderator) + ELSE + User.Name := 'Nobody'; + PrintACR('^9Conference Room: ^3'+PadLeftInt(Chan,5)+' ^9Moderator: ^3'+Caps(User.Name)); + PrintACR('^9Type: ^3'+PadLeftStr(AOnOff(Room.Private,'Private','Public'),17)+'^9Topic: ^3'+Room.Topic); + IF (Room.Anonymous) THEN + BEGIN + NL; + PrintACR('This room is in anonymous mode.'); + END; + NL; + j := 1; + WHILE (J <= MaxNodes) AND (NOT Abort) DO + BEGIN + LoadNode(j); + IF (NodeR.GroupChat) AND (NodeR.Room = Chan) THEN + IF NOT (NInvisible IN NodeR.Status) OR (CoSysOp) THEN + PrintACR('^1'+Caps(NodeR.UserName)+' on node '+IntToStr(j)); + Inc(j); + END; + NL; + END; + END; + + PROCEDURE InputMain(VAR s: STRING); + VAR + os, + cs: STRING; + cp: INTEGER; + c: CHAR; + ml, + origcolor: BYTE; + cb: WORD; + LastCheck: LONGINT; + + PROCEDURE DoBackSpace; + VAR + i,j,c: BYTE; + WasColor: BOOLEAN; + + PROCEDURE set_color; + BEGIN + c := origcolor; + i := 1; + WHILE (i < cp) DO + BEGIN + IF (s[i]='^') THEN + BEGIN + c := Scheme.Color[Ord(s[i+1]) + Ord('1')]; + Inc(i); + END; + IF (s[i]='|') AND (i + 1 < Length(s)) AND (s[i + 1] IN ['0'..'9']) AND (s[i + 2] IN ['0'..'9']) THEN + BEGIN + cs := s[i + 1] + s[i + 2]; + CASE cb OF + 0..15 : c := (c - (c MOD 16) + cb); + 16..23 : c:= ((cb - 16) * 16) + (c MOD 16); + END; + END; + Inc(i); + END; + SetC(c); + END; + + BEGIN + WasColor := FALSE; + IF (cp > 1) THEN + BEGIN + Dec(cp); + IF (cp > 1) THEN + BEGIN + IF (s[cp] IN ['0'..'9']) THEN + BEGIN + IF (s[cp-1] = '^') THEN + BEGIN + Dec(cp); + WasColor := TRUE; + set_color; + END + ELSE + BEGIN + j := 0; + WHILE (s[cp-j] <> '|') AND (s[cp - j] IN ['0'..'9']) AND (j < cp) DO + BEGIN + Inc(j); + END; + IF (s[cp - j] = '|') THEN + BEGIN + WasColor := TRUE; + Dec(cp,j); + set_color; + END; + END; + END; + END; + IF (NOT WasColor) THEN + BEGIN + BackSpace; + IF (trapping) THEN + Write(TrapFile,^H' '^H); + END; + END; + END; + + BEGIN + origcolor := CurrentColor; + os := s; + s:=''; + ml := (253 - Length(MCI(Liner.TeleConfNormal))); + checkhangup; + IF (HangUp) THEN + Exit; + cp := 1; + LastCheck := 0; + repeat + mlc := s; + MultiNodeChat := TRUE; + IF (cp > 1) AND MultiNodeChat AND NOT ThisUser.TeleConfInt THEN + MultiNodeChat := FALSE; + C := CHAR(GetKey); + IF (Timer - LastCheck > 1) THEN + BEGIN + LoadNode(ThisNode); + IF ((RoomNumber MOD 8) IN NodeR.Booted[RoomNumber DIV 8]) THEN + BEGIN + s := ''; + Print('^5You have been ^0EJECTED^5 from the room.'^M^J); + IF (RoomNumber = 1) THEN + Done := TRUE + ELSE + BEGIN + RemoveFromRoom(RoomNumber); + RoomNumber := 1; + AddToRoom(RoomNumber); + END; + Exit; + END + END; + CASE c OF + ^H : DoBackSpace; + ^P : IF (cp < ml) THEN + BEGIN + c := CHAR(GetKey); + IF (c IN ['0'..'9']) THEN + BEGIN + UserColor(Ord(c)-48); + s[cp] := '^'; + s[cp + 1] := c; + Inc(cp,2); + END; + END; + #32..#123,#125..#255 : + IF (cp <= ml) THEN + BEGIN + s[cp] := c; + Inc(cp); + outkey(c); + IF (trapping) THEN + Write(TrapFile,c); + END; + '|' : IF (cp + 1 <= ml) THEN + BEGIN + cs := ''; + c := '0'; + cb := 0; + WHILE (c IN ['0'..'9']) AND (cb < 2) DO + BEGIN + c := CHAR(GetKey); + IF (c IN ['0'..'9']) THEN + cs := cs + c; + Inc(cb); + END; + cb := StrToInt(cs); + CASE cb OF + 0..15 : SetC(CurrentColor - (CurrentColor MOD 16) + cb); + 16..23 : SetC(((cb - 16) * 16) + (CurrentColor MOD 16)); + END; + IF NOT (c IN ['0'..'9']) THEN + BEGIN + outkey(c); + IF (trapping) THEN + Write(TrapFile,c); + cs := cs + c; {here was buf} + END; + s := s + '|' + cs; + Inc(cp,Length(cs)+1); + END + ELSE IF (cp <= ml) THEN + BEGIN + s[cp] := c; + Inc(cp); + outkey(c); + IF (trapping) THEN + Write(TrapFile,c); + END; + ^X : BEGIN + WHILE (cp <> 1) DO + DoBackSpace; + SetC(origcolor); + END; + END; + s[0] := Chr(cp - 1); + until ((c = ^M) OR (c = ^N) OR (HangUp)); + mlc := ''; + NL; + END; + +BEGIN + NL; + IF (NOT General.MultiNode) THEN + BEGIN + Print('This BBS is currently not operating in Multi-Node.'); + Exit; + END; + + Assign(ActionsFile,General.MiscPath+'ACTIONS.LST'); + Reset(ActionsFile); + IF (IOResult = 2) THEN + ReWrite(ActionsFile); + Close(ActionsFile); + + Assign(RoomFile,General.DataPath+'ROOM.DAT'); + Reset(RoomFile); + IF (IOResult = 2) THEN + ReWrite(RoomFile); + FillChar(Room,SizeOf(Room),0); + Seek(RoomFile,FileSize(RoomFile)); + WHILE (FileSize(RoomFile) < 255) DO + Write(RoomFile,Room); + Close(RoomFile); + + IF (IOResult <> 0) THEN + Exit; + + SaveTimeOut := General.TimeOut; + General.TimeOut := -1; + SaveTimeOutBell := General.TimeOutBell; + General.TimeOutBell := -1; + + Kill(General.TempPath+'MSG'+IntToStr(ThisNode)+'.TMP'); + + ChannelOnly := FALSE; + + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + NodeR.GroupChat := TRUE; + SaveNode(ThisNode); + END; + + mlc := ''; + RoomNumber := 1; + NodeChatLastRec := 0; + + CLS; + SysOpLog('Entered Teleconferencing'); + PrintF('TELECONF'); + IF (NoFile) THEN + Print('^0 Welcome to Teleconferencing. Type ^5/?^0 for help or ^5/Q^0 to quit.'); + AddToRoom(RoomNumber); + NL; + Done := FALSE; + WHILE (NOT Done) AND (NOT HangUp) DO + BEGIN + TLeft; + MultiNodeChat := TRUE; + LoadNode(ThisNode); + Usercolor(3); + check_status; + InputMain(s); + ChannelOnly := FALSE; + MultiNodeChat := FALSE; + IF (HangUp) THEN + s := '/Q'; + IF (s = '`') THEN + IF (ChatChannel > 0) THEN + BEGIN + j := 1; + Print('^0The following people are in global channel '+IntToStr(ChatChannel)+': '^M^J); + WHILE (J <= MaxNodes) AND (NOT Abort) DO + BEGIN + LoadNode(j); + WITH NodeR DO + IF (GroupChat) AND (Channel = ChatChannel) AND (j <> ThisNode) THEN + BEGIN + PrintACR('^9'+Caps(UserName)+' on node '+IntToStr(j)); + ChannelOnly := TRUE; + END; + Inc(j); + END; + IF (NOT ChannelOnly) THEN + Print('^9None.') + ELSE + ChannelOnly := FALSE; + NL; + s := ''; + END + ELSE + BEGIN + Print('^0You are not in a global channel.'^M^J); + s := ''; + END; + IF (NOT Done) AND (s <> '') AND (s[1] = '/') THEN + BEGIN + Cmd := UpCase(s[2]); + s3 := AllCaps(Copy(s,2,255)); + IF (Pos(' ',s3) > 0) THEN + BEGIN + SaveName := Copy(s3,(Pos(' ',s3) + 1),255); + s3 := Copy(s3,1,(Pos(' ',s3) - 1)); + END + ELSE + SaveName := ''; + s2 := SaveName; + IF (SaveName <> '') THEN + BEGIN + i := Name2Number(s2,SaveName); + IF (SaveName = '') THEN + i := -1; + END + ELSE + i := 0; + Reset(ActionsFile); + WHILE NOT EOF(ActionsFile) DO + BEGIN + ReadLn(ActionsFile,s2); { Action WORD } + IF (AllCaps(s2) = s3) THEN + BEGIN + ReadLn(ActionsFile,s2); { What sender sees } + s2 := MCI(s2); + IF (Copy(AllCaps(s2),1,5) <> ':EXEC') THEN + BEGIN + Print('^0'+ActionMCI(s2)); + execs := ''; + END + ELSE + execs := Copy(s2,6,255); { strip ":EXEC" } + ReadLn(ActionsFile,s2); { What everybody ELSE sees } + IF (i = 0) THEN + ReadLn(ActionsFile,s2); { What evrybdy sees IF no rcvr } + s2 := MCI(s2); + s2 := '^0' + ActionMCI(s2); + WITH NodeR DO + FOR j := 1 TO MaxNodes DO + BEGIN + LoadNode(j); + IF (GroupChat) AND (Room = RoomNumber) AND + (j <> ThisNode) AND NOT ((ThisNode MOD 8) IN Forget[ThisNode DIV 8]) AND + (j <> i) THEN + LowLevelSend(s2,j); + END; + IF (i > 0) THEN + ReadLn(ActionsFile,s2); + ReadLn(ActionsFile,s2); { What receiver sees } + s2 := MCI(s2); + IF (i > 0) THEN + BEGIN + LoadNode(i); + IF (NodeR.GroupChat) AND (NodeR.Room = RoomNumber) AND + NOT ((ThisNode MOD 8) IN NodeR.Forget[ThisNode DIV 8]) THEN + LowLevelSend('^0'+ActionMCI(s2), i); + END; + s := ''; + IF (execs <> '') THEN + BEGIN + Cmd := execs[1]; + execs := Copy(execs,2,255); + dodoorfunc(Cmd,execs); + END; + Break; + END + ELSE FOR j := 1 TO 4 DO + ReadLn(ActionsFile,s2); + END; + Close(ActionsFile); + + IF (s <> '') THEN + CASE Cmd OF + '/' : IF (Copy(s,2,3) = '/\\') AND (SysOp) THEN + DoMenuCommand(Done,AllCaps(Copy(S,5,2)),AllCaps(Copy(s,7,255)),s2,'Activating SysOp Cmd'); + + 'A' : IF (AllCaps(Copy(s,2,4)) <> 'ANON') THEN + BEGIN + s := Copy(s,4,(Length(s) - 3)); + s := '^0'+Caps(ThisUser.Name)+' '+s; + END + ELSE + BEGIN + IF (Room.Moderator = UserNum) OR (CoSysOp) THEN + BEGIN + LoadRoom(RoomNumber); + Room.Anonymous := NOT Room.Anonymous; + SaveRoom(RoomNumber); + SendMessage('^0[ This room is now in ^2'+AOnOff(Room.Anonymous,'Anonymous','Regular')+'^0 ]',TRUE); + END + ELSE + Nope(NotModerator); + END; + + 'E' : BEGIN + IF (AllCaps(Copy(s,2,4)) = 'ECHO') THEN + BEGIN + ThisUser.TeleConfEcho := NOT ThisUser.TeleConfEcho; + Print('^9Your message echo is now '+ShowOnOff(ThisUser.TeleConfEcho)); + END + ELSE IF (AllCaps(Copy(s,2,5)) = 'EJECT') THEN + BEGIN + IF (Room.Moderator = UserNum) OR (CoSysOp) THEN + BEGIN + s := Copy(s,(Pos(' ',s) + 1),Length(s)); + i := Name2Number(s,SaveName); + IF (i > 0) AND (i <= MaxNodes) THEN + BEGIN + LoadNode(i); + IF (NodeR.GroupChat) AND (NodeR.Room = RoomNumber) THEN + BEGIN + LoadURec(User,NodeR.User); + IF (aacs1(User, NodeR.User, General.CSOp)) THEN + Print('^9You cannot eject that person.'^M^J) + ELSE + BEGIN + NodeR.Booted[RoomNumber DIV 8] := NodeR.Booted[RoomNumber DIV 8] + [RoomNumber MOD 8]; + NodeR.Room := 1; + SaveNode(i); + IF (NOT IsInvisible) THEN + SendMessage('^0'+SaveName+'^9 has just been ejected from the room by ^0'+ + Caps(ThisUser.Name),TRUE); + SysOpLog('Ejected '+SaveName); + END; + END + ELSE + Nope(NotInRoom); + END + ELSE + Nope(NotOnline); + s := ''; + END + ELSE + Nope(NotModerator); + END; + END; + + 'F' : IF (S[3] <> ' ') OR (Copy(S,4,(Length(s) - 3)) = '') THEN + Nope(NotValid) + ELSE + BEGIN + s := Copy(s,4,(Length(s) - 3)); + i := Name2Number(s,SaveName); + IF (i > 0) AND (i <= MaxNodes) THEN + BEGIN + LoadURec(User,NodeR.User); + IF (aacs1(User,NodeR.User,General.CSOp)) THEN + Print('^9You cannot forget a sysop.'^M^J) + ELSE + BEGIN + LoadNode(ThisNode); + NodeR.Forget[i DIV 8] := NodeR.Forget[i DIV 8] + [i MOD 8]; + SaveNode(ThisNode); + Print('^0'+SaveName+'^9 has been forgotten.'); + END; + END + ELSE + Nope(NotOnLine); + s := ''; + END; + + 'G' : IF (AllCaps(Copy(s,2,6)) = 'GLOBAL') THEN + BEGIN + LoadNode(ThisNode); + NodeR.Channel := StrToInt(Copy(s,(Pos(' ',s) + 1),255)); + Print(^M^J'^0You are now in global channel '+IntToStr(NodeR.Channel)+'.'^M^J); + ChatChannel := NodeR.Channel; + SaveNode(ThisNode); + ChannelOnly := TRUE; + IF (NOT IsInvisible) THEN + SendMessage('^9'+Caps(ThisUser.Name)+' has joined global channel '+IntToStr(chatchannel)+'.', FALSE); + END + ELSE IF (AllCaps(s) = '/G') THEN + BEGIN + IF PYNQ('Are you sure you want to disconnect? ',39,FALSE) THEN + BEGIN + IF (NOT IsInvisible) THEN + SendMessage('^0[ ^2'+Caps(ThisUser.Name)+'^0 has disconnected on node '+IntToStr(ThisNode)+' ]',FALSE); + HangUp := TRUE; + END; + END; + + 'I' : IF (AllCaps(Copy(s,2,9)) = 'INTERRUPT') THEN + BEGIN + ThisUser.TeleConfInt := NOT ThisUser.TeleConfInt; + Print('^9Your message interruption is now '+ShowOnOff(ThisUser.TeleConfInt)); + END + ELSE + BEGIN + IF (Room.Moderator = UserNum) OR (CoSysOp) THEN + BEGIN + IF (Length(s) = 2) THEN + BEGIN + LoadRoom(RoomNumber); + Room.Private := NOT Room.Private; + SaveRoom(RoomNumber); + SendMessage('^0[ This room is now ^2'+AOnOff(Room.Private,'private','public') + '^0 ]', TRUE); + END + ELSE + BEGIN + s := Copy(s,4,(Length(s) - 3)); + i := Name2Number(s,SaveName); + IF (i > 0) AND (i <= MaxNodes) THEN + BEGIN + LoadNode(i); + s := ^M^J+'^9[^0 ' + Caps(ThisUser.Name) + '^9 is inviting you to join conference room ' + +IntToStr(RoomNumber)+' ]'; + NodeR.Invited[RoomNumber DIV 8] := NodeR.Invited[RoomNumber DIV 8] + [RoomNumber MOD 8]; + NodeR.Booted[RoomNumber DIV 8] := NodeR.Booted[RoomNumber DIV 8] - [RoomNumber MOD 8]; + Print('^0'+SaveName+'^9 on node '+IntToStr(i)+' has been invited.'); + SaveNode(i); + IF (i <> ThisNode) THEN + LowLevelSend(s,i); + END + ELSE + Nope(NotOnline); + s := ''; + END; + END + ELSE + Nope(NotModerator); + END; + + 'J' : IF (S[3] <> ' ') OR (Copy(S,4,(Length(s) - 3)) = '') THEN + Nope(NotValid) + ELSE + BEGIN + s := Copy(s,4,3); + i := StrToInt(s); + IF (i >= 1) AND (i <= 255) THEN + BEGIN + LoadNode(ThisNode); + IF ((i MOD 8) IN NodeR.Booted[i DIV 8]) THEN + BEGIN + NL; + Print('^5You were ^0EJECTED^5 from that room.'); + NL; + END + ELSE + BEGIN + LoadRoom(i); + IF (Room.Private) AND NOT (CoSysOp) AND NOT ((i MOD 8) IN NodeR.Invited[i DIV 8]) THEN + BEGIN + NL; + Print('^9You must be invited to private conference rooms.'); + NL; + LoadRoom(RoomNumber); + END + ELSE + BEGIN + RemoveFromRoom(RoomNumber); + RoomNumber := i; + AddToRoom(RoomNumber); + SysOpLog('Joined room '+IntToStr(RoomNumber)+' '+Room.Topic); + END; + END; + END + ELSE + Nope(NotRoom); + s := ''; + END; + + 'L' : IF (Copy(S,3,(Length(S) - 2)) <> '') THEN + Nope(NotValid) + ELSE + PrintF('ACTIONS'); + + 'M' : IF (S[3] <> ' ') OR (Copy(S,4,(Length(s) - 3)) = '') THEN + Nope(NotValid) + ELSE + BEGIN + NL; + IF (CoSysOp) OR (Room.Moderator = UserNum) OR ((Room.Moderator = 0) AND (RoomNumber <> 1)) THEN + BEGIN + s := Copy(S,4,40); + LoadRoom(RoomNumber); + Room.Topic := s; + IF (NOT IsInvisible) THEN + SendMessage('^0[ Conference "^2'+Room.Topic+'^0" is now moderated by ^2'+ + Caps(ThisUser.Name)+'^0 ]',TRUE); + IF (Room.Moderator = 0) THEN + BEGIN + FOR i := 1 TO MaxNodes DO + BEGIN + LoadNode(i); + NodeR.Invited[RoomNumber DIV 8] := NodeR.Invited[RoomNumber DIV 8] - [RoomNumber MOD 8]; + NodeR.Booted[RoomNumber DIV 8] := NodeR.Booted[RoomNumber DIV 8] - [RoomNumber MOD 8]; + SaveNode(i); + END; + END; + Room.Moderator := UserNum; + SaveRoom(RoomNumber); + END + ELSE + Nope(NotModerator); + s := ''; + END; + + 'P' : IF (S[3] <> ' ') OR (Copy(s,4,(Length(s) - 3)) = '') THEN + Nope(NotValid) + ELSE + BEGIN + s := Copy(s,4,(Length(s) - 3)); + i := Name2Number(s,SaveName); + IF (i > 0) AND (i <= MaxNodes) THEN + BEGIN + LoadNode(i); + IF ((ThisNode MOD 8) IN NodeR.Forget[ThisNode DIV 8]) THEN + Print('^9That user has forgotten you.'^M^J) + ELSE IF NOT (NAvail IN NodeR.Status) THEN + Print('^9That user is unavailable.'^M^J) + ELSE IF NOT (NInvisible IN NodeR.Status) THEN + BEGIN + Print('^9Private message sent to ^0'+SaveName); + IF AACS(General.TeleConfMCI) THEN + s := MCI(s); + s := MCI(Liner.TeleConfPrivate) + s; + LowLevelSend(s,i) + END + ELSE + Nope(NotOnline); + END + ELSE + Nope(NotOnline); + s := ''; + END; + + 'Q' : BEGIN + s := Copy(s,4,40); + IF (s <> '') THEN + s := '^0'+Caps(ThisUser.Name)+' '+s; + LoadNode(ThisNode); + SaveNode(ThisNode); + Done := TRUE; + END; + + 'R' : IF (AllCaps(Copy(s,2,8)) = 'REMEMBER') THEN + BEGIN + s := Copy(s,(Pos(' ',s) + 1), 255); + i := Name2Number(s,SaveName); + IF (i > 0) AND (i <= MaxNodes) THEN + BEGIN + LoadNode(ThisNode); + NodeR.Forget[i DIV 8] := NodeR.Forget[i DIV 8] - [i MOD 8]; + SaveNode(ThisNode); + Print('^0'+SaveName+'^9 has been remembered.'); + END + ELSE + Nope(NotOnLine); + END + ELSE + BEGIN + s:= Copy(s,(Pos(' ',s) + 1),255); + i := SearchUser(s,FALSE); + readasw(i,'registry'); + s := ''; + END; + + 'S' : IF (Copy(S,3,(Length(s) - 2)) <> '') THEN + Nope(NotValid) + ELSE + BEGIN + Abort := FALSE; + i := 1; + WHILE (i <= 255) AND (NOT Abort) DO + BEGIN + ShowRoom(i); + Inc(i); + END; + LoadRoom(RoomNumber); + s := ''; + END; + + 'U' : IF (Copy(S,3,(Length(s) - 2)) <> '') THEN + Nope(NotValid) + ELSE + BEGIN + ShowRoom(RoomNumber); + s := ''; + END; + + 'W' : IF (Copy(S,3,(Length(s) - 2)) <> '') THEN + Nope(NotValid) + ELSE + lListNodes; + + '?' : IF (Copy(S,3,(Length(s) - 2)) <> '') THEN + Nope(NotValid) + ELSE + PrintF('TELEHELP'); + END; + IF (s[1] = '/') THEN + s := ''; + END + ELSE + IF (s > #0) THEN + BEGIN + LoadRoom(RoomNumber); + IF (s[1] <> '`') THEN + IF (Room.Anonymous) THEN + s := MCI(Liner.TeleConfAnon) + s + ELSE + s := MCI(Liner.TeleConfNormal) + s + ELSE + BEGIN + s := MCI(Liner.TeleConfGlobal) + Copy(s,2,255); + ChannelOnly := TRUE; + END; + END + ELSE + s := ''; + IF (s <> '') THEN + BEGIN + MultiNodeChat := TRUE; + IF (AACS(General.TeleConfMCI)) THEN + s := MCI(s); + SendMessage(s,ThisUser.TeleConfEcho); + END; + END; + MultiNodeChat := FALSE; + + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + NodeR.GroupChat := FALSE; + SaveNode(ThisNode); + END; + + RemoveFromRoom(RoomNumber); + + NodeChatLastRec := 0; + Kill(General.TempPath+'MSG'+IntToStr(ThisNode)+'.TMP'); + General.TimeOut := SaveTimeOut; + General.TimeOutBell := SaveTimeOutBell; +END; + +PROCEDURE ToggleChatAvailability; +BEGIN + NL; + IF (NOT General.MultiNode) THEN + BEGIN + Print('This BBS is currently not operating in Multi-Node.'); + Exit; + END; + LoadNode(ThisNode); + IF (NAvail IN NodeR.Status) THEN + BEGIN + Exclude(NodeR.Status,NAvail); + Print('You are not available for chat.'); + END + ELSE + BEGIN + Include(NodeR.Status,NAvail); + Print('You are now available for chat.'); + END; + SaveNode(ThisNode); +END; + +PROCEDURE lsend_message(CONST b: ASTR); +VAR + s: STRING; + NodeNum: Byte; + Forced: BOOLEAN; +BEGIN + NL; + IF (NOT General.MultiNode) THEN + BEGIN + Print('This BBS is currently not operating in Multi-Node.'); + Exit; + END; + s := b; + NodeNum := StrToInt(s); + IF (b <> '') AND (IsInvisible) THEN + Exit; + Forced := (s <> ''); + IF (NodeNum = 0) AND (Copy(s,1,1) <> '0') THEN + BEGIN + pick_node(NodeNum,TRUE); + Forced := FALSE; + IF (NodeNum = 0) THEN + Exit; + END; + IF (NodeNum = ThisNode) THEN + Exit; + IF (Forced OR AACS(General.TeleConfMCI)) THEN + s := MCI(s); + IF (NodeNum > 0) THEN + BEGIN + LoadNode(NodeNum); + IF (NodeR.User = 0) THEN + Exit; + END; + IF (s <> '') THEN + s := '^1'+Copy(s,(Pos(';',s) + 1),255) + ELSE + BEGIN + Prt('Message: '); + InputMain(s,(SizeOf(s) - 1),[ColorsAllowed]); + END; + IF (Forced OR AACS(General.TeleConfMCI)) THEN + s := MCI(s); + IF (s <> '') THEN + BEGIN + IF (NOT Forced) THEN + BEGIN + LoadNode(NodeNum); + IF (NOT ((ThisNode MOD 8) IN NodeR.Forget[ThisNode DIV 8])) THEN + LowLevelSend(^M^J'^5Message from '+Caps(ThisUser.Name)+' on node '+IntToStr(ThisNode)+':^1'^M^J,NodeNum) + ELSE + Print(^M^J'That node has forgotten you.'); + END; + IF (NodeNum = 0) THEN + FOR NodeNum := 1 TO MaxNodes DO + IF (NodeNum <> ThisNode) THEN + BEGIN + LoadNode(NodeNum); + IF (NodeR.User > 0) THEN + LowLevelSend(s,NodeNum) + END + ELSE (* Match up ELSE Statements ??? *) + ELSE + LowLevelSend(s,NodeNum); + END; +END; + +FUNCTION NodeListMCI(CONST s: ASTR; Data1,Data2: Pointer): STRING; +VAR + NodeRecPtr: ^NodeRecordType; + NodeNum: ^Byte; +BEGIN + NodeRecPtr := Data1; + NodeNum := Data2; + NodeListMCI := s; + IF (NOT (NActive IN NodeRecPtr^.Status)) OR + (NodeRecPtr^.User > (MaxUsers - 1)) OR + (NodeRecPtr^.User < 1) OR + ((NInvisible IN NodeRecPtr^.Status) AND + (NOT CoSysOp)) THEN + BEGIN + NodeListMCI := '-'; + WITH NodeRecPtr^ DO + CASE s[1] OF + 'N' : IF (s[2] = 'N') THEN + NodeListMCI := IntToStr(NodeNum^); + 'A' : CASE s[2] OF + 'C' : NodelistMCI := RGNoteStr(33,TRUE); + 'V' : NodeListMCI := AOnOff((NAvail IN Status),'Y','N'); + END; + 'U' : IF (s[2] = 'N') THEN + NodeListMCI := RGNoteStr(34,TRUE); + END; + END + ELSE + WITH NodeRecPtr^ DO + CASE s[1] OF + 'A' : CASE s[2] OF + 'C' : NodeListMCI := ActivityDesc; + 'G' : NodeListMCI := IntToStr(Age); + 'T' : NodeListMCI := AOnOff((NActive IN Status),'Y','N'); + 'V' : NodeListMCI := AOnOff((NAvail IN Status),'Y','N'); + END; + 'L' : IF (s[2] = 'C') THEN + NodeListMCI := CityState; + 'N' : IF (s[2] = 'N') THEN + NodeListMCI := IntToStr(NodeNum^); + 'U' : IF (s[2] = 'N') THEN + NodeListMCI := Caps(UserName); + 'R' : IF (s[2] = 'M') THEN + NodeListMCI := IntToStr(Room); + 'S' : IF (s[2] = 'X') THEN + NodeListMCI := Sex; + 'T' : IF (s[2] = 'O') THEN + NodeListMCI := IntToStr((GetPackDateTime - LogonTime) DIV 60); + END; +END; + +PROCEDURE lListNodes; +VAR + NodeNum: Byte; +BEGIN + IF (NOT General.MultiNode) THEN + BEGIN + NL; + Print('This BBS is currently not operating in Multi-Node.'); + Exit; + END; + Abort := FALSE; + Next := FALSE; + AllowContinue := TRUE; + IF (NOT ReadBuffer('NODELM')) THEN + Exit; + PrintF('NODELH'); + NodeNum := 1; + WHILE (NodeNum <= MaxNodes) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + LoadNode(NodeNum); + DisplayBuffer(NodeListMCI,@NodeR,@NodeNum); + Inc(NodeNum); + END; + IF (NOT Abort) THEN + PrintF('NODELT'); + AllowContinue := FALSE; +END; + +END. diff --git a/SOURCE/MYIO.PAS b/SOURCE/MYIO.PAS new file mode 100644 index 0000000..71e471b --- /dev/null +++ b/SOURCE/MYIO.PAS @@ -0,0 +1,708 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R+,S-,V-} + +UNIT MyIO; + +INTERFACE + +TYPE + AStr = STRING[160]; + WindowRec = ARRAY[0..8000] OF Byte; + ScreenType = ARRAY [0..3999] OF Byte; + Infield_Special_Function_Proc_Rec = PROCEDURE(c: Char); + +CONST + Infield_Seperators: SET OF Char = [' ','\','.']; + + Infield_Only_Allow_On: BOOLEAN = FALSE; + Infield_Arrow_Exit: BOOLEAN = FALSE; + Infield_Arrow_Exited: BOOLEAN = FALSE; + Infield_Arrow_Exited_Keep: BOOLEAN = FALSE; + Infield_Special_Function_On: BOOLEAN = FALSE; + Infield_Arrow_Exit_TypeDefs: BOOLEAN = FALSE; + Infield_Normal_Exit_Keydefs: BOOLEAN = FALSE; + Infield_Normal_Exited: BOOLEAN = FALSE; + +VAR + Wind: WindowRec; +{$IFDEF MSDOS} + MonitorType: Byte ABSOLUTE $0000:$0449; + ScreenAddr: ScreenType ABSOLUTE $B800:$0000; +{$ENDIF} +{$IFDEF WIN32} + MonitorType: Byte = 3; // REENOTE 3=CO80, a safe assumption I think +{$ENDIF} + ScreenSize: Integer; + MaxDisplayRows, + MaxDisplayCols, + Infield_Out_FGrd, + Infield_Out_BkGd, + Infield_Inp_FGrd, + Infield_Inp_BkGd, + Infield_Last_Arrow, + Infield_Last_Normal: Byte; + Infield_Special_Function_Proc: infield_special_function_proc_rec; + Infield_Only_Allow, + Infield_Special_Function_Keys, + Infield_Arrow_Exit_Types, + Infield_Normal_Exit_Keys: STRING; + +{$IFDEF MSDOS} +PROCEDURE Update_Logo(VAR Addr1,Addr2; BlkLen: Integer); +{$ENDIF} +{$IFDEF WIN32} +procedure Update_Logo(Data: Array of Char; OriginX, OriginY, DataLength: integer); +{$ENDIF} +PROCEDURE CursorOn(b: BOOLEAN); +PROCEDURE infield1(x,y: Byte; VAR s: AStr; Len: Byte); +PROCEDURE Infielde(VAR s: AStr; Len: Byte); +PROCEDURE Infield(VAR s: AStr; Len: Byte); +FUNCTION l_yn: BOOLEAN; +FUNCTION l_pynq(CONST s: AStr): BOOLEAN; +PROCEDURE CWrite(CONST s: AStr); +PROCEDURE CWriteAt(x,y: Integer; CONST s: AStr); +FUNCTION CStringLength(CONST s: AStr): Integer; +PROCEDURE cwritecentered(y: Integer; CONST s: AStr); +PROCEDURE Box(LineType,TLX,TLY,BRX,BRY: Integer); +PROCEDURE SaveScreen(VAR Wind: WindowRec); +PROCEDURE RemoveWindow(VAR Wind: WindowRec); +PROCEDURE SetWindow(VAR Wind: WindowRec; TLX,TLY,BRX,BRY,TColr,BColr,BoxType: Integer); + +IMPLEMENTATION + +USES + Crt +{$IFDEF WIN32} + ,RPScreen + ,VpSysLow +{$ENDIF} + ; + +{$IFDEF WIN32} +VAR + SavedScreen: TScreenBuf; +{$ENDIF} + +{$IFDEF MSDOS} +PROCEDURE CursorOn(b: BOOLEAN); ASSEMBLER; +ASM + cmp b, 1 + je @turnon + mov ch, 9 + mov cl, 0 + jmp @goforit + @turnon: + mov ch, 6 + mov cl, 7 + @goforit: + mov ah,1 + int 10h +END; +{$ENDIF} +{$IFDEF WIN32} +PROCEDURE CursorOn(b: BOOLEAN); +BEGIN + if (b) then + begin + RPShowCursor; + end else + begin + RPHideCursor; + end; +END; +{$ENDIF} + +PROCEDURE infield1(x,y: Byte; VAR s: AStr; Len: Byte); +VAR + SaveS: AStr; + c: Char; + SaveTextAttr, + SaveX, + SaveY: Byte; + i, + p, + z: Integer; + Ins, + Done, + NoKeyYet: BOOLEAN; + + PROCEDURE gocpos; + BEGIN + GoToXY(x + p - 1,y); + END; + + PROCEDURE Exit_W_Arrow; + VAR + i: Integer; + BEGIN + Infield_Arrow_Exited := TRUE; + Infield_Last_Arrow := Ord(c); + Done := TRUE; + IF (Infield_Arrow_Exited_Keep) THEN + BEGIN + z := Len; + FOR i := Len DOWNTO 1 DO + IF (s[i] = ' ') THEN + Dec(z) + ELSE + i := 1; + s[0] := chr(z); + END + ELSE + s := SaveS; + END; + + PROCEDURE Exit_W_Normal; + VAR + i: Integer; + BEGIN + Infield_Normal_Exited := TRUE; + Infield_Last_Normal := Ord(c); + Done := TRUE; + IF (Infield_Arrow_Exited_Keep) THEN + BEGIN + z := Len; + FOR i := Len DOWNTO 1 DO + IF (s[i] = ' ') THEN + Dec(z) + ELSE + i := 1; + s[0] := chr(z); + END + ELSE + s := SaveS; + END; + +BEGIN + SaveTextAttr := TextAttr; + SaveX := WhereX; + SaveY := WhereY; + SaveS := s; + Ins := FALSE; + Done := FALSE; + Infield_Arrow_Exited := FALSE; + GoToXY(x,y); + TextAttr := (Infield_Inp_BkGd * 16) + Infield_Inp_FGrd; + FOR i := 1 TO Len DO + Write(' '); + FOR i := (Length(s) + 1) TO Len DO + s[i] := ' '; + GoToXY(x,y); + Write(s); + p := 1; + gocpos; + NoKeyYet := TRUE; + REPEAT + REPEAT + c := ReadKey + UNTIL ((NOT Infield_Only_Allow_On) OR + (Pos(c,Infield_Special_Function_Keys) <> 0) OR + (Pos(c,Infield_Normal_Exit_Keys) <> 0) OR + (Pos(c,Infield_Only_Allow) <> 0) OR (c = #0)); + + IF ((Infield_Normal_Exit_Keydefs) AND + (Pos(c,Infield_Normal_Exit_Keys) <> 0)) THEN + Exit_W_Normal; + + IF ((Infield_Special_Function_On) AND + (Pos(c,Infield_Special_Function_Keys) <> 0)) THEN + Infield_Special_Function_Proc(c) + ELSE + BEGIN + IF (NoKeyYet) THEN + BEGIN + NoKeyYet := FALSE; + IF (c IN [#32..#255]) THEN + BEGIN + GoToXY(x,y); + FOR i := 1 TO Len DO + BEGIN + Write(' '); + s[i] := ' '; + END; + GoToXY(x,y); + END; + END; + CASE c OF + #0 : BEGIN + c := ReadKey; + IF ((Infield_Arrow_Exit) AND (Infield_Arrow_Exit_TypeDefs) AND + (Pos(c,Infield_Arrow_Exit_Types) <> 0)) THEN + Exit_W_Arrow + ELSE + CASE c OF + #72,#80 : + IF (Infield_Arrow_Exit) THEN + Exit_W_Arrow; + #75 : IF (p > 1) THEN + Dec(p); + #77 : IF (p < Len + 1) THEN + Inc(p); + #71 : p := 1; + #79 : BEGIN + z := 1; + FOR i := Len DOWNTO 2 DO + IF ((s[i - 1] <> ' ') AND (z = 1)) THEN + z := i; + IF (s[z] = ' ') THEN + p := z + ELSE + p := Len + 1; + END; + #82 : Ins := NOT Ins; + #83 : IF (p <= Len) THEN + BEGIN + FOR i := p TO (Len - 1) DO + BEGIN + s[i] := s[i + 1]; + Write(s[i]); + END; + s[Len] := ' '; + Write(' '); + END; + #115 : IF (p > 1) THEN + BEGIN + i := (p - 1); + WHILE ((NOT (s[i - 1] IN Infield_Seperators)) OR + (s[i] IN Infield_Seperators)) AND (i > 1) DO + Dec(i); + p := i; + END; + #116 : IF (p <= Len) THEN + BEGIN + i := p + 1; + WHILE ((NOT (s[i-1] IN Infield_Seperators)) OR + (s[i] IN Infield_Seperators)) AND (i <= Len) DO + Inc(i); + p := i; + END; + #117 : IF (p <= Len) THEN + FOR i := p TO Len DO + BEGIN + s[i] := ' '; + Write(' '); + END; + END; + gocpos; + END; + #27 : BEGIN + s := SaveS; + Done := TRUE; + END; + #13 : BEGIN + Done := TRUE; + z := Len; + FOR i := Len DOWNTO 1 DO + IF (s[i] = ' ') THEN + Dec(z) + ELSE + i := 1; + s[0] := chr(z); + END; + #8 : IF (p <> 1) THEN + BEGIN + Dec(p); + s[p] := ' '; + gocpos; + Write(' '); + gocpos; + END; + ELSE + IF ((c IN [#32..#255]) AND (p <= Len)) THEN + BEGIN + IF ((Ins) AND (p <> Len)) THEN + BEGIN + Write(' '); + FOR i := Len DOWNTO (p + 1) DO + s[i] := s[i - 1]; + FOR i := (p + 1) TO Len DO + Write(s[i]); + gocpos; + END; + Write(c); + s[p] := c; + Inc(p); + END; + END; + END; + UNTIL (Done); + GoToXY(x,y); + TextAttr := (Infield_Out_BkGd * 16) + Infield_Out_FGrd; + FOR i := 1 TO Len DO + Write(' '); + GoToXY(x,y); + Write(s); + GoToXY(SaveX,SaveY); + TextAttr := SaveTextAttr; + Infield_Only_Allow_On := FALSE; + Infield_Special_Function_On := FALSE; + Infield_Normal_Exit_Keydefs := FALSE; +END; + +PROCEDURE Infielde(VAR s: AStr; Len: Byte); +BEGIN + infield1(WhereX,WhereY,s,Len); +END; + +PROCEDURE Infield(VAR S: AStr; Len: Byte); +BEGIN + S := ''; + Infielde(S,Len); +END; + +FUNCTION l_yn: BOOLEAN; +VAR + C: Char; +BEGIN + REPEAT + C := UpCase(ReadKey) + UNTIL (C IN ['Y','N',#13,#27]); + IF (C = 'Y') THEN + BEGIN + l_yn := TRUE; + WriteLn('Yes'); + END + ELSE + BEGIN + l_yn := FALSE; + WriteLn('No'); + END; +END; + +FUNCTION l_pynq(CONST S: AStr): BOOLEAN; +BEGIN + TextColor(4); + Write(S); + TextColor(11); + l_pynq := l_yn; +END; + +PROCEDURE CWrite(CONST S: AStr); +VAR + C: Char; + Counter: Byte; + LastB, + LastC: BOOLEAN; +BEGIN + LastB := FALSE; + LastC := FALSE; + FOR Counter := 1 TO Length(S) DO + BEGIN + C := S[Counter]; + IF ((LastB) OR (LastC)) THEN + BEGIN + IF (LastB) THEN + TextBackGround(Ord(C)) + ELSE IF (LastC) THEN + TextColor(Ord(C)); + LastB := FALSE; + LastC := FALSE; + END + ELSE + CASE C OF + #2 : LastB := TRUE; + #3 : LastC := TRUE; + ELSE + Write(C); + END; + END; +END; + +PROCEDURE CWriteAt(x,y: Integer; CONST s: AStr); +BEGIN + GoToXY(x,y); + CWrite(s); +END; + +FUNCTION CStringLength(CONST s: AStr): Integer; +VAR + Len, + i: Integer; +BEGIN + Len := Length(s); + i := 1; + WHILE (i <= Length(s)) DO + BEGIN + IF ((s[i] = #2) OR (s[i] = #3)) THEN + BEGIN + Dec(Len,2); + Inc(i); + END; + Inc(i); + END; + CStringLength := Len; +END; + +PROCEDURE cwritecentered(y: Integer; CONST s: AStr); +BEGIN + CWriteAt(40 - (CStringLength(s) DIV 2),y,s); +END; + +{* + * Ŀ ͻ ķ ͸ + * 1 2 3 4 5 6 7 8 + * ͼ Ľ ; + *} +PROCEDURE Box(LineType,TLX,TLY,BRX,BRY: Integer); +VAR + TL,TR,BL,BR,HLine,VLine: Char; + i: Integer; +BEGIN + Window(1,1,MaxDisplayCols,MaxDisplayRows); + CASE LineType OF + 1 : BEGIN + TL := #218; + TR := #191; + BL := #192; + BR := #217; + VLine := #179; + HLine := #196; + END; + 2 : BEGIN + TL := #201; + TR := #187; + BL := #200; + BR := #188; + VLine := #186; + HLine := #205; + END; + 3 : BEGIN + TL := #176; + TR := #176; + BL := #176; + BR := #176; + VLine := #176; + HLine := #176; + END; + 4 : BEGIN + TL := #177; + TR := #177; + BL := #177; + BR := #177; + VLine := #177; + HLine := #177; + END; + 5 : BEGIN + TL := #178; + TR := #178; + BL := #178; + BR := #178; + VLine := #178; + HLine := #178; + END; + 6 : BEGIN + TL := #219; + TR := #219; + BL := #219; + BR := #219; + VLine := #219; + HLine := #219; + END; + 7 : BEGIN + TL := #214; + TR := #183; + BL := #211; + BR := #189; + VLine := #186; + HLine := #196; + END; + 8 : BEGIN + TL := #213; + TR := #184; + BL := #212; + BR := #190; + VLine := #179; + HLine := #205; + END; + ELSE + BEGIN + TL := #32; + TR := #32; + BL := #32; + BR := #32; + VLine := #32; + HLine := #32; + END; + END; + GoToXY(TLX,TLY); + Write(TL); + GoToXY(BRX,TLY); + Write(TR); + GoToXY(TLX,BRY); + Write(BL); + GoToXY(BRX,BRY); + Write(BR); + FOR i := (TLX + 1) TO (BRX - 1) DO + BEGIN + GoToXY(i,TLY); + Write(HLine); + END; + FOR i := (TLX + 1) TO (BRX - 1) DO + BEGIN + GoToXY(i,BRY); + Write(HLine); + END; + FOR i := (TLY + 1) TO (BRY - 1) DO + BEGIN + GoToXY(TLX,i); + Write(VLine); + END; + FOR i := (TLY + 1) TO (BRY - 1) DO + BEGIN + GoToXY(BRX,I); + Write(VLine); + END; + IF (LineType > 0) THEN + Window((TLX + 1),(TLY + 1),(BRX - 1),(BRY - 1)) + ELSE + Window(TLX,TLY,BRX,BRY); +END; + +PROCEDURE SaveScreen(VAR Wind: WindowRec); +BEGIN +{$IFDEF MSDOS} + Move(ScreenAddr[0],Wind[0],ScreenSize); +{$ENDIF} +{$IFDEF WIN32} + RPSaveScreen(SavedScreen); +{$ENDIF} +END; + +PROCEDURE RemoveWindow(VAR Wind: WindowRec); +BEGIN +{$IFDEF MSDOS} + Move(Wind[0],ScreenAddr[0],ScreenSize); +{$ENDIF} +{$IFDEF WIN32} + RPRestoreScreen(SavedScreen); +{$ENDIF} +END; + +PROCEDURE SetWindow(VAR Wind: WindowRec; TLX,TLY,BRX,BRY,TColr,BColr,BoxType:Integer); +BEGIN + SaveScreen(Wind); { save under Window } + Window(TLX,TLY,BRX,BRY); { SET Window size } + TextColor(TColr); + TextBackGround(BColr); + ClrScr; { clear window for action } + Box(BoxType,TLX,TLY,BRX,BRY); { Set the border } +END; + +{$IFDEF MSDOS} +PROCEDURE Update_Logo(VAR Addr1,Addr2; BlkLen: Integer); +BEGIN + INLINE ( + $1E/ + $C5/$B6/ADDR1/ + $C4/$BE/ADDR2/ + $8B/$8E/BLKLEN/ + $E3/$5B/ + $8B/$D7/ + $33/$C0/ + $FC/ + $AC/ + $3C/$20/ + $72/$05/ + $AB/ + $E2/$F8/ + $EB/$4C/ + $3C/$10/ + $73/$07/ + $80/$E4/$F0/ + $0A/$E0/ + $EB/$F1/ + $3C/$18/ + $74/$13/ + $73/$19/ + $2C/$10/ + $02/$C0/ + $02/$C0/ + $02/$C0/ + $02/$C0/ + $80/$E4/$8F/ + $0A/$E0/ + $EB/$DA/ + $81/$C2/$A0/$00/ + $8B/$FA/ + $EB/$D2/ + $3C/$1B/ + $72/$07/ + $75/$CC/ + $80/$F4/$80/ + $EB/$C7/ + $3C/$19/ + $8B/$D9/ + $AC/ + $8A/$C8/ + $B0/$20/ + $74/$02/ + $AC/ + $4B/ + $32/$ED/ + $41/ + $F3/$AB/ + $8B/$CB/ + $49/ + $E0/$AA/ + $1F); +END; +{$ENDIF} +{$IFDEF WIN32} +procedure Update_Logo(Data: Array of Char; OriginX, OriginY, DataLength: integer); +var + i, x, y, count, counter: Integer; + character: Char; + spaces: String; +begin + i := 0; + x := OriginX; + y := OriginY; + spaces := ' '; // 80 spaces + + while (i < DataLength) do + begin + case Data[i] of + #0..#15: begin + TextColor(Ord(Data[i])); + end; + #16..#23: begin + TextBackground(Ord(Data[i]) - 16); + end; + #24: begin + x := OriginX; + Inc(y); + end; + #25: begin + Inc(i); + count := Ord(Data[i])+1; + SysWrtCharStrAtt(@spaces[1], count, x-1, y-1, TextAttr); + Inc(x, count); + end; + #26: begin + Inc(i); + count := Ord(Data[i])+1; + Inc(i); + character := Data[i]; + for counter := 1 to count do + begin + SysWrtCharStrAtt(@Data[i], 1, x-1, y-1, TextAttr); + Inc(x); + end; + end; + #27: begin + TextAttr := TextAttr XOR $80; // Invert blink flag + end; + #32..#255: begin + SysWrtCharStrAtt(@Data[i], 1, x-1, y-1, TextAttr); + Inc(x); + end; + end; + Inc(i); + end; +end; +{$ENDIF} + +END. diff --git a/SOURCE/NEWUSERS.PAS b/SOURCE/NEWUSERS.PAS new file mode 100644 index 0000000..d9b0313 --- /dev/null +++ b/SOURCE/NEWUSERS.PAS @@ -0,0 +1,284 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT NewUsers; + +INTERFACE + +PROCEDURE NewUser; +PROCEDURE NewUserInit; + +IMPLEMENTATION + +USES + Common, + CUser, + EMail, + Mail0, + Menus, + MiscUser, + Script, + SysOp2G, + TimeFunc; + +PROCEDURE NewUser; +VAR + Letter: Text; + User: UserRecordType; + UserIDX: UserIDXRec; + MHeader: MHeaderRec; + TempStr: STRING; + Cmd, + NewMenuCmd: AStr; + NewUserPassword: Str20; + SaveMenu, + PasswordAttemps, + CmdToExec: Byte; + Counter, + Counter1, + TempNewApp: Integer; + CmdNotHid, + CmdExists, + Done: Boolean; +BEGIN + SL1('* New user logon'); + + UserNum := 0; + + Update_Node(RGNoteStr(36,TRUE){'New user logging on'},TRUE); + + UserNum := -1; + + IF (General.NewUserPW <> '') THEN + BEGIN + PasswordAttemps := 0; + NewUserPassword := ''; + WHILE ((NewUserPassword <> General.NewUserPW) AND (PasswordAttemps < General.MaxLogonTries) AND (NOT HangUp)) DO + BEGIN + (* + Prt(FString.NewUserPassword); + *) + RGMainStr(10,FALSE); + GetPassword(NewUserPassword,20); + IF ((NewUserPassword <> '') AND (General.NewUserPW <> NewUserPassword)) THEN + BEGIN + (* + Print('Invalid password, keep trying ...'); + *) + RGNoteStr(38,FALSE); + SL1('* Invalid new user password: '+NewUserPassword); + Inc(PasswordAttemps); + END; + END; + IF (PasswordAttemps >= General.MaxLogonTries) THEN + BEGIN + PrintF('NUPWFAIL'); + IF (NoFile) THEN + (* + Print('You have exceeded the maximum new user logon attempts, hanging up ...'); + *) + RGNoteStr(39,FALSE); + SL1('* Maximum new user logon attempts exceeded - hung user up.'); + HangUp := TRUE; + END; + END; + + IF (NOT HangUp) THEN + BEGIN + PrintF('NEWUSER'); + Counter := 1; + WHILE (Counter <= 20) AND (NOT HangUp) DO + BEGIN + IF (General.NewUserToggles[Counter] <> 0) THEN + BEGIN + Update_Screen; + CStuff(General.NewUserToggles[Counter],1,ThisUser); + END; + Inc(Counter); + END; + + Abort := FALSE; + Next := FALSE; + + SaveMenu := CurMenu; + CurMenu := General.NewUserInformationMenu; + LoadMenuPW; + AutoExecCmd('FIRSTCMD'); + REPEAT + MainMenuHandle(Cmd); + NewMenuCmd := ''; + CmdToExec := 0; + Done := FALSE; + REPEAT + FCmd(Cmd,CmdToExec,CmdExists,CmdNotHid); + IF (CmdToExec <> 0) THEN + BEGIN + DoMenuCommand(Done, + MemCmd^[CmdToExec].CmdKeys, + MemCmd^[CmdToExec].Options, + NewMenuCmd, + MemCmd^[CmdToExec].NodeActivityDesc); + + IF (MemCmd^[CmdToExec].CmdKeys = 'OQ') THEN + Abort := TRUE; + + END; + UNTIL (CmdToExec = 0) OR (Done) OR (HangUp); + UNTIL (Abort) OR (Next) OR (HangUp); + CurMenu := SaveMenu; + NewMenuToLoad := TRUE; + LastError := IOResult; + + END; + IF (NOT HangUp) THEN + BEGIN + (* + Prompt('Saving your information ... '); + *) + RGNoteStr(40,FALSE); + SysOpLog('Saving new user information ...'); + Counter1 := 0; + Counter := 1; + Reset(UserIDXFile); + WHILE (Counter <= (FileSize(UserIDXFile) - 1)) AND (Counter1 = 0) DO + BEGIN + Read(UserIDXFile,UserIDX); + IF (UserIDX.Deleted) THEN + BEGIN + LoadURec(User,UserIDX.Number); + IF (Deleted IN User.SFlags) THEN + Counter1 := UserIDX.Number; + END; + Inc(Counter); + END; + Close(UserIDXFile); + LastError := IOResult; + IF (Counter1 > 0) THEN + UserNum := Counter1 + ELSE + UserNum := MaxUsers; + WITH ThisUser DO + BEGIN + FirstOn := GetPackDateTime; + LastOn := FirstOn; + IF (CallerIDNumber <> '') THEN + BEGIN + CallerID := CallerIDNumber; + Note := CallerID; + END; + END; + + SaveURec(ThisUser,UserNum); + + AutoValidate(ThisUser,UserNum,'!'); + + InsertIndex(ThisUser.Name,UserNum,FALSE,FALSE); + InsertIndex(ThisUser.Realname,UserNum,TRUE,FALSE); + Inc(lTodayNumUsers); + SaveGeneral(TRUE); + (* + Print('^3Saved.'); + *) + RGNoteStr(41,FALSE); + SysOpLog('Saved as user #'+IntToStr(UserNum)); + UserOn := TRUE; + WasNewUser := TRUE; + END; + IF (NOT HangUp) THEN + BEGIN + CLS; + IF ((Exist(General.MiscPath+'NEWUSER.INF')) OR (Exist(General.DataPath+'NEWUSER.INF'))) THEN + ReadQ('NEWUSER'); + Update_Screen; + TempNewApp := -1; + IF (General.NewApp <> -1) THEN + BEGIN + TempNewApp := General.NewApp; + IF (TempNewApp < 1) OR (TempNewApp > (MaxUsers - 1)) THEN + BEGIN + SL1('* Invalid user number for New User Application: '+IntToStr(General.NewApp)); + TempNewApp := 1; + END; + END; + IF (TempNewApp <> -1) THEN + BEGIN + PrintF('NEWAPP'); + IF (NoFile) THEN + (* + Print('You must now send a new user application letter to the SysOp.'); + *) + RGNoteStr(42,FALSE); + InResponseTo := '\'+#1+RGNoteStr(43,TRUE); { 'New User Application' } + MHeader.Status := []; + SeMail(TempNewApp,MHeader); + END; + END; + IF (NOT HangUp) THEN + BEGIN + IF (Exist(General.MiscPath+'NEWLET.ASC')) THEN + BEGIN + FillChar(MHeader,SizeOf(MHeader),0); + InitMsgArea(-1); + Reset(MsgHdrF); + Seek(MsgHdrF,FileSize(MsgHdrF)); + Reset(MsgTxtF,1); + Seek(MsgTxtF,FileSize(MsgTxtF)); + MHeader.Pointer := (FileSize(MsgTxtF) + 1); + MHeader.TextSize := 0; + Assign(Letter,General.MiscPath+'NEWLET.ASC'); + Reset(Letter); + ReadLn(Letter,MHeader.From.A1S); + ReadLn(Letter,MHeader.Subject); + WITH MHeader DO + BEGIN + From.UserNum := TempNewApp; + MTO.UserNum := UserNum; + MTO.A1S := ThisUser.Name; + Date := GetPackDateTime; + Status := [AllowMCI]; + END; + WHILE NOT EOF(Letter) DO + BEGIN + ReadLn(Letter,TempStr); + Inc(MHeader.TextSize,(Length(TempStr) + 1)); + BlockWrite(MsgTxtF,TempStr[0],(Length(TempStr) + 1)); + END; + Close(Letter); + Close(MsgTxtF); + Write(MsgHdrF,MHeader); + Close(MsgHdrF); + LastError := IOResult; + ThisUser.Waiting := 1; + END; + END; +END; + +PROCEDURE NewUserInit; +BEGIN + IF (General.ClosedSystem) THEN + BEGIN + PrintF('NONEWUSR'); + IF (NoFile) THEN + (* + Print('This BBS is currently not accepting new users, hanging up ...'); + *) + RGNoteStr(32,FALSE); + SL1('* Attempted logon when BBS closed to new users - hung user up.'); + HangUp := TRUE; + END + ELSE + BEGIN + LoadURec(ThisUser,0); + WITH ThisUser DO + BEGIN + FirstOn := GetPackDateTime; + LastOn := FirstOn; + END; + InitTrapFile; + END; +END; + +END. diff --git a/SOURCE/NODELIST.PAS b/SOURCE/NODELIST.PAS new file mode 100644 index 0000000..684380e --- /dev/null +++ b/SOURCE/NODELIST.PAS @@ -0,0 +1,652 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT Nodelist; + +INTERFACE + +USES + Common; + +PROCEDURE ToggleNetAttr(NetAttrT: NetAttr; VAR NetAttrS: NetAttribs); +PROCEDURE ToggleNetAttrs(C: CHAR; VAR NetAttrS: NetAttribs); +FUNCTION GetNewAddr(DisplayStr: AStr; MaxLen: Byte; VAR Zone,Net,Node,Point: SmallWord): Boolean; +PROCEDURE GetNetAddress(VAR SysOpName: AStr; VAR Zone,Net,Node,Point: SmallWord; var Fee: Word; GetFee: Boolean); +PROCEDURE ChangeFlags(VAR MsgHeader: MHeaderRec); +FUNCTION NetMail_Attr(NetAttribute: NetAttribs): AStr; + +IMPLEMENTATION + +USES + Mail0; + +TYPE + CompProc = FUNCTION(VAR ALine,Desire; L: Char): Integer; + + DATRec = RECORD + Zone, { Zone of board } + Net, { Net Address of board } + Node, { Node Address of board } + Point: SmallInt; { Either Point number OR 0 } + CallCost, { Cost to sysop to send } + MsgFee, { Cost to user to send } + NodeFlags: SmallWord; { Node flags } + ModemType, { Modem TYPE } + PassWord: STRING[9]; + Phone, + BName, + CName, + SName: STRING[39]; + BaudRate, { Highest Baud Rate } + RecSize: Byte; { Size of the Node on FILE } + END; + + IndxRefBlk = RECORD + IndxOfs, { Offset of STRING into block } + IndxLen: SmallWord; { Length of STRING } + IndxData, { RECORD number of STRING } + IndxPtr: LongInt; { Block number of lower index } + END; { IndxRef } + + LeafRefBlk = RECORD + KeyOfs, { Offset of STRING into block } + KeyLen: SmallWord; { Length of STRING } + KeyVal: LongInt; { Pointer to Data block } + END; { LeafRef } + + CtlBlk = RECORD + CtlBlkSize: SmallWord; { blocksize of Index blocks } + CtlRoot, { Block number of Root } + CtlHiBlk, { Block number of last block } + CtlLoLeaf, { Block number of first leaf } + CtlHiLeaf, { Block number of last leaf } + CtlFree: LongInt; { Head of freelist } + CtlLvls, { Number of index levels } + CtlParity: SmallWord; { XOR of above fields } + END; + + INodeBlk = RECORD + IndxFirst, { Pointer to next lower level } + IndxBLink, { Pointer to previous link } + IndxFLink: LongInt; { Pointer to next link } + IndxCnt: SmallInt; { Count of Items IN block } + IndxStr: SmallWord; { Offset IN block of 1st str } + { IF IndxFirst is NOT -1, this is INode: } + IndxRef: ARRAY [0..49] OF IndxRefBlk; + END; + + LNodeBlk = RECORD + IndxFirst, { Pointer to next lower level } + IndxBLink, { Pointer to previous link } + IndxFLink: LongInt; { Pointer to next link } + IndxCnt: SmallInt; { Count of Items IN block } + IndxStr: SmallWord; { Offset IN block of 1st str } + LeafRef: ARRAY [0..49] OF LeafRefBlk; + END; + +PROCEDURE ToggleNetAttr(NetAttrT: NetAttr; VAR NetAttrS: NetAttribs); +BEGIN + IF (NetAttrT IN NetAttrS) THEN + Exclude(NetAttrS,NetAttrT) + ELSE + Include(NetAttrS,NetAttrT); +END; + +PROCEDURE ToggleNetAttrs(C: CHAR; VAR NetAttrS: NetAttribs); +BEGIN + CASE C OF + 'C' : ToggleNetAttr(Crash,NetAttrS); + 'H' : ToggleNetAttr(Hold,NetAttrS); + 'I' : ToggleNetAttr(InTransit,NetAttrS); + 'K' : ToggleNetAttr(KillSent,NetAttrS); + 'L' : ToggleNetAttr(Local,NetAttrS); + 'P' : ToggleNetAttr(Private,NetAttrS); + END; +END; + +FUNCTION GetNewAddr(DisplayStr: AStr; MaxLen: Byte; VAR Zone,Net,Node,Point: SmallWord): Boolean; +BEGIN + GetNewAddr := FALSE; + Prt(DisplayStr); + MPL(MaxLen); + Input(DisplayStr,MaxLen); + IF (DisplayStr = '') OR (Pos('/',DisplayStr) = 0) THEN + Exit; + IF (Pos(':',DisplayStr) > 0) THEN + BEGIN + Zone := StrToInt(Copy(DisplayStr,1,Pos(':',DisplayStr))); + DisplayStr := Copy(DisplayStr,Pos(':',DisplayStr)+1,Length(DisplayStr)); + END + ELSE + Zone := 1; + IF (Pos('.',DisplayStr) > 0) THEN + BEGIN + Point := StrToInt(Copy(DisplayStr,Pos('.',DisplayStr)+1,Length(DisplayStr))); + DisplayStr := Copy(DisplayStr,1,Pos('.',DisplayStr)-1); + END + ELSE + Point := 0; + Net := StrToInt(Copy(DisplayStr,1,Pos('/',DisplayStr))); + Node := StrToInt(Copy(DisplayStr,Pos('/',DisplayStr)+1,Length(DisplayStr))); + GetNewAddr := TRUE; +END; + +FUNCTION NetMail_Attr(NetAttribute: NetAttribs): Astr; +VAR + s: AStr; +BEGIN + s := ''; + IF (Local IN NetAttribute) THEN + s := 'Local '; + IF (Private IN NetAttribute) THEN + s := s + 'Private '; + IF (Crash IN NetAttribute) THEN + s := s + 'Crash '; + IF (FileAttach IN NetAttribute) THEN + s := s + 'FileAttach '; + IF (InTransit IN NetAttribute) THEN + s := s + 'InTransit '; + IF (KillSent IN NetAttribute) THEN + s := s + 'KillSent '; + IF (Hold IN NetAttribute) THEN + s := s + 'Hold '; + IF (FileRequest IN NetAttribute) THEN + s := s + 'File Request '; + IF (FileUpdateRequest IN NetAttribute) THEN + s := s + 'Update Request '; + NetMail_Attr := s; +END; + +FUNCTION CompName(VAR ALine,Desire; L: Char): Integer; +VAR + Key, + Desired: STRING[36]; + Len: Byte ABSOLUTE L; +BEGIN + Key[0] := L; + Desired[0] := L; + Move(ALine,Key[1],Len); + Move(Desire,Desired[1],Len); + IF (Key > Desired) THEN + CompName := 1 + ELSE IF (Key < Desired) THEN + CompName := -1 + ELSE + CompName := 0; +END; + +FUNCTION CompAddress(VAR ALine,Desire; L: Char): Integer; +TYPE + NodeType = RECORD + Zone, + Net, + Node, + Point: SmallWord; + END; +VAR + Key: NodeType ABSOLUTE ALine; + Desired: NodeType ABSOLUTE Desire; + Count: Byte; + K: Integer; +BEGIN + Count := 0; + REPEAT + Inc(Count); + CASE Count OF + 1 : Word(K) := Key.Zone - Desired.Zone; + 2 : Word(K) := Key.Net - Desired.Net; + 3 : Word(K) := Key.Node - Desired.Node; + 4 : BEGIN + IF (L = #6) THEN + Key.Point := 0; + Word(K) := Key.Point - Desired.Point; + END; + END; + UNTIL (Count = 4) OR (K <> 0); + Compaddress := K; +END; + +PROCEDURE GetNetAddress(VAR SysOpName: AStr; VAR Zone,Net,Node,Point: SmallWord; var Fee: Word; GetFee: Boolean); +VAR + DataFile, + NDXFile: FILE; + s: STRING[36]; + Location: LongInt; + Dat: DatRec; + Internet: Boolean; + + FUNCTION FullNodeStr(NodeStr: AStr): STRING; + { These constants are the defaults IF the user does NOT specify them } + CONST + DefZone = '1'; { Default Zone } + DefNet = '1'; { Default Net } + DefNode = '1'; { Default Node } + DefPoint = '0'; { Default Point } + BEGIN + IF (NodeStr[1] = '.') THEN + NodeStr := DefNode + NodeStr; + IF (Pos('/',NodeStr) = 0) THEN + IF (Pos(':',NodeStr) = 0) THEN + NodeStr := DefZone+':'+DefNet+'/'+NodeStr + ELSE + ELSE + BEGIN + IF (NodeStr [1] = '/') THEN + NodeStr := DefNet + NodeStr; + IF (Pos(':',NodeStr) = 0) THEN + NodeStr := DefZone + ':' + NodeStr; + IF (NodeStr[Length(NodeStr)] = '/') THEN + NodeStr := NodeStr + DefNode; + END; + IF (Pos('.',NodeStr) = 0) THEN + NodeStr := NodeStr+'.'+DefPoint; + FullNodeStr := NodeStr; + END; + + FUNCTION MakeAddress(Z,Nt,N,P: Word): STRING; + TYPE + NodeType = RECORD { A Node address TYPE } + Len: Byte; + Zone, + Net, + Node, + Point: SmallWord; + END; + VAR + Address: NodeType; + S2: STRING ABSOLUTE Address; + BEGIN + WITH Address DO + BEGIN + Zone := Z; + Net := Nt; + Node := N; + Point := P; + Len := 8; + END; + MakeAddress := S2; + END; + + FUNCTION MakeName(Name: AStr): STRING; + VAR + Temp: STRING[36]; + Comma: STRING[2]; + BEGIN + Temp := Caps(Name); + IF (Pos(' ', Name) > 0) THEN + Comma := ', ' + ELSE + Comma := ''; + MakeName := Copy(Temp, Pos(' ',Temp) + 1, Length(Temp) - Pos(' ',Temp)) + + Comma + Copy(Temp,1,Pos(' ',Temp) - 1) + #0; + END; + + PROCEDURE UnPk(S1: STRING; VAR S2: STRING; Count: Byte); + CONST + UnWrk: ARRAY [0..38] OF Char = ' EANROSTILCHBDMUGPKYWFVJXZQ-''0123456789'; + TYPE + CharType = RECORD + C1, + C2: Byte; + END; + VAR + U: CharType; + W1: Word ABSOLUTE U; + I, + J: Integer; + OBuf: ARRAY [0..2] OF Char; + Loc1, + Loc2: Byte; + BEGIN + S2 := ''; + Loc1 := 1; + Loc2 := 1; + WHILE (Count > 0) DO + BEGIN + U.C1 := Ord(S1[Loc1]); + Inc(Loc1); + U.C2 := Ord(S1[Loc1]); + Inc(Loc1); + Count := Count - 2; + for J := 2 downto 0 DO + BEGIN + I := W1 MOD 40; + W1 := W1 DIV 40; + OBuf[J] := UnWrk[I]; + END; + Move(OBuf,S2[Loc2],3); + Inc(Loc2,3); + END; + S2[0] := Chr(Loc2); + END; + + FUNCTION GetData(VAR F1: FILE; SL: LongInt; VAR Dat: DATRec): Boolean; + TYPE + RealDATRec = RECORD + Zone, { Zone of board } + Net, { Net Address of board } + Node, { Node Address of board } + Point: SmallInt; { Either Point number OR 0 } + CallCost, { Cost to sysop to send } + MsgFee, { Cost to user to send } + NodeFlags: SmallWord; { Node flags } + ModemType, { Modem TYPE } + PhoneLen, { Length of Phone Number } + PassWordLen, { Length of Password } + BNameLen, { Length of Board Name } + SNameLen, { Length of Sysop Name } + CNameLen, { Length of City/State Name } + PackLen, { Length of Packed STRING } + Baud: Byte; { Highest Baud Rate } + Pack: ARRAY [1..160] of Char; { The Packed STRING } + END; + VAR + Data: RealDATRec; + Error: Boolean; + UnPack: STRING[160]; + BEGIN + Seek(F1,SL); + { Read everything at once to keep disk access to a minimum } + BlockRead(F1,Data,SizeOf(Data)); + Error := (IOResult <> 0); + IF (NOT Error) THEN + WITH Dat,Data DO + BEGIN + Move(Data,Dat,15); + Phone := Copy(Pack,1,PhoneLen); + PassWord := Copy(Pack,(PhoneLen + 1),PasswordLen); + Move(Pack[PhoneLen + PasswordLen + 1],Pack[1],PackLen); + UnPk(Pack,UnPack,PackLen); + BName := Caps(Copy(UnPack,1,BNameLen)); + SName := Caps(Copy(Unpack,(BNameLen + 1),SNameLen)); + CName := Caps(Copy(UnPack,BNameLen + SNameLen + 1,CNameLen)); + BaudRate := Baud; + RecSize := (PhoneLen + PassWordLen + PackLen) + 22; + END; + END; + + PROCEDURE Get7Node(VAR F: FILE; SL: LongInt; VAR Buf); + BEGIN + Seek(F,SL); + BlockRead(F,Buf,512); + IF (IOResult <> 0) THEN + Halt(1); + END; + + FUNCTION BTree(VAR F1: FILE; Desired: AStr; Compare: CompProc): LongInt; + LABEL + Return; + VAR + Buf: ARRAY [0..511] OF Char; { These four variables all occupy } + CTL: CTLBlk ABSOLUTE Buf; { the same memory location. Total } + INode: INodeBlk ABSOLUTE Buf; { of 512 bytes. } + LNode: LNodeBlk ABSOLUTE Buf; { --------------------------------- } + NodeCTL: CTLBlk; { Store the CTL block seperately } + ALine: STRING[160]; { Address from NDX FILE } + J, + K, + L,Count: Integer; { Temp integers } + TP: Word; { Pointer to location IN BUF } + Rec, { A temp RECORD IN the FILE } + FRec: LongInt; { The RECORD when found OR NOT } + BEGIN + FRec := -1; + Get7Node(F1,0,Buf); + IF (CTL.CTLBlkSize = 0) THEN GOTO + Return; + Move(Buf,NodeCTL,SizeOf(CTL)); + Get7Node(F1,NodeCTL.CtlRoot * NodeCTL.CtlBlkSize,Buf); + WHILE (INode.IndxFirst <> -1) AND (FRec = -1) DO + BEGIN + Count := INode.IndxCnt; + IF (Count = 0) THEN GOTO + Return; + J := 0; + K := -1; + WHILE (J < Count) AND (K < 0) DO + BEGIN + TP := INode.IndxRef[J].IndxOfs; + L := INode.IndxRef[J].IndxLen; + { ALine [0] := Chr (L); } + Move(Buf[TP],ALine[1],L); + K := Compare(ALine[1],Desired[1],Chr(L)); + IF (K = 0) THEN + FRec := INode.IndxRef[J].IndxData + ELSE IF (K < 0) THEN + Inc(J); + END; + IF (FRec = -1) THEN + BEGIN + IF (J = 0) THEN + Rec := INode.IndxFirst + ELSE + Rec := INode.IndxRef[J - 1].IndxPtr; + Get7Node(F1,Rec * NodeCTL.CtlBlkSize,Buf); + END; + END; + IF (FRec = -1) THEN + BEGIN + Count := LNode.IndxCnt; + IF (Count <> 0) THEN + BEGIN + J := 0; + WHILE (J < Count) AND (FRec = -1) DO + BEGIN + TP := LNode.LeafRef[J].KeyOfs; + L := LNode.LeafRef[J].KeyLen; + { ALine [0] := Chr (L); } + Move(Buf[TP],ALine[1],L); + K := Compare(ALine[1],Desired[1],Chr(L)); + IF (K = 0) THEN + FRec := LNode.LeafRef[J].KeyVal; + Inc(J); + END; + END; + END; + Return : + BTree := FRec; + END; + + FUNCTION Pull(VAR S: STRING; C: Char): STRING; + VAR + I: Byte; + BEGIN + I := Pos(C,S); + Pull := Copy(S,1,(I - 1)); + Delete(S,1,I); + END; + +BEGIN + NL; + Internet := FALSE; + IF NOT Exist(General.NodePath+'NODEX.DAT') OR + NOT Exist(General.NodePath+'SYSOP.NDX') OR + NOT Exist(General.NodePath+'NODEX.NDX') THEN + BEGIN + IF (GetFee) THEN + BEGIN + Fee := 0; + Exit; + END; + Print('Enter name of intended receiver.'); + Prt(':'); + InputDefault(SysOpName,SysOpName,36,[CapWords],TRUE); + IF (SysOpName = '') THEN + Exit; + IF (Pos('@',SysOpName) > 0) THEN + IF (PYNQ('Is this an Internet message? ',0,FALSE)) THEN + BEGIN + Internet := TRUE; + Zone := General.Aka[20].Zone; + Net := General.Aka[20].Net; + Node := General.Aka[20].Node; + Point := General.Aka[20].Point; + Fee := 0; + Exit; + END + ELSE + NL; + IF NOT GetNewAddr('Enter network address (^5Z^4:^5N^4/^5N^4.^5P^4 format): ',30,Zone,Net,Node,Point) THEN + Exit; + Exit; + END; + Assign(DataFile,General.NodePath+'NODEX.DAT'); + IF (GetFee) THEN + BEGIN + s := IntToStr(Net)+'/'+IntToStr(Node); + IF (Zone > 0) THEN + s := IntToStr(Zone)+':'+s; + IF (Point > 0) THEN + s := s+'.'+IntToStr(Point); + s := FullNodeStr(s); + Assign(NDXFile,General.NodePath+'NODEX.NDX'); + Reset(NDXFile,1); + Location := BTree(NDXFile,MakeAddress(StrToInt(Pull(S,':')), + StrToInt(Pull(S,'/')),StrToInt(Pull(S,'.')), + StrToInt(S)),Compaddress); + Close(NDXFile); + IF (Location <> -1) THEN + BEGIN + Reset(DataFile,1); + GetData(DataFile,Location,Dat); + Close(DataFile); + Fee := Dat.MsgFee; + END + ELSE + Fee := 0; + Exit; + END; + s := SysOpName; + SysOpName := ''; + Fee := 0; + REPEAT + Print('Enter a name, a Fidonet address, or an Internet address.'); + Prt(':'); + InputDefault(s,s,36,[],TRUE); + IF (s = '') THEN + Break; + IF (Pos('/',s) > 0) THEN + BEGIN + s := FullNodeStr(s); + Assign(NDXFile,General.NodePath+'NODEX.NDX'); + Reset(NDXFile,1); + Location := BTree(NDXFile,MakeAddress(StrToInt(Pull(S,':')),StrToInt(Pull(S,'/')),StrToInt(Pull(S,'.')),StrToInt(S)), + Compaddress); + Close(NDXFile); + END + ELSE + BEGIN + Assign(NDXFile,General.NodePath+'SYSOP.NDX'); + Reset(NDXFile,1); + Location := BTree(NDXFile,MakeName(S),CompName); + Close(NDXFile); + END; + IF (Location <> -1) THEN + BEGIN + Reset(DataFile,1); + GetData(DataFile,Location,Dat); + Close(DataFile); + WITH Dat DO + BEGIN + Print('^1System: '+BName+' ('+IntToStr(Zone)+':'+IntToStr(Net)+'/'+IntToStr(Node)+')'); + Print('SysOp : '+SName); + Print('Phone : '+Phone); + Print('Where : '+CName); + Print('Cost : '+IntToStr(MsgFee)+' credits'); + END; + NL; + IF (Dat.MsgFee > (ThisUser.lCredit - ThisUser.Debit)) THEN + BEGIN + Print('You do not have enough credit to netmail this Node!'); + s := ''; + END + ELSE IF PYNQ('Is this correct? ',0,FALSE) THEN + BEGIN + SysOpName := Dat.Sname; + Zone := Dat.Zone; + Net := Dat.Net; + Node := Dat.Node; + Point := 0; + Fee := Dat.MsgFee; + END + ELSE + s := ''; + END + ELSE IF (Pos('@',s) > 0) THEN + IF (NOT PYNQ('Is this an Internet message? ',0,FALSE)) THEN + BEGIN + Print('That name is not in the nodelist!'^M^J); + S := ''; + END + ELSE + BEGIN + Internet := TRUE; + SysOpName := s; + Zone := General.Aka[20].Zone; + Net := General.Aka[20].Net; + Node := General.Aka[20].Node; + Point := General.Aka[20].Point; + Fee := 0; + END + ELSE + BEGIN + Print('That name is not in the nodelist!'^M^J); + S := ''; + END + UNTIL (SysOpName <> '') OR (HangUp); + IF (NOT Internet) AND (Pos('/',s) = 0) AND (s <> '') THEN + BEGIN + NL; + Print('Enter name of intended receiver.'); + Prt(':'); + InputDefault(SysOpName,SysOpName,36,[CapWords],FALSE); + IF (SysOpName = '') THEN + Exit; + END; + LastError := IOResult; +END; + +PROCEDURE ChangeFlags(VAR MsgHeader: MHeaderRec); +VAR + Cmd: Char; +BEGIN + IF (CoSysOp) AND (PYNQ('Change default netmail flags? ',0,FALSE)) THEN + BEGIN + Cmd := #0; + NL; + REPEAT + IF (Cmd <> '?') THEN + BEGIN + Print('^4Current flags: ^5'+NetMail_Attr(MsgHeader.NetAttribute)); + NL + END; + Prt('Flag to change: '); + OneK(Cmd,'QPCAIKHRLU?'^M,TRUE,TRUE); + IF (Cmd IN ['?']) THEN + NL; + WITH MsgHeader DO + CASE Cmd OF + 'L' : ToggleNetAttr(Local,NetAttribute); + 'U' : ToggleNetAttr(FileUpdateRequest,NetAttribute); + 'R' : ToggleNetAttr(FileRequest,NetAttribute); + 'H' : ToggleNetAttr(Hold,NetAttribute); + 'K' : ToggleNetAttr(KillSent,NetAttribute); + 'I' : ToggleNetAttr(InTransit,NetAttribute); + 'A' : ToggleNetAttr(FileAttach,NetAttribute); + 'C' : ToggleNetAttr(Crash,NetAttribute); + 'P' : ToggleNetAttr(Private,NetAttribute); + '?' : BEGIN + LCmds3(15,3,'Private','Crash','Attached File'); + LCmds3(15,3,'InTransit','KillSent','Hold'); + LCmds3(15,3,'Req file','Update Req','Local'); + END; + END; + UNTIL (Cmd IN ['Q',^M]) OR (HangUp); + END; + NL; +END; + +END. diff --git a/SOURCE/OFFLINE.PAS b/SOURCE/OFFLINE.PAS new file mode 100644 index 0000000..a4c9003 --- /dev/null +++ b/SOURCE/OFFLINE.PAS @@ -0,0 +1,1225 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S-,V-} + +UNIT OffLine; + +INTERFACE + +PROCEDURE SetMessageAreaNewScanDate; +PROCEDURE DownloadPacket; +PROCEDURE uploadpacket(Already: Boolean); + +IMPLEMENTATION + +USES + Crt, + Dos, + Common, + Archive1, + ExecBat, + File0, + File1, + File2, + File8, + File11, + Mail0, + Mail1, + Mail2, + Mail4, + NodeList, + TimeFunc; + +TYPE + BSingle = ARRAY [0..3] OF Byte; + + NDXRec = RECORD + Pointer: BSingle; + Conf: Byte; + END; + + QWKHeadeRec = RECORD + Flag: Char; + Num: ARRAY [1..7] OF Char; + MsgDate: ARRAY [1..8] OF Char; + MsgTime: ARRAY [1..5] OF Char; + MsgTo: ARRAY [1..25] OF Char; + MsgFrom: ARRAY [1..25] OF Char; + MsgSubj: ARRAY [1..25] OF Char; + MsgPWord: STRING[11]; + RNum: STRING[7]; + NumBlocks: ARRAY [1..6] OF Char; + Status: Byte; + MBase: SmallWord; + Crap: STRING[3]; + END; + +(* +PROCEDURE SetFileAreaNewScanDate; +VAR + TempDate: Str10; + Key: CHAR; +BEGIN + { + NL; + Prt(FString.FileNewScan); + } + lRGLngStr(54,FALSE); + MPL(10); + Prompt(PD2Date(NewDate)); + Key := Char(GetKey); + IF (Key = #13) THEN + BEGIN + NL; + TempDate := PD2Date(NewDate); + END + ELSE + BEGIN + Buf := Key; + DOBackSpace(1,10); + InputFormatted('',TempDate,'##/##/####',TRUE); + IF (TempDate = '') THEN + TempDate := PD2Date(NewDate); + END; + IF (DayNum(TempDate) = 0) OR (DayNum(TempDate) > DayNum(DateStr)) THEN + BEGIN + NL; + Print('Invalid date entered.'); + END + ELSE + BEGIN + NL; + Print('New file scan date set to: ^5'+TempDate+'^1'); + NewDate := Date2PD(TempDate); + SL1('Reset file new scan date to: ^5'+TempDate+'.'); + END; +END; +*) + +PROCEDURE SetMessageAreaNewScanDate; +VAR + S: AStr; + DT: DateTime; + MArea, + SaveMsgArea: Integer; + l: LongInt; +BEGIN + NL; + Prt('Enter oldest date for new messages (mm/dd/yyyy): '); + + InputFormatted('',S,'##/##/####',TRUE); + IF (DayNum(S) = 0) THEN + BEGIN + NL; + Print('^7Invalid date entered!^1') + END + ELSE IF (S <> '') THEN + BEGIN + NL; + Print('Current newscan date is now: ^5'+S); + SaveMsgArea := MsgArea; + FillChar(DT,SizeOf(DT),0); + WITH DT DO + BEGIN + Month := StrToInt(Copy(S,1,2)); + Day := StrToInt(Copy(S,4,2)); + Year := StrToInt(Copy(S,7,4)); + END; + l := DateToPack(DT); + FOR MArea := 1 TO NumMsgAreas DO + BEGIN + InitMsgArea(MArea); + LastReadRecord.LastRead := L; + SaveLastReadRecord(LastReadRecord); + END; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); + SL1('Reset message last read pointers.'); + END; +END; + +PROCEDURE DownloadPacket; +VAR + IndexR: + NDXRec; + NDXFile, + PNDXFile: FILE OF NDXRec; + MsgFile: FILE; + ControlTxt: Text; + MHeader: MHeaderRec; + QWKHeader: QWKHeadeRec; + DT: DateTime; + TransferFlags: TransferFlagSet; + S, + Texts: STRING; + + C: Char; + + FArrayRecNum: Byte; + + MArea, + UseMsgArea, + AvailableMsgAreas, + SaveMsgArea, + SaveFileArea: Integer; + + + TotalNewMsgsInArea, + TotalYourMsgsInArea, + MsgNum, + TempTextSize: Word; + + X, + LastK, + Marker, + TotalMsgsAllAreas, + TotalNewMsgsAllAreas, + TotalYourMsgsAllAreas, + LastUpdate: LongInt; + + SaveConfSystem, + Ok: Boolean; + + PROCEDURE Real_To_Msb(PReal: Real; VAR B: BSingle); + VAR + R: ARRAY [0 .. 5] OF Byte ABSOLUTE PReal; + BEGIN + B[3] := R[0]; + Move(R[3],B[0],3); + END; + + PROCEDURE KillEmail; + VAR + MsgNum1: Word; + BEGIN + InitMsgArea(-1); + Reset(MsgHdrF); + IF (IOResult = 0) THEN + BEGIN + FOR MsgNum1 := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum1 - 1)); + Read(MsgHdrF,MHeader); + IF ToYou(MHeader) THEN + BEGIN + Include(MHeader.Status,MDeleted); + Seek(MsgHdrF,(MsgNum1 - 1)); + Write(MsgHdrF,MHeader); + END + END; + Close(MsgHdrF); + END; + ThisUser.Waiting := 0; + END; + + PROCEDURE Upload_Display; + BEGIN + LastUpdate := Timer; + IF (NOT Abort) THEN + Prompt(' '+PadRightInt(TotalNewMsgsInArea,7)+ + ''+PadRightInt(TotalYourMsgsInArea,6)+ + ''+PadRightStr(IntToStr((FileSize(MsgFile) - LastK) DIV 1024)+'k',8)); + END; + + PROCEDURE UpdatePointers; + VAR + MArea1: Integer; + MsgNum1: Word; + BEGIN + TotalNewMsgsAllAreas := 0; + FOR MArea1 := 1 TO NumMsgAreas DO + IF (CompMsgArea(MArea1,0) <> 0) THEN + BEGIN + InitMsgArea(MArea1); + IF AACS(MemMsgArea.ACS) AND ((LastReadRecord.NewScan) OR (MAForceRead IN MemMsgArea.MAFlags)) THEN + BEGIN + LastError := IOResult; + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + MsgNum1 := FirstNew; + IF (MsgNum1 > 0) THEN + TotalNewMsgsInArea := FileSize(MsgHdrF) - MsgNum1 + 1 + ELSE + TotalNewMsgsInArea := 0; + MsgNum1 := FileSize(MsgHdrF); + IF (TotalNewMsgsAllAreas + TotalNewMsgsInArea > General.MaxQWKTotal) THEN + MsgNum1 := (FileSize(MsgHdrF) - TotalNewMsgsInArea) + (General.MaxQWKtotal - TotalNewMsgsAllAreas); + IF (TotalNewMsgsInArea > general.maxqwkbase) AND + (((FileSize(MsgHdrF) - TotalNewMsgsInArea) + General.MaxQWKBase) < MsgNum1) THEN + MsgNum1 := (FileSize(MsgHdrF) - TotalNewMsgsInArea) + General.MaxQWKBase; + Seek(MsgHdrF,MsgNum1- 1); + Read(MsgHdrF,MHeader); + LoadLastReadRecord(LastReadRecord); + LastReadRecord.LastRead := MHeader.Date; + SaveLastReadRecord(LastReadRecord); + Inc(TotalNewMsgsAllAreas, MsgNum1 - (FileSize(MsgHdrF) - TotalNewMsgsInArea)); + Close(MsgHdrF); + END; + END; + END; + +BEGIN + NL; + IF (ThisUser.DefArcType < 1) OR (ThisUser.DefArcType > MaxArcs) OR + (NOT General.FileArcInfo[ThisUser.DefArcType].Active) THEN + BEGIN + Print('Please select an archive type first.'); + Exit; + END; + + IF (MakeQWKFor > 0) OR (Exist(TempDir+'QWK\'+General.PacketName+'QWK') AND + PYNQ('Create a new QWK packet for download? ',0,FALSE)) THEN + PurgeDir(TempDir+'QWK\',FALSE) + ELSE + PurgeDir(TempDir+'QWK\',FALSE); + + SaveMsgArea := MsgArea; + + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + + OffLineMail := TRUE; + + IF (NOT Exist(TempDir+'QWK\'+General.PacketName+'QWK')) THEN + BEGIN + Assign(ControlTxt,TempDir+'QWK\CONTROL.DAT'); + ReWrite(ControlTxt); + WriteLn(ControlTxt,StripColor(General.BBSName)); + WriteLn(ControlTxt); + WriteLn(ControlTxt,General.BBSPhone); + WriteLn(ControlTxt,General.SysOpName,', Sysop'); + WriteLn(ControlTxt,'0,'+General.PacketName); + WriteLn(ControlTxt,Copy(DateStr,1,2)+'-'+Copy(DateStr,4,2)+'-'+Copy(DateStr,7,4)+','+TimeStr); + WriteLn(ControlTxt,ThisUser.Name); + WriteLn(ControlTxt); + WriteLn(ControlTxt,'0'); + WriteLn(ControlTxt,'0'); + + AvailableMsgAreas := 1; + + FOR MArea := 1 TO NumMsgAreas DO + IF MsgAreaAC(MArea) THEN + Inc(AvailableMsgAreas); + + WriteLn(ControlTxt,(AvailableMsgAreas - 1)); + + FOR MArea := -1 TO NumMsgAreas DO + IF (MArea > 0) AND MsgAreaAC(MArea) THEN + BEGIN + WriteLn(ControlTxt,MemMsgArea.QWKIndex); + WriteLn(ControlTxt,Caps(StripColor(MemMsgArea.FileName))); + END + ELSE IF (MArea = -1) THEN + BEGIN + WriteLn(ControlTxt,0); + WriteLn(ControlTxt,'Private Mail'); + END; + + WriteLn(ControlTxt,'WELCOME'); + WriteLn(ControlTxt,'NEWS'); + WriteLn(ControlTxt,'GOODBYE'); + Close(ControlTxt); + + IF (ThisUser.ScanFilesQWK) THEN + BEGIN + Assign(NewFilesF,TempDir+'QWK\NEWFILES.DAT'); + ReWrite(NewFilesF); + InitFArray(FArray); + FArrayRecNum := 0; + GlobalNewFileScan(FArrayRecNum); + Close(NewFilesF); + LastError := IOResult; + END; + + IF (General.QWKWelcome <> '') THEN + BEGIN + S := General.QWKWelcome; + IF (OkANSI) AND Exist(S+'.ANS') THEN + S := S +'.ANS' + ELSE + S := S +'.ASC'; + CopyMoveFile(TRUE,'',S,TempDir+'QWK\WELCOME',FALSE); + END; + + IF (General.QWKNews <> '') THEN + BEGIN + S := General.QWKNews; + IF (OkANSI) AND Exist(S+'.ANS') THEN + S := S +'.ANS' + ELSE + S := S +'.ASC'; + CopyMoveFile(TRUE,'',S,TempDir+'QWK\NEWS',FALSE); + END; + + IF (General.QWKGoodBye <> '') THEN + BEGIN + S := General.QWKGoodBye; + IF (OkANSI) AND Exist(S+'.ANS') THEN + S := S +'.ANS' + ELSE + S := S +'.ASC'; + CopyMoveFile(TRUE,'',S,TempDir+'QWK\GOODBYE',FALSE); + END; + + Assign(MsgFile,TempDir+'QWK\MESSAGES.DAT'); + + S := 'The Renegade Developement Team, Copyright (c) 1992-2009 (All rights reserved)'; + WHILE (Length(S) < 128) DO + S := S + ' '; + ReWrite(MsgFile,1); + BlockWrite(MsgFile,S[1],128); + + FillChar(QWKHeader.Crap,SizeOf(QWKHeader.Crap),0); + + Assign(PNDXFile,TempDir+'QWK\PERSONAL.NDX'); + ReWrite(PNDXFile); + + LastK := 0; + (* + TotalNewMsgsInArea := 0; + *) + TotalMsgsAllAreas := 0; + TotalNewMsgsAllAreas := 0; + TotalYourMsgsAllAreas := 0; + + TempPause := FALSE; + Abort := FALSE; + Next := FALSE; + + CLS; + Print(Centre('|The QWKSystem is now gathering mail.')); + NL; + PrintACR('sĿ'); + PrintACR('st Num su Message area name sv Short sw Echo sx Total '+ + 'sy New sz Your s{ Size s'); + PrintACR('s'); + + FillChar(QWKHeader.MsgPWord,SizeOf(QWKHeader.MsgPWord),' '); + + FillChar(QWKHeader.RNum,SizeOf(QWKHeader.RNum),' '); + + QWKHeader.Status := 225; + + FOR MArea := -1 TO NumMsgAreas DO + BEGIN + IF (IOResult <> 0) THEN + BEGIN + WriteLn('error processing QWK packet.'); + Exit; + END; + + IF (MArea = 0) OR ((MArea = -1) AND (NOT ThisUser.PrivateQWK)) OR + ((CompMsgArea(MArea,0) = 0) AND (MArea >= 0)) THEN + Continue; + + InitMsgArea(MArea); + + IF (MArea > 0) THEN + UseMsgArea := MemMsgArea.QWKIndex + ELSE + UseMsgArea := 0; + + IF AACS(MemMsgArea.ACS) AND ((LastReadRecord.NewScan) OR + (MAForceRead IN MemMsgArea.MAFlags)) AND (NOT Abort) AND (NOT HangUp) THEN + BEGIN + LastError := IOResult; + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + + QWKHeader.MBase := UseMsgArea; + + IndexR.Conf := UseMsgArea; + + TotalNewMsgsInArea := 0; + + TotalYourMsgsInArea := 0; + + PrintMain('}'+PadRightInt(MArea,4)+ + ' ~'+PadLeftStr(MemMsgArea.Name,22)+ + ' '+PadLeftStr(MemMsgArea.FileName,11)+ + ''+PadLeftStr(ShowYesNo(MemMsgArea.MAType <> 0),3)+ + ''+PadRightInt(FileSize(MsgHdrF),8)); + + Upload_Display; + + IF (UseMsgArea > 0) THEN + MsgNum := FirstNew + ELSE + MsgNum := 1; + + IF (MsgNum > 0) THEN + BEGIN + + S := IntToStr(UseMsgArea); + + WHILE (Length(S) < 3) DO + S := '0' + S; + + Assign(NDXFile,TempDir+'QWK\'+S+'.NDX'); + ReWrite(NDXFile); + + WKey; + + WHILE (MsgNum <= FileSize(MsgHdrF)) AND + (TotalNewMsgsInArea < General.MaxQWKBase) AND + ((TotalNewMsgsAllAreas + TotalNewMsgsInArea) < General.MaxQWKTotal) AND + (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (MArea >= 0) THEN + Inc(TotalNewMsgsInArea); + WKey; + IF ((Timer - LastUpdate) > 3) OR ((Timer - LastUpdate) < 0) THEN + BEGIN + BackErase(22); + Upload_Display; + END; + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (NOT (MDeleted IN MHeader.Status)) AND + NOT (Unvalidated IN MHeader.Status) AND + NOT (FromYou(MHeader) AND NOT ThisUser.GetOwnQWK) AND + NOT ((Prvt IN MHeader.Status) AND NOT (FromYou(MHeader) OR ToYou(MHeader))) AND + NOT ((MArea = -1) AND NOT (ToYou(MHeader))) THEN + BEGIN + + IF (MArea = -1) THEN + Inc(TotalNewMsgsInArea); + + IF (Prvt IN MHeader.Status) THEN + QWKHeader.Flag := '*' + ELSE + QWKHeader.Flag := ' '; + + S := IntToStr(MsgNum); + FillChar(QWKHeader.Num[1],SizeOf(QWKHeader.Num),' '); + Move(S[1],QWKHeader.Num[1],Length(S)); + + PackToDate(DT,MHeader.Date); + + IF (MHeader.From.Anon = 0) THEN + S := ZeroPad(IntToStr(DT.Month))+ + '-'+ZeroPad(IntToStr(DT.Day))+ + '-'+Copy(IntToStr(DT.Year),3,2) + ELSE + S := ''; + + FillChar(QWKHeader.MsgDate[1],SizeOf(QWKHeader.MsgDate),' '); + Move(S[1],QWKHeader.MsgDate[1],Length(S)); + + IF (MHeader.From.Anon = 0) THEN + S := ZeroPad(IntToStr(DT.Hour))+ + ':'+ZeroPad(IntToStr(DT.Min)) + ELSE + S := ''; + + FillChar(QWKHeader.MsgTime,SizeOf(QWKHeader.MsgTime),' '); + Move(S[1],QWKHeader.MsgTime[1],Length(S)); + + S := MHeader.MTo.A1S; + IF (MARealName IN MemMsgArea.MAFlags) THEN + S := AllCaps(MHeader.MTo.Real); + S := Caps(Usename(MHeader.MTo.Anon,S)); + + FillChar(QWKHeader.MsgTo,SizeOf(QWKHeader.MsgTo),' '); + Move(S[1],QWKHeader.MsgTo[1],Length(S)); + + S := MHeader.From.A1S; + IF (MARealName IN MemMsgArea.MAFlags) THEN + S := AllCaps(MHeader.From.Real); + S := Caps(Usename(MHeader.From.Anon,S)); + + FillChar(QWKHeader.MsgFrom[1],SizeOf(QWKHeader.MsgFrom),' '); + Move(S[1],QWKHeader.MsgFrom[1],Length(S)); + + FillChar(QWKHeader.MsgSubj[1],SizeOf(QWKHeader.MsgSubj),' '); + + IF (MHeader.FileAttached > 0) THEN + MHeader.Subject := StripName(MHeader.Subject); + + Move(MHeader.Subject[1],QWKHeader.MsgSubj[1],Length(MHeader.Subject)); + + Marker := FilePos(MsgFile); + + BlockWrite(MsgFile,QWKHeader,128); + + Real_To_Msb(FileSize(MsgFile) DIV 128,IndexR.Pointer); + Write(NDXFile,IndexR); + + IF ToYou(MHeader) THEN + BEGIN + Write(PNDXFile,IndexR); + Inc(TotalYourMsgsInArea); + END; + + X := 1; + TempTextSize := 0; + Texts := ''; + + IF ((MHeader.Pointer - 1) < FileSize(MsgTxtF)) AND + (((MHeader.Pointer - 1) + MHeader.TextSize) <= FileSize(MsgTxtF)) THEN + BEGIN + Seek(MsgTxtF,(MHeader.Pointer - 1)); + REPEAT + BlockRead(MsgTxtF,S[0],1); + BlockRead(MsgTxtF,S[1],Byte(S[0])); + Inc(TempTextSize,(Length(S) + 1)); + S := S + ''; + Texts := Texts + S; + IF (Length(Texts) > 128) THEN + BEGIN + BlockWrite(MsgFile,Texts[1],128); + Inc(X); + Move(Texts[129],Texts[1],(Length(Texts) - 128)); + Dec(Texts[0],128); + END; + UNTIL (TempTextSize >= MHeader.TextSize); + IF (Texts <> '') THEN + BEGIN + IF (Length(Texts) < 128) THEN + BEGIN + FillChar(Texts[Length(Texts) + 1],(128 - Length(Texts)),32); + Texts[0] := #128; + END; + BlockWrite(MsgFile,Texts[1],128); + Inc(X); + END; + END + ELSE + BEGIN + Include(MHeader.Status,MDeleted); + MHeader.TextSize := 0; + MHeader.Pointer := -1; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + + S := IntToStr(X); + + FillChar(QWKHeader.NumBlocks[1],SizeOf(QWKHeader.NumBlocks),' '); + Move(S[1],QWKHeader.NumBlocks[1],Length(S)); + + Seek(MsgFile,Marker); + BlockWrite(MsgFile,QWKHeader,128); + Seek(MsgFile,FileSize(MsgFile)); + END; + Inc(MsgNum); + END; + Close(NDXFile); + END; + BackErase(22); + Upload_Display; + NL; + IF (TotalNewMsgsInArea >= General.MaxQWKBase) THEN + Print('Maximum number of messages per area reached.'); + IF ((TotalNewMsgsAllAreas + TotalNewMsgsInArea) >= General.MaxQWKTotal) THEN + Print('Maximum number of messages per QWK packet reached.'); + LastK := FileSize(MsgFile); + Inc(TotalNewMsgsAllAreas,TotalNewMsgsInArea); + Inc(TotalYourMsgsAllAreas,TotalYourMsgsInArea); + Inc(TotalMsgsAllAreas,FileSize(MsgHdrF)); + Close(MsgHdrF); + Close(MsgTxtF); + END; + IF ((TotalNewMsgsAllAreas + TotalNewMsgsInArea) >= General.MaxQWKTotal) OR Abort THEN + Break; + END; + + IF (FileSize(PNDXFile) = 0) THEN + BEGIN + Close(PNDXFile); + Erase(PNDXFile); + END + ELSE + Close(PNDXFile); + NL; + + IF (NOT Abort) THEN + Print('^0 Totals:'+PadRightInt(TotalMsgsAllAreas,43)+PadRightInt(TotalNewMsgsAllAreas,7)+ + PadRightInt(TotalYourMsgsAllAreas,6)+ + PadRightStr(IntToStr(FileSize(MsgFile) DIV 1024)+'k',8)); + + Close(MsgFile); + NL; + + lil := 0; + IF (TotalNewMsgsAllAreas < 1) OR (Abort) THEN + BEGIN + IF (TotalNewMsgsAllAreas < 1) THEN + Print('No new messages!'); + OffLineMail := FALSE; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); + Exit; + END; + + IF (MakeQWKFor = 0) THEN + BEGIN + NL; + IF NOT PYNQ('Proceed to packet compression: ',0,TRUE) THEN + BEGIN + OffLineMail := FALSE; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); + Exit; + END; + END; + + NL; + Star('Compressing '+General.PacketName+'.QWK'); + + ArcComp(Ok,ThisUser.DefArcType,TempDir+'QWK\'+General.PacketName+'.QWK',TempDir+'QWK\*.*'); + IF (NOT Ok) OR (NOT Exist(TempDir+'QWK\'+General.PacketName+'.QWK')) THEN + BEGIN + NL; + Print('Error archiving QWK packet!'); + OffLineMail := FALSE; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); + Exit; + END; + + SysOpLog('QWK packet created.'); + END; + + FindFirst(TempDir+'QWK\'+General.PacketName+'.QWK',AnyFile,DirInfo); + IF (InCom) AND (NSL < (DirInfo.Size DIV Rate)) AND (NOT General.qwktimeignore) THEN + BEGIN + NL; + Print('Sorry, not enough time left online to transfer.'); + OffLineMail := FALSE; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); + Exit; + END; + + Star('Compressed packet size is '+ConvertBytes(DirInfo.Size,FALSE)+'.'); + + IF (InCom) AND (NOT HangUp) THEN + BEGIN + SaveFileArea := FileArea; + FileArea := -1; + WITH MemFileArea DO + BEGIN + AreaName := 'Offline Mail'; + DLPath := TempDir+'QWK\'; + ULPath := TempDir+'QWK\'; + FAFlags := [FANoRatio]; + END; + WITH FileInfo DO + BEGIN + FileName := Align(General.PacketName+'.QWK'); + Description := 'QWK Download'; + FilePoints := 0; + Downloaded := 0; + FileSize := GetFileSize(TempDir+'QWK\'+General.PacketName+'.QWK'); + OwnerNum := UserNum; + OwnerName := Caps(ThisUser.Name); + FileDate := Date2PD(DateStr); + VPointer := -1; + VTextSize := 0; + FIFlags := []; + END; + TransferFlags := [IsQWK]; + DLX(FileInfo,-1,TransferFlags); + FileArea := SaveFileArea; + LoadFileArea(FileArea); + IF (IsTransferOk IN TransferFlags) AND (NOT (IsKeyboardAbort IN TransferFlags)) THEN + BEGIN + + Star('Updating message pointers'); + + Inc(PublicReadThisCall,TotalNewMsgsAllAreas); + + UpdatePointers; + + Star('Message pointers updated'); + + IF (ThisUser.PrivateQWK) THEN + BEGIN + KillEmail; + Star('Private messages killed.'); + END; + + END; + END + ELSE + BEGIN + S := General.QWKLocalPath+General.PacketName; + IF Exist(S+'.QWK') AND ((MakeQWKFor > 0) OR NOT (PYNQ(^M^J'Replace existing .QWK? ',0,FALSE))) THEN + FOR C := 'A' TO 'Z' DO + IF NOT (Exist(S+'.QW'+C)) THEN + BEGIN + S := S + '.QW' + C; + Break; + END; + IF (Pos('.', S) = 0) THEN + S := S + '.QWK'; + + CopyMoveFile(TRUE,'',TempDir+'QWK\'+General.PacketName+'.QWK',S,FALSE); + + NL; + UpdatePointers; + IF (ThisUser.PrivateQWK) THEN + KillEmail; + END; + IF Exist(TempDir+'QWK\'+General.PacketName+'.REP') THEN + BEGIN + NL; + Star('Bidirectional upload of '+General.PacketName+'.REP detected'); + UploadPacket(TRUE); + END; + OffLineMail := FALSE; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); + LastError := IOResult; +END; + + +PROCEDURE uploadpacket(Already:Boolean); +VAR + F: FILE; + User: UserRecordType; + MHeader: MHeaderRec; + QWKHeader: QWKHeadeRec; + + S, + Os: STRING; + + Counter, + Counter1: Byte; + + RCode, + MArea, + SaveMsgArea: Integer; + + X, + Blocks: Word; + + TransferTime, + TempDate: LongInt; + + Ok, + UploadOk, + KeyboardAbort, + AddBatch, + SaveConfSystem: Boolean; + + FUNCTION FindBase(IndexNumber: Word): Word; + VAR + j, + k: Integer; + BEGIN + Reset(MsgAreaFile); + j := 0; + k := 0; + WHILE (j = 0) AND NOT (EOF(MsgAreaFile)) DO + BEGIN + Inc(k); + Read(MsgAreaFile,MemMsgArea); + IF (MemMsgArea.QWKIndex = IndexNumber) THEN + j := k; + END; + Close(MsgAreaFile); + FindBase := k; + END; + +BEGIN + IF (RPost IN ThisUser.Flags) THEN + BEGIN + NL; + Print('You are restricted from posting messages.'); + Exit; + END; + + SaveMsgArea := MsgArea; (* Was ReadMsgArea *) + + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + + PurgeDir(TempDir+'UP\',FALSE); + + TimeLock := TRUE; + + UploadOk := TRUE; + KeyboardAbort := FALSE; + + IF (ComPortSpeed = 0) OR (UpQWKFor > 0) THEN + CopyMoveFile(TRUE,'',General.QWKLocalPath+General.PacketName+'.REP',TempDir + 'QWK\' + General.PacketName+'.REP',FALSE) + ELSE + BEGIN + IF (NOT Already) THEN + Receive(General.PacketName+'.REP',TempDir+'\QWK',FALSE,UploadOk,KeyboardAbort,AddBatch,TransferTime) + ELSE + CopyMoveFile(FALSE,'',TempDir+'UP\'+General.PacketName+'.REP', + TempDir+'QWK\'+General.PacketName+'.REP',FALSE); + END; + + TimeLock := FALSE; + + IF (UploadOk) AND (NOT KeyboardAbort) THEN + BEGIN + + SysOpLog('Uploaded REP packet'); + + IF (NOT Already) THEN + Print('Transfer successful'); + + ExecBatch(Ok,TempDir+'QWK\',General.ArcsPath+ + FunctionalMCI(General.FileArcInfo[ThisUser.DefArcType].UnArcLine, + TempDir+'QWK\'+General.PacketName+'.REP', + General.PacketName+'.MSG'), + General.FileArcInfo[ThisUser.DefArcType].SuccLevel,RCode,FALSE); + + IF (Ok) AND Exist(TempDir+'QWK\'+General.PacketName+'.MSG') THEN + BEGIN + Assign(F,TempDir+'QWK\'+General.PacketName+'.MSG'); + Reset(F,1); + + GetFTime(F,TempDate); + + IF (TempDate = ThisUser.LastQWK) THEN + BEGIN + NL; + Print('This packet has already been uploaded here.'); + Close(F); + Exit; + END; + + ThisUser.LastQWK := TempDate; + + MHeader.FileAttached := 0; + MHeader.MTo.UserNum := 0; + MHeader.MTo.Anon := 0; + MHeader.ReplyTo := 0; + MHeader.Replies := 0; + + TempDate := GetPackDateTime; + + BlockRead(F,S,128); + WHILE NOT EOF(F) DO + BEGIN + IF (IOResult <> 0) THEN + BEGIN + WriteLn('error processing REP packet.'); + Break; + END; + + BlockRead(F,QWKHeader,128); + + S[0] := #6; + Move(QWKHeader.NumBlocks[1],S[1],6); + + Blocks := (StrToInt(S) - 1); + + IF (QWKHeader.MBase = 0) THEN + MArea := -1 + ELSE + MArea := FindBase(QWKHeader.MBase); + + InitMsgArea(MArea); + + IF AACS(MemMsgArea.ACS) AND AACS(MemMsgArea.PostACS) AND NOT + ((PublicPostsToday >= General.MaxPubPost) AND (NOT MsgSysOp)) THEN + BEGIN + LastError := IOResult; + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + + IF AACS(General.QWKNetworkACS) THEN + BEGIN + S[0] := #25; + Move(QWKHeader.MsgFrom[1],S[1],SizeOf(QWKHeader.MsgFrom)); + WHILE (S[Length(S)] = ' ') DO + Dec(S[0]); + MHeader.From.UserNum := 0; + END + ELSE + BEGIN + IF (MARealName IN MemMsgArea.MAFlags) THEN + S := ThisUser.RealName + ELSE + S := ThisUser.Name; + MHeader.From.UserNum := UserNum; + END; + + MHeader.From.A1S := S; + MHeader.From.Real := S; + MHeader.From.Name := S; + MHeader.From.Anon := 0; + + S[0] := #25; + Move(QWKHeader.MsgTo[1],S[1],SizeOf(QWKHeader.MsgTo)); + + WHILE (S[Length(S)] = ' ') DO + Dec(S[0]); + + MHeader.MTo.A1S := S; + MHeader.MTo.Real := S; + MHeader.MTo.Name := S; + MHeader.MTo.UserNum := SearchUser(MHeader.MTo.Name,FALSE); + + MHeader.Pointer := (FileSize(MsgTxtF) + 1); + MHeader.Date := TempDate; + Inc(TempDate); + GetDayOfWeek(MHeader.DayOfWeek); + + MHeader.Status := []; + + IF (QWKHeader.Flag IN ['*','+']) AND (MAPrivate IN MemMsgArea.MAFlags) THEN + Include(MHeader.Status,Prvt); + + IF (RValidate IN ThisUser.Flags) THEN + Include(MHeader.Status,Unvalidated); + + IF (AACS(MemMsgArea.MCIACS)) THEN + Include(MHeader.Status,AllowMCI); + + Move(QWKHeader.MsgSubj[1],S[1],SizeOf(QWKHeader.MsgSubj)); + S[0] := Chr(SizeOf(QWKHeader.MsgSubj)); + + WHILE (S[Length(S)] = ' ') DO + Dec(S[0]); + + MHeader.Subject := S; + + SysOpLog(MHeader.From.Name+' posted on '+MemMsgArea.Name); + SysOpLog('To: '+MHeader.MTo.Name); + + MHeader.OriginDate[0] := #14; + Move(QWKHeader.MsgDate[1],MHeader.OriginDate[1],8); + MHeader.OriginDate[9] := #32; + Move(QWKHeader.MsgTime[1],MHeader.OriginDate[10],5); + + MHeader.TextSize := 0; + + IF (AllCaps(MHeader.MTo.A1S) <> 'QMAIL') THEN + BEGIN + Seek(MsgTxtF,FileSize(MsgTxtF)); + Os := ''; + X := 1; + WHILE (X <= Blocks) AND (IOResult = 0) DO + BEGIN + BlockRead(F,S[1],128); + S[0] := #128; + S := Os + S; + WHILE (Pos('',S) > 0) DO + BEGIN + Os := Copy(S,1,Pos('',S)-1); + S := Copy(S,Pos('',S)+1,Length(S)); + IF (MemMsgArea.MAType <> 0) AND (Copy(Os,1,4) = '--- ') THEN + Os := '' + ELSE + BEGIN + IF (LennMCI(Os) > 78) THEN + Os := Copy(Os,1,78 + Length(Os) - LennMCI(Os)); + Inc(MHeader.TextSize,Length(Os)+1); + BlockWrite(MsgTxtF,Os,Length(Os)+1); + END; + END; + Os := S; + Inc(X); + END; + + WHILE (S[Length(S)] = ' ') DO + Dec(S[0]); + + IF (Length(S) > 0) THEN + BEGIN + Inc(MHeader.TextSize,(Length(S) + 1)); + BlockWrite(MsgTxtF,S,(Length(S) + 1)); + END; + + IF (MemMsgArea.MAType <> 0) THEN + BEGIN + NewEchoMail := TRUE; + IF NOT (MAScanOut IN MemMsgArea.MAFlags) THEN + UpdateBoard; + END; + + IF (MemMsgArea.MAType <> 0) AND (MAAddTear IN MemMsgArea.MAFlags) THEN + WITH MemMsgArea DO + BEGIN + S := '--- Renegade v'+General.Version; + Inc(MHeader.TextSize,(Length(S) + 1)); + BlockWrite(MsgTxtF,S,(Length(S) + 1)); + IF (MemMsgArea.Origin <> '') THEN + S := MemMsgArea.Origin + ELSE + S := General.Origin; + S := ' * Origin: '+S+' ('; + IF (AKA > 19) THEN + AKA := 0; + S := S + IntToStr(General.AKA[AKA].Zone)+':'+ + IntToStr(General.AKA[AKA].Net)+'/'+ + IntToStr(General.AKA[AKA].Node); + IF (General.AKA[AKA].Point > 0) THEN + S := S +'.'+IntToStr(General.AKA[AKA].Point); + S := S + ')'; + Inc(MHeader.TextSize,(Length(S) + 1)); + BlockWrite(MsgTxtF,S,(Length(S) + 1)); + END; + + CLS; + Ok := FALSE; + UploadOk := FALSE; + Seek(MsgHdrF,FileSize(MsgHdrF)); + Write(MsgHdrF,MHeader); + + IF (UpQWKFor <= 0) THEN + Anonymous(TRUE,MHeader); + + IF (MArea = -1) THEN + BEGIN + IF (MHeader.MTo.UserNum = 0) THEN + BEGIN + IF (AACS(General.NetMailACS)) AND + (PYNQ(^M^J'Is this to be a netmail message? ',0,FALSE)) THEN + BEGIN + IF (General.AllowAlias) AND PYNQ('Send this with your real name? ',0,FALSE) THEN + MHeader.From.A1S := ThisUser.RealName; + WITH MHeader.MTo DO + GetNetAddress(Name,Zone,Net,Node,Point,X,FALSE); + IF (MHeader.MTo.Name = '') THEN + Include(MHeader.Status,MDeleted) + ELSE + BEGIN + Inc(ThisUser.Debit,X); + Include(MHeader.Status,NetMail); + MHeader.NetAttribute := General.NetAttribute * + [Intransit,Private,Crash,KillSent,Hold,Local]; + ChangeFlags(MHeader); + Counter1 := 0; + Counter := 0; + WHILE (Counter <= 19) AND (Counter1 = 0) DO + BEGIN + IF (General.AKA[Counter].Zone = MHeader.MTo.Zone) AND + (General.AKA[Counter].Zone <> 0) THEN + Counter1 := Counter; + Inc(Counter); + END; + MHeader.From.Zone := General.AKA[Counter1].Zone; + MHeader.From.Net := General.AKA[Counter1].Net; + MHeader.From.Node := General.AKA[Counter1].Node; + MHeader.From.Point := General.AKA[Counter1].Point; + END; + END + ELSE + Include(MHeader.Status,MDeleted); + END + ELSE + BEGIN + IF (MHeader.MTo.UserNum > 1) THEN + BEGIN + Inc(ThisUser.EmailSent); + + IF (PrivatePostsToday < 255) THEN + Inc(PrivatePostsToday); + + END + ELSE + BEGIN + Inc(ThisUser.Feedback); + + IF (FeedbackPostsToday < 255) THEN + Inc(FeedbackPostsToday); + + END; + LoadURec(User,MHeader.MTo.UserNum); + Inc(User.Waiting); + SaveURec(User,MHeader.MTo.UserNum); + END; + END + ELSE + BEGIN + Inc(ThisUser.MsgPost); + + IF (PublicPostsToday < 255) THEN + Inc(PublicPostsToday); + + AdjustBalance(General.CreditPost); + END; + Seek(MsgHdrF,(FileSize(MsgHdrF) - 1)); + Write(MsgHdrF,MHeader); + + END + ELSE + BEGIN + IF (MHeader.Subject = 'DROP') THEN + BEGIN + LoadLastReadRecord(LastReadRecord); + LastReadRecord.NewScan := FALSE; + SaveLastReadRecord(LastReadRecord) + END + ELSE IF (MHeader.Subject = 'ADD') THEN + BEGIN + LoadLastReadRecord(LastReadRecord); + LastReadRecord.NewScan := TRUE; + SaveLastReadRecord(LastReadRecord); + END; + Seek(F,FilePos(F) + (Blocks * 128)); + END; + Close(MsgHdrF); + Close(MsgTxtF); + END + ELSE + Seek(F,FilePos(F) + (Blocks * 128)); + END; + Close(F); + END + ELSE + Print('Unable to decompress REP packet.'); + END + ELSE + Print('Transfer unsuccessful'); + + IF Exist(General.QWKLocalPath+General.PacketName+'.REP') AND (ComPortSpeed = 0) + AND (UpQWKFor = 0) AND PYNQ(^M^J'Delete REP packet? ',0,FALSE) THEN + Kill(General.QWKLocalPath+General.PacketName+'.REP'); + + PurgeDir(TempDir+'QWK\',FALSE); + + Update_Screen; + + IF (SaveConfSystem) THEN + BEGIN + ConfSystem := SaveConfSystem; + NewCompTables; + END; + + MsgArea := SaveMsgArea; + InitMsgArea(MsgArea); + + LastError := IOResult; +END; + +END. diff --git a/SOURCE/ONELINER.PAS b/SOURCE/ONELINER.PAS new file mode 100644 index 0000000..a14ed93 --- /dev/null +++ b/SOURCE/ONELINER.PAS @@ -0,0 +1,320 @@ +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} +Unit OneLiner; + +INTERFACE + +Uses + Common, + Timefunc, + Mail1; + +Type + OneLinerRecordType = {$IFDEF WIN32} Packed {$ENDIF} Record + RecordNum : LongInt; + OneLiner : String[55]; + UserID : LongInt; + UserName : String[36]; + DateAdded, + DateEdited : UnixTime; + Anonymous : Boolean; + End; + +PROCEDURE DoOneLiners; +PROCEDURE OneLiner_Add; +PROCEDURE OneLiner_View; +FUNCTION OneLiner_Random : STRING; +FUNCTION ToLower( S : STRING ) : STRING; + +IMPLEMENTATION + +VAR + OneLinerListFile : FILE OF OneLinerRecordType; + OneLineRec : OneLinerRecordType; + +FUNCTION ToLower( S : STRING ) : STRING; +VAR + i : BYTE; +BEGIN + FOR i := 1 TO Length(S) DO + BEGIN + IF S[i] IN ['A'..'Z'] THEN + S[i] := Chr(Ord(S[i]) + 32); + END; + ToLower := S; +END; + +FUNCTION OneLinerListMCI(CONST S: ASTR; Data1,Data2: Pointer): STRING; +VAR + OneLinerListPtr: ^OneLinerRecordType; + User: UserRecordType; + TmpStr : String; +BEGIN + OneLinerListPtr := Data1; + OneLinerListMCI := S; + CASE S[1] OF + 'A' : CASE S[2] OF + 'N' : OneLinerListMCI := ShowYesNo(OneLinerListPtr^.Anonymous); { Anon - Yes/No } + 'T' : OneLinerListMCI := AonOff(OneLinerListPtr^.Anonymous, 'True', 'False'); { Anon - True/False } + END; + 'D' : CASE S[2] OF + 'A' : OneLinerListMCI := Pd2Date(OneLinerListPtr^.DateAdded); { Date Added } + 'E' : OneLinerListMCI := Pd2Date(OneLinerListPtr^.DateEdited); { Date Edited - Not Used } + END; + 'O' : CASE S[2] OF + 'L' : OneLinerListMCI := OneLinerListPtr^.OneLiner; { The Oneliner } + END; + 'R' : CASE S[2] OF + 'N' : OneLinerListMCI := IntToStr(OneLinerListPtr^.RecordNum); { Oneliner Record Number } + END; + 'U' : CASE S[2] OF + '#' : BEGIN { User ID } + IF (OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := ''; + IF (OneLinerListPtr^.Anonymous) AND (SysOp) THEN + OneLinerListMCI := '#' + IntToStr(OneLinerListPtr^.UserID); + IF (NOT OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := '#' + IntToStr(OneLinerListPtr^.UserID); + END; + '1' : BEGIN { User ID Without # } + IF (OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := ''; + IF (OneLinerListPtr^.Anonymous) AND (SysOp) THEN + OneLinerListMCI := IntToStr(OneLinerListPtr^.UserID); + IF (NOT OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := IntToStr(OneLinerListPtr^.UserID); + END; + 'N' : BEGIN { User Name } + LoadURec(User,OneLinerListPtr^.UserID); + IF (OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := 'Anon'; + IF (OneLinerListPtr^.Anonymous) AND (SysOp) THEN + OneLinerListMCI := Caps(User.Name) + ' ^4(^5A^4)'; + IF (NOT OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := Caps(User.Name); + END; + 'L' : BEGIN { User Name Lower } + LoadURec(User,OneLinerListPtr^.UserID); + IF (OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := 'anon'; + IF (OneLinerListPtr^.Anonymous) AND (SysOp) THEN + OneLinerListMCI := ToLower(User.Name) + ' ^4(^5a^4)'; + IF (NOT OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := ToLower(User.Name); + END; + 'S' : BEGIN { User Name Short } + LoadURec(User,OneLinerListPtr^.UserID); + IF (OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := 'Anon'; + IF (OneLinerListPtr^.Anonymous) AND (SysOp) THEN + OneLinerListMCI := Copy(User.Name,1,2) + ' ^4(^5A^4)'; + IF (NOT OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := Copy(User.Name,1,2); + END; + 'U' : BEGIN { User Name Short Lower } + LoadURec(User,OneLinerListPtr^.UserID); + IF (OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := 'anon'; + IF (OneLinerListPtr^.Anonymous) AND (SysOp) THEN + OneLinerListMCI := ToLower(Copy(User.Name,1,2)) + ' ^4(^5a^4)'; + IF (NOT OneLinerListPtr^.Anonymous) THEN + OneLinerListMCI := ToLower(Copy(User.Name,1,2)); + END; + END; + END; +END; + +FUNCTION OneLinerList_Exists: Boolean; +VAR + OneLinerListFile: FILE OF OneLinerRecordType; + FSize: Longint; + FExist: Boolean; +BEGIN + FSize := 0; + FExist := Exist(General.DataPath+'ONELINER.DAT'); + IF (FExist) THEN + BEGIN + Assign(OneLinerListFile,General.DataPath+'ONELINER.DAT'); + Reset(OneLinerListFile); + FSize := FileSize(OneLinerListFile); + Close(OneLinerListFile); + END; + IF (NOT FExist) OR (FSize = 0) THEN + BEGIN + NL; + PrintF('ONELH'); + IF (NoFile) THEN + BEGIN + CLS; NL; + Print(Centre('^4' + General.BBSName + ' One Liners')); + Print(Centre('^5')); + END; + Print(' ^4There are currently no One Liners.'); + NL; + PrintF('ONELE'); + IF (NoFile) THEN + Print(Centre('^5')); + + SysOpLog('^5* The ONELINER.DAT file is missing.'); + END; + OneLinerList_Exists := (FExist) AND (FSize <> 0); +END; + +PROCEDURE DisplayError(FName: ASTR; VAR FExists: Boolean); +BEGIN + NL; + PrintACR('|12 |09The '+FName+'.* File is missing.'); + PrintACR('|12 |09Please, inform the Sysop!'); + SysOpLog('The '+FName+'.* file is missing.'); + FExists := FALSE; +END; + +FUNCTION OneLinerAddScreens_Exists: Boolean; +VAR + FExistsH, + FExistsM, + FExistsE: Boolean; +BEGIN + FExistsH := TRUE; + FExistsM := TRUE; + FExistsE := TRUE; + (*IF (NOT ReadBuffer('ONELH')) THEN + DisplayError('ONELH',FExistsH); *) + IF (NOT ReadBuffer('ONELM')) THEN + DisplayError('ONELM',FExistsM); + (*IF (NOT ReadBuffer('ONELE')) THEN + DisplayError('ONELE',FExistsE); *) + OneLinerAddScreens_Exists := (*(FExistsH) AND *)(FExistsM) (*AND (FExistsE)*); +END; + +Procedure AskOneLinerQuestions(VAR OneLinerList: OneLinerRecordType); +{Var MHeader : MHeaderRec; } +Begin + + WHILE (NOT Abort) AND (NOT Hangup) DO + Begin + NL; + Print('^4 Enter your one liner'); + Prt(' ^5:'); + MPL(76); + InputMain(OneLinerList.OneLiner,(SizeOf(OneLinerList.OneLiner) - 1),[InterActiveEdit,ColorsAllowed]); + NL; + Abort := (OneLinerList.OneLiner = ''); + IF (Abort) THEN + Exit + ELSE + OneLinerList.Anonymous := PYNQ('^4 Post Anonymous? ^5',0,FALSE); + Exit; + End; +End; + +PROCEDURE OneLiner_Add; +VAR + Data2: Pointer; + OneLinerList: OneLinerRecordType; +BEGIN + IF (OneLinerAddScreens_Exists) THEN + BEGIN + NL; + OneLiner_View; + IF PYNQ('^4 Add a one liner? ^5',0, FALSE) THEN + BEGIN + FillChar(OneLinerList,SizeOf(OneLinerList),0); + AskOneLinerQuestions(OneLinerList); + IF (NOT Abort) THEN + BEGIN + PrintF('ONELH'); + IF (NoFile) THEN + BEGIN + CLS; NL; + Print(Centre('^4' + General.BBSName + ' One Liners')); + Print(Centre('^5')); + END; + Print(' ^4'+OneLinerList.OneLiner); + PrintF('ONELE'); + IF (NoFile) THEN + Print(Centre('^5')); + NL; + IF (PYNQ('^4 Add this oneliner? ^5',0,TRUE)) THEN + BEGIN + Assign(OneLinerListFile,General.DataPath+'ONELINER.DAT'); + IF (Exist(General.DataPath+'ONELINER.DAT')) THEN + Reset(OneLinerListFile) + ELSE + Rewrite(OneLinerListFile); + Seek(OneLinerListFile,FileSize(OneLinerListFile)); + OneLinerList.UserID := UserNum; + OneLinerList.DateAdded := GetPackDateTime; + OneLinerList.DateEdited := OneLinerList.DateAdded; + OneLinerList.RecordNum := (FileSize(OneLinerListFile) + 1); + Write(OneLinerListFile,OneLinerList); + Close(OneLinerListFile); + LastError := IOResult; + + SysOpLog('Added Oneliner : '+OneLinerList.OneLiner+'.'); + END; + END; + END; + END; +END; + +PROCEDURE OneLiner_View; +VAR + Data2: Pointer; + OneLinerList: OneLinerRecordType; + OnRec: Longint; + Cnt : Byte; +BEGIN + + IF (OneLinerList_Exists) AND (OneLinerAddScreens_Exists) THEN + BEGIN + Assign(OneLinerListFile,General.DataPath+'ONELINER.DAT'); + Reset(OneLinerListFile); + ReadBuffer('ONELM'); + AllowContinue := TRUE; + Abort := FALSE; + PrintF('ONELH'); + IF (NoFile) THEN + BEGIN + CLS; NL; + Print(Centre('^4' + General.BBSName + ' One Liners')); + Print(Centre('^5')); + NL; + END; + OnRec := 1; + Cnt := (FileSize(OneLinerListFile)); + {WHILE (OnRec <= FileSize(OneLinerListFile)) AND (NOT Abort) AND (NOT HangUp) DO} + + FOR Cnt := (FileSize(OneLinerListFile)) DOWNTO 1 DO + BEGIN + Seek(OneLinerListFile,(Cnt-1)); + Read(OneLinerListFile,OneLinerList); + DisplayBuffer(OneLinerListMCI,@OneLinerList,Data2); + Inc(OnRec); + IF ((OnRec-1) = 10) THEN + Break + ELSE + OnRec := OnRec; + END; + Close(OneLinerListFile); + LastError := IOResult; + IF (NOT Abort) THEN + PrintF('ONELE'); + IF (NoFile) THEN + Print(Centre('^5')); + + AllowContinue := FALSE; + SysOpLog('^5* ^4'+ ThisUser.Name + '^5 Viewed the OneLiners.'); + END; +END; + +Function OneLiner_Random : String; +Begin + +End; + +Procedure DoOneLiners; { To-Do : Variable Number of One Liners To Display } +Begin +OneLiner_Add; +End; + +End. diff --git a/SOURCE/RECORDS.PAS b/SOURCE/RECORDS.PAS new file mode 100644 index 0000000..10ec8e2 --- /dev/null +++ b/SOURCE/RECORDS.PAS @@ -0,0 +1,1012 @@ +CONST + Build = '1.20'; + +{$IFDEF MSDOS} + OS = '/DOS'; +{$ENDIF} + +{$IFDEF WIN32} + OS = '/Win32'; +{$ENDIF} + +{$IFDEF OS/2} + OS = '/2'; +{$ENDIF} + + Ver = Build + OS; + MaxProtocols = 120; + MaxEvents = 10; + MaxArcs = 8; + MaxCmds = 200; + MaxMenus = 100; + MaxResultCodes = 20; + MaxExtDesc = 99; + MaxFileAreas = 32767; + MaxMsgAreas = 32767; + MaxConfigurable = 1024; + MaxVotes = 25; + MaxChoices = 25; + MaxSchemes = 255; + MaxValKeys = 92; + MaxConfKeys = 27; + + User_String_Ask = ' '; {Ask for user string fields} + User_String_None = ''; {None for user string fields} + + User_Date_Ask = -2145916799; {Ask for user date fields - 01/01/1902} + User_Date_None = -2146003199; {None for user date fields - 12/31/1901} + + User_Word_Ask = 65535; {Ask for user word fields} + User_Word_None = 65534; {None for user word fields} + + User_Char_Ask = '~'; {Ask for user character fields} + User_Char_None = ' '; {None for user character fields} + + User_Phone_Ask = ' '; {Ask for user phone fields} + User_Phone_None = ''; {None for user phone fields} + +TYPE +{$IFDEF MSDOS} + SmallInt = Integer; + SmallWord = Word; +{$ENDIF} + AStr = STRING[160]; + Str1 = STRING[1]; + Str2 = STRING[2]; + Str3 = STRING[3]; + Str4 = STRING[4]; + Str5 = STRING[5]; + Str7 = STRING[7]; + Str8 = STRING[8]; + Str9 = STRING[9]; + Str11 = STRING[11]; + Str10 = STRING[10]; + Str12 = STRING[12]; + Str15 = STRING[15]; + Str20 = STRING[20]; + Str26 = STRING[26]; + Str30 = STRING[30]; + Str35 = STRING[35]; + Str36 = STRING[36]; + Str40 = STRING[40]; + Str50 = STRING[50]; + Str52 = STRING[52]; + Str65 = STRING[65]; + Str74 = STRING[74]; + Str78 = STRING[78]; + Str160 = STRING[160]; + + UnixTime = LongInt; { Seconds since 1-1-70 } + + ACString = STRING[20]; { Access Condition STRING } + + ARFlagType = '@'..'Z'; {AR flags} + + ARFlagSet = SET OF ARFlagType; {SET OF AR flags} + + FlagType = + (RLogon, { L - Limited to one call a day } + RChat, { C - No SysOp paging } + RValidate, { V - Posts are unvalidated } + RUserList, { U - Can't list users } + RAMsg, { A - Can't leave automsg } + RPostAn, { * - Can't post anonymously } + RPost, { P - Can't post } + REmail, { E - Can't send email } + RVoting, { K - Can't use voting booth } + RMsg, { M - Force email deletion } + + VT100, { Supports VT00 } + HotKey, { hotkey input mode } + Avatar, { Supports Avatar } + Pause, { screen pausing } + Novice, { user requires novice help } + ANSI, { Supports ANSI } + Color, { Supports color } + Alert, { Alert SysOp upon login } + SMW, { Short message(s) waiting } + NoMail, { Mailbox is closed } + + FNoDLRatio, { 1 - No UL/DL ratio } + FNoPostRatio, { 2 - No post/call ratio } + FNoCredits, { 3 - No credits checking } + FNoDeletion); { 4 - Protected from deletion } + + FlagSet = SET OF FlagType; + + StatusFlagType = + (LockedOut, { if locked out } + Deleted, { if deleted } + TrapActivity, { if trapping users activity } + TrapSeparate, { if trap to seperate TRAP file } + ChatAuto, { if auto chat trapping } + ChatSeparate, { if separate chat file to trap to } + SLogSeparate, { if separate SysOp log } + CLSMsg, { if clear-screens } + RIP, { if RIP graphics can be used } + FSEditor, { if Full Screen Editor } + AutoDetect, { Use auto-detected emulation } + FileAreaLightBar, + MsgAreaLightBar, + UnUsedStatusFlag1, + UnUsedStatusFlag2, + UnUsedStatusFlag3 + ); + + StatusFlagSet = SET OF StatusFlagType; + + ANonTyp = + (ATNo, { Anonymous posts not allowed } + ATYes, { Anonymous posts are allowed } + ATForced, { Force anonymous } + ATDearAbby, { "Dear Abby" } + ATAnyName); { Post under any name } + + NetAttr = + (Private, + Crash, + Recd, + NSent, + FileAttach, + Intransit, + Orphan, + KillSent, + Local, + Hold, + Unused, + FileRequest, + ReturnReceiptRequest, + IsReturnReceipt, + AuditRequest, + FileUpdateRequest); + + NetAttribs = SET OF NetAttr; + + SecurityRangeType = ARRAY [0..255] OF LongInt; { Access tables } + + UserIDXRec = { USERS.IDX : Sorted names listing } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Name: STRING[36]; { the user's name } + Number, { user number } + Left, { Left node } + Right: SmallInt; { Right node } + RealName, { User's real name? } + Deleted: Boolean; { deleted or not } + END; + + UserRecordType = { USERS.DAT : User records } + {$IFDEF WIN32} PACKED {$ENDIF} RECORD + Name, { system name } + RealName: STRING[36]; { real name } + + Street, { street address } + CityState: STRING[30]; { city, state } + + CallerID: STRING[20]; { caller ID STRING } + + ZipCode: STRING[10]; { zipcode } + + PH: STRING[12]; { phone # } + + ForgotPWAnswer: STRING[40]; + + UsrDefStr: ARRAY [1..3] OF STRING[35]; { definable strings } + + Note: STRING[35]; { SysOp note } + + LockedFile: STRING[8]; { print lockout msg } + + Vote: ARRAY [1..25] OF Byte; { voting data } + + Sex, { gender } + Subscription, { their subscription } + ExpireTo, { level to expire to } + LastConf, { last conference in } + UnUsedChar1, + UnUsedChar2: Char; + + SL, { SL } + DSL, { DSL } + Waiting, { mail waiting } + LineLen, { line length } + PageLen, { page length } + OnToday, { # times on today } + Illegal, { # illegal logons } + DefArcType, { QWK archive type } + ColorScheme, { Color scheme # } + UserStartMenu, { menu to start at } + UnUsedByte1, + UnUsedByte2: Byte; + + BirthDate, { Birth date } + FirstOn, { First On Date } + LastOn, { Last On Date } + TTimeOn, { total time on } + LastQWK, { last qwk packet } + Expiration, { Expiration date } + UnUsedUnixTime1, + UnUsedUnixTime2: UnixTime; + + UserID, { Permanent userid } + TLToday, { # min left today } + ForUsr, { forward mail to } + LastMsgArea, { # last msg area } + LastFileArea, { # last file area } + UnUsedInteger1, + UnUsedInteger2: SmallInt; + + PasswordChanged, { Numeric date pw changed - was UnixTime } + UnUsedWord1, + UnUsedWord2: SmallWord; + + lCredit, { Amount OF credit } + Debit, { Amount OF debit } + PW, { password } + Uploads, { # OF DLs } + Downloads, { # OF DLs } + UK, { UL k } + DK, { DL k } + LoggedOn, { # times on } + MsgPost, { # message posts } + EmailSent, { # email sent } + FeedBack, { # feedback sent } + TimeBank, { # mins in bank } + TimeBankAdd, { # added today } + DLKToday, { # kbytes dl today } + DLToday, { # files dl today } + FilePoints, + TimeBankWith, { Time withdrawn } + UnUsedLongInt1, + UnUsedLongInt2: LongInt; + + TeleConfEcho, { Teleconf echo? } + TeleConfInt, { Teleconf interrupt } + GetOwnQWK, { Get own messages } + ScanFilesQWK, { new files in qwk } + PrivateQWK, { private mail qwk } + UnUsedBoolean1, + UnUsedBoolean2: Boolean; + + AR: ARFlagSet; { AR flags } + + Flags: FlagSet; { flags } + + SFlags: StatusFlagSet; { status flags } + END; + + MsgStatusR = + (MDeleted, + Sent, + Unvalidated, + Permanent, + AllowMCI, + NetMail, + Prvt, + Junked); + + FromToInfo = { from/to information for mheaderrec } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Anon: Byte; + UserNum: SmallWord; { user number } + A1S: STRING[36]; { posted as } + Real: STRING[36]; { real name } + Name: STRING[36]; { system name } + Zone, + Net, + Node, + Point: SmallWord; + END; + + MHeaderRec = +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + From, + MTO: FromToInfo; { message from/to info } + Pointer: LongInt; { starting record OF text } + TextSize: SmallWord; { size OF text } + ReplyTo: SmallWord; { ORIGINAL + REPLYTO = CURRENT } + Date: UnixTime; { date/time PACKED STRING } + DayOfWeek: Byte; { message day OF week } + Status: SET OF MsgStatusR; { message status flags } + Replies: SmallWord; { times replied to } + Subject: STRING[40]; { subject OF message } + OriginDate: STRING[19]; { date OF echo/group msgs } + FileAttached: Byte; { 0=No, 1=Yes&Del, 2=Yes&Save } + NetAttribute: NetAttribs; { Netmail attributes } + Res: ARRAY [1..2] OF Byte; { reserved } + END; + + HistoryRecordType = { HISTORY.DAT : Summary logs } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Date: UniXTime; + Active, + Callers, + NewUsers, + Posts, + Email, + FeedBack, + Errors, + Uploads, + Downloads, + UK, + DK: LongInt; + UserBaud: ARRAY [0..20] OF LongInt; + END; + + FileArcInfoRecordType = { Archive configuration records } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Active: Boolean; { active or not } + Ext: STRING[3]; { file extension } + ListLine, { /x for internal; x: 1=ZIP, 2=ARC/PAK, 3=ZOO, 4=LZH } + ArcLine, { compression cmdline } + UnArcLine, { de-compression cmdline } + TestLine, { integrity test cmdline } + CmtLine: STRING[25]; { comment cmdline } + SuccLevel: SmallInt; { success errorlevel, -1=ignore results } + END; + + ModemFlagType = { MODEM.DAT status flags } + (Lockedport, { COM port locked at constant rate } + XOnXOff, { XON/XOFF (software) flow control } + CTSRTS); { CTS/RTS (hardware) flow control } + + MFlagSet = SET OF ModemFlagType; + + LineRec = +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + InitBaud: LongInt; { initialization baud } + ComPort: Byte; { COM port number } + MFlags: MFlagSet; { status flags } + Init, { init STRING } + Answer, { answer STRING or blank } + Hangup, { hangup STRING } + Offhook: STRING[30]; { phone off-hook STRING } + DoorPath, { door drop files written to } + TeleConfNormal, + TeleConfAnon, { Teleconferencing strings } + TeleConfGlobal, + TeleConfPrivate: STRING[40]; + Ok, + Ring, + Reliable, + CallerID, + NoCarrier: STRING[20]; + Connect: ARRAY [1..22] OF STRING[20]; + { 300, 600, 1200, 2400, 4800, 7200, 9600, 12000, 14400, 16800, 19200, + 21600, 24000, 26400, 28800, 31200, 33600, 38400, 57600, 115200 + 2 extra } + UseCallerID: Boolean; { Insert Caller ID into sysop note? } + LogonACS: ACString; { ACS STRING to logon this node } + IRQ, + Address: STRING[10]; { used only for functional MCI codes + %C = Comport address + %E = IRQ + } + AnswerOnRing: Byte; { Answer after how many rings? } + MultiRing: Boolean; { Answer Ringmaster or some other type + OF multiple-ring system ONLY } + NodeTelnetUrl: STRING[65]; + END; + + ValidationRecordType = +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Key, { Key '!' to '~' } + ExpireTo: Char; { validation level to expire to } + Description: STRING[30]; { description } + UserMsg: STRING[78]; { Message sent to user upon validation } + NewSL, { new SL } + NewDSL, { new DSL } + NewMenu: Byte; { User start out menu } + Expiration: SmallWord; { days until expiration } + NewFP, { nothing } + NewCredit: LongInt; { new credit } + SoftAR, { TRUE=AR added to current, else replaces } + SoftAC: Boolean; { TRUE=AC " " " " " } + NewAR: ARFlagSet; { new AR } + NewAC: FlagSet; { new AC } + END; + + GeneralRecordType = +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + ForgotPWQuestion: STRING[70]; + + QWKWelcome, { QWK welcome file name } + QWKNews, { QWK news file name } + QWKGoodbye, { QWK goodbye file name } + Origin: STRING[50]; { Default Origin line } + + DataPath, { DATA path } + MiscPath, { MISC path } + LogsPath, { LOGS path } + MsgPath, { MSGS path } + NodePath, { NODE list path } + TempPath, { TEMP path } + ProtPath, { PROT path } + ArcsPath, { ARCS path } + lMultPath, { MULT path } + FileAttachPath, { directory for file attaches } + QWKLocalPath, { QWK path for local usage } + DefEchoPath, { default echomail path } + NetmailPath, { path to netmail } + BBSName: STRING[40]; { BBS name } + + SysOpName: STRING[30]; { SysOp's name } + + Version: STRING[20]; + + BBSPhone: STRING[12]; { BBS phone number } + + LastDate: STRING[10]; { last system date } + + PacketName, { QWK packet name } + BulletPrefix: STRING[8]; { default bulletins filename } + + SysOpPW, { SysOp password } + NewUserPW, { newuser password } + MinBaudOverride, { override minimum baud rate } + QWKNetworkACS, { QWK network REP ACS } + LastOnDatACS, + SOP, { SysOp } + CSOP, { Co-SysOp } + MSOP, { Message SysOp } + FSOP, { File SysOp } + SPW, { SysOp PW at logon } + AddChoice, { Add voting choices acs } + NormPubPost, { make normal public posts } + NormPrivPost, { send normal e-mail } + + AnonPubRead, { see who posted public anon } + AnonPrivRead, { see who sent anon e-mail } + AnonPubPost, { make anon posts } + AnonPrivPost, { send anon e-mail } + + SeeUnval, { see unvalidated files } + DLUnval, { DL unvalidated files } + NoDLRatio, { no UL/DL ratio } + NoPostRatio, { no post/call ratio } + NoFileCredits, { no file credits checking } + ULValReq, { uploads require validation } + TeleConfMCI, { ACS access for MCI codes while teleconfin' } + OverrideChat, { override chat hours } + NetMailACS, { do they have access to netmail? } + Invisible, { Invisible mode? } + FileAttachACS, { ACS to attach files to messages } + ChangeVote, { ACS to change their vote } + UnUsedACS1, + UnUsedACS2: ACString; + + MaxPrivPost, { max email can send per call } + MaxFBack, { max feedback per call } + MaxPubPost, { max posts per call } + MaxChat, { max sysop pages per call } + MaxWaiting, { max mail waiting } + CSMaxWaiting, { max mail waiting for Co-SysOp + } + MaxMassMailList, + MaxLogonTries, { tries allowed for PW's at logon } + SysOpColor, { SysOp color in chat mode } + UserColor, { user color in chat mode } + SliceTimer, + MaxBatchDLFiles, + MaxBatchULFiles, + Text_Color, { color OF standard text } + Quote_Color, { color OF quoted text } + Tear_Color, { color OF tear line } + Origin_Color, { color OF origin line } + BackSysOpLogs, { days to keep SYSOP##.LOG } + EventWarningTime, { minutes before event to warn user } + WFCBlankTime, { minutes before blanking WFC menu } + AlertBeep, { time between alert beeps - Was Integer } + FileCreditComp, { file credit compensation ratio } + FileCreditCompBaseSize, { file credit area compensation size } + ULRefund, { percent OF time to refund on ULs } + GlobalMenu, + AllStartMenu, + ShuttleLogonMenu, + NewUserInformationMenu, + FileListingMenu, + MessageReadMenu, + CurWindow, { type OF SysOp window in use } + SwapTo, { Swap where? } + UnUsedByte1, + UnUsedByte2: Byte; + + lLowTime, { SysOp begin minute (in minutes) } + HiTime, { SysOp END time } + DLLowTime, { normal downloading hours begin.. } + DLHiTime, { ..and END } + MinBaudLowTime, { minimum baud calling hours begin.. } + MinBaudHiTime, { ..and END } + MinBaudDLLowTime, { minimum baud downloading hours begin.. } + MinBaudDLHiTime, { ..and END } + NewApp, { send new user application to # } + TimeOutBell, { minutes before timeout beep } + TimeOut, { minutes before timeout } + ToSysOpDir, { SysOp file area } + CreditMinute, { Credits per minute } + CreditPost, { Credits per post } + CreditEmail, { Credits per Email sent } + CreditFreeTime, { Amount OF "Free" time given to user at logon } + NumUsers, { number OF users } + PasswordChange, { change password at least every x days } + RewardRatio, { % OF file points to reward back } + CreditInternetMail, { cost for Internet mail } + BirthDateCheck, { check user's birthdate every xx logons } + UnUsedInteger1, + UnUsedInteger2: SmallInt; + + MaxQWKTotal, { max msgs in a packet, period } + MaxQWKBase, { max msgs in a area } + DaysOnline, { days online } + UnUsedWord1, + UnUsedWord2: SmallWord; + + MinimumBaud, { minimum baud rate to logon } + MinimumDLBaud, { minimum baud rate to download } + MaxDepositEver, + MaxDepositPerDay, + MaxWithdrawalPerDay, + CallerNum, { system caller number } + RegNumber, { registration number } + TotalCalls, { incase different from callernum } + TotalUsage, { total usage in minutes } + TotalPosts, { total number OF posts } + TotalDloads, { total number OF dloads } + TotalUloads, { total number OF uloads } + MinResume, { min K to allow resume-later } + MaxInTemp, { max K allowed in TEMP } + MinSpaceForPost, { minimum drive space left to post } + MinSpaceForUpload, { minimum drive space left to upload } + UnUsedLongInt1, + UnUsedLongInt2: LongInt; + + AllowAlias, { allow handles? } + PhonePW, { phone number password in logon? } + LocalSec, { use local security? } + GlobalTrap, { trap everyone's activity? } + AutoChatOpen, { automatically open chat buffer? } + AutoMInLogon, { Auto-Message at logon? } + BullInLogon, { bulletins at logon? } + YourInfoInLogon, { "Your Info" at logon? } + OffHookLocalLogon, { phone off-hook for local logons? } + ForceVoting, { manditory voting? } + CompressBases, { "compress" file/msg area numbers? } + SearchDup, { search for dupes files when UL? } + ForceBatchDL, + ForceBatchUL, + LogonQuote, + UserAddQuote, + StripCLog, { strip colors from SysOp log? } + SKludge, { show kludge lines? } + SSeenby, { show SEEN-BY lines? } + SOrigin, { show origin line? } + AddTear, { show tear line? } + ShuttleLog, { Use Shuttle Logon? } + ClosedSystem, { Allow new users? } + SwapShell, { Swap on shell? } + UseEMS, { use EMS for overlay } + UseBios, { use BIOS for video output } + UseIEMSI, { use IEMSI } + ULDLRatio, { use UL/DL ratios? } + FileCreditRatio, { use auto file-credit compensation? } + ValidateAllFiles, { validate files automatically? } + FileDiz, { Search/Import file_id.diz } + SysOpPword, { check for sysop password? } + TrapTeleConf, { Trap teleconferencing to ROOMx.TRP? } + IsTopWindow, { is window at top OF screen? } + ReCompress, { recompress like archives? } + RewardSystem, { use file rewarding system? } + TrapGroup, { record group chats? } + QWKTimeIgnore, { ignore time remaining for qwk download? } + NetworkMode, { Network mode ? } + WindowOn, { is the sysop window on? } + ChatCall, { Whether system keeps beeping after chat} + DailyLimits, { Daily file limits on/off } + MultiNode, { enable multinode support } + PerCall, { time limits are per call or per day?} + TestUploads, { perform integrity tests on uploads? } + UseFileAreaLightBar, + UseMsgAreaLightBar, + UnUsedBoolean1, + UnUsedBoolean2: Boolean; + + FileArcInfo: + ARRAY [1..MaxArcs] OF FileArcInfoRecordType; { archive specs } + + FileArcComment: + ARRAY [1..3] OF STRING[40]; { BBS comment files for archives } + + Aka: ARRAY [0..20] OF + {$IFDEF WIN32} PACKED {$ENDIF} RECORD { 20 Addresses } + Zone, { 21st is for UUCP address } + Net, + Node, + Point: SmallWord; + END; + + NewUserToggles: ARRAY [1..20] OF Byte; + + Macro: ARRAY [0..9] OF STRING[100]; { sysop macros } + + Netattribute: NetAttribs; { default netmail attribute } + + TimeAllow, { time allowance } + CallAllow, { call allowance } + DLRatio, { # ULs/# DLs ratios } + DLKRatio, { DLk/ULk ratios } + PostRatio, { posts per call ratio } + DLOneday, { Max number OF dload files in one day} + DLKOneDay: SecurityRangeType; { Max k downloaded in one day} + END; + + ShortMessageRecordType = { SHORTMSG.DAT : One-line messages } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Msg: AStr; + Destin: SmallInt; + END; + + VotingRecordType = { VOTING.DAT : Voting records } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Question1, { Voting Question 1 } + Question2: STRING[60]; { Voting Question 2 } + ACS: ACString; { ACS required to vote on this } + ChoiceNumber: Byte; { number OF choices } + NumVotedQuestion: SmallInt; { number OF votes on it } + CreatedBy: STRING[36]; { who created it } + AddAnswersACS: ACString; { ACS required to add choices } + Answers: ARRAY [1..25] OF + {$IFDEF WIN32} PACKED {$ENDIF} RECORD + Answer1, { answer description } + Answer2: STRING[65]; { answer description #2 } + NumVotedAnswer: SmallInt; { # user's who picked this answer } + END; + END; + + MessageAreaFlagType = + (MARealName, { whether real names are forced } + MAUnHidden, { whether *VISIBLE* to users w/o access } + MAFilter, { whether to filter ANSI/8-bit ASCII } + MAPrivate, { allow private messages } + MAForceRead, { force the reading of this area } + MAQuote, { Allow Quote/Tagline to messages posted in this area } + MASKludge, { strip IFNA kludge lines } + MASSeenBy, { strip SEEN-BY lines } + MASOrigin, { strip origin lines } + MAAddTear, { add tear/origin lines } + MAInternet, { if internet message area } + MAScanOut); { Needs to be scanned out by renemail } + + MAFlagSet = SET OF MessageAreaFlagType; + + MessageAreaRecordType = { MBASES.DAT : Message area records } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Name: STRING[40]; { message area description } + FileName: STRING[8]; { HDR/DAT data filename } + MsgPath: STRING[40]; {Not Used} { messages pathname } + ACS, { access requirement } + PostACS, { post access requirement } + MCIACS, { MCI usage requirement } + SysOpACS: ACString; { Message area sysop requirement } + MaxMsgs: SmallWord; { max message count } + Anonymous: AnonTyp; { anonymous type } + Password: STRING[20]; { area password } + MAFlags: MAFlagSet; { message area status vars } + MAType: SmallInt; { Area type (0=Local,1=Echo, 3=Qwk) } + Origin: STRING[50]; { origin line } + Text_Color, { color OF standard text } + Quote_Color, { color OF quoted text } + Tear_Color, { color OF tear line } + Origin_Color, { color OF origin line } + MessageReadMenu: Byte; + QuoteStart, + QuoteEnd: STRING[70]; + PrePostFile: STRING[8]; + AKA: Byte; { alternate address } + QWKIndex: SmallWord; { QWK indexing number } + END; + + FileAreaFlagType = + (FANoRatio, { if active } + FAUnHidden, { whether *VISIBLE* to users w/o access } + FADirDLPath, { if *.DIR file stored in DLPATH } + FAShowName, { show uploaders in listings } + FAUseGIFSpecs, { whether to use GifSpecs } + FACDROM, { Area is read only, no sorting or ul scanning } + FAShowDate, { show date uploaded in listings } + FANoDupeCheck); { No dupe check on this area } + + FAFlagSet = SET OF FileAreaFlagType; + + FileAreaRecordType = { FBASES.DAT : File area records } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + AreaName: STRING[40]; { area description } + FileName: STRING[8]; { filename + ".DIR" } + DLPath, { download path } + ULPath: STRING[40]; { upload path } + MaxFiles: SmallInt; { max files allowed - VerbRec Limit would allow up to LongInt Value or Maximum 433835} + Password: STRING[20]; { password required } + ArcType, { wanted archive type (1..max,0=inactive) } + CmtType: Byte; { wanted comment type (1..3,0=inactive) } + ACS, { access requirements } + ULACS, { upload requirements } + DLACS: ACString; { download requirements } + FAFlags: FAFlagSet; { file area status vars } + END; + + FileInfoFlagType = + (FINotVal, { If file is not validated } + FIIsRequest, { If file is REQUEST } + FIResumeLater, { If file is RESUME-LATER } + FIHatched, { Has file been hatched? } + FIOwnerCredited, + FIUnusedFlag1, + FIUnusedFlag2, + FIUnusedFlag3); + + FIFlagSet = SET OF FileInfoFlagType; + + FileInfoRecordType = { *.DIR : File records } + {$IFDEF WIN32} PACKED {$ENDIF} RECORD + FileName: STRING[12]; { Filename } + Description: STRING[50]; { File description } + FilePoints: SmallInt; { File points } + Downloaded: LongInt; { Number DLs } + FileSize: LongInt; { File size in Bytes } + OwnerNum: SmallInt; { ULer OF file } + OwnerName: STRING[36]; { ULer's name } + FileDate: UnixTime; { Date ULed } + VPointer: LongInt; { Pointer to verbose descr, -1 if none } + VTextSize: SmallInt; { Verbose descr textsize - 50 Bytes x 99 Lines = 4950 max } + FIFlags: FIFlagSet; { File status } + END; + + LastCallerRec = { LASTON.DAT : Last few callers records } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Node: Byte; { Node number } + UserName: STRING[36]; { User name OF caller } + Location: STRING[30]; { Location OF caller } + Caller, { system caller number } + UserID, { User ID # } + Speed: LongInt; { Speed OF caller 0=Local } + LogonTime, { time user logged on } + LogoffTime: UnixTime; { time user logged off } + NewUser, { was it a new user? } + Invisible: Boolean; { Invisible user? } + Uploads, { Uploads/Downloads during call } + Downloads, + MsgRead, { Messages Read } + MsgPost, { Messages Posted } + EmailSent, { Email sent } + FeedbackSent: SmallWord; { Feedback sent } + UK, { Upload/Download kbytes during call } + DK: LongInt; + Reserved: ARRAY [1..17] OF Byte; { Reserved } + END; + + EventFlagType = + (EventIsExternal, + EventIsActive, + EventIsErrorLevel, + EventIsShell, + EventIsPackMsgAreas, + EventIsSortFiles, + EventIsFilesBBS, + EventIsLogon, + EventIsChat, + EventIsOffHook, + EventIsMonthly, + EventIsPermission, + EventIsSoft, + EventIsMissed, + BaudIsActive, + ACSIsActive, + TimeIsActive, + ARisActive, + SetARisActive, + ClearARisActive, + InRatioIsActive); + + EFlagSet = SET OF EventFlagType; + + EventDaysType = SET OF 0..6; {Set of event days} + + EventRecordType = {Events - EVENTS.DAT} +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + EventDescription: STRING[30]; {Description of the Event} + EventDayOfMonth: BYTE; {If monthly, the Day of Month} + EventDays: EventDaysType; {If Daily, the Days Active} + EventStartTime, {Start Time in Min from Mid.} + EventFinishTime: SmallWord; {Finish Time} + EventQualMsg, {Msg/Path if he qualifies} + EventNotQualMsg: STRING[64]; {Msg/Path if he doesn't} + EventPreTime: BYTE; {Min. B4 event to rest. Call} + EventNode: Byte; + EventLastDate: UnixTime; {Last Date Executed} + EventErrorLevel: BYTE; {For Ext Event ErrorLevel} + EventShellPath: STRING[8]; {File for Ext Event Shell} + LoBaud, {Low baud rate limit} + HiBaud: LongInt; {High baud rate limit} + EventACS: ACString; {Event ACS} + MaxTimeAllowed: SmallWord; {Max Time per user this event} + SetARflag, {AR Flag to Set} + ClearARflag: CHAR; {AR Flag to Clear} + EFlags: EFlagSet; {Kinds of Events Supported} { Changed } + END; + + ProtocolFlagType = + (ProtActive, + ProtIsBatch, + ProtIsResume, + ProtXferOkCode, + ProtBiDirectional, + ProtReliable); + + PRFlagSet = SET OF ProtocolFlagType; + + ProtocolCodeType = ARRAY [1..6] OF STRING[6]; + + ProtocolRecordType = { PROTOCOL.DAT records } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + PRFlags: PRFlagSet; { Protocol Flags } + CKeys: STRING[14]; { Command Keys } + Description: STRING[40]; { Description } + ACS: ACString; { User Access STRING } + TempLog, { Utilized for Batch DL's - Temporary Log File } + DLoadLog, { Utilized for Batch DL's - Permanent Log Files } + ULoadLog, { Not Utilized } + DLFList: STRING[25]; { Utilized for Batch DL's - DL File Lists } + DLCmd, { DL Command Line } + ULCmd: STRING[76]; { UL Command Line } + DLCode, { DL Status/Return codes } + ULCode: ProtocolCodeType; { UL StAtus/Return codes } + EnvCmd: STRING[60]; { Environment Setup Cmd } + MaxChrs, { Utilized for Batch DL's - Max chrs in cmdline } + TempLogPF, { Utilized for Batch DL's - Position in log for DL Status } + TempLogPS: Byte; { Utilized for Batch DL's - Position in log for file data } + END; + + ConferenceRecordType = { CONFRENC.DAT : Conference data } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Key: Char; { key '@' to 'Z' } + Name: STRING[30]; { name of conference } + ACS: ACString; { access requirement } + END; + + NodeFlagType = + (NActive, { Is this node active? } + NAvail, { Is this node's user available? } + NUpdate, { This node should re-read it's user } + NHangup, { Hangup on this node } + NRecycle, { Recycle this node to the OS } + NInvisible); { This node is Invisible } + + NodeFlagSet = SET OF NodeFlagType; + + NodeRecordType = { MULTNODE.DAT } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + User: SmallWord; { What user number } + UserName: STRING[36]; { User's name } + CityState: STRING[30]; { User's location } + Sex: Char; { User's sex } + Age: Byte; { User's age } + LogonTime: UnixTime; { What time they logged on } + GroupChat: Boolean; { Are we in MultiNode Chat } + ActivityDesc: STRING[50]; { Activity STRING } + Status: NodeFlagSet; + Room: Byte; { What room are they in? } + Channel: SmallWord; { What channel are they in? } + Invited, { Have they been invited ? } + Booted, { Have they been kicked off ? } + Forget: ARRAY [0..31] OF SET OF 0..7; { Who are they forgetting? } + END; + + RoomRec = { ROOM.DAT } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Topic: STRING[40]; { Topic OF this room } + Anonymous: Boolean; { Is Room anonymous ? } + Private: Boolean; { Is Room private ? } + Occupied: Boolean; { Is anyone in here? } + Moderator: SmallWord; { Who's the moderator? } + END; + + ScanRec = { *.SCN files / MESSAGES } + {$IFDEF WIN32} PACKED {$ENDIF} RECORD + NewScan: Boolean; { Scan this area? } + LastRead: UnixTime; { Last date read } + END; + + SchemeRec = { Scheme.dat } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Description: STRING[30]; { Description OF the color scheme } + Color: ARRAY [1..200] OF Byte; { Colors in scheme } + END; + + { 1 - 10 system colors + 11 - file list colors + 28 - msg list colors + 45 - file area list colors + 55 - msg area list colors + 65 - user list colors + 80 - who's online colors + 100- last on colors + 115- qwk colors + 135- email colors + } + + BBSListRecordType = { *.BBS file records } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + RecordNum, { Number OF the Record For Edit } + UserID, { User ID OF person adding this } + MaxNodes : LongInt; { Maximum Number Of Nodes } + Port : Word; { Telnet Port } + BBSName : STRING[30]; { Name OF BBS } + SysOpName : STRING[30]; { SysOp OF BBS } + TelnetUrl : STRING[60]; { Telnet Urls } + WebSiteUrl : STRING[60]; { Web Site Url } + PhoneNumber : STRING[20]; { Phone number OF BBS } + Location : STRING[30]; { Location of BBS } + Software, { Software used by BBS } + SoftwareVersion : String[12]; { Software Version of BBS } + OS : STRING[20]; { Operating System of BBS } + Speed : STRING[8]; { Highest connect speed OF BBS } + Hours : STRING[20]; { Hours of Operation } + Birth : STRING[10]; { When the BBS Began } + Description : STRING[60]; { Description OF BBS } + Description2 : STRING[60]; { Second line OF descrition } + DateAdded : UnixTime; { Date entry was added } + DateEdited : UnixTime; { Date entry was last edited } + SDA : STRING[8]; { sysop definable A } + SDB : STRING[30]; { sysop definable B } + SDC : STRING[30]; { sysop definable C } + SDD : STRING[40]; { sysop definable D } + SDE : STRING[60]; { sysop definable E } + SDF : STRING[60]; { sysop definable F } + SDG : Word; { sysop definable G } + SDH, { sysop definable H } + SDI : Boolean; { sysop definable I } + + END; + + MenuFlagType = + (ClrScrBefore, { C: clear screen before menu display } + DontCenter, { D: don't center the menu titles! } + NoMenuTitle, { T: no menu title displayed } + NoMenuPrompt, { N: no menu prompt whatsoever? } + ForcePause, { P: force a pause before menu display? } + AutoTime, { A: is time displayed automatically? } + ForceLine, { F: Force full line input } + NoGenericAnsi, { 1: DO NOT generate generic prompt if ANSI } + NoGenericAvatar, { 2: DO NOT generate generic prompt if AVT } + NoGenericRIP, { 3: DO NOT generate generic prompt if RIP } + NoGlobalDisplayed, { 4: DO NOT display the global commands! } + NoGlobalUsed); { 5: DO NOT use global commands! } + + MenuFlagSet = SET OF MenuFlagType; + + CmdFlagType = + (Hidden, { H: is command ALWAYS hidden? } + UnHidden); { U: is command ALWAYS visible? } + + CmdFlagSet = SET OF CmdFlagType; + + MenuRec = +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + LDesc: ARRAY [1..3] OF STRING[100]; { Menu Or Command Long Description ARRAY } + ACS: ACString; { Access Requirements } + NodeActivityDesc: STRING[50]; + CASE Menu: Boolean OF { Menu Or Command - Variant section} + TRUE: + (MenuFlags: MenuFlagSet; { Menu Flag SET } + LongMenu: STRING[12]; { Displayed In Place OF Long Description } + MenuNum: Byte; { Menu Number } + MenuPrompt: STRING[120]; { Menu Prompt } + Password: STRING[20]; { Menu Password } + FallBack: Byte; { Menu Fallback Number } + Directive: STRING[12]; + ForceHelpLevel: Byte; { Menu Forced Help Level } + GenCols: Byte; { Generic Menus: # OF Columns } + GCol: ARRAY [1..3] OF Byte); { Generic Menus: Colors } + FALSE: + (CmdFlags: CmdFlagSet; { Command Flag SET } + SDesc: STRING[35]; { Command Short Description } + CKeys: STRING[14]; { Command Execution Keys } + CmdKeys: STRING[2]; { Command Keys: Type OF Command } + Options: STRING[50]); { MString: Command Data } + END; diff --git a/SOURCE/RENEGADE.PAS b/SOURCE/RENEGADE.PAS new file mode 100644 index 0000000..376cc69 --- /dev/null +++ b/SOURCE/RENEGADE.PAS @@ -0,0 +1,578 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$IFDEF MSDOS} +{$M 35500,0,131072} +{$ENDIF} + +{ R E N E G A D E } +{ =============== } + +{$A+} { Align Data for faster execution } +{$B-} { Shortcut Boolean eval } +{$D+} { No Debug Info } +{$E-} { No Math-Co library } +{$F+} { Force Far Calls } +{$I-} { Disable I/O check } +{$L+} { Local Symbols, Ignored IF D-, don't need cause of D- } +{$N-} { No Math-Co use } +{$P+} { Allow OpenString } +{$O+} { Use Overlays? } +{$Q-} { No overflow check } +{$R-} { No range check } +{$S-} { Don't Check stack usage } +{$V-} { Variable string Length allowed } +{$X+} { Allow extended syntax } + +PROGRAM Renegade; + +USES + OverLay, +{ OvrUMB,} + Crt, + Dos, + Boot, + Common, + Common1, + Events, + File0, + File7, + File13, + Logon, + Mail0, + Maint, + Menus, + Menus2, + MsgPack, + MyIO, + NewUsers, + OffLine, + TimeFunc, + WfCMenu; + +{$O MsgPack } {$O Common1 } {$O Common2 } {$O Common3 } {$O Boot } +{$O WfcMenu } {$O Timefunc } {$O Sysop1 } {$O Sysop2 } {$O Offline } +{$O Sysop2j } {$O Sysop2a } {$O Sysop2b } {$O Sysop2c } {$O Sysop2d } +{$O Sysop2e } {$O Sysop2f } {$O Sysop2l } {$O Sysop2g } {$O Sysop2i } +{$O Sysop2h } {$O File4 } {$O Sysop2k } {$O Sysop3 } {$O Sysop4 } +{$O Sysop6 } {$O Sysop7 } {$O Sysop7m } {$O Sysop8 } {$O Sysop2m } +{$O Sysop9 } {$O Sysop10 } {$O Sysop11 } {$O Mail0 } {$O Mail1 } +{$O Email } {$O Mail2 } {$O Mail3 } {$O Vote } {$O Nodelist } +{$O Mail4 } {$O Arcview } {$O File0 } {$O File1 } {$O File2 } +{$O File5 } {$O File6 } {$O File8 } {$O MultNode } {$O Script } +{$O File9 } {$O File10 } {$O File11 } {$O File12 } {$O File13 } +{$O File14 } {$O Archive1 } {$O Archive2 } {$O Archive3 } {$O Logon } +{$O Maint } {$O NewUsers } {$O TimeBank } {$O Bulletin } {$O MiscUser } +{$O ShortMsg } {$O CUser } {$O Doors } {$O ExecBat } {$O Automsg } +{$O MyIO } {$O Menus2 } {$O Menus3 } {$O LineChat } {$O Stats } +{$O Events } {$O BBSList } {$O Common4 } {$O File7 } {$O SplitCha } +{$O Sysop2o } {$O Sysop5 } {$O SysOp12 } {$O OneLiner } + +CONST + NeedToHangUp: Boolean = FALSE; + +VAR + ExitSave: Pointer; + GeneralF: FILE OF GeneralRecordType; + ByteFile: FILE OF Byte; + TextFile: Text; + S: Astr; + Counter: Byte; + Counter1: Integer; + +PROCEDURE ErrorHandle; +VAR + TextFile: Text; + S: STRING[50]; +BEGIN + ExitProc := ExitSave; + IF (ErrorAddr <> NIL) THEN + BEGIN + + CHDir(StartDir); + + IF (General.Multinode) AND (ThisNode > 0) THEN + Assign(SysOpLogFile,TempDir+'TEMPLOG.'+IntToStr(ThisNode) ) + ELSE + Assign(SysOpLogFile,General.LogsPath+'SYSOP.LOG'); + + Append(SysOpLogFile); + S := '^8*>>^7 Runtime error '+IntToStr(ExitCode)+' at '+DateStr+' '+TimeStr+ '^8 <<*^5'+' (Check ERROR.LOG)'; + WriteLn(SysOpLogFile,S); + Flush(SysOpLogFile); + Close(SysOpLogFile); + + IF (TextRec(Trapfile).Mode = FMOutPut) THEN + BEGIN + WriteLn(Trapfile,S); + Flush(Trapfile); + Close(Trapfile); + END; + + Assign(TextFile,'ERROR.LOG'); + Append(TextFile); + IF (IOResult <> 0) THEN + ReWrite(TextFile); + + WriteLn(TextFile,''); + WriteLn(TextFile,'Critical error Log file - Contains screen images at instant of error.'); + WriteLn(TextFile,'The "" character shows the cursor position at time of error.'); + WriteLn(TextFile,''); + WriteLn(TextFile); + WriteLn(TextFile); + WriteLn(TextFile,'> error #'+IntToStr(ExitCode)+' at '+DateStr+' '+TimeStr+' version: '+General.Version); + + IF (UserOn) THEN + BEGIN + Write(TextFile,'> User "'+AllCaps(ThisUser.name)+' #'+IntToStr(UserNum)+'" was on '); + IF (ComPortSpeed > 0) THEN + WriteLn(TextFile,'at '+IntToStr(ActualSpeed)+ 'baud') + ELSE + WriteLn(TextFile,'Locally'); + END; + Close(TextFile); + + ScreenDump('ERROR.LOG'); + + Assign(TextFile,'CRITICAL.ERR'); + ReWrite(TextFile); + Close(TextFile); + SetFAttr(TextFile,Dos.Hidden); + + Print('^8System malfunction.'); + + LoadNode(ThisNode); + Noder.Status := []; + Noder.User := 0; + SaveNode(ThisNode); + + Com_Flush_Send; + Dtr(FALSE); + Com_DeInstall; + + Halt(ExitErrors); + + END; +END; + +PROCEDURE ReadP; +VAR + d: astr; + Counter: Integer; + + FUNCTION SC(s: astr; i: Integer): Char; + BEGIN + SC := UpCase(s[i]); + END; + +BEGIN + Reliable := FALSE; + Telnet := FALSE; + CallerIDNumber := ''; + Counter := 0; + WHILE (Counter < ParamCount) DO + BEGIN + Inc(Counter); + IF ((SC(ParamStr(Counter),1) = '-') OR (SC(ParamStr(Counter),1) = '/')) THEN + CASE SC(ParamStr(Counter),2) OF + '5' : TextMode(259); + 'B' : AnswerBaud := StrToInt(Copy(ParamStr(Counter),3,255)); + 'C' : Reliable := (Pos(AllCaps(Liner.Reliable),AllCaps(ParamStr(Counter))) > 0); + 'D' : OvrUseEms := FALSE; + 'E' : IF (Length(ParamStr(Counter)) >= 4) THEN + BEGIN + d := AllCaps(ParamStr(Counter)); + CASE d[3] OF + 'E' : ExitErrors := StrToInt(Copy(d,4,(Length(d) - 3))); + 'N' : ExitNormal := StrToInt(Copy(d,4,(Length(d) - 3))); + END; + END; + 'H' : SockHandle := Copy(ParamStr(Counter),3,255); + 'I' : BEGIN + CASE SC(ParamStr(Counter),3) OF + 'D' : CallerIDNumber := Copy(ParamStr(Counter),4,255); + 'P' : CallerIDNumber := Copy(ParamStr(Counter),4,255); + END; + END; + 'L' : LocalIOOnly := TRUE; + 'M' : BEGIN + MakeQWKFor := StrToInt(Copy(ParamStr(Counter),3,255)); + LocalIOOnly := TRUE; + END; + 'N' : ThisNode := StrToInt(Copy(ParamStr(Counter),3,255)); + 'P' : BEGIN + PackBasesOnly := TRUE; + LocalIOOnly := TRUE; + END; + 'Q' : QuitAfterDone := TRUE; + 'S' : BEGIN + SortFilesOnly := TRUE; + LocalIOOnly := TRUE; + END; + 'F' : BEGIN + FileBBSOnly := TRUE; + LocalIOOnly := TRUE; + END; + 'T' : BEGIN + IF (SC(ParamStr(Counter),3) <> 'C') THEN + HangUpTelnet := TRUE; + Telnet := TRUE; + END; + 'U' : BEGIN + UpQWKFor := StrToInt(Copy(ParamStr(Counter),3,255)); + LocalIOOnly := TRUE; + END; + 'X' : ExtEventTime := StrToInt(Copy(ParamStr(Counter),3,255)); + END; + END; + AllowAbort := TRUE; +END; + +BEGIN + ClrScr; + TextColor(Yellow); +{$IFDEF MSDOS} + GetIntVec($14,Interrupt14); +{$ENDIF} + FileMode := 66; +{$IFDEF WIN32} + FileModeReadWrite := FileMode; +{$ENDIF} + ExitSave := ExitProc; + ExitProc := @ErrorHandle; + + DirectVideo := FALSE; + CheckSnow := FALSE; + + UserOn := FALSE; + UserNum := 0; + + GetDir(0,StartDir); + + DatFilePath := GetEnv('RENEGADE'); + IF (DatFilePath <> '') THEN + DatFilePath := BSlash(DatFilePath,TRUE); + Assign(ByteFile,DatFilePath+'RENEGADE.DAT'); + Reset(ByteFile); + IF (IOResult <> 0) THEN + BEGIN + WriteLn('Error opening RENEGADE.DAT.'); + Halt; + END; + Counter := 0; + Seek(ByteFile,FileSize(ByteFile)); + WHILE FileSize(ByteFile) < SizeOf(General) DO + Write(ByteFile,Counter); + Close(ByteFile); + + Assign(GeneralF,DatFilePath+'RENEGADE.DAT'); + Reset(GeneralF); + Read(GeneralF,General); + Close(GeneralF); + + ReadP; + +{$IFDEF MSDOS} + OvrFileMode := 0; + Write('Initializing RENEGADE.OVR ... '); + OvrInit('RENEGADE.OVR'); + IF (OvrResult <> OvrOK) THEN + OvrInit(General.DataPath+'RENEGADE.OVR'); + IF (OvrResult <> OvrOK) THEN + BEGIN + CASE OvrResult OF + OvrError : WriteLn('Program has no overlays.'); + OvrNotFound : WriteLn('Overlay file not found.'); + END; + Halt; + END + ELSE + WriteLn('Done.'); + + IF (General.UseEMS) AND (OvrUseEms) THEN + BEGIN + + Write('Attempting to load overlays into XMS memory ... '); + + {vrMovBufToUMB;} + + IF (OvrResult <> OvrOK) THEN + BEGIN + WriteLn('Failed.'); + Write('Attempting to load overlays into EMS memory ... '); + OvrInitEMS; + IF (OvrResult = OvrOK) THEN + BEGIN + WriteLn('Done.'); + OverLayLocation := 1 + END + ELSE + BEGIN + CASE OvrResult OF + OvrIOError : WriteLn('Overlay file I/O error.'); + OvrNoEMSDriver : WriteLn('EMS driver not installed.'); + OvrNoEMSMemory : WriteLn('Not enough EMS memory.'); + END; + Halt; + END; + END + ELSE + BEGIN + WriteLn('Done.'); + OverLayLocation := 2; + END; + END; + WriteLn('Initial size of the overlay buffer is '+FormatNumber(OvrGetBuf)+' bytes.'); +{$ENDIF} + + Init; + + MaxDisplayRows := (Hi(WindMax) + 1); + MaxDisplayCols := (Lo(WindMax) + 1); + ScreenSize := 2 * MaxDisplayRows * MaxDisplayCols; + IF (ScreenSize > 8000) THEN + ScreenSize := 8000; + + IF (FileBBSOnly) OR (PackBasesOnly) OR (SortFilesOnly) OR (MakeQWKFor > 0) OR (UpQWKFor > 0) THEN + BEGIN + WFCMDefine; + TempPause := FALSE; + IF (MakeQWKFor > 0) THEN + BEGIN + UserNum := MakeQWKFor; + LoadURec(ThisUser,MakeQWKFor); + NewFileDate := ThisUser.LastOn; + Downloadpacket; + SaveURec(ThisUser,MakeQWKFor); + END; + + IF (UpQWKFor > 0) THEN + BEGIN + UserNum := UpQWKFor; + LoadURec(ThisUser,UpQWKFor); + Uploadpacket(TRUE); + SaveURec(ThisUser,UpQWKFor); + END; + + IF (PackBasesOnly) THEN + BEGIN + DoShowPackMessageAreas; + NL; + Print('^5Message areas packed.'); + END; + + IF (SortFilesOnly) THEN + Sort; + + IF (FileBBSOnly) THEN + CheckFilesBBS; + + Halt(0); + END; + + GetMem(MemCmd,MaxCmds * SizeOf(MemCmdRec)); + + REPEAT + + IF (NeedToHangUp) THEN + BEGIN + NeedToHangUp := FALSE; + DoPhoneHangUp(FALSE); + END; + + WFCMenus; + + UserOn := FALSE; + UserNum := 0; + + IF (NOT DoneDay) THEN + BEGIN + + lStatus_Screen(100,'User logging in.',FALSE,S); + + LastScreenSwap := 0; + + IF (GetUser) THEN + NewUser; + + IF (NOT HangUp) THEN + BEGIN + + NumBatchDLFiles := 0; + NumBatchULFiles := 0; + BatchDLPoints := 0; + BatchDLSize := 0; + BatchDLTime := 0; + + LogonMaint; + + IF (NOT HangUp) THEN + BEGIN + + NewFileDate := ThisUser.LastOn; + + IF (MsgAreaAC(ThisUser.LastMsgArea)) THEN + MsgArea := ThisUser.LastMsgArea + ELSE + BEGIN + FOR Counter := 1 TO NumMsgAreas DO + IF (MsgAreaAC(Counter)) THEN + BEGIN + MsgArea := Counter; + Counter := NumMsgAreas; + END; + END; + + IF (FileAreaAC(ThisUser.LastFileArea)) THEN + FileArea := ThisUser.LastFileArea + ELSE + BEGIN + FOR Counter := 1 TO NumFileAreas DO + IF (FileAreaAC(Counter)) THEN + BEGIN + FileArea := Counter; + Counter := NumFileAreas; + END; + END; + + NewCompTables; + + MenuStackPtr := 0; + + FOR Counter := 1 TO MaxMenus DO + MenuStack[Counter] := 0; + + IF (Novice in ThisUser.Flags) THEN + CurHelpLevel := 2 + ELSE + CurHelpLevel := 1; + + GlobalCmds := 0; + NumCmds := 0; + CurMenu := 0; + FallBackMenu := 0; + + IF (General.GlobalMenu <> 0) THEN + BEGIN + CurMenu := General.GlobalMenu; + LoadMenu; + GlobalCmds := NumCmds; + END; + + IF (ThisUser.UserStartMenu = 0) THEN + CurMenu := General.AllStartMenu + ELSE + CurMenu := ThisUser.UserStartMenu; + + LoadMenu; + + AutoExecCmd('FIRSTCMD'); + + END; + + WHILE (NOT HangUp) DO + MenuExec; + + END; + + IF (QuitAfterDone) THEN + BEGIN + IF (ExitErrorLevel = 0) THEN + ExitErrorLevel := ExitNormal; + HangUp := TRUE; + DoneDay := TRUE; + NeedToHangUp := TRUE; + END; + + LogOffMaint; + + IF (General.Multinode) THEN + BEGIN + Assign(TextFile,General.LogsPath+'SYSOP.LOG'); + IF Exist(General.LogsPath+'SYSOP.LOG') THEN + Append(TextFile) + ELSE + ReWrite(TextFile); + Reset(SysOpLogFile); + WHILE NOT EOF(SysOpLogFile) DO + BEGIN + ReadLn(SysOpLogFile,S); + WriteLn(TextFile,S); + END; + Close(SysOpLogFile); + Close(TextFile); + ReWrite(SysOpLogFile); + Close(SysOpLogFile); + LastError := IOResult; + END; + + IF (Com_Carrier) AND (NOT DoneDay) THEN + IF (InCom) THEN + NeedToHangUp := TRUE; + + END; + + UNTIL (DoneDay); + + FreeMem(MemCmd,MaxCmds * SizeOf(MemCmdRec)); + + IF (MCIBuffer <> NIL) THEN + Dispose(MCIBuffer); + + IF (MemEventArray[NumEvents] <> NIL) THEN + FOR Counter1 := 1 TO NumEvents DO + IF (MemEventArray[Counter1] <> NIL) THEN + Dispose(MemEventArray[Counter1]); + + IF (NeedToHangUp) THEN + BEGIN + IF (HangUpTelnet) THEN + DoTelnetHangUp(TRUE); + IF (NOT HangUpTelnet) THEN + DoPhoneHangUp(FALSE); + END; + + IF (General.Multinode) THEN + BEGIN + Assign(TextFile,General.LogsPath+'SYSOP.LOG'); + IF Exist(General.LogsPath+'SYSOP.LOG') THEN + Append(TextFile) + ELSE + ReWrite(TextFile); + Reset(SysOpLogFile); + WHILE NOT EOF(SysOpLogFile) DO + BEGIN + ReadLn(SysOpLogFile,S); + WriteLn(TextFile,S); + END; + Close(SysOpLogFile); + Close(TextFile); + ReWrite(SysOpLogFile); + Close(SysOpLogFile); + LastError := IOResult; + END; + + IF (General.Multinode) THEN + Kill(TempDir+'TEMPLOG.'+IntToStr(ThisNode)); + + Window(1,1,MaxDisplayCols,MaxDisplayRows); + TextBackGround(0); + TextColor(7); + ClrScr; + TextColor(14); + + IF (NewEchoMail) AND (ExitErrorLevel = 0) THEN + ExitErrorLevel := 2; + + LoadNode(ThisNode); + Noder.Status := []; + SaveNode(ThisNode); + + PurgeDir(TempDir,FALSE); + + Com_DeInstall; + + WriteLn('Exiting with errorlevel ',ExitErrorLevel); + Halt(ExitErrorLevel); +END. diff --git a/SOURCE/RENEMAIL.PAS b/SOURCE/RENEMAIL.PAS new file mode 100644 index 0000000..5e89a56 --- /dev/null +++ b/SOURCE/RENEMAIL.PAS @@ -0,0 +1,2218 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$IFDEF MSDOS} +{$M 49152,0,65536} +{$ENDIF} +{$A+,I-,E-,F+} + +PROGRAM ReneMail; + +USES + Crt, + Dos, + TimeFunc; + +{$I RECORDS.PAS} + +CONST + Activity_Log: Boolean = FALSE; + NetMailOnly: Boolean = FALSE; + IsNetMail: Boolean = FALSE; +{$IFDEF MSDOS} + FastPurge: Boolean = TRUE; +{$ENDIF} +{$IFDEF WIN32} + FastPurge: Boolean = FALSE; +{$ENDIF} + Process_NetMail: Boolean = TRUE; + Purge_NetMail: Boolean = TRUE; + Absolute_Scan: Boolean = FALSE; + Ignore_1Msg: Boolean = TRUE; + Toss_Mail: Boolean = FALSE; + Scan_Mail: Boolean = FALSE; + Purge_Dir: Boolean = FALSE; + +TYPE + FidoRecordType = RECORD + FromUserName: STRING[35]; + ToUserName: STRING[35]; + Subject: STRING[71]; + DateTime: STRING[19]; + TimesRead: SmallWord; + DestNode: SmallWord; + OrigNode: SmallWord; + Cost: SmallWord; + OrigNet: SmallWord; + DestNet: SmallWord; + Filler: ARRAY[1..8] OF Char; + ReplyTo: SmallWord; + Attribute: SmallWord; + NextReply: SmallWord; + END; + + BufferArrayType = ARRAY[1..32767] OF Char; + +VAR + FCB: ARRAY[1..37] OF Char; + + BufferArray: BufferArrayType; + + GeneralFile: FILE OF GeneralRecordType; + + UserFile: FILE OF UserRecordType; + + MessageAreaFile: FILE OF MessageAreaRecordType; + + IndexFile: FILE OF UserIDXRec; + + RGMsgHdrFile: FILE OF MHeaderRec; + + RGMsgTxtFile: FILE; + + FidoFile: FILE; + + HiWaterF: FILE OF SmallWord; + + General: GeneralRecordType; + + User: UserRecordType; + + MemMsgArea: MessageAreaRecordType; + + IndexR: UserIDXRec; + + RGMsgHdr: MHeaderRec; + + FidoMsgHdr: FidoRecordType; + +{$IFDEF MSDOS} + Regs: Registers; +{$ENDIF} + + DirInfo: SearchRec; + + TempParamStr, + StartDir: STRING; + + LastError, + ParamCounter, + MsgArea: Integer; + + ParamFound: Boolean; + +{$IFDEF WIN32} +(* REENOTE + In BP/TP you can do this: + + var + MySet: NetAttribs; + MyWord: Word; + begin + MySet := [Private, Crash]; + MyWord := Word(MySet); + { MyWord now contains the value 3 in BP/TP } + { but VP refuses to compile the code due to Word(MySet) } + end; + + In VP this typecast isn't allowed (maybe there's a compiler setting to allow it, didn't look actually) + so this function converts from a set to a word type. + + While this function should work for both BP/TP and for VP, I'm only using it for VP and using the + original cast for BP/TP, since there's no need to change what isn't broken +*) +function NetAttribsToWord(inSet: NetAttribs): Word; +var + Result: Word; +begin + Result := 0; + if (Private in inSet) then result := result + 1; + if (Crash in inSet) then result := result + 2; + if (Recd in inSet) then result := result + 4; + if (NSent in inSet) then result := result + 8; + if (FileAttach in inSet) then result := result + 16; + if (Intransit in inSet) then result := result + 32; + if (Orphan in inSet) then result := result + 64; + if (KillSent in inSet) then result := result + 128; + if (Local in inSet) then result := result + 256; + if (Hold in inSet) then result := result + 512; + if (Unused in inSet) then result := result + 1024; + if (FileRequest in inSet) then result := result + 2048; + if (ReturnReceiptRequest in inSet) then result := result + 4096; + if (IsReturnReceipt in inSet) then result := result + 8192; + if (AuditRequest in inSet) then result := result + 16384; + if (FileUpdateRequest in inSet) then result := result + 32768; + NetAttribsToWord := Result; +end; +{$ENDIF} + +FUNCTION CenterStr(S: STRING): STRING; +VAR + Counter1: Byte; +BEGIN + Counter1 := ((80 - Length(S)) DIV 2); + Move(S[1],S[Counter1 + 1],Length(S)); + Inc(S[0],Counter1); + FillChar(S[1],Counter1,#32); + CenterStr := S; +END; + +PROCEDURE WriteCharXY(C: Char; X,Y,FColor,BColor: Byte); +BEGIN + TextColor(FColor); + TextBackGround(BColor); + GotoXY(X,Y); + Write(C); +END; + +PROCEDURE WriteStrXY(S: STRING; X,Y,FColor,BColor: Byte); +BEGIN + TextColor(FColor); + TextBackGround(BColor); + GotoXY(X,Y); + Write(S); +END; + +PROCEDURE DisplayMain(FColor,BColor: Byte); +VAR + X, + Y: Byte; +BEGIN + ClrScr; + Window(1,1,80,24); + TextColor(FColor); + TextBackGround(BColor); + ClrScr; + Window(1,1,80,25); + WriteCharXY(#201,1,1,FColor,BColor); + FOR X := 2 TO 79 DO + WriteCharXY(#205,X,1,FColor,BColor); + WriteCharXY(#187,80,1,FColor,BColor); + FOR Y := 2 TO 3 DO + BEGIN + WriteCharXY(#186,1,Y,FColor,BColor); + WriteCharXY(#186,80,Y,FColor,BColor); + END; + WriteCharXY(#204,1,4,FColor,BColor); + FOR X := 2 TO 79 DO + WriteCharXY(#205,X,4,FColor,BColor); + WriteCharXY(#185,80,4,FColor,BColor); + WriteStrXY(CenterStr('Renegade Echomail Interface v'+Ver),2,2,FColor,BColor); + WriteStrXY(CenterStr('Copyright 2004-2011 - The Renegade Developement Team'),2,3,FColor,BColor); + FOR Y := 5 TO 21 DO + BEGIN + WriteCharXY(#186,1,Y,FColor,BColor); + WriteCharXY(#186,80,Y,FColor,BColor); + END; + WriteCharXY(#204,1,22,FColor,BColor); + FOR X := 2 TO 79 DO + WriteCharXY(#205,X,22,FColor,BColor); + WriteCharXY(#185,80,22,FColor,BColor); + WriteCharXY(#186,1,23,FColor,BColor); + WriteStrXY('Message: None',3,23,FColor,BColor); + WriteCharXY(#186,80,23,FColor,BColor); + WriteCharXY(#200,1,24,FColor,BColor); + FOR X := 2 TO 79 DO + WriteCharXY(#205,X,24,FColor,BColor); + WriteCharXY(#188,80,24,FColor,BColor); + Window(2,5,78,21); + GoToXY(1,1); +END; + +PROCEDURE DisplayHelp(FColor,BColor: Byte); +BEGIN + WriteStrXY('Commands: -T Toss incoming messages',22,2,FColor,BColor); + WriteStrXY('-P Purge echomail dirs',33,3,FColor,BColor); + WriteStrXY('-S Scan outbound messages',33,4,FColor,BColor); + WriteStrXY('Options: -A Absolute Scan',22,6,FColor,BColor); + WriteStrXY('-D Do not delete netmail',37,7,FColor,BColor); + WriteStrXY('-F No fast purge',37,8,FColor,BColor); + WriteStrXY('-I Import 1.MSG',37,9,FColor,BColor); + WriteStrXY('-L Activity logging',37,10,FColor,BColor); + WriteStrXY('-N No netmail',37,11,FColor,BColor); + WriteStrXY('-O Only netmail',37,12,FColor,BColor); +END; + +PROCEDURE ErrorStrXY(S: STRING; X,Y,FColor,BColor: Byte); +VAR + SaveX, + SaveY: Byte; +BEGIN + SaveX := WhereX; + SaveY := WhereY; + Window(1,1,80,25); + GoToXY(X,Y); + TextColor(FColor); + TextBackGround(BColor); + Write(S); + Window(2,5,78,21); + GoToXY(SaveX,SaveY); +END; + +PROCEDURE HaltErrorStrXY(S: STRING; X,Y,FColor,BColor,HaltNum: Byte); +BEGIN + DisplayHelp(White,Blue); + Window(1,1,80,25); + GoToXY(X,Y); + TextColor(FColor); + TextBackGround(BColor); + Write(S); + GotoXY(1,25); + Halt(HaltNum); +END; + +PROCEDURE LogActivity(ActivityMsg: STRING); +VAR + ActivityFile: Text; +BEGIN + IF (Activity_Log) THEN + BEGIN + Assign(ActivityFile,General.LogsPath+'RENEMAIL.LOG'); + {$I-} Append(ActivityFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + {$I-} ReWrite(ActivityFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + ErrorStrXY('Unable to create RENEMAIL.LOG.',12,23,Red + 128,Blue); + END; + {$I-} Write(ActivityFile,ActivityMsg); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + ErrorStrXY('Unable to write to RENEMAIL.LOG.',12,23,Red + 128,Blue); + {$I-} Close(ActivityFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + ErrorStrXY('Unable to close RENEMAIL.LOG.',12,23,Red + 128,Blue); + END; +END; + +PROCEDURE LogError(ErrMsg: STRING); +VAR + ErrorFile: Text; +BEGIN + Assign(ErrorFile,General.LogsPath+'RENEMAIL.ERR'); + {$I-} Append(ErrorFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + {$I-} ReWrite(ErrorFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + ErrorStrXY('Unable to create RENEMAIL.ERR.',12,23,Red + 128,Blue); + END; + {$I-} WriteLn(ErrorFile,ToDate8(DateStr)+' '+TimeStr+': '+ErrMsg); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + ErrorStrXY('Unable to write to RENEMAIL.ERR.',12,23,Red + 128,Blue); + {$I-} Close(ErrorFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + ErrorStrXY('Unable to close RENEMAIL.ERR.',12,23,Red + 128,Blue); +END; + +FUNCTION SC(S: STRING; I: Integer): Char; +BEGIN + SC := UpCase(S[I]); +END; + +FUNCTION Hex(L: LongInt; B: Byte): STRING; +CONST + HC: ARRAY[0..15] OF Char = '0123456789ABCDEF'; +VAR + One, + Two, + Three, + Four: Byte; +BEGIN + One := (L AND $000000FF); + Two := ((L AND $0000FF00) SHR 8); + Three := ((L AND $00FF0000) SHR 16); + Four := ((L AND $FF000000) SHR 24); + Hex[0] := Chr(B); + IF (B = 4) THEN + BEGIN + Hex[1] := HC[Two SHR 4]; + Hex[2] := HC[Two AND $F]; + Hex[3] := HC[One SHR 4]; + Hex[4] := HC[One AND $F]; + END + ELSE + BEGIN + Hex[8] := HC[One AND $F]; + Hex[7] := HC[One SHR 4]; + Hex[6] := HC[Two AND $F]; + Hex[5] := HC[Two SHR 4]; + Hex[4] := HC[Three AND $F]; + Hex[3] := HC[Three SHR 4]; + Hex[2] := HC[Four AND $F]; + Hex[1] := HC[Four SHR 4]; + END; +END; + +FUNCTION SQOutSp(S: STRING): STRING; +BEGIN + WHILE (Pos(' ',S) > 0) DO + Delete(S,Pos(' ',S),1); + SQOutSp := S; +END; + +FUNCTION BSlash(S: STRING; B: Boolean): STRING; +BEGIN + IF (B) THEN + BEGIN + WHILE (Copy(S,(Length(S) - 1),2) = '\\') DO + S := Copy(S,1,(Length(S) - 2)); + IF (Copy(S,Length(S),1) <> '\') THEN + S := S + '\'; + END + ELSE + WHILE (S[Length(S)] = '\') DO + Dec(S[0]); + BSlash := S; +END; + +FUNCTION ExistDir(Dir: STRING): Boolean; +BEGIN + WHILE (Dir[Length(Dir)] = '\') DO + Dec(Dir[0]); + FindFirst(Dir,AnyFile,DirInfo); + ExistDir := (DOSError = 0) AND (DirInfo.Attr AND $10 = $10); +END; + +FUNCTION ExistFile(FileName: STRING): Boolean; +BEGIN + FindFirst(SQOutSp(FileNAme),AnyFile,DirInfo); + ExistFile := (DOSError = 0); +END; + +(* +PROCEDURE MakeDir(Dir: STRING); +VAR + Counter: Integer; +BEGIN + Dir := BSlash(Dir,TRUE); + IF (Length(Dir) > 3) AND (NOT ExistDir(Dir)) THEN + BEGIN + Counter := 2; + WHILE (Counter <= Length(Dir)) DO + BEGIN + IF (Dir[Counter] = '\') THEN + IF (Dir[Counter - 1] <> ':') THEN + IF (NOT ExistDir(Copy(Dir,1,(Counter - 1)))) THEN + BEGIN + MkDir(Copy(Dir,1,(Counter - 1))); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + WriteLn('Error creating message path: '+Copy(Dir,1,(Counter - 1))); + LogError(Copy(Dir,1,(Counter - 1))+'/ '); + Halt(1); + END; + END; + Inc(Counter); + END; + END; +END; +*) + +{$IFDEF MSDOS} +FUNCTION AOnOff(B: Boolean; S1,S2: STRING): STRING; ASSEMBLER; +ASM + PUSH ds + Test b, 1 + JZ @@1 + LDS si, s1 + JMP @@2 + @@1: LDS si, s2 + @@2: LES di, @Result + XOR Ch, Ch + MOV cl, Byte ptr ds:[si] + MOV Byte ptr es:[di], cl + Inc di + Inc si + CLD + REP MOVSB + POP ds +END; +{$ENDIF} +{$IFDEF WIN32} +FUNCTION AOnOff(B: Boolean; S1,S2: STRING): STRING; +BEGIN + if (B) then + AOnOff := S1 + else + AOnOff := S2; +END; +{$ENDIF} + +FUNCTION StripName(S: STRING): STRING; +VAR + Counter: Integer; +BEGIN + Counter := Length(S); + WHILE (Counter > 0) AND (Pos(S[Counter],':\/') = 0) DO + Dec(Counter); + Delete(S,1,Counter); + StripName := S; +END; + +FUNCTION AllCaps(S: STRING): STRING; +VAR + Counter: Integer; +BEGIN + AllCaps[0] := s[0]; + FOR Counter := 1 TO Length(S) DO + AllCaps[Counter] := UpCase(S[Counter]); +END; + +FUNCTION Caps(S: STRING): STRING; +VAR + Counter: Integer; +BEGIN + FOR Counter := 1 TO Length(s) DO + IF (S[Counter] IN ['A'..'Z']) THEN + S[Counter] := Chr(Ord(S[Counter]) + 32); + FOR Counter := 1 TO Length(S) DO + IF (NOT (S[Counter] IN ['A'..'Z','a'..'z',Chr(39)])) THEN + IF (S[Counter + 1] IN ['a'..'z']) THEN + S[Counter + 1] := UpCase(S[Counter + 1]); + S[1] := UpCase(S[1]); + Caps := S; +END; + +FUNCTION StrToInt(S: STRING): LongInt; +VAR + I: Integer; + L: LongInt; +BEGIN + Val(S,L,I); + IF (I <> 0) THEN + BEGIN + S[0] := Chr(I - 1); + Val(S,L,I) + END; + StrToInt := L; + IF (S = '') THEN + StrToInt := 0; +END; + +FUNCTION IntToStr(L: LongInt): STRING; +VAR + S: STRING; +BEGIN + Str(L,S); + IntToStr := S; +END; + +FUNCTION PadRightStr(S: STRING; Len: Byte): STRING; +VAR + X, + Counter: Byte; +BEGIN + X := Length(S); + FOR Counter := X TO (Len - 1) DO + S := ' ' + S; + PadRightStr := S; +END; + +FUNCTION StripColor(MAFlags: MAFlagSet; InStr: STRING): STRING; +VAR + OutStr: STRING; + Counter, + Counter1: Byte; +BEGIN + Counter := 0; + OutStr := ''; + WHILE (Counter < Length(InStr)) DO + BEGIN + Inc(Counter); + CASE InStr[Counter] OF + #128..#255 : + IF (MAFilter IN MAFlags) THEN + OutStr := OutStr + Chr(Ord(InStr[Counter]) AND 128) + ELSE + OutStr := OutStr + InStr[Counter]; + '^' : IF InStr[Counter + 1] IN [#0..#9,'0'..'9'] THEN + Inc(Counter) + ELSE + OutStr := OutStr + '^'; + '|' : IF (MAFilter IN MAFlags) AND (InStr[Counter + 1] IN ['0'..'9']) THEN + BEGIN + Counter1 := 0; + WHILE (InStr[Counter + 1] IN ['0'..'9']) AND (Counter <= Length(InStr)) AND (Counter1 <= 2) DO + BEGIN + Inc(Counter); + Inc(Counter1) + END + END + ELSE + OutStr := OutStr + '|' + ELSE + OutStr := OutStr + InStr[Counter]; + END; + END; + StripColor := OutStr; +END; + +FUNCTION UseName(B: Byte; S: STRING): STRING; +BEGIN + CASE b OF + 1,2 + : S := 'Anonymous'; + 3 : S := 'Abby'; + 4 : S := 'Problemed Person'; + END; + UseName := S; +END; + +FUNCTION SearchUser(GenDataPath: STRING; Uname: STRING): Integer; +VAR + Current: Integer; + Done: Boolean; +BEGIN + Assign(IndexFile,GenDataPath+'USERS.IDX'); + {$I-} Reset(IndexFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to open USERS.IDX.'); + TextColor(LightGray); + LogError(GenDataPath+'USERS.IDX/Open File Error - '+IntToStr(LastError)+' (Proc: SearchUser)'); + Exit; + END; + Uname := AllCaps(UName); + Current := 0; + Done := FALSE; + IF (FileSize(IndexFile) > 0) THEN + REPEAT + {$I-} Seek(IndexFile,Current); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to seek record in USERS.IDX.'); + TextColor(LightGray); + LogError(GenDataPath+'USERS.IDX/Seek Record '+IntTostr(Current)+' Error - '+IntToStr(LastError)+' (Proc: SearchUser)'); + Exit; + END; + {$I-} Read(IndexFile,IndexR); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to read record from USERS.IDX.'); + TextColor(LightGray); + LogError(GenDataPath+'USERS.IDX/Read Record '+IntTostr(Current)+' Error - '+IntToStr(LastError)+' (Proc: SearchUser)'); + Exit; + END; + IF (Uname < IndexR.Name) THEN + Current := IndexR.Left + ELSE IF (Uname > IndexR.Name) THEN + Current := IndexR.Right + ELSE + Done := TRUE; + UNTIL (Current = -1) OR (Done); + {$I-} Close(IndexFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to close USERS.IDX.'); + TextColor(LightGray); + LogError(GenDataPath+'USERS.IDX/Close File Error - '+IntToStr(LastError)+' (Proc: SearchUser)'); + Exit; + END; + IF (Done) AND (NOT IndexR.Deleted) THEN + SearchUser := IndexR.Number + ELSE + SearchUser := 0; +END; + +PROCEDURE GetGeneral(VAR General1: GeneralRecordType); +BEGIN + Assign(GeneralFile,'RENEGADE.DAT'); + {$I-} Reset(GeneralFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError('RENEGADE.DAT/Open File Error - '+IntToStr(LastError)+' (Proc: GetGeneral)'); + HaltErrorStrXY('Unable to open RENEGADE.DAT!',12,23,Red + 128,Blue,1); + END; + {$I-} Seek(GeneralFile,0); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError('RENEGADE.DAT/Seek Record 0 Error - '+IntToStr(LastError)+' (Proc: GetGeneral)'); + HaltErrorStrXY('Unable to seek record in RENEGADE.DAT!',12,23,Red + 128,Blue,1); + END; + {$I-} Read(GeneralFile,General1); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError('RENEGADE.DAT/Read Record 0 Error - '+IntToStr(LastError)+' (Proc: GetGeneral)'); + HaltErrorStrXY('Unable to read record from RENEGADE.DAT!',12,23,Red + 128,Blue,1); + END; + {$I-} Close(GeneralFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError('RENEGADE.DAT/Close File Error - '+IntToStr(LastError)+' (Proc: GetGeneral)'); + HaltErrorStrXY('Unable to close RENEGADE.DAT!',12,23,Red + 128,Blue,1); + END; +END; + +PROCEDURE GeneralPaths(General1: GeneralRecordType); +BEGIN + IF (NOT ExistDir(General1.DataPath)) THEN + BEGIN + LogError(General1.DataPath+'/Data Path - "Invalid" (Proc: GeneralPaths)'); + HaltErrorStrXY('The system configuration data path is invalid!',12,23,Red + 128,Blue,1); + END; + IF (NOT ExistDir(General1.NetMailPath)) THEN + BEGIN + LogError(General1.NetMailPath+'/NetMail Path - "Invalid" (Proc: GeneralPaths)'); + HaltErrorStrXY('The system configuration netmail path is invalid!',12,23,Red + 128,Blue,1); + END; + IF (NOT ExistDir(General1.MsgPath)) THEN + BEGIN + LogError(General1.MsgPath+'/Message Path - "Invalid" (Proc: GeneralPaths)'); + HaltErrorStrXY('The system configuration message path is invalid!',12,23,Red + 128,Blue,1); + END; + IF (NOT ExistDir(General1.LogsPath)) THEN + BEGIN + LogError(General1.LogsPath+'/Log Path - "Invalid" (Proc: GeneralPaths)'); + HaltErrorStrXY('The system configuration log path is invalid!',12,23,Red + 128,Blue,1); + END; +END; + +PROCEDURE GeneralFiles(General1: GeneralRecordType); +BEGIN + IF (NOT ExistFile(General1.DataPath+'USERS.DAT')) THEN + BEGIN + LogError(General1.DataPath+'USERS.DAT/File - "Missing" (Proc: GeneralFiles)'); + HaltErrorStrXY('Unable to locate USERS.DAT!',12,23,Red + 128,Blue,1); + END; + IF (NOT ExistFile(General1.DataPath+'USERS.IDX')) THEN + BEGIN + LogError(General1.DataPath+'USERS.IDX/File - "Missing" (Proc: GeneralFiles)'); + HaltErrorStrXY('Unable to locate USERS.IDX!',12,23,Red + 128,Blue,1); + END; + IF (NOT ExistFile(General1.DataPath+'MBASES.DAT')) THEN + BEGIN + LogError(General1.DataPath+'MBASES.DAT/File - "Missing" (Proc: GeneralFiles)'); + HaltErrorStrXY('Unable to locate MBASES.DAT!',12,23,Red + 128,Blue,1); + END; +END; + +(* +PROCEDURE MessageFile(General1: GeneralRecordType); +VAR + MArea: Integer; +BEGIN + Assign(MessageAreaFile,General1.DataPath+'MBASES.DAT'); + {$I-} Reset(MessageAreaFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to open MBASES.DAT.'); + TextColor(LightGray); + LogError(General1.DataPath+'MBASES.DAT/Open File Error - '+IntToStr(LastError)+' (Proc: MessageFile)'); + Halt(1); + END; + MArea := 1; + WHILE (MArea <= (FileSize(MessageAreaFile))) DO + BEGIN + {$I-} Seek(MessageAreaFile,(MArea - 1)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to seek record in MBASES.DAT.'); + TextColor(LightGray); + LogError(General1.DataPath+'MBASES.DAT/Seek Record '+IntToStr(MArea - 1)+' Error - '+IntToStr(LastError)+ + ' (Proc: MessageFile)'); + Halt(1); + END; + {$I-} Read(MessageAreaFile,MemMsgArea); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to read record from MBASES.DAT.'); + TextColor(LightGray); + LogError(General1.DataPath+'MBASES.DAT/Read Record '+IntToStr(MArea - 1)+' Error - '+IntToStr(LastError)+ + ' (Proc: MessageFile)'); + Halt(1); + END; + IF (MemMsgArea.MAType = 1) THEN + BEGIN + IF (NOT ExistDir(MemMsgArea.MsgPath)) THEN + + END; + Inc(MArea); + END; + {$I-} Close(MessageAreaFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to close MBASES.DAT.'); + TextColor(LightGray); + LogError(General1.DataPath+'MBASES.DAT/Close File Error - '+IntToStr(LastError)+' (Proc: MessageFile)'); + Halt(1); + END; +END; +*) + +PROCEDURE GetMsgLst(MemMsgPath: STRING; VAR LowMsg,HighMsg: Word); +VAR + FidoMsgNum, + HiWater: SmallWord; +BEGIN + HiWater := 1; + IF (NOT IsNetMail) THEN + BEGIN + Assign(HiWaterF,MemMsgPath+'HI_WATER.MRK'); + {$I- } Reset(HiWaterF); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + {$I-} ReWrite(HiWaterF); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to create '+MemMsgPath+'HI_WATER.MRK.'); + TextColor(LightGray); + LogError(MemMsgPath+'HI_WATER.MRK/ReWrite File Error - '+IntToStr(LastError)+' (Proc: GetMsgList)'); + Exit; + END; + {$I-} Write(HiWaterF,HiWater); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to write record to '+MemMsgPath+'HI_WATER.MRK.'); + TextColor(LightGray); + LogError(MemMsgPath+'HI_WATER.MRK/Write Record 0 Error - '+IntToStr(LastError)+' (Proc: GetMsgList)'); + Exit; + END; + END + ELSE + BEGIN + {$I-} Read(HiWaterF,HiWater); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to read record from '+MemMsgPath+'HI_WATER.MRK.'); + TextColor(LightGray); + LogError(MemMsgPath+'HI_WATER.MRK/Read Record 0 Error - '+IntToStr(LastError)+' (Proc: GetMsgList)'); + Exit; + END; + FindFirst(MemMsgPath+IntToStr(HiWater)+'.MSG',AnyFile,DirInfo); + IF (DOSError <> 0) THEN + HiWater := 1; + END; + {$I-} Close(HiWaterF); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to close '+MemMsgPath+'HI_WATER.MRK.'); + TextColor(LightGray); + LogError(MemMsgPath+'HI_WATER.MRK/Close File Error - '+IntToStr(LastError)+' (Proc: GetMsgList)'); + Exit; + END; + END; + HighMsg := 1; + LowMsg := 65535; + FindFirst(MemMsgPath+'*.MSG',AnyFile,DirInfo); + WHILE (DOSError = 0) DO + BEGIN + FidoMsgNum := StrToInt(DirInfo.Name); + IF (FidoMsgNum < LowMsg) THEN + LowMsg := FidoMsgNum; + IF (FidoMsgNum > HighMsg) THEN + HighMsg := FidoMsgNum; + FindNext(DirInfo); + END; + IF (HiWater <= HighMsg) THEN + IF (HiWater > 1) THEN + LowMsg := (HiWater + 1); + IF (Ignore_1Msg) THEN + IF (LowMsg = 1) AND (HighMsg > 1) THEN + LowMsg := 2; +END; + +PROCEDURE UpdateHiWater(MemMsgPath: STRING; HighWater: SmallWord); +BEGIN + Assign(HiWaterF,MemMsgPath+'HI_WATER.MRK'); + {$I-} ReWrite(HiWaterF); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to create '+MemMsgPath+'HI_WATER.MRK.'); + TextColor(LightGray); + LogError(MemMsgPath+'HI_WATER.MRK/ReWrite File Error - '+IntToStr(LastError)+' (Proc: UpdateHiWater)'); + Exit; + END; + {$I-} Write(HiWaterF,HighWater); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to write record to '+MemMsgPath+'HI_WATER.MRK.'); + TextColor(LightGray); + LogError(MemMsgPath+'HI_WATER.MRK/Write Record 0 Error - '+IntToStr(LastError)+' (Proc: UpdateHiWater)'); + Exit; + END; + {$I-} Close(HiWaterF); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to close '+MemMsgPath+'HI_WATER.MRK.'); + TextColor(LightGray); + LogError(MemMsgPath+'HI_WATER.MRK/Close File Error - '+IntToStr(LastError)+' (Proc: UpdateHiWater)'); + Exit; + END; +END; + +PROCEDURE PurgeDir(MemMsgPath: STRING); +VAR + TotalMsgsProcessed: Word; + Purged: Boolean; +BEGIN + TotalMsgsProcessed := 0; + IF (FastPurge) THEN + BEGIN + Randomize; + FillChar(FCB,SizeOf(FCB),' '); + FCB[1] := Chr(Ord(StartDir[1]) - 64); + FCB[2] := '*'; + FCB[10] := 'M'; + FCB[11] := 'S'; + FCB[12] := 'G'; + ChDir(Copy(MemMsgPath,1,Length(MemMsgPath) - 1)); + IF (IOResult <> 0) THEN + Exit; + IF (MemMsgPath[2] = ':') THEN + FCB[1] := Chr(Ord(MemMsgPath[1]) - 64) + ELSE + FCB[1] := Chr(Ord(StartDir[1]) - 64); +{$IFDEF MSDOS} + Regs.DS := Seg(FCB); + Regs.DX := Ofs(FCB); + Regs.AX := $1300; + MSDOS(Regs); + Purged := (Lo(Regs.AX) = 0); +{$ENDIF} +{$IFDEF WIN32} + // We ensure FastPurge is false in Win32, so this is never called +{$ENDIF} + END + ELSE + BEGIN + Purged := TRUE; + FindFirst(MemMsgPath+'*.MSG',AnyFile,DirInfo); + IF (DOSError <> 0) THEN + Purged := FALSE + ELSE + BEGIN + WHILE (DOSError = 0) DO + BEGIN + Assign(FidoFile,MemMsgPath+DirInfo.Name); + {$I-} Erase(FidoFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to erase '+MemMsgPath+DirInfo.Name); + TextColor(LightGray); + LogError(MemMsgPath+DirInfo.Name+'/Erase File Error - '+IntToStr(LastError)+ + ' (Proc: PurgeDir)'); + END; + FindNext(DirInfo); + Inc(TotalMsgsProcessed); + END; + END; + END; + IF (NOT Purged) THEN + BEGIN + LogActivity('No Messages!'^M^J); + Write('No messages!') + END + ELSE + BEGIN + IF (FastPurge) THEN + BEGIN + LogActivity('Fast purged!'^M^J); + Write('Fast purged!'); + END + ELSE + BEGIN + LogActivity(IntToStr(TotalMsgsProcessed)+' purged!'^M^J); + Write(IntToStr(TotalMsgsProcessed)+' purged!'); + END; + END; + UpdateHiWater(MemMsgPath,1); +END; + +PROCEDURE UpdateMailWaiting(GenDataPath: STRING; UserNum: Integer); +BEGIN + Assign(UserFile,GenDataPath+'USERS.DAT'); + {$I-} Reset(UserFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to open '+GenDataPath+'USERS.DAT.'); + TextColor(LightGray); + LogError(GenDataPath+'USERS.DAT/Open File Error - '+IntToStr(LastError)+' (Proc: UpdateMailWaiting)'); + Exit; + END; + {$I-} Seek(UserFile,UserNum); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to seek record in '+GenDataPath+'USERS.DAT.'); + TextColor(LightGray); + LogError(GenDataPath+'USERS.DAT/Seek Record '+IntToStr(UserNum)+' Error - '+IntToStr(LastError)+ + ' (Proc: UpdateMailWaiting)'); + Exit; + END; + {$I-} Read(UserFile,User); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to read record from '+GenDataPath+'USERS.DAT.'); + TextColor(LightGray); + LogError(GenDataPath+'USERS.DAT/Read Record '+IntToStr(UserNum)+' Error - '+IntToStr(LastError)+ + ' (Proc: UpdateMailWaiting)'); + Exit; + END; + Inc(User.Waiting); + {$I-} Seek(UserFile,UserNum); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to seek record in '+GenDataPath+'USERS.DAT.'); + TextColor(LightGray); + LogError(GenDataPath+'USERS.DAT/Seek Record '+IntToStr(UserNum)+' Error - '+IntToStr(LastError)+ + ' (Proc: UpdateMailWaiting)'); + Exit; + END; + {$I-} Write(UserFile,User); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to write record to '+GenDataPath+'USERS.DAT.'); + TextColor(LightGray); + LogError(GenDataPath+'USERS.DAT/Write Record '+IntToStr(UserNum)+' Error - '+IntToStr(LastError)+ + ' (Proc: UpdateMailWaiting)'); + Exit; + END; + {$I-} Close(UserFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to close '+GenDataPath+'USERS.DAT.'); + TextColor(LightGray); + LogError(GenDataPath+'USERS.DAT/Close File Error - '+IntToStr(LastError)+' (Proc: UpdateMailWaiting)'); + Exit; + END; +END; + +PROCEDURE InitRGMsgHdrVars(VAR RGMsgHdr: MHeaderRec); +VAR + Counter: Integer; +BEGIN + WITH RGMsgHdr DO + BEGIN + WITH From DO + BEGIN + Anon := 0; + UserNum := 0; + A1S := ''; + Real := ''; + Name := ''; + Zone := 0; + Net := 0; + Node := 0; + Point := 0; + END; + WITH MTO DO + BEGIN + Anon := 0; + UserNum := 0; + A1S := ''; + Real := ''; + Name := ''; + Zone := 0; + Net := 0; + Node := 0; + Point := 0; + END; + Pointer := -1; + TextSize := 0; + ReplyTo := 0; + Date := GetPackDateTime; + GetDayOfWeek(DayOfWeek); + Status := []; + Replies := 0; + Subject := ''; + OriginDate := ''; + FileAttached := 0; + NetAttribute := []; + FOR Counter := 1 TO 2 DO + Res[Counter] := 0; + END; +END; + +FUNCTION ReadFidoMsg(General1: GeneralRecordType; + VAR RGMsgHdr: MHeaderRec; + FidoMsgNum: Word; + MemMsgPath: STRING; + VAR MsgLength: Integer): Boolean; +VAR + FidoTxt: STRING[81]; + BufSize, + Counter: Integer; + MsgRead: Boolean; +BEGIN + MsgRead := FALSE; + + IF (NOT ExistFile(MemMsgPath+IntToStr(FidoMsgNum)+'.MSG')) THEN + BEGIN + ReadFidoMsg := MsgRead; + Exit; + END; + + Assign(FidoFile,MemMsgPath+IntToStr(FidoMsgNum)+'.MSG'); + {$I-} Reset(FidoFile,1); {$I+} + IF (IOResult <> 0) THEN + BEGIN + LogError(MemMsgPath+IntToStr(FidoMsgNum)+'.MSG/Open File Error (Proc: ReadFidoMsg)'); + ErrorStrXY('Unable to open '+MemMsgPath+IntToStr(FidoMsgNum)+'.MSG',12,23,Red + 128,Blue); + END + ELSE + BEGIN + + IF (FileSize(FidoFile) < SizeOf(FidoMsgHdr)) THEN + BEGIN + LogError(MemMsgPath+IntToStr(FidoMsgNum)+'.MSG/Truncated File Error (Proc: ReadFidoMsg)'); + ErrorStrXY('Truncated file '+MemMsgPath+IntToStr(FidoMsgNum)+'.MSG',12,23,Red + 128,Blue); + END + ELSE + BEGIN + {$I-} BlockRead(FidoFile,FidoMsgHdr,SizeOf(FidoMsgHdr)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError(MemMsgPath+IntToStr(FidoMsgNum)+'.MSG/Block Read Header Error - '+IntToStr(LastError)+ + ' (Proc: ReadFidoMsg)'); + ErrorStrXY('Unable to block read header from '+MemMsgPath+IntToStr(FidoMsgNum)+'.MSG',12,23,Red + 128,Blue); + END; + + InitRGMsgHdrVars(RGMsgHdr); + + IF ((FidoMsgHdr.Attribute AND 16) = 16) THEN + RGMsgHdr.FileAttached := 1; + + FidoTxt := FidoMsgHdr.FromUserName[0]; + + FidoTxt := FidoTxt + Copy(FidoMsgHdr.FromUserName,1,((Pos(#0,FidoMsgHdr.FromUserName) - 1))); + + FidoTxt := Caps(FidoTxt); + + RGMsgHdr.From.A1S := FidoTxt; + RGMsgHdr.From.Real := FidoTxt; + RGMsgHdr.From.Name := FidoTxt; + + FidoTxt := FidoMsgHdr.ToUserName[0]; + + FidoTxt := FidoTxt + Copy(FidoMsgHdr.ToUserName,1,((Pos(#0,FidoMsgHdr.ToUserName) - 1))); + + FidoTxt := Caps(FidoTxt); + + RGMsgHdr.MTO.A1S := FidoTxt; + RGMsgHdr.MTO.Real := FidoTxt; + RGMsgHdr.MTO.Name := FidoTxt; + + FidoTxt := FidoMsgHdr.Subject[0]; + + FidoTxt := FidoTxt + Copy(FidoMsgHdr.Subject,1,((Pos(#0,FidoMsgHdr.Subject) - 1))); + + RGMsgHdr.Subject := FidoTxt; + + FidoTxt := FidoMsgHdr.DateTIme[0]; + + FidoTxt := FidoTxt + Copy(FidoMsgHdr.DateTime,1,((Pos(#0,FidoMsgHdr.DateTime) - 1))); + + RGMsgHdr.OriginDate := FidoTxt; + + RGMsgHdr.Status := [Sent]; + + IF (FidoMsgHdr.Attribute AND 1 = 1) THEN + Include(RGMsgHdr.Status,Prvt); + + MsgRead := TRUE; + + IF (IsNetMail) THEN + BEGIN + MsgRead := FALSE; + RGMsgHdr.From.Node := FidoMsgHdr.OrigNode; + RGMsgHdr.From.Net := FidoMsgHdr.OrigNet; + RGMsgHdr.MTO.Node := FidoMsgHdr.DestNode; + RGMsgHdr.MTO.Net := FidoMsgHdr.DestNet; + RGMsgHdr.From.Point := 0; + RGMsgHdr.MTO.Point := 0; + RGMsgHdr.From.Zone := 0; + RGMsgHdr.MTO.Zone := 0; + IF (FidoMsgHdr.Attribute AND 256 = 0) AND (FidoMsgHdr.Attribute AND 4 = 0) THEN + FOR Counter := 0 TO 19 DO + IF (RGMsgHdr.MTO.Node = General1.AKA[Counter].Node) AND (RGMsgHdr.MTO.Net = General1.AKA[Counter].Net) THEN + BEGIN + RGMsgHdr.MTO.Zone := General1.AKA[Counter].Zone; + RGMsgHdr.From.Zone := General1.AKA[Counter].Zone; + MsgRead := TRUE; + END; + IF (NOT MsgRead) THEN + BEGIN +{ LogError(MemMsgPath+IntToStr(FidoMsgNum)+'.MSG/Unknown Zone Error (Proc: ReadFidoMsg)'); + ErrorStrXY('Unknown zone '+MemMsgPath+IntToStr(FidoMsgNum)+'.MSG',12,23,Red + 128,Blue); +} END; + END; + + IF (MsgRead) THEN + BEGIN + + IF (FileSize(FidoFile) - 190) <= SizeOf(BufferArray) THEN + BufSize := (FileSize(FidoFile) - 190) + ELSE + BufSize := SizeOf(BufferArray); + + {$I-} BlockRead(FidoFile,BufferArray,BufSize,MsgLength); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError(MemMsgPath+IntToStr(FidoMsgNum)+'.MSG/Block Read Text Error - '+IntToStr(LastError)+ + ' (Proc: ReadFidoMsg)'); + ErrorStrXY('Unable to block read text from '+MemMsgPath+IntToStr(FidoMsgNum)+'.MSG',12,23,Red + 128,Blue); + MsgRead := FALSE; + END; + END; + END; + IF (IsNetMail) THEN + IF (MsgRead) AND (Purge_NetMail) THEN + BEGIN + {$I-} Close(FidoFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError(MemMsgPath+IntToStr(FidoMsgNum)+'.MSG/Close File Error - '+IntToStr(LastError)+ + ' (Proc: ReadFidoMsg)'); + ErrorStrXY('Unable to close '+MemMsgPath+IntToStr(FidoMsgNum)+'.MSG',12,23,Red + 128,Blue); + END; + {$I-} Erase(FidoFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError(MemMsgPath+IntToStr(FidoMsgNum)+'.MSG/Erase File Error - '+IntToStr(LastError)+ + ' (Proc: ReadFidoMsg)'); + ErrorStrXY('Unable to erase '+MemMsgPath+IntToStr(FidoMsgNum)+'.MSG',12,23,Red + 128,Blue); + END; + END + ELSE IF (MsgRead) THEN + BEGIN + FidoMsgHdr.Attribute := 260; + {$I-} Seek(FidoFile,0); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError(MemMsgPath+IntToStr(FidoMsgNum)+'.MSG/Seek Record 0 Error - '+IntToStr(LastError)+ + ' (Proc: ReadFidoMsg)'); + ErrorStrXY('Unable to seek record in '+MemMsgPath+IntToStr(FidoMsgNum)+'.MSG',12,23,Red + 128,Blue); + END; + {$I-} BlockWrite(FidoFile,FidoMsgHdr,SizeOf(FidoMsgHdr)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError(MemMsgPath+IntToStr(FidoMsgNum)+'.MSG/Block Write Header Error - '+IntToStr(LastError)+ + ' (Proc: ReadFidoMsg)'); + ErrorStrXY('Unable to block write header to '+MemMsgPath+IntToStr(FidoMsgNum)+'.MSG',12,23,Red + 128,Blue); + END; + END; + IF (NOT (IsNetMail AND MsgRead AND Purge_NetMail)) THEN + BEGIN + {$I-} Close(FidoFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError(MemMsgPath+IntToStr(FidoMsgNum)+'.MSG/Close File Error - '+IntToStr(LastError)+ + ' (Proc: ReadFidoMsg)'); + ErrorStrXY('Unable to close '+MemMsgPath+IntToStr(FidoMsgNum)+'.MSG',12,23,Red + 128,Blue); + END; + END; + END; + ReadFidoMsg := MsgRead; +END; + +PROCEDURE Toss(General1: GeneralRecordType; MemMsgArea1: MessageAreaRecordType); +VAR + MsgTxt: STRING[255]; + FidoTxt: STRING[81]; + AddressStr: STRING[20]; + C: Char; + Counter, + Counter1, + MsgPointer, + MsgLength: Integer; + LowMsg, + HighMsg, + FidoMsgNum, + TotalMsgsProcessed: Word; + FirstTime: Boolean; +BEGIN + + FirstTime := TRUE; + + TotalMsgsProcessed := 0; + + GetMsgLst(MemMsgArea1.MsgPath,LowMsg,HighMsg); + + IF (IsNetMail) AND (HighMsg > 1) THEN + LowMsg := 1; + + IF (LowMsg <= HighMsg) AND ((HighMsg > 1) OR (IsNetMail)) THEN + BEGIN + + Assign(RGMsgHdrFile,General1.MsgPath+MemMsgArea1.FileName+'.HDR'); + {$I-} Reset(RGMsgHdrFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + {$I-} ReWrite(RGMsgHdrFile); {$I+} + LastError := IOResult; + IF (IOResult <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to create '+General1.MsgPath+MemMsgArea1.FileName+'.HDR.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.HDR/ReWrite File Error - '+IntToStr(LastError)+' (Proc: Toss)'); + Exit; + END; + END; + + Assign(RGMsgTxtFile,General1.MsgPath+MemMsgArea1.FileName+'.DAT'); + {$I-} Reset(RGMsgTxtFile,1); {$I+} + LastError := IOResult; + IF (IOResult <> 0) THEN + BEGIN + {$I-} ReWrite(RGMsgTxtFile); {$I+} + LastError := IOResult; + IF (IOResult <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to create '+General1.MsgPath+MemMsgArea1.FileName+'.DAT.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.DAT/ReWrite File Error - '+IntToStr(LastError)+' (Proc: Toss)'); + Exit; + END; + END; + + {$I-} Seek(RGMsgHdrFile,FileSize(RGMsgHdrFile)); {$I+} + LastError := IOResult; + IF (IOResult <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to seek record in '+General1.MsgPath+MemMsgArea1.FileName+'.HDR.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.HDR/Seek End Of File Error - '+IntToStr(LastError)+' (Proc: Toss)'); + Exit; + END; + + {$I-} Seek(RGMsgTxtFile,FileSize(RGMsgTxtFile)); {$I+} + LastError := IOResult; + IF (IOResult <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to seek record in '+General1.MsgPath+MemMsgArea1.FileName+'.DAT.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.DAT/Seek End Of File Error - '+IntToStr(LastError)+' (Proc: Toss)'); + Exit; + END; + + FOR FidoMsgNum := LowMsg TO HighMsg DO + BEGIN + + TextColor(LightCyan); + TextBackGround(Blue); + Write(PadRightStr(IntToStr(FidoMsgNum),5)); + + IF ReadFidoMsg(General1,RGMsgHdr,FidoMsgNum,MemMsgArea1.MsgPath,MsgLength) THEN + BEGIN + + IF (FirstTime) THEN + BEGIN + LogActivity(^M^J); + FirstTime := FALSE; + END; + LogActivity(^M^J); + LogActivity('Processing: '+IntToStr(FidoMsgNum)+'.MSG'^M^J); + LogActivity(^M^J); + LogActivity('From : '+RGMsgHdr.From.Name+^M^J); + LogActivity('To : '+RGMsgHdr.MTO.Name+^M^J); + LogActivity('Subject: '+RGMsgHdr.Subject+^M^J); + LogActivity('Date : '+RGMsgHdr.OriginDate+^M^J); + + Inc(RGMsgHdr.Date); + + RGMsgHdr.Pointer := (FileSize(RGMsgTxtFile) + 1); + + RGMsgHdr.TextSize := 0; + + FidoTxt := ''; + + MsgPointer := 0; + WHILE (MsgPointer < MsgLength) DO + BEGIN + + MsgTxt := FidoTxt; + REPEAT + Inc(MsgPointer); + C := BufferArray[MsgPointer]; + IF (NOT (C IN [#0,#10,#13,#141])) THEN + IF (Length(MsgTxt) < 255) THEN + BEGIN + Inc(MsgTxt[0]); + MsgTxt[Length(MsgTxt)] := C; + END; + UNTIL ((FidoTxt = #13) OR (C IN [#13,#141]) OR ((Length(MsgTxt) > 79) AND (Pos(#27,MsgTxt) = 0)) + OR (Length(MsgTxt) = 254) OR (MsgPointer >= MsgLength)); + + IF (Length(MsgTxt) = 254) THEN + MsgTxt := MsgTxt + #29; + + Counter := Pos(#1'INTL ',MsgTxt); + IF (Counter > 0) THEN + BEGIN + Inc(Counter,6); + FOR Counter1 := 1 TO 8 DO + BEGIN + AddressStr := ''; + WHILE (MsgTxt[Counter] IN ['0'..'9']) AND (Counter <= Length(MsgTxt)) DO + BEGIN + AddressStr := AddressStr + MsgTxt[Counter]; + Inc(Counter); + END; + CASE Counter1 OF + 1 : RGMsgHdr.MTO.Zone := StrToInt(AddressStr); + 2 : RGMsgHdr.MTO.Net := StrToInt(AddressStr); + 3 : RGMsgHdr.MTO.Node := StrToInt(AddressStr); + 4 : RGMsgHdr.MTO.Point := StrToInt(AddressStr); + 5 : RGMsgHdr.From.Zone := StrToInt(AddressStr); + 6 : RGMsgHdr.From.Net := StrToInt(AddressStr); + 7 : RGMsgHdr.From.Node := StrToInt(AddressStr); + 8 : RGMsgHdr.From.Point := StrToInt(AddressStr); + END; + IF (Counter1 = 3) AND (MsgTxt[Counter] <> '.') THEN + Inc(Counter1); + IF (Counter1 = 7) AND (MsgTxt[Counter] <> '.') THEN + Break; + Inc(Counter); + END; + LogActivity('INTL : '+IntToStr(RGMsgHdr.MTO.Zone)+ + ':'+IntToStr(RGMsgHdr.MTO.Net)+ + '/'+IntToStr(RGMsgHdr.MTO.Node)+ + ' '+ + ' '+IntToStr(RGMsgHdr.From.Zone)+ + ':'+IntToStr(RGMsgHdr.From.Net)+ + '/'+IntToStr(RGMsgHdr.From.Node)+^M^J); + END; + + IF (Length(MsgTxt) > 79) THEN + BEGIN + Counter := Length(MsgTxt); + WHILE (MsgTxt[Counter] = ' ') AND (Counter > 1) DO + Dec(Counter); + WHILE (Counter > 65) AND (MsgTxt[Counter] <> ' ') DO + Dec(Counter); + FidoTxt[0] := Chr(Length(MsgTxt) - Counter); + Move(MsgTxt[Counter + 1],FidoTxt[1],(Length(MsgTxt) - Counter)); + MsgTxt[0] := Chr(Counter - 1); + END + ELSE + FidoTxt := ''; + + IF ((MsgTxt[1] = #1) AND (MASkludge IN MemMsgArea1.MAFlags)) OR + ((Pos('SEEN-BY',MsgTxt) > 0) AND (MASSeenby IN MemMsgArea1.MAFlags)) OR + ((Pos('* Origin:',MsgTxt) > 0) AND (MASOrigin IN MemMsgArea1.MAFlags)) THEN + MsgTxt := '' + ELSE + BEGIN + Inc(RGMsgHdr.TextSize,(Length(MsgTxt) + 1)); + + {$I-} BlockWrite(RGMsgTxtFile,MsgTxt,(Length(MsgTxt) + 1)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to block write text to '+General1.MsgPath+MemMsgArea1.FileName+'.DAT.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.DAT/Block Write Text Error - '+IntToStr(LastError)+ + ' (Proc: Toss)'); + Exit; + END; + END; + + END; + + IF (IsNetMail) THEN + BEGIN + Include(RGMsgHdr.Status,NetMail); + RGMsgHdr.MTO.UserNum := SearchUser(General1.DataPath,RGMsgHdr.MTO.A1S); + IF (RGMsgHdr.MTO.UserNum = 0) THEN + RGMsgHdr.MTO.UserNum := 1; + UpdateMailWaiting(General1.DataPath,RGMsgHdr.MTO.UserNum); + END; + + {$I-} Write(RGMsgHdrFile,RGMsgHdr); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to write record to '+General1.MsgPath+MemMsgArea1.FileName+'.HDR.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.HDR/Write End Of File Error - '+IntToStr(LastError)+ + ' (Proc: Toss)'); + Exit; + END; + + Inc(TotalMsgsProcessed); + + END; + + IF (FidoMsgNum < HighMsg) THEN + Write(#8#8#8#8#8); + + END; + + {$I-} Close(RGMsgHdrFile); {$I+} + LastError := IOResult; + IF (IOResult <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to close '+General1.MsgPath+MemMsgArea1.FileName+'.HDR.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.HDR/Close File Error - '+IntToStr(LastError)+' (Proc: Toss)'); + Exit; + END; + + {$I-} Close(RGMsgTxtFile); {$I+} + LastError := IOResult; + IF (IOResult <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to close '+General1.MsgPath+MemMsgArea1.FileName+'.DAT.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.DAT/Close File Error - '+IntToStr(LastError)+' (Proc: Toss)'); + Exit; + END; + + IF (NOT IsNetMail) THEN + UpdateHiWater(MemMsgArea1.MsgPath,HighMsg); + + END + ELSE + Write('No messages!'); + + IF (TotalMsgsProcessed = 0) THEN + LogActivity('No Messages!'^M^J) + ELSE + BEGIN + LogActivity(^M^J); + LogActivity('Total processed: '+IntToStr(TotalMsgsProcessed)+^M^J); + LogActivity(^M^J); + END; +END; + +PROCEDURE Scan(General1: GeneralRecordType; MemMsgArea1: MessageAreaRecordType); +VAR + DT: DateTime; + FidoTxt: STRING[81]; + MsgLength: Integer; + LowMsg, + HighMsg, + RGMsgNum, + FidoMsgNum, + HighestWritten, + TotalMsgsProcessed: Word; + Scanned, + FirstTime: Boolean; +BEGIN + + Scanned := FALSE; + + TotalMsgsProcessed := 0; + + FirstTime := TRUE; + + GetMsgLst(MemMsgArea1.MsgPath,LowMsg,HighMsg); + + FidoMsgNum := HighMsg; + + Assign(RGMsgHdrFile,General1.MsgPath+MemMsgArea1.FileName+'.HDR'); + {$I-} Reset(RGMsgHdrFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to open '+General1.MsgPath+MemMsgArea1.FileName+'.HDR.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.HDR/Open File Error - '+IntToStr(LastError)+' (Proc: Scan)'); + Exit; + END; + + Assign(RGMsgTxtFile,General1.MsgPath+MemMsgArea1.FileName+'.DAT'); + {$I-} Reset(RGMsgTxtFile,1); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to open '+General1.MsgPath+MemMsgArea1.FileName+'.DAT.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.DAT/Open File Error - '+IntToStr(LastError)+' (Proc: Scan)'); + Exit; + END; + + FOR RGMsgNum := 1 TO FileSize(RGMsgHdrFile) DO + BEGIN + + {$I-} Seek(RGMsgHdrFile,(RGMsgNum - 1)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to seek record in '+General1.MsgPath+MemMsgArea1.FileName+'.HDR.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.HDR/Seek Record '+IntToStr(RGMsgNum - 1)+' Error - ' + +IntToStr(LastError)+' (Proc: Scan)'); + Exit; + END; + + {$I-} Read(RGMsgHdrFile,RGMsgHdr); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to read record from '+General1.MsgPath+MemMsgArea1.FileName+'.HDR.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.HDR/Read Record '+IntToStr(RGMsgNum - 1)+' Error - ' + +IntToStr(LastError)+' (Proc: Scan)'); + Exit; + END; + + IF (NOT (Sent IN RGMsgHdr.Status)) AND + (NOT (MDeleted IN RGMsgHdr.Status)) AND + (NOT (UnValidated IN RGMsgHdr.Status)) AND + (NOT (IsNetMail AND (NOT (NetMail IN RGMsgHdr.Status)))) THEN + BEGIN + + Inc(FidoMsgNum); + + Assign(FidoFile,MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG'); + {$I-} ReWrite(FidoFile,1); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to create '+MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG.'); + TextColor(LightGray); + LogError(MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG/Rewrite File Error - '+IntToStr(LastError)+' (Proc: Scan)'); + Exit; + END; + + TextColor(LightCyan); + TextBackGround(Blue); + Write(PadRightStr(IntToStr(RGMsgNum),5)); + + Include(RGMsgHdr.Status,Sent); + + IF (IsNetMail) THEN + Include(RGMsgHdr.Status,MDeleted); + + {$I-} Seek(RGMsgHdrFile,(RGMsgNum - 1)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to seek record in '+General1.MsgPath+MemMsgArea1.FileName+'.HDR.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.HDR/Seek Record '+IntToStr(RGMsgNum - 1)+ + ' Error - '+IntToStr(LastError)+' (Proc: Scan)'); + Exit; + END; + + {$I-} Write(RGMsgHdrFile,RGMsgHdr); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to write record to '+General1.MsgPath+MemMsgArea1.FileName+'.HDR.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.HDR/Write Record '+IntToStr(RGMsgNum - 1)+ + ' Error - '+IntToStr(LastError)+' (Proc: Scan)'); + Exit; + END; + + FillChar(FidoMsgHdr,SizeOf(FidoMsgHdr),#0); + + IF (FirstTime) THEN + BEGIN + LogActivity(^M^J); + FirstTime := FALSE; + END; + LogActivity(^M^J); + LogActivity('Processing: '+IntToStr(FidoMsgNum)+'.MSG'^M^J); + LogActivity(^M^J); + + FidoTxt := UseName(RGMsgHdr.From.Anon, + AOnOff((MARealName IN MemMsgArea1.MAFlags), + Caps(RGMsgHdr.From.Real), + Caps(RGMsgHdr.From.A1S))); + Move(FidoTxt[1],FidoMsgHdr.FromUserName[0],Length(FidoTxt)); + + LogActivity('From : '+FidoTxt+^M^J); + + FidoTxt := UseName(RGMsgHdr.MTO.Anon, + AOnOff((MARealName IN MemMsgArea1.MAFlags), + Caps(RGMsgHdr.MTO.Real), + Caps(RGMsgHdr.MTO.A1S))); + Move(FidoTxt[1],FidoMsgHdr.ToUserName[0],Length(FidoTxt)); + + LogActivity('To : '+FidoTxt+^M^J); + + FidoTxt := StripColor(MemMsgArea1.MAFlags,RGMsgHdr.Subject); + IF (NOT IsNetMail) AND (RGMsgHdr.FileAttached > 0) THEN + FidoTxt := StripName(FidoTxt); + Move(FidoTxt[1],FidoMsgHdr.Subject[0],Length(FidoTxt)); + + LogActivity('Subject: '+FidoTxt+^M^J); + + PackToDate(DT,RGMsgHdr.Date); + FidoTxt := ZeroPad(IntToStr(DT.Day))+ + ' '+Copy(MonthString[DT.Month],1,3)+ + ' '+Copy(IntToStr(DT.Year),3,2)+ + ' '+ZeroPad(IntToStr(DT.Hour))+ + ':'+ZeroPad(IntToStr(DT.Min))+ + ':'+ZeroPad(IntToStr(DT.Sec)); + Move(FidoTxt[1],FidoMsgHdr.DateTime[0],Length(FidoTxt)); + + LogActivity('Date : '+FidoTxt+^M^J); + + IF (IsNetMail) THEN + BEGIN + FidoMsgHdr.OrigNet := RGMsgHdr.From.Net; + FidoMsgHdr.OrigNode := RGMsgHdr.From.Node; + FidoMsgHdr.DestNet := RGMsgHdr.MTO.Net; + FidoMsgHdr.DestNode := RGMsgHdr.MTO.Node; + + LogActivity('Origin : '+IntToStr(FidoMsgHdr.OrigNet)+ + '/'+IntToStr(FidoMsgHdr.OrigNode)+^M^J); + + LogActivity('Destin : '+IntToStr(FidoMsgHdr.DestNet)+ + '/'+IntToStr(FidoMsgHdr.DestNode)+^M^J); + END + ELSE + BEGIN + FidoMsgHdr.OrigNet := General1.AKA[MemMsgArea1.AKA].Net; + FidoMsgHdr.OrigNode := General1.AKA[MemMsgArea1.AKA].Node; + FidoMsgHdr.DestNet := 0; + FidoMsgHdr.DestNode := 0; + + LogActivity('Origin : '+IntToStr(General1.AKA[MemMsgArea1.AKA].Net)+ + '/'+IntToStr(General1.AKA[MemMsgArea1.AKA].Node)+^M^J); + + END; + + IF (IsNetMail) THEN +{$IFDEF MSDOS} + FidoMsgHdr.Attribute := Word(RGMsgHdr.NetAttribute) +{$ENDIF} +{$IFDEF WIN32} + FidoMsgHdr.Attribute := NetAttribsToWord(RGMsgHdr.NetAttribute) +{$ENDIF} + ELSE IF (Prvt IN RGMsgHdr.Status) THEN + FidoMsgHdr.Attribute := 257 + ELSE + FidoMsgHdr.Attribute := 256; + + IF (RGMsgHdr.FileAttached > 0) THEN + FidoMsgHdr.Attribute := (FidoMsgHdr.Attribute + 16); + + {$I-} BlockWrite(FidoFile,FidoMsgHdr,SizeOf(FidoMsgHdr)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to block write header '+MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG'); + TextColor(LightGray); + LogError(MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG/Block Write Header Error - '+IntToStr(LastError)+ + ' (Proc: Scan)'); + Exit; + END; + + {$I-} Seek(RGMsgTxtFile,(RGMsgHdr.Pointer - 1)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to seek text in '+MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG'); + TextColor(LightGray); + LogError(MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG/Seek Text Error - '+IntToStr(LastError)+ + ' (Proc: Scan)'); + Exit; + END; + + IF (IsNetMail) THEN + BEGIN + + LogActivity('INTL : '+IntToStr(RGMsgHdr.MTO.Zone)+ + ':'+IntToStr(RGMsgHdr.MTO.Net)+ + '/'+IntToStr(RGMsgHdr.MTO.Node)+ + ' '+ + ' '+IntToStr(RGMsgHdr.From.Zone)+ + ':'+IntToStr(RGMsgHdr.From.Net)+ + '/'+IntToStr(RGMsgHdr.From.Node)+^M^J); + + FidoTxt := #1'INTL '+IntToStr(RGMsgHdr.MTO.Zone)+ + ':'+IntToStr(RGMsgHdr.MTO.Net)+ + '/'+IntToStr(RGMsgHdr.MTO.Node)+ + ' '+IntToStr(RGMsgHdr.From.Zone)+ + ':'+IntToStr(RGMsgHdr.From.Net)+ + '/'+IntToStr(RGMsgHdr.From.Node)+#13; + + {$I-} BlockWrite(FidoFile,FidoTxt[1],Length(FidoTxt)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to block write text to '+MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG'); + TextColor(LightGray); + LogError(MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG/Block Write Text Error - '+IntToStr(LastError)+ + ' (Proc: Scan)'); + Exit; + END; + + IF (RGMsgHdr.MTO.Point > 0) THEN + BEGIN + LogActivity('TOPT : '+IntToStr(RGMsgHdr.MTO.Point)+^M^J); + + FidoTxt := #1'TOPT '+IntToStr(RGMsgHdr.MTO.Point)+#13; + + {$I-} BlockWrite(FidoFile,FidoTxt[1],Length(FidoTxt)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to block write text to '+MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG'); + TextColor(LightGray); + LogError(MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG/Block Write Text Error - '+IntToStr(LastError)+ + ' (Proc: Scan)'); + Exit; + END; + + END; + + IF (RGMsgHdr.From.Point > 0) THEN + BEGIN + LogActivity('FMPT : '+IntToStr(RGMsgHdr.From.Point)+^M^J); + + FidoTxt := #1'FMPT '+IntToStr(RGMsgHdr.From.Point)+#13; + + {$I-} BlockWrite(FidoFile,FidoTxt[1],Length(FidoTxt)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to block write text to '+MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG'); + TextColor(LightGray); + LogError(MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG/Block Write Text Error - '+IntToStr(LastError)+ + ' (Proc: Scan)'); + Exit; + END; + + END; + + FidoTxt := #1'MSGID: '+IntToStr(RGMsgHdr.From.Zone)+ + ':'+IntToStr(RGMsgHdr.From.Net)+ + '/'+IntToStr(RGMsgHdr.From.Node)+ + ' '+Hex(Random($FFFF),4)+Hex(Random($FFFF),4); + IF (RGMsgHdr.From.Point > 0) THEN + FidoTxt := FidoTxt +'.'+IntToStr(RGMsgHdr.From.Point); + + FidoTxt := FidoTxt + #13; + + {$I-} BlockWrite(FidoFile,FidoTxt[1],Length(FidoTxt)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to block write text to '+MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG'); + TextColor(LightGray); + LogError(MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG/Block Write Text Error - '+IntToStr(LastError)+ + ' (Proc: Scan)'); + Exit; + END; + + END; + + MsgLength := 0; + + IF (RGMsgHdr.TextSize > 0) THEN + REPEAT + + {$I-} BlockRead(RGMsgTxtFile,FidoTxt[0],1); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to block read text from '+MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG'); + TextColor(LightGray); + LogError(MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG/Block Read Text Error - '+IntToStr(LastError)+ + ' (Proc: Scan)'); + Exit; + END; + + {$I-} BlockRead(RGMsgTxtFile,FidoTxt[1],Ord(FidoTxt[0])); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to block read text from '+MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG'); + TextColor(LightGray); + LogError(MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG/Block Read Text Error - '+IntToStr(LastError)+ + ' (Proc: Scan)'); + Exit; + END; + + Inc(MsgLength,(Length(FidoTxt) + 1)); + + WHILE (Pos(#0,FidoTxt) > 0) DO + Delete(FidoTxt,Pos(#0,FidoTxt),1); + + IF (FidoTxt[Length(FidoTxt)] = #29) THEN + Dec(FidoTxt[0]) + + (* NOTE: Should this be (Pos(#27,FidoTxt) <> 0) *) + + ELSE IF (Pos(#27,FidoTxt) = 0) THEN + FidoTxt := StripColor(MemMsgArea1.MAFlags,FidoTxt); + + FidoTxt := FidoTxt + #13; + + {$I-} BlockWrite(FidoFile,FidoTxt[1],Length(FidoTxt)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to block write text to '+MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG'); + TextColor(LightGray); + LogError(MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG/Block Write Text Error - '+IntToStr(LastError)+ + ' (Proc: Scan)'); + Exit; + END; + + UNTIL (MsgLength >= RGMsgHdr.TextSize); + + {$I-} Close(FidoFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to close '+MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG.'); + TextColor(LightGray); + LogError(MemMsgArea1.MsgPath+IntToStr(FidoMsgNum)+'.MSG/Close File Error - '+IntToStr(LastError)+' (Proc: Scan)'); + Exit; + END; + + Write(#8#8#8#8#8); + + Scanned := TRUE; + + Inc(TotalMsgsProcessed); + END; + + HighestWritten := FidoMsgNum; + + END; + + IF (NOT IsNetMail) THEN + UpdateHiWater(MemMsgArea1.MsgPath,HighestWritten); + + {$I-} Close(RGMsgHdrFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to close '+General1.MsgPath+MemMsgArea1.FileName+'.HDR.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.HDR/Close File Error - '+IntToStr(LastError)+' (Proc: Scan)'); + Exit; + END; + + {$I-} Close(RGMsgTxtFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to close '+General1.MsgPath+MemMsgArea1.FileName+'.DAT.'); + TextColor(LightGray); + LogError(General1.MsgPath+MemMsgArea1.FileName+'.DAT/Close File Error - '+IntToStr(LastError)+' (Proc: Scan)'); + Exit; + END; + + IF (NOT Scanned) THEN + BEGIN + LogActivity('No Messages!'^M^J); + Write('No messages!'); + END + ELSE + BEGIN + LogActivity(^M^J); + LogActivity('Total processed: '+IntToStr(TotalMsgsProcessed)+^M^J); + LogActivity(^M^J); + END; + +END; + +BEGIN + DisplayMain(White,Blue); + + IF (ParamCount = 0) THEN + HaltErrorStrXY('No command line parameters specified!',12,23,Red + 128,Blue,1); + + TempParamStr := ''; + ParamFound := FALSE; + ParamCounter := 1; + WHILE (ParamCounter <= ParamCount) DO + BEGIN + IF (SC(ParamStr(ParamCounter),1) = '-') THEN + BEGIN + CASE SC(ParamStr(ParamCounter),2) OF + 'A' : Absolute_Scan := TRUE; + 'D' : Purge_NetMail := FALSE; + 'F' : FastPurge := FALSE; + 'I' : Ignore_1Msg := FALSE; + 'L' : Activity_Log := TRUE; + 'N' : Process_NetMail := FALSE; + 'O' : NetMailOnly := TRUE; + 'P' : BEGIN + Purge_Dir := TRUE; + ParamFound := TRUE; + END; + 'S' : BEGIN + Scan_Mail := TRUE; + ParamFound := TRUE; + END; + 'T' : BEGIN + Toss_Mail := TRUE; + ParamFound := TRUE; + END; + END; + TempParamStr := TempParamStr + AllCaps(ParamStr(ParamCounter))+' '; + END; + Inc(ParamCounter); + END; + + Dec(TempParamStr[0]); + + IF (NOT ParamFound) THEN + HaltErrorStrXY('Valid commands are -T, -P, -S, (With or without options)',12,23,Red + 128,Blue,1); + + GetDir(0,StartDir); + + FileMode := 66; +{$IFDEF WIN32} + FileModeReadWrite := FileMode; +{$ENDIF} + + GetGeneral(General); + + GeneralPaths(General); + + GeneralFiles(General); + + LogActivity(^M^J); + LogActivity(ToDate8(DateStr)+' '+TimeStr+': Renemail initiated with '+TempParamStr+' parameter(s).'^M^J); + LogActivity(^M^J); + + IF (Process_NetMail) AND (Toss_Mail) OR (Scan_Mail) THEN + BEGIN + IsNetMail := TRUE; + MemMsgArea.MsgPath := General.NetMailPath; + MemMsgArea.FileName := 'EMAIL'; + MemMsgArea.MAFlags := [MASkludge]; + IF (Toss_Mail) THEN + BEGIN + LogActivity(' Tossing: NETMAIL - '); + TextColor(3); + Write(' Tossing: '); + TextColor(14); + Write(' NETMAIL - '); + Toss(General,MemMsgArea); + WriteLn; + END; + IF (Scan_Mail) THEN + BEGIN + LogActivity('Scanning: NETMAIL - '); + TextColor(3); + Write('Scanning: '); + TextColor(14); + Write(' NETMAIL - '); + TextColor(11); + Scan(General,MemMsgArea); + WriteLn; + END; + IsNetMail := FALSE; + END; + + IF (NOT NetMailOnly) THEN + BEGIN + IF (Toss_Mail) OR (Purge_Dir) OR (Scan_Mail) THEN + BEGIN + Assign(MessageAreaFile,General.DataPath+'MBASES.DAT'); + {$I-} Reset(MessageAreaFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + LogError(General.DataPath+'MBASES.DAT/Open File Error - '+IntToStr(LastError)+' (Proc: Main)'); + HaltErrorStrXY('Unable to open '+General.DataPath+'MBASES.DAT!',12,23,Red + 128,Blue,1); + END; + MsgArea := 1; + WHILE (MsgArea <= FileSize(MessageAreaFile)) DO + BEGIN + {$I-} Seek(MessageAreaFile,(MsgArea - 1)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to seek record in '+General.DataPath+'MBASES.DAT'); + TextColor(LightGray); + LogError(General.DataPath+'MBASES.DAT/Seek Record '+IntToStr(MsgArea - 1)+' Error - '+IntToStr(LastError)+ + ' (Proc: Main)'); + Exit; + END; + {$I-} Read(MessageAreaFile,MemMsgArea); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to read record from '+General.DataPath+'MBASES.DAT'); + TextColor(LightGray); + LogError(General.DataPath+'MBASES.DAT/Read Record '+IntToStr(MsgArea - 1)+' Error - '+IntToStr(LastError)+ + ' (Proc: Main)'); + Exit; + END; + IF (MemMsgArea.MAType = 1) AND (NOT Scan_Mail OR (Absolute_Scan OR (MAScanOut IN MemMsgArea.MAFlags))) THEN + BEGIN + IF (Toss_Mail) THEN + BEGIN + LogActivity(' Tossing: '+PadRightStr(MemMsgArea.FileName,8)+' - '); + TextColor(3); + Write(' Tossing: '); + TextColor(14); + Write(PadRightStr(MemMsgArea.FileName,8)+' - '); + TextColor(11); + Toss(General,MemMsgArea); + WriteLn; + END; + IF (Purge_Dir) THEN + BEGIN + LogActivity(' Purging: '+PadRightStr(MemMsgArea.FileName,8)+' - '); + TextColor(3); + Write(' Purging: '); + TextColor(14); + Write(PadRightStr(MemMsgArea.FileName,8)+' - '); + TextColor(11); + PurgeDir(MemMsgArea.MsgPath); + WriteLn; + END; + IF (Scan_Mail) THEN + BEGIN + LogActivity('Scanning: '+PadRightStr(MemMsgArea.FileName,8)+' - '); + TextColor(3); + Write('Scanning: '); + TextColor(14); + Write(PadRightStr(MemMsgArea.FileName,8)+' - '); + TextColor(11); + Scan(General,MemMsgArea); + WriteLn; + END; + IF (Scan_Mail) AND (MAScanOut IN MemMsgArea.MAFlags) THEN + BEGIN + {$I-} Seek(MessageAreaFile,(MsgArea - 1)); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to seek record in '+General.DataPath+'MBASES.DAT'); + TextColor(LightGray); + LogError(General.DataPath+'MBASES.DAT/Seek Record '+IntToStr(MsgArea - 1)+' Error - '+IntToStr(LastError)+ + ' (Proc: Main)'); + Exit; + END; + Exclude(MemMsgArea.MAFlags,MAScanOut); + {$I-} Write(MessageAreaFile,MemMsgArea); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to write record to '+General.DataPath+'MBASES.DAT'); + TextColor(LightGray); + LogError(General.DataPath+'MBASES.DAT/Write Record '+IntToStr(MsgArea - 1)+' Error - '+IntToStr(LastError)+ + ' (Proc: Main)'); + Exit; + END; + END; + END; + Inc(MsgArea); + END; + {$I-} Close(MessageAreaFile); {$I+} + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + TextColor(Red); + WriteLn('Unable to close '+General.DataPath+'MBASES.DAT'); + TextColor(LightGray); + LogError(General.DataPath+'MBASES.DAT/Close File Error - '+IntToStr(LastError)+' (Proc: Main)'); + Exit; + END; + END; + END; + + LogActivity(^M^J); + LogActivity(ToDate8(DateStr)+' '+TimeStr+': Renemail completed with '+TempParamStr+' parameter(s).'^M^J); + + ChDir(StartDir); + + Window(1,1,80,25); + + GoToXY(1,25); + +END. + + diff --git a/SOURCE/RGLNG.PAS b/SOURCE/RGLNG.PAS new file mode 100644 index 0000000..7145258 --- /dev/null +++ b/SOURCE/RGLNG.PAS @@ -0,0 +1,927 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +PROGRAM RGLNG; + +USES + Crt, + Dos; + +TYPE + StrPointerRec = RECORD + Pointer, + TextSize: LongInt; + END; + +VAR + RGStrFile: FILE; + StrPointerFile: FILE OF StrPointerRec; + StrPointer: StrPointerRec; + F: Text; + S: STRING; + RGStrNum: LongInt; + Done, + Found: Boolean; + +FUNCTION AllCaps(S: STRING): STRING; +VAR + I: Integer; +BEGIN + FOR I := 1 TO Length(S) DO + IF (S[I] IN ['a'..'z']) THEN + S[I] := Chr(Ord(S[I]) - Ord('a')+Ord('A')); + AllCaps := S; +END; + +FUNCTION SQOutSp(S: STRING): STRING; +BEGIN + WHILE (Pos(' ',S) > 0) DO + Delete(s,Pos(' ',S),1); + SQOutSp := S; +END; + +FUNCTION Exist(FN: STRING): Boolean; +VAR + DirInfo: SearchRec; +BEGIN + FindFirst(SQOutSp(FN),AnyFile,DirInfo); + Exist := (DOSError = 0); +END; + +PROCEDURE CompileLanguageStrings; +BEGIN + WriteLn; + Write('Compiling language strings ... '); + Found := TRUE; + Assign(StrPointerFile,'RGLNGPR.DAT'); + ReWrite(StrPointerFile); + Assign(RGStrFile,'RGLNGTX.DAT'); + ReWrite(RGStrFile,1); + Assign(F,'RGLNG.TXT'); + Reset(F); + WHILE NOT EOF(F) AND (Found) DO + BEGIN + ReadLn(F,S); + IF (S <> '') AND (S[1] = '$') THEN + BEGIN + Delete(S,1,1); + S := AllCaps(S); + RGStrNum := -1; + IF (S = 'ANONYMOUS_STRING') THEN + RGStrNum := 0 + ELSE IF (S = 'ECHO_CHAR_FOR_PASSWORDS') THEN + RGStrNum := 1 + ELSE IF (S = 'ENGAGE_CHAT') THEN + RGStrNum := 2 + ELSE IF (S = 'END_CHAT') THEN + RGStrNum := 3 + ELSE IF (S = 'SYSOP_WORKING') THEN + RGStrNum := 4 + ELSE IF (S = 'PAUSE') THEN + RGStrNum := 5 + ELSE IF (S = 'ENTER_MESSAGE_LINE_ONE') THEN + RGStrNum := 6 + ELSE IF (S = 'ENTER_MESSAGE_LINE_TWO') THEN + RGStrNum := 7 + ELSE IF (S = 'NEWSCAN_BEGIN') THEN + RGStrNum := 8 + ELSE IF (S = 'NEWSCAN_DONE') THEN + RGStrNum := 9 + ELSE IF (S = 'AUTO_MESSAGE_TITLE') THEN + RGStrNum := 10 + ELSE IF (S = 'AUTO_MESSAGE_BORDER_CHARACTERS') THEN + RGStrNum := 11 + ELSE IF (S = 'SYSOP_SHELLING_TO_DOS') THEN + RGStrNum := 12 + ELSE IF (S = 'READ_MAIL') THEN + RGStrNum := 13 + ELSE IF (S = 'PAGING_SYSOP') THEN + RGStrNum := 14 + ELSE IF (S = 'CHAT_CALL') THEN + RGStrNum := 15 + ELSE IF (S = 'BULLETIN_PROMPT') THEN + RGstrNum := 16 + ELSE IF (S = 'PROTOCOL_PROMPT') THEN + RGStrNum := 17 + ELSE IF (S = 'LIST_FILES') THEN + RGStrNum := 18 + ELSE IF (S = 'SEARCH_FOR_NEW_FILES') THEN + RGStrNum := 19 + ELSE IF (S = 'SEARCH_ALL_DIRS_FOR_FILE_MASK') THEN + RGStrNum := 20 + ELSE IF (S = 'SEARCH_FOR_DESCRIPTIONS') THEN + RGStrNum := 21 + ELSE IF (S = 'ENTER_THE_STRING_TO_SEARCH_FOR') THEN + RGStrNum := 22 + ELSE IF (S = 'DOWNLOAD') THEN + RGStrNum := 23 + ELSE IF (S = 'UPLOAD') THEN + RGStrNum := 24 + ELSE IF (S = 'VIEW_INTERIOR_FILES') THEN + RGStrNum := 25 + ELSE IF (S = 'INSUFFICIENT_FILE_CREDITS') THEN + RGStrNum := 26 + ELSE IF (S = 'RATIO_IS_UNBALANCED') THEN + RGStrNum := 27 + ELSE IF (S = 'ALL_FILES') THEN + RGStrNum := 28 + ELSE IF (S = 'FILE_MASK') THEN + RGStrNum := 29 + ELSE IF (S = 'FILE_ADDED_TO_BATCH_QUEUE') THEN + RGStrNum := 30 + ELSE IF (S = 'BATCH_DOWNLOAD_FLAGGING') THEN + RGStrNum := 31 + ELSE IF (S = 'READ_QUESTION_PROMPT') THEN + RGStrNum := 32 + ELSE IF (S = 'SYSTEM_PASSWORD_PROMPT') THEN + RGStrNum := 33 + ELSE IF (S = 'DEFAULT_MESSAGE_TO') THEN + RGStrNum := 34 + ELSE IF (S = 'NEWSCAN_ALL') THEN + RGStrNum := 35 + ELSE IF (S = 'NEWSCAN_DONE') THEN + RGStrNum := 36 + ELSE IF (S = 'CHAT_REASON') THEN + RGStrNum := 37 + ELSE IF (S = 'USER_DEFINED_QUESTION_ONE') THEN + RGStrNum := 38 + ELSE IF (S = 'USER_DEFINED_QUESTION_TWO') THEN + RGStrNum := 39 + ELSE IF (S = 'USER_DEFINED_QUESTION_THREE') THEN + RGStrNum := 40 + ELSE IF (S = 'USER_DEFINED_QUESTION_EDITOR_ONE') THEN + RGStrNum := 41 + ELSE IF (S = 'USER_DEFINED_QUESTION_EDITOR_TWO') THEN + RGStrNum := 42 + ELSE IF (S = 'USER_DEFINED_QUESTION_EDITOR_THREE') THEN + RGStrNum := 43 + ELSE IF (S = 'CONTINUE_PROMPT') THEN + RGStrNum := 44 + ELSE IF (S = 'INVISIBLE_LOGIN') THEN + RGStrNum := 45 + ELSE IF (S = 'CANT_EMAIL') THEN + RGStrNum := 46 + ELSE IF (S = 'SEND_EMAIL') THEN + RGStrNum := 47 + ELSE IF (S = 'SENDING_MASS_MAIL_TO') THEN + RGStrNum := 48 + ELSE IF (S = 'SENDING_MASS_MAIL_TO_ALL_USERS') THEN + RGStrNum := 49 + ELSE IF (S = 'NO_NETMAIL') THEN + RGStrNum := 50 + ELSE IF (S = 'NETMAIL_PROMPT') THEN + RGStrNum := 51 + ELSE IF (S = 'NO_MAIL_WAITING') THEN + RGStrNum := 52 + ELSE IF (S = 'MUST_READ_MESSAGE') THEN + RGStrNum := 53 + ELSE IF (S = 'SCAN_FOR_NEW_FILES') THEN + RGStrNum := 54 + ELSE IF (S = 'NEW_SCAN_CHAR_FILE') THEN + RGStrNum := 55 + ELSE IF (S = 'BULLETINS_PROMPT') THEN + RGStrNum := 56 + ELSE IF (S = 'QUICK_LOGON') THEN + RGStrNum := 57 + ELSE IF (S = 'MESSAGE_AREA_SELECT_HEADER') THEN + RGStrNum := 58 + ELSE IF (S = 'FILE_AREA_SELECT_HEADER') THEN + RGStrNum := 59 + ELSE IF (S = 'RECEIVE_EMAIL_HEADER') THEN + RGStrNum := 60 + ELSE IF (S = 'VOTE_LIST_TOPICS_HEADER') THEN + RGStrNum := 61 + ELSE IF (S = 'VOTE_TOPIC_RESULT_HEADER') THEN + RGStrNum := 62 + ELSE IF (S = 'FILE_AREA_NAME_HEADER_NO_RATIO') THEN + RGStrNum := 63 + ELSE IF (S = 'FILE_AREA_NAME_HEADER_RATIO') THEN + RGStrNum := 64 + ELSE IF (S = 'SYSOP_CHAT_HELP') THEN + RGStrNum := 65 + ELSE IF (S = 'NEW_SCAN_CHAR_MESSAGE') THEN + RGStrNum := 66 + ELSE IF (S = 'FILE_AREA_SELECT_NO_FILES') THEN + RGStrNum := 67 + ELSE IF (S = 'MESSAGE_AREA_SELECT_NO_FILES') THEN + RGStrNum := 68 + ELSE IF (S = 'MESSAGE_AREA_LIST_PROMPT') THEN + RGStrNum := 69 + ELSE IF (S = 'FILE_AREA_LIST_PROMPT') THEN + RGStrNum := 70 + ELSE IF (S = 'FILE_MESSAGE_AREA_LIST_HELP') THEN + RGStrNum := 71 + ELSE IF (S = 'FILE_AREA_CHANGE_PROMPT') THEN + RGStrNum := 72 + ELSE IF (S = 'MESSAGE_AREA_CHANGE_PROMPT') THEN + RGStrNum := 73 + ELSE IF (S = 'FILE_AREA_NEW_SCAN_TOGGLE_PROMPT') THEN + RGStrNum := 74 + ELSE IF (S = 'MESSAGE_AREA_NEW_SCAN_TOGGLE_PROMPT') THEN + RGStrNum := 75 + ELSE IF (S = 'FILE_AREA_MOVE_FILE_PROMPT') THEN + RGStrNum := 76 + ELSE IF (S = 'MESSAGE_AREA_MOVE_MESSAGE_PROMPT') THEN + RGStrNum := 77 + ELSE IF (S = 'FILE_AREA_CHANGE_MIN_MAX_ERROR') THEN + RGStrNum := 78 + ELSE IF (S = 'MESSAGE_AREA_CHANGE_MIN_MAX_ERROR') THEN + RGStrNum := 79 + ELSE IF (S = 'FILE_AREA_CHANGE_NO_AREA_ACCESS') THEN + RGStrNum := 80 + ELSE IF (S = 'MESSAGE_AREA_CHANGE_NO_AREA_ACCESS') THEN + RGStrNum := 81 + ELSE IF (S = 'FILE_AREA_CHANGE_LOWEST_AREA') THEN + RGStrNum := 82 + ELSE IF (S = 'FILE_AREA_CHANGE_HIGHEST_AREA') THEN + RGStrNum := 83 + ELSE IF (S = 'MESSAGE_AREA_CHANGE_LOWEST_AREA') THEN + RGStrNum := 84 + ELSE IF (S = 'MESSAGE_AREA_CHANGE_HIGHEST_AREA') THEN + RGStrNum := 85 + ELSE IF (S = 'FILE_AREA_NEW_SCAN_SCANNING_ALL_AREAS') THEN + RGStrNum := 86 + ELSE IF (S = 'MESSAGE_AREA_NEW_SCAN_SCANNING_ALL_AREAS') THEN + RGStrNum := 87 + ELSE IF (S = 'FILE_AREA_NEW_SCAN_NOT_SCANNING_ALL_AREAS') THEN + RGStrNum := 88 + ELSE IF (S = 'MESSAGE_AREA_NEW_SCAN_NOT_SCANNING_ALL_AREAS') THEN + RGStrNum := 89 + ELSE IF (S = 'FILE_AREA_NEW_SCAN_MIN_MAX_ERROR') THEN + RGStrNum := 90 + ELSE IF (S = 'MESSAGE_AREA_NEW_SCAN_MIN_MAX_ERROR') THEN + RGStrNum := 91 + ELSE IF (S = 'FILE_AREA_NEW_SCAN_AREA_ON_OFF') THEN + RGStrNum := 92 + ELSE IF (S = 'MESSAGE_AREA_NEW_SCAN_AREA_ON_OFF') THEN + RGStrNum := 93 + ELSE IF (S = 'MESSAGE_AREA_NEW_SCAN_AREA_NOT_REMOVED') THEN + RGStrNum := 94; + + IF (RGStrNum = -1) THEN + BEGIN + WriteLn('Error!'); + WriteLn; + WriteLn(^G^G^G'The following string definition is invalid:'); + WriteLn; + WriteLn(' '+S); + Found := FALSE; + END + ELSE + BEGIN + Done := FALSE; + WITH StrPointer DO + BEGIN + Pointer := (FileSize(RGStrFile) + 1); + TextSize := 0; + END; + Seek(RGStrFile,FileSize(RGStrFile)); + WHILE NOT EOF(F) AND (NOT Done) DO + BEGIN + ReadLn(F,S); + IF (S[1] = '$') THEN + Done := TRUE + ELSE + BEGIN + Inc(StrPointer.TextSize,(Length(S) + 1)); + BlockWrite(RGStrFile,S,(Length(S) + 1)); + END; + END; + Seek(StrPointerFile,RGStrNum); + Write(StrPointerFile,StrPointer); + END; + END; + END; + Close(F); + Close(RGStrFile); + Close(StrPointerFile); + IF (Found) THEN + WriteLn('Done!') + ELSE + BEGIN + Erase(StrPointerFile); + Erase(RGStrFile); + END; +END; + +PROCEDURE CompileMainStrings; +BEGIN + WriteLn; + Write('Compiling main strings ... '); + Found := TRUE; + Assign(StrPointerFile,'RGMAINPR.DAT'); + ReWrite(StrPointerFile); + Assign(RGStrFile,'RGMAINTX.DAT'); + ReWrite(RGStrFile,1); + Assign(F,'RGMAIN.TXT'); + Reset(F); + WHILE NOT EOF(F) AND (Found) DO + BEGIN + ReadLn(F,S); + IF (S <> '') AND (S[1] = '$') THEN + BEGIN + Delete(S,1,1); + S := AllCaps(S); + RGStrNum := -1; + IF (S = 'BAUD_OVERRIDE_PW') THEN + RGStrNum := 0 + ELSE IF (S = 'CALLER_LOGON') THEN + RGStrNum := 1 + ELSE IF (S = 'LOGON_AS_NEW') THEN + RGStrNum := 2 + ELSE IF (S = 'USER_LOGON_PASSWORD') THEN + RGStrNum := 3 + ELSE IF (S = 'USER_LOGON_PHONE_NUMBER') THEN + RGStrNum := 4 + ELSE IF (S = 'SYSOP_LOGON_PASSWORD') THEN + RGStrNum := 5 + ELSE IF (S = 'FORGOT_PW_QUESTION') THEN + RGStrNum := 6 + ELSE IF (S = 'VERIFY_BIRTH_DATE') THEN + RGStrNum := 7 + ELSE IF (S = 'LOGON_WITHDRAW_BANK') THEN + RGStrNum := 8 + ELSE IF (S = 'SHUTTLE_LOGON') THEN + RGStrNum := 9 + ELSE IF (S = 'NEW_USER_PASSWORD') THEN + RGStrNum := 10; + IF (RGStrNum = -1) THEN + BEGIN + WriteLn('Error!'); + WriteLn; + WriteLn(^G^G^G'The following string definition is invalid:'); + WriteLn; + WriteLn(' '+S); + Found := FALSE; + END + ELSE + BEGIN + Done := FALSE; + WITH StrPointer DO + BEGIN + Pointer := (FileSize(RGStrFile) + 1); + TextSize := 0; + END; + Seek(RGStrFile,FileSize(RGStrFile)); + WHILE NOT EOF(F) AND (NOT Done) DO + BEGIN + ReadLn(F,S); + IF (S[1] = '$') THEN + Done := TRUE + ELSE + BEGIN + Inc(StrPointer.TextSize,(Length(S) + 1)); + BlockWrite(RGStrFile,S,(Length(S) + 1)); + END; + END; + Seek(StrPointerFile,RGStrNum); + Write(StrPointerFile,StrPointer); + END; + END; + END; + Close(F); + Close(RGStrFile); + Close(StrPointerFile); + IF (Found) THEN + WriteLn('Done!') + ELSE + BEGIN + Erase(StrPointerFile); + Erase(RGStrFile); + END; +END; + +PROCEDURE CompileNoteStrings; +BEGIN + WriteLn; + Write('Compiling Note strings ... '); + Found := TRUE; + Assign(StrPointerFile,'RGNOTEPR.DAT'); + ReWrite(StrPointerFile); + Assign(RGStrFile,'RGNOTETX.DAT'); + ReWrite(RGStrFile,1); + Assign(F,'RGNOTE.TXT'); + Reset(F); + WHILE NOT EOF(F) AND (Found) DO + BEGIN + ReadLn(F,S); + IF (S <> '') AND (S[1] = '$') THEN + BEGIN + Delete(S,1,1); + S := AllCaps(S); + RGStrNum := -1; + IF (S = 'INTERNAL_USE_ONLY') THEN + RGStrNum := 0 + ELSE IF (S = 'ONLY_CHANGE_LOCALLY') THEN + RGStrNum := 1 + ELSE IF (S = 'INVALID_MENU_NUMBER') THEN + RGStrNum := 2 + ELSE IF (S = 'MINIMUM_BAUD_LOGON_PW') THEN + RGStrNum := 3 + ELSE IF (S = 'MINIMUM_BAUD_LOGON_HIGH_LOW_TIME_PW') THEN + RGStrNum := 4 + ELSE IF (S = 'MINIMUM_BAUD_LOGON_HIGH_LOW_TIME_NO_PW') THEN + RGStrNum := 5 + ELSE IF (S = 'LOGON_EVENT_RESTRICTED_1') THEN + RGStrNum := 6 + ELSE IF (S = 'LOGON_EVENT_RESTRICTED_2') THEN + RGStrNum := 7 + ELSE IF (S = 'NAME_NOT_FOUND') THEN + RGStrNum := 8 + ELSE IF (S = 'ILLEGAL_LOGON') THEN + RGStrNum := 9 + ELSE IF (S = 'LOGON_NODE_ACS') THEN + RGStrNum := 10 + ELSE IF (S = 'LOCKED_OUT') THEN + RGStrNum := 11 + ELSE IF (S = 'LOGGED_ON_ANOTHER_NODE') THEN + RGStrNum := 12 + ELSE IF (S = 'INCORRECT_BIRTH_DATE') THEN + RGStrNum := 13 + ELSE IF (S = 'INSUFFICIENT_LOGON_CREDITS') THEN + RGStrNum := 14 + ELSE IF (S = 'LOGON_ONCE_PER_DAY') THEN + RGStrNum := 15 + ELSE IF (S = 'LOGON_CALLS_ALLOWED_PER_DAY') THEN + RGStrNum := 16 + ELSE IF (S = 'LOGON_TIME_ALLOWED_PER_DAY_OR_CALL') THEN + RGStrNum := 17 + ELSE IF (S = 'LOGON_MINUTES_LEFT_IN_BANK') THEN + RGStrNum := 18 + ELSE IF (S = 'LOGON_MINUTES_LEFT_IN_BANK_TIME_LEFT') THEN + RGStrNum := 19 + ELSE IF (S = 'LOGON_BANK_HANGUP') THEN + RGStrNum := 20 + ELSE IF (S = 'LOGON_ATTEMPT_IEMSI_NEGOTIATION') THEN + RGStrNum := 21 + ELSE IF (S = 'LOGON_IEMSI_NEGOTIATION_SUCCESS') THEN + RGStrNum := 22 + ELSE IF (S = 'LOGON_IEMSI_NEGOTIATION_FAILED') THEN + RGStrNum := 23 + ELSE IF (S = 'LOGON_ATTEMPT_DETECT_EMULATION') THEN + RGStrNum := 24 + ELSE IF (S = 'LOGON_RIP_DETECTED') THEN + RGStrNum := 25 + ELSE IF (S = 'LOGON_ANSI_DETECT_OTHER') THEN + RGStrNum := 26 + ELSE IF (S = 'LOGON_ANSI_DETECT') THEN + RGStrNum := 27 + ELSE IF (S = 'LOGON_AVATAR_DETECT_OTHER') THEN + RGStrNum := 28 + ELSE IF (S = 'LOGON_AVATAR_DETECT') THEN + RGStrNum := 29 + ELSE IF (S = 'LOGON_EMULATION_DETECTED') THEN + RGStrNum := 30 + ELSE IF (S = 'SHUTTLE_LOGON_VALIDATION_STATUS') THEN + RGStrNum := 31 + ELSE IF (S = 'LOGON_CLOSED_BBS') THEN + RGStrNum := 32 + ELSE IF (S = 'NODE_ACTIVITY_WAITING_ONE') THEN + RGStrNum := 33 + ELSE IF (S = 'NODE_ACTIVITY_WAITING_TWO') THEN + RGStrNum := 34 + ELSE IF (S = 'NODE_ACTIVITY_LOGGING_ON') THEN + RGStrNum := 35 + ELSE IF (S = 'NODE_ACTIVITY_NEW_USER_LOGGING_ON') THEN + RGStrNum := 36 + ELSE IF (S = 'NODE_ACTIVITY_MISCELLANEOUS') THEN + RGStrNum := 37 + ELSE IF (S = 'NEW_USER_PASSWORD_INVALID') THEN + RGStrNum := 38 + ELSE IF (S = 'NEW_USER_PASSWORD_ATTEMPT_EXCEEDED') THEN + RGStrNum := 39 + ELSE IF (S = 'NEW_USER_RECORD_SAVING') THEN + RGStrNum := 40 + ELSE IF (S = 'NEW_USER_RECORD_SAVED') THEN + RGStrNum := 41 + ELSE IF (S = 'NEW_USER_APPLICATION_LETTER') THEN + RGStrNum := 42 + ELSE IF (S = 'NEW_USER_IN_RESPONSE_TO_SUBJ') THEN + RGStrNum := 43; + IF (RGStrNum = -1) THEN + BEGIN + WriteLn('Error!'); + WriteLn; + WriteLn(^G^G^G'The following string definition is invalid:'); + WriteLn; + WriteLn(' '+S); + Found := FALSE; + END + ELSE + BEGIN + Done := FALSE; + WITH StrPointer DO + BEGIN + Pointer := (FileSize(RGStrFile) + 1); + TextSize := 0; + END; + Seek(RGStrFile,FileSize(RGStrFile)); + WHILE NOT EOF(F) AND (NOT Done) DO + BEGIN + ReadLn(F,S); + IF (S[1] = '$') THEN + Done := TRUE + ELSE + BEGIN + Inc(StrPointer.TextSize,(Length(S) + 1)); + BlockWrite(RGStrFile,S,(Length(S) + 1)); + END; + END; + Seek(StrPointerFile,RGStrNum); + Write(StrPointerFile,StrPointer); + END; + END; + END; + Close(F); + Close(RGStrFile); + Close(StrPointerFile); + IF (Found) THEN + WriteLn('Done!') + ELSE + BEGIN + Erase(StrPointerFile); + Erase(RGStrFile); + END; +END; + +PROCEDURE CompileSysOpStrings; +BEGIN + WriteLn; + Write('Compiling sysop strings ... '); + Found := TRUE; + Assign(StrPointerFile,'RGSCFGPR.DAT'); + ReWrite(StrPointerFile); + Assign(RGStrFile,'RGSCFGTX.DAT'); + ReWrite(RGStrFile,1); + Assign(F,'RGSCFG.TXT'); + Reset(F); + WHILE NOT EOF(F) AND (Found) DO + BEGIN + ReadLn(F,S); + IF (S <> '') AND (S[1] = '$') THEN + BEGIN + Delete(S,1,1); + S := AllCaps(S); + RGStrNum := -1; + IF (S = 'SYSTEM_CONFIGURATION_MENU') THEN + RGStrNum := 0 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION') THEN + RGStrNum := 1 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_BBS_NAME') THEN + RGStrNum := 2 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_BBS_PHONE') THEN + RGStrNum := 3 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_TELNET_URL') THEN + RGStrNum := 4 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSOP_NAME') THEN + RGStrNum := 5 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSOP_CHAT_HOURS') THEN + RGStrNum := 6 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_MINIMUM_BAUD_HOURS') THEN + RGStrNum := 7 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_DOWNLOAD_HOURS') THEN + RGStrNum := 8 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_MINIMUM_BAUD_DOWNLOAD_HOURS') THEN + RGStrNum := 9 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSOP_PASSWORD_MENU') THEN + RGStrNum := 10 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSOP_PASSWORD') THEN + RGStrNum := 11 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_NEW_USER_PASSWORD') THEN + RGStrNum := 12 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_BAUD_OVERRIDE_PASSWORD') THEN + RGStrNum := 13 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_PRE_EVENT_TIME') THEN + RGStrNum := 14 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS') THEN + RGStrNum := 15 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_GLOBAL') THEN + RGStrNum := 16 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_START') THEN + RGStrNum := 17 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_SHUTTLE') THEN + RGStrNum := 18 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_NEW_USER') THEN + RGStrNum := 19 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_MESSAGE_READ') THEN + RGStrNum := 20 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_FILE_LISTING') THEN + RGStrNum := 21 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_BULLETIN_PREFIX') THEN + RGStrNum := 22 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_LOCAL_SECURITY') THEN + RGStrNum := 23 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_DATA_PATH') THEN + RGStrNum := 24 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_MISC_PATH') THEN + RGStrNum := 25 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_MSG_PATH') THEN + RGStrNum := 26 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_NODELIST_PATH') THEN + RGStrNum := 27 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_LOG_PATH') THEN + RGStrNum := 28 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_TEMP_PATH') THEN + RGStrNum := 29 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_PROTOCOL_PATH') THEN + RGStrNum := 30 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_ARCHIVE_PATH') THEN + RGStrNum := 31 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_ATTACH_PATH') THEN + RGStrNum := 32 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_STRING_PATH') THEN + RGStrNum := 33; + IF (RGStrNum = -1) THEN + BEGIN + WriteLn('Error!'); + WriteLn; + WriteLn(^G^G^G'The following string definition is invalid:'); + WriteLn; + WriteLn(' '+S); + Found := FALSE; + END + ELSE + BEGIN + Done := FALSE; + WITH StrPointer DO + BEGIN + Pointer := (FileSize(RGStrFile) + 1); + TextSize := 0; + END; + Seek(RGStrFile,FileSize(RGStrFile)); + WHILE NOT EOF(F) AND (NOT Done) DO + BEGIN + ReadLn(F,S); + IF (S[1] = '$') THEN + Done := TRUE + ELSE + BEGIN + Inc(StrPointer.TextSize,(Length(S) + 1)); + BlockWrite(RGStrFile,S,(Length(S) + 1)); + END; + END; + Seek(StrPointerFile,RGStrNum); + Write(StrPointerFile,StrPointer); + END; + END; + END; + Close(F); + Close(RGStrFile); + Close(StrPointerFile); + IF (Found) THEN + WriteLn('Done!') + ELSE + BEGIN + Erase(StrPointerFile); + Erase(RGStrFile); + END; +END; + +PROCEDURE CompileFileAreaEditorStrings; +BEGIN + WriteLn; + Write('Compiling file area editor strings ... '); + Found := TRUE; + Assign(StrPointerFile,'FAEPR.DAT'); + ReWrite(StrPointerFile); + Assign(RGStrFile,'FAETX.DAT'); + ReWrite(RGStrFile,1); + Assign(F,'FAELNG.TXT'); + Reset(F); + WHILE NOT EOF(F) AND (Found) DO + BEGIN + ReadLn(F,S); + IF (S <> '') AND (S[1] = '$') THEN + BEGIN + Delete(S,1,1); + S := AllCaps(S); + RGStrNum := -1; + IF (S = 'FILE_AREA_HEADER_TOGGLE_ONE') THEN + RGStrNum := 0 + ELSE IF (S = 'FILE_AREA_HEADER_TOGGLE_TWO') THEN + RGStrNum := 1 + ELSE IF (S = 'FILE_AREA_HEADER_NO_FILE_AREAS') THEN + RGStrNum := 2 + ELSE IF (S = 'FILE_AREA_EDITOR_PROMPT') THEN + RGStrNum := 3 + ELSE IF (S = 'FILE_AREA_EDITOR_HELP') THEN + RGStrNum := 4 + ELSE IF (S = 'NO_FILE_AREAS') THEN + RGStrNum := 5 + ELSE IF (S = 'FILE_CHANGE_DRIVE_START') THEN + RGStrNum := 6 + ELSE IF (S = 'FILE_CHANGE_DRIVE_END') THEN + RGStrNum := 7 + ELSE IF (S = 'FILE_CHANGE_DRIVE_DRIVE') THEN + RGStrNum := 8 + ELSE IF (S = 'FILE_CHANGE_INVALID_ORDER') THEN + RGStrNum := 9 + ELSE IF (S = 'FILE_CHANGE_INVALID_DRIVE') THEN + RGStrNum := 10 + ELSE IF (S = 'FILE_CHANGE_UPDATING_DRIVE') THEN + RGStrNum := 11 + ELSE IF (S = 'FILE_CHANGE_UPDATING_DRIVE_DONE') THEN + RGStrNum := 12 + ELSE IF (S = 'FILE_CHANGE_UPDATING_SYSOPLOG') THEN + RGStrNum := 13 + ELSE IF (S = 'FILE_DELETE_PROMPT') THEN + RGStrNum := 14 + ELSE IF (S = 'FILE_DELETE_DISPLAY_AREA') THEN + RGStrNum := 15 + ELSE IF (S = 'FILE_DELETE_VERIFY_DELETE') THEN + RGStrNum := 16 + ELSE IF (S = 'FILE_DELETE_NOTICE') THEN + RGStrNum := 17 + ELSE IF (S = 'FILE_DELETE_SYSOPLOG') THEN + RGStrNum := 18 + ELSE IF (S = 'FILE_DELETE_DATA_FILES') THEN + RGStrNum := 19 + ELSE IF (S = 'FILE_DELETE_REMOVE_DL_DIRECTORY') THEN + RGStrNum := 20 + ELSE IF (S = 'FILE_DELETE_REMOVE_UL_DIRECTORY') THEN + RGStrNum := 21 + ELSE IF (S = 'FILE_INSERT_MAX_FILE_AREAS') THEN + RGStrNum := 22 + ELSE IF (S = 'FILE_INSERT_PROMPT') THEN + RGStrNum := 23 + ELSE IF (S = 'FILE_INSERT_AFTER_ERROR_PROMPT') THEN + RGStrNum := 24 + ELSE IF (S = 'FILE_INSERT_CONFIRM_INSERT') THEN + RGStrNum := 25 + ELSE IF (S = 'FILE_INSERT_NOTICE') THEN + RGStrNum := 26 + ELSE IF (S = 'FILE_INSERT_SYSOPLOG') THEN + RGStrNum := 27 + ELSE IF (S = 'FILE_MODIFY_PROMPT') THEN + RGStrNum := 28 + ELSE IF (S = 'FILE_MODIFY_SYSOPLOG') THEN + RGStrNum := 29 + ELSE IF (S = 'FILE_POSITION_NO_AREAS') THEN + RGStrNum := 30 + ELSE IF (S = 'FILE_POSITION_PROMPT') THEN + RGStrNum := 31 + ELSE IF (S = 'FILE_POSITION_NUMBERING') THEN + RGStrNum := 32 + ELSE IF (S = 'FILE_POSITION_BEFORE_WHICH') THEN + RGStrNum := 33 + ELSE IF (S = 'FILE_POSITION_NOTICE') THEN + RGStrNum := 34 + ELSE IF (S = 'FILE_EDITING_AREA_HEADER') THEN + RGStrNum := 35 + ELSE IF (S = 'FILE_INSERTING_AREA_HEADER') THEN + RGStrNum := 36 + ELSE IF (S = 'FILE_EDITING_INSERTING_SCREEN') THEN + RGStrNum := 37 + ELSE IF (S = 'FILE_EDITING_INSERTING_PROMPT') THEN + RGStrNum := 38 + ELSE IF (S = 'FILE_AREA_NAME_CHANGE') THEN + RGStrNum := 39 + ELSE IF (S = 'FILE_FILE_NAME_CHANGE') THEN + RGStrNum := 40 + ELSE IF (S = 'FILE_DUPLICATE_FILE_NAME_ERROR') THEN + RGStrNum := 41 + ELSE IF (S = 'FILE_USE_DUPLICATE_FILE_NAME') THEN + RGStrNum := 42 + ELSE IF (S = 'FILE_OLD_DATA_FILES_PATH') THEN + RGStrNum := 43 + ELSE IF (S = 'FILE_NEW_DATA_FILES_PATH') THEN + RGStrNum := 44 + ELSE IF (S = 'FILE_RENAME_DATA_FILES') THEN + RGStrNum := 45 + ELSE IF (S = 'FILE_DL_PATH') THEN + RGStrNum := 46 + ELSE IF (S = 'FILE_SET_DL_PATH_TO_UL_PATH') THEN + RGStrNum := 47 + ELSE IF (S = 'FILE_UL_PATH') THEN + RGStrNum := 48 + ELSE IF (S = 'FILE_ACS') THEN + RGStrNum := 49 + ELSE IF (S = 'FILE_DL_ACCESS') THEN + RGStrNum := 50 + ELSE IF (S = 'FILE_UL_ACCESS') THEN + RGStrNum := 51 + ELSE IF (S = 'FILE_MAX_FILES') THEN + RGStrNum := 52 + ELSE IF (S = 'FILE_PASSWORD') THEN + RGStrNum := 53 + ELSE IF (S = 'FILE_ARCHIVE_TYPE') THEN + RGStrNum := 54 + ELSE IF (S = 'FILE_COMMENT_TYPE') THEN + RGStrNum := 55 + ELSE IF (S = 'FILE_TOGGLE_FLAGS') THEN + RGStrNum := 56 + ELSE IF (S = 'FILE_MOVE_DATA_FILES') THEN + RGStrNum := 57 + ELSE IF (S = 'FILE_TOGGLE_HELP') THEN + RGStrNum := 58 + ELSE IF (S = 'FILE_JUMP_TO') THEN + RGStrNum := 59 + ELSE IF (S = 'FILE_FIRST_VALID_RECORD') THEN + RGStrNum := 60 + ELSE IF (S = 'FILE_LAST_VALID_RECORD') THEN + RGStrNum := 61 + ELSE IF (S = 'FILE_INSERT_EDIT_HELP') THEN + RGStrNum := 62 + ELSE IF (S = 'FILE_INSERT_HELP') THEN + RGStrNum := 63 + ELSE IF (S = 'FILE_EDIT_HELP') THEN + RGStrNum := 64 + ELSE IF (S = 'CHECK_AREA_NAME_ERROR') THEN + RGStrNum := 65 + ELSE IF (S = 'CHECK_FILE_NAME_ERROR') THEN + RGStrNum := 66 + ELSE IF (S = 'CHECK_DL_PATH_ERROR') THEN + RGStrNum := 67 + ELSE IF (S = 'CHECK_UL_PATH_ERROR') THEN + RGStrNum := 68 + ELSE IF (S = 'CHECK_ARCHIVE_TYPE_ERROR') THEN + RGStrNum := 69 + ELSE IF (S = 'CHECK_COMMENT_TYPE_ERROR') THEN + RGStrNum := 70; + IF (RGStrNum = -1) THEN + BEGIN + WriteLn('Error!'); + WriteLn; + WriteLn('The following string definition is invalid:'); + WriteLn; + WriteLn(' '+S); + Found := FALSE; + END + ELSE + BEGIN + Done := FALSE; + WITH StrPointer DO + BEGIN + Pointer := (FileSize(RGStrFile) + 1); + TextSize := 0; + END; + Seek(RGStrFile,FileSize(RGStrFile)); + WHILE NOT EOF(F) AND (NOT Done) DO + BEGIN + ReadLn(F,S); + IF (S[1] = '$') THEN + Done := TRUE + ELSE + BEGIN + Inc(StrPointer.TextSize,(Length(S) + 1)); + BlockWrite(RGStrFile,S,(Length(S) + 1)); + END; + END; + Seek(StrPointerFile,RGStrNum); + Write(StrPointerFile,StrPointer); + END; + END; + END; + Close(F); + Close(RGStrFile); + Close(StrPointerFile); + IF (Found) THEN + WriteLn('Done!') + ELSE + BEGIN + Erase(StrPointerFile); + Erase(RGStrFile); + END; +END; + +BEGIN + CLrScr; + WriteLn('Renegade Language String Compiler Version 3.1'); + Writeln('Copyright 2009 - The Renegade Developement Team'); + IF (NOT Exist('RGLNG.TXT')) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'RGLNG.TXT does not exist!'); + Exit; + END; + IF (NOT Exist('RGMAIN.TXT')) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'RGMAIN.TXT does not exists!'); + Exit; + END; + IF (NOT Exist('RGNOTE.TXT')) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'RGNOTE.TXT does not exists!'); + Exit; + END; + IF (NOT Exist('RGSCFG.TXT')) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'RGSCFG.TXT does not exists!'); + Exit; + END; + IF (NOT Exist('FAELNG.TXT')) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'FAELNG.TXT does not exists!'); + Exit; + END; + CompileLanguageStrings; + CompileMainStrings; + CompileNoteStrings; + CompileSysOpStrings; + CompileFileAreaEditorStrings; +END. \ No newline at end of file diff --git a/SOURCE/RGQUOTE.PAS b/SOURCE/RGQUOTE.PAS new file mode 100644 index 0000000..768943b --- /dev/null +++ b/SOURCE/RGQUOTE.PAS @@ -0,0 +1,103 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +PROGRAM RGQUOTE; + +USES + Crt, + Dos; + +TYPE + StrPointerRec = RECORD + Pointer, + TextSize: LongInt; + END; + +VAR + RGStrFile: FILE; + StrPointerFile: FILE OF StrPointerRec; + StrPointer: StrPointerRec; + F: Text; + S: STRING; + RGStrNum: LongInt; + Done,Found: Boolean; + +FUNCTION AllCaps(S: STRING): STRING; +VAR + I: Integer; +BEGIN + FOR I := 1 TO Length(S) DO + IF (S[I] IN ['a'..'z']) THEN + S[I] := Chr(Ord(S[I]) - Ord('a')+Ord('A')); + AllCaps := S; +END; + +FUNCTION Exist(FN: STRING): Boolean; +VAR + DirInfo: SearchRec; +BEGIN + FindFirst(FN,AnyFile,DirInfo); + Exist := (DosError = 0); +end; + + +BEGIN + CLrScr; + WriteLn('Renegade Quote String Compiler Version 1.0'); + Writeln('Copyright 2006 - The Renegade Developement Team'); + WriteLn; + IF (ParamCount < 1) THEN + Writeln(^G^G^G'Please specify a file name!') + ELSE IF (Pos('.',ParamStr(1)) = 0) THEN + WriteLn(^G^G^G'Please Specify a valid file name (Example: "Name.Ext")') + ELSE IF (Length(ParamStr(1)) > 12) THEN + Writeln(^G^G^G'The file name must not be longer then twelve characters!') + ELSE IF (NOT Exist(ParamStr(1))) THEN + WriteLn(^G^G^G'That file name was not found!') + ELSE + BEGIN + S := ParamStr(1); + Write('Compiling strings ... '); + Found := TRUE; + Assign(StrPointerFile,Copy(S,1,(Pos('.',S) - 1))+'.PTR'); + ReWrite(StrPointerFile); + Assign(RGStrFile,Copy(S,1,(Pos('.',S) - 1))+'.DAT'); + ReWrite(RGStrFile,1); + Assign(F,ParamStr(1)); + Reset(F); + WHILE NOT EOF(F) DO + BEGIN + ReadLn(F,S); + IF (S <> '') AND (S[1] = '$') THEN + BEGIN + Delete(S,1,1); + S := AllCaps(S); + Done := FALSE; + WITH StrPointer DO + BEGIN + Pointer := (FileSize(RGStrFile) + 1); + TextSize := 0; + END; + Seek(RGStrFile,FileSize(RGStrFile)); + WHILE NOT EOF(F) AND (NOT Done) DO + BEGIN + ReadLn(F,S); + IF (S[1] = '$') THEN + Done := TRUE + ELSE + BEGIN + Inc(StrPointer.TextSize,(Length(S) + 1)); + BlockWrite(RGStrFile,S,(Length(S) + 1)); + END; + END; + Seek(StrPointerFile,FileSize(StrPointerFile)); + Write(StrPointerFile,StrPointer); + END; + END; + Close(F); + Close(RGStrFile); + Close(StrPointerFile); + WriteLn('Done!') + END; +END. \ No newline at end of file diff --git a/SOURCE/RPSCREEN.PAS b/SOURCE/RPSCREEN.PAS new file mode 100644 index 0000000..16aab0d --- /dev/null +++ b/SOURCE/RPSCREEN.PAS @@ -0,0 +1,157 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} +unit RPScreen; + +interface + +{$IFDEF WIN32} +uses + Windows; + +type + TScreenBuf = Array[1..25, 1..80] of TCharInfo; // REETODO Don't hardcode to 80x25 +{$ENDIF} + +procedure RPBlockCursor; +procedure RPGotoXY(xy: SmallWord); +procedure RPHideCursor; +procedure RPInsertCursor; +procedure RPRestoreScreen(var screenBuf: TScreenBuf); +procedure RPSaveScreen(var screenBuf: TScreenBuf); +function RPScreenSizeX: Word; +function RPScreenSizeY: Word; +procedure RPSetAttrAt(x, y, attr: SmallWord); +procedure RPShowCursor; +function RPWhereXY: SmallWord; + +implementation + +{$IFDEF WIN32} +var + StdOut: THandle; +{$ENDIF} + +{$IFDEF WIN32} +procedure RPBlockCursor; +var + CCI: TConsoleCursorInfo; +begin + CCI.bVisible := true; + CCI.dwSize := 15; + SetConsoleCursorInfo(StdOut, CCI); +end; + +procedure RPGotoXY(xy: SmallWord); +var + Coord: TCoord; +begin + Coord.x := xy AND $00FF; + Coord.y := xy AND $FF00 SHR 8; + SetConsoleCursorPosition(StdOut, Coord); +end; + +procedure RPHideCursor; +var + CCI: TConsoleCursorInfo; +begin + GetConsoleCursorInfo(StdOut, CCI); + CCI.bVisible := false; + SetConsoleCursorInfo(StdOut, CCI); +end; + +procedure RPInsertCursor; +var + CCI: TConsoleCursorInfo; +begin + CCI.bVisible := true; + CCI.dwSize := 99; + SetConsoleCursorInfo(StdOut, CCI); +end; + +{ REETODO Should detect screen size } +procedure RPRestoreScreen(var screenBuf: TScreenBuf); +var + BufSize : TCoord; + WritePos : TCoord; + DestRect : TSmallRect; +begin + BufSize.X := 80; + BufSize.Y := 25; + WritePos.X := 0; + WritePos.Y := 0; + DestRect.Left := 0; + DestRect.Top := 0; + DestRect.Right := 79; + DestRect.Bottom := 24; + WriteConsoleOutput(StdOut, @screenBuf[1][1], BufSize, WritePos, DestRect); +end; + +{ REETODO Should detect screen size } +procedure RPSaveScreen(var screenBuf: TScreenBuf); +var + BufSize : TCoord; + ReadPos : TCoord; + SourceRect : TSmallRect; +begin + BufSize.X := 80; + BufSize.Y := 25; + ReadPos.X := 0; + ReadPos.Y := 0; + SourceRect.Left := 0; + SourceRect.Top := 0; + SourceRect.Right := 79; + SourceRect.Bottom := 24; + ReadConsoleOutput(StdOut, @screenBuf[1][1], BufSize, ReadPos, SourceRect); +end; + +function RPScreenSizeX: Word; +var + CSBI: TConsoleScreenBufferInfo; +begin + GetConsoleScreenBufferInfo(StdOut, CSBI); + RPScreenSizeX := CSBI.srWindow.Right - CSBI.srWindow.Left + 1; +end; + +function RPScreenSizeY: Word; +var + CSBI: TConsoleScreenBufferInfo; +begin + GetConsoleScreenBufferInfo(StdOut, CSBI); + RPScreenSizeY := CSBI.srWindow.Bottom - CSBI.srWindow.Top + 1; +end; + +procedure RPSetAttrAt(x, y, attr: SmallWord); +var + NumWritten: Longint; + WriteCoord: TCoord; +begin + WriteCoord.X := x; + WriteCoord.Y := y; + WriteConsoleOutputAttribute(StdOut, @attr, 1, WriteCoord, NumWritten); +end; + +procedure RPShowCursor; +var + CCI: TConsoleCursorInfo; +begin + GetConsoleCursorInfo(StdOut, CCI); + CCI.bVisible := true; + SetConsoleCursorInfo(StdOut, CCI); +end; + +function RPWhereXY: SmallWord; +var + CSBI: TConsoleScreenBufferInfo; +begin + GetConsoleScreenBufferInfo(StdOut, CSBI); + RPWhereXY := CSBI.dwCursorPosition.x + (CSBI.dwCursorPosition.y SHL 8); +end; +{$ENDIF} + + +{$IFDEF WIN32} +BEGIN + StdOut := GetStdHandle(STD_OUTPUT_HANDLE); +{$ENDIF} +END. \ No newline at end of file diff --git a/SOURCE/SCRIPT.PAS b/SOURCE/SCRIPT.PAS new file mode 100644 index 0000000..1952fde --- /dev/null +++ b/SOURCE/SCRIPT.PAS @@ -0,0 +1,431 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT Script; + +INTERFACE + +USES + Common; + +PROCEDURE ReadQ(CONST FileN: AStr); +PROCEDURE ReadASW(UserN: Integer; FN: AStr); +PROCEDURE ReadASW1(MenuOption: Str50); + +IMPLEMENTATION + +USES + Dos, + Doors, + MiscUser, + SysOp2G, + TimeFunc; + +PROCEDURE ReadQ(CONST FileN: AStr); +VAR + InFile, + OutFile, + OutFile1: Text; + C: Char; + OutP, + Lin, + S, + Mult, + Got, + LastInp, + InFileName, + OutFileName: AStr; + PS: PathStr; + NS: NameStr; + ES: ExtStr; + I, + X: Integer; + + PROCEDURE GoToLabel(Got: AStr); + VAR + S: AStr; + BEGIN + Got := ':'+AllCaps(Got); + Reset(InFile); + REPEAT + ReadLn(InFile,S); + UNTIL (EOF(InFile)) OR (AllCaps(S) = Got); + END; + + PROCEDURE DumpToFile; + VAR + NewOutFile: Text; + WriteOut: Boolean; { goes to false when passing OLD infoform } + BEGIN + Assign(NewOutFile,General.MiscPath+'INF'+IntToStr(ThisNode)+'.TMP'); + ReWrite(NewOutFile); + Reset(OutFile); + WriteOut := TRUE; + WHILE (NOT EOF(OutFile)) DO + BEGIN + ReadLn(OutFile,S); + IF (Pos('User: '+Caps(ThisUser.Name), S) > 0) THEN + WriteOut := FALSE + ELSE IF (NOT WriteOut) THEN + IF (Pos('User: ', S) > 0) THEN + WriteOut := TRUE; + IF (WriteOut) THEN + WriteLn(NewOutFile,S); + END; + Reset(OutFile1); + WHILE (NOT EOF(OutFile1)) DO + BEGIN + ReadLn(OutFile1,S); + WriteLn(NewOutFile,S); + END; + Close(OutFile1); + Close(OutFile); + Close(NewOutFile); + Kill(General.MiscPath+NS+'.ASW'); + Erase(OutFile1); + ReName(NewOutFile,General.MiscPath+NS+'.ASW'); + LastError := IOResult; + END; + +BEGIN + InFileName := FileN; + FSplit(InFileName,PS,NS,ES); + InFileName := PS+NS+'.INF'; + IF (NOT Exist(InFileName)) THEN + BEGIN + InFileName := General.MiscPath+NS+'.INF'; + IF (NOT Exist(InFileName)) THEN + BEGIN + S := '* Infoform not found: '+FileN; + SysOpLog(S); + Exit; + END; + IF (OkAvatar) AND Exist(General.MiscPath+NS+'.INV') THEN + InFileName := General.MiscPath+NS+'.INV' + ELSE IF (OkAnsi) AND Exist(General.MiscPath+NS+'.INA') THEN + InFileName := General.MiscPath+NS+'.INA'; + END + ELSE IF (OkAvatar) AND Exist(PS+NS+'.INV') THEN + InFileName := PS+NS+'.INV' + ELSE IF (OkAnsi) AND Exist(PS+NS+'.INA') THEN + InFileName := PS+NS+'.INA'; + Assign(InFile,InFileName); + Reset(InFile); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('* Infoform not found: '+FileN); + SysOpLog(S); + Exit; + END; + FSplit(InFileName,PS,NS,ES); + OutFileName := General.MiscPath+NS+'.ASW'; + Assign(OutFile1,General.MiscPath+'TMP'+IntToStr(ThisNode)+'.ASW'); + ReWrite(OutFile1); + SysOpLog('* Answered InfoForm "'+FileN+'"'); + Assign(OutFile,OutFileName); + WriteLn(OutFile1,'User: '+Caps(ThisUser.name)); + WriteLn(OutFile1,'Date: '+Dat); + WriteLn(OutFile1); + NL; + PrintingFile := TRUE; + REPEAT + Abort := FALSE; + X := 0; + REPEAT + Inc(X); + Read(InFile,OutP[X]); + IF EOF(InFile) THEN {check again incase avatar parameter} + BEGIN + Inc(X); + Read(InFile,OutP[X]); + IF EOF(InFile) THEN + Dec(X); + END; + UNTIL ((OutP[X] = ^M) AND NOT (OutP[X - 1] IN [^V,^Y])) OR (X = 159) OR EOF(InFile) OR HangUp; + OutP[0] := Chr(X); + IF (Pos(^[,OutP) > 0) OR (Pos(^V,OutP) > 0) THEN + BEGIN + CROff := TRUE; + CtrlJOff := TRUE; + END + ELSE + BEGIN + IF (OutP[X] = ^M) THEN + Dec(OutP[0]); + IF (OutP[1] = ^J) THEN + Delete(OutP,1,1); + END; + IF (Pos('*',OutP) <> 0) AND (OutP[1] <> ';') THEN + OutP := ';A'+OutP; + IF (Length(OutP) = 0) THEN + NL + ELSE + CASE OutP[1] OF + ';' : BEGIN + IF (Pos('*',OutP) <> 0) THEN + IF (OutP[2] <> 'D') THEN + OutP := Copy(OutP,1,(Pos('*',OutP) - 1)); + Lin := Copy(OutP,3,255); + I := (80 - Length(Lin)); + S := Copy(OutP,1,2); + IF (S[1] = ';') THEN + CASE S[2] OF + 'R','F','V','C','D','G','I','K','L','Q','S','T',';': I := 1; { DO nothing } + ELSE IF (Lin[1] = ';') THEN + Prompt(Copy(Lin,2,255)) + ELSE + Prompt(Lin); + END; + S := #1#1#1; + CASE OutP[2] OF + 'A' : InputL(S,I); + 'B' : Input(S,I); + 'C' : BEGIN + Mult := ''; + I := 1; + S := Copy(OutP,Pos('"',OutP),(Length(OutP) - Pos('"',OutP))); + REPEAT + Mult := Mult + S[I]; + Inc(I); + UNTIL (S[I] = '"') OR (I > Length(S)); + Lin := Copy(OutP,(I + 3),(Length(S) - (I - 1))); + Prompt(Lin); + OneK(C,Mult,TRUE,TRUE); + S := C; + END; + 'D' : BEGIN + DoDoorFunc(OutP[3],Copy(OutP,4,(Length(OutP) - 3))); + S := #0#0#0; + END; + 'F' : BEGIN + ChangeARFlags(Copy(OutP,3,255)); + OutP := #0#0#0 + END; + 'G' : BEGIN + Got := Copy(OutP,3,(Length(OutP) - 2)); + GoToLabel(Got); + S := #0#0#0; + END; + 'S' : BEGIN + Delete(OutP,1,3); + IF AACS(Copy(OutP,1,(Pos('"',OutP) - 1))) THEN + BEGIN + Got := Copy(OutP,(Pos(',',OutP) + 1),255); + GoToLabel(Got); + END; + S := #0#0#0; + END; + 'H' : HangUp := TRUE; + 'I' : BEGIN + Mult := Copy(OutP,3,(Length(OutP) - 2)); + I := Pos(',',Mult); + IF (I <> 0) THEN + BEGIN + Got := Copy(Mult,(I + 1),(Length(Mult) - I)); + Mult := Copy(Mult,1,(I - 1)); + IF (AllCaps(LastInp) = AllCaps(Mult)) THEN + GoToLabel(Got); + END; + S := #1#1#1; + OutP := #0#0#0; + END; + 'K' : BEGIN + Close(InFile); + Close(OutFile1); + Erase(OutFile1); + SysOpLog('* InfoForm aborted.'); + PrintingFile := FALSE; + Exit; + END; + 'L' : BEGIN + S := Copy(OutP,3,(Length(OutP) - 2)); + WriteLn(OutFile1,MCI(S)); + S := #0#0#0; + END; + 'Q' : BEGIN + WHILE NOT EOF(InFile) DO + ReadLn(InFile,S); + S := #0#0#0; + END; + 'R' : BEGIN + ChangeACFlags(Copy(OutP,3,255)); + OutP := #0#0#0; + END; + 'T' : BEGIN + S := Copy(OutP,3,(Length(OutP) - 2)); + PrintF(S); + S := #0#0#0; + END; + 'Y' : BEGIN + IF YN(0,TRUE) THEN + S := 'YES' + ELSE + S := 'NO'; + IF (Lin[1] = ';') THEN + OutP := #0#0#0; + END; + 'N' : BEGIN + IF YN(0,FALSE) THEN + S := 'YES' + ELSE + S := 'NO'; + IF (Lin[1] = ';') THEN + OutP := #0#0#0 + END; + 'V' : IF (UpCase(OutP[3]) IN ['!'..'~']) THEN + AutoValidate(ThisUser,UserNum,UpCase(OutP[3])); + ';' : S := #0#0#0; + END; + IF (S <> #1#1#1) THEN + BEGIN + IF (OutP <> #0#0#0) THEN + OutP := Lin + S; + LastInp := S; + END; + IF (S = #0#0#0) THEN + OutP := #0#0#0; + END; + ':' : OutP := #0#0#0; + ELSE + PrintACR(OutP); + END; + IF (OutP <> #0#0#0) THEN + BEGIN + IF (Pos('%CL',OutP) <> 0) THEN + Delete(OutP,Pos('%CL',OutP),3); + WriteLn(OutFile1,MCI(OutP)); + END; + UNTIL ((EOF(InFile)) OR (HangUp)); + Close(OutFile1); + Close(InFile); + IF (HangUp) THEN + BEGIN + WriteLn(OutFile1); + WriteLn(OutFile1,'** HUNG UP **'); + END + ELSE + DumpToFile; + PrintingFile := FALSE; + LastError := IOResult; +END; + +PROCEDURE ReadASW(UserN: Integer; FN: AStr); +VAR + QF: Text; + User: UserRecordType; + QS: AStr; + PS: PathStr; + NS: NameStr; + ES: ExtStr; + UserFound: Boolean; + + PROCEDURE ExactMatch; + BEGIN + Reset(QF); + REPEAT + ReadLn(QF,QS); + IF (Pos('User: '+Caps(User.Name),QS) > 0) THEN + UserFound := TRUE; + IF (NOT Empty) THEN + WKey; + UNTIL (EOF(QF)) OR (UserFound) OR (Abort); + END; + +BEGIN + IF ((UserN >= 1) AND (UserN <= (MaxUsers - 1))) THEN + LoadURec(User,UserN) + ELSE + BEGIN + Print('Invalid user number.'); + Exit; + END; + Abort := FALSE; + Next := FALSE; + FSplit(FN,PS,NS,ES); + FN := General.MiscPath+NS+'.ASW'; + IF (NOT Exist(FN)) THEN + BEGIN + FN := General.DataPath+NS+'.ASW'; + IF (NOT Exist(FN)) THEN + BEGIN + Print('Answers file not found.'); + Exit; + END; + END; + Assign(QF,FN); + Reset(QF); + IF (IOResult <> 0) THEN + Print('"'+FN+'": unable to open.') + ELSE + BEGIN + UserFound := FALSE; + ExactMatch; + IF (NOT UserFound) AND (NOT Abort) THEN + Print('That user has not completed the questionnaire.') + ELSE + BEGIN + IF (CoSysOp) THEN + Print(QS); + REPEAT + WKey; + ReadLn(QF,QS); + IF (Copy(QS,1,6) <> 'Date: ') OR (CoSysOp) THEN + IF (Copy(QS,1,6) <> 'User: ') THEN + PrintACR(QS) + ELSE + UserFound := FALSE; + UNTIL EOF(QF) OR (NOT UserFound) OR (Abort) OR (HangUp); + END; + Close(QF); + END; + LastError := IOResult; +END; + +PROCEDURE ReadASW1(MenuOption: Str50); +VAR + PS: PathStr; + NS: NameStr; + ES: ExtStr; + UserN: Integer; +BEGIN + IF (MenuOption = '') THEN + BEGIN + Prt('Enter filename: '); + MPL(8); + Input(MenuOption,8); + NL; + IF (MenuOption = '') THEN + Exit; + END; + FSplit(MenuOption,PS,NS,ES); + MenuOption := AllCaps(General.DataPath+NS+'.ASW'); + IF (NOT Exist(MenuOption)) THEN + BEGIN + MenuOption := AllCaps(General.MiscPath+NS+'.ASW'); + IF (NOT Exist(MenuOption)) THEN + BEGIN + Print('InfoForm answer file not found: "'+MenuOption+'"'); + Exit; + END; + END; + NL; + Print('Enter the name of the user to view: '); + Prt(':'); + LFindUserWS(UserN); + IF (UserN <> 0) THEN + ReadASW(UserN,MenuOption) + ELSE IF (CoSysOp) THEN + BEGIN + NL; + IF PYNQ('List entire answer file? ',0,FALSE) THEN + BEGIN + NL; + PrintF(NS+'.ASW'); + END; + END; +END; + +END. diff --git a/SOURCE/SHORTMSG.PAS b/SOURCE/SHORTMSG.PAS new file mode 100644 index 0000000..e03108b --- /dev/null +++ b/SOURCE/SHORTMSG.PAS @@ -0,0 +1,79 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT ShortMsg; + +INTERFACE + +USES + Common; + +PROCEDURE ReadShortMessage; +PROCEDURE SendShortMessage(CONST UNum: Integer; CONST Message: AStr); + +IMPLEMENTATION + +PROCEDURE ReadShortMessage; +VAR + ShortMsgFile: FILE OF ShortMessageRecordType; + ShortMsg: ShortMessageRecordType; + RecNum: LongInt; +BEGIN + Assign(ShortMsgFile,General.DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + IF (IOResult = 0) THEN + BEGIN + UserColor(1); + RecNum := 0; + WHILE (RecNum <= (FileSize(ShortMsgFile) - 1)) AND (NOT HangUp) DO + BEGIN + Seek(ShortMsgFile,RecNum); + Read(ShortMsgFile,ShortMsg); + IF (ShortMsg.Destin = UserNum) THEN + BEGIN + Print(ShortMsg.Msg); + ShortMsg.Destin := -1; + Seek(ShortMsgFile,RecNum); + Write(ShortMsgFile,ShortMsg); + END; + Inc(RecNum); + END; + Close(ShortMsgFile); + UserColor(1); + END; + Exclude(ThisUser.Flags,SMW); + SaveURec(ThisUser,UserNum); + LastError := IOResult; +END; + +PROCEDURE SendShortMessage(CONST UNum: Integer; CONST Message: AStr); +VAR + ShortMsgFile: FILE OF ShortMessageRecordType; + ShortMsg: ShortMessageRecordType; + User: UserRecordType; +BEGIN + IF (UNum >= 1) AND (UNum <= (MaxUsers - 1)) THEN + BEGIN + Assign(ShortMsgFile,General.DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + IF (IOResult = 2) THEN + ReWrite(ShortMsgFile); + Seek(ShortMsgFile,FileSize(ShortMsgFile)); + WITH ShortMsg DO + BEGIN + Msg := Message; + Destin := UNum; + END; + Write(ShortMsgFile,ShortMsg); + Close(ShortMsgFile); + LoadURec(User,UNum); + Include(User.Flags,SMW); + SaveURec(User,UNum); + LastError := IOResult; + END; +END; + +END. diff --git a/SOURCE/SPAWNO.PAS b/SOURCE/SPAWNO.PAS new file mode 100644 index 0000000..f6b74fa --- /dev/null +++ b/SOURCE/SPAWNO.PAS @@ -0,0 +1,59 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +UNIT SPAWNO; + +INTERFACE + +CONST + (* symbolic constants for specifying permissible swap locations *) + (* add/or together the desired destinations *) + Swap_Disk = 0; + Swap_XMS = 1; + Swap_EMS = 2; + Swap_Ext = 4; + Swap_All = $FF; (* swap to any available destination *) + + (* error codes *) + ENotFound = 2; + ENoPath = 3; + EAccess = 5; + ENoMem = 8; + E2Big = 20; + EWriteFault = 29; + +VAR + Spawno_Error: Integer; (* error code when Spawn returns -1 *) + +PROCEDURE Init_Spawno(Swap_Dirs: STRING; Swap_Types: Integer; Min_Res: Integer; Res_Stack: Integer); + (* Min_Res = minimum number of paragraphs to keep resident + Res_Stack = minimum paragraphs of stack to keep resident + (0 = no change) + *) + +FUNCTION Spawn(ProgName: STRING; Arguments: STRING; EnvSeg: Integer): Integer; + +IMPLEMENTATION + +{$IFDEF MSDOS} +{$L SPAWNTP.OBJ} + +PROCEDURE Init_Spawno(Swap_Dirs: STRING; Swap_Types: Integer; Min_Res: Integer; Res_Stack: Integer); EXTERNAL; + +FUNCTION Spawn(ProgName: STRING; Arguments: STRING; EnvSeg: Integer): Integer; EXTERNAL; +{$ENDIF} +{$IFDEF WIN32} +PROCEDURE Init_Spawno(Swap_Dirs: STRING; Swap_Types: Integer; Min_Res: Integer; Res_Stack: Integer); +BEGIN + WriteLn('REETODO SPAWNO Init_Spawno'); Halt; +END; + +FUNCTION Spawn(ProgName: STRING; Arguments: STRING; EnvSeg: Integer): Integer; +BEGIN + WriteLn('REETODO SPAWNO Spawn'); Halt; +END; +{$ENDIF} + +END. + diff --git a/SOURCE/SPLITCHA.PAS b/SOURCE/SPLITCHA.PAS new file mode 100644 index 0000000..6f91883 --- /dev/null +++ b/SOURCE/SPLITCHA.PAS @@ -0,0 +1,1421 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT SplitCha; + +INTERFACE + +USES + Common, + MyIO; + +PROCEDURE RequestSysOpChat(CONST MenuOption: Str50); +PROCEDURE ChatFileLog(b: Boolean); +PROCEDURE SysOpSplitChat; + +IMPLEMENTATION + +USES + Crt, + Dos, + Email, + Events, + TimeFunc; + +TYPE + ChatStrArray = ARRAY [1..10] OF AStr; + +VAR + UserChat: ChatStrArray; + SysOpChat: ChatStrArray; + UserXPos, + UserYPos, + SysOpXPos, + SysOpYPos: Byte; + Cmd : Char; + ChatHelp : Boolean; + ClrHlp : Shortint; +PROCEDURE RequestSysOpChat(CONST MenuOption: Str50); +VAR + User: UserRecordType; + MHeader: MHeaderRec; + Reason: AStr; + Cmd: Char; + Counter: Byte; + UNum, + Counter1: Integer; + Chatted: Boolean; +BEGIN + IF (ChatAttempts < General.MaxChat) OR (CoSysOp) THEN + BEGIN + NL; + IF (Pos(';',MenuOption) <> 0) THEN + Print(Copy(MenuOption,(Pos(';',MenuOption) + 1),Length(MenuOption))) + ELSE + lRGLngStr(37,FALSE); { FString.ChatReason; } + Chatted := FALSE; + Prt(': '); + MPL(60); + InputL(Reason,60); + IF (Reason <> '') THEN + BEGIN + Inc(ChatAttempts); + SysOpLog('^4Chat attempt:'); + SL1(Reason); + IF (NOT SysOpAvailable) AND AACS(General.OverRideChat) THEN + PrintF('CHATOVR'); + IF (SysOpAvailable) OR (AACS(General.OverRideChat) AND PYNQ(^M^J'SysOp is not available. Override? ',0,FALSE)) THEN + BEGIN + lStatus_Screen(100,'Press [SPACE] to chat or [ENTER] for silence.',FALSE,Reason); + { Print(FString.ChatCall1); } + lRGLngStr(14,FALSE); + Counter := 0; + Abort := FALSE; + NL; + REPEAT + Inc(Counter); + WKey; + IF (OutCom) THEN + Com_Send(^G); + { Prompt(FString.ChatCall2); } + lRGLngStr(15,FALSE); + IF (OutCom) THEN + Com_Send(^G); + IF (ShutUpChatCall) THEN + Delay(600) + ELSE + BEGIN + {$IFDEF MSDOS} + FOR Counter1 := 300 DOWNTO 2 DO + BEGIN + Delay(1); + Sound(Counter1 * 10); + END; + FOR Counter1 := 2 TO 300 DO + BEGIN + Delay(1); + Sound(Counter1 * 10); + END; + NoSound; +{$ENDIF} +{$IFDEF WIN32} + WriteLn('REETODO SPLITCHA RequestSysOpChat'); Halt; +{$ENDIF} + END; + IF (KeyPressed) THEN + BEGIN + Cmd := ReadKey; + CASE Cmd OF + #0 : BEGIN + Cmd := ReadKey; + SKey1(Cmd); + END; + #32 : BEGIN + Chatted := TRUE; + ChatAttempts := 0; + SysOpSplitChat; + END; + ^M : ShutUpChatCall := TRUE; + END; + END; + UNTIL (Counter = 9) OR (Chatted) OR (Abort) OR (HangUp); + NL; + END; + lStatus_Screen(100,'Chat Request: '+Reason,FALSE,Reason); + IF (Chatted) THEN + ChatReason := '' + ELSE + BEGIN + ChatReason := Reason; + PrintF('NOSYSOP'); + UNum := StrToInt(MenuOption); + IF (UNum > 0) THEN + BEGIN + InResponseTo := #1'Tried chatting'; + LoadURec(User,UNum); + NL; + IF PYNQ('Send mail to '+Caps(User.Name)+'? ',0,FALSE) THEN + BEGIN + MHeader.Status := []; + SEmail(UNum,MHeader); + END; + END; + END; + TLeft; + END; + END + ELSE + BEGIN + PrintF('GOAWAY'); + UNum := StrToInt(MenuOption); + IF (UNum > 0) THEN + BEGIN + InResponseTo := 'Tried chatting (more than '+IntToStr(General.MaxChat)+' times!)'; + SysOpLog(InResponseTo); + MHeader.Status := []; + SEmail(UNum,MHeader); + END; + END; +END; + +PROCEDURE ChatFileLog(b: Boolean); +VAR + s: AStr; +BEGIN + s := 'Chat'; + IF (ChatSeparate IN ThisUser.SFlags) THEN + s := s + IntToStr(UserNum); + s := General.LogsPath+s+'.LOG'; + IF (NOT b) THEN + BEGIN + IF (CFO) THEN + BEGIN + lStatus_Screen(100,'Chat recorded to '+s,FALSE,s); + CFO := FALSE; + IF (TextRec(ChatFile).Mode <> FMClosed) THEN + Close(ChatFile); + END; + END + ELSE + BEGIN + CFO := TRUE; + IF (TextRec(ChatFile).Mode = FMOutPut) THEN + Close(ChatFile); + Assign(ChatFile,s); + Append(ChatFile); + IF (IOResult = 2) THEN + ReWrite(ChatFile); + IF (IOResult <> 0) THEN + SysOpLog('Cannot open chat log file: '+s); + lStatus_Screen(100,'Recording chat to '+s,FALSE,s); + WriteLn(ChatFile); + WriteLn(ChatFile); + WriteLn(ChatFile,Dat); + WriteLn(ChatFile); + Writeln(ChatFile,'Recorded with user: '+Caps(ThisUser.Name)); + WriteLn(ChatFile); + WriteLn(ChatFile,'Chat reason: '+AOnOff(ChatReason = '','None',ChatReason)); + WriteLn(ChatFile); + WriteLn(ChatFile); + WriteLn(ChatFile,'------------------------------------'); + WriteLn(ChatFile); + END; +END; + +PROCEDURE ANSIG(X,Y: Byte); +BEGIN + IF (ComPortSpeed > 0) THEN + IF (OkAvatar) THEN + SerialOut(^V^H+Chr(Y)+Chr(X)) + ELSE + SerialOut(#27+'['+IntToStr(Y)+';'+IntToStr(X)+'H'); + IF (WantOut) THEN + GoToXY(X,Y); +END; + +PROCEDURE Clear_Eol; +BEGIN + IF (NOT OkAvatar) THEN + SerialOut(#27'[K') + ELSE + SerialOut(^V^G); + IF (WantOut) THEN + ClrEOL; +END; + +PROCEDURE SysOpChatWindow; +Var SysopNameLength : Integer; +BEGIN + Printf('SPLTCHAT'); + IF NOT NoFile THEN exit; + + SysopNameLength := ( 80 - Length(General.SysOpName) ); + CLS; + ANSIG(1,1); + Prompt('^4'); + ANSIG( ( SysopNameLength - 5 ), 1); + Prompt('^4[ ^5' + General.SysOpName + ' ^4]'); + ANSIG(1,12); + Prompt('^4'); + ANSIG(31,12); + Prompt('^4[ ^5Ctl^4+^5Z for Help ^4]'); + ANSIG(1,23); + Prompt('^4'); + ANSIG(3,23); + Prompt('^4[ ^5'+ ThisUser.Name + ' ^4]'); + +END; + +PROCEDURE SysOpSplitChat; +VAR + S, + SysOpStr, + UserStr, + SysOpLastLineStr, + UserLastLineStr: AStr; + + SysOpLine, + UserLine, + SaveWhereX, + SaveWhereY, + SaveTextAttr: Byte; + + C: Char; + SysOpCPos, + UserCPos: Byte; + + ChatTime: LongInt; + SaveEcho, + SavePrintingFile, + SaveMCIAllowed: Boolean; + + PROCEDURE DoChar(C: Char; VAR CPos,XPos,YPos,Line: Byte; VAR ChatArray: ChatStrArray; VAR WrapLine: AStr); + VAR + Counter, + Counter1: Byte; + BEGIN + + IF C = #27 THEN { Esc Exit } + BEGIN + InChat := False; + Update_Screen; + END; + IF C = #63 THEN { F5 Exit } + BEGIN + InChat := False; + Update_Screen; + END; + + IF (CPos < 79) THEN + BEGIN + ANSIG(XPos,YPos); + ChatArray[Line][CPos] := C; + OutKey(C); + Inc(CPos); + Inc(XPos); + + ChatArray[Line][0] := Chr(CPos - 1); + + IF (Trapping) THEN + Write(TrapFile,C); + + END + ELSE + BEGIN + ChatArray[Line][CPos] := C; + Inc(CPos); + + ChatArray[Line][0] := Chr(CPos - 1); + Counter := (CPos - 1); + WHILE (Counter > 0) AND (ChatArray[Line][Counter] <> ' ') AND (ChatArray[Line][Counter] <> ^H) DO + Dec(Counter); + IF (Counter > (CPos DIV 2)) AND (Counter <> (CPos - 1)) THEN + BEGIN + WrapLine := Copy(ChatArray[Line],(Counter + 1),(CPos - Counter)); + FOR Counter1 := (CPos - 2) DOWNTO Counter DO + BEGIN + ANSIG(XPos,YPos); + Prompt(^H); + Dec(XPos); + END; + FOR Counter1 := (CPos - 2) DOWNTO Counter DO + BEGIN + ANSIG(XPos,YPos); + Prompt(' '); + Inc(XPos); + END; + ChatArray[Line][0] := Chr(Counter - 1); + END; + + NL; + + XPos := 2; + + IF (YPos > 1) AND (YPos < 11) OR (YPos > 12) AND (YPos < 22) THEN + BEGIN + Inc(YPos); + Inc(Line); + END + ELSE + BEGIN + + FOR Counter := 1 TO 9 DO + ChatArray[Counter] := ChatArray[Counter + 1]; + + ChatArray[10] := ''; + + + FOR Counter := 10 DOWNTO 1 DO + BEGIN + ANSIG(2,Counter + 1); + PrintMain(ChatArray[Counter]); + Clear_EOL; + END; + + END; + + ANSIG(XPos,YPos); + + CPos := 1; + + ChatArray[Line] := ''; + + IF (WrapLine <> '') THEN + BEGIN + Prompt(WrapLine); + ChatArray[Line] := WrapLine; + WrapLine := ''; + CPos := (Length(ChatArray[Line]) + 1); + XPos := Length(ChatArray[Line]) + 2; + END; + + END; + + END; + + PROCEDURE DOBackSpace(VAR Cpos,XPos: Byte; YPos: Byte; VAR S: AStr); + BEGIN + IF (CPos > 1) THEN + BEGIN + ANSIG(XPos,YPos); + BackSpace; + Dec(CPos); + Dec(XPos); + S[0] := Chr(CPos - 1); + END; + END; + + PROCEDURE DoTab(VAR CPos,XPos: Byte; YPos: Byte; VAR S: AStr); + VAR + Counter, + Counter1: Byte; + BEGIN + Counter := (5 - (CPos MOD 5)); + IF ((CPos + Counter) < 79) THEN + BEGIN + FOR Counter1 := 1 TO Counter DO + BEGIN + ANSIG(XPos,YPos); + Prompt(' '); + S[CPos] := ' '; + Inc(CPos); + Inc(XPos); + END; + S[0] := Chr(CPos - 1); + END; + END; + + PROCEDURE DOCarriageReturn(VAR CPos,XPos,YPos: Byte; VAR S: AStr); + Var i : Integer; + BEGIN + + S[0] := Chr(CPos - 1); + + (* Check Scrool here *) + + Inc(YPos); + XPos := 2; + { Fix Splitscreen so user and op stay on their own sides } + If (YPos = 12) Then + Begin + For i := 2 To 10 Do + Begin + ANSIG(1,i); + Clear_EOL; + End; + YPos := 2; + End + Else If (YPos = 23) Then + Begin + For i := 13 To 21 Do + Begin + ANSIG(1,i); + Clear_EOL; + End; + YPos := 13; + End; + + ANSIG(XPos,YPos); + + (* Do Cmds Here or add as Ctrl *) + + CPos := 1; + S := ''; + END; + + PROCEDURE DOBackSpaceWord(VAR CPos,XPos: Byte; YPos: Byte; VAR S: AStr); + BEGIN + IF (CPos > 1) THEN + BEGIN + REPEAT + ANSIG(XPos,YPos); + BackSpace; + Dec(CPos); + Dec(XPos); + UNTIL (CPos = 1) OR (S[CPos] = ' '); + S[0] := Chr(CPos - 1); + END; + END; + + PROCEDURE DOBackSpaceLine(VAR CPos,Xpos: Byte; YPos: Byte; VAR S: AStr); + VAR + Counter: Byte; + BEGIN + IF (CPos > 1) THEN + BEGIN + FOR Counter := 1 TO (CPos - 1) DO + BEGIN + ANSIG(XPos,YPos); + BackSpace; + Dec(CPos); + Dec(XPos); + END; + S[0] := Chr(CPos - 1); + END; + END; + +BEGIN + SaveWhereX := WhereX; + SaveWhereY := WhereY; + SaveTextAttr := TextAttr; + SaveScreen(Wind); + + UserColor(1); + SaveMCIAllowed := MCIAllowed; + MCIAllowed := TRUE; + ChatTime := GetPackDateTime; + DOSANSIOn := FALSE; + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + SaveNAvail := (NAvail IN Noder.Status); + Exclude(Noder.Status,NAvail); + SaveNode(ThisNode); + END; + SavePrintingFile := PrintingFile; + InChat := TRUE; + ChatCall := FALSE; + SaveEcho := Echo; + Echo := TRUE; + IF (General.AutoChatOpen) THEN + ChatFileLog(TRUE) + ELSE IF (ChatAuto IN ThisUser.SFlags) THEN + ChatFileLog(TRUE); + NL; + Exclude(ThisUser.Flags,Alert); + { + PrintF('CHATINIT'); + IF (NoFile) THEN + (* + Prompt('^5'+FString.EnGage); + *) + lRGLNGStr(2,FALSE); + } + + + IF (ChatReason <> '') THEN + BEGIN + lStatus_Screen(100,ChatReason,FALSE,S); + ChatReason := ''; + END; + + SysOpLastLineStr := ''; + UserLastLineStr := ''; + SysOpXPos := 2; + SysOpYPos := 2; + UserXPos := 2; + UserYPos := 13; + + SysOpStr := ''; + UserStr := ''; + SysOpCPos := 1; + UserCPos := 1; + SysOpLine := 1; + UserLine := 1; + + SysOpChatWindow; + + ANSIG(SysOpXPos,SysOpYPos); + + UserColor(General.SysOpColor); + WColor := TRUE; + + REPEAT + + C := Char(GetKey); + + CheckHangUp; + + CASE Ord(C) OF + 32..255 : + IF (WColor) THEN + DoChar(C,SysOpCPos,SysOpXPos,SysOpYPos,SysOpLine,SysOpChat,SysOpLastLineStr) + ELSE + DoChar(C,UserCPos,UserXPos,UserYPos,UserLine,UserChat,UserLastLineStr); + 3 : BEGIN + FOR ClrHlp := 18 TO 21 DO {Ctrl+Z Help Clear - (Ctrl+C) } + BEGIN + ANSIG(38,ClrHlp); + Clear_EOL; + END; + ANSIG(SaveWhereX,SaveWhereY); + END; + 7 : IF (OutCom) THEN + Com_Send(^G); + 8 : IF (WColor) THEN + DOBackSpace(SysOpCpos,SysOpXPos,SysOpYPos,SysOpStr) + ELSE + DOBackSpace(UserCpos,UserXPos,UserYPos,UserStr); + 9 : IF (WColor) THEN + DoTab(SysOpCPos,SysOpXPos,SysOpYPos,SysOpStr) + ELSE + DoTab(UserCPos,UserXPos,UserYPos,UserStr); + 13 : IF (WColor) THEN + DOCarriageReturn(SysOpCPos,SysOpXPos,SysOpYPos,SysOpStr) + ELSE + DOCarriageReturn(UserCPos,UserXPos,UserYPos,UserStr); + + 17 : InChat := FALSE; + + 23 : IF (WColor) THEN + DOBackSpaceWord(SysOpCPos,SysOpXPos,SysOpYPos,SysOpStr) + ELSE + DOBackSpaceWord(UserCPos,UserXPos,UserYPos,UserStr); + 24 : IF (WColor) THEN + DOBackSpaceLine(SysOpCPos,SysOpXpos,SysOpYPos,SysOpStr) + ELSE + DOBackSpaceLine(UserCPos,UserXpos,UserYPos,UserStr); + + 26 : Begin { Ctrl+Z } + + + + PrintF('CHATHELP'); + + If Not nofile Then + + Begin + + OneK(Cmd,#27#26,FALSE,FALSE); + + Case Ord(Cmd) Of + + 26,27 : SysOpChatWindow; { Escape } + + End; { /case } + + End { /If Not } + + Else + + Begin + + ChatHelp := TRUE; + + ANSIG(38,18); + + Print('^5Chat Help |15: ^4(^5Ctrl+C ^5:: ^4Clear Help^5)'); + + ANSIG(38,19); + + Print('^5Ctrl+G |15: ^4Hangup ^5Ctrl+W |15: ^4Delete Word'); + + ANSIG(38,20); + + Print('^5Ctrl+H |15: ^4Backspace ^5Ctrl+X |15: ^4Delete Line'); + + ANSIG(38,21); + + Print('^5Ctrl+H |15: ^4Tab ^5Ctrl+Q |15: ^4Quit|07'); + + + + ANSIG(SaveWhereX,SaveWhereY); + + End; { /If Not else case } + + End; { /26 } { Help } + END; + + (* + + IF (S[1] = '/') THEN + S := AllCaps(S); + + IF (Copy(S,1,6) = '/TYPE ') AND (SysOp) THEN + BEGIN + S := Copy(S,7,(Length(S) - 6)); + IF (S <> '') THEN + BEGIN + PrintFile(S); + IF (NoFile) THEN + Print('*File not found*'); + END; + END + ELSE IF ((S = '/HELP') OR (S = '/?')) THEN + BEGIN + IF (SysOp) THEN + Print('^5/TYPE d:\path\filename.ext^3: Type a file'); + { + Print('^5/BYE^3: Hang up'); + Print('^5/CLS^3: Clear the screen'); + Print('^5/PAGE^3: Page the SysOp and User'); + Print('^5/Q^3: Exit chat mode'^M^J); + } + lRGLngStr(65,FALSE); + END + ELSE IF (S = '/CLS') THEN + CLS + ELSE IF (S = '/PAGE') THEN + BEGIN + FOR Counter := 650 TO 700 DO + BEGIN + Sound(Counter); + Delay(4); + NoSound; + END; + REPEAT + Dec(Counter); + Sound(Counter); + Delay(2); + NoSound; + UNTIL (Counter = 200); + Prompt(^G^G); + END + ELSE IF (S = '/BYE') THEN + BEGIN + Print('Hanging up ...'); + HangUp := TRUE; + END + ELSE IF (S = '/Q') THEN + BEGIN + InChat := FALSE; + Print('Chat Aborted ...'); + END; + IF (CFO) THEN + WriteLn(ChatFile,S); + *) + UNTIL ((NOT InChat) OR (HangUp)); + + RemoveWindow(Wind); + ANSIG(SaveWhereX,SaveWhereY); + TextAttr := SaveTextAttr; + + { + PrintF('CHATEND'); + IF (NoFile) THEN + (* + Print('^5'+FString.lEndChat); + *) + lRGLngStr(3,FALSE); + } + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + IF (SaveNAvail) THEN + Include(Noder.Status,NAvail); + SaveNode(ThisNode); + END; + ChatTime := (GetPackDateTime - ChatTime); + IF (ChopTime = 0) THEN + Inc(FreeTime,ChatTime); + TLeft; + S := 'Chatted for '+FormattedTime(ChatTime); + IF (CFO) THEN + BEGIN + S := S+' -{ Recorded in Chat'; + IF (ChatSeparate IN ThisUser.SFlags) THEN + S := S + IntToStr(UserNum); + S := S+'.LOG }-'; + END; + SysOpLog(S); + InChat := FALSE; + Echo := SaveEcho; + IF ((HangUp) AND (CFO)) THEN + BEGIN + WriteLn(ChatFile); + WriteLn(ChatFile,'=> User disconnected'); + WriteLn(ChatFile); + END; + PrintingFile := SavePrintingFile; + IF (CFO) THEN + ChatFileLog(FALSE); + IF (InVisEdit) THEN + Buf := ^L; + MCIAllowed := SaveMCIAllowed; +END; + +END. +======= +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT SplitCha; + +INTERFACE + +USES + Common, + MyIO; + +PROCEDURE RequestSysOpChat(CONST MenuOption: Str50); +PROCEDURE ChatFileLog(b: Boolean); +PROCEDURE SysOpSplitChat; + +IMPLEMENTATION + +USES + Crt, + Dos, + Email, + Events, + TimeFunc; + +TYPE + ChatStrArray = ARRAY [1..10] OF AStr; + +VAR + UserChat: ChatStrArray; + SysOpChat: ChatStrArray; + UserXPos, + UserYPos, + SysOpXPos, + SysOpYPos: Byte; + +PROCEDURE RequestSysOpChat(CONST MenuOption: Str50); +VAR + User: UserRecordType; + MHeader: MHeaderRec; + Reason: AStr; + Cmd: Char; + Counter: Byte; + UNum, + Counter1: Integer; + Chatted: Boolean; +BEGIN + IF (ChatAttempts < General.MaxChat) OR (CoSysOp) THEN + BEGIN + NL; + IF (Pos(';',MenuOption) <> 0) THEN + Print(Copy(MenuOption,(Pos(';',MenuOption) + 1),Length(MenuOption))) + ELSE + lRGLngStr(37,FALSE); { FString.ChatReason; } + Chatted := FALSE; + Prt(': '); + MPL(60); + InputL(Reason,60); + IF (Reason <> '') THEN + BEGIN + Inc(ChatAttempts); + SysOpLog('^4Chat attempt:'); + SL1(Reason); + IF (NOT SysOpAvailable) AND AACS(General.OverRideChat) THEN + PrintF('CHATOVR'); + IF (SysOpAvailable) OR (AACS(General.OverRideChat) AND PYNQ(^M^J'SysOp is not available. Override? ',0,FALSE)) THEN + BEGIN + lStatus_Screen(100,'Press [SPACE] to chat or [ENTER] for silence.',FALSE,Reason); + { Print(FString.ChatCall1); } + lRGLngStr(14,FALSE); + Counter := 0; + Abort := FALSE; + NL; + REPEAT + Inc(Counter); + WKey; + IF (OutCom) THEN + Com_Send(^G); + { Prompt(FString.ChatCall2); } + lRGLngStr(15,FALSE); + IF (OutCom) THEN + Com_Send(^G); + IF (ShutUpChatCall) THEN + Delay(600) + ELSE + BEGIN + {$IFDEF MSDOS} + FOR Counter1 := 300 DOWNTO 2 DO + BEGIN + Delay(1); + Sound(Counter1 * 10); + END; + FOR Counter1 := 2 TO 300 DO + BEGIN + Delay(1); + Sound(Counter1 * 10); + END; + NoSound; +{$ENDIF} +{$IFDEF WIN32} + WriteLn('REETODO SPLITCHA RequestSysOpChat'); Halt; +{$ENDIF} + END; + IF (KeyPressed) THEN + BEGIN + Cmd := ReadKey; + CASE Cmd OF + #0 : BEGIN + Cmd := ReadKey; + SKey1(Cmd); + END; + #32 : BEGIN + Chatted := TRUE; + ChatAttempts := 0; + SysOpSplitChat; + END; + ^M : ShutUpChatCall := TRUE; + END; + END; + UNTIL (Counter = 9) OR (Chatted) OR (Abort) OR (HangUp); + NL; + END; + lStatus_Screen(100,'Chat Request: '+Reason,FALSE,Reason); + IF (Chatted) THEN + ChatReason := '' + ELSE + BEGIN + ChatReason := Reason; + PrintF('NOSYSOP'); + UNum := StrToInt(MenuOption); + IF (UNum > 0) THEN + BEGIN + InResponseTo := #1'Tried chatting'; + LoadURec(User,UNum); + NL; + IF PYNQ('Send mail to '+Caps(User.Name)+'? ',0,FALSE) THEN + BEGIN + MHeader.Status := []; + SEmail(UNum,MHeader); + END; + END; + END; + TLeft; + END; + END + ELSE + BEGIN + PrintF('GOAWAY'); + UNum := StrToInt(MenuOption); + IF (UNum > 0) THEN + BEGIN + InResponseTo := 'Tried chatting (more than '+IntToStr(General.MaxChat)+' times!)'; + SysOpLog(InResponseTo); + MHeader.Status := []; + SEmail(UNum,MHeader); + END; + END; +END; + +PROCEDURE ChatFileLog(b: Boolean); +VAR + s: AStr; +BEGIN + s := 'Chat'; + IF (ChatSeparate IN ThisUser.SFlags) THEN + s := s + IntToStr(UserNum); + s := General.LogsPath+s+'.LOG'; + IF (NOT b) THEN + BEGIN + IF (CFO) THEN + BEGIN + lStatus_Screen(100,'Chat recorded to '+s,FALSE,s); + CFO := FALSE; + IF (TextRec(ChatFile).Mode <> FMClosed) THEN + Close(ChatFile); + END; + END + ELSE + BEGIN + CFO := TRUE; + IF (TextRec(ChatFile).Mode = FMOutPut) THEN + Close(ChatFile); + Assign(ChatFile,s); + Append(ChatFile); + IF (IOResult = 2) THEN + ReWrite(ChatFile); + IF (IOResult <> 0) THEN + SysOpLog('Cannot open chat log file: '+s); + lStatus_Screen(100,'Recording chat to '+s,FALSE,s); + WriteLn(ChatFile); + WriteLn(ChatFile); + WriteLn(ChatFile,Dat); + WriteLn(ChatFile); + Writeln(ChatFile,'Recorded with user: '+Caps(ThisUser.Name)); + WriteLn(ChatFile); + WriteLn(ChatFile,'Chat reason: '+AOnOff(ChatReason = '','None',ChatReason)); + WriteLn(ChatFile); + WriteLn(ChatFile); + WriteLn(ChatFile,'------------------------------------'); + WriteLn(ChatFile); + END; +END; + +PROCEDURE ANSIG(X,Y: Byte); +BEGIN + IF (ComPortSpeed > 0) THEN + IF (OkAvatar) THEN + SerialOut(^V^H+Chr(Y)+Chr(X)) + ELSE + SerialOut(#27+'['+IntToStr(Y)+';'+IntToStr(X)+'H'); + IF (WantOut) THEN + GoToXY(X,Y); +END; + +PROCEDURE Clear_Eol; +BEGIN + IF (NOT OkAvatar) THEN + SerialOut(#27'[K') + ELSE + SerialOut(^V^G); + IF (WantOut) THEN + ClrEOL; +END; + +PROCEDURE SysOpChatWindow; +BEGIN + CLS; + ANSIG(1,1); + Prompt('������������������������������������������������������������������������������͸'); + ANSIG(1,12); + Prompt('�������������������������������͵ CTRL-Z Help ��������������������������������͵'); + ANSIG(1,23); + Prompt('������������������������������������������������������������������������������;'); +END; + +PROCEDURE SysOpSplitChat; +VAR + S, + SysOpStr, + UserStr, + SysOpLastLineStr, + UserLastLineStr: AStr; + + SysOpLine, + UserLine, + SaveWhereX, + SaveWhereY, + SaveTextAttr: Byte; + + C: Char; + SysOpCPos, + UserCPos: Byte; + + ChatTime: LongInt; + SaveEcho, + SavePrintingFile, + SaveMCIAllowed: Boolean; + + PROCEDURE DoChar(C: Char; VAR CPos,XPos,YPos,Line: Byte; VAR ChatArray: ChatStrArray; VAR WrapLine: AStr); + VAR + Counter, + Counter1: Byte; + BEGIN + IF (CPos < 79) THEN + BEGIN + ANSIG(XPos,YPos); + ChatArray[Line][CPos] := C; + OutKey(C); + Inc(CPos); + Inc(XPos); + + ChatArray[Line][0] := Chr(CPos - 1); + + IF (Trapping) THEN + Write(TrapFile,C); + + END + ELSE + BEGIN + ChatArray[Line][CPos] := C; + Inc(CPos); + + ChatArray[Line][0] := Chr(CPos - 1); + Counter := (CPos - 1); + WHILE (Counter > 0) AND (ChatArray[Line][Counter] <> ' ') AND (ChatArray[Line][Counter] <> ^H) DO + Dec(Counter); + IF (Counter > (CPos DIV 2)) AND (Counter <> (CPos - 1)) THEN + BEGIN + WrapLine := Copy(ChatArray[Line],(Counter + 1),(CPos - Counter)); + FOR Counter1 := (CPos - 2) DOWNTO Counter DO + BEGIN + ANSIG(XPos,YPos); + Prompt(^H); + Dec(XPos); + END; + FOR Counter1 := (CPos - 2) DOWNTO Counter DO + BEGIN + ANSIG(XPos,YPos); + Prompt(' '); + Inc(XPos); + END; + ChatArray[Line][0] := Chr(Counter - 1); + END; + + NL; + + XPos := 2; + + IF (YPos > 1) AND (YPos < 11) OR (YPos > 12) AND (YPos < 22) THEN + BEGIN + Inc(YPos); + Inc(Line); + END + ELSE + BEGIN + + FOR Counter := 1 TO 9 DO + ChatArray[Counter] := ChatArray[Counter + 1]; + + ChatArray[10] := ''; + + + FOR Counter := 10 DOWNTO 1 DO + BEGIN + ANSIG(2,Counter + 1); + PrintMain(ChatArray[Counter]); + Clear_EOL; + END; + + END; + + ANSIG(XPos,YPos); + + CPos := 1; + + ChatArray[Line] := ''; + + IF (WrapLine <> '') THEN + BEGIN + Prompt(WrapLine); + ChatArray[Line] := WrapLine; + WrapLine := ''; + CPos := (Length(ChatArray[Line]) + 1); + XPos := Length(ChatArray[Line]) + 2; + END; + + END; + + END; + + PROCEDURE DOBackSpace(VAR Cpos,XPos: Byte; YPos: Byte; VAR S: AStr); + BEGIN + IF (CPos > 1) THEN + BEGIN + ANSIG(XPos,YPos); + BackSpace; + Dec(CPos); + Dec(XPos); + S[0] := Chr(CPos - 1); + END; + END; + + PROCEDURE DoTab(VAR CPos,XPos: Byte; YPos: Byte; VAR S: AStr); + VAR + Counter, + Counter1: Byte; + BEGIN + Counter := (5 - (CPos MOD 5)); + IF ((CPos + Counter) < 79) THEN + BEGIN + FOR Counter1 := 1 TO Counter DO + BEGIN + ANSIG(XPos,YPos); + Prompt(' '); + S[CPos] := ' '; + Inc(CPos); + Inc(XPos); + END; + S[0] := Chr(CPos - 1); + END; + END; + + PROCEDURE DOCarriageReturn(VAR CPos,XPos,YPos: Byte; VAR S: AStr); + BEGIN + + S[0] := Chr(CPos - 1); + + (* Check Scrool here *) + + Inc(YPos); + XPos := 2; + { Fix Splitscreen so user and op stay on their own sides } + If (YPos = 12) Then + Begin + For i := 2 To 11 Do + Begin + ANSIG(1,i); + Clear_EOL; + End; + YPos := 2; + End + Else If (YPos = 23) Then + Begin + For i := 13 To 22 Do + Begin + ANSIG(1,i); + Clear_EOL; + End; + YPos := 13; + End; + + ANSIG(XPos,YPos); + + (* Do Cmds Here or add as Ctrl *) + + CPos := 1; + S := ''; + END; + + PROCEDURE DOBackSpaceWord(VAR CPos,XPos: Byte; YPos: Byte; VAR S: AStr); + BEGIN + IF (CPos > 1) THEN + BEGIN + REPEAT + ANSIG(XPos,YPos); + BackSpace; + Dec(CPos); + Dec(XPos); + UNTIL (CPos = 1) OR (S[CPos] = ' '); + S[0] := Chr(CPos - 1); + END; + END; + + PROCEDURE DOBackSpaceLine(VAR CPos,Xpos: Byte; YPos: Byte; VAR S: AStr); + VAR + Counter: Byte; + BEGIN + IF (CPos > 1) THEN + BEGIN + FOR Counter := 1 TO (CPos - 1) DO + BEGIN + ANSIG(XPos,YPos); + BackSpace; + Dec(CPos); + Dec(XPos); + END; + S[0] := Chr(CPos - 1); + END; + END; + +BEGIN + SaveWhereX := WhereX; + SaveWhereY := WhereY; + SaveTextAttr := TextAttr; + SaveScreen(Wind); + + UserColor(1); + SaveMCIAllowed := MCIAllowed; + MCIAllowed := TRUE; + ChatTime := GetPackDateTime; + DOSANSIOn := FALSE; + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + SaveNAvail := (NAvail IN Noder.Status); + Exclude(Noder.Status,NAvail); + SaveNode(ThisNode); + END; + SavePrintingFile := PrintingFile; + InChat := TRUE; + ChatCall := FALSE; + SaveEcho := Echo; + Echo := TRUE; + IF (General.AutoChatOpen) THEN + ChatFileLog(TRUE) + ELSE IF (ChatAuto IN ThisUser.SFlags) THEN + ChatFileLog(TRUE); + NL; + Exclude(ThisUser.Flags,Alert); + { + PrintF('CHATINIT'); + IF (NoFile) THEN + (* + Prompt('^5'+FString.EnGage); + *) + lRGLNGStr(2,FALSE); + } + + + IF (ChatReason <> '') THEN + BEGIN + lStatus_Screen(100,ChatReason,FALSE,S); + ChatReason := ''; + END; + + SysOpLastLineStr := ''; + UserLastLineStr := ''; + SysOpXPos := 2; + SysOpYPos := 2; + UserXPos := 2; + UserYPos := 13; + + SysOpStr := ''; + UserStr := ''; + SysOpCPos := 1; + UserCPos := 1; + SysOpLine := 1; + UserLine := 1; + + SysOpChatWindow; + + ANSIG(SysOpXPos,SysOpYPos); + + UserColor(General.SysOpColor); + WColor := TRUE; + + REPEAT + + C := Char(GetKey); + + CheckHangUp; + + CASE Ord(C) OF + 32..255 : + IF (WColor) THEN + DoChar(C,SysOpCPos,SysOpXPos,SysOpYPos,SysOpLine,SysOpChat,SysOpLastLineStr) + ELSE + DoChar(C,UserCPos,UserXPos,UserYPos,UserLine,UserChat,UserLastLineStr); + 7 : IF (OutCom) THEN + Com_Send(^G); + 8 : IF (WColor) THEN + DOBackSpace(SysOpCpos,SysOpXPos,SysOpYPos,SysOpStr) + ELSE + DOBackSpace(UserCpos,UserXPos,UserYPos,UserStr); + 9 : IF (WColor) THEN + DoTab(SysOpCPos,SysOpXPos,SysOpYPos,SysOpStr) + ELSE + DoTab(UserCPos,UserXPos,UserYPos,UserStr); + 13 : IF (WColor) THEN + DOCarriageReturn(SysOpCPos,SysOpXPos,SysOpYPos,SysOpStr) + ELSE + DOCarriageReturn(UserCPos,UserXPos,UserYPos,UserStr); + + 17 : InChat := FALSE; + + 23 : IF (WColor) THEN + DOBackSpaceWord(SysOpCPos,SysOpXPos,SysOpYPos,SysOpStr) + ELSE + DOBackSpaceWord(UserCPos,UserXPos,UserYPos,UserStr); + 24 : IF (WColor) THEN + DOBackSpaceLine(SysOpCPos,SysOpXpos,SysOpYPos,SysOpStr) + ELSE + DOBackSpaceLine(UserCPos,UserXpos,UserYPos,UserStr); + + 26 : ; { Help } + END; + + (* + + IF (S[1] = '/') THEN + S := AllCaps(S); + + IF (Copy(S,1,6) = '/TYPE ') AND (SysOp) THEN + BEGIN + S := Copy(S,7,(Length(S) - 6)); + IF (S <> '') THEN + BEGIN + PrintFile(S); + IF (NoFile) THEN + Print('*File not found*'); + END; + END + ELSE IF ((S = '/HELP') OR (S = '/?')) THEN + BEGIN + IF (SysOp) THEN + Print('^5/TYPE d:\path\filename.ext^3: Type a file'); + { + Print('^5/BYE^3: Hang up'); + Print('^5/CLS^3: Clear the screen'); + Print('^5/PAGE^3: Page the SysOp and User'); + Print('^5/Q^3: Exit chat mode'^M^J); + } + lRGLngStr(65,FALSE); + END + ELSE IF (S = '/CLS') THEN + CLS + ELSE IF (S = '/PAGE') THEN + BEGIN + FOR Counter := 650 TO 700 DO + BEGIN + Sound(Counter); + Delay(4); + NoSound; + END; + REPEAT + Dec(Counter); + Sound(Counter); + Delay(2); + NoSound; + UNTIL (Counter = 200); + Prompt(^G^G); + END + ELSE IF (S = '/BYE') THEN + BEGIN + Print('Hanging up ...'); + HangUp := TRUE; + END + ELSE IF (S = '/Q') THEN + BEGIN + InChat := FALSE; + Print('Chat Aborted ...'); + END; + IF (CFO) THEN + WriteLn(ChatFile,S); + *) + UNTIL ((NOT InChat) OR (HangUp)); + + RemoveWindow(Wind); + ANSIG(SaveWhereX,SaveWhereY); + TextAttr := SaveTextAttr; + + { + PrintF('CHATEND'); + IF (NoFile) THEN + (* + Print('^5'+FString.lEndChat); + *) + lRGLngStr(3,FALSE); + } + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + IF (SaveNAvail) THEN + Include(Noder.Status,NAvail); + SaveNode(ThisNode); + END; + ChatTime := (GetPackDateTime - ChatTime); + IF (ChopTime = 0) THEN + Inc(FreeTime,ChatTime); + TLeft; + S := 'Chatted for '+FormattedTime(ChatTime); + IF (CFO) THEN + BEGIN + S := S+' -{ Recorded in Chat'; + IF (ChatSeparate IN ThisUser.SFlags) THEN + S := S + IntToStr(UserNum); + S := S+'.LOG }-'; + END; + SysOpLog(S); + InChat := FALSE; + Echo := SaveEcho; + IF ((HangUp) AND (CFO)) THEN + BEGIN + WriteLn(ChatFile); + WriteLn(ChatFile,'=> User disconnected'); + WriteLn(ChatFile); + END; + PrintingFile := SavePrintingFile; + IF (CFO) THEN + ChatFileLog(FALSE); + IF (InVisEdit) THEN + Buf := ^L; + MCIAllowed := SaveMCIAllowed; +END; + +END. +>>>>>>> b4a1907d1337950c0b7225c9b507a9a7cb4eb7f6 diff --git a/SOURCE/STATS.PAS b/SOURCE/STATS.PAS new file mode 100644 index 0000000..acf8018 --- /dev/null +++ b/SOURCE/STATS.PAS @@ -0,0 +1,457 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} +UNIT STATS; + +INTERFACE + +USES + Common; + +TYPE + Top10UserRecordArray = RECORD + UNum: SmallInt; + Info: Real; + END; + + Top20FileRecordArray = RECORD + DirNum, + DirRecNum: SmallInt; + Downloaded: LongInt; + END; + + Top10UserArray = ARRAY [1..10] OF Top10UserRecordArray; + Top20FileArray = ARRAY [1..20] OF Top20FileRecordArray; + +VAR + Top10User: Top10UserArray; + Top20File: Top20FileArray; + +PROCEDURE GetUserStats(MenuOption: Str50); + +IMPLEMENTATION + +USES + File0, + File1, + File11; + +FUNCTION MaxR(R,R1: Real): Real; +BEGIN + IF (R1 = 0.0) THEN + MaxR := R + ELSE + MaxR := R1; +END; + +FUNCTION Center(S: AStr; Len: Byte; TF: Boolean): AStr; +VAR + Counter, + StrLength: Byte; + Which_Way: Boolean; +BEGIN + Which_Way := TF; + StrLength := Length(S); + FOR Counter := (StrLength + 1) TO Len DO + BEGIN + IF (Which_Way) THEN + BEGIN + S := ' ' + S; + Which_Way := FALSE; + END + ELSE + BEGIN + S := S + ' '; + Which_Way := TRUE; + END; + END; + Center := S; +END; + +PROCEDURE InitTop10UserArray(VAR Top10User: Top10UserArray); +VAR + Counter: Byte; +BEGIN + FOR Counter := 1 TO 10 DO + BEGIN + Top10User[Counter].UNum := -1; + Top10User[Counter].Info := 0.0; + END; +END; + +PROCEDURE InitTop20FileArray(VAR Top20User: Top20FileArray); +VAR + Counter: Byte; +BEGIN + FOR Counter := 1 TO 20 DO + BEGIN + Top20File[Counter].DirNum := -1; + Top20File[Counter].DirRecNum := -1; + Top20File[Counter].Downloaded := 0; + END; +END; + +PROCEDURE SortUserDecending(VAR Top10User: Top10UserArray; UNum: Integer; Info: Real); +VAR + Counter, + Counter1: Byte; +BEGIN + IF (Info > 0.0) THEN + FOR Counter := 1 TO 10 DO + IF (Info >= Top10User[Counter].Info) THEN + BEGIN + FOR Counter1 := 10 DOWNTO (Counter + 1) DO + Top10User[Counter1] := Top10User[Counter1 - 1]; + Top10User[Counter].UNum := UNum; + Top10User[Counter].Info := Info; + Counter := 10; + END; +END; + +PROCEDURE SortFileDecending(VAR Top20File: Top20FileArray; DirNum,DirRecNum: Integer; Downloaded: LongInt); +VAR + Counter, + Counter1: Byte; +BEGIN + IF (Downloaded > 0) THEN + FOR Counter := 1 to 20 DO + IF (Downloaded >= Top20File[Counter].Downloaded) THEN + BEGIN + FOR Counter1 := 20 DOWNTO (Counter + 1) DO + Top20File[Counter1] := Top20File[Counter1 - 1]; + Top20File[Counter].DirNum := DirNum; + Top20File[Counter].DirRecNum := DirRecNum; + Top20File[Counter].Downloaded := Downloaded; + Counter := 20; + END; +END; + +PROCEDURE SearchTop10User(VAR Top10User: Top10UserArray; Cmd: Char; ExcludeUserNum: Integer); +VAR + User: UserRecordType; + UNum: Integer; + Info: Real; +BEGIN + InitTop10UserArray(Top10User); + Abort := FALSE; + Next := FALSE; + Reset(UserFile); + UNum := 1; + WHILE (UNum <= (FileSize(UserFile) - 1)) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (ExcludeUserNum = 0) OR (UNum <> ExcludeUserNum) THEN + BEGIN + Seek(UserFile,UNum); + Read(UserFile,User); + IF (NOT (Deleted IN User.SFlags)) AND (NOT (LockedOut IN User.SFlags)) THEN + BEGIN + CASE Cmd OF + 'A' : Info := User.TTimeOn; + 'B' : Info := User.UK; + 'C' : Info := User.DK; + 'D' : Info := User.EmailSent; + 'E' : Info := User.MsgPost; + 'F' : Info := User.FeedBack; + 'G' : Info := User.LoggedOn; + 'H' : Info := User.Uploads; + 'I' : Info := User.Downloads; + 'J' : Info := User.FilePoints; + 'K' : Info := (User.UK / MaxR(1.0,User.DK)); + 'L' : Info := (User.MsgPost / MaxR(1.0,User.LoggedOn)); + END; + SortUserDecending(Top10User,UNum,Info); + END; + END; + Inc(UNum); + END; + Close(UserFile); +END; + +PROCEDURE SearchTop20AreaFileSpec(FArea: Integer; VAR Top20File: Top20FileArray); +VAR + F: FileInfoRecordType; + DirFileRecNum: Integer; +BEGIN + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + BEGIN + RecNo(F,'*.*',DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileInfoFile,DirFileRecNum); + Read(FileInfoFile,F); + IF (CanSee(F)) THEN + SortFileDecending(Top20File,FileArea,DirFileRecNum,F.Downloaded); + NRecNo(F,DirFileRecNum); + END; + Close(FileInfoFile); + Close(ExtInfoFile); + END; +END; + +PROCEDURE SearchTop20GlobalFileSpec(VAR Top20File: Top20FileArray); +VAR + FArea, + SaveFileArea: Integer; + SaveConfSystem: Boolean; +BEGIN + InitTop20FileArray(Top20File); + SaveFileArea := FileArea; + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + Abort := FALSE; + Next := FALSE; + FArea := 1; + WHILE (FArea >= 1) AND (FArea <= NumFileAreas) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + SearchTop20AreaFileSpec(FArea,Top20File); + WKey; + IF (Next) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + END; + Inc(FArea); + END; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + FileArea := SaveFileArea; + LoadFileArea(FileArea); +END; + +PROCEDURE DisplayTop10UserArray(Top10User: Top10UserArray; Title,Header: AStr; Decimal,Width: Byte); +VAR + User: UserRecordType; + TempStr: AStr; + Counter, + Counter1: Byte; +BEGIN + Abort := FALSE; + Next := FALSE; + CLS; + PrintACR('^5'+Center('-=[ Top 10 '+Title+' ]=-',78,TRUE)); + NL; + PrintACR('^5## User Name '+Center(Header,55,TRUE)); + NL; + Counter := 1; + WHILE (Counter <= 10) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + User.Name := ''; + IF (Top10User[Counter].UNum >= 1) THEN + LoadURec(User,Top10User[Counter].UNum); + TempStr := '^5'+PadRightInt(Counter,2)+ + ' '+ + AOnOff(User.Name = ThisUser.Name,'^7','^0')+ + User.Name+' ^1'; + FOR Counter1 := (Length(User.Name) + 1) TO 35 DO + TempStr := TempStr + '.'; + TempStr := TempStr + ' '+AOnOff((Top10User[Counter].Info > 0.0),'^4' + +PadRightStr(RealToStr(Top10User[Counter].Info,0,Decimal),Width),''); + PrintACR(TempStr); + WKey; + Inc(Counter); + END; + NL; + PauseScr(FALSE); +END; + +PROCEDURE DisplayTop20FileArray(Top20File: Top20FileArray); +VAR + F: FileInfoRecordType; + TempStr: AStr; + Counter, + SaveFileArea: Integer; + AddBatch: Boolean; +BEGIN + SaveFileArea := FileArea; + Abort := FALSE; + Next := FALSE; + CLS; + PrintACR('^5'+Center('-=[ Top 20 Files Downloaded ]=-',78,TRUE)); + NL; + PrintACR('^5## Filename.Ext Number Downloads ## Filename.Ext Number Downloads'); + NL; + FOR Counter := 1 to 10 DO + BEGIN + F.FileName := ''; + IF (Counter <= 10) THEN + BEGIN + IF (Top20File[Counter].DirNum > 0) THEN + BEGIN + InitFileArea(Top20File[Counter].DirNum); + IF (BadDownloadPath) THEN + Exit; + Seek(FileInfoFile,Top20File[Counter].DirRecNum); + Read(FileInfoFile,F); + Close(FileInfoFile); + Close(ExtInfoFile); + END; + TempStr := '^5'+PadRightInt(Counter,2); + TempStr := TempStr + '^0'+PadRightStr(F.FileName,15); + IF (Top20File[Counter].Downloaded > 0) THEN + TempStr := TempStr + '^4'+PadRightInt(Top20File[Counter].Downloaded,12) + ELSE + TempStr := TempStr + ' '; + END; + TempStr := TempStr + ' '; + F.FileName := ''; + IF ((Counter + 10) > 10) THEN + BEGIN + IF (Top20File[Counter + 10].DirNum > 0) THEN + BEGIN + InitFileArea(Top20File[Counter + 10].DirNum); + IF (BadDownloadPath) THEN + Exit; + Seek(FileInfoFile,Top20File[Counter + 10].DirRecNum); + Read(FileInfoFile,F); + Close(FileInfoFile); + Close(ExtInfoFile); + END; + TempStr := TempStr + '^5'+PadRightInt(Counter + 10,2); + TempStr := TempStr + '^0'+PadRightStr(F.FileName,15); + IF (Top20File[Counter + 10].Downloaded > 0) THEN + TempStr := TempStr + '^4'+PadRightInt(Top20File[Counter + 10].Downloaded,12) + END; + PrintACR(TempStr); + END; + NL; + PauseScr(FALSE); + (* + IF (PYNQ('Would you like to download one of these files? ',0,FALSE)) THEN + BEGIN + Counter := -1; + NL; + InputIntegerWOC('Download which file',Counter,1,20); + IF (Counter <> -1) THEN + IF (Top20File[Counter].DirNum <> -1) AND (Top20File[Counter].DirRecNum <> -1) THEN + BEGIN + InitFileArea(Top20File[Counter].DirNum); + IF (BadDownloadPath) THEN + Exit; + Seek(FileInfoFile,Top20File[Counter].DirRecNum); + Read(FileInfoFile,F); + NL; + DLX(F,Top20File[Counter].DirRecNum,FALSE,Abort); + Close(FileInfoFile); + Close(ExtInfoFile); + END; + END; + *) + FileArea := SaveFileArea; + LoadFileArea(FileArea); +END; + +PROCEDURE GetUserStats(MenuOption: Str50); +VAR + Title, + Header: AStr; + Decimal, + Width: Byte; + ExcludeUserNum: Integer; +BEGIN + MenuOption := ALLCaps(MenuOption); + IF (MenuOption = '') OR (NOT (MenuOption[1] IN ['A'..'M'])) THEN + BEGIN + NL; + Print('Invalid menu option for user statistics, please inform the SysOp.'); + PauseScr(FALSE); + SysOpLog('Invalid menu option for user statistics, valid options are A-M.'); + END + ELSE IF (MenuOption[1] IN ['A'..'L']) THEN + BEGIN + ExcludeUserNum := 0; + IF (Pos(';',MenuOption) <> 0) THEN + ExcludeUserNum := StrToInt(Copy(MenuOption,(Pos(';',MenuOption) + 1),50)); + SearchTop10User(Top10User,MenuOption[1],ExcludeUserNum); + CASE UpCase(MenuOption[1]) OF + 'A' : BEGIN + Title := 'High Time Users'; + Header := 'Minutes Online'; + Decimal := 0; + Width := 10; + END; + 'B' : BEGIN + Title := 'File Kbyte Uploaders'; + Header := 'Kbytes Uploaded'; + Decimal := 0; + Width := 10; + END; + 'C' : BEGIN + Title := 'File Kbyte Downloaders'; + Header := 'Kbytes Downloaded'; + Decimal := 0; + Width := 10; + END; + 'D' : BEGIN + Title := 'Private Message Senders'; + Header := 'Private Messages Sent'; + Decimal := 0; + Width := 10; + END; + 'E' : BEGIN + Title := 'Public Message Posters'; + Header := 'Messages Posted'; + Decimal := 0; + Width := 10; + END; + 'F' : BEGIN + Title := 'SysOp Feedback Senders'; + Header := 'SysOp Feedback Sent'; + Decimal := 0; + Width := 10; + END; + 'G' : BEGIN + Title := 'All Time Callers'; + Header := 'Calls To The System'; + Decimal := 0; + Width := 10; + END; + 'H' : BEGIN + Title := 'File Uploaders'; + Header := 'Files Uploaded'; + Decimal := 0; + Width := 10; + END; + 'I' : BEGIN + Title := 'File Downloaders'; + Header := 'Files Downloaded'; + Decimal := 0; + Width := 10; + END; + 'J' : BEGIN + Title := 'File Points'; + Header := 'File Points On Hand'; + Decimal := 0; + Width := 10; + END; + 'K' : BEGIN + Title := 'Upload/Download Ratios'; + Header := 'KB Uploaded for Each KB Downloaded'; + Decimal := 2; + Width := 12; + END; + 'L' : BEGIN + Title := 'Post/Call Ratios'; + Header := 'Public Messages Posted Each Call'; + Decimal := 2; + Width := 12; + END; + END; + DisplayTop10UserArray(Top10User,Title,Header,Decimal,Width); + END + ELSE IF (MenuOption[1] = 'M') THEN + BEGIN + SearchTop20GlobalFileSpec(Top20File); + DisplayTop20FileArray(Top20File); + END; +END; + +END. \ No newline at end of file diff --git a/SOURCE/SYSOP1.PAS b/SOURCE/SYSOP1.PAS new file mode 100644 index 0000000..f6758a7 --- /dev/null +++ b/SOURCE/SYSOP1.PAS @@ -0,0 +1,831 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp1; + +INTERFACE + +PROCEDURE ProtocolEditor; + +IMPLEMENTATION + +USES + Common; + +PROCEDURE ProtocolEditor; +VAR + TempProtocol: ProtocolRecordType; + Cmd: Char; + RecNumToList: Integer; + SaveTempPause: Boolean; + + PROCEDURE ToggleXBFlag(XBFlagT: ProtocolFlagType; VAR XBFlags: PRFlagSet); + BEGIN + IF (XBFlagT IN XBFlags) THEN + Exclude(XBFlags,XBFlagT) + ELSE + Include(XBFlags,XBFlagT); + END; + + PROCEDURE ToggleXBFlags(C: Char; VAR XBFlags: PRFlagSet; VAR Changed: Boolean); + VAR + TempXBFlags: PRFlagSet; + BEGIN + TempXBFlags := XBFlags; + CASE C OF + '1' : ToggleXBFlag(ProtActive,XBFlags); + '2' : ToggleXBFlag(ProtIsBatch,XBFlags); + '3' : ToggleXBFlag(ProtIsResume,XBFlags); + '4' : ToggleXBFlag(ProtBiDirectional,XBFlags); + '5' : ToggleXBFlag(ProtReliable,XBFlags); + '6' : ToggleXBFlag(ProtXferOkCode,XBFlags); + END; + IF (XBFlags <> TempXBFlags) THEN + Changed := TRUE; + END; + + PROCEDURE InitProtocolVars(VAR Protocol: ProtocolRecordType); + VAR + Counter: BYTE; + BEGIN + FillChar(Protocol,SizeOf(Protocol),0); + WITH Protocol DO + BEGIN + PRFlags := [ProtXferOkCode]; + CKeys := '!'; + Description := '<< New Protocol >>'; + ACS := ''; + TempLog := ''; + DLoadLog := ''; + ULoadLog := ''; + DLCmd := ''; + ULCmd := ''; + FOR Counter := 1 TO 6 DO + BEGIN + DLCode[Counter] := ''; + ULCode[Counter] := ''; + END; + EnvCmd := ''; + DLFList := ''; + MaxChrs := 127; + TempLogPF := 0; + TempLogPS := 0; + END; + END; + + PROCEDURE DeleteProtocol(TempProtocol1: ProtocolRecordType; RecNumToDelete: SmallInt); + VAR + RecNum: Integer; + BEGIN + IF (NumProtocols = 0) THEN + Messages(4,0,'protocols') + ELSE + BEGIN + RecNumToDelete := -1; + InputIntegerWOC('%LFProtocol to delete?',RecNumToDelete,[NumbersOnly],1,NumProtocols); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= NumProtocols) THEN + BEGIN + Reset(ProtocolFile); + Seek(ProtocolFile,(RecNumToDelete - 1)); + Read(ProtocolFile,TempProtocol1); + Close(ProtocolFile); + LastError := IOResult; + Print('%LFProtocol: ^5'+TempProtocol1.Description); + IF PYNQ('%LFAre you sure you want to delete it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Deleting protocol record ...'); + Dec(RecNumToDelete); + Reset(ProtocolFile); + IF (RecNumToDelete >= 0) AND (RecNumToDelete <= (FileSize(ProtocolFile) - 2)) THEN + FOR RecNum := RecNumToDelete TO (FileSize(ProtocolFile) - 2) DO + BEGIN + Seek(ProtocolFile,(RecNum + 1)); + Read(ProtocolFile,Protocol); + Seek(ProtocolFile,RecNum); + Write(ProtocolFile,Protocol); + END; + Seek(ProtocolFile,(FileSize(ProtocolFile) - 1)); + Truncate(ProtocolFile); + Close(ProtocolFile); + LastError := IOResult; + Dec(NumProtocols); + SysOpLog('* Deleted Protocol: ^5'+TempProtocol1.Description); + END; + END; + END; + END; + + FUNCTION CmdOk(Protocol: ProtocolRecordType): Boolean; + VAR + Ok1: Boolean; + BEGIN + Ok1 := TRUE; + WITH Protocol DO + IF (DLCmd = 'ASCII') OR (DLCmd = 'BATCH') OR (DLCmd = 'EDIT') OR + (DLCmd = 'NEXT') OR (DLCmd = 'QUIT') OR (ULCmd = 'ASCII') OR + (ULCmd = 'BATCH') OR (ULCmd = 'EDIT') OR (ULCmd = 'NEXT') OR + (ULCmd = 'QUIT') THEN + OK1 := FALSE; + CmdOk := Ok1; + END; + + FUNCTION DLCodesEmpty(Protocol: ProtocolRecordType): Boolean; + VAR + Counter1: Byte; + BEGIN + DLCodesEmpty := TRUE; + FOR Counter1 := 1 TO 6 DO + IF (Protocol.DLCode[Counter1] <> '') THEN + DLCodesEmpty := FALSE; + END; + + FUNCTION ULCodesEmpty(Protocol: ProtocolRecordType): Boolean; + VAR + Counter1: Byte; + BEGIN + ULCodesEmpty := TRUE; + FOR Counter1 := 1 TO 6 DO + IF (Protocol.ULCode[Counter1] <> '') THEN + ULCodesEmpty := FALSE; + END; + + PROCEDURE CheckProtocol(Protocol: ProtocolRecordType; StartErrMsg,EndErrMsg: Byte; VAR Ok: Boolean); + VAR + Counter: Byte; + BEGIN + FOR Counter := StartErrMsg TO EndErrMsg DO + CASE Counter OF + 1 : IF (Protocol.Ckeys = '') THEN + BEGIN + Print('%LF^7The command keys are invalid!^1'); + Ok := FALSE; + END; + 2 : IF (Protocol.Description = '<< New Protocol >>') THEN + BEGIN + Print('%LF^7The description is invalid!^1'); + Ok := FALSE; + END; + 3 : IF (CmdOk(Protocol)) AND (ProtIsBatch IN Protocol.PRFLags) AND (Protocol.TempLog <> '') AND + (Protocol.TempLogPF = 0) THEN + BEGIN + Print('%LF^7You must specify the file name position if you utilize the Temp Log.^1'); + Ok := FALSE; + END; + 4 : IF (CmdOk(Protocol)) AND (ProtIsBatch IN Protocol.PRFLags) AND (Protocol.TempLog <> '') AND + (Protocol.TempLogPS = 0) THEN + BEGIN + Print('%LF^7You must specify the status position if you utilize the Temp Log.'); + Ok := FALSE; + END; + 5 : IF (CmdOk(Protocol)) AND (ProtIsBatch IN Protocol.PRFLags) AND (Protocol.TempLog <> '') AND + (DLCodesEmpty(Protocol)) THEN + BEGIN + Print('%LF^7You must specify L codes if you utilize the Temp. Log.^1'); + Ok := FALSE; + END; + 6 : IF (CMDOk(Protocol)) AND (ProtIsBatch IN Protocol.PRFlags) AND (Protocol.DLoadLog <> '') AND + (Protocol.TempLog = '') THEN + BEGIN + Print('%LF^7You must specify a Temp. Log if you utilize the L Log.^1'); + Ok := FALSE; + END; + 7 : IF (CmdOk(Protocol)) AND (NOT (ProtIsBatch IN Protocol.PRFlags)) AND (Protocol.ULCmd <> '') AND + (ULCodesEmpty(Protocol)) THEN + BEGIN + Print('%LF^7You must specify L Codes if you utilize the L Command.^1'); + Ok := FALSE; + END; + 8 : IF (CmdOk(Protocol)) AND (NOT (ProtIsBatch IN Protocol.PRFlags)) AND (Protocol.DLCmd <> '') AND + (DLCodesEmpty(Protocol)) THEN + BEGIN + Print('%LF^7You must specify L Codes if you utilize the L Command.^1'); + Ok := FALSE; + END; + 9 : IF (CmdOk(Protocol)) AND (ProtIsBatch IN Protocol.PRFlags) AND (Protocol.DLCmd <> '') AND + (Protocol.DLFList = '') THEN + BEGIN + Print('%LF^7You must specify a DL File List if you utilize the L Command.^1'); + Ok := FALSE; + END; + 10 : IF (CmdOk(Protocol)) AND (ProtIsBatch IN Protocol.PRFlags) AND (Protocol.DLCmd <> '') AND + (Protocol.MaxChrs = 0) THEN + BEGIN + Print('%LF^7You must specify the Max DOS Chars if you utilize the L Command.^1'); + Ok := FALSE; + END; + 11 : IF (Protocol.ULCmd = '') AND (Protocol.DLCmd = '') THEN + BEGIN + Print('%LF^7You must specify a L or L Command.^1'); + Ok := FALSE; + END; + 12 : IF (CmdOk(Protocol)) AND (NOT (ProtIsBatch IN Protocol.PRFlags)) AND (Protocol.DLCmd = '') AND + (NOT DLCodesEmpty(Protocol)) THEN + BEGIN + Print('%LF^7You must specify a L Command if you utilize L Codes.^1'); + Ok := FALSE; + END; + 13 : IF (CmdOk(Protocol)) AND (NOT (ProtIsBatch IN Protocol.PRFlags)) AND (Protocol.ULCmd = '') AND + (NOT ULCodesEmpty(Protocol)) THEN + BEGIN + Print('%LF^7You must specify a L Command if you utilize L Codes.^1'); + Ok := FALSE; + END; + 14 : IF (CmdOk(Protocol)) AND (ProtIsBatch IN Protocol.PRFlags) AND (Protocol.TempLog = '') AND + (NOT DLCodesEmpty(Protocol)) THEN + BEGIN + Print('%LF^7You must specify a Temp Log if you utilize L Codes.^1'); + Ok := FALSE; + END; + END; + END; + + PROCEDURE EditProtocol(TempProtocol1: ProtocolRecordType; VAR Protocol: ProtocolRecordType; VAR Cmd1: Char; + VAR RecNumToEdit: SmallInt; VAR Changed: Boolean; Editing: Boolean); + VAR + TempStr, + CmdStr: AStr; + Cmd2: Char; + Counter: Byte; + OK: Boolean; + BEGIN + WITH Protocol DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + MCIAllowed := FALSE; + Abort := FALSE; + Next := FALSE; + CLS; + IF (Editing) THEN + PrintACR('^5Editing protocol #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumProtocols)) + ELSE + PrintACR('^5Inserting protocol #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumProtocols + 1)); + NL; + PrintACR('^1!. Type/protocl: ^5'+ + AOnOff(ProtActive IN PRFlags,'Active','INACTIVE')+' - '+ + AOnOff(ProtIsBatch IN PRFlags,'Batch','Single')+ + AOnOff(ProtIsResume IN PRFlags,' - Resume','')+ + AOnOff(ProtBiDirectional IN PRFlags,' - Bidirectional','')+ + AOnOff(ProtReliable IN PRFlags,' - Reliable only','')); + PrintACR('^11. Keys/descrip: ^5'+CKeys+'^1 / ^5'+AOnOff(Description = '','*None*',Description)+'^1'); + PrintACR('^12. ACS required: ^5'+AOnOff(ACS = '','*None*',ACS)+'^1'); + IF (CmdOk(Protocol)) AND (ProtIsBatch IN PRFLags) THEN + BEGIN + PrintACR('^13. Temp. log : ^5'+AOnOff(TempLog = '','*None*',TempLog)); + IF (Protocol.TempLog <> '') THEN + PrintACR('^1 : File name position: ^5'+IntToStr(TempLogPF)+ + ' ^1/ Status position: ^5'+IntToStr(TempLogPS)); + END; + IF (CmdOk(Protocol)) AND (ProtIsBatch IN PRFLags) THEN + BEGIN + PrintACR('^14. L log : ^5'+AOnOff(ULoadLog = '','*None*',ULoadLog)); + PrintACR('^1 L log : ^5'+AOnOff(DLoadLog = '','*None*',DLoadLog)); + END; + PrintACR('^15. L command: ^5'+AOnOff(ULCmd = '','*None*',ULCmd)); + PrintACR('^1 L command: ^5'+AOnOff(DLCmd = '','*None*',DLCmd)); + IF (ProtIsBatch IN PRFLags) AND (CMDOk(Protocol)) AND (Protocol.DLCmd <> '') THEN + PrintACR('^1 : DL File List: ^5'+AOnOff(DLFList = '','*None*',DLFList)+ + ' ^1/ Max DOS chars: ^5'+IntToStr(MaxChrs)); + IF (CmdOk(Protocol)) THEN + PrintACR('^16. Codes mean : ^5'+AOnOff(ProtXferOkCode IN PRFlags,'Transfer Successful','Transfer Failed')); + IF (CmdOk(Protocol)) THEN + BEGIN + TempStr := '^17. L codes :'; + FOR Counter := 1 TO 3 DO + TempStr := TempStr + PadLeftStr('^1 ('+IntToStr(Counter)+') "^5'+ULCode[Counter]+'^1" ',13); + PrintACR(TempStr); + TempStr := '^1 :'; + FOR Counter := 4 TO 6 DO + TempStr := TempStr + PadLeftStr('^1 ('+IntToStr(Counter)+') "^5'+ULCode[Counter]+'^1" ',13); + PrintACR(TempStr); + TempStr := '^1 L codes :'; + FOR Counter := 1 TO 3 DO + TempStr := TempStr + PadLeftStr('^1 ('+IntToStr(Counter)+') "^5'+DLCode[Counter]+'^1" ',13); + PrintACR(TempStr); + TempStr := '^1 :'; + FOR Counter := 4 TO 6 DO + TempStr := TempStr + PadLeftStr('^1 ('+IntToStr(Counter)+') "^5'+DLCode[Counter]+'^1" ',13); + PrintACR(TempStr); + END; + IF (CmdOk(Protocol)) THEN + PrintACR('^18. Environ. cmd: ^5'+AOnOff(EnvCmd = '','*None*',EnvCmd)); + MCIAllowed := TRUE; + END; + IF (NOT Editing) THEN + CmdStr := '!12345678' + ELSE + CmdStr := '!12345678[]FJL'; + LOneK('%LFModify menu [^5?^4=^5Help^4]: ',Cmd1,'Q?'+CmdStr+^M,TRUE,TRUE); + CASE Cmd1 OF + '!' : BEGIN + REPEAT + Print('%LF^5Protocol types:^1'); + Print('%LF^11. Protocol active : ^5'+ShowYesNo(ProtActive IN PRFlags)); + Print('^12. Is batch protocol : ^5'+ShowYesNo(ProtIsBatch IN PRFlags)); + Print('^13. Is resume protocol: ^5'+ShowYesNo(ProtIsResume IN PRFlags)); + Print('^14. Is bidirectional : ^5'+ShowYesNo(ProtBiDirectional IN PRFlags)); + Print('^15. For reliable only : ^5'+ShowYesNo(ProtReliable IN PRFlags)); + LOneK('%LFNew protocol type? [^51^4-^55^4,^5^4=^5Quit^4]: ',Cmd1,^M'12345',TRUE,TRUE); + IF (Cmd1 IN ['1'..'5']) THEN + ToggleXBFlags(Cmd1,PRFlags,Changed); + UNTIL (Cmd1 = ^M) OR (HangUp); + Cmd1 := #0; + END; + '1' : BEGIN + REPEAT + Ok := TRUE; + TempProtocol1.Ckeys := CKeys; + InputWN1('%LFNew command keys: ',CKeys,(SizeOf(Ckeys) - 1),[InterActiveEdit],Changed); + CheckProtocol(Protocol,1,1,Ok); + IF (NOT Ok) THEN + Ckeys := TempProtocol1.Ckeys; + UNTIL (Ok) OR (HangUp); + REPEAT + Ok := TRUE; + TempProtocol1.Description := Description; + InputWNWC('%LFNew description: ',Description,(SizeOf(Description) - 1),Changed); + CheckProtocol(Protocol,2,2,Ok); + IF (NOT Ok) THEN + Description := TempProtocol1.Description; + UNTIL (Ok) OR (HangUp); + END; + '2' : InputWN1('%LFNew ACS: ',ACS,(SizeOf(ACS) - 1),[InterActiveEdit],Changed); + '3' : IF (CmdOk(Protocol)) AND (ProtIsBatch IN PRFlags) THEN + BEGIN + Print('%LFIf you specify a Temporary Log file, you must also'); + Print('specify the "File Name" position, "Status" position and'); + Print('the corresponding Batch L Codes.'); + InputWN1('%LFNew temporary log: ',TempLog,(SizeOf(TempLog) - 1),[InterActiveEdit],Changed); + IF (Protocol.TempLog = '') THEN + BEGIN + Protocol.TempLogPF := 0; + Protocol.TempLogPS := 0; + END; + IF (ProtIsBatch IN PRFLags) AND (CMDOk(Protocol)) AND (Protocol.TempLog <> '') THEN + BEGIN + REPEAT + Ok := TRUE; + TempProtocol1.TempLogPF := TempLogPF; + InputByteWC('%LFNew file name log position',TempLogPF,[DisplayValue,NumbersOnly],0,127,Changed); + CheckProtocol(Protocol,3,3,Ok); + IF (NOT Ok) THEN + TempLogPF := TempProtocol1.TempLogPF; + UNTIL (Ok) OR (HangUp); + REPEAT + Ok := TRUE; + TempProtocol1.TempLogPS := TempLogPS; + InputByteWC('%LFNew status log position',TempLogPS,[DisplayValue,NumbersOnly],0,127,Changed); + CheckProtocol(Protocol,4,4,Ok); + IF (NOT Ok) THEN + TempLogPS := TempProtocol1.TempLogPS; + UNTIL (Ok) OR (HangUp); + END; + END; + '4' : IF (CmdOk(Protocol)) AND (ProtIsBatch IN PRFlags) THEN + BEGIN + LOneK('%LFFile transfer type? [^5U^4=^5Upload^4,^5D^4=^5Download^4,^5^4=^5Quit^4]: ', + Cmd1,^M'UD',TRUE,TRUE); + CASE Cmd1 OF + 'U' : BEGIN + Print('%LF^7The permanent batch upload log is not utilized by Renegade!^1'); + PauseScr(FALSE); + END; + 'D' : BEGIN + Print('%LFIf you specify a permanent batch download log, you must also'); + Print('specify a temporary log.'); + InputWN1('%LFNew permanent download log: ',DLoadLog,(SizeOf(DloadLog) - 1), + [InterActiveEdit],Changed); + END; + END; + Cmd1 := #0; + END; + '5' : BEGIN + TempStr := #0; + LOneK('%LFFile transfer type? [^5U^4=^5Upload^4,^5D^4=^5Download^4,^5^4=^5Quit^4]: ', + Cmd1,^M'UD',TRUE,TRUE); + IF (Cmd1 <> ^M) THEN + BEGIN + LOneK('%LFFile transfer method? [^5E^4=^5External^4,^5I^4=^5Internal^4,^5O^4=^5Off^4,^5^4=^5Quit^4]: ', + Cmd2,^M'EIO',TRUE,TRUE); + CASE Cmd2 OF + 'E' : CASE Cmd1 OF + 'U' : BEGIN + TempStr := ULCmd; + IF (CmdOk(Protocol)) AND (NOT (ProtIsBatch IN PRFlags)) THEN + BEGIN + Print('%LFIf you specify an external single upload protocol, you must also'); + Print('specify single upload L codes.'); + END; + InputWN1('%LF^1New external upload protocol:%LF^4: ',TempStr,(SizeOf(DlCmd) - 1), + [InterActiveEdit],Changed); + END; + 'D' : BEGIN + TempStr := DLCmd; + IF (CmdOk(Protocol)) THEN + IF (ProtIsBatch IN PRFlags) THEN + BEGIN + Print('%LFIf you specify an external batch download protocol, you must'); + Print('also specify a batch file list and the maximum DOS characters'); + Print('allowed on the DOS commandline.'); + END + ELSE + BEGIN + Print('%LFIf you specify an external single download protocol, you must also'); + Print('specify single download L codes.'); + END; + InputWN1('%LF^1New external download protocol:%LF^4: ',TempStr,(SizeOf(DlCmd) - 1), + [InterActiveEdit],Changed); + IF (TempStr = '') THEN + BEGIN + Protocol.DLFList := ''; + Protocol.MaxChrs := 127; + END; + IF (CmdOk(Protocol)) AND (ProtIsBatch IN PRFlags) AND (TempStr <> '') THEN + BEGIN + REPEAT + Ok := TRUE; + TempProtocol1.DLFList := DLFList; + InputWN1('%LFNew batch file list: ',DLFList,(SizeOf(DLFList) - 1), + [InterActiveEdit],Changed); + CheckProtocol(Protocol,9,9,Ok); + IF (NOT Ok) THEN + DLFList := TempProtocol1.DLFList; + UNTIL (Ok) OR (HangUp); + REPEAT + Ok := TRUE; + TempProtocol1.MaxChrs := MaxChrs; + InputByteWC('%LFNew max DOS characters in commandline',MaxChrs, + [DisplayValue,NumbersOnly],0,127,Changed); + CheckProtocol(Protocol,10,10,Ok); + IF (NOT Ok) THEN + MaxChrs := TempProtocol1.MaxChrs; + UNTIL (Ok) OR (HangUp); + END; + END; + END; + 'I' : BEGIN + Print('%LF^5Internal protocol types:^1'); + NL; + LCmds(40,3,'ASCII',''); + LCmds(40,3,'BATCH',''); + LCmds(40,3,'EDIT',''); + LCmds(40,3,'NEXT',''); + LCmds(40,3,'QUIT',''); + LOneK('%LFNew internal protocol? [^5A^4,^5B^4,^5E^4,^5N^4,^5Q^4,^5^4=^5Quit^4]: ', + Cmd2,^M'ABENQ',TRUE,TRUE); + IF (Cmd2 <> ^M) THEN + CASE Cmd2 OF + 'A' : TempStr := 'ASCII'; + 'B' : TempStr := 'BATCH'; + 'E' : TempStr := 'EDIT'; + 'N' : TempStr := 'NEXT'; + 'Q' : TempStr := 'QUIT'; + END; + IF (Cmd2 <> ^M) THEN + Changed := TRUE; + Cmd2 := #0; + END; + 'O' : IF PYNQ('%LFSet to NULL string? ',0,FALSE) THEN + BEGIN + TempStr := ''; + Changed := TRUE; + END; + END; + IF (TempStr <> #0) THEN + CASE Cmd1 OF + 'D' : DLCmd := TempStr; + 'U' : ULCmd := TempStr; + END; + IF (NOT CmdOk(Protocol)) THEN + BEGIN + TempLog := ''; + ULoadLog := ''; + DLoadLog := ''; + FOR Counter := 1 TO 6 DO + BEGIN + ULCode[Counter] := ''; + DLCode[Counter] := ''; + END; + EnvCmd := ''; + DLFList := ''; + MaxChrs := 127; + TempLogPF := 0; + TempLogPS := 0; + END; + END; + Cmd1 := #0; + Cmd2 := #0; + END; + '6' : IF (CmdOk(Protocol)) THEN + ToggleXBFlags('6',PRFlags,Changed); + '7' : IF (CmdOk(Protocol)) THEN + BEGIN + LOneK('%LFFile transfer type? [^5U^4=^5Upload^4,^5D^4=^5Download^4,^5^4=^5Quit^4]: ', + Cmd1,'UD'^M,TRUE,TRUE); + CASE Cmd1 OF + 'U' : BEGIN + IF (ProtIsBatch IN PRFlags) THEN + BEGIN + Print('%LF^7The batch upload codes are not utilized by Renegade!^1'); + PauseScr(FALSE); + END + ELSE + BEGIN + Print('%LF^5New upload codes:^1'); + FOR Counter := 1 TO 6 DO + InputWN1('%LFCode #'+IntToStr(Counter)+': ',ULCode[Counter], + (SizeOf(ULCode[Counter]) - 1),[InterActiveEdit],Changed); + END; + END; + 'D' : BEGIN + Print('%LF^5New download codes:^1'); + FOR Counter := 1 TO 6 DO + InputWN1('%LFCode #'+IntToStr(Counter)+': ',DLCode[Counter], + (SizeOf(DlCode[Counter]) - 1),[InterActiveEdit],Changed); + END; + END; + Cmd1 := #0; + END; + '8' : IF (CmdOk(Protocol)) THEN + InputWN1('%LFNew environment setup commandline:%LF: ',EnvCmd,(SizeOf(EnvCmd) - 1),[InterActiveEdit],Changed); + '[' : IF (RecNumToEdit > 1) THEN + Dec(RecNumToEdit) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + ']' : IF (RecNumToEdit < NumProtocols) THEN + Inc(RecNumToEdit) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNumToEdit <> 1) THEN + RecNumToEdit := 1 + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + InputIntegerWOC('%LFJump to entry?',RecNumToEdit,[NumbersOnly],1,NumProtocols); + IF (RecNumToEdit < 1) OR (RecNumToEdit > NumProtocols) THEN + Cmd1 := #0; + END; + 'L' : IF (RecNumToEdit <> NumProtocols) THEN + RecNumToEdit := NumProtocols + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay current screen'); + Print('^31^1-^38^1:Modify item'); + IF (NOT Editing) THEN + LCmds(20,3,'Quit and save','') + ELSE + BEGIN + LCmds(20,3,'[Back entry',']Forward entry'); + LCmds(20,3,'First entry in list','Jump to entry'); + LCmds(20,3,'Last entry in list','Quit and save'); + END; + END; + END; + UNTIL (Pos(Cmd1,'Q[]FJL') <> 0) OR (HangUp); + END; + + PROCEDURE InsertProtocol(TempProtocol1: ProtocolRecordType; RecNumToInsertBefore: SmallInt); + VAR + Cmd1: Char; + RecNum, + RecNumToEdit: SmallInt; + Ok, + Changed: Boolean; + BEGIN + IF (NumProtocols = MaxProtocols) THEN + Messages(5,MaxProtocols,'protocols') + ELSE + BEGIN + RecNumToInsertBefore := -1; + InputIntegerWOC('%LFProtocol to insert before?',RecNumToInsertBefore,[NumbersOnly],1,(NumProtocols + 1)); + IF (RecNumToInsertBefore >= 1) AND (RecNumToInsertBefore <= (NumProtocols + 1)) THEN + BEGIN + Reset(ProtocolFile); + InitProtocolVars(TempProtocol1); + IF (RecNumToInsertBefore = 1) THEN + RecNumToEdit := 1 + ELSE IF (RecNumToInsertBefore = (NumProtocols + 1)) THEN + RecNumToEdit := (NumProtocols + 1) + ELSE + RecNumToEdit := RecNumToInsertBefore; + REPEAT + OK := TRUE; + EditProtocol(TempProtocol1,TempProtocol1,Cmd1,RecNumToEdit,Changed,FALSE); + CheckProtocol(TempProtocol1,1,14,Ok); + IF (NOT OK) THEN + IF (NOT PYNQ('%LFContinue inserting protocol? ',0,TRUE)) THEN + Abort := TRUE; + UNTIL (OK) OR (Abort) OR (HangUp); + IF (NOT Abort) AND (PYNQ('%LFIs this what you want? ',0,FALSE)) THEN + BEGIN + Print('%LF[> Inserting protocol record ...'); + Seek(ProtocolFile,FileSize(ProtocolFile)); + Write(ProtocolFile,Protocol); + Dec(RecNumToInsertBefore); + FOR RecNum := ((FileSize(ProtocolFile) - 1) - 1) DOWNTO RecNumToInsertBefore DO + BEGIN + Seek(ProtocolFile,RecNum); + Read(ProtocolFile,Protocol); + Seek(ProtocolFile,(RecNum + 1)); + Write(ProtocolFile,Protocol); + END; + FOR RecNum := RecNumToInsertBefore TO ((RecNumToInsertBefore + 1) - 1) DO + BEGIN + Seek(ProtocolFile,RecNum); + Write(ProtocolFile,TempProtocol1); + Inc(NumProtocols); + SysOpLog('* Inserted protocol: ^5'+TempProtocol1.Description); + END; + Close(ProtocolFile); + LastError := IOResult; + END; + END; + END; + END; + + PROCEDURE ModifyProtocol(TempProtocol1: ProtocolRecordType; Cmd1: Char; RecNumToEdit: SmallInt); + VAR + SaveRecNumToEdit: Integer; + Ok, + Changed: Boolean; + BEGIN + IF (NumProtocols = 0) THEN + Messages(4,0,'protocols') + ELSE + BEGIN + RecNumToEdit := -1; + InputIntegerWOC('%LFProtocol to modify?',RecNumToEdit,[NumbersOnly],1,NumProtocols); + IF (RecNumToEdit >= 1) AND (RecNumToEdit <= NumProtocols) THEN + BEGIN + SaveRecNumToEdit := -1; + Cmd1 := #0; + Reset(ProtocolFile); + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNumToEdit <> RecNumToEdit) THEN + BEGIN + Seek(ProtocolFile,(RecNumToEdit - 1)); + Read(ProtocolFile,Protocol); + SaveRecNumToEdit := RecNumToEdit; + Changed := FALSE; + END; + REPEAT + Ok := TRUE; + EditProtocol(TempProtocol1,Protocol,Cmd1,RecNumToEdit,Changed,TRUE); + CheckProtocol(Protocol,1,14,Ok); + IF (NOT OK) THEN + BEGIN + PauseScr(FALSE); + IF (RecNumToEdit <> SaveRecNumToEdit) THEN + RecNumToEdit := SaveRecNumToEdit; + END; + UNTIL (OK) OR (HangUp); + IF (Changed) THEN + BEGIN + Seek(ProtocolFile,(SaveRecNumToEdit - 1)); + Write(ProtocolFile,Protocol); + Changed := FALSE; + SysOpLog('* Modified protocol: ^5'+Protocol.Description); + END; + END; + Close(ProtocolFile); + LastError := IOResult; + END; + END; + END; + + PROCEDURE PositionProtocol(TempProtocol1: ProtocolRecordType; RecNumToPosition: SmallInt); + VAR + RecNumToPositionBefore, + RecNum1, + RecNum2: SmallInt; + BEGIN + IF (NumProtocols = 0) THEN + Messages(4,0,'protocols') + ELSE IF (NumProtocols = 1) THEN + Messages(6,0,'protocols') + ELSE + BEGIN + RecNumToPosition := -1; + InputIntegerWOC('%LFPosition which protocol?',RecNumToPosition,[NumbersOnly],1,NumProtocols); + IF (RecNumToPosition >= 1) AND (RecNumToPosition <= NumProtocols) THEN + BEGIN + RecNumToPositionBefore := -1; + Print('%LFAccording to the current numbering system.'); + InputIntegerWOC('%LFPosition before which protocol?',RecNumToPositionBefore,[NumbersOnly],1,(NumProtocols + 1)); + IF (RecNumToPositionBefore >= 1) AND (RecNumToPositionBefore <= (NumProtocols + 1)) AND + (RecNumToPositionBefore <> RecNumToPosition) AND (RecNumToPositionBefore <> (RecNumToPosition + 1)) THEN + BEGIN + Print('%LF[> Positioning protocol records ...'); + IF (RecNumToPositionBefore > RecNumToPosition) THEN + Dec(RecNumToPositionBefore); + Dec(RecNumToPosition); + Dec(RecNumToPositionBefore); + Reset(ProtocolFile); + Seek(ProtocolFile,RecNumToPosition); + Read(ProtocolFile,TempProtocol1); + RecNum1 := RecNumToPosition; + IF (RecNumToPosition > RecNumToPositionBefore) THEN + RecNum2 := -1 + ELSE + RecNum2 := 1; + WHILE (RecNum1 <> RecNumToPositionBefore) DO + BEGIN + IF ((RecNum1 + RecNum2) < FileSize(ProtocolFile)) THEN + BEGIN + Seek(ProtocolFile,(RecNum1 + RecNum2)); + Read(ProtocolFile,Protocol); + Seek(ProtocolFile,RecNum1); + Write(ProtocolFile,Protocol); + END; + Inc(RecNum1,RecNum2); + END; + Seek(ProtocolFile,RecNumToPositionBefore); + Write(ProtocolFile,TempProtocol1); + Close(ProtocolFile); + LastError := IOResult; + END; + END; + END; + END; + + PROCEDURE ListProtocols(VAR RecNumToList1: Integer); + VAR + NumDone: Integer; + BEGIN + IF (RecNumToList1 < 1) OR (RecNumToList1 > NumProtocols) THEN + RecNumToList1 := 1; + Abort := FALSE; + Next := FALSE; + CLS; + PrintACR('^0 ###^4:^3ACS ^4:^3Description'); + PrintACR('^4 ===:==========:============================================================='); + Reset(ProtocolFile); + NumDone := 0; + WHILE (NumDone < (PageLength - 5)) AND (RecNumToList1 >= 1) AND (RecNumToList1 <= NumProtocols) + AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(ProtocolFile,(RecNumToList1 - 1)); + Read(ProtocolFile,Protocol); + WITH Protocol DO + PrintACR(AOnOff((ProtActive IN PRFlags),'^5+','^1-')+ + '^0'+PadRightInt(RecNumToList1,3)+ + ' ^9'+PadLeftStr(ACS,10)+ + ' ^1'+Description); + Inc(RecNumToList1); + Inc(Numdone); + END; + Close(ProtocolFile); + LastError := IOResult; + IF (NumProtocols = 0) THEN + Print('*** No protocols defined ***'); + END; + +BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + RecNumToList := 1; + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + ListProtocols(RecNumToList); + LOneK('%LFProtocol editor [^5?^4=^5Help^4]: ',Cmd,'QDIMP?'^M,TRUE,TRUE); + CASE Cmd OF + ^M : IF (RecNumToList < 1) OR (RecNumToList > NumProtocols) THEN + RecNumToList := 1; + 'D' : DeleteProtocol(TempProtocol,RecNumToList); + 'I' : InsertProtocol(TempProtocol,RecNumToList); + 'M' : ModifyProtocol(TempProtocol,Cmd,RecNumToList); + 'P' : PositionProtocol(TempProtocol,RecNumToList); + '?' : BEGIN + Print('%LF^1<^3CR^1>Next screen or redisplay current screen'); + Print('^1(^3?^1)Help/First protocol'); + LCmds(16,3,'Delete protocol','Insert protocol'); + LCmds(16,3,'Modify protocol','Position protocol'); + LCmds(16,3,'Quit',''); + END; + END; + IF (Cmd <> ^M) THEN + RecNumToList := 1; + UNTIL (Cmd = 'Q') OR (HangUp); + TempPause := SaveTempPause; + LastError := IOResult; +END; + +END. diff --git a/SOURCE/SYSOP10.PAS b/SOURCE/SYSOP10.PAS new file mode 100644 index 0000000..9fa37e3 --- /dev/null +++ b/SOURCE/SYSOP10.PAS @@ -0,0 +1,746 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp10; + +INTERFACE + +PROCEDURE VotingEditor; + +IMPLEMENTATION + +USES + Common, + MiscUser; + +PROCEDURE VotingEditor; +VAR + TempTopic: VotingRecordType; + Cmd: Char; + RecNumToList: Byte; + SaveTempPause: Boolean; + + PROCEDURE InitTopicVars(VAR Topic: VotingRecordType); + VAR + User: UserRecordType; + Counter: Byte; + BEGIN + LoadURec(User,UserNum); + FillChar(Topic,SizeOf(Topic),0); + WITH Topic DO + BEGIN + Question1 := '<< New Voting Topic >>'; + Question2 := ''; + ACS := 'VV'; + ChoiceNumber := 0; + NumVotedQuestion := 0; + CreatedBy := Caps(User.Name); + AddAnswersACS := General.AddChoice; + FOR Counter := 1 TO MaxChoices DO + WITH Answers[Counter] DO + BEGIN + Answer1 := '<< New Topic Choice >>'; + Answer2 := ''; + NumVotedAnswer := 0; + END; + END; + END; + + PROCEDURE DeleteChoice(VAR Topic: VotingRecordType; RecNumToDelete: Byte; VAR Changed: Boolean); + VAR + User: UserRecordType; + RecNum, + RecNum1: Byte; + UNum: Integer; + BEGIN + IF (Topic.ChoiceNumber < 1) THEN + Messages(4,0,'topic choices') + ELSE + BEGIN + RecNum := 0; + InputByteWOC('%LFDelete which choice',RecNum,[Numbersonly],1,Topic.ChoiceNumber); + IF (RecNum >= 1) AND (RecNum <= Topic.ChoiceNumber) THEN + BEGIN + Dec(Topic.ChoiceNumber); + Dec(Topic.NumVotedQuestion,Topic.Answers[RecNum].NumVotedAnswer); + IF (RecNum < MaxChoices) THEN + FOR RecNum1 := RecNum TO Topic.ChoiceNumber DO + BEGIN + Topic.Answers[RecNum1].Answer1 := Topic.Answers[RecNum1 + 1].Answer1; + Topic.Answers[RecNum1].Answer2 := Topic.Answers[RecNum1 + 1].Answer2; + Topic.Answers[RecNum1].NumVotedAnswer := Topic.Answers[RecNum1 + 1].NumVotedAnswer; + END; + Reset(UserFile); + FOR UNum := 1 TO (FileSize(UserFile) - 1) DO + BEGIN + Seek(UserFile,Unum); + Read(UserFile,User); + IF (User.Vote[RecNumToDelete] = RecNum) THEN + User.Vote[RecNumToDelete] := 0 + ELSE IF (User.Vote[RecNumToDelete] > RecNum) THEN + Dec(User.Vote[RecNumToDelete]); + Seek(UserFile,UNum); + Write(UserFile,User); + END; + Close(UserFile); + IF (ThisUser.Vote[RecNumToDelete] = RecNum) THEN + ThisUser.Vote[RecNumToDelete] := 0; + Changed := TRUE; + END; + END; + END; + + PROCEDURE InsertChoice(VAR Topic: VotingRecordType; RecNumToEdit: Byte; VAR Changed: Boolean); + BEGIN + IF (Topic.ChoiceNumber >= MaxChoices) THEN + Messages(5,MaxChoices,'topic choices') + ELSE IF PYNQ('%LFAdd topic choice #'+IntToStr(Topic.ChoiceNumber + 1)+'? ',0,FALSE) THEN + BEGIN + InputWNWC('%LFChoice: ',Topic.Answers[Topic.ChoiceNumber + 1].Answer1,65,Changed); + IF (Topic.Answers[Topic.ChoiceNumber + 1].Answer1 <> '') THEN + BEGIN + Topic.Answers[Topic.ChoiceNumber + 1].NumVotedAnswer := 0; + InputWNWC(PadLeftStr('',6)+': ',Topic.Answers[Topic.ChoiceNumber + 1].Answer2,65,Changed); + Inc(Topic.ChoiceNumber); + END; + Changed := TRUE; + END; + END; + + PROCEDURE CheckChoice(Topic: VotingRecordType; RecNum1: Byte; StartErrMsg,EndErrMsg: Byte; VAR Ok: Boolean); + VAR + Counter: Byte; + BEGIN + FOR Counter := StartErrMsg TO EndErrMsg DO + CASE Counter OF + 1 : IF (Topic.Answers[RecNum1].Answer1 = '') OR (Topic.Answers[RecNum1].Answer1 = '<< New Topic Choice >>') THEN + BEGIN + Print('%LF^7The answer is invalid!^1'); + OK := FALSE; + END; + END; + END; + + PROCEDURE ModifyChoice(TempTopic1: VotingRecordType; VAR Topic: VotingRecordType; RecNumToEdit: Byte; VAR Changed: Boolean); + VAR + Cmd1: Char; + RecNum: Byte; + Ok: Boolean; + BEGIN + IF (Topic.ChoiceNumber < 1) THEN + Messages(4,0,'topic choices') + ELSE + BEGIN + RecNum := 0; + InputByteWOC('%LFModify which choice',RecNum,[Numbersonly],1,Topic.ChoiceNumber); + IF (RecNum >= 1) AND (RecNum <= Topic.ChoiceNumber) THEN + BEGIN + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + Print('%CL^5Topic choice #'+IntToStr(RecNum)+' of '+IntToStr(Topic.ChoiceNumber)); + NL; + PrintACR('^11. Choice: ^5'+Topic.Answers[RecNum].Answer1); + IF (Topic.Answers[RecNum].Answer2 <> '') THEN + PrintACR('^1 : ^5'+Topic.Answers[RecNum].Answer2); + PrintACR('^12. Voters: ^5'+IntToStr(Topic.Answers[RecNum].NumVotedAnswer)); + END; + LOneK('%LFModify menu [^5?^4=^5Help^4]: ',Cmd1,'Q12[]FJL?'^M,TRUE,TRUE); + CASE Cmd1 OF + '1' : BEGIN + REPEAT + TempTopic1.Answers[RecNum].Answer1 := Topic.Answers[RecNum].Answer1; + Ok := TRUE; + InputWNWC('%LFNew choice: ',Topic.Answers[RecNum].Answer1, + (SizeOf(Topic.Answers[RecNum].Answer1) - 1),Changed); + CheckChoice(Topic,RecNum,1,1,Ok); + IF (NOT Ok) THEN + Topic.Answers[RecNum].Answer1 := TempTopic1.Answers[RecNum].Answer1; + UNTIL (Ok) OR (HangUp); + IF (Topic.Answers[RecNum].Answer1 <> '') THEN + InputWNWC(PadLeftStr('',10)+': ',Topic.Answers[Recnum].Answer2, + (SizeOf(Topic.Answers[RecNum].Answer2) - 1),Changed); + END; + '2' : InputIntegerWC('%LFNew number of voters',Topic.Answers[RecNum].NumVotedAnswer,[DisplayValue,NumbersOnly],0, + (MaxUsers - 1),Changed); + '[' : IF (RecNum > 1) THEN + Dec(RecNum) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + ']' : IF (RecNum < Topic.ChoiceNumber) THEN + Inc(RecNum) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNum <> 1) THEN + RecNum := 1 + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + InputByteWOC('%LFJump to entry',RecNum,[Numbersonly],1,Topic.ChoiceNumber); + IF (RecNum < 1) OR (RecNum > Topic.ChoiceNumber) THEN + Cmd1 := #0; + END; + 'L' : IF (RecNum <> Topic.ChoiceNumber) THEN + RecNum := Topic.ChoiceNumber + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay screen'); + Print('^31-2^1:Modify item'); + LCmds(20,3,'[Back entry',']Forward entry'); + LCmds(20,3,'First entry in list','Jump to entry'); + LCmds(20,3,'Last entry in list','Quit and save'); + END; + END; + UNTIL (Cmd1 = 'Q') OR (HangUp); + END; + END; + END; + + PROCEDURE ListChoices(VAR Topic: VotingRecordType; VAR RecNumToList1: Byte); + VAR + NumDone: Byte; + BEGIN + IF (RecNumToList1 < 1) OR (RecNumToList1 > Topic.ChoiceNumber) THEN + RecNumToList1 := 1; + Abort := FALSE; + Next := FALSE; + CLS; + PrintACR('^0##^4:^3Answer^4:^3Choice'); + PrintACR('^4==:======:====================================================================='); + NumDone := 0; + WHILE (NumDone < (PageLength - 5)) AND (RecNumToList1 >= 1) AND (RecNumToList1 <= Topic.ChoiceNumber) + AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + PrintACR('^0'+PadRightInt(RecNumToList1,2)+ + ' ^3'+PadRightInt(Topic.Answers[RecNumToList1].NumVotedAnswer,6)+ + ' ^5'+Topic.Answers[RecNumToList1].Answer1); + WKey; + Inc(RecNumToList1); + Inc(NumDone); + END; + IF (Topic.ChoiceNumber = 0) THEN + Print('*** No voting choices defined ***'); + END; + + PROCEDURE ChoiceEditor(TempTopic1: VotingRecordType; VAR Topic: VotingRecordType; Cmd1: Char; + RecNumToEdit: Byte; VAR Changed: Boolean); + VAR + RecNumToList1: Byte; + BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + RecNumToList1 := 1; + Cmd1 := #0; + REPEAT + IF (Cmd1 <> '?') THEN + ListChoices(Topic,RecNumToList1); + LOneK('%LFTopic choice editor [^5?^4=^5Help^4]: ',Cmd1,'QDIM?'^M,TRUE,TRUE); + CASE Cmd1 OF + ^M : IF (RecNumToList1 < 1) OR (RecNumToList1 > Topic.ChoiceNumber) THEN + RecNumToList1 := 1; + 'D' : DeleteChoice(Topic,RecNumToEdit,Changed); + 'I' : InsertChoice(Topic,RecNumToEdit,Changed); + 'M' : ModifyChoice(TempTopic1,Topic,RecNumToEdit,Changed); + '?' : BEGIN + Print('%LF^1<^3CR^1>Next screen or redisplay current screen'); + Print('^1(^3?^1)Help/First topic choice'); + LCmds(20,3,'Delete topic choice','Insert topic choice'); + LCmds(20,3,'Modify topic choice','Quit'); + END; + END; + IF (Cmd1 <> ^M) THEN + RecNumToList1 := 1; + UNTIL (Cmd1 = 'Q') OR (HangUp); + TempPause := SaveTempPause; + END; + + PROCEDURE DeleteTopic(TempTopic1: VotingRecordType; RecNumToDelete: Byte); + VAR + User: UserRecordType; + RecNum: Integer; + BEGIN + IF (NumVotes = 0) THEN + Messages(4,0,'voting topics') + ELSE + BEGIN + RecNumToDelete := 0; + InputByteWOC('%LFVoting topic to delete',RecNumToDelete,[NumbersOnly],1,NumVotes); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= NumVotes) THEN + BEGIN + Reset(VotingFile); + Seek(VotingFile,(RecNumToDelete - 1)); + Read(VotingFile,TempTopic1); + Close(VotingFile); + LastError := IOResult; + Print('%LF^1Voting topic: ^5'+TempTopic1.Question1); + IF (TempTopic1.Question2 <> '') THEN + Print('^1'+PadLeftStr('',12)+': ^5'+TempTopic1.Question2); + IF PYNQ('%LFAre you sure you want to delete it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Deleting voting topic record ...'); + Dec(RecNumToDelete); + Reset(VotingFile); + IF (RecNumToDelete >= 0) AND (RecNumToDelete <= (FileSize(VotingFile) - 2)) THEN + FOR RecNum := RecNumToDelete TO (FileSize(VotingFile) - 2) DO + BEGIN + Seek(VotingFile,(RecNum + 1)); + Read(VotingFile,Topic); + Seek(VotingFile,RecNum); + Write(VotingFile,Topic); + END; + Seek(VotingFile,(FileSize(VotingFile) - 1)); + Truncate(VotingFile); + Close(VotingFile); + LastError := IOResult; + SysOpLog('* Deleted topic: ^5'+TempTopic1.Question1); + IF (Topic.Question2 <> '') THEN + SysOpLog(PadLeftStr('',15)+': ^5'+TempTopic1.Question2); + Reset(UserFile); + FOR RecNum := 1 TO (FileSize(UserFile) - 1) DO + BEGIN + Seek(UserFile,RecNum); + Read(UserFile,User); + Move(User.Vote[RecNumToDelete + 1],User.Vote[RecNumToDelete],(MaxVotes - RecNumToDelete)); + User.Vote[25] := 0; + Seek(UserFile,RecNum); + Write(UserFile,User); + END; + Close(UserFile); + LastError := IOResult; + Move(ThisUser.Vote[RecNumToDelete + 1],ThisUser.Vote[RecNumToDelete],(MaxVotes - RecNumToDelete)); + ThisUser.Vote[25] := 0; + Dec(NumVotes); + END; + END; + END; + END; + + PROCEDURE CheckTopic(Topic: VotingRecordType; StartErrMsg,EndErrMsg: Byte; VAR Ok: Boolean); + VAR + Counter, + Counter1: Byte; + BEGIN + FOR Counter := StartErrMsg TO EndErrMsg DO + CASE Counter OF + 1 : IF (Topic.Question1 = '') OR (Topic.Question1 = '<< New Voting Topic >>') THEN + BEGIN + Print('%LF^7The question is invalid!^1'); + OK := FALSE; + END; + 2 : IF (Topic.ChoiceNumber = 0) THEN + BEGIN + Print('%LF^7You must setup choices for your topic!^1'); + OK := FALSE; + END; + END; + END; + + PROCEDURE EditTopic(TempTopic1: VotingRecordType; VAR Topic: VotingRecordType; VAR Cmd1: Char; + VAR RecNumToEdit: Byte; VAR Changed: Boolean; Editing: Boolean); + VAR + User: UserRecordType; + CmdStr: AStr; + Unum: Integer; + Ok: Boolean; + BEGIN + WITH Topic DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + CLS; + IF (Editing) THEN + PrintACR('^5Editing voting topic #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumVotes)) + ELSE + PrintACR('^5Inserting voting topic #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumVotes + 1)); + NL; + PrintACR('^11. Topic : ^5'+Question1); + IF (Question2 <> '') THEN + PrintACR('^1'+PadLeftStr('',16)+': ^5'+Question2); + PrintACR('^12. Creator : ^5'+CreatedBy); + PrintACR('^13. ACS to vote : ^5'+AOnOff(ACS = '','*None*',ACS)); + PrintACR('^14. ACS to add : ^5'+AOnOff(AddAnswersACS = '','*None*',AddAnswersACS)); + PrintACR('^15. Total votes : ^5'+IntToStr(NumVotedQuestion)); + Print('%LF^1[Choices on this topic: ^5'+IntToStr(ChoiceNumber)+'^1]'); + END; + IF (NOT Editing) THEN + CmdStr := '12345C' + ELSE + CmdStr := '12345C[]FJL'; + LOneK('%LFModify menu [^5C^4=^5Choice Editor^4,^5?^4=^5Help^4]: ',Cmd1,'Q?'+CmdStr+^M,TRUE,TRUE); + CASE Cmd1 OF + '1' : BEGIN + REPEAT + TempTopic1.Question1 := Question1; + Ok := TRUE; + InputWNWC('%LFNew topic: ',Question1,(SizeOf(Question1) - 1),Changed); + CheckTopic(Topic,1,1,Ok); + IF (NOT Ok) THEN + Question1 := TempTopic1.Question1; + UNTIL (Ok) OR (HangUp); + IF (Question1 <> '') THEN + InputWNWC(PadLeftStr('',9)+': ',Question2,(SizeOf(Question2) - 1),Changed); + END; + '2' : BEGIN + Print('%LF^5New creator of this topic (1-'+IntToStr(MaxUsers - 1)+')?^1'); + Print('%LFEnter User Number, Name, or Partial Search String.'); + Prt(': '); + lFindUserWS(Unum); + IF (Unum < 1) THEN + PauseScr(FALSE) + ELSE + BEGIN + LoadURec(User,UNum); + IF (CreatedBy <> Caps(User.Name)) THEN + IF (PYNQ('%LFSet the new creator name to '+Caps(User.Name)+'? ',0,FALSE)) THEN + BEGIN + CreatedBy := Caps(User.Name); + Changed := TRUE; + END; + END; + END; + '3' : InputWN1('%LFNew voting ACS: ',ACS,(SizeOf(ACS) - 1),[InterActiveEdit],Changed); + '4' : IF PYNQ('%LFAllow other users to add choices? ',0,FALSE) THEN + AddAnswersACS := ACS + ELSE + AddAnswersACS := General.AddChoice; + '5' : InputIntegerWOC('%LFNew number of voters',NumVotedQuestion,[DisplayValue,NumbersOnly],0,(MaxUsers - 1)); + 'C' : ChoiceEditor(TempTopic1,Topic,Cmd1,RecNumToEdit,Changed); + '[' : IF (RecNumToEdit > 1) THEN + Dec(RecNumToEdit) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + ']' : IF (RecNumToEdit < NumVotes) THEN + Inc(RecNumToEdit) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNumToEdit <> 1) THEN + RecNumToEdit := 1 + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + InputByteWOC('%LFJump to entry',RecNumToEdit,[NumbersOnly],1,NumVotes); + IF (RecNumToEdit < 1) OR (RecNumToEdit > NumVotes) THEN + Cmd1 := #0; + END; + 'L' : IF (RecNumToEdit <> NumVotes) THEN + RecNumToEdit := NumVotes + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay current screen'); + Print('^31^1-^35^1,^3C^1:Modify item'); + IF (NOT Editing) THEN + LCmds(20,3,'Quit and save','') + ELSE + BEGIN + LCmds(20,3,'[Back entry',']Forward entry'); + LCmds(20,3,'First entry in list','Jump to entry'); + LCmds(20,3,'Last entry in list','Quit and save'); + END; + END; + END; + UNTIL (Pos(Cmd1,'Q[]FJL') <> 0) OR (HangUp); + END; + + PROCEDURE InsertTopic(TempTopic1: VotingRecordType; Cmd1: Char; RecNumToInsertBefore: Byte); + VAR + RecNumToEdit: Byte; + Ok, + Changed: Boolean; + BEGIN + IF (NumVotes = MaxVotes) THEN + Messages(5,MaxVotes,'voting topics') + ELSE IF (PYNQ('%LFAdd voting topic #'+IntToStr(NumVotes + 1)+'? ',0,FALSE)) THEN + BEGIN + Reset(VotingFile); + InitTopicVars(TempTopic1); + RecNumToInsertBefore := (FileSize(VotingFile) + 1); + IF (RecNumToInsertBefore = 1) THEN + RecNumToedit := 1 + ELSE IF (RecNumToInsertBefore = (NumVotes + 1)) THEN + RecNumToEdit := (NumVotes + 1) + ELSE + RecNumToEdit := RecNumToInsertBefore; + REPEAT + OK := TRUE; + EditTopic(TempTopic1,TempTopic1,Cmd1,RecNumToEdit,Changed,FALSE); + CheckTopic(TempTopic1,1,2,Ok); + IF (NOT OK) THEN + IF (NOT PYNQ('%LFContinue inserting topic? ',0,TRUE)) THEN + Abort := TRUE; + UNTIL (OK) OR (Abort) OR (HangUp); + IF (NOT Abort) AND (PYNQ('%LFIs this what you want? ',0,FALSE)) THEN + BEGIN + Print('%LF[> Inserting voting topic record ...'); + Seek(VotingFile,FileSize(VotingFile)); + Write(VotingFile,TempTopic1); + Close(VotingFile); + LastError := IOResult; + Inc(NumVotes); + SysOpLog('* Inserted topic: ^5'+TempTopic1.Question1); + IF (TempTopic1.Question2 <> '') THEN + SysOpLog(PadLeftStr('',16)+': ^5'+TempTopic1.Question2); + END; + END; + END; + + PROCEDURE ModifyTopic(TempTopic1: VotingRecordType; Cmd1: Char; RecNumToEdit: Byte); + VAR + SaveRecNumToEdit: Byte; + Ok, + Changed: Boolean; + BEGIN + IF (NumVotes = 0) THEN + Messages(4,0,'voting topics') + ELSE + BEGIN + RecNumToEdit := 0; + InputByteWOC('%LFModify which topic',RecNumToEdit,[NumbersOnly],1,NumVotes); + IF (RecNumToEdit >= 1) AND (RecNumToEdit <= NumVotes) THEN + BEGIN + SaveRecNumToEdit := 0; + Cmd1 := #0; + Reset(VotingFile); + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNumToEdit <> RecNumToEdit) THEN + BEGIN + Seek(VotingFile,(RecNumToEdit - 1)); + Read(VotingFile,Topic); + SaveRecNumToEdit := RecNumToEdit; + Changed := FALSE; + END; + REPEAT + Ok := TRUE; + EditTopic(TempTopic1,Topic,Cmd1,RecNumToEdit,Changed,TRUE); + CheckTopic(Topic,1,2,Ok); + IF (NOT OK) THEN + BEGIN + PauseScr(FALSE); + IF (RecNumToEdit <> SaveRecNumToEdit) THEN + RecNumToEdit := SaveRecNumToEdit; + END; + UNTIL (Ok) OR (HangUp); + IF (Changed) THEN + BEGIN + Seek(VotingFile,(SaveRecNumToEdit - 1)); + Write(VotingFile,Topic); + Changed := FALSE; + SysOpLog('* Modified topic: ^5'+Topic.Question1); + IF (Topic.Question2 <> '') THEN + SysOpLog(PadLeftStr('',16)+': ^5'+Topic.Question2); + END; + END; + Close(VotingFile); + LastError := IOResult; + END; + END; + END; + + PROCEDURE ResetTopic(RecNumToReset: Byte); + VAR + User: UserRecordType; + RecNum: Byte; + UNum: Integer; + BEGIN + IF (NumVotes = 0) THEN + Messages(4,0,'voting topics') + ELSE + BEGIN + RecNumToReset := 0; + InputByteWOC('%LFReset which topic',RecNumToReset,[NumbersOnly],1,NumVotes); + IF (RecNumToReset >= 1) AND (RecNumToReset <= NumVotes) THEN + BEGIN + Reset(VotingFile); + Seek(VotingFile,(RecNumToReset - 1)); + Read(VotingFile,Topic); + Close(VotingFile); + Print('%LF^1Voting topic: ^5'+Topic.Question1); + IF (Topic.Question2 <> '') THEN + Print('^1'+PadLeftStr('',12)+': ^5'+Topic.Question2); + IF PYNQ('%LFAre you sure you want to reset it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Resetting voting topic record ...'); + Reset(VotingFile); + Seek(VotingFile,(RecNumToReset - 1)); + Read(VotingFile,Topic); + Topic.NumVotedQuestion := 0; + FOR RecNum := 1 TO Topic.ChoiceNumber DO + Topic.Answers[RecNum].NumVotedAnswer := 0; + Seek(VotingFile,(RecNumToReset - 1)); + Write(VotingFile,Topic); + Close(VotingFile); + Reset(UserFile); + FOR UNum := 1 TO (FileSize(UserFile) - 1) DO + BEGIN + Seek(UserFile,Unum); + Read(UserFile,User); + User.Vote[RecNumToReset] := 0; + Seek(UserFile,UNum); + Write(UserFile,User); + END; + Close(UserFile); + ThisUser.Vote[RecNumToReset] := 0; + SysOpLog('* Reset topic: ^5'+Topic.Question1); + IF (Topic.Question2 <> '') THEN + SysOpLog(PadLeftStr('',13)+': ^5'+Topic.Question2); + END; + END; + END; + END; + + PROCEDURE RecalculateTopics; + VAR + User: UserRecordType; + RecNum, + RecNum1: Byte; + UNum: Integer; + BEGIN + IF (NumVotes = 0) THEN + Messages(4,0,'voting topics') + ELSE IF (PYNQ('%LFRecalculate all voting topics? ',0,FALSE)) THEN + BEGIN + Print('%LF[> Recalculating all voting topics ...'); + Reset(VotingFile); + FOR RecNum := 1 TO NumVotes DO + BEGIN + Reset(VotingFile); + Seek(VotingFile,(RecNum - 1)); + Read(VotingFile,Topic); + Topic.NumVotedQuestion := 0; + FOR RecNum1 := 1 TO Topic.ChoiceNumber DO + Topic.Answers[RecNum1].NumVotedAnswer := 0; + Seek(VotingFile,(RecNum - 1)); + Write(VotingFile,Topic); + END; + Close(VotingFile); + Reset(VotingFile); + Reset(UserFile); + FOR UNum := 1 TO (FileSize(UserFile) - 1) DO + BEGIN + Seek(UserFile,Unum); + Read(UserFile,User); + IF (Deleted IN User.SFlags) THEN + BEGIN + FOR RecNum := 1 TO MaxVotes DO + User.Vote[RecNum] := 0; + END + ELSE + BEGIN + FOR RecNum := 1 TO NumVotes DO + IF (User.Vote[RecNum] <> 0) THEN + BEGIN + Seek(VotingFile,(RecNum - 1)); + Read(VotingFile,Topic); + Inc(Topic.NumVotedQuestion); + Inc(Topic.Answers[User.Vote[RecNum]].NumVotedAnswer); + Seek(VotingFile,(RecNum - 1)); + Write(VotingFile,Topic); + END; + END; + Seek(UserFile,Unum); + Write(UserFile,User); + END; + Close(UserFile); + Close(VotingFile); + SysOpLog('* Recalculated all voting topics.'); + END; + END; + + PROCEDURE ListTopics(VAR RecNumToList1: Byte); + VAR + NumDone: Byte; + BEGIN + IF (RecNumToList1 < 1) OR (RecNumToList1 > NumVotes) THEN + RecNumToList1 := 1; + Abort := FALSE; + Next := FALSE; + CLS; + PrintACR('^0##^4:^3Votes^4:^3Topic'); + PrintACR('^4==:=====:======================================================================'); + Reset(VotingFile); + NumDone := 0; + WHILE (NumDone < (PageLength - 5)) AND (RecNumToList1 >= 1) AND (RecNumToList1 <= NumVotes) + AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(VotingFile,(RecNumToList1 - 1)); + Read(VotingFile,Topic); + WITH Topic DO + PrintACR('^0'+PadRightInt(RecNumToList1,2)+ + '^3'+PadRightInt(NumVotedQuestion,6)+ + '^5 '+Question1); + WKey; + Inc(RecNumToList1); + Inc(NumDone); + END; + Close(VotingFile); + LastError := IOResult; + IF (NumVotes = 0) THEN + Print('*** No voting topics defined ***'); + END; + +BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + RecNumToList := 1; + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + ListTopics(RecNumToList); + LOneK('%LFVoting topic editor [^5?^4=^5Help^4]: ',Cmd,'QDIMRS?'^M,TRUE,TRUE); + CASE Cmd OF + ^M : IF (RecNumToList < 1) OR (RecNumToList > NumVotes) THEN + RecNumToList := 1; + 'D' : DeleteTopic(TempTopic,RecNumToList); + 'I' : InsertTopic(TempTopic,Cmd,RecNumToList); + 'M' : ModifyTopic(TempTopic,Cmd,RecNumToList); + 'R' : ResetTopic(RecNumToList); + 'S' : RecalculateTopics; + '?' : BEGIN + Print('%LF^1<^3CR^1>Next screen or redisplay current screen'); + Print('^1(^3?^1)Help/First voting topic'); + LCmds(20,3,'Delete voting topic','Insert voting topic'); + LCmds(20,3,'Modify voting topic','Quit'); + LCmds(20,3,'Reset voting topic','SRecalculate voting topics'); + END; + END; + IF (Cmd <> ^M) THEN + RecNumToList := 1; + UNTIL (Cmd = 'Q') OR (HangUp); + TempPause := SaveTempPause; + LastError := IOResult; +END; + +END. diff --git a/SOURCE/SYSOP11.PAS b/SOURCE/SYSOP11.PAS new file mode 100644 index 0000000..932fa84 --- /dev/null +++ b/SOURCE/SYSOP11.PAS @@ -0,0 +1,77 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp11; + +INTERFACE + +PROCEDURE ChangeUser; +PROCEDURE ShowLogs; + +IMPLEMENTATION + +USES + Common, + TimeFunc, + MiscUser; + +PROCEDURE ChangeUser; +VAR + UNum: Integer; +BEGIN + Prt('Change to which User (1-'+IntToStr(MaxUsers - 1)+'): '); + FindUser(UNum); + IF (UNum >= 1) THEN + BEGIN + SaveURec(ThisUser,UserNum); + LoadURec(ThisUser,UNum); + UserNum := UNum; + ChopTime := 0; + ExtraTime := 0; + FreeTime := 0; + IF (ComPortSpeed > 0) THEN + SysOpLog('---> ^7Switched accounts to: ^5'+Caps(ThisUser.Name)); + Update_Screen; + NewCompTables; + LoadNode(ThisNode); + WITH NodeR DO + BEGIN + User := UserNum; + UserName := ThisUser.Name; + END; + SaveNode(ThisNode); + END; +END; + +PROCEDURE ShowLogs; +VAR + TempStr: Str10; + Day: Word; +BEGIN + NL; + Print('SysOp Logs available for up to '+IntToStr(General.BackSysOpLogs)+' days ago.'); + Prt('Date (MM/DD/YYYY) or # days ago (0-'+IntToStr(General.BackSysOpLogs)+') [0]: '); + Input(TempStr,10); + IF (Length(TempStr) = 10) AND (DayNum(TempStr) > 0) THEN + Day := (DayNum(DateStr) - DayNum(TempStr)) + ELSE + Day := StrToInt(TempStr); + AllowContinue := TRUE; + IF (Day = 0) THEN + PrintF(General.LogsPath+'SYSOP.LOG') + ELSE + PrintF(General.LogsPath+'SYSOP'+IntToStr(Day)+'.LOG'); + AllowContinue := FALSE; + IF (NoFile) THEN + BEGIN + NL; + Print('SysOp log not found.'); + END; + IF (UserOn) THEN + SysOpLog('Viewed SysOp Log - '+AOnOff(Day = 0,'Today''s',IntToStr(Day)+' days ago')); +END; + +END. diff --git a/SOURCE/SYSOP12.PAS b/SOURCE/SYSOP12.PAS new file mode 100644 index 0000000..46c9a31 --- /dev/null +++ b/SOURCE/SYSOP12.PAS @@ -0,0 +1,566 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} +UNIT SysOp12; + +INTERFACE + +USES + Common; + +FUNCTION FindConference(Key: Char; VAR Conference: ConferenceRecordType): Boolean; +FUNCTION ShowConferences: AStr; +PROCEDURE ChangeConference(MenuOption: Str50); +PROCEDURE ConferenceEditor; + +IMPLEMENTATION + +FUNCTION FindConference(Key: Char; VAR Conference: ConferenceRecordType): Boolean; +VAR + RecNumToList: Integer; + Found: Boolean; +BEGIN + Found := FALSE; + Reset(ConferenceFile); + RecNumToList := 1; + WHILE (RecNumToList <= NumConfKeys) AND (NOT Found) DO + BEGIN + Seek(ConferenceFile,(RecNumToList - 1)); + Read(ConferenceFile,Conference); + IF (Key = Conference.Key) THEN + Found := TRUE; + Inc(RecNumToList); + END; + Close(ConferenceFile); + LastError := IOResult; + FindConference := Found; +END; + +FUNCTION ShowConferences: AStr; +VAR + TempStr: AStr; + RecNumToList: Integer; +BEGIN + Abort := FALSE; + Next := FALSE; + TempStr := ''; + Reset(ConferenceFile); + RecNumToList := 1; + WHILE (RecNumToList <= NumConfKeys) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(ConferenceFile,(RecNumToList - 1)); + Read(ConferenceFile,Conference); + IF AACS(Conference.ACS) THEN + BEGIN + TempStr := TempStr + Conference.Key; + IF (RecNumToList < NumConfKeys) THEN + TempStr := TempStr + ','; + END; + Inc(RecNumToList); + END; + Close(ConferenceFile); + LastError := IOResult; + IF (TempStr[Length(TempStr)] = ',') THEN + Dec(TempStr[0]); + ShowConferences := TempStr; +END; + +PROCEDURE DisplayConferenceRecords(RecNumToList: Integer; DisplayListNum: Boolean); +VAR + TempStr: AStr; + NumOnline: Byte; +BEGIN + AllowContinue := TRUE; + Abort := FALSE; + Next := FALSE; + CLS; + IF (DisplayListNum) THEN + BEGIN + PrintACR('^0##^4:^3C^4:^3Name ^0##^4:^3C^4:^3Name'); + PrintACR('^4==:=:============================== ==:=:=============================='); + END + ELSE + BEGIN + PrintACR(' ^3C^4:^3Name ^3C^4:^3Name'); + PrintACR(' ^4=:============================== =:=============================='); + END; + Reset(ConferenceFile); + TempStr := ''; + NumOnline := 0; + RecNumToList := 1; + WHILE (RecNumToList <= NumConfKeys) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(ConferenceFile,(RecNumToList - 1)); + Read(ConferenceFile,Conference); + IF (DisplayListNum) THEN + TempStr := TempStr + PadLeftStr('^0'+PadRightInt(RecNumToList,2)+ + ' ^3'+Conference.Key+ + ' ^5'+Conference.Name,37) + ELSE + TempStr := TempStr + PadLeftStr(' ^3'+Conference.Key+ + ' ^5'+Conference.Name,34); + Inc(NumOnline); + IF (NumOnline = 2) THEN + BEGIN + PrintaCR(TempStr); + NumOnline := 0; + TempStr := ''; + END; + Inc(RecNumToList); + END; + Close(ConferenceFile); + LastError := IOResult; + AllowContinue := FALSE; + IF (NumOnline = 1) AND (NOT Abort) AND (NOT HangUp) THEN + PrintaCR(TempStr); + IF (NumConfKeys = 0) AND (NOT Abort) AND (NOT HangUp) THEN + Print('^7No conference records.'); +END; + +PROCEDURE ChangeConference(MenuOption: Str50); +VAR + OneKCmds: AStr; + Cmd: Char; + RecNumToList: Integer; +BEGIN + MenuOption := AllCaps(SQOutSp(MenuOption)); + IF (MenuOption <> '') THEN + Cmd := MenuOption[1] + ELSE + Cmd := #0; + IF (Cmd <> #0) AND (Cmd <> '?') AND (NOT (Cmd IN ConfKeys)) THEN + BEGIN + Print('%NLCommand error, operation aborted!'); + SysOpLog('^7Change conference cmd error, invalid options: "'+Cmd+'".'); + Exit; + END; + IF (Cmd = '?') THEN + BEGIN + PrintF('CONFLIST'); + IF (NoFile) THEN + DisplayConferenceRecords(RecNumToList,FALSE); + END + ELSE IF (Cmd IN ConfKeys) AND FindConference(Cmd,Conference) THEN + BEGIN + IF ((AACS(Conference.ACS))) THEN + BEGIN + CurrentConf := Cmd; + ThisUser.LastConf := CurrentConf; + END; + END + ELSE + BEGIN + OneKCmds := ''; + FOR Cmd := '@' TO 'Z' DO + IF (Cmd IN ConfKeys) THEN + OneKCmds := OneKCmds + Cmd; + Print('%LF^4Current conference: ^5%CT - %CN'); + REPEAT + LOneK('%LFJoin which conference? (^5?^4=^5List^4,<^5CR^4>=^5Quit^4): ',Cmd,^M'?'+OneKCmds,TRUE,TRUE); + IF (Cmd = '?') THEN + BEGIN + PrintF('CONFLIST'); + IF (NoFile) THEN + DisplayConferenceRecords(RecNumToList,FALSE); + END + ELSE IF (Cmd IN ConfKeys) AND FindConference(Cmd,Conference) THEN + IF (NOT AACS(Conference.ACS)) THEN + Print('%LF^7You do not have the required access level for this conference!^1') + ELSE + BEGIN + CurrentConf := Cmd; + ThisUser.LastConf := CurrentConf; + PrintF('CONF'+Cmd); + IF (NoFile) THEN + Print('%LFJoined conference: ^5%CT - %CN'); + Cmd := ^M; + END; + UNTIL (Cmd = ^M) OR (HangUp); + END; + NewCompTables; +END; + +PROCEDURE ConferenceEditor; +VAR + TempConference: ConferenceRecordType; + Cmd: Char; + RecNumToList: Integer; + + PROCEDURE InitConferenceVars(VAR Conference: ConferenceRecordType); + BEGIN + FillChar(Conference,SizeOf(Conference),0); + WITH Conference DO + BEGIN + Key := ' '; + Name := '<< New Conference Record >>'; + ACS := '' + END; + END; + + PROCEDURE DeleteConference(TempConference1: ConferenceRecordType; RecNumToDelete: SmallInt); + VAR + User: UserRecordType; + RecNum: Integer; + BEGIN + IF (NumConfKeys = 0) THEN + Messages(4,0,'conference records') + ELSE + BEGIN + RecNumToDelete := -1; + InputIntegerWOC('%LFConference record to delete?',RecNumToDelete,[NumbersOnly],1,NumConfKeys); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= NumConfKeys) THEN + BEGIN + Reset(ConferenceFile); + Seek(ConferenceFile,(RecNumToDelete - 1)); + Read(ConferenceFile,TempConference1); + Close(ConferenceFile); + LastError := IOResult; + IF (TempConference1.Key = '@') THEN + BEGIN + Print('%LF^7You can not delete the general conference key!^1'); + PauseScr(FALSE); + END + ELSE + BEGIN + Print('%LFConference record: ^5'+TempConference1.Name); + IF PYNQ('%LFAre you sure you want to delete it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Deleting conference record ...'); + FOR RecNum := 1 TO (MaxUsers - 1) DO + BEGIN + LoadURec(User,RecNum); + IF (User.LastConf = TempConference1.Key) THEN + User.LastConf := '@'; + SaveURec(User,RecNum); + END; + Exclude(ConfKeys,TempConference1.Key); + Dec(RecNumToDelete); + Reset(ConferenceFile); + IF (RecNumToDelete >= 0) AND (RecNumToDelete <= (FileSize(ConferenceFile) - 2)) THEN + FOR RecNum := RecNumToDelete TO (FileSize(ConferenceFile) - 2) DO + BEGIN + Seek(ConferenceFile,(RecNum + 1)); + Read(ConferenceFile,Conference); + Seek(ConferenceFile,RecNum); + Write(ConferenceFile,Conference); + END; + Seek(ConferenceFile,(FileSize(ConferenceFile) - 1)); + Truncate(ConferenceFile); + Close(ConferenceFile); + LastError := IOResult; + Dec(NumConfKeys); + SysOpLog('* Deleted conference: ^5'+TempConference1.Name); + END; + END; + END; + END; + END; + + PROCEDURE CheckConference(Conference: ConferenceRecordType; StartErrMsg,EndErrMsg: Byte; VAR Ok: Boolean); + VAR + Counter: Byte; + BEGIN + FOR Counter := StartErrMsg TO EndErrMsg DO + CASE Counter OF + 1 : IF (Conference.Name = '') OR (Conference.Name = '<< New Conference Record >>') THEN + BEGIN + Print('%LF^7The description is invalid!^1'); + OK := FALSE; + END; + END; + END; + + PROCEDURE EditConference(TempConference1: ConferenceRecordType; VAR Conference: ConferenceRecordType; VAR Cmd1: Char; + VAR RecNumToEdit: SmallInt; VAR Changed: Boolean; Editing: Boolean); + VAR + CmdStr: AStr; + Ok: Boolean; + BEGIN + WITH Conference DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + CLS; + IF (Editing) THEN + PrintACR('^5Editing conference record #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumConfKeys)) + ELSE + PrintACR('^5Inserting conference record #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumConfKeys + 1)); + NL; + PrintACR('^1A. Key : ^5'+Key); + PrintACR('^1B. Description: ^5'+Name); + PrintACR('^1C. ACS : ^5'+AOnOff(ACS = '','*None*',ACS)); + END; + IF (NOT Editing) THEN + CmdStr := 'ABC' + ELSE + CmdStr := 'ABC[]FJL'; + LOneK('%LFModify menu [^5?^4=^5Help^4]: ',Cmd1,'Q?'+CmdStr+^M,TRUE,TRUE); + CASE Cmd1 OF + 'A' : BEGIN + Print('%LF^7You can not modify the conference key.'); + PauseScr(FALSE); + END; + 'B' : REPEAT + TempConference1.Name := Conference.Name; + OK := TRUE; + InputWNWC('%LFNew description: ',Name,(SizeOf(Name) - 1),Changed); + CheckConference(Conference,1,1,Ok); + IF (NOT Ok) THEN + Conference.Name := TempConference1.Name; + UNTIL (OK) OR (HangUp); + 'C' : InputWN1('%LFNew ACS: ',ACS,(SizeOf(ACS) - 1),[InterActiveEdit],Changed); + '[' : IF (RecNumToEdit > 1) THEN + Dec(RecNumToEdit) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + ']' : IF (RecNumToEdit < NumConfKeys) THEN + Inc(RecNumToEdit) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNumToEdit <> 1) THEN + RecNumToEdit := 1 + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + InputIntegerWOC('%LFJump to entry',RecNumToEdit,[NumbersOnly],1,NumConfKeys); + IF (RecNumToEdit < 1) OR (RecNumToEdit > NumConfKeys) THEN + Cmd1 := #0; + END; + 'L' : IF (RecNumToEdit <> NumConfKeys) THEN + RecNumToEdit := NumConfKeys + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay current screen'); + Print('^3A^1-^3C^1:Modify item'); + IF (NOT Editing) THEN + LCmds(20,3,'Quit and save','') + ELSE + BEGIN + LCmds(20,3,'[Back entry',']Forward entry'); + LCmds(20,3,'First entry in list','Jump to entry'); + LCmds(20,3,'Last entry in list','Quit and save'); + END; + END; + END; + UNTIL (Pos(Cmd1,'Q[]FJL') <> 0) OR (HangUp); + END; + + PROCEDURE InsertConference(TempConference1: ConferenceRecordType; Cmd1: Char; RecNumToInsertBefore: SmallInt); + VAR + OneKCmds: AStr; + RecNum, + RecNumToEdit: SmallInt; + Ok, + Changed: Boolean; + BEGIN + IF (NumConfKeys = MaxConfKeys) THEN + Messages(5,MaxConfKeys,'conference records') + ELSE + BEGIN + RecNumToInsertBefore := -1; + InputIntegerWOC('%LFConference record to insert before?',RecNumToInsertBefore,[NumbersOnly],1,(NumConfKeys + 1)); + IF (RecNumToInsertBefore >= 1) AND (RecNumToInsertBefore <= (NumConfKeys + 1)) THEN + BEGIN + OneKCmds := ''; + FOR Cmd1 := '@' TO 'Z' DO + IF (NOT (Cmd1 IN ConfKeys)) THEN + OneKCmds := OneKCmds + Cmd1; + LOneK('%LFChoose conference key [^5@^4-^5Z^4,^5^4=^5Quit^4]: ',Cmd1,^M+OneKCmds,TRUE,TRUE); + IF (Cmd1 <> ^M) THEN + BEGIN + Reset(ConferenceFile); + InitConferenceVars(TempConference1); + TempConference1.Key := Cmd1; + IF (RecNumToInsertBefore = 1) THEN + RecNumToEdit := 1 + ELSE IF (RecNumToInsertBefore = (NumConfKeys + 1)) THEN + RecNumToEdit := (NumConfKeys + 1) + ELSE + RecNumToEdit := RecNumToInsertBefore; + REPEAT + OK := TRUE; + EditConference(TempConference1,TempConference1,Cmd1,RecNumToEdit,Changed,FALSE); + CheckConference(TempConference1,1,1,Ok); + IF (NOT OK) THEN + IF (NOT PYNQ('%LFContinue inserting conference record? ',0,TRUE)) THEN + Abort := TRUE; + UNTIL (OK) OR (Abort) OR (HangUp); + IF (NOT Abort) AND (PYNQ('%LFIs this what you want? ',0,FALSE)) THEN + BEGIN + Print('%LF[> Inserting conference record ...'); + Include(ConfKeys,Cmd1); + Seek(ConferenceFile,FileSize(ConferenceFile)); + Write(ConferenceFile,Conference); + Dec(RecNumToInsertBefore); + FOR RecNum := ((FileSize(ConferenceFile) - 1) - 1) DOWNTO RecNumToInsertBefore DO + BEGIN + Seek(ConferenceFile,RecNum); + Read(ConferenceFile,Conference); + Seek(ConferenceFile,(RecNum + 1)); + Write(ConferenceFile,Conference); + END; + FOR RecNum := RecNumToInsertBefore TO ((RecNumToInsertBefore + 1) - 1) DO + BEGIN + Seek(ConferenceFile,RecNum); + Write(ConferenceFile,TempConference1); + Inc(NumConfKeys); + SysOpLog('* Inserted conference: ^5'+TempConference1.Name); + END; + END; + Close(ConferenceFile); + LastError := IOResult; + END; + END; + END; + END; + + PROCEDURE ModifyConference(TempConference1: ConferenceRecordType; Cmd1: Char; RecNumToEdit: SmallInt); + VAR + SaveRecNumToEdit: Integer; + Ok, + Changed: Boolean; + BEGIN + IF (NumConfKeys = 0) THEN + Messages(4,0,'conference records') + ELSE + BEGIN + RecNumToEdit := -1; + InputIntegerWOC('%LFConference record to modify?',RecNumToEdit,[NumbersOnly],1,NumConfKeys); + IF (RecNumToEdit >= 1) AND (RecNumToEdit <= NumConfKeys) THEN + BEGIN + SaveRecNumToEdit := -1; + Cmd1 := #0; + Reset(ConferenceFile); + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNumToEdit <> RecNumToEdit) THEN + BEGIN + Seek(ConferenceFile,(RecNumToEdit - 1)); + Read(ConferenceFile,Conference); + SaveRecNumToEdit := RecNumToEdit; + Changed := FALSE; + END; + REPEAT + Ok := TRUE; + EditConference(TempConference1,Conference,Cmd1,RecNumToEdit,Changed,TRUE); + CheckConference(Conference,1,1,Ok); + IF (NOT OK) THEN + BEGIN + PauseScr(FALSE); + IF (RecNumToEdit <> SaveRecNumToEdit) THEN + RecNumToEdit := SaveRecNumToEdit; + END; + UNTIL (OK) OR (HangUp); + IF (Changed) THEN + BEGIN + Seek(ConferenceFile,(SaveRecNumToEdit - 1)); + Write(ConferenceFile,Conference); + Changed := FALSE; + SysOpLog('* Modified conference: ^5'+Conference.Name); + END; + END; + Close(ConferenceFile); + LastError := IOResult; + END; + END; + END; + + PROCEDURE PositionConference(TempConference1: ConferenceRecordType; RecNumToPosition: SmallInt); + VAR + RecNumToPositionBefore, + RecNum1, + RecNum2: SmallInt; + BEGIN + IF (NumConfKeys = 0) THEN + Messages(4,0,'conference records') + ELSE IF (NumConfKeys = 1) THEN + Messages(6,0,'conference records') + ELSE + BEGIN + RecNumToPosition := -1; + InputIntegerWOC('%LFPosition which conference record?',RecNumToPosition,[NumbersOnly],1,NumConfKeys); + IF (RecNumToPosition >= 1) AND (RecNumToPosition <= NumConfKeys) THEN + BEGIN + RecNumToPositionBefore := -1; + Print('%LFAccording to the current numbering system.'); + InputIntegerWOC('%LFPosition before which conference record?',RecNumToPositionBefore, + [NumbersOnly],1,(NumConfKeys + 1)); + IF (RecNumToPositionBefore >= 1) AND (RecNumToPositionBefore <= (NumConfKeys + 1)) AND + (RecNumToPositionBefore <> RecNumToPosition) AND (RecNumToPositionBefore <> (RecNumToPosition + 1)) THEN + BEGIN + Print('%LF[> Positioning conference records ...'); + Reset(ConferenceFile); + IF (RecNumToPositionBefore > RecNumToPosition) THEN + Dec(RecNumToPositionBefore); + Dec(RecNumToPosition); + Dec(RecNumToPositionBefore); + Seek(ConferenceFile,RecNumToPosition); + Read(ConferenceFile,TempConference1); + RecNum1 := RecNumToPosition; + IF (RecNumToPosition > RecNumToPositionBefore) THEN + RecNum2 := -1 + ELSE + RecNum2 := 1; + WHILE (RecNum1 <> RecNumToPositionBefore) DO + BEGIN + IF ((RecNum1 + RecNum2) < FileSize(ConferenceFile)) THEN + BEGIN + Seek(ConferenceFile,(RecNum1 + RecNum2)); + Read(ConferenceFile,Conference); + Seek(ConferenceFile,RecNum1); + Write(ConferenceFile,Conference); + END; + Inc(RecNum1,RecNum2); + END; + Seek(ConferenceFile,RecNumToPositionBefore); + Write(ConferenceFile,TempConference1); + Close(ConferenceFile); + LastError := IOResult; + END; + END; + END; + END; + +BEGIN + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + DisplayConferenceRecords(RecNumToList,TRUE); + LOneK('%LFConference editor [^5?^4=^5Help^4]: ',Cmd,'QDIMP?'^M,TRUE,TRUE); + CASE Cmd OF + 'D' : DeleteConference(TempConference,RecNumToList); + 'I' : InsertConference(TempConference,Cmd,RecNumToList); + 'M' : ModifyConference(TempConference,Cmd,RecNumToList); + 'P' : PositionConference(TempConference,RecNumToList); + '?' : BEGIN + Print('%LF^1<^3CR^1>Next Screen or redisplay screen'); + Print('^1(^3?^1)Help/First conference'); + LCmds(18,3,'Delete conference','Insert conference'); + LCmds(18,3,'Modify conference','Position conference'); + LCmds(18,3,'Quit',''); + END; + END; + IF (Cmd <> ^M) THEN + RecNumToList := 1; + UNTIL (Cmd = 'Q') OR (HangUp); + LastError := IOResult; +END; + +END. \ No newline at end of file diff --git a/SOURCE/SYSOP2.PAS b/SOURCE/SYSOP2.PAS new file mode 100644 index 0000000..75c1275 --- /dev/null +++ b/SOURCE/SYSOP2.PAS @@ -0,0 +1,95 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT SysOp2; + +INTERFACE + +PROCEDURE SystemConfigurationEditor; + +IMPLEMENTATION + +USES + Common, + SysOp2A, + SysOp2B, + SysOp2C, + SysOp2D, + SysOp2E, + SysOp2F, + SysOp2G, + SysOp2H, + SysOp2I, + SysOp2J, + SysOp2K, + SysOp2L, + SysOp2M, + SysOp2O, + Maint; + + { + 1. RGSysCfgStr(0,FALSE) + + %CL^5System Configuration:^1 + + ^1A. Main BBS Configuration B. Modem/Node Configuration + ^1C. System ACS Settings D. System Variables + ^1E. System Toggles F. File System Configuration + ^1G. Subscription/Validation System H. Network Configuration + ^1I. Offline Mail Configuration J. Color Configuration + ^1K. Archive Configuration L. Credit System Configuration + ^1M. New User Log-In Toggles + + ^11. Time allowed per %CD 2. Max calls per day + ^13. UL/DL # files ratio 4. UL/DL K-bytes ratio + ^15. Post/Call ratio 6. Max downloads per day + ^17. Max download kbytes per day 8. Update System Averages + + Enter selection [^5A^4-^5M^4,^51^4-^58^4,^5Q^4=^5Quit^4]: @ + + } + +PROCEDURE SystemConfigurationEditor; +VAR + Cmd: Char; +BEGIN + REPEAT + SaveGeneral(TRUE); + WITH General DO + BEGIN + Abort := FALSE; + Next := FALSE; + RGSysCfgStr(0,FALSE); + OneK(Cmd,'QABCDEFGHIJKLM12345678'^M,TRUE,TRUE); + CASE Cmd OF + 'A' : MainBBSConfiguration; + 'B' : ModemConfiguration; + 'C' : SystemACSSettings; + 'D' : SystemGeneralVariables; + 'E' : SystemFlaggedFunctions; + 'F' : FileAreaConfiguration; + 'G' : ValidationEditor; + 'H' : NetworkConfiguration; + 'I' : OffLineMailConfiguration; + 'J' : ColorConfiguration; + 'K' : ArchiveConfiguration; + 'L' : CreditConfiguration; + 'M' : NewUserTogglesConfiguration; + '1' : GetSecRange(1,TimeAllow); + '2' : GetSecRange(2,CallAllow); + '3' : GetSecRange(3,DLRatio); + '4' : GetSecRange(4,DLKratio); + '5' : GetSecRange(5,PostRatio); + '6' : GetSecRange(6,DLOneDay); + '7' : GetSecRange(7,DLKOneDay); + '8' : UpdateGeneral; + END; + END; + SaveGeneral(FALSE); + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +END. diff --git a/SOURCE/SYSOP2A.PAS b/SOURCE/SYSOP2A.PAS new file mode 100644 index 0000000..d7809c8 --- /dev/null +++ b/SOURCE/SYSOP2A.PAS @@ -0,0 +1,427 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp2A; + +INTERFACE + +PROCEDURE MainBBSConfiguration; + +IMPLEMENTATION + +USES + Crt, + Common, + SysOp7, + TimeFunc; + + { + RGSysCfgStr(1,FALSE) + + $Main_BBS_Configuration + %CL^5Main BBS Configuration:^1 + + ^1A. BBS name/number : ^5%BN ^1(^5%BP^1) + ^1B. Telnet Url : ^5%TN + ^1C. SysOp's name : ^5%SN{15 ^1D. Renegade Version : ^5%VR + ^1E. SysOp chat hours : ^5%CS ^1F. Minimum baud hours : ^5%BL + ^1G. Regular DL hours : ^5%DH ^1H. Minimum baud DL hrs: ^5%BM + ^1I. BBS Passwords : ^1J. Pre-event warning : ^5%ET seconds + ^1K. System Menus : ^1L. Bulletin Prefix : ^5%PB + ^1M. MultiNode support: ^5%MN ^1N. Network mode : ^5%NM + + ^10. Main data files dir. : ^5%PD + ^11. Miscellaneous Files dir.: ^5%PM + ^12. Message file storage dir: ^5%P1 + ^13. Nodelist (Version 7) dir: ^5%P2 + ^14. Log files/trap files dir: ^5%PL + ^15. Temporary directory : ^5%PT + ^16. Protocols directory : ^5%PP + ^17. Archivers directory : ^5%P7 + ^18. File attach directory : ^5%PF + ^19. RAM drive/MultiNode path: ^5%P3 + + Enter selection [^5A^4-^5N^4,^50^4-^59^4,^5Q^4=^5Quit^4]: @ + $ + + RGSysCfgStr(2,TRUE) + + $Main_BBS_Configuration_BBS_Name + %LFNew BBS name: @ + $ + + RGSysCfgStr(3,TRUE) + + $Main_BBS_Configuration_BBS_Phone + %LFNew BBS phone number: @ + $ + + RGSysCfgStr(4,TRUE) + + $Main_BBS_Configuration_Telnet_URL + %LF^4New Telnet Url:%LF^4: @ + $ + + RGSysCfgStr(5,TRUE) + + $Main_BBS_Configuration_SysOp_Name + %LFNew SysOp name: @ + $ + + RGNoteStr(0,FALSE) + + $Internal_Use_Only + %LF^7This is for internal use only. + %PA + $ + + RGNoteStr(1,FALSE) + + $Only_Change_Locally + %LF^7This can only be changed locally. + %PA + $ + + RGSysCfgStr(6,TRUE) + + $Main_BBS_Configuration_SysOp_Chat_Hours + %LFDo you want to declare sysop chat hours? @ + $ + + RGSysCfgStr(7,TRUE) + + $Main_BBS_Configuration_Minimum_Baud_Hours + %LFDo you want to declare hours people at the minimum baud can logon? @ + $ + + RGSysCfgStr(8,TRUE) + + $Main_BBS_Configuration_Download_Hours + %LFDo you want to declare download hours? @ + $ + + RGSysCfgStr(9,TRUE) + + $Main_BBS_Configuration_Minimum_Baud_Download_Hours + %LFDo you want to declare hours people at minimum baud can download? @ + $ + + RGSysCfgStr(10,FALSE) + + $Main_BBS_Configuration_SysOp_Password_Menu + %CL^5System Passwords:^1 + + ^1A. SysOp password : ^5%P4 + ^1B. New user password : ^5%P5 + ^1C. Baud override password: ^5%P6 + + Enter selection [^5A^4-^5C^4,^5Q^4=^5Quit^4]: @ + $ + + RGSysCfgStr(11,TRUE) + + $Main_BBS_Configuration_SysOp_Password + %LFNew SysOp password: @ + $ + + RGSysCfgStr(12,TRUE) + + $Main_BBS_Configuration_New_User_Password + %LFNew new-user password: @ + $ + + RGSysCfgStr(13,TRUE) + + $Main_BBS_Configuration_Baud_Override_Password + %LFNew minimum baud rate override password: @ + $ + + RGSysCfgStr(14,TRUE) + + $Main_BBS_Configuration_Pre_Event_Time + %LFNew pre-event warning time@ + $ + + RGSysCfgStr(15,FALSE) + + $Main_BBS_Configuration_System_Menus + %CL^5System Menus:^1 + + ^11. Global : ^5%M1 + ^12. All Start : ^5%M2 + ^13. Shutle logon : ^5%M3 + ^14. New user info: ^5%M4 + ^15. Message Read : ^5%M5 + ^16. File List : ^5%M6 + + Enter selection [^51^4-^56^4,^5Q^4=^5Quit^4]: @ + $ + + RGSysCfgStr(16,TRUE) + + $Main_BBS_Configuration_System_Menus_Global + %LFMenu for global commands (0=None)@ + $ + + RGSysCfgStr(17,TRUE) + + $Main_BBS_Configuration_System_Menus_Start + %LFMenu to start all users at@ + $ + + RGSysCfgStr(18,TRUE) + + $Main_BBS_Configuration_System_Menus_Shuttle + %LFMenu for shuttle logon (0=None)@ + $ + + RGSysCfgStr(19,TRUE) + + $Main_BBS_Configuration_System_Menus_New_User + %LFMenu for new user information@ + $ + + RGSysCfgStr(20,TRUE) + + $Main_BBS_Configuration_System_Menus_Message_Read + %LFMenu for message read@ + $ + + RGSysCfgStr(21,TRUE) + + $Main_BBS_Configuration_System_Menus_File_Listing + %LFMenu for file listing@ + $ + + RGNoteStr(2,FALSE) + + $Invalid_Menu_Number + %LF^7Invalid menu number. + %PA + $ + + RGSysCfgStr(22,TRUE) + + $Main_BBS_Configuration_Bulletin_Prefix + %LFDefault bulletin prefix: @ + $ + + RGNoteStr(1,FALSE) + + $Only_Change_Locally + %LF^7This can only be changed locally. + %PA + $ + + RGSysCfgStr(23,TRUE) + + $Main_BBS_Configuration_Local_Security + %LFDo you want local security to remain on? @ + $ + + RGSysCfgStr(24,TRUE) + + $Main_BBS_Configuration_Data_Path + %LF^4New data files path (^5End with a ^4"^5\^4"):%LF^4: @ + $ + + RGSysCfgStr(25,TRUE) + + $Main_BBS_Configuration_Misc_Path + %LF^4New miscellaneous files path (^5End with a ^4"^5\^4"):%LF^4: @ + $ + + RGSysCfgStr(26,TRUE) + + $Main_BBS_Configuration_Msg_Path + %LF^4New message files path (^5End with a ^4"^5\^4"):%LF^4: @ + $ + + RGSysCfgStr(27,TRUE) + + $Main_BBS_Configuration_NodeList_Path + %LF^4New nodelist files path (^5End with a ^4"^5\^4"):%LF^4: @ + $ + + RGSysCfgStr(28,TRUE) + + $Main_BBS_Configuration_Log_Path + %LF^4New sysop log files path (^5End with a ^4"^5\^4"):%LF^4: @ + $ + + RGSysCfgStr(29,TRUE) + + $Main_BBS_Configuration_Temp_Path + %LF^4New temporary files path (^5End with a ^4"^5\^4"):%LF^4: @ + $ + + RGSysCfgStr(30,TRUE) + + $Main_BBS_Configuration_Protocol_Path + %LF^4New protocol files path (^5End with a ^4"^5\^4"):%LF^4: @ + $ + + RGSysCfgStr(31,TRUE) + + $Main_BBS_Configuration_Archive_Path + %LF^4New archive files path (^5End with a ^4"^5\^4"):%LF^4: @ + $ + + RGSysCfgStr(32,TRUE) + + $Main_BBS_Configuration_Attach_Path + %LF^4New file attach files path (^5End with a ^4"^5\^4"):%LF^4: @ + $ + + RGSysCfgStr(33,TRUE) + + $Main_BBS_Configuration_MultNode_Path + %LF^4New multi-node files path (^5End with a ^4"^5\^4"):%LF^4: @ + $ + + } + + PROCEDURE GetTimeRange(CONST RGStrNum: LongInt; VAR LoTime,HiTime: SmallInt); + VAR + TempStr: Str5; + LowTime, + HighTime: Integer; + BEGIN + IF (NOT (PYNQ(RGSysCfgStr(RGStrNum,TRUE),0,FALSE))) THEN + BEGIN + LowTime := 0; + HighTime := 0; + END + ELSE + BEGIN + NL; + Print('All entries in 24 hour time. Hour: (0-23), Minute: (0-59)'); + NL; + Prt('Starting time: '); + MPL(5); + InputFormatted('',TempStr,'##:##',TRUE); + IF (StrToInt(Copy(TempStr,1,2)) IN [0..23]) AND (StrToInt(Copy(TempStr,4,2)) IN [0..59]) THEN + LowTime := ((StrToInt(Copy(TempStr,1,2)) * 60) + StrToInt(Copy(TempStr,4,2))) + ELSE + LowTime := 0; + NL; + Prt('Ending time: '); + MPL(5); + InputFormatted('',TempStr,'##:##',TRUE); + IF (StrToInt(Copy(TempStr,1,2)) IN [0..23]) AND (StrToInt(Copy(TempStr,4,2)) IN [0..59]) THEN + HighTime := ((StrToInt(Copy(TempStr,1,2)) * 60) + StrToInt(Copy(TempStr,4,2))) + ELSE + HighTime := 0; + END; + NL; + Print('Hours: '+PHours('Always allowed',LowTime,HighTime)); + NL; + IF PYNQ('Are you sure this is what you want? ',0,FALSE) THEN + BEGIN + LoTime := LowTime; + HiTime := HighTime; + END; + END; + +PROCEDURE MainBBSConfiguration; +VAR + LineFile: FILE OF LineRec; + Cmd: Char; + Changed: Boolean; +BEGIN + Assign(LineFile,General.DataPath+'NODE'+IntToStr(ThisNode)+'.DAT'); + Reset(LineFile); + Seek(LineFile,0); + Read(LineFile,Liner); + REPEAT + WITH General DO + BEGIN + Abort := FALSE; + Next := FALSE; + RGSysCfgStr(1,FALSE); + OneK(Cmd,'QABCDEFGHIJKLMN0123456789'^M,TRUE,TRUE); + CASE Cmd OF + 'A' : BEGIN + InputWNWC(RGSysCfgStr(2,TRUE),BBSName,(SizeOf(BBSName) - 1),Changed); + InputFormatted(RGSysCfgStr(3,TRUE),BBSPhone,'###-###-####',FALSE); + END; + 'B' : InputWN1(RGSysCfgStr(4,TRUE),Liner.NodeTelnetURL,(SizeOf(Liner.NodeTelnetURL) - 1),[InteractiveEdit],Changed); + 'C' : InputWN1(RGSysCfgStr(5,TRUE),SysOpName,(SizeOf(SysOpName) - 1),[InterActiveEdit],Changed); + 'D' : RGNoteStr(0,FALSE); + 'E' : IF (InCom) THEN + RGNoteStr(1,FALSE) + ELSE + GetTimeRange(6,lLowTime,HiTime); + 'F' : GetTimeRange(7,MinBaudLowTime,MinBaudHiTime); + 'G' : GetTimeRange(8,DLLowTime,DLHiTime); + 'H' : GetTimeRange(9,MinBaudDLLowTime,MinBaudDLHiTime); + 'I' : BEGIN + REPEAT + RGSysCfgStr(10,FALSE); + OneK(Cmd,^M'ABC',TRUE,TRUE); + CASE Cmd OF + 'A' : InputWN1(RGSysCfgStr(11,TRUE),SysOpPw,(SizeOf(SysOpPW) - 1),[InterActiveEdit,UpperOnly],Changed); + 'B' : InputWN1(RGSysCfgStr(12,TRUE),NewUserPW,(SizeOf(SysOpPW) - 1),[InterActiveEdit,UpperOnly],Changed); + 'C' : InputWN1(RGSysCfgStr(13,TRUE),MinBaudOverride,(SizeOf(SysOpPW) - 1), + [InterActiveEdit,UpperOnly],Changed); + END; + UNTIL (Cmd = ^M) OR (HangUp); + Cmd := #0; + END; + 'J' : InputByteWOC(RGSysCfgStr(14,TRUE),EventWarningTime,[DisplayValue,NumbersOnly],0,255); + 'K' : BEGIN + REPEAT + RGSysCfgStr(15,FALSE); + OneK(Cmd,^M'123456Q',TRUE,TRUE); + CASE Cmd OF + '1' : FindMenu(RGSysCfgStr(16,TRUE),GlobalMenu,0,NumMenus,Changed); + '2' : FindMenu(RGSysCfgStr(17,TRUE),AllStartMenu,1,NumMenus,Changed); + '3' : FindMenu(RGSysCfgStr(18,TRUE),ShuttleLogonMenu,0,NumMenus,Changed); + '4' : FindMenu(RGSysCfgStr(19,TRUE),NewUserInformationMenu,1,NumMenus,Changed); + '5' : FindMenu(RGSysCfgStr(20,TRUE),MessageReadMenu,1,NumMenus,Changed); + '6' : FindMenu(RGSysCfgStr(21,TRUE),FileListingMenu,1,NumMenus,Changed); + END; + UNTIL (Cmd IN [^M,'Q']) OR (HangUp); + Cmd := #0; + END; + 'L' : InputWN1(RGSysCfgStr(22,TRUE),BulletPrefix,(SizeOf(BulletPrefix) - 1),[InterActiveEdit,UpperOnly],Changed); + 'M' : IF (InCom) THEN + RGNoteStr(1,FALSE) + ELSE + BEGIN + MultiNode := (NOT MultiNode); + SaveGeneral(FALSE); + ClrScr; + Writeln('Please restart Renegade.'); + Halt; + END; + 'N' : BEGIN + NetworkMode := (NOT NetworkMode); + IF (NetworkMode) THEN + LocalSec := TRUE + ELSE + LocalSec := PYNQ(RGSysCfgStr(23,TRUE),0,FALSE); + END; + '0' : InputPath(RGSysCfgStr(24,TRUE),DataPath,TRUE,FALSE,Changed); + '1' : InputPath(RGSysCfgStr(25,TRUE),MiscPath,TRUE,FALSE,Changed); + '2' : InputPath(RGSysCfgStr(26,TRUE),MsgPath,TRUE,FALSE,Changed); + '3' : InputPath(RGSysCfgStr(27,TRUE),NodePath,TRUE,FALSE,Changed); + '4' : InputPath(RGSysCfgStr(28,TRUE),LogsPath,TRUE,FALSE,Changed); + '5' : InputPath(RGSysCfgStr(29,TRUE),TempPath,FALSE,FALSE,Changed); + '6' : InputPath(RGSysCfgStr(30,TRUE),ProtPath,TRUE,FALSE,Changed); + '7' : InputPath(RGSysCfgStr(31,TRUE),ArcsPath,TRUE,FALSE,Changed); + '8' : InputPath(RGSysCfgStr(32,TRUE),FileAttachPath,TRUE,FALSE,Changed); + '9' : InputPath(RGSysCfgStr(33,TRUE),lMultPath,TRUE,FALSE,Changed); + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); + Seek(LineFile,0); + Write(LineFile,Liner); + Close(LineFile); + LastError := IOResult; +END; + +END. diff --git a/SOURCE/SYSOP2B.PAS b/SOURCE/SYSOP2B.PAS new file mode 100644 index 0000000..eeff6f1 --- /dev/null +++ b/SOURCE/SYSOP2B.PAS @@ -0,0 +1,230 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,L+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp2B; + +INTERFACE + +PROCEDURE ModemConfiguration; + +IMPLEMENTATION + +USES + Common; + +PROCEDURE ModemConfiguration; +VAR + LineFile: FILE OF LineRec; + Cmd: Char; + TempB: Byte; + Changed: Boolean; + + PROCEDURE ToggleMFlag(MFlagT: ModemFlagType; VAR MFlags: MFlagSet); + BEGIN + IF (MFlagT IN MFlags) THEN + Exclude(MFlags,MFlagT) + ELSE + Include(MFlags,MFlagT); + END; + + PROCEDURE ToggleMFlags(C: Char; VAR MFlags: MFlagSet; VAR Changed: Boolean); + VAR + SaveMFlags: MFlagSet; + BEGIN + SaveMFlags := MFlags; + CASE C OF + '7' : ToggleMFlag(LockedPort,MFlags); + '8' : ToggleMFlag(XONXOFF,MFlags); + '9' : ToggleMFlag(CTSRTS,MFlags); + END; + IF (MFlags <> SaveMFlags) THEN + Changed := TRUE; + END; + + PROCEDURE NewModemString(CONST DisplayStr: AStr; VAR InputStr: AStr; Len: Byte); + VAR + Changed: Boolean; + BEGIN + Print('%LF^1Current modem '+DisplayStr+' string: "^5'+InputStr+'^1"'); + Print('%LFUse: "|" for a carriage return'); + Print(' "~" for a half-second delay'); + Print(' "^" to toggle DTR off for 1/4 second'); + InputWN1('%LF^1Enter new modem '+DisplayStr+' string:%LF^4: ',InputStr,Len,[InterActiveEdit],Changed); + END; + + FUNCTION WhichBaud(B: Byte): AStr; + BEGIN + CASE B OF + 1 : WhichBaud := 'CONNECT 300'; + 2 : WhichBaud := 'CONNECT 600'; + 3 : WhichBaud := 'CONNECT 1200'; + 4 : WhichBaud := 'CONNECT 2400'; + 5 : WhichBaud := 'CONNECT 4800'; + 6 : WhichBaud := 'CONNECT 7200'; + 7 : WhichBaud := 'CONNECT 9600'; + 8 : WhichBaud := 'CONNECT 12000'; + 9 : WhichBaud := 'CONNECT 14400'; + 10 : WhichBaud := 'CONNECT 16800'; + 11 : WhichBaud := 'CONNECT 19200'; + 12 : WhichBaud := 'CONNECT 21600'; + 13 : WhichBaud := 'CONNECT 24000'; + 14 : WhichBaud := 'CONNECT 26400'; + 15 : WhichBaud := 'CONNECT 28800'; + 16 : WhichBaud := 'CONNECT 31200'; + 17 : WhichBaud := 'CONNECT 33600'; + 18 : WhichBaud := 'CONNECT 38400'; + 19 : WhichBaud := 'CONNECT 57600'; + 20 : WhichBaud := 'CONNECT 115200'; + END; + END; + +BEGIN + Assign(LineFile,General.DataPath+'NODE'+IntToStr(ThisNode)+'.DAT'); + Reset(LineFile); + Read(LineFile,Liner); + REPEAT + WITH Liner DO + BEGIN + Abort := FALSE; + Next := FALSE; + Print('%CL^5Modem/Node Configuration:'); + NL; + PrintACR('^11. Maximum baud rate: ^5'+PadLeftInt(InitBaud,20)+ + '^12. Port number : ^5'+IntToStr(ComPort)); + PrintACR('^13. Modem init : ^5'+PadLeftStr(Init,20)+ + '^14. Modem answer : ^5'+Answer); + PrintACR('^15. Modem HangUp : ^5'+PadLeftStr(HangUp,20)+ + '^16. Modem offhook : ^5'+Offhook); + PrintACR('^17. COM port locking : ^5'+PadLeftStr(ShowOnOff(LockedPort IN MFlags),20)+ + '^18. XON/XOFF flow : ^5'+ShowOnOff(XONXOFF IN MFlags)); + PrintACR('^19. CTS/RTS flow : ^5'+PadLeftStr(ShowOnOff(CTSRTS IN MFlags),20)+ + '^1A. ACS for this node: ^5'+LogonACS); + PrintACR('^1B. Drop file path : ^5'+PadLeftStr(DoorPath,20)+ + '^1C. Answer on ring : ^5'+IntToStr(AnswerOnRing)); + PrintACR('^1D. TeleConf Normal : ^5'+PadLeftStr(TeleConfNormal,20)+ + '^1E. MultiRing only : ^5'+ShowOnOff(MultiRing)); + PrintACR('^1F. TeleConf Anon : ^5'+PadLeftStr(TeleConfAnon,20)); + PrintACR('^1G. TeleConf Global : ^5'+TeleConfGlobal); + PrintACR('^1H. TeleConf Private : ^5'+TeleConfPrivate); + PrintACR('^1I. IRQ string : ^5'+IRQ); + PrintACR('^1J. Address string : ^5'+Address); + PrintACR('^1R. Modem result codes'); + Prt('%LFEnter selection [^51^4-^59^4,^5A^4-^5J^4,^5R^4,^5Q^4=^5Quit^4]: '); + OneK(Cmd,'Q123456789ABCDEFGHIJR'^M,TRUE,TRUE); + CASE Cmd OF + '1' : IF (InCom) THEN + BEGIN + Print('%LF^7This can only be changed locally.'); + PauseScr(FALSE); + END + ELSE + BEGIN + Print('%LF^5Modem maximum baud rates:^1'); + Print('%LF^1(^3A^1). 2400'); + Print('^1(^3B^1). 9600'); + Print('^1(^3C^1). 19200'); + Print('^1(^3D^1). 38400'); + Print('^1(^3E^1). 57600'); + Print('^1(^3F^1). 115200'); + LOneK('%LFModem speed? [^5A^4-^5F^4,^5^4=^5Quit^4]: ',Cmd,^M'ABCDEF',TRUE,TRUE); + CASE Cmd OF + 'A' : InitBaud := 2400; + 'B' : InitBaud := 9600; + 'C' : InitBaud := 19200; + 'D' : InitBaud := 38400; + 'E' : InitBaud := 57600; + 'F' : InitBaud := 115200; + END; + Cmd := #0; + END; + '2' : IF (InCom) THEN + BEGIN + Print('%LF^7This can only be changed locally.'); + PauseScr(FALSE); + END + ELSE + BEGIN + TempB := ComPort; + InputByteWC('%LFCom port',TempB,[DisplayValue,NumbersOnly],0,64,Changed); + IF (Changed) THEN + IF PYNQ('%LFAre you sure this is what you want? ',0,FALSE) THEN + BEGIN + Com_DeInstall; + ComPort := TempB; + Com_Install; + END; + IF (NOT LocalIOOnly) AND (ComPort = 0) THEN + LocalIOOnly := TRUE; + END; + '3' : NewModemString('init',Init,(SizeOf(Init) - 1)); + '4' : NewModemString('answer',Answer,(SizeOf(Answer) - 1)); + '5' : NewModemString('hangup',HangUp,(SizeOf(HangUp) - 1)); + '6' : NewModemString('offhook',Offhook,(SizeOf(Offhook) - 1)); + '7' : ToggleMFlags('7',MFlags,Changed); + '8' : ToggleMFlags('8',MFlags,Changed); + '9' : ToggleMFlags('9',MFlags,Changed); + 'A' : InputWN1('%LFNew ACS: ',LogonACS,(SizeOf(LogonACS) - 1),[InterActiveEdit],Changed); + 'B' : InputPath('%LF^1Enter path to write door interface files to (^5End with a ^1"^5\^1"):%LF^4: ', + DoorPath,TRUE,FALSE,Changed); + 'C' : InputByteWOC('%LFAnswer after ring number',AnswerOnRing,[DisplayValue,NumbersOnly],0,255); + 'E' : MultiRing := NOT MultiRing; + 'D' : InputWN1('%LF^1Enter new teleconference string:%LF^4: ',TeleConfNormal,(SizeOf(TeleConfNormal) - 1), + [ColorsAllowed,InterActiveEdit],Changed); + 'F' : InputWN1('%LF^1Enter new teleconference string:%LF^4: ',TeleConfAnon,(SizeOf(TeleConfAnon) - 1), + [ColorsAllowed,InterActiveEdit],Changed); + 'G' : InputWN1('%LF^1Enter new teleconference string:%LF^4: ',TeleConfGlobal,(SizeOf(TeleConfGlobal) - 1), + [ColorsAllowed,InterActiveEdit],Changed); + 'H' : InputWN1('%LF^1Enter new teleconference string:%LF^4: ',TeleConfPrivate,(SizeOf(TeleConfPrivate) - 1), + [ColorsAllowed,InterActiveEdit],Changed); + 'I' : InputWN1('%LFIRQ for %E MCI code: ',IRQ,(SizeOf(IRQ) - 1),[InterActiveEdit],Changed); + 'J' : InputWN1('%LFAddress for %C MCI code: ',Address,(SizeOf(Address) - 1),[InterActiveEdit],Changed); + 'R' : BEGIN + REPEAT + Abort := FALSE; + Next := FALSE; + Print('%CL^5Modem configuration - Result Codes'); + NL; + PrintACR('^1A. NO CARRIER : ^5'+PadLeftStr(NOCARRIER,21)+'^1B. RELIABLE : ^5'+RELIABLE); + PrintACR('^1C. OK : ^5'+PadLeftStr(OK,21)+'^1D. RING : ^5'+RING); + PrintACR('^1E. CALLER ID : ^5'+PadLeftStr(CALLERID,21)+ + '^1F. ID/User note : ^5'+ShowOnOff(UseCallerID)); + FOR TempB := 1 TO MaxResultCodes DO + IF (NOT Odd(TempB)) THEN + Print('^1'+Chr(TempB + 70)+'. '+PadLeftStr(WhichBaud(TempB),14)+': ^5'+Connect[TempB]) + ELSE + Prompt(PadLeftStr('^1'+Chr(TempB + 70)+'. '+PadLeftStr(WhichBaud(TempB),14)+': ^5'+Connect[TempB],40)); + LOneK('%LFEnter selection [^5A^4-^5Z^4,^5^4=^5Quit^4]: ',Cmd,^M'ABCDEFGHIJKLMNOPQRSTUVWXYZ',TRUE,TRUE); + CASE Cmd OF + 'A' : InputWN1('%LFEnter NO CARRIER string: ',NOCARRIER,(SizeOf(NOCARRIER) - 1), + [InterActiveEdit,UpperOnly],Changed); + 'B' : InputWN1('%LFEnter RELIABLE string: ',RELIABLE,(SizeOf(RELIABLE) - 1), + [InterActiveEdit,UpperOnly],Changed); + 'C' : InputWN1('%LFEnter OK string: ',OK,(SizeOf(OK) - 1),[InterActiveEdit,UpperOnly],Changed); + 'D' : InputWN1('%LFEnter RING string: ',RING,(SizeOf(RING) - 1),[InterActiveEdit,UpperOnly],Changed); + 'E' : InputWN1('%LFEnter Caller ID string: ',CALLERID,(SizeOf(CALLERID) - 1), + [InterActiveEdit,UpperOnly],Changed); + 'F' : UseCallerID := NOT UseCallerID; + 'G'..'Z' : + BEGIN + TempB := (Ord(Cmd) - 70); + IF (TempB IN [1..MaxResultCodes]) THEN + InputWN1('%LFEnter '+WhichBaud(TempB)+' string: ',Connect[TempB],(SizeOf(Connect[1]) - 1), + [InterActiveEdit,UpperOnly],Changed); + END; + END; + UNTIL (Cmd = ^M); + Cmd := #0; + END; + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); + Seek(LineFile,0); + Write(LineFile,Liner); + Close(LineFile); + LastError := IOResult; +END; + +END. diff --git a/SOURCE/SYSOP2C.PAS b/SOURCE/SYSOP2C.PAS new file mode 100644 index 0000000..0081f3f --- /dev/null +++ b/SOURCE/SYSOP2C.PAS @@ -0,0 +1,124 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT SysOp2C; + +INTERFACE + +PROCEDURE SystemACSSettings; + +IMPLEMENTATION + +USES + Common; + +PROCEDURE SystemACSSettings; +VAR + TempACS: ACString; + Cmd: Char; + Changed: Boolean; +BEGIN + REPEAT + WITH General DO + BEGIN + Abort := FALSE; + Next := FALSE; + MCIAllowed := FALSE; + CLS; + Print('^5System ACS Settings:'); + NL; + PrintACR('^1A. Full SysOp : ^5'+PadLeftStr(SOp,18)+ + '^1B. Full Co-SysOp : ^5'+CSOp); + PrintACR('^1C. Msg Area SysOp : ^5'+PadLeftStr(MSOp,18)+ + '^1D. File Area SysOp : ^5'+FSOp); + PrintACR('^1E. Change a vote : ^5'+PadLeftStr(ChangeVote,18)+ + '^1F. Add voting choice: ^5'+AddChoice); + PrintACR('^1G. Post public : ^5'+PadLeftStr(NormPubPost,18)+ + '^1H. Send e-mail : ^5'+NormPrivPost); + PrintACR('^1I. See anon pub post: ^5'+PadLeftStr(AnonPubRead,18)+ + '^1J. See anon E-mail : ^5'+AnonPrivRead); + PrintACR('^1K. Global Anon post : ^5'+PadLeftStr(AnonPubPost,18)+ + '^1L. E-mail anon : ^5'+AnonPrivPost); + PrintACR('^1M. See unval. files : ^5'+PadLeftStr(SeeUnVal,18)+ + '^1N. DL unval. files : ^5'+DLUnVal); + PrintACR('^1O. No UL/DL ratio : ^5'+PadLeftStr(NoDLRatio,18)+ + '^1P. No PostCall ratio: ^5'+NoPostRatio); + PrintACR('^1R. No DL credits chk: ^5'+PadLeftStr(NoFileCredits,18)+ + '^1S. ULs auto-credited: ^5'+ULValReq); + PrintACR('^1T. MCI in TeleConf : ^5'+PadLeftStr(TeleConfMCI,18)+ + '^1U. Chat at any hour : ^5'+OverRideChat); + PrintACR('^1V. Send Netmail : ^5'+PadLeftStr(NetMailACS,18)+ + '^1W. "Invisible" Mode : ^5'+Invisible); + PrintACR('^1X. Mail file attach : ^5'+PadLeftStr(FileAttachACS,18)+ + '^1Y. SysOp PW at logon: ^5'+SPW); + PrintACR('^1Z. Last On Add : ^5'+PadLeftStr(LastOnDatACS,18)); + MCIAllowed := TRUE; + NL; + Prt('Enter selection [^5A^4-^5P^4,^5R^4-^5Z^4,^5Q^4=^5Quit^4]: '); + OneK(Cmd,'QABCDEFGHIJKLMNOPRSTUVWXYZ'^M,TRUE,TRUE); + IF (Cmd IN ['A'..'P','R'..'Z']) THEN + BEGIN + CASE Cmd OF + 'A' : TempACS := SOp; + 'B' : TempACS := CSOp; + 'C' : TempACS := MSOp; + 'D' : TempACS := FSOp; + 'E' : TempACS := ChangeVote; + 'F' : TempACS := AddChoice; + 'G' : TempACS := NormPubPost; + 'H' : TempACS := NormPrivPost; + 'I' : TempACS := AnonPubRead; + 'J' : TempACS := AnonPrivRead; + 'K' : TempACS := AnonPubPost; + 'L' : TempACS := AnonPrivPost; + 'M' : TempACS := SeeUnVal; + 'N' : TempACS := DLUnVal; + 'O' : TempACS := NoDLRatio; + 'P' : TempACS := NoPostRatio; + 'R' : TempACS := NoFileCredits; + 'S' : TempACS := ULValReq; + 'T' : TempACS := TeleConfMCI; + 'U' : TempACS := OverRideChat; + 'V' : TempACS := NetMailACS; + 'W' : TempACS := Invisible; + 'X' : TempACS := FileAttachACS; + 'Y' : TempACS := SPW; + 'Z' : TempACS := LastOnDatACS; + END; + InputWN1('%LFNew ACS: ',TempACS,(SizeOf(ACString) - 1),[InterActiveEdit],Changed); + CASE Cmd OF + 'A' : SOp := TempACS; + 'B' : CSOp := TempACS; + 'C' : MSOp := TempACS; + 'D' : FSOp := TempACS; + 'E' : ChangeVote := TempACS; + 'F' : AddChoice := TempACS; + 'G' : NormPubPost := TempACS; + 'H' : NormPrivPost := TempACS; + 'I' : AnonPubRead := TempACS; + 'J' : AnonPrivRead := TempACS; + 'K' : AnonPubPost := TempACS; + 'L' : AnonPrivPost := TempACS; + 'M' : SeeUnVal := TempACS; + 'N' : DLUnVal := TempACS; + 'O' : NoDLRatio := TempACS; + 'P' : NoPostRatio := TempACS; + 'R' : NoFileCredits := TempACS; + 'S' : ULValReq := TempACS; + 'T' : TeleConfMCI := TempACS; + 'U' : OverRideChat := TempACS; + 'V' : NetMailACS := TempACS; + 'W' : Invisible := TempACS; + 'X' : FileAttachACS := TempACS; + 'Y' : SPW := TempACS; + 'Z' : LastOnDatACS := TempACS; + END; + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +END. diff --git a/SOURCE/SYSOP2D.PAS b/SOURCE/SYSOP2D.PAS new file mode 100644 index 0000000..15fdb69 --- /dev/null +++ b/SOURCE/SYSOP2D.PAS @@ -0,0 +1,348 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT SysOp2D; + +INTERFACE + +PROCEDURE SystemGeneralVariables; + +IMPLEMENTATION + +USES + Common; + +PROCEDURE SystemGeneralVariables; +VAR + Cmd: Char; + TempB, + MinByte, + MaxByte: Byte; + TempI, + MinInt, + MaxInt: SmallInt; + TempL, + MinLongInt, + MaxLongInt: LongInt; + + FUNCTION DisplaySwapTo(SwapTo: Byte): Str4; + BEGIN + CASE SwapTo OF + 0 : DisplaySwapTo := 'Disk'; + 1 : DisplaySwapTo := 'XMS'; + 2 : DisplaySwapTo := 'EMS'; + 4 : DisplaySwapTo := 'EXT'; + 255 : DisplaySwapTo := 'Any'; + END; + END; + + PROCEDURE DisplayMacroo(CONST S: AStr; MaxLen: Byte); + VAR + TempStr: AStr; + Counter: Byte; + BEGIN + TempStr := ''; + Prompt('^5"^1'); + FOR Counter := 1 TO Length(S) DO + IF (S[Counter] >= ' ') THEN + TempStr := TempStr + S[Counter] + ELSE + TempStr := TempStr + '^3^'+Chr(Ord(S[Counter]) + 64)+'^1'; + Prompt(PadLeftStr(TempStr,MaxLen)+'^5"'); + END; + + PROCEDURE MMacroo(MacroNum: Byte); + VAR + S: AStr; + C: Char; + Counter: Byte; + BEGIN + Print('%CL^5Enter new F'+IntToStr(MacroNum + 1)+' macro now.'); + Print('^5Enter ^Z to end recording. 100 character limit.%LF'); + S := ''; + Counter := 1; + REPEAT + C := Char(GetKey); + IF (C = ^H) THEN + BEGIN + C := #0; + IF (Counter >= 2) THEN + BEGIN + BackSpace; + Dec(Counter); + IF (S[Counter] < #32) THEN + BackSpace; + END; + END; + IF (Counter <= 100) AND (C <> #0) THEN + BEGIN + IF (C IN [#32..#255]) THEN + BEGIN + OutKey(C); + S[Counter] := C; + Inc(Counter); + END + ELSE IF (C IN [^A,^B,^C,^D,^E,^F,^G,^H,^I,^J,^K,^L,^M,^N,^P,^Q,^R,^S,^T,^U,^V,^W,^X,^Y,#27,#28,#29,#30,#31]) THEN + BEGIN + IF (C = ^M) THEN + NL + ELSE + Prompt('^3^'+Chr(Ord(C) + 64)+'^1'); + S[Counter] := C; + Inc(Counter); + END; + END; + UNTIL ((C = ^Z) OR (HangUp)); + S[0] := Chr(Counter - 1); + Print('%LF%LF^3Your F'+IntToStr(MacroNum + 1)+' macro is now:%LF'); + DisplayMacroo(S,160); + Com_Flush_Recv; + IF (NOT PYNQ('%LFIs this what you want? ',0,FALSE)) THEN + Print('%LFMacro not saved.') + ELSE + BEGIN + General.Macro[MacroNum] := S; + Print('%LFMacro saved.'); + END; + PauseScr(FALSE); + END; + +BEGIN + REPEAT + WITH General DO + BEGIN + Abort := FALSE; + Next := FALSE; + Print('%CL^5System Variables:'); + NL; + PrintACR('^1A. Max private sent per call: ^5'+PadLeftInt(MaxPrivPost,6)+ + '^1 B. Max feedback sent per call: ^5'+PadLeftInt(MaxFBack,6)); + PrintACR('^1C. Max public posts per call: ^5'+PadLeftInt(MaxPubPost,6)+ + '^1 D. Max chat attempts per call: ^5'+PadLeftInt(MaxChat,6)); + PrintACR('^1E. Normal max mail waiting : ^5'+PadLeftInt(MaxWaiting,6)+ + '^1 F. CoSysOp max mail waiting : ^5'+PadLeftInt(CSMaxWaiting,6)); + PrintACR('^1G. Max mass mail list : ^5'+PadLeftInt(MaxMassMailList,6)+ + '^1 H. Logins before bday check : ^5'+PadLeftInt(BirthDateCheck,6)); + PrintACR('^1I. Swap shell should use : ^5'+PadLeftStr(DisplaySwapTo(SwapTo),6)+ + '^1 J. Number of logon attempts : ^5'+PadLeftInt(MaxLogonTries,6)); + PrintACR('^1K. Password change in days : ^5'+PadLeftInt(PasswordChange,6)+ + '^1 L. SysOp chat color : ^5'+PadLeftInt(SysOpColor,6)); + PrintACR('^1M. User chat color : ^5'+PadLeftInt(UserColor,6)+ + '^1 N. Min. space for posts : ^5'+PadLeftInt(MinSpaceForPost,6)); + PrintACR('^1O. Min. space for uploads : ^5'+PadLeftInt(MinSpaceForUpload,6)+ + '^1 P. Back SysOp Log keep days : ^5'+PadLeftInt(BackSysOpLogs,6)); + PrintACR('^1R. Blank WFC menu minutes : ^5'+PadLeftInt(WFCBlankTime,6)+ + '^1 S. Alert beep delay : ^5'+PadLeftInt(AlertBeep,6)); + PrintACR('^1T. Number of system callers : ^5'+PadLeftInt(CallerNum,6)+ + '^1 U. Minimum logon baud rate : ^5'+PadLeftInt(MinimumBaud,6)); + PrintACR('^1V. Minimum D/L baud rate : ^5'+PadLeftInt(MinimumDLBaud,6)+ + '^1 W. Sec''s between Time Slices : ^5'+PadLeftInt(SliceTimer,6)); + PrintACR('^1X. TB max time allowed : ^5'+PadLeftInt(MaxDepositEver,6)+ + '^1 Y. TB max per day deposit : ^5'+PadLeftInt(MaxDepositPerDay,6)); + PrintACR('^1Z. TB max per day withdrawal: ^5'+PadLeftInt(MaxWithDrawalPerDay,6)); + NL; + FOR TempB := 0 TO 9 DO + BEGIN + Prompt('^1'+IntToStr(TempB)+'. F'+IntToStr(TempB + 1)+' Macro :^5'); + DisplayMacroo(Macro[TempB],21); + IF Odd(TempB) THEN + NL + ELSE + Prompt(' '); + END; + Prt('%LFEnter selection [^5A^4-^5P^4,^5R^4-^5Z^4,^50^4-^59^4,^5Q^4=^5Quit^4]: '); + OneK(Cmd,'QABCDEFGHIJKLMNOPRSTUVWXYZ1234567890'^M,TRUE,TRUE); + CASE Cmd OF + '0'..'9' : + MMacroo(Ord(Cmd) - Ord('0')); + 'I' : BEGIN + Print('%LF^5Swap locations:^1'); + Print('%LF^1(^3D^1)isk'); + Print('^1(^3E^1)MS'); + Print('^1(^3X^1)MS'); + Print('^1(^3N^1)on XMS Extended'); + Print('^1(^3A^1)ny'); + lOneK('%LFSwap to which? [^5D^4,^5E^4,^5X^4,^5N^4,^5A^4,^5^4=^5Quit^4]: ',Cmd,'DEXNA'^M,TRUE,TRUE); + CASE Pos(Cmd,'DXENA') OF + 1..3 : SwapTo := (Pos(Cmd,'DXE') - 1); + 4 : SwapTo := 4; + 5 : SwapTo := 255; + END; + Cmd := #0; + END; + 'A'..'H','J'..'P','R'..'Z' : + BEGIN + CASE Cmd OF + 'A' : BEGIN + MinByte := 0; + MaxByte := 255; + TempB := MaxPrivPost; + END; + 'B' : BEGIN + MinByte := 0; + MaxByte := 255; + TempB := MaxFBack; + END; + 'C' : BEGIN + MinByte := 0; + MaxByte := 255; + TempB := MaxPubPost; + END; + 'D' : BEGIN + MinByte := 0; + MaxByte := 255; + TempB := MaxChat; + END; + 'E' : BEGIN + MinByte := 0; + MaxByte := 255; + TempB := MaxWaiting; + END; + 'F' : BEGIN + MinByte := 0; + MaxByte := 255; + TempB := CSMaxWaiting; + END; + 'G' : BEGIN + MinByte := 2; + MaxByte := 255; + TempB := MaxMassMailList; + END; + 'H' : BEGIN + MinInt := 0; + MaxInt := 365; + TempI := BirthDateCheck; + END; + 'J' : BEGIN + MinByte := 0; + MaxByte := 255; + TempB := MaxLogonTries; + END; + 'K' : BEGIN + MinInt := 0; + MaxInt := 32767; + TempI := PasswordChange; + END; + 'L' : BEGIN + MinByte := 0; + MaxByte := 9; + TempB := SysOpColor; + END; + 'M' : BEGIN + MinByte := 0; + MaxByte := 9; + TempB := UserColor; + END; + 'N' : BEGIN + MinInt := 1; + MaxInt := 32767; + TempI := MinSpaceForPost; + END; + 'O' : BEGIN + MinInt := 1; + MaxInt := 32767; + TempI := MinSpaceForUpload; + END; + 'P' : BEGIN + MinByte := 1; + MaxByte := 255; + TempB := BackSysOpLogs; + END; + 'R' : BEGIN + MinByte := 0; + MaxByte := 60; + TempB := WFCBlankTime; + END; + 'S' : BEGIN + MinByte := 0; + MaxByte := 60; + TempB := AlertBeep; + END; + 'T' : BEGIN + MinLongInt := 0; + MaxLongInt := 2147483647; + TempL := CallerNum; + END; + 'U' : BEGIN + MinLongInt := 0; + MaxLongInt := 115200; + TempL := MinimumBaud; + END; + 'V' : BEGIN + MinLongInt := 0; + MaxLongInt := 115200; + TempL := MinimumDLBaud; + END; + 'W' : BEGIN + MinByte := 1; + MaxByte := 255; + TempB := SliceTimer; + END; + 'X' : BEGIN + MinLongInt := 0; + MaxLongInt := 6000; + TempL := MaxDepositEver; + END; + 'Y' : BEGIN + MinLongInt := 0; + MaxLongInt := 6000; + TempL := MaxDepositPerDay; + END; + 'Z' : BEGIN + MinLongInt := 0; + MaxLongInt := 6000; + TempL := MaxWithdrawalPerDay + END; + END; + CASE Cmd OF + 'H','K','N'..'O' : + InputIntegerWOC('%LFNew value',TempI,[NumbersOnly],MinInt,MaxInt); + 'T'..'V','X'..'Z' : + InputLongIntWOC('%LFNew value',TempL,[DisplayValue,NumbersOnly],MinLongInt,MaxLongInt); + ELSE + InputByteWOC('%LFNew value',TempB,[NumbersOnly],MinByte,MaxByte); + END; + CASE Cmd OF + 'A' : MaxPrivPost := TempB; + 'B' : MaxFBack := TempB; + 'C' : MaxPubPost := TempB; + 'D' : MaxChat := TempB; + 'E' : MaxWaiting := TempB; + 'F' : CSMaxWaiting := TempB; (* Not Hooked Up *) + 'G' : MaxMassMailList := TempB; + 'H' : BEGIN + BirthDateCheck := TempI; + (* + IF (BirthDateCheck = 0) THEN + NewUserToggles[9] := 0 + ELSE + NewUserToggles[9] := 2; + *) + END; + 'J' : MaxLogonTries := TempB; + 'K' : PasswordChange := TempI; + 'L' : SysOpColor := TempB; + 'M' : UserColor := TempB; + 'N' : MinSpaceForPost := TempI; + 'O' : MinSpaceForUpload := TempI; + 'P' : BackSysOpLogs := TempB; + 'R' : WFCBlankTime := TempB; + 'S' : AlertBeep := TempB; + 'T' : CallerNum := TempL; + 'U' : MinimumBaud := TempL; + 'V' : MinimumDLBaud := TempL; + 'W' : SliceTimer := TempB; + 'X' : MaxDepositEver := TempL; + 'Y' : MaxDepositPerDay := TempL; + 'Z' : MaxWithDrawalPerDay := TempL; + END; + END; + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +END. diff --git a/SOURCE/SYSOP2E.PAS b/SOURCE/SYSOP2E.PAS new file mode 100644 index 0000000..9fd6ba7 --- /dev/null +++ b/SOURCE/SYSOP2E.PAS @@ -0,0 +1,159 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +{ System Configuration - System Flagged Functions } + +(* 1. Add checking for deleted users or forwarded mail to option 1 *) + +UNIT SysOp2E; + +INTERFACE + +PROCEDURE SystemFlaggedFunctions; + +IMPLEMENTATION + +USES + Crt, + Common; + +PROCEDURE SystemFlaggedFunctions; +VAR + Cmd, + Cmd1: Char; + LowNum, + HiNum, + TempInt: SmallInt; +BEGIN + REPEAT + WITH General DO + BEGIN + Abort := FALSE; + Next := FALSE; + Print('%CL^5System Flagged Functions:'); + NL; + PrintACR('^1A. Handles allowed on system: ^5'+ShowOnOff(AllowAlias)+ + '^1 B. Phone number in logon : ^5'+ShowOnOff(PhonePW)); + PrintACR('^1C. Local security protection: ^5'+ShowOnOff(LocalSec)+ + '^1 D. Use EMS for overlay file : ^5'+ShowOnOff(UseEMS)); + PrintACR('^1E. Global activity trapping : ^5'+ShowOnOff(GlobalTrap)+ + '^1 F. Auto chat buffer open : ^5'+ShowOnOff(AutoChatOpen)); + PrintACR('^1G. AutoMessage in logon : ^5'+ShowOnOff(AutoMInLogon)+ + '^1 H. Bulletins in logon : ^5'+ShowOnOff(BullInLogon)); + PrintACR('^1I. User info in logon : ^5'+ShowOnOff(YourInfoInLogon)+ + '^1 J. Strip color off SysOp Log : ^5'+ShowOnOff(StripCLog)); + PrintACR('^1K. Offhook in local logon : ^5'+ShowOnOff(OffHookLocalLogon)+ + '^1 L. Trap Teleconferencing : ^5'+ShowOnOff(TrapTeleConf)); + PrintACR('^1M. Compress file/msg numbers: ^5'+ShowOnOff(CompressBases)+ + ' ^1 N. Use BIOS for video output : ^5'+ShowOnOff(UseBIOS)); + PrintACR('^1O. Use IEMSI handshakes : ^5'+ShowOnOff(UseIEMSI)+ + '^1 P. Refuse new users : ^5'+ShowOnOff(ClosedSystem)); + PrintACR('^1R. Swap shell function : ^5'+ShowOnOff(SwapShell)+ + '^1 S. Use shuttle logon : ^5'+ShowOnOff(ShuttleLog)); + PrintACR('^1T. Chat call paging : ^5'+ShowOnOff(ChatCall)+ + '^1 U. Time limits are per call : ^5'+ShowOnOff(PerCall)); + PrintACR('^1V. SysOp Password checking : ^5'+ShowOnOff(SysOpPWord)+ + '^1 W. Random quote in logon : ^5'+ShowOnOff(LogonQuote)); + PrintACR('^1X. User add quote in logon : ^5'+ShowOnOff(UserAddQuote)+ + '^1 Y. Use message area lightbar : ^5'+ShowOnOff(UseMsgAreaLightBar)); + PrintACR('^1Z. Use file area lightbar : ^5'+ShowOnOff(UseFileAreaLightBar)); + PrintACR(''); + PrintACR('^11. New user message sent to : ^5'+AOnOff((NewApp = -1),'Off',PadLeftInt(NewApp,5))); + PrintACR('^12. Mins before TimeOut bell : ^5'+AOnOff((TimeOutBell = -1),'Off',PadLeftInt(TimeOutBell,3))); + PrintACR('^13. Mins before TimeOut : ^5'+AOnOff((TimeOut = -1),'Off',PadLeftInt(TimeOut,3))); + Prt('%LFEnter selection [^5A^4-^5P^4,^5R^4-^5Z^4,^51^4-^53^4,^5Q^4=^5Quit^4]: '); + OneK(Cmd,'QABCDEFGHIJKLMNOPRSTUVWXYZ123'^M,TRUE,TRUE); + CASE Cmd OF + 'A' : AllowAlias := NOT AllowAlias; + 'B' : BEGIN + PhonePW := NOT PhonePW; + IF (PhonePW) THEN + NewUserToggles[7] := 8 + ELSE + NewUserToggles[7] := 0; + END; + 'C' : LocalSec := NOT LocalSec; + 'D' : BEGIN + UseEMS := NOT UseEMS; + IF (UseEMS) THEN + OvrUseEMS := TRUE + ELSE + OvrUseEMS := FALSE; + END; + 'E' : GlobalTrap := NOT GlobalTrap; + 'F' : AutoChatOpen := NOT AutoChatOpen; + 'G' : AutoMInLogon := NOT AutoMInLogon; + 'H' : BullInLogon := NOT BullInLogon; + 'I' : YourInfoInLogon := NOT YourInfoInLogon; + 'J' : StripCLog := NOT StripCLog; + 'K' : OffHookLocalLogon := NOT OffHookLocalLogon; + 'L' : TrapTeleConf := NOT TrapTeleConf; + 'M' : BEGIN + CompressBases := NOT CompressBases; + IF (CompressBases) THEN + Print('%LFCompressing file/message areas ...') + ELSE + Print('%LFDe-compressing file/message areas ...'); + NewCompTables; + END; + 'N' : BEGIN + UseBIOS := NOT UseBIOS; + DirectVideo := NOT UseBIOS; + END; + 'O' : UseIEMSI := NOT UseIEMSI; + 'P' : ClosedSystem := NOT ClosedSystem; + 'R' : SwapShell := NOT SwapShell; + 'S' : ShuttleLog := NOT ShuttleLog; + 'T' : ChatCall := NOT ChatCall; + 'U' : PerCall := NOT PerCall; + 'V' : SysOpPWord := NOT SysOpPWord; + 'W' : LogonQuote := NOT LogonQuote; + 'X' : UserAddQuote := NOT UserAddQuote; + 'Y' : UseMsgAreaLightBar := NOT UseMsgAreaLightBar; + 'Z' : UseFileAreaLightBar := NOT UseFileAreaLightBar; + '1'..'3' : + BEGIN + Prt('%LFSelect option [^5E^4=^5Enable^4,^5D^4=^5Disable^4,^5^4=^5Quit^4]: '); + OneK(Cmd1,^M'ED',TRUE,TRUE); + IF (Cmd1 IN ['E','D']) THEN + BEGIN + CASE Cmd1 OF + 'E' : BEGIN + CASE Cmd OF + '1' : BEGIN + LowNum := 1; + HiNum := (MaxUsers - 1); + TempInt := NewApp; + END; + '2' : BEGIN + LowNum := 1; + HiNum := 20; + TempInt := TimeOutBell; + END; + '3' : BEGIN + LowNum := 1; + HiNum := 20; + TempInt := TimeOut; + END; + END; + InputIntegerWOC('%LFEnter value for this function',TempInt,[NumbersOnly],LowNum,HiNum); + END; + 'D' : TempInt := -1; + END; + CASE Cmd OF + '1' : NewApp := TempInt; + '2' : TimeOutBell := TempInt; + '3' : TimeOut := TempInt; + END; + Cmd := #0; + END; + END; + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +END. diff --git a/SOURCE/SYSOP2F.PAS b/SOURCE/SYSOP2F.PAS new file mode 100644 index 0000000..4e6acab --- /dev/null +++ b/SOURCE/SYSOP2F.PAS @@ -0,0 +1,78 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT SysOp2F; + +INTERFACE + +PROCEDURE FileAreaConfiguration; + +IMPLEMENTATION + +USES + Common; + +PROCEDURE FileAreaConfiguration; +VAR + Cmd: Char; +BEGIN + REPEAT + WITH General DO + BEGIN + Abort := FALSE; + Next := FALSE; + Print('%CL^5File Area Configuration:'); + NL; + PrintACR('^1A. Upload/download ratio system : ^5'+ShowOnOff(ULDLRatio)); + PrintACR('^1B. File point system : ^5'+ShowOnOff(FileCreditRatio)); + PrintACR('^1C. Daily download limits : ^5'+ShowOnOff(DailyLimits)); + PrintACR('^1D. Test and convert uploads : ^5'+ShowOnOff(TestUploads)); + PrintACR('^1E. File point rewarding system : ^5'+ShowOnOff(RewardSystem)); + PrintACR('^1F. Search for/Use FILE_ID.DIZ : ^5'+ShowOnOff(FileDiz)); + PrintACR('^1G. Recompress like archives : ^5'+ShowOnOff(Recompress)); + PrintACR('^1H. Credit reward compensation ratio: ^5'+IntToStr(RewardRatio)+'%'); + PrintACR('^1I. File point compensation ratio : ^5'+IntToStr(FileCreditComp)+' to 1'); + PrintACR('^1J. Area file size per 1 file point : ^5'+IntToStr(FileCreditCompBaseSize)+'k'); + PrintACR('^1K. Upload time refund percent : ^5'+IntToStr(ULRefund)+'%'); + PrintACR('^1L. "To-SysOp" file area : ^5'+AOnOff(ToSysOpDir = 0,'*None*',IntToStr(ToSysOpDir))); + PrintACR('^1M. Auto-validate ALL files ULed? : ^5'+ShowYesNo(ValidateAllFiles)); + PrintACR('^1N. Max k-bytes allowed in temp dir : ^5'+IntToStr(MaxInTemp)); + PrintACR('^1O. Min k-bytes to save for resume : ^5'+IntToStr(MinResume)); + PrintACR('^1P. Max batch download files : ^5'+IntToStr(MaxBatchDLFiles)); + PrintACR('^1R. Max batch upload files : ^5'+IntToStr(MaxBatchUlFiles)); + PrintACR('^1S. UL duplicate file search : ^5'+ShowOnOff(SearchDup)); + PrintACR('^1T. Force batch download at login : ^5'+ShowOnOff(ForceBatchDL)); + PrintACR('^1U. Force batch upload at login : ^5'+ShowOnOff(ForceBatchUL)); + NL; + Prt('Enter selection [^5A^4-^5P^4,^5R^4-^5U^4,^5Q^4=^5Quit^4]: '); + OneK(Cmd,'QABCDEFGHIJKLMNOPRSTU'^M,TRUE,TRUE); + CASE Cmd OF + 'A' : ULDLRatio := NOT ULDLRatio; + 'B' : FileCreditRatio := NOT FileCreditRatio; + 'C' : DailyLimits := NOT DailyLimits; + 'D' : TestUploads := NOT TestUploads; + 'E' : RewardSystem := NOT RewardSystem; + 'F' : FileDiz := NOT FileDiz; + 'G' : Recompress := NOT Recompress; + 'H' : InputIntegerWOC('%LFNew percentage of file credits to reward',RewardRatio,[DisplayValue,NumbersOnly],0,100); + 'I' : InputByteWOC('%LFNew file point compensation ratio',FileCreditComp,[DisplayValue,Numbersonly],0,100); + 'J' : InputByteWOC('%LFNew area file size per 1 file Point',FileCreditCompBaseSize,[DisplayValue,NumbersOnly],0,255); + 'K' : InputByteWOC('%LFNew upload time refund percent',ULRefund,[DisplayValue,NumbersOnly],0,100); + 'L' : InputIntegerWOC('%LFNew "To-SysOp" file area (0=None)',ToSysOpDir,[DisplayValue,NumbersOnly],0,NumFileAreas); + 'M' : ValidateAllFiles := NOT ValidateAllFiles; + 'N' : InputLongIntWOC('%LFNew max k-bytes',MaxInTemp,[DisplayValue,NumbersOnly],0,2097151); + 'O' : InputLongIntWOC('%LFNew min resume k-bytes',MinResume,[DisplayValue,NumbersOnly],0,2097151); + 'P' : InputByteWOC('%LFNew max batch download files',MaxBatchDLFiles,[DisplayValue,NumbersOnly],1,255); + 'R' : InputByteWOC('%LFNew max batch upload files',MaxBatchULFiles,[DisplayValue,NumbersOnly],1,255); + 'S' : SearchDup := NOT SearchDup; + 'T' : ForceBatchDL := NOT ForceBatchDL; + 'U' : ForceBatchUL := NOT ForceBatchUL; + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +END. diff --git a/SOURCE/SYSOP2G.PAS b/SOURCE/SYSOP2G.PAS new file mode 100644 index 0000000..ca2451b --- /dev/null +++ b/SOURCE/SYSOP2G.PAS @@ -0,0 +1,884 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp2G; + +INTERFACE + +USES + Common; + +PROCEDURE AutoVal(VAR User: UserRecordType; UNum: Integer); +PROCEDURE AutoValidate(VAR User: UserRecordType; UNum: Integer; Level: Char); +PROCEDURE AutoValidationCmd(MenuOption: Str50); +PROCEDURE ValidationEditor; + +IMPLEMENTATION + +USES + ShortMsg, + SysOp7, + TimeFunc; + +CONST + Settings: FlagSet = [RLogon, + RChat, + RValidate, + RUserList, + RAMsg, + RPostAN, + RPost, + REmail, + RVoting, + RMsg, + FNoDLRatio, + FNoPostRatio, + FNoCredits, + FNoDeletion]; + +FUNCTION ARMatch(SoftAR: Boolean; UserAR,NewAR: ARFlagSet): Boolean; +VAR + SaveUserAR: ARFlagSet; + Match: Boolean; +BEGIN + Match := FALSE; + SaveUserAR := UserAR; + IF (SoftAR) THEN + UserAR := (UserAR + NewAR) + ELSE + UserAR := NewAR; + IF (SaveUserAR = UserAR) THEN + Match := TRUE; + ARMatch := Match; +END; + +FUNCTION ACMatch(SoftAC: Boolean; UserAC,NewAC: FlagSet): Boolean; +VAR + SaveUserAC: FlagSet; + Match: Boolean; +BEGIN + Match := FALSE; + SaveUserAC := UserAC; + IF (NOT SoftAC) THEN + UserAC := (UserAC - Settings); + UserAC := (UserAC + (NewAC * Settings)); + IF (SaveUserAC = UserAC) THEN + Match := TRUE; + ACMatch := Match; +END; + +PROCEDURE DisplayValidationRecords(VAR RecNumToList1: Integer); +VAR + TempStr: AStr; + NumDone, + NumOnline: Byte; +BEGIN + IF (RecNumToList1 < 1) OR (RecNumToList1 > NumValKeys) THEN + RecNumToList1 := 1; + Abort := FALSE; + Next := FALSE; + TempStr := ''; + NumOnline := 0; + CLS; + PrintACR('^0##^4:^3K^4:^3Description ^0##^4:^3K^4:^3Description'); + PrintACR('^4==:=:============================== ==:=:=============================='); + Reset(ValidationFile); + NumDone := 0; + WHILE (NumDone < (PageLength - 5)) AND (RecNumToList1 >= 1) AND (RecNumToList1 <= NumValKeys) + AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(ValidationFile,(RecNumToList1 - 1)); + Read(ValidationFile,Validation); + TempStr := TempStr + '^0'+PadLeftStr(PadRightInt(RecNumToList1,2)+ + ' ^3'+Validation.Key+ + ' ^5'+Validation.Description,37); + Inc(NumOnline); + IF (NumOnline = 2) THEN + BEGIN + PrintaCR(TempStr); + NumOnline := 0; + Inc(NumDone); + TempStr := ''; + END; + Inc(RecNumToList1); + END; + Close(ValidationFile); + LastError := IOResult; + IF (NumOnline = 1) AND (NOT Abort) AND (NOT HangUp) THEN + PrintaCR(TempStr); + IF (NumValKeys = 0) AND (NOT Abort) AND (NOT HangUp) THEN + Print('^7No validation records.'); +END; + +PROCEDURE AutoValidate(VAR User: UserRecordType; UNum: Integer; Level: Char); +VAR + RecNum, + RecNum1: Integer; +BEGIN + IF (NOT (Level IN ValKeys)) THEN + BEGIN + SysOpLog('^7Validation error, invalid level: "'+Level+'"!'); + Exit; + END; + Reset(ValidationFile); + RecNum1 := -1; + RecNum := 1; + WHILE (RecNum <= NumValKeys) AND (RecNum1 = -1) DO + BEGIN + Seek(ValidationFile,(RecNum - 1)); + Read(ValidationFile,Validation); + IF (Validation.Key = Level) THEN + RecNum1 := RecNum; + Inc(RecNum); + END; + Close(ValidationFile); + LastError := IOResult; + IF (Validation.Expiration = 0) AND (Validation.ExpireTo <> ' ') OR + (Validation.Expiration <> 0) AND (Validation.ExpireTo = ' ') THEN + BEGIN + SysOpLog('^7Validation error, expiration data invalid: "'+Level+'"!'); + Exit; + END + ELSE IF (Validation.ExpireTo <> ' ') AND (NOT (Validation.ExpireTo IN ValKeys)) THEN + BEGIN + SysOpLog('^7Validation error, expire to level "'+Validation.ExpireTo+'" does not exists!'); + Exit; + END; + User.Subscription := Level; + User.TLToday := General.TimeAllow[Validation.NewSL] - (General.TimeAllow[User.SL] - User.TLToday); + User.SL := Validation.NewSL; + User.DSL := Validation.NewDSL; + User.UserStartMenu := Validation.NewMenu; + IF (Validation.Expiration > 0) THEN + User.Expiration := (GetPackDateTime + (Validation.Expiration * 86400)) + ELSE + User.Expiration := 0; + Inc(User.FilePoints,Validation.NewFP); + Inc(User.lCredit,Validation.NewCredit); + IF (Validation.ExpireTo IN [' ','!'..'~']) THEN + User.ExpireTo := Validation.ExpireTo; + IF (Validation.SoftAR) THEN + User.AR := (User.AR + Validation.NewAR) + ELSE + User.AR := Validation.NewAR; + IF (NOT Validation.SoftAC) THEN + User.Flags := (User.Flags - Settings); + User.Flags := (User.Flags + (Validation.NewAC * Settings)); + SaveURec(User,UNum); + IF (UNum = UserNum) THEN + NewCompTables; +END; + +PROCEDURE AutoVal(VAR User: UserRecordType; UNum: Integer); +VAR + TempAR: ARFlagSet; + TempAC: FlagSet; + Level: Char; + CmdKeys: AStr; + RecNum, + RecNum1, + RecNumToList: Integer; +BEGIN + CmdKeys := ''; + FOR Level := '!' TO '~' DO + IF (Level IN ValKeys) THEN + CmdKeys := CmdKeys + Level; + RecNumToList := 1; + Level := '?'; + REPEAT + IF (Level = '?') THEN + DisplayValidationRecords(RecNumToList); + Prt('%LFValidation level? (^5!^4-^5P^4,^5R^4-^5p^4,^5r^4-^5~^4) [^5?^4=^5First^4,^5^4=^5Next^4,^5Q^4=^5Quit^4]: '); + OneK1(Level,'Q'+CmdKeys+'?'^M,TRUE,TRUE); + IF (Level <> 'Q') THEN + BEGIN + IF (Level = ^M) THEN + BEGIN + Level := '?'; + IF (RecNumToList < 1) OR (RecNumToList > NumValKeys) THEN + RecNumToList := 1 + END + ELSE IF (Level = '?') THEN + RecNumToList := 1 + ELSE + BEGIN + IF (Level IN ValKeys) THEN + BEGIN + Reset(ValidationFile); + RecNum1 := -1; + RecNum:= 1; + WHILE (RecNum <= NumValKeys) AND (RecNum1 = -1) DO + BEGIN + Seek(ValidationFile,(RecNum - 1)); + Read(ValidationFile,Validation); + IF (Validation.Key = Level) THEN + RecNum1 := RecNum; + Inc(RecNum); + END; + Close(ValidationFile); + IF (Validation.Expiration = 0) AND (Validation.ExpireTo <> ' ') OR + (Validation.Expiration <> 0) AND (Validation.ExpireTo = ' ') THEN + BEGIN + Print('%LF^7The expiration days/expire to level is invalid!^1'); + Level := #0; + END + ELSE IF (Validation.ExpireTo <> ' ') AND (NOT (Validation.ExpireTo IN ValKeys)) THEN + BEGIN + Print('%LF^7The expiration level does not exist for level: "'+Level+'"!^1'); + Level := #0; + END + ELSE IF (User.SL = Validation.NewSL) AND (User.DSL = Validation.NewDSL) AND + ARMatch(Validation.SoftAR,User.AR,Validation.NewAR) AND + ACMatch(Validation.SoftAC,User.Flags,Validation.NewAC) THEN + BEGIN + Print('%LF^7This user is already validated at level "'+Level+'"!^1'); + Level := #0; + END + ELSE + BEGIN + Print('%LF^1Description: ^5'+Validation.Description); + Print('%LF^1 < Old Settings > < New Settings >'); + Print('%LF^1Sub: ^5'+PadLeftStr(User.Subscription,30)+'^1Sub: ^5'+Level); + Print('^1SL : ^5'+PadLeftInt(User.SL,30)+'^1SL : ^5'+IntToStr(Validation.NewSL)); + Print('^1DSL: ^5'+PadLeftInt(User.DSL,30)+'^1DSL: ^5'+IntToStr(Validation.NewDSL)); + TempAR := User.AR; + IF (Validation.SoftAR) THEN + TempAR := (TempAR + Validation.NewAR) + ELSE + TempAR := Validation.NewAR; + Print('^1AR : ^5'+PadLeftStr(DisplayARFlags(User.AR,'5','1'),30)+'^1AR : ^5'+DisplayArFlags(TempAR,'5','1')); + TempAC := User.Flags; + IF (NOT Validation.SoftAC) THEN + TempAC := (TempAC - Settings); + TempAC := (TempAC + (Validation.NewAC * Settings)); + Print('^1AC : ^5'+PadLeftStr(DisplayACFlags(User.Flags,'5','1'),30)+'^1AC : ^5'+DisplayACFlags(TempAC,'5','1')); + Print('^1FP : ^5'+PadLeftInt(User.FilePoints,30)+'^1FP : ^5'+IntToStr(User.FilePoints + Validation.NewFP)); + Print('^1Crd: ^5'+PadLeftInt(User.lCredit,30)+'^1Crd: ^5'+IntToStr(User.lCredit + Validation.NewCredit)); + Print('^1Mnu: ^5'+PadLeftInt(User.UserStartMenu,30)+'^1Mnu: ^5'+IntToStr(Validation.NewMenu)); + Print('^1ExD: ^5'+PadLeftStr(AOnOff((User.Expiration > 0),ToDate8(PD2Date(User.Expiration)),'Never'),30)+ + '^1ExD: ^5'+AOnOff((Validation.Expiration > 0), + ToDate8(PD2Date(GetPackDateTime + (Validation.Expiration * 86400))), + 'Never')); + Print('^1ExS: ^5'+PadLeftStr(AOnOff(User.ExpireTo = ' ','No Change',User.ExpireTo),30)+ + '^1ExS: ^5'+AOnOff(Validation.ExpireTo = ' ','No Change',Validation.ExpireTo)); + IF (NOT PYNQ('%LFContinue validating user at this level? ',0,FALSE)) THEN + Level := #0; + END; + END; + END; + END; + UNTIL (Level IN ValKeys) OR (Level = 'Q') OR (HangUp); + IF (Level IN ValKeys) THEN + BEGIN + AutoValidate(User,UNum,Level); + Print('%LFThis user was validated using validation level "'+Level+'".'); + SendShortMessage(UNum,Validation.UserMsg); + LoadURec(User,UNum); + SysOpLog('Validated '+Caps(User.Name)+' with validation level "'+Level+'".'); + END; +END; + +PROCEDURE AutoValidationCmd(MenuOption: Str50); +VAR + Level: Char; + PW, + TempPW: Str20; + RecNum, + RecNum1: Integer; +BEGIN + IF (MenuOption = '') OR (Pos(';',MenuOption) = 0) OR + (Copy(MenuOption,(Pos(';',MenuOption) + 1),1) = '') OR + (Copy(MenuOption,1,(Pos(';',MenuOption) - 1)) = '') THEN + BEGIN + Print('%LF^7Command error, operation aborted!^1'); + SysOpLog('^7Auto-validation command error, invalid options!'); + Exit; + END; + PW := AllCaps(Copy(MenuOption,1,(Pos(';',MenuOption) - 1))); + MenuOption := Copy(MenuOption,(Pos(';',MenuOption) + 1),1); + Level := MenuOption[1]; + IF (NOT (Level IN ValKeys)) THEN + BEGIN + Print('%LF^7Command error, operation aborted!^1'); + SysOpLog('^7Auto-validation command error, level not found: '+Level+'!'); + Exit; + END; + Reset(ValidationFile); + RecNum1 := -1; + RecNum:= 1; + WHILE (RecNum <= NumValKeys) AND (RecNum1 = -1) DO + BEGIN + Seek(ValidationFile,(RecNum - 1)); + Read(ValidationFile,Validation); + IF (Validation.Key = Level) THEN + RecNum1 := RecNum; + Inc(RecNum); + END; + Close(ValidationFile); + LastError := IOResult; + IF (Validation.Expiration = 0) AND (Validation.ExpireTo <> ' ') OR + (Validation.Expiration <> 0) AND (Validation.ExpireTo = ' ') THEN + BEGIN + Print('%LF^7Command error, operation aborted!^1'); + SysOpLog('^7Auto-validation command error, expiration data invalid: "'+Level+'"!'); + Exit; + END + ELSE IF (Validation.ExpireTo <> ' ') AND (NOT (Validation.ExpireTo IN ValKeys)) THEN + BEGIN + Print('%LF^7Command error, operation aborted!^1'); + SysOpLog('^7Auto-validation command error, expire to level "'+Validation.ExpireTo+'" does not exists!'); + Exit; + END + ELSE IF (ThisUser.SL = Validation.NewSL) AND (ThisUser.DSL = Validation.NewDSL) AND + ARMatch(Validation.SoftAR,ThisUser.AR,Validation.NewAR) AND + ACMatch(Validation.SoftAC,ThisUser.Flags,Validation.NewAC) THEN + BEGIN + Print('%LF^7You have already been validated at this access level!^1'); + SysOpLog('User error, previously validated at level: "'+Level+'".'); + Exit; + END + ELSE IF (ThisUser.SL > Validation.NewSL) OR (ThisUser.DSL > Validation.NewDSL) THEN + BEGIN + Print('%LF^7This option would lower your access level!^1'); + SysOpLog('User error, access would be lowered to level: "'+Level+'".'); + Exit; + END; + Print('%LFPress to abort.'); + Prt('%LFPassword: '); + GetPassword(TempPW,20); + IF (TempPW = '') THEN + BEGIN + Print('%LFAborted.'); + Exit; + END; + IF (TempPW <> PW) THEN + BEGIN + Print('%LF^7Incorrect password entered!^1'); + SysOpLog('User error, invalid password entered: "'+TempPW+'"'); + Exit; + END; + AutoValidate(ThisUser,UserNum,Level); + lStatus_Screen(100,'This user has auto-validated ' + +AOnOff(ThisUser.Sex = 'M','himself','herself')+' with level: "'+Level+'".',FALSE,TempPW); + PrintF('AUTOVAL'); + IF (NoFile) THEN + Print('%LF'+Validation.UserMsg); + SysOpLog('This user has auto-validated '+AOnOff(ThisUser.Sex = 'M','himself','herself')+' with level: "'+Level+'".'); +END; + +PROCEDURE ValidationEditor; +VAR + TempValidation: ValidationRecordType; + Cmd: Char; + RecNumToList: Integer; + SaveTempPause: Boolean; + + PROCEDURE InitValidateVars(VAR Validation: ValidationRecordType); + VAR + User: UserRecordType; + BEGIN + LoadURec(User,0); + FillChar(Validation,SizeOf(Validation),0); + WITH Validation DO + BEGIN + Key := ' '; + ExpireTo := ' '; + Description := '<< New Validation Record >>'; + UserMsg := 'You have been validated, enjoy the system!'; + NewSL := User.SL; + NewDSL := User.DSL; + NewMenu := 0; + Expiration := 0; + NewFP := 0; + NewCredit := 0; + SoftAR := TRUE; + SoftAC := TRUE; + NewAR := []; + NewAC := []; + END; + END; + + PROCEDURE DeleteValidationLevel(TempValidation1: ValidationRecordType; RecNumToDelete: SmallInt); + VAR + User: UserRecordType; + RecNum: Integer; + BEGIN + IF (NumValKeys = 0) THEN + Messages(4,0,'validation records') + ELSE + BEGIN + RecNumToDelete := -1; + InputIntegerWOC('%LFValidation record to delete?',RecNumToDelete,[NumbersOnly],1,NumValKeys); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= NumValKeys) THEN + BEGIN + Reset(ValidationFile); + Seek(ValidationFile,(RecNumToDelete - 1)); + Read(ValidationFile,TempValidation1); + Close(ValidationFile); + LastError := IOResult; + IF (TempValidation1.Key = '!') THEN + BEGIN + Print('%LFYou can not delete the new user validation key.'); + PauseScr(FALSE); + END + ELSE + BEGIN + Print('%LFValidation: ^5'+TempValidation1.Description); + IF PYNQ('%LFAre you sure you want to delete it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Deleting validation record ...'); + FOR RecNum := 1 TO (MaxUsers - 1) DO + BEGIN + LoadURec(User,RecNum); + IF (User.ExpireTo = TempValidation1.Key) THEN + BEGIN + User.ExpireTo := ' '; + User.Expiration := 0; + END; + SaveURec(User,RecNum); + END; + Exclude(ValKeys,TempValidation1.Key); + Dec(RecNumToDelete); + Reset(ValidationFile); + IF (RecNumToDelete >= 0) AND (RecNumToDelete <= (FileSize(ValidationFile) - 2)) THEN + FOR RecNum := RecNumToDelete TO (FileSize(ValidationFile) - 2) DO + BEGIN + Seek(ValidationFile,(RecNum + 1)); + Read(ValidationFile,Validation); + Seek(ValidationFile,RecNum); + Write(ValidationFile,Validation); + END; + Seek(ValidationFile,(FileSize(ValidationFile) - 1)); + Truncate(ValidationFile); + Close(ValidationFile); + LastError := IOResult; + Dec(NumValKeys); + SysOpLog('* Deleted validation record: ^5'+TempValidation1.Description); + END; + END; + END; + END; + END; + + PROCEDURE CheckValidationLevel(Validation: ValidationRecordType; StartErrMsg,EndErrMsg: Byte; VAR Ok: Boolean); + VAR + Counter: Byte; + BEGIN + FOR Counter := StartErrMsg TO EndErrMsg DO + CASE Counter OF + 1 : IF (Validation.Description = '') OR (Validation.Description = '<< New Validation Record >>') THEN + BEGIN + Print('%LF^7The description is invalid!^1'); + OK := FALSE; + END; + END; + END; + + PROCEDURE EditValidationLevel(TempValidation1: ValidationRecordType; VAR Validation: ValidationRecordType; VAR Cmd1: Char; + VAR RecNumToEdit: SmallInt; VAR Changed: Boolean; Editing: Boolean); + VAR + User: UserRecordType; + CmdStr, + OneKCmds: AStr; + Cmd2: Char; + RecNumToList: Integer; + Ok, + SaveUpgrade: Boolean; + BEGIN + WITH Validation DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + CLS; + IF (Editing) THEN + PrintACR('^5Editing validation record #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumValKeys)) + ELSE + PrintACR('^5Inserting validation record #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumValKeys + 1)); + NL; + PrintACR('^1A. Key : ^5'+Key); + PrintACR('^1B. Description: ^5'+Description); + PrintACR('^1C. User msg : ^5'+AOnOff(UserMsg = '','*None*',UserMsg)); + PrintACR('^1D. New SL : ^5'+IntToStr(NewSL)); + PrintACR('^1E. New DSL : ^5'+IntToStr(NewDSL)); + PrintACR('^1G. AR : Flags: ^5'+DisplayARFlags(NewAR,'5','1')+ + ' ^1Upgrade: ^5'+AOnOff(SoftAR,'Soft','Hard')); + PrintACR('^1H. AC : Flags: ^5'+DisplayACFlags(NewAC,'5','1')+ + ' ^1Upgrade: ^5'+AOnOff(SoftAC,'Soft','Hard')); + PrintACR('^1I. New points : ^5'+IntToStr(NewFP)); + PrintACR('^1K. New credit : ^5'+IntToStr(NewCredit)); + PrintACR('^1M. Start menu : ^5'+IntToStr(NewMenu)); + PrintACR('^1N. Expiration : Days: ^5'+AOnOff((Expiration > 0),IntToStr(Expiration),'No Expiration')+ + ' ^1Level: ^5'+AOnOff((ExpireTo IN ['!'..'~']),ExpireTo,'No Change')); + END; + IF (NOT Editing) THEN + CmdStr := 'ABCDEGHIKMN' + ELSE + CmdStr := 'ABCDEGHIKMN[]FJL'; + LOneK('%LFModify menu [^5?^4=^5Help^4]: ',Cmd1,'Q?'+CmdStr+^M,TRUE,TRUE); + CASE Cmd1 OF + 'A' : BEGIN + Print('%LF^7You can not modify the validation key.'); + PauseScr(FALSE); + END; + 'B' : IF (Validation.Key = '!') THEN + BEGIN + Print('%LF^7You can not modify the new user description.'); + PauseScr(FALSE); + END + ELSE + REPEAT + TempValidation1.Description := Description; + Ok := TRUE; + InputWN1('%LFNew description: ',Description,(SizeOf(Description) - 1),[InterActiveEdit],Changed); + CheckValidationLevel(Validation,1,1,Ok); + IF (NOT Ok) THEN + Description := TempValidation1.Description; + UNTIL (Ok) OR (HangUp); + 'C' : InputWN1('%LF^1New user message:%LF^4:',UserMsg,(SizeOf(UserMsg) - 1),[InterActiveEdit],Changed); + 'D' : BEGIN + LoadURec(User,0); + REPEAT + InputByteWC('%LFEnter new SL',NewSL,[DisplayValue,NumbersOnly],User.SL,255,Changed); + UNTIL (NewSL >= User.SL) OR (HangUp); + END; + 'E' : BEGIN + LoadURec(User,0); + REPEAT + InputByteWC('%LFEnter new DSL',NewDSL,[DisplayValue,NumbersOnly],User.DSL,255,Changed); + UNTIL (NewDSL >= User.DSL) OR (HangUp); + END; + 'G' : BEGIN + REPEAT + Prt('%LFToggle which AR flag? ('+DisplayARFlags(NewAR,'5','4')+'^4)'+ + ' [^5*^4=^5All^4,^5?^4=^5Help^4,^5^4=^5Quit^4]: '); + OneK(Cmd1,^M'ABCDEFGHIJKLMNOPQRSTUVWXYZ*?',TRUE,TRUE); + IF (Cmd1 = '?') THEN + PrintF('ARFLAGS') + ELSE IF (Cmd1 IN ['A'..'Z']) THEN + ToggleARFlag(Cmd1,NewAR,Changed) + ELSE IF (Cmd1 = '*') THEN + FOR Cmd2 := 'A' TO 'Z' DO + ToggleARFlag(Cmd2,NewAr,Changed); + UNTIL (Cmd1 = ^M) OR (HangUp); + SaveUpgrade := SoftAR; + SoftAR := NOT PYNQ('%LFShould the AR upgrade be hard? ',0,FALSE); + IF (SaveUpgrade <> SoftAR) THEN + Changed := TRUE; + Cmd1 := #0; + END; + 'H' : BEGIN + REPEAT + Prt('%LFToggle which AC flag? ('+DisplayACFlags(NewAC,'5','4')+'^4)'+ + ' [^5?^4=^5Help^4,^5^4=^5Quit^4]: '); + OneK(Cmd1,^M'LCVUA*PEKM1234?',TRUE,TRUE); + IF (Cmd1 = '?') THEN + PrintF('ACFLAGS') + ELSE IF (Cmd1 <> ^M) THEN + ToggleACFlags(Cmd1,NewAC,Changed); + UNTIL (Cmd1 = ^M) OR (HangUp); + SaveUpgrade := SoftAC; + SoftAC := NOT PYNQ('%LFShould the AC upgrade be hard? ',0,FALSE); + IF (SaveUpgrade <> SoftAC) THEN + Changed := TRUE; + Cmd1 := #0; + END; + 'I' : InputLongIntWC('%LFEnter additional file points',NewFP, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'K' : InputLongIntWC('%LFEnter additional credit',NewCredit,[DisplayValue,NumbersOnly],0,2147483647,Changed); + 'M' : FindMenu('%LFEnter start menu (^50^4=^5Default^4)',NewMenu,0,NumMenus,Changed); + 'N' : IF (Validation.Key = '!') THEN + BEGIN + Print('%LF^7You can not modify the new user expiration days or level.'); + PauseScr(FALSE); + END + ELSE + BEGIN + InputWordWC('%LFEnter days until expiration',Expiration,[DisplayValue,NumbersOnly],0,65535,Changed); + OneKCmds := ''; + FOR Cmd2 := '!' TO '~' DO + IF (Cmd2 IN ValKeys) THEN + IF (NOT (Cmd2 = Key)) THEN + OneKCmds := OneKCmds + Cmd2; + Prt('%LFEnter expiration level (^5!^4-^5P^4,^5R^4-^5p^4,^5r^4-^5~^4) [^5^4=^5No Change^4]: '); + OneK1(Cmd1,^M' '+OneKCmds,TRUE,TRUE); + IF (Cmd1 = ' ') OR (Cmd1 IN ValKeys) THEN + BEGIN + IF (Cmd1 <> ExpireTo) THEN + Changed := TRUE; + ExpireTo := Cmd1; + END; + IF (Expiration = 0) THEN + BEGIN + ExpireTo := ' '; + Changed := TRUE; + END; + IF (ExpireTo = ' ') THEN + BEGIN + Expiration := 0; + Changed := TRUE; + END; + Cmd1 := #0; + Cmd2 := #0; + END; + '[' : IF (RecNumToEdit > 1) THEN + Dec(RecNumToEdit) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + ']' : IF (RecNumToEdit < NumValKeys) THEN + Inc(RecNumToEdit) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNumToEdit <> 1) THEN + RecNumToEdit := 1 + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + InputIntegerWOC('%LFJump to entry',RecNumToEdit,[NumbersOnly],1,NumValKeys); + IF (RecNumToEdit < 1) OR (RecNumToEdit > NumValKeys) THEN + Cmd1 := #0; + END; + 'L' : IF (RecNumToEdit <> NumValKeys) THEN + RecNumToEdit := NumValKeys + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay current screen'); + Print('^3A^1-^3E^1,^3G^1-^3I^1,^3K^1,^3M^1-^3N^1:Modify item'); + IF (NOT Editing) THEN + LCmds(20,3,'Quit and save','') + ELSE + BEGIN + LCmds(20,3,'[Back entry',']Forward entry'); + LCmds(20,3,'First entry in list','Jump to entry'); + LCmds(20,3,'Last entry in list','Quit and save'); + END; + END; + END; + UNTIL (Pos(Cmd1,'Q[]FJL') <> 0) OR (HangUp); + END; + + PROCEDURE InsertValidationLevel(TempValidation1: ValidationRecordType; Cmd1: Char; RecNumToInsertBefore: SmallInt); + VAR + OneKCmds: AStr; + RecNum, + RecNumToEdit: SmallInt; + Ok, + Changed: Boolean; + BEGIN + IF (NumValKeys = MaxValKeys) THEN + Messages(5,MaxValKeys,'validation records') + ELSE + BEGIN + RecNumToInsertBefore := -1; + InputIntegerWOC('%LFValidation record to insert before?',RecNumToInsertBefore,[NumbersOnly],1,(NumValKeys + 1)); + IF (RecNumToInsertBefore >= 1) AND (RecNumToInsertBefore <= (NumValKeys + 1)) THEN + BEGIN + OneKCmds := ''; + FOR Cmd1 := '!' TO '~' DO + IF (NOT (Cmd1 IN ValKeys)) AND (NOT (Cmd1 = 'Q')) AND (NOT (Cmd1 = 'q')) THEN + OneKCmds := OneKCmds + Cmd1; + Prt('%LFChoose validation key (^5!^4-^5P^4,^5R^4-^5p^4,^5r^4-^5~^4) [^5^4=^5Quit^4]: '); + OneK1(Cmd1,^M+OneKCmds,TRUE,TRUE); + IF (Cmd1 <> ^M) THEN + BEGIN + Reset(ValidationFile); + InitValidateVars(TempValidation1); + TempValidation1.Key := Cmd1; + IF (RecNumToInsertBefore = 1) THEN + RecNumToEdit := 1 + ELSE IF (RecNumToInsertBefore = (NumValKeys + 1)) THEN + RecNumToEdit := (NumValKeys + 1) + ELSE + RecNumToEdit := RecNumToInsertBefore; + REPEAT + OK := TRUE; + EditValidationLevel(TempValidation1,TempValidation1,Cmd1,RecNumToEdit,Changed,FALSE); + CheckValidationLevel(TempValidation1,1,1,Ok); + IF (NOT OK) THEN + IF (NOT PYNQ('%LFContinue inserting validation record? ',0,TRUE)) THEN + Abort := TRUE; + UNTIL (OK) OR (Abort) OR (HangUp); + IF (NOT Abort) AND (PYNQ('%LFIs this what you want? ',0,FALSE)) THEN + BEGIN + Include(ValKeys,Cmd1); + Print('%LF[> Inserting validation record ...'); + Seek(ValidationFile,FileSize(ValidationFile)); + Write(ValidationFile,Validation); + Dec(RecNumToInsertBefore); + FOR RecNum := ((FileSize(ValidationFile) - 1) - 1) DOWNTO RecNumToInsertBefore DO + BEGIN + Seek(ValidationFile,RecNum); + Read(ValidationFile,Validation); + Seek(ValidationFile,(RecNum + 1)); + Write(ValidationFile,Validation); + END; + FOR RecNum := RecNumToInsertBefore TO ((RecNumToInsertBefore + 1) - 1) DO + BEGIN + Seek(ValidationFile,RecNum); + Write(ValidationFile,TempValidation1); + Inc(NumValKeys); + SysOpLog('* Inserted validation record: ^5'+TempValidation1.Description); + END; + END; + Close(ValidationFile); + LastError := IOResult; + END; + END; + END; + END; + + PROCEDURE ModifyValidationLevel(TempValidation1: ValidationRecordType; Cmd1: Char; RecNumToEdit: SmallInt); + VAR + SaveRecNumToEdit: Integer; + Ok, + Changed: Boolean; + BEGIN + IF (NumValKeys = 0) THEN + Messages(4,0,'validation records') + ELSE + BEGIN + RecNumToEdit := -1; + InputIntegerWOC('%LFValidation record to modify?',RecNumToEdit,[NumbersOnly],1,NumValKeys); + IF (RecNumToEdit >= 1) AND (RecNumToEdit <= NumValKeys) THEN + BEGIN + SaveRecNumToEdit := -1; + Cmd1 := #0; + Reset(ValidationFile); + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNumToEdit <> RecNumToEdit) THEN + BEGIN + Seek(ValidationFile,(RecNumToEdit - 1)); + Read(ValidationFile,Validation); + SaveRecNumToEdit := RecNumToEdit; + Changed := FALSE; + END; + REPEAT + Ok := TRUE; + EditValidationLevel(TempValidation1,Validation,Cmd1,RecNumToEdit,Changed,TRUE); + CheckValidationLevel(Validation,1,1,Ok); + IF (NOT OK) THEN + BEGIN + PauseScr(FALSE); + IF (RecNumToEdit <> SaveRecNumToEdit) THEN + RecNumToEdit := SaveRecNumToEdit; + END; + UNTIL (OK) OR (HangUp); + IF (Changed) THEN + BEGIN + Seek(ValidationFile,(SaveRecNumToEdit - 1)); + Write(ValidationFile,Validation); + Changed := FALSE; + SysOpLog('* Modified validation record: ^5'+Validation.Description); + END; + END; + Close(ValidationFile); + LastError := IOResult; + END; + END; + END; + + PROCEDURE PositionValidationLevel(TempValidation1: ValidationRecordType; RecNumToPosition: SmallInt); + VAR + RecNumToPositionBefore, + RecNum1, + RecNum2: SmallInt; + BEGIN + IF (NumValKeys = 0) THEN + Messages(4,0,'validation records') + ELSE IF (NumValKeys = 1) THEN + Messages(6,0,'validation records') + ELSE + BEGIN + RecNumToPosition := -1; + InputIntegerWOC('%LFPosition which validation record?',RecNumToPosition,[NumbersOnly],1,NumValKeys); + IF (RecNumToPosition >= 1) AND (RecNumToPosition <= NumValKeys) THEN + BEGIN + Print('%LFAccording to the current numbering system.'); + RecNumToPositionBefore := -1; + InputIntegerWOC('%LFPosition before which validation record?',RecNumToPositionBefore,[NumbersOnly],1,(NumValKeys + 1)); + IF (RecNumToPositionBefore >= 1) AND (RecNumToPositionBefore <= (NumValKeys + 1)) AND + (RecNumToPositionBefore <> RecNumToPosition) AND (RecNumToPositionBefore <> (RecNumToPosition + 1)) THEN + BEGIN + Print('%LF[> Positioning validation records ...'); + Reset(ValidationFile); + IF (RecNumToPositionBefore > RecNumToPosition) THEN + Dec(RecNumToPositionBefore); + Dec(RecNumToPosition); + Dec(RecNumToPositionBefore); + Seek(ValidationFile,RecNumToPosition); + Read(ValidationFile,TempValidation1); + RecNum1 := RecNumToPosition; + IF (RecNumToPosition > RecNumToPositionBefore) THEN + RecNum2 := -1 + ELSE + RecNum2 := 1; + WHILE (RecNum1 <> RecNumToPositionBefore) DO + BEGIN + IF ((RecNum1 + RecNum2) < FileSize(ValidationFile)) THEN + BEGIN + Seek(ValidationFile,(RecNum1 + RecNum2)); + Read(ValidationFile,Validation); + Seek(ValidationFile,RecNum1); + Write(ValidationFile,Validation); + END; + Inc(RecNum1,RecNum2); + END; + Seek(ValidationFile,RecNumToPositionBefore); + Write(ValidationFile,TempValidation1); + Close(ValidationFile); + LastError := IOResult; + END; + END; + END; + END; + +BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + RecNumToList := 1; + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + DisplayValidationRecords(RecNumToList); + LOneK('%LFValidation editor [^5?^4=^5Help^4]: ',Cmd,'QDIMP?'^M,TRUE,TRUE); + CASE Cmd OF + ^M : IF (RecNumToList < 1) OR (RecNumToList > NumValKeys) THEN + RecNumToList := 1; + 'D' : DeleteValidationLevel(TempValidation,RecNumToList); + 'I' : InsertValidationLevel(TempValidation,Cmd,RecNumToList); + 'M' : ModifyValidationLevel(TempValidation,Cmd,RecNumToList); + 'P' : PositionValidationLevel(TempValidation,RecNumToList); + '?' : BEGIN + Print('%LF^1<^3CR^1>Next screen or redisplay screen'); + Print('^1(^3?^1)Help/First validation level'); + LCmds(24,3,'Delete validation level','Insert validation level'); + LCmds(24,3,'Modify validation level','Position validation level'); + LCmds(24,3,'Quit',''); + END; + END; + IF (Cmd <> ^M) THEN + RecNumToList := 1; + UNTIL (Cmd = 'Q') OR (HangUp); + TempPause := SaveTempPause; + LastError := IOResult; +END; + +END. diff --git a/SOURCE/SYSOP2H.PAS b/SOURCE/SYSOP2H.PAS new file mode 100644 index 0000000..4dd3acf --- /dev/null +++ b/SOURCE/SYSOP2H.PAS @@ -0,0 +1,135 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp2H; + +INTERFACE + +PROCEDURE NetworkConfiguration; + +IMPLEMENTATION + +USES + Common, + NodeList; + +PROCEDURE NetworkConfiguration; +VAR + Cmd: Char; + Counter: Byte; + Changed: Boolean; +BEGIN + REPEAT + WITH General DO + BEGIN + Abort := FALSE; + Next := FALSE; + Print('%CL^5Network Configuration:'); + NL; + PrintACR('^1A. Net addresses'); + PrintACR('^1B. Origin line : ^5'+Origin); + NL; + PrintACR('^1C. Strip IFNA kludge lines : ^5'+ShowYesNo(SKludge)+ + '^1 1. Color of standard text : ^'+IntToStr(Text_Color)+IntToStr(Text_Color)); + PrintACR('^1D. Strip SEEN-BY lines : ^5'+ShowYesNo(SSeenBy)+ + '^1 2. Color of quoted text : ^'+IntToStr(Quote_Color)+IntToStr(Quote_Color)); + PrintACR('^1E. Strip origin lines : ^5'+ShowYesNo(SOrigin)+ + '^1 3. Color of tear line : ^'+IntToStr(Tear_Color)+IntToStr(Tear_Color)); + PrintACR('^1F. Add tear/origin line : ^5'+ShowYesNo(AddTear)+ + '^1 4. Color of origin line : ^'+IntToStr(Origin_Color)+IntToStr(Origin_Color)); + NL; + PrintACR('^1G. Default Echomail path : ^5'+DefEchoPath); + PrintACR('^1H. Netmail path : ^5'+NetMailPath); + PrintACR('^1I. Netmail attributes : ^5'+NetMail_Attr(NetAttribute)); + PrintACR('^1J. UUCP gate address : ^5'+PadLeftStr('^5'+IntToStr(AKA[20].Zone)+':'+IntToStr(AKA[20].Net)+ + '/'+IntToStr(AKA[20].Node)+'.'+IntToStr(AKA[20].Point),20)); + Prt('%LFEnter selection [^5A^4-^5J^4,^51^4-^54^4,^5Q^4=^5Quit^4]: '); + OneK(Cmd,'QABCDEFGHIJ1234'^M,TRUE,TRUE); + CASE Cmd OF + 'A' : BEGIN + REPEAT + Abort := FALSE; + Next := FALSE; + Print('%CL^5Network Addresses:^1'); + NL; + FOR Counter := 0 TO 19 DO + BEGIN + Prompt('^1'+Chr(Counter + 65)+'. Address #'+PadLeftInt(Counter,2)+' : '+ + PadLeftStr('^5'+IntToStr(AKA[Counter].Zone)+ + ':'+IntToStr(AKA[Counter].Net)+ + '/'+IntToStr(AKA[Counter].Node)+ + '.'+IntToStr(AKA[Counter].Point),20)); + IF (Odd(Counter)) THEN + NL; + END; + LOneK('%LFEnter selection [^5A^4-^5T^4,^5^4=^5Quit^4]: ',Cmd,^M'ABCDEFGHIJKLMNOPQRST',TRUE,TRUE); + IF (Cmd IN ['A'..'T']) THEN + GetNewAddr('%LFEnter new network address (^5Z^4:^5N^4/^5N^4.^5P^4 format): ',30, + AKA[(Ord(Cmd) - 65)].Zone, + AKA[(Ord(Cmd) - 65)].Net, + AKA[(Ord(Cmd) - 65)].Node, + AKA[(Ord(Cmd) - 65)].Point); + UNTIL (Cmd = ^M) OR (HangUp); + Cmd := #0; + END; + 'B' : InputWN1('%LF^1Enter new origin line:%LF^4: ',Origin,50,[],Changed); + 'C' : SKludge := NOT SKludge; + 'D' : SSeenBy := NOT SSeenBy; + 'E' : SOrigin := NOT SOrigin; + 'F' : AddTear := NOT AddTear; + 'G' : InputPath('%LF^1Enter new default echomail path (^5End with a ^1"^5\^1"):%LF^4:',DefEchoPath,TRUE,FALSE,Changed); + 'H' : InputPath('%LF^1Enter new netmail path (^5End with a ^1"^5\^1"):%LF^4:',NetMailPath,TRUE,FALSE,Changed); + 'I' : BEGIN + + REPEAT + Print('%LF^1Netmail attributes: ^5'+NetMail_Attr(NetAttribute)+'^1'); + LOneK('%LFToggle attributes (CHIKLP) [?]Help [Q]uit: ',Cmd,'QPCKHIL?',TRUE,TRUE); + CASE Cmd OF + 'C','H','I','K','L','P' : + ToggleNetAttrS(Cmd,NetAttribute); + '?' : BEGIN + NL; + LCmds(22,3,'Crash mail','Hold'); + LCmds(22,3,'In-Transit','Kill-Sent'); + LCmds(22,3,'Local','Private'); + END; + END; + + UNTIL (Cmd = 'Q') OR (HangUp); + + Cmd := #0; + END; + 'J' : GetNewAddr('%LFEnter new UUCP Gate Address (^5Z^4:^5N^4/^5N^4.^5P^4 format): ',30, + AKA[20].Zone, + AKA[20].Net, + AKA[20].Node, + AKA[20].Point); + '1' : BEGIN + Prompt('%LF^5Colors: '); + ShowColors; + InputByteWC('%LFNew standard text color',Text_Color,[DisplayValue,NumbersOnly],0,9,Changed); + END; + '2' : BEGIN + Prompt('%LF^5Colors: '); + ShowColors; + InputByteWC('%LFNew quoted text color',Quote_Color,[DisplayValue,NumbersOnly],0,9,Changed); + END; + '3' : BEGIN + Prompt('%LF^5Colors: '); + ShowColors; + InputByteWC('%LFNew tear line color',Tear_Color,[DisplayValue,NumbersOnly],0,9,Changed); + END; + '4' : BEGIN + Prompt('%LF^5Colors: '); + ShowColors; + InputByteWC('%LFNew origin line color',Origin_Color,[DisplayValue,NumbersOnly],0,9,Changed); + END; + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +END. diff --git a/SOURCE/SYSOP2I.PAS b/SOURCE/SYSOP2I.PAS new file mode 100644 index 0000000..5366472 --- /dev/null +++ b/SOURCE/SYSOP2I.PAS @@ -0,0 +1,61 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT SysOp2I; + +INTERFACE + +PROCEDURE OfflineMailConfiguration; + +IMPLEMENTATION + +USES + Common; + +PROCEDURE OfflineMailConfiguration; +VAR + Cmd: CHAR; + Changed: Boolean; +BEGIN + REPEAT + WITH General DO + BEGIN + Abort := FALSE; + Next := FALSE; + Print('%CL^5Offline Mail Configuration:'); + NL; + PrintACR('^1A. QWK/REP Packet name : ^5'+PacketName); + PrintACR('^1B. Welcome screen name : ^5'+QWKWelcome); + PrintACR('^1C. News file name : ^5'+QWKNews); + PrintACR('^1D. Goodbye file name : ^5'+QWKGoodbye); + PrintACR('^1E. Local QWK/REP path : ^5'+QWKLocalPath); + PrintACR('^1F. Ignore time for DL : ^5'+ShowOnOff(QWKTimeIgnore)); + PrintACR('^1G. Max total messages : ^5'+IntToStr(MaxQWKTotal)); + PrintACR('^1H. Max msgs per base : ^5'+IntToStr(MaxQWKBase)); + PrintACR('^1I. ACS for Network .REP: ^5'+QWKNetworkACS); + Prt('%LFEnter selection [^5A^4-^5I^4,^5Q^4=^5Quit^4]: '); + OneK(Cmd,'QABCDEFGHI'^M,TRUE,TRUE); + CASE Cmd OF + 'A' : InputWN1('%LFQWK Packet name: ',PacketName,(SizeOf(PacketName) - 1),[InterActiveEdit],Changed); + 'B' : InputWN1('%LF^1Welcome screen file d:\path\name (^5Do not enter ^1"^5.EXT^1"):%LF^4: ', + QWKWelcome,(SizeOf(QWKWelcome) - 1), + [UpperOnly,InterActiveEdit],Changed); + 'C' : InputWN1('%LF^1News file d:\path\name (^5Do not enter ^1"^5.EXT^1"):%LF^4: ',QWKNews,(SizeOf(QWKNews) - 1), + [UpperOnly,InterActiveEdit],Changed); + 'D' : InputWN1('%LF^1Goodbye file d:\path\name (^5Do not enter ^1"^5.EXT^1"):%LF^4: ', + QWKGoodbye,(SizeOf(QWKGoodBye) - 1), + [UpperOnly,InterActiveEdit],Changed); + 'E' : InputPath('%LF^1Enter local QWK reader path (^5End with a ^1"^5\^1"):%LF^4:',QWKLocalPath,TRUE,FALSE,Changed); + 'F' : QWKTimeIgnore := NOT QWKTimeIgnore; + 'G' : InputWordWOC('%LFMaximum total messages in a QWK packet',MaxQWKTotal,[DisplayValue,NumbersOnly],0,65535); + 'H' : InputWordWOC('%LFMaximum messages per base in a packet',MaxQWKBase,[DisplayValue,NumbersOnly],0,65535); + 'I' : InputWN1('%LFNew ACS: ',QWKNetworkACS,(SizeOf(QWKNetworkACS) - 1),[InterActiveEdit],Changed); + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +END. diff --git a/SOURCE/SYSOP2J.PAS b/SOURCE/SYSOP2J.PAS new file mode 100644 index 0000000..b4c18ef --- /dev/null +++ b/SOURCE/SYSOP2J.PAS @@ -0,0 +1,823 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp2J; + +INTERFACE + +PROCEDURE ColorConfiguration; + +IMPLEMENTATION + +USES + Common, + File11, + File1, + Mail4, + TimeFunc; + +PROCEDURE ColorConfiguration; +CONST + ColorName: ARRAY[0..7] OF STRING[7] = ('Black','Blue','Green','Cyan','Red','Magenta','Yellow','White'); +VAR + TempScheme: SchemeRec; + Cmd: Char; + RecNumToList: Integer; + SaveTempPause: Boolean; + + FUNCTION DisplayColorStr(Color: Byte): AStr; + VAR + TempStr: AStr; + BEGIN + TempStr := ColorName[Color AND 7]+' on '+ColorName[(Color SHR 4) AND 7]; + IF ((Color AND 8) <> 0) THEN + TempStr := 'Bright '+TempStr; + IF ((Color AND 128) <> 0) THEN + TempStr := 'Blinking '+TempStr; + DisplayColorStr := TempStr; + END; + + FUNCTION GetColor: Byte; + VAR + NewColor, + SaveOldColor, + TempColor, + Counter: Byte; + BEGIN + SetC(7); + NL; + FOR Counter := 0 TO 7 DO + BEGIN + SetC(7); + Prompt(IntToStr(Counter)+'. '); + SetC(Counter); + Prompt(PadLeftStr(ColorName[Counter],12)); + SetC(7); + Prompt(PadRightInt((Counter + 8),2)+'. '); + SetC(Counter + 8); + Print(PadLeftStr(ColorName[Counter]+'!',9)); + END; + InputByteWOC('%LFForeground',TempColor,[Numbersonly],0,15); (* Suppress Error *) + IF (TempColor IN [0..15]) THEN + NewColor := TempColor + ELSE + NewColor := 7; + NL; + FOR Counter := 0 TO 7 DO + BEGIN + SetC(7); + Prompt(IntToStr(Counter)+'. '); + SetC(Counter); + Print(PadLeftStr(ColorName[Counter],12)); + END; + InputByteWOC('%LFBackground',TempColor,[NumbersOnly],0,7); (* Suppress Error *) + IF (TempColor IN [0..7]) THEN + NewColor := NewColor OR TempColor SHL 4; + IF PYNQ('%LFBlinking? ',0,FALSE) THEN + NewColor := NewColor OR 128; + SetC(7); + Prompt('%LFExample: '); + SetC(NewColor); + Print(DisplayColorStr(NewColor)); + SetC(7); + GetColor := NewColor; + END; + + PROCEDURE SystemColors(VAR TempScheme1: SchemeRec; Cmd1: Char; VAR Changed: Boolean); + VAR + Counter, + NewColor: Byte; + BEGIN + REPEAT + CLS; + NL; + FOR Counter := 1 TO 10 DO + BEGIN + SetC(7); + Prompt(PadRightInt((Counter - 1),2)+'. System color '+PadRightInt((Counter - 1),2)+': '); + SetC(TempScheme1.Color[Counter]); + Print(DisplayColorStr(Scheme.Color[Counter])); + END; + LOneK('%LFSystem color to change [^50^4-^59^4,^5^4=^5Quit^4]: ',Cmd1,^M'0123456789',TRUE,TRUE); + IF (Cmd1 IN ['0'..'9']) THEN + BEGIN + NewColor := GetColor; + IF PYNQ('%LFIs this correct? ',0,FALSE) THEN + BEGIN + TempScheme1.Color[Ord(Cmd1) - Ord('0') + 1] := NewColor; + Changed := TRUE; + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + END; + + PROCEDURE FileColors(VAR TempScheme1: SchemeRec; Cmd1: Char; VAR Changed: Boolean); + VAR + F: FileInfoRecordType; + NewColor: Byte; + BEGIN + REPEAT + Abort := FALSE; + Next := FALSE; + FileAreaNameDisplayed := FALSE; + DisplayFileAreaHeader; + WITH F DO + BEGIN + FileName := 'RENEGADE.ZIP'; + Description := 'Latest version of Renegade!'; + FilePoints := 0; + Downloaded := 0; + FileSize := 2743; + OwnerNum := 1; + OwnerName:= 'Exodus'; + FileDate := Date2Pd(DateStr); + VPointer := -1; + VTextSize := 0; + FIFlags := []; + END; + lDisplay_File(F,1,'',FALSE); + PrintACR(PadLeftStr('',28)+'This is the latest version available'); + PrintACR(PadLeftStr('',28)+'Uploaded by: Exodus'); + WITH F DO + BEGIN + FileName := 'RG .ZIP'; + Description := 'Latest Renegade upgrade.'; + FilePoints := 0; + Downloaded := 0; + FileSize := 2158; + OwnerNum := 2; + OwnerName := 'Nuclear'; + FileDate := Date2PD(DateStr); + VPointer := -1; + VTextSize := 0; + FIFlags := []; + END; + lDisplay_File(F,2,'RENEGADE',FALSE); + PrintACR(PadLeftStr('',28)+'This is the latest upgrade available'); + PrintACR(PadLeftStr('',28)+'Uploaded by: Nuclear'); + NL; + LCmds3(20,3,'A Border','B File Name field','C Pts Field'); + LCmds3(20,3,'D Size field','E Desc Field','F Area field'); + NL; + LCmds3(20,3,'G File name','H File Points','I File size'); + LCmds3(20,3,'J File desc','K Extended','L Status flags'); + LCmds(20,3,'M Uploader','N Search Match'); + LOneK('%LFFile color to change [^5A^4-^5N^4,^5^4=^5Quit^4]: ',Cmd1,^M'ABCDEFGHIJKLMN',TRUE,TRUE); + IF (Cmd1 IN ['A'..'N']) THEN + BEGIN + NewColor := GetColor; + IF PYNQ('%LFIs this correct? ',0,FALSE) THEN + BEGIN + TempScheme1.Color[Ord(Cmd1) - 54] := NewColor; + Changed := TRUE; + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + END; + + PROCEDURE MsgColors(VAR TempScheme1: SchemeRec; Cmd1: Char; VAR Changed: Boolean); + VAR + NewColor: Byte; + BEGIN + REPEAT + Abort := FALSE; + Next := FALSE; + CLS; { starts at color 28 } + PrintACR('Ŀ'); + PrintACR(' Msg#  Sender  Receiver  '+ + 'Subject ! Posted '); + PrintACR(''); + PrintACR('''* "2# Exodus $Nuclear %Re: Renegade &01/01/93'); + PrintACR('''> "3# Nuclear $Exodus %RG Update &01/01/93'); + NL; + LCmds3(20,3,'A Border','B Msg Num field','C Sender Field'); + LCmds3(20,3,'D Receiver field','E Subject Field','F Date field'); + NL; + LCmds3(20,3,'G Msg Num','H Msg Sender','I Msg Receiver'); + LCmds3(20,3,'J Subject','K Msg Date','L Status flags'); + LOneK('%LFMessage color to change [^5A^4-^5L^4,^5^4=^5Quit^4]: ',Cmd1,^M'ABCDEFGHIJKL',TRUE,TRUE); + IF (Cmd1 IN ['A'..'L']) THEN + BEGIN + NewColor := GetColor; + IF PYNQ('%LFIs this correct? ',0,FALSE) THEN + BEGIN + TempScheme1.Color[Ord(Cmd1) - 37] := NewColor; + Changed := TRUE; + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + END; + + PROCEDURE FileAreaColors(VAR TempScheme1: SchemeRec; Cmd1: Char; VAR Changed: Boolean); + VAR + NewColor: Byte; + FArea, + NumFAreas: Integer; + SaveConfSystem: Boolean; + BEGIN + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + REPEAT + Abort := FALSE; + Next := FALSE; + Farea := 1; + NumFAreas := 0; + LFileAreaList(FArea,NumFAreas,10,TRUE); { starts at 45 } + NL; + LCmds3(20,3,'A Border','B Base Num field','C Base Name Field'); + NL; + LCmds3(20,3,'D Scan Indicator','E Base Number','F Base Name'); + LOneK('%LFFile area color to change [^5A^4-^5F^4,^5^4=^5Quit^4]: ',Cmd1,^M'ABCDEF',TRUE,TRUE); + IF (Cmd1 IN ['A'..'F']) THEN + BEGIN + NewColor := GetColor; + IF PYNQ('%LFIs this correct? ',0,FALSE) THEN + BEGIN + TempScheme1.Color[Ord(Cmd1) - 20] := NewColor; + Changed := TRUE; + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + END; + + PROCEDURE MsgAreaColors(VAR TempScheme1: SchemeRec; Cmd1: Char; VAR Changed: Boolean); + VAR + NewColor: Byte; + MArea, + NumMAreas: Integer; + BEGIN + REPEAT + Abort := FALSE; + Next := FALSE; + MArea := 1; + NumMAreas := 0; + MessageAreaList(MArea,NumMAreas,5,TRUE); { starts at 55 } + NL; + LCmds3(20,3,'A Border','B Base Num field','C Base Name Field'); + NL; + LCmds3(20,3,'D Scan Indicator','E Base Number','F Base Name'); + LOneK('%LFMessage area color to change [^5A^4-^5F^4,^5^4=^5Quit^4]: ',Cmd1,^M'ABCDEF',TRUE,TRUE); + IF (Cmd1 IN ['A'..'F']) THEN + BEGIN + NewColor := GetColor; + IF PYNQ('%LFIs this correct? ',0,FALSE) THEN + BEGIN + TempScheme1.Color[Ord(Cmd1) - 10] := NewColor; + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + END; + + PROCEDURE QWKColors(VAR TempScheme1: SchemeRec; Cmd1: Char; VAR Changed: Boolean); + VAR + NewColor: Byte; + BEGIN + REPEAT + Abort := FALSE; + Next := FALSE; + CLS; { starts at 115 } + Print(Centre('|The QWKSystem is now gathering mail.')); + NL; + PrintACR('sĿ'); + PrintACR('st Num su Message base name sv Short sw Echo sx Total '+ + 'sy New sz Your s{ Size s'); + PrintACR('s'); + PrintACR(' }1 ~General GENERAL No 530 328 13 103k'); + PrintACR(' }2 ~Not so general NSGEN No 854  86 15 43k'); + PrintACR(' }3 ~Vague VAGUE No 985 148 8 74k'); + NL; + LCmds3(20,3,'A Border','B Base num field','C Base name field'); + LCmds3(20,3,'D Short field','E Echo field','F Total field'); + LCmds3(20,3,'G New field','H Your field','I Size field'); + NL; + LCmds3(20,3,'J Title','K Base Number','L Base name'); + LCmds3(20,3,'M Short','N Echo flag','O Total Msgs'); + LCmds3(20,3,'P New Msgs','R Your Msgs','S Msgs size'); + LOneK('%LFQWK color to change [^5A^4-^5S^4,^5^4=^5Quit^4]: ',Cmd1,^M'ABCDEFGHIJKLMNOPRS'^M,TRUE,TRUE); + IF (Cmd1 IN ['A'..'P','R'..'S']) THEN + BEGIN + NewColor := GetColor; + IF PYNQ('%LFIs this correct? ',0,FALSE) THEN + IF (Cmd1 < 'Q') THEN + BEGIN + TempScheme1.Color[Ord(Cmd1) + 50] := NewColor; + Changed := TRUE; + END + ELSE + BEGIN + TempScheme1.Color[Ord(Cmd1) + 49] := NewColor; + Changed := TRUE; + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + END; + + PROCEDURE EmailColors(VAR TempScheme1: SchemeRec; Cmd1: Char; VAR Changed: Boolean); + VAR + NewColor: Byte; + BEGIN + REPEAT + Abort := FALSE; + Next := FALSE; + CLS; { starts at 135 } + PrintACR('Ŀ'); + PrintACR(' Num  Date/Time  Sender  Subject '); + PrintACR(''); + PrintACR(' 1 01 Jan 1993 01:00a Exodus Renegade'); + PrintACR(' 1 01 Jan 1993 01:00a Nuclear Upgrades'); + NL; + LCmds3(20,3,'A Border','B Number field','C Date/Time field'); + LCmds(20,3,'D Sender field','E Subject field'); + NL; + LCmds3(20,3,'F Number','G Date/Time','H Sender'); + LCmds(20,3,'I Subject',''); + LOneK('%LFEmail color to change [^5A^4-^5I^4,^5^4=^5Quit^4]: ',Cmd1,^M'QABCDEFGHI',TRUE,TRUE); + IF (Cmd1 IN ['A'..'I']) THEN + BEGIN + NewColor := GetColor; + IF PYNQ('%LFIs this correct? ',0,FALSE) THEN + BEGIN + TempScheme1.Color[Ord(Cmd1) + 70] := NewColor; + Changed := TRUE; + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + END; + + PROCEDURE InitSchemeVars(VAR Scheme: SchemeRec); + BEGIN + WITH Scheme DO + BEGIN + Description := '<< New Color Scheme >>'; + FillChar(Color,SizeOf(Color),7); + Color[1] := 15; + Color[2] := 3; + Color[3] := 13; + Color[4] := 11; + Color[5] := 9; + Color[6] := 14; + Color[7] := 31; + Color[8] := 4; + Color[9] := 132; + Color[10] := 10; + END; + END; + + PROCEDURE DeleteScheme(TempScheme1: SchemeRec; RecNumToDelete: SmallInt); + VAR + User: UserRecordType; + RecNum: Integer; + BEGIN + IF (NumSchemes = 0) THEN + Messages(4,0,'color schemes') + ELSE + BEGIN + RecNumToDelete := -1; + InputIntegerWOC('%LFColor scheme to delete',RecNumToDelete,[NumbersOnly],1,NumSchemes); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= NumSchemes) THEN + BEGIN + Reset(SchemeFile); + Seek(SchemeFile,(RecNumToDelete - 1)); + Read(SchemeFile,TempScheme1); + Close(SchemeFile); + LastError := IOResult; + Print('%LFColor scheme: ^5'+TempScheme1.Description); + IF PYNQ('%LFAre you sure you want to delete it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Deleting color scheme record ...'); + Dec(RecNumToDelete); + Reset(SchemeFile); + IF (RecNumToDelete >= 0) AND (RecNumToDelete <= (FileSize(SchemeFile) - 2)) THEN + FOR RecNum := RecNumToDelete TO (FileSize(SchemeFile) - 2) DO + BEGIN + Seek(SchemeFile,(RecNum + 1)); + Read(SchemeFile,Scheme); + Seek(SchemeFile,RecNum); + Write(SchemeFile,Scheme); + END; + Seek(SchemeFile,(FileSize(SchemeFile) - 1)); + Truncate(SchemeFile); + Close(SchemeFile); + LastError := IOResult; + Dec(NumSchemes); + SysOpLog('* Deleted color scheme: ^5'+TempScheme1.Description); + Inc(RecNumToDelete); + Print('%LFUpdating user records ...'); + Reset(UserFile); + RecNum := 1; + WHILE (RecNum < FileSize(UserFile)) DO + BEGIN + LoadURec(User,RecNum); + IF (User.ColorScheme = RecNumToDelete) THEN + BEGIN + User.ColorScheme := 1; + SaveURec(User,RecNum); + END + ELSE IF (User.ColorScheme > RecNumTodelete) THEN + BEGIN + Dec(User.ColorScheme); + SaveURec(User,RecNum); + END; + Inc(RecNum); + END; + Close(UserFile); + LastError := IOResult; + END; + END; + END; + END; + + PROCEDURE CheckScheme(Scheme: SchemeRec; StartErrMsg,EndErrMsg: Byte; VAR Ok: Boolean); + VAR + Counter: Byte; + BEGIN + FOR Counter := StartErrMsg TO EndErrMsg DO + CASE Counter OF + 1 : IF (Scheme.Description = '') OR (Scheme.Description = '<< New Color Scheme >>') THEN + BEGIN + Print('%LF^7The description is invalid!^1'); + OK := FALSE; + END; + END; + END; + + PROCEDURE EditScheme(TempScheme1: SchemeRec; VAR Scheme: SchemeRec; VAR Cmd1: Char; + VAR RecNumToEdit: SmallInt; VAR Changed: Boolean; Editing: Boolean); + VAR + CmdStr: AStr; + Ok: Boolean; + BEGIN + WITH Scheme DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + CLS; + IF (Editing) THEN + PrintACR('^5Editing color scheme #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumSchemes)) + ELSE + PrintACR('^5Inserting color scheme #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumSchemes + 1)); + NL; + PrintACR('^11. Description : ^5'+Scheme.Description); + Prompt('^12. System colors : '); + ShowColors; + PrintACR('^13. File listings'); + PrintACR('^14. Message listings'); + PrintACR('^15. File area listings'); + PrintACR('^16. Message area listings'); + PrintACR('^17. Offline mail screen'); + PrintACR('^18. Private mail listing'); + END; + IF (NOT Editing) THEN + CmdStr := '12345678' + ELSE + CmdStr := '12345678[]FJL'; + LOneK('%LFModify menu [^5?^4=^5Help^4]: ',Cmd1,'Q?'+CmdStr++^M,TRUE,TRUE); + CASE Cmd1 OF + '1' : REPEAT + TempScheme1.Description := Description; + Ok := TRUE; + InputWN1('%LFNew description: ',Description,(SizeOf(Description) - 1),[InterActiveEdit],Changed); + CheckScheme(Scheme,1,1,Ok); + IF (NOT Ok) THEN + Description := TempScheme1.Description; + UNTIL (Ok) OR (HangUp); + '2' : SystemColors(Scheme,Cmd1,Changed); + '3' : FileColors(Scheme,Cmd1,Changed); + '4' : MsgColors(Scheme,Cmd1,Changed); + '5' : FileAreaColors(Scheme,Cmd1,Changed); + '6' : MsgAreaColors(Scheme,Cmd1,Changed); + '7' : QWKColors(Scheme,Cmd1,Changed); + '8' : EmailColors(Scheme,Cmd1,Changed); + '[' : IF (RecNumToEdit > 1) THEN + Dec(RecNumToEdit) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + ']' : IF (RecNumToEdit < NumSchemes) THEN + Inc(RecNumToEdit) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNumToEdit <> 1) THEN + RecNumToEdit := 1 + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + InputIntegerWOC('%LFJump to entry?',RecNumToEdit,[NumbersOnly],1,NumSchemes); + IF (RecNumToEdit < 1) OR (RecNumToEdit > NumSchemes) THEN + Cmd1 := #0; + END; + 'L' : IF (RecNumToEdit <> NumSchemes) THEN + RecNumToEdit := NumSchemes + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay current screen'); + Print('^31^1-^38^1:Modify item'); + IF (NOT Editing) THEN + LCmds(20,3,'Quit and save','') + ELSE + BEGIN + LCmds(20,3,'[Back entry',']Forward entry'); + LCmds(20,3,'First entry in list','Jump to entry'); + LCmds(20,3,'Last entry in list','Quit and save'); + END; + END; + END; + UNTIL (Pos(Cmd1,'Q[]FJL') <> 0) OR (HangUp); + END; + + PROCEDURE InsertScheme(TempScheme1: SchemeRec; Cmd1: Char; RecNumToInsertBefore: SmallInt); + VAR + User: UserRecordType; + RecNum, + RecNumToEdit: SmallInt; + Ok, + Changed: Boolean; + BEGIN + IF (NumSchemes = MaxSchemes) THEN + Messages(5,MaxSchemes,'color schemes') + ELSE + BEGIN + RecNumToInsertBefore := -1; + InputIntegerWOC('%LFColor scheme to insert before',RecNumToInsertBefore,[NumbersOnly],1,(NumSchemes + 1)); + IF (RecNumToInsertBefore >= 1) AND (RecNumToInsertBefore <= (NumSchemes + 1)) THEN + BEGIN + Reset(SchemeFile); + InitSchemeVars(TempScheme1); + IF (RecNumToInsertBefore = 1) THEN + RecNumToEdit := 1 + ELSE IF (RecNumToInsertBefore = (NumSchemes + 1)) THEN + RecNumToEdit := (NumSchemes + 1) + ELSE + RecNumToEdit := RecNumToInsertBefore; + REPEAT + OK := TRUE; + EditScheme(TempScheme1,TempScheme1,Cmd1,RecNumToEdit,Changed,FALSE); + CheckScheme(TempScheme1,1,1,Ok); + IF (NOT OK) THEN + IF (NOT PYNQ('%LFContinue inserting color scheme? ',0,TRUE)) THEN + Abort := TRUE; + UNTIL (OK) OR (Abort) OR (HangUp); + IF (NOT Abort) AND (PYNQ('%LFIs this what you want? ',0,FALSE)) THEN + BEGIN + Print('%LF[> Inserting color scheme record ...'); + Seek(SchemeFile,FileSize(SchemeFile)); + Write(SchemeFile,Scheme); + Dec(RecNumToInsertBefore); + FOR RecNum := ((FileSize(SchemeFile) - 1) - 1) DOWNTO RecNumToInsertBefore DO + BEGIN + Seek(SchemeFile,RecNum); + Read(SchemeFile,Scheme); + Seek(SchemeFile,(RecNum + 1)); + Write(SchemeFile,Scheme); + END; + FOR RecNum := RecNumToInsertBefore TO ((RecNumToInsertBefore + 1) - 1) DO + BEGIN + Seek(SchemeFile,RecNum); + Write(SchemeFile,TempScheme1); + Inc(NumSchemes); + SysOpLog('* Inserted color scheme: ^5'+TempScheme1.Description); + END; + END; + Close(SchemeFile); + LastError := IOResult; + Inc(RecNumToInsertBefore); + Print('%LFUpdating user records ...'); + Reset(UserFile); + RecNum := 1; + WHILE (RecNum < FileSize(UserFile)) DO + BEGIN + LoadURec(User,RecNum); + IF (User.ColorScheme >= RecNumToInsertBefore) THEN + BEGIN + Inc(User.ColorScheme); + SaveURec(User,RecNum); + END; + Inc(RecNum); + END; + Close(UserFile); + LastError := IOResult; + END; + END; + END; + + PROCEDURE ModifyScheme(TempScheme1: SchemeRec; Cmd1: Char; RecNumToEdit: SmallInt); + VAR + SaveRecNumToEdit: Integer; + Ok, + Changed: Boolean; + BEGIN + IF (NumSchemes = 0) THEN + Messages(4,0,'color schemes') + ELSE + BEGIN + RecNumToEdit := -1; + InputIntegerWOC('%LFColor scheme to modify',RecNumToEdit,[NumbersOnly],1,NumSchemes); + IF (RecNumToEdit >= 1) AND (RecNumToEdit <= NumSchemes) THEN + BEGIN + SaveRecNumToEdit := -1; + Cmd1 := #0; + Reset(SchemeFile); + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (RecNumToEdit <> SaveRecNumToEdit) THEN + BEGIN + Seek(SchemeFile,(RecNumToEdit - 1)); + Read(SchemeFile,Scheme); + SaveRecNumToEdit := RecNumToEdit; + Changed := FALSE; + END; + REPEAT + Ok := TRUE; + EditScheme(TempScheme1,Scheme,Cmd1,RecNumToEdit,Changed,TRUE); + CheckScheme(Scheme,1,1,Ok); + IF (NOT OK) THEN + BEGIN + PauseScr(FALSE); + IF (RecNumToEdit <> SaveRecNumToEdit) THEN + RecNumToEdit := SaveRecNumToEdit; + END; + UNTIL (Ok) OR (HangUp); + IF (Changed) THEN + BEGIN + Seek(SchemeFile,(SaveRecNumToEdit - 1)); + Write(SchemeFile,Scheme); + SysOpLog('* Modified color scheme: ^5'+Scheme.Description); + END; + END; + Close(SchemeFile); + LastError := IOResult; + END; + END; + END; + + PROCEDURE PositionScheme(TempScheme1: SchemeRec); + VAR + User: UserRecordType; + RecNumToPosition, + RecNumToPositionBefore, + RecNum1, + RecNum2: SmallInt; + BEGIN + IF (NumSchemes = 0) THEN + Messages(4,0,'color schemes') + ELSE IF (NumSchemes = 1) THEN + Messages(6,0,'color schemes') + ELSE + BEGIN + RecNumToPosition := -1; + InputIntegerWOC('%LFPosition which color scheme',RecNumToPosition,[NumbersOnly],1,NumSchemes); + IF (RecNumToPosition >= 1) AND (RecNumToPosition <= NumSchemes) THEN + BEGIN + Print('%LFAccording to the current numbering system.'); + RecNumToPositionBefore := -1; + InputIntegerWOC('%LFPosition before which color scheme',RecNumToPositionBefore,[NumbersOnly],1,(NumSchemes + 1)); + IF (RecNumToPositionBefore >= 1) AND (RecNumToPositionBefore <= (NumSchemes + 1)) AND + (RecNumToPositionBefore <> RecNumToPosition) AND (RecNumToPositionBefore <> (RecNumToPosition + 1)) THEN + BEGIN + Print('%LF[> Positioning color scheme record ...'); + Reset(SchemeFile); + IF (RecNumToPositionBefore > RecNumToPosition) THEN + Dec(RecNumToPositionBefore); + Dec(RecNumToPosition); + Dec(RecNumToPositionBefore); + Seek(SchemeFile,RecNumToPosition); + Read(SchemeFile,TempScheme1); + RecNum1 := RecNumToPosition; + IF (RecNumToPosition > RecNumToPositionBefore) THEN + RecNum2 := -1 + ELSE + RecNum2 := 1; + WHILE (RecNum1 <> RecNumToPositionBefore) DO + BEGIN + IF ((RecNum1 + RecNum2) < FileSize(SchemeFile)) THEN + BEGIN + Seek(SchemeFile,(RecNum1 + RecNum2)); + Read(SchemeFile,Scheme); + Seek(SchemeFile,RecNum1); + Write(SchemeFile,Scheme); + END; + Inc(RecNum1,RecNum2); + END; + Seek(SchemeFile,RecNumToPositionBefore); + Write(SchemeFile,TempScheme1); + Close(SchemeFile); + LastError := IOResult; + Inc(RecNumToPosition); + Inc(RecNumToPositionBefore); + Print('%LFUpdating user records ...'); + Reset(UserFile); + RecNum1 := 1; + WHILE (RecNum1 < FileSize(UserFile)) DO + BEGIN + LoadURec(User,RecNum1); + IF (User.ColorScheme = RecNumToPosition) THEN + BEGIN + User.ColorScheme := RecNumToPositionBefore; + SaveURec(User,RecNum1); + END + ELSE IF (User.ColorScheme = RecNumToPositionBefore) THEN + BEGIN + User.ColorScheme := RecNumToPosition; + SaveURec(User,RecNum1); + END; + Inc(RecNum1); + END; + Close(UserFile); + LastError := IOResult; + END; + END; + END; + END; + + PROCEDURE ListSchemes(VAR RecNumToList1: Integer); + VAR + NumDone: Integer; + BEGIN + IF (RecNumToList1 < 1) OR (RecNumToList1 > NumSchemes) THEN + RecNumToList1 := 1; + Abort := FALSE; + Next := FALSE; + CLS; + PrintACR('^0###^4:^3'+PadLeftStr('Description',30)+'^4:^3Colors'); + PrintACR('^4===:==============================:============================'); + Reset(SchemeFile); + NumDone := 0; + WHILE (NumDone < (PageLength - 5)) AND (RecNumToList1 >= 1) AND (RecNumToList1 <= NumSchemes) + AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(SchemeFile,(RecNumToList1 - 1)); + Read(SchemeFile,Scheme); + WITH Scheme DO + Prompt('^0'+PadRightInt(RecNumToList1,3)+ + ' ^5'+PadLeftStr(Description,30)+ + ' '); + ShowColors; + Inc(RecNumToList1); + Inc(NumDone); + END; + Close(SchemeFile); + LastError := IOResult; + IF (NumSchemes = 0) THEN + Print('*** No color schemes defined ***'); + END; + +BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + RecNumToList := 1; + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + ListSchemes(RecNumToList); + LOneK('%LFColor scheme editor [^5?^4=^5Help^4]: ',Cmd,'QDIMP?'^M,TRUE,TRUE); + CASE Cmd OF + ^M : IF (RecNumToList < 1) OR (RecNumToList > NumSchemes) THEN + RecNumToList := 1; + 'D' : DeleteScheme(TempScheme,RecNumToList); + 'I' : InsertScheme(TempScheme,Cmd,RecNumToList); + 'M' : ModifyScheme(TempScheme,Cmd,RecNumToList); + 'P' : PositionScheme(TempScheme); + '?' : BEGIN + Print('%LF^1<^3CR^1>Next screen or redisplay current screen'); + Print('^1(^3?^1)Help/First color scheme'); + LCmds(20,3,'Delete color scheme','Insert color scheme'); + LCmds(20,3,'Modify color scheme','Position color scheme'); + LCmds(20,3,'Quit',''); + END; + END; + IF (CMD <> ^M) THEN + RecNumToList := 1; + UNTIL (Cmd = 'Q') OR (HangUp); + TempPause := SaveTempPause; + IF (ThisUser.ColorScheme < 1) OR (ThisUser.ColorScheme > FileSize(SchemeFile)) THEN + ThisUser.ColorScheme := 1; + Reset(SchemeFile); + Seek(SchemeFile,(ThisUser.ColorScheme - 1)); + Read(SchemeFile,Scheme); + Close(SchemeFile); + LastError := IOResult; +END; + +END. diff --git a/SOURCE/SYSOP2K.PAS b/SOURCE/SYSOP2K.PAS new file mode 100644 index 0000000..0339b04 --- /dev/null +++ b/SOURCE/SYSOP2K.PAS @@ -0,0 +1,363 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp2K; + +INTERFACE + +PROCEDURE DisplayArcs; +PROCEDURE DisplayCmt; +PROCEDURE ArchiveConfiguration; + +IMPLEMENTATION + +USES + Common; + + +PROCEDURE DisplayArcs; +VAR + RecNumToList: Byte; +BEGIN + Abort := FALSE; + Next := FALSE; + PrintACR('^0 ##^4:^3Ext^4:^3Compression cmdline ^4:^3Decompression cmdline ^4:^3Success Code'); + PrintACR('^4 ==:===:=========================:=========================:============'); + RecNumToList := 1; + WHILE (RecNumToList <= NumArcs) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + WITH General.FileArcInfo[RecNumToList] DO + PrintACR(AOnOff(Active,'^5+','^1-')+ + '^0'+PadRightInt(RecNumToList,2)+ + ' ^3'+PadLeftStr(Ext,3)+ + ' ^5'+PadLeftStr(ArcLine,25)+ + ' '+PadLeftStr(UnArcLine,25)+ + ' '+AOnOff(SuccLevel <> - 1,IntToStr(SuccLevel),'-1 (ignores)')); + Inc(RecNumToList); + END; +END; + +PROCEDURE DisplayCmt; +VAR + RecNumToList: Byte; +BEGIN + FOR RecNumToList := 1 TO 3 DO + PrintACR('^1'+IntToStr(RecNumToList)+'. Archive comment file: ^5'+ + AOnOff(General.FileArcComment[RecNumToList] <> '', + General.FileArcComment[RecNumToList],'*None*')); +END; + +PROCEDURE ArchiveConfiguration; +VAR + TempArchive: FileArcInfoRecordType; + Cmd: Char; + RecNumToList: Byte; + Changed : Boolean; + + FUNCTION DisplayArcStr(S: AStr): AStr; + BEGIN + IF (S <> '') THEN + DisplayArcStr := S + ELSE + DisplayArcStr := '*None*'; + IF (S[1] = '/') THEN + BEGIN + S := '"'+S+'" - '; + CASE s[3] OF + '1' : DisplayArcStr := S + '*Internal* ZIP viewer'; + '2' : DisplayArcStr := S + '*Internal* ARC/PAK viewer'; + '3' : DisplayArcStr := S + '*Internal* ZOO viewer'; + '4' : DisplayArcStr := S + '*Internal* LZH viewer'; + '5' : DisplayArcStr := S + '*Internal* ARJ viewer'; + END; + END; + END; + + PROCEDURE InitArchiveVars(VAR Archive: FileArcInfoRecordType); + BEGIN + FillChar(Archive,SizeOf(Archive),0); + WITH Archive DO + BEGIN + Active := FALSE; + Ext := 'AAA'; + ListLine := ''; + ArcLine := ''; + UnArcLine := ''; + TestLine := ''; + CmtLine := ''; + SuccLevel := -1; + END; + END; + + PROCEDURE DeleteArchive(TempArchive1: FileArcInfoRecordType; RecNumToDelete: Byte); + VAR + RecNum: Byte; + BEGIN + IF (NumArcs = 0) THEN + Messages(4,0,'archive records') + ELSE + BEGIN + RecNumToDelete := 0; + InputByteWOC('%LFArchive to delete?',RecNumToDelete,[NumbersOnly],1,NumArcs); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= NumArcs) THEN + BEGIN + TempArchive1 := General.FileArcInfo[RecNumToDelete]; + Print('%LFArchive: ^5'+TempArchive1.Ext); + IF PYNQ('%LFAre you sure you want to delete it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Deleting archive record ...'); + FOR RecNum := RecNumToDelete TO (NumArcs - 1) DO + General.FileArcInfo[RecNum] := General.FileArcInfo[RecNum + 1]; + General.FileArcInfo[NumArcs].Ext := ''; + Dec(NumArcs); + SysOpLog('* Deleted archive: ^5'+TempArchive1.Ext); + END; + END; + END; + END; + + PROCEDURE CheckArchive(Archive: FileArcInfoRecordType; StartErrMsg,EndErrMsg: Byte; VAR Ok: Boolean); + VAR + Counter: Byte; + BEGIN + FOR Counter := StartErrMsg TO EndErrMsg DO + CASE Counter OF + 1 : IF (Archive.Ext = '') OR (Archive.Ext = 'AAA') THEN + BEGIN + Print('%LF^7The archive extension is invalid!^1'); + OK := FALSE; + END; + END; + END; + + PROCEDURE EditArchive(TempArchive1: FileArcInfoRecordType; VAR Archive: FileArcInfoRecordType; VAR Cmd1: Char; + VAR RecNumToEdit: Byte; VAR Changed1: Boolean; Editing: Boolean); + VAR + CmdStr: AStr; + Ok: Boolean; + BEGIN + WITH Archive DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + CLS; + IF (Editing) THEN + PrintACR('^5Editing archive #'+IntToStr(RecNumToEdit)+ + ' of '+IntToStr(NumArcs)) + ELSE + PrintACR('^5Inserting archive #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumArcs + 1)); + NL; + PrintACR('^11. Active : ^5'+ShowYesNo(Active)); + PrintACR('^12. Extension name : ^5'+Ext); + PrintACR('^13. Interior list method : ^5'+DisplayArcStr(ListLine)); + PrintACR('^14. Compression cmdline : ^5'+DisplayArcStr(ArcLine)); + PrintACR('^15. Decompression cmdline : ^5'+DisplayArcStr(UnArcLine)); + PrintACR('^16. File testing cmdline : ^5'+DisplayArcStr(TestLine)); + PrintACR('^17. Add comment cmdline : ^5'+DisplayArcStr(CmtLine)); + PrintACR('^18. Errorlevel for success : ^5'++AOnOff(SuccLevel <> - 1,IntToStr(SuccLevel),'-1 (ignores)')); + END; + IF (NOT Editing) THEN + CmdStr := '12345678' + ELSE + CmdStr := '12345678[]FJL'; + LOneK('%LFModify menu [^5?^4=^5Help^4]: ',Cmd1,'Q?'+CmdStr+^M,TRUE,TRUE); + CASE Cmd1 OF + '1' : BEGIN + Active := NOT Active; + Changed1 := TRUE; + END; + '2' : REPEAT + TempArchive1.Ext := Ext; + Ok := TRUE; + InputWN1('%LFNew extension: ',Ext,(SizeOf(Ext) - 1),[InterActiveEdit,UpperOnly],Changed1); + CheckArchive(Archive,1,1,Ok); + IF (NOT Ok) THEN + Ext := TempArchive1.Ext; + UNTIL (Ok) OR (HangUp); + '3' : InputWN1('%LFNew interior list method: ',ListLine,(SizeOf(ListLine) - 1),[InterActiveEdit],Changed1); + '4' : InputWN1('%LFNew compression command line: ',ArcLine,(SizeOf(ArcLine) - 1),[InterActiveEdit],Changed1); + '5' : InputWN1('%LFNew decompression command line: ',UnArcLine,(SizeOf(UnArcLine) - 1), + [InterActiveEdit],Changed1); + '6' : InputWN1('%LFNew file testing command line: ',TestLine,(SizeOf(TestLine) - 1), + [InterActiveEdit],Changed1); + '7' : InputWN1('%LFNew add comment command line: ',CmtLine,(SizeOf(CmtLine) - 1),[InterActiveEdit],Changed1); + '8' : InputIntegerWC('%LFNew errorlevel for success',SuccLevel,[DisplayValue,NumbersOnly],-1,255,Changed1); + '[' : IF (RecNumToEdit > 1) THEN + Dec(RecNumToEdit) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + ']' : IF (RecNumToEdit < NumArcs) THEN + Inc(RecNumToEdit) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNumToEdit <> 1) THEN + RecNumToEdit := 1 + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + InputByteWOC('%LFJump to entry?',RecNumToEdit,[NumbersOnly],1,NumArcs); + IF (RecNumToEdit < 1) OR (RecNumToEdit > NumArcs) THEN + Cmd1 := #0; + END; + 'L' : IF (RecNumToEdit <> NumArcs) THEN + RecNumToEdit := NumArcs + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay current screen'); + Print('^31^1-^38^1:Modify item'); + IF (NOT Editing) THEN + LCmds(20,3,'Quit and save','') + ELSE + BEGIN + LCmds(20,3,'[Back entry',']Forward entry'); + LCmds(20,3,'First entry in list','Jump to entry'); + LCmds(20,3,'Last entry in list','Quit and save'); + END; + END; + END; + UNTIL (Pos(Cmd1,'Q[]FJL') <> 0) OR (HangUp); + END; + + PROCEDURE InsertArchive(TempArchive1: FileArcInfoRecordType; Cmd1: Char; RecNumToInsertBefore: Byte); + VAR + RecNum, + RecNumToEdit: Byte; + Ok, + Changed1: Boolean; + BEGIN + IF (NumArcs = MaxArcs) THEN + Messages(5,MaxArcs,'archive records') + ELSE + BEGIN + RecNumToInsertBefore := 0; + InputByteWOC('%LFArchive to insert before?',RecNumToInsertBefore,[NumbersOnly],1,(NumArcs + 1)); + IF (RecNumToInsertBefore >= 1) AND (RecNumToInsertBefore <= (NumArcs + 1)) THEN + BEGIN + InitArchiveVars(TempArchive1); + IF (RecNumToInsertBefore = 1) THEN + RecNumToEdit := 1 + ELSE IF (RecNumToInsertBefore = (NumArcs + 1)) THEN + RecNumToEdit := (NumArcs + 1) + ELSE + RecNumToEdit := RecNumToInsertBefore; + REPEAT + OK := TRUE; + EditArchive(TempArchive1,TempArchive1,Cmd1,RecNumToEdit,Changed1,FALSE); + CheckArchive(TempArchive1,1,2,Ok); + IF (NOT OK) THEN + IF (NOT PYNQ('%LFContinue inserting archive? ',0,TRUE)) THEN + Abort := TRUE; + UNTIL (OK) OR (Abort) OR (HangUp); + IF (NOT Abort) AND (PYNQ('%LFIs this what you want? ',0,FALSE)) THEN + BEGIN + Print('%LF[> Inserting archive record ...'); + IF (RecNumToInsertBefore <> (NumArcs + 1)) THEN + FOR RecNum := (NumArcs + 1) DOWNTO (RecNumToInsertBefore + 1) DO + General.FileArcInfo[RecNum] := General.FileArcInfo[RecNum - 1]; + General.FileArcInfo[RecNumToInsertBefore] := TempArchive1; + Inc(NumArcs); + SysOpLog('* Inserted archive: ^5'+TempArchive1.Ext); + END; + END; + END; + END; + + PROCEDURE ModifyArchive(TempArchive1: FileArcInfoRecordType; Cmd1: Char; RecNumToEdit: Byte); + VAR + Archive: FileArcInfoRecordType; + SaveRecNumToEdit: Byte; + OK, + Changed1: Boolean; + BEGIN + IF (NumArcs = 0) THEN + Messages(4,0,'archive records') + ELSE + BEGIN + RecNumToEdit := 0; + InputByteWOC('%LFArchive to modify?',RecNumToEdit,[NumbersOnly],1,NumArcs); + IF (RecNumToEdit >= 1) AND (RecNumToEdit <= NumArcs) THEN + BEGIN + SaveRecNumToEdit := 0; + Cmd1 := #0; + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNumToEdit <> RecNumToEdit) THEN + BEGIN + Archive := General.FileArcInfo[RecNumToEdit]; + SaveRecNumToEdit := RecNumToEdit; + Changed1 := FALSE; + END; + REPEAT + Ok := TRUE; + EditArchive(TempArchive1,Archive,Cmd1,RecNumToEdit,Changed1,TRUE); + CheckArchive(Archive,1,2,Ok); + IF (NOT OK) THEN + BEGIN + PauseScr(FALSE); + IF (RecNumToEdit <> SaveRecNumToEdit) THEN + RecNumToEdit := SaveRecNumToEdit; + END; + UNTIL (Ok) OR (HangUp); + IF (Changed1) THEN + BEGIN + General.FileArcInfo[SaveRecNumToEdit] := Archive; + Changed1 := FALSE; + SysOpLog('* Modified archive: ^5'+Archive.Ext); + END; + END; + END; + END; + END; + +BEGIN + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + BEGIN + CLS; + DisplayArcs; + NL; + DisplayCmt; + END; + LOneK('%LFArchive editor [^5?^4=^5Help^4]: ',Cmd,'QDIM123?'^M,TRUE,TRUE); + CASE Cmd OF + 'D' : DeleteArchive(TempArchive,RecNumToList); + 'I' : InsertArchive(TempArchive,Cmd,RecNumToList); + 'M' : ModifyArchive(TempArchive,Cmd,RecNumToList); + '1'..'3' : + BEGIN + Changed := FALSE; + InputWNWC('%LFNew comment file #'+IntToStr(Ord(Cmd) - 48)+': ',General.FileArcComment[Ord(Cmd) - 48],40,Changed); + IF (Changed) THEN + SysOpLog('* Modified comment: ^5'+IntToStr(Ord(Cmd) - 48)+'.'); + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Next screen or redisplay current screen'); + Print('^1(^3?^1)Help/First archive'); + Print('^31^1-^33^1:Modify Item'); + LCmds(16,3,'Delete archive','Insert archive'); + LCmds(16,3,'Modify archive','Quit'); + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +END. diff --git a/SOURCE/SYSOP2L.PAS b/SOURCE/SYSOP2L.PAS new file mode 100644 index 0000000..9fae3ba --- /dev/null +++ b/SOURCE/SYSOP2L.PAS @@ -0,0 +1,48 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT SysOp2L; + +INTERFACE + +PROCEDURE CreditConfiguration; + +IMPLEMENTATION + +USES + Common; + +PROCEDURE CreditConfiguration; +VAR + Cmd: Char; +BEGIN + REPEAT + WITH General DO + BEGIN + Abort := FALSE; + Next := FALSE; + CLS; + Print('^5Credit System Configuration:'); + NL; + PrintACR('^1A. Charge/minute : ^5'+IntToStr(CreditMinute)); + PrintACR('^1B. Message post : ^5'+IntToStr(CreditPost)); + PrintACR('^1C. Email sent : ^5'+IntToStr(CreditEmail)); + PrintACR('^1D. Free time at logon : ^5'+IntToStr(CreditFreeTime)); + PrintACR('^1E. Internet mail cost : ^5'+IntToStr(CreditInternetMail)); + Prt('%LFEnter selection [^5A^4-^5E^4,^5Q^4=^5Quit^4]: '); + OneK(Cmd,'QABCDE'^M,TRUE,TRUE); + CASE Cmd OF + 'A' : InputIntegerWOC('%LFCredits charged per minute online',CreditMinute,[NumbersOnly],0,32767); + 'B' : InputIntegerWOC('%LFCredits charged per message post',CreditPost,[NumbersOnly],0,32767); + 'C' : InputIntegerWOC('%LFCredits charged per email sent',CreditEmail,[Numbersonly],0,32767); + 'D' : InputIntegerWOC('%LFMinutes to give users w/o credits at logon',CreditFreeTime,[NumbersOnly],0,32767); + 'E' : InputIntegerWOC('%LFCost for Internet mail messages',CreditInternetMail,[NumbersOnly],0,32767); + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +END. diff --git a/SOURCE/SYSOP2M.PAS b/SOURCE/SYSOP2M.PAS new file mode 100644 index 0000000..8817666 --- /dev/null +++ b/SOURCE/SYSOP2M.PAS @@ -0,0 +1,134 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT SysOp2M; + +INTERFACE + +PROCEDURE NewUserTogglesConfiguration; + +IMPLEMENTATION + +USES + Common; + +PROCEDURE NewUserTogglesConfiguration; +VAR + TempStr: STRING[70]; + Cmd: CHAR; + TempB: BYTE; + Changed: Boolean; + + FUNCTION Toggle(NUToggle,CUSerNum: BYTE): BYTE; + BEGIN + IF (NUToggle = 0) THEN + Toggle := CUserNum + ELSE + Toggle := 0; + END; + +BEGIN + REPEAT + CLS; + Abort := FALSE; + Next := FALSE; + MCIAllowed := FALSE; + WITH General DO + BEGIN + Print('^5New User Question Toggles Configuration:'); + NL; + NewUserToggles[1] := 7; + PrintACR('^1A. Ask what the REAL NAME is : ^5'+ShowYesNo(NewUserToggles[2] <> 0)); + PrintACR('^1B. Ask which COUNTRY from : ^5'+ShowYesNo(NewUserToggles[3] <> 0)); + PrintACR('^1C. Ask what the ADDRESS is : ^5'+ShowYesNo(NewUserToggles[4] <> 0)); + PrintACR('^1D. Ask what the CITY, STATE is : ^5'+ShowYesNo(NewUserToggles[5] <> 0)); + PrintACR('^1E. Ask what the ZIP CODE is : ^5'+ShowYesNo(NewUserToggles[6] <> 0)); + PrintACR('^1F. Ask what the PHONE NUMBER is : ^5'+ShowYesNo(NewUserToggles[7] <> 0)); + PrintACR('^1G. Ask which Gender (Male/Female) : ^5'+ShowYesNo(NewUserToggles[8] <> 0)); + PrintACR('^1H. Ask what the BIRTHDAY is : ^5'+ShowYesNo(NewUserToggles[9] <> 0)); + PrintACR('^1I. Ask SysOp Question #1 : ^5'+ShowYesNo(NewUserToggles[10] <> 0)); + PrintACR('^1J. Ask SysOp Question #2 : ^5'+ShowYesNo(NewUserToggles[11] <> 0)); + PrintACR('^1K. Ask SysOp Question #3 : ^5'+ShowYesNo(NewUserToggles[12] <> 0)); + PrintACR('^1L. Ask EMULATION that is required : ^5'+ShowYesNo(NewUserToggles[13] <> 0)); + PrintACR('^1M. Ask SCREEN SIZE that is required : ^5'+ShowYesNo(NewUserToggles[14] <> 0)); + PrintACR('^1N. Ask if Msg SCREEN CLEARING is needed: ^5'+ShowYesNo(NewUserToggles[15] <> 0)); + PrintACR('^1O. Ask if SCREEN PAUSES are needed : ^5'+ShowYesNo(NewUserToggles[16] <> 0)); + PrintACR('^1P. Ask if HOTKEYS are needed : ^5'+ShowYesNo(NewUserToggles[17] <> 0)); + PrintACR('^1R. Ask if EXPERT MODE is needed : ^5'+ShowYesNo(NewUserToggles[18] <> 0)); + NewUserToggles[19] := 9; + PrintACR('^1S. Ask FORGOT PW question : ^5'+ShowYesNo(NewUserToggles[20] <> 0)); + IF (RGMainStr(6, TRUE) <> '') THEN + {PrintACR('^1 ('+ForgotPWQuestion+')');} PrintACR('^1 ('+ RGMainStr(6,TRUE) + ')'); + END; + MCIAllowed := TRUE; + Prt('%LFEnter selection [^5A^4-^5P^4,^5R^4-^5S^4,^5Q^4=^5Quit^4]: '); + OneK(Cmd,'QABCDEFGHIJKLMNOPRS'^M,TRUE,TRUE); + WITH General DO + CASE Cmd OF + 'A' : NewUserToggles[2] := Toggle(NewUserToggles[2],10); + 'B' : NewUserToggles[3] := Toggle(NewUserToggles[3],23); + 'C' : NewUserToggles[4] := Toggle(NewUserToggles[4],1); + 'D' : NewUserToggles[5] := Toggle(NewUserToggles[5],4); + 'E' : NewUserToggles[6] := Toggle(NewUserToggles[6],14); + 'F' : BEGIN + NewUserToggles[7] := Toggle(NewUserToggles[7],8); + IF (NewUserToggles[7] <> 0) THEN + General.PhonePW := TRUE + ELSE + General.PhonePW := FALSE; + END; + 'G' : NewUserToggles[8] := Toggle(NewUserToggles[8],12); + 'H' : BEGIN + NewUserToggles[9] := Toggle(NewUserToggles[9],2); + (* + IF (NewUserToggles[9] = 0) THEN + General.BirthDateCheck := 0 + ELSE + BEGIN + REPEAT + NL; + Prt('Logins before birthday check (0-255): '); + Ini(TempB); + IF (TempB < 0) OR (TempB > 255) THEN + BEGIN + NL; + Print('Invalid Range!'); + PauseScr(FALSE); + END; + UNTIL (TempB >= 0) AND (TempB <= 255) OR (HangUp); + General.BirthDateCheck := TempB; + END; + *) + END; + 'I' : NewUserToggles[10] := Toggle(NewUserToggles[10],5); + 'J' : NewUserToggles[11] := Toggle(NewUserToggles[11],6); + 'K' : NewUserToggles[12] := Toggle(NewUserToggles[12],13); + 'L' : NewUserToggles[13] := Toggle(NewUserToggles[13],3); + 'M' : NewUserToggles[14] := Toggle(NewUserToggles[14],11); + 'N' : NewUserToggles[15] := Toggle(NewUserToggles[15],29); + 'O' : NewUserToggles[16] := Toggle(NewUserToggles[16],24); + 'P' : NewUserToggles[17] := Toggle(NewUserToggles[17],25); + 'R' : NewUserToggles[18] := Toggle(NewUserToggles[18],28); + 'S' : BEGIN + NewUserToggles[20] := Toggle(NewUserToggles[20],30); + (*)IF (NewUserToggles[20] = 0) THEN + ForgotPWQuestion := '' + ELSE + BEGIN + TempStr := General.ForgotPWQuestion; + REPEAT + InputWN1('%LFEnter question to ask user if they forget thier password:%LF: ',TempStr,70, + [InterActiveEdit],Changed); + UNTIL (TempStr <> '') OR (HangUp); + IF (Changed) THEN + ForgotPWQuestion := TempStr; + END; *) + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +END. diff --git a/SOURCE/SYSOP2O.PAS b/SOURCE/SYSOP2O.PAS new file mode 100644 index 0000000..204250f --- /dev/null +++ b/SOURCE/SYSOP2O.PAS @@ -0,0 +1,98 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT SysOp2O; + +INTERFACE + +USES + Common; + +PROCEDURE GetSecRange(CONST DisplayType: LongInt; VAR Sec: SecurityRangeType); + +IMPLEMENTATION + +PROCEDURE GetSecRange(CONST DisplayType: LongInt; VAR Sec: SecurityRangeType); +VAR + Cmd: Char; + Counter: Byte; + DisplayValue, + FromValue, + ToValue: SmallInt; + NewValue: LongInt; + + PROCEDURE ShowSecRange(Start: Byte); + VAR + TempStr: AStr; + LineNum, + Counter1: Byte; + SecNum: Integer; + BEGIN + Abort := FALSE; + Next := FALSE; + LineNum := 0; + REPEAT + TempStr := ''; + FOR Counter1 := 0 TO 7 DO + BEGIN + SecNum := Start + LineNum + Counter1 * 20; + IF (SecNum <= 255) THEN + BEGIN + TempStr := TempStr + '^1'+PadLeftInt(SecNum,3)+':^5'+PadLeftInt(Sec[SecNum],5); + IF (Counter1 <> 7) THEN + TempStr := TempStr + ' '; + END; + END; + PrintACR(TempStr); + Inc(LineNum); + UNTIL (LineNum > 19) OR (Abort) OR (HangUp); + END; + +BEGIN + Abort := FALSE; + Next := FALSE; + DisplayValue := 0; + REPEAT + CLS; + CASE DisplayType OF + 1 : Print('^5Time limitations:^1'); + 2 : Print('^5Call allowance per day:^1'); + 3 : Print('^5UL/DL # files ratio (# files can DL per UL):^1'); + 4 : Print('^5UL/DL K-bytes ratio (#k can DL per 1k UL):^1'); + 5 : Print('^5Post/Call ratio (posts per 100 calls) to have Z ACS flag set:^1'); + 6 : Print('^5Maximum number of downloads in one day:^1'); + 7 : Print('^5Maximum amount of downloads (in kbytes) in one day:^1'); + END; + NL; + ShowSecRange(DisplayValue); + LOneK('%LFRange settings [^5S^4=^5Set^4,^5T^4=^5Toggle^4,^5Q^4=^5Quit^4]: ',Cmd,'QST'^M,TRUE,TRUE); + CASE Cmd OF + 'S' : BEGIN + FromValue := -1; + InputIntegerWOC('%LFFrom?',FromValue,[NumbersOnly],0,255); + IF (FromValue >= 0) AND (FromValue <= 255) THEN + BEGIN + ToValue := -1; + InputIntegerWOC('%LFTo?',ToValue,[NumbersOnly],0,255); + IF (ToValue >= 0) AND (ToValue <= 255) THEN + BEGIN + NewValue := -1; + InputLongIntWOC('%LFValue to set?',NewValue,[NumbersOnly],0,32767); + IF (NewValue >= 0) AND (NewValue <= 32767) THEN + FOR Counter := FromValue TO ToValue DO + Sec[Counter] := NewValue; + END; + END; + END; + 'T' : IF (DisplayValue = 0) THEN + DisplayValue := 160 + ELSE + DisplayValue := 0; + END; + UNTIL (Cmd = 'Q') OR (HangUp); +END; + +END. diff --git a/SOURCE/SYSOP3.PAS b/SOURCE/SYSOP3.PAS new file mode 100644 index 0000000..0e39cde --- /dev/null +++ b/SOURCE/SYSOP3.PAS @@ -0,0 +1,1416 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp3; + +INTERFACE + +USES + Common; + +PROCEDURE ShowUserInfo(DisplayType: Byte; UNum: Integer; CONST User: UserRecordType); +PROCEDURE UserEditor(UNum: Integer); + +IMPLEMENTATION + +USES + CUser, + Mail0, + Script, + ShortMsg, + SysOp2G, + SysOp7, + TimeFunc, + MiscUser; + +FUNCTION DisplayTerminalStr(StatusFlags: StatusFlagSet; Flags: FlagSet): Str8; +VAR + TempS: Str8; +BEGIN + IF (AutoDetect IN StatusFlags) THEN + TempS := 'Auto' + ELSE IF (RIP IN StatusFlags) THEN + TempS := 'RIP' + ELSE IF (Avatar IN Flags) THEN + TempS := 'Avatar' + ELSE IF (ANSI IN Flags) THEN + TempS := 'Ansi' + ELSE IF (OKVT100) THEN + TempS := 'VT-100' + ELSE + TempS := 'None'; + DisplayTerminalStr := PadLeftStr(TempS,8); +END; + +PROCEDURE ShowUserInfo(DisplayType: Byte; UNum: Integer; CONST User: UserRecordType); +VAR + Counter: Byte; + + PROCEDURE ShowUser(VAR Counter1: Byte); + VAR + S: AStr; + BEGIN + WITH User DO + CASE Counter1 OF + 1 : BEGIN + IF (UNum = 0) THEN + S := '^5New User Configuration:' + ELSE + BEGIN + S := '^5User #'+IntToStr(UNum)+' of '+IntToStr(MaxUsers - 1); + IF NOT (OnNode(UNum) IN [0,ThisNode]) THEN + S := PadLeftStr(S,45)+'^8Note: ^3User is on node '+IntToStr(OnNode(UNum)); + END; + S := S + #13#10; + END; + 2 : S := '^1A. User Name : ^3'+PadLeftStr(Name,29)+'^1 L. Security : ^3'+IntToStr(SL); + 3 : S := '^1B. Real Name : ^3'+PadLeftStr(RealName,29)+'^1 M. D Security: ^3'+IntToStr(DSL); + 4 : S := '^1C. Address : ^3'+PadLeftStr(Street,29)+'^1 N. AR: ^3'+DisplayARFlags(AR,'3','1'); + 5 : S := '^1D. City/State: ^3'+PadLeftStr(CityState,29)+'^1 O. AC: ^3'+DisplayACFlags(Flags,'3','1'); + 6 : S := '^1E. Zip code : ^3'+PadLeftStr(ZipCode,29)+'^1 P. Sex/Age : ^3'+ + Sex+IntToStr(AgeUser(BirthDate))+' ('+ToDate8(PD2Date(BirthDate))+')'; + 7 : S := '^1F. SysOp note: ^3'+PadLeftStr(Note,29)+'^1 R. Phone num : ^3'+Ph; + 8 : S := '^1G. '+PadLeftStr(lRGLngStr(41,TRUE){FString.UserDefEd[1]},10)+': ^3'+PadLeftStr(UsrDefStr[1],29)+ + '^1 T. Last/1st : ^3'+ToDate8(PD2Date(LastOn))+ + ' ('+ToDate8(PD2Date(FirstOn))+')'; + 9 : BEGIN + S := '^1H. '+PadLeftStr(lRGLngStr(42,TRUE){FString.UserDefEd[2]},10)+': ^3'+PadLeftStr(UsrDefStr[2],29)+ + '^1 V. Locked out: '+AOnOff(LockedOut IN SFlags,'^7'+LockedFile+'.ASC','^3Inactive'); + END; + 10 : BEGIN + S := '^1I. '+PadLeftStr(lRGLngStr(43,TRUE){FString.UserDefEd[3]},10)+': ^3'+PadLeftStr(UsrDefStr[3],29)+ + '^1 W. Password : [Not Shown]'; + END; + 11 : BEGIN + IF (Deleted IN SFlags) THEN + S := '^8' + ELSE + S := '^1'; + S := S + '[DEL] '; + IF (TrapActivity IN SFlags) AND ((UNum <> UserNum) OR (UserNum = 1)) THEN + IF (TrapSeparate IN SFlags) THEN + S := S + '^8[TRP SEP] ' + ELSE + S := S + '^8[TRP COM] ' + ELSE + S := S + '^1[TRP OFF] '; + IF (LockedOut IN SFlags) THEN + S := S + '^8' + ELSE + S := S + '^1'; + S := S + '[LOCK] '; + IF (Alert IN Flags) THEN + S := S + '^8' + ELSE + S := S + '^1'; + S := S + '[ALRT] '; + S := '^1J. Status : ^3'+PadLeftStr(S,29)+'^1 X. Caller ID : ^3'+CallerID; + END; + 12 : S := '^1K. QWK setup : ^3'+PadLeftStr(General.FileArcInfo[DefArcType].ext,29)+ + '^1 Y. Start Menu: ^3'+IntToStr(UserStartMenu); + 13 : S := '^1Z. Forgot PW : ^3'+ForgotPWAnswer+#13#10; + 14 : S := '^11. Call records - TC: ^3'+PadLeftInt(LoggedOn,8)+ + ' ^1TT: ^3'+PadLeftInt(TTimeOn,8)+ + ' ^1CT: ^3'+PadLeftInt(OnToday,8)+ + ' ^1TL: ^3'+PadLeftInt(TLToday,8)+ + ' ^1TB: ^3'+IntToStr(TimeBank); + 15 : S := '^12. Mail records - PB: ^3'+PadLeftInt(MsgPost,8)+ + ' ^1PV: ^3'+PadLeftInt(EmailSent,8)+ + ' ^1FB: ^3'+PadLeftInt(FeedBack,8)+ + ' ^1WT: ^3'+IntToStr(Waiting); + 16 : S := '^13. File records - DL: ^3'+PadLeftStr(IntToStr(Downloads)+'-'+FormatNumber(DK)+'k',15)+ + ' ^1UL: ^3'+PadLeftStr(IntToStr(Uploads)+'-'+FormatNumber(UK)+'k',15)+ + ' ^1DT: ^3'+IntToStr(DLToday)+'-'+FormatNumber(DLKToday)+'k'; + 17 : S := ' ^1FP: ^3'+IntToStr(FilePoints); + 18 : S := '^14. Pref records - EM: ^3'+DisplayTerminalStr(SFlags,Flags)+ + ' ^1CS: ^3'+PadLeftStr(ShowYesNo(CLSMsg IN SFlags),8)+ + ' ^1PS: ^3'+PadLeftStr(ShowYesNo(Pause IN Flags),8)+ + ' ^1CL: ^3'+PadLeftStr(ShowYesNo(Color IN Flags),8)+ + ' ^1ED: ^3'+AOnOff((FSEditor IN SFlags),'F/S','Reg'); + 19 : S := '^15. Subs records - CR: ^3'+PadLeftInt(lCredit,8)+ + ' ^1DB: ^3'+PadLeftInt(Debit,8)+ + ' ^1BL: ^3'+PadLeftInt(lCredit - Debit,8)+ + ' ^1ED: ^3'+AOnOff((Expiration > 0),ToDate8(PD2Date(Expiration)),'Never ')+ + ' ^1ET: ^3'+AOnOff(ExpireTo <> ' ',ExpireTo,'None'); + END; + PrintACR(S); + Inc(Counter1); + END; + +BEGIN + Abort := FALSE; + Next := FALSE; + CLS; + Counter := 1; + CASE DisplayType OF + 1 : WHILE (Counter <= 19) AND (NOT Abort) AND (NOT HangUp) DO + ShowUser(Counter); + 2 : WHILE (Counter <= 5) AND (NOT Abort) AND (NOT HangUp) DO + ShowUser(Counter); + END; +END; + +PROCEDURE UserEditor(UNum: Integer); +TYPE + F_StatusFlagsRec = (FS_Deleted,FS_Trapping,FS_ChatBuffer,FS_LockedOut,FS_Alert,FS_SLogging); +CONST + AutoList: Boolean = TRUE; + UserInfoTyp: Byte = 1; + F_State: ARRAY [0..14] OF Boolean = (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); + F_GenText: STRING[40] = ''; + F_ACS: STRING[20] = ''; + F_SL1: Byte = 0; + F_SL2: Byte = 255; + F_DSL1: Byte = 0; + F_DSL2: Byte = 255; + F_AR: ARFlagSet = []; + F_AC: FlagSet = []; + F_Status: SET OF F_StatusFlagsRec = []; + F_LastOn1: LongInt = 0; + F_LastOn2: LongInt = $FFFFFFF; + F_FirstOn1: LongInt = 0; + F_FirstOn2: LongInt = $FFFFFFF; + F_NumCalls1: LongInt = 0; + F_NumCalls2: LongInt = 2147483647; + F_Age1: Byte = 0; + F_Age2: Byte = 255; + F_Gender: Char = 'M'; + F_PostRatio1: LongInt = 0; + F_PostRatio2: LongInt = 2147483647; + F_DLKRatio1: LongInt = 0; + F_DLKRatio2: LongInt = 2147483647; + F_DLRatio1: LongInt = 0; + F_DLRatio2: LongInt = 2147483647; +VAR + User: UserRecordType; + TempStr: AStr; + Cmd: Char; + TempB, + Counter: Byte; + UNum1, + SaveUNum, + TempMaxUsers, + RecNumToList: Integer; + Changed, + Save, + Save1, + Ok: Boolean; + + FUNCTION SearchType(SType: Byte): AStr; + BEGIN + CASE SType OF + 0 : SearchType := 'General text'; + 1 : SearchType := 'Search ACS'; + 2 : SearchType := 'User SL'; + 3 : SearchType := 'User DSL'; + 4 : SearchType := 'User AR Flags'; + 5 : SearchType := 'User AC Flags'; + 6 : SearchType := 'User status'; + 7 : SearchType := 'Date since last on'; + 8 : SearchType := 'Date since first on'; + 9 : SearchType := 'Number of calls'; + 10 : SearchType := 'User age'; + 11 : SearchType := 'User gender'; + 12 : SearchType := '# 1/10''s call/post'; + 13 : SearchType := '#k DL/1k UL'; + 14 : SearchType := '# DLs/1 UL'; + END; + END; + + FUNCTION Find_FS: AStr; + VAR + FSF: F_StatusFlagsRec; + TempStr1: AStr; + BEGIN + TempStr1 := ''; + FOR FSF := FS_Deleted TO FS_SLogging DO + IF (FSF IN F_Status) THEN + CASE FSF OF + FS_Deleted : TempStr1 := TempStr1 +'Deleted,'; + FS_Trapping : TempStr1 := TempStr1 +'Trapping,'; + FS_ChatBuffer: TempStr1 := TempStr1 +'Chat Buffering,'; + FS_LockedOut : TempStr1 := TempStr1 +'Locked Out,'; + FS_Alert : TempStr1 := TempStr1 +'Alert,'; + FS_SLogging : TempStr1 := TempStr1 +'Sep. SysOp Log,'; + END; + IF (TempStr1 <> '') THEN + TempStr1 := Copy(TempStr1,1,(Length(TempStr1) - 1)) + ELSE + TempStr1 := 'None.'; + Find_FS := TempStr1; + END; + + PROCEDURE DisplaySearchOptions; + VAR + TempStr1: AStr; + Cmd1: Char; + Counter1: Byte; + BEGIN + Print('^5Search Criterea:^1'); + NL; + Abort := FALSE; + Next := FALSE; + Counter1 := 0; + WHILE ((Counter1 <= 14) AND (NOT Abort) AND (NOT HangUp)) DO + BEGIN + CASE Counter1 OF + 0..9 : + Cmd1 := Chr(Counter1 + 48); + 10 : Cmd1 := 'A'; + 11 : Cmd1 := 'G'; + 12 : Cmd1 := 'P'; + 13 : Cmd1 := 'K'; + 14 : Cmd1 := 'N'; + END; + Prompt('^1'+Cmd1+'. '+PadLeftStr(SearchType(Counter1),19)+': '); + TempStr1 := ''; + IF (NOT F_State[Counter1]) THEN + TempStr1 := '^5' + ELSE + BEGIN + CASE Counter1 OF + 0 : TempStr1 := '"'+F_GenText+'"'; + 1 : TempStr1 := '"'+F_ACS+'"'; + 2 : TempStr1 := IntToStr(F_SL1)+' SL ... '+IntToStr(F_SL2)+' SL'; + 3 : TempStr1 := IntToStr(F_DSL1)+' DSL ... '+IntToStr(F_DSL2)+' DSL'; + 4 : TempStr1 := DisplayARFlags(F_AR,'3','1'); + 5 : TempStr1 := DisplayACFlags(F_AC,'3','1'); + 6 : TempStr1 := Find_FS; + 7 : TempStr1 := PD2Date(F_LastOn1)+' ... '+PD2Date(F_LastOn2); + 8 : TempStr1 := PD2Date(F_FirstOn1)+' ... '+PD2Date(F_FirstOn2); + 9 : TempStr1 := IntToStr(F_NumCalls1)+' calls ... '+IntToStr(F_NumCalls2)+' calls'; + 10 : TempStr1 := IntToStr(F_Age1)+' years ... '+IntToStr(F_Age2)+' years'; + 11 : TempStr1 := AOnOff(F_Gender = 'M','Male','Female'); + 12 : TempStr1 := IntToStr(F_PostRatio1)+' ... '+IntToStr(F_PostRatio2); + 13 : TempStr1 := IntToStr(F_DLKRatio1)+' ... '+IntToStr(F_DLKRatio2); + 14 : TempStr1 := IntToStr(F_DLRatio1)+' ... '+IntToStr(F_DLRatio2); + END; + UserColor(3); + END; + Print(TempStr1); + WKey; + Inc(Counter1); + END; + END; + + FUNCTION OKUser(UNum1: Integer): Boolean; + VAR + FSF: F_StatusFlagsRec; + User1: UserRecordType; + Counter1: Byte; + TempL: LongInt; + Ok1: Boolean; + + FUNCTION NoFindIt(TempStr1: AStr): Boolean; + BEGIN + NoFindIt := (Pos(AllCaps(F_GenText),AllCaps(TempStr1)) = 0); + END; + + BEGIN + WITH User1 DO + BEGIN + LoadURec(User1,UNum1); + Ok1 := TRUE; + Counter1 := 0; + WHILE ((Counter1 <= 14) AND (Ok1)) DO + BEGIN + IF (F_State[Counter1]) THEN + CASE Counter1 OF + 0 : IF ((NoFindIt(Name)) AND (NoFindIt(RealName)) AND + (NoFindIt(Street)) AND (NoFindIt(CityState)) AND + (NoFindIt(ZipCode)) AND (NoFindIt(UsrDefStr[1])) AND + (NoFindIt(Ph)) AND (NoFindIt(Note)) AND + (NoFindIt(UsrDefStr[2])) AND (NoFindIt(UsrDefStr[3]))) THEN + Ok1 := FALSE; + 1 : IF (NOT AACS1(User1,UNum1,F_ACS)) THEN + Ok1 := FALSE; + 2 : IF ((SL < F_SL1) OR (SL > F_SL2)) THEN + Ok1 := FALSE; + 3 : IF ((DSL < F_DSL1) OR (DSL > F_DSL2)) THEN + Ok1 := FALSE; + 4 : IF (NOT (AR >= F_AR)) THEN + Ok1 := FALSE; + 5 : IF (NOT (Flags >= F_AC)) THEN + Ok1 := FALSE; + 6 : FOR FSF := FS_Deleted TO FS_SLogging DO + IF (FSF IN F_Status) THEN + CASE FSF OF + FS_Deleted : IF NOT (Deleted IN User1.SFlags) THEN + Ok1 := FALSE; + FS_Trapping : IF NOT (TrapActivity IN User1.SFlags) THEN + Ok1 := FALSE; + FS_ChatBuffer : IF NOT (ChatAuto IN User1.SFlags) THEN + Ok1 := FALSE; + FS_LockedOut : IF NOT (LockedOut IN User1.SFlags) THEN + Ok1 := FALSE; + FS_Alert : IF NOT ((Alert IN Flags)) THEN + Ok1 := FALSE; + FS_SLogging : IF NOT (SLogSeparate IN User1.SFlags) THEN + Ok1 := FALSE; + END; + 7 : IF ((LastOn < F_LastOn1) OR (LastOn > F_LastOn2)) THEN + Ok1 := FALSE; + 8 : IF ((FirstOn < F_FirstOn1) OR (FirstOn > F_FirstOn2)) THEN + Ok1 := FALSE; + 9 : IF ((LoggedOn < F_NumCalls1) OR (LoggedOn > F_NumCalls2)) THEN + Ok1 := FALSE; + 10 : IF (((AgeUser(BirthDate) < F_Age1) OR (AgeUser(BirthDate) > F_Age2)) AND (AgeUser(BirthDate) <> 0)) THEN + Ok1 := FALSE; + 11 : IF (Sex <> F_Gender) THEN + Ok1 := FALSE; + 12 : BEGIN + IF (LoggedOn > 0) THEN + TempL := LoggedOn + ELSE + TempL := 1; + TempL := ((MsgPost DIV TempL) * 100); + IF ((TempL < F_PostRatio1) OR (TempL > F_PostRatio2)) THEN + Ok1 := FALSE; + END; + 13 : BEGIN + IF (UK > 0) THEN + TempL := UK + ELSE + TempL := 1; + TempL := (DK DIV TempL); + IF ((TempL < F_DLKRatio1) OR (TempL > F_DLKRatio2)) THEN + Ok1 := FALSE; + END; + 14 : BEGIN + IF (Uploads > 0) THEN + TempL := Uploads + ELSE + TempL := 1; + TempL := (Downloads DIV TempL); + IF ((TempL < F_DLRatio1) OR (TempL > F_DLRatio2)) THEN + Ok1 := FALSE; + END; + END; + Inc(Counter1); + END; + END; + OKUser := Ok1; + END; + + PROCEDURE Search(i: Integer); + VAR + n, + TempMaxUsers: Integer; + BEGIN + Prompt('Searching ... '); + Reset(UserFile); + TempMaxUsers := (MaxUsers - 1); + n := UNum; + REPEAT + Inc(UNum,i); + IF (UNum < 1) THEN + UNum := TempMaxUsers; + IF (UNum > TempMaxUsers) THEN + UNum := 1; + UNTIL ((OKUser(UNum)) OR (UNum = n)); + Close(UserFile); + END; + + PROCEDURE Clear_F; + VAR + Counter1: Byte; + BEGIN + FOR Counter1 := 0 TO 14 DO + F_State[Counter1] := FALSE; + F_GenText := ''; + F_ACS := ''; + F_SL1 := 0; + F_SL2 := 255; + F_DSL1 := 0; + F_DSL2 := 255; + F_AR := []; + F_AC := []; + F_Status := []; + F_LastOn1 := 0; + F_LastOn2 := $FFFFFFF; + F_FirstOn1 := 0; + F_FirstOn2 := $FFFFFFF; + F_NumCalls1 := 0; + F_NumCalls2 := 2147483647; + F_Age1 := 0; + F_Age2 := 255; + F_Gender := 'M'; + F_PostRatio1 := 0; + F_PostRatio2 := 2147483647; + F_DLKRatio1 := 0; + F_DLKRatio2 := 2147483647; + F_DLRatio1 := 0; + F_DLRatio2 := 2147483647; + END; + + PROCEDURE UserSearch; + VAR + User1: UserRecordType; + FSF: F_StatusFlagsRec; + TempStr1: AStr; + Cmd1: Char; + SType, + UNum1, + UserCount: Integer; + Changed1: Boolean; + BEGIN + DisplaySearchOptions; + REPEAT + NL; + Prt('Change [^5?^4=^5Help^4]: '); + OneK(Cmd1,'Q0123456789AGPKNCLTU?'^M,TRUE,TRUE); + NL; + CASE Cmd1 OF + '0'..'9' : + SType := (Ord(Cmd1) - 48); + 'A' : SType := 10; + 'G' : SType := 11; + 'P' : SType := 12; + 'K' : SType := 13; + 'N' : SType := 14; + ELSE + SType := -1; + END; + IF (SType <> -1) THEN + BEGIN + Prompt('^5[>^0 '); + IF (F_State[SType]) THEN + Print(SearchType(SType)+'^1') + ELSE + BEGIN + F_State[SType] := TRUE; + Print(SearchType(SType)+' is now *ON*^1'); + END; + NL; + END; + CASE Cmd1 OF + '0' : BEGIN + Print('General text ["'+F_GenText+'"]'); + Prt(': '); + MPL(40); + Input(TempStr1,40); + IF (TempStr1 <> '') THEN + F_GenText := TempStr1; + END; + '1' : BEGIN + Print('Search ACS ["'+F_ACS+'"]'); + Prt(': '); + MPL(20); + InputL(TempStr1,20); + IF (TempStr1 <> '') THEN + F_ACS := TempStr1; + END; + '2' : BEGIN + InputByteWOC('Lower limit',F_SL1,[DisplayValue,NumbersOnly],0,255); + InputByteWOC('%LFUpper limit',F_SL2,[DisplayValue,NumbersOnly],(0 + F_SL1),255); + END; + '3' : BEGIN + InputByteWOC('Lower limit',F_DSL1,[DisplayValue,NumbersOnly],0,255); + InputByteWOC('%LFUpper limit',F_DSL2,[DisplayValue,NumbersOnly],(0 + F_DSL1),255); + END; + '4' : BEGIN + REPEAT + Prt('Toggle which AR flag? ('+DisplayArFlags(F_AR,'5','4')+'^4) [^5?^4=^5Help^4,^5^4=^5Quit^4]: '); + OneK(Cmd1,^M'ABCDEFGHIJKLMNOPQRSTUVWXYZ?',TRUE,TRUE); + IF (Cmd1 = '?') THEN + PrintF('ARFLAGS') + ELSE IF (Cmd1 <> ^M) THEN + ToggleARFlag(Cmd1,F_AR,Changed); + UNTIL ((Cmd1 = ^M) OR (HangUp)); + Cmd1 := #0; + END; + '5' : BEGIN + REPEAT + Prt('Toggle which AC flag? ['+DisplayACFlags(F_AC,'5','4')+'] [?]Help: '); + OneK(Cmd1,^M'LCVUA*PEKM1234?',TRUE,TRUE); + IF (Cmd1 = '?') THEN + PrintF('ACFLAGS') + ELSE IF (Cmd1 <> ^M) THEN + ToggleACFlags(Cmd1,F_AC,Changed1); + UNTIL (Cmd1 = ^M) OR (HangUp); + Cmd1 := #0; + END; + '6' : BEGIN + REPEAT + Print('^4Current flags: ^3'+Find_FS); + NL; + Prt('Toggle which status flag? (^5?^4=^5Help^4): '); + OneK(Cmd1,'QACDLST? '^M,TRUE,TRUE); + CASE Cmd1 OF + 'A' : FSF := FS_Alert; + 'C' : FSF := FS_ChatBuffer; + 'D' : FSF := FS_Deleted; + 'L' : FSF := FS_LockedOut; + 'S' : FSF := FS_SLogging; + 'T' : FSF := FS_Trapping; + '?' : BEGIN + NL; + LCmds(15,3,'Alert','Chat-buffering'); + LCmds(15,3,'Deleted','Locked-out'); + LCmds(15,3,'Separate SysOp logging','Trapping'); + END; + END; + IF (Cmd1 IN ['A','C','D','L','S','T']) THEN + IF (FSF IN F_Status) THEN + Exclude(F_Status,FSF) + ELSE + Include(F_Status,FSF); + UNTIL ((Cmd1 IN ['Q',' ',^M]) OR (HangUp)); + Cmd1 := #0; + END; + '7' : BEGIN + Prt('Starting date: '); + MPL(10); + InputFormatted('',TempStr1,'##/##/####',TRUE); + F_LastOn1 := Date2PD(TempStr1); + NL; + Prt('Ending date: '); + MPL(10); + InputFormatted('',TempStr1,'##/##/####',TRUE); + F_LastOn2 := Date2PD(TempStr1); + END; + '8' : BEGIN + Prt('Starting date: '); + MPL(10); + InputFormatted('',TempStr1,'##/##/####',TRUE); + F_FirstOn1 := Date2PD(TempStr1); + NL; + Prt('Ending date: '); + MPL(10); + InputFormatted('',TempStr1,'##/##/####',TRUE); + F_FirstOn2 := Date2PD(TempStr1); + END; + '9' : BEGIN + InputLongIntWOC('%LFLower limit',F_NumCalls1,[DisplayValue,NumbersOnly],0,2147483647); + InputLongIntWOC('%LFUpper limit',F_NumCalls2,[DisplayValue,NumbersOnly],(0 + F_NumCalls1),2147483647); + END; + 'A' : BEGIN + InputByteWOC('Lower limit',F_Age1,[DisplayValue,NumbersOnly],0,255); + InputByteWOC('%LFUpper limit',F_Age2,[displayValue,NumbersOnly],(0 + F_Age1),255); + END; + 'G' : BEGIN + Prt('Gender ['+F_Gender+']: '); + OneK(Cmd1,^M'MF',TRUE,TRUE); + IF (Cmd1 IN ['F','M']) THEN + F_Gender := Cmd1; + END; + 'P' : BEGIN + InputLongIntWOC('%LFLower limit',F_PostRatio1,[DisplayValue,NumbersOnly],0,2147483647); + InputLongIntWOC('%LFUpper limit',F_PostRatio2,[DisplayValue,NumbersOnly],(0 + F_PostRatio1),2147483647); + END; + 'K' : BEGIN + InputLongIntWOC('%LFLower limit',F_DLKRatio1,[DisplayValue,NumbersOnly],0,2147483647); + InputLongIntWOC('%LFUpper limit',F_DLKRatio2,[DisplayValue,NumbersOnly],(0 + F_DLKRatio1),2147483647); + END; + 'N' : BEGIN + InputLongIntWOC('%LFLower limit',F_DLRatio1,[DisplayValue,NumbersOnly],0,2147483647); + InputLongIntWOC('%LFUpper limit',F_DLRatio2,[DisplayValue,NumbersOnly],(0 + F_DLRatio1),2147483647); + END; + 'C' : IF PYNQ('Are you sure? ',0,FALSE) THEN + Clear_F; + ^M,'L' : + DisplaySearchOptions; + 'T' : BEGIN + Prt('Which (0-9,A,G,P,K,N)? [Q]=Quit]: '); + OneK(Cmd1,'Q0123456789AGPKN'^M,TRUE,TRUE); + NL; + CASE Cmd1 OF + '0'..'9' : + SType := (Ord(Cmd1) - 48); + 'A' : SType := 10; + 'G' : SType := 11; + 'P' : SType := 12; + 'K' : SType := 13; + 'N' : SType := 14; + ELSE + SType := -1; + END; + IF (SType <> -1) THEN + BEGIN + F_State[SType] := NOT F_State[SType]; + Prompt('^5[>^0 '+SearchType(SType)+' is now *'+AonOff(F_State[SType],'ON','OFF')+'*^1'); + NL; + END; + Cmd1 := #0; + END; + 'U' : BEGIN + Abort := FALSE; + Next := FALSE; + Reset(UserFile); + UserCount := 0; + TempMaxUsers := (MaxUsers - 1); + UNum1 := 1; + WHILE (UNum1 <= TempMaxUsers) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (OKUser(UNum1)) THEN + BEGIN + LoadURec(User1,UNum1); + PrintACR('^3'+Caps(User1.Name)+' #'+IntToStr(UNum1)); + Inc(UserCount); + END; + Inc(UNum1); + END; + Close(UserFile); + IF (NOT Abort) THEN + BEGIN + NL; + Print('^7 ** ^5'+IntToStr(UserCount)+' Users.^1'); + END; + END; + '?' : BEGIN + Print('^30-9,AGPKN^1: Change option'); + LCmds(14,3,'List options','Toggle options on/off'); + LCmds(14,3,'Clear options','User''s who match'); + LCmds(14,3,'Quit',''); + END; + END; + UNTIL (Cmd1 = 'Q') OR (HangUp); + END; + + PROCEDURE KillUserMail; + VAR + User1: UserRecordType; + MHeader: MHeaderRec; + SaveReadMsgArea: Integer; + MsgNum: Word; + BEGIN + SaveReadMsgArea := ReadMsgArea; + InitMsgArea(-1); + Reset(MsgHdrF); + FOR MsgNum := 1 TO HiMsg DO + BEGIN + LoadHeader(MsgNum,MHeader); + IF (NOT (MDeleted IN MHeader.Status)) AND ((MHeader.MTO.UserNum = UNum) OR (MHeader.From.UserNum = UNum)) THEN + BEGIN + Include(MHeader.Status,MDeleted); + SaveHeader(MsgNum,MHeader); + LoadURec(User1,MHeader.MTO.UserNum); + IF (User1.Waiting > 0) THEN + Dec(User1.Waiting); + SaveURec(User1,MHeader.MTO.UserNum); + Reset(MsgHdrF); + END; + END; + Close(MsgHdrF); + InitMsgArea(SaveReadMsgArea); + END; + + PROCEDURE KillUserVotes; + VAR + Counter1: Byte; + BEGIN + Assign(VotingFile,General.DataPath+'VOTING.DAT'); + Reset(VotingFile); + IF (IOResult = 0) THEN + BEGIN + FOR Counter1 := 1 TO FileSize(VotingFile) DO + IF (User.Vote[Counter1] > 0) THEN + BEGIN + Seek(VotingFile,(Counter1 - 1)); + Read(VotingFile,Topic); + Dec(Topic.Answers[User.Vote[Counter1]].NumVotedAnswer); + Dec(Topic.NumVotedQuestion); + Seek(VotingFile,(Counter1 - 1)); + Write(VotingFile,Topic); + User.Vote[Counter1] := 0; + END; + Close(VotingFile); + END; + LastError := IOResult; + END; + + PROCEDURE ChangeRecords(On: Byte); + VAR + OneKCmds: AStr; + Cmd1: Char; + TempL1: LongInt; + BEGIN + WITH User DO + REPEAT + NL; + CASE on OF + 1 : BEGIN + Print('^5Call records:^1'); + NL; + Print('^11. Total calls : ^5'+IntToStr(LoggedOn)); + Print('^12. Total time on : ^5'+IntToStr(TTimeOn)); + Print('^13. Calls today : ^5'+IntToStr(OnToday)); + Print('^14. Time left today: ^5'+IntToStr(TLToday)); + Print('^15. Ill. logons : ^5'+IntToStr(Illegal)); + Print('^16. Time Bank : ^5'+IntToStr(TimeBank)); + NL; + Prt('Select: (1-6) [M]ail [F]ile [P]ref [S]ubs: '); + OneK(Cmd1,^M'123456MFPS',TRUE,TRUE); + END; + 2 : BEGIN + Print('^5Mail records:^1'); + NL; + Print('^11. Pub. posts : ^5'+IntToStr(MsgPost)); + Print('^12. Priv. posts : ^5'+IntToStr(EmailSent)); + Print('^13. Fback sent : ^5'+IntToStr(FeedBack)); + Print('^14. Mail Waiting: ^5'+IntToStr(Waiting)); + NL; + Prt('Select: (1-4) [C]all [F]ile [P]ref [S]ubs: '); + OneK(Cmd1,^M'1234CFPS',TRUE,TRUE); + END; + 3 : BEGIN + Print('^5File records:^1'); + NL; + Print('^11. # of DLs : ^5'+IntToStr(Downloads)); + Print('^12. DL K : ^5'+FormatNumber(DK)+'k'); + Print('^13. # of ULs : ^5'+IntToStr(Uploads)); + Print('^14. UL K : ^5'+FormatNumber(UK)+'k'); + Print('^15. # DLs today: ^5'+IntToStr(DLToday)); + Print('^16. DL K today : ^5'+FormatNumber(DLKToday)+'k'); + Print('^17. File Points: ^5'+FormatNumBer(FilePoints)); + NL; + Prt('Select: (1-7) [C]all [M]ail [P]ref [S]ubs: '); + OneK(Cmd1,^M'1234567CMPS',TRUE,TRUE); + END; + 4 : BEGIN + Print('^5Preference records:^1'); + NL; + Print('^11. Emulation: ^5'+DisplayTerminalStr(SFlags,Flags)); + Print('^12. Clr Scrn : ^5'+AOnOff((CLSMsg IN SFlags),'On','Off')); + Print('^13. Pause : ^5'+AOnOff((Pause IN Flags),'On','Off')); + Print('^14. Color : ^5'+AOnOff((Color IN Flags),'On','Off')); + Print('^15. Editor : ^5'+AOnOff((FSEditor IN SFlags),'F/S','Reg')); + NL; + Prt('Select (1-5) [C]all [M]ail [F]ile [S]ubs: '); + OneK(Cmd1,^M'12345CMFS',TRUE,TRUE); + END; + 5 : BEGIN + Print('^5Subscription records:^1'); + NL; + Print('^11. Credit : ^5'+IntToStr(lCredit)); + Print('^12. Debit : ^5'+IntToStr(Debit)); + Print('^13. Expires : ^5'+AOnOff(Expiration = 0,'Never',ToDate8(PD2Date(Expiration)))); + Print('^1 Expire to: ^5'+AOnOff(ExpireTo = ' ','None',ExpireTo)); + NL; + Prt('Select: (1-3) [C]all [M]ail [P]ref [F]ile: '); + OneK(Cmd1,^M'123CMPF',TRUE,TRUE); + END; + END; + CASE Cmd1 OF + 'C' : on := 1; + 'M' : on := 2; + 'F' : on := 3; + 'P' : on := 4; + 'S' : on := 5; + '1'..'7' : + BEGIN + NL; + IF (on <> 4) THEN + BEGIN + IF (on <> 5) OR NOT (StrToInt(Cmd1) IN [3..4]) THEN + BEGIN + Prt('New value: '); + Input(TempStr,10); + TempL1 := StrToInt(TempStr); + END + ELSE + CASE StrToInt(Cmd1) OF + 3 : IF (PYNQ('Reset expiration date & level? ',0,FALSE)) THEN + BEGIN + TempL1 := 0; + TempStr := ' '; + END + ELSE + BEGIN + NL; + Prt('New expiration date: '); + MPL(10); + InputFormatted('',TempStr,'##/##/####',TRUE); + IF (TempStr <> '') THEN + TempL1 := Date2PD(TempStr) + ELSE + TempL1 := 0; + OneKCmds := ''; + FOR Cmd1 := '!' TO '~' DO + IF (Cmd1 IN ValKeys) THEN + OneKCmds := OneKCmds + Cmd1; + NL; + Prt('Level to expire to (!-~) [Space=No Change]: '); + OneK1(Cmd1,^M' '+OneKCmds,TRUE,TRUE); + TempStr := Cmd1; + IF (TempL1 = 0) OR (TempStr = ' ') THEN + BEGIN + TempL1 := 0; + TempStr := ' '; + END; + Cmd1 := '3'; + END; + END; + IF (TempStr <> '') THEN + CASE on OF + 1 : CASE StrToInt(Cmd1) OF + 1 : LoggedOn := TempL1; + 2 : TTimeOn := TempL1; + 3 : OnToday := TempL1; + 4 : TLToday := TempL1; + 5 : Illegal := TempL1; + 6 : TimeBank := TempL1; + END; + 2 : CASE StrToInt(Cmd1) OF + 1 : MsgPost := TempL1; + 2 : EmailSent := TempL1; + 3 : FeedBack := TempL1; + 4 : Waiting := TempL1; + END; + 3 : CASE StrToInt(Cmd1) OF + 1 : Downloads := TempL1; + 2 : DK := TempL1; + 3 : Uploads := TempL1; + 4 : UK := TempL1; + 5 : DLToday := TempL1; + 6 : DLKToday := TempL1; + 7 : FilePoints := TempL1; + END; + 5 : CASE StrToInt(Cmd1) OF + 1 : lCredit := TempL1; + 2 : Debit := TempL1; + 3 : BEGIN + Expiration := TempL1; + IF (TempStr[1] IN [' ','!'..'~']) THEN + ExpireTo := TempStr[1]; + END; + END; + END; + END + ELSE + CASE StrToInt(Cmd1) OF + 1 : CStuff(3,3,User); + 2 : ToggleStatusFlag(CLSMsg,SFlags); + 3 : ToggleACFlag(Pause,Flags); + 4 : ToggleACFlag(Color,Flags); + 5 : ToggleStatusFlag(FSEditor,SFlags); + END; + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + END; + +BEGIN + IF ((UNum < 1) OR (UNum > (MaxUsers - 1))) THEN + Exit; + IF (UNum = UserNum) THEN + BEGIN + User := ThisUser; + SaveURec(User,UNum); + END; + LoadURec(User,UNum); + Clear_F; + SaveUNum := 0; + Save := FALSE; + REPEAT + Abort := FALSE; + IF (AutoList) OR (UNum <> SaveUNum) OR (Cmd = ^M) THEN + BEGIN + ShowUserInfo(UserInfoTyp,UNum,User); + SaveUNum := UNum; + END; + NL; + Prt('User editor [^5?^4=^5Help^4]: '); + OneK(Cmd,'Q?[]=${}*ABCDEFGHIJKLMNOPRSTUVWXYZ12345-+_;:\/^'^M,TRUE,TRUE); + IF (Cmd IN ['A','F','L'..'O','S'..'X','Z','/','{','}','-',';','^','?','<','\','=','_']) THEN + NL; + CASE Cmd OF + '?' : BEGIN + Abort := FALSE; + PrintACR('^5Editor Help'); + NL; + LCmds3(21,3,';New list mode',':AutoList toggle','\Show sysop log'); + LCmds3(21,3,'[Back one user',']Forward one user','=Reload old data'); + LCmds3(21,3,'{Search backward','}Search forward','*Validate user'); + LCmds3(21,3,'+Mailbox','UGoto user name/#','Search options'); + LCmds3(21,3,'-New user answers','_Other Q. answers','^Delete user'); + LCmds3(21,3,'/New user config','$Clear fields',''); + NL; + PauseScr(FALSE); + Save := FALSE; + END; + '[',']','/','{','}','U','Q' : + BEGIN + IF (Save) THEN + BEGIN + SaveURec(User,UNum); + IF (UNum = UserNum) THEN + ThisUser := User; + Save := FALSE; + END; + CASE Cmd OF + '[' : BEGIN + Dec(UNum); + IF (UNum < 1) THEN + UNum := (MaxUsers - 1); + END; + ']' : BEGIN + Inc(UNum); + IF (UNum > (MaxUsers - 1)) THEN + UNum := 1; + END; + '/' : UNum := 0; + '{' : Search(-1); + '}' : Search(1); + 'U' : BEGIN + Print('Enter User Name, #, or partial search string.'); + Prt(': '); + lFindUserWS(UNum1); + IF (UNum1 > 0) THEN + BEGIN + LoadURec(User,UNum1); + UNum := UNum1; + END; + END; + END; + LoadURec(User,UNum); + IF (UNum = UserNum) THEN + ThisUser := User; + END; + '=' : IF PYNQ('Reload old user data? ',0,FALSE) THEN + BEGIN + LoadURec(User,UNum); + IF (UNum = UserNum) THEN + ThisUser := User; + Save := FALSE; + Print('^7Old data reloaded.^1'); + END; + 'S','-','_',';',':','\' : + BEGIN + CASE Cmd OF + 'S' : UserSearch; + '-' : BEGIN + ReadAsw(UNum,General.MiscPath+'NEWUSER'); + PauseScr(FALSE); + END; + '_' : BEGIN + Prt('Print questionairre file: '); + MPL(8); + Input(TempStr,8); + NL; + ReadAsw(UNum,General.MiscPath+TempStr); + PauseScr(FALSE); + END; + ';' : BEGIN + Prt('(L)ong or (S)hort list mode: '); + OneK(Cmd,'QSL '^M,TRUE,TRUE); + CASE Cmd OF + 'S' : UserInfoTyp := 2; + 'L' : UserInfoTyp := 1; + END; + Cmd := #0; + END; + ':' : AutoList := NOT AutoList; + '\' : BEGIN + TempStr := General.LogsPath+'SLOG'+IntToStr(UNum)+'.LOG'; + PrintF(TempStr); + IF (NoFile) THEN + Print('"'+TempStr+'": File not found.'); + PauseScr(FALSE); + END; + END; + END; + '$','*','+','A','B','C','D','E','F','G','H','I','J','K','L','M', + 'N','O','P','R','T','V','W','X','Y','Z','1','2','3','4','5','^' : + BEGIN + IF (((ThisUser.SL <= User.SL) OR (ThisUser.DSL <= User.DSL)) AND + (UserNum <> 1) AND (UserNum <> UNum)) THEN + BEGIN + SysOpLog('Tried to modify '+Caps(User.Name)+' #'+IntToStr(UNum)); + Print('Access denied.'); + NL; + PauseScr(FALSE); + END + ELSE + BEGIN + Save1 := Save; + Save := TRUE; + CASE Cmd OF + '$' : BEGIN + REPEAT + NL; + Prt('Clear fields (^5A^4-^5J^4,^5Q^4=^5Quit^4,^5?^4=^5Help^4): '); + OneK(Cmd,'QABCDEFGHIJ?',TRUE,TRUE); + IF (Cmd = '?') THEN + NL; + CASE Cmd OF + 'A' : User.RealName := User_String_Ask; + 'B' : User.Street := User_String_Ask; + 'C' : User.CityState := User_String_Ask; + 'D' : User.ZipCode := User_String_Ask; + 'E' : User.Birthdate := User_Date_Ask; + 'F' : User.Ph := User_Phone_Ask; + 'G' : User.UsrDefStr[1] := User_String_Ask; + 'H' : User.UsrDefStr[2] := User_String_Ask; + 'I' : User.UsrDefStr[3] := User_String_Ask; + 'J' : User.ForgotPWAnswer := User_String_Ask; + '?' : BEGIN + LCmds(20,3,'AReal Name','BStreet'); + LCmds(20,3,'CCity/State','DZip Code'); + LCmds(20,3,'EBirth Date','FPhone'); + LCmds(20,3,'GString 1','HString 2'); + LCmds(20,3,'IString 3','JPW Answer'); + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); + Cmd := #0; + END; + '*' : AutoVal(User,UNum); + '+' : CStuff(15,3,User); + '1'..'5' : + ChangeRecords(Ord(Cmd) - 48); + 'A' : BEGIN + IF (Deleted IN User.SFlags) THEN + Print('Can''t rename deleted users.') + ELSE + BEGIN + Print('Enter new name.'); + Prt(': '); + MPL((SizeOf(ThisUser.Name) - 1)); + Input(TempStr,(SizeOf(ThisUser.Name) - 1)); + UNum1 := SearchUser(TempStr,TRUE); + IF ((UNum1 = 0) OR (UNum1 = UNum)) AND (TempStr <> '') THEN + BEGIN + InsertIndex(User.Name,UNum,FALSE,TRUE); + User.Name := TempStr; + InsertIndex(User.Name,UNum,FALSE,FALSE); + Save := TRUE; + IF (UNum = UserNum) THEN + ThisUser.Name := TempStr; + END + ELSE + Print('Illegal Name.'); + END; + END; + 'B' : BEGIN + TempStr := User.RealName; + CStuff(10,3,User); + IF (User.RealName <> TempStr) THEN + BEGIN + InsertIndex(TempStr,UNum,TRUE,TRUE); + InsertIndex(User.RealName,UNum,TRUE,FALSE); + END; + END; + 'C' : CStuff(1,3,User); + 'D' : CStuff(4,3,User); + 'E' : CStuff(14,3,User); + 'F' : InputWN1('^1New SysOp note:%LF^4: ',User.Note,(SizeOf(User.Note) - 1),[ColorsAllowed],Next); + 'G' : CStuff(5,3,User); + 'H' : CStuff(6,3,User); + 'I' : CStuff(13,3,User); + 'J' : BEGIN + REPEAT + NL; + Print('^11. Trapping status: '+AOnOff((TrapActivity IN User.SFlags), + '^7'+AOnOff((TrapSeparate IN User.SFlags), + 'Trapping to TRAP'+IntToStr(UNum)+'.LOG', + 'Trapping to TRAP.LOG'), + 'Off')+AOnOff(General.globaltrap,'^8 ','')); + Print('^12. Auto-chat state: '+AOnOff((ChatAuto IN User.SFlags), + AOnOff((ChatSeparate IN User.SFlags), + '^7Output to CHAT'+IntToStr(UNum)+'.LOG', + '^7Output to CHAT.LOG'),'Off')+ + AOnOff(General.autochatopen,'^8 ','')); + Print('^13. SysOp Log state: '+AOnOff((SLogSeparate IN User.SFlags), + '^7Logging to SLOG'+IntToStr(UNum)+'.LOG', + '^3Normal output')); + Print('^14. Alert : '+AOnOff((Alert IN User.Flags), + '^7Alert', + '^3Normal')); + NL; + Prt('Select (1-4): '); + OneK(Cmd,^M'1234',TRUE,TRUE); + IF (Cmd <> ^M) THEN + NL; + CASE Cmd OF + '1' : BEGIN + IF PYNQ('Trap User activity? ['+ShowYesNo((TrapActivity IN User.SFlags))+']: ', + 0,TrapActivity IN User.SFlags) THEN + Include(User.SFlags,TrapActivity) + ELSE + Exclude(User.SFlags,TrapActivity); + IF (TrapActivity IN User.SFlags) THEN + BEGIN + IF PYNQ('Log to separate file? ['+ShowYesNo(TrapSeparate IN User.SFlags)+']: ', + 0,TrapSeparate IN User.SFlags) THEN + Include(User.SFlags,TrapSeparate) + ELSE + Exclude(User.SFlags,TrapSeparate); + END + ELSE + Exclude(User.SFlags,TrapSeparate); + END; + '2' : BEGIN + IF PYNQ('Auto-chat buffer open? ['+ShowYesNo(ChatAuto IN User.SFlags)+']: ', + 0,ChatAuto IN User.SFlags) THEN + Include(User.SFlags,ChatAuto) + ELSE + Exclude(User.SFlags,ChatAuto); + IF (ChatAuto IN User.SFlags) THEN + BEGIN + IF PYNQ('Separate buffer file? ['+ShowYesNo(ChatSeparate IN User.SFlags)+']: ', + 0,ChatSeparate IN User.SFlags) THEN + Include(User.SFlags,ChatSeparate) + ELSE + Exclude(User.SFlags,ChatSeparate); + END + ELSE + Exclude(User.SFlags,ChatSeparate); + END; + '3' : BEGIN + IF PYNQ('Output SysOp Log separately? ['+ShowYesNo(SLogSeparate IN User.SFlags)+']: ', + 0,SLogSeparate IN User.SFlags) THEN + Include(User.SFlags,SLogSeparate) + ELSE + Exclude(User.SFlags,SLogSeparate); + END; + '4' : ToggleACFlag(Alert,User.Flags); + END; + UNTIL (Cmd = ^M) OR (HangUp); + Cmd := #0; + END; + 'K' : CStuff(27,3,User); + 'L' : BEGIN + TempB := User.SL; + InputByteWOC('Enter new SL',TempB,[NumbersOnly],0,255); + IF (TempB >= 0) AND (TempB <= 255) THEN + BEGIN + Ok := TRUE; + IF (TempB < ThisUser.SL) OR (UserNum = 1) THEN + BEGIN + IF (UserNum = UNum) AND (TempB < ThisUser.SL) THEN + BEGIN + NL; + IF NOT PYNQ('Lower your own SL level? ',0,FALSE) THEN + Ok := FALSE; + END; + IF (Ok) THEN + BEGIN + User.SL := TempB; + User.TLToday := (General.TimeAllow[User.SL] - User.TTimeOn); + END; + END + ELSE + BEGIN + NL; + Print('Access denied.'^G); + SysOpLog('Illegal SL edit attempt: '+Caps(User.Name)+' #'+IntToStr(UNum)+' to '+IntToStr(TempB)); + END; + END; + END; + 'M' : BEGIN + TempB := User.DSL; + InputByteWOC('Enter new DSL',TempB,[NumbersOnly],0,255); + IF (TempB >= 0) AND (TempB <= 255) THEN + BEGIN + Ok := TRUE; + IF (TempB < ThisUser.DSL) OR (UserNum = 1) THEN + BEGIN + IF (UserNum = UNum) AND (TempB < ThisUser.SL) THEN + BEGIN + NL; + IF NOT PYNQ('Lower your own DSL level? ',0,FALSE) THEN + Ok := FALSE; + END; + IF (Ok) THEN + User.DSL := TempB; + END + ELSE + BEGIN + NL; + Print('Access denied.'^G); + SysOpLog('Illegal DSL edit attempt: '+Caps(User.Name)+' #'+IntToStr(UNum)+ + ' to '+IntToStr(TempB)); + END; + END; + END; + 'N' : BEGIN + REPEAT + Prt('Toggle which AR flag? ('+DisplayARFlags(User.AR,'5','4')+'^4)'+ + ' [^5*^4=^5All^4,^5?^4=^5Help^4,^5^4=^5Quit^4]: '); + OneK(Cmd,^M'ABCDEFGHIJKLMNOPQRSTUVWXYZ*?',TRUE,TRUE); + IF (Cmd = '?') THEN + PrintF('ARFLAGS') + ELSE IF (Cmd <> ^M) THEN + BEGIN + IF (NOT (Cmd IN ThisUser.AR)) AND (NOT SysOp) THEN + BEGIN + Print('Access denied.'^G); + SysOpLog('Tried to give '+Caps(User.Name)+' #'+IntToStr(UNum)+' AR flag "'+Cmd+'"'); + END + ELSE IF (Cmd IN ['A'..'Z']) THEN + ToggleARFlag(Cmd,User.AR,Changed) + ELSE IF (Cmd = '*') THEN + BEGIN + FOR Cmd := 'A' TO 'Z' DO + ToggleARFlag(Cmd,User.AR,Changed); + Cmd := '*'; + END; + END; + UNTIL (Cmd = ^M) OR (HangUp); + Cmd := #0; + END; + 'O' : BEGIN + REPEAT + Prt('Toggle which AC flag? ('+DisplayACFlags(User.Flags,'5','4')+'^4)'+ + ' [^5?^4=^5Help^4,^5^4=^5Quit^4]: '); + OneK(Cmd,^M'LCVUA*PEKM1234?',TRUE,TRUE); + IF (Cmd = '?') THEN + PrintF('ACFLAGS') + ELSE + BEGIN + IF (Cmd = '4') AND (NOT SysOp) THEN + BEGIN + Print('Access denied.'^G); + SysOpLog('Tried to change '+Caps(User.Name)+' #'+IntToStr(UNum)+' deletion status'); + END + ELSE IF (Cmd <> ^M) THEN + ToggleACFlags(Cmd,User.Flags,Changed); + END; + UNTIL (Cmd = ^M) OR (HangUp); + Cmd := #0; + END; + 'P' : BEGIN + CStuff(2,3,User); + CStuff(12,3,User); + END; + 'R' : CStuff(8,3,User); + 'T' : BEGIN + Print('New last on date (MM/DD/YYYY).'); + Prt(': '); + MPL(10); + InputFormatted('',TempStr,'##/##/####',TRUE); + IF (TempStr <> '') THEN + User.LastOn := Date2PD(TempStr); + END; + 'V' : BEGIN + IF (LockedOut IN User.SFlags) THEN + Exclude(User.SFlags,LockedOut) + ELSE + Include(User.SFlags,LockedOut); + IF (LockedOut IN User.SFlags) THEN + BEGIN + Print('User is now locked out.'); + NL; + Print('Each time the user logs on from now on, a text file will'); + Print('be displayed before user is terminated.'); + NL; + Prt('Enter lockout filename: '); + MPL(8); + Input(TempStr,8); + IF (TempStr = '') THEN + Exclude(User.SFlags,LockedOut) + ELSE + BEGIN + User.LockedFile := TempStr; + SysOpLog('Locked '+Caps(User.Name)+' #'+IntToStr(UNum)+' out: Lockfile "'+TempStr+'"'); + END; + END; + IF NOT (LockedOut IN User.SFlags) THEN + BEGIN + NL; + Print('User is no longer locked out of system.'); + END; + NL; + PauseScr(FALSE); + END; + 'W' : BEGIN + Print('Enter new password.'); + Prt(': '); + MPL(20); + Input(TempStr,20); + IF (TempStr <> '') THEN + User.PW := CRC32(TempStr); + END; + 'X' : BEGIN + Print('Enter new caller ID string.'); + Prt(': '); + MPL((SizeOf(User.CallerID) - 1)); + Input(TempStr,(SizeOf(User.CallerID) - 1)); + IF (TempStr <> '') THEN + User.CallerID := TempStr; + END; + 'Y' : FindMenu('%LFEnter new start menu (^50^4=^5Default^4)',User.UserStartMenu,0,NumMenus,Changed); + 'Z' : BEGIN + Print('Question:'); + NL; + {Print(General.ForgotPWQuestion);} + Print(RGMainStr(6,TRUE)); + NL; + Print('Enter new forgot password answer.'); + Prt(': '); + MPL((SizeOf(User.ForgotPWAnswer) - 1)); + Input(TempStr,(SizeOf(User.ForgotPWAnswer) - 1)); + IF (TempStr <> '') THEN + User.ForgotPWAnswer := TempStr; + END; + '^' : IF (Deleted IN User.SFlags) THEN + BEGIN + Print('User is currently deleted.'); + NL; + IF PYNQ('Restore this user? ',0,FALSE) THEN + BEGIN + InsertIndex(User.Name,UNum,FALSE,FALSE); + InsertIndex(User.RealName,UNum,TRUE,FALSE); + Inc(LTodayNumUsers); + SaveGeneral(TRUE); + Exclude(User.SFlags,Deleted); + END + ELSE + Save := Save1; + END + ELSE IF (FNoDeletion IN User.Flags) THEN + BEGIN + Print('Access denied - This user is protected from deletion.'); + SysOpLog('* Attempt to delete user: '+Caps(User.Name)+' #'+IntToStr(UNum)); + NL; + PauseScr(FALSE); + Save := Save1; + END + ELSE + BEGIN + NL; + IF PYNQ('*DELETE* this User? ',0,FALSE) THEN + BEGIN + IF NOT (Deleted IN User.SFlags) THEN + BEGIN + Save := TRUE; + Include(User.SFlags,Deleted); + InsertIndex(User.Name,UNum,FALSE,TRUE); + InsertIndex(User.RealName,UNum,TRUE,TRUE); + Dec(LTodayNumUsers); + SaveGeneral(TRUE); + SysOpLog('* Deleted User: '+Caps(User.Name)+' #'+IntToStr(UNum)); + UNum1 := UserNum; + UserNum := UNum; + ReadShortMessage; + UserNum := UNum1; + User.Waiting := 0; + KillUserMail; + KillUserVotes; + END + ELSE + Save := Save1; + END; + END; + ELSE + Save := Save1; + END; + END; + END; + END; + IF (UNum = UserNum) THEN + BEGIN + ThisUser := User; + NewComptables; + END; + UNTIL (Cmd = 'Q') OR (HangUp); + Update_Screen; + LastError := IOResult; +END; + +END. diff --git a/SOURCE/SYSOP4.PAS b/SOURCE/SYSOP4.PAS new file mode 100644 index 0000000..80cfc35 --- /dev/null +++ b/SOURCE/SYSOP4.PAS @@ -0,0 +1,563 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S-,V-} + +UNIT SysOp4; + +INTERFACE + +USES + Common; + +PROCEDURE TEdit1; +PROCEDURE TEdit(CONST FSpec: AStr); + +IMPLEMENTATION + +USES + Dos; + +PROCEDURE TEdit1; +VAR + FSpec: AStr; + Dir: DirStr; + Name: NameStr; + Ext: ExtStr; +BEGIN + NL; + Prt('File name: '); + IF (FileSysOp) THEN + BEGIN + MPL(50); + Input(FSpec,50); + END + ELSE + BEGIN + MPL(12); + Input(FSpec,12); + FSplit(FSpec,Dir,Name,Ext); + FSpec := Name+Ext; + END; + TEdit(FSpec); +END; + +PROCEDURE TEdit(CONST FSpec: AStr); +TYPE + StrPtr = ^StrRec; + + StrRec = RECORD + S: AStr; + Next, + Last: StrPtr; + END; + +VAR + TopHeap: ^Byte; + Fil: Text; + Cur, + Nex, + Las, + Top, + Bottom, + Used: StrPtr; + S: AStr; + TotalLines, + CurLine, + I: Integer; + Done, + AllRead: Boolean; + + PROCEDURE InLi(VAR S1: AStr); + VAR + C, + C1: Char; + Cp, + Rp, + CV, + CC: Integer; + + PROCEDURE BKSpc; + BEGIN + IF (Cp > 1) THEN + BEGIN + IF (S1[Cp - 2] = '^') AND (S1[Cp - 1] IN ['0'..'9']) THEN + BEGIN + UserColor(1); + Dec(Cp); + END + ELSE IF (S1[Cp - 1] = #8) THEN + BEGIN + Prompt(' '); + Inc(Rp); + END + ELSE IF (S1[Cp - 1] <> #10) THEN + BEGIN + Prompt(#8+' '+#8); + Dec(Rp); + END; + Dec(Cp); + END; + END; + + BEGIN + Rp := 1; + Cp := 1; + S1 := ''; + IF (LastLineStr <> '') THEN + BEGIN + Prompt(LastLineStr); + S1 := LastLineStr; + LastLineStr := ''; + Cp := (Length(S1) + 1); + Rp := Cp; + END; + REPEAT + C := Char(GetKey); + CASE C of + #32..#255 : + IF (Cp < StrLen) AND (Rp < ThisUser.LineLen) THEN + BEGIN + S1[Cp] := C; + Inc(Cp); + Inc(Rp); + OutKey(C); + END; + ^H : BKSpc; + ^S : BEGIN + CV := (5 - (Cp MOD 5)); + IF ((Cp + CV) < StrLen) AND ((Rp + CV) < ThisUser.LineLen) THEN + FOR CC := 1 TO CV DO + BEGIN + Prompt(' '); + S1[Cp] := ' '; + Inc(Rp); + Inc(Cp); + END; + END; + ^P : IF (OkANSI OR OkAvatar) AND (Cp < (StrLen - 1)) THEN + BEGIN + C1 := Char(GetKey); + IF (C1 IN ['0'..'9']) THEN + BEGIN + S1[Cp] := '^'; + Inc(Cp); + S1[Cp] := C1; + Inc(Cp); + UserColor(Ord(S1[Cp - 1])); + END; + END; + ^X : BEGIN + Cp := 1; + FOR CV := 1 TO (Rp - 1) DO + Prompt(#8+' '+#8); + UserColor(1); + Rp := 1; + END; + END; + UNTIL ((C = ^M) OR (Rp = ThisUser.LineLen) OR (HangUp)); + S1[0] := Chr(Cp - 1); + IF (C <> ^M ) THEN + BEGIN + CV := (Cp - 1); + WHILE (CV > 1) AND (S1[CV] <> ' ') AND ((S1[CV] <> ^H) OR (S1[CV - 1] = '^')) DO + Dec(CV); + IF (CV > (Rp DIV 2)) AND (CV <> (Cp - 1)) THEN + BEGIN + LastLineStr := Copy(S1,(CV + 1),(Cp - CV)); + FOR CC := (Cp - 2) DOWNTO CV DO + Prompt(^H); + FOR CC := (Cp - 2) DOWNTO CV DO + Prompt(' '); + S1[0] := Chr(CV - 1); + END; + END; + NL; + END; + + FUNCTION NewPtr(VAR x: StrPtr): Boolean; + BEGIN + IF (Used <> NIL) THEN + BEGIN + x := Used; + Used := Used^.Next; + NewPtr := TRUE; + END + ELSE + BEGIN + IF (MaxAvail > 2048) THEN + BEGIN + New(x); + NewPtr := TRUE; + END + ELSE + NewPtr := FALSE; + END; + END; + + PROCEDURE OldPtr(VAR x: StrPtr); + BEGIN + x^.Next := Used; + Used := x; + END; + + PROCEDURE PLine(Cl: Integer; VAR Cp: StrPtr); + VAR + S1: AStr; + BEGIN + IF (NOT Abort) THEN + BEGIN + IF (Cp = NIL) THEN + S1 := ' ^5'+'[^3'+'END^5'+']' + ELSE + S1 := PadRightInt(Cl,4)+': '+Cp^.S; + PrintACR(S1); + END; + END; + + PROCEDURE PL; + BEGIN + Abort := FALSE; + PLine(CurLine,Cur); + END; + +BEGIN +{$IFDEF MSDOS} + Mark(TopHeap); +{$ENDIF} +{$IFDEF WIN32} + // REETODO Prepare to leak memory... +{$ENDIF} + Used := NIL; + Top := NIL; + Bottom := NIL; + AllRead := TRUE; + IF (FSpec = '') THEN + BEGIN + Print('Aborted.'); + END + ELSE + BEGIN + Abort := FALSE; + Next := FALSE; + TotalLines := 0; + New(Cur); + Cur^.Last := NIL; + Cur^.S := ''; + NL; + Assign(Fil,FSpec); + Reset(Fil); + IF (IOResult <> 0) THEN + BEGIN + ReWrite(Fil); + IF (IOResult <> 0) THEN + BEGIN + Print('Error reading file.'); + Abort := TRUE; + END + ELSE + BEGIN + Close(Fil); + Erase(Fil); + Print('New file.'); + TotalLines := 0; + Cur := NIL; + Top := Cur; + Bottom := Cur; + END; + END + ELSE + BEGIN + Abort := NOT NewPtr(Nex); + Top := Nex; + Print('^1Loading...'); + WHILE ((NOT EOF(Fil)) AND (NOT Abort)) DO + BEGIN + Inc(TotalLines); + Cur^.Next := Nex; + Nex^.Last := Cur; + Cur := Nex; + ReadLn(Fil,S); + Cur^.S := S; + Abort := NOT NewPtr(Nex); + END; + Close(Fil); + Cur^.Next := NIL; + IF (TotalLines = 0) THEN + BEGIN + Cur := NIL; + Top := NIL; + END; + Bottom := Cur; + IF (Abort) THEN + BEGIN + NL; + Print(^G^G'|12WARNING: |10Not all of file read.^3'); + NL; + AllRead := FALSE; + END; + Abort := FALSE; + END; + IF (NOT Abort) THEN + BEGIN + Print('Total lines: '+IntToStr(TotalLines)); + Cur := Top; + IF (Top <> NIL) THEN + Top^.Last := NIL; + CurLine := 1; + Done := FALSE; + PL; + REPEAT + Prt(':'); + Input(S,10); + IF (S = '') THEN + S := '+'; + IF (StrToInt(S) > 0) THEN + BEGIN + I := StrToInt(S); + IF ((I > 0) AND (I <= TotalLines)) THEN + BEGIN + WHILE (I <> CurLine) DO + IF (I < CurLine) THEN + BEGIN + IF (Cur = NIL) THEN + BEGIN + Cur := Bottom; + CurLine := TotalLines; + END + ELSE + BEGIN + Dec(CurLine); + Cur := Cur^.Last; + END; + END + ELSE + BEGIN + Inc(CurLine); + Cur := Cur^.Next; + END; + PL; + END; + END + ELSE + CASE S[1] of + '?' : BEGIN + LCmds(14,3,'+Forward line','-Back line'); + LCmds(14,3,'Top','Bottom'); + LCmds(14,3,'Print line','List'); + LCmds(14,3,'Insert lines','Delete line'); + LCmds(14,3,'Replace line','Clear all'); + LCmds(14,3,'Quit (Abort)','Save'); + LCmds(14,3,'*Center line','!Memory Available'); + END; + '!' : Print('Heap space available: '+IntToStr(MemAvail)); + '*' : IF (Cur <> NIL) THEN + Cur^.S := #2+Cur^.S; + '+' : IF (Cur <> NIL) THEN + BEGIN + I := StrToInt(Copy(S,2,9)); + IF (I = 0) THEN + I := 1; + WHILE (Cur <> NIL) AND (I > 0) DO + BEGIN + Cur := Cur^.Next; + Inc(CurLine); + Dec(I); + END; + PL; + END; + '-' : BEGIN + I := StrToInt(Copy(S,2,9)); + IF (I = 0) THEN + I := 1; + IF (Cur = NIL) THEN + BEGIN + Cur := Bottom; + CurLine := TotalLines; + Dec(I); + END; + IF (Cur <> NIL) THEN + IF (Cur^.Last <> NIL) THEN + BEGIN + WHILE ((Cur^.Last <> NIL) AND (I > 0)) DO + BEGIN + Cur := Cur^.Last; + Dec(CurLine); + Dec(I); + END; + PL; + END; + END; + 'B' : BEGIN + Cur := NIL; + CurLine := (TotalLines + 1); + PL; + END; + 'C' : IF PYNQ('Clear workspace? ',0,FALSE) THEN + BEGIN + TotalLines := 0; + CurLine := 1; + Cur := NIL; + Top := NIL; + Bottom := NIL; +{$IFDEF MSDOS} + Release(TopHeap); +{$ENDIF} +{$IFDEF WIN32} + // REETODO Likely going to leak memory right about now +{$ENDIF} + END; + 'D' : BEGIN + I := StrToInt(Copy(S,2,9)); + IF (I = 0) THEN + I := 1; + WHILE (Cur <> NIL) AND (I > 0) DO + BEGIN + Las := Cur^.Last; + Nex := Cur^.Next; + IF (Las <> NIL) THEN + Las^.Next := Nex; + IF (Nex <> NIL) THEN + Nex^.Last := Las; + OldPtr(Cur); + IF (Bottom = Cur) THEN + Bottom := Las; + IF (Top = Cur) THEN + Top := Nex; + Cur := Nex; + Dec(TotalLines); + Dec(I); + END; + PL; + END; + 'I' : BEGIN + Abort := FALSE; + Next := FALSE; + LastLineStr := ''; + NL; + Print(' Enter "." on a separate line to exit insert mode.'); + IF (OkANSI OR OkAvatar) THEN + Print('^2 ^1'); + Dec(ThisUser.LineLen,6); + S := ''; + WHILE (S <> '.') AND (S <> '.'+#1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Prompt(PadRightInt(CurLine,4)+': '); + InLi(S); + IF (S <> '.') AND (S <> '.'+#1) THEN + BEGIN + Abort := NOT NewPtr(Nex); + IF (Abort) THEN + Print('Out of space.') + ELSE + BEGIN + Nex^.S := S; + IF (Top = Cur) THEN + IF (Cur = NIL) THEN + BEGIN + Nex^.Last := NIL; + Nex^.Next := NIL; + Top := Nex; + Bottom := Nex; + END + ELSE + BEGIN + Nex^.Next := Cur; + Cur^.Last := Nex; + Top := Nex; + END + ELSE + BEGIN + IF (Cur = NIL) THEN + BEGIN + Bottom^.Next := Nex; + Nex^.Last := Bottom; + Nex^.Next := NIL; + Bottom := Nex; + END + ELSE + BEGIN + Las := Cur^.Last; + Nex^.Last := Las; + Nex^.Next := Cur; + Cur^.Last := Nex; + Las^.Next := Nex; + END; + END; + Inc(CurLine); + Inc(TotalLines); + END + END; + END; + Inc(ThisUser.LineLen,6); + END; + 'L' : BEGIN + Abort := FALSE; + Next := FALSE; + Nex := Cur; + I := CurLine; + WHILE (Nex <> NIL) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + PLine(I,Nex); + Nex := Nex^.Next; + Inc(I); + END; + END; + 'P' : PL; + 'R' : IF (Cur <> NIL) THEN + BEGIN + PL; + Prompt(PadRightInt(CurLine,4)+': '); + InLi(S); + Cur^.S := S; + END; + 'Q' : Done := TRUE; + 'S' : BEGIN + IF (NOT AllRead) THEN + BEGIN + UserColor(5); + Prompt('Not all of file read. '); + AllRead := PYNQ('Save anyway? ',0,FALSE); + END; + IF (AllRead) THEN + BEGIN + Done := TRUE; + Print('Saving ...'); + SysOpLog('Saved "'+FSpec+'"'); + ReWrite(Fil); + I := 0; + Cur := Top; + WHILE (Cur <> NIL) DO + BEGIN + WriteLn(Fil,Cur^.S); + Cur := Cur^.Next; + Dec(I); + END; + + IF (I = 0) THEN + WriteLn(Fil); + + Close(Fil); + END; + END; + 'T' : BEGIN + Cur := Top; + CurLine := 1; + PL; + END; + END; + UNTIL ((Done) OR (HangUp)); + END; + END; +{$IFDEF MSDOS} + Release(TopHeap); +{$ENDIF} +{$IFDEF WIN32} + // REETODO Likely going to leak memory right about now +{$ENDIF} + PrintingFile := FALSE; + LastError := IOResult; +END; + +END. diff --git a/SOURCE/SYSOP5.PAS b/SOURCE/SYSOP5.PAS new file mode 100644 index 0000000..2c6241d --- /dev/null +++ b/SOURCE/SYSOP5.PAS @@ -0,0 +1,553 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp5; + +INTERFACE + +PROCEDURE HistoryEditor; + +IMPLEMENTATION + +USES + Common, + TimeFunc; + +PROCEDURE HistoryEditor; +CONST + MaxHistoryDates = 32767; +VAR + HistoryFile: FILE OF HistoryRecordType; + History: HistoryRecordType; + TempHistory: HistoryRecordType; + Cmd: Char; + RecNumToList, + NumHistoryDates: Integer; + SaveTempPause: Boolean; + + PROCEDURE InitHistoryVars(VAR History: HistoryRecordType); + VAR + Counter: Byte; + BEGIN + FillChar(History,SizeOf(History),0); + WITH History DO + BEGIN + Date := 0; + FOR Counter := 0 TO 20 DO + UserBaud[Counter] := 0; + Active := 0; + Callers := 0; + NewUsers := 0; + Posts := 0; + EMail := 0; + FeedBack := 0; + Errors := 0; + Uploads := 0; + Downloads := 0; + UK := 0; + Dk := 0; + END; + END; + + PROCEDURE LocateHistoryDate(DisplayStr: AStr; TempHistory1: HistoryRecordType; VAR DateToLocate: Str10; + VAR RecNum1: SmallInt; ShowErr,Searching: Boolean); + VAR + RecNum: Integer; + BEGIN + RecNum1 := -1; + InputFormatted(DisplayStr,DateToLocate,'##-##-####',TRUE); + IF (DateToLocate <> '') AND (Length(DateToLocate) = 10) THEN + BEGIN + IF (Searching) THEN + Reset(HistoryFile); + RecNum := 1; + WHILE (RecNum <= FileSize(HistoryFile)) AND (RecNum1 = -1) DO + BEGIN + Seek(HistoryFile,(RecNum - 1)); + Read(HistoryFile,TempHistory1); + IF (PD2Date(TempHistory1.Date) = DateToLocate) THEN + RecNum1 := RecNum; + Inc(RecNum); + END; + IF (Searching) THEN + Close(HistoryFile); + IF (ShowErr) AND (RecNum1 = -1) THEN + BEGIN + Print('%LF^7The date entered is invalid!^1'); + PauseScr(FALSE); + END; + END; + END; + + PROCEDURE DeleteHistoryRecord(TempHistory1: HistoryRecordType; RecNumToDelete: SmallInt); + VAR + DateToDelete: Str10; + RecNum: Integer; + BEGIN + IF (NumHistoryDates = 0) THEN + Messages(4,0,'history dates') + ELSE + BEGIN + LocateHistoryDate('%LFHistory date to delete: ',TempHistory1,DateToDelete,RecNumToDelete,TRUE,TRUE); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= NumHistoryDates) THEN + BEGIN + Reset(HistoryFile); + Seek(HistoryFile,(RecNumToDelete - 1)); + Read(HistoryFile,TempHistory1); + Close(HistoryFile); + LastError := IOResult; + IF (PD2Date(TempHistory1.Date) = DateStr) THEN + BEGIN + Print('%LF^7The current history date can not be deleted!^1'); + PauseScr(FALSE); + END + ELSE + BEGIN + Print('%LFHistory date: ^5'+PD2Date(TempHistory1.Date)); + IF PYNQ('%LFAre you sure you want to delete it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Deleting history record ...'); + Dec(RecNumToDelete); + Reset(HistoryFile); + IF (RecNumToDelete >= 0) AND (RecNumToDelete <= (FileSize(HistoryFile) - 2)) THEN + FOR RecNum := RecNumToDelete TO (FileSize(HistoryFile) - 2) DO + BEGIN + Seek(HistoryFile,(RecNum + 1)); + Read(HistoryFile,History); + Seek(HistoryFile,RecNum); + Write(HistoryFile,History); + END; + Seek(HistoryFile,(FileSize(HistoryFile) - 1)); + Truncate(HistoryFile); + Close(HistoryFile); + LastError := IOResult; + Dec(NumHistoryDates); + SysOpLog('* Deleted history date: ^5'+Pd2Date(TempHistory1.Date)); + END; + END; + END; + END; + END; + + PROCEDURE CheckHistoryRecord(History: HistoryRecordType; StartErrMsg,EndErrMsg: Byte; VAR Ok: Boolean); + VAR + Counter: Byte; + BEGIN + FOR Counter := StartErrMsg TO EndErrMsg DO + CASE Counter OF + 1 : ; + END; + END; + + PROCEDURE EditHistoryRecord(TempHistory1: HistoryRecordType; VAR History: HistoryRecordType; VAR Cmd1: Char; + VAR RecNumToEdit,SaveRecNumToEdit: SmallInt; VAR Changed: Boolean; Editing: Boolean); + VAR + CmdStr, + TempStr1: AStr; + DateToLocate: Str10; + RecNum: SmallInt; + Ok: Boolean; + BEGIN + WITH History DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + CLS; + IF (Editing) THEN + PrintACR('^5Editing history record #'+IntToStr((NumHistoryDates + 1) - RecNumToEdit)+ + ' of '+IntToStr(NumHistoryDates)) + ELSE + PrintACR('^5Inserting history record #'+IntToStr((NumHistoryDates + 1) - RecNumToEdit)+ + ' of '+IntToStr(NumHistoryDates + 1)); + NL; + IF (Callers > 0) THEN + TempStr1 := IntToStr(Active DIV Callers) + ELSE + TempStr1 := '0'; + PrintACR('^1A. Date : ^5'+PD2Date(Date)+AOnOff(RecNumToEdit = NumHistoryDates,' (Today)','')); + PrintACR('^1B. Minutes Active: ^5'+FormatNumber(Active)); + PrintACR('^1C. Calls : ^5'+FormatNumber(Callers)); + PrintACR('^1D. Percent Active: ^5'+SQOutSp(CTP(Active,1440))); + PrintACR('^1E. New Users : ^5'+FormatNumber(NewUsers)); + PrintACR('^1G. Time/User : ^5'+TempStr1); + PrintACR('^1H. Public Posts : ^5'+FormatNumber(Posts)); + PrintACR('^1I. Private Posts : ^5'+FormatNumber(EMail)); + PrintACR('^1K. SysOp FeedBack: ^5'+FormatNumber(FeedBack)); + PrintACR('^1M. Errors : ^5'+FormatNumber(Errors)); + PrintACR('^1N. Uploads : ^5'+FormatNumber(Uploads)); + PrintACR('^1O. Upload K : ^5'+FormatNumber(UK)); + PrintACR('^1P. DownLoads : ^5'+FormatNumber(DownLoads)); + PrintACR('^1R. Download K : ^5'+FormatNumber(DK)); + PrintACR('^1S. Baud Rates'); + END; + IF (NOT Editing) THEN + CmdStr := 'ABCDEGHIKMNOPRS' + ELSE + CmdStr := 'ABCDEGHIKMNOPRS[]FJL'; + LOneK('%LFModify menu [^5?^4=^5Help^4]: ',Cmd1,'Q?'+CmdStr+^M,TRUE,TRUE); + CASE Cmd1 OF + 'A' : IF (PD2Date(Date) = DateStr) THEN + BEGIN + Print('%LF^7The current history date can not be changed!^1'); + PauseScr(FALSE); + END + ELSE + BEGIN + REPEAT + Ok := TRUE; + LocateHistoryDate('%LFNew history date: ',TempHistory1,DateToLocate,RecNum,FALSE,FALSE); + IF (DateToLocate <> '') AND (NOT (DateToLocate = PD2Date(History.Date))) THEN + BEGIN + IF (RecNum <> -1) THEN + BEGIN + Print('%LF^7The date entered is invalid!^1'); + Ok := FALSE; + END + ELSE IF (DayNum(DateToLocate) > DayNum(DateStr)) THEN + BEGIN + Print('%LF^7The date can not be changed to a future date!^1'); + Ok := FALSE; + END + ELSE IF (DateToLocate <> '') THEN + BEGIN + Date := Date2PD(DateToLocate); + Changed := TRUE; + END; + END; + UNTIL (Ok) OR (HangUp); + END; + 'B' : InputLongIntWC('%LFNew minutes active for this date',Active, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'C' : InputLongIntWC('%LFNew number of system callers for this date',Callers, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'D' : BEGIN + Print('%LF^7This is for internal use only.'); + PauseScr(FALSE); + END; + 'E' : InputLongIntWC('%LFNew new user''s for this date',NewUsers, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'G' : BEGIN + Print('%LF^7This is for internal use only.'); + PauseScr(FALSE); + END; + 'H' : InputLongIntWC('%LFNew public message post''s this date',Posts, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'I' : InputLongIntWC('%LFNew private message post''s this date',Email, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'K' : InputLongIntWC('%LFNew sysop feedback sent this date',FeedBack, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'M' : InputLongIntWC('%LFNew system error''s this date',Errors, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'N' : InputLongIntWC('%LFNew user upload''s for this date',Uploads, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'O' : InputLongIntWC('%LFNew user kbytes uploaded this date',UK, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'P' : InputLongIntWC('%LFNew user download''s this date',Downloads, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'R' : InputLongIntWC('%LFNew user kbytes downloaded this date',DK, + [DisplayValue,NumbersOnly],0,2147483647,Changed); + 'S' : BEGIN + REPEAT + Print('%CL^5User Baud Rates'); + Print('%LF'+PadLeftStr('^1A. Telnet/Other: ^5'+FormatNumber(UserBaud[0]),32)+ + '^1B. 300 Baud : ^5'+IntToStr(UserBaud[1])); + Print(PadLeftStr('^1C. 600 Baud : ^5'+IntToStr(UserBaud[2]),32)+ + '^1D. 1200 Baud : ^5'+FormatNumber(UserBaud[3])); + Print(PadLeftStr('^1E. 2400 Baud : ^5'+FormatNumber(UserBaud[4]),32)+ + '^1F. 4800 Baud : ^5'+FormatNumber(UserBaud[5])); + Print(PadLeftStr('^1G. 7200 Baud : ^5'+FormatNumber(UserBaud[6]),32)+ + '^1H. 9600 Baud : ^5'+FormatNumber(UserBaud[7])); + Print(PadLeftStr('^1I. 12000 Baud : ^5'+FormatNumber(UserBaud[8]),32)+ + '^1J. 14400 Baud : ^5'+FormatNumber(UserBaud[9])); + Print(PadLeftStr('^1K. 16800 Baud : ^5'+FormatNumber(UserBaud[10]),32)+ + '^1L. 19200 Baud : ^5'+FormatNumber(UserBaud[11])); + Print(PadLeftStr('^1M. 21600 Baud : ^5'+FormatNumber(UserBaud[12]),32)+ + '^1N. 24000 Baud : ^5'+FormatNumber(UserBaud[13])); + Print(PadLeftStr('^1O. 26400 Baud : ^5'+FormatNumber(UserBaud[14]),32)+ + '^1P. 28800 Baud : ^5'+FormatNumber(UserBaud[15])); + Print(PadLeftStr('^1Q. 31200 Baud : ^5'+FormatNumber(UserBaud[16]),32)+ + '^1R. 33600 Baud : ^5'+FormatNumber(UserBaud[17])); + Print(PadLeftStr('^1S. 38400 Baud : ^5'+FormatNumber(UserBaud[18]),32)+ + '^1T. 57600 Baud : ^5'+FormatNumber(UserBaud[19])); + Print(PadLeftStr('^1U. 115200 Baud : ^5'+FormatNumber(UserBaud[20]),32)); + LOneK('%LFModify menu [^5A^4-^5U^4,^5^4=^5Quit^4]: ',Cmd1,^M'ABCDEFGHIJKLMNOPQRSTU',TRUE,TRUE); + IF (Cmd1 <> ^M) THEN + InputLongIntWC('%LFNew value',UserBaud[Ord(Cmd1) - 65], + [DisplayValue,NumbersOnly],0,2147483647,Changed); + UNTIL (Cmd1 = ^M) OR (HangUp); + Cmd1 := #0; + END; + ']' : IF (RecNumToEdit > 1) THEN + Dec(RecNumToEdit) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '[' : IF (RecNumToEdit < NumHistoryDates) THEN + Inc(RecNumToEdit) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNumToEdit <> NumHistoryDates) THEN + RecNumToEdit := NumHistoryDates + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + RecNumToEdit := -1; + InputIntegerWOC('%LFJump to entry?',RecNumToEdit,[NumbersOnly],1,NumHistoryDates); + IF (RecNumToEdit < 1) OR (RecNumToEdit > NumHistoryDates) THEN + BEGIN + RecNumToEdit := SaveRecNumToEdit; + Cmd1 := #0; + END + ELSE + RecNumToEdit := ((NumHistoryDates - RecNumToEdit) + 1); + END; + 'L' : IF (RecNumToEdit <> 1) THEN + RecNumToEdit := 1 + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay current screen'); + Print('^3A^1-^3E^1,^3G^1-^3I^1,^3K^1,^3M^1-^3P^1,^3R^1-^3S^1:Modify item'); + IF (NOT Editing) THEN + LCmds(20,3,'Quit and save','') + ELSE + BEGIN + LCmds(20,3,'[Back entry',']Forward entry'); + LCmds(20,3,'First entry in list','Jump to entry'); + LCmds(20,3,'Last entry in list','Quit and save'); + END; + END; + END; + UNTIL (Pos(Cmd1,'Q[]FJL') <> 0) OR (HangUp); + END; + + PROCEDURE InsertHistoryRecord(TempHistory1: HistoryRecordType; Cmd1: Char; RecNumToInsertBefore: SmallInt); + VAR + DateToInsert, + DateToInsertBefore: Str10; + RecNum, + RecNum1, + SaveRecNumToEdit: SmallInt; + Ok, + Changed: Boolean; + BEGIN + IF (NumHistoryDates = MaxHistoryDates) THEN + Messages(5,MaxHistoryDates,'history dates') + ELSE + BEGIN + LocateHistoryDate('%LFHistory date to insert before: ',TempHistory1,DateToInsertBefore,RecNumToInsertBefore,TRUE,TRUE); + IF (RecNumToInsertBefore >= 1) AND (RecNumToInsertBefore <= (NumHistoryDates + 1)) THEN + BEGIN + LocateHistoryDate('%LFNew history date to insert: ',TempHistory1,DateToInsert,RecNum1,FALSE,TRUE); + IF (RecNum1 <> -1) THEN + BEGIN + Print('%LF^7Duplicate date entered!^1'); + PauseScr(FALSE); + END + ELSE IF (DayNum(DateToInsert) > DayNum(DateStr)) THEN + BEGIN + Print('%LF^7Future dates can not be entered!^1'); + PauseScr(FALSE); + END + ELSE + BEGIN + IF (DayNum(DateToInsert) > DayNum(DateToInsertBefore)) THEN + Inc(RecNumToInsertBefore); + Reset(HistoryFile); + InitHistoryVars(TempHistory1); + TempHistory1.Date := Date2PD(DateToInsert); + IF (RecNumToInsertBefore = 1) THEN + RecNum1 := 0 + ELSE IF (RecNumToInsertBefore = NumHistoryDates) THEN + RecNum1 := (RecNumToInsertBefore - 1) + ELSE + RecNum1 := RecNumToInsertBefore; + REPEAT + OK := TRUE; + EditHistoryRecord(TempHistory1,TempHistory1,Cmd1,RecNum1,SaveRecNumToEdit,Changed,FALSE); + CheckHistoryRecord(TempHistory1,1,1,Ok); + IF (NOT OK) THEN + IF (NOT PYNQ('%LFContinue inserting history date? ',0,TRUE)) THEN + Abort := TRUE; + UNTIL (OK) OR (Abort) OR (HangUp); + IF (NOT Abort) AND (PYNQ('%LFIs this what you want? ',0,FALSE)) THEN + BEGIN + Print('%LF[> Inserting history record ...'); + Seek(HistoryFile,FileSize(HistoryFile)); + Write(HistoryFile,History); + Dec(RecNumToInsertBefore); + FOR RecNum := ((FileSize(HistoryFile) - 1) - 1) DOWNTO RecNumToInsertBefore DO + BEGIN + Seek(HistoryFile,RecNum); + Read(HistoryFile,History); + Seek(HistoryFile,(RecNum + 1)); + Write(HistoryFile,History); + END; + FOR RecNum := RecNumToInsertBefore TO ((RecNumToInsertBefore + 1) - 1) DO + BEGIN + Seek(HistoryFile,RecNum); + Write(HistoryFile,TempHistory1); + Inc(NumHistoryDates); + SysOpLog('* Inserted history date: ^5'+PD2Date(TempHistory1.Date)); + END; + END; + Close(HistoryFile); + LastError := IOResult; + END; + END; + END; + END; + + PROCEDURE ModifyHistoryRecord(TempHistory1: HistoryRecordType; Cmd1: Char; RecNumToEdit: SmallInt); + VAR + DateToEdit: Str10; + SaveRecNumToEdit: SmallInt; + Ok, + Changed: Boolean; + BEGIN + IF (NumHistoryDates = 0) THEN + Messages(4,0,'history dates') + ELSE + BEGIN + LocateHistoryDate('%LFHistory date to modify: ',TempHistory1,DateToEdit,RecNumToEdit,TRUE,TRUE); + IF (RecNumToEdit >= 1) AND (RecNumToEdit <= NumHistoryDates) THEN + BEGIN + SaveRecNumToEdit := -1; + Cmd1 := #0; + Reset(HistoryFile); + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNumToEdit <> RecNumToEdit) THEN + BEGIN + Seek(HistoryFile,(RecNumToEdit - 1)); + Read(HistoryFile,History); + SaveRecNumToEdit := RecNumToEdit; + Changed := FALSE; + END; + REPEAT + Ok := TRUE; + EditHistoryRecord(TempHistory1,History,Cmd1,RecNumToEdit,SaveRecNumToEdit,Changed,TRUE); + CheckHistoryRecord(History,1,1,Ok); + IF (NOT OK) THEN + BEGIN + PauseScr(FALSE); + IF (RecNumToEdit <> SaveRecNumToEdit) THEN + RecNumToEdit := SaveRecNumToEdit; + END; + UNTIL (OK) OR (HangUp); + IF (Changed) THEN + BEGIN + Seek(HistoryFile,(SaveRecNumToEdit - 1)); + Write(HistoryFile,History); + Changed := FALSE; + SysOpLog('* Modified history date: ^5'+PD2Date(History.Date)); + END; + END; + Close(HistoryFile); + LastError := IOResult; + END; + END; + END; + + PROCEDURE ListHistoryDates(VAR RecNumToList1: Integer); + VAR + TempStr: AStr; + NumDone: Integer; + BEGIN + IF (RecNumToList1 < 1) OR (RecNumToList1 > NumHistoryDates) THEN + RecNumToList1 := NumHistoryDates; + Abort := FALSE; + Next := FALSE; + CLS; + PrintACR('^3 ^4:^3Mins ^4:^3 ^4:^3 ^4:^3#New^4:^3Tim/^4:^3Pub ^4:^3Priv^4:^3Feed^4:^3 ^4:^3'+ + ' ^4:^3 ^4:^3 ^4:^3'); + PrintACR('^3 Date ^4:^3Activ^4:^3Call^4:^3%Activ^4:^3User^4:^3User^4:^3Post^4:^3Post'+ + '^4:^3Back^4:^3Errs^4:^3#ULs^4:^3UL-k ^4:^3#DLs^4:^3DL-k'); + PrintACR('^4========:=====:====:======:====:====:====:====:====:====:====:=====:====:====='); + Reset(HistoryFile); + NumDone := 0; + WHILE (NumDone < (PageLength - 6)) AND (RecNumToList1 >= 1) AND (RecNumToList1 <= NumHistoryDates) + AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(HistoryFile,(RecNumToList1 - 1)); + Read(HistoryFile,History); + WITH History DO + BEGIN + IF (Callers > 0) THEN + TempStr := PadRightInt(Active DIV Callers,4) + ELSE + TempStr := ' '; + PrintACR('^1'+AOnOff((RecNumToList1 = NumHistoryDates),'Today''s ',ToDate8(PD2Date(Date)))+ + ' '+PadRightInt(Active,5)+ + ' '+PadRightInt(Callers,4)+ + ' '+CTP(Active,1440)+ + ' '+PadRightInt(NewUsers,4)+ + ' '+TempStr+ + ' '+PadRightInt(Posts,4)+ + ' '+PadRightInt(EMail,4)+ + ' '+PadRightInt(FeedBack,4)+ + ' '+PadRightInt(Errors,4)+ + ' '+PadRightInt(Uploads,4)+ + ' '+PadRightInt(UK,5)+ + ' '+PadRightInt(DownLoads,4)+ + ' '+PadRightInt(DK,5)); + END; + Dec(RecNumToList1); + Inc(NumDone); + END; + Close(HistoryFile); + LastError := IOResult; + IF (NumHistoryDates = 0) THEN + Print('*** No history dates defined ***'); + END; + +BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + Assign(HistoryFile,General.DataPath+'HISTORY.DAT'); + Reset(HistoryFile); + NumHistoryDates := FileSize(HistoryFile); + Close(HistoryFile); + RecNumToList := NumHistoryDates; + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + ListHistoryDates(RecNumToList); + LOneK('%LFHistory editor [^5?^4=^5Help^4]: ',Cmd,'QDIM?'^M,TRUE,TRUE); + CASE Cmd OF + ^M : IF (RecNumToList < 1) OR (RecNumToList > NumHistoryDates) THEN + RecNumToList := NumHistoryDates; + 'D' : DeleteHistoryRecord(TempHistory,RecNumToList); + 'I' : InsertHistoryRecord(TempHistory,Cmd,RecNumToList); + 'M' : ModifyHistoryRecord(TempHistory,Cmd,RecNumToList); + '?' : BEGIN + Print('%LF^1<^3CR^1>Next screen or redisplay current screen'); + Print('^1(^3?^1)Help/First history date'); + LCmds(20,3,'Delete history date','Insert history date'); + LCmds(20,3,'Modify history date','Quit'); + END; + END; + IF (Cmd <> ^M) THEN + RecNumToList := NumHistoryDates; + UNTIL (Cmd = 'Q') OR (HangUp); + TempPause := SaveTempPause; + LastError := IOResult; +END; + +END. diff --git a/SOURCE/SYSOP6.PAS b/SOURCE/SYSOP6.PAS new file mode 100644 index 0000000..0e93253 --- /dev/null +++ b/SOURCE/SYSOP6.PAS @@ -0,0 +1,1001 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp6; + +INTERFACE + +PROCEDURE EventEditor; + +IMPLEMENTATION + +USES + Common, + TimeFunc; + +PROCEDURE EventEditor; +VAR + TempEvent: EventRecordType; + Cmd: Char; + RecNumToList: Integer; + SaveTempPause: Boolean; + + FUNCTION DaysEventActive(EventDays: EventDaysType; C1,C2: Char): AStr; + CONST + Days: Str7 = 'SMTWTFS'; + VAR + TempStr: AStr; + Counter: Byte; + BEGIN + TempStr := ''; + FOR Counter := 0 TO 6 DO + IF (Counter IN EventDays) THEN + TempStr := TempStr + '^'+C1+Days[Counter + 1] + ELSE + TempStr := TempStr + '^'+C2+'-'; + DaysEventActive := TempStr; + END; + + FUNCTION NextDay(Date: Str10): LongInt; + VAR + Day, + Month, + Year: Word; + BEGIN + Month := StrToInt(Copy(Date,1,2)); + Day := StrToInt(Copy(Date,4,2)); + Year := StrToInt(Copy(Date,7,4)); + IF (Day = 31) AND (Month = 12) THEN + BEGIN + Inc(Year); + Month := 1; + Day := 1; + END + ELSE + BEGIN + IF (Day < Days(Month,Year)) THEN + Inc(Day) + ELSE IF (Month < 12) THEN + BEGIN + Inc(Month); + Day := 1; + END; + END; + NextDay := Date2PD(ZeroPad(IntToStr(Month))+'/'+ZeroPad(IntToStr(Day))+'/'+IntToStr(Year)); + END; + + FUNCTION ShowTime(W: Word): Str5; + BEGIN + ShowTime := ZeroPad(IntToStr(W DIV 60))+':'+ZeroPad(IntToStr(W MOD 60)); + END; + + PROCEDURE ToggleEFlag(EFlagT: EventFlagType; VAR EFlags: EFlagSet); + BEGIN + IF (EFlagT IN EFlags) THEN + Exclude(EFlags,EFlagT) + ELSE + Include(EFlags,EFlagT); + END; + + PROCEDURE ToggleEFlags(C: Char; VAR EFlags: EFlagSet; VAR Changed: Boolean); + VAR + SaveEFlags: EFlagSet; + BEGIN + SaveEFlags := EFlags; + CASE C OF + 'A' : ToggleEFlag(EventIsExternal,EFlags); + 'B' : ToggleEFlag(EventIsActive,EFlags); + 'C' : ToggleEFlag(EventIsShell,EFlags); + 'D' : ToggleEFlag(EventIsOffhook,EFlags); + 'E' : ToggleEFlag(EventIsMonthly,EFlags); + 'F' : ToggleEFlag(EventIsPermission,EFlags); + 'G' : ToggleEFlag(EventIsLogon,EFlags); + 'H' : ToggleEFlag(EventIsChat,EFlags); + 'I' : ToggleEFlag(EventIsPackMsgAreas,EFlags); + 'J' : ToggleEFlag(EventIsSortFiles,EFlags); + 'K' : ToggleEFlag(EventIsSoft,EFlags); + 'L' : ToggleEFlag(EventIsMissed,EFlags); + 'M' : ToggleEFlag(BaudIsActive,EFlags); + 'N' : ToggleEFlag(AcsIsActive,EFlags); + 'O' : ToggleEFlag(TimeIsActive,EFlags); + 'P' : ToggleEFlag(ARisActive,EFlags); + 'Q' : ToggleEFlag(SetARisActive,EFlags); + 'R' : ToggleEFlag(ClearARisActive,EFlags); + 'S' : ToggleEFlag(InRatioIsActive,EFlags); + END; + IF (EFlags <> SaveEFlags) THEN + Changed := TRUE; + END; + + PROCEDURE InitEventVars(VAR Event: EventRecordType); + BEGIN + FillChar(Event,SizeOf(Event),0); + WITH Event DO + BEGIN + EventDescription := '<< New Event >>'; + EventDayOfMonth := 0; + EventDays := []; + EventStartTime := 0; + EventFinishTime := 0; + EventQualMsg := ''; + EventNotQualMsg := ''; + EventPreTime := 0; + EventNode := 0; + EventLastDate := 0; + EventErrorLevel := 0; + EventShellPath := ''; + LoBaud := 300; + HiBaud := 19200; + EventACS := 's10'; + MaxTimeAllowed := 60; + SetARflag := '@'; + ClearARflag := '@'; + EFlags := [EventIsExternal,EventIsShell]; + END; + END; + + PROCEDURE DeleteEvent(TempEvent1: EventRecordType; RecNumToDelete: SmallInt); + VAR + RecNum: Integer; + BEGIN + IF (NumEvents = 0) THEN + Messages(4,0,'events') + ELSE + BEGIN + RecNumToDelete := -1; + InputIntegerWOC('%LFEvent to delete?',RecNumToDelete,[NumbersOnly],1,NumEvents); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= NumEvents) THEN + BEGIN + Reset(EventFile); + Seek(EventFile,(RecNumToDelete - 1)); + Read(EventFile,TempEvent1); + Close(EventFile); + LastError := IOResult; + Print('%LFEvent: ^5'+TempEvent1.EventDescription); + IF PYNQ('%LFAre you sure you want to delete it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Deleting event record ...'); + Dec(RecNumToDelete); + Reset(EventFile); + IF (RecNumToDelete >= 0) AND (RecNumToDelete <= (FileSize(EventFile) - 2)) THEN + FOR RecNum := RecNumToDelete TO (FileSize(EventFile) - 2) DO + BEGIN + Seek(EventFile,(RecNum + 1)); + Read(EventFile,Event); + Seek(EventFile,RecNum); + Write(EventFile,Event); + END; + Seek(EventFile,(FileSize(EventFile) - 1)); + Truncate(EventFile); + Close(EventFile); + LastError := IOResult; + Dec(NumEvents); + SysOpLog('* Deleted event: ^5'+TempEvent1.EventDescription); + END; + END; + END; + END; + + PROCEDURE CheckEvent(Event: EventRecordType; StartErrMsg,EndErrMsg: Byte; VAR Ok: Boolean); + VAR + Counter: Byte; + BEGIN + FOR Counter := StartErrMsg TO EndErrMsg DO + CASE Counter OF + 1 : ; + END; + END; + + + + PROCEDURE EditEvent(TempEvent1: EventRecordType; VAR Event: EventRecordType; VAR Cmd1: Char; + VAR RecNumToEdit: SmallInt; VAR Changed: Boolean; Editing: Boolean); + CONST + BaudRates: ARRAY [1..20] OF LongInt = (300,600,1200,2400,4800,7200,9600, + 12000,14400,16800,19200,21600,24000, + 26400,28800,31200,33600,38400,57600, + 115200); + VAR + OneKCmds, + TempStr: AStr; + Counter: Byte; + BEGIN + WITH Event DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + CLS; + IF (Editing) THEN + PrintACR('^5Editing event #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumEvents)) + ELSE + PrintACR('^5Inserting event #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumEvents + 1)); + NL; + PrintACR('^1A. Event type : ^5'+AOnOff(EventIsExternal IN EFlags,'External','Internal')); + PrintACR('^1B. Description : ^5'+EventDescription); + PrintACR('^1C. Active : ^5'+AOnOff(EventIsActive IN EFlags,'Active','Inactive')); + IF (EventIsExternal IN EFlags) THEN + BEGIN + PrintACR('^1D. Execution hard/soft : ^5'+AOnOff(EventIsSoft IN EFlags,'Soft','Hard')); + TempStr := '^1E. Event type : ^5'; + IF (EventIsErrorLevel IN EFlags) THEN + TempStr := TempStr + 'Error level = '+IntToStr(EventErrorLevel) + ELSE IF (EventIsShell IN EFlags) THEN + TempStr := TempStr + 'Shell file = "'+EventShellPath+'"' + ELSE IF (EventIsSortFiles IN EFlags) THEN + TempStr := TempStr + 'Sort Files' + ELSE IF (EventIsPackMsgAreas IN EFlags) THEN + TempStr := TempStr + 'Pack Message Areas' + ELSE IF (EventIsFilesBBS IN EFlags) THEN + TempStr := TempStr + 'Check Files.BBS'; + PrintACR(TempStr); + PrintACR('^1G. Scheduled day(s) : ^5'+AOnOff(EventIsMonthly IN EFlags, + 'Monthly ^1-^5 Day ^1=^5 '+IntToStr(EventDayOfMonth), + 'Weekly ^1-^5 Days ^1=^5 '+DaysEventActive(EventDays,'5','1'))); + PrintACR('^1H. Start time : ^5'+ShowTime(EventStartTime)); + PrintACR('^1I. Phone status : ^5'+AOnOff(EventIsOffHook IN EFlags, + 'Off-hook ('+IntToStr(EventPreTime)+' minutes before the Event)', + 'Remain on-hook')); + PrintACR('^1K. Executed today : ^5'+ShowYesNo(PD2Date(EventLastDate) = DateStr)+' ' + +AOnOff(EventIsActive IN EFlags, + '(Next scheduled date: '+PD2Date(EventLastDate)+')', + '(Not scheduled for execution)')); + END + ELSE + BEGIN + PrintACR('^1D. Scheduled day(s) : ^5'+AOnOff(EventIsMonthly IN EFlags, + 'Monthly ^1-^5 Day ^1=^5 '+IntToStr(EventDayOfMonth), + 'Weekly ^1-^5 Days ^1=^5 '+DaysEventActive(EventDays,'5','1'))); + PrintACR('^1E. Time active : ^5'+ShowTime(EventStartTime)+' to '+ + ShowTime(EventFinishTime)); + PrintACR('^1G. Permission/restriction: ^5'+AOnOff(EventIsPermission IN EFlags, + 'Permission','Restriction')); + PrintACR('^1H. Event type : ^5'+AOnOff(EventIsChat IN EFlags,'Chat','Logon')); + PrintACR('^1I. Affected message : "^5'+eventqualmsg+'^1"'); + PrintACR('^1K. Unaffected message : "^5'+eventnotqualmsg+'^1"'); + END; + PrintACR('^1M. Run if missed : ^5'+ShowYesNo(EventIsMissed IN EFlags)); + PrintACR('^1N. Node number : ^5'+IntToStr(EventNode)); + IF (NOT (EventIsExternal IN EFlags)) THEN + BEGIN + NL; + PrintACR(' ^4<<<^5 Qualifiers ^4>>>'); + NL; + PrintACR('^11. Baud rate range : ^5'+AOnOff(BaudIsActive IN EFlags, + IntToStr(LoBaud)+' to '+IntToStr(HiBaud), + '<>')); + PrintACR('^12. ACS : ^5'+AOnOff(ACSIsActive IN EFlags,EventACS,'<>')); + IF (EventIsPermission IN EFlags) THEN + PrintACR('^13. Maximum time : ^5'+AOnOff(TimeIsActive IN EFlags, + IntToStr(MaxTimeAllowed), + '<>')); + IF (EventIsPermission IN EFlags) THEN + BEGIN + PrintACR('^14. Set AR flag : ^5'+AOnOff(SetArIsActive IN EFlags, + SetArFlag, + '<>')); + PrintACR('^15. Clear AR flag : ^5'+AOnOff(ClearArIsActive IN EFlags, + ClearArFlag, + '<>')); + END; + PrintACR('^16. UL/DL ratio check: ^5'+AOnOff(InRatioIsActive IN EFlags, + 'Active', + '<>')); + END; + END; + IF (EventIsExternal IN EFlags) THEN + OneKCmds := '' + ELSE + BEGIN + IF (EventIsPermission IN EFlags) THEN + OneKCmds := '123456' + ELSE + OneKCmds := '126'; + END; + LOneK('%LFModify '+AOnOff(EventIsExternal IN EFlags,'external','internal')+' event [^5?^4=^5Help^4]: ', + Cmd1,'QABCDEGHIKMN'+OneKCmds+'[]FJL?'^M,TRUE,TRUE); + CASE Cmd1 OF + 'A' : ToggleEFlagS('A',EFlags,Changed); { External/Internal } + 'B' : InputWN1('%LFNew description: ',EventDescription,30,[InterActiveEdit],Changed); + 'C' : ToggleEFlags('B',EFlags,Changed); { Active/InActive } + 'D' : IF (EventIsExternal IN EFlags) THEN + ToggleEFlags('K',EFlags,Changed) { Soft/Hard } + ELSE { Dialy/Monthly } + BEGIN + LOneK('%LFSchedule? [^5D^4=^5Daily^4,^5M^4=^5Monthly^4,^5^4=^5Quit^4]: ',Cmd1,^M'DM',TRUE,TRUE); + CASE Cmd1 OF + 'D' : BEGIN + IF (EventIsMonthly IN EFlags) THEN + BEGIN + Exclude(EFlags,EventIsMonthly); + EventDayOfMonth := 0; + Changed := TRUE; + END; + REPEAT + Print('%LF^5Active Days: ^3'+DaysEventActive(EventDays,'5','4')+'^1'); + NL; + LCmds(11,3,'1Sunday',''); + LCmds(11,3,'2Monday',''); + LCmds(11,3,'3Tuesday',''); + LCmds(11,3,'4Wednesday',''); + LCmds(11,3,'5Thursday',''); + LCmds(11,3,'6Friday',''); + LCmds(11,3,'7Saturday',''); + LOneK('%LFToggle which day? [^51^4-^57^4,^5^4=^5Quit^4]: ',Cmd1,^M'1234567',TRUE,TRUE); + IF (Cmd1 <> ^M) THEN + BEGIN + IF ((StrToInt(Cmd1) - 1) IN EventDays) THEN + Exclude(EventDays,(StrToInt(Cmd1) - 1)) + ELSE + Include(EventDays,(StrToInt(Cmd1) - 1)); + Changed := TRUE; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + Cmd1 := #0; + END; + 'M' : BEGIN + IF (NOT (EventIsMonthly IN EFlags)) THEN + BEGIN + Include(EFlags,EventIsMonthly); + EventDays := []; + Changed := TRUE; + END; + InputByteWC('%LFDay of the month',EventDayOfMonth,[],1,31,Changed); + END; + END; + Cmd1 := #0; + END; + 'E' : IF (EventIsExternal IN EFlags) THEN + BEGIN + Print('%LF^5External event type'); + NL; + LCmds(18,3,'1Errorlevel',''); + LCmds(18,3,'2Shell',''); + LCmds(18,3,'3Sort Files',''); + LCmds(18,3,'4Pack Message Areas',''); + LCmds(18,3,'5Files.BBS',''); + LOneK('%LFWhich external event? [^51^4-^55^4,^5^4=^5Quit^4]: ',Cmd1,^M'12345',TRUE,TRUE); + IF (Cmd1 <> ^M) THEN + BEGIN + CASE Cmd1 OF + '1' : BEGIN + IF (EventIsShell IN EFlags) THEN + BEGIN + Exclude(EFlags,EventIsShell); + EventShellPath := ''; + END; + IF (EventIsSortFiles IN EFlags) THEN + Exclude(EFlags,EventIsSortFiles); + IF (EventIsPackMsgAreas IN EFlags) THEN + Exclude(EFlags,EventIsPackMsgAreas); + IF (EventIsFilesBBS IN EFlags) THEN + Exclude(EFlags,EventIsFilesBBS); + Include(EFlags,EventIsErrorLevel); + InputByteWC('%LFError Level',EventErrorLevel,[],0,255,Changed); + END; + '2' : BEGIN + IF (EventIsErrorLevel IN EFlags) THEN + BEGIN + Exclude(EFlags,EventIsErrorLevel); + EventErrorLevel := 0; + END; + IF (EventIsSortFiles IN EFlags) THEN + Exclude(EFlags,EventIsSortFiles); + IF (EventIsPackMsgAreas IN EFlags) THEN + Exclude(EFlags,EventIsPackMsgAreas); + IF (EventIsFilesBBS IN EFlags) THEN + Exclude(EFlags,EventIsFilesBBS); + Include(EFlags,EventIsShell); + InputWN1('%LFShell file: ',EventShellPath,8,[UpperOnly],Changed); + END; + '3' : BEGIN + IF (EventIsShell IN EFlags) THEN + BEGIN + Exclude(EFlags,EventIsShell); + EventShellPath := ''; + END; + IF (EventIsErrorLevel IN EFlags) THEN + BEGIN + Exclude(EFlags,EventIsErrorLevel); + EventErrorLevel := 0; + END; + IF (EventIsPackMsgAreas IN EFlags) THEN + Exclude(EFlags,EventIsPackMsgAreas); + IF (EventIsFilesBBS IN EFlags) THEN + Exclude(EFlags,EventIsFilesBBS); + Include(EFlags,EventIsSortFiles); + END; + '4' : BEGIN + IF (EventIsShell IN EFlags) THEN + BEGIN + Exclude(EFlags,EventIsShell); + EventShellPath := ''; + END; + IF (EventIsErrorLevel IN EFlags) THEN + BEGIN + Exclude(EFlags,EventIsErrorLevel); + EventErrorLevel := 0; + END; + IF (EventIsSortFiles IN EFlags) THEN + Exclude(EFlags,EventIsSortFiles); + IF (EventIsFilesBBS IN EFlags) THEN + Exclude(EFlags,EventIsFilesBBS); + Include(EFlags,EventIsPackMsgAreas); + END; + '5' : BEGIN + IF (EventIsShell IN EFlags) THEN + BEGIN + Exclude(EFlags,EventIsShell); + EventShellPath := ''; + END; + IF (EventIsErrorLevel IN EFlags) THEN + BEGIN + Exclude(EFlags,EventIsErrorLevel); + EventErrorLevel := 0; + END; + IF (EventIsSortFiles IN EFlags) THEN + Exclude(EFlags,EventIsSortFiles); + IF (EventIsPackMsgAreas IN EFlags) THEN + Exclude(EFlags,EventIsPackMsgAreas); + Include(EFlags,EventIsFilesBBS); + END; + END; + Changed := TRUE; + END; + Cmd1 := #0; + END + ELSE + BEGIN + Prt('%LFNew event start time? (24 Hour Format) Hour: (0-23), Minute: (0-59): '); + InputFormatted('',TempStr,'##:##',TRUE); + IF (TempStr <> '') AND (Length(TempStr) = 5) AND (Pos(':',TempStr) = 3) THEN + BEGIN + IF (StrToInt(Copy(TempStr,1,2)) IN [0..23]) AND (StrToInt(Copy(TempStr,4,2)) IN [0..59]) THEN + BEGIN + EventStartTime := ((StrToInt(Copy(TempStr,1,2)) * 60) + StrToInt(Copy(TempStr,4,2))); + Changed := TRUE; + END + ELSE + BEGIN + Print('%LF^5Invalid time - Format is HH:MM (24 hour military)'); + PauseScr(FALSE); + END; + END; + Prt('%LFNew event finish time? (24 Hour Format) Hour: (0-23), Minute: (0-59): '); + InputFormatted('',TempStr,'##:##',TRUE); + IF (TempStr <> '') AND (Length(TempStr) = 5) AND (Pos(':',TempStr) = 3) THEN + BEGIN + IF (StrToInt(Copy(TempStr,1,2)) IN [0..23]) AND (StrToInt(Copy(TempStr,4,2)) IN [0..59]) THEN + BEGIN + EventFinishTime := ((StrToInt(Copy(TempStr,1,2)) * 60) + StrToInt(Copy(TempStr,4,2))); + Changed := TRUE; + END + ELSE + BEGIN + Print('%LF^5Invalid time - Format is HH:MM (24 hour military)'); + PauseScr(FALSE); + END; + END; + END; + 'G' : IF (EventIsExternal IN EFlags) THEN + BEGIN + LOneK('%LFSchedule? [^5D^4=^5Daily^4,^5M^4=^5Monthly^4,^5^4=^5Quit^4]: ',Cmd1,^M'DM',TRUE,TRUE); + CASE Cmd1 OF + 'D' : BEGIN + IF (EventIsMonthly IN EFlags) THEN + BEGIN + Exclude(EFlags,EventIsMonthly); + EventDayOfMonth := 0; + Changed := TRUE; + END; + REPEAT + Print('%LF^5Active Days: ^3'+DaysEventActive(EventDays,'5','4')+'^1'); + NL; + LCmds(11,3,'1Sunday',''); + LCmds(11,3,'2Monday',''); + LCmds(11,3,'3Tuesday',''); + LCmds(11,3,'4Wednesday',''); + LCmds(11,3,'5Thursday',''); + LCmds(11,3,'6Friday',''); + LCmds(11,3,'7Saturday',''); + LOneK('%LFToggle which day? [^51^4-^57^4,^5^4=^5Quit^4]: ',Cmd1,^M'1234567',TRUE,TRUE); + IF (Cmd1 <> ^M) THEN + BEGIN + IF (StrToInt(Cmd1) - 1 IN EventDays) THEN + Exclude(EventDays,StrToInt(Cmd1) - 1) + ELSE + Include(EventDays,StrToInt(Cmd1) - 1); + Changed := TRUE; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + Cmd1 := #0; + END; + 'M' : BEGIN + IF (NOT (EventIsMonthly IN EFlags)) THEN + BEGIN + Include(EFlags,EventIsMonthly); + EventDays := []; + Changed := TRUE; + END; + InputByteWC('%LFDay of the month',EventDayOfMonth,[],1,31,Changed); + END; + END; + Cmd1 := #0; + END + ELSE + BEGIN + ToggleEFlag(EventIsPermission,EFlags); + Changed := TRUE; + END; + 'H' : IF (EventIsExternal IN EFlags) THEN + BEGIN + Prt('%LFNew event start time? (24 Hour Format) Hour: (0-23), Minute: (0-59): '); + InputFormatted('',TempStr,'##:##',TRUE); + IF (TempStr <> '') AND (Length(TempStr) = 5) AND (Pos(':',TempStr) = 3) THEN + BEGIN + IF (StrToInt(Copy(TempStr,1,2)) IN [0..23]) AND (StrToInt(Copy(TempStr,4,2)) IN [0..59]) THEN + BEGIN + EventStartTime := ((StrToInt(Copy(TempStr,1,2)) * 60) + StrToInt(Copy(TempStr,4,2))); + Changed := TRUE; + END + ELSE + BEGIN + Print('%LF^5Invalid time - Format is HH:MM (24 hour military)'); + PauseScr(FALSE); + END; + END; + END + ELSE + BEGIN + Print('%LF^5Internal event type:'); + NL; + LCmds(7,3,'1Logon',''); + LCmds(7,3,'2Chat',''); + LOneK('%LFWhich internal event? [^51^4-^52^4,^5^4=^5Quit^4]: ',Cmd1,^M'12',TRUE,TRUE); + IF (Cmd1 <> ^M) THEN + BEGIN + CASE Cmd1 OF + '1' : BEGIN + IF (EventIsChat IN EFlags) THEN + Exclude(EFlags,EventIsChat); + Include(EFlags,EventIsLogon); + END; + '2' : BEGIN + IF (EventIsLogon IN EFlags) THEN + Exclude(EFlags,EventIsLogon); + Include(EFlags,EventIsChat); + END; + END; + Changed := TRUE; + END; + Cmd1 := #0; + END; + 'I' : IF (EventIsExternal IN EFlags) THEN + BEGIN + IF (EventIsOffHook IN EFlags) THEN + BEGIN + Exclude(EFlags,EventIsOffHook); + EventPreTime := 0; + Changed := TRUE; + END + ELSE + BEGIN + Include(EFlags,EventIsOffHook); + InputByteWC('%LFMinutes before event to take phone offhook',EventPreTime,[],0,255,Changed); + END; + END + ELSE + InputWN1('%LF^1Message/@File if the user is effected by the event:%LF^4: ',EventQualMsg,64,[],Changed); + 'K' : IF (EventIsExternal IN EFlags) THEN + BEGIN + IF (PD2Date(EventLastDate) = DateStr) THEN + EventLastDate := NextDay(PD2Date(EventLastDate)) + ELSE + EventLastDate := Date2PD(DateStr); + Changed := TRUE; + END + ELSE + InputWN1('%LF^1Message/@File if the user IS NOT effected by the event:%LF^4: ', + EventNotQualMsg,64,[],Changed); + 'M' : BEGIN + IF PYNQ('%LFRun this event later if the event time is missed? ',0,FALSE) THEN + Include(EFlags,EventIsMissed) + ELSE + Exclude(EFlags,EventIsMissed); + Changed := TRUE; + END; + 'N' : InputByteWC('%LFNode number to execute event from (0=All)',EventNode, + [DisplayValue,NumbersOnly],0,MaxNodes,Changed); + '1' : IF (NOT (EventIsExternal IN EFlags)) THEN + IF (BaudIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,BaudIsActive); + LoBaud := 300; + HiBaud := 115200; + Changed := TRUE; + END + ELSE + BEGIN + Include(EFlags,BaudIsActive); + Print('%LF^5Baud lower limit:^1%LF'); + Counter := 1; + WHILE (Counter <= 20) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + PrintACR(Char(Counter + 64)+'. '+IntToStr(BaudRates[Counter])); + Inc(Counter); + END; + LOneK('%LFWhich? (^5A^4-^5T^4): ',Cmd1,'ABCDEFGHIJKLMNOPQRST',TRUE,TRUE); + LoBaud := BaudRates[Ord(Cmd1) - 64]; + Print('%LF^5Baud upper limit:^1%LF'); + Counter := 1; + WHILE (Counter <= 20) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + PrintACR(Char(Counter + 64)+'. '+IntToStr(BaudRates[Counter])); + Inc(Counter); + END; + LOneK('%LFWhich? (^5A^4-^5T^4): ',Cmd1,'ABCDEFGHIJKLMNOPQRST',TRUE,TRUE); + HiBaud := BaudRates[Ord(Cmd1) - 64]; + Changed := TRUE; + Cmd1 := #0; + END; + '2' : IF (NOT (EventIsExternal IN EFlags)) THEN + IF (ACSIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,ACSIsActive); + EventACS := 's10'; + Changed := TRUE; + END + ELSE + BEGIN + Include(EFlags,ACSIsActive); + InputWN1('%LFSL ACS: ',EventACS,(SizeOf(EventACS) - 1),[InterActiveEdit],Changed); + END; + '3' : IF (NOT (EventIsExternal IN EFlags)) THEN + IF (EventIsPermission IN EFlags) THEN + BEGIN + IF (TimeIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,TimeIsActive); + MaxTimeAllowed := 60; + Changed := TRUE; + END + ELSE + BEGIN + Include(EFlags,TimeIsActive); + InputWordWoc('%LFMaximum time allowed on-line (minutes)',MaxTimeAllowed, + [DisplayValue,NumbersOnly],0,65535); + END; + END; + '4' : IF NOT (EventIsExternal IN EFlags) THEN + IF (EventIsPermission IN EFlags) THEN + BEGIN + IF (SetArIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,SetArIsActive); + SetArFlag := '@'; + Changed := TRUE; + END + ELSE + BEGIN + Include(EFlags,SetArIsActive); + LOneK('%LFAR flag to set (^5A^4-^5Z^4): ',Cmd1,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',TRUE,TRUE); + SetArFlag := Cmd1; + Cmd1 := #0; + END; + END; + '5' : IF NOT (EventIsExternal IN EFlags) THEN + IF (EventIsPermission IN EFlags) THEN + BEGIN + IF (ClearArIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,ClearArIsActive); + ClearArFlag := '@'; + Changed := TRUE; + END + ELSE + BEGIN + Include(EFlags,ClearArIsActive); + LOneK('%LFAR flag to clear (^5A^4-^5Z^4): ',Cmd1,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',TRUE,TRUE); + ClearArFlag := Cmd1; + Cmd1 := #0; + END; + END; + '6' : IF (NOT (EventIsExternal IN EFlags)) THEN + ToggleEFlags('S',EFlags,Changed); + '[' : IF (RecNumToEdit > 1) THEN + Dec(RecNumToEdit) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + ']' : IF (RecNumToEdit < NumEvents) THEN + Inc(RecNumToEdit) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNumToEdit <> 1) THEN + RecNumToEdit := 1 + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + InputIntegerWOC('%LFJump to entry?',RecNumToEdit,[NumbersOnly],1,NumEvents); + IF (RecNumToEdit < 1) OR (RecNumToEdit > NumEvents) THEN + Cmd1 := #0; + END; + 'L' : IF (RecNumToEdit <> NumEvents) THEN + RecNumToEdit := NumEvents + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay screen'); + Print('^3 0) OR (HangUp); + END; + + PROCEDURE InsertEvent(TempEvent1: EventRecordType; Cmd1: Char; RecNumToInsertBefore: SmallInt); + VAR + RecNum, + RecNumToEdit: SmallInt; + Ok, + Changed: Boolean; + BEGIN + IF (NumEvents = MaxEvents) THEN + Messages(5,MaxEvents,'events') + ELSE + BEGIN + RecNumToInsertBefore := -1; + InputIntegerWOC('%LFEvent to insert before?',RecNumToInsertBefore,[NumbersOnly],1,(NumEvents + 1)); + IF (RecNumToInsertBefore >= 1) AND (RecNumToInsertBefore <= (NumEvents + 1)) THEN + BEGIN + Reset(EventFile); + InitEventVars(TempEvent1); + IF (RecNumToInsertBefore = 1) THEN + RecNumToEdit := 1 + ELSE IF (RecNumToInsertBefore = (NumEvents + 1)) THEN + RecNumToEdit := (NumEvents + 1) + ELSE + RecNumToEdit := RecNumToInsertBefore; + REPEAT + OK := TRUE; + EditEvent(TempEvent1,TempEvent1,Cmd1,RecNumToEdit,Changed,FALSE); + CheckEvent(TempEvent1,1,1,Ok); + IF (NOT OK) THEN + IF (NOT PYNQ('%LFContinue inserting event? ',0,TRUE)) THEN + Abort := TRUE; + UNTIL (OK) OR (Abort) OR (HangUp); + IF (NOT Abort) AND (PYNQ('%LFIs this what you want? ',0,FALSE)) THEN + BEGIN + Print('%LF[> Inserting event record ...'); + Seek(EventFile,FileSize(EventFile)); + Write(EventFile,Event); + Dec(RecNumToInsertBefore); + FOR RecNum := ((FileSize(EventFile) - 1) - 1) DOWNTO RecNumToInsertBefore DO + BEGIN + Seek(EventFile,RecNum); + Read(EventFile,Event); + Seek(EventFile,(RecNum + 1)); + Write(EventFile,Event); + END; + FOR RecNum := RecNumToInsertBefore TO ((RecNumToInsertBefore + 1) - 1) DO + BEGIN + Seek(EventFile,RecNum); + Write(EventFile,TempEvent1); + Inc(NumEvents); + SysOpLog('* Inserted event: ^5'+TempEvent1.EventDescription); + END; + END; + Close(EventFile); + LastError := IOResult; + END; + END; + END; + + PROCEDURE ModifyEvent(TempEvent1: EventRecordType; Cmd1: Char; RecNumToEdit: SmallInt); + VAR + SaveRecNumToEdit: Integer; + Ok, + Changed: Boolean; + BEGIN + IF (NumEvents = 0) THEN + Messages(4,0,'events') + ELSE + BEGIN + RecNumToEdit := -1; + InputIntegerWOC('%LFModify which event?',RecNumToEdit,[NumbersOnly],1,NumEvents); + IF (RecNumToEdit >= 1) AND (RecNumToEdit <= NumEvents) THEN + BEGIN + SaveRecNumToEdit := -1; + Cmd1 := #0; + Reset(EventFile); + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNumToEdit <> RecNumToEdit) THEN + BEGIN + Seek(EventFile,(RecNumToEdit - 1)); + Read(EventFile,Event); + SaveRecNumToEdit := RecNumToEdit; + Changed := FALSE; + END; + REPEAT + Ok := TRUE; + EditEvent(TempEvent1,Event,Cmd1,RecNumToEdit,Changed,TRUE); + CheckEvent(Event,1,1,Ok); + IF (NOT OK) THEN + BEGIN + PauseScr(FALSE); + IF (RecNumToEdit <> SaveRecNumToEdit) THEN + RecNumToEdit := SaveRecNumToEdit; + END; + UNTIL (Ok) OR (HangUp); + IF (Changed) THEN + BEGIN + Seek(EventFile,(SaveRecNumToEdit - 1)); + Write(EventFile,Event); + Changed := FALSE; + SysOpLog('* Modified event: ^5'+Event.EventDescription); + END; + END; + Close(EventFile); + LastError := IOResult; + END; + END; + END; + + PROCEDURE PositionEvent(TempEvent1: EventRecordType; RecNumToPosition: SmallInt); + VAR + RecNumToPositionBefore, + RecNum1, + RecNum2: SmallInt; + BEGIN + IF (NumEvents = 0) THEN + Messages(4,0,'events') + ELSE IF (NumEvents = 1) THEN + Messages(6,0,'events') + ELSE + BEGIN + InputIntegerWOC('%LFPosition which event?',RecNumToPosition,[NumbersOnly],1,NumEvents); + IF (RecNumToPosition >= 1) AND (RecNumToPosition <= NumEvents) THEN + BEGIN + Print('%LFAccording to the current numbering system.'); + InputIntegerWOC('%LFPosition before which event?',RecNumToPositionBefore,[Numbersonly],1,(NumEvents + 1)); + IF (RecNumToPositionBefore >= 1) AND (RecNumToPositionBefore <= (NumEvents + 1)) AND + (RecNumToPositionBefore <> RecNumToPosition) AND (RecNumToPositionBefore <> (RecNumToPosition + 1)) THEN + BEGIN + Print('%LF[> Positioning event.'); + Reset(EventFile); + IF (RecNumToPositionBefore > RecNumToPosition) THEN + Dec(RecNumToPositionBefore); + Dec(RecNumToPosition); + Dec(RecNumToPositionBefore); + Seek(EventFile,RecNumToPosition); + Read(EventFile,TempEvent1); + RecNum1 := RecNumToPosition; + IF (RecNumToPosition > RecNumToPositionBefore) THEN + RecNum2 := -1 + ELSE + RecNum2 := 1; + WHILE (RecNum1 <> RecNumToPositionBefore) DO + BEGIN + IF ((RecNum1 + RecNum2) < FileSize(EventFile)) THEN + BEGIN + Seek(EventFile,(RecNum1 + RecNum2)); + Read(EventFile,Event); + Seek(EventFile,RecNum1); + Write(EventFile,Event); + END; + Inc(RecNum1,RecNum2); + END; + Seek(EventFile,RecNumToPositionBefore); + Write(EventFile,TempEvent1); + Close(EventFile); + LastError := IOResult; + END; + END; + END; + END; + + PROCEDURE ListEvents(VAR RecNumToList1: Integer); + VAR + NumDone: Integer; + BEGIN + IF (RecNumToList1 < 1) OR (RecNumToList1 > NumFileAreas) THEN + RecNumToList1 := 1; + Abort := FALSE; + Next := FALSE; + CLS; + PrintACR('^0 ##^4:^3Description ^4:^3Typ^4:^3Bsy^4:^3Time ^4:^3Len^4:^3Days ^4:^3Execinfo'); + PrintACR('^4 ==:==============================:===:===:=====:===:=======:============'); + Reset(EventFile); + NumDone := 0; + WHILE (NumDone < (PageLength - 5)) AND (RecNumToList1 >= 1) AND (RecNumToList1 <= NumEvents) + AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(EventFile,(RecNumToList1 - 1)); + Read(EventFile,Event); + WITH Event DO + PrintACR(AOnOff(EventIsActive IN EFlags,'^5+','^1-')+ + '^0'+PadRightInt(RecNumToList1,2)+ + ' ^3'+PadLeftStr(EventDescription,30)+ + (* + ' '+SchedT(FALSE,EType)+ + *) + ' ^5'+PadLeftInt(EventPreTime,3)+ + ' '+Copy(CTim(EventStartTime),4,5)); + (* + ' '+PadLeftInt(DurationOrLastDay,3)+ + ' '+DActiv(FALSE,ExecDays,Monthly)+ + ' ^3'+PadLeftStr(lExecData,9)); + *) + Inc(RecNumToList1); + Inc(NumDone); + END; + Close(EventFile); + LastError := IOResult; + IF (NumEvents = 0) THEN + Print('*** No events defined ***'); + END; + + +BEGIN + IF (MemEventArray[Numevents] <> NIL) THEN + FOR RecNumToList := 1 TO NumEvents DO + IF (MemEventArray[RecNumToList] <> NIL) THEN + Dispose(MemEventArray[RecNumToList]); + SaveTempPause := TempPause; + TempPause := FALSE; + RecNumToList := 1; + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + ListEvents(RecNumToList); + LOneK('%LFEvent editor [^5?^4=^5Help^4]: ',Cmd,'QDIMP?'^M,TRUE,TRUE); + CASE Cmd OF + ^M : IF (RecNumToList < 1) OR (RecNumToList > NumEvents) THEN + RecNumToList := 1; + 'D' : DeleteEvent(TempEvent,RecNumToList); + 'I' : InsertEvent(TempEvent,Cmd,RecNumToList); + 'M' : ModifyEvent(TempEvent,Cmd,RecNumToList); + 'P' : PositionEvent(TempEvent,RecNumToList); + '?' : BEGIN + Print('%LF^1<^3CR^1>Next screen or redisplay current screen'); + Print('^1(^3?^1)Help/First event'); + LCmds(13,3,'Delete event','Insert event'); + LCmds(13,3,'Modify event','Position event'); + LCmds(13,3,'Quit',''); + END; + END; + IF (Cmd <> ^M) THEN + RecNumToList := 1; + UNTIL (Cmd = 'Q') OR (HangUp); + TempPause := SaveTempPause; + NumEvents := 0; + Reset(EventFile); + WHILE NOT EOF(EventFile) DO + BEGIN + Inc(NumEvents); + New(MemEventArray[NumEvents]); + Read(EventFile,MemEventArray[NumEvents]^); + END; + Close(EventFile); + LastError := IOResult; +END; + +END. diff --git a/SOURCE/SYSOP7.PAS b/SOURCE/SYSOP7.PAS new file mode 100644 index 0000000..2c9cd55 --- /dev/null +++ b/SOURCE/SYSOP7.PAS @@ -0,0 +1,665 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B+,D+,E+,F+,I+,L+,N-,O+,R-,S+,V-} +UNIT SysOp7; + +INTERFACE + +USES + Common; + +PROCEDURE FindMenu(DisplayStr: AStr; + VAR MenuNum: Byte; + LowMenuNum, + HighMenuNum: Byte; + VAR Changed: Boolean); +PROCEDURE MenuEditor; + +IMPLEMENTATION + +USES + Common5, + Menus2, + SysOp7M; + +PROCEDURE DisplayMenus(VAR RecNumToList1: Integer; DisplayListNum: Boolean); +VAR + NumDone: Byte; +BEGIN + Abort := FALSE; + Next := FALSE; + AllowContinue := TRUE; + MCIAllowed := FALSE; + CLS; + IF (DisplayListNum) THEN + BEGIN + PrintACR('^0###^4:^3Menu #^4:^3Menu name'); + PrintACR('^4===:======:===================================================================='); + END + ELSE + BEGIN + PrintACR('^0Menu #^4:^3Menu name'); + PrintACR('^4======:===================================================================='); + END; + Reset(MenuFile); + NumDone := 0; + WHILE (NumDone < (PageLength - 7)) AND (RecNumToList1 >= 1) AND (RecNumToList1 <= NumMenus) + AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(MenuFile,MenuRecNumArray[RecNumToList1]); + Read(MenuFile,MenuR); + WITH MenuR DO + BEGIN + IF (DisplayListNum) THEN + PrintACR('^0'+PadRightInt(RecNumToList1,3)+ + ' ^5'+PadRightInt(MenuNum,6)+ + ' ^3'+PadLeftStr(LDesc[1],68)) + ELSE + PrintACR('^5'+PadRightInt(MenuNum,6)+ + ' ^3'+PadLeftStr(LDesc[1],68)); + END; + Inc(RecNumToList1); + Inc(NumDone); + END; + Close(MenuFile); + LastError := IOResult; + MCIAllowed := TRUE; + AllowContinue := FALSE; + IF (NumMenus = 0) THEN + Print('*** No menus defined ***'); + IF (DisplayListNum) THEN + PrintACR('%LF^1[Users start at menu number: ^5'+IntToStr(General.AllStartMenu)+'^1]'); +END; + +PROCEDURE FindMenu(DisplayStr: AStr; + VAR MenuNum: Byte; + LowMenuNum, + HighMenuNum: Byte; + VAR Changed: Boolean); +VAR + TempMenuR: MenuRec; + InputStr: AStr; + SaveMenuNum: Byte; + RecNum, + RecNum1, + RecNumToList: Integer; +BEGIN + SaveMenuNum := MenuNum; + RecNumToList := 1; + InputStr := '?'; + REPEAT + IF (InputStr = '?') THEN + DisplayMenus(RecNumToList,FALSE); + Prt(DisplayStr+' (^5'+IntToStr(LowMenuNum)+'^4-^5'+IntToStr(HighMenuNum)+'^4)'+ + ' [^5?^4=^5First^4,^5^4=^5Next^4,^5Q^4=^5Quit^4): '); + MPL(Length(IntToStr(NumMenus))); + ScanInput(InputStr,'Q?'^M); + IF (InputStr = '-') THEN + InputStr := 'Q'; + IF (InputStr <> 'Q') THEN + BEGIN + IF (InputStr = ^M) THEN + BEGIN + InputStr := '?'; + IF (RecNumToList < 1) OR (RecNumToList > NumMenus) THEN + RecNumToList := 1 + END + ELSE IF (InputStr = '?') THEN + RecNumToList := 1 + ELSE IF (StrToInt(InputStr) < LowMenuNum) OR (StrToInt(InputStr) > HighMenuNum) THEN + Print('%LF^7The range must be from '+IntToStr(LowMenuNum)+' to '+IntToStr(HighMenuNum)+'!^1') + ELSE IF (InputStr = '0') AND (LowMenuNum = 0) THEN + BEGIN + MenuNum := StrToInt(InputStr); + InputStr := 'Q'; + Changed := TRUE; + END + ELSE + BEGIN + RecNum1 := -1; + RecNum := 1; + + Reset(MenuFile); + + WHILE (RecNum <= NumMenus) AND (RecNum1 = -1) DO + BEGIN + Seek(MenuFile,MenuRecNumArray[RecNum]); + Read(MenuFile,TempMenuR); + IF (StrToInt(InputStr) = TempMenuR.MenuNum) THEN + RecNum1 := TempMenuR.MenuNum; + Inc(RecNum); + END; + + Close(MenuFile); + + IF (RecNum1 = -1) THEN + BEGIN + RGNoteStr(2,FALSE); + MenuNum := SaveMenuNum; + END + ELSE + BEGIN + MenuNum := StrToInt(InputStr); + InputStr := 'Q'; + Changed := TRUE; + END; + END; + END; + UNTIL (InputStr = 'Q') OR (HangUp); +END; + +PROCEDURE MenuEditor; +VAR + Cmd: Char; + SaveCurMenu: Byte; + RecNumToList: Integer; + SaveTempPause: Boolean; + + FUNCTION DisplayMenuFlags(MenuFlags: MenuFlagSet; C1,C2: Char): AStr; + VAR + MenuFlagT: MenuFlagType; + TempS: AStr; + BEGIN + TempS := ''; + FOR MenuFlagT := ClrScrBefore TO NoGlobalUsed DO + IF (MenuFlagT IN MenuFlags) THEN + TempS := TempS + '^'+C1+Copy('CDTNPAF12345',(Ord(MenuFlagT) + 1),1) + ELSE + TempS := TempS + '^'+C2+'-'; + DisplayMenuFlags := TempS; + END; + + PROCEDURE ToggleMenuFlag(MenuFlagT: MenuFlagType; VAR MenuFlags: MenuFlagSet); + BEGIN + IF (MenuFlagT IN MenuFlags) THEN + Exclude(MenuFlags,MenuFlagT) + ELSE + Include(MenuFlags,MenuFlagT); + END; + + PROCEDURE ToggleMenuFlags(C: Char; VAR MenuFlags: MenuFlagSet; VAR Changed: Boolean); + VAR + TempMenuFlags: MenuFlagSet; + BEGIN + TempMenuFlags := MenuFlags; + CASE C OF + 'C' : ToggleMenuFlag(ClrScrBefore,MenuFlags); + 'D' : ToggleMenuFlag(DontCenter,MenuFlags); + 'T' : ToggleMenuFlag(NoMenuTitle,MenuFlags); + 'N' : ToggleMenuFlag(NoMenuPrompt,MenuFlags); + 'P' : ToggleMenuFlag(ForcePause,MenuFlags); + 'A' : ToggleMenuFlag(AutoTime,MenuFlags); + 'F' : ToggleMenuFlag(ForceLine,MenuFlags); + '1' : ToggleMenuFlag(NoGenericAnsi,MenuFlags); + '2' : ToggleMenuFlag(NoGenericAvatar,MenuFlags); + '3' : ToggleMenuFlag(NoGenericRIP,MenuFlags); + '4' : ToggleMenuFlag(NoGlobalDisplayed,MenuFlags); + '5' : ToggleMenuFlag(NoGlobalUsed,MenuFlags); + END; + IF (MenuFlags <> TempMenuFlags) THEN + Changed := TRUE; + END; + + PROCEDURE InitMenuVars(VAR MenuR: MenuRec); + BEGIN + FillChar(MenuR,SizeOf(MenuR),0); + WITH MenuR DO + BEGIN + LDesc[1] := '<< New Menu >>'; + LDesc[2] := ''; + LDesc[3] := ''; + ACS := ''; + NodeActivityDesc := ''; + Menu := TRUE; + MenuFlags := [AutoTime]; + LongMenu := ''; + MenuNum := 0; + MenuPrompt := 'Command? '; + Password := ''; + FallBack := 0; + Directive := ''; + ForceHelpLevel := 0; + GenCols := 4; + GCol[1] := 4; + GCol[2] := 3; + GCol[3] := 5; + END; + END; + + PROCEDURE DeleteMenu; + VAR + RecNumToDelete, + RecNum: SmallInt; + DeleteOk: Boolean; + BEGIN + IF (NumMenus = 0) THEN + Messages(4,0,'menus') + ELSE + BEGIN + RecNumToDelete := -1; + InputIntegerWOC('%LFMenu number to delete?',RecNumToDelete,[NumbersOnly],1,NumMenus); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= NumMenus) THEN + BEGIN + Reset(MenuFile); + Seek(MenuFile,MenuRecNumArray[RecNumToDelete]); + Read(MenuFile,MenuR); + Close(MenuFile); + LastError := IOResult; + DeleteOK := TRUE; + IF (MenuR.MenuNum = General.AllStartMenu) THEN + BEGIN + Print('%LFYou can not delete the menu new users start at.'); + DeleteOK := FALSE; + END + ELSE IF (MenuR.MenuNum = General.NewUserInformationMenu) THEN + BEGIN + Print('%LFYou can not delete the new user information menu.'); + DeleteOK := FALSE; + END + ELSE IF (MenuR.MenuNum = General.FileListingMenu) THEN + BEGIN + Print('%LFYou can not delete the file listing menu.'); + DeleteOK := FALSE; + END + ELSE IF (MenuR.MenuNum = General.MessageReadMenu) THEN + BEGIN + Print('%LFYou can not delete the message read menu.'); + DeleteOK := FALSE; + END + ELSE IF (CmdNumArray[RecNumToDelete] <> 0) THEN + BEGIN + Print('%LFThis menu is not empty.'); + DeleteOK := FALSE; + END; + IF (NOT DeleteOK) THEN + PauseScr(FALSE) + ELSE + BEGIN + Print('%LFMenu: ^5'+MenuR.LDesc[1]); + IF PYNQ('%LFAre you sure you want to delete it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Deleting menu record ...'); + SysOpLog('* Deleted menu: ^5'+MenuR.LDesc[1]); + RecNumToDelete := MenuRecNumArray[RecNumToDelete]; { Convert To Real Record Number } + Reset(MenuFile); + IF (RecNumToDelete >= 0) AND (RecNumToDelete <= (FileSize(MenuFile) - 2)) THEN + FOR RecNum := RecNumToDelete TO (FileSize(MenuFile) - 2) DO + BEGIN + Seek(MenuFile,(RecNum + 1)); + Read(MenuFile,MenuR); + Seek(MenuFile,RecNum); + Write(MenuFile,MenuR); + END; + Seek(MenuFile,(FileSize(MenuFile) - 1)); + Truncate(MenuFile); + LoadMenuPointers; + Close(MenuFile); + LastError := IOResult; + END; + END; + END; + END; + END; + + PROCEDURE InsertMenu; + VAR + RecNumToInsertBefore, + NewMenuNum, + RecNum: SmallInt; + BEGIN + IF (NumMenus = MaxMenus) THEN + Messages(5,MaxMenus,'menus') + ELSE + BEGIN + RecNumToInsertBefore := -1; + InputIntegerWOC('%LFMenu number to insert before?',RecNumToInsertBefore,[NumbersOnly],1,(NumMenus + 1)); + IF (RecNumToInsertBefore >= 1) AND (RecNumToInsertBefore <= (NumMenus + 1)) THEN + BEGIN + Print('%LF[> Inserting menu record ...'); + SysOpLog('* Inserted 1 menu.'); + IF (RecNumToInsertBefore = (NumMenus + 1)) THEN + MenuRecNumArray[RecNumToInsertBefore] := (MenuRecNumArray[NumMenus] + CmdNumArray[NumMenus] + 1); + RecNumToInsertBefore := MenuRecNumArray[RecNumToInsertBefore]; {Convert To Real Record Number } + NewMenuNum := 0; + Reset(MenuFile); + RecNum := 1; + WHILE (RecNum <= NumMenus) DO + BEGIN + Seek(MenuFile,MenuRecNumArray[RecNum]); + Read(MenuFile,MenuR); + IF (MenuR.MenuNum > NewMenuNum) THEN + NewMenuNum := MenuR.MenuNum; + Inc(RecNum); + END; + FOR RecNum := 1 TO 1 DO + BEGIN + Seek(MenuFile,FileSize(MenuFile)); + Write(MenuFile,MenuR); + END; + FOR RecNum := ((FileSize(MenuFile) - 1) - 1) DOWNTO RecNumToInsertBefore DO + BEGIN + Seek(MenuFile,RecNum); + Read(MenuFile,MenuR); + Seek(MenuFile,(RecNum + 1)); + Write(MenuFile,MenuR); + END; + InitMenuVars(MenuR); + FOR RecNum := RecNumToInsertBefore TO ((RecNumToInsertBefore + 1) - 1) DO + BEGIN + Seek(MenuFile,RecNum); + MenuR.MenuNum := (NewMenuNum + 1); + Write(MenuFile,MenuR); + END; + LoadMenuPointers; + Close(MenuFile); + LastError := IOResult; + END; + END; + END; + + PROCEDURE ModifyMenu; + VAR + TempMenuR: MenuRec; + Cmd1: Char; + SaveMenuNum: Byte; + RecNum, + RecNum1, + RecNumToModify, + SaveRecNumToModify: SmallInt; + Changed: Boolean; + BEGIN + IF (NumMenus = 0) THEN + Messages(4,0,'menus') + ELSE + BEGIN + RecNumToModify := -1; + InputIntegerWOC('%LFMenu number to modify?',RecNumToModify,[NumbersOnly],1,NumMenus); + IF (RecNumToModify >= 1) AND (RecNumToModify <= NumMenus) THEN + BEGIN + SaveRecNumToModify := -1; + Cmd1 := #0; + Reset(MenuFile); + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNumToModify <> RecNumToModify) THEN + BEGIN + Seek(MenuFile,MenuRecNumArray[RecNumToModify]); + Read(MenuFile,MenuR); + SaveRecNumToModify := RecNumToModify; + Changed := FALSE; + END; + WITH MenuR DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + MCIAllowed := FALSE; + CLS; + PrintACR('^5Menu #'+IntToStr(RecNumToModify)+' of '+IntToStr(NumMenus)); + NL; + PrintACR('^11. Menu number : ^5'+IntToStr(MenuNum)); + PrintACR('^12. Menu titles : ^5'+LDesc[1]); + IF (LDesc[2] <> '') THEN + PrintACR('^1 Menu title #2 : ^5'+LDesc[2]); + IF (LDesc[3] <> '') THEN + PrintACR('^1 Menu title #3 : ^5'+LDesc[3]); + PrintACR('^13. Help files : ^5'+AOnOff((Directive = ''),'*Generic*',Directive)+'/'+ + AOnOff((LongMenu = ''),'*Generic*',LongMenu)); + PrintACR('^14. Menu prompt : ^5'+MenuPrompt); + PrintACR('^15. ACS required : ^5"'+ACS+'"'); + PrintACR('^16. Password : ^5'+AOnOff((Password = ''),'*None*',Password)); + PrintACR('^17. Fallback menu : ^5'+IntToStr(FallBack)); + PrintACR('^18. Forced ?-level: ^5'+AOnOff((ForceHelpLevel=0),'*None*',IntToStr(ForceHelpLevel))); + PrintACR('^19. Generic info : ^5'+IntToStr(GenCols)+' cols - '+IntToStr(GCol[1])+'/'+IntToStr(GCol[2])+ + '/'+IntToStr(GCol[3])); + IF (General.MultiNode) THEN + PrintACR('^1N. Node activity : ^5'+NodeActivityDesc); + PrintACR('^1T. Flags : ^5'+DisplayMenuFlags(MenuFlags,'5','1')); + MCIAllowed := TRUE; + Print('%LF^1[Commands on this menu: ^5'+IntToStr(CmdNumArray[RecNumToModify])+'^1]'); + IF (NumMenus = 0) THEN + Print('*** No menus defined ***'); + END; + IF (General.MultiNode) THEN + LOneK('%LFModify menu [^5C^4=^5Command Editor^4,^5?^4=^5Help^4]: ',Cmd1,'Q123456789CNT[]FJL?'^M,TRUE,TRUE) + ELSE + LOneK('%LFModify menu [^5C^4=^5Command Editor^4,^5?^4=^5Help^4]: ',Cmd1,'Q123456789CT[]FJL?'^M,TRUE,TRUE); + CASE Cmd1 OF + '1' : BEGIN + REPEAT + SaveMenuNum := MenuNum; + RecNum1 := -1; + InputByteWC('%LFNew menu number',MenuNum,[DisplayValue,NumbersOnly],1,(NumMenus + 1),Changed); + IF (MenuNum <> SaveMenuNum) AND (MenuNum >= 1) AND (MenuNum <= (NumMenus + 1)) THEN + BEGIN + RecNum := 1; + WHILE (Recnum <= NumMenus) AND (RecNum1 = -1) DO + BEGIN + Seek(MenuFile,MenuRecNumArray[RecNum]); + Read(MenuFile,TempMenuR); + IF (MenuNum = TempMenuR.MenuNum) THEN + RecNum1 := TempMenuR.MenuNum; + Inc(RecNum); + END; + IF (RecNum1 <> -1) THEN + BEGIN + NL; + Print('^7Duplicate menu number!^1'); + MenuNum := SaveMenuNum; + END; + END; + UNTIL (RecNum1 = -1) OR (HangUp); + Changed := TRUE; + END; + '2' : BEGIN + InputWNWC('%LFNew menu title #1: ',LDesc[1], + (SizeOf(LDesc[1]) - 1),Changed); + IF (LDesc[1] <> '') THEN + InputWNWC('New menu title #2: ',LDesc[2], + (SizeOf(LDesc[2]) - 1),Changed); + IF (LDesc[2] <> '') THEN + InputWNWC('New menu title #3: ',LDesc[3], + (SizeOf(LDesc[3]) - 1),Changed); + END; + '3' : BEGIN + InputWN1('%LFNew file displayed for help: ',Directive,(SizeOf(Directive) - 1), + [InterActiveEdit,UpperOnly],Changed); + InputWN1('%LFNew file displayed for extended help: ',LongMenu,(SizeOf(LongMenu) - 1), + [InterActiveEdit,UpperOnly],Changed); + END; + '4' : InputWNWC('%LFNew menu prompt: ',MenuPrompt,(SizeOf(MenuPrompt) - 1),Changed); + '5' : InputWN1('%LFNew menu ACS: ',ACS,(SizeOf(ACS) - 1),[InterActiveEdit],Changed); + '6' : InputWN1('%LFNew password: ',Password,(SizeOf(Password) - 1),[InterActiveEdit,UpperOnly],Changed); + '7' : BEGIN + SaveMenuNum := FallBack; + IF (Changed) THEN + BEGIN + Seek(MenuFile,MenuRecNumArray[SaveRecNumToModify]); + Write(MenuFile,MenuR); + Changed := FALSE; + END; + Close(MenuFile); + FindMenu('%LFNew fallback menu (^50^4=^5None^4)',SaveMenuNum,0,NumMenus,Changed); + Reset(MenuFile); + Seek(MenuFile,MenuRecNumArray[SaveRecNumToModify]); + Read(MenuFile,MenuR); + IF (Changed) THEN + FallBack := SaveMenuNum; + END; + '8' : InputByteWC('%LFNew forced menu help-level (0=None)',ForceHelpLevel, + [DisplayValue,NumbersOnly],0,3,Changed); + '9' : BEGIN + REPEAT + NL; + PrintACR('^1C. Generic columns : ^5'+IntToStr(GenCols)); + PrintACR('^11. Bracket color : ^5'+IntToStr(GCol[1])); + PrintACR('^12. Command color : ^5'+IntToStr(GCol[2])); + PrintACR('^13. Description color: ^5'+IntToStr(GCol[3])); + PrintACR('^1S. Show menu'); + LOneK('%LFSelect (CS,1-3,Q=Quit): ',Cmd1,'QCS123'^M,TRUE,TRUE); + CASE Cmd1 OF + 'S' : BEGIN + IF (Changed) THEN + BEGIN + Seek(MenuFile,MenuRecNumArray[SaveRecNumToModify]); + Write(MenuFile,MenuR); + Changed := FALSE; + END; + Seek(MenuFile,MenuRecNumArray[SaveRecNumToModify]); + Read(MenuFile,MenuR); + CurMenu := MenuR.MenuNum; + LoadMenu; + Reset(MenuFile); + GenericMenu(2); + NL; + PauseSCR(FALSE); + Seek(MenuFile,MenuRecNumArray[SaveRecNumToModify]); + Read(MenuFile,MenuR); + END; + 'C' : InputByteWC('%LFNew number of generic columns',GenCols, + [DisplayValue,NumbersOnly],0,7,Changed); + '1' : InputByteWC('%LFNew bracket color',GCol[1],[DisplayValue,NumbersOnly],0,9,Changed); + '2' : InputByteWC('%LFNew command color',GCol[2],[DisplayValue,NumbersOnly],0,9,Changed); + '3' : InputByteWC('%LFNew description color',GCol[3],[DisplayValue,NumbersOnly],0,9,Changed); + END; + UNTIL (Cmd1 IN ['Q',^M]) OR (HangUp); + Cmd1 := #0; + END; + 'C' : BEGIN + IF (Changed) THEN + BEGIN + Seek(MenuFile,MenuRecNumArray[SaveRecNumToModify]); + Write(MenuFile,MenuR); + Changed := FALSE; + END; + CommandEditor(RecNumToModify,MenuNum,LDesc[1]); + SaveRecNumToModify := -1; + END; + 'N' : IF (General.MultiNode) THEN + InputWNWC('%LF^1New node activity description:%LF^4: ',NodeActivityDesc, + (SizeOf(NodeActivityDesc) - 1),Changed); + 'T' : BEGIN + REPEAT + LOneK('%LFToggle which flag? ('+DisplayMenuFlags(MenuFlags,'5','4')+'^4)'+ + ' [^5?^4=^5Help^4,^5^4=^5Quit^4]: ',Cmd1,^M'CDTNPAF12345?',TRUE,TRUE); + CASE Cmd1 OF + 'C','D','T','N','P','A','F','1'..'5' : + ToggleMenuFlags(Cmd1,MenuFlags,Changed); + '?' : BEGIN + NL; + LCmds(21,3,'Clear screen','Don''t center titles'); + LCmds(21,3,'No menu prompt','Pause before display'); + LCmds(21,3,'Auto Time display','Force line input'); + LCmds(21,3,'Titles not displayed','1 No ANS prompt'); + LCmds(21,3,'2 No AVT prompt','3 No RIP prompt'); + LCmds(21,3,'4 No Global disp','5 No global use'); + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + Cmd1 := #0; + END; + '[' : IF (RecNumToModify > 1) THEN + Dec(RecNumToModify) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + ']' : IF (RecNumToModify < NumMenus) THEN + Inc(RecNumToModify) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNumToModify <> 1) THEN + RecNumToModify := 1 + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + InputIntegerWOC('%LFJump to entry?',RecNumToModify,[NumbersOnly],1,NumMenus); + IF (RecNumToModify < 1) AND (RecNumToModify > NumMenus) THEN + Cmd1 := #0; + END; + 'L' : IF (RecNumToModify <> NumMenus) THEN + RecNumToModify := NumMenus + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay screen'); + Print('^31-9,C,N,T^1:Modify item'); + LCmds(16,3,'[Back entry',']Forward entry'); + LCmds(16,3,'Command Editor','First entry in list'); + LCmds(16,3,'Jump to entry','Last entry in list'); + LCmds(16,3,'Quit and save',''); + END; + END; + UNTIL (Pos(Cmd1,'QC[]FJL') <> 0) OR (HangUp); + IF (Changed) THEN + BEGIN + Seek(MenuFile,MenuRecNumArray[SaveRecNumToModify]); + Write(MenuFile,MenuR); + Changed := FALSE; + SysOpLog('* Modified menu: ^5'+Menur.LDesc[1]); + END; + END; + Close(MenuFile); + LastError := IOResult; + END; + END; + END; + +BEGIN + LoadMenuPointers; + SaveTempPause := TempPause; + TempPause := FALSE; + RecNumToList := 1; + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + DisplayMenus(RecNumToList,TRUE); + LOneK('%LFMenu editor [^5?^4=^5Help^4]: ',Cmd,'QDIM?'^M,TRUE,TRUE); + CASE Cmd OF + ^M : IF (RecNumToList < 1) OR (RecNumToList > NumMenus) THEN + RecNumToList := 1; + 'D' : DeleteMenu; + 'I' : InsertMenu; + 'M' : ModifyMenu; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay screen'); + LCmds(12,3,'Delete menu','Insert menu'); + LCmds(12,3,'Modify menu','Quit'); + END; + END; + IF (CMD <> ^M) THEN + RecNumToList := 1; + UNTIL (Cmd = 'Q') OR (HangUp); + TempPause := SaveTempPause; + LastError := IOResult; + LoadMenuPointers; + IF (UserOn) THEN + BEGIN + SaveCurMenu := CurMenu; + NumCmds := 0; + GlobalCmds := 0; + IF (General.GlobalMenu > 0) THEN + BEGIN + CurMenu := General.GlobalMenu; + LoadMenu; + GlobalCmds := NumCmds; + END; + CurMenu := SaveCurMenu; + LoadMenu; + END; +END; + +END. diff --git a/SOURCE/SYSOP7M.PAS b/SOURCE/SYSOP7M.PAS new file mode 100644 index 0000000..3af822c --- /dev/null +++ b/SOURCE/SYSOP7M.PAS @@ -0,0 +1,488 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B+,D+,E+,F+,I+,L+,N-,O+,R-,S+,V-} +UNIT SysOp7M; + +INTERFACE + +USES + Common; + +PROCEDURE CommandEditor(MenuToModify,MenuNumber: Integer; MenuName: AStr); +PROCEDURE LoadMenuPointers; + +IMPLEMENTATION + +USES + Menus2; + +PROCEDURE LoadMenuPointers; +VAR + RecNum: Integer; +BEGIN + NumMenus := 0; + NumCmds := 0; + FOR RecNum := 1 TO MaxMenus DO + MenuRecNumArray[RecNum] := 0; + FOR RecNum := 1 TO MaxMenus DO + CmdNumArray[RecNum] := 0; + Reset(MenuFile); + RecNum := 0; + WHILE NOT Eof(MenuFile) DO + BEGIN + Read(MenuFile,MenuR); + IF (MenuR.Menu = FALSE) THEN + Inc(NumCmds) + ELSE + BEGIN + Inc(NumMenus); + MenuRecNumArray[NumMenus] := RecNum; + IF (NumMenus > 1) THEN + CmdNumArray[NumMenus - 1] := NumCmds; + NumCmds := 0; + END; + Inc(RecNum); + END; + CmdNumArray[NumMenus] := NumCmds; +END; + +PROCEDURE CommandEditor(MenuToModify,MenuNumber: Integer; MenuName: AStr); +VAR + TempS: AStr; + Cmd: Char; + RecNumToList, + Counter: Integer; + + FUNCTION DisplayCmdFlags(CmdFlags: CmdFlagSet; C1,C2: Char): AStr; + VAR + CmdFlagT: CmdFlagType; + DisplayStr: AStr; + BEGIN + DisplayStr := ''; + FOR CmdFlagT := Hidden TO UnHidden DO + IF (CmdFlagT IN CmdFlags) THEN + DisplayStr := DisplayStr + '^'+C1+Copy('HU',(Ord(CmdFlagT) + 1),1) + ELSE + DisplayStr := DisplayStr + '^'+C2+'-'; + DisplayCmdFlags := DisplayStr; + END; + + PROCEDURE ToggleCmdFlag(CmdFlagT: CmdFlagType; VAR CmdFlags: CmdFlagSet); + BEGIN + IF (CmdFlagT IN CmdFlags) THEN + Exclude(CmdFlags,CmdFlagT) + ELSE + Include(CmdFlags,CmdFlagT); + END; + + PROCEDURE ToggleCmdFlags(C: Char; VAR CmdFlags: CmdFlagSet; VAR Changed: Boolean); + VAR + TempCmdFlags: CmdFlagSet; + BEGIN + TempCmdFlags := CmdFlags; + CASE C OF + 'H' : ToggleCmdFlag(Hidden,CmdFlags); + 'U' : ToggleCmdFlag(UnHidden,CmdFlags); + END; + IF (CmdFlags <> TempCmdFlags) THEN + Changed := TRUE; + END; + + PROCEDURE InitCommandVars(VAR MenuR: MenuRec); + BEGIN + FillChar(MenuR,SizeOf(MenuR),0); + WITH MenuR DO + BEGIN + LDesc[1] := '<< New Command >>'; + ACS := ''; + NodeActivityDesc := ''; + Menu := FALSE; + CmdFlags := []; + SDesc := '(XXX)New Cmd'; + CKeys := 'XXX'; + CmdKeys := '-L'; + Options := ''; + END; + END; + + FUNCTION GetRecNum(NumCmds: Integer): Integer; + VAR + R: REAL; + BEGIN + R := (NumCmds / 3); + IF (Frac(r) = 0.0) THEN + GetRecNum := Trunc(R) + ELSE + GetRecNum := (Trunc(R) + 1); + END; + + PROCEDURE DeleteCommand; + VAR + RecNumToDelete, + RecNum: SmallInt; + BEGIN + IF (CmdNumArray[MenuToModify] = 0) THEN + Messages(4,0,'commands') + ELSE + BEGIN + RecNumToDelete := -1; + InputIntegerWOC('%LFDelete which command?',RecNumToDelete,[NumbersOnly],1,CmdNumArray[MenuToModify]); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= CmdNumArray[MenuToModify]) THEN + BEGIN + Seek(MenuFile,(MenuRecNumArray[MenuToModify] + RecNumToDelete)); + Read(MenuFile,MenuR); + Print('%LFCommand: ^5'+MenuR.LDesc[1]); + IF PYNQ('%LFAre you sure you want to delete it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Deleting command record ...'); + SysOpLog('* Deleted command: ^5'+MenuR.LDesc[1]); + RecNumToDelete := (MenuRecNumArray[MenuToModify] + RecNumToDelete); { Convert To Real Record Number } + IF (RecNumToDelete <= (FileSize(MenuFile) - 2)) THEN + FOR RecNum := RecNumToDelete TO (FileSize(MenuFile) - 2) DO + BEGIN + Seek(MenuFile,(RecNum + 1)); + Read(MenuFile,MenuR); + Seek(MenuFile,RecNum); + Write(MenuFile,MenuR); + END; + Seek(MenuFile,FileSize(MenuFile) - 1); + Truncate(MenuFile); + LoadMenuPointers; + LastError := IOResult; + END; + END; + END; + END; + + PROCEDURE InsertCommand; + VAR + RecNumToInsertBefore, + InsertNum, + RecNum: SmallInt; + BEGIN + IF (CmdNumArray[MenuToModify] = MaxCmds) THEN + Messages(5,MaxCmds,'commands') + ELSE + BEGIN + RecNumToInsertBefore := -1; + InputIntegerWOC('%LFCommand to insert before?',RecNumToInsertBefore,[NumbersOnly],1,(CmdNumArray[MenuToModify] + 1)); + IF (RecNumToInsertBefore >= 1) AND (RecNumToInsertBefore <= (CmdNumArray[MenuToModify] + 1)) THEN + BEGIN + InsertNum := 1; + InputIntegerWOC('%LFInsert how many commands?',InsertNum, + [DisplayValue,NumbersOnly],1,(MaxCmds - CmdNumArray[MenuToModify])); + IF (InsertNum < 1) OR (InsertNum > (MaxCmds - CmdNumArray[MenuToModify])) THEN + InsertNum := 1; + Print('%LF[> Inserting '+IntToStr(InsertNum)+' commands.'); + SysOpLog('* Inserted '+IntToStr(InsertNum)+' commands.'); + RecNumToInsertBefore := (MenuRecNumArray[MenuToModify] + RecNumToInsertBefore); { Convert To Real Record Number } + FOR RecNum := 1 TO InsertNum DO + BEGIN + Seek(MenuFile,FileSize(MenuFile)); + Write(MenuFile,MenuR); + END; + FOR RecNum := ((FileSize(MenuFile) - 1) - InsertNum) DOWNTO RecNumToInsertBefore DO + BEGIN + Seek(MenuFile,RecNum); + Read(MenuFile,MenuR); + Seek(MenuFile,(RecNum + InsertNum)); + Write(MenuFile,MenuR); + END; + InitCommandVars(MenuR); + FOR RecNum := RecNumToInsertBefore TO ((RecNumToInsertBefore + InsertNum) - 1) DO + BEGIN + Seek(MenuFile,RecNum); + Write(MenuFile,MenuR); + END; + LoadMenuPointers; + LastError := IOResult; + END; + END; + END; + + PROCEDURE ModifyCommand; + VAR + TempS1: AStr; + Cmd1: Char; + TempB: Byte; + RecNumToModify, + SaveRecNumToModify: SmallInt; + Changed: Boolean; + BEGIN + IF (CmdNumArray[MenuToModify] = 0) THEN + Messages(4,0,'commands') + ELSE + BEGIN + RecNumToModify := -1; + InputIntegerWOC('%LFCommand to modify?',RecNumToModify,[NumbersOnly],1,CmdNumArray[MenuToModify]); + IF (RecNumToModify >= 1) AND (RecNumToModify <= CmdNumArray[MenuToModify]) THEN + BEGIN + SaveRecNumToModify := -1; + Cmd1 := #0; + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNumToModify <> RecNumToModify) THEN + BEGIN + Seek(MenuFile,(MenuRecNumArray[MenuToModify] + RecNumToModify)); + Read(MenuFile,MenuR); + SaveRecNumToModify := RecNumToModify; + Changed := FALSE; + END; + WITH MenuR DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + MCIAllowed := FALSE; + CLS; + Print('^5'+MenuName+' #'+IntToStr(MenuNumber)); + Print('^5Command #'+IntToStr(RecNumToModify)+' of '+IntToStr(CmdNumArray[MenuToModify])); + NL; + PrintACR('^11. Long descript : ^5'+LDesc[1]); + PrintACR('^12. Short descript: ^5'+SDesc); + PrintACR('^13. Menu keys : ^5'+CKeys); + PrintACR('^14. ACS required : ^5"'+ACS+'"'); + PrintACR('^15. CmdKeys : ^5'+CmdKeys); + PrintACR('^16. Options : ^5'+Options+'^1'); + IF (General.MultiNode) THEN + PrintACR('^1N. Node activity : ^5'+NodeActivityDesc); + PrintACR('^1T. Flags : ^5'+DisplayCmdFlags(CmdFlags,'5','1')); + MCIAllowed := TRUE; + END; + IF (General.MultiNode) THEN + LOneK('%LFModify menu [^5?^4=^5Help^4]: ',Cmd1,'Q123456NT[]FJL?'^M,TRUE,TRUE) + ELSE + LOneK('%LFModify menu [^5?^4=^5Help^4]: ',Cmd1,'Q123456T[]FJL?'^M,TRUE,TRUE); + CASE Cmd1 OF + '1' : InputWNWC('%LF^1New long description:%LF^4: ',LDesc[1],(SizeOf(LDesc[1]) - 1),Changed); + '2' : InputWNWC('%LFNew short description: ',SDesc,(SizeOf(SDesc) - 1),Changed); + '3' : InputWN1('%LFNew menu keys: ',Ckeys,(SizeOf(CKeys) - 1),[InterActiveEdit,UpperOnly],Changed); + '4' : InputWN1('%LFNew ACS: ',ACS,(SizeOf(ACS) - 1),[InterActiveEdit],Changed); + '5' : BEGIN + REPEAT + Prt('%LFNew command keys [^5?^4=^5List^4]: '); + MPL(2); + Input(TempS1,2); + IF (TempS1 = '?') THEN + BEGIN + CLS; + PrintF('MENUCMD'); + NL; + END; + UNTIL (HangUp) OR (TempS1 <> '?'); + IF (Length(TempS1) = 2) THEN + BEGIN + CmdKeys := TempS1; + Changed := TRUE; + END; + END; + '6' : InputWNWC('%LFNew options: ',Options,(SizeOf(Options) - 1),Changed); + 'N' : IF (General.MultiNode) THEN + InputWNWC('%LF^1New node activity description:%LF^4: ',NodeActivityDesc, + (SizeOf(NodeActivityDesc) - 1),Changed); + 'T' : BEGIN + REPEAT + LOneK('%LFToggle which flag? ('+DisplayCmdFlags(CmdFlags,'5','4')+')'+ + ' [^5?^4=^5Help^4,^5^4=^5Quit^4]: ',Cmd1,^M'HU?',TRUE,TRUE); + CASE Cmd1 OF + 'H','U' : + ToggleCmdFlags(Cmd1,CmdFlags,Changed); + '?' : BEGIN + NL; + LCmds(17,3,'Hidden command','UnHidden Command'); + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + Cmd1 := #0; + END; + '[' : IF (RecNumToModify > 1) THEN + Dec(RecNumToModify) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + ']' : IF (RecNumToModify < CmdNumArray[MenuToModify]) THEN + Inc(RecNumToModify) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNumToModify <> 1) THEN + RecNumToModify := 1 + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + InputIntegerWOC('%LFJump to entry',RecNumToModify,[NumbersOnly],1,CmdNumArray[MenuToModify]); + IF (RecNumToModify < 1) and (RecNumToModify > CmdNumArray[MenuToModify]) THEN + Cmd1 := #0; + END; + 'L' : IF (RecNumToModify <> CmdNumArray[MenuToModify]) THEN + RecNumToModify := CmdNumArray[MenuToModify] + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay screen'); + Print('^31-6,N,T^1:Modify item'); + LCmds(20,3,'[Back entry',']Forward entry'); + LCmds(20,3,'First entry in list','Jump to entry'); + LCmds(20,3,'Last entry in list','Quit and save'); + END; + END; + UNTIL (Pos(Cmd1,'Q[]FJL') <> 0) OR (HangUp); + IF (Changed) THEN + BEGIN + Seek(MenuFile,(MenuRecNumArray[MenuToModify] + SaveRecNumToModify)); + Write(MenuFile,MenuR); + Changed := FALSE; + SysOpLog('* Modified command: ^5'+MenuR.LDesc[1]); + END; + END; + LastError := IOResult; + END; + END; + END; + + PROCEDURE PositionCommand; + VAR + TempMenuR: MenuRec; + RecNumToPosition, + RecNumToPositionBefore, + RecNum1, + RecNum2: SmallInt; + BEGIN + IF (CmdNumArray[MenuToModify] = 0) THEN + Messages(4,0,'commands') + ELSE IF (CmdNumArray[MenuToModify] = 1) THEN + Messages(6,0,'commands') + ELSE + BEGIN + RecNumToPosition := -1; + InputIntegerWOC('%LFPosition which command',RecNumToPosition,[NumbersOnly],1,CmdNumArray[MenuToModify]); + IF (RecNumToPosition >= 1) AND (RecNumToPosition <= CmdNumArray[MenuToModify]) THEN + BEGIN + Print('%LFAccording to the current numbering system.'); + InputIntegerWOC('%LFPosition before which command?',RecNumToPositionBefore, + [NumbersOnly],1,(CmdNumArray[MenuToModify] + 1)); + IF (RecNumToPositionBefore <> RecNumToPosition) AND + (RecNumToPositionBefore <> (RecNumToPosition + 1)) THEN + BEGIN + RecNumToPosition := (MenuRecNumArray[MenuToModify] + RecNumToPosition); { Convert To Real Record Number } + RecNumToPositionBefore := (MenuRecNumArray[MenuToModify] + RecNumToPositionBefore); + Print('%LF[> Positioning command.'); + IF (RecNumToPositionBefore > RecNumToPosition) THEN + Dec(RecNumToPositionBefore); + Seek(MenuFile,RecNumToPosition); + Read(MenuFile,TempMenuR); + RecNum1 := RecNumToPosition; + IF (RecNumToPosition > RecNumToPositionBefore) THEN + RecNum2 := -1 + ELSE + RecNum2 := 1; + WHILE (RecNum1 <> RecNumToPositionBefore) DO + BEGIN + IF ((RecNum1 + RecNum2) < FileSize(MenuFile)) THEN + BEGIN + Seek(MenuFile,(RecNum1 + RecNum2)); + Read(MenuFile,MenuR); + Seek(MenuFile,RecNum1); + Write(MenuFile,MenuR); + END; + Inc(RecNum1,RecNum2); + END; + Seek(MenuFile,RecNumToPositionBefore); + Write(MenuFile,TempMenuR); + END; + LastError := IOResult; + END; + END; + END; + +BEGIN + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + MCIAllowed := FALSE; + CLS; + PrintACR('^0###^4:^3Short Desc. ^0###^4:^3Short Desc. ^0###^4:^3Short Desc.'); + PrintACR('^4===:===================== ===:===================== ===:====================='); + Reset(MenuFile); + RecNumToList := 1; + WHILE (RecNumToList <= GetRecNum(CmdNumArray[MenuToModify])) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(MenuFile,(RecNumToList + MenuRecNumArray[MenuToModify])); + Read(MenuFile,MenuR); + TempS := '^0'+PadRightStr(IntToStr(RecNumToList),3)+' ^5'+PadLeftStr(MenuR.SDesc,21)+' '; + Counter := (RecNumToList + GetRecNum(CmdNumArray[MenuToModify])); + IF (Counter <= CmdNumArray[MenuToModify]) THEN + BEGIN + Seek(MenuFile,(Counter + MenuRecNumArray[MenuToModify])); + Read(MenuFile,MenuR); + TempS := TempS + '^0'+PadRightStr(IntToStr(Counter),3)+' ^5'+PadLeftStr(MenuR.SDesc,21)+' '; + END; + Counter := (Counter + GetRecNum(CmdNumArray[MenuToModify])); + IF (Counter <= CmdNumArray[MenuToModify]) THEN + BEGIN + Seek(MenuFile,Counter + MenuRecNumArray[MenuToModify]); + Read(MenuFile,MenuR); + TempS := TempS + '^0'+PadRightStr(IntToStr(Counter),3)+' ^5'+PadLeftStr(MenuR.SDesc,21); + END; + PrintACR(TempS); + Inc(RecNumToList); + END; + IF (CmdNumArray[MenuToModify] = 0) THEN + Print('*** No commands defined ***'); + MCIAllowed := TRUE; + END; + LOneK('%LFCommand editor [^5?^4=^5Help^4]: ',Cmd,'QDILMPSX?'^M,TRUE,TRUE); + CASE Cmd OF + 'D' : DeleteCommand; + 'I' : InsertCommand; + 'L' : BEGIN + Seek(MenuFile,MenuRecNumArray[MenuNumber]); + Read(MenuFile,MenuR); + CurMenu := MenuNumber; + LoadMenu; + Reset(MenuFile); + GenericMenu(3); + NL; + PauseScr(FALSE); + END; + 'M' : ModifyCommand; + 'P' : PositionCommand; + 'S' : BEGIN + Seek(MenuFile,MenuRecNumArray[MenuNumber]); + Read(MenuFile,MenuR); + CurMenu := MenuNumber; + LoadMenu; + Reset(MenuFile); + GenericMenu(2); + NL; + PauseScr(FALSE); + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay screen'); + LCmds(20,3,'Delete command','Insert command'); + LCmds(20,3,'Long generic menu','Modify commands'); + LCmds(20,3,'Position command','Quit'); + LCmds(20,3,'Short generic menu',''); + END; + END; + UNTIL (Cmd = 'Q') OR (HangUp); + LastError := IOResult; +END; + +END. diff --git a/SOURCE/SYSOP8.PAS b/SOURCE/SYSOP8.PAS new file mode 100644 index 0000000..5b7faa1 --- /dev/null +++ b/SOURCE/SYSOP8.PAS @@ -0,0 +1,1135 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysOp8; + +INTERFACE + +PROCEDURE MessageAreaEditor; + +IMPLEMENTATION + +USES + Common, + File2, + Mail0, + SysOp7; + +PROCEDURE MessageAreaEditor; +CONST + DisplayType: Byte = 1; +VAR + MsgareaDefFile: FILE OF MessageAreaRecordType; + TempMemMsgArea: MessageAreaRecordType; + Cmd: Char; + RecNumToList: SmallInt; + Ok, + Changed, + SaveTempPause: Boolean; + + FUNCTION DisplayNetFlags(MAFlags: MAFlagSet; C1,C2: Char): AStr; + VAR + MAFlagT: MessageAreaFlagType; + TempS: AStr; + BEGIN + TempS := ''; + FOR MAFlagT := MASKludge TO MAInternet DO + IF (MAFlagT IN MAFlags) THEN + TempS := TempS + '^'+C1+Copy('RUAPFQKSOTI',(Ord(MAFlagT) + 1),1) + ELSE + TempS := TempS + '^'+C2+'-'; + DisplayNetFlags := TempS; + END; + + FUNCTION DisplayMAFlags(MAFlags: MAFlagSet; C1,C2: Char): AStr; + VAR + MAFlagT: MessageAreaFlagType; + TempS: AStr; + BEGIN + TempS := ''; + FOR MAFlagT := MARealName TO MAQuote DO + IF (MAFlagT IN MAFlags) THEN + TempS := TempS + '^'+C1+Copy('RUAPFQKSOTI',(Ord(MAFlagT) + 1),1) + ELSE + TempS := TempS + '^'+C2+'-'; + DisplayMAFlags := TempS; + END; + + PROCEDURE ToggleMAFlag(MAFlagT: MessageAreaFlagType; VAR MAFlags: MAFlagSet); + BEGIN + IF (MAFlagT IN MAFlags) THEN + Exclude(MAFlags,MAFlagT) + ELSE + Include(MAFlags,MAFlagT); + END; + + PROCEDURE ToggleMAFlags(C: Char; VAR MAFlags: MAFlagSet; VAR Changed: Boolean); + VAR + TempMAFlags: MAFlagSet; + BEGIN + TempMAFlags := MAFlags; + CASE C OF + 'R' : ToggleMAFlag(MARealName,MAFlags); + 'U' : ToggleMAFlag(MAUnHidden,MAFlags); + 'A' : ToggleMAFlag(MAFilter,MAFlags); + 'P' : ToggleMAFlag(MAPrivate,MAFlags); + 'F' : ToggleMAFlag(MAForceRead,MAFlags); + 'Q' : ToggleMAFlag(MAQuote,MAFlags); + 'K' : ToggleMAFlag(MASKludge,MAFlags); + 'S' : ToggleMAFlag(MASSeenby,MAFlags); + 'O' : ToggleMAFlag(MASOrigin,MAFlags); + 'T' : ToggleMAFlag(MAAddTear,MAFlags); + 'I' : ToggleMAFlag(MAInternet,MAFlags); + END; + IF (MAFlags <> TempMAFlags) THEN + Changed := TRUE; + END; + + FUNCTION AnonTypeChar(Anonymous: AnonTyp): Char; + BEGIN + CASE Anonymous OF + ATYes : AnonTypeChar := 'Y'; + ATNo : AnonTypeChar := 'N'; + ATForced : AnonTypeChar := 'F'; + ATDearAbby : AnonTypeChar := 'D'; + ATAnyName : AnonTypeChar := 'A'; + END; + END; + + FUNCTION NodeStr(AKA: BYTE): AStr; + VAR + TempS: AStr; + BEGIN + TempS := IntToStr(General.AKA[AKA].Zone)+':'+ + IntToStr(General.AKA[AKA].Net)+'/'+ + IntToStr(General.AKA[AKA].Node); + IF (General.AKA[AKA].Point > 0) THEN + TempS := TempS+'.'+IntToStr(General.AKA[AKA].Point); + NodeStr := TempS; + END; + + FUNCTION MATypeStr(MAType: Integer): AStr; + BEGIN + CASE MAType OF + 0 : MATypeStr := 'Local'; + 1 : MATypeStr := 'EchoMail'; + 2 : MATypeStr := 'GroupMail'; + 3 : MATypeStr := 'QwkMail'; + END; + END; + + FUNCTION AnonTypeStr(Anonymous: AnonTyp): ASTR; + BEGIN + CASE Anonymous OF + ATYes : AnonTypeStr := 'Yes'; + ATNo : AnonTypeStr := 'No'; + ATForced : AnonTypeStr := 'Forced'; + ATDearAbby : AnonTypeStr := 'Dear Abby'; + ATAnyName : AnonTypeStr := 'Any Name'; + END; + END; + + PROCEDURE InitMsgAreaVars(VAR MemMsgArea: MessageAreaRecordType); + BEGIN + FillChar(MemMsgArea,SizeOf(MemMsgArea),0); + WITH MemMsgArea DO + BEGIN + Name := '<< New Message Area >>'; + FileName := 'NEWBOARD'; + MsgPath := ''; + ACS := ''; + PostACS := ''; + MCIACS := ''; + SysOpACS := ''; + MaxMsgs := 100; + Anonymous := ATNo; + Password := ''; + MAFlags := []; + MAType := 0; + Origin := ''; + Text_Color := General.Text_Color; + Quote_Color := General.Quote_Color; + Tear_Color := General.Tear_Color; + Origin_Color := General.Origin_Color; + MessageReadMenu := 0; + QuoteStart := '|03Quoting message from |11@F |03to |11@T'; + QuoteEnd := '|03on |11@D|03.'; + PrePostFile := ''; + AKA := 0; + QWKIndex := 0; + END; + END; + + PROCEDURE ChangeMsgAreaDrive(Drive: Char; FirstRecNum: SmallInt); + VAR + LastRecNum, + RecNum: SmallInt; + BEGIN + IF (NumMsgAreas = 0) THEN + Messages(4,0,'message areas') + ELSE + BEGIN + FirstRecNum := -1; + InputIntegerWOC('%LFMessage area to start at?',FirstRecNum,[NumbersOnly],1,NumMsgAreas); + IF (FirstRecNum >= 1) AND (FirstRecNum <= NumMsgAreas) THEN + BEGIN + LastRecNum := -1; + InputIntegerWOC('%LFMessage area to end at?',LastRecNum,[NumbersOnly],1,NumMsgAreas); + IF (LastRecNum >= 1) AND (LastRecNum <= NumMsgAreas) THEN + BEGIN + IF (FirstRecNum > LastRecNum) OR (LastRecNum < FirstRecNum) THEN + Messages(8,0,'') + ELSE + BEGIN + LOneK('%LFChange to which drive? (^5A^4-^5Z^4): ',Drive,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'^M,TRUE,TRUE); + ChDir(Drive+':'); + IF (IOResult <> 0) THEN + Messages(7,0,'') + ELSE + BEGIN + ChDir(StartDir); + Prompt('%LFUpdating the drive for message area '+IntToStr(FirstRecNum)+' to '+IntTostr(LastRecNum)+' ... '); + Reset(MsgAreaFile); + FOR RecNum := FirstRecNum TO LastRecNum DO + BEGIN + Seek(MsgAreaFile,(RecNum - 1)); + Read(MsgAreaFile,MemMsgArea); + IF (MemMsgArea.MAType IN [1,2]) THEN + MemMsgArea.MsgPath[1] := Drive; + Seek(MsgAreaFile,(RecNum - 1)); + Write(MsgAreaFile,MemMsgArea); + END; + Close(MsgAreaFile); + LastError := IOResult; + Print('Done'); + SysOpLog('* Changed message areas: ^5'+IntToStr(FirstRecNum)+'^1-^5'+IntToStr(LastRecNum)+'^1 to ^5'+Drive+':\'); + END; + END; + END; + END; + END + END; + + PROCEDURE DeleteMsgArea(TempMemMsgArea1: MessageAreaRecordType; RecNumToDelete: SmallInt); + VAR + RecNum: Integer; + Ok, + Ok1: Boolean; + BEGIN + IF (NumMsgAreas = 0) THEN + Messages(4,0,'message areas') + ELSE + BEGIN + RecNumToDelete := -1; + InputIntegerWOC('%LFMessage area to delete?',RecNumToDelete,[NumbersOnly],1,NumMsgAreas); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= NumMsgAreas) THEN + BEGIN + Reset(MsgAreaFile); + Seek(MsgAreaFile,(RecNumToDelete - 1)); + Read(MsgAreaFile,TempMemMsgArea1); + Close(MsgAreaFile); + LastError := IOResult; + Print('%LFMessage area: ^5'+TempMemMsgArea1.Name); + IF PYNQ('%LFAre you sure you want to delete it? ',0,FALSE) THEN + BEGIN + Print('%LF[> Deleting message area record ...'); + Dec(RecNumToDelete); + Reset(MsgAreaFile); + IF (RecNumToDelete >= 0) AND (RecNumToDelete <= (FileSize(MsgAreaFile) - 2)) THEN + FOR RecNum := RecNumToDelete TO (FileSize(MsgAreaFile) - 2) DO + BEGIN + Seek(MsgAreaFile,(RecNum + 1)); + Read(MsgAreaFile,MemMsgArea); + Seek(MsgAreaFile,RecNum); + Write(MsgAreaFile,MemMsgArea); + END; + Seek(MsgAreaFile,(FileSize(MsgAreaFile) - 1)); + Truncate(MsgAreaFile); + Close(MsgAreaFile); + LastError := IOResult; + Dec(NumMsgAreas); + SysOpLog('* Deleted message area: ^5'+TempMemMsgArea1.Name); + Ok := TRUE; + Ok1 := TRUE; + Reset(MsgAreaFile); + FOR RecNum := 1 TO FileSize(MsgAreaFile) DO + BEGIN + Seek(MsgAreaFile,(RecNum - 1)); + Read(MsgAreaFile,MemMsgArea); + IF (MemMsgArea.FileName = TempMemMsgArea1.FileName) THEN + Ok := FALSE; + IF (TempMemMsgArea1.MAType IN [1,2]) AND (MemMsgArea.MsgPath = TempMemMsgArea1.MsgPath) THEN + Ok1 := FALSE; + END; + Close(MsgAreaFile); + IF (Ok) THEN + IF (PYNQ('%LFDelete message area data files also? ',0,FALSE)) THEN + BEGIN + Kill(General.MsgPath+MemMsgArea.FileName+'.HDR'); + Kill(General.MsgPath+MemMsgArea.FileName+'.DAT'); + Kill(General.MsgPath+MemMsgArea.FileName+'.SCN'); + END; + IF (Ok1) AND (TempMemMsgArea1.MAType IN [1,2]) THEN + IF PYNQ('%LFRemove the message directory? ',0,FALSE) THEN + PurgeDir(TempMemMsgArea1.MsgPath,TRUE); + END; + END; + END; + END; + + PROCEDURE CheckMessageArea(MemMsgArea: MessageAreaRecordType; StartErrMsg,EndErrMsg: Byte; VAR Ok: Boolean); + VAR + Counter: Byte; + BEGIN + FOR Counter := StartErrMsg TO EndErrMsg DO + CASE Counter OF + 1 : IF (MemMsgArea.Name = '') OR (MemMsgArea.Name = '<< New Message Area >>') THEN + BEGIN + Print('%LF^7The area name is invalid!^1'); + OK := FALSE; + END; + 2 : IF (MemMsgArea.FileName = '') OR (MemMsgArea.FileName = 'NEWBOARD') THEN + BEGIN + Print('%LF^7The file name is invalid!^1'); + OK := FALSE; + END; + 3 : IF (MemMsgArea.MAType IN [1,2]) AND (MemMsgArea.MsgPath = '') THEN + BEGIN + Print('%LF^7The message path is invalid!^1'); + OK := FALSE; + END; + 4 : IF (MemMsgArea.MAType IN [1,2]) AND (General.AKA[MemMsgArea.AKA].Net = 0) THEN + BEGIN + Print('%LF^7The AKA address is invalid!^1'); + Ok := FALSE; + END; + 5 : IF (MemMsgArea.MAType IN [1..3]) AND (MemMsgArea.Origin = '') THEN + BEGIN + Print('%LF^7The origin is invalid!^1'); + Ok := FALSE; + END; + END; + END; + + PROCEDURE EditMessageArea(TempMemMsgArea1: MessageAreaRecordType; VAR MemMsgArea: MessageAreaRecordType; VAR Cmd1: Char; + VAR RecNumToEdit: SmallInt; VAR Changed: Boolean; Editing: Boolean); + VAR + TempFileName: Str8; + Path1, + Path2: Str52; + CmdStr: AStr; + RecNum, + RecNum1, + RecNumToList: Integer; + SaveQWKIndex: Word; + Ok: Boolean; + BEGIN + WITH MemMsgArea DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + MCIAllowed := FALSE; + Abort := FALSE; + Next := FALSE; + CLS; + IF (RecNumToEdit = -1) THEN + PrintACR('^5Default Message Area Configuration:') + ELSE + BEGIN + IF (Editing) THEN + PrintACR('^5Editing '+AOnOff(RecNumToEdit = 0,'private mail','message area #'+IntToStr(RecNumToEdit)+ + ' of '+IntToStr(NumMsgAreas))) + ELSE + PrintACR('^5Inserting message area #'+IntToStr(RecNumToEdit)+' of '+IntToStr(NumMsgAreas + 1)); + END; + NL; + PrintACR('^1A. Area name : ^5'+Name); + PrintACR('^1B. File name : ^5'+FileName+' ^7('+General.MsgPath+MemMsgArea.FileName+'.*)'); + PrintACR('^1C. Area type : ^5'+MATypeStr(MAType)); + IF (MAType IN [1,2]) THEN + PrintACR('^1 Message path: ^5'+MsgPath); + PrintACR('^1D. ACS required: ^5'+AOnOff(ACS = '','*None*',ACS)); + PrintACR('^1E. Post/MCI ACS: ^5'+AOnOff(PostACS = '','*None*',PostACS)+'^1 / ^5' + +AOnOff(MCIACS = '','*None*',MCIACS)); + PrintACR('^1G. Sysop ACS : ^5'+AOnOff(SysOpACS = '','*None*',SysOpACS)); + PrintACR('^1H. Max messages: ^5'+IntToStr(MaxMsgs)); + PrintACR('^1I. Anonymous : ^5'+AnonTypeStr(Anonymous)); + PrintACR('^1K. Password : ^5'+AOnOff(Password = '','*None*',Password)); + IF (MAType IN [1,2]) THEN + PrintACR('^1M. Net Address : ^5'+NodeStr(AKA)); + PrintACR('^1N. Colors : ^1Text=^'+IntToStr(Text_Color)+IntToStr(Text_Color)+ + '^1, Quote=^'+IntToStr(Quote_Color)+IntToStr(Quote_Color)+ + '^1, Tear=^'+IntToStr(Tear_Color)+IntToStr(Tear_Color)+ + '^1, Origin=^'+IntToStr(Origin_Color)+IntToStr(Origin_Color)); + PrintACR('^1O. Read menu : ^5'+IntToStr(MessageReadMenu)); + IF (MAType IN [1,2]) THEN + PrintACR('^1P. Mail flags : ^5'+DisplayNetFlags(MAFlags,'5','1')); + IF (MAType IN [1..3]) THEN + PrintACR('^1R. Origin line : ^5'+Origin); + PrintACR('^1S. Start quote : ^5'+AOnOff(QuoteStart = '','*None*',QuoteStart)); + PrintACR('^1T. End quote : ^5'+AOnOff(QuoteEnd = '','*None*',QuoteEnd)); + PrintACR('^1U. Post file : ^5'+AOnOff(PrePostFile = '','*None*',PrePostFile)); + PrintACR('^1V. QWK Index : ^5'+IntToStr(QWKIndex)); + PrintACR('^1W. Flags : ^5'+DisplayMAFlags(MAFlags,'5','1')); + MCIAllowed := TRUE; + END; + IF (RecNumToEdit = 0) THEN + CmdStr := 'ADEGHNOSTUW' + ELSE + BEGIN + IF (NOT Editing) THEN + CmdStr := 'ABCDEGHIKNOSTUVW' + ELSE + CmdStr := 'ABCDEGHIKNOSTUVW[]FJL'; + IF (MAType IN [1,2]) THEN + CmdStr := CmdStr + 'MP'; + IF (MAType IN [1..3]) THEN + CmdStr := CmdStr + 'R'; + END; + LOneK('%LFModify menu [^5?^4=^5Help^4]: ',Cmd1,'Q?'+CmdStr+^M,TRUE,TRUE); + CASE Cmd1 OF + 'A' : REPEAT + TempMemMsgArea1.Name := MemMsgArea.Name; + Ok := TRUE; + InputWNWC('%LFNew area name: ',Name,(SizeOF(Name) - 1),Changed); + CheckMessageArea(MemMsgArea,1,1,Ok); + IF (NOT Ok) THEN + MemMsgArea.Name := TempMemMsgArea1.Name; + UNTIL (Ok) OR (HangUp); + 'B' : REPEAT + Ok := TRUE; + TempFileName := FileName; + InputWN1('%LFNew file name (^5Do not enter ^4"^5.EXT^4"): ',TempFileName,(SizeOf(FileName) - 1), + [UpperOnly,InterActiveEdit],Changed); + TempFileName := SQOutSp(TempFileName); + IF (Pos('.',TempFileName) > 0) THEN + FileName := Copy(TempFileName,1,(Pos('.',TempFileName) - 1)); + MemMsgArea.FileName := TempFileName; + CheckMessageArea(MemMsgArea,2,2,Ok); + TempFileName := MemMsgArea.FileName; + IF (Ok) AND (TempFileName <> MemMsgArea.FileName) THEN + BEGIN + RecNum1 := -1; + RecNum := 0; + WHILE (RecNum <= (FileSize(MsgAreaFile) - 1)) AND (RecNum1 = -1) DO + BEGIN + Seek(MsgAreaFile,RecNum); + Read(MsgAreaFile,TempMemMsgArea1); + IF (TempFileName = TempMemMsgArea1.FileName) THEN + BEGIN + Print('%LF^7The file name is already in use!^1'); + RecNum1 := 1; + IF NOT PYNQ('%LFUse this file name anyway? ',0,FALSE) THEN + Ok := FALSE; + END; + Inc(RecNum); + END; + END; + IF (Ok) THEN + BEGIN + Path1 := General.MsgPath+MemMsgArea.FileName; + FileName := TempFileName; + IF (Editing) THEN + BEGIN + Path2 := General.MsgPath+MemMsgArea.FileName; + IF Exist(Path1+'.HDR') AND (NOT Exist(Path2+'.HDR')) THEN + BEGIN + Print('%LFOld HDR/DAT/SCN file names: "^5'+Path1+'.*^1"'); + Print('%LFNew HDR/DAT/SCN file names: "^5'+Path2+'.*^1"'); + IF PYNQ('%LFRename old data files? ',0,FALSE) THEN + BEGIN + CopyMoveFile(FALSE,'%LF^1Renaming "^5'+Path1+'.HDR^1" to "^5'+Path2+'.HDR^1": ',Path1+'.HDR', + Path2+'.HDR',TRUE); + CopyMoveFile(FALSE,'%LF^1Renaming "^5'+Path1+'.DAT^1" to "^5'+Path2+'.DAT^1": ',Path1+'.DAT', + Path2+'.DAT',TRUE); + CopyMoveFile(FALSE,'%LF^1Renaming "^5'+Path1+'.SCN^1" to "^5'+Path2+'.SCN^1": ',Path1+'.SCN', + Path2+'.SCN',TRUE); + END; + END; + END; + END; + UNTIL (Ok) OR (HangUp); + 'C' : BEGIN + TempMemMsgArea1.MAType := MaType; + Print('%LF^5Message area types:^1'); + NL; + LCmds(10,3,'Local',''); + LCmds(10,3,'Echomail',''); + LCmds(10,3,'Groupmail',''); + LCmds(10,3,'QWKmail',''); + LOneK('%LFNew message area type [^5L^4,^5E^4,^5G^4,^5Q^4,^5^4=^5Quit^4]: ',Cmd1,'LEGQ'^M,TRUE,TRUE); + CASE Cmd1 OF + 'L' : MAType := 0; + 'E' : MAType := 1; + 'G' : MAType := 2; + 'Q' : MAType := 3; + END; + IF (MAType IN [1,2]) THEN + BEGIN + IF (MsgPath <> '') THEN + MsgPath := MsgPath + ELSE + MsgPath := General.DefEchoPath+FileName+'\'; + InputPath('%LF^1New message path (^5End with a ^1"^5\^1"):%LF^4:',MsgPath,FALSE,FALSE,Changed); + END; + IF (TempMemMsgArea1.MAtype <> MaType) THEN + BEGIN + IF (MaType IN [0,3]) THEN + BEGIN + MsgPath := ''; + IF (MASKludge IN MAFlags) THEN + Exclude(MAFlags,MASKludge); + IF (MASSeenby IN MAFlags) THEN + Exclude(MAFlags,MASSeenby); + IF (MASOrigin IN MAFlags) THEN + Exclude(MAFlags,MASOrigin); + IF (MAAddTear IN MAFlags) THEN + Exclude(MAFlags,MAAddTear); + END + ELSE + BEGIN + IF (General.SKludge) THEN + Include(MAFlags,MASKludge); + IF (General.SSeenby) THEN + Include(MAFlags,MASSeenby); + IF (General.SOrigin) THEN + Include(MAFlags,MASOrigin); + IF (General.Addtear) THEN + Include(MAFlags,MAAddTear); + END; + IF (MAType = 0) THEN + Origin := '' + ELSE + BEGIN + IF (General.Origin <> '') THEN + Origin := General.Origin; + END; + Changed := TRUE; + END; + Cmd1 := #0; + END; + 'D' : InputWN1('%LFNew ACS: ',ACS,(SizeOf(ACS) - 1),[InterActiveEdit],Changed); + 'E' : BEGIN + InputWN1('%LFNew Post ACS: ',PostACS,(SizeOf(PostACS) - 1),[InterActiveEdit],Changed); + InputWN1('%LFNew MCI ACS: ',MCIACS,(SizeOf(MCIACS) - 1),[InterActiveEdit],Changed); + END; + 'G' : InputWN1('%LFNew SysOp ACS: ',SysOpACS,(SizeOf(SysOpACS) - 1),[InterActiveEdit],Changed); + 'H' : InputWordWC('%LFMax messages',MaxMsgs,[DisplayValue,NumbersOnly],1,65535,Changed); + 'I' : BEGIN + TempMemMsgArea1.Anonymous := Anonymous; + Print('%LF^5Anonymous types:^1'); + NL; + LCmds(40,3,'Yes, Anonymous allowed, selectively',''); + LCmds(40,3,'No, Anonymous not allowed',''); + LCmds(40,3,'Forced Anonymous',''); + LCmds(40,3,'Dear Abby',''); + LCmds(40,3,'Any Name',''); + LOneK('%LFNew anonymous type [^5Y^4,^5N^4,^5F^4,^5D^4,^5A^4,^5^4=^5Quit^4]: ',Cmd1,'YNFDA'^M,TRUE,TRUE); + CASE Cmd1 OF + 'Y' : Anonymous := ATYes; + 'N' : Anonymous := ATNo; + 'F' : Anonymous := ATForced; + 'D' : Anonymous := ATDearAbby; + 'A' : Anonymous := ATAnyName; + END; + IF (TempMemMsgArea1.Anonymous <> Anonymous) THEN + Changed := TRUE; + Cmd1 := #0; + END; + 'K' : InputWN1('%LFNew password: ',Password,(SizeOf(Password) - 1),[InterActiveEdit,UpperOnly],Changed); + 'M' : IF (MAType IN [1,2]) THEN + BEGIN + TempMemMsgArea1.AKA := AKA; + REPEAT + Ok := TRUE; + Print('%LF^5Network addresses:'); + NL; + FOR RecNum := 0 TO 19 DO + BEGIN + Prompt('^1'+PadRightStr(IntToStr(RecNum),2)+'. ^5'+PadLeftStr(NodeStr(RecNum),25)); + IF (Odd(RecNum)) THEN + NL; + END; + InputByteWOC('%LFNew AKA address',AKA,[DisplayValue,NumbersOnly],0,19); + CheckMessageArea(MemMsgArea,4,4,Ok); + IF (NOT Ok) THEN + AKA := TempMemMsgArea1.AKA; + UNTIL (Ok) OR (HangUp); + IF (TempMemMsgArea1.AKA <> AKA) THEN + Changed := TRUE; + END; + 'N' : BEGIN + Prompt('%LF^5Colors: '); + ShowColors; + InputByteWC('%LFNew standard text color',Text_Color,[DisplayValue,NumbersOnly],0,9,Changed); + InputByteWC('%LFNew quoted text color',Quote_Color,[DisplayValue,NumbersOnly],0,9,Changed); + InputByteWC('%LFNew tear line color',Tear_Color,[DisplayValue,NumbersOnly],0,9,Changed); + InputByteWC('%LFNew origin line color',Origin_Color,[DisplayValue,NumbersOnly],0,9,Changed); + END; + 'O' : FindMenu('%LFNew read menu (^50^4=^5Default^4)',MessageReadMenu,0,NumMenus,Changed); + 'P' : IF (MAType IN [1,2]) THEN + BEGIN + REPEAT + LOneK('%LFToggle which network flag ('+DisplayNetFlags(MAFlags,'5','4')+ + '^4) [^5?^4=^5Help^4,^5^4=^5Quit^4]: ',Cmd1,^M'IKSOCBMT?',TRUE,TRUE); + CASE Cmd1 OF + 'K','S','O','T','I' : + ToggleMAFlags(Cmd1,MAFlags,Changed); + '?' : BEGIN + NL; + LCmds(22,3,'Kludge line strip','SEEN-BY line strip'); + LCmds(22,3,'Origin line strip','Tear/Origin line add'); + LCmds(22,3,'Internet flag',''); + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + Cmd1 := #0; + END; + 'R' : IF (MAType IN [1..3]) THEN + REPEAT + OK := TRUE; + InputWN1('%LF^4New origin line:%LF: ',Origin,(SizeOf(Origin) - 1),[InterActiveEdit],Changed); + CheckMessageArea(MemMsgArea,5,5,Ok); + UNTIL (Ok) OR (HangUp); + 'S' : InputWNWC('%LF^1New starting quote:%LF^4: ',QuoteStart,(SizeOf(QuoteStart) - 1),Changed); + 'T' : InputWNWC('%LF^1New ending quote:%LF^4: ',QuoteEnd,(SizeOf(QuoteEnd) - 1),Changed); + 'U' : InputWN1('%LFNew pre-post filename: ',PrePostFile,(SizeOf(PrePostFile) - 1),[],Changed); + 'V' : BEGIN + SaveQWKIndex := QWKIndex; + InputWordWOC('%LFNew permanent QWK Index',QWKIndex,[DisplayValue,NumbersOnly],1,(NumMsgAreas + 1)); + IF (SaveQWKIndex <> QWKIndex) AND (QWKIndex >= 1) AND (QWKIndex <= (NumMsgAreas + 1)) THEN + BEGIN + RecNum1 := -1; + RecNum := 0; + WHILE (RecNum <= (FileSize(MsgAreaFile) - 1)) AND (RecNum1 = -1) DO + BEGIN + Seek(MsgAreaFile,RecNum); + Read(MsgAreaFile,TempMemMsgArea1); + IF (QWKIndex = TempMemMsgArea1.QWKIndex) THEN + BEGIN + Print('%LF^7The QWK Index number is already in use!^1'); + PauseScr(FALSE); + RecNum1 := 1; + QWKIndex := SaveQWKIndex; + END; + Inc(RecNum); + END; + END; + IF (SaveQWKIndex <> QWKIndex) THEN + Changed := TRUE; + END; + 'W' : BEGIN + REPEAT + LOneK('%LFToggle which flag ('+DisplayMAFlags(MAFlags,'5','4')+ + '^4) [^5?^4=^5Help^4,^5^4=^5Quit^4]: ',Cmd1,^M'RUAPFQ?',TRUE,TRUE); + CASE Cmd1 OF + 'R','U','A','P','F','Q' : + ToggleMAFlags(Cmd1,MAFlags,Changed); + '?' : BEGIN + NL; + LCmds(25,3,'Real names','Unhidden'); + LCmds(25,3,'AFilter ANSI/8-bit ASCII','Private msgs allowed'); + LCmds(25,3,'Force Read','Quote/Tagline'); + END; + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + Cmd1 := #0; + END; + '[' : IF (RecNumToEdit > 1) THEN + Dec(RecNumToEdit) + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + ']' : IF (RecNumToEdit < NumMsgAreas) THEN + Inc(RecNumToEdit) + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + 'F' : IF (RecNumToEdit <> 1) THEN + RecNumToEdit := 1 + ELSE + BEGIN + Messages(2,0,''); + Cmd1 := #0; + END; + 'J' : BEGIN + InputIntegerWOC('%LFJump to entry?',RecNumToEdit,[NumbersOnly],1,NumMsgAreas); + IF (RecNumToEdit < 1) OR (RecNumToEdit > NumMsgAreas) THEN + Cmd1 := #0; + END; + 'L' : IF (RecNumToEdit <> NumMsgAreas) THEN + RecNumToEdit := NumMsgAreas + ELSE + BEGIN + Messages(3,0,''); + Cmd1 := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Redisplay current screen'); + Print('^3A^1-^3E^1,^3G^1-^3I^1,^3K^1,^3M^1-^3P^1,^3R^1-^3W^1:Modify item'); + IF (NOT Editing) THEN + LCmds(20,3,'Quit and save','') + ELSE + BEGIN + LCmds(20,3,'[Back entry',']Forward entry'); + LCmds(20,3,'First entry in list','Jump to entry'); + LCmds(20,3,'Last entry in list','Quit and save'); + END; + END; + END; + UNTIL (Pos(Cmd1,'Q[]FJL') <> 0) OR (HangUp); + END; + + PROCEDURE InsertMsgArea(TempMemMsgArea1: MessageAreaRecordType; Cmd1: Char; RecNumToInsertBefore: SmallInt); + VAR + MsgAreaScanFile: FILE OF ScanRec; + RecNum, + RecNum1, + RecNumToEdit: SmallInt; + Ok, + Changed: Boolean; + BEGIN + IF (NumMsgAreas = MaxMsgAreas) THEN + Messages(5,MaxMsgAreas,'message areas') + ELSE + BEGIN + RecNumToInsertBefore := -1; + InputIntegerWOC('%LFMessage area to insert before?',RecNumToInsertBefore,[NumbersOnly],1,(NumMsgAreas + 1)); + IF (RecNumToInsertBefore >= 1) AND (RecNumToInsertBefore <= (NumMsgAreas + 1)) THEN + BEGIN + Reset(MsgAreaFile); + + Assign(MsgAreaDefFile,General.DataPath+'MBASES.DEF'); + IF (NOT Exist(General.DataPath+'MBASES.DEF')) THEN + InitMsgAreaVars(TempMemMsgArea1) + ELSE + BEGIN + Reset(MsgAreaDefFile); + Seek(MsgAreaDefFile,0); + Read(MsgAreaDefFile,TempMemMsgArea1); + Close(MsgAreaDefFile); + END; + + TempMemMsgArea1.QWKIndex := (FileSize(MsgAreaFile) + 1); + IF (RecNumToInsertBefore = 1) THEN + RecNumToEdit := 1 + ELSE IF (RecNumToInsertBefore = (NumMsgAreas + 1)) THEN + RecNumToEdit := (NumMsgAreas + 1) + ELSE + RecNumToEdit := RecNumToInsertBefore; + REPEAT + OK := TRUE; + EditMessageArea(TempMemMsgArea1,TempMemMsgArea1,Cmd1,RecNumToEdit,Changed,FALSE); + CheckMessageArea(TempMemMsgArea1,1,5,Ok); + IF (NOT OK) THEN + IF (NOT PYNQ('%LFContinue inserting message area? ',0,TRUE)) THEN + Abort := TRUE; + UNTIL (OK) OR (Abort) OR (HangUp); + IF (NOT Abort) AND (PYNQ('%LFIs this what you want? ',0,FALSE)) THEN + BEGIN + Print('%LF[> Inserting message area record ...'); + Seek(MsgAreaFile,FileSize(MsgAreaFile)); + Write(MsgAreaFile,MemMsgArea); + Dec(RecNumToInsertBefore); + FOR RecNum := ((FileSize(MsgAreaFile) - 1) - 1) DOWNTO RecNumToInsertBefore DO + BEGIN + Seek(MsgAreaFile,RecNum); + Read(MsgAreaFile,MemMsgArea); + Seek(MsgAreaFile,(RecNum + 1)); + Write(MsgAreaFile,MemMsgArea); + END; + FOR RecNum := RecNumToInsertBefore TO ((RecNumToInsertBefore + 1) - 1) DO + BEGIN + IF (TempMemMsgArea1.MAType IN [1,2]) THEN + MakeDir(TempMemMsgArea1.MsgPath,FALSE); + IF (NOT Exist(General.MsgPath+TempMemMsgArea1.FileName+'.HDR')) THEN + BEGIN + Assign(MsgHdrF,General.MsgPath+TempMemMsgArea1.FileName+'.HDR'); + ReWrite(MsgHdrF); + Close(MsgHdrF); + END; + IF (NOT Exist(General.MsgPath+TempMemMsgArea1.FileName+'.DAT')) THEN + BEGIN + Assign(MsgTxtF,General.MsgPath+TempMemMsgArea1.FileName+'.DAT'); + ReWrite(MsgTxtF,1); + Close(MsgTxtF); + END; + IF (NOT Exist(General.MsgPath+TempMemMsgArea1.FileName+'.SCN')) THEN + BEGIN + Assign(MsgAreaScanFile,General.MsgPath+TempMemMsgArea1.FileName+'.SCN'); + ReWrite(MsgAreaScanFile); + Close(MsgAreaScanFile); + END; + IF (Exist(General.MsgPath+TempMemMsgArea1.FileName+'.SCN')) THEN + BEGIN + Assign(MsgAreaScanFile,General.MsgPath+TempMemMsgArea1.FileName+'.SCN'); + Reset(MsgAreaScanFile); + WITH LastReadRecord DO + BEGIN + LastRead := 0; + NewScan := TRUE; + END; + FOR RecNum1 := (FileSize(MsgAreaScanFile) + 1) TO (MaxUsers - 1) DO + Write(MsgAreaScanFile,LastReadRecord); + Close(MsgAreaScanFile); + END; + Seek(MsgAreaFile,RecNum); + Write(MsgAreaFile,TempMemMsgArea1); + Inc(NumMsgAreas); + SysOpLog('* Inserted message area: ^5'+TempMemMsgArea1.Name); + END; + END; + Close(MsgAreaFile); + LastError := IOResult; + END; + END; + END; + + PROCEDURE ModifyMsgArea(TempMemMsgArea1: MessageAreaRecordType; Cmd1: Char; RecNumToEdit: SmallInt); + VAR + User: UserRecordType; + MsgAreaScanFile: FILE OF ScanRec; + RecNum1, + SaveRecNumToEdit: Integer; + Ok, + Changed: Boolean; + BEGIN + RecNumToEdit := -1; + InputIntegerWOC('%LFModify which message area?',RecNumToEdit,[NumbersOnly],0,NumMsgAreas); + IF ((RecNumToEdit >= 0) AND (RecNumToEdit <= NumMsgAreas)) THEN + BEGIN + SaveRecNumToEdit := -1; + Cmd1 := #0; + IF (RecNumToEdit = 0) THEN + BEGIN + Assign(EMailFile,General.DataPath+'MEMAIL.DAT'); + Reset(EmailFile); + END + ELSE + BEGIN + Assign(MsgAreaFile,General.DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + END; + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNumToEdit <> RecNumToEdit) THEN + BEGIN + IF (RecNumToEdit = 0) THEN + BEGIN + Seek(EMailFile,0); + Read(EMailFile,MemMsgArea); + END + ELSE + BEGIN + Seek(MsgAreaFile,(RecNumToEdit - 1)); + Read(MsgAreaFile,MemMsgArea); + END; + SaveRecNumToEdit := RecNumToEdit; + Changed := FALSE; + END; + REPEAT + Ok := TRUE; + EditMessageArea(TempMemMsgArea1,MemMsgArea,Cmd1,RecNumToEdit,Changed,TRUE); + CheckMessageArea(MemMsgArea,1,5,Ok); + IF (NOT OK) THEN + BEGIN + PauseScr(FALSE); + IF (RecNumToEdit <> SaveRecNumToEdit) THEN + RecNumToEdit := SaveRecNumToEdit; + END; + UNTIL (Ok) OR (HangUp); + IF (MemMsgArea.MAType IN [1,2]) THEN + MakeDir(MemMsgArea.MsgPath,FALSE); + IF (NOT Exist(General.MsgPath+MemMsgArea.FileName+'.HDR')) THEN + BEGIN + Assign(MsgHdrF,General.MsgPath+MemMsgArea.FileName+'.HDR'); + ReWrite(MsgHdrF); + Close(MsgHdrF); + END; + IF (NOT Exist(General.MsgPath+MemMsgArea.FileName+'.DAT')) THEN + BEGIN + Assign(MsgTxtF,General.MsgPath+MemMsgArea.FileName+'.DAT'); + ReWrite(MsgTxtF,1); + Close(MsgTxtF); + END; + IF (RecNumToEdit <> 0) THEN + BEGIN + IF (NOT Exist(General.MsgPath+MemMsgArea.FileName+'.SCN')) THEN + BEGIN + Assign(MsgAreaScanFile,General.MsgPath+MemMsgArea.FileName+'.SCN'); + ReWrite(MsgAreaScanFile); + Close(MsgAreaScanFile); + END; + IF (Exist(General.MsgPath+MemMsgArea.FileName+'.SCN')) THEN + BEGIN + Assign(MsgAreaScanFile,General.MsgPath+MemMsgArea.FileName+'.SCN'); + Reset(MsgAreaScanFile); + WITH LastReadRecord DO + BEGIN + LastRead := 0; + NewScan := TRUE; + END; + Seek(MsgAreaScanFile,FileSize(MsgAreaScanFile)); + FOR RecNum1 := (FileSize(MsgAreaScanFile) + 1) TO (MaxUsers - 1) DO + Write(MsgAreaScanFile,LastReadRecord); + Reset(UserFile); + FOR RecNum1 := 1 TO (MaxUsers - 1) DO + BEGIN + LoadURec(User,RecNum1); + IF (Deleted IN User.SFlags) THEN + BEGIN + Seek(MsgAreaScanFile,(RecNum1 - 1)); + Write(MsgAreaScanFile,LastReadRecord); + END; + END; + Close(UserFile); + Close(MsgAreaScanFile); + END; + END; + IF (Changed) THEN + BEGIN + IF (RecNumToEdit = 0) THEN + BEGIN + Seek(EMailFile,0); + Write(EMailFile,MemMsgArea); + END + ELSE + BEGIN + Seek(MsgAreaFile,(SaveRecNumToEdit - 1)); + Write(MsgAreaFile,MemMsgArea); + END; + SysOpLog('* Modified message area: ^5'+MemMsgArea.Name); + END; + END; + IF (RecNumToEdit = 0) THEN + Close(EmailFile) + ELSE + Close(MsgAreaFile); + LastError := IOResult; + END; + END; + + PROCEDURE PositionMsgArea(TempMemMsgArea1: MessageAreaRecordType; RecNumToPosition: SmallInt); + VAR + RecNumToPositionBefore, + RecNum1, + RecNum2: SmallInt; + BEGIN + IF (NumMsgAreas = 0) THEN + Messages(4,0,'message areas') + ELSE IF (NumMsgAreas = 1) THEN + Messages(6,0,'message areas') + ELSE + BEGIN + RecNumToPosition := -1; + InputIntegerWOC('%LFPosition which message area?',RecNumToPosition,[NumbersOnly],1,NumMsgAreas); + IF (RecNumToPosition >= 1) AND (RecNumToPosition <= NumMsgAreas) THEN + BEGIN + RecNumToPositionBefore := -1; + Print('%LFAccording to the current numbering system.'); + InputIntegerWOC('%LFPosition before which message area?',RecNumToPositionBefore,[NumbersOnly],1,(NumMsgAreas + 1)); + IF (RecNumToPositionBefore >= 1) AND (RecNumToPositionBefore <= (NumMsgAreas + 1)) AND + (RecNumToPositionBefore <> RecNumToPosition) AND (RecNumToPositionBefore <> (RecNumToPosition + 1)) THEN + BEGIN + Print('%LF[> Positioning message area records ...'); + IF (RecNumToPositionBefore > RecNumToPosition) THEN + Dec(RecNumToPositionBefore); + Dec(RecNumToPosition); + Dec(RecNumToPositionBefore); + Reset(MsgAreaFile); + Seek(MsgAreaFile,RecNumToPosition); + Read(MsgAreaFile,TempMemMsgArea1); + RecNum1 := RecNumToPosition; + IF (RecNumToPosition > RecNumToPositionBefore) THEN + RecNum2 := -1 + ELSE + RecNum2 := 1; + WHILE (RecNum1 <> RecNumToPositionBefore) DO + BEGIN + IF ((RecNum1 + RecNum2) < FileSize(MsgAreaFile)) THEN + BEGIN + Seek(MsgAreaFile,(RecNum1 + RecNum2)); + Read(MsgAreaFile,MemMsgArea); + Seek(MsgAreaFile,RecNum1); + Write(MsgAreaFile,MemMsgArea); + END; + Inc(RecNum1,RecNum2); + END; + Seek(MsgAreaFile,RecNumToPositionBefore); + Write(MsgAreaFile,TempMemMsgArea1); + Close(MsgAreaFile); + LastError := IOResult; + END; + END; + END; + END; + + PROCEDURE RenumberQWKIndex; + VAR + RecNum: Integer; + BEGIN + IF (NumMsgAreas = 0) THEN + Messages(4,0,'message areas') + ELSE + BEGIN + IF PYNQ('%LFRenumber QWK Index for all message areas? ',0,FALSE) THEN + BEGIN + Prompt('%LFRenumbering the QWK index''s for all areas ... '); + Reset(MsgAreaFile); + RecNum := 1; + WHILE (RecNum <= NumMsgAreas) DO + BEGIN + Seek(MsgAreaFile,(RecNum - 1)); + Read(MsgAreaFile,MemMsgArea); + MemMsgArea.QWKIndex := RecNum; + Seek(MsgAreaFile,(RecNum - 1)); + Write(MsgAreaFile,MemMsgArea); + Inc(RecNum); + END; + Close(MsgAreaFile); + LastError := IOResult; + Print('Done'); + SysOpLog('* Renumbered the QWK index for all message areas.'); + END; + END; + END; + + PROCEDURE DisplayMsgArea(RecNumToList1: Integer); + BEGIN + WITH MemMsgArea DO + CASE DisplayType OF + 1 : PrintACR('^0'+PadRightInt(RecNumToList1,5)+ + ' ^5'+PadLeftStr(Name,24)+ + ' ^3'+Copy('LEGQ',(MAType + 1),1)+DisplayMAFlags(MAFlags,'5','4')+ + ' ^9'+PadLeftStr(AOnOff(ACS = '','*None*',ACS),10)+ + ' '+PadLeftStr(AOnOff(PostACS = '','*None*',PostACS),9)+ + ' '+PadLeftStr(AOnOff(MCIACS = '','*None*',MCIACS),9)+ + ' ^3'+PadLeftInt(MaxMsgs,6)+ + ' '+AnonTypeChar(Anonymous)); + 2 : PrintACR('^0'+PadRightInt(RecNumToList1,5)+ + ' ^5'+PadLeftStr(Name,27)+ + ' ^3'+PadLeftStr(AOnOff(MAType IN [0,3],'*None*',NodeStr(AKA)),11)+ + ' '+PadLeftStr(AOnOff(MsgPath = '','*None*',MsgPath),33)); + END; + END; + + PROCEDURE ListMsgAreas(VAR RecNumToList1: SmallInt); + VAR + NumDone: Integer; + BEGIN + IF (RecNumToList1 < 0) OR (RecNumToList1 > NumMsgAreas) THEN + RecNumToList1 := 0; + MCIAllowed := FALSE; + Abort := FALSE; + Next := FALSE; + CLS; + CASE DisplayType OF + 1 : BEGIN + PrintACR('^0#####^4:^3Message area name ^4:^3Flag ^4:^3ACS ^4:^3Post ACS ^4:^3MCI ACS'+ + ' ^4:^3MaxM ^4:^3A'); + PrintACR('^4=====:========================:=======:==========:=========:=========:======:='); + END; + 2 : BEGIN + PrintACR('^0#####^4:^3Message area name ^4:^3Address ^4:^3Message path'); + PrintACR('^4=====:===========================:===========:================================='); + END; + END; + IF (RecNumToList1 = 0) THEN + BEGIN + NumDone := 0; + Assign(EmailFile,General.DataPath+'MEMAIL.DAT'); + Reset(EMailFile); + Seek(EmailFile,RecNumToList1); + Read(EMailFile,MemMsgArea); + DisplayMsgArea(RecNumToList1); + Close(EmailFile); + LastError := IOResult; + RecNumToList := 1; + END; + Assign(MsgAreaFile,General.DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + NumDone := 1; + WHILE (NumDone < (PageLength - 5)) AND (RecNumToList1 >= 1) AND (RecNumToList1 <= NumMsgAreas) + AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(MsgAreaFile,(RecNumToList1 - 1)); + Read(MsgAreaFile,MemMsgArea); + DisplayMsgArea(RecNumToList1); + Inc(RecNumToList1); + Inc(NumDone); + END; + Close(MsgAreaFile); + LastError := IOResult; + MCIAllowed := TRUE; + END; + +BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + RecNumToList := 0; + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + ListMsgAreas(RecNumToList); + LOneK('%LFMessage area editor [^5?^4=^5Help^4]: ',Cmd,'QCDIMPRTX?'^M,TRUE,TRUE); + CASE Cmd OF + ^M : IF (RecNumToList < 0) OR (RecNumToList > NumMsgAreas) THEN + RecNumToList := 0; + 'C' : ChangeMsgAreaDrive(Cmd,RecNumToList); + 'D' : DeleteMsgArea(TempMemMsgArea,RecNumToList); + 'I' : InsertMsgArea(TempMemMsgArea,Cmd,RecNumToList); + 'M' : ModifyMsgArea(TempMemMsgArea,Cmd,RecNumToList); + 'P' : PositionMsgArea(TempMemMsgArea,RecNumToList); + 'R' : ReNumberQWKIndex; + 'T' : DisplayType := ((DisplayType MOD 2) + 1); + 'X' : BEGIN + Assign(MsgAreaDefFile,General.DataPath+'MBASES.DEF'); + IF (Exist(General.DataPath+'MBASES.DEF')) THEN + BEGIN + Reset(MsgAreaDefFile); + Seek(MsgAreaDefFile,0); + Read(MsgAreaDefFile,MemMsgArea); + END + ELSE + BEGIN + ReWrite(MsgAreaDefFile); + InitMsgAreaVars(MemMsgArea); + END; + RecNumToList := -1; + EditMessageArea(TempMemMsgArea,MemMsgArea,Cmd,RecNumToList,Changed,FALSE); + Seek(MsgAreaDefFile,0); + Write(MsgAreaDefFile,MemMsgArea); + Close(MsgAreaDefFile); + Cmd := #0; + END; + '?' : BEGIN + Print('%LF^1<^3CR^1>Next screen or redisplay current screen'); + Print('^1(^3?^1)Help/First message area'); + LCmds(22,3,'Change message storage drive',''); + LCmds(22,3,'Delete message area','Insert message area'); + LCmds(22,3,'Modify message area','Position message area'); + LCmds(22,3,'Quit','Renumber QWK index'); + LCmds(22,3,'Toggle display format','XDefault configuration'); + END; + END; + IF (Cmd <> ^M) THEN + RecNumToList := 0; + UNTIL (Cmd = 'Q') OR (HangUp); + TempPause := SaveTempPause; + NewComptables; + IF ((MsgArea < 1) OR (MsgArea > NumMsgAreas)) THEN + MsgArea := 1; + ReadMsgArea := -1; + LoadMsgArea(MsgArea); + LastError := IOResult; +END; + +END. + diff --git a/SOURCE/SYSOP9.PAS b/SOURCE/SYSOP9.PAS new file mode 100644 index 0000000..45f7ed8 --- /dev/null +++ b/SOURCE/SYSOP9.PAS @@ -0,0 +1,1266 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} +UNIT SysOp9; + +INTERFACE + +PROCEDURE FileAreaEditor; + +IMPLEMENTATION + +USES + Common, + File0, + File2, + SysOp2K; + +PROCEDURE FileAreaEditor; +TYPE + MCIVarRecord = Record + OldPath, + NewPath: AStr; + Drive: Char; + FirstRecNum, + LastRecNum, + RecNumToEdit: SmallInt; + END; + +CONST + DisplayType: Byte = 1; + +VAR + TempMemFileArea: FileAreaRecordType; + MCIVars: MCIVarRecord; + Cmd: Char; + RecNumToList: Integer; + SaveTempPause: Boolean; + + FUNCTION DisplayFAFlags(FAFlags: FAFlagSet; C1,C2: Char): AStr; + VAR + FAFlagT: FileAreaFlagType; + DisplayStr: AStr; + BEGIN + DisplayStr := ''; + FOR FAFlagT := FANoRatio TO FANoDupeCheck DO + BEGIN + IF (FAFlagT IN FAFlags) THEN + DisplayStr := DisplayStr + '^'+C1+Copy('NUISGCDP',(Ord(FAFlagT) + 1),1) + ELSE + DisplayStr := DisplayStr + '^'+C2+'-' + END; + DisplayFAFlags := DisplayStr; + END; + + PROCEDURE ToggleFAFlag(FAFlagT: FileAreaFlagType; VAR FAFlags: FAFlagSet); + BEGIN + IF (FAFlagT IN FAFlags) THEN + Exclude(FAFlags,FAFlagT) + ELSE + Include(FAFlags,FAFlagT); + END; + + PROCEDURE ToggleFAFlags(C: Char; VAR FAFlags: FAFlagSet; VAR Changed: Boolean); + VAR + SaveFAFlags: FAFlagSet; + BEGIN + SaveFAFlags := FAFlags; + CASE C OF + 'N' : ToggleFAFlag(FANoRatio,FAFlags); + 'U' : ToggleFAFlag(FAUnHidden,FAFlags); + 'I' : ToggleFAFlag(FADirDLPath,FAFlags); + 'S' : ToggleFAFlag(FAShowName,FAFlags); + 'G' : ToggleFAFlag(FAUseGIFSpecs,FAFlags); + 'C' : ToggleFAFlag(FACDRom,FAFlags); + 'D' : ToggleFAFlag(FAShowDate,FAFlags); + 'P' : ToggleFAFlag(FANoDupeCheck,FAFlags); + END; + IF (FAFlags <> SaveFAFlags) THEN + Changed := TRUE; + END; + + PROCEDURE InitFileAreaVars(VAR MemFileArea: FileAreaRecordType); + BEGIN + FillChar(MemFileArea,SizeOf(MemFileArea),0); + WITH MemFileArea DO + BEGIN + AreaName := '<< New File Area >>'; + FileName := 'NEWDIR'; + DLPath := StartDir[1]+':\'; + ULPath := DLPath; + MaxFiles := 2000; + Password := ''; + ArcType := 0; + CmtType := 0; + ACS := ''; + ULACS := ''; + DLACS := ''; + FAFlags := []; + END; + END; + + FUNCTION FAEMCI(CONST S: STRING; MemFileArea: FileAreaRecordType; MCIVars1: MCIVarRecord): STRING; + VAR + Temp: STRING; + Add: AStr; + Index: Byte; + BEGIN + Temp := ''; + FOR Index := 1 TO Length(S) DO + IF (S[Index] = '%') AND (Index + 1 < Length(S)) THEN + BEGIN + Add := '%' + S[Index + 1] + S[Index + 2]; + CASE UpCase(S[Index + 1]) OF + 'A' : CASE UpCase(S[Index + 2]) OF + 'N' : Add := MemFileArea.AreaName; + 'R' : Add := AOnOff((MemFileArea.ACS = ''),'*None*',MemFileArea.ACS); + 'T' : Add := AOnOff((MemFileArea.ArcType = 0),'*None*',General.FileArcInfo[MemFileArea.ArcType].Ext); + END; + 'C' : CASE UpCase(S[Index + 2]) OF + 'T' : Add := +AOnOff((MemFileArea.CmtType = 0),'*None*',IntToStr(MemFileArea.CmtType)); + END; + 'D' : CASE UpCase(S[Index + 2]) OF + 'D' : Add := MCIVars1.Drive; + 'P' : Add := MemFileArea.DLPath; + 'R' : Add := AOnOff((MemFileArea.DLACS = ''),'*None*',MemFileArea.DLACS); + END; + 'F' : CASE UpCase(S[Index + 2]) OF + 'N' : Add := MemFileArea.FileName; + 'R' : Add := IntToStr(MCIVars1.FirstRecNum); + 'S' : Add := DisplayFAFlags(MemFileArea.FAFlags,'5','1'); + 'T' : Add := DisplayFAFlags(MemFileArea.FAFlags,'5','4'); + END; + 'G' : CASE UpCase(S[Index + 2]) OF + 'D' : Add := GetDirPath(MemFileArea); + END; + 'L' : CASE UpCase(S[Index + 2]) OF + 'R' : Add := IntToStr(MCIVars1.LastRecNum); + END; + 'M' : CASE UpCase(S[Index + 2]) OF + 'A' : Add := IntToStr(MaxFileAreas); + 'F' : Add := IntToStr(MemFileArea.MaxFiles); + END; + 'N' : CASE UpCase(S[Index + 2]) OF + 'A' : Add := IntToStr(NumFileAreas); + 'F' : Add := IntToStr(NumFileAreas + 1); + 'P' : Add := MCIVars1.NewPath; + END; + 'O' : CASE UpCase(S[Index + 2]) OF + 'P' : Add := MCIVars1.OldPath; + END; + 'P' : CASE UpCase(S[Index + 2]) OF + 'W' : Add := AOnOff((MemFileArea.Password = ''),'*None*',MemFileArea.Password); + END; + 'R' : CASE UpCase(S[Index + 2]) OF + 'E' : Add := IntToStr(MCIVars1.RecNumToEdit); + END; + 'U' : CASE UpCase(S[Index + 2]) OF + 'P' : Add := MemFileArea.ULPath; + 'R' : Add := AOnOff((MemFileArea.ULACS = ''),'*None*',MemFileArea.ULACS); + END; + END; + Temp := Temp + Add; + Inc(Index,2); + END + ELSE + Temp := Temp + S[Index]; + FAEMCI := Temp; + END; + + FUNCTION FAELngStr(StrNum: LongInt; MemFileArea: FileAreaRecordType; MCIVars1: MCIVarRecord; PassValue: Boolean): AStr; + VAR + StrPointerFile: FILE OF StrPointerRec; + StrPointer: StrPointerRec; + RGStrFile: FILE; + S: STRING; + TotLoad: LongInt; + Found: Boolean; + BEGIN + Assign(StrPointerFile,General.LMultPath+'FAEPR.DAT'); + Reset(StrPointerFile); + Seek(StrPointerFile,StrNum); + Read(StrPointerFile,StrPointer); + Close(StrPointerFile); + LastError := IOResult; + TotLoad := 0; + Assign(RGStrFile,General.LMultPath+'FAETX.DAT'); + Reset(RGStrFile,1); + Seek(RGStrFile,(StrPointer.Pointer - 1)); + REPEAT + BlockRead(RGStrFile,S[0],1); + BlockRead(RGStrFile,S[1],Ord(S[0])); + Inc(TotLoad,(Length(S) + 1)); + S := FAEMCI(S,MemFileArea,MCIVars1); + IF (PassValue) THEN + BEGIN + IF (S[Length(s)] = '@') THEN + Dec(S[0]); + END + ELSE + BEGIN + IF (S[Length(S)] = '@') THEN + BEGIN + Dec(S[0]); + Prompt(S); + END + ELSE + PrintACR(S); + END; + UNTIL (TotLoad >= StrPointer.TextSize) OR (Abort) OR (HangUp); + Close(RGStrFile); + LastError := IOResult; + FAELNGStr := S; + END; + + { + ChangeFileArea External String Table + + 1. NO_FILE_AREAS + + %LF^7No file areas exist!^1 + %PA + + 2. FILE_CHANGE_DRIVE_START + + %LFFile area to start at? @ + + 3. FILE_CHANGE_DRIVE_END + + %LFFile area to end at?' @ + + 4. FILE_CHANGE_INVALID_ORDER + + %LF^7Invalid record number order!^1 + %PA + + 5. FILE_CHANGE_DRIVE_DRIVE + + %LFChange to which drive? (^5A^4-^5Z^4): @ + + 6. FILE_CHANGE_INVALID_DRIVE + + %LF^7Invalid drive!^1 + %PA + + 7. FILE_CHANGE_UPDATING_DRIVE + + %LFUpdating the drive for file area %FR to %LR ... + + 8. FILE_CHANGE_UPDATING_DRIVE_DONE + + Done! + + 9. FILE_CHANGE_UPDATING_SYSOPLOG + + * Changed file areas: ^5%FR^1-^5%LR^1 to ^5%DD:\ + } + + PROCEDURE ChangeFileAreaDrive(MCIVars1: MCIVarRecord); + VAR + RecNum: Integer; + BEGIN + IF (NumFileAreas = 0) THEN + FAELngStr(5,MemFileArea,MCIVars1,FALSE) + ELSE + BEGIN + MCIVars1.FirstRecNum := -1; + InputIntegerWOC(FAELngStr(6,MemFileArea,MCIVars1,TRUE),MCIVars1.FirstRecNum,[NumbersOnly],1,NumFileAreas); + IF (MCIVars1.FirstRecNum >= 1) AND (MCIVars1.FirstRecNum <= NumFileAreas) THEN + BEGIN + MCIVars1.LastRecNum := -1; + InputIntegerWOC(FAELngStr(7,MemFileArea,MCIVars1,TRUE),MCIVars1.LastRecNum,[NumbersOnly],1,NumFileAreas); + IF (MCIVars1.LastRecNum >= 1) AND (MCIVars1.LastRecNum <= NumFileAreas) THEN + BEGIN + IF (MCIVars1.FirstRecNum > MCIVars1.LastRecNum) OR (MCIVars1.LastRecNum < MCIVars1.FirstRecNum) THEN + FAELngStr(9,MemFileArea,MCIVars1,FALSE) + ELSE + BEGIN + LOneK(FAELngStr(8,MemFileArea,MCIVars1,TRUE),MCIVars1.Drive,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'^M,TRUE,TRUE); + ChDir(MCIVars1.Drive+':'); + IF (IOResult <> 0) THEN + FAELngStr(10,MemFileArea,MCIVars1,FALSE) + ELSE + BEGIN + ChDir(StartDir); + FAELngStr(11,MemFileArea,MCIVars1,FALSE); + Reset(FileAreaFile); + FOR RecNum := MCIVars1.FirstRecNum TO MCIVars1.LastRecNum DO + BEGIN + Seek(FileAreaFile,(RecNum - 1)); + Read(FileAreaFile,MemFileArea); + MemFileArea.ULPath[1] := MCIVars1.Drive; + MemFileArea.DLPath[1] := MCIVars1.Drive; + Seek(FileAreaFile,(RecNum - 1)); + Write(FileAreaFile,MemFileArea); + END; + Close(FileAreaFile); + LastError := IOResult; + FAELngStr(12,MemFileArea,MCIVars1,FALSE); + FAELngStr(13,MemFileArea,MCIVars1,FALSE); + END; + END; + END; + END; + END; + END; + + { + DeleteFileArea External String Table + + 1. NO_FILE_AREAS + + %LF^7No file areas exist!^1 + %PA + + 2. FILE_DELETE_PROMPT + + %LFFile area to delete? @ + + 3. FILE_DELETE_DISPLAY_AREA + + %LFFile area: ^5%AN^1 + + 4. FILE_DELETE_VERIFY_DELETE + + %LFAre you sure you want to delete it? @ + + 5. FILE_DELETE_NOTICE + + %LF[> Deleting file area ... + + 6. FILE_DELETE_SYSOPLOG + + * Deleted file area: ^5%AN + + 7. FILE_DELETE_DATA_FILES + + %LFDelete file area data files also? @ + + 8. FILE_DELETE_REMOVE_DL_DIRECTORY + + %LFRemove the download directory? @ + + 9. FILE_DELETE_REMOVE_UL_DIRECTORY + + %LFRemove the upload directory? @ + } + + + PROCEDURE DeleteFileArea(TempMemFileArea1: FileAreaRecordType; MCIVars1: MCIVarRecord); + VAR + RecNum, + RecNumToDelete: SmallInt; + Ok, + OK1, + Ok2: Boolean; + BEGIN + IF (NumFileAreas = 0) THEN + FAELngStr(5,MemFileArea,MCIVars1,FALSE) + ELSE + BEGIN + RecNumToDelete := -1; + InputIntegerWOC(FAELngStr(14,MemFileArea,MCIVars1,TRUE),RecNumToDelete,[NumbersOnly],1,NumFileAreas); + IF (RecNumToDelete >= 1) AND (RecNumToDelete <= NumFileAreas) THEN + BEGIN + Reset(FileAreaFile); + Seek(FileAreaFile,(RecNumToDelete - 1)); + Read(FileAreaFile,TempMemFileArea1); + Close(FileAreaFile); + LastError := IOResult; + FAELngStr(15,TempMemFileArea1,MCIVars1,FALSE); + IF PYNQ(FAELngStr(16,MemFileArea,MCIVars1,TRUE),0,FALSE) THEN + BEGIN + FAELngStr(17,MemFileArea,MCIVars1,FALSE); + Dec(RecNumToDelete); + Reset(FileAreaFile); + IF (RecNumToDelete >= 0) AND (RecNumToDelete <= (FileSize(FileAreaFile) - 2)) THEN + FOR RecNum := RecNumToDelete TO (FileSize(FileAreaFile) - 2) DO + BEGIN + Seek(FileAreaFile,(RecNum + 1)); + Read(FileAreaFile,MemFileArea); + Seek(FileAreaFile,RecNum); + Write(FileAreaFile,MemFileArea); + END; + Seek(FileAreaFile,(FileSize(FileAreaFile) - 1)); + Truncate(FileAreaFile); + Close(FileAreaFile); + LastError := IOResult; + Dec(NumFileAreas); + SysOpLog(FAELngStr(18,TempMemFileArea1,MCIVars1,TRUE)); + Ok := TRUE; + Ok1 := TRUE; + OK2 := TRUE; + Reset(FileAreaFile); + FOR RecNum := 1 TO FileSize(FileAreaFile) DO + BEGIN + Seek(FileAreaFile,(RecNum - 1)); + Read(FileAreaFile,MemFileArea); + IF (MemFileArea.FileName = TempMemFileArea1.FileName) THEN + Ok := FALSE; + IF (MemFileArea.DLPath = TempMemFileArea1.DLPath) THEN + Ok1 := FALSE; + IF (MemFileArea.ULPath = TempMemFileArea1.ULPath) THEN + Ok2 := FALSE; + END; + Close(FileAreaFile); + IF (Ok) AND (PYNQ(FAELngStr(19,TempMemFileArea1,MCIVars1,TRUE),0,FALSE)) THEN + BEGIN + Kill(GetDirPath(TempMemFileArea1)+'.DIR'); + Kill(GetDirPath(TempMemFileArea1)+'.EXT'); + Kill(GetDirPath(TempMemFileArea1)+'.SCN'); + END; + IF (Ok1) AND (ExistDir(TempMemFileArea1.DLPath)) THEN + IF PYNQ(FAELngStr(20,TempMemFileArea1,MCIVars1,TRUE),0,FALSE) THEN + PurgeDir(TempMemFileArea1.DLPath,TRUE); + IF (Ok2) AND (ExistDir(TempMemFileArea1.ULPath)) THEN + IF PYNQ(FAELngStr(21,TempMemFileArea1,MCIVars1,TRUE),0,FALSE) THEN + PurgeDir(TempMemFileArea1.ULPath,TRUE); + END; + END; + END; + END; + + { + DeleteFileArea External String Table + + 1. CHECK_AREA_NAME_ERROR + + %LF^7The area name is invalid!^1 + + 2. CHECK_FILE_NAME_ERROR + + %LF^7The file name is invalid!^1' + + 3. CHECK_DL_PATH_ERROR + + %LF^7The download path is invalid!^1 + + 4. CHECK_UL_PATH_ERROR + + %LF^7The upload path is invalid!^1 + + 5. CHECK_ARCHIVE_TYPE_ERROR + + %LF^7The archive type is invalid!^1 + + 6. CHECK_COMMENT_TYPE_ERROR + + %LF^7The comment type is invalid!^1 + + } + + PROCEDURE CheckFileArea(MemFileArea: FileAreaRecordType; + MCIVars1: MCIVarRecord; + StartErrMsg, + EndErrMsg: Byte; + VAR Ok: Boolean); + VAR + Counter: Byte; + BEGIN + FOR Counter := StartErrMsg TO EndErrMsg DO + CASE Counter OF + 1 : IF (MemFileArea.AreaName = '') OR (MemFileArea.AreaName = '<< New File Area >>') THEN + BEGIN + FAELngStr(65,MemFileArea,MCIVars1,FALSE); + OK := FALSE; + END; + 2 : IF (MemFileArea.FileName = '') OR (MemFileArea.FileName = 'NEWDIR') THEN + BEGIN + FAELngStr(66,MemFileArea,MCIVars1,FALSE); + OK := FALSE; + END; + 3 : IF (MemFileArea.DLPath = '') THEN + BEGIN + FAELngStr(67,MemFileArea,MCIVars1,FALSE); + OK := FALSE; + END; + 4 : IF (MemFileArea.ULPath = '') THEN + BEGIN + FAELngStr(68,MemFileArea,MCIVars1,FALSE); + OK := FALSE; + END; + 5 : IF (MemFileArea.ArcType <> 0) AND (NOT General.FileArcInfo[MemFileArea.ArcType].Active) THEN + BEGIN + FAELngStr(69,MemFileArea,MCIVars1,FALSE); + OK := FALSE; + END; + 6 : IF (MemFileArea.CmtType <> 0) AND (General.FileArcComment[MemFileArea.CmtType] = '') THEN + BEGIN + FAELngStr(70,MemFileArea,MCIVars1,FALSE); + OK := FALSE; + END; + END; + END; + + { + DeleteFileArea External String Table + + 1. FILE_EDITING_AREA_HEADER + + ^5Editing file area #%RE of %NA + + 2. FILE_INSERTING_AREA_HEADER + + ^5Inserting file area #%RE of %NF + + 3. FILE_EDITING_INSERTING_SCREEN + + %LF^11. Area name : ^5%AN + ^12. File name : ^5%FN ^7(%GD.*) + ^13. DL path : ^5%DP + ^14. UL path : ^5%UP + ^15. ACS required: ^5%AR + ^16. DL/UL ACS : ^5%DR^1 / ^5%UR + ^17. Max files : ^5%MF + ^18. Password : ^5%PW + ^19. Arc/cmt type: ^5%AT^1 / ^5%CT + ^1T. Flags : ^5%FS + + 4. FILE_EDITING_INSERTING_PROMPT + + %LFModify menu [^5?^4=^5Help^4]: @ + + 5. FILE_AREA_NAME_CHANGE + + %LFNew area name: @ + + 6. FILE_FILE_NAME_CHANGE + + %LFNew file name (^5Do not enter ^4"^5.EXT^4"): @ + + 7. FILE_DUPLICATE_FILE_NAME_ERROR + + %LF^7The file name is already in use!^1 + + 8. FILE_USE_DUPLICATE_FILE_NAME + + %LFUse this file name anyway? @ + + 9. FILE_OLD_DATA_FILES_PATH + + %LFOld DIR/EXT/SCN file names: "^5%OP.*^1" + + 10. FILE_NEW_DATA_FILES_PATH + + %LFNew DIR/EXT/SCN file names: "^5%NP.*^1" + + 11. FILE_RENAME_DATA_FILES + + %LFRename old data files? @ + + 12. FILE_DL_PATH + + ^4New download path @ + + 13. FILE_SET_DL_PATH_TO_UL_PATH + + %LFSet the upload path to the download path? @ + + 14. FILE_UL_PATH + + ^4New upload path @ + + 15. FILE_ACS + + %LFNew ACS: @ + + 16. FILE_DL_ACCESS + + %LFNew download ACS: @ + + 17. FILE_UL_ACCESS + + %LFNew upload ACS: @ + + 18. FILE_MAX_FILES + + %LFNew max files @ + + 19. FILE_PASSWORD + + %LFNew password: @ + + 20. FILE_ARCHIVE_TYPE + + %LFNew archive type (^50^4=^5None^4) @ + + 21. FILE_COMMENT_TYPE + + %LFNew comment type (^50^4=^5None^4) @ + + 22. FILE_TOGGLE_FLAGS + + %LFToggle which flag (%FT)+'^4) [^5?^4=^5Help^4,^5^4=^5Quit^4]: @ + + 23. FILE_MOVE_DATA_FILES + + %LFMove old data files to new directory? @ + + 24. FILE_TOGGLE_HELP + + %LF^1(^3N^1)oRatio ^1(^3U^1)nhidden + ^1(^3G^1)ifSpecs ^1(^3I^1)*.DIR file in DLPath + ^1(^3C^1)D-ROM ^1(^3S^1)how uploader Name + ^1(^3D^1)ate uploaded ^1du(^3P^1)e checking off + + 25. FILE_JUMP_TO + + %LFJump to entry? + + 26. FILE_FIRST_VALID_RECORD + + %LF^7You are at the first valid record!^1 + + 27. FILE_LAST_VALID_RECORD + + %LF^7You are at the last valid record!^1 + + 28. FILE_INSERT_EDIT_HELP + + %LF^1<^3CR^1>Redisplay current screen + ^31-9,T^1:Modify item + + 29. FILE_INSERT_HELP + + ^1(^3Q^1)uit and save + + 30. FILE_EDIT_HELP + + ^1(^3[^1)Back entry ^1(^3]^1)Forward entry'); + ^1(^3F^1)irst entry in list ^1(^3J^1)ump to entry'); + ^1(^3L^1)ast entry in list ^1(^3Q^1)uit and save'); + } + + PROCEDURE EditFileArea(TempMemFileArea1: FileAreaRecordType; VAR MemFileArea: FileAreaRecordType; VAR Cmd1: Char; + VAR MCIVars1: MCIVarRecord; VAR Changed: Boolean; Editing: Boolean); + VAR + TempFileName: Str8; + CmdStr: AStr; + RecNum, + RecNum1: Integer; + Ok: Boolean; + BEGIN + WITH MemFileArea DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + CLS; + IF (Editing) THEN + FAELngStr(35,MemFileArea,MCIVars1,FALSE) + ELSE + FAELngStr(36,MemFileArea,MCIVars1,FALSE); + FAELngStr(37,MemFileArea,MCIVars1,FALSE); + END; + IF (NOT Editing) THEN + CmdStr := '123456789T' + ELSE + CmdStr := '123456789T[]FJL'; + LOneK(FAELngStr(38,MemFileArea,MCIVars1,TRUE),Cmd1,'Q?'+CmdStr+^M,TRUE,TRUE); + CASE Cmd1 OF + '1' : REPEAT + TempMemFileArea1.AreaName := MemFileArea.AreaName; + OK := TRUE; + InputWNWC(FAELngStr(39,MemFileArea,MCIVars1,TRUE),AreaName,(SizeOf(AreaName) - 1),Changed); + CheckFileArea(MemFileArea,MCIVars1,1,1,Ok); + IF (NOT Ok) THEN + MemFileArea.AreaName := TempMemFileArea1.AreaName; + UNTIL (OK) OR (HangUp); + '2' : REPEAT + OK := TRUE; + TempFileName := FileName; + InputWN1(FAELngStr(40,MemFileArea,MCIVars1,TRUE),TempFileName,(SizeOf(FileName) - 1), + [UpperOnly,InterActiveEdit],Changed); + TempFileName := SQOutSp(TempFileName); + IF (Pos('.',TempFileName) > 0) THEN + TempFileName := Copy(TempFileName,1,(Pos('.',TempFileName) - 1)); + TempMemFileArea1.FileName := TempFileName; + CheckFileArea(TempMemFileArea1,MCIVars1,2,2,Ok); + IF (Ok) AND (TempFileName <> MemFileArea.FileName) THEN + BEGIN + RecNum1 := -1; + RecNum := 0; + WHILE (RecNum <= (FileSize(FileAreaFile) - 1)) AND (RecNum1 = -1) DO + BEGIN + Seek(FileAreaFile,RecNum); + Read(FileAreaFile,TempMemFileArea1); + IF (TempFileName = TempMemFileArea1.FileName) THEN + BEGIN + FAELngStr(41,MemFileArea,MCIVars1,FALSE); + RecNum1 := 1; + IF NOT PYNQ(FAELngStr(42,MemFileArea,MCIVars1,TRUE),0,FALSE) THEN + Ok := FALSE; + END; + Inc(RecNum); + END; + END; + IF (Ok) THEN + BEGIN + MCIVars1.OldPath := GetDirPath(MemFileArea); + FileName := TempFileName; + IF (Editing) THEN + BEGIN + MCIVars1.NewPath := GetDirPath(MemFileArea); + IF Exist(MCIVars1.OldPath+'.DIR') AND (NOT Exist(MCIVars1.NewPath+'.DIR')) THEN + BEGIN + FAELngStr(43,MemFileArea,MCIVars1,FALSE); + FAELngStr(44,MemFileArea,MCIVars1,FALSE); + IF PYNQ(FAELngStr(45,MemFileArea,MCIVars1,TRUE),0,FALSE) THEN + BEGIN + CopyMoveFile(FALSE,'%LF^1Renaming "^5'+MCIVars1.OldPath+'.DIR^1" to "^5'+ + MCIVars1.NewPath+'.DIR^1": ',MCIVars1.OldPath+'.DIR',MCIVars1.NewPath+'.DIR',TRUE); + CopyMoveFile(FALSE,'%LF^1Renaming "^5'+MCIVars1.OldPath+'.EXT^1" to "^5'+ + MCIVars1.NewPath+'.EXT^1": ',MCIVars1.OldPath+'.EXT',MCIVars1.NewPath+'.EXT',TRUE); + CopyMoveFile(FALSE,'%LF^1Renaming "^5'+MCIVars1.OldPath+'.SCN^1" to "^5'+ + MCIVars1.NewPath+'.SCN^1": ',MCIVars1.OldPath+'.SCN',MCIVars1.NewPath+'.SCN',TRUE); + END; + END; + END; + END; + UNTIL (Ok) OR (HangUp); + '3' : BEGIN + InputPath(FAELngStr(46,MemFileArea,MCIVars1,TRUE),DLPath,Editing,FALSE,Changed); + IF (ULPath <> DLPath) AND (PYNQ(FAELngStr(47,MemFileArea,MCIVars1,TRUE),0,FALSE)) THEN + BEGIN + ULPath := DLPath; + Changed := TRUE; + END; + END; + '4' : InputPath(FAELngStr(48,MemFileArea,MCIVars1,TRUE),ULPath,Editing,FALSE,Changed); + '5' : InputWN1(FAELngStr(49,MemFileArea,MCIVars1,TRUE),ACS,(SizeOf(ACS) - 1),[InterActiveEdit],Changed); + '6' : BEGIN + InputWN1(FAELngStr(50,MemFileArea,MCIVars1,TRUE),DLACS,(SizeOf(DLACS) - 1),[InterActiveEdit],Changed); + InputWN1(FAELngStr(51,MemFileArea,MCIVars1,TRUE),ULACS,(SizeOf(ULACS) - 1),[InterActiveEdit],Changed); + END; + '7' : InputIntegerWC(FAELngStr(52,MemFileArea,MCIVars1,TRUE),MaxFiles,[DisplayValue,NumbersOnly],0,32767,Changed); + '8' : InputWN1(FAELngStr(53,MemFileArea,MCIVars1,TRUE),Password,(SizeOf(Password) - 1), + [InterActiveEdit,UpperOnly],Changed); + '9' : BEGIN + REPEAT + OK := TRUE; + NL; + DisplayARCS; + InputByteWC(FAELngStr(54,MemFileArea,MCIVars1,TRUE),MemFileArea.ArcType, + [DisplayValue,NumbersOnly],0,NumArcs,Changed); + CheckFileArea(MemFileArea,MCIVars1,5,5,Ok); + UNTIL (Ok) OR (HangUp); + REPEAT + OK := TRUE; + NL; + DisplayCmt; + InputByteWC(FAELngStr(55,MemFileArea,MCIVars1,TRUE),CmtType,[DisplayValue,NumbersOnly],0,3,Changed); + CheckFileArea(MemFileArea,MCIVars1,6,6,Ok); + UNTIL (Ok) OR (HangUp) + END; + 'T' : BEGIN + REPEAT + LOneK(FAELngStr(56,MemFileArea,MCIVars1,TRUE),Cmd1,^M'CDGINPSU?',TRUE,TRUE); + CASE (Cmd1) OF + 'C','D','G','N','P','S','U' : + ToggleFAFlags(Cmd1,FAFlags,Changed); + 'I' : BEGIN + MCIVars1.OldPath := GetDIRPath(MemFileArea); + ToggleFAFlags('I',FAFlags,Changed); + IF (Editing) THEN + BEGIN + MCIVars1.NewPath := GetDIRPath(MemFileArea); + IF (Exist(MCIVars1.OldPath+'.DIR')) AND (NOT Exist(MCIVars1.NewPath+'.DIR')) THEN + BEGIN + FAELngStr(43,MemFileArea,MCIVars1,FALSE); + FAELngStr(44,MemFileArea,MCIVars1,FALSE); + IF PYNQ(FAELngStr(57,MemFileArea,MCIVars1,TRUE),0,FALSE) THEN + BEGIN + CopyMoveFile(FALSE,'%LF^1Moving "^5'+MCIVars1.OldPath+'.DIR^1" to "^5'+ + MCIVars1.NewPath+'.DIR^1": ',MCIVars1.OldPath+'.DIR',MCIVars1.NewPath+'.DIR', + TRUE); + CopyMoveFile(FALSE,'%LF^1Moving "^5'+MCIVars1.OldPath+'.EXT^1" to "^5'+ + MCIVars1.NewPath+'.EXT^1": ',MCIVars1.OldPath+'.EXT',MCIVars1.NewPath+'.EXT', + TRUE); + CopyMoveFile(FALSE,'%LF^1Moving "^5'+MCIVars1.OldPath+'.SCN^1" to "^5'+ + MCIVars1.NewPath+'.SCN^1": ',MCIVars1.OldPath+'.SCN',MCIVars1.NewPath+'.SCN', + TRUE); + END; + END; + END; + END; + '?' : FAELngStr(58,MemFileArea,MCIVars1,FALSE); + END; + UNTIL (Cmd1 = ^M) OR (HangUp); + Cmd1 := #0; + END; + '[' : IF (MCIVars1.RecNumToEdit > 1) THEN + Dec(MCIVars1.RecNumToEdit) + ELSE + BEGIN + FAELngStr(60,MemFileArea,MCIVars1,FALSE); + Cmd1 := #0; + END; + ']' : IF (MCIVars1.RecNumToEdit < NumFileAreas) THEN + Inc(MCIVars1.RecNumToEdit) + ELSE + BEGIN + FAELngStr(61,MemFileArea,MCIVars1,FALSE); + Cmd1 := #0; + END; + 'F' : IF (MCIVars1.RecNumToEdit <> 1) THEN + MCIVars1.RecNumToEdit := 1 + ELSE + BEGIN + FAELngStr(60,MemFileArea,MCIVars1,FALSE); + Cmd1 := #0; + END; + 'J' : BEGIN + InputIntegerWOC(FAELngStr(59,MemFileArea,MCIVars1,TRUE),MCIVars1.RecNumToEdit,[Numbersonly],1,NumFileAreas); + IF (MCIVars1.RecNumToEdit < 1) OR (MCIVars1.RecNumToEdit > NumFileAreas) THEN + Cmd1 := #0; + END; + 'L' : IF (MCIVars1.RecNumToEdit <> NumFileAreas) THEN + MCIVars1.RecNumToEdit := NumFileAreas + ELSE + BEGIN + FAELngStr(61,MemFileArea,MCIVars1,FALSE); + Cmd1 := #0; + END; + '?' : BEGIN + FAELngStr(62,MemFileArea,MCIVars1,FALSE); + IF (NOT Editing) THEN + FAELngStr(63,MemFileArea,MCIVars1,FALSE) + ELSE + FAELngStr(64,MemFileArea,MCIVars1,FALSE); + END; + END; + UNTIL (Pos(Cmd1,'Q[]FJL') <> 0) OR (HangUp); + END; + + { + InsertFileArea External String Table + + 1. FILE_INSERT_MAX_FILE_AREAS + + %LF^7No more then %MA file areas can exist!^1 + %PA + + 2. FILE_INSERT_PROMPT + + %LFFile area to insert before? @ + + 3. FILE_INSERT_AFTER_ERROR_PROMPT + + %LFContinue inserting file area? @ + + 4. FILE_INSERT_CONFIRM_INSERT + + %LFIs this what you want? @ + + 5. FILE_INSERT_NOTICE + + %LF[> Inserting file area ... + + 6. FILE_INSERT_SYSOPLOG + + * Inserted file area: ^5%AN + } + + PROCEDURE InsertFileArea(TempMemFileArea1: FileAreaRecordType; MCIVars1: MCIVarRecord); + VAR + FileAreaScanFile: FILE OF Boolean; + Cmd1: Char; + RecNum, + RecNum1, + RecNumToInsertBefore: SmallInt; + Ok, + Changed: Boolean; + BEGIN + IF (NumFileAreas = MaxFileAreas) THEN + FAELngStr(22,MemFileArea,MCIVars1,FALSE) + ELSE + BEGIN + RecNumToInsertBefore := -1; + InputIntegerWOC(FAELngStr(23,MemFileArea,MCIVars1,TRUE),RecNumToInsertBefore,[NumbersOnly],1,(NumFileAreas + 1)); + IF (RecNumToInsertBefore >= 1) AND (RecNumToInsertBefore <= (NumFileAreas + 1)) THEN + BEGIN + Reset(FileAreaFile); + InitFileAreaVars(TempMemFileArea1); + IF (RecNumToInsertBefore = 1) THEN + MCIVars1.RecNumToEdit := 1 + ELSE IF (RecNumToInsertBefore = (NumFileAreas + 1)) THEN + MCIVars1.RecNumToEdit := (NumFileAreas + 1) + ELSE + MCIVars1.RecNumToEdit := RecNumToInsertBefore; + REPEAT + OK := TRUE; + EditFileArea(TempMemFileArea1,TempMemFileArea1,Cmd1,MCIVars1,Changed,FALSE); + CheckFileArea(TempMemFileArea1,MCIVars1,1,6,Ok); + IF (NOT OK) THEN + IF (NOT PYNQ(FAELngStr(24,MemFileArea,MCIVars1,TRUE),0,TRUE)) THEN + Abort := TRUE; + UNTIL (OK) OR (Abort) OR (HangUp); + IF (NOT Abort) AND (PYNQ(FAELngStr(25,MemFileArea,MCIVars1,TRUE),0,FALSE)) THEN + BEGIN + FAELngStr(26,MemFileArea,MCIVars1,FALSE); + Seek(FileAreaFile,FileSize(FileAreaFile)); + Write(FileAreaFile,MemFileArea); + Dec(RecNumToInsertBefore); + FOR RecNum := ((FileSize(FileAreaFile) - 1) - 1) DOWNTO RecNumToInsertBefore DO + BEGIN + Seek(FileAreaFile,RecNum); + Read(FileAreaFile,MemFileArea); + Seek(FileAreaFile,(RecNum + 1)); + Write(FileAreaFile,MemFileArea); + END; + FOR RecNum := RecNumToInsertBefore TO ((RecNumToInsertBefore + 1) - 1) DO + BEGIN + MakeDir(TempMemFileArea1.DLPath,FALSE); + MakeDir(TempMemFileArea1.ULPath,FALSE); + IF (NOT Exist(GetDirPath(TempMemFileArea1)+'.DIR')) THEN + BEGIN + Assign(FileInfoFile,GetDIRPath(TempMemFileArea1)+'.DIR'); + ReWrite(FileInfoFile); + Close(FileInfoFile); + END; + IF (NOT Exist(GetDirPath(TempMemFileArea1)+'.EXT')) THEN + BEGIN + Assign(ExtInfoFile,GetDIRPath(TempMemFileArea1)+'.EXT'); + ReWrite(ExtInfoFile,1); + Close(ExtInfoFile); + END; + IF (NOT Exist(GetDirPath(TempMemFileArea1)+'.SCN')) THEN + BEGIN + Assign(FileAreaScanFile,GetDIRPath(TempMemFileArea1)+'.SCN'); + ReWrite(FileAreaScanFile); + Close(FileAreaScanFile); + END; + IF (Exist(GetDirPath(TempMemFileArea1)+'.SCN')) THEN + BEGIN + Assign(FileAreaScanFile,GetDIRPath(TempMemFileArea1)+'.SCN'); + Reset(FileAreaScanFile); + NewScanFileArea := TRUE; + FOR RecNum1 := (FileSize(FileAreaScanFile) + 1) TO (MaxUsers - 1) DO + Write(FileAreaScanFile,NewScanFileArea); + Close(FileAreaScanFile); + END; + Seek(FileAreaFile,RecNum); + Write(FileAreaFile,TempMemFileArea1); + Inc(NumFileAreas); + SysOpLog(FAELngStr(27,TempMemFileArea1,MCIVars1,TRUE)); + END; + END; + Close(FileAreaFile); + LastError := IOResult; + END; + END; + END; + + { + ModifyFileArea External String Table + + 1. NO_FILE_AREAS + + %LF^7No file areas exist!^1 + %PA + + 2. FILE_MODIFY_PROMPT + + %LFFile area to modify? @ + + 3. FILE_MODIFY_SYSOPLOG + + * Modified file area: ^5%AN + } + + PROCEDURE ModifyFileArea(TempMemFileArea1: FileAreaRecordType; MCIVars1: MCIVarRecord); + VAR + FileAreaScanFile: FILE OF Boolean; + User: UserRecordType; + Cmd1: Char; + RecNum1, + SaveRecNumToEdit: Integer; + Ok, + Changed: Boolean; + BEGIN + IF (NumFileAreas = 0) THEN + FAELngStr(5,MemFileArea,MCIVars1,FALSE) + ELSE + BEGIN + MCIVars1.RecNumToEdit := -1; + InputIntegerWOC(FAELngStr(28,MemFileArea,MCIVars1,TRUE),MCIVars1.RecNumToEdit,[NumbersOnly],1,NumFileAreas); + IF (MCIVars1.RecNumToEdit >= 1) AND (MCIVars1.RecNumToEdit <= NumFileAreas) THEN + BEGIN + SaveRecNumToEdit := -1; + Cmd1 := #0; + Reset(FileAreaFile); + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNumToEdit <> MCIVars1.RecNumToEdit) THEN + BEGIN + Seek(FileAreaFile,(MCIVars1.RecNumToEdit - 1)); + Read(FileAreaFile,MemFileArea); + SaveRecNumToEdit := MCIVars1.RecNumToEdit; + Changed := FALSE; + END; + REPEAT + Ok := TRUE; + EditFileArea(TempMemFileArea1,MemFileArea,Cmd1,MCIVars1,Changed,TRUE); + CheckFileArea(MemFileArea,MCIVars1,1,6,Ok); + IF (NOT OK) THEN + BEGIN + PauseScr(FALSE); + IF (MCIVars1.RecNumToEdit <> SaveRecNumToEdit) THEN + MCIVars1.RecNumToEdit := SaveRecNumToEdit; + END; + UNTIL (OK) OR (HangUp); + MakeDir(MemFileArea.DLPath,FALSE); + MakeDir(MemFileArea.ULPath,FALSE); + IF (NOT Exist(GetDirPath(MemFileArea)+'.DIR')) THEN + BEGIN + Assign(FileInfoFile,GetDIRPath(MemFileArea)+'.DIR'); + ReWrite(FileInfoFile); + Close(FileInfoFile); + END; + IF (NOT Exist(GetDirPath(MemFileArea)+'.EXT')) THEN + BEGIN + Assign(ExtInfoFile,GetDIRPath(MemFileArea)+'.EXT'); + ReWrite(ExtInfoFile,1); + Close(ExtInfoFile); + END; + IF (NOT Exist(GetDirPath(MemFileArea)+'.SCN')) THEN + BEGIN + Assign(FileAreaScanFile,GetDIRPath(MemFileArea)+'.SCN'); + ReWrite(FileAreaScanFile); + Close(FileAreaScanFile); + END; + IF (Exist(GetDirPath(MemFileArea)+'.SCN')) THEN + BEGIN + Assign(FileAreaScanFile,GetDIRPath(MemFileArea)+'.SCN'); + Reset(FileAreaScanFile); + NewScanFileArea := TRUE; + Seek(FileAreaScanFile,FileSize(FileAreaScanFile)); + FOR RecNum1 := (FileSize(FileAreaScanFile) + 1) TO (MaxUsers - 1) DO + Write(FileAreaScanFile,NewScanFileArea); + Reset(UserFile); + FOR RecNum1 := 1 TO (MaxUsers - 1) DO + BEGIN + LoadURec(User,RecNum1); + IF (Deleted IN User.SFlags) THEN + BEGIN + Seek(FileAreaScanFile,(RecNum1 - 1)); + Write(FileAreaScanFile,NewScanFileArea); + END; + END; + Close(UserFile); + Close(FileAreaScanFile); + END; + IF (Changed) THEN + BEGIN + Seek(FileAreaFile,(SaveRecNumToEdit - 1)); + Write(FileAreaFile,MemFileArea); + Changed := FALSE; + SysOpLog(FAELngStr(29,MemFileArea,MCIVars1,TRUE)); + END; + END; + Close(FileAreaFile); + LastError := IOResult; + END; + END; + END; + + { + PositionFileArea External String Table + + 1. NO_FILE_AREAS + + %LF^7No file areas exist!^1 + %PA + + 2. FILE_POSITION_NO_AREAS + + %LF^7No file areas to position!^1 + %PA + + 3. FILE_POSITION_PROMPT + + %LFPosition which file area? @ + + 4. FILE_POSITION_NUMBERING + + %LFAccording to the current numbering system. + + 5. FILE_POSITION_BEFORE_WHICH + + %LFPosition before which file area?' + + 6. FILE_POSITION_NOTICE + + %LF[> Positioning file areas ... + } + + PROCEDURE PositionFileArea(TempMemFileArea1: FileAreaRecordType; MCIVars1: MCIVarRecord); + VAR + RecNumToPosition, + RecNumToPositionBefore, + RecNum1, + RecNum2: SmallInt; + BEGIN + IF (NumFileAreas = 0) THEN + FAELngStr(5,MemFileArea,MCIVars1,FALSE) + ELSE IF (NumFileAreas = 1) THEN + FAELngStr(30,MemFileArea,MCIVars1,FALSE) + ELSE + BEGIN + RecNumToPosition := -1; + InputIntegerWOC(FAELngStr(31,MemFileArea,MCIVars1,TRUE),RecNumToPosition,[NumbersOnly],1,NumFileAreas); + IF (RecNumToPosition >= 1) AND (RecNumToPosition <= NumFileAreas) THEN + BEGIN + RecNumToPositionBefore := -1; + FAELngStr(32,MemFileArea,MCIVars1,FALSE); + InputIntegerWOC(FAELngStr(33,MemFileArea,MCIVars1,TRUE),RecNumToPositionBefore,[Numbersonly],1,(NumFileAreas + 1)); + IF (RecNumToPositionBefore >= 1) AND (RecNumToPositionBefore <= (NumFileAreas + 1)) AND + (RecNumToPositionBefore <> RecNumToPosition) AND (RecNumToPositionBefore <> (RecNumToPosition + 1)) THEN + BEGIN + FAELngStr(34,MemFileArea,MCIVars1,FALSE); + Reset(FileAreaFile); + IF (RecNumToPositionBefore > RecNumToPosition) THEN + Dec(RecNumToPositionBefore); + Dec(RecNumToPosition); + Dec(RecNumToPositionBefore); + Seek(FileAreaFile,RecNumToPosition); + Read(FileAreaFile,TempMemFileArea1); + RecNum1 := RecNumToPosition; + IF (RecNumToPosition > RecNumToPositionBefore) THEN + RecNum2 := -1 + ELSE + RecNum2 := 1; + WHILE (RecNum1 <> RecNumToPositionBefore) DO + BEGIN + IF ((RecNum1 + RecNum2) < FileSize(FileAreaFile)) THEN + BEGIN + Seek(FileAreaFile,(RecNum1 + RecNum2)); + Read(FileAreaFile,MemFileArea); + Seek(FileAreaFile,RecNum1); + Write(FileAreaFile,MemFileArea); + END; + Inc(RecNum1,RecNum2); + END; + Seek(FileAreaFile,RecNumToPositionBefore); + Write(FileAreaFile,TempMemFileArea1); + Close(FileAreaFile); + LastError := IOResult; + END; + END; + END; + END; + + { + ListFileAreas External String Table + + 1. FILE_AREA_HEADER_TOGGLE_ONE + + ^0#####^4:^3File area name ^4:^3Flags ^4:^3ACS ^4:^3UL ACS ^4:^3DL ACS ^4:^3MaxF + ^4=====:=========================:========:==========:==========:==========:===== + + 2. FILE_AREA_HEADER_TOGGLE_TWO + + ^0#####^4:^3File area name ^4:^3FileName^4:^3Download path ^4:^3Upload path + ^4=====:================:========:=======================:======================= + + 3. FILE_AREA_HEADER_NO_FILE_AREAS + + #7*** No file areas defined ***^1 + } + + PROCEDURE ListFileAreas(VAR RecNumToList1: Integer; MCIVars1: MCIVarRecord); + VAR + NumDone: Integer; + BEGIN + IF (RecNumToList1 < 1) OR (RecNumToList1 > NumFileAreas) THEN + RecNumToList1 := 1; + Abort := FALSE; + Next := FALSE; + CLS; + CASE DisplayType OF + 1 : FAELngStr(0,MemFileArea,MCIVars1,FALSE); + 2 : FAELngStr(1,MemFileArea,MCIVars1,FALSE); + END; + Reset(FileAreaFile); + NumDone := 0; + WHILE (NumDone < (PageLength - 5)) AND (RecNumToList1 >= 1) AND (RecNumToList1 <= NumFileAreas) + AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(FileAreaFile,(RecNumToList1 - 1)); + Read(FileAreaFile,MemFileArea); + WITH MemFileArea DO + CASE DisplayType OF + 1 : PrintACR('^0'+PadRightInt(RecNumToList1,5)+ + ' ^5'+PadLeftStr(AreaName,25)+ + ' ^3'+DisplayFAFlags(FAFlags,'5','4')+ + ' ^9'+PadLeftStr(AOnOff(ACS = '','*None*',ACS),10)+ + ' '+PadLeftStr(AOnOff(ULACS = '','*None*',ULACS),10)+ + ' '+PadLeftStr(AOnOff(DLACS = '','*None*',DLACS),10)+ + ' ^3'+PadRightInt(MaxFiles,5)); + 2 : PrintACR('^0'+PadRightInt(RecNumToList1,5)+ + ' ^5'+PadLeftStr(AreaName,16)+ + ' ^3'+PadLeftStr(FileName,8)+ + ' '+PadLeftStr(DLPath,23)+ + ' '+PadLeftStr(ULPath,23)); + END; + Inc(RecNumToList1); + Inc(NumDone); + END; + Close(FileAreaFile); + LastError := IOResult; + IF (NumFileAreas = 0) AND (NOT Abort) AND (NOT HangUp) THEN + FAELngStr(2,MemFileArea,MCIVars1,FALSE); + END; + + { + MainFileArea External String Table + + 1. FILE_AREA_EDITOR_PROMPT + + %LFFile area editor [^5?^4=^5Help^4]: + + 2. FILE_AREA_EDITOR_HELP + + %LF^1<^3CR^1>Next screen or redisplay current screen + ^1(^3C^1)hange file area storage drive + ^1(^3D^1)elete area ^1(^3I^1)nsert area + ^1(^3M^1)odify area ^1(^3P^1)osition area + ^1(^3Q^1)uit ^1(^3T^1)oggle display format + } + +BEGIN + SaveTempPause := TempPause; + TempPause := FALSE; + RecNumToList := 1; + Cmd := #0; + REPEAT + IF (Cmd <> '?') THEN + ListFileAreas(RecNumToList,MCIVars); + LOneK(FAELngStr(3,MemFileArea,MCIVars,TRUE),Cmd,'QCDIMPT?'^M,TRUE,TRUE); + CASE Cmd OF + ^M : IF (RecNumToList < 1) OR (RecNumToList > NumFileAreas) THEN + RecNumToList := 1; + 'C' : ChangeFileAreaDrive(MCIVars); + 'D' : DeleteFileArea(TempMemFileArea,MCIVars); + 'I' : InsertFileArea(TempMemFileArea,MCIVars); + 'M' : ModifyFileArea(TempMemFileArea,MCIVars); + 'P' : PositionFileArea(TempMemFileArea,MCIVars); + 'T' : DisplayType := ((DisplayType MOD 2) + 1); + '?' : FAELngStr(4,MemFileArea,MCIVars,FALSE); + END; + IF (Cmd <> ^M) THEN + RecNumToList := 1; + UNTIL (Cmd = 'Q') OR (HangUp); + TempPause := SaveTempPause; + NewCompTables; + IF ((FileArea < 1) OR (FileArea > NumFileAreas)) THEN + FileArea := 1; + ReadFileArea := -1; + LoadFileArea(FileArea); + LastError := IOResult; +END; + +END. diff --git a/SOURCE/TAGLINE.PAS b/SOURCE/TAGLINE.PAS new file mode 100644 index 0000000..2672772 --- /dev/null +++ b/SOURCE/TAGLINE.PAS @@ -0,0 +1,105 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +PROGRAM TAGLINE; + +USES + Crt, + Dos; + +TYPE + StrPointerRec = RECORD + Pointer, + TextSize: LongInt; + END; + +VAR + RGStrFile: FILE; + StrPointerFile: FILE OF StrPointerRec; + F: Text; + StrPointer: StrPointerRec; + S: STRING; + RGStrNum, + Counter: Word; + +FUNCTION Exist(FN: STRING): Boolean; +VAR + DirInfo: SearchRec; +BEGIN + FindFirst(FN,AnyFile,DirInfo); + Exist := (DosError = 0); +END; + +BEGIN + CLrScr; + WriteLn('Renegade Tagline Compiler Version 1.1'); + Writeln('Copyright 2006-2009 - The Renegade Developement Team'); + WriteLn; + IF (NOT Exist('TAGLINE.TXT')) THEN + WriteLn(^G^G^G'TAGLINE.TXT file was not found!') + ELSE + BEGIN + Counter := 0; + Write('Checking maximum string length of 74 characters ... '); + Assign(F,'TAGLINE.TXT'); + Reset(F); + WHILE NOT EOF(F) DO + BEGIN + ReadLn(F,S); + IF (Length(S) > 74) THEN + BEGIN + WriteLn; + WriteLn; + WriteLn('This string is longer then 74 characters:'); + WriteLn; + Writeln(^G^G^G'-> '+S); + WriteLn; + WriteLn('Please reduce it''s length or delete from TAGLINE.TXT!'); + Halt; + END; + Inc(Counter); + END; + WriteLn('Done!'); + IF (Counter > 65535) THEN + BEGIN + WriteLn; + WriteLn; + WriteLn(^G^G^G'This file contains more then 65,535 lines'); + WriteLn; + Writeln('Please reduce the number of lines in TAGLINE.TXT!'); + WriteLn; + WriteLn('NOTE: Blank lines between Taglines are not required.'); + Writeln; + Halt; + END; + WriteLn; + Write('Compiling taglines ... '); + Assign(StrPointerFile,'TAGLINE.PTR'); + ReWrite(StrPointerFile); + Assign(RGStrFile,'TAGLINE.DAT'); + ReWrite(RGStrFile,1); + Reset(F); + WHILE NOT EOF(F) DO + BEGIN + ReadLn(F,S); + IF (S <> '') THEN + BEGIN + WITH StrPointer DO + BEGIN + Pointer := (FileSize(RGStrFile) + 1); + TextSize := 0; + END; + Seek(RGStrFile,FileSize(RGStrFile)); + Inc(StrPointer.TextSize,(Length(S) + 1)); + BlockWrite(RGStrFile,S,(Length(S) + 1)); + Seek(StrPointerFile,FileSize(StrPointerFile)); + Write(StrPointerFile,StrPointer); + END; + END; + Close(F); + Close(RGStrFile); + Close(StrPointerFile); + WriteLn('Done!') + END; +END. diff --git a/SOURCE/TIMEBANK.PAS b/SOURCE/TIMEBANK.PAS new file mode 100644 index 0000000..0ffd8be --- /dev/null +++ b/SOURCE/TIMEBANK.PAS @@ -0,0 +1,215 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT TimeBank; + +INTERFACE + +PROCEDURE Deposit; +PROCEDURE WithDraw; + +IMPLEMENTATION + +USES + Common; + +(* +PROCEDURE TimeBank; +VAR + CmdStr: Str3; + Cmd: CHAR; + DepositTime, + MaxDepositTime: BYTE; + + FUNCTION MinStr(W: WORD): Str160; + BEGIN + MinStr := #3'3'+PadRightInt(W,3)+' minutes'; + END; + +BEGIN + { Display time bank statistics } + NewLine; + Print(#3'0 << Time Bank Information >>'); + NewLine; + Print('Time left on-line : '+MinStr(Trunc(TimeLeft / 60))); + Print('Time in time bank : '+MinStr(ThisUser.TimeBank)); + Print('Maximum allowed in bank: '+MinStr(Systat.MaxTimeInBank)); + NewLine; + Print('Time deposited today : '+MinStr(ThisUser.TbDeposit)); + Print('Maximum daily deposit : '+MinStr(Systat.TbMaxDeposit)); + Print('Time withdrawn today : '+MinStr(ThisUser.TbWithDraw)); + Print('Maximum daily withdraw : '+MinStr(Systat.TbMaxWithDraw)); + NewLine; + Print('Time bank options available:'); + { Determine options user has available } + CmdStr := 'Q'; + IF (Trunc(TimeLeft / 60) > 0) AND (ThisUser.TbDeposit < Systat.TbMaxDeposit) AND + (ThisUser.TimeBank < Systat.MaxTimeInBank) THEN + BEGIN + Print(' ('#3'3D'#3'1)eposit time into the bank'); + CmdStr := CmdStr + 'D'; + END; + IF (ThisUser.TimeBank > 0) AND (ThisUser.TbWithDraw < Systat.TbMaxWithDraw) THEN + BEGIN + Print(' ('#3'3W'#3'1)ithdraw time from the bank'); + CmdStr := CmdStr + 'W'; + END; + Print(' ('#3'3Q'#3'1)uit (exit time bank manager)'); + NewLine; + Prt('Time Bank: '); + OneKeyInput(Cmd,CmdStr); + CASE Cmd OF + 'D' : BEGIN + { Set default deposit to use } + DepositTime := 0; + { Make sure user is unable to deposit more then maximum minus what + was already deposited } + MaxDepositTime := (Systat.TbMaxDeposit - ThisUser.TbDeposit); + { Make sure user is unable to deposit more then they have } + IF (MaxDepositTime > Trunc(TimeLeft / 60)) THEN + MaxDepositTime := Trunc(TimeLeft / 60); + InputByteWoc('How many minutes do you wish to deposit',DepositTime,[],0,MaxDepositTime, + Length(IntToStr(MaxDepositTime)),TRUE); + IF (DepositTime >= 1) AND (DepositTime <= MaxDepositTime) THEN + BEGIN + { Increase what user deposited today } + Inc(ThisUser.TbDeposit,DepositTime); + { Increase what user has in bank } + Inc(ThisUser.TimeBank,DepositTime); + { Decrease user's time on-line } + Dec(ThisUser.AdjTime,DepositTime); + END; + END; + 'W' : BEGIN + { Set default withdraw to use } + DepositTime := 0; + { Make sure user is unable to withdraw more then maximum minus what + was already withdrawn } + MaxDepositTime := (Systat.TbMaxWithDraw - ThisUser.TbWithDraw); + { Make sure user is unable to withdraw more then they have } + IF (MaxDepositTime > ThisUser.TimeBank) THEN + MaxDepositTime := ThisUser.TimeBank; + InputByteWoc('How many minutes do you wish to withdraw',DepositTime,[],0,MaxDepositTime, + Length(IntToStr(MaxDepositTime)),TRUE); + IF (DepositTime >= 1) AND (DepositTime <= MaxDepositTime) THEN + BEGIN + { Increase what user withdrew today } + Inc(ThisUSer.TbWithDraw,DepositTime); + { Decrease what user has in bank } + Dec(ThisUser.TimeBank,DepositTime); + { Increase user's time on-line } + Inc(ThisUSer.AdjTime,DepositTime); + END; + END; + END; + IF (Cmd <> 'Q') THEN + BEGIN + { Display Time Bank Statistics } + NewLine; + TStr(255); + END; +END; +*) + +PROCEDURE Deposit; +CONST + Deposit: LongInt = 0; +BEGIN + NL; + IF ((ThisUser.TimeBank >= General.MaxDepositEver) AND (General.MaxDepositEver <> 0)) THEN + BEGIN + Print('Your time bank has reached the maximum limit allowed.'); + PauseScr(FALSE); + Exit; + END; + IF ((ThisUser.TimeBankAdd >= General.MaxDepositPerDay) AND (General.MaxDepositPerDay <> 0)) THEN + BEGIN + Print('You cannot deposit any more time today.'); + PauseScr(FALSE); + Exit; + END; + + Print('^5Time left online : ^3'+FormattedTime(NSL)); + Print('^5Time in time bank: ^3'+FormattedTime(ThisUser.TimeBank * 60)); + + IF (General.MaxDepositEver > 0) THEN + Print('^5Max account limit: ^3'+FormattedTime(General.MaxDepositEver * 60)); + + IF (General.MaxDepositPerDay > 0) THEN + Print('^5Max deposit/day : ^3'+FormattedTime(General.MaxDepositPerDay * 60)); + + IF (ThisUser.TimeBankAdd <> 0) THEN + Print('^5Deposited today : ^3'+FormattedTime(ThisUser.TimeBankAdd * 60)); + + InputLongIntWOC('%LFDeposit how many minutes',Deposit,[DisplayValue,NumbersOnly],0,32767); + + IF (Deposit > 0) THEN + BEGIN + NL; + IF ((Deposit * 60) > NSL) THEN + Print('^7You don''t have that much time left to deposit!') + ELSE IF ((Deposit + ThisUser.TimeBankAdd) > General.MaxDepositPerDay) AND (General.MaxDepositPerDay <> 0) THEN + Print('^7You can only add '+IntToStr(General.MaxDepositPerDay)+' minutes to your account per day!') + ELSE IF ((Deposit + ThisUser.TimeBank) > General.MaxDepositEver) AND (General.MaxDepositEver <> 0) THEN + Print('^7Your account deposit limit is '+IntToStr(General.MaxDepositEver)+' minutes!') + ELSE + BEGIN + Inc(ThisUser.TimeBankAdd,Deposit); + Inc(ThisUser.TimeBank,Deposit); + Dec(ThisUser.TLToday,Deposit); + SysOpLog('Timebank: Deposited '+IntToStr(Deposit)+' minutes.'); + END; + END; +END; + +PROCEDURE WithDraw; +CONST + Withdrawal: LongInt = 0; +BEGIN + NL; + IF (ChopTime <> 0) THEN + BEGIN + Print('You cannot withdraw any more time during this call.'); + PauseScr(FALSE); + Exit; + END; + IF (ThisUser.TimeBankWith >= General.MaxWithdrawalPerDay) AND (General.MaxWithDrawalPerDay > 0) THEN + BEGIN + Print('You cannot withdraw any more time today.'); + PauseScr(FALSE); + Exit; + END; + + Print('^5Time left online : ^3'+FormattedTime(NSL)); + Print('^5Time in time bank : ^3'+FormattedTime(ThisUser.TimeBank * 60)); + + IF (General.MaxWithdrawalPerDay > 0) THEN + Print('^5Max withdrawal/day: ^3'+FormattedTime(General.MaxWithdrawalPerDay * 60)); + + IF (ThisUser.TimeBankWith > 0) THEN + Print('^5Withdrawn today : ^3'+FormattedTime(ThisUser.TimeBankWith * 60)); + + InputLongIntWOC('%LFWithdraw how many minutes',WithDrawal,[DisplayValue,NumbersOnly],0,32767); + IF (Withdrawal > 0) THEN + BEGIN + NL; + IF (Withdrawal > ThisUser.TimeBank) THEN + Print('^7You don''t have that much time left in your account!') + ELSE IF ((Withdrawal + ThisUser.TimeBankWith) > General.MaxWithdrawalPerDay) AND (General.MaxWithdrawalPerDay > 0) THEN + Print('^7You cannot withdraw that amount of time.') + ELSE + BEGIN + Inc(ThisUser.TimeBankWith,Withdrawal); + Dec(ThisUser.TimeBank,Withdrawal); + Inc(ThisUser.TLToday,Withdrawal); + IF (TimeWarn) AND (NSL > 180) THEN + TimeWarn := FALSE; + SysOpLog('Timebank: Withdrew '+IntToStr(Withdrawal)+' minutes.'); + END; + END; +END; + +END. diff --git a/SOURCE/TIMEFUNC.PAS b/SOURCE/TIMEFUNC.PAS new file mode 100644 index 0000000..cc6f551 --- /dev/null +++ b/SOURCE/TIMEFUNC.PAS @@ -0,0 +1,393 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT TimeFunc; + +INTERFACE + +USES + Dos; + +CONST + MonthString: ARRAY [1..12] OF STRING[9] = ('January','February','March','April','May','June', + 'July','August','September','October','November','December'); + +TYPE + Str2 = STRING[2]; + Str5 = STRING[5]; + Str8 = STRING[8]; + Str10 = STRING[10]; + Str160 = STRING[160]; + +PROCEDURE ConvertAmPm(VAR Hour: Word; VAR AmPm: Str2); +FUNCTION ZeroPad(S: Str8): Str2; +PROCEDURE PackToDate(VAR DT: DateTime; L: LongInt); +FUNCTION DateToPack(VAR DT: DateTime): LongInt; +PROCEDURE GetDateTime(VAR DT: DateTime); +PROCEDURE GetYear(VAR Year: Word); +PROCEDURE GetDayOfWeek(VAR DOW: Byte); +FUNCTION GetPackDateTime: LongInt; +FUNCTION DoorToDate8(CONST SDate: Str10): Str8; +FUNCTION PD2Time24(CONST PD: LongInt): Str5; +FUNCTION ToDate8(CONST SDate: Str10): Str8; +FUNCTION PDT2Dat(VAR PDT: LongInt; CONST DOW: Byte): STRING; +FUNCTION PD2Date(CONST PD: LongInt): STR10; +FUNCTION Date2PD(CONST SDate: Str10): LongInt; +FUNCTION TimeStr: Str8; +FUNCTION DateStr: Str10; +FUNCTION CTim(L: LongInt): Str8; +FUNCTION Days(VAR Month,Year: Word): Word; +FUNCTION DayNum(DateStr: Str10): Word; +FUNCTION Dat: Str160; + +IMPLEMENTATION + +CONST + DayString: ARRAY [0..6] OF STRING[9] = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'); + + SecondsPerYear: ARRAY [FALSE..TRUE] OF LongInt = (31536000,31622400); + + M31 = (86400 * 31); + M30 = (86400 * 30); + M28 = (86400 * 28); + + SecondsPerMonth: ARRAY [1..12] OF LongInt = (M31,M28,M31,M30,M31,M30,M31,M31,M30,M31,M30,M31); + +TYPE + Str11 = STRING[11]; + +(* Done - Lee Palmer 11/23/07 *) +FUNCTION IntToStr(L: LongInt): Str11; +VAR + S: Str11; +BEGIN + Str(L,S); + IntToStr := S; +END; + +(* Done - Lee Palmer 12/06/07 *) +FUNCTION StrToInt(S: Str11): LongInt; +VAR + I: Integer; + L: LongInt; +BEGIN + Val(S,L,I); + IF (I > 0) THEN + BEGIN + S[0] := Chr(I - 1); + Val(S,L,I) + END; + IF (S = '') THEN + StrToInt := 0 + ELSE + StrToInt := L; +END; + +(* Done - Lee Palmer 03/27/07 *) +FUNCTION ZeroPad(S: Str8): Str2; +BEGIN + IF (Length(s) > 2) THEN + s := Copy(s,(Length(s) - 1),2) + ELSE IF (Length(s) = 1) THEN + s := '0'+s; + ZeroPad := s; +END; + +(* Done - 10/25/07 - Lee Palmer *) +PROCEDURE ConvertAmPm(VAR Hour: Word; VAR AmPm: Str2); +BEGIN + IF (Hour < 12) THEN + AmPm := 'am' + ELSE + BEGIN + AmPm := 'pm'; + IF (Hour > 12) THEN + Dec(Hour,12); + END; + IF (Hour = 0) THEN + Hour := 12; +END; + +PROCEDURE February(VAR Year: Word); +BEGIN + IF ((Year MOD 4) = 0) THEN + SecondsPerMonth[2] := (86400 * 29) + ELSE + SecondsPerMonth[2] := (86400 * 28); +END; + +PROCEDURE PackToDate(VAR DT: DateTime; L: LongInt); +BEGIN + DT.Year := 1970; + WHILE (L < 0) DO + BEGIN + Dec(DT.Year); + Inc(L,SecondsPerYear[((DT.Year MOD 4) = 0)]); + END; + WHILE (L >= SecondsPerYear[((DT.Year MOD 4) = 0)]) DO + BEGIN + Dec(L,SecondsPerYear[((DT.Year MOD 4) = 0)]); + Inc(DT.Year); + END; + DT.Month := 1; + February(DT.Year); + WHILE (L >= SecondsPerMonth[DT.Month]) DO + BEGIN + Dec(L,SecondsPerMonth[DT.Month]); + Inc(DT.Month); + END; + DT.Day := (Word(L DIV 86400) + 1); + L := (L MOD 86400); + DT.Hour := Word(L DIV 3600); + L := (L MOD 3600); + DT.Min := Word(L DIV 60); + DT.Sec := Word(L MOD 60); +END; + +FUNCTION DateToPack(VAR DT: DateTime): LongInt; +VAR + Month, + Year: Word; + DTP: LongInt; +BEGIN + DTP := 0; + Inc(DTP,LongInt(DT.Day - 1) * 86400); + Inc(DTP,LongInt(DT.Hour) * 3600); + Inc(DTP,LongInt(DT.Min) * 60); + Inc(DTP,LongInt(DT.Sec)); + February(DT.Year); + FOR Month := 1 TO (DT.Month - 1) DO + Inc(DTP,SecondsPerMonth[Month]); + Year := DT.Year; + WHILE (Year <> 1970) DO + BEGIN + IF (DT.Year > 1970) THEN + BEGIN + Dec(Year); + Inc(DTP,SecondsPerYear[(Year MOD 4 = 0)]); + END + ELSE + BEGIN + Inc(Year); + Dec(DTP,SecondsPerYear[((Year - 1) MOD 4 = 0)]); + END; + END; + DateToPack := DTP; +END; + +PROCEDURE GetDateTime(VAR DT: DateTime); +VAR + DayOfWeek, + HundSec: Word; +BEGIN + GetDate(DT.Year,DT.Month,DT.Day,DayOfWeek); + GetTime(DT.Hour,DT.Min,DT.Sec,HundSec); +END; + +FUNCTION GetPackDateTime: LongInt; +VAR + DT: DateTime; +BEGIN + GetDateTime(DT); + GetPackDateTime := DateToPack(DT); +END; + +PROCEDURE GetYear(VAR Year: Word); +VAR + Month, + Day, + DayOfWeek: Word; +BEGIN + GetDate(Year,Month,Day,DayOfWeek); +END; + +PROCEDURE GetDayOfWeek(VAR DOW: Byte); +VAR + Year, + Month, + Day, + DayOfWeek: Word; +BEGIN + GetDate(Year,Month,Day,DayOfWeek); + DOW := DayOfWeek; +END; + +FUNCTION DoorToDate8(CONST SDate: Str10): Str8; +BEGIN + DoorToDate8 := Copy(SDate,1,2)+'/'+Copy(SDate,4,2)+'/'+Copy(SDate,9,2); +END; + +FUNCTION PD2Time24(CONST PD: LongInt): Str5; +VAR + DT: DateTime; +BEGIN + PackToDate(DT,PD); + PD2Time24 := ZeroPad(IntToStr(DT.Hour))+':'+ZeroPad(IntToStr(DT.Min)); +END; + +FUNCTION PD2Date(CONST PD: LongInt): Str10; +VAR + DT: DateTime; +BEGIN + PackToDate(DT,PD); + PD2Date := ZeroPad(IntToStr(DT.Month))+'-'+ZeroPad(IntToStr(DT.Day))+'-'+IntToStr(DT.Year); +END; + +FUNCTION Date2PD(CONST SDate: Str10): LongInt; +VAR + DT: DateTime; +BEGIN + FillChar(DT,SizeOf(DT),0); + DT.Sec := 1; + DT.Year := StrToInt(Copy(SDate,7,4)); + DT.Day := StrToInt(Copy(SDate,4,2)); + DT.Month := StrToInt(Copy(SDate,1,2)); + IF (DT.Year = 0) THEN + DT.Year := 1; + IF (DT.Month = 0) THEN + DT.Month := 1; + IF (DT.Day = 0) THEN + DT.Day := 1; + Date2PD := DateToPack(DT); +END; + +FUNCTION ToDate8(CONST SDate: Str10): Str8; +BEGIN + IF (Length(SDate) = 8) THEN + ToDate8 := SDate + ELSE + ToDate8 := Copy(SDate,1,6)+Copy(SDate,9,2); +END; + +(* Done - Lee Palmer 11/23/07 *) +FUNCTION PDT2Dat(VAR PDT: LongInt; CONST DOW: Byte): STRING; +(* Example Output: 12:00 am Fri Nov 23, 2007 *) +VAR + DT: DateTime; + AmPm: Str2; +BEGIN + PackToDate(DT,PDT); + ConvertAmPm(DT.Hour,AmPm); + PDT2Dat := IntToStr(DT.Hour)+ + ':'+ZeroPad(IntToStr(DT.Min))+ + ' '+AmPm+ + ' '+Copy(DayString[DOW],1,3)+ + ' '+Copy(MonthString[DT.Month],1,3)+ + ' '+IntToStr(DT.Day)+ + ', '+IntToStr(DT.Year); +END; + +FUNCTION TimeStr: Str8; +VAR + AmPm: Str2; + Hour, + Minute, + Second, + Sec100: Word; +BEGIN + GetTime(Hour,Minute,Second,Sec100); + ConvertAmPm(Hour,AmPm); + TimeStr := IntToStr(Hour)+':'+ZeroPad(IntToStr(Minute))+' '+AmPm; +END; + +FUNCTION DateStr: Str10; +VAR + Year, + Month, + Day, + DayOfWeek: Word; +BEGIN + GetDate(Year,Month,Day,DayOfWeek); + DateStr := ZeroPad(IntToStr(Month))+'-'+ZeroPad(IntToStr(Day))+'-'+IntToStr(Year); +END; + +FUNCTION CTim(L: LongInt): Str8; +VAR + Hour, + Minute, + Second: Str2; +BEGIN + Hour := ZeroPad(IntToStr(L DIV 3600)); + L := (L MOD 3600); + Minute := ZeroPad(IntToStr(L DIV 60)); + L := (L MOD 60); + Second := ZeroPad(IntToStr(L)); + CTim := Hour+':'+Minute+':'+Second; +END; + +(* Done - 10/25/07 - Lee Palmer *) +FUNCTION Days(VAR Month,Year: Word): Word; +VAR + TotalDayCount: Word; +BEGIN + TotalDayCount := StrToInt(Copy('312831303130313130313031',(1 + ((Month - 1) * 2)),2)); + IF ((Month = 2) AND (Year MOD 4 = 0)) THEN + Inc(TotalDayCount); + Days := TotalDaycount; +END; + +(* Done - 10/25/07 - Lee Palmer *) +FUNCTION DayNum(DateStr: Str10): Word; +(* Range 01/01/85 - 07/26/3061 = 0-65535 *) +VAR + Day, + Month, + Year, + YearCounter, + TotalDayCount: Word; + + FUNCTION DayCount(VAR Month1,Year1: Word): Word; + VAR + MonthCounter, + TotalDayCount1: Word; + BEGIN + TotalDayCount1 := 0; + FOR MonthCounter := 1 TO (Month1 - 1) DO + Inc(TotalDayCount1,Days(MonthCounter,Year1)); + DayCount := TotalDayCount1; + END; + +BEGIN + TotalDayCount := 0; + Month := StrToInt(Copy(DateStr,1,2)); + Day := StrToInt(Copy(DateStr,4,2)); + Year := StrToInt(Copy(DateStr,7,4)); + IF (Year < 1985) THEN + DayNum := 0 + ELSE + BEGIN + FOR YearCounter := 1985 TO (Year - 1) DO + IF (YearCounter MOD 4 = 0) THEN + Inc(TotalDayCount,366) + ELSE + Inc(TotalDayCount,365); + TotalDayCount := ((TotalDayCount + DayCount(Month,Year)) + (Day - 1)); + DayNum := TotalDayCount; + END; +END; + +(* Done - 10/25/07 - Lee Palmer *) +FUNCTION Dat: Str160; +VAR + DT: DateTime; + AmPm: Str2; + DayOfWeek, + Sec100: Word; +BEGIN + GetDate(DT.Year,DT.Month,DT.Day,DayOfWeek); + GetTime(DT.Hour,DT.Min,DT.Sec,Sec100); + ConvertAmPm(DT.Hour,AmPm); + Dat := IntToStr(DT.Hour)+ + ':'+ZeroPad(IntToStr(DT.Min))+ + ' '+AmPm+ + ' '+Copy(DayString[DayOfWeek],1,3)+ + ' '+Copy(MonthString[DT.Month],1,3)+ + ' '+IntToStr(DT.Day)+ + ', '+IntToStr(DT.Year); +END; + + +END. diff --git a/SOURCE/UNUSED/ACFLAGS.ASC b/SOURCE/UNUSED/ACFLAGS.ASC new file mode 100644 index 0000000..c573735 --- /dev/null +++ b/SOURCE/UNUSED/ACFLAGS.ASC @@ -0,0 +1,14 @@ + +^3Restrictions: + +^1(^3L^1)Can logon ONLY once/day ^1(^3C^1)Can't page SysOp +^1(^3V^1)Posts marked unvalidated ^1(^3U^1)Can't list users +^1(^3A^1)Can't add to BBS list ^1(^3*^1)Can't post/send anon. +^1(^3P^1)Can't post at all ^1(^3E^1)Can't send email +^1(^3K^1)Can't vote ^1(^3M^1)anditory mail deletion + +^3Special: + +^1(^31^1)No UL/DL ratio check ^1(^32^1)No post/call ratio check +^1(^33^1)No credits check ^1(^34^1)Protection from deletion + diff --git a/SOURCE/UNUSED/ARCHIVE1.TPU b/SOURCE/UNUSED/ARCHIVE1.TPU new file mode 100644 index 0000000000000000000000000000000000000000..3fc338b597f1b58fffc372ffe54c0df150058c81 GIT binary patch literal 24832 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/ARCVIEW.TPU b/SOURCE/UNUSED/ARCVIEW.TPU new file mode 100644 index 0000000000000000000000000000000000000000..e4b7ec043d9408af9c2c8adf8831f5b4ffb47bc3 GIT binary patch literal 23456 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 Kz$fM;`Tqf*87dh7 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/AUTOMSG.TPU b/SOURCE/UNUSED/AUTOMSG.TPU new file mode 100644 index 0000000000000000000000000000000000000000..c843ab0c817ccbc4d88c152dccabbd4f2b9c137f GIT binary patch literal 5840 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 DrtAaT literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/BOOT.TPU b/SOURCE/UNUSED/BOOT.TPU new file mode 100644 index 0000000000000000000000000000000000000000..5623b7a587a850a2c5a933121911ebddf543d44f GIT binary patch literal 34208 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

__L7n@h_%(nT;m{a#aX<*&z`w&qTj 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/BULLETIN.TPU b/SOURCE/UNUSED/BULLETIN.TPU new file mode 100644 index 0000000000000000000000000000000000000000..b0a51a956078d1d83f507ec857745d8b2f934637 GIT binary patch literal 15232 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 or + << New Topic Choice >>. + + D. Unused fields in the Voting Topic and Topic Choice Editor + Insert/Modify command will now display *None*. + + E. The Voting Topic and Topic Choice Editor Insert command will + now display the Topic and Choice Record information for editing + verses just inserting the new record and then requiring you to + go to the modify command to edit. You will not be able to save + the new topic or choice record until all of the above items + are correct. Upon completion of editing the inserted record, + you will be prompted to save or discard the new Topic record. + + F. The Reset Topic option has been moved to the Voting Topic Editor + Main screen and is accessed by pressing "R". You will then be + prompted to enter the record number of the topic you want to + reset. + + G. A Recalculate Voting Topics command has also been added to the + Voting Topic Editor main screen and is accessed by pressing "S". + This option will clear all voting data from the voting topic + records. It will then access the vote array for all User Records + and update the voting topic records based on what question the + user voted on and the choice the user made. This option excludes + deleted users and will ensure that the values in the user.vote + array are set to zero. Depending on Sysop Input, locked out users + could also be excluded per above. + + E. Other changes included adding some missing help data for + certain commands and color changes. + + 3. I recommend that you access the Voting Topic Modify Command + once you have installed this update and toggle thru all + of the voting topic records and make corrections as they are + presented to you. + + + diff --git a/SOURCE/UNUSED/CHANGE11.TXT b/SOURCE/UNUSED/CHANGE11.TXT new file mode 100644 index 0000000..dc4c1a7 --- /dev/null +++ b/SOURCE/UNUSED/CHANGE11.TXT @@ -0,0 +1,28 @@ +Renegade Bug Fix's/Enhancements: + + 1. The Archive Editor has made modified with the following: + + A. The Archive Editor extension can not be blank or the default + of "AAA". + + B. Unused fields in the Archive Editor Insert/Modify command + will now display *None*. + + C. The Archive Editor Insert command will now display the + archive record information for editing verses just inserting + the new record and then requiring you to go to the modify + command to edit. You will not be able to save the new archive + record until all of the above items are correct. Upon completion + of editing the inserted record, you will be prompted to save + or discard the new archive record. + + D. Other changes included adding some missing help data for + certain commands and color changes. + + 2. I recommend that you access the Archive Modify Command + once you have installed this update and toggle thru all + of the archive records and make corrections as they are + presented to you. + + + diff --git a/SOURCE/UNUSED/CHANGE12.TXT b/SOURCE/UNUSED/CHANGE12.TXT new file mode 100644 index 0000000..705af58 --- /dev/null +++ b/SOURCE/UNUSED/CHANGE12.TXT @@ -0,0 +1,28 @@ +Renegade Bug Fix's/Enhancements: + + 1. The Scheme Editor has made modified with the following: + + A. The Scheme Editor description can not be blank or the default + of << New Color Scheme >>. + + B. Unused fields in the Scheme Editor Insert/Modify command + will now display *None*. + + C. The Scheme Editor Insert command will now display the + scheme record information for editing verses just inserting + the new record and then requiring you to go to the modify + command to edit. You will not be able to save the new scheme + record until all of the above items are correct. Upon completion + of editing the inserted record, you will be prompted to save + or discard the new scheme record. + + D. Other changes included adding some missing help data for + certain commands and color changes. + + 2. I recommend that you access the Scheme Modify Command + once you have installed this update and toggle thru all + of the scheme records and make corrections as they are + presented to you. + + + diff --git a/SOURCE/UNUSED/CHANGE13.TXT b/SOURCE/UNUSED/CHANGE13.TXT new file mode 100644 index 0000000..9e1d46f --- /dev/null +++ b/SOURCE/UNUSED/CHANGE13.TXT @@ -0,0 +1,5 @@ + Scan All new public messages + + SAPM[Node#].DAT + + FoundMap: ARRAY [0..4095] OF SET OF 0..7; diff --git a/SOURCE/UNUSED/CHANGE14.TXT b/SOURCE/UNUSED/CHANGE14.TXT new file mode 100644 index 0000000..9b2aa38 --- /dev/null +++ b/SOURCE/UNUSED/CHANGE14.TXT @@ -0,0 +1,29 @@ +Renegade Bug Fix's/Enhancements: + + 1. The History Editor has made modified with the following: + + A. You can not delete the history record for the current date. + + B. You will not be able to insert a new history record for + a date beyond the current date. You can only insert missing + history dates and or dates prior to the first History date. + + C. The History Editor Insert command will now display the + history record information for editing verses just inserting + the new record and then requiring you to go to the modify + command to edit. Upon completion of editing the inserted + record, you will be prompted to save or discard the new + history record. + + D. You can not change a history record date if the date is + utilized by another history record. + + E. The history editor listing will now display one page at a time + verses scrolling to the prompt. + + F. Other changes included adding some missing help data for + certain commands and color changes. + + + + diff --git a/SOURCE/UNUSED/CHANGE2.TXT b/SOURCE/UNUSED/CHANGE2.TXT new file mode 100644 index 0000000..55b2fb4 --- /dev/null +++ b/SOURCE/UNUSED/CHANGE2.TXT @@ -0,0 +1,8 @@ +Renegade Enhancements/Bug Fix's: + + 1. Message Header Editing Option - + + 1. The MAScanOut Flag will no longer be set if the message status + is changed to Un-Sent by a MsgSysOp (or above) if the message + is in the private message area or the message area is not an + Echomail or Groupmail area. diff --git a/SOURCE/UNUSED/CHANGE3.TXT b/SOURCE/UNUSED/CHANGE3.TXT new file mode 100644 index 0000000..c63814b --- /dev/null +++ b/SOURCE/UNUSED/CHANGE3.TXT @@ -0,0 +1,7 @@ +Renegade Bug Fix's/Enhancements: + + 1. The update GIF specifications cmd will now allow updating of + all file areas vice just the current file area. The total GIF + files updated is also now sent to the SysOp.Log. I was also + able to reduce a number of vars utilized in 3 different + procedures down to just one. diff --git a/SOURCE/UNUSED/CHANGE4.TXT b/SOURCE/UNUSED/CHANGE4.TXT new file mode 100644 index 0000000..7585cf6 --- /dev/null +++ b/SOURCE/UNUSED/CHANGE4.TXT @@ -0,0 +1,70 @@ +Renegade Bug Fix's/Enhancements: + + 1. You will now be prompt to set the upload path to the download + path when editing the download path in the File Area Editor. The + 'D' option has been removed due to drive conflicts. + + 2. The File Area Delete has been modified to prompt you to delete + the download/upload directory if they are not being utilized by + another file area. + + 3. The Message Area Editor has made modified with the following: + + A. The message area listing will now display one page at a time + verses scrolling to the prompt. + + B. The File Area Name can not be blank or the default of + << New Message Area >>. + + C. The File Area File Name can not be blank or the default of + NEWBOARD. + + D. The Message Path for Echomail/Groupmail can not be blank. + + E. The Message AKA Address must be an active address setup in + the System Configuration. + + F. The Message Origin for Echomail/Groupmail/QWKmail can not be + blank. + + G. Unused fields in the Insert/Modify command will now + display *None*. + + H. The Message Area Insert command will now display the Message + Area information for editing verses just inserting the + new record and then requiring you to go to the modify + command to edit. You will not be able to save the + new message area until all of the above items are correct. + Upon completion of editing the inserted record, you will + be prompted to save or discard the new message area. The + message directory and the data files will be auto-created + after the new message area is saved. The *.SCN file will + also be updated for all users to scan this file area. + + I. The Message Area Delete command will no longer prompt to + delete the data files if the message area file name is being + utilized by another file area. This option has also been + modified to prompt you to delete the message directory if it + is not being utilized by another message area. + + J. The Message Area Modify command will auto-create the + message directory and data files after editing or + changing to another file area. The *.SCN file will + also be updated to ensure all users are toggled to + scan this message area. You will not be able to save the + message area you are editing until all of the above items + are correct. This command has also been modified + to scan the user file for deleted users and to set the + *.SCN file to allow new scan for the next user to utilize + this message area. + + K. Other changes included added some missing help data for + certain commands and color changes. + + 4. I recommend that you access the File Area Modify command + once you have installed this update and toggle thru all + file areas and make corrections to your file areas as they + are presented to you. + + + diff --git a/SOURCE/UNUSED/CHANGE5.TXT b/SOURCE/UNUSED/CHANGE5.TXT new file mode 100644 index 0000000..2b5a462 --- /dev/null +++ b/SOURCE/UNUSED/CHANGE5.TXT @@ -0,0 +1,42 @@ +Renegade Updates/Enhancements: + + 1. The message area display header was off by one character, fixed. + + 2. In the past, the maximum number of message areas allowed was 2048 with + compression turned on and 32767 with it turned off. Renegade will + now support 32767 message areas with compression on or off. + + 3. The message area listing will now display the message areas one page + at a time vice scrolling thru the entire list. The '?' will now + re-list the message areas starting from message area 1. Pressing + will now display the next page (it will also restart the listing from + message area 1 when the last message area is reached). Pressing 'Q' + will exit the message area display. Previously, this procedure opened + all 3 files associated to a message (*.HDR, *.DAT & *.SCN) to read + the message area scan flag. This process sould now be faster since it + now only opens the *.SCN file. + + 4. The message area change listing will now display the message areas + one page at a time vice scrolling thru the entire list. The '?' will + now re-list the message areas starting from message area 1. Pressing + will now display the next page (it will also restart the listing + from message area 1 when the last message area is reached). Pressing + 'Q' will exit the message area display. Entering an invalid message + area will redisplay the current page. + + 5. The message area set scan listing will now display the message areas + one page at a time vice scrolling thru the entire list. The '?' will + now re-list the message areas starting from message area 1. Pressing + will now display the next page (it will also restart the listing + from message area 1 when the last message area is reached). Pressing + 'Q' will exit the message area display. Previously, this procedure + opened all 3 files associated to a message area (*.HDR, *.DAT & *.SCN) + to set the message area scan flag on or off. This process sould now be + faster since it now only opens the *.SCN file. Also, this procedure + will now only set the scan on message areas the user has access to. + The message area scan char has been moved to the left of the message + area number vice between it and the message area description. + + 6. The file area delete command will now prompt to remove the download + and upload directory if they are not being utilized by another file + area. diff --git a/SOURCE/UNUSED/CHANGE6.TXT b/SOURCE/UNUSED/CHANGE6.TXT new file mode 100644 index 0000000..80499ce --- /dev/null +++ b/SOURCE/UNUSED/CHANGE6.TXT @@ -0,0 +1,70 @@ +Renegade Bug Fix's/Enhancements: + + 1. You will now be prompted to set the upload path to the download + path when editing the download path in the File Area Editor. The + 'D' option has been removed due to drive conflicts. + + 2. The File Area Delete option has been modified to prompt you to + delete the download/upload directory if they are not being utilized + by another file area. + + 3. The Message Area Editor has made modified with the following: + + A. The message area listing will now display one page at a time + verses scrolling to the prompt. + + B. The File Area Name can not be blank or the default of + << New Message Area >>. + + C. The File Area File Name can not be blank or the default of + NEWBOARD. + + D. The Message Path for Echomail/Groupmail can not be blank. + + E. The Message AKA Address for Echomail/Groupmail must be an + active address setup in the System Configuration. + + F. The Message Origin for Echomail/Groupmail/QWKmail can not be + blank. + + G. Unused fields in the Insert/Modify command will now + display *None*. + + H. The Message Area Insert command will now display the Message + Area information for editing verses just inserting the + new record and then requiring you to go to the modify + command to edit. You will not be able to save the + new message area until all of the above items are correct. + Upon completion of editing the inserted record, you will + be prompted to save or discard the new message area. The + message directory and the data files will be auto-created + after the new message area is saved. The *.SCN file will + also be updated for all users to scan this file area. + + I. The Message Area Delete command will no longer prompt to + delete the data files if the message area file name is being + utilized by another file area. This option has also been + modified to prompt you to delete the message directory if it + is not being utilized by another message area. + + J. The Message Area Modify command will auto-create the + message directory and data files after editing or + changing to another file area. The *.SCN file will + also be updated to ensure all users are toggled to + scan this message area. You will not be able to save the + message area you are editing until all of the above items + are correct. This command has also been modified + to scan the user file for deleted users and to set the + *.SCN file to allow new scan for the next user to utilize + this message area. + + K. Other changes included added some missing help data for + certain commands and color changes. + + 4. I recommend that you access the Message Area Modify command + once you have installed this update and toggle thru all + message areas and make corrections to your message areas as they + are presented to you. + + + diff --git a/SOURCE/UNUSED/CHANGE7.TXT b/SOURCE/UNUSED/CHANGE7.TXT new file mode 100644 index 0000000..2ea4747 --- /dev/null +++ b/SOURCE/UNUSED/CHANGE7.TXT @@ -0,0 +1,75 @@ +Renegade bug enhancements: + +1. The file/message area compression routines have been replaced + completely. In the previous version the following variables, + functions and procedures were utilized: + + VAR - "FileCompArray = ARRAY[0..4095] OF SET OF 0..7" + VAR - "MsgCompArray = ARRAY[0..4095] OF SET OF 0..7" + Procedure - "NewCompTables: + Function - "CompFileArea(FArea: Integer): Integer" + Function - "CompMsgArea(MArea: Integer): Integer" + Function - "AFBase(FArea: Integer): Integer" + Function - "AMBase(MArea: Integer): Integer" + + The FileCompArray/MsgCompArray were previously updated by the + NewCompTables Procedure. The NewCompTables Procedure would + simply read in all file/message areas and set a bit to on or off. + The CompFileArea/CompMsgArea Functions would then display the proper + File/Message area after counting from the first file/message area to + the file/message area that needed to be displayed based on the user + access and compression setting in System Configuration. The + AFBase/AMBase Functions were utilized to return the proper file/message + area after counting from the first file/message area to the + file/message area the user actually selected based on the user access + and compression settings in System Confguration. + + As you can see from the above discription, this required alot of + memory to maintain the FileCompArray/MsgCompArray. It also required + four functions for area number display and access. Not to mention + that the real area number for both display and access had to be + counted up to every time an area was displayed or accessed. + + The following varibales, functions and procedures are being + utilized in this release: + + FILE - "FACT[Node].DAT" (Stored in the Node Temp Directory) + FILE - "MACT[Node].DAT" (Stored in the Node Temp Directory) + TYPE - "CompArrayType = ARRAY[0..1] OF INTEGER" + VAR - "LowFileArea: Integer" + VAR - "HighFileArea: Integer" + VAR - "LowMsgArea: Integer" + VAR - "HighMsgArea: Integer" + Procedure - "NewCompTables" + Function - "CompFileArea(FArea,ArrayNum: Integer): Integer" + Function - "CompMsgArea(MArea,ArrayNum: Integer): Integer" + + Two new files (FACT[Node].DAT/MACT[Node].DAT have been created and + are temporarily stored in the Node temp directory. A record of type + ARRAY[0..1] OF Integer is the storage method utilized for the + individual file areas. ARRAY 0 is utilized for storage of the + file/message area to display and ARRAY 1 is utilized for the storage + of the file/message area being accessed. Each record takes up 2 bytes + of space on your harddrive and the above file will only contain + records for the actual number of message/file areas you actually have + available. Both of these files are created at user logon and updated + at other appropriate times as Renegade requires and then deleted when + the user logs off. The NewCompTables Procedure creates and updates + the actual file/message area for display (ARRAY 0) and the actual + file/message area to access (ARRAY 1). This saves on the need to + have the FileCompArray/MsgCompArray and the need for the + CompFileArea/CompMsgArea And AFBase/AMBAse to count everytime + from 1 to the file/message area displayed or accessed. The + CompFileArea/CompMsgArea Functions have been modified to access the + record contained in the FACT[Node].DAT/MACT[Node].DAT file for the + file/message area being display/accessed. This eliminated the need + for the AFBase/AMBase Functions. CompFileArea(FArea,0) or + CompMsgArea(FArea,0) is called to obtained the display area number + and CompFileArea(FArea,1) or CompMsgArea(FArea,1) is called for + the area number to access. NewCompTables will now also return the + LowFileArea, HighFile, LowMsgArea & HighMsgArea for trapping correct + or incorrect file/message area user input. + + As you can see, this enhancement saved alot of memory. Display and + access to a file/message areas should now be faster. Adding the + low/high File/Messae variables will also help trap user input errors. \ No newline at end of file diff --git a/SOURCE/UNUSED/CHANGE8.TXT b/SOURCE/UNUSED/CHANGE8.TXT new file mode 100644 index 0000000..a8121d7 --- /dev/null +++ b/SOURCE/UNUSED/CHANGE8.TXT @@ -0,0 +1,25 @@ +Renegade Enhancements: + + 1. The Conference Editor has made modified with the following: + + A. The Conference Name can not be blank or the default of + << New Conference Record >>. + + B. Unused fields in the Insert/Modify command will now + display *None*. + + C. The Conference Insert option command will now display the + Conference information for editing verses just inserting the + new record and then requiring you to go to the modify + command to edit. You will not be able to save the + new conference until the item above is correct. + Upon completion of editing the inserted record, you will + be prompted to save or discard the new conference area. + + D. The Conference Modify command will also require that the + above item is correct before saving the record being edited. + + 2. I recommend that you access the Conference Modify command + once you have installed this update and toggle thru all + conferences and make corrections to your conferences as they + are presented to you. diff --git a/SOURCE/UNUSED/CHANGE9.TXT b/SOURCE/UNUSED/CHANGE9.TXT new file mode 100644 index 0000000..a9c6bd2 --- /dev/null +++ b/SOURCE/UNUSED/CHANGE9.TXT @@ -0,0 +1,33 @@ +Renegade Bug Fix's/Enhancements: + + 1. The 'Q' and 'q' are no longer available for Validation Keys. + + 2. The Validation Editor has made modified with the following: + + A. The Validation Editor Listing will now display one page at + a time verses scrolling to the prompt. + + B. The Validation Level Description can not be blank or the + default of << New Validation Record >>. + + C. Unused fields in the Validation Editor Insert/Modify command + will now display *None*. + + D. The Validation Editor Insert command will now display the + Validation Record information for editing verses just inserting + the new record and then requiring you to go to the modify + command to edit. You will not be able to save the + new validation record until all of the above items are correct. + Upon completion of editing the inserted record, you will + be prompted to save or discard the new validation record. + + E. Other changes included added some missing help data for + certain commands and color changes. + + 3. I recommend that you access the Validation Modify command + once you have installed this update and toggle thru all + the validation records and make corrections as they are presented + to you. + + + diff --git a/SOURCE/UNUSED/CHANGES.TXT b/SOURCE/UNUSED/CHANGES.TXT new file mode 100644 index 0000000..ca402c3 --- /dev/null +++ b/SOURCE/UNUSED/CHANGES.TXT @@ -0,0 +1,38 @@ +Renegade changes/bug fixes: + +1. File Downloads - + + A. If an actual protocol (Like ZModem) was the first protocol + (or record zero), the downloaded file would not have the UL/DL + ratio checked. This was do to the ratio being set to look for + protocol records from [1..200]. Also, the maximum protocols + allowed at present is 120. The above should have been [0..120] + to be correct. + + B. For the ratio check, the FindFirst procedure would look for the + file on the harddrive even if the ratio didn't need to be checked. + This procedure was moved to only get the filesize if the ratio + needs to be checked. This applies to unlisted downloads, etc. + + NOTE: The FindFirst procedure would allow searching of any type + of file on the hardrive. This has been changed to not allow + searching of Directory, VolumnID, Hidden & SysFiles. + + C. In the present version, duplicate files could be added to the + batch download queue. This alpha release no longer allows + duplicate files in the queue. + + D. Downloading any file locally would place an entry in + the sysop.log that the DL was successfull, fixed. + + E. Adding a file to the batch DL queue will no loner indicate in the + sysop.log that the file was downloaded successfully. Now, it + will either indicate that the file was added to the batch queue or + that an unlisted file was added to the batch queue. Adding a file + to the queue doesn't complete the DL. + + F. The ASCII download of a file has been modified. The allow + continue prompt and a pause after the DL has been added. + +Enjoy!!! + diff --git a/SOURCE/UNUSED/CHANGES1.TXT b/SOURCE/UNUSED/CHANGES1.TXT new file mode 100644 index 0000000..9381d28 --- /dev/null +++ b/SOURCE/UNUSED/CHANGES1.TXT @@ -0,0 +1,44 @@ +File download buf fixes/enhancements: + + 1. The Star procedure would carry the last color to the next + line, fixed. + + 2. Downloading a file locally would increment various dl statistics, + fixed. + + 3. Downloading an unlisted file locally will now prompt the sysop + or user for a path to copy the file to (Like a regular download + currently does). + + 4. The copy command for local downloads, local unlisted downloads + and copy from CDRom now gives more detail as to the status of + the copy both to the user and sysop.log. + + 5. Viewing a text file will now indicate that it was viewed vice + downloaded both to the user and sysop.log. + + 6. Attemtping to view a text file that is missing will no longer + increment the DL statistics. + + 7. The system should no longer allow downloading or uploading of + batch files locally. It should also no longer increment DL/UL + statistics for batch transfers. + + 8. The user record was saved everytime a file was selected for + download even if the download was aborted or not completed, + fixed. + + 9. There was an error in the checking of DL codes against the + returncode when downloading files. The DL codes in the + protocol record are currently strings. This string was being + converted to a numeric value internally even if it were empty. + The string to numeric conversion routine would interpret this + empty string as a value of zero. Since the value for success + was set to a zero also, the system would assume a successful + result. Now, if the DLCode is a null string, it is not compared + against the return code. You may now have to input a zero into + one of the DLCodes in the protocol record for a proper comparison. + This also applies to the ULCodes in the protocol record. + + 10. Removed an extra file area initialization procedure in the DLX + procedure. \ No newline at end of file diff --git a/SOURCE/UNUSED/CHANGES2.TXT b/SOURCE/UNUSED/CHANGES2.TXT new file mode 100644 index 0000000..6fb01fa --- /dev/null +++ b/SOURCE/UNUSED/CHANGES2.TXT @@ -0,0 +1,57 @@ + +Additional Message Editor Changes: + + 1. Non-abortable message changes (New User, etc): + + A. File attachment not allowed - Attaching a file + would change the original subject of the message. + + B. Title change not allowed - The original receiver and + subject should remain the same. + + Note: The user can not abort or save a message that + contains no text. + + 2. File attachment changes: + + A. In previous releases, a user with file attachment access + was not warned if they tried to attach a file when a file + was already attached. However, this basically allowed the + user to swap out the file should they attach an incorrect + file. In this release, if a file is already attached, the + attached file will be displayed and the user will be prompted + to replace the file. I took this a step further, a user may + also want to remove the attached file all together. Presently, + there is no option for this without aborting the message. + Therefore, an option has been added for removing the attached + file. In this case, the user is also prompted to change the + message subject. If the subject contains no text, removing + the attached file is aborted. + + 3. Error messages: + + A. I did not feel there was adequate messages to the user as to + certain editor options. So, this area has been greatly + expanded. For example: Pressing "C" to clear a message + when the message contains no text, now informs the user of + this situation rather then nothing at all. + + 4. Empty messages: + + A. In an effort to reduce the possibilty of an empty message being + saved, the following apply: + + 1. All null lines at the end of a message are deleted. + 2. All lines at the end of a message containing nothing + but spaces are deleted. + + NOTE: Lines are reviewed in reverse order up to the first + line containing text. The user will not be able to + save the message unless it contains some kind of + text. + + 5. Title change: + + A. In certain cases, changing the title would actually remove + the subject of the message. I believe this error has now + been corrected. \ No newline at end of file diff --git a/SOURCE/UNUSED/CHANGES3.TXT b/SOURCE/UNUSED/CHANGES3.TXT new file mode 100644 index 0000000..94d494a --- /dev/null +++ b/SOURCE/UNUSED/CHANGES3.TXT @@ -0,0 +1,18 @@ +Renegade enhancements/bug fix's: + + 1. Removed a duplicate procedure for crediting the uploader for a + file that was downloaded by another user. + + 2. During a batch download, if no DL/Temp log was specified in the + protocol editor, the uploader did not receive credit for the + download. Other system/user statistics were updated though, + fixed. + + 3. The above credit procedure never worked anyway due to some + calculation errors in the code, fixed. + + 4. A message telling the user to enjoy the file was only displayed + if the user was charged file points, fixed. + + 5. Messages to the user and the sysop.log provide additonal + information about the Single Download. \ No newline at end of file diff --git a/SOURCE/UNUSED/CHANGES4.TXT b/SOURCE/UNUSED/CHANGES4.TXT new file mode 100644 index 0000000..c8608c5 --- /dev/null +++ b/SOURCE/UNUSED/CHANGES4.TXT @@ -0,0 +1,133 @@ +Renegade BBS Enhancements/Bug Fix's: + + 1. Before the posting of a message or uploading of a file + (Batch/Single), the available drive space was checked to + ensure adequate space exists according to the system setup. + This section of the code was duplicated in 3 places. I converted + this section to a function reducing numerous lines of code and + extra variabes whenever it was utilized in the code. + + 2. The copy/move procedures are now combined into one function. + Variables for failure, no space and success were required + external to the procedures everytime they were called. Various + messages to the user/sysop.log were also reported external + to these procedures. I also noticed that the move procedure + called the copy procedure if renaming a file was not successfull. + Now, no variables are required externally for the function and + messages to the user/sysop.log are handled internally within + the copy/move function. + + 3. I noticed that a section of the code for executing file + transfer's was duplicated in 4 places. This has been moved to + a single procedure reducing numerous lines of code and + variables. + + 4. I noticed that a section of the code for checking the return + code on file transfer's was duplicated in 3 places. This has + been moved to a single procedure reducing numerous lines of code + and variables. + + 5. The FILES.BBS selected for download during a batch transfer by + the user now contains this starting entry: + + "(BBS Name) Batch Download File Listing" + + Previously, unlisted files were not written to the above list. + Now, they are with "[No Description Available]" as the description. + Also, files in the batch download queue with a bad path download + path will have "[Bad Download Path]" as the description. These + additions help account for files selected for Batch DL by the + user. + + 6. The max dos character field in the protocol editor has now been + limited to 127 characters (Was 255). I always thought it was 128, + however I couldn't type in any more then 127 characters on the + command line in DOS. Please feel free to check this out for + yoursele and change you editor accordingly. + + 7. Removed spaces from the file name written to the protocol file + list for batch downloads. + + 8. The procedure that reads the success/failure codes and file name + from the protocol temp log has been modified. The starting + position of the code and file name is specified in the protocol + editor. Assumming you set this up correctly, the success/failure + code and the filename are copied to temporary strings. The success + code is compared against the returncode from dos for single + download/upload protocols or the DLCode specified in the protocol + editor for batch downloads and the temp log. This code is not + utilized for batch uploads, the file is simply checked for existance. + The temporary file name is compared against the batch queue for + existance. Since different protocol programs like dsz, etc utilize + different log formats, it's impossible to tell the actual length of + the success code or filename read from the temp log. RG would simply + read each string from the starting position and then chop off any + trailing spaces and compared them as per above. However, with ZM + protocol, the file name ends with ",". Therefore, I changed the + comparison to look for the success code/filename to a String POS + procedure rather then String = String. In local tests (Both Single + and Batch) it seemed to work without issue, we will see? The way it + was handled before did not work with ZM protocol. Hopefully, this + solves it for all others (assuming you set things up correctly in the + protocol editor. + + Here's a few things I learned about protocols while editing the + RG code: + + 1. If you set the option "Codes mean" in the protocol editor + to "Transfer Successfull", you must specify a return dlcode + and or ulcode for single protocols of zero. Zero is hard + coded into the procedure that executes the protocol. A + return code of zero from DOS indicates a successfull result. + Of course, you could also reverse the above and specify + "Codes mean" as "Transfer Failed" and specify all possible + DLCodes/ULCodes as something other then zero. + + 2. If you do not specify a temp log for batch downloads, no + error checking occurs within RG. RG assumes the files were + downloaded and increments statistics, etc. RG does not create + the temp log, you must add it to the DL/UL command line. You + must also specify the proper file name and status starting + positions within the log for RG to locate them. Please + read the protocol document for a description of the log + entries and then count out the status & filename positions + for the protocol editor. + + Here's what you need for the ZM protocol: + + 1. Specify a Temp Log. + 2. Add -lz%L to the DL/UL Command Line to create a ZM + style log. + 3. Set "Codes mean" to "Transfer Successfull". + 4. Set DL/UL Code 1 as Z, Set DL/UL Code 2 as z. + 5. Set "File name" to 22. + 6. Set "Status" to 1. + + OR + + 1. Specify a Temp Log. + 2. Add -ld%L to the DL/UL Command Line to create a DSZ + style log. + 3. Set "Codes mean" to "Transfer Successfull". + 4. Set DL/UL Code 1 as Z, Set DL/UL Code 2 as z. + 5. Set "File name" to 51. + 6. Set "Status" to 1. + + 3. The temp log is deleted by RG automatically, if you need + or want a permanent log please specify a UL or DL Log. + + NOTE: I realize some of you may know all there is to know + about protocols and how they are handled by RG. However, + some do not. Remember, if you do not specify all the above, + your files will be transferred without error checking and + statistics will not be updated. Of course, you could forgo + the above setup and RG will assume all files tranferred + successfully. + + 4. Using the above setup may or may not work with currently + released versions of RG or all external protocol programs. + +Please feel free to drop me an email if you require any further +explanation of the above! + +Enjoy!!! \ No newline at end of file diff --git a/SOURCE/UNUSED/CHANGES7.TXT b/SOURCE/UNUSED/CHANGES7.TXT new file mode 100644 index 0000000..cb20b72 --- /dev/null +++ b/SOURCE/UNUSED/CHANGES7.TXT @@ -0,0 +1,42 @@ +Renegade Updates/Enhancements: + + 1. A file can no longer be copied onto itself or moved to the same + directory it currently resides in. + + 2. In local mode, you must have CoSysOp access to move or copy an + attached file or file selected for download. + + 3. I noticed that download and upload statistics were displayed for + batch transfers even if "Log-off after file transfer was selected", + but not for single download or upload transfers, fixed. + + 4. Some items selected for download went thru the DLX procedure and + some went directly to the send procedure. Alot of extra code and + variables were required for the send procedures everytime it was + called. Now, all download requests go thru the DLX procedure and + then to the send procedure. With this change, file downloading + can be tracked for all downloads thru the same statistcal process. + This includes, File attach, QWK, Unlisted and user archive. + + 5. All regular downloads were checked to ensure the user met all + security requirements, ratio, etc prior to the download. However, + if a user was exempt from certain ratio checks, the user was + charged anyway for the download unless the file area was marked + as No-Ratio. This applied to users flagged as No UL/DL Ratio in + the User Record, No UL/DL Ratio in the System record, etc. + + 6. You will now be asked if the file exists on a CDROM for unlisted + downloads. This will alow for faster file transfers since the + file is copied from the CDRom to the Temp Node Directory for + download. + + 7. The default file name for extracting text from a message has been + changed from "MSG.TXT" to MSG.TXT. Of course, you still + have the option of changing this to whatever you like at the + prompt. + + 8. For Offline mail transfers, the bbs will no longer attempt to copy + the WELCOME, NEWS or GOODBYE file if they path to the file is + blank. + +Enjoy!!! \ No newline at end of file diff --git a/SOURCE/UNUSED/CHANGES8.TXT b/SOURCE/UNUSED/CHANGES8.TXT new file mode 100644 index 0000000..43ab41d --- /dev/null +++ b/SOURCE/UNUSED/CHANGES8.TXT @@ -0,0 +1,35 @@ +Renegade updates/enhancements: + + 1. Fixed a bug related to the length of the dlcode/ulcode in the + protocol editor. The maximum length of this string is 6 chars. + + 2. No process was in place to prevent ul/dl statistical variable + overrun, fixed. + + 3. The color from the auto-logoff countdown procedure carried the + last color to the next line, fixed. This would only be noticed + if the user escaped or cancelled the auto-logoff. + + 5. The color from the scaninput procedure carried the last color to + the next line, fixed. I noticed this with the batch download file + remove command. + + 6. Since files added to the batch downloaded queue are listed as such + in the sysop.log, it only made since to list files removed from + the batch download queue in the sysop.log as well. An entry to + the sysop.log is also made when the batch download queue is + cleared. + + 8. The uploader name/date and the message to the user to continue a + resume file did not redisplay the file name when wrapped to the + next page while utlizing the file list command, fixed. + + 9. I think I finally have some issues corrected with the file + listing display. Every now and then an extra file area + header would display when not needed. Also, sometimes the line + counter would be off by one or two lines and push the file area + header up one or two lines or completely off the screen. I also + noticed a line feed missing when the listing was aborted or + exited normally. + +Enjoy!!! diff --git a/SOURCE/UNUSED/CHANGES9.TXT b/SOURCE/UNUSED/CHANGES9.TXT new file mode 100644 index 0000000..3d00d14 --- /dev/null +++ b/SOURCE/UNUSED/CHANGES9.TXT @@ -0,0 +1,29 @@ +Renegade bug fix's/enhancements: + + 1. Due to space limitations, the file listing display will utilize + bytes or kbytes depending on the file point settings in the + system configuration. To be consistant, this process is now + also being utilized for the file size displayed when a file is + selected for download. + + 2. When a file is selected for viewing, the user will be cautioned + that the file is not checked to ensure it is an ascii text file + and then asked if they would like to continue. + + 3. The file listing download and add batch prompt has been cleaned + up. It would formally allow input of '-' by itself or the '-' + proceeding or following a file number and alpha characters. The + input of an invalid file number will now display a message to the + user. + + 4. Adding a file to the batch queue from the file listing display + will now display all the file information related to that file. + It will also now properly check the file to ensure it is ok to + download and send it thru the proper ratio checks. I have to + admit that this was an oversite on my part when I added the + ability to select a file by number. Basically it now goes + directly thru the DLX procedure vice being added directly to + the batch download queue. + +Enjoy!!! + diff --git a/SOURCE/UNUSED/CHNAGE2.TXT b/SOURCE/UNUSED/CHNAGE2.TXT new file mode 100644 index 0000000..56cc9e3 --- /dev/null +++ b/SOURCE/UNUSED/CHNAGE2.TXT @@ -0,0 +1,27 @@ +Renegade Enhancements/Bug Fix's: + + 1. Close Mail Box/Mail Forwarding - + + A. Both of these procedures have been cleaned up with + slight verbage changes and a reduction of variables + required. + + B. A user with access to the User Editor can no longer + setup a user with mail forwarding back to the same + user. + + C. Mail can no longer be forwarded to a locked out user. + + 2. Private Message Read - + + A. This procedure has been cleaned up with slight verbage + changes and a reduction of variables required. + + B. The Message Listing will now display one screen at a + time vice scrolling to the prompt. Entering a "?" + will redisplay the message listing starting at the + first message. Pressing will display the + next screen of messages and or start back at the + first message. A valid message number must be entered + in order to exit to read the message. + diff --git a/SOURCE/UNUSED/COMMON.TPU b/SOURCE/UNUSED/COMMON.TPU new file mode 100644 index 0000000000000000000000000000000000000000..3c0b306e389c09c1cb49bcceefb8e38885e69887 GIT binary patch literal 125632 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

$H4^pEXKF6KiCLnQa<5{b~+PY5C5+H z@`GIN^R=!NvTie+?l{MhcY`Kpy=C~Y<5owlAC-Q;;}J)`t0w0=VW{&r<*#!gVG&qC zznF+VpY-iWC+y?M`p`K0GQ&$96_@O)9ocso-{82#@nzawc5S@9bB(9rKdPrQ;KToq zet6n{=$o`#>x4gzOT|@z{YbD7u5$x@zt08xg5&Vp#Q2Zazx~+1vrol-soVX+cniis zluqC0TPAJdw%QT%I^tK`E3T3AL|l(|6Bkn-*H~fs9wA19K-6n+{<~f=R42yUF`Y&+>!EG zzK?mnzkw^?Mo{^_2rAz{gMFzt)~i%opYU`?)nkDE$KZbSOTh%?yT|e z0YCaac9TES(N5HN4_MSLI{#C+rpq}wO98`UdGP}HF)IWRao~cQ-!S@b#c}ez*@ZS6$ zA@VZ=tiYeFt3zoJaqQBay_0wGwdC_hn?Cr#=1k;o%MwFbNSBCah!r&<7c+xoV01yE|sol zT|<4A1zOK2{vBW~_y(x*y#pq|k4ayS|FraIJ(&T@Z``qy-FI?Ildj~`CzT@4M}Lv) zFE@RkU`~3}E=`gX_g~HaK=p@?M?GC?Gx<4C-KJUOXCSEjMmm<-ePy3u23+HDmCNsU ze3X03M&jPnOzn{tyaiYNw{NcUP6>K8m;dD#_UAs+`k&u#o@M%h!MTQ`g7ce4`|c9A zo9=d(H;>L4ZU+O(@c>xD{P1f_*Ng9`{O2Y6JJOHsyoPZ~{=@COR`q>7^LrKjaRL2Q z^?hQ0R*QW({+Rd8Po3d`>R&l(K2o{)4w%1fhGqI)8N8RiH->y?EIsQ)a6pppBJwVb z?C2g(>!(B%2m0M{&gDyLh)45874qfA(`-E^&ir8MH}N~a;c%OODgQHOm!Wq#Rv#}L z&$9C_rF+BEy=T}@`$hX6YQE6?*&NIV^}96flRMacFE2R7=YxKR1Cj&L*J8(fLA=Zd zX4lX5%W4Om=e7p5o|4^CP;&k5MRL6(m;6af*FM`kn|Efr{%s;@U|355N`I2A8YdH>Rbt4vG5nU+_~y zes94)pdLSTySB{3O8?#WA@Z-^9m@X%)5n5RxW>grltcF8?*2?r}?( zZR=yjwZ-MUmmK)cqfTIC%6JG zJ^OcyYk_lp7i7O2x%{v3bi9KiU6)`7TyeeZ^1~)SCHM?3e_wgJZ{dn7i+Nu4F)TGo zKMF3pbNo9|;`%wJ?;Xr{{Y`vNRA0-TuWRluv@H~D?TTCfTJJDYDZG8@sC!~Xy(?j}o@68y#ao8CY6 z!xQNL?S6ItSOwR;d_DcCE$t)T&BlF3rtTr-cQ7cwx|dIYMZBlj32J{O&hK+b-#nND zuY#+;R8p>GU={UyCvy4umD#nh`9c2by?^NU2GYOe`ai*?=UmAAykYZ29=|_`zT@w^ z{ZX^e=3Pc)f0DOrbJ|t@I??X+^t0~X?z*p6T>WjH$kXpmY<-~j(XwYA!M<%U!R<@k zU%Bgl?D`7VU+4aKw@Y*6*?L8OR+wE*u*&T?N3#B~&i(w>^;=y3jQe>3`DWVt*R+fL zur97;wU(`WqDuH?Z$I`S*p0CFISJ(Zj9(jk`@YvWz^sjpQN7DLR2YXM`L_9l?SAb29 z?|47tduHcKhn({c$ojke?gjfElw0Z5zZB1C=QC2q+WQ918Jo0wpxuchS^1ISvbiUv zF1P!p99xIZ3&p`4 zKeThP+`=-$PUC)rd?WJcJg(EY>rK99+ydk|$ZvLjtJ|;DIu-ePI`2QGC1GX?|1wdUquG zTVMrv4*enlvVK9IWxso?f@?n{el>dW>y4)bYu)})-QFl=NMQAcAy`K58%7i zl-4R30i3h}j{O4tvc6FBqx$_7F25SC{;vBkrJrx|U9p=C z_r!bKI-BuHJRA9Lv;V-)H-%@Jyu#jXCMXZ`q4T`=h2eW4%nrA?;TULexBs(;%Vl0U(3$!Hy8Ua@ym|O()agu z^f0&A`Z^!K#g^{>w?F9p=YQ89YA2pz`7fWS_e<)Bic9_Ghs2*j`RNCCzcbP7j#Sg{ zsL!cE!qd&fUj1^8^Z9V~$Et{z-U`p9oOio^JzV{BBdB~HHTkX>`&Qbeb|U*!aQVa{ z^omFOAK8&_No(S{+~c{*?Q~C}{BLx=7_Rbjk7<7Hfh)hY#*b7-{b_mWZ;&glr%k>m z{ycswN%sn5E^TPb;1Q9?uAmXSDk% zp?rNQpW<$!p7bswf&Gc|-ePzayc{G$`#%5)Q18ve?gm(kg zKDwV6j{J0gPf%ufUiW!H^xpjiumJzNu~S_C1eM>{pyCSfn*g+a)cKEo@81NT4;J8e z2B>_lwDs4n*wt{^AEX}lGTzyj*#5es%X@*!XC&Xz0_v#%u6*QI>GWP&`Z=agwckHW zf0OHf?&ZDL^y%F9&`&AvgD!u<rX-gEzlEd8~?r{dJ}H`vMl1g#&jE91K? zel4heQVA-)g|?pD6GuSyuv5HRmn!{}pyGWRJJrXtX7}4*m)q@j zJFQn`cNn`5=og>+IczKT$5q60D(ip*daYw?z(VI&*t%d(Jd^&i8UG!@jbL;?P+xd9 z<8&wXXV4#&ehm5&^xA)@U9JUHUpjA5`E(v9&Udw>gnXm#Y0=+FSWSKv)D!c&ookQAK7svMxbi77o^Jo&O8g?ysa;sNV3)!7B&zSF?r){Z zTiW|X**)m`$4$<7aK6R;Z-@8AZV;FcYCg^&pG&|5obOkYZr?Jn-${8}fsJ5?V49Ur zaqC?b@nTn?_cfeZ*gII>*z4RQvYUlm9DioN)aA=O9qnZ4_zqcq9jspaCwpQy3xB7A z72p|QK3G6`)SswdyT{V^xQ;k31eFixwfH$Th`z`DlUKT*3ing#eyYI|{MC5Atb1xX zRY(qSd*xSw{w%lWULAdK(ggCaA%ES+Yd)L`sva)It~CZf^>}VDe{YXx{TJk;Ujmj8 z-z|={;AZ4cfIE@XE=?-k4mf}4z6>~(d-W);4?V6U9@oD;uJn_laxl-seH z>D9j<2G#$b1_{XCl~;l~=S+Z{b09u={`>GM_+j^ZocLP9dEaFD53%wbsHXqnzITxA zsP~(7*mX1>>KzFBGGC|mqQ;nS(6f#-ByRFMRQ(gU=8GH2w~6={S-LL#o=W<>&&TjK5zjGn3etL&x_dC;!_YN+za%GqP zkT_JIs(;NVCA3E!?J))anm;cE>p;zC3CeT3#hG1tAAB?N2b?#+H^P~}C`Web^KiwZ z_a!x?+voVD>-8QyfnL8aQNE-7yFJFgi_E(v8;N5$>C|po|0;jQDZC8K2Z`7A1N4`Y zdhE3hlRe`Oo?`d8vSYsD4M=oOB>hsi*E(4IcK5s1{XPbkBmbN8|M7fItVfP}dfihh zz23Rkr#H8APvyruIm@rV>v>;l@trvT{Ou(HAm4PTUvhoqr{9-v(BIcbT8mfcJnF|3>7B^D+1LwE0`r;zj4Yvmvhb zWuH6OI!pO-FNC~i?tqllHvbMXK6ly~hC8R~97XLv*7)|R7r@odI#=18o^IzV;#1vU z^e%8;Oa1=^rQ;kI|J$cldAg;ZPWR7Bce|%sYj%su>rI~${Lb+y)>EpdMz`brAO7B1 z@`m#d?7VMg!0)cDy>w5Vz;8S{r#ru^bIxl>_sj8TvmR2v(z&1PCYijU^fKoa=xeFp zYB)Iuzi|6IU0-MR%S$&oXB~#$Bh|0C-D@sC;C{bCuKD0w)@hs5V?i@pUp17r^mCZj zUr+;lGKmETY<$JEl_m&nr zzr^}sneNq^wCbra?8W(F6hHSB_F(#mv2dnerNqhNA-8r%eQ7x0+ zMd4?L3&Jnm&oS4xu=D--VHd-BVJ_$Vs;8d3ACaHaOx`Oz7rEMDg3G7EODOM5-kUV0 zcMYy{dD7*}Ox`QF*X0iz9~3;{yb)A=?Kl5p!o!AR!~Ze6VZkxy+4gQ_OxUJ*v8{to z2Fr=7Q}d|*-KA0zQN>U z!v@1K;a2i3z~4^v`QWQAf79*Warr^_|GE1~$x!_a3tD7Eapr(3_wWq0SIykQjMa7z zR-6&Vb&=a$;rcn~OUQ4Y@l{iAaD9#Oq2W5iA>l(AQT=QLRX>lq-B#0oI`vQZFG;0e zWQ?`?+KXQ0co(_q=_9v4YW5AKEm|neA3W#wJKgR> zv+EoGvPH42kB_^bteE2MAMYNEzS8Au zT>fj54~#$U@@HM%Wbz^L11>-4@-Iw2G~T>r6i-&mD4s4Y^MeZ3Cj&wC$DuAi7gRkY zT3R{6pSu1A*WY6D_GK%a*SUS8$$N&o4U12I%dqJ5eWX|WzUTIzn0!%q%y2=No~e8) z!z{xEVVg|$9rTm_nQH$D!D(={a{*{^ncbP;e8b`4jhRuuTL`M(Ephu5mj1%vKIfav zzM=H@j(>1`KQmgFe1x6))ls)^mZi9kmd3N9{BuF&Utsbjl_gp0Y}`!Fit6uDx4YW( z-QtT}UgPq+Ox``d!R1f5{27zy#+zLJrpphS{FL}tE>F#l;%J?%xPB1tksakbz~v)M z-Xng2%O|;fhRJ8duQN=b1iZ^H-#hcYyan27r8qN!Q7*>S+oe#oJ{d8RGsGk;lx=TRix6tgihqs!(G^lm` z{U+ZUZZP@e;8B-vb@>Y>za-e@@;6+5z~nQ6gD(HV_*KC-&NJhRw@=tD9@S&txZ?Ur zkQa~EtNEty8;*4Sc`h#m6BPR*(?1i=Mz4Cf&gDx?zCFCl<#jH9)Z|;kMwh?r^1Uwq zr^~-^d1@QQw>50vCh~tun<(FbCJ)1rZ4_@sFb=uKagoa}!e0GiI`T^7mwCDh({Bqa zE#1Okk;`v0o(xtxU+;Fm^L!g!{tBpe`q=bSGrw?odRxU=of&T%#g}WmPu2kEBaPpb zJo!FzgaMWp;nbe97(h8owp{$S@fmY8TD(M_m7{$v0)jPWCuK)%Vbo74Oa0o_BK8 zt{1xgVw3Nkca6)hcX`s&tuuW?X+3)FBcF8r^R9mnc@_QR8<)r0N4!t_DE}eOCpw?r zKA$+|$LAQ%i(iLc->Dm1e~Za`hO3dQ|E+WRVCCSMg^YPd4I-1S$wexAwi2!Cc+ z8~(!ex4ZtACSMXhZdesIxc>L9f5GHy!`BUe8NTKEeXjpkhv@f+$DL>8DDJz%?uKi^ zALK;m{&_i^=TmP(;R*0ucrE3eoD;1#rn!8!r7M~+-}zGGrQvGBp5gtGzVjo7#ho9= zkLrDk+wU;>+2LNpQQ_O@)n5Bu|FOvnIIQ*euemJ&c^uFwT zQ2CU){iSYK>2?b`M(c~kpys8d+udpUe&Iu&{&AOYHTm*zx8btzRrHGUb=SXd@*BgW zhLz#huK(8cnVl5p+_1Z0MfihGQTjfeydT4>_%4nG6?d`ArE`JbIy)>GBRQ5|Q-|O~XYCPTUuf#7l-rUZS#b=T} zz%TdrcHTG_)O`x~LgW*(_k_}~cloo9I~{ii(LMHlumFGm1o6o4tD}37FYwbuytBB^ z`vf`u;c5KNC;ES8+{?iA|1_g|(mjUi;{h)Z_fqKF+Iw=v`vmE9KKP{jz&W$qQ{N5Y;e)fM_s_?Jh{pcR$T$2y6|HC4= z{;!kdKXT-}nsh^hRdDIoffe9JFaiD^EC+S|s`BU@TJh_CI{|hD3&>yZ8fSq8U@qUO ziQs`9Vw^s89;q}K)v)! F`(N-hjWqxO literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/COMMON1.TPU b/SOURCE/UNUSED/COMMON1.TPU new file mode 100644 index 0000000000000000000000000000000000000000..b85e3297f4749bd8deecaffbb5f8f92af179ade7 GIT binary patch literal 10976 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

i4(^^P_0%kh^g@ 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 O$!~j{5~mUB-~R?x&1KI3 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/COMMON4.TPU b/SOURCE/UNUSED/COMMON4.TPU new file mode 100644 index 0000000000000000000000000000000000000000..d582b499d05ff1b5c18a3aa348f849b8e9b3aa8f GIT binary patch literal 4656 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/CRC32.ASM b/SOURCE/UNUSED/CRC32.ASM new file mode 100644 index 0000000..3d120b9 --- /dev/null +++ b/SOURCE/UNUSED/CRC32.ASM @@ -0,0 +1,193 @@ +IDEAL +; This CRC-32 routine and tables were converted from code discovered +; in the DEZIP.PAS V2.0 by R. P. Byrne. The comments there are: +; +; Converted to Turbo Pascal (tm) V4.0 March, 1988 by J.R.Louvau +; COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or +; code or tables extracted from it, as desired without restriction. +; +; First, the polynomial itself and its table of feedback terms. The +; polynomial is +; X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 +; +; Note that we take it "backwards" and put the highest-order term in +; the lowest-order bit. The X^32 term is "implied"; the LSB is the +; X^31 term, etc. The X^0 term (usually shown as "+1") results in +; the MSB being 1. +; +; Note that the usual hardware shift register implementation, which +; is what we're using (we're merely optimizing it by doing eight-bit +; chunks at a time) shifts bits into the lowest-order term. In our +; implementation, that means shifting towards the right. Why do we +; do it this way? Because the calculated CRC must be transmitted in +; order from highest-order term to lowest-order term. UARTs transmit +; characters in order from LSB to MSB. By storing the CRC this way, +; we hand it to the UART in the order low-byte to high-byte; the UART +; sends each low-bit to high-bit; and the result is transmission bit +; by bit from highest- to lowest-order term without requiring any bit +; shuffling on our part. Reception works similarly. +; +; The feedback terms table consists of 256, 32-bit entries. Notes: +; +; The table can be generated at runtime if desired; code to do so +; is shown later. It might not be obvious, but the feedback +; terms simply represent the results of eight shift/xor opera- +; tions for all combinations of data and CRC register values. +; +; The values must be right-shifted by eight bits by the "updcrc" +; logic; the shift must be unsigned (bring in zeroes). On some +; hardware you could probably optimize the shift in assembler by +; using byte-swap instructions. +; polynomial $edb88320 +; +; +; +; The Pascal logic is: +; +; Function UpdC32(Octet: Byte; Crc: LongInt) : LongInt; +; Begin +; +; UpdC32 := CRC_32_TAB[Byte(Crc XOR LongInt(Octet))] XOR ((Crc SHR 8) +; AND $00FFFFFF); +; +; End {UpdC32}; +; +; This routine computes the 32 bit CRC used by PKZIP and its derivatives, +; and by Chuck Forsberg's "ZMODEM" protocol. The block CRC computation +; should start with high-values (0ffffffffh), and finish by inverting all +; bits. +; +; This TASM conversion done by: +; +; Edwin T. Floyd [76067,747] +; #9 Adams Park Ct. +; Columbus, GA 31909 +; 404-576-3305 (work) +; 404-322-0076 (home) +; +; Borland's Turbo Assembler - TASM is required to assemble this program. +; +SEGMENT code BYTE PUBLIC + ASSUME cs:code + +; 0 +crc32tab dd 000000000h, 077073096h, 0ee0e612ch, 0990951bah + dd 0076dc419h, 0706af48fh, 0e963a535h, 09e6495a3h + dd 00edb8832h, 079dcb8a4h, 0e0d5e91eh, 097d2d988h + dd 009b64c2bh, 07eb17cbdh, 0e7b82d07h, 090bf1d91h +; 1 + dd 01db71064h, 06ab020f2h, 0f3b97148h, 084be41deh + dd 01adad47dh, 06ddde4ebh, 0f4d4b551h, 083d385c7h + dd 0136c9856h, 0646ba8c0h, 0fd62f97ah, 08a65c9ech + dd 014015c4fh, 063066cd9h, 0fa0f3d63h, 08d080df5h +; 2 + dd 03b6e20c8h, 04c69105eh, 0d56041e4h, 0a2677172h + dd 03c03e4d1h, 04b04d447h, 0d20d85fdh, 0a50ab56bh + dd 035b5a8fah, 042b2986ch, 0dbbbc9d6h, 0acbcf940h + dd 032d86ce3h, 045df5c75h, 0dcd60dcfh, 0abd13d59h +; 3 + dd 026d930ach, 051de003ah, 0c8d75180h, 0bfd06116h + dd 021b4f4b5h, 056b3c423h, 0cfba9599h, 0b8bda50fh + dd 02802b89eh, 05f058808h, 0c60cd9b2h, 0b10be924h + dd 02f6f7c87h, 058684c11h, 0c1611dabh, 0b6662d3dh +; 4 + dd 076dc4190h, 001db7106h, 098d220bch, 0efd5102ah + dd 071b18589h, 006b6b51fh, 09fbfe4a5h, 0e8b8d433h + dd 07807c9a2h, 00f00f934h, 09609a88eh, 0e10e9818h + dd 07f6a0dbbh, 0086d3d2dh, 091646c97h, 0e6635c01h +; 5 + dd 06b6b51f4h, 01c6c6162h, 0856530d8h, 0f262004eh + dd 06c0695edh, 01b01a57bh, 08208f4c1h, 0f50fc457h + dd 065b0d9c6h, 012b7e950h, 08bbeb8eah, 0fcb9887ch + dd 062dd1ddfh, 015da2d49h, 08cd37cf3h, 0fbd44c65h +; 6 + dd 04db26158h, 03ab551ceh, 0a3bc0074h, 0d4bb30e2h + dd 04adfa541h, 03dd895d7h, 0a4d1c46dh, 0d3d6f4fbh + dd 04369e96ah, 0346ed9fch, 0ad678846h, 0da60b8d0h + dd 044042d73h, 033031de5h, 0aa0a4c5fh, 0dd0d7cc9h +; 7 + dd 05005713ch, 0270241aah, 0be0b1010h, 0c90c2086h + dd 05768b525h, 0206f85b3h, 0b966d409h, 0ce61e49fh + dd 05edef90eh, 029d9c998h, 0b0d09822h, 0c7d7a8b4h + dd 059b33d17h, 02eb40d81h, 0b7bd5c3bh, 0c0ba6cadh +; 8 + dd 0edb88320h, 09abfb3b6h, 003b6e20ch, 074b1d29ah + dd 0ead54739h, 09dd277afh, 004db2615h, 073dc1683h + dd 0e3630b12h, 094643b84h, 00d6d6a3eh, 07a6a5aa8h + dd 0e40ecf0bh, 09309ff9dh, 00a00ae27h, 07d079eb1h +; 9 + dd 0f00f9344h, 08708a3d2h, 01e01f268h, 06906c2feh + dd 0f762575dh, 0806567cbh, 0196c3671h, 06e6b06e7h + dd 0fed41b76h, 089d32be0h, 010da7a5ah, 067dd4acch + dd 0f9b9df6fh, 08ebeeff9h, 017b7be43h, 060b08ed5h +; A + dd 0d6d6a3e8h, 0a1d1937eh, 038d8c2c4h, 04fdff252h + dd 0d1bb67f1h, 0a6bc5767h, 03fb506ddh, 048b2364bh + dd 0d80d2bdah, 0af0a1b4ch, 036034af6h, 041047a60h + dd 0df60efc3h, 0a867df55h, 0316e8eefh, 04669be79h +; B + dd 0cb61b38ch, 0bc66831ah, 0256fd2a0h, 05268e236h + dd 0cc0c7795h, 0bb0b4703h, 0220216b9h, 05505262fh + dd 0c5ba3bbeh, 0b2bd0b28h, 02bb45a92h, 05cb36a04h + dd 0c2d7ffa7h, 0b5d0cf31h, 02cd99e8bh, 05bdeae1dh +; C + dd 09b64c2b0h, 0ec63f226h, 0756aa39ch, 0026d930ah + dd 09c0906a9h, 0eb0e363fh, 072076785h, 005005713h + dd 095bf4a82h, 0e2b87a14h, 07bb12baeh, 00cb61b38h + dd 092d28e9bh, 0e5d5be0dh, 07cdcefb7h, 00bdbdf21h +; D + dd 086d3d2d4h, 0f1d4e242h, 068ddb3f8h, 01fda836eh + dd 081be16cdh, 0f6b9265bh, 06fb077e1h, 018b74777h + dd 088085ae6h, 0ff0f6a70h, 066063bcah, 011010b5ch + dd 08f659effh, 0f862ae69h, 0616bffd3h, 0166ccf45h +; E + dd 0a00ae278h, 0d70dd2eeh, 04e048354h, 03903b3c2h + dd 0a7672661h, 0d06016f7h, 04969474dh, 03e6e77dbh + dd 0aed16a4ah, 0d9d65adch, 040df0b66h, 037d83bf0h + dd 0a9bcae53h, 0debb9ec5h, 047b2cf7fh, 030b5ffe9h +; F + dd 0bdbdf21ch, 0cabac28ah, 053b39330h, 024b4a3a6h + dd 0bad03605h, 0cdd70693h, 054de5729h, 023d967bfh + dd 0b3667a2eh, 0c4614ab8h, 05d681b02h, 02a6f2b94h + dd 0b40bbe37h, 0c30c8ea1h, 05a05df1bh, 02d02ef8dh + + + MODEL TPASCAL + +PUBLIC UpdateCRC32 +PROC UpdateCRC32 FAR initcrc:DWORD,inbuf:DWORD,inlen:WORD +; UpdateCRC32 takes an initial CRC value and updates it with inlen bytes from +; inbuf. The updated CRC is returned in DX:AX. The Pascal declaration is: +; Function UpdateCRC32(InitCRC : LongInt; Var InBuf; InLen : Word) : LongInt; +; Stomps registers: AX,BX,CX,DX,ES,SI + push ds + lds si,[inbuf] ; ds:si := ^inbuf + les ax,[initcrc] ; dx:ax := initcrc + mov dx,es + mov cx,[inlen] ; cx := inlen + or cx,cx + jz @@done +@@loop: + xor bh,bh + mov bl,al + lodsb + xor bl,al + mov al,ah + mov ah,dl + mov dl,dh + xor dh,dh + shl bx,1 + shl bx,1 + les bx,[crc32tab+bx] + xor ax,bx + mov bx,es + xor dx,bx + loop @@loop +@@done: + pop ds + ret +ENDP + +ENDS +END + \ No newline at end of file diff --git a/SOURCE/UNUSED/CRC32A.PAS b/SOURCE/UNUSED/CRC32A.PAS new file mode 100644 index 0000000..0b8480c --- /dev/null +++ b/SOURCE/UNUSED/CRC32A.PAS @@ -0,0 +1,132 @@ +unit crc32a; +{ + /* ============================================================= */ + /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ + /* code or tables extracted from it, as desired without restriction. */ + /* */ + /* First, the polynomial itself and its table of feedback terms. The */ + /* polynomial is */ + /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ + /* */ + /* Note that we take it "backwards" and put the highest-order term in */ + /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ + /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ + /* the MSB being 1. */ + /* */ + /* Note that the usual hardware shift register implementation, which */ + /* is what we're using (we're merely optimizing it by doing eight-bit */ + /* chunks at a time) shifts bits into the lowest-order term. In our */ + /* implementation, that means shifting towards the right. Why do we */ + /* do it this way? Because the calculated CRC must be transmitted in */ + /* order from highest-order term to lowest-order term. UARTs transmit */ + /* characters in order from LSB to MSB. By storing the CRC this way, */ + /* we hand it to the UART in the order low-byte to high-byte; the UART */ + /* sends each low-bit to hight-bit; and the result is transmission bit */ + /* by bit from highest- to lowest-order term without requiring any bit */ + /* shuffling on our part. Reception works similarly. */ + /* */ + /* The feedback terms table consists of 256, 32-bit entries. Notes: */ + /* */ + /* The table can be generated at runtime if desired; code to do so */ + /* is shown later. It might not be obvious, but the feedback */ + /* terms simply represent the results of eight shift/xor opera- */ + /* tions for all combinations of data and CRC register values. */ + /* */ + /* The values must be right-shifted by eight bits by the "updcrc" */ + /* logic; the shift must be unsigned (bring in zeroes). On some */ + /* hardware you could probably optimize the shift in assembler by */ + /* using byte-swap instructions. */ + /* polynomial $edb88320 */ + /* */ + /* -------------------------------------------------------------------- */ +} + +interface + +type + pbyte = ^byte; + longrec = record + lo,hi : word; + end; + +var + crc32val : longint; + + +procedure updatecrc(s : pchar; len : integer); + +implementation + +const + crc_32_tab : array[0..255] of longint = ( + $00000000, $77073096, $ee0e612c, $990951ba, $076dc419, + $706af48f, $e963a535, $9e6495a3, $0edb8832, $79dcb8a4, + $e0d5e91e, $97d2d988, $09b64c2b, $7eb17cbd, $e7b82d07, + $90bf1d91, $1db71064, $6ab020f2, $f3b97148, $84be41de, + $1adad47d, $6ddde4eb, $f4d4b551, $83d385c7, $136c9856, + $646ba8c0, $fd62f97a, $8a65c9ec, $14015c4f, $63066cd9, + $fa0f3d63, $8d080df5, $3b6e20c8, $4c69105e, $d56041e4, + $a2677172, $3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b, + $35b5a8fa, $42b2986c, $dbbbc9d6, $acbcf940, $32d86ce3, + $45df5c75, $dcd60dcf, $abd13d59, $26d930ac, $51de003a, + $c8d75180, $bfd06116, $21b4f4b5, $56b3c423, $cfba9599, + $b8bda50f, $2802b89e, $5f058808, $c60cd9b2, $b10be924, + $2f6f7c87, $58684c11, $c1611dab, $b6662d3d, $76dc4190, + $01db7106, $98d220bc, $efd5102a, $71b18589, $06b6b51f, + $9fbfe4a5, $e8b8d433, $7807c9a2, $0f00f934, $9609a88e, + $e10e9818, $7f6a0dbb, $086d3d2d, $91646c97, $e6635c01, + $6b6b51f4, $1c6c6162, $856530d8, $f262004e, $6c0695ed, + $1b01a57b, $8208f4c1, $f50fc457, $65b0d9c6, $12b7e950, + $8bbeb8ea, $fcb9887c, $62dd1ddf, $15da2d49, $8cd37cf3, + $fbd44c65, $4db26158, $3ab551ce, $a3bc0074, $d4bb30e2, + $4adfa541, $3dd895d7, $a4d1c46d, $d3d6f4fb, $4369e96a, + $346ed9fc, $ad678846, $da60b8d0, $44042d73, $33031de5, + $aa0a4c5f, $dd0d7cc9, $5005713c, $270241aa, $be0b1010, + $c90c2086, $5768b525, $206f85b3, $b966d409, $ce61e49f, + $5edef90e, $29d9c998, $b0d09822, $c7d7a8b4, $59b33d17, + $2eb40d81, $b7bd5c3b, $c0ba6cad, $edb88320, $9abfb3b6, + $03b6e20c, $74b1d29a, $ead54739, $9dd277af, $04db2615, + $73dc1683, $e3630b12, $94643b84, $0d6d6a3e, $7a6a5aa8, + $e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1, $f00f9344, + $8708a3d2, $1e01f268, $6906c2fe, $f762575d, $806567cb, + $196c3671, $6e6b06e7, $fed41b76, $89d32be0, $10da7a5a, + $67dd4acc, $f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5, + $d6d6a3e8, $a1d1937e, $38d8c2c4, $4fdff252, $d1bb67f1, + $a6bc5767, $3fb506dd, $48b2364b, $d80d2bda, $af0a1b4c, + $36034af6, $41047a60, $df60efc3, $a867df55, $316e8eef, + $4669be79, $cb61b38c, $bc66831a, $256fd2a0, $5268e236, + $cc0c7795, $bb0b4703, $220216b9, $5505262f, $c5ba3bbe, + $b2bd0b28, $2bb45a92, $5cb36a04, $c2d7ffa7, $b5d0cf31, + $2cd99e8b, $5bdeae1d, $9b64c2b0, $ec63f226, $756aa39c, + $026d930a, $9c0906a9, $eb0e363f, $72076785, $05005713, + $95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38, $92d28e9b, + $e5d5be0d, $7cdcefb7, $0bdbdf21, $86d3d2d4, $f1d4e242, + $68ddb3f8, $1fda836e, $81be16cd, $f6b9265b, $6fb077e1, + $18b74777, $88085ae6, $ff0f6a70, $66063bca, $11010b5c, + $8f659eff, $f862ae69, $616bffd3, $166ccf45, $a00ae278, + $d70dd2ee, $4e048354, $3903b3c2, $a7672661, $d06016f7, + $4969474d, $3e6e77db, $aed16a4a, $d9d65adc, $40df0b66, + $37d83bf0, $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9, + $bdbdf21c, $cabac28a, $53b39330, $24b4a3a6, $bad03605, + $cdd70693, $54de5729, $23d967bf, $b3667a2e, $c4614ab8, + $5d681b02, $2a6f2b94, $b40bbe37, $c30c8ea1, $5a05df1b, + $2d02ef8d); + +procedure updatecrc(s : pchar; len : integer); +(* update running CRC calculation with contents of a buffer *) + +var + crcl : longrec absolute crc32val; + x : integer; + +begin + for x := 1 to len do + begin + crc32val := crc_32_tab[lo(crcl.lo) xor byte(s^)] xor ((crc32val +shr 8) and $00ffffff); + inc(s); + end; +end; + + +end. diff --git a/SOURCE/UNUSED/CUSER.TPU b/SOURCE/UNUSED/CUSER.TPU new file mode 100644 index 0000000000000000000000000000000000000000..22373fbd318a68d15a8dad375245ce953b68277b GIT binary patch literal 30704 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 K+~hh{B>oS?EdD_N literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/DEZIP.PAS b/SOURCE/UNUSED/DEZIP.PAS new file mode 100644 index 0000000..507419d --- /dev/null +++ b/SOURCE/UNUSED/DEZIP.PAS @@ -0,0 +1,1192 @@ +Program DeZip; + +{ DeZip v1.5 (C) Copyright 1989 by R. P. Byrne } +{ } +{ This is a "bare-bones" program to extract files from ZIP archives. } +{ By "bare-bones", I mean that there is no facility included to do anything } +{ but extraction (ie. no echo to console, no send to printer, etc.). } +{ If relative pathnames are stored in the Zip file, make sure all of the } +{ required directories exist on your system before attempting an } +{ extraction. } + +{$M 10240, 0, 0} { Stack, Min. Heap, Max. Heap} +{$F+} { Force far calls } + +Uses + Dos, + Crt, + MemAlloc, + StrProcs; + +Const + COPYRIGHT = 'DeZip (C) Copyright 1989 by R. P. Byrne'; + VERSION = 'Version 1.5 - Compiled on March 11, 1989'; + +{ Stuff needed generically by all uncompression methods } + +Const + MAXNAMES = 20; + +Var + InFileSpecs : Array[1..MAXNAMES] of String; { Input file specifications } + MaxSpecs : Word; { Total number of entries in InFileSpecs array } + OutPath : String; { Output path specification } + + TenPercent : LongInt; + +{ Define ZIP file header types } + +Const + LOCAL_FILE_HEADER_SIGNATURE = $04034B50; + +Type + Local_File_Header_Type = Record + { Signature : LongInt; } + Extract_Version_Reqd : Word; + Bit_Flag : Word; + Compress_Method : Word; + Last_Mod_Time : Word; + Last_Mod_Date : Word; + Crc32 : LongInt; + Compressed_Size : LongInt; + Uncompressed_Size : LongInt; + Filename_Length : Word; + Extra_Field_Length : Word; + end; + +Const + CENTRAL_FILE_HEADER_SIGNATURE = $02014B50; + +Type + Central_File_Header_Type = Record + { Signature : LongInt; } + MadeBy_Version : Word; + Extract_Version_Reqd : Word; + Bit_Flag : Word; + Compress_Method : Word; + Last_Mod_Time : Word; + Last_Mod_Date : Word; + Crc32 : LongInt; + Compressed_Size : LongInt; + Uncompressed_Size : LongInt; + Filename_Length : Word; + Extra_Field_Length : Word; + File_Comment_Length : Word; + Starting_Disk_Num : Word; + Internal_Attributes : Word; + External_Attributes : LongInt; + Local_Header_Offset : LongInt; + End; + +Const + END_OF_CENTRAL_DIR_SIGNATURE = $06054B50; + +Type + End_of_Central_Dir_Type = Record + { Signature : LongInt; } + Disk_Number : Word; + Central_Dir_Start_Disk : Word; + Entries_This_Disk : Word; + Total_Entries : Word; + Central_Dir_Size : LongInt; + Start_Disk_Offset : LongInt; + ZipFile_Comment_Length : Word; + end; + +Const + CRC_32_TAB : Array[0..255] of LongInt = ( +$00000000, $77073096, $ee0e612c, $990951ba, $076dc419, $706af48f, $e963a535, $9e6495a3, +$0edb8832, $79dcb8a4, $e0d5e91e, $97d2d988, $09b64c2b, $7eb17cbd, $e7b82d07, $90bf1d91, +$1db71064, $6ab020f2, $f3b97148, $84be41de, $1adad47d, $6ddde4eb, $f4d4b551, $83d385c7, +$136c9856, $646ba8c0, $fd62f97a, $8a65c9ec, $14015c4f, $63066cd9, $fa0f3d63, $8d080df5, +$3b6e20c8, $4c69105e, $d56041e4, $a2677172, $3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b, +$35b5a8fa, $42b2986c, $dbbbc9d6, $acbcf940, $32d86ce3, $45df5c75, $dcd60dcf, $abd13d59, +$26d930ac, $51de003a, $c8d75180, $bfd06116, $21b4f4b5, $56b3c423, $cfba9599, $b8bda50f, +$2802b89e, $5f058808, $c60cd9b2, $b10be924, $2f6f7c87, $58684c11, $c1611dab, $b6662d3d, +$76dc4190, $01db7106, $98d220bc, $efd5102a, $71b18589, $06b6b51f, $9fbfe4a5, $e8b8d433, +$7807c9a2, $0f00f934, $9609a88e, $e10e9818, $7f6a0dbb, $086d3d2d, $91646c97, $e6635c01, +$6b6b51f4, $1c6c6162, $856530d8, $f262004e, $6c0695ed, $1b01a57b, $8208f4c1, $f50fc457, +$65b0d9c6, $12b7e950, $8bbeb8ea, $fcb9887c, $62dd1ddf, $15da2d49, $8cd37cf3, $fbd44c65, +$4db26158, $3ab551ce, $a3bc0074, $d4bb30e2, $4adfa541, $3dd895d7, $a4d1c46d, $d3d6f4fb, +$4369e96a, $346ed9fc, $ad678846, $da60b8d0, $44042d73, $33031de5, $aa0a4c5f, $dd0d7cc9, +$5005713c, $270241aa, $be0b1010, $c90c2086, $5768b525, $206f85b3, $b966d409, $ce61e49f, +$5edef90e, $29d9c998, $b0d09822, $c7d7a8b4, $59b33d17, $2eb40d81, $b7bd5c3b, $c0ba6cad, +$edb88320, $9abfb3b6, $03b6e20c, $74b1d29a, $ead54739, $9dd277af, $04db2615, $73dc1683, +$e3630b12, $94643b84, $0d6d6a3e, $7a6a5aa8, $e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1, +$f00f9344, $8708a3d2, $1e01f268, $6906c2fe, $f762575d, $806567cb, $196c3671, $6e6b06e7, +$fed41b76, $89d32be0, $10da7a5a, $67dd4acc, $f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5, +$d6d6a3e8, $a1d1937e, $38d8c2c4, $4fdff252, $d1bb67f1, $a6bc5767, $3fb506dd, $48b2364b, +$d80d2bda, $af0a1b4c, $36034af6, $41047a60, $df60efc3, $a867df55, $316e8eef, $4669be79, +$cb61b38c, $bc66831a, $256fd2a0, $5268e236, $cc0c7795, $bb0b4703, $220216b9, $5505262f, +$c5ba3bbe, $b2bd0b28, $2bb45a92, $5cb36a04, $c2d7ffa7, $b5d0cf31, $2cd99e8b, $5bdeae1d, +$9b64c2b0, $ec63f226, $756aa39c, $026d930a, $9c0906a9, $eb0e363f, $72076785, $05005713, +$95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38, $92d28e9b, $e5d5be0d, $7cdcefb7, $0bdbdf21, +$86d3d2d4, $f1d4e242, $68ddb3f8, $1fda836e, $81be16cd, $f6b9265b, $6fb077e1, $18b74777, +$88085ae6, $ff0f6a70, $66063bca, $11010b5c, $8f659eff, $f862ae69, $616bffd3, $166ccf45, +$a00ae278, $d70dd2ee, $4e048354, $3903b3c2, $a7672661, $d06016f7, $4969474d, $3e6e77db, +$aed16a4a, $d9d65adc, $40df0b66, $37d83bf0, $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9, +$bdbdf21c, $cabac28a, $53b39330, $24b4a3a6, $bad03605, $cdd70693, $54de5729, $23d967bf, +$b3667a2e, $c4614ab8, $5d681b02, $2a6f2b94, $b40bbe37, $c30c8ea1, $5a05df1b, $2d02ef8d +); + +Const + BUFSIZE = 8192; { Size of buffers for I/O } + +Type + BufPtr = ^BufType; + BufType = Array[1..BUFSIZE] of Byte; + +Var + ZipName : String; { Name of Zip file to be processed } + ZipFile : File; { Zip file variable } + EndFile : Boolean; { End of file indicator for ZipFile } + ZipBuf : BufPtr; { Input buffer for ZipFile } + ZipPtr : Word; { Index for ZipFile input buffer } + ZipCount : Word; { Count of bytes in ZipFile input buffer } + + ExtFile : File; { Output file variable } + ExtBuf : BufPtr; { Output buffer for ExtFile } + ExtPtr : Word; { Index for ExtFile output buffer } + ExtCount : LongInt; { Count of characters written to output } + + LocalHdr : Local_File_Header_Type; { Storage for a local file hdr } + Hdr_FileName : String; + Hdr_ExtraField : String; + Hdr_Comment : String; + + Crc32Val : LongInt; { Running CRC (32 bit) value } + + Bytes_To_Go : LongInt; { Bytes left to process in compressed file } + + +{ Stuff needed for unSHRINKing } + +Const + MINCODESIZE = 9; + MAXCODESIZE = 13; + SPECIAL = 256; + FIRSTFREE = 257; + LZW_TABLE_SIZE = (1 SHL MAXCODESIZE) - 1; { 0..8191 } + LZW_STACK_SIZE = (1 SHL MAXCODESIZE) - 1; { 0..8191 } + +Type + + LZW_Table_Rec = Record + Prefix : Integer; + Suffix : Byte; + ChildCount : Word; { If ChildCount = 0 then leaf node } + end; + LZW_Table_Ptr = ^LZW_Table_Type; + LZW_Table_Type = Array[0..LZW_TABLE_SIZE] of LZW_Table_Rec; + + FreeListPtr = ^FreeListArray; + FreeListArray = Array[FIRSTFREE..LZW_TABLE_SIZE] of Word; + + StackPtr = ^StackType; + StackType = Array[0..LZW_STACK_SIZE] of Word; + +Var + LZW_Table : LZW_Table_Ptr; { Code table for LZW decoding } + FreeList : FreeListPtr; { List of free table entries } + NextFree : Word; { Index for free list array } + { FreeList^[NextFree] always contains the } + { index of the next available entry in } + { the LZW Prefix:Suffix table (LZW_Table^) } + LZW_Stack : StackPtr; { A stack used to build decoded strings } + StackIdx : Word; { Stack array index variable } + { StackIdx always points to the next } + { available entry in the stack } + SaveByte : Byte; { Our input code buffer - 1 byte long } + BitsLeft : Byte; { Unprocessed bits in the input code buffer } + FirstCh : Boolean; { Flag indicating first char being processed } + + +{ Stuff needed for unREDUCEing } + +Type + FollowerSet = Record + SetSize : Word; + FSet : Array[0..31] of Byte; + end; + FollowerPtr = ^FollowerArray; + FollowerArray = Array[0..255] of FollowerSet; + + StreamPtr = ^StreamArray; + StreamArray = Array[0..4095] of Byte; + +Var + Followers : FollowerPtr; + Stream : StreamPtr; { The output stream } + StreamIdx : Word; { Always points to next pos. to be filled } + State : Byte; + Len : Word; + V : Byte; + +{ --------------------------------------------------------------------------- } + +Procedure Abort(Msg : String); +Begin + Writeln; + Writeln(Msg); + Writeln('Returning to DOS'); + Writeln; + Halt; +end {Abort}; + +{ --------------------------------------------------------------------------- } + +Procedure Syntax; +Begin + Writeln('Usage: DeZip ZipFileName [OutPathSpec] [FileSpec [...]]'); + Writeln; + Writeln('Optional file specifications may contain DOS '); + Writeln('wildcard characters.'); + Writeln; + Writeln('If no filespecs are entered, *.* is assumed.'); + Writeln; + Halt; +End; + +{ --------------------------------------------------------------------------- } + +Function HexLInt(L : LongInt) : String; +Type + HexType = Array [0..15] of Char; +Const + HexChar : HexType = ('0','1','2','3','4','5','6','7', + '8','9','A','B','C','D','E','F'); +Begin + HexLInt := HexChar[(L AND $F0000000) SHR 28] + + HexChar[(L AND $0F000000) SHR 24] + + HexChar[(L AND $00F00000) SHR 20] + + HexChar[(L AND $000F0000) SHR 16] + + HexChar[(L AND $0000F000) SHR 12] + + HexChar[(L AND $00000F00) SHR 8] + + HexChar[(L AND $000000F0) SHR 4] + + HexChar[(L AND $0000000F) ] + + 'h'; +end {HexLInt}; + +{ --------------------------------------------------------------------------- } + +Function IO_Test : Boolean; +Var + ErrorCode : Word; + CodeStr : String; + Ok : Boolean; +Begin + Ok := TRUE; + ErrorCode := IOResult; + If ErrorCode <> 0 then begin + Ok := FALSE; + Case ErrorCode of + 2 : Writeln('File Not Found'); + 3 : Writeln('Path Not Found'); + 5 : Writeln('Access Denied'); + 101 : Writeln('Disk Full'); + else Writeln('I/O Error # ', ErrorCode); + end {Case}; + end {if}; + IO_Test := Ok; +end {IO_Test}; + +{ --------------------------------------------------------------------------- } + +Procedure Load_Parms; +Var + I : Word; + Name : String; + DosDTA : SearchRec; +Begin + I := ParamCount; + If I < 1 then + Syntax; + + ZipName := ParamStr(1); + For I := 1 to Length(ZipName) do + ZipName[I] := UpCase(ZipName[I]); + If Pos('.', ZipName) = 0 then + ZipName := ZipName + '.ZIP'; + + MaxSpecs := 0; + OutPath := ''; + I := 1; + While I < ParamCount do begin + Inc(I); + Name := ParamStr(I); + If Name[length(Name)] = '\' then + Delete(Name, length(Name), 1); + FindFirst(Name, DIRECTORY, DosDTA); { outpath spec? } + If DosError = 0 then begin + If (DosDTA.Attr AND DIRECTORY) <> 0 then begin { yup } + OutPath := Name; + If OutPath[Length(OutPath)] <> '\' then + OutPath := OutPath + '\'; + end {then} + else begin + If MaxSpecs < MAXNAMES then begin + Inc(MaxSpecs); + InFileSpecs[MaxSpecs] := Name; + end {if}; + end {if}; + end {then} + else begin + If MaxSpecs < MAXNAMES then begin + Inc(MaxSpecs); + InFileSpecs[MaxSpecs] := Name; + end {if}; + end {if} + end {while}; + + If MaxSpecs = 0 then begin + MaxSpecs := 1; + InFileSpecs[1] := '*.*'; + end {if}; + +end {Load_Parms}; + +{ --------------------------------------------------------------------------- } + +Procedure Initialize; +Var + Code : Integer; +Begin + Code := Malloc(ZipBuf, SizeOf(ZipBuf^)) OR + Malloc(ExtBuf, SizeOf(ExtBuf^)); + If Code <> 0 then + Abort('Not enough memory available to allocate I/O buffers!'); +end {Initialize}; + +{ --------------------------------------------------------------------------- } + +{ Converted to Turbo Pascal (tm) V4.0 March, 1988 by J.R.Louvau } +{ COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or } +{ code or tables extracted from it, as desired without restriction. } +{ } +{ First, the polynomial itself and its table of feedback terms. The } +{ polynomial is } +{ X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 } +{ } +{ Note that we take it "backwards" and put the highest-order term in } +{ the lowest-order bit. The X^32 term is "implied"; the LSB is the } +{ X^31 term, etc. The X^0 term (usually shown as "+1") results in } +{ the MSB being 1. } +{ } +{ Note that the usual hardware shift register implementation, which } +{ is what we're using (we're merely optimizing it by doing eight-bit } +{ chunks at a time) shifts bits into the lowest-order term. In our } +{ implementation, that means shifting towards the right. Why do we } +{ do it this way? Because the calculated CRC must be transmitted in } +{ order from highest-order term to lowest-order term. UARTs transmit } +{ characters in order from LSB to MSB. By storing the CRC this way, } +{ we hand it to the UART in the order low-byte to high-byte; the UART } +{ sends each low-bit to hight-bit; and the result is transmission bit } +{ by bit from highest- to lowest-order term without requiring any bit } +{ shuffling on our part. Reception works similarly. } +{ } +{ The feedback terms table consists of 256, 32-bit entries. Notes: } +{ } +{ The table can be generated at runtime if desired; code to do so } +{ is shown later. It might not be obvious, but the feedback } +{ terms simply represent the results of eight shift/xor opera- } +{ tions for all combinations of data and CRC register values. } +{ } +{ The values must be right-shifted by eight bits by the "updcrc" } +{ logic; the shift must be unsigned (bring in zeroes). On some } +{ hardware you could probably optimize the shift in assembler by } +{ using byte-swap instructions. } +{ polynomial $edb88320 } +{ } + +Function UpdC32(Octet: Byte; Crc: LongInt) : LongInt; +Var + L : LongInt; + W : Array[1..4] of Byte Absolute L; +Begin + + UpdC32 := CRC_32_TAB[Byte(Crc XOR LongInt(Octet))] XOR ((Crc SHR 8) AND $00FFFFFF); + +end {UpdC32}; + +{ --------------------------------------------------------------------------- } + +Procedure Read_Zip_Block; +Begin + BlockRead(ZipFile, ZipBuf^, BUFSIZE, ZipCount); + If ZipCount = 0 then + EndFile := TRUE; + ZipPtr := 1; +End {Read_Zip_Block}; + +{ --------------------------------------------------------------------------- } + +Procedure Write_Ext_Block; +Begin + If ExtPtr > 1 then begin + BlockWrite(ExtFile, ExtBuf^, Pred(ExtPtr)); + If NOT IO_Test then + Halt; + ExtPtr := 1; + end {if}; +End {Write_Ext_Block}; + +{ --------------------------------------------------------------------------- } + +Procedure Open_Zip; +Begin + Assign(ZipFile, ZipName); + FileMode := 64; { Read Only / Deny None } + {$I-} Reset(ZipFile, 1) {$I+}; + If NOT IO_Test then + Halt; + EndFile := FALSE; + Read_Zip_Block; +End {Open_Zip}; + +{ --------------------------------------------------------------------------- } + +Function Open_Ext : Boolean; +Begin + Assign(ExtFile, OutPath + Hdr_FileName); + FileMode := 66; { Read & Write / Deny None } + {$I-} Rewrite(ExtFile, 1) {$I+}; + If NOT IO_Test then + Open_Ext := FALSE + else begin + ExtPtr := 1; + Open_Ext := TRUE; + end {if}; +end {Open_Ext}; + +{ --------------------------------------------------------------------------- } + +Function Get_Zip : Integer; +Begin + If ZipPtr > ZipCount then + Read_Zip_Block; + + If EndFile then + Get_Zip := -1 + else begin + Get_Zip := ZipBuf^[ZipPtr]; + Inc(ZipPtr); + end {if}; +end {Get_Zip}; + +{ --------------------------------------------------------------------------- } + +Procedure Put_Ext(C : Byte); +Begin + Crc32Val := UpdC32(C, Crc32Val); + ExtBuf^[ExtPtr] := C; + Inc(ExtPtr); + Inc(ExtCount); + If ExtPtr > BUFSIZE then + Write_Ext_Block; +end {Put_Ext}; + +{ --------------------------------------------------------------------------- } + +Procedure Close_Zip; +Begin + {$I-} Close(Zipfile) {$I+}; + If IO_Test then ; +end {Close_Zip}; + +{ --------------------------------------------------------------------------- } + +Procedure Close_Ext; +Type + TimeDateRec = Record + Time : Word; + Date : Word; + end {record}; +Var + TimeDate : TimeDateRec; + TimeDateStamp : LongInt Absolute TimeDate; +Begin + Write_Ext_Block; + TimeDate.Time := LocalHdr.Last_Mod_Time; + TimeDate.Date := LocalHdr.Last_Mod_Date; + SetFTime(ExtFile, TimeDateStamp); + {$I-} Close(ExtFile) {$I+}; + If IO_Test then ; + GotoXY(1, WhereY); + Write(ExtCount); + GotoXY(1, WhereY); +end {Close_Ext}; + +{ --------------------------------------------------------------------------- } + +Procedure FSkip(Offset : LongInt); +Var + Rec : LongInt; +Begin + If (Offset + ZipPtr) <= ZipCount then + Inc(ZipPtr, Offset) + else begin + Rec := FilePos(ZipFile) + (Offset - (ZipCount - ZipPtr) - 1); + {$I-} Seek(ZipFile, Rec) {$I+}; + If NOT IO_Test then + Halt; + Read_Zip_Block; + end {if}; +end {FSkip}; + +{ --------------------------------------------------------------------------- } + +Procedure FRead(Var Buf; RecLen : Word); +Var + I : Word; + B : Array[1..MaxInt] of Byte Absolute Buf; +Begin + For I := 1 to RecLen do + B[I] := Get_Zip; +end {FRead}; + +{ --------------------------------------------------------------------------- } + +Function Read_Local_Hdr : Boolean; +Var + Sig : LongInt; +Begin + If EndFile then + Read_Local_Hdr := FALSE + else begin + FRead(Sig, SizeOf(Sig)); + If Sig = CENTRAL_FILE_HEADER_SIGNATURE then begin + Read_Local_Hdr := FALSE; + EndFile := TRUE; + end {then} + else begin + If Sig <> LOCAL_FILE_HEADER_SIGNATURE then + Abort('Missing or invalid local file header in ' + ZipName); + FRead(LocalHdr, SizeOf(LocalHdr)); + With LocalHdr do begin + If FileName_Length > 255 then + Abort('Filename of compressed file exceeds 255 characters!'); + FRead(Hdr_FileName[1], FileName_Length); + Hdr_FileName[0] := Chr(FileName_Length); + If Extra_Field_Length > 255 then + Abort('Extra field of compressed file exceeds 255 characters!'); + FRead(Hdr_ExtraField[1], Extra_Field_Length); + Hdr_ExtraField[0] := Chr(Extra_Field_Length); + end {with}; + Read_Local_Hdr := TRUE; + end {if}; + end {if}; +end {Read_Local_Hdr}; + +{ --------------------------------------------------------------------------- } + +Function Get_Compressed : Integer; +Var + PctDone : Integer; +Begin + If Bytes_To_Go = 0 then + Get_Compressed := -1 + else begin + Get_Compressed := Get_Zip; + If Bytes_To_Go mod TenPercent = 0 then begin + PctDone := 100 - Round( 100 * (Bytes_To_Go / LocalHdr.Compressed_Size)); + GotoXY(WhereX - 4, WhereY); + Write(PctDone:3, '%'); + end {if}; + Dec(Bytes_To_Go); + end {if}; +end {Get_Compressed}; + +{ --------------------------------------------------------------------------- } + +Function LZW_Init : Boolean; +Var + RC : Word; + I : Word; +Label + Exit; +Begin + { Initialize LZW Table } + RC := Malloc(LZW_Table, SizeOf(LZW_Table^)); + If RC <> 0 then begin + LZW_Init := FALSE; + Goto Exit; + end {if}; + For I := 0 to LZW_TABLE_SIZE do begin + With LZW_Table^[I] do begin + Prefix := -1; + If I < 256 then + Suffix := I + else + Suffix := 0; + ChildCount := 0; + end {with}; + end {for}; + + RC := Malloc(FreeList, SizeOf(FreeList^)); + If RC <> 0 then begin + LZW_Init := FALSE; + Goto Exit; + end {if}; + For I := FIRSTFREE to LZW_TABLE_SIZE do + FreeList^[I] := I; + NextFree := FIRSTFREE; + + { Initialize the LZW Character Stack } + RC := Malloc(LZW_Stack, SizeOf(LZW_Stack^)); + If RC <> 0 then begin + LZW_Init := FALSE; + Goto Exit; + end {if}; + StackIdx := 0; + LZW_Init := TRUE; + +Exit: +end {LZW_Init}; + +{ --------------------------------------------------------------------------- } + +Procedure LZW_Cleanup; +Var + Code : Word; +Begin + Code := Dalloc(LZW_Table); + Code := Dalloc(FreeList); + Code := Dalloc(LZW_Stack); +end {LZW_Cleanup}; + +{ --------------------------------------------------------------------------- } + +Procedure Clear_LZW_Table; +Var + I : Word; +Begin + StackIdx := 0; + + For I := FIRSTFREE to LZW_TABLE_SIZE do begin { Find all leaf nodes } + If LZW_Table^[I].ChildCount = 0 then begin + LZW_Stack^[StackIdx] := I; { and put each on stack } + Inc(StackIdx); + end {if}; + end {for}; + + NextFree := Succ(LZW_TABLE_SIZE); + + While StackIdx > 0 do begin { clear all leaf nodes } + Dec(StackIdx); + I := LZW_Stack^[StackIdx]; + With LZW_Table^[I] do begin + If LZW_Table^[I].Prefix <> -1 then + Dec(LZW_Table^[Prefix].ChildCount); + Prefix := -1; + Suffix := 0; + ChildCount := 0; + end {with}; + Dec(NextFree); { add cleared nodes to freelist } + FreeList^[NextFree] := I; + end {while}; + +End {Clear_LZW_Table}; + +{ --------------------------------------------------------------------------- } + +Procedure Add_To_LZW_Table(Prefix : Integer; Suffix : Byte); +Var + I : Word; +Begin + + If NextFree <= LZW_TABLE_SIZE then begin + I := FreeList^[NextFree]; + Inc(NextFree); + LZW_Table^[I].Prefix := Prefix; + LZW_Table^[I].Suffix := Suffix; + Inc(LZW_Table^[Prefix].ChildCount); + end {if}; + +End {Add_To_LZW_Table}; + +{ --------------------------------------------------------------------------- } + +Function Get_Code(CodeSize : Byte) : Integer; +Const + Mask : Array[1..8] of Byte = ($01, $03, $07, $0F, $1F, $3F, $7F, $FF); + TmpInt : Integer = 0; +Var + BitsNeeded : Byte; + HowMany : Byte; + HoldCode : Integer; +Label + Exit; +Begin + If FirstCh then begin { If first time through ... } + TmpInt := Get_Compressed; { ... then prime the code buffer } + If TmpInt = -1 then begin { If EOF on fill attempt ... } + Get_Code := -1; { ... then return EOF indicator ... } + Goto Exit; { ... and return to caller. } + end {if}; + SaveByte := TmpInt; + BitsLeft := 8; { there's now 8 bits in our buffer } + FirstCh := FALSE; + end {if}; + + BitsNeeded := CodeSize; + HoldCode := 0; + + While (BitsNeeded > 0) And (TmpInt <> -1) do begin + + If BitsNeeded >= BitsLeft + then HowMany := BitsLeft { HowMany <-- Min(BitsLeft, BitsNeeded) } + else HowMany := BitsNeeded; + + HoldCode := HoldCode OR ((SaveByte AND Mask[HowMany]) SHL (CodeSize - BitsNeeded)); + SaveByte := SaveByte SHR HowMany; + Dec(BitsNeeded, HowMany); + Dec(BitsLeft, HowMany); + + If BitsLeft <= 0 then begin { If no bits left in buffer ... } + TmpInt := Get_Compressed; { ... then attempt to get 8 more. } + If TmpInt = -1 then + Goto Exit; + SaveByte := TmpInt; + BitsLeft := 8; + end {if}; + + end {while}; + +Exit: + + If (BitsNeeded = 0) then { If we got what we came for ... } + Get_Code := HoldCode { ... then return it } + else + Get_Code := -1; { ... Otherwise, return EOF } + +end {Get_Code}; + +{ --------------------------------------------------------------------------- } + +Procedure UnShrink; +Var + Ch : Char; + CodeSize : Byte; { Current size (in bits) of codes coming in } + CurrCode : Integer; + SaveCode : Integer; + PrevCode : Integer; + BaseChar : Byte; +Label + Exit; +Begin + CodeSize := MINCODESIZE; { Start with the smallest code size } + + PrevCode := Get_Code(CodeSize); { Get first code from file } + If PrevCode = -1 then { If EOF already, then ... } + Goto Exit; { ... just exit without further ado } + BaseChar := PrevCode; + Put_Ext(BaseChar); { Unpack the first character } + + CurrCode := Get_Code(CodeSize); { Get next code to prime the while loop } + + While CurrCode <> -1 do begin { Repeat for all compressed bytes } + + If CurrCode = SPECIAL then begin { If we've got a "special" code ... } + + CurrCode := Get_Code(CodeSize); + Case CurrCode of + 1 : Begin { ... and if followed by a 1 ... } + Inc(CodeSize); { ... then increase code size } + end {1}; + 2 : Begin { ... and if followed by a 2 ... } + Clear_LZW_Table; { ... clear leaf nodes in the table } + end {2}; + else begin { ... if neither 1 or 2, discard } + Writeln; + Writeln('Encountered code 256 not followed by 1 or 2!'); + Writeln; + Write('Press a key to continue ...'); + Ch := ReadKey; + DelLine; + GotoXY(1, WhereY); + end {else}; + end {case}; + + end {then} + else begin { Not a "special" code } + + SaveCode := CurrCode; { Save this code someplace safe... } + + If CurrCode > LZW_TABLE_SIZE then + Abort('Invalid code encountered!'); + + If (CurrCode >= FIRSTFREE) and (LZW_Table^[CurrCode].Prefix = -1) then begin + If StackIdx > LZW_STACK_SIZE then begin + Write_Ext_Block; + Writeln; + Writeln('Stack Overflow (', StackIdx, ')!'); + Halt; + end {if}; + LZW_Stack^[StackIdx] := BaseChar; + Inc(StackIdx); + CurrCode := PrevCode; + end {if}; + + While CurrCode >= FIRSTFREE do begin + If StackIdx > LZW_STACK_SIZE then begin + Write_Ext_Block; + Writeln; + Writeln('Stack Overflow (', StackIdx, ')!'); + Halt; + end {if}; + LZW_Stack^[StackIdx] := LZW_Table^[CurrCode].Suffix; + Inc(StackIdx); + CurrCode := LZW_Table^[CurrCode].Prefix; + end {while}; + + BaseChar := LZW_Table^[CurrCode].Suffix; { Get last character ... } + Put_Ext(BaseChar); + + While (StackIdx > 0) do begin + Dec(StackIdx); + Put_Ext(LZW_Stack^[StackIdx]); + end {while}; { ... until there are none left } + + Add_to_LZW_Table(PrevCode, BaseChar); { Add new entry to table } + + PrevCode := SaveCode; + + end {if}; + + CurrCode := Get_Code(CodeSize); { Get next code from input stream } + + end {while}; +Exit: +end {UnShrink}; + +{ --------------------------------------------------------------------------- } + +Function Init_UnReduce : Boolean; +Var + Code : Word; +Label + Exit; +Begin + Code := Malloc(Followers, SizeOf(Followers^)); + If Code <> 0 then begin + Init_UnReduce := FALSE; + Goto Exit; + end {if}; + + Code := Malloc(Stream, SizeOf(Stream^)); + If Code <> 0 then begin + Init_UnReduce := FALSE; + Goto Exit; + end {if}; + + Init_UnReduce := TRUE; + +Exit: +end {Init_UnReduce}; + +{ --------------------------------------------------------------------------- } + +Procedure Cleanup_UnReduce; +Var + Code : Word; +Begin + Code := Dalloc(Followers); + Code := Dalloc(Stream); +end {Cleanup_UnReduce}; + +{ --------------------------------------------------------------------------- } + +Function D(X, Y : Byte) : Word; +Var + tmp : LongInt; +Begin + X := X SHR (8 - Pred(LocalHdr.Compress_Method)); + Tmp := X * 256; + D := Tmp + Y + 1; +end {D}; + +{ --------------------------------------------------------------------------- } + +Function F(X : Word) : Byte; +Const + TestVal : Array[1..4] of Byte = (127, 63, 31, 15); +Begin + If X = TestVal[Pred(LocalHdr.Compress_Method)] then + F := 2 + else + F := 3; +end {F}; + +{ --------------------------------------------------------------------------- } + +Function L(X : Byte) : Byte; +Const + Mask : Array[1..4] of Byte = ($7F, $3F, $1F, $0F); +Begin + L := X AND Mask[Pred(LocalHdr.Compress_Method)]; +end {L}; + +{ --------------------------------------------------------------------------- } + +Procedure StreamOut(C : Byte); +Begin + Put_Ext(C); + Stream^[StreamIdx] := C; + StreamIdx := Succ(StreamIdx) MOD 4096; +end {StreamOut}; + +{ --------------------------------------------------------------------------- } + +Procedure ScrnchInit; +Begin + State := 0; + For StreamIdx := 0 to 4095 do + Stream^[StreamIdx] := 0; + StreamIdx := 0; +end {ScrnchInit}; + +{ --------------------------------------------------------------------------- } + +Procedure UnScrnch(C : Byte); +Const + DLE = $90; +Var + S : Integer; + Count : Word; + OneByte : Byte; + Tmp1 : LongInt; +Begin + Case State of + 0 : begin + If C = DLE then + State := 1 + else + StreamOut(C); + end {0}; + 1 : begin + If C = 0 then begin + StreamOut(DLE); + State := 0; + end {then} + else begin + V := C; + Len := L(V); + State := F(Len); + end {if}; + end {1}; + 2 : begin + Inc(Len, C); + State := 3; + end {2}; + 3 : begin + Tmp1 := D(V, C); + S := StreamIdx - Tmp1; + If S < 0 then + S := S + 4096; + Count := Len + 3; + While Count > 0 do begin + OneByte := Stream^[S]; + StreamOut(OneByte); + S := Succ(S) MOD 4096; + Dec(Count); + end {while}; + State := 0; + end {3}; + end {case}; + +end {UnScrnch}; + +{ --------------------------------------------------------------------------- } + +Function MinBits(Val : Byte) : Byte; +Begin + Dec(Val); + Case Val of + 0..1 : MinBits := 1; + 2..3 : MinBits := 2; + 4..7 : MinBits := 3; + 8..15 : MinBits := 4; + 16..31 : MinBits := 5; + else MinBits := 6; + end {case}; +end {MinBits}; + +{ --------------------------------------------------------------------------- } + +Procedure UnReduce; +Var + LastChar : Byte; + N : Byte; + I, J : Word; + Code : Integer; + Ch : Char; +Begin + For I := 255 downto 0 do begin { Load follower sets } + N := Get_Code(6); { Get size of 1st set } + Followers^[I].SetSize := N; + If N > 0 then + For J := 0 to Pred(N) do + Followers^[I].FSet[J] := Get_Code(8); + end {for}; + + ScrnchInit; + + LastChar := 0; + Repeat + + If Followers^[LastChar].SetSize = 0 then begin + Code := Get_Code(8); + UnScrnch(Code); + LastChar := Code; + end {then} + else begin + Code := Get_Code(1); + If Code <> 0 then begin + Code := Get_Code(8); + UnScrnch(Code); + LastChar := Code; + end {then} + else begin + I := MinBits(Followers^[LastChar].SetSize); + Code := Get_Code(I); + UnScrnch(Followers^[LastChar].FSet[Code]); + LastChar := Followers^[LastChar].FSet[Code]; + end {if}; + end {if}; + Until (ExtCount = LocalHdr.Uncompressed_Size); + Code := Dalloc(Followers); +end {UnReduce}; + +{ --------------------------------------------------------------------------- } + +Procedure UnZip; +Var + C : Integer; +Begin + Crc32Val := $FFFFFFFF; + Bytes_To_Go := LocalHdr.Compressed_Size; + FirstCh := TRUE; + + ExtCount := 0; + + TenPercent := LocalHdr.Compressed_Size DIV 10; + + Case LocalHdr.Compress_Method of + 0 : Begin + While Bytes_to_go > 0 do + Put_Ext(Get_Compressed); + end {0 = Stored}; + 1 : Begin + If LZW_Init then + UnShrink + else begin + Writeln('Not enough memory available to unshrink!'); + Writeln('Skipping ', Hdr_FileName, ' ...'); + FSkip(LocalHdr.Compressed_Size); + Crc32Val := NOT LocalHdr.Crc32; + end {if}; + LZW_Cleanup; + end {1 = shrunk}; + 2..5 : Begin + If Init_UnReduce then + UnReduce + else begin + Writeln('Not enough memory available to unreduce!'); + Writeln('Skipping ', Hdr_FileName, ' ...'); + FSkip(LocalHdr.Compressed_Size); + Crc32Val := NOT LocalHdr.Crc32; + end {if}; + Cleanup_UnReduce; + end {2..5}; + else Begin + Writeln('Unknown compression method used on ', Hdr_FileName); + Writeln('Skipping ', Hdr_FileName, ' ...'); + FSkip(LocalHdr.Compressed_Size); + Crc32Val := NOT LocalHdr.Crc32; + end {else}; + end {case}; + + Crc32Val := NOT Crc32Val; + If Crc32Val <> LocalHdr.Crc32 then begin + Writeln; + Writeln('WARNING: File ', OutPath + Hdr_FileName, ' fails CRC check!'); + Writeln(' Stored CRC = ', HexLInt(LocalHdr.Crc32), + ' Calculated CRC = ', HexLInt(Crc32Val)); + end {if}; + +end {UnZip}; + +{ --------------------------------------------------------------------------- } + +Procedure Extract_File; +Var + YesNo : Char; + DosDTA : SearchRec; +Label + Exit; +Begin + FindFirst(OutPath + Hdr_FileName, ANYFILE, DosDTA); + If DosError = 0 then begin + Write('WARNING: ', OutPath + Hdr_FileName, ' already exists. Overwrite (Y/N)? '); + YesNo := ReadKey; + Writeln(YesNo); + If UpCase(YesNo) <> 'Y' then begin + FSkip(LocalHdr.Compressed_Size); + Goto Exit; + end {if}; + end {if}; + + If Open_Ext then begin + Write('Extracting: ', OutPath + Hdr_FileName, ' ... '); + UnZip; + GotoXY(WhereX - 4, WhereY); + ClrEol; + Writeln(' done'); + Close_Ext; + end {then} + else begin + Writeln('Could not open output file ', OutPath + Hdr_FileName, '! Skipping to next file ...'); + FSkip(LocalHdr.Compressed_Size); + end {If}; +Exit: +end {Extract_File}; + +{ --------------------------------------------------------------------------- } + +Procedure Extract_Zip; +Var + Match : Boolean; + I : Word; +Begin + Open_Zip; + While Read_Local_Hdr do begin + Match := FALSE; + I := 1; + Repeat + If SameFile(InFileSpecs[I], Hdr_FileName) then + Match := TRUE; + Inc(I); + Until Match or (I > MaxSpecs); + If Match then + Extract_File + else + FSkip(LocalHdr.Compressed_Size); + end {while}; + Close_Zip; + GotoXY(1, WhereY); + ClrEOL; +end; + +{ --------------------------------------------------------------------------- } + +Begin + Assign(Output, ''); + Rewrite(Output); + Writeln; + Writeln(COPYRIGHT); + Writeln(VERSION); + Writeln; + Load_Parms; { get command line parameters } + Initialize; { one-time initialization } + Extract_Zip; { de-arc the file } +end. diff --git a/SOURCE/UNUSED/DOOR.SYS b/SOURCE/UNUSED/DOOR.SYS new file mode 100644 index 0000000..bbdb6c0 --- /dev/null +++ b/SOURCE/UNUSED/DOOR.SYS @@ -0,0 +1,52 @@ +COM0: +0 +8 +6 +0 +Y +N +Y +N +Lee Palmer +Kellogg, ID +000 000-0000 +000 000-0000 +PASSWORD +255 +32 +10/02/09 +1965732 +32762 +GR +24 +Y +@,A +@ +01/01/70 +2 +Z +0 +0 +0 +32767 +02/04/60 +F:\RG\DATA\ +F:\RG\DATA\ +Renegade SysOp +Lee Palmer +00:00 +N +N +Y +3 +0 +10/02/09 +17:58 +15:56 +32767 +0 +0 +0 + +0 +0 diff --git a/SOURCE/UNUSED/DOOR32.SYS b/SOURCE/UNUSED/DOOR32.SYS new file mode 100644 index 0000000..f15fdb5 --- /dev/null +++ b/SOURCE/UNUSED/DOOR32.SYS @@ -0,0 +1,11 @@ +0 + +0 +Renegade BBS 09-17-07/Alpha +2 +John Smith +John Smith +255 +5998 +1 +6 diff --git a/SOURCE/UNUSED/DOOR32~1.TXT b/SOURCE/UNUSED/DOOR32~1.TXT new file mode 100644 index 0000000..4a20054 --- /dev/null +++ b/SOURCE/UNUSED/DOOR32~1.TXT @@ -0,0 +1,121 @@ +.--------------------------------------------------------------------------. + | DOOR32 Revision 1 Specifications Updated: Feb 23rd, 2001 | + `--------------------------------------------------------------------------' + + What is Door32? + --------------- + + Door32 is a standard text-based drop file designed to take advantage of + 32-bit operating systems. Supporting handle inheritance, it will allow + for doors to work under multiple platforms and over both serial and + socket (telnet) connections. + + Programming Door32 Doors + ------------------------ + There are several freeware door libraries which support Door32 although + most if not all of them are for Pascal at this time. These libraries are + able to compile doors for DOS, Windows, OS/2, and Linux. + + I personally suggest the D32 library which is freeware and comes with + source code. It can compile doors for DOS, Windows, OS/2 and Linux using + various Pascal compilers. There are other great door libraries as well, + so give them all a try! + + Testing Door32 Support in BBS Software + -------------------------------------- + Included in the Door32 specification archive is a Win32 executable by the + name of SAMPLE.EXE. This is a very simple Door32 compatible door compiled + with the Pascal library mentioned above. BBS authors may find this + program useful for testing their Door32 support. + + Notes about Door32 Programming + ------------------------------ + At this point, there seems to be two things which need to be kept + in mind when doing Door32 programming: + + 1. Under Linux or any operating system with case sensitive file names, + the Door32 drop file (DOOR32.SYS) will be created with all lower + cased lettering. IE: door32.sys + + 2. There appears to be a bug in the Win32 programming API (ie, a bug in + Windows) which prevents Door32 programs from running from a batch + file. This means that the doors have to be executed directly from + the software. Instead of running MYDOOR.BAT which eventually + executes MYDOOR.EXE, you must run MYDOOR.EXE directly. This problem + has said to have been fixed in Windows NT, but still exists under + the Windows 9x platforms. + + What does this mean to BBS authors? Not much. + + What does this mean to DOOR authors? Maybe some changes... + + Because Door32 doors must be executed directly, there is a good + chance that the current directory will NOT be the directory that + your door executable is stored. When porting an old DOS door, + the door might assume that the system is in the same directory + as the .EXE when loading data files. Because of this, it is + recommended that you have your Door switch to the directory where + the door .EXE is located, or read that directory and use it when + accessing door related files. In Pascal, this is a sample of + getting the directory where the door .EXE is found: + + Function ProgPath : String; + Var + Dir : DirStr; + Name : NameStr; + Ext : ExtStr; + Begin + FSplit (ParamStr(0), Dir, Name, Ext); + ProgPath := Dir + '\'; + End; + + The above example will return the path where your door is located. + Some door libraries might already switch to the directory of the + executable, so you may not have to worry about it. + + The DOOR32.SYS Drop file + ------------------------ + + Below is the final Revision 1 version of DOOR32.SYS. It is a straight + DOS-style text file in all lower cased letters under operating systems + with case sensitive file systems: + +[cut here]------------------------------------------------------------------- + +0 Line 1 : Comm type (0=local, 1=serial, 2=telnet) +0 Line 2 : Comm or socket handle +38400 Line 3 : Baud rate +Mystic 1.07 Line 4 : BBSID (software name and version) +1 Line 5 : User record position (1-based) +James Coyle Line 6 : User's real name +g00r00 Line 7 : User's handle/alias +255 Line 8 : User's security level +58 Line 9 : User's time left (in minutes) +1 Line 10: Emulation *See Below +1 Line 11: Current node number + +[cut here]------------------------------------------------------------------- + + * The following are values we've predefined for the emulation: + + 0 = Ascii + 1 = Ansi + 2 = Avatar + 3 = RIP + 4 = Max Graphics + + Avatar, RIP, and Max Graphics all have ANSI fallback support, so most door + libraries that don't support those emulations can just use ANSI if emulation + 2, 3, or 4 is encountered. + + Conclusion + ---------- + + Thats it for the Revision 1 specifications of DOOR32.SYS. You can find the + latest information at the official Door32 web page: + + http://www.mysticbbs.com/door32 + + You can e-mail mysticbbs@geocities.com for any questions or suggestions + relating to Door32 or post a message in the FidoNet DOORGAMES echo + diff --git a/SOURCE/UNUSED/DOORS.TPU b/SOURCE/UNUSED/DOORS.TPU new file mode 100644 index 0000000000000000000000000000000000000000..3837f4315b7625317b44adcf2b0378104f5447cf GIT binary patch literal 29264 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/DOORSY~1.DOC b/SOURCE/UNUSED/DOORSY~1.DOC new file mode 100644 index 0000000000000000000000000000000000000000..34a8f3a468a8120fb4ec846d58da50e2f6d37144 GIT binary patch literal 3551 zcmb_f+iu%95Z&hh{f9vxcGZOvTXGU7#^%AdxW@Vh+eJ5kUs#E@iAbU$QcnH%ouQ;i zvYoUGlt=@+8sih$&sZ$<0gam=W4K%GSp4C_IcqwRK8HyX ze&aFPI|O}ye`1L*tR7#pB+z8xe99p2-6OiRdvDn{WUrv@>4XK)nJpkD_P8`r{0gk+ zO@{DvvK1jLyqNO{dP402Mt(d!Oe28F!*so_EGUzDdKYpQi%6r7OS#zu6vy8H$u=B1 zJP1-szXP(%f&fXj0~Uvf`u`y3!h41RMlQ}{M6vv$@cA)8mJ=58G;bsRBGg{sUN$Vh zU!gf!(&i%Cz+)`K)XsIT!F8R><{eJVAiK{p}N&g9Cg6orX;wRn4%u>Jr6R=>zmsGiDqQElp1SpDMGGb8l{%?M$Ngd z-Icn9EJsXfK#JVB&a?fSH@8Owvi)V`E12_;iHO3q{5)KMhcN?dja{ac$#M2NRizv}Z@(g6kdN8kgm-;t|*={R51!HR6OBl=_%qtrvgNKQXF0-d* z|DkF3Q`h1Y&~2OpoKYQ*c(l>m)a-mynnKF5L z^ze%FC<6W$dF5d#XOj9}Jaavr#ZpU82AInKZ0OqXWW&IQAx74QzV@zCkfWLeFl~_* z`yi=$)ETCE1{*=jXz4=0%!QJFElrISW)Ihaqrh`Fa_d;sfZ zi{+L{BBl$3`g9I)(9Z!)ddrCPsQ^4?mp&I9$HLn(o*fY8BQabYl-!}qB*s*gguH=A(t9S5Gvgdyen1xH#IKsx zyyLqvK;Nx}W|7ZOD~6phx=-&sq-%q~U+2=f!P&+Ve+?P~^_?i=O!e3J2q-ZLw$c2YFtIA^`jpTEQ>2<5&7Gb~{ zA=7ybat+I^Q07dkSkS{;l~ixG8YP-Xc!n{F$S>m^AH^v@R4frDA^1l8Oy1Uo`)rS| z**8>-(@}VSa=IFcHdv)l`n3Q{RY_PgyfsK4FSu`v0@-aGU3E(0Pcqv%&_yCW1`zy> zQQ$Ri8}5DC>MUM<1iXb<;I)Aqghk>#XSYwvxjA0xUmg;XUl;}6NwudnWNvmnDN!4z jJ088oE8nV&=iXJbV`|dijk!{I15$VeTE9=T!29C|xWirH literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/DORINFO1.DEF b/SOURCE/UNUSED/DORINFO1.DEF new file mode 100644 index 0000000..1d20586 --- /dev/null +++ b/SOURCE/UNUSED/DORINFO1.DEF @@ -0,0 +1,13 @@ +The Renegade BBS +Renegade +SysOp +COM0 +0 BAUD,N,8,1 +0 +LEE +PALMER +Kellogg, ID +1 +255 +32762 +0 diff --git a/SOURCE/UNUSED/DORINF~1.TXT b/SOURCE/UNUSED/DORINF~1.TXT new file mode 100644 index 0000000..fd5d47c --- /dev/null +++ b/SOURCE/UNUSED/DORINF~1.TXT @@ -0,0 +1,29 @@ +Lines are ended with carriage return and linefeed combination. The fields are: +Node name +The name of the system. +Sysop f.name +The sysop's name up to the first space. +Sysop l.name +The sysop's name following the first space. +Com port +The serial port the modem is connected to, or 0 if logged in on console. +Baud rate +The current port (DTE) rate. +Networked +The number "0" +User's first name +The current user's name, up to the first space. +User's last name +The current user's name, following the first space. +City +Where the user lives, or a blank line if unknown. +Terminal type +The number "0" if TTY, or "1" if ANSI. +Security level +The number 5 for problem users, 30 for regular users, 80 for Aides, and 100 for Sysops. +Minutes remaining +The number of minutes left in the current user's account, limited to 546 to keep from overflowing other software. +FOSSIL +The number "-1" if using an external serial driver or "0" if using internal serial routines. + +-------------------------------------------------------------------------------- diff --git a/SOURCE/UNUSED/DRAG_010.PAS b/SOURCE/UNUSED/DRAG_010.PAS new file mode 100644 index 0000000..6f81ba6 --- /dev/null +++ b/SOURCE/UNUSED/DRAG_010.PAS @@ -0,0 +1,1333 @@ +{***************************************************************************} +{* Dragon Bulletin Board System *} +{* Copyright (c) 1998 By Dragon Software *} +{* All rights reserved. *} +{* *} +{* ----------------------------------- *} +{* Dragon Version .010 Data Structures *} +{* ----------------------------------- *} +{* *} +{***************************************************************************} + +CONST + {**************************************************************************} + {* The following values are used by the system for user fields *} + {* "ask" values will be asked of the user the next time they logon if *} + {* the question is part of the new user logon *} + {* "none" values are normally for optional fields where the user simply *} + {* pressed *} + {**************************************************************************} + User_String_Ask = ' '; {Ask for user string fields} + User_String_None = ''; {None for user string fields} + + User_Date_Ask = $fe21; {Ask for user date fields - 1/1/2027} + User_Date_None = $0021; {None for user date fields - 1/1/0} + + User_Word_Ask = 65535; {Ask for user word fields} + User_Word_None = 65534; {None for user word fields} + + User_Char_Ask = '~'; {Ask for user character fields} + User_Char_None = ' '; {None for user character fields} + + User_Phone_Ask = ' '; {Ask for user phone fields} + User_Phone_None = ''; {None for user phone fields} + + +TYPE + DefaultYesNoType = ( {Default/yes/no type} + dyn_default, {Default} + dyn_yes, {Yes} + dyn_no {No} + ); {1 byte} + + ArFlagType = '@'..'Z'; {AR flags} + + ArFlagset = SET OF ArFlagType; {Set of AR flags} + + FlagRec = ( {User special flags} + AutoPrivDel, {A = Force user to delete private mail} + NoPostCall, {B = No post call ratio} + ForceULScan, {C = Force this user to automatically scan when uploading} + Ranon, {D = Restrict from posting anonymous} + RbbsList, {E = Restrict from adding to other BBS list} + Rchat, {F = Restrict from chatting} + NoDLlimit, {G = No download ratio limit} + RpubMsg, {H = Restrict from posting public mail} + RprivMsg, {I = Restrict from sending private mail} + Rvoting, {J = Restrict from voting} + OneCall, {K = One call per day allowed} + PubNotVal, {L = Public posts are not validated} + ProtDel, {M = Protect from deletion} + NoFilePts, {N = No file point checks} + RfileVal, {O = Credit from upload on validation} + Pause, {P = [PAUSE] active} + Ansi, {Q = ANSI graphics active} + Color, {R = Color active if ANSI present} + OneKey, {S = Onekey input used instead of line input} + Alert, {T = Alert active from user's next call} + FlagRecUnused, {U = Unused} + MboxClosed, {V = Mail box closed to all but SysOp's} + Tabs, {W = VT100 tabs are used to optimize display} + ClsChar {X = Clear screen characters used} + ); {3 bytes used for 24 flags in set} + + FlagSet = SET OF FlagRec; {Set of special flags} + + UlRecFlagType = ( {File section flags} + IsCdRom, {Section is on a CD-ROM (read only device)} + uuUlRecFlag1, {Reserved} + uuUlRecFlag2, {Reserved} + uuUlRecFlag3, {Reserved} + uuUlRecFlag4, {Reserved} + uuUlRecFlag5, {Reserved} + uuUlRecFlag6, {Reserved} + uuUlRecFlag7 {Reserved} + ); {1 byte} + + UlRecFlagSet = {Set of file section flags} + SET OF UlRecFlagType; + + ConfigFlagRec = ( {User configuration flags} + UseCustomMenus, {A = Allow custom ANSI menus} + ClsMsgRead, {B = Clear screen between reading messages} + DoNotDisturbUser, {C = Do not disturb user (multi-user only)} + LogonScanAllMsgSections, {D = Scan all msg sections at logon for mail} + QWKNewBulletins, {E = Put new bulletins in QWK packet} + QWKNewFiles, {F = Put new files list in QWK packet} + uuCFFlag18, {G = Reserved} + uuCFFlag17, {H = Reserved} + uuCFFlag16, {I = Reserved} + uuCFFlag15, {J = Reserved} + uuCFFlag14, {K = Reserved} + uuCFFlag13, {L = Reserved} + uuCFFlag12, {M = Reserved} + uuCFFlag11, {N = Reserved} + uuCFFlag10, {O = Reserved} + uuCFFlag9, {P = Reserved} + uuCFFlag8, {Q = Reserved} + uuCFFlag7, {R = Reserved} + uuCFFlag6, {S = Reserved} + uuCFFlag5, {T = Reserved} + uuCFFlag4, {U = Reserved} + uuCFFlag3, {V = Reserved} + uuCFFlag2, {W = Reserved} + uuCFFlag1 {X = Reserved} + ); {3 bytes used for 24 flags in set} + + ConfigFlagSet = {Set of configuration flags} + SET OF ConfigFlagRec; + + {**********************************************************************} + {* ColorRec = Array of B&W / Color Color Bytes *} + {**********************************************************************} + ColorRec = ARRAY[FALSE..TRUE, {False = B&W, True = Color} + 0..9] {0..9 = Color number} + OF BYTE; + + SmalRec = RECORD {User name index - NAMES.LST} + Name : STRING[36]; {User name} + + Number : INTEGER; {User number} + END; + + UserRec = RECORD {User log - USER.LST} + Uname, {User name} + Rname : STRING[36]; {Real name} + + ADDR, {Address} + ComType, {Computer type} + CityState, {City/State} + Snote : STRING[30]; {SysOp note} + + LastDate, {Last date on - Semi-MS-DOS 1900 based format} + LastTime : WORD; {Last time on - MS-DOS format} + + PW : STRING[16]; {Password} + + Phone : STRING[12]; {Phone number 1} + + Zcode : STRING[10]; {Zip code} + + Phone2 : STRING[12]; {Phone number 2} + + ExtraStr1, {Extra string 1} + ExtraStr2, {Extra string 2} + ExtraStr3 : STRING[40]; {Extra string 3} + + ExtraDate1, {Extra date 1 - Semi-MS-DOS 1900 based format} + ExtraDate2 : WORD; {Extra date 2 - Semi-MS-DOS 1900 based format} + + ExtraWord1, {Extra word 1} + ExtraWord2, {Extra word 2} + ExtraWord3, {Extra word 3} + ExtraWord4 : WORD; {Extra word 4} + + ExtraChar1, {Extra character 1} + ExtraChar2, {Extra character 2} + ExtraChar3, {Extra character 3} + ExtraChar4 : CHAR; {Extra character 4} + + ExtraPhone : STRING[12]; {Extra phone} + + uureserved {Reserved} + : ARRAY[1..3] OF BYTE; + + {**********************************************************************} + {* Vote = An array of Voting Answers, One for each question *} + {**********************************************************************} + Vote : ARRAY[1..20] OF BYTE; {Voting} + + {**********************************************************************} + {* Call spread for last 15 calls - Number of days between each call: *} + {* 0 = Called the same day *} + {* 1..253 = X number of days between *} + {* 254 = 254 or more days between *} + {* 255 = Element not used yet *} + {**********************************************************************} + CallSpr {Call spread} + : ARRAY[1..15] OF BYTE; + + Ttimeon, {Total time on system in minutes} + UlK, {UL K-Bytes} + Dlk : REAL; {DL K-Bytes} + + {**********************************************************************} + {* UserNum = The User number *} + {* 0 -----------------------------> Deleted *} + {* Same as Record Number ----------> Normal *} + {* Different from Record Number ---> Locked Out *} + {**********************************************************************} + UserNum : INTEGER; {User number} + + PrivPost, {Private posts} + PubPost, {Public posts} + FeedBack, {Feedback sent to SysOp} + NumCalls, {Total number of calls to system} + NumUL, {Number of uploads} + NumDL : WORD; {Number of downloads} + + {**********************************************************************} + {* Fmail = Status of Mail Forwarding *} + {* 0 --------> Forwarding inactive *} + {* Other ----> User Number to forward mail to *} + {**********************************************************************} + Fmail : INTEGER; {Forward mail to which user number} + + Hbaud, {Highest baud rate user supports} + TimeToday, {Minutes on system date of last call} + Credit, {Credit for mail in cents} + Debit, {Debit for mail in cents} + Points, {File points} + TimeBank, {Minutes in time bank} + Bday, {Birthdate of user - Semi-MS-DOS format} + LastChange : WORD; {Reserved} + + StrtMenu, {Reserved} + SL, {Security level - SL} + DSL, {Download security level - DSL} + Hlvl, {Help level} + Colms, {Number of screen columns} + Lines, {Number of screen lines} + Callstoday, {Number of calls to system today} + Illegal : BYTE; {Illegal logon attempts} + + Gender : CHAR; {User gender M/F/' '=not specified} + + uulMsgBase, {Reserved} + uuLdlBase, {Reserved} + Cls : BYTE; {Reserved} + + FullEdit : defaultyesnotype; {Full screen editor status} + + Ar : ArFlagset; {AR flag set} + + Flags : FlagSet; {Special flag set} + + FirstOn, {Date first on - Semi-MS-DOS format} + Expires : WORD; {Date expires - Semi-MS-DOS format} + + UserRecUnused : {Reserved} + ARRAY[1..29] OF BYTE; + + Colors : ColorRec; {User colors} + + TBdeposit, {Time deposited in bank today} + TBwithdraw : BYTE; {Time withdraw from bank today} + + AdjTime : INTEGER; {Adjusted time date of last call} + + ConfigFlags : ConfigFlagSet; {Configuration Flags} + + lMbase, {Last message section} + lFbase : WORD; {Last file section} + + LastQWKCRC : LongInt; {CRC of last QWK .REP packet uploaded} + + Unused : Byte; {Reserved} + END; + + SmallMessageRec = RECORD {Short messages - SHORTMSG.DAT} + Msg : STRING[160]; {Message text} + + Destin : INTEGER; {User number of who message is to} + END; + + Vdatar = RECORD {Voting questions - VOTING.DAT} + Question : STRING[74]; {Question} + + NumA : WORD; {Number of answers in below array} + + Answ : ARRAY[0..9] OF RECORD {Array of answer data} + Ans : STRING[40]; {Answer} + + NumRes : WORD; {Number of users who choose this response} + END; + END; + + + UlRec = RECORD {File section - FBOARDS.DAT} + Name : STRING[39]; {Section name 26 Real Len, Rest Colors} + + Filename : STRING[8]; {Listing filename (does not include ".DIR")} + {If UL and DL paths are different,} + {filename for upload section is "FILES"} + {If first character is "@" then *.DIR file} + {is found in main data files directory} + + DlPathname, {Download pathname} + UlPathName : STRING[30]; {Upload pathname} + + Password : STRING[15]; {Password required} + + Flags : UlRecFlagSet; {File section flags} + + DSL, {DSL required} + SeeNames : BYTE; {DSL required to see uploader names} + + ArLvl : ArFlagType; {AR flag required} + + NoRatioGroupNum : BYTE; {bit 0 : Ratio disabled} + {bits 1-7 : Group number } + END; + + Filerec = ( {File flags} + NotValidated, {File is not validated} + OwnerRestricted, {Uploader did not receive credit on upload} + LocalUpload, {File existed locally} { Added } + uuF5, {Reserved} + uuF4, {Reserved} + uuF3, {Reserved} + uuF2, {Reserved} + uuF1 {Reserved} + ); {1 byte used for 8 flags in set} + + FlagRecSet = SET OF Filerec; {Set of file flags} + + UlfRec = RECORD {File listing - *.DIR} + Filename : STRING[12]; {File name} + + Description : STRING[78]; {Description} + + Nacc : WORD; {Number of times file downloaded} + + Unused : BYTE; {Reserved} + + Blocks : WORD; {Number of 128 byte blocks in file} + + Owner : STRING[36]; {Uploader of file} + + Date : STRING[8]; {Date file uploaded} + + DateN : WORD; {Date uploaded in days since Jan 1, 1985} + + Flag : FlagRecSet; {File status} + + Points : BYTE; {File points} + END; + + Range = ARRAY[0..255] OF WORD; {Range of values for all security levels} + + +CONST + numshellfiles = 13; {Number of defined internal shell files} + maxshelldesclength = 29; {Maximum shell file description length} + + + shellfiledesc : {Array of shell file descriptions} + ARRAY[1..numshellfiles] OF + STRING[maxshelldesclength] = ( + 'Front end mailer', {mailer.bat / binkley.bat} + 'External editor', {extedit.bat} + 'External SysOp function key', {extern#.bat} + 'Archive file testing', {filetest.bat} + 'Logon', {logon.bat} + 'New logon', {newlogon.bat} + 'Post download', {postdl.bat} + 'Post upload', {postul.bat} + 'Wait screen special function', {special.bat} + 'TAGMail external reader', {tagmail.bat} + 'Wait screen terminal function', {term.bat} + 'Welcome', {welcome.bat} + 'Logoff' {logoff.bat} + ); + + +TYPE + shellfileflagtype = ( {Shell file flags} + shellshowcall, {Display shell message on screen} + shelllogcall {Log shell message} + ); + + shellfileflagset = {Shell file flag set} + SET OF shellfileflagtype; + + shellfilerec = RECORD + UseSwap : defaultyesnotype; {Swap shell setting} + + Flags : shellfileflagset; {Shell file flags} + END; + + shellfilelist = {Array of shell files} + ARRAY[1..numshellfiles] OF + shellfilerec; + + +CONST + numnewuserquests = 29; {Number of current new user questions} + + maxnewuserdesclength = 15; {Maximum new user description length} + + newuserquestdesc : {Array of new user question descriptions} + ARRAY[0..numnewuserquests] OF + STRING[maxnewuserdesclength] = ( + 'Inactive', + 'Real Name', + 'Address', + 'City State', + 'Zip Code', + 'Phone Number 1', + 'Phone Number 2', + 'Computer Type', + 'Gender', + 'Birthday', + 'Maximum Baud', + 'Extra String 1', + 'Extra String 2', + 'Extra String 3', + 'Extra Date 1', + 'Extra Date 2', + 'Extra Number 1', + 'Extra Number 2', + 'Extra Number 3', + 'Extra Number 4', + 'Extra Char 1', + 'Extra Char 2', + 'Extra Char 3', + 'Extra Char 4', + 'Extra Phone', + 'Columns/Lines*', + 'Pause*', + 'ANSI/Color*', + 'Tabs*', + 'Password*' + ); + + +TYPE + newuserquestrec = RECORD + itemnum : BYTE; {Item number to ask or 0=inactive} + + required : BOOLEAN; {Required/optional} + END; + + newuserquestlist = {Array of new user questions} + ARRAY[1..numnewuserquests] OF + newuserquestrec; + + {*************************************************************************} + {* Provide for full 4D awareness (And point support) *} + {*************************************************************************} + AddressType = RECORD {Fidonet Style Address (24 Bytes)} + Zone, {Zone, 1 = N. America} + Net, {Net, 120 = SE Michigan} + Node, {Node, 116 = CRIMP BBS} + Point : WORD; {Point, 99% of the time = 0} + + Domain : STRING[15]; {As in FIDONET.ORG} + END; + + SystatRec = RECORD {System status - STATUS.DAT} + AltPath, {Alternate file path} + DictPath : STRING[40]; {Dictionary path} + + DefReadMsgMenu : BYTE; {Wait screen read message menu} + + dynamicmsg, {Dynamic message numbering active} + dynamicfile, {Dynamic file numbering active} + waitscreendisable, {Wait screen activity disable} + requiredvoting : BOOLEAN; {Require voting when user logs on} + + automsglines, {Auto message number of lines} + uunewuserexpdays, {Reserved} + addwordsl : BYTE; {Add word to dictionary SL} + + expvalkey : CHAR; {User expired validation key (#13=None)} + + expwarning, {Number of days to give warning before expires} + modifymailflags, {SL when allowed to modify mail flags} + netmailfilerequest, {SL for net mail file requests} + netmailfileattach : BYTE; {SL for net mail file attach} + + ModemDebug, {Modem debug information written to log} + UseXMS, {Use XMS memory for swap shell} + ShowFilesOpen, {Show Files Open on Top Screen} + LocalSysopWindow, {SysOp window when on locally} + AllowSuperFast, {Allow SHIFT password override} + WaitSend, {FOSSIL buffer inactive} + OverlayEMS, {Attempt EMS of overlays} + EMSOverXMS, {Use EMS over XMS memory for swap} + DirectScreen, {Direct screen writes} + UseEMS, {Use EMS memory for swap shell} + useswap, {Use swap shell} + UseFossil, {Use FOSSIL driver} + SnowCheck : BOOLEAN; {Snow checking active} + + BrowseDSL : BYTE; {DSL to have U/D commands on File Browse Menu} + + BbsID : String[8]; {!2.6f - ID used for Qwk Packets} + + TempDlPath : STRING[40]; {Temp File Download Path} + + MinKpost, {Minimum K-Bytes to post} + MinKul : WORD; {Minimum K-Bytes to upload} + + AutoChatBufOpen : BOOLEAN; {Auto chat buffer open} + + nettype : STRING[20]; {Multi-user network type} + + uusystatrec2 : {Reserved} + ARRAY[1..15] OF BYTE; + + LogonPassword, {SL when SysOp PW #1 needed to logon} + ReadTextMsg : BYTE; {SL when allowed to use /READ command} + + AlertChatOnly, {Alert active only when chat on} + genericinfo, {Generic mode active} + LogonPhone : BOOLEAN; {Logon requires phone number} + + DefMsgGroup : STRING[20]; {Default msg section group mask} + DefFileGroup : STRING[20]; {Default file section group mask} + + MaxQWKMsgsSection:Word; {Maximum QWK messages allowed per section} + MaxQWKMsgsTotal :Word; {Maximum QWK messages allowed total} + + uusystatrec3 : + ARRAY[1..9] OF BYTE; {Reserved} + + LastCaller : STRING[42]; {Name and number of last caller} + + MenuFastKeys : STRING[20]; {Menu fast keys (e.g. "/")} + + BoardPW : STRING[16]; {New user password (Null=None)} + + BoardPhone : STRING[12]; {Board phone number} + + SysopColor, {Chat SysOp color} + UserColor : BYTE; {Chat user color} + + PostCallFlag : ArFlagType; {Post call ratio AR flag} + + NoPostCallChk, {SL when post call ratio ignored} + ReinitTime, {Minutes to re-init modem when no calls} + StartMenu : BYTE; {Unused} + + UseAutoMsg, {Display auto-message during logon} + LogonOffHook : BOOLEAN; {Take phone off-hook on local logon} + + NoPointChk : BYTE; {DSL when file points ignored} + + LastDate : STRING[8]; {Date last user logged on} + + Address : AddressType; {Zone/Net/Node/Point/Domain} + + UserOn11x : Boolean; {Use USERON.BBS version 1.1x} + + shellfile : shellfilelist; {Shell file information} + + uushellfile : {Reserved for shell files} + ARRAY[1..10] OF BYTE; + + newuserquest : {New user question information} + newuserquestlist; + + uunewuserquest : {Reserved} + ARRAY[1..270] OF BYTE; + + ActiveModemRecNum : BYTE; {Active Modem Record Number} + + MultiUserPath : STRING[40]; {Multi-user path} + + defusereditlist : BYTE; {Default user editor list mode} + {0=short, 1=normal, 2=extended, 3=info} + + uusystatrec5 : {Reserved} + ARRAY[1..10] OF BYTE; + + GfilesPath : STRING[40]; {Main data files path} + + StoreBadLogon : BOOLEAN; {Store bad logon info in SysOp log} + + MaxBdNum, {Maximum number of batch DL files} + MaxBuNum : BYTE; {Maximum number of batch UL files} + + BoardName : STRING[48]; {Board name} + + SysopMenuSL : BYTE; {SL required for SysOp Control-Q menu} + + SysopMenuAR : ArFlagType; {AR flag required from Control-Q menu} + + SysopName : STRING[36]; {SysOp name} + + SwapPath : STRING[40]; {Swap shell path} + + ChatPW : STRING[16]; {Chat password} + + LastDragonVersion : STRING[20]; {Last version of Dragon to run} { Changed } + + nodelistpath : STRING[40]; {Nodelist directory} + + BoardCityState : String[32]; {Board City, State for QWK Pkt} + + QWKPath : String[40]; {QWK Path} + RIPPath : String[40]; {RIP Path} + + uusystatrec6 : {Reserved} + ARRAY[1..2193] OF BYTE; + + SysopPW : {Array of SysOp passwords} + ARRAY[1..3] OF STRING[16]; + + uusystatrec7 : {Reserved} + ARRAY[1..120] OF BYTE; + + CallerNum, {Total number of calls to system} + UlKtoday, {K-Bytes uploaded today} + DlkToday, {K-Bytes downloaded today} + uur1, {Reserved} + uur2, {Reserved} + uur3 : REAL; {Reserved} + + Users, {Number of active users} + ActiveToday, {Minutes active today} + Callstoday, {Calls today} + MsgPostToday, {Public messages posted today} + EmailToday, {Private messages posted today} + FbackToday, {Feedback sent to SysOp today} + UlToday, {Number of uploads today} + uuw1, {Reserved} + uuw2, {Reserved} + uuw3, {Reserved} + MaxUsers, {Maximum users allowed to be active} + ErrorsToday, {Number of errors today} + NusersToday, {Number of new users today} + DlToday : WORD; {Number of downloads today} + + NewUserMsgTo, {User number new user message sent to} + uui1, {Reserved} + SysopMailTo, {User number mail to "SYSOP" is sent to} + GuestUser, {Guest user number (0=None)} + FailedLogonMsgTo : INTEGER; {Failed logon message sent to} + + uuw5, {Reserved} + UsageLogDays, {Number of days to keep USAGE.LOG} + WaitMailUser : INTEGER; {Mail waiting on wait screen (0=none)} + + UEditJumpSL : BYTE; {SL required for SysOp Control-U menu} + UEditJumpAR : ArFlagType; {AR flag required from Control-U menu} + + NoviceDisplay : BYTE; {Number of calls to display novice msg} + + NodeNumber : BYTE; {Multi-user node number} + + UEditJumpPassword, {Use System pswd for Quick User Edit} + ScanOnUploads : BOOLEAN; {System permits forced scan on uploads} + + MaxTimeInBank : WORD; {Maximum minutes in time bank} + + ShowGifRes, {Show GIF resolution} + CheckUploadSpace, {Show upload drive space} + SystemSecur : BOOLEAN; {Full keyboard security active} + + MultiUser : BOOLEAN; {Board in multi-user mode} + + TBmaxDeposit, {Maximum daily time bank deposit} + TBmaxWithdraw, {Maximum daily time bank withdraw} + SysopLvl, {SL for SysOp} + CoSysopLvl, {SL for CoSysOp} + uub1, {Reserved} + AddBbsLvl, {SL for adding boards to bbs listing} + EmailLvl, {SL for sending normal private mail} + uub2, {Reserved} + uub3, {Reserved} + SeeUnvalLvl, {DSL for seeing unvalidated files} + DlCoSysopLvl, {DSL for Download CoSysOp} + NoRatioChk, {DSL for no ratio} + ReadAnon, {SL to know see anonymous real name } + ReplyAnon, {SL to reply to anonymous private mail } + PublicAnonAny, {SL to post anonymous on any public base} + PrivateAnonAny, {SL to send private anonymous mail } + MaxPublicCall, {Maximum public posts per call} + MaxPrivCall, {Maximum private messages per call} + MaxFbackCall, {Maximum feedback to SysOp per call} + uub4, {Reserved} + SeePasswords, {SL to see user passwords remotely} + uub5, {Reserved} + uub6, {Reserved} + ComPort, {Communications port} + TimeOut, {Minutes for inactivity time-out} + TimeOutBell, {Minutes for inactivity bell} + Backlogdays, {Number of days to keep SYSOP.LOG's} + PrivilegeSL, {Privilege SL} + PrivilegeDSL, {Privilege DSL} + CDmask, {Carrier detect mask} + MaxLogonTries, {Maximum logon attempts per call} + uub7, {Reserved} + uub8, {Reserved} + UlTimePercent, {UL time percent refund} + MaxChats, {Maximum chat pages per call} + uub9, {Reserved} + TagLineSL : BYTE; {Reserved} + + ClosedSystem, {System closed} + TitlePause, {Allow [PAUSE] on welcome screen} + LogonBulletin, {Logon to the bulletin section} + BlankWait, {Blank the wait screen if no activity} + Handles, {Allow handles} + AutoANSIDetect, {Logon auto-detect ANSI} + SecureSystem, {Keyboard security active} + TimePerDay, {Time limits represent time per day} + Mailer, {External mailer active} + SysopFemale, {SysOp is female} + scantosysoplog : BOOLEAN; {File scans are saved in SysOp log} + + TimeAllowed, {SL array of time per call/per day} + UlDlNumRatio, {DSL array of number of file UL ratios} + UlDlKratio, {DSL array of K-Byte UL ratios} + CallsAllowed, {SL array of calls allowed per day} + PostCall : Range; {SL array of posts per 1/10 call} + + AutoRIPDetect : BOOLEAN; {Logon auto-detect RIP} + + uusystatrec8 : + ARRAY[1..7] OF BYTE; {Reserved} + END; + + + MenuFlagType = ( {Menu flag type} + MenuOrCheck, {SL/DSL or AR - When off SL/DSL and AR} + MenuTimeHelpDisplay, {Time/Help display} + MenuBoardDisplayOverride, {Board display override} + MenuNamePrompt, {Menu name prompt} + AscIIClearBeforeMenu, {ASCII Clear screen before printing menu} + AnsiClearBeforeMenu, {ANSI Clear screen before printing menu} + RipClearBeforeMenu, {RIP Clear screen before printing menu} + UUMF9, {Reserved} + UUMF8, {Reserved} + UUMF7, {Reserved} + UUMF6, {Reserved} + UUMF5, {Reserved} + UUMF4, {Reserved} + UUMF3, {Reserved} + UUMF2, {Reserved} + UUMF1 {Reserved} + ); {1 byte} + + MenuFlagSet = {Set of menu flags} + SET OF MenuFlagType; + + CmdFlagType = ( + CmdOrCheck, {SL or AR - When off SL and AR} + CmdHidden, {Hidden status} + CmdLinkToNext, {Link to next} + AscIIClearBeforeCmd, {ASCII clear screen before command} + AscIIPauseAfterCmd, {ASCII pause after command completed} + AnsiClearBeforeCmd, {ANSI clear screen before command} + AnsiPauseAfterCmd, {ANSI pause after command completed} + RipClearBeforeCmd, {RIP clear screen before command} + RipPauseAfterCmd, {RIP pause after command completed} + AnsiOnly, {Command requires ANSI or RIP} + RipOnly, {Command requires RIP} + UUCF5, {Reserved} + UUCF4, {Reserved} + UUCF3, {Reserved} + UUCF2, {Reserved} + UUCF1 {Reserved} + ); {2 bytes} + + CmdFlagSet = {Set of command flags} + SET OF CmdFlagType; + + MenuRec = RECORD {Menus - MENUS.LST} + LongD : STRING[80]; {Menu desc (menu) or Long command desc (cmd)} + + SL, {Security level (SL)} + DSL : Byte; {Download security level (DSL)} + + ArFlags : ArFlagSet; {AR flag set} + + UUMenu:Array[1..10] of byte; {Reserved} + + CASE Menu : BOOLEAN OF {Menu or command - Variant section} +{80} TRUE : + (MenuFlags : MenuFlagSet; {Menu flag set} + + MenuNum : BYTE; {Menu number} + + mPrompt : STRING[48]; {Menu prompt unless MenuNamePrompt active} + + Password : STRING[16]; {Menu password} + + FallBack : BYTE; {Fallback menu number} + + HelpFile : STRING[7]; {Help file ID name} + + StartHelp : BYTE; {Starting help level 0=default} + + Location : BYTE); {Menu location (0=Main, 1=File, 2=ReadMessage)} +{80} FALSE : + (CmdFlags : CmdFlagSet; {Command flag set} + + Pkey : BYTE; {Command PKey} + + Pdata : STRING[30]; {Command PData} + + Shortd : STRING[32]; {Command short description} + + CmdKey : STRING[12]); {Command execution key} + END; {case/record} + + + MacroRec = RECORD {Macro list - MACROS.LST} + UserN : INTEGER; {User number of macro owner} + + Key : {Txt for each of the macros} + ARRAY[1..4] OF STRING[160]; + END; + + + SprotocolRec = RECORD {Single protocols - SPROT.DAT} + Key : STRING[12]; {Execution key} + + Desc : STRING[60]; {Description} + + MinBaud, {Minimum baud rate to use} + MaxBaud : WORD; {Maximum baud rate to use} + + DSL : BYTE; {DSL required} + + TempLog, {Temp log path and name} + UlLog, {UL log path and name} + DlLog : STRING[52]; {DL log path and name} + + UlString, {UL string for DOS call} + DlString : STRING[70]; {DL string for DOS call} + + GoodCode : BOOLEAN; {Result codes mean good transfer} + + DlCode, {DL error level result codes} + ULcode : ARRAY[1..6] OF BYTE; {DL error level result codes} + END; + + BprotocolRec = RECORD {Batch protocols - BPROT.DAT} + Key : STRING[12]; {Execution key} + + Desc : STRING[60]; {Description} + + MinBaud, {Minimum baud rate to use} + MaxBaud : WORD; {Maximum baud rate to use} + + DSL : BYTE; {DSL required} + + UlString, {UL string for DOS call} + DlString : STRING[70]; {DL string for DOS call} + + UlList, {UL file list file path and name} + DlList, {DL file list file path and name} + TempLog, {Temp log path and name} + UlLog, {UL log path and name} + DlLog : STRING[52]; {DL log path and name} + + MaxCmdLen, {Maximum command line length} + PosFn, {Position of filename in log} + PosStatus : BYTE; {Position of status in log} + + GoodCode : BOOLEAN; {Result codes mean good transfer} + + DlCode, {DL status result codes} + ULcode : {UL status result codes} + ARRAY[1..6] OF STRING[10]; + END; + + ValidationRec = RECORD {Validation information - VALIDATE.DAT} + Key : CHAR; {Execution key} + + Desc : STRING[160]; {Descrip sent to user after validation} + {76 max real length - Rest for color} + + SL, {SL to set on validation} + DSL : BYTE; {DSL to set on validation} + + Credit, {Credit in cents to set on validation} + Points, {File points to set on validation} + TimeBank : WORD; {Time bank minutes to set on validation} + + Ar : ArFlagset; {AR flags to set on validation} + + Flags : FlagSet; {Special flags to set on validation} + + UnusedWord : WORD; {Reserved} + END; + + EventType = ( {Event flags} + UnknownEvent, {1 Unknown} + EventIsExternal, {2 External/Internal} + EventIsActive, {3 Active/InActive} + EventIsShell, {4 Shell/Error} + EventIsMonthly, {5 Monthly/Daily} + EventIsPermission, {6 Permission/Restriction} + EventIsChat, {7 Chat Event} + EventIsSoft, {8 Soft/Hard} + + BaudIsActive, {9 Baud Rate Flag} + SLisActive, {10 SL Flag} + DSLisActive, {11 DSL Flag} + ARisActive, {12 ARflag required} + InRatioIsActive, {13 InRatioFlag} + TimeIsActive, {14 Time Flag} + SetARisActive, {15 Set AR flag} + ClearARisActive, {16 Clear AR Flag} + + uuEvent24, {17 Reserved} + uuEvent23, {18 Reserved} + uuEvent22, {19 Reserved} + uuEvent21, {20 Reserved} + uuEvent20, {21 Reserved} + uuEvent19, {22 Reserved} + uuEvent18, {23 Reserved} + uuEvent17, {24 Reserved} + + uuEvent16, {25 Reserved} + uuEvent15, {26 Reserved} + uuEvent14, {27 Reserved} + uuEvent13, {28 Reserved} + uuEvent12, {29 Reserved} + uuEvent11, {30 Reserved} + uuEvent10, {31 Reserved} + uuEvent9, {32 Reserved} + + uuEvent8, {33 Reserved} + uuEvent7, {34 Reserved} + uuEvent6, {35 Reserved} + uuEvent5, {36 Reserved} + uuEvent4, {37 Reserved} + uuEvent3, {38 Reserved} + uuEvent2, {39 Reserved} + uuEvent1 {40 Reserved} + ); + + EventFlagSet = SET OF EventType; { Added } + + EventDaysType = SET OF 0..6; {Set of event days} + + {*************************************************************************} + {* The Record Structure of the EventFile *} + {*************************************************************************} + EventRecordType = RECORD {Events - EVENTS.DAT} + EventFlags : EventFlagSet; {Kinds of Events Supported} { Changed } + + EventDayOfMonth : BYTE; {If monthly, the Day of Month} + + EventDays : EventDaysType; {If Daily, the Days Active} + + EventStartTime, {Start Time in Min from Mid.} + EventFinishTime : WORD; {Finish Time} + + EventDesc : STRING[32]; {Description of the Event} + + EventQualMsg, {Msg/Path if he qualifies} + EventNotQualMsg : STRING[64]; {Msg/Path if he doesn't} + + EventPreTime : BYTE; {Min. B4 event to rest. Call} + + EventOffHook : BOOLEAN; {Take phone Offhook ?} + + EventLastDate : STRING[8]; {Last Date Executed} + + EventErrorLevel : BYTE; {For Ext Event ErrorLevel} + + EventShellPath : STRING[8]; {File for Ext Event Shell} + + LoBaud, {Low baud rate limit} + HiBaud : WORD; {High baud rate limit} + + LoSL, {Low SL limit} + HiSL, {High SL limit} + LoDSL, {Low DSL limit} + HiDSL : BYTE; {High DSL limit} + + ARflagRequired : CHAR; {AR flag required} + + MaxTimeAllowed : WORD; {Max Time per user this event} + + SetARflag, {AR Flag to Set} + ClearARflag : CHAR; {AR Flag to Clear} + + EventUnused : {Reserved} + ARRAY[1..128] OF BYTE; + END; + +CONST + maxmodemresultcodes = 45; {Maximum number of modem result codes} + +TYPE + modemresulttype = ( {Modem result types} + resulterror, {Command error} + resultok, {Command accepted} + resultring, {Phone ringing} + resultnocarrier, {Connect attempt failed} + resultconnect, {Connect succcessful} + resultwaitscreen, {Go to wait screen} + resultlocallogon, {Logcal logon} + resultshellbatch, {Shell to batch file} + resultexiterrorlevel, {Exit system with error level} + resultexitsystem, {Exit system with error level 255} + + {The following are not supported} + resultnodialtone, {Reserved} + resultringing, {Reserved} + resultbusy, {Reserved} + resultnoanswer, {Reserved} + resultvoice {Reserved} + ); + + modemresultset = {Set to modem results - Used intenally} + SET OF modemresulttype; + + + resultrec = RECORD + typeofresult : {Type of result} + modemresulttype; + + result : STRING[50]; {Test of result} + + connectrate, {Connect rate modem to modem} + realrate, {Real rate computer to modem} + controlcode : LONGINT; {Error level or startup code} + + fullduplex, {Full duplex operation?} + errorcorrecting : BOOLEAN; {Error correcting modem?} + + Unused : ARRAY[1..8] OF CHAR; {Reserved} + END; + +{ +Modem string mapping codes: + +Char. Name Action +----- --------------- ------------------------------ + ^ Carat Control code of next character + | Pipe, Split Bar Carriage return sent + ` Accent Mark 1/20th second delay + ~ Tilde 1/2 second delay + ^- Carat & Minus Lower DTR line + ^+ Carat & Plus Raise DTR line +} + + modemrec = RECORD {Modem record - MODEM.DAT} + uuunused : BOOLEAN; {Unused} + + modemdescription : {Description on modem} + STRING[64]; + + characterdelay : BYTE; {Miliseconds} + + ctsrts, {Hardware flow control active} + samering, {Reserved} + nocollide : BOOLEAN; {Reserved} + + numberresults : BYTE; {Number of modem result codes defined} + + result : {Array of results} + ARRAY[1..maxmodemresultcodes] OF + resultrec; + + preinitialization, {Pre-initialization string} + initialization, {Initialization string} + answer, {Answer string} + busy, {Busy string} + hangupprimary, {Hangup primary string} + hangupsecondary, {Hangup secondard string} + afterhangup, {After hangup string} + exitsystem, {Exit system string} + predial, {Reserved} + dialprefix, {Reserved} + dialsuffix : STRING[64]; {Reserved} + + waitbaud : LONGINT; {Init modem speed} + + lockedbaud : BOOLEAN; {Is baud rate locked - Not used by Dragon} + + ecefficiency, {Error correcting efficiency} + ncefficiency : BYTE; {Normal connect efficiency} + + Unused : + ARRAY[1..249] OF CHAR; {Reserved} + END; + +CONST + MaxSubOps = 10; {Maximum number of message section SubOps} + +TYPE + NoYesForcedType = ( {Message section type} + No, {Anonymous messages not allowed} + Yes, {Anonymous messages allowed} + Forced, {Messages forced anonymous} + AtUnused {Reserved} + ); + + {*************************************************************************} + {* Standard Attributes for Messages *} + {*************************************************************************} + MessageAttrFlagType = ( + Msg_Private, {1 fPrivate,RaPrivate,JamPrivate} + Msg_Crash, {2 fCrash,Crash,JamCrash} + Msg_Received, {3 fReceived,Received,JamRead} + Msg_Sent, {4 fSent,Sent,JamSent} + Msg_FileAttached, {5 fFileAttached,FileAttach, + JamFileAttach} + Msg_KillSent, {6 fKillSent,KillSent,JamKillSent} + Msg_Local, {7 fLocal,LocalMessage,JamLocal} + Msg_ReturnReceiptRequest, {8 fReportReceiptRequest,RequestReceipt, + JamReceiptReq} + Msg_IsReturnReceipt, {9 fIsReturnReceipt,ReturnReceipt} + Msg_AuditRequest, {10 fAuditRequest,AuditRequest} + + Msg_InTransit, {11 fInTransit,JamIntransit} + Msg_Orphan, {12 fOrphan,JamOrphan} + Msg_HoldForPickup, {13 fHoldForPickup,JamHold} + Msg_Fido_UnusedBit10, {14 fUnusedBit10} + Msg_FileRequest, {15 fFileRequest,JamFileRequest} + Msg_Fido_FileUpdateRequest, {16 fFileUpdateRequest} + + Msg_Deleted, {17 Deleted,JamDeleted} + Msg_Ra_NetmailPendingExport, {18 NetmailPendingExport} + Msg_NetMailMessage, {19 NetMailMessage,JamTypeNet} + Msg_Ra_EchomailPendingExport, {20 EchomailPendingExport} + Msg_Ra_UnusedMsgBit7, {21 UnusedMsgBit7} + Msg_Ra_UnusedNetBit7, {22 UnusedNetBit7} + + Msg_Jam_ArchiveSent, {23 JamArchiveSent} + Msg_Jam_Immediate, {24 JamImmediate} + Msg_Jam_Direct, {25 JamDirect} + Msg_Jam_Gate, {26 JamGate} + Msg_Jam_ConfirmRequest, {27 JamConfirmReq} + Msg_Jam_ForcePickUp, {28 JamFpu} + Msg_Jam_TypeLocal, {29 JamTypeLocal} + Msg_Jam_TypeEcho, {30 JamTypeEcho} + Msg_Jam_NoDisplay, {31 JamNoDisp} + Msg_Jam_Locked {32 JamLocked} + ); {4 Bytes Total} + + MessageAttrFlagSet = {Set of message attributes} + Set of MessageAttrFlagType; + + MBstyle = ( {Message section style flags} + uumbbstyle, {Was For Private Mail Board} + LocalStyle, {Local} + EchoStyle, {Echomail} + NetmailStyle, {Netmail} + GroupStyle {Groupmail} + ); + + MBtype = ( {Message section type flags} + uumbtype, {Was For Netmail Board} + FidoFormat, {Fido 1.Msg Format} + RaFormat, {Remote Access Format} + JamFormat); {Jam Format} + + MboardType = RECORD {Message boards - MBOARDS.DAT} + Name : STRING[64]; {Name of the Board} + + Mstyle : MBstyle; {Local/Echo/Netmail} + + Mtype : MBtype; {Message Board Type} + + RaBoard : BYTE; {Board Number if RA/QBBS type} + + Path : STRING[64]; {Directory PathName} + + OriginLine : STRING[65]; {Origin Line} + + AccessAR, {AR flag Required to Access} + PostAR : ArFlagType; {AR flag required to Post} + + AccessSL, {Security Level Required to Access} + PostSL : BYTE; {Security Level Required to Post} + + MsgCount, {Count of Msgs on the Board} + MaxMsgs, {Max Number of Messages} + uuMaxOld : WORD; {Max Days for Messages} + + Password : STRING[16]; {Password Required} + + Anon : NoYesForcedType; {Anonymous Type} + + AllowAnsi : BOOLEAN; {Should we allow ANSI} + + AllowHandle : {Should we allow handles} + NoYesForcedType; + + {*********************************************************} + {* Message Board SubOpts List - Up to 10 - User Numbers *} + {*********************************************************} + SubOps : {SubOps - Item 0 = How many} + ARRAY[0..MaxSubOps] OF + INTEGER; + + EchoTag : STRING[32]; {Echo Tag for Writing ECHOMAIL.BBS} + + UseOtherAddress: BOOLEAN; {Use something other than system} + + JamBoard : STRING[8]; {JAM 8 character file name} + + AskPrivate : Boolean; {Ask if in area private message (echos)} + + Reserved: {Unused} + ARRAY[1..13] of byte; + + MenuNumber : BYTE; {Default read message number (if 0, use system default} + + PrePostFile : STRING[8]; {Prepost file name} + + MinMsgs : BYTE; {Minimum number of messages} + + QuoteStart, {Override starting quote} + QuoteEnd : STRING[70]; {Override ending quote} + + QwkConf : WORD; {QWK Conference Number} + + GroupNumber : BYTE; {What group the board belongs} + + OtherAddress : AddressType; {The Address to use!} + + RestrictPrivate: {Private mail status} + NoYesForcedType; + + DefaultAttr : {Default message flags} + MessageAttrFlagSet; + + QwkName : String[10]; {QWK Conference Name} + + Filter7Bit : Boolean; {Only allow 7 bit characters} + END; + +TYPE + LastOnType = {Last Few Callers - LASTON.DAT} + Array[1..8] of String[160]; + +Const + MaxBits = 1024; {Means a 128 Byte BitSet Bits 0 to 1023} + +Type + BitSetType = {Board Flags - ?ZSCAN.DAT} + Array[0..(MaxBits Div 8)-1] of + Byte; + + + WhoRecType = RECORD {Who's online - $WHO.DAT} + Active : Boolean; + + Node : Byte; {Node number for this record} + + Available : Boolean; {Is he available for anything} + + Uname : String[36]; {Users Name} + + CityState : String[30]; {City and State} + + Baud : LongInt; {Baud Rate} + + Paging : Byte; {Paging Node Number} + + InPrivateChat : Byte; {Node in private chat with} + + InGroupChat : Boolean; {Is he in Group Chat} + + Desc : String[64]; {Long Description} + END; + + UserOnType100 = RECORD {USERON.BBS file version 1.00} + Name : String[35]; {User name} + + Line : Byte; {Node number} + + Baud : Word; {Connect rate} + + City : String[25]; {City/State} + + DoNotDisturb : Boolean; {Do not disturb} + + Status : Byte; {Status} + END; + + UserOnType11x = RECORD {USERON.BBS file version 1.1x} + Name : String[35]; {Real name} + + Handle : String[35]; {User name} + + Line : Byte; {Node number} + + Baud : Word; {Connect rate} + + City : String[25]; {City/State} + + DoNotDisturb : Boolean; {Do not disturb} + + Status : Byte; {Status} + + Attribute : Byte; {Attribute} + END; + + Type200Attr = (RA_Hidden, {Bit 0} + RA_WantsChat, {Bit 1} + RA_Netmgr, {Bit 2} + RA_DoNotDisturb, {Bit 3} + RA_Bit4, {Bit 4} + RA_Bit5, {Bit 5} + RA_Ready, {Bit 6} + RA_Bit7); {Bit 7} + + UserOnType200 = RECORD {USERON.BBS file version 2.00 Gamma} + Name : String[35]; {Real name} + Handle : String[35]; {User name} + Line : Byte; {Node number} + Baud : Word; {Connect rate} + City : String[25]; {City/State} + Status : Byte; {Status} + + { Status byte - 0 : Browsing (in a menu) + 1 : Uploading/downloading + 2 : Reading/posting messages + 3 : In a door/external utility + 4 : Chatting with sysop + 5 : Answering questionnaire + 6 : RTC + 7 : New user logon + 255 : User-defined - display StatDesc + } + Attribute : Type200Attr; {Attribute} + StatDesc : String[10]; {Status Description} + FreeSpace : Array[1..98] of Byte; {For Expansion} + NoCalls : Word; + END; + diff --git a/SOURCE/UNUSED/EC.PAS b/SOURCE/UNUSED/EC.PAS new file mode 100644 index 0000000..05d03e9 --- /dev/null +++ b/SOURCE/UNUSED/EC.PAS @@ -0,0 +1,55 @@ +uses crt; + +var verline:array [0..3] of string; + s3:string; + f:text; + i:byte; + loop:integer; + +function encrypt(s:string):string; +var b:byte; + s2:string; + t:byte; +begin + s2:=''; + s2[0] := s[0]; t := 0; + for b:=1 to length(s) do + begin + s2[b] := chr(ord(s[b]) + ord(s2[b-1])); + inc(t, ord(s2[b])); + end; + writeln('Total: ',t); + encrypt:=s2; +end; + +function decrypt(s:string):string; +var b:byte; + s2:string; +begin + s2:=''; + for b:=1 to length(s) do + s2:=s2+chr(ord(s[b]) - ord(s[b-1])); + decrypt:=s2; +end; + +begin + clrscr; + {verline[0]:='|03The |11Renegade Bulletin Board System|03 Version ';} + verline[1]:= ('|03Copyright (C) 2003-2005 |03.'); + verline[2]:= ('|03Copyright (C) 2003-2005 |03.'); + verline[3]:= ('|03Copyright (C) 2003-2005 |03.'); + {verline:='--- Renegade v';} + assign(f,'ec.txt'); + s3:=''; + rewrite(f); +{ for loop := 0 to 3 do + begin} + writeln(verline[3]); + writeln(f,verline[3]); + s3:=encrypt(verline[3]); + writeln(s3); + writeln(f,s3); +{ end;} + close(f); +end. + diff --git a/SOURCE/UNUSED/EC.TXT b/SOURCE/UNUSED/EC.TXT new file mode 100644 index 0000000..fcea237 --- /dev/null +++ b/SOURCE/UNUSED/EC.TXT @@ -0,0 +1,2 @@ +|03Copyright (C) 2003-2005 |03. +A tCBkP}DdCq diff --git a/SOURCE/UNUSED/EMAIL.TPU b/SOURCE/UNUSED/EMAIL.TPU new file mode 100644 index 0000000000000000000000000000000000000000..75ebfb575de8a6cd752820d981dccb260c900291 GIT binary patch literal 33248 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͆f{A9kWFb<)|Dsem%n*UcKrP;_bPRJ5 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 Cjk}lt literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/ERROR.LOG b/SOURCE/UNUSED/ERROR.LOG new file mode 100644 index 0000000..10a69a3 --- /dev/null +++ b/SOURCE/UNUSED/ERROR.LOG @@ -0,0 +1,33 @@ + +Critical error Log file - Contains screen images at instant of error. +The "" character shows the cursor position at time of error. + + + +> error #207 at 10-13-2009 9:44 pm version: 1.10/Alpha +> User "LEE PALMER #2" was on Locally + 1 Test Area 1 2 Test Area 2 + 3 Test Area 3 4 Test Area 4 + 5 Test Area 5 6 Test Area 6 + 7 Test Area 7 8 Test Area 8 + 9 Test Area 9 10 Test Area 10 + 11 Test Area 11 12 Test Area 12 + 13 Test Area 13 14 Test Area 14 + 15 Test Area 15 16 Test Area 16 + 17 Test Area 17 18 Test Area 18 + 19 Test Area 19 20 Test Area 20 + 21 Test Area 21 22 Test Area 22 + 23 Test Area 23 24 Test Area 24 + 25 Test Area 25 26 Test Area 26 + 27 Test Area 27 28 Test Area 28 + 29 Test Area 29 30 Test Area 30 + 31 Test Area 31 32 Test Area 32 + 33 Test Area 33 34 Test Area 34 + 35 Test Area 35 36 Test Area 36 + +Change file area? (1-69) [#,?=Help,Q=Quit]: + +Invalid command keys: + + Lee Palmer AR: ABCDEFGHIJKLMNOPQRSTUVWXYZ NSL: 255 Time: 32759 + Lee Palmer #2 AC: LCVUA*PEKM1234 Baud: 0 DSL: 255 Node: 6 diff --git a/SOURCE/UNUSED/EVENT.PAS b/SOURCE/UNUSED/EVENT.PAS new file mode 100644 index 0000000..98cfd3a --- /dev/null +++ b/SOURCE/UNUSED/EVENT.PAS @@ -0,0 +1,248 @@ +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Event; + +INTERFACE + +FUNCTION InTime(Tim,Tim1,Tim2: LongInt): Boolean; +FUNCTION CheckEventDay(EventNum: Integer; T: LongInt): Boolean; +FUNCTION CheckPreEventTime(EventNum: Integer; T: LongInt): Boolean; +FUNCTION CheckEventTime(EventNum: Integer; T: LongInt): Boolean; +FUNCTION CheckEvents(T: LongInt): Integer; +FUNCTION SysOpAvailable: Boolean; + +IMPLEMENTATION + +USES + Dos, + Common, + TimeFunc; + +FUNCTION InTime(Tim,Tim1,Tim2: LongInt): Boolean; +BEGIN + InTime := TRUE; + WHILE (Tim >= 86400) DO + Dec(Tim,86400); + IF (Tim1 <> Tim2) THEN + IF (Tim2 > Tim1) THEN + IF (Tim <= (Tim1 * 60)) OR (Tim >= (Tim2 * 60)) THEN + InTime := FALSE + ELSE + ELSE + IF (Tim <= (Tim1 * 60)) AND (Tim >= (Tim2 * 60)) THEN + InTime := FALSE; +END; + +(* +function checkeventday(i:integer; t:longint):boolean; +var + year,month,day,dayofweek:word; + e:integer; +begin + e := 0; + checkeventday := FALSE; + if not events[i]^.active then + exit; + with events[i]^ do + begin + getdate(year,month,day,dayofweek); + if (timer + t >= 86400.0) then + begin + inc(dayofweek); + e := 1; + if (dayofweek > 6) then + dayofweek := 0; + end; + if (monthly) then + begin + if (value(copy(date,4,2)) + e = execdays) then + checkeventday := TRUE; + end + else + begin + e := 1 shl (dayofweek + 1); + if (execdays and e = e) then + checkeventday:=TRUE; + end; + end; +end; +*) + +FUNCTION CheckEventDay(EventNum: Integer; T: LongInt): Boolean; +VAR + DayOfWeek, + Day: Byte; + DeleteMeTimer: Longint; +BEGIN + CheckEventDay := FALSE; + WITH MemEventArray[EventNum]^ DO + BEGIN + IF (NOT (EventIsActive IN EFlags)) THEN + Exit; + Day := 0; + GetDayOfWeek(DayOfWeek); + DeleteMeTimer := Timer + T; + IF ((Timer + T) >= 86400.0) THEN + BEGIN + Inc(DayOfWeek); + IF (DayOfWeek > 6) THEN + DayOfWeek := 0; + Day := 1; + END; + IF (EventIsMonthly IN EFlags) THEN + BEGIN + IF ((StrToInt(Copy(DateStr,4,2)) + Day) = EventDayOfMonth) THEN + CheckEventDay := TRUE; + END + ELSE IF (DayOfWeek IN EventDays) THEN + CheckEventDay := TRUE; + END; +END; + +(* +function checkpreeventtime(i:integer; t:longint):boolean; +begin + with events[i]^ do + if (offhooktime = 0) or + (durationorlastday=daynum(date)) or + ((Enode > 0) and (Enode <> node)) or + (not events[i]^.active) or not + (checkeventday(i,t)) then + checkpreeventtime:=FALSE + else + checkpreeventtime:=intime(timer+t,exectime-offhooktime,exectime); +end; +*) + +FUNCTION CheckPreEventTime(EventNum: Integer; T: LongInt): Boolean; + +BEGIN + WITH MemEventArray[EventNum]^ DO + IF (NOT (EventIsActive IN EFlags)) OR + (EventPreTime = 0) OR + (PD2Date(EventLastDate) = DateStr) OR + ((EventNode > 0) AND (EventNode <> ThisNode)) OR + NOT (CheckEventDay(EventNum,T)) THEN + CheckPreEventTime := FALSE + ELSE + CheckPreEventTime := InTime((Timer + T),(EventStartTime - EventPreTime),EventStartTime); + (* + checkpreeventtime := intime(timer + t,exectime-offhooktime,exectime); + *) +END; + +(* +function checkeventtime(i:integer; t:longint):boolean; +begin + with events[i]^ do + if (durationorlastday=daynum(date)) or + ((Enode > 0) and (Enode <> node)) or + (not events[i]^.active) or not + (checkeventday(i,t)) then + checkeventtime:=FALSE + else + if (etype in ['A','C']) then + checkeventtime:=intime(timer+t,exectime,exectime+durationorlastday) + else + if (missed) then + checkeventtime := (((timer + t) div 60) > exectime) + else + checkeventtime := (((timer + t) div 60) = exectime); +end; +*) + +FUNCTION CheckEventTime(EventNum: Integer; T: LongInt): Boolean; +VAR + DeleteMe: AStr; +BEGIN + DeleteMe := PD2Date(MemEventArray[EventNum]^.EventLastDate); + WITH MemEventArray[EventNum]^ DO + IF (PD2Date(EventLastDate) = DateStr) OR + ((EventNode > 0) AND (EventNode <> ThisNode)) OR + (NOT (EventIsActive IN EFlags)) OR + NOT (CheckEventDay(EventNum,T)) THEN + CheckEventTime := FALSE + ELSE + IF (EventIsLogon IN EFlags) OR (EventIsChat IN EFlags) THEN + CheckEventTime := InTime((Timer + T),EventStartTime,(EventStartTime + EventFinishTime)) + (* + checkeventtime := intime(timer + t,exectime,exectime+durationorlastday) + *) + ELSE + IF (EventIsMissed IN EFlags) THEN + CheckEventTime := (((Timer + T) DIV 60) > EventStartTime) + ELSE + CheckEventTime := (((Timer + T) DIV 60) = EventStartTime); +END; + +(* +function checkevents(t:longint):integer; +var i:integer; +begin + for i := 1 to numevents do + with events[i]^ do + if (active) and ((Enode = 0) or (Enode = node)) then + if (checkeventday(i,t)) then begin + if (softevent) and (not inwfcmenu) then + checkevents:=0 + else + checkevents:=i; + if (checkpreeventtime(i,t)) or (checkeventtime(i,t)) then begin + if (etype in ['D','E','P']) then exit; + if ((etype='A') and (not aacs(execdata)) and (useron)) then exit; + end; + end; + checkevents:=0; +end; +*) + +FUNCTION CheckEvents(T: LongInt): Integer; +VAR + EventNum: Integer; +BEGIN + FOR EventNum := 1 TO NumEvents DO + WITH MemEventArray[EventNum]^ DO + IF (EventIsActive IN EFlags) AND ((EventNode = 0) OR (EventNode = ThisNode)) THEN + IF (CheckEventDay(EventNum,T)) THEN + BEGIN + IF (EventISSoft IN EFlags) AND (NOT InWFCMenu) THEN + CheckEvents := 0 + ELSE + CheckEvents := EventNum; + IF (CheckPreEventTime(EventNum,T)) OR (CheckEventTime(EventNum,T)) THEN + BEGIN + IF (EventIsExternal IN EFlags) THEN + IF (EventIsShell IN EFlags) OR + (EventIsErrorLevel IN EFlags) OR + (EventIsPackMsgAreas IN EFlags) OR + (EventIsSortFiles IN EFlags) OR + (EventISFilesBBS IN EFlags) THEN + Exit; + IF ((EventIsLoGon IN EFlags) AND (NOT AACS(EventACS)) AND (UserOn)) THEN + Exit; + END; + END; + CheckEvents := 0; +END; + +FUNCTION SysOpAvailable: Boolean; +VAR + A: Byte ABSOLUTE $0000:$0417; + EventNum: Integer; + ChatOk: Boolean; +BEGIN + + ChatOk := ((A AND 16) = 0); + + IF (RChat IN ThisUser.Flags) THEN + ChatOk := FALSE; + + FOR EventNum := 1 TO NumEvents DO + WITH MemEventArray[EventNum]^ DO + IF (EventIsActive IN EFlags) AND (EventIsChat IN EFlags) AND (CheckEventTime(EventNum,0)) THEN + ChatOk := TRUE; + + SysOpAvailable := ChatOk; +END; + +END. diff --git a/SOURCE/UNUSED/EVENT.TPU b/SOURCE/UNUSED/EVENT.TPU new file mode 100644 index 0000000000000000000000000000000000000000..28d638a86b87e6f612e022ca65784baf95aeb85f GIT binary patch literal 4448 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 S{>lqq(EZNSc`Ly6xBmh{n18qc literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/EVENTS.TPU b/SOURCE/UNUSED/EVENTS.TPU new file mode 100644 index 0000000000000000000000000000000000000000..10ade6c6835ed498d3b1e9ac38ccc33413313802 GIT binary patch literal 4224 zcmb7IeNa@_6+iETw{LfG1;G^~4xo`_?4$+EOiVYmSmlj^z%C$IgGOS>kSNNq9|WZf zj&&-m*8EjJW0bK<$s{$?B(>9OkrLF935X_Q(-|gy6v^VGaUw$y+5Ya`x9n=DwGZ$6 z-E;0azjr?Fef!2D`$`Alx<>10t^8ZLQ~&!`R-&S#&PKIJ6;VWQ2+Sr!6mhSj28l_J zcX>$_s<`*$_Sc~9dBpnN2)F0C-LXelM;J#;3zaNS`6ic>Xz<8gn$40ZR0?aIuJTGE zQ^zO>@vlHxzNzTd%5p(fVemezlqoW2sTKkxQ338^_y&jAB^BlCH`uGoIepMK1|B<5 zpGaSk=1=&-&BEOxd=lXE;iG-bVIQZUCc|MM!hz8X!2lUQQp>Me>?wP7W7*3akF+oLz($dW+%2NX-k(aqpS+cpZa`Psl@1kaltSnThva~e!ru9VM?m)Ff3Uw6I zNv}{xd7US*2z8Y4|9>4F)}N@*bw2CC-60{sITq|PWR5bN5gjr#>2pjIDi|?U#vCO= zRbbf|F6q*;T0u=itn(v^%DNueIfdu)qU3~)L*?zub64UyEG*UmsD&atgvl(FXC;Rb z%=xdBl$UQ1#{*1ng+51eNYIP-Cp1CoJ<{=qsabs@shP~EgAQ%dm4_YJQHyk7a@awT zzhMqMN_LFcN@OzPSb(V+fkMl%V>0*wa0rW~8GOdVf5?FyUgj`Ib|_0K%3S#y#Crjz ztmd{v0bIOv`i-3scClU0u4H~EV!M=G?DP>`*5yIUq?wT0X&Eg7E*2_i6);J#Qw^{Y zc87qcXyQaC3lrxZ)6kYqpoy)FR6bc=X)|RNXXO&`#e-CKBWhaP_0rUt(um!w$Jl{jz}$fp530Vy!u=lAKvKRF}fc3+`!>IdV^x!RwW~?_uZpOR? z*aB6dZK1)}x4_R!t8=~3dtr9~YX`A*2y2Jn^Co=WBty}@(NDKIhK}sY z#+#=^SmD|}Bz9^6VY@d*s5jP4+vc@2II7LtHUYM;jS>9+@@XbtakQ;ib*nZ_aZ7`{ z$fqg3V%1h0U2mvcV$)2XMM0xKzd-37h7$JcJJK2so~i>?+xP zX5_w=-9sFwWU`~G_AsIEyzd`P+WoW}>Alj~xJyio2r0EGD~T=HE}^n#-K-XZe`ZtO zc*A$9Gxns=+s2;utE^-fU(yp*c%n)uQALbkZ1j%q(#C>Gx_+M8aQXz1%dz{+C_?P; zj;01ac$;wheX#S;BY|+VuBVty!|4_xk2$qzM+^NJKSb`>fX5W@r~!{+xrN`!Hn+l? zmJw010z30;+JVD!!`GAQ%S!n{dwOqyoy{0B$DLZ>u`_t=h%+XQIFV_2r(NF*-oSz% z{D49x4Q`b;RB%1>y@d4WSr(~M*4&6p{O+LtRZ4a}7vUG)BaY0&3x3@HlR6IJv@34;0W8I=`l)*xuUcDS>R-s8<@i18K}J1++1rcPzaBhj(dg z?*{k(-znH=mt~^SE@|)`3V6mI=(RMsAEg@RC5mxb8ra8>+mPPYsEzv-pEd@3*aanj zfWx&aNYF=uYd#M^btiL_-3c6H+%X)Jc`y1X(uOf-*NHD!Ev>Vhm&LZ$&M%*7YY4;|!dRORuOKC^&C55l1w5Oq3 zqhqa(2X*`tFlc9egXnm1BBi7)g#GhmO|#=;a1rDN$iIYL6|f2Ve?z~Ag7$xS$Ug!0 z6|h^X`{iSOC*&fs_7J^78}S*L26?N_zZ0?w`ThUG^Q_MEQ=Mn2&Qq%McyykzEk*rg1dZuHQ|Fl Vg6}Uy^EltTB|p-6b9KMh=s!N3Q`!Ik literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/EXECBAT.TPU b/SOURCE/UNUSED/EXECBAT.TPU new file mode 100644 index 0000000000000000000000000000000000000000..7862a119093f4e3f40b88a96b72b5111c3f3b5b1 GIT binary patch literal 6048 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 g>c^>-;sj0L)DY)K1pS=zI!zGrNdlKCC>A^fvl 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 z zhTK#|+}U|2BB$?cOfoE7${MD`o|1CX7PwaIJSBBDj-<~>-;ssq+{4B1*)zkC<&~0~ zo4eRF6Ji;LFu`Y~u*>`&6V@m#zll1?ON{EQ)O+eZioc(LC6YIOFnQ!>k$2;fComE{7YY%xIo!=r`l?RD-;t^#=R7hYN}- zkNQ`X=LNRH!;V1^h&B4-%vvZ`tyB($V*BGzllqMGX+?|rlyoti2;yrS^X#gXeu1=x z{$HR3L+BTXG6eG-yxopFR^CLu`#pgkWrtcH8GYJ%-+IS%%OowGWjbrpr=>59IlYj% z+z`L`g@zgCT19=sl=gb_eFYyh3kOMZ7ca_To{aXCO)Q;NJQPl;jIiErypA`K!9Ip2 zRH%YoPIn!bV1s;2YfMwU+h%O9Za{4l91T-uo{~1iZ;x6$v0-Xht+ZhVROu-xWS9v) zDXka7`d**op3*DwLUx|Xm||-HV0zm#th>Hp=KT-g(vB~W@Z~YSbbnBPIHn1ojj1h@ z$DSym;8;jyb=AenY7?r2$I8l0T0`YV2s<&Yvf4&K*dZ0Tm4{OCPD{Ui(@zys)>Aj- z`#@*p-WyNg#9TO>gW}JjDDVL*IGsYlorb#-?r>5?tMZ;%(JJ5o-QoQgIr-tQE^_4I zuP&hd;5UYS=HTWPAj!$RP z*=o-a*p@-U{{I3QoM^%-qSPlcm2kWUoc!SjW;Ki`48+MpX5gzg;*S}@6RfCn?a%SY zoK~-g133^Q0bqtnyWC$b@r1qvB?iG0-SY1BO0czm%eTx}_l!}eLZ9hd)gWY@z% z7CN1cAr{LD7Ukx6Wf=c$7o;a(>0ezmPE#|fP~I}R=A6b+M3HA=nrL-xiIQ|zMf7&= z)wpG9OBp0zMj8FmK;R9uShffn$0oj%(lRd7};I|J>5D_UcHhc9eF?fjs$Csd^dbIHpn*-Yhydoy@A_N8@Od;rm zWC!pNov!v23=~_3oqr4QzVXqN)#qcF6!`isXR;LYSlDS*2Y*aYQ#XHa-WeL<%mqN^ z{P)InUVC&?3e0w#Ek3GTZIwmes?As8PtT2|Qa!uM4F!kK#<2e`OQB=`>Bce+5hT~| z5Fz2@hX{fr;cS*zpc#`vAwNE~*5G!$4^jzro*)bqBsl=PU&{E15;-X4cJ++O_60cA z-!=fy(S!frJNnKPbYMnI6GvC0_`^aLO69ntL8l#x?_Y}@4m$5-J>Pqi(4ri*Y274b z7!bB8a}pgMa~cMR4dILq+YAa9Rpw z83zM``-va!Cp;{4XJ8UDLJK|Leqh$&>(iK%uA8vSr_ObqIkhNV&P@oC9F2SM6nQQ#DT2~7Us;*W;OeSo#>xpS)Ks7P8Zv*kx;3ioA zJfEOB8+x@!I-finbT!%7md6F>!RfKKW2bMrwrzDi+~#@+QO?J-!b*r-6sAo!%EV;y z#9Yz=UpAh#1n`mpLy%(-Dvp zB?>_4STLvirq>iptToSg6e3S;nG!}}xfRZO0Ur%VR&dWIA8Kj}gA#B|*s(8(IUQF6 zJ9}z47!39@r}#wVeFFGlTy5bTXXo>LWNa2rtL3fxBXAtY%wWTWT5Re{VfIsrdGkD-AJpA!6 z6}!)^f<41xm|Vra|$$@y@BKmhK$1OLd}1t)!CT2*ZSUTFVt5V$ai zsbS9hK+YZv4M2tdnwrq_h0-bl-lJ`B;f*>iSZ$*Ql+c8&9s&7H(|g}=?ic5#>9J73 zBEt6>!NB9fblLHr4v`(YAl006w8hwZJ1hCWwjfUUesRP5L;ipK0u$iR8iS7sUnnIA Jj!*jh{x71)(un{7 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/FAELNG.PAS b/SOURCE/UNUSED/FAELNG.PAS new file mode 100644 index 0000000..b938cf1 --- /dev/null +++ b/SOURCE/UNUSED/FAELNG.PAS @@ -0,0 +1,267 @@ +PROGRAM RGLNG; + +USES + Crt, + Dos, + Common; + +TYPE + StrPointerRec = RECORD + Pointer, + TextSize: LongInt; + END; + +VAR + RGStrFile: FILE; + StrPointerFile: FILE OF StrPointerRec; + StrPointer: StrPointerRec; + F: Text; + S: STRING; + RGStrNum: LongInt; + Done, + Found: Boolean; + +FUNCTION AllCaps(S: STRING): STRING; +VAR + I: Integer; +BEGIN + FOR I := 1 TO Length(S) DO + IF (S[I] IN ['a'..'z']) THEN + S[I] := Chr(Ord(S[I]) - Ord('a')+Ord('A')); + AllCaps := S; +END; + +FUNCTION SQOutSp(S: STRING): STRING; +BEGIN + WHILE (Pos(' ',S) > 0) DO + Delete(s,Pos(' ',S),1); + SQOutSp := S; +END; + +FUNCTION Exist(FN: STRING): Boolean; +VAR + DirInfo: SearchRec; +BEGIN + FindFirst(SQOutSp(FN),AnyFile,DirInfo); + Exist := (DOSError = 0); +END; + +PROCEDURE CompileFileAreaEditorStrings; +BEGIN + WriteLn; + Write('Compiling file area editor strings ... '); + Found := TRUE; + Assign(StrPointerFile,'FAEPR.DAT'); + ReWrite(StrPointerFile); + Assign(RGStrFile,'FAETX.DAT'); + ReWrite(RGStrFile,1); + Assign(F,'FAELNG.TXT'); + Reset(F); + WHILE NOT EOF(F) AND (Found) DO + BEGIN + ReadLn(F,S); + IF (S <> '') AND (S[1] = '$') THEN + BEGIN + Delete(S,1,1); + S := AllCaps(S); + RGStrNum := -1; + IF (S = 'FILE_AREA_HEADER_TOGGLE_ONE') THEN + RGStrNum := 0 + ELSE IF (S = 'FILE_AREA_HEADER_TOGGLE_TWO') THEN + RGStrNum := 1 + ELSE IF (S = 'FILE_AREA_HEADER_NO_FILE_AREAS') THEN + RGStrNum := 2 + ELSE IF (S = 'FILE_AREA_EDITOR_PROMPT') THEN + RGStrNum := 3 + ELSE IF (S = 'FILE_AREA_EDITOR_HELP') THEN + RGStrNum := 4 + ELSE IF (S = 'NO_FILE_AREAS') THEN + RGStrNum := 5 + ELSE IF (S = 'FILE_CHANGE_DRIVE_START') THEN + RGStrNum := 6 + ELSE IF (S = 'FILE_CHANGE_DRIVE_END') THEN + RGStrNum := 7 + ELSE IF (S = 'FILE_CHANGE_DRIVE_DRIVE') THEN + RGStrNum := 8 + ELSE IF (S = 'FILE_CHANGE_INVALID_ORDER') THEN + RGStrNum := 9 + ELSE IF (S = 'FILE_CHANGE_INVALID_DRIVE') THEN + RGStrNum := 10 + ELSE IF (S = 'FILE_CHANGE_UPDATING_DRIVE') THEN + RGStrNum := 11 + ELSE IF (S = 'FILE_CHANGE_UPDATING_DRIVE_DONE') THEN + RGStrNum := 12 + ELSE IF (S = 'FILE_CHANGE_UPDATING_SYSOPLOG') THEN + RGStrNum := 13 + ELSE IF (S = 'FILE_DELETE_PROMPT') THEN + RGStrNum := 14 + ELSE IF (S = 'FILE_DELETE_DISPLAY_AREA') THEN + RGStrNum := 15 + ELSE IF (S = 'FILE_DELETE_VERIFY_DELETE') THEN + RGStrNum := 16 + ELSE IF (S = 'FILE_DELETE_NOTICE') THEN + RGStrNum := 17 + ELSE IF (S = 'FILE_DELETE_SYSOPLOG') THEN + RGStrNum := 18 + ELSE IF (S = 'FILE_DELETE_DATA_FILES') THEN + RGStrNum := 19 + ELSE IF (S = 'FILE_DELETE_REMOVE_DL_DIRECTORY') THEN + RGStrNum := 20 + ELSE IF (S = 'FILE_DELETE_REMOVE_UL_DIRECTORY') THEN + RGStrNum := 21 + ELSE IF (S = 'FILE_INSERT_MAX_FILE_AREAS') THEN + RGStrNum := 22 + ELSE IF (S = 'FILE_INSERT_PROMPT') THEN + RGStrNum := 23 + ELSE IF (S = 'FILE_INSERT_AFTER_ERROR_PROMPT') THEN + RGStrNum := 24 + ELSE IF (S = 'FILE_INSERT_CONFIRM_INSERT') THEN + RGStrNum := 25 + ELSE IF (S = 'FILE_INSERT_NOTICE') THEN + RGStrNum := 26 + ELSE IF (S = 'FILE_INSERT_SYSOPLOG') THEN + RGStrNum := 27 + ELSE IF (S = 'FILE_MODIFY_PROMPT') THEN + RGStrNum := 28 + ELSE IF (S = 'FILE_MODIFY_SYSOPLOG') THEN + RGStrNum := 29 + ELSE IF (S = 'FILE_POSITION_NO_AREAS') THEN + RGStrNum := 30 + ELSE IF (S = 'FILE_POSITION_PROMPT') THEN + RGStrNum := 31 + ELSE IF (S = 'FILE_POSITION_NUMBERING') THEN + RGStrNum := 32 + ELSE IF (S = 'FILE_POSITION_BEFORE_WHICH') THEN + RGStrNum := 33 + ELSE IF (S = 'FILE_POSITION_NOTICE') THEN + RGStrNum := 34 + ELSE IF (S = 'FILE_EDITING_AREA_HEADER') THEN + RGStrNum := 35 + ELSE IF (S = 'FILE_INSERTING_AREA_HEADER') THEN + RGStrNum := 36 + ELSE IF (S = 'FILE_EDITING_INSERTING_SCREEN') THEN + RGStrNum := 37 + ELSE IF (S = 'FILE_EDITING_INSERTING_PROMPT') THEN + RGStrNum := 38 + ELSE IF (S = 'FILE_AREA_NAME_CHANGE') THEN + RGStrNum := 39 + ELSE IF (S = 'FILE_FILE_NAME_CHANGE') THEN + RGStrNum := 40 + ELSE IF (S = 'FILE_DUPLICATE_FILE_NAME_ERROR') THEN + RGStrNum := 41 + ELSE IF (S = 'FILE_USE_DUPLICATE_FILE_NAME') THEN + RGStrNum := 42 + ELSE IF (S = 'FILE_OLD_DATA_FILES_PATH') THEN + RGStrNum := 43 + ELSE IF (S = 'FILE_NEW_DATA_FILES_PATH') THEN + RGStrNum := 44 + ELSE IF (S = 'FILE_RENAME_DATA_FILES') THEN + RGStrNum := 45 + ELSE IF (S = 'FILE_DL_PATH') THEN + RGStrNum := 46 + ELSE IF (S = 'FILE_SET_DL_PATH_TO_UL_PATH') THEN + RGStrNum := 47 + ELSE IF (S = 'FILE_UL_PATH') THEN + RGStrNum := 48 + ELSE IF (S = 'FILE_ACS') THEN + RGStrNum := 49 + ELSE IF (S = 'FILE_DL_ACCESS') THEN + RGStrNum := 50 + ELSE IF (S = 'FILE_UL_ACCESS') THEN + RGStrNum := 51 + ELSE IF (S = 'FILE_MAX_FILES') THEN + RGStrNum := 52 + ELSE IF (S = 'FILE_PASSWORD') THEN + RGStrNum := 53 + ELSE IF (S = 'FILE_ARCHIVE_TYPE') THEN + RGStrNum := 54 + ELSE IF (S = 'FILE_COMMENT_TYPE') THEN + RGStrNum := 55 + ELSE IF (S = 'FILE_TOGGLE_FLAGS') THEN + RGStrNum := 56 + ELSE IF (S = 'FILE_MOVE_DATA_FILES') THEN + RGStrNum := 57 + ELSE IF (S = 'FILE_TOGGLE_HELP') THEN + RGStrNum := 58 + ELSE IF (S = 'FILE_JUMP_TO') THEN + RGStrNum := 59 + ELSE IF (S = 'FILE_FIRST_VALID_RECORD') THEN + RGStrNum := 60 + ELSE IF (S = 'FILE_LAST_VALID_RECORD') THEN + RGStrNum := 61 + ELSE IF (S = 'FILE_INSERT_EDIT_HELP') THEN + RGStrNum := 62 + ELSE IF (S = 'FILE_INSERT_HELP') THEN + RGStrNum := 63 + ELSE IF (S = 'FILE_EDIT_HELP') THEN + RGStrNum := 64 + ELSE IF (S = 'CHECK_AREA_NAME_ERROR') THEN + RGStrNum := 65 + ELSE IF (S = 'CHECK_FILE_NAME_ERROR') THEN + RGStrNum := 66 + ELSE IF (S = 'CHECK_DL_PATH_ERROR') THEN + RGStrNum := 67 + ELSE IF (S = 'CHECK_UL_PATH_ERROR') THEN + RGStrNum := 68 + ELSE IF (S = 'CHECK_ARCHIVE_TYPE_ERROR') THEN + RGStrNum := 69 + ELSE IF (S = 'CHECK_COMMENT_TYPE_ERROR') THEN + RGStrNum := 70; + IF (RGStrNum = -1) THEN + BEGIN + WriteLn('Error!'); + WriteLn; + WriteLn('The following string definition is invalid:'); + WriteLn; + WriteLn(' '+S); + Found := FALSE; + END + ELSE + BEGIN + Done := FALSE; + WITH StrPointer DO + BEGIN + Pointer := (FileSize(RGStrFile) + 1); + TextSize := 0; + END; + Seek(RGStrFile,FileSize(RGStrFile)); + WHILE NOT EOF(F) AND (NOT Done) DO + BEGIN + ReadLn(F,S); + IF (S[1] = '$') THEN + Done := TRUE + ELSE + BEGIN + Inc(StrPointer.TextSize,(Length(S) + 1)); + BlockWrite(RGStrFile,S,(Length(S) + 1)); + END; + END; + Seek(StrPointerFile,RGStrNum); + Write(StrPointerFile,StrPointer); + END; + END; + END; + Close(F); + Close(RGStrFile); + Close(StrPointerFile); + IF (Found) THEN + WriteLn('Done!') + ELSE + BEGIN + Erase(StrPointerFile); + Erase(RGStrFile); + END; +END; + +BEGIN + CLrScr; + WriteLn('Renegade File Area Editor Compiler Version 1.0'); + Writeln('Copyright 2009 - The Renegade Developement Team'); + IF (NOT Exist('FAELNG.TXT')) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'FAELNG.TXT does not exist!'); + Exit; + END; + CompileFileAreaEditorStrings; +END. \ No newline at end of file diff --git a/SOURCE/UNUSED/FAELNG.TXT b/SOURCE/UNUSED/FAELNG.TXT new file mode 100644 index 0000000..12e3e96 --- /dev/null +++ b/SOURCE/UNUSED/FAELNG.TXT @@ -0,0 +1,312 @@ +$FILE_AREA_HEADER_TOGGLE_ONE +^0#####^4:^3File area name ^4:^3Flags ^4:^3ACS ^4:^3UL ACS ^4:^3DL ACS ^4:^3MaxF +^4=====:=========================:========:==========:==========:==========:===== +$ + +$FILE_AREA_HEADER_TOGGLE_TWO +^0#####^4:^3File area name ^4:^3FileName^4:^3Download path ^4:^3Upload path +^4=====:================:========:=======================:======================= +$ + +$FILE_AREA_HEADER_NO_FILE_AREAS +^7*** No file areas defined ***^1 +$ + +$FILE_AREA_EDITOR_PROMPT +%LFFile area editor [^5?^4=^5Help^4]: @ +$ + +$FILE_AREA_EDITOR_HELP +%LF^1<^3CR^1>Next screen or redisplay current screen +^1(^3?^1)Help/First file area +^1(^3C^1)hange file area storage drive +^1(^3D^1)elete file area ^1(^3I^1)nsert file area +^1(^3M^1)odify file area ^1(^3P^1)osition file area +^1(^3Q^1)uit ^1(^3T^1)oggle display format +$ + +$NO_FILE_AREAS +%LF^7No file areas exist!^1 +%PA +$ + +$FILE_CHANGE_DRIVE_START +%LFFile area to start at?@ +$ + +$FILE_CHANGE_DRIVE_END +%LFFile area to end at?@ +$ + +$FILE_CHANGE_DRIVE_DRIVE +%LFChange to which drive? (^5A^4-^5Z^4): @ +$ + +$FILE_CHANGE_INVALID_ORDER +%LF^7Invalid record number order!^1 +%PA +$ + +$FILE_CHANGE_INVALID_DRIVE +%LF^7Invalid drive!^1 +%PA +$ + +$FILE_CHANGE_UPDATING_DRIVE +%LFUpdating the drive for file area %FR to %LR ... @ +$ + +$FILE_CHANGE_UPDATING_DRIVE_DONE +Done! +$ + +$FILE_CHANGE_UPDATING_SYSOPLOG +* Changed file areas: ^5%FR^1-^5%LR^1 to ^5%DD:\ +$ + +$FILE_DELETE_PROMPT +%LFFile area to delete?@ +$ + +$FILE_DELETE_DISPLAY_AREA +%LFFile area: ^5%AN^1 +$ + +$FILE_DELETE_VERIFY_DELETE +%LFAre you sure you want to delete it? @ +$ + +$FILE_DELETE_NOTICE +%LF[> Deleting file area record ... +$ + +$FILE_DELETE_SYSOPLOG +* Deleted file area: ^5%AN +$ + +$FILE_DELETE_DATA_FILES +%LFDelete file area data files also? @ +$ + +$FILE_DELETE_REMOVE_DL_DIRECTORY +%LFRemove the download directory? @ +$ + +$FILE_DELETE_REMOVE_UL_DIRECTORY +%LFRemove the upload directory? @ +$ + +$FILE_INSERT_MAX_FILE_AREAS +^7No more then %MA file areas can exist!^1 +%PA +$ + +$FILE_INSERT_PROMPT +%LFFile area to insert before?@ +$ + +$FILE_INSERT_AFTER_ERROR_PROMPT +%LFContinue inserting file area? @ +$ + +$FILE_INSERT_CONFIRM_INSERT +%LFIs this what you want? @ +$ + +$FILE_INSERT_NOTICE +%LF[> Inserting file area record ... +$ + +$FILE_INSERT_SYSOPLOG +* Inserted file area: ^5%AN +$ + +$FILE_MODIFY_PROMPT +%LFFile area to modify?@ +$ + +$FILE_MODIFY_SYSOPLOG +* Modified file area: ^5%AN +$ + +$FILE_POSITION_NO_AREAS +%LF^7No file areas to position!^1 +%PA +$ + +$FILE_POSITION_PROMPT +%LFPosition which file area?@ +$ + +$FILE_POSITION_NUMBERING +%LFAccording to the current numbering system. +$ + +$FILE_POSITION_BEFORE_WHICH +%LFPosition before which file area?@ +$ + +$FILE_POSITION_NOTICE +%LF[> Positioning file area records ... +$ + +$FILE_EDITING_AREA_HEADER +^5Editing file area #%RE of %NA +$ + +$FILE_INSERTING_AREA_HEADER +^5Inserting file area #%RE of %NF +$ + +$FILE_EDITING_INSERTING_SCREEN +%LF^11. Area name : ^5%AN +^12. File name : ^5%FN ^7(%GD.*) +^13. DL path : ^5%DP +^14. UL path : ^5%UP +^15. ACS required: ^5%AR +^16. DL/UL ACS : ^5%DR^1 / ^5%UR +^17. Max files : ^5%MF +^18. Password : ^5%PW +^19. Arc/cmt type: ^5%AT^1 / ^5%CT +^1T. Flags : ^5%FS +$ + +$FILE_EDITING_INSERTING_PROMPT +%LFModify menu [^5?^4=^5Help^4]: @ +$ + +$FILE_AREA_NAME_CHANGE +%LFNew area name: @ +$ + +$FILE_FILE_NAME_CHANGE +%LFNew file name (^5Do not enter ^4"^5.EXT^4"): @ +$ + +$FILE_DUPLICATE_FILE_NAME_ERROR +%LF^7The file name is already in use!^1 +$ + +$FILE_USE_DUPLICATE_FILE_NAME +%LFUse this file name anyway? @ +$ + +$FILE_OLD_DATA_FILES_PATH +%LFOld DIR/EXT/SCN file names: "^5%OP.*^1" +$ + +$FILE_NEW_DATA_FILES_PATH +%LFNew DIR/EXT/SCN file names: "^5%NP.*^1" +$ + +$FILE_RENAME_DATA_FILES +%LFRename old data files? @ +$ + +$FILE_DL_PATH +%LF^1New download path (^5End with a ^1"^5\^1"):%LF^4:@ +$ + +$FILE_SET_DL_PATH_TO_UL_PATH +%LFSet the upload path to the download path? @ +$ + +$FILE_UL_PATH +%LF^1New upload path (^5End with a ^1"^5\^1"):%LF^4:@ +$ + +$FILE_ACS +%LFNew ACS: @ +$ + +$FILE_DL_ACCESS +%LFNew download ACS: @ +$ + +$FILE_UL_ACCESS +%LFNew upload ACS: @ +$ + +$FILE_MAX_FILES +%LFNew max files@ +$ + +$FILE_PASSWORD +%LFNew password: @ +$ + +$FILE_ARCHIVE_TYPE +%LFNew archive type (^50^4=^5None^4)@ +$ + +$FILE_COMMENT_TYPE +%LFNew comment type (^50^4=^5None^4)@ +$ + +$FILE_TOGGLE_FLAGS +%LFToggle which flag (%FT^4) [^5?^4=^5Help^4,^5^4=^5Quit^4]: @ +$ + +$FILE_MOVE_DATA_FILES +%LFMove old data files to new directory? @ +$ + +$FILE_TOGGLE_HELP +%LF^1(^3N^1)oRatio ^1(^3U^1)nhidden +^1(^3G^1)ifSpecs ^1(^3I^1)*.DIR file in DLPath +^1(^3C^1)D-ROM ^1(^3S^1)how uploader Name +^1(^3D^1)ate uploaded ^1du(^3P^1)e checking off +$ + +$FILE_JUMP_TO +%LFJump to entry?@ +$ + +$FILE_FIRST_VALID_RECORD +%LF^7You are at the first valid record!^1 +%PA +$ + +$FILE_LAST_VALID_RECORD +%LF^7You are at the last valid record!^1 +%PA +$ + +$FILE_INSERT_EDIT_HELP +%LF^1<^3CR^1>Redisplay current screen +^31^1-^39^1,^3T^1:Modify item +$ + +$FILE_INSERT_HELP +^1(^3Q^1)uit and save +$ + +$FILE_EDIT_HELP +^1(^3[^1)Back entry ^1(^3]^1)Forward entry +^1(^3F^1)irst entry in list ^1(^3J^1)ump to entry +^1(^3L^1)ast entry in list ^1(^3Q^1)uit and save +$ + +$CHECK_AREA_NAME_ERROR +%LF^7The area name is invalid!^1 +$ + +$CHECK_FILE_NAME_ERROR +%LF^7The file name is invalid!^1 +$ + +$CHECK_DL_PATH_ERROR +%LF^7The download path is invalid!^1 +$ + +$CHECK_UL_PATH_ERROR +%LF^7The upload path is invalid!^1 +$ + +$CHECK_ARCHIVE_TYPE_ERROR +%LF^7The archive type is invalid!^1 +$ + +$CHECK_COMMENT_TYPE_ERROR +%LF^7The comment type is invalid!^1 +$ \ No newline at end of file diff --git a/SOURCE/UNUSED/FAEPR.DAT b/SOURCE/UNUSED/FAEPR.DAT new file mode 100644 index 0000000000000000000000000000000000000000..c6dad9a6275c62b8246929d11026e15f7b2bc45c GIT binary patch literal 568 zcmXZYzb`{k6u|NGl-BR0^`k}AQ|;@cQK^JjIy6iy7ORC(42{J~LfS}-5`Tbn(#@a} zX$(!2*bTMV*a-&TlY57gPtMJ~_xx}~q)yxsRbtl>N#Y6mc#V@pt3$*k|G)_h21Lei z3bVM5dcTC@c!o>Zz#uj;kKd^8!kr?cn88`x#1tN&{(p`cys_u6sD1t60%p5RKN~nh zzK?ONU>a*SZ=u$Ex4Aask$afHHOyfN_1y*P9QWwr8){uAWcHBgHuZ`)%=s2B;wk!A zLl<9A_wr*+_n7{QxWf4%>Ks*E#x@S(Cq^;QD>8yHjNlv&VF5kdv6gX_{0X(*7e3%^ ppSk~xI^QqOquNext screen or redisplay current screen^1(^3?^1)Help/First file area&^1(^3C^1)hange file area storage drive3^1(^3D^1)elete file area ^1(^3I^1)nsert file area5^1(^3M^1)odify file area ^1(^3P^1)osition file area8^1(^3Q^1)uit ^1(^3T^1)oggle display format%LF^7No file areas exist!^1%PA%LFFile area to start at?@%LFFile area to end at?@*%LFChange to which drive? (^5A^4-^5Z^4): @#%LF^7Invalid record number order!^1%PA%LF^7Invalid drive!^1%PA4%LFUpdating the drive for file area %FR to %LR ... @Done!0* Changed file areas: ^5%FR^1-^5%LR^1 to ^5%DD:\%LFFile area to delete?@%LFFile area: ^5%AN^1(%LFAre you sure you want to delete it? @#%LF[> Deleting file area record ...* Deleted file area: ^5%AN&%LFDelete file area data files also? @#%LFRemove the download directory? @!%LFRemove the upload directory? @*^7No more then %MA file areas can exist!^1%PA%LFFile area to insert before?@"%LFContinue inserting file area? @%LFIs this what you want? @$%LF[> Inserting file area record ...* Inserted file area: ^5%AN%LFFile area to modify?@* Modified file area: ^5%AN!%LF^7No file areas to position!^1%PA%LFPosition which file area?@-%LFAccording to the current numbering system.$%LFPosition before which file area?@'%LF[> Positioning file area records ...^5Editing file area #%RE of %NA!^5Inserting file area #%RE of %NF%LF^11. Area name : ^5%AN$^12. File name : ^5%FN ^7(%GD.*)^13. DL path : ^5%DP^14. UL path : ^5%UP^15. ACS required: ^5%AR"^16. DL/UL ACS : ^5%DR^1 / ^5%UR^17. Max files : ^5%MF^18. Password : ^5%PW"^19. Arc/cmt type: ^5%AT^1 / ^5%CT^1T. Flags : ^5%FS"%LFModify menu [^5?^4=^5Help^4]: @%LFNew area name: @1%LFNew file name (^5Do not enter ^4"^5.EXT^4"): @'%LF^7The file name is already in use!^1%LFUse this file name anyway? @*%LFOld DIR/EXT/SCN file names: "^5%OP.*^1"*%LFNew DIR/EXT/SCN file names: "^5%NP.*^1"%LFRename old data files? @7%LF^1New download path (^5End with a ^1"^5\^1"):%LF^4:@.%LFSet the upload path to the download path? @5%LF^1New upload path (^5End with a ^1"^5\^1"):%LF^4:@ %LFNew ACS: @%LFNew download ACS: @%LFNew upload ACS: @%LFNew max files@%LFNew password: @%%LFNew archive type (^50^4=^5None^4)@%%LFNew comment type (^50^4=^5None^4)@B%LFToggle which flag (%FT^4) [^5?^4=^5Help^4,^5^4=^5Quit^4]: @*%LFMove old data files to new directory? @*%LF^1(^3N^1)oRatio ^1(^3U^1)nhidden4^1(^3G^1)ifSpecs ^1(^3I^1)*.DIR file in DLPath1^1(^3C^1)D-ROM ^1(^3S^1)how uploader Name0^1(^3D^1)ate uploaded ^1du(^3P^1)e checking off%LFJump to entry?@)%LF^7You are at the first valid record!^1%PA(%LF^7You are at the last valid record!^1%PA%%LF^1<^3CR^1>Redisplay current screen^31^1-^39^1,^3T^1:Modify item^1(^3Q^1)uit and save3^1(^3[^1)Back entry ^1(^3]^1)Forward entry2^1(^3F^1)irst entry in list ^1(^3J^1)ump to entry2^1(^3L^1)ast entry in list ^1(^3Q^1)uit and save %LF^7The area name is invalid!^1 %LF^7The file name is invalid!^1$%LF^7The download path is invalid!^1"%LF^7The upload path is invalid!^1#%LF^7The archive type is invalid!^1#%LF^7The comment type is invalid!^1 \ No newline at end of file diff --git a/SOURCE/UNUSED/FILE0.TPU b/SOURCE/UNUSED/FILE0.TPU new file mode 100644 index 0000000000000000000000000000000000000000..1735fe2799e674265cc6197067f04f338848f915 GIT binary patch literal 21504 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 NndAn49Q<7+{s$|L)9nBN literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/FILE1.TPU b/SOURCE/UNUSED/FILE1.TPU new file mode 100644 index 0000000000000000000000000000000000000000..775251bb8fddc2b10704da9bc57b55268d211796 GIT binary patch literal 46448 zcmce<31E~((l_4EH8Z(qLK1Emf`l6rKtMpblHm|SF3vzCBmu&a#K{b|VGxWVA&TMx zxBuCA`G?ykO` zXC@j+IO)U`a=#c-n)6$&8zT^O0!Ojszy=73bLVi_k0u zl4&yd)Fw4mo7R-HqY4-&+4CKFwuzEy2C|I~2`o-GkX~i7k}S(<;S-8-vylbGjxLym zelQ0akK8b$fh$V}@iia-V=3x7t-S`f#p-4w6L+nFwCBpJr=!7GL?Zi zw+W-l$Ap1bi+YXBbwpB*W1!nQ@PXNZUjT*pKlM+Vtka|jCET$PV4HU^keLqZg*;f zd=w0ou!6g^ahzfx^Ch7Cbn9yEPK`aTrt2g~Ixu#lc9$PlU&dD3c516N_`!73IOlvv za$#;BV_CEIX&X78DSb|%-7&6sHe>BePiZ@KA`Lg2vml4DU+-mXpT_>m5noVsN6ae( z`*8oru6M+B;aoB!Q}mI0Vc6?`UA0dYs^~tgKpm%@mG9J=I^w&a{U_2!4c!}mPQw}m zQZ*a(pI8GUhflo(v{2o9>aJF9bW;*_8$IIzj(i!($5Y1V4XGh|M(%Qvk5cq}-y)CM zc#R4)kA;-wVOnkN{2Q}T48mJb!0j&f`Eo2Ez&tAwqC-o3C zCnbp<2nP;a!44+m^hZtmdHy~Pu}l6 z8uPAB8be`PC6U4>pjtpzfXyk5L>gE)X2Pk#MfmjfvA9UStP&kIENQVLuOK%scbMIt zy(BK2r_pSOEWzk?NT&HUE|@1!&m9(=YRo9aI%|9py4_i!Xs6&*!?^6lWAh4Rx0{H1 zC*Oji9{@m_Y)i&ip_LoW07Mu+4>cu%UemTAeL~I$pA1wsoXHS&V`YPR+6|O7@C4G} zH7JV}5H+>T+$3rPYh=a{R3UFcQM$t}zt>3A2QUs$jCY{E%c*)DszbJ7f-eR5jEI3s z>sQh%J)}wJz(A!m(X|5&9DAgm(uB^&vH1mgFtU7@Q>nPQA*sql+j#jMPSFi>3Psn4 zGz2JsmZIgiFbvr?SYMCpotOqsii7+Daq0auJnT2DI`p;}KQGRT$v`(f#AqW53l=)! z+IVTLL*bFr^OxquwcxZg=++~Y{71n;nuFq^yyT%^9i5R^?1+u@X3qdCcen6Bv%)!< zT788eQzu53A_b@u&w~WMii5sHBi0R}sUhR%^Cb>(%UNzu%5z9b&RgUezVhpho|OHe zslmvDg+RuVqCELEoN*CsS8=AS~4|Dm!=Bh!OJVUgEZ})S!$x`NcB}v+cR^X)hfW3iDKG94*4- z&%9|LA`hvr(?9jn0IEvBTnNA65&kPnlP6%}t_D|3 zM4+|`Z$N#CDim#HdBc3d{GAyh{oQFDN)nB28e5nHH$0&T2ttxfj8lLYs}|qWa`rqO}gM*ZxS_)?iJ)YUgGcI_e>u&tmRyulm=1HqWrYHS?Ga0 zVTLy$(wrJjZXnNIj4c;WoaRj&ZcbGuj7^s_IfZPOX-+li+Yk8rsa|qtb86Tfc}sY& z9X1myU3rQ(ZLwK6Bzdxzb^t~irf+-YNnUEXnUpMcVo^*kexf(w33F=5BrNpBOeIh7 zrZ7vYar~@VWNZci@qO(R^(%%7%tC4FSAgOnwye6I}dYatcfR3XK+|jY309&RyCN*iJwX#t%yV` zV)T9@-=ykumS-lL#;N2xzq4R?I~R<{jtrH|HShpXNru25Rldgp{A?#CgD7QK|{ z#vftNA78>EVrD6vRK}7x-()tP$7e9?^zdh8!JIxo#D}tWoE|T53Om8$bNDBY(*$13 z^x{UbC{EeLoE&dq`UJd#CGz-gR={x!QBD_jE04Rd<)FWHtPwk~WQM&d{s_ka_maCv zJ%H1cKcun1^VI=zDR8;eLi!HaA{}Q@5O9v|;PqO}2C!VjZ^ z=BuLKgM)0N$0jB8N*R_8bFz2?ZCGzXXaEal;c8bRs)iuij*dXk7C_~DQ1q(_X#0*m zVdeI>v9^&cG<;GCa4y=rfc0V#Y8Z<)GOa7q+OuhD1XGn}Op8{P7W@+hX}79! z4@8=)EQof0Rmk}i%U~TfEeK?$g#{shdqoaH0|4VV0?S0Ev5qXtXp%cdF(gM1#YEUT z2nkweBYnE6z(a$;jKmH`WG(|Q9!HJlVVxaBNSg9WyFEv93 z)<$K~00VLvk!qwJPma`%&62{99LBVEOha=Rf@nA6kfNAV>dd-_gtH(PMa~+3t#rg% zn8HX5m|5E{7-0t5e^f~)*b`DW7NNC_VaA|n)=vesA4En4MYdvQLy!?$!{BCZEkmk}D;B3J z#u2Q!K@JHq8E9=!hg+K5n%%4!v8aqNhKI74n2;#eyr0pCy$vjCpf!01u*J%4Sws+P z7iNrY4J}L{1sS_W8Z=li8jWF~h3!b$%`)V>APHT&D>EvrFN;94c0n=JhU8+RSo>jY z60@Q?vHu+tEwgA$KQL7g3+_mrG!$JT0_iabvEcSdZfRuQz{i3^#-J$J0a^&Ji4BGSEV~ zR!)*k$}KFy5Ui@{5{a;5?JD6D_vFX*K`xreO+U-UK z%4yNW&B#U?NQmp>1x?Z%5e3eIK3O>0km}f%v%r8_QU{}%#e^A~8=Iq5NYo_sG}fj| z7={(o(#T${Qv?Pg3kjidNI7{~)L0s#?a)&-NbL^mhf^YrU2xpg(Tq52XMntB;0x6} z#O7K|t0>l@A4VG1l9BjSwP93fvgEf^aGs>GX%;4vSG53qncZ%^2$frYNXr38v!BDlLyzX`!rKOUAfC zgKNw}cEX>bBS$U5wb9IE2yQ|8saC6zS(=l8=16sYkFty`gpP+%kUlnk^M{S&w2z$=*BP_G%ccSds-bdi;AL>+BMTm;fD6jLs2w_iPm0Y&5T;Gf|?p= zY0}bAz}gt#3ALyw-F?YaUzr8zwfqXUZY2e?JK&6#Nuk(^h2iXkPD3Ja)MsYdax-?X z97P9SID?77i9-u)^;=^5+zRJEZCHrf7Hh|LtUzs#b7(7M-GU?9V7A84A2LVabTxz> zFeE{CD*M(D%B~sGaiW@mv&^|T=A4T|&iSm|xBz8Uv7PAu`;8WM#u&-27@uHKrmd{I zX&cTipG5gr*>qDha{$(v8rUw=HJsBmvQs8Ej?W~ieUK#e2aF3+q-=StR2-Bn-7Duv ze?!y#BPdV$RB_-8s}1`ea8|C8!h>U2C%~}a<~X@(&WeJ!NS{dWNe={vvn|2La0zo- zdJSej2{;chhMbYwhI}FQ3HefrRU|n*qy^4UTHv^*1=|{;$kidLoS}4(PldF^8A?mm z0H{<(%B@3N;XI=i8w$t(%nNPJRsc2to&)R;O_6bGApaJcCWnWm%R8l7IUy_z8~JzS zJHrmkj<6&017YvV+rr+HYr>AoABG*1e+YYDmcx(B?ZQvU{lY(x7Xj7+o(5C{j)s3I z*M-{@YlKbd4@d^gju@q^ju@?Mh!~?h8*ztnAY!a?I%1sidqlDlX&$e1Hm4}Gr^+;^ zDT~eNO1U{hdBQwFdBZ$WIboipd}p4lFv}FBm1U|Dq7KmpT83$l{&2pa>9a*Mzk6eSp{ZF-&$o6b@9PajCW$Znshm0VW6ogtI;9kCm7#H={ppMt|HRHwSJG8qST>mI$}P z>3S>R)`+)5dOL*MA$$ukL4S5qxs}Z|4gqZh;si;cjRb8R@@BB5#;I(kng#k?lZqxirI@5=3?Wi)L#Q;@ z7zv01!~oh#m*ftBSZTA`5xkuNT>xFBd1`lQraDC0jB&A9P6lrZ=;?q-i01(E5S|T~ zhqMCVRe%cVPi=#=M}7?Hj{$E1Z9CFm1Fn%qD{o4T$^j|dcmT5B2G4tdV@Nv=o{zwP zTFNq>0sd0Tk-q|*lNK1hfo|WT4&Nbf9rD&mOO<+Qu;C}j_*ELJT!sD(Ql)YYe2u8H zB=3wv3>ILEJX4L9cLLVRF~BkMCAlTi+Q`R^ZNb}4u2eh7 z^VC7eKT7^m9Rqv^k&8n)R@2XEJp@3%UTw^q#t(qezsEZAK)CGoH5Vj#a3gI#8Mdc3l8N)c>aq3Jp zRow|#E2jacsh8vo$eV!l$w;599yd+_Z7OJ);GGWn`G7)%9Vl}- zq^$*1YK_W+TDb8+@I8w77Hxsy32mnO9AF>dAm9+-2+Dj<+pHc1&k5u|3;ZMCCqSrS zo*HJDYqS{p+d|p5S{OTprA~ia1WT9~0c>V%@*@FJNQ(xJ1}z3@F~BW=TL8C2T1(_> z4NTAmd~FbK&mJ5;h`C&YSXj~^_R`M5ENb~+_C&YA?DOE;*wvET*x?qpfp$Bq>32JL zM}v1Xct?YG4CrH6VYe~t`QSUidk1*$0BtPW-ft|*Ol2L+>4;Bci~CPxT}Mu2W7iX& z#P*d|u&SSG}c_?=-Yiu>26($w210#!A_)a_9QC!Rls+??8 z)k2iDkj?JA5b?$A>#a+e`Mzbyy9{}kF=f{>mbh{m+uM3MD@|I7{43do4J*OB3VBzv z%%uB3yAO504|48fQ@Y)Uv^7X8M?ETGgG%UI2^sf;z7F&U*|y3DS>(uv*@tBhv+_+3 zgT4Xujet#vZ-Ty6Xp6_$<5(x%X57lAm2YQ72p>k99cDY{90A{Zh`-0$ zB)$he3Li!IC}f>LStnuR4`7cEkoEz}`v~QH0{NdZ+e2r7zXab`(B*5^Z|gbWbKw03 zyx#zS3;Zp3z5~=FtscBTF?I8K7WwoARyXGo>h=rLE(3l?AH0fsUj>$=D=vdHtvpCt zUK}JN?CG%5GyG-)~DU&|&SK0)f; zdjirXB0N!g@8*e8J)oc}QwrZXP1;dB9eJ~)Hu*Wy<=Jy2>pgRjHdp$3>pbaO%>lXt ze9MrwT-sK-3Q!^Ku39Ut-Cha4b;$dmg#IEW%&S6tE6Ug=CC6`r?%R;|By@aQsvEuo z`tOj!l6FY5Z972UDJi>lN+zsGM^(Lm@CyjPAg!%>39?_7?%e)QX{(K3k5m}6N4i?F zM>^bM4`f$Eb~R*IL+)P0_aeR*;a9=C5AY^nzjR^4e%Ne33XETX{x8r8z5<*B@At@C54k@BUq*X1f?tvo z=1KC-kp_AFNR#}fD+CaRuo;-ZBAet$q(>th186B%yV?NS$_>lf$^C5|yFCKmy{u6tdEjv(?nK;) zIE5D>yhy&%ZjoG2wL~uX`%-zxqb0Jkt3*y*St5_BS^>BReD}(C_P{=j!4X}M-UYO7pmhW8j=b>* z$Ag{#*$D_IAlw@=dL!Ns&>wuaLe@a#Tg`^}G{AJk3qdbZav!`)nO5#pipm!%`<^L5 zIVDP)#1iF->mH@rbuXY4;ZmhE=|1556wD#WTaLUH%H(xxL0hW~9l2JyTC!FdXI`sZ z*sxYv=zIV?4}#|*$X}1}2IcFm8=>1qgsVV*4D`pr`xJPe0__>lcB1T^D0?UPc7paC zXwL)hM&5sbw;JJBL3<54)quA~nUGim+M7zj-}fuA6}6z%B7dzCwY*k&rcW)>-UI(p z(2s(C6mpM(b{w=5z#pLj7F%_5OPjKub_BbxKh8J<}WE z-U#;wy$|3P_1$~=sq5zsP`hs)pguSER&`(5t!nMuK`Q0|^~<@pp{(1~t+v}x-Vn86 z?l3iG-f;Ehdu)(ngB%-VjzoAQ!XrT+1sDUqJAm&1?^xh*$U7e4RNz#^(}2@}Gt`D< z6QILnz!c~)1$ZiGnW)Ef=${4s?*yKq7W_S1Rd!{Ao~?eiE?dQV2>dgl_e|JeruyKB znc&L<-z?zS(0vY|0D9Tg&|Y@6Te$=Dg@C2tUkRJ7M7{1)BS+o`ydHQx=<7jWkGif0 z?Qh7tQT?;uM$k8cz7e!d(0h~m(#|TRRjF@ut5QGjR|WcG>Vc7usV^rzhVT<=HNd>` z352%+Z&TZ^*#US)owjBdXuD9>E`*;&_*sOXMfiEt=SA56MU?d->hdDuuc$E(yaJwA z!1Ib~c<>dq?*3}Ts}ZkO7dl@>UEcuD8=$=b+8c=P1K&R21HcD>49w7w(49TD!R4SBSa)_rp)t>4x-@W+8a4*YQ_yQ^k+u&dUsygO*| z&>gwU&<$)~=Qe*7lVR*1pw-ftIMf zv~wiN9jSejI1=?3jWWh);XB7^|GFm`@f6f6Rohm1r?$IlhPHNlHuRbadY(3_YL<3k z!(8OGLub3zZMhwEC+G_iUJ6*IO)FonEiWc;X{vg!c1kHlnH8X~)r!h1wO^JzsEu3t z5ad4!*rH8wJ)w7gpZ?MCs5}P0Ux3MpK2Yuy!v=q74-WqW?R{07ZEFB;gSORnO*?CA z)UMdv=o`$?Z8mCI>4(HyT6 z{uZ?F0QET2zW}(1@Fl=y!0$N2*Kme!!1+Bv5FkYABU^wilEZ{YO-zx%&A=0lbN;rV zx0m*rI)m07Y4La_I3DqMX`QLJw9C{7&==4T@qWMq00RMoq*JEB;2#YB!QdYZ+7R#z zLpTw41}T7az$CyF+#}2Yo+14sXg2N<<^UJqPT?-#yO6dJ;YHH-L5py&umpHHa3$b= zz{7wIfQ?eMya{*{(l<#{gSP>;2fz&XG-(#haD++F;D za6NE6@K3nUAUF@W0NO>|cl?a-&*1$9@m~-o{Ht_6_%h&k&B0+Bk+zjz(grgBA90ME!z83P_kTytbi+hufa(zfAxgn${ zpfBJSKtJ4{Opr4|C&@!Yr^qV+8vy%5vk=ZgI1BeCGZ3GFyOWuKTtFURHee3Y2<9U^ zA9pN8;4cEU1BwAo$Z#UfDbEXC1inQmYZ>q|$XkZ+a^Mo+dqKMweD}&dLhnPk0^tgT z*8=WG_sQ)@1Q>h`eP{bap>_l>hlEBp8(#5^d~{v zj`())?E>E}gr9|s=Ma7Yv=_kh4}@Pv_+^A&LHHHmy})}Rb1(AmMf_FZeSrP)bD;-7 zKY;K7+zEY*JED()KLIBA40lDRaZg0>1@4v30?r})E$)$i0R9R10^lOxXTT-gN&SjD zr^~o|`W^RDf8y?`0pV-lb>ogoQ5<1G%C@i&r6w#?*(rr931Jb+m@qT288{L+61W*4 z3J?v50W=4+P~`BIO1tn@$^&7o0d15Y!rCeQ!rLR<9x~g5r@ita;DInJcsoE=N0iqQ z@tZ&==nPsH#Jd1@gREYV(F@^t<<77K(0hZYH*jC%>jxbNK*vG2`Qx(;#W}a72F3lfYtzf4RklKtj>;5 z)N->1FaaV}W{Fn6GdEYQ5iQlTax3*fL@Ur*A+4>t*xVlU4oL5Scn9?fKr-T;IqrzG zPJjXGvk}S2mkc}}kP1jse~*|0{`tTK>Tt6idF;Rr^$qiKwUwm=daOj=mB9Bv_G;k! z0A&cT0WJq#2flT4+_AEYAI7m2C)bL*A#r_agAi(B~CEHNvj~?}PmPkbeN-gV3`Ua^C?QM))Y; z7{cEGegj;Fe3RD7V$!S;AzFqK10178nq#yR=2qJ2h*nxG?hRsA+V2s!;;wZv?p(70GXXhTUHClUd7u+6K)evR5OKnG#FrvW z;KKcD1@2<+$DQm0+Fr{e+HuRHxR>1u*rsi!7^> z+CIRWpdSE!3waMB{I*tRIfV2hpdCZ}eZ-HWybp2L`xW48-0l9L&5k^e@CDrYUcjC2 z1>E^wK>Q-&mjS;cT{bMm<4S$x2w(!U;c#RW?t?o3Vga4;I7Cn2o`%s<4%RfwSabP# zR;C)Hwh>0_29 zbx>PLUo(@GCYhv(Qn9o^YAx*m?3W9q1M*<`gw$3#B@LDdX2^%6Wq3Dqqg*NNm7h{^ zo(Whag~%bHc5R?+*CGLpl3n{0P!IUcRIGI|E!BpEE<<>^_M&`7J12jkHCMjWmV{l< zLP9Sh-$mrRhPNZO*2q?s7~GD|m+|D2FW9@0xU*ansXbrZ`DzZ8Xt+83Rs9AktdxcFY zbXx6sIeB;)G}kIwgJvIltSL>twq`@hHJzE0(o!l*j>qU`osv1| z1BX&KNE);ssIRoDCgmDi5rMM0Ae?-SEmG>*Nfo8J?urew+zNy>gRqrX-7A(GS2VxP z?Jkb20I>o@2}~9+)rTHJ$n8EOaFI-?%I%Fj@PYWPZuPG>8G{hP#c@kp7Vs-XxyuxVh z*e$C+i9`g9BrVVC6tDbKztW{c3}h#AR=YJjCnvAC*g8LNVcvXn!n|UhvnbELAm8Eb zl=%g-tLzMk+b^CSqTHO`j0Ls#;fG{Ir(_Q!Ro*>(hxYyVJ+kj z{L@(Qc5id>Ijka42NZyC7!_NJf8f;{or4H+3P8 zqy_eec9W{R2>G?Py{uYdDU~(VP=QNAZ5f7>sIcnjCKPdY;DO4TwE@cd@)$jNB*)FZ z3d8MrGTQ$l<1t2st-5E>rE_Val}8!dcvEl?53=~8R+V>3h7l>>Z^0Ii>)*B@(Qfk4o7y*oV?tDSqaTN zuk`cYs}H1zafJ(!&pWU>Wc8=#?|tJSJICS7os}m#IKP0tk)yy`g!ezJU9xUTD#*1i%11ccn$;I`!Zdt#9mq2d49iM@ z3Z!zcUcId0Sqbzyv?qFVRzixM24^M-K@nLA(`hW>T_+Uc%(G(ZKvF8m&V0u}tDG7} zBdS5;7FzjZgXTYTgo>G?7LCpL2k&~C>}bXLD{C6Ax4xc2uFNx1Jel(JaoAPl4R`ww zoq&;rq5PIyuQxGzsaE$-xxTZ=7Wr?pt(CbK)jOp#go<{JljJ&sTw9v#hI@$BH5OyO ziOWSl?!?CjJU)u4?kmP3Ee@;>laMCW_lF$ai~OaWs2j;~K`e7l7d2r4H4((vCgX?7 z(Y4lf(%Eh>Q}BekwUTb+*1Tr!g~56*Xf9k*U4yP%Of{5EsbIFZWJeqG;ybc*|iZ*j0$~k{p~A6;NTY1jK~_R2aa&sx>NEAh5#7 z%BNRS&yx+FwF#HU-=M0VrjxlwNs{cC5O-OVo#RFBO9Ay3#Ey_&S<@~+Nyzkwb=7oq zr#iz(BD$D~#)ojT5U<6#@}z4tdk3=tm|*`0v!-{t>qSFzjAsEm#yc`Ey}dB>*}*t$ z+8w&{!T6tOZAZRM?{FoT$PO3%7ZT{zO5If~elNN)us&pZ4^isg^@jHAnJa7;Jrfca z#y_|*RvlD#hw0v%ubv&@zBGu>4T#;wWA23)D@qJ24;fg@BpQx1RfEv)a+1;H(73fK zNm(wR2016yx73Yavd7;!aN5BVQ(Ud4uUUBszG~LRx_uh>LOk0xyalGO;e(m@k|N

JWDZ!t+6#8vNcGs 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 AllCaps(User.Name)) THEN + BEGIN + Print('Uploader name does not match user name!'); + Print('Cannot add/remove credit from user.'); + Exit; + END; + IF (NOT General.FileCreditRatio) THEN + GotPts := 0 + ELSE IF (GotPts = 0) THEN + BEGIN + FilePointsReceived := 0; + IF (General.FileCreditCompBaseSize <> 0) THEN + FilePointsReceived := ((F.Blocks DIV 8) DIV General.FileCreditCompBaseSize); + GotPts := (FilePointsReceived * General.FileCreditComp); + IF (GotPts < 1) THEN + GotPts := 1; + END; + Print(AOnOff(Credit,'^5Awarding upload','^5Removing upload')+ + ' credits: 1 file, '+ConvertKB(F.Blocks DIV 8,FALSE)+', '+IntToStr(GotPts)+' credits.'); + IF (Credit) THEN + BEGIN + IF (User.Uploads < 2147483647) THEN + Inc(User.Uploads); + IF ((User.UK + (F.Blocks DIV 8)) < 2147483647) THEN + Inc(User.UK,(F.Blocks DIV 8)) + ELSE + User.UK := 2147483647; + IF ((User.Credit + GotPts) < 2147483647) THEN + Inc(User.Credit,GotPts) + ELSE + User.UK := 2147483647; + END + ELSE + BEGIN + IF (User.Uploads > 0) THEN + Dec(User.Uploads); + IF ((User.UK - (F.Blocks DIV 8)) > 0) THEN + Dec(User.UK,(F.Blocks DIV 8)) + ELSE + User.UK := 0; + IF ((User.Credit - GotPts) > 0) THEN + Dec(User.Credit,GotPts) + ELSE + User.Credit := 0; + END; + SaveURec(User,F.OwnerNum); +END; + +PROCEDURE EditFile(DirFileRecNum: Integer; VAR Cmd: Char; NoPrompt,IsPoints: Boolean; VAR BackUp: Boolean); +VAR + FF: FILE; + ExtText: Text; + User: UserRecordType; + F: FileInfoRecordType; + V: VerbRec; + Mheader: MheaderRec; + InputStr, + MoveFromDir, + MoveToDir: AStr; + LineNum, + NumExtDesc: Byte; + UNum, + NewFileArea, + SaveFileArea, + Totload: Integer; + FSize: Longint; + SaveConfSystem, + DontShowList, + Done, + Ok, + NoSpace: Boolean; + + PROCEDURE ToggleFIFlag(FIFlagT: FileInfoFlagType; VAR FIFlagS: FIFlagSet); + BEGIN + IF (FIFlagT IN FIFlagS) THEN + Exclude(FIFlagS,FIFlagT) + ELSE + Include(FIFlagS,FIFlagT); + END; + + PROCEDURE ToggleFIFlags(C: Char; VAR FIFlagS: FIFlagSet); + BEGIN + CASE C OF + 'V' : ToggleFIFlag(FiNotVal,FIFlagS); + 'T' : ToggleFIFlag(FiIsRequest,FIFlagS); + 'R' : ToggleFIFlag(FIResumeLater,FIFlagS); + 'H' : ToggleFIFlag(FIHatched,FIFlagS); + END; + END; + +BEGIN + Seek(DirFile,DirFileRecNum); + Read(DirFile,F); + IF (IOResult <> 0) THEN + Exit; + IF (F.OwnerNum > (MaxUsers - 1)) THEN + F.OwnerNum := 1; + LoadURec(User,F.OwnerNum); + IF (IsPoints) THEN + BEGIN + NL; + FileInfo(F,TRUE); + NL; + Prt('Credits for file (0-999) ([Enter]=Skip,Q=Quit): '); + Input(InputStr,3); + NL; + IF (InputStr = '') OR (InputStr = 'Q') THEN + BEGIN + Print('Aborted.'); + Abort := TRUE + END + ELSE IF (StrToInt(InputStr) >= 0) AND (StrToInt(InputStr) <= 999) THEN + BEGIN + F.FilePoints := StrToInt(InputStr); + Exclude(F.FIFlagS,FINotVal); + Seek(DirFile,DirFileRecNum); + Write(DirFile,F); + CreditFile(User,F,TRUE,F.FilePoints); + NL; + Prt('Credits for ^5'+Caps(F.OwnerName)+'^4 (-999 to 999): '); + Input(InputStr,4); + IF (InputStr <> '') AND (StrToInt(InputStr) >= -999) AND (StrToInt(InputStr) <= 999) THEN + BEGIN + IF (F.OwnerNum = UserNum) THEN + AdjustBalance(-StrToInt(InputStr)) + ELSE IF (StrToInt(InputStr) > 0) THEN + Inc(User.Debit,StrToInt(InputStr)) + ELSE + Dec(User.Credit,StrToInt(InputStr)); + SaveURec(User,F.OwnerNum); + END; + END; + NL; + Exit; + END; + IF (NoPrompt) THEN + BEGIN + Exclude(F.FIFlagS,FINotVal); + Seek(DirFile,DirFileRecNum); + Write(DirFile,F); + CreditFile(User,F,TRUE,0); + Exit; + END; + DontShowList := FALSE; + REPEAT + Abort := FALSE; + Next := FALSE; + IF (NOT DontShowList) THEN + BEGIN + NL; + FileInfo(F,TRUE); + Abort := FALSE; + END + ELSE + DontShowList := FALSE; + NL; + Abort := FALSE; + IF (Next) THEN + Cmd := 'N' + ELSE + BEGIN + Prt('Edit files (^5?^4=^5Help^4): '); + OneK(Cmd,'Q1234567DEGHIMNPRTUVW?'^M,TRUE,TRUE); + IF (NOT (Cmd IN ['H','I','M','N','P','R','T','U',^M])) THEN + NL; + END; + CASE Cmd OF + '1' : BEGIN + Prt('New file name: '); + MPL((SizeOf(F.FileName) - 1)); + Input(InputStr,(SizeOf(F.FileName) - 1)); + IF (InputStr = '') THEN + BEGIN + NL; + Print('Aborted.'); + END + ELSE + BEGIN + IF (SQOutSp(InputStr) = SQOutSp(F.FileName)) THEN + BEGIN + NL; + Print('You must specify a different file name.'); + END + ELSE + BEGIN + Ok := TRUE; + IF (Exist(MemFileArea.DLPath+InputStr) OR Exist(MemFileArea.ULPath+InputStr)) THEN + BEGIN + NL; + Print('That file name exists in the download or upload path.'); + Ok := FALSE; + END; + IF (Ok) THEN + IF (NOT Exist(MemFileArea.DLPath+F.FileName)) OR (NOT Exist(MemFileArea.ULPath+F.FileName)) THEN + BEGIN + NL; + Print('That file name does not exist in the download or upload path.'); + Ok := FALSE; + IF (CoSysOp) THEN + BEGIN + IF (NOT (FIIsRequest IN F.FIFlagS)) THEN + BEGIN + NL; + IF (PYNQ('Do you want to set this file to Offline? ',0,FALSE)) THEN + BEGIN + F.Blocks := 0; + F.SizeMod := 0; + Include(F.FIFlagS,FIIsRequest); + END; + END; + NL; + IF (PYNQ('Do you want to rename the file anyway? ', 0,FALSE)) THEN + Ok := TRUE; + END; + END; + IF (Ok) THEN + BEGIN + IF (Exist(MemFileArea.DLPath+F.FileName)) THEN + BEGIN + Assign(FF,MemFileArea.DLPath+F.FileName); + ReName(FF,MemFileArea.DLPath+InputStr); + END + ELSE IF (Exist(MemFileArea.ULPath+F.FileName)) THEN + BEGIN + Assign(FF,MemFileArea.ULPath+F.FileName); + ReName(FF,MemFileArea.ULPath+InputStr); + END; + LastError := IOResult; + F.FileName := Align(InputStr); + END; + END; + END; + END; + '2' : BEGIN + Print('Limit on file size restricted to 1.9 Gig.'); + OK := TRUE; + IF (NOT Exist(MemFileArea.DLPath+F.FileName)) OR (NOT Exist(MemFileArea.ULPath+F.FileName)) THEN + BEGIN + NL; + IF (PYNQ('File does not exist, set to Offline? ',0,FALSE)) THEN + BEGIN + FSize := 0; + Include(F.FIFlags,FiIsRequest); + OK := FALSE; + END; + END; + IF (Ok) THEN + BEGIN + NL; + IF PYNQ('Update with actual file size? ', 0,FALSE) THEN + BEGIN + FSize := 0; + IF (Exist(MemFileArea.DLPath+F.FileName)) THEN + FSize := GetFileSize(MemFileArea.DLPath+SQOutSp(F.FileName)) + ELSE IF (Exist(MemFileArea.ULPath+F.FileName)) THEN + FSize := GetFileSize(MemFileArea.ULPath+SqOutSp(F.FileName)); + END + ELSE + BEGIN + FSize := ((F.Blocks * 128) + F.SizeMod); + NL; + InputLongIntWOC('/New file size in bytes',FSize,0,2147483647); + END; + END; + IF (FSize >= 0) AND (FSize <= 2147483647) THEN + BEGIN + F.Blocks := (FSize DIV 128); + F.SizeMod := (FSize MOD 128); + END; + END; + '3' : BEGIN + Print('New description: '); + Prt(': '); + MPL((SizeOf(F.Description) - 1)); + InputMain(F.Description,(SizeOf(F.Description) - 1),[InteractiveEdit]); + END; + '4' : BEGIN + LoadURec(User,F.OwnerNum); + IF (AllCaps(F.OwnerName) <> AllCaps(User.Name)) THEN + BEGIN + Print('Previous owner was '+Caps(F.OwnerName)+' #'+IntToStr(F.OwnerNum)); + NL; + LoadURec(User,1); + F.OwnerNum := 1; + F.OwnerName := AllCaps(User.Name); + END; + Print('New owner user number or name ('+Caps(F.OwnerName)+' #'+IntToStr(F.OwnerNum)+'): '); + Prt(': '); + MPL((SizeOf(F.OwnerName) - 1)); + FindUser(UNum); + IF (UNum <= 0) THEN + BEGIN + NL; + Print('User not found.'); + END + ELSE + BEGIN + LoadURec(User,UNum); + F.OwnerNum := UNum; + F.OwnerName := AllCaps(User.Name); + END; + END; + '5' : BEGIN + Prt('New upload file date ('+PD2Date(F.Date)+'): '); + InputFormatted(InputStr,'##/##/####',TRUE); + IF (InputStr = '') THEN + BEGIN + NL; + Print('Aborted.'); + END + ELSE + BEGIN + IF (DayNum(InputStr) = 0) OR (DayNum(InputStr) > DayNum(DateStr)) THEN + BEGIN + NL; + Print('Invalid date entered.'); + END + ELSE + BEGIN + F.Date := Date2PD(InputStr); + F.DateN := DayNum(PD2Date(F.Date)); + END; + END; + END; + '6' : InputLongIntWOC('/New number of downloads',F.DownLoaded,0,2147483647); + '7' : InputIntegerWOC('/New amount of credits',F.FilePoints,0,999); + 'D' : IF PYNQ('Are you sure? ',0,FALSE) THEN + BEGIN + Deleteff(F,DirFileRecNum); + Dec(LastDIRRecNum); + InputStr := 'Removed "'+SQOutSp(F.FileName)+'" from '+MemFileArea.AreaName; + IF (Exist(MemFileArea.DLPath+F.FileName) OR Exist(MemFileArea.ULPath+F.FileName)) THEN + BEGIN + NL; + IF PYNQ('Erase file also? ',0,FALSE) THEN + BEGIN + Kill(MemFileArea.DLPath+F.FileName); + Kill(MemFileArea.ULPath+F.FileName); + InputStr := InputStr+' [FILE DELETED]' + END; + END; + IF (NOT (FINotVal IN F.FIFlagS)) THEN + BEGIN + NL; + IF PYNQ('Remove from ^5'+Caps(User.Name)+' #'+IntToStr(F.OwnerNum)+'^7''s ratio? ',0,FALSE) THEN + BEGIN + NL; + CreditFile(User,F,FALSE,F.FilePoints); + END; + END; + SysOpLog(InputStr); + Cmd := 'N'; + END; + 'E' : BEGIN + OK := TRUE; + IF (F.VPointer <> -1) THEN + BEGIN + IF (NOT PYNQ('Delete the extended description for this file? ',0,FALSE)) THEN + LoadVerbArray(F,V,NumExtDesc) + ELSE + BEGIN + F.VPointer := -1; + F.VTextSize := 0; + OK := FALSE; + END; + END + ELSE + BEGIN + IF (NOT PYNQ('Create an extended description for this file? ',0,FALSE)) THEN + BEGIN + F.VPointer := -1; + F.VTextSize := 0; + OK := FALSE + END + ELSE + BEGIN + FillChar(V,SizeOf(V),0); + NumExtDesc := 1; + END; + END; + IF (Ok) THEN + BEGIN + Assign(ExtText,TempDir+MemFileArea.FileName+'.TMP'); + ReWrite(ExtText); + LineNum := 0; + REPEAT + Inc(LineNum); + IF (V[LineNum] <> '') THEN + WriteLn(ExtText,V[LineNum]); + UNTIL (LineNum = NumExtDesc); + Close(ExtText); + MHeader.Status := []; + InResponseTo := ''; + IF (InputMessage(TRUE,FALSE,FALSE,'Extended Description', + MHeader,TempDir+MemFileArea.FileName+'.TMP')) then + IF Exist(TempDir+MemFileArea.FileName+'.TMP') THEN + BEGIN + FillChar(V,SizeOf(V),0); + Assign(ExtText,TempDir+MemFileArea.FileName+'.TMP'); + Reset(ExtText); + NumExtDesc := 0; + REPEAT + ReadLn(ExtText,InputStr); + IF (InputStr <> '') THEN + BEGIN + Inc(NumExtDesc); + V[NumExtDesc] := InputStr; + END; + UNTIL (NumExtDesc = MaxExtDesc) OR EOF(ExtText); + Close(ExtText); + IF (V[1] <> '') THEN + SaveVerbArray(F,V,NumExtDesc); + END; + Kill(TempDir+MemFileArea.FileName+'.TMP'); + END; + Cmd := #0; + END; + 'G' : IF (NOT General.FileDiz) THEN + Print('This option is not active in the System Configuration.') + ELSE + BEGIN + IF (Exist(MemFileArea.ULPath+F.FileName)) THEN + InputStr := MemFileArea.ULPath+SQOutSp(F.FileName) + ELSE + InputStr := MemFileArea.DLPath+SQOutSp(F.FileName); + IF (NOT DizExists(InputStr)) THEN + Print('File has no internal description.') + ELSE + BEGIN + GetDiz(F,V,NumExtDesc); + IF (V[1] <> '') THEN + SaveVerbArray(F,V,NumExtDesc) + ELSE + BEGIN + F.VPointer := -1; + F.VTextSize := 0; + END; + END; + END; + 'H' : ToggleFIFlags('H',F.FIFlagS); + 'I' : IF (NOT ValidIntArcType(F.FileName)) THEN + BEGIN + NL; + Print('Not a valid archive type or not supported.') + END + ELSE + BEGIN + OK := FALSE; + IF Exist(MemFileArea.DLPath+F.FileName) THEN + BEGIN + LFI(MemFileArea.DLPath+SQOutSp(F.FileName)); + OK := TRUE; + END + ELSE IF Exist(MemFileArea.ULPath+F.FileName) THEN + BEGIN + LFI(MemFileArea.ULPath+SQOutSp(F.FileName)); + OK := TRUE; + END; + IF (NOT Ok) THEN + BEGIN + NL; + IF (PYNQ('File does not exist, set to offline? ',0,FALSE)) THEN + BEGIN + F.Blocks := 0; + F.SizeMod := 0; + ToggleFIFlags('T',F.FIFlagS); + END; + END; + Abort := FALSE; + END; + 'M' : BEGIN + SaveConfSystem := ConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + InputStr := ''; + Done := FALSE; + REPEAT + IF (InputStr <> '?') THEN + NL; + Prt('Move file to which file area (1-'+IntToStr(NumFileAreas)+') [?=List,Q=Quit]: '); + MPL(Length(IntToStr(NumFileAreas))); + Input(InputStr,Length(IntToStr(NumFileAreas))); + NewFileArea := AFBase(StrToInt(InputStr)); + IF (InputStr = '') THEN + BEGIN + NL; + Print('Aborted.'); + Done := TRUE; + END + ELSE IF (InputStr = 'Q') THEN + Done := TRUE + ELSE IF (InputStr = '?') THEN + BEGIN + FileAreaList(FALSE); + Abort := FALSE; + END + ELSE IF (NewFileArea < 1) OR (NewFileArea > NumFileAreas) THEN + BEGIN + NL; + Print('The range must be from 1 to '+IntToStr(NumFileAreas)+'.'); + END + ELSE IF (NewFileArea = FileArea) THEN + BEGIN + NL; + Print('This file can not be moved to the same file area.'); + END + ELSE + BEGIN + SaveFileArea := FileArea; + IF (FileArea <> NewFileArea) THEN + ChangeFileArea(NewFileArea); + IF (FileArea = NewFileArea) THEN + BEGIN + Done := TRUE; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + IF Exist(MemFileArea.DLPath+F.FileName) THEN + InputStr := MemFileArea.DLPath+F.FileName + ELSE + InputStr := MemFileArea.ULPath+F.FileName; + MoveFromDir := BSlash(MemFileArea.DLPath,FALSE); + LoadFileArea(NewFileArea); + NL; + Print('^5Moving file to: ^3'+MemFileArea.AreaName+'^5'); + MoveToDir := BSlash(MemFileArea.ULPath,FALSE); + Ok := TRUE; + IF Exist(MemFileArea.ULPath+F.FileName) THEN + BEGIN + NL; + Print('There is already a file by that name there.'); + NL; + IF (NOT PYNQ('Overwrite it? ',0,FALSE)) THEN + BEGIN + FileArea := SaveFileArea; + InitFileArea(FileArea); + Exit; + END; + END; + IF (MoveFromDir = MoveToDir) THEN + BEGIN + NL; + Print('^7No move: directory paths are the same.'); + Ok := TRUE; + END + ELSE IF (NOT Exist(InputStr)) THEN + BEGIN + NL; + Print('File does not actually exist.'); + END + ELSE + BEGIN + NL; + Prompt('^5Progress: '); + MoveFile(Ok,NoSpace,TRUE,InputStr,MemFileArea.ULPath+F.FileName); + IF (Ok) THEN + NL; + IF (NOT Ok) THEN + BEGIN + Prompt('^7Move Failed'); + IF (NOT NoSpace) THEN + NL + ELSE + Prompt(' - Insuffient space on drive '+Chr(ExtractDriveNumber(MemFileArea.ULPath) + 64)+':'); + Print('!'); + END; + END; + IF ((Ok)) OR (NOT Exist(InputStr)) THEN + BEGIN + Prompt('^5Moving file records ... '); + FileArea := SaveFileArea; + InitFileArea(FileArea); + IF (BadDownloadPath) THEN + Exit; + IF (F.VPointer <> -1) THEN + LoadVerbArray(F,V,NumExtDesc); + Deleteff(F,DirFileRecNum); + FileArea := NewFileArea; + InitFileArea(FileArea); + IF (BadDownloadPath) THEN + Exit; + IF (F.VPointer <> - 1) THEN + SaveVerbArray(F,V,NumExtDesc); + Seek(DirFile,FileSize(DirFile)); + Write(DirFile,F); + FileArea := SaveFileArea; + InitFileArea(FileArea); + IF (BadDownloadPath) THEN + Exit; + SysOpLog('Moved '+SQOutSp(F.FileName)+' from Dir#'+IntToStr(FileArea)+' to Dir#'+IntToStr(NewFileArea)); + Print('^5Done.'); + Dec(LastDIRRecNum); + Cmd := 'N'; + END; + END; + END; + UNTIL ((Done) OR (HangUp)); + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + END; + 'P' : BackUp := TRUE; + 'Q' : Abort := TRUE; + 'R' : ToggleFIFlags('R',F.FIFlagS); + 'T' : ToggleFIFlags('T',F.FIFlagS); + 'U' : IF (NOT CoSysOp) THEN + BEGIN + NL; + Print('You do not have the required access level for this option.') + END + ELSE + BEGIN + IF (F.OwnerNum < 1) OR (F.OwnerNum > (MaxUsers - 1)) THEN + BEGIN + LoadURec(User,1); + F.OwnerNum := 1; + F.OwnerName := AllCaps(User.Name); + END; + UserEditor(F.OwnerNum); + END; + 'V' : BEGIN + ToggleFIFlags('V',F.FIFlagS); + CreditFile(User,F,(NOT (FINotVal IN F.FIFlagS)),0) + END; + 'W' : BEGIN + Print('^8WARNING: ^5User may not have received credit for upload!'); + NL; + IF PYNQ('Withdraw credit? ',0,FALSE) THEN + BEGIN + NL; + CreditFile(User,F,FALSE,F.FilePoints); + END; + END; + '?' : BEGIN + Print('^31-7^1:Modify item'); + LCmds(18,3,'Move file','Delete file'); + LCmds(18,3,'Extended edit','Hatched toggle'); + LCmds(18,3,'Previous file','Next file'); + LCmds(18,3,'Resume toggle','Toggle availability'); + LCmds(18,3,'Validation toggle','Withdraw credit'); + LCmds(18,3,'Internal listing','Get Description'); + LCmds(18,3,'Uploader','Quit'); + DontShowList := TRUE; + END; + ^M : Cmd := 'N'; + ELSE + Next := TRUE; + END; + IF NOT (Cmd IN ['P','N','Q']) THEN + BEGIN + Seek(DirFile,DirFileRecNum); + Write(DirFile,F); + END; + UNTIL (Cmd IN ['P','Q','N']) OR (Abort) OR (Next) OR (HangUp); +END; + +PROCEDURE EditFiles; +VAR + F: FileInfoRecordType; + FN: Str12; + Cmd: Char; + DirFileRecNum: Integer; + BackUp: Boolean; +BEGIN + NL; + Print('File editor:'); + GetFileName(FN); + IF (FN = '') OR (Pos('.',FN) = 0) THEN + BEGIN + NL; + Print('Aborted.'); + END + ELSE + BEGIN + RecNo(F,FN,DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + IF (DirFileRecNum = -1) THEN + BEGIN + NL; + Print('No matching files.'); + END + ELSE + BEGIN + Abort := FALSE; + Next := FALSE; + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + EditFile(DirFileRecNum,Cmd,FALSE,FALSE,BackUp); + IF (Cmd = 'Q') THEN + Abort := TRUE + ELSE + BEGIN + IF (Cmd = 'P') THEN + LRecNo(F,FN,DirFileRecNum) + ELSE + NRecNo(F,FN,DirFileRecNum); + END; + WKey; + END; + END; + Close(DirFile); + Close(VerbF); + LastCommandOvr := TRUE; + END; + LastError := IOResult; +END; + +PROCEDURE ValidateFiles; +VAR + Cmd: Char; + FArea, + SaveFileArea: Integer; + SaveConfSystem: Boolean; + + PROCEDURE ValFiles(FArea: Integer; Cmd1: Char; NoPrompt,IsPoints: BOOLEAN); + VAR + F: FileInfoRecordType; + DirFileRecNum: Integer; + BackUp, + ShownAlready: Boolean; + BEGIN + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + BEGIN + RecNo(F,'*.*',DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + ShownAlready := FALSE; + WHILE (DirFileRecNum <> -1) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(DirFile,DirFileRecNum); + Read(DirFile,F); + BackUp := FALSE; + IF (FINotVal IN F.FIFlagS) AND (NOT (FIResumeLater IN F.FIFlagS)) THEN + BEGIN + IF (NOT ShownAlready) THEN + BEGIN + NL; + Print('^1Unvalidated files present in ^5'+MemFileArea.AreaName+'^5 #'+IntToStr(FileArea)); + ShownAlready := TRUE; + END; + EditFile(DirFileRecNum,Cmd1,NoPrompt,IsPoints,BackUp); + END; + IF (BackUp) THEN + BEGIN + REPEAT + LRecNo(F,'*.*',DirFileRecNum); + UNTIL (DirFileRecNum = -1) OR ((FINotVal IN F.FIFlags) AND NOT (FIResumeLater IN F.FIFlags)); + END + ELSE + NRecNo(F,'*.*',DirFileRecNum); + WKey; + END; + Close(DirFile); + Close(VerbF); + END; + LastError := IOResult; + END; + +BEGIN + NL; + Print('^4[^5M^4]anual, [^5A^4]utomatic, [^5P^4]oint entry, [^5Q^4]uit'); + NL; + Prt('File validation: '); + OneK(Cmd,'QMAP',TRUE,TRUE); + IF (Cmd <> 'Q') THEN + BEGIN + SaveFileArea := FileArea; + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + TempPause := (Cmd <> 'A'); + Abort := FALSE; + Next := FALSE; + NL; + IF (NOT InWFCMenu) AND (NOT PYNQ('Search all file areas? ',0,TRUE)) THEN + ValFiles(FileArea,Cmd,(Cmd = 'A'),(Cmd = 'P')) + ELSE + BEGIN + FArea := 1; + WHILE (FArea <= NumFileAreas) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + ValFiles(FArea,Cmd,(Cmd = 'A'),(Cmd = 'P')); + WKey; + IF (Next) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + END; + Inc(FArea); + END; + END; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + FileArea := SaveFileArea; + LoadFileArea(FileArea); + END; + LastError := IOResult; +END; + +END. diff --git a/SOURCE/UNUSED/FILE10.TPU b/SOURCE/UNUSED/FILE10.TPU new file mode 100644 index 0000000000000000000000000000000000000000..655b79a83f9e6cf3d41807f28a1e9c5a6685216b GIT binary patch literal 29008 zcmdVDd3;n=(l>tYy}e~$2qA2tSwz;5AUjcDAPWj13yX$yB#;Jzki?{$ozR&;2*eDE z4j_Uo3L~O|iV|@Q$Rdb>3NAd13xlA>paKJE5Xt+kx~Dto1bpWA`@H|W%v9H@Z`G+& zr_OTET_!U&d0dLXzjI=e*k!q7>EfgRXTQ%$pVK~*1Hzi8MF}y%<0)QL1x+Pp%C zeU=cuhbT1sH_bFWZ`Q25Tp?Wx%L9ZVnO8?O$bwfL2n4Z z2GKt_R57K*Lp5BnvonMX>T0vrW!bDjKm00l^m-^)FZux=r%h^?N*Nr6rytLBsEq? zMrY;BM6I)56sSq6h)_BCWAg72BK^=(brKs{#^%hj$2)VU2yu1kI<-I*XO%R|=$yhS z;|lEsLM*;dh^4By{dD4Z5i-WtMi!?0H4<5gE30V_nE z_(4lC$IW$&wa;~^u3Lnz270$a&w!eAlOS3J_Zm{nqo>=mvh4+`<#$4ZTZbxj)J$%^ z(~;&VP^aD?_^KAFBpXuvM(548$0ICsMLksO*6h_%d`L4kkMIs2d@9_J%E`5(yJ~wz z!_kXyLy9jD1USN8I7PL36gw$EvW;YjQnLnaCfVmu+J+U_v(z>o&1FN1e_9rzajRN+ zREG^I#&|Z5@L*pXQheZ=;X*asgZmj%%wzK$GxM^t)i4h_$e7~8&e=<-2TwJ^b6U=P zyBf$?DnfJ_Qv%6$cwX*QeVbAPSV<$+*_aYQ%CYuY`N>(%Lc8kk(YqwiP zH)m8%p+oiasGc&WsAC>ceLcV;L#qGSylK;B+T%yY&&-;pSh`^NyEoctR53U%R8hOr z)&`Y$z|@zRNHOcR#&+<>b}87Z9!=|PVU(&(H>L(OYzI44G#YxUNkcSC>l=E-^sL^H zG8|20p)6;yY?zuLlp_-@&1UR;4}tXcmy|Wju3o95y})eZ_1BDYHY%&oA(sqWocCCq zFs0CfQNLw`nz~?Ww7k@_tdq;Dc_V-N5>&tT*z`4H35`*|Vt@wDB;GJP%qI~eqU6Tv z>S(i({gU(RCS$S@@9B8MqgrQfGC^utN$r%HQ!ThO&@4u-2Z%k2FD_c%*DLa`a>A*G z%0D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 NKF=_I%=a7R{{Ud+Ug7`% literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/FILE11.TPU b/SOURCE/UNUSED/FILE11.TPU new file mode 100644 index 0000000000000000000000000000000000000000..5c94845a310581382b8123ff6267dbde9cdfc9c3 GIT binary patch literal 35776 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


*m1f`GSLG}m_R zl(t(qdz(GO&hm*scIkbkus zQ;zOGluoF1{A-2P0=Xx0%IzK|)f(oKpkd_g9%=0Y@$%tVkG}3w$^{hX|HGxMDN3)- zEWekd)I11@?g?t-9Xm6+T5XTP6S~JSHfjayFs7p3Q~nx1b=uaJuV;CUwWXnfhCDQ+ zQax5--q*-F>#F94RQ`j9!u;FSd2WUIx9GlLpTt`Tt=}9~U5x7If$lG!br;*US$BID z7t`Z~l{GuNMK!6Cnv{*J;%2Q2`}3zcxK-1<)vAmC>F$ZOuqUb}udk!hsVm*T(w*JC zPW4v~(w3#t^5@~eskSXxYhowIr7O5HYxV2@&=mju#;igcRSd_j0W0*Ek z)!UM_s=2cJ--mVI_HkrUQ#@BqKI_++-0M^jg*;?(J6AVlm?g@Fh`oFrb*+UAyvWwn z|MAX2`!m#RS80yxcDJKz=4e)I3l`CO&6{1R3YXO$r3 zyu_&4WL(0$g{&Nh7spj;ouSFe!u-p$2>ht6DCizv)TEAR7ix3NmmLmxZq6)mK;Z z>lkXlQA>^r;!!_n%m1BOTZ%3`xy~t)mkviq@>tOb?@;{C@*;ReYIRso{ovgL3O~kK zLY)sAsfd-`$#tfvhqyBjJVWa%p7b?ETKg^^Qz{(r`aqtw0 z(((&v(6WHK=R3gQ4$L}pv=KhXeC{93HSp31+tv$oI1oX)Ud+1T%|M4#+rrh6)?5tz zV$1)9(`HJsH-D8)ELz2 zY=n82;~#Fjt?GXBFH)7cqH-JgvBv)0ta+~fSrg^H?_7D-F;_YoxG*2Jj=A#eKb$Lv zSCMYbTuIgYe{impdzxIQ%LX;mB`vS?dO?U3(xisT=TLsCrxzzMh5o1MwYg)05Q)
7T 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 E3%vb{OaK4? literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/FILE12.TPU b/SOURCE/UNUSED/FILE12.TPU new file mode 100644 index 0000000000000000000000000000000000000000..3a5e89610e262b3a38b46cebe9762f982adbdff5 GIT binary patch literal 35120 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/FILE13.TPU b/SOURCE/UNUSED/FILE13.TPU new file mode 100644 index 0000000000000000000000000000000000000000..bd1c3796ee70827c5f191d889d0c6649e03302fa GIT binary patch literal 4016 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/FILE14.TPU b/SOURCE/UNUSED/FILE14.TPU new file mode 100644 index 0000000000000000000000000000000000000000..5bc6b496d06a95b55fef91141fb67b3d607c7474 GIT binary patch literal 7728 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/FILE2.TPU b/SOURCE/UNUSED/FILE2.TPU new file mode 100644 index 0000000000000000000000000000000000000000..3eb261fc958904c1c712f12fb0a52460e30ddfed GIT binary patch literal 4048 zcmc&%drVu`9sc=T``Xx)Kno<~Rfi;m(2>|3grpD>0`aJ5h#ydBX&u~P9>HLCu{|gY zrRzlVa+R(Rbty%tLwj^IMOnni6gjDu<&SKCOnppKGJ}+D+F079TG6^pUDE_Kd&7vXc2nyFptlZLc^Ka|c$=cGLSAvS6t>XEolr;g!S zO@}z#}XsBoLVgY(rp*pf{igQFwhe~_pkGEYss1dr_L?+y98h|Cvw zW%%!rD}!BK!ET}(h9=!Sm)xn9!Jhs-!HA#7>r5s@ehgi{M=#PVx-ZB;{K@8}44ruF z;tP*9_TQ z)zRA%@b!B_O0IW-9~j>e3`UQ#zt-2~Z%q~MTuoyxQdC{>SI@Bt;VqUWdrbIgdcF&~0Y9dj8RO0dhpW@dQY5&D8Q zFqc#pbTIFt@|n&hSB90U4uzeKC+fb$Tozu2;_vOnj@Y!Yd|RKP8)q(KZMe(r_qDJo zp_XI0PUcFj3x<4wgz1zp@v5e=E8eauU&zl+F3L+J7u#FI-WCGyVS$9i!QLLG^3M_ zF&90hcf;R96~=mc8sihG9=1lrdolLW3~Qqgu=5Y342*1Q(Jv+aNG^RoumK~Vs^543 zxCNtxe*0D#(1Gza`0T-WlrF#CMBQ&ZK|L?|;M++%P6TMnn*q$fj=6%l0t^Gg=*4RE z;(qkWir%e3FLTk;wdmh^^mIKi4}Hyp-$vLAfQ7IZ0yo2MgUyDy9ezdNMZjY4t-wv?}0k@M>TUd~1;Z5u8yie4RK$C(g_Xn~Q%TFn7V`2D;(r zfsY5g9$1g_<>OJ<8sXar`(udn!nO~!He-!utlf+2x24jj-{01mYT&2Y4R4^ZMOAZJ0?~upU5VByu}ixE4(Ew z`0>=y?F)4TyR9usN5pS!4F>{iymsS${P^qWZj-x$5rD~CvRhGtiZ#ueUmGm+@UQR2 zhpf4Bt~C_2=Ca&17H>(b58wY51gBW@AKtuI*zr@e!{1`yza?6j*KW49!UuugVzbw- z278P3m~N^+{Kx5*btib~&wkXh?%4Y;{QTIJ&!aK#!Y?A}6J=uxn;d)VMcc=pj=yl_ z;_%yX-NoUFI8Bl>8ao@$ZkQe;rwASzlqqE4aoG);kV#=zG&VDn-Ed(rRaVsmH)&kB zevjz6aug6U@)hXX3Xv=;8haBfoFht8W7V`Vc!W}h29aHwt7f7mk^jPAB5Bwp^2`;m z#B#STKdsY>zIAmiYF?*CMPnziyl}ah+Kqkl9SQji>Frm8hhhfl{7d+^TUkjRR% zrxLqS7seB&g{i5y{k&5>!=u9>@9B^sX2iJ2cJj5N1M*#wLE3eBi2Cm~OiT&tf-Z zRiwG43!)qMOzPAWS{~kMZMt|`;>s)=689%#D27`cHYZ<9ew{^(YLn)^ONmY&hv~Ko zqOp-H$s#yvKjO&5rp9k^hvgP7))0@IDR0)1tR-&BO-+Q&tTF|pV><=R z$GgXMve#4X_d1 z2ITpQnOfIF8kRGwSpRXx>r26JKDE9crtU8c{u<&>0LOqo0rK@e)bKjDV;}Px>LsiL zo(dcS<^acltAQrqS0%pAy;Kg)`%nq&1J(*X2Y+a&yiroue-gMAaS`-+ zLg)K>2iykx&qSV8^dUIUe;Ib(=UJgw(_b|Gy5QSLuUGw2^t`SL%G7v{-ePOUtLkcS zUf)__cTv8^3pFeedNY-2yh6hop|_D!Dz{w4G% znGI@vOANd(L$prg8wG!!iZs5>p!TU8oYzq)?8m8E<9jr05c=!%gvNaub_)Ib)T8k* K^6@@BZTL4p0Dr8_J+vncBeAF2; zwy&P|-1D60oO|v)XWZ8Y_ihjP+(a9yO`qAJ|C}<%&7Yc?mWViG0?$%_7YxDoW<;cV z#Harec@LxAeV9YxiN=?@wbPg23Uvl6fbY-V#ahQ%3H64|gZNes;Jx4MHL4bo za$wR8)Ek(;5andVza;5@c;+ueZMP(@-jFAIvI z41~mE>`o>}Ba8kWyv1+ey4Z;+QP2MD!fNw5L@nt!Oa4W2qn1p3X34^j%sjkpEx7n>24V2xKChW89$0ue6 zoF}p=IhY>EMfbVYs5@uJzh<{5_Vwu5ww~(>VinYt z#43qZBJIQ`+Evt5)Ya70tYHgfD{Uz?T-V~W0Vig@<-+H0c@PYHDL&TSfFq;3d8S6< zO+2HYvIn)_Zo&0at=My-jhr@~tqm8(JBS}3eu$h9~#wzz~1krw9&VZ zdLR8#@2Bqo@n%1TmN z%hkUyq3(nB)~^bCfwi^VURGANd*rVZ@0f2$?uk3^m~R5rE?dMFJ8Dyyw$0m5iAz9U zQ*_cB%WC2>wMqG-lg+f%QoU@KBj#<3(7wjGrCgOjd6vdE&So`nxAMzwj!ws z9OP!PKJ)gl!R7{KUMN$!QS54 zX+OZ#U3r@8FS6?KIE2)H0qkBpV#vdt5%QWyur^0B)`hjgxA6D zs3W{l+nbg42DT&1E!kec;iqmQZ=8A`^;6Ubk?a^SfnLS4$d4q&8&vVHHxJW3MqX6; zSK>8opJKd?_&DP~;BVf$8h=mmGVyb5U!wmQ^IuWoBmg(1)PL35fBuPam8-arm*S=VYK*)h!h*J@sc<~^%uscpO&Zl{M=x^h`ZOXpZ64dr#>S4z9DEz}D{trXVRWR&F}wC4P<-qN8?rPmF;py#Pi#Xo_Ub^MTy|E}T&}j)S_-;jm5X<%Zqi<~}P7Id}Yi<5}a+e*ger B<5vIx literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/FILE4.TPU b/SOURCE/UNUSED/FILE4.TPU new file mode 100644 index 0000000000000000000000000000000000000000..ca723cd2a8cb10edca31adfc463aceffc2c9733f GIT binary patch literal 6928 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 A$p8QV literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/FILE5.TPU b/SOURCE/UNUSED/FILE5.TPU new file mode 100644 index 0000000000000000000000000000000000000000..4a18e3496401af9bbd9a2c685cfe5cd92fad0764 GIT binary patch literal 25728 zcmeHw30Rg@+W&dZ^KPuNL$0rw$RH4Eh!QRcyl#jr3TmPtye5b*1n=uoMldR)7;0JS zn6{W>rkT!UYBrH&V#`cf+04|mxrex<<*2Ce{m$|(EY9@5{@?Xo-~YP)OgHzrfA@Xv zbD#U1=bZB_IFr&RXAu0HBzYv!P;Gcq{_jDz61Q@DLEnOqC|DDOIvA%u8Yt}9+K|K6NM`|>y)Ki+t7_bcOl$_G? zLYm#oTE9V?h$kCg{IK6{piHF&E4^HB2&PbQbGM3 zat}3wRt%tJH|z#cYKA7c)MBQk94d!n7C>5Q(!4@yabUyM41HQ@R#|?5na*>d8K^wY zW|>P%91yEq3}_&o>%h#azy{G`2W9|fDz#Y(X^{haRL$_5RGx3Cm~AefR5Z^_3%QDQ zc8i*+P0uf{Fe`=-qE|eSCD*yF@Xn6Xk-nN(O$wj$==W>`IiouBP()i=nH(Yds1(!N z4mnVhq0FVt4tbxN>5*+NuP7?DjJ3=zRSZV7y0~4dh=C0N|M>_NaOtI#mzS1LsCY;* zgrmZrTq>~9P)HEkrlQstB1{9Xl4hG1YQPjA+~UuOCX3E!WiqRG2E9*aBcd2$;MNV} z-f8cnbv<>*wR-r^P+^V!pOPN@wHbzNmu&?t z;V>KST5X1AQdZF;bdCdh6+I}T4{@1gaSr5SI@=+?4NsY7YpQv^xr7#Sm<{xGn9ZUE zTxOH|93q%Fm(FqkIt2|DFXIXIAs?eZG9EX3uLgu(ZDqLZmX~X{ z280=S9pj({qXISkrO(4BhBb zYr3_9UT}a}`V4&%E_|!GoSt`}m3l;u0XNgL9AlH<2rNw{`41sk^bAK?j=s|K0X*#h z%z8F#m-&#Ks_FW3fPbYXh`e9b3uLk)h|fko&`eyT)scee@W9V;@w}YJ+={2z?|OOvV!p7G$lP z)?LM5+`W=Zozbj{y+WYjH>9f@n)Praf!^E$3nHXfga=WLq)Rsv2&aJt->?*qK58I( zqGi2tcMsMh{qEE~nAnIGCLX@TFCduALNOp}sCS^AL|ck@lk$rnj3R zkm%S!qZ_WOvDA-XoCCF5;uqoVq4m%kecd%|eJP}KiIx7A^w(e(8a!~o(P}jrB)li- z8Q`X}^G;s_F=*k?3wg%mBwEZJ4I&K)d>E@A2{Zw338qGtzJsG)H4B*{x4(mY-YH!j*4JA=(A2M9M7u#`PVphY* zqiR30N)5+x<~L-Y8bLn7oIZmA3e-g5=yD&4)x?k#%>Xi4GX{r&bSx0*&qxHJWPWP{gTQ6>DJg zBy67nUkBO@{Q=OMWbG?&p`CX??*jh_bPV_x;9r8i2AzU@7W_xF-30rKkT0Tq3H~pk z{1eJo!LNZ|huuw33&>4b`--;`vDgRXi*g_+7}QOfUfWA4t2F}ejdG~6xFQtgdqH7} zWpflLMlq}#plsVd5ZEAP%;s1{-5Co$9QBicrGQK*j{~KG(%~lyJ|_X6jB+-7W}`d> zG!6dp;BOZE6+kY8pV{y?TiN^kT$IZ|^Ffu$JFlz&e?oa;^BQH(<|maWwmqdReQK>T zV&gja*aY2ksQ(gZ8)!S^ouFOHXB&3G-!3I+^)A@$RL0gKNmmxi2EDtn$&`fs|dl&!r2enqi7`!nor z!{!cn3wSFyp<^~HAWAKpRr<~=29(_>a!vyl2hyj)0%_%%Ae4jXr6ED|M9(1D^@dF- zcpvb4!TW-Tf%>5wj=Do(ACJ26s2h)Z@$}=K@zAG0KOQ_4d;-;M%AotVWzrEFbLirV zDfCp$RC-oB15`+ps~3VE0WGFaEU%<{pMMUZG3qZ6K31)Ei{Sp|6&@F%I?=qJISqVJ7%i9oTMukK z${S(75q;Q7Zw=lGA6wyLE3mE5ZKFQb+o7Qx{4Mae!QV!mcTj#0<@adW+9PQ52--Y?`bTJ4 z?T2XdEBODG)@=F~zP^L6?}0J;fg0!u&`I?FB=UL+e$LPXAfM_p$n9C$f74m`ISZd> zk-M|dou}VdHPLO`F95%Y{9d6qR$rwrt-A`FtFXC>{9c8x8yKsb;LY^ZmRsPr!S8@8 zs%8^aEt|FKn9Vwn9%X}C_@tXUz1CALtMyWotGj^w)Ca2rfCZ?FD+1JQ+k=611$9$5 z(FpRrra!5}n!7_Y1QbtZX%fJPfkvP_lJrp%!IQ{7nhx99;B#PKL^fgD`dpm{vVclS zvHmge8rZKT1#~0H*F8%%X*L1h0(={}rQHjkZ$f?xHitn+Kn=he$anMu*nUW6YX1TL z73`Zp7hro4bQSb70jh|Ai_Xh=nf34K0-A8BAI!!*^L}!5)LN27A(<1O<$n)s;8Vht4sAogH z`JgKL2XzIVt9goUP}f6#9<&Ae9iZ1huY(Sv&9}kdf$bssy#77dG(i3k@<%BDh0fA^ zMqAXcsJH$rl)s@rsb`=+N3YWJpeEG63cFjNJ0LgpbJY{%rOwiXsC_kqa2B{9`#Pgo z?Cpa|iY5+w{Se?o!G{8m2ag9&03QZE415GQqmi&nM4d!niKw3ljPX(6qkt#jd@u>; zgUL86%a;=w5^T8qO@cf$avi8|6KqKZ5=QdL6VE^akqg106t}H$iWq{1)&(qkIVb z5ZXS3m<|I!41NT>0lWeHDCh%}{|f#oa&!#*3(%LKe*pg;{3P&G;Ae3jy8wO>{AbV& zlyAdEqa33;kOAZg@=^?{7q~a53&=<5sq+Q-q3j3l4<4Y*(FQ0cP!4F0HV}A_vPc^Y z9iy%&cZI$y^sL-XxvuRAyth)Ty%+ZP!oIKatTqg~Fz|5jaM*{#J{&d?z#>p55)`ZS zP=})K1E67`M9?V2I0`%olnhFNKNDy)%A>)@fR9BxW8rfwe6sR5;N#IwDs+q{qC64$ ziO{ohI@-zvJ{j##f&CQNPemNlpqmCh9eg_Mr^9|aY;u9+qRvdvY{Xa$DgjxbV^o0{ z7eIa#J|BZz4PFiYThJ2FQs{mMjL`~EE#y_8r$B2#Pb-gtR)MyFKH~B-z}JB`D3dk6 z2j7T#o0YeiDKK|3Jt0^bE}7i|9s`E|s)7jf+c-v@ag_LqE z>J@*`b*yu>oDQLU2<3M{?|}}3j({2zy{-XuK7xX~<`kSnV0)@eJ~K2J%_x&O&z%_&MO`AfJQW2wfw}=ap#PCD3K~ybSp= z@XOF&2KE!mSJ3ti@MiEkpjO!F=`qU4K+kF2>8o0Al)HfY(Cb=Xl>NZ{Ap4{2kFr0? z0rXKdkQzYev_ZgwfCb?pR0!>%_JG_AJQQ><^pTJw!J}X^0Of(;gW%_Wlw-kTArD4* zFv^2bj)U(Z@I4fD;(^Bli-+$7ipNm!nM{XcFPN-JgH1XpgGQ;D^o*JXo<;G@9DFit zv%zynR{2u5q$_=2u0RIg1 zIp_<>U&8k9xS#qO^bP2H&<~&!pp%I49OyFQyo&p>Tew$i0jX-9&O_ay^Hx9Bby3HH z@<6L~e(Iw-e^3DMAn+jQf}msN5a_$A!<6}?o3fA$Qy#%ha}}rtv=3xZw3=bc0=kH9 zql>X3RpUyjq02SDqlcB{kgw9cs;X|I-P8=PrNqN?8HvXp(V{FPe&FGT7&GBjlE{@RW9p&6+h~$Ebes^NCD^&n1|_OK1z`m>>98;MWXGX}F;V^gGZh z&_>W!(00&%&=JsCI>PfJa({?)RU(wGO0JTsELAL;T4j>Dk^V#3N-0Jw6lahb%F}pH zc0@U@992q`Kw6>(JIIDaOuICDUU{T@Hn7j*QfsYM}8YOAT`z>DPi?3R_4I`zijhGlQuBugq= z+-zsL!BNv~g&Z|CE9Cu3Ls-=?#TKB;fob*8?B<}H122$t?vN>KwK1n3Ftt=JfXkJp z7WD?qjaDxgm2Il4z?!bBZ@v?hgWoMdIne2HTIb(J-TtQA!Y_Bu<7?*eRUduhrc1Lh z9l64EyVca(xVUx2h1`#HWK^cvVty#U(A=-WSi~MiTk=bcc!6Uy&$E@}TT9EMjm9in zSy^eh)m&&SzzfiPOJRjEzuasrDVkRVFq$PQnee8UTuA1;uJX@8Iq%>BVh$JE{bDUs z(r?lnv$4Xm$eO>g}-%~)Y8H;*uCCQVIGQ8QE0)a0?5^u8Q5B02)oGMYw5(4=H-(ip&MQu1`)v6lJy zB}IkCvV7|t3*MbX(+SDi3FDy-PK2*ng+;7CrR9r^rRB!itW6(dehJ>16fQEF7Zz1m zE24c93ku8?=zWE;&}=C}a%pC=Hgf`eMDTR+ciqNOms3s~PU+%6=atR}s3xUmdE2v6SdLfX z(VFbBDLGxU7FpP+7gfX?Lm9y9v6O{svQpBL^_eM2DPyx!Jovz{*HH0B65={3jW+)J z9`h#NsAi{R>XD$VvC~rg(#&QyJDq_?cS$Sd?kmLT_EtjG(0HRkV39^c^4P5Lrp%O- z9&G|O%4`~gc&h^(mbUhZnjlu2%xHjAam@{lo9pENNIVN6n!vM2R3 zMj7oF6|NKhDFD)BnJ-?W+9!Fmw@Vg`#?VM(!o-q7BVJpuZwI1SHijD$(##7Ska?li zY+-L=hlh@EG_atkq(pkh{4Fn?$0r0{WILLkU0Oab-)gj$3JtEa^5{`hF}+JIC5wy} zB#h}qe;09^K~W`UD+V32QnqNnKrIMI_>1N*L(&o_q(p}#IXh>wRM_|wo^30M)=o}K z%uK@XX=Bs-cb1hxa}+N5vT{s$HrwRoA8insi8lrr6X0MBrowRJgY4x?R(eWOR_;(X zx$T*?E-J&qk#8~10%lp{z-6}=%qc3EW1N#;0lnEW5aTer=pkI!Y^tN%jy%pU$~THH zNsQKAD^B$9>0NvchpXZZ$)%; zbm(0>mzXy7-*@hwQTdJ)+Ofp&g@~=t&w21wxcb6#9t}F|Y5W&932b4O8$|3+e53Mf zvtzKWiy_X%+#2XGbAq;zy83C@;hYF>t#Nnv&WtB;@H*_dmEn*z1jyj3x34!7t5@|= zho;Hsz-@YN+vMH0ZsUYbTkvG{8kUvbP#PmUGq9?SUz4_;42Nuf?GdX7^TXp}JWl*z%o7Ka!3#^%Q+~!1he^YTwKrl8*oE>QHA@XKBfB45&?C#hCTG z#`tdBYujP74e2aS?pD+bY~L`~HD2uMQjgCKg`^))Wkk;LMn+%kn9)!~BF8lt{@Y9> z?!T!R?r;3(^wm{XwKsA?8*a& g`_va-H(Y^$+%*G>|Hz{k^unu2Dfq2{4x+N5a# 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/FILE6.TPU b/SOURCE/UNUSED/FILE6.TPU new file mode 100644 index 0000000000000000000000000000000000000000..5730496f109d7e1a5955910871e0daf74f4aa31d GIT binary patch literal 38384 zcmchA2|!iV_V+&L+=&Y!DB_UARdb$jHqq47tCl5`NG2pIDyED&X%TTzDi3gUr*D_$jp%8`>l2MvZ`zkoF7k-3QGwc$lCrnO^9jDmpK=|G54E=`2>+Yb`2wkx` zVEZRhac2R@|H5j7#Z5^}jgu)z>z2@U@v3S)ND1@rKRGTo$uOQQ^9_RWySEslZ?pl4 zx)3e?)mf$965&>(ueu7+$~s7G%3W$5I3sQ>;t7$y;|aAh%edna^}T&l)IlCeM=t?3A(kB4qmm$At9Xv*Z|#}dcI2@x~? z6Lq~RmZ{;k@QH~@$&cz2glLp~PTgu)M#N8vbEYJW72?`FAwE&Xy-rG=D`+n_2HgGc zn%Jt+q~wOXh2T%10hBPRz=AUVakDGfAW{6Yh*er92K)_BsEu0pSnQOzCWp&tmC%fW z*b){u_OX;H>V6i6VX{H!MYhhwl!S5WK9>_G?g$H*kdC8@p2rH`0HZBp7%4K5eQnnUejamgu33H>pL)gG*9 zjVONRP#;QwYVMa57przFS1mJ#R+Bl&snMleH^Ut28%_e z=qCqjV66rvf+^umV#-b-45=u%dqksIO5=RW5>|cq)N!%Nap713dUE_&?8<`?e{6;L z6s$_JQ=qPxEUidNcAO>5yZ^+*sl&#HPmLXm%SH%dy?IM4O2}d~{Cy}n*XB0iLYY)v zmN2_BenLu8TzCrgUKE1-QY8rOJEv`{Y$I%Yu%<)p5ph$dVo+$&h_XX4rbPpV_kf|e zEV(tM6*LwI!;_QLm=Y3Fy?y=9p+C7~DSxD1q3QXP8 zsYbc9t&OH5Edte_g*0DkuqkJz`jt!HuwhrE9g(f8m&>zkq19PlVV(JwYb~M?u5=m* zSykh8o-!pOk@gDgo^(qh_d9pSMJ%L@E#i5v;a*P}uC^fwQ&YH|#btC&m}~M^9`y3e zo0}|^v8tEXV_d7%qKaB~P1jjSH7!6Oci$A2OD*DauA5VLI~AAF?G!l`RB*acE+ykK z{39-e5C61@<;;7C{(MK%S9l?Y5Q9Yo^AK^0^?qVDbGl8Te-8dBL`z&d=wFa{2|xXm zgN#}$Ic#xEt)o5&Nw)A4Gr?`@Rgnk&s)!ON!QZz!%s+ysHQZ7+8ueWJ9v+3<+o-VOyxIjSIzFbx;nzRJ?Sglw;Lv-gxd@sqlBA@I>P3;50D19 zp)d(~Z-EX-9@D9pmvhL_f!*4N^b1F3;;cs3V+X?AF9JjxlU>~JYp*Zr)Tn2&sdk&N zc+q9{0d!+8Ttt1X!W@7eF$Xl#?9f&-(SDSG&Px;>MN^Bg)Z+hYqEX(pYubd}F1#&G zy)@_wc8u2`d0hmHrowI#4Qq<( zqP{`m=H1R)xT~}dK?>FY z#70+JEe@|CB=N7|^cS`21%yLtwR%|tYyzp;F$|c}=rfDi(!4%e9auw{s#ixp)au!_ zySY2IOkcB4BeccOWLJ@axt6Rb5R=8+yB-D*DT)YmYvb}1OkM4wbq($qxCDFq`qV)L zFHy%N?5a0nB1* zt}E3ccZf{Qj$8RAxRGxPn+I?k9t^u-bn7YVn!<4Z8;)D*2r=3;T+B2@ishyexM3ZM zo5d%@H>OeIx+xmBd@-Vv`APAJd9;W%$BG%|F=Cl{ta#l#P8>AH;WlZ!@Ul$6jn_oc z*%B{?SSE>amZ!vQ%Ve?Gl7PFQ1l*LoD5_as6b-EFMQ7`4VhYG*y?{;jf;eQoD*m(< z;_~^MXluJB`q_RLBW%}k<^4ls*=~qcwm-!iwj!~|b`!S;#b{$aP4lX+HS%hp9aJ9C z9`t%t8}9X(_LSE!ZGl&a_Pkf9c3t_qR^YW!``l}j_JY+eUa&fZBdfVMpV?9b%xWnL zo3%u_6{roU9jLvqXAyM}JL5ZuT{#^@0{HpN&Z2l`7x?xT32Xa^!E5`14-kvi4iq*1 z?i921q2i<#Eq+8F^@&dqU&K!p)h8y2M<*qTj0{~Y>#vIz6O)0Hfm47}MDK~Iz^TB~ zfv1bGi8Fv_0H*<`iQzf3#jyG5Vtd9MP?k8G;SvKf=Yg^jKU@5nF<;DGJ|Fqbhkg+# z4>F>~;!o#d;3c4?z)QiG!+!;Q^Fb>S`)`Q73T=2!B&=SIII9t7wdnKQ8kE?&s0A7tyZQgk#cMptr@9_^qIAV)n!x$ax23yFnj`u@m4FF59R)d-5B2bQmJPPzU=n2p$$VP!jgJMvQ0Ur&DMZ7r0ku^z4SUXu6ymkusH1H&F zT}fD-tXy2241F@nDN5jy6y?FJ6qHjTPgSC_Qc<3+Bxg+rpP?*VH3PDzm7?^gl_j;G zMvPgAH5)t~d=7l(KtBiN43slqmjSyB=ra)`8~)iS=Rm&zd?DJrL`h9qg*;a)0kc*s zh0Ru@yhho)e4SF1y-wM+@g?-lOR#$hee;qsb;Ww%^}y?a*F*mb>|TNVRq$7VH$cAu z`VGpu&<&7p1l|a|5qKl&d`r^V@NvXB3HkzlUqE*Xx>L}dg6A77{}o=}K3|AsdIhTN|ySK@zHER(JSUsoKH{!kuW^ap(Z zP`XdL0enOGBIkzk=%hcXmp^ zO;~GE2d_1QENb8q3*;8qSb(kS#l==&E9|VmxZ%yRA(jn3Uch!WIm@mV&-7N$XZnKt zK{Y`Eup_Fa?u@Uc?#ij9t_Od9LM`~!hhGEOGy*jSH3i)dTcT#LZwC8jux|$YW{@>k z6XKhzMcFOXxyxGsw*V&I3O23O*C(_>xiw_1VbdBmtr4#cs4e7e)qq)@)tSvZtLaNS zt1U7*t6zr_?+)G_HV=S;LA^l_!k(xPa_EB``oQNQ;D-?VA^7xH7lid!`#d)gwoc$j z)pend!e$uC!%!Xuc_=6xG#nHOU!oC+Hv;iSp!_&uJ&yi*68$hnO;|k^Igdw-35YR4 z4GEh7c>?5#>aLB`AfE>LG{l~!PF;}%oCKT%oCJL`e3Ma6Dku#!6Eq8T5Y0xNvr*@4 z)HfS;vsFjd9E?>4bQu`G49ta0lru5TnV1V%C}&}eiM!CRF7&Glb|`i)zmW z>p?GrUR8_IH>j%vH-K*h-w6I1_-o*AsA;v|0N)J08GH-)7Vx*#y@79ozXSdb_v>3%(EizaR5{KllNx zhXddTfe(ToQZ364fgc7wjJfbB_!0H%rAJ_Q6y?vLKL&mrF;5}Zmx%cl_}B0`4f$#C zGq61a{tfUqh;bJD9Acb<{5zDt$5@?5fBpoz47vjP1^rBP72|pp<9Ze4LX2G@_-`1u z-%#HT)Ki4|Zh{vhehFfgAXW*=rHEY$UItki>QuCgi&f2$rD|UYkjmoSNUi~=|0+{em>f`W!1F0FH{GvuIUBP9yj< zhEEf1)WT-k)P>D~TWD7|v;?(6+}2vatkzm#v(_lL0kwx+du^899_1iVN6nr^)JfYJ z-wE+M!LN%}duV|SR?Th$s&~?+cuIY}vyF=DpyAt0WxCd|# z;2xS|67dJL?voyXUr%lJ#Gb%CwMQrQ1P<25P7DSP1`gI<-S8lC=%*FWd{^vJ+*e_F$G%OU@dk^?7cvHqP`Y+8&O!4oBM~!K1ZBYhyI+wHU}_ zv@L6&MEOaSpVW4*7_CiwE*9mnu#1EJc<9Chk4N2;(La;XKa)|O0!jo;10^9xA|3sr zqhEB`&p`cYkfot*X~^ekl%Ga>pGKZDQJ#suAU;c5A3sZbeZnkl>WbOGv(bm3wdtsP z4*GQtWOE>!gSKPmaXQ19J&|J_w$mW4(gXW_=AAA95At)EL6n(Y~IW0%re8hbQ zZF&ay8O*C^Ft1i3zm@2>zah83LADBfm1bGC3T+@-1N~aao`?Sn@Lz{qUc|h388Kdm zY%^qUg1@c(@X|Zr@1f4E=&P;htF0(+1HBL00osZDh(1JLeTcsL5HWV4j@^*$Mqlkl zT_2(R5&G&Q)cG;WAEU2`??GSfL0|1bU+o3ni+6N%YYd$m101{|D;*67Bd3vA;&V)7l!$H4|gimST#fmAI<45gRS-L?=soG07Sv#+W*aLbbD4W9lMKsKMeDtsmr0JctU1 z{|FId9ffkN$TLjDB6uRZ06^QvfeAkOjrdObU z6ZAG{8>j&E5$K@ktDOa%1APbjUNqG%!TyrCX}*l|&)`2Jhu={54b)wXwv>T{GFH`; zDHfBm#$;9|S*^f!1C;qiM3bb!EVy{t3wdWOI>+{g91HBG<6S}w1=C{$#cR=sLZY$z$NBj>^-ww!j zA-98|Lnwa+Iu6}Q=)OSt6zB|e--6Df|NaU5FXZzR@MYK)BUUl;ErF~IB-Ak`1*EDc zG>f{%OxVm)`)YGQ8K6v17HsE(=fY+YY!<_23HVavvkZI%iZL%xfOx*`WD2 z`yyHhS_E1GT|R7{fzRLIvkEq=L2Gc{^$O0th+akcRq(%q{~hOH8&KYWv$oARhuaMP zCit7+Z{a-dEu4?Nh4R}dzm4+SD8GyHyWm@KPPY}Zttf9pc^k^xP<|if_fg(~@`pIr z`w+YUya0SR&i8ghw;Sb;Q2q$zk5Jx&@*b4;qkI5oe+N)Lfbv0<52Ab!<-;f+#yQ@n zz(mJDCqQ3-PJzyWz5{&^`T=wvXL>(@E`ctCe#Y5d8P4zo9>r-Olk$ems?@OALEfNh z$|{>LLo3=`4Ydgr>gE}Z#wjl5z@J^sEC5 zo{vB`3={$iLySo95uhmeJr4dj_!FRLl*cNAlq^uLa?rd4v<&5y%4XB^c!2u4vd8om z=xxwDpm&vqmTjQzpbvm|DgQL@QT)t%mD!ekp#91+^C!yd<|EL327V0uIQU8MQ%WcE zS4yn;Yw)kZPeXPF{0w}~!S_4F`T?=dL;f$s{|Wpu^wrgd7C(@`8f*3kuL&LqUK_j~ zxC7J})D+YP)Ly-A>a2QMx}w|@6b$MO+z;}HK>a}jA#;L;sNa}|fkIFY1BHWz13wP? zktmNsIR^Ie>J0N!>JZChwXj-=s_;&E^;5*gjAgm+s55f1Np8enl5dQ%9L3Ji*h~*HrM^VfQ(5`5fhw;3t7kqI??V)8J>2#~JW%Q2#gJ=O8}^{vG7s zfqxJA_u&6R%zuGjKs^`GKbJt4L02Fvgsu?$H|TzY?01w)Au9zhgRBf((;fzGHkq`U zpdpqT+Bi!9&eq%FY`q<*Jtzpc3#b>$eQ?(PIOqv&jWP;+G|t>(!HLG8JQjQc&f=fK zIeY>r5i|`r1(XVXDsU#w=d-}Gz~_RpQO*S|hVRQbv)>MSAG8B>0O$7y!4HBT27QY1 z3GEfr9Nfpv5!019;uX_A6f`4xB zr94Nv%*(x$MV~L;v*>hjUi#sEsg~D!bxBgUblJ2l=;z;FUVM7LbDzkdhtt!wi#x?G zJSrWLSFpD zapE-A3$f6-FUMK7&{?+Na`a)7XdE#y&M}5wh;fXQuNOL|(c6fQc-?{5J(ANV@#`{G zwNJ!!?H|*nH-6GC!f)>rj@`YY`QMVJtM>VQ|Dc#^W^&HV$QZXi9u?Oqb}M z4pV6Vpix;&XXJ>@=zdFf}k!z*_4rEyY~e~T(Fy)1Av12Ft4^Nnk7RHTp z43M4XPw&PgCdDSDIr=4yofw}Q=My^Ok#coihmN;w;&gp{%H+vu<((Nfu6^y8&Xqej zZd^}ClbEjFF`b(@#wR6Cal~|0+Eb?_sGN7^wQWHE$E}Vt)m*FgM-OZNa>t5}s%PnFk&$ z2^_KAN7kB&HM8X(TST(bmn?JUIZC=^eCQ|<$pN0J=_!>5>{gQN`~|a>Re1%=vC{I= zm&-}c)pS8M+#meIwmVt7*j%AHTpxBRDNBxWC)6!>UYC+*@3@d$SVf8}5G(s09X!c; zN>pv`yly2(Shmiq46hG!W`-_^bVlE>TX_euP1Od%q~aWh8jbY`tD18RkD4o}B4fxu zkO!@Ni=Zj>vXNuv<(GwfN)^PEVNSi?YaO<~b?)tNVRlSePWGs>ElN-PoF0^u9bIi{5?1F53*5U z<3GIcQgs3c23{>I!_UI9Il0bXpCyqt@J6?q!;7SMAbI<{bqaL;!;9R$H`o`|U@i1b zd5pX>X8&U3^9!Nef!C1F^?#GkHN?E`j(Lq^UgwyOlwR(dwSmRRs`L(76(d5aJ3=u> zC@q`A3j=A4plz$_+~CPjKHK(VwhPpSNzidOepKMO&fkFY(hu-V!=>wfIZjm#8FL`d zL@ULMBDu~#b0crILJf7XoQ#3+pkJSLmow5Yt0{KRYBuJ9;-L9xa?b>lvNzqW?mkW6l z*J8RisUOqbc%jfS7H{rWG4LChFwPSV!5md8fT+S93us$%q#G@DTg|*pjxG_fT|MqY#xTI2cuiHi=UXN7Ui!7eA3!H zqqj&NjhM8%7ubypHQiWw8=1*bgsKwuRByO?aBo$lcvlco!zr&nD-JX;YWl0$dMfd3 zv@EO8C43R;rx_A#d2}Ik?{;jPQGkI+u4`my7+qW7`4Ik@dkp(; zNznN=AIqtkSFjTUR31C8;9lM8-Oi0-dA5%#kt-_qXZzA*s$OhdD?K;2*@4BlyUngs zTZog|Yn&NsMEpZj#$DHcO{~ss^77H}s zNQJxib}HSV2fG{jwvdh7c#F+~Yx<< z>@JiP7mD(31TYuKj1L1R?)+hZd!uY?KylgD8pYf`mUub|9~g3FD5^YV71f(!d^qq} z-8u>!%SEH>LOaF9#-%)fv?a??kW17P1f`0%E|-Eb3NUF>THUk9#W#xocPrLdkQKL# zi~?+!m}v(v(=Ok-?Qlcyb>b(uCw|<2INcr6PhQ*qKTS@|J)hzVle5?}Ig9`2le3s7 zXYqe9IcJyV6#OT7UiYEW|V{UtV&Z_)D%+Zp*k${hR_`*i3o-rNk#B}8E67k2^ zmU=4({p$%gwSrEMe>#p8Qdh~zF_pi*#7L zivBU(ha~7JCB%KhihmJo`_KO_~rF zI|k13pRDz9GLIcQmcEi?Xh<=*O0Ar0h1~AB>WU{X+VGH3qFTSO{-fyi`SA7+Jrv%U zzVXv;a^i%<@#7t_ref>&0IQpf=#!sd`hz@W(@ldSibG#!YHhE&SzvBt^e++kX{FRXC zrZF8^;_fr%)Ia47;LZ)NF#MiA#E`PH9R5lQe66hfIKY?)6tztVj#czH$Mo3vS*7-y+i9iV3gX-**vEEz!_uX;>PKYDX}x+r=(1A3>X&f z7>nV?TuPXbJW<|~c5Ko-EG~9jnj<;Up~vC=b4=yqA9s(pSF70@S6LEn9a5Syb#h#C zT>JXBE*s+;ckU%4$Ip?3FF=*|n#nPCs$MOov!k8Eu%^y^MpY28{8^0(TZwE`1lv>PltltxBnJRNAld3LLQH zTfUAbE9A|G;OYu6YIZ zjrmKC4JvgIRF$yD@y_|U<2EW^7Y&WO{3;F3EBIgL%UR_WR9^cu(z1VZvKyC38?{nj zRj}cYDZBB3{R)3VR^8prez&xajAX>S+gJI_S?*VPMjXg)T|%Gg+Ll!QRM)nIm*st0 zFbwdasD{RVxj?xq+m_t=DT39UnCHO-?y!%jE*uV*r3@)=9)FNiF*WiEDmRs#xA>Mn z43VEODz)R{Y!y4lf^2ydomX(DbLgCGM@dG(-HxCaWOpk;EF6b%>Q%GJE4bzC`M=eM z&58@b|9gEB~bQXVnkJIE21-@Qc-m3x=ABQHDmx-JXmHaXf(33f?sZw%e zL=~nyZA=NjB;F2I!uwjEF89?bn31-iag z)NwGbkbki1j!#TVQNN6#py+SJrjQljv+gp-$}9Nx)?FQGSGkL!4sc(s-P~TA{yHt2@zV2P5{7SnYa}nF>9XD6otjB3*O$yH_fMLo|9+JPd zyQX;4t$>ok3(GSxFFj*~)Gm%O&e`({uH8B=Twi&%cS)4a_Uht@gRcU9?w#f@UIjkk zgJ}iVgO3Dmf~wv~a55Dx+*O7M8uy)qX9V3-2e%ptv~E;bxzCnw^*7Fj<)-0QVz06T7lZf{uTz6rj7jr$4`_z%0CT-~)-e2)WF-r=UmHft=e+vvYC zW3XxQdmQzRWZAXSm5aL8)4of&h8<_dKd`+p&nvib>r%eWJTr`Lxk3J`x8z7vj!A`q z+Fn+M1>A!>y@|X3WOkMBgQf6)c|ZPdKR@8(R2`KEpu*5bRdmw5 ziax>90@(A0<|=?cO56UEm6ejh$^4rSH7UdB*{i%ByC1RM3O!F>abdvYR}Rgi;9l+v zvYTTuwX87NF4ivNrli=p9q6C0gllti+~qvqvczZ+M=+j*EXb~pgXD%dNN$eL0WC{{ zQ7%77uFnU_#%iUf9Oz2ERpK<<8Qj}bjpb5`M~ITz;r>I!La6&j-o> zrkjTw&({B!6Lz8VO3?X^co!eP&H^`Am0k&uI`>W1B_HFakbmM0hpV}fh3^Yf$J0DM zRU$N^R~_nAHM)JMh0b5@k^}4h%Z|CuYq^ov|84S>jc%XAe=(F?P;H#W_eGYviUi)< ztJNEqEx%l6ac*R(d)-~KReD)M?sAns-m_3@Zg-3)hqmGY*{ z)S|M~8y>5>1>Sl;7FrWyp?N&Ymr42VPe+zU7G)J(D&~(RTJZvY`xv)rx5p2UZuxMa zUZqbAaH;U{yplEU>Tc6Dl}v7sN#*|V=shJ={Rb>7wvD^PW8o>m_PV>`N*;IV4K$*s z^B3I$p5y$5=Z_qgzdCPtIaaLcZo`{;y)5A^1qu3a>uBcMy39_?J)jw z*I~RR(@Ft(7%Qje(Q~$ZM~L&|D++F(omUq)3yI%Y;4FgSz24i!@V%XUs}R?(dq3(* zsV#R8#d*~~vJl`|#d*U&vdD88ytK69xEI}eBX^gPyv^f+yI9|5QQXzK^7^=o>21>R z48!f0FI?_A?zil0l>**%`EsH>x?HN*ySLkOJ(h0Aiu;v&m9Q0k=x3wrxGwu8`{6Td zrInsh&=@bbn%M-8oNDc@7_H@<^K#IMU^xjyO@p@AH}LMoy{>_dg3Kxhc%|Vqg}gp z4mGB$=7{M6>Rv6TD?K}H$G=!JTKGz6{Jza-JovV{AKyjB$4$rk(Dc}>%JW2i_RMcE z2l;ZpWL^&PH9n@*XPlRQ>ei=cZ)$wz#XqFg?pv(#(r=aVFy$2#;WXSct|(O;QdX4T z=I?iwDF>WI^n!lnH<%)e=TyVJeG4_%S%j1BMk;5G8~R%1C2!*+L$0$ZH}c-!W7>ze zON#Ib$&;3mFy2Y0`>n8$E!rKHMiC#6%PpefsRj2@#dw8SA$%IUMWiTw@xiRH(!~?F z%4>0j*qdp3yFY*8G;NEyLKE!FO1 z|63JHV=5GUUl=%oR$yO#wH%E*55tNT{ZI*eQqLEmb_)3swvmv%8- zTgG&0<-j*f`jmf%guf-ytAE&omA@#WR_oI+raQgUgJ=2^;v7>_@O6_hcwkT8m*_|@ zHqaCMirXAsd7xi*J-44ZXNASD60me%Y1BN;bC)U)9=~(4m2;SG|Wev}p3wC;A zz<4L8`Q6?)N=Te;e7UB5WB&fkzuPz+R_@}=%MRlkDJkxa^XM(Za1q~Lq|J_BZ{DuC zpDv_Vx~VX};=(a+KO66QId}VE)>gK|E4>Tlj=|OQL*-kh4l>~gInJVm&XQi$aIkPq z>(vhIXRTKsuphOI^dcq6YoW7<4+q2D72amqR8D{mt5kTK-nckd+wZ(-9ATjS_kN`~ z;Kc64|9M4Zcczp#(dx(@UcAB;0vDH}b|kKMh@^lsa!Nbl&XgEW-6AUHLzr z>fEKr&>t1A8&!Ji_S50+KCXo8iYw;Etw%!6D+?m8=5j{_M_!$y&oT!)uS}neJMaaO z*Dl#y&O+>**W}@tvoJUE+C7~CrC!5rtb3>%R=CR32@r=tZ7DCJu9P*LxhMTw$HNnc zOADOW7ewB0VVqr&H^jx-r5<0_V^4RVFc-N`UT?RZ-*sN%)lw`1{H!#g;c|yPpI$_D z@5%1FQFq?uAH*+L-QsVtILDWQbFf3Bq~Dz@J$Ks+0SCP_u+ljP`oxV{&0k0KR3T-@ zDpo6Hl{Y23yJtgg-s8ojzVYqD+imB49RJnr|G&DOH+O%Nueos_S-zd0yrqvW&NXcF z(!Z{#!z^%51b#^*#<1eanpg1kU)j;<)qQ7a20>JQwt)$G*0+}Bfm7ZuT!*r-B=J= zMBCR5Y!XH8?dwKvWYN8CU*#XFx#uc%U#^qFpf=jRPTlMF<#M70k)`5d&)aNQ?xk6k z%O&`B#c3sF+i#K4dKC1}J7}GP18MxWZ5&DKI0FUGPjWIp>m3Sx6s#geU6QEYA}^O8F(o{qP%)uZuwZvU4FcB~UoPtAV!!udRq<_**EVv0~&g z7yf>bzrp#e97*+$2HwGPA7Qj}C z=q)BgPxE&gIFh3Ce2J=JFTbO?m{T}lp(eE=4 zi~dmQ6jTR!e9SmgKgfKceuDWT{S@;o9b<@bn5&;>o~>VIo}*tyyQm*Zkq5Qc3+<+H z>m>W3FXlJRuc5%y|Fqv^fIlJSGo*aBl+Onz|Ha^=!PkIOT>K7m)Sn)O*UXrofPWD5 z-#|}sznA!Di3_ow1^oU1Zi(?K1`h(aB2UWKSYNB6nkq(|_K;JY&JsT;aeuUr;tb~Y zu8NA4`pHs1P2yP+XG;5QV5&D4d@$zWN^q)oHFyumUt>Q->;R^EcXRyosN*u;87cox z;>!|aeQ`cmUqR~-ht}5&_zTR_AW=)0VaddL^p67a4P7IE~R{h#Lr8-9{#jWHh|N-d_%^4o9$|eZ4&R4^?U@3Jzab%`L}F0M*Id$ z>*0p9E8+SvJ{DvCcw3C|sSiy3)>z`6z%)L?B#vMnpg#^djZX~YM14H-Lf0gzPqG;E zU>4*2q!(n|mnGgK@j;1gR->KnE{O+C2g}&4UmrpDg(_ z$f-T4(hq;ZgV#w8@RyM1S!tZ{n;wCwe>Pc-aefnc9pXLA^CnY|Fd5gyk(f6ApZ zMD~*)r~9Hrsh`gJrXow~=S%$}sb9wW0r<_4hX0E){_D_hN4)nSp8@^>+eM3A67Pkc zuDgd=K3dTHrux5P|GD}nP8Rt)lOJy7l^P-1H!{6mF;?(5%kfS$Z zo~<{s{<=u|uaNeur2krpUy}ZRmwCU=JV)Qc{H2I@nXil31-lI7dw~7- ziW9P)e?U&-cSh>JW4%qeEcL(2c*c6k*71S`_lpVhm-@xaLj8#6K@!)5p5oPEd1Iw1 z_&MIv4b zP{vF9rzEEJOa3!qPy1m8cn&^S%;Wg!QTfvD1!?!P#I%md?_KGKKLEz}3k5Q-LsEZ~ z?emq-fhn&qW&CfX-DPR_tF*f=?QY6=!ba`?G|JmX{j)*|v>El@CvkI$+t`f!gTN{O zuF`LSv>PVvA|!rN;&IY1p8U}M1aO+qI@{r|4M;l|$?->67EAr#Sie_!N$USD^>1^% z8Lq=p{u$flD<^@e{a=B%#Q1#+-UIw1+h40z1b^B$%h>)q#pGq!dx6t^k3Trw_XJAb z*vps~&4FoNbdb0&Fzw3&C5{26>x?e(4CVp)Y{=_Cp2av(U&y@BwV3%d{cqClJul<) z$_HL8gB-|z7hziOUNj!1%BP4!?K%!ld42^>d49|OKe>Kne$w?b56|69C`_IevU+RxkQ|5}U#^se4UJ9>H>dG;ZUJO{D<$>^c5r#wT!DbL5j zDbEIywaZD9De>dQM6GMOn`kSjU&>fGOVdj2DM(^by?On;8$$-;w&Aj1%;a znHReDGf&hHF`uR%VXo^ZrT!nxQ}nNyXSjZld0dcr{4Db*M16E${s-Gl*Nd5_>7p9- z&o!6Ee7f$#JWcnjhR=1dugQ3(UWfT?y*~3fdSmAKN%u?M3ih;~+k?|Q>MG?unFr{7 zAgBAY0gN;CN14ymLzvIjBbYDLqnIz!M=_tSKgm2zAIm&TpTK;s{uFavPhg&{>&$cX z>D7#V@#$(b4*k@5sF%iNA>?#jUc&M?^*Jejf&J3-*O*V&--O+6*uMuojo$}skNYr* z_sTejSe~w)lySade_cNh{dV~MB<+8Z{?{b_Q~H;(e7W%QHS+WIrE!?8*JD0YZ|G~> zH#LTy@@Vc$?THp`Bo6X5+S3)Bt^++;|2K7@jQ23d!F?EW+=t0{(b9j6j5k5z$uizF zV4Cl#?048clX-qpI^?u}&zE>DFpc+167K}2aX&8cDdqwCX~=2+KF2swzreiEb(wjB zUMTagQJvbiMQu>s=#M7VjrO&uPW_Uf)E088zpKPfV5@XGY`;RkW>9R zj1%>x%nM!l%oFsrT<;3yP1w;qc~|LFpbCO((YU2N#|rgNcn~8 z;kdNp^QDYmB;%O;jQC!D)Xp=iFEGWa=|}Ag&>Q+0ahghbODS&$JQ{Z080RMi15-P3 zD98OWT-uF{_oW!q4yb1Nwebt-5l-Il9RPP?P zJExwMc3;VO-vVbq{{!Rvq+ft(d~QhW@|0_r=! ze)&nCLQeDOIO9*FE=#V|FzWTGVbtp{aeav!*D&&E4%`y{ZNPhgcdKEvHyD`uV}QiN zfvKL65>El9{>YMeKJx&55#-b#%NQr>&oVD`t(E!>(9?Bw3pibe-UFxW&@pgYw_mW` zVf)v}kM@OcIB#F=0`$~>KSS<-yim5MM9S5gly`=!T1~^QMont}5~VgU^<#b3pM1Op z%U39!q+NH3ACh=bO`~6ivb?JnD*YoRkFD8@*GDSsD8HF(*F(#e{<)A-eoMK&Poq}L z_^(R+YZ7mjc!#WSH#pr-?~{HfrQKO+cV6OOB)%s7{v<#2Td8cnSAfxe-vDZVzETsI z+FvKYh~FT<7~fWq)A)9hco;B^Z-m5|z%;%qC0@-uKwk$rjqfXr6ZJQk7rNe(`mM|} zTpz)X#%sUK;}c-Y;~01j_!n%Ksei+Krhbn3Z2dg*h57~Ni}cIPr|Z8kPt$*6o~8f6 ze6D_zxvrNo&(`tBMKKR@bSv`&-J5xU?qAF3r$EN}N#V7O_C`s(3YgmahQx16zip6H zdv{9tUTJq+;#1P@G~~2@os;rn$(2B(9t$|d#}`0&->U=sC2#}A8LpPV)L-oajdAM) zO#RgzkDX|Idj$sKcOnbXpY7A5hO*rXWrXw_CGiA_C)499_)Q~!%&S!CH&5Cvm3Gfa zyiVd*q~9i4@0;vbgeRSLZfm zZkpRd;&u{uW}Y0;mw9T$0EtIQJX+%M5>IBnCL)db^AWQpen#SFC4NETS7aXVF`gB% zgL!(yE-C+7%Fjvpd5M3L_^PzSUlm3>Rz+BtKNn%IW3;cCl(&)c4ia~jIGFjmh`!8U ziWngAXo<&3{FKBA%&)lgI>vsJT8HMxNG%if(R|2;obC&ArG6>v2Z+^DzYg;4uzMGn z=F|JYv_BQF-Dq)0+8u>_H}v02yMIZ$%WRh>{*ZRXGG4X1M!Xtzjd-=|QeMkN6UZsA z7LeD${Oc+0`bfJ0Y&TsSCha2Xw&e5oDbQ1%$R!IL<((iR? z_ZI8dYg;AW!T1&JQ)z!3_I}9gYpFlW`c2w-i7!G={ZJyYT94YbNwd~7+Urx#$g_dO zO<4bi)VIzZv;$s_uohTlO{SyyDpGZyn)j0VQDvv?Y`1RO1meeoi6QWuztNZ zTjDIn_`5pNeiiI#++LLWS6RPFdrjgk(CjD&rhmd-?&aX>XSS_sUt95C%Z{J1eo^q7>UO+56~wUXn#fcQk}kFkHIej0k} z|MQU3I9&v$ak|3xqs5=nz7+D^(AQ{S*wt=e*wt@fjAskTsou7bQ@q~N?jdP6i0x{c z!ld1Z21dV)k@inX`>AZVUQ3bqX~wT;xzcZ`^m_(=G``PDyXV<%leS*s4bW4*J0<=| z>i0|hiLCdG#NV<0g7%}tm!PNdy~_3FC;bjNore`MzT#3E8vSl+NbPTBs@~9Oe?UWO z*W$27(9<~I4>|Q~E4J%nYAj84k1-C4if9tsx4vzF|45dP662&iUdj{LKR?NM59F+Oy41Va{uz-2Ozq7BAB^@dm-c@Hru#?a%GPSfvWK3#8w=hx)d1f2X@OS=vl_0JB`MdAn8ezrc4 z`AmI?W}LqamHJSY&(WjVZNVYGNPr3pUbVV^P--VH)4Dae~rm#PZ!ulp`Uum=Y{=PzfCwLeuSSh=IGJPv-McmQ~!>m`0$%7 z?WVEcCXp)fO!=HLPd=wyCjIiIA3YDH@q3Z|c8FIcevR!H>D!nu)OVPSaVe1cJ#7Dt zI4JQEiidWdVEF}c267sw?;xlB>qlVPC!XN-lc~qab^jFBE1i#~V4acu(~#3XF^A<% z#eB#|L;j4!F96f$u$PrU;Q)VK#(9(V&BO;X&MsNcVdxJcug@W;c7DlreZ)5se-Ayq zKld+bUnuRd&V!ahj=wRC{3eQ8nD>-lJ*$=?U5Irx7_YlOgZ!xd&q=#ippU|MY=WG|_f59@NW3fY`_NOr7O;H3 zI3)d#O8>8<|F_cq2kC!7;-8_X`CG{L`AKDvQ$Lz`UF0Wq$GoO~G~QRpPa4MZ0KB(g z^yA~wE>_x2mUx=9qjh=?`5WsrKWT;3uY#QFSu6cEN%@<=Uqb$_#P3VH0*UGU1lpJA z{TteszGeAg`wz@B^?zYKQh(BWID_$)>P^^De+quyo~e7|c|6V20QsE1E}qK|##^Kf zC2q?2hUg-n(?1~n9)us=2R$V12C-d<7%Fin+s)OZnP=&-u-}bpJ?|q>JtbnAv`=Nb z96gJ9ww?|9?XX`U^^0X*72i+5KB8=dp4zin`n@Cb^1QEO)I;y<(0tj?c8l~A%opmX zU{9ZWzLNTHfocByAoZ7}{V&Y3^lQxL>VGiL){B|v=w98%s4a++tYS>9B1ft>ca2l%~!R-zv;?VsQ9`+^up`9AQ^cuz0{cJy8#wHsd_ z<$M+FUsS&r_PY?#RMeFFBHG5!shdhY?#p;TFz(CFdiRlb1K6*x7$Wz{$G`_8zi??E z1x))(ti)4+X}+dNya<@q#S0R@%sfEf2zedIH#1Juw=yqueZV|Z-@|;Sjz3m~yk_gz zzrh#kN10=sm`~TgV4kLb#XL(l-rJq4f5#ZlgP3RQ7n$eiKQm9zjrVy2^gqykS|7#S z&Y{AJ{gL|5hxf+-9q;e*zEU4@nkS91--h6A@#Ye@k^6NJ%V+TY9r^c_{*Ori5NSVL z`j3?ON$6?3$I1P88syY}sS?xsh}3^OCH_dp-48kS-zQQ|`#jlwEAbD~?gHeruly|K zX1Raa<^EM2oc!ubd1K%&ftyR*4VdJKwsq(90$OAli{S0Bzi uTOY|B_bb>xX&#Qoz8WI(1ik-A{e<@)d7dV-{9TbQcH8h_sRoiF)N$RL;69CgL7q!~%T)C9#r*0O;?P-I3B$FE{wnL%k|bqGX2 zQQHkq5(OLC$=c)E$pSm4k)x#KwytSsw_Q)C;@Ck>Y}>l_VcN|8?tL#afS$AU$G&>s z=RUvZ^FH^vcX)HGE3*hs9~II@Wrwm){5!9Frt~Wg|6KqxgF4VJ1~gZw3f|}JClhn{{0#?GRHQZ?FqNXSwa-nV*-Hx*^x^& zIg1}-n(oDmZIS`YrsuF=U8E-HiA`)u`lB|YY5l1ZPtK-WQd&|{>LR+XwMonysR2zy zZ@%l4QbUND$Y$Ugxx{Iya1|3>+ex%dqM`C}CnM4r$?#PT zgNDjCiR~C3o|Zc0Z<`uXAh(tep~Z8JvLn*gug@t>-(1czmJCsltQb`oiLxxelw=*P zg5W8+6z?npQ_pm5D4kpzV0kbNyfrJ`&T={X2L>faaVTs>Maj}iPrB1xEN5{+tmG#h zDas*vxiS&$mKBCQ$*J@(mof#|@(z$6iDc<>oF!#8Pr2;yGxVCmJ!&m!<<26xfMYY^ z%qM3>*ow9~nFB7$4~nkHS&?FK+0J65BCiU{5I}1wt#GZE^Eg%xS0Bn*V=SA?-5$1E za&8b$RI(yj2$qnwsKV`(R|aLQm;pSD8t4ckcxGax$wzsuuWEZWi^1P12m9$I3btuC z4fU{rhIL7V3Zt*?QD-LfYGiiOf-#oNhnFTNSkus{M5l-qdpzRZMM*Se9K-NvS&M5Y z#)fHOrPpJwpF$K(b7LruqQhuv97Q187+OXK9V@O4ncK-p<6`uBtyZg>MKp#m(PmRT z(bVueD9#v0luLSs5n8LzHOG-HD!=Xjm6e0~N zdi@xKICOoakY3Vb0prnIw)ihDbr$l89EmsOC z*)pCcMa9q;FHE3MEk?R-nM5-(rc!D~JbmzNJUtQ>PgNPy=yw^@>D7!GbTVTmwJn`V zcUH|NU(#&YBw(1q&!PU=b1+Y&J2Dc%CxTC;sOlulQ|Lxg3VFRLq)$(wS*6LO(mal$Jf8L5o^4VVeotO!&&ArMJEoI zfiFXDjJiSHRIs~}u6wHxs|t0fBG>a?jB42KL=HP4+X>lD*zSVOF4*h>z6NwB| ztP?RhvHnif>mB6e!#II@cGFwv9lw%9WA#b&l`@~!X&%BzqYKJXYSkN6o`9hq9^%zc!O*jWza2_7R+=a8^#_(WNU~I#=VWSe`35+V}ZpU~E zx_fbs_F?=McnijJ7_As>80|QRhv4%y_&9>`I_Ae<(~0pm;=hADeDtDb8vPUFBPoSs zdSqVNeRr$wcoqHUrM;J$eAz$5 z=5!g5p35=6fdo5!VGRV2H;Ha3s*p_ifC6N7~dZMZ_7* zP#^Z*F|?v4p9Lu)`q*Kq2iGUS+paHU6Use=g-Xyt)G%m2tD!hsagocl*|pKQp|sq{ zegvH|l>AE~WnY&Rvjy3smM(oq=Y7QNo8Ro{^t)8oc z*(&8OMr}^eJuye>f-!7&|jwy|vqW6`7vY-bC>etmS4${z? z_!(ys0gO=c`W${j7Bk=@`+I&H;Midvv|<;CdPjt^Z-SNZw`|zzc>unGu85)2?926& zXB?OC7b`q&o*eaX2b+K7+J_vCJTSsW)N*vaLLpGrLY%n~5x5j4*M~P4cq}ooKYSK+TF->RXKa2>ugcDV*{z=L$s|Bva|By12?HnfFob1)wfaoCnw z8|xf?)8%0srwW6etd}-0r$qtB-HgViR~g?nyh2@|Bb7t_09t1MxQ+apk>;-y~dsNH35iE-J3h@*TAQ z3HM>>2{*OlLj@m1rt=EXD$sU(`aDVDra~w+kkRA?eFn4)^dQlGqMqn3PVb3^FYxz7 ze*k?G1Z9Nz4>=Y;U>hQyCgEP@11GjE5Y9<%{EO3HFLdl z_C?^CUwos&KD!_XdR_3hTFBQzUI_Vm&Qt9cPW?3=L7x=37k13gKF;fEn>jVq9u)X7 zfxj(qpWu50e-?Re!Ux&~Db@-%^fByM{(ZnJk$*qO!|AHPzZL7!%j&u!WM+3aMGHPw zX6reSf4AU`TpmwT1wT_J(-o}qe(?3!p9i@9*|2%w*?zrAu~zmm+JpMCJl?~;G5vGA z?)BvtiO#cc+Cd1EQnCq&(o~LrS(Aiye24YT z!}<)!KV7UZlgkg}uK>^X&Bo<3XqDjY@Wb*eg?%sTwoTwwT<<=r7JMD#sqnv>`|Hg= z0GzGoIj)yT?LzMm^y=Z~RiSrM=$#RI?+d*TK&PV)e+4yxeg?W9bP)6_)XjkU8Nf%P zzDC5k7knY;Y}DUC3&{bV#V-c+g1SJE??<-1R@gT|?!`I|3i<-~ zw}_4ie{TqVALOjxPXT9j>*ab@`m^9KK+fv%H?H5C-zV(*h5c1w|Eu#1Nk2dzE9-WFZe-`-@iG&kfJqe+*nXA;!gr)`MCe}@`u`I8-wXYKh@;V}@gub?Zg2hs z@GQ>HIiGExu2uJIHgL9Ia~Kbr%;nG87jW8QPZj!0w6PQgd8W!2Jk0!Kzp^-gp&(cA zYd}+hyEtCH#shv6crWL_tl6to&+!Y0$IkJ~96yl%26%SPx8&Z|Np3c*IsM=*4k^Yz0W@D94^`u zrX~vfd@W{+U(D?+L;1gLmS-({EWi1j4hZieL{YfHjMp@LJ|R90P~2bpDP&lf{A>88 zs9#uMA^VgDUEh9ad7JH-^2mF*ZTL_p3jVt|^%6!VnDF1KTW5WWYLXZ%0K5S!}~ zqQ|K)`3v#pF}VvC7GW{Nj4YhWR(+W3Kav#NQ%*6Aak{Zc$Dfy! z$SIbw1&*}QsgM=Ed`Lc|rmD{}QivDcI4Pg6mqZCsm2g@fs+U9y(KG*wJXtU4FT{P} z!P@D1$v`1?_Ux=(A&FV#FA8R_#ShSeDS=jd)&fUdUQU`2zuYNAXHERom8J#ormX>O zywWr!(jG#fDzL*C_n<-TR3T`3b+#!I!{g_QObQ&6=}4Qe!c9tbXXQ$38>N6%!=!8V zYh^YIyJ5KDNg#wsv?{}!b24%}ukxtj)RN*eFu|GY&P~hBo|Ly>j>FmAOtGk??qo=` zjLFT*aXXw^F`0xy>T5_eW7UDy3Q4F|5q^A?`w63`WG!)MOX?I^hC~wutGP*5E3Sx@ zhD7V=)O20!BC*;N_Zt%ZVpFrS7sqEU$a1?hXPqWkOY+5bNXv|kAC-6JprslXZ z9L~7x)VZ$CW?CKP7{K`VSd3g}x_$9N$9ZFo&_qk|38w5Z z`k2fj#x&oQU|NaT5-ncbX zlEay7!&=y3#P7JEu2(p6tmc2K4D&MPR8M+FV3XY z1&+?=Jn9Hl=M%)fQy13lg6*VG=~s#*hbs?90aDjFln!0BQ-_-qt-8hJ`Q2OAiMyE- z112~Y&&f@7rjMGF>vVSytkWr9*t=8XX&-m@tyAQf8%K^MR)ML=1I>+6v6TW-si-nv zm5R-EO0@|+_)#=id`@Ra8!6ButhRXt38?n}iQ|qp(=a_{5FO;O8S+`zq(c)W%eFmoOFWL?730y>yvaCQPHn zXo&sHVWPFg3vaDBFfBySqMtx9zFA%R2a(0Mg;NabDom{nKI)^d`T(SBmtYa7?E4Fg zO^Be5FtH$N97@7sMF$^d5g@LEnEo?~0Qz5qw)92FLHN&K*$YJb2X!p1>AzNDIDDy7 zV3_<|n=B8DLCT-mD#C@2El3zmrq)&iJ`C-xh!}&mZf)u)tSYJiFz)M-f^?WH7At(n zF+NN)0kl|=^{$v4U}KAl$;2dzDg;gxW1v68MocNdU$k$D*yy82JM`$|x|T>wy(|zR znOd8AM)tlnR;B7a98Vvdsi>q z)q08HhTga{_7PcFu$6{L+x?K$J|P+HizJ3YK@Dzt9HWNO&b*FC)#BNitkK8Vo+Q!(ekGL!nSgt_;$r$ z5wdi!IM;13`ZuBtK^ulPT==e3ZG?CwYlPTWIzr@t&W#%(mSv8Fe59B-Ptj4rHg6R0 zvEuR_V?}M@c=255c+d&rK&x zBJi=L;!)Q!k+Z2-?5J1;dZ!q-sYFz-ErDGL{FjK6_bC1@@OL4GyMQSLrVO$&j8lej z%b+X6*k!=3hHN!tt07wr*=pd*AuC7R<&c#_R*rG+!MOLr*8>=LJ?Mk*xdGS>z-&Ms zHy}3~;BO=Njp%QLz7qOM@Ri7SC308^{U-36(BA|fn}OK^%odEd1^L_p-4=|u1@di> zZ-aar)@B>z+aTYDIQ|E1Ct`UF_D>_0XF#6?{yDT4&~}Rv8}^D`m3y%#_M%?}KUJ`= zLJUoL%(G%g z*3V+|+@C?ui?wsl<68I?*TS#jc-C*QSM8EGlT|CejH?B`3?4PXJde2kCJ(5Tws{8G z@+N~EG|vQTlE+I;GAPp`C(g5iT4j$+AM|}eedVxBKlJ@U{bf>S0Q!NTfiiYQF#0WI zT4oFMTcIB!mt}^?Z&!q&wUNFn+km!}ww2e(;VavNZ;x@?OZUo-=y$}}9p&_uozU+j z&!D*5QPD%@Y>JTMHeD|bkN1RKPkHj5o-*|AUa;>atJmHD{0)%ZAkFvohM(SuwJ+@Z zV(h-Ms3=n2J0=n_M?n?^SrlZ^kVPZ*evtKptRH0kA?uGh41jC^WCI`@2-!e6V#8p$ zYTaPS2g{tS!I0kw`HgZ=+%VZLYox5sOpwN`Bza-3UG^wSmg_QSAm-Z;^K9r+(N9O; zA@lR*p`U|(F4{u$Z=E7TPX*k9nCBT zf2YjZSOUHT*b-n>zZCsa^h;q=CJXObjaXL8grwCnWa%1tNB1?5t$}QfJejx#*fqee zfvwga~v`Pc!v13q@Z#}4G`vB zxi|A+xu$d{^p8XTIP{N0|2XtdK>q~x)HCwSxM#61o=1N-=u6;VmbHa@<;KvxpjDt% zp!-4hgT5vghrI^+I_T@5Z-Bl5dQct+JqUUT^bqLVpl^d7mUF@mgT4#;F6jH9?}Hwd zcZVGXJqCIV^h3}OrB?P4+6lCO%9yfG&^|@`T(;fvB`{ygeWhPwK3`+*-(p?<1^OLw za0>G}g?XJq|9kAi??J1v5350cz`TFJKKudw8pvue&l=?8NA%BNkDdYkC-lz(^E2o< z_&*Q7zrz0o(BEKp5%P$lS_{4wJ}!g)0Uv)reg%DxycB2B_7s`XEZXHetlFAV zKP_idfHrPZpmu3}pjKNLs7(wG)Y9(_(mtKsO6yV7N~=m}r7d%|(vD_^YTudKLDpN# z&l{>ewQiJFTQUmvW3-%&v0AUnSgpG=PAj};JTT+6grxCW$kKT2j_&c0#X}aaok@%b zE*`i<*iC_*9r9_~kfdoCXPRbse418)TA@;FffgdZFt!#I#$IBV)*JmkXnn;vb0l=p zB261C7MO1oXAMKdPV+DkZ5}S>7)POv7U#5BQE412jv2;@d6opU>FCcwyA}O8Xldxr zMVk+NKIkg6^=Qw)?`NXG`~`e}CFUEga=y_Q%^xigtp!?$+-VMzXANQUh^37@r?r)H zjMt&HN9%~zNggxwK;T=sQ8(@?k?B zWXr&-wi2>pver(B7b` zMWRK6?*}>%bP(E&=*OT9LmLG?4m43)t_6tYS}@uOxm;_nWf}UTj_i;6F$Qf2+A#1V zP)m+Ne>7^zai}RLfS&+55p*KxWXKahr=U$mO9nq3Z5HazTYay7nyi zS~T4Mj0R~on&e=k1_d>rHv1^ol^ zKR~ZQeg)J6xd;BGR%$e8x8r&$HJU*!+CF2bmTc~!<(RM6c9?tN8Kt*29PNa;FXWME z(a`k+9SAx|TW!7({TQ@ic;1QCx|weVjn}HolVCp?a-5H7k7!vUUe?HXc}^C{FfClZ zBf@2{oFH4FJuk!MOY#mWwFhM~`lWKV+$bNEy@4C2&6d+Zm&xB{i1v*LmD96?7%gv> z=Zzicna^+ZDEpXkvGILkN7>D>@%D+MrngIpvgf9!F19Vs&9h~u<~wZZ{LasjZj&}+ z243y>r$pJ@>Rnn^&Rmp%f~*C33&=1nHK)$bmX%}6&4C{{&2rgHvGEut zEM>rqs|Sd&ndU2aLv0?tYQo^Q7$vvaqHMazmXYhUIr1IO#kLN0gSl)A@?37)92E{; zuAw>7`*bF=`E{x~m-QY3=GVD^fh9J6v`PkYG8$x9%79TWyw_6GRcY~N#OB7dRYF|0 z)NH3CH60VoA>kbL_SJTKo+Hn3!+?|lFmiI#ed~;!>YcQ0QEpy#x{5b9&uz=iu+2%$ zPR&Vk^cg}{tacQnIgkN0oHxsLZnEj^FC~Ms+$SQIm(1pLWaPOV=`l8Xm)K;C7@OHP zHQp6tv)X#wVpV5q*}wK|uxwC!W5wwWmNg%&eSOU*mn#Zay^-(x;!<(`p|zis$Gu%X z?eL4j81)I^%1V}a%I;t4DZ*M6sIX za-XH6sFNSVz6g^vC7~Ri%Hhd?ky>F4lFvxFjc8ek+f%kVAK5DK)O2bV+7Pl;h{$it zFCIO0^i=U)ebhnJ$&YNHD!&u6`8$tPzSiw2-<9tvuPX4+kS>#oT6&|7)1w~IBx-UO zb<7*I3Hd#CjnKRQIsU&CKkcnNnhTb}=@BGwXEw|OUb~g!%@$A1fQ4v9!0txDC}e8z5Jm#j>Jmo` zYV_}+$=C8n2G@wC!HRfZKv-z?CVwF;@71vym%ueb{ENfT(A5W!`0PJV{KNmH#52?iRz}T94NF@iPl)FoMhx>X9G1hWzfwzuDpzl zth6jgj@#zOZ%J+0jtmrOIjDObD1dFL>8Qza8x(wvy}?Vv0y{h_$^fpb zwHs`{G?#_y7sDFNn;n#-xZUiBP`kpQ-@#xUJ=J2Oz33MePTvlf9>8=7Y*q=n03Q z3}tL{%fPA&ab}#fMfgRhR?`iPQD=-bZNOM{##-YC1|^e%1*@}(;zm+QV!KK*lBPr- zg#6Q5zaDZ0Q6o%M*sCvEwa}w(!anF#={elf;ZG_jwUlsOR~MfFe%@%h!zVP~9n-ZR=;xLxh?w|Y?XgN9yEgN6cE@BGgP4gK}n{%8zU$7=4@ z}p#3ZFNHm@6~bk^o|;Yt_mZqFYw{HaFuY3Uw3k6}~A^^yLvp zdM9+J%+Ff55ZwtW1IDE0;Q>1b=WEoYTw9v@DwsOo7o?`s;qAcb?nI9t;pxHN<;ZrV zsUuds7|73ZEW#6iN)*m*+im6Wcp!@H0d@bzK z>b*(Pmr!iJh-SgUY=_&?$H%TFq+nL>Ehf;Ghcu<7Ib1H>7yD=_gZyn7_|BPnr9d~7 zL3KA2^E4Pb(tW+Aj&v=hpHWBkt3!248Q=xjTyDGpak;b7T($`PdrjBJq(p_%Jue5} zIr8QlFMd)6=wcVXE!T{g?w1j+>q({1Embi3J=+U!SvM}-%9S|O`xPh~-o@yCm9f#5 zw$K%j(hqM%^sr)V^*3mPEn}fc0n}TiI+qQnGA1+CIoIK;n~OItJrFfOAo*rojLis_ zeOjgr7@IRMcX8c@yuoI`##6WH(^k3|R-8U7&;lZ>B-*Pw5pSe z9P&5y@l*E;Ch4{wEa~96?5PQ-iwK9#(^5S%dQYD+XqC|gQ<1xGIhfx*#$#zHO6Zo% zX-?}8FCU+1Oq7_vgaF+}G9)~XA!>)Mpx>1-FRe@JmxD?MsX|0a)ANGf*?&jYN zvbwAPu*;sjHav!^ua&W9fEuaV;y>(nPoAOLlL;TYc2-##^b zdakItc(st>jWrGOf}50IUGQbpy)afvgs@w`i&a#ex!NmoTT#`vQ5q_$+Tey=QKcrt zgSLTTlbRkVy&k%%Oo0Y>p(b$e>Y?ho9svC;ZN^j$x@R&Ukjq>KUa^Ae}BLXo%Jr>&p{u&J!(qzD9c1M!|;Y3xVjZ4t_ zF?gmbrHuv(Z@LoU&8PgNxd1w)mW*gOw5tfH`Y>(FY);PMK_1^u!2@-jD#FSt=W z6;%c`v2mziDx*y*50FO*C&gw1+6;VLPhsq2&w5hG&9ftYe-k+r!#W6 zr)B-^;7UnnkNyZCOS{gtFNwfQ`JSHo7yeD0 zbW-EDyBgMfBv<49pWN|7ORthh&vi&qajjTxSsFG>h&@zJKd*3DKOzx6v%KNgytZ0w^sq-R%m zk7rj`kN4hJe~rOYGoC%Wuwi%Ip#MUoA^04?jcyB#FR+TLb2xeG<0R917HVAno?Y$W zJp5|s%|?=c*pvTuBa?;)VZHBb%-*~5%^Ox!g{U*BDx^^!l+B+!wua!&)NDfQgMl~P z*{;rFJ)*t`ta{UTRZJd(2gjRG9|yvf^~6q3)6D+#C7r zo*3$n$0&dOF{+|)`y2Ufu6nX++5JtEJWv=2A`n&7{_bU_?qy>&nq%El)#|uV{hBL_ z+gu*E8Ml}`-vfopR#b14>T#(Bv$`u;eWz59Mop!;QaujA)K?8#JzJ^=pgK>9lAnXT zu1Df`2b=XPNXZ9%s4BN`D?K2Z^%|F6cjENyP!4(df7 zN>P=g^0=+uolPbxhovU9v%-b`;}^MA3K6FHMdFWj#0X8?gD*z7CKA2RIgRKSeyPw; zhdx8=kf7}5gD(JG2s#dbBa+AXCEydl7c>7i@O!|oXZ|tpkAkma{&k`uu0xQwf&5+K zb6v-Yo-6(*>pzFS6ytqQ{BqY>qKjM?h%R>3La*Z23@ZNnoYxurB4@*&4YU;V>qhdo zeR~pJV(&+^z&@1eXqLwTzuq9k&BQOY&m>xCPhokg@&|nu>+fWJ8SB>&-_^c}=%gMy ziN^PMmgRexKfwA!Z1)c6J@ES}$({CUq6_Wkm|kT0WyX7mU*WPC)qLIdAfoy9Rz^Mk zcAzTGt|VXK8pOB}j2pwac;dU-ZzVdZOBT`iE>4ygFu#iRrEFIYs^YCA`Rgrq5!G3~hSNmzA@qI56oz(X-(G@Na(Mmi1WDE1#Z1*GT z8ysO0k$dn5LA{CJYac|k)H%i!5t)GXk0ahWE1u{ISDH!fSAVh1r0?HHV80&rkDJ61 z_4j1YfG@&4UQ!hH?=ydb>{^Mh+3pni+iX8iw9@_?aC?BSgPcB&z*JN$E?PU z7UAI4b<@$T=22rJ>p_?EA3H;8Z>>|=>-}e}wRZ#Bt_NGX7sgC-wVTx9j&Sk9(1Ee~?|Q&@B4=Ef#$~{uY%#w+M%v z@&~zEx2_g_-Fkvo^X;c7@-vS41hQKqX0hFDi^_YUJ)7uK`$FJUK3zOs0pZt)Wz4T6 zT)urRQMY{^m#f=hM=v=P%5v@)jxDG2e;!Xb}xw#fLu( zB)g%oQ}K;t+*t4`zVV&{_IX4nb;&0h-(?Apzl{B?B)dc6F6P&; z-+M`ZN>sAHZS3y}-CvJAy1yQ;u)lq5e}L?K!uZ)p8z6ez1b+wF+w1VC(_4QpZJ0vK62jd=vT&?GmQq6mX>jk1MTD-{k zD#8yGZ!!Ko#(w~M561n3@V^v)4Sgj1{!IL8*Kb7ExPE6pzNn9^;ug^w^@y5JxTcTW zk?NHDoIQws;TO&NL4@Cq@AByL7zH{GX<>`&C?8pbr1<%kjMl;=uhnoM+& zYYx%Ht_-5T6lY<4wH{bo;O}rPBf8ABg6MKrIn(t_A7-l8W2MgBhM}}?UShdkmz6r- zf;3615ZAAee~Eos%W@6%64p%U_1X#-{{9^C zE^-AEUF-@Wy3*B#=qgt`qIbAD5?$u%LUgsO2hlaIUPN84K154g{fL&TI*-n^@rq)- zl8kCUJ|%9&_-a4SA>0br0_YE6|KvliuAe&y_m(JP{!ZfG5%;s*Mz-4uJ9S<>#JHV= zJ0hN9{yD;}a_u9!()Bv<`{DmB*1yO2519X$aHXzqiI%v&2YwImHLO3&asA4CE%6@+ zKd#GysU9nF;m`XiuC`o{bwE94#gX5IdDM-__ZnA!qN`nlfp3F(3}O99!hbHtGCv-A zbzV#+{BqY+(tjmp5r6;8*}%<4oLQ{Do%BD7MXX=S`a4-)L3)q)8|&AzejDp|lD>uf z2kW0_{a%uHkcYsl^?R4}A+C=R-*m+P8RTmHz9w9xJjMKJ_VY9I7l2pi=kMUv`S~xp zz9Xkc8R8<_z<#u$1O8P8A+Tp?->floNKpI#0qkQnZYAU@AKO^Ji}ZftRo1`B`gh>R z2K)~Ob-x`UE-^kB>lQ3R#dTOm<>?e8J^5wV%&JD5HXy*mF6fGOfrieZc&P5g0@!n}G;3C6!o zki)zScC#_h0`Mx%Wu!OYFLQMMF69^cb?ko!>4W7{Z2uhbX8Atz9}@2;zhM4b_Fv8Z z&X7J_o@f3d^eRtQuG0fhrw5CUvL*9jsN-$Ww*#-{KODTmPh$NP!XLqNiLOtBUd<p<&l1bT*CZv=v5w9QC(j&V;j-P>5o9J&gb12UtNc<@c1Xme!RTE z{(mRlF3nsA>fq1)|#r$mc=U_kc zNS`ZnnRi34)_oQ8Wu#v!*E0V%s_XBcxt{q=z^ij;JIT)!KTr4#axe5M|F02WDnDob z8{+SlXP7_F@myqoe~^BY)VMCTaJ?PId^^<5!D74Y#C&(Em+zn1i}^^>ca#H|kKy`! z1bEausQ=aeDRt)g==DGW^Y?*Q_2mP^yX`L!&9|ez2i|Qz#{5Ujf6DyVL@Vuj{l3}$ z3-bX~_inbgAX;e;W4=A=-AIhnm-waj0YnS!H?n*h%Wq-%Z00kV&t_a9@$2oYh;Fc# zvixC|KhE-hF#iJcFB9Er-%oVA{Q&ddGXFjEKQVufXl?NoqL+&`Kb4Q#;_HZBF7C*D zH|Bf!>GK;#ytZl#QRAwcSf0-Ec`VOi-p%|HqHB|u6Fpaar=N)Y82ho5_%p?KgICw> zIzP1!o|2p3SM9UykgNO8|FHfE(jSq#S^o;;YF{4)UjY13@ap>ch;XOmSB(1(^8L_X zW}Nibab|xt-WA!xUmq_N@;$&^4_^7}!?=EgYpqRYoSpax?KbAqfm7#47Rke94%@pR zSM^H?^X2UC9>NXLHnROz|A@$7jQ1k+YW)3-e}iyI+S|;(&-NdZJX!mK?Z0KaON_fh zdWU8R(C1+dQ1hItwFN&N{yPNdbyx)Jdy_s}i)MZh^!tIE$b1s(lbOE-dKG6b^KR1T zYKxgKWPCC6rNFB^Y-D~b>mO$Ru>gJkZ?NCPEI&#(m-Z3!pFpq9r7r{2emzrs3cT7k zKM-!Q_A78|ezlORedA%hF;LCFQVR;y^&x@0&fp7x?*m@#n|_2lC5JO^4CMQvpTW2k z#-$PNip*i0i~W@_uAFiA5bil`BjdI*?ghrZM0$s|kNE?{&()4I{v`0Kj{lbR)uhkX z&MOUYib*{o6A3obT_qJ*V5YEUR!3aikg|3k3{Z%XMV%INVppxY>Gq6F$74iw+pf?UzJ??t>DioI$6O-oyL@IG zWJG7rotvFSbVFB_D_oUm#AN5hWH_0HFZd)n8f`SR%paAmr~ypzG6L8LCu<^@6E&di z%+eN!ed_ISM$I5gj3d*L>#zeD1mKUYfC?qp;kTc3*=a)dQ%_|&_zH$Q9cf83)3WTD zX;0-aiw&K(VLmM<1r;R*COLAO@#7r}c$b*8TnDrCf%PZ-=RJ~CER?ACnf8jM`BL6N7Icl)61> zo?~XZg}9FICv=vP`Sa4UW;tf{Foc?K9@I+A1SL`Q&9+z-rY3kzaLk>Tlgd zP!hD^bK~bKyM?NnB`Zm4g7M3&%#19DvP&of;VxZGu#C@}%XcbA*)G(HP(KH!P-B)k z$`-eFm73r^;@MnB&cqzYEM=2hZ_wB3VXTb*+%{=`Xyl~L^(mKKT*udEP?lDqjS{(> z!0bIrT>RMZwBt)m9FH|~1y4bLje8a86sBkbS3yl=(-K&cqBU{Yn~=k`1jRmH(QY*> z;K*x2cJA2hv{{NGwA|ZdEujrRB3N>wVfe(({5X^p6G8L_!b8}6nXt_t7EH(ep7Vd4rv-2E1EJDq@8Kj|O7tuMv!Y9Lv1cJ&7=Kv)c$16b{<9Js2L1>PO zXcD>bBgUgb!7Su2cw4dxZljKZ_n{2Id5I(H=G9j0-itJwo`$?#ou?For&B7u51yda zDyP5$l@;t6j9;g?%W(>G7wa8l7OKJ2qR@0uo6Eb6nroD1wosciYOZC-_K=B#BE9W# zV@EzVFn)LvhNBwBPi<$cr6*0N{=vH5$19Nfj)Y0K>AG&UTKjeAP91&QcZbTG+6NS# z=lzI$DLQ(v6(=u#u+^V@(9pao*@~z=3fYT%bS&7aw)e3j0;zn_20wl!2-mOC**={tQK5ZR>KSbwecp6pN3DcFF#Td`5T7L|KmUH$q3-P zl|&sV0I8t2R|Ck~;GgcFAOlO&11PXPR6zpaZW6WWhO2Rsg$x6Egogqk=uYJCAJ|^J z5`xG;N0De4)$rCeo?iJZgBG!1Gj)P2K^BAb2N1e$J|V^fG?4U;5cIwQeX)PH|C}Th z_1KCxfe&hwFHS}qI>!8<>r59ED>2nd9YOuo?x_3sQ<7>!p?v^VwFj+IgK3BQ3-m3a z!>SJ|XDNKFCYOr+(0ozU)}WBRNTam1s8s7vB-c}gwgF>&La%C{(LwEV`bzr(2l!vu z-Y+Rw|B52?6DUq!Q;vQTC+ieW;VJqCbd2RQ%~;5~7|*efF`v`AmBQ`5^s(9*?atu$ z(+e;6qLhl>G_Rr$^;^^zG=MJc7)V(g2Z28XJ{YAN*U!H0pO=$*1C z@Zq2lplHx2Qg_9HMuWzH#)8H{A5VL#6G2I6PXK>{8kRkQHm50|6pS|=d?uAvJHQ>_ zbHF)e!Zr^)4?G{V5VROR7Q+YU1>gnHEkSz;+ME}H7g7@VX}uKdD5Kbo<@8cjC8!GW za*8QhL4}1Y$tz|h;*2HH+v74D$7M!XFC%hYBh=R47F zCmo62NgWpLrprBdL$@39Zs1=9y#{(6e*S>Ib>Ma2Z-Vy1Z$0F9VBZJY58b<<18Bbw zIt)4j`Wxsd=mXF(&~a*f?qe#^Kf}CFgU-^yqH~}Npo^eOpzoo-O3{n2fv(d(U;K$2 z&YPe{dT61Go?b}or7CZx?($~4ioDrM(5@mY8@0}#O)Uz9ttX2q>WB6Kvs4~Ta+`GMK8``|9o*Cb2y)Y&I!t4`|@&uDPpx7f5o)wVs^Hy zn7y!}gk^2~HQHq?rgSNDuBl=Rwk?Ca0{Yb~cH?ir*MYBxZUgJGzM56zJXI?`RE4uq zt#qb6$^*#%U(g({UUXdT4eCRiy#~?@Z6atYCwnrrN!naV4aZ~PwiSD}9m_SeyV1MNNFd%){xvGOKpFKyKK zVvM(FCuphiHu&4H?}M-XbXj?qs?-DE2Pw@sgud^C4#R!~KK}-O6u1w-k3oNop7%OV z)!N6H-wDk5B={+;_Y~H80dv0yx(;fDOl*#q4)SI@HE(uY?FkwLdYs+VV_2{n3myww zEOZk=vw+QI$Cc;ME&?xsyo^0*=}tbreW{7{r5`Q*sE=g;76m>Wd^q?B*hhdzLyo4|zN1L7jG}r=EUmS~(QeCVdfqYy@>n`%83$ZE z@bMUD0(G=J0X_vh1^SuL&xGs%&4DhHhWX}U4hx9+6rxJoC|il88YK=i8Z;I(j(nAc zY@t>RDg&)xPwK1Kx7sSUMccqGD7{dN`=b7afCivF5PTr`L*Ngi9zTM59FBVYDC+TJ z&<{b~9s(XgsuBen4vIz{ABj3X3KWYv9*e$lXmc738Uq>&8VB2W*b+fWpb79h5&Q|z z6pS+!W2B%x9plabcfg(wJ_oj^VatR*3-UbBGiW9 z=d=fR&Yz&G!yWV{XfNcqz~6%HZSc1t*Tc@~9rSw#e)gfgANGTwLm1-_#(p3A!{CR( zkHG#n@T1@#;BGn%Is-b3JL){>ThMp7!>-~Ey9T;}d+a9ew_CX1nsDba7Obo6nx^7~ zt%2(d&lX_3Ut%Zo`&``j5!_hbjVLaeiH3;;M0MBibd#iz~{0_dKM^~<>=2q z=fvG!0(u_zd>Qys@MWOopcSB1p!J{)plbF<jS5!VI6KA1(XK($5>K>ZiL7%=g_LS%Y76Yj&;- z{q~2g%RaBF-*hW5ncD)BYgxSLWJ+~4WQqsz@+0wKf-6d&beWcSi2Ra8mpTi@L+Wly z#Y52}H&B?X>T8<tJbZ6CEtw)kIeUBen{h6o>shG-|_X zwNL~}ZTQ07I*$57zi1oTHqTeg$g(d_ZKxGWOQZ$ut)i_&DtT5OVwS5mtaPiq-JN-Z zgVcsKN@0OPX!tYNBlx`!R8^mdtrq^P>L;UFRlmDAVrIn61y+_$aD^RDyi1Tb{lq(N zx*3>USvsi|PWW!QBb#n;SYj*KZHQ~a-F1$e+zR(|cRvd7RSuqVCom>w46ChJ&A? z3!2t^dlr-&m~Z)?MZ_;n&kk38&Qmf$+J!w zISsi}=aP7S0pBCEs$LWK1BasxFU_vyt>5e)DEE9kQy9Rg_%kXm{i!i*Uj#l8p8>4A zly05ZT=+B>ipJeTQ(SP=e!dpN|++hwtO?-Pl;ZrU_3QbE0mu3^u>M zmF9@vsGM}uoYHMuQLpj5LNvqn#k)@wQlwsozM@oX3O(g9nQ|0^SNE81Sd<4>2|$GX z)}rc4%&-zOEVth%pLFvcmRyN|@L=I$`n1UtOHZps5Spj(-}lGU)m*(NW%IO%{ki!q z>`L>7Az}F>mQ20Fc17KNzl1Bkg1bYS*O#|TfLjbMvZdwLh>aE>FPW#*Ae_yxeL{un zCBkmawYcV6TgZ7)9*2bm7MAD5->vMt4T53{biO?VHLs0$f7MbRi`s&JL&m=W3qR8i z8^neg3HFIorwwBX`~}YJY$6-L%R&!DV2UpEP%wVE{Vckb+0Tf#abdw3%GHHkXip36 zA^Szf-;?$WVj|)LQ}ja#!V{&=M~+%)zgTWRCv?Ip+~9gCxQLTiZ~;$qJ>K&=Kg~0C zv{~`oPxjL|o|sf~c6t%T3Qp{<9PRCA! z9XE66+`5qcT|O$eUo0-T$QJ8jt#?>l!y8I#XFajt2<%LOQE5L12Y2eVTyDQ~eqL4m2_%cK zwYpV3c%C6A?(C}a!wUPA&{H9QHV=m!`VzcH*e?~d6Qf+Lv|qw>L<$QF_H~grlwyMi z%a~4Sz0A9Bd?C5!Uv}RoaP69ZsfCC!Fy1LKhgRFE-X39dn*41g(kA7er%-7>`|~`? zwTg;?n<&1q!hQxtqs5W0u%Cv)?B{-Kh|`Ye#b3!99Q>g8KRCGa^zgW>`DvLMvuv~Q zU7gLrzbAFfdSH53H+;`;OXt7s=ir+@)0*SRwdH0Hu}yzinI3k3qJzrW?1Iu-~FU4kMLuoI&2q z^cN)L4%8F!WZ3&L?tf1BgOItO!4elOa6vR);*!8WRETDRbH^Fr9G@j{{U}Gu`H~ki z3Qfg2%D@X%#6;lw(^}a1xEm#Ihs3=iaj#4Jd1?On`*m zC4Ch75P#!BgM^$G9-&a^qnK}ul;b5&5&Uv-x|Fje&zHPN@LAz63O*xz1IDYt_*<3k zq5NymH{ka@tm`P`wvazkczh%16UB_jzoh-DwBM9^Qcaw$nmBylEc|qnat~pDoO(;S zzqF53&2dIc{VxSBiY7?;35jz`+ybdz1df2wQYo(lPla5g@;Ii2Z-dPD;cek>1Ra&~ zNAQ=5{rX(?J0bghC+(#1b;MGDX7&%%Oni69JRgF=`8b25JzC)VQLMC&)69HJlyb7f zr%QZ^z&}pq(!NaKXNT7ao*upx|-cR%IWYk8F9># zat=6;%dfzB+&9bqJ0IVD@`3cB7AkUI=2IL^fIa02W_TNZ(J>(Pcw^hi;Q+7i}?V&e>?3}t+ z@b{)1f}XGAh>+izatt!x2VUP(!T&AvU-?{?xN8#EC~-{I#kR6u_C|eei+=rO-3$Yd z#kh}fJNQUZ=Mz&#L+0!IrIdNy=IdJ`g>5%z&PAM;d%;RO&-Qy{1Ag98`X0-49{82CKk{vrK-4wgp_$5<}!);mzdH6^^DKsK`9T090Yl&l$=RzZx8OAgvSn!`4lZdA{L!j5wA#eUO*PU7qJc z?jraqXE5}s(D#w@V9AF|K3?)<$)^B68~EwS5AMIK(3d%T3f_5Ch~$HCE_gg6iQku9 z3H}7f95DW2i|OwOzE2K`x4~bk%*QM#7eFq9zL3OWt-yKHHR-oe$UfwQeB$G@#k+vVw-fT)2KjO5Q^CgwxeZO0 zxM?B}E1a_>j^{PU6-k-rGxzrbe`kR26!_Q3l;A6zanN(W({az+z%zkQ1z)H>EaG1- z`C5F#&(~Wo@n1_kzxO%*mhe~R)N!xc@aJ=FaDVc6w$sda*L~t1?L4X%?q!}|4+?!( zeA{j2_2ZHc*UUN`BkUt+H2m;<#Tvvs%fVNmuCEq(a=o}l@T`zL&2Se<1P4W&WN32Y|j8xb;h}O1%sHZJ4hWdC&*;4#)$(ADxBF zsE?HKuV$ei;!oHf7Wr|#c$DB*i^ni?Ui_V$ihe1O*Mg^m7lP+Wd7Vn|=gd3_`2c}Czz(Ix4J Zzo&UWm(V|jceN>dBQH@a$q!`y{0FLBT5bRU literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/FILES.BBS b/SOURCE/UNUSED/FILES.BBS new file mode 100644 index 0000000..ee3b5f1 --- /dev/null +++ b/SOURCE/UNUSED/FILES.BBS @@ -0,0 +1,63 @@ +The Renegade BBS Batch Download File Listing + +RG0930F .ZIP -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + The Renegade Bulletin Board System + v09-30.6 FULL INSTALL!! + + Download This To Start You Own BBS!! + + -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +ACTIONS .ASC 1 +ACTIONS .LST 1 +ARFLAGS .ASC 1 +AUTO .ASC 1 +BATCHUL0.ASC 1 +BBSEH .ASC 1 +BBSET .ASC 1 +BBSLEM .ASC 1 +BBSLET .ASC 1 +BBSLIST .SCR 1 +BBSME .ASC 1 +BBSMN .ASC 1 +BBSNH .ASC 1 +BBSNT .ASC 1 +BULLET1 .ASC 1 +BULLET2 .ASC 1 +BULLET3 .ASC 1 +COLOR .ASC 1 +FILEHN .ANS 1 +FILEHN .ASC 1 +FILEHP .ANS 1 +FILEHP .ASC 1 +FSHELP .ASC 1 +LASTH .ASC 1 +LASTM .ASC 1 +LASTT .ASC 1 +MAIN .ASC 1 +MAIN25 .ASC 1 +MAIN250 .ASC 1 +MAIN255 .ASC 1 +MENUCMD .ASC 1 +NEWINFO .ASC 1 +NODELH .ASC 1 +NODELM .ASC 1 +NODELT .ASC 1 +PRELOGON.ANS 1 +PRELOGON.ASC 1 +PRHELP .ASC 1 +PROTLIST.ASC 1 +PSEUDOS .ASC 1 +QUOTEFTR.ANS 1 +QUOTEFTR.ASC 1 +QUOTEHDR.ANS 1 +QUOTEHDR.ASC 1 +SYSTEM .ASC 1 +TELEHELP.ASC 1 +TIMEDOUT.ANS 1 +TIMEDOUT.ASC 1 +USERH .ASC 1 +USERM .ASC 1 +USERT .ASC 1 +YOURINFO.ASC 1 + diff --git a/SOURCE/UNUSED/FSHELP.ASC b/SOURCE/UNUSED/FSHELP.ASC new file mode 100644 index 0000000..53d83c4 --- /dev/null +++ b/SOURCE/UNUSED/FSHELP.ASC @@ -0,0 +1,10 @@ +|08 +^1Press ^3ENTER ^1to get a blank line and press ^3/ +^1and one of the following command keys. + + ^1(^3^1)Continue message + ^1(^3A^1)bort message ^1(^3C^1)lear message + ^1(^3F^1)ile attach ^1(^3M^1)CI codes Yes/No + ^1(^3Q^1)uote message ^1(^3S^1)ave message + ^1(^3T^1)itle change ^1(^3U^1)pload message +|08^1 diff --git a/SOURCE/UNUSED/FSTR.PAS b/SOURCE/UNUSED/FSTR.PAS new file mode 100644 index 0000000..e94ab7b --- /dev/null +++ b/SOURCE/UNUSED/FSTR.PAS @@ -0,0 +1,136 @@ +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S-,V-} + +unit fstr; + +interface + +procedure read_in_fstrings; + +implementation + +uses + common; + +procedure read_in_fstrings; +var + lang : text; + WhichNum : String; + WhichStr : Longint; + InString : String; +begin + if not exist(general.datapath+'renegade.lng') then + begin + sysoplog('Bad or missing language file. Obtain a new one from the distribution package.'); + writeln ('Bad or missing language file. Obtain a new one from the distribution package.'); + halt; + end; + + fillchar(fstring,sizeof(fstring),#0); + + assign(lang,general.datapath+'renegade.lng'); + reset(lang); + while not eof(Lang) do begin + + readln(lang,InString); + + if InString[1] = '[' then begin + + + WhichNum := Copy(InString,Pos('[',InString)+1,Pos(']',InString)-2); + WhichStr := StrToInt(WhichNum); + if Pos(']',InString) = Length(InString) then InString := '' + else InString := Copy(InString,Pos(']',InString)+1,Length(InString)); + + + with fstring do begin + case WhichStr of + 1: anonymous := InString; + 2: note[1] := InString; + 3: note[2] := InString; + 4: lprompt := InString; + 5: echoc := InString[1]; + 6: yourpassword := InString; + 7: yourphonenumber := InString; + 8: engage := InString; + 9: endchat := InString; + 10: wait := InString; + 11: pause := InString; + 12: entermsg1 := InString; + 13: entermsg2 := InString; + 14: newscan1 := InString; + 15: newscan2 := InString; + 16: newuserpassword := InString; + 17: automsgt := InString; + 18: autom := InString[1]; + 19: shelldos1 := InString; + 20: readingemail := InString; + 21: chatcall1 := InString; + 22: chatcall2 := InString; + 23: shuttleprompt := Instring; + 24: namenotfound := Instring; + 25: bulletinline := Instring; + 26: protocolp := Instring; + 27: listline := Instring; + 28: newline := Instring; + 29: searchline := Instring; + 30: findline1 := Instring; + 31: findline2 := Instring; + 32: downloadline := Instring; + 33: uploadline := Instring; + 34: viewline := Instring; + 35: nofilecredits := Instring; + 36: unbalance := Instring; + 37: ilogon := Instring; + 38: gfnline1 := Instring; + 39: gfnline2 := Instring; + 40: batchadd := Instring; + 41: addbatch := Instring; + 42: readq := Instring; + 43: sysopprompt := Instring; + 44: default := Instring; + 45: newscanall := Instring; + 46: newscandone := Instring; + 47: chatreason := Instring; + 48: quote_line[1] := Instring; + 49: quote_line[2] := Instring; + 50: userdefques[1] := Instring; + 51: userdefques[2] := Instring; + 52: userdefques[3] := Instring; + 53: userdefed[1] := Instring; + 54: userdefed[2] := Instring; + 55: userdefed[3] := Instring; + 56: continue := Instring; + 57: waitfortelnet := Instring; + 58: stringtwo := Instring; + 59: AskInvisibleLoginStr := Instring; + 60: cantemail := Instring; + 61: sendemail := Instring; + 62: nodenotavail := Instring; + 63: massemail := Instring; + 64: massemailall := Instring; + 65: nonetmail := Instring; + 66: isnetmail := Instring; + 67: nomailwaiting := Instring; + 68: sorryreply := Instring; + 69: FileNewScan := Instring; + 70: ScanCharCheck := InString; + 71: ShowBulletins := InString; + 72: QuickLogon := InString; + 73: LogonAsNew := InString; + 74: MsgHeader := InString; + 75: MsgAreaHeader := InString; + 76: FileAreaHeader := InString; + 77: EmailSenderHeader := InString; + 78: VoteListTopicsHeader := InString; + 79: votetopicresultheader := InString; + 80: FileBoardNameHeader := InString; + 81: syschathelp := InString; + end;{case} + end; + end;{if = [} + end;{while} + close(lang); +end; + + +end. diff --git a/SOURCE/UNUSED/FTS-0001.016 b/SOURCE/UNUSED/FTS-0001.016 new file mode 100644 index 0000000..93908d5 --- /dev/null +++ b/SOURCE/UNUSED/FTS-0001.016 @@ -0,0 +1,1239 @@ +Document: FTS-0001 +Version: 016 +Date: 30-Sep-95 + + + + + A Basic FidoNet(r) Technical Standard +| Revision 16 + Formerly known as FSC001, FSC-0001 +| Randy Bush, Pacific Systems Group +| September 30, 1995 + + + + +Status of this document: + + This FTS (FidoNet(r) Technical Standard) specifies a standard for + the FidoNet community. FidoNet nodes are expected to adopt and implement + this standard. Distribution is subject to the restrictions stated in the + copyright paragraph below. + + Fido and FidoNet are registered marks of Tom Jennings and Fido Software. + + Copyright 1986-95, Randy Bush. All rights reserved. A right to + distribute only without modification and only at no charge is granted. + Under no circumstances is this document to be reproduced or distributed + as part of or packaged with any product or other sales transaction for + which any fee is charged. Any and all other reproduction or excerpting + requires the explicit written consent of the author. + + + A. Introduction + + FidoNet has grown beyond most peoples' fantasies, and new FidoNet + implementations are appearing regularly. Unfortunately, the scattered + nature of the documentation and absence of clear testing procedures have + made implementation difficult. FidoNet, in its desire to promote and + encourage FidoNet implementations, suggested a project to create a + technical standard for FidoNet. The author did not design or specify + the data formats or protocols, only attempted to document them. + + This document defines the data structures and communication protocols + which a FidoNet implementation must provide. The implementor of FidoNet + compatible systems is the intended audience of this document. + + The layered metaphor of the ISO Open Systems Interface reference model + has been used to view FidoNet from a standard perspective. As with most + prospective ISO/OSI descriptions, FidoNet does not always make this + easy. + + The content of this document was gleaned from the references given at + the end. + + Please direct technical comments and errata to +| Randy Bush randy@psg.com +| Pacific Systems Group + 9501 S.W. Westhaven Drive + Portland, Oregon US-97225 +| + + 1. Basic Requirements for a FidoNet Implementation + + Compatibility is a set of abilities which, when taken as a whole, make + it safe to list a net or node in the FidoNet nodelist. In other words, + if another node should attempt contact, does it have a reasonable + chance of successful communication? This is a social obligation, as + the calling system pays money for the attempt. Conversely, an + implementation should be able to successfully contact other systems, + as life is not a one-way street. + + A FidoNet implementation must be able to call other nodes and transfer + messages and files in both directions. This includes pickup and poll. + A FidoNet implementation must be able to accept calls from other nodes + and transfer messages and files in both directions. This includes + pickup. + + FidoNet implementations must be able to receive and process the FidoNet + format nodelist, and transfer nodelists to other nodes. A companion + document, FTS-0005, defines the FidoNet format nodelist and how to + interpret and process it. + + A FidoNet implementation must route messages which do not have files + attached through net hosts as shown in a FidoNet format nodelist. + + + 2. Levels of Compliance + + This documents represents the most basic FidoNet implementation. A + future document will define well tested extensions which are optional + but provide sufficient additional function that implementors should + seriously consider them. SEAdog(tm), from System Enhancement + Associates, is an excellent example of such an extended FidoNet + implementation. + + + 3. The ISO/OSI Reference Model (cribbed from "Protocol Verification via + Executable Logic Specifications", D. P. Sidhu, in Rudin & West) + + In the ISO/OSI model, a distributed system consists of entities that + communicate with each other according to a set of rules called a + protocol. The model is layered, and there are entities associated + with each layer of the model which provide services to higher layers + by exchanging information with their peer entities using the services + of lower layers. The only actual physical communication between two + systems is at the lowest level. + + Several techniques have been used in the specification of such + protocols. A common ingredient in all techniques is the notion of the + extended finite state automata or machine. Extensions include the + addition of state variables for the storing of state information about + the protocol. The state of an automation can change as a result of + one of the following events: + + o Request from an upper network layer for service + + o Response to the upper layer + + o Request to the lower network layer to perform a service + + o Response from the lower layer + + o Interaction with the system and environment in which the protocol is + implemented (e.g. timeouts, host operating system aborts, ...) + + A protocol specification, in a large part, consists of specifying + state changes in automata which model protocol entities and in + describing the data which they exchange. + + For historical reasons, the term packet is used in FidoNet to + represent a bundle of messages, as opposed to the more common use as a + unit of communication, which is known as a block in FidoNet. + + + 4. Data Description + + A language specific notation was avoided. Please help stamp out + environmental dependencies. Only you can prevent PClone market + dominance. Don't panic, there are rectangular record layouts too. + + (* non-terminals *) + UpperCaseName - to be defined further on + + (* literals *) + "ABC" - ASCII character string, no termination implied + nnH - byte in hexadecimal + + (* terminals *) + someName - 16-bit integer, low order byte first (8080 style) + someName[n] - field of n bytes + someName[.n] - field of n bits + someName(n) - Null terminated string allocated n chars (incl Null) + someName{max} - Null terminated string of up to max chars (incl Null) + + (* punctuation *) + a b - one 'a' followed by one 'b' + ( a | b ) - either 'a' or 'b', but not both + { a } - zero or more 'a's + [ b ] - zero or one 'b' + (* comment *) - ignored + + (* predeclared constant *) + Null = 00H + + + + 5. Finite State Machine Notation + + .-----+----------+-------------------------+-------------------------+-----. + |State| State | Predicate(s) | Action(s) | Next| + | # | Name | | | St | + |-----+----------+-------------------------+-------------------------+-----| + | fnn*| | | | | + `-----+----------+-------------------------+-------------------------+-----' + + State # - Number of this state (e.g. R13). + f - FSM initial (Window, Sender, Receiver, ...) + nn - state number + * - state which represents a lower level protocol which + is represented by yet another automation. + + State Name - Descriptive name of this state. + + Predicate(s) - Conditions which terminate the state. If predicates are + non-exclusive, consider them ordered. + + Action(s) - Action(s) corresponding to predicate(s) + + Next State - Subsequent state corresponding to predicate(s) + + Ideally, there should be a supporting section for each state which + should give a prose description of the state, its predicates, actions, + etc. So much for ideals. + + + B. Application Layer : the System from the User's View + + The application layer is outside the domain of a FidoNet standard, as it + is the layer that the user's application sees as opposed to what FidoNet + sees. In recent months, there has been sufficient confusion and + discussion about the format of data at this level to warrant the + description of the data structure, the message as it is stored by Fido, + SEAdog, and Rover. + + Perfectly valid FidoNet systems may be implemented whose stored messages + differ greatly from this format. + + + 1. Application Layer Data Definition : a Stored Message + + Stored Message + + Offset + dec hex + .-----------------------------------------------. + 0 0 | | + ~ fromUserName ~ + | 36 bytes | + +-----------------------+-----------------------+ + 36 24 | | + ~ toUserName ~ + | 36 bytes | + +-----------------------+-----------------------+ + 72 48 | | + ~ subject ~ + | 72 bytes | + +-----------------------+-----------------------+ + 144 90 | | + ~ DateTime ~ + | 20 bytes | + +-----------------------+-----------------------+ + 164 A4 | timesRead (low order) | timesRead (high order)| + +-----------------------+-----------------------+ + 166 A6 | destNode (low order) | destNode (high order) | + +-----------------------+-----------------------+ + 168 A8 | origNode (low order) | origNode (high order) | + +-----------------------+-----------------------+ + 170 AA | cost (low order) | cost (high order) | + +-----------------------+-----------------------+ + 172 AC | origNet (low order) | origNet (high order) | + +-----------------------+-----------------------+ + 174 AE | destNet (low order) | destNet (high order) | + +-----------------------+-----------------------+ + 176 B0 | destZone (optional) | destZone (optional) | + +-----------------------+-----------------------+ + 178 B2 | origZone (optional) | origZone (optional) | + +-----------------------+-----------------------+ + 180 B4 | destPoint(optional) | destPoint(optional) | + +-----------------------+-----------------------+ + 182 B6 | origPoint(optional) | origPoint(optional) | + +-----------------------+-----------------------+ + 184 B8 | replyTo (low order) | replyTo (high order) | + +-----------------------+-----------------------+ + 186 BA | Attribute (low order) | Attribute (high order)| + +-----------------------+-----------------------+ + 188 BC | nextReply (low order) | nextReply (high order)| + +-----------------------+-----------------------+ + 190 BE | text | + ~ unbounded ~ + | null terminated | + `-----------------------------------------------' + + Message = fromUserName(36) (* Null terminated *) + toUserName(36) (* Null terminated *) + subject(72) (* see FileList below *) + DateTime (* message body was last edited *) + timesRead (* number of times msg has been read *) + destNode (* of message *) + origNode (* of message *) + cost (* in lowest unit of originator's + currency *) + origNet (* of message *) + destNet (* of message *) + destZone (* of message *) + origZone (* of message *) + destPoint (* of message *) + origPoint (* of message *) + replyTo (* msg to which this replies *) + AttributeWord + nextReply (* msg which replies to this *) + text(unbounded) (* Null terminated *) + + DateTime = (* a character string 20 characters long *) + (* 01 Jan 86 02:34:56 *) + DayOfMonth " " Month " " Year " " + " " HH ":" MM ":" SS + Null + + DayOfMonth = "01" | "02" | "03" | ... | "31" (* Fido 0 fills *) + Month = "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" | + "Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec" + Year = "01" | "02" | .. | "85" | "86" | ... | "99" | "00" + HH = "00" | .. | "23" + MM = "00" | .. | "59" + SS = "00" | .. | "59" + + AttributeWord bit meaning + --- -------------------- + 0 + Private + 1 + s Crash + 2 Recd + 3 Sent + 4 + FileAttached + 5 InTransit + 6 Orphan + 7 KillSent + 8 Local + 9 s HoldForPickup + 10 + unused + 11 s FileRequest + 12 + s ReturnReceiptRequest + 13 + s IsReturnReceipt + 14 + s AuditRequest + 15 s FileUpdateReq + + s - need not be recognized, but it's ok + + - not zeroed before packeting + + Bits numbers ascend with arithmetic significance of bit position. + + + Message Text + + Message text is unbounded and null terminated (note exception below). + + A 'hard' carriage return, 0DH, marks the end of a paragraph, and must + be preserved. + + So called 'soft' carriage returns, 8DH, may mark a previous + processor's automatic line wrap, and should be ignored. Beware that + they may be followed by linefeeds, or may not. + + All linefeeds, 0AH, should be ignored. Systems which display message + text should wrap long lines to suit their application. + + If the first character of a physical line (e.g. the first character of + the message text, or the character immediately after a hard carriage + return (ignoring any linefeeds)) is a ^A (, 01H), then that + line is not displayed as it contains control information. The + convention for such control lines is: + o They begin with ^A + o They end at the end of the physical line (i.e. ignore soft s). + o They begin with a keyword followed by a colon. + o The keywords are uniquely assigned to applications. + o They keyword/colon pair is followed by application specific data. + + Current ^A keyword assignments are: +| o TOPT - destination point address + o FMPT - origin point address + o INTL - used for inter-zone address + + + File Specifications + + If one or more of FileAttached, FileRequest, or FileUpdateReq are + asserted in an AttributeWord, the subject{72} field is interpreted as + a list of file specifications which may include wildcards and other + system-dependent data. This list is of the form + + FileList = [ FileSpec { Sep FileSpec } ] Null + + FileSpec = (* implementation dependent file specification. may + not contain Null or any of the characters in Sep. *) + + Sep = ( " " | "," ) { " " } + + + There are deviations from and additions to these specifications + + 1 - Fido does not necessarily terminate the message text with a Null, + but uses an empty line (0DH 0AH 0DH 0AH). Some Fido utilities + use an EOF (1AH). + + 2 - SEAdog zeros the message cost field when building a message. + + 4 - SEAdog uses a different format for dates, e.g. + + DateTime = (* a character string 20 characters long *) + (* SEAdog format Mon 1 Jan 86 02:34 *) + DayOfWk " " DayOfMo " " Month " " Year " " HH ":" MM Null + + DayOfWk = "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun" + DayOfMo = " 1" | " 2" | " 3" | ... | "31" (* blank fill *) + + + + 2. Application Layer Protocol : Schedules and Events + + At the application level, FidoNet imposes few protocol requirements. + An implementation must automatically originate and receive + node-to-node FidoNet connections. Some implementations do this in + 'windows' or time slots. Routing of messages will usually be + different and customizable for each scheduled window. + + The ability to send to and receive from any FidoNet listed node during + the Zone Mail Hour (eg. 9:00-10:00 UCT in Z1) is considered mandatory. + + Current implementations assemble all data for outbound connections at + the start of a window, and disassemble inbound data at the end of a + window. Due to performance considerations on small machines, this is + considered a valid optimization. Observe that it somewhat inhibits + dynamic routing. + + + C. Presentation Layer : the User from the System's View + + 1. Presentation Layer Data Definition : the Packed Message + + To conserve space and eliminate fields which would be meaningless if + sent (e.g. timesRead), messages are packed for transmission. As this + is a data structure which is actually transferred, its definition is + critical to FidoNet. A packed message has a number of fixed length + fields followed by four null terminated strings. + + While most of the string fields in a stored message are fixed length, + to conserve space strings are variable length when in a packet. All + variable length strings are all Null terminated, including especially + the message text. + + + Packed Message + + Offset + dec hex + .-----------------------------------------------. + 0 0 | 0 | 2 | 0 | 0 | + +-----------------------+-----------------------+ + 2 2 | origNode (low order) | origNode (high order) | + +-----------------------+-----------------------+ + 4 4 | destNode (low order) | destNode (high order) | + +-----------------------+-----------------------+ + 6 6 | origNet (low order) | origNet (high order) | + +-----------------------+-----------------------+ + 8 8 | destNet (low order) | destNet (high order) | + +-----------------------+-----------------------+ + 10 A | Attribute (low order) | Attribute (high order)| + +-----------------------+-----------------------+ + 12 C | cost (low order) | cost (high order) | + +-----------------------+-----------------------+ + 14 E | | + ~ DateTime ~ + | 20 bytes | + +-----------------------+-----------------------+ + 34 22 | toUserName | + ~ max 36 bytes ~ + | null terminated | + +-----------------------+-----------------------+ + | fromUserName | + ~ max 36 bytes ~ + | null terminated | + +-----------------------+-----------------------+ + | subject | + ~ max 72 bytes ~ + | null terminated | + +-----------------------+-----------------------+ + | text | + ~ unbounded ~ + | null terminated | + `-----------------------------------------------' + + Due to routing, the origin and destination net and node of a packet + are often quite different from those of the messages within it, nor + need the origin and destination nets and nodes of the messages within + a packet be homogenous. + + PakdMessage = 02H 00H (* message type, old type-1 obsolete *) + origNode (* of message *) + destNode (* of message *) + origNet (* of message *) + destNet (* of message *) + AttributeWord + cost (* in lowest unit of originator's + currency *) + DateTime (* message body was last edited *) + toUserName{36} (* Null terminated *) + fromUserName{36} (* Null terminated *) + subject{72} (* Null terminated *) + text{unbounded} (* Null terminated *) + + + + + + + + 2. Presentation Layer Protocol : a Mail Window + + .-----+----------+-------------------------+-------------------------+-----. + |State| State | Predicate(s) | Action(s) | Next| + | # | Name | | | St | + |-----+----------+-------------------------+-------------------------+-----| + | W0 | WindTop | 1 end of window reached | reset modem to not answr| exit| + | | | 2 time remains in window| ensure modem can answer | W1 | + |-----+----------+-------------------------+-------------------------+-----| + | W1 | WindIdle | 1 incoming call | | W2 | + | | | 2 receive-only mode | | W0 | + | | | 3 send-only mode | | W3 | + | | | 4 60-180 secs & no call | | W3 | + |-----+----------+-------------------------+-------------------------+-----| + | W2* | WindRecv | | (receive call R0) | W3 | + |-----+----------+-------------------------+-------------------------+-----| + | W3 | WindCall | 1 select outgoing call | increment try count | W4 | + | | | 2 no outgoing calls | | W0 | + |-----+----------+-------------------------+-------------------------+-----| + | W4* | WindSend | | (make call S0) | W5 | + |-----+----------+-------------------------+-------------------------+-----| + | W5 | WindMark | 1 call successful | remove node fr call list| W0 | + | | | 2 no connect | remove if try cnt > lim | W0 | + | | | 3 call failed | incr conn cnt, remove | W0 | + | | | | if con cnt > lim | | + `-----+----------+-------------------------+-------------------------+-----' + + + The length of the inter-call delay time at W1.4 is not critical. It is + important that this not be a constant, so two systems calling each other + do not incur infinite busy signals. Sophisticated implementations may + vary the inter-call delay depending on number of calls to be made, + window width, user specification, etc. + + + D. Session Layer Protocol : Connecting to Another FidoNet Machine + + A session is a connection between two FidoNet machines. It is currently + assumed to be over the DDD telephone network via modems. The calling + machine starts out as the sender and the called machine as the receiver. + The pickup feature is described by the sender and receiver changing + roles midway through the session, after the sender has transferred the + message packet and any attached files. Due to the lack of security in + the pickup protocol (danger of pickup by a fake node), a change in the + protocol may be expected in the near future. + + Once a connection has been established, each system should ensure that + the physical connection remains throughout the session. For physical + layers implemented through modems, this means monitoring the carrier + detect signal, and terminating the session if it is lost. + + Error detection at the physical layer should be monitored for both sent + and received characters. Parity, framing, and other physical errors + should be detected. + + Sender + + .-----+----------+-------------------------+-------------------------+-----. + |State| State | Predicate(s) | Action(s) | Next| + | # | Name | | | St | + |-----+----------+-------------------------+-------------------------+-----| + | S0 | SendInit | | dial modem | S1 | + |-----+----------+-------------------------+-------------------------+-----| + | S1 | WaitCxD | 1 carrier detected | delay 1-5 seconds | S2 | + | | | 2 busy, etc. | report no connection | exit| + | | | 3 voice | report no carrier | exit| + | | | 4 carrier not detected | report no connection | exit| + | | | within 60 seconds | | | + |-----+----------+-------------------------+-------------------------+-----| + | S2 | WhackCRs | 1 over 30 seconds | report no response | exit| + | | | 2 ?? s received | delay 1 sec | S3 | + | | | 3 s not received | send | S2 | + | | | | delay ??? secs | | + |-----+----------+-------------------------+-------------------------+-----| + | S3 | WaitClear| 1 no input for 0.5 secs | send TSYNCH = AEH | S4 | + | | | 2 over 60 seconds | hang up, report garbage | exit| + | | | and line not clear | | | + |-----+----------+-------------------------+-------------------------+-----| + | S4* | TSyncChk | 1 'C' or NAK (peeked at)| (XMODEM send packet XS1)| S5 | + | | | 2 over 2 seconds | eat noise, resend TSYNCH| S4 | + | | | 3 over 30 seconds | hang up report not Fido | exit| + |-----+----------+-------------------------+-------------------------+-----| + | S5 | CheckMail| 1 XMODEM successful | (Fido registers success)| S6 | + | | | 2 XMODEM fail or timeout| hang up, report mail bad| exit| + |-----+----------+-------------------------+-------------------------+-----| + | S6* | SendFiles| | (BATCH send files BS0) | S7 | + |-----+----------+-------------------------+-------------------------+-----| + | S7 | CheckFile| 1 BATCH send successful | | S8 | + | | | 2 BATCH send failed | hang up, rept files fail| exit| + |-----+----------+-------------------------+-------------------------+-----| + | S8 | TryPickup| 1 wish to pickup | note send ok | R2* | + | | | 2 no desire to pickup | delay 5 secs | exit| + | | | | hang up, rept send ok | | + `-----+----------+-------------------------+-------------------------+-----' + + Although the above shows the sender emitting only one TSYNCH, it is + recommended that a timeout of 5-20 seconds should initiate another TSYNCH. + The receiver should tolerate multiple TSYNCHs. + + In state S4, the phrase "peeked at" means that the character is not removed + from the buffer. Therefore when XS1 is started the proper character for + beginning the Xmodem transfer will be detected. + + Receiver + + The receiving FSM is given an external timer, the expiration of which + will cause termination with a result of 'no calls' (R0.2). + + .-----+----------+-------------------------+-------------------------+-----. + |State| State | Predicate(s) | Action(s) | Next| + | # | Name | | | St | + |-----+----------+-------------------------+-------------------------+-----| + | R0 | WaitCxD | 1 carrier detected | | R1 | + | | | 2 external timer expires| report no calls | exit| + |-----+----------+-------------------------+-------------------------+-----| + | R1 | WaitBaud | 1 baud rate detected | send signon with s | R2 | + | | | 2 no detect in ?? secs | hang up, report no baud | exit| + |-----+----------+-------------------------+-------------------------+-----| + | R2 | WaitTsync| 1 TSYNCH received | ignore input not TSYNCH | R3 | + | | | 2 60 seconds timeout | hang up, report not Fido| exit| + |-----+----------+-------------------------+-------------------------+-----| + | R3* | RecMail | | (XMODEM rec packet XR0) | R4 | + |-----+----------+-------------------------+-------------------------+-----| + | R4 | XRecEnd | 1 XMODEM successful | delay 1 second | R5 | + | | | | flush input | | + | | | 2 XMODEM failed | hang up, rept mail fail | exit| + |-----+----------+-------------------------+-------------------------+-----| + | R5* | RecFiles | | (BATCH rec files BR0) | R6 | + |-----+----------+-------------------------+-------------------------+-----| + | R6 | ChkFiles | 1 BATCH recv successful | delay 2 secs | R7 | + | | | 2 BATCH recv failed | hang up, report bad file| exit| + |-----+----------+-------------------------+-------------------------+-----| + | R7 | AllowPkup| 1 have pickup for sender| receiver becomes sender | S3* | + | | | 2 nothing to pickup | hang up, rept recv ok | exit| + `-----+----------+-------------------------+-------------------------+-----' + + + E. Transport Layer : ????? + + 1. Data Definitions + + 2. Transport Layer Protocol : Routing + + FidoNet does not necessarily send a message directly to its + destination. To reduce the number of network connections, mail to a + subset of the nodelist may be routed to one node for further + distribution within that subset. In addition, custom routing is + possible. Routing of a message is determined in one of three ways. + + o If there are files attached, then a message must be sent directly to + its destination. + + o Messages without attached files should be routed through the inbound + host of the destination node's subnet as specified by a FidoNet + format nodelist. + + o To prevent overloading of inbound hosts, a system should provide for + host routing to be disabled for a target node, or nodes. + + + F. Network Layer : the Network's View of the System, Routing and Packets + + + 1. Network Layer Data Definition : the Packet Header + + The packet contains messages in packed format to be transferred over + the net during a connection. As this data structure is transferred, + its definition is critical to FidoNet. + + A packet may contain zero or more packed messages. A packet without + messages is often generated as a poll packet. + + Every packet begins with a packet header. The fields of the packet + header are of fixed length. + + + Packet Header + Offset + dec hex + .-----------------------------------------------. + 0 0 | origNode (low order) | origNode (high order) | + +-----------------------+-----------------------+ + 2 2 | destNode (low order) | destNode (high order) | + +-----------------------+-----------------------+ + 4 4 | year (low order) | year (high order) | + +-----------------------+-----------------------+ + 6 6 | month (low order) | month (high order) | + +-----------------------+-----------------------+ + 8 8 | day (low order) | day (high order) | + +-----------------------+-----------------------+ + 10 A | hour (low order) | hour (high order) | + +-----------------------+-----------------------+ + 12 C | minute (low order) | minute (high order) | + +-----------------------+-----------------------+ + 14 E | second (low order) | second (high order) | + +-----------------------+-----------------------+ + 16 10 | baud (low order) | baud (high order) | + +-----------------------+-----------------------+ + 18 12 | 0 | 2 | 0 | 0 | + +-----------------------+-----------------------+ + 20 14 | origNet (low order) | origNet (high order) | + +-----------------------+-----------------------+ + 22 16 | destNet (low order) | destNet (high order) | + +-----------------------+-----------------------+ + 24 18 | prodCode | serialNo | + +-----------------------+-----------------------+ + 26 1A | | + | password (some impls) | + | eight bytes | + | null padded | + | | + +-----------------------+-----------------------+ + 34 22 | origZone (low) (opt) | origZone (high) (opt) | + +-----------------------+-----------------------+ + 36 24 | destZone (low) (opt) | destZone (high) (opt) | + +-----------------------+-----------------------+ + 38 26 | fill | + ~ 20 bytes ~ + | | + +-----------------------+-----------------------+ + 58 3A | zero or more | + ~ packed ~ + | messages | + +-----------------------+-----------------------+ + | 0 | 0 | 0 | 0 | + `-----------------------+-----------------------' + + + Packet = PacketHeader { PakdMessage } 00H 00H + + PacketHeader = origNode (* of packet, not of messages in packet *) + destNode (* of packet, not of messages in packet *) + year (* of packet creation, e.g. 1986 *) + month (* of packet creation, 0-11 for Jan-Dec *) + day (* of packet creation, 1-31 *) + hour (* of packet creation, 0-23 *) + minute (* of packet creation, 0-59 *) + second (* of packet creation, 0-59 *) + baud (* max baud rate of orig and dest, 0=SEA *) + PacketType (* old type-1 packets now obsolete *) + origNet (* of packet, not of messages in packet *) + destNet (* of packet, not of messages in packet *) + prodCode (* 0 for Fido, write to FTSC for others *) + serialNo (* binary serial number (otherwise null)*) + password (* session password (otherwise null) *) + origZone (* zone of pkt sender (otherwise null) *) + destZone (* zone of pkt receiver (otherwise null)*) + fill[20] + + PacketType = 02H 00H (* 01H 00H was used by Fido versions before 10 + which did not support local nets. The packed + message header was also different for those + versions *) + + prodCode = ( 00H (* Fido *) + | ... + | ??H (* Please apply for new codes *) + ) + + + The remainder of the packet consists of packed messages. Each packed + message begins with a message type word 0200H. A pseudo-message + beginning with the word 0000H signifies the end of the packet. + + + 2. Network Layer Data Description : a File with Attributes + + The BATCH protocol uses the MODEM7 filename and TeLink/XMODEM file + transfer protocols to transfer the file with attributes. + + When a file is transferred via FidoNet, an attempt is made to also + pass the operating system's attributes for the file such as length, + modification date, etc. FidoNet does this via a special prefix block + to the XMODEM file transfer using a protocol known as TeLink. As the + TeLink protocol relies on a modification to the XMODEM file transfer + protocol, it is documented at the data link layer level. + + The MODEM7 file name is redundant if there is also a TeLink block, in + which case the name may be taken from either or both. + + FileName as Sent + Offset + dec hex + .-----------------------------------------------. + 0 0 | fileName | + ~ 8 bytes ~ + | left adjusted blank filled | + +-----------------------+-----------------------+ + 8 8 | fileExt | + ~ 3 bytes ~ + | left adjusted blank filled | + `-----------------------------------------------' + + + 3. Network Layer Protocol : BATCH File Finite State Machines + + + BATCH File Sender + + .-----+----------+-------------------------+-------------------------+-----. + |State| State | Predicate(s) | Action(s) | Next| + | # | Name | | | St | + |-----+----------+-------------------------+-------------------------+-----| + | BS0*| MoreFiles| 1 more files to send | (MODEM7 FName send MS0) | BS1 | + | | | 2 no more files to send | | BS3 | + |-----+----------+-------------------------+-------------------------+-----| + | BS1 | CheckFNm | 1 MODEM7 Filename ok | (TeLink send file XS0) | BS2 | + | | | 2 MODEM7 Filename bad | report name send bad | exit| + |-----+----------+-------------------------+-------------------------+-----| + | BS2 | CheckFile| 1 TeLink send ok | | BS0 | + | | | 2 TeLink send bad | report file send bad | exit| + |-----+----------+-------------------------+-------------------------+-----| + | BS3 | EndSend | 1 rec NAK for next file | send EOT, report send ok| exit| + | | | 2 10 seconds no NAK | send EOT, report no NAK | exit| + `-----+----------+-------------------------+-------------------------+-----' + + When no files remain, the sender responds to the receiver's NAK with an + EOT. The EOT is not ACK/NAKed by the receiver. + + Filenames must be upper case ASCII. The data link layer uses "u" as a + control character. + + + BATCH File Receiver + + .-----+----------+-------------------------+-------------------------+-----. + |State| State | Predicate(s) | Action(s) | Next| + | # | Name | | | St | + |-----+----------+-------------------------+-------------------------+-----| + | BR0*| RecvName | | (MODEM7 FName recv MR0) | BR1 | + |-----+----------+-------------------------+-------------------------+-----| + | BR1 | CheckFNm | 1 MODEM7 no more files | report files recd ok | exit| + | | | 2 MODEM7 Filename ok | (TeLink recv file XR0) | BR2 | + | | | 2 MODEM7 Filename bad | report name recv bad | exit| + |-----+----------+-------------------------+-------------------------+-----| + | BR2 | CheckFile| 1 TeLink recv ok | | BR0 | + | | | 2 TeLink recv bad | report file recv bad | exit| + `-----+----------+-------------------------+-------------------------+-----' + + + G. Data Link Layer : Error-Free Data Transfer + + 1. Data Link Layer Data Definition : XMODEM/TeLink Blocks + + XMODEM transfers are in blocks of 128 uninterpreted data bytes + preceded by a three byte header and followed by either a one byte + checksum or a two byte crc remainder. XMODEM makes no provision for + data streams which are not an integral number of blocks long. + Therefore, the sender pads streams whose length is not a multiple of + 128 bytes with the end-of-file character (^Z for MS-DOS), and use some + other means to convey the true data length to the receiver (e.g. + TeLink file info block). + + Data blocks contain sequence numbers so the receiver can ensure it has + the correct block. Block numbers are sequential unsigned eight bit + integers beginning with 01H and wrapping to 00H, except that a TeLink + block is given sequence number 00H. + + For files which are attached to the mail packet, not the mail packet + itself, if the sending system is aware of the file attributes as they + are known to the operating system, then the first block of the XMODEM + transfer may be a special TeLink block to transfer that information. + This block differs in that the first byte is a SYN character as + opposed to an SOH, and it is always sent checksum as opposed to CRC. + Should the receiver be unwilling to handle such information, after two + NAKs (or "C"s), the sender skips this special block and goes on to the + data itself. + + + + XMODEM Data Block (CRC mode) + Offset + dec hex + .-----------------------------------------------. + 0 0 | SOH - Start Of Header - 01H | + +-----------------------------------------------+ + 1 1 | BlockNumber | + +-----------------------------------------------+ + 2 2 | BlockComplement | + +-----------------------------------------------+ + 3 3 | 128 bytes of | + ~ uninterpreted ~ + | data | + +-----------------------------------------------+ + 131 83 | CRC high order byte | + +-----------------------------------------------+ + 132 84 | CRC low order byte | + `-----------------------------------------------' + + + + XMODEM Data Block (Checksum mode) + Offset + dec hex + .-----------------------------------------------. + 0 0 | SOH - Start Of Header - 01H | + +-----------------------------------------------+ + 1 1 | BlockNumber | + +-----------------------------------------------+ + 2 2 | BlockComplement | + +-----------------------------------------------+ + 3 3 | 128 bytes of | + ~ uninterpreted ~ + | data | + +-----------------------------------------------+ + 131 83 | Checksum byte | + `-----------------------------------------------' + + + TeLink File Descriptor Block + Offset + dec hex + .-----------------------------------------------. + 0 0 | SYN - File Info Header - 16H | + +-----------------------------------------------+ + 1 1 | 00H | + +-----------------------------------------------+ data offset + 2 2 | FFH | dec hex + +-----------------------------------------------+ + 3 3 | File Length, least significant byte | 0 0 + +-----------------------------------------------+ + 4 4 | File Length, second to least significant byte | 1 1 + +-----------------------------------------------+ + 5 5 | File Length, second to most significant byte | 2 2 + +-----------------------------------------------+ + 6 6 | File Length, most significant byte | 3 3 + +-----------------------------------------------+ + 7 7 | Creation Time of File | 4 4 + | "DOS Format" | + +-----------------------------------------------+ + 9 9 | Creation Date of File | 6 6 + | "DOS Format" | + +-----------------------------------------------+ + 11 B | File Name | 8 8 + ~ 16 chars ~ + | left justified blank filled | + +-----------------------------------------------+ + 27 1B | 00H | 24 18 + +-----------------------------------------------+ + 28 1C | Sending Program Name | 25 19 + ~ 16 chars ~ + | left justified Null filled | + +-----------------------------------------------+ + 44 2C | 01H (for CRC) or 00H | 41 29 + +-----------------------------------------------+ + 45 2D | fill | 42 2A + ~ 86 bytes ~ + | all zero | + +-----------------------------------------------+ + 132 84 | Checksum byte | + `-----------------------------------------------' + + + + XMODEMData = XMODEMBlock (* block of data with header and + trailer *) + | TeLinkBlock (* TeLink File Descriptor Block *) + | ACK (* acknowledge data received ok *) + | NAK (* negative ACK & poll 1st block *) + | EOT (* end of xfer, after last block *) + | "C" (* 43H *) + + XMODEMBlock = SOH (* Start of Header, XMODEM Block *) + blockNumber[1] (* sequence, i'=mod( i+1, 256 ) *) + blockCompl[1] (* one's compl of BlockNumber *) + data[128] (* uninterpreted user data block *) + (CRC | Checksum) (* error detect/correction code *) + + TeLinkBlock = SYN (* File Info Header *) + 00H (* block no, must be first block *) + FFH (* one's complement of block no *) + fileLength[4] (* length of data in bytes *) + CreationTime[2] (* time file last modified or zero *) + CreationDate[2] (* date file last modified or zero *) + fileName(16) (* name of file, not vol or dir *) + 00H (* header version number *) + sendingProg(16) (* name of program on send side *) + crcMode[1] (* 01H for CRC 00H for Checksum *) + fill[87] (* zeroed *) + Checksum (* error detect/correction code *) + + ACK = 06H (* acknowledge data received ok *) + NAK = 15H (* negative ACK & poll 1st block *) + SOH = 01H (* start of header, begins block *) + SYN = 16H (* start of TeLink file info blk *) + EOT = 04H (* end of xfer, after last block *) + + CRC = crc[2] (* CCITT Cyclic Redundancy Check *) + + Checksum = checksum[1] (* low 8 bits of sum of data bytes + using unsigned 8 bit arithmetic *) + + CreationDate = year[.7] (* 7 bits, years since 1980, 0-127 *) + month[.4] (* 4 bits, month of year, 1-12 *) + day[.5] (* 5 bits, day of month, 1-31 *) + + CreationTime = hour[.5] (* 5 bits, hour of day, 0-23 *) + minute[.6] (* 6 bits, minute of hour, 0-60 *) + biSeconds[.2] (* 6 bits, seconds/2, 0-29 *) + + + Note that the crcMode is always set to 01H in current implementations + as all TeLink/XMODEM implementations use the CRC method. Therefore, + it is always set to 01H by the sender, and is ignored by the receiver. + + + 2. Data Link Layer Protocol : XMODEM/TeLink Finite State Machines + + The protocol is receiver driven, the receiver polling the sender for + each block. If the receiver polls for the first block using a "C" + (43H) as the poll character, it would prefer to have the CRC-CCITT + polynomial remainder error detection code at the end of each block as + opposed to a one byte unsigned checksum. The sender will respond to + the "C" poll iff it can comply. If the sender chooses checksum as + opposed to CRC, it waits for the receiver to poll with NAK (15H). + Should the checksum method be preferable to the receiver, it polls + with NAK rather than "C". + + The sender returns an EOT instead of a data block when no data remain. + + Neither the sender nor the receiver should send the block or ACK/NAK + response while there is data being received. They should wait for the + line to settle, and possibly time out. + + It is suggested that one's input buffer be cleared immediately after + sending block or ACK/NAK response, before waiting for the response from + the other end. This clears any line garbage which occurred during + transmit. + + + XMODEM/TeLink Sender + + .-----+----------+-------------------------+-------------------------+-----. + |State| State | Predicate(s) | Action(s) | Next| + | # | Name | | | St | + |-----+----------+-------------------------+-------------------------+-----| + | XS0 | WaitTeLnk| 1 over 40-60 seconds | report sender timeout | exit| + | | | 2 over 2 tries | note TeLink block failed| XS1 | + | | | 3 NAK or "C" received | send TeLink, incr tries | XS0 | + | | | 4 ACK received | TeLink ok, set crc/cksm | XS2 | + |-----+----------+-------------------------+-------------------------+-----| + | XS1 | WaitStart| 1 over 40-60 seconds | report sender timeout | exit| + | | | 2 over 20 tries | report send failed | exit| + | | | 3 NAK received | set checksum mode | XS2 | + | | | 4 "C" recd, I can crc | set crc mode | XS2 | + | | | 5 "C" recd, I can't crc | | XS1 | + |-----+----------+-------------------------+-------------------------+-----| + | XS2 | SendBlock| 1 more data available | send next data block | XS3 | + | | | | as checksum or crc | | + | | | 2 last block has gone | send EOT | XS4 | + |-----+----------+-------------------------+-------------------------+-----| + | XS3 | WaitACK | 1 10 retries or 1 minute| report send failed | exit| + | | | 2 ACK received | | XS2 | + | | | 3 NAK (or C if 1st blk) | resend last block | XS3 | + |-----+----------+-------------------------+-------------------------+-----| + | XS4 | WaitEnd | 1 10 retries or 1 minute| report send failed | exit| + | | | 2 ACK received | report send successful | exit| + | | | 3 NAK received | resend EOT | XS4 | + `-----+----------+-------------------------+-------------------------+-----' + + + XMODEM/TeLink Receiver + + .-----+----------+-------------------------+-------------------------+-----. + |State| State | Predicate(s) | Action(s) | Next| + | # | Name | | | St | + |-----+----------+-------------------------+-------------------------+-----| + | XR0 | RecStart | 1 prefer crc mode | Send "C" | XR1 | + | | | 2 want checksum mode | send NAK | XR1 | + |-----+----------+-------------------------+-------------------------+-----| + | XR1 | WaitFirst| 1 10 retries or 1 minute| report receive failure | exit| + | | | 2 > 3 retries or 30 secs| set want checksum mode | XR0 | + | | | 3 EOT received | delay < sec, purge input| exit| + | | | | send ACK, report no file| | + | | | 4 TeLink block recd | send ACK, set crc/cksm | XR2 | + | | | 5 data block recd | send ACK, set crc/cksm | XR2 | + | | | 6 bad block or 2-10 secs| incr retry count | XR0 | + |-----+----------+-------------------------+-------------------------+-----| + | XR2 | WaitBlock| 1 10 retries or 1 minute| report receive failure | exit| + | | | 2 EOT received | send ACK, report recd ok| exit| + | | | | send ACK, report recd ok| | + | | | 3 data block received | send ACK | XR2 | + | | | 4 bad block or 2-10 secs| send NAK, incr retry cnt| XR2 | + `-----+----------+-------------------------+-------------------------+-----' + + + A number of checks should be made to ensure a valid data block has been + received. + + o The physical layer should have encountered no errors, e.g. parity, + framing, etc. + + o The length of the block should not be less than expected. + + o If the blocks sequence number does not match the complement, then + respond with a NAK and attempt to read the block again. + + o If the block's sequence number is one previous (remember wrap around) + to that of the expected block, respond with an ACK and read again. + + o If the sequence number fits neither of the above criteria, and is yet + not the expected sequence number, abort the receive. + + o The checksum or CRC should be correct. + + + + 3. Data Link Layer Protocol : MODEM7 Filename Finite State Machines + + + MODEM7 Filename Sender + + .-----+----------+-------------------------+-------------------------+-----. + |State| State | Predicate(s) | Action(s) | Next| + | # | Name | | | St | + |-----+----------+-------------------------+-------------------------+-----| + | MS0 | WaitNak | 1 20 retries or 1 minute| filename send failed | exit| + | | | 2 NAK received | send ACK & 1st ch of fn | MS1 | + | | (note 1) | 3 C received | return fn skipped | exit| + |-----+----------+-------------------------+-------------------------+-----| + | MS1 | WaitChAck| 1 ACK rcd, fname done | send SUB = 1AH | MS2 | + | | | 2 ACK rcd, fname ~done | send next ch of fname | MS1 | + | | | 3 other char or 1 sec | send "u", incr retry cnt| MS0 | + |-----+----------+-------------------------+-------------------------+-----| + | MS2 | WaitCksm | 1 cksum recd and ok | send ACK, report fn ok | exit| + | | | 2 cksum recd but bad | send "u", incr retry cnt| MS0 | + | | | 3 no cksum in 1 sec | send "u", incr retry cnt| MS0 | + `-----+----------+-------------------------+-------------------------+-----' + + + MODEM7 Filename Receiver + + .-----+----------+-------------------------+-------------------------+-----. + |State| State | Predicate(s) | Action(s) | Next| + | # | Name | | | St | + |-----+----------+-------------------------+-------------------------+-----| + | MR0 | SendNak | 1 20 tries or 1 minute | report filename failure | exit| + | | | 2 | send NAK, incr try cnt | MR1 | + |-----+----------+-------------------------+-------------------------+-----| + | MR1 | WaitAck | 1 rcd ACK | | MR2 | + | | | 2 rcd EOT | report no files remain | exit| + | | | 3 5 secs & no ACK/EOT | | MR0 | + |-----+----------+-------------------------+-------------------------+-----| + | MR2 | WaitChar | 1 recd EOT (can happen?)| report no files remain | exit| + | | | 2 recd SUB | send checksum byte | MR3 | + | | | 3 recd "u" | | MR0 | + | | | 4 recd char of name | send ACK | MR2 | + | | | 5 no char in 1 second | | MR0 | + |-----+----------+-------------------------+-------------------------+-----| + | MR3 | WaitOkCk | 1 recd ACK within 1 sec | report recd filename ok | exit| + | | | 2 recd "u" or other char| | MR0 | + `-----+----------+-------------------------+-------------------------+-----' + + SUB is the ASCII character ^Z or 1AH. The checksum is the unsigned low + order eight bits of the sum of the characters in the transferred filename + including the SUB. + + Although one second timeouts are used successfully by Fido and SEAdog, + some fear that this is too small a timeout for some satellite and packet + network links. + + Note 1 - MS0.3 is a common addition to accommodate a common noncompliance. + Support of MS0.3 is optional for a compliant mailer. This hack + also requires modification of a number of state tables, see + FSC-0011. + + + H. Physical Layer : the Actual Connection of Two FidoNet Systems + + Will one of the more hardware-oriented comm types give me some idea of + what's needed here? Can we leave it open enough to allow implementation + over a non-dial net? Thanks. + + + I. Revisions since FTS-0001 + + 89 Oct 25 (rev 13) + o packet header: optional serialNo, password, and orig/dest zone + o stored message to/from zone/point info added as option per + Fido-12 and Dutchie + o XR1 and XR2 changes per FSC-0011 + o reference to FSC-0011 for the MODEM7-avoidance hack, MS0.3 + o dropped enumeration of product codes + o S4 modification from FSC-0011 + o Nodelist and EID reference appropriate documents + o various cosmetics + 90 July 1-5 (rev 14) + o spelling errors caught by Ray Gardner + o references to the now dead IFNA elided + o offset at end of Packed Message was 10 as opposed to 20 bytes + o Packed Message and Packet Header corrections by Roland Gautschi + o Offsets in TeLink header caught by Rick Moore + 90 August 30 (rev 15) + o corrected offsets in packet header + 95 September 30 (rev 16) + o TOPT corrected + o contact info changed + + + J. Acknowledgements + + Ben Baker, Thom Henderson, Tom Jennings, Ken Kaplan, and Gee Wong + suggested, informed, reviewed, and encouraged. Tom and Thom gave me + all the basics, and even allowed me to look at actual code. Bob Hartman + was foolish enough to implement the specification, and was generous + with useful feedback. Ray Gardner caught my spelling errors , + and Roland Gautschi and Rick Moore found offset and length errors. + + My employer, Pacific Systems Group was kind enough to donate my time to + research and to write this document. + + Fido and FidoNet are registered trademarks of Tom Jennings. + + SEAdog is a trademark of System Enhancement Associates. + + + K. Bibliography + + Documentation for the protocols and data formats are scattered. Some + are unattributed, some even untitled. + + Anonymous, changes to MODEM to implement CRC option XMDM-CRC.TXT + + Baker, Ken and Moore, Rick, Nodelist Definition, currently FTS-0005 + + Christensen, Ward, "MODEM Protocol Overview" of 1 January 82 XMODEM.TXT + + Hartman, Bob, "Some thoughts that I had on FSC001", FSC-0011 + + Henderson, Thom, "SEAdog Electronic Mail System Version 3" of April 86 + + International Standards Organization, "Data Processing - Open Systems + Interconnection - Basic Reference Model" ISO/DIS 7498 April 82 + + Jennings, Tom, "FidoNet Electronic Mail Protocol" 8 February 85 + FIDOMAIL.DOC + + Jennings, Tom, "Fido's Internal Structures" of 13 September 85 + STRUCT.TXT aka STRUCT.APX + + Jennings, Tom, "Extending XMODEM/MODEM File Transfer Protocol to support + DOS" 20 September 83 FILEXFER.DOC + + Jordan, Larry, "XMODEM File Transfer Protocol" XMDM-LJ.TXT + + Rudin, H and West, C, "Protocol Specification, Testing, and + Verification, III" Proceedings of the IFIP WG 6.1 Third International + Workshop on Protocol Specification, Testing, and Verification, + Rueschlikon Switzerland 31 May - 2 June 1983. + + Tanenbaum, Andrew, "Computer Networks" Prentice Hall 1981 + + Messages generated by Fido 11w, SEAdog 3.8, and QMail 1.01 diff --git a/SOURCE/UNUSED/GREP.COM b/SOURCE/UNUSED/GREP.COM new file mode 100644 index 0000000000000000000000000000000000000000..2cc12585699eec9bf0ab6645285eb85a0ca42922 GIT binary patch literal 7023 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/INSTALL.EXE b/SOURCE/UNUSED/INSTALL.EXE new file mode 100644 index 0000000000000000000000000000000000000000..751ee31310e6ae6bd5a8e00b348a472b6eb9af20 GIT binary patch literal 10304 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�gT+3N=Uf81xJPj~Cx{^Z2ft zoovK&rl*yf{nru`PJD97;u+{`@!~x3&i?{|JD1<3G$w '\') then + s := s + '\'; + end + else + while (s[length(s)] = '\') do + dec(s[0]); + bslash := s; +end; + +FUNCTION ExistDir(Fn: STRING): Boolean; +VAR + DirInfo: SearchRec; +BEGIN + Fn := BSlash(FALSE,FN); + IF (Length(Fn) = 2) AND (Fn[2] = ':') THEN + ExistDir := TRUE + ELSE + BEGIN + findfirst(Fn,AnyFile,DirInfo); + ExistDir := (DOSError = 0) AND (DirInfo.Attr AND $10 = $10); + END; +END; + +function sqoutsp(s: string):string; +begin + while (pos(' ',s)>0) do + delete(s,pos(' ',s),1); + sqoutsp := s; +end; + +function exist(fn: STRING): boolean; +var + srec: searchrec; +begin + findfirst(sqoutsp(fn),anyfile,srec); + exist := (doserror = 0); +end; + +FUNCTION SYN(B: BOOLEAN): STRING; +BEGIN + IF (B) THEN + SYN := 'Yes' + ELSE + SYN := 'No '; +END; + +FUNCTION YN: BOOLEAN; +VAR + C: CHAR; +BEGIN + Write(SQOutSp(SYN(DYNY))); + REPEAT + C := UpCase(Char(ReadKey)); + UNTIL (C IN ['Y','N',^M]); + IF (DYNY) AND (C <> 'N') THEN + C := 'Y'; + IF (DYNY) AND (C = 'N') THEN + Write(#8#8#8'No ') + ELSE IF (NOT DYNY) AND (C = 'Y') THEN + Write(#8#8'Yes'); + WriteLn; + YN := (C = 'Y'); + DYNY := FALSE; +end; + +FUNCTION PYNQ(CONST S: STRING): BOOLEAN; +BEGIN + Write(S); + PYNQ := YN; +END; + +PROCEDURE UnArc(FileName,Path: STRING); +BEGIN + SwapVectors; + Exec('PKUNZIP.EXE','-EN '+FileName+' '+Path); + SwapVectors; +END; + +procedure Kill(const fn: STRING); +var + f:file; +begin + assign(f,fn); + erase(f); +end; + +function allcaps(s:string):string; +var + i:integer; +begin + for i:=1 to length(s) do + if (s[i] in ['a'..'z']) then + s[i] := chr(ord(s[i]) - ord('a')+ord('A')); + allcaps:=s; +end; + +BEGIN + ClrScr; + WriteLn('Renegade Version 1.10 Install Utility'); + WriteLn; + WriteLn('This utility will install Renegade BBS Version 1.10.'); + WriteLn('Please make sure that PKUNZIP.EXE and this file are located'); + WriteLn('in the same directory as the archive RGV110.ZIP.'); + Writeln; + WriteLn('You will only be asked to enter the main path for the BBS'); + WriteLn('directory.'); + WriteLn; + IF PYNQ('Install Renegade BBS Version 1.10? ') THEN + BEGIN + Writeln; + WriteLn('Please enter main path for the bbs (Example: C:\RG'); + Write(': '); + ReadLn(S); + IF (S <> '') THEN + BEGIN + S := AllCaps(S); + IF (S[Length(S)] = '\') THEN + Dec(S[0]); + IF (S <> '') AND (NOT ExistDir(S)) THEN + MkDir(S); + IF (Exist(S+'\RENEGADE.DAT')) THEN + BEGIN + WriteLn; + Writeln(^G^G^G'Renegade is already installed in directory "'+S+'"'); + Exit; + END + ELSE + BEGIN + UnArc('RGV10.ZIP',S); + MkDir(S+'\ARCS'); + MkDir(S+'\DATA'); + MKDir(S+'\LOGS'); + MkDir(S+'\MISC'); + MkDir(S+'\MSGS'); + MkDir(S+'\NETFOSS'); + MkDir(S+'\PROTOCOL'); + UNArc(S+'\BBS.RGD',S); + UnArc(S+'\DATA.RGD',S+'\DATA'); + UnArc(S+'\MISC.RGD',S+'\MISC'); + UnArc(S+'\MSGS.RGD',S+'\MSGS'); + UnArc(S+'\NETFOSS.RGD',S+'\NETFOSS'); + UnArc(S+'\PROT.RGD',S+'\PROTOCOL'); + Kill(S+'\BBS.RGD'); + Kill(S+'\DATA.RGD'); + Kill(S+'\MISC.RGD'); + Kill(S+'\MSGS.RGD'); + Kill(S+'\NETFOSS.RGD'); + Kill(S+'\PROT.RGD'); + Assign(GeneralFile,S+'\RENEGADE.DAT'); + Reset(GeneralFile); + Seek(GeneralFile,0); + Read(GeneralFile,General); + WITH General Do + BEGIN + General.Version := '1.10'; (* <-- Update this with version *) + DataPath := S+'\DATA\'; + MiscPath := S+'\MISC\'; + MsgPath := S+'\MSGS\'; + LogsPath := S+'\LOGS\'; + TempPath := S+'\TEMP\'; + ProtPath := S+'\PROTOCOL\'; + ArcsPath := S+'\ARCS\'; + FileAttachPath := S+'\TEMP\'; + MultPath := S+'\DATA\'; + NodePath := S+'\NODELIST\'; + NetMailPath := S+'\NETMAIL\'; + DefEchoPath := S+'\ECHOMAIL\'; + END; + Seek(GeneralFile,0); + Write(GeneralFile,General); + Close(GeneralFile); + END; + Writeln; + WriteLn(^G^G^G'Installation complete!'); + END; + END; +END. diff --git a/SOURCE/UNUSED/IS286.PAS b/SOURCE/UNUSED/IS286.PAS new file mode 100644 index 0000000..3281bc1 --- /dev/null +++ b/SOURCE/UNUSED/IS286.PAS @@ -0,0 +1,33 @@ +unit is286; + +{$G-} + +interface + +implementation + +function a286or_better:boolean; assembler; +asm + pushf + pop bx + and bx,0fffh + push bx + popf + pushf + pop bx + and bx,0f000h + cmp bx,0f000h + mov ax,0 + jz @@1 + mov ax,1 + @@1: +end; + +begin + if not a286or_better then begin + writeln; + writeln('Renegade requires an 80286 or better processor.'); + halt; + end; +end. +{$G+} diff --git a/SOURCE/UNUSED/LEE.EXE b/SOURCE/UNUSED/LEE.EXE new file mode 100644 index 0000000000000000000000000000000000000000..0542ecaf207b12b9b8bca0629584316b7d98f785 GIT binary patch literal 2976 zcmZ`*eM}VT8Gq(u-yMc!1x0HW7l=5iuE!yxR9H|>5A+iCwon8ih{m(0Nvmd=UE1Va zmhi`AcYyZ(X#XIdkz(!-*j~UR%>a!o?sCh=5s^!}7H!gaXK(20)q_T_k?!`HSvWD# zNuGJ%_xboeAM?)hzDH}XQ3Te45w^42uipnK1*iak45TWgQ%FrnzeV~O$&WOK^cZOY z=@}A5Awe2!rqUplNrT5+8gNNzU_mNDTK#O@l`rnzQ}ENhg?X=?<-At1%8omFS~_#? zY-4sOpzA8{Lj|bLX*vyB9sxB1V6Gmi086#973`gVCTY-q6XF}HM{-c0P+-^jbI2cY zt=7_Q^jBxQF%25IFzLkHqLzd})71qoT|h(B@Hx2xlxN=+04ZbSDrKo2c?VtW3fMa@ zA$sTE4fy&9!}30=-xcWGfF*kA8Tu1+%(aodAU;+Z)>}wx&DDY)7joFZDn+8 zn0@eXi#c=1L@BUsI(ujxrEJy4d!XcKBTFg!am-Y%g2isJD`#l4-K-v?&FVOQ2<2Y^cvP-d1J+RilhD4kzlOMkNm7gm_P{%=7Mi zkVlh)Qb|`TBnPB7I|4#tw%HnN`q8tyC6L;fI+O~}9x$U0qhKQ(IEc`d4$(XEcw5kF z*$b`FRIhnAcr67GvgATr0O8h&f$m)B&V%k^P%cnrJE@$~OJG)aB=R<^+4Rdb-DVkE zkCoC&`lM?&B$EP=whten)g9244{AOP*U_p4x(Yxog}x%S3Q$Yk1H-3i)u^cq9GT9} z^%?nqMAW@-FuEA*e-9=7yowu%&Hwu8cWj;=5o&y)pxqZzDX6jcv$LwoKuyjXHm|tI zL9<5R%mA6r4g$S7duvYOS1Pg((+q9Y5kPD@#ko5F+rqC+}= z@j_$P!HbuE<2e8RIVtNWXSQeUD%>mXEX>b3aMAJ0(-+379_|Qz9^bAZ7sCkzx%sCOx}r zBSqjq=_JhWhz*Ie@_kD|sF^DmYhstgK(Epl=~XF^;k;Bm}2Jo%T z_(>jy`XfgpLv*8kI33jWP=leH zhBH9r;e|b^Ce=dx$GE8(+=LCrV4_5o$W}~vcO=%WgI{zI>s3f z5dC(QzBnO#c$CvDO3}h-9hDg6tgif8C0YzFk(px_mf|zkg|=ID#!SK6#3cuuTu{sZ90ct@tEeWG zsz}ut8){F~tYA3*5=@|%YUnp2&O$+c7h`DVthcRq8d+vioFzi2$;8C^vX&NmtTChD zZASOatTU+s0Utn}u@*PSxbEmYEW;gMhI?xj+$h40ivbL}V@?P)n3(5Fi`T8s^YCJ45%E`!qQDS z!Dr0>I&{(`A1Brsx52Jnh+*OqFS|6ba`n@ghOs2yZ<|~BYyCaG@%+b&*E{Ag^@L=s ziAO0Zz>nuI8g+z$YH(-3?q`H%eq7#ca@b3@!W`gDf*?;&48mjz7AGUno!v?j6BH!c&&twa8WPo3-Ku>3c9@}0#`B(wazJSDsM^5{RsK$JafEhm}v*i%;0;xH}N zFZi~hgQ71mu`l=uiD34hIO(DgRzO$Pa_^&h3Vesy9z5<=s>NfzSQBI}XF{~-@K!>% zx(RjJ5H2Uw@@*vK=81kAk;}s7gIjYJhgLVI`{iEYm(%=K##XtL%Q>c;*b^=b z(WNWlGQnVVpIZC16pS^q;)FLvfs#b~OX;KI2AqBtk?4V9&*eOjlG>~Cu%*;`4N5XQ zl%^l-3FSBCEegCno&EHdM>(a5Va R0$ju6L;;`ykL#D7{{zyQF@FF6 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/LEE.PAS b/SOURCE/UNUSED/LEE.PAS new file mode 100644 index 0000000..483962e --- /dev/null +++ b/SOURCE/UNUSED/LEE.PAS @@ -0,0 +1,17 @@ +Var + Name: String[35]; + name1: string[35]; + Current: Integer; + Done: Boolean; +BEGIN + Name := '12345678901234567890123456789012345'; + Name1 := Copy('123456789012345678901234567890123456',1,35); + IF (Name < Name) THEN + Current := 1 + ELSE IF (Name > Name1) THEN + Current := 2 + ELSE + Done := TRUE; + IF (Done) THEN + Writeln('Matches!'); +END. \ No newline at end of file diff --git a/SOURCE/UNUSED/LEE.TXT b/SOURCE/UNUSED/LEE.TXT new file mode 100644 index 0000000..0c0d7ff --- /dev/null +++ b/SOURCE/UNUSED/LEE.TXT @@ -0,0 +1,35 @@ +As I work my thru the editors, something stood out that could reduce the +overall size of the code and memory requirements. The InputWN1 +Procedure was utilized in every editor just as you see it below and +utilized four lines of code: + +NL; +Print('New description: '); +MPL(SizeOf(Name) - 1)); +InputWN1(Name,(SizeOf(Name) - 1),Changed); + +The above procedure has made modified to require only one line of code +to do the same job. I added the NL as %LF to the Print Procedure. I +then added an extra var to the InputWN1 to pass the Print procedure text +into the InputWN1 Procedure. I also added the MPL internal to the +InputWN1 Procedure (See Below). + +InputWN1('%LFNew description: ',Name,(SizeOf(Name) - 1),Changed); + + +The InputWNWC required 3 lines of code every time it was called (MPL +isn't used for color input prompts). + +NL; +Print('New description: '); +InputWNWC(Name,(SizeOf(Name) - 1),Changed); + +The above procedure has made modified to require only one line of code +to do the same job. I added the NL as %LF to the Print Procedure. I +then added an extra var to the InputWNWC to pass the Print procedure text +into the InputWNWC Procedure (See below). + +InputWNWC('%LFNew description: ',Name,(SizeOf(Name) - 1),Changed); + +I modified all numeric input routines in accordance with the above in +a previous release of Renegade. diff --git a/SOURCE/UNUSED/LGNQUOTE.DAT b/SOURCE/UNUSED/LGNQUOTE.DAT new file mode 100644 index 0000000..49358cf --- /dev/null +++ b/SOURCE/UNUSED/LGNQUOTE.DAT @@ -0,0 +1,5 @@ +7It takes a big man to cry, but it takes a bigger man tolaugh at that man.8If you ever fall off the Sears Tower, just go real limp,:because maybe you'll look like a dummy and people will try'to catch you, because, hey, free dummy.>&?j7u)WYz$~= z^(jMVoW9=DJM?ZPZQ=Rzt)(<_2OsK#x6!Gye;cdAHvCA=@MTZfy{(jsC790pq3xvo zan+{w1f7*UeZb|LT4Z0!BQ#u z@=;%*ONew1i*PTF?L&>Qc3-PcJ~m+7YoXG7+5`L9{-5D&a#(+9Ej~tPpF0NFcTF2; z>#Gzd#nGOCQH*nDkY$g-b}sIqQ_tif(l{)}Vq6z)^$LlQmXI&wE*uj{ZE-!WLXV-+ z6?}xwIP-={otWofl${@+;kLd4boQAzLYj$BaVsW|wDS=@>i_-2xwMZPZFT>NY+Zq4 ztp1nq19{(A`@Uh()SmfbV(k2t;$-?m*vuNdi_Z7Tj1-n2aXvMyFnWsrEl`8lClrQq05n1;68qS<*6$ z=5Tz#UUO`}UvVipiQ;}?+>!I`dwxUb9G0X}2j{&7(s8W9A{+6X*FxzRx$Yv)CMMxg zte0Wy%Eab8w~tHU)Gd<3Qa~=JID9&dV$!PQ*k#glazK`?(>q&wN&btuxM8`(RH{m` Q`|x~N4)=-NZl#^Ke}9(h&j0`b literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/LGNQUOTE.TXT b/SOURCE/UNUSED/LGNQUOTE.TXT new file mode 100644 index 0000000..9fd0349 --- /dev/null +++ b/SOURCE/UNUSED/LGNQUOTE.TXT @@ -0,0 +1,1205 @@ +$ +It takes a big man to cry, but it takes a bigger man to +laugh at that man. +$ + +$ +If you ever fall off the Sears Tower, just go real limp, +because maybe you'll look like a dummy and people will try +to catch you, because, hey, free dummy. +$ + +$ +If a kid asks where rain comes from, I think a cute thing to +tell him is "God is crying." And if he asks why God is +crying, another cute thing to tell him is "Probably because +of something you did." +$ + +$ +To me, boxing is like a ballet, except there's no music, no +choreography, and the dancers hit each other. +$ + +$ +If trees could scream, would we be so cavalier about cutting +them down? We might, if they screamed all the time, for no +good reason. +$ + +$ +Better not take a dog on the Space Shuttle, because if he +sticks his head out when you're coming home his face might +burn up. +$ + +$ +To me, clowns aren't funny. In fact, they're kinda scary. +I've wondered where this started, and I think it goes back +to the time I went to the circus and a clown killed my dad. +$ + +$ +I'd like to see a nude opera, because when they hit those +high notes I bet you can really see it in those genitals. +$ + +$ +Contrary to popular belief, the most dangerous animal is not +the lion or tiger or even the elephant. The most dangerous +animal is a shark riding on an elephant, just trampling and +eating everything they see. +$ + +$ +As we were driving we saw a sign that said "Watch For +Rocks." Marta said it should read "Watch For Pretty Rocks." +I told her she should write in her suggestion to the highway +department, but she started saying it was a joke--just to +get out of writing a simple letter And I thought I was lazy +$ + +$ +As I bit into the nectarine, it had a crisp juiciness about +it that was very pleasurable--until I realized it wasn't a +nectarine at all, but A HUMAN HEAD +$ + +$ +Once, when I was in Hawaii, on the island of Kauai, I met a +mysterious old stranger. He said he was about to die and +wanted to tell someone about the treasure. I said, "Okay, as +long as it's not a long story. Some of us have a plane to +catch, you know." He started telling his story, about the +treasure and his life and all, and I thought: "This story +isn't too long." But then, he kept going, and I started +thinking, "Uh-oh, this story is getting long." But then, +the story was over, and I said to myself: "You know, that +story wasn't too long after all." I forget what the story +was about, but there was a good movie on the plane. It was +a little long, though. +$ + +$ +If you ever teach a yodeling class, probably the hardest +thing is to keep the students from just trying to yodel +right off. You see, we_build_ to that. +$ + +$ +Is there anything more beautiful than a beautiful, beautiful +flamingo, flying across in front of a beautiful sunset? And +he's carrying a beautiful rose in his beak, and also he's +carrying a very beautiful painting with his feet. And also, +you're drunk. +$ + +$ +I guess of all my uncles, I liked Uncle Cave Man the best. +We called him Uncle Cave Man because he lived in a cave and +because sometimes he'd eat one of us. Later on we found out +he was a bear. +$ + +$ +Anytime I see something screech across a room and latch onto +someone's neck, and the guy screams and tries to get it off, +I have to laugh, because what IS that thing? +$ + +$ +In weightlifting, I don't think sudden, uncontrolled +urination should automatically disqualify you. +$ + +$ +If you're a horse, and someone gets on you, and falls off, +and then gets right back on you, I think you should buck him +off right away. +$ + +$ +If you define cowardice as running away at the first sign of +danger, screaming and tripping and begging for mercy, then +yes, Mister Brave Man, I guess I am a coward. +$ + +$ +The memories of my family outings are still a source of +strength to me. I remember we'd all pile into the car--I +forget what kind it was--and drive and drive. I'm not sure +where we'd go, but I think there were some trees there. The +smell of something was strong in the air as we played +whatever sport we played. I remember a bigger, older guy we +called "Dad." We'd eat some stuff, or not, and then I think +we went home. I guess some things never leave you. +$ + +$ +Blow ye winds, Like the trumpet blows; But without that +noise. +$ + +$ +I wish a robot would get elected President. That way, when +he came to town, we could all take a shot at him and not +feel too bad. +$ + +$ +He was a cowboy, mister, and he loved the land. He loved it +so much he made a woman out of dirt and married her. But +when he kissed her, she disintegrated. Later, at the +funeral, when the preacher said "Dust to dust," some people +laughed, and the cowboy shot them. At his hanging, he told +the others, "I'll be waiting for you in heaven--with a gun." +$ + +$ +Sometimes when I feel like killing someone, I do a little +trick to calm myself down. I'll go over to the person's +house and ring the doorbell. When the person comes to the +door, I'm gone, but you know what I've left on the porch? A +jack-o'-lantern with a knife in the side of its head with a +note that says "You." After that, I usually feel a lot +better, and no harm done. +$ + +$ +I can still recall old Mister Barnslow getting out every +morning and nailing a fresh load of tadpoles to that old +board of his. The he'd spin it round and round, like a +wheel of fortune, and no matter where it stopped he'd yell +out, "Tadpoles Tadpoles is a winner " We all thought he +was crazy. But then, we had some growing up to do. +$ + +$ +The face of a child can say it all, especially the mouth +part of the face. +$ + +$ +If I ever opened a trampoline store, I don't think I'd call +it Trampo-Land, because you might think it was a store for +tramps, which is not the impression we are trying to convey +with our store. On the other hand, we would not prohibit +tramps from browsing, or testing the trampolines, unless a +tramp's gyrations seemed to be getting out of control. +$ + +$ +I wish I had a kryptonite cross, because then you could keep +Dracula _and_ Superman away. +$ + +$ +Too bad you can't just grab a tree by the very tip-top and +bend it clear over the ground and then let her fly, because +I bet you'd be amazed at all the stuff that comes flying out. +$ + +$ +I remember that fateful day when Coach took me aside. I +knew what was coming. "You don't have to tell me," I said. +"I'm off the team, aren't I?" "Well," said the Coach, "you +never were really _on_ the team. You made that uniform +you're wearing out of rags and towels, and your helmet is a +toy space helmet. You show up at practice and then either +steal the ball and make us chase you to get it back, or you +try to tackle people at inappropriate times." It was all +true what he was saying. And yes, I thought, something is +brewing inside the head of this Coach. He sees something in +me, some kind of raw talent that he can mold. But that's +when I felt the handcuffs go on. +$ + +$ +If you saw two guys named Hambone and Flippy, which one +would you think like dolphins the most? I'd say Flippy, +wouldn't you? You'd be wrong though. It's Hambone. +$ + +$ +When I heard that trees grow a new "ring" for each year they +live, I though, we humans are kind of like that: we grow a +new layer of skin each year, and after many years we are +thick and unwieldy from all our skin layers. +$ + +$ +Laurie got offended that I used the word "puke." But to me, +that's what her dinner tasted like. +$ + +$ +If you're in a boxing match, try not to let the other guy's +glove touch your lips, because you don't know where that +glove has been. +$ + +$ +It's too bad that whole families have to be torn apart by +something as simple as wild dogs. +$ + +$ +Marta says the interesting thing about fly fishing is that +it's two lives connected by a thin strand. Come on, Marta. +Grow up. +$ + +$ +The old pool shooter had won many a game in his life. But +now it was time to hang up the cue. When he did, all the +other cues came crashing to the floor. "Sorry," he said with +a smile. +$ + +$ +If I ever do a book on the Amazon, I hope I am able to bring +a certain lightheartedness to the subject, in a way that +tells the reader we are going to have fun with this thing. +$ + +$ +Even though he was an enemy of mine, I had to admit that +what he had accomplished was a brilliant piece of strategy. +First, he punched me, then he kicked me, then he punched me +again. +$ + +$ +If you're at a Thanksgiving dinner, but you don't like the +stuffing or the cranberry sauce or anything else, just +pretend like you're eating it, but instead, put it all in +your lap and form it into a big, mushy ball. Then, later, +when you're out back having cigars with the boys, let out a +big, fake cough and throw the ball to the ground. Then say, +"Boy, these are good cigars " +$ + +$ +Most people don't realize that large pieces of coral, which +have been painted brown and attached to the skull by common +wood screws, can make a child look like a deer. +$ + +$ +The sound of fresh rain run-off splashing from the roof +reminded me of the sound of urine splashing into a filthy +Texaco latrine. +$ + +$ +I think somebody should come up with a way to breed a very +large shrimp. That way, you could ride him, then, after you +camped at night, you could eat him. How about it, science? +$ + +$ +When you go for a job interview, I think a good thing to ask +is if they ever press charges. +$ + +$ +I bet the main reason the police keep people away from a +plane crash is they don't want anybody walking in and lying +down in the crash stuff, then when somebody comes up act +like they just woke up and go, "What was _that_? " +$ + +$ +I scrambled to the top of the precipice where Nick was +watching. "That was fun," I said. "You bet it was," said +Nick. "Let's climb higher." "No," I said. "I think we +should be heading back now." "We have time," Nick insisted. +I said we didn't, and Nick said we did. We argued back and +forth like that for about 20 minutes, then finally decided +to head back. I didn't say it was an interesting story. +$ + +$ +If you're a young Mafia gangster out on your first date, I +bet it's really embarrassing if someone tries to kill you. +$ + +$ +Some folks say it was a miracle. Saint Francis suddenly +appeared and knocked the next pitch clean over the fence. +But I think it was just a lucky swing. +$ + +$ +Too bad there's not such a thing as a golden skunk, because +you'd probably be proud to be sprayed by one. +$ + +$ +I bet one legend that keeps recurring throughout history, in +every culture, is the story of Popeye. +$ + +$ +To me, truth is not some vague, foggy notion. Truth is real. + And, at the same time, unreal. Fiction and fact and +everything in between, plus some things I can't remember, +all rolled into one big "thing." This is truth, to me. +$ + +$ +Whenever I see an old lady slip and fall on a wet sidewalk, +my first instinct is to laugh. But then I think, what if I +was an ant, and she fell on me. Then it wouldn't seem quite +so funny. +$ + +$ +You know what would make a good story? Something about a +clown who makes people happy, but inside he's real sad. +Also, he has severe diarrhea. +$ + +$ +I bet a fun thing would be to go back in time to where there +was going to be an eclipse and tell the cave men, "If I have +come to destroy you, may the sun be blotted out from the +sky." Just then the eclipse would start, and they'd +probably try to kill you or something, but then you could +explain about the rotation of the moon and all, and everyone +would have a good laugh. +$ + +$ +We used to laugh at Grandpa when he'd head off to go fishing. +But we wouldn't be laughing that evening, when he'd come +back with some whore he picked up in town. +$ + +$ +I think in one of my previous lives I was a mighty king, +because I like people to do what I say. +$ + +$ +Today I accidentally stepped on a snail on the sidewalk in +front of our house. And thought, I too am like that snail. +I build a defensive wall around myself, a "shell" if you +will. But my shell isn't made out of a hard, protective +substance. Mine is made out of tinfoil and paper bags. +$ + +$ +A man doesn't automatically get my respect. He has to get +down in the dirt and beg for it. +$ + +$ +One thing kids like is to be tricked. For instance, I was +going to take my little nephew to Disneyland, but instead +drove him to an old, burned-out warehouse. "Oh no," I said, +"Disneyland burned down." He cried and cried, but I think +that deep down, he thought it was a pretty good joke. I +started to drive over to the real Disneyland, but it was +getting pretty late. +$ + +$ +As the evening sun faded from a salmon color to a sort of +flint gray, I thought back to the salmon I caught that +morning, and how gray he was, and how I named him Flint. +$ + +$ +If you're ever stuck in some thick undergrowth, in your +underwear, don't stop and start thinking of what other words +have "under" in them, because that's probably the first sign +of jungle madness. +$ + +$ +Sometimes the beauty of the world is so overwhelming, I just +want to throw back my head and gargle. Just gargle and +gargle, and I don't care who hears me, because I am +beautiful. +$ + +$ +Fear can sometimes be a useful emotion. For instance, let's +say you're an astronaut on the moon and you fear that your +partner has been turned into Dracula. The next time he goes +out for the moon pieces, wham , you just slam the door +behind him and blast off. He might call you on the radio +and say he's not Dracula, but you just say, "Think again, +bat man." +$ + +$ +I wish scientists would come up with a way to make dogs a +lot bigger, but with a smaller head. That way, they'd still +be good as watchdogs, but they wouldn't eat so much. +$ + +$ +I bet for an Indian, shooting an old fat pioneer woman in +the back with an arrow, and she fires her shotgun into the +ground as she falls over, is like the top thing you can do. +$ + +$ +I think a good movie would be about a guy who's a brain +scientist, but he gets hit on the head and it damages the +part of the brain that makes you want to study the brain. +$ + +$ +I wouldn't be surprised if someday some fishermen caught a +big shark and cut it open, and there inside was a whole +person. Then they cut the person open, and in him is a +little baby shark. And in the baby shark there isn't a +person, because it would be too small. But there's a little +doll or something, like a Johnny Combat little toy guy-- +something like that. +$ + +$ +It makes me mad when I go to all the trouble of having Marta +cook up about a hundred drumsticks, then the guy at +Marineland says "You can't throw chicken to the dolphins. +They eat fish." Sure they eat fish, if that's all you give +them. Man, wise up. +$ + +$ +If the Vikings were around today, they would probably be +amazed at how much glow-in-the-dark stuff we have, and how +we take so much of it for granted. +$ + +$ +We tend to scoff at the beliefs of the ancients. But we +can't scoff at them personally, to their faces, and this is +what annoys me. +$ + +$ +It's not good to let any kid near a container that has a +skull and crossbones on it, because there might be a +skeleton costume inside and the kid could put it on and +really scare you. +$ + +$ +If you had a school for professional fireworks people, I +don't think you could cover fuses in just one class. It's +just too rich a subject. +$ + +$ +People think it would be fun to be a bird because you could +fly. But they forget the negative side, which is the +preening. +$ + +$ +If I lived back in the Wild West days, instead of carrying a +six-gun in my holster, I'd carry a soldering iron. That way, +if some smart-aleck cowboy said something like "Hey, look. +He's carrying a soldering iron " and started laughing, I +could just say, "That's right, it's a soldering iron. The +soldering iron of justice." Then everybody would get real +quiet and ashamed, because they made fun of the soldering +iron of justice, and I could probably hit them up for a free +drink. +$ + +$ +When I think back on all the blessings I have been given in +my life, I can't think of a single one, unless you count +that rattlesnake that granted me all those wishes. +$ + +$ +I hope in the future Americans are thought of as a warlike, +vicious people, because I bet a lot of high schools would +pick "Americans" as their mascot. +$ + +$ +Sometimes I think the world has gone completely mad. And +then I think, "Aw, who cares?" And then I think, "Hey, +what's for supper?" +$ + +$ +If you ever discover that what you're seeing is a play +within a play, just slow down, take a deep breath, and hold +on for the ride of your life. +$ + +$ +I can see why it would be prohibited to throw most things +off the top of the Empire State Building, but what's wrong +with little bits of cheese? They'd probably break down into +their various gases before they even hit. +$ + +$ +If you're a circus clown, and you have a dog that you use in +your act, I don't think it's a good idea to also dress the +dog up like a clown, because people see that and they think, +"Forgive me, but that's just too much." +$ + +$ +Here's a good joke to do during an earthquake: straddle a +big crack in the ground, and if it opens wider, go "Whoa +Whoa " and flail your arms around, like you're going to fall +in. +$ + +$ +If you ever go temporarily insane, don't shoot somebody, +like a lot of people do. Instead, try to get some weeding +done, because you'd really be surprised. +$ + +$ +It makes me mad when people say I turned and ran like a +scared jackrabbit. Maybe it was like an angry rabbit, who +was running to go fight in another fight, away from the +first fight. +$ + +$ +I hope if dogs ever take over the world, and they choose a +king, they don't just go by size, because I bet there are +some Chihuahuas with some good ideas. +$ + +$ +I think a good idea to get into a movie is to show up where +they're making the movie, then stick a big cactus plant onto +your buttocks and start yowling and running around. +Everyone would think it was funny, and the head movie guy +would say, "Hey, let's put him in the movie." +$ + +$ +What is it that makes a complete stranger dive into an icy +river to save a solid gold baby? Maybe we'll never know. +$ + +$ +Instead of having "answers" on a math test, they should just +call them "impressions," and if you got a different +"impression," so what, can't we all be brothers? +$ + +$ +If God dwells inside us, like some people say, I sure hope +He likes enchiladas, because that's what He's getting +$ + +$ +Probably to a shark, about the funniest thing there is is a +wounded seal, trying to swim to shore, because WHERE DOES HE +THINK HE'S GOING? +$ + +$ +Perhaps, if I am very lucky, the feeble efforts of my +lifetime will someday be noticed, and maybe, in some small +way, they will be acknowledged as the greatest works of +genius ever created by Man. +$ + +$ +Maybe in order to understand mankind, we have to look at the +word itself. Mankind. Basically, it's made up of two +separate words--"mank" and "ind." What do these words mean? +It's a mystery, and that's why so is mankind. +$ + +$ +Children need encouragement. So if a kid gets an answer +right, tell him it was a lucky guess. That way, he develops +a good, lucky feeling. +$ + +$ +If you ever drop your keys into a river of molten lava, let +'em go, because, man, they're gone. +$ + +$ +I think a good novel would be where a bunch of men on a ship +are looking for a whale. They look and look, but you know +what? They never find him. And you know why they never find +him? It doesn't say. The book leaves it up to you, the +reader, to decide. Then, at the very end, there's a page you +can lick and it tastes like Kool-Aid. +$ + +$ +Marta talks about sensuality, but I don't think she'd know +sensuality if it bit her on the ass. +$ + +$ +It's easy to sit there and say you'd like to have more money. + And I guess that's what I like about it. It's easy. Just +sitting there, rocking back and forth, wanting that money. +$ + +$ +I think a good gift for the President would be a chocolate +revolver. And since he's so busy, you'd probably have to +run up to him real quick and hand it to him. +$ + +$ +Whether they find life there or not, I think Jupiter should +be considered an enemy planet. +$ + +$ +If you lived in the Dark Ages, and you were a catapult +operator, I bet the most common question people would ask is, +"Can't you make it shoot farther?" No. I'm sorry. That's +as far as it shoots. +$ + +$ +Why is it that we will laugh at a man in a clown outfit, but +we won't laugh at a man just walking down the street +carrying a clown outfit in one of those plastic dry-cleaner +bags? +$ + +$ +Probably the earliest fly swatters were nothing more than +some sort of striking surface attached to the end of a long +stick. +$ + +$ +Instead of trying to build newer and bigger weapons of +destruction, mankind should be thinking about getting more +use out of the weapons we already have. +$ + +$ +The crows seemed to be calling his name, thought Caw. +$ + +$ +If you go flying back through time, and you see somebody +else flying forward into the future, it's probably best to +avoid eye contact. +$ + +$ +To me, it's always a good idea to always carry two sacks of +something when you walk around. That way, if anybody says, +"Hey, can you give me a hand?" you can say, "Sorry, got +these sacks." +$ + +$ +Whenever someone asks me to define love, I usually think for +a minute, then I spin around and pin the guy's arm behind +his back. NOW who's asking the questions? +$ + +$ +I remember we were all horrified to see Grandpa up on the +roof with his Superman cape on. "Get down " yelled Uncle +Lou. "Don't move " screamed Grandma. But Grandpa wouldn't +listen. He walked to the edge of the roof and stuck out his +arms, like he was going to fly. I forget what happened +after that. +$ + +$ +If you ever catch on fire, try to avoid seeing yourself in +the mirror, because I bet that's what really throws you into +a panic. +$ + +$ +I wish my name was Todd, because then I could say, "Yes, my +name's Todd. Todd Blankenship." Oh, also I wish my last +name was Blankenship. +$ + +$ +If you're an ant, and you're walking across the top of a cup +of pudding, you probably have no idea that the only thing +between you and disaster is the strength of that pudding +skin. +$ + +$ +Dad always thought laughter was the best medicine, which I +guess was why several of us died from tuberculosis. +$ + +$ +I don't think God put me on this planet to judge others. I +think he put me on this planet to gather specimens and take +them back to my home planet. +$ + +$ +Just because swans mate for life, I don't think it's that +big of a deal. First of all, if you're a swan, you're +probably not going to find a swan that looks that much +better than the one you've got, so why not mate for life. +$ + +$ +If you're robbing a bank, and your pants suddenly fall down, +I think it's okay to laugh, and to let the hostages laugh +too, because come on, life is funny. +$ + +$ +Just as bees will swarm about to protect their nest, so will +I "swarm about" to protect my nest of chocolate eggs. +$ + +$ +If you were a gladiator in olden days, I bet the +inefficiency of how the gladiator fights were organized and +scheduled would just drive you up a wall. +$ + +$ +Sometimes I think I'd be better off dead. No, wait. Not me, +you. +$ + +$ +Something tells me that the first mousetrap wasn't designed +to catch mice at all, but to protect little cheese "gems" +from burglars. +$ + +$ +I can't stand cheap people. It makes me real mad when +someone says something like "Hey, when are you going to pay +me that hundred dollars you owe me?" or "Do you have that +fifty dollars you borrowed?" Man, quit being so cheap +$ + +$ +You can't tell me that cowboys, when they're branding cattle, +don't sort of "accidentally" brand each other every once in +a while. It's their way of letting off stress. +$ + +$ +One day one of my little nephews came up to me and asked me +if the equator was a real line that went around the Earth, +or just an imaginary one. I had to laugh. Laugh and laugh. +Because I didn't know, and I thought that maybe by laughing +he would forget what he asked me. +$ + +$ +If I come back as an animal in my next lifetime, I hope it's +some type of parasite, because this is the part where I take +it easy +$ + +$ +I think the mistake a lot of us make is thinking the state- +appointed psychiatrist is our "friend." +$ + +$ +When you first start wearing a turban, probably the most +common mistake is wrapping it too tight. You have to allow +the head to breathe. +$ + +$ +If you go through a lot of hammers each month, I don't think +it necessarily means you're a hard worker. It may just mean +that you have a lot to learn about proper hammer maintenance. +$ + +$ +When people say that the desert is lifeless, it just makes +me want to grab them by the collar and yell, "Why you stupid, +stupid bastard " Then I drive them out into the desert to +where the circus is, and point out the many forms of zebra +and clown life. +$ + +$ +If there was a big gardening convention, and you got up and +gave a speech in favor of fast-motion gardening, I bet you +would get booed off the stage. They're just not ready. +$ + +$ +We like to praise birds for flying. But how much of it is +actually flying, and how much of it is just sort of coasting +from the previous flap? +$ + +$ +Instead of raising your hand to ask a question in class, how +about individual push buttons on each desk? That way, when +you want to ask a question, you just push the button and it +lights up a corresponding number on a tote board at the +front of the class. Then all the professor has to do is +check the lighted number against a master sheet of names and +numbers to see who is asking the question. +$ + +$ +If you're a boxing referee, it's probably illegal to wear a +bow tie that spins or changes colors. +$ + +$ +You know something that would really make me applaud? A guy +gets stuck in quicksand, then sinks, then suddenly comes +shooting out, riding on water skis How do they do that? +$ + +$ +Whether they live in an igloo or a grass shack or a mud hut, +people around the world all want the same thing: a better +house +$ + +$ +When you're going up the stairs and you take a step, kick +the other leg up high behind you to keep people from +following too close. +$ + +$ +When Rick told me he was having trouble with his wife, I had +to laugh. Not because of what he said, but because of a +joke I thought of. I told him the joke, but he didn't +laugh very much. Some friend HE is. +$ + +$ +If you ever reach total enlightenment while you're drinking +a beer, I bet it makes beer shoot out your nose. +$ + +$ +Love is not something that you can put chains on and throw +into a lake. That's called Houdini. Love is liking someone +a lot. +$ + +$ +If I was being executed by lethal injection, I'd clean up my +cell real neat. Then, when they came to get me, I'd say, +"Injection? I thought you said 'inspection.'" They'd +probably feel real bad, and maybe I could get out of it. +$ + +$ +I'm not afraid of insects taking over the world, and you +know why? It would take about a billion ants just to aim a +gun at me, let alone fire it. And you know what I'm doing +while they're aiming it at me? I just sort of slip off to +the side, and then suddenly run up and kick the gun out of +their hands. +$ + +$ +I believe in making the world safe for our children, but not +our children's children, because I don't think children +should be having sex. +$ + +$ +If you're a blacksmith, probably the proudest day of your +life is when you get your first anvil. How innocent you are, +little blacksmith. +$ + +$ +What am I afraid of? I'll tell you: a feather. That's +right, a feather. How could anyone be afraid of a feather, +you say. That's an honest question, and I'll try to give an +honest answer. First of all, did I say it was a poison +feather? +$ + +$ +When you die, if you get a choice between going to regular +heaven and pie heaven, choose pie heaven. It might be a +trick, but if it's not, ummmm, boy. +$ + +$ +Of all the warning sounds that animals make, I think the one +that is least effective on me is a kind of clicking noise. +$ + +$ +I bet a funny thing about driving a car off a cliff is, +while you're in midair, you still hit those brakes Hey, +better try the emergency brake +$ + +$ +I wish there was a disease where you're afraid of clouds, +because I think I could cure it. First, you sit the patient +down and have a long, personal talk. After that, I'm not +sure, but maybe you could throw water in his face or +something. +$ + +$ +As the light changed from red to green to yellow and back to +red again, I sat there thinking about life. Was it nothing +more than a bunch of honking and yelling? Sometimes it +seemed that way. +$ + +$ +How come the dove gets to be the peace symbol? How about +the pillow? It has more feathers than the dove, and it +doesn't have that dangerous beak. +$ + +$ +Even though I was their captive, the Indians allowed me +quite a bit of freedom. I could walk about freely, make my +own meals, and even hurl large rocks at their heads. It was +only later that I discovered they were not Indians after all, +but dirty clothes hampers. +$ + +$ +If life deals you lemons, why not go kill someone with the +lemons (maybe by shoving them down his throat)? +$ + +$ +I wish outer-space guys would conquer Earth and make people +their pets, because I'd like to have one of those little +basket-beds with my name on it. +$ + +$ +I think Superman and Santa Claus are actually the same guy, +and I'll tell you why: Both fly, both wear red, and both +have a beard. +$ + +$ +Frank knew that no man had ever crossed the desert on foot +and lived to tell about it. So, he decided to get back in +his car and keep driving. +$ + +$ +It's true that every time you hear a bell, an angel gets his +wings. But what they don't tell you is, every time you hear +a mousetrap snap, an angel gets set on fire. +$ + +$ +If I was a father in a waiting room, and the nurse came out +and said, "Congratulations, it's a girl," I think a good gag +would be to get real mad and yell, "A girl ? You must have +me mixed up with THAT dork " and point to another father. +$ + +$ +I bet what happened was, they discovered fire and invented +the wheel on the same day. Then, that night, they burned +the wheel. +$ + +$ +The wise man can pick up a grain of sand and envision a +whole universe. But the stupid man will just lay down on +some seaweed and roll around until he's completely draped in +it. Then he'll stand up and go, "Hey, I'm Vine Man." +$ + +$ +I remember how, in college, I got that part-time job as a +circus clown, and how the children would laugh and laugh at +me. I vowed, then and there, that I would get revenge. +$ + +$ +If I could be a bird, I think I'd be a penguin, because then +I could walk around on two feet with a lot of other guys +like me. +$ + +$ +The big, huge meteor headed toward the Earth. Could nothing +stop it? Maybe Bob could. He was suddenly on top of the +meteor--through some kind of space warp or something. "Go, +Bob, go " yelled one of the generals. "Give me that " said +the big-guy general as he took the microphone away. "Listen, +Bob," he said. "You've got to steer that meteor away from +Earth." "Yes, but how?" thought Bob. Then he got an idea. +Right next to him there was a steering wheel sticking out of +the meteor. +$ + +$ +If I could come back as a horsefly, I think my favorite +thing would be to land on someone's lip. Even if they smash +you, ick , you're all over their lip +$ + +$ +I think a new, different kind of bowling should be "carpet +bowling." It's just like regular bowling, only the lanes +are carpet instead of wood. I don't know why we should do +this, but my God, we've got to try something +$ + +$ +Isn't it funny how whenever we go to a county fair or a +state fair, the first thing we do is see if they have some +kind of pornography booth. +$ + +$ +People laugh when I say that I think a jellyfish is one of +the most beautiful things in the world. What they don't +understand is, I mean a jellyfish with long, blond hair. +$ + +$ +If you want to be the popular one at a party, here's a good +thing to do: Go up to some people who are talking and +laughing and say, "Well, technically that's illegal." It +might just fit in with what somebody just said. And even if +it doesn't, so what, I hate this stupid party. +$ + +$ +To us, it might look like just a rag. But to the brave, +embattled men of the fort, it was more than that. It was a +flag of surrender. And after that, it was torn up and used +for shoe-shine rags, so the men would look nice for the +surrender. +$ + +$ +It's easy to sit and scoff at an old man's folly. But also, +check out his Adam's apple +$ + +$ +I think one way police departments could make some money +would be to hold a yard sale of murder weapons. Many people, +for example, could probably use a cheap ice pick. +$ + +$ +I hope they never find out that lightning has a lot of +vitamins in it, because do you hide from it or not? +$ + +$ +There are many stages to a man's life. In the first stage, +he is young and eager, like a beaver. In the second stage, +he wants to build things, like dams, and maybe chew down +some trees. In the third stage, he feels trapped, and then +"skinned." I'm not sure what the fourth stage is. +$ + +$ +I wish I would have a real tragic love affair and get so +bummed out that I'd just quit my job and become a bum for a +few years, because I was thinking about doing that anyway. +$ + +$ +If aliens from outer space ever come and we show them our +civilization and they make fun of it, we should say we were +just kidding, that this isn't our real civilization, but a +gag we hoped they would like. Then we tell them to come +back in twenty years to see our real civilization. After +that, we start a crash program of coming up with a new +civilization. Either that, or just shoot down the aliens as +they're waving good-bye. +$ + +$ +Like jewels in a crown, the precious stones glittered in the +queen's round metal hat. +$ + +$ +I wish I could shrink down to the size of an ant. And maybe +there would be thousands of other people shrunken down to +ant-size, and we would get together and dig tunnels down +into the ground, and live there. But don't ever call us +"ants," because we hate that. +$ + +$ +If you're travelling in a time machine, and you're eating +corn on the cob, I don't think it's going to affect things +one way or the other. But here's the point I'm trying to +make: Corn on the cob is good, isn't it. +$ + +$ +I bet if you were a mummy wrapper in ancient Egypt, one +thing you would constantly find yourself telling people +would be, "Be sure, before I start, you have all the jewelry +and so forth on the body, because I am NOT unwrapping him +later." +$ + +$ +If you're ever selling your house, and some people come by, +and a big rat comes out and he's dragging the rattrap +because it didn't quite kill him, just tell the people he's +your pet and that's a trick you taught him. +$ + +$ +If I had the time to sit down and write a thank-you note to +everyone who sent me a nice, expensive present, what a +wonderful world that would be +$ + +$ +You know one thing that will make a woman mad? Just run up +and kick her in the butt. (P.S. This also works with men.) +$ + +$ +It seemed to me that, somehow, the blue jay was trying to +communicate with me. I would see him fly into the house +across the way, pick up the telephone, and dial. My phone +would ring, and it would be him, but it was just this +squawking and cheeping. "What? What? " I would yell back, +but he never did speak English. +$ + +$ +If you're in a war, instead of throwing a hand grenade at +some guys, throw one of those little baby-type pumpkins. +Maybe it'll make everyone think of how crazy war is, and +while they're thinking, you can throw a real grenade. +$ + +$ +I hope life isn't a big joke, because I don't get it. +$ diff --git a/SOURCE/UNUSED/LINECHAT.TPU b/SOURCE/UNUSED/LINECHAT.TPU new file mode 100644 index 0000000000000000000000000000000000000000..79c05d7064d5d22dcb8fa2254256c1bd8217c463 GIT binary patch literal 11632 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 U&-)&BypEef9!?6rrWv1q0T!xOq5uE@ literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/LOGON.BAT b/SOURCE/UNUSED/LOGON.BAT new file mode 100644 index 0000000..b6b5e00 --- /dev/null +++ b/SOURCE/UNUSED/LOGON.BAT @@ -0,0 +1,18 @@ +@echo off +:: This is the default LOGON.BAT file. It is executed right after a +:: user reads Email. If you have utilities that run each time someone +:: logs on, put them in here. The parameters passed are: +:: %1 - Node number +:: %2 - User Number +:: %3 - Actual baud rate +:: %4 - Dropfile path (DOOR.SYS is dropped) +:: %5 - Username +:: +:: +:: Note: For %5 to be the username, dropfile path for node must not +:: be "", which is what Renegade tries to default to at this time. +:: This is not hard to fix. Also, username is passed just as Renegade +:: stores it, in all uppercase. This means %5 is likely NOT the full +:: username. 4DOS allows you to get the whole thing as %5&, those +:: without 4DOS will have to find other batch tricks. + diff --git a/SOURCE/UNUSED/LOGON.TPU b/SOURCE/UNUSED/LOGON.TPU new file mode 100644 index 0000000000000000000000000000000000000000..b6ed9f65fcd874e44f72cce674c5f02f8bb90f68 GIT binary patch literal 31952 zcmchA34D#$*8YBnGiH{Akd}j(hlUawQw#|)W;ljYiU>jmk`qHE5e<<@qcv1jiJ_?K zK$RA4Lt9traI5r|>Y&uEMs&EQYLNV&wcecx9q#x0zJJF*tECxh8k{mEC0U5Cw_gv2)X0@kv7154A>l_&>(dKi)Mw zEk0GTTA?xDCWP5TXFsV*Ib*EWH`Rrv`d6sJVa1yJrX(ei%UCIzc(k~??HBE>*-E)`LPDYtNB^~2ak0c4J}W-i z1*MV=FDbc((h%qb3$fq#9c6X31ciNf@>AudDoHZJ95DT?@{S@xl~~h|_~dl>>D}py z@~PpPB^`xWq?*;UiuhECwGNG+O;JMcvCV<%6-B%QVeHhDRM(KSDMB>L4TdgN(So)c zHlt&IA$qRprv|dj>P$$Ak4R6B6XNQkht*(J{xiT6ZglD&^-GxtWoQ zw)9VN4V{n_FLRCFjkXL+oW!vjfpzij2k$Z3fcQCz)f=keTJ?a~FUo}~VlXV!y7Xce zUu!AIKLUzY5}H`WeMnJ0@za`^nJ3jpwPEZ@+!$2TC~YIH8nn7yN@2z$-^Nl?YCZGDYdLOyMS!YI3F~#HXR$Uu3zEsm=~+84G0nRA)!^dQE{f zJSi>V(a6-9>US)jr=yx`bv6A^4B6U*KNm^WoC2K&dbHjz1@%0`W~mSt=+Tzg^tibA zv^4eGDru1(t;DL|mQz&J6}$ClEix@Z{q}aHw7F0E zgj7_)X0Pwb))M!Qmg?+R|r}SxGUVC^92GT!x^qr^%Pr@yY`5j#*Vu63OS>( zb6t=28X7;x6^T_QDkUM=h1|`YO9l^^Vldx~T*d0Zh+TvBuIve_6ZHiBZHAl%QLH+y zViwX@H6EAtzEk7lra#&{IW0l4wuHv%8unyC_RY+?Io#|IN72e)41(Rzk)4Ltxyd}W z4)yA=Ip|eVpy74i6s^orf3M=n!Cdu56@L}^vFZrsDWJ~g828>oVL~}FCNFOrGkOA=%CZUJ-my@P zQxhi95M06;G_2mYMQekTr>J=>p_WtZl?#7vl?;WVi56DzE$q=|C++!Z>f=>HUwbr- znCvRSV0*Nc4>8mWSyke(cG8)%IwMGbLq6dfZg? zu`20WG!g2`i|^bjDUI|B{1JwU18Aq}KX36SGZ;Gj=Mc>pE6=noMIq}43)-iI=qkqH zHCM?dMtCd1tY2#RP7ecLsvHwv0=H-m)daiKR;zgoFiXi(ys(|Pnf7Xtzzm|S-8+-I+Zr1`Qh6%%YxOJwJ%?%Kr&7ZCNo;8ZNwqm#Lk-jQ$tgT@XB5x zM8wceCO6&9gn-;M6BJmxkuaHbT?M$oJ9US@8%ptpQ}L{|YObwG6>ZVBtPtQQ5-gp)+=OoNG2$4_@X_8xf!Zg$BI8xzcr2ns8h#c z)l~$BIE~o-F|bv=4TA9mnGh{JxS4z`hyYXgjCw%1tnO00OlA*v)BVDRZgofha0UFu zBXva|OIy*}A}k@I6N+o?1}~xm20FEysOO1!;cua31(nwt)sm7z0K|ya;%S7#Z2{c| z?oEZMu@$30H~H&UQ^ST05pG-V3t`b|M$|F+Vou1v0K4vKWW%G7&H_AxpyyK~!-Q#M zp=wf3SWKQ453~wmhpdulVKe$iwbT*q;r~Gl4huIp28S*g-B!Ict|hM{C+nl!)4R9&i5Knu|V=Q9s)s|StLfDjbQEsCbJ z;Gm8!vglZxEq0h$%|dT$vC@QsF7={CXJzt4f9HfIEQ&?^ieaq04)P;G~X1v z%(rloOi=E(B;d@LfD_?#oD~ys+DlThEXm5#mK0^XWrlLlGE+He2~_RY`_%@ZHr9q} zck57fx;0A81mU=&zG970|6z?)zqC5lpRL1H-8Mq?vyD_+fO>+4fu?{g${97^c2-?$ zJE!ileXqW6JFlLw{agLf_JgX}FQ~ruAJrE2619u{qB_`Ks*bf^QeF0+)W!Cn)z$W2 z)EDi)st4@!mMsFhCP@9P3Y7nrMC{Z5(MnK*l`H_$h5`}25EzWJ%();ghz%!`NRn*}c>UJIUJ8V6b?Rs71n5C&Q4YXPd0yP6Q2enY9>#db7 zS{q;(@_PdZ0tbPHfQEq|0UQMy4H~a}WrE#PgS zNj?(Kw-#>RNqizkT(K(Bf*abjR8#sr9tOOV39ge zU#}*aUshiDF`sctefTw_`k^h^PWLETFHC2Dntmz%i zX8p2i(T{81`ZS9VumSKsU^8F~U>i^;q`T-7^=?QgXzV>qe6Be~^LdlS*?CihU&a*i zWXKc|UYICGJ(CPd5x=Z(iEp1y7a3`DMAFJRkj(|ngM0zxk0ZTEy!7m1;Bw$f=&eC| zjcD>zkti+N0G}Jh^DQ=tcA%Z!8^Lc9Q(A07{ucOn0Y0`te>>wcF63Ixk2Uu-Un0%vO19Y zLguebT~i;_KnX8ws+45~DMtf>l;-vzq?;k#Oc`TuhIDhJn=6{VInphZZvt8e+2SJAm$N}j{=Q`e5^8H z-FT$OE9DKQE1zqL%1S*+8DO5F^uXQ{neI~jGF(c>PA;YSyjjYliL(?}A=aP54Di|D zvw;hM3!s;y+}9}w{6eL5;zH=6De3rxaO4zJ~@0F0PR9tme zDx;pF^wY?H8ZkYGc3G<&$Xl!YzPbqVB4vnok)pj+1X&Sm*Q31kO5mDJ$lI)3^4$#i z7N!3Bt>CvJy%jp!l-Rc0fZLT;q1%=A&9)JAA){7++U*uG_6Vv2_pRZ$SPA z{Ov>DTfl>my{9BS`yuQB4 z!uFyP5OPr&?RF9Q7t!ArVRs4XOGNYs?Sr(B>b zr)5o$Zh|ynQ+3burjP|89fWj{dLXX_s3rWgQcH_k16zY{0}NIhKHCB5&Pa!-ult1n zyQp9IKBSKG4@JzO>eco0I)NS>8qWmz}_EvkX>7)L>x)1F7 zAjUq3KT`c%i$Z-KR(*5Fg2utmICW(EacZmFiRzZclhhpx6V=A?iNGXa651pUF}OhK zpxGc?h-S@2td9X713wR#jq(-%7a`6?z+A+chdA@$KOb@CBhGxpxdd?*AkHTcXCdNz z5_V4^&Si*m8SIuJ&SfZj1@Lz6RQ*E@FCJ&1?EP_&4EyAL7^t`98H(&_1-oJLuP9_rR#Gvk~q@NpGwbq!@-Q`hBRS6@&4P3>QF17+S&8y1zRC3DJDbJk6@?(m!Hdquav z-%>O3%hjShq5Yn(YOR-O+PQpP^I2lj0@qkH?IoL5GRLN!oo7edUE4X&UHfpJhn6zW zM_clkFVGKE7rKGSb7+1U4lSUg1NxM1qV0U3iM9gdml33W*)m9T72>>5*cyCW@NG5E z?d`Q~X%A@Og~3`zS|@GPGhLC_6*gUAOX*PPg~AT!io!7PeZcpDT|d}`!)_q#27#iH z7X!N(*u@~S7Y?8EqkR&ZKJqbRN zv^~$IXuH?X&<3oVsmvY<9wC59Duv_9O3Y&_6(jwbG&w5W@#ZAJO7dk7`}* zN5LP}js_gne$4w2=?}Hn{XWz#=6ri#M4Q}D-t$G{&$`Z&_Zk;aM1egb|^K=wKCbMT)d{RPrrApM2b+C;G`M*1|;Un7>Uf!}Cf_@2?m`G1FY_)a?;`kgk@_d9Jsy|dcfdgru>^}g4()jN;8 zAGF?Ge}Mi4=w1MS0lF8UdjYZ%?W$i1@FMUcuvGK%E!BFh`3dQtkS6>Y?ea6yKVuC4 z2mEF2lJ{k#FKhMJUjcsw`GjS_n_9zXZ=rpK?lWJ}%d%8G&`(90NCU5dCo};~keT%m zkk5RJ{`z*Sjx}A^Ub5?0*Y)s1Z#^T;2XbG%YnHE`-NYBXFLeBoUl;ie^j>QM;VV!d z;vERPK)qy6Aaw52N4qtIyrKS0Ktu2iVdDVr(39&pVA~kB&0yOcvgWXD4xJXDR{Dk~ z+v=Ee`jp_d`q%b$$Zw|~4QL1Z2VfTryH2p{40&hRb%t(;z9%>Ywp}0#)v*Ua77AG? ze1t;QO&?gd8)V%e>!uI3^@OY^eD;K_r~Z3rPkp8@$$IHu`1aCY_v?kSdZVm9C@TW; zNXR3h8wuS==te>|5PAclHyCZ%0;d8K^a1q}fYX4}fYX7~fr-dZ1SX-JB>0+%c1T5= zr|L^qr-PrT2d>FRem2@A8||?GvE=BnZF7)b2wH@^T+}63KaiIPK2MKKFF>4yh;ykv zY1xxVuYkW5;8%iw8n_C2tMp5=SL+R*eOC9}v<~SaefRqHkZ;sCYi)2h(gyb-ZGmlZ zC(;hs4)-GMf$ed3@&N8lh=P&si2IX{(CvuygGfJ!^n*xuLb?;~RXQQv8R^bQcSial zq#r{1A*4f*4n;Z?>264OgKamYyCdBl>F!APK)MHF=z(-kq>jfSv&V z1h5eFBD+ z?N9`H5%?n9MQy+x)kfe($TuOq8Mqm^1-J#c6|@a;zX;#kVgC~F70?dIb|P;V%G(Xv zgS9Bq0IZTfG}51tcBF|sK%USi z@zNE7*k>M9%Yp7Ta?J*4ZwZ+)ce!*>JNG=S~{kO$)}><&nGM4IS9P$%#q zpe{&v1wDjxH&Az^dw_bvrneGq?yvZRnlTOl4uE_xXb5PSqMKuo9|OHuU@YN8L1?~mz1MLSL038Iq3qS8e_Ym+X_z!^};hym`&~eZyf8TXyD;cqVRG0;4enSp!H4EV}GekRhHz%1xw!{2h)tpKe=8BYUOL2o_e z&m+AVv<335z!yNtfH=eC-Q>3pKNr3;ANC zS3qwi^i~010q)RN+xKcN`#!{S0C*7myYT-H&BNt0(25Su4)&|*PwF^z6r0x z<~Ps{{(zeI0ge+sl5v;wpW@=e&YHi^fuez>d2;4JE6y0`k1?gI<~h5#1<7pa@I z>!5Nq*JRTk)4$e!0&UhVBHc^>3G|pg5I9ipp*2!^XmLuUvJtc&^e)IpZJ@lTOi}#Q zK;==;=V}{eyt+||SC1*v)K2Ph(DUjR#RXcfwNpM)?aIe$JEd52DxaxVrK>hWiPIvL zpSADB&mwQSo9LqUQoDG&iClFl<3w$$_R(NB@s0L_M)JzP;rajGtBW>6(X)auk z++mdI8dz97?snagc&(^AlH)?Myza;vic1!Kc`b^wD)XVbcY`owm4%k(*D#^*GphqK zydTQ4nn&)fkapA_s_<^znm$DMXk<)u*YM!39`5!^LElKLk<&NQJ})LdIerR07}ZwI zoYypS-e7z#)-f5MQFNrFIwmE=H_n`wIS-#VNS*7NnvguDai%nljZ|B=Ry-R6oDKih`MpAm+Z!= zUI&C|ICAeQ5w%lRZX@2M#QUZ$OLkB6bh=h@+srzJ#hWjq?fgZD<1tY?6{7_^9IVy4 zr>{XnSgU+-Dftm)`6F)0h+A#m4Lo5xKG*Ww@!wA6oUX_z6Z0(@?R%(VR;wBj zlt)x#XH}@FW|Xaz8ZE#jvkt!)F0U7ixN%RHwjNfIs*^cu=jDELJG=Os+hVp>GDy!Z z{DXu1E;Fr^GOG@5b=%xkqC8&;07!s69e>W<{*kv3K4wuAGv zlG9psNrlBr|44U$Q9@zy85CYvOdYfY4H|sjkQ?dz+*8-MkQ!Y@m7@r|3zuJa50`fZ zbcin~K6NcG=gVux=;**^Z6eA7N8Gxj2kK^+dgx-d7qyUw%enw|!kYd(b*Hre&e~Z- z!HvSVzC=VubbGC`y>ebXbD5&-Ol3{(;iXnSxv6fbGbqz=YP3Y{=6)+S}v-KF&d9m?Un1VdNVug zTjA=7C>x@Fyb9O-vsE~+)?&cUOS{*!uJ>owOYXM*Aa^sq3SksIoF*JQ+Z$9h%P6M5 zlhN>xEZpzTFnY4ayfGHhs-n1FMj(|thq2H?=2>%{<-lq*aqj8cImM@Mi!Ag5c`Jb6 z*%)J*82;=s8aBda{}Jt(?v+O$nZQTMa*p!>C_nsGNdEBhki+3Ov8R=RuJSqYunAyo z4q!)g#^^S@Ji|J_eMqUykZJ(%uZrJommv-G_xJ*{N4vGd?l zmbJ^SGB665%>~SqhTU9Ki~`127T~PXM*$&A!f$pDP7Uk+(CqHnSy%P6kiz1tbgs&( zTm!*lR**NS8V$t`SOX_>LsT-?n85#Ca54W)aAh@uE34W}|0pzd6*TD4lWj1Ivx9=2DGhwbWNoR{o8bP9_{ zpr!WWf#Q!2N!iWu-5h$EPcJv=rCc7l(yiH^LS&cRrx~qVJQ#=7>e0+Xeldn#e#EW( z5#@&?Fz9ke$i=tYi1G}}{AS%EZlyW0vu?(?8W=rqEK3+#R(6mVakKPO&euxLh~hA@ z^l=IhXH1kz!orVd=EXNJPVblmVQy`8=fPv9cTZac#cYMMa`thrmkPB zsUfU+z~_JpiwEA_j)hsj(+IyI*R3THH}EufY)QoL!RNL2_<+?<;ohLWRkGn$xVpnT zKW|VO(lvK?gIY0E=F|+NG)RUUSWESea0`oL?h$G6(7S~QG%up;u1b^zpAVC@==NTE zGF8C)FJiy1RzQCm`~9_4?})wB|DMrTmyUT+J(dmQ%F^h3)UcLw&f%9*FX{mc&n_0w zdhBTJh)hhxV^yLfk-pXFnBc-!jApnRJLt<=lR_P;qp9wQ8rj3#))6(JX^$Z2C(oLY zm@vsPnZGCEm@y$OZFWlPBuA?Jx=yI0O>0LueMKpLk|Qo9H8noY^@qysMPPLV#*DC%uAOzr@WIYVd=}l_wCMx#Q9mWIVy-gfw;($k#+Fo7pjyU=P z7A=NRX6~B>m!fccV#k)J@VeuwI>dY1XUE zrS;` zsUIL+Y;rZ{8QE4(9(GG=N*-)5&a$Y;#f+Du#>-Sw9`g+E7hUM*@XIc zIM_VjL~M2s;c9}WKpXBrP}M==2B$_e)jqIyYq)Wgwn%S~lTj;KC7V$zd4k%EW+pzq zPiL2!GxIdHm7JM)1~&?AX!NbiDedkWpN70TJj0T^^B#RV-^A@D$9#3H`NqQrTc9HI z3X8YZsx)U9gCIagV!yivRI};^sTmW^4<1)k>+0aDRajOP8#VqIqd4bvj8?@(9W2|T zb{KAdKaA=!cq(TNs~Y&$gR}Z@F6#aeZa4m_?(TOM%8?s^X(h{)>V{n;muRhIp2DT# zQfa0_YXRMY0SmBhanbol@=x22;XoIILl=(`%blg%ITQu?81F8ltcY734n8lRbMNu3}a> z*P|ff7PJbp&^U!zm_qdIza-)&qBVjDWbN7x*boa#K}0#(7MG#AwOSS;jEd?Ob9JGH z5IhMBZhUs(vkL`yqXo7c;-4V5ANw&}B95vDe=3#ZsxF69rC1~=50{O1EOT_Ov_{2* z#|{|o9Bhq!7a}I?z9sp~J|?*{H^uP^!SL z`gBVD=ro?~7F=@T{&uqwqzszl8)CYmTA(h0LGbzg^_1Vv9m003 z-B|F!hZW`;TMe{Ke@p9(a+j~>*_j^=fP+K#&T5CO7pvB$^;mLV#&Eg&_*31xw0bF- zTFG!)z4CK+mH+wJeq)y$+|c9^x`UfxFJ5_k=k6%~8w30Yv?T?0$IyNmv!r^+{jUsd za#?d|Q>oRJuP&^x_%&4FuI4tn?jGV#(4&RLZ{OP{4w>w_^u9mpfC`Mc(h>hRrSee3 z(*vqRBeMT(Oo8qSwxEB>yT@F)tbUNYyS$>}gWNaD6=MbIhGa%qPBFyk4{_n@(Q@iVJFuCrr|Y3#U8j+Q3J z#0lw>><`4mCnijom>AzmX=QWZ%k2~6Q$ro@j>xDg#x^K^?!=S{sgqjShYsu0dw9S0 zy<_{j8OZ^Zc7HfLmgLOP;>%yJHsQ9gZIWa9RHDLz7&lx{wMgl#i z(_?k~toX!GM-#P4`~MG*-9v}4LS`!fszoHfS)IF#37mlR~p?H7!UgG ztsRH-9{Ou=eABl(lNvRWNJEo@0b|g(mp6f_TNKSXfr}@%v2=tkd zJU!H5=)})<)TzwG)rNE#RC&um^^TuIZ}mD{uzVnHLL%-#5|R)>d&|i1!F`7f38%d# z&$vfka4FB7x0MetfGa9^XxDn*7K>m$&U(CR78cLJ6XD*bwMU;Eg&0J}A%WdhaXcDp zI{B-O8->(*N@WKS;x?{&b{LWHxc#G}IaGeDx!l$??t?Q+)zhkRzV*T$(bPEW;vL)i z*jcE=!eUab3;~s|wW7295B(Yw9ybNlXf+)Dp+RZuzpu;AXU#OGHtyvAund$YA3%%{ zs;XVu>3?MPU&L6W&WCd|@YYA}`I~gWq-O^@+Glv;S$&;C=lfKxWTkx2ppM9^>WD1b zw%b6X$0`#Js0-yIX)`1C4hQczrxg}2!QiQU95s5Njv=gW2)e6HzI%)r+E}1@kl%F& z#fx9bT=$Yv?&T3{NQC0P|<&=PoQO)hqB?P`t2=4&{g55u*9^MW^u9sYu3b zSMQ297M2+uRM|M~$(vHsX2Ays1RXRspsrOTvjC3sbF<0_slfE7>F7noON;DPql#_@ z=#;zDQsWsN-N^HoIAn zjCxd#x4UkmYE+Dl@QoIht$bKB{A(q2u;(GI+gsW^lW4LF3GV|xcK8uasicFDmbK!S5nhm4;eR47JeVB)Wq*0k|-M=+M;(5 z4bglOc^e{cL-dO=Ols|L#we&Bv#y7D3i8JLUp z!+dMT2;Ll`VAQ>FYGn7U+2Qvdmr$rNP0@%oPtiu3hVT=!p=HG4%NhJq^)5n{E=OUE zHSfaWc^IvQ#kqK;g(e%kaG9u+@$MgbI{p3{t}5pr_ov~8b*e^Sw_8S;7i7#_%B)T- zWPQ40<96zByxWNk^ZfeV-kt5w*(|MkUMV%MMLDP18jmg2j4{?9HC9-5j=RGD^~qgb z9&dq<%Nrov$NuFszsG$nEmqYYk*d15p(RN+%wOHd8neJ@^x(a&VR=cs$2II9mClW4 zEM>(w%wVVAsu|-*D_N@@&V8)RI2XtZ(r3G!nD36G%nE_dqZ@Q%m}@1E^K=fQ%j$dW zBem8*&pTIaV~XCZaX36GL&>yol%@6PWbzv%#scxIf*J3FX;rdK<;F>`&rNAe;~Z?@ zB0YsbNuNsfQc@@UjRhf{&Qi6G<{XI8Ftn8848GUv&T3F=DJ2fIMgRqcI2f*zH+?kj z=bJO)yS>Xnz{j1d()F50dkzAU>Y;K+5cJ7Ye8Ri-TNg$U&lyKeoJ5yZ-777|=|B0e z{Q2C|pV7;7hV4^zhV4oZ6BI(7J58iqZgn*t=Vg-LoHuYabbdKL)Wg{K7MzWl3k2!7d{^G*OQWmQa2os zD(^68BBkqsY)rRS-mcIIY+)Ildl6BsL2pDz z+w~uu^QxWX;K*!q8E;Ld8*fdzUgjCgt-~+8$#TjF5Fab9pf3f`-AizXjt_R~9MYxh zL%sX-?H3*)f;TAiyH6sxD{742EMpubF<#U?2C>MOxK843iAN-!k$7FAT`}w$OYAIh zu*C5aXDij^k3u=?QSMW~{lGau4BFuFz<)|KOZ{Tu2DNhQ2atcK3UPw@!}e2*N9}0z#xeaD0QQ}p&o(!@jxf!)J_ir z1@z*8m^>m$aXThND=}BvWk}o#B>jUx(*ID(KLs8Ee;aU-iHb zHgobPf9!|iS6$9{Ey_X%lw;?7rG-j4CT4$Mx1qZ!+(99;(Jgulzda* zc<6Ox`AC6Ji*ww4q}>>)H%?-L)Sn~u@^zyRTko01Kq&E&o{T633`n3Q^?Y|aCc|%!d3c>GwR4#(xRx%@E~MPcs{Oo@S%`dO#|_iJAP(5WSI4 z=fv02?yR)?!CY53P|ojWV;#7K{PEyT7DHagLh`0I`~n`!8%lW_mJhJCm+~%B-jC%| zZ2hG?O3KGdewySnEodLaoz40#+aj62)I#mFM?4Fj+NntDzXYE8=T+FzFS5UGaRg5V ze~j((ZU2(?-;!Un)A!&BEm*IpeZ3|27P6heTOpqcJP5s+GXDvQo21_RQtznLJC1dd z;<^c>apQ^ghvM>;>sw>FKDCnAORj6rdg>-O8ui4vzsOk_OZM15g@*q+XK z#6DN%&xb!MCs)*sa=`C0S>IKV(>Q((NbR{n;(pmq$H7zmuy1hv&Pv`_*0%?c^0Cfy z{xb@df51uWJH@|W*83=UD*vAfm2VSYLQd`UE#y@G_exzXwD>t;wtw5{!Rzo=QAe)d zt*}0mznL?EBa8^rR)Vyu);lOHor*&Z+klJk}kGCFT3%Ad9pO+b3wl~mz6yL`{+K;}G^7FFY zuSouP#ut6c8K>Axs2|w{0?Do|*MExbA&Jz^RL|;tmfB~EZ9M0P#3o9dDfO~s`xJ7& z^$;sKf4k2b_`d-^FEXF(+`*XW+#~I=|H5xb>_4QR<3O&5Z2xk(A6t0eyPV^Lc5MlN z4zvrkcQckRjR{6OZbQ3wmhBqKdW}Ud$@i1?!=QJ>gr5VJ^3kjpgkO{}`gxMX6ySLH z&tkh5eHMbJ@>a2aEAgDv+aU2JslQ+A9PACfqbTP)#Pd1Zw|1VE<$ue#H0HeIFGBAW z`u`{9J$!C3j;v?asa-y{docEm_0x^@EfD)7^;<{aQ?Tm+yn&yQ9VGQeU_Yhy8-sne zC1%uA@Dz8F+;3_B9uIyo>?pqFx)JY2>Hh_`8!ldvdT&d;52W4~T+Y&%vwELkEBySx ze2|ZZ{j#N4AUx!LSqJ;*LHKu=s2*Ltnt{is+eB*<)uWf_%h*Z`ft>0y8Ax%@X8n1d zkHZh~iy@x@EMotU^L|eCq5Yif-bOyv<6XA%@cCH!J;{8dAwMIZ%Duw&MM9PPqy_ur zYRKJre{Lh{$o;h?@0UwsLZn_d?5{1w77+%X$_r=x$+WNYIC@yh$FW|qh?D$O3?&ucs$H0-BTf2)Q1qmA$cPwgDUd@Iq8v4`j=`2oBi zNBP7^9K)FHjAMMFE5JG1z%r`u|G$|Bmhbl#9~-7a9Lm8Go6K-`h&%-mf&Y8s#>%8tvE;JjKR%6^HNdI#nr+Q|xpBUwFskaz**^n=n z{4-W#zO7|Fm$H%Vx94m{{&?u^unrCm0KR86=KB%G(c(DrX&(sW{k+`TOk#WN#}3Ft zm~UzempDkuW0}94GfARxPFNa~BI;s%sRBQ_9_&DQnVi2g=5g53^UM;dzg*PC575)O zfb@mfDsj8C-zn|(NI!V)4BmopQQLY;v5o;a(l>gNFUZ)8Z!j>w2#ChT2KiF1$LjgZ7#%*VCI6fl!Ru!c`>}}^rJq;D1eU+fde6>3!1#U6 zA;=x@_fKF;U>VEDW%{EYT}2&%F~IHEjO#Hjvm49(`T3mMcaW4%keHzu{rLpyMfEh! z6_;~fQKoY_yIAjX&R&V{O2l(I+IMNpCv2~Z<0#hw`>&+@JNTpVQzG>*<6KAWq^d@F zHi;gLs_^Cge`!nr_I>ix82di;Pji-sIy*CVbv~pT8+!faIbks8w{kiegPfxn z2M11KjB!q3Tk^<8CN?q7}q%GGj4V+WZddp%;%5MqCm#=B+ijt z@uTr;P(Jnhde&PSvmN;~ZgxOU?YSE~jT_@!IWF@U>y692AW_#Q@I8_j_J0~z&3WG+ zmx=Qu+IL*$Sc#8Gy+zD_pYt4JgZ^7^-k|gPtIRtF9FX$QAg4Htb4G*y-?My8{~sYo z8_RRXn*P_NzMb}Y$i0kx+==rA%C`?_gmXYwtSTLlPxTDJIe_+yZhTH?BYK0UxJR;H zPZ2Nmrpfa{3i~PcnGc@Y<7r?v*82_m96let2(&`}D(hX&*)7i>Z|TN3d5`(g;sbpV zuZJJ8p2O!Duy7dTeGBp2gMMnV za3o{ULb?Yd|8a6$PDQzNE=pp#BIZbWri_c8i|8Co_hZyQt60xVJSX`Lh<5|zFG+qU z=lh90lHU&;kNl%t{t-Lw&k)aH`&W?Dc=?t2_w2VA58CNIjmpz74yimV&e36_f$)%g z9U%E@%;WNqy#;vk^APJfL{F*LSL(&c{CLi9Bc{px+UNFF_`M;D>l15%)L+N??ZhUj z{{rW)vcD|(*MJnqL8*U&^}7h1(K+sKr2aX{)4d$&Uzhqe%!e@it0JD54^&TInqR;s za$dCKae2_*o$)<;7~@2revIRNhA|$ok77J*pTyYFCy6oGXC~to&rCV5mIG;he_qO8 zl(+}wl6*hMGZgd4XwQ$KPxJUQo+oX@N$@kE_miAA*TK`ef_Z~>3&uZ1LD ziO;j2V4v-b9erM7Kk?!n>E}J^=L6~I6Y1xB)_-;6uZ&wq_?n;O^&^&W#CbXx^LY*M25>!a8|w2q zZ~$;Ga1P|}NIA~uEdN5vzmoD_r2MLs|Bmx{m`KGxono|;O`dN(aqbNh^Mpgnn?X+V zs0(-+U)`l%Z+Q;xFVDeaEk=DN z{f*N81^Acqk>_1A&dJo@ZhVeyBYeP9f47k5+hB>E z`5b&Xr#sHYVPdfu0Q*tU8zSvvq&?2#Y@f{f@A%ASEcVHQoZ?&wqw@Ivp}4X<(z^Y#eGr6{R?=C`>HIr3_Qi{Z8OG0eTgk?)Sj1fI@*kVt*hjRNgTzv zG-iy=I2TQl@+8K$oio|bed00ZyE-!&L!Ap4ujedeypfZ~IKo-L`1qWqjH8^(81qtB zG9GZQwo$)7sIHg%R*A2$JQ)Al2F3ffbDzY6QvMIge=P9?W2p06#;(qDHsk#DZ(ugs z;a8inzFgz{R?gduK~BX^{s#woFvd8&8CN>}8CN;+k0&92t@D1yBBz6KwX+%H8fQz! z&CYg=Tb;p-CwxK}gPh$N2L}#djByTPjBpNP?B^V1H}=_aQa(w_6B!-OnRXgqOU2`M zV|*=^^5x(Wm{M?k(8@-b3ANy^hD{}}S=+?XTz0-66LW7zPO$fxt; zvr@hhJe?c2B96V7CwtwfT^EQCAg6izG2}F#z6DS1`8{}=Pd{?JZN$&uXF#sI8}WO% zQ#~6E@o_i&)s^z5?&Nouc);E8+X?yP=ONB-BYJ@+Kf~F6X-u5do62_kL=t!^Kb7?- zi%jTKT)9$Szyt=w_%kJ8NLG2Lc(^z5%<2%kU4{8TLWw3|Q4$;u3b{OG7?bk*; z0-o9-mGzg#WJ|q8YuoQ8}TTf#yVp5r26$z ze8G=`Jiyba-~FCO{hETO`aR@H?GxmTWE|XRIOEVp4>PuMKEfF4bTM{y&ha$Ln+K%w za%Fi1vb@!@ymhj?O|ragvbyo`F!gM26C%ccD~X}?9{cE**?HyKws-;#Jh%8y7q zCgmp>pK^Z9xZL?2V~q1h8P82Ff4XABKe0{i?&)pJ4+nUPvza%=H(zNj`3I0sX!-LRNtjBv!tJSY`0v=mUfGvN6#Zmyp8$(6zhBVtd#r)iCb9S%K0+m<(!>T zzMrv&_=x?!shpPOoPl4O2j@AzjkpNDC7$!HNIk2MQ7;c4qh5``Q@w(~lU*wxV|+aT op6t3xKAf?Y7|b|Y#3Fwu;vWedh5mU&$|r)SbKqpDpXl@d08i4{+W-In literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MAIL0.TPU b/SOURCE/UNUSED/MAIL0.TPU new file mode 100644 index 0000000000000000000000000000000000000000..ccf804d7e9800b96188c7b82204b9de0c02f9308 GIT binary patch literal 34000 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 -1) THEN + BEGIN + An := MemMsgArea.Anonymous; + IF (An = ATNo) AND (AACS(General.AnonPubPost) AND (NOT Offline)) THEN + An := ATYes; + IF (RPostAn IN ThisUser.Flags) THEN + An := ATNo; + END + ELSE IF (AACS(General.AnonPrivPost)) THEN + An := ATYes + ELSE + An := ATNo; + IF (Offline) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + IF (An = ATNo) THEN + FOR Counter := 1 TO 5 DO + BEGIN + HeaderL := Headerline(MHeader,FileSize(MsgHdrF),FileSize(MsgHdrF),Counter); + IF (HeaderL <> '') THEN + PrintACR(HeaderL); + END + ELSE + BEGIN + ReadMsg(FileSize(MsgHdrF),FileSize(MsgHdrF),FileSize(MsgHdrF)); + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + IF (IOResult <> 0) THEN + SysOpLog('Anon: error opening message areas.'); + END; + END; + CASE An OF + ATNo : ; + ATForced : IF (CoSysOp) THEN + MHeader.From.Anon := 2 + ELSE + MHeader.From.Anon := 1; + ATYes : BEGIN + NL; + IF PYNQ(AOnOff(ReadMsgArea <> - 1,'Post anonymously? ','Send anonymously? '),0,FALSE) THEN + IF (CoSysOp) THEN + MHeader.From.Anon := 2 + ELSE + MHeader.From.Anon := 1; + END; + ATDearAbby : BEGIN + NL; + Print(AOnOff(ReadMsgArea <> - 1,'Post as:','Send as:')); + NL; + Print('1. Abby'); + Print('2. Problemed Person'); + Print('3. '+Caps(ThisUser.Name)); + NL; + Prt('Which? '); + OneK(Cmd,'123'^M,TRUE,TRUE); + CASE Cmd OF + '1' : MHeader.From.Anon := 3; + '2' : MHeader.From.Anon := 4; + END; + END; + ATAnyName : BEGIN + NL; + Print('You can post under any name in this area.'); + NL; + Prt('Name: '); + InputDefault(UName,MHeader.From.A1S,36,[InterActiveEdit],TRUE); + IF (UName <> MHeader.From.A1S) THEN + BEGIN + MHeader.From.Anon := 5; + MHeader.From.A1S := Caps(UName); + END; + END; + END; +END; + +FUNCTION Inputmessage(Pub, + IsReply: Boolean; + CONST MsgTitle: Str40; + VAR MHeader: MHeaderRec; + CONST ReadInMsg: Astr): Boolean; +TYPE + LinePointer = ^LineArray; + LineArray = ARRAY [1..500] OF STRING[120]; +VAR + LinePtr: LinePointer; + PhyLine: ARRAY [1..20] OF STRING[78]; + TotalLines: 1..500; + + MsgSubj: Str40; + + MsgTo, + UserName: Str36; + + MaxLines, + LastQuoteLine, + MaxQuoteLines, + CurrentLine, + TopLine, + CCol: Integer; + + DisableMCI, + CantAbort, + Insert_Mode, + SaveMsg: Boolean; + + PROCEDURE ANSIG(X,Y: Byte); + BEGIN + IF (ComPortSpeed > 0) THEN + IF (OkAvatar) THEN + SerialOut(^V^H+Chr(Y)+Chr(X)) + ELSE + SerialOut(#27+'['+IntToStr(Y)+';'+IntToStr(X)+'H'); + IF (WantOut) THEN + GoToXY(X,Y); + END; + + PROCEDURE DoLines; + BEGIN + IF (OkANSI OR OkAvatar) THEN + Print('^4::::::::::::::Ŀ^1') + ELSE + Print('[---:----:----:----:----:----:----:----|----:----:----:----:----:----:----:---]'); + END; + + PROCEDURE Count_Lines; + BEGIN + TotalLines := MaxLines; + WHILE (TotalLines > 0) AND (Length(LinePtr^[TotalLines]) = 0) DO + Dec(TotalLines); + END; + + PROCEDURE Append_Space; + BEGIN + LinePtr^[CurrentLine] := LinePtr^[CurrentLine]+' '; + END; + + FUNCTION CurLength: Integer; + BEGIN + CurLength := Length(LinePtr^[CurrentLine]); + END; + + FUNCTION Line_Boundry: Boolean; + {is the cursor at either the start OF the END OF a line?} + BEGIN + Line_Boundry := (CCol = 1) OR (CCol > CurLength); + END; + + FUNCTION CurChar: Char; + {return the character under the cursor} + BEGIN + IF (CCol <= CurLength) THEN + CurChar := LinePtr^[CurrentLine][CCol] + ELSE + CurChar := ' '; + END; + + FUNCTION LastChar: Char; + {return the last character on the current line} + BEGIN + IF (CurLength = 0) THEN + LastChar := ' ' + ELSE + LastChar := LinePtr^[CurrentLine][CurLength]; + END; + + PROCEDURE Remove_Trailing; + BEGIN + WHILE (Length(LinePtr^[CurrentLine]) > 0) AND (LinePtr^[CurrentLine][Length(LinePtr^[CurrentLine])] <= ' ') DO + Dec(LinePtr^[CurrentLine][0]); + END; + + FUNCTION Delimiter: Boolean; + {return TRUE IF the current character is a Delimiter FOR words} + BEGIN + CASE CurChar OF + '0'..'9', 'a'..'z', 'A'..'Z', '_': + Delimiter := FALSE; + ELSE + Delimiter := TRUE; + END; + END; + + PROCEDURE Reposition( x: Boolean); + VAR + Eol: Integer; + BEGIN + IF (x) THEN + BEGIN + Eol := (CurLength + 1); + IF (CCol > Eol) THEN + CCol := Eol; + END; + Count_Lines; + ANSIG(CCol,((CurrentLine - TopLine) + TopScreen)); + IF (Pos('>',Copy(LinePtr^[CurrentLine],1,4)) > 0) THEN + Usercolor(3) + ELSE + Usercolor(1); + END; + + PROCEDURE Set_PhyLine; + {set physical line to match logical line (indicates display update)} + BEGIN + PhyLine[((CurrentLine - TopLine) + 1)] := LinePtr^[CurrentLine]; + END; + + PROCEDURE Clear_Eol; + BEGIN + IF (NOT OkAvatar) THEN + SerialOut(#27'[K') + ELSE + SerialOut(^V^G); + IF (WantOut) THEN + ClrEOL; + END; + + PROCEDURE Truncate_Line; + {update screen after changing END-OF-line} + BEGIN + IF (CCol > 0) THEN + LinePtr^[CurrentLine][0] := Chr(CCol - 1); + Reposition(TRUE); + Clear_Eol; + {Set_PhyLine; don't understand this} + END; + + PROCEDURE Refresh_Screen; + VAR + PLine, + PCol, + Phline, + Junk: Integer; + BEGIN + IF (CurrentLine >= MaxLines) THEN + CurrentLine := MaxLines; + PLine := CurrentLine; + CurrentLine := TopLine; + PCol := CCol; + CCol := 1; + FOR Junk := TopLine TO ((TopLine + ScreenLines) - 1) DO + BEGIN + CurrentLine:= Junk; + Phline := ((CurrentLine - TopLine) + 1); + IF (CurrentLine > MaxLines) THEN + BEGIN + Reposition (TRUE); + Prompt('^9--'); + PhyLine[Phline] := '--'; + Clear_Eol; + END + ELSE + BEGIN + IF (LinePtr^[CurrentLine] <> PhyLine[Phline]) THEN + BEGIN + Reposition (TRUE); + MCIAllowed := FALSE; + ColorAllowed := FALSE; + AllowAbort := FALSE; + PrintMain(Copy(LinePtr^[CurrentLine],1,LineMaxLen)); + MCIAllowed := TRUE; + ColorAllowed := TRUE; + AllowAbort := TRUE; + IF (CurLength < Length(PhyLine[Phline])) THEN + Clear_Eol; + Set_PhyLine; + END; + END; + END; + Tleft; + CCol := PCol; + CurrentLine := PLine; + Reposition(TRUE); + END; + + PROCEDURE Scroll_Screen(Lines: Integer); + BEGIN + Inc(TopLine,Lines); + IF (CurrentLine < TopLine) OR (CurrentLine >= (TopLine + ScreenLines)) THEN + TopLine := ((CurrentLine - ScreenLines) DIV 2); + IF (TopLine < 1) THEN + TopLine := 1 + ELSE IF (TopLine >= MaxLines) THEN + Dec(TopLine,ScrollSize DIV 2); + Refresh_Screen; + END; + + PROCEDURE Cursor_Up; + BEGIN + IF (CurrentLine > 1) THEN + Dec(CurrentLine); + IF (CurrentLine < TopLine) THEN + Scroll_Screen(-ScrollSize) + ELSE + Reposition(FALSE); + END; + + PROCEDURE Cursor_Down; + BEGIN + Inc(CurrentLine); + IF (CurrentLine >= MaxLines) THEN + BEGIN + CurrentLine := MaxLines; + IF (InportFileOpen) THEN + BEGIN + InportFileOpen := FALSE; + Close(InportFile); + END; + END; + IF ((CurrentLine - TopLine) >= ScreenLines) THEN + Scroll_Screen(ScrollSize) + ELSE + Reposition(FALSE); + END; + + PROCEDURE Cursor_EndLine; + BEGIN + CCol := 79; (* Should this be 78 *) + Reposition(TRUE); + END; + + PROCEDURE Cursor_StartLine; + BEGIN + CCol := 1; + Reposition(TRUE); + END; + + PROCEDURE Cursor_Left; + BEGIN + IF (CCol = 1) THEN + BEGIN + Cursor_Up; + Cursor_EndLine; + END + ELSE + BEGIN + Dec(CCol); + IF (NOT OkAvatar) THEN + SerialOut(#27'[D') + ELSE + SerialOut(^V^E); + GoToXY((WhereX - 1),WhereY); + END; + END; + + PROCEDURE Cursor_Right; + BEGIN + IF (CCol > CurLength) THEN + BEGIN + CCol := 1; + Cursor_Down; + END + ELSE + BEGIN + OutKey(CurChar); + Inc(CCol); + END; + END; + + PROCEDURE Cursor_WordRight; + BEGIN + IF (Delimiter) THEN + BEGIN + {skip blanks right} + REPEAT + Cursor_Right; + IF (Line_Boundry) THEN + Exit; + UNTIL (NOT Delimiter); + END + ELSE + BEGIN + {find Next blank right} + REPEAT + Cursor_Right; + IF (Line_Boundry) THEN + Exit; + UNTIL (Delimiter); + {THEN move to a Word start (recursive)} + Cursor_WordRight; + END; + END; + + PROCEDURE Cursor_WordLeft; + BEGIN + IF (Delimiter) THEN + BEGIN + {skip blanks left} + REPEAT + Cursor_Left; + IF (Line_Boundry) THEN + Exit; + UNTIL (NOT Delimiter); + {find Next blank left} + REPEAT + Cursor_Left; + IF (Line_Boundry) THEN + Exit; + UNTIL (Delimiter); + {move to start OF the Word} + Cursor_Right; + END + ELSE + BEGIN + {find Next blank left} + REPEAT + Cursor_Left; + IF (Line_Boundry) THEN + Exit; + UNTIL (Delimiter); + {AND THEN move a Word left (recursive)} + Cursor_WordLeft; + END; + END; + + PROCEDURE Delete_Line; + {Delete the line at the cursor} + VAR + LineNum1: Integer; + BEGIN + FOR LineNum1 := CurrentLine TO (MaxLines - 1) DO + LinePtr^[LineNum1] := LinePtr^[LineNum1 + 1]; + LinePtr^[MaxLines] := ''; + IF (CurrentLine <= TotalLines) AND (TotalLines > 1) THEN + Dec(TotalLines); + END; + + PROCEDURE Insert_Line(CONST Contents: Astr); + {open a new line at the cursor} + VAR + LineNum1: Integer; + BEGIN + FOR LineNum1 := MaxLines DOWNTO (CurrentLine + 1) DO + LinePtr^[LineNum1] := LinePtr^[LineNum1 - 1]; + LinePtr^[CurrentLine] := Contents; + IF (CurrentLine < TotalLines) THEN + Inc(TotalLines); + IF (CurrentLine > TotalLines) THEN + TotalLines := CurrentLine; + END; + + PROCEDURE Reformat_Paragraph; + BEGIN + Remove_Trailing; + CCol := CurLength; + {FOR each line OF the paragraph} + WHILE (CurChar <> ' ') DO + BEGIN + {FOR each Word OF the current line} + REPEAT + {determine Length OF first Word on the following line} + Inc(CurrentLine); + Remove_Trailing; + CCol := 1; + WHILE (CurChar <> ' ') DO + Inc(CCol); + Dec(CurrentLine); + {hoist a Word From the following line IF it will fit} + IF (CCol > 1) AND ((CCol + CurLength) < LineMaxLen) THEN + BEGIN + IF (CurLength > 0) THEN + BEGIN + {add a second space after sentences} + CASE LastChar OF + '.', '?', '!': + Append_Space; + END; + Append_Space; + END; + LinePtr^[CurrentLine] := LinePtr^[CurrentLine] + Copy(LinePtr^[CurrentLine + 1],1,(CCol - 1)); + {remove the hoisted Word} + Inc(CurrentLine); + WHILE (CurChar = ' ') AND (CCol <= CurLength) DO + Inc(CCol); + Delete(LinePtr^[CurrentLine],1,(CCol - 1)); + IF (CurLength = 0) THEN + Delete_Line; + Dec(CurrentLine); + END + ELSE + CCol := 0; {END OF line} + UNTIL (CCol = 0); + {no more lines will fit - either time FOR Next line, OR END OF paragraph} + Inc(CurrentLine); + CCol := 1; + Remove_Trailing; + END; + END; + + PROCEDURE Word_Wrap; + {line is full AND a character must be inserted. perform Word-wrap, + updating screen AND leave ready FOR the insertion} + VAR + TempStr1: AStr; + PCol, + PLine: Integer; + BEGIN + Remove_Trailing; + PLine := CurrentLine; + PCol := CCol; + {find start OF Word to wrap} + CCol := CurLength; + WHILE (CCol > 0) AND (CurChar <> ' ') DO + Dec(CCol); + {cancel wrap IF no spaces IN whole line} + IF (CCol = 0) THEN + BEGIN + CCol := 1; + Cursor_Down; + Exit; + END; + {get the portion to be moved down} + Inc(CCol); + TempStr1 := Copy(LinePtr^[CurrentLine],CCol,LineMaxLen); + {remove it From current line AND refresh screen} + Truncate_Line; + {place Text on open a new line following the cursor} + Inc(CurrentLine); + Insert_Line(TempStr1); + {join the wrapped Text WITH the following lines OF Text} + Reformat_Paragraph; + {restore cursor to proper position after the wrap} + CurrentLine := PLine; + IF (PCol > CurLength) THEN + BEGIN + CCol := (PCol - CurLength); {position cursor after wrapped Word} + Inc(CurrentLine); {Cursor_Down;} + END + ELSE + CCol := PCol; {restore original cursor position} + IF ((CurrentLine - TopLine) >= ScreenLines) THEN + Scroll_Screen(ScrollSize) + ELSE + Refresh_Screen; + END; + + PROCEDURE Join_Lines; + {join the current line WITH the following line, IF possible} + BEGIN + Inc(CurrentLine); + Remove_Trailing; + Dec(CurrentLine); + Remove_Trailing; + IF ((CurLength + Length(LinePtr^[CurrentLine + 1])) >= LineMaxLen) THEN + Exit; + IF (LastChar <> ' ') THEN + Append_Space; + LinePtr^[CurrentLine] := LinePtr^[CurrentLine]+LinePtr^[CurrentLine + 1]; + Inc(CurrentLine); + Delete_Line; + Dec(CurrentLine); + Refresh_Screen; + END; + + PROCEDURE Split_Line; + {splits the current line at the cursor, leaves cursor IN original position} + VAR + TempStr1: AStr; + PCol: Integer; + BEGIN + PCol := CCol; + Remove_Trailing; {get the portion FOR the Next line} + TempStr1 := Copy(LinePtr^[CurrentLine],CCol,LineMaxLen); + Truncate_Line; + CCol := 1; {open a blank line} + Inc(CurrentLine); + Insert_Line(TempStr1); + IF ((CurrentLine - TopLine) > (ScreenLines - 2)) THEN + Scroll_Screen(ScrollSize) + ELSE + Refresh_Screen; + Dec(CurrentLine); + CCol := PCol; + END; + + PROCEDURE Cursor_NewLine; + BEGIN + IF (Insert_Mode) THEN + Split_Line; + CCol := 1; + Cursor_Down; + END; + + PROCEDURE FS_Reformat; + {reformat paragraph, update display} + VAR + PLine: Integer; + BEGIN + PLine := CurrentLine; + Reformat_Paragraph; + {find start OF Next paragraph} + WHILE (CurLength = 0) AND (CurrentLine <= TotalLines) DO + Inc(CurrentLine); + {find top OF screen FOR Redisplay} + WHILE ((CurrentLine - TopLine) > (ScreenLines - 2)) DO + BEGIN + Inc(TopLine,ScrollSize); + PLine := TopLine; + END; + Refresh_Screen; + END; + + PROCEDURE Insert_Char(C1: Char); + BEGIN + IF (CCol < CurLength) THEN + BEGIN + Remove_Trailing; + IF (CCol > CurLength) THEN + Reposition(TRUE); + END; + IF (Insert_Mode AND (CurLength >= LineMaxLen)) OR (CCol > LineMaxLen) THEN + BEGIN + IF (CCol <= LineMaxLen) THEN + Word_Wrap + ELSE IF (C1 = ' ') THEN + BEGIN + Cursor_NewLine; + Exit; + END + ELSE IF (LastChar = ' ') THEN + Cursor_NewLine {nonspace w/space at END-line is newline} + ELSE + Word_Wrap; {otherwise wrap Word down AND continue} + END; + {Insert character into the middle OF a line} + IF (Insert_Mode) AND (CCol <= CurLength) THEN + BEGIN + Insert(C1,LinePtr^[CurrentLine],CCol); + {update display line following cursor} + MCIAllowed := FALSE; + ColorAllowed := FALSE; + AllowAbort := FALSE; + PrintMain(Copy(LinePtr^[CurrentLine],CCol,LineMaxLen)); + MCIAllowed := TRUE; + ColorAllowed := TRUE; + AllowAbort := TRUE; + {position cursor FOR Next insertion} + Inc(CCol); + Reposition(TRUE); + END + ELSE + BEGIN {append a character to the END OF a line} + WHILE (CurLength < CCol) DO + Append_Space; + LinePtr^[CurrentLine][CCol] := C1; + {advance the cursor, updating the display} + Cursor_Right; + END; + Set_PhyLine; + END; + + PROCEDURE Delete_Char; + BEGIN + {Delete whole line IF it is empty} + IF (CCol > CurLength) AND (CurLength > 0) THEN + Join_Lines + ELSE IF (CCol <= CurLength) THEN + BEGIN {Delete IN the middle OF a line} + Delete(LinePtr^[CurrentLine],CCol,1); + MCIAllowed := FALSE; + ColorAllowed := FALSE; + AllowAbort := FALSE; + PrintMain(Copy(LinePtr^[CurrentLine],CCol,LineMaxLen)+' '); + MCIAllowed := TRUE; + ColorAllowed := TRUE; + AllowAbort := TRUE; + Reposition(TRUE); + Set_PhyLine; + END; + END; + + PROCEDURE Delete_WordRight; + BEGIN + IF (CurChar = ' ') THEN + REPEAT {skip blanks right} + Delete_Char; + UNTIL (CurChar <> ' ') OR (CCol > CurLength) + ELSE + BEGIN + REPEAT {find Next blank right} + Delete_Char; + UNTIL (Delimiter); + Delete_Char; + END; + END; + + PROCEDURE Page_Down; + BEGIN + IF ((TopLine + ScreenLines) < MaxLines) THEN + BEGIN + Inc(CurrentLine,ScrollSize); + Scroll_Screen(ScrollSize); + END; + END; + + PROCEDURE Page_Up; + BEGIN + IF (TopLine > 1) THEN + BEGIN + Dec(CurrentLine,ScrollSize); + IF (CurrentLine < 1) THEN + CurrentLine := 1; + Scroll_Screen(-ScrollSize); + END + ELSE + BEGIN + CurrentLine := 1; + CCol := 1; + Scroll_Screen(0); + END; + END; + + PROCEDURE FS_Insert_Line; + {open a blank line, update display} + BEGIN + Insert_Line(''); + IF ((CurrentLine - TopLine) > (ScreenLines - 2)) THEN + Scroll_Screen(ScrollSize) + ELSE + Refresh_Screen; + END; + + PROCEDURE FS_Delete_Line; + {Delete the line at the cursor, update display} + BEGIN + Delete_Line; + Refresh_Screen; + END; + + PROCEDURE Display_Insert_Status; + BEGIN + ANSIG(69,1); + Prompt('^1(Mode: '); + IF (Insert_Mode) THEN + Prompt('INS)') + ELSE + Prompt('OVR)'); + END; + + PROCEDURE Prepare_Screen; + VAR + Counter: Integer; + BEGIN + CLS; + ANSIG(1,1); + IF (TimeWarn) THEN + Prompt(^G^G' |12Warning: |10You have less than '+IntToStr(NSL DIV 60 + 1)+' '+ + Plural('minute',NSL DIV 60 + 1)+' remaining online!') + ELSE + BEGIN + Prompt('^1(Ctrl-Z = Help) ^5To:^1 '+PadLeftStr(MsgTo,20)+' ^5Subj: ^1'); + IF (MHeader.FileAttached = 0) THEN + Print(PadLeftStr(MsgSubj,20)) + ELSE + Print(PadLeftStr(StripName(MsgSubj),20)); + Display_Insert_Status; + END; + ANSIG(1,2); + DoLines; + FOR Counter := 1 TO ScreenLines DO {physical lines are now invalid} + PhyLine[Counter] := ''; + Scroll_Screen(0); {causes Redisplay} + END; + + PROCEDURE Redisplay; + BEGIN + TopLine := ((CurrentLine - ScreenLines) DIV 2); + Prepare_Screen; + END; + + PROCEDURE FS_Help; + BEGIN + CLS; + PrintF('FSHELP'); + PauseScr(FALSE); + Prepare_Screen; + END; + + PROCEDURE DoQuote(RedrawScreen: Boolean); + VAR + QuoteFile: Text; + TempStr1: AStr; + Fline, + Nline, + QuoteLi: Integer; + Done: Boolean; + + PROCEDURE GetOut(x: Boolean); + BEGIN + IF (x) THEN + Close(QuoteFile); + IF (InvisEdit) AND (RedrawScreen) THEN + Prepare_Screen; + MCIAllowed := TRUE; + END; + + BEGIN + Assign(QuoteFile,'TEMPQ'+IntToStr(ThisNode)); + Reset(QuoteFile); + IF (IOResult <> 0) THEN + Exit; + IF (MaxQuoteLines = 0) THEN + BEGIN + WHILE NOT EOF(QuoteFile) DO + BEGIN + ReadLn(QuoteFile,TempStr1); + Inc(MaxQuoteLines); + END; + Close(QuoteFile); + Reset(QuoteFile); + END; + + MCIAllowed := FALSE; + Done := FALSE; + + REPEAT + Abort := FALSE; + Next := FALSE; + CLS; + QuoteLi := 0; + IF (LastQuoteLine > 0) THEN + WHILE NOT EOF(QuoteFile) AND (QuoteLi < LastQuoteLine) DO + BEGIN + ReadLn(QuoteFile,TempStr1); + Inc(QuoteLi); + END; + IF EOF(QuoteFile) THEN + BEGIN + LastQuoteLine := 0; + QuoteLi := 0; + Reset(QuoteFile); + END; + WHILE (NOT EOF(QuoteFile)) AND ((QuoteLi - LastQuoteLine) < (PageLength - 4)) DO + BEGIN + ReadLn(QuoteFile,TempStr1); + Inc(QuoteLi); + TempStr1 := Copy(PadRightInt(QuoteLi,Length(IntToStr(MaxQuoteLines)))+':'+TempStr1,1,LineMaxLen); + PrintACR('^3'+TempStr1); + END; + Close(QuoteFile); + Reset(QuoteFile); + REPEAT + NL; + Prt('First line to quote [^5?^4=^5Help^4]: '); + Scaninput(TempStr1,'HQ?'^M); + IF (TempStr1 = '?') THEN + BEGIN + NL; + Print('^1<^3Q^1>uit, <^3H^1>eader, <^3?^1>Help, or first line to quote.'); + END + ELSE IF (TempStr1 = 'H') THEN + BEGIN + WHILE (TempStr1 > '') AND (NOT EOF(QuoteFile)) AND (CurrentLine <= MaxLines) DO + BEGIN + ReadLn(QuoteFile,TempStr1); + IF (InvisEdit) THEN + Insert_Line(TempStr1) + ELSE + BEGIN + LinePtr^[TotalLines] := TempStr1; + Inc(TotalLines); + END; + Inc(CurrentLine); + END; + Close(QuoteFile); + Reset(QuoteFile); + TempStr1 := 'H'; + END; + UNTIL ((TempStr1 <> '?') AND (TempStr1 <> 'H')) OR (HangUp); + Fline := StrToInt(TempStr1); + IF (Fline <= 0) THEN + LastQuoteLine := QuoteLi; + IF (TempStr1 = 'Q') THEN + Done := TRUE; + IF (Fline > MaxQuoteLines) OR (HangUp) THEN + BEGIN + GetOut(TRUE); + Exit; + END; + IF (Fline > 0) THEN + BEGIN + Prt('Last line to quote: '); + Scaninput(TempStr1,'Q'^M); + IF (TempStr1 <> #13) THEN + Nline := StrToInt(TempStr1) + ELSE + Nline := Fline; + IF (Nline < Fline) OR (Nline > MaxQuoteLines) THEN + BEGIN + GetOut(TRUE); + Exit; + END; + Nline := ((Nline - Fline) + 1); + WHILE (NOT EOF(QuoteFile)) AND (Fline > 1) DO + BEGIN + Dec(Fline); + ReadLn(QuoteFile,TempStr1); + END; + IF (NOT InvisEdit) THEN + CurrentLine := TotalLines; + WHILE (NOT EOF(QuoteFile)) AND (Nline > 0) AND (CurrentLine <= MaxLines) DO + BEGIN + Dec(Nline); + ReadLn(QuoteFile,TempStr1); + IF (InvisEdit) THEN + Insert_Line(TempStr1) + ELSE + BEGIN + LinePtr^[TotalLines] := TempStr1; + Inc(TotalLines); + END; + Inc(CurrentLine); + END; + Done := TRUE; + END; + UNTIL (Done) OR (HangUp); + GetOut(TRUE); + LastError := IOResult; + END; + + PROCEDURE FS_Editor; + VAR + GKey: Word; + SaveTimeWarn: Boolean; + BEGIN + InvisEdit := TRUE; + Insert_Mode := TRUE; + SaveTimeWarn := TimeWarn; + Count_Lines; + IF (TotalLines > 0) THEN + CurrentLine := (TotalLines + 1) + ELSE + CurrentLine := 1; + CCol := 1; + TopLine := 1; + ScreenLines := (PageLength - 4); + IF (ScreenLines > 20) THEN + ScreenLines := 20; + WHILE (CurrentLine - TopLine) > (ScrollSize + 3) DO + Inc(TopLine,ScrollSize); + Prepare_Screen; + REPEAT + IF ((InportFileOpen) AND (Buf = '')) THEN + IF (NOT EOF(InportFile)) THEN + BEGIN + ReadLn(InportFile,Buf); + Buf := Buf + ^M + END + ELSE + BEGIN + Close(InportFile); + InportFileOpen := FALSE; + END; + IF (TimeWarn) AND (NOT SaveTimeWarn) THEN + BEGIN + ANSIG(1,1); + Prompt(^G^G' |12Warning: |10You have '+IntToStr(NSL DIV 60)+' minute(s) remaining online!'); + ANSIG(CCol,((CurrentLine - TopLine) + TopScreen)); + SaveTimeWarn := TRUE; + END; + GKey := GetKey; + CASE GKey OF + 47 : + IF (CCol = 1) AND (NOT InportFileOpen) THEN + GKey := 27 + ELSE + Insert_Char(Char(GKey)); + 127 : + Delete_Char; + 32..254 : + Insert_Char(Char(GKey)); + 8 : BEGIN + IF (CCol = 1) THEN + BEGIN + Cursor_Left; + Join_Lines; + END + ELSE + BEGIN + Cursor_Left; + Delete_Char; + END; + END; + F_CTRLLEFT,1 : + Cursor_WordLeft; { ^A } + 2 : FS_Reformat; { ^B } + F_PGDN,3 : + Page_Down; { ^C } + F_RIGHT,4 : + Cursor_Right; { ^D } + F_UP,5 : + Cursor_Up; { ^E } + F_CTRLRIGHT,6 : + Cursor_WordRight; { ^F } + F_DEL,7 : + Delete_Char; { ^G } + 9 : REPEAT + Insert_Char(' '); + UNTIL ((CCol MOD 5) = 0); { ^I } + 10 : + Join_Lines; { ^J } + F_END,11 : + Cursor_EndLine; { ^K } + 12 : + Redisplay; { ^L } + 13 : + Cursor_NewLine; { ^M } + 14 : + BEGIN + Split_Line; + Reposition(TRUE); + END; { ^N } + 16 : + BEGIN { ^P } + GKey := GetKey; + IF (GKey IN [0..9,Ord('0')..Ord('9')]) THEN + BEGIN + Insert_Char('^'); + Insert_Char(Char(GKey)); + END + ELSE + Buf := Char(GKey); + GKey := 0; + END; + 17 : + DoQuote(TRUE); { ^Q } + F_PGUP,18 : + Page_Up; { ^R } + F_LEFT,19 : + Cursor_Left; { ^S } + 20 : + Delete_WordRight;{ ^T } + F_INS,22 : + BEGIN { ^V } + Insert_Mode := NOT Insert_Mode; + Display_Insert_Status; + Reposition(TRUE); + END; + F_HOME,23 : + Cursor_StartLine; { ^W } + F_DOWN,24 : + Cursor_Down; { ^X } + 25 : + FS_Delete_Line; { ^Y } + 26 : + FS_Help; { ^Z } + END; + UNTIL ((GKey = 27) AND (NOT InportFileOpen)) OR (HangUp); + IF (InportFileOpen) THEN + BEGIN + Close(InportFile); + InportFileOpen := FALSE; + END; + Count_Lines; + InvisEdit := FALSE; + END; + + PROCEDURE PrintMsgTitle; + BEGIN + CLS; + (* + Print(FString.lentermsg1); + *) + lRGLngStr(6,FALSE); + (* + Print(FString.lentermsg2); + *) + lRGLNGStr(7,FALSE); + DoLines; + END; + + PROCEDURE InputTheMessage(CantAbort1: Boolean; VAR DisableMCI1,SaveMsg1: Boolean); + VAR + LineStr, + TempStr1, + TempStr2, + TempStr3: AStr; + Cmd, + Drive: Char; + HelpCounter: Byte; + LineNum1, + LineNum2: Integer; + ShowCont, + ExitMsg, + SaveLine, + AbortMsg: Boolean; + + PROCEDURE AddressMessage(CantAbort2: Boolean); + VAR + User: UserRecordType; + TempMsgTo: Str36; + TempMsgSubj: Str40; + UNum: Integer; + BEGIN + { Print(FString.default + ^M^J); } + lRGLngStr(34,FALSE); + IF (Pub) AND (NOT (MAInternet IN MemMsgArea.MAFlags)) THEN + BEGIN + Prt('To: '); + IF (MsgTo <> '') THEN + InputDefault(TempMsgTo,MsgTo,36,[NoLineFeed,CapWords],FALSE) + ELSE + BEGIN + MPL(36); + InputMain(TempMsgTo,36,[NoLineFeed,CapWords]); + END; + MsgTo := TempMsgTo; + UserColor(6); + FOR UNum := 1 TO LennMCI(MsgTo) DO + BackSpace; + UNum := StrToInt(MsgTo); + IF (UNum >= 1) AND (UNum <= (MaxUsers - 1)) AND NOT (NetMail IN MHeader.Status) THEN + BEGIN + LoadURec(User,UNum); + MsgTo := Caps(User.Name); + MHeader.MTO.UserNum := UNum; + MHeader.MTO.Real := User.RealName; + IF (Pub) AND (MARealName IN MemMsgArea.MAFlags) THEN + MsgTo := Caps(User.RealName) + ELSE + MsgTo := Caps(User.Name); + END; + IF (SQOutSp(MsgTo) = '') THEN + MsgTo := 'All'; + IF (MsgTo <> '') THEN + BEGIN + Prompt(MsgTo); + UserColor(1); + NL; + END; + NL; + END + ELSE IF (NOT (MAInternet IN MemMsgArea.MAFlags)) THEN + BEGIN + Print(PadLeftStr('^4To: ^6'+Caps(MsgTo),40)); + NL; + END; + IF (MHeader.FileAttached = 0) AND (NOT CantAbort2) THEN + BEGIN + Prt('Subject: '); + IF (MsgSubj <> '') THEN + InputDefault(TempMsgSubj,MsgSubj,40,[NoLineFeed],FALSE) + ELSE + BEGIN + MPL(40); + InputMain(TempMsgSubj,40,[NoLineFeed]); + NL; + END; + IF (TempMsgSubj <> '') THEN + BEGIN + UserColor(1); + NL; + MsgSubj := TempMsgSubj; + END + ELSE + BEGIN + IF (MsgSubj <> '') THEN + Print('^6'+MsgSubj+'^1') + ELSE + Exit; + END; + END + ELSE + MsgSubj := MHeader.Subject; + END; + + PROCEDURE FileAttach; + VAR + FName: Str40; + DOk, + KAbort, + AddBatch: Boolean; + TookTime: LongInt; + BEGIN + IF PYNQ('Attach a file to this message? ',0,FALSE) THEN + BEGIN + NL; + Prt('File name: '); + MPL(40); + Input(FName,40); + NL; + IF (NOT CoSysOp) OR (NOT IsUL(FName)) THEN + FName := General.FileAttachPath+StripName(FName); + IF (NOT Exist(FName)) AND (NOT InCom) AND (NOT Exist(FName)) AND (FName <> '') THEN + Print('^7That file does not exist!^1') + ELSE + BEGIN + IF Exist(FName) AND (NOT CoSysOp) THEN + Print('^7You cannot use that file name!^1') + ELSE + BEGIN + IF NOT Exist(FName) AND (InCom) THEN + BEGIN + Receive(FName,TempDir+'\UP',FALSE,DOk,KAbort,AddBatch,TookTime); + MHeader.FileAttached := 1; + END + ELSE IF Exist(FName) THEN + BEGIN + DOk := TRUE; + MHeader.FileAttached := 2; + END; + IF (DOk) THEN + BEGIN + MsgSubj := FName; + IF (CoSysOp) AND (NOT (NetMail IN MHeader.Status)) THEN + BEGIN + IF PYNQ('Delete file upon receipt? ',0,FALSE) THEN + MHeader.FileAttached := 1 + ELSE + MHeader.FileAttached := 2 + END + ELSE + MHeader.FileAttached := 1; + END + ELSE + MHeader.FileAttached := 0; + END; + END; + END; + UserColor(1); + END; + + PROCEDURE ListMsg(LineNum1: Integer; DisplayLineNum: Boolean; VAR SaveLine: Boolean); + BEGIN + MCIAllowed := FALSE; + AllowContinue := TRUE; + DOSANSIOn := FALSE; + Abort := FALSE; + Next := FALSE; + NL; + WHILE ((LineNum1 <= (TotalLines - 1)) AND (NOT Abort) AND (NOT HangUp)) DO + BEGIN + IF (DisplayLineNum) THEN + Print('^3'+IntToStr(LineNum1)+':'); + Reading_A_Msg := TRUE; + IF (NOT DOSANSIOn) THEN + IF (Pos('>',Copy(LinePtr^[LineNum1],1,4)) > 0) THEN + UserColor(3) + ELSE + UserColor(1); + PrintACR(LinePtr^[LineNum1]); + Reading_A_Msg := FALSE; + Inc(LineNum1); + END; + IF (DisplayLineNum) THEN + BEGIN + NL; + Print(' ^7** ^3'+IntToStr(TotalLines - 1)+' '+(Plural('line',(TotalLines - 1))+' ^7**')); + END; + MCIAllowed := TRUE; + AllowContinue := FALSE; + DOSANSIOn := FALSE; + SaveLine := FALSE; + UserColor(1); + END; + + PROCEDURE UploadFile; + VAR + TempStr1: AStr; + DOk, + KAbort, + AddBatch: Boolean; + TookTime: LongInt; + BEGIN + IF PYNQ('Import a file to this message? ',0,FALSE) THEN + BEGIN + NL; + TempStr1 := ''; + IF (CoSysOp) THEN + BEGIN + Prt('Enter file to import [Enter=Upload]: '); + MPL(40); + InputL(TempStr1,40); + END; + IF (TempStr1 = '') THEN + BEGIN + TempStr1 := 'TEMPMSG.'+IntToStr(ThisNode); + IF Exist(TempStr1) THEN + Kill(TempStr1); + END; + IF (NOT Exist(TempStr1)) AND (InCom) THEN + BEGIN + Receive(TempStr1,TempDir+'UP\',FALSE,DOk,KAbort,AddBatch,TookTime); + TempStr1 := TempDir+'UP\'+TempStr1; + END; + IF ((TempStr1 <> '') AND (NOT HangUp)) THEN + BEGIN + Assign(InportFile,TempStr1); + Reset(InportFile); + IF (IOResult = 0) THEN + InportFileOpen := TRUE; + END; + END; + UserColor(1); + END; + + BEGIN + FillChar(LinePtr^,(MaxLines * 121),0); + Abort := FALSE; + Next := FALSE; + AbortMsg := FALSE; + SaveMsg1 := FALSE; + DisableMCI1 := FALSE; + TotalLines := 1; + LastLineStr := ''; + + IF (DiskKBFree(General.MsgPath) < General.MinSpaceForPost) THEN + BEGIN + NL; + Print('Not enough disk space to save a message.'); + Drive := Chr(ExtractDriveNumber(General.MsgPath) + 64); + IF (Drive = '@') THEN + SysOpLog('^8--->^3 Message save failure: Drive full.') + ELSE + SysOpLog('^8--->^3 Message save failure: '+Drive+' Drive full.'); + MsgSubj := ''; + END + ELSE + BEGIN + IF (ReadInMsg <> '') THEN + BEGIN + Assign(InportFile,ReadInMsg); + Reset(InportFile); + IF (IOResult = 0) THEN + BEGIN + WHILE (NOT EOF(InportFile)) AND ((TotalLines - 1) <= MaxLines) DO + BEGIN + ReadLn(InportFile,LinePtr^[TotalLines]); + Inc(TotalLines); + END; + Close(InportFile); + END; + END + ELSE + AddressMessage(CantAbort1); + END; + + IF (MsgSubj = '') THEN + IF (NOT CantAbort1) THEN + BEGIN + SaveMsg1 := FALSE; + Exit; + END; + + IF (FSEditor IN ThisUser.SFlags) THEN + BEGIN + REPEAT + FS_Editor; + REPEAT + NL; + Prt('Full screen editor (^5?^4=^5Help^4): '); + OneK(Cmd,^M'ACFMQSTU?',TRUE,TRUE); + NL; + CASE Cmd OF + + 'A' : IF (CantAbort1) THEN + BEGIN + Print('^7You can not abort this message!^1'); + Cmd := #0; + END + ELSE IF PYNQ('Abort message? ',0,FALSE) THEN + BEGIN + AbortMsg := TRUE; + SaveMsg1 := FALSE; + NL; + Print('Aborted!'); + END; + + 'C' : BEGIN + IF PYNQ('Are you sure? ',0,FALSE) THEN + FOR LineNum1 := 1 TO (TotalLines - 1) DO + LinePtr^[LineNum1][0] := #0; + END; + + 'F' : IF (NOT AACS(General.FileAttachACS)) THEN + BEGIN + Print('^7You do not have access to this command!^1'); + Cmd := #0; + END + ELSE + FileAttach; + + 'M' : IF (NOT AACS(MemMsgArea.MCIACS)) THEN + BEGIN + Print('^7You do not have access to this command!^1'); + Cmd := #0; + END + ELSE + DisableMCI1 := PYNQ('Disable MCI Codes for this message ['+SQOutSp(ShowYesNo(DisableMCI1))+']? ',0,FALSE); + + 'Q' : BEGIN + InvisEdit := TRUE; + DoQuote(FALSE); + InvisEdit := FALSE; + END; + + (* + 'S' : BEGIN + WHILE (((TotalLines - 1) >= 1) AND ((LinePtr^[TotalLines - 1] = '') OR + (LinePtr^[TotalLines - 1] = ^J))) DO + Dec(TotalLines); + IF ((TotalLines - 1) = 1) THEN + BEGIN + LineNum2 := 0; + FOR LineNum1 := 1 TO Length(LinePtr^[1]) DO + IF (LinePtr^[1][LineNum1] <> ' ') THEN + Inc(LineNum2); + IF (LineNum2 = 0) THEN + Dec(TotalLines); + END; + IF (CantAbort1) AND ((TotalLines - 1) < 1) THEN + Print('^7You must complete this message!^1') + ELSE IF ((TotalLines - 1) < 1) THEN + Print('^7Nothing to save!^1') + ELSE + BEGIN + SaveMsg1 := TRUE; + AbortMsg := FALSE; + ShowCont := FALSE; + END; + END; + *) + + 'A','S': IF (CantAbort1) AND ((TotalLines = 0) OR (Cmd = 'A')) THEN + BEGIN + Cmd := #0; + Print('You cannot abort this message.'); + END + ELSE IF (Cmd = 'A') THEN + BEGIN + IF (NOT PYNQ('Are you sure? ',0,FALSE)) THEN + Cmd := #0 + ELSE + BEGIN + SaveMsg1 := FALSE; + AbortMsg := TRUE; + NL; + Print('Aborted!'); + Exit; + END; + END + ELSE IF (Cmd = 'A') THEN + Cmd := #0; + + 'T' : AddressMessage(CantAbort1); + + 'U' : UploadFile; + + '?' : BEGIN + Print('^1(^3^1)Continue message'); + LCmds(16,3,'Abort message','Clear message'); + LCmds(16,3,'File attach','MCI Codes Yes/No'); + LCmds(16,3,'Quote message','Save message'); + LCmds(16,3,'Title change','Upload message'); + END; + + END; + + UNTIL (Pos(Cmd,^M'ACFMQSTU') > 0) OR (HangUp); + + UNTIL (HangUp) OR (Pos(Cmd,'AS') > 0); + + Inc(TotalLines); + + IF (TotalLines > 1) AND (NOT HangUp) THEN + SaveMsg := TRUE + + END + ELSE + BEGIN + + PrintMsgTitle; + + TotalLines := 0; + + HelpCounter := 1; + + REPEAT + + SaveLine := TRUE; + + ExitMsg := TRUE; + + InputLine(LineStr); + + REPEAT + + IF (LineStr = '/'^H) THEN + BEGIN + SaveLine := FALSE; + IF ((TotalLines - 1) >= 1) THEN + BEGIN + Dec(TotalLines); + LastLineStr := LinePtr^[TotalLines]; + IF (LastLineStr[Length(LastLineStr)] = #1) THEN + LastLineStr := Copy(LastLineStr,1,(Length(LastLineStr) - 1)); + NL; + Print('^3Backed up to line '+IntToStr(TotalLines)+':^1'); + END; + END; + + IF (LineStr = '/') AND (NOT (InportFileOpen)) THEN + BEGIN + + SaveLine := FALSE; + + ShowCont := TRUE; + + NL; + Prt('Line editor (^5?^4=^5Help^4): '); + OneK(Cmd,^M'ACDFILMOPQRSTUZ?',TRUE,TRUE); + IF (Cmd <> ^M) THEN + NL; + CASE UpCase(Cmd) OF + 'A' : IF (CantAbort1) THEN + Print('^7You can not abort this message!^1') + ELSE IF PYNQ('Abort message? ',0,FALSE) THEN + BEGIN + AbortMsg := TRUE; + SaveMsg1 := FALSE; + ShowCont := FALSE; + NL; + Print('Aborted!'); + END; + 'C' : IF (TotalLines = 0) THEN + Print('^7Nothing to clear!^1') + ELSE IF PYNQ('Clear message? ',0,FALSE) THEN + BEGIN + IF (TotalLines = MaxLines) THEN + ExitMsg := TRUE; + FOR LineNum1 := 1 TO TotalLines DO + LinePtr^[LineNum1][0] := #0; + TotalLines := 0; + Escp := FALSE; + ShowCont := FALSE; + NL; + Print('^0Message cleared ... Start over ...^1'); + NL; + END; + 'D' : IF (TotalLines = 0) THEN + Print('^7No lines to delete!^1') + ELSE + BEGIN + LineNum1 := -1; + InputIntegerWOC('Delete which line',LineNum1,1,TotalLines); + IF (LineNum1 >= 1) AND (LineNum1 <= TotalLines) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + NL; + Print('^3Line '+IntToStr(LineNum1)+':'); + MCIAllowed := FALSE; + PrintAcr('^1'+LinePtr^[LineNum1]); + MCIAllowed := TRUE; + NL; + IF (PYNQ('Delete this line? ',0,FALSE)) THEN + BEGIN + IF (TotalLines = MaxLines) THEN + ExitMsg := TRUE; + + FOR LineNum2 := LineNum1 TO (TotalLines - 2) DO + LinePtr^[LineNum2] := LinePtr^[LineNum2 + 1]; + + Dec(TotalLines); + NL; + Print('^0Line '+IntToStr(LineNum1)+' deleted.^1'); + END; + END; + END; + 'F' : IF (NOT AACS(General.FileAttachACS)) THEN + Print('^7You do not have access to this command!^1') + ELSE + FileAttach; + 'I' : IF ((TotalLines - 1) < 1) THEN + Print('^7No lines to insert before!^1') + ELSE IF ((TotalLines - 1) >= MaxLines) THEN + Print('^7You have reached the maximum line limit!^1') + ELSE + BEGIN + LineNum1 := -1; + InputIntegerWOC('Insert before which line',LineNum1,1,TotalLines); + IF (LineNum1 >= 1) AND (LineNum1 <= TotalLines) THEN + BEGIN + NL; + Print('^3Line '+IntToStr(LineNum1)+':'); + UserColor(1); + InputLine(TempStr1); + NL; + IF (PYNQ('Insert this line? ',0,FALSE)) THEN + BEGIN + FOR LineNum2 := TotalLines DOWNTO (LineNum1 + 1) DO + LinePtr^[LineNum2] := LinePtr^[LineNum2 - 1]; + LinePtr^[LineNum1] := TempStr1; + Inc(TotalLines); + IF ((TotalLines - 1) = MaxLines) THEN + ExitMsg := FALSE; + NL; + Print('^0Line '+IntToStr(LineNum1)+' inserted.^1'); + END; + END; + END; + 'L' : IF ((TotalLines - 1) < 1) THEN + Print('^7Nothing to list!^1') + ELSE + BEGIN + IF (PYNQ('List entire message? ',0,TRUE)) THEN + BEGIN + NL; + ListMsg(1,PYNQ('List message with line numbers? ',0,FALSE),SaveLine); + END + ELSE + BEGIN + LineNum1 := -1; + NL; + InputIntegerWOC('Staring line number',LineNum1,1,(TotalLines - 1)); + IF (LineNum1 >= 1) AND (LineNum1 <= (TotalLines - 1)) THEN + BEGIN + NL; + ListMsg(LineNum1,PYNQ('List message with line numbers? ',0,FALSE),SaveLine); + END; + END; + ShowCont := FALSE; + END; + 'M' : IF (NOT AACS(MemMsgArea.MCIACS)) THEN + Print('^7You do not have access to this command!^1') + ELSE + DisableMCI1 := PYNQ('Disable MCI Codes for this message ['+SQOutSp(ShowYesNo(DisableMCI1))+']? ',0,FALSE); + 'O' : PrintF('COLOR'); + 'P' : IF ((TotalLines - 1) < 1) THEN + Print('^7No lines to replace a string!^1') + ELSE + BEGIN + LineNum1 := -1; + InputIntegerWOC('Line to replace string',LineNum1,1,(TotalLines - 1)); + IF (LineNum1 >= 1) AND (LineNum1 <= (TotalLines - 1)) THEN + BEGIN + TempStr3 := LinePtr^[LineNum1]; + Abort := FALSE; + Next := FALSE; + NL; + Print('^3Old line '+IntToStr(LineNum1)+':'); + MCIAllowed := FALSE; + PrintACR('^1'+TempStr3); + MCIAllowed := TRUE; + NL; + Print('^4Enter string to replace:'); + Prt(': '); + InputL(TempStr1,LineMaxLen); + IF (TempStr1 <> '') THEN + IF (Pos(TempStr1,LinePtr^[LineNum1]) = 0) THEN + BEGIN + NL; + Print('^7String not found.^1'); + END + ELSE + BEGIN + NL; + Print('^4Enter replacement string:'); + Prt(': '); + InputL(TempStr2,LineMaxLen); + IF (TempStr2 <> '') THEN + BEGIN + IF (Pos(TempStr1,TempStr3) > 0) THEN + BEGIN + Insert(TempStr2,TempStr3,(Pos(TempStr1,TempStr3) + Length(TempStr1))); + Delete(TempStr3,Pos(TempStr1,TempStr3),Length(TempStr1)); + END; + NL; + Print('^3New line '+IntToStr(LineNum1)+':'); + MCIAllowed := FALSE; + PrintACR('^1'+TempStr3); + MCIAllowed := TRUE; + NL; + IF (PYNQ('Save this line? ',0,FALSE)) THEN + BEGIN + Insert(TempStr2,LinePtr^[LineNum1],(Pos(TempStr1,LinePtr^[LineNum1]) + Length(TempStr1))); + Delete(LinePtr^[LineNum1],Pos(TempStr1,LinePtr^[LineNum1]),Length(TempStr1)); + NL; + Print('^0Line '+IntToStr(LineNum1)+' saved.^1'); + END; + END; + END; + END; + END; + 'Q' : IF (NOT Exist('TEMPQ'+IntToStr(ThisNode))) THEN + Print('^7You are not replying to a message!^1') + ELSE IF ((TotalLines - 1) >= MaxLines) THEN + Print('^7You have reached the maximum line limit!^1') + ELSE + BEGIN + DoQuote(FALSE); + NL; + CLS; + PrintMsgTitle; + Print('^0Quoting complete ... Continue ...^1'); + NL; + IF ((TotalLines - 1) >= 1) THEN + IF ((TotalLines - 1) > 10) THEN + ListMsg(((TotalLines - 1) - 10),FALSE,SaveLine) + ELSE + ListMsg(1,FALSE,SaveLine); + ShowCont := FALSE; + END; + 'R' : IF ((TotalLines - 1) < 1) THEN + Print('^7No last line to delete!^1') + ELSE + BEGIN + LineNum1 := (TotalLines - 1); + Print('^3Line '+IntToStr(LineNum1)+':'); + MCIAllowed := FALSE; + PrintAcr('^1'+LinePtr^[(LineNum1)]); + MCIAllowed := TRUE; + NL; + IF (PYNQ('Delete the last line? ',0,FALSE)) THEN + BEGIN + IF ((TotalLines - 1) = MaxLines) THEN + ExitMsg := TRUE; + Dec(TotalLines); + NL; + Print('^0Line '+IntToStr(LineNum1)+' deleted.^1'); + END; + END; + 'S' : BEGIN + WHILE (((TotalLines - 1) >= 1) AND ((LinePtr^[TotalLines - 1] = '') OR + (LinePtr^[TotalLines - 1] = ^J))) DO + Dec(TotalLines); + IF ((TotalLines - 1) = 1) THEN + BEGIN + LineNum2 := 0; + FOR LineNum1 := 1 TO Length(LinePtr^[1]) DO + IF (LinePtr^[1][LineNum1] <> ' ') THEN + Inc(LineNum2); + IF (LineNum2 = 0) THEN + Dec(TotalLines); + END; + IF (CantAbort1) AND ((TotalLines - 1) < 1) THEN + Print('^7You must complete this message!^1') + ELSE IF ((TotalLines - 1) < 1) THEN + Print('^7Nothing to save!^1') + ELSE + BEGIN + SaveMsg1 := TRUE; + AbortMsg := FALSE; + ShowCont := FALSE; + END; + END; + 'T' : IF (CantAbort1) THEN + Print('^7Message subject can not be changed!^1') + ELSE + AddressMessage(CantAbort1); + 'U' : IF ((TotalLines - 1) >= MaxLines) THEN + Print('^7You have reached the maximum line limit!^1') + ELSE + UploadFile; + 'Z' : IF ((TotalLines - 1) < 1) THEN + Print('^7No lines to replace!') + ELSE + BEGIN + LineNum1 := -1; + InputIntegerWOC('Line number to replace',LineNum1,1,(TotalLines - 1)); + IF ((LineNum1 >= 1) AND (LineNum1 <= (TotalLines - 1))) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + NL; + Print('^3Old line '+IntToStr(LineNum1)+':'); + MCIAllowed := FALSE; + PrintACR('^1'+LinePtr^[LineNum1]); + MCIAllowed := TRUE; + Print('^3New line '+IntToStr(LineNum1)+':'); + UserColor(1); + InputLine(TempStr1); + NL; + IF PYNQ('Replace this line? ',0,FALSE) THEN + BEGIN + IF (LinePtr^[LineNum1][Length(LinePtr^[LineNum1])] = #1) AND (TempStr1[Length(TempStr1)]<>#1) THEN + LinePtr^[LineNum1] := TempStr1 + #1 + ELSE + LinePtr^[LineNum1] := TempStr1; + NL; + Print('^0Line '+IntToStr(LineNum1)+' replaced.^1'); + END; + END; + END; + ^M : BEGIN + IF (HelpCounter = 5) THEN + BEGIN + NL; + PrintF('PRHELP'); + HelpCounter := 0; + END; + Inc(HelpCounter); + END; + '?' : PrintF('PRHELP'); + END; + + IF (ShowCont) AND (ExitMsg) THEN + BEGIN + NL; + Print('^0Continue...^1'); + NL; + END; + + END; + + IF (SaveLine) THEN + BEGIN + LinePtr^[TotalLines] := LineStr; + Inc(TotalLines); + IF (LineStr <> '') THEN + HelpCounter := 1 + ELSE + BEGIN + IF (HelpCounter = 5) THEN + BEGIN + Print('^0Enter "/?" on a blank line for help.^1'); + Dec(TotalLines,5); + HelpCounter := 0; + END; + Inc(HelpCounter); + END; + + IF ((TotalLines - 1) >= MaxLines) THEN + BEGIN + NL; + Print('^7You have reached the maximum line limit!'); + IF (InportFileOpen) THEN + BEGIN + InportFileOpen := FALSE; + Close(InportFile); + END; + HelpCounter := 1; + ExitMsg := FALSE; + LineStr := '/'; + END; + + END; + + UNTIL (AbortMsg) OR (ExitMsg) OR (SaveMsg1) OR (HangUp); + + UNTIL ((AbortMsg) OR (SaveMsg1) OR (HangUp)); + + END; + + END; + + PROCEDURE SaveIt(DisableMCI1: Boolean); + VAR + LineStr: AStr; + C: Char; + LineNum1, + Counter: Integer; + AddTagLine: Boolean; + BEGIN + + IF (ReadInMsg <> '') THEN + BEGIN + + Assign(InportFile,ReadInMsg); + ReWrite(InportFile); + IF (IOResult = 0) THEN + BEGIN + FOR LineNum1 := 1 TO (TotalLines - 1) DO + WriteLn(InportFile,LinePtr^[LineNum1]); + Close(InportFile); + END; + + END + ELSE + BEGIN + + AddTagLine := FALSE; + IF (MAQuote IN MemMsgArea.MAFlags) THEN + AddTagLine := PYNQ('Add a tagline to your message? ',0,FALSE); + + MHeader.Subject := MsgSubj; + MHeader.OriginDate := ''; + MHeader.From.Anon := 0; + MHeader.MTO.Anon := 0; + MHeader.Replies := 0; + MHeader.ReplyTo := 0; + MHeader.Date := GetPackDateTime; + GetDayOfWeek(MHeader.DayOfWeek); + + IF (Pub AND (MemMsgArea.MAType IN [1,2])) OR (NOT Pub AND (NetMail IN MHeader.Status)) THEN + BEGIN + NewEchoMail := TRUE; + IF (NOT (MAScanOut IN MemMsgArea.MAFlags)) THEN + UpdateBoard; + END; + + MHeader.From.UserNum := UserNum; + UserName := AllCaps(ThisUser.Name); + IF (NOT Pub) AND (NetMail IN MHeader.Status) AND (ThisUser.Name <> AllCaps(ThisUser.RealName)) THEN + IF (General.AllowAlias) THEN + BEGIN + NL; + IF PYNQ('Send this with your real name? ',0,TRUE) THEN + UserName := AllCaps(ThisUser.RealName); + END; + MHeader.From.A1S := UserName; + MHeader.From.Real := AllCaps(ThisUser.RealName); + MHeader.From.Name := AllCaps(ThisUser.Name); + + MHeader.Status := [] + (MHeader.Status * [NetMail]); + + IF (Pub) AND (RValidate IN ThisUser.Flags) THEN + Include(MHeader.Status,Unvalidated); + + IF (AACS(MemMsgArea.MCIACS)) THEN + BEGIN + Include(MHeader.Status,AllowMCI); + IF (DisableMCI1) THEN + Exclude(MHeader.Status,AllowMCI); + END; + + IF (Pub) THEN + BEGIN + MHeader.MTO.Name := MsgTo; + MHeader.MTO.Real := MsgTo; + MHeader.MTO.A1S := MsgTo; + END; + + IF (NOT (NetMail IN MHeader.Status)) THEN + Anonymous(FALSE,MHeader); + + NL; + Prompt('^5Saving ...'); + + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + MHeader.TextSize := 0; + MHeader.Pointer := (FileSize(MsgTxtF) + 1); + Seek(MsgTxtF,FileSize(MsgTxtF)); + + IF (NetMail IN MHeader.Status) AND (Pos('@',MHeader.MTO.A1S) > 0) THEN + BEGIN + FOR Counter := 1 TO Length(MHeader.MTO.A1S) DO + IF (MHeader.MTO.A1S[Counter] IN ['A'..'Z']) THEN + Inc(MHeader.MTO.A1S[Counter],32); + LineStr := 'To: '+MsgTo; + BlockWrite(MsgTxtF,LineStr,Length(LineStr) + 1); + Inc(MHeader.TextSize,Length(LineStr) + 1); + MHeader.MTO.A1S := 'UUCP'; + END; + + IF ((Pub) AND (MAFilter IN MemMsgArea.MAFlags)) THEN + FOR LineNum1 := 1 TO (TotalLines - 1) DO + IF (Length(LinePtr^[LineNum1]) > 0) THEN + BEGIN + LinePtr^[LineNum1] := StripColor(LinePtr^[LineNum1]); + FOR Counter := 1 TO Length(LinePtr^[LineNum1]) DO + BEGIN + C := LinePtr^[LineNum1][Counter]; + IF (C IN [#0..#1,#3..#31,#127..#255]) THEN + C := '*'; + LinePtr^[LineNum1][Counter] := C; + END; + END; + + FOR LineNum1 := 1 TO (TotalLines - 1) DO + BEGIN + LineStr := LinePtr^[LineNum1]; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,(Length(LineStr) + 1)); + END; + + IF (AddTagLine) THEN + BEGIN + LineStr := ''; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,(Length(LineStr) + 1)); + LineStr := '... '+TagLine; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,(Length(LineStr) + 1)); + END; + + IF (MemMsgArea.MAType IN [1,2]) AND (MAAddTear IN MemMsgarea.MAFlags) THEN + BEGIN + LineStr := ''; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,1); + + LineStr := Decode(';hl?kf',183) + General.Version; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,(Length(LineStr) + 1)); + + LineStr := ' * Origin: '; + IF (MemMsgArea.Origin <> '') THEN + LineStr := LineStr + MemMsgArea.Origin + ELSE + LineStr := LineStr + General.Origin; + + IF (MemMsgArea.AKA > 19) THEN + MemMsgArea.AKA := 0; + + LineStr := LineStr + ' ('; + + LineStr := LineStr + IntToStr(General.AKA[MemMsgArea.AKA].Zone)+':'+ + IntToStr(General.AKA[MemMsgArea.AKA].Net)+'/'+ + IntToStr(General.AKA[MemMsgArea.AKA].Node); + + IF (General.AKA[MemMsgArea.AKA].Point > 0) THEN + LineStr := LineStr + '.'+IntToStr(General.AKA[MemMsgArea.AKA].Point); + + LineStr := LineStr + ')'; + Inc(MHeader.TextSize,(Length(LineStr) + 1)); + BlockWrite(MsgTxtF,LineStr,(Length(LineStr) + 1)); + + END; + + Close(MsgTxtF); + LastError := IOResult; + + BackErase(9); + + END; + + InputMessage := TRUE; + + END; + +BEGIN + CLS; + InputMessage := FALSE; + + MaxLines := ((MaxAvail DIV 120) - 20); + IF (MaxLines > 500) THEN + MaxLines := 500; + GetMem(LinePtr,(MaxLines * 120)); + + InportFileOpen := FALSE; + Escp := FALSE; + MaxQuoteLines := 0; + LastQuoteLine := 0; + + IF (NOT IsReply) THEN + MsgTo := '' + ELSE + BEGIN + IF (MARealName IN MemMsgArea.MAFlags) THEN + MsgTo := Caps(MHeader.MTO.Real) + ELSE + MsgTo := Caps(MHeader.MTO.A1S) + END; + + IF (InResponseTo <> '') THEN + MsgSubj := InResponseTo + ELSE + MsgSubj := MsgTitle; + + IF (Copy(MsgSubj,1,1) <> '\') THEN + CantAbort := FALSE + ELSE + BEGIN + MsgSubj := Copy(MsgSubj,2,(Length(MsgSubj) - 1)); + MHeader.Subject := MsgSubj; + CantAbort := TRUE; + END; + + IF (MsgSubj[1] = #1) THEN + BEGIN + MsgSubj := Copy(MsgSubj,2,(Length(MsgSubj) - 1)); + IF (MHeader.Subject[1] = #1) THEN + MHeader.Subject := Copy(MHeader.Subject,2,(Length(MHeader.Subject) - 1)); + END + ELSE IF (MsgSubj <> '') AND (Copy(MsgSubj,1,3) <> 'Re:') THEN + MsgSubj := 'Re: '+Copy(MsgSubj,1,36); + + MHeader.FileAttached := 0; + + InputTheMessage(CantAbort,DisableMCI,SaveMsg); + + IF (SaveMsg) THEN + SaveIt(DisableMCI); + + Kill('TEMPQ'+IntToStr(ThisNode)); + + DOSANSIOn := FALSE; + + FreeMem(LinePtr,(MaxLines * 120)); +END; + +PROCEDURE InputLine(VAR S: Astr); +VAR + CKeyPos, + RP, + Counter, + Counter1: Integer; + CKey, + ccc: Char; + HitCmdKey, + HitBkSpc, + DoThisChar: Boolean; + + PROCEDURE BkSpc; + BEGIN + IF (CKeyPos > 1) THEN + BEGIN + IF (S[CKeyPos - 2] = '^') AND (S[CKeyPos - 1] IN [#0..#9]) THEN + BEGIN + Dec(CKeyPos); + UserColor(1); + END + ELSE + BEGIN + BackSpace; + Dec(RP); + END; + Dec(CKeyPos); + END; + END; + +BEGIN + Write_Msg := TRUE; + HitCmdKey := FALSE; + HitBkSpc := FALSE; + ccc := '1'; + RP := 1; + CKeyPos := 1; + S := ''; + IF (LastLineStr <> '') THEN + BEGIN + Abort := FALSE; + Next := FALSE; + AllowAbort := FALSE; + Reading_A_Msg := TRUE; + PrintMain(LastLineStr); + Reading_A_Msg := FALSE; + AllowAbort := TRUE; + S := LastLineStr; + LastLineStr := ''; + IF (Pos(^[,S) > 0) THEN + Escp := TRUE; + CKeyPos := (Length(S) + 1); + RP := CKeyPos; + END; + REPEAT + IF ((InportFileOpen) AND (Buf = '')) THEN + IF (NOT EOF(InportFile)) THEN + BEGIN + Counter1 := 0; + REPEAT + Inc(Counter1); + Read(InportFile,Buf[Counter1]); + IF (Buf[Counter1] = ^J) THEN + Dec(Counter1); + UNTIL (Counter1 >= 255) OR (Buf[Counter1] = ^M) OR (EOF(InportFile)); + Buf[0] := Chr(Counter1); + END + ELSE + BEGIN + Close(InportFile); + InportFileOpen := FALSE; + DOSANSIOn := FALSE; + Buf := ^P+'1'; + END; + CKey := Char(GetKey); + DoThisChar := FALSE; + IF ((CKey >= #32) AND (CKey <= #255)) THEN + BEGIN + IF (CKey = '/') AND (CKeyPos = 1) THEN + HitCmdKey := TRUE + ELSE + DoThisChar := TRUE; + END + ELSE + CASE CKey OF + ^[ : DoThisChar := TRUE; + ^H : IF (CKeyPos = 1) THEN + BEGIN + HitCmdKey := TRUE; + HitBkSpc := TRUE; + END + ELSE + BkSpc; + ^I : BEGIN + Counter := (5 - (CKeyPos MOD 5)); + IF ((CKeyPos + Counter) < StrLen) AND ((RP + Counter) < ThisUser.LineLen) THEN + FOR Counter1 := 1 TO Counter DO + BEGIN + OutKey(' '); + IF (Trapping) THEN + Write(TrapFile,' '); + S[CKeyPos] := ' '; + Inc(RP); + Inc(CKeyPos); + END; + END; + ^J : BEGIN + OutKey(CKey); + S[CKeyPos] := CKey; + IF (Trapping) THEN + Write(TrapFile,^J); + Inc(CKeyPos); + END; + ^N : BEGIN + OutKey(^H); + S[CKeyPos] := ^H; + IF (Trapping) THEN + Write(TrapFile,^H); + Inc(CKeyPos); + Dec(RP); + END; + ^P : IF (OkANSI OR OkAvatar) AND (CKeyPos < (StrLen - 1)) THEN + BEGIN + CKey := Char(GetKey); + IF (CKey IN ['0'..'9']) THEN + BEGIN + ccc := CKey; + S[CKeyPos] := '^'; + Inc(CKeyPos); + S[CKeyPos] := CKey; + Inc(CKeyPos); + UserColor(Ord(CKey) - Ord('0')); + END; + CKey := #0; + END; + ^W : IF (CKeyPos = 1) THEN + BEGIN + HitCmdKey := TRUE; + HitBkSpc := TRUE; + END + ELSE + REPEAT + BkSpc + UNTIL (CKeyPos = 1) OR (S[CKeyPos] = ' ') OR ((S[CKeyPos] = ^H) AND (S[CKeyPos - 1] <> '^')); + ^X,^Y : BEGIN + CKeyPos := 1; + FOR Counter := 1 TO (RP - 1) DO + BackSpace; + RP := 1; + IF (ccc <> '1') THEN + BEGIN + CKey := ccc; + S[CKeyPos] := '^'; + Inc(CKeyPos); + S[CKeyPos] := CKey; + Inc(CKeyPos); + UserColor(Ord(CKey) - Ord('0')); + END; + CKey := #0; + END; + END; + IF (DoThisChar) AND ((CKey <> ^G) AND (CKey <> ^M)) THEN + IF ((CKeyPos < StrLen) AND (Escp)) OR ((RP < ThisUser.LineLen) AND (NOT Escp)) THEN + BEGIN + IF (CKey = ^[) THEN + Escp := TRUE; + S[CKeyPos] := CKey; + Inc(CKeyPos); + Inc(RP); + OutKey(CKey); + IF (Trapping) THEN + Write(TrapFile,CKey); + END; + UNTIL (((RP - 1) = LineMaxLen) AND (NOT Escp)) OR (CKeyPos = StrLen) OR (CKey = ^M) OR (HitCmdKey) OR (HangUp); + IF (HitCmdKey) THEN + BEGIN + IF (HitBkSpc) THEN + S := '/'^H + ELSE + S := '/'; + END + ELSE + BEGIN + S[0] := Chr(CKeyPos - 1); + IF (CKey <> ^M) AND (CKeyPos <> StrLen) AND (NOT Escp) THEN + BEGIN + Counter := (CKeyPos - 1); + WHILE (Counter > 1) AND (S[Counter] <> ' ') AND ((S[Counter] <> ^H) OR (S[Counter - 1] = '^')) DO + Dec(Counter); + IF (Counter > (RP DIV 2)) AND (Counter <> (CKeyPos - 1)) THEN + BEGIN + LastLineStr := Copy(S,(Counter + 1),(CKeyPos - Counter)); + FOR Counter1 := (CKeyPos - 2) DOWNTO Counter DO + BackSpace; + S[0] := Chr(Counter - 1); + END; + END; + IF (Escp) AND (RP = ThisUser.LineLen) THEN + CKeyPos := StrLen; + IF (CKeyPos <> StrLen) THEN + NL + ELSE + BEGIN + RP := 1; + CKeyPos := 1; + S := S + #29; + END; + END; + Write_Msg := FALSE; +END; + +END. diff --git a/SOURCE/UNUSED/MAIL1.TPU b/SOURCE/UNUSED/MAIL1.TPU new file mode 100644 index 0000000000000000000000000000000000000000..695c967b5b4f205f17e657eac3a7e473843ce2fb GIT binary patch literal 62864 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 z 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 BWpn@l literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MAIL3.TPU b/SOURCE/UNUSED/MAIL3.TPU new file mode 100644 index 0000000000000000000000000000000000000000..d913fdd5ce4cb4dc50ae9f1fe9c1a3cc2dfbb7b3 GIT binary patch literal 14672 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 E2kaNfR{#J2 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MAIL4.TPU b/SOURCE/UNUSED/MAIL4.TPU new file mode 100644 index 0000000000000000000000000000000000000000..d71f6a0c1b2d8e535586ff995b8c6faaa01d3efb GIT binary patch literal 9936 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 General.MaxPubPost) AND (NOT MsgSysOp)) THEN + Nope('Too many messages posted today.'); + IF (ok) THEN + BEGIN + InitMsgArea(MsgArea); + MHeader.FileAttached := 0; + MHeader.Status := []; + IF (ReplyTo <> -1) THEN + BEGIN + MHeader.MTo := TToI; + IF (MHeader.MTo.Anon > 0) THEN + MHeader.MTo.A1S := UseName(MHeader.MTo.Anon,MHeader.MTo.A1S); + END + ELSE + BEGIN + FillChar(MHeader.MTo,SizeOf(MHeader.MTo),0); + InResponseTo := ''; + END; + + IF (MemMsgArea.PrePostFile <> '') THEN + BEGIN + PrintF(MemMsgArea.PrePostFile); + PauseScr(FALSE); + END; + + IF (InputMessage(TRUE,(ReplyTo <> -1),TRUE,'',MHeader,'')) THEN + BEGIN + IF (ReplyTo <> -1) THEN + MHeader.ReplyTo := ((HiMsg + 1) - ReplyTo); + IF (PvtMsg) THEN + Include(MHeader.Status,Prvt); + SaveHeader((HiMsg + 1),MHeader); + IF (ReplyTo <> -1) THEN + BEGIN + LoadHeader(ReplyTo,MHeader2); + Inc(MHeader2.Replies); + SaveHeader(ReplyTo,MHeader2); + END; + SysOpLog(MHeader.Subject+' posted on ^5'+MemMsgArea.Name); + IF (MHeader.MTo.A1S <> '') THEN + SysOpLog(' To: "'+MHeader.MTo.A1S+'"'); + Print('^9Message posted on ^5'+MemMsgArea.Name+'^9.'); + NL; + Inc(ThisUser.MsgPost); + Inc(PToday); + IF NOT (FNoCredits IN ThisUser.Flags) THEN + AdjustBalance(General.CreditPost); + SaveURec(ThisUser,UserNum); + Update_Screen; + END; + END; +END; + +PROCEDURE ListMessages; +VAR + MHeader: MheaderRec; + S, + S1: STRING; + TempHiMsg: Word; + ADate: DateTime; + NumDone: Byte; +BEGIN + NumDone := 0; + TempHiMsg := HiMsg; + IF ((Msg_On < 1) OR (Msg_On > TempHiMsg)) THEN + Exit; + Abort := FALSE; + Next := FALSE; (* Added *) + Cls; + PrintACR('Ŀ'); + PrintACR(' Msg#  Sender  Receiver  '+'Subject ! Posted '); + PrintACR(''); + Dec(Msg_On); + WHILE ((NumDone < (PageLength - 7)) AND (Msg_On >= 0) AND (Msg_On < TempHiMsg) AND (NOT Next) AND (NOT Abort) AND + (NOT HangUp)) DO + BEGIN + Inc(Msg_On); + LoadHeader(Msg_On,MHeader); + IF ((NOT (UnValidated IN MHeader.Status)) AND NOT (Mdeleted IN MHeader.Status)) OR (MsgSysOp) THEN + BEGIN + IF (Mdeleted IN MHeader.Status) THEN + S := '''D ' + ELSE IF (UnValidated IN MHeader.Status) THEN + S := '''U ' + ELSE IF ToYou(MHeader) OR FromYou(MHeader) THEN + S := '''> ' + ELSE IF (TempLastRead < MHeader.Date) THEN + S := '''* ' + ELSE + S := ' '; + S := S + '"'+PadLeftInt(Msg_On,5)+' #'; + IF (MARealName IN MemMsgArea.MAFlags) THEN + S1 := UseName(MHeader.From.Anon,MHeader.From.Real) + ELSE + S1 := UseName(MHeader.From.Anon,MHeader.From.A1S); + S := S + PadLeftStr(S1,18)+' $'; + IF ((MARealName IN MemMsgArea.MAFlags) AND (MHeader.MTo.Real <> '')) THEN + S1 := UseName(MHeader.MTo.Anon,MHeader.MTo.Real) + ELSE + S1 := UseName(MHeader.MTo.Anon,MHeader.MTo.A1S); + S := S + PadLeftStr(S1,19)+' % '; + IF (MHeader.FileAttached = 0) THEN + S := S + PadLeftStr(MHeader.Subject,18) + ELSE + S := S + PadLeftStr(Stripname(MHeader.Subject),18); + PackToDate(ADate,MHeader.Date); + S := S + ' &'+ZeroPad(IntToStr(ADate.Month))+'/'+ ZeroPad(IntToStr(ADate.Day))+'/'+ZeroPad(IntToStr(ADate.Year)); + IF (AllowMCI IN MHeader.Status) THEN + PrintACR(S) + ELSE + Print(S); + Inc(NumDone); + END; + Wkey; + IF (Next) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + END; + END; + IF (Msg_On = TempHiMsg) THEN + BEGIN + Dec(Msg_On); + LoadHeader(Msg_On,MHeader); + END; +END; + +PROCEDURE MainRead(OncOnly,AskUpdate,Pub: Boolean); +VAR + User: UserRecordType; + MHeader: MHeaderRec; + LastReadRecord: ScanRec; + Cmd, + NewMenuCmd: AStr; + Cmd1: Char; + SaveMenu, + CmdToExec, + Counter: Byte; + MsgNum, + ThreadStart: Word; + Done, + CmdNotHid, + CmdExists, + AskPost, + Contlist, + DoneScan, + HadUnVal: Boolean; + + FUNCTION CantBeSeen: Boolean; + BEGIN + CantBeSeen := (NOT MsgSysOp) AND ((UnValidated IN MHeader.Status) OR (Mdeleted IN MHeader.Status) OR + ((Prvt IN MHeader.Status) AND NOT (ToYou(MHeader) OR FromYou(MHeader)))); + END; + +BEGIN + AskPost := FALSE; + Contlist := FALSE; + DoneScan := FALSE; + HadUnVal := FALSE; + AllowContinue := TRUE; + ThreadStart := 0; + TReadPrompt := 0; + Abort := FALSE; + Next := FALSE; + SaveMenu := CurMenu; + + IF (MemMsgArea.MessageReadMenu <> 0) THEN + CurMenu := MemMsgArea.MessageReadMenu + ELSE + CurMenu := General.MessageReadMenu; + + IF (NOT NewMenuToLoad) THEN + LoadMenuPW; + + AutoExecCmd('FIRSTCMD'); + + REPEAT + IF (Contlist) AND (Abort) THEN + BEGIN + Contlist := FALSE; + NL; + Print('Continuous message listing off.'); + TReadPrompt := 255; + END; + IF (Msg_On < 1) OR (Msg_On > HiMsg) THEN + BEGIN + IF (NOT Contlist) THEN + BEGIN + DoneScan := TRUE; + AskPost := TRUE; + END + ELSE + BEGIN + Contlist := FALSE; + Msg_On := HiMsg; + NL; + Print('Continuous message listing off.'); + TReadPrompt := 255; + END; + END; + IF (NOT DoneScan) AND (TReadPrompt IN [0..2,8..10,18]) THEN + BEGIN + IF (Contlist) THEN + Next := TRUE; + LoadHeader(Msg_On,MHeader); + IF (UnValidated IN MHeader.Status) THEN + HadUnVal := TRUE; + WHILE (((Msg_On < HiMsg) AND (TReadPrompt <> 2)) OR ((Msg_On > 1) AND (TReadPrompt = 2))) AND + (CantBeSeen) DO + BEGIN + IF (TReadPrompt = 2) THEN + Dec(Msg_On) + ELSE + Inc(Msg_On); + LoadHeader(Msg_On,MHeader); + END; + IF ((Msg_On = 1) OR (Msg_On = HiMsg)) AND (CantBeSeen) THEN + BEGIN + DoneScan := TRUE; + AskPost := TRUE; + END + ELSE + BEGIN + IF ((CLSMsg IN ThisUser.SFlags) AND (NOT Contlist)) THEN + Cls + ELSE + NL; + ReadMsg(Msg_On,Msg_On,HiMsg); + IF (TempLastRead < MHeader.Date) AND (MHeader.Date <= GetPackDateTime) THEN + TempLastRead := MHeader.Date; + IF (Pub) THEN + Inc(MRead); + END; + END; + IF (NOT Contlist) AND (NOT DoneScan) THEN + REPEAT + TReadPrompt := 0; + MainMenuHandle(Cmd); + NewMenuCmd := ''; + CmdToExec := 0; + Done := FALSE; + REPEAT + FCmd(Cmd,CmdToExec,CmdExists,CmdNotHid); + IF (CmdToExec <> 0) AND (MemCmd^[CmdToExec].CmdKeys <> '-^') AND + (MemCmd^[CmdToExec].CmdKeys <> '-/') AND (MemCmd^[CmdToExec].CmdKeys <> '-\') THEN + DoMenuCommand(Done, + MemCmd^[CmdToExec].CmdKeys, + MemCmd^[CmdToExec].Options, + NewMenuCmd, + MemCmd^[CmdToExec].NodeActivityDesc); + UNTIL (CmdToExec = 0) OR (Done) OR (HangUp); + Abort := FALSE; + Next := FALSE; + CASE TReadPrompt OF + 1 : ; { Read Again } + 2 : Dec(Msg_On); { Previous Message } + 3 : IF (NOT MsgSysOp) THEN + Print('You do not have the required access level for this option.') + ELSE + MoveMsg(Msg_On); + 4 : IF (NOT CoSysOp) THEN + Print('You do not have the required access level for this option.') + ELSE + ExtractMsgToFile(Msg_On); + 5 : IF (MsgSysOp) OR FromYou(MHeader) THEN + BEGIN + REPEAT + NL; + Prt('Message editing (^5?^4=^5Help^4): '); + MPL(1); + IF (MsgSysOp) THEN + Onek(Cmd1,'QVPRAFTSEOD?'^M) + ELSE + Onek(Cmd1,'QFTSEOD?'^M); + IF (NOT (Cmd1 IN ['Q',^M])) THEN + NL; + CASE Cmd1 OF + '?' : BEGIN + LCmds(15,5,'From','To'); + LCmds(15,5,'Subject','Edit text'); + LCmds(15,5,'Oops','Display header'); + IF (MsgSysOp) THEN + BEGIN + LCmds(15,5,'Permanent','Validation'); + LCmds(15,5,'Rescan','Anonymous'); + END; + LCmds(15,5,'Quit',''); + END; + 'D' : FOR Counter := 1 TO 6 DO + IF (HeaderLine(MHeader,Msg_On,HiMsg,Counter) <> '') THEN + PrintACR(Headerline(MHeader,Msg_On,HiMsg,Counter)); + 'O' : IF PYNQ('Reload old information? ',0) THEN + LoadHeader(Msg_On,MHeader); + 'E' : BEGIN + EditMessageText(Msg_On); + LoadHeader(Msg_On,MHeader); + END; + 'S' : IF (MHeader.FileAttached = 0) OR (MsgSysOp) THEN + BEGIN + Prt('Subj: '); + InputDefault(MHeader.Subject,MHeader.Subject,40,[ColorsAllowed],FALSE) + END + ELSE + Print('Sorry, you can''t edit that.'); + 'T' : BEGIN + Print('^11. Posted to : ^5'+MHeader.MTo.A1S); + Print('^12. Real name : ^5'+MHeader.MTo.Real); + Print('^13. System name: ^5'+MHeader.MTo.Name); + NL; + Prt('Edit name (^51^4-^53^4) [^5Q^4]uit: '); + Onek(Cmd1,'Q123'^M); + IF (NOT (Cmd1 IN ['Q',^M])) THEN + NL; + CASE Cmd1 OF + '1' : BEGIN + Prt('Posted to: '); + InputDefault(MHeader.MTo.A1S,MHeader.MTo.A1S,36,[],FALSE); + END; + '2' : BEGIN + Prt('Real name: '); + InputDefault(MHeader.MTo.Real,MHeader.MTo.Real,36,[],FALSE); + END; + '3' : BEGIN + Prt('System name: '); + InputDefault(MHeader.MTo.Name,MHeader.MTo.Name,36,[],FALSE); + END; + END; + Cmd1 := #0; + END; + 'F' : IF (MHeader.From.Anon > 0) OR (MsgSysOp) THEN + BEGIN + Print('^11. Posted to : ^5'+MHeader.From.A1S); + Print('^12. Real name : ^5'+MHeader.From.Real); + Print('^13. System name: ^5'+MHeader.From.Name); + NL; + Prt('Edit name (^51^4-^53^4) [^5Q^4]uit: '); + Onek(Cmd1,'Q123'^M); + IF (NOT (Cmd1 IN ['Q',^M])) THEN + NL; + CASE Cmd1 OF + '1' : BEGIN + Prt('Posted to: '); + InputDefault(MHeader.From.A1S,MHeader.From.A1S,36,[],FALSE); + END; + '2' : BEGIN + Prt('Real name: '); + InputDefault(MHeader.From.Real,MHeader.From.Real,36,[],FALSE); + END; + '3' : BEGIN + Prt('System name: '); + InputDefault(MHeader.From.Name,MHeader.From.Name,36,[],FALSE); + END; + END; + Cmd1 := #0; + END + ELSE + Print('Sorry, you can''t edit that.'); + 'A' : IF (MsgSysOp) THEN + BEGIN + IF (MHeader.From.Anon IN [1,2]) THEN + MHeader.From.Anon := 0 + ELSE + BEGIN + Loadurec(User,MHeader.From.UserNum); + IF AACS1(User,MHeader.From.UserNum,General.CSOP) THEN + MHeader.From.Anon := 2 + ELSE + MHeader.From.Anon := 1; + END; + Print('Message is '+AOnOff((MHeader.From.Anon = 0),'not ','')+'anonymous'); + SysOpLog('Message is '+AOnOff((MHeader.From.Anon = 0),'not ','')+'anonymous'); + END; + 'R' : IF (MsgSysOp) THEN + BEGIN + IF (Sent IN MHeader.Status) THEN + BEGIN + Exclude(MHeader.Status,Sent); + IF NOT (MAScanOut IN MemMsgArea.MAFlags) THEN + UpdateBoard; + END + ELSE + Include(MHeader.Status,Sent); + Print('Message '+AOnOff((Sent IN MHeader.Status),'','not ')+'marked as scanned.'); + SysOpLog('Message '+AOnOff((Sent IN MHeader.Status),'','not ')+'marked as scanned.'); + END; + 'P' : IF (MsgSysOp) THEN + BEGIN + IF (Permanent IN MHeader.Status) THEN + Exclude(MHeader.Status,Permanent) + ELSE + Include(MHeader.Status,Permanent); + Print('Message is '+AOnOff((Permanent IN MHeader.Status),'','not ')+'permanent.'); + SysOpLog('Message is '+AOnOff((Permanent IN MHeader.Status),'','not ')+'permanent.'); + END; + 'V' : IF (MsgSysOp) THEN + BEGIN + IF (UnValidated IN MHeader.Status) THEN + Exclude(MHeader.Status,UnValidated) + ELSE + Include(MHeader.Status,UnValidated); + Print('Message '+AOnOff((UnValidated IN MHeader.Status),'un','')+'validated.'); + SysOpLog('Message '+AOnOff((UnValidated IN MHeader.Status),'un','')+'validated.'); + END; + END; + UNTIL (Cmd1 IN ['Q',^M]) OR (HangUp); + Cmd1 := #0; + SaveHeader(Msg_On,MHeader); + END; + 6 : BEGIN + DumpQuote(MHeader); + IF (NOT Pub) THEN + AutoReply(MHeader) + ELSE + BEGIN + NL; + IF (Prvt IN MHeader.Status) THEN + Dyny := TRUE; + IF (MHeader.From.Anon = 0) OR (AACS(General.Anonpubread)) THEN + IF PYNQ('Is this to be a private reply? ',0) THEN + IF (MAPrivate IN MemMsgArea.MAFlags) THEN + IF PYNQ('Reply in Email? ',0) THEN + AutoReply(MHeader) + ELSE + Post(Msg_On,MHeader.From,TRUE) + ELSE + AutoReply(MHeader) + ELSE + Post(Msg_On,MHeader.From,FALSE) + ELSE + Post(Msg_On,MHeader.From,FALSE); + END; + END; + 7 : BEGIN + Msg_On := (HiMsg + 1); + LoadHeader(HiMsg,MHeader); + IF (MHeader.Date <= GetPackDateTime) THEN + TempLastRead := MHeader.Date; + Next := FALSE; + END; + 8 : IF ((Msg_On - MHeader.ReplyTo) > 0) AND (MHeader.ReplyTo > 0) THEN + BEGIN + IF (ThreadStart = 0) THEN + ThreadStart := Msg_On; + Dec(Msg_On,MHeader.ReplyTo); + END; + 9 : IF ((ThreadStart >= 1) AND (ThreadStart <= HiMsg)) THEN + BEGIN + Msg_On := ThreadStart; + ThreadStart := 0; + END; + 10 : BEGIN + Contlist := TRUE; + Abort := FALSE; + NL; + Print('Continuous message listing on.'); + END; + 11 : IF (Pub) THEN + BEGIN + IF (Permanent IN MHeader.Status) THEN + BEGIN + NL; + Print('This is a permanent public message.'); + END + ELSE + BEGIN + IF (Msg_On >= 1) AND (Msg_On <= HiMsg) AND (MsgSysOp OR FromYou(MHeader)) THEN + BEGIN + LoadHeader(Msg_On,MHeader); + IF (Mdeleted IN MHeader.Status) THEN + Exclude(MHeader.Status,Mdeleted) + ELSE + Include(MHeader.Status,Mdeleted); + SaveHeader(Msg_On,MHeader); + IF NOT (Mdeleted IN MHeader.Status) THEN + BEGIN + IF FromYou(MHeader) THEN + BEGIN + IF (ThisUser.MsgPost < 2147483647) THEN + Inc(ThisUser.MsgPost); + AdjustBalance(General.Creditpost); + END; + NL; + Print('Public message undeleted.'); + SysOpLog('* Undeleted public message '+MHeader.Subject); + END + ELSE + BEGIN + IF FromYou(MHeader) THEN + BEGIN + IF (ThisUser.MsgPost > 0) THEN + Dec(ThisUser.MsgPost); + AdjustBalance(-General.Creditpost); + END; + NL; + Print('Public message deleted.'); + SysOpLog('* Deleted public message '+MHeader.Subject); + END; + END + ELSE + BEGIN + NL; + Print('You can only delete public messages from you.'); + END; + END; + END + ELSE + BEGIN + IF (Msg_On >= 1) AND (Msg_On <= HiMsg) AND (MsgSysOp OR FromYou(MHeader) OR ToYou(MHeader)) THEN + BEGIN + LoadHeader(Msg_On,MHeader); + IF (Mdeleted IN MHeader.Status) THEN + Exclude(MHeader.Status,Mdeleted) + ELSE + Include(MHeader.Status,Mdeleted); + SaveHeader(Msg_On,MHeader); + IF NOT (MDeleted IN MHeader.Status) THEN + BEGIN + LoadURec(User,MHeader.MTO.UserNum); + IF (User.Waiting < 255) THEN + Inc(User.Waiting); + SaveURec(User,MHeader.MTO.UserNum); + NL; + Print('Private message undeleted.'); + IF FromYou(MHeader) OR (MsgSysOp) THEN + SysOpLog('* Uneleted private message from '+MHeader.From.A1S) + ELSE IF ToYou(MHeader) OR (MsgSysOp) THEN + SysOpLog('* Undeleted private message to '+MHeader.MTo.A1S); + END + ELSE + BEGIN + LoadURec(User,MHeader.MTO.UserNum); + IF (User.Waiting > 0) THEN + Dec(User.Waiting); + SaveURec(User,MHeader.MTO.UserNum); + NL; + Print('Private message deleted.'); + IF FromYou(MHeader) OR (MsgSysOp) THEN + SysOpLog('* Deleted private message from '+MHeader.From.A1S) + ELSE IF ToYou(MHeader) OR (MsgSysOp) THEN + SysOpLog('* Deleted private message to '+MHeader.MTo.A1S); + END; + END + ELSE + BEGIN + NL; + Print('You can only delete private messages from/to you.'); + END; + END; + 12 : IF (NOT Pub) THEN + BEGIN + NL; + Print('This option is not available when reading private messages.'); + END + ELSE + BEGIN + NL; + Print('Highest-read pointer for this area set to message #'+IntToStr(Msg_On)+'.'); + IF (MHeader.Date <= GetPackDateTime) THEN + TempLastRead := MHeader.Date; + END; + 13 : BEGIN + IF (AskUpdate) THEN + BEGIN + NL; + IF PYNQ('Update message read pointers for this area? ',0) THEN + SaveLastRead(GetPackDateTime); + END; + DoneScan := TRUE; + Next := TRUE; + END; + 14 : BEGIN + DoneScan := TRUE; + Abort := TRUE; + END; + 15 : ListMessages; + 16 : IF (NOT CoSysOp) THEN + Print('You do not have the required access level for this option.') + ELSE IF (LastAuthor < 1) OR (LastAuthor > (MaxUsers - 1)) THEN + Print('The sender of this message does not have an account on this BBS.') + ELSE IF (CheckPW) THEN + UserEditor(LastAuthor); + 17 : IF (NOT PUB) THEN + BEGIN + NL; + Print('This option is not available when reading private messages.'); + END + ELSE + BEGIN + IF (MAForceRead IN MemMsgArea.MAFlags) THEN + BEGIN + NL; + Print('^5'+MemMsgArea.Name+'^3 cannot be removed from your NewScan.') + END + ELSE + BEGIN + NL; + Print('^5'+MemMsgArea.Name+'^3 '+AOnOff(NewScanMsgArea,'will NOT','WILL')+ + ' be scanned in future new scans.'); + SysOpLog('* Toggled ^5'+MemMsgArea.Name+ '^1 '+AOnOff(NewScanMsgArea,'out of','back in')+ ' new scan.'); + Reset(MsgAreaScanFile); + Seek(MsgAreaScanFile,(UserNum - 1)); + Read(MsgAreaScanFile,LastReadRecord); + LastReadRecord.NewScan := NOT LastReadRecord.NewScan; + NewScanMsgArea := LastReadRecord.NewScan; + Seek(MsgAreaScanFile,(UserNum - 1)); + Write(MsgAreaScanFile,LastReadRecord); + Close(MsgAreaScanFile); + END; + END; + 18 : Inc(Msg_On); + 19 : IF (NOT CoSysOp) THEN + Print('You do not have the required access level for this option.') + ELSE IF (LastAuthor < 1) OR (LastAuthor > (MaxUsers - 1)) THEN + Print('The sender of this message does not have an account on this BBS.') + ELSE + BEGIN + LoadURec(User,LastAuthor); + ShowUserInfo(1,LastAuthor,User); + END; + 20 : IF (NOT CoSysOp) THEN + Print('You do not have the required access level for this option.') + ELSE IF (LastAuthor < 1) OR (LastAuthor > (MaxUsers - 1)) THEN + Print('The sender of this message does not have an account on this BBS.') + ELSE + BEGIN + LoadURec(User,LastAuthor); + AutoVal(User,LastAuthor); + END; + 21 : ForwardMessage(Msg_On); + END; + UNTIL (TReadPrompt IN [1..2,7..10,13..15,18]) OR (Abort) OR (Next) OR (HangUp) + ELSE + Inc(Msg_On); + IF (OncOnly) AND (TReadPrompt IN [13,14,18]) THEN + DoneScan := TRUE; + UNTIL (DoneScan) OR (HangUp); + + CurMenu := SaveMenu; + + NewMenuToLoad := TRUE; + + AllowContinue := FALSE; + + IF ((Pub) AND (HadUnVal) AND (MsgSysOp)) THEN + BEGIN + NL; + IF PYNQ('Validate messages here? ',0) THEN + BEGIN + FOR MsgNum := 1 TO HiMsg DO + BEGIN + LoadHeader(MsgNum,MHeader); + IF (UnValidated IN MHeader.Status) THEN + Exclude(MHeader.Status,UnValidated); + SaveHeader(MsgNum,MHeader); + END; + END; + END; + + IF ((Pub) AND (AskPost) AND (AACS(MemMsgArea.PostACS)) AND + (NOT (RPost IN ThisUser.Flags)) AND (PToday < General.MaxPubPost)) THEN + BEGIN + NL; + IF (TReadPrompt <> 7) THEN + IF PYNQ('Post on ^5'+MemMsgArea.Name+'^7? ',0) THEN + IF (MAPrivate IN MemMsgArea.MAFlags) THEN + BEGIN + NL; + Post(-1,MHeader.From,PYNQ('Is this to be a private message? ',0)); + END + ELSE + Post(-1,MHeader.From,FALSE); + END; +END; + +PROCEDURE ReadMessages(MenuOption: Str50); +VAR + InputStr: AStr; + SaveReadMsgArea: Integer; +BEGIN + SaveReadMsgArea := ReadMsgArea; + Abort := FALSE; + Next := FALSE; + IF (MenuOption = '') THEN + MsgArea := -1; + InitMsgArea(MsgArea); + IF (HiMsg = 0) THEN + BEGIN + NL; + Print('No messages on ^5'+MemMsgArea.Name+'^1.'); + IF (Novice IN ThisUser.Flags) THEN + PauseScr(FALSE); + END + ELSE + BEGIN + Msg_On := 1; + REPEAT + ListMessages; + NL; + { Prompt(FString.ReadQ); } + lRGLngStr(32,FALSE); + ScanInput(InputStr,'Q'^M); + IF (InputStr = ^M) THEN + IF ((Msg_On + 1) = HiMsg) THEN + Msg_On := 1 + ELSE + Inc(Msg_On); + UNTIL (InputStr <> ^M) OR (HangUp); + IF (InputStr <> 'Q') AND (NOT HangUp) THEN + BEGIN + IF (StrToInt(InputStr) < 1) OR (StrToInt(InputStr) > HiMsg) THEN + Msg_On := 1 + ELSE + Msg_On := StrToInt(InputStr); + IF (MsgArea <> -1) THEN + TempLastRead := LastMsgRead; + MainRead(FALSE,FALSE,(MsgArea <> -1)); + IF (MsgArea <> - 1) THEN + SaveLastRead(TempLastRead); + END; + END; + MsgArea := SaveReadMsgArea; + LoadMsgArea(MsgArea); +END; + +FUNCTION FirstNew: Word; +VAR + MHeader: MHeaderRec; + MaxMsgs, + Cn: Word; + Done: Boolean; +BEGIN + MaxMsgs := HiMsg; + Cn := 0; + IF (MaxMsgs > 0) THEN + BEGIN + Done := FALSE; + Cn := 1; + WHILE (CN <= MaxMsgs) AND (NOT Done) DO + BEGIN + LoadHeader(Cn,MHeader); + IF (LastMsgRead < MHeader.Date) THEN + Done := TRUE + ELSE + BEGIN + IF (CN < MaxMsgs) THEN + Inc(Cn,1) + ELSE + BEGIN + CN := 0; + Done := TRUE; + END; + END; + END; + END; + FirstNew := Cn; +END; + +PROCEDURE ScanMessages(MArea: Integer; AskUpdate: Boolean; MenuOption: Str50); +VAR + ScanFor: STRING[40]; + Cmd: Char; + SaveMsgArea, + MsgNum: Word; + ScanNew, + ScanGlobal: Boolean; + + PROCEDURE Searchboard(MArea1: Integer; Cmd1: Char); + VAR + MsgHeader: MHeaderRec; + Searched: STRING; + TotLoad: Word; + Match, + AnyShown: Boolean; + BEGIN + IF (MsgArea <> MArea1) THEN + ChangeMsgArea(MArea1); + IF (MsgArea = MArea1) THEN + BEGIN + InitMsgArea(MsgArea); + AnyShown := FALSE; + LIL := 0; + CLS; + Prompt('^1Scanning ^5'+MemMsgArea.Name+' #'+IntToStr(CompMsgArea(MsgArea))+'^1...'); + Reset(MsgHdrF); + Reset(MsgTxtF,1); + IF (IOResult <> 0) THEN + Exit; + IF (ScanNew) THEN + MsgNum := FirstNew + ELSE + MsgNum := 1; + IF (MsgNum > 0) AND (FileSize(MsgHdrF) > 0) THEN + WHILE (MsgNum <= FileSize(MsgHdrF)) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + LoadHeader(MsgNum,MsgHeader); + Match := FALSE; + IF (Cmd1 IN ['Y',^M] ) THEN + IF ToYou(MsgHeader) THEN + Match := TRUE; + IF (Cmd1 IN ['F','A'] ) THEN + BEGIN + IF (MARealName IN MemMsgArea.MAFlags) THEN + Searched := MsgHeader.From.Real + ELSE + Searched := MsgHeader.From.A1S; + IF (MemMsgArea.MAtype = 0) THEN + Searched := Searched; + Searched := AllCaps(UseName(MsgHeader.From.Anon,Searched)); + IF (Pos(ScanFor,Searched) > 0) THEN + Match := TRUE; + END; + IF (Cmd1 IN ['T','A'] ) THEN + BEGIN + IF (MARealName IN MemMsgArea.MAFlags) THEN + Searched := MsgHeader.MTo.Real + ELSE + Searched := MsgHeader.MTo.A1S; + IF (MemMsgArea.MAtype = 0) THEN + Searched := Searched; + Searched := AllCaps(UseName(MsgHeader.MTo.Anon,Searched)); + IF (Pos(ScanFor,Searched) > 0) THEN + Match := TRUE; + END; + IF (Cmd1 IN ['S','A'] ) THEN + IF (Pos(ScanFor,AllCaps(MsgHeader.Subject)) > 0) THEN + Match := TRUE; + IF (Cmd1 = 'A') AND (NOT Match) AND (MsgHeader.TextSize > 0) AND + (((MsgHeader.Pointer - 1) + MsgHeader.TextSize) <= FileSize(MsgTxtF)) AND + (MsgHeader.Pointer > 0) THEN + WITH MsgHeader DO + BEGIN + Seek(MsgTxtF,(Pointer - 1)); + TotLoad := 0; + REPEAT + BlockRead(MsgTxtF,Searched[0],1); + BlockRead(MsgTxtF,Searched[1],Ord(Searched[0])); + LastError := IOResult; + Inc(TotLoad,Length(Searched) + 1); + IF (Pos(ScanFor,AllCaps(Searched)) > 0) THEN + Match := TRUE; + UNTIL (TotLoad >= TextSize) OR (Match); + END; + IF (Match) THEN + BEGIN + Close(MsgHdrF); + Close(MsgTxtF); + Msg_On := MsgNum; + MainRead(TRUE,AskUpdate,(MsgArea <> -1)); + NL; + Reset(MsgHdrF); + Reset(MsgTxtF,1); + AnyShown := TRUE; + END; + Wkey; + IF (Next) THEN + Abort := TRUE; + Inc(MsgNum); + END; + Close(MsgHdrF); + Close(MsgTxtF); + IF (NOT AnyShown) THEN + BackErase(14 + Lennmci(MemMsgArea.Name) + Length(IntToStr(CompMsgArea(MsgArea) ) ) ); + END; + END; + +BEGIN + SaveMsgArea := MsgArea; + ScanNew := FALSE; + ScanGlobal := FALSE; + MenuOption := AllCaps(MenuOption); + IF (MenuOption <> '') THEN + Cmd := 'Y' + ELSE + Cmd := #0; + IF (Pos('N',MenuOption) > 0) THEN + ScanNew := TRUE; + IF (Pos('G',MenuOption) > 0) THEN + ScanGlobal := TRUE; + IF (Cmd = #0) THEN + REPEAT + NL; + Prt('Scan method (^5?^4=^5Help^4): '); + Onek(Cmd,'FTSAY?Q'^M); + IF (Cmd = '?') THEN + BEGIN + NL; + LCmds(15,5,'From field','To field'); + LCmds(15,5,'Subject field','All text'); + LCmds(15,5,'Your messages','Quit'); + END; + UNTIL (Cmd <> '?') OR (HangUp); + NL; + IF (Cmd <> 'Q') AND (Cmd <> ^M) THEN + BEGIN + IF (Cmd <> 'Y') THEN + BEGIN + Prt('Text to scan for: '); + Input(ScanFor,40); + IF (ScanFor = '') THEN + Exit; + NL; + END; + IF (MenuOption = '') THEN + BEGIN + Dyny := TRUE; + ScanNew := PYNQ('Scan new messages only? ',0); + END; + IF (ScanGlobal) OR ((MenuOption = '') AND PYNQ('Global scan? ',0)) THEN + BEGIN + MArea := 1; + WHILE (MArea <= NumMsgAreas) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (CompMsgArea(MArea) > 0) THEN + Searchboard(MArea,Cmd); + Wkey; + IF (Next) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + END; + Inc(MArea); + END; + END + ELSE + Searchboard(MArea,Cmd); + END; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); +END; + +PROCEDURE ScanYours; +VAR + FoundMap: ARRAY [0..255] OF SET OF 0..7; + MsgHeader: MHeaderRec; + SaveMsgArea, + MArea: Integer; + MsgNum, + Found: Word; + SaveConfSystem, + AnyFound, + FirstTime: Boolean; +BEGIN + FillChar(FoundMap,SizeOf(FoundMap),0); + SaveMsgArea := MsgArea; + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + NL; + Prompt('^5Scanning for your new public messages ... '); + FirstTime := TRUE; + AnyFound := FALSE; + MArea := 1; + WHILE (MArea <= NumMsgAreas) AND (NOT HangUp) DO + BEGIN + IF (CompMsgArea(MArea) > 0) THEN + BEGIN + IF (MsgArea <> MArea) THEN + ChangeMsgArea(MArea); + IF (MsgArea = MArea) THEN + BEGIN + InitMsgArea(MsgArea); + IF (NewScanMsgArea) THEN + BEGIN + Reset(MsgHdrF); + Reset(MsgTxtF,1); + IF (IOResult = 0) THEN + BEGIN + Found := 0; + MsgNum := FirstNew; + IF (MsgNum > 0) AND (FileSize(MsgHdrF) > 0) THEN + WHILE (MsgNum <= FileSize(MsgHdrF)) AND (NOT HangUp) DO + BEGIN + LoadHeader(MsgNum,MsgHeader); + IF (ToYou(MsgHeader)) THEN + BEGIN + FoundMap[MArea DIV 8] := FoundMap[MArea DIV 8] + [MArea MOD 8]; + Inc(Found); + END; + Inc(MsgNum); + END; + Close(MsgHdrF); + Close(MsgTxtF); + IF (Found > 0) THEN + BEGIN + IF (FirstTime) THEN + BEGIN + NL; + NL; + FirstTime := FALSE; + END; + Print(PadLeftStr(MemMsgArea.Name,30)+' ^1'+IntToStr(Found)); + AnyFound := TRUE; + END; + END; + END; + END; + END; + Inc(MArea); + END; + IF (NOT AnyFound) THEN + Print('^5No messages found.') + ELSE + BEGIN + Abort := FALSE; + Next := FALSE; + NL; + IF PYNQ('Read these now? ',0) THEN + BEGIN + MArea := 1; + WHILE (MArea <= NumMsgAreas) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (MArea MOD 8) IN FoundMap[MArea DIV 8] THEN + ScanMessages(MArea,TRUE,'N'); + WKey; + IF (Next) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + END; + Inc(MArea); + END; + END; + END; + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); + LastError := IOResult; +END; + +PROCEDURE StartNewScan(MenuOption: Str50); +VAR + MArea, + SaveMsgArea: Integer; + Global: Boolean; + + PROCEDURE NewScan(MArea1: Integer); + BEGIN + IF (MsgArea <> MArea1) THEN + ChangeMsgArea(MArea1); + IF (MsgArea = MArea1) THEN + BEGIN + InitMsgArea(MsgArea); + TempLastRead := LastMsgRead; + Lil := 0; + { Prompt('^3'+FString.NewScan1);} + lRGLngStr(8,FALSE); + Msg_On := FirstNew; + IF (Msg_On > 0) THEN + MainRead(FALSE,FALSE,(MsgArea <> -1)); + (* Add backarase *) + END; + SaveLastRead(TempLastRead); + END; + +BEGIN + SaveMsgArea := MsgArea; + MArea := MsgArea; + Abort := FALSE; + Next := FALSE; + Global := FALSE; + IF (UpCase(MenuOption[1]) = 'C') THEN + MArea := MsgArea + ELSE IF (UpCase(MenuOption[1]) = 'G') THEN + Global := TRUE + ELSE IF (StrToInt(MenuOption) <> 0) THEN + MArea := StrToInt(MenuOption) + ELSE IF (MenuOption = '') THEN + BEGIN + NL; + Global := PYNQ('Scan all message areas? ',0) + END; + IF (NOT Global) THEN + NewScan(MArea) + ELSE + BEGIN + MArea := 1; + WHILE (MArea <= NumMsgAreas) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (CompMsgArea(MArea) > 0) THEN + BEGIN + InitMsgArea(MArea); + IF (NewScanMsgArea) OR ((MAForceRead IN MemMsgArea.MAFlags) AND (NOT CoSysOp)) THEN + NewScan(MArea); + END; + WKey; + IF (Next) THEN + BEGIN + Abort := FALSE; + Next := FALSE; + END; + Inc(MArea); + END; + SysOpLog('Global new scan of message areas'); + END; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); +END; + +END. diff --git a/SOURCE/UNUSED/MAIL5.TPU b/SOURCE/UNUSED/MAIL5.TPU new file mode 100644 index 0000000000000000000000000000000000000000..9558f07e86f5a4c0e08a3b64bf68283cf418df8d GIT binary patch literal 35536 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

6=j2XwqD#{snzcA~ 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MAIL6.PAS b/SOURCE/UNUSED/MAIL6.PAS new file mode 100644 index 0000000..705b2b8 --- /dev/null +++ b/SOURCE/UNUSED/MAIL6.PAS @@ -0,0 +1,583 @@ +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Mail6; + +INTERFACE + +PROCEDURE EditMessageText(MsgNum: Word); +PROCEDURE ForwardMessage(MsgNum: Word); +PROCEDURE MoveMsg(MsgNum: Word); +PROCEDURE ToggleMsgAreaScanFlags; + +IMPLEMENTATION + +USES + Dos, + Common, + Mail0, + Mail1, + Mail7, + MsgPack, + MiscUser; + +PROCEDURE EditMessageText(MsgNum: Word); +VAR + TempQuoteFile: Text; + MHeader: MHeaderRec; + TempStr: STRING; + SaveFileAttached: Byte; + TotLoad: Word; + FileDateTime1, + FileDateTime2: LongInt; +BEGIN + SysOpLog('Edited message #'+IntToStr(MsgNum)+' on '+MemMsgArea.Name); + Assign(TempQuoteFile,'TEMPQ'+IntToStr(ThisNode)+'.MSG'); + ReWrite(TempQuoteFile); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error creating TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + SysOpLog('Error creating TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + Exit; + END; + LoadHeader(MsgNum,MHeader); + Reset(MsgTxtF,1); + Seek(MsgTxtF,(MHeader.Pointer - 1)); + TotLoad := 0; + REPEAT + BlockRead(MsgTxtF,TempStr[0],1); + BlockRead(MsgTxtF,TempStr[1],Ord(TempStr[0])); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error reading from '+MemMsgArea.FileName+'.DAT file.'); + SysOpLog('Error reading from '+MemMsgArea.FileName+'.DAT file.'); + TotLoad := MHeader.TextSize; + END; + Inc(TotLoad,(Length(TempStr) + 1)); + WriteLn(TempQuoteFile,TempStr); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error writting to TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + SysOpLog('Error writting to TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + TotLoad := MHeader.TextSize; + END; + UNTIL (TotLoad >= MHeader.TextSize); + Close(MsgTxtF); + Close(TempQuoteFile); + FileDateTime1 := GetFileDateTime('TEMPQ'+IntToStr(ThisNode)+'.MSG'); + SaveFileAttached := MHeader.FileAttached; + IF NOT (InputMessage((ReadMsgArea <> -1),FALSE,TRUE,'',MHeader,'TEMPQ'+IntToStr(ThisNode)+'.MSG')) THEN + BEGIN + Kill('TEMPQ'+IntToStr(ThisNode)+'.MSG'); + Exit; + END; + MHeader.FileAttached := SaveFileAttached; + FileDateTime2 := GetFileDateTime('TEMPQ'+IntToStr(ThisNode)+'.MSG'); + IF (FileDateTime1 <> FileDateTime2) THEN + BEGIN + Assign(TempQuoteFile,'TEMPQ'+IntToStr(ThisNode)+'.MSG'); + Reset(TempQuoteFile); + MHeader.TextSize := 0; + Reset(MsgTxtF,1); + MHeader.Pointer := (FileSize(MsgTxtF) + 1); + Seek(MsgTxtF,(MHeader.Pointer - 1)); + REPEAT + ReadLn(TempQuoteFile,TempStr); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error reading from TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + SysOpLog('Error reading from TEMPQ'+IntToStr(ThisNode)+'.MSG file.'); + END; + Inc(MHeader.TextSize,(Length(TempStr) + 1)); + BlockWrite(MsgTxtF,TempStr,(Length(TempStr) + 1)); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + NL; + Print('Error writting to '+MemMsgArea.FileName+'.DAT file.'); + SysOpLog('Error writting to '+MemMsgArea.FileName+'.DAT file.'); + END; + UNTIL (EOF(TempQuoteFile)); + Close(MsgTxtF); + Close(TempQuoteFile); + SaveHeader(MsgNum,MHeader); + LastError := IOResult; + END; + Kill('TEMPQ'+IntToStr(ThisNode)+'.MSG'); +END; + +PROCEDURE ForwardMessage(MsgNum: Word); +VAR + MsgHdrF1: FILE OF MHeaderRec; + MsgTxtF1: FILE; + User: UserRecordType; + MHeader: MHeaderRec; + TempStr: STRING; + SaveReadMsgArea, + Unum: Integer; + TempTextSize, + TotLoad: Word; + TempPtr, + TempPtr1: LongInt; + SaveConfSystem: Boolean; +BEGIN + SaveReadMsgArea := ReadMsgArea; + + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + + NL; + Print('Forward message to which user (1-'+(IntToStr(MaxUsers - 1))+')?'); + NL; + Print('Enter User Number, Name, or Partial Search String.'); + Prt(': '); + lFindUserWS(UNum); + IF (UNum > 0) THEN + BEGIN + IF (UNum = UserNum) THEN + BEGIN + NL; + Print('You can not forward messages to yourself.'); + END + ELSE + BEGIN + LoadURec(User,UNum); + IF ((User.Waiting < General.MaxWaiting) AND NOT (NoMail IN User.Flags)) OR (CoSysOp) THEN + BEGIN + InitMsgArea(SaveReadMsgArea); + + LoadHeader(MsgNum,MHeader); + + Mheader.MTO.UserNum := UNum; + MHeader.MTO.A1S := User.Name; + MHeader.MTO.Name := User.Name; + MHeader.MTO.Real := User.RealName; + + TempPtr := (MHeader.Pointer - 1); + + Reset(MsgTxtF,1); + + MHeader.Pointer := (FileSize(MsgTxtF) + 1); + + Seek(MsgTxtF,FileSize(MsgTxtF)); + + IF (SaveReadMsgArea <> -1) THEN + BEGIN + + LoadMsgArea(-1); + + Assign(MsgHdrF1,General.MsgPath+MemMsgArea.FIleName+'.HDR'); + Reset(MsgHdrF1); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF1); + + Assign(MsgTxtF1,General.MsgPath+MemMsgArea.FIleName+'.DAT'); + Reset(MsgTxtF1,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF1,1); + + TempPtr1 := (FileSize(MsgTxtF1) + 1); + + Seek(MsgTxtF1,FileSize(MsgTxtF1)); + END; + + UNum := 0; + + TempStr := 'Message forwarded from '+Caps(ThisUser.Name); + Inc(UNum,(Length(TempStr) + 1)); + IF (SaveReadMsgArea <> -1) THEN + BlockWrite(MsgTxtF1,TempStr,(Length(TempStr) + 1)) + ELSE + BlockWrite(MsgTxtF,TempStr,(Length(TempStr) + 1)); + + TempStr := 'Message forwarded on '+DateStr+' at '+TimeStr; + Inc(UNum,(Length(TempStr) + 1)); + IF (SaveReadMsgArea <> -1) THEN + BlockWrite(MsgTxtF1,TempStr,(Length(TempStr) + 1)) + ELSE + BlockWrite(MsgTxtF,TempStr,(Length(TempStr) + 1)); + + TempStr := ''; + Inc(UNum,(Length(TempStr) + 1)); + IF (SaveReadMsgArea <> -1) THEN + BlockWrite(MsgTxtF1,TempStr,(Length(TempStr) + 1)) + ELSE + BlockWrite(MsgTxtF,TempStr,(Length(TempStr) + 1)); + + TotLoad := 0; + + REPEAT + Seek(MsgTxtF,(TempPtr + TotLoad)); + + BlockRead(MsgTxtF,TempStr[0],1); + + BlockRead(MsgTxtF,TempStr[1],Ord(TempStr[0])); + + LastError := IOResult; + + Inc(TotLoad,(Length(TempStr) + 1)); + + IF (SaveReadMsgArea <> - 1) THEN + BEGIN + Seek(MsgTxtF1,FileSize(MsgTxtF1)); + BlockWrite(MsgTxtF1,TempStr,(Length(TempStr) + 1)); + END + ELSE + BEGIN + Seek(MsgTxtF,FileSize(MsgTxtF)); + BlockWrite(MsgTxtF,TempStr,(Length(TempStr) + 1)); + END; + + UNTIL (TotLoad >= MHeader.TextSize); + + Close(MsgTxtF); + IF (SaveReadMsgArea <> -1) THEN + BEGIN + Close(MsgTxtF1); + Close(MsgHdrF1); + END; + + Inc(MHeader.TextSize,UNum); + + IF (SaveReadMsgArea <> -1) THEN + BEGIN + InitMsgArea(-1); + MHeader.Pointer := TempPtr1; + END; + + SaveHeader((HiMsg + 1),MHeader); + + LoadURec(User,MHeader.MTO.UserNum); + Inc(User.Waiting); + SaveURec(User,MHeader.MTO.UserNum); + + NL; + Print('A copy of this message has been forwarded.'); + + SysOpLog('Forwarded message to '+Caps(User.Name)); + END; + END; + END; + + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + + InitMsgArea(SaveReadMsgArea); +END; + +PROCEDURE MoveMsg(MsgNum: Word); +VAR + MsgHdrF1: File of MHeaderRec; + MsgTxtF1: File; + MHeader: MHeaderRec; + TempStr: STRING; + NewMsgArea, + SaveReadMsgArea: Integer; + TotLoad: Word; + Done, + SaveConfSystem: Boolean; +BEGIN + SaveReadMsgArea := ReadMsgArea; + + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + + NewMsgArea := 0; + Done := FALSE; + REPEAT + NL; + Prt('Move to which area? (^50^4-^5'+IntToStr(AmBase(NumMsgAreas))+'^4) [^5?^4=^5List^4] [^5Q^4=^5Quit^4]: '); + ScanInput(TempStr,'?Q'^M); + IF (TempStr = 'Q') OR (TempStr = ^M) OR (TempStr = '') THEN + Done := TRUE + ELSE IF (TempStr = '?') THEN + MessageAreaList(FALSE) + ELSE + BEGIN + IF (TempStr = '0') THEN + NewMsgArea := -1 + ELSE + NewMsgArea := AMBase(StrToInt(TempStr)); + IF (NewMsgArea = ReadMsgArea) THEN + BEGIN + NL; + Print('You can not move a message to the same area.'); + END + ELSE IF (NewMsgArea = -1) OR (NewMsgArea >= 1) AND (NewMsgArea <= NumMsgAreas) THEN + Done := TRUE + ELSE + BEGIN + NL; + Print('You can not move a message to this area.'); + END; + END; + UNTIL ((Done) OR (HangUp)); + IF ((NewMsgArea >= 1) AND (NewMsgArea <= NumMsgAreas)) OR (NewMsgArea = -1) THEN + BEGIN + IF (MsgAreaAC(NewMsgArea)) THEN + BEGIN + InitMsgArea(SaveReadMsgArea); + + LoadHeader(MsgNum,MHeader); + + LoadMsgArea(NewMsgArea); + + Assign(MsgHdrF1,General.MsgPath+MemMsgArea.FIleName+'.HDR'); + Reset(MsgHdrF1); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF1); + + Assign(MsgTxtF1,General.MsgPath+MemMsgArea.FIleName+'.DAT'); + Reset(MsgTxtF1,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF1,1); + + Seek(MsgHdrF1,FileSize(MsgHdrF1)); + Reset(MsgTxtF,1); + Seek(MsgTxtF,(MHeader.Pointer - 1)); + MHeader.Pointer := (FileSize(MsgTxtF1) + 1); + Seek(MsgTxtF1,FileSize(MsgTxtF1)); + IF (MDeleted IN MHeader.Status) THEN + Exclude(MHeader.Status,MDeleted); + Write(MsgHdrF1,MHeader); + Close(MsgHdrF1); + TotLoad := 0; + + REPEAT + BlockRead(MsgTxtF,TempStr[0],1); + BlockRead(MsgTxtF,TempStr[1],Ord(TempStr[0])); + LastError := IOResult; + Inc(TotLoad,(Length(TempStr) + 1)); + BlockWrite(MsgTxtF1,TempStr,(Length(TempStr) + 1)); + LastError := IOResult; + UNTIL (TotLoad >= MHeader.TextSize); + Close(MsgTxtF1); + Close(MsgTxtF); + InitMsgArea(SaveReadMsgArea); + LoadHeader(MsgNum,MHeader); + Include(MHeader.Status,MDeleted); + SaveHeader(MsgNum,MHeader); + NL; + Print('The message was moved successfully.'); + END; + END; + + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + + InitMsgArea(SaveReadMsgArea); +END; + +(* +PROCEDURE ToggleFileAreaScanFlags; +VAR + InputStr: STRING[9]; + Temp, + First, + Last, + SaveFileBoard: Integer; + SaveConfSystem: Boolean; + + PROCEDURE ToggleScanFlags(Start,Finish: Integer; ScanType: Byte); + VAR + ScanArea: Boolean; + BEGIN + FOR FileBoard := Start TO Finish DO + BEGIN + InitFileArea(FileBoard); + Reset(ScnFile); + Seek(ScnFile,(UserNum - 1)); + IF (ScanType = 1) THEN + ScanArea := TRUE + ELSE IF (ScanType = 2) THEN + ScanArea := FALSE + ELSE IF (ScanType = 3) THEN + ScanArea := NOT NewScanFBase; + Write(ScnFile,ScanArea); + Close(ScnFile); + END; + IF (ScanType IN [1..2]) OR (ScanType = 3) AND (First = Last) THEN + NL; + IF (ScanType = 1) THEN + Print('You are now scanning all file areas.') + ELSE IF (ScanType = 2) THEN + Print('You are now not scanning any file areas.') + ELSE IF (ScanType = 3) THEN + IF (First = Last) THEN + Print('^5'+MemFileArea.Name+'^3 will '+AOnOff(ScanArea,'','not ')+'be scanned.'); + IF (ScanType IN [1..2]) OR (ScanType = 3) AND (First = Last) THEN + NL; + END; + +BEGIN + SaveFileBoard := FileBoard; + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + IF (Novice IN ThisUser.Flags) THEN + FileAreaList(TRUE) + ELSE + NL; + REPEAT + Prt('Range to toggle (^5x^4-^5y^4), [^5F^4]lag or [^5U^4]nflag all, [^5?^4=^5List^4]: '); + MPL(9); + ScanInput(InputStr,'FU-?'^M); + IF (InputStr = '-') THEN + InputStr := ^M + ELSE IF (InputStr = '?') THEN + FileAreaList(TRUE) + ELSE IF (InputStr = 'F') THEN + ToggleScanFlags(1,NumFileAreas,1) + ELSE IF (InputStr = 'U') THEN + ToggleScanFlags(1,NumFileAreas,2) + ELSE IF (StrToInt(InputStr) > 0) THEN + BEGIN + First := AFBase(StrToInt(InputStr)); + IF (Pos('-',InputStr) = 0) THEN + Last := First + ELSE + BEGIN + Last := AFBase(StrToInt(Copy(InputStr,(Pos('-',InputStr) + 1),(Length(InputStr) - Pos('-',InputStr))))); + IF (First > Last) THEN + BEGIN + Temp := First; + First := Last; + Last := Temp; + END; + END; + IF (First >= 1) AND (Last <= NumFileAreas) THEN + ToggleScanFlags(First,Last,3) + ELSE + BEGIN + NL; + Print('Invalid range entered.'); + NL; + END; + END; + UNTIL (InputStr = ^M) OR (HangUp); + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + FileBoard := SaveFileBoard; + InitFileArea(FileBoard); + LastError := IOResult; + LastCommandOvr := TRUE; +END; +*) + +PROCEDURE ToggleMsgAreaScanFlags; +VAR + InputStr: Str9; + First, + Last, + Temp, + SaveMsgArea: Integer; + SaveConfSystem: Boolean; +BEGIN + SaveMsgArea := MsgArea; + SaveConfSystem := ConfSystem; + ConfSystem := FALSE; + IF (SaveConfSystem) THEN + NewCompTables; + MessageAreaList(TRUE); + REPEAT + Prt('Range to toggle (^5X^4-^5Y^4,^5F^4lag or ^5U^4nflag all,^5?^4=^5List^4,^5^4=^5Quit^4): '); + MPL(9); + ScanInput(InputStr,'FU-?'^M); + IF (InputStr = '-') THEN + InputStr := ^M + ELSE IF (InputStr = '?') THEN + MessageAreaList(TRUE) + ELSE IF (InputStr = 'F') THEN + BEGIN + FOR MsgArea := 1 TO NumMsgAreas DO + BEGIN + InitMsgArea(MsgArea); + IF (NOT NewScanMsgArea) THEN + NewScanMsgArea := ToggleNewScan; + END; + NL; + Print('You are now reading all message areas.'); + NL; + END + ELSE IF (InputStr = 'U') THEN + BEGIN + FOR MsgArea := 1 TO NumMsgAreas DO + BEGIN + InitMsgArea(MsgArea); + IF (NewScanMsgArea) AND NOT (MAForceRead IN MemMsgArea.MAFlags) THEN + NewScanMsgArea := ToggleNewScan; + END; + NL; + Print('You are now not reading any message areas.'); + NL; + END + ELSE IF (StrToInt(InputStr) > 0) THEN + BEGIN + First := AMBase(StrToInt(InputStr)); + IF (Pos('-',InputStr) > 0) THEN + BEGIN + Last := AMBase(StrToInt(Copy(InputStr,(Pos('-',InputStr) + 1),255))); + IF (First > Last) THEN + BEGIN + Temp := First; + First := Last; + Last := Temp; + END; + END + ELSE + Last := First; + IF (First < 1) AND (Last > NumMsgAreas) THEN + BEGIN + NL; + Print('Invalid range.'); + NL; + END + ELSE + BEGIN + FOR MsgArea := First TO Last DO + BEGIN + InitMsgArea(MsgArea); + IF NOT (MAForceRead IN MemMsgArea.MAFlags) THEN + BEGIN + NewScanMsgArea := ToggleNewScan; + IF (First = Last) THEN + BEGIN + NL; + Print('^5' + MemMsgArea.Name + '^3 will ' + AOnOff(NewScanMsgArea, 'not ','')+ 'be scanned.'); + NL; + END; + END + ELSE + BEGIN + NL; + Print('^5' + MemMsgArea.Name + '^3 cannot be removed from your newscan.'); + NL; + END; + END; + END; + END; + UNTIL (InputStr = ^M) OR (HangUp); + ConfSystem := SaveConfSystem; + IF (SaveConfSystem) THEN + NewCompTables; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); + LastCommandOvr := TRUE; +END; + +END. diff --git a/SOURCE/UNUSED/MAIL6.TPU b/SOURCE/UNUSED/MAIL6.TPU new file mode 100644 index 0000000000000000000000000000000000000000..489f1e75a46241ce305bbf0d4878516336b58099 GIT binary patch literal 15488 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 O91r_V(taw=^Zx;huSF#Q literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MAIL7.PAS b/SOURCE/UNUSED/MAIL7.PAS new file mode 100644 index 0000000..8cb9af9 --- /dev/null +++ b/SOURCE/UNUSED/MAIL7.PAS @@ -0,0 +1,165 @@ +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Mail7; + +INTERFACE + +USES + Common; + +PROCEDURE MessageAreaList(ShowScan: Boolean); +PROCEDURE MessageAreaChange(VAR Done: Boolean; CONST MenuOption: Str50); + +IMPLEMENTATION + +USES + Mail0; + +(* Done - 06/21/07 - Lee Palmer *) +PROCEDURE MessageAreaList(ShowScan: Boolean); +VAR + ScanChar, + TempStr: AStr; + NumOnline: Byte; + MArea, + NumMAreas, + SaveMsgArea: Integer; +BEGIN + SaveMsgArea := MsgArea; + Abort := FALSE; + Next := FALSE; + AllowContinue := TRUE; + NumOnline := 0; + NumMAreas := 0; + TempStr := ''; + ScanChar := lRGLngStr(55,TRUE); {FString.ScanCharCheck} + (* + CLS; + IF (FString.MsgAreaHeader <> '') THEN + PrintMain(FString.MsgAreaHeader) + ELSE + BEGIN + PrintACR('7Ŀ'); + PrintACR('78 Num 79 Name 78 Num 79 Name 7'); + PrintACR('7'); + END; + *) + lRGLngStr(58,FALSE); + Reset(MsgAreaFile); + MArea := 1; + WHILE (MArea <= NumMsgAreas) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (ShowScan) THEN + InitMsgArea(Marea) + ELSE + LoadMsgArea(MArea); + IF (AACS(MemMsgArea.ACS)) OR (MAUnHidden IN MemMsgArea.MAFlags) THEN + BEGIN + TempStr := TempStr + PadLeftStr(PadRightStr(';'+IntToStr(CompMsgArea(MArea)),5)+ + ' '+AOnOff(ShowScan AND NewScanMsgArea,':'+ScanChar[1],' ')+ + '< '+MemMsgArea.Name,39); + Inc(NumOnline); + IF (NumOnline = 2) THEN + BEGIN + PrintaCR(TempStr); + NumOnline := 0; + TempStr := ''; + END; + Inc(NumMAreas); + END; + WKey; + Inc(MArea); + END; + Close(MsgAreaFile); + AllowContinue := FALSE; + IF (NumOnline = 1) AND (NOT Abort) THEN + PrintaCR(TempStr); + IF (NumMAreas = 0) AND (NOT Abort) THEN + Print('^7No message areas.'); + NL; + MsgArea := SaveMsgArea; + LoadMsgArea(MsgArea); +END; + +(* Done - 06/21/2007 - Lee Palmer *) +PROCEDURE MessageAreaChange(VAR Done: Boolean; CONST MenuOption: Str50); +VAR + InputStr: Str4; + MArea: Integer; +BEGIN + IF (MenuOption <> '') THEN + CASE UpCase(MenuOption[1]) OF + '+' : BEGIN + MArea := MsgArea; + IF (MsgArea >= NumMsgAreas) THEN + MArea := 0 + ELSE + REPEAT + Inc(MArea); + ChangeMsgArea(MArea); + UNTIL (MsgArea = MArea) OR (MArea > NumMsgAreas); + IF (MsgArea <> MArea) THEN + BEGIN + NL; + Print('Highest accessible message area.'); + END + ELSE + LastCommandOvr := TRUE; + END; + '-' : BEGIN + MArea := MsgArea; + IF (MsgArea <= 0) THEN + MArea := NumMsgAreas + ELSE + REPEAT + Dec(MArea); + ChangeMsgArea(MArea); + UNTIL (MsgArea = MArea) OR (MArea <= 0); + IF (MsgArea <> MArea) THEN + BEGIN + NL; + Print('Lowest accessible message area.'); + END + ELSE + LastCommandOvr := TRUE; + END; + 'L' : BEGIN + MessageAreaList(FALSE); + IF (Novice IN ThisUser.Flags) THEN + PauseScr(FALSE); + END; + ELSE + BEGIN + IF (StrToInt(MenuOption) > 0) THEN + BEGIN + MArea := StrToInt(MenuOption); + IF (MArea <> MsgArea) THEN + ChangeMsgArea(MArea); + IF (Pos(';',MenuOption) > 0) THEN + BEGIN + CurMenu := StrToInt(Copy(MenuOption,(Pos(';',MenuOption) + 1),Length(MenuOption))); + NewMenuToLoad := TRUE; + Done := TRUE; + END; + LastCommandOvr := TRUE; + END; + END; + END + ELSE + BEGIN + InputStr := '?'; + REPEAT + IF (InputStr = '?') THEN + MessageAreaList(FALSE); + Prt('Change message area (^5?^4=^5List^4,^5^4=^5Quit^4): '); + MPL(4); + ScanInput(InputStr,'?'^M); + MArea := AMBase(StrToInt(InputStr)); + IF (MArea <> MsgArea) THEN + ChangeMsgArea(MArea); + UNTIL (InputStr <> '?') OR (HangUp); + LastCommandOvr := TRUE; + END; +END; + +END. diff --git a/SOURCE/UNUSED/MAIL7.TPU b/SOURCE/UNUSED/MAIL7.TPU new file mode 100644 index 0000000000000000000000000000000000000000..f134700806ac927ec7afecebe78df4cf0009e008 GIT binary patch literal 4160 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MAINT.TPU b/SOURCE/UNUSED/MAINT.TPU new file mode 100644 index 0000000000000000000000000000000000000000..5c2f46b978a4210d5f2ef483ada24371c2505fc4 GIT binary patch literal 31680 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 ec literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MARRIAGE.PTR b/SOURCE/UNUSED/MARRIAGE.PTR new file mode 100644 index 0000000000000000000000000000000000000000..19d880a2b9629149f062f21827d54760ad7f630e GIT binary patch literal 336 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MENUS2.TPU b/SOURCE/UNUSED/MENUS2.TPU new file mode 100644 index 0000000000000000000000000000000000000000..5072044d8a66c6586021c9a8ce7a1f5d0733247b GIT binary patch literal 17584 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 ArvLx| literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MENUS3.TPU b/SOURCE/UNUSED/MENUS3.TPU new file mode 100644 index 0000000000000000000000000000000000000000..6eff82e740c7480382d21ed0891d27e32eadad85 GIT binary patch literal 2352 zcmd^AO-NKx6h8O8H_xB!PjEIZS`}1a6ZS)CVflj_V`>x&(q2Di1Zw0=6vg;jG~^6} zK_n3^tVOkmAcC+E%Myzg6-5*+T3A6+L`718Ieq8dGgH!^i=ah!WWM)(_uTKCckaDo zO|W(iVGNN&b*f3V%IB~;rOx6*biyKfY;cT29`NIYM^qxS;q<35^pk)QPn$7;)jwG* zQpm1uY>BiL5q;?$A+M5<9opL#ZfqvX9bf@}A-k-#xw*B4=(CS#gr&84<*jAgH?=f1 zvVqFZ7DIb7dLqN3T`EQP2Qy#UckpC%X636@Jek7KLEN?z)?-8SOlqP`VR+QpVZ7Gd zvLv^3{k2%-EE0cXaU;ODcih|(33a?5Vj`K&(+3s?Rn8TlllQ*P( zo1CZ9$;;EpS^P0^CbTpdk2RzM&(rzGrHIEiru0NfS;RMJqbWbWa>fd;oaLfM70DWe zC%yVBHMnRwg-dnky|+6>#Azrz6QbAPObG+gJp0@B3`D2R9`q@$TMb_}O6FrDE#u#A zabMSNlw*>zV_d{R)9D zaH;52Je;m+sc2BsG1%L{~*38aL#8LI^R@7 z*HH-0dXeZWfSj)a=m2XBUH3NO`(#}VoYy6QF0f1V3!+~Vy&uSacYzM@DUkc|QheXb zx>4xtr%dgaXX^SEfwR6$^a>#Rg@6ulv#I;hY;v8)+IM@{)gBWb7oPMm89gfT=Vbl@ zIQQ?S_&qdr|Au7UJHd~#J|*i6OZUaL^!rQ~KEu*=&w|c%&jq@`g`(GpzFzb#Kz^S# TOV_an+yReSx{f26|My=3x!zA= literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MENUS4.PAS b/SOURCE/UNUSED/MENUS4.PAS new file mode 100644 index 0000000..39923a9 --- /dev/null +++ b/SOURCE/UNUSED/MENUS4.PAS @@ -0,0 +1,50 @@ +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +UNIT Menus4; + +INTERFACE + +USES + Common; + +PROCEDURE AutoValidationCmd(CONST PW: AStr; Level: Char); + +IMPLEMENTATION + +PROCEDURE AutoValidationCmd(CONST PW: AStr; Level: Char); +VAR + TempStr: AStr; +BEGIN + NL; + IF (ThisUser.SL = General.Validation[Level].NewSL) AND (ThisUser.DSL = General.Validation[Level].NewDSL) THEN + BEGIN + Print('You''ve been validated! You do not need to use this command.'); + Exit; + END; + Print('Press [Enter] to abort.'); + NL; + Prt('Password: '); + Input(TempStr,50); + NL; + IF (TempStr = '') THEN + Print('^7Function aborted.'^G) + ELSE + BEGIN + IF (TempStr <> AllCaps(PW)) THEN + BEGIN + Print('^7Wrong!'^G); + SysOpLog('Wrong password for auto-validation: "'+TempStr+'"'); + END + ELSE + BEGIN + AutoValidate(ThisUser,UserNum,Level); + lStatus_Screen(100,'This user has auto-validated himself.',FALSE,TempStr); + PrintF('AUTOVAL'); + IF (NoFile) THEN + Print('Correct. You are now validated.'); + SysOpLog('Used auto-validation password.'); + END; + END; +END; + +END. diff --git a/SOURCE/UNUSED/MENUS4.TPU b/SOURCE/UNUSED/MENUS4.TPU new file mode 100644 index 0000000000000000000000000000000000000000..ed4a409a2f6a292a168c031469f0ca359bb88c76 GIT binary patch literal 1504 zcmb7^T}TvB6vxj@HJW`uk!z6HRj{6R*i3TS%-Brvp{>>3bqiA*oiVrE8JQ11Ud)Op zwGE+%Bnqsk9(<9WBxr&Vf}rRn>Mn2m;G zjeyr2v_liu!JTFI7Vn1RM!td%K(@jxb zJ3M8&=g6J@FEGyFpW6rIS8?t<)miYB>6V%92j%A>k9YlT#yEibBHr=+0E*drDGxrt zzI%9QzoTtl8U<@VazFYBQ2irlV0}W!-{bri%3nbj7(Wc)UAXZ~IOHvqs#p8x;= literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MISCCHAT.PAS b/SOURCE/UNUSED/MISCCHAT.PAS new file mode 100644 index 0000000..3f3d1c1 --- /dev/null +++ b/SOURCE/UNUSED/MISCCHAT.PAS @@ -0,0 +1,184 @@ +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT MiscChat; + +INTERFACE + +USES + Common; + +PROCEDURE RequestSysOpChat(CONST MenuOption: STr50); +PROCEDURE ChatFileLog(b: Boolean); + +IMPLEMENTATION + +USES + Crt, + Dos, + Email, + Event, + TimeFunc; + +PROCEDURE RequestSysOpChat(CONST MenuOption: Str50); +VAR + User: UserRecordType; + MHeader: MHeaderRec; + Reason: AStr; + Cmd: Char; + Counter: Byte; + UNum, + Counter1: Integer; + Chatted: Boolean; +BEGIN + IF (ChatAttempts < General.MaxChat) OR (CoSysOp) THEN + BEGIN + NL; + IF (Pos(';',MenuOption) <> 0) THEN + Print(Copy(MenuOption,(Pos(';',MenuOption) + 1),Length(MenuOption))) + ELSE + lRGLngStr(37,FALSE); { FString.ChatReason; } + Chatted := FALSE; + Prt(': '); + MPL(60); + InputL(Reason,60); + IF (Reason <> '') THEN + BEGIN + Inc(ChatAttempts); + SysOpLog('^4Chat attempt:'); + SL1(Reason); + IF (NOT SysOpAvailable) AND AACS(General.OverRideChat) THEN + PrintF('CHATOVR'); + IF (SysOpAvailable) OR (AACS(General.OverRideChat) AND PYNQ(^M^J'SysOp is not available. Override? ',0,FALSE)) THEN + BEGIN + lStatus_Screen(100,'Press [SPACE] to chat or [ENTER] for silence.',FALSE,Reason); + { Print(FString.ChatCall1); } + lRGLngStr(14,FALSE); + Counter := 0; + Abort := FALSE; + NL; + REPEAT + Inc(Counter); + WKey; + IF (OutCom) THEN + Com_Send(^G); + { Prompt(FString.ChatCall2); } + lRGLngStr(15,FALSE); + IF (OutCom) THEN + Com_Send(^G); + IF (ShutUpChatCall) THEN + Delay(600) + ELSE + BEGIN + FOR Counter1 := 300 DOWNTO 2 DO + BEGIN + Delay(1); + Sound(Counter1 * 10); + END; + FOR Counter1 := 2 TO 300 DO + BEGIN + Delay(1); + Sound(Counter1 * 10); + END; + END; + NoSound; + IF (KeyPressed) THEN + BEGIN + Cmd := ReadKey; + CASE Cmd OF + #0 : BEGIN + Cmd := ReadKey; + SKey1(Cmd); + END; + #32 : BEGIN + Chatted := TRUE; + ChatAttempts := 0; + SysOpLineChat; + END; + ^M : ShutUpChatCall := TRUE; + END; + END; + UNTIL (Counter = 9) OR (Chatted) OR (Abort) OR (HangUp); + NL; + END; + lStatus_Screen(100,'Chat Request: '+Reason,FALSE,Reason); + IF (Chatted) THEN + ChatReason := '' + ELSE + BEGIN + ChatReason := Reason; + PrintF('NOSYSOP'); + UNum := StrToInt(MenuOption); + IF (UNum > 0) THEN + BEGIN + InResponseTo := #1'Tried chatting'; + LoadURec(User,UNum); + NL; + IF PYNQ('Send mail to '+Caps(User.Name)+'? ',0,FALSE) THEN + BEGIN + MHeader.Status := []; + SEmail(UNum,MHeader); + END; + END; + END; + TLeft; + END; + END + ELSE + BEGIN + PrintF('GOAWAY'); + UNum := StrToInt(MenuOption); + IF (UNum > 0) THEN + BEGIN + InResponseTo := 'Tried chatting (more than '+IntToStr(General.MaxChat)+' times!)'; + SysOpLog(InResponseTo); + MHeader.Status := []; + SEmail(UNum,MHeader); + END; + END; +END; + +PROCEDURE ChatFileLog(b: Boolean); +VAR + s: AStr; +BEGIN + s := 'Chat'; + IF (ChatSeparate IN ThisUser.SFlags) THEN + s := s + IntToStr(UserNum); + s := General.LogsPath+s+'.LOG'; + IF (NOT b) THEN + BEGIN + IF (CFO) THEN + BEGIN + lStatus_Screen(100,'Chat recorded to '+s,FALSE,s); + CFO := FALSE; + IF (TextRec(ChatFile).Mode <> FMClosed) THEN + Close(ChatFile); + END; + END + ELSE + BEGIN + CFO := TRUE; + IF (TextRec(ChatFile).Mode = FMOutPut) THEN + Close(ChatFile); + Assign(ChatFile,s); + Append(ChatFile); + IF (IOResult = 2) THEN + ReWrite(ChatFile); + IF (IOResult <> 0) THEN + SysOpLog('Cannot open chat log file: '+s); + lStatus_Screen(100,'Recording chat to '+s,FALSE,s); + WriteLn(ChatFile); + WriteLn(ChatFile); + WriteLn(ChatFile,Dat); + WriteLn(ChatFile); + Writeln(ChatFile,'Recorded with user: '+Caps(ThisUser.Name)); + WriteLn(ChatFile); + WriteLn(ChatFile,'Chat reason: '+AOnOff(ChatReason = '','None',ChatReason)); + WriteLn(ChatFile); + WriteLn(ChatFile); + WriteLn(ChatFile,'------------------------------------'); + WriteLn(ChatFile); + END; +END; + +END. diff --git a/SOURCE/UNUSED/MISCUSER.TPU b/SOURCE/UNUSED/MISCUSER.TPU new file mode 100644 index 0000000000000000000000000000000000000000..71f6cd5ca50d8085485c3fbfb57050171242919e GIT binary patch literal 7184 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 D%M=Cp literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/MSGQUOTE.TXT b/SOURCE/UNUSED/MSGQUOTE.TXT new file mode 100644 index 0000000..addaab6 --- /dev/null +++ b/SOURCE/UNUSED/MSGQUOTE.TXT @@ -0,0 +1,37 @@ +$ +Love: a temporary insanity, curable by marriage. +$ + + +$ +He that hath a wife and children hath given hostages to fortune. +$ + +$ +Never trust a husband too far, nor a bachelor too near. +$ + +$ +All weddings are similar, but every marriage is different. +$ + +$ +Marriage is our last, best chance to grow up. +$ + +$ +I first learned the concepts of non-violence in my marriage. +$ + +$ +Marriage is the triumph of imagination over intelligence. +$ + + +$ +The goal in marriage is not to think alike, but to think together. +$ + +$ +Marriage is the triumph of hope over experience. +$ \ No newline at end of file diff --git a/SOURCE/UNUSED/MULT.PAS b/SOURCE/UNUSED/MULT.PAS new file mode 100644 index 0000000..18f1474 --- /dev/null +++ b/SOURCE/UNUSED/MULT.PAS @@ -0,0 +1,73 @@ +Program ChangeMultiNode; +Uses CRT, DOS, RgAPI; +Var + RGIn : GeneralRec; + WhichErr : Byte; + MultNodeDatPath : String; + Noder : noderec; + Node : String; + +procedure OpenReadCloseRenegadeDat; + begin + OpenRenegadeDat('d:\bbs\',WhichErr); + If WhichErr <> 0 then HandleError('Can''t find Renegade.dat',True,1); + ReadFromRenegadeDat(RGIn,WhichErr); + If WhichErr <> 0 then HandleError('Can''t read from Renegade.dat',True,2); + CloseRenegadeDat; + end; + +Procedure GetMultNodeDatPath; + begin + if paramstr(2) = '' then MultNodeDatPath := rgin.datapath + else MultNodeDatPath := ParamStr(2); + end; + +procedure SetWhichNode; + begin + if paramstr(1) = '' then HandleError('Which node do you want me to apply this to..',True,3) + else Node := paramstr(1); + end; + +procedure initnoder; + begin + FillChar(Noder,SizeOf(Noder),' '); + OpenMultNodeDat(MultNodeDatPath,WhichErr); + If WhichErr <> 0 then HandleError('Can''t find multnode.dat',True,4); + ReadFromMultNodeDat(Noder,StrToInt(Node)); + end; + +Procedure MainProgram; + begin + with noder do begin + User := 1; + UserName := 'The Titantic BBS'; + Status := []; + Status := [NActive]; + CityState := 'Internet'; + LogonTime := TodayinUnix; +{ 12345678901234567890} + Description := 'Waiting for Call'; + Activity := 255; + end; + end; + +Procedure WriteToCloseNoder; + begin + WriteToMultNodeDat(Noder,StrToInt(Node)); + CloseMultNodeDat; + end; + +procedure DoProgram; + begin + OpenReadCloseRenegadeDat; + GetMultNodeDatPath; + SetWhichNode; + InitNoder; + MainProgram; + WriteToCloseNoder; + end; + + +Begin + DoProgram; +End. diff --git a/SOURCE/UNUSED/MULTNODE.TPU b/SOURCE/UNUSED/MULTNODE.TPU new file mode 100644 index 0000000000000000000000000000000000000000..8e91c7bfb320b2cdee5860b60be7e7893d7b3817 GIT binary patch literal 31744 zcmchA31HOK@&EhoZjvP=A%Otl3JVB=2qYl)A^}X;AV&z{P-;ko4MZWqWS2uQE=JOj z7_`=d+N#uQ<)_w0Yc=)QqSb&$Tk6qLQR`i{K}#tjXh{B_nK$3Pl4#}M-w!3TbG&); zX6DU1zTXW6c}o{7{P|E7slApJR=Z9Ax5l=`R)znRT7IcgX%~`Ak+Kl@PJgOII^NJ9 z<_IJ#B}(00VLWN3zJz7^&kLP!O{rr+-k{(olc&@Y`vUKJPg(gIw^D^AU#fcQcS-D$ zt(6}42BqR(B;)Y^lGr)r8#a`eDRm}hrsYc_<;Sm|Us~x|h_;o6-7Y#~6XBPzKlyzM z%Ga)4@1C=+*fVQWaq0TvD@)gxdbS$&$VF1(j=+8eCIvS*?i$r5oHi-m=w7o!qI^CL$`;jz0wVDHj2Ci-L0e zNmk!un5M=utW}S5Tm!;yF?ov-N%u|CIu8_Ph zQui{xPVHdmQ{xzJQ92zqGN#mC6^l<+V;?Ms^}q?H7>x{LEy_apDYb|33oOY7;p@~C z#!Yy@$Y6Sg^(aG^q4lI%4>O)++`{soSoSkM*rMBCYUD9}n=Om`*)^=T59vQC{Z(6! zv;3c}8yOBT-e-BG!lsE*!RdjI=CpuFC~8WXk;f;AI5m?p#uMl$(};UYQ&d>h@$=1QTkfHlfD>IlN?kE2fRAIU>(9ed-f8F`f6`Q zg}cnNek;c8ag=X#R}_0n;hoYl2i5S>F;t1iTBjFI=@#@xwra^6t%!jTNPvial<}1}rR&&BdkUkg?VUOXk|f z7A(l4A>LpP@dhh;(D9<&vw5w7+fja0ZO!#}r5V7`pJVtl z2gzd%oYb98@1xZ9N!M8eAFJsQMQ$HKq;( z8{2gvvT0gR&@oJ#VNu>5QH)@J<{%}ZOuE8+s;g0`I9Z+g#Pox%g;vx8>pFJ@;0DU< zJagcAp@A3jz@2+5ERB23;WyVj+otMj3enB3nx;0GJsqIR8hFmwRr7RPi>)0$>-|r+ z`JO3kACAOYWz>U`Re!p!x=<>dbBWj4;BSI=8vM_iqX8kpk>VTTH|>?AA>Dxl!RqT!fsb?e&y3}z{Ip=zd8~lyYHZ;Npni2~dmDkA1Yw$mT{=;*U2azQ$O$Twq*Vi)9uT!%SHtMmU=Keqfuix!}w=W|65Ti7Eee0*ra^D<@) z+$M{>USL8+J3KpR(GIKiJjM`Tf=0 z{<=fVc+C37(fZRj-i`%)5JEP|_niHV^7hoLMR%x1Wf8g2c-`nLfyU!VSlclh+@ zy+e3&R@Fb)(1Tj0%M)y&)wdp2Ooz!xz02EuRd(gMK&$Q*@+(#WUZUXkpci<_qO`QD zn8J*eg;V=G3NvU^f~}0Z0^1VLI=7>uynMr0#}&g0Gih}%uApt*X4=@SE-x#ARM~1R z<0zb9TTonD*1s^b0L|v;9g(A;d}HZqY>}pcKRBd=G?$lQzf@l4#!kVFlbdI(1w|Ac z*jWQQG8}P^a!6J$b!|oj zH*^24oHjEXbH1Wv%=v1wb5~Ali?uzcRi{i&tJl)vsLN>$%Sh^bdW<(-CjeyI>T_Dr z*84I#+;ITKBW_pK>6>!CBEjkzhL>_AY59v)r%|d#N+AM<1BmhrZt$OusL(9NX7P{e zDwvNg>EZCI&YZxrNVMZou00N2Xo3SJuLhB4p@ypC9kj5j(2R#htT6RCZCxD#8vO60 zWQ29$KZ*w73f_;vLn8^vFb)3IJ|!>J#oR}SW1;9W9?SE^(YG*zck%1pC7$rvLV0Pk zu&N!$Y?lAayo^YrV9d?JGNL~FLar?Fs4TIW`$y~o{@>3v3W2v9r8uRw(&JBzFirc> z;Pap@)^rt2LgF|0zlusbETk;bZGY8FBqb6{FRs|kcFa*zI2b~twz=tP>BSA%lps-8 z0j6;;`~!0>nhu;3u+?0dSrBFSW>sC)s;;*NYII$|%8=8#{o3Hv=qMy4|Xrm<^qBw#H&HuGc!VKt*$E@aDRY1h4PBA>EQB>6JNXF?tyL`aJfR)2<2sC z`+}WYwyAi1=^9?T9cA7PSGp_44(Y5JR&fvAV(=P&ept)$jh<56=!|h>(@wxKbll9L zd_S?yy?!Irwvjr`tB;Ljuh-?+oyyy%q3Xl%YRjya5~o3&_d9atJ1xXH+L1HfX(i5k z9XV-En>V$y1&2E$|JhXR!tyK2*KF-wICV~Fi;|CR4DCUZ9feaDn9d|ZT%NwCh|Tj} zxxRFDeBsoBtsC9M>5h-Id*Q7M-}aE7=(-1fD=sT9+q$9LTj`+CjI|VIhHiGqL#gHo zFxA>nWyh)|+XkwMzUOG!w+1eXhB9fI%2RpsIThh zK&t4ym-dU9f!>}rLsc`$S6Q>U8rY*ZYC?6^Ao3S0v zTgF|HaZtj`TK%D5gRJQ8XDC&1(TpBy^Eln_Svn6U(|NG|5Jm@d z^b4lE74q~MQEHhoBUx2Un9)~l9^0{@*?>A2ldK-Iz45-4wV);O;QPRUHfg8LrSz~U ztKDIz6tSCy+TNVg$|0+MuI;RWMRJHSslB1?EDD6i-&4rHHr8qeo4wzxo%&mDOcE~Y zE|e^(gpww7U@WDRQQ(KFIS1ETIam~RsHvGAz1eQNXX-cb>tdW46=}|?n^UzAdZ4_$ zE~X8;r3b&EAu`U}hYSg}8-;dkl@A* z+g*k;a`wFJIR)956i#%MRA5C29+MN}jqT+11oKFmU_+Uxt@-*aZ_spF2D2x)Jv*tZ zqm+kLaWYAo&Z^Nb)Z$zpW;Cvntp{olF@>e0=H%I3HK(+09!yX*pX{sg6ve3OrAM2< zK<)roVQtM>t$8%`47lUe+3K&<^@*r^b!vt|chxt94n1^y2*2D|$Cn$2gJgZ2_ACw# zsX1Z=;r?h3YR_bP?zQX0ddA{R_AbMA z3$qDVFK4Uf21mkz85NU|G~?-W#>ZnaWIe<62>A%btvRN!?vAr(iIAl!wY{r>SOUcs zr=!B=+_uT?ysl!AvwicWpRMcC?{R!WRTuP1A8@3~EFY1!65uDuW*xS|erz zbwB+D-16=;nrl>>Y9@Oro~KzWa(^X;vAi1R980C{gMuYPoC@B=2LDNHDRl*7AAo=? z3K=EDh;r4A4qEOGYeYTP<1f{&5mdW|@TwN9Ta1lsOa=a63HZ9R$ZZ9JD`n6iysB6QcCck`4t9K#&%LghtnROL3bwZn04`rVxh}H^kPj zFW*d0MD-0G-y>ody>@;1mBs7nv1eJCd%eRp&5;;yDV!SGO2-vWU5G2fvF8;=9EoTH z9@Q9+O$|rPwCokxb1a1!)^XqaUh1sX9(n{x-QuO0MH?M+HmtGDTDWLow^`=yJuct9 z*1NvAqCf6)91(kbx#cVzZ^M|buw~D2EgDcb6)Qo7L*6iPxL2<$r{e&L#_*ajge4rS zF&v!A+*i3*)A0?j2k84t*mz;#RK78~%3JAi@N&XZ2uZ|J;<$1v)){*?X#g)hLNA=Y z*6o1@Dz{daZ-ml5qLlR!x7_1#myL~`JAcvaS@VY`#)o^4FK?q9Z-tTp+OBfEj7Q+;WfHS4zZv$_>zF* zif*|J3$pX`m*y1=i}GqI9XTt!`UEQ8jgyDTu^ai2hHJM@qE$HFj*(7XiJnKpA$(5T z#E+fXYS?)d2G`-<8pph#VLjPqc4KK7+Pc?_9if;1&A96BY~@F6`Sd(qM`(i%D^7^q znw(=k2MWuWZw3qp@p4WhZc@UZVolmOzr{TOG=ROILwCb0?6IL z;M0&1)Is3_@JRUUDT(m|3#ZEIH<;6O5l>bl`SPV+yDHop+;pJ;&)6&6 zYw?m<#a1pJuI%}F20eCaN>Aj1yW^OA&^wQ`2LGE8TP+p}>`gbHxY{*Wc0r*UE-RVO zEaZ&KbDkhkE779*0sA+r+@}r&A@N<`ZuHyqp?y8}pfQkbo`J z_PFc&&uCYbz2(_@@L-C^buDj2JxK4iA3KA)2Vozzt0v(LZGqa`8HpF9!Qa(5!1?l9 z-ppVdn``i_NfuqK=Xx#T{b2;A^!_VzKb{}rf9*;C=N%)4r)3?9T7T~bzrQ1o_eH!K ziap(6j~_oU^g#o4OKYIlK+UCHV9>Bet2UQT6%Bp|c08q6LC0yhcN5 zgx)d?zK6x(C&4&SLx+Ct#E_77H*IUfAKrxcY$N}m4Jh9d+#0+ksKt}~$V-Baq$&J) z-YVR>uf*_lYY*OwVyHC!3q?%`~38Lu`hOdxXuh| zXStRbcAvCye63pgH~2s77`Emb@XR=^?B|2~>CS2~J`MSL9K1QVUtP`6uXTWGYkHm0 zW6>j!SXfl(0-HN*@V^6#!tUK;BMj7RmgI}v8xbHIOw)9H?n*lBp0>eHFD!&zW`z{c z&F?oTk*n<}8_8d(XJ81a#oIZ!Ob*)b15tU-(^M_N3A(E$`3&>Cu?O(6y}gB=Yv5CO znF_sMgE#c7fo)c^5Jq$%Zlfxoy9x6ne?-&dZ*GbVi)b35AMrv;nXw}lYb94T#YnXX zWsqk)BqLs71pbAoKQzf%M{~`zGpc1|xI|NISVlDXr%|Lr&oro-M|qePRr`~X&Pda) z1Ui@>r3HKpGBk{E`H<03jks%i7a;aDyfGaBC$=gS>ZCLDUQW`P=-Gamp4g~h-i4t# zK8HU>oSwUQHJ~3&?CHo7dcaSS;12WyeqzL)_SUj1s=m<`=jtS_+FJ($^rY6sbxmkg zdVv4QP{#dd9_PMjfKqIbFP^Nrn(1f4>j@`GcqNI-n>y4UOluP3khP3&8KbMa4pY}@ zQ|(VWWAh#fRN_Hja3^6Fy30~Yv6Cv@U9?W{1f(UXiEOcUm>S*+?j3Wvv;nId&#ADP z#Vs+Rs5J}n59q~g!cU$ryA_FRTnn#&w3-2tH z|DJ0h&&F|=kg7wq$CZgWtPX1_85nA>TLbTEnIg4fJojL}0~NSWnM-1QO%2h%+E8D3oPp0gf^m zwtZrB>c<3@#JfJ$z%$5+SWYgA06s?<6AV$71YeugA@aI4Eq?4ATE)0hU>B9EA2ZQr zCYc_XOvM#fMDc(b186q~2~pPwN>Uf_>Y2V-o6EeZVhudU9Qr0+iYHYH;NDKIioF~jgUlGpqKZkNI*!>%J7L` zX4E%mU^U1%YcTgD3%L-6rQ#bsoH_8@wT90>>}!YjeCP}nqK@+x!^3+!-tLVyN#%=! zm4WAB#}?lu-XH5@K``ELA{_r=G>=AXb9FR-7`k6ZSRqi4>@fpFPng2u3a%N~kW`1j zhFJBdDYC)I2De2R&}lHupoE7ake}q7ivYYF^kbO+X^LV)!|nJ-sH&jJ=i%MQ2CFS* zVw5RiGckC2VRbl%!SJYgOCME}!It^f z`GF`{Gan#RgM;kojh*0s7%`N_^Ml7~%=i**-{p{sSm%K2Y1oy0AD;M@Q?O|wPxHVH z3C>&uCl*`gPFKusoyYT>Yx`Xmsy1{6j9Bo(3iU<{Z8oA4IJRJHl!!x{1gE-7OEC zQzj~J!2ZVU>rlK7Vh~}~J*tR+X%>;7P=^{4qAkK^WLE zj4^iLY}c-EvKkt?_6e17d6#;ce%u(M%k##e>;t^@8Ik&-ObWb;s*`MPU3gY`3Ym>9 z($bJR=_al7ZoH$Vn>V}YCNyzdR)#*4dQ{;MA(-sJhf`F6DBn5{u)cl_jRt|U=w+RE z34y2Lob$adXbtTMuz%M(d6!&f=na7<-rNwh;Eql~K9qc{KX7%Na{)48C~DC;?K3{r zliu|01vIJ-MK875uisC4m@ncCY!83hF@wyPkfSmv+>ew?aye^C>*WJ)Ge$4;!TZT$fhR30$b#^l`D$#@5 zBs;%Jl6=!iosX*cfd;E{F)Y26EDaS4Eb~p~^og>8FF`!HK~q8%OV^IhCr;Ov2DhTY z56v}r1tf6N;>?F(PX?1B%skp%+dJQlp-B%k`L3Jls6lE}2dl%`_5pL!%h{H{k7^z> zX-g1VJvtmh!}b{=sSX>B5Ub;1<=eLhoH?O5w_NjIa)QXS- zz*i5ij!3C*Uw@|Xa~rx9H_oJ+m4zGHVubko2} zwUTP(T<)Fp9hKPVin1lwIn$f{9b00xZHp)k>^^>if>*KV2}|G)n3Ob)L(3Chy?P>S z+d$Gqo>hDu=D{oKG(|!crRzD@a=~|yrR$C;z4~}WrtyuZd4<IYhJt*NvM)={G z&8Mx9nKZwxKLBA6-U|B;;6d5DX~# zmhTYP<5?_rZuK?s1n?@(xqR7wFugRWzb=PYHO$`$!7t44xBSESn>*vvlk|&p5vo3R zk6X_>)M285$*E5Q+|XEeeYlg29rH2^!wu>i}dT~S`9u&_$bT|SsfnDMtH0RSB)nl z+J;%z*dBV0agL*c=@>*`3<6HUdj4}fJU55PGc;oB*2NRED-a<4?rd;_Lf#B{I4W2W zM>+e(0>D;qy+`eSucHHWY!|a)yp-A2XiUS;%@E1XELJJ$I!Ev>ql+J)0fS|h=T8eR`fR; zI1rmYx=SRfH4txbes$2ktLo%UIj7L`h`MaUxzIaqgzq}bLho>$JM=YD`pQ7?t}?QH z;4$T#<=w7ZTby&uW=%u*b`!@iHafCV%RJ{YZw|f*iqO1Rb&`i?;dzU1kl-pXY#wy- zh0-Wpnb=W`q5j$GVcP1Zq2JJbU^?ncYvi!$3EWZqVxDXo16+7=$AJYZIuwE5(Jx6D zWjf|0#OHSHnLCuTfR6Uzqr}%{QJv0Vl>bGK1)K)%9L^J$&GGi-(VpLNw5gO02>RY=;oIhaYr>ei%_-ePFY3FJ@`+cE)MWY1ai|T26b#1l`+( z8VnEqVkFGIChXsI1?JyL#9G^O+FO37W%1=bz0VB4m*#yQ?KzbBCoyBMp%nf4K0E$S zgihkjP>C5U0B5VT4BRxTC4l>FN?j)SRVwX}QYESi_&)HzuhMS8ZZEe%;B5kb3Vs%T zN!x>fKFBq){_g5&(f?b}w}Ad4%Qw3IB<&6h{F}7@1oC7j?aQ+87e?lhy;q8!wU9d) zqtrIwTR`_QzYl)Do5t&?f7pLJAlZAL=-4=PA+isBf{(i@L zcIW>A{C)7_8$v(Ka+B4&f`2G_J`+8sg#I?S~lHI0gN72Tt}*ly(=Be%OV0 z-$HS8F&t5_Sognp1@z^i|6;*Q7@nxU8g#Pj8li8}FrVU(2D(q^wZMyjHvrb6-&>jf zO8lMZw-NNa7#~q^FL3f7#U%}P{tEId0GmK3zda}X7g#)BL9KN|6Snc+-{WmLh!E`U#bj)@;Y6`8pwC(>tT>T?#S)U@U~nB!$%S(z<*@d z6zo&e)Np){NBeg+w=Yo((4OMCOz10FZj>q#+zsf$xUT{vziyF!s->UrgHC>}1KbaI z8{i(mMuD$FKl$U&z{#&40+L_<&h1}`KPLA7Q}mq_{ii`63Ar}NQ~Z;8{EsALi=XGg z?+%P>5%4X51>{$ZW1ZmmZJ6NORE6N10cjlD0cjldfMmxlfGdFC4~Rpp`ZXYp=UKqL zfPV!fyFUgb`2gGTO8n=<2i^Izj)WtQ8AYfUbHS&6<^vW1t`zxAqUQ!~XIHlh z{Z7$ypWqLQo=1R_p2q-5&wk6o6zo$6kkBh zTg=lErRQylvdg?1!g2BBj*)qMG2@xJmoV;9^B6kRBBqbeT`ssAeYr568>HQjm|vKD zFXD%ngVg;@AE6!vPV=rwa6jTie)h9HWeW8O;Vj5KiSd)ZcGypTv$4M2`KTuxzf_5L zKje!GQA!tl7<8?JdgY{>tR_LR4@wf|ymsC3Pj`R%!+yXepqQ^a+`EE5^_;ZCmpXoQL z%Z0v*@tta`;8l#*s#?Jt(2nNUt-wkDoy@;o{Y3Def=}c8mEfo$uRWlth&Egs~%5xtInfj;FMRXR*GL{?qH!01)bKF5okwo z9wBkgkT~P_%jV^wf69BZL$CY0^EXqTB5$cK()f0;TpZ^;;q~}Sao&T!)DG)E`aMzo znB@8ElHbQ9-&^%O%*FZyxmFkQ=#Wxn$P*p!EX0rO!|$)nBYlI!o}qv~;Mm_WeV)*% zz7zd2z>R>b0E+-O2&8=q%~Pz?8OJdWTBiwr2$16P4CHDdzaKc|*&Bf5zmM3?MwhPV z8M((nr}<0!5$b2S0lKoc$C%6&N2Y9W}?-BaXg#HUa()$GT z>_tDn0bT_Bpx|!{9so{ueop-X8W!?nqbrW#9c&rtss`O`u_%k-rx5&j|hp70CRwZ8Ckk=m@z7y5-l z&jh6YCxK4(kWZ)`)ot=C^7atb<5z)`e~(DMzR$4L)dD)TkAa>;fT(kMl>ZkUN*4Y47CSz(sMWCW7V^QKhO9i z^{U{9s2%FiTYxLj-@BskLzZ)4Kc)LWCh#liryY>S(*t#79d=3m5GU#{o$3zk7zRlE zk$~i%$sFI&HzIG?KPwq;brmzr%w5YcBew#4nlD>euSb1f^xnk$$6a?)d+iFg>T|(k1uqMJ2<=D0{x<<> z|MV`?OBCuU$3d~(F3L;fuS*SN`wMbM!hRp@nI`tn#5iewMD8P8*bmYkmGV=!FBMn@ z`bN;V0PY2({3JW>0h|K(9N=-lK^AIv8RZMyzkAUr`1v5(Oadf7O-J0Q-45X7$NK;w zs2&HTexCv?0;D)oo&F2!`Jno9fvuoZ{Or80eNf#G>lxt_0jd8>d7ZmVEoT1iMa!|y zQU7ZIssBi1ee>bDM%`n?&j2=E@^KZ@s(J~c-DO889zeDdn9&f5m z_csKP`Wu0{xEFe-*|eRPu>2^sn&t2EZ2+C}_!`Jl{`^Mp7nuKg%0WD8r`q%;_+H7r)whYN+C$#V16 zB*CYHPyJ=Z(l}pFxm4OM27Mp=xRmLwu9ZSxMfyNr&Gfr`rA&9JGRAMq^)kF8cMIfB zLv9=Qw^-GPo%Ns}#W-(a`c>-3Lf;Ge9@MP|Sl?*%F!L+bQ^J21e2VMy(jVPxZNxZ# z4?5+?A*PQ~p8($r{By?B)k%gW>NMyyo>oAbkG43a9B3a8xCgLz9Qi9%~Zxvluy`(>N{#o$Sj4B>#So`SC`X@GFJC1^6NK_W&Tp z;~?mJf&U(O5%71o-8kd#((V|b5A-jE-n*ObuRkEshXazH48S75nRsis7OTqTBDYH9 zt`fOxM9wGhC)g1C(C$g#G_MZ>-U9d$;Bn-6JD?r7EneH%J6^}r0Z9C5fW)5(z8!cT zaI#~S$ZrBp_EpD|U71ELaLR`U#wQzh0Vn_6i+?yG5Abo|6#rkNJ^Ax#Y5z805$FLx z>bDJ$`n7h~_+UW7&+D%3mMGPBs<+r+x~sKvO?!fm1(MiQHDSqr9pDqmi1jxsBZ^-(BiSh9&A5fz1N{#&VwA7U*|DZ)}3L>jFTsYn5N61BV7=$WML>YFqzV+z_21WtOhlXSazEVsm11Ul(25WW|%2>6Z6pKRO=oW^%s z68UF${=I0w5B=T`I*s#xSZF|dd3cL?JvjLCvK8Nbq)EBO2#dY`-)IN7s|`8$o3f)_#WI?%5Iq;Yyc zCqMic?Z|(7S-#GA0CeI%)Pu&^Sn#;OXPAGp@gn$S@5@4e6YbYwPjFcJc^5d%n-4|5 zEm`aDmQ3S$*hos&`g6b$G7UT{GKMVOfTHsXSUkuy@dM>pGTqyJv(ryjI%-nU*dk}V9!~8O}IfeW( z*{G&=7+)v6HaebEMmE|ST^NR4_g8Wg)zYRHx z>!$*b3v7oR`FBiD&7av*8^``+z>c7SVGGa>t?PYqoQIu1Y1laxC3awR}=4**`wFU#ecu z9iWq)!&$D>a)IFEz$ZH|68WjAG+u{tGAvOusXh2}7%x)`x&0UFa_MIkx7(e6733&S z%0;h-*;NL5|ML0H?V4nSY|X893Fgcer1d`X}t5_NN4o!#@U61U#t^jVsOCw~y98knwKT@q$lg zJjFU&@VR|-9iI=J@?$accN)tCUkSbIKz9SDaqa{x0=x}$AK-&%-vm3G04Z;O&+Rj; zhapGyz1xSzzdQdZ@nQdGqW1*LO|^b0cxxZ>ze~mS)&5WHtL^F8m&SA0(pT_-fJM+d zy04a>)R**Mlsg-An$IqQ%Y?rYIL+%4K$_QA3*9U2b_ia_ctP$R(*7p`9}@mAMbFcK zMbPtGp}#Ec-eNl^8}ETnm!{*M4oLHE zWSY*)F=={Va|s~j)k1++pdH1fUhumGe+sY&^k(RxI`Jpb^H1Our+=rB-wJXE_0#+J zq5a5?8?9sdY5T{6PWd-k_|ASh-{u3SJY3dK`~61Y@8b3kTW^#0Ka%$M2>)mObiDS7 zo?i<71n@1e^BKWk5cm@4G_KcJ?|as_MDN?e{{(tzp0i6H)si0H87X#8ba+w}$TPXOF0o2d#{K5fx z{;U@II+ojMY!JKx{m?w!4mp~SyGS1Jmtx1$tmmTKX2{b#c}?Kk!v7m^nkWANr2PJ; z(9cM_n1OmcNdtA>^dG48I0TLr{siEp=VCz8Ge_tPq}^o$bzT=UexkZk_}329^=k(p z<##>WQ~dpc9}@gH=>@$VbRS^PL3+Hy0BO8a29cd5YKFjNgUDV_?v;bc-$QI025Em+ zK%Vk@GxIZYeaxS2yGi&z5dIy)znA$%wnv5kD?o~uU*vwra)rqUfz$KB-vin){tqEn z1i61P-#@Qa=tjD3p8!bw0qJ^vUkFI!pCm8~eDXty$a&Lg9FvXj1E;*XDP8Bso#{G1 zegZn#^;4D`XZ&37hXpDo`PP&@eH4}!k|{2=hZK#uy28LZc}_`%fgb+#UZ z^}3eI_&6g2IN31~&4V?PDb+C@lLy)JuY!v7R zq&)f~=>dFGI;XSKW)It&KMj>sh=@Jbi0{DG(Q_S$5aC}K&N~bzlkT^Y@Cx8-Iqyd!r4!$%UF!?eF<4I}@# zR1WYhu>Vrgw~X|`&Q(HR!*cUgso-Vc*BVMyvOZ_Zc81eZs=?n2`n7nTKG=uie?;`t`!hwr(GTw*@H`h?l_`3EW+Uin zcpkDxO;CdjonJ$tI}3C?$Aw%8y;pGy{_Wi4%kW%-;#~+x^{^81MUcaL6+GS_vRtF< zN33tM`X%^e#}kZC40|r8=jRddssB#_w*aI6S#~@%(L%x&+VDwEjk>@6LaQ+F?Ji zA9S+kC6-&JUJ?9{qUUYMQ9gYnbexf)uZZ7Ipmryq!v%Pj>3Dy|s{2W_>Uj4Ar23g| z)&9L0IN9s6l6{S?h4dNiiv(^%dy03W#L-D{2Rg?xx4-yx zFvh=E*%UqZqJGB0Z=`nuaFUQvQAQT<`+#QvJ|*&g;lBn*{$3>WY6bZlu_%O}_d%ZCm!t7) z0G;N21lvl^y*JSRf+04d{X0rI2;%)&46D)gG1~0~j`tpckG}B?>z}1;hzr@-4RIpGN2?QFV0Xho-WJy>W2ul)^ZUhHI0ELhU z%D^~-fTE+Qh>GF>A|fgSjN2fHjw^z^(HI657{w6M?|14}cRC?BGv7DwkJotm)LHA) zsj5?TJJ($I*er(6X;#2oVPA$7g)ay%$G?Zew}tNrpA@;+ey&v)w#Ukt`?^6E1)7)m zVmn#VAwg)mBbW0(r zG`r1=9nku6lJ!vL>#2~&sms(-WvwX*7CI#7O&8VE>?>%}=VtVpqm5dWF@~{Sk6mEh zEnw#8Ig84?p80TnkQlIXYeRCprOEs|=1_!tVZ8<4+58H#vd4t)_tB1o4)m?#3X5hG z-<9o|K9P(xF&<%*mS`ApHYAZkjfK$&!^oC1z0~6=%3W0AS=-F&(eQxPmhidK>K?4j70<-2@E)4heoMfvX1;_3Ma;cY1DPK`Y#L+6YlMMznZL0eCW zr*x{fxU@{_G{D9jkt9MUZ79bCl*bg!Ta-U!-n`+pBG1&lnjsc6 ztpGTbvp;0Uj8az!m^TiQx|0y-&Mwj2_d-~ zqh^H&(~IYovEe}>Tt);^H^%49ca12W!CXP{MzyJU=-d%A*odHbjM6C1C@L|mM+U{A z&Pgn+GlJrSO5>W#oLc717c;_c3o5`qDiEAdFw)Cz57lTF(70;mY00xpp-Zd2m)6)_ zUykFZH=Dm!$lPKd-H!jd|vxNjTvC5mPg{%!)MNktf-B8Q6k1d%o)$7U6 zES^=&EmV5^PE;xE)WAn&%Mhe4zG%{wC@tHP?kg=TE*(>})Di)`*I^fG!Wr!}<%F7T zDKrX0Pi~2W;wQ}%HBovLS}qDzHeIyl@@$J7q=#FQVE2rzX$J~x)J9PFs$w50BCi1xXFBS9VbQEiPth#zY;JMG?&AAzt3!(ya!UaOgPJLtLgEo7jb9jyEobTi zk8wb7%WRl;Y_?XoC^5RzlYpyd|F4Ht;K;)t4(L8te32vY%{T5 zv-rY}Vd4TJD=}Zx(b0r1OSTA_R>=iRmWtH@Uvy=W7A7${$`n8GNK3V5@#)HBLDTX1 zwI$0zI=P;O-XUIZsWM53$h^NbOPG&WCI)#Kk~cxQBgl(_%R*(mplJ>kf-X_=f^=ul zcPqI;dXqIv%_u5Uas-D4J;R!%4J$74DA_^Q{njkY=wg(n2_CPK6=ZL>X6v(xrv4RHQOmY7zLAC z9)ybrT5z$UnG2dfa-p-g(Ap`aS)AtUyqpQlubeO9P{MWgJ@ih7=q6z_G;58z#4&U! zU^^-Rt&?;FJqi+Z$R z)Mvgu%S1=tQ00o?(bSERymX~L$kW+w^l{k!6uxNS$|1Q-ma^ICQ3> z_M8fd@SK#$44@a{kgp#RbD>ffq;=K~w%q}NUJ`Jb4)jXB5N-4l>1=R(;`k1_S(ePg zA`e}9u+`|EE)CS&%<%|3z!~Al0%rn34{)Y{GcVvW`a)-4wwRsfiRE>S(6ZNKHhL zvj`kYO<0gqEjSa9P}m>@mK#axFm)-%kC z?<^DDOnW9f*hK6jx{(BUy|CLtc>2(JbBzK?Od|-~Z1ABRRnk|;CyCJ|hOsV^M^^*- z^kWzSK562cv60NE<8Fz^OI#r3vn5?3@j{6!B(_K#A#t3*@zS~vi(_rjex9X>NC*!H zU1q7!rU55G9)%|(vg!!Dk`=ICz=NPS3ix%zn-6>o=;gp(mc-Tpcg5(Q13sfZt?UEt z0e)Y_z{7!8vjb7NGi*^|s{wpyc2CX=&$LSn}xXKURAp>;Ne(wUh6*!X5Iq{ z*ccl#saiC^WQ~r~nbQU}E!GrcQZaFHET(;*_PtE3bsM@n+bAGs>u@t-)2ZtBM(S_o z7-@EcJyJE+94b4o0J(P_<6)wX!Xjc0{w0$ZlG zV;j}>Y>%4APN+%jqS}E)X&v$GcOB|#C;T?l8NVDQiyVGbAJ@a0k9i_izV5* zakcA#OJNV>rU#1xbhc*WPM5RNaRMJ~ z?~SX$M4oS-#C`V3e3g9)e^p<|pR(VK%fZdK9MBlb`6+uJ9OM;Tbu8rx=C!03w}_@Je%-(#=V^h*C0~l#e)NrgH#W z1gHjV2D|`x18@RR1DI&)s93|g;W+7r*_j&={gO@I{8JpsKSyBW|2 z&=+tEU;y|-pyNgyIly_~O#p8au!qet&tjWRvw;g)np(_ilv42T2E7>kdw|QqzZd+K zh~u|_b%6EksQC|Uo3;UX6LcPBmrYLqo&;?`=8=$R0*`_$3wF7XPlWCy&{H5Q08HiEv}qjU2h0II7cdX@C4f6& zQ^r?o3jyVTrO;gtxDWBILOfM~`@vre*a+X7fggd*KLFnYegs?q{0yiEaOJ33SLT=^ z05QsHEe_C8>C4-qHYA`nB%@aJ0Neyf0rUd&2HXtj1L%u7(htxdFaY~A9XvN68+)_> z`>z1|v;Z|_7V5%m?9tiShlQvwbFeSxVeihvKAaCcAA7k7?IQ4tf$s!eigqcm5BuAP z8nhU7Lg?Ule)@KJ^Oum<(v0n~>F zL9YdWEo#GW;cp#cT#uN4hj@R7I`$Ci*+ZxyzlY!718;!t2DAx34EkZ{ZiMbe(3>#M z&8RDnpuRkc_#Q_s{Uh)bsC`cWKZ)A+B=A<$!>y>NPow<|c+a5zY(t&h4*EIhK8Kq5 zJlfC0&x?SaXuphpcA=kL=yNyv-;MtEqP-XVec|DAHer9w2y&Da2)O9;C+bphtNF%d;<7m z=zfg6eS-FcT6yScV2CQ+_YC_utz7A{wZAIJ4H(BifC+INX zFn-Az4rs;uTcbfo!#0}lv&Nzwi*_t*+W@x#-3B&oK@-G-jt4&;yadn*@X-!F5K2j^NJ{uV&zbgm8H=S>5F2lDR$c6&Nt7+^RbrH=q)LXXb6T%37%pz}aa zz&Tfdb8afmylFW9rtvZM8Nf3@&w$JWnFn|l__NV21fBzWF52_ZE=Icq?K{yfgFiYe z@8-J!>-FF8!}i~RSI&R5FUOg=9Ovb|fcwxUSc&#Z$W{SY0q*DL^fjQ@z-BGZ-F2YX z@$QawIA7QCJ?a*|5ir8>7~ksnBhJ$&aGpMi^K>iD(x-5yJ`Mh};BN>2Iq;tc{{`@O zfWH&`m%;xN_`AU04gMbRUj=_3_^*M#AN<$BKLGw);2#A4&)^>d|1kJRz<&q)cfo%T z{P)5CEBHsjKMwwf;GY2hBk(^4|8L-b2L9*Ze*ylN;GYElEAY>N|3BdW9sF;={}%ij zKE-jCmjJdp{=t_y&Y^t{df$Wp178m~;`kB#^Jt%k-38nqE<$z@yo+f61pS}j=V!Ek z0sj~9e?j{)^e=;7k9Gre8bCKd&XhXMm>BS4K*xZNQ!34Eai?jkEON#x)qu@_ z7XWWK6O_htv;AB1s`zl-O3h0J*cV4db;adPl)pVX|$^ne!3vd=^ z;w;YA?&b;F7T~jhbATTJ=K((fE(4g7t(lYr%?hvs;+0HOg0jHWPI*&nkJ~$AV^{r8 zMY+zs`kzqbYqdY=FPdNG??p_0TSyr_u|uW0T<=>oJS^o*U-iB`|HuumTMVP+XO%;E^x;D1zRCW_8S8uKzHC3QxD^WCY4E7Sd|B_ny&9u3zdVSDI?$(O!CZ zia&OoWa{JgY+**MtIq!aj8^=Fg7nE8FFm_MMYD3nB)^z~$`um>jXV4Y%Pso2)%z&{ z!Eqm2k>h8FR%GJ~bHl1!VeTrIoIf~9Ia7U9pcl2{U#V{fX8?0o<-%;OS~1$chqHk| zOKw=TV!Xdr^Wz)qq5ZfWN$#EpjO>b7sv#gn-xonsM3h`*N;#7z9CU4TK)S)spoOVE zWJ(Hp_`FG+qBk+PCjA{=k>}@ZY}mI91I+SsnUKkTW4%pXz2DssJFaTQWWN!la3hqg z2Yl&}Ub&{UGolZemI?E0&k4iTxpJ!3Vmm@4*X`I&bi zjf)XKHK}xNlbi%n++fU3!;-;`$-U<6Tr=YhzQawuQKNa`!z*$z??Q8s!WQ?J179=VPwS_#SQ*O-6~r69d_PQl7Lu=m_457W z{R&D5n$1#T)En?uq4Qds5e~I$`YNf}zE&0cv7L4>A5W{q#;WO{q~;(?uNcu#*!QS4 zPaD)o?42vsU}5cFSu(3}dMJvtX8l$=@c{Bf~3mS;?}$3dsIZ+^B4@p#09rj zi)*50Do-u*-DOO}e2Nu8x17c*)60BslHs(v?%w-Q(64VXu&dOZlx<$F`!PYaPmqns z=igbX7pW_6Ox@x;DT1{Begv&VQU;>u#X425+AV=7YNw|9e3PX(&%ZcZG@DFZ$i8Y} zyeL{NW|mZG-hGFSt?&&`jrS!OwOLfMkOGYpvgR;Pb^7k0I?ZJWxqi{0GqO+972a%> z(2_-RaXjjW(JRhJ%D3->Dy(93g@duCkf&OF>0+9_{b{#RqMNzFNJOYD4#yZoM{bm& zGPS0)5vE-6Rxb91Ppx^UaXLZ0hM&n>JSfC8k8Y5OAKkDxkmYM^;%jUVnPpMEjKiuy zEFomRVM%J^juTO|Fnib7Mh(8V8&e^wa+7nXYR%-95?JY^f>p5}M=gea=PykP>i^+U z8*-qFaf;>DG+?kmq0(E)O{0#eJahi!Mkuy8DT`VVsz5;S00mrbBk}+d9c< zO&u~ZeOxGCo!}``Mi)c8{Hz}0q0)s(Zb)@{9jWnNOX_GG1rvNHE6N)t_^vhikSacG5&6P8V4uk8#qV;TLLT9wO>0lXvnS9WM22mZlwT_4xP zFrQvgUeCN;sqM9+7o*qOaKW|)8G(*!yMvXg_^4-Io0O_jtDe`!iX4%8lTje8hzAwa z7ZSeT2*29p2<~oowaeB>$U^}sF=o^PgW%;7qc%p1d!MWRu&a*C(Wjgl=&D;hpxRXz z^aMq5Jy*P~TVks|^YWs4#qX-af3>evyXtYz#}(hmv{*$lh7GSM?B`#qkM8NhZhX`2 zUtkjx7Fcf-ogCEiv$h@FjsLdbIfOurrP>vS66uS_D*5z~tKoGd?*P*F$st$W&O@%t z2Wu`eToQ!*FOa_q`4PzXLB1FA_i8@Gt zw}oXRjT)M+!)86{jUL4ONTVywjhggy4Ws(2j7F|<{e%wF2D*M)GJKWm5}q7gm#STt z8ausuwaW-DH+OakPJ9P2=6}cOH6pyGQ{8ZCYaVHneHjvVXs+t673sB{Hp%6G=5%>^ z7%Lx4DQ%L%CX}V|N{v;ahfpHw+WyU!KuEc1wxXJ6(KvI&9`}p7i@Dmv_PEE18t@on zjX{a70#%w`EC|$)fXT0DqXVHGZB)H#S7f8#YF9)k5f(~>OqS^W>b2Emd_qTj`4{N^ z1(E&*5&i{X{sj)Bm_DkklYBN(K%FGpK zez1L2`(tXHH>#{nw+Q8c@vq{{17Lr;^vx}-x~}$EYJ92L_in|-irT}eZK^-nUUg(g zl2_S&d#`^Cx$tcDI~iYXOQhr6`0zA=jn^(D?^?+2rXwK%zYP2Vf2dAm(JAzPMt5dE ziogHjEdcw24DaqH2>Lpf%YtH*HE!rzIZN3Ay;xwpW@Nh5uy@vj&pCdxA6MI+ceIffj zE%m+;bY|jDh%*KHaf&gX{)#dFVZbz=42AM#VL71x06I@G^cMir_*N)1z7Fg`fjhI` zLy!7@S`p*y@Eqt0&@bUHxs|}LN&Tae{+smQPc{4xRE_>-O1eiw&Eh*|;%aeS4D;XBR2IQOXBN`EV(JNXj>uj5wbHP2+h9n8vf)WUR9z zpbOytl(cK38~rBeMn46To~|4EWxC;S0r=!^DKPn4A?2&3{GgQoRmwk<{;q(gb->Jq z|46ez$CwSjw@H4k&YuCyNnhFYsyK4wmv^Ql4Wm{7kYK`?f&f zPRt{4GMfWEsymvjJ9se)wTQ8{z)8T7;1i9v;!=*{m-1*?SNfxlkX<_XOaw`3;CC1qwI8ANpebA*Xz% zLS6!Tn$#5_(|gieVe35$$FI|>+g8*Def7-G=9`k zVP7iseUe@x>1EQsQrfSU_8X-ABU1kPajG5Q;l_V ztE}7U;8Xl#fNB16rT#prUo7dnC4G;iD4zk}0sd(nJu3OzB>y={@0RplNgtH- zVM%`==?|r!PgSZrL$N;X?h^QIT>n_=s#yO)`NEdvjK&`c`wC#ZNh;y&Vw85w zWP-)NW44CDy4!-K_)3$6yc{Pp1wa`Li=Ug>46*sSx%qiSH}p%Gn1f9p%S#}N`^`$m z6Ov6IH#;+D8PWfKQpJ{N2nVc0hlaeuRx(OuHvMdSULoq9KDm}vF9j9b$itWX zC1Q9c>-cPy4|_Ni9gxl;BZm@Z%vW{`^f~`@wns@e&W^WdX2W*DO>P?yuGyyAa|>)v zpxqojgrILL$!ctFwo-qCBiGb))~O_$v9!F~ToKZ%FsaG@a?O)69gd>><=F}eZH^(G zomY}gw#*fF?x%R%JX#22Y?G4g@3o$e3FQ_zlv};pCMDSiNmBFUitSm-PrdjEHQ5-O zUzo=m&@IqN9!pI&NpzCp?uDIdvYAf|wM{Q5P&#`RdsPuVG2a=VldW7A_;SQ~SHt6q za~w{Ga;+DirzY!WfqDF%bPsl$ne_VcLhlzQm_`5R4eGn0Xpb_C z-d4h?Nx7TOEB8>RGMr56y);6#;4F@ydFsEBQyod0)KRoo9Zm15W2jlZk1nfYNzp|h zmWR@fVRS$lNiN+O+Mz_yv&MxXqY!#@KcIehauB2Rp zi+)h6>3+jz*uG5d$~Ne>L$@DxwcxeD>oEQ+#_xb11l41F3cQ(ash^Xd@pHualHM?! zMXa+JpTqb(#+)utmU0o;SM;#q66kAMrG5|oBjUDG4QP|n0p5Y!*Fl~1k+BQhjXG{1 zkBL2NG_w%_!{{mhaJn_@ZaR%##TzUXzI_}W*)V~g*g28nToW;#L_upFpkren0FMTb zCfoRETH}Z&rwhGtJpw!icns`g;Xea%JZ$30ujaS3&oK-59N=shQ zw1qT$+aiq9F;1uMl5~1{V-^)`%%&j~&w!Rdw}e(iEuq?SCylT>!3$}jy%4;J(z1)d zR{~!Nzg3947Q6)hB^Z~$e;xgCMJe^HUJtn(wN%oh+c(nb5*Mf%w3&PZ{y=Rzw@|(R z7RvX1fxZlV0pk~;+Xlbw=)n%qPI_|7PSm%HUJ2SmZw2iI-%I(c|3p^;UITxPqVIYg z~AL}vj(R0!J@;6a#P~(nyo~XGfOg;xItn@tIsrNfYQp{XG5Be4PM?D=fLd^#FM_@T zU4ncG{A+Md-@v{V^7o)0argZQtR0+F2e9jqyJ#3or`2pJjbk~qhdoChu>zW`IOtV% z59kUgkR`A;=|i?3R7>HkftIk-l%Re=yYO`w9pFpf(06$M@FjmXgmKyX35c}d8{1Nd z*B8sO{3ZE$_e5F}@>XOn%gMInc@+inMPr)9lsGpjZRYfZC#OYPW@i@XCDN`vqVKj`SX{WY)hs?i!#zz#)wKtoN4W=SWF|YFn2L#1Aj3!{$^&uE6K8) zED>&+#Q^8&NlD7n%#6{Kaj8+$ZLxDJFV%Ak;6? zMyRL3Wx3kAfrOV+Z7uPpFl#ADOHp=0r^ToX(tuJ#BxfRO9G<3WL@CaPWrbq~y7S8W z=G4zgc-}%at@Av+MJ2i#E)Q&iR%WP7a^Jut^#gqxF-PW|UnRR^+>;gEZboGd-R_`u z4`>}6Uj?c3Fq-KM7Zq}O2Sx}1jchK>8ealv;*V@VJa0Zs52r4vd4O3fV<>m|2fL=Th z%j$8XAHr88!d~_+$x$qc*wtePE@w05*q2;*PC8my;dW~aCYGUog50Eii-LE-vd^gM z?^T~wVR^Pa^zj)~0&VsGus$;6bz zLoBAY8~Bxj%i{?q6q=8yO2`=XzsO8S3rE64OCv9&0Vd919GlxJ=}UaFqSNj1lp(3d zISZv#LN06Qbh9;sgi-uM0M<_G%^{Qj!c=%fe*6&^hpQBa>&n25r!ATH?uq<$ovRxNH5)zO}CRc=~M) zuIWqN7fr6I0P0!)t#fA^5krqoHKXZ?J(Vvd_3-1E(u3RF!>_AfTvg3T#PHfL;$@GL ziEq=S;~4h#NNB3CNR<@}Z;BQFKwKz&N>M$|y*MkCR~G%llsHGc zLZrk*TC`t8oOr*`-e8KB+Vd=rKW?*REz5TRb>{cJmpFd@GQ(dRNIP@uuXw-X5?v(& z&rR>%<;zrW8L)Rtj`lzFqF_;N+jubzOkZH$nGC$ogoe)zH$mUWx|`vbCl->#p?euw z=Yx-8zSi^jvpj7CuUH6ILBLcsW@;POKH5B$OBJXOtD)Y7j=W)8gE#Qhe z!8#T^O6BuTUpq(gXCyC!ek%0UQr@NVzLZmqs;xtw#wgKMc%I%U)E5O*o| za}js};%w6Me*Y(JM;-ip?vj2r(ElBFb-?-gdIvIJheIOH0y--ALV8c|2x@}fje0*8 z{-!}^WxR_b{z3Xy#<>c+4T#$=?9TZzgO=A|;B_1%U&uUPfI+hh7Px~(NxKNcBC(I7 zpy%i10R!*v)WAn2j|0xv(I)(klU@2fEA@rY^Lee7c}gMk`{;RLe~ora``3W;b6;c7 z&V3zZ-mgYscau&_yH6$los8EZ^3;^MA!opz8JCLl7;MzeNw|^MYZ?@3)aE_W$me~F zCPU`)e$c4RI|eeZE6upvx)gYZ@GCB|1LylcPs$F-i-GfVuoiqDc)7scMU~S2k5YbF z@*UECkF?(>@xMs?zl3ZWbOtit7hlLaFF@vXehoerdD_6O;GN()=+0M9_2*(U9rr9j>czh|Xine^Kr?A=9MA@7F17W^^rze)TUyI>OKP{|_J}VKD#z literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/NODELIST.TPU b/SOURCE/UNUSED/NODELIST.TPU new file mode 100644 index 0000000000000000000000000000000000000000..b860cc2a7639dac30dfca91c150d4c9c34979d3d GIT binary patch literal 12448 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∈sdGD80{Dhi)k}8JrlBfC!{}`kmqRc&34{4 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 BiPHc8 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/OFFLINE.TPU b/SOURCE/UNUSED/OFFLINE.TPU new file mode 100644 index 0000000000000000000000000000000000000000..7e5e7c35a4390666b8a73b55022b6e73ada0ceeb GIT binary patch literal 37856 zcmeHwcX*V=7WcemTQ*q|Qb-78={@%^NF$vV0*fmU1BeKSfPg4f zM4AX1uuv|FBBGRIKo5V(ri(>e> z&f-{}*I6&UMf-Qea?Wzm($)7`amVdN0-GmlDyI!KpbZNvZKOBIBpev1Lj|Z*c!r zm!@Y{8tJ78y+G&@#I5?r6~ zog(*gbD(qWYMMOC&4KIOPnXJ5+??)=jeKXFoW?oEF{v|bqY^U^ci(6C$V)Y5Y+|x4 zA}eJ&W49k?Y@N)Uy^EI>)#Ci&<#ZCjyvYT9T7e<|arZ7>fsEHIm;5d%DB~!EmnJ7j zOL^gVO$i^2^^(Jt428%@!@!utlvzo(>B_InlRA?4A!#(4Q(`I$2N8huSm?k+KW6ZR zXxsE9pk$_FKr>WsST zrL4>HHY~qUd8{#6(`Flo!ZKPn@Bu7Cpp&FV84+vbBdO^#jBzk6)GZ=Y+1)cR>Ul9u z=r7K26QR>pjZ&kjMUr6luI@+;GiQsKn7dxLLFXkk$^@%{NvYH4WEeAH%k;O%R&++n zn7Wo$vsx#k*8B=Og}NwxOlEv$R)%pt4E^=gOQUtD?t$?cHsb>D+UYTUOH7ZxmmZ&H zTtxoSg{v2d`Yic3p|jHu`R@xIJ$qhXpr5aQojRZtBTuO`A)MRFDQUJoN*)|5M{`E1 zaX;9|l_p*}lJnYAt}MzN6Q6BEg>uQ5suC$l9>HnKSkDf4T=!^eO7wt@et60ZTW+*m zUP&tt4Kpwe7<4pa$@4ka-@v)XNGH3zf|QA^vV1B7H@u?f9YHhX8Y{6{+|);TU?gUy zrzXYbX3F#Llj(X0!VFO7qcL6Xevi1`!Kb81LzKxmO4H>-cZp9!wL+_dmpDVzfmdvL zd`iYlTRM%_40$J)bxS-YQ%T!(6NGZJbBd{jDL&V_b%-wzs+j7GsppfNad|@zau=;tYAS zOWw>-y`46>Btwl+p45U=fxHPfx$w6-BrP;X`ErGc zsafe&G}gH^$_-I^2&iOhUCb@WGS-%yMwJtjINv6(af#X(qofJ)lbohr^RY2XH!40O zbELf7#fvw>XMFk`Te`f=#jHdH@K7j>0ZB;|X@;EdlAkh0`Bg28OJ$);Wtb_-zglTr zI=L>LIi@HNif3Hf49u@`rc2;!in35O()6$GT;vQcOh+kpo1)~gbL4avJW5ueV9hQ^G03fCqY>S{xv^KWCcX=Gwj(vW2IBFWem0j;VLkTy$g z1ebpJutURkkt-@`P*aEa)D&$Q$9GXv2PbBvCB@H^jG>TxR;MS;&uVT%)hQO#49VCN zHl8*1URv%QXl}+2x&SpXWquvbX>bIX-67rMTnb6ge7yWT51GHlR32p*kOZR{^P1}! zZAz(asO}=<{7Rx%qP|C(qf`vBba~8uVug91lID_QF=rU>5trtSW#+1LhT|^rY0e;r zF|wnaXqpB<%VRTSN12lm4|ju7vuN)iKhC+-23O2cM#1fZeoe~6e%l!4m$|=UM+s4ljIh<>^gnkI<57-*k54ePFV^e@9$Z=9S@XO5t8$1u3 z#v<7{?1P)vKkfM)@IjsHfymF~eqL(n>3Y!U%d}^Z?#$@khvze$*zp^+6!!I=%=KUp z$oNwOm@2FCcmiEo4iLGjrSN$KdRF9i?Q0$z5ix4` zm?0sN17c7jc1ESGMLeo8fi-6aoj(hy$8`RR2h&*%^-M&rKLGhBDBY*n8XM|+eFGSJmj59f&?Ij#gMzna%+QhbMm@765*SonS7y{PUtc_$Y7AyD zK-#>1AoFD&`A>nVV;~HZM8e--4JC#X*JlPRI=L?kVr_g`J?4w%_SEaxOvW0rz+iLx z4yXl>U>);9rLk5z5O|0}`*`~LqLIm!Z%`mp6*B_SdH6T;_qAB+qs(n(FSs+CWoFhP zk{1yP61oP=+h1ou^_x(7gxZw3D5h)29_fcZ*lL7 z_SQFP;EDRx`x#6YG%_krhflbMHENf&i!}FQ{bi4)?b%qg1lm0eIYG{&Fsd{=^nqS~ z#lrL!oz9Ob^^JPjLvNzVv5B%)8lz-ORISv3MAvDKOpvK}8hYh;mcy&rk8;=hv;5;A z85_)cS}=|H!OjDQXf(YJE58>D^bw7Z@k%|yUgkc*v}+f)AW=__ImyNHt59 z3~zYyLR(k;xlY4HGGIwCVyQ6ULEnnU`Q~_3Z-EE-mUs|vgD2*;c!F(*$Gi4;I_!WM zpd+3yJE1BHi<{E1w4uk<7+I@<4v~F;}jmgK4I5AzF`68YpjF$JJdxJ zWu)1};>}iNuDO}A%-merWNx7xGPhFRHn&!;nAA=x>JZ4%qC5{z0}`KFo&ckAnXio2@$m{wbEMf17Pq-(k0uGi;Ck9P6q-&*rG_ zA^kqPWVp!wkS{^@CH!22{&&#*88#)rzpz|9AKy}L0saL11^63K3fnUHDQDBv3eXks zQORCZJfzEt1yB#*0|=028yZT}j)3o>NRN~@tD}(Lc;q`CI1V@tcsB5C=p{>g z)img)OHaxfQiYNwSqxd==YW?BouvRfU>RhqAX^2z26zqpu19_wr5BZFC4Xfr=)F?1 zejo6D*uISP0i<6+`k-`6DMCK)!|#WnFM<9TW%)wdqyJ9os=tnO3H<&Ezkf=zb+@5= z8|A+XUL|;y;4yhGCW8vaC|e9hdA803+63Agv^QuU&_198K?i~k0v!Z87<4dbD`=~H zLuoEQDYukwDXry8hBkl>@-($0=x%`S@*aH;d6C=`&`UlBn5OoI9l^t}>km2{z6O9E zfK$YQz(bM8aNyyPkAi%(JV%X&pKv-N5UG zbRY2gDarb9Wxg^Ye*l5 z{7uDTcvIP{7AfJ%DbOE*{s{CH&>thO&lQYc#QU`}N4){~5l{@h66lpE#quw}zd-*t z=>Hr1zX4^+9(^V3Dv^(@E|OLCuFjygP)xukU=Lsqb+77yv>D)yw6{7<^#S%#pOotZ z*9RQ{9HfRT4S^ehZUWo{@}|H|)!BxY;B`W}6L=xOA)xyL_XYhh@Wbk5WdLBHx<@}q zy`>CNFBt~IZYX$T0Fi(gb&fg?b`yXn0?zs=mrd077z1D1eZ3f;%CzODkS!P>eG>n*KEuVFoU9qSRn38YV8O*#WOhjsBh z;9r3EK)(-s5$oAitbLzj?fU}j=a*RXzQkI018dj!fFA%qVGa8Y@Nekd0=@0cHJ}ZkEufv$#@InBH*^AoAl(_fF2G$tcLQ_>-2)JYbT8mOfWCnKfN;P7 zz(Abv4F`;n=%8?)AsP?^7zY>+cnmNJFc~lv5C^aUW&&mb5&^TNW`<9eE?eGVX3sx;1*+M4pDVW!2>98*5zt8l!$3V4lFs9OV!r(FG7#Jmo$ z8L$Pg4X{J97+(Oq2%STczy1)?homd|Bht&t5u}gcc<`9C#dsXLC!_-&r@?z$I%RwZ za0YM=@mv7!0`U8Qi#W9X5cosjOOSsI`%e(pr@)`W$LGLbNUKd>!PmEte}_}s>wp`8 z?*TsmeuUmnz&`>14E++Me?@%1NyW-ngXKV7 zFyxH^O#oK#tl(K?UsH3rnSr1scrE2mO|6k`Enm^MmN#I1ys2-4bQ{>TlPmNcknSLF zF?N*yZR{+6Yz&o88oEH%4bUCX1Nrs@^n$E6FhL*a^abt<{4jj?2ksC1aNq%efzTZc z+rdZ=0SpBU2aJI3DBw}h9SwOjAO;XCpE8aE9uJ=rA)AP}ACuqJJqCIb(vy&$1luVn z+Z5ob;7tXNgWWWgXNG*hW0t(om?#f3%>kYxR~nNcPX?U=Iz^siN<|q{<+i3Y@G`;6 zMA>rz^8pJ0d5|rIY$M^4Ok-&HLeBT0@#Z5Hu;Qc4`46oR{#gW zI|O_h@D|eV$nnPa<<*88fbWt10r)5Q`$fL)@td6JaU12k2e>bPXs7_L1g->@ln(*> z3@SheFeukOJd{KaPbERBuVAhM1Sms|fy!y61@_$ouIe;%F%76C6-;>}9{ zO99L996;bedL{5GJV&enJOx+_cp9({{PmD;#Iwal;Aa8b@vN~O^b5c{ag(+a>797C zcnSC=@OI;(Yd4-d_5k)F?tS3x18*Pbm!b0p=r?iC_$JZ>MSxSt>oo8gz&WJP1KvaW zJ>d6&-v_=3d=dBq;7joF5$-rYLYm+T;A6->1^yKHD)3d{&wxJz{v7Zn;474e;A^D6 z0bGNh>$u9jj`R({kAPzEN^qN50$YM#K>q^z7o>j!{2MyI1OE>EC*U^V4s`y;J@4O0 z6O@83!|iPu(gb$__wj7T)PbH7Kvtsx@n%&$#6btFSKkI4G8=$Rzyuyhn*pAHdH`>A znb`-JpgzDKI{xq%02~Bp2xtVICcp$u0Ubei0wxFngaWz(x&e9sdIS1Er!O$U!|Jo1 z1Ju2q1Hl^%7^?bt4hJ3yhyp|-zZl?Hz&NBQ08a!w3Yer8n_`)=0XzeE4t2O4b-5jQ z7w|6NJ?d@G*8wNhww|ZdkCo{xWlJJ^a?5O%^I{UxschJmG~i6&EcUZKn=Ury&d@r*J8?LfRD?elE=FeG!Ed*b%W1GKZ%Dyj=*Z1u3-kWT={U$5ze-ruL zWR^#6vY381+0pQu?B0T(;j0AjE8rI3Pv*DqHrv?cHqw6~{TI@N@32E%?tu3<(tjiU zH`1j@mm*z?bQz!={_g_rp=|fqs^EJ_-v_?}P>K4`N#%KZN%qrAM?qwty7jCTv{mZVhH!J~>o(1STS&9ov;b}iy_SffwKUqh zwRFke3D8X%Zto!t9N0rD+ZYD>FwkL=y+8J5d4r`9frF)vOCsPq0(dB3q;zk=DEJyH z&22RnI0`sQVjH6oPc-z#gEvuH*=i#2W5AC=HVLvxki~&FUE0=aI?$#rzfPvyPuF!wk(%!?Op*`33w8*V;`2cS+WIgM$9ju z3@=EB_wGV^msHw+m$V7k^2jbJrr&Pxc1uUYcf;>)X<^20lwq$l&At!tvb4;80B}$` zyZeOHV9N=~vH2wQPfDZupG5i%q~Ab&yn*za(o;L$1pTJ;Uih2PErNX!7NiS^`$Ora z-IqasjIwzmErV`IuLs|dh6Q~O z{5{I^gVZ(f2kE(>A3^^J{44OU$m0)bRq!3Db#STlLr^K`GC(=tE_ky1Ll7Qx_bC8X z?iFm7Ee*|b#lxQRaJ#2`G~84EXrmYSUh?3EUUJz+3(^+YSmf5hzR>lBt{-&$pz8-+ zfAIaG>kr)kqywNEAkS*lSiTk9L|(SG39wZj8Qe`?X72{vU5*DVvlH|H-2=EMpcnXq z<=2Cw<(5IwNXI}HD^IhJ1B^$k6Xnv?Gv$;m39{e9MEOt`>{GVPMtY9CvCAB!lc1Ld zm33*^s3whgcyvX|tP=XN2_U2;s@U2=Ke9$EI= zBbPh&fVT&{J@TnNdqM97y%+Re*z8AsFT>vf_AW1U`aEpT!~TN2 zFyn$ec**;Ki*kPc2l7*cF3E<$A0e-g$~$Tty65 zG_z6IMqWLw}L zNdE=@_vCL{-$NevP>1)?7WdH(_mQqd{ssker4rNDprmXuDdl-)#TIB*PVKQM$CLwWCnNvKO6&Bg%6AK9 zDBjsKkhe|wrnL?E+aR-nPDDBpX@WVR=YXDrbQ01@NGHKQRq4Me6M5u-KM(wQ%G%cR zl)N?bk)E&o)^k2$nXkxx^Of(KAnjNH{sPz%UI@GpcoFm#L2nWC7AYf|E<*h*hVEj> z7DI>9OORfI^b+VflyCeTDBE)6y8`qo(5sYLjn*i=f}c`KgPsCjtNakOR>=*1TKOV) zoszKWCFStmS5Q~4D5d>hQ9Qz5QT}@3AbcKFE_XPnytn=!>i3W`&3+hgR9R*}1~?9z z6VN%K{N471(mMDwe4kb-9)1^o-c^o{ziE{_?ptM-*v=r9Wh)7eM5OJ=!TMN`T=qLfOh`@ydRZeK|dn?o6x(d zSi^6ESFB_P;VC)zceL4`h~rQA{}b{*l~Miw1n)NTz75`OrG2A2fWHByfHEaM_^$HN z#`}=pN6hyTPbKWk>U-g4^@a8I0N!eRu#dXTULUv#a8q@-y*cE~)vmcM)t~yc0^LeI z8cw(!`0dm;`n3by4s?6fZ(&FEg*F{w+X=QI;B{87g?9!H1rCM0tNMDYu4?GO?tq8z zz|;f09_mxQdVubsUIbS5g@G3aUKn^`>NQ|xUr+FQg4Ywgp6VaKehYhn?ghG+s_Weg zI=#W`4PI~XdV|*+ar8wT535I>4_Bwz2LT4F-q{gqui%ktY0yaZ@ZQm|8LgT+j8<># z7=v`As&tP;I#O*N9Hm+sMycg_QEHrb6l|i^1r1}=Lx3}YtAL*Yy@F%Gk5yj}9;dbp z8VCIeYFxks&=b|=K@-)bjUI*HN7b{vA5~43$J7H}kEw3~LXjQ^7!2@R7>~H)QT}-N zi$@;u;7tQ>8hFzX%S`ZQf;SVqnc&R?Zx-U11>P+1W}%*DftP@|62MCUF9G$G0A3>E zOaw0xyhPMXB4SHMtjWl0F6v<}V$M+I1{vx@%d-I4pckkO8!S-$mM;S2sU=&NKz9jr zm#FJ}m#RU}+d8G8S{3!jX5d0*Klq|S83Xp$P+R3lU zPXo3C4g=l=1R;-?m0YQ{dPClz1}M)0ZvlQ@9j=^KW%)NI%kN07v0=7U`<|lKi9GP5xeeC%dllS^ROo2oj@zS zT4qht-U`nM8MoqxCBGb#_)9~DMS+z8kDS6q_#>Pa%;D9Tg+)_97Z&xa#yu!S3T=|| zr0H~4W5ElprpuYd9i@DDVp&RYb7$@&DyrtLWyF>F$9BB0;}}y}SQHI!$30o(LFUYp z3^n!R5{o=83jsG<;fRGz6%Dnv#`x+Q253Obo%ISww8&Su98tMq{isSF(XdM7*~c-g za&eCpj>yUqwGy9|$094aYJp=!WdT%QK=1*Kp>CUKwNn5svdX$tfI>lBiT7l8-WGNOW;6+~1F>vB1|ilc%&{gQLt?}_%czpGYf z7*A(*0jEcP;Y0VO2X+xrfvmGux@+bvy&Hk@UXYn$^<66a+GXEm(j4AVnNF)!s?S=p<&p%&4MQprT7WoW)pQ=GKG{ z6sODOg7XDmkfzooJrpXd?=yL2eXcClFMPPqTiLzb(%LzZwdMvcI*@HJY?ZfsufV_4 zun)?bZF4ocI|eOUmk%=I;ZUh~{-Mafqti`YC9P(QEV*yg%6}Uv?ie)hq4#?fJk#}l z?P33%AFT&rb->~j&zB}JtlIa?_-Zvnd_}FlwI1mY8apO7dhDo> z!2@Cq9j$nqJT*-Y?I?AUI(kN?CuWlydg;>e$dFNk#*QAMjv4YujA7{5v4aOr9O6w5 zz=#+=YDf%uP(ucciNQzAAVyzAnk0;jLNA6hs~V3U5)(6EsAfDmHo<0%wx!r+;p!8%MdFhF>5;CoAr?<0q>D8-ir>>!)y{v8V?!1)?GO#S- zb?R)}jCPWhM;AFHI%e#c0i#0j#f~<<3n>c(Q>nc*Z`GDq>#X?91Y0`3w`HaG(L*AA zGroA2e%|JvwLjc^k*dk4&OVjqn{n7T(~38Ot(3~LiZ2$T5p8Ir_+*=ven^&WwZv3N}>d(dDw5&4!#CoXt))% zRCV^}jcn=Z*y*IDr%uO4hiVG7D0)?h?7K+Mwi&p=Sy24Zep1d%IlBUPeyNPj`x_< zYMZiVO(Q9A+YD=Fs&gnzPfbokXURxRP3dj*#1|+v3MErRkcR;DUUF{$b4^EzVZmT9%6q-M=Zux8>FcWaVuW~MbYB?(_Vr64lJ>+c~A zojD^oF-SA05z#ZH5Knwnm0QpV^rYOJ-!Bc~-wEM8R@->Gwt|7qzUAB-TC@1qM`i>% zhqG&|ItSmtK#d1^c|_ar^@-^=t1TCARFhY#g8o(oNDYY|5*au!aYkY~W**d5d=fm; zcUP$$y+~@EVatTfHiIwjYb<;PqXkP!Z%D|PPC@U6&E$K(?($N_`;&}QZ5!dEliGL?R8I+ZXP$r&Senxh?<#mp>}UDA#Mrr-*tO+ zF2p6x|GN&~F>WeDp_V%`%J@zvzbK=OWor8xVo3jY@hipo0fj~Lv5kTKKSavQswq`T z*3|EEy2=ivmNu`$I#jCh3yWq~tIIm{UAfk3o4S?nI19!jueQy1Hzu6k=6ZjLT^ViT zt3M7@Q~rZ1|LIh&wePQ{{JT)&0n`y>wHl~Wzg3b4LnG@jtjRs+*jy$t-c`~{`NKt8 z>Ec!^9NWt1;bL1^<*{vL+$s7c7@Nxq!0h8lE6w^&Ypw$DhCLfyJuj!fN<4O?m0~w} z9FJ2@m-eDRNWoeez#YW@5HI$6>`yL@0Tyhz$p#-qHEU46IK48v8qPL0%A$Br^QpX|WI zRYSr_>;tuZx>9^u+n5&??JUP*Ze`WSP_%cXmbWH#dJ;p3lhEl19o{nJp@vQkwWh*Ta=)bh@_^czHwxg@@B1e6B0g)-d;krA=kD*kJiQs8-ns zRnx)tf@gg&;GZuI()Ou}K#RKTz$Sez9pIwG` zi56QI>K;~DPEbw3Lc`+v4>OkG!-M9MBa({R>t=x+NG9U-f;J5VLp z-5&~z4&&JKIQGZx*@z})jla^dvpn>BXGeMonw7`8-mg3sdY{)=J_=6fvrl3FjS3gVR+xRq$vjWH78hW*rT|=qB@seAa&c&G~t zqbjSRnO~H3pJlr$swW*s-*&DMQ~bt8&Yu&5dpE7p!l8zY`XNFPNAccSwA0d``Qu(L#zWaCE#cj_Ms% zZRo^&;$y-x0hXAFEkBFU<@l$~nQz8)1>Sk#KoaioH%%0j>I1Vvs$ z`3K;n03r54MP(?(0hQ#IWyW&v8SORo@Pg99la#qe7F3PN{=Ro~iH zRYKvL|Me?zazeWW3A+U!>=p_zkci3!HNVORR>A{<&-$fRIK1ZnODJ9o)jn@!h>eC^ z;#K7cW7=(P7;_J%OLU}J?z~8>k}NS-A-Jx#DOZYLMCYVu{Hg24FUH1eVVRUJDkxH8n-(|X>^qaUZe;_=_zZQP1=@m!5t zYa7ko<`<=7t_g#d7Dg?tx_oj=ly-=SY<#sMaOMNoL$nTWThwkH1f($^D4^s0S(S@q zt!HPtMm7=!cwvIaB^DFD@aPvuVpNUN9wwb-8HieT*XaLN76(>XQID?eCl!PG5`pvK zmwT;|i57)Yd`r7!$0qkj34yP0Y%Dv6O&Fh{E!s0%mEFXDtfc>0j~b2c4A7kaT>sAC zoA4tAC*=&St60_e@Z=vDOaJWbAA1+9=p`4_K;8Dpy`^hUMYX^K;UB_Ot2OPD2g1AL zImgbs-r{`)yxD@)3)?GhR)Cs@scYQdalClfJ98=_W7dSiq6xJ-Mgb;!{JJeB_FHvm zXkD@4KPwa;tLu_RboyFrD-~2@y6fFtaDF&)oN0GgxIvnrjUdq#X`&J}hDSoBcr`og zc%f`SiCO^!W!~tnUAwz?LWI>}C6ubH13XjYHvm#B2zAB;5f+3RhBb;*;*nqULfNAT zCl^QYY1OK@ic_2x;dD9epGsfDsdll5=h$=TzX$E_yjcW$o|=09~Tf%MY39iF6Zdor&La ziaTNLHrILM8={PhoW%HzE`L`SENovUG zn4ukF6L2#vE~*paGpzC2@3^y0v)NL_y)ZoCZ3a z(F2B$l5VJ-I(4#I=)?6YNVeJ9-Z~a9cqHPgUbeQyI|ZGk5UE`YFOT6F)=Y{BSL)NW z_gymS6%Ob71^ul}V{9q7_9va3#LNWiJbGCIclAm9wTu2%b#V09NM*p_!Papp^y@6i z(+r#Q<$x+x65{WwldKeXt@wL+48}V-cuU4zxc*jt5x&lo9^u0?ov%;UvAh*e_2vsr zUKzhjPIlfUC%f*F3yZ|vSFOd^IY#)(an_MmCY^PpmeI6rMz)y-J{RSs@e!F+V?@^S zS<5@}{U3HE&RB}Cu>3qd%fjt_tt?#2@;^C-6Kx(UEJ{VZg+(d+GaH|Lbd}_AjsIGf z|FE6=zbh4=1M)FN(rd17dF3NKIthEt3)5`1isfPQ3c$X%4iPTic#-}?-C){wk8^~J z86I83_3p%ybM)%z|5glWYtI<98kxt-KdRQNHvOl@cNZEd(SqEZ+qo_WgqL(@pD1vomldqfEbD^}OI9a3N6u=anH7as zTY}xbc&hkEPp7Havz&Ddzt7KH?Dx((mfqt@`93|ZduRusE0EO+WFy6M8V zC9%91&*53Ova-ah@|bjwubFf^Mvs(S-Cfzdakk-Cb~#^Y=8V-I=nuV7ndzRQKxq8= z9z2ce;@bc9l~Ya2d3(cc>$ugansa6t6*j1_=!mh_{UM#=XR^E-s&RP4_h2!Xh)Bo4EJ1c%b2OlUuC)382+ShSu?`jf zgfMy(>4Tw%L)5pl*RuJ``9~!&r1_w&dNxUwl#gur+Z_()RHjuBk3dVh&N}fPmbMnV z%I+HYrqhd+;?8)ENzk0p{D2_``kyR@xh4-}TqO&)ga2S09;vmh%LnD>9BO>SL9eaM zb`^|baeW7)O1>3Y3W}BW01bZs4vOcSqBLbcOeTd27!}|HD*RGXO2y8Uvw5ER>0F zwvO+MV6Qb9YC^OMb!@(&C@6hZx$;xNY!(PQs4o!Ig2*{vVZV1X@McPH&xN zk9G|^XSnXF*Gf{wq;}vn-2X>s)s~?LY&~8(XC2sW(S}}IXx%-c`fZHSIbY#Xk@u{{ z7QWYa^NX{c%* zD;y&*W4p?D7B_aNtH;Z5j{JC;Z%)7bA~3STR)R&_1!w>3H#xuTRl}8QT`o_2jP4_=M&+C&!~;u7+XuBS zo_Cw8at9@N2&?`wxQjg=JrA)}d(No+WK;L^5_b0!#6x!0SZzulR#-H?+UCC6D9UUH zu{L(x9^I+`5`+*t#|bY&ei0oIc&>CL(+vt|72tihsz<1tshvmR8+hWUL1@0h*bZin zB*x2luABgTh&2dZ4*qML-<7>B_~$s?jeREQuc3DdzkmA&);@G2>~4W3e`Q>+A5$gG zpGj&EnhU-KnB-Q8@|(aq2ze-QF6{dVy>O|)8pf994gvofVx0(_26;NK!tTY-;2 z@vFfp-dxsA*2>dUZouQh(@Q8rc^WazznPKW+#GMzPbA{RUk?ghF5yW^@Y{pNn=7od zpofCq4LVlP6F~=po&|sT$TwH;R|>rig5C`J8vO1R^a;>$usg-+*0E>M4wSzir#mcb zgZ2o7zaG$=0Ne-iG{ij)G}Zf~T&}XIf}SDdd4jfcxq&SgbRjU6V;68J?2Dj(9=`zl z4A=8u7lhu2;Kw1KtAhRtbU5hmcwG6p0Vt;t_792r8_f9+We4d8J;EBFV%r}z&G`ZGbJKcoG|`}`pI zf#_GH*O>R4@je|np5QZv+jHbnZ1N zjJMAZoSv8aH^&Qd?+SSZi2>p}B*#VWx(;@bVz$XQM zi{nV24^(qxTlo7z)%wM^sy0r)R~uYn_rTY5m5iBmapOFG1JW zk-zq=fuI}dFpr=en{j>!3k9G0-$UT%W8Mho_WAa)f*;HETCs`3ehT#B(B3nJUWU-i z6?%(=-cq5rlItzaUCnXO(Dedug**ZEvPVbdYRp~{{$3aUiiE#+gunA#o@lu!=*wK* zo?R96SMW#W`cC*M6MibV-Z-Y{Mg0J`MZR9ZJ%I!DRA0Bf+UXmFeg--O{DUZ858z9{ zIIZG1g6l(iKH>~iU#p_$2!4j(=L&2GJ`cThf__%edjenFU`NsNdEJ4J&c;XE2pz^20%`FBZXch=PTK>j9R-T0n@xa7jlYs zp3ut^cFzfVn~~}zlf4R>+UFQB=@$w4J6yhmeJA8U3i)qB{wJ5OV5&*8HvyBq4=~kF zfQkICVr_)HqmXwO@?OB~dd{j95yhY5KE=fBEg zh2BID-tP9;>O<$oFGo({_*IPSP?q*sH`QmnUQy{KG6q&U)ty$$?fsL$EJwEs;7rgb@! z>m^Hzh2ApoK^NXZ)g8!`GZ{_^X@*crIAozztQ#sBEe3i$OpZgtX8h;gDjK-^E zuuxq2a(#;yR|8<0N16iDJkruayuq3rnmX~%ZKFXexb^DlTD)%0_YgHQXkw}kwx;9mkw?ejUOOLM*vdOr!h zUj+Y-(5vL-*&^dF7V&y+Ur*c5_6JSvHn<*@cbhz1&|~UR`M$`S2)zlY|9HWl$@O;0 za|E5n^_1)dLeDPv%emfuxlqt+x!w!eJ1Jl6V-5)YV?utC>%StO7W5gepPO?D^l_B) z6S6}b-wOHnWRLbQu7?4H_;1zI_N(RKp9jCWx7N?QcvHC!$%8;s{~88N<&6>YY2H-M ze0!FV&*%EB*kYl#OyJd=e?(p<=x2ecpKk@Gc6iwv&kxA=5cijx^BVXR_Zys^;B$@R z@jf>>?y$_;M{D^uS_tEyl`GS5NbRg{3_=JTn zhyEeXKNS0hpf3aGga4ht`FV&}d zOk?|?NA-75$p0ne9|-;xq4$}fzZQCTK&Qb@@zv~&z;U1(08{>BWze@5^(0h7Nyz~t|3VDk5c;Q!l~>Ti4YU$EZ>xxr7<5AX});m1^+8x^79)o`N7|g;&h-t`Y*uo@HUe*i-WGo|vx43anx1P<_-pNaUeI6pQ=Fwa zm7vL94bbQg0U8}DXdCF=kk1$NV$d5wuNCwLLB9-4;9}1-WC-}S(NacD{J_mg&=lhV; z`tuQ&kN5eM%YT;d3%MMm$qhkTe)WU2a`X{&xS&Uaru?HhU7GWVpeJ#9yiYvG9hTXJ z-Buxg88`uU_>Kv;KZE=z-U~wiQV_-4Sos!miuZfSX?`pRP3=-CX#a*9-LRo14;A!7 zz*JA8fT>@Nhn(hx$qmVGM`fDOn+1Lx{H6*z6ExM!JkV6GWuPgp6%DEUzuDJt++o>H z?k7Y!4LyqQjIg`VkmkL{>=M@t8u}UdRL<+1UYc7X@V^^|@pGgvSL7oFQ+)ju z&tT23PcZVwdeSIZ^V>R@;s_cV0zUce$?2uJ0|Xuttoa>Ac8EKY`BWY1)T{yE0v$?b%ex6aL2tU)Ie-ru%Trc0AA^5pm zuN7M);#tb&iIyh>{UnzsDNhM{J(rIPd%jWgP&6pp$>ZwJ_HzDh`$3LphP}>lLfD(I z3x(ck5tvuIMMQ_uq)+uNy>d;CpSsv=f#F5R8P^9J)3Cp`8T2Z zQPhT6(d8v&Z?Z!DK5T4Dt~k;{{m zDT1Ef1kVf5OW=ANCns~fY4Ti-|FCCrym@jC$E%|Ap}!mb<8e-JoxBo$;$Z)D6YczE zD{va<7r6YL$-6l|GkHJ9=O!QI_+OKcas1xoH#xpI`7Ms4C%@MuC$uN*zu@%p^cw>I zg!+mE|7RY*x2iPN%4=+@^#`w}RFAjp4Vs$qcWN=8HKlrNueK6;?S)=vu6HE%A?US* z-ospPkQyQMMhd-1t~bwXir`P@bfP5zG}UV|a2)VLAur^9l9aVVz5#xgV?Eg1l=|sl zwuj3nsYiwW3CL;QJtOFwT%N7|D(wFNMuC`Y)$%h~HGiIkq*G!8ys2P>B z6>9>T;%mX>iI%p4?!@Ku)vkgLYo^sxUtr2-2$wHbBZa?l!v0aAKb6Zjsxt(g2s@fz zQV>rd^2=$a&F2faUC>ZFqmp_k$b2=+$n2@9G_CRoIsb`F&w8<9>$9Z{YVei55>m`{2H&CvF=9 z1RX5ot;Ky#2QHtML z^XcE*ZeXmA-_L}{nsHx4^N%;~XL{oH5Puz-x0e-sYL`}^Y5(6@==bM%VC*1Wdwy>) z4RU&pTnbF{#FM}@uWZz5=WE-!-wkX(_!H0$uL9Hg8r?6^`C1V$*?$hqkl&xk_ZDc} z7qM{YH`j;p^R`a>e&(U0VaMs;56V+;5gv^xR2<`-ecp1-eW>N6S=Xa5hk)QX!m~9c* z59j-&*Migg&Fux<3-mmzwR4Hx!v1CM?-n~G=+}h)+Z=BV_(14?BII9i{XcMTq2>R*(Em5b+XC(ief%YR z9-jd?4sizXdx6ZHV2*bLv;m*W)eH9uJ=ty6Pv{R4dSis%qqt|FbCh@?pDFxh33~^( zzrzZIe2tJl&+SWdUI9(*einYPX0i7;KR4$Kfxm^E`v3R9)c;Ea{}yO|UdHcRBA9B~ zz}FpLeh;wRyQ8>==z@EIo~)D&qI&_9XBhajkB{McyM5xgypfb7RETLc9T-&dmuH*ecHPTLDvjcNP3F&{W?8aWBx5^_5~k)A*jC z$#bWAYwxAZ5cF(;Q^1ddUIw=tAmt0Y$A$b!VfU1vHwgTku-gXxgNWl5V2bCwCeOJD zIu7(@PM79f74%m^|5u@}$9)0m`T9`YLnJF`>IbcSv~|5b=g*YF1i!D~58(F-^Snk0 zeiWw@E#pDcxPFY=b!Ksbw!x0}E3>)YS&s~k&wJ$XdyfdVi0dzuRtSHqpilkqS&`3f z!GBrgb4d7oP2}^2px>f=&<(0Iude@*A2fdrXRDZv6{h*=uK_`G_ c^|j{>lfYi}wf%)R?k&i_Kj&ZYXjuRM0Q7sq{{R30 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/OVRUMB.DOC b/SOURCE/UNUSED/OVRUMB.DOC new file mode 100644 index 0000000..f4c4b25 --- /dev/null +++ b/SOURCE/UNUSED/OVRUMB.DOC @@ -0,0 +1,220 @@ + OvrUMB version 1.2 + by Jean-Marc Lasgouttes + + + + +Overview + + +The purpose of this unit for Turbo Pascal 6/7 is to allow your programs +that use overlays to free more conventional memory. This is made possible +by the relocation of the overlay buffer in upper memory on systems that +support that kind of memory. + +This unit should be compatible with the use of OvrInitEMS, OvrInitXMS (from +the unit OverXMS - overxms.zip at garbo.uwasa.fi) or the procedures from the +Streams unit (streams15.zip by Duncan Murdoch). The purpose of all these +procedures is to speed up the overlay reading by keeping the overlay file in +EMS or XMS memory. It is recommended to use OvrInitEMS/XMS or the streams +unit in conjunction with OvrUMB. + +This unit is released to the Public Domain. Feel free to use it in your +applications and distribute it, as long as this documentation is included. +You can distribute a modified version of it, as long as credit is given to me +as the original author; in this case, I would appreciate to get a copy of +your modifications. Although this unit has been tested on several systems, +there is no warranty that it will work for your application and I should +not be liable of any damage that it may cause. However, I would be glad +to try to correct any problem that you may encounter (see my address at the +end of this document). + + + +Why you should use OvrUMB + + +If you use overlays in your applications, you are probably aware that +all the free memory that you can get will be welcome. One way to gain +memory is to use the upper memory which is accessible for real-mode +programs on a wide range of systems (most 80386/486/... and some +8086/286). With this unit, your applications will make use of upper +memory if it is available, with a slight modification of your code. + +The idea of this unit is very simple: Borland Pascal overlay manager +uses a part of the heap as a buffer where it loads the overlaid code +that needs to be executed. OvrMovBufToUMB tries to allocate a buffer +of at least the same size in upper memory and to set the variables of +the overlay manager to point to this new buffer. The old block can +then be disposed of and is added to the heap. The gains in memory will +be equal to the size of the biggest overlaid unit (20-30k in my case) +if you use the default buffer. But I find it more efficient to +overlay as many units as possible and to declare a buffer of 60-80k +with OvrSetBuf. This will free more memory and the slowdown will be +hardly noticeable. In this case, OvrUMB will free even more +conventional memory (as long as there is a 60-80k contiguous upper +memory block on the host computer). + +There are other means to use upper memory in your Turbo Pascal +applications; one of them is the unit UMB_Heap published in PC +Magazine (vol. 11 no. 20). This unit will map the existing upper +memory blocks in the regular Turbo Pascal heap. Although this is the +most transparent way to use upper memory, this unit has some +shortcomings: + + - a program using this unit could have big problems when trying to + execute child DOS processes, since Turbo Pascal does not expect its + memory to be allocated as several DOS memory blocks; + - the unit itself has some bugs concerning the restoration of the DOS + memory allocation strategy and tests for the presence of an XMS driver, + which cannot be installed on a 8086 based computer. + + + +System Requirements + + + - TP6 or TP7/BP7 + - A program that uses overlays... + - Some free UMBs in the system on which your program is to be executed. + Note that your program will work without UMB, except that no memory + will be gained. Since the overhead of the unit is about 320 bytes, + decrease in available memory will hardly noticeable. + + + +Contents + + +The complete package contains: + + - ovrumb.doc This file + + - ovrumb.pas The main unit source + + - ovrtest.pas A test program that demonstrates the use of the + ovr1.pas OvrUMB unit. + ovr2.pas + + + +How to use this unit in your programs + + +This is very easy : the modifications must be done in the main program +or in the initialization part of a unit that is declared before any +overlaid unit. + + - Add "OvrUMB" in your uses statement; + - Instead of code like + + ... + OvrInit('MYPROG.OVR'); {Opens the overlay files} + OvrSetBuf(MyBufSize); {Sets the overlay buffer size to MyBufSize, + since the default value is often too small} + ... + + use: + + ... + OvrInit('MYPROG.OVR'); {Opens the overlay files} + OvrSetBuf(MyBufSize); {Sets the overlay buffer size to MyBufSize, + since the default value is often too small} + OvrMovBufToUMB; {Tries to move the overlay buffer in upper + memory. It this is not possible, + nothing happens} + ... + + - That's all : OvrUMB will automatically free the UMB on exit. + + +You can also use the procedure OvrSetBufUMB(Size:longint) that allows +you to specify the size of the wanted buffer. This function can be +useful if you want to change the buffer size when it is in upper +memory. + +In order to help you to select the best block size, OvrUMB provides +the function umb_MaxAvail which returns the size of the biggest upper +memory block as a longint. + +In fact, OvrMovBufToUMB is logically equivalent to: + + if umb_MaxAvail>OvrGetBuf then OvrSetBufUMB(umb_MaxAvail); + +But of course it is more efficient and generate less code. + +These two procedure will do nothing if they detect any problem and +return an error value in OvrResult. I have tried to map the error +conditions to existing error codes. + +The procedures return ovrError when: + - the overlay file has not be opened (use OvrInit to open it) + - there are some overlays loaded (use OvrClearBuf to unload them) + - the heap is not empty + - the buffer has already been reallocated somewhere + - you tried to allocate a buffer smaller than the minimum allowed + (only with OvrSetBufUMB). + +The procedures return ovrNoMemory when: + - There is no upper memory manager running + - There is no big enough upper memory block to contain the overlay + buffer. + + + +Acknowledgments + + +I would like to thank the testers without whom I could not have +written this unit, since I have no upper memory dispenser on my 286 :-( +In particular, my thanks go to Mike McWhinney (elja.inc@mixcom.com), +Herbert Zarb (hzarb@unimt.mt) and Jack Nomssi +(Nomssi@Physik.TU-Chemnitz.DE). + + + +Revision history + + + version 1.0 (27/10/93) + First public version. + version 1.1 (21/07/94) + Added function umb_MaxAvail; + OvrMovBufToUMB now tries to allocate the biggest possible block. + version 1.2 (15/09/94) + Fixed bug that could make program fail in some cases where there + are no UMB available. + Changed the compilation directives of the test program so that + they compile on Timo Salmi's PC :-) + + + +Known Bugs and limitations + + + - The system will crash if you try to call OvrSetBuf after reallocating + the overlay buffer in upper memory (however, I don't know why you + would want to do that...) + - There might be a compatibility problem with ExecWithSwap (from + TurboPower Software) + +If you use this unit (or even if you don't like it), please send me a +message at the address below. Any feedback that I can get is welcome. + + + +Contacting me + + +Report bugs and send comments and suggestions to: + + Jean-Marc Lasgouttes + + e-mail Jean-Marc.Lasgouttes@inria.fr + + tel. (33) 1 39 63 56 40 + + postal address + 118, rue Marcadet + 75018 Paris + FRANCE diff --git a/SOURCE/UNUSED/OVRUMB.PAS b/SOURCE/UNUSED/OVRUMB.PAS new file mode 100644 index 0000000..90a2ba9 --- /dev/null +++ b/SOURCE/UNUSED/OVRUMB.PAS @@ -0,0 +1,224 @@ +unit OvrUMB; + + { Unit OvrUMB : Uses an upper memory block as overlay buffer } + { } + { Version 1.2 (15/09/94) } + { } + { Author : Jean-Marc Lasgouttes } + { } + { e-mail : Jean-Marc.Lasgouttes@inria.fr } + + +{$A+,F-,O-,S-} + + +interface + + uses Overlay; + + Procedure OvrSetBufUMB(Size:longint); + {Frees the current overlay buffer (which must be before the heap), + allocates a new buffer of Size bytes in upper memory and sets the + overlay manager to use this buffer. This is only possible if the + heap is empty and no overlays are currently loaded. This procedure + must not be used if the buffer has been already reallocated + somewhere + + #OvrMovBufToUMB# is an automatic version of this procedure that generate + more efficient code.} + + Procedure OvrMovBufToUMB; + {Same procedure as #OvrSetBufUMB#, except that the size of the UMB buffer + is the biggest available upper memory block. No rellocation occurs if + the biggest block is smaller than the current overlay buffer. This is the + most convenient procedure to use.} + + Function UMB_MaxAvail:longint; + {Returns the size of the biggest available upper memory block} + +implementation + + const OvrUMBSeg:word=0; {The Segment of the overlay buffer} + + var OldExitProc:Pointer; {The old ExitProc (surprise!)} + SaveMemStrat, {Temporary variables to save system state} + SaveUMBLink:word; + + Function ChangeMemStrat:boolean; assembler; + {Save the current memory allocation strategy and change it in order + to allocate upper memory} + asm + MOV AX, 5800h {Save memory allocation strategy} + INT 21h + MOV SaveMemStrat, AX + MOV AX, 5802h {Save UMB Link state} + INT 21h + MOV SaveUMBLink, AX + JC @@1 {If this function is not recognized} + { then DOS version <5 : Error} + MOV AX, 5801h {Set memory allocation strategy to} + MOV BX, 40h { use only upper memory} + INT 21h + MOV AX, 5803h {Add UMB to DOS memory chain} + MOV BX, 1 + INT 21h + JNC @@2 {Error: no UMB provider} +@@1:MOV AX, false {Return an error} + JMP @@3 +@@2:MOV AX, true {Return success} +@@3: + end; + + Procedure ResetMemStrat; assembler; + {Restore the memory allocation strategy as it was before the call to + ChangeMemStrat} + asm + MOV AX, 5801h {Reset the memory allocation strategy} + MOV BX, SaveMemStrat + INT 21h + MOV AX, 5803h {Reset the UMB link state} + MOV BX, SaveUMBLink + INT 21h + end; + + Procedure ReleaseUMB(UMBSeg:word); assembler; + {Releases the block corresponding to UMBSeg if UMBSeg<>0} + asm + MOV AX, UMBSeg {If the segment is zero, do nothing} + CMP AX, 0 + JZ @@1 + MOV AX, 5802h {Save UMB Link state} + INT 21h + MOV SaveUMBLink, AX + MOV AX, 5803h + MOV BX, 0 {Remove UMB from DOS memory chain} + INT 21h + MOV AH, 49h {Free block used by UMBSeg} + MOV ES, UMBSeg + INT 21h + MOV AX, 5803h {Reset UMB link state} + MOV BX, SaveUMBLink + INT 21h +@@1: + end; + + Procedure PrimSetBufUMB(Size:word); assembler; + {The basic procedure called by OvrSetBufUMB and OvrMovBufToUMB. Size + is given in paragraphs.} + asm + XOR AX, AX {Check for errors: } + CMP AX, OvrDOSHandle { Is the Overlay file opened?} + JZ @@3 + CMP AX, OvrLoadList { Are there some Overlays loaded?} + JNZ @@3 + MOV AX, OvrHeapEnd { Is the buffer already rellocated?} + CMP AX, WORD PTR HeapOrg+2 + JNZ @@3 + CMP AX, WORD PTR HeapPtr+2 { Is there something in the heap?} + JNZ @@3 + MOV AH, 48h {Allocate UMBSize segments of memory} + MOV BX, Size + INT 21h + JNC @@1 + MOV AX, ovrNoMemory {Not enough UMB} + JMP @@2 +@@1:MOV OvrUMBSeg, AX {Keep the segment in OvrUMBSeg} + MOV AX, OvrHeapOrg + MOV WORD PTR HeapOrg+2, AX {Seg(HeapOrg):=OvrHeapOrg} + MOV WORD PTR HeapPtr+2, AX {Seg(HeapPtr):=OvrHeapOrg} + MOV WORD PTR FreeList+2, AX {Seg(FreeList):=OvrHeapOrg} + XOR AX, AX + MOV WORD PTR HeapOrg, AX {Ofs(HeapOrg):=0} + MOV WORD PTR HeapPtr, AX {Ofs(HeapPtr):=0} + MOV WORD PTR FreeList, AX {Ofs(FreeList):=0} + MOV AX, OvrUMBSeg + MOV OvrHeapOrg, AX {OvrHeapOrg:=OvrUMBSeg } + MOV OvrHeapPtr, AX {OvrHeapPtr:=OvrUMBSeg } + ADD AX, Size + MOV OvrHeapEnd, AX {OvrHeapEnd:=OvrUMBSeg+Size} + MOV AX, ovrOK {Success} + JMP @@2 +@@3:MOV AX, ovrError +@@2:MOV OvrResult, AX {Put the result in OvrResult} + end; + + Function UMB_MaxAvail:longint; assembler; + asm + CALL ChangeMemStrat {Allow the use of upper memory} + CMP AX, false + JZ @@1 {if it not possible, return 0} + MOV AH, 48h {Try to allocate too much memory} + MOV BX, 0FFFFh + INT 21h {BX contains the size of the biggest} + MOV AX, BX { available block} + XOR DX, DX + SHL AX, 1 {Multiply by 16 and put the result} + RCL DX, 1 { in DX:AX} + SHL AX, 1 + RCL DX, 1 + SHL AX, 1 + RCL DX, 1 + SHL AX, 1 + RCL DX, 1 + JMP @@2 +@@1:XOR AX, AX + XOR DX, DX +@@2:PUSH AX + PUSH DX + CALL ResetMemStrat {Reset the memory allocation strategy} + POP DX + POP AX + end; + + Procedure OvrSetBufUMB(Size:longint); assembler; + asm + CALL ChangeMemStrat {Allow the use of upper memory} + CMP AX, false + JZ @@1 {If it is impossible, abort} + MOV AX, WORD PTR Size {Transform Size} + MOV DX, WORD PTR Size+2 { into a number of paragraphs} + MOV CL, 04h + SHR AX, CL + ROR DX, CL + AND DX, 0F000h + OR AX, DX { the result is in AX} + CMP AX, OvrHeapSize {If AX < OvrHeapSize --> Error} + JB @@1 + PUSH AX + CALL PrimSetBufUMB {Actually allocate and set the buffer} + JMP @@2 +@@1:MOV AX, ovrError {Report an Error} + MOV OvrResult, AX +@@2:CALL ResetMemStrat + end; + + Procedure OvrMovBufToUMB; assembler; + asm + CALL ChangeMemStrat {Allow the use of upper memory} + CMP AX, false + JZ @@1 {If it is impossible, abort} + MOV AH, 48h {Try to allocate too much memory} + MOV BX, 0FFFFh + INT 21h {BX contains the size of the biggest} + { available upper memory block} + MOV AX, OvrHeapEnd {Compute the size of the} + SUB AX, OvrHeapOrg { current Overlay buffer} + CMP AX, BX {Is the UMB bigger than the current buffer?} + JNB @@1 {If not, abort} + PUSH BX + CALL PrimSetBufUMB {Actually allocate and set the buffer} + JMP @@2 +@@1:MOV OvrResult, OvrNoMemory +@@2:CALL ResetMemStrat + end; + + Procedure OvrUMBExitProc; far; + begin + ExitProc:=OldExitProc; {Chain to the old exit handler} + ReleaseUMB(OvrUMBSeg); {Release the overlay buffer} + end; + +begin + OldExitProc:=ExitProc; + ExitProc:=@OvrUMBExitProc; {Release the UMB on exit} +end. diff --git a/SOURCE/UNUSED/OVRUMB.TPU b/SOURCE/UNUSED/OVRUMB.TPU new file mode 100644 index 0000000000000000000000000000000000000000..25bca065cabf239c16613023b2100cd198cb6cc7 GIT binary patch literal 2704 zcma)8U2IfE6#ni{Z*NOmfdXwv!7Zr*(gJHzL{U?UG;N^SzZM%~l@%6T+(NUvZTJb; z22jgJ0@w!=ebAVQK2Sybu!xbyB1W(YP!oQPfQ>|wzW72+Ovw73xp%iMVsy4M-h4LJ-Lc0>lNC!}ORu+Vn@9U1l zW8q!EQ?0;VSqm1?G89SHcWt44uWd8%Ap@|A&D<6=1houwl1oT#-qB5R%MPJqI!VXx zql;azi0YS{!#h`ZhoiAxlyj|T5>FfgPU&jt891OuktUbUms=eZ6>8}N7(nlH9_?apY@AK$UbQD6YF>p)Q`+#P9- zbcB-ea1u_PvPPm}>g%K1UxTI098Iuf&8y+7(TQ*uhau>1+6BjWC_v-Q(b?)BuM4@j(keM&_ zua;oAB?I>WJdW9bp&R_uA)}#FGWb2&8rj$J{eofY{L|!uv~X<$W|Au=G76YFO!+cV zYGbIPN0UD;o1%7z$~z6D(NG=mqvRiBk`h{olbfa)nx@HzJVDj~W;rp1C4My(U3nR% z{w(+8dXepl+A=h`l2@p`%KK!L8N zu?Fwc$7Q1)+wz~|yoEiA0ed_8?N02m9qXoT`_ftMV`5<*~ z;uZTX@(oIqH5SZv?S|YwS1JZ!*6bSgY+pftJEt?QMLl9VUK5 zJi|Up-6(UdWv(lU%|t)*e4h9sF-+Xde0Q=gd)eQh+{c={!7I~kC%Yu$%{66)3X z^k8G^CE76Nz0A0m`=Xws^XDDPiMeH?!Q`T|!%T*vM7aaVj^+(Ep3Y=OD*LW_FJHQK zX-XeAy+hv1{vfF@v|Zq~T$}l+1}n9}K535L89m=ShCd1}%Fg1JpM-HMtzuAYKW}Ek zl)GWLrzNC5c{O2$6#0A3?qw*7e`-^6R3?3d%nFEk`#&{I<*OX6{Q|GVlvZ{GyfYRA zEtDuUkvC;-@r*h8g}_C53iB0~pjcs%+)=L2;ZJZbDo{pLPZ81PbL8mxG%7tGPvQcs zQaB5B3d^xZp$84FeUqBo{2xpBh43jXLMx_m4s1jjJVcGSh*<5;`Fv2X<6+Jj3y-+` z8ke`+* literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/PCBOAR~1.TXT b/SOURCE/UNUSED/PCBOAR~1.TXT new file mode 100644 index 0000000..2289eae --- /dev/null +++ b/SOURCE/UNUSED/PCBOAR~1.TXT @@ -0,0 +1,57 @@ +FeatherNet PRO! v1.01 Documentation +Page 44.15 + +This is the exit to DOS information FeatherNet PRO! uses to maintain a caller's stats and the system's configuration upon exit to DOS when running a DOOR, during file transfers, or viewing some archives + +START POS SAVED +& LENGTH AS DESCRIPTION OF DATA +--------- ------ -------------------------------------------- +1, 2 ASCII "-1" always used by FeatherNet PRO! +3, 2 ASCII " 0" always used By FeatherNet PRO! +5, 2 ASCII "-1" if page allowed or 0 if not. +7, 2 ASCII User Number in Users file +9, 1 ASCII "Y" if Expert or "N"if Not +10, 2 ASCII "-1" if Error Correcting modem, "0" if not +12, 1 ASCII "Y" if Graphics Mode or "N" if Not +13, 1 ASCII "A" is always placed here by FeatherNet PRO! +14, 5 ASCII The DTE speed or PC to Modem baud rate +19, 5 ASCII The connect baud rate:"300-38400" or "Local" +24, 2 MKI$ User's Record # in "USERS" file +26, 15 ASCII User's FIRST Name padded with spaces +41, 12 ASCII User's Password +53, 2 MKI$ Time user logged on in Mins: (60 x Hr)+Mins +55, 2 MKI$ User's Time on today in minutes +57, 5 ASCII Time user logged on in HH:MM format. Ex: "12:30" +62, 2 MKI$ Time user allowed today in minutes +64, 2 ASCII Daily D/L Limit from pwrd file +66, 1 Chr$ Conference the user has last joined +67, 5 Bitmap Areas user has been in +72, 5 Bitmap Areas user has scanned +77, 2 MKI$i An mki$(0) used by FeatherNet PRO! +79, 2 MKI$ Currently a value of 0 is here (MKI$(0)) +81, 4 ASCII 4 Spaces are placed here +85, 25 ASCII User's Full name placed here. +110, 2 MKI$ Number of minutes user has left today +112, 1 chr$ Node user is on (actual character) +113, 5 ASCII Scheduled EVENT time +118, 2 ASCII A "-1" if EVENT is active or a " 0" +120, 2 ASCII " 0" is Placed here by FeatherNet PRO! +122, 4 MKS$ Time of day in secs format when user is on +126, 1 ASCII The Com port this node uses (0 - 8) +127, 2 ASCII Flag to let FNET PRO! know type of file xfer +129, 1 CHAR Ansi Detected Flag - Char[0] or Char[1] +130, 13 ASCII Unused by FeatherNet PRO! - SPACE filled +143, 2 MKI$ Last Area User was in (0 - 32766 possible) +145 BITMAP Not Currently Used by FeatherNet PRO! + + +-------------------------------------------------------------------------------- +Some BASIC functions: +CHR$ +Writes a character (8 bit value). One byte. +MKI$ +Writes a short integer (16 bit value). Low byte then high byte. +MKS$ +I didn't want to research this, and am writing four zeroes. Anyone know? + +-------------------------------------------------------------------------------- diff --git a/SOURCE/UNUSED/PKUNZIP.EXE b/SOURCE/UNUSED/PKUNZIP.EXE new file mode 100644 index 0000000000000000000000000000000000000000..3efd9f374772429ecb9ed36eb7ad5f28bea6d9f0 GIT binary patch literal 34583 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/PKZIP.EXE b/SOURCE/UNUSED/PKZIP.EXE new file mode 100644 index 0000000000000000000000000000000000000000..120625075c638b0cc3d5dab59d676eb067faa2c3 GIT binary patch literal 42166 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 Gxc(0_3m^Xg literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/PRHELP.ASC b/SOURCE/UNUSED/PRHELP.ASC new file mode 100644 index 0000000..116168a --- /dev/null +++ b/SOURCE/UNUSED/PRHELP.ASC @@ -0,0 +1,14 @@ +|08 +^1Press ^3ENTER ^1to get a blank line and press ^3/ +^1and one of the following command keys. + + ^1(^3^1)Continue message + ^1(^3A^1)bort message ^1(^3C^1)lear message + ^1(^3D^1)elete line ^1(^3F^1)ile attach + ^1(^3I^1)nsert line ^1(^3L^1)ist message + ^1(^3M^1)CI codes ^1(^3O^1)Color help + ^1(^3P^1)Replace string ^1(^3Q^1)uote message + ^1(^3R^1)Delete last line ^1(^3S^1)ave message + ^1(^3T^1)itle change ^1(^3U^1)pload message + ^1(^3Z^1)Replace line +|08^1 diff --git a/SOURCE/UNUSED/RENEGADE.DAT b/SOURCE/UNUSED/RENEGADE.DAT new file mode 100644 index 0000000000000000000000000000000000000000..54f307ca18180939d294254b9a9a0a1906eacc32 GIT binary patch literal 11392 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 z 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RENEGADE.LNG b/SOURCE/UNUSED/RENEGADE.LNG new file mode 100644 index 0000000..829e9ae --- /dev/null +++ b/SOURCE/UNUSED/RENEGADE.LNG @@ -0,0 +1,283 @@ +$Anonymous_String +^4[^0 Anonymous ^4] +$ + +$Echo_Char_For_Passwords + +$ + +$Engage_Chat +%LF^0Your SysOp, ^5%SN^0, Is Here To Chat With You!%LF%LF +$ + +$End_Chat +%LF^0Welcome Back To ^9%BN. +$ + +$SysOp_Working +^4[^0 Please Wait ^4]@ +$ + +$Pause +^4[^0 Press any key ^4]@ +$ + +$Enter_Message_Line_One +%LF|03Press |11ENTER |03to get a |11BLANK LINE |03and press the following: +$ + +$Enter_Message_Line_Two +|03To Save: |11/S |03To Quote: |11/Q |03To Abort: |11/A |03Help: |11/? +$ + +$NewScan_Begin +%CL|09Scanning ... |01[|11%MB |01- |11%HM|01]@ +$ + +$NewScan_Done +@ +$ + +$Auto_Message_Title +^9AutoMessage Posted Here By: ^3 +$ + +$Auto_Message_Border_Characters + +$ + +$SysOp_Shelling_To_DOS +|09[|15 Please Wait |09]@ +$ + +$Read_Mail +|09Read Mail (|14?|09=|14Help|09): @ +$ + +$Paging_SysOp +^9I will now attempt to call ^0%SN ^9to his computer! +$ + +$Chat_Call +|09[|11(|15<|14*|15>|11)|09] @ +$ + + +$Bulletin_Prompt +^4Time Left [^3%TL^4] (^3?^4=^3Help^4) %LFBulletin Menu^2: @ +$ + +$Protocol_Prompt +%DFPROTLIST%^4Selection^2: @ +$ + +$List_Files +|03List Files - |11P |03to Pause +$ + +$Search_For_New_Files +|03Search for new files - +$ + +$Search_All_Dirs_For_File_Mask +|03Search All Directories For a File Name|01: |11 +$ + +$Search_For_Descriptions +|03Enter a Description to Search For|01: |01[|11No Wildcards!|01]|01: |11 +$ + +$Enter_The_String_To_Search_For +|03Press |01[|11ENTER|01] |03to abort.%LF|11 +$ + +$Download +^3Download - From File Area %FB. +$ + +$Upload +^3Upload - To File Area %FB^3. +$ + +$View_Interior_Files +%LF^9Enter the name of the archive(s) you would like to view: +%LF^4File name:^3 @ +$ + +$Insufficient_File_Credits +^5You have insufficient file points to download this. +$ + +$Ratio_Is_Unbalanced +^5Your upload/download ratio is too poor to download this. +$ + +$All_Files + +$ + +$File_Mask +|03Press |01[|11ENTER|01] |03For |11ALL |03Files |01: |11@ +$ + +$File_Added_To_Batch_Queue +^5File added to Batch Queue +$ + +$Batch_Download_Flagging +^9Enter filename(s) for addition to the batch queue. +$ + +$Read_Question_Prompt +^4[^5%MB^4]%LFBegin reading at [^51^4-^5%HM^4] (^5Q^4=^5Quit^4): @ +$ + +$System_Password_Prompt +%LF|03SysOp Password|01: |11@ +$ + +$Default_Message_To +|03Press |01[|11ENTER|01] |03for |11ALL|03:%LF +$ + +$Newscan_All +|01[= |11Global NewScan Beginning |01=] +$ + +$Newscan_Done +%CL|01[= |11Global NewScan Completed |01=] +$ + +$Chat_Reason +^9%UN^0, State your reason for a Chat Session. +$ + +$User_Defined_Question_One +Is ALL of your information REAL & CORRECT? (Yes/No) +$ + +$User_Defined_Question_Two +Do you run a Telnet BBS? (If so, type in address below) +$ + +$User_Defined_Question_Three +What BBS or Web Site did you hear about this BBS? (Specific Please) +$ + +$User_Defined_Question_Editor_One +Info Real +$ + +$User_Defined_Question_Editor_Two +Telnet BBS +$ + +$User_Defined_Question_Editor_Three +Reference +$ + +$Continue_Prompt +|10 |15Continue: [^5Y^0]es, [N]o, [C]ontinuous: @ +$ + +$Invisible_Login +Invisible Login: @ +$ + +$Cant_Email +|11Can't send mail to that user. +$ + +$Send_Email +%CL|03Press |01[|11ENTER|01] |03to |11ABORT|03: +$ + +$Sending_Mass_Mail_To +|01Sending Mail-Mass to: +$ + +$Sending_Mass_Mail_To_All_Users +|01Sending mass-mail to ALL USERS. +$ + +$No_Netmail +|01You are not allowed to send netmail. +$ + +$Netmail_Prompt +%LF|09Is this to be a netmail message? @ +$ + +$No_Mail_Waiting +%LF^5You have no mail waiting. +$ + +$Must_Read_Message +Sorry, you must read and reply to (or delete) your mail. +$ + +$Scan_For_New_Files + |11S|03can |11F|03or |11NEW |11F|03iles |11S|03ince |11MM|03/|11DD|03/|11YYYY|03: @ +$ + +$New_Scan_Char_File + +$ + +$Bulletins_Prompt +^5There are new bulletins read them: @ +$ + +$Quick_Logon +Quick Logon: @ +$ + +$Message_Area_Select_Header +%CL7Ŀ +78 Num 79 Name 78 Num 79 Name 7 +7 +$ + + +$File_Area_Select_Header +%CL-Ŀ +-. Num -/ Name -. Num -/ Name - +- +$ + +$Receive_Email_Header +%CLĿ + Num  Date/Time  Sender  Subject  + +$ + +$Vote_List_Topics_Header +%CL|03Ŀ +|11|17 Num |03|16|11|17Votes|03|16|11|17 Choice |03|16 + +$ + +$Vote_Topic_Result_Header +|03Ŀ +|11|17 N |03|16|11|17 % |03|16|11|17 Choice |03|16 + +$ + +$File_Area_Name_Header_No_Ratio +%CL Ŀ +  ##  File Name   Size   Description %FB{32  + +$ + +$File_Area_Name_Header_Ratio +%CL Ŀ +  ##  File Name  Pts  Size   Description %FB{30  + +$ + +$Sysop_Chat_Help +^5/BYE^3: Hang up +^5/CLS^3: Clear the screen +^5/PAGE^3: Page the SysOp and User +^5/Q^3: Exit chat mode%LF +$ diff --git a/SOURCE/UNUSED/RENEGADE.OVR b/SOURCE/UNUSED/RENEGADE.OVR new file mode 100644 index 0000000000000000000000000000000000000000..3553d3909282d3cdfbf95878a0ce45f976088e89 GIT binary patch literal 743276 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 z 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

Dax~IoP{2R(pTjgELCIi-#9*F}Oc9 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

hVR}0;h`&`;mJ@|Ra;1$J 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RENEGADE.PIF b/SOURCE/UNUSED/RENEGADE.PIF new file mode 100644 index 0000000000000000000000000000000000000000..953eab2bd608f2b394d64b53086492bfb5227da6 GIT binary patch literal 2405 zcmZQL8RY8c>h9>`s^=Qv%AkM_8WQV#)j`0VLvC(DsY@{200|{uU_K23=1~_0A0Qk|02pq*?m>Dk QK7-3ygDHqc-2x8*0HEE5{Qv*} literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RENEGADE.TPH b/SOURCE/UNUSED/RENEGADE.TPH new file mode 100644 index 0000000000000000000000000000000000000000..1f536ac5acfb08f6002b3d1fe74e3a51bdae5b65 GIT binary patch literal 150106 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RENEMAIL.EXE b/SOURCE/UNUSED/RENEMAIL.EXE new file mode 100644 index 0000000000000000000000000000000000000000..4ac04fc6ac59060372c35379bc2092dd0b36883b GIT binary patch literal 47456 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 ZCb##y@r$OYEtqg)+$N#0pdtGA{{U%$M9TmG literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RENEMAIL.TPH b/SOURCE/UNUSED/RENEMAIL.TPH new file mode 100644 index 0000000000000000000000000000000000000000..c39df7b165b046bafaa1764159de49b71ac995ed GIT binary patch literal 2324 zcmah~UrbYH6hFN!wEVH37LmmlE)yy;M@x}EvzgZ_WnzFwpK`4L1pNsS&s}CcC zC|Rk^YEY$bj=KxKw%3af%gv%O%%g>;cj7ee0sD1 zibjJ1JtK@y1^2++Fh4RM3{F^Kat04>ZxAqcxSGxIX1y~XJau_cg8{}g7llwrj|x0J zTm<%E7X>!(3KZ-E(j6S)r-wuS;A{tFS>O+Z=YxZ@Ca}<`BXiS3Mlc8X7UVVWh5WxT z12)WKr<%sG;N%QDGCmo^ycKtOJG~vAw)Wb9{|p#j@iC7(zQCx%x)_kBv*+uuS%)n; zT%f~+I$Wf~#X7u4hpjqHba*eAdZxz(*r&5G1%`o!1H_h|`pvz;MlMRM+%+I~4#*wl za$Bs0h-2a;$*@x~dz2vzCrF`lC0yosl0C^)U0LEX{_D}In+aUT<@)l|KM+Rl;3Q|_ zZ)$KwR73aIP0vH5YQ3W=H72tseSv7E`}4+y*7xaQv~i{5(r7|rlWelpeekjrB3(;F z^oMJ{KcYnOOS>{fyfBqVq52t>Q#Nq&umZZ&t3U zySN$1w3Ld?i41#^ET>$3o)6JB^W23V(bQMrkY>)HsT_>e_{@OmVZekBmJj$i*fNDs z1jVoitUzEd?%JRPm5PhQRhUH;X29xV zYO(@jy6aRY&AfEXN+kB4>R|=*X)yjb&zZ|}{y)zlHD~kCl*9WfOXqfi=!@Tz*z&|@ zN_a)7v#yDC4(S4!eZj^qOQVe`HZHLdk=_bZL2F1lN?tAN2`(90Yg=ZTFx`@plC%PM zn|GE+a&%tJ(%GVf)q+Hg&s2#{l-P(5_mqesEZcN{RJvfL8DJt$xCcv0c=ITE5*N0B z?|~TVi~fw^H+vTkam(7aPZ_(tjrkkbG$YsZ-N%S>B|XfNw9_Ozn)GSo%CLP_ly~CK zk~DY8>dmta{p+eKzS8mK7K{hJjr>GadC0Bwq$)X}$vo?Rg7(Mv?#I$9sr>%JL#~XT z;HpTOIOVYaLV3P}nTyw{bxq(8$I}}2Ro195_YO@!ZrxqHE$%c3HspcjQn8xvU1w9r z$s%n|tZp%cm(pH7*NF=r-5G2mrv~HpM|b2}UqEaAh!bnNZ z+rE`80>=cUs16o)ROAMByoR_nUo>uJ9>Y7*;fmLEsC~C;-7xxhrH#8ezB#;WM5@+i z45#4y!b{SrnLdJn)dJ1A?TOt!)LEBO^NmoKqYoA`xVjiE6IEYo`D9Ovx3hgYmhkP! z@~g+9GG0q<*iBXE>+|X>bXam&02o?rBN|(KcQ^SRaQNzGRTDNqi7OSNQ^BEl*JN*8 Y_C)1&-QS4d-w1zP+7CjjkKF_BA0>f%e*gdg literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/REUPDATE.PAS b/SOURCE/UNUSED/REUPDATE.PAS new file mode 100644 index 0000000..ae15277 --- /dev/null +++ b/SOURCE/UNUSED/REUPDATE.PAS @@ -0,0 +1 @@ +wcwc \ No newline at end of file diff --git a/SOURCE/UNUSED/RGAPI.PAS b/SOURCE/UNUSED/RGAPI.PAS new file mode 100644 index 0000000..67fb721 --- /dev/null +++ b/SOURCE/UNUSED/RGAPI.PAS @@ -0,0 +1,1335 @@ +UNIT RGApi; +{ Renegade Bulletin Board Software & Turbo Pascal/Borland Pascal API unit. } +{ This unit uses commonly used routines in building a utility to work } +{ with the Renegade BBS. } +{ } +{ Copyright 2003 - 2013 Chris Hoppman & T.J. McMillian } + +{ + + This unit will be gave out and will there will never be a charge to use + the API for Renegade. This unit may be changed as wished and alter'd to + suit the needs of the programmer that is using it. Feel free to summit + any changes or updates you might have for this unit to the Programmer of + the Renegade BBS for thanks and for future releases of this API from other + programmers + +} + +{ + Special thanks goes out to the orginal programmer (owner: see below) + Copyright 1994 By Jeff Fanjoy and MatrixSoft(tm). All Rights Reserved. + Upon tring to contact and not being able to contact the authors we + have decided to update and release new releases to the public ourselves. + If the perivous owers would like for us to stop please let us know and + we will comply with your wishes. We regeat that we can't keep the orginal + documention in as it's whole, because the lack of explaination of uses and + the way to use the source. + + Here is a excert of the orginal documentation. + "RGAPI is a PUBLIC DOMAIN product. That means that anybody is free to + modify and use this product at their own personal whim. I would greatly + appreciate it if myself and MatrixSoft(tm) were recognized in the + documentation if this unit is used in any way." +} + +{ + We would like to thank Swag for providing the RunTime Error Libary. + Also, would like to thank the unknow author of the unit and if they + wish to come forward and request for us to stop using the source we + will respect the wishes of the author. + + Thank-you swag again for providing the Time Slice Routines. +} + +INTERFACE + +USES CRT, {Turbo Pascal's standard CRT unit } + DOS; {Turbo Pascal's standard DOS unit } + +{$I RECORDS.PAS} + + +{*** UNIX TIME CONVERSIONS *********************************************} + +FUNCTION LZero(W: Word) : String; +FUNCTION GetTimeZone : ShortInt; +FUNCTION IsLeapYear(Source : Word) : Boolean; +FUNCTION Norm2Unix(Y, M, D, H, Min, S : Word) : LongInt; +PROCEDURE Unix2Norm(Date : LongInt; Var Y, M, D, H, Min, S : Word); +FUNCTION TodayInUnix : LongInt; +FUNCTION AddSlash(Str: String): String; + +{*** RENEGADE COLOR CODE HANDLING **************************************} + +FUNCTION StripColor ( Var InStr ): String; + +{*** MISC ROUTINES *****************************************************} +function IntToStr ( IntIn: LongInt ) : String; +function StrToInt ( InStr: String ) : LongInt; +function DirExists ( InDir: DirStr ) : Boolean; +function FileExists ( InFile: String ) : Boolean; +procedure pipe ( InStr : String ); +procedure pipexy ( x,y : byte; instr : string ); +procedure HandleError ( ErrStr : String; ProgHalt : Boolean; StopWith : Byte ); +function takeoutblanks ( instr : string ) : string; +function detectOS : string; +procedure timeslice; +PROCEDURE FindRGDir; +{ +function InputStrxy ( x,y: byte ) : string; +function InputIntxy ( x,y: byte ) : integer; + + +{*** RENEGADE.DAT ******************************************************} + +PROCEDURE OpenRenegadeDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromRenegadeDat ( Var RenegadeDatIn: GeneralRecordType; Var Err: Byte ); +PROCEDURE WriteToRenegadeDat ( Var RenegadeDatIn: GeneralRecordType; Var Err: Byte ); +PROCEDURE CloseRenegadeDat; + +{*** CONVERENC.DAT *****************************************************} + +PROCEDURE OpenConferencDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromConferencDat ( Var ConferencDatIn: ConferenceRecordType ); +PROCEDURE WriteToConferencDat ( Var ConferencDatIn: ConferenceRecordType ); +PROCEDURE CloseConferencDat; + +{*** SCHEME.DAT ********************************************************} + +PROCEDURE OpenSchemeDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromSchemeDat ( Var SchemeDatIn: SchemeRec ); +PROCEDURE WriteToSchemeDat ( Var SchemeDatIn: SchemeRec ); +PROCEDURE CloseSchemeDat; + +{*** MBASES.DAT ********************************************************} + +PROCEDURE OpenMBasesDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromMBasesDat ( Var MBasesDatIn: MessageAreaRecordType; Rec: Integer ); +PROCEDURE WriteToMBasesDat ( Var MBasesDatIn: MessageAreaRecordType; Rec: Integer ); +PROCEDURE CloseMBasesDat; + +{*** *.HDR *************************************************************} + +PROCEDURE OpenHdr ( FileName: String; Path: String; Var Err: Byte ); +PROCEDURE ReadFromHdr ( Var HdrIn: MHeaderRec; Rec: Integer ); +PROCEDURE WriteToHdr ( Var HdrIn: MHeaderRec; Rec: Integer ); +PROCEDURE CloseHdr; + +{*** *.DAT *************************************************************} + +PROCEDURE OpenDat ( FileName: String; Path: String; Var Err: Byte ); +PROCEDURE CloseDat; + +{*** USERS.DAT *********************************************************} + +PROCEDURE OpenUsersDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromUsersDat ( Var UsersDatIn: UserRecordType; Rec: Integer ); +PROCEDURE WriteToUsersDat ( Var UsersDatIn: UserRecordType; Rec: Integer ); +PROCEDURE CloseUsersDat; + +{*** USERS.IDX *********************************************************} +PROCEDURE OpenUsersIdx(Path: String; VAR Err: Byte); +PROCEDURE ReadFromUsersIdx(VAR UsersIdxIn: UserIdxRec; Rec: Integer); +PROCEDURE WriteToUsersIdx(VAR UsersIdxIn: UserIdxRec; Rec: Integer); +PROCEDURE CloseUsersIdx; + +{*** HISTORY.DAT *******************************************************} + +PROCEDURE OpenHistoryDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromHistoryDat ( Var HistoryDatIn: HistoryRecordType; Rec: Integer ); +PROCEDURE WriteToHistoryDat ( Var HistoryDatIn: HistoryRecordType; Rec: Integer ); +PROCEDURE CloseHistoryDat; + +{*** VOTING.DAT ********************************************************} + +PROCEDURE OpenVotingDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromVotingDat ( Var VotingDatIn: VotingRecordType; Rec: Integer ); +PROCEDURE WriteToVotingDat ( Var VotingDatIn: VotingRecordType; Rec: Integer ); +PROCEDURE CloseVotingDat; + +{*** FBASES.DAT ********************************************************} + +PROCEDURE OpenFBasesDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromFBasesDat ( Var FBasesDatIn: FileAreaRecordType; Rec: Integer ); +PROCEDURE WriteToFBasesDat ( Var FBasesDatIn: FileAreaRecordType; Rec: Integer ); +PROCEDURE CloseFBasesDat; + +{*** *.DIR *************************************************************} + +PROCEDURE OpenDir ( FileName: String; Path: String; Var Err: Byte ); +PROCEDURE ReadFromDir ( Var DirIn: FileInfoRecordType; Rec: Integer ); +PROCEDURE WriteToDir ( Var DirIn: FileInfoRecordType; Rec: Integer ); +PROCEDURE CloseDir; + +{*** FILE DATE CONVERSION FROM STRING FORMAT ***************************} + +PROCEDURE StrDate2FileDate ( S: String; Var Y: Word; Var M: Word; Var D: Word ); + +{*** EXTENDED.DAT ******************************************************} + +PROCEDURE OpenExtendedDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromExtendedDat ( Var ExtendedDatIn: VerbRec; Rec: LongInt ); +PROCEDURE WriteToExtendedDat ( Var ExtendedDatIn: VerbRec; Rec: LongInt ); +PROCEDURE CloseExtendedDat; + +{*** LASTON.DAT ********************************************************} + +PROCEDURE OpenLastOnDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromLastOnDat ( Var LastOnDatIn: LastCallerRec; Rec: Integer ); +PROCEDURE WriteToLastOnDat ( Var LastOnDatIn: LastCallerRec; Rec: Integer ); +PROCEDURE CloseLastOnDat; + +{*** EVENTS.DAT ********************************************************} + +PROCEDURE OpenEventsDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromEventsDat ( Var EventsDatIn: EventRec; Rec: Integer ); +PROCEDURE WriteToEventsDat ( Var EventsDatIn: EventRec; Rec: Integer ); +PROCEDURE CloseEventsDat; + +{*** PROTOCOL.DAT ******************************************************} + +PROCEDURE OpenProtocolDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromProtocolDat ( Var ProtocolDatIn: ProtRec; Rec: Integer ); +PROCEDURE WriteToProtocolDat ( Var ProtocolDatIn: ProtRec; Rec: Integer ); +PROCEDURE CloseProtocolDat; + +{*** MULTNODE.DAT ******************************************************} + +PROCEDURE OpenMultNodeDat ( Path: String; Var Err: Byte ); +PROCEDURE ReadFromMultNodeDat ( Var MultNodeDatIn: NodeRec; Rec: Integer ); +PROCEDURE WriteToMultNodeDat ( Var MultNodeDatIn: NodeRec; Rec: Integer ); +PROCEDURE CloseMultNodeDat; + +{*** *.SCN *************************************************************} + +PROCEDURE OpenScn ( FileName: String; Path: String; Var Err: Byte ); +PROCEDURE ReadFromScn ( Var ScnIn: ScanRec; Rec: Integer ); +PROCEDURE WriteToScn ( Var ScnIn: ScanRec; Rec: Integer ); +PROCEDURE CloseScn; + +{***********************************************************************} + +CONST + RGApiVer = '12-27.3 - DOS'; + RGApiAuthor = 'Bluewolf'; + MonthArray: Array[1..12] OF String[3] = + ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct', + 'Nov','Dec'); + DowArray: Array[0..6] OF String[3] = + ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); + +{*** USED BY UNIX-TIME CONVERTING PROCEDURES ***************************} + + DaysPerMonth : + Array[1..12] of ShortInt = + (031,028,031,030,031,030,031,031,030,031,030,031); + DaysPerYear : + Array[1..12] of Integer = + (031,059,090,120,151,181,212,243,273,304,334,365); + DaysPerLeapYear : + Array[1..12] of Integer = + (031,060,091,121,152,182,213,244,274,305,335,366); + SecsPerYear : LongInt = 31536000; + SecsPerLeapYear : LongInt = 31622400; + SecsPerDay : LongInt = 86400; + SecsPerHour : Integer = 3600; + SecsPerMinute : ShortInt = 60; + +(***************************************************************************) + +type + TaskRec = record + OS : Word; + Version : Word; {writeln('Version ',hi(Version), '.', lo(Version) );} + Delay : Word; + end; + + +const + Task : TaskRec = ( + OS : 0; + Version : 0; + Delay : 100 + ); + +Var + OldExit : Pointer; + SchemeDat : FILE of SchemeRec; + MBasesDat : FILE of MessageAreaRecordType; + RenegadeDat : FILE Of GeneralRecordType; + StringDat : FILE OF FStringRec; + ConferencDat : FILE OF ConfRec; + UsersDat : FILE OF UserRecordType; + Hdr : FILE of MHeaderRec; + HistoryDat : FILE OF HistoryRec; + Dat : FILE; + VotingDat : FILE OF VotingR; + FBasesDat : FILE OF FileAreaRecordType; + Dir : FILE OF UlfRec; + ExtendedDat : FILE OF VerbRec; + LastOnDat : FILE OF LastCallerRec; + EventsDat : FILE OF EventRec; + ProtocolDat : FILE OF ProtRec; + MultNodeDat : FILE OF NodeRec; + Scn : FILE OF ScanRec; + UsersIdx : FILE OF UserIdxRec; + + RGDir : String; + CurrDir : String; + OSVer : String; + +IMPLEMENTATION + +Procedure RunTimeExitProc;Far; +var Message : string; +begin + if ErrorAddr<>Nil then { If error occurs } + begin + case ExitCode of { Pick the appropriate message } + 2:Message:='File not found '; + 3:Message:='Path not found '; + 4:Message:='Too many open files '; + 5:Message:='File access denied '; + 6:Message:='Invalid file handle '; + 8:Message:='Insufficient memory '; + 12:Message:='Invalid file access code '; + 15:Message:='Invalid drive number '; + 16:Message:='Cannot remove current directory '; + 17:Message:='Cannot rename across drives '; + 100:Message:='Disk read error '; + 100:Message:='Disk write error '; + 102:Message:='File not assigned '; + 103:Message:='File not open '; + 104:Message:='File not open for input '; + 105:Message:='File not open for output '; + 106:Message:='Invalid numeric format '; + 150:Message:='Disk is write-protected '; + 151:Message:='Unknown unit '; + 152:Message:='Drive not ready '; + 153:Message:='Unknown command '; + 154:Message:='CRC error in data '; + 155:Message:='Bad drive request structure length '; + 156:Message:='Disk seek error '; + 157:Message:='Unknown media type '; + 158:Message:='Sector not found '; + 159:Message:='Printer out of paper '; + 160:Message:='Device write fault '; + 161:Message:='Device read fault '; + 162:Message:='Hardware failure '; + 200:Message:='Division by zero '; + 201:Message:='Range check error '; + 202:Message:='Stack overflow error '; + 203:Message:='Heap overflow error '; + 204:Message:='Invalid pointer operation '; + 205:Message:='Floating-point overflow '; + 206:Message:='Floating-point underflow '; + 207:Message:='Invalid floating-point operation '; + 208:Message:='Overlay manager not installed '; + 209:Message:='Overlay file read error '; + 210:Message:='Object not initialized '; + 211:Message:='Call to abstract method '; + 212:Message:='Stream register error '; + 213:Message:='Collection index out of range '; + 214:Message:='Collection overflow error '; + end; + writeln; + writeln('Error : ',ExitCode,' - ',Message); + writeln; + + ErrorAddr:=nil; + ExitCode:=1; { End program with errorlevel 1 } + end; + ExitProc:=OldExit; { Restore the original exit procedure } +end; + +FUNCTION AddSlash(Str: String): String; +BEGIN + IF Str <> '' THEN + BEGIN + IF Str[Length(Str)] <> '\' THEN AddSlash := Str + '\' + ELSE AddSlash := Str; + END + ELSE AddSlash := ''; +END; + + +FUNCTION LZero( W: Word ) : String; +Var S1: String; +BEGIN + Str(W:0,S1); + IF LENGTH(S1) = 1 THEN S1 := '0' + S1; + LZero := S1; +END; + + +FUNCTION GetTimeZone : ShortInt; +Var + Environment : String; + Index : Integer; +BEGIN + GetTimeZone := 0; {Assume UTC} + Environment := GetEnv('TZ'); {Grab TZ string} + For Index := 1 TO Length(Environment) DO + Environment[Index] := UpCase(Environment[Index]); + IF Environment = 'EST05' THEN GetTimeZone := -05; {USA EASTERN} + IF Environment = 'EST05EDT' THEN GetTimeZone := -06; + IF Environment = 'CST06' THEN GetTimeZone := -06; {USA CENTRAL} + IF Environment = 'CST06CDT' THEN GetTimeZone := -07; + IF Environment = 'MST07' THEN GetTimeZone := -07; {USA MOUNTAIN} + IF Environment = 'MST07MDT' THEN GetTimeZone := -08; + IF Environment = 'PST08' THEN GetTimeZone := -08; + IF Environment = 'PST08PDT' THEN GetTimeZone := -09; + IF Environment = 'YST09' THEN GetTimeZone := -09; + IF Environment = 'AST10' THEN GetTimeZone := -10; + IF Environment = 'BST11' THEN GetTimeZone := -11; + IF Environment = 'CET-1' THEN GetTimeZone := 01; + IF Environment = 'CET-01' THEN GetTimeZone := 01; + IF Environment = 'EST-10' THEN GetTimeZone := 10; + IF Environment = 'WST-8' THEN GetTimeZone := 08; {Perth, W. Aust.} + IF Environment = 'WST-08' THEN GetTimeZone := 08; +END; + +FUNCTION IsLeapYear( Source : Word ) : Boolean; +BEGIN + IF (Source MOD 400 = 0) OR ((Source Mod 4 = 0) AND + (Source MOD 100 <> 0)) THEN + IsLeapYear := TRUE + ELSE + IsLeapYear := FALSE; +END; + + +FUNCTION Norm2Unix( Y,M,D,H,Min,S : Word ) : LongInt; +Var + UnixDate : LongInt; + Index : Word; +BEGIN + UnixDate := 0; {initialize} + Inc(UnixDate,S); {add seconds} + Inc(UnixDate,(SecsPerMinute * Min)); {add minutes} + Inc(UnixDate,(SecsPerHour * H)); {add hours} + (*************************************************************************) + (* If UTC = 0, and local time is -06 hours of UTC, then *) + (* UTC := UTC - (-06 * SecsPerHour) *) + (* Remember that a negative # minus a negative # yields a positive value *) + (*************************************************************************) + UnixDate := UnixDate - (GetTimeZone * SecsPerHour); + + IF D > 1 THEN + Inc(UnixDate,(SecsPerDay * (D-1))); + + IF IsLeapYear(Y) THEN + DaysPerMonth[02] := 29 + ELSE + DaysPerMonth[02] := 28; + + Index := 1; + IF M > 1 THEN FOR Index := 1 TO (M-1) DO + Inc(UnixDate,(DaysPerMonth[Index] * SecsPerDay)); + + WHILE Y > 1970 DO + BEGIN + IF IsLeapYear((Y-1)) THEN + Inc(UnixDate,SecsPerLeapYear) + ELSE + Inc(UnixDate,SecsPerYear); + Dec(Y,1); + END; + + Norm2Unix := UnixDate; +END; + +PROCEDURE Unix2Norm( Date : LongInt; Var Y, M, D, H, Min, S : Word ); +Var + LocalDate : LongInt; + Done : Boolean; + X : ShortInt; + TotDays : Integer; +BEGIN + Y := 1970; + M := 1; + D := 1; + H := 0; + Min := 0; + S := 0; + LocalDate := Date + (GetTimeZone * SecsPerHour); + Done := FALSE; + WHILE NOT (Done) DO + BEGIN + IF LocalDate >= SecsPerYear THEN + BEGIN + Inc(Y,1); + Dec(LocalDate,SecsPerYear); + END + ELSE + Done := TRUE; + IF (IsLeapYear(Y+1)) AND (LocalDate >= SecsPerLeapYear) AND + (NOT (Done)) THEN + BEGIN + Inc(Y,1); + Dec(LocalDate,SecsPerLeapYear); + END; + END; + M := 1; + D := 1; + Done := FALSE; + TotDays := LocalDate DIV SecsPerDay; + IF IsLeapYear(Y) THEN + BEGIN + DaysPerMonth[02] := 29; + X := 1; + REPEAT + IF (TotDays <= DaysPerLeapYear[x]) THEN + BEGIN + M := X; + Done := TRUE; + Dec(LocalDate,(TotDays * SecsPerDay)); + D := DaysPerMonth[M]-(DaysPerLeapYear[M]-TotDays) + 1; + END + ELSE + Done := FALSE; + Inc(X); + UNTIL (Done) or (X > 12); + END + ELSE + BEGIN + DaysPerMonth[02] := 28; + X := 1; + REPEAT + IF (TotDays <= DaysPerYear[x]) THEN + BEGIN + M := X; + Done := TRUE; + Dec(LocalDate,(TotDays * SecsPerDay)); + D := DaysPerMonth[M]-(DaysPerYear[M]-TotDays) + 1; + END + ELSE + Done := FALSE; + Inc(X); + UNTIL Done = TRUE or (X > 12); + END; + H := LocalDate DIV SecsPerHour; + Dec(LocalDate,(H * SecsPerHour)); + Min := LocalDate DIV SecsPerMinute; + Dec(LocalDate,(Min * SecsPerMinute)); + S := LocalDate; +END; + +FUNCTION TodayInUnix : LongInt; +Var + Year, Month, Day, DayOfWeek: Word; + Hour, Minute, Second, Sec100: Word; +BEGIN + GetDate(Year, Month, Day, DayOfWeek); + GetTime(Hour, Minute, Second, Sec100); + TodayInUnix := Norm2Unix(Year,Month,Day,Hour,Minute,Second); +END; + +FUNCTION StripColor( Var InStr ):String; +Var + Temp: String; + S: String Absolute InStr; + I, + Len: Integer; +BEGIN + Len := Length(S); + I := 1; + Temp := ''; + REPEAT + IF (S[I] = '|') THEN Inc(I,3) + ELSE IF (S[I] = '^') THEN Inc(I,2) + ELSE + BEGIN + Temp := Temp + S[I]; + Inc(I); + END; + UNTIL (I > Len); + StripColor := Temp; +END; + +function IntToStr( intin : longint) : string; +var s : string; +begin + s:=''; + Str(intin, S); + IntToStr := s; +end; + +function StrToInt( InStr: String ) : LongInt; +var i : longint; + code : integer; +begin + Val(InStr, I, Code); + StrToInt := I; +end; + + + +FUNCTION DirExists(inDir : dirstr) : boolean; + var + woFattr : word; + fiTemp : file; + begin + assign(fiTemp, (inDir + '.')); + getfattr(fiTemp, woFattr); + if (doserror <> 0) then DirExists := false + else DirExists := ((woFattr and directory) <> 0) + end; + + +function FileExists( inFile : string) : Boolean; + var + woFattr : word; + fiTemp : file; + begin + assign(fiTemp,inFile); + getfattr(fiTemp, woFattr); + if (doserror <> 0) then FileExists := false + else FileExists := ((woFattr and Archive) <> 0) + end; + +PROCEDURE Pipe(InStr : String ); +Var + S : String; + I, Err : Integer; + Col : byte; +BEGIN + S := InStr; + I := 1; + REPEAT + IF (S[I] = '|') THEN + BEGIN + Val(COPY(S,I+1,2),Col,Err); + IF (Err = 0) AND (Col IN [0..22]) THEN + IF Col IN [0..15] THEN TextColor(Col) + ELSE IF Col IN [16..22] THEN TextBackground(Col - 16); + Inc(I,3); + END + ELSE BEGIN + Write(S[I]); + Inc(I); + END; + UNTIL (I > Length(S)); + Writeln; +END; + +PROCEDURE Pipexy(x,y : byte; InStr : String ); +BEGIN + gotoxy(x,y); + pipe(instr); +END; + +{ + ErrStr : String to display when a error occurs + ProgHalt : 0: No, display the string and keep running + 1: Yes, stop the application + HaltWith : if you want to halt the application you can + provide a RunTime Error. + } +Procedure HandleError(ErrStr : String; ProgHalt : Boolean; StopWith : Byte ); + + begin + pipe('|11 |12ERROR |11 |14: |06#'++IntToStr(StopWith)+'|07'); + pipe(ErrStr+'|07'); + if ProgHalt then Halt(StopWith); + end; + +function takeoutblanks( instr : string) : string; +var t : string; + a : byte; +begin + t := ''; + for a := 1 to length(instr) do + if instr[a] <> ' ' then t := t + instr[a]; + + takeoutblanks := t; +end; + +function detectOS : string; + Procedure InitMulti; Assembler; + Asm + mov Task.OS, 0 + mov Task.Version, 0 + mov Ah, 30h + mov Al, 01h + int 21h + cmp Al, 20 + je @OS2 + + mov Ax, 160Ah + int 2Fh + cmp Ax, 0 + je @Windows + + mov Ax, 1022h + mov Bx, 0000h + int 15h + cmp Bx, 0 + jne @DESQview + + + mov Ah, 2Bh + mov Al, 01h + mov Cx, 4445h + mov Dx, 5351h + int 21h + cmp Al, $FF + jne @TopView + + jmp @Fin + + @Windows: + Mov Task.OS, 1 + Mov Task.Version, BX + jmp @Fin + + @OS2: + Mov Task.OS, 2 + Mov Bh, Ah + Xor Ah, Ah + Mov Cl, 10 + Div Cl + Mov Ah, Bh + Xchg Ah, Al + Mov Task.Version, AX + jmp @Fin + + @DESQview: + mov Task.OS, 3 + jmp @Fin + + @TopView: + mov Task.OS, 4 + + @Fin: + End; +begin + InitMulti; + case Task.OS of + 0 : detectOS := 'No MultiTasking'; + 1 : detectOS := 'Windows'; + 2 : detectOS := 'OS/2'; + 3 : detectOS := 'DESQview'; + 4 : detectOS := 'TopView'; + end; +end; +procedure TimeSlice; +var Regs : Registers; + Procedure TimeSliceASM; Assembler; + Asm + cmp Task.OS, 0 + je @Fin + cmp Task.OS, 1 + je @Win_OS2 + cmp Task.OS, 2 + je @Win_OS2 + @DV_TV: + mov Ax, 1000h + int 15h + jmp @Fin + @Win_OS2: + mov Ax, 1680h + int 2Fh + @Fin: + End; + +begin + if Task.OS <> 0 then TimeSliceASM + else with Regs do Intr($28,Regs); +end; + +PROCEDURE FindRGDir; +BEGIN + GetDir(0,CurrDir); + if paramstr(1) <> '' then RGDir := ParamStr(1); + if (paramstr(1) = '') or (RGDir[2] <> ':') then RGDir := GetEnv('RENEGADE'); + if RGDir = '' then RGDir := GetEnv('RG'); + if RGDir = '' then RGDir := GetEnv('BBS'); + { work on more ..fexpand.. + if RGDir = '' then RGDir := FSearch('RENEGADE.DAT',GetEnv('PATH')) + else if RGDir = '' then RGDir := FSearch('RENEGADE.EXE',GetEnv('PATH')); + if RGDir = '' then RGDir := FSearch('RENEGADE.DAT',CurrDir) + else if RGDir = '' then RGDir := FSearch('RENEGADE.EXE',CurrDir); + } + if (RGDir <> '') and (RGDir[length(RGDir)] <> '\') then RGDir := RGDir + '\'; + if (RGDir = '') or (not DirExists(RGDir)) then begin handleerror(' Renegade.dat not found..',True,15); halt; end; +END; + +PROCEDURE OpenRenegadeDat( Path: String; Var Err: Byte ); +BEGIN + If Path = '' then begin + FindRGDir; + if RGDir <> '' then Path := RGDir; + end; + Assign(RenegadeDat,AddSlash(Path) + 'RENEGADE.DAT'); + {$I-} Reset(RenegadeDat); {$I+} + Err := IoResult; +END; + +PROCEDURE ReadFromRenegadeDat( Var RenegadeDatIn: GeneralRecordType; Var Err: Byte ); +BEGIN + {$I-}Seek(RenegadeDat,0);{$I+} + if ioresult = 0 then Read(RenegadeDat,RenegadeDatIn); + Err := IOResult; +END; + +PROCEDURE WriteToRenegadeDat(Var RenegadeDatIn: GeneralRecordType; Var Err: Byte ); +BEGIN + {$I-}Seek(RenegadeDat,0);{$I+} + if ioresult = 0 then Write(RenegadeDat,RenegadeDatIn); + Err := IOResult; +END; + +PROCEDURE CloseRenegadeDat; +BEGIN + Close(RenegadeDat); +END; + +PROCEDURE OpenConferencDat(Path: String; Var Err: Byte); +BEGIN + Assign(ConferencDat,AddSlash(Path) + 'CONFERENC.DAT'); + {$I-} Reset(ConferencDat); {$I+} + Err := IoResult; +END; + +PROCEDURE ReadFromConferencDat(Var ConferencDatIn: ConfRec); +BEGIN + Seek(ConferencDat,0); + Read(ConferencDat,ConferencDatIn); +END; + +PROCEDURE WriteToConferencDat(Var ConferencDatIn: ConfRec); +BEGIN + Seek(ConferencDat,0); + Read(ConferencDat,ConferencDatIn); +END; + +PROCEDURE CloseConferencDat; +BEGIN + Close(ConferencDat); +END; + +PROCEDURE OpenSchemeDat(Path: String; Var Err: Byte); + +BEGIN + Assign(SchemeDat,AddSlash(Path) + 'SCHEME.DAT'); + {$I-} Reset(SchemeDat); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromSchemeDat(Var SchemeDatIn: SchemeRec); + +BEGIN + Seek(SchemeDat,0); + Read(SchemeDat,SchemeDatIn); +END; + + +PROCEDURE WriteToSchemeDat(Var SchemeDatIn: SchemeRec); + +BEGIN + Seek(SchemeDat,0); + Read(SchemeDat,SchemeDatIn); +END; + + +PROCEDURE CloseSchemeDat; + +BEGIN + Close(SchemeDat); +END; + + +PROCEDURE OpenMBasesDat(Path: String; + Var Err: Byte); + +BEGIN + Assign(MBasesDat,AddSlash(Path) + 'MBASES.DAT'); + {$I-} Reset(MBasesDat); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromMBasesDat(Var MBasesDatIn: MessageAreaRecordType; + Rec: Integer); + +BEGIN + Seek(MBasesDat,Rec); + Read(MBasesDat,MBasesDatIn); +END; + + +PROCEDURE WriteToMBasesDat(Var MBasesDatIn: MessageAreaRecordType; + Rec: Integer); + +BEGIN + Seek(MBasesDat,Rec); + Write(MBasesDat,MBasesDatIn); +END; + + +PROCEDURE CloseMBasesDat; + +BEGIN + Close(MBasesDat); +END; + + +PROCEDURE OpenHdr(FileName: String; + Path: String; + Var Err: Byte); + +BEGIN + Assign(Hdr,AddSlash(Path) + FileName); + {$I-} Reset(Hdr); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromHdr(Var HdrIn: MHeaderRec; + Rec: Integer); + +BEGIN + Seek(Hdr,Rec); + Read(Hdr,HdrIn); +END; + + +PROCEDURE WriteToHdr(Var HdrIn: MHeaderRec; + Rec: Integer); + +BEGIN + Seek(Hdr,Rec); + Write(Hdr,HdrIn); +END; + + +PROCEDURE CloseHdr; + +BEGIN + Close(Hdr); +END; + + +PROCEDURE OpenDat(FileName: String; + Path: String; + Var Err: Byte); + +BEGIN + Assign(Dat,AddSlash(Path) + FileName); + {$I-} Reset(Dat); {$I+} + Err := IoResult; +END; + + +PROCEDURE CloseDat; + +BEGIN + Close(Dat); +END; + + +PROCEDURE OpenUsersDat(Path: String; + Var Err: Byte); + +BEGIN + Assign(UsersDat,AddSlash(Path) + 'USERS.DAT'); + {$I-} Reset(UsersDat); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromUsersDat(Var UsersDatIn: UserRecordType; + Rec: Integer); + +BEGIN + Seek(UsersDat,Rec); + Read(UsersDat,UsersDatIn); +END; + + +PROCEDURE WriteToUsersDat(Var UsersDatIn: UserRecordType; + Rec: Integer); + +BEGIN + Seek(UsersDat,Rec); + Read(UsersDat,UsersDatIn); +END; + + +PROCEDURE CloseUsersDat; + +BEGIN + Close(UsersDat); +END; + +{*** USERS.IDX *********************************************************} +PROCEDURE OpenUsersIdx(Path: String; VAR Err: Byte); +BEGIN + Assign(UsersIdx,AddSlash(Path) + 'users.idx'); + {$I-} Reset(UsersIdx); {$I+} + Err := IoResult; +END; +PROCEDURE ReadFromUsersIdx(VAR UsersIdxIn: UserIdxRec; Rec: Integer); +BEGIN + Seek(UsersIdx,Rec); + Read(UsersIdx,UsersIdxIn); +END; +PROCEDURE WriteToUsersIdx(VAR UsersIdxIn: UserIdxRec; Rec: Integer); +BEGIN + Seek(UsersIdx,Rec); + Write(UsersIdx,UsersIdxIn); +END; +PROCEDURE CloseUsersIdx; +BEGIN + Close(UsersIdx); +END; + + + + +PROCEDURE OpenHistoryDat(Path: String; + Var Err: Byte); + +BEGIN + Assign(HistoryDat,AddSlash(Path) + 'HISTORY.DAT'); + {$I-} Reset(HistoryDat); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromHistoryDat(Var HistoryDatIn: HistoryRec; + Rec: Integer); + +BEGIN + Seek(HistoryDat,Rec); + Read(HistoryDat,HistoryDatIn); +END; + + +PROCEDURE WriteToHistoryDat(Var HistoryDatIn: HistoryRec; + Rec: Integer); + +BEGIN + Seek(HistoryDat,Rec); + Write(HistoryDat,HistoryDatIn); +END; + + +PROCEDURE CloseHistoryDat; + +BEGIN + Close(HistoryDat); +END; + + +PROCEDURE OpenVotingDat(Path: String; + Var Err: Byte); + +BEGIN + Assign(VotingDat,AddSlash(Path) + 'VOTING.DAT'); + {$I-} Reset(VotingDat); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromVotingDat(Var VotingDatIn: VotingR; + Rec: Integer); + +BEGIN + Seek(VotingDat,Rec); + Read(VotingDat,VotingDatIn); +END; + + +PROCEDURE WriteToVotingDat(Var VotingDatIn: VotingR; + Rec: Integer); + +BEGIN + Seek(VotingDat,Rec); + Read(VotingDat,VotingDatIn); +END; + + +PROCEDURE CloseVotingDat; + +BEGIN + Close(VotingDat); +END; + +(* FBASES.DAT *) +PROCEDURE OpenFBasesDat(Path: String; Var Err: Byte); +BEGIN + Assign(FBasesDat,AddSlash(Path) + 'FBASES.DAT'); + {$I-} Reset(FBasesDat); {$I+} + Err := IoResult; +END; + +PROCEDURE ReadFromFBasesDat(Var FBasesDatIn: FileAreaRecordType; Rec: Integer); +BEGIN + Seek(FBasesDat,Rec); + Read(FBasesDat,FBasesDatIn); +END; + +PROCEDURE WriteToFBasesDat(Var FBasesDatIn: FileAreaRecordType; Rec: Integer); +BEGIN + Seek(FBasesDat,Rec); + Write(FBasesDat,FBasesDatIn); +END; + +PROCEDURE CloseFBasesDat; + +BEGIN + Close(FBasesDat); +END; + + +PROCEDURE OpenDir(FileName: String; + Path: String; + Var Err: Byte); + +BEGIN + Assign(Dir,AddSlash(Path) + FileName); + {$I-} Reset(Dir); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromDir (Var DirIn: UlfRec; Rec: Integer ); +BEGIN + Seek(Dir,Rec); + Read(Dir,DirIn); +END; + +PROCEDURE WriteToDir ( Var DirIn: UlfRec; Rec: Integer ); +BEGIN + Seek(Dir,Rec); + Write(Dir,DirIn); +END; + + +PROCEDURE CloseDir; +BEGIN + Close(Dir); +END; + + +PROCEDURE StrDate2FileDate ( S: String; Var Y: Word; Var M: Word; Var D: Word ); +Var Err: Integer; + +BEGIN + VAL(COPY(S,1,2),D,Err); + VAL(COPY(S,4,2),M,Err); + VAL(COPY(S,7,4),Y,Err); +END; + + +PROCEDURE OpenExtendedDat(Path: String; + Var Err: Byte); + +BEGIN + Assign(ExtendedDat,AddSlash(Path) + 'EXTENDED.DAT'); + {$I-} Reset(ExtendedDat); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromExtendedDat(Var ExtendedDatIn: VerbRec; + Rec: LongInt); + +BEGIN + Seek(ExtendedDat,Rec); + Read(ExtendedDat,ExtendedDatIn); +END; + + +PROCEDURE WriteToExtendedDat(Var ExtendedDatIn: VerbRec; + Rec: LongInt); + +BEGIN + Seek(ExtendedDat,Rec); + Write(ExtendedDat,ExtendedDatIn); +END; + + +PROCEDURE CloseExtendedDat; + +BEGIN + Close(ExtendedDat); +END; + + +PROCEDURE OpenLastOnDat(Path: String; + Var Err: Byte); + +BEGIN + Assign(LastOnDat,AddSlash(Path) + 'LASTON.DAT'); + {$I-} Reset(LastOnDat); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromLastOnDat(Var LastOnDatIn: LastCallerRec; Rec: Integer); +BEGIN + Seek(LastOnDat,Rec); + Read(LastOnDat,LastOnDatIn); +END; + +PROCEDURE WriteToLastOnDat(Var LastOnDatIn: LastCallerRec; Rec: Integer); +BEGIN + Seek(LastOnDat,Rec); + Write(LastOnDat,LastOnDatIn); +END; + +PROCEDURE CloseLastOnDat; +BEGIN + Close(LastOnDat); +END; + +PROCEDURE OpenEventsDat(Path: String; Var Err: Byte); +BEGIN + Assign(EventsDat,AddSlash(Path) + 'EVENTS.DAT'); + {$I-} Reset(EventsDat); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromEventsDat(Var EventsDatIn: EventRec; + Rec: Integer); + +BEGIN + Seek(EventsDat,Rec); + Read(EventsDat,EventsDatIn); +END; + + +PROCEDURE WriteToEventsDat(Var EventsDatIn: EventRec; + Rec: Integer); + +BEGIN + Seek(EventsDat,Rec); + Write(EventsDat,EventsDatIn); +END; + + +PROCEDURE CloseEventsDat; + +BEGIN + Close(EventsDat); +END; + + +PROCEDURE OpenProtocolDat(Path: String; + Var Err: Byte); + +BEGIN + Assign(ProtocolDat,AddSlash(Path) + 'PROTOCOL.DAT'); + {$I-} Reset(ProtocolDat); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromProtocolDat(Var ProtocolDatIn: ProtRec; + Rec: Integer); + +BEGIN + Seek(ProtocolDat,Rec); + Read(ProtocolDat,ProtocolDatIn); +END; + + +PROCEDURE WriteToProtocolDat(Var ProtocolDatIn: ProtRec; + Rec: Integer); + +BEGIN + Seek(ProtocolDat,Rec); + Write(ProtocolDat,ProtocolDatIn); +END; + + +PROCEDURE CloseProtocolDat; + +BEGIN + Close(ProtocolDat); +END; + + +PROCEDURE OpenMultNodeDat(Path: String; + Var Err: Byte); + +BEGIN + Assign(MultNodeDat,AddSlash(Path) + 'MULTNODE.DAT'); + {$I-} Reset(MultNodeDat); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromMultNodeDat(Var MultNodeDatIn: NodeRec; + Rec: Integer); + +BEGIN + Seek(MultNodeDat,Rec); + Read(MultNodeDat,MultNodeDatIn); +END; + + +PROCEDURE WriteToMultNodeDat(Var MultNodeDatIn: NodeRec; + Rec: Integer); + +BEGIN + Seek(MultNodeDat,Rec); + Write(MultNodeDat,MultNodeDatIn); +END; + + +PROCEDURE CloseMultNodeDat; + +BEGIN + Close(MultNodeDat); +END; + + +PROCEDURE OpenScn(FileName: String; + Path: String; + Var Err: Byte); + +BEGIN + Assign(Scn,AddSlash(Path) + FileName); + {$I-} Reset(Scn); {$I+} + Err := IoResult; +END; + + +PROCEDURE ReadFromScn(Var ScnIn: ScanRec; + Rec: Integer); + +BEGIN + Seek(Scn,Rec); + Read(Scn,ScnIn); +END; + + +PROCEDURE WriteToScn(Var ScnIn: ScanRec; + Rec: Integer); + +BEGIN + Seek(Scn,Rec); + Write(Scn,ScnIn); +END; + + +PROCEDURE CloseScn; + +BEGIN + Close(Scn); +END; + + +BEGIN + OldExit:=ExitProc; { Save the original exit procedure } + ExitProc:=@RunTimeExitProc; { Insert the RunTime exit procedure } + OSVer := detectOS; +END. + diff --git a/SOURCE/UNUSED/RGFLIST.PAS b/SOURCE/UNUSED/RGFLIST.PAS new file mode 100644 index 0000000..7ae5bee --- /dev/null +++ b/SOURCE/UNUSED/RGFLIST.PAS @@ -0,0 +1,55 @@ +PROGRAM RGFLIST; + + + +PROCEDURE DownloadFileListing; +VAR + FArea: Integer; + + PROCEDURE SearchFileAreaSpec(FArea: Integer; FName: Str12; VAR FArrayRecNum: Byte); + VAR + F: FileInfoRecordType; + DirFileRecNum: Integer; + BEGIN + IF (FileArea <> FArea) THEN + ChangeFileArea(FArea); + IF (FileArea = FArea) THEN + BEGIN + RecNo(F,FName,DirFileRecNum); + IF (BadDownloadPath) THEN + Exit; + WHILE (DirFileRecNum <> -1) AND (NOT Next) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(DirFile,DirFileRecNum); + Read(DirFile,F); + IF (CanSee(F)) THEN + BEGIN + WITH FArray[FArrayRecNum] DO + BEGIN + FArrayFileArea := FileArea; + FArrayDirFileRecNum := DirFileRecNum; + END; + DisplayFileAreaHeader; + Display_File(F,FArrayRecNum,'',FALSE); + Inc(FArrayRecNum); + IF (FArrayRecNum = 100) THEN + FArrayRecNum := 0; + END; + NRecNo(F,FName,DirFileRecNum); + END; + Close(DirFile); + Close(VerbF); + END; + END; + +BEGIN + FArea := 1; + WHILE (FArea <= NumFileAreas) DO + BEGIN + SearchFileAreaSpec(FArea,FName,FArrayRecNum); + Inc(FArea); + END; +END; + +BEGIN +END. \ No newline at end of file diff --git a/SOURCE/UNUSED/RGINTRO.ANS b/SOURCE/UNUSED/RGINTRO.ANS new file mode 100644 index 0000000..bff568d --- /dev/null +++ b/SOURCE/UNUSED/RGINTRO.ANS @@ -0,0 +1,19 @@ +[?7hĿ + Renegade Bulletin Board Sysop Upgrade  + +  Ŀ  +  Welcome to the Renegade Bulletin Board System  + Ĵ +  +  +  +  +  +  +  +  +  +  +      +      + diff --git a/SOURCE/UNUSED/RGLNG.EXE b/SOURCE/UNUSED/RGLNG.EXE new file mode 100644 index 0000000000000000000000000000000000000000..2e0276f5d81a0b57951227b3a670c2a905fbe130 GIT binary patch literal 28272 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 F`yW~gE&%`l literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGLNG.TXT b/SOURCE/UNUSED/RGLNG.TXT new file mode 100644 index 0000000..cf0f58c --- /dev/null +++ b/SOURCE/UNUSED/RGLNG.TXT @@ -0,0 +1,424 @@ +$Anonymous_String +^4[^0 Anonymous ^4] +$ + +$Echo_Char_For_Passwords + +$ + +$Engage_Chat +%LF^0Your SysOp, ^5%SN^0, is here to chat with you!%LF%LF +$ + +$End_Chat +%LF^0Welcome back to ^9%BN. +$ + +$SysOp_Working +^4[^0 Please Wait ^4]@ +$ + +$Pause +^4[^0 Press any key ^4]@ +$ + +$Enter_Message_Line_One +|03Press |11ENTER |03to get a |11BLANK LINE |03and press the following: +$ + +$Enter_Message_Line_Two +|03To Save: |11/S |03To Quote: |11/Q |03To Abort: |11/A |03Help: |11/? +$ + +$NewScan_Begin +%CL|09Scanning ... |01[|11%MB |01- |11%HM|01]@ +$ + +$NewScan_Done +@ +$ + +$Auto_Message_Title +^9AutoMessage posted here by: ^3 +$ + +$Auto_Message_Border_Characters + +$ + +$SysOp_Shelling_To_DOS +|09[|15 Please Wait |09]@ +$ + +$Read_Mail +%LF|09Read Mail (|14?|09=|14Help|09): @ +$ + +$Paging_SysOp +^9I will now attempt to call ^0%SN ^9to his computer! +$ + +$Chat_Call +|09[|11(|15<|14*|15>|11)|09] @ +$ + +$Bulletin_Prompt +^4Time Left [^3%TL^4] (^3?^4=^3Help^4) %LFBulletin Menu^2: @ +$ + +$Protocol_Prompt +|09Press |09[|11ENTER|09] to Transfer, [|11B|09]atch, [|11N|09]ext, [|11Q|09]uit|13: |00@ +$ + +$List_Files +|03List Files - |11P |03to Pause +$ + +$Search_For_New_Files +%LF|03Search for new files - +$ + +$Search_All_Dirs_For_File_Mask +|03Search all directories for a file name|01: |11 +$ + +$Search_For_Descriptions +|03Enter a description to search for|01: |01[|11No Wildcards!|01]|01: |11 +$ + +$Enter_The_String_To_Search_For +|03Press |01[|11ENTER|01] |03to abort.%LF|11 +$ + +$Download +%LF^3Download - from file area %FB^1. +%LF^4File name:^3 @ +$ + +$Upload +%LF^3Upload - to file area %FB^1. +%LF^4File name:^3 @ +$ + +$View_Interior_Files +%LF^3Enter the name of the archive(s) you would like to view:^1 +$ + +$Insufficient_File_Credits +^7You have insufficient file points to download this file!^1 +$ + +$Ratio_Is_Unbalanced +^7Your upload/download ratio is too poor to download this!^1 +$ + +$All_Files + +$ + +$File_Mask +|03Press |01[|11ENTER|01] |03For |11ALL |03Files|01: |11@ +$ + +$File_Added_To_Batch_Queue +%LF^5File added to batch download queue. +$ + +$Batch_Download_Flagging +%LF^3Enter filename(s) for addition to the batch queue. +%LF^4File name:^3 @ +$ + +$Read_Question_Prompt +^4[^5%MB^4]%LFBegin reading at [^51^4-^5%HM^4] (^5Q^4=^5Quit^4): @ +$ + +$System_Password_Prompt +%LF|03SysOp password|01: |11@ +$ + +$Default_Message_To +|03Press |01[|11ENTER|01] |03for |11ALL|03:%LF +$ + +$Newscan_All +|01[= |11Global NewScan Beginning |01=] +$ + +$Newscan_Done +%CL|01[= |11Global NewScan Completed |01=] +$ + +$Chat_Reason +^9%UN^0, State your reason for a Chat Session. +$ + +$User_Defined_Question_One +Is ALL of your information REAL & CORRECT? (Yes/No) +$ + +$User_Defined_Question_Two +Do you run a Telnet BBS? (If so, type in address below) +$ + +$User_Defined_Question_Three +What BBS or Web Site did you hear about this BBS? (Specific Please) +$ + +$User_Defined_Question_Editor_One +Info Real +$ + +$User_Defined_Question_Editor_Two +Telnet BBS +$ + +$User_Defined_Question_Editor_Three +Reference +$ + +$Continue_Prompt +|10 |15Continue: [^5Y^0]es, [N]o, [C]ontinuous: @ +$ + +$Invisible_Login +Invisible Login: @ +$ + +$Cant_Email +|11Can't send mail to that user. +$ + +$Send_Email +%CL^5User to send private message to (1-%UM)?^1 +$ + +$Sending_Mass_Mail_To +|01Sending mass-mail to: +$ + +$Sending_Mass_Mail_To_All_Users +|01Sending mass-mail to ALL USERS. +$ + +$No_Netmail +|01You are not allowed to send netmail. +$ + +$Netmail_Prompt +%LF|09Is this to be a netmail message? @ +$ + +$No_Mail_Waiting +%LF^5You have no mail waiting. +%PA +$ + +$Must_Read_Message +%LF^7Sorry, you must read and reply to (or delete) your mail!^1 +%PA +$ + +$Scan_For_New_Files + |11S|03can |11F|03or |11NEW |11F|03iles |11S|03ince |11MM|03/|11DD|03/|11YYYY|03: @ +$ + +$New_Scan_Char_File + +$ + +$Bulletins_Prompt +^5There are new bulletins read them: @ +$ + +$Quick_Logon +Quick Logon: @ +$ + +$Message_Area_Select_Header +%CL7Ŀ +78 Num 79 Name 78 Num 79 Name 7 +7 +$ + + +$File_Area_Select_Header +%CL-Ŀ +-. Num -/ Name -. Num -/ Name - +- +$ + +$Receive_Email_Header +%CLĿ + Num  Date/Time  Sender  Subject  + +$ + +$Vote_List_Topics_Header +%CL|03Ŀ +|11|17 Num |03|16|11|17Votes|03|16|11|17 Choice |03|16 + +$ + +$Vote_Topic_Result_Header +|03Ŀ +|11|17 N |03|16|11|17 % |03|16|11|17 Choice |03|16 + +$ + +$File_Area_Name_Header_No_Ratio +%CL Ŀ +  ##  File Name   Size   Description %FB{32  + +$ + +$File_Area_Name_Header_Ratio +%CL Ŀ +  ##  File Name  Pts  Size   Description %FB{30  + +$ + +$Sysop_Chat_Help +^5/BYE^3: Hang up +^5/CLS^3: Clear the screen +^5/PAGE^3: Page the SysOp and User +^5/Q^3: Exit chat mode%LF +$ + +$New_Scan_Char_Message + +$ + +$File_Area_Select_No_Files +%LF^7No file areas!^1 +$ + +$Message_Area_Select_No_Files +%LF^7No message areas!^1 +$ + +$Message_Area_List_Prompt +%LFMessage area list? [^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ +$ + +$File_Area_List_Prompt +%LFFile area list? [^5#^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ +$ + +$File_Message_Area_List_Help +%LF^1(^3###^1)Manual entry selection ^1(^3^1)Select current entry +^1(^3^1)First entry on page ^1(^3^1)Last entry on page +^1(^3Left Arrow^1)Previous entry ^1(^3Right Arrow^1)Next entry +^1(^3Up Arrow^1)Move up ^1(^3Down Arrow^1)Move down +^1(^3[^1)Previous page ^1(^3]^1)Next page +%PA +$ + +$File_Area_Change_Prompt +%LFChange file area? [^5#^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ +$ + +$Message_Area_Change_Prompt +%LFChange message area? [^5#^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ +$ + +$File_Area_New_Scan_Toggle_Prompt +%LFToggle new scan? [^5#^4,^5#^4-^5#^4,^5F^4=^5Flag ^4or ^5U^4=^5Unflag All^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ +$ + +$Message_Area_New_Scan_Toggle_Prompt +%LFToggle new scan? [^5#^4,^5#^4-^5#^4,^5F^4=^5Flag ^4or ^5U^4=^5Unflag All^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ +$ + +$File_Area_Move_File_Prompt +%LFMove to which file area? (^5%A1^4-^5%A2^4) [^5#^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ +$ + +$Message_Area_Move_Message_Prompt +%LFMove to which area? (^50^4=^5Private^4,^5%A3^4-^5%A3^4) [^5#^4,^5?^4=^5Help^4,^5Q^4=^5Quit^4]: @ +$ + +$File_Area_Change_Min_Max_Error +%LF^7The range must be from %A1 to %A2!^1 +%PA +$ + +$Message_Area_Change_Min_Max_Error +%LF^7The range must be from %A3 to %A4!^1 +%PA +$ + +$File_Area_Change_No_Area_Access +%LF^7You do not have access to this file area!^1 +%PA +$ + +$Message_Area_Change_No_Area_Access +%LF^7You do not have access to this message area!^1 +%PA +$ + +$File_Area_Change_Lowest_Area +%LFLowest accessible file area. +%PA +$ + +$File_Area_Change_Highest_Area +%LFHighest accessible file area. +%PA +$ + +$Message_Area_Change_Lowest_Area +%LFLowest accessible message area. +%PA +$ + +$Message_Area_Change_Highest_Area +%LFHighest accessible message area. +%PA +$ + +$File_Area_New_Scan_Scanning_All_Areas +%LFYou are now scanning all file areas. +%PA +$ + +$Message_Area_New_Scan_Scanning_All_Areas +%LFYou are now reading all message areas. +%PA +$ + +$File_Area_New_Scan_Not_Scanning_All_Areas +%LFYou are now not scanning any file areas. +%PA +$ + +$Message_Area_New_Scan_Not_Scanning_All_Areas +%LFYou are now not reading any message areas. +%PA +$ + +$File_Area_New_Scan_Min_Max_Error +%LF^7The range must be from %A1 to %A2!^1 +%PA +$ + +$Message_Area_New_Scan_Min_Max_Error +%LF^7The range must be from %A3 to %A4!^1 +%PA +$ + +$File_Area_New_Scan_Area_On_Off +%LF^5%FB^3 will %FSbe scanned. +%PA +$ + +$Message_Area_New_Scan_Area_On_Off +%LF^5%MB^3 will %MSbe scanned. +%PA +$ + +$Message_Area_New_Scan_Area_Not_Removed +%LF^5%MB^3 cannot be removed from your newscan. +%PA +$ \ No newline at end of file diff --git a/SOURCE/UNUSED/RGLNGNEW.TXT b/SOURCE/UNUSED/RGLNGNEW.TXT new file mode 100644 index 0000000..65ebaeb --- /dev/null +++ b/SOURCE/UNUSED/RGLNGNEW.TXT @@ -0,0 +1,288 @@ +$Anonymous_String +^4[^0 Anonymous ^4] +$ + +$Echo_Char_For_Passwords + +$ + +$Engage_Chat +%LF^0Your SysOp, ^5%SN^0, is here to chat with you!%LF%LF +$ + +$End_Chat +%LF^0Welcome back to ^9%BN. +$ + +$SysOp_Working +^4[^0 Please Wait ^4]@ +$ + +$Pause +^4[^0 Press any key ^4]@ +$ + +$Enter_Message_Line_One +|03Press |11ENTER |03to get a |11BLANK LINE |03and press the following: +$ + +$Enter_Message_Line_Two +|03To Save: |11/S |03To Quote: |11/Q |03To Abort: |11/A |03Help: |11/? +$ + +$NewScan_Begin +%CL|09Scanning ... |01[|11%MB |01- |11%HM|01]@ +$ + +$NewScan_Done +@ +$ + +$Auto_Message_Title +^9AutoMessage posted here by: ^3 +$ + +$Auto_Message_Border_Characters + +$ + +$SysOp_Shelling_To_DOS +|09[|15 Please Wait |09]@ +$ + +$Read_Mail +%LF|09Read Mail (|14?|09=|14Help|09): @ +$ + +$Paging_SysOp +^9I will now attempt to call ^0%SN ^9to his computer! +$ + +$Chat_Call +|09[|11(|15<|14*|15>|11)|09] @ +$ + + +$Bulletin_Prompt +^4Time Left [^3%TL^4] (^3?^4=^3Help^4) %LFBulletin Menu^2: @ +$ + +$Protocol_Prompt +|09Press |09[|11ENTER|09] to Transfer, [|11B|09]atch, [|11N|09]ext, [|11Q|09]uit|13: |00@ +$ + +$List_Files +|03List Files - |11P |03to Pause +$ + +$Search_For_New_Files +%LF|03Search for new files - +$ + +$Search_All_Dirs_For_File_Mask +|03Search all directories for a file name|01: |11 +$ + +$Search_For_Descriptions +|03Enter a description to search for|01: |01[|11No Wildcards!|01]|01: |11 +$ + +$Enter_The_String_To_Search_For +|03Press |01[|11ENTER|01] |03to abort.%LF|11 +$ + +$Download +%LF^3Download - from file area %FB^1. +%LF^4File name:^3 @ +$ + +$Upload +%LF^3Upload - to file area %FB^1. +%LF^4File name:^3 @ +$ + +$View_Interior_Files +%LF^3Enter the name of the archive(s) you would like to view:^1 +%LF^4File name:^3 @ +$ + +$Insufficient_File_Credits +^5You have insufficient file points to download this.^1 +$ + +$Ratio_Is_Unbalanced +^5Your upload/download ratio is too poor to download this.^1 +$ + +$All_Files + +$ + +$File_Mask +|03Press |01[|11ENTER|01] |03For |11ALL |03Files|01: |11@ +$ + +$File_Added_To_Batch_Queue +%LF^5File added to batch download queue. +$ + +$Batch_Download_Flagging +%LF^3Enter filename(s) for addition to the batch queue. +%LF^4File name:^3 @ +$ + +$Read_Question_Prompt +^4[^5%MB^4]%LFBegin reading at [^51^4-^5%HM^4] (^5Q^4=^5Quit^4): @ +$ + +$System_Password_Prompt +%LF|03SysOp Password|01: |11@ +$ + +$Default_Message_To +|03Press |01[|11ENTER|01] |03for |11ALL|03:%LF +$ + +$Newscan_All +|01[= |11Global NewScan Beginning |01=] +$ + +$Newscan_Done +%CL|01[= |11Global NewScan Completed |01=] +$ + +$Chat_Reason +^9%UN^0, State your reason for a Chat Session. +$ + +$User_Defined_Question_One +Is ALL of your information REAL & CORRECT? (Yes/No) +$ + +$User_Defined_Question_Two +Do you run a Telnet BBS? (If so, type in address below) +$ + +$User_Defined_Question_Three +What BBS or Web Site did you hear about this BBS? (Specific Please) +$ + +$User_Defined_Question_Editor_One +Info Real +$ + +$User_Defined_Question_Editor_Two +Telnet BBS +$ + +$User_Defined_Question_Editor_Three +Reference +$ + +$Continue_Prompt +|10 |15Continue: [^5Y^0]es, [N]o, [C]ontinuous: @ +$ + +$Invisible_Login +Invisible Login: @ +$ + +$Cant_Email +|11Can't send mail to that user. +$ + +$Send_Email +%CL^5User to send private message to (1-%UM)?^1 +$ + +$Sending_Mass_Mail_To +|01Sending mass-mail to: +$ + +$Sending_Mass_Mail_To_All_Users +|01Sending mass-mail to ALL USERS. +$ + +$No_Netmail +|01You are not allowed to send netmail. +$ + +$Netmail_Prompt +%LF|09Is this to be a netmail message? @ +$ + +$No_Mail_Waiting +%LF^5You have no mail waiting. +%PA +$ + +$Must_Read_Message +%LF^7Sorry, you must read and reply to (or delete) your mail!^1 +%PA +$ + +$Scan_For_New_Files + |11S|03can |11F|03or |11NEW |11F|03iles |11S|03ince |11MM|03/|11DD|03/|11YYYY|03: @ +$ + +$New_Scan_Char_File + +$ + +$Bulletins_Prompt +^5There are new bulletins read them: @ +$ + +$Quick_Logon +Quick Logon: @ +$ + +$Message_Area_Select_Header +%CL7Ŀ +78 Num 79 Name 78 Num 79 Name 7 +7 +$ + + +$File_Area_Select_Header +%CL-Ŀ +-. Num -/ Name -. Num -/ Name - +- +$ 12345678901234567890123456789012 1234567890123456789012345678901 + +$Receive_Email_Header +%CLĿ + Num  Date/Time  Sender  Subject  + +$ + +$Vote_List_Topics_Header +%CL|03Ŀ +|11|17 Num |03|16|11|17Votes|03|16|11|17 Choice |03|16 + +$ + +$Vote_Topic_Result_Header +|03Ŀ +|11|17 N |03|16|11|17 % |03|16|11|17 Choice |03|16 + +$ + +$File_Area_Name_Header_No_Ratio +%CL Ŀ +  ##  File Name   Size   Description %FB{32  + +$ + +$File_Area_Name_Header_Ratio +%CL Ŀ +  ##  File Name  Pts  Size   Description %FB{30  + +$ + +$Sysop_Chat_Help +^5/BYE^3: Hang up +^5/CLS^3: Clear the screen +^5/PAGE^3: Page the SysOp and User +^5/Q^3: Exit chat mode%LF +$ diff --git a/SOURCE/UNUSED/RGLNGPR.DAT b/SOURCE/UNUSED/RGLNGPR.DAT new file mode 100644 index 0000000000000000000000000000000000000000..e9331a614b5ed5f6db5e67de5f0538fb467bb550 GIT binary patch literal 760 zcmXxiJ8X?%7zgmDlsc_TX%Y9FRJBq^-8pV?siYbaQH`V#OFMPZ#vqo4MR0VnN`$aj z3{7f5=RzqW8k`OUSSp1&!bCQ34dEWDV&wKgahKN`tt7V?7k%KZQ>*b2%*lk%S zPo!VI$yup3MD%j!!iXM@smrV}`%N+XJYzRMavz)gxrtkNgd-g0YnD074gAYptjv!X z;5AnGl)27XX215vh-19K1H8xV`;MlJ_sr)T7es7jg=cu3C;5sS`H8uolKtd*|Nkzj zbG*hqe8ZgQH~V;~DWaLD*urx~JeD>VyBz1A!m;*^IYqNUzp$T9|b8xEC2ui literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGLNGTX.DAT b/SOURCE/UNUSED/RGLNGTX.DAT new file mode 100644 index 0000000000000000000000000000000000000000..e15a509cf63b83f56ed427e31509a27742716703 GIT binary patch literal 6167 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGMAIN.EXE b/SOURCE/UNUSED/RGMAIN.EXE new file mode 100644 index 0000000000000000000000000000000000000000..5b503cdbe0fed38fe5c38f9bda618567c38659dd GIT binary patch literal 7424 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 O '') AND (S[1] = '$') THEN + BEGIN + Delete(S,1,1); + S := AllCaps(S); + RGStrNum := -1; + IF (S = 'BAUD_OVERRIDE_PW') THEN + RGStrNum := 0 + ELSE IF (S = 'CALLER_LOGON') THEN + RGStrNum := 1 + ELSE IF (S = 'LOGON_AS_NEW') THEN + RGStrNum := 2 + ELSE IF (S = 'USER_LOGON_PASSWORD') THEN + RGStrNum := 3 + ELSE IF (S = 'USER_LOGON_PHONE_NUMBER') THEN + RGStrNum := 4 + ELSE IF (S = 'SYSOP_LOGON_PASSWORD') THEN + RGStrNum := 5 + ELSE IF (S = 'FORGOT_PW_QUESTION') THEN + RGStrNum := 6 + ELSE IF (S = 'VERIFY_BIRTH_DATE') THEN + RGStrNum := 7 + ELSE IF (S = 'LOGON_WITHDRAW_BANK') THEN + RGStrNum := 8 + ELSE IF (S = 'SHUTTLE_LOGON') THEN + RGStrNum := 9 + ELSE IF (S = 'NEW_USER_PASSWORD') THEN + RGStrNum := 10; + IF (RGStrNum = -1) THEN + BEGIN + WriteLn('Error!'); + WriteLn; + WriteLn(^G^G^G'The following string definition is invalid:'); + WriteLn; + WriteLn(' '+S); + Found := FALSE; + END + ELSE + BEGIN + Done := FALSE; + WITH StrPointer DO + BEGIN + Pointer := (FileSize(RGStrFile) + 1); + TextSize := 0; + END; + Seek(RGStrFile,FileSize(RGStrFile)); + WHILE NOT EOF(F) AND (NOT Done) DO + BEGIN + ReadLn(F,S); + IF (S[1] = '$') THEN + Done := TRUE + ELSE + BEGIN + Inc(StrPointer.TextSize,(Length(S) + 1)); + BlockWrite(RGStrFile,S,(Length(S) + 1)); + END; + END; + Seek(StrPointerFile,RGStrNum); + Write(StrPointerFile,StrPointer); + END; + END; + END; + Close(F); + Close(RGStrFile); + Close(StrPointerFile); + IF (Found) THEN + WriteLn('Done!') + ELSE + BEGIN + Erase(StrPointerFile); + Erase(RGStrFile); + END; +END. \ No newline at end of file diff --git a/SOURCE/UNUSED/RGMAIN.TXT b/SOURCE/UNUSED/RGMAIN.TXT new file mode 100644 index 0000000..86ec4c3 --- /dev/null +++ b/SOURCE/UNUSED/RGMAIN.TXT @@ -0,0 +1,46 @@ +$Baud_Override_PW +%LFBaud rate override password: @ +$ + +$Caller_Logon +%LF|01[|03Node |11%ND|01] |03Login|01: |11@ +$ + +$Logon_As_New +%LFLogon as new? @ +$ + +$User_Logon_Password +%LF|03Enter Password|01: |11@ +$ + +$User_Logon_Phone_Number +%LF|03Last 4 Digits of phone #|01: |08###-###-|11@ +$ + +$SysOp_Logon_Password +%LF|03SysOp Password|01: |11@ +$ + +$Forgot_PW_Question +%LF|03Please answer the following question to logon to the BBS. + +|03What is your mothers maiden name? +: @ +$ + +$Verify_Birth_Date +%LFPlease verify your date of birth (mm/dd/yyyy): @ +$ + +$Logon_Withdraw_Bank +Withdraw from Time Bank? @ +$ + +$Shuttle_Logon +%LF|01[|09Node %ND|01] |09Login|11: @ +$ + +$New_User_Password +%LF|03New User Password|01: @ +$ \ No newline at end of file diff --git a/SOURCE/UNUSED/RGMAINPR.DAT b/SOURCE/UNUSED/RGMAINPR.DAT new file mode 100644 index 0000000000000000000000000000000000000000..e862cac8b91c921bff9d04348e8b68ab55845c00 GIT binary patch literal 88 zcmZQ%U|>)JVr3xK0b+k376#%ZAeIB-1|T*D;>|z|;$H;fEFiXKWMD7>()mDI8c25m NX*D3d0Z4OzA;b^-0sIX#fv>?0pp_9a7OVo# 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 0) DO + Delete(S,Pos(' ',S),1); + SQOutSp := S; +END; + +FUNCTION Exist(fn: AStr): Boolean; +VAR + DirInfo: SearchRec; +BEGIN + FindFirst(SQOutSp(fn),AnyFile,DirInfo); + Exist := (DOSError = 0); +END; + +FUNCTION SYN(B: BOOLEAN): STRING; +BEGIN + IF (B) THEN + SYN := 'Yes' + ELSE + SYN := 'No '; +END; + +FUNCTION YN: BOOLEAN; +VAR + C: CHAR; +BEGIN + Write(SQOutSp(SYN(DYNY))); + REPEAT + C := UpCase(Char(ReadKey)); + UNTIL (C IN ['Y','N',^M]); + IF (DYNY) AND (C <> 'N') THEN + C := 'Y'; + IF (DYNY) AND (C = 'N') THEN + Write(#8#8#8'No ') + ELSE IF (NOT DYNY) AND (C = 'Y') THEN + Write(#8#8'Yes'); + WriteLn; + YN := (C = 'Y'); + DYNY := FALSE; +END; + +FUNCTION PYNQ(CONST S: AStr): BOOLEAN; +BEGIN + Write(S); + PYNQ := YN; +END; + +FUNCTION StrToInt(S: STRING): LongInt; +VAR + I: Integer; + L: LongInt; +BEGIN + Val(S,L,I); + IF (I > 0) THEN + BEGIN + S[0] := Chr(I - 1); + Val(S,L,I) + END; + IF (S = '') THEN + StrToInt := 0 + ELSE + StrToInt := L; +END; + +FUNCTION GetFileSize(FileName: AStr): LongInt; +VAR + F: FILE OF Byte; + FSize: LongInt; +BEGIN + FSize := 0; + IF (Exist(SQOutSp(FileName))) THEN + BEGIN + Assign(F,SQOutSp(FileName)); + Reset(F); + FSize := FileSize(F); + Close(F); + END; + GetFileSize := FSize; +END; + +PROCEDURE KillUserVotes(DataPath: STRING; VAR User: UserRecordType); +VAR + VotingFile: FILE OF VotingRecordType; + Topic: VotingRecordType; + Counter: Integer; +BEGIN + IF (Exist(DataPath+'VOTING.DAT')) THEN + BEGIN + Assign(VotingFile,DataPath+'VOTING.DAT'); + Reset(VotingFile); + FOR Counter := 1 TO FileSize(VotingFile) DO + IF (User.Vote[Counter] > 0) THEN + BEGIN + Seek(VotingFile,(Counter - 1)); + Read(VotingFile,Topic); + IF (Topic.NumVotedQuestion > 0) THEN + Dec(Topic.NumVotedQuestion); + IF (Topic.Answers[User.Vote[Counter]].NumVotedAnswer > 0) THEN + Dec(Topic.Answers[User.Vote[Counter]].NumVotedAnswer); + Seek(VotingFile,(Counter - 1)); + Write(VotingFile,Topic); + User.Vote[Counter] := 0; + END; + Close(VotingFile); + END; +END; + +PROCEDURE ResetVotes(DataPath: STRING); +VAR + VotingFile: FILE OF VotingRecordType; + Topic: VotingRecordType; + Counter, + Counter1: Integer; +BEGIN + IF (Exist(DataPath+'VOTING.DAT')) THEN + BEGIN + Assign(VotingFile,DataPath+'VOTING.DAT'); + Reset(VotingFile); + FOR Counter := 1 TO FileSize(VotingFile) DO + BEGIN + Seek(VotingFile,(Counter - 1)); + Read(VotingFile,Topic); + Topic.NumVotedQuestion := 0;; + FOR Counter1 := 1 TO 25 DO + Topic.Answers[Counter1].NumVotedAnswer := 0; + Seek(VotingFile,(Counter - 1)); + Write(VotingFile,Topic); + END; + Close(VotingFile); + END; +END; + +PROCEDURE ReScanUserVotes(DataPath: STRING; VAR User: UserRecordType); +VAR + VotingFile: FILE OF VotingRecordType; + Topic: VotingRecordType; + Counter: Integer; +BEGIN + IF (Exist(DataPath+'VOTING.DAT')) THEN + BEGIN + Assign(VotingFile,DataPath+'VOTING.DAT'); + Reset(VotingFile); + FOR Counter := 1 TO FileSize(VotingFile) DO + IF (User.Vote[Counter] > 0) THEN + BEGIN + Seek(VotingFile,(Counter - 1)); + Read(VotingFile,Topic); + Inc(Topic.NumVotedQuestion); + Inc(Topic.Answers[User.Vote[Counter]].NumVotedAnswer); + Seek(VotingFile,(Counter - 1)); + Write(VotingFile,Topic); + END; + Close(VotingFile); + END; +END; + +PROCEDURE KillShortMsgs(DataPath: STRING; VAR User: UserRecordType); +VAR + ShortMsgFile: FILE OF ShortMessageRecordType; + ShortMsg: ShortMessageRecordType; + Counter: Integer; +BEGIN + IF (Exist(DataPath+'SHORTMSG.DAT')) THEN + BEGIN + Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + FOR Counter := 1 TO FileSize(ShortMsgFile) DO + BEGIN + Seek(ShortMsgFile,(Counter - 1)); + Read(ShortMsgFile,ShortMsg); + IF (ShortMsg.Destin = User.UserID) THEN + ShortMsg.Destin := -1; + Seek(ShortMsgFile,(Counter - 1)); + Write(ShortMsgFile,ShortMsg); + END; + Close(ShortMsgFile); + END; +END; + +PROCEDURE UpdateShortMsgs(DataPath: STRING; VAR User: UserRecordType; NewUserNumber: Integer); +VAR + ShortMsgFile: FILE OF ShortMessageRecordType; + ShortMsg: ShortMessageRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'SHORTMSG.DAT') THEN + BEGIN + Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + FOR Counter := 1 TO FileSize(ShortMsgFile) DO + BEGIN + Seek(ShortMsgFile,(Counter - 1)); + Read(ShortMsgFile,ShortMsg); + IF (ShortMsg.Destin = User.UserID) THEN + ShortMsg.Destin := NewUserNumber; + Seek(ShortMsgFile,(Counter - 1)); + Write(ShortMsgFile,ShortMsg); + END; + Close(ShortMsgFile); + END; +END; + +PROCEDURE PurgingShortMsgs(DataPath: STRING); +VAR + ShortMsgFile: FILE OF ShortMessageRecordType; + ShortMsgFile1: FILE OF ShortMessageRecordType; + ShortMsg: ShortMessageRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'SHORTMSG.DAT') THEN + BEGIN + Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + Assign(ShortMsgFile1,DataPath+'SHORTMSG.BAK'); + ReWrite(ShortMsgFile1); + FOR Counter := 1 TO FileSize(ShortMsgFile) DO + BEGIN + Seek(ShortMsgFile,(Counter - 1)); + Read(ShortMsgFile,ShortMsg); + IF (ShortMsg.Destin <> -1) THEN + BEGIN + Seek(ShortMsgFile1,FileSize(ShortMsgFile1)); + Write(ShortMsgFile1,ShortMsg); + END; + END; + Close(ShortMsgFile); + Erase(ShortMsgFile); + Close(ShortMsgFile1); + ReName(ShortMsgFile1,DataPath+'SHORTMSG.DAT'); + END; +END; + +PROCEDURE KillBatchQueue(DataPath: STRING; VAR User: UserRecordType); +VAR + BatchDLFile: FILE OF BatchDlRecordType; + BatchDL: BatchDlRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'BATCHDL.DAT') THEN + BEGIN + Assign(BatchDLFile,DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + FOR Counter := 1 TO FileSize(BatchDLFile) DO + BEGIN + Seek(BatchDLFile,(Counter - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = User.UserID) THEN + BatchDL.BDLUserNum := -1; + Seek(BatchDLFile,(Counter - 1)); + Write(BatchDLFile,BatchDL); + END; + Close(BatchDLFile); + END; +END; + +PROCEDURE UpdateBatchQueue(DataPath: STRING; VAR User: UserRecordType; NewUserNumber: Integer); +VAR + BatchDLFile: FILE OF BatchDLRecordType; + BatchDL: BatchDlRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'BATCHDL.DAT') THEN + BEGIN + Assign(BatchDLFile,DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + FOR Counter := 1 TO FileSize(BatchDLFile) DO + BEGIN + Seek(BatchDLFile,(Counter - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = User.UserID) THEN + BatchDL.BDLUserNum := NewUserNumber; + Seek(BatchDLFile,(Counter - 1)); + Write(BatchDLFile,BatchDL); + END; + Close(BatchDLFile); + END; +END; + +PROCEDURE PurgingBatchQueue(DataPath: STRING); +VAR + BatchDLFile: FILE OF BatchDLRecordType; + BatchDLFile1: FILE OF BatchDLRecordType; + BatchDL: BatchDLRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'BATCHDL.DAT') THEN + BEGIN + Assign(BatchDLFile,DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + Assign(BatchDLFile1,DataPath+'BATCHDL.BAK'); + ReWrite(BatchDLFile1); + FOR Counter := 1 TO FileSize(BatchDLFile) DO + BEGIN + Seek(BatchDLFile,(Counter - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum <> -1) THEN + BEGIN + Seek(BatchDLFile1,FileSize(BatchDLFile1)); + Write(BatchDLFile1,BatchDL); + END; + END; + Close(BatchDLFile); + Erase(BatchDLFile); + Close(BatchDLFile1); + ReName(BatchDLFile1,DataPath+'BATCHDL.DAT'); + END; +END; + +PROCEDURE KillUserEMail(DataPath,MsgPath: STRING; VAR User: UserRecordType); +VAR + MsgHdrF: FILE OF MHeaderRec; + MHeader: MHeaderRec; + MsgNum: Word; +BEGIN + IF (Exist(MsgPath+'EMAIL.HDR')) THEN + BEGIN + Assign(MsgHdrF,MsgPath+'EMAIL.HDR'); + Reset(MsgHdrF); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF ((MHeader.MTO.UserNum = User.UserID) OR (MHeader.From.UserNum = User.UserID)) THEN + Include(MHeader.Status,MDeleted); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := 0; + IF (MHeader.FROM.UserNum = User.UserID) THEN + MHeader.FROM.UserNum := 0; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + User.Waiting := 0; + END; +END; + +PROCEDURE UpdateUserEMail(MsgPath: STRING; VAR User: UserRecordType; NewUserNum: Integer); +VAR + MsgHdrF: FILE OF MHeaderRec; + MHeader: MHeaderRec; + MsgNum: Word; +BEGIN + IF (Exist(MsgPath+'EMAIL.HDR')) THEN + BEGIN + Assign(MsgHdrF,MsgPath+'EMAIL.HDR'); + Reset(MsgHdrF); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := NewUserNum; + IF (MHeader.From.UserNum = User.UserID) THEN + MHeader.From.UserNum := NewUserNum; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + END; +END; + +PROCEDURE ReScanUserEMail(MsgPath: STRING; VAR User: UserRecordType; UserNum: Integer); +VAR + MsgHdrF: FILE OF MHeaderRec; + MHeader: MHeaderRec; + MsgNum: Word; +BEGIN + IF (Exist(MsgPath+'EMAIL.HDR')) THEN + BEGIN + User.Waiting := 0; + Assign(MsgHdrF,MsgPath+'EMAIL.HDR'); + Reset(MsgHdrF); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = UserNum) THEN + IF (NOT (MDeleted IN MHeader.Status)) THEN + Inc(User.Waiting); + END; + Close(MsgHdrF); + END; +END; + +PROCEDURE UpdateDIRFilesDeletedUsers(DataPath: STRING; User,SysOpUser: UserRecordType); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: FILE OF FileInfoRecordType; + FileArea: FileAreaRecordType; + VerbF: FILE; + F: FileInfoRecordType; + Counter, + Counter1: Integer; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(VerbF,FileArea.DLPath+FileArea.FileName+'.EXT') + ELSE + Assign(VerbF,Datapath+FileArea.FileName+'.EXT'); + Reset(VerbF,1); + IF (IOResult = 2) THEN + ReWrite(VerbF,1); + FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO + BEGIN + Seek(DirFile,Counter1); + Read(DirFile,F); + IF (F.OwnerNum = User.UserID) THEN + BEGIN + F.OwnerNum := SysOpUser.UserID; + F.OwnerName := AllCaps(SysOpUser.Name); + END; + Seek(DirFile,Counter1); + Write(DirFile,F); + END; + Close(DirFile); + Close(VerbF); + END; + Close(FileAreaFile); +END; + +PROCEDURE UpdateDIRFilesExistingUsers(DataPath: STRING; User: UserRecordType; NewUserNum: Integer); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: FILE OF FileInfoRecordType; + VerbF: FILE; + FileArea: FileAreaRecordType; + F: FileInfoRecordType; + Counter, + Counter1: Integer; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(VerbF,FileArea.Dlpath+FileArea.FileName+'.EXT') + ELSE + Assign(VerbF,Datapath+FileArea.FileName+'.EXT'); + Reset(VerbF,1); + IF (IOResult = 2) THEN + ReWrite(VerbF,1); + FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO + BEGIN + Seek(DirFile,Counter1); + Read(DirFile,F); + IF (F.OwnerNum = User.UserID) THEN + F.OwnerNum := NewUserNum; + Seek(DirFile,Counter1); + Write(DirFile,F); + END; + Close(DirFile); + Close(VerbF); + END; + Close(FileAreaFile); +END; + +PROCEDURE UpdateDIRFileSize(DataPath: STRING); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: FILE OF FileInfoRecordType; + FileArea: FileAreaRecordType; + VerbF: FILE; + F: FileInfoRecordType; + Counter, + Counter1: Integer; + FSize: Longint; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(VerbF,FileArea.Dlpath+FileArea.FileName+'.EXT') + ELSE + Assign(VerbF,Datapath+FileArea.FileName+'.EXT'); + Reset(VerbF,1); + IF (IOResult = 2) THEN + ReWrite(VerbF,1); + FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO + BEGIN + Seek(DirFile,Counter1); + Read(DirFile,F); + FSize := GetFileSize(FileArea.DLPath+F.FileName); + IF (FSize = 0) THEN + BEGIN + F.FileSize := 0; + Include(F.FIFlags,FIIsRequest); + END + ELSE + F.FileSize := FSize; + Seek(DirFile,Counter1); + Write(DirFile,F); + END; + Close(DirFile); + Close(VerbF); + END; + Close(FileAreaFile); +END; + +PROCEDURE UpdateFileSCNFilesExistingUsers(DataPath: STRING); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + UserFile: FILE OF UserRecordType; + UserFile2: FILE OF UserRecordType; + ScnFile: FILE OF Boolean; + ScnFile1: FILE OF Boolean; + FileArea: FileAreaRecordType; + User: UserRecordType; + Path: STRING; + Counter, + Counter1, + NumUsers: Integer; + NewScanFBase: Boolean; +BEGIN + Assign(UserFile,DataPath+'USERS.DAT'); + Reset(UserFile); + Assign(UserFile2,DataPath+'USERS.BAK'); + Reset(UserFile2); + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Path := FileArea.Dlpath+FileArea.FileName + ELSE + Path := Datapath+FileArea.FileName; + Assign(ScnFile,Path+'.SCN'); + Reset(ScnFile); + IF (IOResult = 2) THEN + ReWrite(ScnFile); + Assign(ScnFile1,Path+'.SCB'); + ReWrite(ScnFile1); + NumUsers := (FileSize(UserFile) - 1); + IF (NumUsers > FileSize(ScnFile)) THEN + BEGIN + Seek(ScnFile,FileSize(ScnFile)); + NewScanFBase := TRUE; + FOR Counter1 := FileSize(ScnFile) TO (NumUsers - 1) DO + Write(ScnFile,NewScanFBase); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(ScnFile1,FileSize(ScnFile1)); + NewScanFBase := TRUE; + Write(ScnFile1,NewScanFBase); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter1); + Read(UserFile2,User); + Seek(ScnFile,(User.UserID - 1)); + Read(ScnFile,NewScanFBase); + Seek(ScnFile1,(Counter1 - 1)); + Write(ScnFile1,NewScanFBase); + END; + Close(ScnFile); + Erase(ScnFile); + Close(ScnFile1); + ReName(ScnFile1,Path+'.SCN'); + END; + Close(FileAreaFile); + Close(UserFile); + Close(UserFile2); +END; + +PROCEDURE UpdateMsgFilesDeletedUsers(DataPath,MsgPath: STRING; User: UserRecordType); +VAR + MsgAreaFile: FILE OF MessageAreaRecordType; + MsgHdrF: FILE OF MHeaderRec; + MsgTxtF: FILE; + MsgArea: MessageAreaRecordType; + MHeader: MHeaderRec; + Counter: Integer; + MsgNum: Word; +BEGIN + Assign(MsgAreaFile,DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + FOR Counter := 0 TO (FileSize(MsgAreaFile) - 1) DO + BEGIN + Seek(MsgAreaFile,Counter); + Read(MsgAreaFile,MsgArea); + Assign(MsgHdrF,MsgPath+MsgArea.FileName+'.HDR'); + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + Assign(MsgTxtF,MsgPath+MsgArea.FileName+'.DAT'); + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := 0; + IF (MHeader.From.UserNum = User.UserID) THEN + MHeader.From.UserNum := 0; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + Close(MsgTxtF); + END; + Close(MsgAreaFile); +END; + +PROCEDURE UpdateMsgFilesExistingUsers(DataPath,MsgPath: STRING; User: UserRecordType; NewUserNum: Integer); +VAR + MsgAreaFile: FILE OF MessageAreaRecordType; + MsgHdrF: FILE OF MHeaderRec; + MsgTxtF: FILE; + MsgArea: MessageAreaRecordType; + MHeader: MHeaderRec; + Counter: Integer; + MsgNum: Word; +BEGIN + Assign(MsgAreaFile,DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + FOR Counter := 0 TO (FileSize(MsgAreaFile) - 1) DO + BEGIN + Seek(MsgAreaFile,Counter); + Read(MsgAreaFile,MsgArea); + Assign(MsgHdrF,MsgPath+MsgArea.FileName+'.HDR'); + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + Assign(MsgTxtF,MsgPath+MsgArea.FileName+'.DAT'); + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := NewUserNum; + IF (MHeader.From.UserNum = User.UserID) THEN + MHeader.From.UserNum := NewUserNum; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + Close(MsgTxtF); + END; + Close(MsgAreaFile); +END; + +PROCEDURE UpdateMsgSCNFilesExistingUsers(DataPath,MsgPath: STRING); +VAR + MessageFile: FILE OF MessageAreaRecordType; + UserFile: FILE OF UserRecordType; + UserFile2: FILE OF UserRecordType; + MsgScanFile: FILE OF ScanRec; + MsgScanFile1: FILE OF ScanRec; + MsgArea: MessageAreaRecordType; + User: UserRecordType; + LastReadRecord: ScanRec; + Path: STRING; + Counter, + Counter1, + NumUsers: Integer; +BEGIN + Assign(UserFile,DataPath+'USERS.DAT'); + Reset(UserFile); + Assign(UserFile2,DataPath+'USERS.BAK'); + Reset(UserFile2); + Assign(MessageFile,DataPath+'MBASES.DAT'); + Reset(MessageFile); + FOR Counter := 0 TO (FileSize(MessageFile) - 1) DO + BEGIN + Seek(MessageFile,Counter); + Read(MessageFile,MsgArea); + Path := MsgPath+MsgArea.FileName; + Assign(MsgScanFile,Path+'.SCN'); + Reset(MsgScanFile); + IF (IOResult = 2) THEN + ReWrite(MsgScanFile); + Assign(MsgScanFile1,Path+'.SCB'); + ReWrite(MsgScanFile1); + NumUsers := (FileSize(UserFile) - 1); + IF (NumUsers > FileSize(MsgScanFile)) THEN + BEGIN + WITH LastReadRecord DO + BEGIN + LastRead := 0; + NewScan := TRUE; + END; + Seek(MsgScanFile,FileSize(MsgScanFile)); + FOR Counter1 := FileSize(MSGScanFile) TO (NumUsers - 1) DO + Write(MsgScanFile,LastReadRecord); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + WITH LastReadRecord DO + BEGIN + LastRead := 0; + NewScan := TRUE; + END; + Seek(MsgScanFile1,FileSize(MsgScanFile1)); + Write(MsgScanFile1,LastReadRecord); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter1); + Read(UserFile2,User); + Seek(MsgScanFile,(User.UserID - 1)); + Read(MsgScanFile,LastReadRecord); + Seek(MsgScanFile1,(Counter1 - 1)); + Write(MsgScanFile1,LastReadRecord); + END; + Close(MsgScanFile); + Erase(MsgScanFile); + Close(MsgScanFile1); + ReName(MsgScanFile1,Path+'.SCN'); + END; + Close(MessageFile); + Close(UserFile); + Close(UserFile2); +END; + +PROCEDURE PackMessageArea(MsgPath,FN: STRING; MaxM: LongInt); +VAR + Buffer: ARRAY [1..4096] OF Char; + MsgHdrF1, + MsgHdrF2: FILE OF MheaderRec; + BrdF1, + BrdF2: FILE; + MHeader: MheaderRec; + Numm, + i, + IDX, + TotLoad, + Buffered: Word; + NeedPack: Boolean; + + PROCEDURE ErrMsg; + BEGIN + Writeln('Error renaming temp files while packing.'); + END; + + PROCEDURE Kill(CONST FN: AStr); + VAR + F: FILE; + BEGIN + IF Exist(FN) THEN + BEGIN + Assign(F,FN); + Erase(F); + END; + END; + +BEGIN + NeedPack := FALSE; + FN := AllCaps(FN); + FN := MsgPath + FN; + + Assign(BrdF1,FN+'.DAT'); + Reset(BrdF1,1); + IF (IOResult <> 0) THEN + Exit; + + Assign(MsgHdrF1,FN+'.HDR'); + Reset(MsgHdrF1); + + IF (IOResult <> 0) THEN + BEGIN + Close(BrdF1); + Exit + END; + + IF (MaxM <> 0) AND (FileSize(MsgHdrF1) > MaxM) THEN + BEGIN + Numm := 0; + IDX := FileSize(MsgHdrF1); + WHILE (IDX > 0) DO + BEGIN + Seek(MsgHdrF1,(IDX - 1)); + Read(MsgHdrF1,MHeader); + IF NOT (MDeleted IN MHeader.Status) THEN + Inc(Numm); + IF (Numm > MaxM) AND NOT (Permanent IN MHeader.Status) THEN + BEGIN + MHeader.Status := [MDeleted]; + Seek(MsgHdrF1,(IDX - 1)); + Write(MsgHdrF1,MHeader); + END; + Dec(IDX); + END; + END + ELSE + BEGIN + + WHILE (FilePos(MsgHdrF1) < FileSize(MsgHdrF1)) AND (NOT NeedPack) DO + BEGIN + Read(MsgHdrF1,MHeader); + IF (MDeleted IN MHeader.Status) THEN + NeedPack := TRUE; + END; + + IF (NOT NeedPack) THEN + BEGIN + Close(MsgHdrF1); + Close(BrdF1); + Exit; + END; + END; + + Assign(BrdF2,FN+'.DA1'); + ReWrite(BrdF2,1); + + Assign(MsgHdrF2,FN+'.HD2'); + ReWrite(MsgHdrF2); + + Kill(FN+'.HD3'); + Kill(FN+'.DA3'); + + IDX := 1; + i := 0; + + WHILE (i <= FileSize(MsgHdrF1) - 1) DO + BEGIN + Seek(MsgHdrF1,i); + Read(MsgHdrF1,MHeader); + + IF (MHeader.Pointer - 1 + MHeader.TextSize > FileSize(BrdF1)) OR + (MHeader.Pointer < 1) THEN + MHeader.Status := [MDeleted]; + + IF NOT (MDeleted IN MHeader.Status) THEN + BEGIN + Inc(IDX); + Seek(BrdF1,MHeader.Pointer - 1); + MHeader.Pointer := (FileSize(BrdF2) + 1); + Write(MsgHdrF2,MHeader); + + TotLoad := 0; + IF (MHeader.TextSize > 0) THEN + WHILE (MHeader.TextSize > 0) DO + BEGIN + Buffered := MHeader.TextSize; + IF (Buffered > 4096) THEN + Buffered := 4096; + Dec(MHeader.TextSize,Buffered); + BlockRead(BrdF1,Buffer[1],Buffered); + BlockWrite(BrdF2,Buffer[1],Buffered); + END; + END; + Inc(i); + END; + + Close(BrdF1); + Close(BrdF2); + Close(MsgHdrF1); + Close(MsgHdrF2); + + ReName(BrdF1,FN+'.DA3'); { ReName .DAT to .DA3 } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + Exit; + END; + + ReName(BrdF2,FN+'.DAT'); { ReName .DA2 to .DAT } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + Exit; + END; + + ReName(MsgHdrF1,FN+'.HD3'); { ReName .HDR to .HD3 } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + Erase(BrdF2); { Erase .DA2 } + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + Exit; + END; + + ReName(MsgHdrF2,FN+'.HDR'); { ReName .HD2 to .HDR } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + Erase(BrdF2); { Erase .DAT (new) } + Erase(MsgHdrF2); { Erase .HD2 (new) } + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + ReName(MsgHdrF1,FN+'.HDR'); { ReName .HD3 to .HDR } + Exit; + END; + + Erase(MsgHdrF1); + Erase(BrdF1); +END; + +PROCEDURE PackMessageAreas(DataPath,MsgPath: STRING); +VAR + MsgAreaFile: FILE OF MessageAreaRecordType; + MsgArea: MessageAreaRecordType; + MArea: Integer; +BEGIN + PackMessageArea(MsgPath,'EMAIL',0); + Assign(MsgAreaFile,DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + FOR MArea := 0 TO (FileSize(MsgAreaFile) - 1) DO + BEGIN + Seek(MsgAreaFile,MArea); + Read(MsgAreaFile,MsgArea); + PackMessageArea(MsgPath,MsgArea.FileName,MsgArea.MaxMsgs); + END; + Close(MsgAreaFile); +END; + +PROCEDURE SortFileArea(VAR DirFile1: DirF; NumFiles: Integer); +VAR + F1, + F2: FileInfoRecordType; + NumSorted, + RecNum, + RecNum1, + Gap: Integer; +BEGIN + Gap := NumFiles; + REPEAT; + Gap := (Gap DIV 2); + IF (Gap = 0) THEN + Gap := 1; + NumSorted := 0; + FOR RecNum := 1 TO (NumFiles - Gap) DO + BEGIN + RecNum1 := (RecNum + Gap); + Seek(DirFile1,(RecNum - 1)); + Read(DirFile1,F1); + Seek(DirFile1,(RecNum1 - 1)); + Read(DirFile1,F2); + IF (F1.FileName > F2.FileName) THEN + BEGIN + Seek(DirFile1,(RecNum - 1)); + Write(DirFile1,F2); + Seek(DirFile1,(RecNum1 - 1)); + Write(DirFile1,F1); + Inc(NumSorted); + END; + END; + UNTIL (NumSorted = 0) AND (Gap = 1); +END; + +PROCEDURE SortAllFileAreas(DataPath: STRING); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: DirF; + FileArea: FileAreaRecordType; + F: FileInfoRecordType; + NumFiles, + Counter: Integer; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + NumFiles := FileSize(DirFile); + IF (NumFiles <> 0) THEN + SortFileArea(DirFile,NumFiles); + Close(DirFile); + END; + Close(FileAreaFile); +END; + +PROCEDURE InsertIndex(VAR UserIndexFile1: SF; Uname: AStr; UserNum: Integer; IsReal,IsDeleted: Boolean); +VAR + IndexR: UserIDXRec; + Current, + InsertAt: Integer; + Done: Boolean; + + PROCEDURE WriteIndex; + BEGIN + FillChar(IndexR,SizeOf(IndexR),0); + WITH IndexR DO + BEGIN + Name := Uname; + Number := UserNum; + RealName := IsReal; + Deleted := IsDeleted; + Left := -1; + Right := -1; + Write(UserIndexFile1,IndexR); + END + END; + +BEGIN + Done := FALSE; + Uname := Allcaps(Uname); + Current := 0; + Reset(UserIndexFile1); + IF (FileSize(UserIndexFile1) = 0) THEN + WriteIndex + ELSE + REPEAT + Seek(UserIndexFile1,Current); + InsertAt := Current; + Read(UserIndexFile1,IndexR); + IF (Uname < IndexR.Name) THEN + Current := IndexR.Left + ELSE IF (Uname > IndexR.Name) THEN + Current := IndexR.Right + ELSE IF (IndexR.Deleted <> IsDeleted) THEN + BEGIN + Done := TRUE; + IndexR.Deleted := IsDeleted; + IndexR.RealName := IsReal; + IndexR.Number := UserNum; + Seek(UserIndexFile1,Current); + Write(UserIndexFile1,IndexR); + END + ELSE + BEGIN + IF (UserNum <> IndexR.Number) THEN + WriteLn('Note: Duplicate user '+UName+' #'+IntToStr(IndexR.Number)+' and '+UName+' #'+IntToStr(UserNum)) + ELSE + BEGIN + IndexR.RealName := FALSE; + Seek(UserIndexFile1,Current); { Make it be his handle IF it's BOTH } + Write(UserIndexFile1,IndexR); + END; + Done := TRUE; + END; + UNTIL (Current = -1) OR (Done); + IF (Current = -1) THEN + BEGIN + IF (Uname < IndexR.Name) THEN + IndexR.Left := FileSize(UserIndexFile1) + ELSE + IndexR.Right := FileSize(UserIndexFile1); + Seek(UserIndexFile1,InsertAt); + Write(UserIndexFile1,IndexR); + Seek(UserIndexFile1,FileSize(UserIndexFile1)); + WriteIndex; + END; + Close(UserIndexFile1); +END; + +PROCEDURE PackUsers; +VAR + GeneralFile: FILE OF GeneralRecordType; + UserFile: FILE OF UserRecordType; + UserFile1: FILE OF UserRecordType; + UserFile2: FILE OF UserRecordType; + UserIndexFile: SF; + F: FILE; + General: GeneralRecordType; + User, + SysOpUser: UserRecordType; + DeleteDateStr: STRING; + TotalUsers, + Counter: Integer; + Year: Word; + PackedDeleteDate: LongInt; + UsersToDelete, + DeleteByDate, + InvalidDate: Boolean; +BEGIN + DeleteByDate := FALSE; + + IF (ParamCount > 0) THEN + FOR Counter := 1 TO ParamCount DO + IF (AllCaps(Copy(ParamStr(Counter),1,2)) = AllCaps('-D')) THEN + BEGIN + DeleteDateStr := Copy(ParamStr(Counter),3,Length(ParamStr(Counter))); + InvalidDate := FALSE; + IF (Length(DeleteDateStr) <> 10) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) = 0) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) > 12) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,4,2)) = 0) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) IN [1,3,5,7,8,10,12]) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 31) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) IN [4,6,9,11]) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 30) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) = 2) AND ((StrToInt(Copy(DeleteDateStr,7,4)) MOD 4) <> 0) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 28) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) = 2) AND ((StrToInt(Copy(DeleteDateStr,7,4)) MOD 4) = 0) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 29) THEN + InvalidDate := TRUE; + GetYear(Year); + IF (StrToInt(Copy(DeleteDateStr,7,4)) > Year) THEN + InvalidDate := TRUE; + + IF (InvalidDate) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'Invalid date or format, valid format is "00/00/0000'); + Exit; + END + ELSE + BEGIN + PackedDeleteDate := Date2PD(DeleteDateStr); + DeleteByDate := TRUE; + END; + END; + + ClrScr; + WriteLn('Renegade User Packer Version 2.0'); + Writeln('Copyright 2009 - The Renegade Developement Team'); + WriteLn; + Writeln('This utility will pack your Renegade BBS Version 1.0'); + WriteLn('USERS.DAT file and update all required data files.'); + WriteLn; + WriteLn('User''s to be packed:'); + WriteLn(' - All user''s currently marked for deletion'); + IF (DeleteByDate) THEN + WriteLn(' - All user''s that have not logged on since '+DeleteDateStr); + WriteLn; + WriteLn('This process could take awhile depending on the total number'); + WriteLn('of files on your BBS that require update.'); + WriteLn; + IF PYNQ('Do you wish to continue? ') THEN + BEGIN + WriteLn; + IF (NOT Exist('RENEGADE.DAT')) THEN + WriteLn('This utility must be executed in the same directory as RENEGADE.DAT!') + ELSE + BEGIN + Write('Reading RENEGADE.DAT ... '); + Assign(GeneralFile,'RENEGADE.DAT'); + Reset(GeneralFile); + Read(GeneralFile,General); + Close(GeneralFile); + WriteLn('Done!'); + + WriteLn; + Write('Checking USERS.DAT for user''s to pack ... '); + Assign(UserFile,General.DataPath+'USERS.DAT'); + Reset(UserFile); + UsersToDelete := FALSE; + Counter := 2; + WHILE (Counter <= (FileSize(UserFile) - 1)) AND (NOT UsersToDelete) DO + BEGIN + Seek(UserFile,Counter); + Read(UserFile,User); + IF (Deleted IN User.SFlags) OR (DeleteByDate) AND (NOT (FNoDeletion IN User.Flags)) + AND (User.LastOn < PackedDeleteDate) THEN + UsersToDelete := TRUE; + Inc(Counter); + END; + WriteLn('Done!'); + + IF (NOT UsersToDelete) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'No deleted user''s found to pack!'); + END + ELSE + BEGIN + + Write('Updating USERS.DAT "UserID" with record number for all user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile) - 1) DO + BEGIN + Seek(UserFile,Counter); + Read(UserFile,User); + User.UserID := Counter; + Seek(UserFile,Counter); + Write(UserFile,User); + END; + WriteLn('Done!'); + + Write('Locating deleted user''s and creating USERS.DEL and USERS.BAK ... '); + Assign(UserFile1,General.DataPath+'USERS.DEL'); + ReWrite(UserFile1); + Assign(UserFile2,General.DataPath+'USERS.BAK'); + ReWrite(UserFile2); + Seek(UserFile,0); + Read(UserFile,User); + User.UserID := 0; + Seek(UserFile2,FileSize(UserFile2)); + Write(UserFile2,User); + Seek(UserFile,1); + Read(UserFile,User); + User.UserID := 1; + Seek(UserFile2,FileSize(UserFile2)); + Write(UserFile2,User); + FOR Counter := 2 TO (FileSize(UserFile) - 1) DO + BEGIN + Seek(UserFile,Counter); + Read(UserFile,User); + IF (Deleted IN User.SFlags) OR (DeleteByDate) AND (NOT (FNoDeletion IN User.Flags)) + AND (User.LastOn < PackedDeleteDate) THEN + BEGIN + Seek(UserFile1,FileSize(UserFile1)); + Write(UserFile1,User); + END + ELSE + BEGIN + Seek(UserFile2,FileSize(UserFile2)); + Write(UserFile2,User); + END; + END; + Close(UserFile); + Close(UserFile2); + WriteLn('Done!'); + + Write('Removing voting records for deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillUserVotes(General.DataPath,User); + Seek(UserFile1,Counter); + Write(UserFile1,User); + END; + WriteLn('Done!'); + + Write('Setting SHORTMSG.DAT "Destin" to -1 for deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillShortMsgs(General.DataPath,User); + END; + WriteLn('Done!'); + + Write('Updating SHORTMSG.DAT "Destin" with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateShortMsgs(General.DataPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + (* + Write('Setting BATCHDL.DAT "BDLUserNum" to -1 for all deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillBatchQueue(General.DataPath,User); + END; + WriteLn('Done!'); + + Write('Updating BATCHDL.DAT "BDLUserNum" with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateBatchQueue(General.DataPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Setting EMAIL.HDR "MDeleted" for email to/from deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillUserEMail(General.DataPath,General.MsgPath,User); + Seek(UserFile1,Counter); + Write(UserFile1,User); + END; + WriteLn('Done!'); + + Write('Updating EMAIL.HDR "MTO/FROM" with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateUserEMail(General.MsgPath,User,Counter); + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Updating *.DIR files with sysop name/number for all deleted user''s ... '); + Assign(UserFile2,General.DataPath+'USERS.BAK'); + Reset(UserFile2); + Seek(UserFile2,1); + Read(UserFile2,SysOpUser); + Close(UserFile2); + Reset(UserFile1); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + UpdateDIRFilesDeletedUsers(General.DataPath,User,SysOpUser); + END; + WriteLn('Done!'); + + Write('Updating *.DIR files with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateDIRFilesExistingUsers(General.DataPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Setting *.HDR files "MTO/FROM" to 0 for all deleted user''s ... '); + Reset(UserFile1); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + UpdateMsgFilesDeletedUsers(General.DataPath,General.MsgPath,User); + END; + WriteLn('Done!'); + + Write('Updating *.HDR files with new user number for existing user''s ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateMsgFilesExistingUsers(General.DataPath,General.MsgPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Updating file area scan flags for existing user''s ... '); + UpdateFileSCNFilesExistingUsers(General.DataPath); + WriteLn('Done!'); + + Write('Updating message area scan flags for existing user''s ... '); + UpdateMsgSCNFilesExistingUsers(General.DataPath,General.MsgPath); + WriteLn('Done!'); + + Write('Re-Scaning email waiting for existing user''s ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + ReScanUserEMail(General.MsgPath,User,Counter); + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + WriteLn('Done!'); + + Write('Re-Scaning voting for existing user''s ... '); + ResetVotes(General.DataPath); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + ReScanUserVotes(General.DataPath,User); + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + WriteLn('Done!'); + + Write('Updating UserID with record number for existing user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + User.UserID := Counter; + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + WriteLn('Done!'); + + Write('Purging SHORTMSG.DAT of deleted records ... '); + PurgingShortMsgs(General.DataPath); + WriteLn('Done!'); + + Write('Purging BATCHDL.DAT of deleted records ... '); + PurgingBatchQueue(General.DataPath); + WriteLn('Done!'); + + Write('Updating all File Area file size ... '); + UpdateDIRFileSize(General.DataPath); + WriteLn('Done!'); + + Write('Sorting all file areas ... '); + SortAllFileAreas(General.DataPath); + WriteLn('Done!'); + + Write('Packing all message areas ... '); + PackMessageAreas(General.DataPath,General.MsgPath); + WriteLn('Done!'); + + Write('Deleting USERS.DEL ... '); + Close(UserFile1); + Erase(UserFile1); + WriteLn('Done!'); + + Write('Deleting USERS.DAT ... '); + Erase(UserFile); + WriteLn('Done!'); + + Write('Re-Naming USERS.BAK to USERS.DAT ... '); + ReName(UserFile2,General.DataPath+'USERS.DAT'); + WriteLn('Done!'); + + Write('Deleting USERS.IDX ... '); + Assign(F,General.DataPath+'USERS.IDX'); + Erase(F); + WriteLn('Done!'); + + Write('Creating and re-indexing USERS.IDX ... '); + TotalUsers := 0; + Assign(UserIndexFile,General.DataPath+'USERS.IDX'); + ReWrite(UserIndexFile); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + IF NOT (Deleted IN User.SFLags) THEN + Inc(TotalUsers); + InsertIndex(UserIndexFile,User.Name,Counter,FALSE,(Deleted IN User.SFLags)); + InsertIndex(UserIndexFile,User.RealName,Counter,TRUE,(Deleted IN User.SFLags)); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Updating RENEGADE.DAT "NumUsers" ... '); + Assign(GeneralFile,'RENEGADE.DAT'); + Reset(GeneralFile); + Read(GeneralFile,General); + General.NumUsers := TotalUsers; + Seek(GeneralFile,0); + Write(GeneralFile,General); + Close(GeneralFile); + WriteLn('Done!'); + *) + + WriteLn; + WriteLn(^G^G^G'Your USERS.DAT file has been packed and associated files have been updated.'); + END; + END; + END; +END; + +BEGIN + PackUsers; +END. \ No newline at end of file diff --git a/SOURCE/UNUSED/RGMAINT1.PAS b/SOURCE/UNUSED/RGMAINT1.PAS new file mode 100644 index 0000000..ebc4608 --- /dev/null +++ b/SOURCE/UNUSED/RGMAINT1.PAS @@ -0,0 +1,1584 @@ +{$M 35500,0,131072} +PROGRAM RGMAINT; + +USES + Crt, + Dos, + TimeFunc; + +{$I RECORDS.PAS} + +TYPE + StorageType = + ( + Disk, + CD, + Copied + ); + + BatchDLRecordType = RECORD + BDLFileName: STRING[52]; + BDLStorage: StorageType; + BDLUserNum, + BDLSection, + BDLPoints, + BDLUploader: Integer; + BDLFSize, + BDLTime, + BDLOwnerCRC: LongInt; + BDLNoRatio: Boolean; + END; + + ULFRec = { *.DIR : File records } +{$IFDEF WIN32} packed {$ENDIF} RECORD + FileName: STRING[12]; { Filename } + LDescription: STRING[60]; { File description } + Credits: Integer; { File points } + Downloaded: Word; { Number DLs } + SizeMod: Word; { # chars over last 128 byte block } + Blocks: LongInt; { # 128 byte blks } + Owner: Word; { ULer of file } + StOwner: STRING[36]; { ULer's name } + Date: STRING[10]; { Date ULed } + DateN: Word; { Numeric Date ULed } + VPointer: LongInt; { Pointer to verbose descr, -1 if none } + FileStat: FiFlagSet; { File status } + Res: ARRAY [1..10] OF Byte; { RESERVED } + END; + + VotingR = { VOTING.DAT : Voting records } +{$IFDEF WIN32} packed {$ENDIF} RECORD + Description: STRING[65]; { voting question } + ACS: ACString; { ACS required to vote on this } + ChoiceNumber: Word; { number of choices } + NumVoted: Word; { number of votes on it } + MadeBy: STRING[35]; { who created it } + AddChoicesACS: ACString; { ACS required to add choices } + Choices: ARRAY [1..25] OF + {$IFDEF WIN32} packed {$ENDIF} RECORD + Description: STRING[65]; { answer description } + Description2: STRING[65]; { answer description #2 } + NumVoted: Integer; { # user's who picked this answer } + END; + END; + + DirF = FILE OF ULFRec; + SF = FILE OF UserIDXRec; + +CONST + DYNY: BOOLEAN = FALSE; + +FUNCTION AllCaps(S: STRING): STRING; +VAR + Counter: Byte; +BEGIN + FOR Counter := 1 TO Length(S) DO + IF (S[Counter] IN ['a'..'z']) THEN + S[Counter] := Chr(Ord(S[Counter]) - Ord('a')+Ord('A')); + AllCaps := S; +END; + +FUNCTION IntToStr(L: LongInt): STRING; +VAR + S: STRING[11]; +BEGIN + Str(L,S); + IntToStr := s; +END; + +FUNCTION SQOutSp(S: STRING): STRING; +BEGIN + WHILE (Pos(' ',S) > 0) DO + Delete(S,Pos(' ',S),1); + SQOutSp := S; +END; + +FUNCTION Exist(fn: AStr): Boolean; +VAR + DirInfo: SearchRec; +BEGIN + FindFirst(SQOutSp(fn),AnyFile,DirInfo); + Exist := (DOSError = 0); +END; + +FUNCTION SYN(B: BOOLEAN): STRING; +BEGIN + IF (B) THEN + SYN := 'Yes' + ELSE + SYN := 'No '; +END; + +FUNCTION YN: BOOLEAN; +VAR + C: CHAR; +BEGIN + Write(SQOutSp(SYN(DYNY))); + REPEAT + C := UpCase(Char(ReadKey)); + UNTIL (C IN ['Y','N',^M]); + IF (DYNY) AND (C <> 'N') THEN + C := 'Y'; + IF (DYNY) AND (C = 'N') THEN + Write(#8#8#8'No ') + ELSE IF (NOT DYNY) AND (C = 'Y') THEN + Write(#8#8'Yes'); + WriteLn; + YN := (C = 'Y'); + DYNY := FALSE; +END; + +FUNCTION PYNQ(CONST S: AStr): BOOLEAN; +BEGIN + Write(S); + PYNQ := YN; +END; + +FUNCTION StrToInt(S: STRING): LongInt; +VAR + I: Integer; + L: LongInt; +BEGIN + Val(S,L,I); + IF (I > 0) THEN + BEGIN + S[0] := Chr(I - 1); + Val(S,L,I) + END; + IF (S = '') THEN + StrToInt := 0 + ELSE + StrToInt := L; +END; + +FUNCTION GetFileSize(FileName: AStr): LongInt; +VAR + F: FILE OF Byte; + FSize: LongInt; +BEGIN + FSize := 0; + IF (Exist(SQOutSp(FileName))) THEN + BEGIN + Assign(F,SQOutSp(FileName)); + Reset(F); + FSize := FileSize(F); + Close(F); + END; + GetFileSize := FSize; +END; + +PROCEDURE KillUserVotes(DataPath: STRING; VAR User: UserRecordType); +VAR + VotingFile: FILE OF VotingR; + Topic: VotingR; + Counter: Integer; +BEGIN + IF (Exist(DataPath+'VOTING.DAT')) THEN + BEGIN + Assign(VotingFile,DataPath+'VOTING.DAT'); + Reset(VotingFile); + FOR Counter := 1 TO FileSize(VotingFile) DO + IF (User.Vote[Counter] > 0) THEN + BEGIN + Seek(VotingFile,(Counter - 1)); + Read(VotingFile,Topic); + IF (Topic.NumVoted > 0) THEN + Dec(Topic.NumVoted); + IF (Topic.Choices[User.Vote[Counter]].NumVoted > 0) THEN + Dec(Topic.Choices[User.Vote[Counter]].NumVoted); + Seek(VotingFile,(Counter - 1)); + Write(VotingFile,Topic); + User.Vote[Counter] := 0; + END; + Close(VotingFile); + END; +END; + +PROCEDURE ResetVotes(DataPath: STRING); +VAR + VotingFile: FILE OF VotingR; + Topic: VotingR; + Counter, + Counter1: Integer; +BEGIN + IF (Exist(DataPath+'VOTING.DAT')) THEN + BEGIN + Assign(VotingFile,DataPath+'VOTING.DAT'); + Reset(VotingFile); + FOR Counter := 1 TO FileSize(VotingFile) DO + BEGIN + Seek(VotingFile,(Counter - 1)); + Read(VotingFile,Topic); + Topic.NumVoted := 0;; + FOR Counter1 := 1 TO 25 DO + Topic.Choices[Counter1].NumVoted := 0; + Seek(VotingFile,(Counter - 1)); + Write(VotingFile,Topic); + END; + Close(VotingFile); + END; +END; + +PROCEDURE ReScanUserVotes(DataPath: STRING; VAR User: UserRecordType); +VAR + VotingFile: FILE OF VotingR; + Topic: VotingR; + Counter: Integer; +BEGIN + IF (Exist(DataPath+'VOTING.DAT')) THEN + BEGIN + Assign(VotingFile,DataPath+'VOTING.DAT'); + Reset(VotingFile); + FOR Counter := 1 TO FileSize(VotingFile) DO + IF (User.Vote[Counter] > 0) THEN + BEGIN + Seek(VotingFile,(Counter - 1)); + Read(VotingFile,Topic); + Inc(Topic.NumVoted); + Inc(Topic.Choices[User.Vote[Counter]].NumVoted); + Seek(VotingFile,(Counter - 1)); + Write(VotingFile,Topic); + END; + Close(VotingFile); + END; +END; + +PROCEDURE KillShortMsgs(DataPath: STRING; VAR User: UserRecordType); +VAR + ShortMsgFile: FILE OF ShortMessageRecordType; + ShortMsg: ShortMessageRecordType; + Counter: Integer; +BEGIN + IF (Exist(DataPath+'SHORTMSG.DAT')) THEN + BEGIN + Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + FOR Counter := 1 TO FileSize(ShortMsgFile) DO + BEGIN + Seek(ShortMsgFile,(Counter - 1)); + Read(ShortMsgFile,ShortMsg); + IF (ShortMsg.Destin = User.UserID) THEN + ShortMsg.Destin := -1; + Seek(ShortMsgFile,(Counter - 1)); + Write(ShortMsgFile,ShortMsg); + END; + Close(ShortMsgFile); + END; +END; + +PROCEDURE UpdateShortMsgs(DataPath: STRING; VAR User: UserRecordType; NewUserNumber: Integer); +VAR + ShortMsgFile: FILE OF ShortMessageRecordType; + ShortMsg: ShortMessageRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'SHORTMSG.DAT') THEN + BEGIN + Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + FOR Counter := 1 TO FileSize(ShortMsgFile) DO + BEGIN + Seek(ShortMsgFile,(Counter - 1)); + Read(ShortMsgFile,ShortMsg); + IF (ShortMsg.Destin = User.UserID) THEN + ShortMsg.Destin := NewUserNumber; + Seek(ShortMsgFile,(Counter - 1)); + Write(ShortMsgFile,ShortMsg); + END; + Close(ShortMsgFile); + END; +END; + +PROCEDURE PurgingShortMsgs(DataPath: STRING); +VAR + ShortMsgFile: FILE OF ShortMessageRecordType; + ShortMsgFile1: FILE OF ShortMessageRecordType; + ShortMsg: ShortMessageRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'SHORTMSG.DAT') THEN + BEGIN + Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + Assign(ShortMsgFile1,DataPath+'SHORTMSG.BAK'); + ReWrite(ShortMsgFile1); + FOR Counter := 1 TO FileSize(ShortMsgFile) DO + BEGIN + Seek(ShortMsgFile,(Counter - 1)); + Read(ShortMsgFile,ShortMsg); + IF (ShortMsg.Destin <> -1) THEN + BEGIN + Seek(ShortMsgFile1,FileSize(ShortMsgFile1)); + Write(ShortMsgFile1,ShortMsg); + END; + END; + Close(ShortMsgFile); + Erase(ShortMsgFile); + Close(ShortMsgFile1); + ReName(ShortMsgFile1,DataPath+'SHORTMSG.DAT'); + END; +END; + +PROCEDURE KillBatchQueue(DataPath: STRING; VAR User: UserRecordType); +VAR + BatchDLFile: FILE OF BatchDlRecordType; + BatchDL: BatchDlRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'BATCHDL.DAT') THEN + BEGIN + Assign(BatchDLFile,DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + FOR Counter := 1 TO FileSize(BatchDLFile) DO + BEGIN + Seek(BatchDLFile,(Counter - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = User.UserID) THEN + BatchDL.BDLUserNum := -1; + Seek(BatchDLFile,(Counter - 1)); + Write(BatchDLFile,BatchDL); + END; + Close(BatchDLFile); + END; +END; + +PROCEDURE UpdateBatchQueue(DataPath: STRING; VAR User: UserRecordType; NewUserNumber: Integer); +VAR + BatchDLFile: FILE OF BatchDLRecordType; + BatchDL: BatchDlRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'BATCHDL.DAT') THEN + BEGIN + Assign(BatchDLFile,DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + FOR Counter := 1 TO FileSize(BatchDLFile) DO + BEGIN + Seek(BatchDLFile,(Counter - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = User.UserID) THEN + BatchDL.BDLUserNum := NewUserNumber; + Seek(BatchDLFile,(Counter - 1)); + Write(BatchDLFile,BatchDL); + END; + Close(BatchDLFile); + END; +END; + +PROCEDURE PurgingBatchQueue(DataPath: STRING); +VAR + BatchDLFile: FILE OF BatchDLRecordType; + BatchDLFile1: FILE OF BatchDLRecordType; + BatchDL: BatchDLRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'BATCHDL.DAT') THEN + BEGIN + Assign(BatchDLFile,DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + Assign(BatchDLFile1,DataPath+'BATCHDL.BAK'); + ReWrite(BatchDLFile1); + FOR Counter := 1 TO FileSize(BatchDLFile) DO + BEGIN + Seek(BatchDLFile,(Counter - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum <> -1) THEN + BEGIN + Seek(BatchDLFile1,FileSize(BatchDLFile1)); + Write(BatchDLFile1,BatchDL); + END; + END; + Close(BatchDLFile); + Erase(BatchDLFile); + Close(BatchDLFile1); + ReName(BatchDLFile1,DataPath+'BATCHDL.DAT'); + END; +END; + +PROCEDURE KillUserEMail(DataPath,MsgPath: STRING; VAR User: UserRecordType); +VAR + MsgHdrF: FILE OF MHeaderRec; + MHeader: MHeaderRec; + MsgNum: Word; +BEGIN + IF (Exist(MsgPath+'EMAIL.HDR')) THEN + BEGIN + Assign(MsgHdrF,MsgPath+'EMAIL.HDR'); + Reset(MsgHdrF); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF ((MHeader.MTO.UserNum = User.UserID) OR (MHeader.From.UserNum = User.UserID)) THEN + Include(MHeader.Status,MDeleted); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := 0; + IF (MHeader.FROM.UserNum = User.UserID) THEN + MHeader.FROM.UserNum := 0; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + User.Waiting := 0; + END; +END; + +PROCEDURE UpdateUserEMail(MsgPath: STRING; VAR User: UserRecordType; NewUserNum: Integer); +VAR + MsgHdrF: FILE OF MHeaderRec; + MHeader: MHeaderRec; + MsgNum: Word; +BEGIN + IF (Exist(MsgPath+'EMAIL.HDR')) THEN + BEGIN + Assign(MsgHdrF,MsgPath+'EMAIL.HDR'); + Reset(MsgHdrF); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := NewUserNum; + IF (MHeader.From.UserNum = User.UserID) THEN + MHeader.From.UserNum := NewUserNum; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + END; +END; + +PROCEDURE ReScanUserEMail(MsgPath: STRING; VAR User: UserRecordType; UserNum: Integer); +VAR + MsgHdrF: FILE OF MHeaderRec; + MHeader: MHeaderRec; + MsgNum: Word; +BEGIN + IF (Exist(MsgPath+'EMAIL.HDR')) THEN + BEGIN + User.Waiting := 0; + Assign(MsgHdrF,MsgPath+'EMAIL.HDR'); + Reset(MsgHdrF); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = UserNum) THEN + IF (NOT (MDeleted IN MHeader.Status)) THEN + Inc(User.Waiting); + END; + Close(MsgHdrF); + END; +END; + +PROCEDURE UpdateDIRFilesDeletedUsers(DataPath: STRING; User,SysOpUser: UserRecordType); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: FILE OF ULFRec; + FileArea: FileAreaRecordType; + VerbF: FILE; + F: ULFRec; + Counter, + Counter1: Integer; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(VerbF,FileArea.Dlpath+FileArea.FileName+'.EXT') + ELSE + Assign(VerbF,Datapath+FileArea.FileName+'.EXT'); + Reset(VerbF,1); + IF (IOResult = 2) THEN + ReWrite(VerbF,1); + FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO + BEGIN + Seek(DirFile,Counter1); + Read(DirFile,F); + IF (F.Owner = User.UserID) THEN + BEGIN + F.Owner := SysOpUser.UserID; + F.StOwner := AllCaps(SysOpUser.Name); + END; + Seek(DirFile,Counter1); + Write(DirFile,F); + END; + Close(DirFile); + Close(VerbF); + END; + Close(FileAreaFile); +END; + +PROCEDURE UpdateDIRFilesExistingUsers(DataPath: STRING; User: UserRecordType; NewUserNum: Integer); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: FILE OF ULFRec; + VerbF: FILE; + FileArea: FileAreaRecordType; + F: ULFRec; + Counter, + Counter1: Integer; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(VerbF,FileArea.Dlpath+FileArea.FileName+'.EXT') + ELSE + Assign(VerbF,Datapath+FileArea.FileName+'.EXT'); + Reset(VerbF,1); + IF (IOResult = 2) THEN + ReWrite(VerbF,1); + FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO + BEGIN + Seek(DirFile,Counter1); + Read(DirFile,F); + IF (F.Owner = User.UserID) THEN + F.Owner := NewUserNum; + Seek(DirFile,Counter1); + Write(DirFile,F); + END; + Close(DirFile); + Close(VerbF); + END; + Close(FileAreaFile); +END; + +PROCEDURE UpdateDIRFileSize(DataPath: STRING); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: FILE OF ULFRec; + FileArea: FileAreaRecordType; + VerbF: FILE; + F: ULFRec; + Counter, + Counter1: Integer; + FSize: Longint; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(VerbF,FileArea.Dlpath+FileArea.FileName+'.EXT') + ELSE + Assign(VerbF,Datapath+FileArea.FileName+'.EXT'); + Reset(VerbF,1); + IF (IOResult = 2) THEN + ReWrite(VerbF,1); + FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO + BEGIN + Seek(DirFile,Counter1); + Read(DirFile,F); + FSize := GetFileSize(FileArea.DLPath+F.FileName); + IF (FSize = 0) THEN + BEGIN + F.SizeMod := 0; + F.Blocks := 0; + Include(F.FileStat,FIIsRequest); + END + ELSE + BEGIN + F.Blocks := FSize DIV 128; + F.SizeMod := FSize MOD 128; + END; + Seek(DirFile,Counter1); + Write(DirFile,F); + END; + Close(DirFile); + Close(VerbF); + END; + Close(FileAreaFile); +END; + +PROCEDURE UpdateFileSCNFilesExistingUsers(DataPath: STRING); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + UserFile: FILE OF UserRecordType; + UserFile2: FILE OF UserRecordType; + ScnFile: FILE OF Boolean; + ScnFile1: FILE OF Boolean; + FileArea: FileAreaRecordType; + User: UserRecordType; + Path: STRING; + Counter, + Counter1, + NumUsers: Integer; + NewScanFBase: Boolean; +BEGIN + Assign(UserFile,DataPath+'USERS.DAT'); + Reset(UserFile); + Assign(UserFile2,DataPath+'USERS.BAK'); + Reset(UserFile2); + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Path := FileArea.Dlpath+FileArea.FileName + ELSE + Path := Datapath+FileArea.FileName; + Assign(ScnFile,Path+'.SCN'); + Reset(ScnFile); + IF (IOResult = 2) THEN + ReWrite(ScnFile); + Assign(ScnFile1,Path+'.SCB'); + ReWrite(ScnFile1); + NumUsers := (FileSize(UserFile) - 1); + IF (NumUsers > FileSize(ScnFile)) THEN + BEGIN + Seek(ScnFile,FileSize(ScnFile)); + NewScanFBase := TRUE; + FOR Counter1 := FileSize(ScnFile) TO (NumUsers - 1) DO + Write(ScnFile,NewScanFBase); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(ScnFile1,FileSize(ScnFile1)); + NewScanFBase := TRUE; + Write(ScnFile1,NewScanFBase); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter1); + Read(UserFile2,User); + Seek(ScnFile,(User.UserID - 1)); + Read(ScnFile,NewScanFBase); + Seek(ScnFile1,(Counter1 - 1)); + Write(ScnFile1,NewScanFBase); + END; + Close(ScnFile); + Erase(ScnFile); + Close(ScnFile1); + ReName(ScnFile1,Path+'.SCN'); + END; + Close(FileAreaFile); + Close(UserFile); + Close(UserFile2); +END; + +PROCEDURE UpdateMsgFilesDeletedUsers(DataPath,MsgPath: STRING; User: UserRecordType); +VAR + MsgAreaFile: FILE OF MessageAreaRecordType; + MsgHdrF: FILE OF MHeaderRec; + MsgTxtF: FILE; + MsgArea: MessageAreaRecordType; + MHeader: MHeaderRec; + Counter: Integer; + MsgNum: Word; +BEGIN + Assign(MsgAreaFile,DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + FOR Counter := 0 TO (FileSize(MsgAreaFile) - 1) DO + BEGIN + Seek(MsgAreaFile,Counter); + Read(MsgAreaFile,MsgArea); + Assign(MsgHdrF,MsgPath+MsgArea.FileName+'.HDR'); + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + Assign(MsgTxtF,MsgPath+MsgArea.FileName+'.DAT'); + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := 0; + IF (MHeader.From.UserNum = User.UserID) THEN + MHeader.From.UserNum := 0; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + Close(MsgTxtF); + END; + Close(MsgAreaFile); +END; + +PROCEDURE UpdateMsgFilesExistingUsers(DataPath,MsgPath: STRING; User: UserRecordType; NewUserNum: Integer); +VAR + MsgAreaFile: FILE OF MessageAreaRecordType; + MsgHdrF: FILE OF MHeaderRec; + MsgTxtF: FILE; + MsgArea: MessageAreaRecordType; + MHeader: MHeaderRec; + Counter: Integer; + MsgNum: Word; +BEGIN + Assign(MsgAreaFile,DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + FOR Counter := 0 TO (FileSize(MsgAreaFile) - 1) DO + BEGIN + Seek(MsgAreaFile,Counter); + Read(MsgAreaFile,MsgArea); + Assign(MsgHdrF,MsgPath+MsgArea.FileName+'.HDR'); + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + Assign(MsgTxtF,MsgPath+MsgArea.FileName+'.DAT'); + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := NewUserNum; + IF (MHeader.From.UserNum = User.UserID) THEN + MHeader.From.UserNum := NewUserNum; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + Close(MsgTxtF); + END; + Close(MsgAreaFile); +END; + +PROCEDURE UpdateMsgSCNFilesExistingUsers(DataPath,MsgPath: STRING); +VAR + MessageFile: FILE OF MessageAreaRecordType; + UserFile: FILE OF UserRecordType; + UserFile2: FILE OF UserRecordType; + MsgScanFile: FILE OF ScanRec; + MsgScanFile1: FILE OF ScanRec; + MsgArea: MessageAreaRecordType; + User: UserRecordType; + LastReadRecord: ScanRec; + Path: STRING; + Counter, + Counter1, + NumUsers: Integer; +BEGIN + Assign(UserFile,DataPath+'USERS.DAT'); + Reset(UserFile); + Assign(UserFile2,DataPath+'USERS.BAK'); + Reset(UserFile2); + Assign(MessageFile,DataPath+'MBASES.DAT'); + Reset(MessageFile); + FOR Counter := 0 TO (FileSize(MessageFile) - 1) DO + BEGIN + Seek(MessageFile,Counter); + Read(MessageFile,MsgArea); + Path := MsgPath+MsgArea.FileName; + Assign(MsgScanFile,Path+'.SCN'); + Reset(MsgScanFile); + IF (IOResult = 2) THEN + ReWrite(MsgScanFile); + Assign(MsgScanFile1,Path+'.SCB'); + ReWrite(MsgScanFile1); + NumUsers := (FileSize(UserFile) - 1); + IF (NumUsers > FileSize(MsgScanFile)) THEN + BEGIN + WITH LastReadRecord DO + BEGIN + LastRead := 0; + NewScan := TRUE; + END; + Seek(MsgScanFile,FileSize(MsgScanFile)); + FOR Counter1 := FileSize(MSGScanFile) TO (NumUsers - 1) DO + Write(MsgScanFile,LastReadRecord); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + WITH LastReadRecord DO + BEGIN + LastRead := 0; + NewScan := TRUE; + END; + Seek(MsgScanFile1,FileSize(MsgScanFile1)); + Write(MsgScanFile1,LastReadRecord); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter1); + Read(UserFile2,User); + Seek(MsgScanFile,(User.UserID - 1)); + Read(MsgScanFile,LastReadRecord); + Seek(MsgScanFile1,(Counter1 - 1)); + Write(MsgScanFile1,LastReadRecord); + END; + Close(MsgScanFile); + Erase(MsgScanFile); + Close(MsgScanFile1); + ReName(MsgScanFile1,Path+'.SCN'); + END; + Close(MessageFile); + Close(UserFile); + Close(UserFile2); +END; + +PROCEDURE PackMessageArea(MsgPath,FN: STRING; MaxM: LongInt); +VAR + Buffer: ARRAY [1..4096] OF Char; + MsgHdrF1, + MsgHdrF2: FILE OF MheaderRec; + BrdF1, + BrdF2: FILE; + MHeader: MheaderRec; + Numm, + i, + IDX, + TotLoad, + Buffered: Word; + NeedPack: Boolean; + + PROCEDURE ErrMsg; + BEGIN + Writeln('Error renaming temp files while packing.'); + END; + + PROCEDURE Kill(CONST FN: AStr); + VAR + F: FILE; + BEGIN + IF Exist(FN) THEN + BEGIN + Assign(F,FN); + Erase(F); + END; + END; + +BEGIN + NeedPack := FALSE; + FN := AllCaps(FN); + FN := MsgPath + FN; + + Assign(BrdF1,FN+'.DAT'); + Reset(BrdF1,1); + IF (IOResult <> 0) THEN + Exit; + + Assign(MsgHdrF1,FN+'.HDR'); + Reset(MsgHdrF1); + + IF (IOResult <> 0) THEN + BEGIN + Close(BrdF1); + Exit + END; + + IF (MaxM <> 0) AND (FileSize(MsgHdrF1) > MaxM) THEN + BEGIN + Numm := 0; + IDX := FileSize(MsgHdrF1); + WHILE (IDX > 0) DO + BEGIN + Seek(MsgHdrF1,(IDX - 1)); + Read(MsgHdrF1,MHeader); + IF NOT (MDeleted IN MHeader.Status) THEN + Inc(Numm); + IF (Numm > MaxM) AND NOT (Permanent IN MHeader.Status) THEN + BEGIN + MHeader.Status := [MDeleted]; + Seek(MsgHdrF1,(IDX - 1)); + Write(MsgHdrF1,MHeader); + END; + Dec(IDX); + END; + END + ELSE + BEGIN + + WHILE (FilePos(MsgHdrF1) < FileSize(MsgHdrF1)) AND (NOT NeedPack) DO + BEGIN + Read(MsgHdrF1,MHeader); + IF (MDeleted IN MHeader.Status) THEN + NeedPack := TRUE; + END; + + IF (NOT NeedPack) THEN + BEGIN + Close(MsgHdrF1); + Close(BrdF1); + Exit; + END; + END; + + Assign(BrdF2,FN+'.DA1'); + ReWrite(BrdF2,1); + + Assign(MsgHdrF2,FN+'.HD2'); + ReWrite(MsgHdrF2); + + Kill(FN+'.HD3'); + Kill(FN+'.DA3'); + + IDX := 1; + i := 0; + + WHILE (i <= FileSize(MsgHdrF1) - 1) DO + BEGIN + Seek(MsgHdrF1,i); + Read(MsgHdrF1,MHeader); + + IF (MHeader.Pointer - 1 + MHeader.TextSize > FileSize(BrdF1)) OR + (MHeader.Pointer < 1) THEN + MHeader.Status := [MDeleted]; + + IF NOT (MDeleted IN MHeader.Status) THEN + BEGIN + Inc(IDX); + Seek(BrdF1,MHeader.Pointer - 1); + MHeader.Pointer := (FileSize(BrdF2) + 1); + Write(MsgHdrF2,MHeader); + + TotLoad := 0; + IF (MHeader.TextSize > 0) THEN + WHILE (MHeader.TextSize > 0) DO + BEGIN + Buffered := MHeader.TextSize; + IF (Buffered > 4096) THEN + Buffered := 4096; + Dec(MHeader.TextSize,Buffered); + BlockRead(BrdF1,Buffer[1],Buffered); + BlockWrite(BrdF2,Buffer[1],Buffered); + END; + END; + Inc(i); + END; + + Close(BrdF1); + Close(BrdF2); + Close(MsgHdrF1); + Close(MsgHdrF2); + + ReName(BrdF1,FN+'.DA3'); { ReName .DAT to .DA3 } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + Exit; + END; + + ReName(BrdF2,FN+'.DAT'); { ReName .DA2 to .DAT } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + Exit; + END; + + ReName(MsgHdrF1,FN+'.HD3'); { ReName .HDR to .HD3 } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + Erase(BrdF2); { Erase .DA2 } + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + Exit; + END; + + ReName(MsgHdrF2,FN+'.HDR'); { ReName .HD2 to .HDR } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + Erase(BrdF2); { Erase .DAT (new) } + Erase(MsgHdrF2); { Erase .HD2 (new) } + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + ReName(MsgHdrF1,FN+'.HDR'); { ReName .HD3 to .HDR } + Exit; + END; + + Erase(MsgHdrF1); + Erase(BrdF1); +END; + +PROCEDURE PackMessageAreas(DataPath,MsgPath: STRING); +VAR + MsgAreaFile: FILE OF MessageAreaRecordType; + MsgArea: MessageAreaRecordType; + MArea: Integer; +BEGIN + PackMessageArea(MsgPath,'EMAIL',0); + Assign(MsgAreaFile,DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + FOR MArea := 0 TO (FileSize(MsgAreaFile) - 1) DO + BEGIN + Seek(MsgAreaFile,MArea); + Read(MsgAreaFile,MsgArea); + PackMessageArea(MsgPath,MsgArea.FIleName,MsgArea.MaxMsgs); + END; + Close(MsgAreaFile); +END; + +PROCEDURE SortFileArea(VAR DirFile1: DirF; NumFiles: Integer); +VAR + F1, + F2: ULFRec; + NumSorted, + RecNum, + RecNum1, + Gap: Integer; +BEGIN + Gap := NumFiles; + REPEAT; + Gap := (Gap DIV 2); + IF (Gap = 0) THEN + Gap := 1; + NumSorted := 0; + FOR RecNum := 1 TO (NumFiles - Gap) DO + BEGIN + RecNum1 := (RecNum + Gap); + Seek(DirFile1,(RecNum - 1)); + Read(DirFile1,F1); + Seek(DirFile1,(RecNum1 - 1)); + Read(DirFile1,F2); + IF (F1.FileName > F2.FileName) THEN + BEGIN + Seek(DirFile1,(RecNum - 1)); + Write(DirFile1,F2); + Seek(DirFile1,(RecNum1 - 1)); + Write(DirFile1,F1); + Inc(NumSorted); + END; + END; + UNTIL (NumSorted = 0) AND (Gap = 1); +END; + +PROCEDURE SortAllFileAreas(DataPath: STRING); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: DirF; + FileArea: FileAreaRecordType; + F: ULFRec; + NumFiles, + Counter: Integer; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + NumFiles := FileSize(DirFile); + IF (NumFiles <> 0) THEN + SortFileArea(DirFile,NumFiles); + Close(DirFile); + END; + Close(FileAreaFile); +END; + +PROCEDURE InsertIndex(VAR UserIndexFile1: SF; Uname: AStr; UserNum: Integer; IsReal,IsDeleted: Boolean); +VAR + IndexR: UserIDXRec; + Current, + InsertAt: Integer; + Done: Boolean; + + PROCEDURE WriteIndex; + BEGIN + FillChar(IndexR,SizeOf(IndexR),0); + WITH IndexR DO + BEGIN + Name := Uname; + Number := UserNum; + RealName := IsReal; + Deleted := IsDeleted; + Left := -1; + Right := -1; + Write(UserIndexFile1,IndexR); + END + END; + +BEGIN + Done := FALSE; + Uname := Allcaps(Uname); + Current := 0; + Reset(UserIndexFile1); + IF (FileSize(UserIndexFile1) = 0) THEN + WriteIndex + ELSE + REPEAT + Seek(UserIndexFile1,Current); + InsertAt := Current; + Read(UserIndexFile1,IndexR); + IF (Uname < IndexR.Name) THEN + Current := IndexR.Left + ELSE IF (Uname > IndexR.Name) THEN + Current := IndexR.Right + ELSE IF (IndexR.Deleted <> IsDeleted) THEN + BEGIN + Done := TRUE; + IndexR.Deleted := IsDeleted; + IndexR.RealName := IsReal; + IndexR.Number := UserNum; + Seek(UserIndexFile1,Current); + Write(UserIndexFile1,IndexR); + END + ELSE + BEGIN + IF (UserNum <> IndexR.Number) THEN + WriteLn('Note: Duplicate user '+UName+' #'+IntToStr(IndexR.Number)+' and '+UName+' #'+IntToStr(UserNum)) + ELSE + BEGIN + IndexR.RealName := FALSE; + Seek(UserIndexFile1,Current); { Make it be his handle IF it's BOTH } + Write(UserIndexFile1,IndexR); + END; + Done := TRUE; + END; + UNTIL (Current = -1) OR (Done); + IF (Current = -1) THEN + BEGIN + IF (Uname < IndexR.Name) THEN + IndexR.Left := FileSize(UserIndexFile1) + ELSE + IndexR.Right := FileSize(UserIndexFile1); + Seek(UserIndexFile1,InsertAt); + Write(UserIndexFile1,IndexR); + Seek(UserIndexFile1,FileSize(UserIndexFile1)); + WriteIndex; + END; + Close(UserIndexFile1); +END; + +PROCEDURE PackUsers; +VAR + GeneralFile: FILE OF GeneralRecordType; + UserFile: FILE OF UserRecordType; + UserFile1: FILE OF UserRecordType; + UserFile2: FILE OF UserRecordType; + UserIndexFile: SF; + F: FILE; + General: GeneralRecordType; + User, + SysOpUser: UserRecordType; + DeleteDateStr: STRING; + TotalUsers, + Counter: Integer; + Year: Word; + PackedDeleteDate: LongInt; + UsersToDelete, + DeleteByDate, + InvalidDate: Boolean; +BEGIN + DeleteByDate := FALSE; + + IF (ParamCount > 0) THEN + FOR Counter := 1 TO ParamCount DO + IF (AllCaps(Copy(ParamStr(Counter),1,2)) = AllCaps('-D')) THEN + BEGIN + DeleteDateStr := Copy(ParamStr(Counter),3,Length(ParamStr(Counter))); + InvalidDate := FALSE; + IF (Length(DeleteDateStr) <> 10) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) = 0) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) > 12) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,4,2)) = 0) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) IN [1,3,5,7,8,10,12]) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 31) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) IN [4,6,9,11]) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 30) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) = 2) AND ((StrToInt(Copy(DeleteDateStr,7,4)) MOD 4) <> 0) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 28) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) = 2) AND ((StrToInt(Copy(DeleteDateStr,7,4)) MOD 4) = 0) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 29) THEN + InvalidDate := TRUE; + GetYear(Year); + IF (StrToInt(Copy(DeleteDateStr,7,4)) > Year) THEN + InvalidDate := TRUE; + + IF (InvalidDate) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'Invalid date or format, valid format is "00/00/0000'); + Exit; + END + ELSE + BEGIN + PackedDeleteDate := Date2PD(DeleteDateStr); + DeleteByDate := TRUE; + END; + END; + + ClrScr; + WriteLn('Renegade User Packer Version 1.0'); + Writeln('Copyright 2007 - The Renegade Developement Team'); + WriteLn; + Writeln('This utility will pack your Renegade BBS Version 09/30/06 '); + WriteLn('USERS.DAT file and update all required data files.'); + WriteLn; + WriteLn('User''s to be packed:'); + WriteLn(' - All user''s currently marked for deletion'); + IF (DeleteByDate) THEN + WriteLn(' - All user''s that have not logged on since '+DeleteDateStr); + WriteLn; + WriteLn('This process could take awhile depending on the total number'); + WriteLn('of files on your BBS that require update.'); + WriteLn; + IF PYNQ('Do you wish to continue? ') THEN + BEGIN + WriteLn; + IF (NOT Exist('RENEGADE.DAT')) THEN + WriteLn('This utility must be executed in the same directory as RENEGADE.DAT!') + ELSE + BEGIN + Write('Reading RENEGADE.DAT ... '); + Assign(GeneralFile,'RENEGADE.DAT'); + Reset(GeneralFile); + Read(GeneralFile,General); + Close(GeneralFile); + WriteLn('Done!'); + + WriteLn; + Write('Checking USERS.DAT for user''s to pack ... '); + Assign(UserFile,General.DataPath+'USERS.DAT'); + Reset(UserFile); + UsersToDelete := FALSE; + Counter := 2; + WHILE (Counter <= (FileSize(UserFile) - 1)) AND (NOT UsersToDelete) DO + BEGIN + Seek(UserFile,Counter); + Read(UserFile,User); + IF (Deleted IN User.SFlags) OR (DeleteByDate) AND (NOT (FNoDeletion IN User.Flags)) + AND (User.LastOn < PackedDeleteDate) THEN + UsersToDelete := TRUE; + Inc(Counter); + END; + WriteLn('Done!'); + + IF (NOT UsersToDelete) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'No deleted user''s found to pack!'); + END + ELSE + BEGIN + + Write('Updating USERS.DAT "UserID" with record number for all user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile) - 1) DO + BEGIN + Seek(UserFile,Counter); + Read(UserFile,User); + User.UserID := Counter; + Seek(UserFile,Counter); + Write(UserFile,User); + END; + WriteLn('Done!'); + + Write('Locating deleted user''s and creating USERS.DEL and USERS.BAK ... '); + Assign(UserFile1,General.DataPath+'USERS.DEL'); + ReWrite(UserFile1); + Assign(UserFile2,General.DataPath+'USERS.BAK'); + ReWrite(UserFile2); + Seek(UserFile,0); + Read(UserFile,User); + User.UserID := 0; + Seek(UserFile2,FileSize(UserFile2)); + Write(UserFile2,User); + Seek(UserFile,1); + Read(UserFile,User); + User.UserID := 1; + Seek(UserFile2,FileSize(UserFile2)); + Write(UserFile2,User); + FOR Counter := 2 TO (FileSize(UserFile) - 1) DO + BEGIN + Seek(UserFile,Counter); + Read(UserFile,User); + IF (Deleted IN User.SFlags) OR (DeleteByDate) AND (NOT (FNoDeletion IN User.Flags)) + AND (User.LastOn < PackedDeleteDate) THEN + BEGIN + Seek(UserFile1,FileSize(UserFile1)); + Write(UserFile1,User); + END + ELSE + BEGIN + Seek(UserFile2,FileSize(UserFile2)); + Write(UserFile2,User); + END; + END; + Close(UserFile); + Close(UserFile2); + WriteLn('Done!'); + + Write('Removing voting records for deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillUserVotes(General.DataPath,User); + Seek(UserFile1,Counter); + Write(UserFile1,User); + END; + WriteLn('Done!'); + + Write('Setting SHORTMSG.DAT "Destin" to -1 for deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillShortMsgs(General.DataPath,User); + END; + WriteLn('Done!'); + + Write('Updating SHORTMSG.DAT "Destin" with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateSHortMsgs(General.DataPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Setting BATCHDL.DAT "BDLUserNum" to -1 for all deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillBatchQueue(General.DataPath,User); + END; + WriteLn('Done!'); + + Write('Updating BATCHDL.DAT "BDLUserNum" with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateBatchQueue(General.DataPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Setting EMAIL.HDR "MDeleted" for email to/from deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillUserEMail(General.DataPath,General.MsgPath,User); + Seek(UserFile1,Counter); + Write(UserFile1,User); + END; + WriteLn('Done!'); + + Write('Updating EMAIL.HDR "MTO/FROM" with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateUserEMail(General.MsgPath,User,Counter); + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Updating *.DIR files with sysop name/number for all deleted user''s ... '); + Assign(UserFile2,General.DataPath+'USERS.BAK'); + Reset(UserFile2); + Seek(UserFile2,1); + Read(UserFile2,SysOpUser); + Close(UserFile2); + Reset(UserFile1); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + UpdateDIRFilesDeletedUsers(General.DataPath,User,SysOpUser); + END; + WriteLn('Done!'); + + Write('Updating *.DIR files with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateDIRFilesExistingUsers(General.DataPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Setting *.HDR files "MTO/FROM" to 0 for all deleted user''s ... '); + Reset(UserFile1); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + UpdateMsgFilesDeletedUsers(General.DataPath,General.MsgPath,User); + END; + WriteLn('Done!'); + + Write('Updating *.HDR files with new user number for existing user''s ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateMsgFilesExistingUsers(General.DataPath,General.MsgPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Updating file area scan flags for existing user''s ... '); + UpdateFileSCNFilesExistingUsers(General.DataPath); + WriteLn('Done!'); + + Write('Updating message area scan flags for existing user''s ... '); + UpdateMsgSCNFilesExistingUsers(General.DataPath,General.MsgPath); + WriteLn('Done!'); + + Write('Re-Scaning email waiting for existing user''s ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + ReScanUserEMail(General.MsgPath,User,Counter); + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + WriteLn('Done!'); + + Write('Re-Scaning voting for existing user''s ... '); + ResetVotes(General.DataPath); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + ReScanUserVotes(General.DataPath,User); + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + WriteLn('Done!'); + + Write('Updating UserID with record number for existing user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + User.UserID := Counter; + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + WriteLn('Done!'); + + Write('Purging SHORTMSG.DAT of deleted records ... '); + PurgingShortMsgs(General.DataPath); + WriteLn('Done!'); + + Write('Purging BATCHDL.DAT of deleted records ... '); + PurgingBatchQueue(General.DataPath); + WriteLn('Done!'); + + Write('Updating all File Area file size ... '); + UpdateDIRFileSize(General.DataPath); + WriteLn('Done!'); + + Write('Sorting all file areas ... '); + SortAllFileAreas(General.DataPath); + WriteLn('Done!'); + + Write('Packing all message areas ... '); + PackMessageAreas(General.DataPath,General.MsgPath); + WriteLn('Done!'); + + Write('Deleting USERS.DEL ... '); + Close(UserFile1); + Erase(UserFile1); + WriteLn('Done!'); + + Write('Deleting USERS.DAT ... '); + Erase(UserFile); + WriteLn('Done!'); + + Write('Re-Naming USERS.BAK to USERS.DAT ... '); + ReName(UserFile2,General.DataPath+'USERS.DAT'); + WriteLn('Done!'); + + Write('Deleting USERS.IDX ... '); + Assign(F,General.DataPath+'USERS.IDX'); + Erase(F); + WriteLn('Done!'); + + Write('Creating and re-indexing USERS.IDX ... '); + TotalUsers := 0; + Assign(UserIndexFile,General.DataPath+'USERS.IDX'); + ReWrite(UserIndexFile); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + IF NOT (Deleted IN User.SFLags) THEN + Inc(TotalUsers); + InsertIndex(UserIndexFile,User.Name,Counter,FALSE,(Deleted IN User.SFLags)); + InsertIndex(UserIndexFile,User.RealName,Counter,TRUE,(Deleted IN User.SFLags)); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Updating RENEGADE.DAT "NumUsers" ... '); + Assign(GeneralFile,'RENEGADE.DAT'); + Reset(GeneralFile); + Read(GeneralFile,General); + General.NumUsers := TotalUsers; + Seek(GeneralFile,0); + Write(GeneralFile,General); + Close(GeneralFile); + WriteLn('Done!'); + + WriteLn; + WriteLn(^G^G^G'Your USERS.DAT file has been packed and associated files have been updated.'); + END; + END; + END; +END; + +BEGIN + PackUsers; +END. \ No newline at end of file diff --git a/SOURCE/UNUSED/RGMAINT2.PAS b/SOURCE/UNUSED/RGMAINT2.PAS new file mode 100644 index 0000000..ebc4608 --- /dev/null +++ b/SOURCE/UNUSED/RGMAINT2.PAS @@ -0,0 +1,1584 @@ +{$M 35500,0,131072} +PROGRAM RGMAINT; + +USES + Crt, + Dos, + TimeFunc; + +{$I RECORDS.PAS} + +TYPE + StorageType = + ( + Disk, + CD, + Copied + ); + + BatchDLRecordType = RECORD + BDLFileName: STRING[52]; + BDLStorage: StorageType; + BDLUserNum, + BDLSection, + BDLPoints, + BDLUploader: Integer; + BDLFSize, + BDLTime, + BDLOwnerCRC: LongInt; + BDLNoRatio: Boolean; + END; + + ULFRec = { *.DIR : File records } +{$IFDEF WIN32} packed {$ENDIF} RECORD + FileName: STRING[12]; { Filename } + LDescription: STRING[60]; { File description } + Credits: Integer; { File points } + Downloaded: Word; { Number DLs } + SizeMod: Word; { # chars over last 128 byte block } + Blocks: LongInt; { # 128 byte blks } + Owner: Word; { ULer of file } + StOwner: STRING[36]; { ULer's name } + Date: STRING[10]; { Date ULed } + DateN: Word; { Numeric Date ULed } + VPointer: LongInt; { Pointer to verbose descr, -1 if none } + FileStat: FiFlagSet; { File status } + Res: ARRAY [1..10] OF Byte; { RESERVED } + END; + + VotingR = { VOTING.DAT : Voting records } +{$IFDEF WIN32} packed {$ENDIF} RECORD + Description: STRING[65]; { voting question } + ACS: ACString; { ACS required to vote on this } + ChoiceNumber: Word; { number of choices } + NumVoted: Word; { number of votes on it } + MadeBy: STRING[35]; { who created it } + AddChoicesACS: ACString; { ACS required to add choices } + Choices: ARRAY [1..25] OF + {$IFDEF WIN32} packed {$ENDIF} RECORD + Description: STRING[65]; { answer description } + Description2: STRING[65]; { answer description #2 } + NumVoted: Integer; { # user's who picked this answer } + END; + END; + + DirF = FILE OF ULFRec; + SF = FILE OF UserIDXRec; + +CONST + DYNY: BOOLEAN = FALSE; + +FUNCTION AllCaps(S: STRING): STRING; +VAR + Counter: Byte; +BEGIN + FOR Counter := 1 TO Length(S) DO + IF (S[Counter] IN ['a'..'z']) THEN + S[Counter] := Chr(Ord(S[Counter]) - Ord('a')+Ord('A')); + AllCaps := S; +END; + +FUNCTION IntToStr(L: LongInt): STRING; +VAR + S: STRING[11]; +BEGIN + Str(L,S); + IntToStr := s; +END; + +FUNCTION SQOutSp(S: STRING): STRING; +BEGIN + WHILE (Pos(' ',S) > 0) DO + Delete(S,Pos(' ',S),1); + SQOutSp := S; +END; + +FUNCTION Exist(fn: AStr): Boolean; +VAR + DirInfo: SearchRec; +BEGIN + FindFirst(SQOutSp(fn),AnyFile,DirInfo); + Exist := (DOSError = 0); +END; + +FUNCTION SYN(B: BOOLEAN): STRING; +BEGIN + IF (B) THEN + SYN := 'Yes' + ELSE + SYN := 'No '; +END; + +FUNCTION YN: BOOLEAN; +VAR + C: CHAR; +BEGIN + Write(SQOutSp(SYN(DYNY))); + REPEAT + C := UpCase(Char(ReadKey)); + UNTIL (C IN ['Y','N',^M]); + IF (DYNY) AND (C <> 'N') THEN + C := 'Y'; + IF (DYNY) AND (C = 'N') THEN + Write(#8#8#8'No ') + ELSE IF (NOT DYNY) AND (C = 'Y') THEN + Write(#8#8'Yes'); + WriteLn; + YN := (C = 'Y'); + DYNY := FALSE; +END; + +FUNCTION PYNQ(CONST S: AStr): BOOLEAN; +BEGIN + Write(S); + PYNQ := YN; +END; + +FUNCTION StrToInt(S: STRING): LongInt; +VAR + I: Integer; + L: LongInt; +BEGIN + Val(S,L,I); + IF (I > 0) THEN + BEGIN + S[0] := Chr(I - 1); + Val(S,L,I) + END; + IF (S = '') THEN + StrToInt := 0 + ELSE + StrToInt := L; +END; + +FUNCTION GetFileSize(FileName: AStr): LongInt; +VAR + F: FILE OF Byte; + FSize: LongInt; +BEGIN + FSize := 0; + IF (Exist(SQOutSp(FileName))) THEN + BEGIN + Assign(F,SQOutSp(FileName)); + Reset(F); + FSize := FileSize(F); + Close(F); + END; + GetFileSize := FSize; +END; + +PROCEDURE KillUserVotes(DataPath: STRING; VAR User: UserRecordType); +VAR + VotingFile: FILE OF VotingR; + Topic: VotingR; + Counter: Integer; +BEGIN + IF (Exist(DataPath+'VOTING.DAT')) THEN + BEGIN + Assign(VotingFile,DataPath+'VOTING.DAT'); + Reset(VotingFile); + FOR Counter := 1 TO FileSize(VotingFile) DO + IF (User.Vote[Counter] > 0) THEN + BEGIN + Seek(VotingFile,(Counter - 1)); + Read(VotingFile,Topic); + IF (Topic.NumVoted > 0) THEN + Dec(Topic.NumVoted); + IF (Topic.Choices[User.Vote[Counter]].NumVoted > 0) THEN + Dec(Topic.Choices[User.Vote[Counter]].NumVoted); + Seek(VotingFile,(Counter - 1)); + Write(VotingFile,Topic); + User.Vote[Counter] := 0; + END; + Close(VotingFile); + END; +END; + +PROCEDURE ResetVotes(DataPath: STRING); +VAR + VotingFile: FILE OF VotingR; + Topic: VotingR; + Counter, + Counter1: Integer; +BEGIN + IF (Exist(DataPath+'VOTING.DAT')) THEN + BEGIN + Assign(VotingFile,DataPath+'VOTING.DAT'); + Reset(VotingFile); + FOR Counter := 1 TO FileSize(VotingFile) DO + BEGIN + Seek(VotingFile,(Counter - 1)); + Read(VotingFile,Topic); + Topic.NumVoted := 0;; + FOR Counter1 := 1 TO 25 DO + Topic.Choices[Counter1].NumVoted := 0; + Seek(VotingFile,(Counter - 1)); + Write(VotingFile,Topic); + END; + Close(VotingFile); + END; +END; + +PROCEDURE ReScanUserVotes(DataPath: STRING; VAR User: UserRecordType); +VAR + VotingFile: FILE OF VotingR; + Topic: VotingR; + Counter: Integer; +BEGIN + IF (Exist(DataPath+'VOTING.DAT')) THEN + BEGIN + Assign(VotingFile,DataPath+'VOTING.DAT'); + Reset(VotingFile); + FOR Counter := 1 TO FileSize(VotingFile) DO + IF (User.Vote[Counter] > 0) THEN + BEGIN + Seek(VotingFile,(Counter - 1)); + Read(VotingFile,Topic); + Inc(Topic.NumVoted); + Inc(Topic.Choices[User.Vote[Counter]].NumVoted); + Seek(VotingFile,(Counter - 1)); + Write(VotingFile,Topic); + END; + Close(VotingFile); + END; +END; + +PROCEDURE KillShortMsgs(DataPath: STRING; VAR User: UserRecordType); +VAR + ShortMsgFile: FILE OF ShortMessageRecordType; + ShortMsg: ShortMessageRecordType; + Counter: Integer; +BEGIN + IF (Exist(DataPath+'SHORTMSG.DAT')) THEN + BEGIN + Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + FOR Counter := 1 TO FileSize(ShortMsgFile) DO + BEGIN + Seek(ShortMsgFile,(Counter - 1)); + Read(ShortMsgFile,ShortMsg); + IF (ShortMsg.Destin = User.UserID) THEN + ShortMsg.Destin := -1; + Seek(ShortMsgFile,(Counter - 1)); + Write(ShortMsgFile,ShortMsg); + END; + Close(ShortMsgFile); + END; +END; + +PROCEDURE UpdateShortMsgs(DataPath: STRING; VAR User: UserRecordType; NewUserNumber: Integer); +VAR + ShortMsgFile: FILE OF ShortMessageRecordType; + ShortMsg: ShortMessageRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'SHORTMSG.DAT') THEN + BEGIN + Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + FOR Counter := 1 TO FileSize(ShortMsgFile) DO + BEGIN + Seek(ShortMsgFile,(Counter - 1)); + Read(ShortMsgFile,ShortMsg); + IF (ShortMsg.Destin = User.UserID) THEN + ShortMsg.Destin := NewUserNumber; + Seek(ShortMsgFile,(Counter - 1)); + Write(ShortMsgFile,ShortMsg); + END; + Close(ShortMsgFile); + END; +END; + +PROCEDURE PurgingShortMsgs(DataPath: STRING); +VAR + ShortMsgFile: FILE OF ShortMessageRecordType; + ShortMsgFile1: FILE OF ShortMessageRecordType; + ShortMsg: ShortMessageRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'SHORTMSG.DAT') THEN + BEGIN + Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT'); + Reset(ShortMsgFile); + Assign(ShortMsgFile1,DataPath+'SHORTMSG.BAK'); + ReWrite(ShortMsgFile1); + FOR Counter := 1 TO FileSize(ShortMsgFile) DO + BEGIN + Seek(ShortMsgFile,(Counter - 1)); + Read(ShortMsgFile,ShortMsg); + IF (ShortMsg.Destin <> -1) THEN + BEGIN + Seek(ShortMsgFile1,FileSize(ShortMsgFile1)); + Write(ShortMsgFile1,ShortMsg); + END; + END; + Close(ShortMsgFile); + Erase(ShortMsgFile); + Close(ShortMsgFile1); + ReName(ShortMsgFile1,DataPath+'SHORTMSG.DAT'); + END; +END; + +PROCEDURE KillBatchQueue(DataPath: STRING; VAR User: UserRecordType); +VAR + BatchDLFile: FILE OF BatchDlRecordType; + BatchDL: BatchDlRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'BATCHDL.DAT') THEN + BEGIN + Assign(BatchDLFile,DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + FOR Counter := 1 TO FileSize(BatchDLFile) DO + BEGIN + Seek(BatchDLFile,(Counter - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = User.UserID) THEN + BatchDL.BDLUserNum := -1; + Seek(BatchDLFile,(Counter - 1)); + Write(BatchDLFile,BatchDL); + END; + Close(BatchDLFile); + END; +END; + +PROCEDURE UpdateBatchQueue(DataPath: STRING; VAR User: UserRecordType; NewUserNumber: Integer); +VAR + BatchDLFile: FILE OF BatchDLRecordType; + BatchDL: BatchDlRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'BATCHDL.DAT') THEN + BEGIN + Assign(BatchDLFile,DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + FOR Counter := 1 TO FileSize(BatchDLFile) DO + BEGIN + Seek(BatchDLFile,(Counter - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum = User.UserID) THEN + BatchDL.BDLUserNum := NewUserNumber; + Seek(BatchDLFile,(Counter - 1)); + Write(BatchDLFile,BatchDL); + END; + Close(BatchDLFile); + END; +END; + +PROCEDURE PurgingBatchQueue(DataPath: STRING); +VAR + BatchDLFile: FILE OF BatchDLRecordType; + BatchDLFile1: FILE OF BatchDLRecordType; + BatchDL: BatchDLRecordType; + Counter: Integer; +BEGIN + IF Exist(DataPath+'BATCHDL.DAT') THEN + BEGIN + Assign(BatchDLFile,DataPath+'BATCHDL.DAT'); + Reset(BatchDLFile); + Assign(BatchDLFile1,DataPath+'BATCHDL.BAK'); + ReWrite(BatchDLFile1); + FOR Counter := 1 TO FileSize(BatchDLFile) DO + BEGIN + Seek(BatchDLFile,(Counter - 1)); + Read(BatchDLFile,BatchDL); + IF (BatchDL.BDLUserNum <> -1) THEN + BEGIN + Seek(BatchDLFile1,FileSize(BatchDLFile1)); + Write(BatchDLFile1,BatchDL); + END; + END; + Close(BatchDLFile); + Erase(BatchDLFile); + Close(BatchDLFile1); + ReName(BatchDLFile1,DataPath+'BATCHDL.DAT'); + END; +END; + +PROCEDURE KillUserEMail(DataPath,MsgPath: STRING; VAR User: UserRecordType); +VAR + MsgHdrF: FILE OF MHeaderRec; + MHeader: MHeaderRec; + MsgNum: Word; +BEGIN + IF (Exist(MsgPath+'EMAIL.HDR')) THEN + BEGIN + Assign(MsgHdrF,MsgPath+'EMAIL.HDR'); + Reset(MsgHdrF); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF ((MHeader.MTO.UserNum = User.UserID) OR (MHeader.From.UserNum = User.UserID)) THEN + Include(MHeader.Status,MDeleted); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := 0; + IF (MHeader.FROM.UserNum = User.UserID) THEN + MHeader.FROM.UserNum := 0; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + User.Waiting := 0; + END; +END; + +PROCEDURE UpdateUserEMail(MsgPath: STRING; VAR User: UserRecordType; NewUserNum: Integer); +VAR + MsgHdrF: FILE OF MHeaderRec; + MHeader: MHeaderRec; + MsgNum: Word; +BEGIN + IF (Exist(MsgPath+'EMAIL.HDR')) THEN + BEGIN + Assign(MsgHdrF,MsgPath+'EMAIL.HDR'); + Reset(MsgHdrF); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := NewUserNum; + IF (MHeader.From.UserNum = User.UserID) THEN + MHeader.From.UserNum := NewUserNum; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + END; +END; + +PROCEDURE ReScanUserEMail(MsgPath: STRING; VAR User: UserRecordType; UserNum: Integer); +VAR + MsgHdrF: FILE OF MHeaderRec; + MHeader: MHeaderRec; + MsgNum: Word; +BEGIN + IF (Exist(MsgPath+'EMAIL.HDR')) THEN + BEGIN + User.Waiting := 0; + Assign(MsgHdrF,MsgPath+'EMAIL.HDR'); + Reset(MsgHdrF); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = UserNum) THEN + IF (NOT (MDeleted IN MHeader.Status)) THEN + Inc(User.Waiting); + END; + Close(MsgHdrF); + END; +END; + +PROCEDURE UpdateDIRFilesDeletedUsers(DataPath: STRING; User,SysOpUser: UserRecordType); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: FILE OF ULFRec; + FileArea: FileAreaRecordType; + VerbF: FILE; + F: ULFRec; + Counter, + Counter1: Integer; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(VerbF,FileArea.Dlpath+FileArea.FileName+'.EXT') + ELSE + Assign(VerbF,Datapath+FileArea.FileName+'.EXT'); + Reset(VerbF,1); + IF (IOResult = 2) THEN + ReWrite(VerbF,1); + FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO + BEGIN + Seek(DirFile,Counter1); + Read(DirFile,F); + IF (F.Owner = User.UserID) THEN + BEGIN + F.Owner := SysOpUser.UserID; + F.StOwner := AllCaps(SysOpUser.Name); + END; + Seek(DirFile,Counter1); + Write(DirFile,F); + END; + Close(DirFile); + Close(VerbF); + END; + Close(FileAreaFile); +END; + +PROCEDURE UpdateDIRFilesExistingUsers(DataPath: STRING; User: UserRecordType; NewUserNum: Integer); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: FILE OF ULFRec; + VerbF: FILE; + FileArea: FileAreaRecordType; + F: ULFRec; + Counter, + Counter1: Integer; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(VerbF,FileArea.Dlpath+FileArea.FileName+'.EXT') + ELSE + Assign(VerbF,Datapath+FileArea.FileName+'.EXT'); + Reset(VerbF,1); + IF (IOResult = 2) THEN + ReWrite(VerbF,1); + FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO + BEGIN + Seek(DirFile,Counter1); + Read(DirFile,F); + IF (F.Owner = User.UserID) THEN + F.Owner := NewUserNum; + Seek(DirFile,Counter1); + Write(DirFile,F); + END; + Close(DirFile); + Close(VerbF); + END; + Close(FileAreaFile); +END; + +PROCEDURE UpdateDIRFileSize(DataPath: STRING); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: FILE OF ULFRec; + FileArea: FileAreaRecordType; + VerbF: FILE; + F: ULFRec; + Counter, + Counter1: Integer; + FSize: Longint; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(VerbF,FileArea.Dlpath+FileArea.FileName+'.EXT') + ELSE + Assign(VerbF,Datapath+FileArea.FileName+'.EXT'); + Reset(VerbF,1); + IF (IOResult = 2) THEN + ReWrite(VerbF,1); + FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO + BEGIN + Seek(DirFile,Counter1); + Read(DirFile,F); + FSize := GetFileSize(FileArea.DLPath+F.FileName); + IF (FSize = 0) THEN + BEGIN + F.SizeMod := 0; + F.Blocks := 0; + Include(F.FileStat,FIIsRequest); + END + ELSE + BEGIN + F.Blocks := FSize DIV 128; + F.SizeMod := FSize MOD 128; + END; + Seek(DirFile,Counter1); + Write(DirFile,F); + END; + Close(DirFile); + Close(VerbF); + END; + Close(FileAreaFile); +END; + +PROCEDURE UpdateFileSCNFilesExistingUsers(DataPath: STRING); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + UserFile: FILE OF UserRecordType; + UserFile2: FILE OF UserRecordType; + ScnFile: FILE OF Boolean; + ScnFile1: FILE OF Boolean; + FileArea: FileAreaRecordType; + User: UserRecordType; + Path: STRING; + Counter, + Counter1, + NumUsers: Integer; + NewScanFBase: Boolean; +BEGIN + Assign(UserFile,DataPath+'USERS.DAT'); + Reset(UserFile); + Assign(UserFile2,DataPath+'USERS.BAK'); + Reset(UserFile2); + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Path := FileArea.Dlpath+FileArea.FileName + ELSE + Path := Datapath+FileArea.FileName; + Assign(ScnFile,Path+'.SCN'); + Reset(ScnFile); + IF (IOResult = 2) THEN + ReWrite(ScnFile); + Assign(ScnFile1,Path+'.SCB'); + ReWrite(ScnFile1); + NumUsers := (FileSize(UserFile) - 1); + IF (NumUsers > FileSize(ScnFile)) THEN + BEGIN + Seek(ScnFile,FileSize(ScnFile)); + NewScanFBase := TRUE; + FOR Counter1 := FileSize(ScnFile) TO (NumUsers - 1) DO + Write(ScnFile,NewScanFBase); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(ScnFile1,FileSize(ScnFile1)); + NewScanFBase := TRUE; + Write(ScnFile1,NewScanFBase); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter1); + Read(UserFile2,User); + Seek(ScnFile,(User.UserID - 1)); + Read(ScnFile,NewScanFBase); + Seek(ScnFile1,(Counter1 - 1)); + Write(ScnFile1,NewScanFBase); + END; + Close(ScnFile); + Erase(ScnFile); + Close(ScnFile1); + ReName(ScnFile1,Path+'.SCN'); + END; + Close(FileAreaFile); + Close(UserFile); + Close(UserFile2); +END; + +PROCEDURE UpdateMsgFilesDeletedUsers(DataPath,MsgPath: STRING; User: UserRecordType); +VAR + MsgAreaFile: FILE OF MessageAreaRecordType; + MsgHdrF: FILE OF MHeaderRec; + MsgTxtF: FILE; + MsgArea: MessageAreaRecordType; + MHeader: MHeaderRec; + Counter: Integer; + MsgNum: Word; +BEGIN + Assign(MsgAreaFile,DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + FOR Counter := 0 TO (FileSize(MsgAreaFile) - 1) DO + BEGIN + Seek(MsgAreaFile,Counter); + Read(MsgAreaFile,MsgArea); + Assign(MsgHdrF,MsgPath+MsgArea.FileName+'.HDR'); + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + Assign(MsgTxtF,MsgPath+MsgArea.FileName+'.DAT'); + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := 0; + IF (MHeader.From.UserNum = User.UserID) THEN + MHeader.From.UserNum := 0; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + Close(MsgTxtF); + END; + Close(MsgAreaFile); +END; + +PROCEDURE UpdateMsgFilesExistingUsers(DataPath,MsgPath: STRING; User: UserRecordType; NewUserNum: Integer); +VAR + MsgAreaFile: FILE OF MessageAreaRecordType; + MsgHdrF: FILE OF MHeaderRec; + MsgTxtF: FILE; + MsgArea: MessageAreaRecordType; + MHeader: MHeaderRec; + Counter: Integer; + MsgNum: Word; +BEGIN + Assign(MsgAreaFile,DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + FOR Counter := 0 TO (FileSize(MsgAreaFile) - 1) DO + BEGIN + Seek(MsgAreaFile,Counter); + Read(MsgAreaFile,MsgArea); + Assign(MsgHdrF,MsgPath+MsgArea.FileName+'.HDR'); + Reset(MsgHdrF); + IF (IOResult = 2) THEN + ReWrite(MsgHdrF); + Assign(MsgTxtF,MsgPath+MsgArea.FileName+'.DAT'); + Reset(MsgTxtF,1); + IF (IOResult = 2) THEN + ReWrite(MsgTxtF,1); + FOR MsgNum := 1 TO FileSize(MsgHdrF) DO + BEGIN + Seek(MsgHdrF,(MsgNum - 1)); + Read(MsgHdrF,MHeader); + IF (MHeader.MTO.UserNum = User.UserID) THEN + MHeader.MTO.UserNum := NewUserNum; + IF (MHeader.From.UserNum = User.UserID) THEN + MHeader.From.UserNum := NewUserNum; + Seek(MsgHdrF,(MsgNum - 1)); + Write(MsgHdrF,MHeader); + END; + Close(MsgHdrF); + Close(MsgTxtF); + END; + Close(MsgAreaFile); +END; + +PROCEDURE UpdateMsgSCNFilesExistingUsers(DataPath,MsgPath: STRING); +VAR + MessageFile: FILE OF MessageAreaRecordType; + UserFile: FILE OF UserRecordType; + UserFile2: FILE OF UserRecordType; + MsgScanFile: FILE OF ScanRec; + MsgScanFile1: FILE OF ScanRec; + MsgArea: MessageAreaRecordType; + User: UserRecordType; + LastReadRecord: ScanRec; + Path: STRING; + Counter, + Counter1, + NumUsers: Integer; +BEGIN + Assign(UserFile,DataPath+'USERS.DAT'); + Reset(UserFile); + Assign(UserFile2,DataPath+'USERS.BAK'); + Reset(UserFile2); + Assign(MessageFile,DataPath+'MBASES.DAT'); + Reset(MessageFile); + FOR Counter := 0 TO (FileSize(MessageFile) - 1) DO + BEGIN + Seek(MessageFile,Counter); + Read(MessageFile,MsgArea); + Path := MsgPath+MsgArea.FileName; + Assign(MsgScanFile,Path+'.SCN'); + Reset(MsgScanFile); + IF (IOResult = 2) THEN + ReWrite(MsgScanFile); + Assign(MsgScanFile1,Path+'.SCB'); + ReWrite(MsgScanFile1); + NumUsers := (FileSize(UserFile) - 1); + IF (NumUsers > FileSize(MsgScanFile)) THEN + BEGIN + WITH LastReadRecord DO + BEGIN + LastRead := 0; + NewScan := TRUE; + END; + Seek(MsgScanFile,FileSize(MsgScanFile)); + FOR Counter1 := FileSize(MSGScanFile) TO (NumUsers - 1) DO + Write(MsgScanFile,LastReadRecord); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + WITH LastReadRecord DO + BEGIN + LastRead := 0; + NewScan := TRUE; + END; + Seek(MsgScanFile1,FileSize(MsgScanFile1)); + Write(MsgScanFile1,LastReadRecord); + END; + FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter1); + Read(UserFile2,User); + Seek(MsgScanFile,(User.UserID - 1)); + Read(MsgScanFile,LastReadRecord); + Seek(MsgScanFile1,(Counter1 - 1)); + Write(MsgScanFile1,LastReadRecord); + END; + Close(MsgScanFile); + Erase(MsgScanFile); + Close(MsgScanFile1); + ReName(MsgScanFile1,Path+'.SCN'); + END; + Close(MessageFile); + Close(UserFile); + Close(UserFile2); +END; + +PROCEDURE PackMessageArea(MsgPath,FN: STRING; MaxM: LongInt); +VAR + Buffer: ARRAY [1..4096] OF Char; + MsgHdrF1, + MsgHdrF2: FILE OF MheaderRec; + BrdF1, + BrdF2: FILE; + MHeader: MheaderRec; + Numm, + i, + IDX, + TotLoad, + Buffered: Word; + NeedPack: Boolean; + + PROCEDURE ErrMsg; + BEGIN + Writeln('Error renaming temp files while packing.'); + END; + + PROCEDURE Kill(CONST FN: AStr); + VAR + F: FILE; + BEGIN + IF Exist(FN) THEN + BEGIN + Assign(F,FN); + Erase(F); + END; + END; + +BEGIN + NeedPack := FALSE; + FN := AllCaps(FN); + FN := MsgPath + FN; + + Assign(BrdF1,FN+'.DAT'); + Reset(BrdF1,1); + IF (IOResult <> 0) THEN + Exit; + + Assign(MsgHdrF1,FN+'.HDR'); + Reset(MsgHdrF1); + + IF (IOResult <> 0) THEN + BEGIN + Close(BrdF1); + Exit + END; + + IF (MaxM <> 0) AND (FileSize(MsgHdrF1) > MaxM) THEN + BEGIN + Numm := 0; + IDX := FileSize(MsgHdrF1); + WHILE (IDX > 0) DO + BEGIN + Seek(MsgHdrF1,(IDX - 1)); + Read(MsgHdrF1,MHeader); + IF NOT (MDeleted IN MHeader.Status) THEN + Inc(Numm); + IF (Numm > MaxM) AND NOT (Permanent IN MHeader.Status) THEN + BEGIN + MHeader.Status := [MDeleted]; + Seek(MsgHdrF1,(IDX - 1)); + Write(MsgHdrF1,MHeader); + END; + Dec(IDX); + END; + END + ELSE + BEGIN + + WHILE (FilePos(MsgHdrF1) < FileSize(MsgHdrF1)) AND (NOT NeedPack) DO + BEGIN + Read(MsgHdrF1,MHeader); + IF (MDeleted IN MHeader.Status) THEN + NeedPack := TRUE; + END; + + IF (NOT NeedPack) THEN + BEGIN + Close(MsgHdrF1); + Close(BrdF1); + Exit; + END; + END; + + Assign(BrdF2,FN+'.DA1'); + ReWrite(BrdF2,1); + + Assign(MsgHdrF2,FN+'.HD2'); + ReWrite(MsgHdrF2); + + Kill(FN+'.HD3'); + Kill(FN+'.DA3'); + + IDX := 1; + i := 0; + + WHILE (i <= FileSize(MsgHdrF1) - 1) DO + BEGIN + Seek(MsgHdrF1,i); + Read(MsgHdrF1,MHeader); + + IF (MHeader.Pointer - 1 + MHeader.TextSize > FileSize(BrdF1)) OR + (MHeader.Pointer < 1) THEN + MHeader.Status := [MDeleted]; + + IF NOT (MDeleted IN MHeader.Status) THEN + BEGIN + Inc(IDX); + Seek(BrdF1,MHeader.Pointer - 1); + MHeader.Pointer := (FileSize(BrdF2) + 1); + Write(MsgHdrF2,MHeader); + + TotLoad := 0; + IF (MHeader.TextSize > 0) THEN + WHILE (MHeader.TextSize > 0) DO + BEGIN + Buffered := MHeader.TextSize; + IF (Buffered > 4096) THEN + Buffered := 4096; + Dec(MHeader.TextSize,Buffered); + BlockRead(BrdF1,Buffer[1],Buffered); + BlockWrite(BrdF2,Buffer[1],Buffered); + END; + END; + Inc(i); + END; + + Close(BrdF1); + Close(BrdF2); + Close(MsgHdrF1); + Close(MsgHdrF2); + + ReName(BrdF1,FN+'.DA3'); { ReName .DAT to .DA3 } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + Exit; + END; + + ReName(BrdF2,FN+'.DAT'); { ReName .DA2 to .DAT } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + Exit; + END; + + ReName(MsgHdrF1,FN+'.HD3'); { ReName .HDR to .HD3 } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + Erase(BrdF2); { Erase .DA2 } + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + Exit; + END; + + ReName(MsgHdrF2,FN+'.HDR'); { ReName .HD2 to .HDR } + + IF (IOResult <> 0) THEN { Didn't work, abort } + BEGIN + ErrMsg; + Erase(BrdF2); { Erase .DAT (new) } + Erase(MsgHdrF2); { Erase .HD2 (new) } + ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT } + ReName(MsgHdrF1,FN+'.HDR'); { ReName .HD3 to .HDR } + Exit; + END; + + Erase(MsgHdrF1); + Erase(BrdF1); +END; + +PROCEDURE PackMessageAreas(DataPath,MsgPath: STRING); +VAR + MsgAreaFile: FILE OF MessageAreaRecordType; + MsgArea: MessageAreaRecordType; + MArea: Integer; +BEGIN + PackMessageArea(MsgPath,'EMAIL',0); + Assign(MsgAreaFile,DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + FOR MArea := 0 TO (FileSize(MsgAreaFile) - 1) DO + BEGIN + Seek(MsgAreaFile,MArea); + Read(MsgAreaFile,MsgArea); + PackMessageArea(MsgPath,MsgArea.FIleName,MsgArea.MaxMsgs); + END; + Close(MsgAreaFile); +END; + +PROCEDURE SortFileArea(VAR DirFile1: DirF; NumFiles: Integer); +VAR + F1, + F2: ULFRec; + NumSorted, + RecNum, + RecNum1, + Gap: Integer; +BEGIN + Gap := NumFiles; + REPEAT; + Gap := (Gap DIV 2); + IF (Gap = 0) THEN + Gap := 1; + NumSorted := 0; + FOR RecNum := 1 TO (NumFiles - Gap) DO + BEGIN + RecNum1 := (RecNum + Gap); + Seek(DirFile1,(RecNum - 1)); + Read(DirFile1,F1); + Seek(DirFile1,(RecNum1 - 1)); + Read(DirFile1,F2); + IF (F1.FileName > F2.FileName) THEN + BEGIN + Seek(DirFile1,(RecNum - 1)); + Write(DirFile1,F2); + Seek(DirFile1,(RecNum1 - 1)); + Write(DirFile1,F1); + Inc(NumSorted); + END; + END; + UNTIL (NumSorted = 0) AND (Gap = 1); +END; + +PROCEDURE SortAllFileAreas(DataPath: STRING); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + DirFile: DirF; + FileArea: FileAreaRecordType; + F: ULFRec; + NumFiles, + Counter: Integer; +BEGIN + Assign(FileAreaFile,DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + IF (FADirDLPath IN FileArea.FAFlags) THEN + Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR') + ELSE + Assign(Dirfile,Datapath+FileArea.FileName+'.DIR'); + Reset(Dirfile); + IF (IOResult = 2) THEN + ReWrite(Dirfile); + NumFiles := FileSize(DirFile); + IF (NumFiles <> 0) THEN + SortFileArea(DirFile,NumFiles); + Close(DirFile); + END; + Close(FileAreaFile); +END; + +PROCEDURE InsertIndex(VAR UserIndexFile1: SF; Uname: AStr; UserNum: Integer; IsReal,IsDeleted: Boolean); +VAR + IndexR: UserIDXRec; + Current, + InsertAt: Integer; + Done: Boolean; + + PROCEDURE WriteIndex; + BEGIN + FillChar(IndexR,SizeOf(IndexR),0); + WITH IndexR DO + BEGIN + Name := Uname; + Number := UserNum; + RealName := IsReal; + Deleted := IsDeleted; + Left := -1; + Right := -1; + Write(UserIndexFile1,IndexR); + END + END; + +BEGIN + Done := FALSE; + Uname := Allcaps(Uname); + Current := 0; + Reset(UserIndexFile1); + IF (FileSize(UserIndexFile1) = 0) THEN + WriteIndex + ELSE + REPEAT + Seek(UserIndexFile1,Current); + InsertAt := Current; + Read(UserIndexFile1,IndexR); + IF (Uname < IndexR.Name) THEN + Current := IndexR.Left + ELSE IF (Uname > IndexR.Name) THEN + Current := IndexR.Right + ELSE IF (IndexR.Deleted <> IsDeleted) THEN + BEGIN + Done := TRUE; + IndexR.Deleted := IsDeleted; + IndexR.RealName := IsReal; + IndexR.Number := UserNum; + Seek(UserIndexFile1,Current); + Write(UserIndexFile1,IndexR); + END + ELSE + BEGIN + IF (UserNum <> IndexR.Number) THEN + WriteLn('Note: Duplicate user '+UName+' #'+IntToStr(IndexR.Number)+' and '+UName+' #'+IntToStr(UserNum)) + ELSE + BEGIN + IndexR.RealName := FALSE; + Seek(UserIndexFile1,Current); { Make it be his handle IF it's BOTH } + Write(UserIndexFile1,IndexR); + END; + Done := TRUE; + END; + UNTIL (Current = -1) OR (Done); + IF (Current = -1) THEN + BEGIN + IF (Uname < IndexR.Name) THEN + IndexR.Left := FileSize(UserIndexFile1) + ELSE + IndexR.Right := FileSize(UserIndexFile1); + Seek(UserIndexFile1,InsertAt); + Write(UserIndexFile1,IndexR); + Seek(UserIndexFile1,FileSize(UserIndexFile1)); + WriteIndex; + END; + Close(UserIndexFile1); +END; + +PROCEDURE PackUsers; +VAR + GeneralFile: FILE OF GeneralRecordType; + UserFile: FILE OF UserRecordType; + UserFile1: FILE OF UserRecordType; + UserFile2: FILE OF UserRecordType; + UserIndexFile: SF; + F: FILE; + General: GeneralRecordType; + User, + SysOpUser: UserRecordType; + DeleteDateStr: STRING; + TotalUsers, + Counter: Integer; + Year: Word; + PackedDeleteDate: LongInt; + UsersToDelete, + DeleteByDate, + InvalidDate: Boolean; +BEGIN + DeleteByDate := FALSE; + + IF (ParamCount > 0) THEN + FOR Counter := 1 TO ParamCount DO + IF (AllCaps(Copy(ParamStr(Counter),1,2)) = AllCaps('-D')) THEN + BEGIN + DeleteDateStr := Copy(ParamStr(Counter),3,Length(ParamStr(Counter))); + InvalidDate := FALSE; + IF (Length(DeleteDateStr) <> 10) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) = 0) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) > 12) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,4,2)) = 0) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) IN [1,3,5,7,8,10,12]) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 31) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) IN [4,6,9,11]) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 30) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) = 2) AND ((StrToInt(Copy(DeleteDateStr,7,4)) MOD 4) <> 0) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 28) THEN + InvalidDate := TRUE; + IF (StrToInt(Copy(DeleteDateStr,1,2)) = 2) AND ((StrToInt(Copy(DeleteDateStr,7,4)) MOD 4) = 0) THEN + IF (StrToInt(Copy(DeleteDateStr,4,2)) > 29) THEN + InvalidDate := TRUE; + GetYear(Year); + IF (StrToInt(Copy(DeleteDateStr,7,4)) > Year) THEN + InvalidDate := TRUE; + + IF (InvalidDate) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'Invalid date or format, valid format is "00/00/0000'); + Exit; + END + ELSE + BEGIN + PackedDeleteDate := Date2PD(DeleteDateStr); + DeleteByDate := TRUE; + END; + END; + + ClrScr; + WriteLn('Renegade User Packer Version 1.0'); + Writeln('Copyright 2007 - The Renegade Developement Team'); + WriteLn; + Writeln('This utility will pack your Renegade BBS Version 09/30/06 '); + WriteLn('USERS.DAT file and update all required data files.'); + WriteLn; + WriteLn('User''s to be packed:'); + WriteLn(' - All user''s currently marked for deletion'); + IF (DeleteByDate) THEN + WriteLn(' - All user''s that have not logged on since '+DeleteDateStr); + WriteLn; + WriteLn('This process could take awhile depending on the total number'); + WriteLn('of files on your BBS that require update.'); + WriteLn; + IF PYNQ('Do you wish to continue? ') THEN + BEGIN + WriteLn; + IF (NOT Exist('RENEGADE.DAT')) THEN + WriteLn('This utility must be executed in the same directory as RENEGADE.DAT!') + ELSE + BEGIN + Write('Reading RENEGADE.DAT ... '); + Assign(GeneralFile,'RENEGADE.DAT'); + Reset(GeneralFile); + Read(GeneralFile,General); + Close(GeneralFile); + WriteLn('Done!'); + + WriteLn; + Write('Checking USERS.DAT for user''s to pack ... '); + Assign(UserFile,General.DataPath+'USERS.DAT'); + Reset(UserFile); + UsersToDelete := FALSE; + Counter := 2; + WHILE (Counter <= (FileSize(UserFile) - 1)) AND (NOT UsersToDelete) DO + BEGIN + Seek(UserFile,Counter); + Read(UserFile,User); + IF (Deleted IN User.SFlags) OR (DeleteByDate) AND (NOT (FNoDeletion IN User.Flags)) + AND (User.LastOn < PackedDeleteDate) THEN + UsersToDelete := TRUE; + Inc(Counter); + END; + WriteLn('Done!'); + + IF (NOT UsersToDelete) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'No deleted user''s found to pack!'); + END + ELSE + BEGIN + + Write('Updating USERS.DAT "UserID" with record number for all user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile) - 1) DO + BEGIN + Seek(UserFile,Counter); + Read(UserFile,User); + User.UserID := Counter; + Seek(UserFile,Counter); + Write(UserFile,User); + END; + WriteLn('Done!'); + + Write('Locating deleted user''s and creating USERS.DEL and USERS.BAK ... '); + Assign(UserFile1,General.DataPath+'USERS.DEL'); + ReWrite(UserFile1); + Assign(UserFile2,General.DataPath+'USERS.BAK'); + ReWrite(UserFile2); + Seek(UserFile,0); + Read(UserFile,User); + User.UserID := 0; + Seek(UserFile2,FileSize(UserFile2)); + Write(UserFile2,User); + Seek(UserFile,1); + Read(UserFile,User); + User.UserID := 1; + Seek(UserFile2,FileSize(UserFile2)); + Write(UserFile2,User); + FOR Counter := 2 TO (FileSize(UserFile) - 1) DO + BEGIN + Seek(UserFile,Counter); + Read(UserFile,User); + IF (Deleted IN User.SFlags) OR (DeleteByDate) AND (NOT (FNoDeletion IN User.Flags)) + AND (User.LastOn < PackedDeleteDate) THEN + BEGIN + Seek(UserFile1,FileSize(UserFile1)); + Write(UserFile1,User); + END + ELSE + BEGIN + Seek(UserFile2,FileSize(UserFile2)); + Write(UserFile2,User); + END; + END; + Close(UserFile); + Close(UserFile2); + WriteLn('Done!'); + + Write('Removing voting records for deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillUserVotes(General.DataPath,User); + Seek(UserFile1,Counter); + Write(UserFile1,User); + END; + WriteLn('Done!'); + + Write('Setting SHORTMSG.DAT "Destin" to -1 for deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillShortMsgs(General.DataPath,User); + END; + WriteLn('Done!'); + + Write('Updating SHORTMSG.DAT "Destin" with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateSHortMsgs(General.DataPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Setting BATCHDL.DAT "BDLUserNum" to -1 for all deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillBatchQueue(General.DataPath,User); + END; + WriteLn('Done!'); + + Write('Updating BATCHDL.DAT "BDLUserNum" with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateBatchQueue(General.DataPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Setting EMAIL.HDR "MDeleted" for email to/from deleted user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + KillUserEMail(General.DataPath,General.MsgPath,User); + Seek(UserFile1,Counter); + Write(UserFile1,User); + END; + WriteLn('Done!'); + + Write('Updating EMAIL.HDR "MTO/FROM" with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateUserEMail(General.MsgPath,User,Counter); + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Updating *.DIR files with sysop name/number for all deleted user''s ... '); + Assign(UserFile2,General.DataPath+'USERS.BAK'); + Reset(UserFile2); + Seek(UserFile2,1); + Read(UserFile2,SysOpUser); + Close(UserFile2); + Reset(UserFile1); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + UpdateDIRFilesDeletedUsers(General.DataPath,User,SysOpUser); + END; + WriteLn('Done!'); + + Write('Updating *.DIR files with new user number ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateDIRFilesExistingUsers(General.DataPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Setting *.HDR files "MTO/FROM" to 0 for all deleted user''s ... '); + Reset(UserFile1); + FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO + BEGIN + Seek(UserFile1,Counter); + Read(UserFile1,User); + UpdateMsgFilesDeletedUsers(General.DataPath,General.MsgPath,User); + END; + WriteLn('Done!'); + + Write('Updating *.HDR files with new user number for existing user''s ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + UpdateMsgFilesExistingUsers(General.DataPath,General.MsgPath,User,Counter); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Updating file area scan flags for existing user''s ... '); + UpdateFileSCNFilesExistingUsers(General.DataPath); + WriteLn('Done!'); + + Write('Updating message area scan flags for existing user''s ... '); + UpdateMsgSCNFilesExistingUsers(General.DataPath,General.MsgPath); + WriteLn('Done!'); + + Write('Re-Scaning email waiting for existing user''s ... '); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + ReScanUserEMail(General.MsgPath,User,Counter); + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + WriteLn('Done!'); + + Write('Re-Scaning voting for existing user''s ... '); + ResetVotes(General.DataPath); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + ReScanUserVotes(General.DataPath,User); + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + WriteLn('Done!'); + + Write('Updating UserID with record number for existing user''s ... '); + FOR Counter := 0 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + User.UserID := Counter; + Seek(UserFile2,Counter); + Write(UserFile2,User); + END; + WriteLn('Done!'); + + Write('Purging SHORTMSG.DAT of deleted records ... '); + PurgingShortMsgs(General.DataPath); + WriteLn('Done!'); + + Write('Purging BATCHDL.DAT of deleted records ... '); + PurgingBatchQueue(General.DataPath); + WriteLn('Done!'); + + Write('Updating all File Area file size ... '); + UpdateDIRFileSize(General.DataPath); + WriteLn('Done!'); + + Write('Sorting all file areas ... '); + SortAllFileAreas(General.DataPath); + WriteLn('Done!'); + + Write('Packing all message areas ... '); + PackMessageAreas(General.DataPath,General.MsgPath); + WriteLn('Done!'); + + Write('Deleting USERS.DEL ... '); + Close(UserFile1); + Erase(UserFile1); + WriteLn('Done!'); + + Write('Deleting USERS.DAT ... '); + Erase(UserFile); + WriteLn('Done!'); + + Write('Re-Naming USERS.BAK to USERS.DAT ... '); + ReName(UserFile2,General.DataPath+'USERS.DAT'); + WriteLn('Done!'); + + Write('Deleting USERS.IDX ... '); + Assign(F,General.DataPath+'USERS.IDX'); + Erase(F); + WriteLn('Done!'); + + Write('Creating and re-indexing USERS.IDX ... '); + TotalUsers := 0; + Assign(UserIndexFile,General.DataPath+'USERS.IDX'); + ReWrite(UserIndexFile); + Reset(UserFile2); + FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO + BEGIN + Seek(UserFile2,Counter); + Read(UserFile2,User); + IF NOT (Deleted IN User.SFLags) THEN + Inc(TotalUsers); + InsertIndex(UserIndexFile,User.Name,Counter,FALSE,(Deleted IN User.SFLags)); + InsertIndex(UserIndexFile,User.RealName,Counter,TRUE,(Deleted IN User.SFLags)); + END; + Close(UserFile2); + WriteLn('Done!'); + + Write('Updating RENEGADE.DAT "NumUsers" ... '); + Assign(GeneralFile,'RENEGADE.DAT'); + Reset(GeneralFile); + Read(GeneralFile,General); + General.NumUsers := TotalUsers; + Seek(GeneralFile,0); + Write(GeneralFile,General); + Close(GeneralFile); + WriteLn('Done!'); + + WriteLn; + WriteLn(^G^G^G'Your USERS.DAT file has been packed and associated files have been updated.'); + END; + END; + END; +END; + +BEGIN + PackUsers; +END. \ No newline at end of file diff --git a/SOURCE/UNUSED/RGMAINTX.DAT b/SOURCE/UNUSED/RGMAINTX.DAT new file mode 100644 index 0000000000000000000000000000000000000000..a9ccd70a0deed664a5aadd8b4be4f33801a83ba9 GIT binary patch literal 461 zcmZXQ(M!WH5XJ@n10Mz9lR8jDw^|?EURK8RY1F}#J%|sHq-(Ir%_OrF`p0{1r-B9o z$=!GN-Th7ni-(!mNjMP{=u$b=@Dx=LKecqs%nb#q$^MEZBP!&ecPXcn?Ab`KHwH}z0tvga%>B-3Q?~c-9=G! z)!x=)-*8p?$L;@y)4t)dRKhC=>npYmg+fkcNtL!6eC(7Dnr94zvKy8ktzOV literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGNOTE.EXE b/SOURCE/UNUSED/RGNOTE.EXE new file mode 100644 index 0000000000000000000000000000000000000000..218c2fb3fa7678d3e05e3ae3c8240239c8e4c4d1 GIT binary patch literal 9552 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 '') AND (S[1] = '$') THEN + BEGIN + Delete(S,1,1); + S := AllCaps(S); + RGStrNum := -1; + IF (S = 'INTERNAL_USE_ONLY') THEN + RGStrNum := 0 + ELSE IF (S = 'ONLY_CHANGE_LOCALLY') THEN + RGStrNum := 1 + ELSE IF (S = 'INVALID_MENU_NUMBER') THEN + RGStrNum := 2 + ELSE IF (S = 'MINIMUM_BAUD_LOGON_PW') THEN + RGStrNum := 3 + ELSE IF (S = 'MINIMUM_BAUD_LOGON_HIGH_LOW_TIME_PW') THEN + RGStrNum := 4 + ELSE IF (S = 'MINIMUM_BAUD_LOGON_HIGH_LOW_TIME_NO_PW') THEN + RGStrNum := 5 + ELSE IF (S = 'LOGON_EVENT_RESTRICTED_1') THEN + RGStrNum := 6 + ELSE IF (S = 'LOGON_EVENT_RESTRICTED_2') THEN + RGStrNum := 7 + ELSE IF (S = 'NAME_NOT_FOUND') THEN + RGStrNum := 8 + ELSE IF (S = 'ILLEGAL_LOGON') THEN + RGStrNum := 9 + ELSE IF (S = 'LOGON_NODE_ACS') THEN + RGStrNum := 10 + ELSE IF (S = 'LOCKED_OUT') THEN + RGStrNum := 11 + ELSE IF (S = 'LOGGED_ON_ANOTHER_NODE') THEN + RGStrNum := 12 + ELSE IF (S = 'INCORRECT_BIRTH_DATE') THEN + RGStrNum := 13 + ELSE IF (S = 'INSUFFICIENT_LOGON_CREDITS') THEN + RGStrNum := 14 + ELSE IF (S = 'LOGON_ONCE_PER_DAY') THEN + RGStrNum := 15 + ELSE IF (S = 'LOGON_CALLS_ALLOWED_PER_DAY') THEN + RGStrNum := 16 + ELSE IF (S = 'LOGON_TIME_ALLOWED_PER_DAY_OR_CALL') THEN + RGStrNum := 17 + ELSE IF (S = 'LOGON_MINUTES_LEFT_IN_BANK') THEN + RGStrNum := 18 + ELSE IF (S = 'LOGON_MINUTES_LEFT_IN_BANK_TIME_LEFT') THEN + RGStrNum := 19 + ELSE IF (S = 'LOGON_BANK_HANGUP') THEN + RGStrNum := 20 + ELSE IF (S = 'LOGON_ATTEMPT_IEMSI_NEGOTIATION') THEN + RGStrNum := 21 + ELSE IF (S = 'LOGON_IEMSI_NEGOTIATION_SUCCESS') THEN + RGStrNum := 22 + ELSE IF (S = 'LOGON_IEMSI_NEGOTIATION_FAILED') THEN + RGStrNum := 23 + ELSE IF (S = 'LOGON_ATTEMPT_DETECT_EMULATION') THEN + RGStrNum := 24 + ELSE IF (S = 'LOGON_RIP_DETECTED') THEN + RGStrNum := 25 + ELSE IF (S = 'LOGON_ANSI_DETECT_OTHER') THEN + RGStrNum := 26 + ELSE IF (S = 'LOGON_ANSI_DETECT') THEN + RGStrNum := 27 + ELSE IF (S = 'LOGON_AVATAR_DETECT_OTHER') THEN + RGStrNum := 28 + ELSE IF (S = 'LOGON_AVATAR_DETECT') THEN + RGStrNum := 29 + ELSE IF (S = 'LOGON_EMULATION_DETECTED') THEN + RGStrNum := 30 + ELSE IF (S = 'SHUTTLE_LOGON_VALIDATION_STATUS') THEN + RGStrNum := 31 + ELSE IF (S = 'LOGON_CLOSED_BBS') THEN + RGStrNum := 32 + ELSE IF (S = 'NODE_ACTIVITY_WAITING_ONE') THEN + RGStrNum := 33 + ELSE IF (S = 'NODE_ACTIVITY_WAITING_TWO') THEN + RGStrNum := 34 + ELSE IF (S = 'NODE_ACTIVITY_LOGGING_ON') THEN + RGStrNum := 35 + ELSE IF (S = 'NODE_ACTIVITY_NEW_USER_LOGGING_ON') THEN + RGStrNum := 36 + ELSE IF (S = 'NODE_ACTIVITY_MISCELLANEOUS') THEN + RGStrNum := 37 + ELSE IF (S = 'NEW_USER_PASSWORD_INVALID') THEN + RGStrNum := 38 + ELSE IF (S = 'NEW_USER_PASSWORD_ATTEMPT_EXCEEDED') THEN + RGStrNum := 39 + ELSE IF (S = 'NEW_USER_RECORD_SAVING') THEN + RGStrNum := 40 + ELSE IF (S = 'NEW_USER_RECORD_SAVED') THEN + RGStrNum := 41 + ELSE IF (S = 'NEW_USER_APPLICATION_LETTER') THEN + RGStrNum := 42 + ELSE IF (S = 'NEW_USER_IN_RESPONSE_TO_SUBJ') THEN + RGStrNum := 43; + + IF (RGStrNum = -1) THEN + BEGIN + WriteLn('Error!'); + WriteLn; + WriteLn(^G^G^G'The following string definition is invalid:'); + WriteLn; + WriteLn(' '+S); + Found := FALSE; + END + ELSE + BEGIN + Done := FALSE; + WITH StrPointer DO + BEGIN + Pointer := (FileSize(RGStrFile) + 1); + TextSize := 0; + END; + Seek(RGStrFile,FileSize(RGStrFile)); + WHILE NOT EOF(F) AND (NOT Done) DO + BEGIN + ReadLn(F,S); + IF (S[1] = '$') THEN + Done := TRUE + ELSE + BEGIN + Inc(StrPointer.TextSize,(Length(S) + 1)); + BlockWrite(RGStrFile,S,(Length(S) + 1)); + END; + END; + Seek(StrPointerFile,RGStrNum); + Write(StrPointerFile,StrPointer); + END; + END; + END; + Close(F); + Close(RGStrFile); + Close(StrPointerFile); + IF (Found) THEN + WriteLn('Done!') + ELSE + BEGIN + Erase(StrPointerFile); + Erase(RGStrFile); + END; +END. \ No newline at end of file diff --git a/SOURCE/UNUSED/RGNOTE.TXT b/SOURCE/UNUSED/RGNOTE.TXT new file mode 100644 index 0000000..0ff2952 --- /dev/null +++ b/SOURCE/UNUSED/RGNOTE.TXT @@ -0,0 +1,181 @@ +$Internal_Use_Only +%LF^7This is for internal use only. +%PA +$ + +$Only_Change_Locally +%LF^7This can only be changed locally. +%PA +$ + +$Invalid_Menu_Number +%LF^7Invalid menu number. +$ + +$Minimum_Baud_Logon_PW +%LFYou must be using at least %M7 baud to call this BBS. +$ + +$Minimum_Baud_Logon_High_Low_Time_PW +%LFHours for those using less than %M7 baud are from %H3 to %H4. +$ + +$Minimum_Baud_Logon_High_Low_Time_No_PW +%LFNOTE: Callers at less than %M7 baud are restricted to the + following hours ONLY: %H3 to %H4. +$ + +$Logon_Event_Restricted_1 +%LFRestricted: Only certain users allowed online at this time. +$ + +$Logon_Event_Restricted_2 +%LFThis time window allows certain other users to get online. +Please call back later, after it has ended. +$ + +$Name_Not_Found +%LFName not found in user list. +$ + +$Illegal_Logon +%LF|15Logon Incorrect. +$ + +$Logon_Node_ACS +%LFYou don't have the required ACS to logon to this node. +$ + +$Locked_Out +%LFYou have been locked out of the BBS by the SysOp. +$ + +$Logged_On_Another_Node +%LFYou are already logged in on another node. +$ + +$Incorrect_Birth_Date +%LFYou entered an incorrect birthdate. +$ + +$Insufficient_Logon_Credits +%LFYou have insufficient credits for online time. +$ + +$Logon_Once_Per_Day +%LFYou can only log on once per day. +$ + +$Logon_Calls_Allowed_Per_Day +%LFYou can only log on %CA times per day. +$ + +$Logon_Time_Allowed_Per_Day_Or_Call +%LFYou can only logon for %T1 minutes per %CD. +$ + +$Logon_Minutes_Left_In_Bank +%LF^5However, you have %TB minutes left in your Time Bank. +$ + +$Logon_Minutes_Left_In_Bank_Time_Left +%LF^5In your account: ^3%TB^5 Time left online: ^3%TL +$ + +$Logon_Bank_Hangup +%LFHanging up. +$ + +$Logon_Attempt_IEMSI_Negotiation + +Attempting IEMSI negotiation ... @ +$ + +$Logon_IEMSI_Negotiation_Success +success. + +$Logon_IEMSI_Negotiation_Failed +failure. + +$Logon_Attempt_Detect_Emulation + +Attempting to detect emulation ... @ +$ + +$Logon_RIP_Detected +RIP +$ + +$Logon_ANSI_Detect_Other +/Ansi +$ + +$Logon_ANSI_Detect +Ansi +$ + +$Logon_Avatar_Detect_Other +/Avatar +$ + +$Logon_Avatar_Detect +Avatar +$ + +$Logon_Emulation_Detected + detected. + +$ + +$Shuttle_Logon_Validation_Status +%LFYou have not been validated yet. +$ + +$Logon_Closed_BBS +%LFThis BBS is currently not accepting new users, hanging up ... @ +$ + +$Node_Activity_Waiting_One +|02Waiting For Logon +$ + +$Node_Activity_Waiting_Two + |08- +$ + +$Node_Activity_Logging_On +Logging on +$ + +$Node_Activity_New_User_Logging_On +New user logging on +$ + +$Node_Activity_Miscellaneous +Miscellaneous +$ + +$New_User_Password_Invalid +%LFInvalid password, keep trying. +$ + +$New_User_Password_Attempt_Exceeded +%LFYou have exceeded the maximum new user logon attempts, hanging up. +$ + +$New_User_Record_Saving +%LFSaving your information ... @ +$ + +$New_User_Record_Saved +^3Saved. +$ + +$New_User_Application_Letter +%LFYou must now send a new user application letter to the SysOp. +%PA +$ + +$New_User_In_Response_To_Subj +New User Application +$ \ No newline at end of file diff --git a/SOURCE/UNUSED/RGNOTEPR.DAT b/SOURCE/UNUSED/RGNOTEPR.DAT new file mode 100644 index 0000000000000000000000000000000000000000..bc3258c69d5c1c9989023ddb3237aeb9490c7cd9 GIT binary patch literal 352 zcmXxeJxjtt9KiA4KdsEd7E1_%Oe?d}2%@JULVAF32wZvrAviR&G&r?1MVniTQ?J9J zrPt8p6g0Is_i^aB?|nEp?kSmX>s{BfaZP-?~#Xi8$p8I~;L^ixUwA?(mpx z?(>Z`esY7q++!&fvBoP_`M^5+JmD7)nNLT|v&1qlndSeuv0t}&q#0ey6rVWBXJ+`y uY4$kBKFj=IgBgbxxXkf;+nnVA^Sow`w_IhH7aXw2A!qo*bME@Y_`W}&h#DpU literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGNOTETX.DAT b/SOURCE/UNUSED/RGNOTETX.DAT new file mode 100644 index 0000000000000000000000000000000000000000..45dceaf375cbcc6e685a4efb9d1191462087b380 GIT binary patch literal 1604 zcmZ`)U29uM5H+M9A<(=u6#CR@liN`0Y~nb^sc1_i*Fge*5vi2C2v+xwq{a8{s{0{F z;2+;Jd#`0Zq(Vs6-8nO7&YW34EzaIgk0(nL2=BS`WNc(_bxkQSIa_bkgW{_H^L<>Y zZGKKOrgEw6f-9T7Og$g+`EQ~;i04|hHupGNN{mE zIqlI25;GFzs-MMr4$+%3qAj4~lAlw4&0Sr)8)3Z6R4y;hKK6Et{D~qTw%{IJLOd$j zM{TUADODu}5<^#GSxDp_qiIenj~5fc&N zX1ctlT4Rv=r04h|6KSafv8}jLKZqI{MXZaMd9oFzp0iSILR8=3{Py7J%q^Uyku9C~ zTt@X99?SSDXP-;DHH$jr`QKzbn(Cj7MX@@=vUC`qbrq{O9WrBP%vKC@EjlDLFwbc) zXPRyDpW{uqT&WiwNam?)&$`-3Zm}EKf|&+=kt3H7g91n0*e(J}_%__?8(dqekM3xsW8XXOYE2Ze& z!;s1no2d5op6x`#0~JSDhqy_w<2L@mhtbuSFZ(u_FXZFvm;JSl+JDu4J?cfX~% zuH3ZPHM=KYEf{A-8;)v#n7lY*Ay}?V@T-kjJ^`R{ZpmA|X;)_-8s7ESHt^*3)$4z> z$vwWuD6;h*w|g(2x3Av5c!Y;p6lcG^=u%}viZIT8b8bS(b*(MC6n+G!yDM;|L%4Ci z+NW#g6-B=RLY?k*#-B=NtY)@fcBI2O5DJ A{{R30 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGQUOTE.EXE b/SOURCE/UNUSED/RGQUOTE.EXE new file mode 100644 index 0000000000000000000000000000000000000000..e815c0d7b936ecc187632c714d0d3f6705ba42aa GIT binary patch literal 7344 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 '') AND (S[1] = '$') THEN + BEGIN + Delete(S,1,1); + S := AllCaps(S); + RGStrNum := -1; + IF (S = 'SYSTEM_CONFIGURATION_MENU') THEN + RGStrNum := 0 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION') THEN + RGStrNum := 1 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_BBS_NAME') THEN + RGStrNum := 2 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_BBS_PHONE') THEN + RGStrNum := 3 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_TELNET_URL') THEN + RGStrNum := 4 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSOP_NAME') THEN + RGStrNum := 5 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSOP_CHAT_HOURS') THEN + RGStrNum := 6 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_MINIMUM_BAUD_HOURS') THEN + RGStrNum := 7 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_DOWNLOAD_HOURS') THEN + RGStrNum := 8 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_MINIMUM_BAUD_DOWNLOAD_HOURS') THEN + RGStrNum := 9 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSOP_PASSWORD_MENU') THEN + RGStrNum := 10 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSOP_PASSWORD') THEN + RGStrNum := 11 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_NEW_USER_PASSWORD') THEN + RGStrNum := 12 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_BAUD_OVERRIDE_PASSWORD') THEN + RGStrNum := 13 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_PRE_EVENT_TIME') THEN + RGStrNum := 14 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS') THEN + RGStrNum := 15 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_GLOBAL') THEN + RGStrNum := 16 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_START') THEN + RGStrNum := 17 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_SHUTTLE') THEN + RGStrNum := 18 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_NEW_USER') THEN + RGStrNum := 19 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_MESSAGE_READ') THEN + RGStrNum := 20 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_SYSTEM_MENUS_FILE_LISTING') THEN + RGStrNum := 21 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_BULLETIN_PREFIX') THEN + RGStrNum := 22 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_LOCAL_SECURITY') THEN + RGStrNum := 23 + + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_DATA_PATH') THEN + RGStrNum := 24 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_MISC_PATH') THEN + RGStrNum := 25 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_MSG_PATH') THEN + RGStrNum := 26 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_NODELIST_PATH') THEN + RGStrNum := 27 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_LOG_PATH') THEN + RGStrNum := 28 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_TEMP_PATH') THEN + RGStrNum := 29 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_PROTOCOL_PATH') THEN + RGStrNum := 30 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_ARCHIVE_PATH') THEN + RGStrNum := 31 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_ATTACH_PATH') THEN + RGStrNum := 32 + ELSE IF (S = 'MAIN_BBS_CONFIGURATION_MULTNODE_PATH') THEN + RGStrNum := 33; + IF (RGStrNum = -1) THEN + BEGIN + WriteLn('Error!'); + WriteLn; + WriteLn(^G^G^G'The following string definition is invalid:'); + WriteLn; + WriteLn(' '+S); + Found := FALSE; + END + ELSE + BEGIN + Done := FALSE; + WITH StrPointer DO + BEGIN + Pointer := (FileSize(RGStrFile) + 1); + TextSize := 0; + END; + Seek(RGStrFile,FileSize(RGStrFile)); + WHILE NOT EOF(F) AND (NOT Done) DO + BEGIN + ReadLn(F,S); + IF (S[1] = '$') THEN + Done := TRUE + ELSE + BEGIN + Inc(StrPointer.TextSize,(Length(S) + 1)); + BlockWrite(RGStrFile,S,(Length(S) + 1)); + END; + END; + Seek(StrPointerFile,RGStrNum); + Write(StrPointerFile,StrPointer); + END; + END; + END; + Close(F); + Close(RGStrFile); + Close(StrPointerFile); + IF (Found) THEN + WriteLn('Done!') + ELSE + BEGIN + Erase(StrPointerFile); + Erase(RGStrFile); + END; +END. \ No newline at end of file diff --git a/SOURCE/UNUSED/RGSCFG.TXT b/SOURCE/UNUSED/RGSCFG.TXT new file mode 100644 index 0000000..0413143 --- /dev/null +++ b/SOURCE/UNUSED/RGSCFG.TXT @@ -0,0 +1,187 @@ +$System_Configuration_Menu +%CL^5System Configuration:^1 + +^1A. Main BBS Configuration B. Modem/Node Configuration +^1C. System ACS Settings D. System Variables +^1E. System Toggles F. File System Configuration +^1G. Subscription/Validation System H. Network Configuration +^1I. Offline Mail Configuration J. Color Configuration +^1K. Archive Configuration L. Credit System Configuration +^1M. New User Log-In Toggles + +^11. Time allowed per %CD 2. Max calls per day +^13. UL/DL # files ratio 4. UL/DL K-bytes ratio +^15. Post/Call ratio 6. Max downloads per day +^17. Max download kbytes per day 8. Update System Averages + +Enter selection [^5A^4-^5M^4,^51^4-^58^4,^5Q^4=^5Quit^4]: @ +$ + +$Main_BBS_Configuration +%CL^5Main BBS Configuration:^1 + +^1A. BBS name/number : ^5%BN ^1(^5%BP^1) +^1B. Telnet Url : ^5%TN +^1C. SysOp's name : ^5%SN{15 ^1D. Renegade Version : ^5%VR +^1E. SysOp chat hours : ^5%CS ^1F. Minimum baud hours : ^5%BL +^1G. Regular DL hours : ^5%DH ^1H. Minimum baud DL hrs: ^5%BM +^1I. BBS Passwords : ^1J. Pre-event warning : ^5%ET seconds +^1K. System Menus : ^1L. Bulletin Prefix : ^5%PB +^1M. MultiNode support: ^5%MN ^1N. Network mode : ^5%NM + +^10. Main data files dir. : ^5%PD +^11. Miscellaneous Files dir.: ^5%PM +^12. Message file storage dir: ^5%P1 +^13. Nodelist (Version 7) dir: ^5%P2 +^14. Log files/trap files dir: ^5%PL +^15. Temporary directory : ^5%PT +^16. Protocols directory : ^5%PP +^17. Archivers directory : ^5%P7 +^18. File attach directory : ^5%PF +^19. String directory : ^5%P3 + +Enter selection [^5A^4-^5N^4,^50^4-^59^4,^5Q^4=^5Quit^4]: @ +$ + +$Main_BBS_Configuration_BBS_Name +%LFNew BBS name: @ +$ + +$Main_BBS_Configuration_BBS_Phone +%LFNew BBS phone number: @ +$ + +$Main_BBS_Configuration_Telnet_URL +%LF^1New Telnet Url:%LF^4: @ +$ + +$Main_BBS_Configuration_SysOp_Name +%LFNew SysOp name: @ +$ + +$Main_BBS_Configuration_SysOp_Chat_Hours +%LFDo you want to declare sysop chat hours? @ +$ + +$Main_BBS_Configuration_Minimum_Baud_Hours +%LFDo you want to declare hours people at the minimum baud can logon? @ +$ + +$Main_BBS_Configuration_Download_Hours +%LFDo you want to declare download hours? @ +$ + +$Main_BBS_Configuration_Minimum_Baud_Download_Hours +%LFDo you want to declare hours people at minimum baud can download? @ +$ + +$Main_BBS_Configuration_SysOp_Password_Menu +%CL^5System Passwords:^1 + +^1A. SysOp password : ^5%P4 +^1B. New user password : ^5%P5 +^1C. Baud override password: ^5%P6 + +Enter selection [^5A^4-^5C^4,^5^4=^5Quit^4]: @ +$ + +$Main_BBS_Configuration_SysOp_Password +%LFNew SysOp password: @ +$ + +$Main_BBS_Configuration_New_User_Password +%LFNew new-user password: @ +$ + +$Main_BBS_Configuration_Baud_Override_Password +%LFNew minimum baud rate override password: @ +$ + +$Main_BBS_Configuration_Pre_Event_Time +%LFNew pre-event warning time@ +$ + +$Main_BBS_Configuration_System_Menus +%CL^5System Menus:^1 + +^11. Global : ^5%M1 +^12. All Start : ^5%M2 +^13. Shutle logon : ^5%M3 +^14. New user info: ^5%M4 +^15. Message Read : ^5%M5 +^16. File List : ^5%M6 + +Enter selection [^51^4-^56^4,^5^4=^5Quit^4]: @ +$ + +$Main_BBS_Configuration_System_Menus_Global +%LFMenu for global commands (^50^4=^5None^4)@ +$ + +$Main_BBS_Configuration_System_Menus_Start +%LFMenu to start all users at@ +$ + +$Main_BBS_Configuration_System_Menus_Shuttle +%LFMenu for shuttle logon (^50^4=^5None^4)@ +$ + +$Main_BBS_Configuration_System_Menus_New_User +%LFMenu for new user information@ +$ + +$Main_BBS_Configuration_System_Menus_Message_Read +%LFMenu for message read@ +$ + +$Main_BBS_Configuration_System_Menus_File_Listing +%LFMenu for file listing@ +$ + +$Main_BBS_Configuration_Bulletin_Prefix +%LFDefault bulletin prefix: @ +$ + +$Main_BBS_Configuration_Local_Security +%LFDo you want local security to remain on? @ +$ + +$Main_BBS_Configuration_Data_Path +%LF^1New data files path (^5End with a ^1"^5\^1"):%LF^4: @ +$ + +$Main_BBS_Configuration_Misc_Path +%LF^1New miscellaneous files path (^5End with a ^1"^5\^1"):%LF^4: @ +$ + +$Main_BBS_Configuration_Msg_Path +%LF^1New message files path (^5End with a ^1"^5\^1"):%LF^4: @ +$ + +$Main_BBS_Configuration_NodeList_Path +%LF^1New nodelist files path (^5End with a ^1"^5\^1"):%LF^4: @ +$ + +$Main_BBS_Configuration_Log_Path +%LF^1New sysop log files path (^5End with a ^1"^5\^1"):%LF^4: @ +$ + +$Main_BBS_Configuration_Temp_Path +%LF^1New temporary files path (^5End with a ^1"^5\^1"):%LF^4: @ +$ + +$Main_BBS_Configuration_Protocol_Path +%LF^1New protocol files path (^5End with a ^1"^5\^1"):%LF^4: @ +$ + +$Main_BBS_Configuration_Archive_Path +%LF^1New archive files path (^5End with a ^1"^5\^1"):%LF^4: @ +$ + +$Main_BBS_Configuration_Attach_Path +%LF^1New file attach files path (^5End with a ^1"^5\^1"):%LF^4: @ +$ + +$Main_BBS_Configuration_String_Path +%LF^1New string files path (^5End with a ^1"^5\^1"):%LF^4: @ +$ diff --git a/SOURCE/UNUSED/RGSCFGPR.DAT b/SOURCE/UNUSED/RGSCFGPR.DAT new file mode 100644 index 0000000000000000000000000000000000000000..7a3f7743bfd2e64cb95e13c29df79cb1acdac6f7 GIT binary patch literal 272 zcmXZW&k6xi6vy!&%73fL!Wa};nI>y8Br+Qhp%i;dZ(=*%L9+KG#&`rP`QGj}4vw*jYYgy&5kAnz6gL=@r5h&L!XJ9*R_tDcJ^BN_ zaa*mg2 z-vfZ8NL%jMdXOpN>|%GZ=PdkWyW6L&(Mo9^ldec+;XIQ}hax$m-qsoQ+705fFd?1J zsJ>2aemX#kfX90SeAlt>sn>0ge3y22L`GceFqx~HKFsf4iM(bqWRr-i57av;-;Tw6 zj(3|(?Yq+kISnITY*$OFN4+yR$|hNP8Z?V8?~xg+aGor zcLiH6QZijIO%@`P$^`=M!5kFv!z7Hem`qp}Q~{kn%)yaMKF=a13C_J@-uqz8L5!NY z!ARv2^)Dhc*DqRT3xT7nUo?rB>IElp zm8VmdkVwo$0zbds?Wa&r$6R1f@5bKT^VWWaGq`zFy)2aMHrn^hYM-l0n$zC)RC$C= zKp=Xiu9=xrHI!?G79hALbc`YiD7Fm2yaMMSFSqvZRPe4n{5M_bUtPE#A$zlLJv3F4A-5xOKU3Pm_fw}h95YJfjR)&XmiJw%%VXTWwSJw z19J=ty>HvQbf%E+I^kQcey(ne!*m^HDj;KfvparVMZ~$>N>rl0V(vG@h%B_|_$h39 ze8w;_$fOu6IADyG4Wy3*?oDQ9Wir$&qXCk~Wu}kM8B;?b=6W)ZEwlU1^;ZGw30kzc0<58lr3S!F0di y*Y@}yB_CW5*?%2=n$NTcZNIJ^%dhJX*}PpQZ>-SRb__nm!<*8Bax?NF#{U7cBs2v8 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGSTAT.PAS b/SOURCE/UNUSED/RGSTAT.PAS new file mode 100644 index 0000000..65fcd58 --- /dev/null +++ b/SOURCE/UNUSED/RGSTAT.PAS @@ -0,0 +1,1419 @@ +UNIT RGSTAT; + +{$M 65520,0,30000} + +{Written By..........: The Renegade Developement Team} +{Date Started........: 01 Sep 2006} +{Last Update.........: ?? ??? ????} + +INTERFACE + +IMPLEMENTATION + +USES + Crt, + Dos, + Common; + +TYPE + (* + Str3 = STRING[3]; + Str8 = STRING[8]; + Str12 = STRING[12]; + Str30 = STRING[30]; + Str36 = STRING[36]; + *) + Str43 = STRING[43]; + (* + Str78 = STRING[78]; + *) + genrec = RECORD + name : str43; + info : real; + END; + + b_array = ARRAY[1..20] OF boolean; + d_array = ARRAY[1..20] OF str8; + e_array = ARRAY[1..10] OF word; + g_array = ARRAY[1..20] OF longint; + gsysactivity = ARRAY[1..20] OF real; + h_array = ARRAY[1..19] OF word; + m_array = ARRAY[1..3] OF word; + t_array = ARRAY[1..10] OF genrec; + + configinfo = RECORD + exuser: e_array; + graph_fg, + graph_bg, + logdays, + dldsl: byte; + use_real: boolean; + END; + +VAR + config: configinfo; + uage: m_array; + usex: m_array; + gdate: d_array; + ubaud: h_array; + tttimeon: t_array; + tfreqc: t_array; + tulk: t_array; + tdlk: t_array; + tprivp: t_array; + tpubp: t_array; + tfeedback: t_array; + tnumc: t_array; + tnumul: t_array; + tnumdl: t_array; + tfilep: t_array; + tupd: t_array; + tpostc: t_array; + gsysact: gsysactivity; + gmina: g_array; + gnumc: g_array; + gnewu: g_array; + gtimeu: g_array; + gmsgpub: g_array; + gmsgpvt: g_array; + gmsgfb: g_array; + gnume: g_array; + gful: g_array; + gulkb: g_array; + gfdl: g_array; + gdlkb: g_array; + +function graph_month(s: str8): str3; +BEGIN + CASE Value(copy(s,1,2)) OF + 1 : graph_month := 'Jan'; + 2 : graph_month := 'Feb'; + 3 : graph_month := 'Mar'; + 4 : graph_month := 'Apr'; + 5 : graph_month := 'May'; + 6 : graph_month := 'Jun'; + 7 : graph_month := 'Jul'; + 8 : graph_month := 'Aug'; + 9 : graph_month := 'Sep'; + 10 : graph_month := 'Oct'; + 11 : graph_month := 'Nov'; + 12 : graph_month := 'Dec'; + END; +END; + +FUNCTION RmvLeadSpace(S: AStr): AStr; +BEGIN + WHILE (S[1] = ' ') DO + Delete(S,1,1); + RmvLeadSpace := S; +END; + +FUNCTION RmvTrailSpace(S: AStr): AStr; +BEGIN + WHILE (S[Length(S)] = ' ') DO + Delete(S,Length(S),1); + RmvTrailSpace := S; +END; + +function reverse_str(s: str160): str160; +VAR + s1: str160; + counter: byte; +BEGIN + s1 := ''; + FOR counter := 20 downto 1 DO + s1 := s1 + s[counter]; + reverse_str := rmvleadspace(rmvtrailspace(s1)); +END; + +function center(s: str160; i: integer; tf: boolean): str160; +VAR + counter,strlength: integer; + which_way: boolean; +BEGIN + which_way := tf; + strlength := length(s); + FOR counter := (strlength + 1) TO i DO + BEGIN + IF which_way THEN + BEGIN + s := ' ' + s; + which_way := false; + END + ELSE + BEGIN + s := s + ' '; + which_way := TRUE; + END; + END; + center := s; +END; + +function return_time(w,w1: word): str160; +BEGIN + IF (w > 0) and (w1 > 0) THEN + return_time := inttostr(trunc(w div w1)) + ELSE + return_time := '0'; +END; + +function age(s: str160): str160; +BEGIN + age := inttostr(Value(copy(datestr,7,2)) - Value(copy(s,7,2))); +END; + +function return_age(userbday: str160): str160; +VAR + today,user_years: str160; +BEGIN + today := datestr; + user_years := age(userbday); + IF (Value(copy(userbday,1,2)) > Value(copy(today,1,2))) THEN + user_years := inttostr(Value(user_years)-1) + ELSE + IF (Value(copy(userbday,1,2)) = Value(copy(today,1,2))) THEN + IF (Value(copy(userbday,4,2)) > Value(copy(today,4,2))) THEN + user_years := inttostr(Value(user_years)-1); + return_age := user_years; +END; + +PROCEDURE read_config_file(VAR config: configinfo); +VAR + f: text; + line,line1: str160; + counter,counter1: byte; +BEGIN + assign(f,'TAGSTAT.CFG'); + {$I-} reset(f); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to access TAGSTAT.CFG!'); + halt; + END; + textcolor(lightgray); + textbackground(black); + with config DO + BEGIN + FOR counter1 := 1 TO 10 DO + exuser[counter1] := 0; + graph_fg := 9; + graph_bg := 7; + logdays := 0; + dldsl := 255; + use_real := false; + END; + counter := 1; + counter1 := 0; + WHILE not eof(f) DO + BEGIN + {$I-} readln(f,line); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to read TAGSTAT.CFG!'); + {$I-} close(f); {$I+} + IF (ioresult <> 0) THEN + writeln(^G^G^G'Unable to close TAGSTAT.CFG!'); + halt; + END; + line := rmvleadspace(rmvtrailspace(line)); + line1 := allcaps(line); + IF (line1 <> '') and (line1[1] <> '%') THEN + BEGIN + IF (pos('USER_EXCLUDE',line1) = 1) and (counter1 < 10) THEN + BEGIN + Delete(line,1,12); + inc(counter1); + config.exuser[counter1] := Value(rmvleadspace(line)); + END + ELSE IF (pos('DOWNLOAD_DSL',line1) = 1) THEN + BEGIN + Delete(line,1,12); + config.dldsl := Value(rmvleadspace(line)); + IF (config.dldsl < 0) OR (config.dldsl > 255) THEN + config.dldsl := 255; + END + ELSE IF (pos('REAL_NAME',line1) = 1) THEN + config.use_real := TRUE + ELSE IF (pos('GRAPH_BACKGROUND',line1) = 1) THEN + BEGIN + Delete(line,1,16); + config.graph_bg := Value(rmvleadspace(line)); + IF (config.graph_bg < 0) OR (config.graph_bg > 15) THEN + config.graph_bg := 7; + END + ELSE IF (pos('GRAPH_BARS',line1) = 1) THEN + BEGIN + Delete(line,1,10); + config.graph_fg := Value(rmvleadspace(line)); + IF (config.graph_fg < 0) OR (config.graph_fg > 15) THEN + config.graph_fg := 9; + END; + END; + END; + {$I-} close(f); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to close TAGSTAT.CFG!'); + halt; + END; +END; + +PROCEDURE init_d_array(VAR gdate: d_array); +VAR + counter: byte; +BEGIN + FOR counter := 1 TO 20 DO + gdate[counter] := ''; +END; + +PROCEDURE init_g_array(VAR ar: g_array; info_val: longint); +VAR + counter: byte; +BEGIN + FOR counter := 1 TO 20 DO + ar[counter] := info_val; +END; + +PROCEDURE init_gsysactivity(VAR gsysact: gsysactivity); +VAR + counter: byte; +BEGIN + FOR counter := 1 TO 20 DO + gsysact[counter] := 0.0; +END; + +PROCEDURE init_h_array(VAR ar: h_array; info_val: word); +VAR + counter: byte; +BEGIN + FOR counter := 1 TO 19 DO + ar[counter] := info_val; +END; + +PROCEDURE init_m_array(VAR ar: m_array; info_val: word); +VAR + counter: byte; +BEGIN + FOR counter := 1 TO 3 DO + ar[counter] := info_val; +END; + +PROCEDURE init_t_array(VAR ar: t_array; info_val: real); +VAR + counter: byte; +BEGIN + FOR counter := 1 TO 10 DO + BEGIN + ar[counter].name := ''; + ar[counter].info := info_val; + END; +END; + +PROCEDURE sort_ascending(s: str43; r: real; VAR tfreqc: t_array); +VAR + counter,counter1: byte; +BEGIN + IF (r > 0.0) THEN + FOR counter := 1 TO 10 DO + IF (r <= tfreqc[counter].info) THEN + BEGIN + FOR counter1 := 10 downto counter DO + IF ((counter1 - 1) > 0) THEN + tfreqc[counter1] := tfreqc[counter1-1]; + tfreqc[counter].name := s; + tfreqc[counter].info := r; + counter := 10; + END; +END; + +PROCEDURE sort_descending(s: str43; r: real; VAR ar: t_array); +VAR + counter,counter1: byte; +BEGIN + IF (r > 0.0) THEN + FOR counter := 1 TO 10 DO + IF (r >= ar[counter].info) THEN + BEGIN + FOR counter1 := 10 downto counter DO + IF ((counter1 - 1) > 0) THEN + ar[counter1] := ar[counter1 - 1]; + ar[counter].name := s; + ar[counter].info := r; + counter := 10; + END; +END; + +PROCEDURE scrn_one; +BEGIN + CLS; + Print(#3'5'+center('Renegade BBS Statistics',78,TRUE)); + NL; + Print(#3'5'+center('Copyright (c) 2006 The Renegade Developement Team',78,TRUE)); + NL; + Print(#3'5'+center('Version 1.0',78,TRUE)); + NL; + NL; + Prompt(#3'2[> '#3'4One Moment Please ... '); +END; + +PROCEDURE scrn_two(s: str160); +BEGIN + window(1,1,80,25); + CLS; + Print(#3'1[> Returning to '+s+'... '); + NL; + delay(2000); + clrscr; +END; + +function in_array(w: word; exuser: e_array): boolean; +VAR + counter: byte; + tf: boolean; +BEGIN + tf := false; + FOR counter := 1 TO 10 DO + IF (w = exuser[counter]) THEN + tf := TRUE; + in_array := tf; +END; + +PROCEDURE read_user_file(General: GeneralRecordType; VAR config: configinfo; VAR uage, + usex: m_array; VAR ubaud: h_array; VAR tfreqc,tttimeon, + tulk,tdlk,tprivp,tpubp,tfeedback,tnumc,tnumul,tnumdl, + tfilep,tupd,tpostc: t_array); +const + maxuserblock = 30000 div sizeof(UserRecordType); {* Allocate 30K *} +type + userblocktype = ARRAY[1..maxuserblock] OF UserRecordType; +VAR + uf: FILE; + userblock: ^userblocktype; + recnum,numusers,unum: word; + totuage: longint; + counter,userage: byte; + calltot,realuserblockcount: integer; + name: str43; +BEGIN + assign(uf,General.DataPath+'USER.LST'); + new(userblock); + init_m_array(uage,0); + init_m_array(usex,0); + init_h_array(ubaud,0); + init_t_array(tfreqc,255.000); + init_t_array(tttimeon,0.000); + init_t_array(tulk,0.000); + init_t_array(tdlk,0.000); + init_t_array(tprivp,0.000); + init_t_array(tpubp,0.000); + init_t_array(tfeedback,0.000); + init_t_array(tnumc,0.000); + init_t_array(tnumul,0.000); + init_t_array(tnumdl,0.000);; + init_t_array(tfilep,0.000); + init_t_array(tupd,0.000); + init_t_array(tpostc,0.000); + recnum := 0; + numusers := 0; + totuage := 0; + uage[2] := 255; + seek(uf,1); + REPEAT + blockread(uf,userblock^,maxuserblock,realuserblockcount); + FOR unum := 1 TO realuserblockcount DO + with userblock^[unum] DO + BEGIN + inc(recnum); + calltot := 0; + IF (recnum = usernum) and not in_array(usernum,config.exuser) THEN + BEGIN + userage := AgeUser(BirthDate); + Inc(totuage,userage); + (* + uage[2] := min(uage[2],userage); + uage[3] := max(userage,uage[3]); + *) + IF (Sex = 'M') THEN + inc(usex[1]) + ELSE IF (Sex = 'F') THEN + inc(usex[2]) + ELSE + inc(usex[3]); + (* + IF (hbaud = 300) THEN + inc(ubaud[1]) + ELSE IF (hbaud = 600) THEN + inc(ubaud[2]) + ELSE IF (hbaud = 1200) THEN + inc(ubaud[3]) + ELSE IF (hbaud = 2400) THEN + inc(ubaud[4]) + ELSE IF (hbaud = 4800) THEN + inc(ubaud[5]) + ELSE IF (hbaud = 7200) THEN + inc(ubaud[6]) + ELSE IF (hbaud = 9600) THEN + inc(ubaud[7]) + ELSE IF (hbaud = 12000) THEN + inc(ubaud[8]) + ELSE IF (hbaud = 14400) THEN + inc(ubaud[9]) + ELSE IF (hbaud = 16800) THEN + inc(ubaud[10]) + ELSE IF (hbaud = 19200) THEN + inc(ubaud[11]) + ELSE IF (hbaud = 21600) THEN + inc(ubaud[12]) + ELSE IF (hbaud = 24000) THEN + inc(ubaud[13]) + ELSE IF (hbaud = 26400) THEN + inc(ubaud[14]) + ELSE IF (hbaud = 28800) THEN + inc(ubaud[15]) + ELSE IF (hbaud = 31200) THEN + inc(ubaud[16]) + ELSE IF (hbaud = 33600) THEN + inc(ubaud[17]) + ELSE IF (hbaud = 38400) THEN + inc(ubaud[18]) + ELSE IF (hbaud = 57600) THEN + inc(ubaud[19]) + ELSE IF (hbaud = 115200) THEN + inc(ubaud[20]); + *) + IF config.use_real THEN + name := allcaps(realname)+' #'+inttostr(usernum) + ELSE + name := name+' #'+inttostr(usernum); + sort_ascending(name,calltot/15,tfreqc); + sort_descending(name,ttimeon,tttimeon); + sort_descending(name,ulk,tulk); + sort_descending(name,dlk,tdlk); + sort_descending(name,privpost,tprivp); + sort_descending(name,pubpost,tpubp); + sort_descending(name,feedback,tfeedback); + sort_descending(name,numcalls,tnumc); + sort_descending(name,numul,tnumul); + sort_descending(name,numdl,tnumdl); + sort_descending(name,points,tfilep); + sort_descending(name,ulk/maxr(1.0,dlk),tupd); + sort_descending(name,pubpost/maxr(1.0,numcalls),tpostc); + inc(numusers); + END; + END; + UNTIL (realuserblockcount < maxuserblock); + dispose(userblock); + uage[1] := totuage div numusers; + {$I-} close(uf); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to close USER.LST!'); + halt; + END; +END; + +PROCEDURE read_usage_file(General: GeneralRecordType; VAR config: configinfo; VAR + gdate: d_array; VAR gsysact: gsysactivity; VAR + gmina,gnumc,gnewu,gtimeu,gmsgpub,gmsgpvt,gmsgfb, + gnume,gful,gulkb,gfdl,gdlkb: g_array); +VAR + ul: text; + line: str160; + counter: byte; + + function ajust_int_size(l,size: longint): longint; + BEGIN + IF (l < 0) THEN + ajust_int_size := 0 + ELSE IF (l > size) THEN + ajust_int_size := size + ELSE + ajust_int_size := l; + END; + + function ajust_real_size(r,size: real): real; + BEGIN + IF (r < 0.0) THEN + ajust_real_size := 0.0 + ELSE IF (r > size) THEN + ajust_real_size := size + ELSE + ajust_real_size := r; + END; + +BEGIN + IF General.multiuser THEN + BEGIN + IF fileexist(General.DataPath+'USAGE.LOG') THEN + assigntxtfile(ul,General.DataPath+'USAGE.LOG') + ELSE + assigntxtfile(ul,General.multiuserpath+'USAGE.LOG'); + END + ELSE + assigntxtfile(ul,General.DataPath+'USAGE.LOG'); + {$I-} reset(ul); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to access USAGE.LOG!'); + halt; + END; + init_d_array(gdate); + init_g_array(gmina,0); + init_g_array(gnumc,0); + init_g_array(gnewu,0); + init_gsysactivity(gsysact); + init_g_array(gtimeu,0); + init_g_array(gmsgpub,0); + init_g_array(gmsgpvt,0); + init_g_array(gmsgfb,0); + init_g_array(gnume,0); + init_g_array(gful,0); + init_g_array(gulkb,0); + init_g_array(gfdl,0); + init_g_array(gdlkb,0); + FOR counter := 1 TO 5 DO + BEGIN + {$I-} readln(ul); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to read USAGE.LOG!'); + {$I-} close(ul); {$I+} + IF (ioresult <> 0) THEN + writeln(^G^G^G'Unable to close USAGE.LOG!'); + halt; + END; + END; + FOR counter := 1 TO 20 DO + IF not eof(ul) THEN + BEGIN + {$I-} readln(ul,line); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to read USAGE.LOG!'); + {$I-} close(ul); {$I+} + IF (ioresult <> 0) THEN + writeln(^G^G^G'Unable to close USAGE.LOG!'); + halt; + END; + gdate[counter] := copy(line,1,8); + Delete(line,1,8); + gmina[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,6))),99999); + Delete(line,1,6); + gnumc[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,5))),9999); + Delete(line,1,5); + gnewu[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,5))),9999); + Delete(line,1,5); + gsysact[counter] := ajust_real_size(valuer(rmvleadspace(copy(line,1,6))),100.0); + Delete(line,1,6); + gtimeu[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,5))),9999); + Delete(line,1,5); + gmsgpub[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,5))),9999); + Delete(line,1,5); + gmsgpvt[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,5))),9999); + Delete(line,1,5); + gmsgfb[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,5))),9999); + Delete(line,1,5); + gnume[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,5))),9999); + Delete(line,1,5); + gful[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,5))),9999); + Delete(line,1,5); + gulkb[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,7))),999999); + Delete(line,1,7); + gfdl[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,5))),9999); + Delete(line,1,5); + gdlkb[counter] := ajust_int_size(Value(rmvleadspace(copy(line,1,7))),999999); + inc(config.logdays); + END; + {$I-} close(ul); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to close USAGE.LOG!'); + halt; + END; +END; + +PROCEDURE read_dir_file(dirpath: pathstr; dirname: str8; name: str160; + dlpath: str30; group: integer; area: word; + sn: byte; flags: ulrecflagset; VAR frec: f_array); +const + maxfileblock = 30000 div sizeof(ulfrec); {* Allocate 30K *} +type + fileblocktype = ARRAY[1..maxfileblock] OF ulfrec; +VAR + udir: FILE; + fileblock: ^fileblocktype; + counter,counter1: byte; + fnum,realfileblockcount,recnum: word; +BEGIN + assign(udir,dirpath+dirname+'.DIR'); + setfilemode(readdenynone); + {$I-} reset(udir,sizeof(ulfrec)); {$I+} + IF (ioresult = 0) THEN + BEGIN + setfilemode(normalmode); + IF (filesize(udir) > 1) THEN + BEGIN + recnum := 0; + new(fileblock); + seek(udir,1); + REPEAT + blockread(udir,fileblock^,maxfileblock,realfileblockcount); + FOR fnum := 1 TO realfileblockcount DO + BEGIN + inc(recnum); + FOR counter := 1 TO 20 DO + IF (fileblock^[fnum].nacc > frec[counter].nacc) THEN + BEGIN + IF (counter <= (20 - 1)) THEN + FOR counter1 := (20 - 1) downto counter DO + frec[counter1 + 1] := frec[counter1]; + frec[counter].recnum := recnum; + frec[counter].filename := fileblock^[fnum].filename; + frec[counter].description := fileblock^[fnum].description; + frec[counter].nacc := fileblock^[fnum].nacc; + frec[counter].unused := fileblock^[fnum].unused; + frec[counter].blocks := fileblock^[fnum].blocks; + frec[counter].owner := fileblock^[fnum].owner; + frec[counter].date := fileblock^[fnum].date; + frec[counter].daten := fileblock^[fnum].daten; + frec[counter].flag := fileblock^[fnum].flag; + frec[counter].points := fileblock^[fnum].points; + frec[counter].dirpath := dirpath; + frec[counter].dirname := dirname; + frec[counter].dlpathname := dlpath; + frec[counter].flags := flags; + frec[counter].areaname := name; + frec[counter].seenames := sn; + frec[counter].group := group; + frec[counter].area := area; + counter := 20; + END; + END; + UNTIL (realfileblockcount < maxfileblock); + dispose(fileblock); + END; + {$I-} close(udir); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to close '+dirname+'.DIR!'); + halt; + END; + END; +END; + +PROCEDURE read_fboard_file(General: GeneralRecordType; VAR frec: f_array); +VAR + ulf: FILE OF ulrec; + uboards: ulrec; + dirpathname: str160; + counter: byte; + grp: ARRAY[0..127] OF integer; + tempgrp: integer; +BEGIN + IF General.multiuser THEN + BEGIN + IF fileexist(General.DataPath+'FBOARDS.DAT') THEN + assign(ulf,General.DataPath+'FBOARDS.DAT') + ELSE + assign(ulf,General.multiuserpath+'FBOARDS.DAT'); + END + ELSE + assign(ulf,General.DataPath+'FBOARDS.DAT'); + setfilemode(readdenynone); + {$I-} reset(ulf); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to access FBOARDS.DAT!'); + halt; + END; + setfilemode(normalmode); + FOR counter := 0 TO 127 DO + grp[counter] := -1; + tempgrp := -1; + init_f_array(frec); + WHILE not eof(ulf) DO + BEGIN + {$I-} read(ulf,uboards); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to read FBOARDS.DAT!'); + {$I-} close(ulf); {$I+} + IF (ioresult <> 0) THEN + writeln(^G^G^G'Unable to close FBOARDS.DAT!'); + halt; + END; + IF General.dynamicfile THEN + BEGIN + inc(grp[uboards.noratiogroupnum shr 1]); + tempgrp := grp[uboards.noratiogroupnum shr 1]; + END + ELSE + inc(tempgrp); + dirpathname := uboards.dlpathname; + IF (uboards.dsl <= thisuser.dsl) and (uboards.arlvl in thisuser.ar) OR + (uboards.dsl <= thisuser.dsl) and (uboards.arlvl = '@') THEN + BEGIN + IF (uboards.filename[1] = '@') THEN + BEGIN + dirpathname := General.DataPath; + uboards.filename := copy(uboards.filename,2,length(uboards.filename)); + END + ELSE IF (uboards.filename[1] = '`') THEN + BEGIN + dirpathname := General.multiuserpath; + uboards.filename := copy(uboards.filename,2,length(uboards.filename)); + END + ELSE IF (uboards.filename[1] = '+') THEN + BEGIN + dirpathname := General.altpath; + uboards.filename := copy(uboards.filename,2,length(uboards.filename)); + END; + read_dir_file(dirpathname,uboards.filename,uboards.name,uboards.dlpathname, + uboards.noratiogroupnum shr 1,tempgrp,uboards.seenames, + uboards.flags,frec); + END; + END; + {$I-} close(ulf); {$I+} + IF (ioresult <> 0) THEN + BEGIN + writeln(^G^G^G'Unable to close FBOARDS.DAT!'); + halt; + END; +END; + +PROCEDURE menu_line(c,c1: char; s,s1: str160); +BEGIN + IF (c <> ' ') THEN + BEGIN + IF (length(s) > 32) THEN + s := copy(s,1,32); + ds_write(#3'1['#3'3'+c+#3'1] : '+addspace(s,33,false)); + END + ELSE + ds_write(addspace(s,39,TRUE)); + IF (c1 <> ' ') THEN + BEGIN + IF (length(s1) > 32) THEN + s1 := copy(s1,1,32); + ds_write(#3'1['#3'3'+c1+#3'1] : '+addspace(s1,33,false)); + END; + NL; +END; + +PROCEDURE menu1_line(c: char; s: str160); +BEGIN + IF (length(s) > 73) THEN + s := copy(s,1,73); + Print(#3'1['#3'3'+c+#3'1] : '+s); +END; + +PROCEDURE sys_menu_line(s,s1: str160); +BEGIN + ds_write(#3'1'+s+#3'0'+s1); +END; + +PROCEDURE sys_menu_line1(s,s1: str160); +BEGIN + Print(#3'1'+s+#3'0'+s1); +END; + +PROCEDURE hdr(s: str160); +BEGIN + CLS; + Print(#3'5'+center('-=[ '+s+' ]=-',78,TRUE)); + NL; +END; + +PROCEDURE ftr(s: str160); +BEGIN + NL; + menu1_line('Q','Return to '+s); + NL; + ds_write(#3'4['#3'1'+realtostr1(nsl / 60,0,0)+' Mins Left'#3'4] Enter Command > '#3'1'); +END; + +PROCEDURE display_t_array(decimal,width: byte; t_ar: t_array; title, + header: str160); +VAR + counter,counter1: byte; +BEGIN + hdr('Top 10 '+title); + Print(#3'2## User Name '+center(header,55,TRUE)); + NL; + FOR counter := 1 TO 10 DO + BEGIN + ds_write(#3'4'+addspace(inttostr(counter),2,TRUE)); + IF (config.use_real) and (t_ar[counter].name = allcaps(thisuser.rname)+' #'+inttostr(thisuser.usernum)) + OR (t_ar[counter].name = thisuser.uname+' #'+inttostr(thisuser.usernum)) THEN + ds_write(' '#3'8'+t_ar[counter].name+' '#3'9') + ELSE + ds_write(' '#3'1'+t_ar[counter].name+' '#3'9'); + FOR counter1 := (length(t_ar[counter].name) + 1) TO 42 DO + ds_write('.'); + IF (t_ar[counter].info > 0) THEN + Print(#3'4'+addspace(realtostr1(t_ar[counter].info,0,decimal),width,TRUE)) + ELSE + NL; + END; + ds_pause_cr; +END; + +PROCEDURE display_t_freqcall(decimal,width: byte; t_ar: t_array; title, + header: str160); +VAR + counter,counter1: byte; +BEGIN + hdr('Top 10 '+title); + Print(#3'2## User Name '+center(header,55,TRUE)); + NL; + FOR counter := 1 TO 10 DO + BEGIN + ds_write(#3'4'+addspace(inttostr(counter),2,TRUE)); + IF config.use_real and (t_ar[counter].name = allcaps(thisuser.rname)+' #'+inttostr(thisuser.usernum)) + OR (t_ar[counter].name = thisuser.uname+' #'+inttostr(thisuser.usernum)) THEN + ds_write(' '#3'8'+t_ar[counter].name+' '#3'9') + ELSE + ds_write(' '#3'1'+t_ar[counter].name+' '#3'9'); + FOR counter1 := (length(t_ar[counter].name) + 1) TO 42 DO + ds_write('.'); + IF (t_ar[counter].info < 255) THEN + Print(#3'4'+addspace(realtostr1(t_ar[counter].info,0,decimal),width,TRUE)) + ELSE + NL; + END; + ds_pause_cr; +END; + +PROCEDURE graph_yes(tf: boolean; VAR first: b_array; i,g_fg,g_bg: byte); +BEGIN + IF (ANSI in thisuser.Flags) THEN + BEGIN + ds_textcolor(g_fg); + ds_write(''); + IF first[i] THEN + BEGIN + ds_textcolor(g_bg); + ds_write(''); + first[i] := false; + END + ELSE + BEGIN + ds_textcolor(black); + ds_write(''); + IF not tf THEN + ds_textcolor(g_bg); + END; + END + ELSE + ds_write('###'); +END; + +PROCEDURE graph_no; +BEGIN + IF (ANSI in thisuser.Flags) THEN + ds_write('') + ELSE + ds_write('...'); +END; + +PROCEDURE display_g_sysactivity(config: configinfo; gdate: d_array; gsysact: + gsysactivity; s: str160); +VAR + first: b_array; + counter,counter1: byte; + average: real; + tf: boolean; +BEGIN + FOR counter := 1 TO 20 DO + first[counter] := TRUE; + average := 0.0; + CLS; + Print(#3'5 '+center('-=[ Graph Of System Activity By Percentage ]=-',60,TRUE)); + FOR counter := 20 downto 1 DO + BEGIN + average := average + gsysact[counter]; + IF (copy(s,counter,1) <> ' ') THEN + ds_write(#3'5'+copy(s,counter,1)) + ELSE + ds_write(' '); + ds_write(#3'2'+addspace(inttostr(counter * 5),7,TRUE)+'% '); + FOR counter1 := 20 downto 1 DO + IF (gsysact[counter1] >= (counter * 5)) THEN + BEGIN + tf := TRUE; + IF (counter1 > 1) THEN + BEGIN + tf := false; + IF (gsysact[counter1 - 1] >= counter * 5) THEN + tf := TRUE; + END; + graph_yes(tf,first,counter1,config.graph_fg,config.graph_bg) + END + ELSE + BEGIN + IF (counter1 = 20) THEN + ds_textcolor(config.graph_bg); + graph_no; + END; + NL; + END; + ds_ansi_color(2); + tf := false; + FOR counter := 20 downto 1 DO + IF (gdate[counter] <> '') and not tf THEN + BEGIN + ds_write(addspace(graph_month(gdate[counter])+' ',11,TRUE)); + tf := TRUE; + END; + IF not tf THEN + ds_write(' '); + FOR counter := 20 downto 1 DO + IF (gdate[counter] <> '') THEN + ds_write(copy(gdate[counter],4,2)+' ') + ELSE + ds_write(' '); + IF (gdate[1] <> '') THEN + Print(graph_month(gdate[1])) + ELSE + NL; + average := average / config.logdays; + Print(#3'5 '+center('(Average '+reverse_str(s)+': '+realtostr1(average,0,0)+'%)',60,TRUE)); + ds_pause_cr; +END; + +PROCEDURE display_g_array(config: configinfo; gdate: d_array; g_ar: g_array; + title,side: str160; increment: longint); +VAR + first: b_array; + counter,counter1: byte; + average: longint; + tf: boolean; +BEGIN + FOR counter := 1 TO 20 DO + first[counter] := TRUE; + average := 0; + CLS; + Print(#3'5 '+center('-=[ Graph Of '+title+' ]=-',60,TRUE)); + FOR counter := 20 downto 1 DO + BEGIN + Inc(average,g_ar[counter]); + IF (copy(side,counter,1) <> ' ') THEN + ds_write(#3'5'+copy(side,counter,1)) + ELSE + ds_write(' '); + ds_write(#3'2'+addspace(inttostr(counter * increment),7,TRUE)+' '); + FOR counter1 := 20 downto 1 DO + IF (g_ar[counter1] >= (counter * increment)) THEN + BEGIN + tf := TRUE; + IF (counter1 > 1) THEN + BEGIN + tf := false; + IF (g_ar[counter1 - 1] >= (counter * increment)) THEN + tf := TRUE; + END; + graph_yes(tf,first,counter1,config.graph_fg,config.graph_bg) + END + ELSE + BEGIN + IF (counter1 = 20) THEN + ds_textcolor(config.graph_bg); + graph_no; + END; + NL; + END; + ds_ansi_color(2); + tf := false; + FOR counter := 20 downto 1 DO + IF (gdate[counter] <> '') and not tf THEN + BEGIN + ds_write(addspace(graph_month(gdate[counter])+' ',11,TRUE)); + tf := TRUE; + END; + IF not tf THEN + ds_write(' '); + FOR counter := 20 downto 1 DO + IF (gdate[counter] <> '') THEN + ds_write(copy(gdate[counter],4,2)+' ') + ELSE + ds_write(' '); + IF (gdate[1] <> '') THEN + Print(graph_month(gdate[1])) + ELSE + NL; + average := average div config.logdays; + Print(#3'5 '+center('(Average '+reverse_str(side)+': '+inttostr(average)+')',60,TRUE)); + ds_pause_cr; +END; + +function div_g(g: g_array): longint; +VAR + i: byte; + counter: longint; + big: longint; + num: real; + + function div_size(num: real): longint; + BEGIN + IF (num <= 1) THEN + div_size := 1 + ELSE IF (num < 2) THEN + div_size := 2 + ELSE IF (num < 3) THEN + div_size := 3 + ELSE IF (num < 4) THEN + div_size := 4 + ELSE IF (num < 5) THEN + div_size := 5 + ELSE + BEGIN + counter := 5; + REPEAT + Inc(counter); + UNTIL (num > 999999) OR (counter > num); + div_size := counter; + END; + END; + +BEGIN + big := 0; + FOR i := 1 TO 20 DO + big := max(big,g[i]); + num := big / 20; + div_g := div_size(num); +END; + +PROCEDURE display_m_array(m_ar: m_array; title,desc1,desc2,desc3: str160; value: byte); +VAR + len: byte; + + PROCEDURE m_line(s: str160; w: word); + VAR + counter: byte; + BEGIN + ds_write(#3'1'+s+' '#3'9'); + FOR counter := 1 TO (len - length(s)) DO + ds_write('.'); + Print(#3'4'+addspace(inttostr(w),value+1,TRUE)); + END; + +BEGIN + len := 0; + len := max(len,length(desc1)); + len := max(len,length(desc2)); + len := max(len,length(desc3)); + Inc(len,3); + hdr(title); + m_line(desc1,m_ar[1]); + m_line(desc2,m_ar[2]); + IF (desc3 = 'Total Not Specified') and (m_ar[3] > 0) OR (desc3 = 'The Oldest User Is') THEN + m_line(desc3,m_ar[3]); + ds_pause_cr; +END; + +PROCEDURE display_h_array(ubaud: h_array); + + PROCEDURE baud_line(s: str160; w: word); + VAR + counter: byte; + BEGIN + ds_write(#3'1Total '+s+' Baud Callers '#3'9'); + FOR counter := 1 TO (27 - length('Total '+s+' Baud Callers')) DO + ds_write('.'); + Print(#3'4'+addspace(inttostr(w),6,TRUE)); + END; + +BEGIN + hdr('User Baud Rate Statistics'); + IF (ubaud[1] > 0) THEN + baud_line('300',ubaud[1]); + IF (ubaud[2] > 0) THEN + baud_line('1200',ubaud[2]); + IF (ubaud[3] > 0) THEN + baud_line('1275',ubaud[3]); + IF (ubaud[4] > 0) THEN + baud_line('2400',ubaud[4]); + IF (ubaud[5] > 0) THEN + baud_line('4800',ubaud[5]); + IF (ubaud[6] > 0) THEN + baud_line('7200',ubaud[6]); + IF (ubaud[7] > 0) THEN + baud_line('9600',ubaud[7]); + IF (ubaud[8] > 0) THEN + baud_line('12000',ubaud[8]); + IF (ubaud[9] > 0) THEN + baud_line('14400',ubaud[9]); + IF (ubaud[10] > 0) THEN + baud_line('16800',ubaud[10]); + IF (ubaud[11] > 0) THEN + baud_line('19200',ubaud[11]); + IF (ubaud[12] > 0) THEN + baud_line('21600',ubaud[12]); + IF (ubaud[13] > 0) THEN + baud_line('24000',ubaud[13]); + IF (ubaud[14] > 0) THEN + baud_line('26400',ubaud[14]); + IF (ubaud[15] > 0) THEN + baud_line('28800',ubaud[15]); + IF (ubaud[16] > 0) THEN + baud_line('38400',ubaud[16]); + IF (ubaud[17] > 0) THEN + baud_line('57600',ubaud[17]); + IF (ubaud[18] > 0) THEN + baud_line('64000',ubaud[18]); + IF (ubaud[19] > 0) THEN + baud_line('115200',ubaud[19]); + ds_pause_cr; +END; + +PROCEDURE todayusage(General: GeneralRecordType); +BEGIN + CLS; + with General DO + BEGIN + Print(#3'5'+center('-=[ Todays Usage ]=-',78,TRUE)); + sys_menu_line(' Date:',datestr); + sys_menu_line1(' Time:',timestr); + NL; + sys_menu_line1('Board Name :',boardname); + sys_menu_line1('Node Number :',inttostr(nodenumber)); + sys_menu_line1('Board Address :',boardcitystate); + sys_menu_line1('SysOp Name :',sysopname); + sys_menu_line1('Phone Number :',boardphone); + sys_menu_line('Mail Address :',inttostr(address.zone)+':'+inttostr(address.net)+'/'+inttostr(address.node)); + IF (address.point > 0) THEN + Print('.'+inttostr(address.point)) + ELSE + NL; + sys_menu_line1('BBS Software :','T.A.G. Version '+lasttagversion); + NL; + sys_menu_line1('Total Calls :',realtostr1(callernum,0,0)); + sys_menu_line1('Number Of Users :',realtostr1(users,0,0)); + sys_menu_line1('Last Caller :',lastcaller); + NL; + Print(#3'5'+center('-=[ Summary Of Activity ]=-',78,TRUE)); + sys_menu_line('Minutes Active :',addspace(inttostr(activetoday),9,false)); + sys_menu_line('Calls Today :',addspace(inttostr(callstoday),9,false)); + sys_menu_line1('New Users Today :',addspace(inttostr(nuserstoday),9,false)); + sys_menu_line('Percent Active :',addspace(return_percent(activetoday),9,false)); + sys_menu_line('Time/User :',addspace(return_time(activetoday,callstoday),9,false)); + sys_menu_line1('Public Posts :',addspace(inttostr(msgposttoday),9,false)); + sys_menu_line('Private Posts :',addspace(inttostr(emailtoday),9,false)); + sys_menu_line('Feedback Sent :',addspace(inttostr(fbacktoday),9,false)); + sys_menu_line1('Errors Today :',addspace(inttostr(errorstoday),9,false)); + sys_menu_line('Number Uploads :',addspace(inttostr(ultoday),9,false)); + sys_menu_line('UL K-Bytes :',addspace(realtostr1(ulktoday,0,0)+'K',9,false)); + sys_menu_line1('Number Downloads:',addspace(inttostr(dltoday),9,false)); + sys_menu_line1('DL K-Bytes :',addspace(realtostr1(dlktoday,0,0)+'K',9,false)); + END; + ds_pause_cr; +END; + +PROCEDURE chlen(s: str78; i,i1: integer); +VAR + line1,line2,temp: str160; + counter: integer; +BEGIN + s := rmvleadspace(rmvtrailspace(s)); + WHILE (pos(' ',s) > 0) DO + Delete(s,pos(' ',s),1); + IF (length(s) > i) THEN + BEGIN + line1 := copy(s,1,i); + WHILE (line1[length(line1)] <> ' ') DO + BEGIN + Delete(line1,length(line1),1); + Dec(i); + END; + line1 := rmvtrailspace(line1); + line2 := copy(s,i + 1,length(s)); + line2 := rmvleadspace(line2); + temp := ''; + FOR counter := 1 TO i1 DO + temp := ' ' + temp; + Print(#3'0'+line1); + ds_write(temp); + ds_write(#3'1:'); + Print(#3'0'+line2); + END + ELSE + Print(#3'0'+s); +END; + +PROCEDURE mainmenuscr(bbsname: str160); +BEGIN + hdr('Renegade Statistics Main Menu'); + menu1_line('A','User Statistics'); + menu1_line('B','Usage Statistics'); + ftr(bbsname); +END; + +PROCEDURE usermenuscr; +BEGIN + hdr('Renegade Statistics User Menu'); + menu1_line('A','Top 10 User Menu'); + menu1_line('B','User Age'); + menu1_line('C','User Gender'); + menu1_line('D','User Baud Rate'); + ftr('Renegade Statistics Main Menu'); +END; + +PROCEDURE usagemenuscr; +BEGIN + hdr('Renegade Statistics Usage Menu'); + menu1_line('A','Usage Graph Menu'); + menu1_line('B','Todays Usage'); + ftr('Renegade Statistics Main Menu'); +END; + +PROCEDURE top10menuscr; +BEGIN + hdr('Renegade Statistics Top 10 User Menu'); + menu_line('A','B','Most Frequent Callers','High Time Users'); + menu_line('C','D','File Kbyte Uploaders','File Kbyte Downloaders'); + menu_line('E','F','Private Message Senders','Public Message Posters'); + menu_line('G','H','SysOp Feedback Senders','All Time Callers'); + menu_line('I','J','File Uploaders','File Downloaders'); + menu_line('K','L','File Points','Upload/Download Ratios'); + menu_line('M',' ','Post/Call Ratios',''); + ftr('Renegade Statistics User Menu'); +END; + +PROCEDURE graph20menuscr; +BEGIN + hdr('Renegade Statistics Usage Graph Menu'); + menu_line('A','B','Minutes Active','Number Of Calls'); + menu_line('C','D','New User Logons','System Activity'); + menu_line('E','F','Average Time/User','Public Message Posting'); + menu_line('G','H','Private Message Posting','SysOp Feedback Sent'); + menu_line('I','J','Number Of Errors','File Uploads'); + menu_line('K','L','File Kbytes Uploaded','File Downloads'); + menu_line('M',' ','File Kbytes Downloaded',''); + ftr('Renegade Statistics Usage Menu'); +END; + +PROCEDURE mainmenu(General: GeneralRecordType; config: configinfo; tfreqc,tttimeon, + tulk,tdlk,tprivp,tpubp,tfeedback,tnumc, + tnumul,tnumdl,tfilep,tupd,tpostc: t_array; gdate: d_array; + gsysact: gsysactivity; gmina,gnumc,gnewu,gtimeu,gmsgpub, + gmsgpvt,gmsgfb,gnume,gful,gulkb,gfdl,gdlkb: g_array; + uage,usex: m_array; ubaud: h_array; frec: f_array); +VAR + c: char; +BEGIN + REPEAT + mainmenuscr(General.boardname); + OneK(c,'QABC'); + CASE c OF + 'A' : BEGIN + REPEAT + usermenuscr; + OneK(c,'QABCD'); + CASE c OF + 'A' : BEGIN + REPEAT + top10menuscr; + OneK(c,'QABCDEFGHIJKLM'); + CASE c OF + 'A' : display_t_freqcall(3,12,tfreqc,'Most Frequent Callers', + 'Average Number Of Days Between Calls'); + 'B' : display_t_array(0,8,tttimeon,'High Time Users', + 'Total Number Of Minutes Online'); + 'C' : display_t_array(0,8,tulk,'File Kbyte Uploaders', + 'Number Of Kbytes Uploaded'); + 'D' : display_t_array(0,8,tdlk,'File Kbyte Downloaders', + 'Number Of Kbytes Downloaded'); + 'E' : display_t_array(0,6,tprivp,'Private Message Senders', + 'Number Of Private Messages Sent'); + 'F' : display_t_array(0,6,tpubp,'Public Message Posters', + 'Number Of Public Messages Posted'); + 'G' : display_t_array(0,6,tfeedback,'SysOp Feedback Senders', + 'Number Of SysOp Feedback Sent'); + 'H' : display_t_array(0,6,tnumc,'All Time Callers', + 'Number Of Calls To The System'); + 'I' : display_t_array(0,6,tnumul,'File Uploaders', + 'Number Of Files Uploaded'); + 'J' : display_t_array(0,6,tnumdl,'File Downloaders', + 'Number Of Files Downloaded'); + 'K' : display_t_array(0,6,tfilep,'File Points', + 'Amount Of File Points On Hand'); + 'L' : display_t_array(3,12,tupd,'Upload/Download Ratios', + 'Number Of KB Uploaded For Each KB Downloaded'); + 'M' : display_t_array(3,12,tpostc,'Post/Call Ratios', + 'Number Of Public Messages Posted Each Call'); + END; + UNTIL (c = 'Q') OR HangUp; + c := #0; + END; + 'B' : display_m_array(uage,'User Age Statistics','The Average User Age Is', + 'The Youngest User Is','The Oldest User Is',3); + 'C' : display_m_array(usex,'User Gender Statistics','Total Male Users', + 'Total Female Users','Total Not Specified',5); + 'D' : display_h_array(ubaud); + END; + UNTIL (c = 'Q') OR HangUp; + c := #0; + END; + 'B' : BEGIN + REPEAT + usagemenuscr; + OneK(c,'QAB'); + CASE c OF + 'A' : BEGIN + REPEAT + graph20menuscr; + OneK(c,'QABCDEFGHIJKLM'); + CASE c OF + 'A' : display_g_array(config,gdate,gmina,'Total Minutes Active', + ' setuniM ',div_g(gmina)); + 'B' : display_g_array(config,gdate,gnumc,'Total Calls', + ' sllaC ',div_g(gnumc)); + 'C' : display_g_array(config,gdate,gnewu,'New User Logons to System', + ' sresU weN ',div_g(gnewu)); + 'D' : display_g_sysactivity(config,gdate,gsysact,' tnecreP '); + 'E' : display_g_array(config,gdate,gtimeu,'Average Time/User', + ' setuniM ',div_g(gtimeu)); + 'F' : display_g_array(config,gdate,gmsgpub,'Public Messages Posted', + ' segasseM ',div_g(gmsgpub)); + 'G' : display_g_array(config,gdate,gmsgpvt,'Private Messages Sent', + ' segasseM ',div_g(gmsgpvt)); + 'H' : display_g_array(config,gdate,gmsgfb,'SysOp Feedback Sent', + ' segasseM ',div_g(gmsgfb)); + 'I' : display_g_array(config,gdate,gnume,'Logon Errors', + ' srorrE ',div_g(gnume)); + 'J' : display_g_array(config,gdate,gful,'File Uploads', + ' seliF ',div_g(gful)); + 'K' : display_g_array(config,gdate,gulkb,'Total Upload Kbytes', + ' setybK ',div_g(gulkb)); + 'L' : display_g_array(config,gdate,gfdl,'File Downloads', + ' seliF ',div_g(gfdl)); + 'M' : display_g_array(config,gdate,gdlkb,'Total Download Kbytes', + ' setybK ',div_g(gdlkb)); + END; + UNTIL (c = 'Q') OR HangUp; + c := #0; + END; + 'B' : todayusage(General); + END; + UNTIL (c = 'Q') OR HangUp; + c := #0; + END; + END; + UNTIL (c = 'Q') OR HangUp; +END; + +BEGIN + read_config_file(config,chatconfig); + TempPause := FALSE; + read_usage_file(General,config,gdate,gsysact,gmina,gnumc,gnewu,gtimeu, + gmsgpub,gmsgpvt,gmsgfb,gnume,gful,gulkb,gfdl,gdlkb); + scrn_one; + read_user_file(General,config,uage,usex,ubaud,tfreqc,tttimeon,tulk,tdlk, + tprivp,tpubp,tfeedback,tnumc,tnumul,tnumdl,tfilep,tupd, + tpostc); + mainmenu(General,config,tfreqc,tttimeon,tulk,tdlk,tprivp,tpubp, + tfeedback,tnumc,tnumul,tnumdl,tfilep,tupd,tpostc,gdate,gsysact, + gmina,gnumc,gnewu,gtimeu,gmsgpub,gmsgpvt,gmsgfb,gnume,gful,gulkb, + gfdl,gdlkb,uage,usex,ubaud,frec); + scrn_two(General.boardname); +END. diff --git a/SOURCE/UNUSED/RGUPDATE.EXE b/SOURCE/UNUSED/RGUPDATE.EXE new file mode 100644 index 0000000000000000000000000000000000000000..8b9ea64cd2aa7b9aae537b8d36411b98ed0f9aed GIT binary patch literal 12912 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 Q*q}S{+j)WmP`|(b1;zFA1ONa4 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGUPDATE.PAS b/SOURCE/UNUSED/RGUPDATE.PAS new file mode 100644 index 0000000..d7fc245 --- /dev/null +++ b/SOURCE/UNUSED/RGUPDATE.PAS @@ -0,0 +1,843 @@ +{$M 49152,0,65536} +PROGRAM RGUPDATE; + +USES + Crt, + Dos, + TimeFunc; + +{$I RECORDS.PAS} + +CONST + DYNY: BOOLEAN = FALSE; + +TYPE + + OldGeneralRecordType = +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + ForgotPWQuestion: STRING[70]; + + QWKWelcome, { QWK welcome file name } + QWKNews, { QWK news file name } + QWKGoodbye, { QWK goodbye file name } + Origin: STRING[50]; { Default Origin line } + + DataPath, { DATA path } + MiscPath, { MISC path } + LogsPath, { LOGS path } + MsgPath, { MSGS path } + NodePath, { NODE list path } + TempPath, { TEMP path } + ProtPath, { PROT path } + ArcsPath, { ARCS path } + lMultPath, { MULT path } + FileAttachPath, { directory for file attaches } + QWKLocalPath, { QWK path for local usage } + DefEchoPath, { default echomail path } + NetmailPath, { path to netmail } + BBSName: STRING[40]; { BBS name } + + SysOpName: STRING[30]; { SysOp's name } + + Version: STRING[20]; + + BBSPhone: STRING[12]; { BBS phone number } + + LastDate: STRING[10]; { last system date } + + PacketName, { QWK packet name } + BulletPrefix: STRING[8]; { default bulletins filename } + + SysOpPW, { SysOp password } + NewUserPW, { newuser password } + MinBaudOverride, { override minimum baud rate } + QWKNetworkACS, { QWK network REP ACS } + LastOnDatACS, + SOP, { SysOp } + CSOP, { Co-SysOp } + MSOP, { Message SysOp } + FSOP, { File SysOp } + SPW, { SysOp PW at logon } + AddChoice, { Add voting choices acs } + NormPubPost, { make normal public posts } + NormPrivPost, { send normal e-mail } + AnonPubRead, { see who posted public anon } + AnonPrivRead, { see who sent anon e-mail } + AnonPubPost, { make anon posts } + AnonPrivPost, { send anon e-mail } + SeeUnval, { see unvalidated files } + DLUnval, { DL unvalidated files } + NoDLRatio, { no UL/DL ratio } + NoPostRatio, { no post/call ratio } + NoFileCredits, { no file credits checking } + ULValReq, { uploads require validation } + TeleConfMCI, { ACS access for MCI codes while teleconfin' } + OverrideChat, { override chat hours } + NetMailACS, { do they have access to netmail? } + Invisible, { Invisible mode? } + FileAttachACS, { ACS to attach files to messages } + ChangeVote: ACString; { ACS to change their vote } + + MaxPrivPost, { max email can send per call } + MaxFBack, { max feedback per call } + MaxPubPost, { max posts per call } + MaxChat, { max sysop pages per call } + MaxWaiting, { max mail waiting } + CSMaxWaiting, { max mail waiting for Co-SysOp + } + MaxMassMailList, + MaxLogonTries, { tries allowed for PW's at logon } + SysOpColor, { SysOp color in chat mode } + UserColor, { user color in chat mode } + SliceTimer, + MaxBatchDLFiles, + MaxBatchULFiles, + Text_Color, { color OF standard text } + Quote_Color, { color OF quoted text } + Tear_Color, { color OF tear line } + Origin_Color, { color OF origin line } + BackSysOpLogs, { days to keep SYSOP##.LOG } + EventWarningTime, { minutes before event to warn user } + WFCBlankTime, { minutes before blanking WFC menu } + AlertBeep, { time between alert beeps - Was Integer } + FileCreditComp, { file credit compensation ratio } + FileCreditCompBaseSize, { file credit area compensation size } + ULRefund, { percent OF time to refund on ULs } + GlobalMenu, + AllStartMenu, + ShuttleLogonMenu, + NewUserInformationMenu, + FileListingMenu, + MessageReadMenu, + CurWindow, { type OF SysOp window in use } + SwapTo: Byte; { Swap where? } + + lLowTime, { SysOp begin minute (in minutes) } + HiTime, { SysOp END time } + DLLowTime, { normal downloading hours begin.. } + DLHiTime, { ..and END } + MinBaudLowTime, { minimum baud calling hours begin.. } + MinBaudHiTime, { ..and END } + MinBaudDLLowTime, { minimum baud downloading hours begin.. } + MinBaudDLHiTime, { ..and END } + MinSpaceForPost, { minimum drive space left to post } + MinSpaceForUpload, { minimum drive space left to upload } + NewApp, { send new user application to # } + TimeOutBell, { minutes before timeout beep } + TimeOut, { minutes before timeout } + ToSysOpDir, { SysOp file area } + CreditMinute, { Credits per minute } + CreditPost, { Credits per post } + CreditEmail, { Credits per Email sent } + CreditFreeTime, { Amount OF "Free" time given to user at logon } + NumUsers, { number OF users } + PasswordChange, { change password at least every x days } + RewardRatio, { % OF file points to reward back } + CreditInternetMail, { cost for Internet mail } + BirthDateCheck: Integer; { check user's birthdate every xx logons } + + MaxQWKTotal, { max msgs in a packet, period } + MaxQWKBase, { max msgs in a area } + DaysOnline: Word; { days online } + + MinimumBaud, { minimum baud rate to logon } + MinimumDLBaud, { minimum baud rate to download } + MaxDepositEver, + MaxDepositPerDay, + MaxWithdrawalPerDay, + CallerNum, { system caller number } + RegNumber, { registration number } + TotalCalls, { incase different from callernum } + TotalUsage, { total usage in minutes } + TotalPosts, { total number OF posts } + TotalDloads, { total number OF dloads } + TotalUloads, { total number OF uloads } + MinResume, { min K to allow resume-later } + MaxInTemp: LongInt; { max K allowed in TEMP } + + AllowAlias, { allow handles? } + PhonePW, { phone number password in logon? } + LocalSec, { use local security? } + GlobalTrap, { trap everyone's activity? } + AutoChatOpen, { automatically open chat buffer? } + AutoMInLogon, { Auto-Message at logon? } + BullInLogon, { bulletins at logon? } + YourInfoInLogon, { "Your Info" at logon? } + OffHookLocalLogon, { phone off-hook for local logons? } + ForceVoting, { manditory voting? } + CompressBases, { "compress" file/msg area numbers? } + SearchDup, { search for dupes files when UL? } + ForceBatchDL, + LogonQuote, + UserAddQuote, + StripCLog, { strip colors from SysOp log? } + SKludge, { show kludge lines? } + SSeenby, { show SEEN-BY lines? } + SOrigin, { show origin line? } + AddTear, { show tear line? } + ShuttleLog, { Use Shuttle Logon? } + ClosedSystem, { Allow new users? } + SwapShell, { Swap on shell? } + UseEMS, { use EMS for overlay } + UseBios, { use BIOS for video output } + UseIEMSI, { use IEMSI } + ULDLRatio, { use UL/DL ratios? } + FileCreditRatio, { use auto file-credit compensation? } + ValidateAllFiles, { validate files automatically? } + FileDiz, { Search/Import file_id.diz } + SysOpPword, { check for sysop password? } + TrapTeleConf, { Trap teleconferencing to ROOMx.TRP? } + IsTopWindow, { is window at top OF screen? } + ReCompress, { recompress like archives? } + RewardSystem, { use file rewarding system? } + TrapGroup, { record group chats? } + QWKTimeIgnore, { ignore time remaining for qwk download? } + NetworkMode, { Network mode ? } + WindowOn, { is the sysop window on? } + ChatCall, { Whether system keeps beeping after chat} + DailyLimits, { Daily file limits on/off } + MultiNode, { enable multinode support } + PerCall, { time limits are per call or per day?} + TestUploads: Boolean; { perform integrity tests on uploads? } + + FileArcInfo: + ARRAY [1..MaxArcs] OF FileArcInfoRecordType; { archive specs } + + FileArcComment: + ARRAY [1..3] OF STRING[40]; { BBS comment files for archives } + + Aka: ARRAY [0..20] OF + {$IFDEF WIN32} PACKED {$ENDIF} RECORD { 20 Addresses } + Zone, { 21st is for UUCP address } + Net, + Node, + Point: Word; + END; + + NewUserToggles: ARRAY [1..20] OF Byte; + + Macro: ARRAY [0..9] OF STRING[100]; { sysop macros } + + Netattribute: NetAttribs; { default netmail attribute } + + TimeAllow, { time allowance } + CallAllow, { call allowance } + DLRatio, { # ULs/# DLs ratios } + DLKRatio, { DLk/ULk ratios } + PostRatio, { posts per call ratio } + DLOneday, { Max number OF dload files in one day} + DLKOneDay: SecurityRangeType; { Max k downloaded in one day} + END; + + OldStatusFlagType = + (OldLockedOut, { if locked out } + OldDeleted, { if deleted } + OldTrapActivity, { if trapping users activity } + OldTrapSeparate, { if trap to seperate TRAP file } + OldChatAuto, { if auto chat trapping } + OldChatSeparate, { if separate chat file to trap to } + OldSLogSeparate, { if separate SysOp log } + OldCLSMsg, { if clear-screens } + OldRIP, { if RIP graphics can be used } + OldFSEditor, { if Full Screen Editor } + OldAutoDetect { Use auto-detected emulation } + ); + + OldStatusFlagSet = SET OF OldStatusFlagType; + + OldUserRecordType = { USERS.DAT : User records } + {$IFDEF WIN32} PACKED {$ENDIF} RECORD + Name, { system name } + RealName: STRING[36]; { real name } + Street, { street address } + CityState: STRING[30]; { city, state } + CallerID: STRING[20]; { caller ID STRING } + ZipCode: STRING[10]; { zipcode } + PH: STRING[12]; { phone # } + ForgotPWAnswer: STRING[40]; + UsrDefStr: ARRAY [1..3] OF STRING[35]; { definable strings } + Note: STRING[35]; { SysOp note } + LockedFile: STRING[8]; { print lockout msg } + Vote: ARRAY [1..25] OF Byte; { voting data } + Sex, { gender } + Subscription, { their subscription } + ExpireTo, { level to expire to } + LastConf: Char; { last conference in } + + SL, { SL } + DSL, { DSL } + Waiting, { mail waiting } + LineLen, { line length } + PageLen, { page length } + OnToday, { # times on today } + Illegal, { # illegal logons } + DefArcType, { QWK archive type } + ColorScheme, { Color scheme # } + UserStartMenu: Byte; { menu to start at } + + BirthDate, { Birth date } + FirstOn, { First On Date } + LastOn, { Last On Date } + TTimeOn, { total time on } + LastQWK, { last qwk packet } + Expiration: UnixTime; { Expiration date } + + UserID, { Permanent userid } + TLToday, { # min left today } + ForUsr, { forward mail to } + LastMsgArea, { # last msg area } + LastFileArea: Integer; { # last file area } + + PasswordChanged: Word; { Numeric date pw changed - was UnixTime } + + Credit, { Amount OF credit } + Debit, { Amount OF debit } + PW, { password } + Uploads, { # OF DLs } + Downloads, { # OF DLs } + UK, { UL k } + DK, { DL k } + LoggedOn, { # times on } + MsgPost, { # message posts } + EmailSent, { # email sent } + FeedBack, { # feedback sent } + TimeBank, { # mins in bank } + TimeBankAdd, { # added today } + DLKToday, { # kbytes dl today } + DLToday, { # files dl today } + TimeBankWith: LongInt; { Time withdrawn } + + TeleConfEcho, { Teleconf echo? } + TeleConfInt, { Teleconf interrupt } + GetOwnQWK, { Get own messages } + ScanFilesQWK, { new files in qwk } + PrivateQWK: Boolean; { private mail qwk } + + AR: ARFlagSet; { AR flags } + Flags: FlagSet; { flags } + OldSFlags: OldStatusFlagSet; { status flags } + END; + +function sqoutsp(s:string):string; +begin + while (pos(' ',s)>0) do delete(s,pos(' ',s),1); + sqoutsp:=s; +end; + +function exist(fn: astr): boolean; +var + srec: searchrec; +begin + findfirst(sqoutsp(fn),anyfile,srec); + exist := (doserror = 0); +end; + +FUNCTION SYN(B: BOOLEAN): STRING; +BEGIN + IF (B) THEN + SYN := 'Yes' + ELSE + SYN := 'No '; +END; + +FUNCTION YN: BOOLEAN; +VAR + C: CHAR; +BEGIN + Write(SQOutSp(SYN(DYNY))); + REPEAT + C := UpCase(Char(ReadKey)); + UNTIL (C IN ['Y','N',^M]); + IF (DYNY) AND (C <> 'N') THEN + C := 'Y'; + IF (DYNY) AND (C = 'N') THEN + Write(#8#8#8'No ') + ELSE IF (NOT DYNY) AND (C = 'Y') THEN + Write(#8#8'Yes'); + WriteLn; + YN := (C = 'Y'); + DYNY := FALSE; +end; + +FUNCTION PYNQ(CONST S: AStr): BOOLEAN; +BEGIN + Write(S); + PYNQ := YN; +END; + +PROCEDURE ChangeLength(S: STRING; VAR S1,S2: STRING); +VAR + TempStr: STRING; + Counter: Byte; +BEGIN + IF (Length(S) <= 60) THEN + BEGIN + S1 := S; + S2 := ''; + END + ELSE + BEGIN + TempStr := Copy(S,1,65); + IF (TempStr[65] <> ' ') THEN + BEGIN + Counter := 65; + WHILE (TempStr[Counter] <> ' ') DO + BEGIN + Dec(TempStr[0]); + Dec(Counter); + END; + Dec(TempStr[0]); + S1 := TempStr; + S2 := Copy(S,(Counter + 1),Length(S)); + END + ELSE + BEGIN + S1 := Copy(S,1,64); + S2 := Copy(S,66,Length(S)); + END; + END; +END; + +PROCEDURE Kill(CONST FileName: AStr); +VAR + F: FILE; +BEGIN + Assign(F,FileName); + Erase(F); +END; + +PROCEDURE ConvertGeneralRec; +VAR + OldGeneralFile: FILE OF OldGeneralRecordType; + GeneralFile: FILE OF GeneralRecordType; + OldGeneral: OldGeneralRecordType; + General: GeneralRecordType; + Counter: Integer; +BEGIN + Write('Converting "RENEGADE.DAT" file ... '); + Assign(OldGeneralFile,'RENEGADE.DAT'); + Reset(OldGeneralFile); + Assign(GeneralFile,'RENEGADE.NEW'); + ReWrite(GeneralFile); + Seek(OldGeneralFile,0); + Read(OldGeneralFile,OldGeneral); + WITH General DO + BEGIN + ForgotPWQuestion := OldGeneral.ForgotPWQuestion; + + QWKWelcome := OldGeneral.QWKWelcome; + QWKNews := OldGeneral.QWKNews; + QWKGoodbye := OldGeneral.QWKGoodBye; + Origin := OldGeneral.Origin; + + DataPath := OldGeneral.DataPath; + MiscPath := OldGeneral.MiscPath; + LogsPath := OldGeneral.LogsPath; + MsgPath := OldGeneral.MsgPath; + NodePath := OldGeneral.NodePath; + TempPath := OldGeneral.TempPath; + ProtPath := OldGeneral.ProtPath; + ArcsPath := OldGeneral.ArcsPath; + lMultPath := OldGeneral.LMultPath; + FileAttachPath := OldGeneral.FileAttachPath; + QWKLocalPath := OldGeneral.QWKLocalPath; + DefEchoPath := OldGeneral.DefEchoPath; + NetmailPath := OldGeneral.NetMailPath; + BBSName := OldGeneral.BBSName; + + SysOpName := OldGeneral.SysOpName; + + Version := '1.XX'; (* <-- Update this with version *) + + BBSPhone := OldGeneral.BBSPhone; + + LastDate := OldGeneral.LastDate; + + PacketName := OldGeneral.PacketName; + BulletPrefix := OldGeneral.BulletPrefix; + + SysOpPW := OldGeneral.SysOpPW; + NewUserPW := OldGeneral.NewUserPW; + MinBaudOverride := OldGeneral.MinBaudOverride; + QWKNetworkACS := OldGeneral.QWKNetworkACS; + LastOnDatACS := OldGeneral.LastOnDatACS; + SOP := OldGeneral.SOP; + CSOP := OldGeneral.CSOP; + MSOP := OldGeneral.MSOP; + FSOP := OldGeneral.FSOP; + SPW := OldGeneral.SPW; + AddChoice := OldGeneral.AddChoice; + NormPubPost := OldGeneral.NormPubPost; + NormPrivPost := OldGeneral.NormPrivPost; + AnonPubRead := OldGeneral.AnonPubRead; + AnonPrivRead := OldGeneral.AnonPrivRead; + AnonPubPost := OldGeneral.AnonPubPost; + AnonPrivPost := OldGeneral.AnonPrivPost; + SeeUnval := OldGeneral.SeeUnval; + DLUnval := OldGeneral.DLUnval; + NoDLRatio := OldGeneral.NoDLRatio; + NoPostRatio := OldGeneral.NoPostRatio; + NoFileCredits := OldGeneral.NoFileCredits; + ULValReq := OldGeneral.ULValReq; + TeleConfMCI := OldGeneral.TeleConfMCI; + OverrideChat := OldGeneral.OverrideChat; + NetMailACS := OldGeneral.NetMailACS; + Invisible := OldGeneral.Invisible; + FileAttachACS := OldGeneral.FileAttachACS; + ChangeVote := OldGeneral.ChangeVote; + UnUsedACS1 := ''; + UnUsedACS2 := ''; + + MaxPrivPost := OldGeneral.MaxPrivPost; + MaxFBack := OldGeneral.MaxFBack; + MaxPubPost := OldGeneral.MaxPubPost; + MaxChat := OldGeneral.MaxChat; + MaxWaiting := OldGeneral.MaxWaiting; + CSMaxWaiting := OldGeneral.CSMaxWaiting; + MaxMassMailList := OldGeneral.MaxMassMailList; + MaxLogonTries := OldGeneral.MaxLogonTries; + SysOpColor := OldGeneral.SysOpColor; + UserColor := OldGeneral.UserColor; + SliceTimer := OldGeneral.SliceTimer; + MaxBatchDLFiles := OldGeneral.MaxBatchDLFiles; + MaxBatchULFiles := OldGeneral.MaxBatchULFiles; + Text_Color := OldGeneral.Text_Color; + Quote_Color := OldGeneral.Quote_Color; + Tear_Color := OldGeneral.Tear_Color; + Origin_Color := OldGeneral.Origin_Color; + BackSysOpLogs := OldGeneral.BackSysOpLogs; + EventWarningTime := OldGeneral.EventWarningTime; + WFCBlankTime := OldGeneral.WFCBlankTime; + AlertBeep := OldGeneral.AlertBeep; + FileCreditComp := OldGeneral.FileCreditComp; + FileCreditCompBaseSize := OldGeneral.FileCreditCompBaseSize; + ULRefund := OldGeneral.ULRefund; + GlobalMenu := OldGeneral.GlobalMenu; + AllStartMenu := OldGeneral.AllStartMenu; + ShuttleLogonMenu := OldGeneral.ShuttleLogonMenu; + NewUserInformationMenu := OldGeneral.NewUserInformationMenu; + FileListingMenu := OldGeneral.FileListingMenu; + MessageReadMenu := OldGeneral.MessageReadMenu; + CurWindow := OldGeneral.CurWindow; + SwapTo := OldGeneral.SwapTo; + UnUsedByte1 := 0; + UnUsedByte2 := 0; + + lLowTime := OldGeneral.lLowTime; + HiTime := OldGeneral.HiTime; + DLLowTime := OldGeneral.DLLowTime; + DLHiTime := OldGeneral.DLHiTime; + MinBaudLowTime := OldGeneral.MinBaudLowTime; + MinBaudHiTime := OldGeneral.MinBaudHiTime; + MinBaudDLLowTime := OldGeneral.MinBaudDLLowTime; + MinBaudDLHiTime := OldGeneral.MinBaudDLHiTime; + NewApp := OldGeneral.NewApp; + TimeOutBell := OldGeneral.TimeOutBell; + TimeOut := OldGeneral.TimeOut; + ToSysOpDir := OldGeneral.ToSysOpDir; + CreditMinute := OldGeneral.CreditMinute; + CreditPost := OldGeneral.CreditPost; + CreditEmail := OldGeneral.CreditEmail; + CreditFreeTime := OldGeneral.CreditFreeTime; + NumUsers := OldGeneral.NumUsers; + PasswordChange := OldGeneral.PasswordChange; + RewardRatio := OldGeneral.RewardRatio; + CreditInternetMail := OldGeneral.CreditInternetMail; + BirthDateCheck := OldGeneral.BirthDateCheck; + UnUsedInteger1 := 0; + UnUsedInteger2 := 0; + + MaxQWKTotal := OldGeneral.MaxQWKTotal; + MaxQWKBase := OldGeneral.MaxQWKBase; + DaysOnline := OldGeneral.DaysOnline; + UnUsedWord1 := 0; + UnUsedWord2 := 0; + + MinimumBaud := OldGeneral.MinimumBaud; + MinimumDLBaud := OldGeneral.MinimumDLBaud; + MaxDepositEver := OldGeneral.MaxDepositEver; + MaxDepositPerDay := OldGeneral.MaxDepositPerDay; + MaxWithdrawalPerDay := OldGeneral.MaxWithdrawalPerDay; + CallerNum := OldGeneral.CallerNum; + RegNumber := OldGeneral.RegNumber; + TotalCalls := OldGeneral.TotalCalls; + TotalUsage := OldGeneral.TotalUsage; + TotalPosts := OldGeneral.TotalPosts; + TotalDloads := OldGeneral.TotalDloads; + TotalUloads := OldGeneral.TotalUloads; + MinResume := OldGeneral.MinResume; + MaxInTemp := OldGeneral.MaxInTemp; + MinSpaceForPost := OldGeneral.MinSpaceForPost; + MinSpaceForUpload := OldGeneral.MinSpaceForUpload; + UnUsedLongInt1 := 0; + UnUsedLongInt2 := 0; + + AllowAlias := OldGeneral.AllowAlias; + PhonePW := OldGeneral.PhonePW; + LocalSec := OldGeneral.LocalSec; + GlobalTrap := OldGeneral.GlobalTrap; + AutoChatOpen := OldGeneral.AutoChatOpen; + AutoMInLogon := OldGeneral.AutoMInLogon; + BullInLogon := OldGeneral.BullInLogon; + YourInfoInLogon := OldGeneral.YourInfoInLogon; + OffHookLocalLogon := OldGeneral.OffHookLocalLogon; + ForceVoting := OldGeneral.ForceVoting; + CompressBases := OldGeneral.CompressBases; + SearchDup := OldGeneral.SearchDup; + ForceBatchDL := OldGeneral.ForceBatchDL; + ForceBatchUL := FALSE; + LogonQuote := OldGeneral.LogonQuote; + UserAddQuote := OldGeneral.UserAddQuote; + StripCLog := OldGeneral.StripCLog; + SKludge := OldGeneral.SKludge; + SSeenby := OldGeneral.SSeenby; + SOrigin := OldGeneral.SOrigin; + AddTear := OldGeneral.AddTear; + ShuttleLog := OldGeneral.ShuttleLog; + ClosedSystem := OldGeneral.ClosedSystem; + SwapShell := OldGeneral.SwapShell; + UseEMS := OldGeneral.UseEMS; + UseBios := OldGeneral.UseBios; + UseIEMSI := OldGeneral.UseIEMSI; + ULDLRatio := OldGeneral.ULDLRatio; + FileCreditRatio := OldGeneral.FileCreditRatio; + ValidateAllFiles := OldGeneral.ValidateAllFiles; + FileDiz := OldGeneral.FileDiz; + SysOpPword := OldGeneral.SysOpPword; + TrapTeleConf := OldGeneral.TrapTeleConf; + IsTopWindow := OldGeneral.IsTopWindow; + ReCompress := OldGeneral.ReCompress; + RewardSystem := OldGeneral.RewardSystem; + TrapGroup := OldGeneral.TrapGroup; + QWKTimeIgnore := OldGeneral.QWKTimeIgnore; + NetworkMode := OldGeneral.NetworkMode; + WindowOn := OldGeneral.WindowOn; + ChatCall := OldGeneral.ChatCall; + DailyLimits := OldGeneral.DailyLimits; + MultiNode := OldGeneral.MultiNode; + PerCall := OldGeneral.PerCall; + TestUploads := OldGeneral.TestUploads; + UseFileAreaLightBar := TRUE; + UseMsgAreaLightBar := TRUE; + UnUsedBoolean1 := FALSE; + UnUsedBoolean2 := FALSE; + + FOR Counter := 1 TO MaxArcs DO + FileArcInfo[Counter] := OldGeneral.FileArcInfo[Counter]; + + FOR Counter := 1 TO 3 DO + FileArcComment[Counter] := OldGeneral.FileArcComment[Counter]; + + FOR Counter := 0 TO 20 DO + WITH AKA[Counter] DO + BEGIN + Zone := OldGeneral.AKA[Counter].Zone; + Net := OldGeneral.AKA[Counter].Net; + Node := OldGeneral.AKA[Counter].Node; + Point := OldGeneral.AKA[Counter].Point; + END; + + FOR Counter := 1 TO 20 DO + NewUserToggles[Counter] := OldGeneral.NewUserToggles[Counter]; + + FOR Counter := 0 TO 9 DO + Macro[Counter] := OldGeneral.Macro[Counter]; + + Netattribute := OldGeneral.NetAttribute; + + TimeAllow := OldGeneral.TimeAllow; + CallAllow := OldGeneral.CallAllow; + DLRatio := OldGeneral.DLRatio; + DLKRatio := OldGeneral.DLKRatio; + PostRatio := OldGeneral.PostRatio; + DLOneday := OldGeneral.DLOneDay; + DLKOneDay := OldGeneral.DLKOneDay; + END; + Seek(GeneralFile,0); + Write(GeneralFile,General); + Close(OldGeneralFile); + Close(GeneralFile); + Assign(OldGeneralFile,'RENEGADE.DAT'); + Erase(OldGeneralFile); + Assign(GeneralFile,'RENEGADE.NEW'); + ReName(GeneralFile,'RENEGADE.DAT'); + WriteLn('Done'); +END; + +PROCEDURE ConvertUserRec(OldGeneral: OldGeneralRecordType); +VAR + OldUserFile: FILE OF OldUserRecordType; + UserFile: FILE OF UserRecordType; + OldUser: OldUserRecordType; + User: UserRecordType; + Counter, + Counter1: Integer; +BEGIN + Write('Converting "USERS.DAT" file ... '); + Assign(OldUserFile,OldGeneral.DataPath+'USERS.DAT'); + Reset(OldUserFile); + Assign(UserFile,OldGeneral.DataPath+'USERS.NEW'); + ReWrite(UserFile); + Counter := 0; + WHILE (Counter <= (FileSize(OldUserFile) - 1)) DO + BEGIN + Seek(OldUserFile,Counter); + Read(OldUserFile,OldUser); + WITH User DO + BEGIN + Name := OldUser.Name; + RealName := OldUser.RealName; + Street := OldUser.Street; + CityState := OldUser.CityState; + CallerID := OldUser.CallerID; + ZipCode := OldUser.ZipCode; + PH := OldUser.PH; + ForgotPWAnswer := OldUser.ForgotPWAnswer; + FOR Counter1 := 1 TO 3 DO + UsrDefStr[Counter1] := OldUser.UsrDefStr[Counter1]; + Note := OldUser.Note; + LockedFile := OldUser.LockedFile; + FOR Counter1 := 1 TO 25 DO + Vote[Counter1] := OldUser.Vote[Counter1]; + Sex := OldUser.Sex; + Subscription := OldUser.SubScription; + ExpireTo := OldUser.ExpireTo; + LastConf := OldUser.LastConf; + UnUsedChar1 := ' '; + UnUsedChar2 := ' '; + + SL := OldUser.SL; + DSL := OldUser.DSL; + Waiting := OldUser.Waiting; + LineLen := OldUser.LineLen; + PageLen := OldUser.PageLen; + OnToday := OldUser.OnToday; + Illegal := OldUser.Illegal; + DefArcType := OldUser.DefArcType; + ColorScheme := OldUser.ColorScheme; + UserStartMenu := OldUser.UserStartMenu; + UnUsedByte1 := 0; + UnUsedByte2 := 0; + + BirthDate := OldUser.BirthDate; + FirstOn := OldUser.FirstOn; + LastOn := OldUser.LastOn; + TTimeOn := OldUser.TTimeOn; + LastQWK := OldUser.LastQWK; + Expiration := OldUser.Expiration; + UnUsedUnixTime1 := 0; + UnUsedUnixTime2 := 0; + + UserID := OldUser.UserID; + TLToday := OldUser.TLToday; + ForUsr := OldUser.ForUsr; + LastMsgArea := OldUser.LastMsgArea; + LastFileArea := OldUser.LastFileArea; + UnUsedInteger1 := 0; + UnUsedInteger2 := 0; + + PasswordChanged := OldUser.PasswordChanged; + UnUsedWord1 := 0; + UnUsedWord2 := 0; + + LCredit := OldUser.Credit; + Debit := OldUser.Debit; + PW := OldUser.PW; + Uploads := OldUser.Uploads; + Downloads := OldUser.Downloads; + UK := OldUser.UK; + DK := OldUser.DK; + LoggedOn := OldUser.LoggedOn; + MsgPost := OldUser.MsgPost; + EmailSent := OldUser.EmailSent; + FeedBack := OldUser.FeedBack; + TimeBank := OldUser.TimeBank; + TimeBankAdd := OldUser.TimeBankAdd; + DLKToday := OldUser.DLKToday; + DLToday := OldUser.DLToday; + FilePoints := 0; + TimeBankWith := OldUser.TimeBankWith; + UnUsedLongInt1 := 0; + UnUsedLongInt2 := 0; + + TeleConfEcho := OldUser.TeleConfEcho; + TeleConfInt := OldUser.TeleConfInt; + GetOwnQWK := OldUser.GetOwnQWK; + ScanFilesQWK := OldUser.ScanFilesQWK; + PrivateQWK := OldUser.PrivateQWK; + UnUsedBoolean1 := FALSE; + UnUsedBoolean2 := FALSE; + + AR := OldUser.AR; + + Flags := OldUser.Flags; + + SFlags := []; + IF (OldLockedOut IN OldUser.OldSFlags) THEN + Include(SFlags,LockedOut); + IF (OldDeleted IN OldUser.OldSFlags) THEN + Include(SFlags,Deleted); + IF (OldTrapActivity IN OldUser.OldSFlags) THEN + Include(SFlags,TrapActivity); + IF (OldTrapSeparate IN OldUser.OldSFlags) THEN + Include(SFlags,TrapSeparate); + IF (OldChatAuto IN OldUser.OldSFlags) THEN + Include(SFlags,ChatAuto); + IF (OldChatSeparate IN OldUser.OldSFlags) THEN + Include(SFlags,ChatSeparate); + IF (OldSLogSeparate IN OldUser.OldSFlags) THEN + Include(SFlags,SLogSeparate); + IF (OldCLSMsg IN OldUser.OldSFlags) THEN + Include(SFlags,CLSMsg); + IF (OldRIP IN OldUser.OldSFlags) THEN + Include(SFlags,RIP); + IF (OldFSEditor IN OldUser.OldSFlags) THEN + Include(SFlags,FSEditor); + IF (OldAutoDetect IN OldUser.OldSFlags) THEN + Include(SFlags,AutoDetect); + Include(SFlags,FileAreaLightBar); + Include(SFlags,MsgAreaLightBar); + END; + Write(UserFile,User); + Inc(Counter); + END; + Close(OldUserFile); + Close(UserFile); + Assign(OldUserFile,OldGeneral.DataPath+'USERS.DAT'); + Erase(OldUserFile); + Assign(UserFile,OldGeneral.DataPath+'USERS.NEW'); + ReName(UserFile,OldGeneral.DataPath+'USERS.DAT'); + WriteLn('Done'); +END; + +VAR + OldGeneralFile: FILE OF OldGeneralRecordType; + OldGeneral: OldGeneralRecordType; + +BEGIN + ClrScr; + WriteLn('Renegade Upgrade Utility (v1.XX to v1.XX)'); (* <-- Update this with version *) + WriteLn; + Writeln('This utility will upgrade your Renegade BBS from'); + WriteLn('Version 1.XX to Version 1.XX'); (* <-- Update this with version *) + WriteLn; + IF PYNQ('Do you want to continue? ') THEN + BEGIN + WriteLn; + Write('Reading "RENEGADE.DAT" file ... '); + Assign(OldGeneralFile,'RENEGADE.DAT'); + Reset(OldGeneralFile); + Seek(OldGeneralFile,0); + Read(OldGeneralFile,OldGeneral); + Close(OldGeneralFile); + WriteLn('Done'); + WriteLn; + IF (Exist(OldGeneral.DataPath+'BATCHDL.DAT')) THEN + BEGIN + Write('Deleting "BATCHDL.DAT" file ... '); + Kill(OldGeneral.DataPath+'BATCHDL.DAT'); + WriteLn('Done'); + END; + ConvertUserRec(OldGeneral); + ConvertGeneralRec; + END; +END. \ No newline at end of file diff --git a/SOURCE/UNUSED/RGUPDT1.EXE b/SOURCE/UNUSED/RGUPDT1.EXE new file mode 100644 index 0000000000000000000000000000000000000000..f4c20258dcc8b6b991413fd8e2339f2b9843708e GIT binary patch literal 13008 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 U!jJdyfM~=20U&q)AMx-10C@Qu0) do delete(s,pos(' ',s),1); + sqoutsp:=s; +end; + +function exist(fn: astr): boolean; +var + srec: searchrec; +begin + findfirst(sqoutsp(fn),anyfile,srec); + exist := (doserror = 0); +end; + +FUNCTION SYN(B: BOOLEAN): STRING; +BEGIN + IF (B) THEN + SYN := 'Yes' + ELSE + SYN := 'No '; +END; + +FUNCTION YN: BOOLEAN; +VAR + C: CHAR; +BEGIN + Write(SQOutSp(SYN(DYNY))); + REPEAT + C := UpCase(Char(ReadKey)); + UNTIL (C IN ['Y','N',^M]); + IF (DYNY) AND (C <> 'N') THEN + C := 'Y'; + IF (DYNY) AND (C = 'N') THEN + Write(#8#8#8'No ') + ELSE IF (NOT DYNY) AND (C = 'Y') THEN + Write(#8#8'Yes'); + WriteLn; + YN := (C = 'Y'); + DYNY := FALSE; +end; + +FUNCTION PYNQ(CONST S: AStr): BOOLEAN; +BEGIN + Write(S); + PYNQ := YN; +END; + +FUNCTION Caps(s: STRING): STRING; +VAR + Counter: Integer; { must be Integer } +BEGIN + IF (s[1] IN ['a'..'z']) THEN + Dec(s[1],32); + FOR Counter := 2 TO Length(s) DO + IF (s[Counter - 1] IN ['a'..'z','A'..'Z']) THEN + IF (s[Counter] IN ['A'..'Z']) THEN + Inc(s[Counter],32) + ELSE + ELSE + IF (s[Counter] IN ['a'..'z']) THEN + Dec(s[Counter],32); + Caps := s; +END; + +FUNCTION IntToStr(L: LongInt): STRING; +VAR + S: STRING[11]; +BEGIN + Str(L,S); + IntToStr := S; +END; + +FUNCTION ReadUsers(OldGeneral: OldGeneralRecordType): Boolean; +VAR + TFile: Text; + UserFile: FILE OF UserRecordType; + User: UserRecordType; + RecNum, + RecNum1, + RecNum2: Integer; +BEGIN + Assign(UserFile,OldGeneral.DataPath+'USERS.DAT'); + Reset(UserFile); + + Write('Number of users with invalid expiration setup ... '); + + Assign(TFile,'EXPIRE.TXT'); + ReWrite(TFile); + WriteLn(TFile,'Users with invalid expiration setup:'); + Writeln(TFile,''); + + RecNum1 := 0; + RecNum := 0; + WHILE (RecNum <= (FileSize(UserFile) - 1)) DO + BEGIN + Seek(UserFile,RecNum); + Read(UserFile,User); + IF (User.Expiration = 0) AND (User.ExpireTo <> ' ') OR + (User.Expiration <> 0) AND (User.ExpireTo = ' ') THEN + BEGIN + WriteLn(TFile,Caps(User.Name)+' #'+IntToStr(RecNum)); + Inc(RecNum1); + END; + Inc(RecNum); + END; + WriteLn(TFile); + Close(TFile); + IF (RecNum1 = 0) THEN + Erase(TFile); + WriteLn(IntToStr(RecNum1)); + + Write('Number of users with invalid expire to key ... '); + + Assign(TFile,'KEY.TXT'); + ReWrite(TFile); + WriteLn(TFile,'Users with invalid expire to keys:'); + WriteLn(TFile,''); + + Reset(UserFile); + RecNum2 := 0; + RecNum := 0; + WHILE (RecNum <= (FileSize(UserFile) - 1)) DO + BEGIN + Seek(UserFile,RecNum); + Read(UserFile,User); + IF (User.ExpireTo <> ' ') THEN + IF (OldGeneral.OldValidation[User.ExpireTo].Description = '') THEN + BEGIN + WriteLn(TFile,Caps(User.Name)+' #'+IntToStr(RecNum)); + Inc(RecNum2); + END; + Inc(RecNum); + END; + Close(TFile); + IF (RecNum2 = 0) THEN + Erase(TFile); + WriteLn(IntToStr(RecNum2)); + + Close(UserFile); + ReadUsers := (RecNum1 = 0) AND (RecNum2 = 0); +END; + +PROCEDURE CreateValidationRec(OldGeneral: OldGeneralRecordType); +VAR + ValidationFile: FILE OF ValidationRecordType; + Validation: ValidationRecordType; + UserFile: FILE OF UserRecordType; + User: UserRecordType; + C: Char; +BEGIN + Write('Creating "VALIDATE.DAT" file ... '); + + Assign(UserFile,OldGeneral.DataPath+'USERS.DAT'); + Reset(UserFile); + Seek(UserFile,0); + Read(UserFile,User); + Close(UserFile); + + Assign(ValidationFile,OldGeneral.DataPath+'VALIDATE.DAT'); + ReWrite(ValidationFile); + FOR C := 'A' TO 'Z' DO + IF (OldGeneral.OldValidation[C].Description <> '') THEN + BEGIN + WITH Validation DO + BEGIN + IF (C = 'A') THEN + Key := '!' + ELSE + Key := C; + IF (OldGeneral.OldValidation[C].Expiration = 0) THEN + ExpireTo := ' ' + ELSE + ExpireTo := OldGeneral.OldValidation[C].ExpireTo; + IF (C = 'A') THEN + Description := 'New User Validation' + ELSE + Description := OldGeneral.OldValidation[C].Description; + UserMsg := 'You have been validated, enjoy the system!'; + IF (OldGeneral.OldValidation[C].NewSL < User.SL) THEN + NewSL := User.SL + ELSE + NewSL := OldGeneral.OldValidation[C].NewSL; + IF (OldGeneral.OldValidation[C].NewDSL < User.DSL) THEN + NewDSL := User.DSL + ELSE + NewDSL := OldGeneral.OldValidation[C].NewDSL; + NewMenu := OldGeneral.OldValidation[C].NewMenu; + IF (OldGeneral.OldValidation[C].ExpireTo = ' ') THEN + Expiration := 0 + ELSE + Expiration := OldGeneral.OldValidation[C].Expiration; + NewFP := OldGeneral.OldValidation[C].NewFP; + NewCredit := OldGeneral.OldValidation[C].NewCredit; + SoftAR := OldGeneral.OldValidation[C].SoftAR; + SoftAC := OldGeneral.OldValidation[C].SoftAR; + NewAR := OldGeneral.OldValidation[C].NewAR; + NewAC := OldGeneral.OldValidation[C].NewAC; + END; + Write(ValidationFile,Validation); + END; + Close(ValidationFile); + Writeln('Done'); +END; + +PROCEDURE ConvertGeneralRec(OldGeneral: OldGeneralRecordType); +VAR + OldGeneralFile: FILE OF OldGeneralRecordType; + GeneralFile: FILE OF GeneralRecordType; + General: GeneralRecordType; + C: Char; + Counter: Byte; +BEGIN + Write('Converting "RENEGADE.DAT" file ... '); + Assign(OldGeneralFile,'RENEGADE.DAT'); + Reset(OldGeneralFile); + Assign(GeneralFile,'RENEGADE.NEW'); + ReWrite(GeneralFile); + Seek(OldGeneralFile,0); + Read(OldGeneralFile,OldGeneral); + FillChar(General,SizeOf(General),0); + WITH General DO + BEGIN + ForgotPWQuestion := OldGeneral.ForgotPWQuestion; + + QWKWelcome := OldGeneral.QWKWelcome; + QWKNews := OldGeneral.QWKNews; + QWKGoodbye := OldGeneral.QWKGoodbye; + Origin := OldGeneral.Origin; + + DataPath := OldGeneral.DataPath; + MiscPath := OldGeneral.MiscPath; + LogsPath := OldGeneral.LogsPath; + MsgPath := OldGeneral.MsgPath; + NodePath := OldGeneral.NodePath; + TempPath := OldGeneral.TempPath; + ProtPath := OldGeneral.ProtPath; + ArcsPath := OldGeneral.ArcsPath; + MultPath := OldGeneral.MultPath; + FileAttachPath := OldGeneral.FileAttachPath; + QWKLocalPath := OldGeneral.QWKLocalPath; + DefEchoPath := OldGeneral.DefEchoPath; + NetmailPath := OldGeneral.NetMailPath; + BBSName := OldGeneral.BBSName; + + SysOpName := OldGeneral.SysOpName; + + Version := Ver; + + BBSPhone := OldGeneral.BBSPhone; + + LastDate := OldGeneral.LastDate; + + PacketName := OldGeneral.PacketName; + BulletPrefix := OldGeneral.BulletPrefix; + + SysOpPW := OldGeneral.SysOpPw; + NewUserPW := OldGeneral.NewUserPW; + MinBaudOverride := OldGeneral.MinBaudOverride; + QWKNetworkACS := OldGeneral.QWKNetworkACS; + LastOnDatACS := OldGeneral.LastOnDatACS; + SOP := OldGeneral.SOP; + CSOP := OldGeneral.CSOP; + MSOP := OldGeneral.MSOP; + FSOP := OldGeneral.FSOP; + SPW := OldGeneral.SPW; + AddChoice := OldGeneral.AddChoice; + NormPubPost := OldGeneral.NormPubPost; + NormPrivPost := OldGeneral.NormPrivPost; + AnonPubRead := OldGeneral.AnonPubPost; + AnonPrivRead := OldGeneral.AnonPrivRead; + AnonPubPost := OldGeneral.AnonPubPost; + AnonPrivPost := OldGeneral.AnonPrivPost; + SeeUnval := OldGeneral.SeeUnVal; + DLUnval := OldGeneral.DLUnval; + NoDLRatio := OldGeneral.NODLRatio; + NoPostRatio := OldGeneral.NoPostRatio; + NoFileCredits := OldGeneral.NoFileCredits; + ULValReq := OldGeneral.ULValReq; + TeleConfMCI := OldGeneral.TeleConfMCI; + OverrideChat := OldGeneral.OverrideChat; + NetMailACS := OldGeneral.NetMailACS; + Invisible := OldGeneral.Invisible; + FileAttachACS := OldGeneral.FileAttachACS; + ChangeVote := OldGeneral.ChangeVote; + + MaxPrivPost := OldGeneral.MaxPrivPost; + MaxFBack := OldGeneral.MaxFBack; + MaxPubPost := OldGeneral.MaxPubPost; + MaxChat := OldGeneral.MaxChat; + MaxWaiting := OldGeneral.MaxWaiting; + CSMaxWaiting := OldGeneral.CSMaxWaiting; + MaxMassMailList := OldGeneral.MaxMassMailList; + MaxLogonTries := OldGeneral.MaxLogonTries; + SysOpColor := OldGeneral.SysOpColor; + UserColor := OldGeneral.UserColor; + SliceTimer := OldGeneral.SliceTimer; + MaxBatchDLFiles := OldGeneral.MaxBatchDLFiles; + MaxBatchULFiles := OldGeneral.MaxBatchULFiles; + Text_Color := OldGeneral.Text_Color; + Quote_Color := OldGeneral.Quote_Color; + Tear_Color := OldGeneral.Tear_Color; + Origin_Color := OldGeneral.Origin_Color; + BackSysOpLogs := OldGeneral.BackSysOpLogs; + EventWarningTime := OldGeneral.EventWarningTime; + WFCBlankTime := OldGeneral.WFCBlankTime; + AlertBeep := OldGeneral.AlertBeep; + FileCreditComp := OldGeneral.FileCreditComp; + FileCreditCompBaseSize := OldGeneral.FileCreditCompBaseSize; + ULRefund := OldGeneral.ULRefund; + GlobalMenu := OldGeneral.GlobalMenu; + AllStartMenu := OldGeneral.AllStartMenu; + ShuttleLogonMenu := OldGeneral.ShuttleLogonMenu; + NewUserInformationMenu := OldGeneral.NewUserInformationMenu; + FileListingMenu := OldGeneral.FileListingMenu; + MessageReadMenu := OldGeneral.MessageReadMenu; + CurWindow := OldGeneral.CurWindow; + SwapTo := OldGeneral.SwapTo; + + LowTime := OldGeneral.LowTime; + HiTime := OldGeneral.HiTime; + DLLowTime := OldGeneral.DLLowTime; + DLHiTime := OldGeneral.DLHiTime; + MinBaudLowTime := OldGeneral.MinBaudLowTime; + MinBaudHiTime := OldGeneral.MinBaudHiTime; + MinBaudDLLowTime := OldGeneral.MinBaudDLLowTime; + MinBaudDLHiTime := OldGeneral.MinBaudDLHiTime; + MinSpaceForPost := OldGeneral.MinSpaceForPost; + MinSpaceForUpload := OldGeneral.MinSpaceForUpload; + NewApp := OldGeneral.NewApp; + TimeOutBell := OldGeneral.TimeOutBell; + TimeOut := OldGeneral.TimeOut; + ToSysOpDir := OldGeneral.ToSysOpDir; + CreditMinute := OldGeneral.CreditMinute; + CreditPost := OldGeneral.CreditPost; + CreditEmail := OldGeneral.CreditEmail; + CreditFreeTime := OldGeneral.CreditFreeTime; + NumUsers := OldGeneral.NumUsers; + PasswordChange := OldGeneral.PasswordChange; + RewardRatio := OldGeneral.RewardRatio; + CreditInternetMail := OldGeneral.CreditInternetMail; + BirthDateCheck := OldGeneral.BirthDateCheck; + + MaxQWKTotal := OldGeneral.MaxQWKTotal; + MaxQWKBase := OldGeneral.MaxQWKBase; + DaysOnline := OldGeneral.DaysOnline; + + MinimumBaud := OldGeneral.MinimumBaud; + MinimumDLBaud := OldGeneral.MinimumDLBaud; + MaxDepositEver := 300; + MaxDepositPerDay := 30; + MaxWithdrawalPerDay := 30; + CallerNum := OldGeneral.CallerNum; + RegNumber := OldGeneral.RegNumber; + TotalCalls := OldGeneral.TotalCalls; + TotalUsage := OldGeneral.TotalUsage; + TotalPosts := OldGeneral.TotalPosts; + TotalDloads := OldGeneral.TotalDloads; + TotalUloads := OldGeneral.TotalUloads; + MinResume := OldGeneral.MinResume; + MaxInTemp := OldGeneral.MaxInTemp; + + AllowAlias := OldGeneral.AllowAlias; + PhonePW := OldGeneral.PhonePW; + LocalSec := OldGeneral.LocalSec; + GlobalTrap := OldGeneral.GlobalTrap; + AutoChatOpen := OldGeneral.AutoChatOpen; + AutoMInLogon := OldGeneral.AutoMInLogon; + BullInLogon := OldGeneral.BullInLogon; + YourInfoInLogon := OldGeneral.YourInfoInLogon; + OffHookLocalLogon := OldGeneral.OffHookLocalLogon; + ForceVoting := OldGeneral.ForceVoting; + CompressBases := OldGeneral.CompressBases; + SearchDup := OldGeneral.SearchDup; + ForceBatchDL := OldGeneral.ForceBatchDL; + LogonQuote := OldGeneral.LogonQuote; + UserAddQuote := OldGeneral.UserAddQuote; + StripCLog := OldGeneral.StripCLog; + SKludge := OldGeneral.SKludge; + SSeenby := OldGeneral.SSeenby; + SOrigin := OldGeneral.SOrigin; + AddTear := OldGeneral.AddTear; + ShuttleLog := OldGeneral.ShuttleLog; + ClosedSystem := OldGeneral.ClosedSystem; + SwapShell := OldGeneral.SwapShell; + UseEMS := OldGeneral.UseEMS; + UseBios := OldGeneral.UseBios; + UseIEMSI := OldGeneral.UseIEMSI; + ULDLRatio := OldGeneral.ULDLRatio; + FileCreditRatio := OldGeneral.FileCreditRatio; + ValidateAllFiles := OldGeneral.ValidateAllFiles; + FileDiz := OldGeneral.FileDiz; + SysOpPword := OldGeneral.SysOpPword; + TrapTeleConf := OldGeneral.TrapTeleConf; + IsTopWindow := OldGeneral.IsTopWindow; + ReCompress := OldGeneral.ReCompress; + RewardSystem := OldGeneral.RewardSystem; + TrapGroup := OldGeneral.TrapGroup; + QWKTimeIgnore := OldGeneral.QWKTimeIgnore; + NetworkMode := OldGeneral.NetworkMode; + WindowOn := OldGeneral.WindowOn; + ChatCall := OldGeneral.ChatCall; + DailyLimits := OldGeneral.DailyLimits; + MultiNode := OldGeneral.MultiNode; + PerCall := OldGeneral.PerCall; + TestUploads := OldGeneral.TestUploads; + + FOR Counter := 1 TO MaxArcs DO + WITH FileArcInfo[Counter] DO + BEGIN + Active := OldGeneral.FileArcInfo[Counter].Active; + Ext := OldGeneral.FileArcInfo[Counter].Ext; + ListLine := OldGeneral.FileArcInfo[Counter].ListLine; + ArcLine := OldGeneral.FileArcInfo[Counter].ArcLine; + UnArcLine := OldGeneral.FileArcInfo[Counter].UnArcLine; + TestLine := OldGeneral.FileArcInfo[Counter].TestLine; + CmtLine := OldGeneral.FileArcInfo[Counter].CmtLine; + SuccLevel := OldGeneral.FileArcInfo[Counter].SuccLevel; + END; + + FOR Counter := 1 TO 3 DO + FileArcComment[Counter] := OldGeneral.FileArcComment[Counter]; + + FOR Counter := 0 TO 20 DO + WITH AKA[Counter] DO + BEGIN + Zone := OldGeneral.AKA[Counter].Zone; + Net := OldGeneral.AKA[Counter].Net; + Node := OldGeneral.AKA[Counter].Node; + Point := OldGeneral.AKA[Counter].Point; + END; + + FOR Counter := 1 TO 20 DO + NewUserToggles[Counter] := OldGeneral.NewUserToggles[Counter];; + + FOR Counter := 0 TO 9 DO + Macro[Counter] := OldGeneral.Macro[Counter]; + + Netattribute := OldGeneral.Netattribute; + + FOR Counter := 0 TO 255 DO + TimeAllow[Counter] := OldGeneral.TimeAllow[Counter]; + + FOR Counter := 0 TO 255 DO + CallAllow[Counter] := OldGeneral.CallAllow[Counter]; + + FOR Counter := 0 TO 255 DO + DLRatio[Counter] := OldGeneral.DLRatio[Counter]; + + FOR Counter := 0 TO 255 DO + DLKRatio[Counter] := OldGeneral.DLKRatio[Counter]; + + FOR Counter := 0 TO 255 DO + PostRatio[Counter] := OldGeneral.PostRatio[Counter]; + + FOR Counter := 0 TO 255 DO + DLOneday[Counter] := OldGeneral.DLOneday[Counter]; + + FOR Counter := 0 TO 255 DO + DLKOneDay[Counter] := OldGeneral.DLKOneDay[Counter]; + + END; + Write(GeneralFile,General); + Close(OldGeneralFile); + Close(GeneralFile); + Assign(OldGeneralFile,'RENEGADE.DAT'); + Erase(OldGeneralFile); + Assign(GeneralFile,'RENEGADE.NEW'); + ReName(GeneralFile,'RENEGADE.DAT'); + WriteLn('Done'); +END; + +VAR + OldGeneralFile: FILE OF OldGeneralRecordType; + OldGeneral: OldGeneralRecordType; + +BEGIN + ClrScr; + WriteLn('Renegade Update Utility (12.07/8 to 01.28/8)'); + WriteLn; + Writeln('This utility will upgrade your Renegade BBS from'); + WriteLn('Version 12.07/8 to Version 01.28/8.'); + WriteLn; + Writeln('This update will scan your USERS.DAT file to ensure'); + WriteLn('that your expiration information for each guest is'); + WriteLn('configured properly. Errors will be logged to the'); + WriteLn('files (EXPIRE.TXT or KEY.TXT). Errors will result in'); + Writeln('the termination of this update utility until corrected.'); + Writeln('The following rules apply:'); + Writeln; + Writeln(' - Both the expiration date and expire to key must'); + Writeln(' be null or contain valid data. You can not have'); + WriteLn(' one configured without the other.'); + WriteLn; + WriteLn(' - The expire to key must be a valid key configured'); + Writeln(' in the validation editor.'); + WriteLn; + IF PYNQ('Do you wish to continue? ') THEN + BEGIN + WriteLn; + Write('Reading "RENEGADE.DAT" file ... '); + Assign(OldGeneralFile,'RENEGADE.DAT'); + Reset(OldGeneralFile); + Read(OldGeneralFile,OldGeneral); + Close(OldGeneralFile); + WriteLn('Done'); + WriteLn; + (* + IF (NOT ReadUsers(OldGeneral)) THEN + BEGIN + WriteLn; + WriteLn(^G^G^G'Please see the file EXPIRE.TXT/KEY.TXT for errors.'); + END + ELSE + BEGIN + *) + WriteLn; + CreateValidationRec(OldGeneral); + ConvertGeneralRec(OldGeneral); + WriteLn; + WriteLn(^G^G^G'Conversion complete!'); + WriteLn; + WriteLn('Please replace your old RENEGADE.EXE/RENEGADE.OVR files'); + WriteLn('with the new files provided with this update.'); + (* + END; + *) + END; +END. diff --git a/SOURCE/UNUSED/RGUPDT2.EXE b/SOURCE/UNUSED/RGUPDT2.EXE new file mode 100644 index 0000000000000000000000000000000000000000..32ae95d88891314d838ef976009400f914ec9ffe GIT binary patch literal 7216 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGUPDT2.PAS b/SOURCE/UNUSED/RGUPDT2.PAS new file mode 100644 index 0000000..ade23b2 --- /dev/null +++ b/SOURCE/UNUSED/RGUPDT2.PAS @@ -0,0 +1,161 @@ +{$M 49152,0,65536} +PROGRAM RGUPDT1; + +USES + Crt, + Dos; + +{$I RECORDS.PAS} + +CONST + DYNY: BOOLEAN = FALSE; + +TYPE + ConfRec = { CONFRENC.DAT : Conference data } +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + Conference: ARRAY ['@'..'Z'] OF + {$IFDEF WIN32} PACKED {$ENDIF} RECORD + ACS: ACString; { access requirement } + Name: STRING[40]; { name of conference } + END; + END; + +function sqoutsp(s:string):string; +begin + while (pos(' ',s)>0) do delete(s,pos(' ',s),1); + sqoutsp:=s; +end; + +function exist(fn: astr): boolean; +var + srec: searchrec; +begin + findfirst(sqoutsp(fn),anyfile,srec); + exist := (doserror = 0); +end; + +FUNCTION SYN(B: BOOLEAN): STRING; +BEGIN + IF (B) THEN + SYN := 'Yes' + ELSE + SYN := 'No '; +END; + +FUNCTION YN: BOOLEAN; +VAR + C: CHAR; +BEGIN + Write(SQOutSp(SYN(DYNY))); + REPEAT + C := UpCase(Char(ReadKey)); + UNTIL (C IN ['Y','N',^M]); + IF (DYNY) AND (C <> 'N') THEN + C := 'Y'; + IF (DYNY) AND (C = 'N') THEN + Write(#8#8#8'No ') + ELSE IF (NOT DYNY) AND (C = 'Y') THEN + Write(#8#8'Yes'); + WriteLn; + YN := (C = 'Y'); + DYNY := FALSE; +end; + +FUNCTION PYNQ(CONST S: AStr): BOOLEAN; +BEGIN + Write(S); + PYNQ := YN; +END; + +FUNCTION Caps(s: STRING): STRING; +VAR + Counter: Integer; { must be Integer } +BEGIN + IF (s[1] IN ['a'..'z']) THEN + Dec(s[1],32); + FOR Counter := 2 TO Length(s) DO + IF (s[Counter - 1] IN ['a'..'z','A'..'Z']) THEN + IF (s[Counter] IN ['A'..'Z']) THEN + Inc(s[Counter],32) + ELSE + ELSE + IF (s[Counter] IN ['a'..'z']) THEN + Dec(s[Counter],32); + Caps := s; +END; + +FUNCTION IntToStr(L: LongInt): STRING; +VAR + S: STRING[11]; +BEGIN + Str(L,S); + IntToStr := S; +END; + +PROCEDURE ConvertConferenceFile(General: GeneralRecordType); +VAR + ConferenceFile: FILE OF ConferenceRecordType; + Conference: ConferenceRecordType; + OldConferenceFile: FILE OF ConfRec; + OldConference: ConfRec; + C: Char; +BEGIN + Write('Converting "CONFRENC.DAT" file ... '); + Assign(OldConferenceFile,General.DataPath+'CONFRENC.DAT'); + Reset(OldConferenceFile); + Assign(ConferenceFile,General.DataPath+'CONFRENC.NEW'); + ReWrite(ConferenceFile); + Seek(OldConferenceFile,0); + Read(OldConferenceFile,OldConference); + FOR C := '@' TO 'Z' DO + BEGIN + WITH Conference DO + BEGIN + Key := C; + IF (C = '@') THEN + Name := 'General' + ELSE + Name := OldConference.Conference[C].Name; + ACS := OldConference.Conference[C].ACS; + END; + IF (OldConference.Conference[C].Name <> '') THEN + Write(ConferenceFile,Conference); + END; + Close(OldConferenceFile); + Close(ConferenceFile); + Assign(OldConferenceFile,General.DataPath+'CONFRENC.DAT'); + Erase(OldConferenceFile); + Assign(ConferenceFile,General.DataPath+'CONFRENC.NEW'); + ReName(ConferenceFile,General.DataPath+'CONFRENC.DAT'); + WriteLn('Done'); +END; + +VAR + GeneralFile: FILE OF GeneralRecordType; + General: GeneralRecordType; + +BEGIN + ClrScr; + WriteLn('Renegade Update Utility (08.04/8 to 08.12/8)'); + WriteLn; + Writeln('This utility will upgrade your Renegade BBS from'); + WriteLn('Version 08.04/8 to Version 08.12/8.'); + WriteLn; + IF PYNQ('Do you wish to continue? ') THEN + BEGIN + WriteLn; + Write('Reading "RENEGADE.DAT" file ... '); + Assign(GeneralFile,'RENEGADE.DAT'); + Reset(GeneralFile); + Read(GeneralFile,General); + Close(GeneralFile); + WriteLn('Done'); + WriteLn; + ConvertConferenceFile(General); + WriteLn; + WriteLn(^G^G^G'Conversion complete!'); + WriteLn; + WriteLn('Please replace your old RENEGADE.EXE/RENEGADE.OVR files'); + WriteLn('with the new files provided with this update.'); + END; +END. diff --git a/SOURCE/UNUSED/RGUPDT3.EXE b/SOURCE/UNUSED/RGUPDT3.EXE new file mode 100644 index 0000000000000000000000000000000000000000..3e19099cf63ecbe4e16222e9d1c10dda83ace284 GIT binary patch literal 8512 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 BSW^H1 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGUPDT3.PAS b/SOURCE/UNUSED/RGUPDT3.PAS new file mode 100644 index 0000000..598609a --- /dev/null +++ b/SOURCE/UNUSED/RGUPDT3.PAS @@ -0,0 +1,222 @@ +{$M 49152,0,65536} +PROGRAM RGUPDT3; + +USES + Crt, + Dos, + TimeFunc; + +{$I RECORDS.PAS} + +CONST + DYNY: BOOLEAN = FALSE; + +TYPE + OldFileInfoFlagType = + (OldFINotVal, { If file is not validated } + OldFIIsRequest, { If file is REQUEST } + OldFIResumeLater, { If file is RESUME-LATER } + OldFIHatched); { Has file been hatched? } + + OldFIFlagSet = SET OF OldFileInfoFlagType; + + OldFileInfoRecordType = { *.DIR : File records } + {$IFDEF WIN32} PACKED {$ENDIF} RECORD + FileName: STRING[12]; { Filename } + Description: STRING[50]; { File description } + FilePoints: Integer; { File points } + Downloaded: LongInt; { Number DLs } + SizeMod: Byte; { # chars over last 128 Byte block } + Blocks: LongInt; { # 128 Byte blks } + OwnerNum: Integer; { ULer OF file } + OwnerName: STRING[36]; { ULer's name } + Date: UnixTime; { Date ULed } + DateN: Word; { Numeric date ULed - 01/01/85 - 07/26/3061 = 0-65535 } + VPointer: LongInt; { Pointer to verbose descr, -1 if none } + VTextSize: Integer; { Verbose descr textsize - 50 Bytes x 99 Lines = 4950 max } + OldFIFlags: OldFIFlagSet; { File status } + END; + +function sqoutsp(s:string):string; +begin + while (pos(' ',s)>0) do delete(s,pos(' ',s),1); + sqoutsp:=s; +end; + +function exist(fn: astr): boolean; +var + srec: searchrec; +begin + findfirst(sqoutsp(fn),anyfile,srec); + exist := (doserror = 0); +end; + +FUNCTION SYN(B: BOOLEAN): STRING; +BEGIN + IF (B) THEN + SYN := 'Yes' + ELSE + SYN := 'No '; +END; + +FUNCTION YN: BOOLEAN; +VAR + C: CHAR; +BEGIN + Write(SQOutSp(SYN(DYNY))); + REPEAT + C := UpCase(Char(ReadKey)); + UNTIL (C IN ['Y','N',^M]); + IF (DYNY) AND (C <> 'N') THEN + C := 'Y'; + IF (DYNY) AND (C = 'N') THEN + Write(#8#8#8'No ') + ELSE IF (NOT DYNY) AND (C = 'Y') THEN + Write(#8#8'Yes'); + WriteLn; + YN := (C = 'Y'); + DYNY := FALSE; +end; + +FUNCTION PYNQ(CONST S: AStr): BOOLEAN; +BEGIN + Write(S); + PYNQ := YN; +END; + +FUNCTION Caps(s: STRING): STRING; +VAR + Counter: Integer; { must be Integer } +BEGIN + IF (s[1] IN ['a'..'z']) THEN + Dec(s[1],32); + FOR Counter := 2 TO Length(s) DO + IF (s[Counter - 1] IN ['a'..'z','A'..'Z']) THEN + IF (s[Counter] IN ['A'..'Z']) THEN + Inc(s[Counter],32) + ELSE + ELSE + IF (s[Counter] IN ['a'..'z']) THEN + Dec(s[Counter],32); + Caps := s; +END; + +FUNCTION IntToStr(L: LongInt): STRING; +VAR + S: STRING[11]; +BEGIN + Str(L,S); + IntToStr := S; +END; + +PROCEDURE ReadDirFile(DirPath,FName: AStr); +VAR + OldDirFile: FILE OF OldFileInfoRecordType; + DirFile: FILE OF FileInfoRecordType; + OldDir: OldFileInfoRecordType; + Dir: FileInfoRecordType; + RecNum: Integer; +BEGIN + IF (Exist(DirPath+FName+'.DIR')) THEN + BEGIN + Assign(OldDirFile,DirPath+FName+'.DIR'); + Reset(OldDirFile); + Assign(DirFile,DirPath+FName+'.NEW'); + ReWrite(DirFile); + RecNum := 0; + WHILE (RecNum <= (FileSize(OldDirFile) - 1)) DO + BEGIN + Seek(OldDirFile,RecNum); + Read(OldDirFile,OldDir); + WITH DIR DO + BEGIN + FileName := OldDir.FileName; + Description := OldDir.Description; + FilePoints := OldDir.FilePoints; + Downloaded := OldDir.Downloaded; + FileSize := ((OldDir.Blocks * 128) + OldDir.SizeMod); + OwnerNum := OldDir.OwnerNum; + OwnerName := OldDir.OwnerName; + FileDate := OldDir.Date; + VPointer := OldDir.VPointer; + VTextSize := OldDir.VTextSize; + FIFlags := []; + IF (OldFINotVal IN OldDir.OldFIFlags) THEN + Include(FIFlags,FINotVal); + IF (OldFIIsRequest IN OldDir.OldFIFlags) THEN + Include(FIFlags,FIIsRequest); + IF (OldFIResumeLater IN OldDir.OldFIFlags) THEN + Include(FIFlags,FIResumeLater); + IF (OldFIHatched IN OldDir.OldFIFlags) THEN + Include(FIFlags,FIHatched); + END; + Write(DirFile,Dir); + Inc(RecNum); + END; + Close(OldDirFile); + Close(DirFile); + Assign(OlDDirFile,DirPath+FName+'.DIR'); + Erase(OlDDirFile); + Assign(DirFile,DirPath+FName+'.NEW'); + ReName(DirFile,DirPath+FName+'.DIR'); + END; +END; + +PROCEDURE ConvertFileInfoRec(General: GeneralRecordType); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + FileArea: FileAreaRecordType; + DirPath: STRING; + Counter: Integer; +BEGIN + Write('Converting "*.DIR" files ... '); + Assign(FileAreaFile,General.DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + Counter := 0; + WHILE (Counter <= (FileSize(FileAreaFile) - 1)) DO + BEGIN + Seek(FileAreaFile,Counter); + Read(FileAreaFile,FileArea); + WITH FileArea DO + BEGIN + IF (FADirDLPath IN FileArea.FAFlags) THEN + DIRPath := FileArea.DLPath + ELSE + DIRPath := General.DataPath; + ReadDirFile(DirPath,FileArea.FileName); + END; + Inc(Counter); + END; + Close(FileAreaFile); + WriteLn('Done'); +END; + +VAR + GeneralFile: FILE OF GeneralRecordType; + General: GeneralRecordType; + +BEGIN + ClrScr; + WriteLn('Renegade Update Utility (??.??/? to 10.01/8)'); + WriteLn; + Writeln('This utility will upgrade your Renegade BBS from'); + WriteLn('Version ??.??/? to Version 10.01/8.'); + WriteLn; + IF PYNQ('Do you wish to continue? ') THEN + BEGIN + WriteLn; + Write('Reading "RENEGADE.DAT" file ... '); + Assign(GeneralFile,'RENEGADE.DAT'); + Reset(GeneralFile); + Read(GeneralFile,General); + Close(GeneralFile); + WriteLn('Done'); + WriteLn; + ConvertFileInfoRec(General); + WriteLn; + WriteLn('Conversion complete!'); + WriteLn; + WriteLn('Please replace your old RENEGADE.EXE/RENEGADE.OVR files'); + WriteLn('with the new files provided with this update.'); + END; +END. diff --git a/SOURCE/UNUSED/RGUPDT4.PAS b/SOURCE/UNUSED/RGUPDT4.PAS new file mode 100644 index 0000000..3f7f077 --- /dev/null +++ b/SOURCE/UNUSED/RGUPDT4.PAS @@ -0,0 +1,126 @@ +{$M 49152,0,65536} +PROGRAM RGUPDATE; + +USES + Crt, + Dos, + TimeFunc; + +{$I records.pas} + +TYPE + oldnoderec= { MULTNODE.DAT } + {$IFDEF WIN32} packed {$ENDIF} record + User:word; { What user number } + UserName:string[36]; { User's name } + CityState:string[30]; { User's location } + Sex:char; { User's sex } + Age:byte; { User's age } + LogonTime:unixtime; { What time they logged on } + activity:byte; { What are they doing? } + Description:string[50]; { Optional string } + Status:NodeFlagSet; + Room:byte; { What room are they in? } + Channel:word; { What channel are they in? } + Invited:array[0..31] of set of 0..7; { Have they been invited ? } + Booted:array[0..31] of set of 0..7; { Have they been kicked off ? } + Forget:array[0..31] of set of 0..7; { Who are they forgetting? } + end; + +function IntToStr(i: longint): string; +var + s: string; +begin + s := ''; + str(I,S); + IntToStr := s; +end; + +function sqoutsp(s:string):string; +begin + while (pos(' ',s)>0) do delete(s,pos(' ',s),1); + sqoutsp:=s; +end; + +function exist(fn: astr): boolean; +var + srec: searchrec; +begin + findfirst(sqoutsp(fn),anyfile,srec); + exist := (doserror = 0); +end; + +PROCEDURE CvtNodeFile(General: GeneralRecordType); +VAR + OldNodeFile: FILE OF OldNodeRec; + NodeFile: FILE OF NodeRecordType; + OldNode: OldNodeRec; + Node: NodeRecordType; + Counter: Byte; +BEGIN + FOR Counter := 1 To 255 Do + IF Exist(General.DataPath+'NODE'+Inttostr(Counter)+'.DAT') THEN + BEGIN + Write('Converting "NODE'+inttostr(Counter)+'.DAT" file ... '); + Assign(Oldnodefile,General.DataPath+'NODE'+inttostr(Counter)+'.DAT'); + Reset(Oldnodefile); + Read(Oldnodefile,Oldnode); + Assign(nodefile,General.DataPath+'NODE'+inttostr(Counter)+'.NEW'); + ReWrite(nodefile); + WITH Node DO + BEGIN + User := Oldnode.User; + UserName := Oldnode.UserName; + CityState := Oldnode.CityState; + Sex := Oldnode.Sex; + Age := Oldnode.Age; + LogonTime := Oldnode.LogonTime; + + (* Start - Delete *) + {activity := Oldnode.Activity} + (* End - Delete *) + + (* Start - Add *) + IF (OldNode.Activity = 2) THEN + GroupChat := TRUE + ELSE + GroupChat := FALSE; + (* End - Add *) + + (* Start - Change *) + ActivityDesc := Oldnode.Description; + (* End - Change *) + + Status := Oldnode.Status; + Room := Oldnode.Room; + Channel := Oldnode.Channel; + FillChar(Node.Invited,SizeOf(Node.Invited),0); + FillChar(Node.Booted,SizeOf(Node.Booted),0); + FillChar(Node.Forget,SizeOf(Node.Forget),0); + END; + Write(NodeFile,Node); + Close(OldNodeFile); + Close(NodeFile); + Assign(OldNodeFile,General.DataPath+'NODE'+inttostr(Counter)+'.DAT'); + Erase(OldNodeFile); + Assign(NodeFile,General.DataPath+'NODE'+inttostr(Counter)+'.NEW'); + ReName(Nodefile,General.DataPath+'NODE'+inttostr(Counter)+'.DAT'); + WriteLn('Done'); + END; +END; + +VAR + GR: FILE OF GeneralRecordType; + General: GeneralRecordType; + +BEGIN + Write('Reading "RENEGADE.DAT" file ... '); + Assign(GR,'RENEGADE.DAT'); + Reset(GR); + Read(GR,General); + Close(GR); + WriteLn('Done'); + + CvtNodeFile(General); + +END. \ No newline at end of file diff --git a/SOURCE/UNUSED/RGV118.EXE b/SOURCE/UNUSED/RGV118.EXE new file mode 100644 index 0000000000000000000000000000000000000000..1790b46a8ad008ea0553d13dd51cae58f66de2dd GIT binary patch literal 12912 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGV118.PAS b/SOURCE/UNUSED/RGV118.PAS new file mode 100644 index 0000000..3945730 --- /dev/null +++ b/SOURCE/UNUSED/RGV118.PAS @@ -0,0 +1,843 @@ +{$M 49152,0,65536} +PROGRAM RGUPDATE; + +USES + Crt, + Dos, + TimeFunc; + +{$I RECORDS.PAS} + +CONST + DYNY: BOOLEAN = FALSE; + +TYPE + + OldGeneralRecordType = +{$IFDEF WIN32} PACKED {$ENDIF} RECORD + ForgotPWQuestion: STRING[70]; + + QWKWelcome, { QWK welcome file name } + QWKNews, { QWK news file name } + QWKGoodbye, { QWK goodbye file name } + Origin: STRING[50]; { Default Origin line } + + DataPath, { DATA path } + MiscPath, { MISC path } + LogsPath, { LOGS path } + MsgPath, { MSGS path } + NodePath, { NODE list path } + TempPath, { TEMP path } + ProtPath, { PROT path } + ArcsPath, { ARCS path } + lMultPath, { MULT path } + FileAttachPath, { directory for file attaches } + QWKLocalPath, { QWK path for local usage } + DefEchoPath, { default echomail path } + NetmailPath, { path to netmail } + BBSName: STRING[40]; { BBS name } + + SysOpName: STRING[30]; { SysOp's name } + + Version: STRING[20]; + + BBSPhone: STRING[12]; { BBS phone number } + + LastDate: STRING[10]; { last system date } + + PacketName, { QWK packet name } + BulletPrefix: STRING[8]; { default bulletins filename } + + SysOpPW, { SysOp password } + NewUserPW, { newuser password } + MinBaudOverride, { override minimum baud rate } + QWKNetworkACS, { QWK network REP ACS } + LastOnDatACS, + SOP, { SysOp } + CSOP, { Co-SysOp } + MSOP, { Message SysOp } + FSOP, { File SysOp } + SPW, { SysOp PW at logon } + AddChoice, { Add voting choices acs } + NormPubPost, { make normal public posts } + NormPrivPost, { send normal e-mail } + AnonPubRead, { see who posted public anon } + AnonPrivRead, { see who sent anon e-mail } + AnonPubPost, { make anon posts } + AnonPrivPost, { send anon e-mail } + SeeUnval, { see unvalidated files } + DLUnval, { DL unvalidated files } + NoDLRatio, { no UL/DL ratio } + NoPostRatio, { no post/call ratio } + NoFileCredits, { no file credits checking } + ULValReq, { uploads require validation } + TeleConfMCI, { ACS access for MCI codes while teleconfin' } + OverrideChat, { override chat hours } + NetMailACS, { do they have access to netmail? } + Invisible, { Invisible mode? } + FileAttachACS, { ACS to attach files to messages } + ChangeVote: ACString; { ACS to change their vote } + + MaxPrivPost, { max email can send per call } + MaxFBack, { max feedback per call } + MaxPubPost, { max posts per call } + MaxChat, { max sysop pages per call } + MaxWaiting, { max mail waiting } + CSMaxWaiting, { max mail waiting for Co-SysOp + } + MaxMassMailList, + MaxLogonTries, { tries allowed for PW's at logon } + SysOpColor, { SysOp color in chat mode } + UserColor, { user color in chat mode } + SliceTimer, + MaxBatchDLFiles, + MaxBatchULFiles, + Text_Color, { color OF standard text } + Quote_Color, { color OF quoted text } + Tear_Color, { color OF tear line } + Origin_Color, { color OF origin line } + BackSysOpLogs, { days to keep SYSOP##.LOG } + EventWarningTime, { minutes before event to warn user } + WFCBlankTime, { minutes before blanking WFC menu } + AlertBeep, { time between alert beeps - Was Integer } + FileCreditComp, { file credit compensation ratio } + FileCreditCompBaseSize, { file credit area compensation size } + ULRefund, { percent OF time to refund on ULs } + GlobalMenu, + AllStartMenu, + ShuttleLogonMenu, + NewUserInformationMenu, + FileListingMenu, + MessageReadMenu, + CurWindow, { type OF SysOp window in use } + SwapTo: Byte; { Swap where? } + + lLowTime, { SysOp begin minute (in minutes) } + HiTime, { SysOp END time } + DLLowTime, { normal downloading hours begin.. } + DLHiTime, { ..and END } + MinBaudLowTime, { minimum baud calling hours begin.. } + MinBaudHiTime, { ..and END } + MinBaudDLLowTime, { minimum baud downloading hours begin.. } + MinBaudDLHiTime, { ..and END } + MinSpaceForPost, { minimum drive space left to post } + MinSpaceForUpload, { minimum drive space left to upload } + NewApp, { send new user application to # } + TimeOutBell, { minutes before timeout beep } + TimeOut, { minutes before timeout } + ToSysOpDir, { SysOp file area } + CreditMinute, { Credits per minute } + CreditPost, { Credits per post } + CreditEmail, { Credits per Email sent } + CreditFreeTime, { Amount OF "Free" time given to user at logon } + NumUsers, { number OF users } + PasswordChange, { change password at least every x days } + RewardRatio, { % OF file points to reward back } + CreditInternetMail, { cost for Internet mail } + BirthDateCheck: Integer; { check user's birthdate every xx logons } + + MaxQWKTotal, { max msgs in a packet, period } + MaxQWKBase, { max msgs in a area } + DaysOnline: Word; { days online } + + MinimumBaud, { minimum baud rate to logon } + MinimumDLBaud, { minimum baud rate to download } + MaxDepositEver, + MaxDepositPerDay, + MaxWithdrawalPerDay, + CallerNum, { system caller number } + RegNumber, { registration number } + TotalCalls, { incase different from callernum } + TotalUsage, { total usage in minutes } + TotalPosts, { total number OF posts } + TotalDloads, { total number OF dloads } + TotalUloads, { total number OF uloads } + MinResume, { min K to allow resume-later } + MaxInTemp: LongInt; { max K allowed in TEMP } + + AllowAlias, { allow handles? } + PhonePW, { phone number password in logon? } + LocalSec, { use local security? } + GlobalTrap, { trap everyone's activity? } + AutoChatOpen, { automatically open chat buffer? } + AutoMInLogon, { Auto-Message at logon? } + BullInLogon, { bulletins at logon? } + YourInfoInLogon, { "Your Info" at logon? } + OffHookLocalLogon, { phone off-hook for local logons? } + ForceVoting, { manditory voting? } + CompressBases, { "compress" file/msg area numbers? } + SearchDup, { search for dupes files when UL? } + ForceBatchDL, + LogonQuote, + UserAddQuote, + StripCLog, { strip colors from SysOp log? } + SKludge, { show kludge lines? } + SSeenby, { show SEEN-BY lines? } + SOrigin, { show origin line? } + AddTear, { show tear line? } + ShuttleLog, { Use Shuttle Logon? } + ClosedSystem, { Allow new users? } + SwapShell, { Swap on shell? } + UseEMS, { use EMS for overlay } + UseBios, { use BIOS for video output } + UseIEMSI, { use IEMSI } + ULDLRatio, { use UL/DL ratios? } + FileCreditRatio, { use auto file-credit compensation? } + ValidateAllFiles, { validate files automatically? } + FileDiz, { Search/Import file_id.diz } + SysOpPword, { check for sysop password? } + TrapTeleConf, { Trap teleconferencing to ROOMx.TRP? } + IsTopWindow, { is window at top OF screen? } + ReCompress, { recompress like archives? } + RewardSystem, { use file rewarding system? } + TrapGroup, { record group chats? } + QWKTimeIgnore, { ignore time remaining for qwk download? } + NetworkMode, { Network mode ? } + WindowOn, { is the sysop window on? } + ChatCall, { Whether system keeps beeping after chat} + DailyLimits, { Daily file limits on/off } + MultiNode, { enable multinode support } + PerCall, { time limits are per call or per day?} + TestUploads: Boolean; { perform integrity tests on uploads? } + + FileArcInfo: + ARRAY [1..MaxArcs] OF FileArcInfoRecordType; { archive specs } + + FileArcComment: + ARRAY [1..3] OF STRING[40]; { BBS comment files for archives } + + Aka: ARRAY [0..20] OF + {$IFDEF WIN32} PACKED {$ENDIF} RECORD { 20 Addresses } + Zone, { 21st is for UUCP address } + Net, + Node, + Point: Word; + END; + + NewUserToggles: ARRAY [1..20] OF Byte; + + Macro: ARRAY [0..9] OF STRING[100]; { sysop macros } + + Netattribute: NetAttribs; { default netmail attribute } + + TimeAllow, { time allowance } + CallAllow, { call allowance } + DLRatio, { # ULs/# DLs ratios } + DLKRatio, { DLk/ULk ratios } + PostRatio, { posts per call ratio } + DLOneday, { Max number OF dload files in one day} + DLKOneDay: SecurityRangeType; { Max k downloaded in one day} + END; + + OldStatusFlagType = + (OldLockedOut, { if locked out } + OldDeleted, { if deleted } + OldTrapActivity, { if trapping users activity } + OldTrapSeparate, { if trap to seperate TRAP file } + OldChatAuto, { if auto chat trapping } + OldChatSeparate, { if separate chat file to trap to } + OldSLogSeparate, { if separate SysOp log } + OldCLSMsg, { if clear-screens } + OldRIP, { if RIP graphics can be used } + OldFSEditor, { if Full Screen Editor } + OldAutoDetect { Use auto-detected emulation } + ); + + OldStatusFlagSet = SET OF OldStatusFlagType; + + OldUserRecordType = { USERS.DAT : User records } + {$IFDEF WIN32} PACKED {$ENDIF} RECORD + Name, { system name } + RealName: STRING[36]; { real name } + Street, { street address } + CityState: STRING[30]; { city, state } + CallerID: STRING[20]; { caller ID STRING } + ZipCode: STRING[10]; { zipcode } + PH: STRING[12]; { phone # } + ForgotPWAnswer: STRING[40]; + UsrDefStr: ARRAY [1..3] OF STRING[35]; { definable strings } + Note: STRING[35]; { SysOp note } + LockedFile: STRING[8]; { print lockout msg } + Vote: ARRAY [1..25] OF Byte; { voting data } + Sex, { gender } + Subscription, { their subscription } + ExpireTo, { level to expire to } + LastConf: Char; { last conference in } + + SL, { SL } + DSL, { DSL } + Waiting, { mail waiting } + LineLen, { line length } + PageLen, { page length } + OnToday, { # times on today } + Illegal, { # illegal logons } + DefArcType, { QWK archive type } + ColorScheme, { Color scheme # } + UserStartMenu: Byte; { menu to start at } + + BirthDate, { Birth date } + FirstOn, { First On Date } + LastOn, { Last On Date } + TTimeOn, { total time on } + LastQWK, { last qwk packet } + Expiration: UnixTime; { Expiration date } + + UserID, { Permanent userid } + TLToday, { # min left today } + ForUsr, { forward mail to } + LastMsgArea, { # last msg area } + LastFileArea: Integer; { # last file area } + + PasswordChanged: Word; { Numeric date pw changed - was UnixTime } + + Credit, { Amount OF credit } + Debit, { Amount OF debit } + PW, { password } + Uploads, { # OF DLs } + Downloads, { # OF DLs } + UK, { UL k } + DK, { DL k } + LoggedOn, { # times on } + MsgPost, { # message posts } + EmailSent, { # email sent } + FeedBack, { # feedback sent } + TimeBank, { # mins in bank } + TimeBankAdd, { # added today } + DLKToday, { # kbytes dl today } + DLToday, { # files dl today } + TimeBankWith: LongInt; { Time withdrawn } + + TeleConfEcho, { Teleconf echo? } + TeleConfInt, { Teleconf interrupt } + GetOwnQWK, { Get own messages } + ScanFilesQWK, { new files in qwk } + PrivateQWK: Boolean; { private mail qwk } + + AR: ARFlagSet; { AR flags } + Flags: FlagSet; { flags } + OldSFlags: OldStatusFlagSet; { status flags } + END; + +function sqoutsp(s:string):string; +begin + while (pos(' ',s)>0) do delete(s,pos(' ',s),1); + sqoutsp:=s; +end; + +function exist(fn: astr): boolean; +var + srec: searchrec; +begin + findfirst(sqoutsp(fn),anyfile,srec); + exist := (doserror = 0); +end; + +FUNCTION SYN(B: BOOLEAN): STRING; +BEGIN + IF (B) THEN + SYN := 'Yes' + ELSE + SYN := 'No '; +END; + +FUNCTION YN: BOOLEAN; +VAR + C: CHAR; +BEGIN + Write(SQOutSp(SYN(DYNY))); + REPEAT + C := UpCase(Char(ReadKey)); + UNTIL (C IN ['Y','N',^M]); + IF (DYNY) AND (C <> 'N') THEN + C := 'Y'; + IF (DYNY) AND (C = 'N') THEN + Write(#8#8#8'No ') + ELSE IF (NOT DYNY) AND (C = 'Y') THEN + Write(#8#8'Yes'); + WriteLn; + YN := (C = 'Y'); + DYNY := FALSE; +end; + +FUNCTION PYNQ(CONST S: AStr): BOOLEAN; +BEGIN + Write(S); + PYNQ := YN; +END; + +PROCEDURE ChangeLength(S: STRING; VAR S1,S2: STRING); +VAR + TempStr: STRING; + Counter: Byte; +BEGIN + IF (Length(S) <= 60) THEN + BEGIN + S1 := S; + S2 := ''; + END + ELSE + BEGIN + TempStr := Copy(S,1,65); + IF (TempStr[65] <> ' ') THEN + BEGIN + Counter := 65; + WHILE (TempStr[Counter] <> ' ') DO + BEGIN + Dec(TempStr[0]); + Dec(Counter); + END; + Dec(TempStr[0]); + S1 := TempStr; + S2 := Copy(S,(Counter + 1),Length(S)); + END + ELSE + BEGIN + S1 := Copy(S,1,64); + S2 := Copy(S,66,Length(S)); + END; + END; +END; + +PROCEDURE Kill(CONST FileName: AStr); +VAR + F: FILE; +BEGIN + Assign(F,FileName); + Erase(F); +END; + +PROCEDURE ConvertGeneralRec; +VAR + OldGeneralFile: FILE OF OldGeneralRecordType; + GeneralFile: FILE OF GeneralRecordType; + OldGeneral: OldGeneralRecordType; + General: GeneralRecordType; + Counter: Integer; +BEGIN + Write('Converting "RENEGADE.DAT" file ... '); + Assign(OldGeneralFile,'RENEGADE.DAT'); + Reset(OldGeneralFile); + Assign(GeneralFile,'RENEGADE.NEW'); + ReWrite(GeneralFile); + Seek(OldGeneralFile,0); + Read(OldGeneralFile,OldGeneral); + WITH General DO + BEGIN + ForgotPWQuestion := OldGeneral.ForgotPWQuestion; + + QWKWelcome := OldGeneral.QWKWelcome; + QWKNews := OldGeneral.QWKNews; + QWKGoodbye := OldGeneral.QWKGoodBye; + Origin := OldGeneral.Origin; + + DataPath := OldGeneral.DataPath; + MiscPath := OldGeneral.MiscPath; + LogsPath := OldGeneral.LogsPath; + MsgPath := OldGeneral.MsgPath; + NodePath := OldGeneral.NodePath; + TempPath := OldGeneral.TempPath; + ProtPath := OldGeneral.ProtPath; + ArcsPath := OldGeneral.ArcsPath; + lMultPath := OldGeneral.LMultPath; + FileAttachPath := OldGeneral.FileAttachPath; + QWKLocalPath := OldGeneral.QWKLocalPath; + DefEchoPath := OldGeneral.DefEchoPath; + NetmailPath := OldGeneral.NetMailPath; + BBSName := OldGeneral.BBSName; + + SysOpName := OldGeneral.SysOpName; + + Version := '1.18a'; (* <-- Update this with version *) + + BBSPhone := OldGeneral.BBSPhone; + + LastDate := OldGeneral.LastDate; + + PacketName := OldGeneral.PacketName; + BulletPrefix := OldGeneral.BulletPrefix; + + SysOpPW := OldGeneral.SysOpPW; + NewUserPW := OldGeneral.NewUserPW; + MinBaudOverride := OldGeneral.MinBaudOverride; + QWKNetworkACS := OldGeneral.QWKNetworkACS; + LastOnDatACS := OldGeneral.LastOnDatACS; + SOP := OldGeneral.SOP; + CSOP := OldGeneral.CSOP; + MSOP := OldGeneral.MSOP; + FSOP := OldGeneral.FSOP; + SPW := OldGeneral.SPW; + AddChoice := OldGeneral.AddChoice; + NormPubPost := OldGeneral.NormPubPost; + NormPrivPost := OldGeneral.NormPrivPost; + AnonPubRead := OldGeneral.AnonPubRead; + AnonPrivRead := OldGeneral.AnonPrivRead; + AnonPubPost := OldGeneral.AnonPubPost; + AnonPrivPost := OldGeneral.AnonPrivPost; + SeeUnval := OldGeneral.SeeUnval; + DLUnval := OldGeneral.DLUnval; + NoDLRatio := OldGeneral.NoDLRatio; + NoPostRatio := OldGeneral.NoPostRatio; + NoFileCredits := OldGeneral.NoFileCredits; + ULValReq := OldGeneral.ULValReq; + TeleConfMCI := OldGeneral.TeleConfMCI; + OverrideChat := OldGeneral.OverrideChat; + NetMailACS := OldGeneral.NetMailACS; + Invisible := OldGeneral.Invisible; + FileAttachACS := OldGeneral.FileAttachACS; + ChangeVote := OldGeneral.ChangeVote; + UnUsedACS1 := ''; + UnUsedACS2 := ''; + + MaxPrivPost := OldGeneral.MaxPrivPost; + MaxFBack := OldGeneral.MaxFBack; + MaxPubPost := OldGeneral.MaxPubPost; + MaxChat := OldGeneral.MaxChat; + MaxWaiting := OldGeneral.MaxWaiting; + CSMaxWaiting := OldGeneral.CSMaxWaiting; + MaxMassMailList := OldGeneral.MaxMassMailList; + MaxLogonTries := OldGeneral.MaxLogonTries; + SysOpColor := OldGeneral.SysOpColor; + UserColor := OldGeneral.UserColor; + SliceTimer := OldGeneral.SliceTimer; + MaxBatchDLFiles := OldGeneral.MaxBatchDLFiles; + MaxBatchULFiles := OldGeneral.MaxBatchULFiles; + Text_Color := OldGeneral.Text_Color; + Quote_Color := OldGeneral.Quote_Color; + Tear_Color := OldGeneral.Tear_Color; + Origin_Color := OldGeneral.Origin_Color; + BackSysOpLogs := OldGeneral.BackSysOpLogs; + EventWarningTime := OldGeneral.EventWarningTime; + WFCBlankTime := OldGeneral.WFCBlankTime; + AlertBeep := OldGeneral.AlertBeep; + FileCreditComp := OldGeneral.FileCreditComp; + FileCreditCompBaseSize := OldGeneral.FileCreditCompBaseSize; + ULRefund := OldGeneral.ULRefund; + GlobalMenu := OldGeneral.GlobalMenu; + AllStartMenu := OldGeneral.AllStartMenu; + ShuttleLogonMenu := OldGeneral.ShuttleLogonMenu; + NewUserInformationMenu := OldGeneral.NewUserInformationMenu; + FileListingMenu := OldGeneral.FileListingMenu; + MessageReadMenu := OldGeneral.MessageReadMenu; + CurWindow := OldGeneral.CurWindow; + SwapTo := OldGeneral.SwapTo; + UnUsedByte1 := 0; + UnUsedByte2 := 0; + + lLowTime := OldGeneral.lLowTime; + HiTime := OldGeneral.HiTime; + DLLowTime := OldGeneral.DLLowTime; + DLHiTime := OldGeneral.DLHiTime; + MinBaudLowTime := OldGeneral.MinBaudLowTime; + MinBaudHiTime := OldGeneral.MinBaudHiTime; + MinBaudDLLowTime := OldGeneral.MinBaudDLLowTime; + MinBaudDLHiTime := OldGeneral.MinBaudDLHiTime; + NewApp := OldGeneral.NewApp; + TimeOutBell := OldGeneral.TimeOutBell; + TimeOut := OldGeneral.TimeOut; + ToSysOpDir := OldGeneral.ToSysOpDir; + CreditMinute := OldGeneral.CreditMinute; + CreditPost := OldGeneral.CreditPost; + CreditEmail := OldGeneral.CreditEmail; + CreditFreeTime := OldGeneral.CreditFreeTime; + NumUsers := OldGeneral.NumUsers; + PasswordChange := OldGeneral.PasswordChange; + RewardRatio := OldGeneral.RewardRatio; + CreditInternetMail := OldGeneral.CreditInternetMail; + BirthDateCheck := OldGeneral.BirthDateCheck; + UnUsedInteger1 := 0; + UnUsedInteger2 := 0; + + MaxQWKTotal := OldGeneral.MaxQWKTotal; + MaxQWKBase := OldGeneral.MaxQWKBase; + DaysOnline := OldGeneral.DaysOnline; + UnUsedWord1 := 0; + UnUsedWord2 := 0; + + MinimumBaud := OldGeneral.MinimumBaud; + MinimumDLBaud := OldGeneral.MinimumDLBaud; + MaxDepositEver := OldGeneral.MaxDepositEver; + MaxDepositPerDay := OldGeneral.MaxDepositPerDay; + MaxWithdrawalPerDay := OldGeneral.MaxWithdrawalPerDay; + CallerNum := OldGeneral.CallerNum; + RegNumber := OldGeneral.RegNumber; + TotalCalls := OldGeneral.TotalCalls; + TotalUsage := OldGeneral.TotalUsage; + TotalPosts := OldGeneral.TotalPosts; + TotalDloads := OldGeneral.TotalDloads; + TotalUloads := OldGeneral.TotalUloads; + MinResume := OldGeneral.MinResume; + MaxInTemp := OldGeneral.MaxInTemp; + MinSpaceForPost := OldGeneral.MinSpaceForPost; + MinSpaceForUpload := OldGeneral.MinSpaceForUpload; + UnUsedLongInt1 := 0; + UnUsedLongInt2 := 0; + + AllowAlias := OldGeneral.AllowAlias; + PhonePW := OldGeneral.PhonePW; + LocalSec := OldGeneral.LocalSec; + GlobalTrap := OldGeneral.GlobalTrap; + AutoChatOpen := OldGeneral.AutoChatOpen; + AutoMInLogon := OldGeneral.AutoMInLogon; + BullInLogon := OldGeneral.BullInLogon; + YourInfoInLogon := OldGeneral.YourInfoInLogon; + OffHookLocalLogon := OldGeneral.OffHookLocalLogon; + ForceVoting := OldGeneral.ForceVoting; + CompressBases := OldGeneral.CompressBases; + SearchDup := OldGeneral.SearchDup; + ForceBatchDL := OldGeneral.ForceBatchDL; + ForceBatchUL := FALSE; + LogonQuote := OldGeneral.LogonQuote; + UserAddQuote := OldGeneral.UserAddQuote; + StripCLog := OldGeneral.StripCLog; + SKludge := OldGeneral.SKludge; + SSeenby := OldGeneral.SSeenby; + SOrigin := OldGeneral.SOrigin; + AddTear := OldGeneral.AddTear; + ShuttleLog := OldGeneral.ShuttleLog; + ClosedSystem := OldGeneral.ClosedSystem; + SwapShell := OldGeneral.SwapShell; + UseEMS := OldGeneral.UseEMS; + UseBios := OldGeneral.UseBios; + UseIEMSI := OldGeneral.UseIEMSI; + ULDLRatio := OldGeneral.ULDLRatio; + FileCreditRatio := OldGeneral.FileCreditRatio; + ValidateAllFiles := OldGeneral.ValidateAllFiles; + FileDiz := OldGeneral.FileDiz; + SysOpPword := OldGeneral.SysOpPword; + TrapTeleConf := OldGeneral.TrapTeleConf; + IsTopWindow := OldGeneral.IsTopWindow; + ReCompress := OldGeneral.ReCompress; + RewardSystem := OldGeneral.RewardSystem; + TrapGroup := OldGeneral.TrapGroup; + QWKTimeIgnore := OldGeneral.QWKTimeIgnore; + NetworkMode := OldGeneral.NetworkMode; + WindowOn := OldGeneral.WindowOn; + ChatCall := OldGeneral.ChatCall; + DailyLimits := OldGeneral.DailyLimits; + MultiNode := OldGeneral.MultiNode; + PerCall := OldGeneral.PerCall; + TestUploads := OldGeneral.TestUploads; + UseFileAreaLightBar := TRUE; + UseMsgAreaLightBar := TRUE; + UnUsedBoolean1 := FALSE; + UnUsedBoolean2 := FALSE; + + FOR Counter := 1 TO MaxArcs DO + FileArcInfo[Counter] := OldGeneral.FileArcInfo[Counter]; + + FOR Counter := 1 TO 3 DO + FileArcComment[Counter] := OldGeneral.FileArcComment[Counter]; + + FOR Counter := 0 TO 20 DO + WITH AKA[Counter] DO + BEGIN + Zone := OldGeneral.AKA[Counter].Zone; + Net := OldGeneral.AKA[Counter].Net; + Node := OldGeneral.AKA[Counter].Node; + Point := OldGeneral.AKA[Counter].Point; + END; + + FOR Counter := 1 TO 20 DO + NewUserToggles[Counter] := OldGeneral.NewUserToggles[Counter]; + + FOR Counter := 0 TO 9 DO + Macro[Counter] := OldGeneral.Macro[Counter]; + + Netattribute := OldGeneral.NetAttribute; + + TimeAllow := OldGeneral.TimeAllow; + CallAllow := OldGeneral.CallAllow; + DLRatio := OldGeneral.DLRatio; + DLKRatio := OldGeneral.DLKRatio; + PostRatio := OldGeneral.PostRatio; + DLOneday := OldGeneral.DLOneDay; + DLKOneDay := OldGeneral.DLKOneDay; + END; + Seek(GeneralFile,0); + Write(GeneralFile,General); + Close(OldGeneralFile); + Close(GeneralFile); + Assign(OldGeneralFile,'RENEGADE.DAT'); + Erase(OldGeneralFile); + Assign(GeneralFile,'RENEGADE.NEW'); + ReName(GeneralFile,'RENEGADE.DAT'); + WriteLn('Done'); +END; + +PROCEDURE ConvertUserRec(OldGeneral: OldGeneralRecordType); +VAR + OldUserFile: FILE OF OldUserRecordType; + UserFile: FILE OF UserRecordType; + OldUser: OldUserRecordType; + User: UserRecordType; + Counter, + Counter1: Integer; +BEGIN + Write('Converting "USERS.DAT" file ... '); + Assign(OldUserFile,OldGeneral.DataPath+'USERS.DAT'); + Reset(OldUserFile); + Assign(UserFile,OldGeneral.DataPath+'USERS.NEW'); + ReWrite(UserFile); + Counter := 0; + WHILE (Counter <= (FileSize(OldUserFile) - 1)) DO + BEGIN + Seek(OldUserFile,Counter); + Read(OldUserFile,OldUser); + WITH User DO + BEGIN + Name := OldUser.Name; + RealName := OldUser.RealName; + Street := OldUser.Street; + CityState := OldUser.CityState; + CallerID := OldUser.CallerID; + ZipCode := OldUser.ZipCode; + PH := OldUser.PH; + ForgotPWAnswer := OldUser.ForgotPWAnswer; + FOR Counter1 := 1 TO 3 DO + UsrDefStr[Counter1] := OldUser.UsrDefStr[Counter1]; + Note := OldUser.Note; + LockedFile := OldUser.LockedFile; + FOR Counter1 := 1 TO 25 DO + Vote[Counter1] := OldUser.Vote[Counter1]; + Sex := OldUser.Sex; + Subscription := OldUser.SubScription; + ExpireTo := OldUser.ExpireTo; + LastConf := OldUser.LastConf; + UnUsedChar1 := ' '; + UnUsedChar2 := ' '; + + SL := OldUser.SL; + DSL := OldUser.DSL; + Waiting := OldUser.Waiting; + LineLen := OldUser.LineLen; + PageLen := OldUser.PageLen; + OnToday := OldUser.OnToday; + Illegal := OldUser.Illegal; + DefArcType := OldUser.DefArcType; + ColorScheme := OldUser.ColorScheme; + UserStartMenu := OldUser.UserStartMenu; + UnUsedByte1 := 0; + UnUsedByte2 := 0; + + BirthDate := OldUser.BirthDate; + FirstOn := OldUser.FirstOn; + LastOn := OldUser.LastOn; + TTimeOn := OldUser.TTimeOn; + LastQWK := OldUser.LastQWK; + Expiration := OldUser.Expiration; + UnUsedUnixTime1 := 0; + UnUsedUnixTime2 := 0; + + UserID := OldUser.UserID; + TLToday := OldUser.TLToday; + ForUsr := OldUser.ForUsr; + LastMsgArea := OldUser.LastMsgArea; + LastFileArea := OldUser.LastFileArea; + UnUsedInteger1 := 0; + UnUsedInteger2 := 0; + + PasswordChanged := OldUser.PasswordChanged; + UnUsedWord1 := 0; + UnUsedWord2 := 0; + + LCredit := OldUser.Credit; + Debit := OldUser.Debit; + PW := OldUser.PW; + Uploads := OldUser.Uploads; + Downloads := OldUser.Downloads; + UK := OldUser.UK; + DK := OldUser.DK; + LoggedOn := OldUser.LoggedOn; + MsgPost := OldUser.MsgPost; + EmailSent := OldUser.EmailSent; + FeedBack := OldUser.FeedBack; + TimeBank := OldUser.TimeBank; + TimeBankAdd := OldUser.TimeBankAdd; + DLKToday := OldUser.DLKToday; + DLToday := OldUser.DLToday; + FilePoints := 0; + TimeBankWith := OldUser.TimeBankWith; + UnUsedLongInt1 := 0; + UnUsedLongInt2 := 0; + + TeleConfEcho := OldUser.TeleConfEcho; + TeleConfInt := OldUser.TeleConfInt; + GetOwnQWK := OldUser.GetOwnQWK; + ScanFilesQWK := OldUser.ScanFilesQWK; + PrivateQWK := OldUser.PrivateQWK; + UnUsedBoolean1 := FALSE; + UnUsedBoolean2 := FALSE; + + AR := OldUser.AR; + + Flags := OldUser.Flags; + + SFlags := []; + IF (OldLockedOut IN OldUser.OldSFlags) THEN + Include(SFlags,LockedOut); + IF (OldDeleted IN OldUser.OldSFlags) THEN + Include(SFlags,Deleted); + IF (OldTrapActivity IN OldUser.OldSFlags) THEN + Include(SFlags,TrapActivity); + IF (OldTrapSeparate IN OldUser.OldSFlags) THEN + Include(SFlags,TrapSeparate); + IF (OldChatAuto IN OldUser.OldSFlags) THEN + Include(SFlags,ChatAuto); + IF (OldChatSeparate IN OldUser.OldSFlags) THEN + Include(SFlags,ChatSeparate); + IF (OldSLogSeparate IN OldUser.OldSFlags) THEN + Include(SFlags,SLogSeparate); + IF (OldCLSMsg IN OldUser.OldSFlags) THEN + Include(SFlags,CLSMsg); + IF (OldRIP IN OldUser.OldSFlags) THEN + Include(SFlags,RIP); + IF (OldFSEditor IN OldUser.OldSFlags) THEN + Include(SFlags,FSEditor); + IF (OldAutoDetect IN OldUser.OldSFlags) THEN + Include(SFlags,AutoDetect); + Include(SFlags,FileAreaLightBar); + Include(SFlags,MsgAreaLightBar); + END; + Write(UserFile,User); + Inc(Counter); + END; + Close(OldUserFile); + Close(UserFile); + Assign(OldUserFile,OldGeneral.DataPath+'USERS.DAT'); + Erase(OldUserFile); + Assign(UserFile,OldGeneral.DataPath+'USERS.NEW'); + ReName(UserFile,OldGeneral.DataPath+'USERS.DAT'); + WriteLn('Done'); +END; + +VAR + OldGeneralFile: FILE OF OldGeneralRecordType; + OldGeneral: OldGeneralRecordType; + +BEGIN + ClrScr; + WriteLn('Renegade Upgrade Utility (v1.10 to v1.18a)'); (* <-- Update this with version *) + WriteLn; + Writeln('This utility will upgrade your Renegade BBS from'); + WriteLn('Version 1.10 to Version 1.18a'); (* <-- Update this with version *) + WriteLn; + IF PYNQ('Do you want to continue? ') THEN + BEGIN + WriteLn; + Write('Reading "RENEGADE.DAT" file ... '); + Assign(OldGeneralFile,'RENEGADE.DAT'); + Reset(OldGeneralFile); + Seek(OldGeneralFile,0); + Read(OldGeneralFile,OldGeneral); + Close(OldGeneralFile); + WriteLn('Done'); + WriteLn; + IF (Exist(OldGeneral.DataPath+'BATCHDL.DAT')) THEN + BEGIN + Write('Deleting "BATCHDL.DAT" file ... '); + Kill(OldGeneral.DataPath+'BATCHDL.DAT'); + WriteLn('Done'); + END; + ConvertUserRec(OldGeneral); + ConvertGeneralRec; + END; +END. diff --git a/SOURCE/UNUSED/RGVER.EXE b/SOURCE/UNUSED/RGVER.EXE new file mode 100644 index 0000000000000000000000000000000000000000..f4245784c2b93d27f7dce8d5d4a8f86dc66b9f17 GIT binary patch literal 17744 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 J2i~6g{U5n*`{Mur literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGVER.PAS b/SOURCE/UNUSED/RGVER.PAS new file mode 100644 index 0000000..d29c2eb --- /dev/null +++ b/SOURCE/UNUSED/RGVER.PAS @@ -0,0 +1,95 @@ +PROGRAM RGVERUDT; + +USES + CRT, + Common1; + +{$I RECORDS.PAS} + +CONST + DYNY: BOOLEAN = FALSE; + +VAR + GeneralFile: FILE OF GeneralRecordType; + General: GeneralRecordType; + VerStr: STRING; + +function sqoutsp(s:string):string; +begin + while (pos(' ',s)>0) do delete(s,pos(' ',s),1); + sqoutsp:=s; +end; + +FUNCTION SYN(B: BOOLEAN): STRING; +BEGIN + IF (B) THEN + SYN := 'Yes' + ELSE + SYN := 'No '; +END; + +FUNCTION YN: BOOLEAN; +VAR + C: CHAR; +BEGIN + Write(SQOutSp(SYN(DYNY))); + REPEAT + C := UpCase(Char(ReadKey)); + UNTIL (C IN ['Y','N',^M]); + IF (DYNY) AND (C <> 'N') THEN + C := 'Y'; + IF (DYNY) AND (C = 'N') THEN + Write(#8#8#8'No ') + ELSE IF (NOT DYNY) AND (C = 'Y') THEN + Write(#8#8'Yes'); + WriteLn; + YN := (C = 'Y'); + DYNY := FALSE; +end; + +FUNCTION PYNQ(CONST S: AStr): BOOLEAN; +BEGIN + Write(S); + PYNQ := YN; +END; + +BEGIN + ClrScr; + WriteLn('Renegade Version Update Utility Version 1.0a'); + WriteLn; + Writeln('This utility will upgrade the Renegade Data Files.'); + WriteLn; + IF PYNQ('Do you wish to continue? ') THEN + BEGIN + { WriteLn; + WriteLn('Example: 07-12.8/Alpha'); + WriteLn; + Write('Please enter the new version: '); + Local_Input1(VerStr,20,TRUE);} + VerStr := '1.19/Alpha'; + {IF (VerStr = '') THEN + WriteLn(^G^G^G'Aborted!') + ELSE + BEGIN + WriteLn; + WriteLn('You entered '+VerStr); + WriteLn; + IF PYNQ('Is this what you want? ') THEN} + BEGIN + WriteLn; + Write('Updating "RENEGADE.DAT" file ... '); + Assign(GeneralFile,'RENEGADE.DAT'); + Reset(GeneralFile); + Seek(GeneralFile,0); + Read(GeneralFile,General); + General.Version := VerStr; + Seek(GeneralFile,0); + Write(GeneralFile,General); + Close(GeneralFile); + WriteLn('Done'); + WriteLn; + WriteLn(^G^G^G'Update complete!'); + END; + END; + +END. diff --git a/SOURCE/UNUSED/RGVERUDT.EXE b/SOURCE/UNUSED/RGVERUDT.EXE new file mode 100644 index 0000000000000000000000000000000000000000..ef6adaf6fa663ee1a88eb87f632a12fd85f56905 GIT binary patch literal 18624 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/RGVERUDT.PAS b/SOURCE/UNUSED/RGVERUDT.PAS new file mode 100644 index 0000000..7347293 --- /dev/null +++ b/SOURCE/UNUSED/RGVERUDT.PAS @@ -0,0 +1,94 @@ +PROGRAM RGVERUDT; + +USES + CRT, + Common1; + +{$I RECORDS.PAS} + +CONST + DYNY: BOOLEAN = FALSE; + +VAR + GeneralFile: FILE OF GeneralRecordType; + General: GeneralRecordType; + VerStr: STRING; + +function sqoutsp(s:string):string; +begin + while (pos(' ',s)>0) do delete(s,pos(' ',s),1); + sqoutsp:=s; +end; + +FUNCTION SYN(B: BOOLEAN): STRING; +BEGIN + IF (B) THEN + SYN := 'Yes' + ELSE + SYN := 'No '; +END; + +FUNCTION YN: BOOLEAN; +VAR + C: CHAR; +BEGIN + Write(SQOutSp(SYN(DYNY))); + REPEAT + C := UpCase(Char(ReadKey)); + UNTIL (C IN ['Y','N',^M]); + IF (DYNY) AND (C <> 'N') THEN + C := 'Y'; + IF (DYNY) AND (C = 'N') THEN + Write(#8#8#8'No ') + ELSE IF (NOT DYNY) AND (C = 'Y') THEN + Write(#8#8'Yes'); + WriteLn; + YN := (C = 'Y'); + DYNY := FALSE; +end; + +FUNCTION PYNQ(CONST S: AStr): BOOLEAN; +BEGIN + Write(S); + PYNQ := YN; +END; + +BEGIN + ClrScr; + WriteLn('Renegade Version Update Utility Version 1.0'); + WriteLn; + Writeln('This utility will upgrade the Renegade Version Number.'); + WriteLn; + IF PYNQ('Do you wish to continue? ') THEN + BEGIN + WriteLn; + WriteLn('Example: 07-12.8/Alpha'); + WriteLn; + Write('Please enter the new version: '); + Local_Input1(VerStr,20,TRUE); + IF (VerStr = '') THEN + WriteLn(^G^G^G'Aborted!') + ELSE + BEGIN + WriteLn; + WriteLn('You entered '+VerStr); + WriteLn; + IF PYNQ('Is this what you want? ') THEN + BEGIN + WriteLn; + Write('Updating "RENEGADE.DAT" file ... '); + Assign(GeneralFile,'RENEGADE.DAT'); + Reset(GeneralFile); + Seek(GeneralFile,0); + Read(GeneralFile,General); + General.Version := VerStr; + Seek(GeneralFile,0); + Write(GeneralFile,General); + Close(GeneralFile); + WriteLn('Done'); + WriteLn; + WriteLn('Update complete!'); + END; + END; + END; +END. diff --git a/SOURCE/UNUSED/RMAILWKS.PAS b/SOURCE/UNUSED/RMAILWKS.PAS new file mode 100644 index 0000000..b144159 --- /dev/null +++ b/SOURCE/UNUSED/RMAILWKS.PAS @@ -0,0 +1,953 @@ +PROGRAM Renemail; {eatus echomailius} + +{$A+,I-,E-,F+} + +(* {A+,B-,D-,E-,F+,G+,N-,R-,S-,V-,I-} *) + +uses crt, dos, timefunc; + +{$I RECORDS.PAS} + +type + fidorecord = record + FromUserName : string[35]; + ToUserName : string[35]; + Subject : string[71]; + DateTime : string[19]; + TimesRead : word; + DestNode : word; + OrigNode : word; + Cost : word; + OrigNet : word; + DestNet : word; + Filler : array[1..8] of char; + Replyto : word; + Attribute : word; + NextReply : word; + END; + +VAR + LastError :integer; + header : fidorecord; + dt : datetime; + MsgTFile : file; + hiwaterf : file of integer; + statusf : file of generalrecordtype; + statusr : generalrecordtype; + boardf : file of MessageAreaRecordType; + BoardR : MessageAreaRecordType; + MsgHdrF : file of mheaderrec; + MsgHdr : mheaderrec; + MsgTxtF : file; + uf : file of userrecordtype; + user : userrecordtype; + sf : file of useridxrec; + toi, fromi, subjecti, datetime : string; + i, j, lines, MsgNumber, highest, lowest, Board, TextSize, + msglength, msgpointer : integer; + c : char; + attribute : word; + ispm : boolean; + dirinfo : searchrec; + s, StartDir, nos, datapath, MsgPath, netmailpath : string [81]; + MsgTxt : string [255]; + buffer : array [1..32767] of char; + fcb : array [1..37] of char; +{$IFDEF MSDOS} + Regs : registers; +{$ENDIF} + x : byte; + +const + netmailonly : boolean = FALSE; + IsNetMail : boolean = FALSE; + fastpurge : boolean = TRUE; + process_netmail : boolean = TRUE; + purge_netmail : boolean = TRUE; + absolute_scan : boolean = FALSE; + ignore_1msg : boolean = TRUE; + +FUNCTION Hex(i : longint; j:byte) : String; +const + hc : array[0..15] of Char = '0123456789ABCDEF'; +VAR + one,two,three,four: Byte; +BEGIN + one := (i AND $000000FF); + two := (i AND $0000FF00) SHR 8; + three := (i AND $00FF0000) SHR 16; + four := (i AND $FF000000) SHR 24; + + Hex[0] := chr(j); { Length of String = 4 or 8} + IF (j = 4) THEN + BEGIN + Hex[1] := hc[two SHR 4]; + Hex[2] := hc[two AND $F]; + Hex[3] := hc[one SHR 4]; + Hex[4] := hc[one AND $F]; + END + ELSE + BEGIN + Hex[8] := hc[one AND $F]; + Hex[7] := hc[one SHR 4]; + Hex[6] := hc[two AND $F]; + Hex[5] := hc[two SHR 4]; + hex[4] := hc[three AND $F]; + hex[3] := hc[three SHR 4]; + hex[2] := hc[four AND $F]; + hex[1] := hc[four SHR 4]; + END; +END {Hex} ; + +FUNCTION Usename(b:byte; s:astr):string; +BEGIN + case b of + 1, + 2:s:='Anonymous'; + 3:s:='Abby'; + 4:s:='Problemed Person'; + END; + Usename:=s; +END; + +FUNCTION ExistDir(fn:string):boolean; +VAR dirinfo:searchrec; +BEGIN + WHILE (fn[Length(fn)] = '\') DO + Dec(fn[0]); + findfirst(fn,anyfile,dirinfo); + ExistDir:=(doserror=0) AND (dirinfo.attr AND $10=$10); +END; + +FUNCTION StrPas(Str: String): String; assembler; +asm + PUSH DS + CLD + LES DI,Str + MOV CX,0FFFFH + XOR AL,AL + REPNE SCASB + NOT CX + Dec CX + LDS SI,Str + LES DI,@Result + MOV AL,CL + STOSB + REP MOVSB + POP DS +END; + + +FUNCTION StripName(s:astr):astr; +VAR + n:integer; +BEGIN + n := Length(s); + WHILE (n > 0) AND (POS(s[n],':\/') = 0) DO + Dec(n); + Delete(s,1,n); + StripName := s; +END; + +FUNCTION AllCaps (const s : string) : string; +VAR + q : integer; +BEGIN + AllCaps [0] := s [0]; + FOR q := 1 TO Length (s) DO + AllCaps [q] := upcase (s [q]); +END; + +FUNCTION Caps (s : string) : string; +VAR + i : integer; +BEGIN + FOR i := 1 TO Length (s) DO + IF (s [i] in ['A'..'Z']) THEN + s [i] := chr (ord (s [i]) + 32); + + FOR i := 1 TO Length (s) DO + IF (NOT (s [i] in ['A'..'Z', 'a'..'z', chr (39) ]) ) THEN + IF (s [i + 1] in ['a'..'z']) THEN + s [i + 1] := upcase (s [i + 1]); + s [1] := upcase (s [1]); + Caps := s; +END; + +FUNCTION searchuser(Uname:string): word; +VAR + Current:integer; + Done:boolean; + IndexR:useridxrec; +BEGIN + + Reset(sf); + IF (IOResult > 0) THEN Exit; + + Uname := AllCaps(UName); + + Current := 0; + Done := FALSE; + + IF (FileSize(sf) > 0) THEN BEGIN + REPEAT + Seek(sf, Current); + Read(sf, IndexR); + IF (Uname < IndexR.Name) THEN BEGIN Current := IndexR.Left END + ELSE BEGIN + IF (Uname > IndexR.Name) THEN Current := IndexR.Right + ELSE Done := TRUE; + END; + UNTIL (Current = -1) or (Done); + END; + + Close(sf); + + IF (Done) AND NOT (IndexR.Deleted) THEN SearchUser := IndexR.Number + ELSE SearchUser := 0; + + LastError := IOResult; +END; + +FUNCTION StripColor (o : string) : string; +VAR i,j : byte; + s : string; +BEGIN + i := 0; + s := ''; + WHILE (i < Length (o) ) DO BEGIN + Inc (i); + case o [i] of + #128..#255:IF (mafilter in BoardR.maflags) THEN + s := s + chr(ord(o[i]) AND 128) + ELSE + s := s + o[i]; + '^' : IF o [i + 1] in [#0..#9, '0'..'9'] THEN + Inc (i) ELSE s := s + '^'; + '|' : IF (mafilter in BoardR.maflags) AND (o[i + 1] in ['0'..'9']) THEN + BEGIN + j:=0; + WHILE (o [i + 1] in ['0'..'9']) AND (i <= Length (o) ) + AND (j<=2) DO BEGIN + Inc (i); + Inc (j) + END + END + ELSE + s := s + '|' + ELSE s := s + o [i]; + END; + END; + StripColor := s; +END; + +procedure aborterror(const s:string); +BEGIN + WriteLn(s); + halt(255); +END; + + FUNCTION Value (s : string) : longint; + VAR i : longint; + j : integer; + BEGIN + val (s, i, j); + IF (j <> 0) THEN BEGIN + s[0]:=chr(j-1); + val (s, i, j) + END; + Value := i; + IF (s = '') THEN Value := 0; + END; + + FUNCTION CStr (i : longint) : string; + VAR c : string [16]; + BEGIN + str (i, c); + CStr := c; + END; + + procedure getmsglst (const dir : string); + VAR hiwater : integer; + BEGIN + hiwater := 1; + IF NOT IsNetMail THEN BEGIN + Assign (hiwaterf, dir + 'HI_WATER.MRK'); + Reset (hiwaterf); + IF IOResult <> 0 THEN BEGIN + ReWrite (hiwaterf); + Write (hiwaterf, hiwater); + IF IOResult <> 0 THEN aborterror('error creating ' + dir + '\HI_WATER.MRK'); + END + ELSE BEGIN + Read (hiwaterf, hiwater); + i := IOResult; + findfirst (dir + CStr (hiwater) + '.MSG', 0, dirinfo); + IF doserror <> 0 THEN hiwater := 1; + END; + Close (hiwaterf); + END; + findfirst (dir + '*.MSG', 0, dirinfo); + highest := 1; + lowest := 32767; + WHILE doserror = 0 DO BEGIN + i := Value (dirinfo.name); + IF i < lowest THEN lowest := i; + IF i > highest THEN highest := i; + findnext (dirinfo); + END; + + IF hiwater <= highest THEN BEGIN + IF hiwater > 1 THEN lowest := hiwater + 1; + END; + + IF (ignore_1msg) THEN BEGIN + IF (lowest = 1) AND (highest > 1) THEN lowest := 2; + END; + LastError := IOResult; + END; + + procedure getpaths; + + procedure badpath(const s:string); + BEGIN + WriteLn('The ',s,' path is bad. Please correct it.'); + halt; + END; + + BEGIN + s := fsearch ('RENEGADE.DAT', getenv ('PATH') ); + Assign (statusf, s); + Reset (statusf); + IF (IOResult <> 0) or (s = '') THEN BEGIN + WriteLn ('RENEGADE.DAT must be in the current directory or the path.'); + halt (1); + END; + Read (statusf, statusr); + datapath := statusr.datapath; + IF NOT (ExistDir(datapath)) THEN badpath('DATA'); + netmailpath := statusr.netmailpath; + IF NOT (ExistDir(netmailpath)) THEN badpath('NETMAIL'); + MsgPath := statusr.MsgPath; + IF NOT (ExistDir(MsgPath)) THEN badpath('MSGS'); + Close (statusf); + IF IOResult <> 0 THEN + aborterror('error reading From RENEGADE.DAT'); + END; + + procedure updatehiwater (const dir:string; x:integer); + BEGIN + Assign (hiwaterf, dir + 'HI_WATER.MRK'); + ReWrite (hiwaterf); + Write (hiwaterf, x); + Close (hiwaterf); + i := IOResult; + END; + + procedure PurgeDir (const dir : string); + VAR purged : boolean; + BEGIN +{$IFDEF MSDOS} + IF fastpurge THEN BEGIN + ChDir (Copy (dir, 1, Length (dir) - 1) ); + IF (IOResult <> 0) THEN Exit; + IF (dir[2] = ':') THEN fcb [1] := chr(ord(dir[1]) - 64) + ELSE fcb [1] := chr(ord(StartDir[1]) - 64); + Regs.ds := seg (fcb); + Regs.dx := ofs (fcb); + Regs.ax := $1300; + msdos (Regs); + purged := (lo (Regs.ax) = 0); + END; +{$ENDIF} + IF NOT fastpurge THEN BEGIN + purged := TRUE; + findfirst (dir + '*.MSG', 0, dirinfo); + IF doserror <> 0 THEN BEGIN purged := FALSE END + ELSE BEGIN + WHILE doserror = 0 DO BEGIN + Assign (hiwaterf, dir + dirinfo.name); + erase (hiwaterf); + i := IOResult; + findnext (dirinfo); + END; + END; + END; + + IF NOT purged THEN Write ('No messages') + ELSE Write ('Purged'); + updatehiwater (dir, 1); + END; + + FUNCTION readmsg (x:integer ; const dir:string) : boolean; + VAR + q : boolean; + BEGIN + Assign (MsgTFile, dir + CStr (x) + '.MSG'); + Reset (MsgTFile, 1); + q := FALSE; + IF IOResult = 0 THEN BEGIN + + IF FileSize (MsgTFile) >= sizeof(header) THEN BEGIN + + BlockRead (MsgTFile, header, sizeof(header)); + s := StrPas(Header.FromUserName); + + IF ((header.attribute AND 16) = 16) THEN MsgHdr.fileattached := 1; + + MsgHdr.From.a1s := s; + MsgHdr.From.real := s; + MsgHdr.From.name := s; + + s := StrPas(Header.ToUserName); + + MsgHdr.MTO.a1s := s; + MsgHdr.MTO.real := s; + MsgHdr.MTO.name := s; + + MsgHdr.Subject := StrPas(Header.Subject); + + MsgHdr.OriginDate := StrPas(Header.DateTime); + + q := TRUE; + + IF (Header.Attribute AND 1 = 1) THEN MsgHdr.status := [Sent, Prvt] + ELSE MsgHdr.status := [Sent]; + + IF IsNetMail THEN BEGIN + q:=FALSE; + MsgHdr.From.node := Header.OrigNode; + MsgHdr.From.net := Header.OrigNet; + MsgHdr.MTO.node := Header.DestNode; + MsgHdr.MTO.net := Header.DestNet; + MsgHdr.From.Point := 0; + MsgHdr.MTO.Point := 0; + MsgHdr.From.Zone := 0; + MsgHdr.MTO.Zone := 0; + IF (Header.Attribute AND 256 = 0) AND + (Header.Attribute AND 4 = 0) THEN BEGIN + {look here FOR the netmail bug} + FOR i := 0 TO 19 DO BEGIN {21 is the uucp} + IF (MsgHdr.MTO.node = statusr.aka[i].node) AND + (MsgHdr.MTO.net = statusr.aka[i].net) THEN BEGIN + MsgHdr.MTO.Zone := statusr.aka[i].Zone; + MsgHdr.From.Zone := statusr.aka[i].Zone; + q := TRUE; + END; + END; + END; + END; + + IF q THEN BEGIN + IF (FileSize(MsgTFile) - 190) <= sizeof(buffer) THEN x := FileSize(MsgTFile) - 190 + ELSE x := sizeof(buffer); + BlockRead (MsgTFile, buffer, x, msglength); + END; + END; + + IF IsNetMail THEN + IF q AND purge_netmail THEN + BEGIN + Close (MsgTFile); + erase (MsgTFile) + END + ELSE IF q THEN + BEGIN + Header.Attribute := 260; + Seek (MsgTFile, 0); + BlockWrite (MsgTFile, header, sizeof(Header)); + END; + IF NOT (IsNetMail AND q AND purge_netmail) THEN Close(MsgTFile); + END; + readmsg := q; + i := IOResult; + END; + + procedure nextboard(Scanning:boolean); + VAR + GoodBoard:boolean; + BEGIN + IF Board = 0 THEN + BEGIN + i := IOResult; + Assign (boardf, datapath + 'MBASES.DAT'); + Reset (boardf); + i := IOResult; + IF i <> 0 THEN + BEGIN + WriteLn (i,':Problem accessing ' + datapath + 'MBASES.DAT. Please fix.'); + halt (1); + END; + END; + + IF Board = FileSize (boardf) THEN + BEGIN + Board := 32767; + Exit; + END; + + BoardR.matype := 0; BoardR.maflags := []; GoodBoard := FALSE; + WHILE NOT GoodBoard AND (Board < FileSize(boardf)) DO + BEGIN + Read (boardf, BoardR); + GoodBoard := (BoardR.matype = 1) AND + (NOT scanning or (absolute_scan or (mascanout in BoardR.maflags))); + Inc(Board); + END; + + IF (NOT GoodBoard) THEN + Board := 32767 + ELSE + IF scanning AND (mascanout in BoardR.maflags) THEN + BEGIN + Seek(boardf, Board - 1); + BoardR.maflags := BoardR.maflags - [mascanout]; + Write(boardf, BoardR); + END; + END; + + + procedure toss; + VAR i,j:word; + z:string [20]; + left, right, gap, oldgap : integer; + BEGIN + MsgHdr.From.anon := 0; + MsgHdr.From.usernum := 0; + MsgHdr.MTO.anon := 0; + MsgHdr.MTO.usernum := 0; + MsgHdr.replyto := 0; + MsgHdr.replies := 0; + MsgHdr.fileattached := 0; + + getdayofweek (MsgHdr.dayofweek); + MsgHdr.date := getpackdatetime; + getmsglst (BoardR.MsgPath); + IF IsNetMail AND (highest > 1) THEN lowest := 1; + + IF (lowest <= highest) AND ((highest > 1) or IsNetMail) THEN BEGIN + + Assign (MsgHdrF, MsgPath + BoardR.FileName + '.HDR'); + Reset (MsgHdrF); + IF (IOResult = 2) THEN ReWrite (MsgHdrF); + + Assign (MsgTxtF, MsgPath + BoardR.FileName + '.DAT'); + Reset (MsgTxtF, 1); + IF (IOResult = 2) THEN ReWrite (MsgTxtF, 1); + + Seek (MsgHdrF, FileSize (MsgHdrF) ); + Seek (MsgTxtF, FileSize (MsgTxtF) ); + + IF IOResult <> 0 THEN + aborterror('error accessing ' + MsgPath + BoardR.FileName + '.*'); + + FOR MsgNumber := lowest TO highest DO BEGIN + Write (MsgNumber : 4); + IF readmsg (MsgNumber, BoardR.MsgPath) THEN + with MsgHdr DO BEGIN + Inc (date); + pointer := FileSize (MsgTxtF) + 1; + TextSize := 0; + msgpointer := 0; + nos := ''; + WHILE (msgpointer < msglength) DO BEGIN + MsgTxt := nos; + REPEAT + Inc (msgpointer); + c := buffer [msgpointer]; + IF NOT (c in [#0, #10, #13, #141]) THEN + IF (Length(MsgTxt) < 255) THEN {MsgTxt := MsgTxt + c;} + BEGIN + Inc(MsgTxt[0]); + MsgTxt[Length(MsgTxt)] := c; + END; + UNTIL ( + (nos = #13) or (c in [#13,#141]) + or + ((Length(MsgTxt) > 79) AND (POS(#27, MsgTxt) = 0)) + or + (Length(MsgTxt) = 254) + or + (msgpointer >= msglength) + ); + + IF Length (MsgTxt) = 254 THEN + MsgTxt := MsgTxt + #29; + + i := POS('INTL ', MsgTxt); + IF (i > 0) THEN + BEGIN + Inc(i, 6); + FOR j := 1 TO 8 DO + BEGIN + z := ''; + WHILE (MsgTxt[i] in ['0'..'9']) AND (i <= Length(MsgTxt)) DO + BEGIN + z := z + MsgTxt[i]; + Inc(i); + END; + case j of + 1:MsgHdr.MTO.Zone := Value(z); + 2:MsgHdr.MTO.net := Value(z); + 3:MsgHdr.MTO.node := Value(z); + 4:MsgHdr.MTO.Point := Value(z); + 5:MsgHdr.From.Zone := Value(z); + 6:MsgHdr.From.net := Value(z); + 7:MsgHdr.From.node := Value(z); + 8:MsgHdr.From.Point := Value(z); + END; + IF (j = 3) AND (MsgTxt[i] <> '.') THEN + Inc(j); + IF (j = 7) AND (MsgTxt[i] <> '.') THEN + break; + Inc(i); + END; + END; + + IF (Length (MsgTxt) > 79) THEN + BEGIN + i := Length (MsgTxt); + WHILE (MsgTxt [i] = ' ') AND (i > 1) DO + Dec (i); + WHILE (i > 65) AND (MsgTxt [i] <> ' ') DO + Dec (i); + + nos[0] := chr(Length(MsgTxt) - i); + Move(MsgTxt[i + 1], nos[1], Length(MsgTxt) - i); + MsgTxt[0] := chr(i - 1); + + END + ELSE + nos := ''; + + IF ( (MsgTxt [1] = #1) AND (maskludge in BoardR.maflags) ) or + ( (POS ('SEEN-BY', MsgTxt) > 0) AND (masseenby in BoardR.maflags) ) or + ( (POS ('* Origin:', MsgTxt) > 0) AND (masorigin in BoardR.maflags) ) THEN + MsgTxt := '' + ELSE BEGIN + Inc (MsgHdr.TextSize, Length (MsgTxt) + 1); + BlockWrite (MsgTxtF, MsgTxt, Length (MsgTxt) + 1); + END; + END; + IF IsNetMail THEN BEGIN + MsgHdr.status := MsgHdr.status + [netmail]; + MsgHdr.MTO.usernum := SearchUser(MsgHdr.MTO.a1s); + IF MsgHdr.MTO.usernum = 0 THEN + MsgHdr.MTO.usernum := 1; + Seek (uf, MsgHdr.MTO.usernum); + Read (uf, user); + Inc (user.waiting); + Seek (uf, MsgHdr.MTO.usernum); + Write (uf, user); + END; + Write (MsgHdrF, MsgHdr); + END; + IF MsgNumber < highest THEN Write (#8#8#8#8); + i := IOResult; + END; + Close (MsgHdrF); + Close (MsgTxtF); + IF NOT IsNetMail THEN updatehiwater (BoardR.MsgPath, highest); + END ELSE Write ('No messages'); + LastError := IOResult; + END; + + procedure scan; + VAR rgmsgnumber : integer; + highestwritten : integer; + AnsiOn, + scanned : boolean; + BEGIN + AnsiOn := FALSE; + scanned := FALSE; + getmsglst (BoardR.MsgPath); + MsgNumber := highest; + IF (NOT ExistDir(BoardR.MsgPath)) THEN + BEGIN + WriteLn('WARNING: Cannot access ', BoardR.MsgPath); + Exit; + END; + + Assign (MsgHdrF, MsgPath + BoardR.FileName + '.HDR'); + Reset (MsgHdrF); + IF IOResult <> 0 THEN Exit; + + Assign (MsgTxtF, MsgPath + BoardR.FileName + '.DAT'); + Reset (MsgTxtF, 1); + IF IOResult <> 0 THEN BEGIN Close (MsgHdrF); Exit; END; + + FOR rgmsgnumber := 1 TO FileSize (MsgHdrF) DO BEGIN + Seek (MsgHdrF, rgmsgnumber - 1); + Read (MsgHdrF, MsgHdr); + IF NOT (Sent in MsgHdr.status) AND (IOResult = 0) AND + NOT (MDeleted in MsgHdr.status) AND + NOT (IsNetMail AND NOT (netmail in MsgHdr.status)) AND + NOT (unvalidated in MsgHdr.status) THEN BEGIN + scanned := TRUE; + Inc (MsgNumber); + Assign (MsgTFile, BoardR.MsgPath + CStr (MsgNumber) + '.MSG'); + ReWrite (MsgTFile, 1); + Write (rgmsgnumber : 5); + + MsgHdr.status := MsgHdr.status + [Sent]; + + IF IsNetMail THEN + MsgHdr.status := MsgHdr.status + [MDeleted]; + + Seek (MsgHdrF, rgmsgnumber - 1); + Write (MsgHdrF, MsgHdr); + + IF (marealname in BoardR.maflags) THEN + s := Caps (MsgHdr.From.real) + ELSE + s := Caps (MsgHdr.From.a1s); + + s := usename(MsgHdr.From.anon, s); + + FillChar(Header,sizeof(Header),#0); + + Move(s[1],Header.FromUserName[0],Length(s)); + + IF (marealname in BoardR.maflags) THEN + s := Caps (MsgHdr.MTO.real) + ELSE + s := Caps (MsgHdr.MTO.a1s); + + s := usename(MsgHdr.MTO.anon, s); + + Move(s[1],Header.ToUserName[0],Length(s)); + + MsgHdr.Subject := StripColor(MsgHdr.Subject); + + IF (NOT IsNetMail) AND (MsgHdr.fileattached > 0) THEN + MsgHdr.Subject := StripName(MsgHdr.Subject); + + Move(MsgHdr.Subject[1],Header.Subject[0],Length(MsgHdr.Subject)); + + packtodate (dt, MsgHdr.date); + with dt DO BEGIN + s := CStr (day); + IF Length (s) < 2 THEN s := '0' + s; + s := s + ' ' + Copy ('JanFebMarAprMayJunJulAugSepOctNovDec', (month - 1) * 3 + 1, 3) + ' '; + s := s + Copy (CStr (year), 3, 2) + ' '; + nos := CStr (hour); + IF Length (nos) < 2 THEN nos := '0' + nos; + s := s + nos + ':'; + nos := CStr (min); + IF Length (nos) < 2 THEN nos := '0' + nos; + s := s + nos + ':'; + nos := CStr (sec); + END; + IF Length (nos) < 2 THEN nos := '0' + nos; + s := s + nos; + + Move(s[1],Header.DateTime[0],Length(s)); + + IF IsNetMail THEN BEGIN + Header.OrigNet := MsgHdr.From.net; + Header.OrigNode := MsgHdr.From.node; + Header.DestNet := MsgHdr.MTO.net; + Header.DestNode := MsgHdr.MTO.node; + END ELSE BEGIN + Header.OrigNet := statusr.aka [BoardR.aka].net; + Header.OrigNode := statusr.aka [BoardR.aka].node; + Header.DestNet := 0; + Header.DestNode := 0; + END; + + IF IsNetMail THEN + Header.Attribute := word(MsgHdr.netattribute) + {word(statusr.netattribute)} + ELSE + IF (prvt in MsgHdr.status) THEN + Header.Attribute := 257 + ELSE + Header.Attribute := 256; + + IF (MsgHdr.fileattached > 0) THEN + Header.Attribute := Header.Attribute + 16; + + BlockWrite (MsgTFile, header, sizeof(Header)); + Seek (MsgTxtF, MsgHdr.pointer - 1); + + IF IsNetMail THEN BEGIN + s := 'INTL ' + CStr (MsgHdr.MTO.Zone) + ':' + CStr (MsgHdr.MTO.net) + '/' + CStr (MsgHdr.MTO.node); + s := s + ' ' + CStr (MsgHdr.From.Zone) + ':' + CStr (MsgHdr.From.net) + '/' + CStr (MsgHdr.From.node); + s := s + #13; + BlockWrite (MsgTFile, s [1], Length (s) ); + IF MsgHdr.MTO.Point > 0 THEN + BEGIN + s := #1'TOPT ' + CStr(MsgHdr.MTO.Point); + BlockWrite (MsgTFile, s [1], Length (s) ); + END; + IF MsgHdr.From.Point > 0 THEN + BEGIN + s := #1'FMPT ' + CStr(MsgHdr.From.Point); + BlockWrite (MsgTFile, s [1], Length (s) ); + END; + + s := ^A'MSGID: ' + CStr (MsgHdr.From.Zone) + ':' + CStr (MsgHdr.From.net) + + '/' + CStr (MsgHdr.From.node) + ' ' + Hex(Random($FFFF), 4) + Hex(Random($FFFF),4); + + IF MsgHdr.From.Point > 0 THEN s := s + '.' + CStr (MsgHdr.From.Point); + s := s + {' '} #13; { *** } + BlockWrite (MsgTFile, s [1], Length (s) ); +{$IFDEF MSDOS} + s := #1'PID: Renemail ' + ver + #13; +{$ELSE} + s := #1'PID: Renemail/2 ' + ver + #13; +{$ENDIF} + BlockWrite (MsgTFile, s [1], Length (s) ); + END; + + j := 0; + IF MsgHdr.TextSize > 0 THEN + REPEAT + BlockRead (MsgTxtF, s [0], 1); + BlockRead (MsgTxtF, s [1], ord (s [0]) ); + Inc (j, Length (s) + 1); + WHILE POS(#0,s) > 0 DO + Delete(s,POS(#0,s),1); + IF s [Length (s) ] = #29 THEN + Dec(s[0]) + ELSE + IF POS (#27, s) = 0 THEN + s := StripColor(s) + ELSE + AnsiOn := TRUE; + s := s + #13; + BlockWrite (MsgTFile, s [1], Length (s) ); + UNTIL (j >= MsgHdr.TextSize); + Close (MsgTFile); + Write (#8#8#8#8#8); + END; + highestwritten := MsgNumber; + END; + i := IOResult; + IF NOT IsNetMail THEN updatehiwater (BoardR.MsgPath, highestwritten); + Close (MsgHdrF); + Close (MsgTxtF); + IF NOT scanned THEN Write ('No messages'); + LastError := IOResult; + END; + +BEGIN + Randomize; + GetDir (0, StartDir); + FOR x := 1 TO 37 DO + fcb [x] := ' '; + fcb [1] := chr (ord (StartDir [1]) - 64); + fcb [2] := '*'; + fcb [10] := 'M'; + fcb [11] := 'S'; + fcb [12] := 'G'; + FileMode := 66; + MsgHdr.From.Zone := 0; + MsgHdr.From.Point := 0; + ClrScr; + TextColor (3); +{$IFDEF MSDOS} + WriteLn ('Renegade Echomail Interface DOS v' + ver); +{$ELSE} + WriteLn ('Renegade Echomail Interface OS/2 v' + ver); +{$ENDIF} + WriteLn ('Copyright 2004-2006'); + WriteLn; + TextColor (10); + + IF ParamStr (1) = '' THEN + BEGIN + WriteLn (' Commands: -T Toss incoming messages'); + WriteLn (' -S Scan outbound messages'); + WriteLn (' -P Purge echomail dirs'); + WriteLn (' Options: -A Absolute scan'); +{$IFDEF MSDOS} + WriteLn (' -F No fast purge'); +{$ENDIF} + WriteLn (' -N No Netmail'); + WriteLn (' -D Do not delete Netmail'); +{$IFDEF MSDOS} + WriteLn (' -B Bios video output'); +{$ENDIF} + WriteLn (' -O Only Netmail'); + WriteLn (' -I Import 1.MSG'); + WriteLn; + halt; + END; + FOR i := 1 TO paramcount DO + IF POS ('-N', AllCaps (ParamStr (i) ) ) > 0 THEN + process_netmail := FALSE + ELSE + IF POS ('-F', AllCaps (ParamStr (i) ) ) > 0 THEN + fastpurge := FALSE + ELSE + IF POS ('-D', AllCaps (ParamStr (i) ) ) > 0 THEN + purge_netmail := FALSE + ELSE +{$IFDEF MSDOS} + IF POS ('-B', AllCaps (ParamStr (i) ) ) > 0 THEN + directvideo := FALSE + ELSE +{$ENDIF} + IF POS ('-O', AllCaps (ParamStr (i) ) ) > 0 THEN + netmailonly := TRUE + ELSE + IF POS ('-A', AllCaps (ParamStr (i) ) ) > 0 THEN + absolute_scan := TRUE + ELSE + IF POS ('-I', AllCaps (ParamStr (i) ) ) > 0 THEN + ignore_1msg := FALSE; + (* 09-16-96 Changed to allow processing of 1.msg + *) + Board := 0; + getpaths; + + IF process_netmail THEN + BEGIN + BoardR.MsgPath := netmailpath; + BoardR.FileName := 'EMAIL'; + BoardR.maflags := [maskludge]; + Assign (uf, datapath + 'users.dat'); + Reset (uf); + IF IOResult <> 0 THEN + aborterror('Cannot find users.dat in your DATA directory'); + Assign (sf, datapath + 'users.idx'); + Reset (sf); + IF IOResult <> 0 THEN + aborterror('Cannot find users.idx in your DATA directory'); + + IsNetMail := TRUE; + TextColor (3); + Write ('Processing: '); + TextColor (14); + Write (' NETMAIL - '); + TextColor (11); + IF POS ('-T', AllCaps (ParamStr (1) ) ) > 0 THEN + toss; + IF POS ('-S', AllCaps (ParamStr (1) ) ) > 0 THEN + scan; + Close (uf); + Close (sf); + LastError := IOResult; + WriteLn; + IsNetMail := FALSE; + END; + + IF netmailonly THEN halt; + + WHILE Board <> 32767 DO BEGIN + nextboard(POS('-S', AllCaps(ParamStr(1))) > 0); + IF Board <> 32767 THEN BEGIN + TextColor (3); + Write ('Processing: '); + TextColor (14); + Write (BoardR.FileName : 8, ' - '); + TextColor (11); + IF POS ('-P', AllCaps (ParamStr (1) ) ) > 0 THEN PurgeDir (BoardR.MsgPath) + ELSE IF POS ('-T', AllCaps (ParamStr (1) ) ) > 0 THEN toss + ELSE IF POS ('-S', AllCaps (ParamStr (1) ) ) > 0 THEN scan; + WriteLn; + END ELSE Close (boardf) + END; + ChDir (StartDir); +END. diff --git a/SOURCE/UNUSED/RMCHANGE.DOC b/SOURCE/UNUSED/RMCHANGE.DOC new file mode 100644 index 0000000..b30c62b --- /dev/null +++ b/SOURCE/UNUSED/RMCHANGE.DOC @@ -0,0 +1,3 @@ +1. Added Caps to tossed From/MTO Names. +2. Bumped the maximum messages that can be handled per based from + 32767 to 65535. \ No newline at end of file diff --git a/SOURCE/UNUSED/RMUPDATE.DOC b/SOURCE/UNUSED/RMUPDATE.DOC new file mode 100644 index 0000000..8a8f4b0 --- /dev/null +++ b/SOURCE/UNUSED/RMUPDATE.DOC @@ -0,0 +1,13 @@ +Renemail Echomail Interface update log for Renegade v1.10 + +10/04/09 + +1. Changed the Style of the code for easier updating. + +2. Removed numerous unused variables thru-out the code. + +3. Replaced all instances of "i := IOResult" with "LastError := IOResult". + +4. Added/Replaced "Include/Excludes" where appropriate tru-out the code. + +5. Replaced the Scan - Fido Message Date/Time calculation routine. \ No newline at end of file diff --git a/SOURCE/UNUSED/SCRIPT.TPU b/SOURCE/UNUSED/SCRIPT.TPU new file mode 100644 index 0000000000000000000000000000000000000000..d4bfb67461a87738bf4614cc0ee71c87096ac5b2 GIT binary patch literal 11248 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SORTING.PAS b/SOURCE/UNUSED/SORTING.PAS new file mode 100644 index 0000000..e7c3313 --- /dev/null +++ b/SOURCE/UNUSED/SORTING.PAS @@ -0,0 +1,157 @@ +unit Sorting; +{=============================================} +{ James L. Allison } +{ 1703 Neptune Lane } +{ Houston, Texas 77062 } +{ Dec 22, 1988 } +{=============================================} + +{ Please feel free to use any part of this in any of your programs.} + +interface + uses TypeSpec; +type + Item=TypeSpec.Character; {This defines the objects being sorted.} + List=array [0..0] of Item; {This is an array of objects to be sorted.} + + L_Less_Than_R = function(L,R:Item):boolean; +{ This is a user defined function that determines the + order of the sort. It may be as simple or complex as + necessary to give the desired order. In particular it + can use any field in a record as the sort key, or use + more than one key. } + + { Make sure that range check is off before you use any of these. } + +procedure QuickSort (var X:List; Less_Than:L_Less_Than_R; N:integer); +{ A very fast sort, uses recursion. + May have stack problems on a large sort. } + +procedure ShellSort (var X:List; Less_Than:L_Less_Than_R; N:integer); +{ Almost as fast as QuickSort, but without recursion. + The work horse of fast sorting methods. } + +procedure LoopSort (var X:List; Less_Than:L_Less_Than_R; N:integer); +{ No reason to use this. Included only for comparison. } + +procedure BubbleSort (var X:List; Less_Than:L_Less_Than_R; N:integer); +{ The only time to use this is when the array is almost in order, with + only a couple of items out of place. It may be useful to modify this + to make the sweep from the other end of the array. BubbleSort is + a special purpose method. Stick to QuickSort or ShellSort.} + +(*---------------------------------------------------------------------*) +implementation +(*---------------------------------------------------------------------*) +procedure Swap(var X:List;I,J:integer); +var + Temp:Item; + begin + Temp:=X[I]; + X[I]:=X[J]; + X[J]:=Temp; + end; +(*---------------------------------------------------------------------*) +procedure Qsort(var X:List;Less_Than:L_Less_Than_R;Left,Right:integer); +label + Again; +var + Pivot:Item; + P,Q:integer; + + begin + P:=Left; + Q:=Right; + Pivot:=X [(Left+Right) div 2]; + + while P<=Q do + begin + while Less_Than(X[P],Pivot) do inc(P); + while Less_Than(Pivot,X[Q]) do dec(Q); + if P>Q then goto Again; + Swap(X,P,Q); + inc(P);dec(Q); + end; + + Again: + if Left0 do + begin + I:=Gap; + + while I=0) and (Less_Than(X[J+Gap],X[J])) do + begin + Swap(X,J,J+Gap); + dec(J,Gap); + end; + + inc(I); + end; + + Gap:=Gap div 2; + end; + + end; + +(*---------------------------------------------------------------------*) +procedure LoopSort(var X:List;Less_Than:L_Less_Than_R;N:integer); +var + I,J:integer; + begin + for I:=0 to N-1 do + begin + for J:=I+1 to N-1 do + begin + if Less_Than(X[J],X[I]) + then + begin + Swap(X,I,J); + end; + end; + end; + end; + +(*---------------------------------------------------------------------*) +procedure BubbleSort(var X:List;Less_Than:L_Less_Than_R;N:integer); +var + J:integer; + Finished:boolean; + begin + repeat + Finished:=true; + for J:=0 to N-2 do + if Less_Than(X[J+1],X[J]) then + begin + Finished:=false; + Swap(X,J,J+1); + end; + dec(N); + until Finished; + end; + + begin + end. + + + \ No newline at end of file diff --git a/SOURCE/UNUSED/SPAWNO.TPU b/SOURCE/UNUSED/SPAWNO.TPU new file mode 100644 index 0000000000000000000000000000000000000000..693adbff80631628c1cf154e1f53c5de244708c4 GIT binary patch literal 8096 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 P0=s4Kd%NhzP|*GVq;udh literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/STATS.TPU b/SOURCE/UNUSED/STATS.TPU new file mode 100644 index 0000000000000000000000000000000000000000..466c1adb84159965d3ef6c646432aa5145c470da GIT binary patch literal 14560 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 PoCeJElgWR*l%M|v;LE)z literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSCHAT.PAS b/SOURCE/UNUSED/SYSCHAT.PAS new file mode 100644 index 0000000..6f1b93d --- /dev/null +++ b/SOURCE/UNUSED/SYSCHAT.PAS @@ -0,0 +1,664 @@ +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT SysChat; + +INTERFACE + +USES + Common; + +PROCEDURE RequestSysOpChat(CONST MenuOption: STr50); +PROCEDURE ChatFileLog(b: Boolean); +PROCEDURE Chat; + +IMPLEMENTATION + +USES + Crt, + Dos, + Email, + Event, + TimeFunc; + +VAR + UserChatArray: ARRAY [1..10] OF AStr; + SysOpChatArray: ARRAY [1..10] OF AStr; + UserXPos, + UserYPos, + SysOpXPos, + SysOpYPos: Byte; + +PROCEDURE RequestSysOpChat(CONST MenuOption: Str50); +VAR + User: UserRecordType; + MHeader: MHeaderRec; + Reason: AStr; + Cmd: Char; + Counter: Byte; + UNum, + Counter1: Integer; + Chatted: Boolean; +BEGIN + IF (ChatAttempts < General.MaxChat) OR (CoSysOp) THEN + BEGIN + NL; + IF (Pos(';',MenuOption) <> 0) THEN + Print(Copy(MenuOption,(Pos(';',MenuOption) + 1),Length(MenuOption))) + ELSE + lRGLngStr(37,FALSE); { FString.ChatReason; } + Chatted := FALSE; + Prt(': '); + MPL(60); + InputL(Reason,60); + IF (Reason <> '') THEN + BEGIN + Inc(ChatAttempts); + SysOpLog('^4Chat attempt:'); + SL1(Reason); + IF (NOT SysOpAvailable) AND AACS(General.OverRideChat) THEN + PrintF('CHATOVR'); + IF (SysOpAvailable) OR (AACS(General.OverRideChat) AND PYNQ(^M^J'SysOp is not available. Override? ',0,FALSE)) THEN + BEGIN + lStatus_Screen(100,'Press [SPACE] to chat or [ENTER] for silence.',FALSE,Reason); + { Print(FString.ChatCall1); } + lRGLngStr(14,FALSE); + Counter := 0; + Abort := FALSE; + NL; + REPEAT + Inc(Counter); + WKey; + IF (OutCom) THEN + Com_Send(^G); + { Prompt(FString.ChatCall2); } + lRGLngStr(15,FALSE); + IF (OutCom) THEN + Com_Send(^G); + IF (ShutUpChatCall) THEN + Delay(600) + ELSE + BEGIN + FOR Counter1 := 300 DOWNTO 2 DO + BEGIN + Delay(1); + Sound(Counter1 * 10); + END; + FOR Counter1 := 2 TO 300 DO + BEGIN + Delay(1); + Sound(Counter1 * 10); + END; + END; + NoSound; + IF (KeyPressed) THEN + BEGIN + Cmd := ReadKey; + CASE Cmd OF + #0 : BEGIN + Cmd := ReadKey; + SKey1(Cmd); + END; + #32 : BEGIN + Chatted := TRUE; + ChatAttempts := 0; + Chat; + END; + ^M : ShutUpChatCall := TRUE; + END; + END; + UNTIL (Counter = 9) OR (Chatted) OR (Abort) OR (HangUp); + NL; + END; + lStatus_Screen(100,'Chat Request: '+Reason,FALSE,Reason); + IF (Chatted) THEN + ChatReason := '' + ELSE + BEGIN + ChatReason := Reason; + PrintF('NOSYSOP'); + UNum := StrToInt(MenuOption); + IF (UNum > 0) THEN + BEGIN + InResponseTo := #1'Tried chatting'; + LoadURec(User,UNum); + NL; + IF PYNQ('Send mail to '+Caps(User.Name)+'? ',0,FALSE) THEN + BEGIN + MHeader.Status := []; + SEmail(UNum,MHeader); + END; + END; + END; + TLeft; + END; + END + ELSE + BEGIN + PrintF('GOAWAY'); + UNum := StrToInt(MenuOption); + IF (UNum > 0) THEN + BEGIN + InResponseTo := 'Tried chatting (more than '+IntToStr(General.MaxChat)+' times!)'; + SysOpLog(InResponseTo); + MHeader.Status := []; + SEmail(UNum,MHeader); + END; + END; +END; + +PROCEDURE ChatFileLog(b: Boolean); +VAR + s: AStr; +BEGIN + s := 'Chat'; + IF (ChatSeparate IN ThisUser.SFlags) THEN + s := s + IntToStr(UserNum); + s := General.LogsPath+s+'.LOG'; + IF (NOT b) THEN + BEGIN + IF (CFO) THEN + BEGIN + lStatus_Screen(100,'Chat recorded to '+s,FALSE,s); + CFO := FALSE; + IF (TextRec(ChatFile).Mode <> FMClosed) THEN + Close(ChatFile); + END; + END + ELSE + BEGIN + CFO := TRUE; + IF (TextRec(ChatFile).Mode = FMOutPut) THEN + Close(ChatFile); + Assign(ChatFile,s); + Append(ChatFile); + IF (IOResult = 2) THEN + ReWrite(ChatFile); + IF (IOResult <> 0) THEN + SysOpLog('Cannot open chat log file: '+s); + lStatus_Screen(100,'Recording chat to '+s,FALSE,s); + WriteLn(ChatFile); + WriteLn(ChatFile); + WriteLn(ChatFile,Dat); + WriteLn(ChatFile); + Writeln(ChatFile,'Recorded with user: '+Caps(ThisUser.Name)); + WriteLn(ChatFile); + WriteLn(ChatFile,'Chat reason: '+AOnOff(ChatReason = '','None',ChatReason)); + WriteLn(ChatFile); + WriteLn(ChatFile); + WriteLn(ChatFile,'------------------------------------'); + WriteLn(ChatFile); + END; +END; + +PROCEDURE ANSIG(X,Y: Byte); +BEGIN + IF (ComPortSpeed > 0) THEN + IF (OkAvatar) THEN + SerialOut(^V^H+Chr(Y)+Chr(X)) + ELSE + SerialOut(#27+'['+IntToStr(Y)+';'+IntToStr(X)+'H'); + IF (WantOut) THEN + GoToXY(X,Y); +END; + +PROCEDURE SysOpChatWindow; +BEGIN + CLS; + + ANSIG(1,1); + + Prompt('͸'); + + ANSIG(1,12); + + Prompt(';'); + + ANSIG(1,13); + + Prompt('͸'); + + ANSIG(1,24); + + Prompt(';'); + + ANSIG(37,25); + + Prompt('Help'); + +END; + +PROCEDURE InLi1(VAR S: STRING); +VAR + C, + C1: Char; + Counter, + Counter1, + CPos: Byte; +BEGIN + CPos := 1; + S := ''; + IF (LastLineStr <> '') THEN + BEGIN + Prompt(LastLineStr); + S := LastLineStr; + LastLineStr := ''; + CPos := (Length(S) + 1); + END; + + REPEAT + C := Char(GetKey); + CheckHangUp; + CASE Ord(C) OF + 32..255 : + IF (CPos < 79) THEN + BEGIN + S[CPos] := C; + Inc(CPos); + OutKey(C); + IF (Trapping) THEN + Write(TrapFile,C); + END; + 16 : IF (OkANSI OR OkAvatar) THEN + BEGIN + C1 := Char(GetKey); + UserColor(Ord(C1) - 48); + END; + 27 : IF (CPos < 79) THEN + BEGIN + S[CPos] := C; + Inc(CPos); + OutKey(C); + IF (Trapping) THEN + Write(TrapFile,C); + END; + 8 : IF (CPos > 1) THEN + BEGIN + Dec(CPos); + BackSpace; + END; + 24 : BEGIN + FOR Counter := 1 TO (CPos - 1) DO + BackSpace; + CPos := 1; + END; + 7 : IF (OutCom) THEN + Com_Send(^G); + 23 : IF (CPos > 1) THEN + REPEAT + Dec(CPos); + BackSpace; + UNTIL (CPos = 1) OR (S[CPos] = ' '); + 9 : BEGIN + Counter := (5 - (CPos MOD 5)); + IF ((CPos + Counter) < 79) THEN + FOR Counter1 := 1 TO Counter DO + BEGIN + S[CPos] := ' '; + Inc(CPos); + Prompt(' '); + END; + END; + END; + UNTIL ((C = ^M) OR (CPos = 79) OR (HangUp) OR (NOT InChat)); + + IF (NOT InChat) THEN + BEGIN + C := #13; + InChat := FALSE; + END; + + S[0] := Chr(CPos - 1); + + IF (C <> ^M) THEN + BEGIN + Counter := (CPos - 1); + WHILE (Counter > 0) AND (S[Counter] <> ' ') AND (S[Counter] <> ^H) DO + Dec(Counter); + IF (Counter > (CPos DIV 2)) AND (Counter <> (CPos - 1)) THEN + BEGIN + LastLineStr := Copy(S,(Counter + 1),(CPos - Counter)); + FOR Counter1 := (CPos - 2) DOWNTO Counter DO + Prompt(^H); + FOR Counter1 := (CPos - 2) DOWNTO Counter DO + Prompt(' '); + S[0] := Chr(Counter - 1); + END; + END; + NL; +END; + +PROCEDURE Chat; +VAR + S, + SysOpStr, + UserStr, + SysOpLastLineStr, + UserLastLineStr: AStr; (* Was S *) + + C: Char; + Counter, + Counter1, + SysOpCPos, + UserCPos: Byte; + + ChatTime: LongInt; + SaveEcho, + SavePrintingFile, + SaveMCIAllowed: Boolean; +BEGIN + UserColor(1); + SaveMCIAllowed := MCIAllowed; + MCIAllowed := TRUE; + ChatTime := GetPackDateTime; + DOSANSIOn := FALSE; + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + SaveNAvail := (NAvail IN Noder.Status); + Exclude(Noder.Status,NAvail); + SaveNode(ThisNode); + END; + SavePrintingFile := PrintingFile; + InChat := TRUE; + ChatCall := FALSE; + SaveEcho := Echo; + Echo := TRUE; + IF (General.AutoChatOpen) THEN + ChatFileLog(TRUE) + ELSE IF (ChatAuto IN ThisUser.SFlags) THEN + ChatFileLog(TRUE); + NL; + Exclude(ThisUser.Flags,Alert); + PrintF('CHATINIT'); + IF (NoFile) THEN + (* + Prompt('^5'+FString.EnGage); + *) + lRGLNGStr(2,FALSE); + + UserColor(General.SysOpColor); + WColor := TRUE; + + IF (ChatReason <> '') THEN + BEGIN + lStatus_Screen(100,ChatReason,FALSE,S); + ChatReason := ''; + END; + + SysOpLastLineStr := ''; + UserLastLineStr := ''; + SysOpXPos := 2; + SysOpYPos := 2; + UserXPos := 2; + UserYPos := 14; + + SysOpStr := ''; + UserStr := ''; + SysOpCPos := 1; + UserCPos := 1; + + SysOpChatWindow; + + ANSIG(SysOpXPos,SysOpYPos); + + REPEAT + + C := Char(GetKey); + + CheckHangUp; + + CASE Ord(C) OF + 32..255 : IF (WColor) THEN + BEGIN + IF (SysOpCPos < 79) THEN + BEGIN + SysOpStr[SysOpCPos] := C; + Inc(SysOpCPos); + ANSIG(SysOpXPos,SysOpYPos); + OutKey(C); + Inc(SysOpXPos); + IF (Trapping) THEN + Write(TrapFile,C); + END + ELSE + BEGIN + SysOpStr[0] := Chr(SysOpCPos - 1); + + Counter := (SysOpCPos - 1); + WHILE (Counter > 0) AND (SysOpStr[Counter] <> ' ') AND (SysOpStr[Counter] <> ^H) DO + Dec(Counter); + IF (Counter > (SysOpCPos DIV 2)) AND (Counter <> (SysOpCPos - 1)) THEN + BEGIN + SysOpLastLineStr := Copy(SysOpStr,(Counter + 1),(SysOpCPos - Counter)); + FOR Counter1 := (SysOpCPos - 2) DOWNTO Counter DO + BEGIN + ANSIG(SysOpXPos,SysOpYPos); + Prompt(^H); + Dec(SysOpXPos); + END; + FOR Counter1 := (SysOpCPos - 2) DOWNTO Counter DO + BEGIN + ANSIG(SysOpXPos,SysOpYPos); + Prompt(' '); + Inc(SysOpXPos); + END; + SysOpStr[0] := Chr(Counter - 1); + END; + NL; + + Inc(SysOpYPos); + SysOpXPos := 2; + ANSIG(SysOpXPos,SysOpYPos); + + SysOpCPos := 1; + SysOpStr := ''; + IF (SysOpLastLineStr <> '') THEN + BEGIN + SysOpXPos := Length(SysOpLastLineStr) + 2; + Prompt(SysOpLastLineStr); + ANSIG(SysOpXPos,SysOpYPos); + SysOpStr := SysOpLastLineStr; + SysOpLastLineStr := ''; + SysOpCPos := (Length(SysOpStr) + 1); + END; + + END; + + END + ELSE + BEGIN + IF (UserCPos < 79) THEN + BEGIN + UserStr[UserCPos] := C; + Inc(UserCPos); + ANSIG(UserCPos,UserYPos); + OutKey(C); + Inc(UserXPos); + IF (Trapping) THEN + Write(TrapFile,C); + END + ELSE + BEGIN + UserStr[0] := Chr(UserCPos - 1); + + Counter := (UserCPos - 1); + WHILE (Counter > 0) AND (UserStr[Counter] <> ' ') AND (UserStr[Counter] <> ^H) DO + Dec(Counter); + IF (Counter > (UserCPos DIV 2)) AND (Counter <> (UserCPos - 1)) THEN + BEGIN + UserLastLineStr := Copy(UserStr,(Counter + 1),(UserCPos - Counter)); + FOR Counter1 := (UserCPos - 2) DOWNTO Counter DO + BEGIN + ANSIG(UserXPos,UserYPos); + Prompt(^H); + Dec(UserXPos); + END; + FOR Counter1 := (UserCPos - 2) DOWNTO Counter DO + BEGIN + ANSIG(UserXPos,UserYPos); + Prompt(' '); + Inc(UserXPos); + END; + UserStr[0] := Chr(Counter - 1); + END; + NL; + + Inc(UserYPos); + UserXPos := 2; + ANSIG(UserXPos,UserYPos); + + UserCPos := 1; + UserStr := ''; + IF (UserLastLineStr <> '') THEN + BEGIN + UserXPos := Length(UserLastLineStr) + 2; + Prompt(UserLastLineStr); + ANSIG(UserXPos,UserYPos); + UserStr := UserLastLineStr; + UserLastLineStr := ''; + UserCPos := (Length(UserStr) + 1); + END; + + END; + + END; + 8 : IF (WColor) THEN + BEGIN + IF (SysOpCPos > 1) THEN + BEGIN + ANSIG(SysOpXPos,SysOpYPos); + Dec(SysOpCPos); + Dec(SysOpXPos); + BackSpace; + END; + END + ELSE + BEGIN + IF (UserCPos > 1) THEN + BEGIN + ANSIG(UserXPos,UserYPos); + Dec(UserCPos); + Dec(UserXPos); + BackSpace; + END; + END; + 13 : IF (WColor) THEN + BEGIN + SysOpStr[0] := Chr(SysOpCPos - 1); + + END + ELSE + BEGIN + UserStr[0] := Chr(UserCPos - 1); + + END; + + END; + + + + + (* + InLi1(S); + + IF (S[1] = '/') THEN + S := AllCaps(S); + + IF (Copy(S,1,6) = '/TYPE ') AND (SysOp) THEN + BEGIN + S := Copy(S,7,(Length(S) - 6)); + IF (S <> '') THEN + BEGIN + PrintFile(S); + IF (NoFile) THEN + Print('*File not found*'); + END; + END + ELSE IF ((S = '/HELP') OR (S = '/?')) THEN + BEGIN + IF (SysOp) THEN + Print('^5/TYPE d:\path\filename.ext^3: Type a file'); + { + Print('^5/BYE^3: Hang up'); + Print('^5/CLS^3: Clear the screen'); + Print('^5/PAGE^3: Page the SysOp and User'); + Print('^5/Q^3: Exit chat mode'^M^J); + } + lRGLngStr(65,FALSE); + END + ELSE IF (S = '/CLS') THEN + CLS + ELSE IF (S = '/PAGE') THEN + BEGIN + FOR Counter := 650 TO 700 DO + BEGIN + Sound(Counter); + Delay(4); + NoSound; + END; + REPEAT + Dec(Counter); + Sound(Counter); + Delay(2); + NoSound; + UNTIL (Counter = 200); + Prompt(^G^G); + END + ELSE IF (S = '/BYE') THEN + BEGIN + Print('Hanging up ...'); + HangUp := TRUE; + END + ELSE IF (S = '/Q') THEN + BEGIN + InChat := FALSE; + Print('Chat Aborted ...'); + END; + IF (CFO) THEN + WriteLn(ChatFile,S); + *) + UNTIL ((NOT InChat) OR (HangUp)); + + PrintF('CHATEND'); + IF (NoFile) THEN + (* + Print('^5'+FString.lEndChat); + *) + lRGLngStr(3,FALSE); + IF (General.MultiNode) THEN + BEGIN + LoadNode(ThisNode); + IF (SaveNAvail) THEN + Include(Noder.Status,NAvail); + SaveNode(ThisNode); + END; + ChatTime := (GetPackDateTime - ChatTime); + IF (ChopTime = 0) THEN + Inc(FreeTime,ChatTime); + TLeft; + S := 'Chatted for '+FormattedTime(ChatTime); + IF (CFO) THEN + BEGIN + S := S+' -{ Recorded in Chat'; + IF (ChatSeparate IN ThisUser.SFlags) THEN + S := S + IntToStr(UserNum); + S := S+'.LOG }-'; + END; + SysOpLog(S); + InChat := FALSE; + Echo := SaveEcho; + IF ((HangUp) AND (CFO)) THEN + BEGIN + WriteLn(ChatFile); + WriteLn(ChatFile,'=> User disconnected'); + WriteLn(ChatFile); + END; + PrintingFile := SavePrintingFile; + IF (CFO) THEN + ChatFileLog(FALSE); + IF (InVisEdit) THEN + Buf := ^L; + MCIAllowed := SaveMCIAllowed; +END; + +END. diff --git a/SOURCE/UNUSED/SYSCHAT.TPU b/SOURCE/UNUSED/SYSCHAT.TPU new file mode 100644 index 0000000000000000000000000000000000000000..719695c4a632e478875a4b7dc273faab0b5c895b GIT binary patch literal 15152 zcmb_j2|$%q_CNQ2%X>T)F#&PyDQe`x;F1es;)Yf(Y^MI5+|fuj;XS}16h|XOpG%5b z+PF2AW=2+uS!9mdsMV;MEz|aQY$2?1N*&WD{D1d;*9Vw2&41?A;oP&{bIv{Y-tT)t zO2XJg!sjeaq2s1z>xuvRvqs*5Pb?=pQN94DLLxl%KT9EU_~_&?bkl9iE> zl}YqW^5g8XU?l}7rOt7u=DMIfCR?~*cDu0Fh|ECUH!Fj2Gd8$2OY#>=@oDL)BeP~P zdoVOwL#?rH4kJ;?B;9ft4y8FpVBb zw4dVNQh+EsKH{eXkc3(>y4MuEO5TjEfDTb&kZ(aO2bRJYzrw*u%Yj`4Fg^hVT^%5N zhhZN0mFx+EUG8IFrbItEom5}r<3ruzOZ~MzzDW;gf7eWXG0K$a7?qmo9+T}#%gUT- zQftg1It2n<1i&v`7cBpvW-L!jw2c~(I&}uPJG_EBw7FC?lTxSVW@U1_WQrQVS{srv zgWDwM9Yp>TjE7{oGhHw?C0FEgM8hnj-5Fe$tj=J4tR>o&Vt3Ac?2W=6tKmwW!I|WW z9u-CJr1zGqm&m5IH_;13LV^fbE}v8`R7fdzsiNA0O$+-6Pp2ee6n68MKx-hxl8PE%tN|I8UCMmpW|vgIWBzWQ)csFp(D6 z2{~z*uC&Zq;w0tAeB$LMc0Ru& zDn#M*w4|Mcb*A=4f;`f?X%##l^m#f!&jP2g3XF)-wFlWb-~xNNITEY2PVRN0bDHnU zIL~|+$_l;yzOmDdBRP_+<6Lk?$zwa5tOGrOe1|lGiQF=%uYdA{qRO2)Lb zj*Ii)cI0#?&88;J$!Hr(;YO%E$U%CjfAi2-Y6sddNH=VD3b)y9xS|8dFVH4_U`jvo z({(?8t{aBV{ou=>uF#~A&>$N%Yhnx}qX{N52z3ywK@LHiVt<#TgzG4hnuOST_cF;w zT@AZK=m7;g91cHcSBImGqmLuW;b`w5Q*7TiQ09Z=M@_=~2GT@ZpeZhyw@~x9QTZSP z(vY8kF1Fm4SdVY%x70+p*~rn%5QVlIn%$&e&CeF5g^@i-b0`8)7@8g)sB8ZIVjQlA zH4CL6Ed+_RL7+PJH}WUHPR5Mlv#V)v)jicYP{;Y}JW&|2G6bU7=8HUZU z`PqO&ZJ0Qm{0z7WgB#RVlvn=H;gsMO)eeU^SPyXMw&o~^KlyhwyHP(U1%&Dj>!-g^ zLmF^R{{8`>hJ1E{vM>z%w+*>J3>xEcIuE(;(R562Tg3p`=8qyViIMQE+5zt#pi zx8quLP@dL~7HjQkqZUCgX&vZ@){#EeI?>;?JIK@{;invTjz9I**Wx00g9-sl0PFR) za7KTLmH3i^jjzdRR8x238yarZ;3Pkfx$k9##z?lr7{#_2qgkaf2FF?gyJRHcAWLSg z%oLnCW7)mt{cNf^9tX_?w%q(5w#%Fdz5`n<9MFP#n77lVz;@K5d3(?iR5PzL?a%K_ zo;y0zv&%Y@QQnn4TOCD(i=ru_yax?0?@1v~_JUp?IMHG6t#8;skr^{YCwZL_1;{&WG+fS&A9(LnGA0fsQ6d^lUj6X5Fs zHhK0Wz+^TtV=CL9KaIWHV;Xz8duLRkPCp8SsJZLf90trjdoLbNa*VjiPx>Us((+U;*-8!$y17LAD;bZ$a))A@@HbmzMyq z!1wFG#~}MFWS>CxDd=wjKR|W`SmT}31Nk{m2%s&-?fCxmbiQqNI`?kO1n9B^2;}qYL%+wm-7ucIrs23bc%NX?noZ}4%)yY>6+0EXH*n$6z$NX=#&->=uXr0 zKESbny8&^4!Qc%8zLy@d%>+DzaW-_6t}S_4Lh5r2Z9b}aast#3HnZUO6$q0d2i6MEJ7QI@lfa|u|52L_L)AOZQv8x zL$=A#o66Q{GckS$bNi}Az2#jsz4`JRCPO@OVK^N;Ym9dkT~IVyl( z27fC>+HHVlfYyLE zyqZS0K353g?K8!s{maAx&qH6F95#)`UUuX5x!o8Ux8nSY%gSc zA=?YtKJfNICh&gvcn$p5K)(U{Amo1n{uAgw!R9dJM=;l$;2i}Pa11)fK_7?Came2S zPr%#Ie+TqCsKXi5;hyLAiDtB_uzdGnZOs}<1+Y{ zL0<)Z4RSBA7qk~PwUF0gF5;Is=kFT=G#;<(pmlu5rSmO@0iFPp-)q`H+jtMN33QtB z2(2ma59nduhH*23Uq6X+wdhu1au-`8wp+{pK2BYig=+hA9z0S?*WSd zj{qL!1?FPD++4v&vB&r>vmBAd5a+Sf%p46!rhaA$@Oa<}G}-(u?a&^e6F7fP;Ot4l zUZ2H^0W0V$V=J{Yw^Baait!GNchDc$4k|J59HmWRPicjm_2)6pCX;%JS8S*F0w*Ke z6=M@Gk7Mpn>JaFV-w`;|a-Er3kmupWbLzD8)F|heywseWv>B-bo!t_0Qgd^i6O$7L z4H@=;)0O3%E_`L>I42GpoiZ%x0q0DNbMYdcIXyKhNKT}_6^(J)MvuX}>X?KkEF~u` zb%rz*@9lxfshKmJ;_FG_kPmd4!^aF7H)ul3#%j*UjI5kgr|ZF~nNGXYg|7&5+ub>K z@fVe3J|W&N7Mv$@6H)ZJ{wC4<0Lil-aBJ01XmaeSs=XFA?scM|agshX&or%(-vL*w zr^L;8^t=B1mbl{OWz zmXfE+?hPAvgDM6^2>450hZH`wBy>d`|H&`xv zh3!TSq>| z2D%NAIxDU+y?(Cn;wrR)yQxgV?XZwmT~jMv$O==V3O6V(mZJeB9l7kXtksoh645|% zRVz2C65O%_>bre$iSAukrF&`K@8o8<+4#csuyJ*JbZf0-e4Z-80!!r^G=fEcLQ^v2 zk9v8d9&&{oDS7rf36Gwt9XF~bEvgqI{;Q4hmi$}AI{DT?$PF*H-L2wioSCGg+N}aw zeExxBI>~=!(W6F=8QxT$T{)@KvvOwOtir+6YRJ?~aWH0Or)FBmUV7Fn=S-Y+G0xkP zq#_P8O9J%}iv`>KG}nVpH@;wvaq6S9GE)PUYw=BejI%?xU-1#g+%sGTzu^2cT$b8X zHK`8U?#8NLMz=X#y}`w*STd=PVQtvB%|wqkEYeNJmQsC%8raLZZg^@qVeveZ+@q{* zIYhRwnCND8X(?M+L@O!Ty9;m#RJ`wU)X!P{43j%XNOr&PZXl65jYCogp7b|>Q$uaZ z!;$XvC8ZAh1|F=a#KHC}W3CVLrjg}A`s;q6aTlr>Z$yt}!LU9St5^*a`DF*=Z*njm z4rKK!$j#!A%6JsGeunxu|7CDeL5113k&~Z^NNg5PJj~8pO~e`c1);fp`?v&4>>QYdYn0#T?A}0$y#vUWJlt!G4Y6X#2{-e zqUzgNj^x!)S*LC~d6Ecy@kka|8h=eXDvhs`xGcUd)|nF@TbDn$c;2-!x&6xSuPckc z7JUvD+LcbFp|$bXpksBIHC>pTL@*n5esvm)4R&{tUh!1qrv@(dKoDPB7GE2Eu3NMU zt2&0owsQZ+lU}4)J02P4U1NFn+R;{S)t^ypxVx)NV?=5E)e069e>Fd}H2!*xRvUj^ z<$WDY_XSbR>gOre=Dy9!&iBYw{W!%ocXyJm+um?3C|7WU0u>K%y3f{R#rnBtOYY)m^3WUJ;eIfzKm`6IJ)jyYiDx zEQ|Mws81Bns|$2B7YpWU^tj~Gs-3km54Ycu__{#3_R{kR(E+7~FvKIRAG4T8=Tt>xH(2MFUA*PpGy0ws zW@k?M$~SEE&;aouf`7)BFKwYtXSYJ9@1Z3v(J~EKZm0M+V&{ys-04}F znW@uZ#{$Im?Q6(+7M$;kuPdzd@l;k?a?~rYb1R6Fx4etjydybkXLo>-r7fOZcm=sw z+!mtZPDIyzBI)Ru6(_gWJ95`tH^ zKjZnclHdID;fp}#V9nGD4>@vSZ}B*Dq@>_F9Vt0uz3^~hRsSRCNXe_UkhT;*PI=jp zl9OI0PGm8Q05O(Pm6p6`J$IL35bMmR)K2~jg>-k>wFWE#s}O%X1N+sico#S)868$(_YH!P*!qU z&QrYq)mpKI8jyCES-b4C7h6ciBKMFK%T08Jlr!ui#lPjBUxUd zD3ZFdl{{4icoL}JOHe8;`LoJ=#E2M-bNZE*yz8yeYnQ#-r~;mMN_g@y~GdH^j^jNHgIybR5QlSH(?m94aGXkxLga`{Rj zd#(&qiMtOqt8RhTIEmIsuv+7!YK@j?jgu(YNw2Tj{_WlnzK~W+^oAPVqBmML?v0kU z4SGXZ-J&<7v!CgWmbdH;VNu^3XRyG&g48djbo<}yjsLH^TlYrGU+fJW4f3QYuEJp= zdgBZdR=pvzy+v;bwx>#z%U23{6qRAUWN)1G*5u$>;y&vTXfF;Bme-Uu&9z@~5NkId#MT^bMXWM5 zi#Cc8EB7&_qzmqtR=8sptGfoTy#81KckmK0mO#KjHN`KeN^KlKjh;%a1F3G$JKnlI zZ#DYvqtRQooE|6GO5X|Qd#%OMTK{r~7aHGM_}J(A?-*+z9Sy&Kk^0wqd;tDB{JPI4(k_(FE4zPyUjY7PrGHK7>)g`! z<06kX)QVgAIl+GradeUV!4#+X!@&Ol^Ckm}d>-T?PAC3N+^W;>fTJzmL*wx`^kyoaVY^=hP|sYsh~CEavYe z_14lr$j8I)Q1B06-m#!X9RDNbf27HZo&mX7pDewX%>Pl)mGHAv>ODhGC_fv)7x6p= zEaKTE<FelYA#Z}d#%}{+ z-&u4E;3?ooGO@nBsh5;HXo%|j5lSx^{V&#Ws?wV!`~Uu~=@O@O&4peZ;x`FzrUdP`$6}G-T}owEaPiUr$LK4d_d=tDR7BF^6d3xB^?_Kzz2rHWpu=rz(`Ds2W| z_}eD=BXf33{uDZ>_-`uyTbO4A`uQaIVxBX=VxCWdMV^0Ce!o`qw~GE=(f?GmSNhK- zo7#^7z`{=mu<+AD?%$NIZ515>EYAO?vfqlEwUT&Vvpdk2E0A|I`ZyTz3{-tM6c`Ob z$-pAc@rs_M=yaHb!)}hW)9|+nR{jfBpRZMV8>HN%&5GWpIetRg4oQUfn?8AYNK`!c#{T4kQ{dHQ&KbP`E`dZ2HHwjYy zy^_}|dsFqHKl)SH2Q$lmYxHS2B~k|^zf;Mhlsrbtx6oiEAFkvhL5q0ttDY$1id@7h zaVIr@7ez-St|^Ec&k0gK6!JLCp8_0=`u-N!j(iu(dQ70@QZJ=TIqd!n|DvwA3rWOXy)XNCMefI-r-1$f{p=)8 ze&|!NjzPFrguiCEcbuRHD*jN#zXy07^4CuJ5q%g5Jx%qI9d#D>S)iYp-h3|n}oTK9u{QwJtd`&>Q#A^fQNW3~APvY`` zLiDqkf3?zEtMt~ZK1VOhe%cBw`f{h5_mI;6TIrux`rJUXqx#`6x8nUq;iz#+mxT@75$RZt5kZgVZJGt z|Age12iSEh9{fp~tWT&e;$9ulN*8@Ifo_-28!25n;`u|=rw6d8PaoiH_&KGXOa52c znTD`04{#Wk-zJ7tAMt!5>eI%s@@y~lRtH2XJXYCFPg-L%#*RN}P(Elew~wu;}$ zw9cnHCA~VJkHqBx{gqyv;*U^z_u&tQgx_%z_n|zAyHJrS>J&&zO{-2Tp)dB^8Y%Ba z8$gSC?>4RTV!!0iq&L79=fz=3Z^d6?TIa+mB|ihXI43?bt#juyDL?1BDDjuBD-vID znKohfy~|;kpr#IcJ^d?KY_B2E3r767v z>3`jnc}j1Eq)qpF_!ZB;o0a}HrT?>|H7Y74&T%LricywXMKMJv6#6dhw1c_z~kiF?yCf%|KAqXOi(NT01 z2NZFE0hcJK;1W>*5l2UHfl*Wh7b3VTqYfnRJ5{H*EQ~Y%_ulWl=;>4Et5c^=ovK^6 zZgt&eQr6^bfxlB?mPm0t=4csO6>@dR+3-QFl1B*feLK=g({y}x(PCSX^vC`x z{+L>`TE8@ra|)PEYa*i=Xrg7}lJd;bWFeNm^^537B_-r`Efm6WfB^iT6P{I8;x3s} zQj}Iu=q@SKY&Iyqh8#tSPi$&b5Uq_>d>{?Z+Nu5JQ3NX_0qvZ)UiBhq5w4AWOddf9hEGl}xK}Ck3wy288 zJ=FFcRN5M519r91om+}6kVz@9o=}NWJ%o;)pIbD5H}m8$V62(Z!u~qAnqFL=n_w{+f{~o z2#t~6=7f)N6}j9lZxPMb9ksmEpcY-)(5c&Wi-^K#{imubEN~Ud&+sG0G)@eCr44%vdnk@+~WTFypLn&CQp{TtS8B^u;;%{i@Hg!D! zdBpAI zc&HDDAw6>eMj0tmB>;S*tgSRG-Nw~SQ=Z@JEOSfn=rVN6Cx$VSE_GnBJUEyWfs-C$>P6U9TFuE z)&M2N!s2-t%Ve3*i9qQhnCLFkmtG|FXCqbHW68FlJ_3(l@PZ|lY;vNXeoR8-#1X2A zFUt=kN&!1*L0re{?@NFxxzUspKCZajRTdD#DTv_`Yj6yMuT!(_739azjNK?+X~^Mt zMR~7NRl_LP+>$aET1YAsjr*vs$}BX~g(d_J6+;ab^29qQ9k*?;?X%T3+1B1bxvg># zban`Wni>RXHf3>hTGIW=8y)I;Ojq9Q5}RyNoCK&z_u2eSiuIur%sDNyO3E>6N{aoB znvX`M*n=At+;{iepSDl8FNIFyzN33Ex2L7oJ8vCm0A+InVj5_$3XtH*BOEMfnbOdFGc^#qh$(S+TKp}S0 ziq*lGl46%$SMNuKsK+183-iTcV!l7LPX4tN(UQlCjgmV>Tgki2Pa%?+4-(7ey=sK$ z1W$w*E4Ip7?gzt>&_uj*3TvLo*I3yklzD%{OAJxTi;_|N)18m$)c^*?E&z&GlHv<2WvHs4xr zzfQ|YH?0{>R$ftJ;%~Vweu!h@)QOo{$%$DbC!!89#GqvjH9rQ^rXwmsM4D*n&>o0W zgo$vw(JBUiQ6j`@p?iHIl#@lA2#>G}Q|s0?v)N*?*hO@-#g2qUSm@3?9)Zjd38IU& zqY&nVXlS=`*qoh3v=QE`n~02zh;+1bIBX^-s4CZLMrcu&p{s|BGW7^F(N9>VinQ-=`Sg~bt|i373R2Jan`s9@NUG7e%%q$=w1$5 zASNOlp^0(U&~P6&x??a|Owl&o1TA<08&OH{E?JnutZ{8oSacHxEIG&ybuj@}VYkp2 zL~TM<7n+C!3>(54ZSF;X$--f3gTGi|wVL&K^n?(RmX7U31PYr&MC;a8hwN!#H5<{W z3XWJ&iw*rA9WqCtR>|N}bYd9#r=8VksaP0HK{6#o0>Z_Cv=svf?L)n2M2dy(3c31L zk*D{^;Bms!ZWuh_7MtAx=gmFZSUZ|ydyD9pNTZL4h>XNA5)rLTPK+g#x6q7whkm)Z zTkqo^dlpl8D`AJW6<(MV;;h1Ew~BBphM~EmFsP)3=B0!Bed36oOa;Be))L(v*M79! zWSGKRwzAr7!s0+bM`Qd7n@(ezYNe^>g8qo8*V~B}k+>qvQBmRM3?ZT-Mde+jVW1Xk zl!YE{!Z8Q6GdhSCR0L1ISs<)SQmuvnKpM0}W?D!$DgDiU%=h#@&6MOMye zu{C>)SeKI~?$1dV&*oeKJLAQ$%1n`TYnCW_Xp)F8nFN^#GeTu9XbNa5Xqvci!*nrr z%M8>tL!90=6X|P!=YwX0aJ5vrKyyVmkf@vonve8+@M}Q}Kt-^z5VniO@Ow*Orv&wT z;O7mXW$=|~Ij92oD)_w)yb8W=1iu^Y+=4pqN4ag_4mcOAkl%p( z2IMyo!@mK03)nlr-U0RwVtN$VdnkVl@-d|Uf&3H5KLPm!&0Euhl^SOl;LZALaxB;;1`p_O)j4)G}M*_!iJs*$H}`v^AR(ke8qh$w@$7H^@C9_k`RNaxchFA&-WCqalxmJO=U@#B&VfF_6F;ER#B7R&2>uB2cOZWU@^*rDfgS}_gPw%$Zs_cW z?jH2{v*_==(0>m4&q1z1{!8F5A%8#ktMKsvbY6r1hrtiS|JULF>q!3%d2hnzQCt)6 zYWF?x9_W402cTo1piSp7c7DV7_#I>70_wR4dv%Cc zJ>nwtnk=h+!*++hF*6+LaDD8SmU_YM5#Z7K(+{`Sja{wvAvr{`x~(J@cst-7fOpUn za)>$t?+C1`o|V%T>8^Uxtv&T&m3_dIL4)+7hf?+Ul2l+sLqQ`zBat@-_Qrz7>GwS_ z9+Uyf1ZC;V$|vD|kqfoy&FhWE(fguRYI-=UkSPq=^MemYB?FWhho z{J8`8J@91{{MZ6Nwm>Gj4?5dW=Y!zeK|5fJ=yA{!i04ztdj|ME&~w0^gY6fde*=FL{4LaT6!jd1O!O|=@&T}8z>YyCIu7h3*fjBb*`q1VC~xUGe;JhO#?dDLjVrKPcEbA)kac7zd{9SPkSz_#fio7~dJxFNRS}y|)1ziEk)WWUV;JM&aLDzs>kc&argKpH08f$=U zK>AM5JxFf@?MC`V@Rz_3fj$I%4&AT7zXpZqM~w(Q+!_n&2lEn7h2}&*IG+a<~ndU$b zD}mn#z6She*j}susBh3Wn{I*aJ7AmWPT2o5>~DkKc9h!zyE|e3G0@{kKLvar%0Gwn z^CisM*GQj3`Wx_XQT{vB{{zxLA^kJ#`~o}Y zVdDa*4z_jUs9_ijEmq^NmQbUgCCr#@Y6Xfie$-=(&8F7K?_gYO?Sk|mM4>g-{6w)> z|Hp#20dIpfem#Zs6U(yMq(;MERb0cIbs? zhJK*_cy1U58UY%K=Z1-(NubG~DR`Ec3YvlREYNH`Q_KOM1MULNLtY7Xk#FzjtdnrH{)U63C`n&@%JPeR^}^lsSS1HK2?v%vNtP4pb(7a_ld^h>C3 zKlpxNuL3)W^g)z61bztE>%iVXn&@wk{|@;bq=}9~ejof8_=mtxAbkR5KL-C8*hyfg zkUoVvPJ^EY_9d`0NS}dTEqE=kb9k2e9nVr1@C>DEn=A&%to1Op&`K;skx0jY$AGs7 zZx8MScY=2Y@2s7)bkRCkyMiZxCxCYYbw|1fcu(-2;JrY-k?sSY2%ZSu7nFo_GI&4m ze&GFKHwAW6v?G?wweyz2pj2&*WhnSi@L`}UKx4Hn`Z(}$*r6tVC1|`h0Q1H~OBU@~ zYuK=aog8396M;_xpA5=HdJ1%=LT4IurU4_G4txgqOypeyKV~6s7Sb;8xuE%=Lf{L) z7eKEV`X$IOg`MkwT?dS)40t)X8+1L=i=eX@I!mCl1Q^j$;5UFTgS{2NSHS-pL93v9 z3;1n_#U0>xg6`5nFu#RZHz9p5@XaW*1!cA%y$$*gfIzJ%>79MBO#e*$w3Vr}|2B2 z*jt#7bRqT>t_5EJUIZ#ex)^&5rMh9c4m#Ii@8LS&*J01$I(>q<3|JZRiONCOLw_0e zCYFOQ2VVhN30e(#HTW9n-waxZJ&MhsEuj0bSFsiQ77u_PMEYT1MB9=6EBIfrhp`iT z8IQq-$FaxpIP@L|{y6Z*;lmTiBdP|r8)bHb?*ZQf>>21hi}XJ5=du6s4(KT8UF?Ir z4>|@q4*CbMe}JC=KLP$R_$T0>f`5j+lT+9;IgK>Y=fFS5{>c}huYjL{d z13w4;E$9cNe?b0Eu<1V=d9wNr(oas6*}WI(HJb(L}f+2#q%b#p!1MM);3FPpJ^+Q zJ|&UUnxH0IguRqc!<5H#osjNpw!6exAWtL=ZxH|wcIKsYgFLd#f4TVK89qYG6v?dlF*@7VXb_R~YReza;Bay=dQnnYIe{;aB+mUS_?GRm@;{HQ&v zy_RmPudk}ngEFfsY%#feM~JMwn#iihcNJ25RRuP+jM`_l4e7Qa_}-$zsNJQ(Vh7pT zQbkJ09=j<=b-e`0ub5nA;{aAhC?N&;@gTl*scCaD(6_3Z-d=sFQdRR~P(H?$cWBx6 zdyLwyT2;+kK^n4HeFhD-0PoNMe3?^wukgFjM;EI;6dMk2_z+%i8uIQk%Zg<~US71g zp~kv3-(RF=gRPjpZcUrIv!;4{O0^A0j0kG5zw|0@FX=R|Lb+txvrCrr7w@Bydx5c( zE%PgQLs%b9Vf^vJrNT&~*(S^*CypLB&OB=5q|swdX=BDsGG(MqnPkeIJZ=(=sxz82 zx$@i@%{QvrU{u+7R2^CqSBG%F9W-9h2Rl%GBXDC=U_~R)UDU9wds zZeqHoc}JDQNuxPsg{AbJzq7DBpwxJ&G8GfpLQlEdSzhXzgToF^H|m;OSmbgR=Pz_Q zOZm8fvv97Q>pbqlqQa#vsYNGEoD)jsCFUikH*c%lo$vOP|1m=&nl_UMD|WkK3k4H?~x2b1A}Jhjzid6g^s2f=902DPGj8!Fdpz{Xet?S&o4_{E)u^#~3jqOdWWm=}urRbaAG~9?QE6W%p)}1H{dArz`{};Pl5W8* zd9qxe9=aA&`}*|o!C==LwNa+EYue)8QHRg~zouQC?(R`pb8Ve)cdo2ZwKs7C z_12zkq?-PSp?cYjqs@C{Gg8f->_#4?Dvwf>M~RK{(aht`8{Ms^T0H5E3MDI}Ju7Qg zqnYv2HU;bwmJ0P$YqRco;9f_}@lCq-LG$iK>8Z9$8a)d4{!^nbX{q*0wwa8g&3jef zUZP7pTB_rceM^=wNG{60y~H5tt)+%|`p6i0P&0~Aw7+gXF#i&%q5m#0o<@QBH(mIM zNDcE~u}cfifHAK|7SQYPct(8Jli3YMZusqS@Bd#ZPmB+o=8VU$jmL7g2dB zd}!1EAP{eImdtg=Y~wOUj-E8`>a^&*7P>@BBu5n%6ykYcol zv;;Pj6P@F+tmw;Y1+r<)OLq1JxAe@wak!p(UNZFhB|1lro``3c>pU=6Kzcy?!y|cn zEh?GkbUF#`fzrW$gVk*-Xi-6$u}<7soH*(mxJY2b0}|D}McI{xQ622cyF@UW!n(Xn zVhdi~05rY{*8*># zB|6iJuP-bsDNc0GStvWf-YL0X{{bljFB=r@OHH4de&vKtxc{j`tj>k5VvlorUdr&i z0Ymdr#=441^9IZu?9{V|Yhm=zo0sB$?8W#hADoxmfnXXOzMOnH9N{O0qpche{XqrKFC|877;U?J0E2CR)N|bfUR<;6i$^Gm23j`gDy9c7`&D!9LiT0%4q5 z{d(8PYCTy}mS47n7M^mw+*_`X*uQ$GOT@c^Z^OB~9uLgQ zLYDN{ zq%|jbfCrM|61S6|DhiylmtbxxcFoH#aN)UTI7~E(d_!vm> zvIrYtcvdAXdOYFFwWzSzm6-O2qIC)PoaA17gLwJ${WEQ1uf`Gcsd-!Njae*oDYhy& zzP1i_cIONKaUF#X3(Ju@QjWb*@)M&L(_@DG z%$A>xFI-F5$Wdt-*{xx8qD$^&W=x(i!CCGu!$2JFG$xM;8$!Oy9f_c;S>2#$U*ZxM zG(`$7AXYs5WGOVzj*QWGz<0*$gPk-}DJ@^fy?Q;7C5N%P0pgy9jSH9CQyLge>X*UJ z2z*}Y!43sBWT95JWO!Gyo1B{0e{@b>@~|9NL1B4mQT`I=91mt&GBl^mCvyCj<3)^+>7(-JEKr8SXX1XfC?C7IvYuAyg=HA&GEMzV z<323NlgJ7A4HYce@_tQEoU85p#JSoY^u*bQpEwUx#H_1%`@$`2j$SxW5t&dqbU60r zHrfwiyH@x=q>W1KhPts-e*5>peKyGdioyPTc)|v=cf(Su`yV@@@>@*q140DlOQo}! z{}X$@O;l;i|4~&_)4<0X@)7M!IB(Xfgh2wq#6xjJG$4--UfA5 z2g!arRW%R&>ML#XmVN{l18aCVNDeIhr+@lNxAd020~P~I-yS3fmR@$=SK8?*=M zrI!cE{?am~I@+&JVNl=6$ZUTGB8v#fC{-?RDXN7>g&SSqS5l?vs~dkc{#>q*?D#?0 z_4Z=r^2_~pgSt)Gz5G&kG35PUhso~)UJ=sU^JX1`|7mPDU!vlSOIDl_RIzLZs!OO` zo*~>bn;GgfEZ5^Zq@>T2kMhoaqlnT4Bz;_e)9FTv-f9}OYG+`pwp_ARFX9_AUq3Yw z&l?*z>ykm5e@Sce|1)bZ;w!sLIcI2rgXrH5ofq*v;HAtx)7ZO!(Sg?w8V#RSge6px zVfW%o#pOkOX?UrsHwRT6H1hrZ|JfhvfA_?ynnxR4K971YpYvv$cM5nRsJBrjNS49$ ze>85o$&g-F)hxx%#on#_CG4R!A6(FA)AEB081tBtR6chNjpe234s)pZ0NGK<>j;i<{!jIQ`%`TYwTl~rpnd~J;#Y~Sgas+#A5 zJn$=4hiC0|3Y^_ReX=cb@G1|hYTidF?>2ZPB;koumi-2Nb*Oxwj|=MqT%v`Y`u53p zGN);mNU^$mBX{&HoKR}U9Xjiw+zC4Q)4-kU>TCOk;Q$oA5O}4DP|ymoI;ue^YA=SS z_D6INXbrAtEDIl#!N&6gtr554TDUjJstjdSP4Hk~u!(zW!%IoEhgOf(aSfb;D{}ql z2@O1HLJy(3XLB+NG zLQ)5yD?e^xy>=*YVZ09uZqR3;0mg3qoA^dKYG!wWdr*RB(Vq29={7kl zJQSqaOnWM^com)&G%*C6Lu?RH^kaPBlof*ugo+upp@H`fdgQ=lME8z3UcFb<1dmP? zG*WD0AmUNF+Mb2~o4P)6?;y*51HL*MOx6MS4$M%WVWPNLRTJE|%E)JzoG2Vw)s7|| z!3=d#_UKv|51yfF|D~ml!{9iGDZPpAlYNLAl$`pGH0YhzgXI73RI6%k3~GS)DsOh? ztHd-w6U1s9hr{(g(zhH9ddfOGH+57qITKRTn#t*xn$b*7Y-+a0yTA>qM|wl2jU9B_ z_z*l2XZxmRdU`dyxdt8obcY^VgX@4xsVhuQpR)Vhqj>rn<7un%)VQN5WA6mMK+d*L zolNT@@_Kx3j9|&Y;1k zt{#qX?JC@rgJ&U`9}u;sA0qy%9fWF2gBym5@uu4KLf$vXnc!8+{~>4SS+qH4ybl1= z^wdF~;SGBdV?OxSp~fXWOID{gXkBe|b?W=?jeEsg z^`~0uOwVO%tDnwuFGo=`iW>jE=tEj+x@RC)>9!`kX4b?XtMpne^-9ku?C1yi1xvW% z8Xh=j`^)V3EoL`HSY~yX8R$dKY52GahB}`a=^(oBZ!TwC>6I_}8HOpCMa+{-PgNFFdHv zA#2WGT!xn|V(DdzTVuU1Tf|=CMG9$X14{V5N|cD-KB}c`GVR%g+DD9ChopS7CRTU0gD)gRGRZT2FTnyf8K<0ZdjyU9bGw96>;feJ=(aT=P5lk!jv@YGI zvU#iHwn~^4?y<^EC`GQ{@M2qV1N=n; z$GlB+%}a8|$H(JTSzdoSHLU)mIL7}@5>ClEhYlS&7{q@8NiXyta3e3Jmx1#;dR~&@ z%)1Jr-^GxZ%Z%Ee@Te=jz>xe(co)V-?MK2p z$G+oBy{4vPDzL$PiTMlnFkA=pbH(1nG!?;LHCN!U349H_YxqU=4vMM-!v+gv*#`L$ zq^0hY9dfa$)0Bn`hChQ0)|>0o>uS$7F>|VyTcfHfPB!vPy>&+&!=V@Vw+6bYQx#I@#r2q_$AM zCGHznEz~mCFZ1a!uYQDg9`LA--^`t5+xR2S)U9wby)9l<^L@~qR0R#XR|ZduL0i6f9VyJyW)<#x+A@cnTQDLjFxOBuwJkL4 zf8%vZx&zlg6I&;1sr^l)j%$pb7O7WxS}R?8(;>@W;IK%|YFywc^+dJ{Zl4NrTaJgS zn&7*E1gl%BXE6)>2^waN%QvUm#0ytm)yM``BZ6e<0L47a&EX*-+y4b$G2ZTKUAK*2 zoK|=GH*f?m@Gm53tA-!%6pCB%3%MCkEWkRJ=ZzX8YZNs4!1;vVo1B<>KkjDO4enkJH}@x!4e zO_h(4ygIjo7Lt^O`n$2*8}bgwgIFF4ITrF*ma`zwf;<^~E!sa#;zu0UXyi{PF&{Yj zvk-hS_+r$%*udt5%ug0;Ill^cCH%QZ;#0*=#-CvQJzU=lz{$UZEWZmGnTf{7uT~ZFkFC(k`rBaR%>sh`{$}wUy%MVCdh{svpEoFU}G|XT4uo?|0UV zHB&u(wZUfP$8fXqV~kn(F&lgY?A$2zO10Zq?@rd+#Cp$yQ+>yz-X869)~jW`Z&@$Y zLiPQsC0bN{{Vl4#K^9ft)iQsCzKHXeasEn)Z_sxz{utv=ak;m_ss8V!-t+oJ*3+%Z zzSXMicLk^Rq*=+2i+YY#`H{^N zwR(=^y;sk7h@@X}-4{7xvZ%i04pq;Mzz^e>mj4WSG4Q|0{AjV2<%ebYsA<)#_YC9D zL!O0l`=x#x@h00l%6eb2-dVQyJ1u{QZ6tY|_<>{h|_3w~!zSzR@HZH%N^&ge_^TivS z|F)FN#78WjWc@E#|7)3FF6^Po-|$fKzf8oj+#yu?7Y~`@++F6c7FTfo1lG@Gc?Rp} zv;JI?5uXK8?=EpY>)pWl>m|NR+{W^qQr<20u--nlcbN0vl=;tzqbwg|`zIv+qWFr- zont$pVX9pbVX7TY$kdLmVbsp&L{FCcQa=0~5T?fWXqo@6n8oE?Qr<0YVtGB=+r;JX zB4zwy zGRyg-kMUE=#-Nbt9x!g{cpWt#eT<%pacUbC8(cWdf<6Q1Hmg~4&SPSKE zWDDhQ>lWl^vDO(l`Pog%_*G|?uOdD8IfKjPbGf-KR6B2!`m41qtiO%RzsmAqE`N;6 zpOE=Gw9i=n68RKo(URlXlH=Ht!45d-v@ay@*kA>5&906A7lPH z*Z&sF?{fVgv3wGo>i>@GH${@aeRX@J!ehay{s9sX)zetMGE&ul4P>gnK;}p2g)A2{ zUoY|2`fV)ViE`Bb%`86vPW4vi>o7x3p4nNGnyp6EfA`wH5gt zq4#9DFZ1ydZ>?vsJQ?Mv{+TS#2B-S315Wj?X{E;1U9#LLeH-$r{_RrUEe^B%Ch21w zonSkkarrM>sr%hIsXs+O&-TqxXoZ2;B;(yk& zSe_gulAQ2!mc;MT7qk9y;EU0&8zugPUd8ww!08{V+QsFoS?_77_m;k&^$xP$C#-jx z_0CAWul1i;?^o7~h*ti^M5}t+MpOGNMgnlz9^h2(7}guddKpr$voV$R@>p*X>n&rw zl~Qk*aSQ9+F6HZu2UvatdK8BzqhmxY;&eQk;@(4if&5vJV`IplO|9BeAurr+;fz zPeyAsj^@eyr;XK|zYh7-Pq#|^tg(sl`xt*v;_;@(8Q;zLUWs2}dX@3RT+eB)Cpwn= z$TN+ORep?(6-oGMFflh)wRdH#^7nqJx6Jec>%Gi+pR(TXtQQ-n{O=b>cJDT2#woj# zqIb*P&zaUSek*Wl=SJ}ESO@+^=Jz!}%K1-n{xcFUF~7|CA;#a3_*(M^ zjDG~2`tQ8NcbG%l@O9Ki`Ii7$jyoxzF%4mPL>uMbc!}>c&t`m{l*25GSzgY1Ya!FP z*w;q2|FG1Hw0z2XpF@w@RV(qUEk85<8{>5nUu?0rRsMwIUpOJZyFw+Nl)#??Wo|DE*<*8dv%H2!Su zm41ACr8lxY*^Ra3wpVs%v{&uU2d8!RT$w+}wutkWNx4ki%znsp!^K$pz4k6K>lag;u-HQ)n{U8wCF1vi)bF+WB=d8c^7|*2FUoS`M5wOHMd+$r zJDuzmh(yNw1E>D|6PNArG6;meqF@ni7tFrue9FlQg9t zkB3ao&*5<~ALD@LKM(i&9WuW<_kNToyN|N`B$s;zIK}IEjEgMno4>{5>0OyWV#;yI z6t9nAm-dD6o3=8}UjwIjeFskQ`dQ*f9KS)PcsdcwPH? zsOKK&Tj9?X{7ZXnV2{ey@sQ== zt1ORwe<|a7LOqMbVb*(-%O92b)wySZQ$MNpRp(OsWdHE^v-7x(VtEW?x<1CS?Ba3k zVHy7x3+hdpvVzNb_wR3Ey?a?O!A~DD}mEEU&HcU=$~2Q zdhrl&s`sx_UMhC8j9(U(&&MxHyh6MJd@=O!tI$dGuS0*r@@bjBQk-G=8)?6A%CFFy z0zHBFP&qT^!CB%a;b6IijNgbUQ7p${UZi+*;CS~1PVpW9PVv5+<2_9BsA;35y>;R$ zGUb#hqZa|C^#Mdk2)mc&1nc%}H3@t>sp zC;ZEPO3y$$=zeWO`{s+S_}Bgv-a*RMq6f?P-b?EBm-s7!t`DkboRnX~Z=x%CD(mIx VYCc>nc{_0v@+q!sIj&Xu{{ji%K^g!6 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP10.TPU b/SOURCE/UNUSED/SYSOP10.TPU new file mode 100644 index 0000000000000000000000000000000000000000..8c9274b765b8d3cce2b9d7f463eaff9ce77b18a3 GIT binary patch literal 29440 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"F@33hgvb%p2Tnvpf!c8t0S3ZZrFv zw7W;n>pmeDo%Jt?-x9dr^d=!6#@~_h$AM|wXMoAyR_WI{>DPH7AITN1I!=RD9e*dS zx?lDIU5t4gh<3`OSnN}uf*y%|%?x{!KN@9T9|0Z&x%WhS34Zycwx0o}c%74Szl!$z8IyUUL!MN_ z-!SCKAhrv6t?D7KMg9z-cGyh@K8Adn349Wm_NN1|yISVwBLWv#HiA$4>Qj<_5j5UQ z#jjh`ala?&lajs!n&My(^Il--B=9Lq7tAxoBTDl7fF?QQsfgb&DTg1~C4CD2ZjyX; zzbUZffKUD2D)r{d_B%kI1b?BV?*dJ6UJOieUMBd>rfPwsvTBf5gV<5#LOaF#VPJ~q zCgk5Y(Ax%jEA%YLqa^Ta>HGs;E9hSA3DBgs73VLl$DK024vG0ps8P?8AvGLvy?}Nd z=HW)jML zmDMKOBXnwev`%gBt)u>f`Bcfzll&Qi--$1he1}f8vl8vJKh;Tkv&8!({-?C}j?_CY z?R_Npz4>pF-v&O#gX^jPOx{Va`qf3R@}mTQ79T44DS{5>Vm~h!l-nx!f8{Sq{$4@P;%`X0QOX?wP5Jt$-{lY$P<`m2=R2TcCpiX!sz2=E-x9}2sp7}cROL7x+}!*Bmq<-@R^C~vV}z)XQ9 z9_x+v;S|&zNzfZ7*ERNUv`1wXf6pH$EX(4Sf-hG$Kd`|wnW^UzNF z_6%U!?@=#`@yrwWl%*Ja+V4vx|6VCyBk7$|55J%ldV8hbe(>o$IUxB>Qtksue<Bh4NAd&pgRmD1n%alTb$J8UWd{BYrF6M&CjisFl8yCC=R>~K!;ibgIdcav zoihsszu9ybXv(kYvfik`xk2+%BhQUhI5#N2)(CzC+ba1xrF=cwDZlnh`riT6fJ5E8tVS8j!aW*>H9YH0ALJqWxpbhoC85r(u`k^`+E53qGC8KLS&{&I^9C z=`v`F*T3X=Pa`fl(Em}!1>+R)x-8qZ=$G2@Z<~mId&>1{7W@d7BKaeQ{iv+Ta=lKK z^q+;?jTpD8zZmVb?=2Jj`RqZ-ua)wfr2aNZ|6RyE%ufraWbnx`Km zt;71GIAT4Ee8ay$Am*j7q$h!<^^q;Ps;sE(uZXGJCgoCplMz{0j7ERLhzeSm^(2q?=kg$a2E4I^ZbjPmy3cP#Edcy zA&3L*SJB9;8zGknO!H&`COs?g9N-GXZzguI8mYHR#&3<_&t@AWf3xIo7yK%=NAmXx zdQCvROy|xK!QaY0l5(F4dJp?n(wGl%KK&y2jZBO2kzYaB?`EVMbX|^dVZ2 z-B<+PNKiLMMc$M_B8ovDU_p6hR7gQVbrFH7V&yutG&9p08uB;3jDc5PAH3d=vs z2W*~jdwaM8_-&OL4LgTGqWWnCz>ks^MyuPI&I*C+2ahpX8D3`|!2hO?wU}8EAP*0* zV`kCdk54#(|6|8fwjAm0{a8ivU{6c5Kyi)D5qq9L7}I}TU=7=D=V+4bh)## zx98;Mt*E>7aa3YAl$JAJB{srjp(ktv#Hs(u!h)mT_0;vcMjnBB_3XH%zbEFX@9+8K zs2>AX){C3yX8r!&;utT8+6A89#dx8vGa2{jI*sunT_-c{)%9}5i*+3XFVXc6@KRlW z2KVXuJ$RX}Ux1hE`WbkIt{;I{>iRCYE4pTsLD>_Hzd;>;egNDZT|Fwr@h>NM7U6_= z9OT)AE%CUDZzpVx$GJR*uq_^MA+PwpL2V1Tq8>xQ`QQ@a?M%1_H7xe=Moysrm8-|7dgL|STGG(rc z_3PMU;Zs$g>ehU&>eGChuTuTyCd~&`pWdbU6ROX=toZ@eXANuq4x18lK4fYxj~QM9 ITQJ4`0z1%Fng9R* literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP2A.TPU b/SOURCE/UNUSED/SYSOP2A.TPU new file mode 100644 index 0000000000000000000000000000000000000000..27cfcce9e0173329ae4bf5937a444f6259bb1cb7 GIT binary patch literal 7056 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP2C.TPU b/SOURCE/UNUSED/SYSOP2C.TPU new file mode 100644 index 0000000000000000000000000000000000000000..7487c828e8a4abc9aef8b3b4227616dfeb041cb0 GIT binary patch literal 5520 zcmeI0e{7pa8OQH^9XpBB`rdUR31zfLOVKJCH!Dt6vUf1oiBqSx~VY50~pc}Plr>#I?8{H&^N*Ps$rRF z$uD$5+TYBv;`ejk?|tvy$InHvJ0hKJgg<6TF9~SfS^|F#YR9$j@gG7quOMW+RCs!c zE?(Z(qwv1mOU>ncZ9?8$I<)M1W*Pl2h?Yk8XIuAe@e$H?=}od#1V1qHyD-k{7&$ zEN+Dm+yW1t46VMkBHA5ojcoC`Bi^V8xeJo2;`MS@jBkt0@2g>T{1&g9`SYn1gL`B0 z(ZJ&MT-uJ3FH^gqqU3Y4P^OOhc*3&3uE2^j?c4*hnU4iPcc@ zyP0=jK#cN&vHrnKvfo0f+07!EY>w^A_ob5k%XYZK&F>{Wz^vM#L^8EZ3J8fWl+L8Z zOtz0lU|`D zH3r!-WnOA^vv7uW1~+rVa3Yt?ELI}|lDKPMg1@hSbo)<80s<+b_(N>MjY z%d$j1m#LMiHGonFf4_VImQ1q_D`ojI={*aT?}Rrc#}fRR-p>Xz`QiB;?!xkht=vL= zF)-$4>jLSKWH#BCvevOsX26=C)y3Bm?}n%YPt7Iz2j``39w^Qbi^Rlwsm$I?8UuUW zESTWcZcRfYER?sQDV?*1S(b0RpVuhO?ugfWmImni+gU1*SF=9 zxwvO{1N%suce}5#$=|#q(6Tca3b#huqaB^QVqM)mD_3j?`oq?!I1UZ0^S;-{YxEQ1 zq}+S8Mt|PHFBX5nc(L$8RqPo;Trt4KU&W`dyt`E4d>wdA?98gjqHl37zgn{-<%0l1 zKB&R}RSn=&hy$jgU#`Q zlxFTwD`T1&P%Gco%oep$(9E4`Wk557YNbUpLu#c?Gs9}7N;6y4%D;&jQ7bdVY*#B6 zh#6HYPZG03tvpD~&iscI@Am6oHg~CoJ~O5k0%n(5s586OLbchGzfrMxvG9kbtqXm4 zrZO_lNTgV}QYHWXW2b@$8UNj>Dn)jxN|BwaQe>y96xpdNMRux6k)5hiWT&bW*{Lc; zcB)E|ovKn~r>Yd$sVYTws!EZas#0X9subC&Dn)jxN|BwaP-Lg71n5+i0G+B5pi@-> zbgDu)P?&AYIS+h>|Id@R&FXL6cXjt9sjmAz|0uJ;MvfBl$wQmrb<-h_jl4j}C&;I5 zr0#A0(d0H;MMV75)NHG+>*B9LK7JP;Z{x2A`0Fmvt4RX&J&<$R^+m3CaeY4@7oSfG z;M+nDA|D3dHCGY&0q*bRpO3x;z7Tl~^PT{oi;iL5IrKjRzCm&x`Iq2ZPk)2_JIs3- zd$v@coTgn0F`mj?g^j-GlzGfX}IY9r+0OPSRt@$1(4_ z;M<`60P}tXzO(c!<~@!6=fHQnb^-a<;G3i`BEN)ruY&Im?Jt;j6@1h5EzEll{Uvr$ zzY(q6F6-yAi~7yc80-!biGJ}&B43qGf@jq9R*x1+xae5bV*aS8bq%$o+^r}Wn`?+x%BHr~NJn?u&C%pvL*)>k60a)|mpY*ZuPMie{(X3evpE0Xf%)h3$8r7-`8Yq@7DpYJKizwG)aAMfS+*Gt8H zUURuhCEo<>qBkRN1zu0LBS(NIjL#w82^^v$$cKRY=uzZHfJf;mWd8jWU+)M#kNhI= zN%}|RtH5XJ+sKYG;h&_d%H;kS@HE|o+yFdB{m31_PNNq&4ZPO)67peSkMSV#W55C9 zN#v)1rKj{H2Zi@tOV literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP2D.TPU b/SOURCE/UNUSED/SYSOP2D.TPU new file mode 100644 index 0000000000000000000000000000000000000000..e8c7ca15d83639056ab9361b4617b2d3e5655bd7 GIT binary patch literal 8720 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 SHR(6lWWUU2FT(%ijqAUPmbroe literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP2F.TPU b/SOURCE/UNUSED/SYSOP2F.TPU new file mode 100644 index 0000000000000000000000000000000000000000..9ff5109386f012ef37af11d65212280805844336 GIT binary patch literal 5024 zcmeH~eQZ&@1%7D8`XQyNO#1SL#l4@yX4lHepx94}o9F0TC&p5pjf z{va?kD^sZk-BM*0>I6d-Y@++nHbre==}^09K-vM?N>{pRowlr_QzPicK8j!+WaplD z?AT7I%CtZB$DR|PchC8qbI&>V_$BV~__`QeZ?i3|UD>Q?^!l>0UpWXb#&$Xw8@5Yk z3$sXZQ&;My=(+IaxvCt^+c~T3MKR=VUfx3Qj(BHurHir2!B7J&)G8RbaMnowpqB!;iHoBv@_C{lH(1RzHn+{`?2B3e4u2db~&wD#PD_u@cgI5M=W91c%ZhxIjOvubcPHOd){+b4- z@I}K$AasAo7>dXnfq9EK)+gYq7yddR*Ecz?+}@gVSP|f z#M2l^BAc9|M~f#!AQBQmBeG44B}5X_$-qQ5=jCL1Qo))8cUv)(12p{q${G{_ZVK(HPT0dP0~x zL$ZTWEfU8QHX9~mDizSD)|^b|f>eEhNEo69_%^3`G=1`r;`$df5!GU%M&R0PHpU(R zc4PXqL_#0bAep`-bPo8S24{koWbMm4jEJ@z9NbQ^w8yBz0bXi`49Gdix~LiLkVZ0L zRBa1{^-v%I^Wt`+LtOaWTId1rAhN?L+5_9gK-Hr=640qYIBX1QA)!YEd?2DCq{q@^ zCy<~{lTdIxuuYTa0;$K7P(hmXm@yv>B;edKVq&X{;W~L^}(+kaVix4n+ zP!?o1*c=UFiR^(RGoXheZ~s6-gpGcvAd{yrm!$o(IFqbzjwIj^<62k?%7=h>*k9M+ zudVXedHl62{B_-U@5B2pf9)E7T~|_1_-i-Ui?XhU^^Hx}%Z5!R~9i5(TZ;x-m zeHCt3hc=Wx>p;IIj6SoZAWmjn&XYNvcN3d6L379O9)fTj%+}=1o=1Mr?;?yUooDRQ zyUjai_g1fwqgYu=VFqUh=k~M;`b*P5gK}ru0&w1m;6#+qv1iYLZ_hj9Mb`cD`S+!Z zMb=6Aw+G)wQd4EUKVj^aUNp|Wjl6vQTDAq&*UNejGUl0O@b3Sh?5f$GLyYa~&T3Fz zV{h21>hm?P|4;c{`B(1QUx8V8Y%SC|#*)f9&q(S@o*iZ*zxdfXxnbQ|t@@Bznpwq| z{GAQ>--2PB^IQKRp>LZ0XyrlJ{}?p0O`XU-4bsh&^^T<8%{GiF9{54?6RsJxA$jX? z=19NE*mS!^U7xR8ZBZNZbrlx1DPPAeYIDBsnxeY$b<>KvAzyb+QCpJBMpCb5Ckr2) zCB5Sl%u_Sr84pp1roX4Ct;u^vQoorO9b=xckXhjLu%fm}^4B*cXNdfqqHdJrZ*NGZ zW3EtCw@h^Y-67G;luj#(+MZwMdra*}I!96$=iR7gLOuh=XJ&qUC!=S<^f9J(N{{m& z*<%k=J;{oZ)bHl?kP|> z#>xLB^k2+hCI7R;zlq!_R70Q0C<*QMDS!p4CJLw;!xPIvm^A@CdTPfZk`Yp3;C%-SE-$}k3 z>`~yqO8nP|e;WBN%OT>QMgD329Ll}?C~)!|UL?Pl$?rJ&?X>)y{C*ZsDIA-7t;R&^tVFYGZ^w#jk&xcU&=Fb+h>M`is zQMA8reTD32(7uSD1^Wcpr_g?f?XP6NjP}L+1G1Nt$oLJmMI~l@Q6lRq=M^QUe=XXB zwq~-op?xjyMEOK)6L2z*M{s?The;;UZ?|n1`RzgdUj8KTqre|V`!{Sy$$kv&qkMww zze4*F+q-0c5AB@)jq*|)GVgOX?lAK%bI80)`67pz_i|i6&sULr0Obq3m1H-{BYYD{ N&B0z{tdbdye*+&_$o~KU literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP2G.TPU b/SOURCE/UNUSED/SYSOP2G.TPU new file mode 100644 index 0000000000000000000000000000000000000000..8c8d1179c7cfd5dcf832fbbcb74638e33f3e16ab GIT binary patch literal 37248 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP2I.TPU b/SOURCE/UNUSED/SYSOP2I.TPU new file mode 100644 index 0000000000000000000000000000000000000000..f7ff1b13dff9a5192060d57ff961e8330d48f45c GIT binary patch literal 2768 zcmc(gZERCz6vxkP*A3}5Xof&cln29Pi`cECHKCN3t}mluZnu=Ns_eRMyBjyOy-Q!R z&6fs{L?Jc-K9DFenexSim@Fp7W*FE9HAY2@fkcfl218^(;tL7UDAeAC+!oTqtctwY5V}Ju149+nLaS_X;CA$D0(h@ zyCU=e`k8NBnJ-w1MQS4B>8_EDA%Gg^ZP>z-M5-~CQ4;`5KjH!W?pob7G!)m8>QgZ- z?$eV)+Hf`%%V>I1TCzkWtFEgmrR67)YM-7+=t+P-Edau75r;wD#)e`4%*J(zMIR+c z0Ky3-{?Q%YY>hk}>5?~w?6Nn)lWa0F-8-^IUx(rnMj3a?Dy+I6RvcbC3-|17*%gqP z92?lLW>_+oP??)4E>zp>tVfLx=om>4q*OIoq5ABsQyopSAuX;N0^>uh_1jsyt`GK) zs}+Dy19sM-55(f7yN|>&`$}trb`}~=>M50FG`#nao?`xvlG<*^V#ZiT&*1umnoh@t z)pSYSVW^4paGH&%Db^oLtFx{`cINd(C}XFZ8P!w!nH`Jgt{jaW!9X&DOVVmw9pIbE zo>g34#rcHd3MtMFiYu%*x8O0WWfW(xn_0u&HlIHbY~K;8TY;;wljU7>vz-`J9QU=5 z+BN9j%PZbX-ELA`ew`)t3{&a;isMnmWe-Gm<4Lod=Wx22mvYTEeDN9ll%Zl%7N2B0 zB{BLGzqf-drN#!aakPn8O&~eQMm5~f7^7PDmKD;B32^(gL^g5%7HUacz?(Qik7839 zS=#2(mJ)1$wFqKk_|Cdn_mQgwlj#lqBRF`|Wcq~vCD9?D`+jB5d4T#J5@!$jb9e8S zE66-j#{AFnopNi2mk9uQ);^t~Fc0_^faB|3|B?OI-sHY0w`W+%6<7A;bHA4hlah>I zl8*+99&ffOpSxBLP|qiq$OQ&+K8Lp?c4nL8Y2)mBbJ>k@VQmH5AbEV8{cr*7&*1TM zwy*&9EO-Lh_4DS%swylT15Yr!?7&uh|^=dr8##hOoQy0mJ7wA z(U=<%&yEF>&7M%UF`xT&PR_{{_jT|#BHvqqY{oKPmXlg5OTOP1-4VnfR&tZoxexxaWv#ku5z!Og7M|(;{?SM(rFQYhw^Im@1p(<)_IQfL()Z|Un0H1`mNBflm4aj zm(an&>j+vc7GwQN3$JszX}!g$a|7w)R)^5rNbfd9gdR2Yx?a>}eEt%2eZls;m|rIT zr0KZePf~o3?G*A8==Tii)26dRpC&zO`&j6gNuM!Y75a73r|N$ZexMq@0%(TX>VE(% CN`cV; literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP2J.TPU b/SOURCE/UNUSED/SYSOP2J.TPU new file mode 100644 index 0000000000000000000000000000000000000000..5fa101cf7e677dc4f775d88fea2133ebf9a4fd95 GIT binary patch literal 32400 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

2lr( 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 D*v@^v literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP2K.TPU b/SOURCE/UNUSED/SYSOP2K.TPU new file mode 100644 index 0000000000000000000000000000000000000000..755a88d6198df5592f23a04f54e3cc1ea6cc53cd GIT binary patch literal 14624 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 Y=^u;!B|0zr7p2@KRbO8tY|%ge1E`k``2YX_ literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP2L.TPU b/SOURCE/UNUSED/SYSOP2L.TPU new file mode 100644 index 0000000000000000000000000000000000000000..2faf70e8bc4153ab236179bfafcf9d4f810e7c42 GIT binary patch literal 1936 zcmdUvU2F_d6vxlZP(_FdsgU5JzH7Uc-9&29?S3Sp+HF^}XpC;wwMM!#&CV<(tP+xv zG!cpTcn~Cb;GvO7`XD|MgpiQv1A>S|D8h?0`k?FFJJ)te8s*KM*|~Gi|9Ag$&fS~4 zHquxR*xo=htd^Rjgt!h$C#2JO0rV&U#WG`>fp_e6*ewgA(c|A+-(O69GXxtQ72Rpo zwJxav_}bA2OIbqEB8=HI1u*6|3*g-_F_5O4bvs}hTl8cm9k+GUkcx|iYtgt7zxYRs z0%j^@8UXzx0YsiTYz}n^9eb2w*%{|qfWc${L=tHH;# zUGq9w5hq{rOLmphvmNKuPQ@z{!Tl zAmw=cPiXdGVO384*<4AiGuu}vbV(7sxqLXB^Z7ILIHYBi(5H3f5r6~ z&@1%Me14VMkNQ14m2wzw!+9fQa5v+4w9NdL!z9`9nFPMou@nDzdCw*dTfBzGO){Fe z_{Z96s}(Y)mPpM9|aw040}nn@6(GBMcN300a_Y05Tro7So=(wNr4A8mH; zd0+b_Z8fQXkC({jo$vkJ^UgWGTF~$zeU13}0km(j$Av4LC?^jX~ zzs5cB%$`&}lS^jD#&%`$!R*w|iLqjCq%e`4QoLS-bJy2Y0+Th}!R+K@c8amjT#O;# zWpT+-FLSM+n}sj+cAxIH#;aK{Rt>{gC0{Z1@{jL+w9Xtd6M9>0vmP*I&>8uGEA{N( z7aZ&*>3#2#W4h#HMel6LdoZ+ovF82IGMf!8KYMBTH*WSox)}LPQ{$;vw`QzJ2eErAw5+l>Gc_tY*%TYumHBcgGbv27RW0ang+`U#5hEGy2@I`> zyP_u%i>7^QFVFoCSs|;Rh~0N{x~nZzx6Vy7C*kEy0LDHzoPMkL-VpD~rmjAlkbC#p0^ zJ&-arQys}=08%QT^(q}sB>T0Y8@N?@8&z7{rfWu0jbW2m8B|(>*rr8?5=L(#sp^C3 zQ1_`r2B;qMA zzIk=!u<)-n3{GzmA?8^@*{a(--F?n~-XCWDdHTQH5Ax8|-s&Ns<5Xz2&X#=?#ob2h zP}&+bRX#*1FMfM@<;k?#T{_V)SS}r2IWVv2;+KYJLnr)!;=03(>GM84wdOoyM;N>C zFU8*tmD}o);txVqZ1vZQzXxiKt-h}KHK=QB^^oEZ6&vYk-l}R9>!BJhx};$ja*Dqf z({HPS7rvqR!%!Wz8dCfbs4iP=Rs4NW-L`tS;_ruAZ>u$mKMK`ps~C$Gi@8;6PNVZ7eL-bSXK-HFZB??7?U5A-m}rwWjVP#=gWFYZ`Re-Zo~_#?z0U`N5fL3}S?1pfi})8Nk#f1E9WKSz9+e+>Rp@K?b*T(Zu;vU-6eg7~i~li+j2_wy3?gW${H zpCf)!nFD`>_$WUHegXVD;7<~NNI4Du4Dm7kC-CRNUk3jP@gFKz!8_ct-Z)?5w(7mh zZPmL$__E&n+_FFaQCfs9_dy%+3BCn<7<>%8L42cQ82l5&>wF6QUhw2oBSGhug9vl-ec9f&Litx za%>Q~toJ^T>`#(!7UOb1KLWlBd^hoR&KP)u_!Lir9|u1PK1bt^@x3(ftIiqBJ3#s% ze;)JZFz*QFy-MS!d`D^CnDdvIw+Q_`@E_3ll=C$FGnoGek9Dq>XneQxADDkhj2{%| z`Jbd8bBcf0Qr#|ZUF%x0{%gImevPm9Hn6p#AC2&v$cA_u^he=uA=}Ht&w?8MAqax zpzng8C7a~?pwGbnKG_uiA@mpFA0j)*Ux9uM{_C*E$)57P4STYdwQd*d`cbXi_wPCX pD15o^|597mdRFZBE46apG&6@!)_=-(htJ~I`z*al{GXC_{TI#D7{>qr literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP2O.TPU b/SOURCE/UNUSED/SYSOP2O.TPU new file mode 100644 index 0000000000000000000000000000000000000000..e3e50b62e80b805bae0ac60a2a2508eb6a258197 GIT binary patch literal 2272 zcmb7FZEO@p7=Gury?zkB1kWHQY+@jkBHT5cXys_JvZ5Bcy=$o!y6I82<>c-bd%F}u z*|uqE=v^+UM&n0fto|U8_@nYiVn{_&DZxKLG%7KMG&P~N@gr^OS<9{O%udVIGbZfb z?tAlmyz|avX0}GItp>bCp%L~Hl^Fbfo170{o5sMFIZ8Ax8CX+s>i}iVf;KK zhw9U=y5x{zx$0O4UjQt#{~>kHRhK~hyMB34kQtq=nX@%F@7%nTFr7~hpLPnV4VK~9 zV0i~~GfZ|L7YD$`I)@HgdHSaR?VlF)FM}|?*2<_hjl=64YOq$dt?b;1vtkt5K^VWA z?wf45o&ygn-kMNE6~m!ONDt~EEgCCTJZlwiMKBx|@zL6X(I!lgObkUuEvoX-Y`?D!Ml>U;FV=2E@ljTF(PCf4`bvpy1=^<`inheW z1By4GZ1dq;)s=0Vabj7kMr&yas|=`SK(!G z!LXsy@nP;Vy1MrRTUgzb`|mGq&*eU8j=>43&_}>{Bx(NSs=L2H88`kR_#BM;KASrO zJ^>6@(!7$zO}y&MVbpLoRprZN)P-zno6pIpYuVHqUmh5%ljfx?iWM4{=H%LCcL9>- zV5TBz;wn#?=QFWEBIA$StQ`Se7|$Ui(yV1A&0jKwNplvrNIA%!%ko8wZ>?@~7ETM} zH=xU$W!wBJj7TZ!om}iq{g*dIy>Fs7#k_I!PFvQ9G(!`NE>18#pTKj=kNtPhz^d*x zXP_g$eP6dZ4Xt}tuy{eY3?`-AE8@MB`@|K@xl0e2&QWY!V84mW`t07bB!*!6wP@e3?&?)eP$DXil% zamn-}bPIJf|96O=K>SCByWm%jPjNiO@DeC=*!txTTff>t^EAPFj&I`lR))U;E4*NLCwb%^()zE!a2b5i&R*rQ!$ literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP3.TPU b/SOURCE/UNUSED/SYSOP3.TPU new file mode 100644 index 0000000000000000000000000000000000000000..9f09e3ed5159999d5c469774017cac4eaa03b547 GIT binary patch literal 59264 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�r`Cqc{_l-y@Y%mL_Q9|=a=F0 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP4.TPU b/SOURCE/UNUSED/SYSOP4.TPU new file mode 100644 index 0000000000000000000000000000000000000000..1b80ef16228c3477b6e15afa646e9898aaeea22a GIT binary patch literal 8160 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP5.TPU b/SOURCE/UNUSED/SYSOP5.TPU new file mode 100644 index 0000000000000000000000000000000000000000..1051567a87a6bbcffb8fd03a36d8eaa55678f850 GIT binary patch literal 23728 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 z zy?PCh|M%+EtM}wQ`>+{{99k*fIB5<#HE@(_Wwlya<&xs^veF**Olo}}Rkn0ZYajKV zch>*)o_}9-d+grVmUMY4duxrld+U=MGrm6ad$;FU+iOeW_pcRae!u?T2kRoz4x7AQ zVkXW$SQlfS?e@IcmN@$_LPX7${&p+A9*jw=A0=FdmTv?yHm9NGgs88x3TIq%oq5gS zdN`mSmqv#hKWI~gAD3A3k>+E~z#km>&MNcj#Ul?ay_KqO80B@%_cMu*|6q~s#g9_Z ziF!B<2aRse2R|py_U`?#&AazloAfOsmpPY>T#(}?lNY&`7Hq1O z6jy4MRZeXoE~vDi3)rchzY&^!$hE-6);P4~RW7a8#hInW@aL~gD|6;(J;0kcT9bzt zc-8H%twx@pXzA(cNqzNF44dFks1h1EFBoNe*R;N1^pBiX7&$f`CFr`L4KLTU30L=h zMp2OYN`c$60GB&3NThws7S-)33c=l;RnXm@YWl3RCeFra!vAnMJL*f!)HwX{$4|%v9SAC;znr?^2_KDv=>zbojXvkROlX<(j7w7udVE&gOLKch0BP4M-zaGLivo)a!R62|wsRVA=l0}|=RGV&9#~>%x$lzPrpDZ#(T5`;R@XK)R(ekw zz4-Lk*bHS%hv_GaF9yxP5dKxr;gza%Z3-Cr+9(@6K%s`TpY^iHZxQHOTuz`vz3!Se zbaJ~Zl6UzlLi5-vZxoICjbcq}qX-%BF+AYcEs1XoLlkaX^iJof1=Q^Zp z#U)5mnd>X^8YPnKL-?f0Kf`$X^)hNzw`$4uA^Ks;B_?PuC8M)Fb8NasCkmSXk7lP; z>ocROw0QY-0*rC#+LW?N7Y^06u_ey3B@SW$AD^y`FD@^y4Y35Co30f&YD#DU3gJ&k z*QPp_YBO;vrQ5KdiRl`ByI>#{NMDTS!;foWd0B~8P*v-M3FDK1*OV=xp!EXAZ%o(Z z_aL-9hof{{amnqBPf6EsZdt{Zq6WsNrfV~+%d3h@eJx;onh)1*)SJe50eY%xY2{?U z1>;3JPM&lN!lUh()6=za#jaAV2$9xCj~zEYcf!Q{NjFZJI<25+dVD*5-u%29CewJw6MT zLHmH9+X#E7+d{E+tIJ9E3fe26I&w_aRq((mmIFt_VW8$j2$D8{IhC%8g}Cwh+G3@=dqfzb_+g0JRLb~#=u^AL7bwRS5;-9n5yt(Hc<-x(t=r~7^pNLgKP3NOV-40e7s;s@x8}S#toX{35?$a zxl+t8&D@outE&Z$k5q5zkp(W7}^oV>X11o0FxJRu{I3K>VW2@ zYgxlPpja=4b@YJM;`*TK*e})!s?8T0qc;G}3RK4^){o4gf$A8Y4D|Xyb&O(78I&2Q zj!~>A)QWbsVLcf%v_oxJO$H6`P+K8-GN^mlFIJergFDoQ^=0tz4t{5(YeR;0;Lb!V zGKct^L4GrE?bazWjKnBq&T(W%2KTs-`5DA zM>haHgsAy>RW(bCYf5#sQ(jq3ty9nAQAR7r{yH)w=D5kl?Fr^Wxj@sd^+U7V60B+c z&>V6T@8*BDNow+>w%ya1hR1*CV-nS2`^X&1u99>m8DAxY-R`TzgC`}bzjbKv738k*Md8=F`iwrVsoR*D49CW9-&THbI~gw<)(*XN1Eg!OOHK0*2}I)d zbU|-Whc%n1PiRZOTey@lcxFgy*T>g{=m8%x_ltF!)4VSIp(SATiv~6rSOZ*N4ed6M zGzfya&Fhl&?AvO}Jj&hG(M3obLX4wOXGBMXkUhWN(E-vgHX;rVV**^6`$dC97{vb? zgCrPq`85XJV37Q440^&q`!xoAVbJH-7^J}<_174r!=Qf$gZPdw1Zb^rCGrHJHxeDE zO$h4ts3A_U4AJ`)wcQBtzuO3`Df(lwjEUB+b*AjGc;AxCkBsdno<0TwEubgaQz1iJ zmiZn(Th5C^jn}ooSya2ht3RywN6>ChUwrD%teD2~X}#XlAFlumEjxu9IXP40RHs1` zx(I-@Ry4qc*O~10h>oF9{o-UX0{QeQ; zlJOi%_H?WmKjCF*RLEG8<4vD;f#DAwb5vhOLQq^QIjOv^L73zj(pVp{n*NGbDj_DA zuWT|DCRqU!nY)UbM!;-%z-%|y6jBLR4X$J~*x3R0)mAbNW@7?oSEwWp?A!qRYAd+` zX88fLD^xNS?8yQ4)mBmjv!H8ng-T|DJ>%C`G8blZ0%ljJ#18h&0ru6lWFgEJ1kA2b z$*o|Q2H00y$zqr-3YcA?l1i}41MI7@p(nXP8ecV*FYNW&Tl_gAi3QU zBE4|T4?0t%S2bnwry@8Sq+e@{(0uPKgI^X0Xd|?4^iF43F5W?w(a*;8lSsVop#x&P z{G}I-_F;K}7s9o{hmQdsy+0jaRf*rpxEvfp@G%9wO3u-eK$^raXO}K2cFJQ(I*rWH zs3kanyzBu7P9VGX<>Jd6LB5KwoZ)Xx>#K&4mpKtZN04i91nFJv()O7!?7gcoWTu83 zHtIuUy8+MCA-L}lvh)`ZAr~8b(_zfWJS$GyZi1uiOFELLneqgb9*}~LGl6-X*y4wp z=_8C^u(YUfdoxC)MCAt>LLOzFo_gRQD`d!qIyit+R%*&6Z4F*|lG^V4Q11cXb6ik$ zO^vI(P50M%=^)l+&3vV)ae?<_x1iHl9H-;RRl*kJD08TBz8BAq`m>_^th3SPkxqp5 z?-8JZ$fIupH4;z15x70`k@uCyW#jo~C z04vWX1U06E7w&d>$N43-?quW9a_0vrKb0kVv z;iPpTowTlB7<|&Y(Cd3w=r`|BMW6&8{4f6kC`BF|QZr~&B~DuNtYdK95E~u$j&57+ z;vm2X*hA?Mgnnsd7wE_7L%n#1=k|CfZF!eDS0ZZz4u3zG0iC(4jk)9Op=XXTe*? zuQ|xlkc&-&uM+dI+=~}F6~0O7=egy)q;Fl|iwbC!+f$Cup!Len^v%o)lmq0qJr$U4 zT`&{%OG?A2((ANPv`u-|dJh#_^j55?hil=yO**760ukvdS|CG5SRuDh=$NB$g*{DM z8$K@T8=JrgYT4gz#>pc8xLR!=te+QanmucTeJ~EqYxNw#64J|MwiiwqWd>*817!w> z-8zd-wfrcN~nSA*U$2$E)U;jj*jVNrgs3N^F4|AGjy0P5r2lxP$Yu$ z^IDndHFL6_nK^mD?Rx#aav916RDdHR{u?2s{M56f0{LIg1rbLXsp(evWdxjMs`gAp z)B5)9t4*y6Im*U~vg6jWO3YIf(kaceG4kT9X?->Z-@&6@W$4b7zL&+DP<*jYuJl2t zGj7j^9oK7o|Lanq4dbreg!Yd|{}ZK7+P*H zaIn}1j5Y-Cqzx_U2H(_8_2-fd`ZOo2X46%Sd>I)gv!%&1$9qrXT(9r+W~_dCGs5ke zgGL@iY1*YvZ+07fyH8rlI=+bxL9tZ|c?k<0tGOO6U4YP!`D#{sxzROHRPo?mA9g+9KdzvB;k^ zea5t+o6>W~&Y-6h-}4equklZ(T;h8<=EB@bQ*t8ZcV+yC-BTUQoSJ^Vt-%TpN0&VN z*6f*m?1OXcnb*r)4`8k{0~%wEO`9u{!omM!-H*&bSzE_;s)PdWrMm^h`Sr_ zXp@K0?z(!KX4U$wuv_~M z+@57{;oa+Oll8Q`EO1)TSx3o7L7-^6!0Y@=7u}`5MyN-e*&z|>J>V(m2>PD$Zw@JP zd-6kcX@5EDtd3Obxk#tKk)##|UNrroZ5^)McKqU=9$WRT#~YOO{e@?2#ZQSXB0S@` z{H?jJ4;6_8_=&Pu1AGo-BYq_RHhxIF9(n_acqO6dY^^78-D++2>fLKb=ylE-&>INu>XL{AwQD- z`--oiQ+(fYeBX0?7iGC!*i^kdTGiXx6Z$gnuT}N-^j9g)8ZnG{*}&`3Zxbc{khqC) zJM&AR%lILwKmUj2i;&cwZy>2XCWEf0KpsbXvLJ~+hj9nw2heLFsoiTJsojkRz1__Q zit8n@8923Xn?aBNdFT}XeuK#P5_TTwzVSeEiG}R@t$j+${%fDHh>UZ%ZhI_=1sd!Q zS#*DI06&6Xx_=3s{CzFUyNc7SpXKsMt6m;w6&VY_?`$PMnn(psaa{+T{Nyq3Mp@of z6tF&%%gb56gZ(UltVdicfoH(a)6ClgeF5}?($6UI2J6S9o+C~`r+UA#>ir?Y^!Q9+ z6xVFg7dn*>l==cOg7us*#EeL)R!iP;v5tBF z!@NH*Zx{1+OWsEDBJ*AW{s7wf8Du_W3-iBW{u#;NDcYECu<7+D+4OdGhfZ;(+Nga8 z#6aNGzAP@!;qqKr{x30&%V)5k+nHC*JeTBsC+eAZC-XKlZyWReAbDZRGtAq|ytkNl zlzHzal2@qYGH(*|7BJ7j zyv34Nrns25f_WR6cR%wUmb^8}ADFj`d9O0>F!SD&ya$!{nfD>%pGbVC(h7V5;=CaB z{fZi)>#-5kuD>bC(CNDLkoqYlll7sH)V{G2KcnQaeq)5l&~RO6Md;&rIb=O}Yf(5<47D@5ts6C)ld})!opMH^g zeWM^B06vc8RLL({vwoDgSRG9yp35ewo2Xu>R#r(2;SY8U!O?)CG`yB=NRu6 zMR9zkW<=?642ja?7y(J`87Ir53^Ta=Cg9|6HQQ}u{C>83nC%{u<>`h!T>b*v9hdk_ z!)eCPGM*Amas0+GFj|izD_XB-uEe(+${D|d@!v`ORl`okpJx1BiJvfh&iF~jV`IpF zxUpA^?!Qlr?tiMp`x_T9?qIxG;xmj}8Gjr&UFRnyzS_8l@fW0CW_*M7x53+o>+uD2 z8egr@=fLiJ*3V0RgRzZuL#)0|C&lu*0-fqfjiq=WG!6ky<6{K#3Yj+xI{CFr-k*#m zj4uLC^{-}qE&FSdyw{8mvA;)|x0iV@vcJDd-oK4U7=Md-pRwM;{=SjC?~GpdXN=S9 z?HZ@ILxWE7^@*c)SWE*LAH=*#tWSkb?VT=pDW+23)ZQ}Y)idu-_UD$o!KQl|{~hz5 zX8k$#w@>mWnf?#^`y2C4Fz+k&cUtmpF`Z@nBJ(}p#r~d=yx!(l+23L29cSJN_V+dOPfPwt^Uusz6DaO-b6kQR zPv-=Eo$e{|2J=wHM*^qysU|^R57)@@1>!j_--q%C(4LnW|AFzJ822)sov7C{Hc{v2 zB~twx%(pRK4tzK2X_WW^(aQLD%>Pm1+s$#EIo{5Czb1DkKS#{hGTxu@Oo`hp`HWAI z`T{YB_4(lCqrQa_?_ycP_)4j#S{hkzX5I#g54LP${0~x}XnBV9z07-2;xjF8GX4*# z+bkcl{t5FwhmH-bI48>&SqxqDc3C0ofk$@H`@1uA+V9eHMjzm__&H!6KYuKcc$BDQ zyq2Fo?vr>Xo-cI2FERcfi5H4*7(c_$6X*DOLg4v<>W_k?>)MHBcRVNb5!GTK_Wd+| zv-mmTdPusjjb+|6mh-@)=LZ-5MUNQp?*vZw)%DObAkRWldt$Nw?;{=%J$V10hW$Q0 zmt@N4gMMpAvYcqp`(rBWbEMtN;x@J`XS<~m|3EY`z8*NuzfI8Tx#USmdVYBZ@;Kr? z!uWp~k2mViHT@uomkUX}d8|Lk`X7xH_XY7+=+qxajQalO-_VyqKW@~YTTVcy=boP- z>A6QW>CZhDlYU*N;JK3eqk*4iu_u!K?v{9zc$o36Lf`isfKL7T9sY$b+MftqM~bs2 zBt4H^kLyhSRzp(%ZszN{Q_=Z{nEx3hwd(@LLx$*!>#etguJs z0_f*4j)#kxioo?IJsRU>xF}JQpi_L^r9M~5WqlGqk2)Z!d@;roJzrI!d>M47{Wq+i;qr5=|IGHCd7LF<91a(^Dm_?F zW0}eLP}WCcJW^aUS)a@0x3FHy<#nt#aQWS=ySe-c)}P|?XIS6Mk`o~;; zp7k~^H((x6KUz(Cd_7se)}*(qKkJ!Xek1DzTt1Waxm@mKeK~X*XLZnN+&&0N#urNc gbwTrr>ZxJgQl4*{q)ZlDQBM8(7_SF32lc=I3qgBYzyJUM literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP6.TPU b/SOURCE/UNUSED/SYSOP6.TPU new file mode 100644 index 0000000000000000000000000000000000000000..8d046b5f7f658c6a26fbfcce94847e7b39f6b4c5 GIT binary patch literal 36352 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 0) then + dec(Y) + ELSE + Y := 99; + M := 12; + D := DaysInMonth(M,Y); + END + ELSE IF (D > 1) THEN + Dec(D) + ELSE IF (M > 1) THEN + BEGIN + Dec(M); + D := DaysInMonth(M,Y); + END; + LastDay := ZeroPad(M)+'/'+ZeroPad(D)+'/'+ZeroPad(Y); + END; + *) + (* + FUNCTION NextDay(dt: Str8): Str8; + VAR + D,M,Y: integer; + BEGIN + M := StrToInt(Copy(dt,1,2)); + D := StrToInt(Copy(dt,4,2)); + Y := StrToInt(Copy(dt,7,2)); + IF (D = 31) AND (M = 12) THEN + BEGIN + IF (Y < 99) THEN + Inc(y) + ELSE + Y := 0; + M := 1; + D := 1; + END + ELSE + BEGIN + IF (D < DaysInMonth(M,Y)) THEN + Inc(D) + ELSE IF (M < 12) THEN + BEGIN + Inc(M); + D := 1; + END; + END; + NextDay := ZeroPad(m)+'/'+ZeroPad(d)+'/'+ZeroPad(y); + END; + *) + + (* + FUNCTION ShowTime(W: WORD): Str5; + BEGIN + ShowTime := ZeroPad(W DIV 60)+':'+ZeroPad(W MOD 60); + END; + *) + + PROCEDURE ToggleEventFlag(EventFlagT: EventFlagType; VAR EventFlagS: EFlagSet); + BEGIN + IF (EventFlagT IN EventFlagS) THEN + Exclude(EventFlagS,EventFlagT) + ELSE + Include(EventFlagS,EventFlagT); + END; + + PROCEDURE ToggleEventFlags(Flag: BYTE; VAR EventFlagS: EFlagSet); + BEGIN + CASE Flag OF + 2 : ToggleEventFlag(EventIsExternal,EventFlagS); + 3 : ToggleEventFlag(EventIsActive,EventFlagS); + 4 : ToggleEventFlag(EventIsShell,EventFlagS); + 5 : ToggleEventFlag(EventIsMonthly,EventFlagS); + 6 : ToggleEventFlag(EventIsPermission,EventFlagS); + 7 : ToggleEventFlag(EventIsChat,EventFlagS); + 8 : ToggleEventFlag(EventIsSoft,EventFlagS); + 9 : ToggleEventFlag(BaudIsActive,EventFlagS); + 10 : ToggleEventFlag(SLisActive,EventFlagS); + 11 : ToggleEventFlag(DSLisActive,EventFlagS); + 12 : ToggleEventFlag(ARisActive,EventFlagS); + 13 : ToggleEventFlag(InRatioIsActive,EventFlagS); + 14 : ToggleEventFlag(TimeIsActive,EventFlagS); + 15 : ToggleEventFlag(SetARisActive,EventFlagS); + 16 : ToggleEventFlag(ClearARisActive,EventFlagS); + END; + END; + + PROCEDURE EventRecordDelete(RecNum1: INTEGER); + VAR + Counter: INTEGER; + BEGIN + IF ((RecNum1 >= 1) AND (RecNum1 <= NumEvents)) THEN + BEGIN + IF (RecNum1 <= (FileSize(EventFile) - 2)) THEN + FOR Counter := RecNum1 TO (FileSize(EventFile) - 2) DO + BEGIN + Seek(EventFile,(Counter + 1)); + Read(EventFile,Events); + Seek(EventFile,Counter); + Write(EventFile,Events); + END; + Seek(EventFile,(FileSize(EventFile) - 1)); + Truncate(EventFile); + Dec(NumEvents); + END; + END; + + PROCEDURE EventRecordInsert(RecNum1: INTEGER); + VAR + Counter: Integer; + BEGIN + IF ((RecNum1 >= 1) AND (RecNum1 <= FileSize(EventFile)) AND (NumEvents < MaxEvents)) THEN + BEGIN + FOR Counter := (FileSize(EventFile) - 1) DOWNTO RecNum1 DO + BEGIN + Seek(EventFile,Counter); + Read(EventFile,Events); + Write(EventFile,Events); + END; + WITH Events DO + BEGIN + EFlags := []; + EventDayOfMonth := 1; + EventDays := [0..6]; + EventStartTime := 0; + EventFinishTime := 0; + EventDescription := '<<< New Event >>>'; + EventQualMsg := ''; + EventNotQualMsg := ''; + EventPreTime := 5; + EventOffHookTime := 0 {FALSE}; + EventLastDate := DateStr; + EventErrorLevel := 0; + EventShellPath := ''; + LoBaud := 300; + HiBaud := 19200; + LoSL := 'S0'; + HiSL := 'S255'; + LoDSL := 'D0'; + HiDSL := 'D255'; + ARflagRequired := #0; + MaxTimeAllowed := 60; + SetARflag := #0; + ClearARflag := #0; + END; + Seek(EventFile,RecNum1); + Write(EventFile,Events); + Inc(NumEvents); + END; + END; + + PROCEDURE EventRecordModify(VAR RecNum1: INTEGER); + VAR + TempS: Str160; + Cmd1: CHAR; + TempB: BYTE; + SaveRecNum1: INTEGER; + TempW, + TempW1: WORD; + Changed: BOOLEAN; + BEGIN + RecNum1 := -1; + InputIntegerWoc('Record number to start editing',RecNum1,1,NumEvents); + IF (RecNum1 <> -1) THEN + BEGIN + SaveRecNum1 := -1; + Cmd1 := #0; + WHILE (Cmd1 <> 'Q') AND (NOT HangUp) DO + BEGIN + IF (SaveRecNum1 <> RecNum1) THEN + BEGIN + Seek(EventFile,RecNum1); + Read(EventFile,Events); + SaveRecNum1 := RecNum1; + Changed := FALSE; + END; + WITH Events DO + REPEAT + IF (Cmd1 <> '?') THEN + BEGIN + CLS; + Print(#3'31.'#3'1 Event type : '#3'5'+AOnOff(EventIsExternal IN EFlags,'External','Internal')); + Print(#3'32.'#3'1 Description : '#3'5'+EventDescription); + Print(#3'33.'#3'1 Active : '#3'5'+AOnOff(EventIsActive IN EFlags,'Active','Inactive')); + IF (EventIsExternal IN EFlags) THEN + BEGIN + Print(#3'34.'#3'1 Execution hard/soft : '#3'5'+AOnOff(EventIsSoft IN EFlags,'Soft','Hard')); + Print(#3'35.'#3'1 Error level/shell file: '#3'5'+AOnOff(EventIsShell IN EFlags, + 'Shell file = "'+eventshellpath+'"', + 'Error level = '+IntToStr(EventErrorLevel))); + Print(#3'36.'#3'1 Scheduled day(s) : '#3'5'+AOnOff(EventIsMonthly IN EFlags, + 'Monthly - Day = '+IntToStr(EventDayOfMonth), + 'Weekly - Days = '+DActive(EventDays))); + (* + Print(#3'37.'#3'1 Start time : '#3'5'+ShowTime(EventStartTime)); + *) + Print(#3'38.'#3'1 Phone status : '#3'5'+AOnOff(EventOffHookTime <> 0, + 'Off-hook ('+IntToStr(eventpretime)+' minutes before the Event)', + 'Remain on-hook')); + Print(#3'39.'#3'1 Executed today : '#3'5'+ShowYesNo(EventLastDate = DateStr)+' ' + +AOnOff(EventIsActive IN EFlags, + '(Next scheduled date:'+EventLastDate+' - in ??? minutes)', + '(Not scheduled for execution)')); + END + ELSE + BEGIN + Print(#3'34.'#3'1 Scheduled day(s) : '#3'5'+AOnOff(EventIsMonthly IN EFlags, + 'Monthly - Day = '+IntToStr(EventDayOfMonth), + 'Weekly - Days = '+DActive(EventDays))); + (* + Print(#3'35.'#3'1 Time active : '#3'5'+ShowTime(EventStartTime)+' to '+ + ShowTime(EventFinishTime)); + *) + Print(#3'36.'#3'1 Permission/restriction: '#3'5'+AOnOff(EventIsPermission IN EFlags, + 'Permission','Restriction')); + Print(#3'37.'#3'1 Logon/chat : '#3'5'+AOnOff(EventIsChat IN EFlags,'Chat','Logon')); + Print(#3'38.'#3'1 Affected message : "'#3'5'+eventqualmsg+#3'1"'); + Print(#3'39.'#3'1 Unaffected message : "'#3'5'+eventnotqualmsg+#3'1"'); + NL; + Print(' '#3'4<<<'#3'5 Qualifiers '#3'4>>>'); + NL; + Print(#3'3A.'#3'1 Baud rate range : '#3'5'+AOnOff(BaudIsActive IN EFlags, + IntToStr(LoBaud)+' to '+IntToStr(HiBaud), + '<>')); + (* + Print(#3'3B.'#3'1 SL range : '#3'5'+AOnOff(SlIsActive IN EFlags, + IntToStr(LoSl)+' to '+IntToStr(HiSl), + '<>')); + Print(#3'3C.'#3'1 DSL range : '#3'5'+AOnOff(DslIsActive IN EFlags, + IntToStr(LoDsl)+' to '+IntToStr(HiDsl), + '<>')); + *) + IF (EventIsPermission IN EFlags) THEN + Print(#3'3D.'#3'1 Maximum time : '#3'5'+AOnOff(TimeIsActive IN EFlags, + IntToStr(MaxTimeAllowed), + '<>')); + Print(#3'3E.'#3'1 AR flag required : '#3'5'+AOnOff(ArIsActive IN EFlags, + ArFlagRequired, + '<>')); + IF (EventIsPermission IN EFlags) THEN + BEGIN + Print(#3'3F.'#3'1 Set AR flag : '#3'5'+AOnOff(SetArIsActive IN EFlags, + SetArFlag, + '<>')); + Print(#3'3G.'#3'1 Clear AR flag : '#3'5'+AOnOff(ClearArIsActive IN EFlags, + ClearArFlag, + '<>')); + END; + Print(#3'3H.'#3'1 UL/DL ratio check: '#3'5'+AOnOff(InRatioIsActive IN EFlags, + 'Active', + '<>')); + END; + END; + IF (EventIsExternal IN EFlags) THEN + BEGIN + EventTypeStr := 'EXTERNAL'; + UserCmds := ''; + OneKCmds := 'Q123456789'; + END + ELSE + BEGIN + EventTypeStr := 'INTERNAL'; + IF (EventIsPermission IN EFlags) THEN + BEGIN + UserCmds := ',A-H'; + OneKCmds := 'ABCDEFGH'; + END + ELSE + BEGIN + UserCmds := ',A-C,E,H'; + OneKCmds := 'ABCEH'; + END; + END; + NL; + Prt('Modify '+EventTypeStr+' event: (1-9'+UserCmds+',Q=Quit): '); + OneK(Cmd1,'Q123456789'+OneKCmds); + IF (Cmd1 IN ['2','4'..'9','E'..'G']) THEN + NL; + CASE Cmd1 OF + '1' : BEGIN + ToggleEventFlag(EventIsExternal,EFlags); + Changed := TRUE; + END; + '2' : BEGIN + Prt('New description: '); + Mpl(32); + InputWn1(EventDescription,32,[],Changed); + END; + '3' : BEGIN + ToggleEventFlag(EventIsActive,EFlags); + Changed := TRUE; + END; + '4' : IF (EventIsExternal IN EFlags) THEN + BEGIN + ToggleEventFlag(EventIsSoft,EFlags); + Changed := TRUE; + END + ELSE + BEGIN + Prt('Schedule: (D:aily,M:onthly,Q:uit): '); + OneK(Cmd1,'QDM'); + CASE Cmd1 OF + 'D' : BEGIN + IF (EventIsMonthly IN EFlags) THEN + Exclude(EFlags,EventIsMonthly); + REPEAT + NL; + Print('Active Days: '#3'5'+DActive(EventDays)); + NL; + Prt('Toggle day: (1:Mon,2:Tue,3:Wed,4:Thu,5:Fri,6:Sat,7:Sun,Q:uit): '); + OneK(Cmd1,'Q1234567'); + IF (Cmd1 <> 'Q') THEN + IF (StrToInt(Cmd1) - 1 IN EventDays) THEN + Exclude(EventDays,StrToInt(Cmd1) - 1) + ELSE + Include(EventDays,StrToInt(Cmd1) - 1); + UNTIL (Cmd1 = 'Q') OR (HangUp); + Cmd1 := #0; + END; + 'M' : BEGIN + IF NOT (EventIsMonthly IN EFlags) THEN + Include(EFlags,EventIsMonthly); + InputByteWC('Day of the month',EventDayOfMonth,[],1,31,Changed); + END; + END; + Cmd1 := #0; + END; + '5' : IF (EventIsExternal IN EFlags) THEN + BEGIN + Prt('Excution method: (S:hell,E:rrorlevel,Q:uit): '); + OneK(Cmd1,'QSE'); + CASE Cmd1 OF + 'S' : BEGIN + IF NOT (EventIsShell IN EFlags) THEN + Include(EFlags,EventIsShell); + NL; + Prt('Shell file: '); + Mpl(8); + InputWn1(eventshellpath,8,[upperonly],Changed); + END; + 'E' : BEGIN + IF (EventIsShell IN EFlags) THEN + Exclude(EFlags,EventIsShell); + TempB := 255; + InputByteWc('Error Level',TempB,[],0,255,Changed); + EventErrorLevel := TempB; + END; + END; + Cmd1 := #0; + END + ELSE + BEGIN + Prt('Event Start Time (HH:MM): '); + Mpl(5); + Input(TempS,5); + IF (TempS <> '') AND (Length(TempS) = 5) AND (Pos(':',TempS) = 3) THEN + BEGIN + TempW := StrToInt(Copy(TempS,1,2)); + TempW1 := StrToInt(Copy(TempS,4,2)); + IF (((TempW * 60) + TempW1) >= 0) AND (((TempW * 60) + TempW1) <= 1440) THEN + BEGIN + EventStartTime := (TempW * 60) + TempW1; + Changed := TRUE; + END + ELSE + BEGIN + NL; + Print(#3'5Invalid time - Format is HH:MM (24 hour military)'); + END; + END; + NL; + Prt('Event Finish Time (HH:MM): '); + Mpl(5); + Input(TempS,5); + IF (TempS <> '') AND (Length(TempS) = 5) AND (Pos(':',TempS) = 3) THEN + BEGIN + TempW := StrToInt(Copy(TempS,1,2)); + TempW1 := StrToInt(Copy(TempS,4,2)); + IF (((TempW * 60) + TempW1) >= 0) AND (((TempW * 60) + TempW1) <= 1440) THEN + BEGIN + EventFinishTime := (TempW * 60) + TempW1; + Changed := TRUE; + END + ELSE + BEGIN + NL; + Print(#3'5Invalid time - Format is HH:MM (24 hour military)'); + END; + END; + END; + '6' : IF (EventIsExternal IN EFlags) THEN + BEGIN + Prt('Schedule: (D:aily,M:onthly,Q:uit): '); + OneK(Cmd1,'QDM'); + CASE Cmd1 OF + 'D' : BEGIN + IF (EventIsMonthly IN EFlags) THEN + Exclude(EFlags,EventIsMonthly); + REPEAT + NL; + Print('Active Days: '#3'5'+DActive(EventDays)); + NL; + Prt('Toggle day: (1:Mon,2:Tue,3:Wed,4:Thu,5:Fri,6:Sat,7:Sun,Q:uit): '); + OneK(Cmd1,'Q1234567'); + IF (Cmd1 <> 'Q') THEN + IF (StrToInt(Cmd1) - 1 IN EventDays) THEN + Exclude(EventDays,StrToInt(Cmd1) - 1) + ELSE + Include(EventDays,StrToInt(Cmd1) - 1); + UNTIL (Cmd1 = 'Q') OR (HangUp); + Cmd1 := #0; + END; + 'M' : BEGIN + IF NOT (EventIsMonthly IN EFlags) THEN + Include(EFlags,EventIsMonthly); + InputByteWc('Day of the month',EventDayOfMonth,[],1,31,Changed); + END; + END; + Cmd1 := #0; + END + ELSE + BEGIN + ToggleEventFlag(EventIsPermission,EFlags); + Changed := TRUE; + END; + '7' : IF (EventIsExternal IN EFlags) THEN + BEGIN + Prt('Event Start Time (HH:MM): '); + Mpl(5); + Input(TempS,5); + IF (TempS <> '') AND (Length(TempS) = 5) AND (Pos(':',TempS) = 3) THEN + BEGIN + TempW := StrToInt(Copy(TempS,1,2)); + TempW1 := StrToInt(Copy(TempS,4,2)); + IF (((TempW * 60) + TempW1) >= 0) AND (((TempW * 60) + TempW1) <= 1440) THEN + BEGIN + EventStartTime := (TempW * 60) + TempW1; + Changed := TRUE; + END + ELSE + BEGIN + NL; + Print(#3'5Invalid time - Format is HH:MM (24 hour military)'); + END; + END; + END + ELSE + BEGIN + ToggleEventFlag(EventIsChat,EFlags); + Changed := TRUE; + END; + '8' : IF (EventIsExternal IN EFlags) THEN + BEGIN + (* + IF (EventOffHookTime) THEN + EventOffHookTime := FALSE + ELSE + BEGIN + InputByteWc('Minutes before Event to take phone OffHook',eventpretime,[],0,255,3,Changed,TRUE); + EventOffHookTime := TRUE; + END; + *) + END + ELSE + BEGIN + Print('Message/@File if the user is effected by the event'); + Prt(': '); + InputWn1(EventQualMsg,64,[],Changed); + END; + '9' : IF (EventIsExternal IN EFlags) THEN + BEGIN + (* + IF (EventLastDate = DateStr) THEN + EventLastDate := NextDay(EventLastDate) + ELSE + EventLastDate := DateStr; + *) + END + ELSE + BEGIN + Print('Message/@File if the user IS NOT effected by the event'); + Prt(': '); + InputWn1(EventNotQualMsg,64,[],Changed); + END; + 'A' : IF NOT (EventIsExternal IN EFlags) THEN + BEGIN + IF (BaudIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,BaudIsActive); + LoBaud := 300; + HiBaud := 19200; + END + ELSE + BEGIN + Include(EFlags,BaudIsActive); + InputLongIntWoc('Baud lower limit',LoBaud,0,65535); + InputLongIntWoc('Baud upper limit',HiBaud,0,65535); + END; + Changed := TRUE; + END; + 'B' : IF NOT (EventIsExternal IN EFlags) THEN + BEGIN + IF (SlIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,SlIsActive); + LoSl := 'S0'; + HiSl := 'S255'; + END + ELSE + BEGIN + Include(EFlags,SlIsActive); + (* + InputByteWoc('SL lower limit',LoSl,0,255); + InputByteWoc('SL upper limit',HiSl,0,255); + *) + END; + Changed := TRUE; + END; + 'C' : IF NOT (EventIsExternal IN EFlags) THEN + BEGIN + IF (DslIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,DslIsActive); + LoDsl := 'd0'; + HiDsl := 'd255'; + END + ELSE + BEGIN + Include(EFlags,DslIsActive); + (* + InputByteWoc('DSL lower limit',LoDsl,0,255); + InputByteWoc('DSL upper limit',HiDsl,0,255); + *) + END; + Changed := TRUE; + END; + 'D' : IF NOT (EventIsExternal IN EFlags) THEN + IF (EventIsPermission IN EFlags) THEN + BEGIN + IF (TimeIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,TimeIsActive); + MaxTimeAllowed := 60; + END + ELSE + BEGIN + Include(EFlags,TimeIsActive); + InputWordWoc('Maximum time allowed on-line (minutes)',MaxTimeAllowed,0,65535); + END; + Changed := TRUE; + END; + 'E' : IF NOT (EventIsExternal IN EFlags) THEN + BEGIN + IF (ArIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,ArIsActive); + ArFlagRequired := #0; + END + ELSE + BEGIN + Include(EFlags,ArIsActive); + Prt('AR flag required (A-Z): '); + Mpl(1); + OneK(Cmd1,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + ArFlagRequired := Cmd1; + Cmd1 := #0; + END; + Changed := TRUE; + END; + 'F' : IF NOT (EventIsExternal IN EFlags) THEN + IF (EventIsPermission IN EFlags) THEN + BEGIN + IF (SetArIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,SetArIsActive); + SetArFlag := #0; + END + ELSE + BEGIN + Include(EFlags,SetArIsActive); + Prt('AR flag to set (A-Z): '); + Mpl(1); + OneK(Cmd1,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + SetArFlag := Cmd1; + Cmd1 := #0; + END; + Changed := TRUE; + END; + 'G' : IF NOT (EventIsExternal IN EFlags) THEN + IF (EventIsPermission IN EFlags) THEN + BEGIN + IF (ClearArIsActive IN EFlags) THEN + BEGIN + Exclude(EFlags,ClearArIsActive); + ClearArFlag := #0; + END + ELSE + BEGIN + Include(EFlags,ClearArIsActive); + Prt('AR flag to clear (A-Z): '); + Mpl(1); + OneK(Cmd1,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + ClearArFlag := Cmd1; + Cmd1 := #0; + END; + Changed := TRUE; + END; + 'H' : IF NOT (EventIsExternal IN EFlags) THEN + BEGIN + IF (InRatioIsActive IN EFlags) THEN + Exclude(EFlags,InRatioIsActive) + ELSE + Include(EFlags,InRatioIsActive); + Changed := TRUE; + END; + END; + UNTIL (Cmd1 = 'Q') OR (HangUp); + IF (Changed) THEN + BEGIN + Seek(EventFile,SaveRecNum1); + Write(EventFile,Events); + Changed := FALSE; + END; + END; + END; + END; + +BEGIN + Reset(EventFile); + REPEAT + CLS; + (* + TStr(419); + *) + Abort := FALSE; + RecNum := 1; + WHILE (RecNum <= NumEvents) AND NOT (Abort) AND NOT (HangUp) DO + BEGIN + Seek(EventFile,RecNum); + Read(EventFile,Events); + WITH Events DO + PrintaCr(PadRightInt(RecNum,3)+ + ' '#3'2'+PadRightStr(AOnOff(EventIsActive IN EFlags,'YES','NO'),6)+ + ' '#3'5'+PadRightStr(EventDescription,32)+ + ' '#3'3'+AOnOff(EventIsExternal IN EFlags,'External','Internal')+ + (* + ' '#3'0'+ShowTime(EventStartTime)+ + *) + (* + ' '#3'0'+AOnOff(EventIsExternal in EFlags,'-----',ShowTime(EventFinishTime))+ + *) + ' '#3'4'+AOnOff(EventIsMonthly IN EFlags,'Day = '+IntToStr(EventDayOfMonth),DActive(EventDays))); + Inc(RecNum); + END; + IF (NumEvents = 0) THEN + Print('No Events Defined.'); + NL; + Prt('Event Editor: (D:elete,I:nsert,M:odify,Q:uit): '); + OneK(Cmd,'QDIM'); + CASE Cmd OF + 'D' : BEGIN + RecNum := -1; + InputIntegerWoc('Event number to delete',RecNum,1,NumEvents); + IF (RecNum <> -1) THEN + BEGIN + Seek(EventFile,RecNum); + Read(EventFile,Events); + NL; + Print('Event: '+Events.EventDescription); + NL; + IF PYNQ('Are you sure you want to delete it',0) THEN + EventRecordDelete(RecNum); + END; + END; + 'I' : IF (NumEvents = MaxEvents) THEN + BEGIN + NL; + Print('No more then '+IntToStr(MaxEvents)+' events can exist.'); + PauseScr(FALSE); + END + ELSE + EventRecordInsert(FileSize(EventFile)); + 'M' : EventRecordModify(RecNum); + END; + UNTIL (Cmd = 'Q') OR (HangUp); + Close(EventFile); +END; + +END. + diff --git a/SOURCE/UNUSED/SYSOP7.TPU b/SOURCE/UNUSED/SYSOP7.TPU new file mode 100644 index 0000000000000000000000000000000000000000..a8d9a1ac5fb8ece254737efe896f11131f35e888 GIT binary patch literal 25616 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 G{eJ+fX)uET literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/SYSOP8.TPU b/SOURCE/UNUSED/SYSOP8.TPU new file mode 100644 index 0000000000000000000000000000000000000000..1fa1695e53a018876a09ee525581fe85b37711b7 GIT binary patch literal 46752 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%0Af^lf1 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 R{FeAUuK7Dc8!3A~{}-x3LkIu> literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/TAGLINE.DAT b/SOURCE/UNUSED/TAGLINE.DAT new file mode 100644 index 0000000..b5afb08 --- /dev/null +++ b/SOURCE/UNUSED/TAGLINE.DAT @@ -0,0 +1 @@ +J12345678901234567890123456789012345678901234567890123456789012345678901234 \ No newline at end of file diff --git a/SOURCE/UNUSED/TAGLINE.EXE b/SOURCE/UNUSED/TAGLINE.EXE new file mode 100644 index 0000000000000000000000000000000000000000..33d04d9e36774b91baa1f3c0644ca73e0e2a9c32 GIT binary patch literal 7424 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 Ar2qf` literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/TAGLINE.PTR b/SOURCE/UNUSED/TAGLINE.PTR new file mode 100644 index 0000000000000000000000000000000000000000..db3ae0ebfc800d27e08015e7dab27cd5c9e79928 GIT binary patch literal 17472 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 (A)bort, (R)etry, (O)verthrow System +Anatomically Correct beats Politically Correct any day. +Ancient Chinese curse:"May you live in interesting times" +Ancient Evil In Training +And now for something completely different. +And now we return you to your (ir)regular conference... +And on the 8th Day God said, "Murphy, you're in charge." +And Satan said to God,"But where will you get a lawyer?" +And she disappeared in a puff of logic. +and that is how we know the Earth is banana-shaped +and then the fun began - N. Bonaparte +And then you typed 'G=C800:5', right? +And they said unto Jesus, "How the Hell did you do that?! +And who decides what is just? Who decides what is right? +and you were expecting something profound & witty? +And, pray tell, whose imagination are you a figment of? +Angels and ministers of grace offend us! -- Snakespeare +Annoy a liberal: Ask them to be truthful. +Another casualty of the seduction of art. - Hobbes +Another good mind not yet ruined by higher education! +Antelope Freeway, 1/64 mile. +Antifloccinaucinihilipihilificationism rules ok! +Any priest or shaman may be presumed guilty until proved innocent. - RAH +Any sufficiently advanced magic looks like technology! +Any system that relies on human reliability is unreliable +Anybody seen the internet around here? +Anyone ever found a use for those tractor feed cutouts? +Anyone who says he can see through women is missing a lot +Anything free is worth what you pay for it. +Anything not a constant, is not a commandment from God. +Anything that kills you makes you... well, dead. +Anything you say will be misquoted and used against you. +Apathy Error: Don't Bother Striking Any Key +Applicants wanted! - Darth Vader School of Management +Archaeologist: one whose career lies in ruins +Are the noises in my head bothering you? +Are you implying that coconuts are migratory? +Are you suggesting that coconuts are migratory? +Are you telling me a 686DX/200 is ALL you got ? +Are you using Windows, or is that just an XT? +Argue if you must, just remember I'm right +Arguments with furniture are rarely productive. +Artificial Intelligence is no match for Natural Stupidity +As confused as a termite in a yo-yo +As of next week, passwords will be entered in Morse code. +Ask me anything: if I don't know, I'll make up something. +Ask me no questions, I'll tell you no lies... +Asphault = Proctologist's malpractice insurance +Assist: v. To increase the factor of incompetency by 1. +Assumption is the mother of all screwups. +At last, the Eludium Q36 explosive space modulator +Atheism is a non-prophet organization. +Attend Miskatonic U. - Why study >lesser< evils? +Auntie Em: Hate you, Hate Kansas. Taking the dog. +Auntie Em: Hate you. Hate Kansas. Took the Dog. Dorothy. +Avoid hangovers - stay drunk +Avoid morning breath... Sleep till noon! +Avoidence - Surrender, Confrontation - Attack +Ay, every inch a king. - King Lear +B: not found, formatting other drives instead.... +Back from the shadows again ... +Back off man, We're scientists!!! +Backup aborted: Please remove disk #92 and start over... +Backup Initiated: Insert disk 1 of 1362. +Backup not found: (A)bort (R)etry (P)anic +Bad Command or Filename. Or maybe you screwed up. +Bagpipes are just Hell's way of giving hints. +Ban the bomb. Save the world for conventional warfare. +Barney:What happens when you feed a smurf after midnight. +Basic programmers never die, they gosub and don't return. +Basic Vampire: If it screams, it's not food... yet. +Bathing beauty: A girl worth wading for +BBS: a method to triple your phone bill. +Be creative - invent a perversion! +Be moderate in all things, including moderation... +Be spontaneous.......combust. +Beam me up, Scotty; this ISN'T the ladies' room! +Beam's Choice Green Label -- It's SMOOTH!!!! +Beauty is in the eye of the beer holder..... +Been there, done that, got the mouse mat. +Been there. Done that. Jumped bail. +Been through Hell?? and what did you bring me?? +Beer is Better: Beer is always in season. +Beer. It's not just for breakfast anymore! +BEERWARE: If it works, buy yourself a beer. +Before making a backup copy, first destroy the original +Before you see the light, you must die. +Beheading: The ultimate loss of face. +Behind every successful man--a surprised mother-in-law. +Being common isn't one of my strengths. +Being human does have certain advantages. +Being ignorant isn't your fault, staying ignorant is. +Being in beta means never having to say you're sorry. +Being paranoid doesn't mean they aren't out to get you. +Believe the road goes on forever and the party never ends. +Ben Dover & C. Howit Feels -- Attorney's at law +Best cure for a case of nerves is a case of beer. +Best file compression around! "DEL *.*" - 100% comp. +Best thing about the future: it comes one day at a time. +Better taglines through confiscation. +Better than a poke in the eye with a stick. +Between two evils, always pick one you never tried before +Beware False Messengers, and Trust Only Your Enemies. +Beware of a tiger in its lair or a moderator in his echo +Beware of programmers who carry screwdrivers. +Beware! This is a dangerous product, manuals required. +Big or small We tax them all. +Big toe: Feature on man to accommodate coroner's tag. +Bigomy: one wife too many. Monogamy: same idea. +Bigot: Anyone who's winning an argument with a liberal +Bill your doctor for the time spent in the waiting room +Billy Bob's Road Kill Cafe - You kill'em, we grill'em. +Bio-Genetix Eng. Labs: "Playing God so you don't have to" +Birds of a feather fluck together. +Black holes are big attractions. +Black Holes are what happens when God divides by Zero +Black holes suck. +Blended coffee...todays & yesterdays. +Blessed are the censors: For They Shall Inhibit the Earth +Blessed are the censors; they shall inhibit the earth. +Blessed are the meek, for they make great scapegoats. +Blessed are the pessimists, for they hath made backups +Blood is thicker than water, and much tastier. +Blow, winds, and crack your cheeks! Rage! Blow! +Bluff means never having to sway your story. +Bo knows your girlfriend..... +Boring women have immaculate homes +Bork was a dork... that's not too political, is it? +Borrow money from pessimists. They don't expect it back. +Bought some powdered water.....What do I add?? +Boy, this Soylent Green tastes great! What's the recipe? -SLR +Brain damage? No thanks, I already have some. +Brain Disengaged; Call Back Tomorrow. +Brain the size of a planet and I have to talk to humans. +Brains...BRAINS! Fresh brai... oh, wrong conference. +Breaking Windows isn't just for kids anymore... +Bring on the dancing girls! +Bring order to your life, use random numbers. +Brought to you by your local SPAM Appreciation Society. +BS (bee ess): n. An uninformed statement. +Budweiser: Breakfast of Champions +Bug removal Tagline. Bang forehead here to debug---->@@ +Bureau of Natural Disasters - Planning Division +Burn the flag. Burn the bra. Burn the bridges behind you. +Burned out but still glowing! +Burning houses simply helps keep me from going Sane, Doc. +But honey, we can afford it, I sold your car +But Honey, you NEED VGA for Dbase management! +But I thought YOU did the backups! +Butcher the Intelligensia in the name of Sanity! +Buy a Pentium so you can reboot Windows faster! +Buy OS/2: Keep Bill Gates on his toes. +By all means, let's not confuse ourselves with the facts. +By Pendragon's sword the Dark shall fall. +C A U T I O N - I drive the same way you do. +C program run. C program crash. C programmer quit. +C-4 works much better than a hammer when things get stuck +C:\CATHOLIC\VATICAN.EXE: Okay program, but no updates, _ever_. +C:\DAMSEL.EXE x-linked with DISTRESS.COM. RESCUE? (y/n?) +Caffeine is my only *real* friend... +CALCULUS..... the agony and dx/dt. +Call me Ishmael. I won't ANSWER, but.. +Calm down. It's only ones and zeros. +Can I trade in this life for a full refund? +Can you believe that thing is STILL moving? +Can you hold this grenade a second, I dropped the pin... +Can you repeat the part after "Listen very carefully" +Canadian Dos prompt= "Like,Insert Disk #1,eh" +Cannibals send out for pizza boys. +Carefull, we might be landing on your street +Carpenter's Rule: Cut to fit; beat into place. +Catch the Blue Wave! +Cats--the ultimate agents of Entropy. +Caution: I drive using The Force +CCITT- Can't Conceive Intelligent Thoughts Today +Cease & Desist citizen, or I'll reduce your head to a fine mist. +Celebrate your freedom: Read a banned book. +Celtic Magic? Didn't he play basketball??? +Cement shoes, dirt cheap; ask for Guido. +Chance makes our parents, but choice makes our friends. +Change is inevitable...except from a vending machine. +Chaotic Evil means never having to say your sorry. +CHASTITY: The most unnatural of sexual perversions. +Chat mode is DISABLED during Quantum Leap +Cheap fuses are protected by expensive chips +Cheer Up! Things are getting worse at a slower rate. +Chef: (shef) A cook who swears in French. +Chicago: Vaporware of the desperate and scared +Children: the most common sexually transmitted disease. +Chile today. Hot tamale. +Chili, the national food ... Fart, the national odor. +Chivalry is not dead - it's on life support. +Choking on another Xanth novel? Try the Heinlein Maneuver +Christmas is coming, the geese are getting *very* worried +Chthulhu calls his shots. +CIA Motto: In God we trust, all others we polygraph +City Morgue: You stab 'em, we slab 'em. +Clean this stuff up or we'll all wind up in jail! +Climate is what we expect. Weather is what we get. - Heinlein +Clowns to the left of me, Jokers to the right, here I am. +CMOS: Commonly Misunderstood Option Switches +Cold as Night, Dark as Death +College is just high school with ashtrays... +College's don't make fools; they only develop them +Columbus HAD a fourth ship--it sailed over the edge. +Combat gear doesn't make a man..... +Come on Mr. Krinkle tell me why... +Come on! There's plenty of room out here on this limb! +Command Not Understood. . . Now erasing Hard Drive +Commercial Software - The Devils payback! +Committee: a lifeform with 12 legs and no brain. +Communism is like one big phone company. +Compile, run, curse. Recompile, rerun, recurse. +Computer Excuse #3: Systems analyst needs psychoanalyst +Computer Hacker Wanted. Must have own axe. +Confuse your local coroner ... die happy. +Congress Virus: Overdraws disk space, won't release files +Congress's road to h*ll is now a 4 lane highway +Congress:"They have what it takes to take what you got" +Conspiracy can never replace simple stupidity. +Consult with a real expert - Call your mother. +Consult with an Expert - Call your Mother. +CONSULTANT: Person who makes good on salesman's promises +Contains less than 2% U.S. RDA for this echo +Contraceptives: to be used on all conceivable occasions. +Cover me. I'm going to change lanes. +Crackpot can't play, he's working on his thesis. +Cream rises to the top... but then, so does scum... +Create opportunities week. Blackmail a senior executive. +Creativity is great, plagiarism's faster. +Crime wouldn't pay if the government ran it. +Crime, Sex, Alcohol, Drugs... God, I love Congress! +Criminal lawyer?...Isn't that redundant? +Crossbows don't kill people; quarrels kill people. +Cry "ribbit" and let slip the frogs of war! +Cthulhu calls.........COLLECT! +Cthulhu in '96: why settle for the LESSER evil? +Cthulhu loves you...on a Ritz cracker. +Cthulhu loves you...on a sesame bun. +Cthulhu loves you...with a tossed salad and white wine. +Cthulhu loves you...with an apple in your mouth. +Cthulhu Saves! ... in case he's hungry later. +Cthulhu saves... passes to Hastur... the crowd goes mad!! +Cthulu for President: Why settle for the Lesser Evil?? +Cthulu fthagn! Cthulu fthagn! Cthulu fthagn! Oh, wow, that really ... +Cure for postal strikes: mail them their strike pay. +Curiosity didn't kill the cat, my 12 gauge did.. +Curiosity didn't kill the cat. I got `em with the mower! +Curiosity killed the cat, but for a while I was a suspect +Cursor: What you become when your system crashes. +Custer was fitted for an Arrow shirt. +Cut my pizza into six pieces please. I can't eat eight. +cyberpunk (si'-ber-punk) n. - a computer with an attitude +Damn it Jim, I'm an Alzheimer's patient, not a...uh...uh. +Damn the documentation, full speed ahead! +Darth Vader: Robert Dole's long-lost half brother. +Dawn: The time when people of reason go to bed. +Dead reckoning: The method of navigation by a driver. +Death before dishonor and either before soap operas. +Death before dishonor, neither before breakfast. +Death Comes as the end... +Death is not the end; there remains the litigation. +Death, Life, and Infinite are the only constants. +Decadent Capitalist and proud of it! +Deep down...I'm really a pretty superficial kind of guy. +Def. of a beetle : A fly on steroids. +Def. of Upgrade: Take old bugs out, put new ones in. +Defeat may test you. It need not stop you. +Define the universe. Give three examples. +Deicide - The Extinction of All That's Holy........ +Democracy-A catchword used by Democrats and Republicans +Demons are a Ghouls best Friend. +Deny everything - remove all evidence - & make counter-accusations! +Department of Redundancy Department +Desperate times call for cheap shots. +Despite the high cost of living, it remains popular. +Detour: The roughest distance between two points. +Diagonally parked in a parallel universe. +Did you hear that? They've shut down the main reactor! +Didn't I meet you in some other hallucination?? +Die: To stop sinning suddenly. +Difference between a virus & windows? Viruses never fail. +Difference between Genius & Stupidity? Genius has limits. +Digital circuits are made from analog parts. +Dime: a dollar with all the taxes taken out. +Ding, Dong the Lich is dead +Dip it in chocolate, it'll be fine. +Diplomacy is saying "nice doggy" until you find a rock. +Diplomacy: The art of letting someone else get your way. +Diplomacy: The patriotic lying for one's country. +Dirty Old Men: Men who haven't quite given up women yet.. +Disclose classified information only when a NEED TO KNOW +Discoveries are made by not following instructions, +Divers do it deeper and stay down longer. +Divorce is not an effective deterrent to marriage. +Do cross-eyed dyslexics read normally? +Do Files get embarassed when they are unzipped? +Do I even WANT ancestors? Some of those I found I wish I could lose. +Do I ice her? Do I marry her? Which wunna deez? +Do it tommorrow. You've made enough mistakes for one day +DO NOT ADJUST YOUR MIND - the fault is with reality. +Do Not Attempt to Traverse a Chasm in Two Leaps +Do not look in laser with remaining eye. +Do unto others BEFORE they do unto you! +Do Winchesters sneeze when they catch a virus? +Do you multitask or just run Windoze? +Do you prefer gin and platonic or scotch and sofa? +Docs? We don need no stinkeeng docs! +Docs? Who wants to look at the Docs. Nurses are better... +Docs? Why would I want to look at the Docs. Nurses are better :) +Doctors bury mistakes. Architects plant ivy. +Documentation - The worst part of programming. +Documentation is for people who can't read. +Documentation is for wimps who cant read listings or the object code. +Does "PIRATE" software come with a treasure map? +Does a Kzin fear to follow where a Puppeteer leads? +Does history record any case in which the majority was right? - Heinlein +Does killing time harm eternity? +Does Microsoft mean "small and limp"? +Does the term 'Rational Anarchist' ring a bell? +Doing strange things in the name of art. +Don't 'yield' to temptation. Go and hunt it down... +Don't be sexist. Broads hate that. +Don't be silly... of course we'll survive... +Don't be stupid; of *course* we intend to resist you! +Don't bother pressing that key. There is no Esc. +Don't bother pushing that key. There is no Esc +Don't call me a sexist, you bimbo! +Don't call me ignorant, you supercilious twit. +Don't confuse me with facts. +Don't crush that dwarf, hand me the pliers! +Don't drink and park...Accidents cause people. +Don't give me that "kinkier than thou" attitude ...! +Don't just stand there...KNEEL!! +Don't let me get too deep. It's already too deep in here. +Don't let school interfere with your education. +Don't look at me in that tone of voice! +Don't look conspicuous-it draws fire. +Don't look for flaws as you go through life. +Don't meddle in the affairs of Wizards... +Don't mess with the Zombie, @TO@ +Don't push it, you fool! That's the History Eraser button! +DON'T read the manual! Just WING that sucker! +Don't run away, it's only me... +Don't steal...the government hates competition. +Don't take criticism from just anybody. +Don't take life seriously...it isn't permanent. +Don't take life seriously; You won't get out alive anyway +Don't take life so seriously. It's not forever. +Don't tell me how hard you work. Tell me how much you get +Don't try to have the last word. You might get it. - Heinlein +Don't use a big word where a diminutive one will suffice. +Don't vote - it only encourages them. +Don't worry . . . everything is out of control +Don't worry, I'm fluent in weirdo +Don't worry, Inspector. Just a swamp cult, no big deal... +Don't worry... It's under warranty. +Dorothy- hate OZ, took shoes, find your own way home Toto +DOS Perot: you boot, it decides whether it wants to run. +Dracula was a vein man... +Drag me, drop me. Treat me like an object. +Dragon? What dragon? You said we were looking for a worm. +Dragons: Friendly Toasters. +Drilling for oil is boring. +Drink till she's cute. Stop before you get married. +Drink your coffee! There are people in India sleeping. +Drive A: format failed. Restarting with drive C:. +Drive defensively. Buy a tank. +Drugs: n - Substance Programmers use while programming. +Duct tape, not The Force, holds the universe together. +Dude did you see her? I think I'm pitching a tent! +Due to inflation, all clouds will now be lined with zinc. +Dumb luck beats sound planning every time. Trust me. +Dusk lures like a lyre beckoning the quietude +Dyslexics of the world untie! +Early to bed, early to rise; makes people suspicious. +Earn cash in your spare time -- blackmail your friends. +Earth is 98% full...please delete anyone you can. +Earth: mostly harmless. +Eat Healthy, Exercise, and Die Anyway... +Eat more lamb. 10,000,000 coyotes can't all be wrong. +Eat the rich - the poor are tough and stringy. +Eat yogurt and get cultured. +Egad, I believe I've blown another synapse. -SLR +ELECTROCUTION : High Tech Burning at the Stake! +Employees are instructed to restrict their orgasms to the lunch hour. +End rush-hour traffic now! Legalize vehicular weaponry! +Enter any 12-digit prime number to continue. +Equal Opportunity: The prospect of pillage for the meek +EROTIC: using a feather. KINKY: using the whole duck! +Eternity? Straight ahead, turn left at infinity. +Ettore's law: the other line always moves faster +Eval Day 1,094,583,217 * I Support Shareware! +Eval Day 15 * Assimilate culture? (Y/n) +Even after fusion, confusion remains. +Even Ockham occasionally cut himself shaving. +Even the boldest zebra fears the hungry lion. +Ever meet a Sysop who would admit the problem was his? +Ever notice how much Cheeze Whiz resembles silicone caulking? +Every absurdity has @TO@ to defend it. +Every absurdity has a champion to defend it. +Every child should be given the desire to learn. +Every girl's crazy 'bout a sharp dressed man. +Every morning is the dawn of a new error... +Every saint has a past and every sinner a future - Wilde +Every Silver lining has a clone around it. +Every solution breeds new problems. +Every sun has a golden lining +Every time a Country singer dies, ten more pop up. +Every time I use a MicroSoft product I feel "dirty." +Everybody lies about sex. - Robert A. heinlein +Everybody loves a moose; they just don't know it. +Everybody must believe - I believe I'll have another beer +Everyone has a photographic memory, some just don't have any film. +Everyone hates me because I'm paranoid. +Everyone is entitled to my opinion. +EVERYONE is weird...some of us are proud of it. +Everything @TO@ does is needlessly violent. +Everything flows and nothing stays. -- Heraclitus +Everything I do is needlessly violent. +Everything I like is illegal, immoral or expensive! +Evolution is God's way of issuing updates. +Excuse me while I change into something more formidable. +Excuse me while I crouch down behind my asbestos shield. +Excuse me, did you say something? +Exercise before kinky sex . . . be fit to be tied. +Experience is directly proportional to ruined equipment +Experience=a name everyone gives to his mistakes. +Experiencing synaptical difficulties; Please stand by. +Explain counter-clockwise to someone with a digital watch +Extinct species will never be Born Again. +Extra Credit: Define the universe. Give 3 examples. +Extreme Conditions Demand Extreme Responses. +Exxon - greasing the coastline for smoother boating! +Eye of newt, toe of frog, and a side order of fries +Face reality; yet, indulge yourself in fantasy and fairy tales. +Fact. Stranger than any science fiction. +Facts, though interesting, are irrelevant. +Fahr-ferg-nug-en: German for "Can't afford the Mercedes." +Failure reading left hemisphere bort etry rolic? +Failure: The path of least persistence. +Falling ego zone. Keep ID covered at all times. +Famous Last Words - "The backups can wait." +Famous Last Words: Look, I'm driving with my eyes closed! +Famous words, "Trust me, I'm a consultant" +Fanatics do everything with unmatched dedication. +Fasten your seat belt--I wanna try something. +Faster horses, Younger women, Older whiskey, More Money! +Fatal Error: Size Of Thought Exceeds Available Memory. +Fatal Error: User Executed +Fear not, for I have given you authority +Fear the Stark Fist of Removal. +Features should be discovered, not documented +Feel lucky???? Update your software! +Few hours in life are more agreeable than afternoon tea +Fight crime....shoot back +Fight Crime: Shoot a politician +File not found. Delete *.* and change directory? (Y/N)_ +Fingers not found - Pound head on keyboard to continue. +Finish the project. We'll buy you a new family. +First listen to sermon, THEN eat missionary. +First rule of adaption: only when evolving. +First rule of marriage: If YOU'RE Right, APOLOGIZE FAST! +First, push the button. Then find out what it does. +First, we'll kill all the programmers +Flying is not dangerous.... CRASHING is dangerous. +Food, glorious food. Hot sausage with mustard.... +Fools fight one another, but wise men agree together. +For a good time, don't call me. +For all my dreams are haunted by a fire on the moon. +For God's sake get the hell off... she's dead, Jim! +For Reply, send a self-abused stomped Antelope to... +FOR SALE: Used Dyson sphere, needs work. Priced to sell. +For sincere personal advice, page your sysop at 3 A.M. +For those who like peace & quiet: a phoneless cord. +For yerz ago i cudent evin spel injuneer. Now i are one +Forego novocaine: Transcend dental medication. +Forget patience! I'm gonna kill something... +Forget the manual, phone the author at home! +Forgive your enemies but never forget their faces +FREE PRIZE! NO PURCHASE NEEDED! (Details inside box) +Friends come and go, but enemies accumulate. +Friends don't let friends use Prodigy +Friends: People who dislike the same people we do. +From IRS Agents that go bump in the night, deliver us. +From the pastor of the 1st Church of Electron Flux +Fun with Greek #4: Fee, , fo, fum! +Funny how life imitates LSD... +Funny, only sensible people agree with me. +Furry Weddings are were "groom" is a verb, not a noun +Gargling twice daily is a good way to see if your neck leaks. +Gee, Mr. Wizard! Aren't nuclear reactors dangerous? +Geee, is that what static electricity does to cpu chips? +Genetic engineering: heir styling. +Genius is ten percent inspiration and 50% capital gains. +Gentleman: One who can play bagpipes but chooses not to. +Get a taste of religion. Bite a preacher. +Get the facts first - you can distort them later ! +Getting caught is the mother of invention. +Ghosts are merely unsubstantiated roomers. +Gimme $50 Or I'll Call Your Religion A Cult. +Gimme a match, I think my gas tank is empty. +Give 'em a fair trial, then hang 'em! +Give me a gun and I'll kill all the liberals. +Give my lawfirm a call sometime: Dewey, Cheetum & Howe. +Give sadists a fair crack at the whip. +Give up, you'll only live till you die. +Go ahead, jump. 100,000 lemmings can't be wrong. +Go ahead, speak your mind! I'll enjoy the silence. +Go climb a gravity well. +God created all men. But Sam Colt made them equal. +God created anchovies. Satan put them on pizza. +God fights on the side with the heaviest artilliary.--RAH +God isn't dead, he just couldn't find a parking place. +Good aim means never having to say you're sorry. +Gosh I miss George. Heck, I even miss Jimmy! +Gotta run. My neighbors just sighted Elvis making crop circles. +Government - the only vessel known to leak from the top +Government Tagline. Takes up space, no known function. +Government: we can't do that, it makes too much sense. +Graduate of the Mad Max School of Defensive Driving +Great minds always meet at infinity. +Great minds twist alike. +Great! She's naked and I forgot the rope!! +Great; Custer had a plan, too. +Gross Ignorance: 144 times worse than ordinary ignorance. +Growing old is mandatory... Growing up is optional. +Guilt trips: the nuclear weapon of relationships. +Gun control is not about guns; it's about control. +Gun Control means .174" @ 100yds. +Gun Control means using 2 hands +Gunpowder and alcohol DO mix - but it tastes awful! +Guns don't kill people. I kill people. +Guns don't kill people. Moderators do. +Guns don't kill people. Moderators kill people. +Guns don't kill. Fast-moving projectiles do. +Guru Meditation Error -- Insufficent User +H*LL (n): Backing up a 600 meg drive with 360K floppies +H*ll hath no fury like a woman scorned. +H*ll, if I was sane why would I be here? +Hand me that dolphin burger. Yeah, the one in styrofoam. +Hand me that planet, will you? +Hard Work never killed anyone, so why chance it? +Has that file been saved? No, but we're praying for it. +Have a nice day - unless you've made other plans +Have an affair. It will help break up the monogamy. +Have I ever claimed to be sane? +Have no fear - I never attack lesser beings. +Have you clubbed an ignorant human today? +Have you clubbed an ignorant kitten today? +Have you crashed your Windows today? +Have you hugged an electric fence today? +Haven't you got any pleasant facts I can face? +HD Crash: (A)bort,(R)etry,(S)tart Self-Destruct Sequence +He did say cleared for final ......didnt he ??? +He died to take away your sins, not your mind. +He does the work of 3 Men...Moe, Larry & Curly +He has a train of thought. You have a tricycle... +He has all the charm of a dirty Christmas card. +He isnt dead; He's electroencephalographically challenged +He knows little who will tell his wife all he knows +He ran for the curb but I bagged him before he made it. +He said "KUNG FU!" I said "M-16." He said "Peace Brother" +He stalks to the beat of a violent state of time .. +He was ever greater than his opportunities. +He who dies with the highest upgrade wins. +He who has never hoped can never despair. -- G.B. Shaw +He who hesitates is trampled by the mob. +He who laughs last probably backed up his hard disk... +He who lives by the sword gets shot with a AK47 +He who steps on others to reach the top has good balance. +He'll feel a lot better once we robbed a couple banks. +He's a SOB -- but at least he's *our* SOB. +He's dead Dave, everyone's dead, everyone is dead Dave! +He's dead Jim, kick him yourself and see. +He's dead, Jim; kick him yourself if you don't believe me. +He's not a lousy pilot, he's gravitationaly challenged. +He's not a politician; he's just ethically challenged. +He's not dead, Jim. He's just considering moving to Seattle. +He's not drunk; He's neurologically challenged. +Headline: War dims hope for peace. +Health tip: Red meat IS good. Blue fuzzy meat is BAD. +Heaven doesn't want me & Hell's afraid I'll take over. +Heavy rain: What you get 2 hours after washing your car. +Hee, hee, eees beeg trouble for moose and squirrel... +Heisenberg really wasn't certain about this. +Heisenburg slept here... or did he? +Helicopters don't fly; they beat the Air into Submission. +Hell hath no fury like the lawyer of a woman scorned +Hell hath no fury like vested interest masquerading as moral principle. +Hell hath no misery like a backup ignored. +Hell is empty... but our Congress is full. Hmmm........ +Help fight against a cure for nymphomania. +Help Prevent Birth Defects; Castrate a RedNeck! +Here is my fist, please run towards it very fast. +Here, doggie. Chase the nice stick of dynamite. +Here, you go first, you're immune to bullets. +Hermits have no sense of peer pressure. +Hero for Hire - Dragons Slain. +Hey, buddy ya need a Comp Sci degree? How about a watch? +Hey, Santa, how much for your list of naughty girls? +Hi Ho, Hi Ho, it's Hand Grenades I throw! +Hi! I'm heavily armed, easily bored, & off medication. +Hi, I'm from the government. I'm here to help you. +Hi, Mr. Rex! I'm Barney!...I love you...you love m.....*CHOMP!!!!* +High message: 943432. Message you last read: 59 +Highballing the skyways between the stars +Higher Versions mean more bugs found... +History books which contain no lies are extremely dull. +History Repeats Itself Because Nobody Listens +Hit and run means never having to say you're sorry. +Hmmmmm.... never tried an atomic bomb before. +Ho! Ha! Guard! Turn! Parry! Dodge! Spin! Ha! Thrust! +Ho! Haha! Guard! Turn! Parry! Dodge! Spin! Ha! Thrust! WHACK! +Homeless man's sign: Will be President for Food. +Honest, Officer! The dwarf was on fire when I got here! +Honest, Officer! The smurf was on fire when I got here! +Honey, your IQ test came back. It's negative. +Honk if you like obscene gestures! +Honk if you're illiterate +Honk if you've never seen an Uzi fired from a car window. +Horn broke...watch for finger. +Hostages? What do you mean, I thought they were targets.. +Hot Tip #5: The light at the end of a tunnel is a train +House physician - a misnomer for a carpenter/repairman. +How about a 7-day wait period on buying Congressmen? +How can I miss you if you don't go away? +How come pizza gets to your house faster than the police? +How come this jacket they gave me doesn't have sleeves? +How do we know you really have those magic powers? +How do we know you're the *real* Angel of Death? +How do you call a *very* large cat wearing a rising-sun headband? +How do you pronounce my name? With reverence. +How many cat skeletons does it take to fill a tree? +How the hell does this thing work? +How will banning *MY* firearms reduce crime? +How's "Nuke 'em All!" for strategy? +However subtle the wizard; a knife in the back will cramp his style. +Human Being: An ingenious assembly of portable plumbing. +Humankind cannot bear very much reality. +Hunting is no fun when the rabbit has the gun. +Hush boy, you'll annoy the Overlords. +Hydrogen bombs are great party gags. +I *could* be arguing in my spare time. +I *told* the Muse I'm not a masochist, so why is the whip out again? +I abstain from wine, women and song; mostly song. +I Almost Saw Elvis - Then My Shovel Broke... +I always poach my Rats...lowers the cholesterol... +I always use the goodest English. +I am =NOT= illiterate. I know who my parents are. +I am a man more sinned against than sinning. - King Lear +I am a mental tourist, my mind wanders. +I am committed--or should be. +I am firm. You're stubborn. He's pigheaded. +I am free of all prejudices. I hate every one equally. +I am Ingnio Montoya. You stole my tagline. Prepare to die. +I am not a human! I am an animal! er...wait.. +I am not an animal! I am ... well, not an animal. +I am NOT anthropomorphic! Now get off my tail... +I am not antisocial, I'm just not real friendly... +I am not arguing with you, I'm telling you. +I am not conceited! I just hate mortals. +I am not young enough to know everything... +I am the neurosis that requires a $500-an-hour shrink! +I am the terror that posts in the night. +I am their leader, which way did they go? +I am tolerant of your (fruitcake) beliefs +I am tolerant of your (pagan) beliefs. +I am torn by conflicting apathies. +I became a power user, I bought 30 unformatted floppies. +I believe in the infliction of pain for the sake of art. +I beta test co unication softwFEL87=\d+A$ NO CARRIER +I came, I saw, I had no idea what was going on, so I left +I can count even higher if I take my shoes off. +I can walk on water, but I stagger on alcohol. +I can walk on water...........I stagger on alcohol. +I can't be stupid, I completed third grade! +I CAN'T go to h*ll, they don't want me. +I carry a gun 4 days a week. You guess which 4. +I couldn't repair the brakes, so I made your horn louder. +I cut it three times and it's still too short! +I debug with a magnet. +I didn't create reality...I'm just trapped in it! +I didn't know it was impossible when I did it. +I didn't wake up grouchy... I let her sleep. +I dislike killing my guests - Steven Brust +I do a weekly format In case I accidently backup c drive. +I do everything better when I'm naked. +I do whatever my Rice Crispies tell me to do. +I don't do jogging, it makes my beer all foamy +I don't do Windows. But OS/2 does. Very well. +I don't get mad...I just delete your COMMAND.COM +I don't have a problem with GOD, it's his FAN CLUB I hate +I don't have a solution, but I do admire the problem. +I don't have any solution, but I admire the problem. +I don't know what I like, but I know what art is. +I don't like violence but I'm very good at it +I don't recall running for this office. +I don't suffer from mental illness...I enjoy it!!! +I don't think Mr. Ranger is gonna like this, Yogi. +I Don't Wanna Overthrow the Govt, I Wanna Fire'em.!! +I don't want more, I want it all! +I Don't Want The World, I Just Want Your Half. +I Don't Want The World, I want the universe. +I don't want to be literate, I just want to program. +I donated my cat to the local Chinese restaurant. +I escaped from a political correction facility... +I even tried to reformat it, but still can't read my file +I fart in your general direction! -John Cleese +I feel a random act of violence coming on... +I FELT something was wrong. Multitasking causes schizophrenia. +I found my x-girlfriend in a find-a-fiend add. +I gave her the ring, she gave me the finger. +I get the news I need on the weather report. +I got a life once. Traded it in for a bigger hard disk. +I had a cat once. Tasted like chicken. +I had a vile comment once, but it escaped -Saint +I had one just like it.... only different. +I harbor no grudges, only angry memories. +I hate the way he says "Interesting Problem." +I have a 486, but a .357 is much faster. +I have a black belt in haiku. +I have a firm grip on reality. Now I can strangle it. +I have a rock garden. Last week three of them died. +I have an interesting way of my words structuring. +I have an OS/2 suit - It's multithreaded. +I have my priorities straight-it's the demands that are screwed up. +I have no idea what I'm doing, but I'm doing it well. +I have seen the evidence. I want DIFFERENT evidence... +I have the heart of a young boy - in a jar on my desk. +I have the simplest of tastes. The best is satisfactory. +I haven't killed anyone yet. Help me keep it that way. +I hear that it's Tourist Season in Florida. +I hunt flies with a sledge hammer....and get em!!! +I intend to live long enough to see my enemies die. +I just forgot my whole philosophy of life!!! +I just need enough to tide me over until I need more. +I just tested out my pitbull. Ever heard a mime scream? +I know so little, but I know it fluently. +I like os2 as much as the next fanatic! +I like to leave messages *before* the beep. +I like to skate on the other side of the ice. +I like to throw boomerangs to dogs. +I live in a quiet neighborhood, they use silencers +I live on good soup, not on fine words. - Moliere +I live to serve the public. How'd you like to be cooked? +I Love Animals......They're Delicious! +I love cats. On a good night, I can eat 5 or 6 of 'em... +I love standards! Such a variety to choose from! +I love the smell of napalm in the morning! +I love the sound of silence. Say what's on your mind. +I love you, you love me, Barney ate my fa-mi-ly... +I M a tru beleever in hour edukashun sistum. +I may be wrong, but I'm not uncertain. +I may have my faults but being wrong isn't one of them. +I may not always be NICE, but I'm always GOOD. }}}:) +I may not be smart, but I can lift heavy things. +I may work slow, but I do poor work +I need someone really bad. Are you really bad? +I never liked crayons much. They just don't have any flavor at all. +I never make stupid mistakes. Only very, very clever ones. +I never said I was perfect, but I never denied it! +I nows is graadiated froum Hi Skule. +I offer you your enemies. +I only drink to make other people seem interesting +I only drink when I'm alone or with someone. +I Only See In Infrared. +I passed my ethics course. I cheated, of course... +I played poker w/ tarot cards-got a flush & 5 people died +I procrastinate, therefore I will be. +I program like a MAN. I use COPY CON PROGRAM.EXE. +I put hard wood floors over carpeting. +I put on women's clothing, And hang around in bars +I quit drinking/smoking/&sex once.Very boring 15mins. +I refuse a battle of wits with an unarmed person. +I refuse to answer on the grounds..in the air maybe... +I refuse to go to a doctor who believes in reincarnation. +I run stop signs; I don't believe what I read. +I said Vulcan MIND meld, not MIME meld. Sorry, Marcel.... +I saw a tree fall in the woods, and I didn't hear it. +I saw Elvis. He sat between me and Bigfoot on the UFO. +I saw this in a cartoon once, but I think I can do it... +I saw what you did, and would like your phone #. +I see that your second lobotomy finally took hold. +I see your .44 and raise you a GAU-8A. +I should have known, you'd bid me farewell +I shpeak seeks different langwages, Eenlish da bast. +I stepped on a Tetanus needle today..... now what? +I still miss my exwife, but my aim is getting better... +I still Miss my wife. But with this new laser Sight... +I stink, therefore I'm Spam. +I SWEAR I thought she was 18! +I think ... therefore I am overqualified. +I think he's from the shallow end of the gene pool. +I think I'll wait for the 80986. +I think. Therefore I am DANGEROUS. +I think.... therefore I am conservative. +I thought you would've ducked.... honest. +I toast...therefore I am. +I tried being reasonable once, I didn't like it. +I tried switching to gum but couldn't keep it lit. +I tried to contain myself, but I escaped. +I turned in Schroedinger for Animal Cruelty... +I used to be a coyote, but I'm alright nooow! +I used to be sane once, didn't care for it much... +I used to jog, but the ice kept falling out of my glass +I used to play with my food, but I kept losing... +I want to live forever, and so far so good. +I was a dirty young man - I haven't changed. +I was gonna be a barber but neurosurgery pays better. +I was there. I saw it happen. You can trust me. +I was walking on water, or was that *under* water? +I went mad once. Did me a world of good. +I went to court for a parking ticket. I pleaded insanity +I will not squeak chalk. (with appropriate squeaks) +I wish I had a lower IQ so I could enjoy your company! +I wish my brain had expansion slots. +I wish scripts would do what I think I tell them +I wish you wouldn't sharpen your teeth when you say that. +I would have got away with it if it wasn't for those meddling kids!! +I would say more,but I'mlimited to only 57 characters here. +I would strongly oppose apathy, if I cared... +I'd give my right arm to be ambidextrous. +I'd give you a piece of my mind, but I'm on the last one. +I'd love to, but I'm taking punk totem pole carving. +I'd love to, but my bathroom tiles need grouting. +I'd offer everyone a Twinkie, but I'm not the host. +I'd rather have a bottle in front of me than a frontal lobotomy. +I'll be mellow when I'm dead. +I'll bring the Chtorr: you bring the barbeque sauce. +I'll have one brain on drugs with bacon and toast. +I'll have what the guy on the floor is having. +I'll never forget you -- you're too weird. +I'll never get off this planet. +I'll play fair if I get to make up the rules +I'm a belligerent omnivore -- I eat vegetarians. +I'm a modemer & I'm OK, I post all night & I sleep all day. +I'm a paranoid hypochondriac enamored with reality. +I'm a peaceful man. I vote to kill all weapon makers. +I'm a perfectionist with other people's work. +I'm a very modest man, and damned proud of it. +I'm an alien, an illegal alien! +I'm an anti-solipsist: everyone/thing exists except me. +I'm an antisolipsist: Everybody exists except me +I'm an Englishman in New York! +I'm an OS/2 developer...I don't NEED a life! +I'm another roadkill on the Information Superhighway. +I'm BETA testing my girlfriend. Bug report follows +I'm dangerous when I know what I'm doing. +I'm easy to please as long as I get my way. +I'm evil... I *LIKE* being evil... +I'm from the government. I'm here to help you. +I'm going to live forever!...or die trying. +I'm growing older, but not up..... +I'm happiest when I'm doing the cooking. +I'm having an out of money experience. +I'm having this tremendous difficulty with my lifestyle +I'm heavily armed, easily bored & off my medication... +I'm heavily armed, easily upset, and off the medication. +I'm immortal. I'm bored. Let's party. +I'm just here for moral support. . . ignore the gun. +I'm not a complete idiot - several parts are missing. +I'm not a mercenary; killing is more of a hobby with me. +I'm not a shyster, I'm a QUACK. +I'm NOT a vampire - I just eat like one... +I'm not arrogant, I'm just better than you. +I'm not Canadian although I tend to like their bacon. +I'm not crazy..I just have a unique sense of reality. +I'm not hostile! I'll kill the #%! that said that! +I'm not insane; Just pschologically challenged. +I'm not lost, I'm locationally challenged. +I'm not nearly as think as you confused I am. +I'm not paranoid! Which of my enemies told you this? +I'm not perfect. (but my inner self is) +I'm not perfect. (but my subconcious is) +I'm not prejudiced; I hate everybody +I'm not stupid, I'm just "politically correct." +I'm not stupid, I'm not expendable, and I'm not going! +I'm on top of the world. To bad there's no air here. +I'm out of bed and dressed. What more do you want? +I'm part Scotch -- my other part's water. +I'm perfect, other people just screw up my plans. +I'm practicing assertiveness. Do you think that's okay? +I'm pretty cool, Beavis, but I can't change the future... +I'm really imprinted with the quality of this conference. +I'm scared of the dark.. the government's in it. +I'm Seymour Cash of the law firm Dowie, Screwem, & Howe +I'm sorry, but my opinion is ROM burned. +I'm sorry, you are not cleared for that information. +I'm spending a year dead for tax purposes. +I'm The Best at what I do, and what I do isn't very nice. +I'm the creature that goes bump in the night. +I'm the person your mother warned you about +I'm weird, but around here it's barely noticeable. +I've already told you more than I know. +I've been pursuing a path of alternate reality +I've committed adultery in my heart many times +I've lost my sense of direction; which way to the bar? +I, myself, AM strange and unusual... +Idiocy is an inbred genetic trait of all politicians. +Idiot (id-ee-it) n.-> One who disagrees with me. +If a bear is chasing you please don't run this way. +If a program is useful, it will have to be changed. +If a program is useless, it will have to be documented. +If a thing is worth doing at all, it's worth doing badly. +If anything -can't- go wrong, it will. +If At First You Don't Succeed Ignore The Docs +If at first you don't succeed, destroy the evidence. +If at first you don't succeed, lower your standards. +If at first you don't succeed, put it out for beta test +If at first you don't succeed, redefine success. +If at first you don't succeed, skydiving isn't for you... +If at first you don't succeed, tell her another lie. +If at first you don't succeed, that means you're average. +If at first you don't succeed, work for Microsoft. +If at first you don't succeed, you must be a programmer. +If at first you don't suceed, you fail. +If everything's coming your way, you're in the wrong lane +If God wanted us to go METRIC Jesus would've had 10 disciples not 12. +If guns are outlawed, can we use swords? +If I knew how to spell, I could use a dictionary. +If I melt dry ice, I can go swimming without getting wet. +If I offend thee... ...tough! +If I want your opinion I'll give it to you. +If I want your opinion, I'll read your entrails. +If I wanted flames, I'd sell my soul to the Devil. +If idiots could fly, this would be an airport. +If ignorance is bliss, 'tis folly to be wise. +If it ain't broke yet, let me have a shot at it. +If it ain't broke, hit it harder. +If it ain't broken, play with it till it is. +If it doesn't work, change the documentation. +If it doesn't work, it doesn't matter how fast it doesn't work. +If it don't mean a thing, it ain't information. +If it isn't broken, I can fix it. +If it jams, force it...If it breaks, it needed replacing. +If it moves shoot it, when its dead paint it green. +If it screams, it's not food.........yet. +If it walks out of your refrigerator, LET IT GO! +If it works, something went wrong. +If it's glowing, don't eat it... +If it's not on fire, it's a software problem. +If its Tourist Season, why can't we shoot 'em ??? +If love is blind, why is lingerie so popular? +If people can't communicate, they could at least shut up. +If she won't live forever, then why give her a diamond? +If someone shoots me, I get to keep the bullet. +If stupidity was a survival value, he would live forever! +If stupidity was painful, then people would get help. +If the enemy is in range, SO ARE YOU. +If the enemy is within range, so are you. +If the facts are against you, argue the law. +If the law is against you, argue the facts. +If the mail wants me so badly, _it_ can walk to _me_. +If they catch us we're dead." "I've been dead before." +If they put your brain in a bird, it would fly backward. +If they're waving, where's the rest of their fingers? +If thine enemy offend thee, give his child a drum. +If this isn't war, why is CNN massing on the border? +If this was a real emergency, you'd've been trampled +If two wrongs don't make a right, try three. +If users can't read the manual, give them the source code +If Version 1.0 works someone goofed... +If we left the bones out it wouldn't be crunchy! +If wishes were horses, beggars would be shoveling manure. +If ya can't say anything nice, sit by me. +If you ain't making waves, you ain't kicking hard enough. +If you believe in telekinesis, raise my hand. +If you call me insane again, I'll eat your other eye too. +If you can count your money, then you don't have enough +If you can't fix it call it a feature. +If you can't laugh at yourself, I'll laugh at you...... +If you can't make fun of your friends ... what good are they? +If you can't make fun of yourself, give me a call! +If you cannot convince them, confuse them. +If you don't bet, you can't win. - Heinlein +If you don't care where you are, then you can't get lost. +If you don't like how I drive, get off the sidewalk! +If you don't like my facts, make up your own. +If you don't like my opinion of you - improve yourself! +If you don't like the Graffiti here, don't order Italian! +If You Don't Think Women Are Explosive... Drop One. +If you drink, don't drive. Don't even putt. +If you find this message offensive then you get my drift +If you hit every time, the target's too near. +If you leave the room, you're elected. +If you want it done right, forget Microsoft. +If you were an Armadillo, you'd worship trees, too! +If you're happy and you know it clank your chains +If you're on the cutting edge, expect to bleed. +If you're trying to drive me crazy, you're too late. +Ifyoucanreadthis,youspendtoomuchtimefiguringouttaglines. +Ignorance won't kill you, but it makes you sweat a lot. +ILLITERATE? Write for a free brochure... +Immortality is no excuse for not flossing. +Improve your IQ...eat gifted children! +In a nuclear war, all men will be cremated equal +In a sense, we have always lived in Ahnk-Morpork. +In a solemn ceremony, they giggle viciously. +In a vegetable garden, flowers are weeds. +In Arkansas, if you get a divorce, technically you're STILL cousins. +In CyberSpace everybody can hear you scream. +In Cyberspace, no one wears a watch. +In DOS we trust, all others please crash. +In extreme circumstances, cautionary measures are always justified. +In handling a stinging insect, movevery slowly. - Heinlein +In life.....pain is mandatory....misery is optional +In space...no one can hear you "Cha! Cha! Cha!" +In the beginning there was the Precambrian epoch. +In the country of the blind, the one-eyed men are kings. +In the end, everything is the same as it ever was. +Incorrigible punster - do not incorrige. +Inductive logic is much more difficult--but can produce new truths.- RAH +Infuriate the media: think for yourself. +Ingratitude, thou marble-hearted fool... - King Lear +Injustice anywhere threatens justice everywhere. +Inquiring minds wanna know. Intelligent minds don't care. +Insanity is fun if you do it right. +Insects really bug me. +Insert disk 5 of 4 and press any key to continue +Insert New Disk for Drive C: Press ENTER when ready. +Insert prong A into hole B and twist HARD! +Insert your favorite rude obnoxious offensive phrase here +Insomnia isn't anything to lose sleep over. +Install failed: Attempting to transfer virus to c: +Installation recommended (not included) +Instead here we are in a silence more eloquent... +Intelligence is the right arm of modern warfare. +Is it Progress when the cannibals use a fork? +Is nothing sacred? Great! When are worship services? +Is there supposed to be a lot of water down here? +Isn't that our pilot over there, kissing the ground? +It appears to make a driver mad if he misses you. +It doesn't work, but it looks pretty. +It is better to copualte than never. - Heinlein +It is better to light a flamethrower than curse the dark. +It is dangerous to be sincere unless you are also well armed. +It is morally wrong to allow suckers to keep their money. +It is when I struggled to be brief that I became obscure +It isn't really mine 'til I've modified it +It made a sound like someone was field-cleaning a badger. +It takes a long time to grow an old friend. +It takes a Real Man to sit indoors all day doing this. +It was supposed to be so easy. +It works better if you plug it in. +It works fine except when it's activated. +It's a chain saw. I always carry one for emergencies. +It's a dead man's party...Who could ask for more? +It's a great day for putting slinkies on an escalator. +It's a great place, and the drinks are cold! +It's a Satanic drug thing - You WOULDN'T understand... +It's all fun and games until the hard drive dies. +It's all psychobabble rap to me. +It's amazing how much "mature wisdom" resembles being too tired. - RAH +It's cold outside...there's no kind of atmosphere... +It's easy to make Windows faster. Just throw it harder. +It's great to do nothing and rest afterwards. +It's hard to RTFM when you can't find the FM.. +It's hard to work in groups when you're omnipotent. +It's not 0 to 60 that counts... it's 85 to 55 that matters! +It's not a bug, it's an undocumented feature. +It's NOT kill the women and rape the men, it's... +It's not so much the bat, but the Cyborg swinging it.... +It's not that life is so short, it's that you're dead for so +It's not the money I want, it's the stuff. +It's not the principle, it's the money. +It's not your imagination... we ARE against you. +It's nothing a warm-boot can't fix, I think +It's on that one, the 6th unlabeled floppy. +It's only my opinion, but it's better than yours. +It's so hard to find good vacuum tubes for my PC anymore. +It's working now; I don't want to break it by fixing it +JaLaPe Brand Ration's - Raw Meat that's great to eat! +Japan says your illiterate. +Jesus Saves --at First National Bank +Jimmy Hoffa, call your office. +Joe's crematorium u kill'em we grill'em! +John Wayne's World: Party time, Pilgrim. -SLR +Join army: travel, meet interesting people & kill them! +Just 'cause it won't work; You think it's buggy. +Just a lowly conference participant; not a moderator. +Just another prisoner of gravity!! +Just climb in, and hang on. Open your eyes, if you dare... +Just don't tell the asylum you saw me here. +Just say NO to negativism. +Just sliding down the razor blade of life . . . +Just when you thought it was safe to go back in the bitstream. +Kant's Categorical Imperative is too long for a tagline. +Keep honking...I'm reloading +Keep thy Tail Bushy and thine Eyes Bright, +Keep you're opinion to yourself. Spread mine around. +Keep your city clean...eat a pigeon. +Keyboard: A device for entering misteaks in a computer +Kill or starve. +Kill the extremists. +KILL the s.o.b. - THEN count to 10. +Kill What You Can't Understand. +Killing time takes practice. +Klingon DOS 6.0- DEL.COM; ERASE.COM; WIPE.COM; TRASH.EXE; BURN.BAT; +Knights errant spend their nights erring. +Knowledge itself is power. -- Francis Bacon +Knowledge rests not on truth alone, but upon error also. +Knowledge without common sense is folly. +LABEL NOT FOUND: go anywhere you like. +Lack of planning does not constitute an emergency. +Land of the Free, Home of the Unemployed. +Last one out of the coffin is a rotten corpse. +Lawyer: one who calls a 137-page document a brief. +Lawyer: the larval form of politician. +Lawyers should advertise on Emergency room ceilings. +Lawyers: the larval form of politicians. +Lay down all thought, surrender to the void... +Lead me not into temptation - unless there's money involved. -SLR +Lead us not into temptation; we can find it ourselves. +Lead, Follow, or get the H*ll out of the way... +Left blank to annoy the moderator. +Lern two spel. Kull mee att wurc four fre hellp. +Let him who understands reckon the number of the Beast. +Let the meek inherit the earth, I want stars. +Let's get some beer and dynamite and go fishing. +Let's take a chance on living; before we die! +Let's you and him fight. +Liberal (n): Anyone who disagrees with you. +Liberal censorship is hogwash. I see no evide ... NO CA +Liberals! Looks like we'll have to blast our way out! +Life and Liberty are safe...when congress is in recess. +Life being what it is, I dream of revenge +Life is a game, and money is how you keep score... +Life is an interruption in entropy. +Life is complex: It consists of real and imaginary parts +Life is like toilet paper; we panic as the end approaches. +Life sucks and then you marry one who won't. +Life's a b*tch...then you are reincarnated. +Life. It's not just a bowl of cereal anymore. +Life: what happens while you're making other plans. +Limit Congressmen to 2 terms - 1 in Congress, 1 in Jail! +Line Noise Brought to You By an I.R.S. Phone Tap +Listen to sermon, THEN eat missionary! +Listen you malfunctioning mess of microchips...... +Little did he know, but I was a master of the pugil... +Live by the sword, die by the longbow. +Living: The best demonstration of victory over mortality. +Logic is a way of going wrong with confidence. +Logic is logic. That's all I say." Holmes +Logic: 1+1= 11, 2+2= 22, 3+3=6 +Loitering with intent to hesitate. +Long live conference hosts ... so they can suffer longer. +Longer life through superior firepower. +Longer than lumber and broader than a bench. +Look unimportant - The enemy may be low on ammo +Looks like I picked a bad year to stop sniffing glue. +Lots of cute, furry animals killed to make this tagline. +LOTUS - Let Only The Users Suffer +Love is deaf as well as blind... and walks with a limp. -SLR +Love is grand... Divorce is twenty grand... +Love me or hate me, but spare me your indifference. +Love your country, but fear the government. +Love your neighbour, but don't get caught. +LSD melts in your mind not in your hands. +LSD melts your mind, not in your hand. +LSD: Virtual Reality without the expensive hardware! +Lucas refrigerators: Why the British drink warm beer. +Lunatic asylum: where optimism most flourishes. +Mac screen message: "Like, dude, something went wrong." +Macintosh - Computer /w training wheels you can't remove. +MACs = Snobby-Expensive-User-Friendly computers +Mad at your neighbor? Buy his kid a drum! +Madness takes it's toll; please have exact change. +Mafia DOS: "Thisa you lasta chance [Y/N]?" +Magicians are a vanishing species. +Mail not found: (A)bort (R)etry (P)anic (B)lame sysop. +Make a bold fashion statement: Get Naked. +Make friends with SysOps: Page them at 3am. +Make it as simple as possible, but no simpler. +Make my day, kill a GUI today. +Make my sushi medium rare +Malice:merely stupidity raised to a higher power. +Man is a god in ruins. -Ralph Waldo Emerson +Man looks into the abyss, and sees himself. +Man made Booze. God made Grass. Who do you trust? +Man of Steel hates industrial electromagnets. +Man often abolishes God; fortunately God is more tolerant +Man with forked tongue has no need for chopsticks. +Man,the missing link between apes and human beings +Mandatory tagline affixed in accordance with rule 3, sec A, par 2. +Manuals come out, after all possible keystrokes fail. +Marriage enders: You propose, we dispose. +Marriage is a rocky road when the attendents get stoned. +Marriage is not a word but a sentence. +Marriage is ok, but I wouldn't recommend it for singles +Marriage? No thanks, I don't breed well in captivity. +Married alive -- a fate worse than death. +Mars Needs Bovines +Mary had a little lamb, some white wine, and a salad. +Mason-Dixon: Line that separates y'all from youse- +Math illiteracy affects eight out of every five people. +Math Problems? Call 1-800-10x(24+13)-(64-16)/2 36x2. +MAXIMUM UNPLEASANT STIMULI!!! +Me opinionated? . . . Not on your life pig! +Me use the manual? Do I look like a sissy to you? +Me, indecisive? I don't think I am, do you? +Me...a skeptic? I trust you have proof. +Medical definition: Dilate. To live too long +MEDICAL STAFF: A doctor's cane. +Meet the new boss, same as the old boss... +Member: International Brotherhood of Tagline Kenders. +Member: International Brotherhood of Tagline Thieves! +Memory parity interrupt at 367A:64DF Self-Destruct 5 sec. +Men who believe absurdities will commit atrocities -Voltaire +Mental compatability not covered by warranty. +Mental Floss prevents Moral Decay. +Mere life is not victory, mere death is not defeat. +Message sent. Destroy immediately upon receipt. +Messiah Complex? Me? Well, let me just sayeth unto you...... +Mickey Mouse wears an Al Gore wristwatch. +Microbiology Lab: STAPH ONLY! +Microsoft Slogan..."McDoublespace..... Over 30 Billion crashed..." +Microsoft Windows - proof that P.T. Barnum was correct. +Microsoft: Making it easier... to switch to OS/2! +Microsoft: Making it all. Make sense? +MilliHelen: Amount of Beauty Needed to Launch One Ship +Millions of sperm and _that_ one got through. Sigh. +Milton's 1st Law: Anything can be used as a hammer. +Mind if I clean my fly swatter over your soup? +Mmm mmm good; Cream of Spotted Owl Soup, yum +Mmmmmm! A problem with grammar have I, yes! -- Yoda +MODEM - M_onumentally O_verpriced D_ata E_ating M_achine +Modem: A great deterrent to phone solicitors +Moderator (n): see also god, dictator, egotist, oppressor +Modesty Becomes You. Try It More Often. +Monday is an awful way to spend one seventh of your life. +Mondays are a rotten way to spend 1/7th of your life. +Money can't buy happiness, but it does quiet the nerves. +Money is truthful. If a man speaks of his honor, make him pay cash.- RAH +Monogamous and monotonous are synonymous. +Monolith Moscow Cemetery: "My God, it's full of czars!" +Monotheism: a gift from the gods +Morale improved, but now I ENJOY floggings! +Morbid: Burying the body, and then visiting weekly. +More fun than @TO@ should be allowed. +More than just a book--it's a major piece of torture. +Morgue, you stab'em, we slab'em! +Mosquito: Designed by God to make flies seem better. +Most "scientists" are bottle washers and button sorters. - Heinlein +Most allies must be watched just like the enemy. +Most have good aims in life, but few pull the trigger. +Most people make sense, I'm not one of them. +Most political jokes get elected +Multitasking - Twice the mistakes in half the time. +Multitasking = screwing up several things at once. +Murphy didn't come close to real trouble. +Murphy's rule of combat: Incoming fire has right of way. +Murphy's: All constants are variables! +MUST...DESTROY...MANKIND.......oops! Time for lunch! +My best feature? I would say my overwhelming humility... +My boss says I'm going to be famous, he says I'm history. +My computer NEVER loc +My demand curves are *always* upward sloping.... +My dog loves cats! He'll eat as many as he can catch! +My ego's bigger than your ego...... +My girlfriend said I never listen to her, or something. +My guru told me there'd be lifetimes like this. +My horse is the one that just broke its leg and fell on the jockey. +My infinity is bigger than yours. +My last original thought died of loneliness. +My life is in your hands... What do you mean, "oops"? +My mind is a scary place, I try not to go there alone. +My mind isn't always in the gutter - sometimes it comes out to feed. +My Mind's like a steel trap: Rusty and Unhinged. +My mistakes are purely erroneous. +My one regret in life is that I'm not someone else +My opinions are my own; mistakes are the computer's fault +My opinions are not those of my employer +My other computer is a TRS-80 Model 4. +My other sentient killing machine is a BOLO +My other tagline's a Rolex... +My psychiatrist told me "Maybe life isn't for everyone" +My reality check just bounced. +My ship came in but unfortunatly it was the flying dutchmen. +My system will resolve an infinite loop in 3 millisec. +My V32bs fx/mdm wrks jst fne wthot a 1550 bffrd URT +My Wife wishes I drank or chased women like other men! +My wife's other car is a broomstick. +Name: John Doe Phone:222-2222 Sex:Not lately +Natural laws have no pity. - Heinlein +Natural Selection works ... if you let it. +Nature always sides with the hidden flaw. +Necrophilia means never having to say... well, anything... +Neurotoxin Lite! Tastes great. Less drooling. +Never accept a drink from a urologist. +Never argue with a skunk, mule, woman, or SysOp... +Never assume conspiracy when stupidity will explain it. +Never assume. It makes an "ass" out of "u" and "me". +Never attribute to malice that which may be explained by stupidity. +Never board a plane whose flight number is 5050! +Never buy wine from a guy with purple feet. +Never draw fire, it irritates everyone around you. +Never eat a hedgehog without peeling it first. +Never enough time, unless you're serving it. +Never fight ugly people, 'cause they have nothing to lose +Never frighten a little man, he'll kill you. - Heinlein +Never give a gun to ducks. +Never go to a cyberpunk play when the review says "Riotous." +Never go to a doctor whose office plants have died. +Never go to bed mad. Stay up and fight instead. +Never hit a man when he's down - always kick him. +Never hit a man with glasses. Use your fist. +Never judge a man by his taglines. +Never laugh at live dragons. +Never lean forward to push an invisible object. +Never let a fool kiss you, or a kiss fool you. +Never let a machine know you're in a hurry. +Never let an inanimate object defeat you. +Never let your dragon overeat! +Never lick a gift horse in the mouth. +Never mind the oxygen. This man's a donor. +Never mind the star - get those camels off the lawn! +Never mistake endurance for hospitality. +Never pet a burning dog. +Never play Global War with someone named after a state. +Never put off till tomorrow what you can ignore entirely. +Never send a monster to do the work of an evil scientist. +Never show up at a gun fight with a knife +Never sleep with anyone crazier than yourself. +Never take a beer to a job interview. +Never tell them what you wouldn't want to do. +Never test for an error you don't know how to handle. +Never trust a computer that smiles at you... +Never underestimate a barbarian knucklewalker. +Never underestimate the power of human stupidity. - Heinlein +Never, ever, ever attempt to learn thermodynamics. +Never, ever, pinch a sorceress on the butt. +New Lurker Conference! Join in and disappear... +new oxymoron: final beta +Next time I send a damn fool, I'll go myself...Geez! +Nice guys finish last, but we get to sleep in. +No amount of careful planning will ever replace dumb luck +No bathroom? Just go boldly where no one has gone before. +No battle plan survives contact with the enemy +No Brain, No Pain. +NO CARRIER...but I've got 2 destroyers and a frigate +No cute, furry animals killed to make this tagline. +No good deed ever goes unpunished. +No good deed goes unpunished - Mark Twain. +No man is free who is not master of himself. +No matter where you go, there you are.... +NO MESSAGES FOUND. [H]it modem. [S]cream at fido gods. [Y]ell profanity +No One Is Ugly After 2:00 AM +No real reason for it; it just happens to be my policy. +No reason for it; it's just my policy. +No sense being pessimistic. It wouldn't work anyway. +No trouble parking, I drive a forklift... +No uninteresting subjects, just uninterested people. +No wanna work. Wanna bang on keyboard. +No, bartender, I said I vanted a BLOOD lite! +No, I never read the documentation. +No, I'm not an elitist. Why do you ask, peasant? +No, no, not "born again." I said, I was into PORN again. +No, really. Where did you get the zombie slime? +Noble deeds that are concealed are most esteemed. +Nobody ever bet too much on a winning horse. +None are so blind as those who will not see. +North East Breakfast: A cuppa coffee and a cigarette. +Not a computer nerd; merely a techno-weenie. +not after devouring so many maidens of the valley. +Not all men are fools, some are bachelors. +Not broke, merely under-funded. +Not now ... I have to go mow the laundry. +Not-so-famous Fraternities: I Phelta Thi, Tappa Kegga Bru +Nothing can go wrong(clik)go wrong(clik)go wro.. +Nothing is 100% certain, bug-free, or IBM compatible +Nothing is final. Except me, of course. +Nothing is so smiple that it can't get screwed up. +Nothing like a bribe to get things rolling. +Nothing wrong w/ this program a strong magnet can't cure. +Nothing's foolproof. Idiots are too ingenious. +Nothing's impossible for those who don't have to do it. +Nothing: Often a good thing to do & a clever thing to say +Now abusing OS/2 2.1 +Now and then an innocent man becomes a senator. +Now and then an innocent man is sent to the Legislature +Now in new great-tasting Grape and Watermelon flavor. +Now where did I put that fire extinguisher? +NT - "The carrot in front of the donkey" - J Dvorak +Nuke 'em til they glow... shoot 'em in the dark! +Number of phone rings = number of steps from commode -1 +O Lord, protect me from those to whom You speak directly!... +Objection, your Honour! My client is an idiot! +Of all the people I have met, you are certainly one. +Of all the things I've lost...I miss my mind the most. +Of course I can cook, but I never do it on the 1st date! +Of course I turned, I hit you didn't I? +Of course I'll pay for that one. Check okay? +Of course it's safe. Go on in, I'll be right behind you. +Of course it's safe. Go in, I'll be right behind you. +Of course, coffee *is* one of the major vitamins +Often it's fatal to live too long +Oh freddled gruntbuggly, thy micturations are to me ... +Oh what a Grand Universe we live in.... +Oh, excuse me, were those your panties? +Oh, I'm sorry, were the voices in my head bothering you? +Oh, it's on page 732 of the docs, paragraph 3, section D1 +Oh, pardon me, was that *your* culture? So sorry. +Ok Space Cadets! Prepare to hurtle through the cosmos! +OK, I pulled the pin. Now what? Hey, where're you going? +OK, I'm weird! But I'm saving up to be eccentric. +OK, I've pulled the pin. Now what ? Where are you going ? +OK-give me ONE good reason why I can't have it both ways. +Old enough to know better, young enough not to care! +Old is when your back goes out more often than you do. +Old soldiers never die...young ones do. +On a clear disk you can seek forever +On Fidonet, nobody knows you're naked. +On one condition -- that it leads to extreme violence! +On the day of the dead, when the year too dies... +Once again, truth and American technology defeat Bill. +Once again, truth and American technology defeat Satan. +Once in a while, I screw up and do something right. +Once you pull the pin, Mr. Grenade is no longer a friend. +One atom bomb can ruin your whole day +One golden glance of what should be +One good turn is usually enough to get a person lost. +One man's Windows are another man's walls. +One more day like today and I'll kill you too. +One murder makes a villian, millions a hero -B Porteus +One nation under God; with liberty, fries & a Coke to go. +One ring to rule them all... +One sword at least thy rights shall guard, +One thing about pain: it proves you're alive. +Online? Good, hit Alt-H for FREE Unlimited Access ! +Only 19,999 lines of C++ to my next ski trip... +Only a lawyer calls a 10,000 word document a "brief". +Only a liberal could coin a word such as "undertaxed." +Only lemmings jump to unknown conclusions. +Only the educated are free: Some Greek guy. +Oops, gotta go feed the dragon. +Open mouth, insert foot, echo internationally +Operating at a higher level - OS/2 v2.1 +Operator error (E)xecute (T)rain (S)end Home +Operator! Trace this call and tell me where I am. +OPINIONS? I have lots. Which one would you like? +Optimism is profoundly depressing. +Or time will grind you down to dust again... +Originality is the art of concealing your sources +OS/2 - because 32 bits are terrible things to waste. +OS/2 - The only true 100% FAT free operating system. +OS/2 fixes broken windows +OS/2! Anything else is just DOS. +OS/2: Windows with bullet-proof glass. +OS/2: Your brain. Windows: Your brain on drugs. +Other than that, Mrs. Lincoln, how did you like the play? +Our swords shall play the orators for us. +Our world is like a cactus except the pricks are inside. +Page your sysop at 3am for Free Prizes! +Pain -- Finally something we can depend on. +Paint it Octarine: the color of magic. +Paranoia is just a heightened sense of awareness. +Pardon me if not every "i" is crossed and "t" dotted... +Pardon my driving; I'm trying to reload. +Pardon my existence and I might pardon yours. +Path = 'down there a ways and to the left' +Patience and time do more than strength or passion. +Patience is a virtue possessed by few men and no women +Patience-A Virtue That Carries A Lot Of Wait +PATROL CAR BUMPERSTICKER: Attitudes adjusted, while you wait. +Paul Harvey fans always have a good day +Paused: enter any 12-digit prime number to continue +PCBackup: 1 of 1362 disks. +PCs rule 1001111 1001011 +Pedestrian: Someone who found a place to park. +Pedestrian: The most approachable chap in the world. +People say I'm apathetic, but I don't care. +People say I'm indecisive. Am I? I don't know. +Perhaps I should take up golf instead? +Personal beliefs become trivial when reality intrudes... +Personals:"Mormon seeks wife, must get along with others" +Philosophy is for people who can't form their own opinions. -SLR +Phoneco.sys corrupted-recommend competitive market. +Pick two: 1)Fast 2)Right 3)Cheap 4)Windows (counts as 2) +Pioneers are the ones with the arrows in their backs. +PKunZIP V56.7 FAST! Exploding Universe->>CRC-@ error +Place your clothes and weapons where you can find them in the dark.- RAH +Plasma is another matter +Played poker w/tarot cards. Got a flush & 5 people died! +Please excuse me. I'm one of the fatigue impaired. +Please stand by, depressurization begins in 15 seconds. +Plunk your magic twanger Froggy... +Polite Virus: Sorry to interrupt, but I need to format... +Political Correctness: marketing term for mind contral. +Politicians aren't born, they are excreted. (Cicero) +Politics: Passing the buck or passing the doe. +Politics:Root(s):[a]Poly-Many [b]Tics-Bloodsuckers +Pornography: n. Things we enjoy but don't want anyone to know about. +Posted by a twisted mind behind a machine. +Power corrupts, but OS/2 is kinda neat. +Power corrupts. Absolute power is kinda neat, though. +Power doesn't corrupt people, people corrupt power. +Power is an illusion; only stupidity is real. +Practice mirth control - used a conumdrum. +Practice mirth control..... always use a conundrum +Practice safe snuggle. Make her wear socks to bed! +Pray for Bill Clinton (see Psalm 109:8) +Precinct toilet stolen... Police have nothing to go on. +Predestination was doomed from the start. +Preserve wildlife...pickle a squirrel today. +President Clinton --- The Eddie Haskel of politics. +Press -- to continue ... +Press -- to store all new data: +Press alt-H to continue, then Y if applicable. +Press any key to continue or any other key to quit +Press SPACEBAR once to quit or twice to save changes +Press to test. Release to detonate... +Press [ESC] to detonate or any other key to explode +Prevent Messes-Cover Hamster before Microwaving +Problems? No, I LIKE my foot there. +Profanity, the language computerists know. +Professor: a textbook wired for sound. +Programmer (n): One who makes salesman's lies come true. +Programming Dept.: Mistakes made while you wait. +Prosecutors will be violated. +Provider of fine voodoo productions..... +Prune Juice . . . The drink of warriors! +Pscyhos R Us +Psychiatry: The study of the ID by the ODD. +Psychic Convention cancelled due to unforeseen problems +Psychoceramics: The study of crackpots. +Psychoses are red, Melancholia's blue, I'm Schizo...you? +Pull once to eject... twice to abort ejection. +Pull trigger repeatedly until problem dissapears +Puns are bad, but poetry is verse. +Put Lawyers on the ETHICS COMMITTEE, for BALANCE +Put the straightjacket over his mouth. Trust me. +QEMM Exception #13: [L]ockup, [L]ockup, or [L]ockup? +QUICK! Hand me the cat; the cherry bomb's lit! +Quick, easy, enlightenment; Just axe for it. +Quoth the Raven, "Eat My Shorts." +Radical: Anyone whose opinion differs from ours. +Radioactive Halibut will make fission chips +RADIOACTIVE: if you can read this you're sterile +Rainy days and automatic weapons get me down. +Read Books And Repeat Quotations. +Real programmers innovate, others LITIGATE ! +REAL programmers use "COPY CON PROGRAM.EXE" +Real Trekkers work out at the He's Dead Gym +Real women don't deflate when you bite them. +Reality is a constant intrusion on my dreams. +Reality Is An Illusion Caused By Lack Of Acid +Reality is an illusion: men are only the dreams of gods. +Reality is an obstacle to hallucination. +Reality is for those people who have no grasp of fantasy. +Reality is for those who can't face fantasy. +Reality is the leading cause of stress amongst those in touch with it. +Reality: a fantasy gone wrong, dreadfully wrong!!! +Reality: an illusion produced by an alcohol deficiency. +Reality:a crutch for those who can't handle drugs. +Really honey, I NEED 10 megawatts for it. +Real_men_don't_need_spacebars. +Red meat is good for you; fuzzy green-blue meat is bad. +Redneck marriage proposal:.........YER WHUT!!?????? +Relativity all depends on how you look at it. +Religion keeps the poor from murdering the rich. +Religious error: (A)tone, (R)epent, (I)mmolate? +REMEMBER that the only proper way to exit a door is ALT-H +Remember: Scan all files for viru(+(+(&*^)6075$%^&$ +Remember: USER is a four letter word. +Reports of my being alive and well are grossly exagerated +Reputation: what others are not thinking about you. +Research has found that research causes cancer in mice. +Retreat h*ll! We're just fighting in another direction! +Revenge is a dish best served....with tangy Miracle Whip! +Reward for a job well done: more work +Right theory, wrong universe +Right, mate, I'll just throw another Ken on the Barbie! +Road Kill Cafe - Today's Special: Swirl of Squirrel +Road Kill Cafe: new meaning for "fresh off the grill." +Robert A. Heinlein memorial taglein. +Rosanne Barr: proof that mankind is troubled +RTFM? - Nah, call the author at home! +Rumour: NT means Not Tested +Run for shelter in these golden years +Sacred cows make better hamburgers. -Graffiti +Sacred Cows make good hamburgers. +Safety needle: pointless, isn't it? +Salvador Dali for Coca Cola: It's surreal thing. +SAPFU -- Surpassing All Previous Foul Ups. +Saudi Arabia, A country where the word "DUCK" is a Verb. +Save a flag - Burn a protester +Save a tree, eat a beaver! +Save Georgia's economy...Eat more canned Possum! +Save time - live several lives at once. +Save toilet paper. Use the other side. +Say something nice to everyone today...drive them crazy. +Scandal is juicy gossip made tedious by morality. +Schizophrenia beats being alone. +Science Fiction: So fun it ought to be illegal or fattening or sumfin'` +Science is truth -- don't be misled by facts. +Screw the company, those first 20 minutes belong to you. +Scripts, the thinking man's route to insanity. +Second star to the right and straight on 'til morning +Secrecy is the beginning of tyranny. - Heinlein +Secret revealed: Press CONTROL-ALT-DEL for SysOp Access! +Sects! Sects! Sects! Is that all Monks think about? +See ya in the chronostream, Time Jockey! +sEe! I cna ytpe 300 wrods pre mniuet!!! +Send $20.00 in small unmarked electrons. +send moneySUBLIMINALsend moneyTAGLINEsend money +Send Monopoly money to your favorite TV Evangelist. +Send more tourists..... the last ones were delicious! +Seriousness is the very next step to being dull. +Set. Spike. Dig. I do it in the sand. +Sex ain't dirty.. it's slippery! +Shall I scream? Let's scream together. -SLR +Share and Enjoy. (or - Go stick your head in a pig) +Sharks don't eat lawyers. Professional Courtesy. +She said "Have a nice day", but I had other plans. +She turned me into a newt! ....well, I got better.... +She won't last forever, so why buy her a diamond? +She's dead, Jim. But hell, she was like that in the sack +She's the bargain hunter. I just carry the ammunition. +Shin - Device for finding furniture in the dark. +Shoot Dr. @FIRST@ on sight and dissolve his body in acid. +Shoot first, and whatever you hit, call it the target. +Shoot first; answers aren't that important. +Shopping tip: Shoes are $.85 at bowling alleys. +Shouldn't you be doing something productive? +Show me a sane man. I'll cure him for you. +Shut up, or I'll nail your other foot to the floor +Sign on the mortuary door: Remains to be Seen. +Sign outside brothel: "On Vacation. Beat it." +Silence cannot be misquoted. +Silence? Oh no, it's the Attack Of The Mimes! +Simon says Stand! Simon says sit! Format your drive! HA! Gotcha! +Since I've used up my sick leave, I'm calling in dead. +Sinner: A stupid person who gets found out. +Sit dux sapienta- Let wisdom be your guide. +Sky diving, its good to the last drop. +Slaying foul maidens, rescuing fair dragons. +SLEDGE-O-MATIC: For life's most difficult problems. +Sleep: (noun), Short time between BBSing and work. +Sleep? I'm a Consultant!! +Slow the aging process: put it through Congress. +Slugs saut... a hors of a different d'oeuvre. +SMILE ! (makes people wonder what you're up to) +Smith & Wesson: The original point-and-click interface. +Smith & Wesson: The ultimate point & click user interface... +Snap, Crackle, Pop ....Darn I hope that was a fuse... +So he says to the Shapeshifter waitress, "Keep the change." +So I said to my one-legged wife, "Peg..." +So many books, so little time. +So many jerks, so few bullets... +So much time, so little to do (or something like that). +Society prepares the crime; the criminal commits it. +Software Troubleshooter - @TO@, w/44 Magnum +Software: What you boot. Hardware: What you kick. +Solve the problems of the world: Vote anarchist. +Some days I look my best in a thick fog. +Some days you're the windshield, some days the bug. +Some nonsense now and then is relished by the wisest men. +Some people are only alive because it is illegal to kill them. +Some settling may have occurred in shipping. +Some thoughts are best guillotined before actions result. +Somehow tuna doesn't taste the same without the dolphin. +Sometimes a cigar is just a cigar. +Sometimes even fools make good suggestions. +Sometimes I wake up grouchy. Most times, I let her sleep. +Sometimes the depths of your ignorance amazes even me. +Sometimes you just have to say 'What the heck' +Sometimes you're a bug, sometimes a windshield +Sometimes you're a Kenworth, sometimes you're a possum. +Sometimes, I wish I could ARJ my wife... +Sometimes, the Dragon wins... +Sooner or later, I'll be free to leave the past behind. +Sorry Congressman... cash only. +Sorry, tomorrow is cancelled due to the lack of interest! +Southern DOS: Y'all reckon? [yep/nope] +Sow dragons teeth, reap trouble. +Spaced Aliens: Columbian drug lords in US. +SPAM - Squirrels, Possum, And Mice. +Speak softly and carry a meat cleaver. +Speed doesn't kill. Stopping very fast kills. +Speed is fine ... accuracy is final. -- Wyatt Earp +Speed kills! Switch to Windows ... +Speed kills; slow just infuriates... +Spindle & Mutilate - See if I care.. +Spiritual Truth thru Superior Weapons +Squeeze Me Hard! I Work Better Under Pressure.... +Squirrels: Rats with good P.R. +Stand aside: I'm fluent in lunatic. +Stand under it, but don't let it lick you. +Start a download. Get a beer. Multitasking. +Stationary mice have bigger balls. +Statistics are no substitute for judgment. +Steven King, eat your heart out. +Strange fits of passion have I known; +Studies show that 51% of Americans are in the majority. +Success is just a matter of luck. Ask any failure. +Success lies in achieving the top of the food chain +Sumo wrestling in the canoe of life. +Support medical examiners--die strangely. +Support NAFTA, export Clinton and Bore +Support nuclear families! The mutants are fun to watch! +Support OS/2: Show NT to your friends! +Support your constitutional right to arm bears. +Support your SysOp... Send your paycheck. +Sure you can trust the government... ask any Indian. +Sure, I stole them. All of them, and I'm *PROUD* of it! HAHAHAHAHA! +Sure, it's embarrassing, but it's over quickly. +Sure, money talks. All mine ever says is goodbye. +SURF NAKED: sharks hate to peel their food +Surrender now - before I have to offer you better terms. +Surrounded? No, we're just in a target rich environment. +Survival Tip #2: Never moon a werewolf. +Survival Tip #3: Never invite Cthulhu over for dinner. +Sushi: Known to the rest of the world as 'Bait'. +Swamp gas usually doesn't create sonic booms. +Swim nude. Sharks hate to peel their food. +Synonym: A word used when you can't spell the first one. +SysOp ('sih sop) n. - The person laughing at your typing. +System error. Strike any user to continue... +SYSTEM ERROR: place sacrifice on keyboard to continue. +SYSTEM FAILURE: PRESS F13 TO CONTINUE! +Tabloid: A newspaper with a permanent crime wave. +Taco Bell is *not* a mexican phone company +Tact is knowing how far to go in going too far. +Tact is knowing how far you can go too far. +Tact: Recalling a lady's birthday but forgetting her age. +Taglines: More interesting than the garbage above. +Take me not for what I seem, but for what I am. +Taking up collection to give Barney a one way ticket to hell. +Talk is cheap... till you hire a lawyer. +TANSTAAFL - There Ain't No Such Thing As A Free Lunch. +Target Shooting - Official Pastime of Nicaraugua +Taxes are not levied for the benefit of the taxed. - RAH +Teamwork is vital. It gives you someone to blame. +Tech Support is Just A Busy Signal Away +Tech Support: Where is it when you need it? +TECHNICALITY: Someone *ELSES* Constitutional rights.. +Tell me, have you ever woken up and realized you were doomed? +Temporal distortion located around workplace clock. +Temporary suspension of disbelief is a wonderful thing. +Terror is also a form of communication. +Thank you for not discussing the outside world. +Thank you for not mooning your checkout girl. +That IS a gun in my pocket, and I AM glad to see you. +That parrot wouldn't VROOM if you put 5000 volts to it! +That rap tune is really the Polyvtsian Dance #2 by Borodin. +That which can be imagined can also actually be realized. +That which does not kill me had better run away damn fast! +That which does not kill us makes us stronger. +That which does not kill us took its ball and went home. +That Which Doesn't Kill Me Better Run Away Damn Fast! +That which makes life good, makes death good also... +That's stronger than a garlic milkshake. +The above opinions are those of my computer! +The absence of alternatives clears the mind marvelously. +The arrogance of age must submit to be taught by youth. +The best blood at times gets into fools and mosquitoes. +The Big Bang is only the universe rebooting. +The bigger they are, the harder they punch. +The Bill of Rights: Void Where Prohibited by Law +The Church has appropriated God for its own ends! - Machiavelli +The dead don't come back to life? Be here at quitting time. +The Department of Agriculture is full of Dirtbags. +The Devil is most devilish when respectable. +THE DEVIL MADE ME DO IT ? NOW OPEN THE CELL DOOR. +The earth is like a tiny grain of sand, only heavier +The Few, The Proud, The Most Frequently Shot At... +The fient a tail she had to shake! +The first ten million years were the worst. +The floggings will continue until morale improves. +The four food groups.. coffee, ice cream, beer and pizza! +The gene pool has no lifeguard +The gene pool needs a lifeguard. +The Gods of one culture become the devils of the next... +The greatest production force is human selfishness. - Heinlein +The height of cleverness is to be able to conceal it. +The hippopotamus rests on his belly in the mud. And you? +The ideal wife is the woman who has an ideal husband. +The illuminati aren't out to get you. What was your name again? +The last sound that it made was "Zap." +The light at the end of the tunnel is a buglight +The living world is a continuum in each and every aspect. +The Magical Mythstery Tour +The moat is off-limits to swimming, except to IRS agents +The more I get to thinking, the less I tend to laugh. +The more I hear about Microsoft, the less I like them. +The most interesting results happen only once. +The Novel: Your imagination intensified. +The only GOOD user is a DEAD user +The only paradise is paradise lost. -Marcel Proust +The only winner of the War of 1812 was Tchaikovsky. +The ox is slow, but the Earth is patient. +The pen is mightier than the sword, but swords are more fun! +The Peregrine Plot Thickens...Alas, we are undone... +The polls show 8 out of 5 schizophrenics agree! +The prince hides his face from the dreams in the mist. +The problem drinker is the one who never buys. +The refrigerator light DOES go out. Now let me out of here. +The Results of your IQ test came back. They're negative. +The Ringworld is Unstable! +The road to hell is paved with legislation. +The road to success is always under construction. +The Roman Empire never died it became the Catholic Church +The Second Amendment -- my concealed-weapons "permit" +The secrecy of my job prevents me from knowing what I do. +The secret of DoubleSpace: Randomly loses half your data +The Strange are strange but to men, but familiar to God. +The sun comes up too early for my liking! +The surest way to be late is to have plenty of time +The tenants are then chopped up by the rotating knifes... +The thrill of the chase is worth the pain. +The toughest thing in business is minding your own. +The trouble with political jokes is they get elected. +The truth is rarely pure, and never simple. (Wilde) +The truth is the safest lie. +The truth, however, is not pertinent to the issue. +The universe by time's fell hand defaced. +The universe is laughing behind your back. +The universe is very BIG. Believe me. +The way to a man's heart is with a broadsword. +The way to a man's heart: between the ribs, and slightly up. +The way to a woman's heart is through her ribs. +The weather's here, wish you were beautiful... +The weed of crime bears bitter fruit but I like the taste +The wise learn more from fools than fools from the wise. +The word today is "legs".....Help spread the word! +The words are there, my dear, but the music is wanting. +The world ended yesterday; sorry, you missed it. +The world ends at 8 P. M.... Film at 11. +The world is a stage, but the play is badly cast. +The worst thing about censorship is ##########. +The X Insurance Co.---How may we shaft you? +There are only 3 lawyer jokes; the rest are true +There Are Three Sides To Every Story. +There are two secrets in life: Never tell everything at once. +There is always one more imbecile than you counted on. +There is infinite hope...... But not for us.... +There is no fool like an old fool. J.Heywood (1497-1580) +There is no intelligence on Earth, I'm just visiting. +There is no Pattern but that we impose on chaos. +There is no problem that cannot be solved by high explosives. +There is no substitute for a genuine lack of preparation. +There is no such thing as bravery; only degrees of fear. +There is no wealth but life. -- John Ruskin +There may be millions of votes, but I'm Gulliver. +There's a light, over at the Frankenstein place. +There's always one more bug. +There's not enough Sax and Violin's on TV +There's nothing a concentrated phaser blast can't solve. +They called him tall in the saddle till his blister broke +They got the library at Alexandria. They're not getting mine. +They say act your age, and when you do they get mad. +They say God made All Men. I say Samuel Colt made all men Equal. +Things are never so bad that they can't get worse. +Things in this room do not react well to bullets. +Things that appear simple, usually aren't. +Things you never hear people say: Please saw my leg off. +Think of it as evolution in action. +This blade here is my best friend.... +This is another fine myth you've gotten me into. +This is beginning to get on my nerves, now that I have some. +This is Discussion; Arguments & Abuse is down the hall. +This message is SHAREWARE! To Register, send $25. +This message will disappear in five seconds +This message will self-destruct in 5 seconds... +This message written with recycled electrons. +This MSG created by pouring warm tea on a Ouiji board. +This offer void except where prohibited by law. +This Space still for rent. Unreasonable rates +This tag is invisible to anyone with a higher IQ than me. +This tagline is a virus. Kis C:\*.* goodbye. +This tagline is NAGWARE! To remove it send $15.00. +This talgine meats all U.S. Guvermnint standerds. +This time he really is dead Jim, he he he. +Thomas Jefferson was a friend of mine... * @TO@ +Those that have the firepower make the rules. +Those truly alive wrestle truly with their own souls. +Those who live by the sword get shot by those who don't. +Those who live by the sword KILL those who don't. +Thou shalt not covet thy neighbor's tagline. +Thou shalt not post messages while drunk. +Three can keep a secret, if two are dead. +Tighten 'til it cracks, then back off 1/2 turn. +Time and distance are out of place here. +Time for the penguin on your telly to explode ..... +Time keeps everything from happening all at once. +Time machine, my foot. Why, it couldn't tell you the time, much less.. +To be, or not to be. What does it really matter... +To boldly go where no man has any business. +To discover one knows nothing is the beginning of wisdom. +To eat or not to eat, the question is whom to eat! +To err is human, to forgive is against company policy. +To err is human, to forgive........$5.00 +To every rule there is an exception, and vice versa. +To get back on your feet, miss 2 car payments. +To live now, first come to terms with your past. +To quote the Librarian at Unseen University, "Oook!" +To really live, you must almost die. +To remove virus, type Format C: at the prompt and... +To scan, or not to scan. There may be a vir^@#@&_*^|> +To strive, to seek, to find, and not to yield. +To take the Genesis online IQ test: press Alt/H +To tolerate everything is to teach nothing. +Today is the first day of the mess of your life. +Too bad about your Rectocranial Inversion. Get well soon +Took an hour to bury the cat. The silly thing kept movin' +Torture: The Ultimate Art Form. +Total is $1000. $10 for the upgrade, and $990 s/h. +Tradition: The art of making the same mistake over and over. +Transplated musical instrument explodes. Organ rejection suspected. +Tree falls in forest. Hits Milli Vanilli. Someone else screams. +Trespassers will be SHOT, survivors will be SHOT again. +Trilogy (n). Series of three books, sometimes more. +Truck Pulls: for people who don't understand WWF. +Trust everyone, but always cut the cards. +Trust me, Ignore the rash. +Truth is shorter than fiction. -Irving Cohen +Try filling a light bulb with gasoline and putting it in a socket. +TV Truth #5: Drinking beer attracts beautiful females. +Twisted mind? No, just bent in several strategic places +Twisted? No, just bent in several strategic places. +Two can live as cheaply as one, for half as long. +Two Great Tennesseans: Charlie and Jack Daniels +Two peanuts were walking down a street, one was assaulted +Type in the Gettysburg Address to continue..._ +Unbounded is thy rage; with varied style +Unfair competition: Selling cheaper than we do. +Unknown Error on Unknown Device for Unexplainable Reason. +Use DEVICE = EXXON to screw up your environment. +Users: Keep them dry and don't feed them after midnight. +Vacation in the billion worlds of a used book store . . . +Vampire making daquiri: blend me a tenor. +Vampire robs sperm bank in state of confusion, news at 11 +Veni Vidi Fetuccini: I came, I saw, I had lunch. +Veni, vidi, clinti: I came, I saw, I lied. +Very good, Einstein, but next time show your work. +Veteran of the Bermuda Triangle Expeditionary Force 1990-1951 +Viking Foreplay: "HEY! YOU! C'MERE!" +Violence in reality is quite different from theory. +Virus located. Delete c:\window\*.*? y/n +Visit your money this year: Vacation in Washington DC +void main (void) { if (windows=="useful") hell=frozen } +Vote NO with the weapon of your choice. +Wagner's music is better than it sounds. - Twain +Wanderers and nomads have gone to see their chieftains. +Wanna do something big? Pick up a boulder. +Wanna read a good horror novel? Get a history book +Want more grey hair? Teach your child to drive! +Want my guns? Come in range and get them. +Want to own a small business? Buy a big one and wait... +Wanted dead or alive -- Schrodinger's cat! +Wanted: Guillotine operator. Good chance to get ahead. +Wanted: Programmers. Some assembly required. +War is just Nature's way of keeping humanity in check. +War never decides who is right, only who is left. +Warm the Northeast...use aerosol spray! +Warning: bonds skin. +Warnings are for people without imagination. +Warped, and proud of it. +Warped, twisted, sick, and proud of it. +Watch it - You're trying my infinite patience +Ways to skin a cat: #27 --- Use a belt sander. +We are NOT surrounded. We are in a target-rich environment. +We come in peace, shoot to kill. +We come not to discuss reality, but to use the BBS. +We don't care, we don't have to: We're Exxon. +We don't care. We don't have to. We're The Phone Company. +We have enough scientists; we need more hunchbacks, Igor. +We have met the enemy and they is us. +We have nothing to fear but sanity itself. +We must flee before they set loose the marmosets upon us! +We now return to our regularly scheduled flame-throwing. +We said you'd get your money back, we didn't say when. +We should back the Metric system every inch of the way +We used to be Schizophrenic. +We want a war the whole family can watch! +We want peaceful relations, or we'll blow up your planet. +We would gladly feast on those who would subdue us. +We'll get standards even if we have to bribe someone! +We're entering the Bond-Age, in more ways than one. +We've broken the space-time continuum and passed the savings on to you! +We've missed you; we'll aim better next time! +Welcome to hell -- here's your copy of Windows. +Well, at least I'm improving my cold tolerance. +Well, I might be high, but...but I'm REAL fast! +Well, I'd like to see you resist. +Well, it seemed like the thing to do at the time. +Well, it was only plan A; plan B is much more interesting. Really. +Well, it worked the last time I tried this.... +Well, it's got *SOME* rat in it ..... +Whaddya mean you don't STAPLE diskette labels on? +What colour wine is served with BOILED TONGUE? +What does it mean when your fortune cookie is empty? +What does the Infantry call Airborne? Skeet Shoot! +What does this red button do? +What garlic is to salad, insanity is to art. +What has 4 legs and an arm? A pit bull. +What if there were no hypothetical situations? +What is Redneck foreplay? (Nudge) Are you awake? +What is the purpose of hanging up if I'm calling again tomorrow? +What is this tiny hole in the bathroom wall for? +What type of support were you looking for? Tech or Jock? +What we need is a Pizza Door and a Beer Door +What?!? DOSSHELL *isn't* supposed to be a joke? +When all else fails, do something else. +When all else fails, refer to the destructions. +When childhood dies, its corpses are called adults. +When donating your brain to science, make sure science wants it. +When governments fall, people like me are lined up & shot +When I played in the sandbox, the cat kept covering me up. +When I was a kid we had to carve our CPU's out of wood... +When in doubt - comment it out. +When in doubt, attack the old bearded guy in the back. +When in doubt, run in circles and scream and shout. +When life gets weird, the weird get a life. +When need arises, any tool close to you becomes a hammer +When people agree with me, I always feel that I must be wrong. +When subtlety fails us we must resort to cream pies. +When symmetries are broken, things begin. +When the going gets tough, most people leave +When the mind is ready, a teacher appears. - Zen +When you get there, there's no there there. +When you seek it, you cannot find it. -Zen +When's the trial? - Right after the hanging... +Where are we going...and why am I in this handbasket?? +where do they hide those swords????!!! +Where do you find 100 talking invertebrates? The US Senate! +Where might is master, justice is servant. +Where they burn books, people are next. +Which one of you alien sombitch artists made these gawddammed circles? +Which version of the truth would you prefer today? +Which way did they go!? I'm they're leader!! +While the lunatic dreams, the Earth changes +Whip me, beat me and cover me in chocolate. Please. +Whip me; beat me; make me register bad software. +Whips & chains? Sorry, thats a hardware problem. +White dwarf seeks red giant for binary relationship. +Who beta tested Preparations A through G? +Who is General Failure and why's he reading my hard disk? +Who popped the cork on my lunch!? +Who wants to live forever? +Who watches the watchmen? +Who you callin' "argumentative", Bucko? +Whoever said that work was fun, didn't work! +Whom gods would destroy, they first teach MS-DOS. +Whom the mad would destroy, they first make gods. +Why are there so many gnarly limbs on my family tree? +Why be normal? +Why buy Cologne when you can wipe a magazine on yourself. +Why do they put locks on the doors of 24 hour stores? +Why get even, when you can get odd? +Why me? +Why not invite her over for a Scotch and sofa? +Why? +Wife: A slave who demands to be set on a throne +William K. Smith:"Wait, my uncle Ted can drive you home." +WindowError:001 Windows loaded. System in danger. +WindowError:005 Multitasking attempted. System confused. +WindowError:00F Unexplained Error, Please tell us how it happened. +WindowError:01E Timing error. Please wait eight years... +Windows - the solution to a problem that didn't exist +Windows 3.1 -- The best $89 solitaire game on the market. +Windows Backup Started: Insert disk 1 of 38,544 +Windows Error 005: Multitasking attempted. System confused. +Windows Error: 002 - No error yet ... +Windows Error: 004 - Operator fell asleep while waiting. +Windows is to OS/2 what Etch-a-Sketch is to art. +Windows isn't crippleware: it's "Fuctionally Challenged" +Windows NT: An imaginary OS for your imaginary 686 PC. +Windows NT: Needs Terabytes +Windows NT: The only 80 meg solitaire game. +Windows NT? Is that the new NinTendo GUI? +Windows: big, expensive, pretty virus. +Windows: Proof that MS has a room of monkeys with PC's +Windows: the $89 solution to your excess speed problem. +Windows:(n.)1. Something that comes with the mouse you bought. +Windows:(n.)2. The Gates of hell. +Windows:(n.)4. Proof that God has a sense of humor. +Windoze for Workgroups: Why crash 1 when you can crash 6? +Windws is ine for bckgroun comunicaions - Bll Gats, 192 +Winning or losing doesn't matter until you lose... +Winter is Natures way of saying, "Up Yours!" +Wise Man cross river *THEN* insult alligator. +Wise men make proverbs, but fools repeat them... +With caller ID, Cthulhu hasn't dialed out in ages!... +With consequences, the unexpected always predominate. +Wizard's Guild Parking: Violators will be toad. +Women and cats do as they like. Men and dogs better get used to it. +Women are to be served and obeyed! +Women speak two languages, one of which is verbal +WOMEN-Wierd Obnoxious Male Enticing Nymphs +Women... you can't live with 'em... pass the beer nuts. +Women: Can't live with 'em, and sheep can't cook. +Won spell Czecker, works grate! $5 oar best offer. +Work fascinates me. I can sit and watch it for hours. +Would all ghouls in the audience please raise their talons? +Would you prefer cache or chkdsk for payment? +WOW! I Didn't know a 386 could smoke like that!!! +Write all complaints legibly in this space -> [] +Written at @TIME@, on @MONTH@ @DATE@ in Knoxville, Tn. +Written on a Cray Laptop (I'm from Texas and I'm BIG) +Yeah, but what's the speed of darkness... +Yes, I do believe that is my axe in your chest... +Yes, son, long ago, mail was written with pen and paper. +You and me against the world? Great! When do we attack?!? +You are only young once, but you can always be immature +You are the Amoeba. You have the power to Flow. +You are the Senate. You have the power to filibuster. +You can lead a man to knowledge, but you cannot make him think. +You can tie me up, but you can't tie me down. +You can trust me. I'm not a doctor. +You CAN trust the government...ask any Indian. +You could have knocked me over with a fender. +You disgust me! Do it some more.... +You don't still use a human and a keyboard do you? +You expect mere PROOF to change my opinion? +You gawddammed aliens keep your ship out of my wheat field!!! +You got any more taglines I can plagerize? +You haven't lived a full life until you're dead. +You hold 'em off, I'll go for help. (heh-heh-heh) +You Klingon son, you killed my bastard... err, wait... +You know what they say about paradigms: shift happens +You know, my sister was bitten by a moose once... +You laughable bowl of mutilated cow cud. +You live and learn. Or you don't live long. - Robert Heinlein +You make it we take it. +You may be recognized soon. Perhaps you should hide? +You may be Southern -- but you're no Comfort. +You now have 10 minutes to reach a safe distance. +You remind me of myself, confused and hungover... +You seem a decent fellow. I hate to kill you. +You shall know the truth, and it shall make you odd. +You should presently be able to deal from a full deck. +You'll never be the man your mother was! +You're a Redneck if: You're entertained by a 6-pack +You're all insane and trying to steal my magic bag +You're floatin' for a slit-throatin'... +You're in a maze of twisty echo conferences, all alike. +You're never too old to learn something stupid. +You're really strange @TO@, really strange... +You're right - now shut up, someone might hear you.... +You're sick and you're twisted...Are we related??? +You're staring at me like I'm driving the nails. +You're twisted and sick, I like that in a person. +You're twisted, perverted and sick. I like that. +You're worse than a fungus... +You've got nicer legs than Hitler... +Your eyes are a striking shade of (insert color) +Your father is waiting for you in the toolshed... +Your friendly neighbourhood Thought Police . . . +Your Lucky Number Has Been Disconnected. +Your mileage may vary. Your car may not run. +Your new credit limit is $1. Have a nice day. +Your proctologist called. He found your head. +Yours for the asking. Torture never works. +Yur'assic Park: Where you butt is on the line daily +Zealots have fanatical tendencies. +Zen Crafters - enlightenment in about an hour. +Zen Druids practice Transcendental Vegetation. +Zo! Lie here and tell me about your mother, Herr Heinlein! +Zymurgy is the best hobby around, homemade hangovers... +[Maxim XII] Plan and Replan Your Sequence -Brown +_You_ see a coffin. _I_ see a cheap living module. diff --git a/SOURCE/UNUSED/TAGSTAT.PAS b/SOURCE/UNUSED/TAGSTAT.PAS new file mode 100644 index 0000000..7548ea0 --- /dev/null +++ b/SOURCE/UNUSED/TAGSTAT.PAS @@ -0,0 +1,1722 @@ +{$M 35500,0,131072} +program tagstat; + +uses + crt, + dos, + Common; + +type + Str39 = STRING[39]; + Str43 = STRING[43]; + Str78 = STRING[78]; + + genrec = record + name : str43; + info : real; + END; + + (* + fileinfo = record + recnum: word; + filename: str12; + description: str78; + Downloaded: word; + unused: byte; + blocks: word; + owner: str36; + date: LongInt; + daten: word; + FIFlags: FIFlagSet; + points: byte; + dirpath: pathstr; + dirname: str8; + DLPath: str30; + FAflags: FAFlagSet; + areaname: str39; + area: word; + END; + + b_array = ARRAY[1..20] OF boolean; + d_array = ARRAY[1..20] OF str8; + e_array = ARRAY[1..10] OF word; + f_array = ARRAY[1..20] OF fileinfo; + g_array = ARRAY[1..20] OF longint; + gsysactivity = ARRAY[1..20] OF real; + h_array = ARRAY[1..19] OF word; + m_array = ARRAY[1..3] OF word; + *) + t_array = ARRAY[1..10] OF genrec; + + (* + configinfo = record + exuser: e_array; + graph_fg, + graph_bg, + logdays, + dldsl: byte; + use_real: boolean; + END; + *) + +VAR + (* + config: configinfo; + uage: m_array; + usex: m_array; + gdate: d_array; + ubaud: h_array; + tttimeon: t_array; + tfreqc: t_array; + tulk: t_array; + tdlk: t_array; + tprivp: t_array; + *) + tpubp: t_array; + (* + tfeedback: t_array; + tnumc: t_array; + tnumul: t_array; + tnumdl: t_array; + tfilep: t_array; + tupd: t_array; + tpostc: t_array; + gsysact: gsysactivity; + gmina: g_array; + gnumc: g_array; + gnewu: g_array; + gtimeu: g_array; + gmsgpub: g_array; + gmsgpvt: g_array; + gmsgfb: g_array; + gnume: g_array; + gful: g_array; + gulkb: g_array; + gfdl: g_array; + gdlkb: g_array; + frec: f_array; + *) + +FUNCTION RealToStr(L: Real; W,D: Integer): STRING; +VAR + S: STRING[11]; +BEGIN + Str(L:W:D,S); + RealToStr := s; +END; + +FUNCTION RmvLeadSpace(S: STRING): STRING; +BEGIN +END; + +FUNCTION RmvTrailSpace(S: STRING): STRING; +BEGIN +END; + +FUNCTION Min(X,Y: Integer): Integer; +BEGIN +END; + +FUNCTION Max(X,Y: Integer): Integer; +BEGIN +END; + +function graph_month(s: str8): str3; +BEGIN + CASE StrToInt(copy(s,1,2)) OF + 1 : graph_month := 'Jan'; + 2 : graph_month := 'Feb'; + 3 : graph_month := 'Mar'; + 4 : graph_month := 'Apr'; + 5 : graph_month := 'May'; + 6 : graph_month := 'Jun'; + 7 : graph_month := 'Jul'; + 8 : graph_month := 'Aug'; + 9 : graph_month := 'Sep'; + 10 : graph_month := 'Oct'; + 11 : graph_month := 'Nov'; + 12 : graph_month := 'Dec'; + END; +END; + +function reverse_str(s: str160): str160; +VAR + s1: str160; + Counter: byte; +BEGIN + s1 := ''; + FOR Counter := 20 downto 1 DO + s1 := s1 + s[Counter]; + reverse_str := rmvleadspace(rmvtrailspace(s1)); +END; + +function center(s: str160; i: integer; tf: boolean): str160; +VAR + Counter,strlength: integer; + which_way: boolean; +BEGIN + which_way := tf; + strlength := length(s); + FOR Counter := (strlength + 1) to i DO + BEGIN + IF which_way THEN + BEGIN + s := ' ' + s; + which_way := false; + END + ELSE + BEGIN + s := s + ' '; + which_way := true; + END; + END; + center := s; +END; + +function return_time(w,w1: word): str160; +BEGIN + IF (w > 0) AND (w1 > 0) THEN + return_time := IntToStr(trunc(w div w1)) + ELSE + return_time := '0'; +END; + +function age(s: str160): str160; +BEGIN + age := IntToStr(StrToInt(copy(datestr,7,2)) - StrToInt(copy(s,7,2))); +END; + +function return_age(userbday: str160): str160; +VAR + today,user_years: str160; +BEGIN + today := datestr; + user_years := age(userbday); + IF (StrToInt(copy(userbday,1,2)) > StrToInt(copy(today,1,2))) THEN + user_years := IntToStr(StrToInt(user_years)-1) + ELSE + IF (StrToInt(copy(userbday,1,2)) = StrToInt(copy(today,1,2))) THEN + IF (StrToInt(copy(userbday,4,2)) > StrToInt(copy(today,4,2))) THEN + user_years := IntToStr(StrToInt(user_years)-1); + return_age := user_years; +END; + +(* +PROCEDURE read_config_file(VAR config: configinfo); +VAR + f: text; + line,line1: str160; + Counter,counter1: byte; +BEGIN + Assign(f,'TAGSTAT.CFG'); + {$I-} Reset(f); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to access TAGSTAT.CFG!'); + Halt; + END; + textcolor(lightgray); + textbackground(black); + WITH config DO + BEGIN + FOR counter1 := 1 to 10 DO + exuser[counter1] := 0; + graph_fg := 9; + graph_bg := 7; + logdays := 0; + dldsl := 255; + use_real := false; + END; + Counter := 1; + counter1 := 0; + while not eof(f) DO + BEGIN + {$I-} readln(f,line); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to read TAGSTAT.CFG!'); + {$I-} Close(f); {$I+} + IF (IOResult <> 0) THEN + WriteLn(^G^G^G'Unable to close TAGSTAT.CFG!'); + Halt; + END; + line := rmvleadspace(rmvtrailspace(line)); + line1 := allcaps(line); + IF (line1 <> '') AND (line1[1] <> '%') THEN + BEGIN + IF (pos('USER_EXCLUDE',line1) = 1) AND (counter1 < 10) THEN + BEGIN + delete(line,1,12); + inc(counter1); + config.exuser[counter1] := StrToInt(rmvleadspace(line)); + END + ELSE IF (pos('DOWNLOAD_DSL',line1) = 1) THEN + BEGIN + delete(line,1,12); + config.dldsl := StrToInt(rmvleadspace(line)); + IF (config.dldsl < 0) OR (config.dldsl > 255) THEN + config.dldsl := 255; + END + ELSE IF (pos('REAL_NAME',line1) = 1) THEN + config.use_real := true + ELSE IF (pos('GRAPH_BACKGROUND',line1) = 1) THEN + BEGIN + delete(line,1,16); + config.graph_bg := StrToInt(rmvleadspace(line)); + IF (config.graph_bg < 0) OR (config.graph_bg > 15) THEN + config.graph_bg := 7; + END + ELSE IF (pos('GRAPH_BARS',line1) = 1) THEN + BEGIN + delete(line,1,10); + config.graph_fg := StrToInt(rmvleadspace(line)); + IF (config.graph_fg < 0) OR (config.graph_fg > 15) THEN + config.graph_fg := 9; + END; + END; + END; + {$I-} Close(f); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to close TAGSTAT.CFG!'); + Halt; + END; +END; +*) + +(* +PROCEDURE init_d_array(VAR gdate: d_array); +VAR + Counter: byte; +BEGIN + FOR Counter := 1 to 20 DO + gdate[Counter] := ''; +END; + +PROCEDURE init_f_array(VAR ar: f_array); +VAR + Counter: byte; +BEGIN + FOR Counter := 1 to 20 DO + WITH ar[Counter] DO + BEGIN + recnum := 0; + filename := ''; + description := ''; + Downloaded := 0; + unused := 0; + blocks := 0; + owner := ''; + date := 0; + daten := 0; + FIflags := []; + points := 0; + dirpath := ''; + dirname := ''; + DLPath := ''; + FAflags := []; + areaname := ''; + area := 0; + END; +END; + +PROCEDURE init_g_array(VAR ar: g_array; info_val: longint); +VAR + Counter: byte; +BEGIN + FOR Counter := 1 to 20 DO + ar[Counter] := info_val; +END; + +PROCEDURE init_gsysactivity(VAR gsysact: gsysactivity); +VAR + Counter: byte; +BEGIN + FOR Counter := 1 to 20 DO + gsysact[Counter] := 0.0; +END; + +PROCEDURE init_h_array(VAR ar: h_array; info_val: word); +VAR + Counter: byte; +BEGIN + FOR Counter := 1 to 19 DO + ar[Counter] := info_val; +END; + +PROCEDURE init_m_array(VAR ar: m_array; info_val: word); +VAR + Counter: byte; +BEGIN + FOR Counter := 1 to 3 DO + ar[Counter] := info_val; +END; + +*) +PROCEDURE init_t_array(VAR ar: t_array; info_val: real); +VAR + Counter: byte; +BEGIN + FOR Counter := 1 to 10 DO + BEGIN + ar[Counter].name := ''; + ar[Counter].info := info_val; + END; +END; + +PROCEDURE sort_ascending(s: str43; r: real; VAR tfreqc: t_array); +VAR + Counter,counter1: byte; +BEGIN + IF (r > 0.0) THEN + FOR Counter := 1 to 10 DO + IF (r <= tfreqc[Counter].info) THEN + BEGIN + FOR counter1 := 10 downto (Counter + 1) DO + tfreqc[counter1] := tfreqc[counter1-1]; + tfreqc[Counter].name := s; + tfreqc[Counter].info := r; + Counter := 10; + END; +END; + +PROCEDURE sort_descending(s: str43; r: real; VAR ar: t_array); +VAR + Counter,counter1: byte; +BEGIN + IF (r > 0.0) THEN + FOR Counter := 1 to 10 DO + IF (r >= ar[Counter].info) THEN + BEGIN + FOR counter1 := 10 downto (Counter + 1) DO + ar[counter1] := ar[counter1 - 1]; + ar[Counter].name := s; + ar[Counter].info := r; + Counter := 10; + END; +END; + +(* +function in_array(w: word; exuser: e_array): boolean; +VAR + Counter: byte; + tf: boolean; +BEGIN + tf := false; + FOR Counter := 1 to 10 DO + IF (w = exuser[Counter]) THEN + tf := true; + in_array := tf; +END; +*) + +PROCEDURE read_user_file(General: GeneralRecordType; VAR config: configinfo; VAR uage, + usex: m_array; VAR ubaud: h_array; VAR tfreqc,tttimeon, + tulk,tdlk,tprivp,tpubp,tfeedback,tnumc,tnumul,tnumdl, + tfilep,tupd,tpostc: t_array); +const + maxuserblock = 30000 div sizeof(UserRecordType); {* Allocate 30K *} +type + userblocktype = ARRAY[1..maxuserblock] OF UserRecordType; +VAR + uf: FILE; + userblock: ^userblocktype; + recnum,numusers,unum: word; + totuage: longint; + Counter,userage: byte; + calltot,realuserblockcount: integer; + name: str43; +BEGIN + Assign(uf,General.DataPath+'USER.LST'); + {$I-} Reset(uf,sizeof(UserRecordType)); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to access USER.LST!'); + Halt; + END; + new(userblock); + init_m_array(uage,0); + init_m_array(usex,0); + init_h_array(ubaud,0); + init_t_array(tfreqc,255.000); + init_t_array(tttimeon,0.000); + init_t_array(tulk,0.000); + init_t_array(tdlk,0.000); + init_t_array(tprivp,0.000); + init_t_array(tpubp,0.000); + init_t_array(tfeedback,0.000); + init_t_array(tnumc,0.000); + init_t_array(tnumul,0.000); + init_t_array(tnumdl,0.000);; + init_t_array(tfilep,0.000); + init_t_array(tupd,0.000); + init_t_array(tpostc,0.000); + recnum := 0; + numusers := 0; + totuage := 0; + uage[2] := 255; + seek(uf,1); + REPEAT + blockread(uf,userblock^,maxuserblock,realuserblockcount); + FOR unum := 1 to realuserblockcount DO + WITH userblock^[unum] DO + BEGIN + inc(recnum); + calltot := 0; + IF (recnum = usernum) AND not in_array(usernum,config.exuser) THEN + BEGIN + userage := AgeUser(BirthDate); + Inc(totuage,userage); + uage[2] := min(uage[2],userage); + uage[3] := max(userage,uage[3]); + IF (Sex = 'M') THEN + inc(usex[1]) + ELSE IF (Sex = 'F') THEN + inc(usex[2]) + ELSE + inc(usex[3]); + (* + IF (hbaud = 300) THEN + inc(ubaud[1]) + ELSE IF (hbaud = 1200) THEN + inc(ubaud[2]) + ELSE IF (hbaud = 1275) THEN + inc(ubaud[3]) + ELSE IF (hbaud = 2400) THEN + inc(ubaud[4]) + ELSE IF (hbaud = 4800) THEN + inc(ubaud[5]) + ELSE IF (hbaud = 7200) THEN + inc(ubaud[6]) + ELSE IF (hbaud = 9600) THEN + inc(ubaud[7]) + ELSE IF (hbaud = 12000) THEN + inc(ubaud[8]) + ELSE IF (hbaud = 14400) THEN + inc(ubaud[9]) + ELSE IF (hbaud = 16800) THEN + inc(ubaud[10]) + ELSE IF (hbaud = 19200) THEN + inc(ubaud[11]) + ELSE IF (hbaud = 21600) THEN + inc(ubaud[12]) + ELSE IF (hbaud = 24000) THEN + inc(ubaud[13]) + ELSE IF (hbaud = 26400) THEN + inc(ubaud[14]) + ELSE IF (hbaud = 28800) THEN + inc(ubaud[15]) + ELSE IF (hbaud = 38400) THEN + inc(ubaud[16]) + ELSE IF (hbaud = 57600) THEN + inc(ubaud[17]) + ELSE IF (hbaud = 64000) THEN + inc(ubaud[18]) + ELSE IF (hbaud = 115200) THEN + inc(ubaud[19]); + *) + IF config.use_real THEN + name := allcaps(RealName)+' #'+IntToStr(usernum) + ELSE + name := Name+' #'+IntToStr(usernum); + sort_ascending(name,calltot/15,tfreqc); + sort_descending(name,ttimeon,tttimeon); + sort_descending(name,uk,tulk); + sort_descending(name,dk,tdlk); + sort_descending(name,emailsent,tprivp); + sort_descending(name,msgpost,tpubp); + sort_descending(name,feedback,tfeedback); + sort_descending(name,loggedon,tnumc); + sort_descending(name,uploads,tnumul); + sort_descending(name,downloads,tnumdl); + sort_descending(name,credit,tfilep); + (* + sort_descending(name,uk/maxr(1.0,dlk),tupd); + sort_descending(name,msgpost/maxr(1.0,numcalls),tpostc); + inc(numusers); + *) + END; + END; + UNTIL (realuserblockcount < maxuserblock); + dispose(userblock); + uage[1] := totuage div numusers; + {$I-} Close(uf); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to close USER.LST!'); + Halt; + END; +END; + +PROCEDURE read_usage_file(General: GeneralRecordType; VAR config: configinfo; VAR + gdate: d_array; VAR gsysact: gsysactivity; VAR + gmina,gnumc,gnewu,gtimeu,gmsgpub,gmsgpvt,gmsgfb, + gnume,gful,gulkb,gfdl,gdlkb: g_array); +VAR + ul: text; + line: str160; + Counter: byte; + + function ajust_int_size(l,size: longint): longint; + BEGIN + IF (l < 0) THEN + ajust_int_size := 0 + ELSE IF (l > size) THEN + ajust_int_size := size + ELSE + ajust_int_size := l; + END; + + function ajust_real_size(r,size: real): real; + BEGIN + IF (r < 0.0) THEN + ajust_real_size := 0.0 + ELSE IF (r > size) THEN + ajust_real_size := size + ELSE + ajust_real_size := r; + END; + +BEGIN + Assign(ul,General.DataPath+'USAGE.LOG'); + {$I-} Reset(ul); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to access USAGE.LOG!'); + Halt; + END; + init_d_array(gdate); + init_g_array(gmina,0); + init_g_array(gnumc,0); + init_g_array(gnewu,0); + init_gsysactivity(gsysact); + init_g_array(gtimeu,0); + init_g_array(gmsgpub,0); + init_g_array(gmsgpvt,0); + init_g_array(gmsgfb,0); + init_g_array(gnume,0); + init_g_array(gful,0); + init_g_array(gulkb,0); + init_g_array(gfdl,0); + init_g_array(gdlkb,0); + FOR Counter := 1 to 5 DO + BEGIN + {$I-} readln(ul); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to read USAGE.LOG!'); + {$I-} Close(ul); {$I+} + IF (IOResult <> 0) THEN + WriteLn(^G^G^G'Unable to close USAGE.LOG!'); + Halt; + END; + END; + FOR Counter := 1 to 20 DO + IF not eof(ul) THEN + BEGIN + {$I-} readln(ul,line); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to read USAGE.LOG!'); + {$I-} Close(ul); {$I+} + IF (IOResult <> 0) THEN + WriteLn(^G^G^G'Unable to close USAGE.LOG!'); + Halt; + END; + gdate[Counter] := copy(line,1,8); + delete(line,1,8); + gmina[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,6))),99999); + delete(line,1,6); + gnumc[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,5))),9999); + delete(line,1,5); + gnewu[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,5))),9999); + delete(line,1,5); + gsysact[Counter] := ajust_real_size(valuer(rmvleadspace(copy(line,1,6))),100.0); + delete(line,1,6); + gtimeu[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,5))),9999); + delete(line,1,5); + gmsgpub[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,5))),9999); + delete(line,1,5); + gmsgpvt[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,5))),9999); + delete(line,1,5); + gmsgfb[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,5))),9999); + delete(line,1,5); + gnume[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,5))),9999); + delete(line,1,5); + gful[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,5))),9999); + delete(line,1,5); + gulkb[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,7))),999999); + delete(line,1,7); + gfdl[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,5))),9999); + delete(line,1,5); + gdlkb[Counter] := ajust_int_size(StrToInt(rmvleadspace(copy(line,1,7))),999999); + inc(config.logdays); + END; + {$I-} Close(ul); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to close USAGE.LOG!'); + Halt; + END; +END; + +(* +read_dir_file(dirpathname,uboards.filename,uboards.name,uboards.dlpathname, + uboards.noratiogroupnum shr 1,tempgrp,uboards.seenames, + uboards.flags,frec); +*) + +PROCEDURE read_dir_file(dirpath: pathstr; dirname: str8; name: str160; + dlpath: str30; area: word; + FAflags: FAFlagSet; VAR frec: f_array); +const + maxfileblock = 30000 div sizeof(FileInfoRecordType); {* Allocate 30K *} +type + fileblocktype = ARRAY[1..maxfileblock] OF FileInfoRecordType; +VAR + udir: FILE; + fileblock: ^fileblocktype; + Counter,counter1: byte; + fnum,realfileblockcount,recnum: word; +BEGIN + Assign(udir,dirpath+dirname+'.DIR'); + {$I-} Reset(udir,sizeof(FileInfoRecordType)); {$I+} + IF (IOResult = 0) THEN + BEGIN + IF (filesize(udir) > 1) THEN + BEGIN + recnum := 0; + new(fileblock); + seek(udir,1); + REPEAT + blockread(udir,fileblock^,maxfileblock,realfileblockcount); + FOR fnum := 1 to realfileblockcount DO + BEGIN + inc(recnum); + FOR Counter := 1 to 20 DO + IF (fileblock^[fnum].Downloaded > frec[Counter].Downloaded) THEN + BEGIN + IF (Counter <= (20 - 1)) THEN + FOR counter1 := (20 - 1) downto Counter DO + frec[counter1 + 1] := frec[counter1]; + frec[Counter].recnum := recnum; + frec[Counter].filename := fileblock^[fnum].filename; + frec[Counter].description := fileblock^[fnum].description; + frec[Counter].Downloaded := fileblock^[fnum].Downloaded; + frec[Counter].blocks := fileblock^[fnum].blocks; + frec[Counter].owner := fileblock^[fnum].ownername; + frec[Counter].date := fileblock^[fnum].date; + frec[Counter].daten := fileblock^[fnum].daten; + frec[Counter].FIflags := fileblock^[fnum].fIFlags; + frec[Counter].points := fileblock^[fnum].credits; + frec[Counter].dirpath := dirpath; + frec[Counter].dirname := dirname; + frec[Counter].DLPath := dlpath; + frec[Counter].FAflags := FAflags; + frec[Counter].areaname := name; + frec[Counter].area := area; + Counter := 20; + END; + END; + UNTIL (realfileblockcount < maxfileblock); + dispose(fileblock); + END; + {$I-} Close(udir); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to close '+dirname+'.DIR!'); + Halt; + END; + END; +END; + +PROCEDURE read_fboard_file(General: GeneralRecordType; VAR frec: f_array); +VAR + FileAreaFile: FILE OF FileAreaRecordType; + Filearea: FileAreaRecordType; + dirpathname: str160; + Counter: byte; + grp: ARRAY[0..127] OF integer; + tempgrp: integer; +BEGIN + Assign(FileAreaFile,General.DataPath+'FBOARDS.DAT'); + {$I-} Reset(FileAreaFile); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to access FBOARDS.DAT!'); + Halt; + END; + FOR Counter := 0 to 127 DO + grp[Counter] := -1; + tempgrp := -1; + init_f_array(frec); + while not eof(FileAreaFile) DO + BEGIN + {$I-} read(FileAreaFile,Filearea); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to read FBOARDS.DAT!'); + {$I-} Close(FileAreaFile); {$I+} + IF (IOResult <> 0) THEN + WriteLn(^G^G^G'Unable to close FBOARDS.DAT!'); + Halt; + END; + (* + IF General.dynamicfile THEN + BEGIN + inc(grp[Filearea.noratiogroupnum shr 1]); + tempgrp := grp[Filearea.noratiogroupnum shr 1]; + END + ELSE + inc(tempgrp); + *) + dirpathname := Filearea.DLPath; + (* + IF (Filearea.dsl <= thisuser.dsl) AND (Filearea.arlvl IN thisuser.ar) OR + (Filearea.dsl <= thisuser.dsl) AND (Filearea.arlvl = '@') THEN + BEGIN + *) + + read_dir_file(dirpathname,Filearea.filename,Filearea.name,Filearea.DLPath,Counter, + Filearea.FAflags,frec); + (* + END; + *) + END; + {$I-} Close(FileAreaFile); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to close FBOARDS.DAT!'); + Halt; + END; +END; + +(* +PROCEDURE menu_line(c,c1: Char; s,s1: str160); +BEGIN + IF (c <> ' ') THEN + BEGIN + IF (length(s) > 32) THEN + s := copy(s,1,32); + Prompt(#3'1['#3'3'+c+#3'1] : '+addspace(s,33,false)); + END + ELSE + Prompt(addspace(s,39,true)); + IF (c1 <> ' ') THEN + BEGIN + IF (length(s1) > 32) THEN + s1 := copy(s1,1,32); + Prompt(#3'1['#3'3'+c1+#3'1] : '+addspace(s1,33,false)); + END; + NL; +END; + +PROCEDURE menu1_line(c: Char; s: str160); +BEGIN + IF (length(s) > 73) THEN + s := copy(s,1,73); + PrintACR(#3'1['#3'3'+c+#3'1] : '+s); +END; +*) + +PROCEDURE sys_menu_line(s,s1: str160); +BEGIN + Prompt(#3'1'+s+#3'0'+s1); +END; + +PROCEDURE sys_menu_line1(s,s1: str160); +BEGIN + PrintACR(#3'1'+s+#3'0'+s1); +END; + +PROCEDURE hdr(s: str160); +BEGIN + CLS; + PrintACR(#3'5'+center('-=[ '+s+' ]=-',78,true)); + NL; +END; + +(* +PROCEDURE ftr(s: str160); +BEGIN + NL; + menu1_line('Q','Return To '+s); + NL; + Prompt(#3'4['#3'1'+realtostr1(nsl / 60,0,0)+' Mins Left'#3'4] Enter Command > '#3'1'); +END; +*) + +PROCEDURE display_t_array(decimal,width: byte; t_ar: t_array; title, + header: str160); +VAR + Counter,counter1: byte; +BEGIN + hdr('Top 10 '+title); + PrintACR(#3'2## User Name '+center(header,55,true)); + NL; + FOR Counter := 1 to 10 DO + BEGIN + Prompt(#3'4'+PadRightStr(IntToStr(Counter),2)); + IF (config.use_real) AND (t_ar[Counter].name = allcaps(thisuser.RealName)+' #'+IntToStr(usernum)) + OR (t_ar[Counter].name = thisuser.Name+' #'+IntToStr(usernum)) THEN + Prompt(' '#3'8'+t_ar[Counter].name+' '#3'9') + ELSE + Prompt(' '#3'1'+t_ar[Counter].name+' '#3'9'); + FOR counter1 := (length(t_ar[Counter].name) + 1) to 42 DO + Prompt('.'); + IF (t_ar[Counter].info > 0) THEN + PrintACR(#3'4'+PadRightStr(realtostr(t_ar[counter].info,0,decimal),width)) + ELSE + NL; + END; + PauseScr(FALSE); +END; + +(* +PROCEDURE display_t_freqcall(decimal,width: byte; t_ar: t_array; title, + header: str160); +VAR + Counter,counter1: byte; +BEGIN + hdr('Top 10 '+title); + PrintACR(#3'2## User Name '+center(header,55,true)); + NL; + FOR Counter := 1 to 10 DO + BEGIN + Prompt(#3'4'+addspace(IntToStr(Counter),2,true)); + IF config.use_real AND (t_ar[Counter].name = allcaps(thisuser.RealName)+' #'+IntToStr(thisuser.usernum)) + OR (t_ar[Counter].name = thisuser.Name+' #'+IntToStr(thisuser.usernum)) THEN + Prompt(' '#3'8'+t_ar[Counter].name+' '#3'9') + ELSE + Prompt(' '#3'1'+t_ar[Counter].name+' '#3'9'); + FOR counter1 := (length(t_ar[Counter].name) + 1) to 42 DO + Prompt('.'); + IF (t_ar[Counter].info < 255) THEN + PrintACR(#3'4'+addspace(realtostr1(t_ar[Counter].info,0,decimal),width,true)) + ELSE + NL; + END; + PauseScr(FALSE); +END; +*) + +(* +PROCEDURE graph_yes(tf: boolean; VAR first: b_array; i,g_fg,g_bg: byte); +BEGIN + IF (ANSI IN thisuser.Flags) THEN + BEGIN + ds_textcolor(g_fg); + Prompt(''); + IF first[i] THEN + BEGIN + ds_textcolor(g_bg); + Prompt(''); + first[i] := false; + END + ELSE + BEGIN + ds_textcolor(black); + Prompt(''); + IF not tf THEN + ds_textcolor(g_bg); + END; + END + ELSE + Prompt('###'); +END; + +PROCEDURE graph_no; +BEGIN + IF (ANSI IN thisuser.Flags) THEN + Prompt('') + ELSE + Prompt('...'); +END; + +PROCEDURE display_g_sysactivity(config: configinfo; gdate: d_array; gsysact: + gsysactivity; s: str160); +VAR + first: b_array; + Counter,counter1: byte; + average: real; + tf: boolean; +BEGIN + FOR Counter := 1 to 20 DO + first[Counter] := true; + average := 0.0; + CLS; + PrintACR(#3'5 '+center('-=[ Graph Of System Activity By Percentage ]=-',60,true)); + FOR Counter := 20 downto 1 DO + BEGIN + average := average + gsysact[Counter]; + IF (copy(s,Counter,1) <> ' ') THEN + Prompt(#3'5'+copy(s,Counter,1)) + ELSE + Prompt(' '); + Prompt(#3'2'+addspace(IntToStr(Counter * 5),7,true)+'% '); + FOR counter1 := 20 downto 1 DO + IF (gsysact[counter1] >= (Counter * 5)) THEN + BEGIN + tf := true; + IF (counter1 > 1) THEN + BEGIN + tf := false; + IF (gsysact[counter1 - 1] >= Counter * 5) THEN + tf := true; + END; + graph_yes(tf,first,counter1,config.graph_fg,config.graph_bg) + END + ELSE + BEGIN + IF (counter1 = 20) THEN + ds_textcolor(config.graph_bg); + graph_no; + END; + NL; + END; + ds_ansi_color(2); + tf := false; + FOR Counter := 20 downto 1 DO + IF (gdate[Counter] <> '') AND not tf THEN + BEGIN + Prompt(addspace(graph_month(gdate[Counter])+' ',11,true)); + tf := true; + END; + IF not tf THEN + Prompt(' '); + FOR Counter := 20 downto 1 DO + IF (gdate[Counter] <> '') THEN + Prompt(copy(gdate[Counter],4,2)+' ') + ELSE + Prompt(' '); + IF (gdate[1] <> '') THEN + PrintACR(graph_month(gdate[1])) + ELSE + NL; + average := average / config.logdays; + PrintACR(#3'5 '+center('(Average '+reverse_str(s)+': '+realtostr1(average,0,0)+'%)',60,true)); + PauseScr(FALSE); +END; + +PROCEDURE display_g_array(config: configinfo; gdate: d_array; g_ar: g_array; + title,side: str160; increment: longint); +VAR + first: b_array; + Counter,counter1: byte; + average: longint; + tf: boolean; +BEGIN + FOR Counter := 1 to 20 DO + first[Counter] := true; + average := 0; + CLS; + PrintACR(#3'5 '+center('-=[ Graph Of '+title+' ]=-',60,true)); + FOR Counter := 20 downto 1 DO + BEGIN + Inc(average,g_ar[Counter]); + IF (copy(side,Counter,1) <> ' ') THEN + Prompt(#3'5'+copy(side,Counter,1)) + ELSE + Prompt(' '); + Prompt(#3'2'+addspace(IntToStr(Counter * increment),7,true)+' '); + FOR counter1 := 20 downto 1 DO + IF (g_ar[counter1] >= (Counter * increment)) THEN + BEGIN + tf := true; + IF (counter1 > 1) THEN + BEGIN + tf := false; + IF (g_ar[counter1 - 1] >= (Counter * increment)) THEN + tf := true; + END; + graph_yes(tf,first,counter1,config.graph_fg,config.graph_bg) + END + ELSE + BEGIN + IF (counter1 = 20) THEN + ds_textcolor(config.graph_bg); + graph_no; + END; + NL; + END; + ds_ansi_color(2); + tf := false; + FOR Counter := 20 downto 1 DO + IF (gdate[Counter] <> '') AND not tf THEN + BEGIN + Prompt(addspace(graph_month(gdate[Counter])+' ',11,true)); + tf := true; + END; + IF not tf THEN + Prompt(' '); + FOR Counter := 20 downto 1 DO + IF (gdate[Counter] <> '') THEN + Prompt(copy(gdate[Counter],4,2)+' ') + ELSE + Prompt(' '); + IF (gdate[1] <> '') THEN + PrintACR(graph_month(gdate[1])) + ELSE + NL; + average := average div config.logdays; + PrintACR(#3'5 '+center('(Average '+reverse_str(side)+': '+IntToStr(average)+')',60,true)); + PauseScr(FALSE); +END; + +function div_g(g: g_array): longint; +VAR + i: byte; + Counter: longint; + big: longint; + num: real; + + function div_size(num: real): longint; + BEGIN + IF (num <= 1) THEN + div_size := 1 + ELSE IF (num < 2) THEN + div_size := 2 + ELSE IF (num < 3) THEN + div_size := 3 + ELSE IF (num < 4) THEN + div_size := 4 + ELSE IF (num < 5) THEN + div_size := 5 + ELSE + BEGIN + Counter := 5; + REPEAT + Inc(Counter); + UNTIL (num > 999999) OR (Counter > num); + div_size := Counter; + END; + END; + +BEGIN + big := 0; + FOR i := 1 to 20 DO + big := max(big,g[i]); + num := big / 20; + div_g := div_size(num); +END; + +PROCEDURE display_m_array(m_ar: m_array; title,desc1,desc2,desc3: str160; StrToInt: byte); +VAR + len: byte; + + PROCEDURE m_line(s: str160; w: word); + VAR + Counter: byte; + BEGIN + Prompt(#3'1'+s+' '#3'9'); + FOR Counter := 1 to (len - length(s)) DO + Prompt('.'); + PrintACR(#3'4'+addspace(IntToStr(w),StrToInt+1,true)); + END; + +BEGIN + len := 0; + len := max(len,length(desc1)); + len := max(len,length(desc2)); + len := max(len,length(desc3)); + Inc(len,3); + hdr(title); + m_line(desc1,m_ar[1]); + m_line(desc2,m_ar[2]); + IF (desc3 = 'Total Not Specified') AND (m_ar[3] > 0) OR (desc3 = 'The Oldest User Is') THEN + m_line(desc3,m_ar[3]); + PauseScr(FALSE); +END; + +PROCEDURE display_h_array(ubaud: h_array); + + PROCEDURE baud_line(s: str160; w: word); + VAR + Counter: byte; + BEGIN + Prompt(#3'1Total '+s+' Baud Callers '#3'9'); + FOR Counter := 1 to (27 - length('Total '+s+' Baud Callers')) DO + Prompt('.'); + PrintACR(#3'4'+addspace(IntToStr(w),6,true)); + END; + +BEGIN + hdr('User Baud Rate Statistics'); + IF (ubaud[1] > 0) THEN + baud_line('300',ubaud[1]); + IF (ubaud[2] > 0) THEN + baud_line('1200',ubaud[2]); + IF (ubaud[3] > 0) THEN + baud_line('1275',ubaud[3]); + IF (ubaud[4] > 0) THEN + baud_line('2400',ubaud[4]); + IF (ubaud[5] > 0) THEN + baud_line('4800',ubaud[5]); + IF (ubaud[6] > 0) THEN + baud_line('7200',ubaud[6]); + IF (ubaud[7] > 0) THEN + baud_line('9600',ubaud[7]); + IF (ubaud[8] > 0) THEN + baud_line('12000',ubaud[8]); + IF (ubaud[9] > 0) THEN + baud_line('14400',ubaud[9]); + IF (ubaud[10] > 0) THEN + baud_line('16800',ubaud[10]); + IF (ubaud[11] > 0) THEN + baud_line('19200',ubaud[11]); + IF (ubaud[12] > 0) THEN + baud_line('21600',ubaud[12]); + IF (ubaud[13] > 0) THEN + baud_line('24000',ubaud[13]); + IF (ubaud[14] > 0) THEN + baud_line('26400',ubaud[14]); + IF (ubaud[15] > 0) THEN + baud_line('28800',ubaud[15]); + IF (ubaud[16] > 0) THEN + baud_line('38400',ubaud[16]); + IF (ubaud[17] > 0) THEN + baud_line('57600',ubaud[17]); + IF (ubaud[18] > 0) THEN + baud_line('64000',ubaud[18]); + IF (ubaud[19] > 0) THEN + baud_line('115200',ubaud[19]); + PauseScr(FALSE); +END; + +PROCEDURE todayusage(General: GeneralRecordType); +BEGIN + CLS; + WITH General DO + BEGIN + PrintACR(#3'5'+center('-=[ Todays Usage ]=-',78,true)); + sys_menu_line(' Date:',datestr); + sys_menu_line1(' Time:',timestr); + NL; + sys_menu_line1('Board Name :',boardname); + sys_menu_line1('Node Number :',IntToStr(nodenumber)); + sys_menu_line1('Board Address :',boardcitystate); + sys_menu_line1('SysOp Name :',sysopname); + sys_menu_line1('Phone Number :',boardphone); + sys_menu_line('Mail Address :',IntToStr(address.zone)+':'+IntToStr(address.net)+'/'+IntToStr(address.node)); + IF (address.point > 0) THEN + PrintACR('.'+IntToStr(address.point)) + ELSE + NL; + sys_menu_line1('BBS Software :','T.A.G. Version '+lasttagversion); + NL; + sys_menu_line1('Total Calls :',realtostr1(callernum,0,0)); + sys_menu_line1('Number Of Users :',realtostr1(users,0,0)); + sys_menu_line1('Last Caller :',lastcaller); + NL; + PrintACR(#3'5'+center('-=[ Summary Of Activity ]=-',78,true)); + sys_menu_line('Minutes Active :',addspace(IntToStr(activetoday),9,false)); + sys_menu_line('Calls Today :',addspace(IntToStr(callstoday),9,false)); + sys_menu_line1('New Users Today :',addspace(IntToStr(nuserstoday),9,false)); + sys_menu_line('Percent Active :',addspace(return_percent(activetoday),9,false)); + sys_menu_line('Time/User :',addspace(return_time(activetoday,callstoday),9,false)); + sys_menu_line1('Public Posts :',addspace(IntToStr(msgposttoday),9,false)); + sys_menu_line('Private Posts :',addspace(IntToStr(emailtoday),9,false)); + sys_menu_line('Feedback Sent :',addspace(IntToStr(fbacktoday),9,false)); + sys_menu_line1('Errors Today :',addspace(IntToStr(errorstoday),9,false)); + sys_menu_line('Number Uploads :',addspace(IntToStr(ultoday),9,false)); + sys_menu_line('UL K-Bytes :',addspace(realtostr1(ulktoday,0,0)+'K',9,false)); + sys_menu_line1('Number Downloads:',addspace(IntToStr(dltoday),9,false)); + sys_menu_line1('DL K-Bytes :',addspace(realtostr1(dlktoday,0,0)+'K',9,false)); + END; + PauseScr(FALSE); +END; + +PROCEDURE chlen(s: str78; i,i1: integer); +VAR + line1,line2,temp: str160; + Counter: integer; +BEGIN + s := rmvleadspace(rmvtrailspace(s)); + while (pos(' ',s) > 0) DO + delete(s,pos(' ',s),1); + IF (length(s) > i) THEN + BEGIN + line1 := copy(s,1,i); + while (line1[length(line1)] <> ' ') DO + BEGIN + delete(line1,length(line1),1); + dec(i); + END; + line1 := rmvtrailspace(line1); + line2 := copy(s,i + 1,length(s)); + line2 := rmvleadspace(line2); + temp := ''; + FOR Counter := 1 to i1 DO + temp := ' ' + temp; + PrintACR(#3'0'+line1); + Prompt(temp); + Prompt(#3'1:'); + PrintACR(#3'0'+line2); + END + ELSE + PrintACR(#3'0'+s); +END; + +PROCEDURE write_status_file(General: GeneralRecordType); +VAR + systatf: FILE OF GeneralRecordType; +BEGIN + Assign(systatf,paramstr(1)+'\RENEGADE.DAT'); + {$I-} Reset(systatf); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to access STATUS.DAT!'); + Halt; + END; + {$I-} Write(systatf,General); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to close STATUS.DAT!'); + {$I-} Close(systatf); {$I+} + IF (IOResult <> 0) THEN + WriteLn(^G^G^G'Unable to close STATUS.DAT!'); + Halt; + END; + {$I-} Close(systatf); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to close STATUS.DAT!'); + Halt; + END; +END; + +PROCEDURE write_user_file(user: UserRecordType); +VAR + uf: FILE OF UserRecordType; + fvar: dos.filerec; +BEGIN + Assign(uf,General.DataPath+'USER.LST'); + {$I-} Reset(uf); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to access USER.LST!'); + Halt; + END; + seek(uf,user.usernum); + WITH fvar DO + lockfile(handle,lock,user.usernum*recsize,recsize); + {$I-} Write(uf,user); {$I+} + WITH fvar DO + lockfile(handle,unlock,user.usernum*recsize,recsize); + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to close USER.LST!'); + {$I-} Close(uf); {$I+} + IF (IOResult <> 0) THEN + WriteLn(^G^G^G'Unable to close USER.LST!'); + Halt; + END; + {$I-} Close(uf); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to close USER.LST!'); + Halt; + END; +END; + +PROCEDURE write_dir_file(b: byte; frec: f_array); +VAR + udir: FILE OF FileInfoRecordType; + udirfile: FileInfoRecordType; + fvar: dos.filerec; +BEGIN + Assign(udir,frec[b].dirpath+frec[b].dirname+'.DIR'); + {$I-} Reset(udir); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to access '+frec[b].dirname+'.DIR!'); + Halt; + END; + WITH udirfile DO + BEGIN + filename := frec[b].filename; + description := frec[b].description; + Downloaded := frec[b].Downloaded + 1; + unused := frec[b].unused; + blocks := frec[b].blocks; + owner := frec[b].owner; + date := frec[b].date; + daten := frec[b].daten; + flag := frec[b].flag; + points := frec[b].points; + END; + seek(udir,frec[b].recnum); + WITH fvar DO + lockfile(handle,lock,frec[b].recnum*recsize,recsize); + {$I-} Write(udir,udirfile); {$I+} + WITH fvar DO + lockfile(handle,unlock,frec[b].recnum*recsize,recsize); + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to close '+frec[b].dirname+'.DIR!'); + {$I-} Close(udir); {$I+} + IF (IOResult <> 0) THEN + WriteLn(^G^G^G'Unable to close '+frec[b].dirname+'.DIR!'); + Halt; + END; + {$I-} Close(udir); {$I+} + IF (IOResult <> 0) THEN + BEGIN + WriteLn(^G^G^G'Unable to close '+frec[b].dirname+'.DIR!'); + Halt; + END; +END; + +PROCEDURE top20file(frec: f_array); +VAR + c: Char; + s,s1: str160; + Counter,counter1: byte; + tempsize: longint; + tf: boolean; +BEGIN + REPEAT + REPEAT + counter1 := 0; + c := #0; + s := ''; + hdr('Top 20 Files Downloaded'); + PrintACR(#3'2## Filename.Ext Number Downloads ## Filename.Ext Number Downloads'); + NL; + FOR Counter := 1 to 10 DO + BEGIN + Prompt(#3'4'+addspace(IntToStr(Counter),2,true)); + Prompt(#3'1'+addspace(frec[Counter].filename,15,true)); + IF (frec[Counter].Downloaded > 0) THEN + BEGIN + Prompt(#3'4'+addspace(IntToStr(frec[Counter].Downloaded),12,true)); + inc(counter1); + END + ELSE + Prompt(' '); + Prompt(' '); + Prompt(#3'4'+addspace(IntToStr(Counter+10),2,true)); + Prompt(#3'1'+addspace(frec[Counter+10].filename,15,true)); + IF (frec[Counter+10].Downloaded > 0) THEN + BEGIN + PrintACR(#3'4'+addspace(IntToStr(frec[Counter+10].Downloaded),12,true)); + inc(counter1); + END + ELSE + PrintACR(' '); + END; + NL; + menu1_line('#','Number for Extended File Information'); + menu1_line('Q','Return To T.A.G. Statistics File Menu'); + NL; + Prompt(#3'4['#3'1'+realtostr1(nsl / 60,0,0)+' Mins Left'#3'4] Enter Command > '#3'1'); + IF (length(IntToStr(counter1)) = 1) THEN + BEGIN + FOR Counter := 1 to counter1 DO + s := s + IntToStr(Counter); + OneK(c,'Q'+s); + s := c; + END + ELSE + BEGIN + ds_input(s,2,false,false,true,false); + s := rmvleadspace(s); + END; + UNTIL (s <> #1) OR ds_hangup; + IF (StrToInt(s) >= 1) AND (StrToInt(s) <= counter1) THEN + BEGIN + hdr('Extended File Information'); + WITH frec[StrToInt(s)] DO + BEGIN + PrintACR(#3'1Group # :'#3'5'+IntToStr(group)); + PrintACR(#3'1Area # :'#3'5'+IntToStr(area)); + PrintACR(#3'1Area Name :'#3'5'+striptagcodes(areaname)); + Prompt(#3'1File Name :'#3'0'+rmvspace(filename)); + IF (notvalidated IN flag) THEN + Prompt(#3'8 '); + NL; + Prompt(#3'1Description :'); + chlen(description,65,13); + PrintACR(#3'1File Points :'#3'5'+IntToStr(points)); + Prompt(#3'1File Size :'); + tempsize := blocks; + Prompt(#3'5'+IntToStr(tempsize * 128)+' Bytes / '); + Prompt(IntToStr(tempsize)+' XModem Blks / '); + PrintACR(realtostr1(((tempsize * 128) + 1023) / 1024,0,0)+' YModem Blks'); + PrintACR(#3'1Date U/L''ed :'#3'5'+date); + PrintACR(#3'1Times D/L''ed :'#3'3'+IntToStr(Downloaded)); + IF (thisuser.dsl >= seenames) THEN + PrintACR(#3'1Uploaded By :'#3'3'+owner); + NL; + IF (thisuser.dsl >= config.dldsl) THEN + BEGIN + Prompt(#3'7Download file (y/[N]? '); + IF ds_yesnoresp THEN + BEGIN + NL; + tf := true; + IF (ISCDROM IN flags) THEN + BEGIN + Prompt('Copying file ... '); + swapvectors; + exec(getenv('COMSPEC'),'/C copy '+DLPath+rmvspace(filename)+ + ' '+copy(General.tempdlpath,1,length(General.tempdlpath)-1)); + swapvectors; + IF (doserror = 0) THEN + BEGIN + PrintACR('Successful'); + DLPath := General.tempdlpath; + tf := true; + END + ELSE + BEGIN + PrintACR('Failed'); + tf := false; + END; + NL; + END; + IF tf THEN + BEGIN + Prompt('['#3'3X'#3'1]Modem, ['#3'3Y'#3'1]Modem, ['#3'3Z'#3'1]Modem, ['#3'3Q'#3'1]uit: '); + OneK(c,'QXYZ'); + CASE c OF + 'X' : s1 := 'protocol dsz port '+IntToStr(General.comport)+' sx -s '+DLPath+rmvspace(filename); + 'Y' : s1 := 'protocol dsz port '+IntToStr(General.comport)+' sb -s '+DLPath+rmvspace(filename); + 'Z' : s1 := 'protocol dsz port '+IntToStr(General.comport)+' sz -m -s '+DLPath+rmvspace(filename); + END; + IF (c <> 'Q') THEN + BEGIN + NL; + Prompt('Ready to send file, ^X to abort...'); + swapvectors; + exec(getenv('COMSPEC'),'/C '+s1); + swapvectors; + delay(2000); + General.dlktoday := General.dlktoday + (((tempsize * 128) + 1023) / 1024); + Inc(General.dltoday); + write_status_file(General); + thisuser.dlk := thisuser.dlk + (((tempsize * 128) + 1023) / 1024); + Inc(thisuser.numdl); + write_user_file(thisuser); + write_dir_file(StrToInt(s),frec); + ds_sysop_window; + END; + END; + END; + END + ELSE + PauseScr(FALSE); + END; + END; + UNTIL (s[1] = 'Q') OR DS_hangup; +END; + + +PROCEDURE mainmenuscr(bbsname: str160); +BEGIN + hdr('T.A.G. Statistics Main Menu'); + menu1_line('A','User Statistics'); + menu1_line('B','Usage Statistics'); + menu1_line('C','File Statistics'); + ftr(bbsname); +END; + +PROCEDURE usermenuscr; +BEGIN + hdr('T.A.G. Statistics User Menu'); + menu1_line('A','Top 10 User Menu'); + menu1_line('B','User Age'); + menu1_line('C','User Gender'); + menu1_line('D','User Baud Rate'); + ftr('T.A.G. Statistics Main Menu'); +END; + +PROCEDURE usagemenuscr; +BEGIN + hdr('T.A.G. Statistics Usage Menu'); + menu1_line('A','Usage Graph Menu'); + menu1_line('B','Todays Usage'); + ftr('T.A.G. Statistics Main Menu'); +END; + +PROCEDURE fboardmenuscr; +BEGIN + hdr('T.A.G. Statistics File Menu'); + menu1_line('A','Top 20 Files Downloaded'); + ftr('T.A.G. Statistics Main Menu'); +END; + +PROCEDURE top10menuscr; +BEGIN + hdr('T.A.G. Statistics Top 10 User Menu'); + menu_line('A','B','Most Frequent Callers','High Time Users'); + menu_line('C','D','File Kbyte Uploaders','File Kbyte Downloaders'); + menu_line('E','F','Private Message Senders','Public Message Posters'); + menu_line('G','H','SysOp Feedback Senders','All Time Callers'); + menu_line('I','J','File Uploaders','File Downloaders'); + menu_line('K','L','File Points','Upload/Download Ratios'); + menu_line('M',' ','Post/Call Ratios',''); + ftr('T.A.G. Statistics User Menu'); +END; + +PROCEDURE graph20menuscr; +BEGIN + hdr('T.A.G. Statistics Usage Graph Menu'); + menu_line('A','B','Minutes Active','Number Of Calls'); + menu_line('C','D','New User Logons','System Activity'); + menu_line('E','F','Average Time/User','Public Message Posting'); + menu_line('G','H','Private Message Posting','SysOp Feedback Sent'); + menu_line('I','J','Number Of Errors','File Uploads'); + menu_line('K','L','File Kbytes Uploaded','File Downloads'); + menu_line('M',' ','File Kbytes Downloaded',''); + ftr('T.A.G. Statistics Usage Menu'); +END; + +PROCEDURE mainmenu(General: GeneralRecordType; config: configinfo; tfreqc,tttimeon, + tulk,tdlk,tprivp,tpubp,tfeedback,tnumc, + tnumul,tnumdl,tfilep,tupd,tpostc: t_array; gdate: d_array; + gsysact: gsysactivity; gmina,gnumc,gnewu,gtimeu,gmsgpub, + gmsgpvt,gmsgfb,gnume,gful,gulkb,gfdl,gdlkb: g_array; + uage,usex: m_array; ubaud: h_array; frec: f_array); +VAR + c: Char; +BEGIN + REPEAT + mainmenuscr(General.boardname); + OneK(c,'QABC'); + CASE c OF + 'A' : BEGIN + REPEAT + usermenuscr; + OneK(c,'QABCD'); + CASE c OF + 'A' : BEGIN + REPEAT + top10menuscr; + OneK(c,'QABCDEFGHIJKLM'); + CASE c OF + 'A' : display_t_freqcall(3,12,tfreqc,'Most Frequent Callers', + 'Average Number Of Days Between Calls'); + 'B' : display_t_array(0,8,tttimeon,'High Time Users', + 'Total Number Of Minutes Online'); + 'C' : display_t_array(0,8,tulk,'File Kbyte Uploaders', + 'Number Of Kbytes Uploaded'); + 'D' : display_t_array(0,8,tdlk,'File Kbyte Downloaders', + 'Number Of Kbytes Downloaded'); + 'E' : display_t_array(0,6,tprivp,'Private Message Senders', + 'Number Of Private Messages Sent'); + 'F' : display_t_array(0,6,tpubp,'Public Message Posters', + 'Number Of Public Messages Posted'); + 'G' : display_t_array(0,6,tfeedback,'SysOp Feedback Senders', + 'Number Of SysOp Feedback Sent'); + 'H' : display_t_array(0,6,tnumc,'All Time Callers', + 'Number Of Calls To The System'); + 'I' : display_t_array(0,6,tnumul,'File Uploaders', + 'Number Of Files Uploaded'); + 'J' : display_t_array(0,6,tnumdl,'File Downloaders', + 'Number Of Files Downloaded'); + 'K' : display_t_array(0,6,tfilep,'File Points', + 'Amount Of File Points On Hand'); + 'L' : display_t_array(3,12,tupd,'Upload/Download Ratios', + 'Number Of KB Uploaded for Each KB Downloaded'); + 'M' : display_t_array(3,12,tpostc,'Post/Call Ratios', + 'Number Of Public Messages Posted Each Call'); + END; + UNTIL (c = 'Q') OR ds_hangup; + c := #0; + END; + 'B' : display_m_array(uage,'User Age Statistics','The Average User Age Is', + 'The Youngest User Is','The Oldest User Is',3); + 'C' : display_m_array(usex,'User Gender Statistics','Total Male Users', + 'Total Female Users','Total Not Specified',5); + 'D' : display_h_array(ubaud); + END; + UNTIL (c = 'Q') OR ds_hangup; + c := #0; + END; + 'B' : BEGIN + REPEAT + usagemenuscr; + OneK(c,'QAB'); + CASE c OF + 'A' : BEGIN + REPEAT + graph20menuscr; + OneK(c,'QABCDEFGHIJKLM'); + CASE c OF + 'A' : display_g_array(config,gdate,gmina,'Total Minutes Active', + ' setuniM ',div_g(gmina)); + 'B' : display_g_array(config,gdate,gnumc,'Total Calls', + ' sllaC ',div_g(gnumc)); + 'C' : display_g_array(config,gdate,gnewu,'New User Logons To System', + ' sresU weN ',div_g(gnewu)); + 'D' : display_g_sysactivity(config,gdate,gsysact,' tnecreP '); + 'E' : display_g_array(config,gdate,gtimeu,'Average Time/User', + ' setuniM ',div_g(gtimeu)); + 'F' : display_g_array(config,gdate,gmsgpub,'Public Messages Posted', + ' segasseM ',div_g(gmsgpub)); + 'G' : display_g_array(config,gdate,gmsgpvt,'Private Messages Sent', + ' segasseM ',div_g(gmsgpvt)); + 'H' : display_g_array(config,gdate,gmsgfb,'SysOp Feedback Sent', + ' segasseM ',div_g(gmsgfb)); + 'I' : display_g_array(config,gdate,gnume,'Logon Errors', + ' srorrE ',div_g(gnume)); + 'J' : display_g_array(config,gdate,gful,'File Uploads', + ' seliF ',div_g(gful)); + 'K' : display_g_array(config,gdate,gulkb,'Total Upload Kbytes', + ' setybK ',div_g(gulkb)); + 'L' : display_g_array(config,gdate,gfdl,'File Downloads', + ' seliF ',div_g(gfdl)); + 'M' : display_g_array(config,gdate,gdlkb,'Total Download Kbytes', + ' setybK ',div_g(gdlkb)); + END; + UNTIL (c = 'Q') OR ds_hangup; + c := #0; + END; + 'B' : todayusage(General); + END; + UNTIL (c = 'Q') OR ds_hangup; + c := #0; + END; + 'C' : BEGIN + REPEAT + fboardmenuscr; + OneK(c,'QA'); + CASE c OF + 'A' : top20file(frec); + END; + UNTIL (c = 'Q') OR DS_hangup; + c := #0; + END; + END; + UNTIL (c = 'Q') OR DS_hangup; +END; +*) + +VAR + GeneralFile: FILE OF GeneralRecordType; + General: GeneralRecordType; + +BEGIN + (* + read_config_file(config,chatconfig); + read_usage_file(General,config,gdate,gsysact,gmina,gnumc,gnewu,gtimeu, + gmsgpub,gmsgpvt,gmsgfb,gnume,gful,gulkb,gfdl,gdlkb); + *) + Assign(GeneralFile,'C:\RG\RENEGADE.DAT'); + Reset(GeneralFile); + Read(GeneralFile,General); + Close(GeneralFile); + + read_user_file(General,config,uage,usex,ubaud,tfreqc,tttimeon,tulk,tdlk, + tprivp,tpubp,tfeedback,tnumc,tnumul,tnumdl,tfilep,tupd, + tpostc); + display_t_array(0,6,tpubp,'Public Message Posters','Number Of Public Messages Posted'); + (* + read_fboard_file(General,frec); + mainmenu(General,config,tfreqc,tttimeon,tulk,tdlk,tprivp,tpubp, + tfeedback,tnumc,tnumul,tnumdl,tfilep,tupd,tpostc,gdate,gsysact, + gmina,gnumc,gnewu,gtimeu,gmsgpub,gmsgpvt,gmsgfb,gnume,gful,gulkb, + gfdl,gdlkb,uage,usex,ubaud,frec); + *) +END. diff --git a/SOURCE/UNUSED/TEMP6.BAT b/SOURCE/UNUSED/TEMP6.BAT new file mode 100644 index 0000000..36a118a --- /dev/null +++ b/SOURCE/UNUSED/TEMP6.BAT @@ -0,0 +1,8 @@ +@ECHO OFF +F: +CD F:\RG\TEMP6\ARC +F:\RG\ARCS\PKUNZIP -o F:\RG\FILES\NEWUP\TDRAW463.ZIP FILE_ID.DIZ DESC.SDI +:DONE +F: +CD F:\RG110 +Exit diff --git a/SOURCE/UNUSED/TIMEBANK.TPU b/SOURCE/UNUSED/TIMEBANK.TPU new file mode 100644 index 0000000000000000000000000000000000000000..0dd343f3c315fda7f5ccf457af380ba8dd300245 GIT binary patch literal 4672 zcmd^CeQZ-z6hE)+pnxb(a7;erO%W#I7{LKFY1oP-dAfDt0{5sASM5Cl=gh)zHjK#f2q7@X&xcOI>51H?c4!;bOmJs-b& z?z!*$x{9oc698YeFcsWNxw1%kg?_dx2b9D31JJUS6CQ3UW2S;l!asUdaCGfevRdOV z&AsZ$ao<%Un#+vYbDY8#@C2Jj z#UbrBN0MElwV8zgm$?AqPJwo_dJOF3?~r+u7(H&p&>@eGNzEFPBeyxgwL$viU~xz@ z@ch~|Y=Gu<6=@-ltHA4VYlhdO1ze@RKyg6x`vN{gbNT(j5|2BzCuV5{E?o~An%nG& z=F-cwKrrMn$&8@eRhHT@KV7y~^LwTnT2S}?7>ZyulJYg)Gje7aN|UwEO|GdUsIoY2b0gSg_Y+ zXo2DauUQNgYXq%>CAT*d@VN2_Wtz+F){-qY+*K=+EwpMb^n^65BUz)YnB8iV*+^fJ z*2xZ}vlY*2-4pgXv9p;D60yHTH%Jsj4^@-!r_LJ90PgfULed`hJm}wYi~E0`pTj*FR|B6QDQC4&T7=Y$x|{9RJJJZoVhdHv8rNk{6>^l*ID5lJ3bxlV~@>f z`PhVqS*Ocry3Gy!0pxG2hAW<|y7!@J{!zp~)Z%~O2Ki4t#`Fr7t77?$m-nFO2HEGI z&ik}qoSc=Qe!Ee>uh27hamc4Xfl`5!TYxf{nsV(NQv;Kl&_EI|%MmYvmP4wbRf)?l z1y9N#X2_2hSsn_fDR-371@+GIG!ne@>k>SyB3{RmdtFvNDe_h=rdGNFB+tR=B$%n~ zWBO$l;VFr!TXXVdDb;6bk4)NQp!@(O|JO*!U0p`3R$FD$XD;$VDrBrK=O8c((S zgp-qfyE*f6{AbBe1|yMDW?zKLmgTJnZGv#ZN9g-E3V_*7zmn2cDFAB~NSkE`*r-4R zAR;ysM#Wab8R`x~uezIY58L-EZL%cq5hW>Y65{vBQ;Iyt5mS)&48<)G=LwgI3xv9Q ziO{bm*yMhGwKbux-fWY6{UOO_@^!VDe0L&BzFy?dhk@)Lg!TyjQ9cSW3H{^IUW#=H z&YMi}VQ_Q2kM@ZOgD@&e(Vl|wvp9bq=P%;?mnd$A`ZA$cT}6D0VIA|m!}hHlw}bh1 zGvDXTcaZrGQ=G0ICG@K&iLVCEG2aEYJM6MAy6Uu>^|iB`=j(`TdA=^VmVHj9xFw@Nex!w6;N% z?JLnPpPRR&AMaru+c$FDd%WLv;{6T2WZrLhzoQ)g6UU$8dVk@1&l2itJ)vK1V01XR zKMr}`yOj10^SnuH?@s7fQyh@C8^46yi+RXfr1Lrh{j!gP9p*Vl653!4nLUW9FBW|>sZM9Mks!!vXs{=xQ^GjjvB6GE#)r} zZxb#P8`%FY`?ruiB0eCDikkVGH)gGKF_=hD85=OCae)scVxXw*}t6Z5%DTvRIFxy zHLbJ78atqV<)bc{&&LK{@1p$&D|>nW1I#D&Nb>)P@lrQVpkF>mrzk#0`IXn_(J$xX GqWv#L^z`ij literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/TIMEFUNC.TPU b/SOURCE/UNUSED/TIMEFUNC.TPU new file mode 100644 index 0000000000000000000000000000000000000000..605e0529a111d4a0dbaefc821ee1065820c7f827 GIT binary patch literal 8048 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/TPX.TP b/SOURCE/UNUSED/TPX.TP new file mode 100644 index 0000000000000000000000000000000000000000..c7475f9d4e9fbfb23492e50e5669b3c627f654cf GIT binary patch literal 4069 zcmeH~Pi#}!6~@o;xz2M4#3T+R1SK}a(}ZV8Vw~}HQeu-BCs2rEY$t|Jn2{mQG{QI! zCorZnlc*!H=%SUXs#3eDK;3i}Wl=WFNK;j`Qmb}R%`j8C=#0vui|l99D#iV7LZ?&I z&4{q$z5KrW|GabVb?$pNf313PDUc~HUn-UZ$)(D|;_KI{#g)aSN?>BKTzQW2^QF;DjFJnAS}T)HPn^kT zztsM0+2&w+I#(FW1O`%>+;sZcjG56)|FoIBp00wM==i3+TORyyY(sN$WG2gC7h=jv)R zoZT#k2cAk3WO;Xl&Bm~0-~UwmKq8*-ulYOUao@;o$EmGZmKV30y=6YhsalEw}Ja|(6|Ecj19bxh5cJmlx5_;Q#(JlMt zsbBOoRq)VQKngRao7ap%t@$(2{I~y>h5z-?akjxj%c942+}(nm+FbQtuhr|1z~Aa% zgA~>4kCA;`AEGge@dyQ6FVp9)R@zU;glR#9ilQhjZpumnEs8}I@laVBsYf-@sO+Tg zt7h^mFC}F+y{TI0xU|xo_$VW7v?6=yUDZzKrGxUaj~wZwS?Sc@lP>)O*{^>j_o8Kq z>9Twh&B()OTK*i(%3q>+`7k;sA4QAuAbLYSj$W5fqwlKEq80f>FUUi^C=c|Se5~J+ zkMvFXP`@L?u<>5BN6qM;NZ7m3-`>WRadl zdRG5Jvih#Ps{g1y)qheK^aJ&o?oc1-UG8yuBo~1TBx$$01O%L*x79pQ;3PGxZvhWD zMf=qvXauL}?{XP5fitu&Wv~-u=*P+dyTMtEzY1DFmTsylXazaCrIvvYQFbpJ}^ixsWA1aqZCpR>Q_S)Rxi_#ijr2EMpTSO z)i51bWAsB+1PsQhj+pC+xsI4`$|WG+1l^E%pg@Y=k`i!(3Hq*D01e%(p4-8TgF`PsUQ-~pp7z&7C z4lxuF!vbQsj2ImC3SCqC!3CvBg;)9=(0@PaJe$DH5C zoZrVhf1p-C80VecZ-*p5Z;bm-mfw=O{~sv^d~qnkl>*Nzsj%i5gt68 z;4nCv;1o~r@UAw_u_o5c+QnK}E7oq-4XiEJ9@dQag)^Inx^YV0fpYVBb?J@eQgzxfhw9}=c#2eR+lPQN|lxQ nT}1E0P~*u`*)d1;|gpK*Nb#rLE{c16T!Jd7~S2+|`<9%^L_ z3|6S**NeKAwSyhV65i7DMYh)ehu6g3kED!gOj2-`kOHe0kpy(=N!A8|ad(_!e)Ys? z=EmH+KZgQW$^D+?1WdSQ?D|m@=^eR3X7&ah5MjqmNLUi|#XR8wtYaaUBifVPh0_mP z9#dE(yl1g33_hcbZfIrah;Ctwf{sz7p!LjA|1x4zi}p}sf2LNT6(!mq3sYl>NIX^* zQ}lMJMX^FE3sYmU%|3`cjh~`sCkdsA(mfld#(&uMOM55iXoG{y3v?*6+fJTw!2gkc)yeDit4@2IBfgM_ zROgA=;YiiV_Kb%=q|5A=I!;=Bq&o`rQEC#h*lU=mUmsMzDibBEL?VIuQ1;fXeSwXY z(-+uSXE@{|Pv82#Rb~^Q-vN~b-(zEGvr*eBwVFGfcA4}|dVHDfR=ZITQ+Jh~P-fRO n8#^7XX?`O08@c(re}c~mbc7K5A2i#YmiZL9bUHsye}aDjod*mf literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/USER.PAS b/SOURCE/UNUSED/USER.PAS new file mode 100644 index 0000000..32d5ea2 --- /dev/null +++ b/SOURCE/UNUSED/USER.PAS @@ -0,0 +1,328 @@ +{$A+,B-,D-,E-,F+,I-,L-,N-,O+,R-,S+,V-} + +{ User related functions } + +unit User; + +interface + +uses + common; + +procedure changeconf(var v:str8); +procedure finduserws(var x:integer); +procedure changearflags(const cms:astr); +procedure changeacflags(const cms:astr); +procedure finduser(var usernum:integer); +procedure InsertIndex(uname:astr;usernum:integer;IsReal,IsDeleted:boolean); + +implementation + +uses + dos; + +procedure changeconf(var v:str8); +var + c:char; + done:boolean; + + procedure listconfs; + var i,onlin:byte; + s:string[100]; + + begin + printf('conflist'); + if not nofile then exit; + cls; + abort:=FALSE; next:=FALSE; + s:='^0N'+seperator+'Title'; + if (thisuser.linelen>=80) then s:=mln(s,38)+seperator+s; + print(s); + s:='^4=:===================================='; + if (thisuser.linelen>=80) then s:=s+':'+s; + print(s); + i:=1; + onlin:=0; + while (i<=27) and (not abort) and (not hangup) do begin + c:=chr(i+63); + if (aacs(confr.conference[c].acs)) and (confr.conference[c].name<>'') then begin + s:='^0'+c+' ^3'+confr.conference[c].name; + inc(onlin); + s:=mln(s,39); + if (onlin=1) then prompt(s) + else begin + if (thisuser.linelen<80) then nl; + print(s); + onlin:=0; + end; + end; + wkey; + inc(i); + end; + if (onlin=1) and (thisuser.linelen>=80) then nl; + end; + +begin + nl; + done:=false; + if v<>'' then c:=v[1] else c:=#0; + if (c>='@') and (c<='Z') and aacs(confr.conference[c].acs) then begin + currentconf:=c; + thisuser.lastconf:=c; + printf('conf'+c); + end else if c='?' then listconfs + else begin + print(^M^J'^4Current conference: ^5%CT - %CN'); + repeat + prompt(^M^J'^4Join which conference (^3?^4=^3List^4): '); + c:=upcase(char(getkey)); + print(c + ^M^J); + if (c>='@') and (c<='Z') then begin + if (aacs(confr.conference[c].acs)) and (confr.conference[c].name<>'') then begin + printf('conf'+c); + if nofile then print('Conference joined.'); + currentconf:=c; + thisuser.lastconf:=c; + done:=true; + nl + end else print('No such conference.'); + end else if c='?' then listconfs; + until (c=#13) or (done) or (hangup); + end; + newcomptables; +end; + +procedure finduserws(var x:integer); +var user:UserRecordType; + IndexR:useridxrec; + nn:astr; + gg,j:integer; + c:char; + done,asked:boolean; +begin + linput(nn,36); + if (nn='SYSOP') then nn:='1'; + x:=value(nn); + if (x>0) then begin + if (x > (maxusers - 1)) then + begin + print(^M^J'Unknown User.'); + x:=0; + end else loadurec(user,x); + end else + if (nn<>'') then begin + done:=FALSE; asked:=FALSE; + x := searchuser(nn, CoSysOp); + if (x > 0) then + exit; + reset(sf); + gg:=0; j:=filesize(sf); + while (gg 0) and + ((not IndexR.RealName) or (CoSysOp)) then + if ((IndexR.Name = nn) or (CoSysOp and (IndexR.Name = nn))) and + (Indexr.number <= (maxusers - 1)) then + x := Indexr.Number + else begin + if (not asked) then begin nl; asked:=TRUE; end; + prompt('^1Did you mean ^3' + caps(IndexR.Name) + '^1? '); + onek(c,'QYN'^M); + done:=TRUE; + case c of + 'Q':x:=-1; + 'Y':x:= IndexR.Number; + else + done:=FALSE; + end; + end; + end; + close(sf); + if (x=0) then print(^M^J'User not found.'); + if x=-1 then x:=0; + end; + Lasterror := IOResult; +end; + +procedure changearflags(const cms:astr); +var + c,cc:char; + i:byte; + +begin + for i:=1 to (length(cms)-1) do + begin + c := upcase(cms[i]); + cc := upcase(cms[i+1]); + case c of + '+':Include(thisuser.ar,cc); + '-':Exclude(thisuser.ar,cc); + '!':if (upcase(cms[i + 1]) in thisuser.ar) then + Exclude(thisuser.ar,cc) + else + Include(thisuser.ar,cc); + end; + end; + + newcomptables; + update_screen; +end; + +procedure changeacflags(const cms:astr); +var + c,cc:char; + i:byte; +begin + for i:=1 to length(cms)-1 do + begin + c:=upcase(cms[i]); + cc := upcase(cms[i+1]); + case c of + '+':Include(thisuser.flags,tacch(cc)); + '-':Exclude(thisuser.flags,tacch(cc)); + '!':acch(upcase(cms[i+1]),thisuser); + end; + end; + newcomptables; + update_screen; +end; + +procedure finduser(var usernum:integer); +var user:UserRecordType; + nn:astr; + ii:integer; +begin + usernum:=0; + linput(nn,36); + + if (nn='NEW') then + begin + usernum := -1; + exit; + end; + + if (nn='?') then exit; + + while (pos(' ',nn)<>0) do + delete(nn,pos(' ',nn),1); + + while (nn[1] = ' ') and (length(nn) > 0) do + delete(nn,1,1); + + if ((hangup) or (nn='')) then exit; + usernum:=value(nn); + if (usernum<>0) then begin + if (usernum<0) then + usernum:=0 + else begin + if (usernum > (maxusers - 1)) then + usernum := 0 + else + begin + loadurec(user,usernum); + if (deleted in user.sflags) then + usernum:=0; + end; + end; + end else begin + if (nn <> '') then begin + ii := searchuser(nn, TRUE); + if (ii <> 0) then + begin + loadurec(user,ii); + if not (deleted in user.sflags) then + usernum:=ii + else + usernum:=0; + end; + end; + end; +end; + +procedure InsertIndex(Uname:astr; usernum:integer; IsReal, IsDeleted:boolean); +var + IndexR:useridxrec; + Current:integer; + InsertAt:integer; + SFO,Done:boolean; + + procedure WriteIndex; + begin + with IndexR do + begin + fillchar(IndexR, sizeof(IndexR), 0); + Name := Uname; + Number := UserNum; + RealName:= IsReal; + Deleted := IsDeleted; + Left := -1; + Right := -1; + write(sf, IndexR); + end + end; + +begin + Done := FALSE; + Uname := Allcaps(Uname); + Current := 0; + + SFO := (filerec(sf).mode<>fmclosed); + + if (not SFO) then + reset(sf); + + if (filesize(sf) = 0) then + WriteIndex + else + repeat + seek(sf, Current); + InsertAt := Current; + read(sf, IndexR); + if (Uname < IndexR.Name) then + Current := IndexR.Left + else + if (Uname > IndexR.Name) then + Current := IndexR.Right + else + if (IndexR.Deleted <> IsDeleted) then + begin + Done := TRUE; + IndexR.Deleted := IsDeleted; + IndexR.RealName := IsReal; + IndexR.Number := Usernum; + seek(sf, Current); + write(sf,IndexR); + end + else + begin + if (Usernum <> IndexR.Number) then + sysoplog('Note: Duplicate user ' + UName + ' #' + cstr(IndexR.Number) + + ' and ' + UName + ' #' + cstr(Usernum)) + else + begin + IndexR.RealName := FALSE; + seek(sf, Current); { Make it be his handle if it's BOTH } + write(sf, IndexR); + end; + Done := TRUE; + end; + until (Current = -1) or (Done); + + if (Current = -1) then + begin + if (Uname < IndexR.Name) then + IndexR.Left := filesize(sf) + else + IndexR.Right := filesize(sf); + seek(sf, InsertAt); + write(sf, IndexR); + seek(sf, filesize(sf)); + WriteIndex; + end; + if (not SFO) then + close(sf); + Lasterror := IOResult; +end; + +end. diff --git a/SOURCE/UNUSED/VOTE.TPU b/SOURCE/UNUSED/VOTE.TPU new file mode 100644 index 0000000000000000000000000000000000000000..1f9e448371a22fe28800d785e6f86916084992f0 GIT binary patch literal 17616 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 KU|RQ6O#cnmxt3M{ literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/WD110107.TXT b/SOURCE/UNUSED/WD110107.TXT new file mode 100644 index 0000000..24a9b7c --- /dev/null +++ b/SOURCE/UNUSED/WD110107.TXT @@ -0,0 +1,50 @@ +Renegade Updates + +FC Cmd (Files.BBS Importer) + +1. Optimized by removing a duplicate procedure. +2. Reports duplicate files in the Sysop.log. +3. Reports missing files in the Sysop.log. +4. The "Hatched" flag is now set for all imported files. +5. The user can now enter file points per file uploaded when not + in the waiting for caller screen (Parameter switch -F). +6. All User/System upload statistics are checked for variable overrun. + +*1 Cmd (Edit Files) + +1. File name change will no longer allow renaming a file if the new file + names exists in the upload or download path. +2. The Filesize limit as been increased to allow for a maximum of 1.9 Gigs. + You now also have the choice of updating with the actual file size or + entering whatever you like up to the 1.9 Gig limit. +3. You may now interactively edit the file description. +4. Changing the user name or number now reports an error if the user + does not exist. +5. Changing the upload date of the file will not allow entry of a date + beyond the current date. +6. The number of downloads has been increased to allow up to 2147483647. +7. The modify extended description option has been revamped. If one exists, + you will first be asked if you would like to delete it, if one doesn't, you + will be asked if you would like to create one. If you decide to keep the + exisiting one or created one, you will be taken to the standard full screen + message editor, the old line by line edit mode has been removed. Existing + extended descriptions will be copied into the message editor for editing. + All message editing option are available for line edit or full screen edit + mode. +8. The file move cmd has been revamped provides clearer error message. +9. The User Editor option will now display messages if the user doesn't meet + the access requirement and also default to User #1 if the current owner + of the file has been deleted. +10. All User/System upload statistics are checked for variable overrun. + +Please add this note to the one about ext desc now being 99 lines + +NOTE: + + The way extended description were handled has been revamped. Prior to this + release, every extended description required 950 bytes of hard drive space rather + the description required it or not and was limited to 19 lines. This version now + allows up to 99 lines of 50 chars each and will only require space for the + actual characters utilized plus one byte for every line in the description. + For example: "This is a great file" would only require 20 + 1 byte or 21 bytes + of harddrive space verses the old minimum of 950 bytes. \ No newline at end of file diff --git a/SOURCE/UNUSED/WD110207.TXT b/SOURCE/UNUSED/WD110207.TXT new file mode 100644 index 0000000..0c585a0 --- /dev/null +++ b/SOURCE/UNUSED/WD110207.TXT @@ -0,0 +1,6 @@ +Renegade Updates + +FC Cmd (Files.BBS Importer) + +1. File_ID.DIZ will only be checked if allowed by System Config + setting. \ No newline at end of file diff --git a/SOURCE/UNUSED/WD110307.TXT b/SOURCE/UNUSED/WD110307.TXT new file mode 100644 index 0000000..ede38c0 --- /dev/null +++ b/SOURCE/UNUSED/WD110307.TXT @@ -0,0 +1,48 @@ +Renegade Updates + + +FC Cmd (Files.BBS Importer) + +1. File_ID.DIZ will only be checked if allowed by System Config + setting. + + +*1 Cmd (Edit Files) + +1. While editing the file owner name, the owner name will be checked + against the user name stored in the user editor. If the names do + not match, the file owner name will be converted to the Sysop name + (User #1). The editor will assume that the orignal uploader account + has been deleted. + +2. While updating the file size, if the file does not exist, you will be + asked if you would like to set the file to offline or request status. + +3. Use File_ID.DIZ must now be turn on in System Config to be able to + update or upload the Extended Description (if it exists). + +5. The internal archive viewer will now only attempt to display files with + the following extentions (ZIP,ARC,PAK,ZOO,LZH,ARK,ARJ). IF the extention + is valid and the file doesn't exist, you will be prompted to set the + file to offline or to request status. + +OB Cmd (User Statistics) + +1. Renegade now has built in User Top 10 Statistics. I recommend that + a new menu be created for these cmds. Menu options are listed below + along with the title of the action performed. + + Option Top 10 Result + + A High Time Users + B File Kbyte Uploaders + C File Kbyte Downloaders + D Private Message Senders + E Public Message Posters + F SysOp Feedback Senders + G All Time Callers + H File Uploaders + I File Downloaders + J File Points + K Upload/Download Ratios + L Post/Call Ratios diff --git a/SOURCE/UNUSED/WFCMENU.TPU b/SOURCE/UNUSED/WFCMENU.TPU new file mode 100644 index 0000000000000000000000000000000000000000..7fbba4c5685ad23bbd5470abd3aed6ad7e84cbc0 GIT binary patch literal 34528 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 literal 0 HcmV?d00001 diff --git a/SOURCE/UNUSED/WFCNEW1.ANS b/SOURCE/UNUSED/WFCNEW1.ANS new file mode 100644 index 0000000..81f2b31 --- /dev/null +++ b/SOURCE/UNUSED/WFCNEW1.ANS @@ -0,0 +1,25 @@ +[?7h The Renegade Bulletin Board System  +     +  Today's Stats   System Averages   System Totals   Critical Info  +  Newusers   Calls   Calls   Errors  +  Calls   Posts   Posts   GB Free  +  Posts   #/GB UL   #/GB UL   Feedback  +  #/GB UL   #/GB DL   #/GB DL    +  #/GB DL   Activity   Days    +     +   Modem  +  Node Summary   +  Node   +  Node Type   +  Nodes Total   +  Nodes Busy  0%Today's Activity100% +  [T]o Nodeview   +   +  +  [S]ystem Config [F]ile Base [C]allers [I]nit Modem [!]Validate  +  [U]ser Editor [B]Msg Base [P]ack Msgs [O]ffhook Modem [L]ogs  +  [#]Menu Editor [X]fer Prots [M]ail Read [A]nswer Modem [Z]History  +  [E]vent Editor [W]rite Mail [R]ead Mail [H]angup Modem [D]rop to DOS  +  [V]oting Editor [$]Conferences [ ] Log On [N]ode listing [Q]uit to Dos  +  + diff --git a/SOURCE/UNUSED/WFC_COM.ANS b/SOURCE/UNUSED/WFC_COM.ANS new file mode 100644 index 0000000..505db48 --- /dev/null +++ b/SOURCE/UNUSED/WFC_COM.ANS @@ -0,0 +1,25 @@ +[?7h + + + + + + + + + + + + + + + + +  +  [S]ystem Config [F]ile Base [C]allers [I]nit Modem [!]Validate  +  [U]ser Editor [B]Msg Base [P]ack Msgs [O]ffhook Modem [L]ogs  +  [#]Menu Editor [X]fer Prots [M]ail Read [A]nswer Modem [Z]History  +  [E]vent Editor [W]rite Mail [R]ead Mail [H]angup Modem [D]rop to DOS  +  [V]oting Editor [$]Conferences [ ] Log On [N]ode listing [Q]uit to DOS  +  + diff --git a/SOURCE/UNUSED/WFC_NODE.ANS b/SOURCE/UNUSED/WFC_NODE.ANS new file mode 100644 index 0000000..34e02ff --- /dev/null +++ b/SOURCE/UNUSED/WFC_NODE.ANS @@ -0,0 +1,25 @@ +[?7h + + + + + + + + + + + + + + + + +   +   Node WFC    +   Node Down    +   Newuser on Node    +  Node Available    +     +   + diff --git a/SOURCE/UNUSED/bootoldback.pas b/SOURCE/UNUSED/bootoldback.pas new file mode 100644 index 0000000..8d2984e --- /dev/null +++ b/SOURCE/UNUSED/bootoldback.pas @@ -0,0 +1,1034 @@ +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Boot; + +INTERFACE + +PROCEDURE initp1; +PROCEDURE init; + +IMPLEMENTATION + +USES + Crt, + Dos, + Common, + MyIo, + MiscUser, + TimeFunc; + +PROCEDURE initp1; +VAR + LineFile: FILE OF LineRec; + F: FILE OF Byte; + User: UserRecordType; + X: Byte; + Counter: Integer; + + PROCEDURE FindBadPaths; + CONST + AnyDone: Boolean = FALSE; + VAR + BootFile: Text; + DirName, + DirDesc, + S2: AStr; + Counter: Byte; + BEGIN + InField_Out_FGrd := 7; + Infield_Out_BkGd := 0; + Infield_Inp_FGrd := 7; + Infield_Inp_BkGd := 0; + IF Exist('1STBOOT') THEN + BEGIN + General.DataPath := StartDir+'\DATA\'; + General.MiscPath := StartDir+'\MISC\'; + General.LogsPath := StartDir+'\LOGS\'; + General.MsgPath := StartDir+'\MSGS\'; + General.NodePath := ''; + General.TempPath := StartDir+'\TEMP\'; + General.ProtPath := StartDir+'\PROT\'; + General.ArcsPath := StartDir+'\ARCS\'; + General.FileAttachPath := StartDir+'\FATTACH\'; + General.lMultPath := StartDir+'\STRING\'; + SaveGeneral(FALSE); + Assign(BootFile,StartDir+'1STBOOT'); + Erase(BootFile); + END; + FOR Counter := 1 TO 8 DO + BEGIN + CASE Counter OF + 1 : BEGIN + DirDesc := 'DATA'; + DirName := General.DataPath; + END; + 2 : BEGIN + DirDesc := 'MSGS'; + DirName := General.MsgPath; + END; + 3 : BEGIN + DirDesc := 'FATTACH'; + DirName := General.FileAttachPath; + END; + 4 : BEGIN + DirDesc := 'MISC'; + DirName := General.MiscPath; + END; + 5 : BEGIN + DirDesc := 'LOGS'; + DirName := General.LogsPath; + END; + 6 : BEGIN + DirDesc := 'ARC'; + DirName := General.ArcsPath; + END; + 7 : BEGIN + DirDesc := 'PROT'; + DirName := General.ProtPath; + END; + 8 : BEGIN + DirDesc := 'STRING'; + DirName := General.lMultPath; + END; + END; + IF (NOT ExistDir(DirName)) THEN + BEGIN + AnyDone := TRUE; + WriteLn(DirDesc+' path is currently '+DirName); + WriteLn('This path is bad or missing.'); + REPEAT + WriteLn; + S2 := DirName; + Write('New '+DirDesc+' path: '); + InField(S2,40); + S2 := AllCaps(SQOutSp(S2)); + IF (DirName = S2) OR (S2 = '') THEN + BEGIN + NL; + WriteLn('Illegal pathname error'); + Halt(ExitErrors); + END + ELSE + BEGIN + IF (S2 <> '') THEN + S2 := BSlash(S2,TRUE); + IF (ExistDir(S2)) THEN + CASE Counter OF + 1 : General.DataPath := S2; + 2 : General.MsgPath := S2; + 3 : General.FileAttachPath := S2; + 4 : General.MiscPath := S2; + 5 : General.LogsPath := S2; + 6 : General.ArcsPath := S2; + 7 : General.ProtPath := S2; + 8 : General.lMultPath := S2; + END + ELSE + BEGIN + WriteLn; + WriteLn('That path does not exist!'); + END; + END; + UNTIL (ExistDir(S2)); + END; + END; + IF (AnyDone) THEN + SaveGeneral(FALSE); + END; + +BEGIN + FindBadPaths; + + TextColor(Yellow); + Write('Opening and checking NODE'+IntToStr(ThisNode)+'.DAT ... '); + Assign(LineFile,General.DataPath+'NODE'+IntToStr(ThisNode)+'.DAT'); + Reset(LineFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(LineFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file NODE'+IntToStr(ThisNode)+'.DAT ... '); + ReWrite(LineFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing NODE'+IntToStr(ThisNode)+'.DAT records ... '); + END; + FillChar(Liner,SizeOf(Liner),0); + WITH Liner DO + BEGIN + InitBaud := 19200; + Comport := 1; + MFlags := [CTSRTS]; + Init := 'ATV1S0=0M0E0H0|'; + Answer := 'ATA|'; + HangUp := '^ATH0|'; + Offhook := 'ATH1|'; + DoorPath := ''; + TeleConfNormal := '^4[%UN] ^9'; + TeleConfAnon := '^4[^9??^4] ^9'; + TeleConfGlobal := '^4[%UN ^0GLOBAL^4] ^9'; + TeleConfPrivate := '^4[%UN ^0PRIVATE^4] ^9'; + Ok := 'OK'; + Ring := 'RING'; + Reliable := '/ARQ'; + CallerID := 'NMBR = '; + NoCarrier := 'NO CARRIER'; + Connect[1] := 'CONNECT'; + Connect[2] := 'CONNECT 600'; + Connect[3] := 'CONNECT 1200'; + Connect[4] := 'CONNECT 2400'; + Connect[5] := 'CONNECT 4800'; + Connect[6] := 'CONNECT 7200'; + Connect[7] := 'CONNECT 9600'; + Connect[8] := 'CONNECT 12000'; + Connect[9] := 'CONNECT 14400'; + Connect[10] := 'CONNECT 16800'; + Connect[11] := 'CONNECT 19200'; + Connect[12] := 'CONNECT 21600'; + Connect[13] := 'CONNECT 24000'; + Connect[14] := 'CONNECT 26400'; + Connect[15] := 'CONNECT 28800'; + Connect[16] := 'CONNECT 31200'; + Connect[17] := 'CONNECT 33600'; + Connect[18] := 'CONNECT 38400'; + Connect[19] := 'CONNECT 57600'; + Connect[20] := 'CONNECT 115200'; + Connect[21] := ''; + Connect[22] := ''; + UseCallerID := FALSE; + LogonACS := ''; + IRQ := '4'; + Address := '3F8'; + AnswerOnRing := 1; + MultiRing := FALSE; + NodeTelnetUrl := ''; + END; + Write(LineFile,Liner); + END; + Close(LineFile); + LastError := IOResult; + WriteLn('Done.'); + + Assign(F,General.DataPath+'NODE'+IntToStr(ThisNode)+'.DAT'); + Reset(F); + X := 0; + Seek(F,FileSize(F)); + WHILE (FileSize(F) < SizeOf(LineRec)) DO + Write(F,X); + Close(F); + Reset(LineFile); + Read(LineFile,Liner); + Close(LineFile); + + IF (Liner.Comport = 0) THEN + LocalIOOnly := TRUE; + + TempDir := Copy(General.TempPath,1,Length(General.TempPath) - 1)+IntToStr(ThisNode)+'\'; + IF (NOT ExistDir(TempDir)) THEN + MkDir(Copy(TempDir,1,Length(TempDir) - 1)); + IF (NOT ExistDir(TempDir+'QWK\')) THEN + MkDir(TempDir+'QWK'); + IF (NOT ExistDir(TempDir+'ARC\')) THEN + MkDir(TempDir+'ARC'); + IF (NOT ExistDir(TempDir+'UP\')) THEN + MkDir(TempDir+'UP'); + IF (NOT ExistDir(TempDir+'CD\')) THEN + MkDir(TempDir+'CD'); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + WriteLn('Error creating directories: '+TempDir); + Delay(1000); + END; + + Assign(SysOpLogFile,General.LogsPath+'SYSOP.LOG'); + Append(SysOpLogFile); + LastError := IOResult; + IF (LastError = 2) THEN + ReWrite(SysOpLogFile); + Close(SysOpLogFile); + + Assign(NodeFile,General.DataPath+'MULTNODE.DAT'); + IF (General.MultiNode) THEN + BEGIN + Reset(NodeFile); + LastError := IOResult; + IF (LastError = 2) THEN + ReWrite(NodeFile); + IF (FileSize(NodeFile) < ThisNode) THEN + BEGIN + Seek(NodeFile,FileSize(NodeFile)); + WITH NodeR DO + BEGIN + User := 0; + UserName := ''; + CityState := ''; + Sex := 'M'; + Age := 0; + LogonTime := 0; + GroupChat := FALSE; + ActivityDesc := ''; + Status := [NActive]; + Room := 0; + Channel := 0; + FillChar(Invited,SizeOf(Invited),0); + FillChar(Booted,SizeOf(Booted),0); + FillChar(Forget,SizeOf(Forget),0); + END; + WHILE (FileSize(NodeFile) < ThisNode) DO + Write(NodeFile,NodeR); + END; + Close(NodeFile); + Assign(SysOpLogFile,TempDir+'TEMPLOG.'+IntToStr(ThisNode)) + END + ELSE + Assign(SysOpLogFile,General.LogsPath+'SYSOP.LOG'); + + Append(SysOpLogFile); + LastError := IOResult; + IF (LastError = 2) THEN + ReWrite(SysOpLogFile); + Close(SysOpLogFile); + + Assign(SysOpLogFile1,General.LogsPath+'SLOGXXXX.LOG'); + SL1(''); + SL1(''); + SL1('^7--> ^5Renegade '+General.Version+' Node '+IntToStr(ThisNode)+' Loaded on '+dat+'^7 <--'); + + Assign(UserFile,General.DataPath+'USERS.DAT'); + + IF ((MaxUsers - 1) >= 1) THEN + LoadURec(ThisUser,1) + ELSE + Exclude(ThisUser.SFLags,SLogSeparate); + + Assign(UserIDXFile,General.DataPath+'USERS.IDX'); + Reset(UserIDXFile); + LastError := IOResult; + IF (LastError = 2) OR (MaxIDXRec = -1) THEN + BEGIN + IF (LastError = 0) THEN + Close(UserIDXFile); + Write('Regenerating corrupted User index: 0%'); + kill(General.DataPath+'USERS.IDX'); + General.NumUsers := 0; + ReWrite(UserIDXFile); + Reset(UserFile); + FOR Counter := 1 TO (MaxUsers - 1) DO + BEGIN + LoadURec(User,Counter); + IF (Counter MOD 25 = 0) THEN + Write(^H^H^H^H,(Counter / FileSize(UserFile) * 100):3:0,'%'); + IF (NOT (Deleted IN User.SFLags)) THEN + Inc(lTodayNumUsers); + InsertIndex(User.Name,Counter,FALSE,(Deleted IN User.SFLags)); + InsertIndex(User.realname,Counter,TRUE,(Deleted IN User.SFLags)); + END; + Close(UserFile); + Close(UserIDXFile); + WriteLn; + SaveGeneral(FALSE); + LastError := IOResult; + END + ELSE + Close(UserIDXFile); + + Assign(EventFile,General.DataPath+'EVENTS.DAT'); + Reset(EventFile); + LastError := IOResult; + IF (LastError = 2) THEN + BEGIN + WriteLn('Bad or missing EVENTS.DAT - creating...'); + ReWrite(EventFile); + NumEvents := 1; + New(MemEventArray[1]); + WITH MemEventArray[1]^ DO + BEGIN + EventDescription := '<< New Event >>'; + EventDayOfMonth := 0; + EventDays := []; + EventStartTime := 0; + EventFinishTime := 0; + EventQualMsg := ''; + EventNotQualMsg := ''; + EventPreTime := 0; + EventNode := 0; + EventLastDate := 0; + EventErrorLevel := 0; + EventShellPath := ''; + LoBaud := 300; + HiBaud := 115200; + EventACS := 's10'; + MaxTimeAllowed := 60; + SetARflag := '@'; + ClearARflag := '@'; + EFlags := [EventIsExternal,EventIsShell]; + END; + Write(EventFile,MemEventArray[1]^); + END + ELSE + BEGIN + NumEvents := 0; + IF NOT EOF(EventFile) THEN + REPEAT + Inc(NumEvents); + New(MemEventArray[NumEvents]); + Read(EventFile,MemEventArray[NumEvents]^); + IF (IOResult <> 0) THEN + BEGIN + SysOpLog('Warning: Bad events file format.'); + Break; + END; + UNTIL (EOF(EventFile)); + END; + Close(EventFile); + LastError := IOResult; + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking MEMAIL.DAT ... '); + Assign(EmailFile,General.DataPath+'MEMAIL.DAT'); + Reset(EmailFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(EmailFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file MEMAIL.DAT ... '); + ReWrite(EmailFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing MEMAIL.DAT records ... '); + END; + FillChar(MemMsgArea,SizeOf(MemMsgArea),0); + WITH MemMsgArea DO + BEGIN + Name := 'Private Messages'; + FileName := 'EMAIL'; + MsgPath := ''; + ACS := '^'; + PostACS := ''; + MCIACS := ''; + SysOpACS := General.MSoP; + MaxMsgs := 65535; + Anonymous := ATNo; + Password := ''; + MAFlags := []; + MAType := 0; + Origin := ''; + Text_Color := General.Text_Color; + Quote_Color := General.Quote_Color; + Tear_Color := General.Tear_Color; + Origin_Color := General.Origin_Color; + MessageReadMenu := 0; + QuoteStart := '|03Quoting message from |11@F |03to |11@T'; + QuoteEnd := '|03on |11@D|03.'; + PrePostFile := ''; + AKA := 0; + QWKIndex := 0; + END; + Write(EmailFile,MemMsgArea); + END; + Close(EmailFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking MBASES.DAT ... '); + Assign(MsgAreaFile,General.DataPath+'MBASES.DAT'); + Reset(MsgAreaFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(MsgAreaFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file MBASES.DAT ... '); + ReWrite(MsgAreaFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing MBASES.DAT records ... '); + END; + FillChar(MemMsgArea,SizeOf(MemMsgArea),0); + WITH MemMsgArea DO + BEGIN + Name := '<< New Message Area >>'; + FileName := 'NEWBOARD'; + MsgPath := ''; + ACS := ''; + PostACS := ''; + MCIACS := ''; + SysOpACS := ''; + MaxMsgs := 100; + Anonymous := ATNo; + Password := ''; + MAFlags := []; + MAType := 0; + Origin := ''; + Text_Color := General.Text_Color; + Quote_Color := General.Quote_Color; + Tear_Color := General.Tear_Color; + Origin_Color := General.Origin_Color; + MessageReadMenu := 0; + QuoteStart := '|03Quoting message from |11@F |03to |11@T'; + QuoteEnd := '|03on |11@D|03.'; + PrePostFile := ''; + AKA := 0; + QWKIndex := (FileSize(MsgAreaFile) + 1); + END; + Write(MsgAreaFile,MemMsgArea); + END; + NumMsgAreas := FileSize(MsgAreaFile); + Close(MsgAreaFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 08/11/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking CONFRENC.DAT ... '); + Assign(ConferenceFile,General.DataPath+'CONFRENC.DAT'); + Reset(ConferenceFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(ConferenceFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file CONFRENC.DAT ... '); + ReWrite(ConferenceFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing CONFRENC.DAT records ... '); + END; + FillChar(Conference,SizeOf(Conference),0); + WITH Conference DO + BEGIN + Key := '@'; + Name := 'General'; + ACS := ''; + END; + Write(ConferenceFile,Conference); + END; + NumConfKeys := FileSize(ConferenceFile); + ConfKeys := []; + Counter := 1; + WHILE (Counter <= NumConfKeys) DO + BEGIN + Seek(ConferenceFile,(Counter - 1)); + Read(ConferenceFile,Conference); + Include(ConfKeys,Conference.Key); + Inc(Counter); + END; + Close(ConferenceFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking FBASES.DAT ... '); + Assign(FileAreaFile,General.DataPath+'FBASES.DAT'); + Reset(FileAreaFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(FileAreaFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file FBASES.DAT ... '); + ReWrite(FileAreaFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing FBASES.DAT records ... '); + END; + FillChar(MemFileArea,SizeOf(MemFileArea),0); + WITH MemFileArea DO + BEGIN + AreaName := '<< New File Area >>'; + FileName := 'NEWDIR'; + DLPath := StartDir[1]+':\'; + ULPath := DLPath; + MaxFiles := 2000; + Password := ''; + ArcType := 0; + CmtType := 0; + ACS := ''; + ULACS := ''; + DLACS := ''; + FAFlags := []; + END; + Write(FileAreaFile,MemFileArea); + END; + NumFileAreas := FileSize(FileAreaFile); + Close(FileAreaFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking PROTOCOL.DAT ... '); + Assign(ProtocolFile,General.DataPath+'PROTOCOL.DAT'); + Reset(ProtocolFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(ProtocolFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file PROTOCOL.DAT ... '); + ReWrite(ProtocolFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing PROTOCOL.DAT records ... '); + END; + FillChar(Protocol,SizeOf(Protocol),0); + WITH Protocol DO + BEGIN + PRFlags := [ProtXferOkCode]; + CKeys := '!'; + Description := '<< New Protocol >>'; + ACS := ''; + TempLog := ''; + DLoadLog := ''; + ULoadLog := ''; + DLCmd := ''; + ULCmd := ''; + FOR Counter := 1 TO 6 DO + BEGIN + DLCode[Counter] := ''; + ULCode[Counter] := ''; + END; + EnvCmd := ''; + DLFList := ''; + MaxChrs := 127; + TempLogPF := 0; + TempLogPS := 0; + END; + Write(ProtocolFile,Protocol); + END; + NumProtocols := FileSize(ProtocolFile); + Close(ProtocolFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking SCHEME.DAT ... '); + Assign(SchemeFile,General.DataPath+'SCHEME.DAT'); + Reset(SchemeFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(SchemeFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file SCHEME.DAT ... '); + ReWrite(SchemeFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing SCHEME.DAT records ... '); + END; + FillChar(Scheme,SizeOf(Scheme),0); + WITH Scheme DO + BEGIN + Description := 'Default Color Scheme'; + FillChar(Color,SizeOf(Color),7); + Color[1] := 15; + Color[2] := 7; + Color[3] := 13; + Color[4] := 11; + Color[5] := 9; + Color[6] := 14; + Color[7] := 31; + Color[8] := 12; + Color[9] := 142; + Color[10] := 10; + END; + Write(SchemeFile,Scheme); + END; + NumSchemes := FileSize(SchemeFile); + Close(SchemeFile); + LastError := IOResult; + WriteLn('Done.'); + + (* Done - 01/04/08 - Lee Palmer *) + TextColor(Yellow); + Write('Opening and checking VOTING.DAT ... '); + Assign(VotingFile,General.DataPath+'VOTING.DAT'); + Reset(VotingFile); + LastError := IOResult; + IF (LastError = 2) THEN + BEGIN + TextColor(Red); + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file VOTING.DAT ... '); + ReWrite(VotingFile); + END; + NumVotes := FileSize(VotingFile); + Close(VotingFile); + LastError := IOResult; + WriteLn('Done.'); + + TextColor(Yellow); + Write('Opening and checking VALIDATE.DAT ... '); + Assign(ValidationFile,General.DataPath+'VALIDATE.DAT'); + Reset(ValidationFile); + LastError := IOResult; + IF (LastError = 2) OR (FileSize(ValidationFile) = 0) THEN + BEGIN + TextColor(Red); + IF (LastError = 2) THEN + BEGIN + WriteLn('File missing!'); + TextColor(Yellow); + Write('Creating missing file VALIDATE.DAT ... '); + ReWrite(ValidationFile); + END + ELSE + BEGIN + WriteLn('Records missing!'); + TextColor(Yellow); + Write('Inserting missing VALIDATE.DAT records ... '); + END; + LoadURec(User,0); + FillChar(Validation,SizeOf(Validation),0); + WITH Validation DO + BEGIN + Key := '!'; + ExpireTo := ' '; + Description := 'New user validation'; + UserMsg := 'You have been validated, enjoy the system!'; + NewSL := User.SL; + NewDSL := User.DSL; + NewMenu := 0; + Expiration := 0; + NewFP := 0; + NewCredit := 0; + SoftAR := TRUE; + SoftAC := TRUE; + NewAR := []; + NewAC := []; + END; + Write(ValidationFile,Validation); + END; + NumValKeys := FileSize(ValidationFile); + ValKeys := []; + Counter := 1; + WHILE (Counter <= NumValKeys) DO + BEGIN + Seek(ValidationFile,(Counter - 1)); + Read(ValidationFile,Validation); + Include(ValKeys,Validation.Key); + Inc(Counter); + END; + Close(ValidationFile); + LastError := IOResult; + WriteLn('Done.'); + + NumArcs := 1; + WHILE (NumArcs <= MaxArcs) AND (General.FileArcInfo[NumArcs].Ext <> '') DO + Inc(NumArcs); + Dec(NumArcs); + + FOR Counter := 1 TO MaxMenus DO + MenuRecNumArray[Counter] := 0; + FOR Counter := 1 TO MaxMenus DO + CmdNumArray[Counter] := 0; + NumMenus := 0; + NumCmds := 0; + Assign(MenuFile,General.DataPath+'MENUS.DAT'); + Reset(MenuFile); + LastError := IOResult; + IF (LastError <> 0) THEN + BEGIN + Print('System Error: MENUS.DAT file is missing!'); + Halt; + END + ELSE + BEGIN + Counter := 0; + WHILE NOT EOF(MenuFile) DO + BEGIN + Read(MenuFile,MenuR); + IF (MenuR.Menu = TRUE) THEN + BEGIN + Inc(NumMenus); + MenuRecNumArray[NumMenus] := Counter; + IF (NumMenus > 1) THEN + CmdNumArray[NumMenus - 1] := NumCmds; + NumCmds := 0; + END + ELSE + Inc(NumCmds); + Inc(Counter); + END; + CmdNumArray[NumMenus] := NumCmds; + Close(MenuFile); + END; + + CFO := FALSE; + +END; + +FUNCTION SchareLoaded: Boolean; +VAR + T_Al: Byte; +BEGIN + ASM + Mov Ah,10h + Mov Al,0h + Int 2fh + Mov T_Al,Al + END; + SchareLoaded := (T_Al = $FF); +END; + +PROCEDURE FindTaskerType; +VAR + D5, + DOS_Major, + DOS_Minor, + Os2Vers: Word; + DVOk, + OS2Ok, + WinOk, + WinNTOk: Boolean; + + FUNCTION TrueDosVer(VAR WinNTOk: Boolean): Word; + VAR + Regs: Registers; + BEGIN + WITH Regs DO + BEGIN + Ax := $3306; + MsDos(Regs); + IF (Bx = $3205) THEN + WinNTOk := TRUE + ELSE + WinNTOk := FALSE; + TrueDosVer := Bl; + END; + END; + + FUNCTION DosVer(VAR Minor,OS2Ver: Word): Word; + VAR + Regs: Registers; + BEGIN + OS2Ver := 0; + WITH Regs DO + BEGIN + Ax := $3000; + MsDos(Regs); + DosVer := Al; + Minor := Ah; + IF (Al = $0A) THEN + OS2Ver := 1 + ELSE IF (Al = $14) THEN + OS2Ver := 2; + END; + END; + + FUNCTION Win3_Check_On: Boolean; + VAR + Regs: Registers; + BEGIN + WITH Regs DO + BEGIN + AX := $1600; + Intr($2F,Regs); { $00 no Win 2.x or 3.x } + IF (AL IN [$00,$01,$80,$FF]) THEN { $01 Win/386 2.x running } + Win3_Check_On := FALSE { $80 obsolete XMS installed } + ELSE { $FF Win/386 2.x running } + Win3_Check_On := TRUE; + END; + END; + + FUNCTION DV_Check_On: Boolean; + VAR + Regs: Registers; + BEGIN + DV_Check_On := FALSE; + WITH Regs DO + BEGIN + Ax := $2B01; + Cx := $4445; + Dx := $5351; + Intr($21,Regs); + END; + IF (Regs.AL = $FF) THEN + DV_Check_On := FALSE + ELSE + DV_Check_On := TRUE; + END; + +BEGIN + D5 := 0; + Tasker := None; + DVOk := FALSE; + OS2Ok := FALSE; + WinOk := FALSE; + WinNTOk := FALSE; { This could also be just plain old Dos 5.0+ } + DOS_Major := DosVer(DOS_Minor,Os2Vers); + IF (Os2Vers IN [1,2]) THEN + OS2Ok := TRUE + ELSE + DVOk := DV_Check_On; + IF (NOT DVOk) AND (NOT OS2Ok) THEN + BEGIN + WinOk := Win3_Check_On; + IF (NOT WinOk) THEN + CASE Dos_Major of + 5..9 : D5 := TrueDosVer(WinNTOk); + END; + END; + IF (DVOk) THEN + Tasker := DV + ELSE IF (WinOk) THEN + Tasker := Win + ELSE IF (OS2Ok) THEN + Tasker := OS2 + ELSE IF (WinNTOk) THEN + Tasker := Win32 + ELSE IF (D5 >= 5) THEN + Tasker := Dos5N; +END; + +PROCEDURE init; +VAR + Node: Byte; +BEGIN + IF (DateStr = '01-01-1980') THEN + BEGIN + ClrScr; + TextColor(Yellow); + WriteLn('Please set the operating system date & time.'); + Halt(ExitErrors); + END; + + FindTaskerType; + + IF (General.MultiNode) AND (NOT SchareLoaded) THEN + BEGIN + ClrScr; + TextColor(Yellow); + WriteLn('WARNING: SHARE.EXE should be loaded for MultiNode operation.'); + Delay(1000); + END; + + HangUp := FALSE; + InCom := FALSE; + OutCom := FALSE; + Echo := TRUE; + DoneDay := FALSE; + CheckBreak := FALSE; + SLogging := TRUE; + Trapping := FALSE; + ReadingMail := FALSE; + SysOpOn := FALSE; + BeepEnd := FALSE; + WantOut := TRUE; + InChat := FALSE; + LIL := 0; + + ThisUser.PageLen := 24; (* Is this needed ??? *) + + Buf := ''; + ChatCall := FALSE; + LastAuthor := 0; + LastLineStr := ''; + ChatReason := ''; + + DirectVideo := NOT General.UseBIOS; + + IF (General.NetworkMode) AND (ThisNode = 0) THEN + BEGIN + LocalIOOnly := TRUE; + Node := 1; + WHILE (Node <= MaxNodes) AND (ThisNode = 0) DO + BEGIN + LoadNode(Node); + IF (NOT (NActive IN NodeR.Status)) THEN + ThisNode := Node; + Inc(Node); + END; + IF (ThisNode = 0) THEN + ThisNode := Node; + END; + + IF (ThisNode > 255) THEN + ThisNode := 1; + + IF (General.MultiNode) AND (ThisNode = 0) THEN + BEGIN + ClrScr; + WriteLn('WARNING: No node number specified. Defaulting to node 1.'); + ThisNode := 1; + Delay(1000); + END + ELSE IF (ThisNode = 0) THEN + ThisNode := 1; + + initp1; + + LoadNode(ThisNode); + WITH NodeR DO + BEGIN + User := 0; + UserName := ''; + CityState := ''; + Sex := 'M'; + Age := 0; + LogonTime := 0; + GroupChat := FALSE; + ActivityDesc := ''; + Status := [NActive]; + Room := 0; + Channel := 0; + FillChar(Invited,SizeOf(Invited),0); + FillChar(Booted,SizeOf(Booted),0); + FillChar(Forget,SizeOf(Forget),0); + END; + SaveNode(ThisNode); + +END; + +END. diff --git a/SOURCE/UNUSED/m.cmd b/SOURCE/UNUSED/m.cmd new file mode 100644 index 0000000..89287c4 --- /dev/null +++ b/SOURCE/UNUSED/m.cmd @@ -0,0 +1 @@ +move %1.pas .. \ No newline at end of file diff --git a/SOURCE/UPGRADE/BBSLEDT.ASC b/SOURCE/UPGRADE/BBSLEDT.ASC new file mode 100644 index 0000000..c4cae12 --- /dev/null +++ b/SOURCE/UPGRADE/BBSLEDT.ASC @@ -0,0 +1,4 @@ +%CL + |03Ŀ + |17|15 Num |16|03|17|15 BBS Name |11Last Edited |16|03 + diff --git a/SOURCE/UPGRADE/BBSLEH.ASC b/SOURCE/UPGRADE/BBSLEH.ASC new file mode 100644 index 0000000..c4cae12 --- /dev/null +++ b/SOURCE/UPGRADE/BBSLEH.ASC @@ -0,0 +1,4 @@ +%CL + |03Ŀ + |17|15 Num |16|03|17|15 BBS Name |11Last Edited |16|03 + diff --git a/SOURCE/UPGRADE/BBSLEM.ASC b/SOURCE/UPGRADE/BBSLEM.ASC new file mode 100644 index 0000000..c595c72 --- /dev/null +++ b/SOURCE/UPGRADE/BBSLEM.ASC @@ -0,0 +1,2 @@ + |12~RN |15~BN |16%LF + diff --git a/SOURCE/UPGRADE/BBSLIST.SCR b/SOURCE/UPGRADE/BBSLIST.SCR new file mode 100644 index 0000000..d724caa --- /dev/null +++ b/SOURCE/UPGRADE/BBSLIST.SCR @@ -0,0 +1,66 @@ +# +# This is an example of a bbslist template. +# +# Anything after a '#' is considered a comment and is ignored. +# Anything That doesn't begin with a [ is ignored. +# +# The ~ Codes in parenthases are MCIs to access the values +# (~BN) [BBSName]: BBS Name +# (~SN) [SysOpName]: Sysop Name +# (~MN) [MaxNodes]: Max Nodes +# (~BP) [Port]: Telnet Port +# (~TN) [TelnetUrl]: Telnet Url +# (~WS) [WebSiteUrl]: Website +# (~PN) [PhoneNumber]: BBS Phone Number +# (~LO) [Location]: Location of BBS +# (~SW) [Software]: BBS Software Used +# (~SV) [SoftwareVersion]: BBS Software Version +# (~OS) [OS]: Operating System of BBS +# (~SP) [Speed]: Speed of the BBS +# (~HR) [Hours]: Hours of Operation +# (~ST) [Birth]: When the bbs started +# (~DS) [Description]: Description +# (~D2) [Description2]: Description 2 +# (~SA) [SDA]: SysOp Definable String 8 +# (~SB) [SDB]: SysOp Definable String 30 +# (~SC) [SDC]: SysOp Definable String 30 +# (~SD) [SDD]: SysOp Definable String 40 +# (~SE) [SDE]: SysOp Definable String 60 +# (~SF) [SDF]: SysOp Definable String 60 +# (~SG) [SDG]: SysOp Definable Number +# (~SH) [SDH]: SysOp Definable Yes/No (Default Yes) +# (~SI) [SDI]: SysOp Definable Yes/No (Default No) +# !! Extra Display Codes !! +# (~AC) : Area Code +# (~DA) : Date Added +# (~DE) : Date Edited +# (~RN) : Record Number +# (~UN) : User who added record +# +# if you want to ask the questions in a certain order change the order. +# if you don't want to ask a question then leave it out. +# +# MCI and Pipe Color Codes are allowed in the question. +# +# Start BBS List Questions +# +[BBSName]:%DFAEBBS%%LF |03Enter the Name of BBS |15:|11 +[SysOpName]:%LF |03What is the Sysop of this BBS name? |15:|11 +[TelnetUrl]:%LF |03What is the Telnet Address of the BBS?%LF |15:|11 +[Port]:%LF |03What port can this BBS be reached at? |15:|08 +[WebSiteUrl]:%LF |03What is the web address of the BBS?%LF |15:|11 +[PhoneNumber]:%DFAEBBS%%LF |03BBS Phone Number |08(|07if any|08) |15:|11 +[Location]:%LF |03What is the location of this BBS? |15:|11 +[Software]:%LF |03What Software does this BBS use? |15:|11 +[SoftwareVersion]:%LF |03Software Version? |15:|11 +[OS]:%LF |03Operating System? |15:|11 +[MaxNodes]:%LF |03How Many Nodes? |15:|08 +[Speed]:%DFAEBBS%%LF |03What is the Speed of the BBS? |08(|072400, 56700, Telnet|08) |15:|11 +[Hours]:%LF |03What hours does this bbs run? |08(|0724/7 |08.. |076am-3pm|08) |15:|11 +[Birth]:%LF |03When did this bbs start? +[Description]:%LF |03Enter a small description of the BBS 60 Chars Max. 2 Lines%LF |15 : |11 +[Description2]: |15: |11 +#[SDG]:%LF |03Number Test? |15:|08 +#[SDH]:%LF |03BBS Is 24/7? |15:|11 +#[SDI]:%LF |03Private Nodes? |15:|11 + diff --git a/SOURCE/UPGRADE/FIXBBSL.PAS b/SOURCE/UPGRADE/FIXBBSL.PAS new file mode 100644 index 0000000..402be6d --- /dev/null +++ b/SOURCE/UPGRADE/FIXBBSL.PAS @@ -0,0 +1,217 @@ +Program FixBBSL; + +Uses + Dos, + Crt, + Common, + BBSList; + +Type + + UnixTime = Longint; + + OldBBSListRecordType = { *.BBS file records } + {$IFDEF WIN32} PACKED {$ENDIF} RECORD + RecordNum : LongInt; { Number OF the Record For Edit } + UserID : LongInt; { User ID OF person adding this } + BBSName : STRING[30]; { Name OF BBS } + SysOpName : STRING[30]; { SysOp OF BBS } + TelnetUrl : STRING[60]; { Telnet Urls } + WebSiteUrl : STRING[60]; { Web Site Url } + PhoneNumber : STRING[20]; { Phone number OF BBS } + Software : STRING[8]; { Software used by BBS } + Speed : STRING[8]; { Highest connect speed OF BBS } + Description : STRING[60]; { Description OF BBS } + Description2 : STRING[60]; { Second line OF descrition } + DateAdded : UnixTime; { Date entry was added } + DateEdited : UnixTime; { Date entry was last edited } + XA : STRING[8]; { sysop definable A } + XB : STRING[30]; { sysop definable B } + XC : STRING[30]; { sysop definable C } + XD : STRING[40]; { sysop definable D } + XE : STRING[60]; { sysop definable E } + XF : STRING[60]; { sysop definable F } + END; + + NewBBSListRecordType = { New *.BBS file records } + {$IFDEF WIN32} PACKED {$ENDIF} RECORD + RecordNum, { Number OF the Record For Edit } + UserID, { User ID OF person adding this } + MaxNodes : LongInt; { Maximum Number Of Nodes } + Port : Word; { Telnet Port } + BBSName : STRING[30]; { Name OF BBS } + SysOpName : STRING[30]; { SysOp OF BBS } + TelnetUrl : STRING[60]; { Telnet Urls } + WebSiteUrl : STRING[60]; { Web Site Url } + PhoneNumber : STRING[20]; { Phone number OF BBS } + Location : STRING[30]; { Location of BBS } + Software, { Software used by BBS } + SoftwareVersion : String[12]; { Software Version of BBS } + OS : STRING[20]; { Operating System of BBS } + Speed : STRING[8]; { Highest connect speed OF BBS } + Hours : STRING[20]; { Hours of Operation } + Birth : STRING[10]; { When The BBS Began } + Description : STRING[60]; { Description OF BBS } + Description2 : STRING[60]; { Second line OF descrition } + DateAdded : UnixTime; { Date entry was added } + DateEdited : UnixTime; { Date entry was last edited } + SDA : STRING[8]; { sysop definable A } + SDB : STRING[30]; { sysop definable B } + SDC : STRING[30]; { sysop definable C } + SDD : STRING[40]; { sysop definable D } + SDE : STRING[60]; { sysop definable E } + SDF : STRING[60]; { sysop definable F } + SDG : Word; { sysop definable G } + SDH, { sysop definable H } + SDI : Boolean; { sysop definable I } + END; + + +Var + + OldBBSFile : File Of OldBBSListRecordType; + OldBBSDat : OldBBSListRecordType; + + BBSFile : File Of NewBBSListRecordType; + BBSDat : NewBBSListRecordType; + + i : Integer; + + TempFile, + Dir, + BBSListDat : String; + + +Function GetDataFile : String; +Var + Old : String; +Begin + GetDir(0,BBSListDat); + BBSListDat := BBSListDat+'\DATA\BBSLIST.DAT'; + GetDir(0,Old); + Old := Old+'\DATA\BBSLIST.OLD'; + If Exist(Old) Then + Begin + WriteLn; + TextColor(12); + Write(' ', Old); + TextColor(4); + WriteLn(' exists. '); + TextColor(7); + WriteLn(' It seems you have already run this program. '); + TextColor(7); + WriteLn(' There is no need to run it again.'); + WriteLn; + Halt; + End + Else If Exist(BBSListDat) Then + Begin + GetDataFile := BBSListDat; + Exit; + End + Else + Begin + WriteLn; + TextColor(12); + Write(' ',BBSListDat); + TextColor(4); + WriteLn(' doesn''t exist'); + TextColor(7); + WriteLn(' Run this from inside your RENEGADE Home Dir.'); + WriteLn; + Halt; + End; +End; + +Begin { Main Program } + +BBSListDat := GetDataFile; { Get BBSLIST.DAT or Quit } + +TempFile := 'DATA\BBSTEMP.DAT'; + + Assign(OldBBSFile, BBSListDat); + Assign(BBSFile, TempFile); + Reset(OldBBSFile); + Rewrite(BBSFile); + Seek(OldBBSFile, 0); + Seek(BBSFile, 0); + WriteLn; + TextColor(3); + Write(' Converting Old BBS Records '); + +For i := 1 to FileSize(OldBBSFile) Do + Begin + Delay(200); + TextColor(11); + Write('.'); + Read(OldBBSFile, OldBBSDat); + + BBSDat.RecordNum := OldBBSDat.RecordNum; + BBSDat.UserID := OldBBSDat.UserID; + BBSDat.BBSName := OldBBSDat.BBSName; + BBSDat.SysOpName := OldBBSDat.SysOpName; + BBSDat.TelnetUrl := OldBBSDat.TelnetUrl; + BBSDat.WebSiteUrl := OldBBSDat.WebSiteUrl; + BBSDat.PhoneNumber := OldBBSDat.PhoneNumber; + BBSDat.Software := OldBBSDat.Software; + BBSDat.Speed := OldBBSDat.Speed; + BBSDat.Description := OldBBSDat.Description; + BBSDat.Description2 := OldBBSDat.Description2; + BBSDat.DateAdded := OldBBSDat.DateAdded; + BBSDat.DateEdited := OldBBSDat.DateEdited; + BBSDat.SDA := OldBBSDat.XA; + BBSDat.SDB := OldBBSDat.XB; + BBSDat.SDC := OldBBSDat.XC; + BBSDat.SDD := OldBBSDat.XD; + BBSDat.SDE := OldBBSDat.XE; + BBSDat.SDF := OldBBSDat.XF; + + Write(BBSFile, BBSDat); + + Seek(OldBBSFile, i); + Seek(BBSFile, i); + + End; +TextColor(3); +WriteLn(' Done!'); + +GetDir(0,Dir); + +WriteLn; +TextColor(3); +Write(' Copying '); +TextColor(11); +Write(Dir,'\DATA\BBSLIST.DAT '); +TextColor(3); +Write('to '); +TextColor(11); +Write(Dir,'\DATA\BBSLIST.OLD '); +TextColor(3); +Write('...'); + +Rename(OldBBSFile,Dir+'\DATA\BBSLIST.OLD'); + +TextColor(3); +WriteLn(' Done!'); + +TextColor(3); +Write(' Moving '); +TextColor(11); +Write(Dir,'\DATA\BBSTEMP.DAT '); +TextColor(3); +Write('to '); +TextColor(11); +Write(Dir,'\DATA\BBSLIST.DAT '); +TextColor(3); +Write('...'); + +Rename(BBSFile,Dir+'\DATA\BBSLIST.DAT'); + +TextColor(3); +WriteLn(' Done!'); +WriteLn; + +Close(OldBBSFile); +Close(BBSFile); + +End. diff --git a/SOURCE/VOTE.PAS b/SOURCE/VOTE.PAS new file mode 100644 index 0000000..c2dac62 --- /dev/null +++ b/SOURCE/VOTE.PAS @@ -0,0 +1,548 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT Vote; + +INTERFACE + +USES + Common; + +FUNCTION GetTopics: Byte; +FUNCTION UnVotedTopics: Byte; +PROCEDURE ListTopics(UsePause: Boolean); +PROCEDURE VoteAll; +PROCEDURE VoteOne(TopicNum: Byte); +PROCEDURE Results(ListVoters: Boolean); +PROCEDURE TrackUser; +PROCEDURE AddTopic; + +IMPLEMENTATION + +USES + Common5, + MiscUser; + +VAR + AvailableTopics: ARRAY [1..25] OF Byte; + +FUNCTION GetTopics: Byte; +VAR + TopicNum, + NumTopics: Byte; +BEGIN + FillChar(AvailableTopics,SizeOf(AvailableTopics),0); + Abort := FALSE; + Next := FALSE; + NumTopics := 0; + Reset(VotingFile); + TopicNum := 1; + WHILE (TopicNum <= NumVotes) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(VotingFile,(TopicNum - 1)); + Read(VotingFile,Topic); + IF AACS(Topic.ACS) THEN + BEGIN + Inc(NumTopics); + AvailableTopics[NumTopics] := TopicNum; + END; + Inc(TopicNum); + END; + Close(VotingFile); + LastError := IOResult; + GetTopics := NumTopics; +END; + +FUNCTION UnVotedTopics: Byte; +VAR + TopicNum, + NumTopics: Byte; +BEGIN + Abort := FALSE; + Next := FALSE; + NumTopics := 0; + Reset(VotingFile); + TopicNum := 1; + WHILE (TopicNum <= NumVotes) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(VotingFile,(TopicNum - 1)); + Read(VotingFile,Topic); + IF AACS(Topic.ACS) AND (ThisUser.Vote[TopicNum] = 0) THEN + Inc(NumTopics); + Inc(TopicNum); + END; + Close(VotingFile); + LastError := IOResult; + UnVotedTopics := NumTopics; +END; + +PROCEDURE ListTopics(UsePause: Boolean); +VAR + TopicNum, + NumTopics: Byte; +BEGIN + NumTopics := GetTopics; + IF (NumTopics = 0) THEN + BEGIN + NL; + Print('There are no topics available.'); + PauseScr(FALSE); + Exit; + END; + Abort := FALSE; + Next := FALSE; + (* + CLS; + PrintACR('|03Ŀ'); + PrintACR('|11|17 Num |03|16|11|17Votes|03|16|11|17 Choice '+ + ' |03|16'); + PrintACR(''); + *) + lRGLngStr(61,FALSE); + Reset(VotingFile); + TopicNum := 1; + WHILE (TopicNum <= NumTopics) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Seek(VotingFile,(AvailableTopics[TopicNum] - 1)); + Read(VotingFile,Topic); + PrintACR('|07'+PadRightInt(TopicNum,5)+ + '|10'+PadRightInt(Topic.NumVotedQuestion,7)+ + '|14 '+Topic.Question1); + IF (Topic.Question2 <> '') THEN + PrintACR(PadRightStr('',12)+'|14 '+Topic.Question2); + WKey; + Inc(TopicNum); + END; + Close(VotingFile); + LastError := IOResult; + IF (UsePause) THEN + BEGIN + NL; + PauseScr(FALSE); + END; +END; + +PROCEDURE TopicResults(TopicNum: Byte; User: UserRecordType; ListVoters: Boolean); +VAR + ChoiceNum: Byte; + NumVoted, + UNum, + TempMaxUsers: Integer; +BEGIN + Reset(VotingFile); + Seek(VotingFile,(TopicNum - 1)); + Read(VotingFile,Topic); + Close(VotingFile); + Abort := FALSE; + Next := FALSE; + CLS; + PrintACR('^5Topic: ^3'+Topic.Question1); + IF (Topic.Question2 <> '') THEN + PrintACR('^5 : ^3'+Topic.Question2); + NL; + PrintACR('^5Created By: ^3'+Topic.CreatedBy); + NL; + (* + PrintACR('|03Ŀ'); + PrintACR('|11|17 N |03|16|11|17 % |03|16'+ + '|11|17 Choice |03|16'); + PrintACR(''); + *) + lRGLngStr(62,FALSE); + ChoiceNum := 1; + WHILE (ChoiceNum <= Topic.ChoiceNumber) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + PrintACR('^3'+PadRightInt(Topic.Answers[ChoiceNum].NumVotedAnswer,4)+ + CTP(Topic.Answers[ChoiceNum].NumVotedAnswer,Topic.NumVotedQuestion)+ + AOnOff(User.Vote[TopicNum] = ChoiceNum,' |12',' |10')+ + PadRightInt(ChoiceNum,2)+ + '.'+Topic.Answers[ChoiceNum].Answer1); + IF (Topic.Answers[ChoiceNum].Answer2 <> '') THEN + PrintACR(PadLeftStr('',14)+Topic.Answers[ChoiceNum].Answer2); + + IF (ListVoters) AND (Topic.Answers[ChoiceNum].NumVotedAnswer > 0) THEN + BEGIN + NumVoted := Topic.Answers[ChoiceNum].NumVotedAnswer; + Reset(UserFile); + TempMaxUsers := (MaxUsers - 1); + UNum := 1; + WHILE (UNum <= TempMaxUsers) AND (NumVoted > 0) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + LoadURec(User,UNum); + IF (User.Vote[TopicNum] = ChoiceNum) THEN + BEGIN + PrintACR(PadLeftStr('^1',14)+Caps(User.Name)+' #'+IntToStr(UNum)); + Dec(NumVoted); + END; + Inc(UNum); + END; + Close(UserFile); + END; + Inc(ChoiceNum); + END; + LastError := IOResult; + NL; + PauseScr(FALSE); +END; + +PROCEDURE GoVote(TopicNum: Byte); +VAR + InputStr: Str2; + ChoiceNum: Byte; +BEGIN + Reset(VotingFile); + Seek(VotingFile,(TopicNum - 1)); + Read(VotingFile,Topic); + Abort := FALSE; + Next := FALSE; + CLS; + Print('^5Renegade Voting:'); + NL; + PrintACR('^5Topic: ^3'+Topic.Question1); + IF (Topic.Question2 <> '') THEN + PrintACR('^5 : ^3'+Topic.Question2); + NL; + PrintACR('^5Created by: ^3'+Topic.CreatedBy); + NL; + ChoiceNum := 1; + WHILE (ChoiceNum <= Topic.ChoiceNumber) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + PrintACR('^3'+PadRightInt(ChoiceNum,3)+'.^9 '+Topic.Answers[ChoiceNum].Answer1); + IF (Topic.Answers[ChoiceNum].Answer2 <> '') THEN + PrintACR(' ^9'+Topic.Answers[ChoiceNum].Answer2); + Inc(ChoiceNum); + END; + Dec(ChoiceNum); + IF (AACS(Topic.AddAnswersACS)) AND (ChoiceNum < 25) THEN + BEGIN + Inc(ChoiceNum); + Print('^3'+PadRightInt(ChoiceNum,3)+'.^9 '); + END; + IF (ThisUser.Vote[TopicNum] >= 1) AND (ThisUser.Vote[TopicNum] <= Topic.ChoiceNumber) THEN + BEGIN + NL; + IF PYNQ('Change your vote? ',0,FALSE) THEN + BEGIN + Dec(Topic.Answers[ThisUser.Vote[TopicNum]].NumVotedAnswer); + Dec(Topic.NumVotedQuestion); + ThisUser.Vote[TopicNum] := 0; + Seek(VotingFile,(TopicNum - 1)); + Write(VotingFile,Topic); + END + ELSE + BEGIN + Close(VotingFile); + Exit; + END; + END; + NL; + Prt('Your choice: '); + MPL(Length(IntToStr(ChoiceNum))); + ScanInput(InputStr,'Q'^M); + ChoiceNum := StrToInt(InputStr); + IF (ChoiceNum = (Topic.ChoiceNumber + 1)) AND AACS(Topic.AddAnswersACS) AND (ChoiceNum <= 25) THEN + BEGIN + NL; + Prt('Choice '+IntToStr(ChoiceNum)+': '); + MPL(65); + InputWC(Topic.Answers[ChoiceNum].Answer1,65); + IF (Topic.Answers[ChoiceNum].Answer1 <> '') THEN + BEGIN + Prt(PadLeftStr('',7+Length(IntToStr(ChoiceNum)))+': '); + MPL(65); + InputWC(Topic.Answers[ChoiceNum].Answer2,65); + NL; + IF (NOT PYNQ('Add this choice? ',0,FALSE)) THEN + BEGIN + Topic.Answers[ChoiceNum].Answer1 := ''; + Topic.Answers[ChoiceNum].Answer2 := ''; + END + ELSE + BEGIN + Inc(Topic.ChoiceNumber); + Topic.Answers[ChoiceNum].NumVotedAnswer := 1; + Inc(Topic.NumVotedQuestion); + ThisUser.Vote[TopicNum] := ChoiceNum; + SL1('Added choice to '+Topic.Question1+':'); + SysOpLog(Topic.Answers[ChoiceNum].Answer1); + IF (Topic.Answers[ChoiceNum].Answer2 <> '') THEN + SysOpLog(Topic.Answers[ChoiceNum].Answer2); + END; + END; + END + ELSE IF (ChoiceNum >= 1) AND (ChoiceNum <= Topic.ChoiceNumber) THEN + BEGIN + Inc(Topic.Answers[ChoiceNum].NumVotedAnswer); + Inc(Topic.NumVotedQuestion); + ThisUser.Vote[TopicNum] := ChoiceNum; + END; + Seek(VotingFile,(TopicNum - 1)); + Write(VotingFile,Topic); + Close(VotingFile); + SaveURec(ThisUser,UserNum); + NL; + IF PYNQ('See results? ',0,TRUE) THEN + TopicResults(TopicNum,ThisUser,FALSE); + IF (InputStr = 'Q') THEN + Abort := TRUE; + LastError := IOResult; +END; + +PROCEDURE VoteAll; +VAR + TopicNum, + NumTopics: Byte; + Found: Boolean; +BEGIN + IF (RVoting IN ThisUser.Flags) THEN + BEGIN + NL; + Print('You are restricted from voting.'); + PauseScr(FALSE); + Exit; + END; + NumTopics := GetTopics; + IF (NumTopics = 0) THEN + BEGIN + NL; + Print('There are no topics available.'); + PauseScr(FALSE); + Exit; + END; + Abort := FALSE; + Next := FALSE; + Found := FALSE; + TopicNum := 1; + WHILE (TopicNum <= NumTopics) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (ThisUser.Vote[AvailableTopics[TopicNum]] = 0) THEN + BEGIN + GoVote(AvailableTopics[TopicNum]); + Found := TRUE; + END; + Inc(TopicNum); + END; + IF (NOT Found) THEN + BEGIN + NL; + Print('You have voted on all available topics.'); + PauseScr(FALSE); + END; +END; + +PROCEDURE VoteOne(TopicNum: Byte); +VAR + NumTopics: Byte; +BEGIN + IF (RVoting IN ThisUser.Flags) THEN + BEGIN + NL; + Print('You are restricted from voting.'); + PauseScr(FALSE); + Exit; + END; + NumTopics := GetTopics; + IF (NumTopics = 0) THEN + BEGIN + NL; + Print('There are no topics available.'); + PauseScr(FALSE); + Exit; + END; + IF (TopicNum < 1) AND (TopicNum > NumTopics) THEN + BEGIN + NL; + Print('The range must be from 1 to '+IntToStr(NumTopics)+'.'); + PauseScr(FALSE); + Exit; + END; + IF (ThisUser.Vote[AvailableTopics[TopicNum]] > 0) AND (NOT AACS(General.ChangeVote)) THEN + BEGIN + NL; + Print('You can only vote once on this topic.'); + PauseScr(FALSE); + Exit; + END; + GoVote(AvailableTopics[TopicNum]); +END; + +PROCEDURE Results(ListVoters: Boolean); +VAR + InputStr: Str2; + TopicNum, + NumTopics: Byte; +BEGIN + NumTopics := GetTopics; + IF (NumTopics = 0) THEN + BEGIN + NL; + Print('There are no topics available.'); + PauseScr(FALSE); + Exit; + END; + REPEAT + NL; + Prt('Results of which topic? (^51^4-^5'+IntToStr(NumTopics)+'^4) [^5?^4=^5List^4]: '); + MPL(Length(IntToStr(NumTopics))); + ScanInput(InputStr,^M'?'); + IF (InputStr = '?') THEN + ListTopics(FALSE); + UNTIL (InputStr <> '?') OR (HangUp); + IF (InputStr <> ^M) THEN + BEGIN + TopicNum := StrToInt(InputStr); + IF (TopicNum >= 1) AND (TopicNum <= NumTopics) THEN + TopicResults(AvailableTopics[TopicNum],ThisUser,ListVoters) + ELSE + BEGIN + NL; + Print('^1The range must be from 1 to '+IntToStr(NumTopics)+'.'); + PauseScr(FALSE); + END; + END; +END; + +PROCEDURE TrackUser; +VAR + User: UserRecordType; + NumTopics, + TopicNum: Byte; + Unum: Integer; + Found: Boolean; +BEGIN + NumTopics := GetTopics; + IF (NumTopics = 0) THEN + BEGIN + NL; + Print('There are no topics available.'); + PauseScr(FALSE); + Exit; + END; + NL; + Print('Track voting for which user (1-'+IntToStr(MaxUsers - 1)+')?'); + NL; + Print('Enter User Number, Name, or Partial Search String.'); + Prt(': '); + lFindUserWS(Unum); + IF (Unum < 1) THEN + PauseScr(FALSE) + ELSE + BEGIN + LoadURec(User,Unum); + IF (RVoting IN User.Flags) THEN + BEGIN + NL; + Print('^1This user is restricted from voting.'); + PauseScr(FALSE); + Exit; + END; + Abort := FALSE; + Next := FALSE; + Found := FALSE; + TopicNum := 1; + WHILE (TopicNum <= NumTopics) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + IF (User.Vote[TopicNum] > 0) THEN + BEGIN + TopicResults(TopicNum,User,FALSE); + Found := TRUE; + END; + Inc(TopicNum); + END; + IF (NOT Found) THEN + BEGIN + NL; + Print('^1This user has not voted on any topics.'); + PauseScr(FALSE); + END; + END; +END; + +PROCEDURE AddTopic; +VAR + ChoiceNum: Byte; +BEGIN + IF (NumVotes = MaxVotes) THEN + BEGIN + NL; + Prt('No room for additional topics!'); + PauseScr(FALSE); + Exit; + END; + FillChar(Topic,SizeOf(Topic),'0'); + CLS; + Print('^3Voting addition:'); + NL; + Print('^9Now enter your topic. You have up to two lines for your topic.'); + Print('^9Press [Enter] on a blank line to leave blank or abort.'); + NL; + Prt('Topic: '); + MPL(SizeOf(Topic.Question1) - 1); + InputWC(Topic.Question1,SizeOf(Topic.Question1) - 1); + IF (Topic.Question1 <> '') THEN + BEGIN + Prt(PadLeftStr('',5)+': '); + MPL(SizeOf(Topic.Question2) - 1); + InputWC(Topic.Question2,SizeOf(Topic.Question2) - 1); + NL; + IF PYNQ('Are you sure? ',0,FALSE) THEN + BEGIN + Topic.CreatedBy := Caps(ThisUser.Name); + Topic.NumVotedQuestion := 0; + Topic.ACS := 'VV'; + NL; + IF PYNQ('Allow other users to add choices? ',0,FALSE) THEN + Topic.AddAnswersACS := Topic.ACS + ELSE + Topic.AddAnswersACS := General.AddChoice; + NL; + Print('^9Now enter the choices. You have up to two lines for each'); + Print('choice. Press [Enter] on a blank first choice line to end.'); + NL; + Topic.ChoiceNumber := 0; + Abort := FALSE; + Next := FALSE; + ChoiceNum := 0; + WHILE (ChoiceNum < 25) AND (NOT Abort) AND (NOT HangUp) DO + BEGIN + Inc(ChoiceNum); + Prt('Choice '+PadRightInt(ChoiceNum,2)+': '); + MPL(SizeOf(Topic.Answers[ChoiceNum].Answer1) - 1); + InputWC(Topic.Answers[ChoiceNum].Answer1,SizeOf(Topic.Answers[ChoiceNum].Answer1) - 1); + IF (Topic.Answers[ChoiceNum].Answer1 = '') THEN + Abort := TRUE + ELSE + BEGIN + Inc(Topic.ChoiceNumber); + Prt(PadLeftStr('',9)+': '); + MPL(SizeOf(Topic.Answers[ChoiceNum].Answer2) - 1); + InputWC(Topic.Answers[ChoiceNum].Answer2,SizeOf(Topic.Answers[ChoiceNum].Answer2) - 1); + Topic.Answers[ChoiceNum].NumVotedAnswer := 0; + END; + END; + IF ((ChoiceNum > 1) OR (Topic.ChoiceNumber > 0)) THEN + BEGIN + NL; + IF (PYNQ('Add this topic? ',0,FALSE)) THEN + BEGIN + Reset(VotingFile); + Seek(VotingFile,FileSize(VotingFile)); + Write(VotingFile,Topic); + Close(VotingFile); + Inc(NumVotes); + SysOpLog('Added voting topic: '+Topic.Question1); + IF (Topic.Question2 <> '') THEN + SysOpLog(' : '+Topic.Question2); + END; + END; + END; + END; + LastError := IOResult; + NL; + PauseScr(FALSE); +END; + +END. diff --git a/SOURCE/WFCMENU.PAS b/SOURCE/WFCMENU.PAS new file mode 100644 index 0000000..cbbdc15 --- /dev/null +++ b/SOURCE/WFCMENU.PAS @@ -0,0 +1,1364 @@ +{$IFDEF WIN32} +{$I DEFINES.INC} +{$ENDIF} + +{$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-} + +UNIT WFCMenu; + +INTERFACE + +PROCEDURE WFCMDefine; +PROCEDURE WFCMenus; + +IMPLEMENTATION + +USES + Crt, + Dos, + Boot, + Bulletin, + Common, + CUser, + Doors, + EMail, + Events, + File7, + File10, + File13, + Mail1, + Mail2, + Mail3, + Maint, + Menus2, + MsgPack, + MultNode, + MyIO, + SysOp1, + SysOp2, + SysOp3, + SysOp4, + SysOp5, + SysOp6, + SysOp7, + SysOp8, + SysOp9, + SysOp10, + SysOp11, + SysOp12, + TimeFunc, + MiscUser +{$IFDEF WIN32} + ,Windows +{$ENDIF} + ; + +VAR + LastKeyPress: LongInt; + +CONST + ANSWER_LENGTH = 203; + ANSWER: ARRAY [1..203] OF Char = ( + #0 ,#17,#25,#23,#14,'R','e','n','e','g','a','d','e',' ','i','s',' ', + 'a','n','s','w','e','r','i','n','g',' ','t','h','e',' ','p','h','o', + 'n','e','.',#25,#19,#24,#25,'K',#24,' ',' ',#15,'[',#14,'A',#15,']', + ' ',' ','3','0','0',#25,#3 ,'[',#14,'C',#15,']',' ','2','4','0','0', + #25,#3 ,'[',#14,'E',#15,']',' ','7','2','0','0',#25,#3 ,'[',#14,'G', + #15,']',' ','1','2','0','0','0',#25,#3 ,'[',#14,'I',#15,']',' ','1', + '6','8','0','0',#25,#3 ,'[',#14,'K',#15,']',' ','3','8','4','0','0', + #25,#2 ,#24,' ',' ','[',#14,'B',#15,']',' ','1','2','0','0',#25,#3 , + '[',#14,'D',#15,']',' ','4','8','0','0',#25,#3 ,'[',#14,'F',#15,']', + ' ','9','6','0','0',#25,#3 ,'[',#14,'H',#15,']',' ','1','4','4','0', + '0',#25,#3 ,'[',#14,'J',#15,']',' ','1','9','2','0','0',#25,#3 ,'[', + #14,'L',#15,']',' ','5','7','6','0','0',#25,#2 ,#24,#25,'K',#24); + + WFCNET_LENGTH = 98; + WFCNET: ARRAY [1..98] OF Char = ( + #0 ,#17,#25,'K',#24,#25,#26,#15,'R','e','n','e','g','a','d','e',' ', + 'N','e','t','w','o','r','k',' ','N','o','d','e',#25,#27,#24,#25,'K', + #24,#25,#9 ,'P','r','e','s','s',' ','[','S','P','A','C','E','B','A', + 'R',']',' ','t','o',' ','l','o','g','i','n','.',' ',' ','P','r','e', + 's','s',' ','[','Q',']',' ','t','o',' ','q','u','i','t',' ','R','e', + 'n','e','g','a','d','e','.',#25,#10,#24,#25,'K',#24); + + WFC_LENGTH = 1153; + WFC : ARRAY [1..1153] OF Char = ( + #15,#17,#25,#22,'T','h','e',' ','R','e','n','e','g','a','d','e',' ', + 'B','u','l','l','e','t','i','n',' ','B','o','a','r','d',' ','S','y', + 's','t','e','m',#25,#22,#24,' ', #0,'',#26,#16,'', #9,'',' ', #0, + '',#26,#16,'', #9,'',' ', #0,'',#26,#16,'', #9,'',' ', #0,'', + #26,#15,'', #9,'',' ',#24,' ', #0,'',' ',' ',#10,'T','o','d','a', + 'y',#39,'s',' ','S','t','a','t','s',' ',' ', #9,'',' ', #0,'',' ', + #10,'S','y','s','t','e','m',' ','A','v','e','r','a','g','e','s',' ', + #9,'',' ', #0,'',' ',' ',#10,'S','y','s','t','e','m',' ','T','o', + 't','a','l','s',' ',' ', #9,'',' ', #0,'',#25, #2,#10,'O','t','h', + 'e','r',' ','I','n','f','o',#25, #2, #9,'',' ',#24,' ', #0,'',' ', + #15,'C','a','l','l','s',#25,#10, #9,'',' ', #0,'',' ',#15,'C','a', + 'l','l','s',#25,#10, #9,'',' ', #0,'',' ',#15,'C','a','l','l','s', + #25,#10, #9,'',' ', #0,'',' ',#15,'N','o','d','e',#25,#10, #9,'', + ' ',#24,' ', #0,'',' ',#15,'P','o','s','t','s',#25,#10, #9,'',' ', + #0,'',' ',#15,'P','o','s','t','s',#25,#10, #9,'',' ', #0,'',' ', + #15,'P','o','s','t','s',#25,#10, #9,'',' ', #0,'',' ',#15,'U','n', + 'd','e','r',#25, #9, #9,'',' ',#24,' ', #0,'',' ',#15,'E','m','a', + 'i','l',#25,#10, #9,'',' ', #0,'',' ',#15,'#',' ','U','L',#25,#11, + #9,'',' ', #0,'',' ',#15,'#',' ','U','L',#25,#11, #9,'',' ', #0, + '',' ',#15,'E','r','r','o','r','s',#25, #8, #9,'',' ',#24,' ', #0, + '',' ',#15,'N','e','w','u','s','e','r','s',#25, #7, #9,'',' ', #0, + '',' ',#15,'#',' ','D','L',#25,#11, #9,'',' ', #0,'',' ',#15,'#', + ' ','D','L',#25,#11, #9,'',' ', #0,'',' ',#15,'M','a','i','l',#25, + #10, #9,'',' ',#24,' ', #0,'',' ',#15,'F','e','e','d','b','a','c', + 'k',#25, #7, #9,'',' ', #0,'',' ',#15,'A','c','t','i','v','i','t', + 'y',#25, #7, #9,'',' ', #0,'',' ',#15,'D','a','y','s',#25,#11, #9, + '',' ', #0,'',' ',#15,'U','s','e','r','s',#25, #9, #9,'',' ',#24, + ' ', #0,'',' ',#15,'#',' ','U','L',#25,#11, #9,'',' ', #0,'', #9, + #26,#16,'','',' ', #0,'', #9,#26,#16,'','',' ', #0,'', #9,#26, + #15,'','',' ',#24,' ', #0,'',' ',#15,'K','b',' ','U','L',#25,#10, + #9,'',' ', #0,'',#26,#23,'',' ',#15,'M','o','d','e','m',' ', #0, + #26,#24,'', #9,'',' ',#24,' ', #0,'',' ',#15,'#',' ','D','L',#25, + #11, #9,'',' ', #0,'',#16,#25,'7', #9,#17,'',' ',#24,' ', #0,'', + ' ',#15,'K','b',' ','D','L',#25,#10, #9,'',' ', #0,'',#16,#25,'7', + #9,#17,'',' ',#24,' ', #0,'',' ',#15,'M','i','n','u','t','e','s', + #25, #8, #9,'',' ', #0,'',#16,#25,'7', #9,#17,'',' ',#24,' ', #0, + '',' ',#15,'O','v','e','r','l','a','y','s',#25, #7, #9,'',' ', #0, + '',#16,#25,'7', #9,#17,'',' ',#24,' ', #0,'',' ',#15,'F','r','e', + 'e',' ',' ',' ',' ',' ',#25, #6, #9,'',' ', #0,'',#16,#25,'7', #9, + #17,'',' ',#24,' ', #0,'', #9,#26,#16,'','',' ', #0,'', #9,#26, + '7','','',' ',#24,#25,'O',#24,' ', #0,'',#26,'K','', #9,'',' ', + #24,' ', #0,'',' ',#15,'[',#14,'S',#15,']','y','s','t','e','m',' ', + 'C','o','n','f','i','g',' ','[',#14,'F',#15,']','i','l','e',' ','B', + 'a','s','e',#25, #3,'[',#14,'C',#15,']','a','l','l','e','r','s',#25, + #3,'[',#14,'I',#15,']','n','i','t',' ','M','o','d','e','m',#25, #3, + '[',#14,'!',#15,']','V','a','l','i','d','a','t','e',#25, #3, #9,'', + ' ',#24,' ', #0,'',' ',#15,'[',#14,'U',#15,']','s','e','r',' ','E', + 'd','i','t','o','r',#25, #2,'[',#14,'B',#15,']','M','s','g',' ','B', + 'a','s','e',#25, #3,'[',#14,'P',#15,']','a','c','k',' ','M','s','g', + 's',' ',' ','[',#14,'O',#15,']','f','f','h','o','o','k',' ','M','o', + 'd','e','m',' ','[',#14,'L',#15,']','o','g','s',#25, #8, #9,'',' ', + #24,' ', #0,'',' ',#15,'[',#14,'#',#15,']','M','e','n','u',' ','E', + 'd','i','t','o','r',' ',' ','[',#14,'X',#15,']','f','e','r',' ','P', + 'r','o','t','s',#25, #2,'[',#14,'M',#15,']','a','i','l',' ','R','e', + 'a','d',' ',' ','[',#14,'A',#15,']','n','s','w','e','r',' ','M','o', + 'd','e','m',' ',' ','[',#14,'Z',#15,']','H','i','s','t','o','r','y', + #25, #4, #9,'',' ',#24,' ', #0,'',' ',#15,'[',#14,'E',#15,']','v', + 'e','n','t',' ','E','d','i','t','o','r',' ',' ','[',#14,'W',#15,']', + 'r','i','t','e',' ','M','a','i','l',#25, #2,'[',#14,'R',#15,']','e', + 'a','d',' ','M','a','i','l',' ',' ','[',#14,'H',#15,']','a','n','g', + 'u','p',' ','M','o','d','e','m',' ',' ','[',#14,'D',#15,']','r','o', + 'p',' ','t','o',' ','D','O','S',' ',' ', #9,'',' ',#24,' ', #0,'', + ' ',#15,'[',#14,'V',#15,']','o','t','i','n','g',' ','E','d','i','t', + 'o','r',' ','[',#14,'$',#15,']','C','o','n','f','e','r','e','n','c', + 'e','s',' ','[',' ',']',' ','L','o','g',' ','O','n',#25, #2,'[',#14, + 'N',#15,']','o','d','e',' ','l','i','s','t','i','n','g',' ',' ','[', + #14,'Q',#15,']','u','i','t',' ','t','o',' ','D','O','S',' ',' ', #9, + '',' ',#24,' ', #0,'', #9,#26,'K','','',' ',#24,#24); + + + WFC0_LENGTH = 488; + WFC0: ARRAY [1..488] OF Char = ( + #14,#16,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24,#24, + #24,#24,#17,' ', #0,'',#26,'K','', #9,'',' ',#24,' ', #0,'',' ', + #15,'[',#14,'S',#15,']','y','s','t','e','m',' ','C','o','n','f','i', + 'g',' ','[',#14,'F',#15,']','i','l','e',' ','B','a','s','e',#25, #3, + '[',#14,'C',#15,']','a','l','l','e','r','s',#25, #3,'[',#14,'I',#15, + ']','n','i','t',' ','M','o','d','e','m',#25, #3,'[',#14,'!',#15,']', + 'V','a','l','i','d','a','t','e',#25, #3, #9,'',' ',#24,' ', #0,'', + ' ',#15,'[',#14,'J',#15,']','u','m','p',' ','t','o',' ','D','O','S', + #25, #2,'[',#14,'B',#15,']','M','s','g',' ','B','a','s','e',#25, #3, + '[',#14,'P',#15,']','a','c','k',' ','M','s','g','s',' ',' ','[',#14, + 'O',#15,']','f','f','h','o','o','k',' ','M','o','d','e','m',' ','[', + #14,'L',#15,']','o','g','s',#25, #8, #9,'',' ',#24,' ', #0,'',' ', + #15,'[',#14,'#',#15,']','M','e','n','u',' ','E','d','i','t','o','r', + ' ',' ','[',#14,'X',#15,']','f','e','r',' ','P','r','o','t','s',#25, + #2,'[',#14,'M',#15,']','a','i','l',' ','R','e','a','d',' ',' ','[', + #14,'A',#15,']','n','s','w','e','r',' ','M','o','d','e','m',' ',' ', + '[',#14,'Z',#15,']','H','i','s','t','o','r','y',#25, #4, #9,'',' ', + #24,' ', #0,'',' ',#15,'[',#14,'E',#15,']','v','e','n','t',' ','E', + 'd','i','t','o','r',' ',' ','[',#14,'W',#15,']','r','i','t','e',' ', + 'M','a','i','l',#25, #2,'[',#14,'R',#15,']','e','a','d',' ','M','a', + 'i','l',' ',' ','[',#14,'H',#15,']','a','n','g','u','p',' ','M','o', + 'd','e','m',' ',' ','[',#14,'U',#15,']','s','e','r',' ','E','d','i', + 't','o','r',' ',' ', #9,'',' ',#24,' ', #0,'',' ',#15,'[',#14,'V', + #15,']','o','t','i','n','g',' ','E','d','i','t','o','r',' ','[',#14, + '$',#15,']','C','o','n','f','e','r','e','n','c','e','s',' ','[',#14, + 'D',#15,']','i','s','p','l','a','y',' ','N','S',' ','[',#14,'N',#15, + ']','o','d','e',' ','l','i','s','t','i','n','g',' ',' ','[',#14,'Q', + #15,']','u','i','t',' ','t','o',' ','D','O','S',' ',' ', #9,'',' ', + #24,' ', #0,'', #9,#26,'K','','',' ',#24,#24); + +PROCEDURE WFCMDefine; +BEGIN + UploadsToday := 0; + DownloadsToday := 0; + UploadKBytesToday := 0; + DownloadKBytesToday := 0; + PrivatePostsToday := 0; + PublicPostsToday := 0; + FeedbackPostsToday := 0; + ChatAttempts := 0; + ShutUpChatCall := FALSE; + ContList := FALSE; + BadDLPath := FALSE; + TellUserEvent := 0; + TimeWarn := FALSE; + FastLogon := FALSE; + FileArea := 1; + MsgArea := 1; + ReadFileArea := -1; + ReadMsgArea := -1; + InWFCMenu := TRUE; + Reading_A_Msg := FALSE; + OutCom := FALSE; + UserOn := FALSE; + LastLineStr := ''; + ChatReason := ''; + Buf := ''; + HangUp := FALSE; + ChatCall := FALSE; + HungUp := FALSE; + TimedOut := FALSE; + Rate := 3840; + ANSIDetected := FALSE; + TextAttr := 7; + ClrScr; + UserNum := 0; + IF ((MaxUsers - 1) >= 1) THEN + BEGIN + LoadURec(ThisUser,1); + TempPause := (Pause IN ThisUser.Flags); + Reset(SchemeFile); + IF (ThisUser.ColorScheme > 0) AND (ThisUser.ColorScheme <= FileSize(SchemeFile)) THEN + Seek(SchemeFile,(ThisUser.ColorScheme - 1)); + Read(SchemeFile,Scheme); + Close(SchemeFile); + NewCompTables; + UserNum := 1; + END + ELSE + WITH ThisUser DO + BEGIN + LineLen := 80; + PageLen := 24; + Flags := [HotKey,Pause,Novice,ANSI,Color]; + Exclude(Flags,Avatar); + Reset(SchemeFile); + Read(SchemeFile,Scheme); + Close(SchemeFile); + END; +END; + +PROCEDURE GetConnection; +VAR + s: AStr; + C: Char; + Done: Boolean; + rl, + SaveTimer: LongInt; + + PROCEDURE GetResultCode(CONST ResultCode: AStr); + VAR + MaxCodes: Byte; + BEGIN + MaxCodes := MaxResultCodes; { NOTE! Done backwards to avoid CONNECT 1200 / CONNECT 12000 confusion!! } + Reliable := (Pos(Liner.Reliable,ResultCode) > 0); + WITH Liner DO + REPEAT + IF (Connect[MaxCodes] <> '') AND (Pos(Connect[MaxCodes],ResultCode) > 0) THEN + BEGIN + CASE MaxCodes OF + 1 : ActualSpeed := 300; + 2 : ActualSpeed := 600; + 3 : ActualSpeed := 1200; + 4 : ActualSpeed := 2400; + 5 : ActualSpeed := 4800; + 6 : ActualSpeed := 7200; + 7 : ActualSpeed := 9600; + 8 : ActualSpeed := 12000; + 9 : ActualSpeed := 14400; + 10 : ActualSpeed := 16800; + 11 : ActualSpeed := 19200; + 12 : ActualSpeed := 21600; + 13 : ActualSpeed := 24000; + 14 : ActualSpeed := 26400; + 15 : ActualSpeed := 28800; + 16 : ActualSpeed := 31200; + 17 : ActualSpeed := 33600; + 18 : ActualSpeed := 38400; + 19 : ActualSpeed := 57600; + 20 : ActualSpeed := 115200; + END; + Done := TRUE; + END + ELSE + Dec(MaxCodes); + UNTIL (Done) OR (MaxCodes = 1); + END; + +BEGIN + IF (AnswerBaud > 0) THEN + BEGIN + ActualSpeed := AnswerBaud; + IF (LockedPort IN Liner.MFlags) THEN + ComPortSpeed := Liner.InitBaud + ELSE + ComPortSpeed := ActualSpeed; + AnswerBaud := 0; + InCom := TRUE; + Exit; + END; + + Reliable := FALSE; { Could've been set in boot - don't move } + + Com_Flush_Recv; + IF (Liner.Answer <> '') THEN + Com_Send_Str(Liner.Answer); + + IF (SysOpOn) THEN +{$IFDEF MSDOS} + Update_Logo(ANSWER,ScreenAddr[(3*2)+(19*160)-162],ANSWER_LENGTH); +{$ENDIF} +{$IFDEF WIN32} + Update_Logo(ANSWER, 3, 19, ANSWER_LENGTH); +{$ENDIF} + + rl := 0; + SaveTimer := Timer; + + s := ''; + + REPEAT + Done := FALSE; + + IF (KeyPressed) THEN + BEGIN + + C := UpCase(ReadKey); + + IF (C = ^[) THEN + BEGIN + DTR(FALSE); + Done := TRUE; + Com_Send_Str(Liner.HangUp); + Delay(100); + DTR(TRUE); + Com_Flush_Recv; + END; + + CASE C OF + 'A' : ActualSpeed := 300; + 'B' : ActualSpeed := 1200; + 'C' : ActualSpeed := 2400; + 'D' : ActualSpeed := 4800; + 'E' : ActualSpeed := 7200; + 'F' : ActualSpeed := 9600; + 'G' : ActualSpeed := 12000; + 'H' : ActualSpeed := 14400; + 'I' : ActualSpeed := 16800; + 'J' : ActualSpeed := 19200; + 'K' : ActualSpeed := 38400; + 'L': ActualSpeed := 57600; + END; + Done := TRUE; + END; + + C := CInKey; + IF (rl <> 0) AND (ABS(rl - Timer) > 2) AND (C = #0) THEN + C := ^M; + IF (C > #0) THEN + BEGIN + WriteWFC(C); + IF (C <> ^M) THEN + BEGIN + IF (Length(s) >= 160) THEN + Delete(s,1,120); + s := s + C; + rl := Timer; + END + ELSE + BEGIN + IF (Pos(Liner.NoCarrier,s) > 0) THEN + Done := TRUE; + IF (Pos(Liner.CallerID,s) > 0) THEN + CallerIDNumber := Copy(s,Pos(Liner.CallerID,s) + Length(Liner.CallerID),40); + GetResultCode(s); + rl := 0; + END; + END; + IF (C = ^M) THEN + s := ''; + IF (ABS(Timer - SaveTimer) > 45) THEN + Done := TRUE; + UNTIL (Done); + + + Com_Flush_Recv; + + IF (ABS(Timer - SaveTimer) > 45) THEN + C := 'X'; + + InCom := (ActualSpeed <> 0); + + IF (InCom) AND (LockedPort IN Liner.MFlags) THEN + ComPortSpeed := Liner.InitBaud + ELSE + ComPortSpeed := ActualSpeed; + +END; + +PROCEDURE WFCDraw; +VAR + HistoryFile: FILE OF HistoryRecordType; + History: HistoryRecordType; + s: STRING[10]; + L: LongInt; +BEGIN + Window(1,1,MaxDisplayCols,MaxDisplayRows); + LastWFCX := 1; + LastWFCY := 1; + CursorOn(FALSE); + ClrScr; + IF (AnswerBaud > 0) THEN + Exit; + + IF (NOT BlankMenuNow) AND (SysOpOn) THEN + BEGIN + + IF (SysOpOn) THEN + BEGIN + +{$IFDEF MSDOS} + Update_Logo(WFC,ScreenAddr[0],WFC_LENGTH); +{$ENDIF} +{$IFDEF WIN32} + Update_Logo(WFC, 1, 1, WFC_LENGTH); +{$ENDIF} + IF (General.NetworkMode) THEN +{$IFDEF MSDOS} + Update_Logo(WFCNET,ScreenAddr[(3*2)+(19*160)-162],WFCNET_LENGTH); +{$ENDIF} +{$IFDEF WIN32} + Update_Logo(WFCNET, 3, 19, WFCNET_LENGTH); +{$ENDIF} + + LoadURec(ThisUser,1); + + TextAttr := 31; + GoToXY(4,1); + Write(PadRightStr(TimeStr,8)); + GoToXY(68,1); + Write(DateStr); + + Assign(HistoryFile,General.DataPath+'HISTORY.DAT'); + IF (NOT Exist(General.DataPath+'HISTORY.DAT')) THEN + BEGIN + ReWrite(HistoryFile); + WITH History DO + BEGIN + Date := Date2PD(DateStr); + Active := 0; + Callers := 0; + NewUsers := 0; + Posts := 0; + EMail := 0; + FeedBack := 0; + Errors := 0; + Uploads := 0; + Downloads := 0; + UK := 0; + Dk := 0; + FOR L := 0 TO 20 DO + UserBaud[L] := 0; + END; + Write(HistoryFile,History); + END + ELSE + BEGIN + Reset(HistoryFile); + Seek(HistoryFile,(FileSize(HistoryFile) - 1)); + Read(HistoryFile,History); + END; + Close(HistoryFile); + + WITH History DO + BEGIN + TextAttr := 19; + + GoToXY(14,04); + Write(PadRightInt(Callers,5)); + + GoToXY(14,05); + Write(PadRightInt(Posts,5)); + + GoToXY(14,06); + Write(PadRightInt(EMail,5)); + + GoToXY(14,07); + Write(PadRightInt(NewUsers,5)); + + GoToXY(14,08); + Write(PadRightInt(FeedBack,5)); + + GoToXY(14,09); + Write(PadRightInt(Uploads,5)); + + TextAttr := 31; + S := ConvertBytes(UK * 1024,FALSE); + GoToXY(04,10); + Write(Copy(S,(Pos(' ',S) + 1),Length(S))+' UL'); + + TextAttr := 19; + GoToXY(14,10); + Write(PadRightStr(Copy(S,1,(Pos(' ',S) - 1)),5)); + + GoToXY(14,11); + Write(PadRightInt(Downloads,5)); + + TextAttr := 31; + S := ConvertBytes(DK * 1024,FALSE); + GoToXY(04,12); + Write(Copy(S,(Pos(' ',S) + 1),Length(S))+' DL'); + + TextAttr := 19; + GoToXY(14,12); + Write(PadRightStr(Copy(S,1,(Pos(' ',S) - 1)),5)); + + GoToXY(14,13); + Write(PadRightInt(Active,5)); + GoToXY(14,14); + + CASE OverlayLocation OF + 0 : Write(' Disk'); + 1 : Write(' EMS'); + 2 : Write(' XMS'); + END; + + GoToXY(11,15); + L := DiskKBFree(StartDir); + IF (L < General.MinSpaceForUpload) OR (L < General.MinSpaceForPost) THEN + TextAttr := 156; + + Write(PadRightStr(ConvertKB(L,FALSE),8)); + TextAttr := 19; + + IF (General.DaysOnline = 0) THEN + Inc(General.DaysOnline); + GoToXY(34,04); + Str(((General.TotalCalls + Callers) / General.DaysOnline):2:2,s); + Write(PadRightStr(s,5)); + + GoToXY(34,05); + Str(((General.TotalPosts + Posts) / General.DaysOnline):2:2,s); + Write(PadRightStr(s,5)); + + GoToXY(34,06); + Str(((General.TotalUloads + Uploads) / General.DaysOnline):2:2,s); + Write(PadRightStr(s,5)); + + GoToXY(34,07); + Str(((General.TotalDloads + Downloads) / General.DaysOnline):2:2,s); + Write(PadRightStr(s,5)); + + GoToXY(34,08); + Str(((General.TotalUsage + Active) / General.DaysOnline) / 14.0:2:2,s); + Write(PadRightStr(s,4),'%'); + + GoToXY(53,04); + Write(PadRightInt(General.CallerNum,6)); + + GoToXY(53,05); + Write(PadRightInt((General.TotalPosts + Posts),6)); + + GoToXY(53,06); + Write(PadRightInt((General.TotalUloads + Uploads),6)); + + GoToXY(53,07); + Write(PadRightInt((General.TotalDloads + Downloads),6)); + + GoToXY(53,08); + Write(PadRightInt(General.DaysOnline,6)); + + GoToXY(73,04); + Write(PadRightInt(ThisNode,5)); + + GoToXY(73,05); + CASE Tasker OF + None : Write(' DOS'); + DV : Write(' DV'); + Win : Write(' Win'); + OS2 : Write(' OS/2'); + Win32 : Write('Win32'); + Dos5N : Write('DOS/N'); + END; + + GoToXY(73,06); + Write(PadRightInt(Errors,5)); + + IF (ThisUser.Waiting > 0) THEN + TextAttr := 156; + GoToXY(73,07); + Write(PadRightInt(ThisUser.Waiting,5)); + + TextAttr := 19; + GoToXY(73,08); + Write(PadRightInt(General.NumUsers,5)); + + IF (General.TotalUsage < 1) OR (General.DaysOnline < 1) THEN + UpdateGeneral; + TextAttr := 7; + END; + END + ELSE +{$IFDEF MSDOS} + Update_Logo(WFC0,ScreenAddr[0],WFC0_LENGTH); +{$ENDIF} +{$IFDEF WIN32} + Update_Logo(WFC0, 1, 1, WFC0_LENGTH); +{$ENDIF} + END; +END; + +PROCEDURE WFCMenus; +CONST + RingNumber: Byte = 0; + MultiRinging: Boolean = FALSE; +VAR + WFCMessage, + s: AStr; + C, + c2: Char; + UNum: Integer; + LastRing, + LastMinute, + rl2, + LastInit: LongInt; + InBox, + RedrawWFC, + PhoneOffHook, + CheckForConnection: Boolean; + + PROCEDURE InitModem; + VAR + s: AStr; + C: Char; + try: Integer; + rl, + rl1: LongInt; + done: Boolean; + BEGIN + C := #0; + done := FALSE; + try := 0; + IF ((Liner.Init <> '') AND (AnswerBaud = 0) AND (NOT LocalIOOnly)) THEN + BEGIN + IF (SysOpOn) AND (NOT BlankMenuNow) THEN + BEGIN + TextAttr := 31; + GoToXY(1,17); + ClrEOL; + GoToXY(31,17); + Write('Initializing modem ...'); + END; + rl := Timer; + + WHILE (KeyPressed) DO + C := ReadKey; + + REPEAT + Com_Set_Speed(Liner.InitBaud); + Com_Flush_Recv; + Com_Send_Str(Liner.Init); + s := ''; + rl1 := Timer; + REPEAT + C := CInKey; + IF (C > #0) THEN + BEGIN + WriteWFC(C); + IF (Length(s) >= 160) THEN + Delete(s,1,120); + s := s + C; + IF (Pos(Liner.OK, s) > 0) THEN + Done := TRUE; + END; + UNTIL ((ABS(Timer - rl1) > 3) OR (done)) OR (KeyPressed); + Com_Flush_Recv; + Inc(try); + IF (try > 10) THEN + Done := TRUE; + UNTIL ((done) OR (KeyPressed)); + IF (SysOpOn) AND (NOT BlankMenuNow) THEN + BEGIN + GoToXY(1,17); + ClrEOL; + END; + END; + PhoneOffHook := FALSE; + WFCMessage := ''; + LastInit := Timer; + WHILE (KeyPressed) DO + C := ReadKey; + Com_Flush_Recv; + TextAttr := 7; + END; + + FUNCTION CPW: Boolean; + VAR + PW: Str20; + BEGIN + IF (NOT SysOpOn) THEN + BEGIN + TextAttr := 25; + Write('Password: '); + TextAttr := 17; + GetPassword(PW,20); + ClrScr; + CPW := (PW = General.SysOpPW); + END + ELSE + CPW := TRUE; + END; + + PROCEDURE TakeOffHook(ShowIt: Boolean); + BEGIN + IF (NOT LocalIOOnly) THEN + BEGIN + DoPhoneOffHook(ShowIt); + PhoneOffHook := TRUE; + WFCMessage := 'Modem off hook'; + END; + END; + + PROCEDURE BeepHim; + VAR + C: Char; + rl, + rl1: LongInt; + BEGIN + TakeOffHook(FALSE); + BeepEnd := FALSE; + rl := Timer; + REPEAT +{$IFDEF MSDOS} + Sound(1500); + Delay(20); + Sound(1000); + Delay(20); + Sound(800); + Delay(20); + NoSound; +{$ENDIF} +{$IFDEF WIN32} + Sound(1000, 60); +{$ENDIF} + rl1 := Timer; + WHILE (ABS(rl1 - Timer) < 0.9) AND (NOT KeyPressed) DO; + UNTIL (ABS(rl - Timer) > 30) OR (KeyPressed); + IF (KeyPressed) THEN + C := ReadKey; + InitModem; + END; + + PROCEDURE PackAllBases; + BEGIN + ClrScr; + TempPause := FALSE; + DoShowPackMessageAreas; + SysOpLog('Message areas packed'); + WFCDraw; + END; + + PROCEDURE ChkEvents; + VAR + EventNum: Byte; + RCode: Integer; + BEGIN + IF (CheckEvents(0) <> 0) THEN + FOR EventNum := 1 TO NumEvents DO + BEGIN + IF (CheckPreEventTime(EventNum,0)) THEN + IF (NOT PhoneOffHook) THEN + BEGIN + TakeOffHook(FALSE); + WFCMessage := 'Modem off hook in preparation for event at '+ + Copy(CTim(MemEventArray[EventNum]^.EventStartTime),4,5)+':00'; + END; + + IF (CheckEventTime(EventNum,0)) THEN + WITH MemEventArray[EventNum]^ DO + BEGIN + Assign(EventFile,General.DataPath+'EVENTS.DAT'); + InitModem; + IF (EventIsOffHook IN EFlags) THEN + TakeOffHook(TRUE); + ClrScr; + Write(Copy(CTim(EventStartTime),4,5)+':00 - Event: '); + WriteLn('"'+EventDescription+'"'); + SL1(''); + SL1('Executing event: '+IntToStr(EventNum)+' '+EventDescription+' on '+DateStr+' '+TimeStr+ + ' from node '+IntToStr(ThisNode)); + IF (EventIsShell IN EFlags) THEN + BEGIN + CursorOn(TRUE); + EventLastDate := Date2PD(DateStr); + Reset(EventFile); + Seek(EventFile,(EventNum - 1)); + Write(EventFile,MemEventArray[EventNum]^); + Close(EventFile); + ShellDOS(FALSE,EventShellPath+'.BAT',RCode); + CursorOn(FALSE); + SL1('Returned from '+EventDescription+' on '+DateStr+' '+TimeStr); + DoPhoneHangup(TRUE); + InitModem; + WFCDraw; + END + ELSE IF (EventIsErrorLevel IN EFlags) THEN + BEGIN + CursorOn(TRUE); + DoneDay := TRUE; + ExitErrorLevel := EventErrorLevel; + EventLastDate := Date2PD(DateStr); + Reset(EventFile); + Seek(EventFile,(EventNum - 1)); + Write(EventFile,MemEventArray[EventNum]^); + Close(EventFile); + CursorOn(FALSE); + END + ELSE IF (EventIsSortFiles IN EFlags) THEN + BEGIN + EventLastDate := Date2PD(DateStr); + Reset(EventFile); + Seek(EventFile,(EventNum - 1)); + Write(EventFile,MemEventArray[EventNum]^); + Close(EventFile); + CursorOn(FALSE); + SortFilesOnly := TRUE; + Sort; + SortFilesOnly := FALSE; + InitModem; + WFCDraw; + END + ELSE IF (EventIsPackMsgAreas IN EFlags) THEN + BEGIN + EventLastDate := Date2PD(DateStr); + Reset(EventFile); + Seek(EventFile,(EventNum - 1)); + Write(EventFile,MemEventArray[EventNum]^); + Close(EventFile); + CursorOn(FALSE); + PackAllBases; + InitModem; + WFCDraw; + END + ELSE IF (EventIsFilesBBS IN EFlags) THEN + BEGIN + EventLastDate := Date2PD(DateStr); + Reset(EventFile); + Seek(EventFile,(EventNum - 1)); + Write(EventFile,MemEventArray[EventNum]^); + Close(EventFile); + CursorOn(FALSE); + CheckFilesBBS; + InitModem; + WFCDraw; + END; + END; + END; + LastError := IOResult; + END; + +BEGIN + IF (NOT General.LocalSec) OR (General.NetworkMode) THEN + SysOpOn := TRUE + ELSE + SysOpOn := FALSE; + LastKeyPress := GetPackDateTime; + InBox := FALSE; + BlankMenuNow := FALSE; + WantOut := TRUE; + RedrawWFC := TRUE; + + Com_Install; + + WFCMDefine; + + WFCDraw; + + DTR(TRUE); + InitModem; + + IF (NOT General.LocalSec) OR (General.NetworkMode) THEN + SysOpOn := TRUE; + IF (BeepEnd) THEN + WFCMessage := 'Modem off hook - paging SysOp'; + Randomize; + TextAttr := CurrentColor; + CursorOn(FALSE); + LastMinute := (Timer - 61); + CheckForConnection := FALSE; + + IF (AnswerBaud > 0) AND NOT (LocalIOOnly) THEN + BEGIN + C := 'A'; + InCom := Com_Carrier; + END + ELSE + BEGIN + C := #0; + CallerIDNumber := ''; + END; + + IF (WFCMessage <> '') AND (SysOpOn) AND NOT (BlankMenuNow) THEN + BEGIN + GoToXY((80 - Length(WFCMessage)) DIV 2,17); + TextAttr := 31; + Write(' '); + Write(WFCMessage); + Write(' '); + END; + + TextAttr := 3; + + IF (BeepEnd) THEN + BeepHim; + + IF (DoneAfterNext) THEN + BEGIN + TakeOffHook(TRUE); + ExitErrorLevel := ExitNormal; + HangUp := TRUE; + DoneDay := TRUE; + ClrScr; + END; + + s := ''; + + REPEAT + InCom := FALSE; + OutCom := FALSE; + FastLogon := FALSE; + ActualSpeed := 0; + HangUp := FALSE; + HungUp := FALSE; + InResponseTo := ''; + LastAuthor := 0; + CFO := FALSE; + ComPortSpeed := 0; + FreeTime := 0; + ExtraTime := 0; + ChopTime := 0; + CreditTime := 0; + LIL := 0; + + DailyMaint; + +{$IFDEF MSDOS} + ASM + Int 28h + END; +{$ENDIF} +{$IFDEF WIN32} + Sleep(1); +{$ENDIF} + + IF (AnswerBaud = 0) THEN + BEGIN + IF ((Timer - LastMinute) > 60) OR ((Timer - LastMinute) < 0) THEN + BEGIN + LastMinute := Timer; + IF (SysOpOn) AND NOT (BlankMenuNow) THEN + BEGIN + TextAttr := 31; + GoToXY(4,1); + Write(PadRightStr(TimeStr,8)); + GoToXY(68,1); + Write(DateStr); + TextAttr := 15; + END; + IF ((Timer - LastInit) > NoCallInitTime) THEN + BEGIN + LastInit := Timer; + IF (NOT PhoneOffHook) AND (AnswerBaud = 0) THEN + BEGIN + Com_Deinstall; + Com_Install; + InitModem; + END; + IF (General.MultiNode) THEN + BEGIN + LoadURec(ThisUser,1); + SaveGeneral(TRUE); + END; + END; + IF (SysOpOn) AND (General.LocalSec) AND (NOT General.NetworkMode) THEN + SysOpOn := FALSE; + IF ((NOT BlankMenuNow) AND (General.WFCBlankTime > 0)) THEN + IF ((GetPackDateTime - LastKeyPress) DIV 60 >= General.WFCBlankTime) THEN + BEGIN + BlankMenuNow := TRUE; + ClrScr; + END; + IF (NumEvents > 0) THEN + ChkEvents; + END; + C := Char(InKey); + END; + + IF (InBox) AND (C > #0) THEN + BEGIN + IF (C IN [#9,#27]) THEN + BEGIN + InBox := FALSE; + Window(1,1,MaxDisplayCols,MaxDisplayRows); + GoToXY(32,17); + ClrEOL; + END + ELSE + BEGIN + Com_send(C); + WriteWFC(C); + END; + C := #0; + END; + + IF (C > #0) THEN + BEGIN + TempPause := (Pause IN ThisUser.Flags); + RedrawWFC := TRUE; + IF (BlankMenuNow) THEN + BEGIN + BlankMenuNow := FALSE; + WFCDraw; + LastKeyPress := GetPackDateTime; + END; + + C := UpCase(C); + CursorOn(TRUE); + IF (NOT SysOpOn) THEN + CASE C OF + 'Q' : BEGIN + ExitErrorLevel := 255; + HangUp := TRUE; + DoneDay := TRUE; + END; + ' ' : BEGIN + SysOpOn := CPW; + IF (SysOpOn) THEN + WantOut := TRUE; + C := #1; + END; + ELSE + RedrawWFC := FALSE; + END + ELSE + BEGIN + TextAttr := 7; + CurrentColor := 7; + IF (General.NetworkMode) AND (Answerbaud = 0) AND (Pos(C,'HIABCDEFJTV$PLNMOS!RUWXZ#') > 0) THEN + C := #0; + CASE C OF + #9 : BEGIN + InBox := TRUE; + TextAttr := 31; + GoToXY(32,17); + Write('Talking to modem ...'); + RedrawWFC := FALSE; + END; + + 'A' : IF (NOT LocalIOOnly) THEN + CheckForConnection := TRUE + ELSE + RedrawWFC := FALSE; + 'B' : IF (CPW) THEN + MessageAreaEditor; + 'C' : TodaysCallers(0,''); + 'D' : SysOpShell; + 'E' : IF (CPW) THEN + EventEditor; + 'F' : IF (CPW) THEN + FileAreaEditor; + 'H' : BEGIN + DoPhoneHangup(TRUE); + RedrawWFC := FALSE; + END; + 'I' : BEGIN + InitModem; + RedrawWFC := FALSE; + END; + 'L' : BEGIN + ClrScr; + ShowLogs; + NL; + PauseScr(FALSE); + END; + 'M' : IF (CPW) THEN + BEGIN + ClrScr; + ReadAllMessages(''); + END; + 'N' : BEGIN + ClrScr; + lListNodes; + PauseScr(FALSE); + END; + 'O' : BEGIN + TakeOffHook(TRUE); + RedrawWFC := FALSE; + END; + 'P' : BEGIN + ClrScr; + IF (PYNQ('Pack the message areas? ',0,FALSE)) THEN + DoShowPackMessageAreas; + END; + 'Q' : BEGIN + ExitErrorLevel := 255; + HangUp := TRUE; + DoneDay := TRUE; + RedrawWFC := FALSE; + END; + 'R' : IF (CPW) THEN + BEGIN + ClrScr; + Print('^5User''s private messages to read (1-'+IntToStr(MaxUsers - 1)+')?^1'); + NL; + Print('Enter User Number, Name, or Partial Search String.'); + Prt(': '); + lFindUserWS(UNum); + IF (UNum < 1) THEN + BEGIN + NL; + PauseScr(FALSE); + END + ELSE + BEGIN + ClrScr; + LoadURec(ThisUser,UNum); + UserNum := UNum; + ReadMail; + SaveURec(ThisUser,UNum); + LoadURec(ThisUser,1); + UserNum := 1; + END; + END; + 'S' : IF (CPW) THEN + SystemConfigurationEditor; + 'U' : IF (CPW) THEN + BEGIN + ClrScr; + UserEditor(UserNum); + END; + 'V' : IF (CPW) THEN + VotingEditor; + 'W' : IF (CPW) THEN + BEGIN + ClrScr; + Print('^5User to send private message from (1-'+IntToStr(MaxUsers - 1)+')?^1'); + NL; + Print('Enter User Number, Name, or Partial Search String.'); + Prt(': '); + lFindUserWS(UNum); + IF (UNum < 1) THEN + BEGIN + NL; + PauseScr(FALSE); + END + ELSE + BEGIN + LoadURec(ThisUser,UNum); + UserNum := UNum; + NL; + SMail(PYNQ('Send mass mail? ',0,FALSE)); + LoadURec(ThisUser,1); + UserNum := 1; + END; + END; + 'X' : IF (CPW) THEN + ProtocolEditor; + 'Z' : IF (CPW) THEN + HistoryEditor; + + '$' : IF (CPW) THEN + ConferenceEditor; + '!' : BEGIN + ClrScr; + ValidateFiles; + END; + '#' : IF (CPW) THEN + MenuEditor; + ' ' : BEGIN + IF (General.OffHookLocalLogon) THEN + TakeOffHook(TRUE); + GoToXY(32,17); + TextAttr := 31; + Write('Log on? (Y/N'); + IF (NOT General.LocalSec) THEN + Write('/Fast): ') + ELSE + Write('): '); + rl2 := Timer; + WHILE (NOT KeyPressed) AND (ABS(Timer - rl2) < 10) DO; + IF (KeyPressed) THEN + C := UpCase(ReadKey) + ELSE + C := 'N'; + WriteLn(C); + CASE C OF + 'F' : IF (NOT General.LocalSec) THEN + BEGIN + FastLogon := TRUE; + C := ' '; + END; + 'Y' : C := ' '; + ELSE + BEGIN + IF (SysOpOn) AND (NOT BlankMenuNow) THEN + BEGIN + GoToXY(1,17); + ClrEOL; + END; + IF (General.OffHookLocalLogon) THEN + InitModem; + RedrawWFC := FALSE; + END; + END; + END; + ELSE + RedrawWFC := FALSE; + END; + LastKeyPress := GetPackDateTime; + END; + IF (RedrawWFC) THEN + BEGIN + IF NOT (C IN ['A','I','H',' ']) THEN + BEGIN + CurrentColor := 7; + TextAttr := CurrentColor; + WFCDraw; + InitModem; + END; + END; + END; + + + IF (NOT Com_IsRecv_Empty) THEN + BEGIN + c2 := CInKey; + IF (c2 > #0) THEN + BEGIN + WriteWFC(c2); + IF (Length(s) >= 160) THEN + Delete(s,1,120); + IF (c2 <> ^M) THEN + s := s + c2 + ELSE + BEGIN + IF (Pos(Liner.CallerID,s) > 0) THEN + BEGIN + CallerIDNumber := Copy(s,Pos(Liner.CallerID,s) + Length(Liner.CallerID),40); + s := ''; + END; + IF (Pos(Liner.Ring, s) > 0) THEN + BEGIN + s := ''; + IF (RingNumber > 0) AND (ABS(Timer - LastRing) > 10) THEN + BEGIN + RingNumber := 0; + CallerIDNumber := ''; + MultiRinging := FALSE; + END; + IF (ABS(Timer - LastRing) < 4) AND (NOT MultiRinging) THEN + MultiRinging := TRUE + ELSE + Inc(RingNumber); + LastRing := Timer; + IF (RingNumber >= Liner.AnswerOnRing) AND (NOT Liner.MultiRing OR MultiRinging) THEN + CheckForConnection := TRUE; + s := ''; + END; + END; + END; + END; + IF (C > #0) OR (CheckForConnection) THEN + BEGIN + IF (NOT General.LocalSec) OR (General.NetworkMode) THEN + SysOpOn := TRUE; + IF (BlankMenuNow) THEN + BEGIN + BlankMenuNow := FALSE; + WFCDraw; + END; + IF (NOT PhoneOffHook) AND (NOT LocalIOOnly) AND (CheckForConnection) THEN + BEGIN + GetConnection; + CheckForConnection := FALSE; + IF (NOT InCom) THEN + BEGIN + WFCDraw; + InitModem; + IF (QuitAfterDone) THEN + BEGIN + ExitErrorLevel := ExitNormal; + HangUp := TRUE; + DoneDay := TRUE; + END; + END; + END; + END; + CursorOn(FALSE); + UNTIL ((InCom) OR (C = ' ') OR (DoneDay)); + + UploadKBytesToday := 0; + DownloadKBytesToday := 0; + UploadsToday := 0; + PrivatePostsToday := 0; + PublicPostsToday := 0; + FeedbackPostsToday := 0; + ChatAttempts := 0; + ShutUpChatCall := FALSE; + ChatChannel := 0; + ContList := FALSE; + BadDLPath := FALSE; + UserNum := -1; + TempSysOp := FALSE; + + Reset(SchemeFile); + Read(SchemeFile,Scheme); + Close(SchemeFile); + + CurrentColor := 7; + TextAttr := CurrentColor; + IF (InCom) THEN + BEGIN + Com_Flush_Recv; + DTR(TRUE); + OutCom := TRUE; + Com_Set_Speed(ComPortSpeed); + END + ELSE + BEGIN + DTR(FALSE); + OutCom := FALSE; + END; + IF (ActualSpeed = 0) THEN + Rate := (Liner.InitBaud DIV 10) + ELSE + Rate := (ActualSpeed DIV 10); + TimeOn := GetPackDateTime; + ClrScr; + Com_Flush_Recv; + BeepEnd := FALSE; + InWFCMenu := FALSE; + + Kill(General.TempPath+'MSG'+IntToStr(ThisNode)+'.TMP'); + NodeChatLastRec := 0; + + IF (ComPortSpeed = 0) AND (NOT WantOut) THEN + WantOut := TRUE; + + IF (WantOut) THEN + CursorOn(TRUE); + + SaveGeneral(TRUE); + + LastError := IOResult; +END; + +END. \ No newline at end of file diff --git a/SOURCE/WIN32/defines.inc b/SOURCE/WIN32/defines.inc new file mode 100644 index 0000000..397b28e --- /dev/null +++ b/SOURCE/WIN32/defines.inc @@ -0,0 +1,7 @@ +{$IFDEF VPASCAL} + {&AlignRec-} + {&Delphi-} + {&Use32+} + {$H-} + {$V-} +{$ENDIF} \ No newline at end of file diff --git a/SOURCE/WIN32/overlay.pas b/SOURCE/WIN32/overlay.pas new file mode 100644 index 0000000..eac3c90 --- /dev/null +++ b/SOURCE/WIN32/overlay.pas @@ -0,0 +1,9 @@ +unit overlay; + +// Dummy unit for Win32, so I don't have to IFDEF the USES OVERLAY out of dozens of files! + +interface + +implementation + +end. \ No newline at end of file diff --git a/SOURCE/crc32.obj b/SOURCE/crc32.obj new file mode 100644 index 0000000000000000000000000000000000000000..e821fa58be391f36646ee5016e5f7e2a053136a8 GIT binary patch literal 1259 zcmVV>I zGcGcjh!Frl>8!b36A5E-V>2=?K~qh%hywsX=}eXa003x+0{}pwl$Hhn1Vc|mMMang z04O*F0s#T}mIeR>L_t(RMwkZxNB{r>0Ra?{5&!@J3sq1=K~zOUQbRK`00aO|hy(yY zq5+Yha5bf4>7$ioo-&Br4y3r;c^>K2 z;E37Mmn%%R3B7!=eg`eM=aC)1kYo_I9r7TsYDjUp^WH(egniW78tdfUZBez<^v8wM zgI1Vq6TqlzWP15x{p`tQiceet6xnPBV`DuJ`t=P6jmRKwJ6;fJOyoge)pBuXqS537 zJV(?7OZ|ln(rdK}rTVC~HEfu&Le|N<+d%oetmAChGId=SgRdj z!96Wzwva*Gb_Q|V0lXm6m?{v}?}>%6aUZp|2BqY`pEK0B=%UF7cr^I{500n_mKc~0 z;kylLe=R+22$yVRkpWy|=JZi(Yhqz+9M~{rg-!rs^6ixdY*>3^~Tw- zWl-t266(0Vi+qT={NEkjVo5F974v-4jAcyJ`&ePJP0mrZI&=WMqv9~T)Ip`+O4pUx zJ#EC%r2F*N(`xByL;TrpG)9PLtyr}-8^vxP^v)!ClC+| zzJ?$S$tAUDSF?q0APLlFxu4`=&JOwBUYN<*DI%EAu(YVx#}_@bS%D3-E<0Skx2aTawofRhA1cMgba}o<<xE|rauZho1%gVyl@xlo;;t*PdpH}m44aP9k`2Dq z<+tzLd?DZ43)IrnhC<@h@%XddXl{erAI%oNfm>sl}eV-ha=sN9q5yFdXu|y^6xR$}p3&Q>LS|Bn39m zx|0Ui%_&#jRKI80BT%4R00H0wE_!COxJqHf0vl*ulq+v4H@*wBp^gm08{Y+5jqd_2 zRg3H%#dZk9MhuL?i%td$$#ftx|BBeGGT4g5isFjaGWOBq(c><}p8xot&2BTyE<24ZTVEQN79dalPr_{dzONy`HuQV9Z#rMj%x$Q_z34XMXOJYT=V%^Pl9b z>IJ2?o7vOn8iaSwH7M`cGkxnBQ{%!{Jp{^jJ)KDv)8c+1S1z6bf+xS4?7=Yi- zZ~7g4*x$)d_`A8QdJhKMuV}^j0LA`^bmnT&KverNbdEsQwMtmwFo4)Jh5;(h+E#0$ zRx!$MWc4+>{KXfAn0J1^9W0?9(SgyRPT|1$mu)N9xQ literal 0 HcmV?d00001 diff --git a/SOURCE/spawntp.obj b/SOURCE/spawntp.obj new file mode 100644 index 0000000000000000000000000000000000000000..eb36f7b2dd968f7d2afe2ade35269676fcdeebb6 GIT binary patch literal 6308 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 literal 0 HcmV?d00001 diff --git a/VPC.CFG b/VPC.CFG new file mode 100644 index 0000000..a759605 --- /dev/null +++ b/VPC.CFG @@ -0,0 +1,25 @@ +/OZ:\PROGRA~1\RG119SRC\EXE\VP +/I.\ELECOM;.\WIN32;Z:\VP21\SOURCE\RTL;Z:\VP21\SOURCE\TV +/U.\ELECOM;.\WIN32;Z:\VP21\UNITS.W32;Z:\VP21\SOURCE\RTL;Z:\VP21\SOURCE\W32;Z:\VP21\SOURCE\TV;Z:\VP21\EXAMPLES\W32\OPENGL\SHARED +/L.\ELECOM;.\WIN32;Z:\VP21\LIB.W32;Z:\VP21\UNITS.W32 +/R.\ELECOM;.\WIN32;Z:\VP21\RES.W32 +/$A+ +/$B- +/$D+ +/$E+ +/$F+ +/$G+ +/$I- +/$L+ +/$N- +/$O+ +/$P- +/$Q- +/$R- +/$S- +/$T- +/$V- +/$X+ +/$Y+ +/B +/GD

+ zb~bc_R^1lSNKee6&wyF)CPP3t;hM#3$6-P;TDNB4gp3r*ib$0UJ?cCmoq7FFs8N5& zSNYj|oGJ18?^B+)xEt;^A6+J6q7$zluIy>;LyXK)A6)+TnE`TFBMWQKfvfDpjWm5@ z#=zm~=>7o}%7ezHWS_04wU+{Jo*+_y&r5>pVDpls4;|gTc*nfr)AIULycjVpPau=$ z{PUOQZun}qM2d^-s2~@uY4oBtZ7kLEY$=ReM>EP*G*0BD5rmugLT)E(AgrE=J{lws zR`-vnm=k!!`uG0EF4g)dNEs%!F;W47vBi~}aqRY|%D^TbBQRA#4C4j)&UZK5`0a-K*MO~@?P za0iQZ1z4;ACX13K7y*0-6#|U_i5Zg$(GWjI{L&UNKewoQAWcE2HH&>5Vg=DP9|ZsY zo^cid$2)pEx~I{i{xm|SI4yYZ=q{#IyGW(aj4g#-_e62f^@K>P5xW^_sck>>wvzfi zQY2gKWt*hDvFCcPS3-sEDesvJ&^F{}Lyq+XB%9DZJc3DxT@Ctd`q18ya#*PJD~n4-Z?Sg40=dpNpiyX#5)6} zPwk|?*D&?Ndy1cMxm2a}Lb&rfWrOl&<=x8rl{=LOlvd@xpiTR)@@FM!)528aC8vzn zs_s|qQ@yTwNA(|7q&iNW2)B$@Sc?Q{QZ*wr<22JWOEjxA>oxakwrl>bIih(_^Ofeb zMxhPR4$)@f4nVnfv38TTLbplx7u_!13%Xx*N-saJV6OzPbgv?>NnZDO9rk+1>q9St zevy7PtU~_o`;)K6FUHU4m+DvGSL8RzZ?4}eztw)tes}xb&)g{f)33+x4ZnB&j>3)N zDOhrl3&kA&3jeG8m-^r4zsbMT|2h8`{onNO_5TSr9ccl10pkNo0wxD63b-*~Q^3Qp z?AQwjit50~z~OffEd6K5(q;GGXh2f2@nZM%m5-7q9`&Lwc1uoZAGiqI+bcwM9oD+uugTv zI#exM^cw42M8xF#t+mfS_ndQYu>HU9`#s$zLT;PFWA{jT=(#O0lG_OuZ*H zl=@uiUsK;t`!?;zv|b1_II7RxeL{T>^?9k!*L~dSV5ZWu)5oNjrO!`anZ73dlJv{c zZ%qGP`rYXr=`W?fmJXd@UBEe|v4%3YyQkoyaxL*<^zmyhM}#gPTku&<@(M*-?T;@% zGA{vfqx7y6d`vuMGrji75T{9p7weh>q_+?eRT?FU&Zov)SnHGIz&`axbM?xvK6@aGm3G`QONqabK}T}j9> z=-OShnSr(A$T-o&5t9TAE%y;EU{CC!9q~T9WZ(8G{&l<~!2{h1F=&WlUvHAP?(C+{ zvKTnVc)@AF37{Z;0}RJcli9oNa7mZ*|NPvLG)A3lxm9=o#Kr6(UKQPYP!F9OQt(gC zN3>!;Am1Ud4c>$3v8dlq*4N!$G-Fg%|)aj-pr=&|^dG0vP zlPT*0phiMORJ!;qX=Svsz7{M1c!zVa?i9--QHHA~80JvG3-BU2Z1OvSEqV%y=1tN& zrg;51QguBc33Q}Xg&QvjOpvE&9cuz#@WHOUDCN>vc2pCTV!C#zT_-Q~#O*TQ32PC= z*?OzQQYHr%IgrNT_^`8hfSji;o+m&ku7PizGGEO@9#l+vdvzPMsk!ou|92$l%b2L|C>(aG%# z2Z(DHEH9tGS=BxLmDxm}$v3aKtaw`C)Z#2$UH6@Z;DOLVBRVzT5aG^6MkyQQD88h= zs-?-4nV8H04j|x?GeoVvh8j*XIT0yhYU?X0SQv#Z6SaNwriq&uYAsD^O*VlL*sB{+ zAN!&Kf(iaeFPTlDI!1>>tK zEC8t4!MUogX|BIMg3tA@h&*%C*URVVrf-p;_Ku6FD|bhpx#@@Gv##nTgnCedlwQ9m zpB3%mbV7Pp7K)v_V>}hAVFe9acOka!GP!l{Jh8oGYkNl>RmhZg;QFJv@6JVAId0|1 zJky!C?();b1mdGi?DzH|{_mjpNB1{Y*`Zj4YFVf%vEM_9{mCC`aDaXez?Q_GUFvOl zfXfHsR9IP!>-I(iAP|_}vf?6~&W7?q0rIBBNdT(o^#Re*r*!@8x$Mvx5#Ks5ap>?s zV#cV%!J<`h(r9{spNVHFXMv%3$UHE_>iHvpiJ3XM+4$dt(V#pDlt)X-v1lZo6|22K z;t-s4oFgq_Y7mG}cF7|tehRyPmBCGzPnWnNIp=&PB}|P>HN)eJ)hT8KUrAspPGC{l zJxvnxO&4Be{QBZb`9Z!j_Y6q_2NU_85dp)&RDk10T7LI<0?q2-1oG=npdQbkRnk*) zRg|&w1Ncl#s^VUlZ0<(cTtgY*Jz^*$b5EyF**V1lz$T!Tx-#v)!zRU#OK^MZaZorE zc|3~8*X5&j=U~?PLkSU%&)-HK$q?A4hK{3sQr9T_azni&STx!<@<@#ilaIPasoppV z5!_&5Ymkw;nzU&+VVOTj8*mnp6dkw;nz8S+tC3hb~HKECsy~`lhlW3{BijCW>=gMg5yzn76S_rDOY|O3-raIhQy|a5}SGdpfd$K4H8<>WbVk+;enY`S;3kW7bA(A_&5wKVtahGEe1) z;LmTCpCI}3s}-OU<=yfVM1NtPNZNww;`NF;r5e?Nb4Fl6O>=Fvf2QuBnkAm7S?6rg zptnqE3c3K_9Hk|2WKEuOZis$*=ZSXs_k7~lngXO?7?14?-%HQO9KyiBl|EXpmZam( zW(#ln9?!htQb{meqa+Y6X&px)%D1-?r}CV%70&I>Z<{fcpU#n2T$z6-GA~k59 zC?mW-8_I4+nO(gw7I;*)B1TzASEf57PoPRa^}3V~uOX4gR{_nFkGwG|f-vvK(!>x%12#2^7pw|Ld0QtS>%zXYo~mS-o>f2H%YMI?rx1dz6s_Po9+!Tsa+NdHdb-nN5>AS_P5tE=VjmSbLlk{xr^SCJsv6sz@bB-%EYT5O583E5d7M~!c;a#vyz(`VeFJroh+395^$H4$7EsT zUx3l)o==R(;b7=mkAOpm-kM7E6R*LUk=UM-8<+v^I(NbZY{WUa`8he2fy8TLinLto zIw>swG?7@+GLJ0rx`jf~+obN&aZ{8KyXqcILaCTX-eKdgM+;p9KWfBaes+~8^|3{( zHC@w{I&N&wLN8&W&>zBSxkve+w1yN}C>2bfTk}P0VgauSQc<;lUTCv&)Fs z&Tc{3m4-6HJ8mc=u6=x8eO)TMOjj1Q?H!b0AzwZpd8F;@ZTYC%5r_%>OhVdQ$?y0F z`N+z!s8+oFRF;**#H7e0RSw8UT`RQj1SO=s^&32nmXAW^)_MqKV`Q1K(Gbg8FUz9X z)9D4JQc~&jp}N6rQt@>gOl0>c`H9_QjKZa+6cq5WT*TK~^H;8^hLAdG65T`TJimma zSEykCJ9)v@bAX~OXO}Os(cSkfx`N9*;Tc9=UjyUuCt$@N-02@K&hX;TU^o7p6^B1V z2I5bq4S$ASi9f?UBq=#eezAs|xF=10u(U+if{g;zIPZj^_v%FM+Bl8S<5ucjp~lrvzVfnGry3m1S3n>m0|?buegL zY6;cV!c+WXyei5?#7_Xzb>QxcDW5HY+dI;r!Bz9eQIRe;9DHHPx<05jFYsB>F6?ce zpzckSaGeGi_G_=h^z7$^Q7ti;m+CHa>3g>oCb}5FZd|cY7dWfB#kBQp6Q`jsafvMS zn~{b75+lZrZTnBtu<_59WjnTgbQ%f9@t4td;RpL*r~?jtPV|+WttyUgP6Ub)8kQ&! z>6UvLS<|?gx~H8>PE0Qlw0Y^f4mq>b8kC2rBrDRH%=9L7()3>Ew_ zvPyLh*eMZO6T7axvdaLcdF;F{k_AczwWW{MW$Iz~Agf^Ephs7QjWrDvRGh+p>0R^U zBp)6ZG5@7+B;hgfjj(H8ig3+KVb{D=c0Ejm>tSlQaLr2-u6eYCLl0!&^Wo_JaLps{ z_0Tg^!bcOWRMj;v6@G{*s%u_a#5GU*nFoY_Ub@ylPY+LJCq24Sl|vMsb;<0Tr?nAi zg11|5cF5!VPjZvO#?b^sxZp|gT$X|?{O%Z$bvm*xKuh;L^>B>rE zKePt;p*3p!&>D==Bm1G@qO*a%;-EOZxZH_|kXa5s=Jv*OKpF;OZn(X`&xjPlXaYKhBn2khs-(V*{;^p*Ry{$r+<>Oeo zp??_)mk_4)Ecpcr%mq}~*HFl|-FdMJ=jaOAiz6jegF+ajf|6=M24}3s=u%k0QgdyR zh~kV@Mq|HS779u{_|TnHNN+^LhDm2ESi9_myH!IM`E${Jqq0CS#if0f0t$!jl4J!Y zf<5WokaTWVEvO-6$1hI7z7yuvSPDd1R8|`hFxAXuV|VyFOTnm?eoRdCPk2)aVvoHO ze$xUMte)U+ycd4d0*9-f;A8(8zKPtcdV(MRIJ|+Jsd|DR35OSx>r_whOFs{fBS)#8 z;5)wwr>Y)NTPK=Z?U~(LkEnW@=qKbv>pY^~S3RP3*@+9f3{|yWMQ5mb2YE#0(RYd_ zo1K|Q>}He3CF%?{VFo>;Wr|`o`K0U@C<&J+9h;`m-|WV2z-(F!pC|!oc40%v-0>gw zUgHxrgQn-NvK!1qw0H2w_-|dI-Y04W)$$KfH?2zjBpZC9stDRQg3X`xQ2ETljQ5<+H+AB)S0-Vt`ii8oJYm~O8M#|``@sHA?{6}KOBzbU6(jQzt<>0y;Vg{Uv zgbNj%4%<6krNe32*>YEALBnZP1dR>?)<~dE(7<9mSB80JN#j)u6@jq?(|*_>X^34+ z>_!iL1u-o&Rpb6Z=o?r_t<`qanE@+JA~rd-k6yLw6{9Z0L_#DiEhs z|EUqcxP>sDlNf?)CmALpDQIN`oooRqhzEaA2rEMBVXEP)t%VWq-y2ixB?^Y;vW0MuBW-#4h~QKuPLhsb+6%sm5d2 zC}OD~geMukT-A}x_~nug;4>-Te5RLgA6eQ=k)^0o?)0 zhqonB5{P7Sd}JYvglnyTSrP_??@oN2H+;)9X zOUbLJediQAv2Z0tE+UN(Ov1^ISVr3r$r1?A#33uQC_INsOnBkOpcxb=h(x6N+9ow; z$WN-H%4PVma;xgtNTRk&IVX%u@n!lVcjfAq;!767G9%QHL-8+|=ubQGku;=|-u zk_OaBph<2CI(}#?ib-#Ev4wXDv1qH1zG*M@V4tkbn<||kM0g*8j!RH`2b~X+u;!RT zIZ;j(=M?JV!GmUwL7Vf@X=tW?G_!K(9F*Yc3#{Nj6J_5hIc(mDXeU=c8d6$j#b7*3~y{-wm=AD~~yPB*uR^+@_J zq22l5v=taa!&8Q>ZidpFQm$=M_l2rxx?Tws^&CLcXt?uo1^HOaAt>0QV>-nay=rtC zF7-5XdHR{tB|<-fW}-D$A1LFh#JG@kNo?UC=rmXKuKMgmBil9mI8a!7HCWMJ(JMq& zypLibb<+U1#op{4Ca*?+@{t#CSwToxt$n z!vio?(0<2F(4wqD5Z5XKvIB_xSS?mkSwS3$hzl+%A<@Km71KdM7ekkgRo1RhfQdkj z7t2COqnaR#+o_m0LUC{N1nU1>qO$UVU%0yV$@Z&j_u$!^%p>il+*gHKwu{!K56b2v zrgNS`sUxUgctQM23}jLGOLp3*M5% zods>wMOs;+N8e;8`6ic7_K!i0|Ju(O0kWd~jI}E%QE@8Pl_{RZx-!MRSX-7Xj~U(C zWY1$0Ey@hZ%w(ANyx`ovEwTHs;{~Vb2+n^jM(AVVjGPK*WG@a}9P4l%9{r<|&HCYS z>Y_{q2&_Dv$nVQi!3`*0$k6NhThh0JhIzAR7l<<-gFTX(K~y{nMlLqi?njck(aO(` zhfkT{qMRy9Ni$rofd2k9VuZj$IR@y06X8P?y*p0S0-e8|3_mCwfbWF^@O#w5k7W-P z8Jbnf{l;rg2Px!|uT*HF1hvCe9?x^-vrfom)M^P*rf8#l)}h8>wnEoQPm8->l3JJ!pJ{*LCg0Yr6dfa7}NoH8&0vD_b5cd){74VX@A6ZHr^G`<$oNBccSb z^q)LGG2$6M&*%>ZU&ZqQ(-hMz(?zC@$b|D7B)NOW^s?!FI4hrPo@JhEUSVEuZZltH zzSexd`9ZiVzh?fs`51!#_O|r1oMj1G3M~sQ>yY;D1_b=Q&2o?BFP4{(^6op!U~86j zighls=Ujl?IjvTgt(PsuHq9Z zz0~iue#iQK-0wucANqOv$M;X_AM8KA|Fr(I`d9XE=-<-+(*D==|84*K`#;$KNdKe# z-|7Ep|E~V-0a*hk47h&49|s&7@ZvyQz#SMA7#CO?SR2?B*dAyP>=LpKe*YUuSt z9~^pQ=zBvGhvfvv2G<4~f_Db*2|gQqFBlx2HGIzS1;eX`*9^aE_%DX<9{$kqr-wf~ z{Jr6y5C3Mk`|Lhv4>&vL>~qg9K6}iFbt4)_>>P31h(jZmj9fYLw&2{BvyNwVW|^}c*-6=FWtU`EWjAMU%zh=?mE+GD zl5ztRotQf-_k!G-+`8ONxox@2N8LE;=24H0>KOIrsLw|wk4_(*GkW^y zoujWC{hQH;M!!DVJ7(ONk}*ri)Qq`$%uQqN81siQhsOM6%$s9A9^)Q6V(i?pm19?p zb?4>fmEMK}_!}qOJmKyM_fL3w!fO-$HsSLLT@$SNee#3(S@~7@*W}-t z|3LoZ`3Ld?LyBfqjFp#IvneWltkC{25X_!eT#jtjE7u~>KASv}u1tjXUtC>_fF9K{ zYKInz(Ehlxf|nviVq^eY?kIH;+J9PoebtJMOg{*my3CW&zoe~;fg(8gm^TEj6>4ADGEpiD3$PHmdTM(}}oF)Ot?tjku2Jaz$=N#n`OkB@6H)NXAIuodaZ=UXdG_@c*8|RHmSNDgQl@bD2mn z_p?^MK}gPU$)(&$c!?NIF(O@VsKM__F_z_;fe>#elO7sgAp%}j(t-dTT8b2wR${8J zS$(C9ED$Mj0bQQr&5Fnc8jtS?TQAtnNRW3DM%heBu)m=}GS)&U70HJ+j65e;4oz0U zPsyw@isvXZAm^*#Z)1TssoJvg)iLw1fmvp&PTQ$1@nN4>4=3H1b;rHosEyfDki-d zu+RD#Y|~{_{ED1HpYOKxvktOmTJw+alAGAJUeaiZZ z^#kiat)E&?S$)hCX4=NvCfcUh=Gm6pDs2t67TXTn&u#bE4%m*`J_Bc%hV;i%k@~pa zezX04`$7Ag_Rs7VM_)dJngJ>-r{1(Yi=|9?? z5q%ox&HQFqh6GAW$_fK(Yg?)iB7zJw$Qq<#>{*;hE)YPR=OUIJ5tyK<89{d`x^6Q? zo&pxg;9wGD<|6~&$SLP3BxFO945C4+WG-&0C&yGK!rcKGoM3`XeWbTd++AI75HngO z(+uBzZjI4IZz!W8C9wx6TSLj%8<@4IWb|l)49>)<)vGF7YMa?xfDKc`kt$~o=OU(B z3lN>fUz$CP2xp_jsBFeWui(Trvae$;i074W&NgQO75NkwE-Wf1*BgY~5^ql-N5syU z$`2_&;B%16aXrTHZ^N;g5II(7P;?J}AKfCtbcw}+1iDBU;pGXWlE7dqhC-SEaXiJy z41`3tG5sBqqx>D_&YQnrvP!BBr%Ro}FUaBIoLfptt+5EQkj;OQKe!zEOu$^Mt85PD zb1+9N6h147g674^Q(c_N5fo^y_$5}uaVYYxe&R@_2rAlk(9{38ZeOk&{od&{W&tJ= zo+3Asx*&!XO)s4}t2`K3Hu-#t&lXrV_k4s?%MZBbmKV*OUOH>Cr>L>AX$@OP*{0Xm zR(VS6MlNWqL_qmw_sp8w+L5r*ZniW3=TuCoh`Wi*0I&O-#j4Og4o!LMAKv z@|*HG#3r!>`VC+uLDPUpAnixZfD{D~`Al{AnztuZI;6$1xp(K-Hz!~Ina!=`GMup4DIj)VS86wFD*gBcM>!?RjdL zF-kW8FpG)-kR72$t~WHYM%T!LhDHwd)JQZy+sK=SMrw48d~ayv>7E*i251`@AejJV zx-QZ+axOtN({-q)Mxp`ShhNJ#_#rO6}-_1rWyZ(1dD!l=bapdNFJB> z*0P|dPXh6E4IM#&+`dpC^FL9J~JY`OcWFZvYY$di14Zg;S>z;ywKP}D+nbr4U9rFMM1^Xh!geLYevPyJVSGpNu5th49f@uwk`eh@VuE29$GXtdWIkT)Y`s127)MyV8`+ zicwY;qpTcdyNBQ-00XNDNc9oN{Rz*tLM%|Sxcw-5z#AvncZ$^AiVs6b5Sdm;1qp4F zR!f$Abuir93hp0eYh>A)V7SWyE+1tzvaBW;{?r0?9%UEFvWtS@qZaV ztfBd{m(l<=&C9o`syuXZ6ed1^i4R{b zwD)Z$UNC!8I0z>vD*Jb&E&7;EHf0)wu3dv@mk=TCCCEn|B6%gIOGrD%%LvFvp_13h zFzufTgky`m_*0DROnNzoX}_V=X3h=rCdnieh8r2GF3Eik*pE9vJzX( zB@z&Nic;-CL?bgNx3Z#kBCcNeb;?C`COQ=P;6|0s!Jg<`LpiF7&d?tUF>;?u=jk5k zbQZ(%wD1gMs5?)qWDfN}MlUFi`i=y}e?qKt+I{xE_JBRdo^PKF0dIkQrG1UP(Z0>T z%YLi<4*MVMkJ+C^&eAvSo%S#7Hiz30=NN#TrK21Lj&jFBM~$Nnc}urCZgAY>xXtmf zW544iHE-#6j?)gGGsW50dA2j(IoUbYxxjgmbF=eu=Pu+ez1?}Av%~o`a+kjE{K)wk zt{P4_?JkdNfGfz?42xX#uC1=^t{Yr`a6RDK=X%NYnd>Xp53WA$0q$Y$68B8^LU)t< z5_g;XD)&zJFWnE|s^LZV$L`6V8c(a|BhUAqc<))>N#5DsdEVvTN^gVrO7C^vecmJ9 zcfFn7FTHkOlCO_1%Qw+C#aHXw&aqYR_C1Qos>gkuzAt^J3Nsxut zsu7!wtwUZF8CaoQg zX>ycjO>wSJREx=G+G~M36QV9pkI+RoRO8&@2;5?X@FUY@}qem9@3? z8=#PYk_4fz8v<1|jdID%0VawiCI(C?hgjha8My_Te2G~uXs)10f{|rIQ(}A-^R$>^ zttj18$E1vCJ|=5cpb9t?hey%;H;Isi3a)~=0I#eba|r#su6>aW7b8&nxloU(w6DPv znE66{j3M+xCWp{Jj};CJV<{X`GztfbhB&7j!v8}5*@`@ z#SqbADz>K^5F2|!Y&0Nl=?U=`1L74uAs#j$ZtMy1O9NtaPl)MKEK=0@m-K`JoDB`pA8dQb1+*Z?W)3Kd&fzVYd?z&eod^qkD*c!P-e9Wv#M%Gv=cN}kJz0z zHQ1duB^a4kE%GKK^0`2s)C2OJdgMK!sHxDB{;L7|z!|Z>H(*!xv}gva+&N!d?OD+i z;%o!r$|yvk<6tNI4H8)^%2Q;q2PHreG9q_8ken`-lGDY(@N5f&Hk38Wvc_O|f<;JY zTV&amV0ef{NM~2bvMYk&UW#5C!rD|wXU(##IT#L`A)TR(OJvz4!SEYqA%?w* z&i+MqHgrnigCQ;MtAd_j8nO2GP;LfX!MqJrRmchbMZ+>ziQwAdHWEL8`8Qyy!b|8m z4JK}NC=7Rak-1Dkvj~h(xmOYV|4V{SoOpaM`qfAbD7yO=+@lvo(imkc9ASwZ^0~)Yw5bUbuOB z4>cZEYlP%ra37`&yYs?=d4x!c&^J`X12GWC70jnAvr0LV%3$YN1q-NXg)CYT?Ce#r zu*KgtX{9V$8Pp3byS^uZ<+QDjeSm$ieYAaweVToieYt(Dy}{mMzsmk|`>*W3wLf5g z5;s#vAgml`amD0_cO*IbID(Gxj){&bj(Luijx~-(#|FpMj$b?WIPP)$(Gg;C<(T7R z$9E2|Gr^he9O%q;&T(GotcI{s@7&_N)_J4zX6N0`$DIe9&p6+3e&YO>^J}LCR#AOn z7nS3h>MC`Wxhh=iT#c}dy4v+i*RNfBTzg$1*CE$mAh!J7beCFNfwO3jUx4GknqsD$Vq z47@N!en%dymQ|}@PEZeiU)v)H4}>EN?FsgWNEsrIzy&lYhJhB{DR~3+Qzt zz^m$wIBJg|B!~+>z6Aj5w~9j7&uPG{h<;;^X0ns`n)>>+f(%)-$UdorAQ0g8qXA-9 zEkvI>jI6qDB@LebBPDqT%=Y@4s_Obc zeM@sg3tw&$A@Ki%Q;IiI8bB2Ns-`uSYZZ=O?Gaf2d5~j(R|jqo|2C>DzuF@({qr}V z*G+4xYmquuSz_Gh$Xg?RA5@ywv@|1_nL6|c7J39uzldHc=B5^w9k|&QBbTG+w+1Gk z;~^!5p$+(W3qebWuzku?}rY4x~Kz?0Qy^_;;M0&IsL&K=+*NOWb{o7S0dx`S; zag!H?rOwfLVrYutiQw65DT~MoT;eK(mI@qR?ab7x2x1ydR#;zQ3UDP&%r#B4G*}8W zk@$!OuaLrZGvu}=C50SM#vHuW6*Tz@3a*l4q3~oAN-22w|40bJO`3WGJ35v?G$5ux zv}o~?^OoX5)=%Cxa<$Ui6bn`uV(~OXie;%rY%vsJ~?R!GqJFmTRF}GDR9@p62F!En;Yufy^o`R7>U> z1DOgfV(5VqhE5vD)N7$yG6NzkH^1-(En=vUpqdw6tA%RGtTvEY zr$r3yG>}=Vg=)#{HIQl5B8FZwkhxq7)soT35j?0CEn=u2G02)hRcWDGGE*ccEu^zO z)mlVx-Jv0Kr536sv&%qcYcygjZn{DbNIa$TwJNW!d5&KQucJJ5FY~I^nx;GRqY1qghP}MG{nW}a~dLlc`&@pT(F4BT4Y&EFg(p%u$aoKWLZ@(Jlb5agvzRA zS#>Zx&|GjHm0c;zt_+5~=7ObEwpEsG4TirnaaO`FMOMNvQnJtjeO;ZVb{N^Rji&e_ z2iTRXLfr!GDwvAQhWEkF5}6I}G~o^$cd@m&j>Lss3dhFY{pPk!=IIEPj&FEJ$;r;) zxPt4=kRv6hl1#UK!lg;LP)pF1eoCbx_-ux3m~~6!+}geVbocsGEKYa2v83%sN=|ko zHWoFC7y>7McYIi93Yy{HpA75tfVhLoKOIIFkb3d+F}^RGWv{W<*_-TJ?KjwOvfpOk zYk%0j-~OEaE&F@+Pwd~>PutCoUXFlch$GuE$x-B(?pWej?WlFEcU;B!|88|W;CRUK zq~it0D~_X%=>0Ii(z**&Nc5ZcUci!N<&G~!hy%0Q~ zLyo|=RKc?sJLF`$#<(Ux^jzXP-?f@^2e!Gccirl`1Gi;Qx(>RIxZZRfcXhhHbalf? zC&@j=J>5OqJG zxmG+7FL;N{0eXk!@U{xdsmU3BZvzDp>WpkB&KF3cx zAMw-9=Zs$-Wc+HI7-%d+TqhhKN}@k95fFi%w0JV!igMgm!0;jxerbuo*ANKZMI91n zD$&-HLjF6fX^pkZy%B63WvWI4fVDv}T)&s&TojGq?I@X%9*|Y}avXXU1g1-1y@TMZ zNoFkZ!n|)~BY7=s$QnZy|LnN1lq4F2V8!i%;<}#|$j!+islE}yKg1sv@W`-Gc?)s) ziT_oM<~Zmjy%e${v^!ZzrsMymv6E#}$jaGDFK|7Id#>LaaN^g)3@W}Q5sUsyTk&EHN8b@JLHEUmf+q!N?424 zr+43KqtbI}(p95-GR43mS7ODaws(vmaDyC`IH~j0<%|@`)u!)`?K*k+5l1$RIY`Y* zyG?sX4%NF-SC0rk@yktSTJAPeidN0GsIsw!gifhmgHH-nVIl$`OY!8BLYfK^!linR zkXBV!SFM06i;(rTSkMVTy~c!ER^YBQ(16rO!e2>82*17;(CDE- zsH@bWLA@ph#aqe&@G25|1MyZElbXXE ziR*POj<^RU{h8V$sMjdTszzP7wz?X(^lHCB2i1B*+FpcATVp-WlC;9eyJ z^;%&q8ECBF`qiXbRsU0Z1oc{E9-BBE3NJ>|>8XUEUc=C8)*-)vnCcakEo^l{??fR4 z^_s+)nmr4*yb+8DA*k2pSFapOdaC9P)lko})^0wQFm#LxA*k0DOyR}ISJzSt%^g>J z1ofJNMBfFip{i<3cMUH%g%H$h1{`uKt7@#=P|4q#1&26{13Xx^bQHl9--<^5OEs7_ z!KlFzVaOTPU}MJSjT=89$4_SC6=Qk9lS73fLB#O|rXr6y_#!Vq6yss`eDQk; z|3;`$1R*HHZ>ZnFJE>_P1yUgZbsLL8j9b9*x?xSt$~BWIH!4(O(BnZB zAiFPCh0rezWFL!#r6v1>f$aWR6+-Xp$==q*vc7hnBu&z9*ws{m9W*1#^u9KXGRfcd zEln?{Or}W9|ra3F?-Mwx=KHsdneh0{#p=e#lA*6E%H(CRWp0szI4yQJK~wu_}aS8OS~x z3rkD3QBSrz?<{mS!_e7Z=&5$+B>*W-kEA8~xRGcQ@O$g=L+|N{?&j$KCJ(9MovyDUpz#k9;pIK9l89#sX4f@(_4R7#fXwr9x zQ4Fm628kkgSju{>;{^96(-&m<8g*e1uQ18b@Q}gn6|x6h7iRKqNJ{4;pV=M&x2Zs( z*8m&Y&ejnxOMp(V(T&v1$wmQ>mXefIbcw-G^RJY7fb_dFq%CdH0GJXrn_Q*12Ah(}SY&b0svJPkY5`o9? z7`jVha(vK5MZLts5vcemQ$W?(CrzCNX32L3HyA6GCBDx%f4f~63aF0_%Frm&^g;gTOshf7X( z+npnFo_gC%!PSmViGBQgbN3ejY*{NQ7-h6$}&>8j|;yeE0aj!V_bNQ%uJ}z z!maP;!WYTTB$0wTojg)YOzcQ zfn_$`76+^ZiFKC=O37GQy@8b^u`V}}no{j>2X&)!9n_SAG`(m@1$~q0wiMJ%Q)+fj zhu$(4QaX_ONu579yS!1wZ&IXvXyo;s$C%Ke4W1~%UjJqH`p>)9f7ZSJQ#QxxjHZw8jOgzy z`4Rs=Eewjp(syI;y8X|?!VAeko*y0_7M@NX@ci(|u<$t)+KC??9Tv_qV`=llzG2}( zw50jrv0>pPTFU&ee^}T_OW3`uPT5HZWJB1H+-V#+LN_sNEcD?BqS{0kEnAwL`$7T#{c z;&ai+o*mY?nT&vTm3+Nx(YL?LK+Us)oi$isvM3Hk3Bk@qSWU91H;R&iokdtWOr&F2 z=Qu1G2~Ghxjf{)VQ;X73)Q^mdmbUnnrUsxWU@$KF=36o@>TeonDmT@bt}y-D^tkDD z(_5x=^BD64^K|nvbG7+O^A7Wk=G)DO%r7DM(r+w(vOHsX&honDElb$)x#dSoA8W34 zvGo_$yV$w@dF#v81lw7*plvkV>dR~uwi?@IwkvFR+8(y;w;i+{aew3vL+{$o~J#}dS3N}J)e8Nfq786cc3@uo#>t7o#tKa zZT4>TZuRc=-s-)>`)BX7-WR=ZdO!Dm<2~th`3CyVf?vZ_U#YLmSK({+ZS-yR?e^X3 zyTkWq-}CTqc-!}t?}YCMpVyB(GyWWZiGQZQ96k=~{hRz(`ET*x=KsC_5&sMRSN!kz zzw)2(|KRs>NT##na^gzk&W~FWR~y$BcU9bVaX*jSANPFR%WJ#*uVhH{w5v|2F>n_}&Q_2}2Y9)!Uqyfv`)n6IUjt zK)e!yEyZq`U){{f9`cdD0r3M$VC2G+w6N<&a_;zucIUEsP6aagGZr3wPUH3u4mo`<`r zfS^jDbX9@sk*u`Qf=Gi>jfUzV6QU-ohm=}mmLx&NN=*d>b%|nVRmc^oT?GUsiGs{D zwQWH+LIhjtAO&WzEr*cgF^ABIAnuM1A_+nfg0PDVXJrFHc(15)2=xa*H0mNU`C+Ki z4QM?8LKSI1zjDo51;nlcuvsIA2m!6GQb15~%q}V=Qywy*B7YjSEhskdQsB)(4lNr4 zP&EnT9CV({g=l)EZ@cDwL5q=5TDQKYsRnAj3<^42Eyo4r#cYa{By4(`n=9cQp>zW( z3$a?t7gKwzNKru0RLrWxY|p9VXb$T1{%1}J!XC$Tu_ zb{ut@l)PfZ7sj+~`GmN$RC(8-M9;f{LW%U&ikGA0oj~X=eE^saCNSGT;E5;#Z1qBN zMCg@R1hyIow7^nS--F+(J@_FOfyWF45{4QHs3tL?A%L+=qX;fMgf9#P@}mfN5ZD(*;69bWi?IkCF%UQw zMc|l9;Ja7^G&cP_2fnD+m?ri9p+SH}y@k|6xPzZ6R(5^~0d3Kg; zvh6!d0BcDJ(I?0$I`<_h*B0S5B;KU(2WWtlk&KfPqOZ;X8AF0j3V(A3NIFS7DIxmM z3=k8UX{3bcGc!Pr6SJ5SqHoIpd4V{`6#lXdkO#@8J|#q-lL2xwNk%FBF&QAOBp#*k z7i54`k%W}O-;V(@gT$ni5PdWTNDj$LDIxk~43HEOmr_FXofsgeiAhZf(N|)C93zf3 zB}AWw0rD)duPGt=Fbt3fNPtQS(br&r{G5cQWd0WPkj_ouY?DK@{tbW?;BS*dwD=8x zQZT#8AzJVTKn_^m%pAbP2WOBA+54J`$y4|c6rRw~!zQ~{ywJ^~RdRX}LDMj&FP3J5LN2t=$@0iop@ zfrynVAhcW~5V2APgqCXrB37z^&~lAH#7Y$qTCNd@Sg8U+Tek`kD^&n!xkdoIQU!pP zYXrb6RRCzYMgY801%Q@o1i&j*0BE_YfVS4KCP1%+&2WZVCtJ&`^Q}v)Ypk2BZPuOE zpId)r{evQSy z!JYkP&x4*9JjXpIh=F6gW!^R3E4;UOANIcF{n%@Q8#^v{q!mt?r|o-JQ~$l@R}UO& zb!1*?Z|=2IlsWfyy?P)sVDId$6nG?(%YObr7l*C3$lSFS#U!SL@(Ch2RUB^69gBCh z+7^HEv+mAeNJrHRM;;sJaN*|e&cuQVE%6Aq5-D8WEvV#|bT=b$lOyx6oo?U{`b=co zflKn1MmS3}2aq46dR@SWa88Youn<`bSAB>nNuIK}*TwT@cv{2IyAoHQjkv9ckk(k; z+|nrAM*5c95=kP#G%9tgf^QucJTtdMRUr^ii;Km zM(5f(e6l=ul;&a77|p|&@tTKmTC@ou;MWq+JdFW~2rLgYB2N=QM12~StEECM zYhZa=Dx=10sf?x`t5imh)>0WgUR!VMIKbl6e&&uvMa>sf;()nYN@x^VJDx(-Y%7do z#{$TtXb6rSD8aoV1k)O}zfkQe6x9J7f6D7&;-Prrsj36i zB8MN|_+YxBHN*jEj07R7-Ub*@(0>ZSu@VF~z|{*Iv>-}%$^_xe#!hRIT1ayAviuOuw+hI_L4azC4p54JfUf80%|RopFM8@9MTks>;_bGGSV`;-_)UD zg&2%0b2>mxnnz$J?MM=^MkZ9z3R8=)_2=23&*lvtSJpi)3c zKnul}n0X4jfFPYKF&j-qI5Wg~qKjG~LSs%~BMz8yjI0O#68PKNst2i>rVz z3UYaOrQqA58%+(cnq%`8F?O7)F^yTAO2|$xYQhI_i0O=W>st|EI_UgP51AE9ZDY;2pg{-SWQ6ub{1fzO~Qmb4CuM;TJg`cYa_`2k8@ zC08K>i!{KYY}Y6z8az#8lM0Ls%o8iKh*l<6EQRKs6DTU2H?OpKo?PT8$HzObcvflQ zlv%}8Di%M=@#W5$DN4j&`Y2G2&vssE*|Z2mDJOM$;jCGpT{@M4N;y8*(y0_fsF5O~ zL(5L(u=KKI1#I;5jPYHCCNXVYrq?ctNhOYu%dVUI(RDzt67f56B)j>w%q4T9t6SI^e z8bk-R71}HzqF1otse}zrB?TRf#8SLTwhkoNGwqpCY3!h)fMt>o>Pd!Xp=Y`vhM^ZF zz0g|fHRnvKO6gWY(Zgr$0`E7CGoXN-ECXoIs{{(N+f{%0{OTC ziX+LF5}7|DX=ffD2ib5r5lhvZ|8!hLh2sr{wNyAWR^hT(g|)E?FEbQ!L)RJ#XHY|X zWMR89>M2zEsw`DTO}0ThY1D-+aYq~_l^42?IHp&cOr1-hr{v=J`(KJ)?OZc*c3|+>C8! z`?glNCN$6>-j;)C?;xuu8R7BV^7f9)@VuKsJhtJdsX3>;V*%ATE^FY`(c2U52hF{9 z4?zC*ouGXCjLO}^@Vjl&H%?QFuWizdN;YQt#%T_p=YZQ7dUy#@ij$TjVs9HzzVMU3 zei6=dAb=xK))Pviib7i);#n^IJmv$r&2TC(h8Kk1n zKF3s6eGz`q4mC~k-f`ujnJ5+GUHD1x^YEYT(AFgH9j^x@d>;O_9U7bDy%Y3+@BS6O z!j6{?Q!k!U)dr0>C~RJwfedC=Q9cyK1 zd&h-@yj?{;iSJgvEE!tov<*uJ4vF7aDd`rzuL^%+!@@$(%BlJtYIWYlhL!KjK)wb| z&-UA}#G)quybswl4fbUn;CUt>HF! z`0?=+(l|cB1v=j1-#1)kGCo9fJG77y(i2JBvB%LeQXs90hJ=ElVZ zNgL)XZ}-=dI-bFZC@bf|PVwQ~Nl^NPVyu|xez)N;_TycRM`CxJgY>Am`zZXD8T#A< zY%hIrs*b^zxtmD<*sV=CONMPOQ<X!%ty`dm_IdtVeU4& zEs2)lmKn$r(`vmL*9#R2Tw4R9wOeeD*j~1U5iGc`eT;p!eV_Lg?>pWv zyx)4eyjEW?Uw}jCPV+7Ht@AbdHv6vk{Q~A@_xPUl9rV56JL-D};dHxvR=?k$>hI?t z;hzp;vxWW(l#sgD`S0~V$XOG4| z5&uH`EAjt`KOTP~{)c#PLPA0yVMxN*gqaD85CO0U_y7WG=u>zZDF z?DcA|fA?D1`_kS&>wQ=6j^3~K{;_vb;@OE)63r``E9C8rm7sB?cx(-SMcxJ(LYSb8E9YsD_S%JWGSW4vw zhUJVLH99zg9KYau#?NCX1mov7S2nUK8zJWhO!mQp^9K+17uQvhf=v|071nMbhc?Kw z6pPkL1QDw0ELhI5rlqL`KYGx=ka+8n;;qNt-f;roM)&%J?)7olV0Mr6Z-T_7VYXWQ zY*tNwPJ}-(E9caH;_PD@H616&IqDq=@$VG&<01Am{Wk$;N+28Yws(9^g|lQKbz%uP z7j%r|z*g+mlw^CK1!u$O@F3l7owUhZkh-A}2$1Ro0-V_m2q1AJ};!lnG!Hn|ZR+YUadCTntLOj16@GwuW^J#SZ=>{{r997-w_aV3SNag>7ZKPpx`UNztytcX${;p8=(w79)T3z*OWXQ{+ zg@1*#)w{x?=yh6Y@kR7H6LHXb*aw*vCK&JrA{wwatkzu)68f z+j__*Er%``M5LOOgHg9B1Sw$gx2U-1+%x`hf`%#E<1ae)I&gRDY1wGr+|_UU=*(}1Wd zBOKry(nTv`(n!YZjN@qt$2q_$Ob~LWf~1)&1*99fdJN=x_KF_etL$!mrrD zIHc`!3fOxD`+#BHr@{~0Axfm}a|zhn1bdfZAD#;T$_~LHZJ%4fjuGr5h8;N-zD&3d zeF`3uC)C48)Mdk)V}Y|?om7ZfmQ;VdyqtzHmOa9AZiQJ+TUQpzW;*x&ZN+!*J(## zA$qfXw+QjOdvp>`?fAsa$*_V+F>g)|!`!T_rLb+%W=Ux?qBh}y!dNW{nmY$8>nBy$ zaWqElkqYQ`#KQW*T#%#AZki60_jB4XNeJQ*vUcN1NSXr`0 zy1s_%tXMV9Gh<=N8h!OOa%0vQYSyf)e)<~k$L!U=O`3JpUteP>wZRjm9r@EHtSi~8 z0s0zSWA^H2Cg`h1D(_*SzQ%pAYII%*J(jEx&{yb+Ss@$xt+SOD2I(uj5vzhh=6V>> zr65toK5Wk@bKPlr()6t9J=5pN;C|BNGW*TR<{?P0IK{lwd;wxJx0!D--)4T?e8Bvi z`F%)X-Bj^h-++f4Rqxp$NL)BZe)0W-SxTa8<)$S;7)e; zbI*5IxG!_x=>DVo8TUWj-?7m!d}VA8B}y;th8x*vl#*o{%(FykRd?sP_$qquwP{Psx)FP9EK2R#((&D$Nm$(p zd#&2i3>ddjR}|wmmtx!o_R>74cR>M%ge^x%<$A;{2~3(qqi{&;I)^Y_`G~iJ-L|aF z$tc*-dg_{z(;(vtod837sP)w4N6aS2;(c-0lPI!Hi0s0+IDv|XDa9zsJX}1%gg<5U zXAS;bb%lxkKEi*kP_36hQD*I;S%X4jzZ1GER6{tc!&jA>5t7YV*kq;TM%qMIr0TG7WezjE>gMXn6fZ*-(>-t0UB0}& zCqq3^Cs2dC{0!7vHVN5JIpp(d4pPlCDnd{Nkn}xexBw$mwzdVD@HiO=HqLs@Yu7$~ z%{!;tJNk7!v)=RAN9J$txb~f`lMY^NY8ki>vK!?U>qsD8HLP0NeV+H=#G_e~NVyYmiS%nqVkTV3YMtl>w^yGmT=I1XOiYDL_?P(?jB8N6)1 znB^ycr&F>AQsi&}^$X0j!oqWrPLtE#kxp`w2lh~kQ~wCUSEZr$j;{%xF5zN_mcf*) z;UVCdULuSs5`*uny31Vp-eCYH3}ClObYbnt&B-Gzrmb(Ac0If6ZS?wA=e)Mrv1Ri) zPi?rwh_Peamp{_5@z0iJJGP~Fb=tb|m(h0N2fOjB0}j21Nzsj$aCCDbP?U|9phUXm zUM8q%+)Ulm&gJf{xc?RiT4h*w+`)@6O>|FNEhhm%rqpTNKT*Voa+&Of^NUJL?NbUD z6iv4kPc2rQF#-fC>(j;iY`6Hv|D&N}pW)$?R=!Uckx;gqT_@WfUx|A+8;4iy z=+otB`8)QV|4pPfwd*Lqr&6X|I%FvYnJPM+Gq0E|E1=$afrLyQY0d z)Pudu%ElTIxf-@ckyssI(2+O9GHLDQ(9&NFEVO=HCF>%l%N@-QIiuGnK z%{8@@k&3VuP;w`P+sdlQ!WCDQxU5l9;yh&_0y!XW0R^3@Z`YI%g{6>O^z{@ zz}F1b*scP@t48O0rl6VdC<^MU0tHI-9kUN|?MBsBUlMB5jxkE=!$w)u&61Ab1ZA__ zS>oG{tsPzl`S=InKay*ZS4hJXKEl8`foC#> z|7wMCcCOgaLw6AhZ>Fe3T3!*Bi0wT{c_=IGw!&_^SRB5BG3&Tk+amMC-nOFu?QguBzp8J^+*j-q#K6I3afA^mWdq@J=#Tt z3Pg{_iXK7GiojPfYBei6&WKyRIX8lb-0S=$?*fBXu7=Wuke~ zghMxxh{5dEk9i6ajf|OyV$A!*yX9AMX-rB8(c;m++mqjcQe=@3B`lI3Ba7r5rO1;`+uSx{JlmbU!u#G}YB8Wt39jr?EUMm7~6jDx_YFBAlVbOxpMa9V# zxr1Q*y|JM>TOe_yK`ZQI?NcaIp<_O-z-p`Aioxu5IfbeS+pL5@!eeJT737*}DF z6bceoQ#v?C*R+Q!)lA_|$paE*>2!BkF*Xs2a_X8W_s{&6l?W->w5p{xUM(v@V20`{ zbP#?F;+S7o4dZt1cJGQ@xG*RkBt9mPZ$m$Z*@NUPhMyS$pcto26!BmM_Y=qmc{n^2 zBRWK5J%WL*T*oiLJxJdB#HqiQonJCz7P+9oo|^bNj^c^1jFUN2$@J>lhKe!g=Lalv zC!3WZky82$G-G{{dHn!7J!x^M5KfUqu|;S)`tpK6^kb27QC+nP49fyA@+craQjxC} z7~U+^)2>UECf;NTxQRyX8s+xJp*xhQM$+PbvMs*wNf_IMExtqCdy$76Ro61o`2n(% zrc!0;6N{Q3(3#nf1xBghekG4A_{sXl%EpbHZ;ANj5zHSmD_vRJR6kDQ604QLYrhN( zb%x3aj|gOlRUaurkdUgugpcUdn70PF_0f$sf7z02BF>0(6x3&mxGOq=Zy`S*vtUwh z0{o%TCn6bdvK6OF3O}v|l>@{*MB*#4zG(&U%pxP{#EP*CImIkbuaf9SNe$e?j9dK+ zr%nM;A%P%-D!5Tx_Um(VQV$@Iz>GeiNEKCq6&uytNXRvlK_Y7Ajnt}SmSWH|yn{6P z4l4Cil_m3uMrdiNR_dvj1EH4~e?UTAqVao~KfBxsXM3xCkkh zdYB}ezqoV`$qL3H)&;5+(#ZZx+qsefSzY*sVGfeR)MH0>o2($ci(Gp9DrF@>s{EEH zmN_|Y#F}zVf5exrPL`}4>Ci-4`>HHisl0JsksPm?Bv@ME(w&C{5ZYfk{Cd+s#asjD z5@Rt`$TGDxb=6rEX!fUP>kQq4JxEjiV8eW=_>rA9i?Zt)W=utsqn2|<&Mq{!Vsg~6 z!d^uIV6ZG{MFvVHFUmed1Ecjw41icY>U&l<;xj08W-D#5w-1({T3I?N!98gTuRsxr zSH$3jn^sJ>B?s&Tip%Dvf+zx6kuI}rA+kOTXOPJO>%yu2bEvPZkr3lm7LquiNH1}Q z51MAGVl2&-wiZqr@-m?_GceeaAE2E|V5w8i)PXk~AYR7e0K}OF#RXic8?>`Y?(&ufx6uXIb#8n;g3Ojjh%L#-)0I$l0~&9+xhA8PH5gbtITo4e7?@suJy zG8|c{4cgFVu*xsP$|qDFr|Mo`hFQ;{*0{`Fc2Zc5e@d}S2~`sc>10vmdqmwmc(D%7 z{s*0N6nYo^Pw44mp)x_mj;4e9__GMj4(cPunR&vlIJmTTJWI;Y%QZOkyj?!;R&yqW z?xHd=ki8g)LPzm^Y46xaZQU#DwRh~L=Re8k2%YwhJCN&Fsjc|Hw0Ha-6hr$Yc6-O2 z^n6f0YinPRm*Wl3e zVEG*RHjQh{Du!;ehDw3l-f<~37iw&X!`qIYW>7R9|5x5X>HqC-;D0cHs5hY55;~9J+XGX>`_B!uC`rwZXZh{5 zJqi1PGi?HQL~mytfsfcP#0|NdU-sYdnW~>#XHw|F=+gF%2k2XVO7;Qlode(91L#QT zLscE_yJ7_&-1@me-kxtZqV zT3JPztp1!Fg)Vs6W6svKaTJ@WYO`>x=`{gK2|S9VbmUFW4%x#6Vt+bviUs)h>#I1?*xh8ax+m~ZcRkUI5%zWrm^dZdx@7Ui9gldyOv z)^gZFmz!Qu1{!JE&B|*G$j3ps9 zgECLSSd4M7BXknA49w2|WLRwz{a7!D;H6YceK{rj(%$hVp5b#yrROI_&&kehZ=NnF zMqeI8tUNw47XClvy$N{JRn|YAt?8O{FI}Jw-Ra&!3vELS0u_;^0wM@jfr22bZBhiG z1PdA3P7pWL;3&9_<2Z`TAdZ^2w(dG^<2EBMgT$)ijEIyj`F+m4-}}usX+hrK`@a9@ z`8|IhNt1ieJ@?%G+;h)@AG=vc@8~8DJ%BnkrT79n@+pqYaq@(Qu_Ei$Wuh8sX|dDn z{(!{$iJ(_RBCq4n%zzc-fmh9`ASYJC`;<8RGm|rh$gv7?ER&@X{Ew(aBIib`xh&p) z`Lhw+=$F`o_H+>JUcY2;W$p*=P*uPSRKZ43%ML`9FT{DjT(4CR)U zfCWOuw4Mm%*+Ewhoa=OUBuOfi((KGmklMyOjR1$4h`3503a!Wg%JmuhIbWYRI|#E6 zfm{dAAMWhH4)p~#iUCMQs4r^$srcfo8%0<>EW(w9bo@i!CwUSzNT7Jcpjg;v}GKbDJ_tmQE+68xlLC{o=qE^oUK@hfBz5* zv4zb%u8+)Bk)f5WxFQd^*J4#e<#@Pcs3+4MR&VX*IM1ewEOCsiUp$#Q=xpaHD4PPx zED47yhO(b`{MB<(YaWj!af_0%h@qxvJ*`+KXFe{YMu;vSa)qGt;E;UqlE;{vY4XL1 z5`Jf=rwykvJ0t7;@)f-%T_RSCe17j3R)Ww>FlUhjN*3_ofWBf0r~j3nkfJ34L<6!LjVcgaKMfYy0NXv~YP<49!R zHc{OglEm5+2w2%aNg z0()-MA5)oYF?~PBJa~}EcuSBW@d9kSIpLScZtF$3VX%XP-9RD|rN!ZJJ@4PibZ~ff zs08#&l$-2>W^*rF{C2WqMncTQcjY2Wy7FHjeh&q`L}W>zGEEFry1O$5u3id&#>Dnl ziDE1OTIh3D`Q(1}pQMbGsIYk;#esTZ>VfAn#LwknUE!e*Y5>TE%TQ=0SxMKNKf*r#( zWXl!?=EeQ@GHKYH%mQMIMzVllij?1oOg{?<%&kfFN)w1_8cM3J3xPF3rG{za%O(&? zJ+WhNkj;cOq}!e_hy{`?m9mD>mv$uf1jDF+zI55+Nv)pL*2HHD`<}o)|SNSG@ z)yopFJgxver$~VzFheBrd zP;EasuocD@iDYcCCs7z%Bo1dtp|maOM2X?-F=S(lL>OC~gs}x`pESK4Uzugc$${-l zq{@JRkwlpMtTuSZJ0(nBY?|DSf_sJNfk2}RLcwZ#kT+6kv_VTPM6uKY&5PDC<*Zt) z0ru3qdYCnETxcL4_t!vTYN< zdJ+CGj9b>oYr)nUb`hA2Aov&i81Bxro<0>bb*T%n6!Q)aG!^o*oME#g8EYeP5DXTx zJD~-_U>vPsSSnU9VA|FkDebWd~d-FwlY*sGH7F_Y*;W_94g$NZFcqZ%`>EFETs?Kk^}co zKbrg|dncV`sGw(ugfqaf&3}vJgbm&FvKmTE@IL~rvWBswHO&8GKd1U^lAtALnmBP{ z75+*8DZYxN|H5BwLwP=eFBEDTO0=eiO8hGwnU|MGf!)N^Z-%nxN@!g*nvfB|Wsv4N zSZp6Z8bT?=`v$1iI9fl#e3)1*764O!Xnh!I%l*<=@5u9k{NoHdGiF_@E+hva+$fO^ zVgyVrPphh*Z_;{x!c~`1fhqZoN-)M+&!=!HiGv(_>|f~{+ikn~c1#62gNEC`q*2Ei zhIMdK|BnqqnTEXjxE~j^I$EJ@;(k*6WUt8Xr|BncZ`=ljSAuB+2HE+qI-xY=Qa}+K zJYpjZ?86jKy6zVQgkr;_{vw3lATMI$_6)Oga^qG6K0XShT{2~4{z99oUPby`GTRDm zE(^4VhblM+Uo`cCS@pFB^33eh{+bO%NE281GBIW2;g!KgGFRZWa0N~Z)5Tn~OU$E4 zX4UJ{ZI0w@t~}2oCG9Z*A1(G_8A3-oWz0Z4RUGoEngeeH@3xN^?9#sxtm?)p#MFZ& z0i*~igSD1$eiR~7^EAlYexyC=&WX|-bO3_RO13S&BvR>=l%58eIg-Je+=g>cy)}&O zEo9`2y@smsL{d;zm{ZaT>^+<~h+3|B(bKDf???aCj$Y4W{6_Xi+{nHpvfmH{O8YiD4b(MaJ<%{9isE-MJ?L?#iY&<>s!06iS0*KB zjmVM=u4aqhexNag^$L;Ya7EMa72-Dor9L-Ur0$^~3XgW{Vcj)i@a{K)o!{%W#@};I zIwmD^Ru`wvRnJr}SMSn1qj???R{y1m(Pn7JYA0!@A?VL?g#Ecj+opAD@6sO9zNr1D zHcpqJ8?UR=Ez@m)1B5o+ZrxqF2X&9=KGlT=r3Q@+njUm%(AuEZpuItN2R#w=VNj_) zBCvRaNzWyH zopd6pH)${_J-IA-e6l(DisX&S*5ob8cP2la{CM(_7}-7Yjgg;? zRF8@p6+bF@RNkoiQJ0Tu9JPAX=23TzdU(|1qmGO^F)BHAOlnc;gw(mIm!vL9-IjVV z_0iPBsZXaqmwG%^mzJDXoHj14ChgL+#&`q=3AKqnTD*)tjn@? zWgW=+H0x;Ak6Axw1!ae2Cuf&uJF|~u$L5sg+@JGwPFK#+oPXwgpQFtU$xX~1m0OrQ zJ$GI1w%i+Yf0z4I?%TPaAJ0FM|5pA#^1sUO%?~Xw7GxHTE2u1(Q*e1f zW5Je!j)Ln8?kf0m!E*)23RH#3h2sim7j7!NuJG={?!se*9~6CC^mEb3;?c!pip|B7 zis zUrRqMJyzON8eBG_Y-Cw^*|f45WmlAKEVGt%mhCS)Q1)2a3uWD9_OY(9FOL0m?0?3_ zk9%<3pU3?;u5VmS`H1rD^1^a+`Mh#l`Ss=ZmOozpefdCnTt!+%X2pbxi4`3c&sTI+ z{G;MT#pv;~$6q$yJ^tkQpb4WUurcMdriim(9n` zznJ^Y`iY|^rcW%GSUYj*#Mu)UPP}Yl^TcZ=-Y{|B#0@nM)x1#iX3g^2RkhdDZmYei z_MX}YYF)K&)xKBjsqL*Dtj(RIu7-AVWWzXE+)_+fGT*RN1y7kidH$RQb2ANLJbtTW z6S1@f_C!k&0Tz)9T2>%zR3k(&h4rutX*MmMS3h~mw981f89L<_I>8oCn>~Np+{;+R zg=QFltY5yO$jB<13u`TSdaE)8&z>`H(Y!hJk?Q$yyV%HzlD(OM1)^n9et}R^Yto-T zXYwVJ7bW|HnR3_B6~lsv6s8d7X0dtn7-FB&^^(GJy8ghExg}p$>z(_zM>tPaUaMvT zXs1?E@%@YxS!9=p@Ms5Bu*G06LSYi#a-k;e6b>iIY{fWf8K}VhE=N(KK8gHLbLF=6~JC*;dy7gZ8icoT-A9~0>ErFAt)7oWTB?s`GDrWxSo04_M?3TP+9ZtIod~F zL|F2XFx4;jAMK-P@b|^FxsLW}te+F0Mn&IGsvfCXynKb&gqeR0kZe4s0*I+O8b zxBZ`e9r$O4DwUkzaQ%~pVI^9RryY|uiiTQU`rJLv{l??Dp*^865rqgWBm`snbzi6@ z(dNQb7$OPl8RUNC=MxkSVx0+JKK7CiIm>$4(wP0-=rGWLrJN`@ndSb9XQq8&?DG;_}R z(QNPHLJI6v*qBnLEL~5wB^x%bfbk4%dt^aI<~CKPn7K@vK>`kz1MoPWgtD7fTUME@ zkXu)obh9_CUty3?FKs4Uzs$mO_>Z=^2Ly}$fX1DUU>*(@g+w0plX`fxC5I&q;BI-I zq)6BR#`55S{dC`!J1L+reiHXd-poWH@=ZyD>CO>xMFPs$TJkj+&ZPhyG>>bDLM8&L5-TbnXF`qo$n4{$^F=Fc=9zA|QF0 z1Ng>x--#LsmwDQLk%leZBsHpL7=qX|@X>tfFd+UkbM)jQFW?)m#JOEHHO|kI-cT^Q zbgWZUL>+Fv3XPXn(Ag0zBm}?lAy^0mwi;{$LN#JXZkdg0GUukNbrqn(EI4sA8x-VUz=?r*U*Imwwi`^L7RBVK8z z>e2&79I2Cb*Y!D#bFL+wFJ~D=kErvSO-*%X@22x?t$lNvD?1jz|5jhg*C+wkTf5^2 z>-qpw@6=sLhe{}phXl9z%G66JktqKYhRa!k56@~f!r|pRZ>nM}L8!BveX%4+^}&4x z{OlB#fUJzE*q5r*<`nCHyV4UXxMhe2>FSn{!P$Mz$T2|uxyqbqEnv-HdiX)i54`;SlL?DVgY26%6h4d$U3w%k z%+qNG><*%WU^qg731f`T86cMsEm@38KICYTCEo9Mh$U!n_CU`Etju4JQ)AGk>KC?a zJ zw3+pq;@bR%at_j1wS=OwEuj;Ntg(wAa%vb`#k@Bl6f7m{il@w+7gSt7`TS{`;9y_Z%8NMkpKX|tzBPzI$z^lyqcnF_Ck@iYnb zkp#O#$_=KY)U>TIZeopz1ucV^3z5~*4txa6mmuMzVC)!|0#7I^H6Fk7RF9Dk&?rkV`@QEB>w8=Fnzayf z&7_U>X%VY{u_(5hPcfyz`On8}f+mFU5H0bp2cAI~32I80{&T7cyR;<*=MCGG{ZAIg z$??O@c>IymHrM6eVk^!rLM)wmCu)fYqtjHLlFEGIed)!6IbV0bM07IOJ*%7>IDtnd2lk_<2Md;=ijEM?3Sp+DkU>j133ASgZu=5% zhlUvaC0_60C0=$3An%0iYQUKL9SAG+jK=zR?;a%xxvr;6g$(kF%KCSN$stNd5`O0S zh_<;NxQ$~3rODO83(Hgj%#;DCUm&j!R`ZIt9cKLEY^KJ3cIJ@iaVKL zlRB^&-u+=P33xwK{iy0!MW_?hi=seVTNy!s9GU*Qq=C-o`y zfI3{0t|`=M9@-rl{{Lbyw@!5%v9`?ta}N-Rru~bzdXmd%sSPc<(O;eH!#rkWL?} zPt@naL+(WVO#NE@CjBn`9s0xiF8w?D5A19H!^Fuk6anK22oLNkGwPTNaVAT|A_o5(i<5Ql@nDEb!pU9 zQQM-fi@G7|p{T=AFGu}7>W8SGqBPO5(W9aZqQ^%sj@}r3P4u?t-$WmdX56yu#J00e z-`Nn-xgf0c)zXutUgwN-xVen$tc&PuFm^78YOg!p-q7E^V6X>)7$itJt+VcQXG4GI zftzN85RNQ4=s@mGgi$L)X>Uu(?L9Gn*WDF)!;gk1K?R!T#lh{4&l$ZPIRi>SW z^WE-g{p@p4Mc#SCtS@rjiblofAlV;n=P4lhrh8Y!BN9%LVDwMG!|JZ6N7{GAJOa#d z*5`bfbz;1A@+d0Cdz04lUVwLDPPGv?oX%;dvpX;A&+fc`r1#vakm@s zsQiVh4YC6?{iCxqoi)39LC97EUZ(F?RoCg!>N^#!j{9G2^@1?}#-fF%y)7Z$7QKJ^ zLh1w2{x}+Zw7*Ev{wl%WR>95%7JJ6y;|F|i`EK)SZ1iQ2X;RSHZu=VpY86XknigD1 zjq6*yF+jQ&^h{r+seT@PF;*j<V=IR-E;%UgvCVPVM%tf%ZFJ8ED`4+JNU~HFWlq zJL`^gF8IsP+!hK@hTLa57r2JzE~JNE1 zTSIdPRfrsd+~+zMyf8HPs0y(|kb9_e!DB;nU!aF(d;T$91P!qTE@F8ZLKE3h2_F^Pq8Dqr@S%g5h|sm*J4R zWjGvcig^#eG2lJ?8veb4e_aE{vcE?wgVC`5;2hwoNGPXvBIzO zT2`SHXvl*sC9a_|0tcteWXUGrk?ru<2)mhhn588(IIcK3E{KyC|oVeIDf5S#oX^BZ^x@;m8 ziOQ22$}=*czQk_O>qUky)hL()cQGZh zSAp522x2@w{}=X?c~X#`7YK)YystE2BXaOGHl7zs3oO)SzqJpKA-DF0VJjTOt%qwS zouF@QEBqGrJyrd%iMbWhBz|hQUHgD~D*_c&;T1xe?rna6J$CTM_%#lMa7cE+$2RTL zJ7Q8F&d%&%4l4*Pm*~>>lL4Ty(j^|Fd%=e&m%Ov@ov3*vnP4LSd56ivZz)(te6N(|oShrP`Yd7B@^JqM>sy>llXp}>OH zJ5NoMFNL=dsw)L5Wv}?PfH#Ow9ePR}#OQiX4X|kh^vsHu)=`uyO{}A`66UbF*)&yh z)CcJlUse}M%ZemvOh7gbI$5UK)^*F^VN*cERi^YGTY_hY#X7|Dix4H~Z=~`Ez7wdp@Q8$zB5uEU^_yOK&7iuudU3f$kF%>M(ufH6rzpw90T5P21B8y{gvB#829oeSWwt+u2cwSyed$T zbp#2g_yRaejpXZxa5`Asha&xE96`${M8n#ihUja1=+*^oPcQMRTHuu<5cOC7s6|2V z;|*T#<4e4UBF;=F+4TmZJLW^@N6=8npUwcuMvQtXC`>gmOa;NW1!~0Xr?l&_vAfbQ zZI}VvsOAHxEc$;piUEVcCaiBTBs%^-7*l0S#K11%13PzU{{{}Mvh=x(E}xWaRk8I0 zF6dAFej8IK*7VQ=fAR%9jska(yMYHvAc;D?7&C9F@ZYz3d2@kjBM+OndOdR2G2MKo zuv1if&KOw020UPsmsuXfVRGTDB6W4-^wn3cGR;RgQ^sR78+pXjX49PYRt6P==)hwtIExmGuiPV1p86S|| zOc|Dhdh4>atC!2b&|!s_%H~L^a5EVf;4LA6>n_!;Skbs_>GCxKXY9~qOB98EWo?}T zcb~u&OMjcebeZPEGblSBSzG(CX%HxCjTB1Jz`=- z3672&o4AGAWFwx|H*n%SWG;hbs7y$P9Il#=-ZJpoUEi+VrzW^8aN$w zZ<;4J>CCfQswDP}y$Zw$cRoy?RvgBXXncX3$qZFiX&DlP8?V!vXM%yN)k1(`-w7up z*I`?B?-Ssh5=lp^(&4fR>hSdpfRpMOy>cL0LhF9%VR{vQ6H3B62aU(C{E@yp6A?EG zcieLKZK%%S$^*+P9|)4uq}|FxqRal9LFhu;2g5w;HMsniyPq7U;2SLMOa;p|xEGhZ zKO3gtPiHOIPgmx0cMyEi1d=+6rJbq97wI-#?jAc#!5L>Q*g+TVa`&af6ukPZ1us(L z4qoowHB7;MXDyhh#`V11{opVKpE_$nJgQ%Sg0Boy@Z+-$5fuk{+r41Pk4NaVgo(f#?%iL3kDR=SN%CQN|Yl0FLCS?caBA)T=gSb#d z{ii3<*81iwYm7VY5sI!F{BP;Y4L|csWvI%eYE-?ddSCUGs!tW9j#H0UPgmci?o~%= z>NK}#dNrNeUTvzbNVijWv+h}_e)sA|1eFKP3%WY!`k+4ry$&gVh(1a`9`gP9`VReF z`p5O}>Hn_(Qf~+z89XLd&^ zp|zn?LoW#ZUFe?>|L(QW_d~x8RfR=`#fK$_WrY=o)r2*Mtq)Gek)Iu7Z~Uk}&B>-e$Q41L#i#f^={ zoAKWmgc%RZ$S7w2XJjNbj2CAzyVWqH~Z$(b-PH7|#zEX!vqy_?AQ{ph(X z;ICNJVOqNswKuI;3d?6Ys&E*RG2V{v4hzM%Gn;swZPQ?K2=yo$0+NXK#DL zn7!`oy^vU4!ZPZ;RLc5JCmMB6$zE?o$zBMCp2TB%E_K&6q92&{FBbOe7%GJSAuFcc z)3lD(NYZNw!K(?pD>#qBP>)`Q0MquJ?uZv^QdGS=`+CTm>o7PZZ)WOqP?ci=>nMjw zogo{e7S#1`x)#=AJz7YwSTRV!rZZJb7KDz#VfDJBdmL_9;$G)VScA$S!z)Efh0Reu zp#D`9!gd<6wz__62ZLv_ye|FwYgn8_MDR4lUZ;s|)5PvnuVE8a734HS$$@HV-(~5o zXuqYUSIB}6<4u{_8;=*UZt)vENx+@E_VqH64wR66BAsdi!bkio2ga3a zha=+$2*|ScLMiK{e$JjKB>Y`142XuA8>Cuk^rh#}oT*gh#9)fFwf3u8av;N`ZsdbS z#-WQA=RcqF9_$s{-c?cmwWFhZ!bCIn_4*)zVuyR38sy>Uf~3x)2dODsMVSx34Y3)+4JYlnOQV-^8DZex<_r;s3|E>7pe;)4Wuga8S37tEYCk1*(pCeNOSk9kv6;gly83X$OE zu|#FzS<~jtgB}|zJc}-Jb62ciaph9@^q;z-WyM-(Z8LBE^H(fgSAh698#g!M&TBE{ zE+1nmt*k67EGsFgH04glwTfl1$T2ILT2?fUQJWZb_0#6gn=^az%%a&-7v{unr7A#- zm){q8B#}*~E1_|>qKWk9$eyLBKDPOjm*~G2*yqp>U%K=yFu_0By)m}=@mLE9DNXdv zD&LC{`2b@i-UcYI#blbd3QBt>2D!;JZTYGV?CUiq+;uGo)xdsjW|4NOz!nn%C^oUg zYfbYg$|6$Hg6A07&krR&AYFp+0rGGD$sdn|EfMApj8Z9r5%m;$QJPgnn%Hf65}3xe z>hQ5$6Km7N?ogNLsLv7q`KtoNL|VNLjpyD7C~}p|E+Lo-#id+I{LJ!ID;kT+eg)W9 zuUy0kn{oP&^-pt^dQBAUwv|lT=rmaTE{BwXECQsZfIu1>$t;S8?wKNfp=G)v)Det- zOYqE=GL1EyuQva7kB(K)f+!GJag9aA^ALq+a{-HIv10uOD)7_;?LMqP8OfGeV+1JD3Y^8_>|CN0lw& zMUwNAu90muCxTVm7dTu^^k!8AGZ!u%zKa0qn0JrJMjHEeuSj!FS<4Kmrho&aVh;$c zIA7_Am8@Fe|7HfgSqy`fpmO&@RWSY6VHgkV?4`Fzdvh;;jC3{k`d%a742F8;{|)_G zk1c^aoI`nkO5c{-O4bw{$VsLXe(-l^p>Go0FPJS|fkf42E-Cn>A1LA&N zk?wF^MSc0X=*wZ?B`UuWAil8~9vJUbyohrRIB-8U-~FvkW zE*Be5ZO>}AALyma#erV$;RC%;*<=hi67J~jL}Iml<0ND^>xG^v zgxza}%_aFmEPd{b_?FS6`9aJGKO~}w;B4p$NQk6K);BD?09i{YwZYf`NGHt?r2t`5 zHRLQH%v{Ma;dwbos?+;R#+63rU~O@_DTf97MOeXAMq^@`VC$7yL)jzxf>f7 zv@D7v86JjMu;aFx=hNvn{I1IVd^*)}FCL?1olwb^g`(?F-8`3XZ=>bPrL7D~$W3fy z2txo&09tyZ3WUuT_yS;Y#do-_rvA(qoy8#>E;a>xTVsL1!0#v@z@FuVXxoYZ$J;hx zXxnl!q;boEJzYSj{XaEslLOm^CBh^t0n>e!fOCEok5jb)KLeU=!|b&+(?krItPhEz z0R?*Aumm;HFw=Z*gARfZdNw z0VJW9iI&PYayAcGq@u(Lvf=|zWRQOdNQ|LYl9bCNTA4~IP~sFRUG{?hFNSRE_lEnn zbs_M{a@V|1Q*$oWep*!Iw;Os|W7#2K$>O^;6yKL&!y7?I0$;{V)DXsiwrV{k;q0&= zArnh#4aG^(Zojj)2NDeW>-HB!d|vyLqQ?V7LJpTwa(dDZ87XG`zxDJ@hi~8LC5Vlj zv%{jeVl5pkZ!wTbmeGFscSwdq%3w{T>Lyu&yX=qk<@E&7ACs64 z)XBro2Z!r%(n|w>EcPCRp~J?^(>v_)_h!2mcm|NMaErPOJ^-v>-`adKMB?Bs@>v}pdl zr$H6D#87UmqH&b2Y#eKeb%}p79`e=5n=w|*Zony;@o)g#St)vfD8h;e>~2a|Qsi(w zibEk_^^&MpP4@7#df^=c5d3xDpQThbqr?7iKe#)_FlJ%?F)ls;t;5w#R3QjJAXSv^ zPu2KerE1AJQ8n%ys5*KEswmx`s@?!do68D|W4WUy;8Ni%x`B)@>8rv=MkTv$Q1K4? z1Q_g!xz42j^D*tAbJwC(N1-0oGe15)9|F?XPIU*3S^ z443bXcdOanxL@sqom<~&FBp(S^>$?$l9(@AEbXeRP!h@dCf!=tzevi|ug)0;+mpLW?0~+nnuTAn62&)#xbbwIsl93f*m)&#*V= zaqvlHEv1q^Mk;W6os{cWz+Ue(s9?O?pN_Ntqt4yxzLq1#8YvpEK4=^%6REA^upP z^T{sV$3$m1UttGH6IMS&*pk>raXXb6B^B?*07SIT$ymGa+G)ctrmKum0@d(QmKEs+wu5xps_7Zp(S-Wp{>53%AEV$C+Z+ zN&Pral*ezh&0CQ$$6FCMhc3T=A1zrfxYrX9ll0N}GNQqH|0tWG98)uG{@Z%H^|1Bv zx;FyeJ+%q9RG-JKGj>wTIl|qggzM6qnz7KhpoO7kuN-s;DrRFbwD;XAE9ihofoXTT zw-IRuN)ig6Se}!t_&Cpc&r~b#g>#-=&xc*BzNgOGo-o}Cll*&Ti1M<_Blk?IDpRVR zV`nmY=Tb2L_gsyl&DL(c)r!+izX_ipWV5wPf2|d4&Aok5Do#E$Tfk3%y>iy5QX)I; zxAiJ@tWVnS>x;5nPJcqI3mvY7G%-5Fz_K+76USb){?7g2w>thILEP&H!6hHb066rS z1n{gMfafrEIL-eYdNg5OEk7*{;hG7MCvr%60f-ezqImvxg%_lSg!V&G9c@(TG3gOX z>$x5ZsrU3wCQG1uz#c6Okgokm<+zMuAx?)50P!dte9Ch9uyryD;y_T+q%4R7A)sJD zlX}8zu6uef#g*<`jE(y*mV=r6a$Sl(xY3LFon`r%46JI+o=+?YKz58Dy5X?lena;wYh(1xXwtiCFdU z8i2Ar-Mk1_4?zl?zcW7qI@K6x0MH{k9>kk1O{>XEk7;GohILR6BWDgb*-*w*1Yrc=dZ%cwDeHD zYAMVS*5cv2akFXJ3i#Kvax;TQ6SOH-6b;oG@KsP0&WHn{8`hh2^EXtPf-agh`GT41 zuXJ#%XEM@YRO(~$9FeJoYb#gJINx{C)x3KYpytI>3H*89>w00Tlrh^I`Njg zPJT;uqO@D zvGRfFSmt(ybpZHYc4&FzEY3(@&6*T2q%sj858Jl;p-kyG!f)*GO5KSa-Q&m5Rs6p) zIDlr-anhP#hunbZai{7Ii6c_h;r;WjF)-->r8KNrsyAb7uB%zwAC3Sn|LG{xuIO$b ze(9)!bz6j^)kb4_4ut!P)4LQaCqE8ISco5Y9#_qc>$ErZcJ8zERww+p##&gd|6z?a zN80Bn5uutf%H_sNv+J4X7`!d;qWAo;rX8ib>=z6$nM+%Lm;Jha_Ej@LxAm|AJkygq zvnB|KEWHv5b_f+@i315kIC8$DV|KKJ2R_@(W<4he@_)9O9xl)-MNWhk76_*yQ$CG! zhwC>~DLDY+LRzB1N#0?(D2QIV+FWWJFNgqR^egZHqyA7|!Tyqq8bSIXhEOAmy( zPx+~vULSVg=KWRr!?{fn&Rc{-<}Lp#uR88kG%Y1J$m6N8NeIH{Yb*sTrN+W)0@7(H z4?S%^ZL;bI_t;PO^w8*p_V-NSqS6HSQaI*xxY)=DFHDG;PP}VCDtKEe$x|J!aFUz& zcv?c>aFq;~c(F3E%O28CrbR^Z{&OT*RJluuNF-9wxgm5=pgu(+{iJnSa~nAYZtM5S z`?&gUyS=}^ecxcenBMJn9bA9t2ih=wArP~WKrDnrq&1k+UG~rcT*U2t=DemTbN(ir zSabHkJELt+=)fd8y>$G$&TZJ^8zz<=<#4?@w9TwHh8-)>#t46zEbRvl7j-M&n=YjF zLB|_sh1ea9UrO1|afw(y4i|L7#-_HckVL2otcomry0l86PyS^{j(^y)22p(9mAoXmANZLU- z;^7M2*JF{Ie{Afv>WQ;etrJm}U1_LOcsp44P(FNpqD;xxL9Ol=7HxC7%cK7&Z-gQdohfjGQ{T?W}~s80QBa0o?i{<04dd11Mi6FF1;ZH zelF|xgjj>{goYP(dLjl3k*J|miZ5@}@M+*)EymXUE!{55(e!w#Wf!h_pcxd+no*e)j&}0Q{+q3mWs+L*uvctgf9j8-) zp13U~;q_-nKNOk6hs>{+&vEpa%ZM&JxGiGnRqSQJ_lPcDW5|dHn>g)P(>*^|u=t zug}u6R1+fGTsZQ69GOxETAP$I(q|7Qre>tPKSM-WS^(l=V|u2RbnyoR6D?8zD;}!9Xx7J zH``Mo!`COQjZR2hOR1)Vr^>SK(YD)XV8>={EJm>|yx5_ycJ+ck-_;wtsmA6)f^~cc zl9cnW+J2(nnxaf?dv-<<;u%oVZXg-N-=3#C@J(3^92N9UlxZ`I+U;8d(q<#AH6X1X zX}10zc2uf+E~XJsw~T1hSFBaHB}`Zgf4KYhdz*EG`hEL*;@k99lx(KtTX^yW=CL(&*r5|57i%^?ORX21pJW9tE?sdsR=Uo`Nay=c;d1|A8@axH?Lm zt}atgRG+6_thT5(tM{q*tBAlg+ChpO!zzDpM-xIej&(H}?u65Ssi9g`AciYbq&jhP*@G-gfAmKaCOJu!cZ`E$(cF(1Ty67xfh zJ~k>gEw&`~g4o5eSI1r(Ym2=;_H~#lAB*jY{V`S*7ZevCmmHTDR~$DPhRa*xZi?Fv z)8&`qK8@>(D~O*Me_s5>@yp{^#a|nLfBe(&&&9tM|M&PW=6pffL;=vJ*jCf_l*CYBz zL?jj^&Q826u_f{0#Ag%VPW&eEbmFL_^rV8MX-PAZ<{%PSQ_}XNok=$#4%kbG0p>~i zDJdd3IyoUZE4e0lLGqg9w&WXG1h5y9-%tK7S)G!UlAAI$<${!jDOaUjmvVE;Ln%+E zyqEHi6mLq{$heV7BP&Ku9l3C%ZRA5EPmVN>8Z&Czs5zq=Mr|0iWmNm9Ka6^7RBUQ# z>XoURQXQ#xq&}S5mHKh&e^Rw+VQC}NGSiCErl-wHYfWoQ+mrT8+FNNKr6rrjn8qQh zSDon!Q;X?Z(+#G5riT#Q>lM?xrjJcunR-k=ntnE^MhA_aJi2al!|3&+w~cm;z73JR zUK;(z=+8zU8~x+xpGQZgC#7ek7p6~4KR%u3Em%UY1NGHYj6d)EC~f6VI6dL!%eEKk;{ ztkCS(?8NMf?8(`U+3T}gv)i(FXa6qy_t{ToKa>4>_BYx8$qvqm&N1bT&6$!jE9a7& zr8ygNEIGI2+?Df(oX2yHQ4%{Sza$WP0kkbhqO-25f^Tk~(oKbZf={6FWr^WV<@81ccr z&;L0;wIBo0!D;CFW6Ubpy0uRCkkFFc&p&Of{zML7DORNSY}~S;n>1Cg^LQ8 z7p^O8Dzp{uE&M~_Q-!X=R|@+IQ;M>RN{eO`%`Lj5sHy0;MYk4p6}?mRMbSw(wT~@M zEY2^kEUqcOsCaSl=Hf?-yNkanK2>ZeDJWThC}OsfJtcRPyj`LxHI>dm46&<9Ev1`F z+e>dQy}k7D(l<-LF8!fYQx;m5jYwjP%T^+e*sij@WltiC*sEn9m7OT_mKny59BUq1 zH}=x8TgE!Z-ofIEWsRFSZt1u+oQ;rK=4 z_m1B(!7<^H39bpRPxy4gzb6b#h^S1h%&V-doL;%Ka!sYR(q4I2m?sQjez z+sYG_gO%E_x~lrBOA&)?L)GT09aZ+K+pGRi^>CHC8dB#Y(}kC^>G0MPW^Mrg z_W}`FD%=I8-r9&EEm8mfbx0Ls zNjl93>TWIhnv|NY&=Ru54`P~iB-Gt{U@DS3Pwl>?dLL=$Vix>QO@)V5<|UX4zX!vQ z8EuJ?YUjm?X2Y$k>gH*1R;w{8yb1d`L9Cv(H_; zhrVW1g{ulx6IIhyYgL<6ttyA=LDgSWFRT6uxA=o9gL;IzL|v_34LY+bo>_43tl*^9Ct)L8 zsKKdN|elm-nULE#v zq~kK4v?ECun}3xB`8^|ih3Rfb7EoRKh5NCtldi|Qb|>NH&VtrZ?lb#fP@=A91cVU* zR^1_04~5>5j>jmqbo1nAoWu1bHBU~3f6*f+uqBuv7J|Nk)>EcdG$z`4_&3+8CzZaN zUl)gN+6axj|mLV6Gd481?_3x7CcHa;wnL$x9%BV0#Uo8X53ou z_N}4YquXlA)_R-6h83CcIT)^#oY1S0x8lHlCrMh^t(&&8Fjal*NbVeBSnm)%M-U3f z3&SPKY3|0@k&nlYGR@siKcgO9@D(#{U}u{JhmD*j!Je>M1*r-oPS*mUy$kU<}rI#X;G zC1tCNX%krxCPjP27n*GC_9OjmH52x#n?esx*jtTXcs*I98)Bk&DUK!gB|2$xGe4aU zR~;oj5Rk|q4I%^{gY+6F?CrAuv0vrPn1wgeU=_U~{1LvGt6zW_QID1gP(khc3#~*0 zQa{iN8E5yl;B=DOqnTcosK#9#3P*vhaah4a0IqYDb;m{n-knu z4FewMUOzO|;d+q0j1j4PnQjD-B=vs~QgZYSN$(E@)jJQ@N$LV_ix0-Hjr=7RQK$%M zhy5>u*g3wWor7`;u-%5L*nsVcG|iWCcx z#cO5z^Ag|wdZv% zj|RX7>1e0@(60ism!t>reAH=wXgJ`2#$!1}S)hf(<}MlGlBzxXL43m?);co<^bGdV z-p#yoDPqP5j=)S#m`?6$AJAFL*##UlNNj(lRZ;8!i zc!_UBk#xZb5-j<9S=>-w+c0ioL;3U-Yd1EGyR6D&xM=d!X?1hz(Ut|ZhR}=X$GrKq z2HAH}vt_9TEn{8^$s^T<^_$nBsYN3NZXbXzGp?buv`Cywq@zgg4Ut$@gwst@$}^dy z#IZ$^UtgxHM~V5R<~l z48x2(^IgpxBc;j}$n(a^eQ2|6T^%NaX8wj?iI)jwBW*$SOWm9e8=H+&S2x2&(Pn6t z!Z}z|Xuasaumwxkt|nJV8`kULB@>Gvbh4O=I+_crv_KtEF-lEvdbGLL6h+RDHq-5I z8mW%fno`fUZr2y(NHYSxh})W=W9a2CN%HV4b+rlcKH)1fI{NXr%%U*zfO*`K*EU=8qA)5EyE2uoHBDt}kk%SX0O* z`1mr-o-+rT#S-)v%0TGq@uX$6yTW3A}%W~M@3Yce38b{H(L+hYc5G|YX%S;Imp?pIUg*#9$c>b8evP|RH@E~RTpZp##iq7}mNPxh<%^@edfbdhG&Mx3;R zD*^!eOD)sa0$abE_G_$0MtDmZ|CJ9l(>qUwJZDMgzx8zcf~PC_<|L!;`7Cf31V$0lIb6#tR4nP64~R$g=n9BU~9}CjZ6CPjiAUOTf#Pl6QFG^h@Ahq={LcNngS4KtaDTvib6Fgl zEDqN(488L?ZH!rKEfAdd2#4z( zS`-iZEsCB{HmG^3-^F2;x>QHH2eMgxi$tH+|SImjFRNj)|aE)REtHP(dR=_|UhyR_Umf#{X zT7c*XWY#bs9rjUu=E)%QO;sRW!*q)0UQCAF{bqGjm07c?q6^~Fesvr3p@`jbcfW?-Eq3<{FG&BP&bTI^j(|j}!*g3O zA|5m|%DU{y*t1~cmW*guMj+s$;ajmC$bozy6+Hx(d{4$)9!xKW7N`{&*^QRQ?#$3k z#A9h4n4gFJ0ALNlR{u~v1lO?=)Og?(BbN& ziKCEZvit{q`GPxEReE}pnX6I8WjOK|-gdkQ-B{ok=trZdqHsyi@ zoP>gixuk|_hz%%7&2YHrGoa)I^H}RRWt}W^w!9P^E@~kE z^e@?kd9Cv74KmM>Yd%TME)+F`IHFIohEy(IHdYIQ%=H+nXSgMiSgLOkiaLRUO>)mZ zdEtzd2pwkO^juAcScs*tCZqCHsYQCR8F$oDA_E9rP?I68cZKI%16 zDK-d414;!XGU`9jn&*M~TV(3b*1PL$u2g9NzV+4fDoF0IR@p1>TvxQ z5+?q6D3|&95mVRUVjFOg49{q*)SBmmwuOGH_96k}a0QXT>MW}^Z@7HLs-5GPFA@Gf zuxi=bTPf(2RxJ_BN%mhszrJdz83-(b&w!G@x@xI`4i|m;m*lJV6SaB4|M=R|@wL~d zoV`tQR}dTQaIsb7OZ3fNomA>anpoEdlnO{>Gh~F?T#F_|@fm{fad5=uaIxL>VNqOS z+#eUeow*YrAeBHFPk&fsIb8izvrGK;17%oW5m_+OBG5O*Zw4w@h6RK^2$V2>;4=Z^ zaGjzu$HZ?LJ%O?X^KX&ma19dZDe+qdmD{H=N^8sE3Z=CcEPgXkc8(Y>? z4rxOT5kz2N(?&N*@{uQP{|mUq(RmIRW5#k7(27F>GG4jfo;c}6f~Vo6G#+2@1xbF- z2%-YW*e?PLQtGHLJeP!+gRL{z9byu0Rcr$u%dZp?N;;N){r14Z&w4^b%pulNh9nns z=G(6u2z{<)RGaHM?2-v>t^_d4!N_R0C-ik9a}4fBp7(>zq1IehD2+hWO^N)r1)wH) zoJr^dVPvh8(C2v|*c@ifp^G4tgWv{FxjrgI@A30-Td+AC!}z9_jUC($sQFPSPNQQq zpBDO;S*2!|Gu#xX`fhyqRiPG4DjtAYM@vk#){_!=ccfa>(5J$AHb@%q_!Th27=-m| zKTMYFv%J+RUS_2RpCICGe#CPw)9nRV`s{MWjxj zibT}+%SS?sUaFCul}`!e5}(c3!oP~dAvGpTW!dEZL4fh$Dbt9qHfs2A)8$|5QE5b1 z;}W6lYSHtuufPwL{Yta+9D5#<;w`Mtw{Qx04{HaQeSyuj(n|&j_LcAkA?L8i@9k`h zW*u&d6vsE;x0U3DioLFoGw|+e0W8>m##7rTNsox^DWBf27!s*bG7{+);JzXd2|MEb zk$7Got~II_-Qb=xwT2C5o4_p%=2=^FhXDTXw8kBXWSG|Uh)MGyP4T0m1fMj2(3&GK zeAjXASg>8gaK}BDNmGyRQtl*#sgoX0X~s%BDDxu5pX_E4fXq1k`flejY0U=fWo*xy zVQURhS*A+$F>Yy&s1KXCVjnm8>_b=;LjtETkr$IkdE6Sa(Q1$qKHjhPJghNCS`o-l zkA3^W&pmf(%u&|Me?>H4ZmTKStKJ&n{G0t+_4I0e!QO2n9In@>W48(tS;zLoKzhfn zzmPr@?8SSvJ;r0!n4{6zuz{k(Pi&jRbhalEhJJ|5Bl~)Imuh(4uLjQvu~)M_V^C!J zlwsUzM6Y9mfU_PirU$b362m~KD1x9geuFfgM)BJhblDv%N=vhuRWnWiDyo?*0F~9~ zshVj58aY(WOz~S$&3sXstzX}OGRMFye)iqjiU?VrUsUE8NPp;@`%Yz!wXXY>A-izc zA$x_$yIdxRb{~?lu#Jkws}Nc`U@hvpn&Yfj{Yr(?hplk9Ig%Psq2i}W zb$v{a!5nYp!mBI@A(;59DG{RA0&_4fb73u+W_88f znc7;zRF*hGVQ4a#jV(HKA|x^-5GF~aRW7i{(*apEB-2b)n1tGVYtVYOL+KQ9Zp$@d zU)~_GWcP_~^k1CN?|@*r-Toa5RfRvBYTE6Ih*$2#r}uCoq&RGY6bB92hU17=W)b(; z3FvB+w!R{<9e)8G5Wj=nJf!l|8Pt02QgIh4blVh~dRk9Al;CdKAB+Oqv9Ggf{IVcf zF^%676VbmJGdV|Dg6L^~@p|WC1rgN_*KwNA9|=5)GT2TM{?-%k508A~aqoxpq_0=S z;mH9ZWu(`IW}n`qx;AkhkH{n*X>!H0bY;W1F}`Q@IttL_|4=;}Z<{RTBE`G)7`(h| zFRC@DFH##)`3nm?@gUspIx8MQ@Os1i`jpb!l%}DSG^;)m>X{#%HAd{gGO(PvUY~*$ zg@v{1yY&cJ=Vf}G%xa8g078*f!`c(-IPMGcq-{sh?N?Bmd{Ug$U$u6UB?R5YloUN< zHQiY0YL&YYU;$A!`A?R^Mck2XHK?9n2#m)+{8&0ca>19lSBk1RDQs@~bWNy!_jZ{Q z2jfsE7OcaSiBI=aqO>z(H{CBO%l#}RGTC|vypmx*8pQNsIc_;8cR0dj?rak}j9Q1g z&ydE9I&;G@yE!;>)`6NCci=* zU+hF$bvlZrcVxC&dc(sPzB?Uep5LDsY;zqRRJAPYvOhiuKMYR{k{^aA2CMCd2RF^K zxsYhB^B#TzCbOi-4ln9Y#z=HlFE|V}xrpkzCz>JYetb~flOjqs>%G9y6HZsHCkA=u zA1G7yw)MK9p>!TSppv>rL%GJ3p*KN)x`+aB9+{z&h@GK>SEuT_FiVKHB@BT=P&fY# znV?QyY+d%lQ+2~Ocm&r@R8d~LB9HldN3qUncgQZ^S8JK0;bqXP`~;OjiYMz@&X#p8r)sG- zuk{Wna*2WKvOftgC3PWYgGFavWQ~)u_>F;HC!ZWpQ}$#F7xUkNQ-yqIgVQ73L#`6$ zQ#(X2lCEJuGI!2^JklQv$m8A42S`$CWLjp-$2N<&?XT&HChX|Go9#vnj@vc0`cq1B zOa-N+h!{{USt^tMctG;GQ_55q|GSjx%=4@{iWbo<;~5Y8x&B^rCedCq9M@ z-+qMB{9`mZzEL=_hVggZW0GI$x`#U#9O8EAeqO1cRI$l&2;~o{wi_|c?!(uI3Dq4O zRi~n;WISGqb$diO|Dbl$beCOHOHM(aMmh$O{C~??!djZA!@OIwGU={EAU zgeQF5kO-T1+8v%vJf3BM6}=7W^(yNGK8uIjLh$_75rkghXFd5`2{NiK)xy~dMMdD8 zkb1WI{8ZWi!3YoMgZDpm&eV+xPZ5;=eE2AJb8P_Fy2Qk)wr z)xUjj&x^nPv>!p~UvAMqWG-vc94dS8hLZ1px_8f~*q7s?z`Ad#BH&_clo;g>*s-Eg6si8DW7CLjVzoA_PSsAjyCrgkY8| zNsMbn4Hm?;tjj7k1eJ`1O%$=0wXGGAVF0lq29kNd&pG$rxs#&q@Be?__y2i6?|#-W z_nhan=RD6T&v{B~-F5i9U;gX^xLeL?t!o6}v+^ecq>lLRB>7%O!Of2QAS2Ma-xTZ@ z;h$GSce4EZ;1PUjb~M1H)9hWQBk zT?U1e+_Q|sypBN6>z+Vgdc@fl$33#I1q$^{tYH##vx>`R=qL*6FkBZZM=Hkz(hY;= z8CTEhZKs8!0}c?Rt%ZN0D@UrY8B1Yjwj{rDSXwzLsts60^{RCj*u+vgfxIK1K;EGf zNK@meo}Cn8R~EgQH=6>@C}FhJ)85I8prg|^>GZ&Qu#P+a~FX5w6Du?qmf6j zPB?WvPkq@y)w5UTES%{(8i(}Y&rmwzjlmJGp&fs*7yLtPp@Nt`M8La;+%~fV#jT11 z=Vp;kT!5)Hd-sm%QO;nLqIFk6Zi+D7bmQUSjI{1@?knYYPfIyWWo&p)@UcsOZfY#R zF|?qEHlhZ00HwwLoK9q|rSIOeBrT!N= zb~E9z*WpW#=9umrRpHl)7+UbL%YKmVvBFx(X_Vg~X43})UH16pE&*#K+s;)=pUmR6 z<^r2d+RkOYR8_!W4njk|L|~V#h7*_k?gsw~+vX2-I675Ip3RQe6%%O_2k^}DC0^*n zR^KUlCh&coZ1>G?)rR=KnjD8bY4YCm2qyNPB5CDP(djlvXMJ5Kq;=l4hp?l}>hVnJ zbR41`=#aQEyTx&c?Lan8TXB3f2;L{SN($`nUBT=#T0> z`g3~05Nudzs5bo7u-mZT@QUFJLx^#Zag=d_aklXi;}Tv=Euyhm|r))WB$_ogV}2~S*(_HOR42Diy{27@YUf6q!oU5_^$9L!#@o_68=;8 zui^HHSrNBKJP`3w#1|1KBYupCh+Guq zqNAgeqlZKnMBAgM!!ypD=+)8JM&AO@IFCj@6WtkoIQpCDpQF2?EioZ6wwQvLsWJ0n zDr2f+YGO9W+#9ne=JlA*V!n>)iZRC~$L7Ws#X4fA#miG^7R0TM`%B#Ial7K4jyn|haop!|-^QJe6XNyp zvGG~)gX71=PmC{(uZ&+DUlV^#{9od4jNcjmK>XYBAH*Mx_r#xz7ZL&!tO+Rz!xBa% zlq8fUR3mkHk|oKFy~VOFa(#X8Jtw-#F+);ZSs z)~l@>txeWDt@l{>SzorkYyHsrgSFcllo+0vm*_~GlQ=(dapH=^jfqL<7w$Uz3N~CfKIiF0#F7J8tW;d2LB4`6(k(N>XN} zT%K}GN?XeAln+uqN%6q@j*uFV8k(AzIwf^R>cZ5^Q`e+!O1&<%DfQ0Ods6qLwx_5a7%<9aonRjLG$$UEV<;;&WKhHd! zsmTh;O3BK|D#)6aRhG3VYjxJ&`uutIIRz#pR92o0?aew=%CO@AkY0 z^Ipj7%=>rVS9zYi(|KKa-aO;rl)=LWPaS*(^Tcy#@VkRU^4I0JB_Y^)<_)OuU!jB6-FZ{kxUldoAS9EdF_M#(2 z8TKOkO#4FnI{S6@gZ2;Y|FNI2NAk$=HLKPz3%jN8{7{oZJ69Xuxwf2W6IvVwxD)ik zgRJ-MWAqDAbG#&$$4`-5P&=*zNG`tMiO|c=)f>F9l>V2{BD>D( z5^9s?;#(E5kWyH{4LPO&hXHUeAa+ai0U^c*Pa$df+UWz-%t54+{6IDH<|QC6ji(;Y za>*~{1aCv#b#wvt;uMYX;@8hTvRo3PucdSy78DN+q`^VEoJI(Q3|7J_6T#|WsFEex zbcA9tn^0_$??EOV0=X19g6TXIjPp=yKx>G)eNfv3aJ7-v7B!V5Ov>;96J}%el8hTaNH3&*{5k0TC%4vphJoCq z>F)^iv&Y=w_*rB^ZdQiq`b?AKEd6`FzV2ti8AVgkT1S3^>wuBqV`F>VI|PcsXbv@$75+DFpG|ijs{8TlPpQ`eKIH(+illu$Uub|Vl zVMtQ9`LAy2#MR?@y4mp)9l?F=Aqa;$LXC7m`H5~G56Pp3r&CalckNm4+B0pwNq>y; zx%B=N28TyjD)qQrs@ZWyJ?VQ@&~(3YoF^LVx3*(=6UVzIpj^-SYCEs0jcWqbeFcaY zWC(V81Vy}-By16G6dn|w7CMDbgyVuBhKOUu8DhD(MZ8V?yZEHoA-*MkEPBM#VwV^Q zcRUH2Vaze)R86U-O0x>CAwSU^(R69_+6Zl|c7gUb?OyF+?I&;vd0H##3~&jVp&Ozr z(2d8@u|ij=tJQ7NU8nntZo6)W&QduHmdT5+tXh&10>2eg_-`1ZR*pngDoOtE6Ei?OV0Eniv~jfV`ATli@!;R{~|TcU=m!#eZeUX^d!9w_ZFC#`_7_98;&4%*u!1 zqzw`^Jkm|NvTE^i-yHlz=}Ll$b21urlI8T00*#NNeY#2y6<`XghGJFNP?P^|w^9aV z+f!>ht5G3hSFMt*L;-nI%jF4xMa@2fSHZ@H(krKct-o!%@8?4Z1OnREx>qYTR04nO zrTlCJth3$>r(#qqJPjhJZKjckQ2`=Hd2qbPJUeBhj&inima{#$Tq#8h2wzHEbuwn8 z`sfKya&*YnkG8&{*y`Ko^cJik0lgyTuJ_f)#!f-pe9X;vPC~kj%U%mYKV{^&W0!&F z2)a#fK~n#!Abl6r-c&&vRK1$rFVB%`{yXF}#&hm75VbDo!QRKpvOkDzLnz)1ifAif zTPkK|p{4=J-dc2rEC*eO`s>a|aw4$uKkLpc%xXDCCQl*FFn&{u{Y@Epi0qL)MD|Y< zm-fsj-&52diC{nl?A7NK1>f@vt>>mkq5+ye=^GoPK%yAtq4GD|AF#UqMl-?JFE$qc z&S4BR z2-}4n@MC>S(1>wjHUfc-5T}dt#ij5axL15nJR-WqUq!PfSQD#B)#TyGGD>q+6Q~W- zUa8%vyo={T%R)0OEK=~n9=)IHApSHGlt zOZTbnOWhfrK_8%x(#Pv_^o9Bh^po`$>lf-*>Nn}H(_gROuHUJDKz~sGs{UL33HZ4V zG=v!v41)|q3B2E8%UINUhSIMG;Uyv(@T=rnFH z-fFzZ__*<9Vw{*?{l`Hy1lu0kXMUI}jb*K_2XYE;l+iHVU zS9Y_0=GPvRN2K(hXIvHor8d>VwQGz-uPIQS#xof{Wd zTultZL^;-5CLGFC*H*2m#%u26nX_zFE1fGA)vj8TPfpHOujW@3L}!EZlqK-L0p|rP zmcfrBoN5rFCd)EmNf){9dGNzg`PjkMMRss!fB0Q8lQ}V{USGTD8WJ;S=7$J;YpM{Zu3}zUiMG6?R6BWUxn{^* zZBBlUm?P$E@^dtkChI3nL9%wzeGQ^MDp0j@b?y3m-K3di^M=e_wqnWRMQbpZlp{N> z#1(W29CR$JW`12TlrV#O*W=%HFZ-rW9FQa5G9ql z$H>=Cnm#L7#>x_S2dT=}&6!#a1yw@{*E7zmD1@Y~o}I|29DuO_0Tmqi0nWX`pHggDl#Ti!03KPOgrY zYMeB)6y2!MPMTAZX;TGIT(oBKl^8eBR1NomHKG7HqcEJez$cTp$(m0)q(~ z<8Ag*I0%uGpp{WoO;wCfy+Gz#8}l;4YX|+3+6OVxs%nxl@TR#-CA!tI9Q;|6KM`6V zOoIbnMIeD7T@OY*>lw_5!SEG>Nw+C2$_z^HLcBhHqAx9;QIa1!$u~H4fX00N?9$@$ zN%(uo)Uw?Eu(G6TupIAEjTsZiOrb5>W=926Knmk+^VtoetYp%xg=2}h<>A$?Uk&s^ zQH7#VR z-KIrHv>1oJY#NQJY+70IH2g(MR(~VwZ&-sc8o$|eyO+R^a;++o;0*b`09OD8+S{L}JYGMU(>O zdP7d6r{zoNT=_1gFfD@lSHmg6V^$yVCkpTkmiP3~IfI0P zaF0z%cN%dKLQ1f&EJ3(us9N|!X(5oxb!=UAR&?j70KSm{aBTiq@YN*Ulem{T*7|CG zx(@KQj}g+{#pPB;NH=WvjX0NH4g~osyGVoRh=ez)NZFixDVgf9-AXcCWsr!h7VgPe zGr!8ss2(+uo$896iTewMEa9=gS0MIx!}$1jAsgX0(9hh339ME&Z6-P!GtKKU{q>Xi zxvd}n32v^q#q~G7lkuu@j5g?yu7%WrAJXOefzkW=Vl)*!k>)jqAGmwr&vO;3Cm)3} z!rJ;rAAj~&fRy-@tlS;AgtYC)saPe$E+?YxHCHL|KE#BnIzCO)(YUw^H}xyJG~_np zimqn-2PZK&>3xMFB1-PU|d&is-oozyoc>yOFe2i+|8je6)QzVHB%l4y5RrPEk?4KQ#a&4z#{n)OIXk{pM zm~8@ViF_nl>4j^eG8S6$rM;y@NhHH0q)U8*C6~sE`9T`qCVu>p-6TBgSy9&Qe&&1# zFXfsh_dr8E`_8-q<>`1`}i{8}6Kr%+XKH%4Dj|$b3 ze;?H~d>3V`#Kc#uS6X+a)`wNCdxmyPCtLre{SycqPECL2*R(rBDs%@{sMsx?wCFOt zQ&H6_MJ&@F2auGVmIzj6Abw%pQ252KW?x%<=h$i988S0H)E-(Z`?STHQs0j4g>=Rh zW@q(j!0h;s@4dlVX?<~qa*W)8H4df@*vgcC@`p~o-b2gUw>MC|JX0nX{-q#;^`JJZ zR}Xx^b0EA`fIX9x5hCOo6YKWbjd+WcIY1>HjZ3>!dSc2L_W7Nd*usvLFaa;1T=_JN zelgj*QRLm_Lt#r0KQHl}#BX`$KYvwG$G%i5mAze*uWAmbZV!*u3p zqu2ookh0S%DXr~`2wOMEmE(xQ@+g=p`>|a9ah3dI34XK<5{g2QkI}EdNez=tOyc^h zT#ZscLo9!ZbX$~E*TeD%+5H8Fa__h9S5^7D<$Pcuk-GxptwFX!Qle7y!S$5f8sBqH zlEPi%ims-{>Mr_qC4OB+FBk)!i=Bh+i=5dK9X(S7aM<>%x*AYiY}j7iCHTZ5p7&ai z8h}cjAVoHHoqi2_oESarlmC{JRdYZDDm^&kJ<;_Mf$$Ccas*58?yc_f?p@KPvd{UC z3Id_Ey?d_$#Fbribo`I3hsMUsc5wHtWacZ8%~2{UZM5ww4hrKZ)wY+Qi?R)yw?`$R zlGA8YFKb&PKn&F7by}f1LZh8bX#P$f7HgKgkh0MR$pKvWXnhrMLj$F=u22H>jhP=G z^jKut4%34<<+$Qy7(SKlCf}%%C`%gENqP_?=eE5VwUYYD0QoVc(#PV8#iw2?(BOG* zc@4ZPcw?pm%@m3*^Aw!=`oh!uwNl^y^f{Z;N-_YLOh{dzYcu|9yV!~_$Nyn@wGQ5d zE7gY}wve!aG8&;@h|}?UIA)bs)Y`s;2<7N7a5kzNf;{(rqYnvr3KC*{i3Lic*1c1M zbZIT3^-~ft5LYS%_?|k3O0gc$#Z?98x=ik{uLSG!s{Tr(63XwAOR#B!D_BbW)Gv{f zX%An67&k~uq)KoBhVE}kd{tFwtdJJ64RSJ)iXqN8Q~}dM+z)dAy3@3_uLc5@^-Z2- zN^EXiP18HYC*bH8*p*BnQaJrkF^(hN?o!_}BFn>iT}(LkadlcZ2cEbffSxILfy8H0 zwM<;bP|8GD^o!HpvrQx-gnZCT;oT{{R~J2e+WQ$PYfVPT?eJlJd6$T$*|@LhVzf<1 zm;r92Ooav6SZVN=g>PYFr~4;YZz%wx>rtOjoAEoU?BIYSdB0QV_VPY<&QiLzxl89c?RJnMh<2Jd3M9le= z_?}-PC+5xl&?Rd{Mc%YY^+(f_;QvQO!37W(ukMo8YLY5MyNm{UlJ=u!&nmjqYDuWP z6hdWMt$addFg>&fYD@UIc}dRcfvAZMx_1#ShwhKgh?>mKJJfZNq(EXJIZ&%#=h(>U zxWEgsPdefGuIEHouHEUNZ0QmSVw7awGTo2PhU&Y#Q%hqI?vhj|p}xk~M_L*O(b9Mi z5r{-h!8A%nO}qvs=?Pa7C;A|xmBhimM5~ghBF0oDQR@!;!^D_HrTQhtfmYUw`YXYR zaUJC-Cv4bi4n&O0`yoa@68qC1Be4y?Phzx=u#J^15!5-CLSo2bv+7Tq5}~oxq@Pud zQ(LRL+W!sIhPBL(+CY81s4WrH#yhOg96O-@F5!7HP=LL4ieS5Nu${czJ?=MOTq`D} zf?kzVNkfF`L$9eqxDJE}@jV#B2b4HoGu}o|t9O~Cr`5Ym9gVBb$~*W(n)vf+YHDDs z5X=!@`;?y_z-(;eqnjESg;u|$bg2N27jz3Co0DA|=nIw3 z_ynhqi6J}}-=?qX+wrvPv`ICm`D&&Tygst+sBcH7eLe&hdtKMJf#pfE4|Me7ct_Id zowRD@YKkh84-5LS_>U~<3q)JO?9~*}=>l8UysDbK(p7ozHIYXFf#9M-chS7kVj;M4 z1c$*hJXCqjl_MCID@PJGZL-3-&8Kkw!@t%B?zRWQfkdF}K%&F(wb$1PU;qW-eoGT^lM)r7EZd-ave}gYOOnk+Wl2P zV{{F5r^vGBL9JAc(ixxplPMrJIgU2XIo9Gh8sIqQ3;|*s&iki0>w~X#YH+!59Br9% z3`tGVNXxj^32PT<%d#q3>rSBAxwr?{*L^M2nn7zrLNE#N-|-c^#zCDPjw42bHvMs- zYM!gn11d!1)iO=`y3?qZDblxpK+}>UPYXMJpgPE9UAb~1zA-PdS{yTt*1#Es5*=}f zJTbm@T_fZ)6vlazwT;baNC@Yx(Q-DM%lf)+n6Hr|ENH_)>d{!aamg>p_q1VtOgXdV z9PF61X;S=&`nvDu!JAjz_r;1h-*JRKnS;h{j&Jb$BJQm5qaDDV=>C}~^8eXU?itQy z5KN7gK4>B7a2$b1FUTp>E~y_M?97LcQGAI`6MOb?KPm1EadN}$ZI17o9p59|1mZ~2 zeE2k9eQ0NAN>nL$qV1(l3->I#O7xiE)Cf*mjxYtu9zB#EmpF9@xDFR3M~H-u;Kx^F zo3>f#W3@q6AIH6p<7gG=Z>{?RO<$tSfmL#rz=SN)0QZf6uI6z%pHBrL%OjOj>kmwI zBBW5Kmmg2v8uD!y zRYlrVeGJs1r1Z;fC%{0ZS1;ca2KSSU_~PpVns#nArV zBOVmrGiZ&`#$2XZeX;RM<8{!g{+sbx<0r;bM!}S9N;egmW|)?k)|eViH<|7={oVAs z>1)$5lh>p(rcdmR2ZxUdzc74$cojS*YzV(0 zd`I}s@CU*l4c{03TKE^?--Le$&k2@@tO$EVal{o7TOyhwc0@cD@nXb>5mAxJkrzc) zMb^TH!hMl1NB%qVXk=hiQB+A(MbwI@wNYE6?ufcS>d~kJQEx|m5_L4{bd)YSC^|ek zA$m~snCKbN<w3i(=-)td6OVX^Ghx z^GMA8n1eAN$NUgui4BQOiOq<$$6gdWC$=(nRcu4-ZLyEWejNLAtTxURmlQWXZc5zZ zxGUqf$Gs5uY224_KgJp31LLFPv*YvQ$G~I4toV!L7s6-44e`6;_rxEHe>48e`0ts& z1WQ74LV7}e!ia>a3703VNoYvemasqJl>~Q!#u{Xefro^l)-l#n>tgG**1s~(2=`l` zw7zJ4&H9%0ed{;Y;OD6XA~JyOVb% zKaur6<(8C( zQx2rOpW;sWG39JZcS=xdLh7K@oYWzy7o<*3tw^1hTA8{kb#v;2@Q!da)tDBTmXLNq zT4`E!T3y;d()Ol3mv%VqyR@IuhNO>6pOIb;ZwS@tb?Hs%x1`^Z{$Tpv^bga&h93m& zpiP6G9`x#z1rLvUX+d z&f1&Rk@Z^E`&l1neU~Yx>vv10NG<$FMbJ;Ivf0XUb4$g_o$<7&@Gd^cZ zPI=DUoT{8vIkh=;Id|tgkn>E=%Q;Wy9>_fm?*|{`ev^AT_iU~)FFY?hZ)n~Hd6VJ) zU{>Dcc~|7E&AT?QK5tvz&G3B?Jeccu(=Jj-_oyu=&d5T|9y(q5Oc`lMZ+o3ZBCCy+ z&n{fspT6kv#8WB1t4Qg}qY9Y_w6@2yzoG1}1%D+CIr4MV+D^%mgoEYr8$ds{1;NLL z8EGAaKCsC~79tHyItCw|=f%xh_hSOQ44$7dg|3lsv0gRM0(;l_}}+4DYXu1ut1-(d~M^Z0~zk_?<#+f$R94*oLTK_KV5$6|rrH0Wk8p zoQzChJ`EG{w&0oMCyrt?+ihzK?A~=l8|u!l+myNU{pDo-(p8t(JjV-I6a~7rMR}Qd z3c$tS6uq=*a*N|^ljA4I`imStZ5{>tcQWER!*)H_Hd)D*4NK`phu#Jo8FZz^ zaR#NFZ@PC2%;o(pg-qeX+}6o{)K0@-)@~}1M%e=|0+`oPnAhQ|x++mo^Bmats0WF! zDSXV$2=7i5;F)TVb(S!^qw`aIeNM*!sn2Iy>8|8z?$zhB)Wa`jI%1PoU*`>i3v&s@ zKHtKtsT0&}#x^~{;JAGTw#etv*x81`q`UnXY=zN9YKkE?X*y`^V8 zhtShI_iHd2MUJx@weE*mZTO9v@4~g_42Tx>!34^2b^?5lp3ilhm6Vr=m=x+kHpWXm znS#-5#E5B@N~Kx4q1TAnoP7D)WqQx7Qbrm+J75v{8_3&n!wDuTY}tCGXH>w}qdm1_ zN3q{6w;k;vbT#QSnr1VQg9ncEWVCF(PsnJw?S6sSsEGP^@aLAmQ$WWteTiBcxHs9@g5z& zQoH5>lHFja{K0VuKRMva$YKH#K23yAMIF%l^!T1FooA_PronlImlhmT@#V~(EI)#K zYQZ&xMe$~5c{AC(uwU>tG97{>Sc$_hBFkvpIBfXb;_}j|r56_3HVzwF%I%iOHif`h zT;Tl55kVEJYGK2+Vp(++?2B+r%?-+RtXi`UwoWY3GI-*m#mm`GZN;k9hKZ|cYgetb zASQElElbr+hb>m%)asflIPGB71n_vs>?5!oL8})nCiA!ID)XcjxH{3rDUbwQwk$TV zY~8FyYpVitCLvfjEH}FHLg@t)gn0&{ndo=I@hgQvz+B# zU@O4v^7~Y3ekvItQIupd%|gI)s+?W2u0iw5c%KnByefZ8XHMb0~fSzfQ4V$MEYo999{{W+-iZzY--XLUngQ5Th{Wv5;z;(4%l! zQ{&m5rtMul2iwo0QZUd1V4$rJ3G_{y8NY_LpJywR0VK`s-szj!y-WJPSio+;0>+Ye zzyeoR3%0hlXHbVUeo|v5A@R(Y;K^cF`bnm`(h%4ihB5@+Yx;}sHg@&2;NKQ>8$lq@ z{Zp!MU}gL99ygg^lamt?^qw=lAWM*18h=8$GfKJE_B`sI&98e>XB1oho3N#G)ycmI zULa4dgyBe8a^x-@M7t6mZ+i&7-sJ{4o_XD^?Gw=~ThCQq0Vs{?RM}%HgV@&P8-#ly zA|EkS6Y7+iqor@_{ct@x0jAE8K3vf+PBn5Dn;JQm_^{HYISwUE4EDnW%OMKm*Jv3H z&spFWf(}b_WN3Utu+;+O__lRS{0`8n zlG)T~hhHaqkANfTW=xnJj$SA9YL=H|vpJuEcfP;pN%j|#|$^hy~G zt?f2K%Ub!Hdq9>zM^V-mIScP;^u1O7_5)>E*UMQ_B#qnUZ$D7hfxF}^sRMtPzx#qd zEoZg1r&0%AlE3?c9+tDDrQ##`yD#WxauzNqRI5k+W}xl}lRd==a|TA5-Etl$&9-l` zl9sFd12fWee_^!eI7iE~O70bij$M&PY5nBv$TxL=&U8OuwC6h4C`GGyQHcgg@!X7q z46`yPpPUMjk_Sb|`|fazw$Kl(KL7pYhK@!o)tq2m z+bNrL8E|kY)<}tWs1oxu@@A7tznHl~ECBg7GoH2?<=nl4%F$7qi;&sMjsaDk?x(T0 zK?=0;yVQ+6?>j8me)R3LyazZ_vDNP$zY)2&NfptosWxo&JOGuq!om1i^5os3FuZdj z74bi7N#D{AE)$IJa3jwf-?lw=;!`^QNF<{oDLULRUgak_zY_?j0(Xb6E2VN%2iuSN z(I(&9{3%lDcAsua-KzF25`5R={2`O7e{KJhA^39;TN<$@xF6}RH-Ns}5gPk+=aoL% zm78b+t8tbb4}PIlPGY^WY=)h~8G$)-y?gCYPM1!NC%$L>RqfNf5-%$79B@A*+RK=r z<$@pFJ4AcAbB?lhP6h2{|L|Xt>XRoqRT2VK#N;j(5s&~{5=HQEGg4&Hu0x=Ifb*Es zjv&2E5F+icyA|@}IuDFy56X$E#dI5vbG!pY4IUaYE9BykO`)x!H;3LHx-;~t(EXwBh8_!z z4zq;~3Y!o%JFGFRCG7sN7b9Macq`&G-c<%g=0p}omPB3|xiWH7sRVIT%d!|B~9PxFK1ASxdQS_o>Ty`50CFSNJ! ze4vmWG7r&!tulgGs5-u8Uc@0>VMzp@M5xlpzVEc z8s?g5?k$zAUi#54a^`zSh0pYk3Z2OW+-;A*I|TnVM3@{|6n$*@X46JXk>Tj_wIqK; z@Gk1ZYo?7uhs}pfZCHp6zZM2rXFw&c_b$vdV~NDZt8;6zc~us@JrAazEtz4K8f2L-M?3I zTU7I$-atrm^q>pQt*8;*#NnmV+X1(=t#zbucuX-Are`Ll+scr>LbtoA+uikbJt5Ae ze64PFAdHo22yo`*r;S8)0frz7OHS5AGxaIg_kL}8Fg0X-A}VGYR0=&4JeU1XTY(;c z%jj2M|E;iD=;qi+<3WRH!_Wx&oc!WhlT7kLC)SBfyCPj)$=AqnMtXRh!RVL5U=%W~Ngy6uM??=4h-~Os5I?4>b$zRza!Kw>+eokJQ(EAu zU(F5=oF_Irjw>z{>C)Ydg;PN?(Y5l?tS@w&SR3k>vdwV<(^6k|vS+QvGt_4n<$kQE zzRoSwntDo4($VfbyvTXicCmTA7q`r2hnqjy(b7OGl1_Gmr_&s)3pU_MCme@5FT?>P zmTGZWTIK}e$**Y+9!r8VnoC4`v9l2WYU~%1_=1i(2kXvfc%S~8h(Ei;wtEo2jydS2 z=tlmvxi8m1vFtKlk;XpFiEYnU!D*`Cl*p{E{L6WAa8`z)gAeu?!5-}o*4-llc!Au; zBxfADx21EL(0gc}k@lI+VW<@IrmlK7RsD#FI7X8r;p=yDq<>!!7|A}vSs>S6=HIWg zR2Wa){fvF72wk~Ba=Dq#7}l>piM{*f9!Dp11+Y{C9Moq3?noT6okQgsFLtK-hS9wB zMldp2a`o!{7lM5@Nc|%`I?-&>BxL)Fd7nN(132FA03Hy4Sic!NLcm}32kcpo!P=CH zaTcf8^8S7C%(f4cX6Lg$gY%5B50^4EeNf~{u#b??lF=uVmbySeUs+%$N7n`8@!X-W z9GO~K!2S*kg-)A&YH9JL3UWO*o`?ILEU$o*m9re&4>HB%ols2P$rY1Z+n?|G*ILtV zyDE*mWIs=g{h3)=fSw0MH9JDpmUKrbm!0OATSNBKbxclVqJVnTF4V$j0Tp+7RMmmS zc!BSg0?fM!*1AV%?fXTBWmh3S{tWU0N1hzlz~$eXWsAufJ#!(q0uNyHjN`-;SWSK+ z^s?~-Pfc(>xCT#8Oj&T%YVwR%Q)s0S$>c)ZMs=W&`hV7Cwd)7WwX*lCMToAvs+v7x zsjIOg8lYA9htMI_bv=95qx7Jd<{bW#iD-C3zlI4{J{F!a>m8+KFSq`d=#Vk(r zB=&bQ`+Fh#3(!0Snqz-wOYx?sR~9S;iYW9n0!uH%dtjl>a#8W5$rny9pEWxunb%D& z^!z#pM|DgOQoHDiD&1lrEObdP#2Bt%$S~uXln+~9Lt`}4^svE1*|JCnbKHzY%d2cM z-DYbl3v`tQaGhvMOB=%eFAf%qbhBrbl*8Bj6fsY%h@7*mY8_^s%`ZKB(pxL7_(v_$ z#pS5ww=OOeL)=6@YJMQa>d!0^d2>O*o?`5pEHh2c#l z4jS+&IbV|V-Nv?=V1T-c10`HQv4eCwNVS|5ZEn1+8}W8i?33UL;A_!7d2O`)!rE|q zIX>URV!zhN7VlR@*K||?=?`jCu2#ITb1kC9$$R?O1M)*$g=w>uzH{Z zrv>ca{SNBr0At}EBH5g8&k}yTiaua+TWCGmq1JaAwPn@;shck8U9!)fU#1ZYEVur zb(RmE*q6STLSQ+FBz8}_oJY({Uo3AF2qJb5EJt`bVqN-TdGVP1XkR&ET)7;Zi6AiB z^x9zD{ViN%pmmRh4{dN|5TamD2eu#3`b4%J2Av6Lj72T3w-p4CEW>v}*$k{k6F+hh zNAv)&6Ux|;n_l2r+pPdnL_@0LgmiokP=zedp@x*wo=Dfb=vkjSIr&pVe2Mswx=%|) z+beNQ4NmL+5Dyr=!9G^NNc!QjFN2=fa3GgQc#MaCY?j7?{_ybAJU(aq`8$i=-57|d z3RxN!fjUKbF^N%LOoGthcC3=#z47PUDBuXEt=4ug68YE}sy|gw&2kv7<-xb#MYv0n zZZD_+7T4-(q}l4PiV5Ua-b(?j`9mlfd$hJ6r~1e%7k{Le`^Uv@uWpiXHBCI@=paun z6Cv=%zF3Y~hKlR%*N8TY z&9-(Z=P5wK*bjeUOz7P^5sggn`tB{h26m$uw&z-05QvRX0M>}jjTunHWX>Lx`Wpa< zExZ;dcj74kG7EJI?yc@g-GcgdZ1M!gWADT>8+F2!AK1ux1c+hQm@M=Pn_a0_b#boo z!oI7+%g_iz>e@rzwXd{owO)$=r}5|Ad%HO$Q3xjf@R7+m5^eUT%Fq0$lDHB~r$c94 zU&y4=PoxuZrC}yJo5JC@O+S6r;zcVA6;&&$t7_?xR4q%ws>NP+;NJH&evzVudI-Bv z6+6>0B>7tGyfDM-EMbv`{BJ+*P#yMC<(@i??vcJyD^Y5BKetFv7VcoG`ddmC4s_Sv zqqUbfhs)QzS^lLK4^(P{*6tXvRMkMGCTrQ^n2#GCzg13h#@I{EoYl&@t-Ycx6Rtl zD(HpjTLpUsc(WCE-t!qPC9^XEO6EcguR*>3?RhR%b!+zj-Q5b&K#-si023t01kh5l zXaH1$0LuNR^3nky-H(yLVYxgblbxB$;8=Wu0g8D>VUGmaoX@D=G!MM%G6PNi2=zp` z0{SGnCy+E^wcK2p^Ky>u8Nl{TU^}Q!3D1Q3@z>g@iHN>=DjN4XXM!7M^urDA!1u$zE6;gTP*4{Pw7yKZ{%tO{|4h5ngYN|DcTpR0(L zZgUl@mMmIdW19rERJy;@QdKBR@Cr4*b)V~XZedSS5w1Jpi3!w4hSv5Dx~i~a411Hf z8z8;T25(|#oWkra2-elAykFd_z%nn+3}|0H*qKfUvYsUzp0Rk}9S~Jogtg;&UF^_6 z$AxBxg#_+6Fc>zcBA$1Wlt9-uYLo%ao1gn)!n;k49e4!q)!#>yKJX_RD$@c$Que!= z>1?uE8V5_!j~)})21AEC`o*+2Nav0Z@D-B2NTH|U-)3^;{`!la69tKaS{mcLE!z{k zs>FHoi{5qWie9WW(CF5U`s0Pti(Yiv>f2Mjf-}xFN!}f)0|;I$?~d*ZpijvL;M*GE zSG*SvcKhK#+7cf{O|C~Nhvv1xja9|B>$}3ICRAPgZ=-H zy)6~Pe6w`bI=m>2pkQBkPb#)up6{5RU| zzpmd)U6?#~l@qZTC35aB8X=uNuON69hqn;&gHpA8dNeJ=T2~e-Mvk`!T$I|d9;2Q41N885CjZxmc z*L1agn*o0kjT@l^OU)tjY8P7oIlJ)=Pez8!NK!Y5f@PJ4)^;``-&1I;G7iZ#RZMGp zH4QqAG8hFDe|wT8sY@*7g)^@V_mm2C1buCJh9CZZFZo0I3@zO1g zlfm!~FTdR=D+;f;4(E1)hqg#ro0%;&JYzF5nj7ojA;_1R(2Zc9; zpM)MkFGh+(pxQM}oGmU9Ys4n;Zt-ELcpVnM5s!-^LbDCmjMGfilxsF$GfjP`F$5Lgv%2I3DY-zIGV0pl@$MP)9 z{@=EIVCe}Q8B`cl732)s5VSey=Ab=6Zv>qPvIJ)ZJA&r~FAZKEye0Vh;G2Tq2>v$s z`(Pm?HY7D_{?w}kv7*`_oG77Lq~>Q5Ly~q8M-XA zIQT){SDj4YB82?6m zbV5eL(1ei*(kbk ztsh&DSl!kht2WV;czx1qN$)3p4iozylX{XI$unVEzb<)eax={8A4=Yx{6g}-U{?QW z@|Vd+lMM(S7H><2Ymlk7%WZYGCv4By4%yzcowjLGj4AOc=_%RF#C~eZyp+n6#VKo2 zwx-;e@=(g|l*1`srJP7PlcGtDOHE51oH{&pCQR%Xr(T&_lX^|+Us7*PeI)g%)b`Yu zQ{PB^H}!O?kfu)yNwcL5!t2-QG<#Zk+9he1rmaqc^NX}Q)9y)oBJG*9LuqfOeUo-F z?T57PG*fy+dRqG6^wH_|^y2i3(&waCrmsognBJIvWBP6Bbc-4#KLL-@{y~Ay#kes% zB}g(KF78;?=QSF>oncPEbr9C{$@Q!u`93bKTRLy*n>iZ-BA&UYZ{`?CcX;MUeKQjv z#NoHhXiaZ<6?`$EM}71QOnt7S?jQIALz|*2P)yJNhp=AL)!zH`VtW2x#5E;)-J+ME zcYd%}5NuVyuwx)M;3N6APap8oKU^9~dY@ssFCx9>J|lUdPc5*ifYfA|e5)^YLei=X z!>P&ej_l`B@BUFh$FA}f;(g5QQ@dvpdciaM(PPN4&n3kSsktqk@1r~ulKNxJy_G~6 z>Au$Z^f~&rwh#h}5k5GG4N2jV&4^Pc$<29+T9L=Y`XLvaCE>K8PxV{|5rB}-)2Gg= z$e%T-99FhAv4>bhC$oqSr#OmM+S=X&Vo<3sDv=MQ!^waVhhNpncWxK`Vt4MRb#kp_ zl)>IZl*2%MyNH0Yu-nu%H)?t$PgRiC;~|$FAE*R=0}-x7SwoH+cQAP&iS`90Vl2;4 zbeu@)4^5QW(w0s`l8Q3%M>5sNo<`{KEx*MD<4^&fmINmxy4H(5p)hU-9W$dx6tFP;nxN zKE)3-2)^=xTKh;RG--clNRg^O5ku~Y?A50OFQ_VgMq?lK2P&1`IoUvokMQuhFHMd6 z1MjOUg|gY`|FTlzU#iq^LJxeVsx(MrAETg;t~q|#rv zn3Ggo0f>b80a87mwCeS(FErks3|3BlR88GFAB^5!-=ZdFi>Cp_%rq zKIC{{jjH@P0ejehZ7tsw|&31uu&$Xe_~ z?Az+v73&e475>wpScUkdh|Nk4&#>&;NL44_26*~ni!jP_F9-A-`ypX`)c7F{BNhOkBZ;sjo?rKNF$HvnC64w05r5?8t|r+zT84NWq{0F-#MlE|HvQpbGd<(Ns# z#|)7AS|Hp+bU~8H0%=C(=h$ox@(!WGONtCp2Ja0uRe8WHMGIxvowdGZ)#?--p*8|# znPUl6QQG35zdBUEF>1?+U7{>YXNrK9UP^z`z{szL>+iDq9rsSeZ`FGhRXtjw5le_h z`vbE^E+C4|T{VL;ELbZLz(J z&AkHxci0!jatApqlO}}u9|}I!L%RDuRPcXh(8$8&k%h}6tA<2{ZnQc%ul`hP(FKo2xlAhbVA9ZqnGdHK+|^#*Beg)7_+5fKe1n9AJ`~;=By&q&6!QKp$D2`8<6B)V_^+w)4gC9t z!Q)%Og_fj(Eb4;5oq1t!8HZOj$hw^Wr1QpA#+3fTU|n3nY47iL6Wlv2;*!CYNxp% zwE7Dl|EWv~-!%4;(Dwzo6nnxVIvF~^qfRv=5k$UT<+r`!m8Z|*mfg1sdc#3EY!QHF z`!a~?0-KsBBZ}Gkjw&B+e%QOtQ!>LM9?r2jobZl|@ZiaRelAN8*V3Kk#SjS(y`|y% zu%>4ZVTg%jLs21H+`|y**fZ5U; zLny08S+zXDzVA#d8SIPwVJnyP_CoUNrpDb^eje>+PpwUjW}Hg`ye;^*1^+fR2H`uz z>no{;5js0lvy{#o|(bvRvsmQ_dNz1`f| zj)cT}{0ZRVa5Vui7-e=l8~?_(qX)4aaeUL_TD1Ma?#*Omm8>ZO0A3@b6-~iFMN?3t zVI^7s(Sibg8;#TxB5rvxBoZkCc{uSTw!6DFuL8mecFT%B#7%N#MQGl+omzI@$iUbi#>;(Yu&sd(36FwC8tws! z5T%I?L^2JSaKU|;v#sC$0_r?d-wujY?j1{MO7_YKm$b0!De*fc@%MSPpPiv<2|Tj( z-5LH@c9qBy)CsOsF)%UtC_g4=?W!OKWO1v);;cwt27f|k@F&3FkAKg&dOH~Wr=Qr* z7W@q1KkGTOwYKl_XKo#owtTBQn@fecrPbknX?6G=UjIOpc>Q%H0OiX{0LuNG9sDVI zV2T`=*B65W@1nU6rH-q3oh8O7iGPIGuc3O9P0R)|Mon)W}-6{}aR zJ1J3FwK^K__hZqh9?swDZM41}B%!e93hMF>xn_wy8!7P}C9yyDRNYD0{j{_qM$(S! zbpc>o*#eo;7l6_`PciZyhlAKqPV~d&!^_|N$@~5|d2n=i@h9)r_Is$8j}ZtXB$_p% zdHjLzJt_NXC7Y({H+aCbaVastn#&lmIOj2exU+oVNn<(EJV^)s0grXQMbopbp9vvf zfleGL*?^w&>#?LYc0CRCMI~pz2`QmzDPa>*^2aA+)JZlW#RJSjLBj9O!UO_QW`Wg4 z5!8K?!S-^80`-5&Wbnxb>RJD$`}L2Zp3eIeBA~UM@kF@-;X5O!d5aF5W+6|QC#(~0 z6&{DufJcZFi^ZAn1aqx;hxoMknW)#m?T}`krbe>`>H)87zSNktd0L0IOgme9nRdB$ zhjyp-DeZgO&$TDD=e1^Cye?grtsACu=&E(s=r-xL>e_VA>kjHZ(w)<3^|AV5{WN`< z{$l+~{dWCMs1N*8|B~LL|5@Lq*BD|9g@%cSxrWV#>kYRW{%$x71p+q|2qKNy#_7fi z<1*v*h$8TJ<7>uujmL}@Q#jNJ9Hwce=iz1Mh{73P)pE_h!~&?rf2~v!MVYA z1V0>nAo%s*FN1#$)`!H04klRD<3wbbPZ^&~Y^Fpr)-3H}?-B2ue zKlGc>MH%|34}2 z(zqpYHE|7b+v4tsyF2cyxUl$ycpLoxkB^@O-~X4#Uladme0zLn{KxU9mFHpAopUDn;!$F0vD9{BNyUy0cJE_gT0j9UK>`!fCakf%0vgFwoJsfE?j*r1r&u1b%b` z^bg-^1}r?kzqAQ~%2+LwybX!c8;Rtk_HlwMgcr0m7Usu%iVB1@*?y}v*5iPFdaT&N z(y~cD*V`m-f1#2?cc-zw{nDQLb?hIT)5uWZ89{y7);Pask64Jm>yoxLF6^O@jthHe zdby|iW_(eu^O%IUfw95J?n0S{)X3!T0F3S=<+otI1xSI3{w^VjtD*g$Fiv>`Qax+E zHVo`aSCal*3#?nSjJXz2^KwmoU@@`w49?m*Vtb}ittw|prH|z5$l)_t)#9tOtDD_n*${usn z>J+3h3V1Lnn)ioS4+jr2zummF4idBbtB=xuLe>(W!%ddls(t;pZ_bfK)R%Ka#PqLxu5+I;_Ef=Oiyy`{9NSEu3mIGo;_8` z@Y0U|OFN`Z+DB8um|=pN9f_-s$rqwy%HGE8YJGGUs<=!Xc(Xi9{1qqrTjYHBFJ+^M zrHzF)H)XR_A+NbHuG^kctHa)T0XN9SUn&4Q+vdhtp9wC>>B`#1-*K&Yf8LF*nJS{x zBXC;Yjc|X(3NqqT02{{V-6&9;^b^#@v3_0jq`9h);JSDRESIyS&9|fRIojf$MHk@d zX%ng7zBWr(iF5Qu;V;7V!cO4<;ehax@E%jc4H9AXA(kRG))nF=@jCH#ahLdz_@dY$ zzAYXTe-Yy~Lo@}NshW#5muadr)tarEe`uc7ys3Flb42r<<|mC;W7Q7RPS8%#&d|=$ zuGHS5-KBj*`dr2Ve$Kf3RAXLN#IuTRzI>4)j<`f~jO z{c62azghoh{a^LB;?(`TzEl6M{-nMer*4ZO#E@wiZLk|A8>Si-8I~EU4eJdz8*VrJ z!?4G2!0?LUL&H~wGlp{pz0qQ;*WZm#8TT7sH@;&$Zv4*J#T0r6n+i>3ra7k7 zh|tn(YBPyNX3?eZf*ZFmKtB+AFcq+Esqhu zz3#A38|~6yx=o;LYN3vXV$`_4=l3~oq`^+ zutuz^Ud$uvjWI~?qGJpP>nsRA($sjUJELKoxG}ix-;LLb2&H1lDAI2Vz`x}FSMLte zz~SAN&bP3GQXX_B$wr^~)Z2PxccEclR!!KbGh4mgrrJDN!k#9VZf$=B^Rh3$x6elR zGpvS|t=qftMB3fZez;rQ7|45o=f&<#26{*38AJqaAc8kAqu#xTyIK47bta+qT2xOP zyAn)>H>dPhW$kb?#hc*=@K>W+!J z_>{nLG7Z)~uutq}&%PZbcyGg-(<|Nd?E4BN^RINj{RJSkXAzD@fO9oMw{tlg&wSYP z^%_qH(Dysz=@?)Ov7Zi09fBcr81`hEb%i9n=7gQgLIFJPU`qH-;-s zd-opVh$lj1@nH6;oJO|Rncz`FC<8dCb$fRM&5pUnVJb50+yUH#i%1bSu9B*Dm^Lo) z)x6fkW|SbDF%5>o6=FlQeFaQ1Z`*%5OQ5Zt2vWi#9gZoxk3JKuHMJQ-VVm`IA%Hmy~j$iminf-@bHd zbNIh_dlUF5tE+!}mds?5%uFVG$i|QWCLuc{!7wZ#A#5Rp9a&-n1V{-4lNln4F^EKx zF=(w)-)I%rpY?5R>Vk-x!40al)}=00Ypq&zI@VnjNHYKLx%auxJhKFC-}n9dX~R7C zo_p@O=Wgeod+s?3sBh6HKB(+bplE{lpcW~i`j1?5xf-#OXdd;VxB6$O9+e(^#4l=W zZ$~K2=3UIg6_=J(7f@<`Kq}2?+&;8cShEqmv$ATLHB*zBqlE{o^MYF|Yiq6KAZl4b z`gzgP%C7JVc+?9w5$iyxO!mr_AUf;!9VUZb{^fKU6eWHLS#2l1)% z4fMf1f)4&5m@WP?JFc8FIxnQAruv#{k(!Et-PF{-pX1~>j>F=`HW{>>6to2Q84LLP zM?YE!aqoV%jw-rmpRaprM#K{8eMChaf=XM?{dkU1|NnSsAAcQJ@ol(DdivYAaU&)y zo4qYfo3_B7b5kp#umq>CbkR1b|i3qw~uQmp387p*#&)L3q{M?ElqHkDQ<7P zw0XN@dr&!wO4Ulv-FCuD92^1wPensH!df{tZ*Jb$OzQ(^YIWe>4UH|0*!1bJz+{1d z#e_&O)XiDGXx^OK`jR;;s1@@VSLfKip{Xs;T89vhc~(5)u5WC!H^WJt6gYSp^9Wb~ z?~0|NmaYoGk>nw1^icbDM~l4~G36!CgA=lgb2tq0$lG1JwWHaNK*iRLh|SdqgIKI= z1?kx(J}5NW+P)jw!0i%_{Ork6ZeXjZxsA-LA%zfQ=nHb$X-M+_2S58De& zN-`_rd9*Z68T0VCsR9w2S-*rLjUT=s?MrO7t`f1 zyCx_OWVu4*8z-sAMo2S~AZ%Nis6>TTo{qzZZmG~eoZS{wNLnidkj~`PlJHeZpJHhq^b3ZEisA7EuPEK5U8V$76$GB zQeT;g{C~*g(?SPrI3*^_ZXfCK3mi|NQoNi#9J>!c)mQMq*MgUxI3iNzJu(k=Qk=Z9 zaQ9}Nq?}tw{Ls*jJ>rueBnphc>q?a?BMQWT!kAlhb~1upNuX&2y2KB(Z*V*%b_68G zQ{qj2i4qQS3+8%8&f#raghVu(vOW`8^w=EzP97S2K?V~%3WZf%8G(K+K-t@TJadu! z&XHt5UkcV4n>e{bF8)#U$yrLxT*a6Ii6J{&TgcIU{&u2@ZuQhOAB?R<&XJIgP zEd*sA_w6eB6|Qoi*GZnB?qI@;?^CLf%Psb~&hB|7cnzMj^=Wpho zR<1GM${X0|YY~^u{+HX~*{^6up@vB?*&1mG%^-znt!M_u4OqqXP|_Hhr^rKhA3m0? z)GcpagAq>s>}n@CxyPZG`>8 z#I3=j6|5f}6oo+QfGO01d;R!y{^`O|63KhW!~%8?OZhlj$SHGzzps4keMrS+{eNTh z%Ol@&i*Lkq4K6yn#NI4X%Vv_oqb#ieoFLg#ly4BQw(csBin3+wdC^e6?T1FgqO-0BmDRYkSis046gTDnRBW=}9xws?rotVA?`; zfrT{n?M>E>tLmfxi`Tel-on+J<6gxb*udN$mQ4l>8Ry z7#xu6AFEM+efPn4PS-qch1`;*+1DAV-V-HsDv{U>3c?Yz1R5hRg7T1-4w4u7WS)L5 zr0h0HEE<{8i2I(V){!`@OU$l@?L;W7awn;SC9x@x#EQ5imcu16frexp*VzzgURDVi zFsSNpsOr-A;Hqy`Q8OKr58njo@sSYHBgt5cnT>UuInnZncE zkB%7Z*@81dxQwR)9|afa8U%ZSh0A;4N~vx{q0y`x;Tp|4yp*ULQFS&syX!`JY9jr+ zORCjASLzQNi3_F#i79wYhNkiozHQhwk@9ID@mnFVJ&eHMO+@UC#Zr zfzX8tXb3?5&~*XOI2R!Zj}m6zll297JG%=?P!LBq#Kpe;s=y7g64<%FJ_zB3R7URO zep!lQLMZDTtcWkb-Xxd0eXk$|*1q#X@Nt4G?gb50D4p6-GnXLkYqEyBM=__qZAmf+thLu_ID zPc`0b@t-6w{(G$cOUVe=tB;^8KQA9~!%F2Vtip6TsAHiCI| z5R2n!{o;erRPbK>0B7#L!6)&TPnZel^S;3w=_D=|asG+mp={AFV1J9)-xBthoT<|8 zz!eoY;t?@kjA98QBz#wpQ9(!Hgfc>l3!FII-}H1JL_EvuNBFIL4O?wzacbyfEnV)* zclK+5(DhN8a{u?3y=8gV<9;4l=1)F4?G95b6J9$VP~$Yz#@-OUi}#iXN3dAF#yLA( z(0krif+%XGv-^e-p9;l&J=7YHV;bvXesI16`fxd6W{@L94--@=hWm;2aVA=SB{{5KPquER>F#hZgpB9rYnz%{r@KJR_x`p%m^b?s=Rl9?^&C=t=OjNK-dl{-8V=;>?Gj&4I$=Z z)32nv6>Gt1fDsDsBL~jmPxm>@qw4tH?xEoW-OGl%2A2&Rcj>wwz(4d`<y6Yxa^N{A$=pGi8)&}pG4_>%%0;ts$eqd2=q6li5~p?Lc`an(LJDl!hJ z+SnFbk20=T2nU_D06^cbiEp2T!@EK5t6;XhuAsxmHmOVN_nz#dWrmjifg~t2=ZroC zx}N+4gxf{IHT*?U1BMwJdbIB_E{{=iIe=IX>~aE!k`kGc+`T7*QPKh$YS>9blPqhQ z;*kdWh;9V)%YEGtEmlSqj_NH<8}0H%6yiSdd!GxX$WAla%}-5pTRX0P5ci3KEwQA! zrb~H>@@^;xmqXemGff#>RnXSBgF<9EV8FVeiO1I}W_o~z;+Q4*mDM$KYwHjnYUS!R zi)NZ^^Eb1%xXOpV(*0N-%jjsvJrao=z$Fa)Hem&8X>Ht8#4cv+_Qs7{aRJ3#m-rmX z;IeEtxgg%aVs%~OXmT_aBv-ZWfHkfI`UkpJW0fMP*Gyb1(Iul*A*)0~Q8Bj_>I;dQ zx%lQ97wH<4i9kd^Thk?uW;`J#VTf)#Tbgz?wfOWYJZ>1IA|RMhUs*2Wq0266n6P3D zZLTQFjj2YT!F6FKgWChvkR+-jDDk|9%Cwoy;qNIe#g2>&~{OUCnqUp{v}2J5;m8 zNr_-f4Yv{#3~e_myWK>dhkRL!=n_yWXr##?J}gTmTU3z{v1}_`f0NW41$|eWm7bio zwwYEowluSFXOv@JZEtJDJj5s?&L^({7qTVlItt0Y71!1~?Kxp|2g^i^Okw<;8F@k< zZcsDr!uw}r?Lyz+KiF}DZj_(^-TGY@5>$><1OUalesoIUF6^ESJmQ`K(aX-@i2d=I z+O9$TalobWDPZgE{>K?e&=Sf|zLWGX?~$(m=y-XJrV0pDxgoHv;}wFTU+gl7QxX7p zaX7YlaY^(EYr)(2>x!Bnp=SY$d%N9d4uCwOjs;aebw=gBO@-jZXAp`g%$84q)Uk)pZb3u|FFm zUa>Pgs8UnhdD=bu$*TM`T^K`pgyMA2$sD`iAl(>pxx3p**T!_0e)+Vg+B&>PoVc~6 zk*zr1yg;N;k0S?jK*BC>$F5fu`4E*9rfx6y z(Z9JU@XJ`YT93eBh~UPY_qmkpAfO>LKkAIS4R1#m+c3`3k0|?*wm3xEEwiI07h{5vS8T1zurwbrX=knhUi_eh# z06;vkHVtek{vU;Vrzd2T);0JZIvtN)?j>TUOcW~vO*_QTk%*bXMm@i0zwUE3HkHGw zMHHi9h4~OXtn53^JC<*x%DV*?X)GV3#FzaNm6iVRShmk)1DR^}AFm-9PD48+r}baD zzt_S)>*Ye3I!f2BCe4CR0k6-y{t7@|Pp$aIuN5AI>|)pD&^53-6Yz|y8JJO?Rn;BK z8Y-4O_iim5v0nTG)!Tk_^|Adb=%=uhL{P05>fN#KM6GQl!azyxN=9knydPafMnDS{ zpH|g%vF`t;v8{I4exSNBA^WKi{p8-Fv8}<-|A$IUH;mvA)6M-9bm>2|kg{^KFHnwr zXn;l?d?zTUM}UvIkV=CuWD`QKq9F%g&u383+h(Gz7js*XftY&4Y?RidI|Lc9LMO5Y z#CL!8RBW3{&?6!Xk>3dPIq~fW`Z8s`A+q`gpQi5*#dk31mm*679TDGtpf3`ZsBC%t zWLVS0w;$-M1UgY-ckpabl~Jdr>RW^ zV{@%5#7C&o|69ktBv4^%m|V5Ap?HS!+`x|{M)GqbP7VR*lbHN^>G&c8_#Yei=^(XX zGG2@aw4ZaB>D{l^Nt(Q?VR|M`4p$G!CkN#*;0n4IzXq|2$uz&GyL0Gd_f-gE>BQe@ z_=3E;PTMtj&Cn9aU`u5^+&r!K$W^!@WLJ`Y+RW~rA*RWs08rsxU~!Mpp6I?}2xIn| zp_%qXCd^V{{{PM)CcH{p=yIsrT!oXxqDN+F($J;Ykk>F}TpPix7BG@1OZI7=aRS6n zAR9t}^rEGZc9&A?=Jj-U4ei5oDRtXSCw@*tn!VI}r0WNprS~4}8uA#ZP!9@uj=9S; zOiqT06a}P>fauvXOkM!5gwTp#3SRO3oWJ1FN-uZ@H+xmP!bT2mhAUY)hidi6DERE^=KX68i@CK;rEibOO|O8_sOmJy&$y+cP}!!`0LClI{@IH&FHWh?>KQ$Z>K*n9zkJl{9>qU5Hrw`B256+-`C2J)Ijf%tB3s8 z))duZI62v+x&iS~9#OrldRui0u1?OVqSO=BMe1qlS!#NmdAa&^^=IltO)=u3?9?36 z{91Ed^BkUGeyI6G^OZ)cHE3hCN!mTy>$Nv&Z`VGgJ*s_Lds2H^8yyDg@35_KbnTtt`giqV;ThoMgU z3-1WO2GLOthu;(ar|`drp9=ScTMTOv9i`3inBk9xR}F6(J~o^)s3LR`YGW!KljIwx z8)q9=8GmBjX>=I(8t*k8F+Og5!}zJuV2U&4nhH%nL0ptqOn))CO`n-YOjW*OMo);&kDeC2AbL%7Q*>*z zJ^EU>FL^5ZjcAP}&XR0Nx8z#NEj5;vmbI34L`u2S@`B|Z#7Oyvtcq!j*&MSg=5oYIc@%L{UW|D+=I=3|#?;3ijJ+-PuGq(8zlc@E#l$7XrN)hq zD~hwl)y6f(ZI0U(*AaJ3+zoLL#9f+j51f^}nee{ksw670C~;QeoW!+>n-cAbyAy9p zye;to#6NjH@zul+5aUQcqHU((OsVN_sfyWYYUdo+NE@ za&k%Xg5-;mf112Ixi|U0l7E~0T=FZ)=aLtXxo^yaV_q5a#+dgJ6D2IgoRXhXl5%lM zXUe{mpQqfM^2?MvQ=Uk9CFR=GJ5!IO{yz1Osc$0|N^DwE+PJimv~om5sX%l=_Kvaf)@=t$8=MW>6>ic5-T z7tbwTU%b7zt@uFk&BebgeyI4F;@=m)SNvJ=*ToSfV@fhgrj%5d%rCjPq_xCea=hf@ zlGMrLC;x8B3sXLvl3u#7bX{p<=_RGRN-r`T;5Usv+_gbzb=2G{HgLc%Resv zwEWBRsHv$_ty8B?oi}yS)D2VHrglv2nu^QE;^RzW>8*?GI%8=ciwl+4j+4{x{W^QB zlxR3Q;(hJ-L>P0$Nhwh>ScGo<3wlzT3OqHD@X2q6Z~!FqDC!okXSHn}QX)i3kJnRU zn~xNoNa^r;rq~uDC0wL5c|Dm3Y-&dQ013}Bug8L5C%C*4DV1KT8s?4_+~(n4;f?%W ze+TNx0S?qp)OfL>HNd!lsY-im5`|8b(%2_OZ0`by%03pG6jEK!sN~ZMD=EDmhut$| z1qSh4NC-sEz6!OGZ2_;7ZmjT4I75|??hEPZHKMfOX|J;EdCF0kkp|qT^YT(v;&#1jB1W!IzH?ZwUoIV{~|HDEI}V!*_*(Uok3t zcu4v$9v$8g3V+k+@FD4G9|fMX7e*{FJQ1^t#)yX98`TMGn7ZB?{ehad*xv_XOrnQ5 z&R=M4(bEilAKr!;ioVW={1W>*-$J)`K8TfxIZh8}mMot1fb@1s_j*0>M1m)>c<4$L zL^2BWf&x9_BdA7dhI?yQIfI`TFFuQ(VCmxDi$M?Zy@u~BZvm;@Y0$g2==~RBensH7f=KhdIRH{xvTLPPZCmJU z)WZzHwg+T~sK@;f?no~777}f=QvEpE*wX(4mACzH<$SrPn5_*y3Y1F%V^j#LCGI!^ zs*t!dg*Qcsh(Qt}R|k~|iIVt_5rJ7jfi%gj9F0jP7{D%uNf`S+jda$SduqOO));$g z&LGlVPYqsa8+vMnPt=??um~2g^$I`{se;i|o>k38_p8F!-m7xBaTX#aaKzwv>sue` zO*_niX^Zih9Fl3F>u!VpP~t4;Omy9g4B((5@C(Gf(h2(}JhMCay4F+PNR4M2e z00XL!Gsz5VDz@rLPm9f(YLfU`081u`S|%tI(6~|%Dr1p0PgczJD{2XK%xHaJ6ta=g zCmX4}&+Rh*`u?94{fnM-kQWfx&YkG~7O_>jzZp@JI}jK!-i%AqZ{b?c`F-y`mG?mR z$jAu3{nNZWtp+a4=FK}$V>sD;c0>aUa__;jBQQsTG2>&|s_(wMp{ILD`Q3voCp=;F z?!Up}96UR6VBcxHO*jh+&l51|Lc@DON6|;1O#3~C1sPM((%FSnsK33GOH^~?KqDI= z4Z4c|Q_+K7#Iz$% z+X9-hc}p&m>0o*;-kb%aH-{spQq+nyp-T7vP-!YfjUy~*9Pq3Sg{Mu42i_9BMBKy! z`=7?RB?dTuAIK-|Q@TVIAf8c40v@v~mCi3AM-A_HmBtrATe$8tfIt0->OBdd)Rqf^>F_!WA-HYqsauCb;DiE>KU#N%dLIn6y%^#} z_yscXYa&8;Z-yVFL(t0}f>uoHew_vOx)n<4evs(wz7=ZPLqmJC?mk@V_YbM?YoF?< z5jKyv4mrPf?)xc9-#Da5XhFiwL(ah)hx#7p#NUpw0RWY-S$96C7UiDD2}K#O$ z4T1=)L!s+Y=!PLr8Z}_vF_8NK5!(iob~)FNkJk@5Z@XbA1RviXc0YpUiF58zFoARK zH&EF7bM6)vfCpUh@$3M=dBILz(9z)prR?#J#5v#h|A=wPK0N+>W9-_7j=Xlr2{yvb zO3zBjjzchVrmb4Ctrpva2ghe;^>VmZws}ZeqWXdh=N3erL zq7VZ7LF)Tgr*XjmD#*IU)pJ%CAjDL}vWu22t}m#oUM;2JmzDdSAkPwH`PK~IAhr@Fvlf9$0ZJV`m)222u8-x+& znuaMA4W)GrQwrJNf`-!ihACu8xV_PygTM!PKPeS%WWFu(;Lf9_c~dK)m(Vb;B+6=~ z^n%ESVuX5wn~(~adS|P14ES2S(^`SE<5nP`AFEh6KK!U6=cANj-3YtJW_$Z&cnJ~i zTcoHdt&S~QrEI!o0}1qslQ+ArbyL&07{P>%t%&Wn5pFZG*h3P=I`D?Of?;NSI{;6f zHO84DN&NmwTvg%6mC$yd=#C**gchtYuHx}92_f4S*JW~K87WfEe1MQr-3M}YAPC~Z zT5vI<067>4qIE|?z<~1$IC;YZY#g}VdklSppV9rw%>*pJ{_Gnx6RyYPM7o-KwlfXx zy;mU&JEFod6O%DomI^a@TD*#YixqoZ6k{dW_>DN;xu$RM3##c!k?VJBZ!aTOsPFh^ z!LyyopzMxM@gtsoe1;zu`tb#R81X|U-WBfQTo`EeV%z(}pgD zU~1gH>8f3bK*o^^0$D|3f5W^4CAb?LuBRO6` z^$os76FQmtLpi5VN5GuocqBHACsBt?w`g8i(TKz^_|KqjB&d)J#Cf{W%(~HspLb);8PQqhfNsq5d<{^tCjUzcoFR>wXTA+l86Pu{+c0Lpex2sW44d!2@(mk4=3Prf z=kv2Yn|-cz{xj6s9XsOhi;}Ild;y@<+}Rx;0H9oQ&@;~N!~lScMHSNZHJiGPK4N~2 zvBZc`=Ks`}Plx!R{B~bHd3E*6r+sOUFQ4k8nd86ixb_nSHH=lu_P#q}@o+G{WfHs= zrNV0wk9tJ~nUSg$ZU)l&2H&M2dr+Wfg->*2W_W%Id5H3!7J2^LNe#?!K`EQ8veJF$6#k`090d=_tX@&utOWxT6=OA4-d_m-d-rXE%$%~ZzXF;u^ zC3D!$$1(cT`|s?Ao|L}9e~wZGEl;#ZM{@rsTKD>MU4sxj9J|iDwm4R?MaV7;$3G?X zfr5gO_;OxB0sDedP|$b`3J3Eqq^L5g;HehRYBn`(ZiLS`S>D>*(zvC4rZui%N)->G zY-K4G@S0(%K_1Cw8(Gl`t8qzvRptDJ^On}Gm}v@^t_*bS#=yic3n0kSl|Y1iWnd6D z24QqzV8GP?d#MoVyDHGJ8we8HtU?EdA964`8FePlL56m9u9V2bp0z6AIx0nc9=zLcTg`oMicg}cW%a8*IzQy;j0%ME1iQ-O3cR_XjRSkWk0!CBVq z`#g@^R`J>YMJY@&rE55FIt!~YWgVfa_!8iUD@X~;8_8Ri%+ zGW^tVtKnh8DZ{r0U4#Wud=^HmjMy5{9IIm>yNuT?pJXq<6en773YaN8>kvKnbXJU8a^)O<&8wM;N zCJrY?BqbyjCe2M+lC(0ZDe0=DTazA7`fJj^lD<#UB*!O@NzO_xO|D3;PF|V3Hn|A~ zESDwkhY3r6@;%A-Cm(|u%L~bGC;uz?tK^|%^%(t_3lWuP#h9Orxpd6aWBxeiqcNY4 z(WV$uvQsvvY)k1+xhLh3l;=`jKs27eAsUY^^=Rr-sc)u!kor}sA#H5h__Um~scF;G zmZYsq+nTm6eOvlv=~t%Tn0{CKgXxc^znK0``ajb@hZ##4Me5KlonNo7gcst*wy;WE zrRrBM&o3@23ai7(nU+4Y&`y|TC3fc!IVIAnxKpC2FgS9ja62r@_)!dIrn|=t{OOt~ zwLQV53(E6sIbAbsK^6ty@h|47MOGKGEWugD{ktoe$$Wwn;>tOz;Gv?#o=5g6-`xKskDF0fVsbKx>O97$6e0W1bUl>{)Sz`CY+ zr*$JyDbrL>G+kO)iEWoBGQ|l9t3d|So#gByYZq57q<<@Gmo8rqIih$08V5Ex+Q~hDAbvF%2w!4&$2h;5B?53^fpy8M zg|OkaJ4lbjTX_*H-DbBgYTDtTL;$WSu;Pv777$v$iUFoH6c=-Zq&GuL+O7H4<*Y9v ztPRD>ms3IdRVDvgUMtd;&!%5MQBq)CL@FmAih7ns1?yJ|@ESR76+@=ZS8qe%$)Jgh zAAE(Y>vjWqcMWS-@lFM6CFaN5NvCpZdTy0I^ zGVRi)Eg-5C%yVpLSD>n5BbZuLEw^JfLtv=GGvhYUM459Ko$_+@QiNpd{Za(^9(eW& zeGgRq*W%WJj_SQS8`&XGQB&T&Ddcp$LfB#e0U9Nsueax!r--L_^(Ll={M!I?Q z-oWJgf#Ul9vv{k@g!TZ=yT_PpI=SwrL)G0JRQDUB*PTyw(`Brp?!gtK)cs4NO^<0n z-q+bE|1ebbzYMDWJ74vRF1;QKDY}f1TDb;l3D()(NA6bR+yXPI+u-9Z;J9zp$ePhL zc;*8-psWZewvL>7ER{WbMEi>PkIX+s*}@&GrKZFXlyAcFj#+>sjejpr5Xd;deQ0aQ zUTTlB8Nex0p;41v6$9s^~DjkC~)>NjoefX~rRy`w_AO(a`~FLqMp#1<`Fl?u7;Om~(A$ip$YU#g z5*6~{Wi9XB|4ZzY$9mW`{N9sZIKB6;X_BZ3NPJuQ?LWA^mg#LK$28s#u34gHPVOUu zT-T@)$9FoL88gQtcB$n81INf{_dfCst#n_h>G($8F8MOi8iHc)BLf8bKmh1&1*q7% zdiUQVHO?RHJ_W4UublgzRgL-bX$nBp-yR$Jarh639P)L_KE|^62 z7pV!=oWK$BwZ<0Xn1yzL87{3a2Bw04@q{f_QEMQM-)d~J=nM*QRY7Pnd}u0s-B5%( zY&w1rjeAe}iIe6}5Ov~Yub(Q=uP7nL8tvg-+`(l3Yw%?+)G54Nm7*MzZpc+F z04Kc#3J`;B-aUChlS)wD3-)I^8Ix)0y_5IH0 zp7&unuOZ8MuWmG`M*u~dKZD9Rw`oUH8x(PNIJ}CKLLDIjP&m`?Evq%Kf2)_(vPe77 zx>@Pwsa^W2;$PegRy)%y#a2^1w{`@ALPQWs zVxe3vbI^PYYU6FSy$9XX5nXhVKII}Q7f5JQnWOc zBhjUWFI;X2CSFXqH{oglIhNp@1!{0C(UlsUQ>4aeJ<*jFoRg@=**ejc7o0Ps!pS$$ zRS}%?fy$;w&b;89->Y!OOLQ#{&Urv(GazS6aL$b?TZALQb$L*Z=W?6~5?s#Uj19IZ zWZW2>F&{Eig6nW_MiE4u1lL2s8A&#?BhKXt%3v2dlFx>`2s}?>{@U`Qami`7&PKeh zrZ)I*%Zrk7pcgf%iYge4)bN2vK0eXa!s+dqyeXX}|yr0e@gL_yP<&oMr;?UpERoEf84hkHTviy*Y$CAYVzc z65?+?=85M5e(b_o?slL>5mM-h8OA@cq(N09(rB5{sNx$+rM0CB*8oj$$XL-(42?Eo zM`&<)4KI}Q>nf|3&tExbhC0(=T~=$wi&?7{KO(GHeArhQ{nD|YQGC&0zxDigly!Gg zBO;bjIX(X!wy3eCNng{n9skfx&fQ^>>hx}y6xD!m*H6bt8>G)D!?*07fKC-pZPt0s zaEdWq$JSf$Ycl;}&S`UWWbAEIwZ+*YI-Fv&w5Wh<`w(7&=Y}~1VfAU-a44d(58E(Ad8#MkbSvA1?9Smvbm75jtME`(15C! zEb6~JI}oQ78uttM{%mG(iQbm1)W7d~@(By+hz|fHpflZ*!+7%?WteQDq@Vydl)2fed~@g9+^;|uzA~(Di&o z+i0j}BXid1s66wq^uUmoW2ymg^=OzDAama6m|%y}pH)q7-iU>KInB8Ea`gz7CHG@z z`7S_<@SVbv=*}N{O-H*CUuk#@l?Dt|2|Xo9_Mfav@HzlHKEKPRO7@6K_TbP*c4rhA zna2fsZWuP_e;CHX{)b^&*iVLa4L---yF7{Y?ho*Jjn|EARn)rgW+^s$mvuK(7K8{Q z_EfLoIE0Mrkn$x@naESFKuRKr224Cs>^u4fOZlgcJ}>SYZ04V*NAQUg%KiNFWBRP@ z8?^J!x9GD3sK7{|dY(Sv4e2GGdyGEg`Mo}J|C>Isd7ugIZ)wSe>j0_2F1FT6v3ezt zS7~ic>+Rm)t}=n{W8YvlJXy6#%8ZKmLdXBpT*31K2(HX2U}7Libl)>496Bv`SSBjKEkBN{|U0b-T} z(bYLZLeu45_cgSYbLD60;}cO8qo_a!gyIFEu0PO2eM0Y5Fvog^Ot| zMY%SVv!h(5RL;uEiPVWwx$$zjBn=kMB4^E@bLH`AiMcU*(x|rVn6`M4Rv?whlgoTa z>*9Rxk)2-eksV%kPvw01FfEYNp6*BvOsA!B+SBcce(4eN@H#}RA>4$n!-yz}5#5TV z*9eB}L$s>nDzr6mU+17|mxa?r;oy4?Aq2efBz~z?ClP^Ng_zM#J6AsIJa__+$9_ND z{}vvPJ+?_z{0@8mB#Jmuz=@*M63Zk8O<@cYsTERVr^<~zP0Qk?`#O(GWE^2+9C5BZ zDsTppam=~$2|qFfps(^7Qsp+k%4bWJ&k~h;F2h2)YhUMpRQCg{?gyMJ2L#H%x*v3| zeE0|Iu951l_N#k=RQEhl_Xt)kcOe4tJU8rH2g6imE^t$v$pll3?f`ijv>*N#XupjTfJj)z=jc$6|Jd4HBC_{`mj`;!x(s~`n9?)hA!ZLj)J9^&b{Qks#2&g!zm>r%I`WGz-nt7W3 zM8)8bF~)lWs}z2jW4wKx?j zQoN4TLmG-knlwadxax1n_HjD{ju78RQ*wjV-(SaTQGNz!Y=gnWRuy#@1;`${^mn~nha@FdK*31mATv}6GId@q=Emcx2Yopd%*Unr|*ek3S zQ*G7C6_vU5a~3Wl7NBqyD;&Z!dUBp0*<2|lNcZqG!F~g}i=6JS)l$p_)1n%4Wm^-AlhE#HYno}zT*cxlW*6mOm{$oW zRP}ia^XhVDTGuXFKb?4vQZa!;#1tV93C-dBpuXn0Q0z|PZ7u;iN#Too_zbg6$twiKk0+5Gk&KBOL z@{l=zFYatAZ&*dbBqcJ0N3(_X>Y*rGv0Ur70vVSn*~$OM)G7yuX0^(}p_R3gkcy2- zvYE9;*-Gei2y}Q4`1mEliP($STs{%^v2c{@2rd(xIhIO}c zoa?FJ#R8pToOcaQ8lLG$l1AYk0nty<*F9q?*JMwov0u;X#mw4!ax9SbpIJ`N=_p%% z05i{f0)Q&_ZzF7_XvUMG8CMIee$9~gOlEw=n;{!txo!>Fj96;MeFEL6&3H^e@MffO zI^hPHnnCsU4Q5drCaw-@!$PSI9)qn6ZTKBcDY}e(N}%L(hOaP>x_z@yT5C?DpIomC zU@3wHUu%+yc#Uw)tRSA~qV?oN_aBGD+|Sdy4fb0D7TT)$Z00+aDtK*Y zzjf~aQrVXC-)eX?U~W#k`TH2@NycCrRcsO!ON(Bd_~vd+`Rfh77G;Vo{shvME57|e z+0t1mve30uORe~3puA!Bcw1H5TwC=nqpj9%uq|twW?SA--h1$m!*twAmycU1Ckg@lRegE^?&=ZYJ`uy$>Fwg^cz_Nu)(rICWxj3S(!bAf6<9V zZIj64tCh4wY!<2LqW;x*HOh10W4JmVLR}9|Wm0Fe)#4HX&KJf1aSdsxAtT29Q@w5K z|7An0s3!COv?1eB!^9Z(9Xi{EWCP2Xb){gID_dFxxwjCwl|JUZa%p}4B>0>ST88r^ z*gLXgoH(Uo&D{5@YH7V+A@_wk%%R|AzDO!d@5n}5=8Gj5c8c{|kv|H<=8jj9Yz;Ul zi05m-;gT4o2K^V58?^9d&^WtA6bzj7HHbp9$PrG1`p%LV_pUIA55cUO@^7$es$kU= zu&QhnR++;fngrKl`#0*DCF-%Eo*ARmbFUU+PjEfe|3*FYL_O80r)HFTW@xcw;+BdH zvD;;4v%Osk*DJ()kc#}#N4VjXXz79b0lSZg4Me-5a3qezo8jJtV#-{5-BA-Snc6^wV zQ2AbzhvG1Uwz+?a)*+j|zYyOFGlp*j3MQ(uw)3_3QM`Qw7vmJs9R1J#@bcF^ewb?k z!27bE{h7ljyC*`4EfLziM#xAQSjl8+ScC{KRnQ>}LjFHoIY7CWrl7XiRE@j6J*HP|G{Lxtq~ z|EeKe^O75UsKI}Wv(nW=aGr+0fh(wo_ZbL7o~7YT6lm$2vc(WpW>e*g#=iP z;HC>Dhxjtaf6F1hKiN*u#=Q1x-K)GTtDl@)c#m`su@J|c6Ok(yFP~pGmz@02QBxzH z?`hPoiHk{`9DyR;)t4oF&AeVNx}SU~Fqoqsm?TF1D{M~!G@vBsvz-2I@N0%xvjb{` zjRo6oS3%{*EfJW$s#CB1zO3uXYB>16j1|DO1iTc{fV(6~!tS~kWc0sA?m32=oHW$W>>s=^v&;`*^gHTBETKIH>4v@e0Ruimktz)FThsG2B3 zDjG-cf5K)!0lb9)eX;I0Y0|ttY;QrZ9q0SjFj6zEJ~x zct;5SXOTq|teT|eBN60P*IE}cj&PdQ+mHIHxH8zuIaS1qbvmIVJ+=o?sikRh1#5)ZA!lSs63 z&UQx&e_x6^G>dm=7jNE-95l76rOmo*W7`hKa3rCb^^J~pdZj6n(8#LRmR5Qn$CAV& zJ3ynU6m5m&5&5}NFjNel(je-kF(eJ1NKSp#qMBuR4NFh;HnuhIq&KiZ)K@XbSw4cO zhnhCP2eXu{knrd4fCAn1U6f8AtWEsJdmpArnL3A9Eb3ViiEY`$(7QxAN&MxmILU9Q>rWy} zA^y6r*V{DckO`tg-Vs1b%&bHHC35^aL^93~-EeJ1s6Ld8^g|aJ6S9b8tRK2aVTdB3 zjP{i+V!WCo3i|PC0rBb*k)`C-CY?A%6?!yoGHrr^)R#bs}otu9=;0p4Cvvnz*lCvwN?NrF;Ai8sa@o7H_y`Y zM2`x{k1~A*Jt{cuJUvXeN?kRBGJc%6+L=toPAL3DjX~}H7lp5-pBncEIz+^!pIY~uIw;%dXPEm% z9n|UcQ|Eq4XDddqhAar|bOTZdH3yr^8h%EYJLE)o6e?OygE-nAErT$J2Y7NcvvwsSQQ%S;`zD zIzVq=OGhYErSZfP;U-06ZdSW@WA1@(AC6APn1B|XB5a?i-M>*0A%VG{QSKLN7-NQ_ zjcmczlvl zEYp`ZwX`-O0fCud71U_CTr$EU4HJPzUm+#HAvk@Tb5}ODG?M`lLur^qTBi-Im&UA^ z+lq5JRl~f57iLLje!}J^CZA|$`G^Yz)2{ZIix=DB{M)*u04~c}im`!PH8C(tpUo15q`V?XY0`xW%hu6(nwPM+vr76(BA#~Lx6s!s=m&Rte6=&WkE3E0+ zwK=V@rou?bUY4`975=B>uBoudgq-U8cH*O@??3UL$9V*HSV~;4o)(U>zjDMW7ePT1<}F> zeFqyN1t#cQo3@~@sQ(I}X{8QV_&9?V8hq1R!6g1vkNC8FX=QzUU;^w;Nm&ldH zq6D|Hg9f%?s?|2PcJb`W+8Gw~xWm5FLF!*?)x65(@qr114~U>XqY0M3ksb&VCMdLG z8p`nkknHNHH1%#Y#XyF${1)<~2COIu-JtwfP!tSrC}(zj1_2H@C=6K|>F4-=6;@1} z7C5dawel47p^j<)5~#)8fgN+r2DfrBuOoB3Bv3`NIX#xE}?9px{SWQTUI-U8wc)gb-<*qV+Xy8Yat!oOl!3N;0+%mx)>m| zYFZoZhz79JUSSO*s$q7BH+S$W+d)t0QUcJ@`#K44ioio@{)htXG-Yd0Ev!K&(;A)2 zCP`&WOVAt%X&jn<9^=ql**erL&)hBWlxK~k2gu|E*P0nXkFXofo)EZSgsgp3i&EcG zf#FC_c`ZB?Iq8AYXu@V8 z6-OoL;qA>kFncx?B=i2JDlu7Dd0Hnbtl`q5TMKtaNMAHAt(h12NX3qZcEbi(CYY`y zu-Rcm6~y^Q(oV@!VL_@djqZ(56n+HT`GznFi;FKC48-ca9o_?Jg)L$OrkXoF#wdzd zBCY-v<9tQXL~<@DDwDRbf)qh7+)82*w72Y*BgV%;7Y?xj`fG~PL0iyFYpLISA%}z_ zkIZ9tw!zioMljCGxX)Ho^mjo@t`)A6X&%ue;)^UpSYeINg(t>2%je|sT8NsNR*NrI zJtb5y6}d4|dUR@x+}EjB?}_49>eFiUS7_a)G-nMSalnaDrpxwIx|}5G>u8ClzJDKH zMM$^jyY&4$Iyk#a#}~b1!rPx`U*?zeC%Q9+VT1mcTW}M9%%XDO@r8aGuDKoI%$UxR zeE4xoy?2+MqceYU$OQm)yH61~`UZzcC-7ejg#turi}+8n5?Rvq|AW5oFR0dM z#kXHkR_kjbt8ego0{w^Yo7MWA_zo@_wn$>5)Nu*E?{kF8EqaR;Js1wQc*9iOxQ=vfJ8-AfUyh1!@U+AOI-nYrc?IgyXxi69dPnZvRB1}6@y zIuoV#2wN1gDnYHjR?@6GZ!6sy$+qc^Eq#Mw#DL|ZI)Ba1oPPr$V_V^_gVn>5CXnW;)nb9S@JaMB-rUAnjX~5VZ3Q>V%Y#CgGMs1tsSP4@L zqURpJ8v0)r4cOJ92 zZ&We9^x=HV81Ofl0nZBtAP0IX^sc|@&r801YOky^k{U*a)m<~*!DD|ItTEKD34#?( zcfBsKu&$HY{6&IoJhVj^;kow9ZIkRBwn}@uZMMDDR%PF2tF~{k&9QH^)z~k#&9$$! z&9kqv&9^VJEwC@PEwnF$`R!cWB72ps&OXz&*gnlxZ!fnkwNHlaTcK^GeUfdJ{Q}!+ zdzS4Y`&io=Oy^>ZmJ*DX$rvqDFj`76S{g7~ewuLj)om5sn-Gxj@N4+dlaed-z9yON_WrbnZ8PQU}lVMf>Kl_hOr~QPj=0gG%V~XE0=Cp>VRkyUcHx1J%HAk9 zh;|%+Pr=^C3-cU#i2DIza1kJzX^QQQ);qq5i;3ZZyvb(QDZiGuvtuw{U>Quah*u}C zlemYV02E9jVBAzfG5xwdn-{_EASf z%*FTtePDWu1rw2Up8@b13zlxJ`@t}23Db}(u!_a9tfqm(GK?d*C$lpb5_ zHLM-Pb!9u~d-Qe~i8W7%dN7fBC(IJB1-!2lBr!FTvOf~peS?wc zQ$%}^o%Y4koP14@Pv7r|?*MetIAd$iIT=Q|RWcDPvR)d3()3Hmof$h8Di3SL7`cy< z_(TL+LShoe(202KIVG0ZMcjBSd;G!TR6Ks;_8C2_D4DoCeB5>y-Of%aZZt#(ri}87M7JIrO-s^M?<_@cH zDW8BrmOD(cW)vj%G!pW1hb#22Zfld=HMell(=l0OwC9MGlScjRq87i?6^;VH1>Y_B zW50k(9sqGfAo&V-<>OaAcJ4o0;=F07WK#DYZ|b2=Z%@q)?jHWcPTHp*6PTq*$wub$ zB9V`IX-A_V?z~@rK=5^aNablhpgh(TqDVzMs*t`;toE`)nt{OAw$)UI`p7j;{F1B<_=%JqR`&?R0n6n~2joAt zKKBa<_F&a*;j1YQdU|${fl@5YAlpbZwSekhsQR-i*utoFJB7Fyav0tzaQ}zH@OPqN zVi@8PtuJkEeS`9&Vb5e*G;$qzv{Y1*A;_fR zkbnfX#_>LZE@Zm3 zvjXv`T^O}g8n(O(Z^o>eG(5%Okh;mya=xV^P89wR`)E9s_jQ8bgJ-r_OZ*S<;Q3jJ zm50b2YQlgfV96dZ1|+z*>k!H=9<%jU(GoIj|S{ zoy4Rs1-Aci9Gs!@e9NG-7+;zEXDD&Tks>vLH7;_Q7`b%#WI3|FsY`2HW$I-X8`v zwu>B-5J;5zaf7I$Z*V)E+*I|4D}RBb3R|44s-MTY;RJCFMi80UFtx%#QNlM+T$g3y zpeOT6((&Ky2N;?;=W&=JQ}3^AQE8aM?MtREzyR(9U5r`B{Hl|>lQ}whUF7)f$M%X) z2Y7z8_CGUw_3;LpY8@&F^_xeAJ=nd|AroZ`ySIW2#F4wSZ}1dx(=BR}W;h$dW0y;# z=|3C7Orr4{gL3Wv6e1V1?yC^>_%#zOdIll#pjyGP8R85yftda0k{SlTPjqkgs-PIU z@dW`b-q(GpJEx1( zkJFdxEA-X+2K`2To4!YXhyGsufc^#jpY-qPztx+GCfTpG0UP(<3KD=0;A5tc_d}xi)fd zgQ3vjQVwyJL>BwjWNME z)>vSyG%hr*F?JaD8m~9rW&Dlt3F9A)ZyHY-wI-7(%~WW*5V0{YGHo=qnXWP>maj z$Mmr28PnS)m04$wHs_cN%+t-w%^S_z&3nv;%nzC$H9uwktN8=-r{;)gb98caNpyL1 zW%Qcpi=%f$ABes?`d85pMgJ-K&(ZHipN;lLM_95DYqQ+4#InZNWiMb@EE9Mt512K=pJR9>~j6OCxc1&yq zqI1qgbk4Te%VMvL?TNiV_QBXkW1ousIQF~Pp;&dCB`!CvCT?NeinvSScExqY-52+p zxJTp8#Erz6yFZtHwhmxO6elht&MB5xn z&KWaxOx>6bW4;+1`${Dqm<85zD`L^ElZu1x*+wU)Sao9rCy!- z^VA0rZS%#{S5n_e{b#B!EjleLEjz6wtuk#x+V-?PX}?UnFYVE^chbI1^QOh7C#6qJ zpOwBKeSP|d^h?s6={Kd{m;M{X;5?E3_jFIXH$5!FoROX}Cu2p%nvCX*eHncjhcoWU zcsS#wjJGm88DC_0Gm^(Lgr)(u(F*&ktj+IcXKScj7c`xoaS6(3}X_5Sv85dU2|^MBqHWMG!dEaU)@hX^9+nh-tT*V z-|jCsPj_{7b#?VsRb8F1HsSV!yAt*#985Tp@J7Nr3I9zvoA6yie?mlJYGQ6;Y2u{B z1&I}jHHoIg8x#MYcrfu;;+e!tiGE4LlEx;@PO4AZkhD4J`lQ`S`;s0@I+FCSq;pA; z$(hN8$)(BDlV>N_CYzFXCEt|%c=9L7-zWc)d@0$>;BSaGq#1S^?lC-Jc*bzdaN6*x z;b((Oif78LDR-pYm-2MVzf#^x`6%UV%Egq+DK4oYsfno>sRgM^Q>#+zQa7dUN$pI1 zAoa=Amr}b^-$?x=^{3RnRJXJdX~k(X(^}Fx((X-rGVOTU=V{-k{gS3icS#?T9-lrV zy)J!I`n~A~(%(%#lkSnB&&bc1nz1fpN5)?=PGr25@m0nT85c6H%e*u5@0qV=zL$AA z^V7_p%x^M(%#6$$k=2;BCF`cFTe9xSdNS*|tQWFQW_^@(KC3@Vo9&Ywn4OfJmOUYR zUiRYbrtE98ug|_K`?2h&vfs@LqS==b`_o~{J8M*!mkQ16!sMc77Z=RDatP@E}B`ix~Q?p zRCHa@T}Atf9xZyZ=%u35MV}U(Df+3%r#P@UsyL=Nt$1?rRmF3PtBN-lUt7Gp_~zn! ziw_oCi;ooltN7o=pA`R8Y%7i!A3Z*9e8%`iSwYmmDa0vE=2Fw@W@K`MTs{NnmMMX;f)a zX<6yy(yL0BmToBBTzYNkp3+05AC`Vr`bFuv(r-&`r6bC6%L>a%%O;ggFRLh9QMR${ zy0W*+zAyWw%-0xX9BxcEPBYFjt~Q#DoyL8}r;PtJT8(cS&lWRZA&YW02Q9a3Z(#}aYOlqFIVRHXu?Ubk~SyQG@ zSvjS3O6{BtbMBt==$wOdv~z>zhR-$39Xofz+_`hjbFZGeW$rC=ADH{>+=FvZ&i!oe zcXNN9>s3CaJh42r+*n>-UQ@oNd~5m5<@c8Vz5G!5iSm!i|5N^D`8VYW^Crw&KF>Vw z@Vr;&y*Kalyf5Zmn&&@1d4B2qtL9hEx6J>`{M+Y$JpZft=jZ=4-)n*Yg75|L3lbL; zESR)l`hxNW^$VI7>{#%Z1)nT9yWrOa{R`X|hAoU;ICf#_!s!cVFI==Re9`DdhDBo* zORRS zzDt6Zj9xN!Nx_miORARCF4?l=#wCAU^6-*_ORP)I;XT&;isFhn6$>hAD;g?VDz2;8 zQ}I&8`xWOZyq88Vjayo{bjH%krR$gOT6*8o7nZ)W^xRVQvWR7A%O)+GziidA9m^hC z_WZK0Wv?wewd~_%pD+7i*@b0&%R(#TD-$bIE3+!gD$SK`mAfi$seGXF;mU)R*2*K5 zpHzNR`D5k9%FC5L%afNEEH7C;ZTXVr%a^ZQUblSH@;jG5y8OxI&ni+t@wF`ZACy;R@LOHtEv`Mt*N@D z>fx#z1(C$3zuvSQ_`l^a)DR_<7N*UEh>A6)s;$`4n5xw3cV&ns;! zb*my*jaZexs(97nRduVjt=h5b_ErB__4uj-tNyj>ja8>son7_ystc?7Rt>A2SbJUV z-L?OyeZ2NS?aQ@CYd@|%TWhP;tqxi}a&^+`{MFM|&sx2Bb^Yq5)tgptU475$*H?eC z`j^%IYeLqHSd*|Oea-ka^Vcj})3oNXHBYVi=bEEyPOSN8&41Q>x#pKOm)2Mqpv)#>U3>xb7D*Bk50 z>lf9ps9#s#QGb8^q5AjhKdk?({#^aH^|pFlLvTYxLrgdVg99Mt+E$tXLRs7AKpZF&%E;?4rxsDx9i1Z}s04B7XrFoyX|uhKoU) zLOS0JRAhEOi0~K)<{AwsRs+FyN};(4)xA)ynV%*Hepi)t(sZNFFlX8fSMCW%ZywL1 zW_gNcd1`SwLNPdr0Gq;Tn7qzRq&DO8x zjiV$^KRay5iR=eO&v9(D)!uDp0x?v{_CHn8Ko7m-h#clH$#JdYxdry`vJA{CmT zpVUy(2&YhTl7(k0x%b1#8F}UOrR3r0UCHS_SFawT z4pk>;@`|-;wOWe{A?l+A z5^eI596U{4M=Y+c5a>Oyj>;x-{@KyBmuXgsSsh(B5z8XAv*1g&8>UO1DUDt`J45Yn zusOllSyCsdl;=WGMriC~sH5wDh{c>Ep%_AS(mg)b6loaBT|yu0&7e?jesVWAi|G}}ou*j*Zn?cl^FXRCvZ zQM8QaNm?BwWMzcHQO2!{1X`(SDl8bBAO#YXC#hW`%1ihhR|SWe6@2E6pmJ4?B zm!F*!VbeZSt#!L<-MJezIeYKEV8egXl)Ms4!>+E~7j|r`=<7_yhm=@pxR>l25H@qt;s84g#{&T71*Y< zqaUqn?5(Z9GAON)TZSR97-iQx&9-=VyPkDJb9>y>y`${}>H2S|=xgm-+UIG8ErIZn zUoidGIUnKPr7GE@sQePLqDoU570e?S&UTt5*A1vy+8z;3+W62MhX=9xRAzU^|DLCz zQ(f8z4_rKQ;QsqHO>FI2)>leTdF)`*x*$|)vorc8%Fk;l3E+|?wG__*9k7A2Z`ka6 zNNiS!(Dt@Nmtgrmd0>Vr@#URuH$XD@f+A`rXD6wk!z|v~HRMvBxv9M^>Jq$4Q{jc0 z1Z&JFc%}}AXDaS+nWEs08V*m?V0Z!e!!g_&{>bjI8tLHKi%8iwTu`fe(_6b<1RA}l zmC=S8WpY{6!Co)y7(q4ru$sVrK6S|KZf{%Ghj^gqS)#EWxMy^l;TYF*y(>J=9FoaG z(X-YSbmB=aI2LU94R1;iElQS4oy5lU0C9l*fQg^8yj>^p;#ptnnZ%c!vJ8!6^YR90 zj-|Dlc)hFZh70Z6A}=ZItQ}nhBR9_m0tu@1g~&^>ChzvPNc34A5;s387)RZ;3n?z> zYx;L0(L!K$S{(Xa!O)H_8w&F(6$Vd^xxLNS#|az2@}49YIMo%kw^jCmB?_6*v3K9V zg=CPzBnLY1{ejjEgS)NgtPYNLv;f(KT`8-bBj9!@6=d=#hF8xM6sh&9fdx7DC(0w@ zeK=CcOzh~QPiWph|G_COi*=As#DIn%$g)o@kfsMag_tvbM?R#=J43Ezo2#i17uM;7 zlZ%*j(}4M75sp1Yc9G|V4yHT7IoA2m+aP%=m|Ez$BHmGyO+r?L7ydT<1{uR|A@KuvZZAM{Et5c%18JDUldO3PLa9F#DpvUNu~kA_DOkC~^*SBx;m*Akt>XW#2Vwht=AtES^;7&oqyBTqvdUonjcuC+yz$ zoMLHL!*>5WqbuP`qid!bLB{`ZbPZ@KeKKzdr?m8|V3;KnEEyXkxRYO~bkKz+3dxUY8j7$85zH)S%iep3J!=N$ zsv84)!?CsrDxL6$Ni6qj#ziEOA=VxzIJ{NWd2uY;v0xG)S!T&h z>I7-dB%J8s@a#C{D((2J*ARBLV0#F>Ip7{`YGbi15kD`dB~Zxz$Wt@3M?mJ_eGK>E|6gijYr_*Tma zm3d4@*L(=D)ra0&rUih9>T;Lv{8&!Fi3uO_g-TY4g`lIXj;>8i`kUC_I{cO7el^>K ztft9GA-V*{MK@YJ@60z|gzG>$dXg#Y=t~TM4INzyT(U}~qwD_yR}yd$MRB679jqoM z%Vjb_?1I!j;R;j=lC2X&0VbgxU8^XOJ((?Y45+Db{O0azyiDz9du}z}cSBQr&#u1I zJ4?vqB*~SE1r2Nvh#h>4Od|vg8=tJDRFT!rHM-=SDRvs9I;M%DGI-KtL2 z6RLx%&sBXYS9PR%n0mC@pdPE9pkAonq~5B&S$(hi@9JmN@2k(Ky)^!s7)^?1x@NX! zwWd+CMbn|VUGtFUIn80stD1K-J(>#|wboVZrF}+wLffPLP3xlb(?#n>>xy(!baQo8 zx<=hLU5D;Y-GjO(bg$^%(4EqKtovTqr*m})afxzCb;)xnbD8W?;Zp0;>~gJ3yURT; z54$|$^1RC%F8_A5?Pj+J;R1BX?TFjI+&*qL-@OicS-sxy3iOWgPVz4C zp6$KdyTf~r_usv{y^ni;>aFt$@=5o(%BRuiYM-q>Z9aeZdD7>Q&vBn~KGD9(aOIik zyTSK*-+jJM`o8S@j_)boUwwW2hWRD-;zQ-vsxagZ?M|d;Kr_hXf=B7z4`TuCqSi=74(xo(|{^cq`zufS&_g z0*3@a)M?BRRwJcx-RIi z%wgw+px1-m4>}XHC%7y4?cg)PJ;6aCaUq6~F(DH|W`)#*tP8m&q&?)8kbi_c9`bU? z>mhH4d>Qh6$fXcfXkut;=$Oz6p;JRELu*2}gzgNzDfF?>e}*1`OV8y{P1wz0N5f8p zy&LwQurI^B;L?*6o*kYSJ}G>5czyVW@N2`b55Fb+9_H9{6s|q*hMx)V3I8>`Kinf? zctmoP_ zp|YwnU=*TK^C(g)U~w@uZB&HM$rz2->JV;=c3a`%9mntv%UKL;*(%A`BNlFgy*wEz zENgrku#kd&)PS_}NXu|Y<73(K9Wu(~40hwmf*GU3LM!7Ok)cqAups+*4(`4KPq4jN z*=083HLCCu9zH}*L98gijA`Rqn1w2`h7~IkXg7r|6rMgT97n4K8munV7!7HqjqG{8 z^_2)+B}eILs$N@Hi-_N~4Loh;yeSA@vSLlOsZgIYuhEPsSb#+gt2J0}SWF&T+?rWX zE9wqs<lH7(&jV!$Y$60))((mtDD@}zwRwQBDs4z zlCig-Io(?=tzROu9hrETU?+Q+VCzxaC|E&hrdM|AX%rkG3i5>yFG90W0v7B8;eXEW zy3&WWi~!mG!jE-nXMrk?|LPc!@5WCC_po#pf79cn$)!0wZoDKKwgU~L-`x-hNw!`Cd6NYq#ZqD~GF-Z(Zh0A?n|>E`ga9S1 z&-^ZEJO|}ZSVZ!z3lk{>(m@0IcC!lL3~H@BQc zPa9QVpHfwovJw9qP25pFw>i2ZX90#9Hg|Z30Q_peNa3d{2OKdKX<>q=3@OWHv4CW* zhKh|~sD{0r+c_528;J*abi1`6Cq`uox8}q|&$CXv4R5WG#-6rd-LA;#HukD`XFRJD zn?u?h@mcaCIgQU{=fKTRMOp{VjqC+m>t`ZOs#nY70`rR&mY?YOSb{-(jqyDD&Nr4;Zcnrog5%H!8CZjZ-7l zyM_H~H-3lEsNo3n8H@m!{`qdWTkqcDp6?0EfwvhkkbW3u2h_o=;0m*X2Qs}_W;D+P zJ`I9>8ox<<`+1$}!uNZiqoA@;SIlOmhw^Nc%QK#DV)X1Xo=>h)S*?~{l_^>p z?1#bVUcprRY{p>Z!^!ymR`Ax;C^21Qo(vXYPi_ryk-CzzjPhxQwLN>k8h`ew@g_}a zFqi*i0_F0Leo@LlebQrfqV&$~`zV;_{qnrTvOq*E4Z&W)Om@R-VMzG+|(x$zY_(<(P$O{IrsrdBtsLU z;_e}4B}Qbp7?IS16y93LA^D4NCHh56+-ooM#PjZMI3t)Y^m^i9ch{q?2cA$P(#e4* zv=|x(8B5vp24&b!)Pv8uISj_GP@2b1%ZbXVkssE@j0giE&Lz<4lEy;nx~)fRG2acE zzj~h5;2skp{#ZuLhQ8CL$}rF3epQsYO2v7$(i| zwPl$^t`?VaM}ZW&b8d}umqnMZ%n^&^AmhPQSFi$rz9YrA{Svx0h0@q6ORtCHHkuUM zg8ahhi^sO07jq?o*} zvsV01&_z9W=6ZsB(TFDq0<==($cs+<=&B z%;gSzk(fx^CR0AI*ZQC+>j25>v>v8BHs`R~*-y#4;g6-3&pMb;Xh+c^b`&jY7Wmpc z0(u^_?LfRL?d@62CQuzni`nByn<1@xy)!Tx1>nfv100F58Yf{K^*eyAmd91*I8cDS z=y2ML@(EXaF}{2IK^0>gZ5Vo2F+!xxP8&F!=q-jh8_{uMU)qiy#RqM1S}pA=Q%Z*g zNlq%*dh{R-?Kr7vRI%8a=u}CH$r2$WtLhLV7qM#D?Auh0Ij)AymUxS&ve^_zswkWd zYSqJ&ZGmb1!Y{3T(r#L*}UPZBY)%szB$^x24 ztDKISW5O$Pm`0ds#4zjP69D9JG|)(~$ayn-L}&9kf?b>3?2yx z$?4NNAdy}AJ|!nI5t8Hhkd~LC`p{e_iG>R8BK`S#>}pb*^mvUN7kn%Far(gcr7@%Q zTj_ll2FQL2T>!tEe!bZhZZ7@3y;5+r4@I54q%_}~Q>h+W#!T_7<>q110>HdYKNf|U z{3D2eKQ1@pk7=5aT8@njc|6=uIKmBuBR*czuD0;Y6pPXnD_SBU?x!W=vIAmRN9e@e z6;4^QD$yG1E0zR>W3JMvj6XcYN)2otO;uKw$R{nDSmh~`*JpR(J%O2*Q$W7Rj+PrZ z#US_s@$}GTHAU0spWWLIUDi|AQ|;V`nQ3X2b;`(?@|3quK__KPQ>qh42`Bf69*|F; ze9jijw!2_*Pb{?GvTa*vzj-HLR+%TV6R^2h*~xLlW~MJC87I*GG9Y1WEfsl^)UXBm z$$Sphy4j{}@+Rp~Q&c@T9q@V}A6Y!rz-0=~%bZQjj6t?80>t)q>(LQ36^fWqGMU<* z$5m|Af&;^D7G2J^1-fl?6QgQ@ph`j`4u*9?V3gF-$xwzPLoJ=drCXmIPR?~81mwBS z6Y!X;Dbf@fo~R9jOYkL53YE)d>$R&WU^}<9v7@BVsJOVe(fBVJ|HTD~`HjOlPH@=n zr@Cwk*?N8-Bb_#*YBQ#`5OypKadIp~4h+s3vnNQyrqz00xoPd_V%l(<580$~ORl!ErMCd3%Yc54R0BK9cc9Zy`X^M6qE-k~s7UkacA?j5TqmEF} z0>|EIpqF&438GG34DZNLYNAL*2eDIVciRdZ{6>l49FUHenB(XTOyM{})ym^qB38NA zAxd~*Zdk`&hwxd)ipr=AlSG2#d!1>N_b2u`PFu+ZAsSBruqfI5*d*x%McmK*jJ;*VmX$X0j@=Nb`n-NeFMgiYWjQ$2pU~IYf=bi;XhQ`CO3X1KF z^*h-PjClC$l}0$zQ|M{ddU~cnv>d2oxEcjp0orfKdjSPRqJk45Szo!b5-lP=v{X0M z*3_=xr_>=8IihulzTe39F!hzD6{}EFfXJZ+A_{etAwV8JH0(h*?;Oa&G0bE>rbo%Ncas>99ac zgQ$v~9>LN_C&fw-mE-}x*)2W~b(vx$B%}l^k&)2M%`$oxL!-18d6OOTIxP1iZKFe) zgou=S_sbdV@FhYyD5+x5t(J4T=BN(KLn!lvT*hAcT`E8Xw+!j9>;uFHgCTl1NgUFe zGgzZpJM+rlHV@A;o-_~R1$Ci=xYlhvr|KQ|8?%qpKaXK_`WPYs|?~_jiHDI~{23 zuu$6La++8`#UVwbDrN!Cg|i0>CeLP+<~5kJq)7=wUytVnFl`~`I#kYlO%%gUIt!lR z7M`u=&#(c-);S!kJ5>1^#QJK3-vTrv2q!_y!_N_egu)(=qk}JIIgtW}ZLCK*tXTLG zE0zi|SqlD*NW6FRwLuzaTaP|V3zrCZN~!in$0}x}K_@Y;jQXQP6CGu)d}xxj#tgfY zW6%9!p5ppEwoWhMJFJ|JuEpqcsU29zet(n2mg5x7A0CD}y2cRe&&h11p)MQ~hB)wA zI>gA53zr?XPe3};`up0yNehKzjcvfO2CrPxv4$4(LB|>vkqyTh8$Z_A=vc$HFaClG zUQ!%uMhiMj;ylCNKz~k?rC`) zqMX>*4pcr4+LqhLLD)p7W7pSKRg<2TjcUAYTwUD|iN_fztG=>fBg~HtP)w}F@LyZG zvYHmzC}GUS@^Kbz|6!;kJ~Fj`Q)BEM#^ziHjogV+S?bwJ47MAEv;rfM&OfGX={si6X`_PaHnRf5z69dk;K;r|WQnYe!q(Mq9TH z6Eg;zMwsROemRY1><-J1fO}A+N!BV7mxn}}sA+(;%7g{+Cxz(WMH9J*sV(@`(?`#~ zfufzD2o6Bjrv+9?zem0Re}*D*CO9q1{=ZPvyM`V=tLd>`Ba+j?#d#V1Za{V-n z5NUT8s*(_~YNQsNAm`Hc0=T2=1k+TpYGij~>kX98mzfiAcp+4dj~d)803@Zs{|Z)S zIS}K@H?kt_#FO4H!x4}_wPch5QbsJZRMZcL}8k}UBlqxKI`(&V{YhGHmh!|X>MHus5S z(uko8q`1G+MH5;(&;%|_?9BR_fM=rMjDB)ru|rX1y@?Wn=aBW8K;T#*DKD{XOz0z& z_I1sDPT8z!xP?D;)Vx)-^u!f^l8PoMa~(VV(}5rTsBbo}U5mT*h3@2bHXUj=ck(tX zo<4h$C;6Hc!?&rj$#YcZXnpyd6h6_XsyB z>|vOk$W_Cpy|SsYUew6y(AQwrq^B1Ldt|XkqabpmZlOo%s^BTlW=yCu$bFcrbhrrR z3K7cfu;7B3by2*K7V;_Wu)L47DmhI)b93MhhYX%}>wq*Y8PyRdO zA+3(xat2?o*PZ{g(Z`guiK;e%dOfo8djyVbHYp)+2az zp!CO?~EX^`%Qxy1_qJbiVc9cbq&V@^f3-$WYKRvlCUe0D5j?d8=DMKM)SZlxiN+zPBN9OP8Tgo7gQ)) z)@n|aBnJDgH_*1#2}-65P?GY?y;H^KFWVtZj3-F$uzZekcQ}+&@&us#^mD)ggfEf) zjCwj`LCuTjD-FIAp-Wv;y;1t4J_!^p2(;I4z>-A5VxT37#(7Jkl5S=F0PSEq^y?i! z2$x-0f@gCXSpiKldug<>rp6F7D6zqCCFxDov@(KHHCwp!_B+(3BnY5fdV`XbG&>UH zSGED0Q2x>`WZ2;E@D1Xw%$Xun4C9Qo+jYWi7$`K`-RMwNZ@l0nO*cgZhdv@U-s1r0 zNK%rK-b93by%MM5m8(q4E1TrygKcMEbZ^0qhlaT!{*QpM8$v5a{0T75bc2urnBumL zR+)!LvlpGmVw07O?9KbdwZ6{XG^91Yz7FDX3J_O0LPWIs0)lTIS{$+*o18KY&ZRi_ z|JhcL{uA)L;iLW>ByW4FXnSgF!F7tZpG3<-41?S5&)fbjUu(-8Az0h}c~+xCmSfw) zvD@ICDb4E5D^^v*OCwij&{t%HLrEgN6+>sY%A!Nz z8vW30Jhw+rGIqP3z607L=2;z(BAOt-fOxbm)TUNZXpdkULy>lvd}=z^ApjEl?p%|+ zDP-0R{(BC7FIbfK&L(e*w&!|P-b+o|o>n+O(A~j}+)&)aAYpdJI^X#YNZEEoX9IHF zzaw=cs>5l4+_RoDUZb`q5JmhjL4FRr7&*lZErWT2GFa4xZC$}OjoFJyBBzzzEwcez z&wQJ`om^CTV^c(9;m!bB=$#1C651OzqjLfjM%$39-lRz0_1dn}j7&7sbxTg(OY8AO zM5t}w={2k%`~1@AcfP&UZ2UVuQ$wUp&=wqdMOeDHIqQi`wD>U^F4T9(NBD)ec$t=D&JpxR{z*@MwK5RJ~#f{ z^PVa{P<(2C>FHMG2Z_%e7od#D4;G)E7wLV)5b+sxi5~6@6`$sd&nLkW?eSWdmJ6~^>j-DrfU2;sP3NV@*R?vg-a8hQW+F~5HE!{>NeD5!-+KuFn z5#Da}rl;NByWDDls$ViFo$F1^*FgOXCqya#S)L!v_ctdpCBbB8Xd2b-xFOiA+MwEu zJAyZ>_NpF0pzh~YU8>hrZ>zpkeXsgXJxViCGfgu~Q>m%ZG-$5Tv}Lo&wS5f zPow7y&$*sUJlA+`@@(_G+4DiqmpzYqe&G3$=NZo*Jk?$SUZGy`UWo|TUF@~ktHx`c zSF6`;UUz!EVK;>B4SOK$ znXu=>y24%$dpqoO*jHia!_?uf;a=f!;iJNn!%GlsyE42c{F?CH;dh1a3x6>DWcYjG zr*S9moA6)4wGn|45fP(sFE2f!IAUwWT@m{tUW_;q@m9oV5nn`e;A+Q6EM1NBIs7 z8d^HEeCV>FYlf~Jx*MUkj|}~Ms3E#2dU5oc=%#N8KvofYG#uT$PW?#%*v44+! zF7}1k_`>+BMpllj8EGDQ^~fzFZy5QPk^4qIIP$rXFN{1k^39Q-jQsD& zvm-Bz>>KGnYRIUiqZ&qS9QDg6m(l*Cn@0a_^xdNmjecpgS3-J1PQu)Tg$W-g_$CG= z8WX1^)+RP2-jmp!cs#Ku@tefdqg{6+G) zWR=0iaIay%!D={S_>bXBL!UvNGBagG%BqxWQ?5_ho$^r1Qz>03-=uh^2B(fnO-@Zm zsP0J!*4>zTeQHPQ-Kob?|DF0x>W`^0X&Gq+X}6?3nD$hfZ@NA`F@1OX-Rb{G|4;gt z>0f2$WaVek>@`Cyj59>Q1yqcE?SaAMb~z2=~v$*9{+b8^4Eg5F2D>;F4cI z>ahHPJ(mvm%`1l@zJ|qDWy*63wx3EudnK3bycY%R$f$U4j8s$!=LjMJh)PdTR5tRb zu|rW(=LKM+8$;j2>h}E(qYVlrno&Jf)ba+=@&>u(eQ5dfTGs4~Xg2#vZT=B$#({_# z+~nti_@yU``Xt(H9_tkBDI6!J24K5Ru#B!3S(~A5XGv7N!?I^EepV$#_Y?&?EQ4`< zh|&@h9TBq9(CImrc5H*pp&!AaAC(-MRFN7NSCN@pkuin+Ev?2rt9C70{q#=$cV+O& z6`AA4<>LRp`#-(@PXK8uQnffF;lC`nmQP1m1qxciRlP7ZH8xc>vjhD7I?1?mzYdW_ zuy^D3~|%0Q75~oD5lyHxFzJhj8l`VTB2jKw&ypMOp3PWYkr)9 z$??DR3mzxho`0(tS}L*2#eVpps;m>2+7BPxNkH;zV7Eb@B;xq_YB7vE0Kh4WO(u;BZuja2=Z17=tr799n9dB+CIz0-_vBjJP5=i+;lp z>th3BVR3*>fE*XAH{kAeGut8R#JOFkX*as!$u@7D{AAn7rDnvZ?IXM0yE;kU@QuSW zK$YF{E9J5yGPBVP*E-7HQDdLYb`&o-ap}r4_HWAHX6dt;vl-kjWB>0+5+ooOFaNp% zYA5g*`+E-#?x}4BFQ6x|jh(bqZ}w$hrb7OOSR||kegBgdEZ6kTV#Q5U_D))QMXn^; z?>!P%0IKB5OmWqbSqyu8iNQxKp75u*8E%)`kEs7f2mJWjnQ@L1wjWU6`{L4Fq1L4Yq~0E=i4V9XSaa`7NPA@|65dxM z;glNf&DS@1Ba)aqexl|*cq9JRr7BYiJ4U1M)}x~}@MWOIm#>3|AWKIvbmb(rJUBwK zb#??li95g!25T+oM!y%^t4pTp>`M|=H+Xqtcw|Vv#NA1g5$KhZIlUhN!EvJZ_i)O~ zoFfK8j1)NHx43tHwH+?8MtAbULJ%x^0EwTU8lhBEObTqUBD_LHR!l`^az)mRip->n ztXb^$TK2n%{kBxVAh@U^s}KuVMHah-%5w8dW)-lc>D3!dEM+G9oN2Db=Mr3unyD%D z$wsAg{i&K%A@*5iV{;1oR!kdE@=6mF92c^j730&3ufGbe*|V!nCK$_`^#x9r{d_$+ zQrSVgS^3%K<%GY!yJX%oC&;tEf*~2$B(wnfKnIO3-MiO_C!Gd z`JVmh7b#Z4S#fVu@=rsMJC58s-$Pz3fsCwFodaJ&`ed&jeN;7 zUFB?*!rOV&ZPveva?X0qdQ5QCj&-ct5sN!pmvUVXEXA(xfC^u?sdHVQr>}=qdtY5T z12N-36aWX#@q91pFmd~yP5Ht7u&HTpHJ^MYCLqksXp&@VD z8*&m2L)R(9&sjs(x}qeppkI`B!dLQ#6cyTAd2k=m{nxVOTsEa z`%8&ICTECm!|sAzPIf@dKoy9e$40{`;{Bqx2CU?0i2YE_R{e1uT?EWeaq^PSIqV<~ ziX)*omQ&~&D(tv9u%lv&bk~0B7mK}-`#}WCfrq^GU}>axbJJ#Y{stSAV`niey!|(! zvmgj`D501;^43IAmUV{Ig)&1N#n&PZ!$d0ImmnStXNbsRdkW5w!Ml-yr-Ana4IvvoQk?sQhmDGEyRK5LGBpfSjSwP2sS z3;SHH>r1HRl`Gcr_rbNaV;Amh*fCIhHQ2CUVb~o*h)L^ncErb+kRF4O5(Boq2m|64 z-%a%EIkjrNZojHm0~^i2smk{30cz}XQUsP+*!_2O9iusDzd+5xSU7eqtCkaa1bQyE zH0@WlsEdIA7+au^p__mAbb$_GF<*F%M<{fyV~t9I=tkSD#{@wgUEMSkyShOpwYBxd zJ!(Dom_{Pa5r-9^^8C3+nvgQja0cm@lP@%PSSa7A4!}sj6@1*rxGTBuXVh@25|8IignRBpAImtDs|o{ z+E?e4G}hzxM3r7rYryYS(pCt2R7F}^MNTn!5-PT&2*Il?C6pnJOqtgllm3S#_|{jB z{fh%mOx_F{kWpiI`Y1|Q0juLOJHt5|w0DwdHosR7DQ za<-Q*(uy!-Xz55L9isQ;d$Vxkr*LJcUmfeVskxd5ro4eKPh*`V77FNzr)grf&UM2CzOYHl>&x0c68m& zmTLHVc35tA4p+pVX!!aWC=%sF@jSJo7Aa4+S(&XZ#j*0xfI4@_$rSdwI zvpyn-k+vmOl=!Zk$P{toT{^ltsgkZvK_RQ^O0AJs$cbm1|v01I!p4*^Q z!!gjb!r2+`cWb)Zu_pVnMr^Y_=2%mxwkKJ=_w6;(k?)9V?>qR-4txis10RKDwpNpK zmwk7?n9>|}_qaoK#{Do3(OXsgyq8ZPwNy-2qVZd?4jWnDvo2rYtT(Nr>k}FWhXw7D zct?>$To#GARy$ZC669#hOd`rOy-TF_toM)_(*l8`pn%q75hGcNeyK?OGw8pBn`J97 z-6#riOqLsv_OP7B9nEp4U0jfFwd_@y!#XTC0qlSbMrXL5zXBs5J1iJ@{EB!n9HMNMxnhP_X)iI}D2PYWoWh#^cyic%R*0g_&kIF*Al>xiV)rSkhW>V$C#Z zS7iAs@&n|2%Wix|h)+e_vqDiFP_o^E!w8l81N$US)h(bjm*Wnd1JGw zx}I5F$~BVetsF7v=tdJg<&X^ZFx!if!4CZD)Zv*9B<$=uc6m4MHN|(k=;OP~)OzcU zxKnuqsaua~=$c?OU@1h8^$|HehSH}?>FsS*HUf{|QMR_dt=fiv*8x!z94+H_mNm1# zX8c;uer?3BYmmKJjXxHs6&{x8`voRzUh5XZE{^Ta0JaeTjdVH)^F3mqV#g=hLWf}` zRxp#N(x#%Snx14ROh-QP6`?km$%-d4UQ*~srWI9Sh5NW6zyT#GTt^~B#CUF|_#+#E zQ3M&2FxDa%@o>N`D$tiw)dN(k5@7~|VORnOz{W^XG0&&UXkYQU*jIcm?<=~l##6PP z&$q#Hf5V5|VmORKiK5p#y3%PNzAj&#{51^I!1bD=Mt2*$RO2c0Gm+V0amRWrxsEa& zq~tYfaaY4~J5$5;l16uYlxiFoL$07Sx;rj;9U#r_8EaQX3OCVK%rCS9`k8*au~WbO6i7quO>_#T;{u?tf!`xtrjZ zyMc3$9F#c((M{$aqI;2@Zr%}~qDc1J9b`I}VVr=R=3dOZL^~c~z>3Nd_`auBfDTY*oagvu1iDYWj4gDA3) zDNv2ip#|~*N|D2WVcx`iiRg11ZG_PLEX_i`s-cK$gxfXF2Y8$gmlO2EaKE?#XRj*( z1y`gM8^~i>n44(eBXPU|bA!wQN_0)2yL<`AD>3NVA*a51B}z#JN)6mNHI*Tf63ciZ zY*3U+i9;&VCK&WEMT!6A>Wy`kE1N0LSC8AmYjLBmip6Qy&2FqQ=_Xb-RiV&C6eIO4Q^nq2YOg0%tR-{cgD82zw zTDg%C=MCbfa*qaB$z)rYSMm6g(y|E?Crz0)-Cyy0(Guh2sWF&^r!^u9(?(vQY~Gw$ zT?gAIjF+03g=!zNqB&l+uIGj5DwSeprX_(NjFsz%0#;r}6vAsD%OjZ$6=}KpD5^4z zlG(Z=xp3!FYG$q<{^3`~3E}Li{tn;hOgcNyXEJi5!#D$ZH8s zBE>A=pFwii>n6Ij#~y6(aUe5rDn(~w6bk^?nQWBPf)FjN&(R(Z3qqu{ARMuT?(F*Q z((bmtOGhk$P?r?qI2o!_+^(TZMXgw#O|x;Kh*agX#r14_L#2Df;tK~gT0v#IfOQ># z&}jl7Py@65(g2eed#-7wgtF!T4kcUKc|EhmJnn`2Z$!~Fvp%?=A7j);y3_H&%5k+6Lv03|*$ z^2*i@vQlsY80)`xT4dc7ikzleTt`Ujbw}4}(2T!i*kEmx&lhAY8)$;F#!^Avhi{+{ zS!3JFHe)OOF5ykH<9&m^v&HwI#xgSUMD}1ZR{_OhlcbkTWm)_T9a$a%1maeCY4W{4Fx1j&@{ z!YPvO>5<5Hbe%_cT5lC)?QFMNDUJ8s=P)WsJ*UP~l)8LNi`{^A9=0Np$wx&;*XLwE zIx!e2;|Wazcn9)*WOsD^9Xndt1qDxVem*$0qw5rnh#v(y%rF$f&Bch603cvQKZAHRft z1FAPFFNbX4<=2wB;4sBT{iJ`!ew);QcHD=g{P^~=wYkV?maZth(39R0h{fhZObfaxO@!7YEP67uS28oC)88AQD6<7 zh~{vtDm zzAs%VvAD$Be0t+3<}}kY{z@%#74&zKo{tu#YGuRE}Z<4YP@DXPC>p& zx=pk5PqyJpRemAF_)|nCc$c^oE{I{$+tGD|5(^v>*^a{iiw^E3W5+`PCIQgV)$7RX zQDZPPx2gp6HfM8?Qg>wK_vZ|3{mN{x>{=A3# zVC9F}XEdP|j?}zHr&>L(-W9O%Cv)fa#C7k1bCJ2I)#5qRl#9RX$hG@z%!QB`R4UDwZ$q_?a*87< z&$dsP7EgBmw-whig8h0*jbs0C&Ci?xj7 zZ~B%)h+XnK$mBT_dRn{Q=~tQYIKV^H%Aukyw5ZF$ve?TJcihD0kQ+B9i-SPtZD*rX1tIs6YuvEYV#wgy=dZ2 z{A6a3XZp7+mMQ}R8Iwb0ye~Q>O#QB8p?HP_X@}qdKeF&0A6Y1f7*^ZEgDo61b$L3Q zx~^z>a{6wdyE=0J!0 zn@n~#;D%%i?uN9jw@Cwv!E~_kMCQnjt`?Av@xTX7+xa@r+-;Xzf~WQ<=jt zdYIXe$;1Ym$&F~*X>{k=(i!i@R-jdxCQ4GW!RfUMNlF-jAcIEN)q;ZxCx7M%@`IDR zomUhOvIWm*Y-Z|cNnfv6y12QwFd0C_h%4JvMe7c9v!q`aDp>w(3T1Gszkw_kGD;~H z47UUf#!SwXSd|30(`Bt$kA;c!s0W2%?VzJ!?Mmk6Wh7`d1rAc^qamX-9_~DVNAKB& z&l%KLLRQ&pCmRKdKakZYm9lz2WXMPa+$~D835^RdGzFA(LS%8r7l*B&SoYu&Lk91; z9CuM3BnY2IOa@H6A@sR)(~f1}BN^3BCfpYVZu>kcj~1z{1ydo0({y+GM~o6@bCfhA zvQg4vlcd>#1BK1>^RAC!jy(#8W-*=GOsAMcRVQJKzk4ja&9wA zCrz7C=#vC^yH$ej9*TH|Fr|=9ksB$vabkEy+Ng?*!iu!fWLHYzwgkmUV5XNa=8WO6 zZRF{Ezoy(y@^s0LF%VCL7)gUl=*Zf^qAhfZVbrDCd%|r;n;CJuPPnO#f{nPl1}icG z?QgUdns9rK<~!fB*@rv2rjkrqisdcNMtn7kM8_S+#3K!q}D53;S6LRr^l335ONP?r{&*L{+(} zQFX2AdetqehgAnu$5o%G{;Sfe^VO5pE7UDeEbLU@seVHJvihj{g!;7lYqd(_qWMG< zs*TqsYV)*3+UeT)+DEhpwQp!oX@Az*w7$9^-B8^~U5YMKSE5^>yIQwJw@-IecS2W> z)AFq@54b$+@{G&#F2@jsNas4-b+qez*Ojhyt}U+Dxc=4kQP&q-54#?7ebaT8+XAi)L-XYN&A+Ym?S5wHDTR>Tqd z$;-n#*gM*Lw0E=jZtp|h$GyMtj`SJklj}3fr_!g!XRVLf=bt{ueZKY4`VR3;@J;a@ z>s#PE*LSIJm9NQnqwh}N`+Ohq-S2zQ_g}tm_`c)&UtgQA&d=8`R*E+?-*1WEO22FT zTK%^B-R1X)U$@_Bzfb+X_S5|j&yw%{GX9l?8o_aRcz%fVj-2ZqFi#D}DY zWQB|mxhiC7NMnd8#1hgGvM1!ukb6T`gx?YVK=>=+uZN!sw}pE|__LTp<08gK)J8N% zTph6`q9fwLh$kZsMI4LxIO6As-y%FCBO;?CM@1$_7DU!YZiu`+@~+4ek#9x*C-S?< zpCfINx*^d+vWMginKESIkflRvhcpbif5?F$9}f9;h+C9*R8&-ARBBXiRAE$2)S9Sk zqS~WwjQU&D-BJ4yq3B4|zoOoc>W%s?N;5QgXvEObLo>D9Ef=(=CznpG5?MEEyfn3 zi%pE39lIv>+SprS{~7yb?9Z_tap7^9am8^{;^xLJj9VACDQ;`rTXAv2vxesm|9o@| z;s#Agn1RSa4GGN&8xq@e&x+-3Nu;Siz|ePuXr_{rd(G9slYWn;>{DTh+tO8HNUIyEsh zFLhCBd+I+@pGkc_^_A4uQ{PVgD)om{uQdO(F=;E)?n-+ottZVrJt#dqJvKclJuTgs zJ~MrFdSm*Y^q104qj%K`>@p*YK>&Gmw?1kA&vs<&bXWx?Dnf+XLclPn@Guc07|C;TW zGc0F#PHxWRoU3vwbJpdw8(KGm2*xR~9!EHy5uP|Je9f#=kLsbxC8%mXhmAI!hid zd7|XilJ`nZmwbl^6E3AGrO_00hX?7IM&3h;pY%EqMJ1r1I_!Uc5Ps)(WAn(Fp%tml zDw@VB0@VLXB|OMa76tmzAkI%hLIOgzGjAn4;8tCOn8sClB+?n8B5e`5eKphbWO(#NpC8`e@k1DwuCnE8W9jkqi}HOcGbBfYU=xLJnB!Y#Z_fW=&*c-1yZFF`*&u8 zw>*lpVGe1%2qa0N^Vd0~@<-ivIHXx~Z-QI?Xv9Eep;~`Jd{7D$$m0aLQJf$n3lp?o z)vPXRKS_>t&@S&+ZBiG-zTAEi76BHwNKRlH4`vRcYpf> z``#ipr=3(c%e5W^O(KXXOJ=RV29MH`GT?pD0DR-r$8eFO2XwKW6hVj^-u_Kcq;TR- z+3qdg!)@LB5x2$;^|1nql&w_r{!+!AZf0Qag^vlV`ah0U{|Tf}tz7{r(QR|-H`;n` z?q|*Bk%x#2Vmm|K4;j$8Bl=SDZ7MUOFj6S;GlB}XZDYK_T_Q%{Ws${sv-kB;11Af;|gD)j`XoEEV2l>q-EK+`hPaG2woo0&Mfp%C#z?weVD%-i!ahdZx`~& z=kPhRKNPCP-7j@2iGPc$YU?ejFdv`@r$bhVL`{75C42W#98@}rjg?=j;_JhU-8>{b18>IX?w25odQ<$lAJis8K)Rgd0^yz)n*#m+rTG`Yy9?n8Mkn- z;U*sUBnouIY+eUKXRs`PDXUXk07V>P6-k_dPqgP29pW+DT{?&$1sLOT-aA`7Hvvps zU0%rQtw0x%P2w_D$M2?4mpSW~NF6}<2yeeazYG%~Y^3y52)4#iI z+0}JJ-<9UWj;>71dkzz#fOv+tcm7pUslWE(KSFp@~M zO}vGTkc5*obG^O@LVZNnjxoj?-ixQi<<9#I(0Y z(mB&-6dTz?CF*3F1ojI9%6`}{@TMItLKKe1);`_V`m2Al33mYAIlSHIZCZ`ti)mju zh$Gx(NvHs)Acqd73%bWFU49-ykR(=E)^1l^SCr();XU5oiGQLdifcvg2PB8qQ3^V6 zl2w>XY+kSeq~bOL)c`)i$hjB%rh7YF-vS;;0h`;WdsBmlu?Ev3vE9WKC?&cd=(oLd zI6lUuH%LnHlEFM&NN>aT6C!q`=7_}`PLMl|c&x-94m|$oW7m0HBimu?`B?>pLl9IH z029eAww_N^`E!u0Q6?|7^&C~@Pe-y=nLN?fv!65#LHl*ed&}{@O5lEXW$Fk0y+wFwC2+roGWDhYUV1zw5O0bp z@IKPt8;ti;{P%k)Q*Y@92$+HxbYz34djjkpySK_$y5Yq(kp%@F(tUOwqFX0;ikOYK zqfa{~8ZhFLmZfjEvETY6;sPA8^dY-S>Rf!mj$f^c@7{h)MSoM&^tY7#U9VQhAKkt| zt*4}`S<>~GK`0gh%56QmgWd_;pv1IYts&S@_BV|E9nSua(CCmJ&;E|oXz_cL#)Yr# zF0|`xj=+YLHH>dR|J*$*zF(D`-tGHXLne?ZUFxNaRHOozJ*sOPVE@HSd=#CE@EAx# zc!feW^u|OTA`+6a`;UN?;nO)Vb75bFODBw8{L3O7)~_{fG|*-AX{ep9OZ?fpVC3?x zybH##+HZjc+HZkT4q>K2XAt%v0}L*-S&J5?AA0T1x zxvsB|GUJ)T*U*@U1i@@s?KWOg_3TnHm^Vk6BReegxX_1#V0u?Ekdq9Ao}KacmL_8v zO>Y?kc}oTvHy9*#m!-e;#Sd;#nZh~yRu6({wZOg6i^eCrq4pS-efH+Wb^*y7Pjfb_ znm_P(v&cn3Dl6M&>v3h3Lfbws0C*v0Nw%I6i3*&|GAUS(+4oA_!!DGu1CH`mSwEQt z*bYiK#j-BP21VL3z^1X2Z!`uXz%$;6l8Lvdx6~q3X0O&}?BjA^?2}Elzjw|Oz*jnx zo#waC7>ZrSK6>=}PF9BfQBb42g=VjiT}5M`h)!~AATPvh56V*yOR)1`D% zt*H)?faP@jV(=_oAD7Oq`T>4GdIn4PNSILFP~B9!A^{K?20hvE^t6N%LI$BuK~APr z7akqNQY__!BZes5Oq>my;5sv2V6EaM5Z*<)FNu=b2E7O;Ll|W$a}0W;^jINZ>S^r- z{1~J+Hmv}z!enL&l+wo<^b)1GfmGAT@wn5&Ma}wTJqqIP;&gg%xDxMXwA7k5ie}FN zLb_zhYnKS1nFcC7X;+9VV)O{2wCSJC*0rV^yMaLMT7 z(vqvEtNb!4kQaN3hz*p>{P$QD4niT{0i^40!fGKBxv2af>fQrB$|~yv zp5Btor1vr@q$eaa6+#mjQ0YaKk~KhFQQ9UMK#d^?j44K0q-aD1b+N1k*%d+J3^s7F zv8b!=D%KTdBj}<_Gv)iAd!PHvGm{CT@4oN%eg1xid2TP~o_p@8_S}-8R4@;wtgzD+ z@B$cdE?xovpq)h)4%FpUFovtFk>XxSK!GfrDY1z>B$h7=heKf$%xhAER=A#pW$g_V zZycMFgb_+%wQ@&ID=aPQUpQqb$)>?lGfo*b4f`J^)>}H!uvGpnKZMjO4OOh-JmoM& z;(W=;78@W%@uCG$7`XDG>&2OkTEmn~fZ?Ia za7j_4moCY{O2c{(-m5sWvPx`rJBN^H9=l4?rI7$If}D%lr!QO#b9An75Y7+-3+N6U zfLMdk(>dy+CxQ&Nwo+o^BPgTPxUC=izIwX&?oZzoa+P-;K7hW*E?PPd=Bm_+Z6GE5 zmM6eMSViFLXAU_$g)MGRvrVoMkx<^hwCJ+JQH2u=r~Ckyh>>6s#O zx!03kA3CTbUOI4(;`h|4MvHHu#RIMnI)m}rd;$kB_1qtHPT8rdAxQ;$C#8i`faoD; zzGeicdC>gD6FtqS*oX!WxZdo9Cc+1uWRv=d)@PIIlh(jXB1sc&@=cgrE>Z(TrO2kC zo*F8^S(xPBk&$FFqnKqdCcR`m%G$iyzfDGe1*sxAdHlU7t$3Y~(5QY`+V7da9p(!1 z3At3-@1>v$+^}xgT1BasxcbygKUAipSJ&FQNZ)p4d_Mo ztmyfPGWaU&#wyeg8{n(Co0|639N<@z4N{tEr`-DGREE9nxQQy8VobCInI5kgyr-Db z6a|^0|0SXz6#v;Y_W1_GV7x>W@azjZ7#i>-QHBq0+hIxgWu@Q}7ZSIn!S#OULDyl1JNHnP--#-ok$^ffmqd5`c?fHQH&LXOEGBsh zJrA)BLtfdbS_Rq88<^q-pwTLl^B`w18kg{5#>)&d-Var`Bb|7(!&!EKsNx96#Y`|V zLBg6xdc~Ts5~QIh-(0N2x!oj`m`5vaQ^}}9Vud2y}7CtTJZn-4kyTFo! z8AZuMa!JB@{w2Man8AvMuK;q92bvh!dgAYB(|w z!eLa}f3V&;rm{-_i|?s`x(F8QF%fvIl=lCvUiY70Gs;&kyDeEgpM1N;{V1))JTVFw zUf~-&H-N7+XzTH>zF@WdITsf>044nKp&J=69p2!*-B@-hxzJ=IXb>at9K|}YQ-y;? zHeK?G@=h_9U52H2Tcf;%pA{7)1m6?AD)HH&fYLoNt+Mn#14{Qqy2{cj*$E(X>)adu zZE?5Jk|&AMQWMWmV!lWecx?xzIz*}huQ4Pw4Xg1F5J3NPh-h~I93&|>5{Tqs$Cg&R z>ORgn^oI-z82td`E)}F#kdrdhvQ)0{ zxuSwuS)sigNK2GoE0_PG*Yd?cGdSn$e!5RC|7CCG*(Qb6n98QqND_D%Zw>+R3c}fY zn+|iF^FQ3e?%nTnvU_GSKlOI7bUAhIP0>MCSX4iZZcm_6hWU2MBd0rmXFstd43~YY zEt?LoIt(<)uJTVsVSfr>z+_GVy!8d606hPpVvLwMCw>VSW`@XV@e}8{C zlF?~AY?!0VCf9_QjjRbRb70v@tJ2B_u1KO~ob2g`Rp!`$_x#|OUaOkfiyGA&)M7Zo zaMPJ77X3-!GemrIt!JqyJBgD-7934b)pGIeSCrxQYLO)sT_?W%iZbxqEV87ce-z(- zMPH;2_lYcNtZ$0%o<;v5vZSKlif>kwo%qW(*9KNFnAkV$gs8hXXm8M^O!r?Wj> zwn#oigXoZ3B1Su}^f}oh4`h@Kz12_=e^F7GBllYIF)~K(&w8tYB?dZGT}*$>5*gPx zTkB3Spo@8j^>wgI31x9hfaI*lpZwRflNysR8Ck(QqL)o zrbLI1ZUorQ=8)=;wZZC?%3ylL?}IMboun^ff?1073vWG{r5N#h=hy8{n4!?mPfoPo zST@{wJrCS=PISg#7L+d0Rdpw^&v6Cv(7wcHrugJwq$t=|xx2#KgmD_{i`R zj2h>nIJyoPF5iM6o1?ZsxALuA)$)jKZ{-T| zV%z0g9v-!&$#B8YbdTts*1fDdpgXMlTIbdMpzG9W^s)MM{U!P`{doO6eU<(W{R8^H>A%%S8O9i{ zHIy4}Fw`1W8=4L44UZUJGaNN&j7H-y<0#`a<80&g#!bdn<8I?&A46lp62nTvt_WKhc3apz zVfThT7WQn|-Y|FAt6^V;9Sbv9L#%n$V(WP86zejp(|U)s)%qynSnsjEYW>)H)Oyl- z*4k-}vnAWIZ3VC@S!CO6yWjStZI|s8+dshR6XUe*i z`%)f6#Obz_ms8$M`7Gt@l#{UGFv5x>GqotSU+U$lzkvMN-q zr+$}uJ~cEgBdsWH2BJ}W(@v&!r5Wr6_96BW_LcT#`@{CQH{fw_O&SrFGXfh)+ zvoi}aOEO1fPS3nHvpjQ2=IxnxWZs#%HFJCBbBIxWB=e_CRhBI)E~|gmrCDRMCS}da zx*=D>8$6o-pcwWt1~OEPf?$-edhLA(Z`Kw)kpgL9nq@evh%Y? zXIEt3l+Mn+iNx0v*$+`*5 zn=R_);Z3oZZ(-@W&A1s{v2uq{tlSYyvC>psy;FT; z|JvYsm0$X_r%Jdu8J*!p` zjbvcjrzUZ-$o<59trIh9WA@&zDn0E{jc6T#4=7JGmY;9Dx}zCd6y@ieukL6)f#lM^ zl%6i_ZoLveol(B5sjNmKq*tm%L;{3V4)h%$3e}vg)+@Gg>K*}9G(w^ zt~=Kaj1t;LL>wIzd4AePQe&LE&6SS)l6u!Y+RY7cq|%c5kVE$Q;nR}oiK%$tXKs=} zD%1-4nMEM1dmrO9kY+vQ;#3e9MpmL5Dk;$wivrS9hMcl^CW}Nxn_P*GEt)(`8MBfl zJsWEe#ktTrt#`d@$ji$wpd@#MY405QzfzJr@++0(tjDLH^M8ZLKu-2G5-gJ{ufI+l zWlArL8%V{VVhOwha}9v%;p9))Phrj?=M{%2Tpbb8F=!-luR)^#-!~*}xi?5#?tARs ziw5yJW!iFE1^j-3yjMkD@9;Y!2moI|du}M2$7_T?GCub;kIRS{xX_0uCJ~)Ap)0rN z4OPJ_K{{zZ%yOW|CTw7Wyn3KIN*7$G+!0eHg=Uw(B-d)h8nCw{kH*O=B~T(aVj=z0 z3smX_*ii%M5>tXA+N!aBx@P>XDxZUkP_C2o+1!LONr8=K5YP%&ue)}30iuti%i5d% zCrWl&zDB=`la8u_08+lqrD3(QqmP|~cZINX7$d4H6z$6VCLgG1cj2c0Vm%&mx|f3# zKk zPDbg_f`fKkP%SuAfr1?FeuNkh`e#y8P>Y+yqvA<=X_T%hFa4#8Y(MX1KU~r-lhw^^ zQi4!5qb9hf&?4nxK-XU=2$4=cQ8Cqii$VqLetK%OE`#k9n43y7MK7VSC7~?7baE(w z@h}tMamFLD%!aSll(gqszi*$kh3(7x|d-hm`?vFGf0yMf0o)mA1C$)mg`E)(V={?WYx#f*!6RCs>d$ zgPj9+SCYA1y?ZWkhI}eO@DYcS)K<+{hBTykNE8OrFGh{H8RZ($&H>j<@(eS#n>2yG zgr)As_v0n`clsmjwp-j+6M>T0AfnYFsmHG-E7&SBpd^QMM;n zG{c*varl+>3{bR(3sIU~Ff9nytR&K8L%dA1t)RiU0u9TaB4_u9NQ7T?itL4Q_RL_} ztL1E;`b{gPu`5&2jvTMobA7OO{w%k%P-J`F@@t0+ozkRre^)LasA$60^O(ry#kcj_ zFj=W+;{M(@KBj2G8;3r~0D|OhU+ua0ZgFQ&YI=wS{R$>4>4OBXl0{Ye1*t;X5|ArG z6M$7@VOeFWn<*m9MAcR%JzK7WL=h!foV^92F%NCj&P>SJd?m;0xGa&m?^z|6q&?ed zm9zj@X;NA6rs|-J0Ldfsp0zE65T|UxiZ|Cc*p|vuB_cD(r&% zK}$$5=bvPt<;kLAbO=1z;#Uh03PICkI`QL0GYV*8pfRpS2TnsG{T5P68VpW62&f6) zwGRL%zJyCCBe-OUxqO-;+G}wSqB&hBzBx}FT?dHr`f{x5jg&-rK)oc&o7Jrltugn7 zzmr?yqCB8t@24cn8|sIJ2=|gmk2N4fdc8KVRTAl;R}$&rAEijI*J_pIT)0Bo=PEI< zUvuF|B0hHEC`5cTITeZcuIw?nnkc`d#*3V(!Z+8Yv@vVMs3rVAj1sr|B|>k9>8h~f zDI2G?xCc|w*X5#0kHVKz*83t$!Y#+eHy6N2tuhpGT4YJ!Vh)p#8!O5|n}MJt$D2r( zU7TEq2gp^NQQVX7oUI2!Qq`0PyMM3g_5M{p8Q8tcJNKlD&J@=c6X%^i(+kN@b~Lh2 zI6oHAFLUZhM6leBpHoMPY#L5PFy7jt5LvfMSew_o$`6DB&V3d>1m-d#>uIL z%EC&ojll|+Y2Y%KX%R9%sX{vT-az0Oow(f{Dg z@HukgPu$T6bXP3BLFu1gl|M=8|4H`Y#DCa(_14sTj^vn0ZBLSXGD#<`hg+smBH%o; zxbpeAAu~4iu(UvoKYqgGY1jOmDBmivnWdhr63$23`07{cC1%`}dOtTgh5$D?2jKeykCJ^|^eBn%#XR9U!qa_)CWNF6cs(V` zN**kc!JEH)>!527#AMBN5_@ej1pmh4Ly#z82)w`U7tU0Icz~M6jn$h`0d4&Cm=-d& zoDh$F#5)K#V(Zy4!VA<#RGh!B$h3fy#4!s0PM%ME zCE755*)50P1hbE6(M6+cH;tLUriS1HUT2@Q=auD73u6eTR7=ifDPYFScL1eYKAEcu9iEqE6 z4^!5IBCEx{oxYzF->fL1$pFov*Ul?%Ka;`PkV)SzIG{8eeTgdsC`EJvUaI% zi*Bp#PrCPX3Hnrhk$#|ljDC`Sx_-WXiGHoVQGcKQ5&h%(*WpI?l>Ur9-H>e%7`7O;8+I6;H540X8s`|RjT?4fP&rYLi~d8FB4o?)JAUS@Wh*P8D%ziB>f{>*&LeAYZH?6+Zy!q$cD z2+OqQS}(B|=xT*r5^ABbG!|N8B3G2$i305j!KEk9aZSP{gSSYh-%l@W`o=iy|8%?}>Z>?qc1M zCnB{`QBmdcy(;m|jyE}GY>{qeJW7TmPadYG5#Z|>^jQcU} zTwHv7N_D3wfwd(?CuJq& zC0&wKmb4{lYtkQ+{*?48oWOpSbUf))l0Mmz9G#rWT)^Ive0%ae$q&H&>r2V6B)CgoWEMqV$w3xa??uE2Br;7o0&Eztt##Iv^&xsNP8L% zVc$smDDBgld5Gi6O!}W#L)p(K=+80zUUABxKCy*pwFKnqH*ETT8 zMP`D@v0&K8q2W*>B9^$|}$-^KZ6KW0CH``FGYVSh`{fjQJN;Rv`Y%d=$3N zgAuiT5zNu6ijziF!N)#Q?UhwkORI(;AnlUh(lDIMiVNkI#b~QxdX4eT8Z&hg1~JY_ z<=|bD3R~pDnMpL(30F*;cE!Z8fyMM=CQctS)ih)BZ$?g?I%%e5^rV>+rJv)+IHvQT zAycmyJ5KtonUJY*WNNO?)J)AJ_P0f_zb)GOVNe`gK5^S9_|Sm0)#do7;FS?C#;MPI z`P#71P1>`o4|=-{Go^ecX6z-G)tTJ-IRx5VCDC!7U%WEa#l)RLKeN_RUw2;R93kB{ z0Y2kcsvqq{)>j6{7N-SFTK;nznN_dnyk8?nH#}_I1l!YxO`Cj^fO1{ay3aP?pN4fN(y!Axy=+t< zwp#yoJInwKpOOgW6Z&(M{``afY}<@Kmv2$yur=3p42BLKR6H){uL*yUr_&g46dUVK z-|0BZioI5M8VXEevDh*pY4yQMibChNR4n-xN*2on0Ra-T8`eFoVowQH;u$I-t4|Rt zoh2WkWT8GKr+B&uW*Dp62*+7r-n$SO6unbvkB(fkvOELwy4$OLSz&%zUG3NSvf}-+ zI@^c(vNHX$I@&Xkm0kbR5tVv5_0YFHf)bk6y@y?oFRqP&c6p2YG|o7*r@3Q8&$i8w z_HaI)vmY{Xx_KJcYdDQpj9i#AvZ;nloHH>F8_*ZD9zMM>%$ZU=edQqZWWQIYkV3bDzIvs943xx z=`rB*TI>?aCaA^MAEo>NeqT4@HG+0eksrd!D%e8SuwRu!J*qS*dclLVXO*|9icQfA z3zR8uJ=e=4Z`kASB+zz6| z5B(AkxbEme$dfy|1_SVcs6Dv*!50F(@jU%9(yu?Fy|si-vdz+S8{Y)as1^+D^Qai- zkgO$uWX1e|n8CeO0g;{}U!8g|fO^!)K0RhLbP2$5hMe?v;xP5~4W^#HOU1X(V+Ep+ zk;CD@{;4gEXseE~n?zmIpzk1Uc?SAMSPKUVJz8CTa3Y;ExU}`1X2nX>A~JT6Iz5lG zVkK%3emh7VcAj$;{V*0_7pCbQ&_!I1e%LfbbYe(v#C?0Usx#*rTlplR2^ z4h`W8yQy{fk}s$BcL>?m4vj!ikjlTl+!Da8ZgJ1SZZeO^tv?PY$^RTolS}Yf0;4?| zAmt`K8$xC?P=*wTJe5{?DM;Qg5h+-#{#1e%OHpDLdLc1U(-;Z0_*}8@&In4$!F7|K zZ}D9Cs(@d`$*t$G!WU|cG2ah>dgUgam7)~p#1II^n#8|Wt zzoxdJDGo*F6*mj7D1%M=e6&X!>1!`|OA?NxUggRMFhi*#!3=CWVYx}OAFN+)z)$$^ zXA977X8%xeG)}7kT+uD9A;XCR1U2f@hS?j{H8vj�Viu)uB>7EN>~qZns*oet3+3 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