1 /*
2  * Argus Software
3  * Copyright (c) 2000-2016 QoSient, LLC
4  * All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  */
21 
22 /*
23  * rabins - time based bin processor.
24  *    this routine will take in an argus stream and align it to
25  *    to a time array, and hold it for a hold period, and then
26  *    output the bin countents as an argus stream.
27  *
28  *    this is the basis for all stream block processors.
29  *    used by ragraph() to structure the data into graphing
30  *    regions.
31  *
32  * written by Carter Bullard
33  * QoSient, LLC
34  *
35  */
36 
37 /*
38  * $Id: //depot/argus/clients/clients/rabins.c#91 $
39  * $DateTime: 2016/06/01 15:17:28 $
40  * $Change: 3148 $
41  */
42 
43 #ifdef HAVE_CONFIG_H
44 #include "argus_config.h"
45 #endif
46 
47 #if defined(CYGWIN)
48 #define USE_IPV6
49 #endif
50 
51 #include <unistd.h>
52 #include <stdlib.h>
53 
54 #include <math.h>
55 
56 #include <argus_compat.h>
57 
58 #include <argus_util.h>
59 #include <argus_client.h>
60 #include <argus_main.h>
61 #include <argus_filter.h>
62 #include <argus_output.h>
63 
64 #include <rabins.h>
65 #include <rasplit.h>
66 #include <argus_sort.h>
67 #include <argus_cluster.h>
68 
69 #include <signal.h>
70 #include <ctype.h>
71 
72 int RaRealTime = 0;
73 float RaUpdateRate = 1.0;
74 
75 struct timeval ArgusLastRealTime = {0, 0};
76 struct timeval ArgusLastTime     = {0, 0};
77 struct timeval ArgusThisTime     = {0, 0};
78 
79 
80 struct timeval dLastTime = {0, 0};
81 struct timeval dRealTime = {0, 0};
82 struct timeval dThisTime = {0, 0};
83 struct timeval dTime     = {0, 0};
84 
85 long long thisUsec = 0;
86 
87 struct RaBinProcessStruct *RaBinProcess = NULL;
88 
89 int ArgusRmonMode = 0;
90 
91 
92 void
ArgusClientInit(struct ArgusParserStruct * parser)93 ArgusClientInit (struct ArgusParserStruct *parser)
94 {
95    time_t tsec = ArgusParser->ArgusRealTime.tv_sec;
96    struct ArgusAdjustStruct *nadp;
97    struct ArgusModeStruct *mode = NULL;
98    int i = 0, ind = 0, size = 1;
99    char outputfile[MAXSTRLEN];
100    char *nocorrect = NULL;
101    char *correct = NULL;
102 
103    parser->RaWriteOut = 0;
104    *outputfile = '\0';
105 
106    if (!(parser->RaInitialized)) {
107       (void) signal (SIGHUP,  (void (*)(int)) RaParseComplete);
108       (void) signal (SIGTERM, (void (*)(int)) RaParseComplete);
109       (void) signal (SIGQUIT, (void (*)(int)) RaParseComplete);
110       (void) signal (SIGINT,  (void (*)(int)) RaParseComplete);
111 
112       if ((RaBinProcess = (struct RaBinProcessStruct *)ArgusCalloc(1, sizeof(*RaBinProcess))) == NULL)
113          ArgusLog (LOG_ERR, "ArgusClientInit: ArgusCalloc error %s", strerror(errno));
114 
115 #if defined(ARGUS_THREADS)
116       pthread_mutex_init(&RaBinProcess->lock, NULL);
117 #endif
118 
119       RaBinProcess->scalesecs = 0;
120 
121       nadp = &RaBinProcess->nadp;
122       bzero((char *)nadp, sizeof(*nadp));
123 
124       nadp->mode      = -1;
125       nadp->modify    =  1;
126       nadp->slen      =  2;
127 
128       if (parser->aflag)
129          nadp->slen = parser->aflag;
130 
131       if (parser->vflag)
132          ArgusReverseSortDir++;
133 
134       parser->RaCumulativeMerge = 1;
135 
136       if ((ArgusSorter = ArgusNewSorter(parser)) == NULL)
137          ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewSorter error %s", strerror(errno));
138 
139       if ((mode = parser->ArgusModeList) != NULL) {
140          while (mode) {
141             if (isdigit((int) *mode->mode)) {
142                ind = 0;
143             } else {
144                if (!(strncasecmp (mode->mode, "rtime", 5)) ||
145                   (!(strncasecmp (mode->mode, "realtime", 8)))) {
146                   char *ptr = NULL;
147                   RaRealTime++;
148                   if ((ptr = strchr(mode->mode, ':')) != NULL) {
149                      double value = 0.0;
150                      char *endptr = NULL;
151                      ptr++;
152                      value = strtod(ptr, &endptr);
153                      if (ptr != endptr) {
154                         RaUpdateRate = value;
155                      }
156                   }
157                } else
158                if (!(strncasecmp (mode->mode, "nomerge", 4)))
159                   parser->RaCumulativeMerge = 0;
160                else
161                if (!(strncasecmp (mode->mode, "rmon", 4)))
162                   parser->RaMonMode++;
163                else
164                if (!(strncasecmp (mode->mode, "nocorrect", 5)))
165                   nocorrect = strdup(mode->mode);
166                else
167                if (!(strncasecmp (mode->mode, "correct", 5)))
168                   correct = strdup(mode->mode);
169                else
170                if (!(strncasecmp (mode->mode, "norep", 5)))
171                   parser->RaAgMode++;
172                else
173                if (!(strncasecmp (mode->mode, "oui", 3)))
174                   parser->ArgusPrintEthernetVendors++;
175                else
176                if (!(strncasecmp (mode->mode, "poll", 4)))
177                   parser->RaPollMode++;
178                else
179                if (!(strncasecmp (mode->mode, "uni", 3)))
180                   parser->RaUniMode++;
181                else
182                if (!(strncasecmp (mode->mode, "man", 3)))
183                   parser->ArgusPrintMan = 1;
184                else
185                if (!(strncasecmp (mode->mode, "noman", 5)))
186                   parser->ArgusPrintMan = 0;
187                else {
188                   int done = 0;
189                   for (i = 0, ind = -1; !(done) && (i < ARGUSSPLITMODENUM); i++) {
190                      if (!(strncasecmp (mode->mode, RaSplitModes[i], 3))) {
191                         ind = i;
192                         switch (ind) {
193                            case ARGUSSPLITTIME:
194                            case ARGUSSPLITSIZE:
195                            case ARGUSSPLITCOUNT: {
196                               if ((mode = mode->nxt) == NULL)
197                                  usage();
198                               done++;
199                            }
200                         }
201                      }
202                   }
203                }
204             }
205 
206             if (ind < 0)
207                usage();
208 
209             switch (ind) {
210                case ARGUSSPLITTIME:
211                   if (ArgusParser->tflag)
212                      tsec = ArgusParser->startime_t.tv_sec;
213 
214                   nadp->mode = ind;
215                   if (isdigit((int)*mode->mode)) {
216                      char *ptr = NULL;
217                      nadp->value = strtod(mode->mode, (char **)&ptr);
218                      if (ptr == mode->mode)
219                         usage();
220                      else {
221 
222                         switch (*ptr) {
223                            case 'y':
224                               nadp->qual = ARGUSSPLITYEAR;
225                               localtime_r(&tsec, &nadp->RaStartTmStruct);
226                               nadp->RaStartTmStruct.tm_sec = 0;
227                               nadp->RaStartTmStruct.tm_min = 0;
228                               nadp->RaStartTmStruct.tm_hour = 0;
229                               nadp->RaStartTmStruct.tm_mday = 1;
230                               nadp->RaStartTmStruct.tm_mon = 0;
231                               tsec= mktime(&nadp->RaStartTmStruct);
232                               nadp->size = nadp->value*3600.0*24.0*7.0*52.0*1000000LL;
233                               break;
234 
235                            case 'M':
236                               nadp->qual = ARGUSSPLITMONTH;
237                               localtime_r(&tsec, &nadp->RaStartTmStruct);
238                               nadp->RaStartTmStruct.tm_sec = 0;
239                               nadp->RaStartTmStruct.tm_min = 0;
240                               nadp->RaStartTmStruct.tm_hour = 0;
241                               nadp->RaStartTmStruct.tm_mday = 1;
242                               nadp->RaStartTmStruct.tm_mon = 0;
243                               tsec = mktime(&nadp->RaStartTmStruct);
244                               nadp->size = nadp->value*3600.0*24.0*7.0*4.0*1000000LL;
245                               break;
246 
247                            case 'w':
248                               nadp->qual = ARGUSSPLITWEEK;
249                               localtime_r(&tsec, &nadp->RaStartTmStruct);
250                               nadp->RaStartTmStruct.tm_sec = 0;
251                               nadp->RaStartTmStruct.tm_min = 0;
252                               nadp->RaStartTmStruct.tm_hour = 0;
253                               nadp->RaStartTmStruct.tm_mday = 1;
254                               nadp->RaStartTmStruct.tm_mon = 0;
255                               tsec = mktime(&nadp->RaStartTmStruct);
256                               nadp->size = nadp->value*3600.0*24.0*7.0*1000000LL;
257                               break;
258 
259                            case 'd':
260                               nadp->qual = ARGUSSPLITDAY;
261                               localtime_r(&tsec, &nadp->RaStartTmStruct);
262                               nadp->RaStartTmStruct.tm_sec = 0;
263                               nadp->RaStartTmStruct.tm_min = 0;
264                               nadp->RaStartTmStruct.tm_hour = 0;
265                               tsec = mktime(&nadp->RaStartTmStruct);
266                               nadp->size = nadp->value*3600.0*24.0*1000000LL;
267                               break;
268 
269                            case 'h':
270                               nadp->qual = ARGUSSPLITHOUR;
271                               localtime_r(&tsec, &nadp->RaStartTmStruct);
272                               nadp->RaStartTmStruct.tm_sec = 0;
273                               nadp->RaStartTmStruct.tm_min = 0;
274                               tsec = mktime(&nadp->RaStartTmStruct);
275                               nadp->size = nadp->value*3600.0*1000000LL;
276                               break;
277 
278                            case 'm': {
279                               nadp->qual = ARGUSSPLITMINUTE;
280                               localtime_r(&tsec, &nadp->RaStartTmStruct);
281                               nadp->RaStartTmStruct.tm_sec = 0;
282                               tsec = nadp->value*60.0*1000000LL;
283                               nadp->size = tsec;
284                               break;
285                            }
286 
287                             default:
288                            case 's': {
289                               long long val = tsec / nadp->value;
290                               nadp->qual = ARGUSSPLITSECOND;
291                               tsec = val * nadp->value;
292                               localtime_r(&tsec, &nadp->RaStartTmStruct);
293 //                            nadp->start.tv_sec = tsec;
294                               nadp->size = nadp->value * 1000000LL;
295                               break;
296                            }
297                         }
298                      }
299                   }
300 
301                   RaBinProcess->rtime.tv_sec = tsec;
302 
303                   if (RaRealTime)
304                      nadp->start.tv_sec = 0;
305 
306                   if (ArgusSorter->ArgusSortAlgorithms[0] == NULL)
307                      ArgusSorter->ArgusSortAlgorithms[0] = ArgusSortStartTime;
308                   break;
309 
310                case ARGUSSPLITSIZE:
311                case ARGUSSPLITCOUNT:
312                   nadp->mode = ind;
313                   nadp->count = 1;
314 
315                   if (isdigit((int)*mode->mode)) {
316                      char *ptr = NULL;
317                      nadp->value = strtol(mode->mode, (char **)&ptr, 10);
318                      if (ptr == mode->mode)
319                         usage();
320                      else {
321                         switch (*ptr) {
322                            case 'B':
323                            case 'b':  nadp->value *= 1000000000; break;
324 
325                            case 'M':
326                            case 'm':  nadp->value *= 1000000; break;
327 
328                            case 'K':
329                            case 'k':  nadp->value *= 1000; break;
330                         }
331                      }
332                   }
333                   ArgusSorter->ArgusSortAlgorithms[0] = NULL;
334                   break;
335 
336                case ARGUSSPLITNOMODIFY:
337                   nadp->modify = 0;
338                   break;
339 
340                case ARGUSSPLITSOFT:
341                case ARGUSSPLITHARD:
342                   nadp->hard++;
343                   break;
344 
345                case ARGUSSPLITZERO:
346                   nadp->zero++;
347                   break;
348             }
349 
350             mode = mode->nxt;
351          }
352       }
353 
354       if ((RaBinProcess->size  = nadp->size) == 0) {
355 //       ArgusLog (LOG_ERR, "ArgusClientInit: no bin size specified");
356          nadp->value = 0xEFFFFFFF;
357          nadp->size = nadp->value * 1000000LL;
358          RaBinProcess->size  = nadp->size;
359       }
360 
361       if (!(nadp->value))
362          nadp->value = 1;
363 
364       if (nadp->mode < 0) {
365          nadp->value = 1;
366          nadp->count = 1;
367       }
368 
369       /* if content substitution, either time or any field, is used,
370          size and count modes will not work properly.  If using
371          the default count, set the value so that we generate only
372          one filename.
373 
374          if no substitution, then we need to add "aa" suffix to the
375          output file for count and size modes.
376       */
377 
378       if (parser->ArgusWfileList != NULL) {
379          struct ArgusWfileStruct *wfile = NULL;
380 
381          if ((wfile = (struct ArgusWfileStruct *)ArgusPopFrontList(parser->ArgusWfileList, ARGUS_NOLOCK)) != NULL) {
382             if (strcmp(wfile->filename, "-")) {
383                strncpy (outputfile, wfile->filename, MAXSTRLEN);
384                if ((strchr(outputfile, '%')) || (strchr(outputfile, '$'))) {
385                   switch (nadp->mode) {
386                      case ARGUSSPLITCOUNT:
387                         nadp->count = -1;
388                         break;
389 
390                      case ARGUSSPLITSIZE:
391                         for (i = 0; i < nadp->slen; i++) {
392 #if defined(HAVE_STRLCAT)
393                            strlcat(outputfile, "a", MAXSTRLEN - strlen(outputfile));
394 #else
395                            strcat(outputfile, "a");
396 #endif
397                         }
398                         break;
399                   }
400 
401                } else {
402                   switch (nadp->mode) {
403                      case ARGUSSPLITSIZE:
404                      case ARGUSSPLITCOUNT:
405                         for (i = 0; i < nadp->slen; i++) {
406 #if defined(HAVE_STRLCAT)
407                            strlcat(outputfile, "a", MAXSTRLEN - strlen(outputfile));
408 #else
409                            strcat(outputfile, "a");
410 #endif
411                         }
412                         break;
413                   }
414                }
415 
416                if (!(strchr(outputfile, '%'))) {
417                   switch (nadp->mode) {
418                      case ARGUSSPLITTIME:
419                        break;
420                   }
421                }
422 
423                nadp->filename = strdup(outputfile);
424                setArgusWfile (parser, outputfile, wfile->filterstr);
425             } else
426                setArgusWfile (parser, "-", NULL);
427          }
428       }
429 
430       parser->RaClientTimeout.tv_sec  = 0;
431       parser->RaClientTimeout.tv_usec = 100000;
432       parser->RaInitialized++;
433 
434 
435       if (ArgusParser->startime_t.tv_sec && ArgusParser->lasttime_t.tv_sec) {
436          nadp->count = (((ArgusParser->lasttime_t.tv_sec - ArgusParser->startime_t.tv_sec) * 1000000LL)/nadp->size) + 1;
437       } else {
438          int cnt = (parser->Bflag * 1000000) / nadp->size;
439          nadp->count = ((size > cnt) ? size : cnt);
440          if (parser->Bflag) {
441             nadp->count += 2;
442          } else {
443             nadp->count += 10000;
444          }
445       }
446 
447       if (parser->Gflag) {
448          parser->uflag++;
449          parser->RaFieldDelimiter = ',';
450       }
451 
452       for (i = 0; parser->RaPrintAlgorithmList[i] != NULL; i++) {
453          if (parser->RaPrintAlgorithmList[i]->print == ArgusPrintProto) {
454             parser->RaPrintMode |= RA_PRINTPROTO;
455             break;
456          }
457          if (parser->RaPrintAlgorithmList[i]->print == ArgusPrintSrcPort) {
458             break;
459          }
460          if (parser->RaPrintAlgorithmList[i]->print == ArgusPrintDstPort) {
461             break;
462          }
463          if (parser->RaPrintAlgorithmList[i]->print == ArgusPrintSourceID) {
464             parser->RaPrintMode |= RA_PRINTSRCID;
465             break;
466          }
467       }
468 
469       if (parser->ArgusFlowModelFile) {
470          if ((parser->ArgusAggregator = ArgusParseAggregator(parser, parser->ArgusFlowModelFile, NULL)) == NULL)
471             ArgusLog (LOG_ERR, "ArgusClientInit: ArgusParseAggregator error");
472 
473          if (parser->ArgusAggregatorFile != NULL)
474             free(parser->ArgusAggregatorFile);
475 
476          parser->ArgusAggregatorFile = strdup(parser->ArgusFlowModelFile);
477 
478       } else
479          if ((parser->ArgusAggregator = ArgusNewAggregator(parser, NULL, ARGUS_RECORD_AGGREGATOR)) == NULL)
480             ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewAggregator error");
481 
482       if (RaBinProcess->size == 0)
483          usage ();
484 
485       if (nocorrect != NULL) {
486          if (parser->ArgusAggregator->correct != NULL) {
487             free (parser->ArgusAggregator->correct);
488             parser->ArgusAggregator->correct = NULL;
489             free (nocorrect);
490          }
491       } else
492       if (correct != NULL) {
493          if (parser->ArgusAggregator->correct == NULL) {
494             parser->ArgusAggregator->correct = correct;
495          }
496       }
497 
498       parser->ArgusReverse = 0;
499       if (parser->ArgusAggregator->correct != NULL)
500          parser->ArgusReverse = 1;
501 
502       if (parser->dflag) {
503          int pid;
504 
505          if (parser->Sflag)
506             parser->ArgusReliableConnection++;
507 
508          ArgusLog(LOG_WARNING, "started");
509          if (chdir ("/") < 0)
510             ArgusLog (LOG_ERR, "Can't chdir to / %s", strerror(errno));
511 
512          if ((pid = fork ()) < 0) {
513             ArgusLog (LOG_ERR, "Can't fork daemon %s", strerror(errno));
514          } else {
515             if (pid) {
516                struct timespec ts = {0, 20000000};
517                int status;
518                nanosleep(&ts, NULL);
519                waitpid(pid, &status, WNOHANG);
520                if (kill(pid, 0) < 0) {
521                   exit (1);
522                } else
523                   exit (0);
524             } else {
525                FILE *tmpfile;
526 
527                parser->ArgusSessionId = setsid();
528                if ((tmpfile = freopen ("/dev/null", "r", stdin)) == NULL)
529                   ArgusLog (LOG_ERR, "Cannot map stdout to /dev/null");
530 
531                if ((tmpfile = freopen ("/dev/null", "a+", stdout)) == NULL)
532                   ArgusLog (LOG_ERR, "Cannot map stdout to /dev/null");
533 
534                if ((tmpfile = freopen ("/dev/null", "a+", stderr)) == NULL)
535                   ArgusLog (LOG_ERR, "Cannot map stderr to /dev/null");
536             }
537          }
538       }
539    }
540 
541 #ifdef ARGUSDEBUG
542    ArgusDebug (6, "ArgusClientInit()\n");
543 #endif
544 }
545 
546 
RaArgusInputComplete(struct ArgusInput * input)547 void RaArgusInputComplete (struct ArgusInput *input) { return; }
548 int RaDeleteBinProcess(struct ArgusParserStruct *, struct RaBinProcessStruct *);
549 
550 void
RaParseComplete(int sig)551 RaParseComplete (int sig)
552 {
553    if (sig >= 0) {
554       switch (sig) {
555          case SIGINT:
556             exit(0);
557             break;
558       }
559       if (!(ArgusParser->RaParseCompleting++)) {
560          if (RaBinProcess != NULL) {
561             RaDeleteBinProcess(ArgusParser, RaBinProcess);
562             RaBinProcess = NULL;
563          }
564 
565          if (ArgusSorter != NULL)
566             ArgusDeleteSorter(ArgusSorter);
567 
568 #ifdef ARGUSDEBUG
569          ArgusDebug (2, "RaParseComplete(caught signal %d)\n", sig);
570 #endif
571          switch (sig) {
572             case SIGHUP:
573             case SIGTERM:
574             case SIGQUIT: {
575                struct ArgusWfileStruct *wfile = NULL;
576 
577                ArgusShutDown(sig);
578 
579                if (ArgusParser->ArgusWfileList != NULL) {
580                   struct ArgusListObjectStruct *lobj = NULL;
581                   int i, count = ArgusParser->ArgusWfileList->count;
582 
583                   if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
584                      for (i = 0; i < count; i++) {
585                         if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
586                            if (wfile->fd != NULL) {
587 #ifdef ARGUSDEBUG
588                               ArgusDebug (2, "RaParseComplete: closing %s\n", wfile->filename);
589 #endif
590                               fflush (wfile->fd);
591                               fclose (wfile->fd);
592                               wfile->fd = NULL;
593                            }
594                         }
595                         lobj = lobj->nxt;
596                      }
597                   }
598                }
599                exit(0);
600                break;
601             }
602          }
603       }
604    }
605 
606 #ifdef ARGUSDEBUG
607    ArgusDebug (6, "RaParseComplete(%d)\n", sig);
608 #endif
609 }
610 
611 
612 void
ArgusClientTimeout()613 ArgusClientTimeout ()
614 {
615    struct ArgusRecordStruct *ns = NULL, *argus = NULL;
616    struct RaBinProcessStruct *rbps = RaBinProcess;
617    struct RaBinStruct *bin = NULL;
618    int i = 0, count, nflag = 0;
619 
620    if (RaRealTime) {  /* establish value for time comparison */
621       gettimeofday(&ArgusParser->ArgusRealTime, 0);
622       ArgusAdjustGlobalTime(ArgusParser, &ArgusParser->ArgusRealTime);
623 
624       if (ArgusLastTime.tv_sec != 0) {
625          if (ArgusLastRealTime.tv_sec > 0) {
626             RaDiffTime(&ArgusParser->ArgusRealTime, &ArgusLastRealTime, &dRealTime);
627             thisUsec = ((dRealTime.tv_sec * 1000000) + dRealTime.tv_usec) * RaUpdateRate;
628             dRealTime.tv_sec  = thisUsec / 1000000;
629             dRealTime.tv_usec = thisUsec % 1000000;
630 
631 
632             ArgusLastTime.tv_sec  += dRealTime.tv_sec;
633             ArgusLastTime.tv_usec += dRealTime.tv_usec;
634 
635             if (ArgusLastTime.tv_usec > 1000000) {
636                ArgusLastTime.tv_sec++;
637                ArgusLastTime.tv_usec -= 1000000;
638             }
639          }
640 
641          ArgusLastRealTime = ArgusParser->ArgusRealTime;
642       }
643    }
644 
645 
646    if ((ArgusParser->Bflag > 0) && rbps->rtime.tv_sec) {
647       struct timeval diffTimeBuf, *diffTime = &diffTimeBuf;
648       long long dtime;
649 
650       RaDiffTime(&ArgusParser->ArgusRealTime, &rbps->rtime, diffTime);
651       dtime = (diffTime->tv_sec * 1000000LL) + diffTime->tv_usec;
652 
653       if (dtime >= ((ArgusParser->Bflag * 1000000LL) + rbps->size)) {
654          long long rtime = (rbps->rtime.tv_sec * 1000000LL) + rbps->rtime.tv_usec;
655 
656          count = (rbps->end - rbps->start)/rbps->size;
657 
658          if (rbps->array != NULL) {
659             if ((bin = rbps->array[rbps->index]) != NULL) {
660                struct ArgusAggregatorStruct *agg = bin->agg;
661                int tcnt = 0;
662 
663                if (ArgusParser->ArgusGenerateManRecords) {
664                   struct ArgusRecordStruct *man = ArgusGenerateStatusMarRecord (NULL, ARGUS_START);
665                   struct ArgusRecord *rec = (struct ArgusRecord *)man->dsrs[0];
666                   rec->argus_mar.startime.tv_sec  = bin->stime.tv_sec;
667                   rec->argus_mar.startime.tv_usec = bin->stime.tv_usec;
668                   rec->argus_mar.now.tv_sec       = bin->stime.tv_sec;
669                   rec->argus_mar.now.tv_usec      = bin->stime.tv_usec;
670 
671                   RaSendArgusRecord (man);
672                   ArgusDeleteRecordStruct(ArgusParser, man);
673                }
674 
675                while (agg) {
676                   if (agg->queue->count) {
677                      int cnt = 0;
678 
679                      ArgusSortQueue(ArgusSorter, agg->queue);
680                      argus = ArgusCopyRecordStruct((struct ArgusRecordStruct *) agg->queue->array[0]);
681 
682                      if (nflag == 0)
683                         cnt = agg->queue->arraylen;
684                      else
685                         cnt = nflag > agg->queue->arraylen ? agg->queue->arraylen : nflag;
686 
687                      for (i = 1; i < cnt; i++)
688                         ArgusMergeRecords (agg, argus, (struct ArgusRecordStruct *)agg->queue->array[i]);
689 
690                      ArgusParser->ns = argus;
691 
692                      for (i = 0; i < cnt; i++) {
693                         if (agg->queue->array[i] != NULL)
694                            ((struct ArgusRecordStruct *)agg->queue->array[i])->rank = i + 1;
695                         RaSendArgusRecord ((struct ArgusRecordStruct *) agg->queue->array[i]);
696                      }
697                      ArgusDeleteRecordStruct(ArgusParser, ArgusParser->ns);
698 
699                      while((argus = (struct ArgusRecordStruct *)ArgusPopQueue(agg->queue, ARGUS_LOCK)) != NULL)
700                         ArgusDeleteRecordStruct(ArgusParser, argus);
701 
702                      tcnt += cnt;
703                   }
704                   agg = agg->nxt;
705                }
706 
707                if (ArgusParser->ArgusGenerateManRecords) {
708                   struct ArgusRecordStruct *man = ArgusGenerateStatusMarRecord (NULL, ARGUS_STOP);
709                   struct ArgusRecord *rec = (struct ArgusRecord *)man->dsrs[0];
710                   rec->argus_mar.startime.tv_sec  = bin->etime.tv_sec;
711                   rec->argus_mar.startime.tv_usec = bin->etime.tv_usec;
712                   rec->argus_mar.now.tv_sec       = bin->etime.tv_sec;
713                   rec->argus_mar.now.tv_usec      = bin->etime.tv_usec;
714                   RaSendArgusRecord (man);
715                   ArgusDeleteRecordStruct(ArgusParser, man);
716                }
717 
718 #ifdef ARGUSDEBUG
719                ArgusDebug (2, "ArgusClientTimeout() RaBinProcess: Bflag %f rtime %lld start %d.%06d size %.06f arraylen %d count %d index %d\n",
720                   ArgusParser->Bflag, rtime, bin->stime.tv_sec, bin->stime.tv_usec, bin->size/1000000.0, rbps->arraylen, tcnt, rbps->index);
721 #endif
722                RaDeleteBin(ArgusParser, bin);
723                rbps->array[rbps->index] = NULL;
724 
725             } else {
726                if (RaBinProcess->nadp.zero) {
727                   long long tval = RaBinProcess->start + (RaBinProcess->size * RaBinProcess->index);
728                   struct ArgusTimeObject *btime = NULL;
729 
730                   ns = ArgusGenerateRecordStruct(NULL, NULL, NULL);
731 
732                   btime = (struct ArgusTimeObject *)ns->dsrs[ARGUS_TIME_INDEX];
733                   btime->src.start.tv_sec  = tval / 1000000;
734                   btime->src.start.tv_usec = tval % 1000000;
735 
736                   tval += RaBinProcess->size;
737                   btime->src.end.tv_sec    = tval / 1000000;;
738                   btime->src.end.tv_usec   = tval % 1000000;
739 
740                   RaSendArgusRecord (ns);
741 
742 #ifdef ARGUSDEBUG
743                ArgusDebug (2, "ArgusClientTimeout() RaBinProcess: Bflag %f rtime %lld start %d.%06d size %.06f arraylen %d count %d index %d\n",
744                   ArgusParser->Bflag, rtime, btime->src.start.tv_sec, btime->src.start.tv_usec, rbps->size/1000000.0, rbps->arraylen, 0, rbps->index);
745 #endif
746 
747 /*
748                   ArgusDeleteRecordStruct(ArgusParser, ns);
749 */
750 #ifdef ARGUSDEBUG
751                   ArgusDebug (2, "ArgusClientTimeout() RaBinProcess: creating zero record\n");
752 #endif
753                }
754             }
755 
756             for (i = 0; i < count; i++)
757                rbps->array[i] = rbps->array[(i + 1)];
758 
759             rbps->start += rbps->size;
760             rbps->end   += rbps->size;
761 
762             rbps->array[count] = NULL;
763             rbps->startpt.tv_sec  += rbps->size;
764 
765             if ((ArgusParser->ArgusWfileList != NULL) && (!(ArgusListEmpty(ArgusParser->ArgusWfileList)))) {
766                struct ArgusWfileStruct *wfile = NULL;
767                struct ArgusListObjectStruct *lobj = NULL;
768                int i, count = ArgusParser->ArgusWfileList->count;
769 
770                if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
771                   for (i = 0; i < count; i++) {
772                      if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
773                         if (wfile->fd != NULL)
774                            fflush(wfile->fd);
775                      }
776                      lobj = lobj->nxt;
777                   }
778                }
779             }
780          }
781 
782          rtime += rbps->size;
783          rbps->rtime.tv_sec  = rtime / 1000000;
784          rbps->rtime.tv_usec = rtime % 1000000;
785       }
786    }
787 
788    if ((rbps->size > 0) && (rbps->rtime.tv_sec == 0)) {
789       long long rtime = (ArgusParser->ArgusRealTime.tv_sec * 1000000LL) / rbps->size;
790       rbps->rtime.tv_sec = (rtime + 1) * rbps->size;
791    }
792 }
793 
parse_arg(int argc,char ** argv)794 void parse_arg (int argc, char**argv) {}
795 
796 void
usage()797 usage ()
798 {
799    extern char version[];
800 
801    fprintf (stdout, "Rabins Version %s\n", version);
802 
803    fprintf (stdout, "usage: %s -M splitmode [splitmode options] [raoptions]\n", ArgusParser->ArgusProgramName);
804 
805    fprintf (stdout, "options: -B <secs>            holding time period for processing input data\n");
806 #if defined (ARGUSDEBUG)
807    fprintf (stdout, "         -D <level>           specify debug level\n");
808 #endif
809    fprintf (stdout, "         -M <mode>            supported modes of operation:\n");
810    fprintf (stdout, "             time N[smhdwmy]  split output into time series bins of N size\n");
811    fprintf (stdout, "                              s[econds], m[inutes], h[ours], d[ays], w[eeks], m[onths], y[ears].\n");
812    fprintf (stdout, "             nomodify         don't modify/split the input records when placing into bins\n");
813    fprintf (stdout, "             hard             set start and ending timestamps to bin time boundary values\n");
814    fprintf (stdout, "             zero             generate zero records when there are gaps in the series\n\n");
815 
816    fprintf (stdout, "         -m <mode>            supported aggregation objects:\n");
817    fprintf (stdout, "             none             no flow key\n");
818    fprintf (stdout, "             saddr            include the source address\n");
819    fprintf (stdout, "             daddr            include the destination address\n");
820    fprintf (stdout, "             proto            include the destination proto\n");
821    fprintf (stdout, "             sport            include the source port\n");
822    fprintf (stdout, "             dport            include the destination port\n");
823    fprintf (stdout, "             srcid            include the source identifier\n");
824 
825    fprintf (stdout, "         -P <sortfield>       specify the fields to sort records on.\n\n");
826 
827    fflush (stdout);
828    exit(1);
829 }
830 
831 void RaProcessThisRecord (struct ArgusParserStruct *, struct ArgusRecordStruct *);
832 
833 void
RaProcessRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * ns)834 RaProcessRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns)
835 {
836    switch (ns->hdr.type & 0xF0) {
837       case ARGUS_MAR:
838       case ARGUS_EVENT:
839          break;
840 
841       case ARGUS_NETFLOW:
842       case ARGUS_FAR: {
843          struct ArgusTimeObject *time = (void *)ns->dsrs[ARGUS_TIME_INDEX];
844 
845          if (time == NULL)
846             return;
847 
848          ArgusThisTime.tv_sec  = time->src.start.tv_sec;
849          ArgusThisTime.tv_usec = time->src.start.tv_usec;
850 
851          if (RaRealTime) {
852             if (ArgusLastTime.tv_sec == 0)
853                ArgusLastTime = ArgusThisTime;
854 
855             if (!((ArgusLastTime.tv_sec  > ArgusThisTime.tv_sec) ||
856                ((ArgusLastTime.tv_sec == ArgusThisTime.tv_sec) &&
857                 (ArgusLastTime.tv_usec > ArgusThisTime.tv_usec)))) {
858 
859                while ((ArgusThisTime.tv_sec  > ArgusLastTime.tv_sec) ||
860                      ((ArgusThisTime.tv_sec == ArgusLastTime.tv_sec) &&
861                       (ArgusThisTime.tv_usec > ArgusLastTime.tv_usec))) {
862                   struct timespec ts = {0, 0};
863                   int thisRate;
864 
865                   RaDiffTime(&ArgusThisTime, &ArgusLastTime, &dThisTime);
866                   thisRate = ((dThisTime.tv_sec * 1000000) + dThisTime.tv_usec)/RaUpdateRate;
867                   thisRate = (thisRate > 100000) ? 100000 : thisRate;
868 
869                   ts.tv_nsec =  thisRate * 1000;
870                   nanosleep (&ts, NULL);
871 
872                   ArgusClientTimeout ();
873 
874                   gettimeofday(&parser->ArgusRealTime, 0);
875 
876                   if (ArgusLastRealTime.tv_sec > 0) {
877                      RaDiffTime(&parser->ArgusRealTime, &ArgusLastRealTime, &dRealTime);
878                      thisUsec = ((dRealTime.tv_sec * 1000000) + dRealTime.tv_usec) * RaUpdateRate;
879                      dRealTime.tv_sec  = thisUsec / 1000000;
880                      dRealTime.tv_usec = thisUsec % 1000000;
881 
882                      ArgusLastTime.tv_sec  += dRealTime.tv_sec;
883                      ArgusLastTime.tv_usec += dRealTime.tv_usec;
884                      if (ArgusLastTime.tv_usec > 1000000) {
885                         ArgusLastTime.tv_sec++;
886                         ArgusLastTime.tv_usec -= 1000000;
887                      }
888                   }
889                   ArgusLastRealTime = parser->ArgusRealTime;
890                }
891             }
892          } else
893             ArgusLastTime = parser->ArgusRealTime;
894 
895          if (parser->RaMonMode) {
896             struct ArgusRecordStruct *tns = ArgusCopyRecordStruct(ns);
897             struct ArgusFlow *flow;
898 
899             if ((flow = (struct ArgusFlow *)ns->dsrs[ARGUS_FLOW_INDEX]) != NULL) {
900                flow->hdr.subtype &= ~ARGUS_REVERSE;
901                flow->hdr.argus_dsrvl8.qual &= ~ARGUS_DIRECTION;
902             }
903 
904             RaProcessThisRecord(parser, ns);
905 
906             ArgusReverseRecord(tns);
907 
908             if ((flow = (struct ArgusFlow *)tns->dsrs[ARGUS_FLOW_INDEX]) != NULL) {
909                flow->hdr.subtype &= ~ARGUS_REVERSE;
910                flow->hdr.argus_dsrvl8.qual &= ~ARGUS_DIRECTION;
911             }
912 
913             RaProcessThisRecord(parser, tns);
914             ArgusDeleteRecordStruct(parser, tns);
915 
916          } else {
917             struct ArgusAggregatorStruct *agg = parser->ArgusAggregator;
918 
919             if (agg && agg->ArgusMatrixMode) {
920                struct ArgusFlow *flow = (struct ArgusFlow *)ns->dsrs[ARGUS_FLOW_INDEX];
921 
922                if (flow != NULL) {
923                   if (agg->mask & ((0x01LL << ARGUS_MASK_SADDR) | (0x01LL << ARGUS_MASK_DADDR))) {
924                      switch (flow->hdr.subtype & 0x3F) {
925                         case ARGUS_FLOW_LAYER_3_MATRIX:
926                            case ARGUS_FLOW_CLASSIC5TUPLE: {
927                               switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
928                                  case ARGUS_TYPE_IPV4: {
929                                     if (flow->ip_flow.ip_src > flow->ip_flow.ip_dst)
930                                        ArgusReverseRecord(ns);
931                                  }
932                                  break;
933 
934                                  case ARGUS_TYPE_IPV6: {
935                                     int i;
936                                     for (i = 0; i < 4; i++) {
937                                        if (flow->ipv6_flow.ip_src[i] < flow->ipv6_flow.ip_dst[i])
938                                           break;
939 
940                                        if (flow->ipv6_flow.ip_src[i] > flow->ipv6_flow.ip_dst[i]) {
941                                           ArgusReverseRecord(ns);
942                                           break;
943                                        }
944                                     }
945                                  }
946                                  break;
947                               }
948                               break;
949                            }
950 
951                            default:
952                               break;
953                         }
954 
955                   } else
956                   if (agg->mask & ((0x01LL << ARGUS_MASK_SMAC) | (0x01LL << ARGUS_MASK_DMAC))) {
957 
958                      struct ArgusMacStruct *m1 = NULL;
959                      if ((m1 = (struct ArgusMacStruct *) ns->dsrs[ARGUS_MAC_INDEX]) != NULL) {
960                         switch (m1->hdr.subtype) {
961                            case ARGUS_TYPE_ETHER: {
962                               struct ether_header *e1 = &m1->mac.mac_union.ether.ehdr;
963                               int i;
964 
965                               for (i = 0; i < 6; i++) {
966 #if defined(ARGUS_SOLARIS)
967                                  if (e1->ether_shost.ether_addr_octet[i] < e1->ether_dhost.ether_addr_octet[i])
968                                     break;
969                                  if (e1->ether_shost.ether_addr_octet[i] > e1->ether_dhost.ether_addr_octet[i]) {
970                                     ArgusReverseRecord(ns);
971                                     break;
972                                  }
973 #else
974                                  if (e1->ether_shost[i] < e1->ether_dhost[i])
975                                     break;
976                                  if (e1->ether_shost[i] > e1->ether_dhost[i]) {
977                                     ArgusReverseRecord(ns);
978                                     break;
979                                  }
980 #endif
981                               }
982                               break;
983                            }
984                         }
985                      }
986                   }
987 
988                   flow->hdr.subtype &= ~ARGUS_REVERSE;
989                   flow->hdr.argus_dsrvl8.qual &= ~ARGUS_DIRECTION;
990                }
991             }
992             RaProcessThisRecord(parser, ns);
993          }
994       }
995    }
996 }
997 
998 void
RaProcessThisRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)999 RaProcessThisRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
1000 {
1001    extern struct RaBinProcessStruct *RaBinProcess;
1002    extern int ArgusTimeRangeStrategy;
1003    struct ArgusAggregatorStruct *agg = parser->ArgusAggregator;
1004    int found = 0, offset, tstrat;
1005 
1006    while (agg && !found) {
1007       int retn = 0, fretn = -1, lretn = -1;
1008       if (ArgusParser->tflag) {
1009          tstrat = ArgusTimeRangeStrategy;
1010          ArgusTimeRangeStrategy = 1;
1011       }
1012 
1013       if (agg->filterstr) {
1014          struct nff_insn *fcode = agg->filter.bf_insns;
1015          fretn = ArgusFilterRecord (fcode, argus);
1016       }
1017 
1018       if (agg->grepstr) {
1019          struct ArgusLabelStruct *label;
1020          if (((label = (void *)argus->dsrs[ARGUS_LABEL_INDEX]) != NULL)) {
1021             if (regexec(&agg->lpreg, label->l_un.label, 0, NULL, 0))
1022                lretn = 0;
1023             else
1024                lretn = 1;
1025          } else
1026             lretn = 0;
1027       }
1028 
1029       retn = (lretn < 0) ? ((fretn < 0) ? 1 : fretn) : ((fretn < 0) ? lretn : (lretn && fretn));
1030 
1031       if (retn != 0) {
1032          struct ArgusRecordStruct *tns = NULL, *ns = NULL;
1033 
1034          ns = ArgusCopyRecordStruct(argus);
1035 
1036          if (agg->labelstr)
1037             ArgusAddToRecordLabel(parser, ns, agg->labelstr);
1038 
1039          ArgusAlignInit(parser, ns, &RaBinProcess->nadp);
1040 
1041          offset = (ArgusParser->Bflag * 1000000)/RaBinProcess->nadp.size;
1042 
1043          while ((tns = ArgusAlignRecord(parser, ns, &RaBinProcess->nadp)) != NULL) {
1044             if ((retn = ArgusCheckTime (parser, tns)) != 0) {
1045                struct ArgusMetricStruct *metric = (void *)tns->dsrs[ARGUS_METRIC_INDEX];
1046 
1047                if ((metric != NULL) && ((metric->src.pkts + metric->dst.pkts) > 0)) {
1048                   if (!(retn = ArgusInsertRecord(parser, RaBinProcess, tns, offset)))
1049                      ArgusDeleteRecordStruct(parser, tns);
1050                } else
1051                   ArgusDeleteRecordStruct(parser, tns);
1052             } else
1053                ArgusDeleteRecordStruct(parser, tns);
1054          }
1055 
1056          ArgusDeleteRecordStruct(parser, ns);
1057          found++;
1058       }
1059       agg = agg->nxt;
1060    }
1061 
1062    if (ArgusParser->tflag)
1063       ArgusTimeRangeStrategy = tstrat;
1064 
1065 #ifdef ARGUSDEBUG
1066    ArgusDebug (6, "RaProcessThisRecord (0x%x) done\n", argus);
1067 #endif
1068 }
1069 
1070 
1071 int
RaSendArgusRecord(struct ArgusRecordStruct * argus)1072 RaSendArgusRecord(struct ArgusRecordStruct *argus)
1073 {
1074    int retn = 1;
1075    char buf[0x10000];
1076 
1077    if (argus->status & ARGUS_RECORD_WRITTEN)
1078       return (retn);
1079 
1080    if (!(retn = ArgusCheckTime (ArgusParser, argus)))
1081       return (retn);
1082 
1083    if ((ArgusParser->ArgusWfileList != NULL) && (!(ArgusListEmpty(ArgusParser->ArgusWfileList)))) {
1084       struct ArgusWfileStruct *wfile = NULL;
1085       struct ArgusListObjectStruct *lobj = NULL;
1086       int i, count = ArgusParser->ArgusWfileList->count;
1087 
1088       if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
1089          for (i = 0; i < count; i++) {
1090             if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
1091                int retn = 1;
1092                if (wfile->filterstr) {
1093                   struct nff_insn *wfcode = wfile->filter.bf_insns;
1094                   retn = ArgusFilterRecord (wfcode, argus);
1095                }
1096 
1097                if (retn != 0) {
1098                   if ((ArgusParser->exceptfile == NULL) || strcmp(wfile->filename, ArgusParser->exceptfile)) {
1099                      struct ArgusRecord *argusrec = NULL;
1100 
1101                      if ((argusrec = ArgusGenerateRecord (argus, 0L, buf)) != NULL) {
1102 #ifdef _LITTLE_ENDIAN
1103                         ArgusHtoN(argusrec);
1104 #endif
1105                         ArgusWriteNewLogfile (ArgusParser, argus->input, wfile, argusrec);
1106                      }
1107                   }
1108                }
1109             }
1110             lobj = lobj->nxt;
1111          }
1112       }
1113 
1114    } else {
1115       if (!ArgusParser->qflag) {
1116          switch (argus->hdr.type & 0xF0) {
1117             case ARGUS_MAR:
1118                if (!(ArgusParser->ArgusPrintMan))
1119                 break;
1120 
1121             default: {
1122                if (ArgusParser->Lflag) {
1123                   if (ArgusParser->RaLabel == NULL)
1124                      ArgusParser->RaLabel = ArgusGenerateLabel(ArgusParser, argus);
1125 
1126                   if (!(ArgusParser->RaLabelCounter++ % ArgusParser->Lflag)) {
1127                      if (ArgusParser->Gflag) {
1128                         printf ("Columns=%s\n", ArgusParser->RaLabel);
1129                      } else
1130                         printf ("%s", ArgusParser->RaLabel);
1131                   }
1132 
1133                   if (ArgusParser->Lflag < 0)
1134                      ArgusParser->Lflag = 0;
1135 
1136                   if (ArgusParser->Gflag) {
1137                      switch (ArgusParser->RaPrintMode) {
1138                         case RA_PRINTSRCID:
1139                            printf ("Probes=\n");
1140                            break;
1141 
1142                         case RA_PRINTPROTO: {
1143                            printf ("Protos=\n");
1144                            break;
1145                         }
1146 
1147                         default: {
1148                            printf ("Objects=\n");
1149                            break;
1150                         }
1151                      }
1152                   }
1153                   printf ("\n");
1154                }
1155 
1156                *(int *)&buf = 0;
1157                ArgusPrintRecord(ArgusParser, buf, argus, MAXSTRLEN);
1158                if (fprintf (stdout, "%s\n", buf) < 0)
1159                   RaParseComplete (SIGQUIT);
1160                fflush(stdout);
1161                break;
1162             }
1163          }
1164       }
1165    }
1166 
1167    argus->status |= ARGUS_RECORD_WRITTEN;
1168    return (retn);
1169 }
1170 
1171 
1172 void ArgusWindowClose(void);
1173 
ArgusWindowClose(void)1174 void ArgusWindowClose(void) {
1175 #ifdef ARGUSDEBUG
1176    ArgusDebug (6, "ArgusWindowClose () returning\n");
1177 #endif
1178 }
1179 
1180 
1181 char *
RaSplitFilename(struct ArgusAdjustStruct * nadp)1182 RaSplitFilename (struct ArgusAdjustStruct *nadp)
1183 {
1184    char *retn = NULL, tmpbuf[MAXSTRLEN];
1185    char *filename = nadp->filename;
1186    int len, i = 1, carry = 0;
1187 
1188    if (filename != NULL) {
1189       len = strlen(filename);
1190 
1191       for (i = 0; i < nadp->slen; i++)
1192          if (filename[len - (i + 1)] == 'z')
1193             carry++;
1194 
1195       if ((carry == (nadp->slen - 1)) && (filename[len - nadp->slen] == 'y')) {
1196          strncpy(tmpbuf, filename, MAXSTRLEN);
1197          tmpbuf[strlen(tmpbuf) - nadp->slen] = 'z';
1198          for (i = 0; i < nadp->slen; i++) {
1199 #if defined(HAVE_STRLCAT)
1200             strlcat(tmpbuf, "a", MAXSTRLEN - strlen(tmpbuf));
1201 #else
1202             strcat(tmpbuf, "a");
1203 #endif
1204          }
1205          nadp->slen++;
1206 
1207       } else {
1208          for (i = 0, carry = 0; i < nadp->slen; i++) {
1209             if (filename[len - (i + 1)] == 'z') {
1210                filename[len - (i + 1)] = 'a';
1211             } else {
1212                filename[len - (i + 1)]++;
1213                break;
1214             }
1215          }
1216          strncpy (tmpbuf, filename, MAXSTRLEN);
1217       }
1218 
1219       if (nadp->filename)
1220          free(nadp->filename);
1221 
1222       nadp->filename = strdup(tmpbuf);
1223       retn = nadp->filename;
1224    }
1225 
1226 
1227 #ifdef ARGUSDEBUG
1228    ArgusDebug (5, "RaSplitFilename (0x%x) returning %s\n", nadp, retn);
1229 #endif
1230 
1231    return (retn);
1232 }
1233 
1234 int
RaProcessSplitOptions(struct ArgusParserStruct * parser,char * str,int len,struct ArgusRecordStruct * ns)1235 RaProcessSplitOptions(struct ArgusParserStruct *parser, char *str, int len, struct ArgusRecordStruct *ns)
1236 {
1237    char resultbuf[MAXSTRLEN], tmpbuf[MAXSTRLEN];
1238    char *ptr = NULL, *tptr = str;
1239    int retn = 0, i, x, slen = 0;
1240 
1241    bzero (resultbuf, len);
1242 
1243    while ((ptr = strchr (tptr, '$')) != NULL) {
1244       *ptr++ = '\0';
1245       slen = strlen(resultbuf);
1246       snprintf (&resultbuf[slen], MAXSTRLEN - slen, "%s", tptr);
1247 
1248       for (i = 0, x = 0; x < MAX_PRINT_ALG_TYPES; x++) {
1249          if (!strncmp (RaPrintAlgorithmTable[x].field, ptr, strlen(RaPrintAlgorithmTable[x].field))) {
1250             bzero (tmpbuf, MAXSTRLEN);
1251             RaPrintAlgorithmTable[x].print(parser, tmpbuf, ns, RaPrintAlgorithmTable[x].length);
1252 
1253             while (isspace((int)tmpbuf[strlen(tmpbuf) - 1]))
1254                tmpbuf[strlen(tmpbuf) - 1] = '\0';
1255 
1256             while (isspace((int)tmpbuf[i])) i++;
1257             slen = strlen(resultbuf);
1258             snprintf (&resultbuf[slen], MAXSTRLEN - slen, "%s", &tmpbuf[i]);
1259 
1260             ptr += strlen(RaPrintAlgorithmTable[x].field);
1261             while (*ptr && (*ptr != '$'))
1262                bcopy (ptr++, &resultbuf[strlen(resultbuf)], 1);
1263             break;
1264          }
1265       }
1266 
1267       tptr = ptr;
1268       retn++;
1269    }
1270 
1271    if (retn) {
1272       bzero (str, len);
1273       bcopy (resultbuf, str, strlen(resultbuf));
1274    }
1275 
1276 #ifdef ARGUSDEBUG
1277    ArgusDebug (1, "RaProcessSplitOptions(%s, %d, 0x%x): returns %d", str, len, ns, retn);
1278 #endif
1279 
1280    return (retn);
1281 }
1282 
1283 
1284 int
RaDeleteBinProcess(struct ArgusParserStruct * parser,struct RaBinProcessStruct * rbps)1285 RaDeleteBinProcess(struct ArgusParserStruct *parser, struct RaBinProcessStruct *rbps)
1286 {
1287    struct RaBinStruct *bin = NULL;
1288    struct ArgusRecordStruct *ns = NULL;
1289    int max = ((parser->tflag && parser->RaExplicitDate) ? rbps->nadp.count : rbps->max) + 1;
1290    int startsecs = 0, endsecs = 0, i;
1291    int retn = 0;
1292 
1293    char stimebuf[128], dtimebuf[128], etimebuf[128];
1294    int bins;
1295 
1296    if (rbps->array != NULL) {
1297       if (!(parser->tflag)) {
1298          for (i = 0; i < max; i++) {
1299             if ((bin = rbps->array[i]) != NULL) {
1300                if (startsecs == 0)
1301                   startsecs = bin->stime.tv_sec;
1302                endsecs = bin->etime.tv_sec;
1303             }
1304          }
1305 
1306          rbps->startpt.tv_sec = startsecs;
1307          rbps->scalesecs      = (endsecs - startsecs) + (rbps->size / 1000000);
1308 
1309          if ((parser->RaEndTime.tv_sec >  rbps->endpt.tv_sec) ||
1310                   ((parser->RaEndTime.tv_sec == rbps->endpt.tv_sec) &&
1311                    (parser->RaEndTime.tv_usec > rbps->endpt.tv_usec)))
1312             parser->RaEndTime = rbps->endpt;
1313 
1314       } else {
1315          rbps->startpt.tv_sec  = parser->startime_t.tv_sec;
1316          rbps->startpt.tv_usec = parser->startime_t.tv_usec;
1317          rbps->endpt.tv_sec    = parser->lasttime_t.tv_sec;
1318          rbps->endpt.tv_usec   = parser->lasttime_t.tv_usec;
1319          rbps->scalesecs       = parser->lasttime_t.tv_sec - parser->startime_t.tv_sec;
1320          rbps->start           = parser->startime_t.tv_sec * 1000000LL;
1321       }
1322 
1323       if ((parser->ArgusWfileList == NULL) && (parser->Gflag)) {
1324          if (parser->Hstr != NULL) {
1325 
1326          } else {
1327 
1328             ArgusPrintTime(parser, stimebuf, &rbps->startpt);
1329             ArgusPrintTime(parser, dtimebuf, &rbps->endpt);
1330             ArgusPrintTime(parser, etimebuf, &parser->RaEndTime);
1331 
1332             stimebuf[strlen(stimebuf) - 1] = '\0';
1333             dtimebuf[strlen(dtimebuf) - 1] = '\0';
1334             etimebuf[strlen(etimebuf) - 1] = '\0';
1335 
1336             printf ("StartTime=%s\n", stimebuf);
1337             printf ("StopTime=%s\n",  dtimebuf);
1338             printf ("LastTime=%s\n",  etimebuf);
1339             printf ("Seconds=%d\n", rbps->scalesecs);
1340             printf ("BinSize=%1.*f\n", parser->pflag, (rbps->size * 1.0)/1000000);
1341             bins = ((rbps->scalesecs + (rbps->size/1000000 - 1))/(rbps->size / 1000000));
1342             printf ("Bins=%d\n", bins);
1343          }
1344       }
1345    }
1346 
1347    for (i = rbps->index; i < max; i++) {
1348       if ((rbps->array != NULL) && ((bin = rbps->array[i]) != NULL)) {
1349          struct ArgusAggregatorStruct *agg = bin->agg;
1350 
1351          if (ArgusParser->ArgusGenerateManRecords) {
1352             struct ArgusRecordStruct *man = ArgusGenerateStatusMarRecord (NULL, ARGUS_START);
1353             struct ArgusRecord *rec = (struct ArgusRecord *)man->dsrs[0];
1354             rec->argus_mar.startime.tv_sec  = bin->stime.tv_sec;
1355             rec->argus_mar.startime.tv_usec = bin->stime.tv_usec;
1356             rec->argus_mar.now.tv_sec       = bin->stime.tv_sec;
1357             rec->argus_mar.now.tv_usec      = bin->stime.tv_usec;
1358 
1359             RaSendArgusRecord (man);
1360             ArgusDeleteRecordStruct(ArgusParser, man);
1361          }
1362 
1363          while (agg) {
1364             int rank = 1;
1365             ArgusSortQueue(ArgusSorter, agg->queue);
1366             while ((ns = (struct ArgusRecordStruct *) ArgusPopQueue(agg->queue, ARGUS_NOLOCK)) != NULL) {
1367                ns->rank = rank++;
1368                if ((parser->eNoflag == 0 ) || ((parser->eNoflag >= ns->rank) && (parser->sNoflag <= ns->rank)))
1369                   RaSendArgusRecord (ns);
1370                ArgusDeleteRecordStruct(parser, ns);
1371             }
1372             agg = agg->nxt;
1373          }
1374 
1375          if (ArgusParser->ArgusGenerateManRecords) {
1376             struct ArgusRecordStruct *man = ArgusGenerateStatusMarRecord (NULL, ARGUS_STOP);
1377             struct ArgusRecord *rec = (struct ArgusRecord *)man->dsrs[0];
1378             rec->argus_mar.startime.tv_sec  = bin->etime.tv_sec;
1379             rec->argus_mar.startime.tv_usec = bin->etime.tv_usec;
1380             rec->argus_mar.now.tv_sec       = bin->etime.tv_sec;
1381             rec->argus_mar.now.tv_usec      = bin->etime.tv_usec;
1382 
1383             RaSendArgusRecord (man);
1384             ArgusDeleteRecordStruct(ArgusParser, man);
1385          }
1386 
1387       } else {
1388          if (rbps->nadp.zero && ((i >= rbps->index) &&
1389                  ((((i - rbps->index) * 1.0) * rbps->size) < (rbps->scalesecs * 1000000LL)))) {
1390             long long tval = rbps->start + (rbps->size * (i - rbps->index));
1391 
1392             ns = ArgusGenerateRecordStruct(NULL, NULL, NULL);
1393 
1394             ((struct ArgusTimeObject *)ns->dsrs[ARGUS_TIME_INDEX])->src.start.tv_sec  = tval / 1000000;
1395             ((struct ArgusTimeObject *)ns->dsrs[ARGUS_TIME_INDEX])->src.start.tv_usec = tval % 1000000;
1396 
1397             tval += rbps->size;
1398             ((struct ArgusTimeObject *)ns->dsrs[ARGUS_TIME_INDEX])->src.end.tv_sec    = tval / 1000000;;
1399             ((struct ArgusTimeObject *)ns->dsrs[ARGUS_TIME_INDEX])->src.end.tv_usec   = tval % 1000000;
1400 
1401             RaSendArgusRecord (ns);
1402          }
1403       }
1404    }
1405 
1406    for (i = rbps->index; i < max; i++) {
1407       if ((rbps->array != NULL) && ((bin = rbps->array[i]) != NULL)) {
1408          RaDeleteBin(parser, bin);
1409       }
1410    }
1411 
1412    if (rbps->array != NULL) ArgusFree(rbps->array);
1413    ArgusFree(rbps);
1414    return (retn);
1415 }
1416