home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / MSGD2OS2.ZIP / MAKEMSG.C < prev    next >
Text File  |  1990-09-21  |  19KB  |  887 lines

  1. /*
  2.  
  3. Title:    MsgEd
  4.  
  5. File:    MakeMsg.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.     routines to create new messages
  14.  
  15. Support Files:
  16.  
  17.     msged.h
  18.  
  19. */
  20.  
  21. #include "msged.h"
  22. #include "date.h"
  23.  
  24. #define TEXTLEN 128
  25. #define INPLEN    60
  26.  
  27. static void _near _pascal show_attrib(void);
  28. static int _near _pascal change_from(void);
  29. static int _near _pascal change_attrib(void);
  30. static int _near _pascal change_to(void);
  31. static int _near _pascal change_dest(void);
  32. static int _near _pascal change_orig(void);
  33. static int _near _pascal change_subject(void);
  34. static void _near _pascal clear_attributes(struct _attributes *);
  35. static void _near _pascal createmsg(void);
  36.  
  37. char * _pascal attrib_line(MSG *m, char *format);
  38. char * _pascal makequote(void);
  39.  
  40. static    char work[TEXTLEN];
  41.  
  42. int     do_lookup = FALSE;
  43.  
  44. int _pascal editmsg(void);
  45.  
  46. static void _near _pascal createmsg()
  47.  
  48. {
  49.     int  *t;
  50.  
  51.     if (arealist[area].messages == 0) {
  52.         message = (MSG *) calloc(1, sizeof(MSG));
  53.         if (arealist[area].echomail)
  54.             message->msgnum = arealist[area].last = 2;
  55.         else
  56.             message->msgnum = arealist[area].last = 1;
  57.     }
  58.     else {
  59.         clearmsg(message);
  60.         message->msgnum = arealist[area].last = msgnum(arealist[area].messages - 1) + 1;
  61.     }
  62.  
  63.     if (arealist[area].messages == 0) {
  64.         t = (int *) calloc(1,sizeof(int));
  65.         arealist[area].messages = 1;
  66.     }
  67.     else
  68.         t = (int *) realloc(messages,++arealist[area].messages * sizeof(int));
  69.  
  70.     if (t == NULL)
  71.         outamemory();
  72.  
  73.     messages = t;
  74.  
  75.     messages[arealist[area].messages - 1] = message->msgnum;
  76.     do_lookup = TRUE;
  77.     message->timestamp = time(NULL);
  78.     message->isfrom = strdup(username);
  79.     memset(&message->to,0,sizeof(message->to));
  80.     message->to.zone = thisnode.zone;
  81.     message->replyfrom = message->replyto = 0;
  82.     message->text = (LINE *) NULL;
  83.     message->from = thisnode;
  84.     message->new = 1;
  85.     message->cost = message->times_read = 0;
  86.     message->from.domain = message->to.domain = (char *) NULL;
  87.     if (thisnode.domain) message->from.domain = strdup(thisnode.domain);
  88.     clear_attributes(&message->attrib);
  89. }
  90.  
  91. void _pascal newmsg()
  92.  
  93. {
  94.     int t = (arealist[area].messages)?arealist[area].current:0;
  95.     int q = 0;
  96.  
  97.     createmsg();
  98.  
  99.     while (!q) {
  100.         if (editheader() == ABORT) {
  101.             if (confirm()) {
  102.                 arealist[area].messages = msg_scan(&arealist[area]);
  103.                 arealist[area].current = (t)?t:arealist[area].current;
  104.                 return;
  105.             }
  106.         }
  107.         else
  108.             q = 1;
  109.     }
  110.  
  111.     switch (editmsg()) {
  112.  
  113.         case SAVE:
  114.             save(message);
  115.             break;
  116.  
  117.         case ABORT:
  118.             arealist[area].messages = msg_scan(&arealist[area]);
  119.             break;
  120.     }
  121.  
  122.     arealist[area].current = (t)?t:arealist[area].current;
  123. }
  124.  
  125. void _pascal reply()
  126.  
  127. {
  128.     char      *msgto;
  129.     char      *subject;
  130.     int link,q=0;
  131.     ADDRESS tmp;
  132.     MSG *    hlink = NULL;
  133.     int t = arealist[area].current;
  134.  
  135.     if (arealist[area].messages == 0) return;
  136.  
  137.     msgto = strdup(message->isfrom);
  138.     subject = strdup(message->subj);
  139.     tmp = message->from;
  140.     if (tmp.domain)
  141.         tmp.domain = strdup(message->from.domain);
  142.     link = msgnum(t);
  143.  
  144.     createmsg();
  145.  
  146.     do_lookup = FALSE;
  147.     message->isto = msgto;
  148.     message->subj = subject;
  149.     message->to = tmp;
  150.  
  151.     message->replyto = link;
  152.  
  153.     message->new = 1;
  154.  
  155.     while (!q) {
  156.         if (editheader() == ABORT) {
  157.             if (confirm()) {
  158.                 arealist[area].messages = msg_scan(&arealist[area]);
  159.                 arealist[area].current = (t)?t:arealist[area].current;
  160.                 return;
  161.             }
  162.         }
  163.         else
  164.             q = 1;
  165.     }
  166.  
  167.     switch (editmsg()) {
  168.  
  169.         case SAVE:
  170.             if ((hlink = msg_readheader(link)) != NULL) {
  171.                 hlink->replyfrom = message->msgnum;
  172.                 msg_writeheader(hlink);
  173.             }
  174.             save(message);
  175.             break;
  176.  
  177.         case ABORT:
  178.             arealist[area].messages = msg_scan(&arealist[area]);
  179.             break;
  180.     }
  181.  
  182.     arealist[area].current = t;
  183.  
  184.     dispose(hlink);
  185.     hlink = NULL;
  186. }
  187.  
  188. char * _pascal makequote()
  189.  
  190. {
  191.     int     i,n;
  192.     char    *qs;
  193.     char    *s;
  194.     char    *l = NULL;
  195.     LINE    *t;
  196.     char    initial[10];
  197.     char    line2[255];
  198.  
  199.     i = rm;
  200.     rm = qm;
  201.     n = msgnum(arealist[area].current);
  202.  
  203.     l = attrib_line(message,attribline);
  204.     dispose(message);
  205.     message = NULL;
  206.     message = readmsg(n);
  207.     rm = i;
  208.  
  209.     i = 0;
  210.     s = message->isfrom;
  211.     while (s && *s && (i < 10)) {
  212.         while (*s && isspace(*s)) s++;
  213.         initial[i++] = *s;
  214.         while (*s && !isspace(*s)) s++;
  215.     }
  216.     initial[i] = '\0';
  217.     if ((s = strchr(quotestr,'&')) == NULL)
  218.         qs = strdup(quotestr);
  219.     else {
  220.         qs = malloc(strlen(quotestr) + strlen(initial) + 1);
  221.         *s = '\0';
  222.         strcpy(qs,quotestr);
  223.         strcat(qs,initial);
  224.         strcat(qs,s + 1);
  225.         *s = '&';
  226.     }
  227.  
  228.     s = qs;
  229.     while ((s = strchr(s,'*')) != NULL)
  230.         if (initial[0])
  231.             *s = initial[0];
  232.         else
  233.             strdel(s,1);
  234.  
  235.     s = qs;
  236.     while ((s = strchr(s,'^')) != NULL)
  237.         if (initial[1])
  238.             *s = initial[1];
  239.         else
  240.             strdel(s,1);
  241.  
  242.     t = message->text;
  243.     while (t) {
  244.         if (!t->quote) {
  245.             if (t->text && (*(t->text) != '\n')) {
  246.                 strcpy(line2," ");
  247.                 strcat(line2,qs);
  248.                 if (t->text != NULL) {
  249.                     strcat(line2,t->text);
  250.                     if (strchr(t->text,'\n') == NULL) {
  251.                         strcat(line2,"\n");
  252.                     }
  253.                     free(t->text);
  254.                 }
  255.                 t->text = strdup(line2);
  256.             }
  257.             t->quote = 1;
  258.         }
  259.         else {
  260.             strcpy(line2,t->text);
  261.             if (t && t->next && t->next->text && (*(t->next->text) != '\n') && !strchr(line2,'\n')) {
  262.                 strcat(line2,t->next->text);
  263.                 free(t->next->text);
  264.                 t->next = t->next->next;
  265.                 free(t->next->prev);
  266.                 t->next->prev = t;
  267.                 free(t->text);
  268.                 t->text = strdup(line2);
  269.             }
  270.         }
  271.         t = t->next;
  272.         while (t && t->text && ((strlen(t->text) == 0))) {
  273.             LINE *t2 = t->next;
  274.             if (t->next)
  275.                 t->next->prev = t->prev;
  276.             if (t->prev)
  277.                 t->prev->next = t->next;
  278.             free(t->text);
  279.             free(t);
  280.             t = t2;
  281.         }
  282.     }
  283.  
  284.     free(qs);
  285.     return(l);
  286. }
  287.  
  288.  
  289. void _pascal quote()
  290. {
  291.     int     *msgs,q=0;
  292.     int     tm = arealist[area].current;
  293.     int     link = msgnum(arealist[area].current);
  294.     MSG    *hlink = NULL;
  295.     char    *t,*l,*s,c;
  296.     LINE    *n;
  297.  
  298.     if (arealist[area].messages == 0) return;
  299.  
  300.     l = makequote();
  301.  
  302.     release(message->isto);
  303.     message->isto = message->isfrom;
  304.     message->to = message->from;
  305.     message->from = thisnode;
  306.     if (message->from.domain)
  307.         message->from.domain = strdup(thisnode.domain);
  308.  
  309.     if (arealist[area].messages == 0) {
  310.         if (arealist[area].echomail)
  311.             message->msgnum = arealist[area].last = 2;
  312.         else
  313.             message->msgnum = arealist[area].last = 1;
  314.     }
  315.     else
  316.         message->msgnum = arealist[area].last = msgnum(arealist[area].messages - 1) + 1;
  317.  
  318.     msgs = realloc(messages,++arealist[area].messages*sizeof(int));
  319.  
  320.     if (msgs == NULL)
  321.         outamemory();
  322.  
  323.     messages = msgs;
  324.  
  325.     messages[arealist[area].messages - 1] = message->msgnum;
  326.     message->isfrom = strdup(username);
  327.     message->timestamp = time(NULL);
  328.  
  329.     clear_attributes(&message->attrib);
  330.     do_lookup = FALSE;
  331.  
  332.     message->replyto = link;
  333.  
  334.     message->new = 1;
  335.  
  336.     if (l) {
  337.         message->text = insline(message->text);
  338.         message->text->text = strdup("\n");
  339.         message->text = insline(message->text);
  340.         t = s = l; l = strchr(s,'\n'); n = message->text;
  341.         if (l != NULL) {
  342.             l++; c = *l; *l = '\0';
  343.             n->text = strdup(s);
  344.             *l = c;
  345.             while (l && *l) {
  346.                 s = l; l = strchr(s,'\n');
  347.                 n = insline(n->next);
  348.                 if (l) {
  349.                     l++; c = *l; *l = '\0';
  350.                     n->text = strdup(s);
  351.                     *l = c;
  352.                 }
  353.             }
  354.             free(t);
  355.         }
  356.         else
  357.             message->text->text = s;
  358.     }
  359.  
  360.     while (!q) {
  361.         if (editheader() == ABORT) {
  362.             if (confirm()) {
  363.                 arealist[area].messages = msg_scan(&arealist[area]);
  364.                 arealist[area].current = (tm)?tm:arealist[area].current;
  365.                 return;
  366.             }
  367.         }
  368.         else
  369.             q = 1;
  370.     }
  371.  
  372.     switch (editmsg()) {
  373.  
  374.         case SAVE:
  375.             if ((hlink = msg_readheader(link)) != NULL) {
  376.                 hlink->replyfrom = message->msgnum;
  377.                 msg_writeheader(hlink);
  378.             }
  379.             save(message);
  380.             break;
  381.  
  382.         case ABORT:
  383.             arealist[area].messages = msg_scan(&arealist[area]);
  384.             break;
  385.     }
  386.  
  387.     arealist[area].current = tm;
  388.     dispose(hlink);
  389.     hlink = NULL;
  390. }
  391.  
  392. void _pascal change()
  393.  
  394. {
  395.     int q = 0;
  396.  
  397.     if (arealist[area].messages == 0) return;
  398.  
  399.     message->attrib.sent = 0;
  400.     message->attrib.orphan = 0;
  401.     message->timestamp = time(NULL);
  402.  
  403.     do_lookup = FALSE;
  404.  
  405.     while (!q) {
  406.         if (editheader() == ABORT) {
  407.             if (confirm()) {
  408.                 arealist[area].messages = msg_scan(&arealist[area]);
  409.                 return;
  410.             }
  411.         }
  412.         else
  413.             q = 1;
  414.     }
  415.  
  416.     switch (editmsg()) {
  417.  
  418.         case SAVE:
  419.             writemsg(message);
  420.             break;
  421.  
  422.         case ABORT:
  423.             break;
  424.     }
  425. }
  426.  
  427. static void _near _pascal show_attrib()
  428.  
  429. {
  430.     gotoxy(9, 5);
  431.     set_color((message->attrib.private)?co_hilite:co_normal);
  432.     bputs("Privileged ");
  433.     set_color((message->attrib.crash)?co_hilite:co_normal);
  434.     bputs("Crash ");
  435.     set_color((message->attrib.attached)?co_hilite:co_normal);
  436.     bputs("Attach ");
  437.     set_color((message->attrib.freq)?co_hilite:co_normal);
  438.     bputs("Request ");
  439.     set_color((message->attrib.ureq)?co_hilite:co_normal);
  440.     bputs("Update ");
  441.     set_color((message->attrib.killsent)?co_hilite:co_normal);
  442.     bputs("Kill/sent ");
  443.     set_color((message->attrib.hold)?co_hilite:co_normal);
  444.     bputs("Hold ");
  445.     set_color((message->attrib.direct)?co_hilite:co_normal);
  446.     bputs("Direct ");
  447.     set_color(co_normal);
  448.     gotoxy(1, 5);
  449.     bputs("Attrib: ");
  450. }
  451.  
  452. static int _near _pascal change_attrib()
  453.  
  454. {
  455.     int     ch;
  456.  
  457.     set_color(co_hilite);
  458.     gotoxy(1, 5);
  459.     video_update();
  460.     bputs("Attrib: ");
  461.     set_color(co_info);
  462.     ch = getkey();
  463.     message->attrib.private ^= (toupper((ch & 0xff)) == 'P');
  464.     message->attrib.crash ^= (toupper((ch & 0xff)) == 'C');
  465.     message->attrib.attached ^= (toupper((ch & 0xff)) == 'A');
  466.     message->attrib.ureq ^= (toupper((ch & 0xff)) == 'U');
  467.     message->attrib.freq ^= (toupper((ch & 0xff)) == 'R');
  468.     message->attrib.killsent ^= (toupper((ch & 0xff)) == 'K');
  469.     message->attrib.hold ^= (toupper((ch & 0xff)) == 'H');
  470.     message->attrib.direct ^= (toupper((ch & 0xff)) == 'D');
  471.     return (ch);
  472. }
  473.  
  474. static int _near _pascal change_from()
  475.  
  476. {
  477.     int     ch;
  478.     char    tmp[70];
  479.     char    *t;
  480.  
  481.     set_color(co_hilite);
  482.     gotoxy(1, 2);
  483.     bputs("From:   ");
  484.     set_color(co_normal);
  485.     clreol();
  486.  
  487.     if (message->isfrom != NULL) {
  488.         strncpy(tmp,message->isfrom, sizeof tmp - 1);
  489.         free(message->isfrom);
  490.     }
  491.     else
  492.         memset(tmp,0,sizeof tmp);
  493.  
  494.     if (message->from.internet)
  495.         strncpy(tmp,message->from.domain,sizeof tmp - 1);
  496.     else if (message->from.bangpath)
  497.         strncat(strcpy(tmp,"@"),message->from.domain,sizeof tmp - 2);
  498.  
  499.     ch = bgets(tmp,sizeof(tmp)-1,maxx - 9);
  500.  
  501.     message->from.notfound = 0;
  502.  
  503.     if (((t = strchr(tmp,'@')) != NULL) &&
  504.         (arealist[area].news || arealist[area].uucp)) {
  505.         message->from.fidonet = 0;
  506.         if (t == tmp) {
  507.             t++;
  508.             message->from.bangpath = 1;
  509.         }
  510.         else {
  511.             message->from.internet = 1;
  512.             t = tmp;
  513.         }
  514.         release(message->from.domain);
  515.         message->from.domain = strdup(t);
  516.         release(message->isfrom);
  517.     }
  518.     else {
  519.         message->isfrom = strdup(tmp);
  520.         if (message->from.internet || message->from.bangpath) {
  521.             message->from = thisnode;
  522.             if (thisnode.domain)
  523.                 message->from.domain = strdup(thisnode.domain);
  524.             else
  525.                 message->from.domain = NULL;
  526.         }
  527.         message->from.internet = 0;
  528.         message->from.bangpath = 0;
  529.         message->from.fidonet = 1;
  530.     }
  531.  
  532.     gotoxy(1, 2);
  533.     set_color(co_info);
  534.     bputs("From:   ");
  535.     return (ch);
  536. }
  537.  
  538. static int _near _pascal change_orig()
  539.  
  540. {
  541.     int     ch;
  542.     char    tmp[TEXTLEN];
  543.  
  544.     gotoxy(9 + strlen(message->isfrom), 2);
  545.     set_color(co_hilite);
  546.     bputs(" of ");
  547.     set_color(co_normal);
  548.     strncpy(tmp,show_address(message->from),TEXTLEN);
  549.     ch = bgets(tmp, sizeof tmp - 1, maxx - (12 + strlen(message->isfrom)));
  550.     message->from = parsenode(tmp);
  551.     gotoxy(9 + strlen(message->isfrom), 2);
  552.     set_color(co_info);
  553.     bputs(" of ");
  554.     return (ch);
  555. }
  556.  
  557. static int _near _pascal change_to()
  558.  
  559. {
  560.     int       ch;
  561.     char      tmp[70];
  562.     char      *tmp2;
  563.     char      *t;
  564.  
  565.     set_color(co_hilite);
  566.     gotoxy(1, 3);
  567.     bputs("To:     ");
  568.     set_color(co_normal);
  569.     clreol();
  570.     tmp2 = message->isto;
  571.  
  572.     if (message->isto != NULL)
  573.         strncpy(tmp,message->isto, sizeof tmp - 1);
  574.     else
  575.         memset(tmp,0,sizeof tmp);
  576.  
  577.     if (message->to.internet)
  578.         strncpy(tmp,message->to.domain,sizeof tmp - 1);
  579.     else if (message->to.bangpath)
  580.         strncat(strcpy(tmp,"@"),message->to.domain,sizeof tmp - 2);
  581.  
  582.     ch = bgets(tmp, sizeof(tmp) - 1, maxx - 9);
  583.  
  584.     message->to.notfound = 0;
  585.  
  586.     if (((t = strchr(tmp,'@')) != NULL) &&
  587.          (arealist[area].news || arealist[area].uucp)) {
  588.         message->to.fidonet = 0;
  589.         if (t == tmp) {
  590.             t++;
  591.             message->to.bangpath = 1;
  592.         }
  593.         else {
  594.             message->to.internet = 1;
  595.             t = tmp;
  596.         }
  597.  
  598.         release(message->to.domain);
  599.         message->to.domain = strdup(t);
  600.         release(message->isto);
  601.         do_lookup = 0;
  602.     }
  603.     else {
  604.         message->to.fidonet = 1;
  605.         message->to.internet = 0;
  606.         message->to.bangpath = 0;
  607.         do_lookup = (tmp != NULL)?((tmp2 != NULL)?abs((strcmpl(tmp2,tmp))):1):0; /*WRA*/
  608.         message->isto = (tmp != NULL)?strdup(tmp):NULL;
  609. /*        do_lookup = (tmp2 == NULL) || !(strcmpl(tmp2,tmp) == 0); */
  610.     }
  611.  
  612.     gotoxy(1, 3);
  613.     set_color(co_info);
  614.     bputs("To:     ");
  615.     if ((arealist[area].netmail) && do_lookup && (fidolist != NULL)) {
  616.         message->to = lookup(message->isto,fidolist);
  617.         if ((message->to.notfound) && (userlist != NULL))
  618.             message->to = lookup(message->isto,userlist);
  619.     }
  620.     return (ch);
  621. }
  622.  
  623. static int _near _pascal change_dest()
  624.  
  625. {
  626.     int     ch;
  627.     char    tmp[TEXTLEN];
  628.  
  629.     gotoxy(9 + strlen(message->isto), 3);
  630.     set_color(co_hilite);
  631.     bputs(" of ");
  632.     set_color((message->to.notfound)?co_warn:co_normal);
  633.     strncpy(tmp,show_address(message->to),TEXTLEN);
  634.  
  635.     ch = bgets(tmp, sizeof tmp - 1, maxx - (12 + strlen(message->isto)));
  636.  
  637.     message->to = parsenode(tmp);
  638.     if ((message->to.domain != NULL) && (thisnode.domain != NULL))
  639.         message->from.domain = strdup(thisnode.domain);
  640.  
  641.     gotoxy(9 + strlen(message->isto), 3);
  642.     set_color(co_info);
  643.     bputs(" of ");
  644.     return (ch);
  645. }
  646.  
  647. static int _near _pascal change_subject()
  648.  
  649. {
  650.     int     ch;
  651.     char    tmp[73];
  652.  
  653.     set_color(co_hilite);
  654.     gotoxy(1, 4);
  655.     bputs(((message->attrib.attached) ||
  656.           (message->attrib.freq) ||
  657.           (message->attrib.ureq))?"Files:  ":"Subj:   ");
  658.     set_color(co_normal);
  659.     if (message->subj != NULL) {
  660.         strncpy(tmp,message->subj, sizeof tmp - 1);
  661.         free(message->subj);
  662.     }
  663.     else
  664.         memset(tmp,0,sizeof tmp);
  665.  
  666.     ch = bgets(tmp,sizeof tmp - 1, maxx - 9);
  667.     message->subj = strdup(tmp);
  668.     if ((*(tmp+1) == ':') && (*(tmp+2) == '\\')) {
  669.         message->attrib.attached = 1;
  670.         show_attrib();
  671.     }
  672.     gotoxy(1, 4);
  673.     set_color(co_info);
  674.     bputs(((message->attrib.attached) ||
  675.           (message->attrib.freq) ||
  676.           (message->attrib.ureq))?"Files:  ":"Subj:   ");
  677.     return (ch);
  678. }
  679.  
  680. int _pascal editheader()
  681.  
  682. {
  683.     int     field = 2;
  684.     int     ch = 0;
  685.  
  686.     cls();
  687.     showheader(message);
  688.     show_attrib();
  689.     for (ch = 1; ch < maxx; ch++) {
  690.            gotoxy(ch,6);
  691.            bputc('_');
  692.         }
  693.     gotoxy(1, 6);
  694.     set_color(co_hilite);
  695.     bputs(arealist[area].description);
  696.     set_color(co_normal);
  697.  
  698.     while (ch != DONE) {
  699.         switch (field) {
  700.         case 0:
  701.             ch = change_from();
  702.             break;
  703.         case 1:
  704.             if (arealist[area].netmail ||
  705.                (arealist[area].uucp && message->from.fidonet))
  706.                 ch = change_orig();
  707.             break;
  708.         case 2:
  709.             if (arealist[area].news) {
  710.                 if (message->isto) free(message->isto);
  711.                 message->isto = strdup("All");
  712.                 message->to = uucp_gate;
  713.                 if (uucp_gate.domain)
  714.                     message->to.domain = strdup(uucp_gate.domain);
  715.                 ch = DOWN;
  716.                 break;
  717.             }
  718.             ch = change_to();
  719.             break;
  720.         case 3:
  721.             if (arealist[area].netmail && message->to.fidonet)
  722.                 ch = change_dest();
  723.             break;
  724.         case 4:
  725.             ch = change_subject();
  726.             break;
  727.         case 5:
  728.             ch = change_attrib();
  729.             show_attrib();
  730.             break;
  731.         }
  732.  
  733.         if (ch == ABORT)
  734.             return(ABORT);
  735.  
  736.         if (ch == UP) {
  737.  
  738.             field--;
  739.  
  740.             if (field < 0)
  741.                 field = 5;
  742.  
  743.         }
  744.  
  745.         if ((ch == DOWN) || (ch == ENTER)) {
  746.  
  747.             if ((field == 5) && (ch == ENTER))
  748.                 break;
  749.  
  750.             field++;
  751.  
  752.             if (field > 5)
  753.                 field = 0;
  754.  
  755.             continue;
  756.         }
  757.     }
  758.     showheader(message);
  759.     return(0);
  760. }
  761.  
  762. static void _near _pascal clear_attributes(struct _attributes * h)
  763.  
  764. {
  765.     h->recvd = h->sent = h->attached = h->forward = h->orphan = h->freq =
  766.     h->rreq = h->rcpt = h->areq = h->ureq = 0;
  767.  
  768.     h->crash     = arealist[area].crash;
  769.         h->private     = (h->private)?h->private:arealist[area].priv;
  770.         h->killsent  = arealist[area].killsent;
  771.         h->hold      = arealist[area].hold;
  772.         h->direct     = arealist[area].direct;
  773.         h->local     = 1;
  774. }
  775.  
  776. void _pascal save(MSG *m)
  777.  
  778. {
  779.     LINE *current;
  780.     char *s,*t;
  781.     char *name;
  782.  
  783.     writemsg(m);
  784.     current = m->text;
  785.     s = current->text;
  786.     while (isspace(*s))
  787.         s++;
  788.  
  789.     if (tolower(*s) != 'c')
  790.         return;
  791.  
  792.     s++;
  793.     if (tolower(*s) != 'c')
  794.         return;
  795.  
  796.     s++;
  797.     if (*s != ':')
  798.         return;
  799.     s++;
  800.  
  801.     m->text = insline(m->text);
  802.     m->text->text = strdup("\n");
  803.     sprintf(work," * Original to %s of %s\n",m->isto,show_address(m->to));
  804.     m->text = insline(m->text);
  805.     m->text->text = strdup(work);
  806.     m->attrib.killsent = 1;
  807.  
  808.     while ((s != NULL)    && (*s != '\0') && isspace(*s))
  809.         s++;
  810.  
  811.     while ((s != NULL) && (*s != '\0')) {
  812.  
  813.         name = strdup(s);
  814.  
  815.         /* strip trailing white space */
  816.  
  817.         t = strchr(name,'\n');
  818.         if (t == NULL)
  819.             break;
  820.  
  821.         while (isspace(*t) && (t > name))
  822.             *t-- = '\0';
  823.  
  824.         memset(&(m->to),0,sizeof(ADDRESS));
  825.         t = strrchr(name,' ');
  826.         s = strchr(name,' ');
  827.         if ((t != NULL)) {
  828.             while (isspace(*s)) s++;
  829.             while (isspace(*t)) t++;
  830.             if ((s == t) && isdigit(*s)) {
  831.                 m->to = parsenode(s);
  832.                 if (!m->to.notfound) {
  833.                     while (isspace(*s--)) ;
  834.                     *s = '\0';
  835.                 }
  836.             }
  837.             else if (isdigit(*t)) {
  838.                 m->to = parsenode(t);
  839.                 if (!m->to.notfound) {
  840.                     while (isspace(*t--)) ;
  841.                     *t = '\0';
  842.                 }
  843.             }
  844.             else {
  845.                 m->to = thisnode;
  846.                 if (m->to.domain != NULL)
  847.                     m->to.domain = strdup(m->to.domain);
  848.                 m->to.notfound = 1;
  849.             }
  850.         }
  851.         if ((fidolist != NULL) && (m->to.notfound)) {
  852.             if (m->to.domain != NULL)
  853.                 free(m->to.domain);
  854.             m->to = lookup(name,fidolist);
  855.             if ((m->to.notfound) && (userlist != NULL)) {
  856.                 m->to = lookup(name,userlist);
  857.                 if (m->to.notfound) {
  858.                     m->to = thisnode;
  859.                     if (m->to.domain != NULL)
  860.                         m->to.domain = strdup(m->to.domain);
  861.                     m->to.notfound = 1;
  862.                 }
  863.             }
  864.         }
  865.  
  866.         if (m->isto != NULL) {
  867.             free(m->isto);
  868.             m->isto = NULL;
  869.         }
  870.         for (t = name + strlen(name) - 1; isspace(*t); t--)
  871.             *t = '\0';
  872.         m->isto = name;
  873.         ++m->msgnum;
  874.         writemsg(m);
  875.         current = current->next;
  876.  
  877.         /* strip leading white space */
  878.  
  879.         s = (current == NULL) ? NULL : current->text;
  880.  
  881.         while ((s != NULL) && (*s != '\0') && isspace(*s))
  882.             s++;
  883.     }
  884.  
  885.     arealist[area].messages = msg_scan((&arealist[area]));
  886. }
  887.