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