home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / MN325SRC.ZIP / makenl-3.2.5 / src / lsttool.c < prev    next >
C/C++ Source or Header  |  2005-02-06  |  17KB  |  552 lines

  1. /* $Id: lsttool.c,v 1.19 2004/12/12 19:45:56 mbroek Exp $ */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7.  
  8. #include "makenl.h"
  9. #include "fileutil.h"
  10. #include "crc16.h"
  11. #include "lsttool.h"
  12. #include "msg.h"
  13. #include "mklog.h"
  14. #include "proc.h"
  15.  
  16. #ifdef MALLOC_DEBUG
  17. #include "rmalloc.h"
  18. #endif
  19.  
  20. #ifdef DMALLOC
  21. #include "dmalloc.h"
  22. #endif
  23.  
  24. long ARCThreshold = 10000;
  25. long DIFFThreshold = 16666;
  26.  
  27. char ArcCopyExt[ARCEXTMAX];
  28. char ArcCopyCmd[ARCCMDMAX];
  29. char ArcMoveExt[ARCEXTMAX];
  30. char ArcMoveCmd[ARCCMDMAX];
  31. char ArcOpenExt[ARCUNPMAX][ARCEXTMAX];
  32. char ArcOpenCmd[ARCUNPMAX][ARCCMDMAX];
  33. int  ArcOpenCnt = 0;
  34.  
  35. int ForceSubmit = 0;
  36.  
  37. #if 0
  38. static unsigned int arcparas = 0x4000; /* 256 KBytes */
  39.  
  40. #endif
  41. static unsigned short DiffCRC;
  42. static char DiffLine[linelength];
  43. static int EditCount;
  44. static int AddLines;
  45. static int dodiffline(int checktop, FILE * oldFILE, FILE * diffFILE);
  46.  
  47. int makearc(char *filename, int move)
  48. {
  49.     char ext[MYMAXEXT];
  50.     char name[MYMAXFILE];
  51.     char fullpath[MYMAXPATH];
  52.     char cmdlinebuf[MYMAXPATH];
  53.     char arccommand[ARCCMDMAX];
  54.  
  55.     if (filesize(filename) <= ARCThreshold || ARCThreshold == -1)
  56.     {
  57.     mklog(3, "Skip arc for %s", filename);
  58.         return 0;
  59.     }
  60.  
  61.     strcpy(fullpath, filename);
  62.     myfnsplit(filename, NULL, NULL, name, ext);
  63.     if (toupper(ext[0]) == 'D')          /* Autogenerated diff - can always be
  64.                                    moved */
  65.     {
  66.         ext[1] = 'd';
  67.         strcpy(arccommand, ArcMoveCmd); /* move instead of add */
  68.     ext[0] = ArcMoveExt[0];
  69.     }
  70.     else
  71.     {
  72.         strcpy(arccommand, (move < 1) ? ArcCopyCmd : ArcMoveCmd);
  73.     ext[0] = (move < 1) ? ArcCopyExt[0] : ArcMoveExt[0];
  74.     }
  75.     myfnmerge(fullpath, NULL, OutDir, name, ext);
  76.     os_filecanonify(fullpath);
  77.     os_filecanonify(filename);
  78.     mklog(1, "Creating archive \"%s\" containing \"%s\"", fullpath, filename);
  79.     fprintf(stdout, "\nCreating archive \"%s\" containing \"%s\"\n",
  80.             fullpath, filename);
  81.     sprintf(cmdlinebuf, "%s %s", fullpath, filename);
  82.     if (os_spawn(arccommand, cmdlinebuf) != 0)
  83.         die(0xFD, 1, "Unable to create archive \"%s\"", fullpath);
  84.     strcpy(filename, fullpath);
  85.     return 1;
  86. }
  87.  
  88. /* Returns:
  89.    1 if list is unchanged,
  90.    0 else
  91.  */
  92. int installlist(char *filename, char *extbfr)
  93. {
  94.     char *outext;
  95.     char *oldstart;
  96.     FILE *oldFILE = NULL;
  97.     char *tmpstart;
  98.     int weeksold = 0;
  99.     FILE *tmpFILE = NULL;
  100.     int unchanged = 0;
  101.     char (*extptr)[MYMAXEXT];
  102.     char tmpname[linelength];
  103.     char tmpline[linelength];
  104.     char oldline[linelength];
  105.  
  106.     for (extptr = OldExtensions; extptr < OldExtensions + 3; extptr++)
  107.     {
  108.         outext = getext(extbfr, OutFile) ? NULL : *extptr;
  109.         myfnmerge(filename, NULL, OutDir, OutFile, outext);
  110.         oldFILE = fopen(filename, "r");
  111.         if (oldFILE != NULL || extbfr[0] != 0)
  112.             break;
  113.         weeksold++;
  114.     }
  115.     swapext(tmpname, filename, "$$$");
  116.     if (oldFILE && OutDiff[0] == 0)
  117.     {
  118.         tmpFILE = fopen(tmpname, "r");
  119.         if (!tmpFILE)
  120.             die(254, 1, "Unable to open new list \"%s\" for input\n",
  121.                 tmpname);
  122.         if (fgets(tmpline, linelength, tmpFILE)
  123.             && fgets(oldline, linelength, oldFILE)
  124.             && (tmpstart = strrchr(tmpline, ' ')) != NULL
  125.             && (oldstart = strrchr(oldline, ' ')) != NULL)
  126.             while (!strcmp(oldstart, tmpstart))
  127.             {
  128.                 tmpstart = fgets(tmpline, linelength, tmpFILE);
  129.                 oldstart = fgets(oldline, linelength, oldFILE);
  130.                 if (tmpstart == NULL || oldstart == NULL)
  131.                 {
  132.                     unchanged = 1;
  133.                     break;
  134.                 }
  135.             }
  136.         fclose(tmpFILE);
  137.     }
  138.     if (oldFILE)
  139.         fclose(oldFILE);
  140.  
  141.     if (unchanged && (ShouldProcess & FORCED_PROCESSING) && ForceSubmit) 
  142.     {
  143.     fputs("Unchanged output file will be forced submitted\n", stdout);
  144.     mklog(1, "Unchanged output file will be forced submitted");
  145.     unchanged = 0;
  146.     }
  147.     
  148.     if (unchanged)
  149.     {
  150.         unlink(tmpname);
  151.         if (extbfr[0] == 0)     /* generic filename given */
  152.         {
  153.             if (weeksold != 0)
  154.             {
  155.                 swapext(tmpname, filename, OldExtensions[0]);
  156.                 rename(filename, tmpname);
  157.                 strcpy(filename, tmpname);
  158.             }
  159.             for (extptr = OldExtensions + weeksold + 1;
  160.                  extptr < OldExtensions + 3; extptr++)
  161.             {
  162.                 swapext(tmpname, filename, *extptr);
  163.                 unlink(tmpname);
  164.             }
  165.         }
  166.         fputs("Unchanged output file will NOT be submitted.\n", stdout);
  167.     mklog(1, "Unchanged output file will NOT be submitted");
  168.     }
  169.     else
  170.     {
  171.         if (weeksold != 0)
  172.             swapext(filename, tmpname, OldExtensions[0]);
  173.         else
  174.             unlink(filename);
  175.         rename(tmpname, filename);
  176.     }
  177.     return unchanged;
  178. }
  179.  
  180. static int ApplyDiff(FILE * oldFILE, char *diffname, char *outname)
  181. {
  182.     int firststatus;
  183.     char *crcptr;               /* 0x02 */
  184.     FILE *outFILE;              /* 0x04 */
  185.     FILE *diffFILE;             /* 0x06 */
  186.     unsigned short newcrc;      /* 0x08 */
  187.  
  188.     mklog(3, "applydiff \"%s\" to \"%s\"", diffname, outname);
  189.  
  190.     diffFILE = fopen(diffname, "r");
  191.     if (!diffFILE)
  192.         die(254, 1, "Unable to open %s for input", diffname);
  193.     outFILE = fopen(outname, "wb");
  194.     if (!outFILE)
  195.         die(254, 1, "Unable to create %s", outname);
  196.     firststatus = dodiffline(1, oldFILE, diffFILE);
  197.     if (firststatus == 0)       /* diff fits */
  198.     {
  199.         /* DiffLine now contains the new header including CRC */
  200.         cutspaces(DiffLine);
  201.         strcat(DiffLine, "\r\n");
  202.         crcptr = DiffLine + strlen(DiffLine);
  203.         while (*(--crcptr) != ' ');
  204.         getnumber(crcptr + 1, (int *)&newcrc);
  205.         fputs(DiffLine, outFILE);
  206.         DiffCRC = 0;
  207.         while (dodiffline(0, oldFILE, diffFILE) == 0)
  208.         {
  209.             cutspaces(DiffLine);
  210.             strcat(DiffLine, "\r\n");
  211.             fputs(DiffLine, outFILE);
  212.             DiffCRC = CRC16String(DiffLine, DiffCRC);
  213.         }
  214.         putc('\x1A', outFILE);
  215.     }
  216.     fclose(outFILE);
  217.     fclose(oldFILE);
  218.     fclose(diffFILE);
  219.     if (firststatus == -1
  220.         || CRC16DoByte((char)(newcrc & 0xFF),
  221.                        CRC16DoByte((char)(newcrc >> 8), DiffCRC)) != 0)
  222.     {
  223.         unlink(outname);
  224.         return -1;
  225.     }
  226.     return 0;
  227. }
  228.  
  229. static int dodiffline(int checktop, FILE * oldFILE, FILE * diffFILE)
  230. {
  231.     char topline[linelength];
  232.  
  233.     if (checktop)
  234.     {
  235.         EditCount = 0;
  236.         if (fgets(topline, linelength, diffFILE) == NULL)
  237.             return -1;
  238.     }
  239.     while (EditCount == 0)
  240.     {
  241.         if (fgets(DiffLine, linelength, diffFILE) == NULL)
  242.             /* return 1 if call fails - -1 if it works */
  243.             return 2 * !fgets(DiffLine, linelength, diffFILE) - 1;
  244.         getnumber(DiffLine + 1, &EditCount);
  245.         switch (DiffLine[0])
  246.         {
  247.         default:
  248.             return -1;
  249.         case 'A':
  250.             AddLines = 1;
  251.             break;
  252.         case 'C':
  253.             AddLines = 0;
  254.             break;
  255.         case 'D':
  256.             if (EditCount)
  257.                 do
  258.                 {
  259.                     if (fgets(DiffLine, linelength, oldFILE) == NULL)
  260.                         return -1;
  261.                     if (checktop)
  262.                     {
  263.                         if (strcmp(DiffLine, topline))
  264.                             return -1;
  265.                         checktop--;
  266.                     }
  267.                 }
  268.                 while (--EditCount);
  269.             break;
  270.         }
  271.     }
  272.     if (fgets(DiffLine, linelength, (AddLines ? diffFILE : oldFILE)) ==
  273.         NULL)
  274.         return -1;
  275.     EditCount--;
  276.     return 0;
  277. }
  278.  
  279.  
  280.  
  281. /*
  282.  * Test unpacker, see also makenl.h for ARCUNPMAX
  283.  */
  284. char *unpacker(char *fn)
  285. {
  286.     FILE            *fp;
  287.     unsigned char   buf[8];
  288.  
  289.     if ((fp = fopen(fn,"r")) == NULL) {
  290.     fprintf(stderr, "Could not open file %s\n", fn);
  291.     return NULL;
  292.     }
  293.  
  294.     if (fread(buf,1,sizeof(buf),fp) != sizeof(buf)) {
  295.     fprintf(stderr, "Could not read head of the file %s\n", fn);
  296.     fclose(fp);
  297.     return NULL;
  298.     }
  299.     fclose(fp);
  300.  
  301.     if (memcmp(buf,"PK\003\004",4) == 0)    return (char *)"Z";        /* ZIP    */
  302.     if (*buf == 0x1a)                       return (char *)"A";        /* ARC    */
  303.     if (memcmp(buf+2,"-l",2) == 0)          return (char *)"L";        /* LHA    */
  304.     if (memcmp(buf,"ZOO",3) == 0)           return (char *)"O";        /* ZOO    */
  305.     if (memcmp(buf,"`\352",2) == 0)         return (char *)"J";        /* ARJ    */
  306.     if (memcmp(buf,"Rar!",4) == 0)          return (char *)"R";        /* RAR    */
  307.     if (memcmp(buf,"HA",2) == 0)            return (char *)"H";        /* HA    */
  308.     if (memcmp(buf,"BZ",2) == 0)            return (char *)"B";        /* BZIP2    */
  309.     if (memcmp(buf,"\037\213",2) == 0)      return (char *)"G";        /* GZIP    */
  310.     if (memcmp(buf,"\037\235",2) == 0)      return (char *)"C";        /* COMPRESS    */
  311.  
  312.     return NULL;    /* Unknown compressed or plain ASCII    */
  313. }
  314.  
  315.  
  316.  
  317. static int searchlistfile(FILE ** someptr, const char *path,
  318.                           char *foundfile, char *name, char *ext,
  319.                           int unpackedonly);
  320.  
  321. /* Returns:
  322.    -1 : error
  323.     0 : not found
  324.    >0 : found, next search for same list should start here
  325.  */
  326. int
  327. openlist(FILE ** listFILEptr, char *filename, char *foundfile, int where,
  328.          int mustbenew)
  329. {
  330.     int status;
  331.     char ext[MYMAXEXT];
  332.     char name[MYMAXFILE + MYMAXEXT];
  333.  
  334.     mklog(3, "openlist \"%s\", mustbenew %s", filename, mustbenew ? "yes":"no");
  335.  
  336.     myfnsplit(filename, NULL, NULL, name, ext);
  337.     switch (where)
  338.     {
  339.     default:
  340.         return 0;
  341.     case SEARCH_UPLOAD:
  342.         status =
  343.             searchlistfile(listFILEptr, UploadDir, foundfile, name, ext,
  344.                            0);
  345.         if (status == 1)
  346.             return SEARCH_MAILFILE;
  347.         if (status != 0)
  348.             return -1;
  349.         /* FALLTHROUGH */
  350.     case SEARCH_MAILFILE:
  351.         status =
  352.             searchlistfile(listFILEptr, MailfileDir, foundfile, name, ext,
  353.                            0);
  354.         if (status == 1)
  355.             return SEARCH_UPDATE;
  356.         if (status != 0)
  357.             return -1;
  358.         /* FALLTHROUGH */
  359.     case SEARCH_UPDATE:
  360.         if (mustbenew)
  361.             return 0;
  362.         status =
  363.             searchlistfile(listFILEptr, UpdateDir, foundfile, name, ext,
  364.                            1);
  365.         if (status == 1)
  366.             return SEARCH_MASTER;
  367.         if (status != 0)
  368.             return -1;
  369.     case SEARCH_MASTER:
  370.         if (mustbenew)
  371.             return 0;
  372.         status =
  373.             searchlistfile(listFILEptr, MasterDir, foundfile, name, ext,
  374.                            1);
  375.         if (status == 1)
  376.             return SEARCH_NOWHERE;
  377.         if (status != 0)
  378.             return -1;
  379.         return 0;
  380.     }
  381. }
  382.  
  383. /* Returns:
  384.    -1: error
  385.     0: no matching file found
  386.    +1: file found and opened */
  387. int
  388. searchlistfile(FILE ** file, const char *path, char *foundfile, char *name,
  389.                char *ext, int unpackedonly)
  390. {
  391.     struct _filefind f;
  392.     char fnamebuf[MYMAXDIR];
  393.     char cmdlinebuf[128];
  394.     char (*extptr)[MYMAXEXT];
  395.     char extbuf[MYMAXEXT];
  396.     char *findresult;
  397.     int searchwhere;
  398.     char *unarc;
  399.     int i;
  400.     char ArcOpen[ARCCMDMAX];
  401.  
  402.     mklog(3, "searchlistfile: \"%s\" \"%s\" \"%s\" \"%s\" %d", path, foundfile, name, ext, unpackedonly);
  403.  
  404.     if (path[0] == 0)
  405.         return 0;
  406.     while (!(ext[0] == 0 && unpackedonly))
  407.     {    
  408.     mklog(4, "searchlistfile: in top of while loop");
  409.         myfnmerge(foundfile, NULL, NULL, name, ext[0] ? ext : "*");
  410.         findresult = os_findfile(&f, path, foundfile);
  411.         if (!findresult)
  412.     {
  413.         mklog(4, "searchlistfile: nothing found, return 0");
  414.         foundfile[0] = '\0';
  415.             return 0;
  416.     }
  417.     mklog(4, "searchlistfile: found \"%s\"", findresult);
  418.         getext(extbuf, findresult);
  419.         myfnmerge(foundfile, NULL, path, findresult, NULL);
  420.         os_deslashify(foundfile);
  421.     if ((unarc = unpacker(foundfile)) != NULL)  /* Compressed file    */
  422.     {
  423.         /*
  424.          * Search decompressor
  425.          */
  426.         ArcOpen[0] = '\0';
  427.         for (i = 0; i < ArcOpenCnt; i++)
  428.         {
  429.         if (toupper((unsigned char)unarc[0]) == toupper((unsigned char)ArcOpenExt[i][0]))
  430.         {
  431.             strcpy(ArcOpen, ArcOpenCmd[i]);
  432.             break;
  433.         }
  434.         }
  435.         if (ArcOpen[0] == '\0')
  436.         {
  437.         fprintf(stderr, "No ArcOpen command for \"%s\"\n", foundfile);
  438.         mklog(0, "No ArcOpen command for \"%s\"", foundfile);
  439.         }
  440.         else
  441.         {
  442.         fprintf(stdout, "Attempting to unpack archive \"%s\"\n", foundfile);
  443.         mklog(1, "Attempting to unpack archive \"%s\"", foundfile);
  444.         }
  445.             myfnmerge(fnamebuf, NULL, path, NULL, NULL);
  446.             os_deslashify(fnamebuf);
  447.         /*
  448.          * We need to chdir to the directory where the archive is found
  449.          * so that the file is hopefully unpacked in the that directory.
  450.          */
  451.         if (chdir(fnamebuf))
  452.         {
  453.         fprintf(stderr, "Can't chdir to \"%s\"\n", fnamebuf);
  454.         mklog(0, "Can't chdir to \"%s\"", fnamebuf);
  455.         }
  456.         else
  457.         {
  458.         /* Some archivers don't work well when the filename is given */
  459.         /* sprintf(cmdlinebuf, "%s %s.%s", foundfile, name, ext); */
  460.         sprintf(cmdlinebuf, "%s", foundfile);
  461.         if ((ArcOpen[0] == '\0') || (os_spawn(ArcOpen, cmdlinebuf) != 0))
  462.         {
  463.             fprintf(stderr, "Unable to unpack archive \"%s\".\n", foundfile);
  464.             mklog(0, "Unable to unpack archive \"%s\"", foundfile);
  465.             WorkFile = os_file_getname(foundfile);
  466.             os_filecanonify(WorkFile);
  467.             *file = OpenMSGFile(NotifyAddress, NULL);
  468.             if (*file != NULL)
  469.             {
  470.             fprintf(*file, "Unable to unpack archive \"%s\".\n", WorkFile);
  471.             fputs("Please resubmit it.", *file);
  472.             CloseMSGFile(1);
  473.             }
  474.         }
  475.         chdir(CurDir);
  476.             }
  477.             unlink(foundfile);
  478.         }
  479.         else if (ext[0] == 0 && toupper((unsigned char)extbuf[0]) == 'D') /* DIFFed 
  480.                                                                              file 
  481.                                                                            */
  482.         {
  483.             fprintf(stdout, "Attempting to apply difference file \"%s\"\n",
  484.                     foundfile);
  485.         mklog(1, "Attempting to apply difference file \"%s\"", foundfile);
  486.             extptr = OldExtensions;
  487.             do
  488.             {
  489.                 swapext(findresult, name, *extptr);
  490.                 searchwhere = SEARCH_UPDATE;
  491.                 while (searchwhere != 0)
  492.                 {
  493.                     searchwhere =
  494.                         openlist(file, findresult, fnamebuf, searchwhere,
  495.                                  0);
  496.                     if (searchwhere)
  497.                     {
  498.                         myfnmerge(fnamebuf, NULL, path, name,
  499.                                   OldExtensions[0]);
  500.                         if (ApplyDiff(*file, foundfile, fnamebuf) == 0)
  501.                             goto out_of_loops;
  502.                     }
  503.                 }
  504.                 extptr++;
  505.             }
  506.             while (extptr < OldExtensions + 3);
  507.           out_of_loops:
  508.             unlink(foundfile);
  509.             if (searchwhere == 0)
  510.             {
  511.                 fprintf(stdout,
  512.                         "Unable to apply difference file \"%s\".  ",
  513.                         foundfile);
  514.         mklog(1, "Unable to apply difference file \"%s\"", foundfile);
  515.                 WorkFile = os_file_getname(foundfile);
  516.                 os_filecanonify(WorkFile);
  517.                 *file = OpenMSGFile(NotifyAddress, NULL);
  518.                 if (*file)
  519.                 {
  520.                     fprintf(*file,
  521.                             "Unable to apply difference file \"%s\".  ",
  522.                             WorkFile);
  523.                     fputs("Please submit your full update file.", *file);
  524.                     *file = CloseMSGFile(1);
  525.                 }
  526.             }
  527.         }
  528.         else
  529.     {
  530.             goto justthisfile;
  531.     }
  532.     }
  533.     for (extptr = OldExtensions; extptr < OldExtensions + 3; extptr++)
  534.     {
  535.         myfnmerge(foundfile, NULL, NULL, name, *extptr);
  536.         if (os_findfile(&f, path, foundfile) != NULL)
  537.         {
  538.             myfnmerge(foundfile, NULL, path, name, *extptr);
  539.             os_deslashify(foundfile);
  540.       justthisfile:
  541.         mklog(3, "searchlistfile: justthisfile, foundfile=\"%s\"", foundfile);
  542.             *file = fopen(foundfile, "r");
  543.             if (!*file)
  544.                 return -1;
  545.             WorkFile = os_file_getname(foundfile);
  546.             os_filecanonify(WorkFile);
  547.             return 1;
  548.         }
  549.     }
  550.     return 0;
  551. }
  552.