1 /*****************************************************************************
2 * HPT --- FTN NetMail/EchoMail Tosser
3 *****************************************************************************
4 * Copyright (C) 1997-1999
5 *
6 * Matthias Tichy
7 *
8 * Fido: 2:2433/1245 2:2433/1247 2:2432/605.14
9 * Internet: mtt@tichy.de
10 *
11 * Grimmestr. 12 Buchholzer Weg 4
12 * 33098 Paderborn 40472 Duesseldorf
13 * Germany Germany
14 *
15 * This file is part of HPT.
16 *
17 * HPT is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2, or (at your option) any
20 * later version.
21 *
22 * HPT is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with HPT; see the file COPYING. If not, write to the Free
29 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
30 *****************************************************************************
31 * $Id$
32 */
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <ctype.h>
37
38 #include <huskylib/compiler.h>
39 #include <huskylib/huskylib.h>
40
41 #include <fidoconf/fidoconf.h>
42 #include <fidoconf/common.h>
43 #include <huskylib/xstr.h>
44 #include <fidoconf/afixcmd.h>
45 #include <huskylib/log.h>
46 #include <huskylib/recode.h>
47
48 #include <areafix/areafix.h>
49 #include <global.h>
50 #include <fcommon.h>
51 #include <pkt.h>
52 #include <global.h>
53
readPktTime(FILE * pkt)54 time_t readPktTime(FILE *pkt)
55 {
56 struct tm time;
57
58 time.tm_year = getUINT16(pkt) - 1900; /* years since 1900 */
59 time.tm_mon = getUINT16(pkt);
60 time.tm_mday = getUINT16(pkt);
61 time.tm_hour = getUINT16(pkt);
62 time.tm_min = getUINT16(pkt);
63 time.tm_sec = getUINT16(pkt);
64 time.tm_isdst = 0; /* disable daylight saving */
65
66 return mktime(&time);
67 }
68
readPktPassword(FILE * pkt,UCHAR * password)69 void readPktPassword(FILE *pkt, UCHAR *password)
70 {
71 int i;
72
73 for (i=0 ;i<8 ;i++ ) {
74 password[i] = (UCHAR) getc(pkt); /* no EOF check :-( */
75 } /* endfor */
76 password[8] = 0;
77 }
78
openPkt(FILE * pkt)79 s_pktHeader *openPkt(FILE *pkt)
80 {
81 s_pktHeader *header;
82 UINT16 pktVersion, capWord;
83
84 header = (s_pktHeader *) safe_malloc(sizeof(s_pktHeader));
85 memset(header, '\0', sizeof(s_pktHeader));
86 header->origAddr.node = getUINT16(pkt);
87 header->destAddr.node = getUINT16(pkt);
88 header->pktCreated = readPktTime(pkt); /* 12 bytes */
89
90 getUINT16(pkt); /* read 2 bytes for the unused baud field */
91
92 pktVersion = getUINT16(pkt);
93 if (pktVersion != 2) {
94 nfree(header);
95 w_log(LL_ERR,"Invalid pkt version %u!",pktVersion);
96 return NULL;
97 } /* endif */
98
99 header->origAddr.net = getUINT16(pkt);
100 header->destAddr.net = getUINT16(pkt);
101
102 header->loProductCode = (UCHAR) getc(pkt);
103 header->majorProductRev = (UCHAR) getc(pkt);
104
105 readPktPassword(pkt, (UCHAR *)header->pktPassword); /* 8 bytes */
106
107 header->origAddr.zone = getUINT16(pkt);
108 header->destAddr.zone = getUINT16(pkt);
109
110 header->auxNet = getUINT16(pkt);
111
112 header->capabilityWord = (UINT16)((fgetc(pkt) << 8) + fgetc(pkt));
113 header->hiProductCode = (UCHAR) getc(pkt);
114 header->minorProductRev = (UCHAR) getc(pkt);
115
116 capWord = getUINT16(pkt);
117
118 if (!config->ignoreCapWord) {
119 /* if both capabilitywords aren't the same, abort */
120 /* but read stone-age pkt */
121 if (capWord!=header->capabilityWord && header->capabilityWord!=0) {
122 nfree(header);
123 w_log(LL_ERR,"CapabilityWord error in following pkt! rtfm: IgnoreCapWord.");
124 return NULL;
125 } /* endif */
126 }
127
128 getUINT16(pkt); getUINT16(pkt); /* read the additional zone info */
129
130 header->origAddr.point = getUINT16(pkt);
131 header->destAddr.point = getUINT16(pkt);
132
133 getUINT16(pkt); getUINT16(pkt); /* read ProdData */
134
135 if (((UINT16)header->origAddr.net) == 65535U) {
136 if (header->origAddr.point) header->origAddr.net = header->auxNet;
137 else header->origAddr.net = header->destAddr.net; /* not in FSC ! */
138 }
139
140 if (header->origAddr.zone == 0) {
141 for (capWord=0; capWord<config->addrCount; capWord++) {
142 if (header->origAddr.net==config->addr[capWord].net) {
143 header->origAddr.zone = config->addr[capWord].zone;
144 break;
145 }
146 }
147 if (header->origAddr.zone==0) header->origAddr.zone=config->addr[0].zone;
148 }
149 if (header->destAddr.zone == 0) {
150 for (capWord=0; capWord<config->addrCount; capWord++) {
151 if (header->destAddr.net==config->addr[capWord].net) {
152 header->destAddr.zone = config->addr[capWord].zone;
153 break;
154 }
155 }
156 if (header->destAddr.zone==0) header->destAddr.zone=config->addr[0].zone;
157 }
158
159 return header;
160 }
161
162 /* WARNING: *from and *to addresses should be properly initialized */
parseINTL(char * msgtxt,hs_addr * from,hs_addr * to)163 int parseINTL(char *msgtxt, hs_addr *from, hs_addr *to)
164 {
165 char *start;
166 hs_addr intl_from= *from, intl_to = *to; /* set defaults */
167 int result = 0, temp_point;
168
169 /* Parse the INTL Kludge */
170
171 start = strstr(msgtxt, "\001INTL ");
172 if (start)
173 {
174 start += 6; /* skip "INTL " */
175
176 if( !(parseFtnAddrZ(start, &intl_to, FTNADDR_GOOD, (const char**)(&start)) & FTNADDR_ERROR) &&
177 !(parseFtnAddrZ(start, &intl_from, FTNADDR_GOOD, (const char**)(&start)) & FTNADDR_ERROR))
178 /* '(const char**)(&start)' is needs for prevent warning "passing arg 4 of `parseFtnAddrZ' from incompatible pointer type" */
179 {
180 /* INTL is valid, copy parsed data to output */
181 /* copying the whole structures is ok since they are initialized by from and to */
182 *from = intl_from;
183 *to = intl_to;
184
185 result |= INTL_FOUND;
186 }
187 } else
188 w_log(LL_DEBUGB, "Warning: no INTL kludge found in message");
189
190 start = strstr(msgtxt, "\001FMPT");
191 if (start)
192 {
193 start += 6; /* skip "FMPT " */
194 temp_point = atoi(start);
195 from->point = (temp_point >= 0 && temp_point <= 32767)?(sword)temp_point:0;
196 /* Actually there should not be */
197 result |= FMPT_FOUND;
198 }
199 else
200 /* while standard says that no FMPT kludge means zero point, we wont change
201 * point nuber here but will rely on interpretation of caller function */
202 ;
203 /* and the same for TOPT */
204 start = strstr(msgtxt, "\001TOPT");
205 if (start)
206 {
207 start += 6; /* skip "TOPT " */
208 temp_point = atoi(start);
209 to->point = (temp_point >= 0 && temp_point <= 32767)?(sword)temp_point:0;
210 result |= TOPT_FOUND;
211 }
212 else
213 /* while standard says that no TOPT kludge means zero point, we wont change
214 * point nuber here but will rely on interpretation of caller function */
215 ;
216 return result;
217 }
218
correctEMAddr(s_message * msg)219 void correctEMAddr(s_message *msg)
220 {
221 char *start = NULL, *temp;
222
223 /* Find originating address in Origin line */
224 start = strrstr(msg->text, " * Origin:");
225
226 if (start) {
227 temp = start += 10; /* skip " * Origin:" */
228 while (*start && (*start != '\r') && (*start != '\n')) start++; /* get to end of line */
229 --start;
230 while (*(start) == ' ') --start; /* skip trailing spaces, just in case */
231
232 if (*(start) == ')') { /* if there is no ')', there is no origin */
233
234 while (--start > temp &&
235 *start != '(' && /* find beginning '(' */
236 !isspace(*start));
237
238 if (*start=='(' || *start==' ') { /* "(1:2/3.4@dom)" or " 1:2/3.4@dom)" is found */
239
240 start++; /* skip '(' or ' ' */
241 if( !(parseFtnAddrZS(start,&msg->origAddr) & FTNADDR_ERROR) ){
242 return; /* FTN address is taken from Origin */
243 }
244 }
245 }
246 }
247
248 /* Find originating address in MSGID line */
249 start = strrstr(msg->text, "\001MSGID:");
250 /* Standard requires "\001MSGID: " but not all software is compatible with FTS-9 :( */
251 if (start) {
252 start+=7;
253 if( !(parseFtnAddrZS(start, &msg->origAddr) & FTNADDR_ERROR) ){
254 return; /* FTN address is taken from MSGID */
255 }
256 }
257
258 /* Another try...
259 * But if MSGID isn't present or broken and origin is broken
260 * then PATH may be broken too...
261 */
262 start = strstr(msg->text, "\001PATH: ");
263 if (start) {
264 start += 7;
265 if( !(parseFtnAddrZ(start, &msg->origAddr, FTNADDR_2D, NULL) & FTNADDR_ERROR) ){
266 return; /* FTN address is taken from PATH */
267 }
268 }
269
270 /* if nothing works then send report to RC ;) */
271 }
272
correctNMAddr(s_message * msg,s_pktHeader * header)273 void correctNMAddr(s_message *msg, s_pktHeader *header)
274 {
275 char *text = NULL;
276 int valid_intl_kludge;
277 int zonegated = 0;
278 hs_addr intl_from = msg->origAddr, intl_to = msg->destAddr;
279 UINT i;
280
281 valid_intl_kludge = parseINTL(msg->text, &intl_from, &intl_to);
282
283 /* Assign point numbers if FMPT/TOPT kludges are found */
284 if(valid_intl_kludge & FMPT_FOUND)
285 msg->origAddr.point = intl_from.point;
286 if(valid_intl_kludge & TOPT_FOUND)
287 msg->destAddr.point = intl_to.point;
288 /* if no kludges are found then leave current values
289 * which most possible are zeroes */
290
291 /* now interpret the INTL kludge */
292
293 if (valid_intl_kludge & INTL_FOUND)
294 {
295 /* the from part is easy - we can always use it */
296
297 msg->origAddr.zone = intl_from.zone;
298 msg->origAddr.net = intl_from.net;
299 msg->origAddr.node = intl_from.node;
300
301 /* the to part is more complicated */
302
303 zonegated = 0;
304
305 if (msg->destAddr.net == intl_from.zone &&
306 msg->destAddr.node == intl_to.zone)
307 {
308 zonegated = 1;
309
310 /* we want to ignore the zone gating if we are the zone gate */
311
312 for (i = 0; i < config->addrCount; i++)
313 {
314 if (config->addr[i].zone == msg->destAddr.net &&
315 config->addr[i].net == msg->destAddr.net &&
316 config->addr[i].node == msg->destAddr.node &&
317 config->addr[i].point == 0)
318 {
319 zonegated = 0;
320 }
321 }
322 }
323
324 if (zonegated)
325 {
326 msg->destAddr.zone = intl_from.zone;
327 msg->destAddr.net = intl_from.zone;
328 msg->destAddr.node = intl_to.zone;
329 }
330 else
331 {
332 msg->destAddr.zone = intl_to.zone;
333 msg->destAddr.net = intl_to.net;
334 msg->destAddr.node = intl_to.node;
335 }
336
337 } else {
338
339 /* no INTL kludge */
340
341 msg->destAddr.zone = header->destAddr.zone;
342 msg->origAddr.zone = header->origAddr.zone;
343
344 msg->textLength += xscatprintf(&text,"\001INTL %u:%u/%u %u:%u/%u\r",msg->destAddr.zone,msg->destAddr.net,msg->destAddr.node,msg->origAddr.zone,msg->origAddr.net,msg->origAddr.node);
345 xstrcat(&text,msg->text);
346 nfree(msg->text);
347 msg->text = text;
348
349 w_log( LL_PKT, "Mail without INTL-Kludge. Assuming %i:%i/%i.%i -> %i:%i/%i.%i",
350 msg->origAddr.zone, msg->origAddr.net, msg->origAddr.node, msg->origAddr.point,
351 msg->destAddr.zone, msg->destAddr.net, msg->destAddr.node, msg->destAddr.point);
352 } /* endif */
353 }
354
correctAddr(s_message * msg,s_pktHeader * header)355 void correctAddr(s_message *msg,s_pktHeader *header)
356 {
357 if (strncmp(msg->text, "AREA:",5) == 0) {
358
359 if (strncmp(msg->text+5, "NETMAIL\r",8) == 0) {
360 switch (config->kludgeAreaNetmail) {
361 case kanKill: /* kill "AREA:NETMAIL\r" */
362 memmove(msg->text, msg->text+13, msg->textLength-12);
363 case kanIgnore: /* process as netmail. don't touch kludge. */
364 msg->netMail = 1;
365 default: /* process as echomail */
366 break;
367 }
368 }
369
370 } else msg->netMail = 1;
371
372 if (msg->netMail) correctNMAddr(msg,header);
373 else correctEMAddr(msg);
374 }
375
376 /* Some toupper routines crash when they get invalid input. As this program
377 is intended to be portable and deal with any sort of malformed input,
378 we have to provide our own toupper routine. */
safe_toupper(char c)379 char safe_toupper(char c)
380 {
381 const char *from_table = "abcdefghijklmnopqrstuvwxyz";
382 const char *to_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
383 const char *p;
384
385 if ((p = strchr(from_table, c)) != NULL)
386 {
387 return (to_table[p - from_table]);
388 }
389
390 return c;
391 }
392
get_month(const char * pmon,flag_t * flag)393 int get_month(const char *pmon, flag_t *flag)
394 {
395 int i;
396
397 if (strlen(pmon) != 3 && flag != NULL)
398 {
399 (*flag) |= FTSC_FLAWY;
400 }
401
402 for (i=0; i < 12; i++)
403 {
404 if (pmon[0] == months_ab[i][0] &&
405 pmon[1] == months_ab[i][1] &&
406 pmon[2] == months_ab[i][2])
407 {
408 return i;
409 }
410 }
411
412 for (i=0; i < 12; i++)
413 {
414 if (safe_toupper(pmon[0]) == safe_toupper(months_ab[i][0]) &&
415 safe_toupper(pmon[1]) == safe_toupper(months_ab[i][1]) &&
416 safe_toupper(pmon[2]) == safe_toupper(months_ab[i][2]))
417 {
418 (*flag) |= FTSC_FLAWY;
419 return i;
420 }
421 }
422
423 (*flag) |= FTSC_BROKEN;
424 return 0;
425 }
426
parse_ftsc_date(struct tm * ptm,char * pdatestr)427 flag_t parse_ftsc_date(struct tm * ptm, char *pdatestr)
428 {
429 const char *pday, *pmon, *pyear, *phour, *pminute, *psecond;
430 flag_t rval;
431 char buf[22];
432 int fixseadog=0;
433 struct tm *pnow;
434 time_t t_now;
435
436 time(&t_now);
437 pnow = localtime(&t_now); /* get the current time */
438
439 pday = pmon = pyear = phour = pminute = psecond = NULL;
440
441 rval = FTSC_BROKEN;
442
443 memcpy(buf, pdatestr, 21); buf[21] = 0;
444
445 if ((pday = strtok(buf, " ")) != NULL)
446 if ((pmon = strtok(NULL, " ")) != NULL)
447 if ((pyear = strtok(NULL, " ")) != NULL)
448 if ((phour = strtok(NULL, ":")) != NULL)
449 if ((pminute = strtok(NULL, ":")) != NULL)
450 if ((psecond = strtok(NULL, " ")) != NULL)
451 rval = 0;
452
453 if (rval == FTSC_BROKEN)
454 {
455 /* let's try and see if it might be the old SeaDog format */
456
457 memcpy(buf, pdatestr, 21); buf[21] = 0;
458
459 if ((strtok(buf, " ")) != NULL)
460 if ((pday = strtok(NULL, " ")) != NULL)
461 if ((pmon = strtok(NULL, " ")) != NULL)
462 if ((pyear = strtok(NULL, " ")) != NULL)
463 if ((phour = strtok(NULL, ": ")) != NULL)
464 if ((pminute = strtok(NULL, ": ")) != NULL)
465 {
466 psecond = NULL;
467 if (fixseadog)
468 rval = FTSC_SEADOG;
469 else
470 rval = 0;
471 }
472 }
473
474
475 ptm->tm_sec = ptm->tm_min = ptm->tm_hour = ptm->tm_mday = ptm->tm_mon =
476 ptm->tm_year = 0;
477
478 while (rval != FTSC_BROKEN) /* at least we could tokenize it! */
479 {
480 if (psecond != NULL)
481 {
482 ptm->tm_sec = atoi(psecond); /* Is the number of seconds valid? */
483 if (strlen(psecond) == 1)
484 {
485 rval |= FTSC_FLAWY;
486 if (ptm->tm_sec < 6) (ptm->tm_sec *= 10);
487 }
488 if (ptm->tm_sec < 0 || ptm->tm_sec > 59)
489 {
490 rval |= FTSC_TS_BROKEN; ptm->tm_sec = 0;
491 }
492 }
493 else
494 {
495 ptm->tm_sec = 0;
496 }
497
498 ptm->tm_min = atoi(pminute); /* Is the number of minutes valid? */
499 if (ptm->tm_min < 0 || ptm->tm_min > 59)
500 {
501 rval |= FTSC_TS_BROKEN; ptm->tm_min = 0;
502 }
503
504 ptm->tm_hour = atoi(phour); /* Is the number of hours valid? */
505 if (ptm->tm_hour < 0 || ptm->tm_hour>23)
506 {
507 rval |= FTSC_TS_BROKEN; ptm->tm_hour = 0;
508 }
509
510 ptm->tm_mday = atoi(pday); /* Is the day in the month valid? */
511 if (ptm->tm_mday < 1 || ptm->tm_mday>31) { rval |= FTSC_BROKEN; break; }
512
513 ptm->tm_mon = get_month(pmon, &rval); /* Is the month valid? */
514
515 if (strlen(pyear) != 2) /* year field format check */
516 {
517 rval |= FTSC_FLAWY;
518 }
519
520 if (*pyear)
521 {
522 ptm->tm_year = (*pyear - '0'); /* allows for the ":0" bug */
523 for (pyear++; isdigit((int)(*pyear)); pyear++)
524 {
525 ptm->tm_year *= 10;
526 ptm->tm_year += (*pyear - '0');
527 }
528 if (*pyear)
529 {
530 rval |= FTSC_BROKEN;
531 break;
532 }
533 }
534 else
535 {
536 rval |= FTSC_BROKEN;
537 break;
538 }
539
540 if (ptm->tm_year < 100) /* correct date field! */
541 {
542 while (pnow->tm_year - ptm->tm_year > 50)
543 { /* sliding window adaption */
544 ptm->tm_year += 100;
545 }
546 }
547 else if (ptm->tm_year < 1900) /* probably the field directly */
548 /* contains tm_year, like produced */
549 /* by the Timed/Netmgr bug and others */
550 {
551 rval |= FTSC_FLAWY;
552 }
553 else /* 4 digit year field, not correct! */
554 {
555 ptm->tm_year -= 1900;
556 rval |= FTSC_FLAWY;
557 }
558 break;
559 }
560
561
562 return rval;
563
564 }
565
make_ftsc_date(char * pdate,const struct tm * ptm)566 void make_ftsc_date(char *pdate, const struct tm *ptm)
567 {
568 sprintf(pdate, "%02d %-3.3s %02d %02d:%02d:%02d",
569 ptm->tm_mday % 100, months_ab[ptm->tm_mon], ptm->tm_year % 100,
570 ptm->tm_hour % 100, ptm->tm_min % 100, ptm->tm_sec % 100);
571 }
572
readMsgFromPkt(FILE * pkt,s_pktHeader * header,s_message ** message)573 int readMsgFromPkt(FILE *pkt, s_pktHeader *header, s_message **message)
574 {
575 s_message *msg;
576 int len, badmsg=0;
577 struct tm tm;
578 long unread;
579
580 if (2 != getUINT16(pkt)) {
581 *message = NULL;
582
583 unread = ftell(pkt);
584 fseek(pkt, 0L, SEEK_END);
585 unread = ftell(pkt) - unread; /* unread bytes */
586
587 if (unread) {
588 w_log(LL_ERR,"There are %d bytes of unknown data at the end of pkt file!",
589 unread);
590 return 2; /* rename to bad */
591 }
592 else return 0; /* end of pkt file */
593 }
594
595 msg = (s_message*) safe_malloc(sizeof(s_message));
596 memset(msg, '\0', sizeof(s_message));
597
598 msg->origAddr.node = getUINT16(pkt);
599 msg->destAddr.node = getUINT16(pkt);
600 msg->origAddr.net = getUINT16(pkt);
601 msg->destAddr.net = getUINT16(pkt);
602 msg->attributes = getUINT16(pkt);
603
604 getc(pkt); getc(pkt); /* read unused cost fields (2bytes) */
605
606 /* val: fgetsUntil0 (msg->datetime, 22, pkt, NULL);*/
607 if ( fread(msg->datetime, 20, 1, pkt) != 1 ) /* read datetime field - 20 bytes */
608 badmsg++;
609 msg->datetime[20] = 0; /* ensure it's null-terminated */
610 parse_ftsc_date(&tm, (char*)msg->datetime);
611 /* val: make_ftsc_date((char*)msg->datetime, &tm); */
612
613 if (globalBuffer==NULL) {
614 globalBuffer = (UCHAR *) safe_malloc(BUFFERSIZE+1); /* 128K (32K in MS-DOS) */
615 }
616
617 len = fgetsUntil0 ((UCHAR *) globalBuffer, BUFFERSIZE+1, pkt, NULL);
618 if (len > XMSG_TO_SIZE) {
619 if (config->intab) recodeToInternalCharset((char*) globalBuffer);
620 w_log(LL_ERR, "wrong msg header: toUserName (%s) is longer than %d bytes.",
621 globalBuffer, XMSG_TO_SIZE-1);
622 if (config->outtab) recodeToTransportCharset((char*) globalBuffer);
623 globalBuffer[XMSG_TO_SIZE-1]='\0';
624 badmsg++;
625 }
626 xstrcat(&msg->toUserName, (char *) globalBuffer);
627
628 fgetsUntil0((UCHAR *) globalBuffer, BUFFERSIZE+1, pkt, NULL);
629 if (len > XMSG_FROM_SIZE) {
630 if (config->intab) recodeToInternalCharset((char*) globalBuffer);
631 w_log(LL_ERR, "wrong msg header: fromUserName (%s) is longer than %d bytes.",
632 globalBuffer, XMSG_FROM_SIZE-1);
633 if (config->outtab) recodeToTransportCharset((char*) globalBuffer);
634 globalBuffer[XMSG_FROM_SIZE-1]='\0';
635 badmsg++;
636 }
637 xstrcat(&msg->fromUserName, (char *) globalBuffer);
638
639 len = fgetsUntil0((UCHAR *) globalBuffer, BUFFERSIZE+1, pkt, NULL);
640 if (len > XMSG_SUBJ_SIZE) {
641 if (config->intab) recodeToInternalCharset((char*) globalBuffer);
642 w_log(LL_ERR, "wrong msg header: subjectLine (%s) is longer than %d bytes.",
643 globalBuffer, XMSG_SUBJ_SIZE-1);
644 if (config->outtab) recodeToTransportCharset((char*) globalBuffer);
645 globalBuffer[XMSG_SUBJ_SIZE-1]='\0';
646 badmsg++;
647 }
648 xstrcat(&msg->subjectLine, (char *) globalBuffer);
649
650 if (badmsg) {
651 freeMsgBuffers(msg);
652 *message = NULL;
653 w_log(LL_ERR, "wrong msg header: renaming pkt to bad.");
654 return 2; /* exit with error */
655 }
656
657 #if !defined(__DOS__) || defined(__FLAT__)
658 w_dbglog(LL_DEBUG, "readMsgFromPkt() 32bit");
659 do {
660 len = fgetsUntil0((UCHAR *) globalBuffer, BUFFERSIZE+1, pkt, "\n");
661 xstrcat(&msg->text, (char*)globalBuffer);
662 msg->textLength+=len-1; /* trailing \0 is not the text */
663 } while (len == BUFFERSIZE+1);
664 #else
665 w_dbglog(LL_DEBUG, "readMsgFromPkt() DOS-16");
666 /* DOS: read only one segment of message */
667 len = fgetsUntil0((UCHAR *) globalBuffer, BUFFERSIZE+1, pkt, "\n");
668 xstrcat(&msg->text, globalBuffer);
669 msg->textLength+=len-1; /* trailing \0 is not the text */
670
671 if( (len == BUFFERSIZE+1) ) {
672 badmsg++;
673 xstrscat(&msg->text, "\r* Message too big, truncated by ", versionStr, "\r",NULLP);
674 do {
675 char *origin;
676
677 len = fgetsUntil0((UCHAR *) globalBuffer, BUFFERSIZE+1, pkt, "\n");
678 /* add kludges to end of striped text */
679 if((origin=strstr(globalBuffer, " * Origin"))) {
680 xstrcat(&msg->text, origin);
681 }
682 } while (len == BUFFERSIZE+1);
683 strncpy( globalBuffer, aka2str(msg->destAddr), BUFFERSIZE );
684 w_log(LL_ERR, "Message from %s to %s is too big!", aka2str(msg->origAddr),
685 globalBuffer);
686 }
687 #endif
688
689 correctAddr(msg, header);
690 #ifndef DO_PERL
691 {
692 char *p, *q;
693 /* del "\001FLAGS" from message text */
694 if (NULL != (p=strstr(msg->text,"\001FLAGS"))) {
695 for (q=p; *q && *q!='\r'; q++);
696 memmove(p,q+1,msg->textLength-(q-msg->text));
697 msg->textLength -= (q-p+1);
698 }
699 }
700 #endif
701 *message = msg;
702 return 1;
703 }
704