home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / BBS / NETMAIL / MSGD2SRC.ZIP / READMAIL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-06  |  13.1 KB  |  631 lines

  1. /*
  2.  
  3. Title:  MsgEd
  4.  
  5. File:   readmail.c
  6.  
  7. Author: Jim Nutt
  8.  
  9. Copr:    released into the PUBLIC DOMAIN 30 Jul 1990 by jim nutt
  10.  
  11. Description:
  12.  
  13.     handles high level message i/o
  14.  
  15. */
  16.  
  17. #ifdef __MSC__
  18. #include <sys\types.h>
  19. #endif
  20.  
  21. #ifdef __OS2__
  22. #define INCL_DOSFILEMGR
  23. #include <fcntl.h>
  24. #endif
  25.  
  26. #if defined(__TURBOC__)
  27. #include <dir.h>
  28. #else
  29. #include <direct.h>
  30. #endif
  31. #include <sys\stat.h>
  32. #include <dos.h>
  33.  
  34. #include "msged.h"
  35. #include "date.h"
  36. #include "bmg.h"
  37.  
  38. int _pascal setcwd(char *path);
  39.  
  40. #define TEXTLEN 96
  41.  
  42. #define ASM
  43.  
  44. static int count;
  45.  
  46. void _pascal normalize(char *s);
  47. int  _pascal wrap(LINE *cl, int x, int y);
  48. static void _pascal checkrecvd(MSG * m);
  49.  
  50. #ifdef __OS2__
  51. extern unsigned short _pascal far DosSelectDisk(unsigned short);
  52. #endif
  53.  
  54. LINE * _pascal clearbuffer(LINE *buffer)
  55.  
  56. {
  57.     LINE *curline;
  58.     
  59.     if ((curline = buffer) != NULL) {
  60.  
  61.         while (curline->next != NULL) {
  62.             curline = curline->next;
  63.             if (curline->prev == NULL)
  64.                 continue;
  65.             if (curline->prev->text != NULL)
  66.                 free(curline->prev->text);
  67.                         curline->prev->next = NULL;
  68.                         free(curline->prev);
  69.                         curline->prev = NULL;
  70.         }
  71.  
  72.         if (curline != NULL) {
  73.             if (curline->text)
  74.                 free(curline->text);
  75.  
  76.             curline->text = NULL;
  77.             free(curline);
  78.             curline = NULL;
  79.         }
  80.     }
  81.     return NULL;
  82. }
  83.  
  84. MSG  * _pascal readmsg(int n)
  85.  
  86. {
  87.     MSG  *m;
  88.     char *text;
  89.     LINE *l = NULL;
  90.     int  af = 0;
  91.     int  dmn = 0;
  92.     char *t;
  93.     char tmp[128];
  94.     int  i,j;
  95.     int  blank = 0;
  96.  
  97.     if ((m = msg_readheader(n)) == NULL)
  98.         return(NULL);
  99.  
  100.     m->new = 0;
  101.     m->change = 0;
  102.  
  103.     while ((text = msg_readtext(n)) != NULL) {
  104.  
  105.         if (*text == '\n') blank = 1;
  106.  
  107.         if ((*text == '\01') && !blank) {
  108.             char *s = NULL;
  109.  
  110.             switch (*(text+1)) {
  111.                 case 'M' :
  112.                     if ((s=strchr(text,':')) != NULL) {
  113.                         s++;
  114.                         while (isspace(*s)) s++;
  115.                         m->msgid = strdup(s);
  116.                         if (strchr(m->msgid,'\n'))
  117.                             *strchr(m->msgid,'\n') = '\0';
  118.                         m->from = parsenode(s);
  119.                         if (!m->from.notfound)
  120.                             af = 1;
  121.                     }
  122.                     break;
  123.  
  124.                 case 'R' :
  125.                     if ((s=strchr(text,':')) != NULL) {
  126.                         s++;
  127.                         while (isspace(*s)) s++;
  128.                         m->reply = strdup(s);
  129.                         if (strchr(m->reply,'\n'))
  130.                             *strchr(m->reply,'\n') = '\0';
  131.                     }
  132.                     break;
  133.  
  134.                 case 'F' :
  135.                     if (!af && ((s=strchr(text,' ')) != NULL))
  136.                         m->from.point = atoi(s+1);
  137.                     break;
  138.  
  139.                 case 'T' :
  140.                     if ((s=strchr(text,' ')) != NULL)
  141.                         m->to.point = atoi(s+1);
  142.                     break;
  143.  
  144.                 case 'D' :
  145.                     if ((s=strchr(text,' ')) != NULL) {
  146.                         dmn = 1;
  147.                         i = m->to.point;
  148.                         j = m->from.point;
  149.                         while(isspace(*s)) s++;
  150.                         i = 0;
  151.                         while(!isspace(*s) && (i < 8))
  152.                             tmp[i++] = *s++;
  153.                         tmp[i] = '\0';
  154.                         while (!isspace(*s)) s++;
  155.                         while(isspace(*s)) s++;
  156.                         m->to = parsenode(s);
  157.                         m->to.domain = strdup(strupr(tmp));
  158.                         if (!af) {
  159.                             while (!isspace(*s)) s++;
  160.                             while(isspace(*s)) s++;
  161.                             i = 0;
  162.                             while(!isspace(*s) && (i < 8))
  163.                                 tmp[i++] = *s++;
  164.                             tmp[i] = '\0';
  165.                             while (!isspace(*s)) s++;
  166.                             while(isspace(*s)) s++;
  167.                             m->from = parsenode(s);
  168.                             m->from.domain = strdup(strupr(tmp));
  169.                             m->from.point = j;
  170.                             m->to.point = i;
  171.                         }
  172.                     }
  173.                     break;
  174.  
  175.                 case 'I' :
  176.                     if (((s=strchr(text,' ')) != NULL) && !dmn) {
  177.                         i = m->to.point;
  178.                         j = m->from.point;
  179.                         strcpy(tmp,s+1);
  180.                         m->to = parsenode(strtok(tmp," "));
  181.                         if (!af) {
  182.                             m->from = parsenode(strtok(NULL," \n\r\0"));
  183.                             m->from.point = j;
  184.                             m->to.point = i;
  185.                         }
  186.                     }
  187.                     break;
  188.             }
  189.  
  190.             if (!shownotes)
  191.                 continue;
  192.         }
  193.  
  194.         if (arealist[area].echomail) {
  195.             if (*text == 'S') {
  196.                 if ((strncmp(text,"SEEN-BY:",8) == 0) && (!seenbys)) {
  197.                     free(text);
  198.                     continue;
  199.                 }
  200.             }
  201.             else if (!af && (*(text+1) == '*')) {
  202.                 if (*(text+3) == 'O') { /* probably the origin line */
  203.                     char *t = strrchr(text,'(');
  204.                     if (t != NULL) {
  205.                         while (!isdigit(*t) && (*t != ')')) t++;
  206.                         if (isdigit(*t))
  207.                             m->from = parsenode(t);
  208.                     }
  209.                     else
  210.                         m->from.notfound = 1;
  211.                 }
  212.             }
  213.         }
  214.  
  215.         if ((arealist[area].uucp || arealist[area].news) && !blank) {
  216.             char *s;
  217.  
  218.             if (arealist[area].uucp) {
  219.                 if (strncmp(text,"To:",3) == 0) {
  220.                     s = strchr(text,' ');
  221.                     m->to.fidonet = 0;
  222.                     m->to.internet = 0;
  223.                     m->to.bangpath = 0;
  224.                     m->to.notfound = 0;
  225.                     while (isspace(*s)) s++;
  226.                     if (strchr(s,'@') != NULL)
  227.                         m->to.internet = 1;
  228.                     else
  229.                         m->to.bangpath = 1;
  230.                     m->to.domain = strdup(s);
  231.                     if (!shownotes) continue;
  232.                 }
  233.             }
  234.  
  235.             if (strncmp(text,"From:",5) == 0) {
  236.                 s = strrchr(text,'(');
  237.                 if (s == NULL) {
  238.                     if (m->isfrom) free(m->isfrom);
  239.                     m->isfrom = strdup("UUCP");
  240.                 }
  241.                 else {
  242.                     *s = '\0';
  243.                     if ((t = strrchr(s+1,')')) != NULL)
  244.                         *t = '\0';
  245.                     m->isfrom = strdup(s+1);
  246.                 }
  247.                 s = strchr(text,' ') + 1;
  248.                 m->from.fidonet = 0;
  249.                 m->from.internet = 0;
  250.                 m->from.bangpath = 0;
  251.                 m->from.notfound = 0;
  252.                 while (isspace(*s)) s++;
  253.                 if (strchr(s,'@') != NULL)
  254.                     m->from.internet = 1;
  255.                 else
  256.                     m->from.bangpath = 1;
  257.                 m->from.domain = strdup(s);
  258.                 if (!shownotes) continue;
  259.             }
  260.  
  261.             if (strncmp(text,"Date:",5) == 0) {
  262.                 s = strchr(text,' ');
  263.                 if (s != NULL) {
  264.                     while (isspace(*s)) s++;
  265.                     m->timestamp = parsedate(s);
  266.                 }
  267.                 if (!shownotes) continue;
  268.             }
  269.         }
  270.  
  271.         if ((*text != '\01') || shownotes) {
  272.  
  273.             if (l == NULL) {
  274.                 l = (LINE *) malloc(sizeof(LINE));
  275.                     m->text = l;
  276.                 l->next = l->prev = NULL;
  277.                 }
  278.                 else {
  279.                 l->next = (LINE *) malloc(sizeof(LINE));
  280.                 if (l->next == NULL) {
  281.                         free(text);
  282.                         break;
  283.                     }
  284.                 l->next->next = NULL;
  285.                     l->next->prev = l;
  286.                     l = l->next;
  287.                 }
  288.  
  289.             l->text = text;
  290.  
  291.             l->hide = (*text ==  '\x01');
  292.  
  293.             if (((t = strchr(text,'>')) != NULL) && ((t - text) < 5)) l->quote = 1;
  294.             else l->quote = 0;
  295.  
  296.                 l->block = 0;
  297.  
  298.             if ((*text != '\01') && (*text != '\n') && (strlen(text) > (size_t) rm))        {
  299.                     wrap(l,1,maxy);
  300.                     while (l->next)
  301.                         l = l->next;
  302.                 }
  303.         }
  304.     }
  305.  
  306.     checkrecvd(m);
  307.     return (m);
  308. }
  309.  
  310. static void _pascal checkrecvd(MSG * m)
  311.  
  312. {
  313.     if (m->attrib.recvd)
  314.         return;
  315.  
  316.     m->times_read++;
  317.  
  318.     if (strcmpl(username, m->isto) == 0) {
  319.         m->attrib.recvd = 1;
  320.         msg_writeheader(m);
  321.     }
  322. }
  323.  
  324. void _pascal clearmsg(MSG *m)
  325.  
  326. {
  327.     m->msgnum = 0;
  328.     if (m->reply) free(m->reply);
  329.     if (m->msgid) free(m->msgid);
  330.     if (m->isfrom) free(m->isfrom);
  331.     if (m->isto) free(m->isto);
  332.     if (m->subj) free(m->subj);
  333.     m->reply = m->msgid = m->isfrom = m->isto = m->subj = NULL;
  334.     m->replyto = 0;
  335.     m->replyfrom = 0;
  336.     m->timestamp = 0;
  337.     memset(&m->attrib,0,sizeof m->attrib);
  338.     m->attrib.private = arealist[area].priv;
  339.     m->attrib.crash = arealist[area].crash;
  340.     m->attrib.hold = arealist[area].hold;
  341.     m->attrib.direct = arealist[area].direct;
  342.     m->attrib.killsent = arealist[area].killsent;
  343.     m->attrib.local = 1;
  344.     if (m->to.domain != NULL) free(m->to.domain);
  345.     memset(&m->to, 0, sizeof m->to);
  346.     if (m->from.domain != NULL) free(m->from.domain);
  347.     memset(&m->from, 0, sizeof m->from);
  348.     m->text = clearbuffer(m->text);
  349. }
  350.  
  351. #ifndef ASM
  352.  
  353. void _pascal normalize(char *s)
  354.  
  355. {
  356.     char   *tmp = s;
  357.  
  358.     while (*s)
  359.         if ((unsigned) (0xff & *s) == (unsigned) 0x8d)
  360.             s++;
  361.         else if (*s == 0x0a)
  362.             s++;
  363.         else if (*s == 0x0d)
  364.             s++, *tmp++ = '\n';
  365.         else {
  366.             *tmp++ = (char) DOROT13((int) *s);
  367.             s++;
  368.         }
  369.     *tmp = '\0';
  370. }
  371.  
  372. #endif
  373.  
  374. int _pascal setcwd(char *path)
  375.  
  376. {
  377.     char *p;
  378.  
  379.     if ((p = strchr(path,':')) == NULL)
  380.         p = path;
  381.  
  382.     if (*p == ':') {
  383.         p++;
  384. #ifdef __OS2__
  385.         (void) DosSelectDisk((USHORT)(toupper(*path) - 'A'+1));
  386. #else
  387.         bdos(14,toupper(*path) - 'A',0);
  388. #endif
  389.     }
  390.     return(chdir(p));
  391. }
  392.  
  393. int _pascal writemsg(MSG *m)
  394.  
  395. {
  396.     char    path[PATHLEN];
  397.     LINE   *l;
  398.     FILE   *fp;
  399.     ADDRESS tmpto, tmpfrom;
  400.     char    corigin[TEXTLEN];
  401.     char    buf[BLOCKLEN+1];
  402.     int     i,n = m->msgnum;
  403.     int     newtear = 1;
  404.     time_t    now = time(NULL);
  405.     char   *uucp_to = NULL, *uucp_fr = NULL;
  406.  
  407.     count++;
  408.     if (!override && arealist[area].echomail) {
  409.         memset(corigin,0,sizeof corigin);
  410.         sprintf(path,"%s\\origin",arealist[area].path);
  411.  
  412.         if ((fp = fopen(path,"rt")) != NULL) {
  413.             fgets(corigin,sizeof(corigin),fp);
  414.             fclose(fp);
  415.         }
  416.         else if (origin != NULL)
  417.             strcpy(corigin,origin);
  418.         else
  419.             strcpy(corigin,username);
  420.     }
  421.     else
  422.         strcpy(corigin,origin);
  423.  
  424.     if (strchr(corigin,'\n'))
  425.         *strchr(corigin,'\n') = '\0';
  426.  
  427.     /* if this is a uucp message, replace the message address with that
  428.        of the nearest uucp gateway
  429.     */
  430.  
  431.     if (m->to.internet || m->to.bangpath) {
  432.         uucp_to = m->to.domain;
  433.         m->to = uucp_gate;
  434.         if (uucp_gate.domain)
  435.             m->to.domain = strdup(uucp_gate.domain);
  436.         if (!arealist[area].news)
  437.             m->isto = strdup("UUCP");
  438.         else
  439.             m->isto = strdup("All");
  440.     }
  441.  
  442.     if (m->from.internet || m->from.bangpath) {
  443.         uucp_fr = m->from.domain;
  444.         m->from = uucp_gate;
  445.         if (uucp_gate.domain)
  446.             m->from.domain = strdup(uucp_gate.domain);
  447.         m->isfrom = strdup("UUCP");
  448.     }
  449.  
  450.     /* remap the message header */
  451.     
  452.     /* save the unmapped source and destination of the message */
  453.  
  454.     tmpto = m->to;
  455.     tmpfrom = m->from;
  456.  
  457.  
  458.     /* map the address by alias if possible */
  459.  
  460.     if ((aliascount > 1) && (thisnode.zone != m->to.zone)) {
  461.         for (i = 1; i < aliascount; i++)
  462.             if (alias[i].zone == m->to.zone)
  463.                 break;
  464.         if (alias[i].zone == m->to.zone) {
  465.             m->from = alias[i];
  466.         }
  467.     }
  468.  
  469.     /* do zone gating as necessary */
  470.  
  471.     if ((thisnode.zone != m->to.zone) && (!m->attrib.direct) &&
  472.         (!m->attrib.crash) && (arealist[area].netmail) &&
  473.         (gate & GZONES)) {
  474.         m->to.net = thisnode.zone;
  475.         m->to.node = m->to.zone;
  476.     }
  477.  
  478.     /* remap point originated crashmail */
  479.  
  480.     if ((!m->attrib.direct) && (!m->attrib.crash) &&
  481.         (m->from.point) && (pointnet != 0)) {
  482.         m->from.net = pointnet;
  483.         m->from.node = m->from.point;
  484.         m->from.point = 0;
  485.     }
  486.  
  487.     /* do domain gating */
  488.  
  489.     if ((gate & GDOMAINS) && domains && 
  490.         !m->attrib.direct && strcmpl(m->from.domain,m->to.domain)) {
  491.         int i;
  492.         for (i = 0; i < domains; i++)
  493.             if (strcmpl(domain_list[i].domain,m->to.domain) == 0) {
  494.                 m->to = domain_list[i];
  495.                 break;
  496.             }
  497.     }
  498.  
  499.     msg_writeheader(m);
  500.  
  501.     m->to = tmpto;
  502.     n = m->msgnum;
  503.  
  504.     if (arealist[area].netmail) {
  505.  
  506.         if ((m->to.domain != NULL) && (m->from.domain != NULL) &&
  507.             (strncmp(strupr(m->to.domain),strupr(m->from.domain),8))) {
  508.             sprintf(buf,"\01DOMAIN %s %d:%d/%d %s %d:%d/%d\r",
  509.                 m->to.domain,m->to.zone,m->to.net,m->to.node,
  510.                 tmpfrom.domain,tmpfrom.zone,tmpfrom.net,tmpfrom.node);
  511.             msg_writetext(buf,n);
  512.         }
  513.  
  514.         if (((m->from.zone != m->to.zone) || (thisnode.zone != m->to.zone)) &&
  515.             (arealist[area].netmail)) {
  516.             sprintf(buf, "\01INTL %d:%d/%d %d:%d/%d\r",
  517.                 m->to.zone, m->to.net, m->to.node,
  518.                 m->from.zone, m->from.net, m->from.node);
  519.             msg_writetext(buf,n);
  520.         }
  521.  
  522.         if (m->to.point) {
  523.             sprintf(buf, "\01TOPT %d\r", m->to.point);
  524.             msg_writetext(buf,n);
  525.         }
  526.  
  527.         if (m->from.point) {
  528.             sprintf(buf, "\01FMPT %d\r", m->from.point);
  529.             msg_writetext(buf,n);
  530.         }
  531.     }
  532.  
  533.     if (msgids && !uucp_to) {
  534.         sprintf(buf,"\01MSGID: %s %08lx\r",show_address(tmpfrom),now);
  535.         msg_writetext(buf,n);
  536.     }
  537.  
  538.     if (m->msgid && !uucp_to && m->new) {
  539.         msg_writetext("\01REPLY: ",n);
  540.         msg_writetext(m->msgid,n);
  541.         msg_writetext("\r",n);
  542.     }
  543.     else if (m->reply) {
  544.         msg_writetext("\01REPLY: ",n);
  545.         msg_writetext(m->reply,n);
  546.         msg_writetext("\r",n);
  547.     }
  548.  
  549.     if (uucp_to && !arealist[area].news) {
  550.         msg_writetext("To:   ",n);
  551.         msg_writetext(uucp_to,n);
  552.         msg_writetext("\r",n);
  553.     }
  554.  
  555.     if (uucp_fr) {
  556.         msg_writetext("From: ",n);
  557.         msg_writetext(uucp_fr,n);
  558.         msg_writetext("\r",n);
  559.     }
  560.  
  561.     l = m->text;
  562.     while (l != NULL) {
  563.         char   *t = NULL;
  564.  
  565.         if (l->text == NULL)
  566.             break;
  567.  
  568.         if ((*l->text == '\01') && (stripnotes)) {
  569.             if (*(l->text+1) != 'P') {
  570.                 l = l->next;
  571.                 continue;
  572.             }
  573.         }
  574.  
  575.         if (newtear)
  576.             newtear = strncmp(l->text,"--- ",4);
  577.  
  578.         if ((t = strchr(l->text,'\n')) != NULL)
  579.             *t = '\r';
  580.  
  581.         msg_writetext(l->text,n);
  582.  
  583.         if (t != NULL)
  584.             *t = '\n';
  585.  
  586.         if ((t == NULL) && softcr) {
  587.             if (!isspace(*(l->text+strlen(l->text)-1)))
  588.                 msg_writetext(" ",n);
  589.             msg_writetext("\x8d",n);
  590.         }
  591.  
  592.         l = l->next;
  593.     }
  594.  
  595.     if ((tearline && arealist[area].echomail) && newtear) {
  596.         msg_writetext("\r\r--- msged " VERSION "\r",n);
  597.         sprintf(buf," * Origin: %s (%s)\r",corigin,show_address(tmpfrom));
  598.         msg_writetext(buf,n);
  599.     }
  600.  
  601.     msg_writetext("\r",n);
  602.     msg_writetext(NULL,n);
  603.     arealist[area].new = 1;
  604.  
  605.     if (uucp_fr) {
  606.         release(m->from.domain);
  607.         m->from = thisnode;
  608.         m->from.fidonet = 0;
  609.         if (strchr(uucp_fr,'@'))
  610.             m->from.internet = 1;
  611.         else
  612.             m->from.bangpath = 0;
  613.  
  614.         m->from.domain = uucp_fr;
  615.     }
  616.  
  617.     if (uucp_to) {
  618.         release(m->to.domain);
  619.         m->to = thisnode;
  620.         m->to.fidonet = 0;
  621.         if (strchr(uucp_to,'@'))
  622.             m->to.internet = 1;
  623.         else
  624.             m->to.bangpath = 0;
  625.  
  626.         m->to.domain = uucp_to;
  627.     }
  628.  
  629.     return (TRUE);
  630. }
  631.