home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / XGRP_000.SZH / GMAILIN.C < prev    next >
C/C++ Source or Header  |  1991-08-21  |  21KB  |  671 lines

  1. /* groupmail tosser (implemented per FSC-0036) */
  2.  
  3. #include "xgroup.h"
  4.  
  5. #define MAXKLUDGE 256
  6.  
  7. /* local-only functions */
  8.  
  9. static int  _fastcall crack_pkt (char *pktname,GROUP *ginfo);
  10. static int  _fastcall import (GROUP *ginfo,char *buff,XMSG *msg,int dataptr,
  11.                               int textptr);
  12. static int  _fastcall get_msg (word buflen,char *buff,char **text,int fp,
  13.                                XMSG *msg);
  14. static void _fastcall report (void);
  15.  
  16. /* global vars created here */
  17.  
  18. char buffer[1024];
  19.  
  20. /* local-only variables */
  21.  
  22. static char to_domain[39],from_domain[39];
  23.  
  24. /* external var references */
  25.  
  26. extern GROUP    *group;
  27. extern CONTROLS control;
  28. extern ADDR     *myaddr;
  29. extern ECHOREC  *echos;
  30. extern char     *groupin;
  31. extern char     *groupout;
  32. extern char     *grouphold;
  33. extern char     *msgdir;
  34. extern char     *outbound;
  35. extern char     *inbound;
  36. extern char     *archive;
  37. extern char     *unarchive;
  38. extern word     packsize;
  39. extern word     netarea;
  40.  
  41.  
  42.  
  43.  
  44. void _fastcall group_import_mail (void) {
  45.  
  46.     FILEFINDBUF f;
  47.     GROUP       *currgroup = group;
  48.     int         search_handle,num_matches,handle;
  49.     char        *p,arcname[257];
  50.     struct __info__ {
  51.         word create_date;
  52.         word create_time;
  53.         word last_date;
  54.         word last_time;
  55.         word write_date;
  56.         word write_time;
  57.         long size;
  58.         long allocation;
  59.         word attrib;
  60.     }           info,info2;
  61.  
  62.  
  63.     /* clean up stray packets in groupin dir */
  64.  
  65.     sprintf(buffer,"%s/*.PKT",groupout);
  66.     search_handle = 1;  /* for bound purposes */
  67.     num_matches = 1;
  68.     if(!DosFindFirst(buffer,&search_handle,0,&f,
  69.         sizeof(FILEFINDBUF),&num_matches,0L)) {
  70.       do {
  71.           sprintf(buffer,"%s/%s",groupout,f.achName);
  72.           my_unlink(buffer);
  73.           num_matches = 1;
  74.       } while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
  75.                            &num_matches));
  76.       DosFindClose(search_handle);
  77.     }
  78.  
  79.     printf("\nImporting groupmail...");
  80.  
  81.     while(currgroup) {
  82.  
  83. Again:
  84.  
  85.         sprintf(buffer,"%s/%s.*",groupin,currgroup->id);
  86.  
  87.         search_handle = 1;  /* for bound purposes */
  88.         num_matches = 1;
  89.  
  90.         if(!DosFindFirst(buffer,&search_handle,0,&f,
  91.            sizeof(FILEFINDBUF),&num_matches,0L)) {
  92.  
  93.           do {
  94.             p = strrchr(f.achName,'.'); /* verify it's a group file */
  95.             if(!p) {
  96.                 goto ContHere;
  97.             }
  98.             p++;
  99.             if(ext_reserved(p)) {       /* check various reserved extensions */
  100.                 goto ContHere;
  101.             }
  102.             if(stricmp(p,"YG0") > 0 && currgroup->uplink) {
  103.                                         /* group file, not msgs */
  104.                                         /* at this time, not doing */
  105.                                         /* anything with them but */
  106.                                         /* passing them through... */
  107.                 if(toupper(*groupin) == toupper(*groupout)) {
  108.                     sprintf(buffer,"%s/%s %s/%s",groupin,f.achName,groupout,f.achName);
  109.                     p = strchr(buffer,' ');
  110.                     *p = 0;
  111.                     p++;
  112.                     DosMove(buffer,p,0L);
  113.                     logf("Non-msg group file %s located",f.achName);
  114.                 }
  115.                 else {
  116.                     sprintf(buffer,"COPY %s/%s %s/%s > NUL",groupin,f.achName,groupout,f.achName);
  117.                     system(buffer);
  118.                     sprintf(buffer,"%s/%s",groupin,f.achName);
  119.                     my_unlink(buffer);
  120.                 }
  121.             }
  122.  
  123.             /* crack archive */
  124.  
  125.             switch_to(groupin);
  126.             sprintf(buffer,"%s %s\\%s *.PKT",unarchive,groupin,f.achName);
  127.             system(buffer);
  128.             switch_back();
  129.  
  130.             DosFindClose(search_handle);
  131.             search_handle = 1;
  132.             num_matches = 1;
  133.             strcpy(arcname,f.achName);
  134.             sprintf(buffer,"%s/*.PKT",groupin);
  135.             if(!DosFindFirst(buffer,&search_handle,0,&f,
  136.                sizeof(FILEFINDBUF),&num_matches,0L)) {
  137.  
  138.                 /* update group date file in inbound dir */
  139.  
  140.                 sprintf(buffer,"%s/%s",groupin,arcname);
  141.                 handle = sopen(buffer,O_RDONLY | O_BINARY,SH_DENYNO);
  142.                 if(handle == -1 || DosQFileInfo(handle,1,&info,sizeof(struct __info__))) {
  143.                     printf("\07Warning:  could not revise timestamp on group date file %s\n",currgroup->id);
  144.                 }
  145.                 else {
  146.                     close(handle);
  147.                     sprintf(buffer,"%s/%s.!",groupin,currgroup->id);
  148.                     handle = sopen(buffer,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IREAD | S_IWRITE);
  149.                     if(handle == -1) {
  150.                         printf("\07Warning:  could not revise timestamp on group date file %s\n",currgroup->id);
  151.                     }
  152.                     else {
  153.                         if(DosQFileInfo(handle,1,&info2,sizeof(struct __info__))) {
  154.                             printf("\07Warning:  could not revise timestamp on group date file %s\n",currgroup->id);
  155.                         }
  156.                         else {
  157.                             if(info.write_date > info2.write_date || (info.write_date == info2.write_date && info.write_time > info2.write_time)) {
  158.                                 DosSetFileInfo(handle,1,&info,12);
  159.                             }
  160.                         }
  161.                         close(handle);
  162.                     }
  163.                 }
  164.  
  165.                 /* move archive to groupout directory (pass it on) */
  166.  
  167.                 if(currgroup->uplink && currgroup->numdays) {
  168.                     if(toupper(*groupin) == toupper(*groupout)) {
  169.                         sprintf(buffer,"%s/%s %s/%s",groupin,arcname,
  170.                                 groupout,arcname);
  171.                         p = strchr(buffer,' ');
  172.                         *p = 0;
  173.                         p++;
  174.                         DosMove(buffer,p,0L);
  175.                     }
  176.                     else {
  177.                         sprintf(buffer,"COPY %s/%s %s/%s > NUL",groupin,arcname,
  178.                                 groupout,arcname);
  179.                         system(buffer);
  180.                         sprintf(buffer,"%s/%s",groupin,arcname);
  181.                         my_unlink(buffer);
  182.                     }
  183.                 }
  184.  
  185.                 do {    /* process packets */
  186.                     sprintf(buffer,"%s/%s",groupin,f.achName);
  187.                     crack_pkt(buffer,currgroup);
  188.                     num_matches = 1;
  189.                 } while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
  190.                                      &num_matches));
  191.                 DosFindClose(search_handle);
  192.             }
  193.  
  194.             else {
  195.                 if(grouphold) {
  196.                     if(toupper(*groupin) == toupper(*grouphold)) {
  197.                         sprintf(buffer,"%s/%s %s/%s",groupin,f.achName,grouphold,f.achName);
  198.                         p = strchr(buffer,' ');
  199.                         *p = 0;
  200.                         p++;
  201.                         DosMove(buffer,p,0L);
  202.                     }
  203.                     else {
  204.                         sprintf(buffer,"COPY %s/%s %s/%s",groupin,f.achName,grouphold,f.achName);
  205.                         system(buffer);
  206.                         sprintf(buffer,"%s/%s",groupin,f.achName);
  207.                         my_unlink(buffer);
  208.                     }
  209.                 }
  210.                 else {
  211.                     sprintf(buffer,"%s/%s",groupin,f.achName);
  212.                     my_unlink(buffer);
  213.                 }
  214.             }
  215.             goto Again;
  216.  
  217. ContHere:
  218.             num_matches = 1;
  219.           } while(!DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),
  220.                                &num_matches));
  221.           DosFindClose(search_handle);
  222.         }
  223.  
  224.         currgroup = currgroup->next;
  225.     }
  226.  
  227.     report();
  228. }
  229.  
  230.  
  231.  
  232. void _fastcall report (void) {
  233.  
  234.     GROUP *currgroup = group;
  235.     long  totalmsgs  = 0L;
  236.  
  237.  
  238.     printf("\n");
  239.  
  240.     while(currgroup) {
  241.         if(currgroup->imported) {
  242.             totalmsgs += (long)currgroup->imported;
  243.                         logf("Imported %u msg%s to area #%u \"%s\"",
  244.                                  currgroup->imported,&"s"[currgroup->imported == 1],
  245.                                  currgroup->areano,currgroup->id);
  246.         }
  247.         currgroup = currgroup->next;
  248.     }
  249.  
  250.     if(totalmsgs) {
  251.         logf("Total msgs imported: %lu",totalmsgs);
  252.     }
  253. }
  254.  
  255.  
  256.  
  257. int _fastcall crack_pkt (char *pktname,GROUP *ginfo) {
  258.  
  259.     int           fp,dataptr,textptr;
  260.     long          len;
  261.     char          *buff,*text;
  262.     word          buflen;
  263.     int           temp;
  264.     XMSG          msg;
  265.     PKTHDR        pi;
  266.  
  267.  
  268.     fp = sopen(pktname,O_RDONLY | O_BINARY,SH_DENYWR);
  269.     if(fp == -1) return -1;      /* Return Can't Open */
  270.     lseek(fp,0L,SEEK_END);    /* Get packet size */
  271.     len = tell(fp);
  272.     if(len <= (long)sizeof(PKTHDR) + 2L) {
  273.         close(fp);
  274.         my_unlink(pktname);
  275.         printf("\nShort packet discarded.\n");
  276.         return 0;            /* Ignore 'short' packet */
  277.     }
  278.     lseek(fp,0L,SEEK_SET);
  279.  
  280.     if((len - (long)sizeof(PKTHDR)) < 65533L)
  281.       buflen = (word)((len - (long)sizeof(PKTHDR)) + 1L);
  282.     else buflen = 65534U;     /* Set minimum buff length */
  283.     buff = (char *)malloc(buflen + 1);        /* Allocate text buff */
  284.     if(!buff) {
  285.         close(fp);
  286.         return -2;        /* Return OOM */
  287.     }
  288.  
  289.     read(fp,&pi,sizeof(PKTHDR)); /* Get packet header */
  290.  
  291.     if(pi.version != 2) {   /* not type 2; can't handle it */
  292.         return -4;
  293.     }
  294.  
  295.     sprintf(buffer,"%s/XTEXT.%03x",msgdir,ginfo->areano);
  296.     textptr = sopen(buffer,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE | S_IREAD);
  297.     sprintf(buffer,"%s/XDATA.%03x",msgdir,ginfo->areano);
  298.     dataptr = sopen(buffer,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE | S_IREAD);
  299.     if(dataptr == -1 || textptr == -1) {
  300.         if(dataptr != -1) close(dataptr);
  301.         if(textptr != -1) close(textptr);
  302.         printf("\nCan't open message base file(s)\n");
  303.         return -4;       /* Error opening message area */
  304.     }
  305.  
  306.     lseek(dataptr,0L,SEEK_END);
  307.     lseek(textptr,0L,SEEK_END);
  308.  
  309.     printf("\n\x1b[K");
  310.  
  311.     while(!eof(fp)) {
  312.         temp = get_msg(buflen,buff,&text,fp,&msg);
  313.         if(temp == -3) {
  314.             continue;
  315.         }
  316.         if(temp == -1) {
  317.             close(fp);
  318.             my_free(buff);
  319.             my_unlink(pktname);
  320.             return -3;         /* Return 'minor' error */
  321.         }
  322.         if(temp < 0) break;    /* End of packet */
  323.         if(!text || !*text) {
  324.             printf("\x1b[s\x1b[1;1H\x1b[KNULL message discarded\x1b[u");
  325.             continue;          /* NULL message */
  326.         }
  327.         if(!temp) {
  328.             printf("%u\r");
  329.             temp = import(ginfo,buff,&msg,dataptr,textptr);
  330.         }
  331.     }
  332.     close(fp);          /* Close packet */
  333.     close(dataptr);
  334.     close(textptr);
  335.     my_unlink(pktname);    /* Get rid of packet after unpacking */
  336.     my_free(buff);
  337.     return 0;            /* Return success */
  338. }
  339.  
  340.  
  341.  
  342.  
  343. int _fastcall import (GROUP *ginfo,char *buff,XMSG *xmsg,int dataptr,
  344.                       int textptr) {
  345.  
  346.     /* Put msg in XBBS base */
  347.  
  348.     char      *hold;
  349.     word      temp;
  350.     time_t    tt;
  351.     struct tm *t;
  352.     int       x;
  353.     long      pos;
  354.  
  355.  
  356.     ginfo->imported++;
  357.  
  358.     if(!ginfo->areano) return 0;    /* pass-thru */
  359.  
  360.     x = 0;
  361.     while(x < 50) {
  362.         if(lseek(textptr,0L,SEEK_END) != -1L) break;
  363.         DosSleep(100L);
  364.         x++;
  365.     }
  366.     if(x >= 50) {
  367.         printf("\nLocking conflict; can't import msg\n");
  368.         return -1;
  369.     }
  370.     locking(textptr,LK_LOCK,65535L);
  371.     xmsg->start = tell(textptr);
  372.     if(packsize && xmsg->length > packsize) {
  373.  
  374.         temp = strlen(buff);
  375.         if(temp > 65100U) {
  376.             buff[65099U] = 0;
  377.             temp = 65100U;
  378.         }
  379.         hold = (char *)malloc(temp + 256);
  380.         if(!hold) {
  381.             printf("\nInsufficient memory for compression\n");
  382.             write(textptr,buff,temp);
  383.         }
  384.         else {
  385.             hold = pack_msg(hold,xmsg);
  386.             if(!hold) {
  387.                printf("\nCompression failed\n");
  388.                write(textptr,buff,temp);
  389.             }
  390.             else {
  391.                 xmsg->m_attr |= MSGPACKED;
  392.                 write(textptr,hold,xmsg->length);
  393.             }
  394.             my_free(hold);
  395.        }
  396.     }
  397.     else write(textptr,buff,strlen(buff));
  398.     write(textptr,"\0",1);
  399.  
  400.     lseek(textptr,xmsg->start,SEEK_SET);
  401.     locking(textptr,LK_UNLCK,65535L);
  402.  
  403.     tt = time(NULL);
  404.     t = localtime(&tt);
  405.     xmsg->indate[0] = (char)(t->tm_year - 89);
  406.     xmsg->indate[1] = (char)(t->tm_mon + 1);
  407.     xmsg->indate[2] = (char)t->tm_mday;
  408.     xmsg->indate[3] = 0;
  409.  
  410.     x = 0;
  411.     while(x < 50) {
  412.         if(lseek(dataptr,0L,SEEK_END) != -1L) break;
  413.         DosSleep(100L);
  414.         x++;
  415.     }
  416.     if(x >= 50) {
  417.         printf("\nLocking conflict; can't import msg\n");
  418.         return -1;
  419.     }
  420.     locking(dataptr,LK_LOCK,(long)sizeof(XMSG));
  421.     pos = tell(dataptr);
  422.     write(dataptr,xmsg,sizeof(XMSG));
  423.     lseek(dataptr,pos,SEEK_SET);
  424.     locking(dataptr,LK_UNLCK,(long)sizeof(XMSG));
  425.  
  426.     return 0;
  427. }
  428.  
  429.  
  430.  
  431.  
  432. int _fastcall get_msg (word buflen,char *buff,char **text,int fp,XMSG *xmsg) {
  433.  
  434.     char *p,*pathline,*seenby,*area,*kludge,*endptr,*tempo,*origin;
  435.     long pos;
  436.     word len,*temp,chk;
  437.  
  438.  
  439. Again:
  440.  
  441.     memset(xmsg,0,sizeof(XMSG));
  442.     *to_domain = 0;
  443.     *from_domain = 0;
  444.     if(eof(fp)) return -2;
  445.     pos = tell(fp);
  446.     chk = read(fp,buff,buflen);
  447.     if(!chk || chk == 65535U) return -2;
  448.     buff[buflen] = 0;
  449.     p = buff;
  450.     if(*p != '\02' || p[1] != '\0') {
  451.         if(eof(fp) || (*p == '\0' && p[1] == '\0')) return -2;
  452.         while(*p != '\02' && p < (buff + buflen)) {
  453.             p++;
  454.             pos++;
  455.         }
  456.         lseek(fp,pos,SEEK_SET);
  457.         goto Again;
  458.     }
  459.     p += 2;
  460.     temp = (word *)p;
  461.     xmsg->orig = *temp;
  462.     p += 2;
  463.     temp = (word *)p;
  464.     xmsg->dest = *temp;
  465.     p += 2;
  466.     temp = (word *)p;
  467.     xmsg->orig_net = *temp;
  468.     p += 2;
  469.     temp = (word *)p;
  470.     xmsg->dest_net = *temp;
  471.     p += 2;
  472.     temp = (word *)p;
  473.     xmsg->attr = *temp;
  474.     p += 2;
  475.     xmsg->cost = 0;
  476.     p += 2;
  477.     strncpy(xmsg->date,p,20);
  478.     xmsg->date[19] = 0;
  479.     while(*p) p++;   /* <--This goddamn kludge thanks to QMail, the broken wonder */
  480.     p++;
  481.     strncpy(xmsg->to,p,36);
  482.     xmsg->to[35] = 0;
  483.     while(*p) p++;
  484.     p++;
  485.     strncpy(xmsg->from,p,36);
  486.     xmsg->from[35] = 0;
  487.     while(*p) p++;
  488.     p++;
  489.     strncpy(xmsg->subj,p,64);
  490.     xmsg->subj[63] = 0;
  491.     while(*p) p++;
  492.     p++;
  493.     *text = p;
  494.     while(*p) p++;
  495.     p++;                            /* Should be start of next msg */
  496.     endptr = p;
  497.     pos += (long)(endptr-buff);
  498.     lseek(fp,pos,SEEK_SET);            /* Now positioned to start of next msg */
  499.     if(!*xmsg->to && !*xmsg->from && !*xmsg->subj) {    /* grunged msg */
  500.         return -3;
  501.     }
  502.     len = strlen(*text);
  503.     if(!len) {                          /* grunged msg (no text) */
  504.         return -3;
  505.     }
  506.  
  507.     p = *text;
  508.     while (*p) {    /* Strip linefeeds and soft cr's FAST */
  509.         if(*p == '\x8d' || *p == '\n') {
  510.             memmove(p,&p[1],len - (word)((long)p - (long)*text));
  511.             len--;
  512.             if(!len) break;
  513.             continue;
  514.         }
  515.         p++;
  516.     }
  517.  
  518.     if(!strnicmp(*text,"AREA:",5)) { /* Echo area tag */
  519.         area = *text;
  520.         while(**text && **text != '\r') {
  521.             (*text)++;
  522.         }
  523.         if(**text) {
  524.             **text = 0;          /* area now = area tag line */
  525.             (*text)++;           /* text = true start of msg body if any */
  526.         }
  527.         while(**text == '\r' && **text) (*text)++; /* Skip leading cr's in body */
  528.         area += 5;
  529.         lstrip(area);
  530.         rstrip(area);                    /* Points directly to tag */
  531.     }
  532.     else area = NULL;
  533.  
  534.     if (area) {             /* Do ECHO specific BS */
  535.         origin = NULL;
  536.         pathline = NULL;
  537.         seenby = NULL;
  538.         kludge = NULL;
  539.         tempo = *text;     /* They oughta outlaw EID's */
  540.         while ((tempo = strstr(tempo,"\01EID:")))
  541.           memmove(tempo,strchr(&tempo[1],'\r'),strlen(strchr(&tempo[1],'\r'))+1);
  542.         while(**text == '\r' && **text) (*text)++; /* Skip leading cr's in body */
  543.         if(!strncmp(*text," * Origin: ",11)) **text = 0;    /* Nothin' but origin */
  544.         origin = strstr(*text,"\r * Origin:");     /* Find the origin line */
  545.         if (origin) {        /* Ain't one; oh, well, screw it */
  546.             while(tempo = strstr(&origin[1],"\r * Origin:")) origin = tempo; /* Find last */
  547.             pathline = strstr(origin,"\r\01PATH:");   /* Find the PATH line */
  548.             seenby = strstr(origin,"\rSEEN-BY:"); /* Find start of SEEN-BYs */
  549.             if (!seenby) seenby = strstr(origin,"\r\01SEEN-BY:");
  550.             if(pathline) {
  551.                 *pathline = 0;
  552.                 pathline = NULL;
  553.             }
  554.             else {
  555.                 if (seenby) {
  556.                     *seenby = 0;  /* Mercifully kill SEEN-BYs */
  557.                     seenby = NULL;
  558.                 }
  559.             }
  560.         }
  561.         if (*text[strlen(*text)-1] != '\r') strcat(*text,"\r");  /* Assure trailing cr for appearance */
  562.         xmsg->attr |= MSGORPHAN;     /* Orphan stripped msgs so they never go back out */
  563.     }
  564.  
  565.     {        /* Fill in header address info from kludges */
  566.  
  567.         char message[MAXKLUDGE];
  568.  
  569.         if ((p = strstr(*text,"\01FMPT "))) {
  570.             strncpy(message,p,MAXKLUDGE);
  571.             message[MAXKLUDGE-1] = 0;
  572.             p = message;
  573.             xmsg->o_point = (word)atol(&p[5]);
  574.         }
  575.         if ((p = strstr(*text,"\01INTL "))) {
  576.             strncpy(message,p,MAXKLUDGE);
  577.             message[MAXKLUDGE-1]=0;
  578.             p = message;
  579.             strtok(p," :");
  580.             strtok(0," ");
  581.             tempo = strtok(0,":");
  582.             if(tempo) if((word)atol(tempo)) xmsg->o_zone = (word)atol(tempo);
  583.         }
  584.  
  585.         if((p = strstr(*text,"\01MSGID: "))) {
  586.             if((p - 1) < *text || *(p - 1) == '\r') {
  587.  
  588.                 ADDR addr;
  589.  
  590.                 memset(&addr,0,sizeof(ADDR));
  591.                 addr.domain = NULL;
  592.                 p += 8;
  593.                 p = skip_white(p);
  594.                 if(!parse_addr(&p,&addr,myaddr)) {
  595.                     if(!addr.zone || !addr.net || !*addr.domain) {
  596.                         guess_rest(&addr,myaddr);
  597.                     }
  598.                     xmsg->o_zone   = addr.zone;
  599.                     xmsg->orig_net = addr.net;
  600.                     xmsg->orig     = addr.node;
  601.                     xmsg->o_point  = addr.point;
  602.                     strncpy(from_domain,addr.domain,38);
  603.                     from_domain[38] = 0;
  604.                     p = strchr(from_domain,'.');
  605.                     if(p) *p = 0;
  606.                     my_free(addr.domain);
  607.                 }
  608.             }
  609.         }
  610.  
  611.         if((p = strstr(*text,"\01MSGTO: "))) {
  612.             if((p - 1) < *text || *(p - 1) == '\r') {
  613.  
  614.                 ADDR addr;
  615.  
  616.                 memset(&addr,0,sizeof(ADDR));
  617.                 addr.domain = NULL;
  618.                 p += 8;
  619.                 p = skip_white(p);
  620.                 if(!parse_addr(&p,&addr,myaddr)) {
  621.                     if(!addr.zone || !addr.net || !*addr.domain) {
  622.                         guess_rest(&addr,myaddr);
  623.                     }
  624.                     xmsg->d_zone   = addr.zone;
  625.                     xmsg->dest_net = addr.net;
  626.                     xmsg->dest     = addr.node;
  627.                     xmsg->d_point  = addr.point;
  628.                     strncpy(to_domain,addr.domain,38);
  629.                     to_domain[38] = 0;
  630.                     p = strchr(to_domain,'.');
  631.                     if(p) *p = 0;
  632.                     my_free(addr.domain);
  633.                 }
  634.             }
  635.         }
  636.     }
  637.  
  638.     p = *text + (strlen(*text) - 1);    /* strip trailing blank lines */
  639.     while(*p == '\r' && p > *text && *(p-1) == '\r') {
  640.         *p = 0;
  641.         p--;
  642.     }
  643.  
  644.     xmsg->length = strlen(*text);
  645.     if(area) xmsg->m_attr |= MSGECHO;        /* Is echo */
  646.     else xmsg->m_attr |= MSGNET;             /* Is net  */
  647.     xmsg->attr &= (~MSGLOCAL);               /* Isn't local! */
  648.     xmsg->attr |= MSGORPHAN;                 /* NEVER reexport */
  649.     return 0;
  650. }
  651.  
  652.  
  653.  
  654. int _fastcall ext_reserved (char *ext) {
  655.  
  656.     static char res_ext[][4] = {
  657.         "ARC","ZIP","FLE","TIC","PAK","PKA","LZH","ZOO","DWC","PKT",
  658.         "ARJ","COM","EXE","BIN","SYS","TXT","DOC","LST","DAT","DBF",
  659.         "IDX","!","INI","CTL","CFG","MAP","INF","HLP","OVL","MSG",
  660.                 "OUT","HUT","DUT","NUT","DB","C","ASM","BAK",""
  661.     };
  662.     register int x = 0;
  663.  
  664.  
  665.     while(*res_ext[x]) {
  666.         if(!stricmp(ext,res_ext[x])) return -1;
  667.         x++;
  668.     }
  669.     return 0;
  670. }
  671.