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 / makenl.c < prev    next >
C/C++ Source or Header  |  2005-02-06  |  11KB  |  326 lines

  1. /* $Id: makenl.c,v 1.28 2004/09/08 18:47:51 mbroek Exp $ */
  2.  
  3. #include <stdio.h>
  4. #include <time.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <stdarg.h>
  8.  
  9. #include "makenl.h"
  10. #include "config.h"
  11. #include "fts5.h"
  12. #include "lsttool.h"
  13. #include "fileutil.h"
  14. #include "merge.h"
  15. #include "msg.h"
  16. #include "proc.h"
  17. #include "crc16.h"
  18. #include "version.h"
  19. #include "unused.h"
  20. #include "mklog.h"
  21.  
  22. #ifdef MALLOC_DEBUG
  23. #include "rmalloc.h"
  24. #endif
  25.  
  26. #ifdef DMALLOC
  27. #include "dmalloc.h"
  28. #endif
  29.  
  30. #if defined(__MSDOS__) && defined(__TURBOC__)
  31. extern unsigned _stklen = 16384;
  32. #endif
  33.  
  34. const char *const DOWLongnames[7] =
  35.     { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
  36.     "Saturday"
  37. };
  38. const char *const MonthLongnames[12] =
  39.     { "January", "February", "March", "April",
  40.     "May", "June", "July", "August", "September",
  41.     "October", "November", "December"
  42. };
  43.  
  44. int NewExtWDay = 6;
  45.  
  46. int MakeType = -1;
  47. int MakeNum;
  48.  
  49. int ExitCode;
  50. int JustTest;
  51.  
  52. int MakenlDebug = 0;            /* 1 - Debugs some code here... */
  53.  
  54. char *WorkFile = NULL;
  55.  
  56. static FILE *CFG_file;
  57. static FILE *MakeSourceFILE;
  58. static char YearBuf[6];
  59. static char NewFile[MYMAXPATH];
  60. static char OutExt[MYMAXEXT];
  61. static char CfgFilenameBuf[MYMAXPATH];
  62. static char HeaderLine[linelength];
  63. static char SubAddrText[20];
  64. int WorkMode;
  65. static int OldWeeks;
  66. static struct tm *SplitTimePtr;
  67. static time_t UnixTime;
  68. static FILE *OutFILE;
  69. static FILE *CommentsFILE;
  70. static FILE *SelfMsgFILE;
  71. static FILE *mainMergeOut;
  72. static char *CfgFile = "makenl.ctl";
  73. static unsigned short OutCRC;
  74.  
  75. /* Looks for the last day with (dow == weekday) before now.
  76.    The returned time is offset days apart from the found day.
  77.    The wall-clock-time of the returned time equals the wall-clock-
  78.    time of now. If the dayligth-saving-time-flag does not change,
  79.    the returned time is a multiple of 24 hours away */
  80. static time_t searchdow(int weekday, int offset, struct tm **timebuf)
  81. {
  82.     time_t temp;
  83.     struct tm *thetime;
  84.     int isdst;
  85.  
  86.     time(&temp);
  87.     thetime = localtime(&temp); /* Get the time */
  88.     isdst = thetime->tm_isdst;
  89.     weekday = weekday - thetime->tm_wday; /* How many days are before the
  90.                                              wanted day? */
  91.     if (weekday > 0)            /* We don't want to look into future - */
  92.         weekday -= 7;           /* - go one week back */
  93.     temp += 3600L * 24 * (offset + weekday); /* Jump to the required day */
  94.     thetime = localtime(&temp);
  95.     temp += 3600 * (isdst - thetime->tm_isdst); /* Do daylight corrections 
  96.                                                  */
  97.     if (timebuf)
  98.         *timebuf = localtime(&temp);
  99.     return temp;
  100. }
  101.  
  102. void die(int exitcode, int on_stderr, const char *format, ...)
  103. {
  104.     char buf[1024], exitstr[50];
  105.     va_list arg;
  106.     
  107.     va_start(arg, format);
  108.     vsprintf(buf, format, arg);
  109.     va_end(arg);
  110.  
  111.     *exitstr = '\0';
  112.  
  113.     if (exitcode != 0)
  114.     {
  115.         sprintf(exitstr, "(rc=%d) ", exitcode);
  116.     }
  117.  
  118.     fprintf(
  119.       on_stderr ? stderr : stdout,
  120.       "%s%s%s\n",
  121.       exitcode == 0 ? "" : "ABORT -- ",
  122.       exitstr,
  123.       buf
  124.     );
  125.  
  126.     mklog(on_stderr ? 0 : 1, "%s", buf);
  127.     mklog(1, "MakeNL finished (rc=%d)", exitcode);
  128.  
  129.     exit(exitcode);
  130. }
  131.  
  132. static void showversion(void)
  133. {
  134.     fprintf(stderr,
  135.       "\nMakeNL " MAKENL_VERSION "  Compiled on " __DATE__ " " __TIME__ "\n\n" MAKENL_DEDICATION "\n");
  136. }
  137.  
  138. int main(int argc, char *argv[])
  139. {
  140.     unused(argc);
  141.  
  142.     showversion();
  143.  
  144.     DoCmdLine(argv, &CfgFile);
  145.     if (!getext(NULL, CfgFile))
  146.     {
  147.         swapext(CfgFilenameBuf, CfgFile, "ctl");
  148.         CfgFile = CfgFilenameBuf;
  149.     }
  150.     CFG_file = fopen(CfgFile, "r");
  151.     die_if_file(CFG_file, CfgFile, 0);
  152.     WorkFile = strdup(CfgFile);
  153.     os_filecanonify(WorkFile);
  154.     os_getcwd(CurDir, MYMAXDIR - 1);
  155.     os_filecanonify(CurDir);
  156.     WorkMode = parsecfgfile(CFG_file);
  157.     mklog(1, "Using %s in %s", CfgFile, CurDir);
  158.  
  159.     for (OldWeeks = 3; OldWeeks >= 0; OldWeeks--)
  160.     {
  161.         searchdow(NewExtWDay, -7 * OldWeeks + 6, &SplitTimePtr);
  162.         sprintf(OldExtensions[OldWeeks], "%03d",
  163.                 SplitTimePtr->tm_yday + 1);
  164.     }
  165.     sprintf(YearBuf, "%d", 1900 + SplitTimePtr->tm_year);
  166.     sprintf(HeaderLine,
  167.             ";A %s Nodelist for %s, %s %d, %s -- Day number %s : ",
  168.             Levels[MakeType], DOWLongnames[SplitTimePtr->tm_wday],
  169.             MonthLongnames[SplitTimePtr->tm_mon], SplitTimePtr->tm_mday,
  170.             YearBuf, OldExtensions[0]);
  171.     time(&UnixTime);
  172.     SplitTimePtr = localtime(&UnixTime);
  173.     printf("Begin processing %s -- %d:%02d, %s, %s %d, %d\n\n", OutFile,
  174.            SplitTimePtr->tm_hour, SplitTimePtr->tm_min,
  175.            DOWLongnames[SplitTimePtr->tm_wday],
  176.            MonthLongnames[SplitTimePtr->tm_mon], SplitTimePtr->tm_mday,
  177.            SplitTimePtr->tm_year + 1900);
  178.     mklog(1, "Begin processing %s -- %d:%02d, %s, %s %d, %d", OutFile,
  179.         SplitTimePtr->tm_hour, SplitTimePtr->tm_min,
  180.         DOWLongnames[SplitTimePtr->tm_wday],
  181.         MonthLongnames[SplitTimePtr->tm_mon], SplitTimePtr->tm_mday,
  182.         SplitTimePtr->tm_year + 1900);
  183.     if (ShouldProcess)
  184.     {
  185.         myfnmerge(NewFile, NULL, OutDir, OutFile, NULL);
  186.     mklog(4, "main: shouldprocess %s", NewFile);
  187.         swapext(NewFile, NewFile, "$$$");
  188.         OutFILE = fopen(NewFile, "wb");
  189.         die_if_file(OutFILE, NewFile, 1);
  190.         fprintf(OutFILE, "%s%05u\r\n", HeaderLine, OutCRC);
  191.         CopyrightLines =
  192.             CopyComment(OutFILE, CopyrightFile, YearBuf, &OutCRC);
  193.         CopyComment(OutFILE, PrologFile, NULL, &OutCRC);
  194.     }
  195.     if (CommentsFile[0] != 0)
  196.     {
  197.         if (!filecmp(CommentsFile, "STDOUT"))
  198.             CommentsFILE = stdout;
  199.         else if (!filecmp(CommentsFile, "STDERR"))
  200.             CommentsFILE = stderr;
  201.         else
  202.         {
  203.             CommentsFILE = fopen(CommentsFile, "w");
  204.             die_if_file(CommentsFILE, CommentsFile, 1);
  205.         }
  206.     }
  207.     mainMergeOut = PrepareMerge();
  208.     if (!JustTest && MailerFlags & MF_SELF)
  209.     {
  210.         /* That means: Do a mailing if errors occur */
  211.         UsualMSGFlags = MF_DOIT << MF_SHIFT_ERRORS;
  212.         SelfMsgFILE = OpenMSGFile(MyAddress, NULL);
  213.     }
  214.     if (WorkMode == CFG_DATA)
  215.         ExitCode =
  216.             processfile(MakeType, MakeNum, CFG_file, OutFILE, NULL,
  217.                         mainMergeOut, SelfMsgFILE, &OutCRC, &WorkMode);
  218.     else if (MakeSourceFile[0] != 0)
  219.     {
  220.         myfnmerge(CfgFilenameBuf, NULL, MasterDir, MakeSourceFile, NULL);
  221.         MakeSourceFILE = fopen(CfgFilenameBuf, "r");
  222.         die_if_file(MakeSourceFILE, CfgFilenameBuf, 0);
  223.         ExitCode = processfile(MakeType, MakeNum, MakeSourceFILE, OutFILE, NULL,
  224.           mainMergeOut, SelfMsgFILE, &OutCRC, &WorkMode);
  225.         fclose(MakeSourceFILE);
  226.     }
  227.     SelfMsgFILE = CloseMSGFile(ExitCode);
  228.     if (ExitCode > 1)
  229.         die(255, 1, "Fatal error in %s", WorkFile);
  230.     ProcessFILES(WorkMode, CFG_file, OutFILE, CommentsFILE, mainMergeOut,
  231.                  &OutCRC);
  232.     FinishMerge();
  233.     if (ShouldProcess)
  234.     {
  235.         CopyComment(OutFILE, EpilogFile, NULL, &OutCRC);
  236.         OutCRC = CRC16DoByte(0, CRC16DoByte(0, OutCRC));
  237.         putc('\x1A', OutFILE);
  238.         fseek(OutFILE, 0L, SEEK_SET);
  239.         fprintf(OutFILE, "%s%05u\r\n", HeaderLine, OutCRC);
  240.         fclose(OutFILE);
  241.         WorkMode = 0;
  242.         if (installlist(NewFile, OutExt) == 0) /* List changed */
  243.         {
  244.             char cmdbuf[1024];  /* space for CalledBatchfile */
  245.  
  246.             sprintf(cmdbuf, "%s %s" STR_DIRSEPARATOR "%s ",
  247.                     CalledBatchFile, OutDir, OutFile);
  248.             WorkMode = 0;       /* Why that?! see three lines above! */
  249.             if (OutExt[0] == 0) /* If output is generic, we could diff and 
  250.                                    ARC */
  251.             {
  252.                 cleanold(OutDir, OutFile, OldExtensions[2]);
  253.                 WorkMode = makediff(NewFile);
  254.                 makearc(NewFile, 0);
  255.                 if (WorkMode & CAUSE_OUTDIFF)
  256.                 {
  257.                     sprintf(cmdbuf + strlen(cmdbuf),
  258.                             "%s" STR_DIRSEPARATOR "%s ", OutDir, OutDiff);
  259.                     myfnmerge(CfgFilenameBuf, NULL, OutDir, OutDiff,
  260.                               OldExtensions[0]);
  261.                     makearc(CfgFilenameBuf, 1);
  262.                     if (WorkMode & CAUSE_THRESHOLD)
  263.                     {
  264.                         myfnmerge(CfgFilenameBuf, NULL, OutDir, OutFile,
  265.                                   OldExtensions[0]);
  266.                         makearc(CfgFilenameBuf, 0);
  267.                     }
  268.                 }
  269.                 else
  270.                     strcat(cmdbuf, "no-diff ");
  271.             }
  272.             else
  273.         {
  274.                 strcat(cmdbuf, "no-diff ");
  275.         /*
  276.          * New feature: compress hub and host segments.
  277.          * Added in 2004 when file size doesn't matter anymore.
  278.          */
  279.         myfnmerge(CfgFilenameBuf, NULL, OutDir, OutFile, NULL);
  280.         makearc(CfgFilenameBuf, 1);
  281.         strcpy(NewFile, CfgFilenameBuf);
  282.         mklog(4, "main: NewFile \"%s\"", MAKE_SS(NewFile));
  283.         }
  284.  
  285.             sprintf(cmdbuf + strlen(cmdbuf), "%c %c %c %c %c %c\n",
  286.                     OldExtensions[0][0], OldExtensions[0][1],
  287.                     OldExtensions[0][2], OldExtensions[1][0],
  288.                     OldExtensions[1][1], OldExtensions[1][2]);
  289.             if (SubmitFile && BatchFile[0])
  290.             {
  291.                 FILE *fp = fopen(BatchFile, "w");
  292.  
  293.                 if (fp)
  294.                 {
  295.                     fputs(os_deslashify(cmdbuf), fp);
  296.                     fclose(fp);
  297.                 }
  298.             }
  299.  
  300.             os_filecanonify(NewFile);
  301.             if (MailerFlags & MF_SUBMIT && SubmitFile
  302.                 && OpenMSGFile(SubmitAddress, NewFile))
  303.             {
  304.                 if (MyAddress[A_ZONE] == SubmitAddress[A_ZONE])
  305.                     sprintf(SubAddrText, "%d/%d", SubmitAddress[A_NET],
  306.                             SubmitAddress[A_NODE]);
  307.                 else
  308.                     sprintf(SubAddrText, "%d:%d/%d", SubmitAddress[A_ZONE],
  309.                             SubmitAddress[A_NET], SubmitAddress[A_NODE]);
  310.                 fprintf(stdout, "\nSending \"%s\" to %s\n", NewFile,
  311.                         SubAddrText);
  312.         mklog(1, "Sending \"%s\" to %s", NewFile, SubAddrText);
  313.             }
  314.         }
  315.         cleanit();
  316.     }
  317.     else
  318.         ExitCode += 3;
  319.     fprintf(stdout, "\nCRC = %05u\n\n", OutCRC);
  320.  
  321.     mklog(1, "CRC = %05u", OutCRC);
  322.     mklog(1, "MakeNL finished (rc=%d)", ExitCode);
  323.  
  324.     return ExitCode;
  325. }
  326.