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