1 /******************************************************************************
2  * FIDOCONFIG --- library for fidonet configs
3  ******************************************************************************
4  * afixcmn.c : common areafix functions
5  *
6  * Compiled from hpt/areafix hpt/toss hpt/pkt
7  * by Max Chernogor <mihz@mail.ru>, 2:464/108@fidonet
8  *
9  * This file is part of FIDOCONFIG library (part of the Husky FIDOnet
10  * software project)
11  *
12  * This is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published
14  * by the Free Software Foundation; either version 2, or (at your option)
15  * any later version.
16  *
17  * FIDOCONFIG library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with FIDOCONFIG library; see the file COPYING.  If not, write
24  * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA
25  *
26  * See also http://www.gnu.org
27  *****************************************************************************
28  * $Id$
29  */
30 
31  /*
32  * This subroutine makes up an ascending unique ^aMSGID stamp
33  * taken from Su.FidoTech.FAQ [2/3]
34  */
35 
36 #include <string.h>
37 #include <stdlib.h>
38 
39 #include <huskylib/huskylib.h>
40 
41 #ifdef HAS_UNISTD_H
42 #   include <unistd.h>
43 #endif
44 
45 #ifdef HAS_STRINGS_H
46 #   include <strings.h>
47 #endif
48 
49 /* export functions from DLL */
50 #define DLLEXPORT
51 #include <huskylib/huskyext.h>
52 
53 #include "fidoconf.h"
54 #include "common.h"
55 #include "afixcmd.h"
56 
57 #if 0
58 static hUINT32 DoMakeMSGIDStamp(void)
59 {
60     static hUINT32 lStampPrev;
61     hUINT32 lStamp, lSecs, lHund, lSecStart = (hUINT32) time(NULL);
62 
63     /*  Make up time stamp out of number of seconds since Jan 1, 1970 */
64     /*  shifted 7 bits to the left OR'ed with current system clock and */
65     /*  loop untill we get a new stamp */
66 
67     do {
68         lSecs = (hUINT32) time(NULL);
69         lHund = (hUINT32) clock();
70         lStamp = (lSecs << 7) | (lHund & 0x07f);
71     } while ((lStampPrev >= lStamp) && ((hUINT32) time(NULL) < lSecStart + 5));
72 
73     /*  Check if we finally have unique ascending ^aMSGID kludge stamp and */
74     /*  if not, use incremented largest stamp value */
75 
76     if (lStampPrev >= lStamp) lStamp = lStampPrev + 1;
77 
78     return lStampPrev = lStamp;
79 }
80 #endif
81 
createKludges(ps_fidoconfig config,const char * area,const hs_addr * ourAka,const hs_addr * destAka,const char * versionStr)82 char *createKludges(ps_fidoconfig config, const char *area, const hs_addr *ourAka,
83                     const hs_addr *destAka, const char* versionStr)
84 {
85    char *buff = NULL;
86    hUINT32 msgid = 0;
87 
88    if (area) {
89       xscatprintf(&buff, "AREA:%s\r", area);
90       strUpper(buff);
91    } else {
92 	   xscatprintf(&buff, "\001INTL %u:%u/%u %u:%u/%u\r",
93 			   destAka->zone, destAka->net, destAka->node,
94 			   ourAka->zone,  ourAka->net,  ourAka->node);
95       if (ourAka->point) xscatprintf(&buff, "\001FMPT %d\r", ourAka->point);
96       if (destAka->point) xscatprintf(&buff, "\001TOPT %d\r", destAka->point);
97    }
98    msgid = GenMsgId(config->seqDir, config->seqOutrun);
99 
100    if (ourAka->point)
101       xscatprintf(&buff, "\001MSGID: %u:%u/%u.%u %08lx\r",
102               ourAka->zone,ourAka->net,ourAka->node,ourAka->point,msgid);
103    else
104       xscatprintf(&buff, "\001MSGID: %u:%u/%u %08lx\r",
105               ourAka->zone,ourAka->net,ourAka->node,msgid);
106 
107    if (!config->disablePID) xscatprintf(&buff, "\001PID: %s\r", versionStr);
108 
109    return buff;
110 }
111 
makeMessage(hs_addr * origAddr,hs_addr * destAddr,char * fromName,char * toName,char * subject,int netmail,long attrs)112 s_message *makeMessage (hs_addr *origAddr, hs_addr *destAddr,
113 			char *fromName,	char *toName, char *subject,
114             int netmail, long attrs)
115 {
116     /*  netmail == 0 - echomail */
117     /*  netmail == 1 - netmail */
118     time_t time_cur;
119     s_message *msg;
120 
121     if (toName == NULL) toName = "sysop";
122 
123     time_cur = time(NULL);
124 
125     msg = (s_message*) scalloc(1,sizeof(s_message));
126 
127     msg->origAddr = *origAddr;
128 
129     msg->destAddr = *destAddr;
130 
131     xstrcat(&(msg->fromUserName), fromName);
132     xstrcat(&(msg->toUserName), toName);
133     xstrcat(&(msg->subjectLine), subject);
134 
135     msg->attributes = attrs;
136     if (!netmail) {
137         msg->attributes &= ~(MSGPRIVATE|MSGKILL);
138     } else {
139 	msg->netMail = 1;
140     }
141 
142     fts_time((char*)msg->datetime, localtime(&time_cur));
143 
144     return msg;
145 }
146 
createXMSG(ps_fidoconfig config,s_message * msg,const s_pktHeader * header,dword forceattr,char * tossDir)147 XMSG createXMSG(ps_fidoconfig config, s_message *msg, const s_pktHeader *header,
148                 dword forceattr, char* tossDir)
149 {
150     char **outbounds[4];
151     XMSG  msgHeader;
152     struct tm *date;
153     time_t    currentTime;
154     union stamp_combo dosdate;
155     unsigned int i;
156     char *newSubj=NULL, *token=NULL, *running=NULL, *p=NULL;
157 
158     /* init outbounds */
159     outbounds[0] = &tossDir;
160     outbounds[1] = &config->protInbound;
161     outbounds[2] = &config->inbound;
162     outbounds[3] = NULL;
163 
164     /*  clear msgheader */
165     memset(&msgHeader, '\0', sizeof(XMSG));
166 
167     /*  attributes of netmail must be fixed */
168     msgHeader.attr = msg->attributes;
169 
170     if (msg->netMail == 1) {
171 	/*  Check if we must remap */
172 	for (i=0;i<config->remapCount;i++)
173 	    if ((config->remaps[i].toname==NULL ||
174 		 stricmp(config->remaps[i].toname,msg->toUserName)==0) &&
175 		(config->remaps[i].oldaddr.zone==0 ||
176 		 addrComp(config->remaps[i].oldaddr,msg->destAddr)==0) )
177 		{   w_log( LL_NETMAIL,"Remap destination %u:%u/%u.%u to %s",
178                            msg->destAddr.zone, msg->destAddr.net,
179                            msg->destAddr.node, msg->destAddr.point,
180                            aka2str(config->remaps[i].newaddr) );
181 		    msg->destAddr = config->remaps[i].newaddr;
182                     /* synchronize 'INTL' kludge with new dest address */
183                     for( running=msg->text; (p=strchr(running,'\r'))!=NULL; running=++p ){
184                       *p = '\0';
185                       if( strlen(running)>5 && !memcmp(running, "\001INTL ",6) ) {
186                           /*replace INTL to new*/
187                           xstrscat( &token, "\001INTL ", aka2str(msg->destAddr), NULLP );
188                           xscatprintf( &token, " %s\r", aka2str(msg->origAddr) );
189                       } else { /* copy kludge or line */
190                           xscatprintf( &token, "%s\r", running );
191                       }
192                     }
193                     xscatprintf( &token, "\001Replace destaddr %s",
194                                  aka2str(config->remaps[i].oldaddr) );
195                     xscatprintf( &token, " with %s", aka2str(msg->destAddr) );
196                     xscatprintf( &token, " by %s", aka2str(config->addr[0]) );
197                     msg->textLength = strlen(token);
198                     nfree(msg->text);
199                     msg->text = token;
200                     token = p = NULL;
201 		    break;
202 		}
203 
204 	/* if (to_us(msg->destAddr)==0) { */
205     if (isOurAka(config,msg->destAddr)) {
206 	    /*  kill these flags */
207 	    msgHeader.attr &= ~(MSGREAD | MSGKILL | MSGFRQ | MSGSCANNED | MSGLOCKED | MSGFWD);
208 	    /*  set this flags */
209 	    msgHeader.attr |= MSGPRIVATE;
210 	} else
211 	    if (header!=NULL) {
212 		/*  set TRS flag, if the mail is not to us(default) */
213 		if ( config->keepTrsMail ) msgHeader.attr &= ~(MSGKILL | MSGFWD);
214 		else msgHeader.attr |= MSGFWD;
215 	    }
216     } else
217 	/*  kill these flags on echomail messages */
218 	msgHeader.attr &= ~(MSGREAD | MSGKILL | MSGFRQ | MSGSCANNED | MSGLOCKED);
219 
220     /*  always kill crash, hold, sent & local flags on netmail & echomail */
221     msgHeader.attr &= ~(MSGCRASH | MSGHOLD | MSGSENT | MSGLOCAL);
222 
223     /* FORCED ATTRIBUTES !!! */
224     msgHeader.attr |= forceattr;
225 
226     sstrcpy((char *) msgHeader.from,msg->fromUserName);
227     sstrcpy((char *) msgHeader.to, msg->toUserName);
228 
229     /* val: strip directories and drives from filenames */
230     if (((msgHeader.attr & MSGFILE) == MSGFILE)
231 	&& (msg->netMail==1)
232 	&& strpbrk(msg->subjectLine, "/\\:")) {
233 
234         /* w_log('B', "Original subj: `%s'", msg->subjectLine); */
235 	running = msg->subjectLine;
236 	token = strseparate(&running, " ,\t");
237 
238 	while (token != NULL) {
239 	    int l = strlen(token) - 1;
240             while ( l >= 0 &&
241                     token[l] != '\\' && token[l] != '/' && token[l] != ':' )
242                 l--;
243             if (newSubj) xstrcat(&newSubj, " ");
244             xstrcat(&newSubj, token + l + 1);
245 	    token = strseparate(&running, " ,\t");
246 	} /*  end while */
247         /* w_log('B', "Modified subj: `%s'", newSubj); */
248     }
249 
250     if (newSubj) {
251 	if (strlen(newSubj) < XMSG_SUBJ_SIZE)
252 	    strcpy((char *) msgHeader.subj, newSubj);
253 	else {
254 	    strncpy((char *) msgHeader.subj, newSubj, XMSG_SUBJ_SIZE-1);
255 	    w_log('9',
256 		  "Long subjectLine! Some files will be not routed.");
257 	}
258 	nfree(newSubj);
259     } else strcpy((char *) msgHeader.subj, msg->subjectLine);
260 
261     msgHeader.orig  = msg->origAddr;
262     msgHeader.dest  = msg->destAddr;
263 
264     strcpy((char *) msgHeader.__ftsc_date, (char *)msg->datetime);
265     ASCII_Date_To_Binary((char *)msg->datetime, (union stamp_combo *) &(msgHeader.date_written));
266 
267     currentTime = time(NULL);
268     date = localtime(&currentTime);
269     TmDate_to_DosDate(date, &dosdate);
270     msgHeader.date_arrived = dosdate.msg_st;
271 
272     return msgHeader;
273 }
274 
freeMsgBuffers(s_message * msg)275 void freeMsgBuffers(s_message *msg)
276 {
277     if (!msg)
278         return;
279 
280     nfree(msg->text);
281     nfree(msg->ctl);
282     nfree(msg->subjectLine);
283     nfree(msg->toUserName);
284     nfree(msg->fromUserName);
285 }
286