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(¤tTime);
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