"Fossies" - the Fresh Open Source Software Archive 
Member "portsentry-2.0b1/portsentry_io.c" (8 Apr 2002, 21510 Bytes) of package /linux/privat/old/portsentry-2.0b1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "portsentry_io.c" see the
Fossies "Dox" file reference documentation.
1 /************************************************************************/
2 /* */
3 /* Psionic PortSentry */
4 /* */
5 /* Created: 10-12-1997 */
6 /* Modified: 03-06-2002 */
7 /* */
8 /* Send all changes/modifications/bugfixes to sentrysupport@psionic.com */
9 /* */
10 /* */
11 /* This software is Copyright(c) 1997-2002 Psionic Technologies, Inc. */
12 /* */
13 /* Disclaimer: */
14 /* */
15 /* All software distributed by Psionic Technologies is distributed */
16 /* AS IS and carries NO WARRANTY or GUARANTEE OF ANY KIND. End users of */
17 /* the software acknowledge that they will not hold Psionic Technologies*/
18 /* liable for failure or non-function of the software product. YOU ARE */
19 /* USING THIS PRODUCT AT YOUR OWN RISK. */
20 /* */
21 /* Licensing restrictions apply. Commercial re-sell is prohibited under */
22 /* certain conditions. See the license that came with this package or */
23 /* visit http://www.psionic.com for more information. */
24 /* */
25 /* $Id: portsentry_io.c,v 1.45 2002/04/08 16:48:35 crowland Exp crowland $ */
26 /************************************************************************/
27
28 #include "portsentry.h"
29 #include "portsentry_io.h"
30 #include "portsentry_util.h"
31
32 /* Main logging function to surrogate syslog */
33 void
34 Log (char *logentry, ...)
35 {
36 char logbuffer[MAXBUF];
37
38 va_list argsPtr;
39 va_start (argsPtr, logentry);
40
41 vsnprintf (logbuffer, MAXBUF, logentry, argsPtr);
42
43 va_end(argsPtr);
44
45 openlog ("portsentry", LOG_PID, SYSLOG_FACILITY);
46 syslog (SYSLOG_LEVEL, "%s", logbuffer);
47 closelog ();
48 }
49
50
51 void
52 ExitNow (int status)
53 {
54 extern pcap_t *gblHandlePtr;
55
56 Log ("securityalert: Psionic PortSentry is shutting down\n");
57 Log ("adminalert: Psionic PortSentry is shutting down\n");
58 PrintStats();
59
60 if(gblHandlePtr)
61 pcap_close(gblHandlePtr);
62
63 exit (status);
64 }
65
66
67 void
68 Start (void)
69 {
70 Log ("adminalert: Psionic PortSentry %s is starting.\n", VERSION);
71 Log ("adminalert: Copyright 1997-2002 Psionic Technologies, Inc. http://www.psionic.com\n");
72 Log ("adminalert: Licensing restrictions apply. COMMERCIAL RESALE PROHIBITED WITHOUT LICENSING.\n");
73
74 #ifdef DEBUG
75 Log ("adminalert: Compiled: " __DATE__ " at " __TIME__ "\n");
76 #endif
77 }
78
79
80 void PrintStats(void)
81 {
82 Log ("adminalert: stats: Frame counter: %d\n",gblStats.gblFrameCount);
83 Log ("adminalert: stats: IP counter: %d\n",gblStats.gblIPPackCount);
84 Log ("adminalert: stats: TCP counter: %d\n",gblStats.gblTcpPackCount);
85 Log ("adminalert: stats: UDP counter: %d\n",gblStats.gblUdpPackCount);
86 Log ("adminalert: stats: ICMP counter: %d\n",gblStats.gblIcmpPackCount);
87 }
88
89 /* XXX Not working yet */
90 void SignalCatcher(int signal)
91 {
92 if(signal == SIGHUP)
93 {
94 PrintStats();
95 }
96 }
97
98 /* The daemonizing code copied from Advanced Programming */
99 /* in the UNIX Environment by W. Richard Stevens with minor changes */
100 int
101 DaemonSeed (void)
102 {
103 int childpid;
104
105 /* XXX Signal handling is broken for some reason with pcap */
106 /* Debug */
107 signal (SIGALRM, SIG_IGN);
108 signal (SIGHUP, SIG_IGN);
109 signal (SIGPIPE, SIG_IGN);
110 signal (SIGTERM, SIG_IGN);
111 signal (SIGABRT, SIG_IGN);
112 signal (SIGURG, SIG_IGN);
113 signal (SIGKILL, SIG_IGN);
114
115 if ((childpid = fork ()) < 0)
116 return (ERROR);
117 else if (childpid > 0)
118 exit(0);
119
120 setsid ();
121 chdir ("/");
122 umask (077);
123
124 /* close stdout, stdin, stderr */
125 close(0);
126 close(1);
127 close(2);
128
129 return (TRUE);
130 }
131
132
133 /* Compares an IP address against a listed address and its netmask*/
134 int
135 CompareIPs(char *target, char *ignoreAddr, int ignoreNetmaskBits)
136 {
137 unsigned long int netmaskAddr, ipAddr, targetAddr;
138
139 ipAddr = inet_addr(ignoreAddr);
140 targetAddr = inet_addr(target);
141 netmaskAddr = htonl (0xFFFFFFFF << (32 - ignoreNetmaskBits));
142
143
144 #ifdef DEBUG
145 Log ("debug: target %s\n", target);
146 Log ("debug: ignoreAddr %s\n", ignoreAddr);
147 Log ("debug: ignoreNetmaskBits %d\n", ignoreNetmaskBits);
148 Log ("debug: ipAddr %lu\n", ipAddr);
149 Log ("debug: targetAddr %lu\n", targetAddr);
150 Log ("debug: netmask %x\n", netmaskAddr);
151 Log ("debug: mix ipAddr %lu\n", (ipAddr & netmaskAddr));
152 Log ("debug: mix target %lu\n", (targetAddr & netmaskAddr));
153 #endif
154
155 /* Network portion mask & op and return */
156 if ((ipAddr & netmaskAddr) == (targetAddr & netmaskAddr))
157 return(TRUE);
158 else
159 return(FALSE);
160 }
161
162
163
164 /* check hosts that should never be blocked */
165 int
166 NeverBlock (char *target, char *filename)
167 {
168 FILE *input;
169 char buffer[MAXBUF], tempBuffer[MAXBUF], netmaskBuffer[MAXBUF];
170 char *slashPos;
171 int count = 0, dest = 0, netmaskBits = 0;
172
173 #ifdef DEBUG
174 Log ("debug: NeverBlock: Opening ignore file: %s \n", filename);
175 #endif
176 if ((input = fopen (filename, "r")) == NULL)
177 return (ERROR);
178
179 #ifdef DEBUG
180 Log ("debug: NeverBlock: Doing lookup for host: %s \n", target);
181 #endif
182
183 while (fgets (buffer, MAXBUF, input) != NULL)
184 {
185 /* Reset destination counter */
186 dest = 0;
187
188 if ((buffer[0] == '#') || (buffer[0] == '\n'))
189 continue;
190
191 for(count = 0; count < strlen(buffer); count++)
192 {
193 /* Parse out digits, colons, and slashes. Everything else rejected */
194 if((isdigit(buffer[count])) ||
195 (buffer[count] == '.') || (buffer[count] == ':') || (buffer[count] == '/'))
196 {
197 tempBuffer[dest++] = buffer[count];
198 }
199 else
200 {
201 tempBuffer[dest] = '\0';
202 break;
203 }
204 }
205
206 /* Return pointer to slash if it exists and copy data to buffer */
207 slashPos = strchr(tempBuffer, '/');
208 if (slashPos)
209 {
210 SafeStrncpy(netmaskBuffer, slashPos + 1, MAXBUF);
211 /* Terminate tempBuffer string at delimeter for later use */
212 *slashPos = '\0';
213 }
214 else
215 /* Copy in a 32 bit netmask if none given */
216 SafeStrncpy(netmaskBuffer, "32", MAXBUF);
217
218
219 /* Convert netmaskBuffer to bits in netmask */
220 netmaskBits = atoi(netmaskBuffer);
221 if ((netmaskBits < 0) || (netmaskBits > 32))
222 {
223 Log ("adminalert: Invalid netmask in config file: %s Ignoring entry.\n", buffer);
224 continue;
225 }
226
227 if (CompareIPs(target, tempBuffer, netmaskBits))
228 {
229 #ifdef DEBUG
230 Log ("debug: NeverBlock: Host: %s found in ignore file with netmask %s\n", target, netmaskBuffer);
231 #endif
232
233 fclose (input);
234 return (TRUE);
235 }
236
237 } /* end while() */
238
239 #ifdef DEBUG
240 Log ("debug: NeverBlock: Host: %s NOT found in ignore file\n", target);
241 #endif
242
243 fclose (input);
244 return (FALSE);
245 }
246
247
248 /* Make sure the config file is available */
249 int
250 CheckConfig (void)
251 {
252 FILE *input;
253
254 if ((input = fopen (CONFIG_FILE, "r")) == NULL)
255 {
256 Log ("adminalert: Cannot open config file: %s. Exiting\n", CONFIG_FILE);
257 return(FALSE);
258 }
259 else
260 fclose (input);
261
262 return(TRUE);
263 }
264
265
266 /* This writes out blocked hosts to the blocked file. It adds the hostname */
267 /* time stamp, and port connection that was acted on */
268 int
269 WriteBlocked (char *target, char *resolvedHost, char *protoType, char *scanType, int dstPort, int srcPort,
270 char *blockedFilename, char *historyFilename)
271 {
272 FILE *output;
273 int blockedStatus = TRUE, historyStatus = TRUE;
274
275 struct tm *tmptr;
276
277 time_t current_time;
278 current_time = time (0);
279 tmptr = localtime (¤t_time);
280
281
282 #ifdef DEBUG
283 Log ("debug: WriteBlocked: Opening block file: %s \n", blockedFilename);
284 #endif
285
286
287 if ((output = fopen (blockedFilename, "a")) == NULL)
288 {
289 Log ("adminalert: ERROR: Cannot open blocked file: %s.\n", blockedFilename);
290 blockedStatus = FALSE;
291 }
292 else
293 {
294 fprintf (output, "%ld - %02d/%02d/%04d %02d:%02d:%02d Host: %s/%s Protocol: %s ScanType: %s DstPort: %d SrcPort %d\n",
295 current_time, tmptr->tm_mon + 1, tmptr->tm_mday, tmptr->tm_year + 1900,
296 tmptr->tm_hour, tmptr->tm_min, tmptr->tm_sec, resolvedHost, target, protoType, scanType, dstPort, srcPort);
297 fclose (output);
298 blockedStatus = TRUE;
299 }
300
301 #ifdef DEBUG
302 Log ("debug: WriteBlocked: Opening history file: %s \n", historyFilename);
303 #endif
304 if ((output = fopen (historyFilename, "a")) == NULL)
305 {
306 Log ("adminalert: ERROR: Cannot open history file: %s.\n", historyFilename);
307 historyStatus = FALSE;
308 }
309 else
310 {
311 fprintf (output, "%ld - %02d/%02d/%04d %02d:%02d:%02d Host: %s/%s Protocol: %s ScanType: %s DstPort: %d SrcPort %d\n",
312 current_time, tmptr->tm_mon + 1, tmptr->tm_mday, tmptr->tm_year + 1900,
313 tmptr->tm_hour, tmptr->tm_min, tmptr->tm_sec, resolvedHost, target, protoType, scanType, dstPort, srcPort);
314 fclose (output);
315 historyStatus = TRUE;
316 }
317
318 return(historyStatus && blockedStatus);
319 }
320
321
322 /* This reads a token from the config file up to the "=" and returns the string */
323 /* up to the first space or NULL. configToken MUST be MAXBUF size */
324 int
325 ConfigTokenRetrieve (char *token, char *configToken)
326 {
327 FILE *config;
328 char buffer[MAXBUF], tokenBuffer[MAXBUF];
329 int count = 0;
330
331 if ((config = fopen (CONFIG_FILE, "r")) == NULL)
332 {
333 Log ("adminalert: ERROR: Cannot open config file: %s.\n", CONFIG_FILE);
334 return (ERROR);
335 }
336 else
337 {
338 #ifdef DEBUG2
339 Log ("debug: ConfigTokenRetrieve: checking for token %s", token);
340 #endif
341 /* Empty configToken */
342 memset(configToken, '\0', MAXBUF);
343
344 while ((fgets (buffer, MAXBUF, config)) != NULL)
345 {
346 /* this skips comments */
347 if (buffer[0] != '#')
348 {
349 #ifdef DEBUG2
350 Log ("debug: ConfigTokenRetrieve: data: %s", buffer);
351 #endif
352 /* search for the token and make sure the trailing character */
353 /* is a " " or "=" to make sure the entire token was found */
354 if ((strstr (buffer, token) != (char) NULL) &&
355 ((buffer[strlen(token)] == '=') || (buffer[strlen(token)] == ' ')))
356 { /* cut off the '=' and send it back */
357 if (strstr (buffer, "\"") == (char) NULL)
358 {
359 Log ("adminalert: Quotes missing from %s token. Option skipped\n", token);
360 fclose (config);
361 return (FALSE);
362 }
363
364 SafeStrncpy (tokenBuffer, strstr (buffer, "\"") + 1, MAXBUF);
365
366 /* strip off unprintables/linefeeds (if any) */
367 count = 0;
368 while (count < MAXBUF - 1)
369 {
370 if ((isprint (tokenBuffer[count])) && tokenBuffer[count] != '"')
371 configToken[count] = tokenBuffer[count];
372 else
373 {
374 configToken[count] = '\0';
375 break;
376 }
377 count++;
378 }
379
380 #ifdef DEBUG2
381 Log ("debug: ConfigTokenRetrieved token: %s\n", configToken);
382 #endif
383 configToken[MAXBUF - 1] = '\0';
384 fclose (config);
385 return (TRUE);
386 }
387 }
388 }
389 fclose (config);
390 return (FALSE);
391 }
392
393 }
394
395
396 /* This will bind a socket to a port. It works for UDP/TCP */
397 int
398 BindSocket (int sockfd, int port)
399 {
400 struct sockaddr_in server;
401
402 #ifdef DEBUG
403 Log ("debug: BindSocket: Binding to port: %d\n", port);
404 #endif
405
406 bzero ((char *) &server, sizeof (server));
407 server.sin_family = AF_INET;
408 server.sin_addr.s_addr = htonl (INADDR_ANY);
409 server.sin_port = htons (port);
410
411 if (bind (sockfd, (struct sockaddr *) &server, sizeof (server)) < 0)
412 {
413 #ifdef DEBUG
414 Log ("debug: BindSocket: Binding failed\n");
415 #endif
416 return (ERROR);
417 }
418 else
419 {
420 #ifdef DEBUG
421 Log ("debug: BindSocket: Binding successful. Doing listen\n");
422 #endif
423 listen (sockfd, 5);
424 return (TRUE);
425 }
426 }
427
428 /* Open a TCP Socket */
429 int
430 OpenTCPSocket (void)
431 {
432 int sockfd;
433
434 #ifdef DEBUG
435 Log ("debug: OpenTCPSocket: opening TCP socket\n");
436 #endif
437
438 if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
439 return (ERROR);
440 else
441 return (sockfd);
442 }
443
444
445 /* Open a UDP Socket */
446 int
447 OpenUDPSocket (void)
448 {
449 int sockfd;
450
451 #ifdef DEBUG
452 Log ("debug: openUDPSocket opening UDP socket\n");
453 #endif
454
455 if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
456 return (ERROR);
457 else
458 return (sockfd);
459 }
460
461 /* This will use a system() call to change the route of the target host to */
462 /* a dead IP address on your LOCAL SUBNET. */
463 int
464 KillRoute (char *target, int port, char *killString, char *detectionType)
465 {
466 char cleanAddr[MAXBUF], commandStringTemp[MAXBUF];
467 char commandStringTemp2[MAXBUF],commandStringFinal[MAXBUF];
468 char portString[MAXBUF];
469 int killStatus = ERROR, substStatus = ERROR;
470
471 CleanIpAddr (cleanAddr, target);
472 snprintf(portString, MAXBUF, "%d", port);
473
474 substStatus = SubstString (cleanAddr, "$TARGET$", killString, commandStringTemp);
475 if (substStatus == 0)
476 {
477 Log ("adminalert: No target variable specified in KILL_ROUTE option. Skipping.\n");
478 return (ERROR);
479 }
480 else if (substStatus == ERROR)
481 {
482 Log ("adminalert: Error trying to parse $TARGET$ Token for KILL_ROUTE. Skipping.\n");
483 return (ERROR);
484 }
485
486 if(SubstString (portString, "$PORT$", commandStringTemp, commandStringTemp2) == ERROR)
487 {
488 Log ("adminalert: Error trying to parse $PORT$ Token for KILL_ROUTE. Skipping.\n");
489 return (ERROR);
490 }
491
492 if(SubstString (detectionType, "$MODE$", commandStringTemp2, commandStringFinal) == ERROR)
493 {
494 Log ("adminalert: Error trying to parse $MODE$ Token for KILL_ROUTE. Skipping.\n");
495 return (ERROR);
496 }
497
498
499 #ifdef DEBUG
500 Log ("debug: KillRoute: running route command: %s\n", commandStringFinal);
501 #endif
502
503 /* Kill the bastard and report a status */
504 killStatus = system (commandStringFinal);
505
506 if (killStatus == 127)
507 {
508 Log ("adminalert: ERROR: There was an error trying to block host (exec fail) %s", target);
509 return (ERROR);
510 }
511 else if (killStatus < 0)
512 {
513 Log ("adminalert: ERROR: There was an error trying to block host (system fail) %s", target);
514 return (ERROR);
515 }
516 else
517 {
518 Log ("attackalert: Host %s has been blocked via dropped route using command: \"%s\"", target,
519 commandStringFinal);
520 return (TRUE);
521 }
522 }
523
524
525
526 /* This will run a specified command with TARGET as the option if one is given. */
527 int
528 KillRunCmd (char *target, int port, char *killString, char *detectionType)
529 {
530 char cleanAddr[MAXBUF], commandStringTemp[MAXBUF];
531 char commandStringTemp2[MAXBUF], commandStringFinal[MAXBUF];
532 char portString[MAXBUF];
533 int killStatus = ERROR;
534
535 CleanIpAddr (cleanAddr, target);
536 snprintf(portString, MAXBUF, "%d", port);
537
538 /* Tokens are not required, but we check for an error anyway */
539 if(SubstString (cleanAddr, "$TARGET$", killString, commandStringTemp) == ERROR)
540 {
541 Log ("adminalert: Error trying to parse $TARGET$ Token for KILL_RUN_CMD. Skipping.\n");
542 return (ERROR);
543 }
544
545 if(SubstString (portString, "$PORT$", commandStringTemp, commandStringTemp2) == ERROR)
546 {
547 Log ("adminalert: Error trying to parse $PORT$ Token for KILL_RUN_CMD. Skipping.\n");
548 return (ERROR);
549 }
550
551 if(SubstString (detectionType, "$MODE$", commandStringTemp2, commandStringFinal) == ERROR)
552 {
553 Log ("adminalert: Error trying to parse $MODE$ Token for KILL_RUN_CMD. Skipping.\n");
554 return (ERROR);
555 }
556
557
558 /* Kill the bastard and report a status */
559 killStatus = system (commandStringFinal);
560
561 if (killStatus == 127)
562 {
563 Log ("adminalert: ERROR: There was an error trying to run command (exec fail) %s", target);
564 return (ERROR);
565 }
566 else if (killStatus < 0)
567 {
568 Log ("adminalert: ERROR: There was an error trying to run command (system fail) %s", target);
569 return (ERROR);
570 }
571 else
572 {
573 /* report success */
574 Log ("attackalert: External command run for host: %s using command: \"%s\"", target,
575 commandStringFinal);
576 return (TRUE);
577 }
578 }
579
580
581 /* this function will drop the host into the TCP wrappers hosts.deny file to deny */
582 /* all access. The drop route metod is preferred as this stops UDP attacks as well */
583 /* as TCP. You may find though that host.deny will be a more permanent home.. */
584 int
585 KillHostsDeny (char *target, int port, char *killString, char *detectionType)
586 {
587
588 FILE *output;
589 char cleanAddr[MAXBUF], commandStringTemp[MAXBUF];
590 char commandStringTemp2[MAXBUF], commandStringFinal[MAXBUF];
591 char portString[MAXBUF];
592 int substStatus = ERROR;
593
594 CleanIpAddr (cleanAddr, target);
595
596 snprintf(portString, MAXBUF, "%d", port);
597
598 #ifdef DEBUG
599 Log ("debug: KillHostsDeny: parsing string for block: %s\n", killString);
600 #endif
601
602 substStatus = SubstString (cleanAddr, "$TARGET$", killString, commandStringTemp);
603 if (substStatus == 0)
604 {
605 Log ("adminalert: No target variable specified in KILL_HOSTS_DENY option. Skipping.\n");
606 return (ERROR);
607 }
608 else if (substStatus == ERROR)
609 {
610 Log ("adminalert: Error trying to parse $TARGET$ Token for KILL_HOSTS_DENY. Skipping.\n");
611 return (ERROR);
612 }
613
614 if(SubstString (portString, "$PORT$", commandStringTemp, commandStringTemp2) == ERROR)
615 {
616 Log ("adminalert: Error trying to parse $PORT$ Token for KILL_HOSTS_DENY. Skipping.\n");
617 return (ERROR);
618 }
619
620 if(SubstString (detectionType, "$MODE$", commandStringTemp2, commandStringFinal) == ERROR)
621 {
622 Log ("adminalert: Error trying to parse $MODE$ Token for KILL_HOSTS_DENY. Skipping.\n");
623 return (ERROR);
624 }
625
626 #ifdef DEBUG
627 Log ("debug: KillHostsDeny: result string for block: %s\n", commandStringFinal);
628 #endif
629
630 if ((output = fopen (WRAPPER_HOSTS_DENY, "a")) == NULL)
631 {
632 Log ("adminalert: cannot open hosts.deny file: %s for blocking.", WRAPPER_HOSTS_DENY);
633 Log ("securityalert: ERROR: There was an error trying to block host %s", target);
634 return (FALSE);
635 }
636 else
637 {
638 fprintf (output, "%s\n", commandStringFinal);
639 fclose (output);
640 Log ("attackalert: Host %s has been blocked via wrappers with string: \"%s\"", target, commandStringFinal);
641 return (TRUE);
642 }
643 }
644
645
646 /* check if the host is already blocked */
647 int
648 IsBlocked (char *target, char *filename)
649 {
650 FILE *input;
651 char buffer[MAXBUF], tempBuffer[MAXBUF];
652 char *ipOffset;
653 int count;
654
655
656 #ifdef DEBUG
657 Log ("debug: IsBlocked: Opening block file: %s \n", filename);
658 #endif
659 if ((input = fopen (filename, "r")) == NULL)
660 {
661 Log ("adminalert: ERROR: Cannot open blocked file: %s for reading.\n", filename);
662 return (FALSE);
663 }
664
665 while (fgets (buffer, MAXBUF, input) != NULL)
666 {
667 if((ipOffset = strstr(buffer, target)) != (char) NULL)
668 {
669 for(count = 0; count < strlen(ipOffset); count++)
670 {
671 if((isdigit(ipOffset[count])) ||
672 (ipOffset[count] == '.'))
673 {
674 tempBuffer[count] = ipOffset[count];
675 }
676 else
677 {
678 tempBuffer[count] = '\0';
679 break;
680 }
681 }
682 if(strcmp(target, tempBuffer) == 0)
683 {
684 #ifdef DEBUG
685 Log ("debug: isBlocked: Host: %s found in blocked file\n", target);
686 #endif
687 fclose (input);
688 return (TRUE);
689 }
690 }
691
692 }
693 #ifdef DEBUG
694 Log ("debug: IsBlocked: Host: %s NOT found in blocked file\n", target);
695 #endif
696 fclose(input);
697 return (FALSE);
698 }
699
700
701
702 /*********************************************************************************
703 * String substitute function
704 *
705 * This function takes:
706 *
707 * 1) A token to use for replacement.
708 * 2) A token to find.
709 * 3) A string with the tokens in it.
710 * 4) A string to write the replaced result.
711 *
712 * It returns the number of substitutions made during the operation.
713 **********************************************************************************/
714 int SubstString (const char *replace, const char *find, const char *target, char *result)
715 {
716 int replaceCount = 0, count = 0, findCount = 0, findLen=0, numberOfSubst=0;
717 char tempString[MAXBUF], *tempStringPtr;
718
719 #ifdef DEBUG2
720 Log ("debug: SubstString: Processing string: %s %d", target, strlen(target));
721 Log ("debug: SubstString: Processing search text: %s %d", replace, strlen(replace));
722 Log ("debug: SubstString: Processing replace text: %s %d", find, strlen(find));
723 #endif
724
725 /* string not found in target */
726 if (strstr (target, find) == (char) NULL)
727 {
728 SafeStrncpy(result, target, MAXBUF);
729 #ifdef DEBUG2
730 Log ("debug: SubstString: Result string: %s", result);
731 #endif
732 return (numberOfSubst);
733 }
734
735 memset(tempString, '\0', MAXBUF);
736 memset(result, '\0', MAXBUF);
737 findLen = strlen(find);
738 tempStringPtr = tempString;
739
740 for(count = 0; count < MAXBUF; count++)
741 {
742 if(*target == '\0')
743 break;
744 else if((strncmp(target, find, findLen)) != 0)
745 *tempStringPtr++ = *target++;
746 else
747 {
748 numberOfSubst++;
749 for(replaceCount = 0; replaceCount < strlen(replace); replaceCount++)
750 *tempStringPtr++ = replace[replaceCount];
751 for(findCount = 0; findCount < findLen; findCount++)
752 target++;
753 }
754 }
755
756 SafeStrncpy(result, tempString, MAXBUF);
757 #ifdef DEBUG2
758 Log ("debug: SubstString: Result string: %s", result);
759 #endif
760 return(numberOfSubst);
761 }
762
763
764
765 /* This function checks a config variable for a numerical flag and returns it */
766 int
767 CheckFlag (char *flagName)
768 {
769 char configToken[MAXBUF];
770
771 if ((ConfigTokenRetrieve (flagName, configToken)) == TRUE)
772 {
773 #ifdef DEBUG
774 Log ("debug: CheckFlag: found %s string.\n", flagName);
775 #endif
776 return (atoi(configToken));
777 }
778 else
779 {
780 #ifdef DEBUG
781 Log ("debug: CheckFlag: %s option not found. Assuming FALSE.\n", flagName);
782 #endif
783 return (FALSE);
784 }
785 }
786