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