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 / msgtool.c < prev    next >
C/C++ Source or Header  |  2005-02-06  |  10KB  |  336 lines

  1. /* $Id: msgtool.c,v 1.15 2004/09/13 14:37:09 ozzmosis Exp $ */
  2.  
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <time.h>
  7.  
  8. #include "makenl.h"
  9. #include "fts5.h"
  10. #include "msg.h"
  11. #include "fileutil.h"
  12. #include "mklog.h"
  13. #include "version.h"
  14.  
  15. #ifdef MALLOC_DEBUG
  16. #include "rmalloc.h"
  17. #endif
  18.  
  19. #ifdef DMALLOC
  20. #include "dmalloc.h"
  21. #endif
  22.  
  23. #define MSG_CRASH    0x0002
  24. #define MSG_PRIVATE  0x0001
  25. #define MSG_FILE     0x0010
  26. #define MSG_KILLSENT 0x0080
  27. #define MSG_LOCAL    0x0100
  28. #define MSG_HOLD     0x0400
  29.  
  30.  
  31.  
  32. int UsualMSGFlags;
  33. int MailerFlags;
  34. int NotifyAddress[3];
  35. int SubmitAddress[3];
  36. int MyAddress[3];
  37.  
  38. static int MSGnum;
  39. static FILE *MailFILE;
  40. static int MSGFlags;
  41. static unsigned char msgbuf[0xbe];
  42.  
  43.  
  44. static char *MakeMSGFilename(char *outbuf, int num);
  45.  
  46.  
  47.  
  48. /*
  49.  * Get unique sequence number
  50.  */
  51. static unsigned long GetSequence(void)
  52. {
  53.     unsigned long   seq;
  54.     char        seqfile[MYMAXDIR];
  55.     FILE        *fp;
  56.     sprintf(seqfile, "%s/sequence.dat", MasterDir);
  57.  
  58.     if ((fp = fopen(seqfile, "r+")) == NULL) {
  59.     seq = (unsigned long)time(NULL);
  60.     if ((fp = fopen(seqfile, "w+")) == NULL) {
  61.         fprintf(stderr, "Can't create %s\n", seqfile);
  62.         mklog(0, "Can't create %s", seqfile);
  63.         return seq;
  64.     } else {
  65.         fwrite(&seq, 1, sizeof(seq), fp);
  66.         fclose(fp);
  67.         return seq;
  68.     }
  69.     } else {
  70.     fread(&seq, 1, sizeof(seq), fp);
  71.     seq++;
  72.     fseek(fp, 0, SEEK_SET);
  73.     fwrite(&seq, 1, sizeof(seq), fp);
  74.     fclose(fp);
  75.     }
  76.     return seq;
  77. }
  78.  
  79.  
  80.  
  81. static int SearchMaxMSG(const char *path)
  82. {
  83.     char *filename;
  84.     int maxnum = 0;
  85.     int aktnum;
  86.     struct _filefind f;
  87.     char searchmask[MYMAXDIR];
  88.  
  89.     myfnmerge(searchmask, NULL, NULL, "*", "msg");
  90.     for (filename = os_findfirst(&f, path, searchmask);
  91.          filename != NULL; filename = os_findnext(&f))
  92.     {
  93.         getnumber(filename, &aktnum);
  94.         if (aktnum > maxnum)
  95.             maxnum = aktnum;
  96.     }
  97.     os_findclose(&f);
  98.  
  99.     mklog(4, "SearchMaxMSG: path=%s, result=%d", MAKE_SS(path), maxnum);
  100.     return maxnum;
  101. }
  102.  
  103.  
  104. int ParseAddress(const char *string, int out[3])
  105. {
  106.     char foo[2];
  107.     int temp[3];
  108.  
  109.     foo[0] = 0;
  110.     if (sscanf
  111.         (string, "%d:%d/%d%1s", &temp[A_ZONE], &temp[A_NET], &temp[A_NODE],
  112.          foo) == 3)
  113.     {
  114.         if (foo[0] != 0 || temp[A_ZONE] == 0 || temp[A_NET] == 0)
  115.             return -1;
  116.     }
  117.     else if (sscanf(string, "%d/%d%1s", &temp[A_NET], &temp[A_NODE], foo)
  118.              == 2)
  119.     {
  120.         temp[A_ZONE] = 0;
  121.         if (foo[0] != 0)
  122.             return -1;
  123.         if (temp[A_NET] == 0)
  124.             return -1;
  125.     }
  126.     else if (sscanf(string, "%d%1s", &temp[A_NODE], foo) != 0)
  127.     {
  128.         if (foo[0] != 0)
  129.             return -1;
  130.         temp[A_NET] = 0;
  131.         temp[A_ZONE] = 0;
  132.     }
  133.     else
  134.         return -1;
  135.     memcpy(out, temp, 3 * sizeof(int));
  136.  
  137.     return 0;
  138. }
  139.  
  140.  
  141.  
  142. FILE *OpenMSGFile(int adress[3], char *filename)
  143. {
  144.     static char *DOWNames[] =
  145.         { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
  146.     static char *MonthNames[12] =
  147.         { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
  148.           "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  149.     time_t akt_time;
  150.     struct tm *the_time;
  151.     char intlline[46];
  152.     char filenamebuf[MYMAXDIR], subject[72], date[21];
  153.     int intl, temp;
  154.  
  155.     MSGnum = SearchMaxMSG(MessageDir);
  156.     mklog(4, "OpenMSGFile: MSGnum is set to %d", MSGnum);
  157.  
  158.     mklog(3, "OpenMSGFile: %d:%d/%d filename=%s", adress[A_ZONE], 
  159.         adress[A_NET], adress[A_NODE], MAKE_SS(filename));
  160.     memset(&filenamebuf, 0, sizeof(filenamebuf));
  161.     memset(&msgbuf, 0, sizeof(msgbuf));
  162.  
  163.     memcpy(&msgbuf[0x00], (char *)"MakeNL ", 7);
  164.     memcpy(&msgbuf[0x07], MAKENL_VERSION, sizeof(MAKENL_VERSION));
  165.     memcpy(&msgbuf[0x24], (char *)"Coordinator", 11);
  166.  
  167.     if (filename)
  168.     {
  169.     sprintf(subject, "%s", filename);
  170.         MSGFlags = (MailerFlags & MF_SUBMIT) >> MF_SHIFT_SUBMIT;
  171.         temp = (MSGFlags & MF_CRASH ? MSG_CRASH : 0) |
  172.             (MSGFlags & MF_HOLD ? MSG_HOLD : 0) |
  173.             MSG_PRIVATE | MSG_FILE | MSG_KILLSENT | MSG_LOCAL;
  174.     }
  175.     else
  176.     {
  177.         temp = MSG_PRIVATE | MSG_KILLSENT | MSG_LOCAL;
  178.         sprintf(subject, "%s received", WorkFile);
  179.         MSGFlags = UsualMSGFlags;
  180.     }
  181.     memcpy(&msgbuf[0x48], subject, strlen(subject));
  182.  
  183.     time(&akt_time);
  184.     the_time = localtime(&akt_time);
  185.     /* BUG FIXED: Y2K-bug changed tm_year to tm_year % 100 and its format
  186.      *        to %02d */
  187.     sprintf(date, "%s %2d %s %02d %02d:%02d",
  188.         DOWNames[the_time->tm_wday], the_time->tm_mday,
  189.         MonthNames[the_time->tm_mon], the_time->tm_year % 100,
  190.         the_time->tm_hour, the_time->tm_min);
  191.     memcpy(&msgbuf[0x90], date, 20);
  192.     msgbuf[0xba] = (temp & 0x00ff);     /* Atribute */
  193.     msgbuf[0xbb] = (temp & 0xff00) >> 8;
  194.  
  195.     if (!MSGFlags)
  196.         return (MailFILE = NULL);
  197.     if (!adress[A_ZONE])
  198.         adress[A_ZONE] = MyAddress[A_ZONE];
  199.     if (MyAddress[A_ZONE] == adress[A_ZONE])
  200.     {
  201.         intlline[0] = 0;
  202.     msgbuf[0xae] = (adress[A_NET] & 0x00ff);    /* destNet    */
  203.     msgbuf[0xaf] = (adress[A_NET] & 0xff00) >> 8;
  204.     msgbuf[0xa6] = (adress[A_NODE] & 0x00ff);    /* destNode    */
  205.     msgbuf[0xa7] = (adress[A_NODE] & 0xff00) >> 8;
  206.     msgbuf[0xb0] = (adress[A_ZONE] & 0x00ff);    /* destZone    */
  207.     msgbuf[0xb1] = (adress[A_ZONE] & 0xff00) >> 8;
  208.         intl = MailerFlags & (MF_INTL |
  209.                               (MF_INTL << MF_SHIFT_ERRORS) |
  210.                               (MF_INTL << MF_SHIFT_SUBMIT));
  211.     }
  212.     else
  213.     {
  214.     msgbuf[0xae] = (MyAddress[A_ZONE] & 0x00ff);    /* destNet    */
  215.     msgbuf[0xaf] = (MyAddress[A_ZONE] & 0xff00) >> 8;
  216.     msgbuf[0xa6] = (adress[A_ZONE] & 0x00ff);    /* destNode    */
  217.     msgbuf[0xa7] = (adress[A_ZONE] & 0xff00) >> 8;
  218.     msgbuf[0xb0] = (MyAddress[A_ZONE] & 0x00ff);    /* destZone    */
  219.     msgbuf[0xb1] = (MyAddress[A_ZONE] & 0xff00) >> 8;
  220.         intl = 1;
  221.     }
  222.  
  223.     msgbuf[0xa8] = (MyAddress[A_NODE] & 0x00ff);    /* origNode    */
  224.     msgbuf[0xa9] = (MyAddress[A_NODE] & 0xff00) >> 8;
  225.     msgbuf[0xac] = (MyAddress[A_NET] & 0x00ff);        /* origNet    */
  226.     msgbuf[0xad] = (MyAddress[A_NET] & 0xff00) >> 8;
  227.     msgbuf[0xb2] = (MyAddress[A_ZONE] & 0x00ff);    /* origZone    */
  228.     msgbuf[0xb3] = (MyAddress[A_ZONE] & 0xff00) >> 8;
  229.     
  230.     if (intl)
  231.     {
  232.         if (MyAddress[A_ZONE] == 0)
  233.         {
  234.             fprintf(stdout,
  235.                     "\nWARNING -- Don't know your zone, can't send interzone message to %d:%d/%d\n\n",
  236.                     adress[A_ZONE], adress[A_NET], adress[A_NODE]);
  237.         mklog(1, "WARNING -- Don't know your zone, can't send interzone message to %d:%d/%d",
  238.             adress[A_ZONE], adress[A_NET], adress[A_NODE]);
  239.             return (MailFILE = NULL);
  240.         }
  241.         sprintf(intlline, "\x01INTL %d:%d/%d %d:%d/%d\r\n", adress[A_ZONE],
  242.                 adress[A_NET], adress[A_NODE], MyAddress[A_ZONE],
  243.                 MyAddress[A_NET], MyAddress[A_NODE]);
  244.     }
  245.     MailFILE = fopen(MakeMSGFilename(filenamebuf, MSGnum + 1), "wb");
  246.     if (!MailFILE)
  247.         die(254, 1, "Cannot create %s", filenamebuf);
  248.     MSGnum++;
  249.     mklog(3, "OpenMSGFile: opened %s, MSGnum %d", filenamebuf, MSGnum);
  250.     
  251.     fwrite(&msgbuf, sizeof(msgbuf), 1, MailFILE);
  252.     fputs(intlline, MailFILE);
  253.     fprintf(MailFILE, "\x01MSGID: %d:%d/%d %08lx\r\n", MyAddress[A_ZONE], 
  254.         MyAddress[A_NET], MyAddress[A_NODE], GetSequence());
  255.     if (!filename)
  256.     {
  257.     mklog(4, "OpenMSGFile: return with open MailFILE");
  258.         return MailFILE;
  259.     }
  260.     fclose(MailFILE);
  261.     mklog(4, "OpenMSGFile: closed, seems Ok");
  262.     return (FILE *) ! NULL;     /* Just say OK - but it *smells* */
  263. }
  264.  
  265.  
  266.  
  267. FILE *CloseMSGFile(int status)
  268. {
  269.     char filename[MYMAXDIR];
  270.     int    i, temp = 0;
  271.  
  272.     mklog(3, "CloseMSGFile: status=%d", status);
  273.  
  274.     if (MailFILE != NULL)
  275.     {
  276.     mklog(4, "CloseMSGFile: MailFILE is open");
  277.         if (status >= 0)
  278.         {
  279.             if (status != 0)
  280.             {
  281.                 MSGFlags >>= MF_SHIFT_ERRORS;    /* Use the error flags        */
  282.         for (i = 0x48; i; i++)        /* Search end of subject    */
  283.         {
  284.             if (msgbuf[i] == '\0')
  285.             {
  286.             break;
  287.             }
  288.         }
  289.                 memcpy(&msgbuf[i], " with errors", 12);
  290.             }
  291.             else
  292.         {
  293.                 MSGFlags &= MF_RECEIPT;
  294.         }
  295.             if (MSGFlags)
  296.             {
  297.         mklog(4, "CloseMSGFile: MSGFlags != 0");
  298.                 putc(0, MailFILE);
  299.                 fseek(MailFILE, 0L, SEEK_SET);
  300.                 temp |=
  301.                     (MSGFlags & MF_CRASH ? MSG_CRASH : 0) | (MSGFlags &
  302.                                                              MF_HOLD ?
  303.                                                              MSG_HOLD : 0);
  304.         msgbuf[0xba] = (temp & 0x00ff);     /* Atribute */
  305.         msgbuf[0xbb] = (temp & 0xff00) >> 8;
  306.                 fwrite(&msgbuf, sizeof(msgbuf), 1, MailFILE);
  307.             }
  308.             else
  309.                 status = -1;
  310.         }
  311.     mklog(4, "CloseMSGFile: closing file, status is now %d, MSGnum=%d", status, MSGnum);
  312.         fclose(MailFILE);
  313.         if (status < 0)
  314.     {
  315.             unlink(MakeMSGFilename(filename, MSGnum--));
  316.         mklog(3, "CloseMSGFile: unlink %s", filename);
  317.     }
  318.     }
  319.     mklog(4, "CloseMSGFile: MSGnum=%d", MSGnum);
  320.     MailFILE = NULL;
  321.     return MailFILE;
  322. }
  323.  
  324.  
  325.  
  326. char *MakeMSGFilename(char *outbuf, int num)
  327. {
  328.     char buffer[6];
  329.  
  330.     sprintf(buffer, "%u", num);
  331.     myfnmerge(outbuf, NULL, MessageDir, buffer, "msg");
  332.     mklog(4, "MakeMSGFilenam: num=%d MSGnum=%d", num, MSGnum);
  333.     return outbuf;
  334. }
  335.  
  336.