home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / FIDO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-13  |  21.7 KB  |  813 lines

  1. #line 1 "FIDO.C"
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
  4.  
  5. /*********************************************/
  6. /* Functions that pertain solely to FidoNet  */
  7. /*********************************************/
  8.  
  9. #include "sbbs.h"
  10.  
  11. extern char *mon[];
  12. void inetmail(char *into, char *subj, char mode);
  13. void qnetmail(char *into, char *subj, char mode);
  14. int qwk_route(char *inaddr, char *fulladdr);
  15.  
  16. void pt_zone_kludge(fmsghdr_t hdr,int fido)
  17. {
  18.     char str[256];
  19.  
  20. sprintf(str,"\1INTL %u:%u/%u %u:%u/%u\r"
  21.     ,hdr.destzone,hdr.destnet,hdr.destnode
  22.     ,hdr.origzone,hdr.orignet,hdr.orignode);
  23. write(fido,str,strlen(str));
  24.  
  25. if(hdr.destpoint) {
  26.     sprintf(str,"\1TOPT %u\r"
  27.         ,hdr.destpoint);
  28.     write(fido,str,strlen(str)); }
  29.  
  30. if(hdr.origpoint) {
  31.     sprintf(str,"\1FMPT %u\r"
  32.         ,hdr.origpoint);
  33.     write(fido,str,strlen(str)); }
  34. }
  35.  
  36. int lookup_netuser(char *into)
  37. {
  38.     char to[128],name[26],str[256],q[128];
  39.     int i;
  40.     FILE *stream;
  41.  
  42. if(strchr(into,'@'))
  43.     return(0);
  44. strcpy(to,into);
  45. strupr(to);
  46. sprintf(str,"%sQNET\\USERS.DAT",data_dir);
  47. if((stream=fnopen(&i,str,O_RDONLY))==NULL)
  48.     return(0);
  49. while(!feof(stream)) {
  50.     if(!fgets(str,250,stream))
  51.         break;
  52.     str[25]=0;
  53.     truncsp(str);
  54.     strcpy(name,str);
  55.     strupr(name);
  56.     str[35]=0;
  57.     truncsp(str+27);
  58.     sprintf(q,"Do you mean %s @%s",str,str+27);
  59.     if(strstr(name,to) && yesno(q)) {
  60.         fclose(stream);
  61.         sprintf(into,"%s@%s",str,str+27);
  62.         return(0); }
  63.     if(sys_status&SS_ABORT)
  64.         break; }
  65. fclose(stream);
  66. return(1);
  67. }
  68.  
  69. /****************************************************************************/
  70. /* Send FidoNet NetMail from BBS                                            */
  71. /****************************************************************************/
  72. void netmail(char *into, char *title, char mode)
  73. {
  74.     char str[256],subj[128],to[256],fname[128],*buf,*p,ch;
  75.     int file,fido,x,cc_found,cc_sent;
  76.     uint i;
  77.     long length,l;
  78.     faddr_t addr;
  79.     fmsghdr_t hdr;
  80.  
  81. sprintf(subj,"%.127s",title);
  82.  
  83.  
  84. strcpy(to,into);
  85.  
  86. lookup_netuser(to);
  87.  
  88. p=strrchr(to,'@');      /* Find '@' in name@addr */
  89. if(p && !isdigit(*(p+1)) && !strchr(p,'.') && !strchr(p,':')) {
  90.     mode&=~WM_FILE;
  91.     qnetmail(to,title,mode|WM_NETMAIL);
  92.     return; }
  93. if(p==NULL || !strchr(p+1,'/') || !total_faddrs) {
  94.     if(!p && dflt_faddr.zone)
  95.         addr=dflt_faddr;
  96.     else if(inetmail_misc&NMAIL_ALLOW) {
  97.         if(mode&WM_FILE && !SYSOP && !(inetmail_misc&NMAIL_FILE))
  98.             mode&=~WM_FILE;
  99.         inetmail(into,title,mode|WM_NETMAIL);
  100.         return; }
  101.     else if(dflt_faddr.zone)
  102.         addr=dflt_faddr;
  103.     else {
  104.         bprintf("\1n\r\nInvalid NetMail address.\r\n");
  105.         return; } }
  106. else {
  107.     addr=atofaddr(p+1);     /* Get fido address */
  108.     *p=0;                    /* Chop off address */
  109.     }
  110.  
  111. if(mode&WM_FILE && !SYSOP && !(netmail_misc&NMAIL_FILE))
  112.     mode&=~WM_FILE;
  113.  
  114. if((!SYSOP && !(netmail_misc&NMAIL_ALLOW)) || useron.rest&FLAG('M')
  115.     || !total_faddrs) {
  116.     bputs(text[NoNetMailAllowed]);
  117.     return; }
  118.  
  119. truncsp(to);                /* Truncate off space */
  120.  
  121. memset(&hdr,0,sizeof(hdr));   /* Initialize header to null */
  122. strcpy(hdr.from,netmail_misc&NMAIL_ALIAS ? useron.alias : useron.name);
  123. sprintf(hdr.to,"%.35s",to);
  124.  
  125. /* Look-up in nodelist? */
  126.  
  127. if(netmail_cost && !(useron.exempt&FLAG('S'))) {
  128.     if(useron.cdt+useron.freecdt<netmail_cost) {
  129.         bputs(text[NotEnoughCredits]);
  130.         return; }
  131.     sprintf(str,text[NetMailCostContinueQ],netmail_cost);
  132.     if(noyes(str))
  133.         return; }
  134.  
  135.  
  136. now=time(NULL);
  137. unixtodos(now,&date,&curtime);
  138. sprintf(hdr.time,"%02u %3.3s %02u  %02u:%02u:%02u"
  139.     ,date.da_day,mon[date.da_mon-1],date.da_year-1900
  140.     ,curtime.ti_hour,curtime.ti_min,curtime.ti_sec);
  141.  
  142. hdr.destzone    =addr.zone;
  143. hdr.destnet     =addr.net;
  144. hdr.destnode    =addr.node;
  145. hdr.destpoint    =addr.point;
  146.  
  147. for(i=0;i<total_faddrs;i++)
  148.     if(addr.zone==faddr[i].zone && addr.net==faddr[i].net)
  149.         break;
  150. if(i==total_faddrs) {
  151.     for(i=0;i<total_faddrs;i++)
  152.         if(addr.zone==faddr[i].zone)
  153.             break; }
  154. if(i==total_faddrs)
  155.     i=0;
  156. hdr.origzone    =faddr[i].zone;
  157. hdr.orignet     =faddr[i].net;
  158. hdr.orignode    =faddr[i].node;
  159. hdr.origpoint    =faddr[i].point;
  160.  
  161. strcpy(str,faddrtoa(faddr[i]));
  162. bprintf(text[NetMailing],hdr.to,faddrtoa(addr),hdr.from,str);
  163.  
  164. hdr.attr=(FIDO_LOCAL|FIDO_PRIVATE);
  165.  
  166. if(netmail_misc&NMAIL_CRASH) hdr.attr|=FIDO_CRASH;
  167. if(netmail_misc&NMAIL_HOLD)  hdr.attr|=FIDO_HOLD;
  168. if(netmail_misc&NMAIL_KILL)  hdr.attr|=FIDO_KILLSENT;
  169. if(mode&WM_FILE) hdr.attr|=FIDO_FILE;
  170.  
  171. sprintf(str,"%sNETMAIL.MSG",node_dir);
  172. remove(str);    /* Just incase it's already there */
  173. // mode&=~WM_FILE;
  174. if(!writemsg(str,nulstr,subj,WM_NETMAIL|mode,INVALID_SUB,into)) {
  175.     bputs(text[Aborted]);
  176.     return; }
  177.  
  178. if(mode&WM_FILE) {
  179.     strcpy(fname,subj);
  180.     sprintf(str,"%sFILE\\%04u.OUT",data_dir,useron.number);
  181.     mkdir(str);
  182.     strcpy(tmp,data_dir);
  183.     if(tmp[0]=='.')    /* Relative path */
  184.         sprintf(tmp,"%s%s",node_dir,data_dir);
  185.     sprintf(str,"%sFILE\\%04u.OUT\\%s",tmp,useron.number,fname);
  186.     strcpy(subj,str);
  187.     if(fexist(str)) {
  188.         bputs(text[FileAlreadyThere]);
  189.         return; }
  190.     if(online==ON_LOCAL) {        /* Local upload */
  191.         bputs(text[EnterPath]);
  192.         if(!getstr(str,60,K_LINE|K_UPPER)) {
  193.             bputs(text[Aborted]);
  194.             return; }
  195.         backslash(str);
  196.         strcat(str,fname);
  197.         if(mv(str,subj,1))
  198.             return; }
  199.     else { /* Remote */
  200.         menu("ULPROT");
  201.         mnemonics(text[ProtocolOrQuit]);
  202.         strcpy(str,"Q");
  203.         for(x=0;x<total_prots;x++)
  204.             if(prot[x]->ulcmd[0] && chk_ar(prot[x]->ar,useron)) {
  205.                 sprintf(tmp,"%c",prot[x]->mnemonic);
  206.                 strcat(str,tmp); }
  207.         ch=getkeys(str,0);
  208.         if(ch=='Q' || sys_status&SS_ABORT) {
  209.             bputs(text[Aborted]);
  210.             return; }
  211.         for(x=0;x<total_prots;x++)
  212.             if(prot[x]->ulcmd[0] && prot[x]->mnemonic==ch
  213.                 && chk_ar(prot[x]->ar,useron))
  214.                 break;
  215.         if(x<total_prots)    /* This should be always */
  216.             protocol(cmdstr(prot[x]->ulcmd,subj,nulstr,NULL),0); }
  217.     l=flength(subj);
  218.     if(l>0)
  219.         bprintf(text[FileNBytesReceived],fname,ultoac(l,tmp));
  220.     else {
  221.         bprintf(text[FileNotReceived],fname);
  222.         return; } }
  223.  
  224. p=subj;
  225. if((SYSOP || useron.exempt&FLAG('F'))
  226.     && !strncmpi(p,"CR:",3)) {     /* Crash over-ride by sysop */
  227.     p+=3;                /* skip CR: */
  228.     if(*p==SP) p++;     /* skip extra space if it exists */
  229.     hdr.attr|=FIDO_CRASH; }
  230.  
  231. if((SYSOP || useron.exempt&FLAG('F'))
  232.     && !strncmpi(p,"FR:",3)) {     /* File request */
  233.     p+=3;                /* skip FR: */
  234.     if(*p==SP) p++;
  235.     hdr.attr|=FIDO_FREQ; }
  236.  
  237. if((SYSOP || useron.exempt&FLAG('F'))
  238.     && !strncmpi(p,"RR:",3)) {     /* Return receipt request */
  239.     p+=3;                /* skip RR: */
  240.     if(*p==SP) p++;
  241.     hdr.attr|=FIDO_RRREQ; }
  242.  
  243. if((SYSOP || useron.exempt&FLAG('F'))
  244.     && !strncmpi(p,"FA:",3)) {     /* File Attachment */
  245.     p+=3;                /* skip FA: */
  246.     if(*p==SP) p++;
  247.     hdr.attr|=FIDO_FILE; }
  248.  
  249. sprintf(hdr.subj,"%.71s",p);
  250.  
  251. sprintf(str,"%sNETMAIL.MSG",node_dir);
  252. if((file=nopen(str,O_RDONLY))==-1) {
  253.     close(fido);
  254.     errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
  255.     return; }
  256. length=filelength(file);
  257. if((buf=(char *)MALLOC(length))==NULL) {
  258.     close(fido);
  259.     close(file);
  260.     errormsg(WHERE,ERR_ALLOC,str,length);
  261.     return; }
  262. read(file,buf,length);
  263. close(file);
  264.  
  265. cc_sent=0;
  266. while(1) {
  267.     for(i=1;i;i++) {
  268.         sprintf(str,"%s%u.MSG",netmail_dir,i);
  269.         if(!fexist(str))
  270.             break; }
  271.     if(!i) {
  272.         bputs(text[TooManyEmailsToday]);
  273.         return; }
  274.     if((fido=nopen(str,O_WRONLY|O_CREAT|O_EXCL))==-1) {
  275.         errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_EXCL);
  276.         return; }
  277.     write(fido,&hdr,sizeof(hdr));
  278.  
  279.     pt_zone_kludge(hdr,fido);
  280.  
  281.     if(netmail_misc&NMAIL_DIRECT) {
  282.         sprintf(str,"\1FLAGS DIR\r\n");
  283.         write(fido,str,strlen(str)); }
  284.     if(mode&WM_FILE) {
  285.         sprintf(str,"\1FLAGS KFS\r\n");
  286.         write(fido,str,strlen(str)); }
  287.  
  288.     if(cc_sent) {
  289.         sprintf(str,"* Originally to: %s\r\n\r\n",into);
  290.         write(fido,str,strlen(str)); }
  291.  
  292.     l=0L;
  293.     while(l<length) {
  294.         if(buf[l]==1)    /* Ctrl-A, so skip it and the next char */
  295.             l++;
  296.         else if(buf[l]!=LF) {
  297.             if((uchar)buf[l]==0x8d)   /* r0dent i converted to normal i */
  298.                 buf[l]='i';
  299.             write(fido,buf+l,1); }
  300.         l++; }
  301.     l=0;
  302.     write(fido,&l,1);    /* Null terminator */
  303.     close(fido);
  304.  
  305.     if(!(useron.exempt&FLAG('S')))
  306.         subtract_cdt(netmail_cost);
  307.     if(mode&WM_FILE)
  308.         sprintf(str,"Sent NetMail file attachment to %s (%s)"
  309.             ,hdr.to,faddrtoa(addr));
  310.     else
  311.         sprintf(str,"Sent NetMail to %s (%s)"
  312.             ,hdr.to,faddrtoa(addr));
  313.     logline("EN",str);
  314.  
  315.     cc_found=0;
  316.     for(l=0;l<length && cc_found<=cc_sent;l++)
  317.         if(l+3<length && !strnicmp(buf+l,"CC:",3)) {
  318.             cc_found++;
  319.             l+=2; }
  320.         else {
  321.             while(l<length && *(buf+l)!=LF)
  322.                 l++; }
  323.     if(!cc_found)
  324.         break;
  325.     while(l<length && *(buf+l)==SP) l++;
  326.     for(i=0;l<length && *(buf+l)!=LF && i<128;i++,l++)
  327.         str[i]=buf[l];
  328.     if(!i)
  329.         break;
  330.     str[i]=0;
  331.     p=strrchr(str,'@');
  332.     if(p) {
  333.         addr=atofaddr(p+1);
  334.         *p=0;
  335.         sprintf(hdr.to,"%.35s",str); }
  336.     else {
  337.         atofaddr(str);
  338.         strcpy(hdr.to,"Sysop"); }
  339.     hdr.destzone    =addr.zone;
  340.     hdr.destnet     =addr.net;
  341.     hdr.destnode    =addr.node;
  342.     hdr.destpoint    =addr.point;
  343.     cc_sent++; }
  344.  
  345. if(netmail_sem[0])        /* update semaphore file */
  346.     if((file=nopen(netmail_sem,O_WRONLY|O_CREAT|O_TRUNC))!=-1)
  347.         close(file);
  348.  
  349. FREE(buf);
  350. }
  351.  
  352. /****************************************************************************/
  353. /* Send FidoNet NetMail from QWK REP Packet                                 */
  354. /****************************************************************************/
  355. void qwktonetmail(FILE *rep, char *block, char *into, uchar fromhub)
  356. {
  357.     char    HUGE16 *qwkbuf,to[129],name[129],sender[129],senderaddr[129]
  358.            ,str[256],*p,*cp,*addr,fulladdr[129],ch,buf[SDT_BLOCK_LEN];
  359.     int     i,fido,inet=0,qnet=0,x;
  360.     ushort    net,xlat;
  361.     long    l,offset,length,m,n;
  362.     faddr_t fidoaddr;
  363.     fmsghdr_t hdr;
  364.     smbmsg_t msg;
  365.  
  366. if(useron.rest&FLAG('M')) {
  367.     bputs(text[NoNetMailAllowed]);
  368.     return; }
  369.  
  370. sprintf(str,"%.6s",block+116);
  371. n=atol(str);      /* i = number of 128 byte records */
  372.  
  373. if(n<2L || n>999999L) {
  374.     errormsg(WHERE,ERR_CHK,"QWK blocks",n);
  375.     return; }
  376. if((qwkbuf=MALLOC(n*128L))==NULL) {
  377.     errormsg(WHERE,ERR_ALLOC,nulstr,n*128L);
  378.     return; }
  379. memcpy((char *)qwkbuf,block,128);
  380. fread(qwkbuf+128,n-1,128,rep);
  381.  
  382. if(into==NULL)
  383.     sprintf(to,"%-128.128s",(char *)qwkbuf+128);  /* To user on first line */
  384. else
  385.     strcpy(to,into);
  386.  
  387. p=strchr(to,0xe3);        /* chop off at first CR */
  388. if(p) *p=0;
  389.  
  390. strcpy(name,to);
  391. p=strchr(name,'@');
  392. if(p) *p=0;
  393. truncsp(name);
  394.  
  395.  
  396. p=strrchr(to,'@');       /* Find '@' in name@addr */
  397. if(p && !isdigit(*(p+1)) && !strchr(p,'.') && !strchr(p,':')) { /* QWKnet */
  398.     qnet=1;
  399.     *p=0; }
  400. else if(p==NULL || !isdigit(*(p+1)) || !total_faddrs) {
  401.     if(p==NULL && dflt_faddr.zone)
  402.         fidoaddr=dflt_faddr;
  403.     else if(inetmail_misc&NMAIL_ALLOW) {    /* Internet */
  404.         inet=1;
  405. /*
  406.         if(p)
  407.             *p=0;                /* Chop off address */
  408. */
  409.         }
  410.     else if(dflt_faddr.zone)
  411.         fidoaddr=dflt_faddr;
  412.     else {
  413.         bprintf("\1n\r\nInvalid NetMail address.\r\n");
  414.         FREE(qwkbuf);
  415.         return; } }
  416. else {
  417.     fidoaddr=atofaddr(p+1);     /* Get fido address */
  418.     *p=0;                    /* Chop off address */
  419.     }
  420.  
  421.  
  422. if(!inet && !qnet &&        /* FidoNet */
  423.     ((!SYSOP && !(netmail_misc&NMAIL_ALLOW)) || !total_faddrs)) {
  424.     bputs(text[NoNetMailAllowed]);
  425.     FREE(qwkbuf);
  426.     return; }
  427.  
  428. truncsp(to);            /* Truncate off space */
  429.  
  430. if(!stricmp(to,"SBBS") && !SYSOP && qnet) {
  431.     FREE(qwkbuf);
  432.     return; }
  433.  
  434. l=128;                    /* Start of message text */
  435.  
  436. if(qnet || inet) {
  437.  
  438.     if(into==NULL) {      /* If name@addr on first line, skip first line */
  439.         while(l<(n*128L) && (uchar)qwkbuf[l]!=0xe3) l++;
  440.         l++; }
  441.  
  442.     memset(&msg,0,sizeof(smbmsg_t));
  443.     memcpy(msg.hdr.id,"SHD\x1a",4);
  444.     msg.hdr.version=SMB_VERSION;
  445.     msg.hdr.when_imported.time=time(NULL);
  446.     msg.hdr.when_imported.zone=sys_timezone;
  447.  
  448.     if(fromhub || useron.rest&FLAG('Q')) {
  449.         net=NET_QWK;
  450.         smb_hfield(&msg,SENDERNETTYPE,sizeof(net),&net);
  451.         if(!strncmp((uchar *)qwkbuf+l,"@VIA:",5)) {
  452.             sprintf(str,"%.128s",qwkbuf+l+5);
  453.             cp=strchr(str,0xe3);
  454.             if(cp) *cp=0;
  455.             l+=strlen(str)+1;
  456.             cp=str;
  457.             while(*cp && *cp<=SP) cp++;
  458.             sprintf(senderaddr,"%s/%s"
  459.                 ,fromhub ? qhub[fromhub-1]->id : useron.alias,cp);
  460.             strupr(senderaddr);
  461.             smb_hfield(&msg,SENDERNETADDR,strlen(senderaddr),senderaddr); }
  462.         else {
  463.             if(fromhub)
  464.                 strcpy(senderaddr,qhub[fromhub-1]->id);
  465.             else
  466.                 strcpy(senderaddr,useron.alias);
  467.             strupr(senderaddr);
  468.             smb_hfield(&msg,SENDERNETADDR,strlen(senderaddr),senderaddr); }
  469.         sprintf(sender,"%.25s",block+46); }    /* From name */
  470.     else {    /* Not Networked */
  471.         msg.hdr.when_written.zone=sys_timezone;
  472.         sprintf(str,"%u",useron.number);
  473.         smb_hfield(&msg,SENDEREXT,strlen(str),str);
  474.         strcpy(sender,(qnet || inetmail_misc&NMAIL_ALIAS)
  475.             ? useron.alias : useron.name);
  476.         }
  477.     truncsp(sender);
  478.     smb_hfield(&msg,SENDER,strlen(sender),sender);
  479.     if(fromhub)
  480.         msg.idx.from=0;
  481.     else
  482.         msg.idx.from=useron.number;
  483.     if(!strncmp((uchar *)qwkbuf+l,"@TZ:",4)) {
  484.         sprintf(str,"%.128s",qwkbuf+l);
  485.         cp=strchr(str,0xe3);
  486.         if(cp) *cp=0;
  487.         l+=strlen(str)+1;
  488.         cp=str+4;
  489.         while(*cp && *cp<=SP) cp++;
  490.         msg.hdr.when_written.zone=(short)ahtoul(cp); }
  491.     else
  492.         msg.hdr.when_written.zone=sys_timezone;
  493.  
  494.     date.da_mon=((qwkbuf[8]&0xf)*10)+(qwkbuf[9]&0xf);
  495.     date.da_day=((qwkbuf[11]&0xf)*10)+(qwkbuf[12]&0xf);
  496.     date.da_year=((qwkbuf[14]&0xf)*10)+(qwkbuf[15]&0xf)+1900;
  497.     curtime.ti_hour=((qwkbuf[16]&0xf)*10)+(qwkbuf[17]&0xf);
  498.     curtime.ti_min=((qwkbuf[19]&0xf)*10)+(qwkbuf[20]&0xf);  /* From QWK time */
  499.     curtime.ti_sec=0;
  500.  
  501.     msg.hdr.when_written.time=dostounix(&date,&curtime);
  502.  
  503.     sprintf(str,"%.25s",block+71);              /* Title */
  504.     smb_hfield(&msg,SUBJECT,strlen(str),str);
  505.     strlwr(str);
  506.     msg.idx.subj=crc16(str); }
  507.  
  508. if(qnet) {
  509.  
  510.     p++;
  511.     addr=p;
  512.     msg.idx.to=qwk_route(addr,fulladdr);
  513.     if(!fulladdr[0]) {        /* Invalid address, so BOUNCE it */
  514.     /**
  515.         errormsg(WHERE,ERR_CHK,addr,0);
  516.         FREE(qwkbuf);
  517.         smb_freemsgmem(msg);
  518.         return;
  519.     **/
  520.         smb_hfield(&msg,SENDER,strlen(sys_id),sys_id);
  521.         msg.idx.from=0;
  522.         msg.idx.to=useron.number;
  523.         strcpy(to,sender);
  524.         strcpy(fulladdr,senderaddr);
  525.         sprintf(str,"BADADDR: %s",addr);
  526.         smb_hfield(&msg,SUBJECT,strlen(str),str);
  527.         strlwr(str);
  528.         msg.idx.subj=crc16(str);
  529.         net=NET_NONE;
  530.         smb_hfield(&msg,SENDERNETTYPE,sizeof(net),&net);
  531.     }
  532.  
  533.     smb_hfield(&msg,RECIPIENT,strlen(name),name);
  534.     net=NET_QWK;
  535.     smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net);
  536.  
  537.     truncsp(fulladdr);
  538.     smb_hfield(&msg,RECIPIENTNETADDR,strlen(fulladdr),fulladdr);
  539.  
  540.     bprintf(text[NetMailing],to,fulladdr,sender,sys_id); }
  541.  
  542. if(inet) {                /* Internet E-mail */
  543.  
  544.     if(inetmail_cost && !(useron.exempt&FLAG('S'))) {
  545.         if(useron.cdt+useron.freecdt<inetmail_cost) {
  546.             bputs(text[NotEnoughCredits]);
  547.             FREE(qwkbuf);
  548.             smb_freemsgmem(&msg);
  549.             return; }
  550.         sprintf(str,text[NetMailCostContinueQ],inetmail_cost);
  551.         if(noyes(str)) {
  552.             FREE(qwkbuf);
  553.             smb_freemsgmem(&msg);
  554.             return; } }
  555.  
  556.     net=NET_INTERNET;
  557.     smb_hfield(&msg,RECIPIENT,strlen(name),name);
  558.     msg.idx.to=0;   /* Out-bound NetMail set to 0 */
  559.     smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net);
  560.     smb_hfield(&msg,RECIPIENTNETADDR,strlen(to),to);
  561.  
  562.     bprintf(text[NetMailing],name,to
  563.         ,inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name
  564.         ,sys_inetaddr); }
  565.  
  566. if(qnet || inet) {
  567.  
  568.     bputs(text[WritingIndx]);
  569.  
  570.     if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) {
  571.         errormsg(WHERE,ERR_OPEN,"MAIL",i);
  572.         FREE(qwkbuf);
  573.         smb_freemsgmem(&msg);
  574.         return; }
  575.     sprintf(smb.file,"%sMAIL",data_dir);
  576.     smb.retry_time=smb_retry_time;
  577.     if((i=smb_open(&smb))!=0) {
  578.         smb_stack(&smb,SMB_STACK_POP);
  579.         errormsg(WHERE,ERR_OPEN,smb.file,i);
  580.         FREE(qwkbuf);
  581.         smb_freemsgmem(&msg);
  582.         return; }
  583.  
  584.     if(filelength(fileno(smb.shd_fp))<1L) {   /* Create it if it doesn't exist */
  585.         smb.status.max_crcs=mail_maxcrcs;
  586.         smb.status.max_msgs=MAX_SYSMAIL;
  587.         smb.status.max_age=mail_maxage;
  588.         smb.status.attr=SMB_EMAIL;
  589.         if((i=smb_create(&smb))!=0) {
  590.             smb_close(&smb);
  591.             smb_stack(&smb,SMB_STACK_POP);
  592.             errormsg(WHERE,ERR_CREATE,smb.file,i);
  593.             FREE(qwkbuf);
  594.             smb_freemsgmem(&msg);
  595.             return; } }
  596.  
  597.     length=n*256L;    // Extra big for CRLF xlat, was (n-1L)*256L (03/16/96)
  598.  
  599.  
  600.     if(length&0xfff00000UL || !length) {
  601.         smb_close(&smb);
  602.         smb_stack(&smb,SMB_STACK_POP);
  603.         sprintf(str,"REP msg (%ld)",n);
  604.         errormsg(WHERE,ERR_LEN,str,length);
  605.         FREE(qwkbuf);
  606.         smb_freemsgmem(&msg);
  607.         return; }
  608.  
  609.     if((i=smb_open_da(&smb))!=0) {
  610.         smb_close(&smb);
  611.         smb_stack(&smb,SMB_STACK_POP);
  612.         errormsg(WHERE,ERR_OPEN,smb.file,i);
  613.         FREE(qwkbuf);
  614.         smb_freemsgmem(&msg);
  615.         return; }
  616.     if(sys_misc&SM_FASTMAIL)
  617.         offset=smb_fallocdat(&smb,length,1);
  618.     else
  619.         offset=smb_allocdat(&smb,length,1);
  620.     smb_close_da(&smb);
  621.  
  622.     fseek(smb.sdt_fp,offset,SEEK_SET);
  623.     xlat=XLAT_NONE;
  624.     fwrite(&xlat,2,1,smb.sdt_fp);
  625.     m=2;
  626.     for(;l<n*128L && m<length;l++) {
  627.         if(qwkbuf[l]==0 || qwkbuf[l]==LF)
  628.             continue;
  629.         if((uchar)qwkbuf[l]==0xe3) {
  630.             fwrite(crlf,2,1,smb.sdt_fp);
  631.             m+=2;
  632.             continue; }
  633.         fputc(qwkbuf[l],smb.sdt_fp);
  634.         m++; }
  635.  
  636.     for(ch=0;m<length;m++)            /* Pad out with NULLs */
  637.         fputc(ch,smb.sdt_fp);
  638.     fflush(smb.sdt_fp);
  639.  
  640.     msg.hdr.offset=offset;
  641.  
  642.     smb_dfield(&msg,TEXT_BODY,length);
  643.  
  644.     i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK);
  645.     smb_close(&smb);
  646.     smb_stack(&smb,SMB_STACK_POP);
  647.  
  648.     smb_freemsgmem(&msg);
  649.     if(i) {
  650.         smb_freemsgdat(&smb,offset,length,1);
  651.         errormsg(WHERE,ERR_WRITE,smb.file,i); }
  652.     else {        /* Successful */
  653.         if(inet) {
  654.             if(inetmail_sem[0])      /* update semaphore file */
  655.                 if((fido=nopen(inetmail_sem,O_WRONLY|O_CREAT|O_TRUNC))!=-1)
  656.                     close(fido);
  657.             if(!(useron.exempt&FLAG('S')))
  658.                 subtract_cdt(inetmail_cost); }
  659.         sprintf(str,"Sent %s NetMail to %s (%s) via QWK"
  660.             ,qnet ? "QWK":"Internet",name,qnet ? fulladdr : to);
  661.         logline("EN",str); }
  662.  
  663.     FREE((char *)qwkbuf);
  664.     return; }
  665.  
  666.  
  667. /****************************** FidoNet **********************************/
  668.  
  669. if(!fidoaddr.zone || !netmail_dir[0]) {  // No fido netmail allowed
  670.     bprintf("\1n\r\nInvalid NetMail address.\r\n");
  671.     FREE(qwkbuf);
  672.     return; }
  673.  
  674. memset(&hdr,0,sizeof(hdr));   /* Initialize header to null */
  675.  
  676. if(fromhub || useron.rest&FLAG('Q')) {
  677.     sprintf(str,"%.25s",block+46);              /* From */
  678.     truncsp(str);
  679.     sprintf(tmp,"@%s",fromhub ? qhub[fromhub-1]->id : useron.alias);
  680.     strupr(tmp);
  681.     strcat(str,tmp); }
  682. else
  683.     strcpy(str,netmail_misc&NMAIL_ALIAS ? useron.alias : useron.name);
  684. sprintf(hdr.from,"%.35s",str);
  685.  
  686. sprintf(hdr.to,"%.35s",to);
  687.  
  688. /* Look-up in nodelist? */
  689.  
  690. if(netmail_cost && !(useron.exempt&FLAG('S'))) {
  691.     if(useron.cdt+useron.freecdt<netmail_cost) {
  692.         bputs(text[NotEnoughCredits]);
  693.         FREE(qwkbuf);
  694.         return; }
  695.     sprintf(str,text[NetMailCostContinueQ],netmail_cost);
  696.     if(noyes(str)) {
  697.         FREE(qwkbuf);
  698.         return; } }
  699.  
  700. hdr.destzone    =fidoaddr.zone;
  701. hdr.destnet     =fidoaddr.net;
  702. hdr.destnode    =fidoaddr.node;
  703. hdr.destpoint    =fidoaddr.point;
  704.  
  705. for(i=0;i<total_faddrs;i++)
  706.     if(fidoaddr.zone==faddr[i].zone && fidoaddr.net==faddr[i].net)
  707.         break;
  708. if(i==total_faddrs) {
  709.     for(i=0;i<total_faddrs;i++)
  710.         if(fidoaddr.zone==faddr[i].zone)
  711.             break; }
  712. if(i==total_faddrs)
  713.     i=0;
  714. hdr.origzone    =faddr[i].zone;
  715. hdr.orignet     =faddr[i].net;
  716. hdr.orignode    =faddr[i].node;
  717. hdr.origpoint   =faddr[i].point;
  718.  
  719. strcpy(str,faddrtoa(faddr[i]));
  720. bprintf(text[NetMailing],hdr.to,faddrtoa(fidoaddr),hdr.from,str);
  721.  
  722. date.da_mon=((qwkbuf[8]&0xf)*10)+(qwkbuf[9]&0xf);
  723. date.da_day=((qwkbuf[11]&0xf)*10)+(qwkbuf[12]&0xf);
  724. date.da_year=((qwkbuf[14]&0xf)*10)+(qwkbuf[15]&0xf)+1900;
  725. curtime.ti_hour=((qwkbuf[16]&0xf)*10)+(qwkbuf[17]&0xf);
  726. curtime.ti_min=((qwkbuf[19]&0xf)*10)+(qwkbuf[20]&0xf);        /* From QWK time */
  727. curtime.ti_sec=0;
  728. sprintf(hdr.time,"%02u %3.3s %02u  %02u:%02u:%02u"          /* To FidoNet */
  729.     ,date.da_day,mon[date.da_mon-1],date.da_year-1900
  730.     ,curtime.ti_hour,curtime.ti_min,curtime.ti_sec);
  731.  
  732. hdr.attr=(FIDO_LOCAL|FIDO_PRIVATE);
  733.  
  734. if(netmail_misc&NMAIL_CRASH) hdr.attr|=FIDO_CRASH;
  735. if(netmail_misc&NMAIL_HOLD)  hdr.attr|=FIDO_HOLD;
  736. if(netmail_misc&NMAIL_KILL)  hdr.attr|=FIDO_KILLSENT;
  737.  
  738. sprintf(str,"%.25s",block+71);      /* Title */
  739. truncsp(str);
  740. p=str;
  741. if((SYSOP || useron.exempt&FLAG('F'))
  742.     && !strncmpi(p,"CR:",3)) {     /* Crash over-ride by sysop */
  743.     p+=3;               /* skip CR: */
  744.     if(*p==SP) p++;     /* skip extra space if it exists */
  745.     hdr.attr|=FIDO_CRASH; }
  746.  
  747. if((SYSOP || useron.exempt&FLAG('F'))
  748.     && !strncmpi(p,"FR:",3)) {     /* File request */
  749.     p+=3;               /* skip FR: */
  750.     if(*p==SP) p++;
  751.     hdr.attr|=FIDO_FREQ; }
  752.  
  753. if((SYSOP || useron.exempt&FLAG('F'))
  754.     && !strncmpi(p,"RR:",3)) {     /* Return receipt request */
  755.     p+=3;               /* skip RR: */
  756.     if(*p==SP) p++;
  757.     hdr.attr|=FIDO_RRREQ; }
  758.  
  759. if((SYSOP || useron.exempt&FLAG('F'))
  760.     && !strncmpi(p,"FA:",3)) {     /* File attachment */
  761.     p+=3;                /* skip FA: */
  762.     if(*p==SP) p++;
  763.     hdr.attr|=FIDO_FILE; }
  764.  
  765. sprintf(hdr.subj,"%.71s",p);
  766.  
  767. for(i=1;i;i++) {
  768.     sprintf(str,"%s%u.MSG",netmail_dir,i);
  769.     if(!fexist(str))
  770.         break; }
  771. if(!i) {
  772.     bputs(text[TooManyEmailsToday]);
  773.     return; }
  774. if((fido=nopen(str,O_WRONLY|O_CREAT|O_EXCL))==-1) {
  775.     FREE(qwkbuf);
  776.     errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_EXCL);
  777.     return; }
  778. write(fido,&hdr,sizeof(hdr));
  779.  
  780. pt_zone_kludge(hdr,fido);
  781.  
  782. if(netmail_misc&NMAIL_DIRECT) {
  783.     sprintf(str,"\1FLAGS DIR\r\n");
  784.     write(fido,str,strlen(str)); }
  785.  
  786. l=128L;
  787.  
  788. if(into==NULL) {      /* If name@addr on first line, skip first line */
  789.     while(l<n*128L && (uchar)qwkbuf[l]!=0xe3) l++;
  790.     l++; }
  791.  
  792. while(l<n*128L) {
  793.     if(qwkbuf[l]==1)   /* Ctrl-A, so skip it and the next char */
  794.         l++;
  795.     else if(qwkbuf[l]!=LF) {
  796.         if((uchar)qwkbuf[l]==0xe3) /* QWK cr/lf char converted to hard CR */
  797.             qwkbuf[l]=CR;
  798.         write(fido,(char *)qwkbuf+l,1); }
  799.     l++; }
  800. l=0;
  801. write(fido,&l,1);    /* Null terminator */
  802. close(fido);
  803. FREE((char *)qwkbuf);
  804. if(netmail_sem[0])        /* update semaphore file */
  805.     if((fido=nopen(netmail_sem,O_WRONLY|O_CREAT|O_TRUNC))!=-1)
  806.         close(fido);
  807. if(!(useron.exempt&FLAG('S')))
  808.     subtract_cdt(netmail_cost);
  809. sprintf(str,"Sent NetMail to %s @%s via QWK",hdr.to,faddrtoa(fidoaddr));
  810. logline("EN",str);
  811. }
  812.  
  813.