home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / util / misc / MergeRec.lha / MergeRec / MergeRec.e < prev   
Text File  |  1995-12-06  |  7KB  |  242 lines

  1. /* 
  2.  
  3.    MergeRec v1.1 - 5 Dec 95
  4.  
  5.    Keeps your local copy of the Aminet INDEX file up to date by incorporating
  6.    changes from RECENT.
  7.  
  8.    Usage: MergeRec INDEXFILE/A,RECENTFILE/A,OUTPUT
  9.    
  10.    INDEXFILE:  the local copy of an Aminet info/index/INDEX file.
  11.                WARNING: The regular INDEX file (pub/aminet/INDEX) will
  12.                NOT work! Use the file pub/aminet/info/index/INDEX because
  13.                it contains a 'weeks old' column.
  14.  
  15.    RECENTFILE: an Aminet RECENT file, either downloaded from an Aminet Site
  16.                or received by e-mail from wuarchive listserver.
  17.    
  18.    OUTPUT:     Filename of the new index file. If no filename is given,
  19.                standard output is used.
  20.  
  21.    Original program by Alex Tucker (alex@warp.demon.co.uk)
  22.    (Aminet: text/misc/MergeRecent.lha) 
  23.  
  24.    Rewritten in AmigaE and modified by Adriano De Minicis (mc4948@mclink.it)
  25.    
  26.    Compiled with AmigaE v3.2e
  27.  
  28. */
  29.  
  30. OPT OSVERSION=37
  31.  
  32. MODULE 'dos','dos/dos','dos/datetime','utility'
  33.  
  34. CONST MAXLEN=200
  35.  
  36. ENUM OK, ER_MEM, ER_BADARGS, ER_UTIL, ER_OPEN,     -> Error codes
  37.      ER_SHORT, ER_DATE, ER_BREAK        -> Error codes
  38.  
  39. RAISE ER_BREAK IF CtrlC()=TRUE, -> Set common exceptions
  40.       ER_MEM   IF String()=NIL
  41.  
  42. OBJECT date
  43.   days: LONG
  44.   str[40]: ARRAY OF CHAR
  45. ENDOBJECT
  46.  
  47. DEF ifh, rfh, ofh,                 -> filehandles
  48.     line[MAXLEN]:STRING, t[MAXLEN]:STRING,    -> line buffers
  49.     recdate:date, indexdate:date,        -> file dates
  50.     wd, not_eof, id=0, reclist=NIL        -> misc
  51.  
  52. /* Main */
  53.  
  54. PROC main() HANDLE
  55.   DEF args:PTR TO LONG, rdargs, templ, output
  56.   templ:='INDEXFILE/A,RECENTFILE/A,OUTPUT'
  57.   args:=[0,0,0]
  58.   
  59.   IF (rdargs:=ReadArgs(templ,args,NIL))=NIL THEN Raise(ER_BADARGS)
  60.   IF (utilitybase:=OpenLibrary('utility.library',37))=NIL THEN Raise(ER_UTIL)
  61.   IF (ifh:=Open(args[0],OLDFILE))=NIL THEN Throw(ER_OPEN,0)
  62.   IF (rfh:=Open(args[1],OLDFILE))=NIL THEN Throw(ER_OPEN,1)
  63.   ofh:=IF args[2]=NIL THEN stdout ELSE Open(args[2],NEWFILE)
  64.   IF ofh=NIL THEN Throw(ER_OPEN,2)
  65.   output:=(ofh<>stdout)
  66.  
  67.   /* Read RECENT, and build the list */
  68.   IF output THEN WriteF('Reading and sorting recent file list...\n')
  69.   read_recent()
  70.  
  71.   /* Get first line of INDEX */
  72.   not_eof:=Fgets(ifh,line,MAXLEN)
  73.   getdate(line,indexdate)
  74.   IF (recdate.days-indexdate.days)>7 THEN WriteF('\nWARNING: Index file is more than a week older than recent file\n\n')
  75.   wd:=(recdate.days-indexdate.days)/7    -> difference in weeks between RECENT and INDEX
  76.  
  77.   /* Write new INDEX header */
  78.   StringF(t,'| Updated Aminet Index on \s\n',recdate.str)
  79.   Fputs(ofh,t)
  80.  
  81.   /* If original INDEX file then save its creation date */
  82.   IF StrCmp(line,'| Updated Aminet Index',STRLEN)=FALSE
  83.     StringF(t,'| Original Index date: \s\n',indexdate.str)
  84.     Fputs(ofh,t)
  85.   ENDIF
  86.  
  87.   /* Skip header lines */
  88.   not_eof:=Fgets(ifh,line,MAXLEN)
  89.   WHILE not_eof AND (line[0]="|")
  90.     Fputs(ofh,line)
  91.     not_eof:=Fgets(ifh,line,MAXLEN)
  92.   ENDWHILE
  93.  
  94.   /* Merging lists */
  95.   IF output THEN WriteF('Merging lists...\n')
  96.   merge()
  97.   IF output AND (id>0) THEN WriteF('\d identical filename\s updated.\n',id, IF id=1 THEN '' ELSE 's')
  98.   Raise(OK)
  99.  
  100. EXCEPT
  101.   /* Program cleanup and error handling */
  102.   IF ifh THEN Close(ifh)
  103.   IF rfh THEN Close(rfh)
  104.   IF ofh<>stdout THEN Close(ofh)
  105.   IF utilitybase THEN CloseLibrary(utilitybase)
  106.   IF rdargs THEN FreeArgs(rdargs)
  107.   IF reclist THEN DisposeLink(reclist)
  108.   SELECT exception
  109.     CASE ER_MEM;    WriteF('Not enough memory\n')
  110.     CASE ER_BADARGS;    PrintFault(IoErr(), NIL)
  111.     CASE ER_UTIL;    WriteF('Can''t open utility.library\n')
  112.     CASE ER_OPEN;    WriteF('Can''t open "\s"\n',args[exceptioninfo])
  113.     CASE ER_DATE;    WriteF('Unable to read valid date\n')
  114.     CASE ER_SHORT;    WriteF('Premature end of file in \s\n',args[1])
  115.     CASE ER_BREAK;    WriteF('** User Break\n')
  116.   ENDSELECT  
  117. ENDPROC
  118.  
  119.  
  120. /* Read the RECENT files and sort it */    
  121.  
  122. PROC read_recent()
  123.   DEF s, curr, prev, found, dircmp, filecmp, len
  124.   not_eof:=Fgets(rfh,line,MAXLEN)
  125.  
  126.   /* Search header start */
  127.   WHILE not_eof AND (StrCmp(line,'| Recent uploads to',STRLEN)=FALSE)
  128.     not_eof:=Fgets(rfh,line,MAXLEN)
  129.   ENDWHILE
  130.  
  131.   getdate(line,recdate)
  132.   WHILE not_eof AND (line[0]="|")
  133.     not_eof:=Fgets(rfh,line,MAXLEN)         -> Skip header
  134.   ENDWHILE
  135.   IF not_eof=FALSE THEN Raise(ER_SHORT)     -> File too short!
  136.   
  137.   WHILE not_eof AND (line[0]<>"|")        -> Do until EOF or another header
  138.     /* Convert CR-LF (if present) to LF */
  139.     len:=StrLen(line)
  140.     IF (len>1) AND (line[len-2]="\b")
  141.       line[len-2]:="\n"
  142.       line[len-1]:="\0"
  143.       SetStr(line,len-1)    -> Adjust the internal lenght
  144.     ENDIF
  145.     /* Sort */
  146.     prev:=reclist
  147.     curr:=Next(prev)
  148.     found:=FALSE
  149.     IF line[0]<>"\n"                -> Sort "line" in the recent list
  150.       WHILE (curr<>NIL) AND Not(found)
  151.         dircmp:=Strnicmp(curr+19,line+19,10)    -> dircmp>0  if line.dir<curr.dir
  152.         filecmp:=Strnicmp(curr,line,18)        -> filecmp>0 if line.file<curr.file
  153.         IF ((dircmp=0) AND (filecmp>0)) OR (dircmp>0)
  154.           found:=TRUE
  155.         ELSE
  156.           prev:=curr
  157.           curr:=Next(curr)
  158.         ENDIF
  159.       ENDWHILE
  160.       s:=String(StrLen(line))    -> Alloc memory for the string
  161.       StrCopy(s,line,ALL)    -> Copy current line
  162.       IF prev THEN Link(prev,s) ELSE reclist:=s
  163.       Link(s,curr)
  164.     ENDIF
  165.     not_eof:=Fgets(rfh,line,MAXLEN)    -> Get next line
  166.     CtrlC()                -> Check user abort
  167.   ENDWHILE
  168. ENDPROC
  169.  
  170.  
  171. /* Extract date from the end of the string 's' */
  172.  
  173. PROC getdate(s,d:PTR TO date)
  174.   DEF i, dt:datetime
  175.   StrCopy(t,s)        -> Work on a backup copy
  176.   i:=StrLen(t)-1
  177.   IF t[i-1]="\b" THEN DEC i    -> Remove carriage returns
  178.   t[i]:="\0"            -> Remove \n at the end of the line.
  179.   IF i>4 AND t[i-3]<>"-"    -> If year has more than two digits, remove
  180.     t[i-4]:=t[i-2]        -> the first two (otherwise the Dos function
  181.     t[i-3]:=t[i-1]        -> 'StrToDate' doesn't work).
  182.     t[i-2]:="\0"
  183.   ENDIF
  184.   WHILE i>=0 AND t[i]<>" " DO DEC i    -> Search start of date string
  185.   AstrCopy(d.str,t+i+1,40)        -> Copy the date string
  186.   dt.format:=FORMAT_DOS
  187.   dt.flags:=0
  188.   dt.strdate:=d.str
  189.   dt.strtime:=NIL
  190.   IF StrToDate(dt)=FALSE THEN Raise(ER_DATE)    -> Convert into days
  191.   d.days:=dt.stamp.days
  192. ENDPROC
  193.  
  194.  
  195. /* Merge INDEX file with the recent list */
  196.  
  197. PROC merge()
  198.   DEF curr, dircmp, filecmp
  199.   curr:=reclist
  200.  
  201.   WHILE not_eof
  202.     IF curr
  203.       dircmp:=Strnicmp(line+19,curr+19,10)    -> dircmp>0 if line.dir>curr.dir
  204.       filecmp:=Strnicmp(line,curr,18)        -> filecmp>0 if line.file>curr.file
  205.       IF (dircmp>0) OR ((dircmp=0) AND (filecmp>=0))
  206.         StringF(t,'\s[34]   0\s',curr,curr+34)
  207.         Fputs(ofh,t)            -> insert 'curr' before 'line'
  208.         IF filecmp=0
  209.           INC id            -> duplicated line
  210.           not_eof:=Fgets(ifh,line,MAXLEN)    -> get next line from index
  211.         ENDIF          
  212.         curr:=Next(curr)
  213.       ELSE    -> copy 'line' and update the age column
  214.         copyline()
  215.       ENDIF
  216.     ELSE    -> copy 'line' and update the age column
  217.       copyline()
  218.     ENDIF
  219.     CtrlC()
  220.   ENDWHILE
  221.  
  222.   WHILE curr
  223.     StringF(t,'\s[34]   0\s',curr,curr+34)
  224.     Fputs(ofh,t)
  225.     curr:=Next(curr)
  226.     CtrlC() 
  227.  ENDWHILE
  228. ENDPROC
  229.  
  230. /* copy INDEX line to OUTPUT, updating the age column */
  231.  
  232. PROC copyline()
  233.   DEF i
  234.   IF wd>0
  235.     StringF(t,'\d[4]',Val(line+34)+wd)
  236.     FOR i:=0 TO 3 DO line[34+i]:=t[i]
  237.   ENDIF
  238.   Fputs(ofh,line)
  239.   not_eof:=Fgets(ifh,line,MAXLEN)
  240. ENDPROC
  241.  
  242.