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