/* * 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; }