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 / process.c < prev    next >
C/C++ Source or Header  |  2005-02-06  |  13KB  |  380 lines

  1. /* $Id: process.c,v 1.15 2004/09/05 10:43:57 mbroek Exp $ */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7. #include "makenl.h"
  8. #include "crc16.h"
  9. #include "proc.h"
  10. #include "msg.h"
  11. #include "fts5.h"
  12. #include "lsttool.h"
  13. #include "fileutil.h"
  14. #include "upcont.h"
  15. #include "stack.h"
  16. #include "config.h"
  17. #include "mklog.h"
  18.  
  19. #ifdef MALLOC_DEBUG
  20. #include "rmalloc.h"
  21. #endif
  22.  
  23. #ifdef DMALLOC
  24. #include "dmalloc.h"
  25. #endif
  26.  
  27. int ShouldProcess = USUAL_PROCESSING;
  28. int SubmitFile;
  29.  
  30. static int LogError(int now, int prev, FILE * OutFILE, FILE * SelfMsgFILE,
  31.                     unsigned short *crc);
  32.  
  33. void
  34. ProcessFILES(int WorkMode, FILE * CfgFILE, FILE * OutFILE,
  35.              FILE * CommentsFILE, FILE * MergeOutFILE, unsigned short *crc)
  36. {
  37.     char *tmpptr;
  38.     int fieldno;
  39.     int searchwhere;
  40.     int mustbenew;
  41.     FILE *commFILE;
  42.     int subfile_level;
  43.     int num;
  44.     FILE *listFILE;
  45.     FILE *NotifyMsgFILE = 0;
  46.     int processstatus = 0;
  47.     char command[8];
  48.     char filename[MYMAXFILE + MYMAXEXT];
  49.     char notifyaddr[18];
  50.     char foundfile[MYMAXDIR];
  51.     char linebuf[linelength];
  52.     const char *const *subleveltxt;
  53.  
  54.     /* another function may have already closed the file... */
  55.  
  56.     if (feof(CfgFILE))
  57.     {
  58.         return;
  59.     }
  60.  
  61.     while (fgets(linebuf, linelength, CfgFILE) != NULL)
  62.     {
  63.         UsualMSGFlags = MailerFlags & (MF_ERRORS | MF_RECEIPT);
  64.         tmpptr = strchr(linebuf, ';');
  65.         if (tmpptr)
  66.             *tmpptr = 0;
  67.         if (*cutspaces(linebuf) == 0)
  68.             continue;
  69.         fieldno =
  70.             sscanf(linebuf, "%7s %d %12s %17s", command, &num, filename,
  71.                    notifyaddr);
  72.         strupr(command);
  73.         if (fieldno < 3)        /* "Net 2410 NET_2410" is minimum... */
  74.             die(255, 1,
  75.                 "%s\n -- Too few parameters -- Statement ignored\n",
  76.                 linebuf);
  77.         subfile_level = xlate_switch(command, MakeTypes);
  78.         if (MakeType >= subfile_level)
  79.             die(255, 1,
  80.                 "%s\n -- \"%s\" is invalid list type -- Statement ignored\n",
  81.                 linebuf, command);
  82.         if (subfile_level < LEVEL_HOST)
  83.         {
  84.             NotifyAddress[A_NET] = num;
  85.             NotifyAddress[A_NODE] = 0;
  86.         }
  87.         else if (MakeType <= LEVEL_HOST)
  88.         {
  89.             NotifyAddress[A_NET] = MakeNum;
  90.             NotifyAddress[A_NODE] = num;
  91.         }
  92.         else
  93.             UsualMSGFlags = 0;
  94.         if (fieldno >= 4)
  95.         {
  96.             if (ParseAddress(notifyaddr, NotifyAddress) != 0)
  97.                 die(255, 1, "Invalid NOTIFY address \"%s\" ignored\n",
  98.                     notifyaddr);
  99.             UsualMSGFlags = MailerFlags & (MF_ERRORS | MF_RECEIPT);
  100.         }
  101.         else
  102.             NotifyAddress[A_ZONE] = MyAddress[A_ZONE];
  103.         if (num < 0)
  104.             die(255, 1,
  105.                 "%s\n -- \"%d\" is invalid list number -- Statement ignored\n",
  106.                 linebuf, num);
  107.         subleveltxt = LevelsSimple + subfile_level;
  108.         searchwhere = 0;
  109.     foundfile[0] = '\0';
  110.         do
  111.         {
  112.             if (ShouldProcess == 0 && MergeOutFILE == 0) /* Process only
  113.                                                             new files */
  114.                 mustbenew = 1;
  115.             else
  116.                 mustbenew = 0;
  117.             searchwhere =
  118.                 openlist(&listFILE, filename, foundfile, searchwhere,
  119.                          mustbenew);
  120.             os_filecanonify(filename);
  121.             os_filecanonify(foundfile);
  122.             if (searchwhere > 0)
  123.             {
  124.                 fprintf(stdout, "Processing %-8s%5d -- file %s\n",
  125.                         *subleveltxt, num, foundfile);
  126.         mklog(1, "Processing %-8s%5d -- file %s", *subleveltxt, num, foundfile);
  127.                 if (UsualMSGFlags != 0 && searchwhere < SEARCH_UPDATE + 1) /* newly 
  128.                                                                               received 
  129.                                                                               file 
  130.                                                                             */
  131.                 {
  132.                     NotifyMsgFILE = OpenMSGFile(NotifyAddress, NULL);
  133.                     if (NotifyMsgFILE)
  134.                         fprintf(NotifyMsgFILE,
  135.                                 "Your nodelist update, %s, has been received",
  136.                                 WorkFile);
  137.                 }
  138.                 commFILE =
  139.                     (searchwhere ==
  140.                      SEARCH_MASTER + 1) ? NULL : CommentsFILE;
  141.                 processstatus =
  142.                     processfile(subfile_level, num, listFILE, OutFILE,
  143.                                 commFILE, MergeOutFILE, NotifyMsgFILE, crc,
  144.                                 &WorkMode);
  145.  
  146.         /* Segmentation fault cause is here, Andrew */
  147.  
  148.                 #ifndef __unix__
  149.                     fclose(listFILE);
  150.                 #endif
  151.                 if (processstatus != 2) /* No fatal error */
  152.                 {
  153.                     if (processstatus > ExitCode)
  154.                         ExitCode = processstatus;
  155.                     break;
  156.                 }
  157.                 ExitCode = processstatus;
  158.                 NotifyMsgFILE = CloseMSGFile(ExitCode);
  159.                 if (BadDir[0] != 0)
  160.                     CopyOrMove(0, foundfile, BadDir, WorkFile);
  161.                 else
  162.                     unlink(foundfile);
  163.             }
  164.         }
  165.         while (searchwhere > 0);
  166.         switch (searchwhere)
  167.         {
  168.         case 0:                /* not found */
  169.             if (!ShouldProcess)
  170.                 break;
  171.             fprintf(stdout, "No file found for %s %d file %s\n",
  172.                     LevelsSimple[subfile_level], num, filename);
  173.         mklog(1, "No file found for %s %d file %s",
  174.             LevelsSimple[subfile_level], num, filename);
  175.             break;
  176.         case SEARCH_UPLOAD + 1:
  177.             cleanold(MailfileDir, filename, NULL);
  178.             /* FALLTHROUGH */
  179.         case SEARCH_MAILFILE + 1:
  180.             CloseMSGFile(processstatus);
  181.             cleanold(UpdateDir, filename, NULL);
  182.             if (!ShouldProcess)
  183.             {
  184.                 CopyOrMove(0, foundfile, UpdateDir, filename);
  185.                 break;
  186.             }
  187.             CopyOrMove(0, foundfile, MasterDir, filename);
  188.             break;
  189.         case SEARCH_MASTER + 1:
  190.             if (!ShouldProcess)
  191.                 break;
  192.             if (getext(NULL, filename)) /* explicit name */
  193.                 break;
  194.             myfnmerge(linebuf, NULL, MasterDir, filename,
  195.                       OldExtensions[0]);
  196.             if (filecmp(foundfile, linebuf))
  197.                 rename(foundfile, linebuf); /* new extension */
  198.             cleanold(MasterDir, filename, OldExtensions[2]);
  199.             break;
  200.         case SEARCH_UPDATE + 1:
  201.             if (!ShouldProcess)
  202.                 break;
  203.             cleanold(MasterDir, filename, OldExtensions[2]);
  204.             CopyOrMove(0, foundfile, MasterDir, filename);
  205.         }
  206.     }
  207.  
  208.     fclose(CfgFILE);
  209. }
  210.  
  211. int
  212. processfile(int myMakeType, int myMakeNum, FILE * InputFILE,
  213.             FILE * OutFILE, FILE * FooFILE, FILE * MergeOutFILE,
  214.             FILE * SelfMsgFILE, unsigned short *OutCRC, int *WorkMode)
  215. {
  216.     long outpos = 0;
  217.     long mergeoutpos = 0;
  218.     int error = 0;
  219.     int level;
  220.     int num;
  221.     int contextlevel;
  222.     int contextnum;
  223.     int totalerror = 0;
  224.     unsigned short oldcrc;
  225.     static char InputLine[linelength];
  226.  
  227.     oldcrc = *OutCRC;
  228.     if (OutFILE)
  229.     {
  230.         outpos = ftell(OutFILE);
  231.         if (myMakeType < LEVEL_HUB)
  232.         {
  233.             *OutCRC = CRC16String(";\r\n", *OutCRC);
  234.             fputs(";\r\n", OutFILE);
  235.         }
  236.     }
  237.     if (MergeOutFILE)
  238.         mergeoutpos = ftell(MergeOutFILE);
  239.     if (FooFILE)
  240.         fprintf(FooFILE, "\nComments from %s:\n\n", WorkFile);
  241.     while (fgets(InputLine, linelength, InputFILE) != NULL)
  242.     {
  243.         error = ParseFTS5(InputLine, &level, &num);
  244.         if (level >= LEVEL_COMMENT)
  245.         {
  246.             if (level == LEVEL_COMMENT && FooFILE && InputLine[1] != 0)
  247.             {
  248.                 fputs(InputLine, FooFILE);
  249.                 putc('\n', FooFILE);
  250.             }
  251.         }
  252.         else
  253.         {
  254.             if (addnumber(myMakeType, myMakeNum, 1) != 0)
  255.                 error = 2;
  256.             contextlevel = level; /* Initialize the context level */
  257.             if (!error)
  258.                 error =
  259.                     UpdateContext(level, num, myMakeNum, &contextnum,
  260.                                   &contextlevel, myMakeType);
  261.             if (error)
  262.             {
  263.                 contextlevel = myMakeType;
  264.                 totalerror = LogError(2, 0, OutFILE, SelfMsgFILE, OutCRC);
  265.             }
  266.             if (OutFILE)
  267.                 OutputFTS5Line(OutFILE, "", "\r\n", OutCRC);
  268.             if (MergeOutFILE)
  269.                 OutputFTS5Line(MergeOutFILE, "", "\r\n", NULL);
  270.             break;
  271.         }
  272.     }
  273.     while (fgets(InputLine, linelength, InputFILE) != NULL)
  274.     {
  275.         error = ParseFTS5(InputLine, &level, &num);
  276.         if (error && *WorkMode == CFG_DATA
  277.             && !strncmp(FTS5Keyword, "FILES", 5))
  278.         {
  279.             *WorkMode = error = CFG_FILES;
  280.             break;
  281.         }
  282.         if (level < LEVEL_COMMENT)
  283.         {
  284.             if (!error)
  285.                 error =
  286.                     UpdateContext(level, num, 0, &contextnum,
  287.                                   &contextlevel, myMakeType);
  288.             if (!error)
  289.                 error = addnumber(level, num, 0);
  290.             if (error)
  291.             {
  292.                 totalerror =
  293.                     LogError(error, totalerror, OutFILE, SelfMsgFILE,
  294.                              OutCRC);
  295.                 continue;
  296.             }
  297.             if (OutFILE)
  298.             {
  299.                 if (level < LEVEL_HUB)
  300.                     /* Make it more readable - empty lines before NET,
  301.                        REGION and ZONE */
  302.                 {
  303.                     *OutCRC = CRC16String(";\r\n", *OutCRC);
  304.                     fputs(";\r\n", OutFILE);
  305.                 }
  306.                 OutputFTS5Line(OutFILE, "", "\r\n", OutCRC);
  307.             }
  308.             if (MergeOutFILE)
  309.             {
  310.                 if (level < LEVEL_HUB)
  311.                     /* Make it more readable - see above */
  312.                     fputs(";\r\n", MergeOutFILE);
  313.                 OutputFTS5Line(MergeOutFILE, "", "\r\n", NULL);
  314.             }
  315.         }
  316.         else if (level == LEVEL_COMMENT && InputLine[1] != 0)
  317.         {
  318.             if (FooFILE)
  319.             {
  320.                 fputs(InputLine, FooFILE);
  321.                 putc('\n', FooFILE);
  322.             }
  323.             if (InputLine[1] == 'E' && OutFILE) /* Pass through only
  324.                                                    errors */
  325.             {
  326.                 strcat(InputLine, "\r\n");
  327.                 *OutCRC = CRC16String(InputLine, *OutCRC);
  328.                 fputs(InputLine, OutFILE);
  329.             }
  330.         }
  331.     }
  332.     if (totalerror == 2)        /* 2 means fatal */
  333.     {
  334.         unmarkstack();          /* Throw away any numbers of this file */
  335.         sprintf(InputLine,
  336.                 "Fatal error(s) caused file \"%s\" to be rejected\r\n",
  337.                 WorkFile);
  338.         fputs(InputLine, stdout);
  339.         if (SelfMsgFILE)
  340.             fputs(InputLine, SelfMsgFILE);
  341.         *OutCRC = oldcrc;
  342.         if (OutFILE)
  343.             fseek(OutFILE, outpos, SEEK_SET);
  344.         if (MergeOutFILE)
  345.             fseek(MergeOutFILE, mergeoutpos, SEEK_SET);
  346.     }
  347.     else
  348.     {
  349.         if (OutFILE)
  350.             SubmitFile = 1;
  351.         if (MergeOutFILE && myMakeType < LEVEL_HUB)
  352.             fputs(";\r\n", MergeOutFILE);
  353.     }
  354.  
  355.     if (SelfMsgFILE && totalerror == 0)
  356.     {
  357.         fputs(" and processed without error.\r\n", SelfMsgFILE);
  358.     }
  359.     return totalerror;
  360. }
  361.  
  362. static int
  363. LogError(int now, int prev, FILE * OutFILE, FILE * SelfMsgFILE,
  364.          unsigned short *crc)
  365. {
  366.     OutputErrorLine(stdout, "", WorkFile, "\n", NULL);
  367.     if (OutFILE)
  368.         OutputErrorLine(OutFILE, ";E ", "", "\r\n", crc);
  369.     if (SelfMsgFILE)
  370.     {
  371.         if (prev == 0)          /* First Error */
  372.             fputs
  373.                 (".  Please correct the following errors and resubmit.\r\n\r\n",
  374.                  SelfMsgFILE);
  375.         OutputErrorLine(SelfMsgFILE, "", "", "\r\n", NULL);
  376.         fputs("\r\n", SelfMsgFILE);
  377.     }
  378.     return max(now, prev);
  379. }
  380.