1 /*-
2 ***********************************************************************
3 *
4 * $Id: digmode.c,v 1.56 2014/07/18 06:40:44 mavrik Exp $
5 *
6 ***********************************************************************
7 *
8 * Copyright 2000-2014 The FTimes Project, All Rights Reserved.
9 *
10 ***********************************************************************
11 */
12 #include "all-includes.h"
13
14 /*-
15 ***********************************************************************
16 *
17 * DigModeInitialize
18 *
19 ***********************************************************************
20 */
21 int
DigModeInitialize(FTIMES_PROPERTIES * psProperties,char * pcError)22 DigModeInitialize(FTIMES_PROPERTIES *psProperties, char *pcError)
23 {
24 const char acRoutine[] = "DigModeInitialize()";
25 char acLocalError[MESSAGE_SIZE] = "";
26 char acMapItem[FTIMES_MAX_PATH];
27 char *pcMapItem = NULL;
28 int iError = 0;
29
30 /*-
31 *******************************************************************
32 *
33 * Initialize variables.
34 *
35 *********************************************************************
36 */
37 psProperties->pFileLog = stderr;
38 psProperties->pFileOut = stdout;
39 if (psProperties->iRunMode == FTIMES_DIGAUTO)
40 {
41 psProperties->bAnalyzeDeviceFiles = TRUE;
42 psProperties->bAnalyzeRemoteFiles = TRUE;
43 }
44 psProperties->psFieldMask = MaskParseMask("all", MASK_RUNMODE_TYPE_DIG, acLocalError); /* A mask is required by nph-ftimes.cgi. */
45 if (psProperties->psFieldMask == NULL)
46 {
47 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
48 return ER;
49 }
50 psProperties->bLogDigStrings = TRUE;
51
52 /*-
53 *******************************************************************
54 *
55 * Read the config file.
56 *
57 *******************************************************************
58 */
59 iError = PropertiesReadFile(psProperties->acConfigFile, psProperties, acLocalError);
60 if (iError != ER_OK)
61 {
62 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
63 return iError;
64 }
65
66 /*-
67 *********************************************************************
68 *
69 * Set the priority.
70 *
71 *********************************************************************
72 */
73 iError = SupportSetPriority(psProperties, acLocalError);
74 if (iError != ER_OK)
75 {
76 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
77 return iError;
78 }
79
80 /*-
81 *******************************************************************
82 *
83 * Add any command line items to the Include list.
84 *
85 *******************************************************************
86 */
87 while ((pcMapItem = OptionsGetNextOperand(psProperties->psOptionsContext)) != NULL)
88 {
89 iError = SupportExpandPath(pcMapItem, acMapItem, FTIMES_MAX_PATH, 0, acLocalError);
90 if (iError != ER_OK)
91 {
92 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
93 return iError;
94 }
95
96 iError = SupportAddToList(acMapItem, &psProperties->psIncludeList, "Include", acLocalError);
97 if (iError != ER_OK)
98 {
99 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
100 return iError;
101 }
102 }
103
104 /*-
105 *********************************************************************
106 *
107 * LogDir defaults to OutDir.
108 *
109 *********************************************************************
110 */
111 if (psProperties->acLogDirName[0] == 0)
112 {
113 snprintf(psProperties->acLogDirName, FTIMES_MAX_PATH, "%s", psProperties->acOutDirName);
114 }
115
116 return ER_OK;
117 }
118
119
120 /*-
121 ***********************************************************************
122 *
123 * DigModeCheckDependencies
124 *
125 ***********************************************************************
126 */
127 int
DigModeCheckDependencies(FTIMES_PROPERTIES * psProperties,char * pcError)128 DigModeCheckDependencies(FTIMES_PROPERTIES *psProperties, char *pcError)
129 {
130 const char acRoutine[] = "DigModeCheckDependencies()";
131 int iLargestDigString = DigGetMaxStringLength();
132 #ifdef USE_SSL
133 char acLocalError[MESSAGE_SIZE] = "";
134 #endif
135
136 /*-
137 *********************************************************************
138 *
139 * There must be at least one dig string defined.
140 *
141 *********************************************************************
142 */
143 if (DigGetStringCount() <= 0)
144 {
145 snprintf(pcError, MESSAGE_SIZE, "%s: Need at least one DigString.", acRoutine);
146 return ER_MissingControl;
147 }
148
149 /*-
150 *********************************************************************
151 *
152 * The carry size must be less than the block size.
153 *
154 *********************************************************************
155 */
156 if (psProperties->iAnalyzeCarrySize >= psProperties->iAnalyzeBlockSize)
157 {
158 snprintf(pcError, MESSAGE_SIZE, "%s: AnalyzeCarrySize (%d) must be less than AnalyzeBlockSize (%d).", acRoutine, psProperties->iAnalyzeCarrySize, psProperties->iAnalyzeBlockSize);
159 return ER;
160 }
161
162 /*-
163 *********************************************************************
164 *
165 * The largest normal/nocase dig string must not be larger than the
166 * carry size.
167 *
168 *********************************************************************
169 */
170 if (iLargestDigString > psProperties->iAnalyzeCarrySize)
171 {
172 snprintf(pcError, MESSAGE_SIZE, "%s: The largest DigStringNormal/DigStringNoCase value (%d) must not exceed AnalyzeCarrySize (%d).", acRoutine, iLargestDigString, psProperties->iAnalyzeCarrySize);
173 return ER;
174 }
175
176 #ifdef USE_XMAGIC
177 /*-
178 *********************************************************************
179 *
180 * If an XMagic dig string was specified, the minimum carry size is
181 * the size of an integer. This limitation is based on the way that
182 * XMagicGetValueOffset() works.
183 *
184 *********************************************************************
185 */
186 if (DigGetSearchList(DIG_STRING_TYPE_XMAGIC, 0) != NULL && psProperties->iAnalyzeCarrySize < sizeof(APP_UI32))
187 {
188 snprintf(pcError, MESSAGE_SIZE, "%s: AnalyzeCarrySize (%d) must be %d or larger when DigStringXMagic values are in use.", acRoutine, psProperties->iAnalyzeCarrySize, (int) sizeof(APP_UI32));
189 return ER;
190 }
191 #endif
192
193 /*-
194 *********************************************************************
195 *
196 * Check mode-specific properties.
197 *
198 *********************************************************************
199 */
200 if (psProperties->iRunMode == FTIMES_DIGMODE)
201 {
202 if (psProperties->acBaseName[0] == 0)
203 {
204 snprintf(pcError, MESSAGE_SIZE, "%s: Missing BaseName.", acRoutine);
205 return ER_MissingControl;
206 }
207
208 if (strcmp(psProperties->acBaseName, "-") == 0)
209 {
210 if (psProperties->bURLPutSnapshot)
211 {
212 snprintf(pcError, MESSAGE_SIZE, "%s: Uploads are not allowed when the BaseName is \"-\". Either disable URLPutSnapshot or change the BaseName.", acRoutine);
213 return ER;
214 }
215 }
216 else
217 {
218 if (psProperties->acOutDirName[0] == 0)
219 {
220 snprintf(pcError, MESSAGE_SIZE, "%s: Missing OutDir.", acRoutine);
221 return ER_MissingControl;
222 }
223 }
224
225 if (psProperties->bURLPutSnapshot && psProperties->psPutURL == NULL)
226 {
227 snprintf(pcError, MESSAGE_SIZE, "%s: Missing URLPutURL.", acRoutine);
228 return ER_MissingControl;
229 }
230
231 if (psProperties->bURLPutSnapshot && psProperties->psPutURL->pcPath[0] == 0)
232 {
233 snprintf(pcError, MESSAGE_SIZE, "%s: Missing path in URLPutURL.", acRoutine);
234 return ER_MissingControl;
235 }
236
237 #ifdef USE_SSL
238 if (SSLCheckDependencies(psProperties->psSslProperties, acLocalError) != ER_OK)
239 {
240 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
241 return ER_MissingControl;
242 }
243 #endif
244 }
245
246 return ER_OK;
247 }
248
249
250 /*-
251 ***********************************************************************
252 *
253 * DigModeFinalize
254 *
255 ***********************************************************************
256 */
257 int
DigModeFinalize(FTIMES_PROPERTIES * psProperties,char * pcError)258 DigModeFinalize(FTIMES_PROPERTIES *psProperties, char *pcError)
259 {
260 const char acRoutine[] = "DigModeFinalize()";
261 char acLocalError[MESSAGE_SIZE] = "";
262 int iError;
263
264 /*-
265 *********************************************************************
266 *
267 * Enforce privilege requirements, if requested.
268 *
269 *********************************************************************
270 */
271 if (psProperties->bRequirePrivilege)
272 {
273 iError = SupportRequirePrivilege(acLocalError);
274 if (iError != ER_OK)
275 {
276 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
277 return iError;
278 }
279 }
280
281 /*-
282 *********************************************************************
283 *
284 * Conditionally check the server uplink.
285 *
286 *********************************************************************
287 */
288 if (psProperties->bURLPutSnapshot && psProperties->iRunMode == FTIMES_DIGMODE)
289 {
290 iError = URLPingRequest(psProperties, acLocalError);
291 if (iError != ER_OK)
292 {
293 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
294 return ER_URLPingRequest;
295 }
296 }
297
298 /*-
299 *********************************************************************
300 *
301 * Set up the Dig engine.
302 *
303 *********************************************************************
304 */
305 AnalyzeEnableDigEngine(psProperties);
306
307 #ifdef USE_XMAGIC
308 /*-
309 *********************************************************************
310 *
311 * Forceably limit the step size if it's bigger than the block size.
312 *
313 *********************************************************************
314 */
315 if (psProperties->iAnalyzeStepSize > psProperties->iAnalyzeBlockSize)
316 {
317 snprintf(acLocalError, MESSAGE_SIZE, "AnalyzeStepSize (%d) is being reduced to match AnalyzeBlockSize (%d).", psProperties->iAnalyzeStepSize, psProperties->iAnalyzeBlockSize);
318 ErrorHandler(ER_Warning, acLocalError, ERROR_WARNING);
319 psProperties->iAnalyzeStepSize = psProperties->iAnalyzeBlockSize;
320 AnalyzeSetStepSize(psProperties->iAnalyzeStepSize);
321 }
322 #endif
323
324 /*-
325 *********************************************************************
326 *
327 * If the Include list is NULL, include everything.
328 *
329 *********************************************************************
330 */
331 if (psProperties->psIncludeList == NULL)
332 {
333 psProperties->psIncludeList = SupportIncludeEverything(acLocalError);
334 if (psProperties->psIncludeList == NULL)
335 {
336 snprintf(pcError, MESSAGE_SIZE, "%s: Failed to build a default Include list: %s", acRoutine, acLocalError);
337 return ER_BadHandle;
338 }
339 }
340
341 /*-
342 *********************************************************************
343 *
344 * Prune the Include list.
345 *
346 *********************************************************************
347 */
348 psProperties->psIncludeList = SupportPruneList(psProperties->psIncludeList, "Include");
349 if (psProperties->psIncludeList == NULL)
350 {
351 snprintf(pcError, MESSAGE_SIZE, "%s: There's nothing left to process in the Include list.", acRoutine);
352 return ER_NothingToDo;
353 }
354
355 /*-
356 *********************************************************************
357 *
358 * Conditionally check the Include and Exclude lists.
359 *
360 *********************************************************************
361 */
362 if (psProperties->bExcludesMustExist)
363 {
364 iError = SupportCheckList(psProperties->psExcludeList, "Exclude", acLocalError);
365 if (iError != ER_OK)
366 {
367 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
368 return iError;
369 }
370 }
371
372 if (psProperties->bIncludesMustExist)
373 {
374 iError = SupportCheckList(psProperties->psIncludeList, "Include", acLocalError);
375 if (iError != ER_OK)
376 {
377 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
378 return iError;
379 }
380 }
381
382 /*-
383 *********************************************************************
384 *
385 * Establish Log file stream, and update Message Handler.
386 *
387 *********************************************************************
388 */
389 if (psProperties->iRunMode == FTIMES_DIGMODE && strcmp(psProperties->acBaseName, "-") != 0)
390 {
391 iError = SupportMakeName(psProperties->acLogDirName, psProperties->acBaseName, psProperties->acBaseNameSuffix, ".log", psProperties->acLogFileName, acLocalError);
392 if (iError != ER_OK)
393 {
394 snprintf(pcError, MESSAGE_SIZE, "%s: Log File: %s", acRoutine, acLocalError);
395 return iError;
396 }
397
398 iError = SupportAddToList(psProperties->acLogFileName, &psProperties->psExcludeList, "Exclude", acLocalError);
399 if (iError != ER_OK)
400 {
401 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
402 return iError;
403 }
404
405 psProperties->pFileLog = fopen(psProperties->acLogFileName, "wb+");
406 if (psProperties->pFileLog == NULL)
407 {
408 snprintf(pcError, MESSAGE_SIZE, "%s: LogFile = [%s]: %s", acRoutine, psProperties->acLogFileName, strerror(errno));
409 return ER_fopen;
410 }
411 /* FIXME Remove this #ifdef at some point in the future. */
412 #ifdef WIN32
413 /*-
414 *****************************************************************
415 *
416 * NOTE: The buffer size was explicitly set to prevent binaries
417 * made with Visual Studio 2005 (no service packs) from crashing
418 * when run in lean mode. This problem may have been fixed in
419 * Service Pack 1.
420 *
421 *****************************************************************
422 */
423 setvbuf(psProperties->pFileLog, NULL, _IOLBF, 1024);
424 #else
425 setvbuf(psProperties->pFileLog, NULL, _IOLBF, 0);
426 #endif
427 }
428 else
429 {
430 strncpy(psProperties->acLogFileName, "stderr", FTIMES_MAX_PATH);
431 psProperties->pFileLog = stderr;
432 }
433
434 MessageSetNewLine(psProperties->acNewLine);
435 MessageSetOutputStream(psProperties->pFileLog);
436 MessageSetAutoFlush(MESSAGE_AUTO_FLUSH_ON);
437
438 /*-
439 *******************************************************************
440 *
441 * Establish Out file stream.
442 *
443 *******************************************************************
444 */
445 if (psProperties->iRunMode == FTIMES_DIGMODE && strcmp(psProperties->acBaseName, "-") != 0)
446 {
447 iError = SupportMakeName(psProperties->acOutDirName, psProperties->acBaseName, psProperties->acBaseNameSuffix, ".dig", psProperties->acOutFileName, acLocalError);
448 if (iError != ER_OK)
449 {
450 snprintf(pcError, MESSAGE_SIZE, "%s: Out File: %s", acRoutine, acLocalError);
451 return iError;
452 }
453
454 iError = SupportAddToList(psProperties->acOutFileName, &psProperties->psExcludeList, "Exclude", acLocalError);
455 if (iError != ER_OK)
456 {
457 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
458 return iError;
459 }
460
461 psProperties->pFileOut = fopen(psProperties->acOutFileName, "wb+");
462 if (psProperties->pFileOut == NULL)
463 {
464 snprintf(pcError, MESSAGE_SIZE, "%s: OutFile = [%s]: %s", acRoutine, psProperties->acOutFileName, strerror(errno));
465 return ER_fopen;
466 }
467 /* FIXME Remove this #ifdef at some point in the future. */
468 #ifdef WIN32
469 /*-
470 *****************************************************************
471 *
472 * NOTE: The buffer size was explicitly set to prevent binaries
473 * made with Visual Studio 2005 (no service packs) from crashing
474 * when run in lean mode. This problem may have been fixed in
475 * Service Pack 1.
476 *
477 *****************************************************************
478 */
479 setvbuf(psProperties->pFileOut, NULL, _IOLBF, 1024);
480 #else
481 setvbuf(psProperties->pFileOut, NULL, _IOLBF, 0);
482 #endif
483 }
484 else
485 {
486 strncpy(psProperties->acOutFileName, "stdout", FTIMES_MAX_PATH);
487 psProperties->pFileOut = stdout;
488 }
489
490 /*-
491 *********************************************************************
492 *
493 * Display properties.
494 *
495 *********************************************************************
496 */
497 PropertiesDisplaySettings(psProperties);
498
499 /*-
500 *********************************************************************
501 *
502 * Write out a header.
503 *
504 *********************************************************************
505 */
506 iError = DigWriteHeader(psProperties, acLocalError);
507 if (iError != ER_OK)
508 {
509 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
510 return iError;
511 }
512
513 return ER_OK;
514 }
515
516
517 /*-
518 ***********************************************************************
519 *
520 * DigModeWorkHorse
521 *
522 ***********************************************************************
523 */
524 int
DigModeWorkHorse(FTIMES_PROPERTIES * psProperties,char * pcError)525 DigModeWorkHorse(FTIMES_PROPERTIES *psProperties, char *pcError)
526 {
527 char acLocalError[MESSAGE_SIZE] = "";
528 FILE_LIST *psList = NULL;
529
530 /*-
531 *********************************************************************
532 *
533 * Process the Include list.
534 *
535 *********************************************************************
536 */
537 for (psList = psProperties->psIncludeList; psList != NULL; psList = psList->psNext)
538 {
539 if (SupportMatchExclude(psProperties->psExcludeList, psList->pcRegularPath) == NULL)
540 {
541 MapFile(psProperties, psList->pcRegularPath, acLocalError);
542 }
543 }
544
545 return ER_OK;
546 }
547
548
549 /*-
550 ***********************************************************************
551 *
552 * DigModeFinishUp
553 *
554 ***********************************************************************
555 */
556 int
DigModeFinishUp(FTIMES_PROPERTIES * psProperties,char * pcError)557 DigModeFinishUp(FTIMES_PROPERTIES *psProperties, char *pcError)
558 {
559 char acMessage[MESSAGE_SIZE];
560 int i;
561 int iFirst;
562 int iIndex;
563 unsigned char aucFileHash[MD5_HASH_SIZE];
564
565 /*-
566 *********************************************************************
567 *
568 * Close up the output stream, and complete the file digest.
569 *
570 *********************************************************************
571 */
572 if (psProperties->pFileOut && psProperties->pFileOut != stdout)
573 {
574 fflush(psProperties->pFileOut);
575 fclose(psProperties->pFileOut);
576 psProperties->pFileOut = NULL;
577 }
578
579 memset(aucFileHash, 0, MD5_HASH_SIZE);
580 MD5Omega(&psProperties->sOutFileHashContext, aucFileHash);
581 MD5HashToHex(aucFileHash, psProperties->acOutFileHash);
582
583 /*-
584 *********************************************************************
585 *
586 * Print output filenames.
587 *
588 *********************************************************************
589 */
590 snprintf(acMessage, MESSAGE_SIZE, "LogFileName=%s", psProperties->acLogFileName);
591 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
592
593 snprintf(acMessage, MESSAGE_SIZE, "OutFileName=%s", psProperties->acOutFileName);
594 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
595
596 snprintf(acMessage, MESSAGE_SIZE, "OutFileHash=%s", psProperties->acOutFileHash);
597 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
598
599 snprintf(acMessage, MESSAGE_SIZE, "DataType=%s", psProperties->acDataType);
600 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
601
602 /*-
603 *********************************************************************
604 *
605 * Write out the statistics.
606 *
607 *********************************************************************
608 */
609 snprintf(acMessage, MESSAGE_SIZE, "DirectoriesEncountered=%d", MapGetDirectoryCount());
610 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
611
612 snprintf(acMessage, MESSAGE_SIZE, "FilesEncountered=%d", MapGetFileCount());
613 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
614
615 #ifdef UNIX
616 snprintf(acMessage, MESSAGE_SIZE, "SpecialsEncountered=%d", MapGetSpecialCount());
617 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
618 #endif
619
620 #ifdef WINNT
621 snprintf(acMessage, MESSAGE_SIZE, "StreamsEncountered=%d", MapGetStreamCount());
622 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
623 #endif
624
625 iIndex = 0;
626 if (psProperties->iLastAnalysisStage > 0)
627 {
628 iIndex = sprintf(&acMessage[iIndex], "AnalysisStages=");
629 for (i = 0, iFirst = 0; i < psProperties->iLastAnalysisStage; i++)
630 {
631 iIndex += sprintf(&acMessage[iIndex], "%s%s", (iFirst++ > 0) ? "," : "", psProperties->asAnalysisStages[i].acDescription);
632 }
633 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
634
635 snprintf(acMessage, MESSAGE_SIZE, "ObjectsAnalyzed=%u", AnalyzeGetFileCount());
636 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
637
638 #ifdef UNIX
639 #ifdef USE_AP_SNPRINTF
640 snprintf(acMessage, MESSAGE_SIZE, "BytesAnalyzed=%qu", (unsigned long long) AnalyzeGetByteCount());
641 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
642 #else
643 snprintf(acMessage, MESSAGE_SIZE, "BytesAnalyzed=%llu", (unsigned long long) AnalyzeGetByteCount());
644 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
645 #endif
646 #endif
647
648 #ifdef WIN32
649 snprintf(acMessage, MESSAGE_SIZE, "BytesAnalyzed=%I64u", AnalyzeGetByteCount());
650 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
651 #endif
652 }
653 else
654 {
655 snprintf(acMessage, MESSAGE_SIZE, "AnalysisStages=None");
656 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
657 }
658
659 /*-
660 *********************************************************************
661 *
662 * List total number of strings.
663 *
664 *********************************************************************
665 */
666 snprintf(acMessage, MESSAGE_SIZE, "DigStrings=%d", DigGetStringCount());
667 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
668
669 /*-
670 *********************************************************************
671 *
672 * List total number of strings matched.
673 *
674 *********************************************************************
675 */
676 snprintf(acMessage, MESSAGE_SIZE, "DigStringsMatched=%d", DigGetStringsMatched());
677 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
678
679 /*-
680 *********************************************************************
681 *
682 * List the number of dig records.
683 *
684 *********************************************************************
685 */
686 #ifdef UNIX
687 #ifdef USE_AP_SNPRINTF
688 snprintf(acMessage, MESSAGE_SIZE, "DigRecords=%qu", (unsigned long long) DigGetTotalMatches());
689 #else
690 snprintf(acMessage, MESSAGE_SIZE, "DigRecords=%llu", (unsigned long long) DigGetTotalMatches());
691 #endif
692 #endif
693 #ifdef WIN32
694 snprintf(acMessage, MESSAGE_SIZE, "DigRecords=%I64u", DigGetTotalMatches());
695 #endif
696 MessageHandler(MESSAGE_QUEUE_IT, MESSAGE_INFORMATION, MESSAGE_PROPERTY_STRING, acMessage);
697
698 SupportDisplayRunStatistics(psProperties);
699
700 return ER_OK;
701 }
702
703
704 /*-
705 ***********************************************************************
706 *
707 * DigModeFinalStage
708 *
709 ***********************************************************************
710 */
711 int
DigModeFinalStage(FTIMES_PROPERTIES * psProperties,char * pcError)712 DigModeFinalStage(FTIMES_PROPERTIES *psProperties, char *pcError)
713 {
714 const char acRoutine[] = "DigModeFinalStage()";
715 char acLocalError[MESSAGE_SIZE] = "";
716 int iError;
717
718 /*-
719 *********************************************************************
720 *
721 * Conditionally upload the collected data.
722 *
723 *********************************************************************
724 */
725 if (psProperties->bURLPutSnapshot && psProperties->iRunMode == FTIMES_DIGMODE)
726 {
727 iError = URLPutRequest(psProperties, acLocalError);
728 if (iError != ER_OK)
729 {
730 snprintf(pcError, MESSAGE_SIZE, "%s: %s", acRoutine, acLocalError);
731 return ER_URLPutRequest;
732 }
733
734 if (psProperties->bURLUnlinkOutput)
735 {
736 FTimesEraseFiles(psProperties, pcError);
737 }
738 }
739
740 return ER_OK;
741 }
742