Fix starts for #11

Adds the option -P --permissive.

Starts implementation for logfiles.

Now -P flag make ttail handle invalid files. When invalid file given the
minmax function set the file pointer and the minmax array to NULL.

May introduce bugs if the binary search function does not handles "holes"
in fp array or in minmax array...
This commit is contained in:
Yann Weber 2017-05-15 19:29:11 +02:00
commit bbaa6b84b4
5 changed files with 70 additions and 6 deletions

View file

@ -41,6 +41,8 @@ typedef struct _ttail_s ttail_t;
#define TTAIL_FLAG_FORMAT 8
#define TTAIL_FLAG_EXTENDED_RE 16
#define TTAIL_FLAG_CI_RE 32
/**! When set indicate that ttail is in permissive mode */
#define TTAIL_FLAG_PERMISSIVE 64
#define TTAIL_DEFAULT_FORMATS {"%m",\
"%A %B %d, %Y %H:%M:%S",\
@ -62,6 +64,10 @@ typedef struct _ttail_s ttail_t;
"%y-%m-%d",\
"%Y/%m/%d:%H:%M",NULL}
#define ttail_permissive(t) ( t->flag & TTAIL_FLAG_PERMISSIVE )
#define ttail_strict_msg() fprintf(stderr, "This error can be non-fatal using \
-P --permissive flag\n")
struct _ttail_s
{

View file

@ -42,10 +42,11 @@
{"date-format", required_argument, 0, 'f'},\
{"date-min", required_argument, 0, 'd'},\
{"date-max", required_argument, 0, 'm'},\
{"permissive", no_argument, 0, 'P'},\
{"help", no_argument, 0, 'h'},\
{0, 0, 0, 0 }\
}
#define TTAIL_SHORT_OPT "vr:Eip:f:d:l:m:h"
#define TTAIL_SHORT_OPT "vr:Eip:f:d:l:m:Ph"
#define TTAIL_OPT_HELP {\
{"Augment the verbosity level",NULL},\
@ -58,6 +59,7 @@ POSIX) ",NULL},\
,"FORMAT"},\
{"Start to output loglines starting from this date","DATE"},\
{"Stop to output loglines before this date","DATE"},\
{"Tell ttail to not stop on loglines not formatted as expected",NULL},\
{"Print this help and exit",NULL},\
{"",NULL}\
}

View file

@ -151,6 +151,14 @@ given\n");
strcpy(date, optarg);
dates[c=='d'?0:1] = date;
break;
case 'P':
if(res->flag & TTAIL_FLAG_PERMISSIVE)
{
fprintf(stderr, "Warning : looks like \
-P --permissive flag was set more than once\n");
}
res->flag |= TTAIL_FLAG_PERMISSIVE;
break;
default: /* ? */
goto ttail_init_err;

View file

@ -117,7 +117,7 @@ const char* ttail_logline_subst(ttail_t* t, const char* logline)
if(ret)
{
regerror(ret, &(t->date_prefix), err,1024);
fprintf(stderr, "Exec error : %s\n", err);
fprintf(stderr, "RegEx exec error : %s\n", err);
return NULL;
}
return logline + pmatch[0].rm_eo;

View file

@ -51,17 +51,21 @@ int _ttail_search_closest_files(ttail_t* t)
ret = _ttail_file_minmax(t, i, ftm[i]);
if(ret < 0)
{
fprintf(stderr, "Minmax error\n");
goto _ttail_search_closest_files_loop_err;
}
else if (ret == 1)
{
fprintf(stderr, "Warning : unable to find a valid date \
fprintf(stderr, "Error : unable to find a valid date \
in '%s'\n", t->logfile_name[i]);
free(ftm[i]);
ftm[i] = NULL;
fclose(t->logfile[i]);
t->logfile[i] = NULL;
if(!ttail_permissive(t))
{
ttail_strict_msg();
goto _ttail_search_closest_files_loop_err;
}
continue;
}
if(i && prev_found &&
@ -312,6 +316,11 @@ running binary search algorithm in '%s'\n", t->logfile_name[*id]);
}
cmpres=0;
ret = _ttail_file_cur_cmp(t, *id, in, &cmpres);
if(!ret && !ttail_permissive(t))
{
ttail_strict_msg();
return -1;
}
if((min && cmpres < 0) || (!min && cmpres > 0))
{
break;
@ -336,6 +345,10 @@ running binary search algorithm in '%s'\n", t->logfile_name[*id]);
fprintf(stderr, "No files to scan\n");
return 0;
}
if(*id == t->logfile_sz)
{
return 0;
}
/* the answer is somewhere in *id file */
*off = _ttail_file_search_from_end(t, *id, in);
return 0;
@ -606,6 +619,7 @@ inline int _ttail_file_minmax(ttail_t* t, size_t id, struct tm tm[2])
fp = t->logfile[id];
if(!fp)
{
fprintf(stderr, "File pointer is null !\n");
return 1;
}
if(fseek(fp, 0, SEEK_SET) < 0)
@ -623,6 +637,22 @@ inline int _ttail_file_minmax(ttail_t* t, size_t id, struct tm tm[2])
{
break;
}
if(!ttail_permissive(t))
{
if(t->verbose <= 0)
{
fprintf(stderr,
"Unable to find a date in logline\n");
}
else
{
fprintf(stderr,
"Unable to find a date in '%s'\n",
ttail_file_getline_buf(t));
}
ttail_strict_msg();
return -1;
}
}
if(fseek(fp, -1, SEEK_END) < 0)
{
@ -633,6 +663,8 @@ inline int _ttail_file_minmax(ttail_t* t, size_t id, struct tm tm[2])
{
if((cur = _ttail_file_start_line(t, id)) < 0)
{
fprintf(stderr, "Error will searching line starts in\
%s\n", t->logfile_name[id]);
return -1;
}
if(ttail_file_getline(t, id) < 0)
@ -647,6 +679,22 @@ inline int _ttail_file_minmax(ttail_t* t, size_t id, struct tm tm[2])
{
return 1;
}
else if(!ttail_permissive(t))
{
if(t->verbose <= 0)
{
fprintf(stderr,
"Unable to find a date in logline\n");
}
else
{
fprintf(stderr,
"Unable to find a date in '%s'\n",
ttail_file_getline_buf(t));
}
ttail_strict_msg();
return -1;
}
if(fseek(fp, cur-1, SEEK_SET) < 0)
{
perror("Unable to manipulate fp");
@ -872,11 +920,11 @@ inline int _ttail_file_cur_cmp(ttail_t* t, size_t id, const struct tm* tm ,
return -1;
}
ret = ttail_logline2date(t, ttail_file_getline_buf(t), &ctm);
if(ret)
if(ret < 0)
{
return -1;
}
else if(ret == 1)
else if(ret > 1)
{
return 1;
}