home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / VRXBETA2.ZIP / VIREXX.CMD < prev   
OS/2 REXX Batch file  |  1992-11-15  |  32KB  |  798 lines

  1. /* Virexx.cmd
  2.    
  3.     Rexx program for virus checking uploaded files for Maximus 2.01wb
  4.               Doug Cullen  1:157/603.52@fidonet 12 Oct. 92
  5.  
  6. I wrote ViREXX for two reasons.  One, to try out REXX as a programming language. 
  7. Two, I wanted an equivalent to ZIPLAB for MAX/2.  So how did it work out?  
  8. ViREXX currently provides services equal to the last version of ZIPLABGEN I had
  9. running.  BUT NO NIFTY screen for the user to watch. It appears that MAX/2 
  10. doesn't pass the port handle when spawning VIRCHECK. On the positive side, that
  11. means I don't have to bother with checking for carrier drops and users 
  12. attempting to break out of the door.  So running ViREXX shouldn't create any 
  13. security problems.        
  14.  
  15. FEATURES:
  16.                 1. Checks for valid archives by extracting all files
  17.                 2. Checks for nested archives down 2 levels.  Checks 
  18.                    for all types of nested archives (i.e .zip file 
  19.                    inside a .lzh file, etc...)
  20.                 3. Runs your virus scanner to check for virii.  I use
  21.                    McAffees Scan for OS/2 beta.  It works here, your 
  22.                    milage may differ 
  23.                 4. Checks dates of all files within archives. Can reject 
  24.                    files older than SYSOP selectable date.
  25.                 5. Logs all actions to Virexx.log.  Can add minimal log
  26.                    info to your Max.log (uses CBCS type log)
  27.                 6. Moves rejected files to a badfiles dir.  Enters error
  28.                    message in files.bbs for rejected files.
  29.                 7. Informs user of file stats for accepted files via 
  30.                    file_ok.bbs 
  31.                 8. Informs user of reason for rejections via file_bad.bbs
  32.                 9. <OPTIONAL> can strip and/or add comment to .zip files
  33.                10. <OPTIONAL> can add file descriptions found in 
  34.                    FILE_ID.DIZ or DESC.SDI to your files.bbs.  THIS IS A
  35.                    KLUDGE all the way.  Since MAX limit descriptions to 
  36.                    3 lines and most of these descriptions are longer, I 
  37.                    use a slightly messy approach.  I add the first line
  38.                    of the description to the fileentry and then add the
  39.                    remainder to the lines as text below that.  This is a
  40.                    pain when you try to hurl the file.  Also, Max doesn't
  41.                    recognize that a description has been added to files.bbs
  42.                    and prompts the user for a description.  So you get two
  43.                    descriptions.  Neither of these is a real big problem 
  44.                    for SYSOPS who sequester files from users until they 
  45.                    have inspected them.  If you allow users immediate access
  46.                    to new uploads it's probably best to disable this option.
  47.                
  48.                         
  49. PRECAUTIONS
  50.               
  51.                 1. Make sure all defined directories exist.  I can't predict 
  52.                    what will happen if they don't ( but I got to use 
  53.                    UNDELETE here) Slotted for fixing REAL-SOON-NOW
  54.                 2. There is not currently any support for GIF, FLI or the
  55.                    like.  If you want them treated as ok then you need to 
  56.                    make some changes.  The easiest if to add some more
  57.                    extensions to the TEXT status line in Subroutine UnArchive.
  58.                    Alternately you could add additonal when statements to the
  59.                    select statement in the same place.
  60.  
  61.  
  62.  
  63. FUTURE ENHANCEMENTS (maybe, no promises here)
  64.                  
  65.                 1. Abilty to convert archives ( i.e. .zip, .arc to .lzh)
  66.                    and properly maintain files.bbs
  67.                 2. file database so users can see more info on each file
  68.                    (filedate, date uploaded, size extracted, # of files
  69.                    in archive, name of uploader)
  70.  
  71.  
  72.  
  73. WARRANTY and LIMITATIONS
  74.  
  75.                 1. Ain't none.  I can assure you that ViREXX will take up
  76.                    space on the storage media of your choice.  I can't 
  77.                    guaranty that it won't cause mayhem on your system. 
  78.                    It does work here on 2.01 beta and on 2.0 GA 
  79.                 2. You've got the source, if you don't like the way it 
  80.                    works, change it! but do not distribute once modified.
  81.                 3. This is FreeWare, there is no charge and I assume no 
  82.                    responsibility for nay damage it may do.  Have Fun.
  83.                 
  84.  
  85.  
  86. ASSUMPTIONS (do it different and you'll probably have to re-code something)
  87.  
  88.                 1. All the archivers can be found in one directory
  89.                    defined as arcpath
  90.                 2. If your NOT using 4OS2 then be sure to change the 
  91.                    don't ask entry to '/N'
  92.                 3. .ZIP files will be extracted with PKZIP 1.02 for
  93.                    OS/2 or the family mode version
  94.                 4. .ARJ file will be extracted with Robert Jungs Unarj 
  95.                    2.10
  96.                 5. .LZH files will be extracted with LH2 2.14
  97.                 6. .ARC files will be extracted with ARC2 6.00p
  98.                 7. Virus scanner will be McAfees SCAN for OS/2 beta 97
  99.                 8. Using exetweak to mark all the programs as windowable
  100.                    to avoid the screen flashing 
  101.  
  102. */
  103. '@echo off'
  104.  
  105. /* -----  Set these variables for your System ------------------------- */
  106.  
  107. bbsname = 'The Point of Confusion'      /* Your BBS name                */
  108. maxpath = 'd:\vrexx\'                   /* Path to Maximus              */
  109. badfiledir = 'd:\max\badfile'           /* path to copy bad files to    */
  110. testfiledir  = 'd:\max\filetest'       /* dir for testing              */
  111. testfiledir2 = 'd:\max\filetes2 '      /* dir for nested archive test  */
  112. miscpath = 'D:\MAX\MISC'                /* Path to misc *.bbs files     */
  113.                                         /* NO FOLLOWING BACKSLASH       */
  114.                                         /* Must be UPPER case !!!!      */
  115. arcpath = 'c:\arctools'                 /* Path to archiver's           */
  116. logname = 'd:\max\virexx.log'           /* Virexx Log                   */
  117. dontask = '/Y'                          /* use /Y for 4OS2, /N for OS2  */
  118.                                         /* turns off "delete *.*? (Y/N)"*/
  119. mlog = 1                                /* set to 1 to add Virexx entry */
  120.                                         /*  to Maxlog                   */
  121. maxlog = '\max\max.log'                 /* path to max log file         */
  122. logfile = '\max\virexx.log'             /* path and name of Virexx log  */
  123. flagfile = '\max\scan.flg'              /* scanner flag file            */
  124. oldest = 8001                           /* date for oldest file YYMM    */
  125.                                         /* 8001 = jan 80 use 0000 to    */
  126.                                         /* disable                      */
  127. sdi='ON'                                /* enter FILE_ID.DIZ or         */
  128.                                         /* DESC.SDI into files.bbs if   */
  129.                                         /* found                        */
  130. descblanks = 45
  131.  
  132. scancmd='scan_os2 d:\max\filetest\*.* d:\max\filetes2\*.* /a /d' 
  133.                                         /* command line for your      */
  134.                                         /* virus scanner                */
  135. file_bad='d:\max\misc\file_bad.bbs'     /* path to bad file message     */
  136. file_ok='d:\max\misc\file_ok.bbs'       /* path to good file message    */
  137. zipcomment = 'ON'
  138. commentfile = 'd:\os2\comment.fil'      /* bbs add file for zip comment */
  139. dbase = 1
  140. database = 'd:\max\filedata.fil'        /* database of additional file info */
  141. userfile='d:\max\lastus01.bbs'          /* name of lastuser file        */
  142. /* -------------------------------------------------------------------- */
  143.  
  144. /* ------------- Main Program ------------------------- */
  145.  
  146. parse upper arg path file ext dummy  /* grab file name, convert to uppercase */
  147.    call initialize                   /* initialize program                   */
  148.    call unarchive                    /* unarchive file to test directory     */
  149.                                      /* test for valid archive               */
  150. if status = GOOD | status = EXE then do
  151.      if oldest <> 0000 then call checkdate      /* check for old files       */
  152.                                                 /* unless turned off         */
  153.      if sdi = 'ON' then call checkdesc  /* check for file descriptions       */
  154.                                         /* packed inside archive             */
  155.      call scanner                   /* scan for virii if the file unpacks OK */
  156.      end /* do */                    
  157.  
  158. call filestats
  159. call sendmsg                              /* send appropriate msg to user   */
  160. if dbase then call databaseout                 /* add fileinfo to data base      */
  161. if zipcomment = ON & ext = .ZIP then do
  162.      if status = GOOD then do                
  163.        'pkzip -z ' fullname '< 'commentfile
  164.        end /* do */
  165.      end /* do */
  166. call cleanupdir                  /* clean up test directory               */
  167. cleanup:
  168. say 'cleaning up ViREXX'
  169. call RxFuncDrop 'SysFileTree'
  170. exit
  171.  
  172. /* ------------ end -  main program ------------------ */
  173.  
  174. /*     Possible Status Values
  175.  
  176.         GOOD     = No problems
  177.         BAD      = Failed to Unarchive 
  178.         INFECTED = Failed Virus Scan 
  179.         UNKNOWN  = File extension was not of any type defined
  180.         EXE      = File was .exe or .com (I treat these with a great 
  181.                     deal of suspicion! )
  182.         TEXT     = .ext was .txt, .doc, .prn, .bat, or .cmd
  183.         NOEXT    = file had no extension i.e. 'filename.'
  184.         OLD      = archive contained files older than oldest date               
  185. */
  186.  
  187. /* ----- Subroutine Initialize ----------------------- */
  188. initialize:
  189.  if ext = '' then call USAGE
  190.  filename=file||ext                              /* file name                 */
  191.  fullname=path||file||ext                        /* full pathname to file     */
  192.  del testfiledir dontask                      /* cleanup test dir          */
  193.  del testfiledir2 dontask                     /* cleanup 2nd test dir      */
  194.  parse value DATE('N') with dd mmm yyyy      /* dd   = day
  195.                                                 mmm  = month
  196.                                                 yyyy = year          */
  197.  if dd = 1 then dd =01
  198.  if dd = 2 then dd =02
  199.  if dd = 3 then dd =03
  200.  if dd = 4 then dd =04
  201.  if dd = 5 then dd =05
  202.  if dd = 6 then dd =06
  203.  if dd = 7 then dd =07
  204.  if dd = 8 then dd =08
  205.  if dd = 9 then dd =09
  206.  archsize = 0
  207.  logdate = ' 'dd' 'mmm' 'TIME()' VIRX'
  208.  uldate = dd'-'mmm'-'yyyy
  209.  logentry = '+'logdate' checking 'filename    /* build up log entry          */
  210.  call LINEOUT logfile,logentry                /* and write log entry         */  
  211.  nested = NO                                  /* clear nested                */
  212.  
  213.    if RxFuncQuery('SysFileTree') then
  214.         Call RxFuncAdd 'SysFileTree','RexxUtil','SysFileTree' 
  215.         CAll RxFuncAdd 'SysMkDir','RexxUtil','SysMkDir'
  216.                                               /* make sure Rexxutils loaded */
  217.  /* get user name from lastuser file */
  218.  tempname=STRIP(CHARIN(userfile,1,36),,'00'x)
  219.  username=tempname
  220.  if \(SUBWORD(tempname,3,1)='') then
  221.    username=SUBWORD(tempname,1,1)' 'SUBWORD(tempname,2,1)SUBWORD(tempname,3,1)
  222. /* check that dirs exist - if not make them */
  223. call SysFileTree testfiledir,'dir','DO'
  224.  if dir.0 = 0 then call SysMkDir testfiledir
  225. call SysFileTree testfiledir2,'dir','DO'
  226.  if dir.0 = 0 then call SysMkDir testfiledir2
  227. call SysFileTree badfiledir,'dir','DO'
  228.  if if dir.0 = 0 then call SysMkDir badfiledir
  229.  
  230. return
  231.  
  232. /* ----- End - Initialize ---------------------------- */
  233.  
  234. /* ----- Subroutine Unarchive ------------------------ */
  235.  
  236. unarchive:
  237.  ffname = fullname
  238.  fname = filename
  239.  testdir = testfiledir
  240.  Select
  241.    when ext = .ZIP then  call unzip
  242.    when ext = .ARJ then  call unarj
  243.    when ext = .LZH then  call unlzh 
  244.    when ext = .ARC then  call unarc
  245.    when ext =  miscpath then do                 /* file had no extension  */
  246.        move fullname badfiledir                 /* move to badfile dir    */
  247.        status = NOEXT
  248.        end   /* do */
  249.    when ext = .TXT | ext = .DOC | ext = .PRN then status = TEXT
  250.    when ext = .EXE | ext = .COM then do 
  251.      status = 'EXE'
  252.      copy fullname testfiledir
  253.      move fullname badfiledir
  254.      end /* do */
  255.    otherwise 
  256.      status = 'UNKNOWN'
  257.      move fullname badfiledir
  258.  end  /* select */
  259. if status = BAD then do
  260.         move fullname badfiledir
  261.         return
  262.         end /* do */
  263.  
  264. if status = GOOD then call checknested
  265.  
  266. return
  267.  
  268. /* ----------- End - unarchive -----------------------------*/
  269.  
  270. /* ------- look for description files ---------------------- */
  271. /* ------- (FILE_ID.DIZ or DESC.SDI)inside archive --------- */
  272.  
  273. checkdesc:
  274. fileinfo = 'd:\max\filetest\file_id.diz'
  275. if stream(fileinfo,'c','query exist') <> '' then do 
  276.    i = 0
  277.    do until lines(fileinfo)=0
  278.      i = i + 1
  279.      mytext.i = LINEIN(fileinfo)
  280.      mytext.1 = STRIP(mytext.i)
  281.      bbsfile = path||files.bbs
  282.      if i = 1 then call LINEOUT bbsfile,filename' 'mytext.i
  283.      else call LINEOUT bbsfile,COPIES(' ',descblanks)||mytext.i
  284.      desc = DONE
  285.      end /* do */
  286.   fstat=stream(fileinfo,'c','close')
  287.   end /* do */
  288.   if desc <> DONE then do
  289.   fileinfo = 'd:\max\filetest\desc.sdi'
  290.   if stream(fileinfo,'c','query exist') <> ''then do 
  291.     i = 0
  292.     do until lines(fileinfo)=0
  293.        i = i + 1
  294.        mytext.i = LINEIN(fileinfo)
  295.        mytext.i = STRIP(mytext.i)
  296.        bbsfile = path||files.bbs
  297.        if i = 1 then call LINEOUT bbsfile,filename' 'mytext.i
  298.        else call LINEOUT bbsfile,COPIES(' ',descblanks)||mytext.i
  299.     end /* do */
  300.     fstat=stream(fileinfo,'c','close')
  301.    end /* do */
  302. end 
  303. return
  304. /* ------ end of checkdesc ------------- */
  305.  
  306. /* - Run McAffees Scan on testfiledir - */
  307.  
  308. scanner:
  309.   scancmd
  310.   if rc>1 then status = ERROR
  311.   if rc=1 then status = INFECTED
  312.   if rc=0 & status= GOOD then status = GOOD
  313.   if rc=0 & status= EXE then status = EXE
  314. return
  315. /* ----------end --  scanner ------------- */
  316.  
  317. /* -  clean up testfile dir when we're done - */
  318.  
  319. cleanupdir:
  320.    del testfiledir dontask                     /* cleanup test dir      */
  321.    del testfiledir2 dontask
  322. return
  323. /* ------- end -- cleanupdir ---------------- */  
  324.  
  325. /*  ----------- Subroutine SendMsg --------------------------- */
  326. /*  enter appropriate messages to log(s) and bbs user          */
  327.  
  328. sendmsg:
  329.    fileentry =''
  330.    select 
  331.     when status = BAD then do
  332.         logentry = '!'logdate filename' failed extract - moved to badfiles'
  333.         fileentry =  filename" failed to extract from archive - uploaded by: "username
  334.         end /* do */
  335.     when status = EXE then do
  336.         logentry = '!'logdate filename' suspicious  - moved to badfiles'
  337.         fileentry = filename" exec, moved to prevent trojan, virii ...-uploaded by: "username
  338.         end /* do */
  339.     when status = TEXT then logentry = '+'logdate filename' ok - credit given (TEXT file)'
  340.     when status = UNKNOWN then do 
  341.         logentry = '!'logdate filename' UNKNOWN type - moved to badfiles'
  342.         fileentry = filename" of unknown type, moved - uploaded by: "username
  343.         end /* do */
  344.     when status = INFECTED then do
  345.         logentry = '!'logdate filename' INFECTED!!! - moved to badfiles'
  346.         fileentry = filename" INFECTED - triggered scanner -uploaded by: "username
  347.         end /* do */
  348.     when status = GOOD then logentry = '+'logdate filename' OK credit given' 
  349.     when status = NOEXT then do
  350.         logentry = '!'logdate filename' had no .ext - moved to badfiles'
  351.         fileentry = filename" had no extension, moved - uploaded by:"username
  352.         end /* do */
  353.     when status = OLD then do
  354.         logentry = '!'logdate filename' was too old - moved to badfiles'
  355.         fileentry = filename" was older than allowed - uploaded by: "username
  356.         end /* do */
  357.   otherwise do
  358.         logentry = '!'logdate' ERROR running ViREXX'
  359.         fileentry = filename "ERROR running ViREXX"
  360.         end /* do */
  361. end /* select */
  362.  
  363. call LINEOUT logfile,logentry                /* write entry to Virexx log   */
  364. if status = GOOD then do
  365.      call LINEOUT logfile,'                       Filesize: 'fsize' bytes, dated: 'fildate
  366.      call LINEOUT logfile,'                       'numfiles' files, Newest: 'newdate' - Oldest: 'olddate
  367.      call LINEOUT logfile,'                       Uploaded by: 'username
  368.      end /* do */
  369. if Mlog then call LINEOUT maxlog,logentry    /* write to Max log if enabled */
  370.  
  371. if status \= GOOD then do 
  372.    if status \= TEXT then do 
  373.      badfilebbs=badfiledir'\files.bbs'
  374.      call LINEOUT badfilebbs,fileentry
  375.      fstat= stream(badfilebbs,'c','close')
  376.    end /* do */
  377. end /* do */
  378.  
  379. call tokens                         /* load mecca tokens for .bbs output  */
  380. call bbsmsg                         /* write file_ok.bbs or file_bad.bbs  */ 
  381. return
  382.  
  383.  
  384. /* ----- check date - move to badfilesarchive if it contains ----- */
  385. /* ----- files older than oldest ----------------------------------*/
  386.  
  387. checkdate:
  388. datelist=''
  389. SrchFile = testfiledir'\*.*'
  390. call SysFileTree SrchFile,'files','FO'
  391. do i = 1 to files.0
  392.    filedate=stream(files.i,'c','query datetime')
  393.    parse value filedate with cm'-'cd'-'cy hours
  394.    testdate  = cy||cm
  395.    if i = 1 then do
  396.      oldestfile = testdate
  397.      newestfile = testdate
  398.      end /* do */
  399.    if i \= 1 then do
  400.      if testdate>newestfile then newestfile=testdate
  401.      if testdate<oldestfile then oldestfile=testdate
  402.      end /* do */
  403.    if testdate<oldest then do 
  404.       status = OLD
  405.       move fullname badfiledir
  406.    end /* do */
  407. end  /* do */
  408. SrchFile = testfiledir2'\*.*'
  409. call SysFileTree SrchFile,'files','FO'
  410. do i = 1 to files.0
  411.    filedate=stream(files.i,'c','query datetime')
  412.    parse value filedate with cm '-' cd '-' cy hours
  413.    testdate  = cy||cm
  414.    if testdate>newestfile then newestfile=testdate
  415.    if testdate<oldestfile then oldestfile=testdate
  416.    if testdate<oldest then do 
  417.       status = OLD
  418.       move fullname badfiledir
  419.    end /* do */
  420. end  /* do */
  421. return   /* checkdate */
  422.  
  423. /* ----- end -- checkdate ---- */
  424.  
  425. /* ------ Unzip - run pkunzip on filename ------- */
  426. unzip:
  427.      /* written for PKUNZIP  (I use the family mode version 1.02)           */
  428.  
  429.      pkunzip ffname testdir           /* unzip file to testdir */
  430.      if RC = 0 then do                             /* unzipped OK           */
  431.        status = 'GOOD'
  432.    end
  433.    else do                                       /* failed to unzip       */
  434.        status = 'BAD'
  435.      end  /* do */
  436.    return  
  437.  
  438. /* end unzip */
  439.  
  440. /* ---------  unarj -- run unarj on filename --------------- */
  441. unarj:
  442.      /* written for Robert Jung's Unarj 2.10                                */
  443.      /* this section will copy the file to the test file dir and also copy  */
  444.      /* unarj to the same directory, run unarj and cleanup afterwards. If   */
  445.      /* your test dir is on a different drive be sure to fix this section   */
  446.  
  447.      copy ffname testdir                          /* copy file to test dir  */
  448.      copy arcpath'\unarj.exe' testdir
  449.      cd testdir
  450.      unarj e fname                                     /* unarj file        */
  451.      if RC = 0 then do                                 /* unarjed OK       */
  452.        status = 'GOOD'
  453.        del fname
  454.        del unarj.exe
  455.  
  456.      end
  457.      else do          
  458.        status = 'BAD'                              /* failed to unarj   */
  459.      end  /* do */
  460.    cd maxpath
  461.    return
  462.  
  463. /* end unarj */
  464.  
  465. /* ----------- unlzh -- unlzh filename ----------- */
  466.          
  467. unlzh:
  468.      /* written for LH2  2.14    */
  469.      lh2 x ffname testdir                          /* unlzh file to testdir */
  470.      if RC = 0 then do                             /* unlzh'd OK           */
  471.        status = 'GOOD'
  472.      end
  473.      else do                                       /* failed to unlzh       */
  474.        status = 'BAD'
  475.      end  /* do */
  476.    return
  477.  
  478. /* end unlzh */
  479.  
  480. /* ----- unarc -- unarc filename using ARC2 ---- */
  481.  
  482. unarc:
  483.      /* written for ARC2 6.00p                                              */
  484.      /* this section will copy the file to the test file dir and also copy  */
  485.      /* arc2 to the same directory, run arc2 and cleanup afterwards. If     */
  486.      /* your test dir is on a different drive be sure to fix this section   */
  487.  
  488.      copy ffname testdir                          /* copy file to test dir  */
  489.      copy arcpath'\arc2.exe' testdir
  490.      cd testdir
  491.      arc2 e fname                                      /* unarc file        */
  492.      if RC = 0 then do                                 /* unarced OK        */
  493.        status = 'GOOD'
  494.        del fname
  495.        del 'arc2.exe'
  496.      end
  497.      else do                                          /* failed to unarc   */
  498.        status = 'BAD'
  499.      end  /* do */
  500.     cd maxpath
  501.    return
  502.  
  503. /* end unarc  */
  504.  
  505. /* ---- checknested -- look for nested archives ------ */ 
  506.  
  507. checknested:
  508.  
  509. testdir = testfiledir2              /* search 1st level for archives        */
  510. call searchnest
  511.   if nested = YES then do         /* check for 2nd level of nested archives */
  512.     testdir = testfiledir
  513.     testfiledir = testfiledir2
  514.     call searchnest
  515.     testfiledir = testdir
  516.     end /* do */
  517. return /* checknested */
  518.  
  519.   /*     searchnest -- does the actual searching for files with   */
  520.   /*     archive type extensions                                  */
  521.  
  522. searchnest:
  523.    SrchFile = testfiledir'\*.zip'             /* look for .zip files       */
  524.      call SysFileTree SrchFile,'files','FO'
  525.        if file.0 >> 0 then do i = 1 to files.0
  526.          ffname = files.i
  527.          fname = FILESPEC("name",ffname)
  528.          call unzip
  529.          del ffname
  530.          nested = YES
  531.        end /* do */
  532.  
  533.    SrchFile = testfiledir'\*.arc'           /* look for .arc files         */
  534.      call SysFileTree SrchFile,'files','FO'
  535.        if file.0 >> 0 then do i = 1 to files.0
  536.          ffname = files.i
  537.          fname = FILESPEC("name",ffname)
  538.          call unarc
  539.          del ffname
  540.         nested = YES
  541.        end /* do */
  542.  
  543.    SrchFile = testfiledir'\*.arj'           /* look for .arj files          */
  544.      call SysFileTree SrchFile,'files','FO'
  545.        if file.0 >> 0 then do i = 1 to files.0
  546.          ffname = files.i
  547.          fname = FILESPEC("name",ffname)
  548.          call unarj
  549.          del ffname
  550.         nested = YES
  551.        end /* do */
  552.  
  553.    SrchFile = testfiledir'\*.lzh'          /* look for .lzh files           */
  554.      call SysFileTree SrchFile,'files','FO'
  555.        if file.0 >> 0 then do i = 1 to files.0
  556.          ffname = files.i
  557.          fname = FILESPEC("name",ffname)
  558.          call unlzh
  559.         nested = YES
  560.        end /* do */
  561.  
  562. return
  563.  
  564. /* --- end checknested ---------- */
  565. tokens:
  566. cls=' '
  567. firstname=''
  568. blue='ü'
  569. lightblue='ë'
  570. cyan='â'
  571. lightcyan='ï'
  572. green='é'
  573. lightgreen='è'
  574. brown='å'
  575. yellow='Ä'
  576. grey='ç'
  577. gray='ç'
  578. white='Å'
  579. red='ä'
  580. lightred='î'
  581. magenta=''
  582. lightmagenta='ì'
  583. blink=''
  584. steady='ì'
  585. enter=''
  586. return
  587.  
  588.  
  589.  
  590. bbsmsg:     
  591.  
  592. do i = 7 to 25    /* clear msg */
  593.   msg.i = ''
  594. end /* do */
  595.  
  596.  msg.1=cls   
  597.  msg.2="      "blue"╔═════════════════════════════════════════════════╗"
  598.  msg.3="      "blue"║             "lightcyan"ViREXX "yellow"Scan Report                  "blue"║" 
  599.  msg.4="      "blue"╟─────────────────────────────────────────────────╢"
  600.  msg.5="      "blue"║  "lightcyan"ViREXX "yellow"Archive verifier/Virus Checker "white"[beta]   "blue"║"
  601.  msg.6="      "blue"╚══════════════ "lightcyan"(c) Doug Cullen, 1992 "blue"════════════╝"
  602.  
  603. select
  604.    when status = GOOD | status = TEXT then do
  605.    file_out = file_ok
  606.  
  607.    msg.8=green"  ╒═════════════════════════╤══════════════════════════════╕"
  608.    msg.9=green"  │"lightcyan" FileName: "yellow||CENTER(filename,14)||green"│ "lightcyan"Dated :"yellow||fildate"              "green"│"
  609.   msg.10=green"  ├─────────────────────────┼──────────────────────────────┤"
  610.   msg.11=green"  │ "lightcyan"FileSize:"yellow||CENTER(filesize,8)"bytes  "green"│ "lightcyan"Extracted Size: "yellow||CENTER(archsize,8)"bytes"green"│"
  611.   msg.12=green"  ├─────────────────────────┴──────────────────────────────┤"
  612.   msg.13=green"  │ "lightcyan"Archive contains: "yellow||CENTER(numfiles,3)" files                            "green"│"
  613.   msg.14=green"  ├─────────────────────────┬──────────────────────────────┤"
  614.   msg.15=green"  │ "lightcyan"Oldest file :"yellow||CENTER(olddate,8)"   "green"│ "lightcyan"Newest file :"yellow||CENTER(newdate,8)"        "green"│"
  615.   msg.16=green"  ╘═════════════════════════╧══════════════════════════════╛"
  616.   msg.18=lightcyan "Thanks for the upload, 'firstname' Everything checks out OK"
  617.   msg.20=lightcyan "Full credit given for your upload"grey
  618.  
  619.    end /* GOOD */
  620.  
  621.   when status = BAD then do
  622.    file_out = file_bad
  623.    msg.7=""
  624.    msg.8="     "lightcyan"ViREXX "yellow"has scanned your file:"white filename       
  625.   msg.10="     "yellow"and was unable to extract any files from the archive"
  626.   msg.12="     "yellow"You may want to check your file for errors. (Please "lightred"DONT "yellow"use"
  627.   msg.14="     "yellow"PKZIP 1.93a)   You won't receive any credit for the file at"
  628.   msg.16="     "yellow"this time, but the file has been moved for SYSOP inspection"grey
  629.   msg.18=enter
  630.    end /* BAD */
  631.  
  632.   when status = INFECTED then do
  633.    file_out = file_bad
  634.    msg.7=""
  635.    msg.8="     "blink red"WARNING "white"WARNING "red"WARNING "white"WARNING - "steady yellow"Your file :"white filename
  636.   msg.10="     "yellow"has caused a "red"VIRUS "yellow"warning from our system.  You won't"
  637.   msg.12="     "yellow"receive any credit for you upload at this time, but the"
  638.   msg.14="     "yellow"file has been moved for SYSOP inspection."grey
  639.   msg.16=""
  640.   msg.18=enter
  641.    end /* infected */
  642.  
  643.   when status = UNKNOWN then do
  644.    file_out = file_bad
  645.    msg.7=""
  646.    msg.8="     "lightcyan"ViREXX "yellow"was unsure what to do with your file:"white filename
  647.   msg.10="     "yellow"since it was not one of the kind we accept.  Please"
  648.   msg.12="     "yellow"limit your uploads to .ZIP, .ARC, .ARJ or .LZH files."
  649.   msg.14="     "yellow"You won't recieve any credit for your upload at this" 
  650.   msg.16="     "yellow"time, but the file has been moved for SYSOP inspection"grey
  651.   msg.18=enter
  652.   end /* UNKNOWN */
  653.  
  654.   when status = EXE then do
  655.    file_out = file_bad
  656.    msg.7=""
  657.    msg.8="     "lightcyan"ViREXX "yellow"has moved your file:"white filename yellow"for "white"SYSOP "yellow"inspection."
  658.   msg.10="     "yellow"Since "lightgreen"virii "yellow"are most often transmitted by "lightred".exe "yellow"and "lightred".com "
  659.   msg.12="     "yellow"files, they are treated as possible infections. Please limit "
  660.   msg.14="     "yellow"future uploads to .ZIP .ARC .ARJ or .LZH files and Thanks"
  661.   msg.16="     "yellow"for supporting"lightmagenta bbsname grey
  662.   msg.18=enter
  663.    end /* EXE */
  664.  
  665.   when status = NOEXT then do
  666.    file_out = file_bad
  667.    msg.7=""
  668.    msg.8="     "lightcyan"ViREXX "yellow"was unsure what to do with your file: "file
  669.   msg.10="     "yellow"since it had no file extension.  Please limit your"
  670.   msg.12="     "yellow"uploads to "lightgreen".ZIP, .ARC, .ARJ "yellow"or "lightgreen".LZH "yellow"files.  You won't"
  671.   msg.14="     "yellow"recieve any credit for your upload at this time, but" 
  672.   msg.16="     "yellow"the file has been moved for "white"SYSOP "yellow"inspection"grey
  673.   msg.18=enter
  674.    end /* NOEXT */
  675.  
  676.   when status = OLD then do
  677.    file_out = file_bad
  678.    msg.7=""
  679.    msg.8="     "lightcyan"ViREXX "yellow"has found that some of the files in "filename
  680.   msg.10="     "yellow"are older than we normally accept.  Sorry, but you"
  681.   msg.12="     "yellow"won't receive credit for your upload.  The file has"
  682.   msg.14="     "yellow"been moved for SYSOP inspection"
  683.   msg.18="     "grey
  684.   msg.20=enter
  685.    end /* OLD */
  686.  
  687. otherwise
  688.   nop
  689. end /* select */
  690.  
  691.  
  692. del file_out
  693.  
  694. do i = 1 to 20
  695.    call LINEOUT file_out,msg.i
  696.    end /* do */
  697.  
  698. fstat=stream(file_out,'C','close')
  699.  
  700. return
  701.  
  702. filestats:
  703. numfiles=0
  704. oldmonth = ''
  705. oldyear  = ''
  706. newyear = ''
  707. newmonth= ''
  708. SrchFile = fullname
  709. filesize = stream(SrchFile,'c','query size')
  710. fdate=stream(SrchFile,'c','query datetime')
  711. parse value fdate with fm'-'fd'-'fy  hours
  712. select 
  713.   when fm = '01' then fildate = fd'-Jan-'fy
  714.   when fm = '02' then fildate = fd'-Feb-'fy
  715.   when fm = '03' then fildate = fd'-Mar-'fy
  716.   when fm = '04' then fildate = fd'-Apr-'fy
  717.   when fm = '05' then fildate = fd'-May-'fy
  718.   when fm = '06' then fildate = fd'-Jun-'fy
  719.   when fm = '07' then fildate = fd'-Jul-'fy
  720.   when fm = '08' then fildate = fd'-Aug-'fy
  721.   when fm = '09' then fildate = fd'-Sep-'fy
  722.   when fm = '10' then fildate = fd'-Oct-'fy
  723.   when fm = '11' then fildate = fd'-Nov-'fy
  724.   otherwise fildate = fd'-Dec-'fy
  725.   end /* select*/
  726. SrchFile = testfiledir'\*.*'
  727. call SysFileTree SrchFile,'files','FO'
  728. do i = 1 to files.0
  729.    fsize=stream(files.i,'c','query size')
  730.    archsize=archsize+fsize
  731.    numfiles=numfiles+1
  732. end /* do */
  733. SrchFile = testfiledir2'\*.*'
  734. call SysFileTree SrchFile,'files','FO'
  735. do i = 1 to files.0
  736.    fsize=stream(files.i,'c','query size')
  737.    archsize=archsize+fsize
  738.    numfiles=numfiles+1
  739. end /* do */
  740. oldmonth =SUBSTR(oldestfile,3,2)
  741. oldyear =SUBSTR(oldestfile,1,2)
  742. newyear =SUBSTR(newestfile,1,2)
  743. newmonth=SUBSTR(newestfile,3,2)
  744. select 
  745.  when oldmonth = 01 then oldmonth = 'Jan'
  746.  when oldmonth = 02 then oldmonth = 'Feb'
  747.  when oldmonth = 03 then oldmonth = 'Mar'
  748.  when oldmonth = 04 then oldmonth = 'Apr'
  749.  when oldmonth = 05 then oldmonth = 'May'
  750.  when oldmonth = 06 then oldmonth = 'Jun'
  751.  when oldmonth = 07 then oldmonth = 'Jul'
  752.  when oldmonth = 08 then oldmonth = 'Aug'
  753.  when oldmonth = 09 then oldmonth = 'Sep'
  754.  when oldmonth = 010 then oldmonth = 'Oct'
  755.  when oldmonth = 011 then oldmonth = 'Nov'
  756. otherwise oldmonth = 'Dec'
  757. end /* select */
  758. select 
  759.  when newmonth = 01 then newmonth = 'Jan'
  760.  when newmonth = 02 then newmonth = 'Feb'
  761.  when newmonth = 03 then newmonth = 'Mar'
  762.  when newmonth = 04 then newmonth = 'Apr'
  763.  when newmonth = 05 then newmonth = 'May'
  764.  when newmonth = 06 then newmonth = 'Jun'
  765.  when newmonth = 07 then newmonth = 'Jul'
  766.  when newmonth = 08 then newmonth = 'Aug'
  767.  when newmonth = 09 then newmonth = 'Sep'
  768.  when newmonth = 010 then newmonth = 'Oct'
  769.  when newmonth = 011 then newmonth = 'Nov'
  770. otherwise newmonth = 'Dec'
  771. end /* select */
  772. olddate=oldmonth'-'oldyear
  773. newdate=newmonth'-'newyear
  774. return
  775.  
  776. databaseout:
  777. databaseentry=filename','fildate','uldate','filesize','archsize','numfiles','olddate','newdate','username
  778. call LINEOUT database,databaseentry
  779. return
  780.  
  781. USAGE:
  782. say ' '
  783. say ' ViREXX.CMD - Maximus File Integrety Tester written in REXX '
  784. say ' '
  785. say ' USAGE: Virexx d:\path\ filename .ext d:\max\misc '
  786. say ' '
  787. say ' d:\path\   = path to file to be checked INCLUDING trailing \'
  788. say ' '
  789. say ' filename   = the name of the file with no path or extension'
  790. say ' '
  791. say ' .ext       = the file extension including the . '
  792. say ' '
  793. say 'd:\max\misc =  path to MAXIMUS misc dir withOUT trailing \'
  794. say ' '
  795. say ' This is the form in which max passes the parameters '
  796. signal CLEANUP
  797. return
  798.