1 // Provide some basic string handling
2 #include <ctype.h>
3 #if !defined(OS_2) && !defined(UNIX)
4 #include <dos.h>
5 #else
6 // #include <direct.h>
7 #endif
8
9 #ifdef UNIX
10 #include <sys/stat.h>
11 #if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(_AIX) && !defined(__GLIBC__) && !defined(mkdir)
12 #define mkdir __mkdir
13 #endif
14 #else
15 #include <io.h>
16 #endif
17
18 #ifdef EMX
19 #define S_IRWXU 0
20 #define S_IRWXG 0
21 #endif
22
23 #include "structs.hpp"
24
25 #ifndef OS_2
26 typedef unsigned long ULONG;
27 typedef short SHORT;
28 typedef unsigned short USHORT;
29
30
31 #ifdef UNIX
32 #include <time.h>
getCurrentTime(void)33 void DateTime::getCurrentTime (void)
34 {
35 time_t t;
36 struct tm *ltm;
37
38 time(&t);
39 ltm = localtime(&t);
40
41 hours = ltm->tm_hour;
42 minutes = ltm->tm_min;
43 seconds = ltm->tm_sec;
44 day = ltm->tm_mday;
45 month = ltm->tm_mon + 1;
46 year = ltm->tm_year + 1900;
47 }
48 #else
getCurrentTime(void)49 void DateTime::getCurrentTime (void)
50 {
51 struct date d;
52 struct time t;
53
54 getdate (&d);
55 gettime (&t);
56 hours=t.ti_hour;
57 minutes=t.ti_min;
58 seconds=t.ti_sec;
59 day=d.da_day;
60 month=d.da_mon;
61 year=d.da_year;
62 }
63 #endif
64 #else
65 // OS/2 routine
getCurrentTime(void)66 void DateTime::getCurrentTime(void)
67 {
68 DATETIME dt;
69 DosGetDateTime(&dt);
70 hours=dt.hours;
71 minutes=dt.minutes;
72 seconds=dt.seconds;
73 day=dt.day;
74 month=dt.month;
75 year=dt.year;
76 }
77 #endif
78
cistrcmp(char * c1,char * c2)79 int cistrcmp (char *c1,char *c2)
80 {
81 char *s1,*s2;
82 s1=c1; s2=c2;
83 while (*s1 || *s2)
84 {
85 if (toupper (*s1)==toupper (*s2))
86 {
87 s1++;
88 s2++;
89 }
90 else
91 return (toupper (*s1)-toupper (*s2));
92 }
93 return 0;
94 }
95
96 // Copy first token from string to token and strip it
GetAndStripToken(char * string,char * token)97 int GetAndStripToken (char *string, char *token)
98 {
99 char *search;
100 if (*string==0)
101 return SH_ZERO;
102 if (string[0]=='"')
103 {
104 strcpy (string,string+1); // Strip "
105 search=strchr (string,'"');
106 }
107 else
108 search=strchr (string,' ');
109 if (search!=NULL)
110 *search=0;
111 strcpy (token,string);
112 if (search!=NULL)
113 {
114 strcpy (string,search+1);
115 while (*string==' ')
116 strcpy (string,string+1);
117 }
118 else
119 *string=0;
120 return SUCCESS;
121 }
122
123 #if 0
124 int IsCommand (int TokenType)
125 {
126 switch (TokenType)
127 {
128 case TT_MAIN:
129 case TT_AKA:
130 case TT_NETMAILDIR:
131 case TT_NETSQUISH:
132 case TT_NETJAM:
133 case TT_OUTBOUND:
134 case TT_QQQOUTBOUND:
135 case TT_LOGFILENAME:
136 case TT_TOPDOWN:
137 case TT_UNKNOWN:
138 case TT_ROUTETO:
139 case TT_DIRECT:
140 case TT_ROUTEMAIL:
141 case TT_ROUTEFILES:
142 case TT_DIRECTMAIL:
143 case TT_DIRECTFILES:
144 case TT_NOROUTE:
145 case TT_NOROUTEMAIL:
146 case TT_NOROUTEFILES:
147 case TT_PACKET2:
148 case TT_PASSWORD:
149 case TT_INCLUDE:
150 case TT_INBOUND:
151 return 1;
152 default:
153 return 0;
154 }
155 }
156
157 #endif
158
159 struct S_Codes
160 CodeTable[]={ {"OUTBOUND",TT_OUTBOUND,NULL,ProcParOutboundDir,1,PT_COMMAND},
161 {"QQQOUTBOUND", TT_QQQOUTBOUND, NULL, ProcParQQQOutboundDir, 1, PT_COMMAND},
162 {"NETMAIL",TT_NETMAILDIR,NULL,ProcParNetmail,1,PT_COMMAND},
163 #ifdef SQUISHCFS
164 {"NETSQUISH",TT_NETSQUISH,NULL,ProcParNetSquish,1,PT_COMMAND},
165 {"NETJAM",TT_NETJAM,NULL,ProcParNetJam,1,PT_COMMAND},
166 #endif
167 {"LOG",TT_LOGFILENAME,NULL,ProcParLogFilename,1,PT_COMMAND},
168 {"RECODE",TT_RECODEFILENAME,NULL,ProcParRecode,1,PT_COMMAND},
169 {"PASSWORD",TT_PASSWORD,InitComPassword,ProcParPassword,1,PT_COMMAND},
170 {"INBOUND",TT_INBOUND,NULL,ProcParInbound,1,PT_COMMAND},
171 {"LOGPATH",TT_LOGPATH,InitComLogpath,NULL,0,PT_COMMAND},
172 {"INCLUDE",TT_INCLUDE,NULL,ProcParInclude,1,PT_COMMAND},
173 {"DEFINE",TT_DEFINE,NULL,ProcParDefine,1,PT_COMMAND},
174 {"ENDDEFINE",TT_ENDDEFINE,InitComEndDefine,NULL,0,PT_COMMAND},
175 {"CHECKFILE",TT_CHECKFILE,NULL,ProcParCheckFile,1,PT_COMMAND},
176 {"TOPDOWN",TT_TOPDOWN,InitComTopdown,NULL,0,PT_COMMAND},
177 {"FECONFIG",TT_FECONFIG,InitComFEConfig,ProcParFEConfig,0,PT_COMMAND},
178 {"ROUTETO",TT_ROUTETO,InitComRouteTo,ProcParRoute,0,PT_COMMAND},
179 {"ROUTE",TT_ROUTETO,InitComRouteTo,ProcParRoute,0,PT_COMMAND},
180 {"SEND",TT_ROUTETO,InitComRouteTo,ProcParRoute,0,PT_COMMAND},
181 {"ROUTEMAIL",TT_ROUTEMAIL,InitComRouteMail,ProcParRoute,0,PT_COMMAND},
182 {"PRODUCTINFO",TT_PRODUCTINFO,InitComProductInfo,ProcParProductInfo,1,PT_COMMAND},
183 {"ROUTEFILES",TT_ROUTEFILES,InitComRouteFiles,ProcParRoute,0,PT_COMMAND},
184 {"DIRECT",TT_DIRECT,InitComDirect,ProcParRoute,0,PT_COMMAND},
185 {"DIRECTTO",TT_DIRECT,InitComDirect,ProcParRoute,0,PT_COMMAND},
186 {"DIRECTMAIL",TT_DIRECTMAIL,InitComDirectMail,ProcParRoute,0,PT_COMMAND},
187 {"DIRECTFILES",TT_DIRECTFILES,InitComDirectFiles,ProcParRoute,0,PT_COMMAND},
188 {"NOROUTE",TT_NOROUTE,InitComNoroute,ProcParRoute,0,PT_COMMAND},
189 {"NOROUTETO",TT_NOROUTE,InitComNoroute,ProcParRoute,0,PT_COMMAND},
190 {"ROUTEBOSS",TT_NOROUTE,InitComNoroute,ProcParRoute,0,PT_COMMAND},
191 {"NOROUTEMAIL",TT_NOROUTEMAIL,InitComNorouteMail,ProcParRoute,0,PT_COMMAND},
192 {"ROUTEBOSSMAIL",TT_NOROUTEMAIL,InitComNorouteMail,ProcParRoute,0,PT_COMMAND},
193 {"NOROUTEFILES",TT_NOROUTEFILES,InitComNorouteFiles,ProcParRoute,0,PT_COMMAND},
194 {"ROUTEBOSSFILES",TT_NOROUTEFILES,InitComNorouteFiles,ProcParRoute,0,PT_COMMAND},
195 {"NOPACK",TT_NOPACK,InitComNoPack,ProcParRoute,0,PT_COMMAND},
196 {"NOPACKTO",TT_NOPACK,InitComNoPack,ProcParRoute,0,PT_COMMAND},
197 {"NOPACKMAIL",TT_NOPACKMAIL,InitComNoPackMail,ProcParRoute,0,PT_COMMAND},
198 {"IGNOREUNKNOWNATTRIBS",TT_IGNOREUNKNOWNATTRIBS,InitComIgnoreUnknownAttribs,NULL,0,PT_COMMAND},
199 {"NOPACKFILES",TT_NOPACKFILES,InitComNoPackFiles,ProcParRoute,0,PT_COMMAND},
200 {"VIABOSSHOLD",TT_VIABOSSHOLD,InitComViaBossHold,NULL,0,PT_COMMAND},
201 {"VIABOSSDIRECT",TT_VIABOSSDIRECT,InitComViaBossDirect,NULL,0,PT_COMMAND},
202 {"IGNOREBSY",TT_IGNOREBSY,InitComIgnoreBSY,NULL,0,PT_COMMAND},
203 {"NODOMAINDIR",TT_NODOMAINDIR,InitComNoDomainDir,NULL,0,PT_COMMAND},
204 {"KILLINTRANSIT",TT_KILLINTRANSIT,InitComKillInTransit,NULL,0,PT_COMMAND},
205 {"KILLTRANSITFILES",TT_KILLTRANSITFILES,InitComKillInTransitFiles,NULL,0,PT_COMMAND},
206 {"FASTECHOPACK",TT_FASTECHOPACK,InitComFastechoPack,ProcParFastechoPack,0,PT_COMMAND},
207 {"NOLOOPROUTE",TT_NOLOOPROUTE,InitComNoLoopRoute,NULL,0,PT_COMMAND},
208 {"ALL",TT_QQQALL,NULL,NULL,0,PT_QQQMODE},
209 {"ENC",TT_ENCRYPTED,NULL,NULL,0,PT_ENC},
210 {"NONENC",TT_NONENCRYPTED,NULL,NULL,0,PT_ENC},
211 {"CRASH",TT_CRASH,NULL,NULL,0,PT_FLAVOUR},
212 {"IMMEDIATE",TT_IMMEDIATE,NULL,NULL,0,PT_FLAVOUR},
213 {"HOLD",TT_HOLD,NULL,NULL,0,PT_FLAVOUR},
214 {"DIR",TT_DIR,NULL,NULL,0,PT_FLAVOUR},
215 {"NORMAL",TT_NORMAL,NULL,NULL,0,PT_FLAVOUR},
216 {"MYZONES",TT_MYZONES,NULL,NULL,0,PT_MACRO},
217 {"MYNETS",TT_MYNETS,NULL,NULL,0,PT_MACRO},
218 {"MYPOINTS",TT_MYPOINTS,NULL,NULL,0,PT_MACRO},
219 {"LOCAL",TT_LOCAL,NULL,NULL,0,PT_MACRO},
220 {"PACKET2",TT_PACKET2,InitComPacket2,ProcParPacket2,0,PT_COMMAND},
221 {"MAIN",TT_MAIN,NULL,ProcParMain,0,PT_COMMAND},
222 {"AKA",TT_AKA,NULL,ProcParAKA,0,PT_COMMAND},
223 {"FROM",TT_FROM,NULL,NULL,0,PT_FROM},
224 {"EXCEPT",TT_EXCEPT,NULL,NULL,0,PT_EXCEPT},
225 {"ASSUMEPOINTS",TT_ASSUMEPOINTS,InitComAssumePoints,NULL,0,PT_COMMAND},
226 {"ASSUMEWAYPOINTS",TT_ASSUMEWAYPOINTS,InitComAssumeWaypoints,NULL,0,PT_COMMAND},
227 {"EOLENDSCOMMAND",TT_EOLENDSCOMMAND,InitComEOLEndsCommand,NULL,0,PT_COMMAND},
228 {"PVT",TT_PVT,NULL,NULL,0,PT_ATTRIB},
229 {"HLD",TT_HLD,NULL,NULL,0,PT_ATTRIB},
230 {"CRA",TT_CRA,NULL,NULL,0,PT_ATTRIB},
231 {"K/S",TT_KS,NULL,NULL,0,PT_ATTRIB},
232 {"SNT",TT_SNT,NULL,NULL,0,PT_ATTRIB},
233 {"RCV",TT_RCV,NULL,NULL,0,PT_ATTRIB},
234 {"A/S",TT_AS,NULL,NULL,0,PT_ATTRIB},
235 {"ZON",TT_ZON,NULL,NULL,0,PT_ATTRIB},
236 {"HUB",TT_HUB,NULL,NULL,0,PT_ATTRIB},
237 {"FIL",TT_FIL,NULL,NULL,0,PT_ATTRIB},
238 {"FRQ",TT_FRQ,NULL,NULL,0,PT_ATTRIB},
239 {"IMM",TT_IMM,NULL,NULL,0,PT_ATTRIB},
240 {"XMA",TT_XMA,NULL,NULL,0,PT_ATTRIB},
241 {"KFS",TT_KFS,NULL,NULL,0,PT_ATTRIB},
242 {"TFS",TT_TFS,NULL,NULL,0,PT_ATTRIB},
243 {"LOK",TT_LOK,NULL,NULL,0,PT_ATTRIB},
244 {"RRQ",TT_RRQ,NULL,NULL,0,PT_ATTRIB},
245 {"CFM",TT_CFM,NULL,NULL,0,PT_ATTRIB},
246 {"HIR",TT_HIR,NULL,NULL,0,PT_ATTRIB},
247 {"COV",TT_COV,NULL,NULL,0,PT_ATTRIB},
248 {"SIG",TT_SIG,NULL,NULL,0,PT_ATTRIB},
249 {"LET",TT_LET,NULL,NULL,0,PT_ATTRIB},
250 {"FAX",TT_FAX,NULL,NULL,0,PT_ATTRIB},
251 {"FPU",TT_FPU,NULL,NULL,0,PT_ATTRIB},
252 {"",0,NULL,NULL,0,PT_END}
253 };
254
255 // Get Token Info
GetTokenInfo(char * Token,struct S_Codes * storage)256 int GetTokenInfo (char *Token, struct S_Codes *storage)
257 {
258 char *Mess,*Update;
259 int count,canbedow;
260 if (Token[0]==0)
261 return SH_ZERO;
262 count=0;
263 Mess=(char *) malloc (strlen (Token)+1);
264 strcpy (Mess,Token);
265 Update=Mess;
266 while (*Update)
267 {
268 *Update=toupper (*Update);
269 Update++;
270 }
271 Update=Mess;
272 while (*Update)
273 {
274 if (*Update=='-'|| *Update=='_')
275 strcpy (Update,Update+1);
276 else
277 Update++;
278 }
279
280 while (CodeTable[count].Keyword[0]!=0)
281 {
282 if (!cistrcmp (Mess,CodeTable[count].Keyword))
283 {
284 memcpy (storage,&CodeTable[count],sizeof (struct S_Codes));
285 free (Mess);
286 return (CodeTable[count].Group);
287 }
288 count++;
289 }
290 // Not a known keyword
291 // Check for a day of the week spec.
292 canbedow=1;
293 Update=Mess;
294 while (*Update && canbedow)
295 {
296 if (*Update!='M' && *Update!='T' && *Update!='W' &&
297 *Update!='H' && *Update!='F' && *Update!='S' &&
298 *Update!='U')
299 {
300 canbedow=0;
301 break;
302 }
303 Update++;
304 }
305 if (canbedow)
306 {
307 free (Mess);
308 storage->Keyword=Token;
309 storage->Code=TT_DOW;
310 storage->Group=PT_DOW;
311 return False;
312 }
313 if (isdigit (Mess[0]) || Mess[0]=='.' || Mess[0]=='!' || Mess[0]=='*' ||
314 Mess[0]=='?' || Mess[0]=='#')
315 {
316 free (Mess);
317 storage->Keyword=Token;
318 storage->Code=TT_ADDRESS;
319 storage->Group=PT_ADDRESS;
320 return (PT_ADDRESS);
321 }
322 // Check if it is a definition
323 storage->Code=TT_UNKNOWN;
324 storage->Group=PT_OTHER;
325 return TT_UNKNOWN;
326 }
327
328
329 // Attempt to determine token type
GetTokenType(char * Token)330 int GetTokenType (char *Token)
331 {
332 char *Mess,*Update;
333 int count,canbedow;
334 if (Token[0]==0)
335 return SH_ZERO;
336 // Tokens starting with a digit are most probably network addresses
337 Mess=(char *) malloc (strlen (Token)+1);
338 strcpy (Mess,Token);
339 Update=Mess;
340 while (*Update)
341 {
342 *Update=toupper (*Update);
343 Update++;
344 }
345 Update=Mess;
346 while (*Update)
347 {
348 if (*Update=='-'|| *Update=='_')
349 strcpy (Update,Update+1);
350 else
351 Update++;
352 }
353 canbedow=1;
354 Update=Mess;
355 while (*Update && canbedow)
356 {
357 if (*Update!='M' && *Update!='T' && *Update!='W' &&
358 *Update!='H' && *Update!='F' && *Update!='S' &&
359 *Update!='U')
360 {
361 canbedow=0;
362 break;
363 }
364 Update++;
365 }
366 if (canbedow)
367 {
368 free (Mess);
369 return TT_DOW;
370 }
371 if (isdigit (Mess[0]) || Mess[0]=='.' || Mess[0]=='!' || Mess[0]=='*' ||
372 Mess[0]=='?' || Mess[0]=='#')
373 {
374 free (Mess);
375 return (TT_ADDRESS);
376 }
377 count=0;
378 while (CodeTable[count].Keyword[0]!=0)
379 {
380 if (!cistrcmp (Mess,CodeTable[count].Keyword))
381 {
382 free (Mess);
383 return (CodeTable[count].Code);
384 }
385 count++;
386 }
387 free (Mess);
388 return TT_UNKNOWN;
389 }
390
GetFullQualifiedAddress(char * Saddress,struct S_FQAddress * storage,struct S_FQAddress * Main)391 int GetFullQualifiedAddress (char *Saddress, struct S_FQAddress *storage,struct S_FQAddress *Main)
392 {
393 int NoMain;
394 size_t count,count2;
395 char Compo[25]; // Maximum: AAAAA:BBBBB:CCCCC:DDDDD\0
396 char *search,*first,*colon,*slash,*point;
397 char address[80];
398 if (strlen (Saddress)>79)
399 return EAD_INVALID;
400 strcpy (address,Saddress);
401 search=strchr (address,' ');
402 if (search)
403 *search=0;
404 if (Main==NULL || (Main->Zone==0xFFFF && Main->Net==0xFFFF &&
405 Main->Node==0xFFFF && Main->Point==0xFFFF))
406 NoMain=1;
407 else
408 NoMain=0;
409 if (*address=='\0')
410 return EAD_ZERO;
411 // First thing to do is parse the domain
412 search=strchr (address,'@');
413 if (search!=NULL)
414 {
415 strcpy (storage->Domain,search+1);
416 *search=0;
417 }
418 else
419 {
420 storage->Domain[0]=0;
421 search=address+strlen(address)-1; /* Last char */
422 while (search >= address &&
423 !isdigit (*search) && *search!=':' && *search!='/' &&
424 *search!='.')
425 *(search--)=0;
426 }
427 for (count=0;count<strlen (address);count++)
428 if (!isdigit (address[count]) && address[count]!=':' &&
429 address[count]!='/' && address[count]!='.')
430 return EAD_INVALID;
431 count2=0;
432 for (count=0;count<strlen (address);count++)
433 if (address[count]==':')
434 count2++;
435 if (count2>1)
436 return EAD_INVALID;
437 count2=0;
438 for (count=0;count<strlen (address);count++)
439 if (address[count]=='/')
440 count2++;
441 if (count2>1)
442 return EAD_INVALID;
443 count2=0;
444 for (count=0;count<strlen (address);count++)
445 if (address[count]=='.')
446 count2++;
447 if (count2>1)
448 return EAD_INVALID;
449 // count2=0;
450 // for (count=0;count<strlen (address);count++)
451
452 // Discard any address with wildcards
453 if (strchr (address,'*') || strchr (address,'?'))
454 return EAD_WILDCARDS;
455 // At the very least, there must be a : and a / to be a FQA.
456 if ((!strchr (address,':') || !strchr (address,'/')) && NoMain)
457 return EAD_CANTRESOLVE;
458 // Add what's missing, if anything, to get a 4D address
459 // Zone
460 first=address;
461 search=strchr (first,':');
462 if (!search)
463 if (NoMain)
464 return EAD_CANTRESOLVE;
465 else
466 sprintf (Compo,"%u",Main->Zone);
467 else
468 {
469 *search=0;
470 strcpy (Compo,first);
471 first=search+1;
472 }
473 strcat (Compo,":");
474 // So far compo has the zone number and the :.
475 // Test for net
476 search=strchr (first,'/');
477 if (!search)
478 if (NoMain)
479 return EAD_CANTRESOLVE;
480 else
481 sprintf (Compo+strlen(Compo),"%u",Main->Net);
482 else
483 {
484 *search=0;
485 strcat (Compo,first);
486 first=search+1;
487 }
488 strcat (Compo,"/");
489 // Compo: XXXX:YYYY/ ->
490 // Node & Point
491 search=strchr (first,'.');
492 if (first==search) // No hay nodo
493 sprintf ("%u",&Compo[strlen (Compo)],Main->Node);
494 strcat (Compo,first);
495 if (!search) // The rest is only the node
496 strcat (Compo,".0");
497 // FQA completed - now we have to split it to get the number
498 #ifdef DEBUG
499 printf ("FQA: %s (",Compo);
500 #endif
501 colon=strchr (Compo,':');
502 slash=strchr (Compo,'/');
503 point=strchr (Compo,'.');
504 if ((slash==colon+1) || (point==slash+1))
505 return EAD_INVALID;
506 *colon=*slash=*point=0;
507 storage->Zone=atoi (Compo);
508 storage->Net=atoi (colon+1);
509 storage->Node=atoi (slash+1);
510 storage->Point=atoi (point+1);
511 if (storage->Domain[0]==0 && NoMain==0)
512 strcpy (storage->Domain,Main->Domain);
513 #ifdef DEBUG
514 printf ("%u:%u/%u.%u)\n",storage->Zone,storage->Net,storage->Node,storage->Point);
515 #endif
516 return SUCCESS;
517 }
518
HasWildcards(char * address)519 int HasWildcards (char *address)
520 {
521 size_t count;
522 for (count=0;count<strlen (address);count++)
523 if ((address[count]=='#') ||
524 (address[count]=='?') ||
525 (address[count]=='*'))
526 return 1;
527 return 0;
528 }
529
SplitWildcardedAddress(char * origaddress,struct S_WAddress * storage,struct S_WAddress * Main)530 int SplitWildcardedAddress (char *origaddress, struct S_WAddress *storage,struct S_WAddress *Main)
531 {
532 int NoMain;
533 size_t count,count2;
534 char *colon,*slash,*point;
535 char address[81];
536 if (Main==NULL)
537 NoMain=1;
538 else
539 NoMain=0;
540 if (strlen (origaddress)>80)
541 return EAD_INVALID;
542 strcpy (address,origaddress);
543 if (*address=='\0')
544 return EAD_ZERO;
545 storage->Reverse=0;
546 colon=strchr (address,'@');
547 if (colon)
548 {
549 *colon=0;
550 strcpy (storage->Domain,colon+1);
551 }
552 else
553 storage->Domain[0]=0;
554 if (address[0]=='!')
555 {
556 storage->Reverse=1;
557 strcpy (address,address+1);
558 }
559 for (count=0;count<strlen (address);count++)
560 if (!isdigit (address[count]) && address[count]!=':' &&
561 address[count]!='/' && address[count]!='.' &&
562 address[count]!='*' && address[count]!='?' &&
563 address[count]!='#')
564 return EAD_INVALID;
565 count2=0;
566 for (count=0;count<strlen (address);count++)
567 if (address[count]==':')
568 count2++;
569 if (count2>1)
570 return EAD_INVALID;
571 count2=0;
572 for (count=0;count<strlen (address);count++)
573 if (address[count]=='/')
574 count2++;
575 if (count2>1)
576 return EAD_INVALID;
577 count2=0;
578 for (count=0;count<strlen (address);count++)
579 if (address[count]=='.')
580 count2++;
581 if (count2>1)
582 return EAD_INVALID;
583 storage->Zone[0]=storage->Net[0]=storage->Node[0]=storage->Point[0]=0;
584 colon=strchr (address,':');
585 slash=strchr (address,'/');
586 point=strchr (address,'.');
587 // There are eight possibilities, based on the separators found
588 switch ((colon!=NULL)*4+(slash!=NULL)*2+(point!=NULL))
589 {
590 case 0: // No separators -> anything there is the node specification
591 if (address[0]=='*')
592 {
593 strcpy (storage->Zone,"*");
594 strcpy (storage->Net,"*");
595 strcpy (storage->Node,"*");
596 strcpy (storage->Point,"*");
597 }
598 else
599 {
600 if (NoMain==1)
601 return EAD_CANTRESOLVE;
602 if (HasWildcards (Main->Zone) || HasWildcards (Main->Net))
603 return EAD_CANTRESOLVE;
604 strcpy ((char *) &storage->Node,address);
605 if (HasWildcards (storage->Node))
606 strcpy ((char *) &storage->Point,"*");
607 }
608 break;
609 case 1: // Only a point
610 *point=0;
611 if (NoMain==1)
612 return EAD_CANTRESOLVE;
613 if (HasWildcards (Main->Zone) || HasWildcards (Main->Net) ||
614 HasWildcards (Main->Node))
615 return EAD_CANTRESOLVE;
616 strcpy ((char *) &storage->Point,point+1);
617 strcpy ((char *) &storage->Node,address);
618 break;
619 case 2: // Only a slash
620 if (NoMain==1)
621 return EAD_CANTRESOLVE;
622 if (HasWildcards (Main->Zone))
623 return EAD_CANTRESOLVE;
624 *slash=0;
625 strcpy ((char *) &storage->Node,slash+1);
626 strcpy ((char *) &storage->Net,address);
627 if ((storage->Node[strlen (storage->Node)-1]=='*') ||
628 (storage->Node[strlen (storage->Node)-1]=='?') ||
629 (storage->Node[strlen (storage->Node)-1]=='#'))
630 strcpy ((char *) &storage->Point,"*");
631 break;
632 case 3: // Slash & point
633 if (slash>point)
634 return EAD_INVALID;
635 if (NoMain==1)
636 return EAD_CANTRESOLVE;
637 if (HasWildcards (Main->Zone))
638 return EAD_CANTRESOLVE;
639 *point=0;
640 *slash=0;
641 strcpy ((char *) &storage->Point,point+1);
642 strcpy ((char *) &storage->Node,slash+1);
643 strcpy ((char *) &storage->Net,address);
644 break;
645 case 4: // Only colon (ie 2: or 2:*)
646 *colon=0;
647 strcpy ((char *) &storage->Net,colon+1);
648 strcpy ((char *) &storage->Zone,address);
649 if ((storage->Net[strlen (storage->Net)-1]=='*') ||
650 (storage->Net[strlen (storage->Net)-1]=='?') ||
651 (storage->Net[strlen (storage->Net)-1]=='#'))
652 {
653 strcpy ((char *) &storage->Node,"*");
654 strcpy ((char *) &storage->Point,"*");
655 }
656 break;
657 case 5: // Colon & point (A:B.C -> nonsense)
658 return EAD_INVALID;
659 case 6: // Colon & slash (ie 2:40/32)
660 if (colon>slash)
661 return EAD_INVALID;
662 *colon=0;
663 *slash=0;
664 strcpy ((char *) &storage->Node,slash+1);
665 strcpy ((char *) &storage->Net,colon+1);
666 strcpy ((char *) &storage->Zone,address);
667 if ((storage->Node[strlen (storage->Node)-1]=='*') ||
668 (storage->Node[strlen (storage->Node)-1]=='?') ||
669 (storage->Node[strlen (storage->Node)-1]=='#'))
670 strcpy ((char *) &storage->Point,"*");
671 break;
672 case 7: // colon & slash & point
673 if (colon>slash || slash>point)
674 return EAD_INVALID;
675 *colon=0;
676 *slash=0;
677 *point=0;
678 strcpy ((char *) &storage->Point,point+1);
679 strcpy ((char *) &storage->Node,slash+1);
680 strcpy ((char *) &storage->Net,colon+1);
681 strcpy ((char *) &storage->Zone,address);
682 break;
683 }
684 if (storage->Node[0]=='*')
685 storage->Node[0]=0;
686 // Sixteen possibilities based on the filled fields
687 switch ((storage->Zone[0]!=0)*8+(storage->Net[0]!=0)*4+
688 (storage->Node[0]!=0)*2+(storage->Point[0]!=0))
689 {
690 case 0: // [ ]:[ ]/[ ].[ ]
691 strcpy ((char *) storage->Zone,"*");
692 strcpy ((char *) storage->Net,"*");
693 strcpy ((char *) storage->Node,"*");
694 strcpy ((char *) storage->Point,"*");
695 break;
696 case 1: // [ ]:[ ]/[ ].[X]
697 if (NoMain)
698 return EAD_CANTRESOLVE;
699 strcpy (storage->Zone,Main->Zone);
700 strcpy (storage->Net,Main->Net);
701 strcpy (storage->Node,Main->Node);
702 break;
703 case 2: // [ ]:[ ]/[X].[ ]
704 if (NoMain)
705 return EAD_CANTRESOLVE;
706 // Notice the following exception:
707 // * is not be parsed as *:*/*.* at not as z:n/*.* !!!!
708 strcpy (storage->Zone,Main->Zone);
709 strcpy (storage->Net,Main->Net);
710 strcpy ((char *) storage->Point,"0");
711 case 3: // [ ]:[ ]/[X].[X]
712 if (NoMain)
713 return EAD_CANTRESOLVE;
714 strcpy (storage->Zone,Main->Zone);
715 strcpy (storage->Net,Main->Net);
716 break;
717 case 4: // [ ]:[X]/[ ].[ ]
718 strcpy (storage->Zone,Main->Zone);
719 strcpy ((char *) storage->Node,"*");
720 strcpy ((char *) storage->Point,"*");
721 break;
722 case 5: // [ ]:[X]/[ ].[X] (node was a *, so 341/*.34).
723 strcpy (storage->Zone,Main->Zone);
724 strcpy ((char *) storage->Node,"*");
725 break;
726 case 6: // [ ]:[X]/[X].[ ]
727 strcpy (storage->Zone,Main->Zone);
728 strcpy ((char *) storage->Point,"0");
729 break;
730 case 7: // [ ]:[X]/[X].[X]
731 strcpy (storage->Zone,Main->Zone);
732 break;
733 case 8: // [X]:[ ]/[ ].[ ]
734 strcpy ((char *) storage->Net,"*");
735 strcpy ((char *) storage->Node,"*");
736 strcpy ((char *) storage->Point,"*");
737 break;
738 case 9: // [X]:[ ]/[ ].[X]
739 case 10: // [X]:[ ]/[X].[ ]
740 case 11: // [X]:[ ]/[X].[X]
741 return EAD_INVALID;
742 case 12: // [X]:[X]/[ ].[ ]
743 strcpy ((char *) storage->Node,"*");
744 strcpy ((char *) storage->Point,"*");
745 break;
746 case 13: // [X].[X]/[ ].[X] // (ie 2:341/*.0)
747 strcpy ((char *) storage->Node,"*");
748 break;
749 case 14: // [X].[X]/[X].[ ]
750 strcpy ((char *) storage->Point,"0");
751 break;
752 case 15: // [X].[X].[X].[X]
753 ;
754 }
755 #ifdef DEBUG
756 printf ("%s,%s,%s,%s)\n",storage->Zone,storage->Net,storage->Node,storage->Point);
757 #endif
758 return SUCCESS;
759 }
760
CompareBit(word Number,char * string)761 int CompareBit (word Number,char *string)
762 {
763 char SNum[6];
764 char *pos1,*pos2;
765 pos1=SNum; pos2=string;
766 sprintf (SNum,"%u",Number);
767 // Pos1 point to the number and cannot have wildcards
768 while (*pos1 && *pos2) // Until a end-of-string is reached
769 {
770 if (*pos2=='*') // No need to check more. It is a match
771 return 1;
772 if (*pos2=='?') // Everything is ok - check next character
773 {pos1++; pos2++;}
774 else
775 if (*pos2=='#')
776 {
777 if (*pos2) // There must be a character - no matter which
778 {pos1++; pos2++;}
779 else
780 return 0; // No match
781 }
782 else // If here, no wildcard in pos2
783 if (*pos1==*pos2)
784 {pos1++;pos2++;}
785 else
786 return 0; // No match
787 }
788 // If here, all the characters in the shortest string matches
789 // the first characters in the largest. What next...?
790 if (*pos1==*pos2 || (*pos1==0 && *pos2=='*'))
791 return 1; // Match
792 else
793 return 0;
794 }
795
796 // Determine whether an address matches a wildcard or not...
CompareAddress(struct S_FQAddress FQA,struct S_WAddress * WA)797 int CompareAddress (struct S_FQAddress FQA,struct S_WAddress *WA)
798 {
799 if (CompareBit (FQA.Zone,WA->Zone) && CompareBit (FQA.Net,WA->Net) &&
800 CompareBit (FQA.Node,WA->Node) && CompareBit (FQA.Point,WA->Point))
801 return 1;
802 else
803 return 0;
804 }
805
lengthoffile(FILE * f)806 long lengthoffile(FILE *f)
807 {
808 #ifndef UNIX
809 return (filelength (fileno(f)));
810 #else
811 long curofs = ftell(f);
812 long rv = 0x7FFFFFFFL;
813
814 fseek(f, 0, SEEK_END);
815 rv = ftell(f);
816 fseek(f, curofs, SEEK_SET);
817
818 return rv;
819 #endif
820 }
821
makedirandfopen(char * filename,const char * mode)822 FILE *makedirandfopen (char *filename,const char *mode)
823 {
824 FILE *fp;
825 char *workout,*pos;
826 char *mkdirwork;
827 adaptcase(filename);
828 fp=fopen (filename,mode);
829 if (fp!=NULL)
830 return fp; // End of problem :-)
831 if (strchr (filename,DIRSEPC)==NULL)
832 return NULL; // Nothing to do without a slash...
833 workout=(char *) malloc (strlen (filename)+1);
834 if (workout==NULL)
835 return NULL;
836 strcpy (workout,filename);
837 pos=workout+strlen (workout)-1;
838 while (*pos!=DIRSEPC)
839 pos--;
840 *pos=0;
841 // OK, now we have just the directory name
842 mkdirwork=(char *) malloc (strlen (workout)+1);
843 if (mkdirwork==NULL)
844 {
845 free (workout);
846 return NULL;
847 }
848 strcpy (mkdirwork,workout);
849 pos=mkdirwork;
850 /* pos=strchr (mkdirwork,':');
851 if (pos==NULL)
852 pos=mkdirwork;
853 else /
854 pos++; */
855 while (*pos)
856 {
857 while (*pos!=DIRSEPC && *pos)
858 pos++;
859 if (*pos)
860 {
861 *pos=0;
862 #if defined(EMX) || defined(UNIX)
863 mkdir (mkdirwork,S_IRWXU|S_IRWXG);
864 #else
865 mkdir (mkdirwork);
866 #endif
867 *pos=DIRSEPC;
868 pos++;
869 }
870 }
871 #if defined(EMX) || defined(UNIX)
872 mkdir (mkdirwork,S_IRWXU|S_IRWXG);
873 #else
874 mkdir (mkdirwork);
875 #endif
876 fp=fopen (filename,mode);
877 return fp;
878 }
879
GetMatchLevel(struct S_FQAddress A1,struct S_FQAddress A2)880 int GetMatchLevel (struct S_FQAddress A1,struct S_FQAddress A2)
881 {
882 int DomCounts;
883 if (A1.Domain[0] && A2.Domain[0])
884 DomCounts=1;
885 else
886 DomCounts=0;
887 if (DomCounts)
888 if (cistrcmp (A1.Domain,A2.Domain)) // Domain mismatch, goodbye!
889 return 0;
890 if (A1.Zone==A2.Zone && A1.Net==A2.Net && A1.Node==A2.Node &&
891 A1.Point==A2.Point)
892 return 4+DomCounts;
893 if (A1.Zone==A2.Zone && A1.Net==A2.Net && A1.Node==A2.Node)
894 return 3+DomCounts;
895 if (A1.Zone==A2.Zone && A1.Net==A2.Net)
896 return 2+DomCounts;
897 if (A1.Zone==A2.Zone)
898 return 1+DomCounts;
899 return DomCounts; //0 = no domain info, 1=domain matches
900 }
901
902 class C_WildAddress
903 {
904 int inited;
905 S_WAddress Last;
906 public:
907 int ParseAddress (char *Token,S_WAddress *storage);
908 C_WildAddress (void);
909 };
910
C_WildAddress(void)911 C_WildAddress::C_WildAddress (void)
912 {
913 inited=0;
914 }
915
ParseAddress(char * Token,S_WAddress * storage)916 int C_WildAddress::ParseAddress (char *Token,S_WAddress *storage)
917 {
918 int keep;
919 if (inited==0)
920 keep=SplitWildcardedAddress (Token,storage,NULL);
921 else
922 keep=SplitWildcardedAddress (Token,storage,&Last);
923 if (keep==SUCCESS)
924 inited=1;
925 else
926 inited=0;
927 memcpy (&Last,storage,sizeof (struct S_WAddress));
928 return (keep);
929 }
930