diff --git a/ACP.e b/ACP.e index 330af46..0058ba6 100644 --- a/ACP.e +++ b/ACP.e @@ -40,39 +40,10 @@ MODULE '*axcommon', '*jsonParser', - '*miscfuncs', - '*stringlist' - - -/* -'Setup' -BBS:Config%d -execute %s -Icon Setup Complete. -Cannot Locate Icon Config. - -aErrorCreatingD:dc.b 'Error Creating Directory %s',$A,0 -aCreatingIconS: dc.b 'Creating Icon %s',$A,0 -a3_3s: dc.b '>%-3.3s',0 -aS_txt: dc.b '%s.txt',0 -aErrorCreatingI:dc.b 'Error creating Icon %s',$A,0 -aErrorCreatin_0:dc.b 'Error Creating Directory %s',$A,0 -aCreatingIcon_0:dc.b 'Creating Icon %s',$A,0 -aDrw: dc.b '>DRW',0 -aS_txt_0: dc.b '%s.txt',0 -aErrorCreatin_1:dc.b 'Error creating Icon %s',$A,0 -aDir: dc.b '(DIR)',0 -aAddingTooltype:dc.b 9,'Adding ToolType %s',$A,0 -aErrorOpeningCo:dc.b 'Error opening config file',$A,0 -aDef: dc.b '>DEF',0 -aUsingDefaultIc:dc.b 'Using Default Icon',$A,0 -aSelectIconconf:dc.b 'Select IconConfig',0 -a?: dc.b '#?',0 -aS_1: dc.b 's:',0 -aAeicon_config: dc.b 'aeicon.config',0 + '*jsonCreate', + '*stringlist', + '*acpversion' -*/ - ENUM ERR_NONE,ERR_ALREADY_RUNNING,ERR_STARTUP, ERR_VALIDATE,ERR_NO_DISKFONT,ERR_FDS_RANGE CONST LISTENQ=100 @@ -329,6 +300,7 @@ DEF activeNodes[MAX_NODES]:ARRAY OF CHAR DEF publicName[200]:STRING DEF pens[9]:ARRAY OF INT DEF myVerStr[255]:STRING +DEF myBuildStr[255]:STRING DEF myappport=NIL:PTR TO mp DEF doMultiCom @@ -525,6 +497,14 @@ PROC add(name:PTR TO CHAR, dateStr:PTR TO CHAR) OF itemsList self.num:=self.num+1 ENDPROC +PROC checkPathSlash(path) + DEF c + c:=path[StrLen(path)-1] + IF (c<>":") AND (c<>"/") + StrAdd(path,'/') + ENDIF +ENDPROC + PROC getSystemDate(outDateStr:PTR TO CHAR) DEF dt : datetime DEF datestr[255]:STRING @@ -617,7 +597,7 @@ ENDPROC PROC openListenSocket(port) DEF server_s DEF servaddr=0:PTR TO sockaddr_in - DEF tempStr[255]:STRING + ->DEF tempStr[255]:STRING IF((server_s:=Socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) ->StringF(tempStr,'/X Telnet: Error creating listening socket. (\d)\b\n',Errno()) @@ -751,7 +731,7 @@ PROC initCycles() ENDPROC PROC initNdCycles() - DEF i,x + DEF x DEF list:PTR TO itemsList FOR x:=0 TO MAX_NODES-1 ndUser[x]:=NEW list.init() @@ -785,9 +765,9 @@ PROC getToolTypes(filename:PTR TO CHAR) isCfg:=FALSE IF(dobj=NIL) StringF(fn,'\s.txt',filename) - IF fileExists(fn)=FALSE + IF (len:=FileLength(fn))=-1 StringF(fn,'\s.cfg',filename) - IF fileExists(fn)=FALSE + IF (len:=FileLength(fn))=-1 StrCopy(fn,'') ENDIF ENDIF @@ -795,7 +775,7 @@ PROC getToolTypes(filename:PTR TO CHAR) IF StrLen(fn)>0 dobj:=GetDefDiskObject(WBPROJECT) IF dobj<>NIL - fileBuf:=New(getFileSize(fn)+1) ->allow an extra char in case file does not end in LF + fileBuf:=New(len+1) ->allow an extra char in case file does not end in LF fh:=Open(fn,MODE_OLDFILE) IF fh>0 @@ -1012,7 +992,7 @@ PROC createCustomMenus(nodes) maddItem( NM_TITLE, 'Project', 0 , 0, 0, 0) maddItem( NM_ITEM, 'About',0,0,0,0) - StringF(version,' AmiExpress Professional \s',myVerStr) + StringF(version,' AmiExpress Professional \s (\s)',myVerStr,myBuildStr) maddItem( NM_SUB,version,0,0,0,0) maddItem( NM_SUB,' Written by Darren Coles ',0,0,0,0) @@ -1047,6 +1027,8 @@ PROC createCustomMenus(nodes) maddItem( NM_SUB,' Stephan Schiemann ',0,0,0,0) maddItem( NM_SUB,' Eddie Oniel ',0,0,0,0) + maddItem( NM_ITEM, 'Quit',0,0,0,0) + maddItem( NM_TITLE, 'Master Control',0,0,0,0) maddItem( NM_ITEM, 'Sysop Login',0, 0, 0, 0) maddNodes(nodes) @@ -1749,7 +1731,7 @@ PROC maddNodes(nodes) ENDFOR ENDPROC -PROC maddItem(type,label:PTR TO CHAR,commKey:PTR TO CHAR,flags,mutual,user) +PROC maddItem(type,label:PTR TO CHAR,commKey:PTR TO CHAR,flags,mutual,userData) ->DEF i=0 was static DEF t:PTR TO newmenu DEF s:PTR TO CHAR @@ -1764,10 +1746,10 @@ PROC maddItem(type,label:PTR TO CHAR,commKey:PTR TO CHAR,flags,mutual,user) s:=AllocMem(80,MEMF_PUBLIC OR MEMF_CLEAR) IF(label) THEN strcpy(s,label) ELSE strcpy(s,'') t.label:=s - t.commkey:=0->//(STRPTR)CommKey + t.commkey:=commKey t.flags:=flags t.mutualexclude:=mutual - t.userdata:=0 + t.userdata:=userData maxMenus++ ENDIF maddItemi++ @@ -1785,7 +1767,6 @@ PROC maddRem() ENDPROC PROC regLastDownloads(name:PTR TO CHAR,dateStr:PTR TO CHAR,node) - DEF i=0 ->DEF num=0 was static regNodeDownloads(name,dateStr,node) @@ -1799,7 +1780,6 @@ PROC regNodeDownloads(name:PTR TO CHAR, dateStr:PTR TO CHAR,node) ENDPROC PROC regLastUploads(name:PTR TO CHAR,dateStr:PTR TO CHAR,node) - DEF i=0 ->DEF num=0 was static regNodeUploads(name,dateStr,node) @@ -1835,7 +1815,6 @@ PROC showQuiet(i) ENDPROC PROC regLastUser(name:PTR TO CHAR,dateStr:PTR TO CHAR,node) - DEF i=0 DEF tempStr[44]:STRING ->DEF num=0; was static @@ -2184,7 +2163,7 @@ PROC initSemaSemiNodes(s:PTR TO multiPort) DEF j WHILE(i":") AND (temp<>"/") THEN StrAdd(baseLang,'/') + checkPathSlash(baseLang) IF findFirst(baseLang,fileName) REPEAT @@ -2291,7 +2268,7 @@ PROC loadTranslators(baseDir:PTR TO CHAR) trans2:=NEW trans2 AstrCopy(trans2.translatorName,translatorName,80) - fsize:=getFileSize(fullFileName) + fsize:=FileLength(fullFileName) workMem:=New(fsize+2) ->allocate some memory (two extra bytes in case there is no newline at the end of the file) trans2.translationText:=New(fsize+4) ->allocate some memory, two extra bytes for ending colon and space and some in case there is no newline @@ -2423,7 +2400,7 @@ PROC getIconNodeInfo(i) DEF s:PTR TO CHAR DEF basis[200]:STRING DEF fileName[200]:STRING - DEF temp[100]:STRING + DEF temp[255]:STRING DEF cmd:PTR TO packedCommands DEF sopt:PTR TO startOption DEF n @@ -2483,7 +2460,7 @@ PROC getIconNodeInfo(i) IF(s:=FindToolType(oldtooltypes,'WINDOW.TO_FRONT')) THEN cmd.acLvl[LVL_SCREEN_TO_FRONT]:=1 IF(s:=FindToolType(oldtooltypes,'WINDOW.NUM_COLORS')) n:=Val(s) - SELECT 9 OF n + SELECT 17 OF n CASE 0 sopt.bitPlanes:=0 CASE 1,2 @@ -2492,6 +2469,8 @@ PROC getIconNodeInfo(i) sopt.bitPlanes:=2 CASE 5,6,7,8 sopt.bitPlanes:=3 + CASE 9,10,11,12,13,14,15,16 + sopt.bitPlanes:=4 DEFAULT sopt.bitPlanes:=3 ENDSELECT @@ -2516,7 +2495,11 @@ PROC getIconNodeInfo(i) IF(s:=FindToolType(oldtooltypes,'IDLENODE')) THEN nodeIdle[i]:=1 IF(s:=FindToolType(oldtooltypes,'TRAPDOOR')) THEN sopt.trapDoor:=TRUE - IF(s:=FindToolType(oldtooltypes,'PLAYPEN')) THEN strcpy(sopt.ramPen,s) + IF(s:=FindToolType(oldtooltypes,'PLAYPEN')) + StrCopy(temp,s) + checkPathSlash(temp) + strcpy(sopt.ramPen,temp) + ENDIF IF(s:=FindToolType(oldtooltypes,'SENTBY_FILES')) THEN cmd.acLvl[LVL_SENTBY_FILES]:=1 IF(s:=FindToolType(oldtooltypes,'CHAT_ON')) THEN cmd.acLvl[LVL_DEFAULT_CHAT_ON]:=1 IF(s:=FindToolType(oldtooltypes,'CAPITOL_FILES')) THEN cmd.acLvl[LVL_CAPITOLS_in_FILE]:=1 @@ -2535,7 +2518,9 @@ PROC getIconNodeInfo(i) IF(s:=FindToolType(oldtooltypes,'DISABLE_QUICK_LOGONS')) THEN sopt.qLogon:=1 IF(s:=FindToolType(oldtooltypes,'FILESNOTALLOWED')) THEN strcpy(sopt.filesNot,s) IF(s:=FindToolType(oldtooltypes,'SCREENS')) - strcpy(sopt.nodeScreens,s) + StrCopy(temp,s) + checkPathSlash(temp) + strcpy(sopt.nodeScreens,temp) ELSE StringF(temp,'\sNode\d/',cmd.bbsLoc,i) strcpy(sopt.nodeScreens,temp) @@ -2620,7 +2605,6 @@ PROC setTheGads() ->DEF j=0 ->static int j=0; ->DEF set=FALSE ->static BOOL Set=FALSE; DEF ng:PTR TO newgadget - DEF s IF(setTheGadsj=FALSE) StrCopy(setOriText[0],'Sysop Login') @@ -2858,9 +2842,10 @@ PROC readStartUp(s:PTR TO CHAR) IF(t:=FindToolType(oldtooltypes,'BBS_GEOGRAPHIC')) THEN StrCopy(mybbslocation,t) IF(t:=FindToolType(oldtooltypes,'BBS_LOCATION')) StrCopy(bbsPath,t) + checkPathSlash(bbsPath) FOR i:=0 TO nodeCount-1 cmd:=cmds[i] - strcpy(cmd.bbsLoc,t) + strcpy(cmd.bbsLoc,bbsPath) ENDFOR ENDIF @@ -3421,6 +3406,29 @@ PROC setSingleFDS(socketVal) fds[n]:=fds[n] OR (Shl(1,socketVal AND 31)) ENDPROC +PROC updateVersion(expVer:PTR TO CHAR,expDate:PTR TO CHAR) + DEF v,p + DEF y,m,d + DEF tmp[4]:STRING + + v:=getBuild() + p:=InStr(v,' ') + IF p>=0 + StrCopy(expVer,v,p) + v:=v+p+1 + StrCopy(tmp,v,4) + y:=Val(tmp) + StrCopy(tmp,v+4,2) + m:=Val(tmp) + StrCopy(tmp,v+6,2) + d:=Val(tmp) + StringF(expDate,'\d[2]-\s[3]-\d[4]',d,'JanFebMarAprMayJunJulAugSepOctNovDec'+((m-1)*3),y) + ELSE + StrCopy(expVer,v,ALL) + StrCopy(expDate,'',ALL) + ENDIF +ENDPROC + PROC main() HANDLE DEF iconStartName[200]:STRING @@ -3441,7 +3449,7 @@ PROC main() HANDLE DEF num DEF version[200]:STRING DEF windowSig,myappsig - DEF i,j,class + DEF i,class DEF newlock=NIL DEF telnetServerSocket=-1 DEF telnetSocket=-1 @@ -3460,7 +3468,7 @@ PROC main() HANDLE KickVersion(37) -> E-Note: requires V37 - StringF(myVerStr,'v5.2.3') + updateVersion(myVerStr,myBuildStr) FOR i:=0 TO MAX_NODES-1 ndUser[i]:=NIL @@ -3957,6 +3965,9 @@ PROC main() HANDLE CASE GADGETUP handleEditGadget(im,0) CASE MENUPICK + ->quit menu item + IF(menunum(im.code)=0) AND (itemnum(im.code)=5) THEN attemptShutdown() + IF(menunum(im.code)=1) i:=button button:=0 diff --git a/MiscFuncs.e b/MiscFuncs.e index 90a86e5..b69844f 100644 --- a/MiscFuncs.e +++ b/MiscFuncs.e @@ -1,8 +1,9 @@ -/* Miscellaneous helper functions */ +/* Miscellaneous helper functions - used by express only */ OPT MODULE - MODULE 'dos/dos','dos/dosextens' + MODULE 'dos/dos','dos/dosextens','dos/datetime' + MODULE '*axenums','*axconsts','*errors' EXPORT PROC getFileSize(s: PTR TO CHAR) /* returns the file size of a given file or 8192 if an error occured */ @@ -62,6 +63,14 @@ EXPORT PROC dirExists(path: PTR TO CHAR) FreeDosObject(DOS_FIB,dir_info) ENDPROC returnval +EXPORT PROC checkPathSlash(path) + DEF c + c:=path[StrLen(path)-1] + IF (c<>":") AND (c<>"/") + StrAdd(path,'/') + ENDIF +ENDPROC + EXPORT PROC strCmpi(test1: PTR TO CHAR, test2: PTR TO CHAR, len) /* case insensitive string compare */ DEF i,l1,l2 @@ -78,6 +87,10 @@ EXPORT PROC strCmpi(test1: PTR TO CHAR, test2: PTR TO CHAR, len) ENDFOR ENDPROC TRUE +EXPORT PROC midStr2(dest,src,pos,len) + IF len>0 THEN MidStr(dest,src,pos,len) ELSE StrCopy(dest,'') +ENDPROC + EXPORT PROC charToLower(c) /* convert a given char to lowercase */ DEF str[1]:STRING @@ -157,3 +170,408 @@ PROC bStrC(bstr: PTR TO CHAR,outbuf: PTR TO CHAR) counter++ ENDFOR ENDPROC + +EXPORT PROC listAdd2(list:PTR TO LONG, v) + ListAdd(list,[0]) + list[ListLen(list)-1]:=v +ENDPROC + +/*must be called with EString*/ +EXPORT PROC removeCR(str:PTR TO CHAR) + DEF i,n=0 + FOR i:=0 TO EstrLen(str)-1 + IF str[i]<>13 + str[n]:=str[i] + n++ + ENDIF + ENDFOR + SetStr(str,n) +ENDPROC + +EXPORT PROC formatSpaceValue(spaceInMB,spacelo,outstr) + DEF frac,whole + IF (spaceInMB<10240) + frac:=Shr(Mul((spacelo AND $FFFFF),10),20) + StringF(outstr,'\d.\d MB',spaceInMB,frac) + ELSEIF(spaceInMB<1048576) + frac:=Shr(Mul((spaceInMB AND 1023),10),10) + whole:=Shr(spaceInMB,10) + StringF(outstr,'\d.\d GB',whole,frac) + ELSE + spaceInMB:=Shr(spaceInMB,10) + frac:=Shr(Mul((spaceInMB AND 1023),10),10) + whole:=Shr(spaceInMB,10) + StringF(outstr,'\d.\d TB',whole,frac) + ENDIF +ENDPROC + +PROC asmputchar() + MOVE.B D0,(A3)+ +ENDPROC + +EXPORT PROC formatUnsignedLong(val,outStr) + DEF outputTxt + + outputTxt:=NEW [0,0,0,0,0,0,0,0,0,0]:CHAR + RawDoFmt('%lu',{val},{asmputchar},outputTxt) + StrCopy(outStr,outputTxt) + END outputTxt +EXPORT ENDPROC + +EXPORT PROC formatLongDate(cDateVal,outDateStr) + DEF d : PTR TO datestamp + DEF dt : datetime + DEF datestr[10]:STRING + DEF dateVal + + dateVal:=cDateVal-21600 + + d:=dt.stamp + d.tick:=(dateVal-Mul(Div(dateVal,60),60)) + d.tick:=Mul(d.tick,50) + dateVal:=Div(dateVal,60) + d.days:=Div((dateVal),1440)-2922 ->-2922 days between 1/1/70 and 1/1/78 + d.minute:=dateVal-(Mul(d.days+2922,1440)) + + dt.format:=FORMAT_USA + dt.flags:=0 + dt.strday:=0 + dt.strdate:=datestr + dt.strtime:=0 + + IF DateToStr(dt) + StringF(outDateStr,'\s',datestr) + RETURN TRUE + ENDIF +ENDPROC FALSE + +EXPORT PROC formatLongTime(cDateVal,outDateStr) + DEF d : PTR TO datestamp + DEF dt : datetime + DEF time[10]:STRING + DEF dateVal + + dateVal:=cDateVal-21600 + + d:=dt.stamp + d.tick:=(dateVal-Mul(Div(dateVal,60),60)) + d.tick:=Mul(d.tick,50) + dateVal:=Div(dateVal,60) + d.days:=Div((dateVal),1440)-2922 ->-2922 days between 1/1/70 and 1/1/78 + d.minute:=dateVal-(Mul(d.days+2922,1440)) + + dt.format:=FORMAT_USA + dt.flags:=0 + dt.strday:=0 + dt.strdate:=0 + dt.strtime:=time + + IF DateToStr(dt) + StringF(outDateStr,'\s',time) + RETURN TRUE + ENDIF +ENDPROC FALSE + +EXPORT PROC formatLongDateTime(cDateVal,outDateStr) + DEF d : PTR TO datestamp + DEF dt : datetime + DEF datestr[10]:STRING + DEF daystr[10]:STRING + DEF timestr[10]:STRING + DEF dateVal + + dateVal:=cDateVal-21600 + + d:=dt.stamp + d.tick:=(dateVal-Mul(Div(dateVal,60),60)) + d.tick:=Mul(d.tick,50) + dateVal:=Div(dateVal,60) + d.days:=Div((dateVal),1440)-2922 ->-2922 days between 1/1/70 and 1/1/78 + d.minute:=dateVal-(Mul(d.days+2922,1440)) + + dt.format:=FORMAT_DOS + dt.flags:=0 + dt.strday:=daystr + dt.strdate:=datestr + dt.strtime:=timestr + + IF DateToStr(dt) + StringF(outDateStr,'\s[3] \s[7]\d\s \s',daystr,datestr,IF dt.stamp.days>=8035 THEN 20 ELSE 19,datestr+7,timestr) + RETURN TRUE + ENDIF +ENDPROC FALSE + +EXPORT PROC formatCDateTime(cDateVal,outDateStr) + DEF d : PTR TO datestamp + DEF dt : datetime + DEF datestr[10]:STRING + DEF daystr[10]:STRING + DEF timestr[10]:STRING + DEF dateVal + + dateVal:=cDateVal-21600 + + d:=dt.stamp + d.tick:=(dateVal-Mul(Div(dateVal,60),60)) + d.tick:=Mul(d.tick,50) + dateVal:=Div(dateVal,60) + d.days:=Div((dateVal),1440)-2922 ->-2922 days between 1/1/70 and 1/1/78 + d.minute:=dateVal-(Mul(d.days+2922,1440)) + + dt.format:=FORMAT_DOS + dt.flags:=0 + dt.strday:=daystr + dt.strdate:=datestr + dt.strtime:=timestr + + IF DateToStr(dt) + StringF(outDateStr,'\s[3] \s[3] \s[2] \s \d\s',daystr,datestr+3,datestr,timestr,IF dt.stamp.days>=8035 THEN 20 ELSE 19,datestr+7) + RETURN TRUE + ENDIF +ENDPROC FALSE + +EXPORT PROC formatLongDateTime2(cDateVal,outDateStr,seperatorChar) + DEF d : PTR TO datestamp + DEF dt : datetime + DEF datestr[10]:STRING + DEF timestr[10]:STRING + DEF dateVal + + dateVal:=cDateVal-21600 + + d:=dt.stamp + d.tick:=(dateVal-Mul(Div(dateVal,60),60)) + d.tick:=Mul(d.tick,50) + dateVal:=Div(dateVal,60) + d.days:=Div((dateVal),1440)-2922 ->-2922 days between 1/1/70 and 1/1/78 + d.minute:=dateVal-(Mul(d.days+2922,1440)) + + dt.format:=FORMAT_USA + dt.flags:=0 + dt.strday:=0 + dt.strdate:=datestr + dt.strtime:=timestr + + IF DateToStr(dt) + StringF(outDateStr,'\s\c\s',datestr,seperatorChar,timestr) + RETURN TRUE + ENDIF +ENDPROC FALSE + +->returns a numeric value of the date suitable for comparing to other dates +EXPORT PROC getDateCompareVal(datestr:PTR TO CHAR) + DEF month,day,year + + month:=Val(datestr) + day:=Val(datestr+3) + year:=Val(datestr+6) + + IF (year>TWODIGITYEARSWITCHOVER) THEN year:=1900+year ELSE year:=2000+year + +ENDPROC Mul(year,10000)+Mul(month,100)+day + +EXPORT PROC isupper(c) +ENDPROC (c>="A") AND (c<="Z") + +->returns system date converted to c time format +EXPORT PROC getSystemDate() + DEF currDate: datestamp + DEF startds:PTR TO datestamp + DEF s4 + + startds:=DateStamp(currDate) + + s4:=(Mul(Mul(startds.days+2922,1440),60)+(startds.minute*60)+(startds.tick/50))+21600 + ->2922 days between 1/1/70 and 1/1/78 +ENDPROC Mul(Div(s4,86400),86400) + +->returns system time converted to c time format +EXPORT PROC getSystemTime() + DEF currDate: datestamp + DEF startds:PTR TO datestamp + + startds:=DateStamp(currDate) + ->2922 days between 1/1/70 and 1/1/78 + +ENDPROC (Mul(Mul(startds.days+2922,1440),60)+(startds.minute*60)+(startds.tick/50))+21600,Mod(startds.tick,50) + +->returns system time converted to c time format and ticks +EXPORT PROC getSystemTime2() + DEF currDate: datestamp + DEF startds:PTR TO datestamp + DEF s1,s2,s3,s4 + + startds:=DateStamp(currDate) + + s1:=startds.days+2922 + s1:=Mul(1440,s1) + s1:=Mul(60,s1) + s2:=Mul(60,startds.minute) + s3:=startds.tick/50 + s4:=Mul(Mul(startds.days+2922,1440),60)+(startds.minute*60)+(startds.tick/50) + + ->2922 days between 1/1/70 and 1/1/78 + +ENDPROC s4+21600,Mod(startds.tick,50) + +EXPORT PROC fileWriteLn(fh,str: PTR TO CHAR) + DEF stat + IF (stat:=fileWrite(fh,str))<>RESULT_SUCCESS THEN RETURN stat +ENDPROC fileWrite(fh,'\n') + +EXPORT PROC fileWrite(fh,str: PTR TO CHAR) + DEF s + + s:=Write(fh,str,StrLen(str)) + IF s<>StrLen(str) THEN RETURN RESULT_FAILURE +ENDPROC RESULT_SUCCESS + +EXPORT PROC strCpy(dest: PTR TO CHAR, source: PTR TO CHAR, len) + DEF c,endfound=FALSE + DEF i + IF len=ALL + AstrCopy(dest,source,ALL) + ELSE + FOR i:=0 TO len-1 + c:=source[i] + IF (c=0) OR (i=(len-1)) THEN endfound:=TRUE + IF endfound THEN c:=0 + dest[i]:=c + ENDFOR + ENDIF +ENDPROC + +EXPORT PROC strAddChar(dest,source) + StrAdd(dest,' ') + dest[EstrLen(dest)-1]:=source +ENDPROC + +EXPORT PROC countSpaces(str:PTR TO CHAR) + DEF i,count=0 + + FOR i:=0 TO StrLen(str)-1 + IF str[i]=" " + count++ + ENDIF + ENDFOR +ENDPROC count + +EXPORT PROC readIntFromFile(filename: PTR TO CHAR) + DEF fh + DEF v[100]:STRING + IF((fh:=Open(filename,MODE_OLDFILE)))<>0 + ReadStr(fh,v) + Close(fh) + RETURN Val(v) + ENDIF +ENDPROC -1 + +EXPORT PROC readFloatFromFile(filename: PTR TO CHAR) + DEF fh + DEF v[100]:STRING + IF((fh:=Open(filename,MODE_OLDFILE)))<>0 + ReadStr(fh,v) + Close(fh) + RETURN RealVal(v) + ENDIF +ENDPROC 0.0 + +EXPORT PROC writeIntToFile(filename: PTR TO CHAR, v: LONG) + DEF fh + DEF vStr[100]:STRING + IF((fh:=Open(filename,MODE_NEWFILE)))<>0 + StringF(vStr,'\d',v) + fileWriteLn(fh,vStr) + Close(fh) + RETURN RESULT_SUCCESS + ENDIF +ENDPROC RESULT_FAILURE + +EXPORT PROC writeFloatToFile(filename: PTR TO CHAR, v: LONG) + DEF fh + DEF vStr[100]:STRING + IF((fh:=Open(filename,MODE_NEWFILE)))<>0 + RealF(vStr,v,8) + fileWriteLn(fh,vStr) + Close(fh) + RETURN RESULT_SUCCESS + ENDIF +ENDPROC RESULT_FAILURE + +EXPORT PROC mulu64(src1,src2) + DEF res1,res2 +-> umult64 - mulu.l d0,d0:d1 + + MOVE.L src1,D0 + MOVE.L src2,D1 + + MOVE.L D2,-(A7) + MOVE.W D0,D2 + MULU D1,D2 + MOVE.L D2,-(A7) + MOVE.L D1,D2 + SWAP D2 + MOVE.W D2,-(A7) + MULU D0,D2 + SWAP D0 + MULU D0,D1 + MULU (A7)+,D0 + ADD.L D2,D1 + MOVEQ #0,D2 + ADDX.W D2,D2 + SWAP D2 + SWAP D1 + MOVE.W D1,D2 + CLR.W D1 + ADD.L (A7)+,D1 + ADDX.L D2,D0 + MOVE.L (A7)+,D2 + MOVE.L D0,res1 + MOVE.L D1,res2 +ENDPROC res1,res2 + +EXPORT PROC addWO(x,y) + MOVE.L x,D0 + ADD.L y,D0 + BCC noover + MOVEQ.L #-1,D0 +noover: +ENDPROC D0 + +EXPORT PROC findFirst(path: PTR TO CHAR,buf: PTR TO CHAR) HANDLE + DEF pdir=NIL: PTR TO filelock + DEF dir_info=NIL: PTR TO fileinfoblock + DEF returnval=0 + + IF ((dir_info:=(AllocDosObject(DOS_FIB,NIL)))=NIL) + Delay(300) + RETURN 0 + ENDIF + + IF((pdir:=(Lock(path,ACCESS_READ)))=FALSE) + Raise(ERR_EXCEPT) + ENDIF + + IF(Examine(pdir,dir_info))=FALSE + Raise(ERR_EXCEPT) + ENDIF + + IF(ExNext(pdir,dir_info)) + IF(dir_info.direntrytype < 0 ) + returnval:=1 + StrCopy(buf,dir_info.filename) + ENDIF + ENDIF + UnLock(pdir) + FreeDosObject(DOS_FIB,dir_info) +EXCEPT + IF pdir THEN UnLock(pdir) + IF dir_info THEN FreeDosObject(DOS_FIB,dir_info) + RETURN 0 +ENDPROC returnval + +EXPORT PROC byteSignExtend(n) + DEF r + r:=n AND 255 + IF r>127 THEN r:=-(256-r) +ENDPROC r \ No newline at end of file diff --git a/VerInfoGen.e b/VerInfoGen.e new file mode 100644 index 0000000..6615a2f --- /dev/null +++ b/VerInfoGen.e @@ -0,0 +1,111 @@ +->Ami-Express verison info + +MODULE 'dos/dos','dos/datetime' + +PROC getBuildDateString(buildString:PTR TO CHAR) + DEF dt : datetime + DEF datestr[10]:STRING + DEF timestr[10]:STRING + + DateStamp(dt.stamp) + dt.format:=FORMAT_USA + dt.flags:=0 + dt.strday:=0 + dt.strdate:=datestr + dt.strtime:=timestr + IF DateToStr(dt) + StringF(buildString,'\s[2]\s[2]\s[2]\s[2]\s[2]\s[2]\s[2]',IF dt.stamp.days>=8035 THEN '20' ELSE '19',datestr+6,datestr,datestr+3,timestr,timestr+3,timestr+6) + RETURN TRUE + ENDIF + StrCopy(buildString,'') +ENDPROC FALSE + +PROC fileWriteLine(fh,line) + DEF l + l:=EstrLen(line) + IF Write(fh,line,l)<>l + WriteF('Error writing to file\n') + Close(fh) + RETURN FALSE + ENDIF +ENDPROC TRUE + +PROC main() + DEF myargs:PTR TO LONG,rdargs + DEF outFile[255]:STRING + DEF programName[255]:STRING + DEF versionString[255]:STRING + DEF tempstr[255]:STRING + DEF p:PTR TO LONG + DEF buildNumber=0 + DEF buildString[255]:STRING + DEF useDate=FALSE + DEF fh + + WriteF('Version Info generator - V1.0 (c)2020 Darren Coles\n\n') + + myargs:=[0,0,0,0,0]:LONG + IF rdargs:=ReadArgs('FILE/A,PROGRAM/A,VERSION/A,BUILD/N,USEDATE/S',myargs,NIL) + IF myargs[0]<>NIL + StrCopy(outFile,myargs[0],255) + ENDIF + IF myargs[1]<>NIL + StrCopy(programName,myargs[1],255) + ENDIF + IF myargs[2]<>NIL + StrCopy(versionString,myargs[2],255) + ENDIF + IF myargs[3]<>NIL + p:=myargs[3] + buildNumber:=p[] + ENDIF + IF myargs[4]<>NIL + useDate:=TRUE + ENDIF + FreeArgs(rdargs) + ELSE + WriteF('required argument missing\n') + RETURN + ENDIF + + IF useDate + getBuildDateString(buildString) + ELSE + StringF(buildString,'\d',buildNumber) + ENDIF + + fh:=Open(outFile,MODE_NEWFILE) + IF fh=0 + WriteF('unable to open \s for writing\n',outFile) + RETURN + ENDIF + + StrCopy(tempstr,'->Version data\n') + IF fileWriteLine(fh,tempstr)=FALSE THEN RETURN + + StrCopy(tempstr,'OPT MODULE\n\n') + IF fileWriteLine(fh,tempstr)=FALSE THEN RETURN + + StrCopy(tempstr,'EXPORT PROC getBuild()\n') + IF fileWriteLine(fh,tempstr)=FALSE THEN RETURN + + StrCopy(tempstr,'LEA verdata(PC),A0\n') + IF fileWriteLine(fh,tempstr)=FALSE THEN RETURN + + StringF(tempstr,'LEA \d(A0),A0\n',EstrLen(programName)+7) + IF fileWriteLine(fh,tempstr)=FALSE THEN RETURN + + StrCopy(tempstr,'MOVE.L A0,D0\n') + IF fileWriteLine(fh,tempstr)=FALSE THEN RETURN + + StrCopy(tempstr,'ENDPROC D0\n') + IF fileWriteLine(fh,tempstr)=FALSE THEN RETURN + + StrCopy(tempstr,'verdata:\n') + IF fileWriteLine(fh,tempstr)=FALSE THEN RETURN + + StringF(tempstr,' CHAR ''$VER: \s \s \s'',0\n',programName,versionString,buildString) + IF fileWriteLine(fh,tempstr)=FALSE THEN RETURN + + Close(fh) +ENDPROC \ No newline at end of file diff --git a/axcommon.e b/axcommon.e index 21622ac..e84fe67 100644 --- a/axcommon.e +++ b/axcommon.e @@ -17,7 +17,7 @@ EXPORT ENUM ACS_ACCOUNT_EDITING,ACS_READ_BULLETINS,ACS_COMMENT_TO_SYSOP,ACS_DOWN ACS_CUSTOMCOMMANDS,ACS_JOIN_SUB_CONFERENCE,ACS_ZOOM_MAIL,ACS_MCI_MSG,ACS_EDIT_DIRS,ACS_EDIT_FILES,ACS_BREAK_CHAT,ACS_QUIET_NODE,ACS_SYSOP_COMMANDS,ACS_WHO_IS_ONLINE, ACS_RELOGON,ACS_ULSTATS,ACS_XPR_RECEIVE,ACS_XPR_SEND,ACS_WILDCARDS,ACS_CONFERENCE_ACCOUNTING,ACS_PRI_MSGFILES,ACS_PUB_MSGFILES,ACS_FULL_EDIT,ACS_CONFFLAGS, ACS_OLM,ACS_HIDE_FILES,ACS_SHOW_PAYMENTS,ACS_CREDIT_ACCESS,ACS_VOTE,ACS_MODIFY_VOTE,ACS_FILE_EXPANSION,ACS_EDIT_REAL_NAME,ACS_EDIT_USER_NAME,ACS_CENSORED, - ACS_ACCOUNT_VIEW,ACS_TRANSLATION,ACS_UNKNOWN,ACS_CREATE_CONFERENCE,ACS_LOCAL_DOWNLOADS,ACS_MAX_PAGES,ACS_OVERRIDE_DEFAULTS,ACS_HOLD_ACCESS + ACS_ACCOUNT_VIEW,ACS_TRANSLATION,ACS_UNKNOWN,ACS_CREATE_CONFERENCE,ACS_LOCAL_DOWNLOADS,ACS_MAX_PAGES,ACS_OVERRIDE_DEFAULTS,ACS_HOLD_ACCESS,ACS_EDIT_EMAIL EXPORT ENUM ENV_IDLE=0,ENV_DOWNLOADING=1,ENV_UPLOADING=2,ENV_DOORS=3,ENV_MAIL=4,ENV_STATS=5,ENV_ACCOUNT=6,ENV_ZOOM=7,ENV_FILES=8,ENV_BULLETINS=9, ENV_VIEWING=10,ENV_ACCOUNTSEQ=11,ENV_LOGOFF=12,ENV_SYSOP=13,ENV_SHELL=14,ENV_EMACS=15,ENV_JOIN=16,ENV_CHAT=17,ENV_NOTACTIVE=18, @@ -239,8 +239,8 @@ EXPORT CONST DT_REALNAME=606 EXPORT CONST UNKNOWN4=607 EXPORT CONST QUICK_KEY=608 EXPORT CONST SER_INOUT=609 -EXPORT CONST UNKNOWN6=610 -EXPORT CONST UNKNOWN7=611 +EXPORT CONST AXNET_RECEIVE=610 +EXPORT CONST AXNET_SEND=611 EXPORT CONST MEMCONF=612 EXPORT CONST SET_SERSHARED=613 EXPORT CONST CONF_ACCESS=614 @@ -282,10 +282,10 @@ undocumented host addresses: 605 - get custom msgbase command to msg.string 606 - get/set real name to/from msg.string 607 - get/set something that isnt used anywhere else in the code (not yet implemented) -608 - some kind of input routine ??? (not yet implemented) +608 - some kind of input routine ??? (currently implemented as default read char routine) 609 - set IO_Flags[IOFLAG_SER_IN] and IO_Flags[IOFLAG_SER_OUT] -610 - trigger netmail receive (not yet implemented) -611 - trigger netmail send (not yet implemented) +610 - trigger netmail receive +611 - trigger netmail send 612 - get MemConf address (not yet implemented) 613 - set something - something to do with external programs accessing serial ??? 614 - check conf access @@ -311,7 +311,7 @@ undocumented host addresses: 637 - get or set internet name 638 - get or set translator 639 - get or set host language name (languages.info) -640 - set amixnet outbound path (not yet implemented) +640 - set amixnet outbound path */ /* New host commands for /X5 using range 700+ */ diff --git a/axconsts.e b/axconsts.e new file mode 100644 index 0000000..7d5b769 --- /dev/null +++ b/axconsts.e @@ -0,0 +1,108 @@ +-> EXPORT constants for express + + OPT MODULE + +EXPORT CONST LISTENQ=100 +EXPORT CONST FIONBIO=$8004667e +EXPORT CONST FIONREAD=$4004667f +EXPORT CONST EINTR=4 +EXPORT CONST EWOULDBLOCK=35 +EXPORT CONST ENOBUFS=55 + +EXPORT CONST DEFAULT_DISK_OBJECT_CACHE_SIZE=100 + +EXPORT CONST MAX_FLAGGED_FILES=1000 + +EXPORT CONST BG_EXIT=1200 +EXPORT CONST BG_DONT_EXIT=1200 +EXPORT CONST BG_CHECKFILE=1201 + +EXPORT CONST ACTION_REQUEST=5000 + +EXPORT CONST FIFOF_READ=$00000100 /* intend to read from fifo */ +EXPORT CONST FIFOF_WRITE=$00000200 /* intend to write to fifo */ +EXPORT CONST FIFOF_RESERVED=$FFFF0000 /* reserved for internal use */ +EXPORT CONST FIFOF_NORMAL=$00000400 /* request blocking/sig support*/ +EXPORT CONST FIFOF_NBIO=$00000800 /* non-blocking IO */ + +EXPORT CONST FIFOF_KEEPIFD=$00002000 /* keep fifo alive if data pending */ +EXPORT CONST FIFOF_EOF=$00004000 /* EOF on close */ +EXPORT CONST FIFOF_RREQUIRED=$00008000 /* reader required to exist */ + +EXPORT CONST FREQ_RPEND=1 +EXPORT CONST FREQ_WAVAIL=2 +EXPORT CONST FREQ_ABORT=3 + +EXPORT CONST TWODIGITYEARSWITCHOVER=70 + +EXPORT CONST MAXNODES=32 + +EXPORT CONST MAIL_SCAN_MASK=4 +EXPORT CONST FILE_SCAN_MASK=8 +EXPORT CONST ZOOM_SCAN_MASK=2 +EXPORT CONST MAILSCAN_ALL=128 + +EXPORT CONST IOFLAG_FIL_IN=0 +EXPORT CONST IOFLAG_KBD_IN=1 +EXPORT CONST IOFLAG_SER_IN=2 +EXPORT CONST IOFLAG_FIL_OUT=3 +EXPORT CONST IOFLAG_PRT_OUT=4 +EXPORT CONST IOFLAG_SCR_OUT=5 +EXPORT CONST IOFLAG_SER_OUT=6 + +EXPORT CONST CMD_NONSTD=9 + +EXPORT CONST SDCMD_QUERY = CMD_NONSTD +EXPORT CONST CIAF_COMCD=32 +EXPORT CONST CIAF_COMDSR=8 + +EXPORT CONST ACCESS_READ=-2 + +EXPORT CONST ED_ANSI_ALLOWED=1 ->// Flag indicating that ANSI Colors are allowed in message +EXPORT CONST ED_ABORT_ALLOWED=2 ->// Flag indicating that the Abort command is enabled +EXPORT CONST ED_LOAD_ALLOWED=4 ->// Flag indicating that the Load command is enabled +EXPORT CONST ED_BATCH_UPLOAD=8 ->// Flag indicating that the Upload command is enabled +EXPORT CONST ED_ATTACH_FILE=16 ->// Flag indicating that the File Attach Command is enabled. +EXPORT CONST ED_BATCH_REQUESTED=32768 ->// Flag indicating batch true +EXPORT CONST ED_ATTACH_REQUESTED=16384 + +EXPORT CONST HISTORY=999 +EXPORT CONST LEFTARROW=2 +EXPORT CONST RIGHTARROW=3 +EXPORT CONST UPARROW=4 +EXPORT CONST DOWNARROW=5 + +EXPORT CONST CHAR_BACKSPACE=8 +EXPORT CONST CHAR_DELETE=127 +EXPORT CONST CHAR_TAB=9 + +EXPORT CONST TRACK_UPLOADS_BIT=1 +EXPORT CONST TRACK_DOWNLOADS_BIT=2 + + +EXPORT CONST MAX_SAYINGS=50 +EXPORT CONST INPUT_TIMEOUT=300 + +EXPORT CONST CONU_CHARMAP=1 +EXPORT CONST CONFLAG_DEFAULT=0 + +EXPORT CONST PG_SM=1 +EXPORT CONST PG_CO=2 +EXPORT CONST PG_SO=3 +EXPORT CONST PG_CC=4 +EXPORT CONST PG_CH=5 +EXPORT CONST PG_PM=6 +EXPORT CONST PG_SC=7 +EXPORT CONST PG_HK=8 +EXPORT CONST PG_SF=10 +EXPORT CONST PG_FF=11 +EXPORT CONST PG_EF=12 +EXPORT CONST PG_UD=13 +EXPORT CONST PG_US=14 +EXPORT CONST PG_PS=15 +EXPORT CONST PG_CS=16 +EXPORT CONST PG_RD=17 +EXPORT CONST PG_CL=18 +EXPORT CONST PG_SG=19 +EXPORT CONST PG_SHUTDOWN=20 +EXPORT CONST PG_TM=21 diff --git a/axenums.e b/axenums.e new file mode 100644 index 0000000..2e70128 --- /dev/null +++ b/axenums.e @@ -0,0 +1,45 @@ +-> EXPORT EXPORT ENUMs for express + + OPT MODULE + +EXPORT ENUM STATE_AWAIT, STATE_CONNECTING, STATE_SYSOPLOGON, STATE_LOGON, STATE_LOGGEDON, STATE_HANGUP, STATE_LOGGING_OFF, STATE_SHUTDOWN, STATE_CHECK,STATE_SUSPEND + +EXPORT ENUM REQ_STATE_NONE, REQ_STATE_LOGOFF, REQ_STATE_SHUTDOWN, REQ_STATE_SHUTDOWN_OFFHOOK, REQ_STATE_SYSOPLOGON, REQ_STATE_LOGON, REQ_STATE_RESUME + +EXPORT ENUM SUBSTATE_DISPLAY_AWAIT, SUBSTATE_INPUT, SUBSTATE_DISPLAY_BULL, SUBSTATE_DISPLAY_CONF_BULL, SUBSTATE_DISPLAY_MENU, SUBSTATE_READ_COMMAND, SUBSTATE_PROCESS_COMMAND + +EXPORT ENUM CMDTYPE_BBSCMD,CMDTYPE_SYSCMD,CMDTYPE_CUSTOM + +EXPORT ENUM TOOLTYPE_PRESET, TOOLTYPE_NODE,TOOLTYPE_CONFCONFIG,TOOLTYPE_CONF,TOOLTYPE_BBSCMD,TOOLTYPE_CONFCMD,TOOLTYPE_NODECMD,TOOLTYPE_SYSCMD,TOOLTYPE_DRIVES,TOOLTYPE_NAMESNOTALLOWED,TOOLTYPE_COMPUTERLIST,TOOLTYPE_ACCESS,TOOLTYPE_AREA,TOOLTYPE_FCHECK,TOOLTYPE_NODE_WINDOW,TOOLTYPE_NODE_TIMES,TOOLTYPE_WINDOW,TOOLTYPE_CONNECT,TOOLTYPE_XPRTYPES,TOOLTYPE_XFERLIB,TOOLTYPE_SCREENTYPES,TOOLTYPE_NRAMS, TOOLTYPE_BBSCONFIG,TOOLTYPE_ASCPACK,TOOLTYPE_QWKPACK,TOOLTYPE_QWKCONFIG,TOOLTYPE_DEFAULT_ACCESS,TOOLTYPE_LANGUAGES,TOOLTYPE_USER_ACCESS, TOOLTYPE_NODE_PRESET,TOOLTYPE_CONFCMD2,TOOLTYPE_CONFSYSCMD,TOOLTYPE_NODESYSCMD, TOOLTYPE_MSGBASE + +EXPORT ENUM DOORTYPE_XIM, DOORTYPE_AIM, DOORTYPE_SIM, DOORTYPE_TIM, DOORTYPE_IIM, DOORTYPE_MCI, DOORTYPE_AEM, DOORTYPE_SUP + +EXPORT ENUM LOG_NONE=0, LOG_ERROR=1, LOG_WARN=2, LOG_DEBUG=3 + +EXPORT ENUM SCREEN_AWAIT, SCREEN_BBSTITLE, SCREEN_LOGON, SCREEN_JOIN, SCREEN_JOINCONF, SCREEN_JOINMSGBASE, SCREEN_JOINED, SCREEN_BULL, SCREEN_NODE_BULL, SCREEN_CONF_BULL, SCREEN_MENU, SCREEN_LOGOFF, SCREEN_DOWNLOAD, SCREEN_UPLOAD, SCREEN_NEWUSERPW, SCREEN_NONEWUSERS, SCREEN_NONEWATBAUD, SCREEN_GUESTLOGON, SCREEN_NOCALLERSATBAUD, SCREEN_LOCKOUT0, SCREEN_LOCKOUT1, SCREEN_PRIVATE, SCREEN_ONENODE, SCREEN_LOGON24, SCREEN_NOT_TIME, SCREEN_FILEHELP,SCREEN_LANGUAGES,SCREEN_REALNAMES,SCREEN_INTERNETNAMES + +EXPORT ENUM LOGON_TYPE_LOGGED_OFF=0, LOGON_TYPE_SYSOP=1, LOGON_TYPE_LOCAL=2, LOGON_TYPE_REMOTE=3 + +EXPORT ENUM RESULT_FAILURE=-1, RESULT_SUCCESS=0, RESULT_NOT_ALLOWED=1, RESULT_ABORT=-2, RESULT_TIMEOUT=-3, RESULT_NO_CARRIER=-4, RESULT_GOODBYE=-5, RESULT_SLEEP_LOGOFF=-6, RESULT_STANDARD_LOGOFF=-7, RESULT_CONNECT=-8, RESULT_NOT_TESTED=2, RESULT_LCFILES=9,RESULT_PRIVATE=10, RESULT_SIGNALLED=11, RESULT_NOT_FOUND=12 + +EXPORT ENUM ERR_MEMORY,ERR_MEMORY2,ERR_MSGBASE,ERR_MEMORY3,ERR_FILELIST,ERR_NOFILES,ERR_FILEEXAMINE,ERR_WORKDIROPEN,ERR_LOCK,ERR_FREESPACE,ERR_SYMBOLS,ERR_FIB_MEMORY,ERR_NO_BULLS,ERR_NO_CONFFLAGS + +EXPORT ENUM MAIL_READ=1,MAIL_CREATE=2, MAIL_SCAN=3 + +EXPORT ENUM CONSOLE_PORT=1, SERIAL_PORT=2 + +EXPORT ENUM ZMODEM_NONE, ZMODEM_UPLOAD, ZMODEM_DOWNLOAD + +EXPORT ENUM NAME_TYPE_USERNAME, NAME_TYPE_REALNAME, NAME_TYPE_INTERNETNAME +EXPORT ENUM UPDATE_RATIO,UPDATE_RATIO_TYPE,UPDATE_MAILSCAN_PTRS,UPDATE_NEW_MAIL_SCAN,UPDATE_NEW_FILE_SCAN,UPDATE_DEFAULT_ZOOM_FLAG,UPDATE_LAST_MESSAGE,UPDATE_MESSAGES_POSTED, UPDATE_RESET_VOTING + +EXPORT ENUM CACHE_RESET_NEVER, CACHE_RESET_LOGON + +EXPORT ENUM TRANS_NONE,TRANS_HOST_TO_DEFINED,TRANS_DEFINED_TO_HOST + +EXPORT ENUM FORCE_MAILSCAN_NOFORCE, FORCE_MAILSCAN_ALL, FORCE_MAILSCAN_SKIP + + +-> User Keys Flags + /* show new user message */ /* show all users only once */ +EXPORT ENUM USER_NEWMSG=1,USER_TOCONF1=2, USER_ONETIME_MSG=4,USER_SCRNCLR=8,USER_DONATED=16,USER_ED_FULLSCREEN=32,USER_ED_PROMPT=64,USER_BGFILECHECK=128 diff --git a/axobjects.e b/axobjects.e new file mode 100644 index 0000000..8dd2c6e --- /dev/null +++ b/axobjects.e @@ -0,0 +1,287 @@ +-> EXPORT EXPORT OBJECTs for express + + OPT MODULE + + MODULE 'exec/ports' + MODULE 'exec/semaphores' + MODULE '*axconsts' + MODULE '*stringlist' + + +EXPORT OBJECT user + name[30]:ARRAY OF CHAR + name31: CHAR -> last character of name (odd sized arrays are always padded so need this kludge) + pass0: CHAR -> first character of pass (odd sized arrays are always padded so need this kludge) + pass[8]:ARRAY OF CHAR + location[30]:ARRAY OF CHAR + phoneNumber[13]:ARRAY OF CHAR + slotNumber: INT + secStatus: INT + secBoard: INT /* File or Byte Ratio */ + secLibrary: INT /* Ratio */ + secBulletin: INT /* Computer Type */ + messagesPosted: INT + /* Note ConfYM = the last msg you actually read, ConfRead is the same ?? */ + newSinceDate: LONG + pwdHash: LONG + confRead2: LONG ->not used + confRead3: LONG ->not used + zoomType: INT + unknown: INT ->not used + unknown2: INT ->not used + unknown3: INT ->not used + xferProtocol: INT + filler2: INT ->not used + lcFiles: INT ->not used + badFiles: INT ->not used + accountDate: LONG + screenType: INT + editorType: INT + conferenceAccess[10]: ARRAY OF CHAR + uploads: INT + downloads: INT + confRJoin: INT + timesCalled: INT + timeLastOn: LONG + timeUsed: LONG + timeLimit: LONG + timeTotal: LONG + bytesDownload: LONG + bytesUpload: LONG + dailyBytesLimit: LONG + dailyBytesDld: LONG + expert: CHAR + chatRemain: LONG + chatLimit: LONG + creditDays: LONG -> used to store days credited credit account + creditAmount: LONG -> used to store amount paid credit account + creditStartDate: LONG -> start date credit account + creditTotalToDate: LONG -> used to store amount paid to date credit account + creditTotalDate: LONG -> credit total to date date + creditTracking: CHAR -> track uploads/downloads flags in credit account + translatorID: CHAR + msgBaseRJoin:INT + confYM9: LONG ->not used + beginLogCall : LONG ->not used + protocol: CHAR ->not really used + uucpa: CHAR + lineLength: CHAR + newUser: CHAR +ENDOBJECT + +EXPORT OBJECT userKeys + userName[31]: ARRAY OF CHAR + number: LONG + newUser: CHAR + oldUpCPS: INT /* highest upload cps rate (max 64k) */ + oldDnCPS: INT /* highest dnload cps rate (max 64k)*/ + userFlags: INT /* */ + baud: INT /* last online baud rate */ + upCPS2: LONG /* new high upload cps with support for >64k */ + dnCPS2: LONG /* new high download cps with support for >64k */ + timesOnToday: INT /* number of times user has been online today */ +ENDOBJECT + +EXPORT OBJECT userMisc + internetName[10]:ARRAY OF CHAR + realName[26]:ARRAY OF CHAR + downloadBytesBCD[8]:ARRAY OF CHAR + uploadBytesBCD[8]:ARRAY OF CHAR + eMail[50]:ARRAY OF CHAR + lastDlCPS:LONG + unused[142]:ARRAY OF CHAR + ->unknown[28]:ARRAY OF CHAR + ->nodeFlags[32]:ARRAY OF LONG + ->confFlags2[10]:ARRAY OF LONG +ENDOBJECT + +EXPORT OBJECT tempAccess + accessLevel: INT + ratioType: INT + ratio: INT + timeTotal: LONG + confAc[10]: ARRAY OF CHAR +ENDOBJECT + +EXPORT OBJECT zModem + fileName[255]:ARRAY OF CHAR + titleBar[60]:ARRAY OF CHAR + zStat[60]:ARRAY OF CHAR + filesize:LONG + cps:LONG + eff:LONG + transPos:LONG + errorCount: LONG + errorPos:LONG + resumePos:LONG + elapsedTime[40]:ARRAY OF CHAR + apxTime[40]:ARRAY OF CHAR + lastTime[40]:ARRAY OF CHAR + pad[2]:ARRAY OF CHAR + lastUpdate: LONG + currentOperation: LONG + freeDFlag: LONG + current: LONG + total: LONG +ENDOBJECT + +EXPORT OBJECT confBase + handle[16]: ARRAY OF CHAR + downloadBytesBCD[8]:ARRAY OF CHAR + uploadBytesBCD[8]:ARRAY OF CHAR + newSinceDate: LONG + confRead: LONG + confYM: LONG + bytesDownload: LONG + bytesUpload: LONG + lastEMail: LONG + dailyBytesDld: LONG + upload: INT + downloads: INT + ratioType: INT + ratio: INT + messagesPosted: INT + access: INT + active:INT +ENDOBJECT + +EXPORT OBJECT doorMsg + door_Msg: mn + command:INT + data:INT + string[80]:ARRAY OF CHAR + carrier:INT +ENDOBJECT + +EXPORT OBJECT awaitState + subState: LONG + redrawScreen: LONG +ENDOBJECT + +EXPORT OBJECT loggedOnState + subState: LONG +ENDOBJECT + +EXPORT OBJECT ansi + ansicode: INT + buf[80]: ARRAY OF CHAR +ENDOBJECT + +EXPORT OBJECT mailHeader + status: CHAR + msgNumb: LONG + toName[31]: ARRAY OF CHAR + fromName[31]: ARRAY OF CHAR + subject[31]: ARRAY OF CHAR + msgDate: LONG + recv: LONG + pad: CHAR +ENDOBJECT + +EXPORT OBJECT mailStat + lowestKey : LONG + highMsgNum : LONG + lowestNotDel : LONG + pad[6]:ARRAY OF CHAR +ENDOBJECT + +EXPORT OBJECT txt + next:PTR TO txt + txt: PTR TO CHAR +ENDOBJECT + +EXPORT OBJECT rndsay + saying[MAX_SAYINGS]: ARRAY OF LONG + rnum:CHAR /* num of random sayings */ + type:CHAR +ENDOBJECT + +->0 word - left +->2 word - top +->4 word - width +->6 word - height +->8 long - bitplanes ? and interlace? +->12 word -statbar +->14 Interlace +->16DupeCheck +->18QLogon +->20TakeCredits +->22SeenIt +->24 word trapdoor +->26 ? +->28 +->30 word +->32 word ??? probably toggles[0] +->34 word +->36 word toggles[2] +->38 word toggles[3] startuplog START_LOG +->40 word toggles[4] +->42 word +->44 word toggles[6] +->46 word +->48 word +->50 word toggles[9] +->52 word Toggles[10] +->54 word toggles[11] +->56 word toggles[12] +->58 word toggles[13] +->60 word toggles[14] +->62 word toggles[15] +->64 word toggles[16] +->66 word toggles[17] +->68 word toggles[18] +->70 word toggles[19] credit by kb +->72 [80] array of char +->152 shutdown [80] array of char +->232 [80] array of char +->312 byte - rampen[80] array of char +->392 name prompt [80] +->472 files not allowed [80] array of char +->552 [80] array of char +->632 [80] array of char +->712 offHook[80]:ARRAY OF CHAR -> should be 712 +->792 nodeScreen[80]:ARRAY OF CHAR -> should be 792 +->872 t: PTR TO LONG -> should be 872 +->876 s: PTR TO LONG -> should be 876 +->880 unknown4: PTR TO LONG -> should be 880 - translator list (currently always null) +->884 unknown5: PTR TO LONG -> should be 884 - acp window + +EXPORT OBJECT editor + maxFileLength:INT + maxScrLength:CHAR + editorTop:CHAR + editorMaxWidth:CHAR + editorFlags:LONG -> // Flags for the editor, duh! + editorFile: PTR TO CHAR + editorIncludeFile:PTR TO CHAR + editorPrependFile: PTR TO CHAR + editorPostPendFile: PTR TO CHAR +ENDOBJECT + +EXPORT OBJECT qwkNDX + recNum:LONG + conf:CHAR +ENDOBJECT + +EXPORT OBJECT bgCheckData + semi: ss + checkedCount: LONG + checkedBytes: LONG +ENDOBJECT + +EXPORT OBJECT diskObjectCacheItem + fileName:PTR TO CHAR + diskObject: LONG + ownsToolTypes: CHAR +ENDOBJECT + +EXPORT OBJECT xprData + currentFile:LONG + fileList:PTR TO stdlist + updateDownloadStats: LONG +ENDOBJECT + +EXPORT OBJECT flagFileItem + fileName:PTR TO CHAR + confNum: LONG +ENDOBJECT diff --git a/bcd.e b/bcd.e new file mode 100644 index 0000000..0465ae0 --- /dev/null +++ b/bcd.e @@ -0,0 +1,192 @@ +->BCD helper methods + +OPT OSVERSION=37 +OPT MODULE + + MODULE '*axobjects' + +/*PROC unsignedCompare(v1,v2) + + MOVE.L #0,D0 + MOVE.L v1,D1 + MOVE.L v2,D2 + CMP.L D1,D2 + BEQ done + BHI high + + MOVE.L #-1,D0 + BRA done +high: + MOVE.L #1,D0 +done: +ENDPROC D0*/ + +EXPORT PROC formatBCD(valArrayBCD:PTR TO CHAR, outStr) + DEF tempStr[2]:STRING + DEF i,n,start=FALSE + + StrCopy(outStr,'') + FOR i:=0 TO 7 + n:=valArrayBCD[i] + IF (n<>0) OR (start) OR (i=7) + IF (start) OR (n>=$10) + StringF(tempStr,'\d\d',Shr(n AND $F0,4),n AND $F) + ELSE + StringF(tempStr,'\d',n AND $F) + ENDIF + StrAdd(outStr,tempStr) + start:=TRUE + ENDIF + ENDFOR +ENDPROC + +EXPORT PROC subBCD2(bcdTotal:PTR TO CHAR, bcdValToSub: PTR TO CHAR) + MOVE.L bcdValToSub,A0 + LEA 8(A0),A0 + MOVE.L bcdTotal,A1 + LEA 8(A1),A1 + + SUB.L D0,D0 ->clear X flag + + SBCD -(A0),-(A1) + SBCD -(A0),-(A1) + SBCD -(A0),-(A1) + SBCD -(A0),-(A1) + SBCD -(A0),-(A1) + SBCD -(A0),-(A1) + SBCD -(A0),-(A1) + SBCD -(A0),-(A1) +ENDPROC + + +EXPORT PROC addBCD2(bcdTotal:PTR TO CHAR, bcdValToAdd: PTR TO CHAR) + MOVE.L bcdValToAdd,A0 + LEA 8(A0),A0 + MOVE.L bcdTotal,A1 + LEA 8(A1),A1 + + SUB.L D0,D0 ->clear X flag + + ABCD -(A0),-(A1) + ABCD -(A0),-(A1) + ABCD -(A0),-(A1) + ABCD -(A0),-(A1) + ABCD -(A0),-(A1) + ABCD -(A0),-(A1) + ABCD -(A0),-(A1) + ABCD -(A0),-(A1) +ENDPROC + + +EXPORT PROC addBCD(bcdTotal:PTR TO CHAR, valToAdd) + DEF bcdVal[8]:ARRAY OF CHAR + + convertToBCD(valToAdd,bcdVal) + addBCD2(bcdTotal,bcdVal) +ENDPROC + +EXPORT PROC divBCD1024(bcdVal:PTR TO CHAR) + + DEF decVal[16]:ARRAY OF CHAR + DEF i,i2,n=0,c=0 + + FOR i:=0 TO 7 + decVal[n]:=Shr(bcdVal[i] AND $f0,4) + n++ + decVal[n]:=bcdVal[i] AND $f + n++ + ENDFOR + + FOR i2:=0 TO 9 + c:=0 + FOR i:=0 TO 15 + n:=Shr(decVal[i],1) + IF c THEN n:=n+5 + c:=decVal[i] AND 1 + decVal[i]:=n + ENDFOR + ENDFOR + + n:=0 + FOR i:=0 TO 7 + bcdVal[i]:=Shl(decVal[n],4)+decVal[n+1] + n:=n+2 + ENDFOR +ENDPROC + + +EXPORT PROC convertFromBCD(inArray:PTR TO CHAR) + DEF tempBCD[8]:ARRAY + DEF bcdStr[20]:STRING + + convertToBCD($ffffffff,tempBCD) + subBCD2(tempBCD,inArray) + IF ((tempBCD[0] AND $F0)<>0) + RETURN $ffffffff + ENDIF + formatBCD(inArray,bcdStr) +ENDPROC Val(bcdStr) + +EXPORT PROC convertToBCD(invalue,outArray: PTR TO CHAR) + DEF shift,i + + FOR i:=0 TO 7 + outArray[i]:=0 + ENDFOR + + FOR shift:=0 TO 31 + FOR i:=0 TO 7 + IF (outArray[i] AND $F0)>=$50 THEN outArray[i]:=outArray[i]+$30 + IF (outArray[i] AND $F)>=$5 THEN outArray[i]:=outArray[i]+$3 + ENDFOR + FOR i:=0 TO 6 + outArray[i]:=Shl(outArray[i],1) + IF outArray[i+1] AND $80 + outArray[i]:=outArray[i] OR 1 + ENDIF + ENDFOR + outArray[7]:=Shl(outArray[7],1) + IF (invalue AND $80000000) + outArray[7]:=outArray[7] OR 1 + ENDIF + invalue:=Shl(invalue,1) + ENDFOR +ENDPROC + +EXPORT PROC convertUserUDBytesTOBCD(userPtr: PTR TO user, userMiscPtr: PTR TO userMisc) + DEF updateUpload=TRUE, updateDownload=TRUE + DEF v + + v:=convertFromBCD(userMiscPtr.downloadBytesBCD) + IF (userPtr.bytesDownload=-1) AND (v=-1) THEN updateDownload:=FALSE + + v:=convertFromBCD(userMiscPtr.uploadBytesBCD) + IF (userPtr.bytesUpload=-1) AND (v=-1) THEN updateUpload:=FALSE + + IF updateUpload + convertToBCD(userPtr.bytesUpload,userMiscPtr.uploadBytesBCD) + ENDIF + + IF updateDownload + convertToBCD(userPtr.bytesDownload,userMiscPtr.downloadBytesBCD) + ENDIF +ENDPROC + +EXPORT PROC convertConfUDBytesTOBCD(confPtr: PTR TO confBase) + DEF updateUpload=TRUE, updateDownload=TRUE + DEF v + + v:=convertFromBCD(confPtr.downloadBytesBCD) + IF (confPtr.bytesDownload=-1) AND (v=-1) THEN updateDownload:=FALSE + + v:=convertFromBCD(confPtr.uploadBytesBCD) + IF (confPtr.bytesUpload=-1) AND (v=-1) THEN updateUpload:=FALSE + + IF updateUpload + convertToBCD(confPtr.bytesUpload,confPtr.uploadBytesBCD) + ENDIF + + IF updateDownload + convertToBCD(confPtr.bytesDownload,confPtr.downloadBytesBCD) + ENDIF +ENDPROC diff --git a/errors.e b/errors.e new file mode 100644 index 0000000..2c2ffa0 --- /dev/null +++ b/errors.e @@ -0,0 +1,4 @@ + +OPT MODULE + +EXPORT ENUM ERR_NONE, ERR_NOICON, ERR_NO_DISKFONT,ERR_SCREEN, ERR_WINDOW, ERR_MP, ERR_IO, ERR_DEV, ERR_PORT, ERR_ARG, ERR_BRKR, ERR_CXERR, ERR_LIB, ERR_ASL, ERR_KICK, ERR_SERVERRP, ERR_NOSERIAL, ERR_KICKVER, ERR_ALREADYRUNNING,ERR_COMPUTERTYPES,ERR_NOSERIALLOCK,ERR_NOOWNDEVUNIT, ERR_EXCEPT,ERR_SSL, ERR_FDSRANGE diff --git a/express.e b/express.e index 46838cf..6af5474 100644 --- a/express.e +++ b/express.e @@ -3,157 +3,11 @@ -> OPT LARGE,REG=5,OSVERSION=37 -ENUM ERR_NONE, ERR_NOICON, ERR_NO_DISKFONT,ERR_SCREEN, ERR_WINDOW, ERR_MP, ERR_IO, ERR_DEV, ERR_PORT, ERR_ARG, ERR_BRKR, ERR_CXERR, ERR_LIB, ERR_ASL, ERR_KICK, ERR_SERVERRP, ERR_NOSERIAL, ERR_KICKVER, ERR_ALREADYRUNNING,ERR_COMPUTERTYPES,ERR_NOSERIALLOCK,ERR_NOOWNDEVUNIT, ERR_EXCEPT,ERR_SSL, ERR_FDSRANGE - -ENUM STATE_AWAIT, STATE_CONNECTING, STATE_SYSOPLOGON, STATE_LOGON, STATE_LOGGEDON, STATE_HANGUP, STATE_LOGGING_OFF, STATE_SHUTDOWN, STATE_CHECK,STATE_SUSPEND - -ENUM REQ_STATE_NONE, REQ_STATE_LOGOFF, REQ_STATE_SHUTDOWN, REQ_STATE_SHUTDOWN_OFFHOOK, REQ_STATE_SYSOPLOGON, REQ_STATE_LOGON, REQ_STATE_RESUME - -ENUM SUBSTATE_DISPLAY_AWAIT, SUBSTATE_INPUT, SUBSTATE_DISPLAY_BULL, SUBSTATE_DISPLAY_CONF_BULL, SUBSTATE_DISPLAY_MENU, SUBSTATE_READ_COMMAND, SUBSTATE_PROCESS_COMMAND - -ENUM CMDTYPE_BBSCMD,CMDTYPE_SYSCMD,CMDTYPE_CUSTOM - -ENUM TOOLTYPE_PRESET, TOOLTYPE_NODE,TOOLTYPE_CONFCONFIG,TOOLTYPE_CONF,TOOLTYPE_BBSCMD,TOOLTYPE_CONFCMD,TOOLTYPE_NODECMD,TOOLTYPE_SYSCMD,TOOLTYPE_DRIVES,TOOLTYPE_NAMESNOTALLOWED,TOOLTYPE_COMPUTERLIST,TOOLTYPE_ACCESS,TOOLTYPE_AREA,TOOLTYPE_FCHECK,TOOLTYPE_NODE_WINDOW,TOOLTYPE_NODE_TIMES,TOOLTYPE_WINDOW,TOOLTYPE_CONNECT,TOOLTYPE_XPRTYPES,TOOLTYPE_XFERLIB,TOOLTYPE_SCREENTYPES,TOOLTYPE_NRAMS, TOOLTYPE_BBSCONFIG,TOOLTYPE_ASCPACK,TOOLTYPE_QWKPACK,TOOLTYPE_QWKCONFIG,TOOLTYPE_DEFAULT_ACCESS,TOOLTYPE_LANGUAGES,TOOLTYPE_USER_ACCESS, TOOLTYPE_NODE_PRESET,TOOLTYPE_CONFCMD2,TOOLTYPE_CONFSYSCMD,TOOLTYPE_NODESYSCMD - -ENUM DOORTYPE_XIM, DOORTYPE_AIM, DOORTYPE_SIM, DOORTYPE_TIM, DOORTYPE_IIM, DOORTYPE_MCI, DOORTYPE_AEM, DOORTYPE_SUP - -ENUM LOG_NONE=0, LOG_ERROR=1, LOG_WARN=2, LOG_DEBUG=3 - -ENUM SCREEN_AWAIT, SCREEN_BBSTITLE, SCREEN_LOGON, SCREEN_JOIN, SCREEN_JOINCONF, SCREEN_JOINED, SCREEN_BULL, SCREEN_NODE_BULL, SCREEN_CONF_BULL, SCREEN_MENU, SCREEN_LOGOFF, SCREEN_DOWNLOAD, SCREEN_UPLOAD, SCREEN_NEWUSERPW, SCREEN_NONEWUSERS, SCREEN_NONEWATBAUD, SCREEN_GUESTLOGON, SCREEN_NOCALLERSATBAUD, SCREEN_LOCKOUT0, SCREEN_LOCKOUT1, SCREEN_PRIVATE, SCREEN_ONENODE, SCREEN_LOGON24, SCREEN_NOT_TIME, SCREEN_FILEHELP,SCREEN_LANGUAGES,SCREEN_REALNAMES,SCREEN_INTERNETNAMES - -ENUM LOGON_TYPE_LOGGED_OFF=0, LOGON_TYPE_SYSOP=1, LOGON_TYPE_LOCAL=2, LOGON_TYPE_REMOTE=3 - -ENUM RESULT_FAILURE=-1, RESULT_SUCCESS=0, RESULT_NOT_ALLOWED=1, RESULT_ABORT=-2, RESULT_TIMEOUT=-3, RESULT_NO_CARRIER=-4, RESULT_GOODBYE=-5, RESULT_SLEEP_LOGOFF=-6, RESULT_STANDARD_LOGOFF=-7, RESULT_CONNECT=-8, RESULT_NOT_TESTED=2, RESULT_LCFILES=9,RESULT_PRIVATE=10, RESULT_SIGNALLED=11, RESULT_NOT_FOUND=12 - -ENUM ERR_MEMORY,ERR_MEMORY2,ERR_MSGBASE,ERR_MEMORY3,ERR_FILELIST,ERR_NOFILES,ERR_FILEEXAMINE,ERR_WORKDIROPEN,ERR_LOCK,ERR_FREESPACE,ERR_SYMBOLS,ERR_FIB_MEMORY,ERR_NO_BULLS,ERR_NO_CONFFLAGS - -ENUM MAIL_READ=1,MAIL_CREATE=2, MAIL_SCAN=3 - -ENUM CONSOLE_PORT=1, SERIAL_PORT=2 - -ENUM ZMODEM_NONE, ZMODEM_UPLOAD, ZMODEM_DOWNLOAD - -ENUM NAME_TYPE_USERNAME, NAME_TYPE_REALNAME, NAME_TYPE_INTERNETNAME -ENUM UPDATE_RATIO,UPDATE_RATIO_TYPE,UPDATE_MAILSCAN_PTRS,UPDATE_NEW_MAIL_SCAN,UPDATE_NEW_FILE_SCAN,UPDATE_DEFAULT_ZOOM_FLAG,UPDATE_LAST_MESSAGE,UPDATE_MESSAGES_POSTED, UPDATE_RESET_VOTING - -ENUM CACHE_RESET_NEVER, CACHE_RESET_LOGON - -ENUM TRANS_NONE,TRANS_HOST_TO_DEFINED,TRANS_DEFINED_TO_HOST - -ENUM FORCE_MAILSCAN_NOFORCE, FORCE_MAILSCAN_ALL, FORCE_MAILSCAN_SKIP - -CONST LISTENQ=100 -CONST FIONBIO=$8004667e -CONST FIONREAD=$4004667f -CONST EINTR=4 -CONST EWOULDBLOCK=35 -CONST ENOBUFS=55 - -CONST DEFAULT_DISK_OBJECT_CACHE_SIZE=100 - -CONST MAX_FLAGGED_FILES=1000 - -CONST BG_EXIT=1200 -CONST BG_DONT_EXIT=1200 -CONST BG_CHECKFILE=1201 - -CONST ACTION_REQUEST=5000 - -CONST FIFOF_READ=$00000100 /* intend to read from fifo */ -CONST FIFOF_WRITE=$00000200 /* intend to write to fifo */ -CONST FIFOF_RESERVED=$FFFF0000 /* reserved for internal use */ -CONST FIFOF_NORMAL=$00000400 /* request blocking/sig support*/ -CONST FIFOF_NBIO=$00000800 /* non-blocking IO */ - -CONST FIFOF_KEEPIFD=$00002000 /* keep fifo alive if data pending */ -CONST FIFOF_EOF=$00004000 /* EOF on close */ -CONST FIFOF_RREQUIRED=$00008000 /* reader required to exist */ - -CONST FREQ_RPEND=1 -CONST FREQ_WAVAIL=2 -CONST FREQ_ABORT=3 - -CONST TWODIGITYEARSWITCHOVER=70 - -CONST MAXNODES=32 - -CONST MAIL_SCAN_MASK=4 -CONST FILE_SCAN_MASK=8 -CONST ZOOM_SCAN_MASK=2 - -CONST IOFLAG_FIL_IN=0 -CONST IOFLAG_KBD_IN=1 -CONST IOFLAG_SER_IN=2 -CONST IOFLAG_FIL_OUT=3 -CONST IOFLAG_PRT_OUT=4 -CONST IOFLAG_SCR_OUT=5 -CONST IOFLAG_SER_OUT=6 - -CONST CMD_NONSTD=9 - -CONST SDCMD_QUERY = CMD_NONSTD -CONST CIAF_COMCD=32 -CONST CIAF_COMDSR=8 - -CONST ACCESS_READ=-2 - -CONST ED_ANSI_ALLOWED=1 ->// Flag indicating that ANSI Colors are allowed in message -CONST ED_ABORT_ALLOWED=2 ->// Flag indicating that the Abort command is enabled -CONST ED_LOAD_ALLOWED=4 ->// Flag indicating that the Load command is enabled -CONST ED_BATCH_UPLOAD=8 ->// Flag indicating that the Upload command is enabled -CONST ED_ATTACH_FILE=16 ->// Flag indicating that the File Attach Command is enabled. -CONST ED_BATCH_REQUESTED=32768 ->// Flag indicating batch true -CONST ED_ATTACH_REQUESTED=16384 - -CONST HISTORY=999 -CONST LEFTARROW=2 -CONST RIGHTARROW=3 -CONST UPARROW=4 -CONST DOWNARROW=5 - -CONST CHAR_BACKSPACE=8 -CONST CHAR_DELETE=127 -CONST CHAR_TAB=9 - -CONST BIO_CTRL_FLUSH=11 -CONST BIO_FLAGS_BASE64_NO_NL=$100 -CONST BIO_CTRL_INFO=3 - -CONST AMISSLMASTER_MIN_VERSION=4 -CONST AMISSL_CURRENT_VERSION=6 - -CONST SSL_VERIFY_PEER=1 -CONST SSL_VERIFY_FAIL_IF_NO_PEER_CERT=2 - -CONST BIO_NOCLOSE=$0 -CONST BIO_FP_TEXT=$10 - -CONST OPENSSL_LINE=0 - -CONST BIO_SET_FILE_PTR=$6a ->dont know what this is - -CONST OPENSSL_INIT_LOAD_SSL_STRINGS=$200000 -CONST OPENSSL_INIT_LOAD_CRYPTO_STRINGS=2 - -DEF amiSSL_SocketBase = $80000001 -DEF amiSSL_ErrNoPtr = $8000000B - -DEF sslerrno -DEF ctx: LONG ->PTR TO SSL_CTX -DEF bio_err: LONG ->PTR TO BIO - --> User Keys Flags - /* show new user message */ /* show all users only once */ -ENUM USER_NEWMSG=1,USER_TOCONF1=2, USER_ONETIME_MSG=4,USER_SCRNCLR=8,USER_DONATED=16,USER_ED_FULLSCREEN=32,USER_ED_PROMPT=64,USER_BGFILECHECK=128 - -> AmiExpress_Node.0 - arexx port for shutdown/suspend messages -> ServerRP0 - Send Messages to ACP (create at startup, register with ACP, receive bbs title) -> AEServer.0 - messages from ACP (create at startup) - global door port -> AEDoorPort0 - communicate with running exe (create while running door) - local door port -CONST TRACK_UPLOADS_BIT=1 -CONST TRACK_DOWNLOADS_BIT=2 - /* stuff to do: @@ -162,9 +16,6 @@ cache msgscan ? any missing Door port commands DT_LANGUAGE(set),SETOVERIDE,FULLEDIT (not implemented in /X3 or 4) 607 - get/set something that isnt used anywhere else in the code (not yet implemented) - 608 - some kind of input routine ??? (not yet implemented) - 610 - trigger netmail receive (not yet implemented) - 611 - trigger netmail send (not yet implemented) 612 - get MemConf address (not yet implemented) 621 - interpret mci string (not yet implemented) 631 - get or set unknown thing ??? (skips messages during download) (not yet implemented) @@ -182,33 +33,6 @@ STICKY - trapdoor command line parameter */ -CONST MAX_SAYINGS=50 -CONST INPUT_TIMEOUT=300 - -CONST CONU_CHARMAP=1 -CONST CONFLAG_DEFAULT=0 - -CONST PG_SM=1 -CONST PG_CO=2 -CONST PG_SO=3 -CONST PG_CC=4 -CONST PG_CH=5 -CONST PG_PM=6 -CONST PG_SC=7 -CONST PG_HK=8 -CONST PG_SF=10 -CONST PG_FF=11 -CONST PG_EF=12 -CONST PG_UD=13 -CONST PG_US=14 -CONST PG_PS=15 -CONST PG_CS=16 -CONST PG_RD=17 -CONST PG_CL=18 -CONST PG_SG=19 -CONST PG_SHUTDOWN=20 -CONST PG_TM=21 - MODULE 'intuition/screens', 'intuition/intuition', 'intuition/gadgetclass', @@ -253,305 +77,26 @@ MODULE 'intuition/screens', 'net/socket', 'net/netdb', 'net/in', - 'amissl', - 'amisslmaster', 'fifo', 'owndevunit', 'asyncio', 'libraries/asyncio' MODULE '*axcommon', + '*axconsts', + '*axenums', + '*axobjects', '*miscfuncs', '*stringlist', - '*ftpd' - -OBJECT user - name[30]:ARRAY OF CHAR - name31: CHAR -> last character of name (odd sized arrays are always padded so need this kludge) - pass0: CHAR -> first character of pass (odd sized arrays are always padded so need this kludge) - pass[8]:ARRAY OF CHAR - location[30]:ARRAY OF CHAR - phoneNumber[13]:ARRAY OF CHAR - slotNumber: INT - secStatus: INT - secBoard: INT /* File or Byte Ratio */ - secLibrary: INT /* Ratio */ - secBulletin: INT /* Computer Type */ - messagesPosted: INT - /* Note ConfYM = the last msg you actually read, ConfRead is the same ?? */ - newSinceDate: LONG - pwdHash: LONG - confRead2: LONG - confRead3: LONG - zoomType: INT - unknown: INT - unknown2: INT - unknown3: INT - xferProtocol: INT - filler2: INT - lcFiles: INT - badFiles: INT - accountDate: LONG - screenType: INT - editorType: INT - conferenceAccess[10]: ARRAY OF CHAR - uploads: INT - downloads: INT - confRJoin: INT - timesCalled: INT - timeLastOn: LONG - timeUsed: LONG - timeLimit: LONG - timeTotal: LONG - bytesDownload: LONG - bytesUpload: LONG - dailyBytesLimit: LONG - dailyBytesDld: LONG - expert: CHAR - chatRemain: LONG - chatLimit: LONG - creditDays: LONG -> used to store days credited credit account - creditAmount: LONG -> used to store amount paid credit account - creditStartDate: LONG -> start date credit account - creditTotalToDate: LONG -> used to store amount paid to date credit account - creditTotalDate: LONG -> credit total to date date - creditTracking: CHAR -> track uploads/downloads flags in credit account - translatorID: CHAR - unused2: INT - confYM9: LONG - beginLogCall : LONG - protocol: CHAR - uucpa: CHAR - lineLength: CHAR - newUser: CHAR -ENDOBJECT - -OBJECT userKeys - userName[31]: ARRAY OF CHAR - number: LONG - newUser: CHAR - oldUpCPS: INT /* highest upload cps rate (max 64k) */ - oldDnCPS: INT /* highest dnload cps rate (max 64k)*/ - userFlags: INT /* */ - baud: INT /* last online baud rate */ - upCPS2: LONG /* new high upload cps with support for >64k */ - dnCPS2: LONG /* new high download cps with support for >64k */ - timesOnToday: INT /* number of times user has been online today */ -ENDOBJECT - -OBJECT userMisc - internetName[10]:ARRAY OF CHAR - realName[26]:ARRAY OF CHAR - downloadBytesBCD[8]:ARRAY OF CHAR - uploadBytesBCD[8]:ARRAY OF CHAR - unknown[28]:ARRAY OF CHAR - nodeFlags[32]:ARRAY OF LONG - confFlags2[10]:ARRAY OF LONG -ENDOBJECT - -OBJECT tempAccess - accessLevel: INT - ratioType: INT - ratio: INT - timeTotal: LONG - confAc[10]: ARRAY OF CHAR -ENDOBJECT - -OBJECT zModem - fileName[255]:ARRAY OF CHAR - titleBar[60]:ARRAY OF CHAR - zStat[60]:ARRAY OF CHAR - filesize:LONG - cps:LONG - eff:LONG - transPos:LONG - errorCount: LONG - errorPos:LONG - resumePos:LONG - elapsedTime[40]:ARRAY OF CHAR - apxTime[40]:ARRAY OF CHAR - lastTime[40]:ARRAY OF CHAR - pad[2]:ARRAY OF CHAR - lastUpdate: LONG - currentOperation: LONG - freeDFlag: LONG - current: LONG - total: LONG -ENDOBJECT - -OBJECT confBase - handle[16]: ARRAY OF CHAR - downloadBytesBCD[8]:ARRAY OF CHAR - uploadBytesBCD[8]:ARRAY OF CHAR - newSinceDate: LONG - confRead: LONG - confYM: LONG - bytesDownload: LONG - bytesUpload: LONG - lastEMail: LONG - dailyBytesDld: LONG - upload: INT - downloads: INT - ratioType: INT - ratio: INT - messagesPosted: INT - access: INT - active:INT -ENDOBJECT - -OBJECT doorMsg - door_Msg: mn - command:INT - data:INT - string[80]:ARRAY OF CHAR - carrier:INT -ENDOBJECT - -OBJECT awaitState - subState: LONG - redrawScreen: LONG -ENDOBJECT - -OBJECT loggedOnState - subState: LONG -ENDOBJECT - -OBJECT ansi - ansicode: INT - buf[80]: ARRAY OF CHAR -ENDOBJECT - -OBJECT mailHeader - status: CHAR - msgNumb: LONG - toName[31]: ARRAY OF CHAR - fromName[31]: ARRAY OF CHAR - subject[31]: ARRAY OF CHAR - msgDate: LONG - recv: LONG - pad: CHAR -ENDOBJECT - -OBJECT mailStat - lowestKey : LONG - highMsgNum : LONG - lowestNotDel : LONG - pad[6]:ARRAY OF CHAR -ENDOBJECT - -OBJECT txt - next:PTR TO txt - txt: PTR TO CHAR -ENDOBJECT - -OBJECT rndsay - saying[MAX_SAYINGS]: ARRAY OF LONG - rnum:CHAR /* num of random sayings */ - type:CHAR -ENDOBJECT - -OBJECT mailConfig - smtpHost[255]:ARRAY OF CHAR - smtpPort:LONG - username[255]:ARRAY OF CHAR - password[255]:ARRAY OF CHAR - sysopEmail[255]:ARRAY OF CHAR - bbsEmail[255]:ARRAY OF CHAR - ssl: INT - mailOnNewUser: INT - mailOnSysopComment: INT - mailOnSysopPage: INT -ENDOBJECT - -->0 word - left -->2 word - top -->4 word - width -->6 word - height -->8 long - bitplanes ? and interlace? -->12 word -statbar -->14 Interlace -->16DupeCheck -->18QLogon -->20TakeCredits -->22SeenIt -->24 word trapdoor -->26 ? -->28 -->30 word -->32 word ??? probably toggles[0] -->34 word -->36 word toggles[2] -->38 word toggles[3] startuplog START_LOG -->40 word toggles[4] -->42 word -->44 word toggles[6] -->46 word -->48 word -->50 word toggles[9] -->52 word Toggles[10] -->54 word toggles[11] -->56 word toggles[12] -->58 word toggles[13] -->60 word toggles[14] -->62 word toggles[15] -->64 word toggles[16] -->66 word toggles[17] -->68 word toggles[18] -->70 word toggles[19] credit by kb -->72 [80] array of char -->152 shutdown [80] array of char -->232 [80] array of char -->312 byte - rampen[80] array of char -->392 name prompt [80] -->472 files not allowed [80] array of char -->552 [80] array of char -->632 [80] array of char -->712 offHook[80]:ARRAY OF CHAR -> should be 712 -->792 nodeScreen[80]:ARRAY OF CHAR -> should be 792 -->872 t: PTR TO LONG -> should be 872 -->876 s: PTR TO LONG -> should be 876 -->880 unknown4: PTR TO LONG -> should be 880 - translator list (currently always null) -->884 unknown5: PTR TO LONG -> should be 884 - acp window - -OBJECT editor - maxFileLength:INT - maxScrLength:CHAR - editorTop:CHAR - editorMaxWidth:CHAR - editorFlags:LONG -> // Flags for the editor, duh! - editorFile: PTR TO CHAR - editorIncludeFile:PTR TO CHAR - editorPrependFile: PTR TO CHAR - editorPostPendFile: PTR TO CHAR -ENDOBJECT - -OBJECT qwkNDX - recNum:LONG - conf:CHAR -ENDOBJECT - -OBJECT bgCheckData - semi: ss - checkedCount: LONG - checkedBytes: LONG -ENDOBJECT - -OBJECT diskObjectCacheItem - fileName:PTR TO CHAR - diskObject: LONG - ownsToolTypes: CHAR -ENDOBJECT - -OBJECT flagFileItem - fileName:PTR TO CHAR - confNum: LONG -ENDOBJECT - -OBJECT xprData - currentFile:LONG - fileList:PTR TO stdlist - updateDownloadStats: LONG -ENDOBJECT + '*ftpd', + '*httpd', + '*errors', + '*mailssl', + '*zmodem', + '*bcd', + '*pwdhash', + '*tooltypes', + '*expversion' DEF masterMsg:acpMessage DEF resmp: PTR TO mp @@ -574,7 +119,7 @@ DEF inac=FALSE DEF state=-1, stateData, reqState,instantLogon=FALSE DEF windowClose=NIL:PTR TO window DEF windowStat=NIL:PTR TO window -DEF windowZmodem:PTR TO window +DEF windowZmodem=NIL:PTR TO window DEF consoleReadMP=NIL: PTR TO mp DEF titlebar[255]:STRING DEF ititlebar[255]:STRING @@ -593,14 +138,14 @@ DEF readQueued=FALSE DEF timerQueued=FALSE DEF ibuf, serbuff, inControl DEF commandText[255]:STRING -DEF loggedOnUser: PTR TO user -DEF loggedOnUserKeys: PTR TO userKeys -DEF loggedOnUserMisc: PTR TO userMisc +DEF loggedOnUser=NIL: PTR TO user ->shared with tooltypes.e +DEF loggedOnUserKeys=NIL: PTR TO userKeys +DEF loggedOnUserMisc=NIL: PTR TO userMisc DEF tempAccess: tempAccess DEF tempAccessGranted=FALSE DEF sopt=NIL: PTR TO startOption -DEF mailOptions: mailConfig -DEF node +DEF mailOptions=NIL: PTR TO mailConfig ->shared with mailssl.e +DEF node ->shared with tooltypes.e DEF ringCount DEF nodeScreenDir[255]:STRING DEF confScreenDir[255]:STRING @@ -609,11 +154,12 @@ DEF reservedName[255]:STRING DEF consoleOutputDeviceName[255]:STRING DEF consoleInputDeviceName[255]:STRING -DEF currentConf=0 +DEF currentConf=0 ->shared with tooltypes.e +DEF currentMsgBase=0 DEF relConfNum=0 DEF callerNum=0 DEF currentConfName[255]:STRING -DEF currentConfDir[255]:STRING +DEF currentConfDir[255]:STRING ->shared with tooltypes.e DEF msgBaseLocation[255]:STRING DEF uploadLocation[255]:STRING DEF userDataFile[255]:STRING @@ -637,7 +183,7 @@ DEF expressDate[15]:STRING DEF regKey[100]:STRING DEF mailStat=NIL: PTR TO mailStat DEF mailHeader=NIL: PTR TO mailHeader -DEF cmds: commands +DEF cmds: PTR TO commands ->shared with tooltyles.e DEF mybbsLoc[255]:STRING DEF parsedParams: PTR TO stringlist DEF confBases: PTR TO stdlist @@ -657,7 +203,6 @@ DEF bytesADL=0 DEF tTEFF=0 DEF tTCPS=0 DEF tTTM=0 -DEF tMPBT=0 DEF tBT=0 DEF dTBT=0 DEF beenUDd=0 @@ -699,7 +244,7 @@ DEF msgNum DEF fwdToMsg DEF currentSeekPos DEF fileattach=TRUE, newmailsearch = FALSE -DEF attachedFile[255]:STRING +DEF attachedFiles: PTR TO stringlist DEF privateFlag=0 DEF alreadyRecvd DEF delMsgNum @@ -708,7 +253,7 @@ DEF lastNewReadConf=0 DEF msgBuf: PTR TO stringlist DEF maxMsgLines = 800 DEF confNames: PTR TO stringlist -DEF confDirs: PTR TO stringlist +DEF confDirs: PTR TO stringlist ->shared with tooltyles.e DEF historyFolder[255]:STRING DEF userNotesFolder[255]:STRING DEF historyBuf : PTR TO stringlist @@ -727,13 +272,13 @@ DEF editor: editor DEF editorFileName[80]:STRING DEF editorFileInclude[80]:STRING -DEF xprLib: PTR TO stringlist +DEF xprLib: PTR TO stringlist ->shared with tooltypes.e DEF xprTitle: PTR TO stringlist DEF screenTypeTitle: PTR TO stringlist DEF screenTypeExt: PTR TO stringlist DEF scomment:PTR TO stringlist -DEF fCheckDir[255]:STRING +DEF fCheckDir[255]:STRING ->shared with tooltypes.e DEF hostLanguage[255]:STRING DEF userLanguage[255]:STRING @@ -765,6 +310,11 @@ DEF lastTimeUpdate DEF bitPlanes=3 DEF ximPort=0 +DEF slowmo=0 +DEF slowmoCount=0 + +DEF resetSerOut=FALSE + DEF mimicVersion[255]:STRING DEF namePrompt[255]:STRING @@ -790,6 +340,7 @@ DEF serShared=FALSE DEF zresume=0 DEF scropen=FALSE +DEF wantzwin=FALSE DEF screen=NIL:PTR TO screen DEF window=NIL:PTR TO window DEF defaultfontattr: textattr @@ -826,10 +377,10 @@ DEF sdReplyRexx=NIL: PTR TO rexxmsg DEF bgData:bgCheckData DEF bgFileCheck=FALSE -DEF diskObjectCache:PTR TO stdlist +DEF diskObjectCache:PTR TO stdlist ->shared with tooltypes.e DEF cacheResetOn=CACHE_RESET_NEVER -DEF cacheTests=0 -DEF cacheHits=0 +DEF cacheTests=0 ->shared with tooltypes.e +DEF cacheHits=0 ->shared with tooltypes.e DEF serialLocked=FALSE DEF ownDevSignal=0 @@ -869,16 +420,16 @@ DEF cntr=0 DEF fds=NIL:PTR TO LONG +DEF zmodemBuffer=0 +DEF zModemBufferSize=65536 +DEF bufferedBytes=0 +DEF bufferReadOffset=0 + + RAISE ERR_BRKR IF CxBroker()=NIL, ERR_PORT IF CreateMsgPort()=NIL, ERR_ASL IF AllocAslRequest()=NIL - -PROC listAdd2(list:PTR TO LONG, v) - ListAdd(list,[0]) - list[ListLen(list)-1]:=v -ENDPROC - PROC configFileExists(fname:PTR TO CHAR) DEF lh DEF fn[255]:STRING @@ -901,46 +452,17 @@ PROC configFileExists(fname:PTR TO CHAR) ENDIF ENDPROC FALSE -PROC checkIconifyMsg() -ENDPROC - -PROC getUserAccessFilename(outFilename: PTR TO CHAR) - DEF tempStr[255]:STRING - - DEF i,c - - StrCopy(tempStr,loggedOnUser.name) - FOR i:=0 TO StrLen(tempStr)-1 - c:=tempStr[i] - SELECT c - CASE "%" - tempStr[i]:="_" - CASE "#" - tempStr[i]:="_" - CASE "?" - tempStr[i]:="_" - CASE "/" - tempStr[i]:="_" - CASE "(" - tempStr[i]:="_" - CASE ")" - tempStr[i]:="_" - ENDSELECT - ENDFOR - - StringF(outFilename,'\sACCESS/\s',cmds.bbsLoc,tempStr) -ENDPROC - PROC convertAccess() DEF tempStr[255]:STRING acsLevel:=findAcsLevel() - StringF(tempStr,'\sAccess',cmds.bbsLoc) - IF configFileExists(tempStr)=FALSE THEN overrideDefaultAccess:=TRUE ELSE overrideDefaultAccess:=checkSecurity(ACS_OVERRIDE_DEFAULTS) getUserAccessFilename(tempStr) userSpecificAccess:=configFileExists(tempStr); + StringF(tempStr,'\sAccess',cmds.bbsLoc) + IF configFileExists(tempStr)=FALSE THEN overrideDefaultAccess:=TRUE ELSE overrideDefaultAccess:=checkSecurity(ACS_OVERRIDE_DEFAULTS) + StrCopy(securityFlags,'') ENDPROC @@ -953,532 +475,6 @@ PROC isConfAccessAreaName(user:PTR TO user) ENDFOR ENDPROC c<>0 -/*must be called with EString*/ -PROC removeCR(str:PTR TO CHAR) - DEF i,n=0 - FOR i:=0 TO EstrLen(str)-1 - IF str[i]<>13 - str[n]:=str[i] - n++ - ENDIF - ENDFOR - SetStr(str,n) -ENDPROC - -PROC stcsma(s: PTR TO CHAR,p: PTR TO CHAR) - DEF ret,len - DEF buf - - len:=StrLen(p)*2+2 - buf:=New(len) - - IF(buf=NIL) - ret:=0 - ELSE - IF (ParsePatternNoCase(p, buf, len) < 0) - ret:=0 - ELSE - ret:=MatchPatternNoCase(buf, s) - ENDIF - ENDIF - Dispose(buf) -ENDPROC ret - -PROC sendMail(subject:PTR TO CHAR,bodytext:PTR TO CHAR, appendMsgBuf, toemail:PTR TO CHAR) - DEF ssl,sock=0,errcode=0 - DEF buffer[4096]:STRING; /* This should be dynamically allocated */ - DEF bufsize=4096 - DEF request[512]:STRING - DEF failed=FALSE,v,i - - /* The following needs to be done once per socket */ - - /* Connect to the HTTPS server, directly or through a proxy */ - sock:=connectToServer(mailOptions.smtpHost,mailOptions.smtpPort) - - /* Check if connection was established */ - IF (sock >= 0) - IF ctx - IF((ssl:=SsL_new(ctx)) <> NIL) - - /* Associate the socket with the ssl structure */ - SsL_set_fd(ssl, sock) - - /* Perform SSL handshake */ - IF((errcode:=SsL_connect(ssl)) >= 0) - - IF ((errcode:=SsL_read(ssl, buffer,bufsize - 1)) >0) - buffer[errcode]:=0 - WriteF('\s \d \d\n',buffer, errcode, 1); - ELSE - WriteF('Couldn''t read initial server message!\n'); - ENDIF - - StrCopy(request,'EHLO relay.example.com\n') - IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) - WriteF('error sending EHLO\n'); - ENDIF - - IF((errcode:=SsL_read(ssl, buffer,bufsize - 1)) > 0) - buffer[errcode]:=0 - v:=Val(buffer) - failed:=((v<200) OR (v>299)) - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - - IF (failed=FALSE) - StringF(request,'\n\s\n\s',mailOptions.username,mailOptions.password) - v:=StrLen(request)-1 - FOR i:=0 TO v - IF request[i]="\n" THEN request[i]:=0 - ENDFOR - base64enc(request,EstrLen(request),buffer) - StringF(request,'AUTH PLAIN \s\n',buffer) - IF ((errcode:=SsL_write(ssl, request, EstrLen(request))) <=0 ) - WriteF('error sending AUTH\n'); - ENDIF - - IF((errcode:=SsL_read(ssl, buffer,bufsize - 1)) > 0) - buffer[errcode]:=0 - v:=Val(buffer) - failed:=((v<200) OR (v>299)) - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - ENDIF - - IF (failed=FALSE) - StringF(request,'mail from:<\s>\n',mailOptions.bbsEmail) - IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) - WriteF('error sending FROM\n'); - ENDIF - - IF((errcode:=SsL_read(ssl, buffer,bufsize - 1)) > 0) - buffer[errcode]:=0 - v:=Val(buffer) - failed:=((v<200) OR (v>299)) - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - ENDIF - - IF (failed=FALSE) - StringF(request,'rcpt to:<\s>\n',toemail) - IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) - WriteF('error sending TO\n'); - ENDIF - - IF((errcode:=SsL_read(ssl, buffer,bufsize - 1)) > 0) - buffer[errcode]:=0 - v:=Val(buffer) - failed:=((v<200) OR (v>299)) - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - ENDIF - - IF (failed=FALSE) - StrCopy(request,'DATA\n') - IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) - WriteF('error sending DATA\n'); - ENDIF - - IF((errcode:=SsL_read(ssl, buffer,bufsize - 1)) > 0) - buffer[errcode]:=0 - v:=Val(buffer) - failed:=(((v<200) OR (v>299)) AND (v<>354)) - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - ENDIF - - IF (failed=FALSE) - StrCopy(request,'From: <\s>\b\n',mailOptions.bbsEmail) - IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) - WriteF('error sending msg data\n'); - ENDIF - - StrCopy(request,'To: \b\n') - IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) - WriteF('error sending msg data\n'); - ENDIF - - StringF(request,'Subject: \s\b\n',subject) - IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) - WriteF('error sending msg data\n'); - ENDIF - - StrCopy(request,'\b\n') - IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) - WriteF('error sending msg data\n'); - ENDIF - - i:=0 - WHILE(i 0) - buffer[errcode]:=0 - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - - - StrCopy(request,'QUIT\n') - IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) - WriteF('error sending QUIT\n'); - ENDIF - ENDIF - ELSE - WriteF('Couldn''t establish SSL connection!\n'); - ENDIF - - /* If there were errors, print them */ - ->IF (errcode < 0) THEN ErR_print_errors(bio_err); - - /* Send SSL close notification and close the socket */ - SsL_shutdown(ssl); - - SsL_free(ssl); - ELSE - WriteF('Couldn''t create new SSL handle!\n'); - ENDIF - - - ELSE - ->standard unencrypted smtp - IF ((errcode:=Recv(sock,buffer,bufsize - 1,0)) >0) - buffer[errcode]:=0 - WriteF('\s \d \d\n',buffer, errcode, 1); - ELSE - WriteF('Couldn''t read initial server message!\n'); - ENDIF - - StrCopy(request,'EHLO relay.example.com\n') - IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) - WriteF('error sending EHLO\n'); - ENDIF - - IF((errcode:=Recv(sock, buffer,bufsize - 1,0)) > 0) - buffer[errcode]:=0 - v:=Val(buffer) - failed:=((v<200) OR (v>299)) - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - - IF (failed=FALSE) - StringF(request,'\n\s\n\s',mailOptions.username,mailOptions.password) - v:=StrLen(request)-1 - FOR i:=0 TO v - IF request[i]="\n" THEN request[i]:=0 - ENDFOR - base64enc(request,EstrLen(request),buffer) - StringF(request,'AUTH PLAIN \s\n',buffer) - IF ((errcode:=Send(sock, request, EstrLen(request),0)) <=0 ) - WriteF('error sending AUTH\n'); - ENDIF - - IF((errcode:=Recv(sock, buffer,bufsize - 1,0)) > 0) - buffer[errcode]:=0 - v:=Val(buffer) - failed:=((v<200) OR (v>299)) - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - ENDIF - - IF (failed=FALSE) - StringF(request,'mail from:<\s>\n',mailOptions.bbsEmail) - IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) - WriteF('error sending FROM\n'); - ENDIF - - IF((errcode:=Recv(sock, buffer,bufsize - 1,0)) > 0) - buffer[errcode]:=0 - v:=Val(buffer) - failed:=((v<200) OR (v>299)) - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - ENDIF - - IF (failed=FALSE) - StringF(request,'rcpt to:<\s>\n',toemail) - IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) - WriteF('error sending TO\n'); - ENDIF - - IF((errcode:=Recv(sock, buffer,bufsize - 1,0)) > 0) - buffer[errcode]:=0 - v:=Val(buffer) - failed:=((v<200) OR (v>299)) - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - ENDIF - - IF (failed=FALSE) - StrCopy(request,'DATA\n') - IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) - WriteF('error sending DATA\n'); - ENDIF - - IF((errcode:=Recv(sock, buffer,bufsize - 1,0)) > 0) - buffer[errcode]:=0 - v:=Val(buffer) - failed:=(((v<200) OR (v>299)) AND (v<>354)) - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - ENDIF - - IF (failed=FALSE) - StrCopy(request,'From: <\s>\b\n',mailOptions.bbsEmail) - IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) - WriteF('error sending msg data\n'); - ENDIF - - StrCopy(request,'To: \b\n') - IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) - WriteF('error sending msg data\n'); - ENDIF - - StringF(request,'Subject: \s\b\n',subject) - IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) - WriteF('error sending msg data\n'); - ENDIF - - StrCopy(request,'\b\n') - IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) - WriteF('error sending msg data\n'); - ENDIF - - i:=0 - WHILE(i 0) - buffer[errcode]:=0 - WriteF('\s \d \d\n',buffer, errcode, 1); - ENDIF - - - StrCopy(request,'QUIT\n') - IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) - WriteF('error sending QUIT\n'); - ENDIF - ENDIF - ENDIF - CloseSocket(sock); - ELSE - WriteF('Couldn''t connect to host!\n'); - ENDIF -ENDPROC - -PROC base64enc(data:PTR TO CHAR,len,output) - DEF b64 - DEF mem - DEF done=FALSE,res=0,outstr,strlen - -> bio is simply a class that wraps BIO* and it free the BIO in the destructor. - - b64:=BiO_new(BiO_f_base64()); ->// create BIO to perform base64 - BiO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); - - mem:=BiO_new(BiO_s_mem()); ->// create BIO that holds the result - - ->// chain base64 with mem, so writing to b64 will encode base64 and write to mem. - BiO_push(b64, mem); - - ->// write data - WHILE(done=FALSE) - res:=BiO_write(b64, data, len); - - IF(res <= 0) -> if failed - IF(BiO_fd_should_retry(b64)=FALSE) - ->// encoding failed - /* Handle Error!!! */ - RETURN 0 - ENDIF - ELSE - ->// success! - done:=TRUE; - ENDIF - ENDWHILE - - BiO_ctrl(b64,BIO_CTRL_FLUSH,0,NIL) - - strlen:=BiO_ctrl(mem,BIO_CTRL_INFO,0,{outstr}) - - StrCopy(output,outstr,strlen) - BiO_free(mem) - BiO_free(b64) - -ENDPROC - -/* Open and initialize AmiSSL */ -PROC initssl(createctx) HANDLE - DEF tags - - IF socketbase=NIL THEN socketbase:=OpenLibrary('bsdsocket.library', 4) - IF (socketbase=NIL) - WriteF('Couldn''t open bsdsocket.library v4!\n') - Raise(ERR_SSL) - ENDIF - - amisslmasterbase:=OpenLibrary('amisslmaster.library',AMISSLMASTER_MIN_VERSION) - IF (amisslmasterbase=NIL) - WriteF('Couldn''t open amisslmaster.library v\d!\n',AMISSLMASTER_MIN_VERSION); - Raise(ERR_SSL) - ENDIF - - IF (InitAmiSSLMaster(AMISSL_CURRENT_VERSION, TRUE))=NIL - WriteF('AmiSSL version is too old!\n'); - Raise(ERR_SSL) - ENDIF - - amisslbase:=OpenAmiSSL() - IF (amisslbase=NIL) - WriteF('Couldn''t open AmiSSL!\n'); - Raise(ERR_SSL) - ENDIF - - tags:=NEW [amiSSL_ErrNoPtr,{sslerrno},amiSSL_SocketBase,socketbase,0] - IF (InitAmiSSLA(tags) <> 0) - END tags - WriteF('Couldn''t initialize AmiSSL!\n'); - Raise(ERR_SSL) - ENDIF - END tags - - /* Basic intialization. Next few steps (up to SSL_new()) need - * to be done only once per AmiSSL opener. - */ - - OpENSSL_init_ssl(0,NIL) ->SSLeay_add_ssl_algorithms(); -$67C8(a6) - OpENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS OR OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NIL) ->SSL_load_error_strings(); - - /* Note: BIO writing routines are prepared for NULL BIO handle */ - IF((bio_err:=BiO_new(BiO_s_file())) <> NIL) THEN BiO_ctrl(bio_err, BIO_SET_FILE_PTR, BIO_NOCLOSE OR BIO_FP_TEXT, Output()); ->BiO_set_fp_amiga(bio_err, Output(), BIO_NOCLOSE OR BIO_FP_TEXT); - - /* Get a new SSL context */ - IF (createctx) - ctx:=SsL_CTX_new(TlS_client_method()) - IF (ctx=0) - WriteF('Couldn''t create ssl ctx!\n'); - Raise(ERR_SSL) - ENDIF - SsL_CTX_set_default_verify_paths(ctx); - SsL_CTX_set_verify(ctx, SSL_VERIFY_PEER OR SSL_VERIFY_FAIL_IF_NO_PEER_CERT,NIL); - ENDIF -EXCEPT - cleanupssl() - RETURN FALSE -ENDPROC TRUE - -PROC cleanupssl() - IF ctx<>NIL - SsL_CTX_free(ctx); - ctx:=NIL - ENDIF - - IF bio_err<>NIL - BiO_free(bio_err) - bio_err:=NIL - ENDIF - - IF (amisslbase) - CleanupAmiSSLA([0]); - CloseAmiSSL(); - amisslbase:=NIL - ENDIF - - CloseLibrary(amisslmasterbase); - amisslmasterbase:=NIL; - - IF socketbase<>NIL THEN CloseLibrary(socketbase) - socketbase:=NIL; -ENDPROC - -/* Connect to the specified server, either directly or through the specified - * proxy using HTTP CONNECT method. - */ - -PROC connectToServer(host:PTR TO CHAR, port) - DEF addr: PTR TO sockaddr_in - DEF is_ok = FALSE; - DEF sock=NIL; - DEF hostEnt: PTR TO hostent - DEF hostaddr: PTR TO LONG - - /* Create a socket and connect to the server */ - IF ((sock:=Socket(AF_INET, SOCK_STREAM, 0)) >= 0) - - hostEnt:=GetHostByName(host) - hostaddr:=hostEnt.h_addr_list[] - hostaddr:=hostaddr[] - - NEW addr - addr.sin_family:=AF_INET; - addr.sin_addr:=hostaddr[]; /* This should be checked against INADDR_NONE */ - addr.sin_port:=port->htons(port); - - IF (Connect(sock, addr, SIZEOF sockaddr_in) >= 0) - is_ok:=TRUE - ELSE - WriteF('Couldn''t connect to server\n'); - ENDIF - END addr - IF (is_ok=FALSE) - CloseSocket(sock); - sock:=-1; - ENDIF - ENDIF - -ENDPROC sock - PROC checkOnlineStatus() DEF stat @@ -1517,7 +513,7 @@ PROC modemOffHook() IF serShared=FALSE serShared:=TRUE IF(sopt.toggles[TOGGLES_SERIALRESET]) - resetSystem(0) + resetSystem() intDoReset(sopt.offHook) ioFlags[IOFLAG_SER_IN]:=0 ioFlags[IOFLAG_SER_OUT]:=0 @@ -1538,8 +534,7 @@ PROC modemOffHook() ENDPROC PROC updateTimeUsed() - DEF currDay,logonDay,currTime,time - DEF tempstr[255]:STRING + DEF currDay,logonDay,currTime currTime:=getSystemTime() currDay:=Div(currTime-21600,86400) logonDay:=Div(logonTime-21600,86400) @@ -1551,18 +546,16 @@ PROC updateTimeUsed() timeLimit:=loggedOnUser.timeTotal-loggedOnUser.timeUsed logonTime:=Mul(currDay,86400)+21600 - StringF(tempstr,'timeused debug: new day reset, currday \d, logonday \d, new logontime \d',currDay,logonDay,logonTime) - debugLog(LOG_WARN,tempstr) lastTimeUpdate:=logonTime ENDIF IF (currTime-lastTimeUpdate)>0 IF(chatFlag=0) - StringF(tempstr,'timeused debug: timeused \d, increment \d, currtime: \d, lasttime: \d',loggedOnUser.timeUsed,currTime-lastTimeUpdate,currTime,lastTimeUpdate) - debugLog(LOG_WARN,tempstr) loggedOnUser.timeUsed:=loggedOnUser.timeUsed+(currTime-lastTimeUpdate) timeLimit:=timeLimit-(currTime-lastTimeUpdate) ELSE - loggedOnUser.chatRemain:=loggedOnUser.chatRemain-(currTime-lastTimeUpdate) + IF loggedOnUser.chatLimit>0 + loggedOnUser.chatRemain:=loggedOnUser.chatRemain-(currTime-lastTimeUpdate) + ENDIF ENDIF lastTimeUpdate:=currTime ENDIF @@ -1582,7 +575,7 @@ PROC updateTimeUsed() ENDIF ENDPROC -PROC checkMailConfScan(conf) +PROC checkMailConfScan(conf,msgBase) DEF cb: PTR TO confBase DEF res=TRUE @@ -1592,7 +585,7 @@ PROC checkMailConfScan(conf) RETURN FALSE ENDIF - cb:=confBases.item(conf-1) + cb:=confBases.item(getConfIndex(conf,msgBase)) IF cb<>NIL IF (cb.handle[0] AND MAIL_SCAN_MASK)<>0 THEN res:=TRUE ELSE res:=FALSE @@ -1611,7 +604,7 @@ PROC checkFileConfScan(conf) RETURN FALSE ENDIF - cb:=confBases.item(conf-1) + cb:=confBases.item(getConfIndex(conf,1)) IF cb<>NIL IF (cb.handle[0] AND FILE_SCAN_MASK)<>0 THEN res:=TRUE ELSE res:=FALSE @@ -1669,7 +662,7 @@ PROC setNRAMS() n++ StringF(nramName,'NRAM.\d',n) UNTIL readToolType(TOOLTYPE_NRAMS,node,nramName,nramData)=FALSE - resetSystem(0); + resetSystem() setEnvStat(ENV_AWAITCONNECT) ELSE setEnvMsg('NO NRAM.DEF') @@ -1745,7 +738,7 @@ retry: ->SerCharSig=1L<mp_SigBit - queueRead(serialReadIO,{serbuff}) + queueSerialRead({serbuff}) RETURN FALSE ENDIF ELSE @@ -1855,7 +848,7 @@ PROC rePurge() ENDWHILE ENDPROC -PROC resetSystem(yes) +PROC resetSystem() DEF tempStr[255]:STRING DEF ni:PTR TO nodeInfo @@ -1925,7 +918,7 @@ PROC checkDoorMsg(mode) DEF ch,cmd DEF type,temp,exit DEF servermsg: PTR TO jhMessage - DEF len,i + DEF i DEF subState: loggedOnState DEF debugstr[255]:STRING DEF tempstring[255]:STRING @@ -2203,7 +1196,7 @@ PROC checkDoorMsg(mode) ENDIF CASE BB_CONFNAME IF (servermsg.data) - StringF(tempstring,'\s',currentConfName) + StrCopy(tempstring,currentConfName) strCpy(servermsg.string,tempstring,80) ELSE StrCopy(currentConfName,servermsg.string) @@ -2211,13 +1204,13 @@ PROC checkDoorMsg(mode) ENDIF CASE BB_CONFLOCAL IF (servermsg.data) - StringF(tempstring,'\s',currentConfDir) + StrCopy(tempstring,currentConfDir) strCpy(servermsg.string,tempstring,80) ELSE setConfLocation(loggedOnUser.confRJoin-1,servermsg.string) ENDIF CASE BB_LOCAL - StringF(tempstring,'\s',cmds.bbsLoc) + StrCopy(tempstring,cmds.bbsLoc) strCpy(servermsg.string,tempstring,80) CASE BB_STATUS @@ -2230,7 +1223,7 @@ PROC checkDoorMsg(mode) serverin:=servermsg.string[0] returnval:=TRUE CASE BB_MAINLINE - StringF(tempstring,'\s',commandText) + StrCopy(tempstring,commandText) strCpy(servermsg.string,tempstring,80) CASE BB_TASKPRI StringF(tempstring,'\c',cmds.taskPri) @@ -2240,9 +1233,9 @@ PROC checkDoorMsg(mode) strCpy(servermsg.string,tempstring,80) CASE BB_CHATFLAG IF sysopAvail - strCpy(servermsg.string,'YES',ALL) + strCpy(servermsg.string,'ON',ALL) ELSE - strCpy(servermsg.string,'NO',ALL) + strCpy(servermsg.string,'OFF',ALL) ENDIF CASE EXPRESS_VERSION getExpressMajorVer(tempstring) @@ -2329,18 +1322,16 @@ PROC checkDoorMsg(mode) CASE SAVE_ACCOUNT doorMsgSaveAccount(servermsg) CASE SAVE_CONFDB - saveConfDB(servermsg.data,servermsg.nodeID,servermsg.filler1) - IF(loggedOnUser.slotNumber=servermsg.data) THEN loadMsgPointers(currentConf) + saveConfDB(servermsg.data,servermsg.nodeID,1,servermsg.filler1) + IF(loggedOnUser.slotNumber=servermsg.data) THEN loadMsgPointers(currentConf,1) CASE LOAD_CONFDB - loadConfDB(servermsg.data,servermsg.nodeID,servermsg.filler1) + loadConfDB(servermsg.data,servermsg.nodeID,1,servermsg.filler1) CASE CANCEL_TRANSFER_OFFHOOK cancelTransferOffHook:=TRUE CASE CLEAR_OLM_QUEUE processOlmMessageQueue(FALSE) CASE INCOMING_TELNET - debugLog(LOG_DEBUG,'incoming telnet') IF (telnetSocket=-1) AND (offHookFlag=FALSE) - debugLog(LOG_DEBUG,'incoming telnet - process') telnetSocket:=ObtainSocket(servermsg.data,PF_INET,SOCK_STREAM,IPPROTO_TCP) IF checkCarrier()=FALSE @@ -2358,7 +1349,6 @@ PROC checkDoorMsg(mode) ReleaseSemaphore(masterNode) ENDIF ELSE - debugLog(LOG_DEBUG,'incoming telnet - donot process') i:=ObtainSocket(servermsg.data,PF_INET,SOCK_STREAM,IPPROTO_TCP) CloseSocket(i) ENDIF @@ -2385,7 +1375,9 @@ PROC getPass2(prompt: PTR TO CHAR,password:PTR TO CHAR,pwdhash:LONG, max:LONG,ou DEF tempstr[255]:STRING i:=1 - IF (password<>NIL) AND (StrLen(password)=0) THEN RETURN RESULT_FAILURE + IF (password<>NIL) + IF (StrLen(password)=0) THEN RETURN RESULT_FAILURE + ENDIF WHILE i aePuts(prompt) @@ -2441,252 +1433,6 @@ PROC getPass2(prompt: PTR TO CHAR,password:PTR TO CHAR,pwdhash:LONG, max:LONG,ou aePuts('\b\n') ENDPROC RESULT_NOT_ALLOWED -PROC asmputchar() - MOVE.B D0,(A3)+ -ENDPROC - -PROC formatSpaceValue(spaceInKB,outstr) - DEF frac,whole - IF (spaceInKB<10240) - StringF(outstr,'\d KB',spaceInKB) - ELSEIF(spaceInKB<1048576) - frac:=Shr(Mul((spaceInKB AND 1023),10),10) - whole:=Shr(spaceInKB,10) - StringF(outstr,'\d.\d MB',whole,frac) - ELSE - spaceInKB:=Shr(spaceInKB,10) - frac:=Shr(Mul((spaceInKB AND 1023),10),10) - whole:=Shr(spaceInKB,10) - StringF(outstr,'\d.\d GB',whole,frac) - ENDIF -ENDPROC - -PROC formatUnsignedLong(val,outStr) - DEF outputTxt - - outputTxt:=NEW [0,0,0,0,0,0,0,0,0,0]:CHAR - RawDoFmt('%lu',{val},{asmputchar},outputTxt) - StrCopy(outStr,outputTxt) - END outputTxt -ENDPROC - -PROC formatBCD(valArrayBCD:PTR TO CHAR, outStr) - DEF tempStr[2]:STRING - DEF i,n,start=FALSE - - StrCopy(outStr,'') - FOR i:=0 TO 7 - n:=valArrayBCD[i] - IF (n<>0) OR (start) OR (i=7) - IF (start) OR (n>=$10) - StringF(tempStr,'\d\d',Shr(n AND $F0,4),n AND $F) - ELSE - StringF(tempStr,'\d',n AND $F) - ENDIF - StrAdd(outStr,tempStr) - start:=TRUE - ENDIF - ENDFOR -ENDPROC - -PROC formatLongDate(cDateVal,outDateStr) - DEF d : PTR TO datestamp - DEF dt : datetime - DEF datestr[10]:STRING - DEF r,dateVal - - dateVal:=cDateVal-21600 - - d:=dt.stamp - d.tick:=(dateVal-Mul(Div(dateVal,60),60)) - d.tick:=Mul(d.tick,50) - dateVal:=Div(dateVal,60) - d.days:=Div((dateVal),1440)-2922 ->-2922 days between 1/1/70 and 1/1/78 - d.minute:=dateVal-(Mul(d.days+2922,1440)) - - dt.format:=FORMAT_USA - dt.flags:=0 - dt.strday:=0 - dt.strdate:=datestr - dt.strtime:=0 - - IF DateToStr(dt) - StringF(outDateStr,'\s',datestr) - RETURN TRUE - ENDIF -ENDPROC FALSE - -PROC formatLongTime(cDateVal,outDateStr) - DEF d : PTR TO datestamp - DEF dt : datetime - DEF time[10]:STRING - DEF r,dateVal - - dateVal:=cDateVal-21600 - - d:=dt.stamp - d.tick:=(dateVal-Mul(Div(dateVal,60),60)) - d.tick:=Mul(d.tick,50) - dateVal:=Div(dateVal,60) - d.days:=Div((dateVal),1440)-2922 ->-2922 days between 1/1/70 and 1/1/78 - d.minute:=dateVal-(Mul(d.days+2922,1440)) - - dt.format:=FORMAT_USA - dt.flags:=0 - dt.strday:=0 - dt.strdate:=0 - dt.strtime:=time - - IF DateToStr(dt) - StringF(outDateStr,'\s',time) - RETURN TRUE - ENDIF -ENDPROC FALSE - -PROC formatLongDateTime(cDateVal,outDateStr) - DEF d : PTR TO datestamp - DEF dt : datetime - DEF datestr[10]:STRING - DEF daystr[10]:STRING - DEF timestr[10]:STRING - DEF r,dateVal - - dateVal:=cDateVal-21600 - - d:=dt.stamp - d.tick:=(dateVal-Mul(Div(dateVal,60),60)) - d.tick:=Mul(d.tick,50) - dateVal:=Div(dateVal,60) - d.days:=Div((dateVal),1440)-2922 ->-2922 days between 1/1/70 and 1/1/78 - d.minute:=dateVal-(Mul(d.days+2922,1440)) - - dt.format:=FORMAT_DOS - dt.flags:=0 - dt.strday:=daystr - dt.strdate:=datestr - dt.strtime:=timestr - - IF DateToStr(dt) - StringF(outDateStr,'\s[3] \s \s',daystr,datestr,timestr) - RETURN TRUE - ENDIF -ENDPROC FALSE - -PROC formatLongDateTime2(cDateVal,outDateStr) - DEF d : PTR TO datestamp - DEF dt : datetime - DEF datestr[10]:STRING - DEF timestr[10]:STRING - DEF r,dateVal - - dateVal:=cDateVal-21600 - - d:=dt.stamp - d.tick:=(dateVal-Mul(Div(dateVal,60),60)) - d.tick:=Mul(d.tick,50) - dateVal:=Div(dateVal,60) - d.days:=Div((dateVal),1440)-2922 ->-2922 days between 1/1/70 and 1/1/78 - d.minute:=dateVal-(Mul(d.days+2922,1440)) - - dt.format:=FORMAT_USA - dt.flags:=0 - dt.strday:=0 - dt.strdate:=datestr - dt.strtime:=timestr - - IF DateToStr(dt) - StringF(outDateStr,'\s,\s',datestr,timestr) - RETURN TRUE - ENDIF -ENDPROC FALSE - -->returns a numeric value of the date suitable for comparing to other dates -PROC getDateCompareVal(datestr:PTR TO CHAR) - DEF month,day,year - - month:=Val(datestr) - day:=Val(datestr+3) - year:=Val(datestr+6) - - IF (year>TWODIGITYEARSWITCHOVER) THEN year:=1900+year ELSE year:=2000+year - -ENDPROC Mul(year,10000)+Mul(month,100)+day - -PROC isupper(c) -ENDPROC (c>="A") AND (c<="Z") - -->returns system date converted to c time format -PROC getSystemDate() - DEF currDate: datestamp - DEF startds:PTR TO datestamp - DEF s1,s2,s3,s4 - - startds:=DateStamp(currDate) - - s1:=startds.days+2922 - s1:=Mul(1440,s1) - s1:=Mul(60,s1) - s2:=Mul(60,startds.minute) - s3:=startds.tick/50 - s4:=Mul(Mul(startds.days+2922,1440),60)+(startds.minute*60)+(startds.tick/50) - - s4:=s4+21600 - - s4:=Mul(Div(s4,86400),86400) - ->2922 days between 1/1/70 and 1/1/78 - -ENDPROC s4 - -->returns system time converted to c time format -PROC getSystemTime() - DEF currDate: datestamp - DEF startds:PTR TO datestamp - DEF s1,s2,s3,s4 - - startds:=DateStamp(currDate) - - s1:=startds.days+2922 - s1:=Mul(1440,s1) - s1:=Mul(60,s1) - s2:=Mul(60,startds.minute) - s3:=startds.tick/50 - s4:=Mul(Mul(startds.days+2922,1440),60)+(startds.minute*60)+(startds.tick/50) - - ->2922 days between 1/1/70 and 1/1/78 - -ENDPROC s4+21600 - -->returns system time converted to c time format and ticks -PROC getSystemTime2() - DEF currDate: datestamp - DEF startds:PTR TO datestamp - DEF s1,s2,s3,s4 - - startds:=DateStamp(currDate) - - s1:=startds.days+2922 - s1:=Mul(1440,s1) - s1:=Mul(60,s1) - s2:=Mul(60,startds.minute) - s3:=startds.tick/50 - s4:=Mul(Mul(startds.days+2922,1440),60)+(startds.minute*60)+(startds.tick/50) - - ->2922 days between 1/1/70 and 1/1/78 - -ENDPROC s4+21600,Mod(startds.tick,50) - -PROC fileWriteLn(fh,str: PTR TO CHAR) - DEF stat - IF (stat:=fileWrite(fh,str))<>RESULT_SUCCESS THEN RETURN stat -ENDPROC fileWrite(fh,'\n') - -PROC fileWrite(fh,str: PTR TO CHAR) - DEF s - - s:=Write(fh,str,StrLen(str)) - IF s<>StrLen(str) THEN RETURN RESULT_FAILURE -ENDPROC RESULT_SUCCESS - PROC stripAnsi(s: PTR TO CHAR, d: PTR TO CHAR, resetit, strip) DEF i,j,k,p,c IF resetit @@ -2751,59 +1497,26 @@ PROC stripAnsi(s: PTR TO CHAR, d: PTR TO CHAR, resetit, strip) SetStr(d,StrLen(d)) ENDPROC -PROC strCpy(dest: PTR TO CHAR, source: PTR TO CHAR, len) - DEF c,endfound=FALSE - DEF i - IF len=ALL - AstrCopy(dest,source,ALL) - ELSE - FOR i:=0 TO len-1 - c:=source[i] - IF (c=0) OR (i=(len-1)) THEN endfound:=TRUE - IF endfound THEN c:=0 - dest[i]:=c - ENDFOR - ENDIF -ENDPROC - -PROC strAddChar(dest,source) - StrAdd(dest,' ') - dest[EstrLen(dest)-1]:=source -ENDPROC - -PROC aePutChar(c) - DEF str[1]:STRING - StrCopy(str,' ') - str[0]:=c - aePuts(str) -ENDPROC - -PROC countSpaces(str:PTR TO CHAR) - DEF i,count=0 - - FOR i:=0 TO StrLen(str)-1 - IF str[i]=" " - count++ - ENDIF - ENDFOR -ENDPROC count - PROC aePuts(string,force=FALSE) aePuts2(string,-1,force) ENDPROC -PROC asl(s: PTR TO CHAR) HANDLE +PROC asl(s: PTR TO CHAR,slines=NIL:PTR TO stringlist) HANDLE DEF fr:PTR TO filerequester DEF src[100]:STRING,tags=NIL + DEF flags,x + DEF frargs: PTR TO wbarg IF KickVersion(37)=FALSE THEN Raise(ERR_KICKVER) -> E-Note: requires V37 aslbase:=OpenLibrary('asl.library',37) IF aslbase=NIL THEN Raise(ERR_LIB) + flags:=FILF_PATGAD + IF slines<>NIL THEN flags:=flags OR FILF_MULTISELECT tags:=NEW [ASL_HAIL,'/X FileRequest', ASLFR_SCREEN,screen, ASL_PATTERN,'#?', - ASL_FUNCFLAGS, FILF_MULTISELECT OR FILF_PATGAD, + ASL_FUNCFLAGS, flags, ASL_DIR,cmds.bbsLoc, NIL] @@ -2811,13 +1524,21 @@ PROC asl(s: PTR TO CHAR) HANDLE IF(AslRequest(fr,0)) - StrCopy(src,fr.drawer) - IF(src[StrLen(src)-1]<>":") - StringF(src,'\s/\s',fr.drawer,fr.file) + IF(fr.numargs) + frargs:=fr.arglist + + FOR x:=0 TO fr.numargs-1 + StrCopy(src,fr.drawer) + AddPart(src,frargs[x].name,100) + IF s<>NIL THEN StrCopy(s,src) + IF slines<>NIL THEN slines.add(src) + ENDFOR ELSE - StringF(src,'\s\s',fr.drawer,fr.file) + StrCopy(src,fr.drawer) + AddPart(src,frargs[x].name,100) + IF s<>NIL THEN StrCopy(s,src) + IF slines<>NIL THEN slines.add(src) ENDIF - StrCopy(s,src) ENDIF EXCEPT DO IF fr THEN FreeAslRequest(fr) @@ -2833,13 +1554,19 @@ EXCEPT DO ENDSELECT ENDPROC -PROC fAEPutStr(string) - aePuts(string) -ENDPROC - PROC aePuts2(string,length,force=FALSE) DEF str[1023]:STRING DEF str2[1023]:STRING + DEF cls[1]:STRING + DEF p + + StrCopy(cls,'#') + cls[0]:=12 + IF length=-1 + IF InStr(string,cls)>=0 THEN lineCount:=0 + ELSE + IF ((p:=InStr(string,cls))>=0) AND (p0) OR (ansiColour=FALSE) OR (bitPlanes<3)) IF length<>-1 THEN StrCopy(str,string,length) ELSE StrCopy(str,string) @@ -2893,7 +1620,6 @@ ENDPROC PROC telnetSend(string:PTR TO CHAR, putlen) DEF i,c,e,maxBlkSize,tot,offs,n,telsendDelay DEF buf2 - DEF debugstr[255]:STRING c:=0 FOR i:=0 TO putlen-1 @@ -2941,8 +1667,9 @@ PROC telnetSend(string:PTR TO CHAR, putlen) ENDPROC PROC serPuts(string: PTR TO CHAR, putlen=-1,binary=FALSE, force=FALSE) - DEF error,actlen,serFlushTime + DEF actlen,serFlushTime DEF tempTime1,tempTime2 + IF (serialWriteIO<>NIL) OR (telnetSocket>=0) IF (transfering=FALSE) OR (force) @@ -2954,35 +1681,20 @@ PROC serPuts(string: PTR TO CHAR, putlen=-1,binary=FALSE, force=FALSE) serFlushTime:=Mul(tempTime1-serialCacheLastFlush1,50)+tempTime2-serialCacheLastFlush2 ENDIF - IF binary OR (serialCacheEnabled=FALSE) OR (serFlushTime>10) OR (serialCache=NIL) - flushSerialCache() - IF telnetSocket>=0 - IF binary AND (putlen=-1) - debugLog(LOG_ERROR,'unsized binary write') - ENDIF - - IF putlen=-1 THEN putlen:=StrLen(string) - telnetSend(string,putlen) - ELSE - serialWriteIO.iostd.command:=CMD_WRITE - serialWriteIO.iostd.data:=string - serialWriteIO.iostd.length:=putlen -> use -1 for print until terminating NIL - error:=DoIO(serialWriteIO) + IF binary OR (serialCacheEnabled=FALSE) OR (serFlushTime>10) OR (serialCache=NIL) OR (slowmo) + flushSerialCache() + IF binary AND (putlen=-1) + debugLog(LOG_ERROR,'unsized binary write') ENDIF + + IF slowmo THEN slowmoSerPuts2(string,putlen) ELSE serPuts2(string,putlen) ->IF error THEN debugLog(LOG_ERROR,'serial write error: \d',error) ELSE actlen:=StrLen(string) IF (putlen=-1) OR (actlenserialCacheSize) THEN flushSerialCache() IF (putlen>=serialCacheSize) - IF telnetSocket>=0 - telnetSend(string,putlen) - ELSE - serialWriteIO.iostd.command:=CMD_WRITE - serialWriteIO.iostd.data:=string - serialWriteIO.iostd.length:=putlen -> use -1 for print until terminating NIL - error:=DoIO(serialWriteIO) - ENDIF + serPuts2(string,putlen) ELSE cacheSerialData(string,putlen) ENDIF @@ -2991,6 +1703,47 @@ PROC serPuts(string: PTR TO CHAR, putlen=-1,binary=FALSE, force=FALSE) ENDIF ENDPROC +PROC slowmoSerPuts2(string: PTR TO CHAR, putlen) + DEF l,p,signals,timersig + + IF putlen=-1 THEN putlen:=StrLen(string) + p:=0 + l:=60*(slowmo) + openTimer() + WHILE pputlen THEN l:=putlen-p + + serPuts2(string+p,l) + slowmoCount:=slowmoCount-l + IF slowmoCount<=0 + setTimer(0,10000) + IF timerport<>NIL THEN timersig:=Shl(1, timerport.sigbit) + signals:=Wait(SIGBREAKF_CTRL_C OR timersig) + IF (signals AND timersig)=0 + stopTime() + ELSE + waitTime() + ENDIF + slowmoCount:=slowmoCount+(60*slowmo) + ENDIF + p:=p+l + ENDWHILE + closeTimer() +ENDPROC + +PROC serPuts2(string: PTR TO CHAR, putlen) + IF telnetSocket>=0 + IF putlen=-1 THEN putlen:=StrLen(string) + + telnetSend(string,putlen) + ELSE + serialWriteIO.iostd.command:=CMD_WRITE + serialWriteIO.iostd.data:=string + serialWriteIO.iostd.length:=putlen -> use -1 for print until terminating NIL + DoIO(serialWriteIO) + ENDIF +ENDPROC + PROC conPutChar(c) DEF str[1]:STRING StrCopy(str,' ') @@ -3045,7 +1798,7 @@ PROC purgeLineStart() IF serialReadIO<>NIL AND (transfering=FALSE) serialReadIO.iostd.command:=CMD_CLEAR DoIO(serialReadIO); - queueRead(serialReadIO,{serbuff}) + queueSerialRead({serbuff}) ENDIF ENDPROC @@ -3055,7 +1808,7 @@ PROC purgeLine() WaitIO(serialReadIO) serialReadIO.iostd.command:=CMD_CLEAR DoIO(serialReadIO) - queueRead(serialReadIO,{serbuff}) + queueSerialRead({serbuff}) ENDIF ENDPROC @@ -3075,7 +1828,7 @@ PROC checkCarrier() ELSE stat:=0 ENDIF - ELSEIF(serialReadIO<>NIL) + ELSEIF(serialWriteIO<>NIL) serialWriteIO.iostd.command:=SDCMD_QUERY stat2:=DoIO(serialWriteIO) stat:=serialWriteIO.status AND CIAF_COMCD @@ -3102,8 +1855,11 @@ PROC checkCarrier() ENDPROC PROC checkInput() - checkIconifyMsg() checkDoorMsg(0) + IF servercmd=SV_UNICONIFY + servercmd:=-1 + IF scropen THEN expressToFront() ELSE openExpressScreen() + ENDIF ENDPROC ((checkCon() OR checkSer() OR checkTelnetData())) PROC checkScreenClear() @@ -3121,6 +1877,60 @@ PROC sCheckInput() IF(telnetSocket>=0) AND (ioFlags[IOFLAG_SER_IN]) THEN result3:=checkTelnetData() ENDPROC result1 OR result2 OR result3 +PROC countMsgBases() + DEF count=0 + DEF num,i + + FOR i:=1 TO cmds.numConf + num:=getConfMsgBaseCount(i) + count:=count+num + ENDFOR +ENDPROC count + +PROC getConfIndex(confNum,msgBaseNum) + DEF index=0 + DEF num=1,i + FOR i:=1 TO confNum-1 + num:=getConfMsgBaseCount(i) + index:=index+num + ENDFOR + index:=index+msgBaseNum-1 +ENDPROC index + +PROC getConfMsgBaseCount(confNum) + DEF num + num:=readToolTypeInt(TOOLTYPE_MSGBASE,confNum,'NMSGBASES') + IF num=-1 THEN num:=1 +ENDPROC num + +PROC getMsgBaseName(confNum,msgBaseNum,outMsgBaseNameString) + DEF tempStr[255]:STRING + StringF(tempStr,'NAME.\d',msgBaseNum) + StrCopy(outMsgBaseNameString,'') + readToolType(TOOLTYPE_MSGBASE,confNum,tempStr,outMsgBaseNameString) +ENDPROC + +PROC getMsgBaseLocation(confNum,msgBaseNum,outMsgBaseLocationString) + DEF toolTypeName[100]:STRING + DEF location[255]:STRING + DEF num + + num:=readToolTypeInt(TOOLTYPE_MSGBASE,confNum,'NMSGBASES') + IF (msgBaseNum>num) OR (msgBaseNum<1) OR (num=-1) + StringF(outMsgBaseLocationString,'\sMsgBase/',getConfLocation(confNum)) + RETURN + ENDIF + StringF(toolTypeName,'LOCATION.\d',msgBaseNum) + readToolType(TOOLTYPE_MSGBASE,confNum,toolTypeName,location) + + ->if the location has a colon then we presume its a full path, otherwise we assume its relative to the conf location + IF (InStr(location,':')>=0) + StrCopy(outMsgBaseLocationString,location) + ELSE + StringF(outMsgBaseLocationString,'\s\s',getConfLocation(confNum),location) + ENDIF +ENDPROC + PROC getConfLocation(confNum,outConfLocationString=NIL) IF outConfLocationString<>NIL THEN StrCopy(outConfLocationString,confDirs.item(confNum-1)) ENDPROC confDirs.item(confNum-1) @@ -3135,15 +1945,18 @@ PROC setConfLocation(confNum,newconfLocation) ENDIF ENDPROC -PROC getConfDbFileName(confNum,outConfDbFile) +PROC getConfDbFileName(confNum,msgBaseNum,outConfDbFile) DEF cn cn:=readToolTypeInt(TOOLTYPE_CONF,confNum,'CONFDB_SHARED') IF cn<>-1 THEN confNum:=cn - getConfLocation(confNum,outConfDbFile) + IF getConfMsgBaseCount(confNum)>1 + getMsgBaseLocation(confNum,msgBaseNum,outConfDbFile) + ELSE + getConfLocation(confNum,outConfDbFile) + ENDIF StrAdd(outConfDbFile,confDBName) ENDPROC - PROC getConfName(confNum,outConfNameString=NIL) IF outConfNameString<>NIL THEN StrCopy(outConfNameString,confNames.item(confNum-1)) ENDPROC confNames.item(confNum-1) @@ -3189,7 +2002,6 @@ PROC yesNo(flag) ENDPROC PROC addToHistory(text) - DEF msg IF historyBuf.count()<20 historyNum:=historyBuf.add(text) historyCycle:=historyNum @@ -3201,7 +2013,7 @@ PROC addToHistory(text) ENDIF ENDPROC -PROC lineInput(promptText,defaultOutput,maxLen,timeout,outputString,addToHistoryFlag=TRUE) +PROC lineInput(promptText,defaultOutput,maxLen,timeout,outputString,allowHistory=TRUE) DEF result DEF wasControl,ch DEF cmdCharString[1]:STRING @@ -3258,7 +2070,7 @@ redoinput: IF timedout=FALSE warning:=FALSE timeout:=originalTimeout - IF (ch=2) AND (wasControl=0) -> CTRL B + IF (allowHistory) AND (ch=2) AND (wasControl=0) -> CTRL B historyBuf.clear() historyNum:=0 historyCycle:=0 @@ -3281,7 +2093,7 @@ redoinput: ENDIF IF (rawArrow=FALSE) - IF (ch=UPARROW) AND (historyBuf.count()>0) + IF (allowHistory) AND (ch=UPARROW) AND (historyBuf.count()>0) StrCopy(tempstr,'') FOR i:=curpos TO StrLen(outputString)-1 StrAdd(tempstr,'') @@ -3298,7 +2110,7 @@ redoinput: aePuts(outputString) curpos:=StrLen(outputString) ENDIF - IF (ch=DOWNARROW) AND (historyBuf.count()>0) + IF (allowHistory) AND (ch=DOWNARROW) AND (historyBuf.count()>0) StrCopy(tempstr,'') FOR i:=curpos TO StrLen(outputString)-1 StrAdd(tempstr,'') @@ -3382,7 +2194,7 @@ redoinput: conPuts('[0 p'); /* turn console cursor off */ IF ch=13 THEN result:=RESULT_SUCCESS - IF (result=RESULT_SUCCESS) AND (StrLen(outputString)>0) AND (addToHistoryFlag) + IF (result=RESULT_SUCCESS) AND (StrLen(outputString)>0) AND (allowHistory) addToHistory(outputString) ENDIF @@ -3439,127 +2251,30 @@ PROC readMayGetChar(msgport, checkTelnet, whereto) ELSE IF NIL=(readreq:=GetMsg(msgport)) THEN RETURN -1 temp:=whereto[] -> Get the character... - queueRead(readreq, whereto) -> ...then re-use the request block + IF checkTelnet THEN queueSerialRead(whereto) ELSE queueConsoleRead(whereto) -> ...then re-use the request block ENDIF ENDPROC temp -> Queue up a read request to console, passing it pointer to a buffer into -> which it can read the character -PROC queueRead(readreq:PTR TO iostd, whereto,bsize=1) - IF readreq=NIL THEN RETURN - readreq.command:=CMD_READ - readreq.data:=whereto - readreq.length:=bsize - SendIO(readreq) -ENDPROC - -PROC calcPasswordHash(pwd: PTR TO CHAR) - DEF hash - DEF hashdata - - hashdata:=NEW[$0000,$0000,$7707,$3096,$EE0E,$612C,$9909,$51BA,$076D,$C419,$706A,$F48F,$E963,$A535,$9E64,$95A3,$0EDB,$8832,$79DC,$B8A4,$E0D5,$E91E, - $97D2,$D988,$09B6,$4C2B,$7EB1,$7CBD,$E7B8,$2D07,$90BF,$1D91,$1DB7,$1064,$6AB0,$20F2,$F3B9,$7148,$84BE,$41DE,$1ADA,$D47D,$6DDD,$E4EB, - $F4D4,$B551,$83D3,$85C7,$136C,$9856,$646B,$A8C0,$FD62,$F97A,$8A65,$C9EC,$1401,$5C4F,$6306,$6CD9,$FA0F,$3D63,$8D08,$0DF5,$3B6E,$20C8, - $4C69,$105E,$D560,$41E4,$A267,$7172,$3C03,$E4D1,$4B04,$D447,$D20D,$85FD,$A50A,$B56B,$35B5,$A8FA,$42B2,$986C,$DBBB,$C9D6,$ACBC,$F940, - $32D8,$6CE3,$45DF,$5C75,$DCD6,$0DCF,$ABD1,$3D59,$26D9,$30AC,$51DE,$003A,$C8D7,$5180,$BFD0,$6116,$21B4,$F4B5,$56B3,$C423,$CFBA,$9599, - $B8BD,$A50F,$2802,$B89E,$5F05,$8808,$C60C,$D9B2,$B10B,$E924,$2F6F,$7C87,$5868,$4C11,$C161,$1DAB,$B666,$2D3D,$76DC,$4190,$01DB,$7106, - $98D2,$20BC,$EFD5,$102A,$71B1,$8589,$06B6,$B51F,$9FBF,$E4A5,$E8B8,$D433,$7807,$C9A2,$0F00,$F934,$9609,$A88E,$E10E,$9818,$7F6A,$0DBB, - $086D,$3D2D,$9164,$6C97,$E663,$5C01,$6B6B,$51F4,$1C6C,$6162,$8565,$30D8,$F262,$004E,$6C06,$95ED,$1B01,$A57B,$8208,$F4C1,$F50F,$C457, - $65B0,$D9C6,$12B7,$E950,$8BBE,$B8EA,$FCB9,$887C,$62DD,$1DDF,$15DA,$2D49,$8CD3,$7CF3,$FBD4,$4C65,$4DB2,$6158,$3AB5,$51CE,$A3BC,$0074, - $D4BB,$30E2,$4ADF,$A541,$3DD8,$95D7,$A4D1,$C46D,$D3D6,$F4FB,$4369,$E96A,$346E,$D9FC,$AD67,$8846,$DA60,$B8D0,$4404,$2D73,$3303,$1DE5, - $AA0A,$4C5F,$DD0D,$7CC9,$5005,$713C,$2702,$41AA,$BE0B,$1010,$C90C,$2086,$5768,$B525,$206F,$85B3,$B966,$D409,$CE61,$E49F,$5EDE,$F90E, - $29D9,$C998,$B0D0,$9822,$C7D7,$A8B4,$59B3,$3D17,$2EB4,$0D81,$B7BD,$5C3B,$C0BA,$6CAD,$EDB8,$8320,$9ABF,$B3B6,$03B6,$E20C,$74B1,$D29A, - $EAD5,$4739,$9DD2,$77AF,$04DB,$2615,$73DC,$1683,$E363,$0B12,$9464,$3B84,$0D6D,$6A3E,$7A6A,$5AA8,$E40E,$CF0B,$9309,$FF9D,$0A00,$AE27, - $7D07,$9EB1,$F00F,$9344,$8708,$A3D2,$1E01,$F268,$6906,$C2FE,$F762,$575D,$8065,$67CB,$196C,$3671,$6E6B,$06E7,$FED4,$1B76,$89D3,$2BE0, - $10DA,$7A5A,$67DD,$4ACC,$F9B9,$DF6F,$8EBE,$EFF9,$17B7,$BE43,$60B0,$8ED5,$D6D6,$A3E8,$A1D1,$937E,$38D8,$C2C4,$4FDF,$F252,$D1BB,$67F1, - $A6BC,$5767,$3FB5,$06DD,$48B2,$364B,$D80D,$2BDA,$AF0A,$1B4C,$3603,$4AF6,$4104,$7A60,$DF60,$EFC3,$A867,$DF55,$316E,$8EEF,$4669,$BE79, - $CB61,$B38C,$BC66,$831A,$256F,$D2A0,$5268,$E236,$CC0C,$7795,$BB0B,$4703,$2202,$16B9,$5505,$262F,$C5BA,$3BBE,$B2BD,$0B28,$2BB4,$5A92, - $5CB3,$6A04,$C2D7,$FFA7,$B5D0,$CF31,$2CD9,$9E8B,$5BDE,$AE1D,$9B64,$C2B0,$EC63,$F226,$756A,$A39C,$026D,$930A,$9C09,$06A9,$EB0E,$363F, - $7207,$6785,$0500,$5713,$95BF,$4A82,$E2B8,$7A14,$7BB1,$2BAE,$0CB6,$1B38,$92D2,$8E9B,$E5D5,$BE0D,$7CDC,$EFB7,$0BDB,$DF21,$86D3,$D2D4, - $F1D4,$E242,$68DD,$B3F8,$1FDA,$836E,$81BE,$16CD,$F6B9,$265B,$6FB0,$77E1,$18B7,$4777,$8808,$5AE6,$FF0F,$6A70,$6606,$3BCA,$1101,$0B5C, - $8F65,$9EFF,$F862,$AE69,$616B,$FFD3,$166C,$CF45,$A00A,$E278,$D70D,$D2EE,$4E04,$8354,$3903,$B3C2,$A767,$2661,$D060,$16F7,$4969,$474D, - $3E6E,$77DB,$AED1,$6A4A,$D9D6,$5ADC,$40DF,$0B66,$37D8,$3BF0,$A9BC,$AE53,$DEBB,$9EC5,$47B2,$CF7F,$30B5,$FFE9,$BDBD,$F21C,$CABA,$C28A, - $53B3,$9330,$24B4,$A3A6,$BAD0,$3605,$CDD7,$0693,$54DE,$5729,$23D9,$67BF,$B366,$7A2E,$C461,$4AB8,$5D68,$1B02,$2A6F,$2B94,$B40B,$BE37, - $C30C,$8EA1,$5A05,$DF1B,$2D02,$EF8D,0]:INT - - MOVE.L pwd,A0 - BSR sub_486F0 - MOVE.L D0,hash - END hashdata - RETURN hash -/* -d1=51 -d1=144 -d1=1C6C6162 -d1=54 -d1=36 -d1=d8 -d1=cfba9599 - - -d6d6a3e8 -a2677172 -e8b8d433 -ad678846 -8a65c9ec - -end1 -8ac8467e -b2373032 -*/ -sub_486F0: - MOVEM.L D1-D7/A1-A6,-(A7) - MOVEA.L A0,A3 - MOVEQ #0,D0 - TST.B (A0) - BNE.W loc_48704 - MOVEM.L (A7)+,D1-D7/A1-A6 - RTS --> --------------------------------------------------------------------------- - -loc_48704: - MOVEQ #0,D1 - -loc_48706: - MOVE.B (A0)+,D0 - TST.B D0 - BEQ.W loc_48712 - ADDQ.B #1,D1 - BRA.S loc_48706 --> --------------------------------------------------------------------------- - -loc_48712: - MOVEA.L A3,A0 - MOVEA.L A0,A1 - MOVEA.L A0,A2 - MOVE.L hashdata,A1 - MOVE.L D1,D5 - - MOVEQ #0,D0 - MOVEQ #8,D2 - MOVEQ #$FFFFFFFF,D3 - MOVEQ #2,D4 - -loc_48726: - MOVEQ #0,D1 - MOVE.B (A0)+,D1 - EOR.B D0,D1 - AND.W D3,D1 - ASL.W D4,D1 - MOVE.L 0(A1,D1.L),D1 - LSR.L D2,D0 - EOR.L D1,D0 - SUBQ.L #1,D5 - BNE.S loc_48726 - SWAP D0 - NOT.W D0 - ROXL.L D0,D0 - NEG.L D0 - MOVEM.L (A7)+,D1-D7/A1-A6 - RTS --> End of function sub_486F0 -ENDPROC --> --------------------------------------------------------------------------- +PROC queueConsoleRead(whereto,bsize=1) + IF consoleReadIO=NIL THEN RETURN FALSE + consoleReadIO.command:=CMD_READ + consoleReadIO.data:=whereto + consoleReadIO.length:=bsize + SendIO(consoleReadIO) +ENDPROC TRUE + +PROC queueSerialRead(whereto,bsize=1) + IF readQueued THEN stopSerialRead() + IF serialReadIO=NIL THEN RETURN FALSE + serialReadIO.iostd.command:=CMD_READ + serialReadIO.iostd.data:=whereto + serialReadIO.iostd.length:=bsize + SetSignal(0,Shl(1, serialReadMP.sigbit)) + SendIO(serialReadIO) + readQueued:=TRUE +ENDPROC TRUE PROC loadTranslator(translator:PTR TO translator,fileName) DEF fh @@ -3659,7 +2374,6 @@ PROC loadTranslator(translator:PTR TO translator,fileName) translator.translationText:=NIL ENDIF Dispose(workMem) - ENDPROC PROC loadTranslators() @@ -3677,8 +2391,7 @@ PROC loadTranslators() managedTranslators:=TRUE trans1:=NIL trans2:=NIL - temp:=baseLang[StrLen(baseLang)-1] - IF (temp<>":") AND (temp<>"/") THEN StrAdd(baseLang,'/') + checkPathSlash(baseLang) temp:=1 StringF(languageName,'LANGUAGE.\d',temp) @@ -3747,10 +2460,9 @@ PROC unloadTranslators() ENDPROC PROC loadHistory() - DEF fh,i + DEF fh DEF fname[255]:STRING DEF tempstr[255]:STRING - DEF msg StringF(fname,'\shistory\d',historyFolder,loggedOnUser.slotNumber) IF(fh:=Open(fname,MODE_OLDFILE))<>0 @@ -3810,7 +2522,7 @@ PROC addFlagItems(list:PTR TO stdlist,confNum,fileNames) FOR i:=0 TO EstrLen(fileNames)-1 IF (fileNames[i]=" ") IF EstrLen(fname)>0 - addFlagItem(list,-1,fname) + addFlagItem(list,confNum,fname) StrCopy(fname,'') ENDIF ELSE @@ -3818,7 +2530,7 @@ PROC addFlagItems(list:PTR TO stdlist,confNum,fileNames) ENDIF ENDFOR IF (EstrLen(fname)>0) - addFlagItem(list,-1,fname) + addFlagItem(list,confNum,fname) ENDIF ENDPROC @@ -3838,7 +2550,7 @@ ENDPROC PROC loadFlagged() DEF fh DEF data[2048]:STRING - DEF conf,len,i + DEF conf,len DEF fname[255]:STRING IF ownPartFiles @@ -3933,48 +2645,6 @@ PROC showFlaggedFiles(maxLen) ENDPROC -PROC readIntFromFile(filename: PTR TO CHAR) - DEF fh - DEF v[100]:STRING - IF((fh:=Open(filename,MODE_OLDFILE)))<>0 - ReadStr(fh,v) - Close(fh) - RETURN Val(v) - ENDIF -ENDPROC -1 - -PROC readFloatFromFile(filename: PTR TO CHAR) - DEF fh - DEF v[100]:STRING - IF((fh:=Open(filename,MODE_OLDFILE)))<>0 - ReadStr(fh,v) - Close(fh) - RETURN RealVal(v) - ENDIF -ENDPROC 0.0 - -PROC writeIntToFile(filename: PTR TO CHAR, v: LONG) - DEF fh - DEF vStr[100]:STRING - IF((fh:=Open(filename,MODE_NEWFILE)))<>0 - StringF(vStr,'\d',v) - fileWriteLn(fh,vStr) - Close(fh) - RETURN RESULT_SUCCESS - ENDIF -ENDPROC RESULT_FAILURE - -PROC writeFloatToFile(filename: PTR TO CHAR, v: LONG) - DEF fh - DEF vStr[100]:STRING - IF((fh:=Open(filename,MODE_NEWFILE)))<>0 - RealF(vStr,v,8) - fileWriteLn(fh,vStr) - Close(fh) - RETURN RESULT_SUCCESS - ENDIF -ENDPROC RESULT_FAILURE - PROC getCallerCount() DEF tempStr[255]:STRING StringF(tempStr,'\sSystemStats',cmds.bbsLoc) @@ -4006,11 +2676,9 @@ PROC dumpActiveUser(filename: PTR TO CHAR) Close(fi) ENDPROC - -PROC checkUserOnLine(user: PTR TO user, check) +PROC checkUserOnLine(check) DEF fh,lock - DEF temp[10]:STRING - DEF error=0,stat,loop + DEF error=0,loop DEF tempStr[255]:STRING DEF tuser:user DEF sp:PTR TO singlePort @@ -4043,7 +2711,7 @@ PROC checkUserOnLine(user: PTR TO user, check) UnLock(lock) StringF(tempStr,'\snode\d.user',cmds.bbsLoc,loop) IF(fh:=Open(tempStr,MODE_OLDFILE))<>0 - IF(stat:=Read(fh,tuser,SIZEOF user)) + IF(Read(fh,tuser,SIZEOF user)) IF(stringCompare(tuser.name,loggedOnUser.name)=RESULT_SUCCESS) error:=0 lock:=NIL @@ -4065,14 +2733,14 @@ PROC checkUserOnLine(user: PTR TO user, check) StringF(tempStr,'\snode\d.user',cmds.bbsLoc,node) IF(fh:=Open(tempStr,MODE_NEWFILE))<>0 - IF(stat:=Write(fh,loggedOnUser,SIZEOF user)) THEN error:=1 + IF(Write(fh,loggedOnUser,SIZEOF user)) THEN error:=1 ENDIF Close(fh) /* Write current userkeys information */ ->//(RTS) StringF(tempStr,'\snode\d.userkeys',cmds.bbsLoc,node) /* file name */ IF(fh:=Open(tempStr,MODE_NEWFILE))<>0 - IF(stat:=Write(fh,loggedOnUserKeys,SIZEOF userKeys)) THEN error:=1 + IF(Write(fh,loggedOnUserKeys,SIZEOF userKeys)) THEN error:=1 ENDIF Close(fh) ->// printf("logon.c (79) User_keys.Userflags = %2x\b\n",User_keys.Userflags) @@ -4080,163 +2748,6 @@ PROC checkUserOnLine(user: PTR TO user, check) ENDPROC error - -PROC getNodeFile(toolType,tooltypeSelector,nodeFile) - DEF tempStr[255]:STRING - DEF tempStr2[255]:STRING - DEF i,p - - SELECT toolType - CASE TOOLTYPE_NODE - -> tooltypeSector is node number - StringF(nodeFile,'\sNode\d',cmds.bbsLoc,tooltypeSelector) - CASE TOOLTYPE_WINDOW - -> tooltypeSector is node number - StringF(nodeFile,'\sNode\d/WINDOW.DEF',cmds.bbsLoc,tooltypeSelector) - CASE TOOLTYPE_CONFCONFIG - -> tooltypeSector is not used - StringF(nodeFile,'\sConfconfig',cmds.bbsLoc) - CASE TOOLTYPE_BBSCONFIG - -> tooltypeSector is not used - StringF(nodeFile,'\sbbsConfig',cmds.bbsLoc) - CASE TOOLTYPE_NAMESNOTALLOWED - -> tooltypeSector is not used - StringF(nodeFile,'\sNamesNotAllowed',cmds.bbsLoc) - CASE TOOLTYPE_CONF - -> tooltypeSector is conf number - ->get conf location - StringF(tempStr,'LOCATION.\d',tooltypeSelector) - readToolType(TOOLTYPE_CONFCONFIG,'',tempStr,tempStr2) - IF tempStr2[StrLen(tempStr2)-1]="/" THEN SetStr(tempStr2,StrLen(tempStr2)-1) - StringF(nodeFile,'\s',tempStr2) - CASE TOOLTYPE_BBSCMD - -> tooltypeSector is command name string - StringF(nodeFile,'\sCommands/BBSCmd/\s',cmds.bbsLoc,tooltypeSelector) - CASE TOOLTYPE_CONFCMD - -> tooltypeSector is command name string - StringF(nodeFile,'\sCommands/Conf\dCmd/\s',cmds.bbsLoc,currentConf,tooltypeSelector) - CASE TOOLTYPE_CONFCMD2 - -> tooltypeSector is command name string - StringF(nodeFile,'\s\s',currentConfDir,tooltypeSelector) - CASE TOOLTYPE_NODECMD - -> tooltypeSector is command name string - StringF(nodeFile,'\sCommands/Node\dCmd/\s',cmds.bbsLoc,node,tooltypeSelector) - CASE TOOLTYPE_CONFSYSCMD - -> tooltypeSector is command name string - StringF(nodeFile,'\sCommands/Conf\dSysCmd/\s',cmds.bbsLoc,currentConf,tooltypeSelector) - CASE TOOLTYPE_NODESYSCMD - -> tooltypeSector is command name string - StringF(nodeFile,'\sCommands/Node\dSysCmd/\s',cmds.bbsLoc,node,tooltypeSelector) - CASE TOOLTYPE_SYSCMD - -> tooltypeSector is command name string - StringF(nodeFile,'\sCommands/SYSCmd/\s',cmds.bbsLoc,tooltypeSelector) - CASE TOOLTYPE_DRIVES - -> tooltypeSector is not used - StringF(nodeFile,'\sDrives',cmds.bbsLoc) - CASE TOOLTYPE_COMPUTERLIST - -> tooltypeSector is not used - StringF(nodeFile,'\sComputerList',cmds.bbsLoc) - CASE TOOLTYPE_DEFAULT_ACCESS - -> tooltypeSector is not used - StringF(nodeFile,'\sAccess',cmds.bbsLoc) - CASE TOOLTYPE_USER_ACCESS - -> tooltypeSector is not used - getUserAccessFilename(nodeFile) - CASE TOOLTYPE_ACCESS - -> tooltypeSector is access level number - StringF(nodeFile,'\sAccess/ACS.\d',cmds.bbsLoc,tooltypeSelector) - CASE TOOLTYPE_AREA - -> tooltypeSector is access area name - StringF(nodeFile,'\sAccess/AREA.\s',cmds.bbsLoc,tooltypeSelector) - CASE TOOLTYPE_PRESET - -> tooltypeSector is preset level number - StringF(nodeFile,'\sAccess/PRESET.\d',cmds.bbsLoc,tooltypeSelector) - CASE TOOLTYPE_NODE_PRESET - -> tooltypeSector is access level number, note this also uses the current node - StringF(nodeFile,'\sNode\d/PRESET.\d',cmds.bbsLoc,node,tooltypeSelector) - CASE TOOLTYPE_FCHECK - -> tooltypeSector is file type - StringF(nodeFile,'\s/\s',fCheckDir,tooltypeSelector) - CASE TOOLTYPE_NODE_WINDOW - -> tooltypeSector is node number - StringF(nodeFile,'\sNode\d/WINDOW.DEF',cmds.bbsLoc,tooltypeSelector) - CASE TOOLTYPE_NODE_TIMES - -> tooltypeSector is node number - StringF(nodeFile,'\sNode\d/TIMES.DEF',cmds.bbsLoc,tooltypeSelector) - CASE TOOLTYPE_CONNECT - -> tooltypeSector is node number - StringF(nodeFile,'\sNode\d/Connect.Def',cmds.bbsLoc,tooltypeSelector) - CASE TOOLTYPE_XPRTYPES - -> tooltypeSector is not used - StringF(nodeFile,'\sProtocols/XprTypes',cmds.bbsLoc) - CASE TOOLTYPE_XFERLIB - -> tooltypeSector is xpr lib number - StringF(nodeFile,'\sProtocols/\s',cmds.bbsLoc,xprLib.item(tooltypeSelector)) - CASE TOOLTYPE_SCREENTYPES - -> tooltypeSector is not used - StringF(nodeFile,'\sScreenTypes',cmds.bbsLoc) - CASE TOOLTYPE_NRAMS - -> tooltypeSector is node, - StringF(tempStr,'\sNode\d/NRAMS',cmds.bbsLoc,tooltypeSelector) - IF findFirst(tempStr,tempStr2) - p:=-1 - FOR i:=0 TO StrLen(tempStr2)-1 - IF tempStr2[i]="." THEN p:=i - ENDFOR - IF (p>=0) - SetStr(tempStr2,p) - ENDIF - StringF(nodeFile,'\s/\s',tempStr,tempStr2) - ELSE - StrCopy(nodeFile,'') - ENDIF - CASE TOOLTYPE_ASCPACK - -> tooltypeSector is not used - StringF(nodeFile,'\sZoom/ASCPACK',cmds.bbsLoc) - CASE TOOLTYPE_QWKPACK - -> tooltypeSector is not used - StringF(nodeFile,'\sZoom/QWKPACK',cmds.bbsLoc) - CASE TOOLTYPE_QWKCONFIG - -> tooltypeSector is not used - StringF(nodeFile,'\sZoom/QWKCFG',cmds.bbsLoc) - CASE TOOLTYPE_LANGUAGES - -> tooltypeSector is not used - StringF(nodeFile,'\sLanguages',cmds.bbsLoc) - ENDSELECT -ENDPROC - -PROC findFirst(path: PTR TO CHAR,buf: PTR TO CHAR) HANDLE - DEF pdir=NIL: PTR TO filelock - DEF dir_info=NIL: PTR TO fileinfoblock - DEF returnval=0 - - IF ((dir_info:=(AllocDosObject(DOS_FIB,NIL)))=NIL) - Delay(300) - RETURN 0 - ENDIF - - IF((pdir:=(Lock(path,ACCESS_READ)))=FALSE) - Raise(ERR_EXCEPT) - ENDIF - - IF(Examine(pdir,dir_info))=FALSE - Raise(ERR_EXCEPT) - ENDIF - - IF(ExNext(pdir,dir_info)) - IF(dir_info.direntrytype < 0 ) - returnval:=1 - StrCopy(buf,dir_info.filename) - ENDIF - ENDIF - UnLock(pdir) - FreeDosObject(DOS_FIB,dir_info) -EXCEPT - IF pdir THEN UnLock(pdir) - IF dir_info THEN FreeDosObject(DOS_FIB,dir_info) - RETURN 0 -ENDPROC returnval - PROC findAcsLevel() DEF ttfile[255]:STRING,found,level level:=loggedOnUser.secStatus/5*5 @@ -4253,213 +2764,13 @@ PROC higherAccess() aePuts('\b\nCommand requires higher access.\b\n') ENDPROC -PROC readToolType(toolType,tooltypeSelector,key,outValue) - DEF nodeFile[255]:STRING - DEF do: PTR TO diskobject - DEF tooltypes - DEF s: PTR TO CHAR - - s:=NIL - getNodeFile(toolType,tooltypeSelector,nodeFile) - - do:=getOrCreateCacheItem(nodeFile) - IF (do) - tooltypes:=do.tooltypes - IF (s:=FindToolType(tooltypes,key)) THEN StrCopy(outValue,s,ALL) - ENDIF - IF diskObjectCache=NIL THEN FreeDiskObject(do) -ENDPROC s<>NIL - -PROC readToolTypeInt(toolType,tooltypeSelector,key) - DEF value[255]:STRING - IF readToolType(toolType,tooltypeSelector,key,value) - RETURN Val(value) - ENDIF -ENDPROC -1 - -PROC checkToolType(toolType,tooltypeSelector,key,testValue) - DEF nodeFile[255]:STRING - DEF do: diskobject - DEF tooltypes - DEF s: PTR TO CHAR - DEF result=FALSE - - s:=NIL - - getNodeFile(toolType,tooltypeSelector,nodeFile) - - do:=getOrCreateCacheItem(nodeFile) - IF (do) - tooltypes:=do.tooltypes - IF(s:=FindToolType(tooltypes,key)) - IF (MatchToolValue(s,testValue)) THEN result:=TRUE - ENDIF - ENDIF - IF diskObjectCache=NIL THEN FreeDiskObject(do) -ENDPROC result - -PROC checkToolTypeExists(toolType,tooltypeSelector,key) - DEF nodeFile[255]:STRING - DEF do: diskobject - DEF tooltypes - DEF s: PTR TO CHAR - DEF result=FALSE - - s:=NIL - - getNodeFile(toolType,tooltypeSelector,nodeFile) - - do:=getOrCreateCacheItem(nodeFile) - IF (do) - tooltypes:=do.tooltypes - IF(s:=FindToolType(tooltypes,key)) THEN result:=TRUE - ENDIF - IF diskObjectCache=NIL THEN FreeDiskObject(do) -ENDPROC result - -PROC getOrCreateCacheItem(fileName:PTR TO CHAR) - DEF i,cnt,found=FALSE - DEF cacheObj: PTR TO diskObjectCacheItem - DEF do=NIL:PTR TO diskobject - DEF fn2[255]:STRING - DEF ownToolTypes - DEF toolTypes:PTR TO LONG - DEF fh,fileBuf,off,lineCount,len - - IF diskObjectCache<>NIL - cnt:=diskObjectCache.count() - - i:=0 - WHILE (iLRU algorithm, move most recently used to end of list - i++ - WHILE iNIL - fileBuf:=New(getFileSize(fn2)+1) ->allow an extra char in case file does not end in LF - - fh:=Open(fn2,MODE_OLDFILE) - IF fh<>0 - off:=0 - lineCount:=0 - WHILE(ReadStr(fh,fn2)<>-1) OR (StrLen(fn2)>0) - len:=0 - WHILE (fn2[len]<>0) AND (fn2[len]<>";") - len++ - ENDWHILE - - ->trim trailing space - WHILE (fn2[len-1]<=32) AND (len>0) - len-- - EXIT len=0 ->this is just here to prevent the fn2[len-1] causing a buffer underrun in the absence of short circuit evaluation - ENDWHILE - SetStr(fn2,len) - - AstrCopy(fileBuf+off,fn2,len+1) - lineCount++ - off:=off+len+1 - ENDWHILE - - toolTypes:=List(lineCount+1) - off:=0 - FOR i:=1 TO lineCount - listAdd2(toolTypes,fileBuf+off) - off:=off+StrLen(fileBuf+off)+1 - ENDFOR - ListAdd(toolTypes,[NIL]) - do.tooltypes:=toolTypes - ownToolTypes:=TRUE - Close(fh) - ELSE - Dispose(fileBuf) - FreeDiskObject(do) - do:=NIL - ENDIF - ENDIF - ENDIF - IF diskObjectCache<>NIL - cacheObj:=NEW cacheObj - cacheObj.fileName:=String(StrLen(fileName)) - cacheObj.ownsToolTypes:=ownToolTypes - StrCopy(cacheObj.fileName,fileName) - cacheObj.diskObject:=do - - IF diskObjectCache.count()<(diskObjectCache.maxSize()-1) - diskObjectCache.add(cacheObj) - ELSE - cacheObj:=diskObjectCache.item(0) - DisposeLink(cacheObj.fileName) - FreeDiskObject(cacheObj.diskObject) - diskObjectCache.remove(0) - diskObjectCache.add(cacheObj) - ENDIF - ENDIF - ENDIF -ENDPROC do - -PROC clearDiskObjectCache() - DEF cacheObj: PTR TO diskObjectCacheItem - DEF i, do: PTR TO diskobject - DEF mem - - IF diskObjectCache=NIL THEN RETURN - FOR i:=0 TO diskObjectCache.count()-1 - IF (cacheObj:=diskObjectCache.item(i)) - IF cacheObj.ownsToolTypes - do:=cacheObj.diskObject - mem:=do.tooltypes[0] -> release the file buffer (first string pointer points to start of buffer) - Dispose(mem) - DisposeLink(do.tooltypes) ->our tooltypes is a list that needs to be freed - ENDIF - DisposeLink(cacheObj.fileName) - IF cacheObj.diskObject<>NIL - do:=cacheObj.diskObject - FreeDiskObject(do) - ENDIF - END cacheObj - ENDIF - ENDFOR - diskObjectCache.clear() - cacheTests:=0 - cacheHits:=0 -ENDPROC - PROC startProcess(exestring, stacksize, priority, async, doorTrap) DEF filetags DEF task,temp DEF doorTrapFH=0 DEF processOutFile[255]:STRING - IF (cmds.taskPri<=priority) + IF (byteSignExtend(cmds.taskPri)<=priority) task:=FindTask(0) SetTaskPri(task,priority+1) ENDIF @@ -4470,12 +2781,12 @@ PROC startProcess(exestring, stacksize, priority, async, doorTrap) doorTrapFH:=Open(processOutFile,MODE_NEWFILE) ENDIF - + filetags:=NEW [SYS_INPUT,0,SYS_OUTPUT,doorTrapFH,SYS_ASYNCH,async,NP_STACKSIZE,stacksize,NP_PRIORITY,priority,0] temp:=SystemTagList(exestring,filetags) END filetags - - IF (cmds.taskPri<=priority) + + IF (byteSignExtend(cmds.taskPri)<=priority) SetTaskPri(task,cmds.taskPri) ENDIF @@ -4485,7 +2796,7 @@ PROC startProcess(exestring, stacksize, priority, async, doorTrap) ENDPROC -PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=20000) +PROC runDoor(cmd,type,command,tooltype,params,resident,doorTrap,privcmd,pri=0,stacksize=20000) DEF doorPort[12]:STRING DEF mp: PTR TO mp DEF exestring[100]:STRING @@ -4494,12 +2805,12 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 DEF doormsg: PTR TO doorMsg DEF temp DEF async,ch - DEF i,f + DEF i DEF nodes = 0,msgcmd DEF tempstring[255]:STRING + DEF tempstring2[255]:STRING DEF runOnExit[255]:STRING DEF runOnExit2[255]:STRING - DEF cb:PTR TO confBase DEF exit=0 DEF alreadyActive=FALSE DEF tuserdata:PTR TO user,tuserkeys:PTR TO userKeys, tusermisc: PTR TO userMisc @@ -4507,13 +2818,14 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 StringF(tempstring,'run door: \s',cmd) debugLog(LOG_DEBUG,tempstring) + IF serShared=FALSE THEN purgeLine() StrCopy(runOnExit,'') StrCopy(runOnExit2,'') - IF resident=FALSE + IF (resident=FALSE) AND ((type<>DOORTYPE_MCI) OR (StrLen(cmd)>0)) IF (fileExists(cmd)=FALSE) IF privcmd=FALSE aePuts('\b\nError, can''t locate Custom Command\b\n') @@ -4541,16 +2853,18 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 async:=FALSE CASE DOORTYPE_TIM IF resident - StringF(exestring,'PARADOOR \d \s',node,cmd) + StringF(exestring,'PARADOOR \s \d',cmd,node) ELSE - StringF(exestring,'\sUtils/PARADOOR \d \s',cmds.bbsLoc,node,cmd) + StringF(exestring,'\sUtils/PARADOOR \s \d',cmds.bbsLoc,cmd,node) ENDIF CASE DOORTYPE_IIM purgeLineEnd() StringF(exestring,'\s \d',cmd,node) purgeLineStart() CASE DOORTYPE_MCI - StringF(exestring,'~\s|',cmd) + StringF(cmd,'~SS_\s',cmd) + readToolType(tooltype,command,'MCI_TEXT',cmd) + StringF(exestring,'~|\s|',cmd) processMci(exestring) CASE DOORTYPE_AEM IF resident @@ -4574,6 +2888,8 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 StringF(doorPort,'\s\d','DoorControl',node) ENDIF + IF (type=DOORTYPE_MCI) THEN RETURN + IF (mp:=FindPort(doorPort)) alreadyActive:=TRUE ELSE @@ -4582,11 +2898,6 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 ximSig:=Shl(1,mp.sigbit) - IF (type=DOORTYPE_MCI ) - IF alreadyActive=FALSE THEN deletePort(mp) - RETURN - ENDIF - doorLog(type,cmd) IF type=DOORTYPE_SUP THEN purgeLineEnd() @@ -4710,7 +3021,7 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 CASE JH_SIGBIT msg.data:=doorExtSig CASE JH_FetchKey - IF checkCon() OR checkSer() OR checkTelnetData() + IF checkInput() msg.command:=readChar(doorTimeout) IF (msg.command<0) THEN msg.data:=-1 ELSE msg.data:=1 ELSE @@ -4905,17 +3216,11 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 loggedOnUser.lineLength:=Val(msg.string) ENDIF CASE ACTIVE_NODES - strCpy(msg.string,' ',ALL) - IF(FindPort('AmiExpress_Node.0')) THEN msg.string[0]:="X" - IF(FindPort('AmiExpress_Node.1')) THEN msg.string[1]:="X" - IF(FindPort('AmiExpress_Node.2')) THEN msg.string[2]:="X" - IF(FindPort('AmiExpress_Node.3')) THEN msg.string[3]:="X" - IF(FindPort('AmiExpress_Node.4')) THEN msg.string[4]:="X" - IF(FindPort('AmiExpress_Node.5')) THEN msg.string[5]:="X" - IF(FindPort('AmiExpress_Node.6')) THEN msg.string[6]:="X" - IF(FindPort('AmiExpress_Node.7')) THEN msg.string[7]:="X" - IF(FindPort('AmiExpress_Node.8')) THEN msg.string[8]:="X" - IF(FindPort('AmiExpress_Node.9')) THEN msg.string[9]:="X" + strCpy(msg.string,' ',ALL) + FOR i:=0 TO MAXNODES-1 + StringF(tempstring,'AmiExpress_Node.\d',i) + IF FindPort(tempstring) THEN msg.string[i]:="X" + ENDFOR CASE DT_DUMP dumpActiveUser(msg.string) CASE DT_MSGCODE @@ -4944,7 +3249,7 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 ENDIF CASE BB_CONFNAME IF (msg.data) - StringF(tempstring,'\s',currentConfName) + StrCopy(tempstring,currentConfName) strCpy(msg.string,tempstring,200) ELSE StrCopy(currentConfName,msg.string) @@ -4952,14 +3257,13 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 ENDIF CASE BB_CONFLOCAL IF (msg.data) - StringF(tempstring,'\s',currentConfDir) + StrCopy(tempstring,currentConfDir) strCpy(msg.string,tempstring,200) ELSE setConfLocation(loggedOnUser.confRJoin-1,msg.string) ENDIF CASE BB_LOCAL - StringF(tempstring,'\s',cmds.bbsLoc) - strCpy(msg.string,tempstring,200) + strCpy(msg.string,cmds.bbsLoc,200) CASE ZMODEMSEND dTBT:=0 tBT:=0 @@ -4999,9 +3303,9 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 strCpy(msg.string,tempstring,200) CASE BB_CHATFLAG IF sysopAvail - strCpy(msg.string,'YES',ALL) + strCpy(msg.string,'ON',ALL) ELSE - strCpy(msg.string,'NO',ALL) + strCpy(msg.string,'OFF',ALL) ENDIF CASE BB_CHATSET IF msg.data @@ -5016,12 +3320,14 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 ENDIF ENDIF CASE DT_STAMP_LASTON - formatLongDateTime(loggedOnUser.timeLastOn,msg.string) + formatCDateTime(loggedOnUser.timeLastOn,tempstring) + strCpy(msg.string,tempstring,200) CASE DT_CURR_TIME StringF(tempstring,'\d',getSystemTime()) strCpy(msg.string,tempstring,200) CASE DT_STAMP_CTIME - formatLongDateTime(getSystemTime(),msg.string) + formatCDateTime(getSystemTime(),tempstring) + strCpy(msg.string,tempstring,200) CASE DT_CONFACCESS IF(msg.data) THEN strCpy(msg.string,loggedOnUser.conferenceAccess,10) ELSE strCpy(loggedOnUser.conferenceAccess,msg.string,10) CASE BB_PCONFNAME @@ -5043,7 +3349,7 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 IF StrLen(params)>0 StringF(tempstring,'\s \s',command,params) ELSE - StringF(tempstring,'\s',command) + StrCopy(tempstring,command) ENDIF strCpy(msg.string,tempstring,200) CASE BB_NODEID @@ -5057,13 +3363,13 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 getExpressMajorVer(tempstring) strCpy(msg.string,tempstring,200) CASE GETKEY - IF(checkSer() OR checkCon() OR checkTelnetData()) THEN msg.string[0]:="1" ELSE msg.string[0]:="0" + IF checkInput() THEN msg.string[0]:="1" ELSE msg.string[0]:="0" msg.string[1]:=0 CASE RAWARROW IF(rawArrow) THEN rawArrow:=FALSE ELSE rawArrow:=TRUE CASE PRV_COMMAND StrCopy(tempstring,msg.string) - processCommand(tempstring) + processCommand(tempstring,FALSE,TRUE) CASE PRV_GROUP StrCopy(tempstring,msg.string) temp:=Val(tempstring) @@ -5080,7 +3386,8 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 processOlmMessageQueue(TRUE) Delay(30) modemOffHook() - reqState:=REQ_STATE_LOGOFF + resetSerOut:=TRUE + ->reqState:=REQ_STATE_LOGOFF CASE BB_GETTASK msg.task:=FindTask(0) CASE NODE_BAUD @@ -5127,6 +3434,7 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 ENDIF CASE DT_LANGUAGE IF msg.data + strCpy(msg.string,'txt',ALL) IF loggedOnUser<>NIL IF (loggedOnUser.screenType0) THEN StringF(tempstring,'\s/',sopt.ramPen) ELSE StringF(tempstring,'\sNode\d/Playpen/',cmds.bbsLoc,node) strCpy(msg.string,tempstring,200) CASE ICONIFYQUERY - strCpy(msg.string,IF scropen THEN "NO" ELSE "YES",200) + strCpy(msg.string,IF scropen THEN 'NO' ELSE 'YES',200) CASE LOGON_UNAME debugLog(LOG_WARN,'LOGON_UNAME not currently supported') CASE LOGON_UPASS @@ -5542,6 +3883,12 @@ PROC runDoor(cmd,type,command,params,resident,doorTrap,privcmd,pri=0,stacksize=2 doorLog(type,'') + IF resetSerOut + ioFlags[IOFLAG_SER_IN]:=0 + ioFlags[IOFLAG_SER_OUT]:=0 + resetSerOut:=FALSE + ENDIF + IF (StrLen(runOnExit)>0) processCommand(runOnExit,TRUE) ENDIF @@ -5562,11 +3909,11 @@ PROC doorMsgLoadAccount(doorMsg: PTR TO jhMessage) tusermisc:=NIL ENDIF IF(loggedOnUser.slotNumber=doorMsg.data) - saveMsgPointers(currentConf) ->AddMsgPointers(); + saveMsgPointers(currentConf,currentMsgBase) ->AddMsgPointers(); IF tuserdata<>NIL THEN CopyMem(loggedOnUser,tuserdata,SIZEOF user); IF tuserkeys<>NIL THEN CopyMem(loggedOnUserKeys,tuserkeys,SIZEOF userKeys) IF tusermisc<>NIL THEN CopyMem(loggedOnUserKeys,tusermisc,SIZEOF userMisc) - loadMsgPointers(currentConf) + loadMsgPointers(currentConf,currentMsgBase) doorMsg.nodeID:=1; ELSE IF(loadAccount(doorMsg.data,tuserdata,tuserkeys,tusermisc)<>RESULT_FAILURE) THEN doorMsg.nodeID:=1; @@ -5598,7 +3945,7 @@ PROC doorMsgSaveAccount(doorMsg: PTR TO jhMessage) IF tuserkeys<>NIL THEN CopyMem(tuserkeys,loggedOnUserKeys,SIZEOF userKeys) IF tusermisc<>NIL THEN CopyMem(tusermisc,loggedOnUserMisc,SIZEOF userMisc) timeLimit:=loggedOnUser.timeTotal-loggedOnUser.timeUsed - loadMsgPointers(currentConf) + loadMsgPointers(currentConf,currentMsgBase) IF(i) THEN convertAccess() ENDIF ENDPROC @@ -5689,8 +4036,6 @@ PROC runCommand(cmdtype,cmd,params,privcmd) commandTypeCode:=DOORTYPE_IIM ELSEIF checkToolType(tooltype,cmd,'TYPE','MCI') commandTypeCode:=DOORTYPE_MCI - StrCopy(commandfile,'') - readToolType(tooltype,cmd,'MCI_TEXT',commandfile) ELSEIF checkToolType(tooltype,cmd,'TYPE','AEM') commandTypeCode:=DOORTYPE_AEM ELSEIF checkToolType(tooltype,cmd,'TYPE','SUP') @@ -5706,20 +4051,6 @@ PROC runCommand(cmdtype,cmd,params,privcmd) RETURN FALSE ENDIF - IF checkToolTypeExists(tooltype,cmd,'INTERNAL') - passparams:=readToolTypeInt(tooltype,cmd,'PASS_PARAMETERS') - IF passparams=1 THEN RETURN TRUE - - readToolType(tooltype,cmd,'INTERNAL',commandfile) - IF passparams=2 - ->pass in the original params - StrAdd(commandfile,' ') - StrAdd(commandfile,params) - ENDIF - - RETURN (processCommand(commandfile,TRUE)=RESULT_SUCCESS) - ENDIF - setEnvStat(ENV_DOORS) IF readToolType(tooltype,cmd,'NAME',doorname) setEnvMsg(doorname) @@ -5736,15 +4067,27 @@ PROC runCommand(cmdtype,cmd,params,privcmd) ->UnLockDoor(&LockDoor) RETURN RESULT_FAILURE ENDIF - IF(strCmpi(passwordstr,commandfile,ALL)) - aePuts('\b\nInValid Password!\b\n\b\n') + IF(strCmpi(passwordstr,commandfile,ALL)=FALSE) + aePuts('\b\nInValid Password!\b\n') ->UnLockDoor(&LockDoor) RETURN RESULT_NOT_ALLOWED - ELSE - aePuts('\b\n') ENDIF ENDIF + IF checkToolTypeExists(tooltype,cmd,'INTERNAL') + passparams:=readToolTypeInt(tooltype,cmd,'PASS_PARAMETERS') + IF passparams=1 THEN RETURN TRUE + + readToolType(tooltype,cmd,'INTERNAL',commandfile) + IF passparams=2 + ->pass in the original params + StrAdd(commandfile,' ') + StrAdd(commandfile,params) + ENDIF + + RETURN (processCommand(commandfile,TRUE)=RESULT_SUCCESS) + ENDIF + IF (commandTypeCode=DOORTYPE_SIM) getNodeFile(tooltype,cmd,commandfile) default:=fileExists(commandfile) @@ -5754,6 +4097,7 @@ PROC runCommand(cmdtype,cmd,params,privcmd) default:=FALSE ENDIF + StrCopy(commandfile,'') IF (default) OR (readToolType(tooltype,cmd,'LOCATION',commandfile)) IF commandTypeCode=-1 THEN RETURN FALSE @@ -5766,7 +4110,7 @@ PROC runCommand(cmdtype,cmd,params,privcmd) stacksize:=20000 IF readToolType(tooltype,cmd,'PRIORITY',passwordstr) IF strCmpi(passwordstr,'same',ALL) - pri:=cmds.taskPri + pri:=byteSignExtend(cmds.taskPri) ELSE pri:=Val(passwordstr) ENDIF @@ -5780,7 +4124,7 @@ PROC runCommand(cmdtype,cmd,params,privcmd) doorTrap:=checkToolTypeExists(tooltype,cmd,'TRAPON') readToolType(tooltype,cmd,'MIMICVER',mimicVersion) - runDoor(commandfile,commandTypeCode,cmd,params,resident,doorTrap,privcmd,pri,stacksize) + runDoor(commandfile,commandTypeCode,cmd,tooltype,params,resident,doorTrap,privcmd,pri,stacksize) StrCopy(mimicVersion,'') ENDIF @@ -5798,25 +4142,25 @@ PROC runSysCommand(cmd,params,privcmd=TRUE) debugLog(LOG_DEBUG,debugstr) ENDPROC runCommand(CMDTYPE_SYSCMD,cmd,params,privcmd) -PROC loadConfDB(account,confNum,addr,force=FALSE) +PROC loadConfDB(account,confNum,msgBase,addr,force=FALSE) DEF bi, confLoc[255]:STRING DEF tmpMem IF (account = loggedOnUser.slotNumber) AND (force=FALSE) - CopyMem(confBases.item(confNum-1),addr,SIZEOF confBase) + CopyMem(confBases.item(getConfIndex(confNum,msgBase)),addr,SIZEOF confBase) RETURN ENDIF - getConfDbFileName(confNum,confLoc) + getConfDbFileName(confNum,msgBase,confLoc) bi:=Open(confLoc,MODE_OLDFILE) IF(bi=0) callersLog('\tError can''t open >:') - callersLog(confLoc) RETURN ENDIF IF(Seek(bi,(account-1)*SIZEOF confBase,OFFSET_BEGINNING)=-1) - callersLog('\tError Reading MsgBase Pointer') + callersLog('\tError Reading confbase data') + callersLog(confLoc) Close(bi) RETURN ENDIF @@ -5834,15 +4178,15 @@ PROC loadConfDB(account,confNum,addr,force=FALSE) Close(bi) ENDPROC -PROC saveConfDB(account,confNum,addr,force=FALSE) +PROC saveConfDB(account,confNum,msgBase,addr,force=FALSE) DEF bi, confLoc[255]:STRING IF (account = loggedOnUser.slotNumber) AND (force=FALSE) - CopyMem(addr,confBases.item(confNum-1),SIZEOF confBase) + CopyMem(addr,confBases.item(getConfIndex(confNum,msgBase)),SIZEOF confBase) RETURN ENDIF - getConfDbFileName(confNum,confLoc) + getConfDbFileName(confNum,msgBase,confLoc) bi:=Open(confLoc,MODE_READWRITE) IF(bi=0) @@ -5861,17 +4205,17 @@ PROC saveConfDB(account,confNum,addr,force=FALSE) Close(bi) ENDPROC -PROC loadMsgPointers(conf) +PROC loadMsgPointers(conf,msgBase) DEF cb: PTR TO confBase DEF i - IF(loggedOnUser.slotNumber<=0) + IF(loggedOnUser.slotNumber<=0) OR (conf<1) OR (msgBase<1) lastMsgReadConf:=0 lastNewReadConf:=0 RETURN ENDIF - cb:=confBases.item(conf-1) + cb:=confBases.item(getConfIndex(conf,msgBase)) IF (checkSecurity(ACS_CONFERENCE_ACCOUNTING)) IF (readToolTypeInt(TOOLTYPE_CONF,conf,'CONFDB_SHARED')<=0) @@ -5885,9 +4229,10 @@ PROC loadMsgPointers(conf) loggedOnUser.downloads:=cb.downloads loggedOnUser.secBoard:=cb.ratioType loggedOnUser.secLibrary:=cb.ratio + loggedOnUser.newSinceDate:=cb.newSinceDate ENDIF - loggedOnUser.messagesPosted:=cb.messagesPosted ENDIF + loggedOnUser.messagesPosted:=cb.messagesPosted IF(newSinceFlag) THEN cb.newSinceDate:=getSystemTime() -> Last_EMail=it->CB.LastEMail @@ -5895,18 +4240,18 @@ PROC loadMsgPointers(conf) lastNewReadConf:=cb.confRead ENDPROC -PROC saveMsgPointers(conf) +PROC saveMsgPointers(conf,msgBase) DEF cb: PTR TO confBase DEF debug[255]:STRING DEF i - IF(loggedOnUser.slotNumber<=0) OR (conf=0) + IF(loggedOnUser.slotNumber<=0) OR (conf<1) OR (msgBase<1) lastMsgReadConf:=0 lastNewReadConf:=0 RETURN ENDIF - cb:=confBases.item(conf-1) + cb:=confBases.item(getConfIndex(conf,msgBase)) IF (checkSecurity(ACS_CONFERENCE_ACCOUNTING)) IF (readToolTypeInt(TOOLTYPE_CONF,conf,'CONFDB_SHARED')<=0) @@ -5921,8 +4266,8 @@ PROC saveMsgPointers(conf) cb.ratioType:=loggedOnUser.secBoard cb.ratio:=loggedOnUser.secLibrary ENDIF - cb.messagesPosted:=loggedOnUser.messagesPosted ENDIF + cb.messagesPosted:=loggedOnUser.messagesPosted IF(newSinceFlag) THEN cb.newSinceDate:=getSystemTime() -> Last_EMail=it->CB.LastEMail @@ -5955,14 +4300,22 @@ PROC saveMsgPointers(conf) cb.confRead:=lastNewReadConf ENDPROC -PROC joinConf(conf, confScan, auto, forceMailScan=FORCE_MAILSCAN_NOFORCE) +PROC joinConf(conf, msgBaseNum,confScan, auto, forceMailScan=FORCE_MAILSCAN_NOFORCE) DEF string[255]:STRING,tempstr[255]:STRING + DEF namestr1[255]:STRING + DEF namestr2[255]:STRING DEF mystat, temp IF (checkConfAccess(conf)=FALSE) THEN conf:=1 IF((conf<1) OR (conf>cmds.numConf)) THEN conf:=1 - IF confScan=FALSE THEN currentConf:=conf + IF (msgBaseNum<1 ) OR (msgBaseNum>getConfMsgBaseCount(conf)) THEN msgBaseNum:=1 + + IF confScan=FALSE + currentConf:=conf + currentMsgBase:=msgBaseNum + ENDIF + getConfName(conf,currentConfName) getConfLocation(conf,currentConfDir) @@ -5973,20 +4326,22 @@ PROC joinConf(conf, confScan, auto, forceMailScan=FORCE_MAILSCAN_NOFORCE) StrCopy(menuPrompt,'') readToolType(TOOLTYPE_CONF,conf,'MENU_PROMPT',menuPrompt) - StringF(msgBaseLocation,'\sMsgBase/',currentConfDir) + getMsgBaseLocation(conf,msgBaseNum,msgBaseLocation) StringF(uploadLocation,'\sUpload/',currentConfDir) confNameType:=NAME_TYPE_USERNAME - IF checkToolTypeExists(TOOLTYPE_CONF,conf,'REALNAME') + StringF(namestr1,'REALNAME.\d',msgBaseNum) + StringF(namestr2,'INTERNETNAME.\d',msgBaseNum) + IF checkToolTypeExists(TOOLTYPE_CONF,conf,'REALNAME') OR checkToolTypeExists(TOOLTYPE_MSGBASE,conf,namestr1) confNameType:=NAME_TYPE_REALNAME - ELSEIF checkToolTypeExists(TOOLTYPE_CONF,conf,'INTERNETNAME') + ELSEIF checkToolTypeExists(TOOLTYPE_CONF,conf,'INTERNETNAME') OR checkToolTypeExists(TOOLTYPE_MSGBASE,conf,namestr2) confNameType:=NAME_TYPE_INTERNETNAME ENDIF - loadMsgPointers(conf) + loadMsgPointers(conf,msgBaseNum) IF checkToolTypeExists(TOOLTYPE_CONF,conf,'CUSTOM')=FALSE - mystat:=getMailStatFile(conf) + mystat:=getMailStatFile(conf,msgBaseNum) IF(mystat=RESULT_FAILURE) lastMsgReadConf:=0 lastNewReadConf:=0 @@ -6024,12 +4379,24 @@ PROC joinConf(conf, confScan, auto, forceMailScan=FORCE_MAILSCAN_NOFORCE) IF (auto) scanHoldDesc() processSysCommand('S') - StringF(string,'Conference \d: \s Auto-ReJoined',relConfNum,currentConfName) + IF getConfMsgBaseCount(conf)>1 + getMsgBaseName(conf,msgBaseNum,tempstr) + StringF(string,'Conference \d: \s [\s] Auto-ReJoined',relConfNum,currentConfName,tempstr) + ELSE + StringF(string,'Conference \d: \s Auto-ReJoined',relConfNum,currentConfName) + ENDIF aePuts(string) ELSE - StringF(string,'Joining Conference: \s',currentConfName) - aePuts(string) - StringF(string,'\s (\d) Conference Joined',currentConfName,conf) + IF getConfMsgBaseCount(conf)>1 + getMsgBaseName(conf,msgBaseNum,tempstr) + StringF(string,'Joining Conference: \s [\s]',currentConfName,tempstr) + aePuts(string) + StringF(string,'\s [\s] (\d) Conference Joined',currentConfName,tempstr,conf) + ELSE + StringF(string,'Joining Conference: \s',currentConfName) + aePuts(string) + StringF(string,'\s (\d) Conference Joined',currentConfName,conf) + ENDIF ENDIF aePuts('\b\n') StringF(tempstr,'\t\s',string) @@ -6061,18 +4428,25 @@ PROC joinConf(conf, confScan, auto, forceMailScan=FORCE_MAILSCAN_NOFORCE) ENDIF IF (auto=FALSE) AND (forceMailScan<>FORCE_MAILSCAN_SKIP) - IF (forceMailScan=FORCE_MAILSCAN_ALL) OR (checkMailConfScan(conf)) + IF (forceMailScan=FORCE_MAILSCAN_ALL) OR (checkMailConfScan(conf, msgBaseNum)) IF checkToolTypeExists(TOOLTYPE_CONF,conf,'CUSTOM')=FALSE - mystat:=callMsgFuncs(MAIL_SCAN,conf) + mystat:=callMsgFuncs(MAIL_SCAN,conf, msgBaseNum) ELSE customMsgbaseCmd(3,conf,0) ENDIF - saveMsgPointers(conf) + saveMsgPointers(conf,msgBaseNum) ENDIF ENDIF - IF (auto=FALSE) AND (confScan=FALSE) THEN loggedOnUser.confRJoin:=conf - + IF (auto=FALSE) AND (confScan=FALSE) + IF (reqState<>REQ_STATE_NONE) THEN RETURN mystat + IF(logonType>=LOGON_TYPE_REMOTE) + IF(checkCarrier()=FALSE) THEN RETURN mystat + ENDIF + loggedOnUser.confRJoin:=conf + loggedOnUser.msgBaseRJoin:=msgBaseNum + captureRealAndInternetNames(conf,msgBaseNum) + ENDIF ENDPROC mystat PROC doPause() @@ -6091,7 +4465,6 @@ ENDPROC 0 PROC readRawChar(timeout,extsig = 0) DEF wasControl,ch DEF timedout,signalled - DEF temp[1]:STRING conPuts('[ p') /* turn console cursor on */ REPEAT @@ -6109,7 +4482,6 @@ ENDPROC ch PROC readChar(timeout, extsig = 0) DEF wasControl,ch DEF timedout,signalled - DEF temp[1]:STRING conPuts('[ p') /* turn console cursor on */ @@ -6126,10 +4498,12 @@ PROC readChar(timeout, extsig = 0) ENDPROC ch PROC checkForPause() - DEF stat,linelen + DEF linelen DEF input[3]:STRING - IF loggedOnUser<>NIL THEN linelen:=loggedOnUser.lineLength ELSE linelen:=30 + IF loggedOnUser=NIL THEN RETURN RESULT_SUCCESS + + linelen:=loggedOnUser.lineLength IF linelen=0 THEN linelen:=22 IF(nonStopDisplayFlag=FALSE) THEN lineCount++ @@ -6164,7 +4538,6 @@ PROC conCLS() StrCopy(cls,' ',ALL) cls[0]:=12 conPuts(cls) - lineCount:=0 ENDPROC PROC sendCLS() @@ -6172,7 +4545,6 @@ PROC sendCLS() StrCopy(cls,' ',ALL) cls[0]:=12 aePuts(cls) - lineCount:=0 ENDPROC PROC sendBELL() @@ -6206,6 +4578,7 @@ PROC processMciCmd(mcidata,len,pos) DEF cmd[100]:STRING DEF num[4]:STRING DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING DEF filename[100]:STRING DEF screenfilename[100]:STRING DEF maxLen,nval,res @@ -6230,7 +4603,7 @@ PROC processMciCmd(mcidata,len,pos) t:=0 ENDIF - MidStr(cmd,mcidata,pos,maxLen-pos) + midStr2(cmd,mcidata,pos,maxLen-pos) IF EstrLen(num)>0 THEN maxLen:=Val(num) ELSE maxLen:=-1 /* @@ -6272,7 +4645,7 @@ PROC processMciCmd(mcidata,len,pos) aePuts2(tempstr,maxLen) ELSEIF (StrCmp(cmd,'TT',ALL)) pos:=pos+2+t - StringF(tempstr,'\d',loggedOnUserKeys.timesOnToday AND $FFFF) + StringF(tempstr,'\d',getTodaysCalls(loggedOnUser,loggedOnUserKeys)) aePuts2(tempstr,maxLen) ELSEIF (StrCmp(cmd,'LC',ALL)) pos:=pos+2+t @@ -6420,14 +4793,14 @@ PROC processMciCmd(mcidata,len,pos) ->display another file pos:=pos+3 nval:=EstrLen(cmd)-3 - MidStr(cmd,mcidata,pos,nval) + midStr2(cmd,mcidata,pos,nval) displayFile(cmd) pos:=pos+EstrLen(cmd)+t ELSEIF StrCmp(cmd,'SX_',3) ->sequential file display pos:=pos+3 nval:=EstrLen(cmd)-3 - MidStr(cmd,mcidata,pos,nval) + midStr2(cmd,mcidata,pos,nval) nval:=readIntFromFile(cmd) IF nval<>-1 nval++ @@ -6460,7 +4833,7 @@ PROC processMciCmd(mcidata,len,pos) debugLog(LOG_DEBUG,tempstr) maxLen:=EstrLen(cmd)-3 -> get full filename - MidStr(cmd,mcidata,pos,maxLen) + midStr2(cmd,mcidata,pos,maxLen) StrCopy(tempstr,cmd,FilePart(cmd)-cmd) StringF(filename,'\z\r\d[3].\s',nval+1,FilePart(cmd),screenfilename) StrAdd(tempstr, filename) @@ -6473,14 +4846,14 @@ PROC processMciCmd(mcidata,len,pos) ->run a command pos:=pos+3 nval:=EstrLen(cmd)-3 - MidStr(cmd,mcidata,pos,nval) + midStr2(cmd,mcidata,pos,nval) processSysCommand(cmd,TRUE) pos:=pos+EstrLen(cmd)+t ELSEIF StrCmp(cmd,'CR_',3) ->promted keypress pos:=pos+3 nval:=EstrLen(cmd)-3 - MidStr(cmd,mcidata,pos,nval) + midStr2(cmd,mcidata,pos,nval) aePuts(cmd) res:=readChar(INPUT_TIMEOUT) IF res<>RESULT_SUCCESS THEN RETURN res @@ -6505,8 +4878,8 @@ PROC processMciCmd(mcidata,len,pos) aePuts(' ') res++ ENDWHILE - StringF(tempstr,'\s\b\n',getConfName(nval)) - aePuts(tempstr) + StringF(tempstr2,'\s\b\n',tempstr) + aePuts(tempstr2) ENDIF ENDFOR ELSEIF StrCmp(cmd,'CD',ALL) @@ -6520,6 +4893,32 @@ PROC processMciCmd(mcidata,len,pos) IF (num AND 1)=0 THEN aePuts('\b\n') ENDIF ENDFOR + ELSEIF StrCmp(cmd,'ML',ALL) + pos:=pos+2+t + num:=getConfMsgBaseCount(currentConf) + FOR nval:=1 TO num + StringF(tempstr,' \d[3]) ',nval) + aePuts(tempstr) + getMsgBaseName(currentConf,nval,tempstr) + IF (num=1) AND (StrLen(tempstr)=0) THEN StrCopy(tempstr,'Default') + res:=StrLen(tempstr) + WHILE(res<30) + aePuts(' ') + res++ + ENDWHILE + StringF(tempstr2,'\s\b\n',tempstr) + aePuts(tempstr2) + ENDFOR + ELSEIF StrCmp(cmd,'MD',ALL) + pos:=pos+2+t + num:=getConfMsgBaseCount(currentConf) + FOR nval:=1 TO num + getMsgBaseName(currentConf,nval,tempstr2) + IF (num=1) AND (StrLen(tempstr2)=0) THEN StrCopy(tempstr2,'Default') + StringF(tempstr,' [\r\z\d[3]] \l\s[30]',nval,tempstr2) + aePuts(tempstr) + IF (nval AND 1)=0 THEN aePuts('\b\n') + ENDFOR ELSEIF StrCmp(cmd,'c0',ALL) aePuts('') pos:=pos+2+t @@ -6595,9 +4994,24 @@ PROC processMciCmd(mcidata,len,pos) ELSEIF StrCmp(cmd,'n9',ALL) blankLines(9) pos:=pos+2+t + ELSEIF StrCmp(cmd,'SMO',3) + slowmo:=1 + slowmoCount:=slowmoCount+(60*slowmo) + pos:=pos+3 + nval:=EstrLen(cmd)-3 + midStr2(cmd,mcidata,pos,nval) + slowmo:=Val(cmd) + IF (slowmo<1) OR (slowmo>5) THEN slowmo:=1 + pos:=pos+t + ELSEIF StrCmp(cmd,'SMC',ALL) + slowmo:=0 + pos:=pos+3+t + ELSEIF StrCmp(cmd,'NS',ALL) + nonStopDisplayFlag:=TRUE + pos:=pos+2+t ELSEIF (StrCmp(cmd,'D',1)) ->this needs to be near the end otherwise it might pick up other commands starting with D - pos:=pos+2+t + pos:=pos+1+t MidStr(cmd,mcidata,pos,ALL) StrCopy(mciterminator,cmd) pos:=pos+StrLen(cmd) @@ -6639,7 +5053,7 @@ PROC processMciCmd2(mcidata,len,pos,outdata) t:=0 ENDIF - MidStr(cmd,mcidata,pos,maxLen-pos) + midStr2(cmd,mcidata,pos,maxLen-pos) IF EstrLen(num)>0 THEN maxLen:=Val(num) ELSE maxLen:=-1 IF (StrCmp(cmd,'',ALL)) @@ -6665,7 +5079,7 @@ PROC processMciCmd2(mcidata,len,pos,outdata) StrAdd(outdata,tempstr,maxLen) ELSEIF (StrCmp(cmd,'TT',ALL)) pos:=pos+2+t - StringF(tempstr,'\d',loggedOnUserKeys.timesOnToday AND $FFFF) + StringF(tempstr,'\d',getTodaysCalls(loggedOnUser,loggedOnUserKeys)) aePuts2(tempstr,maxLen) ELSEIF (StrCmp(cmd,'LC',ALL)) pos:=pos+2+t @@ -6943,7 +5357,7 @@ PROC tranChat() RETURN c ENDIF updateTimeUsed() - IF (loggedOnUser.chatRemain<=0) + IF (loggedOnUser.chatLimit<>0) AND (loggedOnUser.chatRemain<=0) chatFlag:=0 ENDIF EXIT chatFlag=0 @@ -7078,12 +5492,10 @@ PROC tranChat() ENDPROC PROC chat() - DEF c,j,x,i,back,whichCon,whichSer - DEF str[100]:STRING,str2[10]:STRING,space[90]:STRING,buff[256]:STRING + DEF c,x,i,back,whichCon,whichSer + DEF str[100]:STRING,str2[10]:STRING,space[90]:STRING DEF chatfile[255]:STRING - DEF fp -wx: checkOnlineStatus() runSysCommand('CHATIN','') @@ -7101,13 +5513,12 @@ wx: aePuts(cmds.sysopName) aePuts(', How can I help you??\b\n\b\n') ENDIF -sx: pagedFlag:=0 chatConFlag:=1 IF(ansiColour) StringF(str,'[\dm',cmds.acLvl[LVL_CHAT_COLOR_SYSOP]) - fAEPutStr(str) + aePuts(str) ENDIF chatSerFlag:=0 @@ -7137,7 +5548,7 @@ next: ENDIF updateTimeUsed() - IF (loggedOnUser.chatRemain<=0) + IF (loggedOnUser.chatLimit<>0) AND (loggedOnUser.chatRemain<=0) chatFlag:=0 JUMP chatbrk ENDIF @@ -7150,7 +5561,7 @@ next: StrCopy(space,'') x:=0 - fAEPutStr('\b\n') + aePuts('\b\n') checkOnlineStatus() JUMP cnext2 ENDIF @@ -7159,9 +5570,9 @@ next: IF(x>0) x-- SetStr(space,x) - fAEPutStr(CHAR_BACKSPACE) - fAEPutStr(' ') - fAEPutStr(CHAR_BACKSPACE) + sendChar(CHAR_BACKSPACE) + aePuts(' ') + sendChar(CHAR_BACKSPACE) JUMP cnext2 ENDIF @@ -7178,11 +5589,11 @@ next: IF(ansiColour) IF((chatConFlag=1) AND (whichSer=1)) StringF(str,'[\dm',cmds.acLvl[LVL_CHAT_COLOR_SYSOP]) - IF(bitPlanes<3) THEN serPuts(str) ELSE fAEPutStr(str) + IF(bitPlanes<3) THEN serPuts(str) ELSE aePuts(str) ENDIF IF((chatSerFlag=1) AND (whichCon=1)) StringF(str,'[\dm',cmds.acLvl[LVL_CHAT_COLOR_USER]) - IF(bitPlanes<3) THEN serPuts(str) ELSE fAEPutStr(str) + IF(bitPlanes<3) THEN serPuts(str) ELSE aePuts(str) ENDIF sendChar(c) ELSE @@ -7206,7 +5617,7 @@ next: IF(back=0) IF(captureFP) THEN fileWriteLn(captureFP,space) - fAEPutStr('\b\n') + aePuts('\b\n') StrCopy(space,'') x:=0 JUMP next @@ -7228,13 +5639,13 @@ next: x:=StrLen(str) StrCopy(space,str) FOR i:=0 TO x-1 - fAEPutStr(CHAR_BACKSPACE) - fAEPutStr(' ') - fAEPutStr(CHAR_BACKSPACE) + sendChar(CHAR_BACKSPACE) + aePuts(' ') + sendChar(CHAR_BACKSPACE) ENDFOR - fAEPutStr('\b\n') - fAEPutStr(str) + aePuts('\b\n') + aePuts(str) ENDIF chatbrk: @@ -7243,8 +5654,6 @@ chatbrk: statPrintUser(loggedOnUser,loggedOnUserKeys,loggedOnUserMisc) IF(ansiColour) THEN aePuts('') - wy: - StrCopy(chatfile,'') IF (loggedOnUser.screenTypeNIL windowsig:=Shl(1, windowClose.userport.sigbit) win:=windowClose @@ -7947,21 +6365,49 @@ PROC closeAEStats() ENDPROC PROC toggleStatusDisplay() - DEF dp,bp,tags + DEF dp,bp,sz,tags + DEF pub=FALSE + DEF pubScreen[255]:STRING + DEF pubLock=0:PTR TO screen + + + IF bitPlanes=0 + pub:=TRUE + ENDIF + + IF readToolType(TOOLTYPE_WINDOW,node,'WINDOW.PUBSCREEN',pubScreen) + pub:=TRUE + ENDIF + + IF checkToolTypeExists(TOOLTYPE_NODE,node,'SHOW_CACHE_STATS') + sz:=37 + ELSE + sz:=27 + ENDIF + + IF pub + IF StrLen(pubScreen)>0 + pubLock:=LockPubScreen(pubScreen) + ELSE + pubLock:=LockPubScreen(NIL) + ENDIF + IF pubLock=FALSE + pub:=FALSE + ELSE + sz:=sz+pubLock.wbortop+pubLock.font.ysize+pubLock.wborbottom + ENDIF + ENDIF - IF screen=NIL THEN RETURN + IF (screen=NIL) AND (pub=FALSE) THEN RETURN IF(dStatBar) dStatBar:=0 closeAEStats() - IF(bitPlanes) - MoveWindow(window,0,-37) - SizeWindow(window,0,37) - ELSE - MoveWindow(window,0,-38) - SizeWindow(window,0,38) + MoveWindow(window,0,-sz) + SizeWindow(window,0,sz) + IF (loggedOnUser<>NIL) + IF (StrLen(loggedOnUser.name)>0) THEN statPrintUser(loggedOnUser,loggedOnUserKeys,loggedOnUserMisc) ENDIF - IF (loggedOnUser<>NIL) AND (StrLen(loggedOnUser.name)>0) THEN statPrintUser(loggedOnUser,loggedOnUserKeys,loggedOnUserMisc) ELSE IF(bitPlanes<2) @@ -7972,33 +6418,46 @@ PROC toggleStatusDisplay() bp:=4 ENDIF - tags:=NEW [WA_CUSTOMSCREEN,screen, - WA_LEFT,0, - WA_TOP,10, - WA_WIDTH,640, - WA_HEIGHT,39, - WA_DETAILPEN,dp, - WA_BLOCKPEN,bp, - WA_FLAGS, - WFLG_SIMPLE_REFRESH,NIL] + IF pub + tags:=NEW [WA_PUBSCREEN,pubLock, + WA_DEPTHGADGET,1, + WA_DRAGBAR,1, + WA_LEFT,window.leftedge, + WA_TOP,window.topedge, + WA_WIDTH,sopt.width, + WA_HEIGHT,sz, + WA_DETAILPEN,dp, + WA_BLOCKPEN,bp, + WA_FLAGS, + WFLG_SIMPLE_REFRESH,NIL] + ELSE + tags:=NEW [WA_CUSTOMSCREEN,screen, + WA_LEFT,0, + WA_TOP,screen.wbortop+screen.font.ysize-1, + WA_WIDTH,640, + WA_HEIGHT,sz, + WA_DETAILPEN,dp, + WA_BLOCKPEN,bp, + WA_FLAGS, + WFLG_SIMPLE_REFRESH,NIL] + ENDIF IF(( windowStat:=OpenWindowTagList(NIL,tags))<>NIL) dStatBar:=1 - IF(bitPlanes) - SizeWindow(window,0,-37) - MoveWindow(window,0,37) - ELSE - SizeWindow(window,0,-38) - MoveWindow(window,0,38) - ENDIF - + SizeWindow(window,0,-sz) + MoveWindow(window,0,sz) + initStatCon() clearStatusPane() SetWindowTitles(window,titlebar,titlebar) - IF (loggedOnUser<>NIL) AND (StrLen(loggedOnUser.name)>0) THEN statPrintUser(loggedOnUser,loggedOnUserKeys,loggedOnUserMisc) + IF pub THEN SetWindowTitles(windowStat,titlebar,titlebar) + IF (loggedOnUser<>NIL) + IF (StrLen(loggedOnUser.name)>0) THEN statPrintUser(loggedOnUser,loggedOnUserKeys,loggedOnUserMisc) + ENDIF statChatFlag() ENDIF END tags + IF pubLock THEN UnlockPubScreen(NIL,pubLock) ENDIF ENDPROC @@ -8014,7 +6473,7 @@ PROC doFax() serShared:=oldshared reInitModem() - resetSystem(1) + resetSystem() setEnvStat(ENV_AWAITCONNECT) ENDPROC @@ -8069,9 +6528,10 @@ PROC checkIncomingCall() DEF tempstr[255]:STRING DEF tempstr2[255]:STRING DEF stat,n,isConnected=FALSE - DEF filetags + DEF filetags,r DEF peeraddr: sockaddr_in DEF hostent: PTR TO hostent + DEF s ioFlags[IOFLAG_SER_IN]:=-1 ioFlags[IOFLAG_SER_OUT]:=0 @@ -8082,10 +6542,14 @@ PROC checkIncomingCall() IF telnetSocket>=0 StrCopy(connectString,'CONNECT 19200') n:=SIZEOF sockaddr_in - GetPeerName(telnetSocket,peeraddr,{n}) - hostent:=GetHostByAddr(peeraddr.sin_addr,4,AF_INET) - StrCopy(hostName,hostent.h_name,255) - StringF(hostIP,'\d.\d.\d.\d',Shr(peeraddr.sin_addr AND $ff000000,24),Shr(peeraddr.sin_addr AND $ff0000,16),Shr(peeraddr.sin_addr AND $ff00,8),peeraddr.sin_addr AND $ff) + r:=GetPeerName(telnetSocket,peeraddr,{n}) + IF r=0 + StringF(hostIP,'\d.\d.\d.\d',Shr(peeraddr.sin_addr AND $ff000000,24) AND $FF,Shr(peeraddr.sin_addr AND $ff0000,16),Shr(peeraddr.sin_addr AND $ff00,8),peeraddr.sin_addr AND $ff) + s:=peeraddr.sin_addr + hostent:=GetHostByAddr({s},4,AF_INET) + IF hostent<>NIL THEN StrCopy(hostName,hostent.h_name,255) + ENDIF + JUMP go3 ENDIF @@ -8159,6 +6623,7 @@ go2: IF(input=RESULT_TIMEOUT) THEN JUMP timedout ENDIF go3: + stripReturn(string) readToolType(TOOLTYPE_CONNECT,node,string,connectString) @@ -8232,7 +6697,6 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) DEF doorsig=0,rexxsig=0,serialsig=0,timersig=0,timedout=0 DEF temp[255]:STRING DEF statePtr: PTR TO awaitState - DEF n IF (transfering) RETURN TRUE,RESULT_TIMEOUT @@ -8270,8 +6734,7 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) IF signals=0 IF timeout<>0 openTimer() - timeout:=Mul(timeout,1000000) - setTimer(timeout) + setTimer(timeout,0) IF timerport<>NIL THEN timersig:=Shl(1, timerport.sigbit) ENDIF @@ -8323,8 +6786,10 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) IF (ch=0) AND allowSer AND (signals AND (serialsig OR telnetsig)) IF rawMode - lch:=readMayGetChar(serialReadMP,TRUE,{serbuff}) - IF lch<>-1 THEN ch:=lch + IF (ioFlags[IOFLAG_SER_IN]) + lch:=readMayGetChar(serialReadMP,TRUE,{serbuff}) + IF lch<>-1 THEN ch:=lch + ENDIF ELSEIF -1<>(lch:=readMayGetChar(serialReadMP,TRUE,{serbuff})) IF (ioFlags[IOFLAG_SER_IN]) ch:=lch @@ -8332,6 +6797,7 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) StringF(obuf, 'Serial Received: hex $\z\h[2] = \c', ch, ch) debugLog(LOG_DEBUG,obuf) chatSerFlag:=1 + ximPort:=SERIAL_PORT IF ch=$1b ch:=readMayGetChar(serialReadMP,TRUE,{serbuff}) StringF(obuf, 'Escape Serial Received: hex $\z\h[2] = \c', ch, ch) @@ -8365,12 +6831,15 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) -> If a console signal was received, get the character IF rawMode - lch:=readMayGetChar(consoleReadMP, FALSE,{ibuf}) - IF lch<>-1 THEN ch:=lch + IF (ioFlags[IOFLAG_KBD_IN]) + lch:=readMayGetChar(consoleReadMP, FALSE,{ibuf}) + IF lch<>-1 THEN ch:=lch + ENDIF ELSEIF -1<>(lch:=readMayGetChar(consoleReadMP, FALSE, {ibuf})) IF (ioFlags[IOFLAG_KBD_IN]) ch:=lch chatConFlag:=1 + ximPort:=CONSOLE_PORT IF ((ch>=$1F) AND (ch<=$7E)) OR (ch>=$A0) StringF(obuf, 'Received: hex $\z\h[2] = \c inControl=\d\b\n', ch, ch,inControl) @@ -8433,7 +6902,10 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) statClearTime() StrCopy(connectString,'SYSOP_LOCAL') IF (scropen) THEN expressToFront() ELSE openExpressScreen() + ioFlags[IOFLAG_SER_IN]:=0 + ioFlags[IOFLAG_SER_OUT]:=0 ioFlags[IOFLAG_SCR_OUT]:=-1 + ioFlags[IOFLAG_KBD_IN]:=-1 onlineBaud:=cmds.openingBaud onlineBaudR:=cmds.openingBaud intDoReset(sopt.offHook) @@ -8447,7 +6919,10 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) statClearTime() StrCopy(connectString,'F2_LOCAL') IF (scropen) THEN expressToFront() ELSE openExpressScreen() + ioFlags[IOFLAG_SER_IN]:=0 + ioFlags[IOFLAG_SER_OUT]:=0 ioFlags[IOFLAG_SCR_OUT]:=-1 + ioFlags[IOFLAG_KBD_IN]:=-1 onlineBaud:=cmds.openingBaud onlineBaudR:=cmds.openingBaud logonType:=LOGON_TYPE_LOCAL @@ -8476,7 +6951,7 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) conPuts('[ p') conCLS() reserveForUser() - resetSystem(1) + resetSystem() ioFlags[IOFLAG_SER_IN]:=-1 ioFlags[IOFLAG_SCR_OUT]:=0 setEnvStat(ENV_RESERVE) @@ -8526,7 +7001,7 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) setEnvStat(ENV_SHELL) sendCLS() remoteShell() - resetSystem(1) + resetSystem() ioFlags[IOFLAG_SER_IN]:=-1 ioFlags[IOFLAG_SCR_OUT]:=0 IF(ioFlags[IOFLAG_FIL_IN]) THEN ioFlags[IOFLAG_FIL_IN]:=0 @@ -8562,7 +7037,7 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) loggedOnUser:=NIL loggedOnUserMisc:=NIL loggedOnUserKeys:=NIL - resetSystem(1) + resetSystem() ioFlags[IOFLAG_SER_IN]:=-1 ioFlags[IOFLAG_SCR_OUT]:=0 IF(ioFlags[IOFLAG_FIL_IN]) THEN ioFlags[IOFLAG_FIL_IN]:=0 @@ -8594,7 +7069,7 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) loggedOnUser:=NIL loggedOnUserMisc:=NIL loggedOnUserKeys:=NIL - resetSystem(1) + resetSystem() ioFlags[IOFLAG_SER_IN]:=-1 ioFlags[IOFLAG_SCR_OUT]:=0 IF(ioFlags[IOFLAG_FIL_IN]) THEN ioFlags[IOFLAG_FIL_IN]:=0 @@ -8613,7 +7088,7 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) IF (servercmd=SV_INITMODEM) OR ((wasControl=1) AND (ch="7")) servercmd:=-1 reInitModem() - resetSystem(1) + resetSystem() ENDIF ->F9 @@ -8688,14 +7163,14 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) IF ((wasControl=2) AND (ch="3")) servercmd:=-1 startASend() - RETURN TRUE,RESULT_ABORT + RETURN TRUE,RESULT_SUCCESS ENDIF ->F6 - account edit IF (servercmd=SV_ACCOUNTS) OR ((wasControl=1) AND (ch="5")) AND (loggedOnUser<>NIL) servercmd:=-1 doOnLineEdit(TRUE) - checkUserOnLine(loggedOnUser,0) + checkUserOnLine(0) convertAccess() ENDIF @@ -8776,81 +7251,6 @@ PROC processInputMessage(timeout, extsig = 0,rawMode=FALSE, allowSer=TRUE) ENDIF ENDPROC wasControl, ch -PROC convertFromBCD(inArray:PTR TO CHAR) - DEF tempBCD[8]:ARRAY - DEF bcdStr[20]:STRING - DEF i - - convertToBCD($ffffffff,tempBCD) - subBCD2(tempBCD,inArray) - IF ((tempBCD[0] AND $F0)<>0) - RETURN $ffffffff - ENDIF - formatBCD(inArray,bcdStr) -ENDPROC Val(bcdStr) - -PROC convertToBCD(invalue,outArray: PTR TO CHAR) - DEF shift,i - - FOR i:=0 TO 7 - outArray[i]:=0 - ENDFOR - - FOR shift:=0 TO 31 - FOR i:=0 TO 7 - IF (outArray[i] AND $F0)>=$50 THEN outArray[i]:=outArray[i]+$30 - IF (outArray[i] AND $F)>=$5 THEN outArray[i]:=outArray[i]+$3 - ENDFOR - FOR i:=0 TO 6 - outArray[i]:=Shl(outArray[i],1) - IF outArray[i+1] AND $80 - outArray[i]:=outArray[i] OR 1 - ENDIF - ENDFOR - outArray[7]:=Shl(outArray[7],1) - IF (invalue AND $80000000) - outArray[7]:=outArray[7] OR 1 - ENDIF - invalue:=Shl(invalue,1) - ENDFOR -ENDPROC - -PROC convertUserUDBytesTOBCD(userPtr: PTR TO user, userMiscPtr: PTR TO userMisc) - DEF updateUpload=TRUE, updateDownload=TRUE - DEF i - - FOR i:=0 TO 7 - IF (userMiscPtr.downloadBytesBCD[i]<>0) THEN updateDownload:=FALSE - IF (userMiscPtr.uploadBytesBCD[i]<>0) THEN updateUpload:=FALSE - ENDFOR - - IF updateUpload - convertToBCD(userPtr.bytesUpload,userMiscPtr.uploadBytesBCD) - ENDIF - - IF updateDownload - convertToBCD(userPtr.bytesDownload,userMiscPtr.downloadBytesBCD) - ENDIF -ENDPROC - -PROC convertConfUDBytesTOBCD(confPtr: PTR TO confBase) - DEF updateUpload=TRUE, updateDownload=TRUE - DEF i - - FOR i:=0 TO 7 - IF (confPtr.downloadBytesBCD[i]<>0) THEN updateDownload:=FALSE - IF (confPtr.uploadBytesBCD[i]<>0) THEN updateUpload:=FALSE - ENDFOR - - IF updateUpload - convertToBCD(confPtr.bytesUpload,confPtr.uploadBytesBCD) - ENDIF - - IF updateDownload - convertToBCD(confPtr.bytesDownload,confPtr.downloadBytesBCD) - ENDIF -ENDPROC - PROC loadAccount(slot,userPtr:PTR TO user, userKeysPtr:PTR TO userKeys, userMiscPtr:PTR TO userMisc) DEF l,fh DEF result @@ -8968,7 +7368,6 @@ ENDPROC RESULT_SUCCESS PROC processLoggingOff() DEF tempstr[255]:STRING DEF tempstr2[255]:STRING - DEF i DEF filetags pagedFlag:=FALSE @@ -9034,7 +7433,7 @@ PROC processLoggingOff() IF(newSinceFlag) THEN loggedOnUser.newSinceDate:=getSystemTime() - saveMsgPointers(currentConf) + saveMsgPointers(currentConf,currentMsgBase) loggedOnUser.timeLastOn:=getSystemTime() addMsgPointers() @@ -9058,7 +7457,7 @@ PROC processLoggingOff() IF (checkToolTypeExists(TOOLTYPE_BBSCONFIG,0,'MAIL_ON_LOGOFF')) AND (StrLen(mailOptions.sysopEmail)>0) StringF(tempstr,'\s: Ami-Express logoff notification',cmds.bbsName) StringF(tempstr2,'This is a notification that \s from \s has logged off\n\n',loggedOnUser.name,loggedOnUser.location) - sendMail(tempstr,tempstr2,TRUE, mailOptions.sysopEmail) + sendMail(tempstr,tempstr2,FALSE, NIL,0,mailOptions.sysopEmail) ENDIF StrCopy(reservedName,'') @@ -9095,9 +7494,12 @@ PROC processLoggingOff() serialCacheEnabled:=FALSE flushSerialCache() + confNameType:=NAME_TYPE_USERNAME loggedOnUser:=NIL loggedOnUserKeys:=NIL loggedOnUserMisc:=NIL + currentConf:=0 + currentMsgBase:=0 sendQuietFlag(quietFlag) Delay(50) stateData:=0 @@ -9276,8 +7678,7 @@ PROC clearTempSecurityFlags(securityFlag) ENDPROC PROC checkSecurity(securityFlag) - DEF res - IF (loggedOnUser=NIL) OR (acsLevel=-1) THEN RETURN FALSE + IF (loggedOnUser=NIL) THEN RETURN FALSE IF (StrLen(securityFlags)>securityFlag) IF securityFlags[securityFlag]<>"?" THEN RETURN (securityFlags[securityFlag]="T") @@ -9304,29 +7705,32 @@ PROC checkSecurity(securityFlag) RETURN TRUE ENDIF - IF overrideDefaultAccess=FALSE + IF (overrideDefaultAccess=FALSE) AND (securityFlag<>ACS_OVERRIDE_DEFAULTS) IF checkToolTypeExists(TOOLTYPE_DEFAULT_ACCESS,0,ListItem(securityNames,securityFlag)) THEN RETURN TRUE ENDIF + IF (acsLevel=-1) THEN RETURN FALSE + IF userSpecificAccess IF checkToolTypeExists(TOOLTYPE_USER_ACCESS,0,ListItem(securityNames,securityFlag)) THEN RETURN TRUE ENDIF ENDPROC checkToolTypeExists(TOOLTYPE_ACCESS,acsLevel,ListItem(securityNames,securityFlag)) -PROC checkConfAccess(confNum) +PROC checkConfAccess(confNum,user=NIL:PTR TO user) DEF ttname[20]:STRING - IF (loggedOnUser=NIL) THEN RETURN FALSE + IF user=NIL THEN user:=loggedOnUser + IF (user=NIL) THEN RETURN FALSE - IF isConfAccessAreaName(loggedOnUser)=FALSE - IF (confNum<=StrLen(loggedOnUser.conferenceAccess)) - IF loggedOnUser.conferenceAccess[confNum-1]="X" THEN RETURN TRUE + IF isConfAccessAreaName(user)=FALSE + IF (confNum<=StrLen(user.conferenceAccess)) + IF user.conferenceAccess[confNum-1]="X" THEN RETURN TRUE ENDIF RETURN FALSE ENDIF StringF(ttname,'Conf.\d',confNum) -ENDPROC checkToolTypeExists(TOOLTYPE_AREA,loggedOnUser.conferenceAccess,ttname) +ENDPROC checkToolTypeExists(TOOLTYPE_AREA,user.conferenceAccess,ttname) PROC myError(errorCode) DEF errorString[100]:STRING @@ -9398,45 +7802,49 @@ PROC getInverse(cn) ENDPROC j PROC masterLoadPointers(hoozer: PTR TO user) - DEF i,cb: PTR TO confBase + DEF i,m,cb: PTR TO confBase FOR i:=1 TO cmds.numConf - cb:=confBases.item(i-1) - loadConfDB(hoozer.slotNumber,i,cb,TRUE) + FOR m:=1 TO getConfMsgBaseCount(i) + cb:=confBases.item(getConfIndex(i,m)) + loadConfDB(hoozer.slotNumber,i,m,cb,TRUE) + ENDFOR ENDFOR ENDPROC PROC clearMsgPointers() DEF cb: PTR TO confBase - DEF i,j, defaultmask + DEF i,j,m,defaultmask FOR i:=1 TO cmds.numConf - cb:=confBases.item(i-1) - cb.bytesDownload:=0 - cb.bytesUpload:=0 - FOR j:=0 TO 7 - cb.downloadBytesBCD[j]:=0 - cb.uploadBytesBCD[j]:=0 + FOR m:=1 TO getConfMsgBaseCount(i) + cb:=confBases.item(getConfIndex(i,m)) + cb.bytesDownload:=0 + cb.bytesUpload:=0 + FOR j:=0 TO 7 + cb.downloadBytesBCD[j]:=0 + cb.uploadBytesBCD[j]:=0 + ENDFOR + cb.upload:=0 + cb.downloads:=0 + cb.ratioType:=0 + cb.ratio:=0 + cb.messagesPosted:=0 + cb.lastEMail:=0 + cb.confYM:=0 + cb.confRead:=0 + defaultmask:=0 + + IF checkToolTypeExists(TOOLTYPE_CONF,i,'DEFAULT_NEWSCAN') THEN defaultmask:=defaultmask OR MAIL_SCAN_MASK + IF checkToolTypeExists(TOOLTYPE_CONF,i,'DEFAULT_NEW_FILES') THEN defaultmask:=defaultmask OR FILE_SCAN_MASK + IF checkToolTypeExists(TOOLTYPE_CONF,i,'DEFAULT_ZOOM') THEN defaultmask:=defaultmask OR ZOOM_SCAN_MASK + cb.handle[0]:=defaultmask ENDFOR - cb.upload:=0 - cb.downloads:=0 - cb.ratioType:=0 - cb.ratio:=0 - cb.messagesPosted:=0 - cb.lastEMail:=0 - cb.confYM:=0 - cb.confRead:=0 - defaultmask:=0 - - IF checkToolTypeExists(TOOLTYPE_CONF,i,'DEFAULT_NEWSCAN') THEN defaultmask:=defaultmask OR MAIL_SCAN_MASK - IF checkToolTypeExists(TOOLTYPE_CONF,i,'DEFAULT_NEW_FILES') THEN defaultmask:=defaultmask OR FILE_SCAN_MASK - IF checkToolTypeExists(TOOLTYPE_CONF,i,'DEFAULT_ZOOM') THEN defaultmask:=defaultmask OR ZOOM_SCAN_MASK - cb.handle[0]:=defaultmask ENDFOR ENDPROC PROC addMsgPointers() - DEF i + DEF i,m DEF cb: PTR TO confBase IF loggedOnUser.slotNumber<=0 THEN RETURN @@ -9454,34 +7862,39 @@ PROC addMsgPointers() loggedOnUser.messagesPosted:=0 FOR i:=1 TO cmds.numConf - cb:=confBases.item(i-1) - IF (readToolTypeInt(TOOLTYPE_CONF,i,'CONFDB_SHARED')>0) AND (checkConfAccess(i)) - addBCD2(loggedOnUserMisc.downloadBytesBCD,cb.downloadBytesBCD) - addBCD2(loggedOnUserMisc.uploadBytesBCD,cb.uploadBytesBCD) - loggedOnUser.bytesDownload:=convertFromBCD(loggedOnUserMisc.downloadBytesBCD) - loggedOnUser.bytesUpload:=convertFromBCD(loggedOnUserMisc.uploadBytesBCD) - loggedOnUser.uploads:=loggedOnUser.uploads+cb.upload - loggedOnUser.downloads:=loggedOnUser.downloads+cb.downloads - ENDIF - loggedOnUser.messagesPosted:=loggedOnUser.messagesPosted+cb.messagesPosted + FOR m:=1 TO getConfMsgBaseCount(i) + cb:=confBases.item(getConfIndex(i,m)) + IF (checkSecurity(ACS_CONFERENCE_ACCOUNTING)) AND (readToolTypeInt(TOOLTYPE_CONF,i,'CONFDB_SHARED')<=0) AND (checkConfAccess(i)) + addBCD2(loggedOnUserMisc.downloadBytesBCD,cb.downloadBytesBCD) + addBCD2(loggedOnUserMisc.uploadBytesBCD,cb.uploadBytesBCD) + loggedOnUser.bytesDownload:=convertFromBCD(loggedOnUserMisc.downloadBytesBCD) + loggedOnUser.bytesUpload:=convertFromBCD(loggedOnUserMisc.uploadBytesBCD) + loggedOnUser.uploads:=loggedOnUser.uploads+cb.upload + loggedOnUser.downloads:=loggedOnUser.downloads+cb.downloads + ENDIF + loggedOnUser.messagesPosted:=loggedOnUser.messagesPosted+cb.messagesPosted + ENDFOR ENDFOR ENDPROC PROC masterSavePointers(hoozer: PTR TO user) - DEF i,cb: PTR TO confBase + DEF i,m,cb: PTR TO confBase FOR i:=1 TO cmds.numConf - cb:=confBases.item(i-1) - saveConfDB(hoozer.slotNumber,i,cb,TRUE) + FOR m:=1 TO getConfMsgBaseCount(i) + cb:=confBases.item(getConfIndex(i,m)) + saveConfDB(hoozer.slotNumber,i,m,cb,TRUE) + ENDFOR ENDFOR ENDPROC -PROC getMailStatFile(confNum) +PROC getMailStatFile(confNum,msgBaseNum) DEF fd, stat DEF string[100]:STRING - StringF(string,'\sMsgBase/\s',getConfLocation(confNum),'MailStats') + getMsgBaseLocation(confNum,msgBaseNum,string) + StrAdd(string,'MailStats') fd:=Open(string,OLDFILE) IF(fd=0) @@ -9525,7 +7938,7 @@ PROC parseList(liststring,list:PTR TO stringlist) spacepos:=InStr(liststring,' ') IF spacepos>=0 WHILE(spacepos>=0) - MidStr(tempstr,liststring,startpos,spacepos-startpos) + midStr2(tempstr,liststring,startpos,spacepos-startpos) UpperStr(tempstr) newitem:=TrimStr(tempstr) IF StrLen(newitem)>0 THEN list.add(newitem) @@ -9534,7 +7947,7 @@ PROC parseList(liststring,list:PTR TO stringlist) spacepos:=InStr(liststring,' ',startpos) ENDWHILE IF startpos0 THEN list.add(newitem) @@ -9565,12 +7978,15 @@ ENDPROC FALSE PROC commentToSYSOP() DEF stat DEF str[255]:STRING + DEF oldConf,oldMsgBase - stat:=chooseAName(cmds.sysopName,tempUser,tempUserKeys,tempUserMisc,1) + stat:=captureRealAndInternetNames(currentConf,currentMsgBase) + IF stat<0 THEN RETURN stat + + stat:=loadAccount(1,tempUser,tempUserKeys,tempUserMisc) IF(stat<0) RETURN stat ENDIF - stat:=loadAccount(tempUser.slotNumber,tempUser,tempUserKeys,tempUserMisc) SELECT confNameType CASE NAME_TYPE_USERNAME @@ -9596,7 +8012,14 @@ PROC commentToSYSOP() strCpy(mailHeader.subject,str,30) mailHeader.status:="R" comment:=1 - stat:=callMsgFuncs(MAIL_CREATE,0) + oldConf:=currentConf + oldMsgBase:=currentMsgBase + IF currentConf=0 THEN currentConf:=1 + IF currentMsgBase=0 THEN currentMsgBase:=1 + stat:=callMsgFuncs(MAIL_CREATE,0,0) + currentConf:=oldConf + currentMsgBase:=oldMsgBase + comment:=0 IF(stat<0) THEN RETURN stat ENDPROC RESULT_SUCCESS @@ -9616,7 +8039,7 @@ PROC firstCharValue(teststring) ENDPROC teststring[0] PROC stringCompare(nam: PTR TO CHAR,pat: PTR TO CHAR) - DEF i,p,loop=TRUE + DEF p,loop=TRUE WHILE loop IF charToLower(nam[0])=charToLower(pat[0]) @@ -9647,17 +8070,18 @@ ENDPROC RESULT_FAILURE PROC listMSGs(gfh) DEF tempStr[255]:STRING - DEF stat,start,r + DEF r DEF oldMsgNum DEF mailFlag=0 DEF mailStatus[10]:STRING + DEF cb:PTR TO confBase nonStopDisplayFlag:=FALSE oldMsgNum:=msgNum StringF(tempStr,'Starting message [\d]: ',mailStat.lowestNotDel) aePuts(tempStr) - stat:=lineInput('','',10,INPUT_TIMEOUT,tempStr) + lineInput('','',10,INPUT_TIMEOUT,tempStr) IF StrLen(tempStr)=0 msgNum:=mailStat.lowestNotDel r:=1 @@ -9673,10 +8097,12 @@ PROC listMSGs(gfh) IF(msgNum>=mailStat.highMsgNum) JUMP listOUT ENDIF - stat:=loadMessageHeader(gfh) + loadMessageHeader(gfh) IF(mailHeader.status="D") THEN JUMP listNextMSG - IF(((stringCompare(mailHeader.toName,confMailName)=RESULT_SUCCESS) OR (stringCompare(mailHeader.toName,'eall')=RESULT_SUCCESS))) + cb:=confBases.item(getConfIndex(currentConf,currentMsgBase)) + + IF(((stringCompare(mailHeader.toName,confMailName)=RESULT_SUCCESS) OR (stringCompare(mailHeader.toName,'eall')=RESULT_SUCCESS) OR ((stringCompare(mailHeader.toName,'all')=RESULT_SUCCESS) AND (cb.handle[0] AND MAILSCAN_ALL)))) IF(mailFlag=0) aePuts('\b\n\b\n') aePuts('Msg Type From Subject \b\n') @@ -9755,6 +8181,7 @@ PROC displayMessage(gfh) aePuts(str) StringF(str,'Subject: \s\b\n\b\n',mailHeader.subject) aePuts(str) + lineCount:=lineCount+5 alreadyRecvd:=mailHeader.recv @@ -9772,11 +8199,11 @@ PROC displayMessage(gfh) IF(nonStopMail) nonStopDisplayFlag:=TRUE mcioff:=TRUE - displayFile(tempStr,TRUE,FALSE) + displayFile(tempStr,TRUE,FALSE,FALSE) IF(stat=RESULT_FAILURE) THEN nonStopMail:=FALSE ELSE mcioff:=TRUE - displayFile(tempStr,TRUE) + displayFile(tempStr,TRUE,TRUE,FALSE) ENDIF mcioff:=FALSE stat:=checkAttachedFile(mailHeader.msgNumb,1) @@ -9977,12 +8404,12 @@ ENDPROC PROC debugLog(logType,logline:PTR TO CHAR) DEF buff[255]:STRING - DEF currTime + DEF currTime,currTick IF consoleDebugLevel>=logType - currTime:=getSystemTime() + currTime,currTick:=getSystemTime() - WriteF('\d \s\n',currTime,logline) + WriteF('\d.\z\l\d[2] \s\n',currTime,currTick,logline) ENDIF IF debugLogLevel>=logType @@ -10416,68 +8843,104 @@ PROC restricted(str: PTR TO CHAR) ENDIF ENDPROC bad -PROC deleteMsgFiles(num:LONG) +PROC deleteMsgFiles(num:LONG,attachType) DEF image[100]:STRING DEF fBlock:PTR TO fileinfoblock DEF fLock DEF str[100]:STRING + DEF f StringF(str,'\sF\d',msgBaseLocation,num) - - IF(fBlock:=AllocDosObject(DOS_FIB,NIL)) - IF(fLock:=Lock(str,ACCESS_READ)) - - IF(Examine(fLock,fBlock)) - WHILE(ExNext(fLock,fBlock)) - StringF(image,'\sF\d/\s',msgBaseLocation,num,fBlock.filename) - SetProtection(image,FIBF_OTR_DELETE) - DeleteFile(image) + IF attachType=2 + IF(fBlock:=AllocDosObject(DOS_FIB,NIL)) + IF(fLock:=Lock(str,ACCESS_READ)) + + IF(Examine(fLock,fBlock)) + WHILE(ExNext(fLock,fBlock)) + StringF(image,'\sF\d/\s',msgBaseLocation,num,fBlock.filename) + SetProtection(image,FIBF_OTR_DELETE) + DeleteFile(image) + ENDWHILE + aePuts('\b\n') + ENDIF + UnLock(fLock) + ENDIF + FreeDosObject(DOS_FIB,fBlock) + SetProtection(str,FIBF_OTR_DELETE) + DeleteFile(str) + ENDIF + ENDIF + + IF attachType=3 + StringF(image,'\sA\d',msgBaseLocation,num) + f:=Open(image,MODE_OLDFILE) + IF f<>0 + ReadStr(f,str) + IF StrCmp(str,'Y') + aePuts('\b\nDeleted attached file(s):\b\n') + WHILE(ReadStr(f,str)<>-1) OR (StrLen(str)>0) + SetProtection(str,FIBF_OTR_DELETE) + DeleteFile(str) + aePuts(str) + aePuts('\b\n') ENDWHILE - aePuts('\b\n') ENDIF - UnLock(fLock) + Close(f) + SetProtection(image,FIBF_OTR_DELETE) + DeleteFile(image) ENDIF - FreeDosObject(DOS_FIB,fBlock) - SetProtection(str,FIBF_OTR_DELETE) - DeleteFile(str) ENDIF - ENDPROC - -PROC attachMsgFiles(num: LONG,s:PTR TO CHAR) +PROC attachMsgFiles(num: LONG,s:PTR TO CHAR,attachType: LONG) DEF image[100]:STRING DEF str[100]:STRING DEF fBlock: PTR TO fileinfoblock DEF fLock DEF cnt=0 + DEF f StrCopy(s,'') StringF(str,'\sF\d',msgBaseLocation,num) - - IF(fBlock:=AllocDosObject(DOS_FIB,NIL)) - IF(fLock:=Lock(str,ACCESS_READ)) - IF(Examine(fLock,fBlock)) - WHILE(ExNext(fLock,fBlock)) - StringF(image,'\sF\d/\s ',msgBaseLocation,num,fBlock.filename) - IF(StrLen(image)+StrLen(s)<1024) - aePuts('\b\nFlagging >:') - aePuts(fBlock.filename) - cnt++ - StrAdd(s,image) - ENDIF - ENDWHILE - aePuts('\b\n') + IF attachType=2 + IF(fBlock:=AllocDosObject(DOS_FIB,NIL)) + IF(fLock:=Lock(str,ACCESS_READ)) + IF(Examine(fLock,fBlock)) + WHILE(ExNext(fLock,fBlock)) + StringF(image,'\sF\d/\s ',msgBaseLocation,num,fBlock.filename) + IF((StrLen(image)+StrLen(s))<1024) + aePuts('\b\nFlagging >:') + aePuts(fBlock.filename) + cnt++ + StrAdd(s,image) + ENDIF + ENDWHILE + aePuts('\b\n') + ENDIF + UnLock(fLock) ENDIF - UnLock(fLock) + FreeDosObject(DOS_FIB,fBlock) + ENDIF + ENDIF + + IF attachType=3 + StringF(image,'\sA\d',msgBaseLocation,num) + f:=Open(image,MODE_OLDFILE) + IF f<>0 + ReadStr(f,str) ->skip delete flag + WHILE(ReadStr(f,str)<>-1) OR (StrLen(str)>0) + IF((StrLen(str)+StrLen(s)+1)<1024) + cnt++ + StrAdd(s,image) + ENDIF + ENDWHILE + Close(f) ENDIF - FreeDosObject(DOS_FIB,fBlock) ENDIF IF cnt=0 aePuts('File attachment not found\b\n') ENDIF - ENDPROC @@ -10487,7 +8950,7 @@ PROC checkAttachedFile(msgnumb,flag) DEF fBlock:PTR TO fileinfoblock DEF fLock DEF filetype=0 - DEF tempStr[255]:STRING + DEF tempStr[1024]:STRING StrCopy(tempStr,'') @@ -10504,7 +8967,7 @@ PROC checkAttachedFile(msgnumb,flag) IF(Examine(fLock,fBlock)) IF(StrLen(fBlock.comment)>0) StrCopy(tempStr,fBlock.comment) - filetype:=1 + filetype:=1 ->single attached file referenced in file comment ENDIF ENDIF @@ -10514,7 +8977,7 @@ PROC checkAttachedFile(msgnumb,flag) IF(fLock:=Lock(str,ACCESS_READ)) IF(Examine(fLock,fBlock)) IF(ExNext(fLock,fBlock)) - filetype:=2 + filetype:=2 ->sub folder containing attached files ENDIF ENDIF UnLock(fLock) @@ -10523,7 +8986,8 @@ PROC checkAttachedFile(msgnumb,flag) ENDIF FreeDosObject(DOS_FIB,fBlock) ENDIF - + StringF(str,'\sA\d',msgBaseLocation,msgnumb) + IF fileExists(str) THEN filetype:=3 ->corresponding A file containing attachment file details IF(filetype) IF(flag) @@ -10534,12 +8998,12 @@ PROC checkAttachedFile(msgnumb,flag) IF((stat="n") OR (stat="N")) THEN aePuts('No\b\n') IF((stat="y") OR (stat="Y")) aePuts('Yes\b\n\b\n') - IF(filetype=2) THEN attachMsgFiles(msgnumb,tempStr) + IF(filetype<>1) THEN attachMsgFiles(msgnumb,tempStr,filetype) downloadFile(tempStr) ENDIF IF((stat="g") OR (stat="G")) aePuts('Goodbye\b\n\b\n') - IF(filetype=2) THEN attachMsgFiles(msgnumb,tempStr) + IF(filetype<>1) THEN attachMsgFiles(msgnumb,tempStr,filetype) downloadFile(tempStr) aePuts('\b\n') stat:=pGoodbye() @@ -10549,7 +9013,7 @@ PROC checkAttachedFile(msgnumb,flag) stat:=0 aePuts('\b\n') ELSE - IF(filetype=2) THEN deleteMsgFiles(msgnumb) + IF(filetype=1) stat:=isupper(tempStr[0]) IF(stat) SetProtection(tempStr,FIBF_OTR_DELETE) @@ -10557,9 +9021,11 @@ PROC checkAttachedFile(msgnumb,flag) aePuts('\b\nDeleted attached file(s) ') aePuts(tempStr) ENDIF + ELSE + deleteMsgFiles(msgnumb,filetype) ENDIF ENDIF - + ENDIF ENDPROC RESULT_SUCCESS PROC forwardMSG(gfh) @@ -10665,7 +9131,7 @@ PROC replyToMSG(gfh) ENDPROC RESULT_SUCCESS PROC checkToForward(str,name,check) - DEF stat,error + DEF error DEF tempStr[255]:STRING error:=0 @@ -10675,7 +9141,7 @@ PROC checkToForward(str,name,check) IF(check) loadAccount(1,tempUser,tempUserKeys,tempUserMisc) IF(stringCompare(name,tempUser.name)=RESULT_SUCCESS) - IF(stat:=findUserFromName(1,confNameType,str,tempUser,tempUserKeys,tempUserMisc)) + IF(findUserFromName(1,confNameType,str,tempUser,tempUserKeys,tempUserMisc)) SELECT confNameType CASE NAME_TYPE_USERNAME StringF(tempStr,' Forwarding mail To: \s\b\n',tempUserKeys.userName) @@ -10690,7 +9156,7 @@ PROC checkToForward(str,name,check) ENDIF ENDIF ELSE - IF(stat:=findUserFromName(1,confNameType,str,tempUser,tempUserKeys,tempUserMisc)) + IF(findUserFromName(1,confNameType,str,tempUser,tempUserKeys,tempUserMisc)) SELECT confNameType CASE NAME_TYPE_USERNAME StringF(tempStr,' Forwarding mail To: \s\b\n',tempUserKeys.userName) @@ -10758,49 +9224,6 @@ PROC msgToHeader() aePuts(' To: (Enter)=''ALL''? ') ENDPROC -PROC processLine(pat, vorig, dest) - DEF i,i2,nff - DEF rep[80]:STRING - DEF orig[100] : STRING - - StrCopy(orig,vorig,ALL) - FOR i:=0 TO StrLen(pat)-1 - EXIT pat[i]=";" - ENDFOR - - IF(i>=StrLen(pat)) THEN RETURN 0 - - StrCopy(rep,pat+i+1,ALL) - SetStr(pat,i) - - StrCopy(dest,'',ALL) - - FOR i:=0 TO StrLen(orig)-StrLen(pat) - nff:=1 - IF(pat[0]=orig[i]) - nff:=0 - i2:=i+1 - WHILE((i2-i)orig[i2]) - nff:=1 - JUMP wbrk - ENDIF - i2++ - ENDWHILE -wbrk: - ENDIF - IF(nff<>1) - SetStr(orig,i) - StrCopy(dest,orig,ALL) - StrAdd(dest,rep) - IF(i2''=DIR): ') - stat:=lineInput('','',250,INPUT_TIMEOUT,attachedFile) - IF(stat<0) THEN RETURN stat - IF((attachedFile[0]="5") AND (attachedFile[1]=" ")) - myDirAnyWhere(attachedFile) - StrCopy(attachedFile,'') - JUMP cont2 - ENDIF + IF(ximPort=CONSOLE_PORT) + asl(NIL,attachedFiles) + ELSE + aePuts('\b\nEnter path/filename to attach (''5 ''=DIR): ') + stat:=lineInput('','',250,INPUT_TIMEOUT,attachedFile) + IF(stat<0) THEN RETURN stat + IF((attachedFile[0]="5") AND (attachedFile[1]=" ")) + myDirAnyWhere(attachedFile) + StrCopy(attachedFile,'') + JUMP cont2 ENDIF + attachedFiles.clear() + attachedFiles.add(attachedFile) + ENDIF + FOR i:=attachedFiles.count()-1 TO 0 STEP -1 + StrCopy(attachedFile,attachedFiles.item(i)) IF(StrLen(attachedFile)>0) - LowerStr(attachedFile) IF(findAssign(attachedFile)) aePuts('\b\nDevice not Mounted.\b\n') aePuts('\b\n') - StrCopy(attachedFile,'') - JUMP cont2 - ENDIF - IF(restricted(attachedFile)) - StrCopy(attachedFile,'') - JUMP cont2 - ELSE - aePuts('Delete file when message is deleted ') - stat:=yesNo(2) - IF(stat<0) THEN RETURN stat - LowerStr(attachedFile) - IF(stat) - attachedFile[0]:=charToUpper(attachedFile[0]) - ENDIF + attachedFiles.remove(i) ENDIF + IF(restricted(attachedFile)) THEN attachedFiles.remove(i) ENDIF - EXIT TRUE - ENDWHILE + ENDFOR + IF attachedFiles.count()>0 + aePuts('Delete file(s) when message is deleted ') + stat:=yesNo(2) + IF(stat<0) + attachedFiles.clear() + RETURN stat + ENDIF + + IF(stat) + attachedFiles.insert(0,'Y') + ELSE + attachedFiles.insert(0,'N') + ENDIF + JUMP cont2 + ENDIF ELSE higherAccess() ENDIF @@ -11378,10 +9806,72 @@ loopHere: UNTIL stat<0 ENDPROC stat +PROC getMsgId() + DEF lock, loop, error + DEF fh,v,r,c + DEF fname[255]:STRING + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + + loop:=0 + StringF(fname,'\smsgidnr.lck',cmds.bbsLoc) + REPEAT + lock:=Lock(fname,ACCESS_WRITE) + IF(lock=0) + error:=IoErr() + IF(error=205) THEN createFile(fname) + Delay(120) + aePuts('.') + ENDIF + UNTIL((lock<>0) OR (loop++>=30)) + + IF(lock=0) + StringF(tempstr,'\tError \d trying to Lock message serial file',IoErr()) + callersLog(tempstr) + RETURN FALSE,0 + ENDIF + + StringF(fname,'\smsgidnr.nxt',cmds.bbsLoc) + + fh:=Open(fname,MODE_OLDFILE) + IF fh>0 + ReadStr(fh,tempstr) + Close(fh) + ENDIF + StringF(tempstr2,'$\s',tempstr) + v,r:=Val(tempstr2) + c:=getSystemTime() + IF r<>9 THEN v:=c + r:=v + v++ + IF c>v THEN v:=c + + fh:=Open(fname,MODE_NEWFILE) + IF fh>0 + StringF(tempstr,'\z\h[8]\n',v) + Write(fh,tempstr,StrLen(tempstr)) + Close(fh) + ENDIF + + UnLock(lock) +ENDPROC TRUE,r + +PROC saveAttachList(fname:PTR TO CHAR) + DEF f,i + IF((f:=Open(fname,MODE_NEWFILE)))=0 + aePuts('Failed!\b\n\b\n') + RETURN + ENDIF + FOR i:=0 TO attachedFiles.count()-1 + fileWriteLn(f,attachedFiles.item(i)) + ENDFOR + Close(f) +ENDPROC + PROC saveNewMSG(gfh,mh:PTR TO mailHeader) DEF msgbaselock - DEF f,i,stat - DEF rzmsglock + DEF f,i,stat,id + DEF rzmsglock,lock DEF string[255]:STRING DEF tempStr[255]:STRING DEF tempStr2[255]:STRING @@ -11390,8 +9880,43 @@ PROC saveNewMSG(gfh,mh:PTR TO mailHeader) mh.recv:=0 mh.msgDate:=getSystemTime() strCpy(mh.fromName,confMailName,31) + IF(msgbaselock:=lockMsgBase()) - getMailStatFile(currentConf) + + StringF(tempStr,'EXTSEND.\d',currentMsgBase) + IF checkToolTypeExists(TOOLTYPE_MSGBASE,currentConf,tempStr) AND (comment=0) + getMsgBaseLocation(currentConf,currentMsgBase,tempStr) + StrAdd(tempStr,'EXT-OUT') + IF (lock:=CreateDir(tempStr)) THEN UnLock(lock) + i:=0 + REPEAT + i++ + StringF(tempStr2,'\s/\d.msg',tempStr,i) + UNTIL fileExists(tempStr2)=FALSE + f:=Open(tempStr2,MODE_NEWFILE) + IF f>0 + fileWriteLn(f,confMailName) + fileWriteLn(f,mh.toName) + fileWriteLn(f,mh.subject) + formatLongDateTime2(mh.msgDate,tempStr," ") + fileWriteLn(f,tempStr) + stat,id:=getMsgId() + IF stat + StringF(tempStr,'\d',id) + ELSE + StrCopy(tempStr,'') + ENDIF + fileWriteLn(f,tempStr) + + FOR i:=0 TO lines-1 + StringF(tempStr2,'\s\n',msgBuf.item(i)) + Write(f,tempStr2,StrLen(tempStr2)) + ENDFOR + Close(f) + ENDIF + ENDIF + + getMailStatFile(currentConf,currentMsgBase) mh.msgNumb:=mailStat.highMsgNum stat:=saveMessageHeader(gfh,mh) IF(stat<>RESULT_FAILURE) @@ -11410,9 +9935,10 @@ PROC saveNewMSG(gfh,mh:PTR TO mailHeader) Close(f) aePuts('done!\b\n\b\n') - IF(StrLen(attachedFile)<>0) - SetComment(tempStr,attachedFile) - StrCopy(attachedFile,'',ALL) + IF attachedFiles.count()>0 + StringF(tempStr,'\sA\d',msgBaseLocation,mh.msgNumb) + saveAttachList(tempStr) + attachedFiles.clear() ENDIF ELSE aePuts('Failed!\b\n\b\n') @@ -11435,19 +9961,19 @@ PROC saveNewMSG(gfh,mh:PTR TO mailHeader) IF (checkToolTypeExists(TOOLTYPE_BBSCONFIG,0,'MAIL_ON_SYSOP_COMMENT')) AND (StrLen(mailOptions.sysopEmail)>0) StringF(tempStr,'\s: Ami-Express sysop message notification',cmds.bbsName) StringF(tempStr2,'This is a notification that \s has sent you a message.\n\nSubject: \s\n\n',mh.fromName,mh.subject) - sendMail(tempStr,tempStr2,TRUE, mailOptions.sysopEmail) + sendMail(tempStr,tempStr2,TRUE, msgBuf,lines,mailOptions.sysopEmail) ENDIF ENDIF IF(rzmsg) StringF(tempStr,'\sF\d',msgBaseLocation,mh.msgNumb) - IF(rzmsglock=CreateDir(tempStr)) + IF(rzmsglock:=CreateDir(tempStr)) UnLock(rzmsglock) ENDIF setEnvStat(ENV_UPLOADING) aePuts('\b\n') /* 11w */ bgFileCheck:=FALSE - stat:=uploadaFile(0,'','') + stat:=uploadaFile(0,'') rzmsg:=NIL StringF(tempStr,'\sF\d',msgBaseLocation,mh.msgNumb) SetProtection(tempStr,FIBF_OTR_DELETE) @@ -11473,15 +9999,12 @@ PROC enterMSG(gfh) DEF firstparam DEF tempStr[255]:STRING DEF exit,i,i2,i3,stat - DEF t - + DEF extSend + aFlag:=0 - StrCopy(attachedFile,'',ALL) - IF(comment=1) - comment:=0 - JUMP skipAll - ENDIF + attachedFiles.clear() + IF(comment=1) THEN JUMP skipAll IF(replyFlag=1) JUMP skipBegin @@ -11508,6 +10031,9 @@ PROC enterMSG(gfh) skipEntry: + StringF(tempStr,'EXTSEND.\d',currentMsgBase) + extSend:=checkToolTypeExists(TOOLTYPE_MSGBASE,currentConf,tempStr) + IF checkSecurity(ACS_CENSORED) mailHeader.status:="p" ELSE @@ -11523,6 +10049,11 @@ skipEntry: stat:=StrCmp(str,'eall',4) /* looking for eall */ IF(stat) + IF extSend + aePuts('\b\nCan''t use EALL in external message bases!!\b\n\b\n') + RETURN RESULT_FAILURE + ENDIF + IF(checkSecurity(ACS_EALL_MESSAGES)) aFlag:=2 strCpy(mailHeader.toName,'EALL',ALL) @@ -11534,23 +10065,26 @@ skipEntry: stat:=StrCmp(str,'sysop',5) IF(stat) loadAccount(1,tempUser,tempUserKeys,tempUserMisc) + stat:=0 ELSE - stat:=chooseAName(mailHeader.toName,tempUser,tempUserKeys,tempUserMisc,1) - IF(stat<0) + stat:=chooseAName(mailHeader.toName,tempUser,tempUserKeys,tempUserMisc,IF extSend THEN 0 ELSE 1) + IF(stat<0) AND (extSend=FALSE) RETURN stat ENDIF ENDIF - SELECT confNameType - CASE NAME_TYPE_USERNAME - strCpy(mailHeader.toName,tempUserKeys.userName,31) - CASE NAME_TYPE_REALNAME - strCpy(mailHeader.toName,tempUserMisc.realName,26) - CASE NAME_TYPE_INTERNETNAME - strCpy(mailHeader.toName,tempUserMisc.internetName,10) - ENDSELECT - IF(isTempConf(tempUser,currentConf-1)=FALSE) - aePuts('\b\nUser does not have access to this conference!\b\n\b\n') - RETURN RESULT_FAILURE + IF stat>=0 + SELECT confNameType + CASE NAME_TYPE_USERNAME + strCpy(mailHeader.toName,tempUserKeys.userName,31) + CASE NAME_TYPE_REALNAME + strCpy(mailHeader.toName,tempUserMisc.realName,26) + CASE NAME_TYPE_INTERNETNAME + strCpy(mailHeader.toName,tempUserMisc.internetName,10) + ENDSELECT + IF(checkConfAccess(currentConf,tempUser)=FALSE) + aePuts('\b\nUser does not have access to this conference!\b\n\b\n') + RETURN RESULT_FAILURE + ENDIF ENDIF ENDIF ENDIF @@ -11570,7 +10104,7 @@ skipEntry: ENDIF skipBegin: - IF(aFlag=FALSE) + IF(aFlag=FALSE) AND (extSend=FALSE) aePuts(' Private ') stat:=yesNo(2) IF(stat<0) @@ -11899,8 +10433,11 @@ contloop: IF(((str[0]="r") OR (str[0]="R"))) IF((privateFlag=0) OR ((stringCompare(mailHeader.toName,confMailName)=RESULT_SUCCESS)) OR (StrCmp(mailHeader.toName,'EALL',4))) - stat:=replyToMSG(gfh) - RETURN RESULT_SUCCESS + stat:=captureRealAndInternetNames(currentConf,currentMsgBase) + IF stat=RESULT_SUCCESS + stat:=replyToMSG(gfh) + RETURN RESULT_SUCCESS + ENDIF ELSE aePuts('Not your message.\b\n') JUMP contloop @@ -12086,7 +10623,6 @@ ENDPROC RESULT_SUCCESS PROC findUserFromNumber(start,hoozer:PTR TO userKeys) DEF fh - DEF tempstr[255]:STRING fh:=Open(userKeysFile,MODE_OLDFILE) IF(fh=0) THEN RETURN 0 Seek(fh,(start-1)*SIZEOF userKeys,OFFSET_BEGINNING) @@ -12216,24 +10752,8 @@ PROC chooseAName(s,hoozer: PTR TO user,hoozer2: PTR TO userKeys,hoozer3: PTR TO loadAccount(hoozer2.number,hoozer,hoozer2,hoozer3) ENDPROC 1 -PROC isTempConf(user: PTR TO user,conf) - DEF tooltypeName[10]:STRING - - IF isConfAccessAreaName(user)=FALSE - IF (conf0 + StringF(tempStr,'Scanning Conference: \s [\s] - ',currentConfName,msgBaseName) + ELSE + StringF(tempStr,'Scanning Conference: \s - ',currentConfName) + ENDIF aePuts(tempStr) ENDIF @@ -12364,7 +10893,10 @@ PROC searchNewMail(gfh, cn) stat:=loadMessageHeader(gfh) IF(mailHeader.status="D") THEN JUMP getNextMSG - IF(((stringCompare(mailHeader.toName,confMailName)=RESULT_SUCCESS) OR (stringCompare(mailHeader.toName,'eall')=RESULT_SUCCESS))) AND (mailHeader.recv=0) + cb:=confBases.item(getConfIndex(cn,msgBaseNum)) + + IF(((stringCompare(mailHeader.toName,confMailName)=RESULT_SUCCESS) OR (stringCompare(mailHeader.toName,'eall')=RESULT_SUCCESS) OR ((stringCompare(mailHeader.toName,'all')=RESULT_SUCCESS) AND (cb.handle[0] AND MAILSCAN_ALL)))) AND (mailHeader.recv=0) + IF(currentConf=0) IF(mailFlag=0) @@ -12406,7 +10938,7 @@ getOUT: WHILE (msgNum"D") - IF(((stringCompare(mailHeader.toName,confMailName)=RESULT_SUCCESS) OR (stringCompare(mailHeader.toName,'eall')=RESULT_SUCCESS))) AND (mailHeader.recv=0) + IF(((stringCompare(mailHeader.toName,confMailName)=RESULT_SUCCESS) OR (stringCompare(mailHeader.toName,'eall')=RESULT_SUCCESS) OR ((stringCompare(mailHeader.toName,'all')=RESULT_SUCCESS) AND (cb.handle[0] AND MAILSCAN_ALL)))) oldcn:=currentConf currentConf:=cn stat:=displayMessage(gfh) @@ -12493,7 +11025,6 @@ ENDPROC PROC deleteMSG(gfh) DEF string[255]:STRING DEF msgbaselock - DEF stat IF(loggedOnUser.secStatus<210) IF(stringCompare(mailHeader.fromName,confMailName)=RESULT_SUCCESS) THEN JUMP goAheadDel @@ -12504,16 +11035,16 @@ PROC deleteMSG(gfh) goAheadDel: IF(msgbaselock:=lockMsgBase()) - getMailStatFile(currentConf) + getMailStatFile(currentConf,currentMsgBase) delMsgNum:=msgNum-fwdFlag IF(mailStat.lowestNotDel=delMsgNum) THEN mailStat.lowestNotDel:=mailStat.lowestNotDel+1 - stat:=saveStatOnly() + saveStatOnly() mailHeader.status:="D" checkAttachedFile(delMsgNum,0) StringF(string,'\s\d',msgBaseLocation,delMsgNum) SetProtection(string,FIBF_OTR_DELETE) - stat:=DeleteFile(string) - stat:=saveOverHeader(gfh) + DeleteFile(string) + saveOverHeader(gfh) StringF(string,'\b\nMessage \d deleted...\b\n',delMsgNum) aePuts(string) UnLock(msgbaselock) @@ -12734,8 +11265,11 @@ PROC readMSG(gfh) noDirF:=1 JUMP nextMenu CASE "r" - stat:=replyToMSG(gfh) - IF(stat<0) THEN RETURN stat + stat:=captureRealAndInternetNames(currentConf,currentMsgBase) + IF stat=RESULT_SUCCESS + stat:=replyToMSG(gfh) + IF(stat<0) THEN RETURN stat + ENDIF noDirF:=1 JUMP goNextMsg ENDSELECT @@ -12941,7 +11475,6 @@ ENDPROC RESULT_FAILURE PROC loadMessageHeader(gfh) DEF headPoint,size,filePos,error,temp - DEF f: PTR TO CHAR headPoint:=msgNum-mailStat.lowestKey size:=110 ->SIZEOF mailHeader @@ -13014,7 +11547,7 @@ PROC customMsgbaseCmd(n1,n2,n3) runCommand(CMDTYPE_CUSTOM,'MSGBASE.DEF','',1) ENDPROC -PROC callMsgFuncs(msgfunc, conf) +PROC callMsgFuncs(msgfunc, conf, msgBaseNum) DEF stat, gfh DEF filename[255]:STRING @@ -13033,6 +11566,9 @@ PROC callMsgFuncs(msgfunc, conf) currentSeekPos:=0 stat:=RESULT_FAILURE mciViewSafe:=FALSE + + stat:=captureRealAndInternetNames(conf,msgBaseNum) + IF stat<0 THEN RETURN stat SELECT confNameType CASE NAME_TYPE_USERNAME @@ -13049,7 +11585,7 @@ PROC callMsgFuncs(msgfunc, conf) stat:=enterMSG(gfh) CASE MAIL_SCAN newmailsearch:= TRUE - stat:=searchNewMail(gfh,conf) + stat:=searchNewMail(gfh,conf, msgBaseNum) newmailsearch:=FALSE ENDSELECT @@ -13070,27 +11606,33 @@ ENDPROC PROC isInFlaggedList(s,confNum) DEF i DEF item:PTR TO flagFileItem + DEF patternBuf[100]:STRING FOR i:=0 TO flagFilesList.count()-1 item:=flagFilesList.item(i) - IF ((item.confNum=confNum) OR (item.confNum=-1)) AND (stcsma(s,item.fileName)) THEN RETURN TRUE + IF ((item.confNum=confNum) OR (item.confNum=-1)) + IF (ParsePatternNoCase(item.fileName, patternBuf, 100))>=0 + IF MatchPatternNoCase(patternBuf,s) THEN RETURN TRUE + ENDIF + ENDIF ENDFOR + ENDPROC FALSE PROC isInList(list:PTR TO stdlist,s,confNum) DEF i DEF item:PTR TO flagFileItem + DEF fn + fn:=FilePart(s) FOR i:=0 TO list.count()-1 item:=list.item(i) - IF ((item.confNum=confNum) OR (item.confNum=-1)) AND (stcsma(s,item.fileName)) THEN RETURN TRUE + IF ((item.confNum=confNum) OR (item.confNum=-1)) AND (strCmpi(fn,FilePart(item.fileName),ALL)) THEN RETURN TRUE ENDFOR ENDPROC FALSE PROC addFlagToList(s:PTR TO CHAR, confNum = -1) - DEF p: PTR TO CHAR DEF stat - DEF item:PTR TO flagFileItem DEF fileName fileName:=String(StrLen(s)) @@ -13295,12 +11837,21 @@ PROC checkForFileSize(checkFilename:PTR TO CHAR, checkConfNum, tfsizeList:PTR TO DEF fBlock: PTR TO fileinfoblock DEF flagFile:PTR TO flagFileItem - DEF fLock + DEF fLock=0 DEF drivenum DEF ramDir[255]:STRING + DEF patternBuf,patBufLen + DEF debugcount + DEF estDlCPS IF checkConfNum=-1 THEN checkConfNum:=currentConf + IF loggedOnUserMisc.lastDlCPS<>0 + estDlCPS:=loggedOnUserMisc.lastDlCPS + ELSE + estDlCPS:=Div(onlineBaud,10) + ENDIF + FOR min:=0 TO StrLen(checkFilename)-1 IF((checkFilename[min]="?") OR (checkFilename[min]="*")) THEN wflag:=1 ENDFOR @@ -13332,6 +11883,19 @@ PROC checkForFileSize(checkFilename:PTR TO CHAR, checkConfNum, tfsizeList:PTR TO ENDIF IF(z=1) THEN JUMP jumpIn + patBufLen:=StrLen(tempstr2)*2+2 + patternBuf:=New(patBufLen) + IF patternBuf=0 + myError(1) ->// MemError() + RETURN RESULT_FAILURE + ENDIF + + IF (ParsePatternNoCase(tempstr2, patternBuf, patBufLen))=-1 + Dispose(patternBuf) + myError(1) ->// MemError() + RETURN RESULT_FAILURE + ENDIF + IF(sysopdl) z:=1 wflag:=0 @@ -13370,8 +11934,7 @@ jumpIn: fLock:=NIL WHILE(Fgets(ft,ramDir,255)<>NIL) AND (fLock=0) IF ramDir[StrLen(ramDir)-1]=10 THEN SetStr(ramDir,StrLen(ramDir)-1) - UpperStr(ramDir) - IF StrCmp(ramDir,tempstr2) THEN fLock:=Lock(final,ACCESS_READ) + IF MatchPatternNoCase(patternBuf,ramDir) THEN fLock:=Lock(final,ACCESS_READ) ENDWHILE Close(ft) ELSE @@ -13392,16 +11955,15 @@ jumpIn: IF(doflag) IF fLock=NIL - IF((fLock:=Lock(final,ACCESS_READ))=0) - FreeDosObject(DOS_FIB,fBlock) - StringF(str,'Error, Path \s missing, adjust paths file..',path) - aePuts(str) - aePuts('\b\n\b\n') - callersLog(str) - RETURN RESULT_FAILURE - ENDIF + IF((fLock:=Lock(final,ACCESS_READ))=0) + FreeDosObject(DOS_FIB,fBlock) + StringF(str,'Error, Path \s missing, adjust paths file..',path) + aePuts(str) + aePuts('\b\n\b\n') + callersLog(str) + RETURN RESULT_FAILURE + ENDIF ENDIF - IF((Examine(fLock,fBlock))=NIL) FreeDosObject(DOS_FIB,fBlock) myError(1) @@ -13410,13 +11972,14 @@ jumpIn: ENDIF IF(wflag=0) THEN JUMP gotit - - WHILE (ExNext(fLock,fBlock)) /* my change.. prior to this we had a blank file name */ +debugcount:=0 + WHILE (ExNext(fLock,fBlock)) /* my change.. prior to this we had a blank file name */ + debugcount++ IF(fBlock.direntrytype<0) gotit: StrCopy(tempstr,fBlock.filename) UpperStr(tempstr) - stat:=stcsma(tempstr,tempstr2) + stat:=MatchPatternNoCase(patternBuf,tempstr) IF((stat<>0) OR sysopdl) fflag:=1 IF(sysopdl) @@ -13426,10 +11989,10 @@ gotit: StrAdd(final,fBlock.filename) ENDIF fsize:=fBlock.size - tsec:=Div(fsize,Div(onlineBaud,10)) + tsec:=Div(fsize,estDlCPS) min:=tsec/60 secs:=tsec-(min*60) - StringF(str,' \r\dk, \d mins \z\r\d[2] secs \s\t',Div(fsize,1024),min,secs,fBlock.filename) + StringF(str,' \r\dk, \d mins \z\r\d[2] secs \s\t',Shr(fsize,10) AND $003fffff,min,secs,fBlock.filename) ->IF(str[16]=" ") THEN SetStr(str,16) aePuts(str) IF((fBlock.comment[0]="F") OR (freeDownloads)) @@ -13502,8 +12065,8 @@ gotit: ENDSELECT ENDIF ENDWHILE - UnLock(fLock) + fLock:=0 IF(z=1) THEN JUMP outst ENDIF StringF(tempstr,'DLPATH.\d',drivenum++) @@ -13514,6 +12077,8 @@ outst: FreeDosObject(DOS_FIB,fBlock) + Dispose(patternBuf) + IF(fflag=0) StringF(str,' File (\s) not found.\b\n',checkFilename) aePuts(str) @@ -13537,7 +12102,7 @@ ENDPROC PROC statPrint(s: PTR TO CHAR) - DEF str[25]:STRING + DEF str[255]:STRING IF(dStatBar AND (statWriteIO<>NIL)) IF(bitPlanes<3) @@ -14042,7 +12607,11 @@ PROC sendMasterUpload(filename:PTR TO CHAR) StringF(temp1,'\l\s[16]',FilePart(filename)) strCpy(ulMsg.user,temp1,ALL) - strCpy(ulMsg.location,loggedOnUser.location,ALL) + IF loggedOnUser<>NIL + strCpy(ulMsg.location,loggedOnUser.location,ALL) + ELSE + strCpy(ulMsg.location,'',ALL) + ENDIF StringF(temp,'\d',currentStat) strCpy(ulMsg.action,temp,ALL) @@ -14082,7 +12651,11 @@ PROC sendMasterDownload(filename: PTR TO CHAR) StringF(temp1,'\l\s[16]',FilePart(filename)) strCpy(dlMsg.user,temp1,ALL) - strCpy(dlMsg.location,loggedOnUser.location,ALL) + IF loggedOnUser<>NIL + strCpy(dlMsg.location,loggedOnUser.location,ALL) + ELSE + strCpy(dlMsg.location,'',ALL) + ENDIF StringF(temp,'\d',currentStat) strCpy(dlMsg.action,temp,ALL) @@ -14153,15 +12726,21 @@ PROC sendQuietFlag(opt) ENDPROC PROC updateTitle(hoozer: PTR TO user) - DEF aflag,pflag + DEF aflag,pflag,pub=FALSE + DEF pubScreen[20]:STRING IF pagedFlag THEN pflag:="*" ELSE pflag:=" " IF sysopAvail THEN aflag:="*" ELSE aflag:=" " StringF(titlebar,' AmiExpress BBS (c)\s \s Node \d \c',expressDate,expressVer,node,aflag) + IF readToolType(TOOLTYPE_WINDOW,node,'WINDOW.PUBSCREEN',pubScreen) + pub:=TRUE + ENDIF + IF hoozer=NIL IF window<>NIL THEN SetWindowTitles(window,titlebar,titlebar) + IF (windowStat<>NIL) AND pub THEN SetWindowTitles(windowStat,titlebar,titlebar) RETURN ENDIF @@ -14169,9 +12748,10 @@ PROC updateTitle(hoozer: PTR TO user) StringF(ititlebar,' \c\s, \s, (\d \l\s[10] [\d]) \d mins, \d \c',pflag,hoozer.name,hoozer.phoneNumber,hoozer.secStatus,hoozer.conferenceAccess,currentConf,Div(timeLimit,60),onlineBaud,aflag) ->//(RTS) was Online_BaudR IF(dStatBar=NIL) SetWindowTitles(window,ititlebar,ititlebar) - + IF (windowStat<>NIL) AND (pub) THEN SetWindowTitles(windowStat,ititlebar,ititlebar) ELSE SetWindowTitles(window,titlebar,titlebar) + IF (windowStat<>NIL) AND (pub) THEN SetWindowTitles(windowStat,titlebar,titlebar) ENDIF ENDIF ENDPROC @@ -14197,17 +12777,24 @@ ENDPROC PROC statPrintUser(hoozer: PTR TO user,hoozer2: PTR TO userKeys,hoozer3: PTR TO userMisc) DEF string[82]:STRING DEF bcdStr[20]:STRING + DEF pubScreen[20]:STRING + DEF pub=FALSE statChatFlag() IF scropen=FALSE THEN RETURN + IF readToolType(TOOLTYPE_WINDOW,node,'WINDOW.PUBSCREEN',pubScreen) + pub:=TRUE + ENDIF + IF hoozer=NIL SetWindowTitles(window,titlebar,titlebar) + IF (windowStat<>NIL) AND (pub) THEN SetWindowTitles(windowStat,titlebar,titlebar) RETURN ENDIF - IF(pagedFlag) - IF KickVersion(40) OR (bitPlanes<3) + IF(pagedFlag) AND (bitPlanes>2) + IF KickVersion(40) statMessage(1,1,'') ELSE statMessage(1,1,'') @@ -14257,7 +12844,7 @@ PROC statPrintUser(hoozer: PTR TO user,hoozer2: PTR TO userKeys,hoozer3: PTR TO StringF(string,'\l\d[5]',hoozer.uploads AND $FFFF) statMessage(45,2,string) - formatBCD(loggedOnUserMisc.downloadBytesBCD,bcdStr) + formatBCD(hoozer3.downloadBytesBCD,bcdStr) IF StrLen(bcdStr)>12 SetStr(bcdStr,StrLen(bcdStr)-3) StrAdd(bcdStr,'K') @@ -14266,7 +12853,7 @@ PROC statPrintUser(hoozer: PTR TO user,hoozer2: PTR TO userKeys,hoozer3: PTR TO StringF(string,'\l\s[12]',bcdStr) statMessage(51,2,string) - formatBCD(loggedOnUserMisc.uploadBytesBCD,bcdStr) + formatBCD(hoozer3.uploadBytesBCD,bcdStr) IF StrLen(bcdStr)>12 SetStr(bcdStr,StrLen(bcdStr)-3) StrAdd(bcdStr,'K') @@ -14292,7 +12879,7 @@ PROC statPrintUser(hoozer: PTR TO user,hoozer2: PTR TO userKeys,hoozer3: PTR TO statMessage(51,3,' ') IF(hoozer.newUser = FALSE) - formatLongDateTime(loggedOnUser.timeLastOn,string) + formatLongDateTime(hoozer.timeLastOn,string) ELSE IF(validUser=0) StringF(string,' * * Account Not Saved * * ') @@ -14308,13 +12895,15 @@ PROC statPrintUser(hoozer: PTR TO user,hoozer2: PTR TO userKeys,hoozer3: PTR TO StringF(string,' \r\s[15]',hostIP) statMessage(19,3,string) - IF (cacheTests>0) - RealF(bcdStr,!(cacheHits!*100.0)/(cacheTests!),2) - ELSE - StrCopy(bcdStr,'0') + IF checkToolTypeExists(TOOLTYPE_NODE,node,'SHOW_CACHE_STATS') + IF (cacheTests>0) + RealF(bcdStr,!(cacheHits!*100.0)/(cacheTests!),2) + ELSE + StrCopy(bcdStr,'0') + ENDIF + StringF(string,'Tooltype cache: Used \d/\d Hit rate: \d/\d (\s%) ',diskObjectCache.count(),diskObjectCache.maxSize(),cacheHits,cacheTests,bcdStr) + statMessage(1,4,string) ENDIF - StringF(string,'Tooltype cache: Used \d/\d Hit rate: \d/\d (\s%) ',diskObjectCache.count(),diskObjectCache.maxSize(),cacheHits,cacheTests,bcdStr) - statMessage(1,4,string) ENDPROC PROC pGoodbye() @@ -14369,7 +12958,7 @@ PROC xprfopenAsm() ENDPROC D0 PROC xprfopen() - DEF fn,am,i,res,filemode,task: PTR TO tc + DEF fn,am,i,res,filemode DEF tempstr[255]:STRING DEF dup ->(*xpr_fopen)(char *filename, char *accessmode) @@ -14465,10 +13054,8 @@ PROC xprfcloseAsm() ENDPROC D0 PROC xprfclose() - DEF fp,res,task: PTR TO tc + DEF fp DEF tempstr[255]:STRING - DEF bgport - DEF msg:PTR TO jhMessage -> (*xpr_fclose)(long filepointer) -> A0 MOVE.L A0,fp @@ -14483,20 +13070,8 @@ PROC xprfclose() ELSE Close(fp) ENDIF - IF (zModemInfo.currentOperation=ZMODEM_UPLOAD) AND (zModemInfo.filesize>0) AND (zModemInfo.transPos=zModemInfo.filesize) AND bgFileCheck AND (loggedOnUserKeys.userFlags AND USER_BGFILECHECK) - StringF(tempstr,'bgCheckPort\d',node) - IF (bgport:=FindPort(tempstr)) - msg:=AllocMem(SIZEOF jhMessage,MEMF_ANY OR MEMF_CLEAR) - IF msg - msg.command:=BG_CHECKFILE - strCpy(msg.string,FilePart(zModemInfo.fileName),200) - msg.msg.ln.type:=NT_FREEMSG - msg.msg.length:=SIZEOF jhMessage - - ->signal background checking to check the file - PutMsg(bgport,msg) - ENDIF - ENDIF + IF (loggedOnUserKeys<>NIL) AND (zModemInfo.filesize>0) AND (zModemInfo.transPos=zModemInfo.filesize) + doBgCheck() ENDIF ENDIF @@ -14509,16 +13084,16 @@ PROC xprchkabortAsm() ENDPROC D0 PROC xprchkabort() - DEF winmsg:PTR TO intuimessage,res,task: PTR TO tc - DEF tempstr[255]:STRING + DEF winmsg:PTR TO intuimessage,res + ->DEF tempstr[255]:STRING loadA4() res:=0 - IF windowZmodemNIL IF (winmsg:=GetMsg(windowZmodem.userport))<>NIL - ReplyMsg(winmsg) IF winmsg.class=IDCMP_CLOSEWINDOW THEN res:=-1 + ReplyMsg(winmsg) ENDIF ENDIF @@ -14535,8 +13110,8 @@ PROC xprfreadAsm() ENDPROC D0 PROC xprfread() - DEF buf,bsize,bcount,fp,res,task: PTR TO tc - DEF tempstr[255]:STRING + DEF buf,bsize,bcount,fp,res + ->DEF tempstr[255]:STRING -> long count = (*xpr_fread)(char *buffer, long size, long count, -> -D0 A0 D0 D1 -> long fileptr) @@ -14569,8 +13144,8 @@ PROC xprfwriteAsm() ENDPROC D0 PROC xprfwrite() - DEF buf,bsize,bcount,fp,res,task: PTR TO tc - DEF tempstr[255]:STRING + DEF buf,bsize,bcount,fp,res + ->DEF tempstr[255]:STRING -> long count = (*xpr_fwrite)(char *buffer, long size, long count, -> D0 A0 D0 D1 -> long fileptr) @@ -14603,9 +13178,11 @@ PROC xprsreadAsm() ENDPROC D0 PROC xprsread() - DEF buf,bsize,timeout,serialsig,i,signals,task: PTR TO tc,res,timersig,ch + DEF buf,bsize,timeout,serialsig,i,signals,res,timersig DEF tempstr[255]:STRING - DEF waiting,status,sigs,obuf,buf2,c,c2,avail + DEF waiting,stat,obuf,buf2,c,c2,avail + DEF tv:timeval + -> long count = (*xpr_sread)(char *buffer, long size, long timeout) -> D0 A0 D0 D1 @@ -14624,29 +13201,27 @@ PROC xprsread() IF bsize=0 THEN RETURN 0 waiting:=bsize - timersig:=0 - IF timeout<>0 - IF timerport<>NIL THEN timersig:=Shl(1, timerport.sigbit) - setTimer(timeout) - ENDIF + tv.secs:=Div(timeout,1000000) + tv.micro:=Mod(timeout,1000000) + buf2:=New(bsize) obuf:=buf2 c2:=0 REPEAT IF timeout<>0 setSingleFDS(telnetSocket) - sigs:=timersig - status:=WaitSelect(telnetSocket+1,fds,NIL,NIL,NIL,{sigs}) + res:=WaitSelect(telnetSocket+1,fds,NIL,NIL,tv,NIL) ENDIF - IF (timeout=0) OR (status>0) + IF (timeout=0) OR (res>0) REPEAT - status,avail:=checkTelnetData() + stat,avail:=checkTelnetData() IF avail>waiting THEN avail:=waiting IF avail>0 - status:=Recv(telnetSocket,buf2,avail,0) - IF status>0 - StringF(tempstr,'xprsread recv complete: \d bytes',status) + stat:=Recv(telnetSocket,buf2,avail,0) + IF stat>0 + + StringF(tempstr,'xprsread recv complete: \d bytes',stat) debugLog(LOG_DEBUG,tempstr) c:=0 REPEAT @@ -14658,7 +13233,7 @@ PROC xprsread() ELSEIF (buf2[c]=255) OR (lastIAC) IF (lastIAC=FALSE) THEN c++ lastIAC:=FALSE - IF c>=status + IF c>=stat lastIAC:=TRUE ELSE IF buf2[c]=255 @@ -14668,7 +13243,7 @@ PROC xprsread() StringF(tempstr,'known iac code: \d',buf2[c]) debugLog(LOG_DEBUG,tempstr) c++ - IF (c>=status) + IF (c>=stat) lastIAC2:=TRUE ELSE StringF(tempstr,'code: \d',buf2[c]) @@ -14684,22 +13259,15 @@ PROC xprsread() c2++ ENDIF c++ - UNTIL (c>=status) + UNTIL (c>=stat) waiting:=bsize-c2 ENDIF ENDIF UNTIL (avail=0) OR (waiting=0) ENDIF - UNTIL (waiting=0) OR (timeout=0) OR (sigs AND timersig) + UNTIL (waiting=0) OR (timeout=0) OR (res=0) i:=c2 - IF timeout<>0 - IF (sigs AND timersig) - waitTime() - ELSE - stopTime() - ENDIF - ENDIF IF(checkCarrier())=FALSE i:=-1 ENDIF @@ -14713,7 +13281,7 @@ PROC xprsread() IF(bsize > 0) - waiting,status:=getSerialInfo() + waiting:=getSerialInfo() /* Return error if carrier is lost. */ IF(checkCarrier())=FALSE @@ -14773,22 +13341,15 @@ PROC xprsread() serialsig:=0 timersig:=0 + openTimer() IF serialReadMP<>NIL THEN serialsig:=Shl(1, serialReadMP.sigbit) IF timerport<>NIL THEN timersig:=Shl(1, timerport.sigbit) /* Set up the timer. */ - setTimer(timeout) + setTimer(Div(timeout,1000000),Mod(timeout,1000000)) - /* Set up the read request. */ - - IF readQueued THEN stopSerialRead() - - ->clear the serial signal - SetSignal(0,serialsig) - - readQueued:=TRUE - queueRead(serialReadIO,buf,bsize) + queueSerialRead(buf,bsize) /* We'll need them in a minute */ @@ -14800,9 +13361,8 @@ PROC xprsread() IF(signals AND serialsig) /* Abort the timer request. */ - stopTime() - + closeTimer() /* Did the request terminate gracefully? */ @@ -14829,6 +13389,7 @@ PROC xprsread() /* Remove the timer request. */ waitTime() + closeTimer() /* Did the driver receive any * data? @@ -14845,7 +13406,7 @@ PROC xprsread() * driver handles read abort. */ - waiting,status:=getSerialInfo() + waiting:=getSerialInfo() /* Don't read too much. */ @@ -14898,9 +13459,8 @@ PROC xprswriteAsm() ENDPROC D0 PROC xprswrite() - DEF buf,bsize,task:PTR TO tc,res,i + DEF buf,bsize DEF tempstr[255]:STRING - DEF c,buf2 -> long status = (*xpr_swrite)(char *buffer, long size) -> D0 A0 D0 @@ -14924,7 +13484,7 @@ PROC xprfseekAsm() ENDPROC D0 PROC xprfseek() - DEF fp,offset,origin,task:PTR TO tc,res + DEF fp,offset,origin DEF tempstr[255]:STRING -> long status = (*xpr_fseek)(long fileptr, long offset, long origin) -> D0 A0 D0 D1 @@ -14966,12 +13526,8 @@ PROC xprsflushAsm() ENDPROC D0 PROC xprsflush() - DEF task:PTR TO tc,res - loadA4() - debugLog(LOG_DEBUG,'xprsflush') - ENDPROC FALSE PROC xprupdateAsm() @@ -14982,8 +13538,8 @@ ENDPROC D0 PROC xprupdate() DEF xpru: PTR TO xpr_update - DEF task:PTR TO tc,updateTime - DEF res,update=FALSE + DEF updateTime + DEF update=FALSE DEF outmsg[255]:STRING MOVE.L A0,xpru @@ -15087,7 +13643,7 @@ PROC xprupdate() ENDIF ENDIF - ENDPROC +ENDPROC PROC xprsetserialAsm() MOVEM.L D1-D7/A0-A6,-(A7) @@ -15096,7 +13652,7 @@ PROC xprsetserialAsm() ENDPROC D0 PROC xprsetserial() - DEF task:PTR TO tc,res,newstatus,oldstatus + DEF res,newstatus,oldstatus DEF tempstr[255]:STRING MOVE.L D0,newstatus @@ -15105,9 +13661,10 @@ PROC xprsetserial() StringF(tempstr,'xprsetserial \d',newstatus) debugLog(LOG_DEBUG,tempstr) + res:=oldstatus oldstatus:=newstatus -ENDPROC oldstatus +ENDPROC res PROC xprfinfoAsm() MOVEM.L D1-D7/A0-A6,-(A7) @@ -15116,7 +13673,7 @@ PROC xprfinfoAsm() ENDPROC D0 PROC xprfinfo() - DEF task:PTR TO tc,i,res,fn,fitype,fp + DEF i,res,fn,fitype,fp DEF tempstr[255]:STRING ->long info = (*xpr_finfo)(char *filename, long typeofinfo) -> D0 A0 D0 @@ -15167,21 +13724,26 @@ PROC xprunlinkAsm() ENDPROC D0 PROC xprunlink() - DEF task:PTR TO tc,res,fn,tempstr[255]:STRING - + DEF fn MOVE.L A0,fn - loadA4() +ENDPROC xprunlink2(fn) + +PROC xprunlink2(fn) + DEF tempstr[255]:STRING + DEF res StringF(tempstr,'xprunlink \s',fn) debugLog(LOG_DEBUG,tempstr) res:=0 ->partial upload, move it as a partial upload rather than deleting it - IF ownPartFiles - StringF(tempstr,'\sPartUpload/\s@\d-\d',currentConfDir,FilePart(fn),node,loggedOnUser.slotNumber) - ELSE - StringF(tempstr,'\sPartUpload/\s@\d',currentConfDir,FilePart(fn),loggedOnUser.slotNumber) + IF loggedOnUser<>NIL + IF ownPartFiles + StringF(tempstr,'\sPartUpload/\s@\d-\d',currentConfDir,FilePart(fn),node,loggedOnUser.slotNumber) + ELSE + StringF(tempstr,'\sPartUpload/\s@\d',currentConfDir,FilePart(fn),loggedOnUser.slotNumber) + ENDIF ENDIF IF(Rename(fn,tempstr))=FALSE fileCopy(fn,tempstr) @@ -15197,14 +13759,16 @@ PROC xprffirstAsm() ENDPROC D0 PROC xprffirst() - DEF task:PTR TO tc,res,xprObj:PTR TO xprData - DEF fileItem:PTR TO flagFileItem + DEF xprObj:PTR TO xprData DEF buffer:PTR TO CHAR MOVE.L A0,buffer MOVE.L A1,xprObj - loadA4() +ENDPROC xprffirst2(buffer,xprObj) + +PROC xprffirst2(buffer,xprObj:PTR TO xprData) + DEF fileItem:PTR TO flagFileItem fileItem:=xprObj.fileList.item(xprObj.currentFile) strCpy(buffer,fileItem.fileName,255) @@ -15212,7 +13776,6 @@ PROC xprffirst() zModemInfo.freeDFlag:=checkFree(fileItem.fileName) zModemInfo.resumePos:=0 zModemInfo.current:=1 - ENDPROC TRUE PROC xprfnextAsm() @@ -15222,7 +13785,7 @@ PROC xprfnextAsm() ENDPROC D0 PROC xprfnext() - DEF task:PTR TO tc,res,xprObj:PTR TO xprData,tempsize + DEF xprObj:PTR TO xprData DEF buffer:PTR TO CHAR MOVE.L A0,buffer @@ -15234,17 +13797,12 @@ ENDPROC xprfnext2(buffer,xprObj) PROC xprfnext2(buffer:PTR TO CHAR, xprObj:PTR TO xprData) DEF fileItem:PTR TO flagFileItem - DEF tempsize + DEF debuglog[255]:STRING fileItem:=xprObj.fileList.item(xprObj.currentFile) - IF (zModemInfo.transPos<>0) AND (zModemInfo.transPos=zModemInfo.filesize) - removeFlagFromList(FilePart(fileItem.fileName),fileItem.confNum) - ENDIF - - IF (zModemInfo.transPos<>0) AND (zModemInfo.resumePos<>zModemInfo.filesize) AND (zModemInfo.transPos=zModemInfo.filesize) - updateDownloadStats(xprObj,fileItem) - ENDIF + removeFlagFromList(FilePart(fileItem.fileName),fileItem.confNum) + updateDownloadStats(xprObj,fileItem) xprObj.currentFile:=xprObj.currentFile+1 zModemInfo.current:=zModemInfo.current+1 @@ -15337,24 +13895,24 @@ PROC serialErrorReport(request: PTR TO ioextser) ENDPROC isFatal PROC getSerialInfo() - DEF waiting,status + DEF waiting IF(serialWriteIO) serialWriteIO.iostd.command:=SDCMD_QUERY DoIO(serialWriteIO) waiting:=serialWriteIO.iostd.actual - status:=serialWriteIO.status + ->status:=serialWriteIO.status ELSE waiting:=0 - status:=(CIAF_COMCD OR CIAF_COMDSR) + ->status:=(CIAF_COMCD OR CIAF_COMDSR) ENDIF -ENDPROC waiting,status +ENDPROC waiting -PROC setTimer(timeval) +PROC setTimer(timevalSecs,timevalMicro) timermsg.io.command:=TR_ADDREQUEST /* add a new timer request */ - timermsg.time.secs:=Div(timeval,1000000) /* seconds */ - timermsg.time.micro:=Mod(timeval,1000000) /* microseconds */ + timermsg.time.secs:=timevalSecs /* seconds */ + timermsg.time.micro:=timevalMicro /* microseconds */ timermsg.io.mn.replyport:=timerport timerQueued:=TRUE SendIO(timermsg) /* post the request to the timer device */ @@ -15403,15 +13961,22 @@ PROC updateZDisplay() DEF tempstr[255]:STRING DEF xpos,tags2,vi DEF v1,v2 - - /* transfer window not open */ - - IF zModemInfo.currentOperation=ZMODEM_DOWNLOAD - StringF(tempstr,'[Node \d] Send Window (\d/\d)',node,zModemInfo.current,zModemInfo.total) - strCpy(zModemInfo.titleBar,tempstr,ALL) + IF netMailTransfer + IF zModemInfo.currentOperation=ZMODEM_DOWNLOAD + StringF(tempstr,'[Node \d] NetMail Send Window',node) + strCpy(zModemInfo.titleBar,tempstr,ALL) + ELSE + StringF(tempstr,'[Node \d] NetMail Receive Window',node) + strCpy(zModemInfo.titleBar,tempstr,ALL) + ENDIF ELSE - StringF(tempstr,'[Node \d] Receive Window (\d/??)',node,zModemInfo.current) - strCpy(zModemInfo.titleBar,tempstr,ALL) + IF zModemInfo.currentOperation=ZMODEM_DOWNLOAD + StringF(tempstr,'[Node \d] Send Window (\d/\d)',node,zModemInfo.current,zModemInfo.total) + strCpy(zModemInfo.titleBar,tempstr,ALL) + ELSE + StringF(tempstr,'[Node \d] Receive Window (\d/??)',node,zModemInfo.current) + strCpy(zModemInfo.titleBar,tempstr,ALL) + ENDIF ENDIF IF(windowZmodem<>NIL) @@ -15448,14 +14013,14 @@ PROC updateZDisplay() SetAPen(windowZmodem.rport,0) RectFill(windowZmodem.rport,11,136,322,143) ELSE - StringF(tempstr,' Complete: \d%\n',Div(Mul(zModemInfo.transPos,100),zModemInfo.filesize)) + StringF(tempstr,' Complete: \d%\n',Div(zModemInfo.transPos,Div(zModemInfo.filesize,100))) zmodemStatPrint(tempstr) v1:=zModemInfo.transPos v2:=zModemInfo.filesize IF v2>=1048576 - v1:=Shr(v1,10) - v2:=Shr(v2,10) + v1:=Shr(v1,10) AND $003fffff + v2:=Shr(v2,10) AND $003fffff ENDIF xpos:=11+Div(Mul(v1,311),v2) @@ -15469,8 +14034,6 @@ PROC updateZDisplay() RectFill(windowZmodem.rport,xpos+1,136,322,143) ENDIF ENDIF - ->StringF(tempstr,' Resume P: \d\n\n',zModemInfo.resumePos) - ->zmodemStatPrint(tempstr) StringF(tempstr,' LastTime: \s\n',zModemInfo.lastTime) zmodemStatPrint(tempstr) StringF(tempstr,' CPS: \d Efficency \d%\n\n',zModemInfo.cps,zModemInfo.eff) @@ -15494,8 +14057,23 @@ PROC checkFree(fname) IF fileComment[0]="F" THEN RETURN TRUE ENDPROC freeDownloads +PROC doAxNetSend(filename:PTR TO CHAR) + DEF res + netMailTransfer:=TRUE + res:=downloadFile(filename,TRUE) + netMailTransfer:=FALSE +ENDPROC res + +PROC doAxNetReceive(filename:PTR TO CHAR) + DEF res + onlineNFiles:=0 + netMailTransfer:=TRUE + res:=zModemUpload(filename,TRUE) + netMailTransfer:=FALSE +ENDPROC res + ->this returns 0 = fail, 1 = success unlike most of the routines -PROC downloadFile(str: PTR TO CHAR) +PROC downloadFile(str: PTR TO CHAR,forceZmodem=FALSE) DEF templist:PTR TO stdlist DEF res,i DEF flagItem: PTR TO flagFileItem @@ -15512,28 +14090,102 @@ PROC downloadFile(str: PTR TO CHAR) flagItem.confNum:=currentConf templist.setItem(i,flagItem) ENDFOR - ELSE - flagItem:=NEW flagItem - flagItem.fileName:=String(255) - StringF(flagItem.fileName,'\s\s',amixnetOutboundDir,str) - flagItem.confNum:=currentConf - templist.add(flagItem) + ELSE + parseList(str,tempstringlist) + FOR i:=0 TO tempstringlist.count()-1 + flagItem:=NEW flagItem + flagItem.fileName:=String(255) + StringF(flagItem.fileName,'\s\s',amixnetOutboundDir,tempstringlist.item(i)) + flagItem.confNum:=-1 + templist.add(flagItem) + ENDFOR + ENDIF + + res:=downloadFiles(templist,FALSE,forceZmodem) + + clearFlagItems(templist) + END templist + END tempstringlist +ENDPROC res + +PROC httpUpload(uploadFolder: PTR TO CHAR,httpPort) + DEF x: PTR TO xprData + DEF tempstr[100]:STRING + DEF oldSerCache + + x:=NEW x + x.currentFile:=0 + x.fileList:=NIL + x.updateDownloadStats:=FALSE + + oldSerCache:=serialCacheEnabled + flushSerialCache() + serialCacheEnabled:=FALSE + IF readToolType(TOOLTYPE_XFERLIB,loggedOnUser.xferProtocol,'HTTPHOST',tempstr)=FALSE + StrCopy(tempstr,'localhost') + ENDIF + + doHttpd(node,tempstr,httpPort,uploadFolder,{aePuts},{readChar},{sCheckInput},x,{ftpUploadFileStart},{ftpUploadFileEnd}, {ftpTransferFileProgress},{ftpDupeCheck},TRUE) + serialCacheEnabled:=oldSerCache + END x +ENDPROC + +PROC httpDownload(fileList: PTR TO stdlist, pupdateDownloadStats,httpPort) + DEF i + DEF dirLock + DEF tempstr[255]:STRING + DEF tempDir[255]:STRING + DEF linkStr[255]:STRING + DEF item:PTR TO flagFileItem + DEF x: PTR TO xprData + DEF oldSerCache + + IF readToolType(TOOLTYPE_XFERLIB,loggedOnUser.xferProtocol,'HTTPHOST',tempstr)=FALSE + StrCopy(tempstr,'localhost') + ENDIF + + IF readToolType(TOOLTYPE_XFERLIB,loggedOnUser.xferProtocol,'HTTPTEMP',tempstr)=FALSE + StringF(tempDir,'RAM:http\d',node) + ELSE + StringF(tempDir,'\shttp\d',tempstr,node) + ENDIF + + aePuts('\b\nCreating HTTP file area\b\n') + dirLock:=CreateDir(tempDir) + StrAdd(tempDir,'/') + IF dirLock<>NIL THEN UnLock(dirLock) + ->create links in ram + IF fileList<>NIL + FOR i:=0 TO fileList.count()-1 + item:=fileList.item(i) + StringF(linkStr,'\s\s',tempDir,FilePart(item.fileName)) + IF MakeLink(linkStr,item.fileName,1)=0 + StringF(tempstr,'Makelink failed \s \s error: \d\b\n',linkStr,item.fileName,IoErr()) + aePuts(tempstr) + ENDIF + ENDFOR ENDIF - - res:=downloadFiles(templist,FALSE) - - clearFlagItems(templist) - END templist - END tempstringlist -ENDPROC res + + x:=NEW x + x.currentFile:=0 + x.fileList:=fileList + x.updateDownloadStats:=pupdateDownloadStats + + oldSerCache:=serialCacheEnabled + flushSerialCache() + serialCacheEnabled:=FALSE + doHttpd(node,tempstr,httpPort,tempDir,{aePuts},{readChar},{sCheckInput},x,{ftpDownloadFileStart},{ftpDownloadFileEnd}, {ftpTransferFileProgress},{ftpDupeCheck},FALSE) + serialCacheEnabled:=oldSerCache + + ->clean up ram links + StringF(linkStr,'DELETE \s ALL',tempDir) + Execute(linkStr,NIL,NIL) + END x +ENDPROC PROC ftpUploadFileStart(xprInfo:PTR TO xprData, fileName:PTR TO CHAR,filelen) - DEF fileItem:PTR TO flagFileItem - DEF item:PTR TO flagFileItem - DEF i - fileItem:=NIL sendMasterUpload(FilePart(fileName)) - zModemInfo.filesize:=0 + zModemInfo.filesize:=filelen zModemInfo.resumePos:=0 ftptime:=getSystemTime() updateZDisplay() @@ -15594,6 +14246,18 @@ PROC ftpTransferFileProgress(xprInfo:PTR TO xprData, fileName:PTR TO CHAR,pos,cp updateZDisplay() ENDPROC +PROC ftpDupeCheck(xprInfo:PTR TO xprData, fileName:PTR TO CHAR) + DEF dup=FALSE + + IF checkForFile(FilePart(fileName)) + dup:=TRUE + ELSEIF checkInPlaypens(FilePart(fileName)) + dup:=TRUE + ENDIF + + IF dup THEN skipdFiles.add(FilePart(fileName)) +ENDPROC dup + PROC updateDownloadStats(xprObj:PTR TO xprData, fileItem:PTR TO flagFileItem) DEF tempsize DEF cb:PTR TO confBase @@ -15602,20 +14266,20 @@ PROC updateDownloadStats(xprObj:PTR TO xprData, fileItem:PTR TO flagFileItem) IF(zModemInfo.freeDFlag=FALSE) THEN donf++ tempsize:=zModemInfo.filesize - tBT:=tBT+tempsize - dTBT:=dTBT+tempsize + tBT:=addWO(tBT,tempsize) + dTBT:=addWO(dTBT,tempsize) IF xprObj.updateDownloadStats IF sopt.toggles[TOGGLES_CREDITBYKB] - tempsize:=Shr(tempsize,10) + tempsize:=Shr(tempsize,10) AND $003fffff ENDIF IF(checkSecurity(ACS_CONFERENCE_ACCOUNTING)) - saveMsgPointers(currentConf) + saveMsgPointers(currentConf,currentMsgBase) IF(freeDownloads=FALSE) IF creditAccountTrackDownloads(loggedOnUser) - cb:=confBases.item(fileItem.confNum) + cb:=confBases.item(getConfIndex(fileItem.confNum,1)) addBCD(cb.downloadBytesBCD,tempsize) cb.bytesDownload:=convertFromBCD(cb.downloadBytesBCD) @@ -15624,7 +14288,7 @@ PROC updateDownloadStats(xprObj:PTR TO xprData, fileItem:PTR TO flagFileItem) ENDIF cb.dailyBytesDld:=cb.dailyBytesDld+tempsize IF bytesADL<>$7fffffff THEN bytesADL:=bytesADL-tempsize - loadMsgPointers(currentConf) + loadMsgPointers(currentConf,currentMsgBase) ELSE IF(freeDownloads=FALSE) IF creditAccountTrackDownloads(loggedOnUser) @@ -15657,7 +14321,7 @@ PROC ftpUpload(uploadFolder:PTR TO CHAR,ftpPort,ftpDataPort) StrCopy(tempstr,'localhost') ENDIF - doftp(node,tempstr,ftpPort,ftpDataPort,uploadFolder,{aePuts},{readChar},{sCheckInput},x,{ftpUploadFileStart},{ftpUploadFileEnd},{ftpTransferFileProgress},TRUE) + doftp(node,tempstr,ftpPort,ftpDataPort,uploadFolder,{aePuts},{readChar},{sCheckInput},x,{ftpUploadFileStart},{ftpUploadFileEnd},{ftpTransferFileProgress},{ftpDupeCheck},TRUE) serialCacheEnabled:=oldSerCache END x @@ -15707,7 +14371,7 @@ PROC ftpDownload(fileList: PTR TO stdlist, updateDownloadStats,ftpPort,ftpDataPo oldSerCache:=serialCacheEnabled flushSerialCache() serialCacheEnabled:=FALSE - doftp(node,tempstr,ftpPort,ftpDataPort,tempDir,{aePuts},{readChar},{sCheckInput},x,{ftpDownloadFileStart},{ftpDownloadFileEnd},{ftpTransferFileProgress},FALSE) + doftp(node,tempstr,ftpPort,ftpDataPort,tempDir,{aePuts},{readChar},{sCheckInput},x,{ftpDownloadFileStart},{ftpDownloadFileEnd},{ftpTransferFileProgress},{ftpDupeCheck},FALSE) serialCacheEnabled:=oldSerCache ->clean up ram links @@ -15717,26 +14381,30 @@ PROC ftpDownload(fileList: PTR TO stdlist, updateDownloadStats,ftpPort,ftpDataPo ENDPROC ->this returns 0 = fail, 1 = success unlike most of the routines -PROC downloadFiles(fileList: PTR TO stdlist, updateDownloadStats) +PROC downloadFiles(fileList: PTR TO stdlist, updateDownloadStats, forceZmodem=FALSE) DEF tempstr[255]:STRING DEF debugstr[255]:STRING DEF xprio: PTR TO xprIO - DEF i,result,tempsize - DEF cb:PTR TO confBase - DEF task:PTR TO tc + DEF result DEF time1,time2 DEF oldshared - DEF fileItem:PTR TO flagFileItem DEF x: PTR TO xprData - DEF ftpPort,ftpDataPort + DEF ftpPort,ftpDataPort,httpPort + DEF zm: PTR TO zmodem_t + DEF ext=TRUE + DEF dlTimeTaken=0 + + DEF protocol[255]:STRING IF fileList.count()=0 RETURN 0 ENDIF - IF (logonType<>LOGON_TYPE_REMOTE) AND (checkSecurity(ACS_LOCAL_DOWNLOADS)=FALSE) - aePuts('\b\nNot supported locally...') - RETURN 0 + IF netMailTransfer=FALSE + IF (logonType<>LOGON_TYPE_REMOTE) AND (checkSecurity(ACS_LOCAL_DOWNLOADS)=FALSE) + aePuts('\b\nNot supported locally...') + RETURN 0 + ENDIF ENDIF IF xprLib.count()=0 @@ -15744,12 +14412,27 @@ PROC downloadFiles(fileList: PTR TO stdlist, updateDownloadStats) RETURN 0 ENDIF - IF (strCmpi(xprLib.item(loggedOnUser.xferProtocol),'HYDRA',ALL)) + IF forceZmodem OR (loggedOnUser=NIL) + StrCopy(protocol,'INTERNAL') + ELSE + StrCopy(protocol,xprLib.item(loggedOnUser.xferProtocol)) + ENDIF + + IF (strCmpi(protocol,'HYDRA',ALL)) aePuts('\b\nHYDRA protocol is not currently supported') RETURN 0 ENDIF - IF (strCmpi(xprLib.item(loggedOnUser.xferProtocol),'FTP',ALL)) + IF(strCmpi(protocol,'INTERNAL',ALL)) THEN ext:=FALSE + + IF (strCmpi(protocol,'XPRZM',ALL)) + StrCopy(protocol,'INTERNAL') + ext:=TRUE + ENDIF + + zModemInfo.currentOperation:=ZMODEM_DOWNLOAD + + IF (strCmpi(protocol,'FTP',ALL)) ftpPort:=readToolTypeInt(TOOLTYPE_NODE,node,'FTPPORT') ftpDataPort:=readToolTypeInt(TOOLTYPE_NODE,node,'FTPDATAPORT') IF ftpPort=-1 THEN ftpPort:=10000+(node*2) @@ -15762,10 +14445,19 @@ PROC downloadFiles(fileList: PTR TO stdlist, updateDownloadStats) RETURN result ENDIF - IF(strCmpi(xprLib.item(loggedOnUser.xferProtocol),'INTERNAL',ALL)) + IF (strCmpi(protocol,'HTTP',ALL)) + httpPort:=readToolTypeInt(TOOLTYPE_NODE,node,'HTTPPORT') + IF httpPort=-1 THEN httpPort:=20000+node + IF scropen + openZmodemStat() + ENDIF + result:=httpDownload(fileList,updateDownloadStats,httpPort) + closezModemStats() + RETURN result + ENDIF + + IF(strCmpi(protocol,'INTERNAL',ALL)) StringF(tempstr,'Zmodem: Ready to Send\b\n') - ELSEIF(strCmpi(xprLib.item(loggedOnUser.xferProtocol),'FTP',ALL)) - StringF(tempstr,'FTP: Ready to Send\b\n') ELSEIF(checkSecurity(ACS_XPR_SEND)=FALSE) aePuts('\b\nYou are not allowed to download using external xpr protocols') RETURN 0 @@ -15776,18 +14468,16 @@ PROC downloadFiles(fileList: PTR TO stdlist, updateDownloadStats) aePuts(tempstr) ->aePuts('Control-X to Cancel\b\n') - IF(strCmpi(xprLib.item(loggedOnUser.xferProtocol),'INTERNAL',ALL)) - StrCopy(tempstr,'xprzmodem.library') - ELSEIF(strCmpi(xprLib.item(loggedOnUser.xferProtocol),'HYDRA',ALL)) - aePuts('\b\nHYDRA transfers are not currently supported\b\n') - RETURN 0 - ELSE - StringF(tempstr,'\s.library',xprLib.item(loggedOnUser.xferProtocol)) - ENDIF - - IF (xprotocolbase:=OpenLibrary(tempstr,0))=NIL - aePuts('\b\nUnable to open the xpr library\b\n') - RETURN 0 + IF ext + IF(strCmpi(protocol,'INTERNAL',ALL)) + StrCopy(tempstr,'xprzmodem.library') + ELSE + StringF(tempstr,'\s.library',protocol) + ENDIF + IF (xprotocolbase:=OpenLibrary(tempstr,0))=NIL + aePuts('\b\nUnable to open the xpr library\b\n') + RETURN 0 + ENDIF ENDIF zModemInfo.current:=0;zModemInfo.total:=fileList.count();zModemInfo.transPos:=0;zModemInfo.filesize:=0;zModemInfo.errorCount:=0;zModemInfo.errorPos:=0;zModemInfo.cps:=0; zModemInfo.eff:=0; zModemInfo.resumePos:=0 @@ -15798,72 +14488,90 @@ PROC downloadFiles(fileList: PTR TO stdlist, updateDownloadStats) IF scropen openZmodemStat() ENDIF - zModemInfo.currentOperation:=ZMODEM_DOWNLOAD oldshared:=serShared serShared:=FALSE - xprio:=NEW xprio - - xprio.xpr_extension:=4 - xprio.xpr_fopen:={xprfopenAsm} - xprio.xpr_fclose:={xprfcloseAsm} - xprio.xpr_fread:={xprfreadAsm} - xprio.xpr_fwrite:={xprfwriteAsm} - xprio.xpr_sread:={xprsreadAsm} - xprio.xpr_swrite:={xprswriteAsm} - xprio.xpr_sflush:={xprsflushAsm} - xprio.xpr_update:={xprupdateAsm} - xprio.xpr_ffirst:={xprffirstAsm} - xprio.xpr_fnext:={xprfnextAsm} - xprio.xpr_chkabort:={xprchkabortAsm} - xprio.xpr_chkmisc:=0 - xprio.xpr_gets:=0 - xprio.xpr_setserial:={xprsetserialAsm} - xprio.xpr_finfo:={xprfinfoAsm} - xprio.xpr_fseek:={xprfseekAsm} - xprio.xpr_data:=0 - xprio.xpr_options:=0 - xprio.xpr_unlink:={xprunlink} - xprio.xpr_squery:=0 - xprio.xpr_getptr:=0 - - StrCopy(tempstr,'') - IF(strCmpi(xprLib.item(loggedOnUser.xferProtocol),'INTERNAL',ALL)) - StrCopy(tempstr,'TN,AY,OR,E9,KN,SN,RN,DN,B64') + IF ext + xprio:=NEW xprio + + xprio.xpr_extension:=4 + xprio.xpr_fopen:={xprfopenAsm} + xprio.xpr_fclose:={xprfcloseAsm} + xprio.xpr_fread:={xprfreadAsm} + xprio.xpr_fwrite:={xprfwriteAsm} + xprio.xpr_sread:={xprsreadAsm} + xprio.xpr_swrite:={xprswriteAsm} + xprio.xpr_sflush:={xprsflushAsm} + xprio.xpr_update:={xprupdateAsm} + xprio.xpr_ffirst:={xprffirstAsm} + xprio.xpr_fnext:={xprfnextAsm} + xprio.xpr_chkabort:={xprchkabortAsm} + xprio.xpr_chkmisc:=0 + xprio.xpr_gets:=0 + xprio.xpr_setserial:={xprsetserialAsm} + xprio.xpr_finfo:={xprfinfoAsm} + xprio.xpr_fseek:={xprfseekAsm} + xprio.xpr_data:=0 + xprio.xpr_options:=0 + xprio.xpr_unlink:={xprunlink} + xprio.xpr_squery:=0 + xprio.xpr_getptr:=0 + + StrCopy(tempstr,'') + IF(strCmpi(protocol,'INTERNAL',ALL)) + StrCopy(tempstr,'TN,AY,OR,E9,KN,SN,RN,DN,B64') + ELSE + readToolType(TOOLTYPE_XFERLIB,loggedOnUser.xferProtocol,'OPTIONS',tempstr) + ENDIF ELSE - readToolType(TOOLTYPE_XFERLIB,loggedOnUser.xferProtocol,'OPTIONS',tempstr) + zm:=NEW zm + zm.log_level:=ZM_LOG_DEBUG + + bufferedBytes:=0 + bufferReadOffset:=0 + + zmodem_init(zm, 0, + {zmlputs}, + {zmprogress}, + {zmrecvbyte}, + {zmisconnected}, + {zmiscancelled}, + {zmdatawaiting}, + {zmuploadcompleted}, + {zmuploadfailed}, + {zmdupecheck}, + {zmflush}, + NIL, + {zmfopen}, + {zmfclose}, + {zmfseek}, + {zmfread}, + {zmfwrite}, + {zmfirstfile}, + {zmnextfile}, + 1024,0) ENDIF asynciobase:=OpenLibrary('asyncio.library',0) - StringF(debugstr,'xpr setup options = \s',tempstr) - debugLog(LOG_DEBUG,debugstr) - xprio.xpr_filename:=tempstr - IF XprotocolSetup(xprio)=0 - CloseLibrary(xprotocolbase) - END xprio - zModemInfo.currentOperation:=ZMODEM_NONE - closezModemStats() - RETURN 0 - ENDIF - - IF openTimer() - debugLog(LOG_ERROR,'Can''t re-open Timer Device!') - CloseLibrary(xprotocolbase) - zModemInfo.currentOperation:=ZMODEM_NONE - closezModemStats() - END xprio - RETURN 0 + IF ext + StringF(debugstr,'xpr setup options = \s',tempstr) + debugLog(LOG_DEBUG,debugstr) + xprio.xpr_filename:=tempstr + IF XprotocolSetup(xprio)=0 + CloseLibrary(xprotocolbase) + END xprio + zModemInfo.currentOperation:=ZMODEM_NONE + closezModemStats() + RETURN 0 + ENDIF ENDIF ->cancel current queued serial read request - readQueued:=TRUE stopSerialRead() - i:=0 result:=TRUE - time1:=getSystemTime() transfering:=TRUE cancelTransferOffHook:=FALSE lastIAC:=FALSE @@ -15872,9 +14580,19 @@ PROC downloadFiles(fileList: PTR TO stdlist, updateDownloadStats) x.currentFile:=0 x.fileList:=fileList x.updateDownloadStats:=updateDownloadStats - xprio.xpr_filename:=x - result:=XprotocolSend(xprio) - time2:=getSystemTime() + + IF ext + xprio.xpr_filename:=x + time1:=getSystemTime() + result:=XprotocolSend(xprio) + time2:=getSystemTime() + tTTM:=time2-time1; + ELSE + zm.user_data:=x + result:=zmodem_send_files(zm, NIL,{dlTimeTaken}) + tTTM:=Div(dlTimeTaken,50) + ENDIF + IF zModemInfo.transPos<>zModemInfo.filesize THEN result:=FALSE @@ -15884,21 +14602,30 @@ PROC downloadFiles(fileList: PTR TO stdlist, updateDownloadStats) udLog('\tIncomplete 100% Transfer, accumulating Maximum Bytes Downloaded') result:=TRUE ->call fnext to update stats - xprfnext2(NIL,x) + IF ext + xprfnext2(NIL,x) + ELSE + zmnextfile(zm,NIL) + ENDIF ENDIF ENDIF END x - tTTM:=time2-time1; - XprotocolCleanup(xprio) + IF ext + XprotocolCleanup(xprio) + ELSE + zmodem_cleanup(zm) + ENDIF transfering:=FALSE checkOffhookFlag() - END xprio - - closeTimer() + IF ext + END xprio + ELSE + END zm + ENDIF - CloseLibrary(xprotocolbase) + IF ext THEN CloseLibrary(xprotocolbase) IF asynciobase<>NIL THEN CloseLibrary(asynciobase) asynciobase:=NIL @@ -15908,9 +14635,9 @@ PROC downloadFiles(fileList: PTR TO stdlist, updateDownloadStats) serShared:=oldshared ->restart normal serial - queueRead(serialReadIO,{serbuff}) + queueSerialRead({serbuff}) - aePuts(xprTitle.item(loggedOnUser.xferProtocol)) + aePuts(protocol) IF result THEN aePuts(' download successful\b\n') ELSE aePuts(' download unsuccessful\b\n') ENDPROC result @@ -16070,6 +14797,7 @@ ENDPROC 0 PROC moveFile(filename,filesize) DEF stat + DEF spacehi,spacelo DEF pathnum DEF goodtogo=0 DEF tempstr[255]:STRING @@ -16081,16 +14809,15 @@ PROC moveFile(filename,filesize) RETURN 0 ENDIF - filesize:=filesize+16384 - filesize:=Shr(filesize,10) ->changed to take account of disk space now in kb + filesize:=(Shr(filesize,20) AND $00000fff)+1 ->changed to take account of disk space now in mb pathnum:=1 StringF(tempstr3,'ULPATH.\d',pathnum) pathnum++ WHILE(readToolType(TOOLTYPE_CONF,currentConf,tempstr3,tempstr3)) - stat:=rFreeSpace(tempstr3) - IF(StrLen(sopt.ramPen)>0) THEN StringF(tempstr,'\s/\s',sopt.ramPen,filename) ELSE StringF(tempstr,'\sNode\d/Playpen/\s',cmds.bbsLoc,node,filename) + spacehi,spacelo:=rFreeSpace(tempstr3) + IF(StrLen(sopt.ramPen)>0) THEN StringF(tempstr,'\s\s',sopt.ramPen,filename) ELSE StringF(tempstr,'\sNode\d/Playpen/\s',cmds.bbsLoc,node,filename) StringF(tempstr2,'\s\s',tempstr3,filename) IF(Rename(tempstr,tempstr2)) SetProtection(tempstr,FIBF_OTR_DELETE) @@ -16104,7 +14831,7 @@ PROC moveFile(filename,filesize) ->debugLog(LOG_WARN,tempstr3) errorLog(tempstr3) ENDIF - IF(stat>filesize) + IF(spacehi>=filesize) goodtogo:=1 IF(stat:=fileCopy(tempstr,tempstr2)) SetProtection(tempstr,FIBF_OTR_DELETE) @@ -16130,29 +14857,401 @@ PROC moveFile(filename,filesize) aePuts('FAILURE!!! unable to move file!\b\n\b\n') StringF(tempstr,'\tFAILURE!, unable to move file \s from PlayPen',filename) callersLog(tempstr); - IF(StrLen(sopt.ramPen)>0) THEN StringF(tempstr,'\s/\s',sopt.ramPen,filename) ELSE StringF(tempstr,'\sNode\d/Playpen/\s',cmds.bbsLoc,node,filename) + IF(StrLen(sopt.ramPen)>0) THEN StringF(tempstr,'\s\s',sopt.ramPen,filename) ELSE StringF(tempstr,'\sNode\d/Playpen/\s',cmds.bbsLoc,node,filename) SetProtection(tempstr,FIBF_OTR_DELETE) DeleteFile(tempstr) ENDPROC 0 -PROC xprReceive(file) HANDLE +PROC zmlputs(zm: PTR TO zmodem_t,level, str:PTR TO CHAR) + SELECT level + CASE ZM_LOG_DEBUG + debugLog(LOG_DEBUG,str) + CASE ZM_LOG_INFO + debugLog(LOG_DEBUG,str) + CASE ZM_LOG_NOTICE + debugLog(LOG_DEBUG,str) + CASE ZM_LOG_WARNING + debugLog(LOG_WARN,str) + CASE ZM_LOG_ERR + debugLog(LOG_ERROR,str) + ENDSELECT +ENDPROC + +PROC zmprogress(zm: PTR TO zmodem_t, pos) + DEF t1,t2,t,n + DEF h,m,s + DEF tempStr[255]:STRING + DEF updateTime + + t1,t2:=getZmSystemTime() + t:=Mul((t1-zm.transfer_start_time1),50)+t2-zm.transfer_start_time2 + + IF t>0 + IF pos>40000000 + n:=Div(pos,Div(t,50)) + ELSE + n:=Div(Mul(pos,50),t) + ENDIF + ELSE + n:=pos + ENDIF + t:=Div(t,50) + + h:=Div(t,3600) + m:=Mod(t,3600) + s:=Mod(m,60) + m:=Div(m,60) + + StringF(tempStr,'\z\r\d[2]:\z\r\d[2]:\z\r\d[2]',h,m,s) + strCpy(zModemInfo.elapsedTime,tempStr,40) + + IF n>0 + t:=Div(zm.current_file_size,n) + h:=Div(t,3600) + m:=Mod(t,3600) + s:=Mod(m,60) + m:=Div(m,60) + StringF(tempStr,'\z\r\d[2]:\z\r\d[2]:\z\r\d[2]',h,m,s) + ELSE + StrCopy(tempStr,'??:??:??') + ENDIF + strCpy(zModemInfo.apxTime,tempStr,40) + + zModemInfo.filesize:=zm.current_file_size + zModemInfo.errorCount:=zm.errors + + zModemInfo.resumePos:=zm.transfer_start_pos + strCpy(zModemInfo.fileName,zm.current_file_name,255) + + zModemInfo.cps:=n + zModemInfo.eff:=Div(Mul(zModemInfo.cps,100),Div(onlineBaud,10)) + + IF pos>=0 + zModemInfo.transPos:=pos + IF pos=zm.current_file_size THEN strCpy(zModemInfo.lastTime,zModemInfo.elapsedTime,40) + ENDIF + + IF zm.new_file + IF zModemInfo.currentOperation=ZMODEM_DOWNLOAD + StringF(tempStr,'\t\sDownloading \s \d bytes',IF zModemInfo.freeDFlag THEN 'Free ' ELSE '',zModemInfo.fileName,zModemInfo.filesize) + ELSE + IF zModemInfo.resumePos<>0 + StringF(tempStr,'\tResuming \s[12] \d bytes from \d',FilePart(zModemInfo.fileName),zModemInfo.filesize,zModemInfo.resumePos) + ELSE + StringF(tempStr,'\tUploading \s[12] \d bytes',FilePart(zModemInfo.fileName),zModemInfo.filesize) + ENDIF + ENDIF + callersLog(tempStr) + udLog(tempStr) + ENDIF + + updateTime:=getSystemTime() + IF zModemInfo.lastUpdate<>updateTime + updateZDisplay() + debugLog(LOG_DEBUG,'zmprogress update') + StringF(tempStr,'current block size: \d',zm.block_size) + debugLog(LOG_DEBUG,tempStr) + zModemInfo.lastUpdate:=updateTime + + processWindowMessage(-1) + processCommodityMessage(-1) + checkDoorMsg(0) + IF servercmd=SV_UNICONIFY + IF scropen THEN expressToFront() ELSE openExpressScreen() + servercmd:=-1 + ENDIF + checkCarrier() + ENDIF +ENDPROC + +PROC zmrecvbyte(zm: PTR TO zmodem_t, timeout) + DEF res + IF telnetSocket>=0 + res:=zmrecvbyteTelnet(zm,timeout) + ELSE + res:=zmrecvbyteSerial(zm,timeout) + ENDIF +ENDPROC res + +PROC zmrecvbyteTelnet(zm: PTR TO zmodem_t, timeout) + DEF res + DEF temp + DEF recvd,n + DEF tv:timeval + recvd:=FALSE + REPEAT +redo1: + IF (bufferReadOffset=250) AND (res<255) + lastIAC:=2 + ELSE + WriteF('unknown IAC \d\b\n',res) + lastIAC:=2 + ENDIF + ELSEIF lastIAC=2 + lastIAC:=0 + ELSEIF res=255 + lastIAC:=1 + ELSE + recvd:=TRUE + ENDIF + bufferReadOffset++ + + UNTIL (bufferReadOffset>=bufferedBytes) OR (recvd) + IF recvd=FALSE THEN JUMP redo1 + ELSE + + tv.secs:=timeout + tv.micro:=0 + setSingleFDS(telnetSocket) + res:=WaitSelect(telnetSocket+1,fds,NIL,NIL,tv,NIL) + + temp,n:=checkTelnetData() + bufferReadOffset:=0 + bufferedBytes:=0 + IF n>0 + IF n>zModemBufferSize THEN n:=zModemBufferSize + IF Recv(telnetSocket,zmodemBuffer,n,0)=n + bufferedBytes:=n + ENDIF + checkCarrier() + JUMP redo1 + ENDIF + ENDIF + UNTIL (res=0) OR (recvd) OR (timeout=0) + IF recvd=FALSE THEN res:=-1 +ENDPROC res + +PROC zmrecvbyteSerial(zm: PTR TO zmodem_t, timeout) + DEF serialsig,signals,timersig=0,res + DEF waiting,abort + + IF (bufferReadOffsetzModemBufferSize THEN waiting:=zModemBufferSize + IF(waiting > 0) + doSerialRead(zmodemBuffer,waiting) + bufferedBytes:=serialReadIO.iostd.actual + serialReadIO.iostd.actual:=0 + ENDIF + + IF (timeout=0) OR (bufferedBytes>0) + IF bufferedBytes=0 + RETURN -1 + ELSE + res:=zmodemBuffer[bufferReadOffset] + bufferReadOffset++ + RETURN res + ENDIF + ENDIF + + openTimer() + setTimer(timeout,0) + IF timerport<>NIL THEN timersig:=Shl(1, timerport.sigbit) + + queueSerialRead(zmodemBuffer,zModemBufferSize) + serialsig:=Shl(1, serialReadMP.sigbit) + + signals:=Wait(SIGBREAKF_CTRL_C OR serialsig OR timersig) + abort:=signals AND SIGBREAKF_CTRL_C + + IF signals AND timersig THEN waitTime() ELSE stopTime() + closeTimer() + + IF (signals AND serialsig)=FALSE THEN stopSerialRead() ELSE waitSerialRead() + + IF(serialReadIO.iostd.actual > 0) + bufferedBytes:=serialReadIO.iostd.actual + ENDIF + + IF bufferedBytes=0 + res:=-1 + ELSE + res:=zmodemBuffer[bufferReadOffset] + bufferReadOffset++ + ENDIF + checkCarrier() + + IF abort THEN res:=-1 +ENDPROC res + +PROC zmisconnected() IS lostCarrier=FALSE + +PROC zmiscancelled() IS xprchkabort() + +PROC zmdatawaiting(zm:PTR TO zmodem_t, timeout) + DEF signals,timersig,serialsig,recvd=0,waiting + DEF tv:timeval + + IF bufferedBytes>bufferReadOffset + RETURN TRUE + ENDIF + + waiting:=getSerialInfo() + IF (waiting>0) OR checkTelnetData() THEN RETURN TRUE + + IF timeout=0 THEN RETURN FALSE + + IF telnetSocket>=0 + setSingleFDS(telnetSocket) + tv.secs:=timeout + tv.micro:=0 + WaitSelect(telnetSocket+1,fds,NIL,NIL,tv,NIL) + IF checkTelnetData() THEN recvd:=TRUE + ELSE + openTimer() + setTimer(timeout,0) + serialsig:=Shl(1, serialReadMP.sigbit) + IF timerport<>NIL THEN timersig:=Shl(1, timerport.sigbit) + signals:=Wait(SIGBREAKF_CTRL_C OR serialsig OR timersig) + recvd:=(signals AND serialsig)<>0 + IF (signals AND timersig)=0 + stopTime() + ELSE + waitTime() + ENDIF + closeTimer() + ENDIF + +ENDPROC recvd + +PROC zmuploadcompleted(zm: PTR TO zmodem_t, fname:PTR TO CHAR) + IF loggedOnUserKeys<>NIL + doBgCheck() + ENDIF +ENDPROC + +PROC zmuploadfailed(zm: PTR TO zmodem_t, fname:PTR TO CHAR) IS xprunlink2(fname) + +PROC zmdupecheck(zm:PTR TO zmodem_t,fname:PTR TO CHAR) + DEF dup=FALSE + IF (netMailTransfer=FALSE) AND (sysopUploading=FALSE) AND (rzmsg=FALSE) + IF checkForFile(FilePart(fname)) + dup:=TRUE + ELSEIF checkInPlaypens(FilePart(fname)) + dup:=TRUE + ENDIF + ENDIF + + IF dup + skipdFiles.add(FilePart(fname)) + ENDIF + + sendMasterUpload(FilePart(fname)) + +ENDPROC dup + +PROC zmflush(zm:PTR TO zmodem_t,buffer,size) IS serPuts(buffer,size,TRUE,TRUE) + +PROC zmfopen(fn:PTR TO CHAR,filemode) + DEF res + IF asynciobase<>NIL + IF filemode=MODE_OLDFILE + res:=OpenAsync(fn,MODE_READ,65536) + ELSEIF filemode=MODE_NEWFILE + res:=OpenAsync(fn,MODE_WRITE,65536) + ELSEIF filemode=MODE_READWRITE + res:=OpenAsync(fn,MODE_APPEND,65536) + ENDIF + ELSE + res:=Open(fn,filemode) + ENDIF +ENDPROC res + +PROC zmfclose(fh) + IF asynciobase<>NIL + CloseAsync(fh) + ELSE + Close(fh) + ENDIF +ENDPROC + +PROC zmfseek(fh,offset,origin) + DEF res + IF asynciobase<>NIL + IF origin=OFFSET_BEGINNING + res:=SeekAsync(fh,offset,MODE_START) + ELSEIF origin=OFFSET_CURRENT + res:=SeekAsync(fh,offset,MODE_CURRENT) + ELSEIF origin=OFFSET_END + res:=SeekAsync(fh,offset,MODE_END) + ENDIF + ELSE + res:=Seek(fh,offset,origin) + ENDIF +ENDPROC res + +PROC zmfread(fh,buf,size) + DEF res + IF asynciobase<>NIL + res:=ReadAsync(fh,buf,size) + ELSE + res:=Fread(fh,buf,1,size) + ENDIF +ENDPROC res + +PROC zmfwrite(fh,buf,size) + DEF res + IF asynciobase<>NIL + res:=WriteAsync(fh,buf,size) + ELSE + res:=Fwrite(fh,buf,1,size) + ENDIF +ENDPROC res + +PROC zmfirstfile(zm:PTR TO zmodem_t,fname:PTR TO CHAR) IS xprffirst2(fname,zm.user_data) +PROC zmnextfile(zm:PTR TO zmodem_t,fname:PTR TO CHAR) IS xprfnext2(fname,zm.user_data) + +PROC zModemUpload(file,forceZmodem=FALSE) HANDLE DEF tempstr[255]:STRING,debugstr[255]:STRING DEF result DEF xprio=NIL: PTR TO xprIO - DEF task:PTR TO tc - DEF i,time1,time2 + DEF time1,time2 DEF oldshared,bgport - DEF msg:PTR TO jhMessage,tags=NIL,count,ch + DEF msg:PTR TO jhMessage,tags=NIL DEF proc:PTR TO process - DEF ftpPort,ftpDataPort + DEF ftpPort,ftpDataPort,httpPort + DEF protocol[255]:STRING + + DEF zm: PTR TO zmodem_t + DEF ulTimeTaken + DEF ext=TRUE + DEF bgStack - IF(strCmpi(xprLib.item(loggedOnUser.xferProtocol),'INTERNAL',ALL)) + + IF (forceZmodem) OR (loggedOnUser=NIL) + StrCopy(protocol,'INTERNAL') + ELSE + StrCopy(protocol,(xprLib.item(loggedOnUser.xferProtocol))) + ENDIF + + IF(strCmpi(protocol,'INTERNAL',ALL)) THEN ext:=FALSE + + IF (strCmpi(protocol,'XPRZM',ALL)) + StrCopy(protocol,'INTERNAL') + ext:=TRUE + ENDIF + + IF(strCmpi(protocol,'INTERNAL',ALL)) StrCopy(tempstr,'xprzmodem.library') - ELSEIF(strCmpi(xprLib.item(loggedOnUser.xferProtocol),'HYDRA',ALL)) + ELSEIF(strCmpi(protocol,'HYDRA',ALL)) aePuts('\b\nHYDRA transfers are not currently supported\b\n') RETURN RESULT_FAILURE - ELSEIF (strCmpi(xprLib.item(loggedOnUser.xferProtocol),'FTP',ALL)) - IF(StrLen(sopt.ramPen)>0) THEN StringF(tempstr,'\s/',sopt.ramPen) ELSE StringF(tempstr,'\sNode\d/PlayPen/',cmds.bbsLoc,node) + ELSEIF (strCmpi(protocol,'FTP',ALL)) ftpPort:=readToolTypeInt(TOOLTYPE_NODE,node,'FTPPORT') ftpDataPort:=readToolTypeInt(TOOLTYPE_NODE,node,'FTPDATAPORT') @@ -16160,7 +15259,23 @@ PROC xprReceive(file) HANDLE IF ftpDataPort=-1 THEN ftpDataPort:=10001+(node*2) IF scropen THEN openZmodemStat() - ftpUpload(tempstr,ftpPort,ftpDataPort) + ftpUpload(file,ftpPort,ftpDataPort) + closezModemStats() + checkOffhookFlag() + receivePlayPen(TRUE) + IF (tBT>0) AND (tTTM>0) + tTEFF:=Div(Mul(Div(tBT,tTTM),100),Div(onlineBaud,10)) + ELSE + tTEFF:=0 + ENDIF + RETURN 1 + ELSEIF (strCmpi(protocol,'HTTP',ALL)) + + httpPort:=readToolTypeInt(TOOLTYPE_NODE,node,'HTTPPORT') + IF httpPort=-1 THEN httpPort:=20000+node + + IF scropen THEN openZmodemStat() + httpUpload(file,httpPort) closezModemStats() checkOffhookFlag() receivePlayPen(TRUE) @@ -16169,18 +15284,21 @@ PROC xprReceive(file) HANDLE ELSE tTEFF:=0 ENDIF - RETURN + RETURN 1 ELSE - StringF(tempstr,'\s.library',xprLib.item(loggedOnUser.xferProtocol)) + StringF(tempstr,'\s.library',protocol) ENDIF - IF (xprotocolbase:=OpenLibrary(tempstr,0))=NIL - aePuts('\b\nUnable to open the xpr library\b\n') - RETURN RESULT_FAILURE + IF ext + IF (xprotocolbase:=OpenLibrary(tempstr,0))=NIL + aePuts('\b\nUnable to open the xpr library\b\n') + RETURN RESULT_FAILURE + ENDIF + xprio:=NEW xprio + ELSE + zm:=NEW zm ENDIF - xprio:=NEW xprio - zModemInfo.current:=0; zModemInfo.transPos:=0; zModemInfo.filesize:=0; zModemInfo.errorCount:=0; zModemInfo.errorPos:=0; zModemInfo.cps:=0; zModemInfo.eff:=0; zModemInfo.resumePos:=0 strCpy(zModemInfo.zStat,'',ALL) strCpy(zModemInfo.fileName,'',ALL) @@ -16190,68 +15308,90 @@ PROC xprReceive(file) HANDLE oldshared:=serShared serShared:=FALSE + zModemInfo.currentOperation:=ZMODEM_UPLOAD IF scropen openZmodemStat() ENDIF - zModemInfo.currentOperation:=ZMODEM_UPLOAD - - xprio.xpr_extension:=4 - xprio.xpr_fopen:={xprfopenAsm} - xprio.xpr_fclose:={xprfcloseAsm} - xprio.xpr_fread:={xprfreadAsm} - xprio.xpr_fwrite:={xprfwriteAsm} - xprio.xpr_sread:={xprsreadAsm} - xprio.xpr_swrite:={xprswriteAsm} - xprio.xpr_sflush:={xprsflushAsm} - xprio.xpr_update:={xprupdateAsm} - xprio.xpr_chkabort:={xprchkabortAsm} - xprio.xpr_chkmisc:=0 - xprio.xpr_gets:=0 - xprio.xpr_setserial:={xprsetserialAsm} - xprio.xpr_ffirst:=0 - xprio.xpr_fnext:=0 - xprio.xpr_finfo:={xprfinfoAsm} - xprio.xpr_fseek:={xprfseekAsm} - xprio.xpr_data:=0 - xprio.xpr_options:=0 - xprio.xpr_unlink:={xprunlinkAsm} - xprio.xpr_squery:=0 - xprio.xpr_getptr:=0 - - asynciobase:=OpenLibrary('asyncio.library',0) - StrCopy(tempstr,'') - IF(strCmpi(xprLib.item(loggedOnUser.xferProtocol),'INTERNAL',ALL)) - StrCopy(tempstr,'TN,AY,OR,E9,KN,SN,RN,DN,B64') + IF ext + xprio.xpr_extension:=4 + xprio.xpr_fopen:={xprfopenAsm} + xprio.xpr_fclose:={xprfcloseAsm} + xprio.xpr_fread:={xprfreadAsm} + xprio.xpr_fwrite:={xprfwriteAsm} + xprio.xpr_sread:={xprsreadAsm} + xprio.xpr_swrite:={xprswriteAsm} + xprio.xpr_sflush:={xprsflushAsm} + xprio.xpr_update:={xprupdateAsm} + xprio.xpr_chkabort:={xprchkabortAsm} + xprio.xpr_chkmisc:=0 + xprio.xpr_gets:=0 + xprio.xpr_setserial:={xprsetserialAsm} + xprio.xpr_ffirst:=0 + xprio.xpr_fnext:=0 + xprio.xpr_finfo:={xprfinfoAsm} + xprio.xpr_fseek:={xprfseekAsm} + xprio.xpr_data:=0 + xprio.xpr_options:=0 + xprio.xpr_unlink:={xprunlinkAsm} + xprio.xpr_squery:=0 + xprio.xpr_getptr:=0 ELSE - readToolType(TOOLTYPE_XFERLIB,loggedOnUser.xferProtocol,'OPTIONS',tempstr) + zm.log_level:=ZM_LOG_DEBUG + + bufferedBytes:=0 + bufferReadOffset:=0 + + zmodem_init(zm, 0, + {zmlputs}, + {zmprogress}, + {zmrecvbyte}, + {zmisconnected}, + {zmiscancelled}, + {zmdatawaiting}, + {zmuploadcompleted}, + {zmuploadfailed}, + {zmdupecheck}, + {zmflush}, + NIL, + {zmfopen}, + {zmfclose}, + {zmfseek}, + {zmfread}, + {zmfwrite}, + {zmfirstfile}, + {zmnextfile}, + 1024,0) ENDIF - StringF(debugstr,'xpr setup options = \s',tempstr) - debugLog(LOG_DEBUG,debugstr) - xprio.xpr_filename:=tempstr - IF XprotocolSetup(xprio)=0 - Raise(ERR_EXCEPT) - ENDIF + asynciobase:=OpenLibrary('asyncio.library',0) - ->override options with thsee (P = upload folder, KN dont keep partial uploads - actually our xprlink routine moves them into partial uploads - IF(StrLen(sopt.ramPen)>0) THEN StringF(tempstr,'KN,P\s',sopt.ramPen) ELSE StringF(tempstr,'KN,P\sNode\d/PlayPen',cmds.bbsLoc,node) - xprio.xpr_filename:=tempstr - IF XprotocolSetup(xprio)=0 - Raise(ERR_EXCEPT) - ENDIF + IF ext + StrCopy(tempstr,'') + IF(strCmpi(protocol,'INTERNAL',ALL)) + StrCopy(tempstr,'TN,AY,OR,E9,KN,SN,RN,DN,B64') + ELSE + readToolType(TOOLTYPE_XFERLIB,loggedOnUser.xferProtocol,'OPTIONS',tempstr) + ENDIF - IF openTimer() - debugLog(LOG_ERROR,'Can''t re-open Timer Device!') - Raise(ERR_EXCEPT) + StringF(debugstr,'xpr setup options = \s',tempstr) + debugLog(LOG_DEBUG,debugstr) + xprio.xpr_filename:=tempstr + IF XprotocolSetup(xprio)=0 + Raise(ERR_EXCEPT) + ENDIF + + ->override options with thsee (P = upload folder, KN dont keep partial uploads - actually our xprlink routine moves them into partial uploads + StringF(tempstr,'KN,P\s',file) + xprio.xpr_filename:=tempstr + IF XprotocolSetup(xprio)=0 + Raise(ERR_EXCEPT) + ENDIF ENDIF ->cancel current queued serial read request - readQueued:=TRUE stopSerialRead() - i:=0 - time1:=getSystemTime() transfering:=TRUE lastIAC:=FALSE @@ -16262,40 +15402,59 @@ PROC xprReceive(file) HANDLE bgData.checkedBytes:=0 ReleaseSemaphore(bgData) - IF bgFileCheck AND (loggedOnUserKeys.userFlags AND USER_BGFILECHECK) - bgChecking:=TRUE - tags:=NEW [NP_ENTRY,{backgroundFileCheckThread},NP_STACKSIZE,10000,0]:LONG - Forbid() - proc:=CreateNewProc(tags) - END tags - saveA4thread(proc.task) - Permit() + IF loggedOnUserKeys<>NIL + IF bgFileCheck AND (loggedOnUserKeys.userFlags AND USER_BGFILECHECK) + bgChecking:=TRUE + bgStack:=readToolTypeInt(TOOLTYPE_NODE,node,'BGFILECHECKSTACK') + IF bgStack<=0 THEN bgStack:=20000 + + tags:=NEW [NP_ENTRY,{backgroundFileCheckThread},NP_STACKSIZE,bgStack,0]:LONG + Forbid() + proc:=CreateNewProc(tags) + END tags + saveA4thread(proc.task) + Permit() + ENDIF ENDIF - result:=XprotocolReceive(xprio) - time2:=getSystemTime() - tTTM:=time2-time1; - XprotocolCleanup(xprio) + IF ext + time1:=getSystemTime() + result:=XprotocolReceive(xprio) + time2:=getSystemTime() + tTTM:=time2-time1; + ELSE + result:=zmodem_recv_files(zm, file,NIL,{ulTimeTaken}) + tTTM:=Div(ulTimeTaken,50) + ENDIF - IF bgFileCheck AND (loggedOnUserKeys.userFlags AND USER_BGFILECHECK) - StringF(tempstr,'bgCheckPort\d',node) - IF (bgport:=FindPort(tempstr)) - msg:=AllocMem(SIZEOF jhMessage,MEMF_ANY OR MEMF_CLEAR) - IF msg - msg.command:=BG_EXIT - msg.msg.ln.type:=NT_FREEMSG - msg.msg.length:=SIZEOF jhMessage + + IF ext + XprotocolCleanup(xprio) + ELSE + zmodem_cleanup(zm) + ENDIF - ->signal background checking to finish - PutMsg(bgport,msg) + IF (loggedOnUserKeys<>NIL) AND (netMailTransfer=FALSE) + IF bgFileCheck AND (loggedOnUserKeys.userFlags AND USER_BGFILECHECK) + StringF(tempstr,'bgCheckPort\d',node) + IF (bgport:=FindPort(tempstr)) + msg:=AllocMem(SIZEOF jhMessage,MEMF_ANY OR MEMF_CLEAR) + IF msg + msg.command:=BG_EXIT + msg.msg.ln.type:=NT_FREEMSG + msg.msg.length:=SIZEOF jhMessage - IF FindPort(tempstr) - aePuts('Waiting for background filecheck to complete...\b\n\b\n',TRUE) - ->wait for it to finish - WHILE FindPort(tempstr) - Delay(10) - ENDWHILE - bgChecking:=FALSE + ->signal background checking to finish + PutMsg(bgport,msg) + + IF FindPort(tempstr) + aePuts('Waiting for background filecheck to complete...\b\n\b\n',TRUE) + ->wait for it to finish + WHILE FindPort(tempstr) + Delay(10) + ENDWHILE + bgChecking:=FALSE + ENDIF ENDIF ENDIF ENDIF @@ -16305,32 +15464,41 @@ PROC xprReceive(file) HANDLE checkOffhookFlag() receivePlayPen(FALSE) - - tTEFF:=Div(Mul(Div(tBT,tTTM),100),Div(onlineBaud,10)) + + IF (tBT>0) AND (tTTM>0) + tTEFF:=Div(Mul(Div(tBT,tTTM),100),Div(onlineBaud,10)) + ELSE + tTEFF:=0 + ENDIF Delay(50) - aePuts(xprTitle.item(loggedOnUser.xferProtocol)) + aePuts(protocol) IF(result) THEN aePuts(' upload successful\b\n') ELSE aePuts(' upload unsuccessful\b\n') IF tags<>NIL THEN END tags - END xprio - - closeTimer() + + IF ext + END xprio + ELSE + END zm + ENDIF IF asynciobase<>NIL THEN CloseLibrary(asynciobase) asynciobase:=NIL - CloseLibrary(xprotocolbase) + IF ext THEN CloseLibrary(xprotocolbase) zModemInfo.currentOperation:=ZMODEM_NONE closezModemStats() serShared:=oldshared ->restart normal serial IO - queueRead(serialReadIO,{serbuff}) + queueSerialRead({serbuff}) + + RETURN 1 EXCEPT - CloseLibrary(xprotocolbase) + IF ext THEN CloseLibrary(xprotocolbase) zModemInfo.currentOperation:=ZMODEM_NONE closezModemStats() IF xprio THEN END xprio @@ -16338,20 +15506,22 @@ EXCEPT ENDPROC PROC freeDiskSpace() - ->now returns free space in kb not bytes + ->now returns free space in mb not bytes DEF string[200]:STRING,path[100]:STRING DEF tempstr[255]:STRING - DEF tfs,fsu + DEF tfshi,tfslo,fsuhi,fsulo DEF drivenum=1 - tfs:=0 + tfshi:=0 + tfslo:=0 StringF(path,'DRIVE.\d',drivenum) drivenum++ IF readToolType(TOOLTYPE_DRIVES,'',path,string) WHILE(readToolType(TOOLTYPE_DRIVES,'',path,string)) - fsu:=rFreeSpace(string) - tfs:=tfs+fsu + fsuhi,fsulo:=rFreeSpace(string) + tfshi:=tfshi+fsuhi + tfslo:=tfslo+fsulo StringF(path,'DRIVE.\d',drivenum) drivenum++ ENDWHILE @@ -16361,19 +15531,32 @@ PROC freeDiskSpace() RETURN RESULT_FAILURE ENDIF -ENDPROC tfs + WHILE tfslo>=1048576 + tfslo:=tfslo-1048576 + tfshi++ + ENDWHILE + +ENDPROC tfshi,tfslo PROC rFreeSpace(path: PTR TO CHAR) - ->now returns space in kb not bytes + ->now returns two values, space in mb and then extra bytes as second result DEF fLock DEF i_data: PTR TO infodata DEF tempstr[255]:STRING DEF stat=0 + DEF spacehi=0,spacelo=0 + DEF temp1,temp2 IF(i_data:=AllocMem(SIZEOF infodata,MEMF_CHIP)) IF(fLock:=Lock(path,ACCESS_READ)) IF(stat:=Info(fLock,i_data)) - stat:=Mul(Shr((i_data.numblocks-i_data.numblocksused),10),i_data.bytesperblock) ->changed to get kbytes free instead of bytes + + ->spacelo:=Mul((i_data.numblocks-i_data.numblocksused),i_data.bytesperblock) + ->spacehi:=Mul(Shr((i_data.numblocks-i_data.numblocksused),10),i_data.bytesperblock) ->changed to get kbytes free instead of bytes + + temp1,temp2:=mulu64(i_data.numblocks-i_data.numblocksused,i_data.bytesperblock) + spacelo:=temp2 AND $FFFFF + spacehi:=(Shr(temp2,20) AND $FFF) OR Shl(temp1,12) ELSE StringF(tempstr,'\b\nCan not get info from \s for free space\b\n',path) aePuts(tempstr) @@ -16387,11 +15570,7 @@ PROC rFreeSpace(path: PTR TO CHAR) ELSE myError(0) ENDIF -ENDPROC stat - -PROC setProtocol(str: PTR TO CHAR) - loggedOnUser.protocol:="Z" -ENDPROC +ENDPROC spacehi,spacelo PROC stripReturn(str: PTR TO CHAR) DEF i,t @@ -16419,10 +15598,10 @@ PROC scanHoldDesc() IF(string[0]<>" ") string[13]:=0 StringF(text,'\sLCFILES/\s',currentConfDir,string) - IF(StrLen(sopt.ramPen)>0) THEN StringF(tempstr,'\s/\s',sopt.ramPen,string) ELSE StringF(tempstr,'\sNode\d/PlayPen/\s',cmds.bbsLoc,node,string) + IF(StrLen(sopt.ramPen)>0) THEN StringF(tempstr,'\s\s',sopt.ramPen,string) ELSE StringF(tempstr,'\sNode\d/PlayPen/\s',cmds.bbsLoc,node,string) IF(checkForFile(FilePart(text))<>RESULT_FAILURE) - IF(StrLen(sopt.ramPen)>0) THEN StringF(tempstr,'\s/\s',sopt.ramPen,string) ELSE StringF(tempstr,'\sNode\d/PlayPen/\s',cmds.bbsLoc,node,string) + IF(StrLen(sopt.ramPen)>0) THEN StringF(tempstr,'\s\s',sopt.ramPen,string) ELSE StringF(tempstr,'\sNode\d/PlayPen/\s',cmds.bbsLoc,node,string) IF(Rename(text,tempstr))=FALSE THEN fileCopy(text,tempstr) aePuts('\tPrepared!') @@ -16442,7 +15621,7 @@ PROC scanHoldDesc() ELSE bgFileCheck:=FALSE ENDIF - uploadaFile(1,'','') + uploadaFile(1,'') ENDIF /* end if fi != NL */ lcFileXfr:=FALSE aePuts('\b\n') @@ -16620,7 +15799,7 @@ updesccont: StrCopy(str2,str) StrCopy(str,FilePart(str2),ALL) - IF(StrLen(sopt.ramPen)>0) THEN StringF(str4,'\s/\s',sopt.ramPen,str) ELSE StringF(str4,'\sNode\d/Playpen/\s',cmds.bbsLoc,node,str) + IF(StrLen(sopt.ramPen)>0) THEN StringF(str4,'\s\s',sopt.ramPen,str) ELSE StringF(str4,'\sNode\d/Playpen/\s',cmds.bbsLoc,node,str) StringF(str3,'curl -# -f -k \s -o \s',str2,str4) Execute(str3,NIL,NIL) IF fileExists(str4) @@ -16890,9 +16069,9 @@ EXCEPT DO ENDPROC returnval PROC zmodemReceive(flname:PTR TO CHAR,uLFType) - DEF c - DEF p:PTR TO CHAR DEF temp[100]:STRING + DEF protocol[255]:STRING + IF((logonType>=LOGON_TYPE_REMOTE) AND (localUpload=FALSE) AND (lcFileXfr=FALSE)) IF xprLib.count()=0 @@ -16900,16 +16079,20 @@ PROC zmodemReceive(flname:PTR TO CHAR,uLFType) RETURN RESULT_FAILURE ENDIF - IF ((strCmpi(xprLib.item(loggedOnUser.xferProtocol),'HYDRA',ALL))) + StrCopy(protocol,xprLib.item(loggedOnUser.xferProtocol)) + + IF ((strCmpi(protocol,'HYDRA',ALL))) aePuts('\b\nHYDRA protocol is not currently supported') RETURN RESULT_FAILURE ENDIF IF(uLFType=FALSE) - IF(strCmpi(xprLib.item(loggedOnUser.xferProtocol),'INTERNAL',ALL)) + IF(strCmpi(protocol,'INTERNAL',ALL)) StringF(temp,'\b\nZmodem: Ready to Receive\b\n') - ELSEIF(strCmpi(xprLib.item(loggedOnUser.xferProtocol),'FTP',ALL)) + ELSEIF(strCmpi(protocol,'FTP',ALL)) StringF(temp,'\b\nFTP: Ready to Receive\b\n') + ELSEIF(strCmpi(protocol,'HTTP',ALL)) + StringF(temp,'\b\nHTTP: Ready to Receive\b\n') ELSEIF(checkSecurity(ACS_XPR_RECEIVE)=FALSE) aePuts('\b\nYou are not allowed to upload using external xpr protocols') RETURN RESULT_FAILURE @@ -16920,8 +16103,7 @@ PROC zmodemReceive(flname:PTR TO CHAR,uLFType) ->aePuts('Control-X to Cancel\b\n') ENDIF - xprReceive(flname) - RETURN 1 + RETURN zModemUpload(flname) ELSE IF(lcFileXfr=FALSE) IF(batchasl(flname)) THEN receivePlayPen(TRUE) @@ -16997,7 +16179,7 @@ PROC receivePlayPen(log) s++ ENDWHILE onlineNFiles++ - tBT:=tBT+fib.size + tBT:=addWO(tBT,fib.size) IF log StringF(tempstr,'\tUploading \s[12] \d bytes',fib.filename, fib.size) udLog(tempstr) @@ -17037,7 +16219,7 @@ PROC getUN(sa: PTR TO CHAR) ENDIF ENDPROC 0 -PROC resumeStuff(tfs) +PROC resumeStuff() DEF status,ch DEF string[256]:STRING,path[256]:STRING,ray2[256]:STRING,ray[256]:STRING,str[256]:STRING DEF fBlock:PTR TO fileinfoblock @@ -17148,7 +16330,6 @@ PROC resumeStuff(tfs) IF(StrLen(sopt.ramPen)>0) StrCopy(ray,sopt.ramPen) /* should be filename without @name */ - StrAdd(ray,'/'); StrAdd(ray,str) /* should be old partial file with @num on end */ stat:=1 IF (Rename(path,ray)=FALSE) @@ -17243,7 +16424,7 @@ PROC cleanPlayPen() ENDIF IF(StrLen(sopt.ramPen)>0) - StringF(tempstr,'\s/\s',sopt.ramPen,fib.filename) + StringF(tempstr,'\s\s',sopt.ramPen,fib.filename) REPEAT IF(tempstr[StrLen(tempstr)-1] = "/") JUMP fx2 @@ -17297,7 +16478,7 @@ ENDPROC PROC checkOurList(fname: PTR TO CHAR, str: PTR TO CHAR) DEF fp; DEF buff[255]:STRING - DEF dest[255]:STRING + ->DEF dest[255]:STRING IF((fp:=Open(fname,MODE_OLDFILE)))=0 /* can't find our file */ RETURN RESULT_SUCCESS @@ -17322,7 +16503,6 @@ ENDPROC RESULT_SUCCESS PROC checkForFile(fn: PTR TO CHAR) DEF path[255]:STRING,final[255]:STRING - DEF ft DEF x IF((InStr(fn,'%')>=0) OR ((InStr(fn,'#'))>=0) OR ((InStr(fn,'?'))>=0) OR ((InStr(fn,' '))>=0) OR ((InStr(fn,'/'))>=0) OR @@ -17389,6 +16569,28 @@ PROC checkInPlaypens(s: PTR TO CHAR) UNTIL lock1=NIL ENDPROC 0 +PROC doBgCheck() + DEF tempstr[255]:STRING + DEF bgport + DEF msg:PTR TO jhMessage + + IF (zModemInfo.currentOperation=ZMODEM_UPLOAD) AND bgFileCheck AND (loggedOnUserKeys.userFlags AND USER_BGFILECHECK) + StringF(tempstr,'bgCheckPort\d',node) + IF (bgport:=FindPort(tempstr)) + msg:=AllocMem(SIZEOF jhMessage,MEMF_ANY OR MEMF_CLEAR) + IF msg + msg.command:=BG_CHECKFILE + strCpy(msg.string,FilePart(zModemInfo.fileName),200) + msg.msg.ln.type:=NT_FREEMSG + msg.msg.length:=SIZEOF jhMessage + + ->signal background checking to check the file + PutMsg(bgport,msg) + ENDIF + ENDIF + ENDIF +ENDPROC + PROC backgroundFileCheckThread() DEF bgCheckPort:PTR TO mp DEF bgCheckPortName[255]:STRING @@ -17517,7 +16719,6 @@ PROC testFile(str: PTR TO CHAR, path: PTR TO CHAR) DEF x,x2,stat,r DEF temp[100]:STRING,temp2[100]:STRING DEF temp4[100]:STRING - DEF options[200]:STRING aeGoodFile:=RESULT_NOT_ALLOWED stat:=RESULT_NOT_ALLOWED @@ -17623,12 +16824,13 @@ PROC sysopUpload() DEF string[255]:STRING DEF str[255]:STRING DEF stat,cnt - DEF space,space2 + DEF spacehi,spacelo,space2hi,space2lo DEF path[255]:STRING DEF status,x,ch aePuts('\b\nDestination path for upload? ') stat:=lineInput('','',250,INPUT_TIMEOUT,destpath) + checkPathSlash(destpath) IF((stat<0) OR (StrLen(destpath)=0)) aePuts('\b\n') RETURN @@ -17640,14 +16842,14 @@ PROC sysopUpload() RETURN ENDIF - space:=rFreeSpace(destpath) /* check free space - now in kb instead of bytes */ - IF(space=RESULT_FAILURE) THEN RETURN RESULT_SUCCESS + spacehi,spacelo:=rFreeSpace(destpath) /* check free space - now in mb instead of bytes */ + IF(spacehi=RESULT_FAILURE) THEN RETURN RESULT_SUCCESS IF(StrLen(sopt.ramPen)>0) THEN StringF(path,'\s/',sopt.ramPen) ELSE StringF(path,'\sNode\d/Playpen/',cmds.bbsLoc,node) - space2:=rFreeSpace(path) + space2hi,space2lo:=rFreeSpace(path) - IF((space2)<2048) /* Do we have 2 megs or free space ?? */ + IF((space2hi)<2) /* Do we have 2 megs or free space ?? */ IF checkToolTypeExists(TOOLTYPE_NODE,node,'RAMWORK')=FALSE myError(9) /* no free space */ RETURN RESULT_SUCCESS @@ -17655,9 +16857,9 @@ PROC sysopUpload() ENDIF aePuts('\b\n') - formatSpaceValue(space,tempstr) - formatSpaceValue(space2,tempstr2) - StringF(string,'\s available for uploading. \s at one time.\b\n',tempstr,tempstr2) ->changed to indicate space in kb instead of bytes + formatSpaceValue(spacehi,spacelo,tempstr) + formatSpaceValue(space2hi,space2lo,tempstr2) + StringF(string,'\s available for uploading. \s at one time.\b\n',tempstr,tempstr2) ->changed to indicate space in mb/gb/tb instead of bytes aePuts(string) onlineNFiles:=0 @@ -17676,7 +16878,7 @@ PROC sysopUpload() sysopUploading:=FALSE aePuts('\b\n\b\nFile Uploading Complete...\b\n') - StringF(string,' \d file(s), \dk bytes, \d minute(s). \d second(s), \d cps, \d% efficiency.',onlineNFiles,Div(tBT,1024),Div(tTTM,60),Mod(tTTM,60),zModemInfo.cps,zModemInfo.eff) + StringF(string,' \d file(s), \dk bytes, \d minute(s). \d second(s), \d cps, \d% efficiency.',onlineNFiles,Shr(tBT,10) AND $003fffff,Div(tTTM,60),Mod(tTTM,60),zModemInfo.cps,zModemInfo.eff) aePuts(string) aePuts('\b\n\b\n') @@ -17703,19 +16905,14 @@ PROC sysopUpload() StrCopy(str,recFileNames.item(x)) IF(StrLen(sopt.ramPen)>0) - StringF(tempstr,'\s/\s',sopt.ramPen,str) + StringF(tempstr,'\s\s',sopt.ramPen,str) ELSE StringF(tempstr,'\sNode\d/PLAYPEN/\s',cmds.bbsLoc,node,str) ENDIF StringF(tempstr2,'copying \s to \s',str,destpath) aePuts(tempstr2) - ch:=tempstr2[StrLen(tempstr2)-1]; - IF((ch<>":") AND (ch<>"/")) - StringF(tempstr2,'\s/\s',destpath,str) - ELSE - StringF(tempstr2,'\s\s',destpath,str) - ENDIF + StringF(tempstr2,'\s\s',destpath,str) IF fileExists(tempstr2) StringF(string,' - file exists, do you wish to overwrite? ',FilePart(tempstr2)) @@ -17751,14 +16948,14 @@ ENDPROC RESULT_SUCCESS PROC formatFileSizeForDirList(fsize,fsstr:PTR TO CHAR) DEF tmpSize IF sopt.toggles[TOGGLES_CREDITBYKB] - tmpSize:=Shr(fsize,10) + tmpSize:=Shr(fsize,10) AND $003fffff IF tmpSize<=999999 StringF(fsstr,'\r\d[6]K',tmpSize) ELSE IF checkToolTypeExists(TOOLTYPE_BBSCONFIG,0,'CONVERT_TO_MB')=FALSE StringF(fsstr,'\dK',tmpSize) ELSE - StringF(fsstr,'\r\d[4].\dM',Shr(fsize,20),Div(fsize-Shl(Shr(fsize,20),20),104858)) + StringF(fsstr,'\r\d[4].\dM',Shr(fsize,20) AND $fff,Div(fsize-Shl(Shr(fsize,20) AND $fff,20),104858)) ENDIF ENDIF ELSE @@ -17768,22 +16965,22 @@ PROC formatFileSizeForDirList(fsize,fsstr:PTR TO CHAR) IF checkToolTypeExists(TOOLTYPE_BBSCONFIG,0,'CONVERT_TO_MB')=FALSE StringF(fsstr,'\d',fsize) ELSE - StringF(fsstr,'\r\d[4].\dM',Shr(fsize,20),Div(fsize-Shl(Shr(fsize,20),20),104858)) + StringF(fsstr,'\r\d[4].\dM',Shr(fsize,20) AND $fff,Div(fsize-Shl(Shr(fsize,20) AND $fff,20),104858)) ENDIF ENDIF ENDIF ENDPROC -PROC uploadaFile(uLFType,cmd,params) -> JOE +PROC uploadaFile(uLFType,cmd) -> JOE DEF fBlock: fileinfoblock DEF fLock DEF i,x,x2,x3,cnt,status,moveToLCFILES,hold,cstat,noF,lcfile DEF status2,gstat - DEF peff,pcps,tFS,fSUploading + DEF peff,pcps,tFShi,tFSlo,fSUploadingHi,fSUploadingLo DEF path[256]:STRING,str[255]:STRING,istr[255]:STRING,str2[255]:STRING DEF fmtstr[256]:STRING DEF odate[20]:STRING,fcomment[256]:STRING - DEF ray[256]:STRING,ray2[256]:STRING,temp[256]:STRING,string[256]:STRING + DEF ray[256]:STRING,ray2[256]:STRING,string[256]:STRING DEF buff[255]:STRING DEF tempstr[255]:STRING,tempstr2[255]:STRING,tempstr3[255]:STRING DEF uaf,f @@ -17810,14 +17007,14 @@ PROC uploadaFile(uLFType,cmd,params) -> JOE displayScreen(SCREEN_UPLOAD) ENDIF - tFS:=freeDiskSpace() /* check free space - now in kb instead of bytes */ - IF(tFS=RESULT_FAILURE) THEN RETURN RESULT_SUCCESS + tFShi,tFSlo:=freeDiskSpace() /* check free space - now in mb instead of bytes */ + IF(tFShi=RESULT_FAILURE) THEN RETURN RESULT_SUCCESS IF(StrLen(sopt.ramPen)>0) THEN StringF(path,'\s/',sopt.ramPen) ELSE StringF(path,'\sNode\d/Playpen/',cmds.bbsLoc,node) - fSUploading:=rFreeSpace(path) + fSUploadingHi,fSUploadingLo:=rFreeSpace(path) - IF((fSUploading)<2048) /* Do we have 2 megs or free space ?? */ + IF((fSUploadingHi)<2) /* Do we have 2 megs or free space ?? */ IF checkToolTypeExists(TOOLTYPE_NODE,node,'RAMWORK')=FALSE myError(9) /* no free space */ RETURN RESULT_SUCCESS @@ -17825,14 +17022,6 @@ PROC uploadaFile(uLFType,cmd,params) -> JOE ENDIF IF(uLFType=0) - parseParams(params) - IF(parsedParams.count()>0) - StrCopy(string,params[0]) - setProtocol(string) - ELSE - setProtocol('') - ENDIF - IF(StrLen(sopt.ramPen)>0) /* are we uploading to a diff device */ StringF(buff,'\s UPLOADING to \s..\b\n',xprTitle.item(loggedOnUser.xferProtocol),sopt.ramPen) ELSE /* otherwise normal upload to playpen dir */ @@ -17841,13 +17030,13 @@ PROC uploadaFile(uLFType,cmd,params) -> JOE aePuts(buff) /* show it to the user */ - formatSpaceValue(tFS,tempstr) - formatSpaceValue(fSUploading,tempstr2) - StringF(string,'\s available for uploading. \s at one time.\b\n',tempstr,tempstr2) ->changed to indicate space in kb instead of bytes + formatSpaceValue(tFShi,tFSlo,tempstr) + formatSpaceValue(fSUploadingHi,fSUploadingLo,tempstr2) + StringF(string,'\s available for uploading. \s at one time.\b\n',tempstr,tempstr2) ->changed to indicate space in mb instead of bytes aePuts(string) aePuts('Filename lengths above 12 are not allowed.\b\n\b\n') - zresume:=resumeStuff(tFS) + zresume:=resumeStuff() IF(zresume<0) THEN RETURN zresume IF((zresume=0) AND strCmpi(cmd,'RG',ALL)) aePuts('\b\nThere are no more files to resume on.\b\n\b\n') @@ -17895,7 +17084,7 @@ PROC uploadaFile(uLFType,cmd,params) -> JOE pcps:=zModemInfo.cps ENDIF - StringF(string,' \d file(s), \dk bytes, \d minute(s). \d second(s), \d cps, \d% efficiency.',onlineNFiles+bgCnt,Div(tBT+bgBytes,1024),Div(tTTM,60),Mod(tTTM,60),pcps,peff) + StringF(string,' \d file(s), \dk bytes, \d minute(s). \d second(s), \d cps, \d% efficiency.',onlineNFiles+bgCnt,Shr(tBT+bgBytes,10) AND $003fffff,Div(tTTM,60),Mod(tTTM,60),pcps,peff) aePuts(string) IF (pcps > loggedOnUserKeys.upCPS2) @@ -17908,6 +17097,7 @@ PROC uploadaFile(uLFType,cmd,params) -> JOE IF bgCnt>0 StringF(tempstr,'\b\n\b\n\d files were checked and posted in the background during upload',bgCnt) aePuts(tempstr) + onlineNFiles:=onlineNFiles+bgCnt ENDIF bgCnt:=0 ENDIF @@ -17917,7 +17107,7 @@ PROC uploadaFile(uLFType,cmd,params) -> JOE StrCopy(str,'\t') StrAdd(str,string) - IF(onlineNFiles>0) + IF((onlineNFiles)>0) callersLog(str) udLog(str) IF (readToolType(TOOLTYPE_BBSCONFIG,0,'EXECUTE_ON_UPLOAD',str)) @@ -17936,7 +17126,7 @@ PROC uploadaFile(uLFType,cmd,params) -> JOE IF (checkToolTypeExists(TOOLTYPE_BBSCONFIG,0,'MAIL_ON_UPLOAD')) AND (StrLen(mailOptions.sysopEmail)>0) StringF(str,'\s: Ami-Express logoff notification',cmds.bbsName) StringF(string,'This is a notification that \s from \s has logged off\n\n',loggedOnUser.name,loggedOnUser.location) - sendMail(str,string,TRUE, mailOptions.sysopEmail) + sendMail(str,string,FALSE, NIL,0,mailOptions.sysopEmail) ENDIF ELSE callersLog('\tUpload Failed..') @@ -18047,8 +17237,8 @@ inpAgain: ENDIF IF(StrLen(sopt.ramPen)>0) /* check Ram dir */ - StringF(tempstr,'\s/\s',sopt.ramPen,istr) - StringF(tempstr2,'\s/\s',sopt.ramPen,str) + StringF(tempstr,'\s\s',sopt.ramPen,istr) + StringF(tempstr2,'\s\s',sopt.ramPen,str) ELSE StringF(tempstr,'\sNode\d/PlayPen/\s',cmds.bbsLoc,node,istr) StringF(tempstr2,'\sNode\d/PlayPen/\s',cmds.bbsLoc,node,str) @@ -18067,13 +17257,12 @@ inpAgain: ENDIF /* end if str > 12 */ /*===================== jump here if we also lost carrier ========*/ -ax: formatLongDate(getSystemTime(),fmtstr) StrCopy(odate,fmtstr) /* add our check for ram playpen */ - IF(StrLen(sopt.ramPen)>0) THEN StringF(str2,'\s/\s',sopt.ramPen,str) ELSE StringF(str2,'\sNode\d/Playpen/\s',cmds.bbsLoc,node,str) + IF(StrLen(sopt.ramPen)>0) THEN StringF(str2,'\s\s',sopt.ramPen,str) ELSE StringF(str2,'\sNode\d/Playpen/\s',cmds.bbsLoc,node,str) IF((fLock:=Lock(str2,ACCESS_READ))=NIL) myError(8) @@ -18235,7 +17424,7 @@ move_It: /* gets here if lostcarrier, and file is complete but not when file IF(rzmsg) THEN StringF(tempstr2,'\sF\d/\s',msgBaseLocation,mailHeader.msgNumb,str) IF(StrLen(sopt.ramPen)>0) - StringF(tempstr,'\s/\s',sopt.ramPen,str) + StringF(tempstr,'\s\s',sopt.ramPen,str) ELSE StringF(tempstr,'\sNode\d/PLAYPEN/\s',cmds.bbsLoc,node,str) ENDIF @@ -18270,7 +17459,7 @@ move_It: /* gets here if lostcarrier, and file is complete but not when file /* Add Uploaded Bytes to Users Account */ IF((hold=NIL) AND (lcfile=NIL) AND (rzmsg=NIL)) IF creditAccountTrackUploads(loggedOnUser) - IF sopt.toggles[TOGGLES_CREDITBYKB] THEN fsize:=Shr(fsize,10) + IF sopt.toggles[TOGGLES_CREDITBYKB] THEN fsize:=Shr(fsize,10) AND $003fffff addBCD(loggedOnUserMisc.uploadBytesBCD,fsize) loggedOnUser.bytesUpload:=convertFromBCD(loggedOnUserMisc.uploadBytesBCD) ENDIF @@ -18350,7 +17539,7 @@ eit: /* we get here after lcfile but gugued*/ tempsize:=tBT IF sopt.toggles[TOGGLES_CREDITBYKB] - tempsize:=Shr(tempsize,10) + tempsize:=Shr(tempsize,10) AND $003fffff ENDIF IF(lcfile=FALSE) AND (bytesADL<>$7fffffff) THEN bytesADL:=bytesADL+tempsize /* dont add bytes if files moved to LCFILES DIR */ @@ -18391,7 +17580,7 @@ PROC doBackgroundCheck(fname:PTR TO CHAR) IF(StrLen(sopt.ramPen)>0) StringF(path,'\s/',sopt.ramPen) - StringF(fileName,'\s/\s',sopt.ramPen,fname) + StringF(fileName,'\s\s',sopt.ramPen,fname) ELSE StringF(path,'\sNode\d/Playpen/',cmds.bbsLoc,node) StringF(fileName,'\sNode\d/Playpen/\s',cmds.bbsLoc,node,fname) @@ -18411,7 +17600,7 @@ PROC doBackgroundCheck(fname:PTR TO CHAR) exitLoop:=(runSysCommand(tempstr2,fileName)=FALSE) ENDIF UNTIL(exitLoop) - + IF fileExists(tempstr) fh:=Open(tempstr,MODE_OLDFILE) @@ -18428,10 +17617,12 @@ PROC doBackgroundCheck(fname:PTR TO CHAR) fsize:=getFileSize(fileName) + status2:=RESULT_NOT_ALLOWED status2:=testFile(fname,path) status:=checkForFile(fname) + IF(fcomment[0]="/") THEN status:=RESULT_PRIVATE hold:=0 @@ -18459,7 +17650,7 @@ PROC doBackgroundCheck(fname:PTR TO CHAR) StringF(tempstr2,'\sHOLD/\s',currentConfDir,fname) IF(StrLen(sopt.ramPen)>0) - StringF(tempstr,'\s/\s',sopt.ramPen,fname) + StringF(tempstr,'\s\s',sopt.ramPen,fname) ELSE StringF(tempstr,'\sNode\d/PLAYPEN/\s',cmds.bbsLoc,node,fname) ENDIF @@ -18497,7 +17688,7 @@ PROC doBackgroundCheck(fname:PTR TO CHAR) /* Add Uploaded Bytes to Users Account */ IF((hold=NIL)) IF creditAccountTrackUploads(loggedOnUser) - IF sopt.toggles[TOGGLES_CREDITBYKB] THEN fsize:=Shr(fsize,10) + IF sopt.toggles[TOGGLES_CREDITBYKB] THEN fsize:=Shr(fsize,10) AND $003fffff addBCD(loggedOnUserMisc.uploadBytesBCD,fsize) loggedOnUser.bytesUpload:=convertFromBCD(loggedOnUserMisc.uploadBytesBCD) ENDIF @@ -18616,7 +17807,7 @@ PROC calcConfBad(confNum) DEF bad DEF i - cb:=confBases.item(confNum) + cb:=confBases.item(getConfIndex(confNum,1)) IF(cb.ratioType<2) convertToBCD(0,badBCD) @@ -18649,11 +17840,11 @@ PROC downloadAFile(cmdcode: PTR TO CHAR, params) HANDLE DEF tempList=NIL:PTR TO stdlist DEF item:PTR TO flagFileItem DEF finalList:PTR TO stdlist - DEF tmpItem: flagFileItem DEF tfsizes=NIL:PTR TO stdlist DEF freeDFlags=NIL:PTR TO stdlist DEF freeDFlag DEF cb:PTR TO confBase + DEF estDlCPS proto:=0 nad:=0 @@ -18671,6 +17862,12 @@ PROC downloadAFile(cmdcode: PTR TO CHAR, params) HANDLE aePuts('\b\n') ENDIF + IF loggedOnUserMisc.lastDlCPS<>0 + estDlCPS:=loggedOnUserMisc.lastDlCPS + ELSE + estDlCPS:=Div(onlineBaud,10) + ENDIF + dtfsize:=0 displayULStats(loggedOnUser,loggedOnUserMisc) /* Show User stats.. Num Dnloads, uploads */ @@ -18798,7 +17995,7 @@ arestart1: arestart: WHILE TRUE - tsec:=Div(dtfsize,Div(onlineBaud,10)) + tsec:=Div(dtfsize,estDlCPS) min:=tsec/60 IF(((Div(timeLimit,60))-min)<0) aePuts('Not enough time for requested downloads.\b\n\b\n') @@ -18807,29 +18004,29 @@ arestart: IF(checkSecurity(ACS_CONFERENCE_ACCOUNTING)) - saveMsgPointers(currentConf) + saveMsgPointers(currentConf,currentMsgBase) tempsize:=0 FOR i:=0 TO cmds.numConf-1 tempsize:=tempsize+tfsizes.item(i) ENDFOR - IF sopt.toggles[TOGGLES_CREDITBYKB] THEN tempsize:=Shr(tempsize,10) + IF sopt.toggles[TOGGLES_CREDITBYKB] THEN tempsize:=Shr(tempsize,10) AND $003fffff IF(tempsize>bytesADL) aePuts('Not enough daily byte allowance for requested downloads\b\n\b\n') Throw(ERR_EXCEPT,RESULT_SUCCESS) ENDIF - FOR i:=0 TO cmds.numConf-1 - tempsize:=tfsizes.item(i) - freeDFlag:=freeDFlags.item(i) + FOR i:=1 TO cmds.numConf + tempsize:=tfsizes.item(i-1) + freeDFlag:=freeDFlags.item(i-1) - IF sopt.toggles[TOGGLES_CREDITBYKB] THEN tempsize:=Shr(tempsize,10) + IF sopt.toggles[TOGGLES_CREDITBYKB] THEN tempsize:=Shr(tempsize,10) AND $003fffff bad:=calcConfBad(i) - cb:=confBases.item(i) + cb:=confBases.item(getConfIndex(i,1)) IF(((bad-tempsize)<0) AND (cb.ratioType<2) AND (cb.ratio<>0) AND (creditAccountEnabled(loggedOnUser)=FALSE)) - StringF(string,'Conf \d: Not enough free bytes for requested downloads.\b\n\b\n',relConf(i+1)) + StringF(string,'Conf \d: Not enough free bytes for requested downloads.\b\n\b\n',relConf(i)) aePuts(string) Throw(ERR_EXCEPT,RESULT_SUCCESS) ENDIF @@ -18838,7 +18035,7 @@ arestart: nad:=(cb.ratio*(cb.upload+1))-cb.downloads IF (nad0) AND (cb.ratio<>0) AND (creditAccountEnabled(loggedOnUser)=FALSE) @@ -18867,7 +18064,7 @@ arestart: tempsize:=tempsize+tfsizes.item(i) freeDFlag:=freeDFlag+freeDFlags.item(i) ENDFOR - IF sopt.toggles[TOGGLES_CREDITBYKB] THEN tempsize:=Shr(tempsize,10) + IF sopt.toggles[TOGGLES_CREDITBYKB] THEN tempsize:=Shr(tempsize,10) AND $003fffff IF bad0 + StringF(tempStr,' Batch Download Estimate at \d cps:\b\n',estDlCPS) + ELSE + StringF(tempStr,' Batch Download Estimate at \d bps:\b\n',onlineBaud) + ENDIF aePuts(tempStr) -astart2: - tsec:=Div(dtfsize,Div(onlineBaud,10)) + + tsec:=Div(dtfsize,estDlCPS) min:=tsec/60 secs:=tsec-(min*60) - StringF(tempStr,' \d files, \dk bytes, \d mins \d secs\b\n',numFiles,Div(dtfsize,1024),min,secs) + StringF(tempStr,' \d files, \dk bytes, \d mins \d secs\b\n',numFiles,Shr(dtfsize,10) AND $003fffff,min,secs) aePuts(tempStr) IF(min>(Div(timeLimit,60))) @@ -19001,9 +18201,6 @@ breakd: IF (mystat<>13) THEN aePuts('Goodbye!\b\n\b\n') ELSE aePuts('\b\n\b\n') - -sysopDL: - dTBT:=0 tBT:=0 tTTM:=0 @@ -19030,7 +18227,7 @@ sysopDL: pcps:=zModemInfo.cps ENDIF ->// (RTS) added dnload cps rate Fri Mar 27 13:13:29 1992 - StringF(string,' \d files, \dk bytes, \d minutes \d seconds \d cps, \d% efficiency at \d',onlineNFiles,Div(tBT,1024),Div(tTTM,60),Mod(tTTM,60),pcps,peff,onlineBaud) + StringF(string,' \d files, \dk bytes, \d minutes \d seconds \d cps, \d% efficiency at \d',onlineNFiles,Shr(tBT,10) AND $003fffff,Div(tTTM,60),Mod(tTTM,60),pcps,peff,onlineBaud) aePuts(string) aePuts('\b\n\b\n') @@ -19040,6 +18237,7 @@ sysopDL: IF pcps>65535 THEN pcps:=65535 loggedOnUserKeys.oldDnCPS:=pcps ENDIF + loggedOnUserMisc.lastDlCPS:=pcps clearFlagItems(finalList) END finalList @@ -19082,8 +18280,6 @@ PROC ccom() DEF i,i2,stat DEF str[81]:STRING DEF display_time[30]:STRING - DEF string[200]:STRING - DEF date[20]:STRING DEF buff[255]: STRING formatLongDateTime(getSystemTime(),display_time) @@ -19276,7 +18472,7 @@ PROC showVoteTopics() IF fileExists(votefile) confbyte:=Shr(topicNum+3,3) confbit:=Shl(1,Mod(topicNum+3,8)) - cb:=confBases.item(currentConf-1) + cb:=confBases.item(getConfIndex(currentConf,1)) voted:=(cb.handle[confbyte] AND confbit)<>0 loadMsg(votefile) @@ -19297,7 +18493,7 @@ PROC createVoteTopic() DEF topicNum,lock DEF votefile[255]:STRING DEF tempStr[255]:STRING - DEF i,ans,questNum,fh + DEF ans,questNum,fh StringF(votefile,'\sVote',currentConfDir) IF(lock:=CreateDir(votefile)) @@ -19417,7 +18613,7 @@ ENDPROC PROC editVoteTopic() DEF topicNum,questNum,ans DEF votefile[255]:STRING - DEF n,i + DEF n aePuts('\b\nENTER TOPIC NUMBER (1-25)>: ') topicNum:=numberInputNoDefault() @@ -19526,7 +18722,7 @@ PROC vote() IF fileExists(votefile) confbyte:=Shr(topicNum+3,3) confbit:=Shl(1,Mod(topicNum+3,8)) - cb:=confBases.item(currentConf-1) + cb:=confBases.item(getConfIndex(currentConf,1)) voted:=(cb.handle[confbyte] AND confbit)<>0 loadMsg(votefile) FOR i:=0 TO lines-1 @@ -19556,7 +18752,7 @@ PROC vote() IF (topicNum>0) AND (topicNum<26) confbyte:=Shr(topicNum+3,3) confbit:=Shl(1,Mod(topicNum+3,8)) - cb:=confBases.item(currentConf-1) + cb:=confBases.item(getConfIndex(currentConf,1)) voted:=(cb.handle[confbyte] AND confbit)<>0 IF voted showTopicVotes(topicNum) @@ -19740,7 +18936,7 @@ PROC topicVote(topicNum) UnLock(lock) ->flag voting as complete - cb:=confBases.item(currentConf-1) + cb:=confBases.item(getConfIndex(currentConf,1)) confbyte:=Shr(topicNum+3,3) confbit:=Shl(1,Mod(topicNum+3,8)) cb.handle[confbyte]:=cb.handle[confbyte] OR confbit @@ -19823,6 +19019,18 @@ PROC numberInput(n) lineInput('',tempStr,5,INPUT_TIMEOUT,tempStr) ENDPROC Val(tempStr) AND $FFFF +PROC rJoinInput(conf,msgbase) + DEF tempStr[20]:STRING + DEF p + lineInput('','',5,INPUT_TIMEOUT,tempStr) + conf:=Val(tempStr) + IF (p:=InStr(tempStr,'.'))>=0 + msgbase:=Val(tempStr+p+1) + ELSE + msgbase:=0 + ENDIF +ENDPROC conf,msgbase + PROC longNumberInput(n) DEF tempStr[20]:STRING formatUnsignedLong(n,tempStr) @@ -19871,80 +19079,6 @@ PROC bcdVal(inStr:PTR TO CHAR, bcdArray:PTR TO CHAR) ENDIF ENDPROC valid -PROC subBCD2(bcdTotal:PTR TO CHAR, bcdValToSub: PTR TO CHAR) - MOVE.L bcdValToSub,A0 - LEA 8(A0),A0 - MOVE.L bcdTotal,A1 - LEA 8(A1),A1 - - SUB.L D0,D0 ->clear X flag - - SBCD -(A0),-(A1) - SBCD -(A0),-(A1) - SBCD -(A0),-(A1) - SBCD -(A0),-(A1) - SBCD -(A0),-(A1) - SBCD -(A0),-(A1) - SBCD -(A0),-(A1) - SBCD -(A0),-(A1) -ENDPROC - - -PROC addBCD2(bcdTotal:PTR TO CHAR, bcdValToAdd: PTR TO CHAR) - MOVE.L bcdValToAdd,A0 - LEA 8(A0),A0 - MOVE.L bcdTotal,A1 - LEA 8(A1),A1 - - SUB.L D0,D0 ->clear X flag - - ABCD -(A0),-(A1) - ABCD -(A0),-(A1) - ABCD -(A0),-(A1) - ABCD -(A0),-(A1) - ABCD -(A0),-(A1) - ABCD -(A0),-(A1) - ABCD -(A0),-(A1) - ABCD -(A0),-(A1) -ENDPROC - - -PROC addBCD(bcdTotal:PTR TO CHAR, valToAdd) - DEF bcdVal[8]:ARRAY OF CHAR - - convertToBCD(valToAdd,bcdVal) - addBCD2(bcdTotal,bcdVal) -ENDPROC - -PROC divBCD1024(bcdVal:PTR TO CHAR) - - DEF decVal[16]:ARRAY OF CHAR - DEF i,i2,n=0,c=0 - - FOR i:=0 TO 7 - decVal[n]:=Shr(bcdVal[i] AND $f0,4) - n++ - decVal[n]:=bcdVal[i] AND $f - n++ - ENDFOR - - FOR i2:=0 TO 9 - c:=0 - FOR i:=0 TO 15 - n:=Shr(decVal[i],1) - IF c THEN n:=n+5 - c:=decVal[i] AND 1 - decVal[i]:=n - ENDFOR - ENDFOR - - n:=0 - FOR i:=0 TO 7 - bcdVal[i]:=Shl(decVal[n],4)+decVal[n+1] - n:=n+2 - ENDFOR -ENDPROC - PROC checkLockAccounts(f6) DEF tempstr[255]:STRING DEF fh,res=FALSE @@ -19966,15 +19100,40 @@ PROC checkLockAccounts(f6) ENDIF ENDPROC +PROC findUserAnswers(which,answersFilename:PTR TO CHAR) + DEF i,lock + DEF tempStr[255]:STRING + + StrCopy(answersFilename,'') + i:=0 + REPEAT + StringF(tempStr,'\sNode\d',cmds.bbsLoc,i) + lock:=Lock(tempStr,ACCESS_READ) + IF lock<>0 THEN UnLock(lock) + + IF lock + IF checkToolTypeExists(TOOLTYPE_NODE,i,'CENTRAL_ANSWERS') + StringF(answersFilename,'\sAnswers/\d',cmds.bbsLoc,which) + ELSE + StringF(answersFilename,'\sNode\d/Answers/\d',cmds.bbsLoc,i,which) + ENDIF + ENDIF + i++ + UNTIL (lock=0) OR fileExists(answersFilename) OR (i>MAXNODES) + IF (i>MAXNODES) OR (lock=0) THEN StrCopy(answersFilename,'') +ENDPROC StrLen(answersFilename)>0 + PROC editInfo(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: PTR TO userMisc,f6) DEF flag, command DEF tempStr[255]:STRING DEF temp,stat,i,preset DEF checkLock + DEF page=0 + DEF value1,value2 nofkeys:=1 - displayAccount(which,hoozer,hoozer2,hoozer3,f6) + displayAccount(which,page,hoozer,hoozer2,hoozer3,f6) StrCopy(tempStr,hoozer.name) UpperStr(tempStr) strCpy(hoozer2.userName,tempStr,31) @@ -19988,6 +19147,19 @@ PROC editInfo(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: flag:=0 +->b) internet name +->c) email address +->d) lines per screen +->e) computer type +->f) screen type +->g) screen clear +->h) transfer protocol +->i) zoom type +->j) available for chat +->k) translator +->l) expert mode +->m) bg file check + SELECT command CASE "\t" flag:=2 @@ -19995,16 +19167,18 @@ PROC editInfo(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: aePuts('No-Save\b\n') flag:=1 CASE " " - displayAccountInfo(which,hoozer,hoozer2,hoozer3,f6) + ->page:=Eor(page,1) + ->sendCLS() + ->displayAccount(which,page,hoozer,hoozer2,hoozer3,f6) CASE "+" IF(onlineEdit=FALSE) which:=which+1 IF(loadAccount(which,hoozer,hoozer2,hoozer3)<>RESULT_FAILURE) - displayAccountInfo(which,hoozer,hoozer2,hoozer3,f6) + displayAccountInfo(which,page,hoozer,hoozer2,hoozer3,f6) ELSE which:=1 loadAccount(which,hoozer,hoozer2,hoozer3) - displayAccountInfo(which,hoozer,hoozer2,hoozer3,f6) + displayAccountInfo(which,page,hoozer,hoozer2,hoozer3,f6) ENDIF ENDIF CASE "-" @@ -20012,28 +19186,24 @@ PROC editInfo(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: which:=which-1 IF(which<1) THEN which:=findLastAccount() loadAccount(which,hoozer,hoozer2,hoozer3) - displayAccountInfo(which,hoozer,hoozer2,hoozer3,f6) + displayAccountInfo(which,page,hoozer,hoozer2,hoozer3,f6) ENDIF CASE "!" /* Credit Maintenance */ creditMaintenance(which,hoozer,hoozer2,hoozer3,f6) - displayAccount(which,hoozer,hoozer2,hoozer3,f6) + displayAccount(which,page,hoozer,hoozer2,hoozer3,f6) CASE "*" /* User Notes */ userNotes(which,hoozer,hoozer2,hoozer3,f6) - displayAccount(which,hoozer,hoozer2,hoozer3,f6) + displayAccount(which,page,hoozer,hoozer2,hoozer3,f6) CASE "@" /* Conference Accounting */ - IF checkToolTypeExists(TOOLTYPE_ACCESS,hoozer.secStatus,ListItem(securityNames,ACS_CONFERENCE_ACCOUNTING)) - conferenceAccounting(which,hoozer,hoozer2,hoozer3,f6) - displayAccount(which,hoozer,hoozer2,hoozer3,f6) - ENDIF + conferenceAccounting(hoozer,hoozer2,hoozer3,f6) + displayAccount(which,page,hoozer,hoozer2,hoozer3,f6) CASE "?" - IF checkToolTypeExists(TOOLTYPE_NODE,node,'CENTRAL_ANSWERS') - StringF(tempStr,'\sAnswers/\d',cmds.bbsLoc,which) - IF fileExists(tempStr) - sendCLS() - displayFile(tempStr,TRUE,FALSE) - doPause() - displayAccount(which,hoozer,hoozer2,hoozer3,f6) - ENDIF + findUserAnswers(which,tempStr) + IF StrLen(tempStr)>0 + sendCLS() + displayFile(tempStr,TRUE,FALSE) + doPause() + displayAccount(which,page,hoozer,hoozer2,hoozer3,f6) ENDIF ENDSELECT @@ -20049,6 +19219,7 @@ PROC editInfo(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: hoozer.newUser:=0 hoozer.confRJoin:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.CONFRJOIN') + hoozer.msgBaseRJoin:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.MSGBASERJOIN') hoozer.secStatus:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.ACCESS') hoozer.secLibrary:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.RATIO') hoozer.timeLimit:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.TIME_LIMIT') @@ -20068,7 +19239,7 @@ PROC editInfo(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: ->//(RTS) hoozer2->baud_rate = 0 ->saveAccount(hoozer,hoozer2,hoozer3,0,0) - displayAccountInfo(which,hoozer,hoozer2,hoozer3,f6) + displayAccountInfo(which,page,hoozer,hoozer2,hoozer3,f6) ENDIF ENDIF @@ -20083,12 +19254,12 @@ PROC editInfo(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: stat:=saveAccount(hoozer,hoozer2,hoozer3,stat,1) IF(stat<>RESULT_SUCCESS) THEN aePuts('Can''t Save account\b\n') deleteConfAccess(stat) - displayAccountInfo(which,hoozer,hoozer2,hoozer3,f6) + displayAccountInfo(which,page,hoozer,hoozer2,hoozer3,f6) flag:=0 CASE "~" /* SAVE */ aePuts('Save\b\n') hoozer.newUser:=0 - displayAccountInfo(which,hoozer,hoozer2,hoozer3,f6) + displayAccountInfo(which,page,hoozer,hoozer2,hoozer3,f6) IF(hoozer.slotNumber=0) hoozer2.number:=0 stat:=saveAccount(hoozer,hoozer2,hoozer3,which,1) /* 1 = FORCE SAVE */ @@ -20167,7 +19338,7 @@ PROC editInfo(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: aePuts('') StrCopy(tempStr,hoozer.phoneNumber) lineInput('',tempStr,12,INPUT_TIMEOUT,tempStr) - strCpy(tempStr,hoozer.phoneNumber,13) + strCpy(hoozer.phoneNumber,tempStr,13) flag:=0 CASE "F" /* conference access */ aePuts('') @@ -20205,7 +19376,9 @@ PROC editInfo(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: flag:=0 CASE "J" /* conference ReJoin */ aePuts('') - hoozer.confRJoin:=numberInput(hoozer.confRJoin) + value1,value2:=rJoinInput(hoozer.confRJoin, hoozer.msgBaseRJoin) + hoozer.confRJoin:=value1 + hoozer.msgBaseRJoin:=value2 flag:=0 CASE "K" /* UPLOADS */ aePuts('') @@ -20230,7 +19403,7 @@ PROC editInfo(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: flag:=0 CASE "%" aePuts('') - hoozer2.timesOnToday:=numberInput(hoozer2.timesOnToday) + hoozer2.timesOnToday:=numberInput(getTodaysCalls(hoozer,hoozer2)) flag:=0 CASE "O" /* Bytes Uploaded */ aePuts('') @@ -20315,7 +19488,7 @@ PROC editInfo(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: ENDPROC flag PROC applyConfPresets(hoozer:PTR TO user, preset:LONG) - DEF i + DEF i,m DEF cb:PTR TO confBase IF loggedOnUser<>NIL THEN masterSavePointers(loggedOnUser) @@ -20323,15 +19496,17 @@ PROC applyConfPresets(hoozer:PTR TO user, preset:LONG) masterLoadPointers(hoozer) FOR i:=1 TO cmds.numConf - cb:=confBases.item(i-1) + FOR m:=1 TO getConfMsgBaseCount(i) + cb:=confBases.item(getConfIndex(i,m)) - IF checkToolTypeExists(TOOLTYPE_PRESET,preset,'PRESET.RATIO') - cb.ratio:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.RATIO') - ENDIF + IF checkToolTypeExists(TOOLTYPE_PRESET,preset,'PRESET.RATIO') + cb.ratio:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.RATIO') + ENDIF - IF checkToolTypeExists(TOOLTYPE_PRESET,preset,'PRESET.RATIOTYPE') - cb.ratioType:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.RATIOTYPE') - ENDIF + IF checkToolTypeExists(TOOLTYPE_PRESET,preset,'PRESET.RATIOTYPE') + cb.ratioType:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.RATIOTYPE') + ENDIF + ENDFOR ENDFOR masterSavePointers(hoozer) @@ -20685,10 +19860,10 @@ PROC creditMaintenance(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, ENDPROC flag -PROC conferenceAccounting(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: PTR TO userMisc,f6) +PROC conferenceAccounting(hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3: PTR TO userMisc,f6) DEF tempstr[255]:STRING,tempstr2[255]:STRING DEF cb: PTR TO confBase - DEF i,flag=0,conf,ch,oldval + DEF i,m,flag=0,conf,msgbase,ch,oldval DEF checkLock DEF oldBCD[8]:ARRAY OF CHAR @@ -20696,54 +19871,60 @@ PROC conferenceAccounting(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKey masterLoadPointers(hoozer) - IF f6=FALSE + IF f6 ->recalculate totals - hoozer.uploads:=0 - hoozer.downloads:=0 - hoozer.bytesUpload:=0 - hoozer.bytesDownload:=0 - FOR i:=0 TO 7 - hoozer3.downloadBytesBCD[i]:=0 - hoozer3.uploadBytesBCD[i]:=0 - ENDFOR + + IF(checkSecurity(ACS_CONFERENCE_ACCOUNTING)) + hoozer.uploads:=0 + hoozer.downloads:=0 + hoozer.bytesUpload:=0 + hoozer.bytesDownload:=0 + FOR i:=0 TO 7 + hoozer3.downloadBytesBCD[i]:=0 + hoozer3.uploadBytesBCD[i]:=0 + ENDFOR + ENDIF hoozer.messagesPosted:=0 FOR i:=1 TO cmds.numConf - cb:=confBases.item(i-1) - IF (isTempConf(hoozer,i-1)) - hoozer.uploads:=hoozer.uploads+cb.upload - hoozer.downloads:=hoozer.downloads+cb.downloads - hoozer.messagesPosted:=hoozer.messagesPosted+cb.messagesPosted - addBCD2(hoozer3.downloadBytesBCD,cb.downloadBytesBCD) - addBCD2(hoozer3.uploadBytesBCD,cb.uploadBytesBCD) - hoozer.bytesDownload:=convertFromBCD(hoozer3.downloadBytesBCD) - hoozer.bytesUpload:=convertFromBCD(hoozer3.uploadBytesBCD) - ENDIF + FOR m:=1 TO getConfMsgBaseCount(i) + cb:=confBases.item(getConfIndex(i,m)) + IF (checkConfAccess(i,hoozer)) + IF(checkSecurity(ACS_CONFERENCE_ACCOUNTING)) AND (readToolTypeInt(TOOLTYPE_CONF,conf,'CONFDB_SHARED')<=0) + hoozer.uploads:=hoozer.uploads+cb.upload + hoozer.downloads:=hoozer.downloads+cb.downloads + addBCD2(hoozer3.downloadBytesBCD,cb.downloadBytesBCD) + addBCD2(hoozer3.uploadBytesBCD,cb.uploadBytesBCD) + hoozer.bytesDownload:=convertFromBCD(hoozer3.downloadBytesBCD) + hoozer.bytesUpload:=convertFromBCD(hoozer3.uploadBytesBCD) + ENDIF + hoozer.messagesPosted:=hoozer.messagesPosted+cb.messagesPosted + ENDIF + ENDFOR ENDFOR ENDIF conf:=hoozer.confRJoin + msgbase:=hoozer.msgBaseRJoin - IF isTempConf(hoozer,conf-1) + IF checkConfAccess(conf,hoozer)=FALSE i:=0 REPEAT conf++ IF conf>cmds.numConf THEN conf:=1 i++ - UNTIL (isTempConf(hoozer,conf-1)) OR (i>cmds.numConf) - ENDIF - - IF (i>cmds.numConf) - RETURN 1 + UNTIL (checkConfAccess(conf,hoozer)) OR (i>cmds.numConf) + IF (i>cmds.numConf) + RETURN 1 + ENDIF ENDIF checkLock:=checkLockAccounts(f6) - sendCLS() REPEAT conPuts('[0 p') - cb:=confBases.item(conf-1) + cb:=confBases.item(getConfIndex(conf,msgbase)) StringF(tempstr,' Name: \s[32] ',hoozer.name) aePuts(tempstr) @@ -20751,68 +19932,75 @@ PROC conferenceAccounting(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKey StringF(tempstr,' Loc.: \s[29]\b\n',hoozer.location) aePuts(tempstr) - StringF(tempstr,' Conf: \s[29]\b\n',getConfName(conf)) + IF getConfMsgBaseCount(conf)>1 + getMsgBaseName(conf,msgbase,tempstr) + StringF(tempstr2,'\s - \s',getConfName(conf),tempstr) + ELSE + getConfName(conf,tempstr2) + ENDIF + + StringF(tempstr,' Conf: \s[60]\b\n',tempstr2) aePuts(tempstr) - StringF(tempstr,'G>Ratio .........: \d[7]\b\n',cb.ratio) + StringF(tempstr,'G>Ratio .........: \d[7]\b\n',cb.ratio AND $FFFF) aePuts(tempstr) - StringF(tempstr,'I>Ratio Type ....: \d[5]',cb.ratioType) + StringF(tempstr,'I>Ratio Type ....: \d[5]',cb.ratioType AND $FFFF) aePuts(tempstr) IF(cb.ratioType=0) THEN aePuts(' <-Byte)') IF(cb.ratioType=1) THEN aePuts(' <-B/F) ') IF(cb.ratioType=2) THEN aePuts(' <-File)') - StringF(tempstr,'K>Uploads .......: \d[10]\b\n',cb.upload) + StringF(tempstr,'K>Uploads .......: \d[10]\b\n',cb.upload AND $FFFF) aePuts(tempstr) - StringF(tempstr,'M>Downloads .....: \d[10]\b\n',cb.downloads) + StringF(tempstr,'M>Downloads .....: \d[10]\b\n',cb.downloads AND $FFFF) aePuts(tempstr) formatBCD(cb.uploadBytesBCD,tempstr2) IF sopt.toggles[TOGGLES_CREDITBYKB] - StringF(tempstr,'O>KBytes Uled ...: \s[10]\b\n',tempstr2) + StringF(tempstr,'O>KBytes Uled ...: \s[16]\b\n',tempstr2) ELSE - StringF(tempstr,'O>Bytes Uled ....: \s[10]\b\n',tempstr2) + StringF(tempstr,'O>Bytes Uled ....: \s[16]\b\n',tempstr2) ENDIF aePuts(tempstr) formatBCD(cb.downloadBytesBCD,tempstr2) IF sopt.toggles[TOGGLES_CREDITBYKB] - StringF(tempstr,'P>KBytes Dled ...: \s[10]\b\n',tempstr2) + StringF(tempstr,'P>KBytes Dled ...: \s[16]\b\n',tempstr2) ELSE - StringF(tempstr,'P>Bytes Dled ....: \s[10]\b\n',tempstr2) + StringF(tempstr,'P>Bytes Dled ....: \s[16]\b\n',tempstr2) ENDIF aePuts(tempstr) - StringF(tempstr,'L>Messages Posted: \d[10]',cb.messagesPosted) + StringF(tempstr,'L>Messages Posted: \d[10]',cb.messagesPosted AND $FFFF) aePuts(tempstr) aePuts('Accumulated Total') - StringF(tempstr,'Uploads .......: \d[10]\b\n',hoozer.uploads) + StringF(tempstr,'Uploads .......: \d[10]\b\n',hoozer.uploads AND $FFFF) aePuts(tempstr) - StringF(tempstr,'Downloads .....: \d[10]\b\n',hoozer.downloads) + StringF(tempstr,'Downloads .....: \d[10]\b\n',hoozer.downloads AND $FFFF) aePuts(tempstr) formatBCD(hoozer3.uploadBytesBCD,tempstr2) IF sopt.toggles[TOGGLES_CREDITBYKB] - StringF(tempstr,'KBytes Uled ...: \s[10]\b\n',tempstr2) + StringF(tempstr,'KBytes Uled ...: \s[16]\b\n',tempstr2) ELSE - StringF(tempstr,'Bytes Uled ....: \s[10]\b\n',tempstr2) + StringF(tempstr,'Bytes Uled ....: \s[16]\b\n',tempstr2) ENDIF aePuts(tempstr) formatBCD(hoozer3.downloadBytesBCD,tempstr2) IF sopt.toggles[TOGGLES_CREDITBYKB] - StringF(tempstr,'KBytes Dled ...: \s[10]\b\n',tempstr2) + StringF(tempstr,'KBytes Dled ...: \s[16]\b\n',tempstr2) ELSE - StringF(tempstr,'Bytes Dled ....: \s[10]\b\n',tempstr2) + StringF(tempstr,'Bytes Dled ....: \s[16]\b\n',tempstr2) ENDIF aePuts(tempstr) - StringF(tempstr,'Messages_Posted: \d[10]',hoozer.messagesPosted) + StringF(tempstr,'Messages_Posted: \d[10]',hoozer.messagesPosted AND $FFFF) aePuts(tempstr) aePuts(' -/+=Prev/Next Conference ~=SAVE\n') @@ -20830,15 +20018,24 @@ PROC conferenceAccounting(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKey SELECT ch CASE "+" - REPEAT - conf++ - IF conf>cmds.numConf THEN conf:=1 - UNTIL isTempConf(hoozer,conf-1) + msgbase:=msgbase+1 + IF msgbase>getConfMsgBaseCount(conf) + REPEAT + conf++ + IF conf>cmds.numConf THEN conf:=1 + UNTIL checkConfAccess(conf,hoozer) + msgbase:=1 + ENDIF CASE "-" - REPEAT - conf-- - IF conf<1 THEN conf:=cmds.numConf - UNTIL isTempConf(hoozer,conf-1) + msgbase:=msgbase-1 + IF msgbase<1 + REPEAT + conf-- + IF conf<1 THEN conf:=cmds.numConf + UNTIL checkConfAccess(conf,hoozer) + msgbase:=getConfMsgBaseCount(conf) + ENDIF + CASE "\t" flag:=1 ENDSELECT @@ -20859,12 +20056,12 @@ PROC conferenceAccounting(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKey aePuts('') oldval:=cb.upload cb.upload:=numberInput(cb.upload) - hoozer.uploads:=hoozer.uploads-oldval+cb.upload + IF(checkSecurity(ACS_CONFERENCE_ACCOUNTING)) THEN hoozer.uploads:=hoozer.uploads-oldval+cb.upload CASE "M" aePuts('') oldval:=cb.downloads cb.downloads:=numberInput(cb.downloads) - hoozer.downloads:=hoozer.downloads-oldval+cb.downloads + IF(checkSecurity(ACS_CONFERENCE_ACCOUNTING)) THEN hoozer.downloads:=hoozer.downloads-oldval+cb.downloads CASE "O" aePuts('') @@ -20873,9 +20070,11 @@ PROC conferenceAccounting(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKey ENDFOR bcdNumberInput(cb.uploadBytesBCD) cb.bytesUpload:=convertFromBCD(cb.uploadBytesBCD) - subBCD2(hoozer3.uploadBytesBCD,oldBCD) - addBCD2(hoozer3.uploadBytesBCD,cb.uploadBytesBCD) - hoozer.bytesUpload:=convertFromBCD(hoozer3.uploadBytesBCD) + IF(checkSecurity(ACS_CONFERENCE_ACCOUNTING)) + subBCD2(hoozer3.uploadBytesBCD,oldBCD) + addBCD2(hoozer3.uploadBytesBCD,cb.uploadBytesBCD) + hoozer.bytesUpload:=convertFromBCD(hoozer3.uploadBytesBCD) + ENDIF CASE "P" aePuts('') FOR i:=0 TO 7 @@ -20883,9 +20082,11 @@ PROC conferenceAccounting(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKey ENDFOR bcdNumberInput(cb.downloadBytesBCD) cb.bytesDownload:=convertFromBCD(cb.downloadBytesBCD) - subBCD2(hoozer3.downloadBytesBCD,oldBCD) - addBCD2(hoozer3.downloadBytesBCD,cb.downloadBytesBCD) - hoozer.bytesDownload:=convertFromBCD(hoozer3.downloadBytesBCD) + IF(checkSecurity(ACS_CONFERENCE_ACCOUNTING)) + subBCD2(hoozer3.downloadBytesBCD,oldBCD) + addBCD2(hoozer3.downloadBytesBCD,cb.downloadBytesBCD) + hoozer.bytesDownload:=convertFromBCD(hoozer3.downloadBytesBCD) + ENDIF CASE "L" aePuts('') oldval:=cb.messagesPosted @@ -20908,6 +20109,7 @@ PROC conferenceAccounting(which:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKey UNTIL flag<>0 IF loggedOnUser<>NIL THEN masterLoadPointers(loggedOnUser) + IF f6 THEN loadMsgPointers(currentConf,currentMsgBase) ENDPROC flag PROC doOnLineEdit(f6) @@ -20940,41 +20142,43 @@ ENDPROC PROC deleteConfAccess(slot) DEF bi DEF t:confBase - DEF i,j + DEF i,m,j DEF temp[100]:STRING - FOR i:=0 TO cmds.numConf-1 + FOR i:=1 TO cmds.numConf - getConfDbFileName(i,temp) - - bi:=Open(temp,MODE_OLDFILE) - IF(bi<>0) - Seek(bi,(slot-1)*SIZEOF confBase,OFFSET_BEGINNING) - Read(bi,t,SIZEOF confBase) - t.confRead:=0 - t.newSinceDate:=0 - t.confRead:=0 - t.confYM:=0 - t.bytesDownload:=0 - t.bytesUpload:=0 - t.lastEMail:=0 - t.dailyBytesDld:=0 - t.upload:=0 - t.downloads:=0 - t.ratioType:=0 - t.ratio:=0 - t.messagesPosted:=0 - t.active:=0 - t.access:=0 - FOR j:=0 TO 7 - t.downloadBytesBCD[i]:=0 - t.uploadBytesBCD[i]:=0 - ENDFOR - Seek(bi,(slot-1)*SIZEOF confBase,OFFSET_BEGINNING) - Write(bi,t,SIZEOF confBase) + FOR m:=1 TO getConfMsgBaseCount(i) + getConfDbFileName(i,m,temp) + + bi:=Open(temp,MODE_OLDFILE) + IF(bi<>0) + Seek(bi,(slot-1)*SIZEOF confBase,OFFSET_BEGINNING) + Read(bi,t,SIZEOF confBase) + t.confRead:=0 + t.newSinceDate:=0 + t.confRead:=0 + t.confYM:=0 + t.bytesDownload:=0 + t.bytesUpload:=0 + t.lastEMail:=0 + t.dailyBytesDld:=0 + t.upload:=0 + t.downloads:=0 + t.ratioType:=0 + t.ratio:=0 + t.messagesPosted:=0 + t.active:=0 + t.access:=0 + FOR j:=0 TO 7 + t.downloadBytesBCD[j]:=0 + t.uploadBytesBCD[j]:=0 + ENDFOR + Seek(bi,(slot-1)*SIZEOF confBase,OFFSET_BEGINNING) + Write(bi,t,SIZEOF confBase) - Close(bi) - ENDIF + Close(bi) + ENDIF + ENDFOR ENDFOR ENDPROC @@ -21021,7 +20225,7 @@ PROC editAccounts(f6) IF(charToUpper(tempStr[0])="N") listNewAccounts(f6) ELSEIF(charToUpper(tempStr[0])="B") - bulkAccountEditor(f6) + bulkAccountEditor() ELSEIF(charToUpper(tempStr[0])="C") listCreditAccounts(f6) ELSEIF(charToUpper(tempStr[0])="I") @@ -21056,12 +20260,12 @@ returnf: ENDPROC RESULT_SUCCESS -PROC updateAllUsers(confnum,updateType, newVal) +PROC updateAllUsers(confnum,msgBaseNum,updateType, newVal) DEF fh,stat DEF cb: PTR TO confBase DEF confDbFile[255]:STRING - getConfDbFileName(confnum,confDbFile) + getConfDbFileName(confnum,msgBaseNum,confDbFile) cb:=NEW cb @@ -21118,7 +20322,7 @@ PROC updateAllUsers(confnum,updateType, newVal) ENDPROC -PROC dumpUserStats(confnum) +PROC dumpUserStats(confnum,msgBaseNum) DEF fh,fhs DEF cb: PTR TO confBase DEF confDbFile[255]:STRING @@ -21131,7 +20335,7 @@ PROC dumpUserStats(confnum) fhs:=Open(confStatFile,MODE_NEWFILE) IF fhs<>0 - getConfDbFileName(confnum,confDbFile) + getConfDbFileName(confnum,msgBaseNum,confDbFile) cb:=NEW cb @@ -21181,7 +20385,7 @@ PROC dumpUserStats(confnum) ENDIF ENDPROC -PROC resizeConfDB(confnum,newSize) +PROC resizeConfDB(confnum,msgBaseNum,newSize) DEF confDbFile[255]:STRING DEF oldConfDbFile[255]:STRING DEF cb: PTR TO confBase @@ -21191,7 +20395,7 @@ PROC resizeConfDB(confnum,newSize) cb:= NEW cb cb2:= NEW cb2 - getConfDbFileName(confnum,confDbFile) + getConfDbFileName(confnum,msgBaseNum,confDbFile) StrCopy(oldConfDbFile,confDbFile) StrAdd(oldConfDbFile,'.old') @@ -21232,26 +20436,40 @@ ENDPROC PROC conferenceMaintenance() DEF conf,flag=0,ch,size,n,f,m DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING DEF confLoc[255]:STRING + DEF confStr[10]:STRING DEF path[255]:STRING DEF path2[255]:STRING DEF dirCacheEnabled DEF lock,fh DEF num,num2,match + DEF msgBase conf:=1 + msgBase:=1 m:=findLastAccount() - loadMsgPointers(conf) + loadMsgPointers(conf,msgBase) getConfLocation(conf,confLoc) - getMailStatFile(conf) - getConfDbFileName(conf,tempstr) + getMailStatFile(conf,msgBase) + getConfDbFileName(conf,msgBase,tempstr) size:=Div(getFileSize(tempstr),SIZEOF confBase) REPEAT conPuts('[0 p') aePuts(' CONFERENCE MAINTENANCE') - StringF(tempstr,' Conference [\d[3]]: \s[29]\b\n',conf,getConfName(conf)) + + IF getConfMsgBaseCount(conf)>1 + getMsgBaseName(conf,msgBase,tempstr2) + StringF(tempstr,'\s - \s',getConfName(conf),tempstr2) + StringF(confStr,'\d.\d',conf,msgBase) + ELSE + getConfName(conf,tempstr) + StringF(confStr,'\d',conf) + ENDIF + + StringF(tempstr,' Conference [\s[5]]: \s[29]\b\n',confStr,tempstr) aePuts(tempstr) aePuts(' THE FOLLOWING OPTIONS EFFECT ALL USERS FOR THIS CONFERENCE!\b\n') aePuts('1.> Ratio') @@ -21272,12 +20490,19 @@ PROC conferenceMaintenance() aePuts(tempstr) StringF(tempstr,'D.> Capacity \d[4] Users',size) aePuts(tempstr) - f:=Mul(Mod(Mul(m,100),size),1000) - n:=Div(Mul(m,100),size) - IF (n<90) - StringF(tempstr,'\r\d[2].\z\r\d[3]% In use',n,f) + IF size>0 + f:=Mul(Mod(Mul(m,100),size),1000) + n:=Div(Mul(m,100),size) + ELSE + f:=0 + n:=0 + ENDIF + IF (n>100) + StringF(tempstr,'\r>100% In use ') + ELSEIF (n<90) + StringF(tempstr,'\r\d[2].\z\r\d[3]% In use ',n,f) ELSE - StringF(tempstr,'\r\d[2].\z\r\d[3]% In use',n,f) + StringF(tempstr,'\r\d.\z\r\d[3]% In use ',n,f) ENDIF aePuts(tempstr) @@ -21305,54 +20530,54 @@ PROC conferenceMaintenance() aePuts('Ratio > ') n:=numberInputNoDefault() aePuts(' Working....') - IF n>=0 THEN updateAllUsers(conf,UPDATE_RATIO,n) + IF n>=0 THEN updateAllUsers(conf,msgBase,UPDATE_RATIO,n) CASE "2" aePuts('Ratio Type > ') n:=numberInputNoDefault() aePuts(' Working....') - IF n>=0 THEN updateAllUsers(conf,UPDATE_RATIO_TYPE,n) + IF n>=0 THEN updateAllUsers(conf,msgBase,UPDATE_RATIO_TYPE,n) CASE "3" aePuts(' Working....') - updateAllUsers(conf,UPDATE_MAILSCAN_PTRS,-1) + updateAllUsers(conf,msgBase,UPDATE_MAILSCAN_PTRS,-1) CASE "4" aePuts(' Working....') - updateAllUsers(conf,UPDATE_LAST_MESSAGE,-1) + updateAllUsers(conf,msgBase,UPDATE_LAST_MESSAGE,-1) CASE "5" aePuts(' Working....') - dumpUserStats(conf) + dumpUserStats(conf,msgBase) CASE "6" aePuts(' Default ON ') n:=yesNo(1) aePuts(' Working....') IF n - updateAllUsers(conf,UPDATE_NEW_MAIL_SCAN,TRUE) + updateAllUsers(conf,msgBase,UPDATE_NEW_MAIL_SCAN,TRUE) ELSE - updateAllUsers(conf,UPDATE_NEW_MAIL_SCAN,FALSE) + updateAllUsers(conf,msgBase,UPDATE_NEW_MAIL_SCAN,FALSE) ENDIF CASE "7" aePuts(' Default ON ') n:=yesNo(1) aePuts(' Working....') IF n - updateAllUsers(conf,UPDATE_NEW_FILE_SCAN,TRUE) + updateAllUsers(conf,msgBase,UPDATE_NEW_FILE_SCAN,TRUE) ELSE - updateAllUsers(conf,UPDATE_NEW_FILE_SCAN,FALSE) + updateAllUsers(conf,msgBase,UPDATE_NEW_FILE_SCAN,FALSE) ENDIF CASE "8" aePuts(' Default ON ') n:=yesNo(1) aePuts(' Working....') IF n - updateAllUsers(conf,UPDATE_DEFAULT_ZOOM_FLAG,TRUE) + updateAllUsers(conf,msgBase,UPDATE_DEFAULT_ZOOM_FLAG,TRUE) ELSE - updateAllUsers(conf,UPDATE_DEFAULT_ZOOM_FLAG,FALSE) + updateAllUsers(conf,msgBase,UPDATE_DEFAULT_ZOOM_FLAG,FALSE) ENDIF CASE "9" aePuts(' Working....') - updateAllUsers(conf,UPDATE_MESSAGES_POSTED,0) + updateAllUsers(conf,msgBase,UPDATE_MESSAGES_POSTED,0) CASE "A" aePuts(' Working....') - updateAllUsers(conf,UPDATE_RESET_VOTING,-1) + updateAllUsers(conf,msgBase,UPDATE_RESET_VOTING,-1) CASE "B" aePuts('Next Message > ') n:=numberInputNoDefault() @@ -21372,8 +20597,8 @@ PROC conferenceMaintenance() n:=numberInputNoDefault() IF n>0 aePuts('Resizing, Please Standby') - resizeConfDB(conf,n) - getConfDbFileName(conf,tempstr) + resizeConfDB(conf,msgBase,n) + getConfDbFileName(conf,msgBase,tempstr) size:=Div(getFileSize(tempstr),SIZEOF confBase) ENDIF CASE "E" @@ -21382,6 +20607,8 @@ PROC conferenceMaintenance() DeleteFile(tempstr) StringF(tempstr,'DELETE RAM:DirCaches/Conf\dDir#?',conf) Execute(tempstr,0,0) + StringF(tempstr,'DELETE \sDirCaches/Conf\dDir#?',confLoc,conf) + Execute(tempstr,0,0) ELSE StringF(tempstr,'\sDirCaches',confLoc) IF(lock:=CreateDir(tempstr)) @@ -21396,6 +20623,10 @@ PROC conferenceMaintenance() IF fh THEN Close(fh) ENDIF CASE "F" + StringF(tempstr,'DELETE RAM:DirCaches/Conf\dDir#?',conf) + Execute(tempstr,0,0) + StringF(tempstr,'DELETE \sDirCaches/Conf\dDir#?',confLoc,conf) + Execute(tempstr,0,0) IF dirCacheEnabled aePuts('Creating, Please Standby') num:=1 @@ -21422,19 +20653,28 @@ PROC conferenceMaintenance() CASE "\t" flag:=1 CASE "-" - conf:=conf-1 - IF conf<1 THEN conf:=cmds.numConf - loadMsgPointers(conf) - getMailStatFile(conf) + msgBase:=msgBase-1 + IF msgBase<1 + conf:=conf-1 + IF conf<1 THEN conf:=cmds.numConf + msgBase:=getConfMsgBaseCount(conf) + ENDIF + loadMsgPointers(conf,msgBase) + getMailStatFile(conf,msgBase) getConfLocation(conf,confLoc) - getConfDbFileName(conf,tempstr) + getConfDbFileName(conf,msgBase,tempstr) size:=Div(getFileSize(tempstr),SIZEOF confBase) CASE "+" - conf:=conf+1 - IF conf>cmds.numConf THEN conf:=1 - getMailStatFile(conf) + msgBase:=msgBase+1 + IF msgBase>getConfMsgBaseCount(conf) + conf:=conf+1 + IF conf>cmds.numConf THEN conf:=1 + msgBase:=1 + ENDIF + + getMailStatFile(conf,msgBase) getConfLocation(conf,confLoc) - getConfDbFileName(conf,tempstr) + getConfDbFileName(conf,msgBase,tempstr) size:=Div(getFileSize(tempstr),SIZEOF confBase) ENDSELECT aePuts(' ') @@ -21452,7 +20692,7 @@ PROC findOpenAccount(hoozer:PTR TO user, hoozer2: PTR TO userKeys, hoozer3: PTR ENDIF ENDPROC -PROC displayAccount(who:LONG, hoozer:PTR TO user, hoozer2: PTR TO userKeys, hoozer3: PTR TO userMisc, f6:LONG) +PROC displayAccount(who:LONG, page, hoozer:PTR TO user, hoozer2: PTR TO userKeys, hoozer3: PTR TO userMisc, f6:LONG) DEF tempStr[255]:STRING DEF tempStr2[255]:STRING DEF temp @@ -21483,159 +20723,170 @@ PROC displayAccount(who:LONG, hoozer:PTR TO user, hoozer2: PTR TO userKeys, hooz ENDSELECT IF(hoozer.slotNumber=who) - StringF(tempStr,' ACTIVE [\d] BAUD: \d\b\n',hoozer.slotNumber,baud) - aePuts(tempStr) + StrCopy(tempStr2,' ACTIVE') ELSE - StringF(tempStr,'INACTIVE [\d] \b\n',who) - aePuts(tempStr) + StrCopy(tempStr2,'INACTIVE') ENDIF + StringF(tempStr,'\s [\d] BAUD: \d\b\n',tempStr2,who,baud) + aePuts(tempStr) StringF(tempStr,'A> Name: \l\s[32] ',hoozer.name) aePuts(tempStr) - StringF(tempStr,'B> Real Name: \l\s[25]',hoozer3.realName) - aePuts(tempStr) - StringF(tempStr,'C> Loc.: \l\s[29]',hoozer.location) - aePuts(tempStr) - IF((logonType>=LOGON_TYPE_REMOTE) AND (f6=FALSE)) - IF(loggedOnUser.slotNumber=1) + IF page=0 + StringF(tempStr,'B> Real Name: \l\s[25]',hoozer3.realName) + aePuts(tempStr) + StringF(tempStr,'C> Loc.: \l\s[29]',hoozer.location) + aePuts(tempStr) + IF((logonType>=LOGON_TYPE_REMOTE) AND (f6=FALSE)) + IF(loggedOnUser.slotNumber=1) + StringF(tempStr,'D> Pass ....: ENCRYPTED') + aePuts(tempStr) + ELSE + aePuts('D> Pass ....: DISABLED') + ENDIF + ELSE StringF(tempStr,'D> Pass ....: ENCRYPTED') aePuts(tempStr) - ELSE - aePuts('D> Pass ....: DISABLED') ENDIF - ELSE - StringF(tempStr,'D> Pass ....: ENCRYPTED') - aePuts(tempStr) - ENDIF - StringF(tempStr,'E> Phone Number ..: \l\s[13]',hoozer.phoneNumber) - aePuts(tempStr) + StringF(tempStr,'E> Phone Number ..: \l\s[13]',hoozer.phoneNumber) + aePuts(tempStr) - StringF(tempStr,'F> Area Name......: \l\s',hoozer.conferenceAccess) - aePuts(tempStr) + StringF(tempStr,'F> Area Name......: \l\s',hoozer.conferenceAccess) + aePuts(tempStr) - StringF(tempStr,'G> Ratio .........: \l\d[7]',hoozer.secLibrary) - aePuts(tempStr) + StringF(tempStr,'G> Ratio .........: \l\d[7]',hoozer.secLibrary) + aePuts(tempStr) - StringF(tempStr,'H> Sec_Level .....: \l\d[5]',hoozer.secStatus) - aePuts(tempStr) + StringF(tempStr,'H> Sec_Level .....: \l\d[5]',hoozer.secStatus) + aePuts(tempStr) - StringF(tempStr,'I> Ratio Type ....: \l\d[5]',hoozer.secBoard) - aePuts(tempStr) - IF(hoozer.secBoard=0) THEN aePuts(' <-Byte)') - IF(hoozer.secBoard=1) THEN aePuts(' <-B/F) ') - IF(hoozer.secBoard=2) THEN aePuts(' <-File)') + StringF(tempStr,'I> Ratio Type ....: \l\d[5]',hoozer.secBoard) + aePuts(tempStr) + IF(hoozer.secBoard=0) THEN aePuts(' <-Byte)') + IF(hoozer.secBoard=1) THEN aePuts(' <-B/F) ') + IF(hoozer.secBoard=2) THEN aePuts(' <-File)') - StringF(tempStr,'J> AutoReJoin ....: \l\d[10]',hoozer.confRJoin) - aePuts(tempStr) + IF (getConfMsgBaseCount(hoozer.confRJoin)>1) AND (hoozer.msgBaseRJoin>0) + StringF(tempStr2,'\d.\d',hoozer.confRJoin,hoozer.msgBaseRJoin) + ELSE + StringF(tempStr2,'\d',hoozer.confRJoin) + ENDIF + StringF(tempStr,'J> AutoReJoin ....: \l\s[7]',tempStr2) + aePuts(tempStr) - StringF(tempStr,'K> Uploads .......: \l\d[10]',hoozer.uploads AND $FFFF) - aePuts(tempStr) + StringF(tempStr,'K> Uploads .......: \l\d[10]',hoozer.uploads AND $FFFF) + aePuts(tempStr) - StringF(tempStr,'L> Messages Posted: \l\d[7]',hoozer.messagesPosted AND $FFFF) - aePuts(tempStr) + StringF(tempStr,'L> Messages Posted: \l\d[7]',hoozer.messagesPosted AND $FFFF) + aePuts(tempStr) - StringF(tempStr,'M> Downloads .....: \l\d[10]\b\n',hoozer.downloads AND $FFFF) - aePuts(tempStr) + StringF(tempStr,'M> Downloads .....: \l\d[10]\b\n',hoozer.downloads AND $FFFF) + aePuts(tempStr) - IF hoozer.newUser THEN StrCopy(tempStr2,'Yes') ELSE StrCopy(tempStr2,'No') - StringF(tempStr,'N> New_User ......: \s[3] ',tempStr2) - aePuts(tempStr) + IF hoozer.newUser THEN StrCopy(tempStr2,'Yes') ELSE StrCopy(tempStr2,'No') + StringF(tempStr,'N> New_User ......: \s[3] ',tempStr2) + aePuts(tempStr) - StringF(tempStr,'#Calls: \l\d[6]',hoozer.timesCalled AND $FFFF) - aePuts(tempStr) + StringF(tempStr,'#Calls: \l\d[6]',hoozer.timesCalled AND $FFFF) + aePuts(tempStr) - StringF(tempStr,'%Today: \l\d[6]',hoozer2.timesOnToday AND $FFFF) - aePuts(tempStr) + StringF(tempStr,'%Today: \l\d[6]',getTodaysCalls(hoozer,hoozer2)) + aePuts(tempStr) - formatBCD(hoozer3.uploadBytesBCD,tempStr2) + formatBCD(hoozer3.uploadBytesBCD,tempStr2) - IF sopt.toggles[TOGGLES_CREDITBYKB] - StringF(tempStr,'O> KBytes Uled ...: \l\s[14]',tempStr2) - ELSE - StringF(tempStr,'O> Bytes Uled ....: \l\s[14]',tempStr2) - ENDIF - aePuts(tempStr) + IF sopt.toggles[TOGGLES_CREDITBYKB] + StringF(tempStr,'O> KBytes Uled ...: \l\s[14]',tempStr2) + ELSE + StringF(tempStr,'O> Bytes Uled ....: \l\s[14]',tempStr2) + ENDIF + aePuts(tempStr) - formatLongDateTime(hoozer.timeLastOn,tempStr2) - StringF(tempStr,'Last Called ...: \s',tempStr2) - aePuts(tempStr) + formatLongDateTime(hoozer.timeLastOn,tempStr2) + StringF(tempStr,'Last Called ...: \s',tempStr2) + aePuts(tempStr) - formatBCD(hoozer3.downloadBytesBCD,tempStr2) - IF sopt.toggles[TOGGLES_CREDITBYKB] - StringF(tempStr,'P> KBytes Dled ...: \l\s[14]',tempStr2) - ELSE - StringF(tempStr,'P> Bytes Dled ....: \l\s[14]',tempStr2) - ENDIF - aePuts(tempStr) + formatBCD(hoozer3.downloadBytesBCD,tempStr2) + IF sopt.toggles[TOGGLES_CREDITBYKB] + StringF(tempStr,'P> KBytes Dled ...: \l\s[14]',tempStr2) + ELSE + StringF(tempStr,'P> Bytes Dled ....: \l\s[14]',tempStr2) + ENDIF + aePuts(tempStr) - temp:=computerTypes.count() - IF temp=0 - StringF(tempStr,'Computer Type .: ') - ELSEIF hoozer.secBulletin>=temp - StringF(tempStr,'Computer Type .: NOT VALID!',computerTypes.item(hoozer.secBulletin)) - ELSE - StringF(tempStr,'Computer Type .: \l\s[16]',computerTypes.item(hoozer.secBulletin)) - ENDIF - aePuts(tempStr) + temp:=computerTypes.count() + IF temp=0 + StringF(tempStr,'Computer Type .: ') + ELSEIF hoozer.secBulletin>=temp + StringF(tempStr,'Computer Type .: NOT VALID!',computerTypes.item(hoozer.secBulletin)) + ELSE + StringF(tempStr,'Computer Type .: \l\s[16]',computerTypes.item(hoozer.secBulletin)) + ENDIF + aePuts(tempStr) - IF (hoozer.dailyBytesLimit<>0) - formatUnsignedLong(hoozer.dailyBytesLimit,tempStr2) - ELSE - StrCopy(tempStr2,'Infinite') - ENDIF - IF sopt.toggles[TOGGLES_CREDITBYKB] - StringF(tempStr,'Q> KByte Limit ...: \l\s[10]',tempStr2) - ELSE - StringF(tempStr,'Q> Byte Limit ....: \l\s[10]',tempStr2) - ENDIF - aePuts(tempStr) + IF (hoozer.dailyBytesLimit<>0) + formatUnsignedLong(hoozer.dailyBytesLimit,tempStr2) + ELSE + StrCopy(tempStr2,'Infinite') + ENDIF + IF sopt.toggles[TOGGLES_CREDITBYKB] + StringF(tempStr,'Q> KByte Limit ...: \l\s[10]',tempStr2) + ELSE + StringF(tempStr,'Q> Byte Limit ....: \l\s[10]',tempStr2) + ENDIF + aePuts(tempStr) - temp:=screenTypeTitle.count() - IF temp=0 - StringF(tempStr,'Screen Type ..: ') - ELSEIF hoozer.screenType>=temp - StringF(tempStr,'Screen Type ..: NOT VALID!') - ELSE - StringF(tempStr,'Screen Type ..: \l\s',screenTypeTitle.item(hoozer.screenType)) - ENDIF - aePuts(tempStr) + temp:=screenTypeTitle.count() + IF temp=0 + StringF(tempStr,'Screen Type ..: ') + ELSEIF hoozer.screenType>=temp + StringF(tempStr,'Screen Type ..: NOT VALID!') + ELSE + StringF(tempStr,'Screen Type ..: \l\s',screenTypeTitle.item(hoozer.screenType)) + ENDIF + aePuts(tempStr) - StringF(tempStr,'R> Time_Total: [\l\d[8]] mins ',Div(hoozer.timeTotal,60)) - aePuts(tempStr) + StringF(tempStr,'R> Time_Total: [\l\d[8]] mins ',Div(hoozer.timeTotal,60)) + aePuts(tempStr) - formatUnsignedLong(hoozer2.upCPS2,tempStr2) - StringF(tempStr,'S> Cps UP: \l\s[10]',tempStr2) - aePuts(tempStr) + formatUnsignedLong(hoozer2.upCPS2,tempStr2) + StringF(tempStr,'S> Cps UP: \l\s[10]',tempStr2) + aePuts(tempStr) - formatUnsignedLong(hoozer2.dnCPS2,tempStr2) - StringF(tempStr,'T> Cps DN: \l\s[10]',tempStr2) - aePuts(tempStr) + formatUnsignedLong(hoozer2.dnCPS2,tempStr2) + StringF(tempStr,'T> Cps DN: \l\s[10]',tempStr2) + aePuts(tempStr) - StringF(tempStr,'U> Time_Limit: [\l\d[8]] mins ',Div(hoozer.timeLimit,60)) - aePuts(tempStr) - StringF(tempStr,' V> Time_Used: [\l\d[8]] mins W> UUCP: \d ',Div(hoozer.timeUsed,60),hoozer.uucpa) - aePuts(tempStr) + StringF(tempStr,'U> Time_Limit: [\l\d[8]] mins ',Div(hoozer.timeLimit,60)) + aePuts(tempStr) + StringF(tempStr,' V> Time_Used: [\l\d[8]] mins W> UUCP: \d ',Div(hoozer.timeUsed,60),hoozer.uucpa) + aePuts(tempStr) - StringF(tempStr,'Y> Chat_Limit: [\l\d[8]] mins ',Div(hoozer.chatLimit,60)) - aePuts(tempStr) - StringF(tempStr,' Z> Chat_Used: [\l\d[8]] mins ',Div((hoozer.chatLimit-hoozer.chatRemain),60)) - aePuts(tempStr) + StringF(tempStr,'Y> Chat_Limit: [\l\d[8]] mins ',Div(hoozer.chatLimit,60)) + aePuts(tempStr) + StringF(tempStr,' Z> Chat_Used: [\l\d[8]] mins ',Div((hoozer.chatLimit-hoozer.chatRemain),60)) + aePuts(tempStr) - aePuts('\b\n') + aePuts('\b\n') + ENDIF + displayAccountActions(who) +ENDPROC +PROC displayAccountActions(who:LONG) + DEF tempStr[200]:STRING + DEF tempStr2[20]:STRING + aePuts('X =EXIT-NOSAVE ~=SAVE 1-8=PRESETS 9=RE-ACTIVATE =DELETE *=USER NOTES\b\n') StrCopy(tempStr,'=CONT @=CONFERENCE ACCOUNTING !=CREDIT ACCOUNT MAINTENANCE ') - IF checkToolTypeExists(TOOLTYPE_NODE,node,'CENTRAL_ANSWERS') - StrAdd(tempStr,'?=USER ANSWERS') - ENDIF + IF findUserAnswers(who,tempStr2) THEN StrAdd(tempStr,'?=USER ANSWERS') ELSE StrAdd(tempStr,' ') StrAdd(tempStr,'\b\n') aePuts(tempStr) ENDPROC -PROC displayAccountInfo(who:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3:PTR TO userMisc,f6:LONG) +PROC displayAccountInfo(who:LONG, page,hoozer:PTR TO user, hoozer2:PTR TO userKeys, hoozer3:PTR TO userMisc,f6:LONG) DEF tempStr[255]:STRING DEF tempStr2[255]:STRING DEF baud,temp @@ -21673,135 +20924,146 @@ PROC displayAccountInfo(who:LONG, hoozer:PTR TO user, hoozer2:PTR TO userKeys, h StringF(tempStr,'\l\s[32]',hoozer.name) aePuts(tempStr) - StringF(tempStr,'\l\s[25]',hoozer3.realName) - aePuts(tempStr) - StringF(tempStr,'\l\s[29]',hoozer.location) - aePuts(tempStr) - IF((logonType>=LOGON_TYPE_REMOTE) AND (f6=FALSE)) + IF page=0 + StringF(tempStr,'\l\s[25]',hoozer3.realName) + aePuts(tempStr) + StringF(tempStr,'\l\s[29]',hoozer.location) + aePuts(tempStr) + + IF((logonType>=LOGON_TYPE_REMOTE) AND (f6=FALSE)) - IF(loggedOnUser.slotNumber=1) + IF(loggedOnUser.slotNumber=1) + StringF(tempStr,'ENCRYPTED') + aePuts(tempStr) + ELSE + aePuts('DISABLED\b\n') + ENDIF + ELSE StringF(tempStr,'ENCRYPTED') aePuts(tempStr) - ELSE - aePuts('DISABLED\b\n') ENDIF - ELSE - StringF(tempStr,'ENCRYPTED') + StringF(tempStr,'\l\s[13]',hoozer.phoneNumber) aePuts(tempStr) - ENDIF - StringF(tempStr,'\l\s[13]',hoozer.phoneNumber) - aePuts(tempStr) - StringF(tempStr,'\l\s[10]',hoozer.conferenceAccess) - aePuts(tempStr) + StringF(tempStr,'\l\s[10]',hoozer.conferenceAccess) + aePuts(tempStr) - StringF(tempStr,'\l\d[7]',hoozer.secLibrary) - aePuts(tempStr) + StringF(tempStr,'\l\d[7]',hoozer.secLibrary) + aePuts(tempStr) - StringF(tempStr,'\l\d[5]',hoozer.secStatus) - aePuts(tempStr) + StringF(tempStr,'\l\d[5]',hoozer.secStatus) + aePuts(tempStr) - StringF(tempStr,'\l\d[5]',hoozer.secBoard) - aePuts(tempStr) - IF(hoozer.secBoard=0) THEN aePuts(' <-Byte)') - IF(hoozer.secBoard=1) THEN aePuts(' <-B/F) ') - IF(hoozer.secBoard=2) THEN aePuts(' <-File)') + StringF(tempStr,'\l\d[5]',hoozer.secBoard) + aePuts(tempStr) + IF(hoozer.secBoard=0) THEN aePuts(' <-Byte)') + IF(hoozer.secBoard=1) THEN aePuts(' <-B/F) ') + IF(hoozer.secBoard=2) THEN aePuts(' <-File)') - StringF(tempStr,'\l\d[7]',hoozer.confRJoin) - aePuts(tempStr) - StringF(tempStr,'\l\d[10]',hoozer.uploads AND $FFFF) - aePuts(tempStr) + IF (getConfMsgBaseCount(hoozer.confRJoin)>1) AND (hoozer.msgBaseRJoin>0) + StringF(tempStr2,'\d.\d',hoozer.confRJoin,hoozer.msgBaseRJoin) + ELSE + StringF(tempStr2,'\d',hoozer.confRJoin) + ENDIF - StringF(tempStr,'\l\d[7]',hoozer.messagesPosted AND $FFFF) - aePuts(tempStr) + StringF(tempStr,'\l\s[7]',tempStr2) + aePuts(tempStr) - StringF(tempStr,'\l\d[10]',hoozer.downloads AND $FFFF) - aePuts(tempStr) + StringF(tempStr,'\l\d[10]',hoozer.uploads AND $FFFF) + aePuts(tempStr) - IF hoozer.newUser THEN StrCopy(tempStr2,'Yes') ELSE StrCopy(tempStr2,'No') - StringF(tempStr,'N> New_User ......: \s[3] ',tempStr2) - aePuts(tempStr) + StringF(tempStr,'\l\d[7]',hoozer.messagesPosted AND $FFFF) + aePuts(tempStr) - StringF(tempStr,'#Calls: \l\d[6]',hoozer.timesCalled AND $FFFF) - aePuts(tempStr) + StringF(tempStr,'\l\d[10]',hoozer.downloads AND $FFFF) + aePuts(tempStr) - StringF(tempStr,'%Today: \l\d[6]',hoozer2.timesOnToday AND $FFFF) - aePuts(tempStr) + IF hoozer.newUser THEN StrCopy(tempStr2,'Yes') ELSE StrCopy(tempStr2,'No') + StringF(tempStr,'N> New_User ......: \s[3] ',tempStr2) + aePuts(tempStr) - formatBCD(hoozer3.uploadBytesBCD,tempStr2) - StringF(tempStr,'\l\s[14]',tempStr2) - aePuts(tempStr) + StringF(tempStr,'#Calls: \l\d[6]',hoozer.timesCalled AND $FFFF) + aePuts(tempStr) - formatLongDateTime(hoozer.timeLastOn,tempStr2) - StringF(tempStr,'\s',tempStr2) - aePuts(tempStr) + StringF(tempStr,'%Today: \l\d[6]',getTodaysCalls(hoozer,hoozer2)) + aePuts(tempStr) - formatBCD(hoozer3.downloadBytesBCD,tempStr2) - StringF(tempStr,'\l\s[14]',tempStr2) - aePuts(tempStr) + formatBCD(hoozer3.uploadBytesBCD,tempStr2) + StringF(tempStr,'\l\s[14]',tempStr2) + aePuts(tempStr) - temp:=computerTypes.count() - IF temp=0 - StringF(tempStr,'') - ELSEIF hoozer.secBulletin>=temp - StringF(tempStr,'NOT VALID!') - ELSE - StringF(tempStr,'\l\s[16]',computerTypes.item(hoozer.secBulletin)) - ENDIF - aePuts(tempStr) + formatLongDateTime(hoozer.timeLastOn,tempStr2) + StringF(tempStr,'\s',tempStr2) + aePuts(tempStr) - IF (hoozer.dailyBytesLimit<>0) - formatUnsignedLong(hoozer.dailyBytesLimit,tempStr2) - ELSE - StrCopy(tempStr2,'Infinite') - ENDIF - StringF(tempStr,'\l\s[10]',tempStr2) - aePuts(tempStr) + formatBCD(hoozer3.downloadBytesBCD,tempStr2) + StringF(tempStr,'\l\s[14]',tempStr2) + aePuts(tempStr) - temp:=screenTypeTitle.count() - IF temp=0 - StringF(tempStr,'') - ELSEIF (hoozer.screenType>=temp) - StringF(tempStr,'NOT VALID!') - ELSE - StringF(tempStr,'\l\s[16]',screenTypeTitle.item(hoozer.screenType)) - ENDIF - aePuts(tempStr) + temp:=computerTypes.count() + IF temp=0 + StringF(tempStr,'') + ELSEIF hoozer.secBulletin>=temp + StringF(tempStr,'NOT VALID!') + ELSE + StringF(tempStr,'\l\s[16]',computerTypes.item(hoozer.secBulletin)) + ENDIF + aePuts(tempStr) - StringF(tempStr,'\l\d[6]',Div(hoozer.timeTotal,60)) - aePuts(tempStr) + IF (hoozer.dailyBytesLimit<>0) + formatUnsignedLong(hoozer.dailyBytesLimit,tempStr2) + ELSE + StrCopy(tempStr2,'Infinite') + ENDIF + StringF(tempStr,'\l\s[10]',tempStr2) + aePuts(tempStr) - formatUnsignedLong(hoozer2.upCPS2,tempStr2) - StringF(tempStr,'Cps UP: \l\s[10]',tempStr2) - aePuts(tempStr) + temp:=screenTypeTitle.count() + IF temp=0 + StringF(tempStr,'') + ELSEIF (hoozer.screenType>=temp) + StringF(tempStr,'NOT VALID!') + ELSE + StringF(tempStr,'\l\s[16]',screenTypeTitle.item(hoozer.screenType)) + ENDIF + aePuts(tempStr) - formatUnsignedLong(hoozer2.dnCPS2,tempStr2) - StringF(tempStr,'Cps DN: \l\s[10]',tempStr2) - aePuts(tempStr) + StringF(tempStr,'\l\d[6]',Div(hoozer.timeTotal,60)) + aePuts(tempStr) - StringF(tempStr,'\l\d[6]',Div(hoozer.timeLimit,60)) - aePuts(tempStr) - StringF(tempStr,'\l\d[6]',Div(hoozer.timeUsed,60)) - aePuts(tempStr) + formatUnsignedLong(hoozer2.upCPS2,tempStr2) + StringF(tempStr,'Cps UP: \l\s[10]',tempStr2) + aePuts(tempStr) - StringF(tempStr,'\d',hoozer.uucpa) - aePuts(tempStr) + formatUnsignedLong(hoozer2.dnCPS2,tempStr2) + StringF(tempStr,'Cps DN: \l\s[10]',tempStr2) + aePuts(tempStr) - StringF(tempStr,'\l\d[6]',Div(hoozer.chatLimit,60)) - aePuts(tempStr) - StringF(tempStr,'\l\d[6]',Div((hoozer.chatLimit-hoozer.chatRemain),60)) - aePuts(tempStr) + StringF(tempStr,'\l\d[6]',Div(hoozer.timeLimit,60)) + aePuts(tempStr) + StringF(tempStr,'\l\d[6]',Div(hoozer.timeUsed,60)) + aePuts(tempStr) + + StringF(tempStr,'\d',hoozer.uucpa) + aePuts(tempStr) + + StringF(tempStr,'\l\d[6]',Div(hoozer.chatLimit,60)) + aePuts(tempStr) + StringF(tempStr,'\l\d[6]',Div((hoozer.chatLimit-hoozer.chatRemain),60)) + aePuts(tempStr) + ENDIF + displayAccountActions(who) ENDPROC -PROC bulkAccountEditor(f6) +PROC bulkAccountEditor() DEF flag,command DEF settings[15]:ARRAY OF LONG DEF areaName[255]:STRING DEF secLevel[3]:STRING - DEF i,v,r + DEF i,v,v2,r,p DEF tempstr[255]:STRING sendCLS() @@ -21855,7 +21117,16 @@ PROC bulkAccountEditor(f6) aePuts(' ') lineInput('',settings[2],15,INPUT_TIMEOUT,settings[2]) v,r:=Val(settings[2]) - IF (r=0) OR (v<1) OR (v>cmds.numConf) THEN StrCopy(settings[2],'') ELSE StringF(settings[2],'\d',v) + IF (r=0) OR (v<1) OR (v>cmds.numConf) + StrCopy(settings[2],'') + ELSE + IF (p:=InStr(settings[2],'.'))>=0 + v2,r:=Val(p+1+settings[2]) + StringF(settings[2],'\d.\d',v,v2) + ELSE + StringF(settings[2],'\d',v) + ENDIF + ENDIF CASE "K" aePuts(' ') lineInput('',settings[3],15,INPUT_TIMEOUT,settings[3]) @@ -22040,7 +21311,7 @@ PROC displayBulkSettings(settings:PTR TO LONG, areaName:PTR TO CHAR, secLevel:PT ENDPROC PROC applyBulkChanges(settings:PTR TO LONG,areaName:PTR TO CHAR,secLevel:PTR TO CHAR) - DEF fh,fh2,fh3,v + DEF fh,fh2,fh3,v,p DEF stat,stat2,stat3,match IF((fh:=Open(userDataFile,MODE_OLDFILE)))=0 THEN RETURN RESULT_FAILURE @@ -22106,7 +21377,15 @@ PROC applyBulkChanges(settings:PTR TO LONG,areaName:PTR TO CHAR,secLevel:PTR TO IF match IF StrLen(settings[0])>0 THEN tempUser.secLibrary:=Val(settings[0]) IF StrLen(settings[1])>0 THEN tempUser.secBoard:=Val(settings[1]) - IF StrLen(settings[2])>0 THEN tempUser.confRJoin:=Val(settings[2]) + IF StrLen(settings[2])>0 + IF (p:=InStr(settings[2],'.'))>=0 + tempUser.confRJoin:=Val(settings[2]) + tempUser.msgBaseRJoin:=Val(p+1+settings[2]) + ELSE + tempUser.confRJoin:=Val(settings[2]) + tempUser.msgBaseRJoin:=0 + ENDIF + ENDIF IF StrLen(settings[3])>0 THEN tempUser.uploads:=Val(settings[3]) IF StrLen(settings[4])>0 THEN tempUser.messagesPosted:=Val(settings[4]) IF StrLen(settings[5])>0 THEN tempUser.downloads:=Val(settings[5]) @@ -22145,7 +21424,7 @@ PROC bulkPresets() DEF preset:LONG,allConf:LONG DEF areaName[255]:STRING DEF secLevel[3]:STRING - DEF i,v,r + DEF v,r DEF tempstr[255]:STRING sendCLS() @@ -22235,7 +21514,6 @@ PROC bulkPresets() ENDPROC RESULT_SUCCESS PROC displayBulkPresetScreen() - DEF tempStr[255]:STRING aePuts(' BULK ACCOUNT MAINTENANCE') aePuts(' Preset to apply:') @@ -22261,7 +21539,7 @@ ENDPROC PROC displayBulkPresetSettings(preset:LONG, allConfs:LONG, areaName:PTR TO CHAR, secLevel:PTR TO CHAR) DEF tempStr[255]:STRING - DEF i,tot,v + DEF i,tot IF checkToolTypeExists(TOOLTYPE_PRESET,1,'PRESET.AREA') StringF(tempStr,' \s',IF preset=1 THEN 'Yes' ELSE 'No ') @@ -22387,6 +21665,7 @@ PROC applyBulkPresetChanges(preset:LONG,allConf:LONG,areaName:PTR TO CHAR,secLev tempUser.newUser:=0 tempUser.confRJoin:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.CONFRJOIN') + tempUser.msgBaseRJoin:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.MSGBASERJOIN') tempUser.secStatus:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.ACCESS') tempUser.secLibrary:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.RATIO') tempUser.timeLimit:=readToolTypeInt(TOOLTYPE_PRESET,preset,'PRESET.TIME_LIMIT') @@ -22485,14 +21764,14 @@ PROC fileStatus(opt) aePuts(' Conf Files Bytes Files Bytes Bytes Avail Ratio\b\n') ENDIF aePuts(' ---- ------- -------------- ------- -------------- ----------- -----\b\n') - saveMsgPointers(currentConf) + saveMsgPointers(currentConf,currentMsgBase) FOR i:=1 TO s IF (opt=FALSE) OR (i=currentConf) IF i=(currentConf) THEN n:=3 ELSE n:=6 IF checkConfAccess(i) IF (ca=TRUE) OR (i=currentConf) - IF (ca) THEN loadMsgPointers(i) + IF (ca) THEN loadMsgPointers(i,1) formatBCD(loggedOnUserMisc.uploadBytesBCD,bytesup) formatBCD(loggedOnUserMisc.downloadBytesBCD,bytesdown) IF (loggedOnUser.dailyBytesLimit<>0) @@ -22512,7 +21791,7 @@ PROC fileStatus(opt) ENDIF ENDFOR aePuts('\b\n') - loadMsgPointers(currentConf) + loadMsgPointers(currentConf,currentMsgBase) ENDPROC PROC sysopPaged() @@ -22535,7 +21814,7 @@ PROC sysopPaged() IF(checkToolTypeExists(TOOLTYPE_BBSCONFIG,0,'MAIL_ON_SYSOP_PAGE')) AND (StrLen(mailOptions.sysopEmail)>0) StringF(tempstring,'\s: Ami-Express page notification',cmds.bbsName) StringF(tempstring2,'This is a notification that you were paged by \s.',loggedOnUser.name) - sendMail(tempstring,tempstring2,FALSE,mailOptions.sysopEmail) + sendMail(tempstring,tempstring2,FALSE,NIL,0,mailOptions.sysopEmail) ENDIF ENDPROC @@ -22720,6 +21999,19 @@ PROC sendOlmPacket(nodenum,msg:PTR TO CHAR,last) ENDIF ENDPROC RESULT_SUCCESS +PROC internalCommandGreets() + aePuts('\b\nIn memory of those who came before us...\b\n\b\n') + + aePuts('[scoopex] [lsd] [skid row] [alpha flight] [trsi] [bamiga sector one]\b\n\b\n') + aePuts('[fairlight] [defjam] [paradox] [legend] [anthrox] [crystal] [angels]\b\n\b\n') + aePuts('[vision factory] [zenith] [slipstream] [dual crew] [delight] [shining]\b\n\b\n') + aePuts('[quartex] [global overdose] [paranoimia] [supplex] [classic] [hoodlum]\b\n\b\n') + aePuts('[accumulators] [hellfire] [oracle] [endless piracy] [hqc] [setrox]\b\n\b\n') + aePuts('[prodigy] [prestige] [nemesis] [genesis] [loonies] [horizon] [agile]\b\n\b\n') + aePuts('[crack inc] [valhalla] [sunflex inc] [ministry] [the band] [razor1911]\b\n\b\n') + aePuts('[conqueror and zike] [mad] [the company]\b\n\b\n') +ENDPROC + PROC internalCommand0() DEF status DEF string[32]:STRING @@ -22749,10 +22041,11 @@ PROC internalCommand0() remoteShell() ENDPROC RESULT_SUCCESS -PROC internalCommand1(params) +PROC internalCommand1() IF (checkSecurity(ACS_ACCOUNT_EDITING)=FALSE) RETURN RESULT_NOT_ALLOWED ENDIF + callersLog('\tAccount editing.\n') editAccounts(FALSE) ENDPROC RESULT_SUCCESS @@ -22827,7 +22120,7 @@ ENDPROC RESULT_SUCCESS PROC internalCommandLT() DEF newConf IF checkSecurity(ACS_JOIN_CONFERENCE)=FALSE THEN RETURN RESULT_NOT_ALLOWED - saveMsgPointers(currentConf) + saveMsgPointers(currentConf,currentMsgBase) setEnvStat(ENV_JOIN) newConf:=currentConf-1 @@ -22838,7 +22131,7 @@ PROC internalCommandLT() IF newConf<1 internalCommandJ('') ELSE - joinConf(newConf,FALSE,FALSE) + joinConf(newConf,1,FALSE,FALSE) ENDIF ENDPROC RESULT_SUCCESS @@ -22846,7 +22139,7 @@ ENDPROC RESULT_SUCCESS PROC internalCommandGT() DEF newConf IF checkSecurity(ACS_JOIN_CONFERENCE)=FALSE THEN RETURN RESULT_NOT_ALLOWED - saveMsgPointers(currentConf) + saveMsgPointers(currentConf,currentMsgBase) setEnvStat(ENV_JOIN) newConf:=currentConf+1 @@ -22857,7 +22150,35 @@ PROC internalCommandGT() IF newConf>cmds.numConf internalCommandJ('') ELSE - joinConf(newConf,FALSE,FALSE) + joinConf(newConf,1,FALSE,FALSE) + ENDIF +ENDPROC RESULT_SUCCESS + +PROC internalCommandLT2() + DEF newMsgBase + saveMsgPointers(currentConf,currentMsgBase) + + setEnvStat(ENV_JOIN) + newMsgBase:=currentMsgBase-1 + + IF newMsgBase<1 + internalCommandJM('') + ELSE + joinConf(currentConf,newMsgBase,FALSE,FALSE) + ENDIF +ENDPROC RESULT_SUCCESS + +PROC internalCommandGT2() + DEF newMsgBase + saveMsgPointers(currentConf,currentMsgBase) + + setEnvStat(ENV_JOIN) + newMsgBase:=currentMsgBase+1 + + IF newMsgBase>getConfMsgBaseCount(currentConf) + internalCommandJM('') + ELSE + joinConf(currentConf,newMsgBase,FALSE,FALSE) ENDIF ENDPROC RESULT_SUCCESS @@ -22940,72 +22261,92 @@ PROC internalCommandC(params) ENDPROC res PROC internalCommandCF() - DEF i,loop=TRUE,editmask + DEF i,m,loop=TRUE,editmask DEF confNums[255]:STRING DEF tempstr[255]:STRING - DEF c1,c2,c3 + DEF tempstr2[255]:STRING + DEF confStr[10]:STRING + DEF c1,c2,c3,c4 DEF cb: PTR TO confBase DEF ch DEF stat DEF p:PTR TO CHAR DEF v + DEF n,cnt IF checkSecurity(ACS_CONFFLAGS)=FALSE THEN RETURN RESULT_NOT_ALLOWED REPEAT sendCLS() aePuts('\b\n') - IF (0) - aePuts(' M F Z Conference M F Z Conference\b\n') - aePuts(' ~ ~ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~ ~ ~ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~\b\n\b\n') - ELSE - aePuts(' M F Z Conference\b\n') - aePuts(' ~ ~ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~\b\n\b\n') - ENDIF + aePuts(' M A F Z Conference M A F Z Conference\b\n') + aePuts(' ~ ~ ~ ~ ~~~~~~~~~~~~~~~~~~~~~~~ ~ ~ ~ ~ ~~~~~~~~~~~~~~~~~~~~~~~\b\n\b\n') + n:=0 FOR i:=1 TO cmds.numConf IF checkConfAccess(i) - cb:=confBases.item(i-1) - - IF((checkToolTypeExists(TOOLTYPE_CONF,i,'FORCE_NEWSCAN'))) - c1:="F" - ELSEIF (checkToolTypeExists(TOOLTYPE_CONF,i,'NO_NEWSCAN')) - c1:="D" - ELSEIF (cb.handle[0] AND MAIL_SCAN_MASK) - c1:="*" - ELSE - c1:=" " - ENDIF + FOR m:=1 TO getConfMsgBaseCount(i) + cb:=confBases.item(getConfIndex(i,m)) + + IF((checkToolTypeExists(TOOLTYPE_CONF,i,'FORCE_NEWSCAN'))) + c1:="F" + ELSEIF (checkToolTypeExists(TOOLTYPE_CONF,i,'NO_NEWSCAN')) + c1:="D" + ELSEIF (cb.handle[0] AND MAIL_SCAN_MASK) + c1:="*" + ELSE + c1:=" " + ENDIF - IF((checkToolTypeExists(TOOLTYPE_CONF,i,'SHOW_NEW_FILES'))) - c2:="F" - ELSEIF (checkToolTypeExists(TOOLTYPE_CONF,i,'NO_NEW_FILES')) - c2:="D" - ELSEIF(cb.handle[0] AND FILE_SCAN_MASK) - c2:="*" - ELSE - c2:=" " - ENDIF + IF((checkToolTypeExists(TOOLTYPE_CONF,i,'SHOW_NEW_FILES'))) + c2:="F" + ELSEIF (checkToolTypeExists(TOOLTYPE_CONF,i,'NO_NEW_FILES')) + c2:="D" + ELSEIF(cb.handle[0] AND FILE_SCAN_MASK) + c2:="*" + ELSE + c2:=" " + ENDIF + + IF(cb.handle[0] AND MAILSCAN_ALL) + c4:="*" + ELSE + c4:=" " + ENDIF - IF (cb.handle[0] AND ZOOM_SCAN_MASK) THEN c3:="*" ELSE c3:=" " + IF (cb.handle[0] AND ZOOM_SCAN_MASK) THEN c3:="*" ELSE c3:=" " - IF(0) - StringF(tempstr,' [\z\r\d[3]] \c \c \c \l\s[25] ',relConf(i),c1,c2,c3,getConfName(i)) - ELSE - StringF(tempstr,' [\z\r\d[3]] \c \c \c \l\s[25]\b\n',relConf(i),c1,c2,c3,getConfName(i)) - ENDIF - aePuts(tempstr) + IF getConfMsgBaseCount(i)>1 + getMsgBaseName(i,m,tempstr) + StringF(tempstr2,'\s - \s',getConfName(i),tempstr) + StringF(confStr,'\d.\d',relConf(i),m) + StringF(tempstr,'[\r\s[5]] \c \c \c \c \l\s[23]',confStr,c1,c4, c2,c3,tempstr2) + ELSE + getConfName(i,tempstr2) + StringF(tempstr,'[\r\d[5]] \c \c \c \c \l\s[23]',relConf(i),c1,c4, c2,c3,tempstr2) + ENDIF + + aePuts(tempstr) + IF n AND 1 + aePuts('\b\n') + ELSE + aePuts(' ') + ENDIF + n++ + ENDFOR ENDIF ENDFOR - aePuts('\b\n\b\nEnter Flag Type New [M]ailScan, New [F]ileScan, [Z]oom >: ') + aePuts('\b\n\b\nEdit which flags [M]ailScan, [A]ll Messages, [F]ileScan, [Z]oom >: ') ch:=readChar(INPUT_TIMEOUT) - IF (ch="m") OR (ch="M") - editmask:=4 + IF (ch="m") OR (ch="M") + editmask:=MAIL_SCAN_MASK ELSEIF (ch="f") OR (ch="F" ) - editmask:=8 + editmask:=FILE_SCAN_MASK ELSEIF (ch="z") OR (ch="Z") - editmask:=2 + editmask:=ZOOM_SCAN_MASK + ELSEIF (ch="a") OR (ch="A") + editmask:=MAILSCAN_ALL ELSE editmask:=-1 loop:=FALSE @@ -23023,43 +22364,68 @@ PROC internalCommandCF() IF StrLen(confNums)=0 THEN RETURN RESULT_SUCCESS IF StrCmp(confNums,'+') - FOR i:=0 TO cmds.numConf-1 - IF checkConfAccess(i+1) - cb:=confBases.item(i) - cb.handle[0]:=cb.handle[0] OR editmask + FOR i:=1 TO cmds.numConf + IF checkConfAccess(i) + FOR m:=1 TO getConfMsgBaseCount(i) + cb:=confBases.item(getConfIndex(i,m)) + cb.handle[0]:=cb.handle[0] OR editmask + ENDFOR ENDIF ENDFOR ELSEIF StrCmp(confNums,'-') - FOR i:=0 TO cmds.numConf-1 - IF checkConfAccess(i+1) - cb:=confBases.item(i) - cb.handle[0]:=cb.handle[0] AND (Not(editmask)) + FOR i:=1 TO cmds.numConf + IF checkConfAccess(i) + FOR m:=1 TO getConfMsgBaseCount(i) + cb:=confBases.item(getConfIndex(i,m)) + cb.handle[0]:=cb.handle[0] AND (Not(editmask)) + ENDFOR ENDIF ENDFOR ELSEIF StrLen(confNums)>0 p:=confNums WHILE((i:=InStr(p,','))<>-1) AND ((p-confNums)0) - v:=getInverse(v) - IF v<=cmds.numConf - IF checkConfAccess(v) - cb:=confBases.item(v-1) - cb.handle[0]:=Eor(cb.handle[0],editmask) - ENDIF - ENDIF - ENDIF + StrCopy(tempstr,p,i) + fullTrim(tempstr,tempstr2) p:=p+i+1 + + FOR i:=1 TO cmds.numConf + IF checkConfAccess(i) + v:=getInverse(i) + cnt:=getConfMsgBaseCount(i) + FOR m:=1 TO cnt + IF cnt=1 + StringF(tempstr,'\d',v) + ELSE + StringF(tempstr,'\d.\d',v,m) + ENDIF + IF StrCmp(tempstr,tempstr2) + cb:=confBases.item(getConfIndex(i,m)) + cb.handle[0]:=Eor(cb.handle[0],editmask) + ENDIF + ENDFOR + ENDIF + ENDFOR ENDWHILE - IF ((p-confNums)0) - v:=getInverse(v) - IF v<=cmds.numConf - IF checkConfAccess(v) - cb:=confBases.item(v-1) - cb.handle[0]:=Eor(cb.handle[0],editmask) + IF ((p-confNums)EnterMSG() + RETURN callMsgFuncs(2,0,0) ->EnterMSG() ELSE customMsgbaseCmd(2,0,1) RETURN RESULT_SUCCESS @@ -23120,8 +22486,7 @@ PROC internalCommandFM(params) HANDLE DEF foundfile[12]:STRING DEF foundDateStr[20]:STRING DEF flagfilelist=NIL:PTR TO stringlist - DEF matchpos,matchend - DEF newstr + DEF matchpos DEF item:PTR TO flagFileItem IF checkSecurity(ACS_EDIT_FILES)=FALSE THEN RETURN RESULT_NOT_ALLOWED @@ -23295,7 +22660,6 @@ PROC internalCommandG(params) ENDPROC RESULT_SUCCESS PROC internalCommandH(params) - DEF stat DEF tempstr[255]:STRING,screen[255]:STRING parseParams(params) @@ -23338,12 +22702,14 @@ PROC internalCommandUpHat(params) ENDPROC RESULT_SUCCESS PROC internalCommandJ(params) - DEF newConfStr[5]:STRING + DEF newStr[5]:STRING DEF newConf,stat + DEF newMsgBase=1 + DEF param,pos,cnt DEF tempStr[255]:STRING IF checkSecurity(ACS_JOIN_CONFERENCE)=FALSE THEN RETURN RESULT_NOT_ALLOWED - saveMsgPointers(currentConf) + saveMsgPointers(currentConf,currentMsgBase) setEnvStat(ENV_JOIN) @@ -23351,19 +22717,28 @@ PROC internalCommandJ(params) newConf:=-1 IF parsedParams.count()>0 - IF StrLen(parsedParams.item(0))>0 THEN newConf:=Val(parsedParams.item(0)) + param:=parsedParams.item(0) + IF StrLen(param)>0 + newConf:=Val(param) + IF (pos:=InStr(param,'.'))>=0 + newMsgBase:=Val(param+pos+1) + ELSEIF parsedParams.count()>1 + newMsgBase:=Val(parsedParams.item(1)) + ENDIF + ENDIF ENDIF newConf:=getInverse(newConf) IF (newConf<1) OR (newConf>cmds.numConf) displayScreen(SCREEN_JOINCONF) - stat:=lineInput('Conference Number: ','',5,INPUT_TIMEOUT,newConfStr) + StringF(tempStr,'Conference Number (1-\d): ',cmds.numConf) + stat:=lineInput(tempStr,'',5,INPUT_TIMEOUT,newStr) IF stat<>RESULT_SUCCESS THEN RETURN stat - IF StrLen(newConfStr)=0 THEN RETURN RESULT_SUCCESS + IF StrLen(newStr)=0 THEN RETURN RESULT_SUCCESS - newConf:=getInverse(Val(newConfStr)) + newConf:=getInverse(Val(newStr)) ENDIF IF newConf<1 THEN newConf:=1 @@ -23380,14 +22755,79 @@ PROC internalCommandJ(params) callersLog(tempStr) ENDIF - joinConf(newConf,FALSE,FALSE) + cnt:=getConfMsgBaseCount(newConf) + + IF (newMsgBase<1) OR (newMsgBase>cnt) + displayScreen(SCREEN_JOINMSGBASE) + StringF(tempStr,'Message Base Number (1-\d): ',cnt) + stat:=lineInput(tempStr,'',5,INPUT_TIMEOUT,newStr) + IF stat<>RESULT_SUCCESS THEN RETURN stat + + IF StrLen(newStr)=0 THEN RETURN RESULT_SUCCESS + + newMsgBase:=Val(newStr) + ENDIF + + joinConf(newConf,newMsgBase,FALSE,FALSE) +ENDPROC RESULT_SUCCESS + +PROC internalCommandJM(params) + DEF newStr[5]:STRING + DEF newMsgBase,stat,cnt + DEF param + DEF tempStr[255]:STRING + + IF checkSecurity(ACS_JOIN_CONFERENCE)=FALSE THEN RETURN RESULT_NOT_ALLOWED + + saveMsgPointers(currentConf,currentMsgBase) + + setEnvStat(ENV_JOIN) + + parseParams(params) + + newMsgBase:=-1 + IF parsedParams.count()>0 + param:=parsedParams.item(0) + + IF (InStr(param,'.')>=0) + internalCommandJ(params) + RETURN + ENDIF + + IF StrLen(param)>0 THEN newMsgBase:=Val(param) + ENDIF + + cnt:=readToolTypeInt(TOOLTYPE_MSGBASE,currentConf,'NMSGBASES') + IF cnt=-1 + aePuts('\b\nThis conference does not contain multiple message bases\b\n\b\n') + RETURN RESULT_FAILURE + ENDIF + + + cnt:=getConfMsgBaseCount(currentConf) + + IF (newMsgBase<1) OR (newMsgBase>cnt) + displayScreen(SCREEN_JOINMSGBASE) + StringF(tempStr,'Message Base Number (1-\d): ',cnt) + stat:=lineInput(tempStr,'',5,INPUT_TIMEOUT,newStr) + IF stat<>RESULT_SUCCESS THEN RETURN stat + + IF StrLen(newStr)=0 THEN RETURN RESULT_SUCCESS + + newMsgBase:=Val(newStr) + ENDIF + + IF newMsgBase<1 THEN newMsgBase:=1 + IF newMsgBase>cnt THEN newMsgBase:=cnt + + joinConf(currentConf,newMsgBase,FALSE,FALSE) ENDPROC RESULT_SUCCESS PROC internalCommandM() IF(ansiColour) ansiColour:=FALSE - aePuts('\b\nAnsi Color off\b\n') + aePuts('\b\nAnsi Color Off\b\n') ELSE ansiColour:=TRUE aePuts('\b\nAnsi Color On\b\n') @@ -23395,23 +22835,28 @@ PROC internalCommandM() ENDPROC RESULT_SUCCESS PROC internalCommandMS() - DEF conf,mystat,oldconf + DEF conf,msgbase,mystat,oldconf,oldMsgBase,n nonStopDisplayFlag:=FALSE oldconf:=currentConf + oldMsgBase:=currentMsgBase currentConf:=0 lineCount:=2 aePuts('\b\nScanning conferences for mail...\b\n\b\n') mciViewSafe:=FALSE FOR conf:=1 TO cmds.numConf IF (checkConfAccess(conf)) - mystat:=joinConf(conf,TRUE,FALSE,FORCE_MAILSCAN_ALL) + n:=getConfMsgBaseCount(conf) + FOR msgbase:=1 TO n + mystat:=joinConf(conf,msgbase,TRUE,FALSE,FORCE_MAILSCAN_ALL) + ENDFOR ENDIF EXIT mystat=RESULT_FAILURE ENDFOR mciViewSafe:=TRUE - joinConf(oldconf,TRUE,FALSE,FORCE_MAILSCAN_SKIP) + joinConf(oldconf,oldMsgBase,TRUE,FALSE,FORCE_MAILSCAN_SKIP) currentConf:=oldconf + currentMsgBase:=oldMsgBase ENDPROC RESULT_SUCCESS PROC internalCommandN(params) @@ -23537,7 +22982,7 @@ PROC internalCommandO() result:=RESULT_SUCCESS - IF((sysopAvail=FALSE) AND (checkSecurity(ACS_OVERRIDE_CHAT))=FALSE) + IF(sysopAvail=FALSE) AND (checkSecurity(ACS_OVERRIDE_CHAT)=FALSE) StringF(string,'\b\nSorry, \s, is not around right now\b\n',cmds.sysopName) aePuts(string) aePuts('You can use ''C'' to leave a comment.\b\n\b\n') @@ -23648,6 +23093,11 @@ PROC internalCommandQ() IF checkSecurity(ACS_QUIET_NODE) quietFlag:=Not(quietFlag) sendQuietFlag(quietFlag) + IF(quietFlag) + aePuts('\b\nQuiet Mode On\b\n') + ELSE + aePuts('\b\nQuiet Mode Off\b\n') + ENDIF ELSE RETURN RESULT_NOT_ALLOWED ENDIF @@ -23658,10 +23108,10 @@ PROC internalCommandR(params) setEnvStat(ENV_MAIL) parseParams(params) - getMailStatFile(currentConf) + getMailStatFile(currentConf,currentMsgBase) IF checkToolTypeExists(TOOLTYPE_CONF,currentConf,'CUSTOM')=FALSE - RETURN callMsgFuncs(MAIL_READ,0) + RETURN callMsgFuncs(MAIL_READ,0,0) ELSE customMsgbaseCmd(1,0,1) RETURN RESULT_SUCCESS @@ -23678,7 +23128,6 @@ ENDPROC RESULT_SUCCESS PROC internalCommandS() DEF tmp[150]:STRING DEF tmp2[25]:STRING - DEF n,i IF checkSecurity(ACS_DISPLAY_USER_STATS)=FALSE THEN RETURN RESULT_NOT_ALLOWED @@ -23703,7 +23152,7 @@ PROC internalCommandS() aePuts(tmp) StringF(tmp,'# Times On : \d\b\n',loggedOnUser.timesCalled AND $FFFF) aePuts(tmp) - StringF(tmp,'Times Today: \d\b\n',loggedOnUserKeys.timesOnToday AND $FFFF) + StringF(tmp,'Times Today: \d\b\n',getTodaysCalls(loggedOnUser,loggedOnUserKeys)) aePuts(tmp) StringF(tmp,'Msgs Posted: \d\b\n',loggedOnUser.messagesPosted AND $FFFF) aePuts(tmp) @@ -23743,7 +23192,7 @@ PROC internalCommandS() aePuts('\b\n') ENDPROC RESULT_SUCCESS -PROC internalCommandRZ(cmdcode,params) +PROC internalCommandRZ(cmdcode) IF checkSecurity(ACS_UPLOAD)=FALSE THEN RETURN RESULT_NOT_ALLOWED setEnvStat(ENV_UPLOADING) @@ -23752,7 +23201,7 @@ PROC internalCommandRZ(cmdcode,params) ELSE bgFileCheck:=FALSE ENDIF - uploadaFile(1,cmdcode,params) + uploadaFile(1,cmdcode) ENDPROC RESULT_SUCCESS PROC internalCommandT() @@ -23779,7 +23228,7 @@ PROC internalCommandT() ENDIF ENDPROC RESULT_SUCCESS -PROC internalCommandU(cmdcode,params) +PROC internalCommandU(cmdcode) IF checkSecurity(ACS_UPLOAD)=FALSE THEN RETURN RESULT_NOT_ALLOWED setEnvStat(ENV_UPLOADING) @@ -23788,7 +23237,7 @@ PROC internalCommandU(cmdcode,params) ELSE bgFileCheck:=FALSE ENDIF - uploadaFile(0,cmdcode,params) + uploadaFile(0,cmdcode) ENDPROC RESULT_SUCCESS PROC internalCommandUS() @@ -23821,7 +23270,7 @@ ENDPROC RESULT_SUCCESS PROC internalCommandVER() DEF tempStr[255]:STRING - StringF(tempStr,'\b\nAmiExpress \s (\s) Copyright ©2018/2019 Darren Coles\b\n',expressVer,expressDate) + StringF(tempStr,'\b\nAmiExpress \s (\s) Copyright �2018-2020 Darren Coles\b\n',expressVer,expressDate) aePuts(tempStr) aePuts('Original Version (C)1992-95 LightSpeed Technologies Inc.\b\n') StringF(tempStr,'Registered to \s.\b\n',regKey) @@ -23864,9 +23313,16 @@ PROC internalCommandW() aePuts('\b\n') IF((checkSecurity(ACS_EDIT_USER_NAME))=FALSE) + aePuts('[ 0] [DISABLED]\b\n') + ELSE + StringF(str,'[ 0] LOGIN NAME.............. \s\b\n',loggedOnUser.name) + aePuts(str) + ENDIF + + IF((checkSecurity(ACS_EDIT_EMAIL))=FALSE) aePuts('[ 1] [DISABLED]\b\n') ELSE - StringF(str,'[ 1] LOGIN NAME.............. \s\b\n',loggedOnUser.name) + StringF(str,'[ 1] EMAIL ADDRESS........... \s\b\n',loggedOnUserMisc.eMail) aePuts(str) ENDIF @@ -23995,9 +23451,9 @@ PROC internalCommandW() IF(checkToolTypeExists(TOOLTYPE_NODE,node,'BGFILECHECK')) option:=loggedOnUserKeys.userFlags AND USER_BGFILECHECK IF option - StringF(str,'[ 16] BACKGROUND FILE CHECK... NO\b\n') - ELSE StringF(str,'[ 16] BACKGROUND FILE CHECK... YES\b\n') + ELSE + StringF(str,'[ 16] BACKGROUND FILE CHECK... NO\b\n') ENDIF aePuts(str) ELSE @@ -24014,7 +23470,7 @@ PROC internalCommandW() IF (StrLen(str)=0) aePuts('\b\n') saveAccount(loggedOnUser,loggedOnUserKeys,loggedOnUserMisc,0,0) - checkUserOnLine(loggedOnUser,0) + checkUserOnLine(0) RETURN RESULT_SUCCESS ENDIF @@ -24022,7 +23478,7 @@ PROC internalCommandW() option:=Val(str) SELECT option - CASE 1 + CASE 0 ->EDIT USER NAME IF (checkSecurity(ACS_EDIT_USER_NAME)=FALSE) THEN JUMP cant loop1: @@ -24049,9 +23505,19 @@ PROC internalCommandW() UpperStr(str) strCpy(loggedOnUserKeys.userName,str,31) saveAccount(loggedOnUser,loggedOnUserKeys,loggedOnUserMisc,0,0) + CASE 1 + ->EDIT EMAIL ADDRESS + IF (checkSecurity(ACS_EDIT_EMAIL)=FALSE) THEN JUMP cant + aePuts('Email Address: ') + StrCopy(str,loggedOnUserMisc.eMail,50) + stat:=lineInput('',str,100,INPUT_TIMEOUT,str) + IF(stat<0) THEN RETURN stat + IF(StrLen(str)=0) THEN JUMP cant + strCpy(loggedOnUserMisc.eMail,str,50) CASE 2 ->EDIT REAL NAME IF (checkSecurity(ACS_EDIT_REAL_NAME)=FALSE) THEN JUMP cant + loop2: aePuts('Real Name: (Alpha Numeric) ') StrCopy(str,loggedOnUserMisc.realName,26) stat:=lineInput('',str,25,INPUT_TIMEOUT,str) @@ -24061,18 +23527,19 @@ PROC internalCommandW() stat:=checkForAst(str) IF(stat) aePuts('No wildcards allowed in a name.\b\n\b\n') - JUMP loop1 + JUMP loop2 ENDIF stat:=findUserFromName(1,NAME_TYPE_REALNAME,str,tempUser,tempUserKeys,tempUserMisc) IF(stat<>0) aePuts('Already in use!, try another.\b\n\b\n') - JUMP loop1 + JUMP loop2 ENDIF aePuts('Ok!\b\n') strCpy(loggedOnUserMisc.realName,str,26) CASE 3 ->EDIT INTERNET NAME IF (checkSecurity(ACS_EDIT_INTERNET_NAME)=FALSE) THEN JUMP cant + loop3: aePuts('Internet Name: (Alpha Numeric No Spaces) ') StrCopy(str,loggedOnUserMisc.internetName,10) stat:=lineInput('',str,9,INPUT_TIMEOUT,str) @@ -24082,12 +23549,12 @@ PROC internalCommandW() stat:=checkForAst(str) IF(stat) aePuts('No wildcards allowed in a name.\b\n\b\n') - JUMP loop1 + JUMP loop3 ENDIF stat:=findUserFromName(1,NAME_TYPE_INTERNETNAME,str,tempUser,tempUserKeys,tempUserMisc) IF(stat<>0) aePuts('Already in use!, try another.\b\n\b\n') - JUMP loop1 + JUMP loop3 ENDIF aePuts('Ok!\b\n') strCpy(loggedOnUserMisc.internetName,str,10) @@ -24434,7 +23901,7 @@ PROC internalCommandZOOM() ENDIF ENDPROC RESULT_SUCCESS -PROC asciiZoomConf(confNum,confNameType) +PROC asciiZoomConf(confNum,msgBaseNum,confNameType) DEF mystat,fi,fo,fi1,count,timeVar DEF cb:PTR TO confBase DEF tempstr[255]:STRING @@ -24442,8 +23909,9 @@ PROC asciiZoomConf(confNum,confNameType) DEF date[255]:STRING DEF zoomName[255]:STRING DEF zoomConfMailName[31]:STRING + DEF msgBaseLoc[255]:STRING - loadMsgPointers(confNum) + loadMsgPointers(confNum,msgBaseNum) SELECT confNameType CASE NAME_TYPE_USERNAME @@ -24455,7 +23923,7 @@ PROC asciiZoomConf(confNum,confNameType) ENDSELECT IF checkToolTypeExists(TOOLTYPE_CONF,confNum,'CUSTOM')=FALSE - mystat:=getMailStatFile(confNum) + mystat:=getMailStatFile(confNum,msgBaseNum) IF(mystat=RESULT_FAILURE) THEN RETURN RESULT_FAILURE IF(lastMsgReadConf0 WHILE(Fgets(fi1,tempstr,80)<>NIL) fileWrite(fo,tempstr) @@ -24577,7 +24046,7 @@ PROC asciiZoomConf(confNum,confNameType) lastMsgReadConf:=msgNum customAsciiDone: - saveMsgPointers(confNum) + saveMsgPointers(confNum,msgBaseNum) IF (count=0) aePuts('\tNo New Mail!\b\n') @@ -24591,30 +24060,36 @@ customAsciiDone: ENDPROC count PROC asciiZoom() - DEF conf,cnt + DEF conf,cnt,msgbase DEF mystat,zoomConfNameType + DEF tempStr1[255]:STRING + DEF tempStr2[255]:STRING DEF zoomName[255]:STRING StringF(zoomName,'\sNode\d/PlayPen/MESSAGES.DAT',cmds.bbsLoc,node) DeleteFile(zoomName) - saveMsgPointers(currentConf) + saveMsgPointers(currentConf,currentMsgBase) cnt:=0 FOR conf:=1 TO cmds.numConf IF (checkConfAccess(conf)) - zoomConfNameType:=NAME_TYPE_USERNAME - IF checkToolTypeExists(TOOLTYPE_CONF,conf,'REALNAME') - zoomConfNameType:=NAME_TYPE_REALNAME - ELSEIF checkToolTypeExists(TOOLTYPE_CONF,conf,'INTERNETNAME') - zoomConfNameType:=NAME_TYPE_INTERNETNAME - ENDIF - - mystat:=asciiZoomConf(conf,zoomConfNameType) - IF mystat<>RESULT_ABORT THEN cnt++ + FOR msgbase:=1 TO getConfMsgBaseCount(conf) + zoomConfNameType:=NAME_TYPE_USERNAME + StringF(tempStr1,'REALNAME.\d',msgbase) + StringF(tempStr2,'INTERNETNAME.\d',msgbase) + IF checkToolTypeExists(TOOLTYPE_CONF,conf,'REALNAME') OR checkToolTypeExists(TOOLTYPE_MSGBASE,conf,tempStr1) + zoomConfNameType:=NAME_TYPE_REALNAME + ELSEIF checkToolTypeExists(TOOLTYPE_CONF,conf,'INTERNETNAME') OR checkToolTypeExists(TOOLTYPE_MSGBASE,conf,tempStr2) + zoomConfNameType:=NAME_TYPE_INTERNETNAME + ENDIF + + mystat:=asciiZoomConf(conf,msgbase,zoomConfNameType) + IF mystat<>RESULT_ABORT THEN cnt++ + ENDFOR ENDIF EXIT mystat=RESULT_FAILURE IF (mystat=RESULT_TIMEOUT) OR (mystat=RESULT_NO_CARRIER) - loadMsgPointers(currentConf) + loadMsgPointers(currentConf,currentMsgBase) RETURN mystat ENDIF ENDFOR @@ -24624,10 +24099,10 @@ PROC asciiZoom() RETURN RESULT_ABORT ENDIF - loadMsgPointers(currentConf) + loadMsgPointers(currentConf,currentMsgBase) ENDPROC RESULT_SUCCESS -PROC qwkZoomConf(confNum,recNum,confNameType) +PROC qwkZoomConf(confNum,msgBaseNum,recNum,confNameType) DEF mystat,fi,fo,fo2,count DEF cb:PTR TO confBase DEF tempstr[255]:STRING @@ -24639,8 +24114,9 @@ PROC qwkZoomConf(confNum,recNum,confNameType) DEF ndx:qwkNDX DEF cnt DEF zoomConfMailName[31]:STRING + DEF msgBaseLoc[255]:STRING - loadMsgPointers(confNum) + loadMsgPointers(confNum,msgBaseNum) SELECT confNameType CASE NAME_TYPE_USERNAME @@ -24652,7 +24128,7 @@ PROC qwkZoomConf(confNum,recNum,confNameType) ENDSELECT IF checkToolTypeExists(TOOLTYPE_CONF,confNum,'CUSTOM')=FALSE - mystat:=getMailStatFile(confNum) + mystat:=getMailStatFile(confNum,msgBaseNum) IF(mystat=RESULT_FAILURE) THEN RETURN RESULT_FAILURE,recNum IF(lastMsgReadConf6 THEN SetStr(tempstr,6) fileWrite(fo,'000000,') fileWrite(fo,tempstr); fileWrite(fo,'\b\n') - formatLongDateTime2(getSystemTime(),tempstr) + formatLongDateTime2(getSystemTime(),tempstr,",") fileWrite(fo,tempstr); fileWrite(fo,'\b\n') StrCopy(tempstr,loggedOnUser.name) UpperStr(tempstr) @@ -24854,18 +24334,22 @@ PROC qwkZoom() count:=0 FOR conf:=1 TO cmds.numConf - IF (checkConfAccess(conf)) THEN count++ + IF (checkConfAccess(conf)) THEN count:=count+getConfMsgBaseCount(conf) ENDFOR StringF(tempstr,'\d\b\n',count-1) fileWrite(fo,tempstr) + n:=1 FOR conf:=1 TO cmds.numConf IF (checkConfAccess(conf)) - StringF(tempstr,'\d\b\n',relConf(conf)) - fileWrite(fo,tempstr) - StringF(tempstr,'\s',getConfName(conf)) - IF StrLen(tempstr)>10 THEN SetStr(tempstr,10) - StrAdd(tempstr,'\b\n') - fileWrite(fo,tempstr) + FOR msgbase:=1 TO getConfMsgBaseCount(conf) + StringF(tempstr,'\d\b\n',n) + fileWrite(fo,tempstr) + getMsgBaseName(conf,msgbase,tempstr) + IF StrLen(tempstr)>10 THEN SetStr(tempstr,10) + StrAdd(tempstr,'\b\n') + fileWrite(fo,tempstr) + n++ + ENDFOR ENDIF ENDFOR fileWrite(fo,'HELLO\b\n') @@ -24888,25 +24372,29 @@ PROC qwkZoom() floatMsgRecNum:=1.0 cnt:=0 - saveMsgPointers(currentConf) + saveMsgPointers(currentConf,currentMsgBase) FOR conf:=1 TO cmds.numConf IF (checkConfAccess(conf)) - zoomConfNameType:=NAME_TYPE_USERNAME - IF checkToolTypeExists(TOOLTYPE_CONF,conf,'REALNAME') - zoomConfNameType:=NAME_TYPE_REALNAME - ELSEIF checkToolTypeExists(TOOLTYPE_CONF,conf,'INTERNETNAME') - zoomConfNameType:=NAME_TYPE_INTERNETNAME - ENDIF - mystat,floatMsgRecNum:=qwkZoomConf(conf,floatMsgRecNum,zoomConfNameType) - IF mystat<>RESULT_ABORT THEN cnt++ + FOR msgbase:=1 TO getConfMsgBaseCount(conf) + zoomConfNameType:=NAME_TYPE_USERNAME + StringF(namestr1,'REALNAME.\d',msgbase) + StringF(namestr2,'INTERNETNAME.\d',msgbase) + IF checkToolTypeExists(TOOLTYPE_CONF,conf,'REALNAME') OR checkToolTypeExists(TOOLTYPE_MSGBASE,conf,namestr1) + zoomConfNameType:=NAME_TYPE_REALNAME + ELSEIF checkToolTypeExists(TOOLTYPE_CONF,conf,'INTERNETNAME') OR checkToolTypeExists(TOOLTYPE_MSGBASE,conf,namestr2) + zoomConfNameType:=NAME_TYPE_INTERNETNAME + ENDIF + mystat,floatMsgRecNum:=qwkZoomConf(conf,msgbase,floatMsgRecNum,zoomConfNameType) + IF mystat<>RESULT_ABORT THEN cnt++ + ENDFOR ENDIF EXIT mystat=RESULT_FAILURE IF (mystat=RESULT_TIMEOUT) OR (mystat=RESULT_NO_CARRIER) - loadMsgPointers(currentConf) + loadMsgPointers(currentConf,currentMsgBase) RETURN mystat ENDIF ENDFOR - loadMsgPointers(currentConf) + loadMsgPointers(currentConf,currentMsgBase) IF cnt=0 aePuts('No conferences selected for zooming. Use CF to configure\b\n') @@ -25439,6 +24927,7 @@ PROC maintenanceFileSearch(holddir,fname:PTR TO CHAR,searchList: PTR TO stringli DEF datestr[258]:STRING DEF test:PTR TO CHAR DEF viewAllowed,prev + DEF patternBuf,patBufLen fi:=Open(fname,MODE_OLDFILE) @@ -25470,9 +24959,26 @@ PROC maintenanceFileSearch(holddir,fname:PTR TO CHAR,searchList: PTR TO stringli ENDWHILE SetStr(tempStr,i) + patBufLen:=StrLen(tempStr)*2+2 + patternBuf:=New(patBufLen) + IF patternBuf=0 + Close(fi) + myError(1) + RETURN RESULT_FAILURE,0,0 + ENDIF + + IF (ParsePatternNoCase(tempStr, patternBuf, patBufLen))=-1 + myError(1) + Dispose(patternBuf) + Close(fi) + RETURN RESULT_FAILURE,0,0 + ENDIF + FOR i:=0 TO searchList.count()-1 - IF stcsma(tempStr,searchList.item(i)) THEN found:=1 + IF MatchPatternNoCase(patternBuf,searchList.item(i)) THEN found:=1 ENDFOR + + Dispose(patternBuf) ENDIF IF found @@ -25889,7 +25395,7 @@ PROC myNewFiles(params) day:=Val(str+3) year:=Val(str+6) - IF (year>TWODIGITYEARSWITCHOVER) THEN year:=1900+year ELSE year:=2000+year + IF (year<100) AND (year>TWODIGITYEARSWITCHOVER) THEN year:=1900+year ELSE year:=2000+year ->sscanf(str,"%d %d %d",&month,&day,&year); @@ -25983,7 +25489,7 @@ PROC myNewFiles(params) mdt:=Val(dt) ddt:=Val(dt+3) ydt:=Val(dt+6) - IF (ydt>TWODIGITYEARSWITCHOVER) THEN ydt:=1900+ydt ELSE ydt:=2000+ydt + IF (ydt<100) AND (ydt>TWODIGITYEARSWITCHOVER) THEN ydt:=1900+ydt ELSE ydt:=2000+ydt ->sscanf(dt,"%d %d %d",&mdt,&ddt,&ydt); @@ -26079,7 +25585,7 @@ ENDPROC RESULT_SUCCESS PROC confScan() - DEF mystat,conf + DEF mystat,conf,n,msgbase DEF prompt=FALSE DEF mscan=TRUE DEF fscan=TRUE @@ -26100,12 +25606,16 @@ PROC confScan() FOR conf:=1 TO cmds.numConf IF (checkConfAccess(conf)) - IF prompt=FALSE - mscan:=checkMailConfScan(conf) - ENDIF fscan:=checkFileConfScan(conf) - mystat:=joinConf(conf,TRUE,FALSE,IF mscan=FALSE THEN FORCE_MAILSCAN_SKIP ELSE FORCE_MAILSCAN_NOFORCE) + + n:=getConfMsgBaseCount(conf) + FOR msgbase:=1 TO n + IF prompt=FALSE + mscan:=checkMailConfScan(conf,msgbase) + ENDIF + mystat:=joinConf(conf,msgbase,TRUE,FALSE,IF mscan=FALSE THEN FORCE_MAILSCAN_SKIP ELSE FORCE_MAILSCAN_NOFORCE) + ENDFOR IF (mystat=RESULT_SUCCESS) AND (fscan) newFilesPauseFlag:=TRUE currentConf:=conf @@ -26128,7 +25638,7 @@ PROC confScan() ->//AEPutStr("\b\n --Checking for PartUploads\b\n"); FOR conf:=1 TO cmds.numConf IF (checkConfAccess(conf)) - mystat:=joinConf(conf,TRUE,FALSE,FORCE_MAILSCAN_SKIP) + mystat:=joinConf(conf,1,TRUE,FALSE,FORCE_MAILSCAN_SKIP) IF (mystat=RESULT_SUCCESS) mystat:=partUploadOK(1) @@ -26141,7 +25651,7 @@ PROC confScan() ELSE bgFileCheck:=FALSE ENDIF - uploadaFile(0,'URG','') + uploadaFile(0,'URG') ENDIF ELSEIF(mystat=RESULT_ABORT) aePuts('\b\n') @@ -26157,29 +25667,33 @@ PROC confScan() ENDIF ENDPROC RESULT_SUCCESS -PROC captureRealAndInternetNames() - DEF i,stat,valid +PROC captureRealAndInternetNames(conf,msgbase) + DEF stat,valid DEF realNamesUsed=FALSE,internetNamesUsed=FALSE DEF tempstr[30]:STRING + DEF namestr[255]:STRING - FOR i:=1 TO cmds.numConf - IF checkConfAccess(i) - IF checkToolTypeExists(TOOLTYPE_CONF,i,'REALNAME') THEN realNamesUsed:=TRUE - IF checkToolTypeExists(TOOLTYPE_CONF,i,'INTERNETNAME') THEN internetNamesUsed:=TRUE - ENDIF - ENDFOR + IF (conf<1) OR (msgbase<1) THEN RETURN RESULT_SUCCESS + + IF checkToolTypeExists(TOOLTYPE_CONF,conf,'REALNAME') THEN realNamesUsed:=TRUE + IF checkToolTypeExists(TOOLTYPE_CONF,conf,'INTERNETNAME') THEN internetNamesUsed:=TRUE + StringF(namestr,'REALNAME.\d',msgbase) + IF checkToolTypeExists(TOOLTYPE_MSGBASE,conf,namestr) THEN realNamesUsed:=TRUE + StringF(namestr,'INTERNETNAME.\d',msgbase) + IF checkToolTypeExists(TOOLTYPE_MSGBASE,conf,namestr) THEN internetNamesUsed:=TRUE IF ((realNamesUsed=TRUE) AND (StrLen(loggedOnUserMisc.realName)=0)) valid:=FALSE aePuts('\b\n') IF displayScreen(SCREEN_REALNAMES)=FALSE - aePuts('Real Names are required in some conferences\b\non this system\b\n') + aePuts('Real Names are required for messages in this conference/msgbase \b\n') ENDIF aePuts('\b\n') REPEAT aePuts('Real Name (Alpha Numeric): ') stat:=lineInput('','',25,INPUT_TIMEOUT,tempstr) IF stat<0 THEN RETURN stat + IF StrLen(tempstr)=0 THEN RETURN RESULT_FAILURE IF (StrLen(tempstr)<>1) AND (strCmpi(tempstr,loggedOnUserMisc.realName,ALL)=FALSE) aePuts('\b\nChecking for duplicate name...') @@ -26202,7 +25716,7 @@ PROC captureRealAndInternetNames() aePuts('\b\n') IF displayScreen(SCREEN_INTERNETNAMES)=FALSE - aePuts('Internet Names are required in some conferences\b\non this system\b\n') + aePuts('Internet Names are required for messages in this conference/msgbase\b\n') ENDIF aePuts('\b\n') @@ -26211,6 +25725,8 @@ PROC captureRealAndInternetNames() stat:=lineInput('','',9,INPUT_TIMEOUT,tempstr) IF stat<0 THEN RETURN stat + IF StrLen(tempstr)=0 THEN RETURN RESULT_FAILURE + IF (StrLen(tempstr)<>1) AND (strCmpi(tempstr,loggedOnUserMisc.internetName,ALL)=FALSE) aePuts('\b\nChecking for duplicate name...') stat:=checkForAst(tempstr) @@ -26229,7 +25745,7 @@ PROC captureRealAndInternetNames() ENDPROC RESULT_SUCCESS -PROC processCommand(cmdtext,internalOnly=FALSE) +PROC processCommand(cmdtext,internalOnly=FALSE, allowsyscmd=FALSE) DEF cmdcode[255]:STRING DEF cmdparams[255]:STRING DEF spacepos @@ -26239,7 +25755,7 @@ PROC processCommand(cmdtext,internalOnly=FALSE) spacepos:=InStr(cmdtext,' ') IF spacepos>=0 - MidStr(cmdcode,cmdtext,0,spacepos) + midStr2(cmdcode,cmdtext,0,spacepos) MidStr(cmdparams,cmdtext,spacepos+1,ALL) ELSE StrCopy(cmdcode,cmdtext,ALL) @@ -26249,6 +25765,7 @@ PROC processCommand(cmdtext,internalOnly=FALSE) -> try running it as a bbscommand first IF (internalOnly=FALSE) + IF allowsyscmd THEN IF runSysCommand(cmdcode,cmdparams) THEN RETURN RESULT_SUCCESS IF runBbsCommand(cmdcode,cmdparams) THEN RETURN RESULT_SUCCESS ENDIF ENDPROC processInternalCommand(cmdcode,cmdparams) @@ -26261,7 +25778,7 @@ PROC processSysCommand(cmdtext, allowBBSCmd=FALSE) IF EstrLen(cmdtext)=0 THEN RETURN IF (spacepos:=InStr(cmdtext,' '))>=0 - MidStr(cmdcode,cmdtext,0,spacepos) + midStr2(cmdcode,cmdtext,0,spacepos) MidStr(cmdparams,cmdtext,spacepos+1,ALL) ELSE StrCopy(cmdcode,cmdtext,ALL) @@ -26284,7 +25801,7 @@ PROC processInternalCommand(cmdcode,cmdparams,privcmd=FALSE) IF (StrCmp(cmdcode,'0')) res:=internalCommand0() ELSEIF (StrCmp(cmdcode,'1')) - res:=internalCommand1(cmdparams) + res:=internalCommand1() ELSEIF (StrCmp(cmdcode,'2')) res:=internalCommand2(cmdparams) ELSEIF (StrCmp(cmdcode,'3')) @@ -26313,10 +25830,16 @@ PROC processInternalCommand(cmdcode,cmdparams,privcmd=FALSE) res:=internalCommandG(cmdparams) ELSEIF (StrCmp(cmdcode,'J')) res:=internalCommandJ(cmdparams) + ELSEIF (StrCmp(cmdcode,'JM')) + res:=internalCommandJM(cmdparams) ELSEIF (StrCmp(cmdcode,'<')) res:=internalCommandLT() + ELSEIF (StrCmp(cmdcode,'<<')) + res:=internalCommandLT2() ELSEIF (StrCmp(cmdcode,'>')) res:=internalCommandGT() + ELSEIF (StrCmp(cmdcode,'>>')) + res:=internalCommandGT2() ELSEIF (StrCmp(cmdcode,'R')) res:=internalCommandR(cmdparams) ELSEIF (StrCmp(cmdcode,'A')) @@ -26327,6 +25850,8 @@ PROC processInternalCommand(cmdcode,cmdparams,privcmd=FALSE) res:=internalCommandC(cmdparams) ELSEIF (StrCmp(cmdcode,'CF')) res:=internalCommandCF() + ELSEIF (StrCmp(cmdcode,'GR')) + res:=internalCommandGreets() ELSEIF (StrCmp(cmdcode,'CM')) res:=internalCommandCM() ELSEIF (StrCmp(cmdcode,'E')) @@ -26350,13 +25875,13 @@ PROC processInternalCommand(cmdcode,cmdparams,privcmd=FALSE) ELSEIF (StrCmp(cmdcode,'RL')) res:=internalCommandRL(cmdparams) ELSEIF (StrCmp(cmdcode,'U')) - res:=internalCommandU(cmdcode,cmdparams) + res:=internalCommandU(cmdcode) ELSEIF (StrCmp(cmdcode,'US')) res:=internalCommandUS() ELSEIF (StrCmp(cmdcode,'UP')) res:=internalCommandUP() ELSEIF (StrCmp(cmdcode,'RZ')) - res:=internalCommandRZ(cmdcode,cmdparams) + res:=internalCommandRZ(cmdcode) ELSEIF (StrCmp(cmdcode,'V')) res:=internalCommandV(cmdcode,cmdparams) ELSEIF (StrCmp(cmdcode,'VER')) @@ -26402,9 +25927,17 @@ PROC displayMenuPrompt() ENDIF ENDPROC +PROC getTodaysCalls(user:PTR TO user, userKeys:PTR TO userKeys) + DEF currTime,currDay,lastDay + + currTime:=getSystemTime() + currDay:=Div(currTime-21600,86400) + lastDay:=Div(user.timeLastOn-21600,86400) + IF currDay<>lastDay THEN RETURN 0 +ENDPROC userKeys.timesOnToday AND $FFFF + PROC processLoggedOnUser() DEF subState: PTR TO loggedOnState - DEF wasControl,ch DEF string[255]:STRING DEF temp,stat DEF lastDay,currDay @@ -26432,7 +25965,7 @@ PROC processLoggedOnUser() IF (lastDay<>currDay) StringF(string,'timeused debug: \s logon new day reset, currday \d, lastday \d',loggedOnUser.name, currDay,lastDay) - debugLog(LOG_WARN,string) + debugLog(LOG_DEBUG,string) loggedOnUserKeys.timesOnToday:=0 loggedOnUser.timeUsed:=0 @@ -26442,7 +25975,7 @@ PROC processLoggedOnUser() ELSE loggedOnUserKeys.timesOnToday:=loggedOnUserKeys.timesOnToday+1 StringF(string,'timeused debug: \s logon same day, currday \d, lastday \d, timeused \d',loggedOnUser.name,currDay,lastDay,loggedOnUser.timeUsed) - debugLog(LOG_WARN,string) + debugLog(LOG_DEBUG,string) ENDIF timeLimit:=loggedOnUser.timeTotal-loggedOnUser.timeUsed @@ -26478,9 +26011,6 @@ PROC processLoggedOnUser() ENDIF IF (stat) AND (reqState=REQ_STATE_NONE) stat:=confScan() - IF stat=RESULT_SUCCESS - stat:=captureRealAndInternetNames() - ENDIF IF stat=RESULT_SUCCESS subState.subState:=SUBSTATE_DISPLAY_CONF_BULL ELSE @@ -26490,7 +26020,7 @@ PROC processLoggedOnUser() reqState:=REQ_STATE_LOGOFF ENDIF ELSEIF subState.subState=SUBSTATE_DISPLAY_CONF_BULL - joinConf(loggedOnUser.confRJoin,FALSE,FORCE_MAILSCAN_SKIP) + joinConf(loggedOnUser.confRJoin,loggedOnUser.msgBaseRJoin,FALSE,FORCE_MAILSCAN_SKIP) loadFlagged() IF StrLen(historyFolder)>0 THEN loadHistory() blockOLM:=FALSE @@ -26584,7 +26114,7 @@ PROC processSysopLogon() confNameType:=NAME_TYPE_USERNAME displayUserToCallersLog(0) updateCallerNum() - checkUserOnLine(loggedOnUser,0) + checkUserOnLine(0) validUser:=1 ximPort:=CONSOLE_PORT state:=STATE_LOGGEDON @@ -26658,22 +26188,70 @@ ENDPROC 0 PROC checkPassword() - DEF tries=0,stat,lfh + DEF tries=0,stat,lfh,i,r DEF tempStr[255]:STRING DEF tempStr2[255]:STRING + DEF resetCode[25]:STRING + DEF resetChars[62]:STRING WHILE TRUE displayUserToCallersLog(0) REPEAT + StrCopy(resetCode,'') IF(tries>2) aePuts('\b\nExcessive Password Failure\b\n') - runSysCommand('PWFAIL','') - JUMP logoffErr + + IF checkToolTypeExists(TOOLTYPE_BBSCONFIG,'','MAIL_ON_PWD_FAIL') AND (StrLen(mailOptions.smtpHost)>0) AND (StrLen(loggedOnUserMisc.eMail)>0) + + aePuts('\b\nDo you want to send a reset code to your email address ') + stat:=yesNo(1) + IF(stat<0) THEN RETURN RESULT_SLEEP_LOGOFF + IF stat + FOR i:=1 TO 10 + StrCopy(resetChars,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') + r:=Rnd(StrLen(resetChars)) + StrAdd(resetCode,resetChars+r,1) + ENDFOR + + StringF(tempStr,'\s: Ami-Express password failure notification',cmds.bbsName) + StrCopy(tempStr2,'You have forgotten your password and requested a reset code. If you did not request the reset code then please ignore this email\b\n\b\n') + StrAdd(tempStr2,'The reset code is : ') + StrAdd(tempStr2,resetCode) + StrAdd(tempStr2,'\b\n\b\nYou can use this code to reset your password and gain access to the system\b\n') + sendMail(tempStr,tempStr2,FALSE,NIL,0,loggedOnUserMisc.eMail) + + aePuts('\b\nA reset code has been sent to yuour email address. Please enter it exactly below\b\n\b\n') + stat:=lineInput('Reset code: ','',20,INPUT_TIMEOUT,tempStr) + IF(stat<0) THEN RETURN RESULT_SLEEP_LOGOFF + + IF StrCmp(tempStr,resetCode)=FALSE + aePuts('\b\nThe reset code was not correct.\b\n') + StrCopy(resetCode,'') + ELSE + aePuts('\b\nThe reset code was correct, please now update your password.\b\n\b\n') + aePuts('Password: ') + stat:=lineInput('','',50,INPUT_TIMEOUT,tempStr) + IF(stat<0) THEN RETURN RESULT_NO_CARRIER + IF(StrLen(tempStr)>0) + UpperStr(tempStr) + loggedOnUser.pwdHash:=calcPasswordHash(tempStr) + ENDIF + ENDIF + ENDIF + ENDIF + IF StrLen(resetCode)=0 + runSysCommand('PWFAIL','') + JUMP logoffErr + ENDIF ENDIF - stat:=getPass2(passwordPrompt,0,loggedOnUser.pwdHash,50,tempStr) - IF(stat<0) - IF stat=RESULT_NO_CARRIER THEN RETURN RESULT_NO_CARRIER ELSE RETURN RESULT_SLEEP_LOGOFF + IF StrLen(resetCode)=0 + stat:=getPass2(passwordPrompt,0,loggedOnUser.pwdHash,50,tempStr) + IF(stat<0) + IF stat=RESULT_NO_CARRIER THEN RETURN RESULT_NO_CARRIER ELSE RETURN RESULT_SLEEP_LOGOFF + ENDIF + ELSE + stat:=RESULT_SUCCESS ENDIF IF(stat<>RESULT_SUCCESS) StringF(tempStr2,'\tPassword Failure (\s)',tempStr) @@ -26681,6 +26259,7 @@ PROC checkPassword() aePuts('Invalid PassWord\b\n') tries++ ENDIF + UNTIL stat=RESULT_SUCCESS IF(checkToolTypeExists(TOOLTYPE_NODE,node,'PHONECHECK')) @@ -26872,7 +26451,7 @@ PROC processLogon() ENDIF aePuts(tempStr) - StringF(tempStr,'\b\n\b\nRunning AmiExpress \s Copyright ©2018/2019 Darren Coles\b\n',expressVer) + StringF(tempStr,'\b\n\b\nRunning AmiExpress \s Copyright �2018-2020 Darren Coles\b\n',expressVer) aePuts(tempStr) aePuts('Original Version (C)1992-95 LightSpeed Technologies Inc.\b\n') StringF(tempStr,'Registration \s. You are connected to Node \d at \d baud',regKey,node,onlineBaud) @@ -27028,7 +26607,7 @@ logonLoop: RETURN ENDIF - stat:=checkUserOnLine(loggedOnUser,1) + stat:=checkUserOnLine(1) IF(stat=FALSE) StringF(tempStr,'User \s already on another node!',loggedOnUser.name) callersLog(tempStr) @@ -27105,7 +26684,7 @@ logonLoop: IF (checkToolTypeExists(TOOLTYPE_BBSCONFIG,0,'MAIL_ON_LOGON')) AND (StrLen(mailOptions.sysopEmail)>0) StringF(tempStr,'\s: Ami-Express logon notification',cmds.bbsName) StringF(tempStr2,'This is a notification that \s from \s has logged on\n\n',loggedOnUser.name,loggedOnUser.location) - sendMail(tempStr,tempStr2,TRUE, mailOptions.sysopEmail) + sendMail(tempStr,tempStr2,FALSE, NIL,0,mailOptions.sysopEmail) ENDIF ENDIF @@ -27145,7 +26724,7 @@ PROC processAwait() serShared:=FALSE subState.subState:=SUBSTATE_DISPLAY_AWAIT subState.redrawScreen:=FALSE - IF(sopt.trapDoor=FALSE) THEN resetSystem(1) + IF(sopt.trapDoor=FALSE) THEN resetSystem() stateData:=subState logonType:=LOGON_TYPE_LOGGED_OFF @@ -27172,9 +26751,9 @@ PROC processAwait() send017() sendCLS() - StringF(tempstr,'\b\n © 1992-1995 AmiExpress by Light Speed Technologies Inc.\b\n') + StringF(tempstr,'\b\n � 1992-1995 AmiExpress by Light Speed Technologies Inc.\b\n') aePuts(tempstr) - StringF(tempstr,'\b\n  Version 5 ©2018/2019\b\n') + StringF(tempstr,'\b\n  Version 5 �2018-2020\b\n') aePuts(tempstr) StringF(tempstr,'\b\n  Programming by:  Darren Coles') @@ -27214,10 +26793,8 @@ PROC processAwait() ObtainSemaphore(masterNode) ni:=(masterNode.myNode[node]) IF ni.telnetSocket=-2 - debugLog(LOG_DEBUG,'check incoming call - socket = -2') cntr:=cntr+1 IF cntr=20 - debugLog(LOG_DEBUG,'check incoming call - socket = -2, counter=20, reset socket to -1') cntr:=0 ni.telnetSocket:=-1 ENDIF @@ -27227,7 +26804,8 @@ PROC processAwait() ReleaseSemaphore(masterNode) ENDIF - IF (checkSer()) OR (sopt.trapDoor) OR (instantLogon) OR (checkTelnetConnection()) + IF (checkSer()) OR (sopt.trapDoor) OR (instantLogon) OR (checkTelnetConnection()) AND (reqState=REQ_STATE_NONE) + IF checkIncomingCall()=RESULT_CONNECT debugLog(LOG_DEBUG,'REMOTE LOGON') ioFlags[IOFLAG_SCR_OUT]:=-1 @@ -27360,7 +26938,7 @@ PROC newUserAccount(userName: PTR TO CHAR) IF (checkToolTypeExists(TOOLTYPE_BBSCONFIG,0,'MAIL_ON_NEW_USER')) AND (StrLen(mailOptions.sysopEmail)>0) StringF(tempStr,'\s: Ami-Express new user notification',cmds.bbsName) StringF(tempStr2,'This is a notification that a new user called \s from \s has registered.',loggedOnUser.name,loggedOnUser.location) - sendMail(tempStr,tempStr2,FALSE,mailOptions.sysopEmail) + sendMail(tempStr,tempStr2,FALSE,msgBuf,lines,mailOptions.sysopEmail) ENDIF IF displayScreen(SCREEN_JOINED) THEN doPause() @@ -27451,12 +27029,23 @@ jLoop3: JUMP jLoop2 ENDIF +jLoop4: + aePuts('E-Mail Address: ') + stat:=lineInput('','',50,INPUT_TIMEOUT,string) + IF(stat<0) THEN RETURN stat + strCpy(loggedOnUserMisc.eMail,string,50) + + IF(StrLen(loggedOnUserMisc.eMail)=0) + aePuts('\b\n') + JUMP jLoop3 + ENDIF + aePuts('Enter a PassWord: ') stat:=lineInput('','',50,INPUT_TIMEOUT,string) IF(stat<0) THEN RETURN stat IF(StrLen(string)=0) aePuts('\b\n') - JUMP jLoop3 + JUMP jLoop4 ENDIF UpperStr(string) loggedOnUser.pwdHash:=calcPasswordHash(string) @@ -27490,6 +27079,8 @@ jLoop3: aePuts(string) StringF(string,'Phone Num: \s\b\n',loggedOnUser.phoneNumber) aePuts(string) + StringF(string,'E-Mail : \s\b\n',loggedOnUserMisc.eMail) + aePuts(string) StringF(string,'Num Lines: \d\b\n',loggedOnUser.lineLength) aePuts(string) StringF(string,'PassWord : \s\b\n','ENCRYPTED') @@ -27521,7 +27112,6 @@ PROC doNewUserQuestions() DEF filename[200]:STRING, afilename[200]:STRING DEF ch,stat,lock DEF c[200]:STRING,string[200]:STRING,datestr[20]:STRING - DEF p: PTR TO CHAR DEF fp2,fp1 DEF temp1[255]:STRING @@ -27616,9 +27206,20 @@ qbreak: ENDIF ENDPROC RESULT_SUCCESS +PROC memClear(data:PTR TO CHAR,size) + WHILE (size>0) + data[]:=0 + size-- + ENDWHILE +ENDPROC + PROC initNewUser(userData:PTR TO user,userKeys: PTR TO userKeys,userMisc: PTR TO userMisc,slotNumber) DEF ttdata[255]:STRING + memClear(userData,SIZEOF user) + memClear(userKeys,SIZEOF userKeys) + memClear(userMisc,SIZEOF userMisc) + StringF(ttdata,'\sNode\d/Preset.1',cmds.bbsLoc,node) IF configFileExists(ttdata) userData.secStatus:=readToolTypeInt(TOOLTYPE_NODE_PRESET,1,'PRESET.ACCESS') @@ -27626,6 +27227,7 @@ PROC initNewUser(userData:PTR TO user,userKeys: PTR TO userKeys,userMisc: PTR TO userData.secLibrary:=readToolTypeInt(TOOLTYPE_NODE_PRESET,1,'PRESET.RATIO') userData.timeLimit:=readToolTypeInt(TOOLTYPE_NODE_PRESET,1,'PRESET.TIME_LIMIT') userData.confRJoin:=readToolTypeInt(TOOLTYPE_NODE_PRESET,1,'PRESET.CONFRJOIN') + userData.msgBaseRJoin:=readToolTypeInt(TOOLTYPE_NODE_PRESET,1,'PRESET.MSGBASERJOIN') userData.dailyBytesLimit:=readToolTypeInt(TOOLTYPE_NODE_PRESET,1,'PRESET.DAILY_BYTE_LIMIT') readToolType(TOOLTYPE_NODE_PRESET,1,'PRESET.AREA',ttdata) ELSE @@ -27634,37 +27236,17 @@ PROC initNewUser(userData:PTR TO user,userKeys: PTR TO userKeys,userMisc: PTR TO userData.secLibrary:=readToolTypeInt(TOOLTYPE_PRESET,1,'PRESET.RATIO') userData.timeLimit:=readToolTypeInt(TOOLTYPE_PRESET,1,'PRESET.TIME_LIMIT') userData.confRJoin:=readToolTypeInt(TOOLTYPE_PRESET,1,'PRESET.CONFRJOIN') + userData.msgBaseRJoin:=readToolTypeInt(TOOLTYPE_PRESET,1,'PRESET.MSGBASERJOIN') userData.dailyBytesLimit:=readToolTypeInt(TOOLTYPE_PRESET,1,'PRESET.DAILY_BYTE_LIMIT') readToolType(TOOLTYPE_PRESET,1,'PRESET.AREA',ttdata) ENDIF - userData.messagesPosted:=0 userData.newUser:=1 - userData.newSinceDate:=0 - userData.uploads:=0 - userData.downloads:=0 IF(userData.confRJoin=NIL) THEN userData.confRJoin:=1 - userData.timeLastOn:=0 - userData.timeUsed:=0 userData.timeTotal:=userData.timeLimit - userData.timesCalled:=0 - userData.bytesDownload:=0 - userData.bytesUpload:=0 userData.protocol:="Z" userData.timeLastOn:=getSystemTime() - - userData.dailyBytesDld:=0 - userData.chatLimit:=0; userData.chatRemain:=0; userData.creditDays:=0 - userData.creditAmount:=0; userData.creditStartDate:=0; userData.creditTotalToDate:=0 - userData.creditTotalDate:=0; userData.creditTracking:=0; userData.confYM9:=0 - - userData.accountDate:=getSystemTime(); userData.screenType:=0 - userData.editorType:=0 - - /*userData.confRead1:=0*/ userData.confRead2:=0; userData.confRead3:=0 - userData.zoomType:=0; userData.unknown:=0; userData.unknown2:=0; userData.unknown3:=0 - userData.xferProtocol:=0; userData.filler2:=0 - userData.lcFiles:=0; userData.badFiles:=0 + userData.accountDate:=getSystemTime() userData.expert:="N" strCpy(userData.conferenceAccess,ttdata,10) @@ -27673,13 +27255,6 @@ PROC initNewUser(userData:PTR TO user,userKeys: PTR TO userKeys,userMisc: PTR TO userData.slotNumber:=slotNumber userKeys.number:=slotNumber strCpy(userKeys.userName,userData.name,ALL) - - userKeys.oldDnCPS:=0 - userKeys.dnCPS2:=0 - userKeys.oldUpCPS:=0 - userKeys.upCPS2:=0 - userKeys.baud:=0 /* hold last logged on baud rate */ - ENDPROC PROC createNewAccount() @@ -27690,7 +27265,7 @@ PROC createNewAccount() loggedOnUserMisc:=NEW loggedOnUserMisc loggedOnUser.pass0:=0 - ->strCpy(loggedOnUser.pass,'',ALL) + strCpy(loggedOnUser.pass,'',ALL) loggedOnUser.slotNumber:=0 initNewUser(loggedOnUser,loggedOnUserKeys,loggedOnUserMisc,findFreeSlot()) @@ -27711,7 +27286,6 @@ ENDPROC PROC findFreeSlot() DEF slot, stat, fh - DEF tempStr[255]:STRING fh:=Open(userDataFile,MODE_OLDFILE) IF(fh=0) THEN RETURN 1 @@ -27776,36 +27350,87 @@ PROC closezModemStats() IF(windowZmodem<>NIL) THEN CloseWindow(windowZmodem) windowZmodem:=NIL + wantzwin:=FALSE ENDPROC PROC openZmodemStat() DEF tags,tags2,vi DEF tempstr[255]:STRING + DEF pubScreen[255]:STRING + DEF pubLock=0 + DEF pub=FALSE + + wantzwin:=TRUE - IF zModemInfo.currentOperation=ZMODEM_DOWNLOAD - StringF(tempstr,'[Node \d] Send Window (??/??)',node) - strCpy(zModemInfo.titleBar,tempstr,ALL) + IF netMailTransfer + IF zModemInfo.currentOperation=ZMODEM_DOWNLOAD + StringF(tempstr,'[Node \d] NetMail Send Window',node) + strCpy(zModemInfo.titleBar,tempstr,ALL) + ELSE + StringF(tempstr,'[Node \d] NetMail Receive Window',node) + strCpy(zModemInfo.titleBar,tempstr,ALL) + ENDIF ELSE - StringF(tempstr,'[Node \d] Receive Window (??/??)',node) - strCpy(zModemInfo.titleBar,tempstr,ALL) + IF zModemInfo.currentOperation=ZMODEM_DOWNLOAD + StringF(tempstr,'[Node \d] Send Window (??/??)',node) + strCpy(zModemInfo.titleBar,tempstr,ALL) + ELSE + StringF(tempstr,'[Node \d] Receive Window (??/??)',node) + strCpy(zModemInfo.titleBar,tempstr,ALL) + ENDIF ENDIF - tags:=NEW [WA_CLOSEGADGET,1, - WA_CUSTOMSCREEN,screen, - WA_SIZEGADGET,1, - WA_DRAGBAR,1, - WA_LEFT,170, - WA_TOP,45, - WA_WIDTH,350, - WA_HEIGHT,150, - WA_DETAILPEN,0, - WA_BLOCKPEN,7, - WA_TITLE, - zModemInfo.titleBar, - WA_IDCMP,IDCMP_CLOSEWINDOW, - WA_FLAGS,WFLG_ACTIVATE,NIL] - IF (windowZmodem=NIL) AND (screen<>NIL) + IF bitPlanes=0 + pub:=TRUE + ENDIF + + IF readToolType(TOOLTYPE_WINDOW,node,'WINDOW.PUBSCREEN',pubScreen) + pub:=TRUE + ENDIF + + IF pub + IF StrLen(pubScreen)>0 + pubLock:=LockPubScreen(pubScreen) + ELSE + pubLock:=LockPubScreen(NIL) + ENDIF + IF pubLock=FALSE THEN pub:=FALSE + ENDIF + + IF pub + tags:=NEW [WA_CLOSEGADGET,1, + WA_PUBSCREEN,pubLock, + WA_SIZEGADGET,1, + WA_DRAGBAR,1, + WA_LEFT,(window.width-350/2)+window.leftedge, + WA_TOP,(window.height-150/2)+window.topedge, + WA_WIDTH,350, + WA_HEIGHT,150, + WA_DETAILPEN,0, + WA_BLOCKPEN,7, + WA_TITLE, + zModemInfo.titleBar, + WA_IDCMP,IDCMP_CLOSEWINDOW, + WA_FLAGS,WFLG_ACTIVATE,NIL] + ELSE + tags:=NEW [WA_CLOSEGADGET,1, + WA_CUSTOMSCREEN,screen, + WA_SIZEGADGET,1, + WA_DRAGBAR,1, + WA_LEFT,(screen.width-350)/2, + WA_TOP,(screen.height-150)/2, + WA_WIDTH,350, + WA_HEIGHT,150, + WA_DETAILPEN,0, + WA_BLOCKPEN,7, + WA_TITLE, + zModemInfo.titleBar, + WA_IDCMP,IDCMP_CLOSEWINDOW, + WA_FLAGS,WFLG_ACTIVATE,NIL] + ENDIF + IF (windowZmodem=NIL) AND (scropen) windowZmodem:=OpenWindowTagList(NIL,tags) + IF pubLock THEN UnlockPubScreen(NIL,pubLock) initZmodemStatCon() IF (KickVersion(40) AND (bitPlanes>2)) THEN zmodemStatPrint('[ s') zmodemStatPrint('[0 p\n FileName:\n FileSize: 0\n ETA Time:\n Cur Time:\n Position: 0\n Complete: 0%\n LastTime:\n CPS: 0\n\n Z Status: Starting\n Errors: 0\n ErrorPos: 0') @@ -27825,7 +27450,7 @@ PROC openZmodemStat() ENDPROC PROC openExpressScreen() - DEF width,height,top,left,dispId,colourcount + DEF width,height,top,left,dispId DEF pubScreen[255]:STRING DEF penstr[12]:STRING DEF debugstr[255]:STRING @@ -27837,6 +27462,17 @@ PROC openExpressScreen() IF scropen THEN RETURN + top:=sopt.topEdge + left:=sopt.leftEdge + width:=sopt.width + height:=sopt.height + bitPlanes:=sopt.bitPlanes + + IF bitPlanes=0 + StrCopy(pubScreen,'') + pub:=TRUE + ENDIF + IF readToolType(TOOLTYPE_WINDOW,node,'WINDOW.PUBSCREEN',pubScreen) pub:=TRUE ENDIF @@ -27855,37 +27491,6 @@ PROC openExpressScreen() dStatBar:=FALSE ->IF (checkToolTypeExists(TOOLTYPE_WINDOW,node,'WINDOW.STATBAR')) THEN toggleStatusDisplay() - /*width:=readToolTypeInt(TOOLTYPE_WINDOW,node,'WINDOW.WIDTH') - IF width=<1 THEN width:=640 - - height:=readToolTypeInt(TOOLTYPE_WINDOW,node,'WINDOW.HEIGHT') - IF height<1 THEN height:=256 - - top:=readToolTypeInt(TOOLTYPE_WINDOW,node,'WINDOW.TOPEDGE') - IF top<12 THEN top:=12 - - left:=readToolTypeInt(TOOLTYPE_WINDOW,node,'WINDOW.LEFTEDGE') - IF left<0 THEN left:=0 - - colourcount:=readToolTypeInt(TOOLTYPE_WINDOW,node,'WINDOW.NUM_COLORS') - SELECT colourcount - CASE 2 - bitPlanes:=1 - CASE 4 - bitPlanes:=2 - CASE 8 - bitPlanes:=3 - CASE 16 - bitPlanes:=4 - DEFAULT - bitPlanes:=3 - ENDSELECT*/ - top:=sopt.topEdge - left:=sopt.leftEdge - width:=sopt.width - height:=sopt.height - bitPlanes:=sopt.bitPlanes - IF fontHandle=NIL readToolType(TOOLTYPE_NODE,node,'EXPFONT',fontName) defaultfontattr.name:=fontName @@ -27897,18 +27502,63 @@ PROC openExpressScreen() IF pub=FALSE IF screen=NIL - IF (bitPlanes<3) OR (KickVersion(40)=FALSE) + ->colour 1 = white, colour 7 = red pens:=NEW [0,1,1,1,6,4,1,0,4,1,4,1,-1]:INT - cols:=NEW [0,0,0,0,1,15,15,15,2,0,15,0,3,15,15,0,4,0,0,15,5,15,0,15,6,0,15,15,7,15,0,0,-1,0,0,0]:INT + IF (bitPlanes>3) + cols:=NEW [0,0,0,0, + 1,12,12,12, + 2,0,12,0, + 3,12,12,0, + 4,0,0,12, + 5,12,0,12, + 6,0,12,12, + 7,12,0,0, + 8,5,5,5, + 9,15,15,15, + 10,0,15,0, + 11,15,15,0, + 12,0,0,15, + 13,15,0,15, + 14,0,15,15, + 15,15,0,0, + -1,0,0,0]:INT + ELSE + cols:=NEW [0,0,0,0,1,15,15,15,2,0,15,0,3,15,15,0,4,0,0,15,5,15,0,15,6,0,15,15,7,15,0,0,-1,0,0,0]:INT + ENDIF + ELSE + ->colour 1 = red, colour 7 = white pens:=NEW [0,7,7,7,6,4,7,0,4,7,4,7,-1]:INT - cols:=NEW [0,0,0,0,1,15,0,0,2,0,15,0,3,15,15,0,4,0,0,15,5,15,0,15,6,0,15,15,7,15,15,15,-1,0,0,0]:INT + IF (bitPlanes>3) + cols:=NEW [0,0,0,0, + 1,12,0,0, + 2,0,12,0, + 3,12,12,0, + 4,0,0,12, + 5,12,0,12, + 6,0,12,12, + 7,12,12,12, + 8,5,5,5, + 9,15,0,0, + 10,0,15,0, + 11,15,15,0, + 12,0,0,15, + 13,15,0,15, + 14,0,15,15, + 15,15,15,15, + -1,0,0,0]:INT + ELSE + cols:=NEW [0,0,0,0,1,15,0,0,2,0,15,0,3,15,15,0,4,0,0,15,5,15,0,15,6,0,15,15,7,15,15,15,-1,0,0,0]:INT + ENDIF ENDIF - + IF readToolType(TOOLTYPE_NODE,node,'SCREENPENS',penstr) FOR temp:=0 TO StrLen(penstr)-1 IF (penstr[temp]>="0") AND (penstr[temp]<="7") THEN pens[temp]:=penstr[temp]-"0" + IF (penstr[temp]>="A") AND (penstr[temp]<="F") THEN pens[temp]:=penstr[temp]-"A"+10 + IF (penstr[temp]>="a") AND (penstr[temp]<="f") THEN pens[temp]:=penstr[temp]-"a"+10 + ENDFOR ENDIF @@ -27944,7 +27594,7 @@ PROC openExpressScreen() WA_TOP,0, WA_LEFT,0, WA_WIDTH,18, - WA_HEIGHT,12, + WA_HEIGHT,screen.wbortop+screen.font.ysize+1, ->WA_DETAILPEN,0, ->WA_BLOCKPEN,blockpen, WA_IDCMP,IDCMP_CLOSEWINDOW,NIL] @@ -27979,10 +27629,10 @@ PROC openExpressScreen() IF (window) AND (fontHandle<>NIL) THEN SetFont(window.rport,fontHandle) ELSE opentags:=NEW [WA_BORDERLESS,1,WA_CUSTOMSCREEN,screen, - WA_TOP,top+12, + WA_TOP,top+screen.wbortop+screen.font.ysize+1, WA_LEFT,left, WA_WIDTH,width, - WA_HEIGHT,height-12, + WA_HEIGHT,height-(screen.wbortop+screen.font.ysize+1), ->WA_DETAILPEN,0, ->WA_BLOCKPEN,blockpen, WA_FLAGS,WFLG_ACTIVATE,NIL] @@ -28040,7 +27690,7 @@ PROC openExpressScreen() DoIO(consoleReadIO) ENDIF - queueRead(consoleReadIO, {ibuf}) -> Send the first console read request + queueConsoleRead({ibuf}) -> Send the first console read request scropen:=TRUE IF (KickVersion(40)) AND (bitPlanes>2) conPuts('[ s',-1,TRUE) @@ -28048,6 +27698,8 @@ PROC openExpressScreen() conPuts('[0 p',-1,TRUE) statPrintUser(loggedOnUser,loggedOnUserKeys,loggedOnUserMisc) + IF (wantzwin) AND (window<>NIL) THEN openZmodemStat() + IF((sopt.statBar<>FALSE) AND (pub=FALSE)) THEN toggleStatusDisplay() ENDPROC ERR_NONE @@ -28134,7 +27786,7 @@ ENDPROC (telnetSocket>=0) AND (offHookFlag=FALSE) PROC checkTelnetData() DEF count - DEF buf[1]:STRING + ->DEF buf[1]:STRING IF telnetSocket=-1 THEN RETURN FALSE @@ -28153,6 +27805,29 @@ PROC setSingleFDS(socketVal) fds[n]:=fds[n] OR (Shl(1,socketVal AND 31)) ENDPROC +PROC updateVersion(expVer:PTR TO CHAR,expDate:PTR TO CHAR) + DEF v,p + DEF y,m,d + DEF tmp[4]:STRING + + v:=getBuild() + p:=InStr(v,' ') + IF p>=0 + StrCopy(expVer,v,p) + v:=v+p+1 + StrCopy(tmp,v,4) + y:=Val(tmp) + StrCopy(tmp,v+4,2) + m:=Val(tmp) + StrCopy(tmp,v+6,2) + d:=Val(tmp) + StringF(expDate,'\z\r\d[2]-\s[3]-\d[4]',d,'JanFebMarAprMayJunJulAugSepOctNovDec'+((m-1)*3),y) + ELSE + StrCopy(expVer,v,ALL) + StrCopy(expDate,'',ALL) + ENDIF +ENDPROC + PROC main() HANDLE DEF temppath[255]:STRING DEF tempstr[255]:STRING @@ -28165,11 +27840,15 @@ PROC main() HANDLE DEF oldWinPtr DEF proc: PTR TO process - StrCopy(expressVer,'v5.2.4',ALL) - StrCopy(expressDate,'13-Apr-2020',ALL) + updateVersion(expressVer,expressDate) nodeStart:=getSystemTime() + ->initialise random seed from scanline position and node start time + p:=$dff006 + i:=Eor(Shl(p[0],8)+p[0],nodeStart) AND $FFFF + Rnd((Shl(i,16)+i) OR $80000000) + InitSemaphore(bgData) ->set windowptr to -1 to prevent any AmigaDOS insert volume dialogs @@ -28215,6 +27894,10 @@ PROC main() HANDLE stripAnsi(0,0,1,0) + zmodemBuffer:=New(zModemBufferSize) + + cmds:=NEW cmds + securityNames:=[ 'ACS.ACCOUNT_EDITING','ACS.READ_BULLETINS','ACS.COMMENT_TO_SYSOP','ACS.DOWNLOAD','ACS.UPLOAD','ACS.ENTER_MESSAGE','ACS.FILE_LISTINGS','ACS.JOIN_CONFERENCE','ACS.NEW_FILES_SINCE', 'ACS.PAGE_SYSOP','ACS.READ_MESSAGE','ACS.REMOTE_SHELL','ACS.DISPLAY_USER_STATS','ACS.VIEW_A_FILE','ACS.EDIT_USER_INFO','ACS.EDIT_INTERNET_NAME','ACS.EDIT_USER_LOCATION', @@ -28224,7 +27907,7 @@ PROC main() HANDLE 'ACS.CUSTOMCOMMANDS','ACS.JOIN_SUB_CONFERENCE','ACS.ZOOM_MAIL','ACS.MCI_MESSAGE','ACS.EDIT_DIRS','ACS.EDIT_FILES','ACS.BREAK_CHAT','ACS.QUIET_NODE','ACS.SYSOP_COMMANDS','ACS.WHO_IS_ONLINE', 'ACS.RELOGON','ACS.ULSTATS','ACS.XPR_RECEIVE','ACS.XPR_SEND','ACS.WILDCARDS','ACS.CONFERENCE_ACCOUNTING','ACS.PRI_MSGFILES','ACS.PUB_MSGFILES','ACS.FULL_EDIT','ACS.CONFFLAGS', 'ACS.OLM','ACS.HIDE_FILES','ACS.SHOW_PAYMENTS','ACS.CREDIT_ACCESS','ACS.VOTE','ACS.MODIFY_VOTE','ACS.FILE_EXPANSION','ACS.EDIT_REAL_NAME','ACS.EDIT_USER_NAME','ACS.CENSORED', - 'ACS.ACCOUNT_VIEW','ACS.TRANSLATION','ACS.UNKNOWN','ACS.CREATE_CONFERENCE','ACS.LOCAL_DOWNLOADS','ACS.MAX_PAGES','ACS.OVERRIDE_DEFAULTS','ACS.HOLD_ACCESS'] + 'ACS.ACCOUNT_VIEW','ACS.TRANSLATION','ACS.UNKNOWN','ACS.CREATE_CONFERENCE','ACS.LOCAL_DOWNLOADS','ACS.MAX_PAGES','ACS.OVERRIDE_DEFAULTS','ACS.HOLD_ACCESS','ACS.EDIT_EMAIL'] StringF(tempstr,'AmiExpress_Node.\d',node) @@ -28233,6 +27916,8 @@ PROC main() HANDLE Raise(ERR_ALREADYRUNNING) ENDIF + mailOptions:=NEW mailOptions + IF (iconbase:=OpenLibrary('icon.library',33))=NIL THEN Raise(ERR_NOICON) IF (diskfontbase:=OpenLibrary('diskfont.library', 37))=NIL THEN Raise(ERR_NO_DISKFONT) @@ -28241,6 +27926,8 @@ PROC main() HANDLE recFileNames:=NEW recFileNames.stringlist() + attachedFiles:=NEW attachedFiles.stringlist(5) + historyBuf:=NEW historyBuf.stringlist(20) historyNum:=0 historyCycle:=0 @@ -28339,7 +28026,7 @@ PROC main() HANDLE IF checkToolTypeExists(TOOLTYPE_NODE,node,'TELSERD') ringCount:=2; strCpy(cmds.mInit,'',ALL) - strCpy(cmds.mReset,'+++ATH0S0=1+CID=3\b',ALL) + strCpy(cmds.mReset,'+++~ATH0S0=1+CID=3\b',ALL) strCpy(cmds.mRing,'RING',ALL) strCpy(cmds.mAnswer,'ATA',ALL) strCpy(sopt.offHook,'',ALL) @@ -28515,8 +28202,28 @@ PROC main() HANDLE StrCopy(consoleInputDeviceName,'console.device') readToolType(TOOLTYPE_NODE,node,'CONSOLE_INPUT_DEVICE',consoleInputDeviceName) - confBases:=NEW confBases.stdlist(cmds.numConf) + confNames:=NEW confNames.stringlist(cmds.numConf) + confDirs:=NEW confDirs.stringlist(cmds.numConf) FOR i:=1 TO cmds.numConf + StringF(tempstr,'NAME.\d',i) + readToolType(TOOLTYPE_CONFCONFIG,'',tempstr,tempstr2) + confNames.add(tempstr2) + IF i<11 + p:=cmds.conf1Name + strCpy(p+((i-1)*54),tempstr2,54) + ENDIF + + StringF(tempstr,'LOCATION.\d',i) + readToolType(TOOLTYPE_CONFCONFIG,'',tempstr,tempstr2) + confDirs.add(tempstr2) + IF i<11 + p:=cmds.conf1Loc + strCpy(p+((i-1)*54),tempstr2,54) + ENDIF + ENDFOR + + confBases:=NEW confBases.stdlist(countMsgBases()) + FOR i:=1 TO confBases.maxSize() cb:=NEW cb confBases.add(cb) ENDFOR @@ -28598,26 +28305,6 @@ PROC main() HANDLE autoDeactivateDays:=readToolTypeInt(TOOLTYPE_BBSCONFIG,'','AUTO_DEACTIVATE_DAYS') - confNames:=NEW confNames.stringlist(cmds.numConf) - confDirs:=NEW confDirs.stringlist(cmds.numConf) - FOR i:=1 TO cmds.numConf - StringF(tempstr,'NAME.\d',i) - readToolType(TOOLTYPE_CONFCONFIG,'',tempstr,tempstr2) - confNames.add(tempstr2) - IF i<11 - p:=cmds.conf1Name - strCpy(p+((i-1)*54),tempstr2,54) - ENDIF - - StringF(tempstr,'LOCATION.\d',i) - readToolType(TOOLTYPE_CONFCONFIG,'',tempstr,tempstr2) - confDirs.add(tempstr2) - IF i<11 - p:=cmds.conf1Loc - strCpy(p+((i-1)*54),tempstr2,54) - ENDIF - ENDFOR - computerEntries:=readToolTypeInt(TOOLTYPE_COMPUTERLIST,'','COMPUTER.NUM') onlineBaud:=cmds.openingBaud @@ -28726,6 +28413,8 @@ PROC main() HANDLE unloadTranslators() + END attachedFiles + END scomment END parsedParams END computerTypes @@ -28757,6 +28446,8 @@ PROC main() HANDLE END skipdFiles + END cmds + IF (loggedOnUser) THEN END loggedOnUser IF (loggedOnUserKeys) THEN END loggedOnUserKeys IF (loggedOnUserMisc) THEN END loggedOnUserMisc @@ -28768,7 +28459,8 @@ PROC main() HANDLE IF(tempUserMisc) THEN END tempUserMisc cleanupssl() - + END mailOptions + closeExpressScreen() IF iconbase THEN CloseLibrary(iconbase) IF diskfontbase THEN CloseLibrary(diskfontbase) @@ -28794,6 +28486,8 @@ PROC main() HANDLE closeSerial() + Dispose(zmodemBuffer) + IF (doorExtSig<>NIL) THEN FreeSignal(doorExtSig) doorExtSig:=NIL @@ -28823,6 +28517,12 @@ PROC main() HANDLE debugLog(LOG_ERROR,tempstr) CASE ERR_FDSRANGE debugLog(LOG_ERROR,'FDS Range error') + CASE "NIL" + StringF(tempstr,'NIL pointer error at line \d',exceptioninfo) + debugLog(LOG_ERROR,tempstr) + DEFAULT + StringF(tempstr,'Unknown exception \d',exception) + debugLog(LOG_ERROR,tempstr) ENDSELECT ENDPROC @@ -28923,4 +28623,4 @@ threadtasksA4: regA4: LONG NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL - LONG NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL \ No newline at end of file + LONG NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL diff --git a/ftn.cfg b/ftn.cfg new file mode 100644 index 0000000..231a1c0 --- /dev/null +++ b/ftn.cfg @@ -0,0 +1,31 @@ +[MAIN] +MODE=BOTH +INBOUND=mail:inbound/ +INBOUNDINSEC=mail:inbound/ +OUTBOUND=mail:outbound/ +UNPACKCMD=lha x {filename} t:ftn/ +TEMPDIR=t:ftn/ + +[ORIGINNET] +ZONE= +NET= +NODE= +POINT= + +[DESTNET] +ZONE= +NET= +NODE= +POINT= + +[MISC] +PASSWORD= +TEAR=/X Tosser +ORIGIN=Phantasm BBS development system +COST=0 +ATTR=0 +TZOFFSET=0000 + +[CONFS] +TEST_AMY +bbs:Conf05/MsgBase.23/ diff --git a/ftn.e b/ftn.e new file mode 100644 index 0000000..f3a925e --- /dev/null +++ b/ftn.e @@ -0,0 +1,1002 @@ + + MODULE 'dos/dos','dos/dostags','dos/datetime' + MODULE '*stringlist' + + DEF confNames=NIL:PTR TO stringlist + DEF msgBasePaths=NIL:PTR TO stringlist + + ENUM ERR_NOCFG,ERR_WRITE_MAILSTAT,ERR_READ_MESSAGES_DAT,ERR_READ_MAILSTAT,ERR_READ_HEADERFILE + + CONST RESULT_SUCCESS=-1,RESULT_FAILURE=0 + +OBJECT ftnHeader + msgdate[21]:ARRAY OF CHAR + to[37]:ARRAY OF CHAR + from[37]:ARRAY OF CHAR + subject[73]:ARRAY OF CHAR + confId[255]:ARRAY OF CHAR +ENDOBJECT + +OBJECT mailStat + lowestKey : LONG + highMsgNum : LONG + lowestNotDel : LONG + pad[6]:ARRAY OF CHAR +ENDOBJECT + +OBJECT mailHeader + status: CHAR + msgNumb: LONG + toName[31]: ARRAY OF CHAR + fromName[31]: ARRAY OF CHAR + subject[31]: ARRAY OF CHAR + msgDate: LONG + recv: LONG + pad: CHAR +ENDOBJECT + +PROC exec(fileName:PTR TO CHAR) + DEF tags,r + tags:=NEW [SYS_INPUT,0,SYS_OUTPUT,0,SYS_ASYNCH,FALSE,NIL]:LONG + r:=SystemTagList(fileName,tags) + IF r=-1 + WriteF('Error executing \s\n\n',fileName) + ENDIF + END tags +ENDPROC r + +PROC replacestr(sourcestring,searchtext,replacetext) + DEF newstring,tempstring,oldpos, pos,len + newstring:=String(255) + tempstring:=String(255) + len:=StrLen(searchtext) /* not estrlen since this is likely to be a hard coded constant */ + pos:=InStr(sourcestring,searchtext) + IF pos<>-1 + oldpos:=0 + WHILE pos<>-1 + IF pos<>oldpos + MidStr(tempstring,sourcestring,oldpos,pos-oldpos) + StrAdd(newstring,tempstring) + ENDIF + StrAdd(newstring,replacetext) + pos:=pos+len + oldpos:=pos + pos:=InStr(sourcestring,searchtext,oldpos) + ENDWHILE + pos:=EstrLen(sourcestring) + IF pos<>oldpos + MidStr(tempstring,sourcestring,oldpos,pos-oldpos) + StrAdd(newstring,tempstring) + ENDIF + StrCopy(sourcestring,newstring) + ENDIF + DisposeLink(newstring) + DisposeLink(tempstring) +ENDPROC + +PROC trimRight(src:PTR TO CHAR,dest:PTR TO CHAR) + DEF n,v=0 + StrCopy(dest,src) + n:=EstrLen(dest) + IF n>0 THEN v:=dest[n-1] + WHILE (n>0) AND (v=" ") + SetStr(dest,n-1) + n:=EstrLen(dest) + IF n>0 THEN v:=dest[n-1] + ENDWHILE +ENDPROC + +PROC fillStrCopy(src:PTR TO CHAR,dest:PTR TO CHAR,len) + DEF i + FOR i:=0 TO len-1 + dest[i]:=0 + ENDFOR + AstrCopy(dest,src,len) +ENDPROC + +PROC saveMh(fh,mailHeader) + DEF result + + result:=Write(fh,mailHeader,1) -> STATUS + result:=result+Write(fh,mailHeader+110,1) ->PAD + result:=result+Write(fh,mailHeader+2,4) ->MsgNum + result:=result+Write(fh,mailHeader+6,31) ->toName + result:=result+Write(fh,mailHeader+38,31) ->fromName + result:=result+Write(fh,mailHeader+70,31) ->subject + result:=result+Write(fh,mailHeader+110,1) ->PAD + result:=result+Write(fh,mailHeader+102,9) ->msgdate, recv & pad + result:=result+Write(fh,mailHeader+110,1) ->PAD +ENDPROC result + +PROC getMsgBasePath(confName,msgBasePath:PTR TO CHAR) + DEF i + FOR i:=0 TO confNames.count()-1 + IF StrCmp(confNames.item(i),confName) + StrCopy(msgBasePath,msgBasePaths.item(i),ALL) + ENDIF + ENDFOR +ENDPROC + +PROC createMessagePacket(originNode,destNode,originNet,destNet,originZone,destZone,originPoint,destPoint,attr,cost,packetPass:PTR TO CHAR,msgPktFileHandle, srcFilename:PTR TO CHAR,confId:PTR TO CHAR,tearLine:PTR TO CHAR, originLine:PTR TO CHAR,tzOffset:PTR TO CHAR) + DEF fh2 + DEF tempStr[255]:STRING + DEF fromName[255]:STRING + DEF toName[255]:STRING + DEF subject[255]:STRING + DEF msgDateTime[255]:STRING + DEF msgbuf:PTR TO CHAR, msgsz + DEF mhdr[14]:ARRAY OF CHAR + DEF null[1]:ARRAY OF CHAR + DEF phdr[58]:ARRAY OF CHAR + DEF status,p,i + DEF year,month,day,hour,minute,second + DEF monthCodes[40]:STRING + DEF msgId[10]:STRING + DEF originStr[100]:STRING + + IF originPoint<>0 + StringF(originStr,'\d:\d/\d.\d',originZone,originNet,originNode,originPoint) + ELSE + StringF(originStr,'\d:\d/\d',originZone,originNet,originNode) + ENDIF + + formatLongDateTime2(getSystemTime(),msgDateTime,",") + StrCopy(tempStr,msgDateTime,2) + month:=Val(tempStr) + StrCopy(tempStr,msgDateTime+3,2) + day:=Val(tempStr) + StrCopy(tempStr,msgDateTime+6,2) + year:=Val(tempStr) + IF year<38 THEN year:=year+2000 ELSE year:=year+1900 + StrCopy(tempStr,msgDateTime+9,2) + hour:=Val(tempStr) + StrCopy(tempStr,msgDateTime+12,2) + minute:=Val(tempStr) + StrCopy(tempStr,msgDateTime+15,2) + second:=Val(tempStr) + + IF msgPktFileHandle>0 + IF Seek(msgPktFileHandle,0,OFFSET_CURRENT)=0 + + ->create packet header + phdr[0]:=originNode AND 255 + phdr[1]:=Shr(originNode,8) AND 255 + phdr[2]:=destNode AND 255 + phdr[3]:=Shr(destNode,8) AND 255 + phdr[4]:=year AND 255 + phdr[5]:=Shr(year,8) AND 255 + phdr[6]:=month AND 255 + phdr[7]:=Shr(month,8) AND 255 + phdr[8]:=day AND 255 + phdr[9]:=Shr(day,8) AND 255 + phdr[10]:=hour AND 255 + phdr[11]:=Shr(hour,8) AND 255 + phdr[12]:=minute AND 255 + phdr[13]:=Shr(minute,8) AND 255 + phdr[14]:=second AND 255 + phdr[15]:=Shr(second,8) AND 255 + phdr[16]:=0 ->baud low + phdr[17]:=0 ->baud hi + phdr[18]:=2 ->type + phdr[19]:=0 ->type + phdr[20]:=originNet AND 255 + phdr[21]:=Shr(originNet,8) AND 255 + phdr[22]:=destNet AND 255 + phdr[23]:=Shr(destNet,8) AND 255 + phdr[24]:=0 ->prodCode + phdr[25]:=1 ->prodVersionMajor + phdr[26]:=0;phdr[27]:=0;phdr[28]:=0;phdr[29]:=0; ->password + phdr[30]:=0;phdr[31]:=0;phdr[32]:=0;phdr[33]:=0; ->password + AstrCopy(phdr+26,packetPass,9) + phdr[34]:=originZone AND 255 + phdr[35]:=Shr(originZone,8) AND 255 + phdr[36]:=destZone AND 255 + phdr[37]:=Shr(destZone,8) AND 255 + phdr[38]:=0 ->reserved + phdr[39]:=0 ->reserved + phdr[40]:=0 ->capvalid + phdr[41]:=1 ->capvalid + phdr[42]:=1 ->prodcodehi + phdr[43]:=0 ->prodversionminor + phdr[44]:=1 ->capword + phdr[45]:=0 ->capword + phdr[46]:=originZone AND 255 + phdr[47]:=Shr(originZone,8) AND 255 + phdr[48]:=destZone AND 255 + phdr[49]:=Shr(destZone,8) AND 255 + phdr[50]:=originPoint AND 255 + phdr[51]:=Shr(originPoint,8) AND 255 + phdr[52]:=destPoint AND 255 + phdr[53]:=Shr(destPoint,8) AND 255 + phdr[54]:=0 + phdr[55]:=0 + phdr[56]:=0 + phdr[57]:=0 + + ->write packet header + Write(msgPktFileHandle,phdr,58) + ENDIF + + fh2:=Open(srcFilename,MODE_OLDFILE) + IF fh2>0 + + ReadStr(fh2,fromName) + IF EstrLen(fromName)>35 THEN SetStr(fromName,35) + ReadStr(fh2,toName) + IF EstrLen(toName)>35 THEN SetStr(toName,35) + ReadStr(fh2,subject) + IF EstrLen(subject)>71 THEN SetStr(toName,71) + ReadStr(fh2,msgDateTime) + ReadStr(fh2,msgId) + + p:=Seek(fh2,0,OFFSET_END) + msgsz:=Seek(fh2,p,OFFSET_BEGINNING)-p + + msgbuf:=New(msgsz) + Read(fh2,msgbuf,msgsz) + Close(fh2) + + status:=" " + + ->write message header + mhdr[0]:=2 + mhdr[1]:=0 + mhdr[2]:=originNode AND 255 + mhdr[3]:=Shr(originNode,8) AND 255 + mhdr[4]:=destNode AND 255 + mhdr[5]:=Shr(destNode,8) AND 255 + mhdr[6]:=originNet AND 255 + mhdr[7]:=Shr(originNet,8) AND 255 + mhdr[8]:=destNet AND 255 + mhdr[9]:=Shr(destNet,8) AND 255 + mhdr[10]:=attr AND 255 + mhdr[11]:=Shr(attr,8) AND 255 + mhdr[12]:=cost AND 255 + mhdr[13]:=Shr(cost,8) AND 255 + Write(msgPktFileHandle,mhdr,14) + + null[0]:=0 + + StrCopy(monthCodes,'JanFebMarAprMayJunJulAugSepOctNovDec') + StrCopy(tempStr,msgDateTime,2) + month:=Val(tempStr)-1 + + StringF(tempStr,'\s[2] \s[3] \s[2] \s[2]:\s[2]:\s[2]',msgDateTime+3,monthCodes+(month*3),msgDateTime+6,msgDateTime+9,msgDateTime+12,msgDateTime+15) + Write(msgPktFileHandle,tempStr,19) + Write(msgPktFileHandle,null,1) + + Write(msgPktFileHandle,toName,EstrLen(toName)) + Write(msgPktFileHandle,null,1) + + Write(msgPktFileHandle,fromName,EstrLen(fromName)) + Write(msgPktFileHandle,null,1) + + Write(msgPktFileHandle,subject,EstrLen(subject)) + Write(msgPktFileHandle,null,1) + + StringF(tempStr,'AREA:\s\b',confId) + Write(msgPktFileHandle,tempStr,EstrLen(tempStr)) + + StringF(tempStr,'\cCHRS: LATIN-1 2\b',1) + Write(msgPktFileHandle,tempStr,EstrLen(tempStr)) + + IF StrLen(msgId)>0 + StringF(tempStr,'\cMSGID: \s \z\h[8]\b',1,originStr,Val(msgId)) + Write(msgPktFileHandle,tempStr,EstrLen(tempStr)) + ENDIF + + StringF(tempStr,'\cTZUTC: \s\b',1,IF StrLen(tzOffset)=0 THEN '0000' ELSE tzOffset) + Write(msgPktFileHandle,tempStr,EstrLen(tempStr)) + + FOR i:=0 TO msgsz-1 + IF msgbuf[i]=10 THEN msgbuf[i]:=13 + ENDFOR + + ->write tear line + StringF(tempStr,'--- \s\b',tearLine) + Write(msgPktFileHandle,tempStr,EstrLen(tempStr)) + + ->write origin line + StringF(tempStr,' * Origin: \s (\s)\b',originLine,originStr) + Write(msgPktFileHandle,tempStr,EstrLen(tempStr)) + + ->write seen by line + StringF(tempStr,'SEEN-BY: \d/\d \d/\d\b',originNet,originNode,destNet,destNode) + Write(msgPktFileHandle,tempStr,EstrLen(tempStr)) + + StringF(tempStr,'\cPATH: \d/\d\b',1,originNet,originNode) + Write(msgPktFileHandle,tempStr,EstrLen(tempStr)) + + ->nul terminate + StrCopy(tempStr,'') + Write(msgPktFileHandle,tempStr,1) + + Dispose(msgbuf) + ENDIF + ENDIF +ENDPROC + +PROC createMessagesBundle(originNode,destNode,originNet,destNet,originZone,destZone,originPoint,destPoint,attr,cost,packetPass,msgFilename:PTR TO CHAR,tearLine:PTR TO CHAR, originLine:PTR TO CHAR,tzOffset:PTR TO CHAR) + DEF i,fh=0 + DEF msgOutPath[255]:STRING + DEF fBlock:PTR TO fileinfoblock + DEF fLock + DEF msgFile[255]:STRING + DEF null[2]:ARRAY OF CHAR + + IF(fBlock:=AllocDosObject(DOS_FIB,NIL)) + FOR i:=0 TO msgBasePaths.count()-1 + StringF(msgOutPath,'\sEXT-OUT',msgBasePaths.item(i)) + IF(fLock:=Lock(msgOutPath,ACCESS_READ)) + IF(Examine(fLock,fBlock)) + WHILE(ExNext(fLock,fBlock)) + StringF(msgFile,'\s/\s',msgOutPath,fBlock.filename) + + IF fh=0 + fh:=Open(msgFilename,MODE_READWRITE) + IF fh>0 THEN Seek(fh,-2,OFFSET_END) + ENDIF + + IF fh>0 + createMessagePacket(originNode,destNode,originNet,destNet,originZone,destZone,originPoint,destPoint,attr,cost,packetPass,fh,msgFile,confNames.item(i),tearLine,originLine,tzOffset) + SetProtection(msgFile,FIBF_OTR_DELETE) + DeleteFile(msgFile) + ENDIF + ENDWHILE + ENDIF + UnLock(fLock) + + ENDIF + ENDFOR + FreeDosObject(DOS_FIB,fBlock) + ENDIF + + IF fh>0 + null[0]:=0 + null[1]:=0 + Write(fh,null,2) + Close(fh) + ENDIF +ENDPROC + +PROC fileWriteLn(fh,str: PTR TO CHAR) + DEF stat + IF (stat:=fileWrite(fh,str))<>RESULT_SUCCESS THEN RETURN stat +ENDPROC fileWrite(fh,'\n') + +PROC fileWrite(fh,str: PTR TO CHAR) + DEF s + + s:=Write(fh,str,StrLen(str)) + IF s<>StrLen(str) THEN RETURN RESULT_FAILURE +ENDPROC RESULT_SUCCESS + +PROC formatLongDateTime2(cDateVal,outDateStr,seperatorChar) + DEF d : PTR TO datestamp + DEF dt : datetime + DEF datestr[10]:STRING + DEF timestr[10]:STRING + DEF r,dateVal + + dateVal:=cDateVal-21600 + + d:=dt.stamp + d.tick:=(dateVal-Mul(Div(dateVal,60),60)) + d.tick:=Mul(d.tick,50) + dateVal:=Div(dateVal,60) + d.days:=Div((dateVal),1440)-2922 ->-2922 days between 1/1/70 and 1/1/78 + d.minute:=dateVal-(Mul(d.days+2922,1440)) + + dt.format:=FORMAT_USA + dt.flags:=0 + dt.strday:=0 + dt.strdate:=datestr + dt.strtime:=timestr + + IF DateToStr(dt) + StringF(outDateStr,'\s\c\s',datestr,seperatorChar,timestr) + RETURN TRUE + ENDIF +ENDPROC FALSE + +->returns system time converted to c time format +PROC getSystemTime() + DEF currDate: datestamp + DEF startds:PTR TO datestamp + DEF s1,s2,s3,s4 + + startds:=DateStamp(currDate) + + s1:=startds.days+2922 + s1:=Mul(1440,s1) + s1:=Mul(60,s1) + s2:=Mul(60,startds.minute) + s3:=startds.tick/50 + s4:=Mul(Mul(startds.days+2922,1440),60)+(startds.minute*60)+(startds.tick/50) + + ->2922 days between 1/1/70 and 1/1/78 + +ENDPROC s4+21600 + +PROC getEncodedDate(dateStr:PTR TO CHAR) + DEF dt:datetime + DEF tempStr[30]:STRING + DEF strDate[20]:STRING + DEF strTime[20]:STRING + DEF dval + + + StrCopy(strDate,TrimStr(dateStr),9) + strDate[2]:="-" + strDate[6]:="-" + + StrCopy(tempStr,dateStr) + RightStr(strTime,tempStr,8) + + dt.format:=FORMAT_DOS + dt.flags:=0 + dt.strday:=0 + dt.strdate:=strDate + dt.strtime:=strTime + + IF StrToDate(dt)=0 THEN RETURN 0 + + dval:=Mul(Mul(dt.stamp.days+2922,1440),60)+(dt.stamp.minute*60)+(dt.stamp.tick/50) + + ->2922 days between 1/1/70 and 1/1/78 + +ENDPROC dval+21600 + +PROC readString(fileHandle,buffer,maxLength) + DEF char,cnt,i + + cnt:=0 + FOR i:=0 TO maxLength-1 DO buffer[i]:=0 + + REPEAT + char:=FgetC(fileHandle) + IF (char=-1) OR (char=0) THEN RETURN + buffer[cnt]:=char + cnt++ + UNTIL (cnt=maxLength) +ENDPROC + +PROC findBodyLength(fileHandle) + DEF cnt,char + cnt:=0 + REPEAT + char:=FgetC(fileHandle) + IF char<>-1 THEN cnt++ + UNTIL char<=0 + Seek(fileHandle,-cnt,OFFSET_CURRENT) +ENDPROC cnt + +PROC writeMailLine(fh2,lineBuff:PTR TO CHAR) + DEF i,lineLen,ansi=FALSE + DEF lastSpace,s,partlen + + IF (StrCmp(TrimStr(lineBuff),'SEEN-BY: ',9)=FALSE) AND (StrCmp(TrimStr(lineBuff),'AREA: ',6)=FALSE) AND (lineBuff[0]<>1) + lineLen:=EstrLen(lineBuff) + FOR i:=0 TO lineLen-1 DO IF lineBuff[i]=27 THEN ansi:=TRUE + IF (ansi=FALSE) AND (lineLen>75) + partlen:=0 + lastSpace:=-1 + s:=0 + FOR i:=0 TO lineLen-1 + IF lineBuff[i]=" " THEN lastSpace:=i + IF partlen>=75 + IF lastSpace>=0 + lineBuff[lastSpace]:=10 + partlen:=i-lastSpace-1 + lastSpace:=-1 + ELSE + Write(fh2,lineBuff+s,i-s) + Write(fh2,'\n',1) + s:=i + partlen:=0 + ENDIF + ENDIF + partlen++ + ENDFOR + StrAdd(lineBuff,'\n') + Write(fh2,lineBuff+s,lineLen-s+1) + ELSE + StrAdd(lineBuff,'\n') + Write(fh2,lineBuff,lineLen+1) + ENDIF + ENDIF +ENDPROC + +PROC processPacketFile(filename:PTR TO CHAR) HANDLE + DEF ftnh: ftnHeader + DEF ms: mailStat + DEF mh: mailHeader + DEF buf=0:PTR TO CHAR + DEF buf2=0:PTR TO CHAR,bufsz + DEF mf=0,fh=0,fh2=0 + DEF n,c,i,i2 + DEF tempStr[255]:STRING + DEF lineBuff:PTR TO CHAR + DEF newMsgNum + DEF fname[255]:STRING + DEF msgBase[255]:STRING + DEF ftnConfId[255]:STRING + DEF lastConfId[255]:STRING + DEF needToSave + DEF cnt,maxCnt + + needToSave:=FALSE + StrCopy(lastConfId,'######') + + mf:=Open(filename,MODE_OLDFILE) + IF mf>0 + Seek(mf,58,OFFSET_BEGINNING) + buf:=New(35) + c:=0 + REPEAT + n:=Fread(mf,buf,2,1) + IF (buf[0]=2) AND (buf[1]=0) + n:=Fread(mf,buf+2,32,1) + buf[34]:=0 + IF n>0 + + AstrCopy(ftnh.msgdate,buf+14,21) + + readString(mf,ftnh.to,36) + readString(mf,ftnh.from,36) + readString(mf,ftnh.subject,72) + + bufsz:=findBodyLength(mf) + + buf2:=New(bufsz+1) + Fread(mf,buf2,bufsz,1) + + StrCopy(tempStr,'') + n:=0 + WHILE (n0) AND (buf2[n]<>10) AND (buf2[n]<>13) + StrAdd(tempStr,buf2+n,1) + n++ + ENDWHILE + WHILE (n0 + Close(fh) + fh:=0 + ENDIF + IF needToSave + ms.highMsgNum:=newMsgNum+1 + StringF(fname,'\sMailStats',msgBase) + fh:=Open(fname,MODE_NEWFILE) + IF fh>0 + Write(fh,ms,SIZEOF mailStat) + Close(fh) + fh:=0 + ELSE + WriteF('Error saving MailStats\n\n') + Raise(ERR_WRITE_MAILSTAT) + ENDIF + needToSave:=FALSE + ENDIF + + getMsgBasePath(ftnh.confId,msgBase) + IF StrLen(msgBase)=0 + WriteF('FTN conf \s not configured, skipping messages for this conf\n\n',ftnh.confId) + StrCopy(ftnConfId,'######') + ELSE + StrCopy(ftnConfId,ftnh.confId) + + StringF(fname,'\sMailStats',msgBase) + IF fh>0 THEN Close(fh) + fh:=Open(fname,MODE_READWRITE) + IF fh>0 + IF Read(fh,ms,SIZEOF mailStat)=0 + ms.lowestKey:=1 + ms.lowestNotDel:=1 + ms.highMsgNum:=1 + ms.pad[0]:=0;ms.pad[1]:=0;ms.pad[2]:=0;ms.pad[3]:=0;ms.pad[4]:=0;ms.pad[5]:=0 + Write(fh,ms,SIZEOF mailStat) + Close(fh) + fh:=0 + ELSE + Close(fh) + fh:=0 + ENDIF + ELSE + WriteF('Error opening MailStats (\s)\n\n',fname) + Raise(ERR_READ_MAILSTAT) + ENDIF + + newMsgNum:=ms.highMsgNum-1 + StringF(fname,'\sHeaderFile',msgBase) + fh:=Open(fname,MODE_READWRITE) + IF fh>0 + Seek(fh,0,OFFSET_END) + ELSE + WriteF('Error opening HeaderFile\n\n') + Raise(ERR_READ_HEADERFILE) + ENDIF + + ENDIF + + ENDIF + + StrCopy(lastConfId,ftnh.confId) + + IF StrCmp(ftnh.confId,ftnConfId) + newMsgNum++ + + mh.pad:=0 + mh.status:="P" + mh.msgNumb:=newMsgNum + + trimRight(ftnh.to,tempStr) + fillStrCopy(tempStr,mh.toName,31) + + trimRight(ftnh.from,tempStr) + fillStrCopy(tempStr,mh.fromName,31) + + trimRight(ftnh.subject,tempStr) + fillStrCopy(tempStr,mh.subject,31) + + mh.msgDate:=getEncodedDate(ftnh.msgdate) + mh.recv:=0 + + IF saveMh(fh,mh)<>110 + WriteF('Error saving mail header for message \d\n',newMsgNum) + ENDIF + + needToSave:=TRUE + + StringF(fname,'\s\d',msgBase,newMsgNum) + fh2:=Open(fname,MODE_NEWFILE) + IF fh2>0 + i:=n + n:=0 + WHILE i10 + buf2[n]:=buf2[i] + n++ + ENDIF + i++ + ENDWHILE + FOR i:=0 TO n-1 + IF buf2[i]=13 THEN buf2[i]:=10 + ENDFOR + + StrCopy(tempStr,'') + + cnt:=0 + maxCnt:=0 + FOR i:=0 TO n-1 + IF buf2[i]=10 + IF cnt>maxCnt THEN maxCnt:=cnt + cnt:=0 + ELSE + cnt++ + ENDIF + ENDFOR + IF cnt>maxCnt THEN maxCnt:=cnt + + lineBuff:=String(maxCnt+1) + i:=0 + WHILE (i10) + StrAdd(lineBuff,buf2+i,1) + i++ + ELSE + writeMailLine(fh2,lineBuff) + StrCopy(lineBuff,'') + i++ + ENDIF + ENDWHILE + IF StrLen(lineBuff)>0 + writeMailLine(fh2,lineBuff) + ENDIF + Dispose(lineBuff) + Close(fh2) + fh2:=0 + ELSE + WriteF('Error saving message body for message \d\n\n',newMsgNum) + ENDIF + Dispose(buf2) + buf2:=0 + ELSE + Seek(mf,bufsz,OFFSET_CURRENT) + ENDIF + ENDIF + n:=1 + c++ + ELSEIF (buf[0]=0) AND (buf[1]=0) + ->double null indicates no more data + n:=0 + ELSE + WriteF('Error reading message header from \s invalid message type found\n\n',filename) + Raise(ERR_READ_MESSAGES_DAT) + ENDIF + UNTIL (n=0) OR (CtrlC()) + + Close(fh) + fh:=0 + + IF needToSave + ms.highMsgNum:=newMsgNum+1 + StringF(fname,'\sMailStats',msgBase) + fh:=Open(fname,MODE_NEWFILE) + IF fh>0 + Write(fh,ms,SIZEOF mailStat) + Close(fh) + fh:=0 + ELSE + WriteF('Error saving MailStats\n\n') + Raise(ERR_WRITE_MAILSTAT) + ENDIF + needToSave:=FALSE + ENDIF + + IF mf>0 THEN Close(mf) + mf:=0 + RETURN TRUE + + ELSE + WriteF('Error opening \s\n\n',filename) + Raise(ERR_READ_MESSAGES_DAT) + ENDIF +EXCEPT DO + IF fh>0 THEN Close(fh) + IF fh2>0 THEN Close(fh2) + IF mf>0 THEN Close(mf) + IF buf<>0 THEN Dispose(buf) + IF buf2<>0 THEN Dispose(buf2) +ENDPROC + +PROC processPackets(scanPath:PTR TO CHAR) + DEF packetFilename[255]:STRING + DEF fname[255]:STRING + DEF fBlock:PTR TO fileinfoblock + DEF tempStr[255]:STRING + DEF fLock + + IF(fBlock:=AllocDosObject(DOS_FIB,NIL)) + IF(fLock:=Lock(scanPath,ACCESS_READ)) + + IF(Examine(fLock,fBlock)) + WHILE(ExNext(fLock,fBlock)) + StrCopy(fname,fBlock.filename) + RightStr(tempStr,fname,4) + UpperStr(tempStr) + IF StrCmp(tempStr,'.PKT') + StringF(packetFilename,'\s\s',scanPath,fBlock.filename) + IF processPacketFile(packetFilename) + SetProtection(packetFilename,FIBF_OTR_DELETE) + DeleteFile(packetFilename) + ENDIF + ENDIF + ENDWHILE + ENDIF + UnLock(fLock) + ENDIF + FreeDosObject(DOS_FIB,fBlock) + ENDIF +ENDPROC + +PROC processBundles(unpackCommand:PTR TO CHAR, scanPath:PTR TO CHAR, tempDir:PTR TO CHAR) + DEF cleanUp[255]:STRING + DEF unpack[255]:STRING + DEF fname[255]:STRING + DEF fBlock:PTR TO fileinfoblock + DEF tempStr[255]:STRING + DEF bundleFilename[255]:STRING + DEF fLock + + IF(fBlock:=AllocDosObject(DOS_FIB,NIL)) + IF(fLock:=Lock(scanPath,ACCESS_READ)) + + IF(Examine(fLock,fBlock)) + WHILE(ExNext(fLock,fBlock)) + IF fBlock.direntrytype < 0 + StrCopy(fname,fBlock.filename) + RightStr(tempStr,fname,4) + UpperStr(tempStr) + IF StrCmp(tempStr,'.PKT')=FALSE + StringF(bundleFilename,'\s\s',scanPath,fBlock.filename) + + StrCopy(unpack,unpackCommand) + replacestr(unpack,'{filename}',bundleFilename) + exec(unpack) + processPackets(tempDir) + StringF(cleanUp,'delete \s ALL',tempDir) + exec(cleanUp) + + SetProtection(bundleFilename,FIBF_OTR_DELETE) + DeleteFile(bundleFilename) + ENDIF + ENDIF + ENDWHILE + ENDIF + UnLock(fLock) + ENDIF + FreeDosObject(DOS_FIB,fBlock) + ENDIF + + + +ENDPROC + +PROC trimStr(src:PTR TO CHAR) + DEF i + DEF tempStr[255]:STRING + + StrCopy(tempStr,TrimStr(src)) + + i:=EstrLen(tempStr)-1 + WHILE (i>=0) + IF tempStr[i]<>" " + i:=-1 + ELSE + SetStr(tempStr,i) + i-- + ENDIF + ENDWHILE + + StrCopy(src,tempStr) +ENDPROC + +PROC processConfigLine(inString,categoryStr,optName,optValue) + DEF t[255]:STRING + DEF l + StrCopy(t,inString) + trimStr(t) + l:=EstrLen(t) + IF l>1 + IF (t[0]="[") AND (t[l-1]="]") + StrCopy(categoryStr,t+1,l-2) + trimStr(categoryStr) + UpperStr(categoryStr) + StrCopy(optName,'') + StrCopy(optValue,'') + RETURN + ENDIF + ENDIF + l:=InStr(t,'=') + IF l>0 + StrCopy(optName,t,l) + trimStr(optName) + UpperStr(optName) + StrCopy(optValue,t+l+1,ALL) + trimStr(optValue) + ELSE + StrCopy(optName,'') + StrCopy(optValue,'') + ENDIF +ENDPROC + +PROC main() HANDLE + DEF mode[255]:STRING + DEF inboundDir[255]:STRING + DEF inboundInsecureDir[255]:STRING + DEF outboundDir[255]:STRING + + DEF ftnUnpackCommand[255]:STRING + + DEF tempDir[255]:STRING + + DEF cmdCopy[255]:STRING + + DEF pktPass[8]:STRING + + DEF cfgFile[255]:STRING + DEF myargs:PTR TO LONG,rdargs + + DEF fh,lock + DEF tempStr[255]:STRING + DEF msgBundleFilename[255]:STRING + DEF msgPacketFilename[255]:STRING + DEF dow[3]:STRING + + DEF category[255]:STRING + DEF optionName[255]:STRING + DEF optionValue[255]:STRING + + DEF originNode,destNode,originNet,destNet,originZone,destZone,originPoint,destPoint,attr,cost + DEF tearLine[255]:STRING + DEF originLine[255]:STRING + DEF tzOffset[10]:STRING + + WriteF('Ami-Express FTN file processor Copyright 2020 Darren Coles\n') + + myargs:=[0,0]:LONG + IF rdargs:=ReadArgs('CFG/A',myargs,NIL) + IF myargs[0]<>NIL + AstrCopy(cfgFile,myargs[0],255) + ENDIF + FreeArgs(rdargs) + ELSE + RETURN + ENDIF + + confNames:=NEW confNames.stringlist(100) + msgBasePaths:=NEW msgBasePaths.stringlist(100) + + fh:=Open(cfgFile,MODE_OLDFILE) + IF fh>0 + + REPEAT + ReadStr(fh,tempStr) + processConfigLine(tempStr,category,optionName,optionValue) + + IF StrCmp('MAIN',category) AND StrCmp('MODE',optionName) THEN StrCopy(mode,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('INBOUND',optionName) THEN StrCopy(inboundDir,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('INBOUNDINSEC',optionName) THEN StrCopy(inboundInsecureDir,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('OUTBOUND',optionName) THEN StrCopy(outboundDir,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('UNPACKCMD',optionName) THEN StrCopy(ftnUnpackCommand,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('TEMPDIR',optionName) THEN StrCopy(tempDir,optionValue) + + IF StrCmp('ORIGINNET',category) AND StrCmp('ZONE',optionName) THEN originZone:=Val(optionValue) + IF StrCmp('ORIGINNET',category) AND StrCmp('NET',optionName) THEN originNet:=Val(optionValue) + IF StrCmp('ORIGINNET',category) AND StrCmp('NODE',optionName) THEN originNode:=Val(optionValue) + IF StrCmp('ORIGINNET',category) AND StrCmp('POINT',optionName) THEN originPoint:=Val(optionValue) + + IF StrCmp('DESTNET',category) AND StrCmp('ZONE',optionName) THEN destZone:=Val(optionValue) + IF StrCmp('DESTNET',category) AND StrCmp('NET',optionName) THEN destNet:=Val(optionValue) + IF StrCmp('DESTNET',category) AND StrCmp('NODE',optionName) THEN destNode:=Val(optionValue) + IF StrCmp('DESTNET',category) AND StrCmp('POINT',optionName) THEN destPoint:=Val(optionValue) + + IF StrCmp('MISC',category) AND StrCmp('PASSWORD',optionName) THEN StrCopy(pktPass,optionValue) + IF StrCmp('MISC',category) AND StrCmp('COST',optionName) THEN cost:=Val(optionValue) + IF StrCmp('MISC',category) AND StrCmp('ATTR',optionName) THEN attr:=Val(optionValue) + IF StrCmp('MISC',category) AND StrCmp('TEAR',optionName) THEN StrCopy(tearLine,optionValue) + IF StrCmp('MISC',category) AND StrCmp('ORIGIN',optionName) THEN StrCopy(originLine,optionValue) + IF StrCmp('MISC',category) AND StrCmp('TZOFFSET',optionName) THEN StrCopy(tzOffset,optionValue) + UNTIL StrCmp(category,'CONFS') + UpperStr(mode) + + WHILE(ReadStr(fh,tempStr)<>-1) OR (StrLen(tempStr)>0) + confNames.add(tempStr) + ReadStr(fh,tempStr) + msgBasePaths.add(tempStr) + ENDWHILE + Close(fh) + fh:=0 + ELSE + WriteF('Error opening FTN.cfg\n\n') + Raise(ERR_NOCFG) + ENDIF + + IF StrCmp(mode,'OUT') OR StrCmp(mode,'BOTH') + WriteF('Processing outgoing messages\n') + + StringF(msgPacketFilename,'\s\z\h[4]\z\h[4].Out',outboundDir,destNet,destNode) + + ->create messages bundle by scraping confs + createMessagesBundle(originNode,destNode,originNet,destNet,originZone,destZone,originPoint,destPoint,attr,cost,pktPass,msgPacketFilename,tearLine,originLine,tzOffset) + ENDIF + + IF StrCmp(mode,'IN') OR StrCmp(mode,'BOTH') + WriteF('Processing incoming messages\n') + IF StrLen(inboundDir)>0 THEN processBundles(ftnUnpackCommand,inboundDir,tempDir) + IF StrLen(inboundInsecureDir)>0 THEN processBundles(ftnUnpackCommand,inboundInsecureDir,tempDir) + IF StrLen(inboundDir)>0 THEN processPackets(inboundDir) + IF StrLen(inboundInsecureDir)>0 THEN processPackets(inboundInsecureDir) + ENDIF + WriteF('All done\n') + +EXCEPT DO + IF confNames<>NIL THEN END confNames + IF msgBasePaths<>NIL THEN END msgBasePaths +ENDPROC \ No newline at end of file diff --git a/ftpd.e b/ftpd.e index 710505c..71a2362 100644 --- a/ftpd.e +++ b/ftpd.e @@ -41,6 +41,7 @@ OBJECT ftpData fileStart:LONG fileEnd:LONG fileProgress:LONG + fileDupeCheck:LONG xprInfo:LONG ENDOBJECT @@ -101,14 +102,14 @@ PROC releaseSocket(sb,fd,id) MOVEM.L (A7)+,D1-D7/A0-A6 ENDPROC D0 -PROC releaseCopyOfSocket(sb,fd,id) +/*PROC releaseCopyOfSocket(sb,fd,id) MOVEM.L D1-D7/A0-A6,-(A7) MOVE.L sb,A6 MOVE.L fd,D0 MOVE.L id,D1 JSR -$9C(A6) ->ReleaseCopyOfSocket(fd,id) MOVEM.L (A7)+,D1-D7/A0-A6 -ENDPROC D0 +ENDPROC D0*/ PROC closeSocket(sb,s) MOVEM.L D1-D7/A0-A6,-(A7) @@ -200,10 +201,9 @@ ENDPROC D0 PROC fileStart(ftpData:PTR TO ftpData,fn,pos) DEF fs,xprInfo - DEF xi fs:=ftpData.fileStart - xi:=ftpData.xprInfo - MOVE.L xi,-(A7) + xprInfo:=ftpData.xprInfo + MOVE.L xprInfo,-(A7) MOVE.L fn,-(A7) MOVE.L pos,-(A7) fs() @@ -236,6 +236,18 @@ PROC fileProgress(ftpData:PTR TO ftpData,fn,pos,cps) ADD.L #12,A7 ENDPROC +PROC fileDupeCheck(ftpData:PTR TO ftpData,fn) + DEF fdc + DEF xprInfo + fdc:=ftpData.fileDupeCheck + xprInfo:=ftpData.xprInfo + + MOVE.L xprInfo,-(A7) + MOVE.L fn,-(A7) + fdc() + ADD.L #8,A7 +ENDPROC D0 + PROC aePuts(ftpData:PTR TO ftpData, s:PTR TO CHAR) DEF puts puts:=ftpData.aePuts @@ -246,7 +258,7 @@ PROC aePuts(ftpData:PTR TO ftpData, s:PTR TO CHAR) ENDPROC PROC sCheckInput(ftpData:PTR TO ftpData) - DEF chk,r + DEF chk chk:=ftpData.sCheckInput ENDPROC chk() @@ -518,7 +530,7 @@ PROC cmdUser(sb,ftp_c,params:PTR TO CHAR) ENDPROC PROC cmdPass(sb,ftp_c,params) - ->WriteF('user=\s\b\n',params) + ->WriteF('pass=\s\b\n',params) writeLineEx(sb,ftp_c, '230 password accepted\b\n') ENDPROC @@ -599,6 +611,25 @@ PROC cmdStor(sb,ftp_c,data_s,data_c,filename:PTR TO CHAR,ftpData:PTR TO ftpData) DEF cps,lastpos DEF asynclib + IF (ftpData.fileDupeCheck<>NIL) + IF fileDupeCheck(ftpData,filename)=TRUE + StringF(temp,'553 \s: Duplicate file skipped\b\n',filename) + writeLineEx(sb,ftp_c,temp) + + IF (data_c>=0) + ftpData.scount:=ftpData.scount-1 + r:=closeSocket(sb,data_c) + ENDIF + + IF (data_s>=0) + ftpData.scount:=ftpData.scount-1 + r:=closeSocket(sb,data_s) + ENDIF + + RETURN + ENDIF + ENDIF + IF ftpData.uploadMode=FALSE StringF(temp,'550 \s: Not expecting any uploads\b\n',filename) writeLineEx(sb,ftp_c,temp) @@ -669,7 +700,7 @@ PROC cmdStor(sb,ftp_c,data_s,data_c,filename:PTR TO CHAR,ftpData:PTR TO ftpData) t:=t2 ENDIF ENDIF - UNTIL l=0 + UNTIL (l=0) OR (CtrlC()) Dispose(buff) IF ftpData.fileProgress<>NIL @@ -692,7 +723,7 @@ PROC cmdStor(sb,ftp_c,data_s,data_c,filename:PTR TO CHAR,ftpData:PTR TO ftpData) fileEnd(ftpData,filename) ENDIF - fail:=FALSE + fail:=(CtrlC()<>FALSE) StringF(temp, '\d \s ... \s\b\n', IF (fail=FALSE) THEN 226 ELSE 426, @@ -811,7 +842,7 @@ PROC cmdRetr(sb,ftp_c,data_s,data_c,filename:PTR TO CHAR,ftpData:PTR TO ftpData) ENDIF ENDIF ENDIF - UNTIL l=0 + UNTIL (l=0) OR (CtrlC()) Dispose(buff) IF ftpData.fileProgress<>NIL @@ -829,7 +860,7 @@ PROC cmdRetr(sb,ftp_c,data_s,data_c,filename:PTR TO CHAR,ftpData:PTR TO ftpData) ELSE Close(fh) ENDIF - fail:=FALSE + fail:=(CtrlC()<>FALSE) IF ftpData.fileEnd<>NIL fileEnd(ftpData,filename) ENDIF @@ -864,8 +895,7 @@ ENDPROC PROC cmdList(sb,ftp_c,data_s,data_c,ftpData:PTR TO ftpData) DEF r - DEF temp[255]:STRING - + IF (data_c>=0) myDir(sb,data_c,ftpData.workingPath) writeLineEx(sb,ftp_c, '226 Transfer Complete\b\n') @@ -889,8 +919,6 @@ PROC ftpThread() DEF sb,r DEF data_s=-1,data_c=-1 DEF ftpData:PTR TO ftpData - DEF t,svA4 - DEF temp[255]:STRING ftpData:=loadA4() @@ -904,7 +932,7 @@ PROC ftpThread() ftpData.scount:=ftpData.scount+1 writeLineEx(sb,ftp_c, '220 Hi, I''m your Amiga FTP server.\b\n') - WHILE((readLine(sb,ftp_c, request, MAX_LINE-1) > 0) AND (StrCmp(request, 'QUIT', 4)=FALSE)) + WHILE((readLine(sb,ftp_c, request, MAX_LINE-1) > 0) AND (StrCmp(request, 'QUIT', 4)=FALSE)) AND (CtrlC()=FALSE) IF(StrCmp(request, 'USER ', 5)) cmdUser(sb,ftp_c,request+5) @@ -1021,10 +1049,12 @@ taskfound: ENDPROC pa -PROC createThread(node,sockid,ftpData:PTR TO ftpData) +PROC createThread(num,node,sockid,ftpData:PTR TO ftpData) DEF tags,proc:PTR TO process - DEF tempstr[255]:STRING - tags:=NEW [NP_ENTRY,{ftpThread},NP_STACKSIZE,10000,0]:LONG + DEF name[255]:STRING + + StringF(name,'ftpThread\d-\d',node,num) + tags:=NEW [NP_ENTRY,{ftpThread},NP_NAME,name,NP_STACKSIZE,10000,0]:LONG ftpData.sockId:=sockid @@ -1035,11 +1065,12 @@ PROC createThread(node,sockid,ftpData:PTR TO ftpData) END tags ENDPROC -EXPORT PROC doftp(node,ftphost,ftpport,ftpdataport,ftppath,aePutsPtr, readCharPtr, sCheckInputPtr, xprInfo, ftpFileStartPtr, ftpFileEndPtr, ftpFileProgressPtr, uploadMode) - DEF r,ftp_s,ftp_c,s,sb,myargs:PTR TO LONG,rdargs +EXPORT PROC doftp(node,ftphost,ftpport,ftpdataport,ftppath,aePutsPtr, readCharPtr, sCheckInputPtr, xprInfo, ftpFileStartPtr, ftpFileEndPtr, ftpFileProgressPtr, ftpDupeCheckPtr,uploadMode) + DEF r,ftp_s,ftp_c,s,sb DEF temp[255]:STRING DEF ftpData:PTR TO ftpData DEF flg,rchar + DEF tcount=0,i,t ftpData:=NEW ftpData ftpData.rest:=0 @@ -1054,6 +1085,7 @@ EXPORT PROC doftp(node,ftphost,ftpport,ftpdataport,ftppath,aePutsPtr, readCharPt ftpData.fileStart:=ftpFileStartPtr ftpData.fileEnd:=ftpFileEndPtr ftpData.fileProgress:=ftpFileProgressPtr + ftpData.fileDupeCheck:=ftpDupeCheckPtr ftpData.workingPath:=String(255) ftpData.hostName:=String(255) ftpData.xprInfo:=xprInfo @@ -1097,7 +1129,8 @@ EXPORT PROC doftp(node,ftphost,ftpport,ftpdataport,ftppath,aePutsPtr, readCharPt s:=releaseSocket(sb,ftp_c,UNIQUE_ID) ->r:=closeSocket(sb,ftp_c) - createThread(node,s,ftpData) + createThread(tcount,node,s,ftpData) + tcount++ ENDIF ENDWHILE ftpData.scount:=ftpData.scount-1 @@ -1106,6 +1139,14 @@ EXPORT PROC doftp(node,ftphost,ftpport,ftpdataport,ftppath,aePutsPtr, readCharPt IF flg THEN aePuts(ftpData,'\b\n') IF rchar=3 aePuts(ftpData,'CTRL-C detected, FTP transfer aborted\b\n') + FOR i:=0 TO tcount-1 + StringF(temp,'ftpThread\d-\d',node,i) + Forbid() + t:=FindTask(temp) + IF t<>NIL THEN Signal(t,SIGBREAKF_CTRL_C) + Permit() + ENDFOR + ELSE aePuts(ftpData,'FTP transfers complete, all ftp connections closed\b\n') ENDIF diff --git a/httpd.e b/httpd.e new file mode 100644 index 0000000..4bc3062 --- /dev/null +++ b/httpd.e @@ -0,0 +1,749 @@ +/* +** simple httpd +** Amiga E version +*/ + +OPT LARGE,MODULE + +CONST LISTENQ=100 +CONST EINTR=4 +CONST EWOULDBLOCK=35 +CONST MAX_LINE=255 +CONST FIONBIO=$8004667e + +MODULE 'socket', + 'net/netdb', + 'net/in', + 'net/socket', + 'dos/dostags', + 'dos/dosextens', + 'dos/datetime', + 'dos/dos', + 'exec/tasks', + 'exec/alerts', + 'asyncio', + 'libraries/asyncio', + '*axcommon', + '*axobjects', + '*stringlist' + +OBJECT httpData + rest:LONG + tcount:LONG + scount:LONG + hostName:PTR TO CHAR + workingPath:PTR TO CHAR + uploadMode:LONG + port:LONG + restPos:LONG + sockId:LONG + aePuts:LONG + readChar:LONG + sCheckInput:LONG + fileStart:LONG + fileEnd:LONG + fileProgress:LONG + fileDupeCheck:LONG + xprInfo:LONG +ENDOBJECT + + +PROC errno(sb) + MOVE.L sb,A6 + JSR -$A2(A6) ->errno +ENDPROC D0 + +PROC ioctlSocket(sb,s,v,tags) + MOVEM.L D1-D7/A0-A6,-(A7) + MOVE.L sb,A6 + MOVE.L s,D0 + MOVE.L v,D1 + MOVE.L tags,A0 + JSR -$72(A6) + MOVEM.L (A7)+,D1-D7/A0-A6 +ENDPROC D0 + +PROC recv(sb,s,buf,len,flags) + MOVEM.L D1-D7/A0-A6,-(A7) + MOVE.L sb,A6 + MOVE.L s,D0 + MOVE.L buf,A0 + MOVE.L len,D1 + MOVE.L flags,D2 + JSR -$4E(A6) ->recv + MOVEM.L (A7)+,D1-D7/A0-A6 +ENDPROC D0 + +PROC send(sb,s,msg,len,flags) + MOVEM.L D1-D7/A0-A6,-(A7) + MOVE.L sb,A6 + MOVE.L s,D0 + MOVE.L msg,A0 + MOVE.L len,D1 + MOVE.L flags,D2 + JSR -$42(A6) ->send + MOVEM.L (A7)+,D1-D7/A0-A6 +ENDPROC D0 + +PROC accept(sb,s,addr,addrlen) + MOVEM.L D1-D7/A0-A6,-(A7) + MOVE.L sb,A6 + MOVE.L s,D0 + MOVE.L addr,A0 + MOVE.L addrlen,A1 + JSR -$30(A6) ->Accept(s,addr,addrlen) + MOVEM.L (A7)+,D1-D7/A0-A6 +ENDPROC D0 + +PROC closeSocket(sb,s) + MOVEM.L D1-D7/A0-A6,-(A7) + MOVE.L sb,A6 + MOVE.L s,D0 + JSR -$78(A6) ->CloseSocket(s) + MOVEM.L (A7)+,D1-D7/A0-A6 +ENDPROC D0 + +PROC socket(sb,domain, type, protocol) + MOVEM.L D1-D7/A0-A6,-(A7) + MOVE.L sb,A6 + MOVE.L domain,D0 + MOVE.L type,D1 + MOVE.L protocol,D2 + + JSR -$1E(A6) ->Socket(domain,type,protocol) + MOVEM.L (A7)+,D1-D7/A0-A6 +ENDPROC D0 + +PROC bind(sb,s, name, namelen) + MOVEM.L D1-D7/A0-A6,-(A7) + MOVE.L sb,A6 + MOVE.L s,D0 + MOVE.L name,A0 + MOVE.L namelen,D1 + + JSR -$24(A6) ->Bind(domain,type,protocol) + MOVEM.L (A7)+,D1-D7/A0-A6 +ENDPROC D0 + +PROC listen(sb,s, backlog) + MOVEM.L D1-D7/A0-A6,-(A7) + MOVE.L sb,A6 + MOVE.L s,D0 + MOVE.L backlog,D1 + + JSR -$2A(A6) ->Listen(s,backlog) + MOVEM.L (A7)+,D1-D7/A0-A6 +ENDPROC D0 + +PROC getSockOpt(sb,s,level,optname,optval,optlen ) + MOVEM.L D1-D7/A0-A6,-(A7) + MOVE.L sb,A6 + MOVE.L s,D0 + MOVE.L level,D1 + MOVE.L optname,D2 + MOVE.L optval,A0 + MOVE.L optlen,A1 + + JSR -$60(A6) ->getSockOpt(s,level,optname,optval,optlen) + MOVEM.L (A7)+,D1-D7/A0-A6 +ENDPROC D0 + + +PROC setSockOpt(sb,s,level,optname,optval,optlen ) + MOVEM.L D1-D7/A0-A6,-(A7) + MOVE.L sb,A6 + MOVE.L s,D0 + MOVE.L level,D1 + MOVE.L optname,D2 + MOVE.L optval,A0 + MOVE.L optlen,D3 + + JSR -$5A(A6) ->setSockOpt(s,level,optname,optval,optlen) + MOVEM.L (A7)+,D1-D7/A0-A6 +ENDPROC D0 + +PROC fileStart(httpData:PTR TO httpData,fn,pos) + DEF fs,xprInfo + fs:=httpData.fileStart + xprInfo:=httpData.xprInfo + MOVE.L xprInfo,-(A7) + MOVE.L fn,-(A7) + MOVE.L pos,-(A7) + fs() + ADD.L #12,A7 +ENDPROC + +PROC fileEnd(httpData:PTR TO httpData,fn) + DEF fe + DEF xprInfo + fe:=httpData.fileEnd + xprInfo:=httpData.xprInfo + + MOVE.L xprInfo,-(A7) + MOVE.L fn,-(A7) + fe() + ADDQ.L #8,A7 +ENDPROC + +PROC fileProgress(httpData:PTR TO httpData,fn,pos,cps) + DEF fp + DEF xprInfo + fp:=httpData.fileProgress + xprInfo:=httpData.xprInfo + + MOVE.L xprInfo,-(A7) + MOVE.L fn,-(A7) + MOVE.L pos,-(A7) + MOVE.L cps,-(A7) + fp() + ADD.L #12,A7 +ENDPROC + +PROC fileDupeCheck(httpData:PTR TO httpData,fn) + DEF fdc + DEF xprInfo + fdc:=httpData.fileDupeCheck + xprInfo:=httpData.xprInfo + + MOVE.L xprInfo,-(A7) + MOVE.L fn,-(A7) + fdc() + ADD.L #8,A7 +ENDPROC D0 + +PROC aePuts(httpData:PTR TO httpData, s:PTR TO CHAR) + DEF puts + puts:=httpData.aePuts + MOVE.L s,-(A7) + CLR.L -(A7) + puts() + ADDQ.L #8,A7 +ENDPROC + +PROC sCheckInput(httpData:PTR TO httpData) + DEF chk + chk:=httpData.sCheckInput +ENDPROC chk() + +PROC readChar(httpData:PTR TO httpData) + DEF rdChar,r + rdChar:=httpData.readChar + CLR.L -(A7) + CLR.L -(A7) + r:=rdChar() + ADDQ.L #8,A7 +ENDPROC r + +PROC fastSystemTime() + DEF currDate: datestamp + DEF startds:PTR TO datestamp + + startds:=DateStamp(currDate) + +ENDPROC Mul(startds.minute,3000)+startds.tick + +PROC openSocket(sb,port, reuseable,httpData:PTR TO httpData) + DEF server_s + DEF servaddr=0:PTR TO sockaddr_in + DEF tempStr[255]:STRING + DEF optval:PTR TO LONG,optlen:PTR TO LONG + + servaddr:=NEW servaddr + + IF((server_s:=socket(sb,AF_INET, SOCK_STREAM, 0)) < 0) + StringF(tempStr,'/XHTTP: Error creating listening socket. (\d)\b\n',errno(sb)) + aePuts(httpData,tempStr) + END servaddr + RETURN FALSE,-1 + ENDIF + + IF reuseable + IF setSockOpt(sb,server_s, SOL_SOCKET, SO_REUSEADDR, [1]:LONG, 4)<>0 + StringF(tempStr,'/XHTTP: error setting socket options SO_REUSEADDR, error=\d\b\n',errno(sb)) + aePuts(httpData,tempStr) + ENDIF + + optval:=NEW [0,0]:LONG + optlen:=NEW [8]:LONG + IF getSockOpt(sb,server_s, SOL_SOCKET, SO_LINGER, optval,optlen)<>0 + StringF(tempStr,'/XHTTP: error getting socket options SO_LINGER, error=\d\b\n',errno(sb)) + aePuts(httpData,tempStr) + ENDIF + IF optlen[0]=4 + optval[0]:=$10000 + ELSEIF optlen[0]=8 + optval[0]:=1 + optval[1]:=0 + ELSE + aePuts(httpData,'/XHTTP: error setting socket options SO_LINGER, bad size\b\n') + ENDIF + + IF setSockOpt(sb,server_s, SOL_SOCKET, SO_LINGER, optval,optlen[0])<>0 + StringF(tempStr,'/XHTTP: error setting socket options SO_LINGER, error=\d\b\n',errno(sb)) + aePuts(httpData,tempStr) + ENDIF + END optval + END optlen + + ENDIF + + servaddr.sin_len:=SIZEOF sockaddr_in + servaddr.sin_family:=AF_INET + servaddr.sin_port:=port + servaddr.sin_addr:=INADDR_ANY + + IF(bind(sb,server_s, servaddr, SIZEOF sockaddr_in) < 0) + StringF(tempStr,'/XHTTP: Error calling bind() for port \d, error=\d\b\n',port,errno(sb)); + aePuts(httpData,tempStr) + closeSocket(sb,server_s) + END servaddr + RETURN FALSE,-1 + ENDIF + + IF(listen(sb,server_s, LISTENQ) < 0) + StringF(tempStr,'/XHTTP: Error calling listen() for port \d, error=\d\b\n',port,errno(sb)); + aePuts(httpData,tempStr) + closeSocket(sb,server_s) + END servaddr + RETURN FALSE,-1 + ENDIF + + END servaddr + httpData.scount:=httpData.scount+1 +ENDPROC TRUE,server_s + +PROC readLine(sb,sockd, vptr:PTR TO CHAR, maxlen) + DEF n, rc + DEF c[1]:STRING + DEF buffer:PTR TO CHAR + + buffer:=vptr + n:=0 + WHILE (n<(maxlen-1)) AND (c[] <> "\n") + rc:=recv(sb,sockd, c, 1,0) + IF ( rc = 1 ) + IF(c[] <> "\b") AND (c[] <> "\n") + buffer[]++:=c[] + n++ + ENDIF + ELSE + IF ( errno(sb)<>EINTR ) + RETURN -1 + ENDIF + ENDIF + ENDWHILE + buffer[]:=0 +ENDPROC n + +PROC writeLine(sb,sockd, vptr:PTR TO CHAR, n) + send(sb,sockd, vptr, n,0) +ENDPROC n + +PROC writeLineEx(sb,sockd, vptr:PTR TO CHAR) +ENDPROC writeLine(sb,sockd, vptr, StrLen(vptr)) + +PROC listFiles(path: PTR TO CHAR,sb,http_c) + DEF lock + DEF f_info: PTR TO fileinfoblock + DEF tempstr[255]:STRING + + f_info:=AllocDosObject(DOS_FIB,NIL) + IF(f_info)=NIL THEN RETURN + + lock:=Lock(path,ACCESS_READ) + IF(lock)=0 + FreeDosObject(DOS_FIB,f_info) + RETURN + ENDIF + + IF(Examine(lock,f_info))=0 + UnLock(lock) + FreeDosObject(DOS_FIB,f_info) + RETURN + ENDIF + + writeLineEx(sb,http_c,'
\b\n') + writeLineEx(sb,http_c,'
    \b\n') + + WHILE((ExNext(lock,f_info))<>0) + StringF(tempstr,'
  1. \s
  2. \b\n',f_info.filename) + writeLineEx(sb,http_c,tempstr) + ENDWHILE + + writeLineEx(sb,http_c,'
\b\n') + writeLineEx(sb,http_c,'
\b\n') + UnLock(lock) + FreeDosObject(DOS_FIB,f_info) +ENDPROC + +PROC generatePage(sb,http_c,httppath:PTR TO CHAR, xprInfo:PTR TO xprData,node,uploadMode) + DEF temp[255]:STRING + DEF fl:PTR TO stdlist + DEF fi:PTR TO flagFileItem + DEF i + + writeLineEx(sb,http_c,'HTTP/1.1 200 OK\b\n') + writeLineEx(sb,http_c,'content-type: text/html; charset=UTF-8\b\n') + writeLineEx(sb,http_c,'\b\n') + writeLineEx(sb,http_c,'\b\n') + writeLineEx(sb,http_c,'\b\n') + IF uploadMode + writeLineEx(sb,http_c,'Ami-Express uploads\b\n') + ELSE + writeLineEx(sb,http_c,'Ami-Express downloads\b\n') + ENDIF + + writeLineEx(sb,http_c,'\b\n') + writeLineEx(sb,http_c,'\b\n') + IF uploadMode + StringF(temp,'

Ami-Express uploads - node \d

\b\n',node) + writeLineEx(sb,http_c,temp) + listFiles(httppath,sb,http_c) + writeLineEx(sb,http_c,'
\b\n') + writeLineEx(sb,http_c,'
\b\n') + writeLineEx(sb,http_c,'') + writeLineEx(sb,http_c,'\b\n') + writeLineEx(sb,http_c,'
\b\n') + ELSE + StringF(temp,'

Ami-Express downloads - node \d

\b\n',node) + writeLineEx(sb,http_c,temp) + writeLineEx(sb,http_c,'
\b\n') + writeLineEx(sb,http_c,'
    \b\n') + + fl:=xprInfo.fileList + FOR i:=0 TO fl.count()-1 + fi:=fl.item(i) + StringF(temp,'
  1. \s
  2. \b\n',FilePart(fi.fileName),FilePart(fi.fileName)) + writeLineEx(sb,http_c,temp) + ENDFOR + writeLineEx(sb,http_c,'
\b\n') + writeLineEx(sb,http_c,'
\b\n') + ENDIF + + writeLineEx(sb,http_c,'\b\n') + writeLineEx(sb,http_c,'\b\n') +ENDPROC + +PROC readMemLine(outBuf:PTR TO CHAR,sb,socket,inBuf:PTR TO CHAR,bufsize:PTR TO LONG,pos:PTR TO LONG,maxlen,maxbuf,contentLength:PTR TO LONG) + DEF loop=TRUE + DEF len + DEF r + + IF pos[]>=(bufsize[]-maxlen) + len:=bufsize[]-pos[] + CopyMem(inBuf+pos[],inBuf,len) + r:=maxbuf-len + IF contentLength[]"\n" + IF inBuf[pos[]]<>"\b" THEN StrAdd(outBuf,inBuf+pos[],1) + ELSE + loop:=FALSE + ENDIF + IF StrLen(outBuf)=maxlen THEN loop:=FALSE + pos[]:=pos[]+1 + ENDWHILE +ENDPROC StrLen(outBuf) + +PROC extractFileData(sb,socket,httpData:PTR TO httpData,boundary:PTR TO CHAR,contentLength,asynclib) + DEF buff,fh + DEF pos,p,readSize,boundaryLen + DEF fname[255]:STRING + DEF lineBuff[255]:STRING + DEF loop,morefiles=TRUE + DEF bufsize + DEF t,t2,filepos,lastfilepos,cps + + boundaryLen:=StrLen(boundary) + bufsize:=32768+boundaryLen + readSize:=bufsize + buff:=New(readSize) + + ->dupecheck + + IF contentLength 0) + IF (p:=InStr(lineBuff,'filename="'))>=0 + StrCopy(fname,httpData.workingPath) + StrAdd(fname,lineBuff+p+10,ALL) + p:=InStr(fname,'"') + SetStr(fname,p) + ENDIF + ENDWHILE + fh:=0 + IF StrLen(fname)>0 + IF fileDupeCheck(httpData,fname)=FALSE + IF asynclib<>NIL + DeleteFile(fname) + fh:=OpenAsync(fname,MODE_APPEND,32768) + ELSE + fh:=Open(fname,MODE_NEWFILE) + ENDIF + IF httpData.fileStart<>NIL + fileStart(httpData,fname,0) + ENDIF + t:=fastSystemTime() + lastfilepos:=0 + ENDIF + ENDIF + + loop:=TRUE + REPEAT + p:=pos + WHILE (p<(readSize-boundaryLen)) AND (StrCmp(buff+p,boundary,boundaryLen)=FALSE) DO p++ + IF fh>0 + IF asynclib<>NIL + WriteAsync(fh,buff+pos,p-pos) + ELSE + Write(fh,buff+pos,p-pos) + ENDIF + + t2:=fastSystemTime() + ->only call update maximum every 1 second + IF (Abs(t2-t))>=50 + IF asynclib<>NIL + filepos:=SeekAsync(fh,0,MODE_CURRENT) + ELSE + filepos:=Seek(fh,0,OFFSET_CURRENT) + ENDIF + IF (t0 + CopyMem(buff+readSize-boundaryLen,buff,boundaryLen) + readSize:=bufsize-boundaryLen + IF contentLength0 + IF asynclib<>NIL + CloseAsync(fh) + ELSE + Close(fh) + ENDIF + IF httpData.fileEnd<>NIL + fileEnd(httpData,fname) + ENDIF + ENDIF + + UNTIL morefiles=FALSE + Dispose(buff) +ENDPROC + + +EXPORT PROC doHttpd(node,httphost,httpport,httppath,aePutsPtr, readCharPtr, sCheckInputPtr, xprInfo:PTR TO xprData, httpFileStartPtr, httpFileEndPtr, httpFileProgressPtr, httpDupeCheckPtr, uploadMode) + DEF r,http_s,http_c,sb + DEF temp[255]:STRING + DEF httpData:PTR TO httpData + DEF flg,rchar + DEF request[255]:STRING + DEF getCmd[255]:STRING + DEF postCmd[255]:STRING + DEF boundary[255]:STRING + DEF spcPos + DEF fh,buff,l,t,t2,lastpos,pos,cps + DEF asynclib + DEF p,contentLength + + httpData:=NEW httpData + httpData.rest:=0 + httpData.tcount:=0 + httpData.scount:=0 + httpData.port:=-1 + httpData.uploadMode:=uploadMode + httpData.restPos:=0 + httpData.aePuts:=aePutsPtr + httpData.readChar:=readCharPtr + httpData.sCheckInput:=sCheckInputPtr + httpData.fileStart:=httpFileStartPtr + httpData.fileEnd:=httpFileEndPtr + httpData.fileProgress:=httpFileProgressPtr + httpData.fileDupeCheck:=httpDupeCheckPtr + httpData.workingPath:=String(255) + httpData.hostName:=String(255) + httpData.xprInfo:=xprInfo + + StrCopy(httpData.hostName,httphost) + httpData.port:=httpport + StrCopy(httpData.workingPath,httppath) + + sb:=OpenLibrary('bsdsocket.library',2) + IF (sb) + StringF(temp,'\b\nHTTP processor started on \s port \d...\b\n',httpData.hostName,httpData.port) + aePuts(httpData,temp) + aePuts(httpData,'Use Ctrl-C to continue when transfers are complete\b\n\b\n') + + r,http_s:=openSocket(sb,httpport,1,httpData) + + flg:=FALSE + IF r + ioctlSocket(sb,http_s,FIONBIO,[1]) + rchar:=0 + WHILE (rchar<>3) + Delay(10) + rchar:=0 + IF sCheckInput(httpData) + rchar:=readChar(httpData) + ENDIF + EXIT rchar=3 + + http_c:=accept(sb,http_s,NIL,NIL) + IF(http_c< 0) + IF errno(sb)<>35 + StringF(temp,'/XHTTP: Error calling accept() errno=\d\b\n',errno(sb)) + aePuts(httpData,temp) + ENDIF + ELSE + flg:=TRUE + httpData.tcount:=httpData.tcount+1 + StringF(temp,'HTTP connection at port \d accepted\b\n', httpData.port) + aePuts(httpData,temp) + + StrCopy(getCmd,'') + StrCopy(postCmd,'') + WHILE(readLine(sb,http_c, request, MAX_LINE-1) > 0) + IF StrCmp(request,'GET ',4) THEN StrCopy(getCmd,request+4) + IF StrCmp(request,'POST ',5) THEN StrCopy(postCmd,request+5) + IF (InStr(request,'Content-Type:')>=0) AND (InStr(request,'multipart/form-data;')>=0) AND ((p:=InStr(request,'boundary='))>=0) + StrCopy(boundary,'\b\n--') + StrAdd(boundary,TrimStr(request+p+9)) + ENDIF + IF ((p:=InStr(request,'Content-Length:'))>=0) + contentLength:=Val(request+p+15) + ENDIF + ENDWHILE + + IF StrLen(getCmd)>0 + IF (spcPos:=InStr(getCmd,' '))>=0 THEN SetStr(getCmd,spcPos) + IF StrCmp(getCmd,'/',ALL) + generatePage(sb,http_c,httppath,xprInfo,node,uploadMode) + + ELSEIF (StrCmp(getCmd,'/',1)) + StringF(temp,'\s\s',httppath,getCmd+1) + + asynclib:=OpenLibrary('asyncio.library',0) + asynciobase:=asynclib + + IF httpData.fileStart<>NIL + fileStart(httpData,temp,FileLength(temp)) + ENDIF + + IF asynclib<>NIL + fh:=OpenAsync(temp,MODE_READ,32768) + ELSE + fh:=Open(temp,MODE_OLDFILE) + ENDIF + + IF fh>=0 + writeLineEx(sb,http_c,'HTTP/1.1 200 OK\b\n') + writeLineEx(sb,http_c,'content-type: binary/octet-stream\b\n') + writeLineEx(sb,http_c,'\b\n') + + buff:=New(32768) + t:=fastSystemTime() + lastpos:=0 + cps:=0 + + REPEAT + IF asynclib<>NIL + l:=ReadAsync(fh,buff,32768) + ELSE + l:=Fread(fh,buff,1,32768) + ENDIF + IF l>0 + writeLine(sb,http_c,buff,l) + IF (httpData.fileProgress<>NIL) + t2:=fastSystemTime() + ->only call update maximum every 1 second + IF (Abs(t2-t))>=50 + IF asynclib<>NIL + pos:=SeekAsync(fh,0,MODE_CURRENT) + ELSE + pos:=Seek(fh,0,OFFSET_CURRENT) + ENDIF + IF (tNIL + CloseAsync(fh) + ELSE + Close(fh) + ENDIF + IF httpData.fileEnd<>NIL + fileEnd(httpData,temp) + ENDIF + + ENDIF + ENDIF + ENDIF + + IF StrLen(postCmd)>0 + IF (spcPos:=InStr(postCmd,' '))>=0 THEN SetStr(postCmd,spcPos) + IF StrCmp(postCmd,'/',ALL) + extractFileData(sb,http_c,httpData,boundary,contentLength,asynclib) + generatePage(sb,http_c,httppath,xprInfo,node,uploadMode) + ENDIF + ENDIF + + r:=closeSocket(sb,http_c) + ENDIF + ENDWHILE + httpData.scount:=httpData.scount-1 + r:=closeSocket(sb,http_s) + ENDIF + IF flg THEN aePuts(httpData,'\b\n') + IF rchar=3 + aePuts(httpData,'CTRL-C detected, HTTP processor closed\b\n') + ELSE + aePuts(httpData,'HTTP transfers complete, all connections closed\b\n') + ENDIF + CloseLibrary(sb) + ENDIF + DisposeLink(httpData.hostName) + DisposeLink(httpData.workingPath) + END httpData +ENDPROC + diff --git a/icon2cfg.e b/icon2cfg.e index 9d41f0a..0fd8266 100644 --- a/icon2cfg.e +++ b/icon2cfg.e @@ -9,8 +9,6 @@ ENUM ERR_NOICON=1 ENUM SOURCE_ICON,SOURCE_CFG PROC main() HANDLE - DEF rdargs - DEF myargs:PTR TO LONG DEF tempstr[255]:STRING DEF inFile DEF sourceFile[255]:STRING diff --git a/jsonCreate.e b/jsonCreate.e new file mode 100644 index 0000000..8f6be8d --- /dev/null +++ b/jsonCreate.e @@ -0,0 +1,188 @@ +/* +JSON parser + +IF you are saving icons you must open icon library in advance + +*/ +OPT OSVERSION=37 +OPT MODULE + + MODULE 'dos/dos','workbench/workbench','icon','wb','dos/dosextens' + MODULE '*jsonParser','*miscfuncs' + +EXPORT PROC createdata(folderpath: PTR TO CHAR, js:PTR TO CHAR, t, count,doit,iconFiles=TRUE) + DEF i, j, k,s,n,s2,s3,l1,l2,tot,dobj:PTR TO diskobject + DEF fh,lock,toolTypes + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + DEF folderpath2[255]:ARRAY OF CHAR + DEF tok:PTR TO jsmntok_t,tok2:PTR TO jsmntok_t + IF (count = 0) + RETURN 0,NIL,0 + ENDIF + tok:=t + IF (tok.type = JSMN_PRIMITIVE) + IF js[tok.start]="n" + ->null + RETURN 1,js+tok.start,0 + ELSE + RETURN 1,js+tok.start,tok.end - tok.start + ENDIF + ELSEIF (tok.type = JSMN_STRING) + RETURN 1,js+tok.start,tok.end - tok.start + ELSEIF (tok.type = JSMN_OBJECT) + j:=0 + tot:=0 + FOR i:=0 TO tok.size-1 + n,s2,l1:=createdata(folderpath,js, t+((1+j)*SIZEOF jsmntok_t), count-j,FALSE,iconFiles) + j:=j+n + tot:=tot+l1 + + n,s2,l2:=createdata(folderpath,js, t+((1+j)*SIZEOF jsmntok_t), count-j,FALSE,iconFiles) + tok2:=t+((1+j)*SIZEOF jsmntok_t) + IF (tok2.type=JSMN_PRIMITIVE) OR (tok2.type=JSMN_STRING) + tot:=tot+l2+1 + ELSE + DisposeLink(s2) + ENDIF + j:=j+n + tot++ + ENDFOR + s:=String(tot) + j:=0 + FOR i:=0 TO tok.size-1 + n,s2,l1:=createdata(folderpath,js, t+((1+j)*SIZEOF jsmntok_t), count-j,doit,iconFiles) + j:=j+n + + AstrCopy(folderpath2,folderpath) + StrCopy(tempstr,s2,l1) + AddPart(folderpath2,tempstr,255) + + tok2:=t+((1+j)*SIZEOF jsmntok_t) + IF ((tok2.type=JSMN_OBJECT) OR (tok2.type=JSMN_ARRAY)) AND doit + lock:=CreateDir(folderpath) + IF lock + UnLock(lock) + ELSEIF IoErr()<>203 + WriteF('Could not create directory \s error \d\n',folderpath,IoErr()) + ENDIF + ENDIF + + n,s3,l2:=createdata(folderpath2,js, t+((1+j)*SIZEOF jsmntok_t), count-j,doit,iconFiles) + IF (tok2.type=JSMN_PRIMITIVE) OR (tok2.type=JSMN_STRING) + IF l2>0 + IF l1>0 + StrAdd(s,s2,l1) + StrAdd(s,'=') + ENDIF + StrAdd(s,s3,l2) + StrAdd(s,'\n') + ELSE + IF l1>0 + StrAdd(s,s2,l1) + StrAdd(s,'\n') + ENDIF + ENDIF + ELSE + IF l2<>0 + IF doit + + IF iconFiles + l1:=StrLen(s3) + tot:=0 + FOR k:=0 TO l1-1 + IF s3[k]="\n" + s3[k]:=0 + tot++ + ENDIF + ENDFOR + + toolTypes:=List(tot+1) + k:=0 + REPEAT + ListAdd(toolTypes,[s3+k]) + k:=k+StrLen(s3+k)+1 + tot-- + UNTIL tot=0 + ListAdd(toolTypes,[NIL]) + + dobj:=GetDiskObject(folderpath2) + IF dobj=NIL + IF findAssign('BBS:')=FALSE + StringF(tempstr2,'bbs:storage/icons/\s',tempstr) + dobj:=GetDiskObject(tempstr2) + IF dobj=NIL + IF dirExists(folderpath2) + StrCopy(tempstr,'bbs:storage/icons/drawer') + ELSE + StrCopy(tempstr,'bbs:storage/icons/default') + ENDIF + dobj:=GetDiskObject(tempstr) + ENDIF + ENDIF + IF dobj=NIL + IF dirExists(folderpath2) + dobj:=GetDefDiskObject(WBDRAWER) + ELSE + dobj:=GetDefDiskObject(WBTOOL) + ENDIF + ENDIF + IF dobj=NIL + WriteF('Could not create an icon for file \s.info\n',folderpath2) + ENDIF + ENDIF + IF dobj<>NIL + dobj.tooltypes:=toolTypes + IF PutDiskObject(folderpath2,dobj)=FALSE + WriteF('Could not write icon to file \s.info error \d\n',folderpath2,IoErr()) + ENDIF + FreeDiskObject(dobj) + ENDIF + END toolTypes + ELSE + StrCopy(tempstr,folderpath2) + StrAdd(tempstr,'.cfg') + fh:=Open(tempstr,MODE_NEWFILE) + IF fh>0 + Write(fh,s3,EstrLen(s3)) + Close(fh) + ELSE + WriteF('Could not write to file \s error \d\n',tempstr,IoErr()) + ENDIF + ENDIF + ENDIF + DisposeLink(s3) + ELSE + IF doit + lock:=CreateDir(folderpath2) + IF lock + UnLock(lock) + ELSEIF IoErr()<>203 + WriteF('Could not create directory \s error \d\n',folderpath2,IoErr()) + ENDIF + ENDIF + ENDIF + ENDIF + j:=j+n + ENDFOR + + RETURN j+1,s,EstrLen(s) + ELSEIF (tok.type = JSMN_ARRAY) + j:=0 + tot:=0 + FOR i:=0 TO tok.size-1 + n,s2,l1:=createdata(folderpath,js, t+((1+j)*SIZEOF jsmntok_t), count-j,FALSE,iconFiles) + j:=j+n + tot:=tot+l1+1 + ENDFOR + s:=String(tot) + j:=0 + FOR i:=0 TO tok.size-1 + n,s2,l1:=createdata(folderpath,js, t+((1+j)*SIZEOF jsmntok_t), count-j,TRUE,iconFiles) + j:=j+n + StrAdd(s,s2,l1) + StrAdd(s,'\n') + ENDFOR + RETURN j+1,s,EstrLen(s) + ENDIF +ENDPROC 0 diff --git a/jsonImport.e b/jsonImport.e index 09495d9..b2ce9be 100644 --- a/jsonImport.e +++ b/jsonImport.e @@ -4,7 +4,7 @@ JSON parser OPT OSVERSION=37 MODULE 'dos/dos','asl','libraries/asl','workbench/workbench','icon','wb', - '*jsonParser' + '*jsonParser','*jsonCreate' ENUM ERR_NONE, ERR_ASL, ERR_KICK, ERR_LIB @@ -13,7 +13,6 @@ RAISE ERR_ASL IF AllocAslRequest()=NIL, ERR_KICK IF KickVersion()=FALSE, ERR_LIB IF OpenLibrary()=NIL - PROC main() HANDLE DEF r DEF p:jsmn_parser @@ -42,7 +41,7 @@ PROC main() HANDLE FreeArgs(rdargs) ENDIF - WriteF('\nAmi-Express v5.0.0 BBS Import Tool (c)2018 Darren Coles\n\n') + WriteF('\nAmi-Express v5.3.0 BBS Import Tool (c)2018-2020 Darren Coles\n\n') aslbase:=OpenLibrary('asl.library',37) iconbase:=OpenLibrary('icon.library',33) diff --git a/jsonParser.e b/jsonParser.e index 3ba697f..09f9521 100644 --- a/jsonParser.e +++ b/jsonParser.e @@ -7,7 +7,7 @@ IF you are saving icons you must open icon library in advance OPT OSVERSION=37 OPT MODULE - MODULE 'dos/dos','workbench/workbench','icon','wb','dos/dosextens' +-> MODULE 'dos/dos','workbench/workbench','icon','wb','dos/dosextens' MODULE '*miscfuncs' @@ -24,7 +24,7 @@ CONST BUFSIZ = 8192 * o Other primitive: number, boolean (true/false) or NIL */ -ENUM JSMN_UNDEFINED = 0,JSMN_OBJECT = 1,JSMN_ARRAY = 2,JSMN_STRING = 3,JSMN_PRIMITIVE = 4 +EXPORT ENUM JSMN_UNDEFINED = 0,JSMN_OBJECT = 1,JSMN_ARRAY = 2,JSMN_STRING = 3,JSMN_PRIMITIVE = 4 EXPORT ENUM /* Not enough tokens were provided */ @@ -108,7 +108,7 @@ ENDPROC * Fills next available token with JSON primitive. */ PROC jsmn_parse_primitive(parser:PTR TO jsmn_parser, js: PTR TO CHAR,len,tokens, num_tokens) - DEF token:PTR TO jsmntok_t, start,i,ch,found + DEF token:PTR TO jsmntok_t, start,ch,found start:=parser.pos @@ -411,180 +411,3 @@ EXPORT PROC jsmn_init(parser:PTR TO jsmn_parser) parser.toknext:=0 parser.toksuper:=-1 ENDPROC - -EXPORT PROC createdata(folderpath: PTR TO CHAR, js:PTR TO CHAR, t, count,doit,iconFiles=TRUE) - DEF i, j, k,s,n,s2,s3,l1,l2,tot,dobj:PTR TO diskobject - DEF fh,lock,toolTypes - DEF tempstr[255]:STRING - DEF tempstr2[255]:STRING - DEF folderpath2[255]:ARRAY OF CHAR - DEF tok:PTR TO jsmntok_t,tok2:PTR TO jsmntok_t - IF (count = 0) - RETURN 0,NIL,0 - ENDIF - tok:=t - IF (tok.type = JSMN_PRIMITIVE) - IF js[tok.start]="n" - ->null - RETURN 1,js+tok.start,0 - ELSE - RETURN 1,js+tok.start,tok.end - tok.start - ENDIF - ELSEIF (tok.type = JSMN_STRING) - RETURN 1,js+tok.start,tok.end - tok.start - ELSEIF (tok.type = JSMN_OBJECT) - j:=0 - tot:=0 - FOR i:=0 TO tok.size-1 - n,s2,l1:=createdata(folderpath,js, t+((1+j)*SIZEOF jsmntok_t), count-j,FALSE,iconFiles) - j:=j+n - tot:=tot+l1 - - n,s2,l2:=createdata(folderpath,js, t+((1+j)*SIZEOF jsmntok_t), count-j,FALSE,iconFiles) - tok2:=t+((1+j)*SIZEOF jsmntok_t) - IF (tok2.type=JSMN_PRIMITIVE) OR (tok2.type=JSMN_STRING) - tot:=tot+l2+1 - ELSE - DisposeLink(s2) - ENDIF - j:=j+n - tot++ - ENDFOR - s:=String(tot) - j:=0 - FOR i:=0 TO tok.size-1 - n,s2,l1:=createdata(folderpath,js, t+((1+j)*SIZEOF jsmntok_t), count-j,doit,iconFiles) - j:=j+n - - AstrCopy(folderpath2,folderpath) - StrCopy(tempstr,s2,l1) - AddPart(folderpath2,tempstr,255) - - tok2:=t+((1+j)*SIZEOF jsmntok_t) - IF ((tok2.type=JSMN_OBJECT) OR (tok2.type=JSMN_ARRAY)) AND doit - lock:=CreateDir(folderpath) - IF lock - UnLock(lock) - ELSEIF IoErr()<>203 - WriteF('Could not create directory \s error \d\n',folderpath,IoErr()) - ENDIF - ENDIF - - n,s3,l2:=createdata(folderpath2,js, t+((1+j)*SIZEOF jsmntok_t), count-j,doit,iconFiles) - IF (tok2.type=JSMN_PRIMITIVE) OR (tok2.type=JSMN_STRING) - IF l2>0 - IF l1>0 - StrAdd(s,s2,l1) - StrAdd(s,'=') - ENDIF - StrAdd(s,s3,l2) - StrAdd(s,'\n') - ELSE - IF l1>0 - StrAdd(s,s2,l1) - StrAdd(s,'\n') - ENDIF - ENDIF - ELSE - IF l2<>0 - IF doit - - IF iconFiles - l1:=StrLen(s3) - tot:=0 - FOR k:=0 TO l1-1 - IF s3[k]="\n" - s3[k]:=0 - tot++ - ENDIF - ENDFOR - - toolTypes:=List(tot+1) - k:=0 - REPEAT - ListAdd(toolTypes,[s3+k]) - k:=k+StrLen(s3+k)+1 - tot-- - UNTIL tot=0 - ListAdd(toolTypes,[NIL]) - - dobj:=GetDiskObject(folderpath2) - IF dobj=NIL - IF findAssign('BBS:')=FALSE - StringF(tempstr2,'bbs:storage/icons/\s',tempstr) - dobj:=GetDiskObject(tempstr2) - IF dobj=NIL - IF dirExists(folderpath2) - StrCopy(tempstr,'bbs:storage/icons/drawer') - ELSE - StrCopy(tempstr,'bbs:storage/icons/default') - ENDIF - dobj:=GetDiskObject(tempstr) - ENDIF - ENDIF - IF dobj=NIL - IF dirExists(folderpath2) - dobj:=GetDefDiskObject(WBDRAWER) - ELSE - dobj:=GetDefDiskObject(WBTOOL) - ENDIF - ENDIF - IF dobj=NIL - WriteF('Could not create an icon for file \s.info\n',folderpath2) - ENDIF - ENDIF - IF dobj<>NIL - dobj.tooltypes:=toolTypes - IF PutDiskObject(folderpath2,dobj)=FALSE - WriteF('Could not write icon to file \s.info error \d\n',folderpath2,IoErr()) - ENDIF - FreeDiskObject(dobj) - ENDIF - END toolTypes - ELSE - StrCopy(tempstr,folderpath2) - StrAdd(tempstr,'.cfg') - fh:=Open(tempstr,MODE_NEWFILE) - IF fh>0 - Write(fh,s3,EstrLen(s3)) - Close(fh) - ELSE - WriteF('Could not write to file \s error \d\n',tempstr,IoErr()) - ENDIF - ENDIF - ENDIF - DisposeLink(s3) - ELSE - IF doit - lock:=CreateDir(folderpath2) - IF lock - UnLock(lock) - ELSEIF IoErr()<>203 - WriteF('Could not create directory \s error \d\n',folderpath2,IoErr()) - ENDIF - ENDIF - ENDIF - ENDIF - j:=j+n - ENDFOR - - RETURN j+1,s,EstrLen(s) - ELSEIF (tok.type = JSMN_ARRAY) - j:=0 - tot:=0 - FOR i:=0 TO tok.size-1 - n,s2,l1:=createdata(folderpath,js, t+((1+j)*SIZEOF jsmntok_t), count-j,FALSE,iconFiles) - j:=j+n - tot:=tot+l1+1 - ENDFOR - s:=String(tot) - j:=0 - FOR i:=0 TO tok.size-1 - n,s2,l1:=createdata(folderpath,js, t+((1+j)*SIZEOF jsmntok_t), count-j,TRUE,iconFiles) - j:=j+n - StrAdd(s,s2,l1) - StrAdd(s,'\n') - ENDFOR - RETURN j+1,s,EstrLen(s) - ENDIF -ENDPROC 0 diff --git a/mailssl.e b/mailssl.e new file mode 100644 index 0000000..580f7b6 --- /dev/null +++ b/mailssl.e @@ -0,0 +1,547 @@ +-> SSL and mail sending options + + OPT MODULE + + MODULE 'amissl','amisslmaster','socket','net/socket','net/in','net/netdb','*errors','*stringlist' + +CONST BIO_CTRL_FLUSH=11 +CONST BIO_FLAGS_BASE64_NO_NL=$100 +CONST BIO_CTRL_INFO=3 + +CONST AMISSLMASTER_MIN_VERSION=4 +CONST AMISSL_CURRENT_VERSION=6 + +CONST SSL_VERIFY_PEER=1 +CONST SSL_VERIFY_FAIL_IF_NO_PEER_CERT=2 + +CONST BIO_NOCLOSE=$0 +CONST BIO_FP_TEXT=$10 + +CONST OPENSSL_LINE=0 + +CONST BIO_SET_FILE_PTR=$6a ->dont know what this is + +CONST OPENSSL_INIT_LOAD_SSL_STRINGS=$200000 +CONST OPENSSL_INIT_LOAD_CRYPTO_STRINGS=2 + +CONST AMISSL_SOCKETBASE=$80000001 +CONST AMISSL_ERRNOPTR=$8000000B + +EXPORT OBJECT mailConfig + smtpHost[255]:ARRAY OF CHAR + smtpPort:LONG + username[255]:ARRAY OF CHAR + password[255]:ARRAY OF CHAR + sysopEmail[255]:ARRAY OF CHAR + bbsEmail[255]:ARRAY OF CHAR + ssl: INT + mailOnNewUser: INT + mailOnSysopComment: INT + mailOnSysopPage: INT +ENDOBJECT + +EXPORT DEF mailOptions: PTR TO mailConfig + +DEF sslerrno +DEF ctx: LONG ->PTR TO SSL_CTX +DEF bio_err: LONG ->PTR TO BIO + +EXPORT PROC sendMail(subject:PTR TO CHAR,bodytext:PTR TO CHAR, appendMsgBuf, msgBuf:PTR TO stringlist, lines, toemail:PTR TO CHAR) + DEF ssl,sock=0,errcode=0 + DEF buffer[4096]:STRING; /* This should be dynamically allocated */ + DEF bufsize=4096 + DEF request[512]:STRING + DEF failed=FALSE,v,i + + /* The following needs to be done once per socket */ + + /* Connect to the HTTPS server, directly or through a proxy */ + sock:=connectToServer(mailOptions.smtpHost,mailOptions.smtpPort) + + /* Check if connection was established */ + IF (sock >= 0) + IF ctx + IF((ssl:=SsL_new(ctx)) <> NIL) + + /* Associate the socket with the ssl structure */ + SsL_set_fd(ssl, sock) + + /* Perform SSL handshake */ + IF((errcode:=SsL_connect(ssl)) >= 0) + + IF ((errcode:=SsL_read(ssl, buffer,bufsize - 1)) >0) + buffer[errcode]:=0 + WriteF('\s \d \d\n',buffer, errcode, 1); + ELSE + WriteF('Couldn''t read initial server message!\n'); + ENDIF + + StrCopy(request,'EHLO relay.example.com\n') + IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) + WriteF('error sending EHLO\n'); + ENDIF + + IF((errcode:=SsL_read(ssl, buffer,bufsize - 1)) > 0) + buffer[errcode]:=0 + v:=Val(buffer) + failed:=((v<200) OR (v>299)) + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + + IF (failed=FALSE) + StringF(request,'\n\s\n\s',mailOptions.username,mailOptions.password) + v:=StrLen(request)-1 + FOR i:=0 TO v + IF request[i]="\n" THEN request[i]:=0 + ENDFOR + base64enc(request,EstrLen(request),buffer) + StringF(request,'AUTH PLAIN \s\n',buffer) + IF ((errcode:=SsL_write(ssl, request, EstrLen(request))) <=0 ) + WriteF('error sending AUTH\n'); + ENDIF + + IF((errcode:=SsL_read(ssl, buffer,bufsize - 1)) > 0) + buffer[errcode]:=0 + v:=Val(buffer) + failed:=((v<200) OR (v>299)) + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + ENDIF + + IF (failed=FALSE) + StringF(request,'mail from:<\s>\n',mailOptions.bbsEmail) + IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) + WriteF('error sending FROM\n'); + ENDIF + + IF((errcode:=SsL_read(ssl, buffer,bufsize - 1)) > 0) + buffer[errcode]:=0 + v:=Val(buffer) + failed:=((v<200) OR (v>299)) + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + ENDIF + + IF (failed=FALSE) + StringF(request,'rcpt to:<\s>\n',toemail) + IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) + WriteF('error sending TO\n'); + ENDIF + + IF((errcode:=SsL_read(ssl, buffer,bufsize - 1)) > 0) + buffer[errcode]:=0 + v:=Val(buffer) + failed:=((v<200) OR (v>299)) + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + ENDIF + + IF (failed=FALSE) + StrCopy(request,'DATA\n') + IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) + WriteF('error sending DATA\n'); + ENDIF + + IF((errcode:=SsL_read(ssl, buffer,bufsize - 1)) > 0) + buffer[errcode]:=0 + v:=Val(buffer) + failed:=(((v<200) OR (v>299)) AND (v<>354)) + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + ENDIF + + IF (failed=FALSE) + StrCopy(request,'From: <\s>\b\n',mailOptions.bbsEmail) + IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) + WriteF('error sending msg data\n'); + ENDIF + + StrCopy(request,'To: \b\n') + IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) + WriteF('error sending msg data\n'); + ENDIF + + StringF(request,'Subject: \s\b\n',subject) + IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) + WriteF('error sending msg data\n'); + ENDIF + + StrCopy(request,'\b\n') + IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) + WriteF('error sending msg data\n'); + ENDIF + + i:=0 + WHILE(i 0) + buffer[errcode]:=0 + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + + + StrCopy(request,'QUIT\n') + IF ((errcode:=SsL_write(ssl, request, StrLen(request))) <=0 ) + WriteF('error sending QUIT\n'); + ENDIF + ENDIF + ELSE + WriteF('Couldn''t establish SSL connection!\n'); + ENDIF + + /* If there were errors, print them */ + ->IF (errcode < 0) THEN ErR_print_errors(bio_err); + + /* Send SSL close notification and close the socket */ + SsL_shutdown(ssl); + + SsL_free(ssl); + ELSE + WriteF('Couldn''t create new SSL handle!\n'); + ENDIF + + + ELSE + ->standard unencrypted smtp + IF ((errcode:=Recv(sock,buffer,bufsize - 1,0)) >0) + buffer[errcode]:=0 + WriteF('\s \d \d\n',buffer, errcode, 1); + ELSE + WriteF('Couldn''t read initial server message!\n'); + ENDIF + + StrCopy(request,'EHLO relay.example.com\n') + IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) + WriteF('error sending EHLO\n'); + ENDIF + + IF((errcode:=Recv(sock, buffer,bufsize - 1,0)) > 0) + buffer[errcode]:=0 + v:=Val(buffer) + failed:=((v<200) OR (v>299)) + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + + IF (failed=FALSE) + StringF(request,'\n\s\n\s',mailOptions.username,mailOptions.password) + v:=StrLen(request)-1 + FOR i:=0 TO v + IF request[i]="\n" THEN request[i]:=0 + ENDFOR + base64enc(request,EstrLen(request),buffer) + StringF(request,'AUTH PLAIN \s\n',buffer) + IF ((errcode:=Send(sock, request, EstrLen(request),0)) <=0 ) + WriteF('error sending AUTH\n'); + ENDIF + + IF((errcode:=Recv(sock, buffer,bufsize - 1,0)) > 0) + buffer[errcode]:=0 + v:=Val(buffer) + failed:=((v<200) OR (v>299)) + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + ENDIF + + IF (failed=FALSE) + StringF(request,'mail from:<\s>\n',mailOptions.bbsEmail) + IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) + WriteF('error sending FROM\n'); + ENDIF + + IF((errcode:=Recv(sock, buffer,bufsize - 1,0)) > 0) + buffer[errcode]:=0 + v:=Val(buffer) + failed:=((v<200) OR (v>299)) + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + ENDIF + + IF (failed=FALSE) + StringF(request,'rcpt to:<\s>\n',toemail) + IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) + WriteF('error sending TO\n'); + ENDIF + + IF((errcode:=Recv(sock, buffer,bufsize - 1,0)) > 0) + buffer[errcode]:=0 + v:=Val(buffer) + failed:=((v<200) OR (v>299)) + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + ENDIF + + IF (failed=FALSE) + StrCopy(request,'DATA\n') + IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) + WriteF('error sending DATA\n'); + ENDIF + + IF((errcode:=Recv(sock, buffer,bufsize - 1,0)) > 0) + buffer[errcode]:=0 + v:=Val(buffer) + failed:=(((v<200) OR (v>299)) AND (v<>354)) + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + ENDIF + + IF (failed=FALSE) + StrCopy(request,'From: <\s>\b\n',mailOptions.bbsEmail) + IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) + WriteF('error sending msg data\n'); + ENDIF + + StrCopy(request,'To: \b\n') + IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) + WriteF('error sending msg data\n'); + ENDIF + + StringF(request,'Subject: \s\b\n',subject) + IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) + WriteF('error sending msg data\n'); + ENDIF + + StrCopy(request,'\b\n') + IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) + WriteF('error sending msg data\n'); + ENDIF + + i:=0 + WHILE(i 0) + buffer[errcode]:=0 + WriteF('\s \d \d\n',buffer, errcode, 1); + ENDIF + + + StrCopy(request,'QUIT\n') + IF ((errcode:=Send(sock, request, StrLen(request),0)) <=0 ) + WriteF('error sending QUIT\n'); + ENDIF + ENDIF + ENDIF + CloseSocket(sock); + ELSE + WriteF('Couldn''t connect to host!\n'); + ENDIF +ENDPROC + +PROC base64enc(data:PTR TO CHAR,len,output) + DEF b64 + DEF mem + DEF done=FALSE,res=0,outstr,strlen + -> bio is simply a class that wraps BIO* and it free the BIO in the destructor. + + b64:=BiO_new(BiO_f_base64()); ->// create BIO to perform base64 + BiO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + + mem:=BiO_new(BiO_s_mem()); ->// create BIO that holds the result + + ->// chain base64 with mem, so writing to b64 will encode base64 and write to mem. + BiO_push(b64, mem); + + ->// write data + WHILE(done=FALSE) + res:=BiO_write(b64, data, len); + + IF(res <= 0) -> if failed + IF(BiO_fd_should_retry(b64)=FALSE) + ->// encoding failed + /* Handle Error!!! */ + RETURN 0 + ENDIF + ELSE + ->// success! + done:=TRUE; + ENDIF + ENDWHILE + + BiO_ctrl(b64,BIO_CTRL_FLUSH,0,NIL) + + strlen:=BiO_ctrl(mem,BIO_CTRL_INFO,0,{outstr}) + + StrCopy(output,outstr,strlen) + BiO_free(mem) + BiO_free(b64) + +ENDPROC + +/* Open and initialize AmiSSL */ +EXPORT PROC initssl(createctx) HANDLE + DEF tags + + sslerrno:=0 + ctx:=0 + + bio_err:=0 + + IF socketbase=NIL THEN socketbase:=OpenLibrary('bsdsocket.library', 4) + IF (socketbase=NIL) + WriteF('Couldn''t open bsdsocket.library v4!\n') + Raise(ERR_SSL) + ENDIF + + amisslmasterbase:=OpenLibrary('amisslmaster.library',AMISSLMASTER_MIN_VERSION) + IF (amisslmasterbase=NIL) + WriteF('Couldn''t open amisslmaster.library v\d!\n',AMISSLMASTER_MIN_VERSION); + Raise(ERR_SSL) + ENDIF + + IF (InitAmiSSLMaster(AMISSL_CURRENT_VERSION, TRUE))=NIL + WriteF('AmiSSL version is too old!\n'); + Raise(ERR_SSL) + ENDIF + + amisslbase:=OpenAmiSSL() + IF (amisslbase=NIL) + WriteF('Couldn''t open AmiSSL!\n'); + Raise(ERR_SSL) + ENDIF + + tags:=NEW [AMISSL_ERRNOPTR,{sslerrno},AMISSL_SOCKETBASE,socketbase,0] + IF (InitAmiSSLA(tags) <> 0) + END tags + WriteF('Couldn''t initialize AmiSSL!\n'); + Raise(ERR_SSL) + ENDIF + END tags + + /* Basic intialization. Next few steps (up to SSL_new()) need + * to be done only once per AmiSSL opener. + */ + + OpENSSL_init_ssl(0,NIL) ->SSLeay_add_ssl_algorithms(); -$67C8(a6) + OpENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS OR OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NIL) ->SSL_load_error_strings(); + + /* Note: BIO writing routines are prepared for NULL BIO handle */ + IF((bio_err:=BiO_new(BiO_s_file())) <> NIL) THEN BiO_ctrl(bio_err, BIO_SET_FILE_PTR, BIO_NOCLOSE OR BIO_FP_TEXT, Output()); ->BiO_set_fp_amiga(bio_err, Output(), BIO_NOCLOSE OR BIO_FP_TEXT); + + /* Get a new SSL context */ + IF (createctx) + ctx:=SsL_CTX_new(TlS_client_method()) + IF (ctx=0) + WriteF('Couldn''t create ssl ctx!\n'); + Raise(ERR_SSL) + ENDIF + SsL_CTX_set_default_verify_paths(ctx); + SsL_CTX_set_verify(ctx, SSL_VERIFY_PEER OR SSL_VERIFY_FAIL_IF_NO_PEER_CERT,NIL); + ENDIF +EXCEPT + cleanupssl() + RETURN FALSE +ENDPROC TRUE + +EXPORT PROC cleanupssl() + IF ctx<>NIL + SsL_CTX_free(ctx); + ctx:=NIL + ENDIF + + IF bio_err<>NIL + BiO_free(bio_err) + bio_err:=NIL + ENDIF + + IF (amisslbase) + CleanupAmiSSLA([0]); + CloseAmiSSL(); + amisslbase:=NIL + ENDIF + + CloseLibrary(amisslmasterbase); + amisslmasterbase:=NIL; + + IF socketbase<>NIL THEN CloseLibrary(socketbase) + socketbase:=NIL; +ENDPROC + +/* Connect to the specified server, either directly or through the specified + * proxy using HTTP CONNECT method. + */ + +EXPORT PROC connectToServer(host:PTR TO CHAR, port) + DEF addr: PTR TO sockaddr_in + DEF is_ok = FALSE; + DEF sock=NIL; + DEF hostEnt: PTR TO hostent + DEF hostaddr: PTR TO LONG + + /* Create a socket and connect to the server */ + IF ((sock:=Socket(AF_INET, SOCK_STREAM, 0)) >= 0) + + hostEnt:=GetHostByName(host) + hostaddr:=hostEnt.h_addr_list[] + hostaddr:=hostaddr[] + + NEW addr + addr.sin_family:=AF_INET; + addr.sin_addr:=hostaddr[]; /* This should be checked against INADDR_NONE */ + addr.sin_port:=port->htons(port); + + IF (Connect(sock, addr, SIZEOF sockaddr_in) >= 0) + is_ok:=TRUE + ELSE + WriteF('Couldn''t connect to server\n'); + ENDIF + END addr + IF (is_ok=FALSE) + CloseSocket(sock); + sock:=-1; + ENDIF + ENDIF + +ENDPROC sock diff --git a/makefile b/makefile index e90060c..07437a8 100644 --- a/makefile +++ b/makefile @@ -1,40 +1,101 @@ # Compile ACP and EXPRESS and any dependencies -options=DEBUG IGNORECACHE +options=DEBUG IGNORECACHE NILCHECK +compiler=EC +expprogramname=AmiExpress +acpprogramname=ACP +version=5.3.0-beta -all: acp express5 jsonimport icon2cfg +all: acp express5 jsonimport icon2cfg qwk ftn release: options = IGNORECACHE -release: acp express5 jsonimport icon2cfg +release: acp express5 jsonimport icon2cfg qwk ftn -acp: acp.e axcommon.m miscfuncs.m jsonparser.m - ec acp $(options) +acp: acp.e acpversion.m axcommon.m jsonparser.m jsoncreate.m stringlist.m + $(compiler) acp $(options) -express5: express.e axcommon.m stringlist.m ftpd.m - ec express $(options) +express5: express.e expversion.m axcommon.m axconsts.m miscfuncs.m axobjects.m axenums.m stringlist.m errors.m mailssl.m ftpd.m httpd.m zmodem.m tooltypes.m pwdhash.m bcd.m + $(compiler) express $(options) copy express express5 delete express -ftpd.m: ftpd.e - ec ftpd $(options) +verinfogen: verinfogen.e + $(compiler) verinfogen $(options) + +ftn: ftn.e stringlist.m + $(compiler) ftn $(options) + +qwk: qwk.e stringlist.m + $(compiler) qwk $(options) icon2cfg: icon2cfg.e miscfuncs.m - ec icon2cfg $(options) + $(compiler) icon2cfg $(options) -jsonimport: jsonimport.e jsonparser.m - ec jsonimport $(options) +jsonimport: jsonimport.e jsonparser.m jsoncreate.m + $(compiler) jsonimport $(options) jsonparser.m: jsonparser.e miscfuncs.m - ec jsonparser $(options) + $(compiler) jsonparser $(options) + +jsoncreate.m: jsoncreate.e miscfuncs.m jsonparser.m + $(compiler) jsoncreate $(options) + +zmodem.m: zmodem.e + $(compiler) zmodem $(options) stringlist.m: stringlist.e - ec stringlist $(options) + $(compiler) stringlist $(options) + +miscfuncs.m: miscfuncs.e axconsts.m axenums.m errors.m + $(compiler) miscfuncs $(options) + +errors.m: errors.e + $(compiler) errors $(options) + +mailssl.m: mailssl.e + $(compiler) mailssl $(options) + +tooltypes.m: tooltypes.e + $(compiler) tooltypes $(options) + +pwdhash.m: pwdhash.e + $(compiler) pwdhash $(options) -miscfuncs.m: miscfuncs.e - ec miscfuncs $(options) +axcommon.m: axcommon.e stringlist.m + $(compiler) axcommon $(options) + +axconsts.m: axconsts.e + $(compiler) axconsts $(options) + +axobjects.m: axobjects.e axconsts.m + $(compiler) axobjects $(options) + +axenums.m: axenums.e + $(compiler) axenums $(options) + +expversion.m: expversion.e + $(compiler) expversion $(options) + +expversion.e: verinfogen + verinfogen expversion.e $(expprogramname) $(version) usedate + +acpversion.m: acpversion.e + $(compiler) acpversion $(options) + +acpversion.e: verinfogen + verinfogen acpversion.e $(acpprogramname) $(version) usedate + +bcd.m: bcd.e + $(compiler) bcd $(options) + +ftpd.m: ftpd.e + $(compiler) ftpd $(options) -axcommon.m : axcommon.e - ec axcommon $(options) +httpd.m: httpd.e axcommon.m stringlist.m + $(compiler) httpd $(options) -clean : - delete express express5 acp jsonimport icon2cfg miscfuncs.m jsonparser.m axcommon.m ftpd.m \ No newline at end of file +clean: + delete expversion.e acpversion.e delete express verinfogen express5 acp qwk ftn jsonimport icon2cfg miscfuncs.m stringlist.m errors.m mailssl.m jsoncreate.m jsonparser.m axcommon.m ftpd.m httpd.m axconsts.m axobjects.m axenums.m zmodem.m bcd.m expversion.m acpversion.m pwdhash.m tooltypes.m + +.PHONY: expversion.e + \ No newline at end of file diff --git a/modules/amissl.m b/modules/amissl.m index ce27360..6bb15c7 100644 Binary files a/modules/amissl.m and b/modules/amissl.m differ diff --git a/pwdhash.e b/pwdhash.e new file mode 100644 index 0000000..0ff684d --- /dev/null +++ b/pwdhash.e @@ -0,0 +1,89 @@ +-> password hash calculator + + OPT MODULE + +EXPORT PROC calcPasswordHash(pwd: PTR TO CHAR) + DEF hash + + MOVE.L pwd,A0 + BSR sub_486F0 + MOVE.L D0,hash + RETURN hash + +sub_486F0: + MOVEM.L D1-D7/A1-A6,-(A7) + MOVEA.L A0,A3 + MOVEQ #0,D0 + TST.B (A0) + BNE.W loc_48704 + MOVEM.L (A7)+,D1-D7/A1-A6 + RTS +-> --------------------------------------------------------------------------- + +loc_48704: + MOVEQ #0,D1 + +loc_48706: + MOVE.B (A0)+,D0 + TST.B D0 + BEQ.W loc_48712 + ADDQ.B #1,D1 + BRA.S loc_48706 +-> --------------------------------------------------------------------------- + +loc_48712: + MOVEA.L A3,A0 + MOVEA.L A0,A1 + MOVEA.L A0,A2 + LEA hashdata(PC),A1 + MOVE.L D1,D5 + + MOVEQ #0,D0 + MOVEQ #8,D2 + MOVEQ #$FFFFFFFF,D3 + MOVEQ #2,D4 + +loc_48726: + MOVEQ #0,D1 + MOVE.B (A0)+,D1 + EOR.B D0,D1 + AND.W D3,D1 + ASL.W D4,D1 + MOVE.L 0(A1,D1.L),D1 + LSR.L D2,D0 + EOR.L D1,D0 + SUBQ.L #1,D5 + BNE.S loc_48726 + SWAP D0 + NOT.W D0 + ROXL.L D0,D0 + NEG.L D0 + MOVEM.L (A7)+,D1-D7/A1-A6 + RTS +ENDPROC + +hashdata: + INT $0000,$0000,$7707,$3096,$EE0E,$612C,$9909,$51BA,$076D,$C419,$706A,$F48F,$E963,$A535,$9E64,$95A3,$0EDB,$8832,$79DC,$B8A4,$E0D5,$E91E, + $97D2,$D988,$09B6,$4C2B,$7EB1,$7CBD,$E7B8,$2D07,$90BF,$1D91,$1DB7,$1064,$6AB0,$20F2,$F3B9,$7148,$84BE,$41DE,$1ADA,$D47D,$6DDD,$E4EB, + $F4D4,$B551,$83D3,$85C7,$136C,$9856,$646B,$A8C0,$FD62,$F97A,$8A65,$C9EC,$1401,$5C4F,$6306,$6CD9,$FA0F,$3D63,$8D08,$0DF5,$3B6E,$20C8, + $4C69,$105E,$D560,$41E4,$A267,$7172,$3C03,$E4D1,$4B04,$D447,$D20D,$85FD,$A50A,$B56B,$35B5,$A8FA,$42B2,$986C,$DBBB,$C9D6,$ACBC,$F940, + $32D8,$6CE3,$45DF,$5C75,$DCD6,$0DCF,$ABD1,$3D59,$26D9,$30AC,$51DE,$003A,$C8D7,$5180,$BFD0,$6116,$21B4,$F4B5,$56B3,$C423,$CFBA,$9599, + $B8BD,$A50F,$2802,$B89E,$5F05,$8808,$C60C,$D9B2,$B10B,$E924,$2F6F,$7C87,$5868,$4C11,$C161,$1DAB,$B666,$2D3D,$76DC,$4190,$01DB,$7106, + $98D2,$20BC,$EFD5,$102A,$71B1,$8589,$06B6,$B51F,$9FBF,$E4A5,$E8B8,$D433,$7807,$C9A2,$0F00,$F934,$9609,$A88E,$E10E,$9818,$7F6A,$0DBB, + $086D,$3D2D,$9164,$6C97,$E663,$5C01,$6B6B,$51F4,$1C6C,$6162,$8565,$30D8,$F262,$004E,$6C06,$95ED,$1B01,$A57B,$8208,$F4C1,$F50F,$C457, + $65B0,$D9C6,$12B7,$E950,$8BBE,$B8EA,$FCB9,$887C,$62DD,$1DDF,$15DA,$2D49,$8CD3,$7CF3,$FBD4,$4C65,$4DB2,$6158,$3AB5,$51CE,$A3BC,$0074, + $D4BB,$30E2,$4ADF,$A541,$3DD8,$95D7,$A4D1,$C46D,$D3D6,$F4FB,$4369,$E96A,$346E,$D9FC,$AD67,$8846,$DA60,$B8D0,$4404,$2D73,$3303,$1DE5, + $AA0A,$4C5F,$DD0D,$7CC9,$5005,$713C,$2702,$41AA,$BE0B,$1010,$C90C,$2086,$5768,$B525,$206F,$85B3,$B966,$D409,$CE61,$E49F,$5EDE,$F90E, + $29D9,$C998,$B0D0,$9822,$C7D7,$A8B4,$59B3,$3D17,$2EB4,$0D81,$B7BD,$5C3B,$C0BA,$6CAD,$EDB8,$8320,$9ABF,$B3B6,$03B6,$E20C,$74B1,$D29A, + $EAD5,$4739,$9DD2,$77AF,$04DB,$2615,$73DC,$1683,$E363,$0B12,$9464,$3B84,$0D6D,$6A3E,$7A6A,$5AA8,$E40E,$CF0B,$9309,$FF9D,$0A00,$AE27, + $7D07,$9EB1,$F00F,$9344,$8708,$A3D2,$1E01,$F268,$6906,$C2FE,$F762,$575D,$8065,$67CB,$196C,$3671,$6E6B,$06E7,$FED4,$1B76,$89D3,$2BE0, + $10DA,$7A5A,$67DD,$4ACC,$F9B9,$DF6F,$8EBE,$EFF9,$17B7,$BE43,$60B0,$8ED5,$D6D6,$A3E8,$A1D1,$937E,$38D8,$C2C4,$4FDF,$F252,$D1BB,$67F1, + $A6BC,$5767,$3FB5,$06DD,$48B2,$364B,$D80D,$2BDA,$AF0A,$1B4C,$3603,$4AF6,$4104,$7A60,$DF60,$EFC3,$A867,$DF55,$316E,$8EEF,$4669,$BE79, + $CB61,$B38C,$BC66,$831A,$256F,$D2A0,$5268,$E236,$CC0C,$7795,$BB0B,$4703,$2202,$16B9,$5505,$262F,$C5BA,$3BBE,$B2BD,$0B28,$2BB4,$5A92, + $5CB3,$6A04,$C2D7,$FFA7,$B5D0,$CF31,$2CD9,$9E8B,$5BDE,$AE1D,$9B64,$C2B0,$EC63,$F226,$756A,$A39C,$026D,$930A,$9C09,$06A9,$EB0E,$363F, + $7207,$6785,$0500,$5713,$95BF,$4A82,$E2B8,$7A14,$7BB1,$2BAE,$0CB6,$1B38,$92D2,$8E9B,$E5D5,$BE0D,$7CDC,$EFB7,$0BDB,$DF21,$86D3,$D2D4, + $F1D4,$E242,$68DD,$B3F8,$1FDA,$836E,$81BE,$16CD,$F6B9,$265B,$6FB0,$77E1,$18B7,$4777,$8808,$5AE6,$FF0F,$6A70,$6606,$3BCA,$1101,$0B5C, + $8F65,$9EFF,$F862,$AE69,$616B,$FFD3,$166C,$CF45,$A00A,$E278,$D70D,$D2EE,$4E04,$8354,$3903,$B3C2,$A767,$2661,$D060,$16F7,$4969,$474D, + $3E6E,$77DB,$AED1,$6A4A,$D9D6,$5ADC,$40DF,$0B66,$37D8,$3BF0,$A9BC,$AE53,$DEBB,$9EC5,$47B2,$CF7F,$30B5,$FFE9,$BDBD,$F21C,$CABA,$C28A, + $53B3,$9330,$24B4,$A3A6,$BAD0,$3605,$CDD7,$0693,$54DE,$5729,$23D9,$67BF,$B366,$7A2E,$C461,$4AB8,$5D68,$1B02,$2A6F,$2B94,$B40B,$BE37, + $C30C,$8EA1,$5A05,$DF1B,$2D02,$EF8D,0 diff --git a/qwk.cfg b/qwk.cfg new file mode 100644 index 0000000..030d433 --- /dev/null +++ b/qwk.cfg @@ -0,0 +1,84 @@ +[MAIN] +MODE=OUT +BBSNAME=My BBS +BBSLOCATION=UK +BBSNUMBER=XXX-XXX-XXXX +BBSID=FREEWAY +SYSOPNAME=me +USERNAME=username +GETCMD=curl -o t:qwk.zip ftp://myusername:mysecretpass@freeway.apana.org/freeway.qwk +PUTCMD=curl -T t:{bbsid}.rep ftp://myusername:mypassword@freeway.apana.org/freeway.rep +UNPACKCMD=unzip t:qwk.zip MESSAGES.DAT -d t: +PACKCMD=zip t:{bbsid}.rep t:{bbsid}.MSG t:CONTROL.DAT +PACKEDTEMP=t:qwk.zip +MSGTEMP=t:MESSAGES.DAT +CONTROLTEMP=t:CONTROL.DAT +MSGFILE=t:{bbsid}.MSG +REPFILE=t:{bbsid}.rep +[CONFS] +11001 +RTN COMMOD +bbs:Conf05/MsgBase.1/ +11002 +RTN AMIGA +bbs:Conf05/MsgBase.2/ +11003 +RTN COL AD +bbs:Conf05/MsgBas +11004 +RTN ATARIP +bbs:Conf05/MsgBase.4/ +11005 +RTN BBSADS +bbs:Conf05/MsgBase.5/ +11006 +RTN GENERA +bbs:Conf05/MsgBase.6/ +11007 +RTN BUY SE +bbs:Conf05/MsgBase.7/ +11008 +RTN TEST +bbs:Conf05/MsgBase.8/ +11009 +RTN PC ALL +bbs:Conf05/MsgBase.9/ +11010 +RTN CONSOL +bbs:Conf05/MsgBase.10/ +11011 +RTN ADM +bbs:Conf05/MsgBase.11/ +11012 +RTN SUGGES +bbs:Conf05/MsgBase.12/ +11013 +RTN EMULAT +bbs:Conf05/MsgBase.13/ +11014 +RTN SINCLA +bbs:Conf05/MsgBase.14/ +11015 +RTN MSDOS +bbs:Conf05/MsgBase.15/ +11016 +RTN APPLE +bbs:Conf05/MsgBase.16/ +11017 +RTN RETROP +bbs:Conf05/MsgBase.17/ +11018 +RTN MAINFR +bbs:Conf05/MsgBase.18/ +11019 +RTN MYSTIC +bbs:Conf05/MsgBase.19/ +11020 +RTN SYNC +bbs:Conf05/MsgBase.20/ +11021 +RTN TI +bbs:Conf05/MsgBase.21/ +11022 +RTN CNET +bbs:Conf05/MsgBase.22/ \ No newline at end of file diff --git a/qwk.e b/qwk.e new file mode 100644 index 0000000..07b0acd --- /dev/null +++ b/qwk.e @@ -0,0 +1,756 @@ + + MODULE 'dos/dos','dos/dostags','dos/datetime' + MODULE '*stringlist' + + DEF confIds=NIL:PTR TO stringlist + DEF confNames=NIL:PTR TO stringlist + DEF msgBasePaths=NIL:PTR TO stringlist + DEF bbsName[255]:STRING + DEF bbsLocation[255]:STRING + DEF bbsNumber[255]:STRING + DEF sysopName[255]:STRING + DEF userName[255]:STRING + DEF bbsId[255]:STRING + DEF msgNum + + ENUM ERR_NOCFG,ERR_QWK_GRAB,ERR_QWK_UNPACK,ERR_QWK_PACK,ERR_WRITE_MAILSTAT,ERR_READ_MESSAGES_DAT,ERR_READ_MAILSTAT,ERR_READ_HEADERFILE + + CONST RESULT_SUCCESS=-1,RESULT_FAILURE=0 + +OBJECT qwkHeader + status:CHAR + num:LONG + to[26]:ARRAY OF CHAR + msgdate[14]:ARRAY OF CHAR + from[26]:ARRAY OF CHAR + subject[26]:ARRAY OF CHAR + password[13]:ARRAY OF CHAR + inReplyTo:LONG + blockCount:LONG + active: CHAR + confNum: INT + relativeMsgNum: INT + netTag: CHAR +ENDOBJECT + +OBJECT mailStat + lowestKey : LONG + highMsgNum : LONG + lowestNotDel : LONG + pad[6]:ARRAY OF CHAR +ENDOBJECT + +OBJECT mailHeader + status: CHAR + msgNumb: LONG + toName[31]: ARRAY OF CHAR + fromName[31]: ARRAY OF CHAR + subject[31]: ARRAY OF CHAR + msgDate: LONG + recv: LONG + pad: CHAR +ENDOBJECT + +PROC exec(fileName:PTR TO CHAR) + DEF tags,r + tags:=NEW [SYS_INPUT,0,SYS_OUTPUT,0,SYS_ASYNCH,FALSE,NIL]:LONG + r:=SystemTagList(fileName,tags) + IF r=-1 + WriteF('Error executing \s\n\n',fileName) + ENDIF + END tags +ENDPROC r + +PROC replacestr(sourcestring,searchtext,replacetext) + DEF newstring,tempstring,oldpos, pos,len + newstring:=String(255) + tempstring:=String(255) + len:=StrLen(searchtext) /* not estrlen since this is likely to be a hard coded constant */ + pos:=InStr(sourcestring,searchtext) + IF pos<>-1 + oldpos:=0 + WHILE pos<>-1 + IF pos<>oldpos + MidStr(tempstring,sourcestring,oldpos,pos-oldpos) + StrAdd(newstring,tempstring) + ENDIF + StrAdd(newstring,replacetext) + pos:=pos+len + oldpos:=pos + pos:=InStr(sourcestring,searchtext,oldpos) + ENDWHILE + pos:=EstrLen(sourcestring) + IF pos<>oldpos + MidStr(tempstring,sourcestring,oldpos,pos-oldpos) + StrAdd(newstring,tempstring) + ENDIF + StrCopy(sourcestring,newstring) + ENDIF + DisposeLink(newstring) + DisposeLink(tempstring) +ENDPROC + +PROC trimRight(src:PTR TO CHAR,dest:PTR TO CHAR) + DEF n,v=0 + StrCopy(dest,src) + n:=EstrLen(dest) + IF n>0 THEN v:=dest[n-1] + WHILE (n>0) AND (v=" ") + SetStr(dest,n-1) + n:=EstrLen(dest) + IF n>0 THEN v:=dest[n-1] + ENDWHILE +ENDPROC + +PROC fillStrCopy(src:PTR TO CHAR,dest:PTR TO CHAR,len) + DEF i + FOR i:=0 TO len-1 + dest[i]:=0 + ENDFOR + AstrCopy(dest,src,len) +ENDPROC + +PROC saveMh(fh,mailHeader) + DEF result + + result:=Write(fh,mailHeader,1) -> STATUS + result:=result+Write(fh,mailHeader+110,1) ->PAD + result:=result+Write(fh,mailHeader+2,4) ->MsgNum + result:=result+Write(fh,mailHeader+6,31) ->toName + result:=result+Write(fh,mailHeader+38,31) ->fromName + result:=result+Write(fh,mailHeader+70,31) ->subject + result:=result+Write(fh,mailHeader+110,1) ->PAD + result:=result+Write(fh,mailHeader+102,9) ->msgdate, recv & pad + result:=result+Write(fh,mailHeader+110,1) ->PAD +ENDPROC result + +PROC getMsgBasePath(confNum,msgBasePath:PTR TO CHAR) + DEF i + FOR i:=0 TO confIds.count()-1 + IF Val(confIds.item(i))=confNum + StrCopy(msgBasePath,msgBasePaths.item(i),ALL) + ENDIF + ENDFOR +ENDPROC + +PROC createMessageDat2(confNum,msgDatFilename:PTR TO CHAR, srcFilename:PTR TO CHAR) + DEF fh,fh2 + DEF tempStr[255]:STRING + DEF fromName[255]:STRING + DEF toName[255]:STRING + DEF subject[255]:STRING + DEF msgDateTime[255]:STRING + DEF msgDate[10]:STRING + DEF msgTime[10]:STRING + DEF msgId[20]:STRING + DEF msgbuf, msgsz,bufsz + DEF status,p,i + fh:=Open(msgDatFilename,MODE_READWRITE) + + IF fh>0 + Seek(fh,0,OFFSET_END) + IF Seek(fh,0,OFFSET_CURRENT)=0 + StringF(tempStr,'\l\s[128]',bbsId,'') + Write(fh,tempStr,128) + ENDIF + + fh2:=Open(srcFilename,MODE_OLDFILE) + IF fh2>0 + + ReadStr(fh2,fromName) + ReadStr(fh2,toName) + ReadStr(fh2,subject) + ReadStr(fh2,msgDateTime) + ReadStr(fh2,msgId) + + p:=Seek(fh2,0,OFFSET_END) + msgsz:=Seek(fh2,p,OFFSET_BEGINNING)-p + + bufsz:=(msgsz+127)/128*128 + msgbuf:=New(bufsz) + Read(fh2,msgbuf,msgsz) + FOR i:=msgsz TO bufsz-1 DO msgbuf[i]:=32 + Close(fh2) + + status:=" " + StrCopy(msgDate,msgDateTime,8) + IF (p:=InStr(msgDateTime,' '))>=0 + StrCopy(msgTime,msgDateTime+p+1,5) + ELSE + StrCopy(msgTime,'') + ENDIF + + StringF(tempStr,'\c\l\d[7]\l\s[8]\l\s[5]\l\s[25]\l\s[25]\l\s[25] \l\d[6]\c ',status,confNum, + msgDate,msgTime,toName,fromName,subject,(bufsz/128)+1,$E1) + tempStr[123]:=confNum AND $FF + tempStr[124]:=Shr(confNum,8) AND $FF + tempStr[125]:=msgNum AND $FF + tempStr[126]:=Shr(msgNum,8) AND $FF + + Write(fh,tempStr,128) + msgNum++ + + Write(fh,msgbuf,bufsz) + + Dispose(msgbuf) + ENDIF + Close (fh) + ENDIF +ENDPROC + +PROC createMessagesDat(msgFilename:PTR TO CHAR) + DEF i + DEF msgOutPath[255]:STRING + DEF fBlock:PTR TO fileinfoblock + DEF fLock + DEF msgFile[255]:STRING + DEF confNum + + IF(fBlock:=AllocDosObject(DOS_FIB,NIL)) + FOR i:=0 TO confIds.count()-1 + confNum:=Val(confIds.item(i)) + StringF(msgOutPath,'\sEXT-OUT',msgBasePaths.item(i)) + IF(fLock:=Lock(msgOutPath,ACCESS_READ)) + IF(Examine(fLock,fBlock)) + WHILE(ExNext(fLock,fBlock)) + StringF(msgFile,'\s/\s',msgOutPath,fBlock.filename) + createMessageDat2(confNum,msgFilename,msgFile) + SetProtection(msgFile,FIBF_OTR_DELETE) + DeleteFile(msgFile) + ENDWHILE + ENDIF + UnLock(fLock) + + ENDIF + ENDFOR + FreeDosObject(DOS_FIB,fBlock) + ENDIF + +ENDPROC + +PROC fileWriteLn(fh,str: PTR TO CHAR) + DEF stat + IF (stat:=fileWrite(fh,str))<>RESULT_SUCCESS THEN RETURN stat +ENDPROC fileWrite(fh,'\n') + +PROC fileWrite(fh,str: PTR TO CHAR) + DEF s + + s:=Write(fh,str,StrLen(str)) + IF s<>StrLen(str) THEN RETURN RESULT_FAILURE +ENDPROC RESULT_SUCCESS + +PROC formatLongDateTime2(cDateVal,outDateStr,seperatorChar) + DEF d : PTR TO datestamp + DEF dt : datetime + DEF datestr[10]:STRING + DEF timestr[10]:STRING + DEF dateVal + + dateVal:=cDateVal-21600 + + d:=dt.stamp + d.tick:=(dateVal-Mul(Div(dateVal,60),60)) + d.tick:=Mul(d.tick,50) + dateVal:=Div(dateVal,60) + d.days:=Div((dateVal),1440)-2922 ->-2922 days between 1/1/70 and 1/1/78 + d.minute:=dateVal-(Mul(d.days+2922,1440)) + + dt.format:=FORMAT_USA + dt.flags:=0 + dt.strday:=0 + dt.strdate:=datestr + dt.strtime:=timestr + + IF DateToStr(dt) + StringF(outDateStr,'\s\c\s',datestr,seperatorChar,timestr) + RETURN TRUE + ENDIF +ENDPROC FALSE + +PROC createControlDat(controlFilename:PTR TO CHAR) + DEF fo,conf + DEF tempstr[255]:STRING + + fo:=Open(controlFilename,MODE_NEWFILE) + IF(fo=0) + RETURN 0 + ENDIF + + fileWriteLn(fo,bbsName) + fileWriteLn(fo,bbsLocation) + fileWriteLn(fo,bbsNumber) + StringF(tempstr,'\s, Sysop',sysopName) + fileWriteLn(fo,tempstr) + + StringF(tempstr,'000000,\s',bbsId) + fileWriteLn(fo,tempstr) + + formatLongDateTime2(getSystemTime(),tempstr,",") + fileWriteLn(fo,tempstr) + + fileWriteLn(fo,userName) + + fileWriteLn(fo,'') + fileWriteLn(fo,'0') + fileWriteLn(fo,'0') + + StringF(tempstr,'\d\b\n',confIds.count()) + fileWrite(fo,tempstr) + FOR conf:=0 TO confIds.count()-1 + StringF(tempstr,'\s\b\n',confIds.item(conf)) + fileWrite(fo,tempstr) + StringF(tempstr,'\s',confNames.item(conf)) + IF StrLen(tempstr)>10 THEN SetStr(tempstr,10) + StrAdd(tempstr,'\b\n') + fileWrite(fo,tempstr) + ENDFOR + fileWrite(fo,'HELLO\b\n') + fileWrite(fo,'NEWS\b\n') + fileWrite(fo,'GOODBYE\b\n') + Close(fo) +ENDPROC + +->returns system time converted to c time format +PROC getSystemTime() + DEF currDate: datestamp + DEF startds:PTR TO datestamp + DEF s1,s2,s3,s4 + + startds:=DateStamp(currDate) + + s1:=startds.days+2922 + s1:=Mul(1440,s1) + s1:=Mul(60,s1) + s2:=Mul(60,startds.minute) + s3:=startds.tick/50 + s4:=Mul(Mul(startds.days+2922,1440),60)+(startds.minute*60)+(startds.tick/50) + + ->2922 days between 1/1/70 and 1/1/78 + +ENDPROC s4+21600 + + +PROC getEncodedDate(dateStr:PTR TO CHAR) + DEF dt:datetime + DEF strDate[20]:STRING + DEF strTime[20]:STRING + DEF dval + + + StrCopy(strDate,dateStr,8) + StrCopy(strTime,dateStr+8,5) + StrAdd(strTime,':00') + + dt.format:=FORMAT_USA + dt.flags:=0 + dt.strday:=0 + dt.strdate:=strDate + dt.strtime:=strTime + + IF StrToDate(dt)=0 THEN RETURN 0 + + dval:=Mul(Mul(dt.stamp.days+2922,1440),60)+(dt.stamp.minute*60)+(dt.stamp.tick/50) + + ->2922 days between 1/1/70 and 1/1/78 + +ENDPROC dval+21600 + +PROC trimStr(src:PTR TO CHAR) + DEF i + DEF tempStr[255]:STRING + + StrCopy(tempStr,TrimStr(src)) + + i:=EstrLen(tempStr)-1 + WHILE (i>=0) + IF tempStr[i]<>" " + i:=-1 + ELSE + SetStr(tempStr,i) + i-- + ENDIF + ENDWHILE + + StrCopy(src,tempStr) +ENDPROC + +PROC processConfigLine(inString,categoryStr,optName,optValue) + DEF t[255]:STRING + DEF l + StrCopy(t,inString) + trimStr(t) + l:=EstrLen(t) + IF l>1 + IF (t[0]="[") AND (t[l-1]="]") + StrCopy(categoryStr,t+1,l-2) + trimStr(categoryStr) + UpperStr(categoryStr) + StrCopy(optName,'') + StrCopy(optValue,'') + RETURN + ENDIF + ENDIF + l:=InStr(t,'=') + IF l>0 + StrCopy(optName,t,l) + trimStr(optName) + UpperStr(optName) + StrCopy(optValue,t+l+1,ALL) + trimStr(optValue) + ELSE + StrCopy(optName,'') + StrCopy(optValue,'') + ENDIF +ENDPROC + +PROC main() HANDLE + DEF qh: qwkHeader + DEF ms: mailStat + DEF mh: mailHeader + DEF buf=0:PTR TO CHAR + DEF buf2=0:PTR TO CHAR,bufsz + DEF mf=0,fh=0,fh2=0 + DEF n,c,i + DEF tempStr[255]:STRING + DEF newMsgNum + DEF fname[255]:STRING + DEF msgBase[255]:STRING + DEF qwkConfId + DEF lastConfId=-1 + DEF mode[255]:STRING + DEF qwkFilename[255]:STRING + DEF qwkGetCommand[255]:STRING + DEF qwkPutCommand[255]:STRING + DEF qwkPackCommand[255]:STRING + DEF qwkUnpackCommand[255]:STRING + DEF qwkMessageFilename[255]:STRING + DEF qwkControlFilename[255]:STRING + DEF qwkRepMessageFilename[255]:STRING + DEF qwkOutputFilename[255]:STRING + DEF cfgFile[255]:STRING + DEF needToSave + DEF myargs:PTR TO LONG,rdargs + + DEF category[255]:STRING + DEF optionName[255]:STRING + DEF optionValue[255]:STRING + + WriteF('Ami-Express QWK file processor Copyright 2020 Darren Coles\n') + + myargs:=[0,0]:LONG + IF rdargs:=ReadArgs('CFG/A',myargs,NIL) + IF myargs[0]<>NIL + AstrCopy(cfgFile,myargs[0],255) + ENDIF + FreeArgs(rdargs) + ELSE + RETURN + ENDIF + + confIds:=NEW confIds.stringlist(100) + confNames:=NEW confNames.stringlist(100) + msgBasePaths:=NEW msgBasePaths.stringlist(100) + + fh:=Open(cfgFile,MODE_OLDFILE) + IF fh>0 + + REPEAT + ReadStr(fh,tempStr) + processConfigLine(tempStr,category,optionName,optionValue) + + IF StrCmp('MAIN',category) AND StrCmp('MODE',optionName) THEN StrCopy(mode,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('BBSNAME',optionName) THEN StrCopy(bbsName,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('BBSLOCATION',optionName) THEN StrCopy(bbsLocation,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('BBSNUMBER',optionName) THEN StrCopy(bbsNumber,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('BBSID',optionName) THEN StrCopy(bbsId,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('SYSOPNAME',optionName) THEN StrCopy(sysopName,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('USERNAME',optionName) THEN StrCopy(userName,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('GETCMD',optionName) THEN StrCopy(qwkGetCommand,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('PUTCMD',optionName) THEN StrCopy(qwkPutCommand,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('UNPACKCMD',optionName) THEN StrCopy(qwkUnpackCommand,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('PACKCMD',optionName) THEN StrCopy(qwkPackCommand,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('PACKEDTEMP',optionName) THEN StrCopy(qwkFilename,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('MSGTEMP',optionName) THEN StrCopy(qwkMessageFilename,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('CONTROLTEMP',optionName) THEN StrCopy(qwkControlFilename,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('MSGFILE',optionName) THEN StrCopy(qwkRepMessageFilename,optionValue) + IF StrCmp('MAIN',category) AND StrCmp('REPFILE',optionName) THEN StrCopy(qwkOutputFilename,optionValue) + + UNTIL StrCmp(category,'CONFS') + UpperStr(mode) + + replacestr(qwkGetCommand,'{bbsid}',bbsId) + replacestr(qwkPutCommand,'{bbsid}',bbsId) + replacestr(qwkUnpackCommand,'{bbsid}',bbsId) + replacestr(qwkPackCommand,'{bbsid}',bbsId) + replacestr(qwkFilename,'{bbsid}',bbsId) + replacestr(qwkMessageFilename,'{bbsid}',bbsId) + replacestr(qwkControlFilename,'{bbsid}',bbsId) + replacestr(qwkRepMessageFilename,'{bbsid}',bbsId) + replacestr(qwkOutputFilename,'{bbsid}',bbsId) + + WHILE(ReadStr(fh,tempStr)<>-1) OR (StrLen(tempStr)>0) + confIds.add(tempStr) + ReadStr(fh,tempStr) + confNames.add(tempStr) + ReadStr(fh,tempStr) + msgBasePaths.add(tempStr) + ENDWHILE + Close(fh) + fh:=0 + ELSE + WriteF('Error opening Qwk.cfg\n\n') + Raise(ERR_NOCFG) + ENDIF + + IF StrCmp(mode,'OUT') OR StrCmp(mode,'BOTH') + WriteF('Processing outgoing messages\n') + IF FileLength(qwkOutputFilename)=-1 + ->no qwk output file so create item + + msgNum:=1 + + DeleteFile(qwkRepMessageFilename) + DeleteFile(qwkControlFilename) + + ->create messages.dat by scraping confs + createMessagesDat(qwkRepMessageFilename) + + createControlDat(qwkControlFilename) + + IF FileLength(qwkRepMessageFilename)<>-1 + exec(qwkPackCommand) + + IF FileLength(qwkOutputFilename)=-1 + WriteF('Error packing qwk file\n\n') + Raise(ERR_QWK_PACK) + ENDIF + ENDIF + DeleteFile(qwkRepMessageFilename) + DeleteFile(qwkControlFilename) + ELSE + WriteF('Processing already existing qwk output file (\s)\n\n',qwkOutputFilename) + ENDIF + + IF FileLength(qwkOutputFilename)<>-1 + IF exec(qwkPutCommand)=0 + DeleteFile(qwkOutputFilename) + ELSE + WriteF('Failure when sending qwk file to remote server\n\n') + ENDIF + ELSE + WriteF('No messages to post\n\n') + ENDIF + ENDIF + + IF StrCmp(mode,'IN') OR StrCmp(mode,'BOTH') + WriteF('Processing incoming messages\n') + + IF FileLength(qwkFilename)=-1 + ->no qwk file to process so grab a new one + + exec(qwkGetCommand) + IF FileLength(qwkFilename)=-1 + WriteF('No qwk file to process\n\n') + Raise(ERR_QWK_GRAB) + ENDIF + + ELSE + WriteF('Processing already existing qwk file (\s)\n\n',qwkFilename) + ENDIF + + DeleteFile(qwkMessageFilename) + exec(qwkUnpackCommand) + + IF FileLength(qwkMessageFilename)=-1 + WriteF('Error unpacking qwk file\n\n') + Raise(ERR_QWK_UNPACK) + ENDIF + DeleteFile(qwkFilename) + + needToSave:=FALSE + mf:=Open(qwkMessageFilename,MODE_OLDFILE) + IF mf>0 + Seek(mf,128,OFFSET_BEGINNING) + buf:=New(128) + c:=0 + REPEAT + n:=Read(mf,buf,128) + IF n>0 + qh.status:=buf[0] + StrCopy(tempStr,buf+1,7) + qh.num:=Val(tempStr) + AstrCopy(qh.msgdate,buf+8,14) + AstrCopy(qh.to,buf+21,26) + AstrCopy(qh.from,buf+46,26) + AstrCopy(qh.subject,buf+71,26) + AstrCopy(qh.password,buf+96,13) + StrCopy(tempStr,buf+108,8) + qh.inReplyTo:=Val(tempStr) + StrCopy(tempStr,buf+116,8) + qh.blockCount:=Val(tempStr) + qh.active:=buf[122] + qh.confNum:=buf[123]+(256*buf[124]) + qh.relativeMsgNum:=buf[125]+(256*buf[126]) + qh.netTag:=buf[127] + bufsz:=128*(qh.blockCount-1) + WriteF('id: \d\n',c) + WriteF('message: \d\n',qh.num) + WriteF('conf: \d\n',qh.confNum) + WriteF('to: \s\n',qh.to) + WriteF('from: \s\n',qh.from) + WriteF('subject: \s\n',qh.subject) + WriteF('\n') + + IF qh.confNum<>lastConfId + + IF fh>0 + Close(fh) + fh:=0 + ENDIF + IF needToSave + ms.highMsgNum:=newMsgNum+1 + StringF(fname,'\sMailStats',msgBase) + fh:=Open(fname,MODE_NEWFILE) + IF fh>0 + Write(fh,ms,SIZEOF mailStat) + Close(fh) + fh:=0 + ELSE + WriteF('Error saving MailStats\n\n') + Raise(ERR_WRITE_MAILSTAT) + ENDIF + needToSave:=FALSE + ENDIF + + getMsgBasePath(qh.confNum,msgBase) + IF StrLen(msgBase)=0 + WriteF('Qwk conf \d not configured, skipping messages for this conf\n\n',qh.confNum) + qwkConfId:=-1 + ELSE + qwkConfId:=qh.confNum + + StringF(fname,'\sMailStats',msgBase) + IF fh>0 THEN Close(fh) + fh:=Open(fname,MODE_READWRITE) + IF fh>0 + IF Read(fh,ms,SIZEOF mailStat)=0 + ms.lowestKey:=1 + ms.lowestNotDel:=1 + ms.highMsgNum:=1 + ms.pad[0]:=0;ms.pad[1]:=0;ms.pad[2]:=0;ms.pad[3]:=0;ms.pad[4]:=0;ms.pad[5]:=0 + Write(fh,ms,SIZEOF mailStat) + Close(fh) + fh:=0 + ELSE + Close(fh) + fh:=0 + ENDIF + ELSE + WriteF('Error opening MailStats (\s)\n\n',fname) + Raise(ERR_READ_MAILSTAT) + ENDIF + + newMsgNum:=ms.highMsgNum-1 + StringF(fname,'\sHeaderFile',msgBase) + fh:=Open(fname,MODE_READWRITE) + IF fh>0 + Seek(fh,0,OFFSET_END) + ELSE + WriteF('Error opening HeaderFile\n\n') + Raise(ERR_READ_HEADERFILE) + ENDIF + + ENDIF + + ENDIF + + lastConfId:=qh.confNum + + IF qh.confNum=qwkConfId + newMsgNum++ + + buf2:=New(bufsz) + Read(mf,buf2,bufsz) + + mh.pad:=0 + mh.status:="P" + mh.msgNumb:=newMsgNum + + trimRight(qh.to,tempStr) + fillStrCopy(tempStr,mh.toName,31) + + trimRight(qh.from,tempStr) + fillStrCopy(tempStr,mh.fromName,31) + + trimRight(qh.subject,tempStr) + fillStrCopy(tempStr,mh.subject,31) + + mh.msgDate:=getEncodedDate(qh.msgdate) + mh.recv:=0 + + IF saveMh(fh,mh)<>110 + WriteF('Error saving mail header for message \d\n',newMsgNum) + ENDIF + + needToSave:=TRUE + + StringF(fname,'\s\d',msgBase,newMsgNum) + fh2:=Open(fname,MODE_NEWFILE) + IF fh2>0 + FOR i:=0 TO bufsz-1 + IF buf2[i]=$e3 THEN buf2[i]:=10 + ENDFOR + Write(fh2,buf2,bufsz) + Close(fh2) + fh2:=0 + ELSE + WriteF('Error saving message body for message \d\n\n',newMsgNum) + ENDIF + Dispose(buf2) + buf2:=0 + ELSE + Seek(mf,bufsz,OFFSET_CURRENT) + ENDIF + ENDIF + c++ + UNTIL (n=0) OR (CtrlC()) + + Close(fh) + fh:=0 + + IF needToSave + ms.highMsgNum:=newMsgNum+1 + StringF(fname,'\sMailStats',msgBase) + fh:=Open(fname,MODE_NEWFILE) + IF fh>0 + Write(fh,ms,SIZEOF mailStat) + Close(fh) + fh:=0 + ELSE + WriteF('Error saving MailStats\n\n') + Raise(ERR_WRITE_MAILSTAT) + ENDIF + needToSave:=FALSE + ENDIF + + IF mf>0 THEN Close(mf) + mf:=0 + DeleteFile(qwkMessageFilename) + + ELSE + WriteF('Error opening MESSAGES.DAT\n\n') + Raise(ERR_READ_MESSAGES_DAT) + ENDIF + ENDIF + +EXCEPT DO + IF confIds<>NIL THEN END confIds + IF confNames<>NIL THEN END confNames + IF msgBasePaths<>NIL THEN END msgBasePaths + IF fh>0 THEN Close(fh) + IF fh2>0 THEN Close(fh2) + IF mf>0 THEN Close(mf) + IF buf<>0 THEN Dispose(buf) + IF buf2<>0 THEN Dispose(buf2) +ENDPROC \ No newline at end of file diff --git a/stringlist.e b/stringlist.e index e282e61..ab0e422 100644 --- a/stringlist.e +++ b/stringlist.e @@ -23,6 +23,7 @@ EXPORT PROC stringlist(maxSize=-1) OF stringlist ->constructor ENDPROC EXPORT PROC item(n) OF stringlist + ->IF (n<0) OR (n>=ListLen(self.items)) THEN WriteF('stringlist index error \d',n) ENDPROC self.items[n] EXPORT PROC clear() OF stringlist @@ -50,6 +51,22 @@ EXPORT PROC expand() OF stringlist DisposeLink(old) ENDPROC len +EXPORT PROC insert(pos,stringVal:PTR TO CHAR) OF stringlist + DEF s,c,i + + c:=ListLen(self.items) + IF c=ListMax(self.items) THEN self.expand() + ListAdd(self.items,[NIL]) + + FOR i:=ListLen(self.items)-1 TO (pos+1) STEP -1 + self.items[i]:=self.items[i-1] + ENDFOR + s:=String(StrLen(stringVal)) + StrCopy(s,stringVal) + self.items[pos]:=s +ENDPROC + + EXPORT PROC add(stringVal:PTR TO CHAR) OF stringlist DEF s,c @@ -117,10 +134,10 @@ EXPORT PROC stdlist(maxSize=-1) OF stdlist ->constructor ENDPROC EXPORT PROC item(n) OF stdlist + ->IF (n<0) OR (n>=ListLen(self.items)) THEN WriteF('stdlist index error \d',n) ENDPROC self.items[n] EXPORT PROC clear() OF stdlist - DEF i IF ListMax(self.items)>self.initialMax DisposeLink(self.items) self.items:=List(self.initialMax) @@ -142,7 +159,7 @@ EXPORT PROC expand() OF stdlist ENDPROC len EXPORT PROC add(v:LONG) OF stdlist - DEF s,c + DEF c c:=ListLen(self.items) IF c=ListMax(self.items) THEN self.expand() diff --git a/tooltypes.e b/tooltypes.e new file mode 100644 index 0000000..c05b278 --- /dev/null +++ b/tooltypes.e @@ -0,0 +1,377 @@ +/* tooltypes helper functions */ + + OPT MODULE + + MODULE 'workbench/workbench','icon','dos/dos' + MODULE '*axcommon','*axenums','*axobjects','*stringlist','*miscfuncs' + +->all of the below are globals shared with express.e +->must be changed in both places +EXPORT DEF cmds:PTR TO commands +EXPORT DEF confDirs: PTR TO stringlist +EXPORT DEF currentConf +EXPORT DEF currentConfDir:PTR TO CHAR +EXPORT DEF fCheckDir:PTR TO CHAR +EXPORT DEF xprLib: PTR TO stringlist +EXPORT DEF diskObjectCache:PTR TO stdlist +EXPORT DEF node +EXPORT DEF cacheTests +EXPORT DEF cacheHits +EXPORT DEF loggedOnUser: PTR TO user + +EXPORT PROC getNodeFile(toolType,tooltypeSelector,nodeFile) + DEF tempStr[255]:STRING + DEF tempStr2[255]:STRING + DEF i,p + + SELECT toolType + CASE TOOLTYPE_NODE + -> tooltypeSector is node number + StringF(nodeFile,'\sNode\d',cmds.bbsLoc,tooltypeSelector) + CASE TOOLTYPE_WINDOW + -> tooltypeSector is node number + StringF(nodeFile,'\sNode\d/WINDOW.DEF',cmds.bbsLoc,tooltypeSelector) + CASE TOOLTYPE_CONFCONFIG + -> tooltypeSector is not used + StringF(nodeFile,'\sConfconfig',cmds.bbsLoc) + CASE TOOLTYPE_BBSCONFIG + -> tooltypeSector is not used + StringF(nodeFile,'\sbbsConfig',cmds.bbsLoc) + CASE TOOLTYPE_NAMESNOTALLOWED + -> tooltypeSector is not used + StringF(nodeFile,'\sNamesNotAllowed',cmds.bbsLoc) + CASE TOOLTYPE_CONF + -> tooltypeSector is conf number + ->get conf location + StringF(tempStr,'LOCATION.\d',tooltypeSelector) + readToolType(TOOLTYPE_CONFCONFIG,'',tempStr,tempStr2) + IF tempStr2[StrLen(tempStr2)-1]="/" THEN SetStr(tempStr2,StrLen(tempStr2)-1) + StringF(nodeFile,'\s',tempStr2) + CASE TOOLTYPE_MSGBASE + -> tooltypeSector is conf number + ->get conf location + StrCopy(tempStr,confDirs.item(tooltypeSelector-1)) ->getConfLocation(tooltypeSelector,tempStr) + StringF(nodeFile,'\sMsgBases',tempStr) + CASE TOOLTYPE_BBSCMD + -> tooltypeSector is command name string + StringF(nodeFile,'\sCommands/BBSCmd/\s',cmds.bbsLoc,tooltypeSelector) + CASE TOOLTYPE_CONFCMD + -> tooltypeSector is command name string + StringF(nodeFile,'\sCommands/Conf\dCmd/\s',cmds.bbsLoc,currentConf,tooltypeSelector) + CASE TOOLTYPE_CONFCMD2 + -> tooltypeSector is command name string + StringF(nodeFile,'\s\s',currentConfDir,tooltypeSelector) + CASE TOOLTYPE_NODECMD + -> tooltypeSector is command name string + StringF(nodeFile,'\sCommands/Node\dCmd/\s',cmds.bbsLoc,node,tooltypeSelector) + CASE TOOLTYPE_CONFSYSCMD + -> tooltypeSector is command name string + StringF(nodeFile,'\sCommands/Conf\dSysCmd/\s',cmds.bbsLoc,currentConf,tooltypeSelector) + CASE TOOLTYPE_NODESYSCMD + -> tooltypeSector is command name string + StringF(nodeFile,'\sCommands/Node\dSysCmd/\s',cmds.bbsLoc,node,tooltypeSelector) + CASE TOOLTYPE_SYSCMD + -> tooltypeSector is command name string + StringF(nodeFile,'\sCommands/SYSCmd/\s',cmds.bbsLoc,tooltypeSelector) + CASE TOOLTYPE_DRIVES + -> tooltypeSector is not used + StringF(nodeFile,'\sDrives',cmds.bbsLoc) + CASE TOOLTYPE_COMPUTERLIST + -> tooltypeSector is not used + StringF(nodeFile,'\sComputerList',cmds.bbsLoc) + CASE TOOLTYPE_DEFAULT_ACCESS + -> tooltypeSector is not used + StringF(nodeFile,'\sAccess',cmds.bbsLoc) + CASE TOOLTYPE_USER_ACCESS + -> tooltypeSector is not used + getUserAccessFilename(nodeFile) + CASE TOOLTYPE_ACCESS + -> tooltypeSector is access level number + StringF(nodeFile,'\sAccess/ACS.\d',cmds.bbsLoc,tooltypeSelector) + CASE TOOLTYPE_AREA + -> tooltypeSector is access area name + StringF(nodeFile,'\sAccess/AREA.\s',cmds.bbsLoc,tooltypeSelector) + CASE TOOLTYPE_PRESET + -> tooltypeSector is preset level number + StringF(nodeFile,'\sAccess/PRESET.\d',cmds.bbsLoc,tooltypeSelector) + CASE TOOLTYPE_NODE_PRESET + -> tooltypeSector is access level number, note this also uses the current node + StringF(nodeFile,'\sNode\d/PRESET.\d',cmds.bbsLoc,node,tooltypeSelector) + CASE TOOLTYPE_FCHECK + -> tooltypeSector is file type + StringF(nodeFile,'\s/\s',fCheckDir,tooltypeSelector) + CASE TOOLTYPE_NODE_WINDOW + -> tooltypeSector is node number + StringF(nodeFile,'\sNode\d/WINDOW.DEF',cmds.bbsLoc,tooltypeSelector) + CASE TOOLTYPE_NODE_TIMES + -> tooltypeSector is node number + StringF(nodeFile,'\sNode\d/TIMES.DEF',cmds.bbsLoc,tooltypeSelector) + CASE TOOLTYPE_CONNECT + -> tooltypeSector is node number + StringF(nodeFile,'\sNode\d/Connect.Def',cmds.bbsLoc,tooltypeSelector) + CASE TOOLTYPE_XPRTYPES + -> tooltypeSector is not used + StringF(nodeFile,'\sProtocols/XprTypes',cmds.bbsLoc) + CASE TOOLTYPE_XFERLIB + -> tooltypeSector is xpr lib number + StringF(nodeFile,'\sProtocols/\s',cmds.bbsLoc,xprLib.item(tooltypeSelector)) + CASE TOOLTYPE_SCREENTYPES + -> tooltypeSector is not used + StringF(nodeFile,'\sScreenTypes',cmds.bbsLoc) + CASE TOOLTYPE_NRAMS + -> tooltypeSector is node, + StringF(tempStr,'\sNode\d/NRAMS',cmds.bbsLoc,tooltypeSelector) + IF findFirst(tempStr,tempStr2) + p:=-1 + FOR i:=0 TO StrLen(tempStr2)-1 + IF tempStr2[i]="." THEN p:=i + ENDFOR + IF (p>=0) + SetStr(tempStr2,p) + ENDIF + StringF(nodeFile,'\s/\s',tempStr,tempStr2) + ELSE + StrCopy(nodeFile,'') + ENDIF + CASE TOOLTYPE_ASCPACK + -> tooltypeSector is not used + StringF(nodeFile,'\sZoom/ASCPACK',cmds.bbsLoc) + CASE TOOLTYPE_QWKPACK + -> tooltypeSector is not used + StringF(nodeFile,'\sZoom/QWKPACK',cmds.bbsLoc) + CASE TOOLTYPE_QWKCONFIG + -> tooltypeSector is not used + StringF(nodeFile,'\sZoom/QWKCFG',cmds.bbsLoc) + CASE TOOLTYPE_LANGUAGES + -> tooltypeSector is not used + StringF(nodeFile,'\sLanguages',cmds.bbsLoc) + ENDSELECT +ENDPROC + +EXPORT PROC readToolType(toolType,tooltypeSelector,key,outValue) + DEF nodeFile[255]:STRING + DEF do: PTR TO diskobject + DEF tooltypes + DEF s: PTR TO CHAR + + s:=NIL + getNodeFile(toolType,tooltypeSelector,nodeFile) + + do:=getOrCreateCacheItem(nodeFile) + IF (do) + tooltypes:=do.tooltypes + IF (s:=FindToolType(tooltypes,key)) THEN StrCopy(outValue,s,ALL) + ENDIF + IF diskObjectCache=NIL THEN FreeDiskObject(do) +ENDPROC s<>NIL + +EXPORT PROC readToolTypeInt(toolType,tooltypeSelector,key) + DEF value[255]:STRING + IF readToolType(toolType,tooltypeSelector,key,value) + RETURN Val(value) + ENDIF +ENDPROC -1 + +EXPORT PROC checkToolType(toolType,tooltypeSelector,key,testValue) + DEF nodeFile[255]:STRING + DEF do: diskobject + DEF tooltypes + DEF s: PTR TO CHAR + DEF result=FALSE + + s:=NIL + + getNodeFile(toolType,tooltypeSelector,nodeFile) + + do:=getOrCreateCacheItem(nodeFile) + IF (do) + tooltypes:=do.tooltypes + IF(s:=FindToolType(tooltypes,key)) + IF (MatchToolValue(s,testValue)) THEN result:=TRUE + ENDIF + ENDIF + IF diskObjectCache=NIL THEN FreeDiskObject(do) +ENDPROC result + +EXPORT PROC checkToolTypeExists(toolType,tooltypeSelector,key) + DEF nodeFile[255]:STRING + DEF do: diskobject + DEF tooltypes + DEF s: PTR TO CHAR + DEF result=FALSE + + s:=NIL + + getNodeFile(toolType,tooltypeSelector,nodeFile) + + do:=getOrCreateCacheItem(nodeFile) + IF (do) + tooltypes:=do.tooltypes + IF(s:=FindToolType(tooltypes,key)) THEN result:=TRUE + ENDIF + IF diskObjectCache=NIL THEN FreeDiskObject(do) +ENDPROC result + +EXPORT PROC getOrCreateCacheItem(fileName:PTR TO CHAR) + DEF i,cnt,found=FALSE + DEF cacheObj: PTR TO diskObjectCacheItem + DEF do=NIL:PTR TO diskobject + DEF fn2[255]:STRING + DEF ownToolTypes + DEF toolTypes:PTR TO LONG + DEF fh,fileBuf,off,lineCount,len + + IF diskObjectCache<>NIL + cnt:=diskObjectCache.count() + + i:=0 + WHILE (iLRU algorithm, move most recently used to end of list + i++ + WHILE iNIL + fileBuf:=New(getFileSize(fn2)+1) ->allow an extra char in case file does not end in LF + + fh:=Open(fn2,MODE_OLDFILE) + IF fh<>0 + off:=0 + lineCount:=0 + WHILE(ReadStr(fh,fn2)<>-1) OR (StrLen(fn2)>0) + len:=0 + WHILE (fn2[len]<>0) AND (fn2[len]<>";") + len++ + ENDWHILE + + ->trim trailing space + WHILE (fn2[len-1]<=32) AND (len>0) + len-- + EXIT len=0 ->this is just here to prevent the fn2[len-1] causing a buffer underrun in the absence of short circuit evaluation + ENDWHILE + SetStr(fn2,len) + + AstrCopy(fileBuf+off,fn2,len+1) + lineCount++ + off:=off+len+1 + ENDWHILE + + toolTypes:=List(lineCount+1) + off:=0 + FOR i:=1 TO lineCount + listAdd2(toolTypes,fileBuf+off) + off:=off+StrLen(fileBuf+off)+1 + ENDFOR + ListAdd(toolTypes,[NIL]) + do.tooltypes:=toolTypes + ownToolTypes:=TRUE + Close(fh) + ELSE + Dispose(fileBuf) + FreeDiskObject(do) + do:=NIL + ENDIF + ENDIF + ENDIF + IF diskObjectCache<>NIL + cacheObj:=NEW cacheObj + cacheObj.fileName:=String(StrLen(fileName)) + cacheObj.ownsToolTypes:=ownToolTypes + StrCopy(cacheObj.fileName,fileName) + cacheObj.diskObject:=do + + IF diskObjectCache.count()<(diskObjectCache.maxSize()-1) + diskObjectCache.add(cacheObj) + ELSE + cacheObj:=diskObjectCache.item(0) + DisposeLink(cacheObj.fileName) + FreeDiskObject(cacheObj.diskObject) + diskObjectCache.remove(0) + diskObjectCache.add(cacheObj) + ENDIF + ENDIF + ENDIF +ENDPROC do + +EXPORT PROC clearDiskObjectCache() + DEF cacheObj: PTR TO diskObjectCacheItem + DEF i, do: PTR TO diskobject + DEF mem + + IF diskObjectCache=NIL THEN RETURN + FOR i:=0 TO diskObjectCache.count()-1 + IF (cacheObj:=diskObjectCache.item(i)) + IF cacheObj.ownsToolTypes + do:=cacheObj.diskObject + mem:=do.tooltypes[0] -> release the file buffer (first string pointer points to start of buffer) + Dispose(mem) + DisposeLink(do.tooltypes) ->our tooltypes is a list that needs to be freed + ENDIF + DisposeLink(cacheObj.fileName) + IF cacheObj.diskObject<>NIL + do:=cacheObj.diskObject + FreeDiskObject(do) + ENDIF + END cacheObj + ENDIF + ENDFOR + diskObjectCache.clear() + cacheTests:=0 + cacheHits:=0 +ENDPROC + +EXPORT PROC getUserAccessFilename(outFilename: PTR TO CHAR) + DEF tempStr[255]:STRING + + DEF i,c + + StrCopy(tempStr,loggedOnUser.name) + FOR i:=0 TO StrLen(tempStr)-1 + c:=tempStr[i] + SELECT c + CASE "%" + tempStr[i]:="_" + CASE "#" + tempStr[i]:="_" + CASE "?" + tempStr[i]:="_" + CASE "/" + tempStr[i]:="_" + CASE "(" + tempStr[i]:="_" + CASE ")" + tempStr[i]:="_" + ENDSELECT + ENDFOR + + StringF(outFilename,'\sACCESS/\s',cmds.bbsLoc,tempStr) +ENDPROC + diff --git a/zmodem.e b/zmodem.e new file mode 100644 index 0000000..8a04472 --- /dev/null +++ b/zmodem.e @@ -0,0 +1,3137 @@ +OPT LARGE,MODULE,REG=5 + + MODULE 'dos/dos' + +/* +way to update errors, error/resume position +*/ + +/* crc16.c */ + +/* CCITT 16-bit CRC table and calculation function */ + +/* $Id: crc16.c,v 1.7 2014/02/10 04:44:31 deuce Exp $ */ + +EXPORT CONST ZM_LOG_DEBUG=4 +EXPORT CONST ZM_LOG_INFO=3 +EXPORT CONST ZM_LOG_NOTICE=2 +EXPORT CONST ZM_LOG_WARNING=1 +EXPORT CONST ZM_LOG_ERR=0 + +CONST MAX_PATH=512 + +CONST NOINP=-1 /* input buffer empty (incom only) */ +CONST TELNET_IAC=255 + +CONST RXSUBPACKETSIZE=8192 +CONST TXSUBPACKETSIZE=8192 + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2007 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +PROC strcopy(dest: PTR TO CHAR,src: PTR TO CHAR,len=-1) + DEF i,c + i:=0 + REPEAT + dest[i]:=(c:=src[i]) + i++ + UNTIL (i=len) OR (c=0) +ENDPROC + +PROC fexist(file) + DEF lh + IF lh:=Lock(file,ACCESS_READ) + UnLock(lh) + RETURN TRUE + ENDIF +ENDPROC FALSE + +PROC flength(file) + DEF fBlock: fileinfoblock + DEF fLock + DEF fsize=8192 + + IF((fLock:=Lock(file,ACCESS_READ)))=NIL + RETURN 8192 + ENDIF + + IF((fBlock:=AllocDosObject(DOS_FIB,NIL)))=NIL + UnLock(fLock) + RETURN 8192 + ENDIF + IF(Examine(fLock,fBlock)) THEN fsize:=fBlock.size + UnLock(fLock) + FreeDosObject(DOS_FIB,fBlock) +ENDPROC fsize + +->todo proper disk space check +PROC getFreeDiskSpace() IS 300000000 + +EXPORT PROC getZmSystemTime() + DEF currDate: datestamp + DateStamp(currDate) +ENDPROC Mul(Mul(currDate.days,1440),60)+(currDate.minute*60)+(currDate.tick/50),Mod(currDate.tick,50) + +PROC getFileSize(zm,fp) + DEF p + p:=doSeek(zm,fp,0,OFFSET_END) +ENDPROC doSeek(zm,fp,p,OFFSET_BEGINING) + + +/* zmodem.c */ + +/* Synchronet ZMODEM Functions */ + +/* $Id: zmodem.c,v 1.122 2018/02/20 11:44:53 rswindell Exp $ */ + +/******************************************************************************/ +/* Project : Unite! File : zmodem general Version : 1.02 */ +/* */ +/* (C) Mattheij Computer Service 1994 */ +/* + * Date: Thu, 19 Nov 2015 10:10:02 +0100 + * From: Jacques Mattheij + * Subject: Re: zmodem license + * To: Stephen Hurd, Fernando Toledo + * CC: Rob Swindell + * + * Hello there to all of you, + * + * So, this email will then signify as the transfer of any and all rights I + * held up to this point with relation to the copyright of the zmodem + * package as released by me many years ago and all associated files to + * Stephen Hurd. Fernando Toledo and Rob Swindell are named as + * witnesses to this transfer. + * + * ... + * + * best regards, + * + * Jacques Mattheij + ******************************************************************************/ + +/* + * zmodem primitives and other code common to zmtx and zmrx + */ + + /* + * zmodem.h + * zmodem constants + * (C) Mattheij Computer Service 1994 + * + * Date: Thu, 19 Nov 2015 10:10:02 +0100 + * From: Jacques Mattheij + * Subject: Re: zmodem license + * To: Stephen Hurd, Fernando Toledo + * CC: Rob Swindell + * + * Hello there to all of you, + * + * So, this email will then signify as the transfer of any and all rights I + * held up to this point with relation to the copyright of the zmodem + * package as released by me many years ago and all associated files to + * Stephen Hurd. Fernando Toledo and Rob Swindell are named as + * witnesses to this transfer. + * + * ... + * + * best regards, + * + * Jacques Mattheij + */ + +/* $Id: zmodem.h,v 1.55 2018/02/01 08:20:19 deuce Exp $ */ + + + CONST SOH=$01 + CONST STX=$02 + CONST EOT=$04 + CONST ENQ=$05 + CONST ACK=$06 + CONST LF=$0a + CONST CR=$0d + CONST DLE=$10 + CONST XON=$11 + CONST XOFF=$13 + CONST XONOR80=$91 + CONST XOFFOR80=$93 + CONST NAK=$15 + CONST CAN=$18 + +/* + * zmodem constants + */ + +CONST ZBLOCKLEN=1024 /* "true" Zmodem max subpacket length */ + +CONST ZMAXHLEN=$10 /* maximum header information length */ +CONST ZMAXSPLEN=$400 /* maximum subpacket length */ + + +CONST ZPAD=$2a /* pad character; begins frames */ +CONST ZDLE=$18 /* ctrl-x zmodem escape */ +CONST ZDLEE=$58 /* escaped ZDLE */ + +CONST ZBIN=$41 /* binary frame indicator (CRC16) */ +CONST ZHEX=$42 /* hex frame indicator */ +CONST ZBIN32=$43 /* binary frame indicator (CRC32) */ +CONST ZBINR32=$44 /* run length encoded binary frame (CRC32) */ + +CONST ZVBIN=$61 /* binary frame indicator (CRC16) */ +CONST ZVHEX=$62 /* hex frame indicator */ +CONST ZVBIN32=$63 /* binary frame indicator (CRC32) */ +CONST ZVBINR32=$64 /* run length encoded binary frame (CRC32) */ + +CONST ZRESC=$7e /* run length encoding flag / escape character */ + +/* + * zmodem frame types + */ + +CONST ZRQINIT=$00 /* request receive init (s->r) */ +CONST ZRINIT=$01 /* receive init (r->s) */ +CONST ZSINIT=$02 /* send init sequence (optional) (s->r) */ +CONST ZACK=$03 /* ack to ZRQINIT ZRINIT or ZSINIT (s<->r) */ +CONST ZFILE=$04 /* file name (s->r) */ +CONST ZSKIP=$05 /* skip this file (r->s) */ +CONST ZNAK=$06 /* last packet was corrupted (?) */ +CONST ZABORT=$07 /* abort batch transfers (?) */ +CONST ZFIN=$08 /* finish session (s<->r) */ +CONST ZRPOS=$09 /* resume data transmission here (r->s) */ +CONST ZDATA=$0a /* data packet(s) follow (s->r) */ +CONST ZEOF=$0b /* end of file reached (s->r) */ +CONST ZFERR=$0c /* fatal read or write error detected (?) */ +CONST ZCRC=$0d /* request for file CRC and response (?) */ +CONST ZCHALLENGE=$0e /* security challenge (r->s) */ +CONST ZCOMPL=$0f /* request is complete (?) */ +CONST ZCAN=$10 /* pseudo frame; + other end cancelled session with 5* CAN */ +CONST ZFREECNT=$11 /* request free bytes on file system (s->r) */ +CONST ZCOMMAND=$12 /* issue command (s->r) */ +CONST ZSTDERR=$13 /* output data to stderr (??) */ + +/* + * ZDLE sequences + */ + +CONST ZCRCE=$68 /* CRC next, frame ends, header packet follows */ +CONST ZCRCG=$69 /* CRC next, frame continues nonstop */ +CONST ZCRCQ=$6a /* CRC next, frame continuous, ZACK expected */ +CONST ZCRCW=$6b /* CRC next, frame ends, ZACK expected */ +CONST ZRUB0=$6c /* translate to rubout $7f */ +CONST ZRUB1=$6d /* translate to rubout $ff */ + +/* + * frame specific data. + * entries are prefixed with their location in the header array. + */ + +/* + * Byte positions within header array + */ + +CONST FTYPE=0 /* frame type */ + +CONST ZF0=4 /* First flags byte */ +CONST ZF1=3 +CONST ZF2=2 +CONST ZF3=1 + +CONST ZP0=1 /* Low order 8 bits of position */ +CONST ZP1=2 +CONST ZP2=3 +CONST ZP3=4 /* High order 8 bits of file position */ + +/* + * ZRINIT frame + * zmodem receiver capability flags + */ + +CONST ZF0_CANFDX=$01 /* Receiver can send and receive true full duplex */ +CONST ZF0_CANOVIO=$02 /* receiver can receive data during disk I/O */ +CONST ZF0_CANBRK=$04 /* receiver can send a break signal */ +CONST ZF0_CANCRY=$08 /* Receiver can decrypt DONT USE */ +CONST ZF0_CANLZW=$10 /* Receiver can uncompress DONT USE */ +CONST ZF0_CANFC32=$20 /* Receiver can use 32 bit Frame Check */ +CONST ZF0_ESCCTL=$40 /* Receiver expects ctl chars to be escaped */ +CONST ZF0_ESC8=$80 /* Receiver expects 8th bit to be escaped */ + +CONST ZF1_CANVHDR=$01 /* Variable headers OK */ + +/* + * ZSINIT frame + * zmodem sender capability + */ + +CONST ZF0_TESCCTL=$40 /* Transmitter expects ctl chars to be escaped */ +CONST ZF0_TESC8=$80 /* Transmitter expects 8th bit to be escaped */ + +CONST ZATTNLEN=$20 /* Max length of attention string */ +CONST ALTCOFF=ZF1 /* Offset to alternate canit string, 0 if not used */ + +/* + * ZFILE frame + */ + +/* + * Conversion options one of these in ZF0 + */ + +CONST ZF0_ZCBIN=1 /* Binary transfer - inhibit conversion */ +CONST ZF0_ZCNL=2 /* Convert NL to local end of line convention */ +CONST ZF0_ZCRESUM=3 /* Resume interrupted file transfer */ + +/* + * Management include options, one of these ored in ZF1 + */ + +CONST ZF1_ZMSKNOLOC=$80 /* Skip file if not present at rx */ +CONST ZF1_ZMMASK=$1f /* Mask for the choices below */ +CONST ZF1_ZMNEWL=1 /* Transfer if source newer or longer */ +CONST ZF1_ZMCRC=2 /* Transfer if different file CRC or length */ +CONST ZF1_ZMAPND=3 /* Append contents to existing file (if any) */ +CONST ZF1_ZMCLOB=4 /* Replace existing file */ +CONST ZF1_ZMNEW=5 /* Transfer if source newer */ +CONST ZF1_ZMDIFF=6 /* Transfer if dates or lengths different */ +CONST ZF1_ZMPROT=7 /* Protect destination file */ +CONST ZF1_ZMCHNG=8 /* Change filename if destination exists */ + +/* + * Transport options, one of these in ZF2 + */ + +CONST ZF2_ZTNOR=0 /* no compression */ +CONST ZF2_ZTLZW=1 /* Lempel-Ziv compression */ +CONST ZF2_ZTRLE=3 /* Run Length encoding */ + +/* + * Extended options for ZF3, bit encoded + */ + +CONST ZF3_ZCANVHDR=$01 /* Variable headers OK */ + /* Receiver window size override */ +CONST ZF3_ZRWOVR=$04 /* byte position for receive window override/256 */ +CONST ZF3_ZXSPARS=$40 /* encoding for sparse file operations */ + +/* + * ZCOMMAND frame + */ + +CONST ZF0_ZCACK1=$01 /* Acknowledge, then do command */ + + + CONST ENDOFFRAME=2 + CONST FRAMEOK=1 + CONST TIMEOUT=-1 /* rx routine did not receive a character within timeout */ + CONST INVHDR=-2 /* invalid header received; but within timeout */ + CONST ABORTED=-3 /* Aborted *or* disconnected */ + CONST SUBPKTOVERFLOW=-4 /* Subpacket received more than block length */ + CONST CRCFAILED=-5 /* Failed CRC comparison */ + CONST INVALIDSUBPKT=-6 /* Invalid Subpacket Type */ + CONST ZDLEESC=$8000 /* one of ZCRCE; ZCRCG; ZCRCQ or ZCRCW was received; ZDLE escaped */ + CONST BADSUBPKT=$80 + CONST HDRLEN=5 /* size of a zmodem header */ + +EXPORT OBJECT zmodem_t + + rxd_header[ZMAXHLEN]:ARRAY OF CHAR /* last received header */ + rxd_header_len:INT /* last received header size */ + rxd_header_pos:LONG /* last received header position value */ + + /* + * receiver capability flags + * extracted from the ZRINIT frame as received + */ + + can_full_duplex:CHAR + can_overlap_io:CHAR + can_break:CHAR + can_fcs_32:CHAR + want_fcs_16:CHAR + escape_ctrl_chars:CHAR + escape_8th_bit:CHAR + + /* + * file management options. + * only one should be on + */ + + management_newer:INT + management_clobber:INT + management_protect:INT + + /* from zmtx.c */ + + tx_data_subpacket:PTR TO CHAR ->[TXSUBPACKETSIZE]:ARRAY OF CHAR + rx_data_subpacket:PTR TO CHAR ->[RXSUBPACKETSIZE]:ARRAY OF CHAR /* zzap = 8192 */ + + sendBuffer:PTR TO CHAR + sendBufferSize + sendBufferPos + + crc16tbl:PTR TO INT + crc32tbl:PTR TO LONG + + zm_lputs + zm_progress + zm_recv_byte + zm_is_connected + zm_is_cancelled + zm_upload_completed + zm_upload_failed + zm_dupecheck + zm_data_waiting + zm_flush + zm_duplicate_filename + zm_fopen + zm_fclose + zm_fread + zm_fwrite + zm_fseek + zm_firstfile + zm_nextfile + current_file_name[MAX_PATH]:ARRAY OF CHAR + current_file_size:LONG + current_file_pos:LONG + current_file_time:LONG + current_file_num:LONG + total_files:LONG + total_bytes:LONG + files_remaining:LONG + bytes_remaining:LONG + transfer_start_pos:LONG + transfer_start_time1:LONG + transfer_start_time2:INT + new_file:INT + receive_32bit_data:INT + use_crc16:INT + ack_file_pos:LONG /* file position used in acknowledgement of correctly */ + /* received data subpackets */ + + last_sent:INT + + n_cans:INT + + /* Stuff added by RRS */ + + /* Status */ + cancelled:CHAR + local_abort:CHAR + file_skipped:CHAR + no_streaming:CHAR + frame_in_transit:CHAR + recv_bufsize:LONG /* Receiver specified buffer size */ + crc_request:LONG + errors:LONG + consecutive_errors:LONG + + /* Configuration */ + escape_telnet_iac:CHAR + init_timeout:LONG + send_timeout:LONG + recv_timeout:LONG + crc_timeout:LONG + max_errors:LONG + block_size:LONG + max_block_size:LONG + max_file_size:LONG /* 0 = unlimited */ + log_level:PTR TO INT + + user_data:LONG + /* Callbacks */ + /* error C2520: conversion from unsigned __int64 to double not implemented, use signed __int64 */ + cbdata: PTR TO CHAR + ->int (*lputs)(void*, int level, const char* str) + ->int (*send_byte)(void*, BYTE ch, unsigned timeout /* seconds */) + ->int (*recv_byte)(void*, unsigned timeout /* seconds */) + ->void (*progress)(void*, int64_t current_pos) + ->BOOL (*is_connected)(void*) + ->BOOL (*is_cancelled)(void*) + ->BOOL (*data_waiting)(void*, unsigned timeout /* seconds */) + ->BOOL (*duplicate_filename)(void*, void *zm) + ->void (*flush)(void*) +ENDOBJECT + +->#define ucrc16(ch,crc) (crc16tbl[((crc>>8)&0xff)^(unsigned char)ch]^(crc << 8)) +PROC ucrc16(zm:PTR TO zmodem_t,ch,crc) + DEF n + n:=Eor(Shr(crc,8) AND $ff,ch) +ENDPROC Eor(zm.crc16tbl[n],Shl(crc,8)) AND $ffff + +/*PROC crc16(zm:PTR TO zmodem_t,data: PTR TO CHAR,len) + DEF crc=0 + DEF l + IF((len=0) AND (data<>NIL)) THEN len:=StrLen(data) + FOR l:=0 TO len-1 + crc:=ucrc16(zm,data[l],crc) + ENDFOR +ENDPROC crc*/ + +/*PROC ucrc32(ch,crc) + DEF a,b + a:= Eor(crc,ch) + a:= a AND 255 + a:=crc32tbl[a] + b:=Shr(crc,8) AND $ffffff +ENDPROC Eor(a,b)*/ + +PROC ucrc32(zm:PTR TO zmodem_t,ch,crc) IS Eor(zm.crc32tbl[(Eor(crc,ch)) AND 255],Shr(crc,8) AND $ffffff) + +->#define ucrc32(ch,crc) (crc32tbl[(crc^(ch))&$ff]^(crc>>8)) + +PROC fcrc32(zm:PTR TO zmodem_t,fp, len) + DEF ch[1]:ARRAY OF CHAR + DEF crc=$ffffffff + DEF rl + + doSeek(zm,fp,0,OFFSET_BEGINNING) + REPEAT + rl:=doRead(zm,fp,ch,1) + IF rl=1 + crc:=ucrc32(zm,ch,crc) + ENDIF + len-- + UNTIL (rl=0) OR (len=0) +ENDPROC Not(crc) + + +PROC lprintf(zm:PTR TO zmodem_t, level, str:PTR TO CHAR) + DEF p + IF(zm.zm_lputs=NIL) THEN RETURN -1 + + IF(zm.log_level<>NIL) + IF(level > zm.log_level) THEN RETURN 0 + ENDIF + p:=zm.zm_lputs +ENDPROC p(zm,level,str) + +PROC is_connected(zm: PTR TO zmodem_t) + DEF p + p:=zm.zm_is_connected + IF(p<>NIL) THEN RETURN p(zm) +ENDPROC TRUE + +PROC is_cancelled(zm: PTR TO zmodem_t) + DEF p + p:=zm.zm_is_cancelled + IF(p<>NIL) + zm.cancelled:=zm.cancelled OR p(zm) + RETURN zm.cancelled + ENDIF +ENDPROC zm.cancelled + +PROC upload_completed(zm:PTR TO zmodem_t,fname:PTR TO CHAR) + DEF p + p:=zm.zm_upload_completed + IF (p<>NIL) THEN p(zm,fname) +ENDPROC + +PROC upload_failed(zm:PTR TO zmodem_t,fname:PTR TO CHAR) + DEF p + p:=zm.zm_upload_failed + IF (p<>NIL) THEN p(zm,fname) +ENDPROC + +PROC dupe_check(zm:PTR TO zmodem_t,fname) + DEF res=FALSE + DEF p + p:=zm.zm_dupecheck + IF (p<>NIL) THEN res:=p(zm,fname) +ENDPROC res + +PROC zmodem_data_waiting(zm: PTR TO zmodem_t,timeout) + DEF p + + p:=zm.zm_data_waiting + IF(p<>NIL) THEN RETURN p(zm, timeout) +ENDPROC FALSE + +PROC chr(ch,output) + + SELECT ch + CASE TIMEOUT + StrCopy(output,'TIMEOUT') + RETURN + CASE ABORTED + StrCopy(output,'ABORTED') + RETURN + CASE SUBPKTOVERFLOW + StrCopy(output,'Subpacket Overflow') + RETURN + CASE CRCFAILED + StrCopy(output,'CRC Failure') + RETURN + CASE INVALIDSUBPKT + StrCopy(output,'Invalid Subpacket') + RETURN + CASE ZRQINIT + StrCopy(output,'ZRQINIT') + RETURN + CASE ZRINIT + StrCopy(output,'ZRINIT') + RETURN + CASE ZSINIT + StrCopy(output,'ZSINIT') + RETURN + CASE ZACK + StrCopy(output,'ZACK') + RETURN + CASE ZFILE + StrCopy(output,'ZFILE') + RETURN + CASE ZSKIP + StrCopy(output,'ZSKIP') + RETURN + CASE ZCRC + StrCopy(output,'ZCRC') + RETURN + CASE ZNAK + StrCopy(output,'ZNAK') + RETURN + CASE ZABORT + StrCopy(output,'ZABORT') + RETURN + CASE ZFIN + StrCopy(output,'ZFIN') + RETURN + CASE ZRPOS + StrCopy(output,'ZRPOS') + RETURN + CASE ZDATA + StrCopy(output,'ZDATA') + RETURN + CASE ZEOF + StrCopy(output,'ZEOF') + RETURN + CASE ZFERR + StrCopy(output,'ZFERR') + RETURN + CASE ZPAD + StrCopy(output,'ZPAD') + RETURN + CASE ZCAN + StrCopy(output,'ZCAN') + RETURN + CASE ZDLE + StrCopy(output,'ZDLE') + RETURN + CASE ZDLEE + StrCopy(output,'ZDLEE') + RETURN + CASE ZBIN + StrCopy(output,'ZBIN') + RETURN + CASE ZHEX + StrCopy(output,'ZHEX') + RETURN + CASE ZBIN32 + StrCopy(output,'ZBIN32') + RETURN + CASE ZRESC + StrCopy(output,'ZRESC') + RETURN + CASE ZCRCE + StrCopy(output,'ZCRCE') + RETURN + CASE ZCRCG + StrCopy(output,'ZCRCG') + RETURN + CASE ZCRCQ + StrCopy(output,'ZCRCQ') + RETURN + CASE ZCRCW + StrCopy(output,'ZCRCW') + RETURN + ENDSELECT + IF(ch<0) + StringF(output,'\d',ch) + ELSEIF((ch>=" ") AND (ch<="~")) + StringF(output,'''\c'' (\h[2])',ch,ch) + ELSE + StringF(output,'\d (\h[2])',ch,ch) + ENDIF +ENDPROC + +PROC frame_desc(frame,output) + DEF str[25]:STRING + DEF tmp + + IF(frame=TIMEOUT) + StrCopy(output,'TIMEOUT') + RETURN + ENDIF + + IF(frame=INVHDR) + StrCopy(output,'Invalid Header') + RETURN + ENDIF + + IF(frame=ABORTED) + StrCopy(output,'Aborted') + RETURN + ENDIF + + + IF(frame>=0) + IF (frame AND BADSUBPKT) THEN StrCopy(str,'BAD ') + tmp:=frame AND (Not(BADSUBPKT)) + SELECT tmp + CASE ZRQINIT + StrAdd(str,'ZRQINIT') + CASE ZRINIT + StrAdd(str,'ZRINIT') + CASE ZSINIT + StrAdd(str,'ZSINIT') + CASE ZACK + StrAdd(str,'ZACK') + CASE ZFILE + StrAdd(str,'ZFILE') + CASE ZSKIP + StrAdd(str,'ZSKIP') + CASE ZNAK + StrAdd(str,'ZNAK') + CASE ZABORT + StrAdd(str,'ZABORT') + CASE ZFIN + StrAdd(str,'ZFIN') + CASE ZRPOS + StrAdd(str,'ZRPOS') + CASE ZDATA + StrAdd(str,'ZDATA') + CASE ZEOF + StrAdd(str,'ZEOF') + CASE ZFERR + StrAdd(str,'ZFERR') + CASE ZCRC + StrAdd(str,'ZCRC') + CASE ZCHALLENGE + StrAdd(str,'ZCHALLENGE') + CASE ZCOMPL + StrAdd(str,'ZCOMPL') + CASE ZCAN + StrAdd(str,'ZCAN') + CASE ZFREECNT + StrAdd(str,'ZFREECNT') + CASE ZCOMMAND + StrAdd(str,'ZCOMMAND') + CASE ZSTDERR + StrAdd(str,'ZSTDERR') + DEFAULT + StringF(str,'Unknown (\h[8])', frame) + ENDSELECT + ELSE + StringF(str,'\d',frame) + ENDIF + StrCopy(output,str) + ENDPROC + +/*PROC frame_pos(zm: PTR TO zmodem_t,type) + IF (type=ZRPOS) OR (type=ZACK) OR (type=ZEOF) OR (type=ZDATA) THEN RETURN zm.rxd_header_pos +ENDPROC 0*/ + +/* + * read bytes as long as rdchk indicates that + * more data is available. + */ + +PROC zmodem_recv_purge(zm: PTR TO zmodem_t) + DEF p + p:=zm.zm_recv_byte + WHILE p(zm,0)>=0 + ENDWHILE +ENDPROC + +/* + * Flush the output buffer + */ +EXPORT PROC zmodem_flush(zm: PTR TO zmodem_t) + DEF p + p:=zm.zm_flush + IF(p<>NIL) THEN p(zm,zm.sendBuffer,zm.sendBufferPos) + zm.sendBufferPos:=0 +ENDPROC + +/* + * transmit a character. + * this is the raw modem interface + */ +/* Returns 0 on success */ +EXPORT PROC zmodem_send_raw(zm: PTR TO zmodem_t,ch) + + zm.sendBuffer[zm.sendBufferPos]:=ch + zm.sendBufferPos:=zm.sendBufferPos+1 + IF zm.sendBufferPos=zm.sendBufferSize THEN zmodem_flush(zm) + + zm.last_sent:=ch + +ENDPROC 0 + +/* + * transmit a character ZDLE escaped + */ + +PROC zmodem_send_esc(zm: PTR TO zmodem_t,c) + DEF result + + IF ((result:=zmodem_send_raw(zm, ZDLE)))<>0 THEN RETURN result + /* + * exclusive or; not an or so ZDLE becomes ZDLEE + */ +ENDPROC zmodem_send_raw(zm,Eor(c,64)) + + +/* + * transmit a character; ZDLE escaping if appropriate + */ + +PROC zmodem_tx(zm:PTR TO zmodem_t,c) + DEF result + IF (c=DLE) OR (c=(DLE+128)) OR (c=XON) OR (c=(XON+128)) OR (c=XOFF) OR (c=(XOFF+128)) OR (c=ZDLE) + RETURN zmodem_send_esc(zm, c) + ELSEIF (c=CR) OR (c=(CR+128)) + IF(zm.escape_ctrl_chars AND ((zm.last_sent AND 127) ="@")) THEN RETURN zmodem_send_esc(zm, c) + ELSEIF (c=TELNET_IAC) + IF(zm.escape_telnet_iac) + IF((result:=zmodem_send_raw(zm, ZDLE)))<>0 THEN RETURN result + RETURN zmodem_send_raw(zm, ZRUB1) + ENDIF + ELSE + IF((zm.escape_ctrl_chars<>0) AND ((c AND 96)=0)) THEN RETURN zmodem_send_esc(zm, c) + ENDIF + /* + * anything that ends here is so normal we might as well transmit it. + */ +ENDPROC zmodem_send_raw(zm,c) + + +/**********************************************/ +/* Output single byte as two hex ASCII digits */ +/**********************************************/ +PROC zmodem_send_hex(zm:PTR TO zmodem_t,val) + DEF xdigit[16]:STRING + ->DEF tempstr[255]:STRING + DEF result + + StrCopy(xdigit,'0123456789abcdef') + + ->StringF(tempstr,'send_hex: \d \h[2] ',val,val) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr) + + IF((result:=zmodem_send_raw(zm, xdigit[Shr(val,4)])))<>0 THEN RETURN result +ENDPROC zmodem_send_raw(zm, xdigit[val AND 15]); + +PROC zmodem_send_padded_zdle(zm: PTR TO zmodem_t) + DEF result + + IF ((result:=zmodem_send_raw(zm, ZPAD)))<>0 THEN RETURN result + IF ((result:=zmodem_send_raw(zm, ZPAD)))<>0 THEN RETURN result +ENDPROC zmodem_send_raw(zm, ZDLE) + +/* + * transmit a hex header. + * these routines use tx_raw because we're sure that all the + * characters are not to be escaped. + */ +PROC zmodem_send_hex_header(zm:PTR TO zmodem_t, p: PTR TO CHAR) + DEF i; + DEF result; + DEF type + DEF crc; + ->DEF tempstr[255]:STRING + ->DEF tempstr2[255]:STRING + + type:=p[] + ->chr(type,tempstr) + ->StringF(tempstr2,'send_hex_header: \s', tempstr) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr2) + + IF((result:=zmodem_send_padded_zdle(zm)))<>0 THEN RETURN result + + IF((result:=zmodem_send_raw(zm, ZHEX)))<>0 THEN RETURN result + + /* + * initialise the crc + */ + + crc:=0; + + /* + * transmit the header + */ + + FOR i:=0 TO HDRLEN-1 + IF((result:=zmodem_send_hex(zm, p[])))<>0 THEN RETURN result + crc:=ucrc16(zm,p[], crc) + p++ + ENDFOR + + /* + * update the crc as though it were zero + */ + + /* + * transmit the crc + */ + + IF((result:=zmodem_send_hex(zm,(Shr(crc,8)))))<>0 THEN RETURN result + + IF((result:=zmodem_send_hex(zm,(crc AND 255))))<>0 THEN RETURN result + + /* + * end of line sequence + */ + + IF((result:=zmodem_send_raw(zm, "\b")))<>0 THEN RETURN result + + IF((result:=zmodem_send_raw(zm, "\n")))<>0 THEN RETURN result /* FDSZ sends 0x8a instead of 0x0a */ + + IF((type<>ZACK) AND (type<>ZFIN)) THEN result:=zmodem_send_raw(zm, XON) + + zmodem_flush(zm) + +ENDPROC result + +/* + * Send ZMODEM binary header hdr + */ + +PROC zmodem_send_bin32_header(zm:PTR TO zmodem_t, p: PTR TO CHAR) + DEF i + DEF result + DEF crc + ->DEF tempstr[255]:STRING + ->DEF tempstr2[255]:STRING + DEF pp + + ->chr(p[],tempstr) + ->StringF(tempstr2,'"send_bin32_header: \s',tempstr) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr2) + + IF((result:=zmodem_send_padded_zdle(zm)))<>0 THEN RETURN result + + IF((result:=zmodem_send_raw(zm, ZBIN32)))<>0 THEN RETURN result + + crc:=-1 + + FOR i:=0 TO HDRLEN-1 + pp:=p[] + p++ + crc:=ucrc32(zm,pp,crc) + IF((result:=zmodem_tx(zm, pp)))<>0 THEN RETURN result + ENDFOR + + crc:= Not(crc) + + IF((result:=zmodem_tx(zm,((crc) AND $ff))))<>0 THEN RETURN result + + IF((result:=zmodem_tx(zm,((Shr(crc,8)) AND $ff))))<>0 THEN RETURN result + + IF((result:=zmodem_tx(zm,((Shr(crc,16)) AND $ff))))<>0 THEN RETURN result + +ENDPROC zmodem_tx(zm,((Shr(crc,24)) AND $ff)) + +PROC zmodem_send_bin16_header(zm:PTR TO zmodem_t, p: PTR TO CHAR) + DEF i + DEF result + DEF crc + ->DEF tempstr[255]:STRING + ->DEF tempstr2[255]:STRING + DEF tmp + + ->chr(p[],tempstr) + ->StringF(tempstr2,'send_bin16_header: \s',tempstr) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr2) + + IF((result:=zmodem_send_padded_zdle(zm)))<>0 THEN RETURN result + + IF((result:=zmodem_send_raw(zm, ZBIN)))<>0 THEN RETURN result + + crc:=0 + + FOR i:=0 TO HDRLEN-1 + crc:=ucrc16(zm,p[],crc) + tmp:=p[] + p++ + IF((result:=zmodem_tx(zm,tmp)))<>0 THEN RETURN result + ENDFOR + + IF((result:=zmodem_tx(zm,(Shr(crc,8)))))<>0 THEN RETURN result +ENDPROC zmodem_tx(zm, (crc AND $ff)) + + + +/* + * transmit a header using either hex 16 bit crc or binary 32 bit crc + * depending on the receivers capabilities + * we dont bother with variable length headers. I dont really see their + * advantage and they would clutter the code unneccesarily + */ + +PROC zmodem_send_bin_header(zm: PTR TO zmodem_t, p: PTR TO CHAR) + IF((zm.can_fcs_32<>0) AND (zm.want_fcs_16=0)) THEN RETURN zmodem_send_bin32_header(zm, p) +ENDPROC zmodem_send_bin16_header(zm, p) + +/* + * data subpacket transmission + */ + +PROC zmodem_send_data32(zm: PTR TO zmodem_t, subpkt_type, p: PTR TO CHAR, l) + + DEF result + DEF crc + DEF tmp + ->DEF tempstr[255]:STRING + ->DEF tempstr2[255]:STRING + + ->chr(subpkt_type,tempstr) + ->StringF(tempstr2,'send_data32: \s (\d bytes)', tempstr,l) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr2) + + crc:=$ffffffff + + WHILE(l > 0) + crc:=ucrc32(zm,p[],crc) + tmp:=p[] + p++ + IF((result:=zmodem_tx(zm, tmp)))<>0 THEN RETURN result + l-- + ENDWHILE + + crc:=ucrc32(zm,subpkt_type, crc) + + IF((result:=zmodem_send_raw(zm, ZDLE)))<>0 THEN RETURN result + + IF((result:=zmodem_send_raw(zm, subpkt_type)))<>0 THEN RETURN result + + crc:=Not(crc) + + IF((result:=zmodem_tx(zm, ((crc) AND $ff))))<>0 THEN RETURN result + + IF((result:=zmodem_tx(zm, ((Shr(crc,8)) AND $ff))))<>0 THEN RETURN result + + IF((result:=zmodem_tx(zm, ((Shr(crc,16)) AND $ff))))<>0 THEN RETURN result +ENDPROC zmodem_tx(zm, ((Shr(crc,24)) AND $ff)) + +PROC zmodem_send_data16(zm: PTR TO zmodem_t, subpkt_type,p: PTR TO CHAR, l) + + DEF result + DEF crc + ->DEF tempstr[255]:STRING + ->DEF tempstr2[255]:STRING + DEF tmp + + ->chr(subpkt_type,tempstr) + ->StringF(tempstr2,'send_data16: \s (\d bytes)', tempstr,l) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr2) + + crc:=0 + + WHILE(l > 0) + crc:=ucrc16(zm,p[],crc) + tmp:=p[] + p++ + IF((result:=zmodem_tx(zm, tmp)))<>0 THEN RETURN result + l-- + ENDWHILE + + crc:=ucrc16(zm,subpkt_type,crc) + + IF((result:=zmodem_send_raw(zm, ZDLE)))<>0 THEN RETURN result + + IF((result:=zmodem_send_raw(zm, subpkt_type)))<>0 THEN RETURN result + + IF((result:=zmodem_tx(zm, (Shr(crc,8)))))<>0 THEN RETURN result +ENDPROC zmodem_tx(zm, (crc AND $ff)); + + +/* + * send a data subpacket using crc 16 or crc 32 as desired by the receiver + */ + +PROC zmodem_send_data_subpkt(zm: PTR TO zmodem_t, subpkt_type, p: PTR TO CHAR, l) + DEF result + + IF((subpkt_type = ZCRCW) OR (subpkt_type = ZCRCE)) /* subpacket indicating 'end-of-frame' */ + zm.frame_in_transit:=FALSE + ELSE /* other subpacket (mid-frame) */ + zm.frame_in_transit:=TRUE + ENDIF + + IF((zm.want_fcs_16=0) AND (zm.can_fcs_32<>0)) + IF((result:=zmodem_send_data32(zm, subpkt_type,p,l)))<>0 THEN RETURN result + + ELSE + IF((result:=zmodem_send_data16(zm, subpkt_type,p,l)))<>0 THEN RETURN result + + ENDIF + + IF(subpkt_type = ZCRCW) THEN result:=zmodem_send_raw(zm, XON) + zmodem_flush(zm) +ENDPROC result + +PROC zmodem_send_data(zm: PTR TO zmodem_t, subpkt_type, p: PTR TO CHAR, l) + ->DEF tempstr[255]:STRING + + IF(zm.frame_in_transit)=0 /* Start of frame, include ZDATA header */ + ->StringF(tempstr,'send_data: start of frame, offset \d',zm.current_file_pos) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr) + zmodem_send_pos_header(zm, ZDATA, zm.current_file_pos, /* Hex? */ FALSE) + ENDIF +ENDPROC zmodem_send_data_subpkt(zm, subpkt_type, p, l) + +PROC zmodem_send_pos_header(zm: PTR TO zmodem_t, type,pos, hex) + DEF header[5]:ARRAY OF CHAR + + header[]:=type + header[ZP0]:=(pos AND $ff) + header[ZP1]:=((Shr(pos,8)) AND $ff) + header[ZP2]:=((Shr(pos,16)) AND $ff) + header[ZP3]:=((Shr(pos,24)) AND $ff) + + IF(hex) + RETURN zmodem_send_hex_header(zm, header) + ELSE + RETURN zmodem_send_bin_header(zm, header) + ENDIF +ENDPROC + +PROC zmodem_send_ack(zm: PTR TO zmodem_t, pos) +ENDPROC zmodem_send_pos_header(zm, ZACK, pos, /* Hex? */ TRUE) + +EXPORT PROC zmodem_send_zfin(zm: PTR TO zmodem_t) + DEF zfin_header + zfin_header:=[ ZFIN, 0, 0, 0, 0 ]:CHAR + + lprintf(zm,ZM_LOG_NOTICE,'Finishing Session (Sending ZFIN)') +ENDPROC zmodem_send_hex_header(zm,zfin_header) + +PROC zmodem_send_zabort(zm: PTR TO zmodem_t) + lprintf(zm,ZM_LOG_WARNING,'Aborting Transfer (Sending ZABORT)') +ENDPROC zmodem_send_pos_header(zm, ZABORT, 0, /* Hex? */ TRUE) + +PROC zmodem_send_znak(zm: PTR TO zmodem_t) + lprintf(zm,ZM_LOG_INFO,'Sending ZNAK'); +ENDPROC zmodem_send_pos_header(zm, ZNAK, 0, /* Hex? */ TRUE) + +PROC zmodem_send_zskip(zm: PTR TO zmodem_t) + lprintf(zm,ZM_LOG_INFO,'Sending ZSKIP') +ENDPROC zmodem_send_pos_header(zm, ZSKIP, 0, /* Hex? */ TRUE) + +PROC zmodem_send_zeof(zm: PTR TO zmodem_t, pos) + DEF tempstr[255]:STRING + + StringF(tempstr,'Sending End-of-File (ZEOF) frame (pos=\d)', pos) + lprintf(zm,ZM_LOG_INFO,tempstr) +ENDPROC zmodem_send_pos_header(zm, ZEOF, pos, /* Hex? */ TRUE) + +/* + * rx_raw ; receive a single byte from the line. + * reads as many are available and then processes them one at a time + * check the data stream for 5 consecutive CAN characters; + * and if you see them abort. this saves a lot of clutter in + * the rest of the code; even though it is a very strange place + * for an exit. (but that was wat session abort was all about.) + */ + +PROC zmodem_recv_raw(zm: PTR TO zmodem_t) + DEF c + DEF attempt + DEF p + + p:=zm.zm_recv_byte + + FOR attempt:=0 TO zm.recv_timeout + c:=p(zm,1 /* second timeout */) + EXIT c>=0 + IF(is_cancelled(zm)) THEN RETURN ZCAN + + IF(is_connected(zm)=FALSE) THEN RETURN ABORTED + ENDFOR + IF(attempt>zm.recv_timeout) THEN RETURN TIMEOUT + + + IF(c = CAN) + zm.n_cans:=zm.n_cans+1 + IF(zm.n_cans = 5) + zm.cancelled:=TRUE + lprintf(zm,ZM_LOG_WARNING,'recv_raw: Cancelled remotely') +/* return(TIMEOUT); removed June-12-2005 */ + ENDIF + ELSE + zm.n_cans:=0 + ENDIF + +ENDPROC c + +/* + * rx; receive a single byte undoing any escaping at the + * sending site. this bit looks like a mess. sorry for that + * but there seems to be no other way without incurring a lot + * of overhead. at least like this the path for a normal character + * is relatively short. + */ + +EXPORT PROC zmodem_rx(zm: PTR TO zmodem_t) + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + DEF c + DEF loop = TRUE + + /* + * outer loop for ever so for sure something valid + * will come in; a timeout will occur or a session abort + * will be received. + */ + + WHILE((is_connected(zm)) AND (is_cancelled(zm)=FALSE)) + + REPEAT + c:=zmodem_recv_raw(zm) + IF (c=ZDLE) + loop:=FALSE + ELSEIF (c=XON) OR (c=(XONOR80)) OR (c=XOFF) OR (c=(XOFFOR80)) + chr(c,tempstr) + StringF(tempstr2,'rx: dropping flow ctrl char: \s',tempstr) + lprintf(zm,ZM_LOG_WARNING,tempstr2); + ELSE + /* + * if all control characters should be escaped and + * this one wasnt then its spurious and should be dropped. + */ + IF((zm.escape_ctrl_chars AND (c >= 0) AND ((c AND $60)=0))) + chr(c,tempstr) + StringF(tempstr2,'rx: dropping unescaped ctrl char: \s',tempstr) + ELSE + /* + * normal character; return it. + */ + RETURN c + ENDIF + ENDIF + UNTIL (is_cancelled(zm)) OR (loop=FALSE) + + /* + * ZDLE encoded sequence or session abort. + * (or something illegal; then back to the top) + */ + + loop:=TRUE + WHILE((is_cancelled(zm))=FALSE) AND loop + c:=zmodem_recv_raw(zm) + IF (c=XON) OR (c=(XON OR $80)) OR (c=XOFF) OR (c=(XOFF OR $80)) OR (c=ZDLE) + chr(c,tempstr) + StringF(tempstr2,'"rx: dropping escaped flow ctrl char: \s',tempstr) + lprintf(zm,ZM_LOG_WARNING,tempstr2) + ELSEIF (c=ZCRCE) OR (c=ZCRCG) OR (c=ZCRCQ) OR (c=ZCRCW) + /* these four are really nasty. + * for convenience we just change them into + * special characters by setting a bit outside the + * first 8. that way they can be recognized and still + * be processed as characters by the rest of the code. + */ + ->chr(c,tempstr) + ->StringF(tempstr2,'x: encoding data subpacket type: \s',tempstr) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr2) + RETURN (c OR ZDLEESC) + ELSEIF (c=ZRUB0) + RETURN $7f + ELSEIF (c=ZRUB1) + RETURN $ff + ELSE + IF(c < 0) THEN RETURN c + + IF(zm.escape_ctrl_chars AND ((c AND $60) = 0)) + /* + * a not escaped control character; probably + * something from a network. just drop it. + */ + ->chr(c,tempstr) + ->StringF(tempstr2,'rx: dropping unescaped ctrl char: \s',tempstr) + ->lprintf(zm,ZM_LOG_WARNING,tempstr2) + ->JUMP rxcont; + ELSE + /* + * legitimate escape sequence. + * rebuild the orignal and return it. + */ + IF((c AND $60) = $40) THEN RETURN Eor(c,$40) + ->chr(c,tempstr) + ->StringF(tempstr2,'"rx: illegal sequence: ZDLE \s',tempstr) + ->lprintf(zm,ZM_LOG_WARNING,tempstr2) + loop:=FALSE + ENDIF + ENDIF + ENDWHILE + ENDWHILE + + /* + * not reached (unless cancelled). + */ + +ENDPROC ABORTED + +/* + * receive a data subpacket as dictated by the last received header. + * return 2 with correct packet and end of frame + * return 1 with correct packet frame continues + * return 0 with incorrect frame. + * return TIMEOUT with a timeout + * if an acknowledgement is requested it is generated automatically + * here. + */ + +/* + * data subpacket reception + */ + +PROC zmodem_recv_data32(zm: PTR TO zmodem_t, p: PTR TO CHAR, maxlen, l: PTR TO LONG) + + DEF c,n + DEF rxd_crc + DEF crc + DEF subpkt_type + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + + ->lprintf(zm,ZM_LOG_DEBUG,'recv_data32') + + crc:=$ffffffff + + n:=0 + WHILE 1 + c:=zmodem_rx(zm) + + IF(c < 0) THEN RETURN c + + EXIT (c > $ff) + + IF(n >= maxlen) THEN RETURN SUBPKTOVERFLOW + crc:=ucrc32(zm,c,crc) + p[]:=c + p++ + n++ + ENDWHILE + l[]:=l[]+n + + subpkt_type:=c AND $ff + + crc:=ucrc32(zm,subpkt_type,crc) + + crc:= Not(crc) + + rxd_crc:=zmodem_rx(zm) + rxd_crc:=rxd_crc OR (Shl(zmodem_rx(zm),8)) + rxd_crc:=rxd_crc OR (Shl(zmodem_rx(zm),16)) + rxd_crc:=rxd_crc OR (Shl(zmodem_rx(zm),24)) + + IF(rxd_crc <> crc) + chr(subpkt_type,tempstr) + StringF(tempstr2,'CRC32 ERROR (\h[8], expected: \h[8]) Bytes=\d, subpacket-type=\s',rxd_crc, crc, l[], tempstr) + lprintf(zm,ZM_LOG_WARNING,tempstr2) + RETURN CRCFAILED + ENDIF + /*chr(subpkt_type,tempstr) + StringF(tempstr2,'GOOD CRC32: \h[8] (Bytes=\d, subpacket-type=\s)',crc, l[], tempstr) + lprintf(zm,ZM_LOG_DEBUG,tempstr2)*/ + + zm.ack_file_pos:=zm.ack_file_pos+l[] +ENDPROC subpkt_type + + +PROC zmodem_recv_data16(zm: PTR TO zmodem_t, p:PTR TO CHAR, maxlen, l: PTR TO LONG) + + DEF c,n + DEF subpkt_type; + DEF crc; + DEF rxd_crc + DEF tempstr[255]:STRING + ->DEF tempstr2[255]:STRING + + ->lprintf(zm,ZM_LOG_DEBUG,'recv_data16') + + crc:=0 + + n:=0 + WHILE 1 + c:=zmodem_rx(zm) + + IF(c < 0) THEN RETURN c + + EXIT (c > $ff) + + IF(n >= maxlen) THEN RETURN SUBPKTOVERFLOW + ->crc:=ucrc16(zm,c,crc) + p[]:=c + p++ + n++ + l[]:=l[]+1 + ENDWHILE + l[]:=l[]+n + + subpkt_type:= c AND $ff + + crc:=ucrc16(zm,subpkt_type,crc) + + rxd_crc:=Shl(zmodem_rx(zm),8) + rxd_crc:=rxd_crc OR zmodem_rx(zm) + + IF(rxd_crc <> crc) + StringF(tempstr,'CRC16 ERROR (\h[4], expected: \h[4]) Bytes=\d',rxd_crc, crc, l[]) + lprintf(zm,ZM_LOG_WARNING,tempstr) + RETURN CRCFAILED + ENDIF + /*StringF(tempstr,'GOOD CRC16: \h[4] (Bytes=\d)', crc, l[]) + lprintf(zm,ZM_LOG_DEBUG,tempstr)*/ + + zm.ack_file_pos:=zm.ack_file_pos+l[] + +ENDPROC subpkt_type + + +PROC zmodem_recv_data(zm: PTR TO zmodem_t, p:PTR TO CHAR, maxlen, l: PTR TO LONG, ack) + DEF subpkt_type + DEF n=0 + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + + IF(l=NIL) THEN l:={n} + + ->StringF(tempstr,'recv_data (\d-bit)', IF zm.receive_32bit_data THEN 32 ELSE 16) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr); + + /* + * receive the right type of frame + */ + + l[]:=0; + + IF(zm.receive_32bit_data) + subpkt_type:=zmodem_recv_data32(zm, p, maxlen, l) + ELSE + subpkt_type:=zmodem_recv_data16(zm, p, maxlen, l) + ENDIF + + IF(subpkt_type <= 0) THEN RETURN subpkt_type /* e.g. TIMEOUT, SUBPKTOVERFLOW, CRCFAILED */ + + ->chr(subpkt_type,tempstr) + ->StringF(tempstr,'recv_data received subpacket-type: \s',tempstr2) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr2) + + SELECT subpkt_type + /* + * frame continues non-stop + */ + CASE ZCRCG + RETURN FRAMEOK + /* + * frame ends + */ + CASE ZCRCE + RETURN ENDOFFRAME + /* + * frame continues; ZACK expected + */ + CASE ZCRCQ + IF(ack) THEN zmodem_send_ack(zm, zm.ack_file_pos) + RETURN FRAMEOK + /* + * frame ends; ZACK expected + */ + CASE ZCRCW + IF(ack) THEN zmodem_send_ack(zm, zm.ack_file_pos) + RETURN ENDOFFRAME + ENDSELECT + + chr(subpkt_type,tempstr) + StringF(tempstr,'Received invalid subpacket-type: \s',tempstr) + lprintf(zm,ZM_LOG_WARNING,tempstr2) + +ENDPROC INVALIDSUBPKT + + +PROC zmodem_recv_subpacket(zm: PTR TO zmodem_t, ack) + DEF type + + type:=zmodem_recv_data(zm,zm.rx_data_subpacket,RXSUBPACKETSIZE,NIL,ack) + IF((type<>FRAMEOK) AND (type<>ENDOFFRAME)) + zmodem_send_znak(zm) + RETURN FALSE + ENDIF + +ENDPROC TRUE + +PROC zmodem_recv_nibble(zm: PTR TO zmodem_t) + DEF c + + c:=zmodem_rx(zm) + + IF(c < 0) THEN RETURN c + + IF(c > "9") + IF((c < "a") OR (c > "f")) + /* + * illegal hex; different than expected. + * we might as well time out. + */ + RETURN -1 + ENDIF + c:=c-("a" - 10) + ELSE + IF(c < "0") + /* + * illegal hex; different than expected. + * we might as well time out. + */ + RETURN -1 + ENDIF + c:=c-"0" + ENDIF +ENDPROC c + +PROC zmodem_recv_hex(zm: PTR TO zmodem_t) + + DEF n1 + DEF n0 + DEF ret + ->DEF tempstr[255]:STRING + + n1:=zmodem_recv_nibble(zm) + + IF(n1 < 0) THEN RETURN n1 + + n0:=zmodem_recv_nibble(zm) + + IF(n0 < 0) THEN RETURN n0 + + ret:=(Shl(n1,4)) OR n0 + + ->StringF(tempstr,'recv_hex returning: 0x\h[2]', ret) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr) +ENDPROC ret + +/* + * receive routines for each of the six different styles of header. + * each of these leaves zm.rxd_header_len set to 0 if the end result is + * not a valid header. + */ + +PROC zmodem_recv_bin16_header(zm: PTR TO zmodem_t) + + DEF c + DEF n + DEF crc + DEF rxd_crc + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + + ->lprintf(zm,ZM_LOG_DEBUG,'recv_bin16_header') + + crc:=0 + + FOR n:=0 TO HDRLEN-1 + c:=zmodem_rx(zm) + IF(c < 0) + chr(c,tempstr) + StringF(tempstr2,'recv_bin16_header: \s',tempstr) + lprintf(zm,ZM_LOG_WARNING,tempstr2) + RETURN FALSE + ENDIF + crc:=ucrc16(zm,c,crc) + zm.rxd_header[n]:= c + ENDFOR + + rxd_crc:=Shl(zmodem_rx(zm),8) + rxd_crc:=rxd_crc OR zmodem_rx(zm) + + IF(rxd_crc <> crc) + StringF(tempstr,'CRC16 ERROR: 0x\h, expected: 0x\h', rxd_crc, crc) + lprintf(zm,ZM_LOG_WARNING,tempstr) + RETURN FALSE + ENDIF + /*StringF(tempstr,'GOOD CRC16: \h[4]', crc) + lprintf(zm,ZM_LOG_DEBUG,tempstr);*/ + + zm.rxd_header_len:=5 + +ENDPROC TRUE + + +PROC zmodem_recv_hex_header(zm: PTR TO zmodem_t) + DEF c; + DEF i + DEF crc = 0; + DEF rxd_crc; + DEF tempstr[255]:STRING + + ->lprintf(zm,ZM_LOG_DEBUG,'recv_hex_header') + + FOR i:=0 TO HDRLEN-1 + c:=zmodem_recv_hex(zm) + IF(c<0) THEN RETURN FALSE + crc:=ucrc16(zm,c,crc) + + zm.rxd_header[i]:=c + ENDFOR + + /* + * receive the crc + */ + + c:=zmodem_recv_hex(zm) + + IF(c < 0) THEN RETURN FALSE + + rxd_crc:=Shl(c,8) + + c:=zmodem_recv_hex(zm) + + IF(c < 0) THEN RETURN FALSE + + rxd_crc:=rxd_crc OR c + + IF(rxd_crc = crc) + ->StringF(tempstr,'GOOD CRC16: \h[4]', crc) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr); + zm.rxd_header_len:=5 + ELSE + StringF(tempstr,'CRC16 ERROR: 0x\h, expected: 0x\h', rxd_crc, crc) + lprintf(zm,ZM_LOG_WARNING,tempstr) + RETURN FALSE + ENDIF + + /* + * drop the end of line sequence after a hex header + */ + c:=zmodem_rx(zm) + IF(c = "\b") + /* + * both are expected with CR + */ + zmodem_rx(zm) /* drop LF */ + ENDIF + +ENDPROC TRUE + +PROC zmodem_recv_bin32_header(zm: PTR TO zmodem_t) + DEF c + DEF n + DEF crc + DEF rxd_crc + DEF tempstr[255]:STRING + + ->lprintf(zm,ZM_LOG_DEBUG,'recv_bin32_header') + + crc:=$ffffffff + + FOR n:=0 TO HDRLEN-1 + c:=zmodem_rx(zm) + IF(c < 0) THEN RETURN TRUE + + crc:=ucrc32(zm,c,crc) + zm.rxd_header[n]:=c + ENDFOR + + crc:=Not(crc) + + rxd_crc:=zmodem_rx(zm) + rxd_crc:=rxd_crc OR (Shl(zmodem_rx(zm),8)) + rxd_crc:=rxd_crc OR (Shl(zmodem_rx(zm),16)) + rxd_crc:=rxd_crc OR (Shl(zmodem_rx(zm),24)) + + IF(rxd_crc<>crc) + StringF(tempstr,'CRC32 ERROR (\h[8], expected: \h[8]',rxd_crc, crc) + lprintf(zm,ZM_LOG_WARNING,tempstr); + RETURN FALSE + ENDIF + ->StringF(tempstr,'GOOD CRC32: \h[8]', crc) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr) + + zm.rxd_header_len:=5 +ENDPROC TRUE + +/* + * receive any style header + * if the errors flag is set than whenever an invalid header packet is + * received INVHDR will be returned. otherwise we wait for a good header + * also; a flag (receive_32bit_data) will be set to indicate whether data + * packets following this header will have 16 or 32 bit data attached. + * variable headers are not implemented. + */ + +PROC zmodem_recv_header_raw(zm: PTR TO zmodem_t, errors) + DEF c + DEF frame_type + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + + ->lprintf(zm,ZM_LOG_DEBUG,'recv_header_raw') + + zm.rxd_header_len:=0 + + REPEAT +zmrhcont: + REPEAT + IF((c:=zmodem_recv_raw(zm)))<0 THEN RETURN c + + IF(is_cancelled(zm)) THEN RETURN ZCAN + UNTIL c=ZPAD + + + IF((c:=zmodem_recv_raw(zm)))<0 THEN RETURN c + + IF(c = ZPAD) + IF((c:=zmodem_recv_raw(zm)))<0 THEN RETURN c + ENDIF + + /* + * spurious ZPAD check + */ + + IF(c<>ZDLE) + chr(c,tempstr) + StringF(tempstr2,'recv_header_raw: Expected ZDLE, received: \s',tempstr) + lprintf(zm,ZM_LOG_WARNING,tempstr2) + JUMP zmrhcont + ENDIF + + /* + * now read the header style + */ + + c:=zmodem_rx(zm) + + SELECT c + CASE ZBIN + IF(zmodem_recv_bin16_header(zm))=FALSE THEN RETURN INVHDR + zm.receive_32bit_data:=FALSE + CASE ZHEX + IF(zmodem_recv_hex_header(zm))=FALSE THEN RETURN INVHDR + zm.receive_32bit_data:=FALSE + CASE ZBIN32 + + IF(zmodem_recv_bin32_header(zm))=FALSE THEN RETURN INVHDR + zm.receive_32bit_data:=TRUE + DEFAULT + IF(c < 0) + chr(c,tempstr) + StringF(tempstr2,'recv_header_raw: \s', tempstr) + lprintf(zm,ZM_LOG_WARNING,tempstr2); + RETURN c + ENDIF + /* + * unrecognized header style + */ + chr(c,tempstr) + StringF(tempstr2,'recv_header_raw: UNRECOGNIZED header style: \s',tempstr) + lprintf(zm,ZM_LOG_ERR,tempstr2) + IF(errors) THEN RETURN INVHDR + JUMP zmrhcont + ENDSELECT + IF(errors AND (zm.rxd_header_len = 0)) THEN RETURN INVHDR + + UNTIL (zm.rxd_header_len <> 0) OR (is_cancelled(zm)) + + IF(is_cancelled(zm)) THEN RETURN ZCAN + + /* + * this appears to have been a valid header. + * return its type. + */ + + frame_type:=zm.rxd_header[] + + zm.rxd_header_pos:=(zm.rxd_header[ZP0] OR (Shl(zm.rxd_header[ZP1],8)) OR + (Shl(zm.rxd_header[ZP2],16)) OR (Shl(zm.rxd_header[ZP3],24))) + + SELECT frame_type + CASE ZCRC + zm.crc_request:=zm.rxd_header_pos + CASE ZDATA + zm.ack_file_pos:=zm.rxd_header_pos + CASE ZFILE + zm.ack_file_pos:=0 + IF(zmodem_recv_subpacket(zm,/* ack? */FALSE))=FALSE THEN frame_type:=frame_type OR BADSUBPKT + CASE ZSINIT + IF(zmodem_recv_subpacket(zm,/* ack? */TRUE))=FALSE THEN frame_type:=frame_type OR BADSUBPKT + CASE ZCOMMAND + IF(zmodem_recv_subpacket(zm,/* ack? */TRUE))=FALSE THEN frame_type:=frame_type OR BADSUBPKT + CASE ZFREECNT + zmodem_send_pos_header(zm, ZACK, getFreeDiskSpace(), /* Hex? */ TRUE) + ENDSELECT + +->#if 0 /* def _DEBUG */ + ->frame_desc(frame_type,tempstr) + ->StringF(tempstr2,'recv_header_raw received header type: \s',tempstr) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr2) +->#endif +ENDPROC frame_type + +PROC zmodem_recv_header(zm: PTR TO zmodem_t) + DEF ret + ->DEF tempstr[255]:STRING + ->DEF tempstr2[255]:STRING + + ret:=zmodem_recv_header_raw(zm, FALSE) + + SELECT ret + CASE TIMEOUT + lprintf(zm,ZM_LOG_WARNING,'recv_header TIMEOUT') + CASE INVHDR + lprintf(zm,ZM_LOG_WARNING,'recv_header detected an invalid header') + DEFAULT + ->frame_desc(ret,tempstr) + ->StringF(tempstr2,'recv_header returning: \s (pos=\d)',tempstr, frame_pos(zm, ret)) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr2); + + IF(ret=ZCAN) + zm.cancelled:=TRUE + ELSEIF(ret=ZRINIT) + zmodem_parse_zrinit(zm) + ENDIF + ENDSELECT + +ENDPROC ret + +PROC zmodem_recv_header_and_check(zm: PTR TO zmodem_t) + DEF type=ABORTED + ->DEF tempstr[255]:STRING + ->DEF tempstr2[255]:STRING + + WHILE(is_connected(zm) AND (is_cancelled(zm)=FALSE)) + type:=zmodem_recv_header_raw(zm,TRUE); + + EXIT type = TIMEOUT + + EXIT (type<>INVHDR) AND ((type AND BADSUBPKT) = 0) + + zmodem_send_znak(zm) + ENDWHILE + + ->frame_desc(type,tempstr) + ->StringF(tempstr2,'recv_header_and_check returning: \s (pos=\d)',tempstr,frame_pos(zm, type)) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr2) + + IF(type=ZCAN) THEN zm.cancelled:=TRUE +ENDPROC type + +PROC zmodem_request_crc(zm: PTR TO zmodem_t, length) + zmodem_recv_purge(zm) + zmodem_send_pos_header(zm,ZCRC,length,TRUE) +ENDPROC TRUE + +PROC zmodem_recv_crc(zm: PTR TO zmodem_t, crc:PTR TO LONG) + DEF type + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + + IF(zmodem_data_waiting(zm,zm.crc_timeout))=FALSE + StringF(tempstr,'Timeout waiting for response (\d seconds)',zm.crc_timeout) + lprintf(zm,ZM_LOG_ERR,tempstr) + RETURN FALSE + ENDIF + + IF((type:=zmodem_recv_header(zm)))<>ZCRC + frame_desc(type,tempstr) + StringF(tempstr2,'Received \s instead of ZCRC', tempstr) + lprintf(zm,ZM_LOG_ERR,tempstr2) + RETURN FALSE + ENDIF + IF(crc<>NIL) THEN crc[]:=zm.crc_request +ENDPROC TRUE + +/*PROC zmodem_get_crc(zm: PTR TO zmodem_t,length, crc:PTR TO LONG) + IF(zmodem_request_crc(zm, length)) THEN RETURN zmodem_recv_crc(zm, crc) +ENDPROC FALSE*/ + +PROC zmodem_parse_zrinit(zm: PTR TO zmodem_t) + DEF tempstr[255]:STRING + + zm.can_full_duplex:=(zm.rxd_header[ZF0] AND ZF0_CANFDX) + zm.can_overlap_io:=(zm.rxd_header[ZF0] AND ZF0_CANOVIO) + zm.can_break:=(zm.rxd_header[ZF0] AND ZF0_CANBRK) + zm.can_fcs_32:=(zm.rxd_header[ZF0] AND ZF0_CANFC32) + zm.escape_ctrl_chars:=(zm.rxd_header[ZF0] AND ZF0_ESCCTL) + zm.escape_8th_bit:=(zm.rxd_header[ZF0] AND ZF0_ESC8) + + StringF(tempstr,'Receiver requested mode (0x\h[2]):\r\n\s-duplex, \s overlap I/O, CRC-\d, Escape: \s', + zm.rxd_header[ZF0], + IF(zm.can_full_duplex) THEN 'Full' ELSE 'Half', + IF(zm.can_overlap_io) THEN 'Can' ELSE 'Cannot', + IF(zm.can_fcs_32) THEN 32 ELSE 16, + IF(zm.escape_ctrl_chars) THEN 'ALL' ELSE 'Normal') + lprintf(zm,ZM_LOG_INFO,tempstr) + + zm.recv_bufsize:=(zm.rxd_header[ZP0] OR (Shl(zm.rxd_header[ZP1],8))) + IF(zm.recv_bufsize)<>0 + StringF(tempstr,'Receiver specified buffer size of: \d', zm.recv_bufsize) + lprintf(zm,ZM_LOG_INFO,tempstr) + ENDIF +ENDPROC + +PROC zmodem_get_zrinit(zm: PTR TO zmodem_t) + DEF zrqinit_header + + zrqinit_header:=[ZRQINIT, /* ZF3: */0, 0, 0, /* ZF0: */0 ]:CHAR + /* Note: sz/dsz/fdsz sends $80 in ZF3 because it supports var-length headers. */ + /* We do not, so we send $00, resulting in a CRC-16 value of $0000 as well. */ + + zmodem_send_raw(zm,"r") + zmodem_send_raw(zm,"z") + zmodem_send_raw(zm,"\b") + zmodem_send_hex_header(zm,zrqinit_header) + + IF(zmodem_data_waiting(zm,zm.init_timeout))=FALSE THEN RETURN TIMEOUT + +ENDPROC zmodem_recv_header(zm) + +PROC zmodem_send_zrinit(zm: PTR TO zmodem_t) + DEF zrinit_header + + zrinit_header:=[ZRINIT, 0, 0, 0, 0 ]:CHAR + + zrinit_header[ZF0]:=ZF0_CANFDX + + IF(zm.no_streaming)=FALSE THEN zrinit_header[ZF0]:=zrinit_header[ZF0] OR ZF0_CANOVIO + + IF(zm.can_break) THEN zrinit_header[ZF0]:=zrinit_header[ZF0] OR ZF0_CANBRK + + IF(zm.want_fcs_16)=FALSE THEN zrinit_header[ZF0]:=zrinit_header[ZF0] OR ZF0_CANFC32 + + IF(zm.escape_ctrl_chars) THEN zrinit_header[ZF0]:=zrinit_header[ZF0] OR ZF0_ESCCTL + + IF(zm.escape_8th_bit) THEN zrinit_header[ZF0]:=zrinit_header[ZF0] OR ZF0_ESC8 + + IF(zm.no_streaming AND (zm.recv_bufsize=0)) THEN zm.recv_bufsize:=RXSUBPACKETSIZE + + zrinit_header[ZP0]:=( zm.recv_bufsize AND $ff) + zrinit_header[ZP1]:=Shr(zm.recv_bufsize,8) +ENDPROC zmodem_send_hex_header(zm, zrinit_header) + + +/* Returns ZFIN on success */ +/*PROC zmodem_get_zfin(zm: PTR TO zmodem_t) + + DEF result + DEF type=ZCAN + DEF attempts + + FOR attempts:=0 TO zm.max_errors-1 + EXIT (is_connected(zm)=FALSE) OR (is_cancelled(zm)) + + IF(attempts AND 1) /* Alternate between ZABORT and ZFIN */ + result:=zmodem_send_zabort(zm) + ELSE + result:=zmodem_send_zfin(zm) + ENDIF + IF (result<>0) THEN RETURN result + + EXIT (type:=zmodem_recv_header(zm)) = ZFIN + ENDFOR + + /* + * these Os are formally required; but they don't do a thing + * unfortunately many programs require them to exit + * (both programs already sent a ZFIN so why bother ?) + */ + + IF(type = ZFIN) + zmodem_send_raw(zm,"O") + zmodem_send_raw(zm,"O") + ENDIF +ENDPROC type*/ + + +PROC zmodem_handle_zrpos(zm: PTR TO zmodem_t, pos:PTR TO LONG) + DEF tempstr[255]:STRING + IF(zm.rxd_header_pos <= zm.current_file_size) + IF(pos[] <> zm.rxd_header_pos) + pos[]:=zm.rxd_header_pos + StringF(tempstr,'Resuming transfer from offset: \d',pos[]) + lprintf(zm,ZM_LOG_INFO,tempstr) + ENDIF + RETURN TRUE + ENDIF + StringF(tempstr,'Invalid ZRPOS offset: \d', zm.rxd_header_pos) + lprintf(zm,ZM_LOG_WARNING,tempstr) +ENDPROC FALSE + +PROC zmodem_handle_zack(zm: PTR TO zmodem_t) + DEF tempstr[255]:STRING + IF(zm.rxd_header_pos = zm.current_file_pos) THEN RETURN TRUE + + StringF(tempstr,'ZACK for incorrect offset (\d vs \d)',zm.rxd_header_pos, zm.current_file_pos) + lprintf(zm,ZM_LOG_WARNING,tempstr) +ENDPROC FALSE + +/* + * send from the current position in the file + * all the way to end of file or until something goes wrong. + * (ZNAK or ZRPOS received) + * returns ZRINIT on success. + */ + +PROC zmodem_send_from(zm: PTR TO zmodem_t, fp, pos,sent: PTR TO LONG) + DEF n; + DEF type; + DEF buf_sent=0 + DEF subpkts_sent=0; + DEF ack + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + DEF rx_type + DEF c + DEF p + + IF doSeek(zm,fp,pos,OFFSET_BEGINING)=-1 + StringF(tempstr,'ERROR \d seeking to file offset \d',IoErr(), pos) + lprintf(zm,ZM_LOG_ERR,tempstr) + zmodem_send_pos_header(zm, ZFERR, pos, /* Hex? */ TRUE) + RETURN ZFERR + ENDIF + zm.current_file_pos:=pos + + /* + * send the data in the file + */ + + WHILE(is_connected(zm)) + + /* + * read a block from the file + */ + + n:=doRead(zm,fp,zm.tx_data_subpacket,zm.block_size) + + type:=ZCRCW + + /** ZMODEM.DOC: + ZCRCW data subpackets expect a response before the next frame is sent. + If the receiver does not indicate overlapped I/O capability with the + CANOVIO bit, or sets a buffer size, the sender uses the ZCRCW to allow + the receiver to write its buffer before sending more data. + ***/ + /* Note: we always use ZCRCW for the first frame */ + IF(subpkts_sent OR (n < zm.block_size)) + /* ZMODEM.DOC: + In the absence of fatal error, the sender eventually encounters end of + file. If the end of file is encountered within a frame, the frame is + closed with a ZCRCE data subpacket which does not elicit a response + except in case of error. + */ + IF(n < zm.block_size) + type:=ZCRCE + ELSE + IF(zm.can_overlap_io AND (zm.no_streaming=FALSE) AND ((zm.recv_bufsize=0) OR ((buf_sent+n) < zm.recv_bufsize))) + type:=ZCRCG + ELSE /* Send a ZCRCW frame */ + buf_sent:=0; + ENDIF + ENDIF + ENDIF + + /* Note: No support for sending ZCRCQ data sub-packets here */ + + IF(zmodem_send_data(zm, type, zm.tx_data_subpacket, n))<>0 THEN RETURN TIMEOUT + + zm.current_file_pos:=zm.current_file_pos+n + IF(zm.current_file_pos > zm.current_file_size) THEN zm.current_file_size:=zm.current_file_pos + subpkts_sent++ + + p:=zm.zm_progress + IF(p<>NIL) THEN p(zm, zm.current_file_pos) + zm.new_file:=FALSE + + IF((type = ZCRCW) OR (type = ZCRCE)) + ->chr(type,tempstr) + ->StringF(tempstr2,'Sent end-of-frame (\s sub-packet)', tempstr) + ->lprintf(zm,ZM_LOG_DEBUG,tempstr2) + IF(type=ZCRCW) /* ZACK expected */ + ->lprintf(zm,ZM_LOG_DEBUG,'Waiting for ZACK') + WHILE(is_connected(zm)) + IF((ack:=zmodem_recv_header(zm)))<>ZACK THEN RETURN ack + + IF(is_cancelled(zm)) THEN RETURN ZCAN + + EXIT zmodem_handle_zack(zm) + ENDWHILE + ENDIF + ENDIF + + IF(sent<>NIL) THEN sent[]:=sent[]+n + + buf_sent:=buf_sent+n + + IF(n < zm.block_size) + StringF(tempstr,'send_from: end of file (or read error) reached at offset: \d',zm.current_file_pos) + lprintf(zm,ZM_LOG_DEBUG,tempstr) + zmodem_send_zeof(zm, zm.current_file_pos); + + ->send a progress update at end of file just to be safe + p:=zm.zm_progress + IF(p<>NIL) THEN p(zm, zm.current_file_size) + + RETURN zmodem_recv_header(zm) /* If this is ZRINIT, Success */ + ENDIF + + /* + * characters from the other side + * check out that header + */ + + WHILE(zmodem_data_waiting(zm, IF zm.consecutive_errors THEN 1 ELSE 0) AND (is_cancelled(zm)=FALSE) AND (is_connected(zm))) + lprintf(zm,ZM_LOG_DEBUG,'Back-channel traffic detected:') + IF((c:=zmodem_recv_raw(zm)))<0 THEN RETURN c + + IF(c = ZPAD) + /* ZMODEM.DOC: + FULL STREAMING WITH SAMPLING + If one of these characters (CAN or ZPAD) is seen, an + empty ZCRCE data subpacket is sent. + */ + zmodem_send_data(zm, ZCRCE, NIL, 0) + rx_type:=zmodem_recv_header(zm) + chr(rx_type,tempstr) + StringF(tempstr2,'Received back-channel data: \s', tempstr) + lprintf(zm,ZM_LOG_DEBUG,tempstr2) + IF(rx_type >= 0) THEN RETURN rx_type + ELSE + chr(c,tempstr) + StringF(tempstr2,'Received: \s',tempstr) + lprintf(zm,ZM_LOG_DEBUG,tempstr2) + ENDIF + ENDWHILE + + IF (is_cancelled(zm)) THEN RETURN ZCAN + + zm.consecutive_errors:=0 + + IF(zm.block_size < zm.max_block_size) + zm.block_size:=zm.block_size*2 + IF(zm.block_size > zm.max_block_size) THEN zm.block_size:=zm.max_block_size; + ENDIF + ENDWHILE + zm.new_file:=FALSE + + ->lprintf(zm,ZM_LOG_DEBUG,'send_from: returning unexpectedly!') + + /* + * end of file reached. + * should receive something... so fake ZACK + */ + +ENDPROC ZACK + +EXPORT PROC zmodem_send_files(zm: PTR TO zmodem_t,sent: PTR TO LONG, timetaken:PTR TO LONG) + DEF p,res,init=TRUE + DEF fname[255]:STRING + + timetaken[]:=0 + p:=zm.zm_firstfile + IF p<>NIL + IF p(zm,fname) + REPEAT + res:=zmodem_send_file(zm, fname, init,sent, timetaken) + IF res=FALSE THEN RETURN res + init:=FALSE + IF res + p:=zm.zm_nextfile + res:=FALSE + IF p<>NIL THEN res:=p(zm,fname) + ENDIF + UNTIL res=FALSE + zmodem_send_zfin(zm) + zmodem_recv_header(zm) + zmodem_send_raw(zm,"O") + zmodem_send_raw(zm,"O") + zmodem_flush(zm) + + ENDIF + ENDIF +ENDPROC TRUE + +/* + * send a file; returns true when session is successful. (or file is skipped) + */ + +PROC zmodem_send_file(zm: PTR TO zmodem_t, fname: PTR TO CHAR, request_init,sent: PTR TO LONG, timetaken: PTR TO LONG) + + DEF pos=0 + DEF sent_bytes + DEF p: PTR TO CHAR + DEF zfile_frame: PTR TO CHAR + DEF type + DEF i + DEF fp + DEF attempts + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + DEF loop = TRUE + DEF t1,t2,t + + fp:=doOpen(zm,fname,MODE_OLDFILE) + IF fp<=0 + StringF(tempstr,'Error opening file \s',fname) + lprintf(zm,ZM_LOG_ERR,tempstr) + RETURN FALSE + ENDIF + + zfile_frame:= NEW [ ZFILE, 0, 0, 0, 0 ]:CHAR + + IF(zm.block_size = 0) THEN zm.block_size:=ZBLOCKLEN; + + IF(zm.block_size < 128) THEN zm.block_size:=128; + + IF(zm.block_size > TXSUBPACKETSIZE) THEN zm.block_size:=TXSUBPACKETSIZE + + IF(zm.max_block_size < zm.block_size) THEN zm.max_block_size:=zm.block_size; + + IF(zm.max_block_size > RXSUBPACKETSIZE) THEN zm.max_block_size:= RXSUBPACKETSIZE + + zm.file_skipped:=FALSE + + IF(zm.no_streaming) THEN lprintf(zm,ZM_LOG_WARNING,'Streaming disabled') + + IF(request_init) + zm.errors:=0 + WHILE (zm.errors<=zm.max_errors) AND (is_cancelled(zm)=FALSE) AND (is_connected(zm)) + IF(zm.errors) + StringF(tempstr,'Sending ZRQINIT (\d of \d)',zm.errors+1,zm.max_errors+1) + lprintf(zm,ZM_LOG_NOTICE,tempstr) + ELSE + lprintf(zm,ZM_LOG_INFO,'Sending ZRQINIT') + ENDIF + i:=zmodem_get_zrinit(zm) + EXIT i = ZRINIT + frame_desc(i,tempstr) + StringF(tempstr2,'send_file: received \s instead of ZRINIT',tempstr) + lprintf(zm,ZM_LOG_WARNING,tempstr2); + zm.errors:=zm.errors+1 + ENDWHILE + IF((zm.errors>=zm.max_errors) OR (is_cancelled(zm)) OR (is_connected(zm))=FALSE) + doClose(zm,fp) + RETURN FALSE + ENDIF + ENDIF + lprintf(zm,ZM_LOG_INFO,'Sending ZRQINIT done') + + zm.current_file_size:=getFileSize(zm,fp) + strcopy(zm.current_file_name,fname) + + /* + * the file exists. now build the ZFILE frame + */ + + /* + * set conversion option + * (not used; always binary) + */ + + zfile_frame[ZF0]:=ZF0_ZCBIN; + + /* + * management option + */ + + IF(zm.management_protect) + zfile_frame[ZF1]:=ZF1_ZMPROT + lprintf(zm,ZM_LOG_DEBUG,'send_file: protecting destination') + ELSEIF(zm.management_clobber) + zfile_frame[ZF1]:=ZF1_ZMCLOB + lprintf(zm,ZM_LOG_DEBUG,'send_file: overwriting destination') + ELSEIF(zm.management_newer) + zfile_frame[ZF1]:=ZF1_ZMNEW + lprintf(zm,ZM_LOG_DEBUG,'send_file: overwriting destination if newer') + ELSE + zfile_frame[ZF1]:=ZF1_ZMCRC; + ENDIF + + /* + * transport options + * (just plain normal transfer) + */ + + zfile_frame[ZF2]:=ZF2_ZTNOR + + /* + * extended options + */ + + zfile_frame[ZF3]:=0 + + /* + * now build the data subpacket with the file name and lots of other + * useful information. + */ + + /* + * first enter the name and a 0 + */ + + p:=zm.tx_data_subpacket + + strcopy(zm.tx_data_subpacket,FilePart(fname),TXSUBPACKETSIZE-1) + zm.tx_data_subpacket[(TXSUBPACKETSIZE)-1]:=0 + + p:=p+StrLen(p) + 1 + + StringF(tempstr,'\d \d 0 0 \d \d 0', + zm.current_file_size, /* use for estimating only, could be zero! */ + 0, ->(uintmax_t)s.st_mtime + zm.files_remaining, + zm.bytes_remaining) + strcopy(p,tempstr,-1) + + p:=p+StrLen(p) + 1 + + attempts:=0 + WHILE 1 +zsendcont1: + attempts++ + + IF(attempts > zm.max_errors) + doClose(zm,fp) + RETURN FALSE + ENDIF + + /* + * send the header and the data + */ + + StringF(tempstr,'Sending ZFILE frame: ''\s''',zm.tx_data_subpacket+StrLen(zm.tx_data_subpacket)+1) + lprintf(zm,ZM_LOG_DEBUG,tempstr) + + IF((i:=zmodem_send_bin_header(zm,zfile_frame)))<>0 + StringF(tempstr,'zmodem_send_bin_header returned \d',i) + lprintf(zm,ZM_LOG_DEBUG,tempstr) + JUMP zsendcont1 + ENDIF + + IF((i:=zmodem_send_data_subpkt(zm,ZCRCW,zm.tx_data_subpacket,p - zm.tx_data_subpacket)))<>0 + StringF(tempstr,'zmodem_send_data_subpkt returned \d',i) + lprintf(zm,ZM_LOG_DEBUG,tempstr) + JUMP zsendcont1 + ENDIF + /* + * wait for anything but an ZACK packet + */ +zsendignore: + REPEAT + type:=zmodem_recv_header(zm) + IF(is_cancelled(zm)) + doClose(zm,fp) + RETURN FALSE + ENDIF + + UNTIL (type<>ZACK) OR (is_connected(zm)=FALSE) + + IF(is_connected(zm)=FALSE) + doClose(zm,fp) + RETURN FALSE + ENDIF + +->if 0 + ->StringF(tempstr,'type : \d',type) + ->lprintf(zm,ZM_LOG_INFO,tempstr); +->#endif + + IF(type = ZSKIP) + zm.file_skipped:=TRUE + lprintf(zm,ZM_LOG_WARNING,'File skipped by receiver') + doClose(zm,fp) + RETURN TRUE + ENDIF + + IF(type = ZCRC) + IF(zm.crc_request=0) + lprintf(zm,ZM_LOG_NOTICE,'Receiver requested CRC of entire file') + ELSE + StringF(tempstr,'Receiver requested CRC of first \d bytes',zm.crc_request) + lprintf(zm,ZM_LOG_NOTICE,tempstr) + ENDIF + zmodem_send_pos_header(zm,ZCRC,fcrc32(zm,fp,zm.crc_request),TRUE); + type:=zmodem_recv_header(zm) + ENDIF + + IF (type=ZRINIT) + lprintf(zm,ZM_LOG_WARNING,'ignoring duplicate ZRINIT') + JUMP zsendignore + ENDIF + + EXIT type = ZRPOS + ENDWHILE + + IF(zmodem_handle_zrpos(zm, {pos}))=FALSE + doClose(zm,fp) + RETURN FALSE + ENDIF + + zm.transfer_start_pos:=pos; + + t1,t2:=getZmSystemTime() + zm.transfer_start_time1:=t1 + zm.transfer_start_time2:=t2 + + doSeek(zm,fp,0,OFFSET_BEGINNING) + zm.errors:=0 + zm.consecutive_errors:=0 + + StringF(tempstr,'Sending \s from offset \d', fname, pos) + lprintf(zm,ZM_LOG_DEBUG,tempstr) + zm.new_file:=TRUE + + loop:=TRUE + WHILE loop +zsendcont2: + /* + * and start sending + */ + + type:=zmodem_send_from(zm, fp, pos, {sent_bytes}) + + t1,t2:=getZmSystemTime() + t:=Mul((t1-zm.transfer_start_time1),50)+t2-zm.transfer_start_time2 + + IF(sent<>NIL) THEN sent[]:=sent[]+sent_bytes + IF(timetaken<>NIL) THEN timetaken[]:=timetaken[]+t + + IF(is_connected(zm))=FALSE + doClose(zm,fp) + RETURN FALSE + ENDIF + + EXIT (type = ZFERR) OR (type = ZABORT) OR (is_cancelled(zm)) + + IF(type = ZSKIP) + zm.file_skipped:=TRUE + StringF(tempstr,'File skipped by receiver at offset: \d', pos + sent_bytes) + lprintf(zm,ZM_LOG_WARNING,tempstr) + /* ZOC sends a ZRINIT after mid-file ZSKIP, so consume the ZRINIT here */ + zmodem_recv_header(zm) + doClose(zm,fp) + RETURN TRUE + ENDIF + + IF(type=ZRINIT) + doClose(zm,fp) + RETURN TRUE /* Success */ + ENDIF + + IF(type=ZACK) + IF (zmodem_handle_zack(zm)) + pos:=pos+sent_bytes + JUMP zsendcont2 + ENDIF + ENDIF + + /* Error of some kind */ + + chr(type,tempstr) + StringF(tempstr,'Received \s at offset: \d', tempstr, zm.current_file_pos) + lprintf(zm,ZM_LOG_ERR,tempstr) + + IF((zm.block_size = zm.max_block_size) AND (zm.max_block_size > ZBLOCKLEN)) THEN zm.max_block_size:=Div(zm.max_block_size,2) + + IF(zm.block_size > 128) THEN zm.block_size:= Div(zm.block_size,2) + + zm.errors:=zm.errors+1 + zm.consecutive_errors:=zm.consecutive_errors+1 + EXIT(zm.consecutive_errors > zm.max_errors) /* failure */ + + IF(type=ZRPOS) + IF(zmodem_handle_zrpos(zm, {pos}))=FALSE THEN loop:=FALSE + ENDIF + ENDWHILE + + chr(type,tempstr) + StringF(tempstr2,'Transfer failed on receipt of: \s', tempstr) + lprintf(zm,ZM_LOG_WARNING,tempstr2) + END zfile_frame + doClose(zm,fp) +ENDPROC FALSE + +EXPORT PROC zmodem_recv_files(zm: PTR TO zmodem_t, download_dir:PTR TO CHAR,bytes_received: PTR TO LONG,timetaken:PTR TO LONG) + DEF fpath[MAX_PATH]:STRING + DEF fp + DEF l + DEF skip + DEF loop + DEF b + DEF crc + DEF rcrc + DEF bytes + DEF kbytes + DEF start_bytes + DEF files_received=0 + DEF t + DEF cps + DEF timeout + DEF errors + DEF tempstr[255]:STRING + DEF brk=FALSE + DEF p + DEF t1,t2 + + timetaken[]:=0 + zm.current_file_num:=1 + WHILE(zmodem_recv_init(zm)=ZFILE) + bytes:=zm.current_file_size; + kbytes:=Shr(bytes,10) + IF(kbytes<1) THEN kbytes:=0 + StringF(tempstr,'Downloading \s \d KBytes) via Zmodem', zm.current_file_name, kbytes) + lprintf(zm,ZM_LOG_INFO,tempstr) + + REPEAT /* try */ + skip:=TRUE + loop:=FALSE + + IF fpath[StrLen(fpath)-1]<>":" THEN StrAdd(fpath,'/') + StringF(fpath,'\s\s',download_dir,zm.current_file_name) + StringF(tempstr,'fpath=\s',fpath) + lprintf(zm,ZM_LOG_DEBUG,tempstr) + + IF(dupe_check(zm,fpath)) + lprintf(zm,ZM_LOG_WARNING,'dupe check triggered') + brk:=TRUE + JUMP zreccont1 + ENDIF + + IF(fexist(fpath)) + l:=flength(fpath) + StringF(tempstr,'\s already exists (\d bytes)',fpath,l) + lprintf(zm,ZM_LOG_WARNING,tempstr); + IF(l>=bytes) + StringF(tempstr,'Local file size \d >= remote file size \d',l,bytes) + lprintf(zm,ZM_LOG_WARNING,tempstr) + p:=zm.zm_duplicate_filename + IF(p=NIL) + brk:=TRUE + JUMP zreccont1 + ELSE + IF(l > bytes) + IF(p(zm, zm)) + loop:=TRUE + JUMP zreccont1 + ENDIF + brk:=TRUE + JUMP zreccont1 + ENDIF + ENDIF + ENDIF + IF((fp:=doOpen(zm,fpath,MODE_OLDFILE)))=NIL + StringF(tempstr,'Error \d opening \s', IoErr(), fpath) + lprintf(zm,ZM_LOG_ERR,tempstr); + brk:=TRUE + JUMP zreccont1 + ENDIF + ->setvbuf(fp,NULL,_IOFBF,$10000); + + StringF(tempstr,'Requesting CRC of remote file: \s', zm.current_file_name) + lprintf(zm,ZM_LOG_NOTICE,tempstr) + IF(zmodem_request_crc(zm, l))=FALSE + doClose(zm,fp) + lprintf(zm,ZM_LOG_ERR,'Failed to request CRC of remote file') + brk:=TRUE + JUMP zreccont1 + ENDIF + StringF(tempstr,'Calculating CRC of: \s', fpath) + lprintf(zm,ZM_LOG_NOTICE,tempstr) + crc:=fcrc32(zm,fp,l); /* Warning: 4GB limit! */ + doClose(zm,fp) + StringF(tempstr,'CRC of \s (\d bytes): \h[8]',fpath, l, crc) + lprintf(zm,ZM_LOG_INFO,tempstr) + StringF(tempstr,'Waiting for CRC of remote file: \s', zm.current_file_name) + lprintf(zm,ZM_LOG_NOTICE,tempstr) + IF(zmodem_recv_crc(zm,{rcrc}))=FALSE + lprintf(zm,ZM_LOG_ERR,'Failed to get CRC of remote file') + ->brk:=TRUE + ->JUMP zreccont1 + rcrc:=crc + ENDIF + IF(crc<>rcrc) + StringF(tempstr,'Remote file has different CRC value: \h[8]', rcrc) + lprintf(zm,ZM_LOG_WARNING,tempstr) + p:=zm.zm_duplicate_filename + IF(p) + IF(p(zm, zm)) + loop:=TRUE + JUMP zreccont1 + ENDIF + ENDIF + brk:=TRUE + JUMP zreccont1 + ENDIF + IF(l=bytes) + lprintf(zm,ZM_LOG_INFO,'CRC, length, and filename match.') + brk:=TRUE + JUMP zreccont1 + ENDIF + StringF(tempstr,'Resuming download of \s',fpath) + lprintf(zm,ZM_LOG_INFO,tempstr) + ENDIF + + t1,t2:=getZmSystemTime() + zm.transfer_start_time1:=t1 + zm.transfer_start_time2:=t2 + + IF((fp:=doOpen(zm,fpath,MODE_READWRITE)))=NIL + StringF(tempstr,'Error \d opening/creating/appending \s',IoErr(),fpath) + lprintf(zm,ZM_LOG_ERR,tempstr) + brk:=TRUE + JUMP zreccont1 + ENDIF + + start_bytes:=getFileSize(zm,fp) + IF(start_bytes < 0) + doClose(zm,fp); + + StringF(tempstr,'Invalid file length \d: \s', start_bytes, fpath) + lprintf(zm,ZM_LOG_ERR,tempstr) + brk:=TRUE + JUMP zreccont1 + ENDIF + + skip:=FALSE + errors:=zmodem_recv_file_data(zm,fp,start_bytes) + + doClose(zm,fp) + + t1,t2:=getZmSystemTime() + t:=Mul((t1-zm.transfer_start_time1),50)+t2-zm.transfer_start_time2 + IF t<=0 THEN t:=1 + IF timetaken<>NIL THEN timetaken[]:=timetaken[]+t + + l:=flength(fpath); + IF(errors AND (l=0)) /* aborted/failed download */ + IF(DeleteFile(fpath)) /* don't save 0-byte file */ + StringF(tempstr,'Error \d removing \s',IoErr(),fpath) + lprintf(zm,ZM_LOG_ERR,tempstr); + ELSE + StringF(tempstr,'Deleted 0-byte file \s',fpath) + lprintf(zm,ZM_LOG_INFO,tempstr) + ENDIF + ELSE + IF(l<>bytes) + StringF(tempstr,'Incomplete download \d bytes received, expected \d',l,bytes) + lprintf(zm,ZM_LOG_WARNING,tempstr) + upload_failed(zm,fpath) + ELSE + b:=l-start_bytes + + IF t>0 + IF b>40000000 + cps:=Div(b,Div(t,50)) + ELSE + cps:=Div(Mul(b,50),t) + ENDIF + ELSE + cps:=b + ENDIF + IF cps=0 THEN cps:=1 + StringF(tempstr,'Received \d bytes successfully (\d CPS)',b,cps) + lprintf(zm,ZM_LOG_INFO,tempstr) + files_received++ + IF(bytes_received<>NIL) THEN bytes_received[]:=bytes_received[]+b + upload_completed(zm,fpath) + ENDIF + IF(zm.current_file_time) THEN SetFileDate(fpath,zm.current_file_time) + ENDIF + +zreccont1: + UNTIL (loop=FALSE) OR (brk=TRUE) + /* finally */ + IF(skip) + lprintf(zm,ZM_LOG_WARNING,'Skipping file') + zmodem_send_zskip(zm) + ENDIF + zm.current_file_num:=zm.current_file_num+1 + ENDWHILE + IF(zm.local_abort) THEN zmodem_send_zabort(zm) + + /* wait for "over-and-out" */ + timeout:=zm.recv_timeout + zm.recv_timeout:=2 + IF(zmodem_rx(zm)="O") THEN zmodem_rx(zm) + zm.recv_timeout:=timeout + +ENDPROC files_received + + +PROC zmodem_recv_init(zm: PTR TO zmodem_t) + + DEF type=CAN; + DEF errors; + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + + ->lprintf(zm,ZM_LOG_DEBUG,'recv_init') + +->#if 0 +-> while(is_connected(zm) && !is_cancelled(zm) && (ch=zm.recv_byte(zm,0))!=NOINP) +-> lprintf(zm,ZM_LOG_DEBUG,"Throwing out received: %s",chr((uchar)ch)); +->#endif + + errors:=0 + WHILE ((errors<=zm.max_errors) AND (is_cancelled(zm)=FALSE) AND (is_connected(zm))) + IF(errors) + StringF(tempstr,'Sending ZRINIT (\d of \d)',errors+1, zm.max_errors+1) + lprintf(zm,ZM_LOG_NOTICE,tempstr) + ELSE + lprintf(zm,ZM_LOG_INFO,'Sending ZRINIT') + ENDIF + zmodem_send_zrinit(zm) + + type:=zmodem_recv_header(zm) + + EXIT zm.local_abort + + IF(type=TIMEOUT) + errors++ + JUMP zmicont1 + ENDIF + + chr(type,tempstr) + StringF(tempstr2,'recv_init: Received \s',tempstr) + lprintf(zm,ZM_LOG_DEBUG,tempstr2); + + IF(type=ZFILE) + zmodem_parse_zfile_subpacket(zm) + RETURN type + ENDIF + + IF(type=ZFIN) + zmodem_send_zfin(zm) /* ACK */ + RETURN type + ENDIF + + frame_desc(type,tempstr) + StringF(tempstr2,'recv_init: Received \s instead of ZFILE or ZFIN',tempstr); + lprintf(zm,ZM_LOG_WARNING,tempstr2) + StringF(tempstr,'ZF0=\h[2] ZF1=\h[2] ZF2=\h[2] ZF3=\h[2]',zm.rxd_header[ZF0],zm.rxd_header[ZF1],zm.rxd_header[ZF2],zm.rxd_header[ZF3]) + lprintf(zm,ZM_LOG_DEBUG,tempstr) + errors++ + +zmicont1: + + ENDWHILE + +ENDPROC type + +PROC zmodem_parse_zfile_subpacket(zm: PTR TO zmodem_t) + + DEF i + DEF mode=0 + DEF serial=-1 + DEF tempstr[255]:STRING + DEF tmptime + DEF tmp,s,r + + strcopy(zm.current_file_name,zm.rx_data_subpacket) + + zm.current_file_size:=0 + zm.current_file_time:=0 + zm.files_remaining:=0 + zm.bytes_remaining:=0 + +/* i=sscanf((char*)zm.rx_data_subpacket+strlen((char*)zm.rx_data_subpacket)+1,"%"SCNd64" %lo %o %lo %u %"SCNd64 + ,&zm.current_file_size /* file size (decimal) */ + ,&tmptime /* file time (octal unix format) */ + ,&mode /* file mode */ + ,&serial /* program serial number */ + ,&zm.files_remaining /* remaining files to be sent */ + ,&zm.bytes_remaining /* remaining bytes to be sent */ + );*/ + + s:=zm.rx_data_subpacket+StrLen(zm.rx_data_subpacket)+1 + tmp,r:=Val(s) + zm.current_file_size:=tmp + s:=s+r + tmptime,r:=Val(s) + s:=s+r + mode,r:=Val(s) + s:=s+r + serial,r:=Val(s) + tmp,r:=Val(s) + zm.files_remaining:=tmp + s:=s+r + tmp,r:=Val(s) + zm.bytes_remaining:=tmp + + zm.current_file_time:=tmptime + + StringF(tempstr,'Zmodem file (ZFILE) data (\d fields): \d',i, zm.rx_data_subpacket+StrLen(zm.rx_data_subpacket)+1) + lprintf(zm,ZM_LOG_DEBUG,tempstr); + + IF(zm.files_remaining)=FALSE THEN zm.files_remaining:=1 + + IF(zm.bytes_remaining)=FALSE THEN zm.bytes_remaining:= zm.current_file_size + + IF(zm.total_files)=FALSE THEN zm.total_files:=zm.files_remaining + + IF(zm.total_bytes)=FALSE THEN zm.total_bytes:=zm.bytes_remaining +ENDPROC + +/* + * receive file data until the end of the file or until something goes wrong. + * the name is only used to show progress + */ + +PROC zmodem_recv_file_data(zm: PTR TO zmodem_t, fp, offset) + DEF type=0 + DEF errors=0 + DEF pos + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + DEF brk=FALSE + + zm.transfer_start_pos:=offset + + IF(doSeek(zm,fp,offset,OFFSET_BEGINNING))<0 + StringF(tempstr,'ERROR \d seeking to file offset \d',IoErr(), offset) + lprintf(zm,ZM_LOG_ERR,tempstr) + zmodem_send_pos_header(zm, ZFERR, offset, /* Hex? */ TRUE) + RETURN 1 /* errors */ + ENDIF + + zm.new_file:=TRUE + pos:=offset + + + /* zmodem.doc: + + The zmodem receiver uses the file length [from ZFILE data] as an estimate only. + It may be used to display an estimate of the transmission time, + and may be compared with the amount of free disk space. The + actual length of the received file is determined by the data + transfer. A file may grow after transmission commences, and + all the data will be sent. + */ + + WHILE((errors<=zm.max_errors) AND (is_connected(zm)) AND (is_cancelled(zm)=FALSE)) + + IF(pos>zm.current_file_size) THEN zm.current_file_size:= pos + + IF((zm.max_file_size<>0) AND (pos >= zm.max_file_size)) + StringF(tempstr,'Specified maximum file size (\d bytes) reached at offset \d',zm.max_file_size, pos) + lprintf(zm,ZM_LOG_WARNING,tempstr) + + zmodem_send_pos_header(zm, ZFERR, pos, /* Hex? */ TRUE); + brk:=TRUE + ENDIF + EXIT brk + + IF(type<>ENDOFFRAME) THEN zmodem_send_pos_header(zm, ZRPOS, pos, /* Hex? */ TRUE) + + type:=zmodem_recv_file_frame(zm,fp,{pos}) + zm.new_file:=FALSE + + EXIT ((type = ZEOF) OR (type = ZFIN)) + + IF(type=ENDOFFRAME) + StringF(tempstr,'Received complete frame at offset: \d', pos) + lprintf(zm,ZM_LOG_ERR,tempstr) + ELSE + IF((type>0) AND (zm.local_abort=FALSE)) + chr(type,tempstr) + StringF(tempstr2,'Received \s at offset: \d', tempstr, pos) + lprintf(zm,ZM_LOG_ERR,tempstr2) + ENDIF + errors++ + ENDIF + ENDWHILE + zm.new_file:=FALSE + + /* + * wait for the eof header + */ + errors:=0 + WHILE (errors<=zm.max_errors) AND (is_cancelled(zm)=FALSE) AND (type<>ZEOF) AND (type<>ZFIN) + type:=zmodem_recv_header_and_check(zm) + errors++ + ENDWHILE +ENDPROC errors + + +PROC zmodem_recv_file_frame(zm: PTR TO zmodem_t, fp,pos:PTR TO LONG) + DEF n + DEF type + DEF attempt + DEF tempstr[255]:STRING + DEF tempstr2[255]:STRING + DEF p + /* + * wait for a ZDATA header with the right file offset + * or a timeout or a ZFIN + */ + + attempt:=0 + WHILE 1 + IF(attempt>=zm.max_errors) THEN RETURN TIMEOUT + + type:=zmodem_recv_header(zm) + IF (type=ZEOF) + /* ZMODEM.DOC: + If the receiver has not received all the bytes of the file, + the receiver ignores the ZEOF because a new ZDATA is coming. + */ + IF(zm.rxd_header_pos=pos[]) THEN RETURN type + + StringF(tempstr,'Ignoring ZEOF as all bytes (\d) have not been received',zm.rxd_header_pos) + lprintf(zm,ZM_LOG_WARNING,tempstr); + JUMP recframecont + ELSEIF (type=ZFIN) OR (type=TIMEOUT) + RETURN type + ENDIF + IF((is_cancelled(zm)) OR (is_connected(zm))=FALSE) THEN RETURN ZCAN + + EXIT type=ZDATA + + frame_desc(type,tempstr) + StringF(tempstr2,'Received \s instead of ZDATA frame', tempstr) + lprintf(zm,ZM_LOG_WARNING,tempstr2) + +recframecont: + + attempt++ + ENDWHILE + + IF(zm.rxd_header_pos<>pos[]) + StringF(tempstr,'Received wrong ZDATA frame (\d vs \d)"',zm.rxd_header_pos, pos[]) + lprintf(zm,ZM_LOG_WARNING,tempstr) + RETURN FALSE + ENDIF + + REPEAT + ->lprintf(zm,ZM_LOG_DEBUG,'recv_file_frame zmodem_recv_data') + type:=zmodem_recv_data(zm,zm.rx_data_subpacket,RXSUBPACKETSIZE,{n},TRUE) + ->lprintf(zm,ZM_LOG_DEBUG,'recv_file_frame zmodem_recv_data complete') + +/* fprintf(stderr,"packet len %d type %d\n",n,type); +*/ + IF ((type = ENDOFFRAME) OR (type = FRAMEOK)) + IF(doWrite(zm,fp,zm.rx_data_subpacket,n)<>n) + StringF(tempstr,'ERROR \d writing \d bytes at file offset \d',IoErr(), n,pos[]) + lprintf(zm,ZM_LOG_ERR,tempstr) + zmodem_send_pos_header(zm, ZFERR, pos[], /* Hex? */ TRUE) + RETURN FALSE + ENDIF + pos[]:=pos[]+n + ENDIF + + IF(type=FRAMEOK) THEN zm.block_size:=n; + + p:=zm.zm_progress + IF(p<>NIL) THEN p(zm, pos[]) + zm.new_file:=FALSE + + IF(is_cancelled(zm)) THEN RETURN ZCAN + UNTIL type<>FRAMEOK + lprintf(zm,ZM_LOG_DEBUG,'recv_file_frame complete') +ENDPROC type + +EXPORT PROC zmodem_init(zm: PTR TO zmodem_t, cbdata: PTR TO CHAR, + lputs,progress,recv_byte,is_connected,is_cancelled, + data_waiting,upload_completed,upload_failed,dupecheck, + flush,duplicate_filename,fileopen,fileclose,fileseek, + fileread,filewrite,firstfile,nextfile, + block_size,max_errors) + + ->memset(zm,0,SIZEOF zmodem_t) + + /* Use sane default values */ + zm.init_timeout:=10 /* seconds */ + zm.send_timeout:=10 /* seconds (reduced from 15) */ + zm.recv_timeout:=10 /* seconds (reduced from 20) */ + zm.crc_timeout:=120 /* seconds */ + + zm.can_break:=TRUE + zm.can_fcs_32:=TRUE + zm.want_fcs_16:=FALSE + zm.escape_ctrl_chars:=FALSE + zm.escape_8th_bit:=FALSE + zm.no_streaming:=FALSE + + IF block_size<>0 + zm.block_size:=block_size + zm.max_block_size:=block_size + ELSE + zm.block_size:=ZBLOCKLEN + zm.max_block_size:=ZBLOCKLEN + ENDIF + + IF max_errors<>0 THEN zm.max_errors:=max_errors ELSE zm.max_errors:=9 + + + zm.cbdata:=cbdata + zm.zm_lputs:=lputs + zm.zm_progress:=progress + zm.zm_recv_byte:=recv_byte + zm.zm_is_connected:=is_connected + zm.zm_is_cancelled:=is_cancelled + zm.zm_data_waiting:=data_waiting + zm.zm_upload_completed:=upload_completed + zm.zm_upload_failed:=upload_failed + zm.zm_dupecheck:=dupecheck + zm.zm_flush:=flush + zm.zm_duplicate_filename:=duplicate_filename + zm.zm_fopen:=fileopen + zm.zm_fclose:=fileclose + zm.zm_fseek:=fileseek + zm.zm_fread:=fileread + zm.zm_fwrite:=filewrite + zm.zm_firstfile:=firstfile + zm.zm_nextfile:=nextfile + + zm.tx_data_subpacket:=New(TXSUBPACKETSIZE) + zm.rx_data_subpacket:=New(RXSUBPACKETSIZE) + zm.sendBuffer:=New(zm.max_block_size+512) + zm.sendBufferPos:=0 + zm.sendBufferSize:=zm.max_block_size+512 + + zm.crc16tbl:={crc16tbl} + zm.crc32tbl:={crc32tbl} +ENDPROC + +EXPORT PROC zmodem_cleanup(zm: PTR TO zmodem_t) + Dispose(zm.tx_data_subpacket) + Dispose(zm.rx_data_subpacket) + Dispose(zm.sendBuffer) +ENDPROC + +PROC doOpen(zm:PTR TO zmodem_t,fname,mode) + DEF p + p:=zm.zm_fopen + IF p<>NIL + RETURN p(fname,mode) + ENDIF + lprintf(zm,ZM_LOG_WARNING,'zm_fopen not set, defaulting to dos library Open') +ENDPROC Open(fname,mode) + +PROC doClose(zm:PTR TO zmodem_t,fhandle) + DEF p + p:=zm.zm_fclose + IF p<>NIL + RETURN p(fhandle) + ENDIF + lprintf(zm,ZM_LOG_WARNING,'zm_fclose not set, defaulting to dos library Close') +ENDPROC Close(fhandle) + +PROC doSeek(zm:PTR TO zmodem_t,fhandle,pos,origin) + DEF p + p:=zm.zm_fseek + IF p<>NIL + RETURN p(fhandle,pos,origin) + ENDIF + lprintf(zm,ZM_LOG_WARNING,'zm_fseek not set, defaulting to dos library Seek') +ENDPROC Seek(fhandle,pos,origin) + +PROC doRead(zm:PTR TO zmodem_t,fhandle,buffer,length) + DEF p + p:=zm.zm_fread + IF p<>NIL + RETURN p(fhandle,buffer,length) + ENDIF + ->lprintf(zm,ZM_LOG_WARNING,'zm_fread not set, defaulting to dos library FRead') +ENDPROC Fread(fhandle,buffer,1,length) + +PROC doWrite(zm:PTR TO zmodem_t,fhandle,buffer,length) + DEF p + p:=zm.zm_fwrite + IF p<>NIL + RETURN p(fhandle,buffer,length) + ENDIF + ->lprintf(zm,ZM_LOG_WARNING,'zm_fwrite not set, defaulting to dos library FWrite') +ENDPROC Fwrite(fhandle,buffer,1,length) + +crc16tbl: INT $0000, $1021, $2042, $3063, $4084, $50A5, $60C6, $70E7, + $8108, $9129, $A14A, $B16B, $C18C, $D1AD, $E1CE, $F1EF, + $1231, $0210, $3273, $2252, $52B5, $4294, $72F7, $62D6, + $9339, $8318, $B37B, $A35A, $D3BD, $C39C, $F3FF, $E3DE, + $2462, $3443, $0420, $1401, $64E6, $74C7, $44A4, $5485, + $A56A, $B54B, $8528, $9509, $E5EE, $F5CF, $C5AC, $D58D, + $3653, $2672, $1611, $0630, $76D7, $66F6, $5695, $46B4, + $B75B, $A77A, $9719, $8738, $F7DF, $E7FE, $D79D, $C7BC, + $48C4, $58E5, $6886, $78A7, $0840, $1861, $2802, $3823, + $C9CC, $D9ED, $E98E, $F9AF, $8948, $9969, $A90A, $B92B, + $5AF5, $4AD4, $7AB7, $6A96, $1A71, $0A50, $3A33, $2A12, + $DBFD, $CBDC, $FBBF, $EB9E, $9B79, $8B58, $BB3B, $AB1A, + $6CA6, $7C87, $4CE4, $5CC5, $2C22, $3C03, $0C60, $1C41, + $EDAE, $FD8F, $CDEC, $DDCD, $AD2A, $BD0B, $8D68, $9D49, + $7E97, $6EB6, $5ED5, $4EF4, $3E13, $2E32, $1E51, $0E70, + $FF9F, $EFBE, $DFDD, $CFFC, $BF1B, $AF3A, $9F59, $8F78, + $9188, $81A9, $B1CA, $A1EB, $D10C, $C12D, $F14E, $E16F, + $1080, $00A1, $30C2, $20E3, $5004, $4025, $7046, $6067, + $83B9, $9398, $A3FB, $B3DA, $C33D, $D31C, $E37F, $F35E, + $02B1, $1290, $22F3, $32D2, $4235, $5214, $6277, $7256, + $B5EA, $A5CB, $95A8, $8589, $F56E, $E54F, $D52C, $C50D, + $34E2, $24C3, $14A0, $0481, $7466, $6447, $5424, $4405, + $A7DB, $B7FA, $8799, $97B8, $E75F, $F77E, $C71D, $D73C, + $26D3, $36F2, $0691, $16B0, $6657, $7676, $4615, $5634, + $D94C, $C96D, $F90E, $E92F, $99C8, $89E9, $B98A, $A9AB, + $5844, $4865, $7806, $6827, $18C0, $08E1, $3882, $28A3, + $CB7D, $DB5C, $EB3F, $FB1E, $8BF9, $9BD8, $ABBB, $BB9A, + $4A75, $5A54, $6A37, $7A16, $0AF1, $1AD0, $2AB3, $3A92, + $FD2E, $ED0F, $DD6C, $CD4D, $BDAA, $AD8B, $9DE8, $8DC9, + $7C26, $6C07, $5C64, $4C45, $3CA2, $2C83, $1CE0, $0CC1, + $EF1F, $FF3E, $CF5D, $DF7C, $AF9B, $BFBA, $8FD9, $9FF8, + $6E17, $7E36, $4E55, $5E74, $2E93, $3EB2, $0ED1, $1EF0 + +crc32tbl: LONG $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