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

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