|
@@ -29,8 +29,7 @@ void usage()
|
29
|
29
|
printf("\t\t%s\n\n", help[i][0]);
|
30
|
30
|
i++;
|
31
|
31
|
}
|
32
|
|
- printf("\tLOGFILES\n\t\tLogfiles, can take '-' as value to tell ttail \
|
33
|
|
-to read from stdin instead of files\n");
|
|
32
|
+ printf(TTAIL_HELP_TEXT);
|
34
|
33
|
}
|
35
|
34
|
|
36
|
35
|
ttail_t *ttail_init(int argc, char **argv)
|
|
@@ -398,33 +397,19 @@ int ttail_set_dates(ttail_t* res, char* dates[2])
|
398
|
397
|
{
|
399
|
398
|
continue;
|
400
|
399
|
}
|
401
|
|
- if(!(res->flag & TTAIL_FLAG_FORMAT))
|
|
400
|
+ date = dates[c];
|
|
401
|
+ if(!strncmp(date, "#-", 2))
|
402
|
402
|
{
|
403
|
|
- /* no format specified */
|
404
|
|
- ret = ttail_format_guess(res, dates[c],
|
405
|
|
- c==0?&(res->date_min):&(res->date_max));
|
406
|
|
- if(ret < 0)
|
407
|
|
- {
|
408
|
|
- fprintf(stderr, "Unable to guess format for \
|
409
|
|
-date '%s'\n", dates[c]);
|
410
|
|
- return -1;
|
411
|
|
- }
|
412
|
|
- res->flag |= c?TTAIL_FLAG_DATE_MAX:TTAIL_FLAG_DATE_MIN;
|
413
|
|
- continue;
|
|
403
|
+ /* relative date */
|
|
404
|
+ ret = _ttail_set_date_relative(res, date, c);
|
414
|
405
|
}
|
415
|
|
- date = strptime(dates[c], res->fmt,
|
416
|
|
- c==0?&(res->date_min):&(res->date_max));
|
417
|
|
- if(!date)
|
|
406
|
+ else
|
418
|
407
|
{
|
419
|
|
- fprintf(stderr, "Unable to parse date-%s '%s' with \
|
420
|
|
-format '%s'\n", c==0?"min":"max", dates[c], res->fmt);
|
421
|
|
- return -1;
|
|
408
|
+ /* date from format */
|
|
409
|
+ ret = _ttail_set_date_fmt(res, date, c);
|
422
|
410
|
}
|
423
|
|
- else if(*date != '\0')
|
|
411
|
+ if(ret < 0)
|
424
|
412
|
{
|
425
|
|
- fprintf(stderr, "Leading caracters for date-%s : '%s' \
|
426
|
|
-is not matched in '%s'\n",\
|
427
|
|
- c==0?"min":"max", date, dates[c]);
|
428
|
413
|
return -1;
|
429
|
414
|
}
|
430
|
415
|
res->flag |= c?TTAIL_FLAG_DATE_MAX:TTAIL_FLAG_DATE_MIN;
|
|
@@ -436,6 +421,217 @@ is not matched in '%s'\n",\
|
436
|
421
|
return 0;
|
437
|
422
|
}
|
438
|
423
|
|
|
424
|
+int _ttail_set_date_fmt(ttail_t* res, char* date, int c)
|
|
425
|
+{
|
|
426
|
+ int ret;
|
|
427
|
+ char *endp;
|
|
428
|
+
|
|
429
|
+ if(!(res->flag & TTAIL_FLAG_FORMAT))
|
|
430
|
+ {
|
|
431
|
+ /* no format specified */
|
|
432
|
+ ret = ttail_format_guess(res, date,
|
|
433
|
+ c==0?&(res->date_min):&(res->date_max));
|
|
434
|
+ if(ret < 0)
|
|
435
|
+ {
|
|
436
|
+ fprintf(stderr, "Unable to guess format for \
|
|
437
|
+date '%s'\n", date);
|
|
438
|
+ return -1;
|
|
439
|
+ }
|
|
440
|
+ res->flag |= c?TTAIL_FLAG_DATE_MAX:TTAIL_FLAG_DATE_MIN;
|
|
441
|
+ return 0;
|
|
442
|
+ }
|
|
443
|
+ endp = strptime(date, res->fmt,
|
|
444
|
+ c==0?&(res->date_min):&(res->date_max));
|
|
445
|
+ if(!endp)
|
|
446
|
+ {
|
|
447
|
+ fprintf(stderr, "Unable to parse date-%s '%s' with \
|
|
448
|
+format '%s'\n", c==0?"min":"max", date, res->fmt);
|
|
449
|
+ return -1;
|
|
450
|
+ }
|
|
451
|
+ else if(*endp != '\0')
|
|
452
|
+ {
|
|
453
|
+ fprintf(stderr, "Leading caracters for date-%s : '%s' \
|
|
454
|
+is not matched in '%s'\n",\
|
|
455
|
+ c==0?"min":"max", endp, date);
|
|
456
|
+ return -1;
|
|
457
|
+ }
|
|
458
|
+ return 0;
|
|
459
|
+}
|
|
460
|
+int _ttail_set_date_relative(ttail_t* res, char* date, int c)
|
|
461
|
+{
|
|
462
|
+ time_t now;
|
|
463
|
+ char *unit;
|
|
464
|
+ int value;
|
|
465
|
+ struct tm *tm, *tm_p;
|
|
466
|
+ short mod;
|
|
467
|
+
|
|
468
|
+ tm = c==0?&(res->date_min):&(res->date_max);
|
|
469
|
+ ttail_tm_init(tm);
|
|
470
|
+ if(time(&now) < 0)
|
|
471
|
+ {
|
|
472
|
+ fprintf(stderr, "Unable to retrieve time using time()\n");
|
|
473
|
+ return -1;
|
|
474
|
+ }
|
|
475
|
+ if(!(tm_p = localtime(&now)))
|
|
476
|
+ {
|
|
477
|
+ fprintf(stderr, "Unable to retrieve localtime using localtime()\n");
|
|
478
|
+ return -1;
|
|
479
|
+ }
|
|
480
|
+
|
|
481
|
+ memcpy(tm, tm_p, sizeof(struct tm));
|
|
482
|
+
|
|
483
|
+ mod = 0;
|
|
484
|
+ unit = NULL;
|
|
485
|
+ value = (int)strtol(date+2, &unit, 10);
|
|
486
|
+ switch(*unit)
|
|
487
|
+ {
|
|
488
|
+ case 's':
|
|
489
|
+ if(*(unit+1) == '\0' || !strcmp(unit, "sec"))
|
|
490
|
+ {
|
|
491
|
+ tm->tm_sec -= value;
|
|
492
|
+ if(tm->tm_sec < 0)
|
|
493
|
+ {
|
|
494
|
+ mod = 1;
|
|
495
|
+ value = abs(tm->tm_sec);
|
|
496
|
+ tm->tm_sec = 60 - (value % 60);
|
|
497
|
+ value /= 60;
|
|
498
|
+ value++;
|
|
499
|
+ }
|
|
500
|
+ if(!mod)
|
|
501
|
+ {
|
|
502
|
+ break;
|
|
503
|
+ }
|
|
504
|
+ }
|
|
505
|
+ case 'm':
|
|
506
|
+ if(mod || *(unit+1) == '\0' || !strcmp(unit, "min"))
|
|
507
|
+ {
|
|
508
|
+ mod = 0;
|
|
509
|
+ tm->tm_min -= value;
|
|
510
|
+ if(tm->tm_min < 0)
|
|
511
|
+ {
|
|
512
|
+ mod = 1;
|
|
513
|
+ value = abs(tm->tm_min);
|
|
514
|
+ tm->tm_min = 60 - (value % 60);
|
|
515
|
+ value /= 60;
|
|
516
|
+ value++;
|
|
517
|
+ printf("Value left : %d\n", value);
|
|
518
|
+ }
|
|
519
|
+ if(!mod)
|
|
520
|
+ {
|
|
521
|
+ break;
|
|
522
|
+ }
|
|
523
|
+ }
|
|
524
|
+ case 'h':
|
|
525
|
+ if(mod || *(unit+1) == '\0' || !strcmp(unit, "hour"))
|
|
526
|
+ {
|
|
527
|
+ mod = 0;
|
|
528
|
+ tm->tm_hour -= value;
|
|
529
|
+ if(tm->tm_hour < 0)
|
|
530
|
+ {
|
|
531
|
+ mod = 1;
|
|
532
|
+ value = abs(tm->tm_hour);
|
|
533
|
+ tm->tm_hour = 24 - (value % 24);
|
|
534
|
+ value /= 24;
|
|
535
|
+ value++;
|
|
536
|
+ }
|
|
537
|
+ if(!mod)
|
|
538
|
+ {
|
|
539
|
+ break;
|
|
540
|
+ }
|
|
541
|
+ }
|
|
542
|
+ case 'd':
|
|
543
|
+ if(mod || *(unit+1) == '\0' || !strcmp(unit, "day"))
|
|
544
|
+ {
|
|
545
|
+ mod = 0;
|
|
546
|
+ tm->tm_mday -= value;
|
|
547
|
+ if(tm->tm_mday < 0)
|
|
548
|
+ {
|
|
549
|
+ mod = 1;
|
|
550
|
+ value = abs(tm->tm_mday);
|
|
551
|
+ tm->tm_mday = 31 - (value % 31);
|
|
552
|
+ value /= 31;
|
|
553
|
+ value++;
|
|
554
|
+ }
|
|
555
|
+ if(!mod)
|
|
556
|
+ {
|
|
557
|
+ break;
|
|
558
|
+ }
|
|
559
|
+ }
|
|
560
|
+ case 'M':
|
|
561
|
+ if(*(unit+1) == '\0' || !strcmp(unit, "Month"))
|
|
562
|
+ {
|
|
563
|
+ mod = 0;
|
|
564
|
+ tm->tm_mon -= value;
|
|
565
|
+ if(tm->tm_mon < 0)
|
|
566
|
+ {
|
|
567
|
+ mod = 1;
|
|
568
|
+ value = abs(tm->tm_mon);
|
|
569
|
+ tm->tm_mon = 12 - (value % 12);
|
|
570
|
+ value /= 12;
|
|
571
|
+ value++;
|
|
572
|
+ }
|
|
573
|
+ if(!mod)
|
|
574
|
+ {
|
|
575
|
+ break;
|
|
576
|
+ }
|
|
577
|
+ }
|
|
578
|
+ case 'y':
|
|
579
|
+ if(mod || *(unit+1) == '\0' || !strcmp(unit, "year"))
|
|
580
|
+ {
|
|
581
|
+ tm->tm_year -= value;
|
|
582
|
+ break;
|
|
583
|
+ }
|
|
584
|
+ default:
|
|
585
|
+ fprintf(stderr,"Invalid relative date '%s'\n", date);
|
|
586
|
+ return -1;
|
|
587
|
+ }
|
|
588
|
+ return 0;
|
|
589
|
+
|
|
590
|
+}
|
|
591
|
+
|
|
592
|
+int _ttail_norm_dates(ttail_t* ttail)
|
|
593
|
+{
|
|
594
|
+ struct tm *tm_p, tm;
|
|
595
|
+ /* Huge buffer but no way to make a difference between error and
|
|
596
|
+ buffer too small using strftime */
|
|
597
|
+ char date[4096], *endp;
|
|
598
|
+ size_t date_len;
|
|
599
|
+ time_t now;
|
|
600
|
+
|
|
601
|
+ if(time(&now) < 0)
|
|
602
|
+ {
|
|
603
|
+ perror("Unable to retrieve time using time()\n");
|
|
604
|
+ return -1;
|
|
605
|
+ }
|
|
606
|
+ if(!(tm_p = localtime(&now)))
|
|
607
|
+ {
|
|
608
|
+ perror("Unable to retrieve localtime using localtime()\n");
|
|
609
|
+ return -1;
|
|
610
|
+ }
|
|
611
|
+ if(!(date_len = strftime(date, sizeof(date), ttail->fmt, tm_p)))
|
|
612
|
+ {
|
|
613
|
+ fprintf(stderr, "Unable to print the current date using strftime()\n");
|
|
614
|
+ return -1;
|
|
615
|
+ }
|
|
616
|
+ ttail_tm_init(&tm);
|
|
617
|
+ endp = strptime(date, ttail->fmt, &tm);
|
|
618
|
+ if(!endp || *endp != '\0')
|
|
619
|
+ {
|
|
620
|
+ fprintf(stderr, "An error occured, unable to strptime() a date\
|
|
621
|
+we just strftime() !\n");
|
|
622
|
+ exit(EXIT_FAILURE);
|
|
623
|
+ }
|
|
624
|
+
|
|
625
|
+ TTAIL_NORMDATE(ttail, &tm, tm_sec);
|
|
626
|
+ TTAIL_NORMDATE(ttail, &tm, tm_min);
|
|
627
|
+ TTAIL_NORMDATE(ttail, &tm, tm_hour);
|
|
628
|
+ TTAIL_NORMDATE(ttail, &tm, tm_mday);
|
|
629
|
+ TTAIL_NORMDATE(ttail, &tm, tm_mon);
|
|
630
|
+ TTAIL_NORMDATE(ttail, &tm, tm_year);
|
|
631
|
+
|
|
632
|
+ return 0;
|
|
633
|
+}
|
|
634
|
+
|
439
|
635
|
int ttail_format_guess(ttail_t* t, const char* date_str, struct tm* tm)
|
440
|
636
|
{
|
441
|
637
|
int i, res;
|