timed tail for logfiles. Display loglines given a minimum date and/or a maximum date.
c
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ttail_search_std.c 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * Copyright 2017 Yann Weber
  3. *
  4. * This file is part of Ttail.
  5. *
  6. * Ttail 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 3 of the License, or
  9. * any later version.
  10. *
  11. * Ttail 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 Ttail. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "ttail_search_std.h"
  20. int TTAIL_STDIN_FD = 0;
  21. FILE *TTAIL_STDIN = NULL;
  22. int ttail_search_std_init(ttail_t* t)
  23. {
  24. if(!TTAIL_STDIN_FD)
  25. {
  26. TTAIL_STDIN = stdin;
  27. }
  28. else
  29. {
  30. TTAIL_STDIN = fdopen(TTAIL_STDIN_FD, "r");
  31. if(!TTAIL_STDIN)
  32. {
  33. perror("Fail to open stdin");
  34. return -1;
  35. }
  36. }
  37. t->session = (ttail_search_t*)malloc(sizeof(ttail_search_stdin_t));
  38. if(!t->session)
  39. {
  40. perror("Unable to allocate memory for search session");
  41. return -1;
  42. }
  43. t->session->std.buff = NULL;
  44. t->session->std.buff_sz = 0;
  45. if(_ttail_search_std_fmt_init(t) < 0)
  46. {
  47. return -1;
  48. }
  49. return 0;
  50. }
  51. int _ttail_search_std_fmt_init(ttail_t* t)
  52. {
  53. ssize_t rd_sz;
  54. const char *buff;
  55. int fmt_id, max_lines, i;
  56. const char *fmt[] = TTAIL_DEFAULT_FORMATS;
  57. if(t->flag & TTAIL_FLAG_FORMAT)
  58. {
  59. return 1;
  60. }
  61. max_lines = 10;
  62. for(i=0; i<max_lines; i++)
  63. {
  64. if((rd_sz = ttail_std_getline(t)) < 0)
  65. {
  66. fprintf(stderr, "Unable to detect date from stdin\n");
  67. return -1;
  68. }
  69. buff = ttail_logline_subst(t, ttail_std_getline_buff(t));
  70. if(!buff)
  71. {
  72. if(ttail_permissive(t))
  73. {
  74. continue;
  75. }
  76. fprintf(stderr, "Unable to find prefix in logline");
  77. if(t->verbose > 0)
  78. {
  79. fprintf(stderr, " : '%s'",
  80. ttail_std_getline_buff(t));
  81. }
  82. fprintf(stderr, "\n");
  83. return -1;
  84. }
  85. fmt_id = ttail_format_guess(buff, NULL);
  86. if(fmt_id >= 0)
  87. {
  88. break;
  89. }
  90. if(!ttail_permissive(t))
  91. {
  92. ttail_strict_msg();
  93. break;
  94. }
  95. }
  96. if(fmt_id < 0)
  97. {
  98. fprintf(stderr, "Unable to detect date format from stdin\
  99. after %d lines were readed\n", max_lines);
  100. return -1;
  101. }
  102. buff = fmt[fmt_id];
  103. t->fmt = malloc(sizeof(char) * (strlen(buff)+1));
  104. if(!t->fmt)
  105. {
  106. perror("Unable to allocate memory for date format");
  107. return -1;
  108. }
  109. strcpy(t->fmt, buff);
  110. t->flag |= TTAIL_FLAG_FORMAT;
  111. return 0;
  112. }
  113. int _ttail_search_closest_stdin(ttail_t* t)
  114. {
  115. struct tm tm;
  116. ssize_t rd_sz;
  117. int ret, tmp;
  118. if(!(t->flag & TTAIL_FLAG_DATE_MIN))
  119. {
  120. return 0;
  121. }
  122. if(! t->session->std.buff)
  123. {
  124. if((rd_sz = ttail_std_getline(t)) < 0)
  125. {
  126. perror("Unable to read stdin");
  127. return -1;
  128. }
  129. }
  130. else
  131. {
  132. /*first line allready in the buffer thank's to format
  133. *detection*/
  134. rd_sz = strlen(ttail_std_getline_buff(t)) + 1;
  135. }
  136. while(rd_sz > 0)
  137. {
  138. ttail_tm_init(&tm);
  139. ret = ttail_logline2date(t, ttail_std_getline_buff(t), &tm);
  140. if(ret < 0)
  141. {
  142. return -1;
  143. }
  144. else if(ret > 0)
  145. {
  146. if(!ttail_permissive(t))
  147. {
  148. fprintf(stderr,
  149. "Unable to find the %s in logline",
  150. ret==1?"prefix":"date");
  151. if(t->verbose > 0)
  152. {
  153. fprintf(stderr, " : '%s'\n",
  154. ttail_file_getline_buf(t));
  155. }
  156. else
  157. {
  158. fprintf(stderr, "\n");
  159. }
  160. ttail_strict_msg();
  161. return -1;
  162. }
  163. rd_sz = ttail_std_getline(t);
  164. continue;
  165. }
  166. ret = ttail_tm_cmp(&tm, &(t->date_min));
  167. if(ret >= 0)
  168. {
  169. //buffer contains the first line to print
  170. return 0;
  171. }
  172. rd_sz = ttail_std_getline(t);
  173. }
  174. if(rd_sz < 0)
  175. {
  176. tmp = errno;
  177. ret = feof(TTAIL_STDIN);
  178. if(ret <= 0)
  179. {
  180. errno = tmp;
  181. perror("Error while reading loglines from stdin");
  182. return -1;
  183. }
  184. }
  185. return 1;
  186. }
  187. void _ttail_search_print_stdin(ttail_t* t, int fd)
  188. {
  189. struct tm tm;
  190. ssize_t rd_sz;
  191. int ret, tmp;
  192. rd_sz = strlen(ttail_std_getline_buff(t));
  193. if(!(t->flag & TTAIL_FLAG_DATE_MAX))
  194. {
  195. do
  196. {
  197. ret = write(1, ttail_std_getline_buff(t),
  198. sizeof(char)*rd_sz);
  199. if(ret < 0)
  200. {
  201. perror("Unable to write to stdout");
  202. return;
  203. }
  204. }
  205. while((rd_sz = ttail_std_getline(t)) > 0);
  206. }
  207. else
  208. {
  209. do
  210. {
  211. ttail_tm_init(&tm);
  212. ret = ttail_logline2date(t, ttail_std_getline_buff(t),
  213. &tm);
  214. //dropping errors
  215. if(ret == 0)
  216. {
  217. ret = ttail_tm_cmp(&tm, &(t->date_max));
  218. if(ret > 0)
  219. {
  220. return;
  221. }
  222. }
  223. ret = write(1, ttail_std_getline_buff(t),
  224. sizeof(char)*rd_sz);
  225. if(ret < 0)
  226. {
  227. perror("Unable to write to stdout");
  228. return;
  229. }
  230. }
  231. while((rd_sz = ttail_std_getline(t)) > 0);
  232. }
  233. if(rd_sz < 0)
  234. {
  235. tmp = errno;
  236. ret = feof(TTAIL_STDIN);
  237. if(ret <= 0)
  238. {
  239. errno = tmp;
  240. perror("Error while reading loglines from stdin");
  241. }
  242. }
  243. return;
  244. }
  245. void _ttail_search_stdin_free(ttail_t* t)
  246. {
  247. if(TTAIL_STDIN)
  248. {
  249. fclose(TTAIL_STDIN);
  250. }
  251. if(t->session->std.buff)
  252. {
  253. free(t->session->std.buff);
  254. }
  255. }
  256. void _ttail_set_stdin(int std)
  257. {
  258. TTAIL_STDIN_FD = std;
  259. TTAIL_STDIN = NULL;
  260. }