1 #ifndef UNIX
2 #include <conio.h>
3 #else
4 #define getch getchar
5 #ifdef __FreeBSD__
6 #include <sys/time.h>
7 #include <sys/types.h>
8 #endif
9 #include <utime.h>
10 #endif
11 #if defined __BORLANDC__
12 #include <utime.h>
13 #endif
14 #include <stdlib.h> // <malloc.h>
15 #include "buffer.hpp"
16 // #include "datetime.cpp"
17 #include "dirute.h"
18
19 #include "structs.hpp"
20
21 typedef enum {formatMSG, formatSQUISH, formatJAM} format;
22
23 typedef struct
24 {
25 char FromUserName[36];
26 char ToUserName[36];
27 char Subject[72];
28 char OrigDateTime[20];
29 struct
30 {
31 short day,month,year;
32 } date;
33 struct
34 {
35 short hour,minute,second;
36 } time;
37 long ElapsedDays;
38 byte DateParsed;
39 unsigned short attrib;
40 unsigned short attrib2;
41 S_FQAddress Origin,Destination;
42 S_FQAddress TransitAddr,*WishAddresses;
43 short WishAddrCount;
44 byte DetectedLoop;
45 long MessageSize;
46 byte Encrypted;
47 short ProcessedHere;
48 unsigned MSGIDZone;
49 unsigned long MsgNumber;
50 format formattype;
51 } S_Visu;
52
53
FlagAsSent(char * path)54 int FlagAsSent (char *path)
55 {
56 FILE *msg;
57 S_MSG header;
58
59 msg=fopen (path,"r+b");
60 if (msg==NULL)
61 return EFAS_OPENFAILED;
62 if (!header.read(msg)) {
63 fclose(msg);
64 return EFAS_OPENFAILED;
65 }
66 if (fseek (msg,0,SEEK_SET)) {
67 fclose(msg);
68 return EFAS_OPENFAILED;
69 }
70 Set_Sent(header.Attribute,1);
71 if (!header.write(msg)) {
72 fclose (msg);
73 return EFAS_CANTWRITE;
74 }
75 fclose (msg);
76 return SUCCESS;
77 }
78
FindAttachedFile(char * buffer,int maxlen)79 void FindAttachedFile(char *buffer, int maxlen)
80 {
81 char *buf2;
82
83 int i;
84 // first, see if this is an absolute filename
85 // at all
86 if (strchr(buffer, '/') == NULL && strchr(buffer, '\\') == NULL &&
87 strchr(buffer, ':') == NULL)
88 {
89
90 buf2 = (char *)malloc(maxlen + 1 + InboundHandler.GetLongestString());
91 if (buf2 == NULL)
92 { // can't help ...
93 adaptcase(buffer); return;
94 }
95
96 // we have a relative path name. ouch.
97 for (i = 0; i < InboundHandler.GetInboundCount(); i++)
98 {
99 sprintf(buf2, "%s/%s", InboundHandler.GetInbound(i), buffer);
100
101 if (file_exists((char *)buf2))
102 {
103 buf2[maxlen - 1] = '\0';
104 strcpy(buffer, buf2);
105 return;
106 }
107 }
108
109 #ifdef UNIX
110 // next try, this time using the slow adaptcase
111 // code
112 for (i = 0; i < InboundHandler.GetInboundCount(); i++)
113 {
114 sprintf(buf2, "%s/%s", InboundHandler.GetInbound(i), buffer);
115 adaptcase(buf2);
116
117 if (file_exists((char *)buf2))
118 {
119 buf2[maxlen - 1] = '\0';
120 strcpy(buffer, buf2);
121 return;
122 }
123 }
124 #endif
125
126 adaptcase(buf2);
127 }
128 adaptcase(buffer);
129 }
130
SubjectToFile(char * Subject,char * savepath,char * extattach,int Truncate,int Delete)131 int SubjectToFile (char *Subject,char *savepath,char *extattach,int Truncate,int Delete)
132 {
133 FILE *out;
134 char complete[256];
135 strcpy (complete,savepath);
136 strcat (complete,extattach);
137 adaptcase(complete);
138 out=fopen (complete,"r+a");
139 if (out==NULL)
140 {
141 out=makedirandfopen (complete,"w+a");
142 if (out==NULL)
143 return ESTF_FAILURE;
144 }
145 fseek (out,0,SEEK_END);
146 while (Subject[0])
147 {
148 GetAndStripToken (Subject,complete+1);
149 FindAttachedFile(complete + 1, (int)(sizeof(complete) - 1));
150 if (Delete)
151 complete[0]='^';
152 else
153 if (Truncate)
154 complete[0]='#';
155 else
156 strcpy (complete,complete+1);
157 fprintf (out,"%s\n",complete);
158 }
159 fclose (out);
160 return SUCCESS;
161 }
162
StripPath(char * source,char * storage)163 void StripPath (char *source, char *storage)
164 {
165 char token[80],target[80],*c;
166 strcpy (target,source);
167 storage[0]=0;
168 while (strlen (target))
169 {
170 GetAndStripToken (target,token);
171 c=token+strlen (token)-1;
172 while (c>=token && *c!=DIRSEPC && *c!=':')
173 c--;
174 strcat (storage,c+1);
175 strcat (storage," ");
176 }
177 while (strlen (storage) && storage[strlen (storage)-1]==' ')
178 storage[strlen (storage)-1]=0;
179 }
180
SignNet(FILE * onet,S_FQAddress addressinnet)181 int SignNet (FILE *onet,S_FQAddress addressinnet)
182 {
183 DateTime dt;
184 char point[10];
185 dt.getCurrentTime();
186 char ViaLine[120];
187 S_FQAddress OurAddress;
188 AddressHandler.AKAMatch (addressinnet,&OurAddress);
189 if (OurAddress.Point==0)
190 point[0]=0;
191 else
192 sprintf (point,".%hu",OurAddress.Point);
193 sprintf (ViaLine,"%cVia %hu:%hu/%hu%s%s%s @%04hu%02hu%02hu.%02hu%02hu%02hu %s\r",
194 1,OurAddress.Zone,OurAddress.Net,OurAddress.Node,point,
195 OurAddress.Domain[0]?"@":"",OurAddress.Domain,dt.year,
196 dt.month,dt.day,dt.hours,dt.minutes,dt.seconds,
197 IDENTString
198 );
199 fwrite (ViaLine,strlen (ViaLine)+1,1,onet);
200 return SUCCESS;
201 }
202
MSGToPKT(char * MSGPath,char * PKTPath,char * ext,S_FQAddress via,S_FQAddress OurAKA,S_FQAddress FinalDest,int UseT2,int is_qqq)203 int MSGToPKT (char *MSGPath,char *PKTPath,char *ext,S_FQAddress via,S_FQAddress
204 OurAKA,S_FQAddress FinalDest,int UseT2, int is_qqq)
205 {
206 FILE *in,*out;
207 S_MSG headerin;
208 S_Packed headerout;
209 S_PKT headerPKT;
210 DateTime dt;
211 char *buffer,completepath[256];
212 char NoPathSubject[80],lasttwo[2];
213 long ToCopy;
214 size_t BufferSize,read;
215 in=fopen (MSGPath,"rb");
216 if (in==NULL)
217 return ECONV_OPENFAILIN;
218 strcpy (completepath,PKTPath);
219 strcat (completepath,ext);
220 adaptcase(completepath);
221 out=fopen (completepath,"r+b");
222 if (out==NULL)
223 {
224 out=makedirandfopen (completepath,"w+b");
225 if (out==NULL)
226 {
227 fclose (in);
228 return ECONV_OPENFAILOUT;
229 }
230 // The file doesn't exist yet - we have to create it and add
231 // a header
232 dt.getCurrentTime();
233 headerPKT.OrigNode=OurAKA.Node;
234 headerPKT.DestNode=via.Node;
235 headerPKT.Year=dt.year;
236 headerPKT.Month=dt.month - 1;
237 headerPKT.Day=dt.day;
238 headerPKT.Hour=dt.hours;
239 headerPKT.Minute=dt.minutes;
240 headerPKT.Second=dt.seconds;
241 headerPKT.Baud=0;
242 headerPKT.Signature=2;
243 headerPKT.OrigNet=OurAKA.Net;
244 headerPKT.DestNet=via.Net;
245 headerPKT.ProdCode=0;
246 headerPKT.SerialNo=0;
247 memset (&headerPKT.Password,0,8);
248 PasswordHandler.GetPassword (via,headerPKT.Password);
249 headerPKT.OrigZone=OurAKA.Zone;
250 headerPKT.DestZone=via.Zone;
251 memset (&headerPKT.dif.Fill,0,20);
252 memset (&headerPKT.EndOfPKT,0,sizeof (headerPKT.EndOfPKT));
253 if (UseT2==0) // Add type2+ data
254 {
255 headerPKT.dif.t2plus.CapabilitySwapped=256;
256 headerPKT.dif.t2plus.Capability=1;
257 headerPKT.dif.t2plus.PrdCodH=1;
258 headerPKT.dif.t2plus.PVMinor=1;
259 headerPKT.dif.t2plus.OrigZone=OurAKA.Zone;
260 headerPKT.dif.t2plus.DestZone=via.Zone;
261 headerPKT.dif.t2plus.OrigPoint=OurAKA.Point;
262 headerPKT.dif.t2plus.DestPoint=via.Point;
263 }
264 headerPKT.write(out);
265 }
266 if (!headerin.read(in))
267 {
268 fclose (in);
269 fclose (out);
270 return ECONV_SHORTIN;
271 }
272
273 if (DoRecode) {
274 recodeToTransportCharset (headerin.FromUserName, 36);
275 recodeToTransportCharset (headerin.ToUserName, 36);
276 recodeToTransportCharset (headerin.Subject, 72);
277 recodeToTransportCharset (headerin.DateTime, 20);
278 }
279
280 /* We truncate the last 2 bytes of the .PKT if they are both zero.
281 Otherwise it is likely that the .PKT is damaged and it is better
282 not to destroy anything on it */
283 fseek (out,-2,SEEK_END);
284 fread (lasttwo,1,2,out);
285 if (lasttwo[0]==0 && lasttwo[1]==0)
286 fseek (out,-2,SEEK_END);
287
288 headerout.Signature=2;
289 headerout.OrigNode=headerin.OrigNode;
290 headerout.OrigNet=headerin.OrigNet;
291 headerout.DestNode=headerin.DestNode;
292 headerout.DestNet=headerin.DestNet;
293 headerout.Attrib=headerin.Attribute;
294 // Note that the InTransit and local flags are stripped (!!)
295 Set_InTransit(headerout.Attrib,0);
296 Set_Local(headerout.Attrib,0);
297 headerout.Cost=0;
298 memcpy (&headerout.DateTime,&headerin.DateTime,20);
299 headerout.write(out);
300 fwrite (&headerin.ToUserName,1,strlen (headerin.ToUserName)+1,out);
301 fwrite (&headerin.FromUserName,1,strlen (headerin.FromUserName)+1,out);
302 if (S_FileAttached(headerin.Attribute))
303 StripPath (headerin.Subject,NoPathSubject);
304 else
305 strcpy (NoPathSubject,headerin.Subject);
306 fwrite (NoPathSubject,1,strlen (NoPathSubject)+1,out);
307 ToCopy=lengthoffile(in)-headerin.get_filesize(); // sizeof (S_MSG);
308 BufferSize=(ToCopy>32767)?32767:(size_t) ToCopy;
309 while (((buffer=(char *) malloc (BufferSize)) == NULL) && (BufferSize>1024))
310 BufferSize = (BufferSize / 10) * 9;
311 if (buffer==NULL)
312 {
313 fclose (in);
314 fclose (out);
315 return NOMEMORY;
316 }
317 /* Note that in the body copy loop we copy up to, but not including,
318 the first zero. If there is something beyond that zero, it won't
319 be copied, because that would result in a damaged .PKT. */
320 if (ToCopy>0)
321 {
322 while (ToCopy>0)
323 {
324 if (ToCopy>(long)((unsigned long)BufferSize))
325 read=fread (buffer,1,BufferSize,in);
326 else
327 read=fread (buffer,1,(size_t) ToCopy,in);
328 if (strlen (buffer)<read)
329 {
330 read=strlen (buffer);
331 ToCopy=read;
332 }
333 if (DoRecode)
334 recodeToTransportCharset (buffer, read);
335 fwrite (buffer,1,read,out);
336 ToCopy-=read;
337 }
338 if (buffer[read-1]!='\r')
339 fwrite ("\r",1,1,out);
340 }
341 /* Add our via line - note that it has a zero to end the message */
342 SignNet (out,FinalDest);
343 /* End of PKT 00 00 - added UNLESS we are generating .QQQs, to
344 follow Tobias Burchhardt's specs */
345 if (!is_qqq)
346 {
347 memset (&headerPKT.EndOfPKT,0,sizeof (headerPKT.EndOfPKT));
348 fwrite (&headerPKT.EndOfPKT,1,sizeof (headerPKT.EndOfPKT),out);
349 }
350 free (buffer);
351 fclose (in);
352 fclose (out);
353 return (SUCCESS);
354 }
355
ToNextWord(char * begin)356 char *ToNextWord (char *begin)
357 {
358 int sp=0;
359 if (*begin=='\0')
360 return NULL;
361 if (*begin==' ')
362 sp=1;
363 while (*begin && *begin==' ') // Skip all spaces
364 begin++;
365 if (*begin=='\0')
366 return NULL;
367 if (sp)
368 return begin; // We are a the beginning of a new world
369 while (*begin && *begin!=' ') // To end of word
370 begin++;
371 while (*begin && *begin==' ') // Skip all spaces
372 begin++;
373 if (*begin=='\0')
374 return NULL;
375 return begin;
376 }
377
378 // Scan begin for a possible address
ScanForAddress(char * begin)379 char *ScanForAddress (char *begin)
380 {
381 char *store;
382 char *s,*as;
383 int qualify=0;
384 S_FQAddress Address;
385 store=(char *) malloc (strlen (begin)+1);
386 if (!store)
387 return NULL;
388 s=begin;
389 while (qualify==0 && s)
390 {
391 strcpy (store,s);
392 as=strchr (store,' ');
393 if (as) // Keep only to end of word
394 *as=0;
395 as=strchr (store,'@'); // We don't mind about domain stuff
396 if (as)
397 *as=0;
398 if (GetFullQualifiedAddress (store,&Address,NULL)==SUCCESS)
399 qualify=1;
400 else
401 s=ToNextWord (s);
402 }
403 free (store);
404 return s;
405 }
406
407 /* Process line for kludges, vias, etc */
ProcessLine(char * line,S_Visu * storage,C_StringList * SL_Via,C_StringList * SL_Path)408 void ProcessLine (char *line,S_Visu *storage,C_StringList *SL_Via, C_StringList *SL_Path)
409 {
410 struct S_FQAddress FQA;
411 C_FileRead FHandler;
412 char *first,*search,*possible,newpath[26];
413 char Parsing[21];
414 first=(char *) line;
415 if (first[0]==1) // Kludge!
416 {
417 if (strstr (first+1,"ENC")==first+1)
418 storage->Encrypted=1;
419 else
420 if (strstr (first+1,"Via")==first+1) // Already processed...
421 {
422 possible=ScanForAddress (first);
423 if (possible!=NULL)
424 {
425 GetFullQualifiedAddress (possible,&FQA,NULL);
426 if (SL_Path!=NULL)
427 {
428 sprintf (newpath,"%u:%u/%u.%u",FQA.Zone,
429 FQA.Net,FQA.Node,FQA.Point);
430 if (SL_Path->GetStringCount ()==0)
431 SL_Path->AddString (newpath);
432 else
433 if (strcmp (SL_Path->GetString (SL_Path->GetStringCount()-1),newpath))
434 SL_Path->AddString (newpath);
435 }
436 if (AddressHandler.IsLocalAKA (FQA))
437 {
438 storage->ProcessedHere=1;
439 if (!RecordViaLines)
440 if (SL_Via != NULL)
441 SL_Via->DestroyList ();
442 }
443 else
444 /* If there was a previous Via line with one of
445 our addresses but current isn't local, then
446 we have a loop */
447 if (storage->ProcessedHere==1)
448 storage->DetectedLoop=1;
449 }
450 if (SL_Via!=NULL)
451 SL_Via->AddString (first+1);
452 }
453 else
454 if (strstr (first+1,"MSGID")==first+1) // MSGID
455 {
456 search=first+8;
457 while (*search)
458 {
459 if (!isdigit (*search))
460 break;
461 search++;
462 }
463 if (*search==':') // It is a zone
464 {
465 *search=0;
466 storage->MSGIDZone=atoi (first+8);
467 }
468 }
469 else
470 if (strstr (first+1,"TOPT")==first+1) // Destination point
471 {
472 if (isdigit (*(first+6))) // Always should but...
473 {
474 search=first+6;
475 while (isdigit (*search))
476 search++;
477 *search=0;
478 storage->Destination.Point=atoi (first+6);
479 }
480 }
481 if (strstr (first+1,"FMPT")==first+1) // Destination point
482 {
483 if (isdigit (*(first+6))) // Always should but...
484 {
485 search=first+6;
486 while (isdigit (*search))
487 search++;
488 *search=0;
489 storage->Origin.Point=atoi (first+6);
490 }
491 }
492 if (strstr (first+1,"INTL")==first+1) // Zones
493 {
494 search=strchr (first+6,' ');
495 if (search)
496 {
497 *search=0;
498 if (GetFullQualifiedAddress (first+6,&FQA,NULL)==SUCCESS)
499 {
500 storage->Destination.Zone=FQA.Zone;
501 storage->Destination.Net=FQA.Net;
502 storage->Destination.Node=FQA.Node;
503 if (GetFullQualifiedAddress (search+1,&FQA,NULL)==SUCCESS)
504 {
505 storage->Origin.Zone=FQA.Zone;
506 storage->Origin.Net=FQA.Net;
507 storage->Origin.Node=FQA.Node;
508 }
509 }
510 }
511 }
512 if (strstr (first+1,"FLAGS")==first+1)
513 {
514 first++;
515 GetAndStripToken (first,Parsing); // remove 'flags'
516 while (first[0])
517 {
518 GetAndStripToken (first,Parsing);
519 switch (GetTokenType (Parsing))
520 {
521 case TT_PVT:
522 Set_Private(storage->attrib,1);
523 break;
524 case TT_HLD:
525 Set_Hold(storage->attrib,1);
526 break;
527 case TT_CRA:
528 Set_Crash(storage->attrib,1);
529 break;
530 case TT_KS:
531 Set_KillSent(storage->attrib,1);
532 break;
533 case TT_SNT:
534 Set_Sent(storage->attrib,1);
535 break;
536 case TT_RCV:
537 Set_Recd(storage->attrib,1);
538 break;
539 case TT_AS:
540 Set_ArchiveSent(storage->attrib2,1);
541 break;
542 case TT_DIR:
543 Set_Direct(storage->attrib2,1);
544 break;
545 case TT_ZON:
546 Set_Zonegate(storage->attrib2,1);
547 break;
548 case TT_HUB:
549 Set_Hub(storage->attrib2,1);
550 break;
551 case TT_FIL:
552 Set_FileAttached(storage->attrib,1);
553 break;
554 case TT_FRQ:
555 Set_FileRequest(storage->attrib,1);
556 break;
557 case TT_IMM:
558 Set_Immediate(storage->attrib2,1);
559 break;
560 case TT_XMA:
561 Set_XMA(storage->attrib2,1);
562 break;
563 case TT_KFS:
564 Set_KillFileSent(storage->attrib2,1);
565 break;
566 case TT_TFS:
567 Set_Truncate(storage->attrib2,1);
568 break;
569 case TT_LOK:
570 Set_Lock(storage->attrib2,1);
571 break;
572 case TT_RRQ:
573 Set_ReturnReceiptRequest(storage->attrib,1);
574 break;
575 case TT_CFM:
576 Set_IsReturnReceipt(storage->attrib,1);
577 break;
578 case TT_HIR:
579 Set_HiRes(storage->attrib2,1);
580 break;
581 case TT_COV:
582 Set_CoverLetter(storage->attrib2,1);
583 break;
584 case TT_SIG:
585 Set_Signature(storage->attrib2,1);
586 break;
587 case TT_LET:
588 Set_LetterHead(storage->attrib2,1);
589 break;
590 case TT_FAX:
591 Set_Fax(storage->attrib2,1);
592 break;
593 case TT_FPU:
594 Set_ForcePickup(storage->attrib2,1);
595 break;
596 }
597 }
598 }
599 }
600 }
601
602 // Transform the (useless) standard .MSG format in something we can
603 // handle easily.
GetVisibleInfo(char * path,S_Visu * storage,C_StringList * SL_Via,C_StringList * SL_Path)604 int GetVisibleInfo (char *path,S_Visu *storage,C_StringList *SL_Via, C_StringList *SL_Path)
605 {
606 DateTime dtnow;
607 S_MSG header;
608 struct S_FQAddress FQA;
609 C_FileRead FHandler;
610 void *buffer;
611 char newpath[26];
612 char Parsing[21];
613 int count;
614 char *ptr;
615 size_t path_len;
616 storage->ProcessedHere=0;
617 storage->MSGIDZone=0;
618
619 // try to get MsgNumber from path
620 path_len = strlen (path);
621 if (path_len >= 5 &&
622 isdigit (path[path_len-5]) &&
623 path[path_len-4] == '.' &&
624 (path[path_len-3] == 'M' || path[path_len-3] == 'm') &&
625 (path[path_len-2] == 'S' || path[path_len-2] == 's') &&
626 (path[path_len-1] == 'G' || path[path_len-1] == 'g')) {
627 ptr = path + path_len - 5;
628 while (isdigit (*ptr))
629 ptr--;
630 ptr++;
631 storage->MsgNumber = strtol (ptr, NULL, 10);
632 } else
633 storage->MsgNumber = 0;
634 storage->formattype = formatMSG;
635
636 // Get as much info as possible from the header
637 if (FHandler.OpenFile (path)!=SUCCESS)
638 return ENH_OPENFAIL;
639 storage->MessageSize=FHandler.FileSize()-header.get_filesize();
640 // sizeof (S_MSG);
641 buffer=malloc (BUFFER_SIZE); // Buffer to get lines
642 if (buffer==NULL)
643 {
644 FHandler.CloseFile ();
645 return NOMEMORY;
646 }
647 // Read header
648 if (!header.read(FHandler))
649 {
650 FHandler.CloseFile ();
651 free (buffer);
652 return ENH_SHORTFILE;
653 }
654 // Empty zones, point & domain
655 AddressHandler.GetMain (&FQA);
656 storage->Origin.Zone=storage->Destination.Zone=0;
657 storage->Origin.Point=storage->Destination.Point=0;
658 storage->Origin.Domain[0]=storage->Destination.Domain[0]=0;
659 storage->DetectedLoop=0;
660 // Empty encryption
661 storage->Encrypted=0;
662 // Names and subject
663 strcpy (storage->FromUserName,header.FromUserName);
664 strcpy (storage->ToUserName,header.ToUserName);
665 strcpy (storage->Subject,header.Subject);
666 // Original date & time string
667 strcpy (storage->OrigDateTime,header.DateTime);
668 // Attempt to parse the time and date
669 storage->DateParsed=0;
670 strcpy (Parsing,header.DateTime);
671 if (isdigit (Parsing[0]) && isdigit (Parsing[1]) && Parsing[2]==' ' &&
672 isalpha (Parsing[3]) && isalpha (Parsing[4]) && isalpha(Parsing[5]) &&
673 Parsing[6]==' ' && isdigit(Parsing[7]) && isdigit(Parsing[8]) &&
674 Parsing[9]==' ' && Parsing[10]==' ' && isdigit(Parsing[11]) &&
675 isdigit(Parsing[12]) && Parsing[13]==':' && isdigit(Parsing[14]) &&
676 isdigit(Parsing[15]) && Parsing[16]==':' && isdigit(Parsing[17]) &&
677 isdigit(Parsing[18]))
678 {
679 // If here it has the expected format - separate tokens
680 Parsing[2]=Parsing[6]=Parsing[9]=Parsing[13]=Parsing[16]=0;
681 storage->date.day=atoi (Parsing);
682 storage->date.month=0;
683 for (count=0;count<12;count++)
684 {
685 if (cistrcmp (Parsing+3,Months[count])==0)
686 {
687 storage->date.month=count+1;
688 break;
689 }
690 }
691 if (storage->date.month!=0) // If we don't have a month, quit parsing
692 {
693 storage->date.year=1900 + atoi (Parsing+7);
694 storage->time.hour=atoi (Parsing+11);
695 storage->time.minute=atoi (Parsing+14);
696 storage->time.second=atoi (Parsing+17);
697 storage->DateParsed=1;
698
699 /* sliding window adaption of year number */
700
701 dtnow.getCurrentTime();
702 while (storage->date.year + 50 <= dtnow.year)
703 storage->date.year += 100;
704 while (storage->date.year - 50 > dtnow.year)
705 storage->date.year -= 100;
706 }
707 }
708 storage->attrib=header.Attribute;
709 storage->attrib2=0;
710 Set_Direct(storage->attrib2, S_Unused(storage->attrib));
711 storage->Origin.Net=header.OrigNet;
712 storage->Origin.Node=header.OrigNode;
713 storage->Destination.Net=header.DestNet;
714 storage->Destination.Node=header.DestNode;
715 // We still need the origin and destination zones & points
716 // they are somewhere in the message text...
717 while (FHandler.ReadUpTo (buffer,"\r\n")!=EBH_EOF)
718 {
719 ProcessLine ((char *) buffer,storage,SL_Via, SL_Path);
720 }
721 if (storage->Origin.Zone==0)
722 storage->Origin.Zone=storage->MSGIDZone;
723 if (storage->Destination.Zone==0)
724 storage->Destination.Zone=storage->MSGIDZone;
725 AddressHandler.GetMain (&FQA);
726 if (storage->Origin.Zone==0)
727 storage->Origin.Zone=FQA.Zone;
728 if (storage->Destination.Zone==0)
729 storage->Destination.Zone=FQA.Zone;
730 memcpy (&storage->TransitAddr,&storage->Destination,sizeof (struct S_FQAddress));
731 // Handle hostgated messages
732 if (S_Hub(storage->attrib2)==1)
733 {
734 if (AddressHandler.OurNet (storage->Destination.Zone,storage->Destination.Net)==EAD_FOREIGN)
735 {
736 storage->TransitAddr.Node=0;
737 storage->TransitAddr.Point=0;
738 }
739 }
740 // Handle zonegated messages
741 if (S_Zonegate(storage->attrib2)==1)
742 {
743 if (AddressHandler.OurZone (storage->Destination.Zone)==EAD_FOREIGN)
744 { // To a foreign zone...
745 // Example: From 2:* to 1:* becomes 2:2/1.0.
746 storage->TransitAddr.Net=storage->Destination.Zone;
747 storage->TransitAddr.Zone=storage->Destination.Zone;
748 storage->TransitAddr.Node=storage->Origin.Zone;
749 storage->TransitAddr.Point=0;
750 }
751 }
752 sprintf (newpath,"%u:%u/%u.%u",storage->Origin.Zone,
753 storage->Origin.Net,storage->Origin.Node,storage->Origin.Point);
754 if (SL_Path!=NULL)
755 {
756 if (SL_Path->GetStringCount ()==0)
757 SL_Path->AddString (newpath);
758 else
759 if (strcmp (SL_Path->GetString (0),newpath))
760 SL_Path->InsertString (newpath,0);
761 }
762 free (buffer);
763 FHandler.CloseFile ();
764 return SUCCESS;
765 }
766
ShowNet(char * path)767 int ShowNet (char *path)
768 {
769 S_MSG header;
770 S_Visu extra;
771 FILE *fnet;
772 void *buffer;
773 char *point,*first;
774 int count=0;
775 fnet=fopen (path,"rb");
776 if (fnet==NULL)
777 return ENH_OPENFAIL;
778 buffer=malloc (2048);
779 if (buffer==NULL)
780 {
781 fclose (fnet);
782 return NOMEMORY;
783 }
784 fread (buffer,2048,1,fnet);
785 ((char *)buffer)[2047]=0;
786 header.Import((const unsigned char *)buffer);
787 printf (" From: %s\n",header.FromUserName);
788 printf (" To: %s\n",header.ToUserName);
789 printf (" Subject: %s\n",header.Subject);
790 printf (" DateTime: %s\n",header.DateTime);
791 printf (" Times read: %u\n",header.TimesRead);
792 printf ("Destination node: %u\n",header.DestNode);
793 printf (" Origin node: %u\n",header.OrigNode);
794 printf (" Cost: %u\n",header.Cost);
795 printf (" Origin net: %u\n",header.OrigNet);
796 printf (" Destination net: %u\n",header.DestNet);
797 printf (" Reply-to: %u\n",header.ReplyTo);
798 printf (" Attributes: %u\n",header.Attribute);
799 printf (" NextReply: %u\n",header.NextReply);
800 printf (" Rest of text: \n");
801 first=((char *) buffer) + header.get_filesize();
802 while ((point=strchr (first,'\r'))!=NULL && count<8)
803 {
804 if (first+75<point)
805 point=first+75;
806 *point=0;
807 printf ("%s\r\n",first);
808 first=point+1;
809 count++;
810 }
811 free (buffer);
812 fclose (fnet);
813 getch ();
814 GetVisibleInfo (path,&extra,NULL,NULL);
815 //clrscr ();
816 printf ("Information as returned by GetVisibleInfo ().\n");
817 printf (" Sender: %s (%u:%u/%u.%u)\n",extra.FromUserName,
818 extra.Origin.Zone,extra.Origin.Net,extra.Origin.Node,extra.Origin.Point);
819 printf (" Receiver: %s (%u:%u/%u.%u)\n",extra.ToUserName,
820 extra.Destination.Zone,extra.Destination.Net,extra.Destination.Node,extra.Destination.Point);
821 printf (" Subject: %s\n",extra.Subject);
822 printf ("Original date & time: %s ",extra.OrigDateTime);
823 if (extra.DateParsed)
824 {
825 printf ("Parsed: %02u-%02u-%04u %02u:%02u:%02u",
826 extra.date.day,extra.date.month,extra.date.year,
827 extra.time.hour,extra.time.minute,extra.time.second);
828 }
829 printf ("\nAttributes: ");
830 printf ("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
831 S_Private(extra.attrib)?"Pvt":" ",
832 S_Crash(extra.attrib)?"Cra":" ",
833 S_Recd(extra.attrib)?"Rev":" ",
834 S_Sent(extra.attrib)?"Snt":" ",
835 S_FileAttached(extra.attrib)?"Att":" ",
836 S_InTransit(extra.attrib)?"Trs":" ",
837 S_Orphan(extra.attrib)?"Orp":" ",
838 S_KillSent(extra.attrib)?"K/S":" ",
839 S_Local(extra.attrib)?"Loc":" ",
840 S_Hold(extra.attrib)?"Hld":" ",
841 S_Unused(extra.attrib)?"Dir":" ",
842 S_FileRequest(extra.attrib)?"Frq":" ",
843 S_ReturnReceiptRequest(extra.attrib)?"RRQ":" ",
844 S_IsReturnReceipt(extra.attrib)?"ReR":" ",
845 S_AuditRequest(extra.attrib)?"Aud":" ",
846 S_FileUpdateReq(extra.attrib)?"UpR":" ");
847 getch ();
848 return (SUCCESS);
849 }
850
851 // DoQQQPack() determines whether a mail should be packed into the
852 // Binkley outbound or into a .QQQ files. A message only qualifies for
853 // being packed into a QQQ file if:
854 // - FASTECHOPACK has been specified in the cfroute cfg
855 // - FECFONIG has been specified in the cfroute cfg
856 // - the mail is not crash, direct, immediate or hold, or has a file
857 // attached
858 // - the destination system is listed in fastecho.cfg
859 // (which can be seen from the fact if PasswordHandler knows this
860 // system or not).
861
DoQQQPack(S_FQAddress via,int AttribPack)862 int DoQQQPack(S_FQAddress via, int AttribPack)
863 {
864 if ((FastechoPack == 2) || /* Pack anything as QQQ */
865 (FastechoPack == 1 && /* Pack mail to listed links only */
866 PasswordHandler.GetPassword(via, (char *)NULL) == SUCCESS &&
867 /* destination system is a link */
868 AttribPack == TT_NORMAL))
869 /* no "priority" flag is set */
870 return 1;
871 return 0;
872 }
873
FindUniqueQQQ(char * storage)874 void FindUniqueQQQ (char *storage)
875 {
876 char rname[9],temp[80];
877 int c,r;
878 FILE *o;
879 for (;;) /* Keep trying until we succeed */
880 {
881 for (c=0;c<8;c++)
882 {
883 r=rand()%16;
884 if (r>=10)
885 rname[c]=r+'A'-10;
886 else
887 rname[c]=r+'0';
888 }
889 rname[8]=0;
890 sprintf (storage,"%s"DIRSEPS"%s.",QQQOutboundDirectory,rname);
891 sprintf (temp,"%sQQQ",storage);
892 adaptcase(temp);
893 o=fopen (temp,"rb");
894 if (o!=NULL)
895 fclose (o);
896 else /* Failed to open it - finally... */
897 return;
898 }
899 }
900
FindPKTPath(S_FQAddress destination,char * storage)901 int FindPKTPath (S_FQAddress destination,char *storage)
902 {
903 S_FQAddress work;
904 int UseDefaultOutbound;
905 *storage=0;
906 char Domain[256],temp[256],*lookup;
907 int count;
908 if (AddressHandler.GetMain (&work)!=SUCCESS)
909 return (EAD_NOMAIN);
910 // If there isn't domain information, we use zones ONLY
911 if (work.Domain[0]==0 || destination.Domain[0]==0)
912 if (destination.Zone==work.Zone)
913 UseDefaultOutbound=1;
914 else
915 UseDefaultOutbound=0;
916 else
917 // Use specified domain, if there is one
918 if (cistrcmp (work.Domain,destination.Domain)==0 &&
919 destination.Zone==work.Zone)
920 UseDefaultOutbound=1;
921 else
922 UseDefaultOutbound=0;
923 if (UseDefaultOutbound)
924 sprintf (temp,"%s"DIRSEPS,OutboundDirectory);
925 else
926 {
927 if (destination.Domain[0]!=0)
928 strcpy (Domain,destination.Domain);
929 else
930 {
931 Domain[0]=0;
932 for (count=1;count<=AddressHandler.GetAKACount();count++)
933 {
934 AddressHandler.GetAKA (&work,count);
935 if (destination.Zone==work.Zone)
936 {
937 strcpy (Domain,work.Domain);
938 break;
939 }
940 }
941 }
942 // If no domain, simply add the zone number to the outbound
943 if (Domain[0]==0 || NoDomainDir)
944 sprintf (temp,"%s.%03X"DIRSEPS,OutboundDirectory,destination.Zone);
945 else
946 {
947 lookup=strchr (Domain,'.');
948 if (lookup!=NULL)
949 *lookup=0;
950 strcpy (temp,OutboundDirectory);
951 lookup=temp+strlen (temp)-1;
952 while (*lookup!=DIRSEPC)
953 lookup--;
954 sprintf (lookup+1,
955 "%s.%03X"DIRSEPS,Domain,destination.Zone);
956 }
957 }
958 // OK, here we have the path - add the node
959 sprintf (storage,"%s%04X%04X.",temp,destination.Net,destination.Node);
960 // is it a point?
961 if (destination.Point!=0)
962 {
963 sprintf (temp,"PNT"DIRSEPS"%08X.",destination.Point);
964 strcat (storage,temp);
965 }
966 return SUCCESS;
967 }
968
BufferHeader(S_Visu * header,C_StringList * SL_Header)969 void BufferHeader (S_Visu *header, C_StringList *SL_Header)
970 {
971 char buffer[256];
972 sprintf (buffer,"From: %-40s (%u:%u/%u.%u)\n",header->FromUserName,
973 header->Origin.Zone,header->Origin.Net,header->Origin.Node,
974 header->Origin.Point);
975 SL_Header->AddString (buffer);
976 sprintf (buffer," To: %-40s (%u:%u/%u.%u)\n",header->ToUserName,
977 header->Destination.Zone,header->Destination.Net,
978 header->Destination.Node,header->Destination.Point);
979 SL_Header->AddString (buffer);
980 sprintf (buffer,"Subj: %s\n",header->Subject);
981 SL_Header->AddString (buffer);
982 if (header->DateParsed)
983 {
984 sprintf (buffer,"Date: %02hu-%02hu-%04hu %02hu:%02hu:%02hu - %ld days ago",
985 header->date.day,header->date.month,header->date.year,
986 header->time.hour,header->time.minute,header->time.second,
987 (long) GetToday()-GetJulianDate (header->date.day,header->date.month,header->date.year));
988 }
989 else
990 sprintf (buffer,"Date: %s (non-standard)",header->OrigDateTime);
991 sprintf (buffer+strlen (buffer)," - Body size: %lu",header->MessageSize);
992 if (header->Encrypted)
993 strcat (buffer," - Encrypted");
994 strcat (buffer,"\n");
995 SL_Header->AddString (buffer);
996 sprintf (buffer,"Attr: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
997 S_Private(header->attrib)?"Pvt ":"", // Doesn't mind for routing
998 S_Crash(header->attrib)?"Cra ":"", // Direct
999 S_Recd(header->attrib)?"Rev ":"", // D.M.F.R.
1000 S_Sent(header->attrib)?"Snt ":"", // Sent - do not touch
1001 S_FileAttached(header->attrib)?"Att ":"",//D.M.F.R.
1002 S_InTransit(header->attrib)?"Trs ":"", //D.M.F.R.
1003 S_Orphan(header->attrib)?"Orp ":"", //D.M.F.R.
1004 S_KillSent(header->attrib)?"K/S ":"",//D.M.F.R.
1005 S_Local(header->attrib)?"Loc ":"", //D.M.F.R.
1006 S_Hold(header->attrib)?"Hld ":"", // Direct
1007 S_Unused(header->attrib)?"Dir ":"", // D.M.F.R.
1008 S_FileRequest(header->attrib)?"Frq ":"", // Direct
1009 S_ReturnReceiptRequest(header->attrib)?"RRQ ":"", // D.M.F.R.
1010 S_IsReturnReceipt(header->attrib)?"ReR ":"", // D.M.F.R.
1011 S_AuditRequest(header->attrib)?"Aud ":"", // D.M.F.R.
1012 S_FileUpdateReq(header->attrib)?"UpR ":"", // Direct
1013
1014 S_ArchiveSent(header->attrib2)?"A/S ":"",
1015 S_KillFileSent(header->attrib2)?"KFS ":"",
1016 (S_Direct(header->attrib2)
1017 && (!(S_Unused(header->attrib)))) ? "Dir ":"",
1018 S_Zonegate(header->attrib2)?"Zon ":"",
1019 S_Hub(header->attrib2)?"Hub ":"",
1020 S_Immediate(header->attrib2)?"Imm ":"",
1021 S_XMA(header->attrib2)?"XMA ":"",
1022 S_Lock(header->attrib2)?"Lok ":"",
1023 S_Truncate(header->attrib2)?"Tru ":"",
1024 S_HiRes(header->attrib2)?"HiR ":"",
1025 S_CoverLetter(header->attrib2)?"CvL ":"",
1026 S_Signature(header->attrib2)?"Sig ":"",
1027 S_LetterHead(header->attrib2)?"LeH ":"",
1028 S_Fax(header->attrib2)?"Fax ":"",
1029 S_ForcePickup(header->attrib2)?"FPU ":"");
1030 SL_Header->AddString (buffer);
1031 }
1032
GetSendType(S_Visu * header,C_StringList * SL_Routeto)1033 int GetSendType (S_Visu *header,C_StringList *SL_Routeto)
1034 {
1035 int SendType;
1036 char buffer[256];
1037 SendType=ST_ROUTE;
1038 if (AddressHandler.IsLocalAKA (header->Destination))
1039 {
1040 SL_Routeto->AddString (" Via: None (addressed to this system)\n");
1041 SendType=ST_NOTOUCH;
1042 }
1043 else
1044 // Determine the kind of routing
1045 // Conditions that will force the message NOT to be processed
1046 {
1047 if (S_Crash(header->attrib) ||
1048 S_Hold(header->attrib) ||
1049 S_FileRequest(header->attrib) ||
1050 S_FileUpdateReq(header->attrib) ||
1051 S_Direct(header->attrib2)==1 ||
1052 S_Immediate(header->attrib2)==1 ||
1053 S_ForcePickup(header->attrib2)==1)
1054 {
1055 SendType=ST_DIRECT;
1056 if (header->Destination.Point!=0 && (RouteBossDirect==1 && (S_Crash(header->attrib) ||
1057 S_Immediate(header->attrib2)==1 || S_Direct(header->attrib2)==1 &&
1058 (S_FileRequest(header->attrib)==0 && S_FileUpdateReq(header->attrib)==0))))
1059 SendType=ST_BOSS;
1060 if (header->Destination.Point!=0 && (RouteBossHold==1 && (S_Hold(header->attrib) ||
1061 S_ForcePickup(header->attrib2)==1)))
1062 SendType=ST_BOSS;
1063 if (SendType == ST_BOSS)
1064 {
1065 S_FQAddress ShouldGo;
1066 memcpy (&ShouldGo,&header->Destination,
1067 sizeof (S_FQAddress));
1068 ShouldGo.Point=0;
1069 if (AddressHandler.IsLocalAKA(ShouldGo))
1070 {
1071 SendType = ST_DIRECT;
1072 // Mail that is destined to a
1073 // point of our own is always
1074 // sent direct
1075 }
1076 }
1077
1078 }
1079 // Handle hostgated messages
1080 if (S_Hub(header->attrib2)==1)
1081 {
1082 if (AddressHandler.OurNet (header->Destination.Zone,
1083 header->Destination.Net)==
1084 EAD_FOREIGN)
1085 {
1086 sprintf (buffer,"(Hostgated to %u:%u/%u.%u)\n",
1087 header->TransitAddr.Zone,
1088 header->TransitAddr.Net,
1089 header->TransitAddr.Node,
1090 header->TransitAddr.Point);
1091 SL_Routeto->AddString (buffer);
1092 }
1093 }
1094 // Handle zonegated messages
1095 if (S_Zonegate(header->attrib2)==1)
1096 {
1097 if (AddressHandler.OurZone (header->Destination.Zone)==EAD_FOREIGN)
1098 { // To a foreign zone...
1099 // Example: From 2:* to 1:* becomes 2:2/1.0.
1100 sprintf (buffer,"(Zonegated to %u:%u/%u.%u)\n",
1101 header->TransitAddr.Zone,header->TransitAddr.Net,
1102 header->TransitAddr.Node,header->TransitAddr.Point);
1103 SL_Routeto->AddString (buffer);
1104 }
1105 }
1106 }
1107 return (SendType);
1108 }
1109
DetermineRouteToSystem(S_Visu * header,int SendType,C_StringList * SL_Routeto,S_FQAddress * ShouldGo,int * AttribPack,char * ext,char * extattach)1110 int DetermineRouteToSystem (S_Visu *header,int SendType,
1111 C_StringList *SL_Routeto,S_FQAddress *ShouldGo,int *AttribPack,
1112 char *ext,char *extattach)
1113 {
1114 int GotSystem=0;
1115 char buffer[256];
1116 switch (SendType)
1117 {
1118 case ST_NOTOUCH:
1119 SL_Routeto->AddString ("Attributes caused message not to be processed.\n");
1120 break;
1121 case ST_ROUTE:
1122 if (RouteHandler.FindPackSystem (header->TransitAddr,
1123 header->Origin,S_FileAttached(header->attrib),
1124 header->Encrypted,ShouldGo,AttribPack))
1125 {
1126 sprintf (buffer," Via: %u:%u/%u.%u as ",
1127 ShouldGo->Zone,ShouldGo->Net,ShouldGo->Node,ShouldGo->Point);
1128 GotSystem=1;
1129 }
1130 else
1131 {
1132 SL_Routeto->AddString (" Via: None (no route defined for this message).\n");
1133 SendType=ST_NOTOUCH;
1134 GotSystem=0;
1135 }
1136 break;
1137 case ST_DIRECT:
1138 memcpy (ShouldGo,&header->Destination,sizeof (S_FQAddress));
1139 *AttribPack=TT_NORMAL;
1140 sprintf (buffer," Via: Direct to %u:%u/%u.%u as ",
1141 ShouldGo->Zone,ShouldGo->Net,ShouldGo->Node,ShouldGo->Point);
1142 GotSystem=1;
1143 break;
1144 case ST_BOSS:
1145 memcpy (ShouldGo,&header->Destination,sizeof (S_FQAddress));
1146 ShouldGo->Point=0;
1147 *AttribPack=TT_NORMAL;
1148 sprintf (buffer," Via: Boss %u:%u/%u.%u as ",
1149 ShouldGo->Zone,ShouldGo->Net,ShouldGo->Node,ShouldGo->Point);
1150 GotSystem=1;
1151 break;
1152 }
1153 // The final attribute may be different that the one
1154 // on the route-to sentences
1155 if (GotSystem==1)
1156 {
1157 if (S_Hold(header->attrib) && S_Crash(header->attrib))
1158 *AttribPack=TT_DIR;
1159 else
1160 if (S_Hold(header->attrib))
1161 *AttribPack=TT_HOLD;
1162 else
1163 if (S_Crash(header->attrib))
1164 *AttribPack=TT_CRASH;
1165 else
1166 if (S_Direct(header->attrib2)==1)
1167 *AttribPack=TT_DIR;
1168 else
1169 if (S_Immediate(header->attrib2)==1)
1170 *AttribPack=TT_IMMEDIATE;
1171 switch (*AttribPack)
1172 {
1173 case TT_NORMAL:
1174 strcat (buffer,"NORMAL (OUT)");
1175 strcpy (ext,"OUT");
1176 strcpy (extattach,"FLO");
1177 break;
1178 case TT_HOLD:
1179 strcat (buffer,"HOLD (HUT)");
1180 strcpy (ext,"HUT");
1181 strcpy (extattach,"HLO");
1182 break;
1183 case TT_CRASH:
1184 strcat (buffer,"CRASH (CUT)");
1185 strcpy (ext,"CUT");
1186 strcpy (extattach,"CLO");
1187 break;
1188 case TT_DIR:
1189 strcat (buffer,"DIRECT (DUT)");
1190 strcpy (ext,"DUT");
1191 strcpy (extattach,"DLO");
1192 break;
1193 case TT_IMMEDIATE:
1194 strcat (buffer,"IMMEDIATE (IUT)");
1195 strcpy (ext,"IUT");
1196 strcpy (extattach,"ILO");
1197 break;
1198 default:
1199 strcat (buffer,"*** corrupted attribute ***");
1200 break;
1201 } // switch (Attribpack);
1202 strcat (buffer,".\n");
1203 SL_Routeto->AddString (buffer);
1204 } // if (GotSystem);
1205 return (GotSystem);
1206 }
1207
CheckAndCreateSem(char * path)1208 int CheckAndCreateSem (char *path)
1209 {
1210 char *sav;
1211 FILE *f;
1212 #ifdef OS_2
1213 FILEFINDBUF3 ffblk;
1214 ULONG ulFileCount=1;
1215 HDIR hdir=HDIR_SYSTEM;
1216 #else
1217 struct ffblk ffblk;
1218 #endif
1219 int result;
1220 sav=(char *) malloc (strlen (path)+5);
1221 strcpy (sav,path);
1222 strcat (sav,"BSY");
1223 result = adaptcase(sav);
1224 if (!result) /* BSY file does not exist - create it! */
1225 {
1226 f = fopen(sav, "wt");
1227 if (f) fclose(f);
1228 }
1229 free (sav);
1230 return (result);
1231 }
1232
ReleaseSem(char * path)1233 void ReleaseSem (char *path)
1234 {
1235 char *sav;
1236 FILE *f;
1237
1238 int result;
1239 sav=(char *) malloc (strlen (path)+5);
1240 strcpy (sav,path);
1241 strcat (sav,"BSY");
1242 result = adaptcase(sav);
1243 if (result) /* BSY file does exist - delete it! */
1244 remove(sav);
1245 free (sav);
1246 }
1247
1248
CreatePathLines(C_StringList * source,C_StringList * target)1249 void CreatePathLines (C_StringList *source,C_StringList *target)
1250 {
1251 char work[80];
1252 int c;
1253 if (PathLogStyle==0)
1254 return;
1255 if (PathLogStyle==1)
1256 {
1257 strcpy (work,"Path: ");
1258 for (c=0;c<source->GetStringCount();c++)
1259 {
1260 strcat (work,source->GetString (c));
1261 if (c<source->GetStringCount()-1)
1262 strcat (work," -> ");
1263 if (strlen (work)>60)
1264 {
1265 strcat (work,"\n");
1266 target->AddString (work);
1267 strcpy (work,"Path: ");
1268 }
1269 }
1270 strcat (work,"\n");
1271 if (strlen (work)>7) /* 6=strlen ("Path: \n") */
1272 target->AddString (work);
1273 return;
1274 }
1275 }
1276
PostAnalysis(S_Visu * extra,struct S_Control * x)1277 int PostAnalysis (S_Visu *extra,struct S_Control *x)
1278 {
1279 int count;
1280 DateTime dt;
1281 if (RouteHandler.NoPack (extra->Destination,
1282 extra->Origin,S_FileAttached(extra->attrib),
1283 extra->Encrypted))
1284 return RET_SUCCESS;
1285 // If the message has any of the following flags, it is skipped
1286 // without further check.
1287 if (S_Sent(extra->attrib)==1 ||
1288 (
1289 (S_XMA(extra->attrib2)==1 ||
1290 S_Lock(extra->attrib2)==1 ||
1291 S_HiRes(extra->attrib2)==1 ||
1292 S_HiRes(extra->attrib2)==1 ||
1293 S_CoverLetter(extra->attrib2)==1 ||
1294 S_CoverLetter(extra->attrib2)==1 ||
1295 S_Signature(extra->attrib2)==1 ||
1296 S_LetterHead(extra->attrib2)==1 ||
1297 S_Fax(extra->attrib2)==1)
1298 &&!IgnoreUnknownAttribs)
1299 )
1300 {
1301 #ifdef DEBUG
1302 printf ("Skipped because of attributes (%u %u %d).\n",
1303 extra->attrib, extra->attrib2, IgnoreUnknownAttribs);
1304 #endif
1305 return RET_SUCCESS;
1306 }
1307 BufferHeader (extra,&x->SL_Header);
1308 x->SendType=GetSendType (extra,&x->SL_Routeto);
1309 if (x->SendType==ST_NOTOUCH)
1310 return RET_SUCCESS;
1311 x->GotSystem=DetermineRouteToSystem (extra,x->SendType,&x->SL_Routeto,
1312 &x->ShouldGo,&x->AttribPack,
1313 x->ext,x->extattach);
1314 // At this point: The message has to be processed, and
1315 // we have the header and route-to information. We log
1316 // them.
1317 Log.WriteOnLog ("------------------------------------------------------------------------------\n");
1318
1319 printf ("Message: %lu, format: ",extra->MsgNumber);
1320 switch (extra->formattype) {
1321 case formatMSG: printf ("MSG.\n");
1322 break;
1323 case formatSQUISH: printf ("SQUISH.\n");
1324 break;
1325 case formatJAM: printf ("JAM.\n");
1326 break;
1327 default: printf ("unknown.\n");
1328 }
1329
1330 for (count=0;count<x->SL_Header.GetStringCount();count++)
1331 Log.WriteOnLog ("%s",x->SL_Header.GetString (count));
1332 CreatePathLines (&x->SL_Path,&x->SL_ToWrite);
1333 for (count=0;count<x->SL_ToWrite.GetStringCount();count++)
1334 Log.WriteOnLog ("%s",x->SL_ToWrite.GetString (count));
1335 for (count=0;count<x->SL_Routeto.GetStringCount();count++)
1336 Log.WriteOnLog ("%s",x->SL_Routeto.GetString (count));
1337 if (extra->DetectedLoop==1)
1338 Log.WriteOnLog ("Warning: %s already processed here - possible loop.\n",x->define);
1339 if (extra->DetectedLoop==1 || RecordViaLines)
1340 {
1341 for (count=0;count<x->SL_Via.GetStringCount();count++)
1342 Log.WriteOnLog ("%s\n",x->SL_Via.GetString (count));
1343 }
1344 if (extra->DetectedLoop && NoLoopRoute)
1345 {
1346 Log.WriteOnLog("Mail is looping - we do not route it.\n");
1347 Log.WriteOnLog("\n");
1348 printf ("Mail loop detected.\n");
1349 return (RET_SUCCESS);
1350 }
1351 if (!x->GotSystem)
1352 {
1353 #ifdef DEBUG
1354 printf ("No path.\n");
1355 #endif
1356 Log.WriteOnLog ("\n");
1357 return (RET_SUCCESS);
1358 }
1359 #ifdef DEBUG
1360 printf ("Found a path.\n");
1361 #endif
1362 if (DoQQQPack(x->ShouldGo, x->AttribPack))
1363 {
1364 x->is_qqq = 1;
1365 strcpy(x->ext, "QQQ");
1366 FindUniqueQQQ (x->savepath);
1367 }
1368 else
1369 FindPKTPath (x->ShouldGo,x->savepath);
1370
1371 FindPKTPath (x->ShouldGo, x->savepathattach);
1372
1373 Log.WriteOnLog ("File: %s%s\n",x->savepath,x->ext);
1374 dt.getCurrentTime();
1375 Log.WriteOnLog ("Packed mail at %s %02d,%04d (%s) %02u:%02u:%02u\n",
1376 Months[dt.month-1],dt.day,dt.year,
1377 Days[GetDOW()],dt.hours,dt.minutes,dt.seconds);
1378 Log.WriteOnLog ("------------------------------------------------------------------------------\n");
1379 AddressHandler.AKAMatch (x->ShouldGo,&x->OurAKA);
1380 printf ("%lu bytes from %hu:%hu/%hu.%hu to %hu:%hu/%hu.%hu "
1381 "via %hu:%hu/%hu.%hu%s.\n", extra->MessageSize,
1382 extra->Origin.Zone,extra->Origin.Net,
1383 extra->Origin.Node,extra->Origin.Point,
1384 extra->Destination.Zone,extra->Destination.Net,
1385 extra->Destination.Node,extra->Destination.Point,
1386 x->ShouldGo.Zone,x->ShouldGo.Net,
1387 x->ShouldGo.Node,x->ShouldGo.Point,
1388 Packet2Handler.DoesMatch (x->ShouldGo,
1389 x->ShouldGo,0,0)?" (Packet 2)":"");
1390 return SUCCESS;
1391 }
1392
touchFile(char * path)1393 void touchFile(char *path)
1394 {
1395 FILE *touch;
1396 unsigned char buffer[8];
1397 int nok = 1;
1398
1399 #if defined(UNIX) && (defined(__FreeBSD__) || defined(__NetBSD__))
1400 nok=utimes(path, NULL);
1401 #endif
1402 #if defined(UNIX) || defined(__BORLANDC__)
1403 nok=utime(path, NULL);
1404 #endif
1405
1406 if (nok)
1407 {
1408 // try conventional method
1409 touch=fopen (path,"r+b");
1410 if (!touch)
1411 touch=fopen (path, "wb");
1412 if (touch)
1413 {
1414 fseek (touch,0,SEEK_SET);
1415 if (fread (buffer,1,8,touch)==8)
1416 {
1417 fseek (touch,0,SEEK_SET);
1418 fwrite (buffer,1,8,touch);
1419 }
1420 fclose (touch);
1421 }
1422 }
1423 }
1424
AnalyzeNet(char * path)1425 int AnalyzeNet (char *path)
1426 {
1427 S_Visu extra;
1428 struct S_Control x;
1429 char buffer[256];
1430 x.GotSystem=0; x.is_qqq = 0;
1431 adaptcase(path);
1432 strcpy (x.define,path);
1433 if (GetVisibleInfo (path,&extra,&x.SL_Via,&x.SL_Path)!=SUCCESS)
1434 return FATAL;
1435 if (PostAnalysis (&extra,&x)==RET_SUCCESS)
1436 return SUCCESS;
1437 if (IgnoreBSY==0 && CheckAndCreateSem (x.savepath))
1438 {
1439 printf ("(System is now busy - message not exported)\n");
1440 Log.WriteOnLog ("This message was not exported because"
1441 " the waypoint was busy.\n\n");
1442 // Touch file so it is not skipped in the next run
1443 // because of lastrun.cfr
1444
1445 touchFile(path);
1446 return (ENH_DELAYED);
1447 }
1448
1449 if (MSGToPKT (path,x.savepath,x.ext,x.ShouldGo,x.OurAKA,
1450 extra.Destination,
1451 Packet2Handler.DoesMatch(x.ShouldGo,x.ShouldGo,0,0), x.is_qqq)
1452 ==ECONV_OPENFAILOUT)
1453 {
1454 Log.WriteOnLog ("Warning: Failed to open/create PKT "
1455 "(%s).\n\n",x.savepath);
1456 if (IgnoreBSY == 0)
1457 ReleaseSem (x.savepath);
1458 return (SUCCESS);
1459 }
1460
1461 // Process file-attaches and file-requests
1462 if (S_FileAttached(extra.attrib))
1463 {
1464 if (SubjectToFile(extra.Subject,x.savepathattach,x.extattach,
1465 S_Truncate(extra.attrib2),
1466 S_KillFileSent(extra.attrib2) ||
1467 KillInTransitFiles)!=SUCCESS)
1468 Log.WriteOnLog ("Warning: Failed to update "
1469 "fileattach queue.\n");
1470 }
1471 if (S_FileRequest(extra.attrib))
1472 {
1473 strcpy (x.extattach,"REQ");
1474 if (SubjectToFile (extra.Subject,x.savepathattach,
1475 x.extattach,0,0)!=SUCCESS)
1476 Log.WriteOnLog ("Warning: Failed to update"
1477 " filerequest queue.\n");
1478 }
1479 if (S_KillSent(extra.attrib) ||
1480 (S_InTransit(extra.attrib) && KillInTransit))
1481 {
1482 if (remove (path))
1483 Log.WriteOnLog ("Warning: Unable to delete %s.\n",
1484 x.define);
1485 }
1486 else
1487 {
1488 if (FlagAsSent (path)!=SUCCESS)
1489 Log.WriteOnLog ("Warning: Can't flag %s "
1490 "as sent.\n",x.define);
1491 }
1492 Log.WriteOnLog ("\n");
1493 if (IgnoreBSY==0)
1494 ReleaseSem (x.savepath);
1495 return (ENH_PROCESSED);
1496 }
1497