/*
* Copyright 2017 Yann Weber
*
* This file is part of Ttail.
*
* Ttail is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Ttail is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Ttail. If not, see .
*/
#include "ttail_search_std.h"
int TTAIL_STDIN_FD = 0;
FILE *TTAIL_STDIN = NULL;
int ttail_search_std_init(ttail_t* t)
{
if(!TTAIL_STDIN_FD)
{
TTAIL_STDIN = stdin;
}
else
{
TTAIL_STDIN = fdopen(TTAIL_STDIN_FD, "r");
if(!TTAIL_STDIN)
{
perror("Fail to open stdin");
return -1;
}
}
t->session = (ttail_search_t*)malloc(sizeof(ttail_search_stdin_t));
if(!t->session)
{
perror("Unable to allocate memory for search session");
return -1;
}
t->session->std.buff = NULL;
t->session->std.buff_sz = 0;
if(_ttail_search_std_fmt_init(t) < 0)
{
return -1;
}
return 0;
}
int _ttail_search_std_fmt_init(ttail_t* t)
{
ssize_t rd_sz;
const char *buff;
int fmt_id, max_lines, i;
const char *fmt[] = TTAIL_DEFAULT_FORMATS;
if(t->flag & TTAIL_FLAG_FORMAT)
{
return 1;
}
max_lines = 10;
for(i=0; iverbose > 0)
{
fprintf(stderr, " : '%s'",
ttail_std_getline_buff(t));
}
fprintf(stderr, "\n");
return -1;
}
fmt_id = ttail_format_guess(buff, NULL);
if(fmt_id >= 0)
{
break;
}
if(!ttail_permissive(t))
{
ttail_strict_msg();
break;
}
}
if(fmt_id < 0)
{
fprintf(stderr, "Unable to detect date format from stdin\
after %d lines were readed\n", max_lines);
return -1;
}
buff = fmt[fmt_id];
t->fmt = malloc(sizeof(char) * (strlen(buff)+1));
if(!t->fmt)
{
perror("Unable to allocate memory for date format");
return -1;
}
strcpy(t->fmt, buff);
t->flag |= TTAIL_FLAG_FORMAT;
return 0;
}
int _ttail_search_closest_stdin(ttail_t* t)
{
struct tm tm;
ssize_t rd_sz;
int ret, tmp;
if(!(t->flag & TTAIL_FLAG_DATE_MIN))
{
return 0;
}
if(! t->session->std.buff)
{
if((rd_sz = ttail_std_getline(t)) < 0)
{
perror("Unable to read stdin");
return -1;
}
}
else
{
/*first line allready in the buffer thank's to format
*detection*/
rd_sz = strlen(ttail_std_getline_buff(t)) + 1;
}
while(rd_sz > 0)
{
ttail_tm_init(&tm);
ret = ttail_logline2date(t, ttail_std_getline_buff(t), &tm);
if(ret < 0)
{
return -1;
}
else if(ret > 0)
{
if(!ttail_permissive(t))
{
fprintf(stderr,
"Unable to find the %s in logline",
ret==1?"prefix":"date");
if(t->verbose > 0)
{
fprintf(stderr, " : '%s'\n",
ttail_file_getline_buf(t));
}
else
{
fprintf(stderr, "\n");
}
ttail_strict_msg();
return -1;
}
rd_sz = ttail_std_getline(t);
continue;
}
ret = ttail_tm_cmp(&tm, &(t->date_min));
if(ret >= 0)
{
//buffer contains the first line to print
return 0;
}
rd_sz = ttail_std_getline(t);
}
if(rd_sz < 0)
{
tmp = errno;
ret = feof(TTAIL_STDIN);
if(ret <= 0)
{
errno = tmp;
perror("Error while reading loglines from stdin");
return -1;
}
}
return 1;
}
void _ttail_search_print_stdin(ttail_t* t, int fd)
{
struct tm tm;
ssize_t rd_sz;
int ret, tmp;
rd_sz = strlen(ttail_std_getline_buff(t));
if(!(t->flag & TTAIL_FLAG_DATE_MAX))
{
do
{
ret = write(1, ttail_std_getline_buff(t),
sizeof(char)*rd_sz);
if(ret < 0)
{
perror("Unable to write to stdout");
return;
}
}
while((rd_sz = ttail_std_getline(t)) > 0);
}
else
{
do
{
ttail_tm_init(&tm);
ret = ttail_logline2date(t, ttail_std_getline_buff(t),
&tm);
//dropping errors
if(ret == 0)
{
ret = ttail_tm_cmp(&tm, &(t->date_max));
if(ret > 0)
{
return;
}
}
ret = write(1, ttail_std_getline_buff(t),
sizeof(char)*rd_sz);
if(ret < 0)
{
perror("Unable to write to stdout");
return;
}
}
while((rd_sz = ttail_std_getline(t)) > 0);
}
if(rd_sz < 0)
{
tmp = errno;
ret = feof(TTAIL_STDIN);
if(ret <= 0)
{
errno = tmp;
perror("Error while reading loglines from stdin");
}
}
return;
}
void _ttail_search_stdin_free(ttail_t* t)
{
if(TTAIL_STDIN)
{
fclose(TTAIL_STDIN);
}
if(t->session->std.buff)
{
free(t->session->std.buff);
}
}
void _ttail_set_stdin(int std)
{
TTAIL_STDIN_FD = std;
TTAIL_STDIN = NULL;
}