home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / Dloads / OTHERUTI / WWIV310S.ZIP / BBS.PAS next >
Pascal/Delphi Source File  |  1986-04-02  |  32KB  |  1,060 lines

  1. PROGRAM BBS;
  2.  
  3.                       {*****************************}
  4.                       {Copyright (c) 1986 Wayne Bell}
  5.                       {*****************************}
  6.  
  7.  
  8. {$V-} {$C-}
  9. TYPE j=array[1..8] of string[14];
  10.  
  11. CONST strlen=160;
  12.       comnum=1;
  13.       maxbaud=1200;
  14.       maxusers=300;
  15.       dsaves : Integer = 0;
  16.       buffer_Max    = 5120;
  17.       comptyp:j=('IBM','APPLE','TRS-80','Z-80 CP/M','COMMODORE','ATARI',
  18.                  'DUMB TERMINAL','OTHER');
  19.  
  20. TYPE str=string[strlen];
  21.      restrictions=(rlogon,rchat,rvalidate,rbackspace,ramsg,rpostan,
  22.                    rpost,remail,rvoting,rmsg);
  23.      acrq='@'..'G';
  24.      newtyp=(rp,lt,rm);
  25.      deflts=(spcsr,onekey,wordwrap,pause);
  26.      anontyp=(no,yes,forced,dearabby);
  27.      ansttype=(postn,emailn,pana,sanm,cosysop,lcosysop);
  28.      opts=(alert,smw,nomail);
  29.      pnr=record name:string[40]; number:string[14]; hs:boolean; end;
  30.      slr=record
  31.            ttime:byte;
  32.            mallowed:integer;
  33.            emails,posts:byte;
  34.            anst:set of ansttype;
  35.          end;
  36.      messages=record
  37.                 ltr:char;
  38.                 number:integer;
  39.                 ext:byte;
  40.               end;
  41.      smalrec=record
  42.                name:string[25];
  43.                number:integer;
  44.              end;
  45.      userrec=record
  46.                name:string[25];
  47.                realname:string[14];
  48.                deleted:boolean;
  49.                pw:string[8];
  50.                ph:string[12];
  51.                waiting:byte;
  52.                laston:string[10];
  53.                loggedon:integer;
  54.                msgpost:integer;
  55.                emailsent:integer;
  56.                feedback:integer;
  57.                linelen:byte;
  58.                pagelen:byte;
  59.                defaults:set of deflts;
  60.                ontoday:byte;
  61.                illegal:byte;
  62.                cursor:string[10];
  63.                sl:byte;
  64.                ac:set of restrictions;
  65.                ar:set of acrq;
  66.                qscan:array[1..19] of messages;
  67.                qscn:array[1..19] of boolean;
  68.                macro:array[1..2] of string[79];
  69.                comptype:byte;
  70.                option:set of opts;
  71.                vote:array[1..9] of byte;
  72.                sbn:byte;
  73.                dsl:byte;
  74.                uploads,downloads:integer;
  75.                uk,dk:integer;
  76.              end;
  77.       boardrec=record
  78.                  name:string[25];
  79.                  filename:string[12];
  80.                  sl:byte;
  81.                  maxmsgs:byte;
  82.                  pw:string[10];
  83.                  anonymous:anontyp;
  84.                  ar:acrq;
  85.                  key:char;
  86.                end;
  87.       msgstat=(validated,unvalidated,deleted);
  88.       messagerec=record
  89.                    title:string[30];
  90.                    messagestat:msgstat;
  91.                    message:messages;
  92.                    owner:integer;
  93.                    date:integer;
  94.                    mage:byte;
  95.                  end;
  96.       systatrec=record
  97.                   boardpw:string[8];
  98.                   sysoppw:string[8];
  99.                   hmsg:messages;
  100.                   users:integer;
  101.                   lastdate:string[8];
  102.                   callernum:integer;
  103.                   activetoday:integer;
  104.                   callstoday:integer;
  105.                   msgposttoday:integer;
  106.                   emailtoday:integer;
  107.                   fbacktoday:integer;
  108.                   uptoday:integer;
  109.                   closedsystem:boolean;
  110.                 end;
  111.       blk=array[1..255] of byte;
  112.       mailrec=record
  113.                 title:string[30];
  114.                 from,destin:integer;
  115.                 msg:messages;
  116.                 date:integer;
  117.                 mage:byte;
  118.               end;
  119.       gft=record
  120.             num:integer;
  121.             title:string[40];
  122.             filen:string[12];
  123.           end;
  124.       charfil=text;
  125.       smr=record
  126.             msg:str;
  127.             destin:integer;
  128.           end;
  129.       vdatar=record
  130.                question:string[79];
  131.                numa:integer;
  132.                answ:array[0..9] of record
  133.                       ans:string[25];
  134.                       numres:integer;
  135.                     end;
  136.              end;
  137.       regs=record ax,bx,cx,dx,bp,si,di,ds,es,flags:integer; end;
  138.       ulrec=record
  139.               name:string[25];
  140.               filename:string[12];
  141.               password:string[10];
  142.               dsl:byte;
  143.               maxfiles:integer;
  144.             end;
  145.  
  146. var sf:file of smalrec;
  147.     uf:file of userrec;
  148.     bf:file of boardrec;
  149.     mf:file of messagerec;
  150.     mailfile:file of mailrec;
  151.     sysopf:charfil;
  152.     slf:file of slr;
  153.     seclev:array[0..255] of slr;
  154.     systatf:file of systatrec;
  155.     systat:systatrec;
  156.     sr:smalrec;
  157.     thisline,chatr,buf,spd,irt,lastname,ll,cursor,i:str;
  158.     thisuser,user:userrec;
  159.     boards:array[1..19] of boardrec;
  160.     fw,extramsgs,mread,board,numboards,t,usernum:integer;
  161.     pap,lil,realsl,ftoday,ptoday,etoday:integer;
  162.     c,ID:char;
  163.     hungup,useron,next,chatcall,expert,doneday,echo,hangup,incom,outcom:boolean;
  164.     extratime,timeon:real;
  165.     macok,lan,enddayf,ch,quit:boolean;
  166.     buffer:Array[0..buffer_Max] of Char;
  167.     comport,base:Integer;
  168.     Async_Irq:Integer;
  169.     buffer_Head,buffer_tail,buffer_newtail:Integer;
  170.     smf:file of smr;
  171.     srl:array[0..maxusers] of smalrec;
  172.     vqu:array[1..9] of boolean;
  173.     ret:byte absolute cseg:$0080;
  174.     ldate:integer;
  175.     maxspd:integer;
  176.     cmd:char;
  177.     help:array[1..25000] of char;
  178.     helpi:array['0'..'^'] of integer;
  179.     helpl:char;
  180.     ihelp:boolean;
  181.     cf:text; cfo,okt:boolean;
  182.     elevel:byte;
  183.  
  184. label reent,reent1;
  185.  
  186. {$I COMMON.PAS}
  187. {$I PART1.PAS}
  188.  
  189. procedure dos(c:char);
  190. var f:file;
  191. begin
  192.   cmd:=upcase(c);
  193.   assign(f,'dos.chn');
  194.   {$I-} reset(f); {$I+}
  195.   if ioresult=0 then begin
  196.     print('Loading.');
  197.     close(f);
  198.     remove_port;
  199.     chain(f);
  200.   end else print('Dos system not present.');
  201. end;
  202.  
  203. function greater(mrec:messages):boolean;
  204. begin
  205.  if mrec.ext>thisuser.qscan[board].ext then greater:=true else
  206.   if mrec.ltr>thisuser.qscan[board].ltr then greater:=true else
  207.     if (mrec.ltr=thisuser.qscan[board].ltr) and (mrec.number>thisuser.qscan[board].number) then
  208.       greater:=true
  209.     else greater:=false;
  210. end;
  211.  
  212. procedure mcursor;
  213. var i:integer;
  214. begin
  215.   cursor:='';
  216.   for i:=1 to length(thisuser.cursor) do
  217.     cursor:=cursor+thisuser.cursor[i]+chr(8);
  218. end;
  219.  
  220. function maxage(x:integer):integer;
  221. begin
  222.   maxage:=255;
  223.   if x<20 then
  224.     maxage:=5
  225.   else if x<30 then
  226.     maxage:=14
  227.   else if x<40 then
  228.     maxage:=90
  229.   else if x<60 then
  230.     maxage:=120;
  231. end;
  232.  
  233. function boardac(nb:integer):boolean;
  234. var i:str;
  235. begin
  236.   boardac:=false;
  237.   if cs then boardac:=true else
  238.     if (thisuser.sl>=boards[nb].sl) and
  239.     ((boards[nb].ar='@') or (boards[nb].ar in thisuser.ar)) then
  240.     if boards[nb].pw='' then boardac:=true else begin
  241.       prompt('Password? '); input(i,10);
  242.       if i=boards[nb].pw then boardac:=true else print('Wrong.');
  243.     end;
  244. end;
  245.  
  246. function mln(i:str; l:integer):str;
  247. begin
  248.   while length(i)<l do i:=i+' ';
  249.   mln:=i;
  250. end;
  251.  
  252. function mn(i,l:integer):str;
  253. begin
  254.   mn:=mln(cstr(i),l);
  255. end;
  256.  
  257. procedure inu(var i:integer);
  258. var s:str;
  259. begin
  260.   input(s,3); i:=value(s);
  261. end;
  262.  
  263. procedure ini(var i:byte);
  264. var s:str;
  265. begin
  266.   input(s,3); i:=value(s);
  267. end;
  268.  
  269. function rmail(n:integer):str;
  270. var tu,cn,c:integer; f:file; mr,mr1:mailrec; u:userrec; dm:boolean;
  271. begin
  272.   dm:=true;
  273.   seek(mailfile,n); read(mailfile,mr); tu:=mr.destin;
  274.   if mr.msg.ext>128 then begin
  275.     for c:=0 to filesize(mailfile)-1 do begin
  276.       seek(mailfile,c); read(mailfile,mr1);
  277.       if (mr1.msg.ltr=mr.msg.ltr) and (mr1.msg.number=mr1.msg.number)
  278.       and (mr.msg.ext=mr1.msg.ext) and (c<>n) and (mr1.destin<>-1) then
  279.         dm:=false;
  280.     end;
  281.   end;
  282.   if dm then begin
  283.     assign(f,filename(mr.msg)); {$I-} erase(f); {$I+} cn:=ioresult;
  284.   end;
  285.   mr.destin:=-1; mr.from:=0; mr.mage:=0;
  286.   seek(mailfile,n); write(mailfile,mr);
  287.   reset(uf);
  288.   if (tu>0) and (tu<filesize(uf)) then begin
  289.     seek(uf,tu); read(uf,u); u.waiting:=u.waiting-1;
  290.     seek(uf,tu); write(uf,u);if tu=1 then fw:=fw-1;
  291.   end;
  292.   close(uf);
  293.   rmail:=u.name+' #'+cstr(tu);
  294. end;
  295.  
  296. procedure isr(uname:str;usernum:integer);
  297. var t,i,ii:integer; sr:smalrec;
  298. begin
  299.  ii:=systat.users; i:=0;
  300.  while (ii-i)>1 do begin
  301.    t:=(ii+i) div 2;
  302.    if uname<srl[t].name then
  303.      ii:=t
  304.    else
  305.      i:=t;
  306.  end;
  307.  if srl[ii].name<uname then i:=ii;
  308.  for ii:=systat.users downto i+1 do
  309.    srl[ii+1]:=srl[ii];
  310.  sr.name:=uname; sr.number:=usernum;
  311.  srl[i+1]:=sr;
  312.  systat.users:=systat.users+1; reset(systatf);write(systatf,systat);
  313.  close(systatf);
  314.  rewrite(sf); for ii:=0 to systat.users do write(sf,srl[ii]); close(sf);
  315. end;
  316.  
  317. procedure dsr(uname:str);
  318. var i,rn:integer; sr:smalrec;
  319. begin
  320.   rn:=0;
  321.   for i:=1 to systat.users do
  322.     if srl[i].name=uname then
  323.       rn:=i;
  324.   if rn<>0 then begin
  325.     for i:=rn to systat.users-1 do srl[i]:=srl[i+1];
  326.     reset(systatf); systat.users:=systat.users-1;
  327.     write(systatf,systat); close(systatf);
  328.     rewrite(sf); for i:=0 to systat.users do write(sf,srl[i]); close(sf);
  329.   end else sl1('*** Couldn''t delete "'+uname+'"');
  330. end;
  331.  
  332. procedure ssm(dest:integer; s:str);
  333. var x:smr; e,cp,t:integer; u:userrec;
  334. begin
  335.   {$I-} reset(smf);{$I+}
  336.   if ioresult<>0 then rewrite(smf);
  337.   e:=filesize(smf);
  338.   if e=0 then cp:=0 else begin
  339.     t:=e-1;
  340.     seek(smf,t); read(smf,x);
  341.     while (T>0) and (x.destin=-1) do begin
  342.       t:=t-1; seek(smf,t); read(smf,x);
  343.     end;
  344.     cp:=t+1;
  345.   end;
  346.   seek(smf,cp); x.msg:=s; x.destin:=dest;
  347.   write(smf,x);
  348.   close(smf);
  349.   reset(uf); seek(uf,dest); read(uf,u);
  350.   if not (smw in u.option) then
  351.     begin u.option:=u.option+[smw]; seek(uf,dest); write(uf,u); end;
  352.   close(uf);
  353.   if (dest=usernum) then thisuser.option:=thisuser.option+[smw];
  354. end;
  355.  
  356. procedure rsm;
  357. var x:smr; i:integer;
  358. begin
  359.   {$I-} reset(smf); {$I+}
  360.   if ioresult=0 then begin
  361.     i:=0;
  362.     repeat
  363.       if i<=filesize(smf)-1 then begin seek(smf,i); read(smf,x); end;
  364.       while (i<filesize(smf)-1) and (x.destin<>usernum) do begin
  365.         i:=i+1; seek(smf,i); read(smf,x);
  366.       end;
  367.       if (x.destin=usernum) and (i<=filesize(smf)-1) then begin
  368.         print(x.msg);
  369.         seek(smf,i); x.destin:=-1; write(smf,x);
  370.       end;
  371.       i:=i+1;
  372.     until (i>filesize(smf)-1) or hangup;
  373.     close(smf);
  374.   end;
  375. end;
  376.  
  377. procedure email(touser:integer);
  378. var mr:mailrec; t,e,cp:integer; f:messages; a:anontyp; i:str; us:userrec;
  379. begin
  380.   if (remail in thisuser.ac) or ((touser<>1) and (etoday>=seclev[thisuser.sl].emails) and  (thisuser.sl<55))
  381.   or hangup or ((touser=1) and (ftoday>=5))
  382.   then print('Too much mail sent today.') else
  383.    if (touser=usernum) and (realsl<>255) then
  384.      print('Can''t E-mail yourself.') else begin
  385.     a:=no; if sanm in seclev[thisuser.sl].anst then a:=yes;
  386.     reset(uf); seek(uf,touser); read(uf,user); close(uf);
  387.     if ((touser=1) and (user.waiting>50)) or ((touser<>1) and
  388.     (user.waiting>15)) or ((nomail in user.option) and not cs)
  389.     then print('Can''t send him mail.') else
  390.      if user.deleted then print('That user is deleted.') else begin
  391.       inmsg(f,a,i,false,false);
  392.       if f.ext<>0 then begin
  393.         {$I-} reset(mailfile); {$I+}
  394.         if (ioresult<>0) then
  395.           rewrite(mailfile);
  396.         e:=filesize(mailfile);
  397.         if e=0 then cp:=0 else begin
  398.           cp:=-1; t:=e-1;
  399.           seek(mailfile,t); read(mailfile,mr);
  400.           while (t>0) and (mr.destin=-1) do begin
  401.             t:=t-1; seek(mailfile,t); read(mailfile,mr);
  402.           end;
  403.           cp:=t+1;
  404.         end;
  405.         seek(mailfile,cp);
  406.         mr.msg:=f; if lan then mr.from:=-usernum else mr.from:=usernum;
  407.         mr.destin:=touser;
  408.         mr.title:=i; mr.date:=daynum(date);
  409.         mr.mage:=maxage(thisuser.sl);
  410.         write(mailfile,mr);
  411.         if touser=1 then begin thisuser.feedback:=thisuser.feedback+1;
  412.           ftoday:=ftoday+1; fw:=fw+1; end else begin thisuser.emailsent:=
  413.           thisuser.emailsent+1; etoday:=etoday+1; end;
  414.         close(mailfile); reset(uf); seek(uf,touser); read(uf,user);
  415.         user.waiting:=user.waiting+1; seek(uf,touser); write(uf,user);
  416.         if touser=usernum then thisuser.waiting:=thisuser.waiting+1;
  417.         i:=user.name+' #'+cstr(touser);
  418.         close(uf); topscr;
  419.         sysoplog('Mail sent to '+i);
  420.         print('Mail sent to '+i);
  421.       end;
  422.     end;
  423.   end;
  424. end;
  425.  
  426. function ctp(t,b:integer):str;
  427. var i,i1:str; n:real;
  428. begin
  429.   i:=cstr((t*100) div b); if length(i)=1 then i:=' '+i; i:=i+'.';
  430.   if length(i)=3 then i:=' '+i;
  431.   n:=t/b+0.0005;
  432.   i1:=cstr(trunc(n*1000) mod 10);
  433.   ctp:=i+i1+'%';
  434. end;
  435.  
  436. procedure finduser(var usernum:integer);
  437. var t,i,i1:integer;
  438.     nn:str;
  439. begin
  440.   input(nn,25);
  441.   usernum:=value(nn); if usernum>0 then begin
  442.     reset(uf);
  443.     if usernum>filesize(uf)-1 then begin
  444.       print('Unknown User.');
  445.       usernum:=0; end
  446.     else begin
  447.       seek(uf,usernum);
  448.       read(uf,user);
  449.       if user.deleted then begin
  450.         print('Unknown User.');
  451.         usernum:=0; end;
  452.       end;
  453.     close(uf); end
  454.   else begin
  455.     i:=1; i1:=systat.users; t:=(i1+i) div 2;
  456.     while ((i1-i)>1) and (srl[t].name<>nn) do begin
  457.       if srl[t].name<nn then
  458.         i:=t
  459.       else
  460.         i1:=t;
  461.       t:=(i1+i) div 2;
  462.     end;
  463.     usernum:=0;
  464.     if srl[i].name=nn then usernum:=srl[i].number;
  465.     if srl[i1].name=nn then usernum:=srl[i1].number;
  466.     if srl[t].name=nn then usernum:=srl[t].number;
  467.     if nn='NEW' then usernum:=-1;
  468.     if usernum=0 then print('Unknown User.');
  469.    end;
  470.  end;
  471.  
  472. procedure imail(i:integer);
  473. begin
  474.   reset(uf); seek(uf,i); read(uf,user); close(uf);
  475.   if user.deleted then begin
  476.     print('That user is deleted.');
  477.   end else begin
  478.     prompt('E-mail '+user.name+' #'+cstr(i)+'? ');
  479.     if yn then email(i);
  480.   end;
  481. end;
  482.  
  483. procedure readamsg;
  484. var filv:text; i,n:str; ii:integer;
  485. begin
  486.   nl;nl;assign(filv,'gfiles\auto.msg');
  487.   {$I-} reset(filv); {$I+}
  488.   if ioresult<>0 then print('No Auto-message') else begin
  489.     readln(filv,n); if n[1]='@' then
  490.       if postn in seclev[thisuser.sl].anst then n:='<<< '+copy(n,2,length(n))+' >>>'
  491.       else n:='>UNKNOWN<';
  492.     print('Auto message by: '+n); nl;
  493.     for ii:=1 to 3 do begin
  494.       readln(filv,i); print(i); end;
  495.     close(filv);
  496.   end;
  497.   nl;nl;
  498. end;
  499.  
  500. procedure autoreply;
  501. var i:integer; c:char;
  502. begin
  503.   if lastname='' then print('Can''t Auto-reply now.') else begin
  504.     i:=length(lastname);
  505.     while (lastname[i]<>'#') and (i>1) do i:=i-1;
  506.     i:=value(copy(lastname,i+1,5));
  507.     if i=0 then print('It seems I can''t do that now.') else imail(i);
  508.   end;
  509. end;
  510.  
  511. procedure vali(un:integer);
  512. var i:integer; c:char; ii:str; r:restrictions;
  513. begin
  514.   reset(uf); seek(uf,un); read(uf,user);
  515.   print('Name: '+user.name+' #'+cstr(un));
  516.   print('RN  : '+user.realname);
  517.   print('PH  : '+user.ph);
  518.   print('SL  : '+cstr(user.sl));
  519.   if user.sl=99 then print('SBN : '+cstr(user.sbn));
  520.   prompt('Enter new sl : '); input(ii,3);
  521.   if ii<>'' then begin
  522.     i:=value(ii); if i<>255 then user.sl:=i;
  523.   end;
  524.   if user.sl=99 then begin
  525.     prompt('Which board #? '); input(ii,2);
  526.     user.sbn:=value(ii);
  527.   end;
  528.   print('      LCVBA*PEKM');
  529.   repeat
  530.     prompt('AC  : ');
  531.     for r:=rlogon to rmsg do
  532.     if r in user.ac then prompt(copy('LCVBA*PEKM',ORD(R)+1,1)) else prompt(' '); nl;
  533.     prompt('Which? ');
  534.     getkey(c); c:=upcase(c); print(c);acch(c,user);
  535.   until (c=chr(13)) or hangup;
  536.   print('DSL : '+cstr(user.dsl));
  537.   prompt('Enter new dsl : '); input(ii,3);
  538.   if ii<>'' then user.dsl:=value(ii);
  539.   seek(uf,un); write(uf,user); close(uf);
  540. end;
  541.  
  542. procedure vallastuser;
  543. var i:integer;
  544. begin
  545.   if lastname='' then print('Can''t validate anyone.') else begin
  546.     i:=length(lastname);
  547.     while (lastname[i]<>'#') and (i>1) do i:=i-1;
  548.     i:=value(copy(lastname,i+1,5));
  549.     if i=0 then print('Oops, there''s a problem.') else vali(i);
  550.   end;
  551. end;
  552.  
  553. procedure iscan(var pl:integer);
  554. var b:messagerec;
  555. begin
  556.   assign(mf,'gfiles\'+boards[board].filename);
  557.   {$I-} reset(mf); {$I+}
  558.   if (ioresult=0) then begin
  559.     read(mf,b);
  560.     pl:=b.message.number;
  561.   end else begin
  562.     rewrite(mf);
  563.     b.message.number:=0;
  564.     write(mf,b);
  565.     pl:=0;
  566.     close(mf);
  567.     reset(mf);
  568.     read(mf,b);
  569.   end;
  570. end;
  571.  
  572. procedure deletem(var pl:integer; ntd:integer);
  573. var b:messagerec; filvar:file; t:integer;
  574. begin
  575.   seek(mf,ntd); read(mf,b);  assign(filvar,filename(b.message));
  576.   {$I-} erase(filvar); {$I+} t:=ioresult; pl:=pl-1;
  577.   for t:=ntd+1 to pl+1 do begin
  578.     seek(mf,t);read(mf,b); seek(mf,t-1); write(mf,b);
  579.   end;
  580.   seek(mf,0); b.message.number:=pl; write(mf,b);
  581. end;
  582.  
  583. procedure readm(cn:integer; var next:boolean; var unvali:boolean; pl:integer);
  584. var i:str; b:messagerec; ratall,rname:boolean;
  585. begin
  586.   nl;nl;
  587.   ratall:=true; next:=false;unvali:=false;
  588.   seek(mf,cn); read(mf,b);
  589.   if b.messagestat<>validated then begin  unvali:=true;
  590.     print(cstr(cn)+'/'+cstr(pl)+': <<< NOT VALIDATED YET >>>');
  591.     lastname:='';
  592.     if not lcs then ratall:=false;
  593.   end;
  594.   if ratall then begin
  595.     print(cstr(cn)+'/'+cstr(pl)+': '+b.title); irt:=b.title;
  596.     if postn in seclev[thisuser.sl].anst then rname:=true else rname:=false;
  597.     if (thisuser.sl=255) then writeln('Days left: '+
  598.       cstr(b.date-daynum(date)+b.mage));
  599.     readmsg(b.message,rname,next); tleft;
  600.     if greater(b.message) then thisuser.qscan[board]:=b.message;
  601.   end;
  602. end;
  603.  
  604.  
  605. {$I PART2.PAS}
  606. {$I PART3.PAS}
  607.  
  608. procedure dloads;
  609. var f:file; ok:boolean;
  610. begin
  611.   ok:=true;
  612.   if (thisuser.sl<=10) or (thisuser.dsl=0) then ok:=false;
  613.   if cs then ok:=true;
  614.   if not ok then print('You can''t access the file system.') else
  615.   begin
  616.     assign(f,'dloads.chn');
  617.     {$I-} reset(f); {$I+}
  618.     if ioresult=0 then begin
  619.       print('Loading file system...');
  620.       close(f);
  621.       remove_port;
  622.       chain(f);
  623.     end else print('File system not present.');
  624.   end;
  625. end;
  626.  
  627. procedure getcaller;
  628. var c:char; x:smr; chkcom:boolean; rl,rl1:real; i:str;
  629.  
  630.   procedure init1;
  631.   begin
  632.     set_baud(maxbaud);
  633.     if maxbaud=300 then pr('ATS0=0Q0V0E0M0S2=1');
  634.     if maxbaud=1200 then pr('ATS0=0Q0V0E0M0S2=1X1');
  635.     if maxbaud=2400 then pr('ATS0=0Q0V0E0M0S2=1X1');
  636.     dump;
  637.   end;
  638.  
  639.   procedure i1;
  640.   begin
  641.     init1; c:=#0; write('Waiting...'); rl:=timer;
  642.     repeat
  643.       c:=cinkey;if abs(timer-rl)>4.0 then begin init1; rl:=timer; end;
  644.     until c=#13; delay(50);
  645.   end;
  646.  
  647. begin
  648.   buf:=''; enddayf:=false; delay(50);
  649.   dump;
  650.   window(1,1,80,25); clrscr; chatr:='';
  651.   outcom:=false; useron:=false; ll:='';
  652.   hangup:=false; usernum:=0; chatcall:=false; hungup:=false;
  653.   term_ready(true); i1; clrscr; thisline:=''; okt:=false;
  654.   if systat.users>0 then
  655.     begin reset(uf); seek(uf,1); read(uf,thisuser); close(uf); mcursor; usernum:=1; end;
  656.   repeat
  657.     if daynum(date)<>ldate then
  658.       if (daynum(date)-ldate)=1 then
  659.         ldate:=ldate+1
  660.       else begin
  661.         writeln('Date corrupted.');
  662.         halt(1);
  663.       end;
  664.     randomize; incom:=false; outcom:=false; ihelp:=false; helpl:=#0; ret:=201;
  665.     hangup:=false; hungup:=false; irt:=''; lastname:=''; macok:=true; cfo:=false;
  666.     spd:='KB'; c:=#0; chkcom:=false; c:=inkey; if c<>chr(0) then begin
  667.       c:=upcase(c);
  668.       case c of
  669.         'V':uedit(1);
  670.         ' ':begin
  671.               write('Log on? '); read(kbd,c); c:=upcase(c); writeln(c);
  672.               if c='Y' then c:=' ' else c:='@';
  673.             end;
  674.         'Q':begin elevel:=0; hangup:=true; doneday:=true; end;
  675.         'L':begin printfile('gfiles\sysop.log');getkey(c); c:='@';end;
  676.         'Y':begin printfile('gfiles\ysysop.log');getkey(c); c:='@';end;
  677.         'A':chkcom:=true;
  678.         'S':pstat;
  679.         'M':mailr;
  680.         'B':boardedit;
  681.         'T':dos('T');
  682.         'E':dos('E');
  683.         'G':dos('G');
  684.         'P':changestuff;
  685.         'D':dlboardedit;
  686.         'R':if systat.users>0 then begin print('Feedback: '); nl; nl;
  687.               macok:=true; readmail; macok:=false;
  688.               reset(uf); seek(uf,1); write(uf,thisuser); close(uf);
  689.             end;
  690.         'F':dos('D');
  691.       end;
  692.       clrscr; dump;
  693.     end;
  694.     if c<>' ' then c:=#0;
  695.     if commpressed then c:=cinkey;
  696.     if c='2' then begin
  697.       chkcom:=true; rl:=timer; write('* ');
  698.       while (c<>#13) and (abs(rl-timer)<0.2) do c:=cinkey;
  699.     end;
  700.     if chkcom then begin
  701.       pr('ATA'); writeln('Answering phone, "H" to abort');
  702.       delay(50); dump; rl1:=timer; i:=''; rl:=0.0;
  703.       repeat
  704.         chkcom:=false;
  705.         if keypressed then begin read(kbd,c);
  706.           if upcase(c)='H' then begin chkcom:=true; pr('A');end;
  707.         end;
  708.         c:=cinkey;
  709.         if (rl<>0.0) and (abs(rl-timer)>2.0) and (c=#0) then c:=#13;
  710.         if c<>#0 then
  711.           if c<>#13 then begin i:=i+c; rl:=timer; end else begin
  712.             if i='1' then begin spd:='300'; chkcom:=true; end;
  713.             if i='5' then begin spd:='1200'; chkcom:=true; end;
  714.             if i='10' then begin spd:='2400'; chkcom:=true; end;
  715.             if i='3' then chkcom:=true;
  716.             rl:=0.0;
  717.           end;
  718.         if c=#13 then i:='';
  719.         if abs(timer-rl1)>45.0 then chkcom:=true;
  720.       until chkcom;
  721.       if abs(timer-rl1)>45.0 then i1;
  722.       clrscr;
  723.     end;
  724.     if spd<>'KB' then incom:=true;
  725.   until incom or (c=' ') or doneday;
  726.   etoday:=0; ptoday:=0; ftoday:=0; if not doneday then writeln('Logging on...');
  727.   if incom then begin
  728.     outcom:=true;
  729.     set_baud(value(spd));
  730.     delay(1000);
  731.   end else begin term_ready(false); incom:=false; outcom:=false; end;
  732.   timeon:=timer; ftoday:=0;
  733.   dump;
  734.   window(1,5,80,25); lil:=0; okt:=true;
  735. end;
  736.  
  737. procedure post;
  738. var b:messagerec; pl:integer; i:str; mesag:messages; a:anontyp; c:char;
  739. begin
  740.  irt:='';
  741.  if ((ptoday>=seclev[thisuser.sl].posts) and (thisuser.sl<55)) or (rpost in
  742.  thisuser.ac) or (thisuser.sl<boards[board].sl) then
  743.    print('Too many messages posted today.') else begin
  744.   iscan(pl);
  745.   if pl>=boards[board].maxmsgs then deletem(pl,1);
  746.   a:=boards[board].anonymous;
  747.   if (a=no) and (pana in seclev[thisuser.sl].anst) then
  748.     a:=yes;
  749.   if rpostan in thisuser.ac then a:=no;
  750.   inmsg(mesag,a,i,true,false);
  751.     if mesag.ext<>0 then begin
  752.       b.message:=mesag;
  753.       b.title:=i;
  754.       b.owner:=usernum;
  755.       b.date:=daynum(date);
  756.       b.mage:=maxage(thisuser.sl);
  757.       if rvalidate in thisuser.ac then
  758.         b.messagestat:=unvalidated else b.messagestat:=validated;
  759.       if rmsg in thisuser.ac then b.messagestat:=deleted;
  760.       pl:=pl+1; seek(mf,pl); write(mf,b);
  761.       seek(mf,0); b.message.number:=pl; write(mf,b);
  762.       thisuser.msgpost:=thisuser.msgpost+1; ptoday:=ptoday+1;
  763.       systat.msgposttoday:=systat.msgposttoday+1;
  764.       sysoplog('+'+i+' posted on '+boards[board].name); topscr;
  765.       print('Message posted on '+boards[board].name+'.');
  766.     end;
  767.   close(mf);
  768.  end;
  769. end;
  770.  
  771. procedure titles(var cn:integer; pl:integer);
  772. var abort,next:boolean; nl:integer; b:messagerec; i:str;
  773. begin
  774.   nl:=0;
  775.   abort:=false;
  776.   while (not abort) and (nl<10) and (cn<=pl) do begin
  777.     seek(mf,cn); read(mf,b);
  778.     if b.owner=usernum then i:='['+cstr(cn)+']' else i:='('+cstr(cn)+')';
  779.     while length(i)<8 do i:=' '+i; i:=i+' '+b.title;
  780.     if greater(b.message) then i[1]:='*';
  781.     if b.messagestat<>validated then if lcs
  782.       then begin
  783.         i[1]:='N'; i[2]:='V';
  784.       end else
  785.         i:=copy(i,1,9)+'<<< NOT VALIDATED YET >>>';
  786.     printacr(i,abort,next);
  787.     nl:=nl+1;cn:=cn+1;
  788.   end;
  789.   cn:=cn-1;
  790. end;
  791.  
  792. procedure scan2(pl:integer; var cn:integer; iread:newtyp; var quit:boolean);
  793. var unvali,uv,pq,donescan,abort,next:boolean; i:str; t:integer;
  794.  b:messagerec;
  795. begin
  796.   quit:=false;pq:=false; unvali:=false; helpl:='S';
  797.   donescan:=false;
  798.   repeat
  799.     if iread=lt then begin cn:=cn+1; titles(cn,pl); iread:=rp; end;
  800.     if iread=rp then begin
  801.       tleft; prompt('Read:(1-'+cstr(pl)+',^'+cstr(cn)+'),T,R,Q,P,A,? :');
  802.       input(i,4); t:=value(i);
  803.       if i='R' then begin t:=cn; i:=cstr(t); end;
  804.       if (i<>'') and (t=0) then case i[1] of
  805.         'P':begin close(mf);post; iscan(pl); end;
  806.         'T':iread:=lt;
  807.         'Q':begin quit:=true; donescan:=true; end;
  808.         'B':donescan:=true;
  809.         'D':if lcs and (cn>0) and (cn<=pl) then begin
  810.               deletem(pl,cn); cn:=cn-1;
  811.             end;
  812.         'A':autoreply;
  813.         'V':if cs then vallastuser;
  814.         'M':if cs then movemsg(pl,cn);
  815.         '?':begin
  816.               print('Read:number');
  817.               print('<CR>=next');
  818.               print('T:itles     Q:uit');
  819.               print('P:ost       A:uto-reply');
  820.               print('R:e-read    B:next board in N-scan');
  821.             end;
  822.       end else begin
  823.         if (t>0) and (t<=pl) then begin
  824.           cn:=t;
  825.           iread:=rm;
  826.         end else if i='' then begin
  827.           t:=cn+1;
  828.           if t<=pl then begin
  829.             cn:=t;
  830.             iread:=rm;
  831.           end else begin donescan:=true; pq:=true; end;
  832.         end;
  833.       end;
  834.     end;
  835.     if (iread=rm) and (cn>0) and (cn<=pl) then begin
  836.       readm(cn,next,uv,pl); if uv then unvali:=true;
  837.       if next then cn:=cn+1 else iread:=rp;
  838.       mread:=mread+1; tleft;
  839.       if (mread>=extramsgs+seclev[thisuser.sl].mallowed)
  840.       and (thisuser.sl<>255) and (thisuser.ontoday<>1) then begin
  841.         print('You have read all your messages.');
  842.         hangup:=true;
  843.       end;
  844.       if (mread+5=extramsgs+seclev[thisuser.sl].mallowed) and (thisuser.ontoday<>1) then
  845.         print('5 messages left until forced logoff');
  846.     end else if iread=rm then iread:=rp;
  847.     if (iread=rm) and (cn=pl+1) then begin donescan:=true; pq:=true; end;
  848.   until donescan or hangup;
  849.   if unvali and lcs then begin
  850.     prompt(chr(7)+'Validate messages here? ');
  851.     if yn then for t:=1 to pl do begin
  852.       seek(mf,t); read(mf,b); if b.messagestat<>validated then begin
  853.         b.messagestat:=validated; seek(mf,t); write(mf,b);
  854.       end;
  855.     end;
  856.   end;
  857.   if pq then begin
  858.     nl;prompt('Post on '+boards[board].name+'? ');
  859.     if yn then begin close(mf); post; iscan(pl); end;
  860.   end;
  861.   nl;
  862. end;
  863.  
  864. procedure scan1;
  865. var pl,cn:integer; i:str; quit:boolean;
  866. begin
  867.   iscan(pl); helpl:='N';
  868.   print(cstr(pl)+' msgs on '+boards[board].name);
  869.   if pl<>0 then begin
  870.     prompt('Start listing at? ');
  871.     input(i,4);
  872.     cn:=value(i); if cn<=0 then cn:=0 else  if cn>pl then cn:=pl else cn:=cn-1;
  873.     if i='S' then scan2(pl,cn,rp,quit) else
  874.       if (i<>'Q') then
  875.         scan2(pl,cn,lt,quit);
  876.   end;
  877.   close(mf);
  878. end;
  879.  
  880.  
  881. procedure qscan(var quit:boolean);
  882. var b:messagerec; pl,cn:integer; i:str;
  883. begin
  884.   iscan(pl);
  885.   if boards[board].key=' ' then i:='#'+cstr(board) else i:=boards[board].key;
  886.   cn:=1; nl; print('< Q-scan '+boards[board].name+' '+i+' - '+cstr(pl)+' msgs >');
  887.   if pl<>0 then begin
  888.     seek(mf,1); read(mf,b);
  889.     while (not greater(b.message)) and (cn<pl) do begin
  890.       cn:=cn+1; seek(mf,cn); read(mf,b);
  891.     end;
  892.     if greater(b.message) then scan2(pl,cn,rm,quit) else quit:=false;
  893.   end;
  894.   print('< '+boards[board].name+' Q-scan done >');
  895.   close(mf);
  896. end;
  897.  
  898. procedure nscan;
  899. var quit:boolean;
  900. begin
  901.   nl;nl;print('<< Q-scan all >>');
  902.   board:=1; quit:=false;
  903.   while (board<=numboards) and (not quit) and (not hangup) do begin
  904.    if thisuser.qscn[board] then
  905.      if boardac(board) then qscan(quit);
  906.    board:=board+1;
  907.   end;
  908.   nl;print('<<Global Q-scan done>>');nl;
  909.   board:=1;
  910. end;
  911.  
  912. procedure mmkey(var i:str);
  913. var c:char;
  914. begin
  915.   repeat
  916.     repeat
  917.       getkey(c);
  918.       if c=#26 then phelp;
  919.       skey(c);
  920.     until (((c>=' ') and (c<chr(127))) or (c=chr(13))) or hangup;
  921.     c:=upcase(c);
  922.     outkey(c);
  923.     thisline:=thisline+c;
  924.     if (c='/') or (c='1') then begin
  925.       i:=c;
  926.       repeat
  927.         getkey(c);
  928.         if c=#26 then phelp;
  929.         skey(c);
  930.       until ((c>=' ')and(c<=chr(127))) or (c=chr(13)) or (c=chr(8)) or hangup;
  931.       c:=upcase(c);
  932.       if c<>chr(13) then begin outkey(c); thisline:=thisline+c; end;
  933.       if (c=chr(8)) or (c=chr(127)) then prompt(' '+c);
  934.       if c='/' then input(i,20) else if c<>chr(13) then i:=i+c;
  935.     end else i:=c;
  936.   until (c<>chr(8)) and (c<>chr(127)) or hangup;
  937.   nl;
  938. end;
  939.  
  940. procedure mainmenu;
  941. var nb,inte:integer; abort,next:boolean; ii:str; rl:real; mr:mailrec;
  942. begin
  943.   dump;tleft;nl;nl; macok:=true;
  944.   if not expert then printfile('gfiles\mainmenu.msg');
  945.   rl:=(seclev[thisuser.sl].ttime*60.0+extratime+timeon-timer);
  946.   if rl>32767.0 then rl:=32000; if rl<0.0 then rl:=0;
  947.   inte:=trunc(rl);
  948.   i:=cstr(inte div 3600)+':'; ii:=cstr((inte mod 3600) div 60);
  949.   if length(ii)=1 then ii:='0'+ii; i:='T - '+i+ii+':';
  950.   ii:=cstr(inte mod 60); if length(ii)=1 then ii:='0'+ii;
  951.   i:=i+ii; print(i);
  952.   if boards[board].key=' ' then i:='['+cstr(board)+'] ' else
  953.     i:='['+boards[board].key+'] ';
  954.   i:=i+'['+boards[board].name+'] :';
  955.   prompt(i); helpl:='@';
  956.   if onekey in thisuser.defaults then mmkey(i) else input(i,20);
  957.   helpl:=#0;
  958.   if length(i)=1 then case i[1] of
  959.     '?':if expert then begin nl;nl; printfile('gfiles\mainmenu.msg'); end;
  960.     'O':begin
  961.           helpl:='O';nl;nl;prompt('Hangup?  Sure? ');
  962.           if yn then begin
  963.             cls;
  964.             printfile('gfiles\logoff.msg');
  965.             hangup:=true;
  966.             hungup:=false;
  967.           end;
  968.         end;
  969.     '*':boardlist;
  970.     'X':expert:=not expert;
  971.     'D':default;
  972.     'Y':yourinfo;
  973.     'I':begin printfile('gfiles\logon.msg'); printfile('gfiles\system.msg'); end;
  974.     'C':reqchat;
  975.     '$':chpw;
  976.     'R':removem;
  977.     'U':ulist;
  978.     'E':smail(false);
  979.     'F':begin irt:='Feedback'; imail(1); end;
  980.     'S':scan1;
  981.     'P':post;
  982.     'T':dloads;
  983.     'M':readmail;
  984.     'Q':qscan(next);
  985.     'G':gfiles;
  986.     'N':nscan;
  987.     'W':wamsg;
  988.     'V':vote;
  989.     'L':printfile('gfiles\user.log');
  990.     'A':abbs;
  991.     'H':mmacro;
  992.     'K':delmail;
  993.     'J':prg(false);
  994.     'Z':prg(true);
  995.     'B':printfile('gfiles\bbslist.msg');
  996.     '!':if cs then begin
  997.           print('Enter name or number of person.'); prompt(':');
  998.           finduser(inte); if inte>0 then vali(inte);
  999.         end;
  1000.  end else
  1001.   begin
  1002.     if copy(i,1,2)='//' then i:=copy(i,3,length(i)-2);
  1003.     if i='/O' then hangup:=true;
  1004.     if i='/E' then smail(true);
  1005.     if i='/K' then if onekey in thisuser.defaults then thisuser.defaults:=
  1006.       thisuser.defaults-[onekey] else thisuser.defaults:=thisuser.defaults+[onekey];
  1007.     if (i='UEDIT') and cs then uedit(usernum);
  1008.     if (i='STATUS') and cs THEN PSTAT;
  1009.     if (i='IVOTES') AND cs then initvotes;
  1010.     if (i='LOG') and cs then printfile('gfiles\sysop.log');
  1011.     if (i='YLOG') and cs then printfile('gfiles\ysysop.log');
  1012.     if (i='BOARDEDIT') and so then boardedit;
  1013.     if (i='DLBOARDEDIT') and so then dlboardedit;
  1014.     if (i='MAILR') and so then mailr;
  1015.     if (i='/?') and cs then printfile('gfiles\sysopmnu.msg');
  1016.     if (i='QUIT') and so then begin doneday:=true; hangup:=true; elevel:=1; end;
  1017.     if (i='DOS') and cs then begin ret:=200; dos('D'); end;
  1018.   end;
  1019.   nb:=value(i);
  1020.   if nb>0 then
  1021.     if nb<=numboards then
  1022.       if (boards[nb].key=' ') and boardac(nb) then board:=nb
  1023.       else
  1024.     else
  1025.   else begin
  1026.     nb:=0;
  1027.     for inte:=1 to numboards do if boards[inte].key=i then nb:=inte;
  1028.     if (nb<>0) and (i<>' ') then if boardac(nb) then board:=nb;
  1029.   end;
  1030. end;
  1031.  
  1032. begin
  1033.   getdir(0,i); ovrpath(i);
  1034.   if ret>127 then begin
  1035.     iport;
  1036.     if ret=200 then
  1037.       goto reent;
  1038.     if ret=201 then
  1039.       goto reent1;
  1040.   end;
  1041.   ret:=ret+128;
  1042.   init;
  1043.   repeat
  1044.     reent1: getcaller;
  1045.     if getuser then newuser;
  1046.     macok:=true;
  1047.     if not hangup then logon;
  1048.     while not hangup do
  1049.       reent: mainmenu;
  1050.     term_ready(false); delay(500);
  1051.     if useron then logoff;
  1052.     if enddayf then endday;
  1053.     enddayf:=false;
  1054.   until doneday;
  1055.   term_ready(true); delay(100); pr('ATZ');
  1056.   remove_port;
  1057.   halt(elevel);
  1058. end.
  1059.  
  1060.