home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / MNLDOS.ZIP / src / lsttool.c < prev    next >
C/C++ Source or Header  |  2004-07-21  |  13KB  |  439 lines

  1. /* $Id: lsttool.c,v 1.12 2004/07/20 04:29:47 fido 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.  
  14. #ifdef MALLOC_DEBUG
  15. #include "rmalloc.h"
  16. #endif
  17.  
  18. #ifdef DMALLOC
  19. #include "dmalloc.h"
  20. #endif
  21.  
  22. long ARCThreshold = 10000;
  23. long DIFFThreshold = 16666;
  24.  
  25. char ArcExt[4] = "a";           /* Let's add some default values */
  26. char ArcCopyCmd[20] = "arc a";
  27. char ArcMoveCmd[20] = "arc m";
  28. char ArcOpenCmd[20] = "arc ew";
  29.  
  30.  
  31. #if 0
  32. static unsigned int arcparas = 0x4000; /* 256 KBytes */
  33.  
  34. #endif
  35. static unsigned short DiffCRC;
  36. static char DiffLine[linelength];
  37. static int EditCount;
  38. static int AddLines;
  39. static int dodiffline(int checktop, FILE * oldFILE, FILE * diffFILE);
  40.  
  41. int makearc(char *filename, int move)
  42. {
  43.     char ext[MYMAXEXT];
  44.     char name[MYMAXFILE];
  45.     char fullpath[MYMAXPATH];
  46.     char cmdlinebuf[124];
  47.     char arccommand[ARCCMDMAX];
  48.  
  49.     if (filesize(filename) <= ARCThreshold || ARCThreshold == -1)
  50.         return 0;
  51.     strcpy(fullpath, filename);
  52.     myfnsplit(filename, NULL, NULL, name, ext);
  53.     if (toupper(ext[0]) == 'D')          /* Autogenerated diff - can always be
  54.                                    moved */
  55.     {
  56.         ext[1] = 'd';
  57.         strcpy(arccommand, ArcMoveCmd); /* move instead of add */
  58.     }
  59.     else
  60.         strcpy(arccommand, (move < 1) ? ArcCopyCmd : ArcMoveCmd);
  61.     ext[0] = ArcExt[0];
  62.     myfnmerge(fullpath, NULL, OutDir, name, ext);
  63.     os_filecanonify(fullpath);
  64.     os_filecanonify(filename);
  65.     fprintf(stdout, "\nCreating archive \"%s\" containing \"%s\"\n",
  66.             fullpath, filename);
  67.     sprintf(cmdlinebuf, "%s %s", fullpath, filename);
  68.     if (os_spawn(arccommand, cmdlinebuf) != 0)
  69.         die(0xFD, 1, "Unable to create archive \"%s\"", fullpath);
  70.     strcpy(filename, fullpath);
  71.     return 1;
  72. }
  73.  
  74. /* Returns:
  75.    1 if list is unchanged,
  76.    0 else
  77.  */
  78. int installlist(char *filename, char *extbfr)
  79. {
  80.     char *outext;
  81.     char *oldstart;
  82.     FILE *oldFILE = NULL;
  83.     char *tmpstart;
  84.     int weeksold = 0;
  85.     FILE *tmpFILE = NULL;
  86.     int unchanged = 0;
  87.     char (*extptr)[MYMAXEXT];
  88.     char tmpname[linelength];
  89.     char tmpline[linelength];
  90.     char oldline[linelength];
  91.  
  92.     for (extptr = OldExtensions; extptr < OldExtensions + 3; extptr++)
  93.     {
  94.         outext = getext(extbfr, OutFile) ? NULL : *extptr;
  95.         myfnmerge(filename, NULL, OutDir, OutFile, outext);
  96.         oldFILE = fopen(filename, "r");
  97.         if (oldFILE != NULL || extbfr[0] != 0)
  98.             break;
  99.         weeksold++;
  100.     }
  101.     swapext(tmpname, filename, "$$$");
  102.     if (oldFILE && OutDiff[0] == 0)
  103.     {
  104.         tmpFILE = fopen(tmpname, "r");
  105.         if (!tmpFILE)
  106.             die(254, 1, "Unable to open new list \"%s\" for input\n",
  107.                 tmpname);
  108.         if (fgets(tmpline, linelength, tmpFILE)
  109.             && fgets(oldline, linelength, oldFILE)
  110.             && (tmpstart = strrchr(tmpline, ' ')) != NULL
  111.             && (oldstart = strrchr(oldline, ' ')) != NULL)
  112.             while (!strcmp(oldstart, tmpstart))
  113.             {
  114.                 tmpstart = fgets(tmpline, linelength, tmpFILE);
  115.                 oldstart = fgets(oldline, linelength, oldFILE);
  116.                 if (tmpstart == NULL || oldstart == NULL)
  117.                 {
  118.                     unchanged = 1;
  119.                     break;
  120.                 }
  121.             }
  122.         fclose(tmpFILE);
  123.     }
  124.     if (oldFILE)
  125.         fclose(oldFILE);
  126.  
  127.     if (unchanged)
  128.     {
  129.         unlink(tmpname);
  130.         if (extbfr[0] == 0)     /* generic filename given */
  131.         {
  132.             if (weeksold != 0)
  133.             {
  134.                 swapext(tmpname, filename, OldExtensions[0]);
  135.                 rename(filename, tmpname);
  136.                 strcpy(filename, tmpname);
  137.             }
  138.             for (extptr = OldExtensions + weeksold + 1;
  139.                  extptr < OldExtensions + 3; extptr++)
  140.             {
  141.                 swapext(tmpname, filename, *extptr);
  142.                 unlink(tmpname);
  143.             }
  144.         }
  145.         fputs("Unchanged output file will NOT be submitted.\n", stdout);
  146.     }
  147.     else
  148.     {
  149.         if (weeksold != 0)
  150.             swapext(filename, tmpname, OldExtensions[0]);
  151.         else
  152.             unlink(filename);
  153.         rename(tmpname, filename);
  154.     }
  155.     return unchanged;
  156. }
  157.  
  158. static int ApplyDiff(FILE * oldFILE, char *diffname, char *outname)
  159. {
  160.     int firststatus;
  161.     char *crcptr;               /* 0x02 */
  162.     FILE *outFILE;              /* 0x04 */
  163.     FILE *diffFILE;             /* 0x06 */
  164.     unsigned short newcrc;      /* 0x08 */
  165.  
  166.     diffFILE = fopen(diffname, "r");
  167.     if (!diffFILE)
  168.         die(254, 1, "Unable to open %s for input", diffname);
  169.     outFILE = fopen(outname, "wb");
  170.     if (!outFILE)
  171.         die(254, 1, "Unable to create %s", outname);
  172.     firststatus = dodiffline(1, oldFILE, diffFILE);
  173.     if (firststatus == 0)       /* diff fits */
  174.     {
  175.         /* DiffLine now contains the new header including CRC */
  176.         cutspaces(DiffLine);
  177.         strcat(DiffLine, "\r\n");
  178.         crcptr = DiffLine + strlen(DiffLine);
  179.         while (*(--crcptr) != ' ');
  180.         getnumber(crcptr + 1, (int *)&newcrc);
  181.         fputs(DiffLine, outFILE);
  182.         DiffCRC = 0;
  183.         while (dodiffline(0, oldFILE, diffFILE) == 0)
  184.         {
  185.             cutspaces(DiffLine);
  186.             strcat(DiffLine, "\r\n");
  187.             fputs(DiffLine, outFILE);
  188.             DiffCRC = CRC16String(DiffLine, DiffCRC);
  189.         }
  190.         putc('\x1A', outFILE);
  191.     }
  192.     fclose(outFILE);
  193.     fclose(oldFILE);
  194.     fclose(diffFILE);
  195.     if (firststatus == -1
  196.         || CRC16DoByte((char)(newcrc & 0xFF),
  197.                        CRC16DoByte((char)(newcrc >> 8), DiffCRC)) != 0)
  198.     {
  199.         unlink(outname);
  200.         return -1;
  201.     }
  202.     return 0;
  203. }
  204.  
  205. static int dodiffline(int checktop, FILE * oldFILE, FILE * diffFILE)
  206. {
  207.     char topline[linelength];
  208.  
  209.     if (checktop)
  210.     {
  211.         EditCount = 0;
  212.         if (fgets(topline, linelength, diffFILE) == NULL)
  213.             return -1;
  214.     }
  215.     while (EditCount == 0)
  216.     {
  217.         if (fgets(DiffLine, linelength, diffFILE) == NULL)
  218.             /* return 1 if call fails - -1 if it works */
  219.             return 2 * !fgets(DiffLine, linelength, diffFILE) - 1;
  220.         getnumber(DiffLine + 1, &EditCount);
  221.         switch (DiffLine[0])
  222.         {
  223.         default:
  224.             return -1;
  225.         case 'A':
  226.             AddLines = 1;
  227.             break;
  228.         case 'C':
  229.             AddLines = 0;
  230.             break;
  231.         case 'D':
  232.             if (EditCount)
  233.                 do
  234.                 {
  235.                     if (fgets(DiffLine, linelength, oldFILE) == NULL)
  236.                         return -1;
  237.                     if (checktop)
  238.                     {
  239.                         if (strcmp(DiffLine, topline))
  240.                             return -1;
  241.                         checktop--;
  242.                     }
  243.                 }
  244.                 while (--EditCount);
  245.             break;
  246.         }
  247.     }
  248.     if (fgets(DiffLine, linelength, (AddLines ? diffFILE : oldFILE)) ==
  249.         NULL)
  250.         return -1;
  251.     EditCount--;
  252.     return 0;
  253. }
  254.  
  255. static int searchlistfile(FILE ** someptr, const char *path,
  256.                           char *foundfile, char *name, char *ext,
  257.                           int unpackedonly);
  258.  
  259. /* Returns:
  260.    -1 : error
  261.    0 : not found
  262.    >0 : found, next search for same list should start here
  263.  */
  264. int
  265. openlist(FILE ** listFILEptr, char *filename, char *foundfile, int where,
  266.          int mustbenew)
  267. {
  268.     int status;
  269.     char ext[MYMAXEXT];
  270.     char name[MYMAXFILE + MYMAXEXT];
  271.  
  272.     myfnsplit(filename, NULL, NULL, name, ext);
  273.     switch (where)
  274.     {
  275.     default:
  276.         return 0;
  277.     case SEARCH_UPLOAD:
  278.         status =
  279.             searchlistfile(listFILEptr, UploadDir, foundfile, name, ext,
  280.                            0);
  281.         if (status == 1)
  282.             return SEARCH_MAILFILE;
  283.         if (status != 0)
  284.             return -1;
  285.         /* FALLTHROUGH */
  286.     case SEARCH_MAILFILE:
  287.         status =
  288.             searchlistfile(listFILEptr, MailfileDir, foundfile, name, ext,
  289.                            0);
  290.         if (status == 1)
  291.             return SEARCH_UPDATE;
  292.         if (status != 0)
  293.             return -1;
  294.         /* FALLTHROUGH */
  295.     case SEARCH_UPDATE:
  296.         if (mustbenew)
  297.             return 0;
  298.         status =
  299.             searchlistfile(listFILEptr, UpdateDir, foundfile, name, ext,
  300.                            1);
  301.         if (status == 1)
  302.             return SEARCH_MASTER;
  303.         if (status != 0)
  304.             return -1;
  305.     case SEARCH_MASTER:
  306.         if (mustbenew)
  307.             return 0;
  308.         status =
  309.             searchlistfile(listFILEptr, MasterDir, foundfile, name, ext,
  310.                            1);
  311.         if (status == 1)
  312.             return SEARCH_NOWHERE;
  313.         if (status != 0)
  314.             return -1;
  315.         return 0;
  316.     }
  317. }
  318.  
  319. /* Returns:
  320.    -1: error
  321.    0: no matching file found
  322.    +1: file found and opened */
  323. int
  324. searchlistfile(FILE ** file, const char *path, char *foundfile, char *name,
  325.                char *ext, int unpackedonly)
  326. {
  327.     struct _filefind f;
  328.     char fnamebuf[MYMAXDIR];
  329.     char cmdlinebuf[128];
  330.     char (*extptr)[MYMAXEXT];
  331.     char extbuf[MYMAXEXT];
  332.     char *findresult;
  333.     int searchwhere;
  334.  
  335.     if (path[0] == 0)
  336.         return 0;
  337.     while (!(ext[0] == 0 && unpackedonly))
  338.     {
  339.         myfnmerge(foundfile, NULL, NULL, name, ext[0] ? ext : "*");
  340.         findresult = os_findfile(&f, path, foundfile);
  341.         if (!findresult)
  342.             return 0;
  343.         getext(extbuf, findresult);
  344.         myfnmerge(foundfile, NULL, path, findresult, NULL);
  345.         os_deslashify(foundfile);
  346.         if ((ext[0] == 0) && (extbuf[0] == ArcExt[0])) /* ARCed file */
  347.         {
  348.             myfnmerge(fnamebuf, NULL, path, NULL, NULL);
  349.             os_deslashify(fnamebuf);
  350.  
  351.             fprintf(stdout, "Attempting to unpack archive \"%s\"\n",
  352.                     foundfile);
  353.             sprintf(cmdlinebuf, "%s %s", foundfile, fnamebuf);
  354.             if (os_spawn(ArcOpenCmd, cmdlinebuf) != 0)
  355.             {
  356.                 fprintf(stderr, "Unable to unpack archive \"%s\".  ",
  357.                         foundfile);
  358.                 WorkFile = os_file_getname(foundfile);
  359.                 os_filecanonify(WorkFile);
  360.                 *file = OpenMSGFile(NotifyAddress, NULL);
  361.                 if (*file != NULL)
  362.                 {
  363.                     fprintf(*file, "Unable to unpack archive \"%s\".  ",
  364.                             WorkFile);
  365.                     fputs("Please resubmit it.", *file);
  366.                     CloseMSGFile(1);
  367.                 }
  368.             }
  369.             unlink(foundfile);
  370.         }
  371.         else if (ext[0] == 0 && toupper((unsigned char)extbuf[0]) == 'D') /* DIFFed 
  372.                                                                              file 
  373.                                                                            */
  374.         {
  375.             fprintf(stdout, "Attempting to apply difference file \"%s\"\n",
  376.                     foundfile);
  377.             extptr = OldExtensions;
  378.             do
  379.             {
  380.                 swapext(findresult, name, *extptr);
  381.                 searchwhere = SEARCH_UPDATE;
  382.                 while (searchwhere != 0)
  383.                 {
  384.                     searchwhere =
  385.                         openlist(file, findresult, fnamebuf, searchwhere,
  386.                                  0);
  387.                     if (searchwhere)
  388.                     {
  389.                         myfnmerge(fnamebuf, NULL, path, name,
  390.                                   OldExtensions[0]);
  391.                         if (ApplyDiff(*file, foundfile, fnamebuf) == 0)
  392.                             goto out_of_loops;
  393.                     }
  394.                 }
  395.                 extptr++;
  396.             }
  397.             while (extptr < OldExtensions + 3);
  398.           out_of_loops:
  399.             unlink(foundfile);
  400.             if (searchwhere == 0)
  401.             {
  402.                 fprintf(stdout,
  403.                         "Unable to apply difference file \"%s\".  ",
  404.                         foundfile);
  405.                 WorkFile = os_file_getname(foundfile);
  406.                 os_filecanonify(WorkFile);
  407.                 *file = OpenMSGFile(NotifyAddress, NULL);
  408.                 if (*file)
  409.                 {
  410.                     fprintf(*file,
  411.                             "Unable to apply difference file \"%s\".  ",
  412.                             WorkFile);
  413.                     fputs("Please submit your full update file.", *file);
  414.                     *file = CloseMSGFile(1);
  415.                 }
  416.             }
  417.         }
  418.         else
  419.             goto justthisfile;
  420.     }
  421.     for (extptr = OldExtensions; extptr < OldExtensions + 3; extptr++)
  422.     {
  423.         myfnmerge(foundfile, NULL, NULL, name, *extptr);
  424.         if (os_findfile(&f, path, foundfile) != NULL)
  425.         {
  426.             myfnmerge(foundfile, NULL, path, name, *extptr);
  427.             os_deslashify(foundfile);
  428.           justthisfile:
  429.             *file = fopen(foundfile, "r");
  430.             if (!*file)
  431.                 return -1;
  432.             WorkFile = os_file_getname(foundfile);
  433.             os_filecanonify(WorkFile);
  434.             return 1;
  435.         }
  436.     }
  437.     return 0;
  438. }
  439.