PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/multitail-5.2.8/stripstring.c

#
C | 554 lines | 440 code | 91 blank | 23 comment | 191 complexity | 2c0ddaa4223bf3d066921e7b906bdf68 MD5 | raw file
Possible License(s): AGPL-1.0
  1. #define _LARGEFILE64_SOURCE /* required for GLIBC to enable stat64 and friends */
  2. #include <sys/types.h>
  3. #include <regex.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <ctype.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include "mt.h"
  10. #include "help.h"
  11. #include "mem.h"
  12. #include "error.h"
  13. #include "term.h"
  14. #include "utils.h"
  15. #include "selbox.h"
  16. #include "globals.h"
  17. int edit_stripper_edit_regexp(NEWWIN *win, char **old_re, mybool_t *case_insensitive)
  18. {
  19. int changed = 0;
  20. char *new_re;
  21. /* ask new reg exp */
  22. mvwprintw(win -> win, 15, 2, "Edit regular expression: ");
  23. new_re = edit_string(win, 16, 2, 58, 128, 0, *old_re, HELP_ENTER_REGEXP, -1, &search_h, case_insensitive);
  24. if (new_re)
  25. {
  26. myfree(*old_re);
  27. *old_re = new_re;
  28. changed = 1;
  29. }
  30. return changed;
  31. }
  32. int edit_stripper_edit_offsets(NEWWIN *win, int *offset_start, int *offset_end)
  33. {
  34. char *str_start = NULL, *str_end = NULL;
  35. char buffer[32] = { 0 };
  36. char linebuf[68 + 1];
  37. int changed = 0;
  38. if (*offset_start != -1)
  39. snprintf(buffer, sizeof(buffer), "%d", *offset_start);
  40. mvwprintw(win -> win, 15, 2, "Enter start offset: ");
  41. str_start = edit_string(win, 16, 2, 5, 5, 1, buffer, HELP_STRIPPER_START_OFFSET, -1, NULL, NULL);
  42. if (str_start)
  43. {
  44. if (*offset_end != -1)
  45. snprintf(buffer, sizeof(buffer), "%d", *offset_end);
  46. else
  47. buffer[0] = 0x00;
  48. mvwprintw(win -> win, 15, 2, "Enter end offset: ");
  49. memset(linebuf, ' ', sizeof(linebuf));
  50. linebuf[sizeof(linebuf) - 1] = 0x00;
  51. mvwprintw(win -> win, 16, 1, "%s", linebuf);
  52. str_end = edit_string(win, 16, 2, 5, 5, 1, buffer, HELP_STRIPPER_END_OFFSET, -1, NULL, NULL);
  53. if (str_end)
  54. {
  55. *offset_start = atoi(str_start);
  56. *offset_end = atoi(str_end);
  57. changed = 1;
  58. }
  59. }
  60. myfree(str_start);
  61. myfree(str_end);
  62. return changed;
  63. }
  64. int edit_stripper_edit_field(NEWWIN *win, char **del, int *col_nr)
  65. {
  66. int changed = 0;
  67. char *new_del = NULL;
  68. char *new_col_nr = NULL;
  69. char buffer[32] = { 0 };
  70. char linebuf[58 + 1];
  71. mvwprintw(win -> win, 15, 2, "Enter delimiter: ");
  72. new_del = edit_string(win, 16, 2, 58, 128, 0, *del, HELP_STRIPPER_DELIMITER, -1, NULL, NULL);
  73. if (new_del)
  74. {
  75. mvwprintw(win -> win, 15, 2, "Enter column number: ");
  76. memset(linebuf, ' ', sizeof(linebuf));
  77. linebuf[sizeof(linebuf) - 1] = 0x00;
  78. mvwprintw(win -> win, 16, 1, "%s", linebuf);
  79. if (*col_nr != -1)
  80. snprintf(buffer, sizeof(buffer), "%d", *col_nr);
  81. new_col_nr = edit_string(win, 16, 2, 5, 5, 1, buffer, HELP_STRIPPER_COL_NR, -1, NULL, NULL);
  82. }
  83. if (new_del != NULL && new_col_nr != NULL)
  84. {
  85. *del = mystrdup(new_del, __FILE__, __PRETTY_FUNCTION__, __LINE__);
  86. *col_nr = atoi(new_col_nr);
  87. changed = 1;
  88. }
  89. myfree(new_col_nr);
  90. myfree(new_del);
  91. return changed;
  92. }
  93. int edit_strippers(void)
  94. {
  95. int changed = 0;
  96. NEWWIN *mywin;
  97. proginfo *cur;
  98. int f_index = 0;
  99. int cur_strip = 0;
  100. mybool_t case_insensitive = re_case_insensitive;
  101. /* select window */
  102. if (nfd > 1)
  103. f_index = select_window(HELP_ENTER_STRIPPER_SELECT_WINDOW, "Select window (stripper editing)");
  104. if (f_index == -1) /* user pressed Q/X */
  105. return 0;
  106. /* select subwindow */
  107. cur = &pi[f_index];
  108. if (cur -> next)
  109. cur = select_subwindow(f_index, HELP_ENTER_STRIPPER_SELECT_SUBWINDOW, "Select subwindow (stripper editing)");
  110. if (!cur)
  111. return 0;
  112. /* create window */
  113. mywin = create_popup(23, 70);
  114. for(;;)
  115. {
  116. int c, key;
  117. int loop;
  118. char linebuf[68 + 1];
  119. werase(mywin -> win);
  120. draw_border(mywin);
  121. win_header(mywin, "Edit strip regular expressions");
  122. mvwprintw(mywin -> win, 2, 2, "%s", cur -> filename);
  123. escape_print(mywin, 3, 2, "^a^dd, ^e^dit, ^d^elete, ^q^uit");
  124. /* clear */
  125. memset(linebuf, ' ', sizeof(linebuf) - 1);
  126. linebuf[sizeof(linebuf) - 1] = 0x00;
  127. for(loop=4; loop<22; loop++)
  128. mvwprintw(mywin -> win, loop, 1, linebuf);
  129. /* display them lines */
  130. for(loop=0; loop<cur -> n_strip; loop++)
  131. {
  132. if (loop == cur_strip) ui_inverse_on(mywin);
  133. switch((cur -> pstrip)[loop].type)
  134. {
  135. case STRIP_KEEP_SUBSTR:
  136. case STRIP_TYPE_REGEXP:
  137. strncpy(linebuf, (cur -> pstrip)[loop].regex_str, 55);
  138. linebuf[55] = 0x00;
  139. mvwprintw(mywin -> win, 4 + loop, 1, "RE: %s", linebuf);
  140. break;
  141. case STRIP_TYPE_RANGE:
  142. mvwprintw(mywin -> win, 4 + loop, 1, "Range: %d - %d", (cur -> pstrip)[loop].start, (cur -> pstrip)[loop].end);
  143. break;
  144. case STRIP_TYPE_COLUMN:
  145. mvwprintw(mywin -> win, 4 + loop, 1, "Column: %d (delimiter: '%s')", (cur -> pstrip)[loop].col_nr, (cur -> pstrip)[loop].del);
  146. break;
  147. }
  148. if (loop == cur_strip) ui_inverse_off(mywin);
  149. mvwprintw(mywin -> win, 4 + loop, 60, "%d", (cur -> pstrip)[loop].match_count);
  150. }
  151. mydoupdate();
  152. /* wait for key */
  153. for(;;)
  154. {
  155. key = wait_for_keypress(HELP_REGEXP_MENU, 2, mywin, 1);
  156. c = toupper(key);
  157. /* convert return to 'E'dit */
  158. if (key == 13)
  159. key = c = 'E';
  160. /* any valid keys? */
  161. if (c == 'Q' || c == abort_key || c == 'X' || c == 'A' || c == 'E' || c == 'D' || key == KEY_DOWN || key == 13 || key == KEY_UP)
  162. break;
  163. if (key == -1) /* T/O waiting for key? then update counters */
  164. {
  165. for(loop=0; loop<cur -> n_strip; loop++)
  166. mvwprintw(mywin -> win, 4 + loop, 60, "%d", (cur -> pstrip)[loop].match_count);
  167. mydoupdate();
  168. }
  169. else
  170. wrong_key();
  171. }
  172. /* exit this screen? */
  173. if (c == 'Q' || c == abort_key || c == 'X')
  174. break;
  175. if (key == KEY_UP)
  176. {
  177. if (cur_strip > 0)
  178. cur_strip--;
  179. else
  180. wrong_key();
  181. }
  182. else if (key == KEY_DOWN || key == 13)
  183. {
  184. if (cur_strip < (cur -> n_strip -1))
  185. cur_strip++;
  186. else
  187. wrong_key();
  188. }
  189. /* add or edit */
  190. if (c == 'A')
  191. {
  192. int rc;
  193. char *regex_str = NULL;
  194. int offset_start = -1, offset_end = -1;
  195. char *del = NULL;
  196. int col_nr = -1;
  197. int c;
  198. int cur_changed = 0;
  199. /* max. 10 regular expressions */
  200. if (cur -> n_strip == 10)
  201. {
  202. wrong_key();
  203. continue;
  204. }
  205. /* ask type */
  206. escape_print(mywin, 15, 2, "reg.^e^xp., ^r^ange, ^c^olumn, ^S^ubstrings");
  207. mydoupdate();
  208. for(;;)
  209. {
  210. c = toupper(wait_for_keypress(HELP_STRIPPER_TYPE, 0, mywin, 0));
  211. if (c == 'E' || c == 'R' || c == 'C' || c == 'S' ||
  212. c == abort_key || c == 'Q' || c == 'X')
  213. break;
  214. wrong_key();
  215. }
  216. if (c == abort_key || c == 'Q' || c == 'X') continue;
  217. if (c == 'E' || c == 'S')
  218. {
  219. /* user did not abort edit? */
  220. if (edit_stripper_edit_regexp(mywin, &regex_str, &case_insensitive))
  221. cur_changed = 1;
  222. }
  223. else if (c == 'R')
  224. {
  225. if (edit_stripper_edit_offsets(mywin, &offset_start, &offset_end))
  226. cur_changed = 1;
  227. }
  228. else if (c == 'C')
  229. {
  230. if (edit_stripper_edit_field(mywin, &del, &col_nr))
  231. cur_changed = 1;
  232. }
  233. if (!cur_changed) continue;
  234. changed = 1;
  235. cur_strip = cur -> n_strip++;
  236. cur -> pstrip = (strip_t *)myrealloc(cur -> pstrip, cur -> n_strip * sizeof(strip_t), __FILE__, __PRETTY_FUNCTION__, __LINE__);
  237. memset(&(cur -> pstrip)[cur_strip], 0x00, sizeof(strip_t));
  238. /* compile */
  239. if (c == 'E' || c == 'S')
  240. {
  241. if ((rc = regcomp(&(cur -> pstrip)[cur_strip].regex, regex_str, REG_EXTENDED)))
  242. {
  243. regexp_error_popup(rc, &(cur -> pre)[cur_strip].regex);
  244. cur -> n_strip--;
  245. if (cur -> n_strip == cur_strip) cur_strip--;
  246. myfree(regex_str);
  247. }
  248. else
  249. {
  250. /* compilation went well, remember everything */
  251. (cur -> pstrip)[cur_strip].regex_str = regex_str;
  252. (cur -> pstrip)[cur_strip].type = (c == 'E' ? STRIP_TYPE_REGEXP : STRIP_KEEP_SUBSTR);
  253. }
  254. }
  255. else if (c == 'R')
  256. {
  257. (cur -> pstrip)[cur_strip].type = STRIP_TYPE_RANGE;
  258. (cur -> pstrip)[cur_strip].start = offset_start;
  259. (cur -> pstrip)[cur_strip].end = offset_end;
  260. }
  261. else if (c == 'C')
  262. {
  263. (cur -> pstrip)[cur_strip].type = STRIP_TYPE_COLUMN;
  264. (cur -> pstrip)[cur_strip].col_nr = col_nr;
  265. (cur -> pstrip)[cur_strip].del = del;
  266. }
  267. /* reset counter (as it is a different regexp which has not matched anything at all) */
  268. (cur -> pstrip)[cur_strip].match_count = 0;
  269. }
  270. /* delete entry */
  271. else if (c == 'D')
  272. {
  273. if (cur -> n_strip > 0)
  274. {
  275. changed = 1;
  276. /* delete entry */
  277. myfree((cur -> pstrip)[cur_strip].regex_str);
  278. /* update administration */
  279. if (cur -> n_strip == 1)
  280. {
  281. myfree(cur -> pstrip);
  282. cur -> pstrip = NULL;
  283. }
  284. else
  285. {
  286. int n_to_move = (cur -> n_strip - cur_strip) - 1;
  287. if (n_to_move > 0)
  288. memmove(&(cur -> pstrip)[cur_strip], &(cur -> pstrip)[cur_strip+1], sizeof(strip_t) * n_to_move);
  289. }
  290. cur -> n_strip--;
  291. /* move cursor */
  292. if (cur_strip > 0 && cur_strip == cur -> n_strip)
  293. {
  294. cur_strip--;
  295. }
  296. }
  297. else
  298. wrong_key();
  299. }
  300. else if (c == 'E')
  301. {
  302. if (cur -> n_strip > 0)
  303. {
  304. if ((cur -> pstrip)[cur_strip].type == STRIP_TYPE_REGEXP ||
  305. (cur -> pstrip)[cur_strip].type == STRIP_KEEP_SUBSTR)
  306. {
  307. if (edit_stripper_edit_regexp(mywin, &(cur -> pstrip)[cur_strip].regex_str, &case_insensitive))
  308. changed = 1;
  309. }
  310. else if ((cur -> pstrip)[cur_strip].type == STRIP_TYPE_RANGE)
  311. {
  312. if (edit_stripper_edit_offsets(mywin, &(cur -> pstrip)[cur_strip].start, &(cur -> pstrip)[cur_strip].end))
  313. changed = 1;
  314. }
  315. else if ((cur -> pstrip)[cur_strip].type == STRIP_TYPE_COLUMN)
  316. {
  317. if (edit_stripper_edit_field(mywin, &(cur -> pstrip)[cur_strip].del, &(cur -> pstrip)[cur_strip].col_nr))
  318. changed = 1;
  319. }
  320. }
  321. else
  322. wrong_key();
  323. }
  324. }
  325. delete_popup(mywin);
  326. return changed;
  327. }
  328. void zero_str(char *what, int start, int end)
  329. {
  330. memset(&what[start], 0x00, end-start);
  331. }
  332. char do_strip_re(regex_t *pre, int *match_count, char *in, char *strip_what)
  333. {
  334. char changed = 0;
  335. int search_offset = 0;
  336. regmatch_t matches[MAX_N_RE_MATCHES];
  337. do
  338. {
  339. int new_offset = -1;
  340. if (regexec(pre, &in[search_offset], MAX_N_RE_MATCHES, matches, 0) != REG_NOMATCH)
  341. {
  342. int match_i;
  343. for(match_i=0; match_i<MAX_N_RE_MATCHES; match_i++)
  344. {
  345. if (matches[match_i].rm_so == -1 ||
  346. matches[match_i].rm_eo == -1)
  347. break;
  348. zero_str(strip_what, matches[match_i].rm_so + search_offset, matches[match_i].rm_eo + search_offset);
  349. changed = 1;
  350. new_offset = matches[match_i].rm_eo + search_offset;
  351. (*match_count)++;
  352. }
  353. }
  354. search_offset = new_offset;
  355. }
  356. while (search_offset != -1);
  357. return changed;
  358. }
  359. char do_keep_re(regex_t *pre, int *match_count, char *in, char *strip_what)
  360. {
  361. char changed = 0;
  362. regmatch_t matches[MAX_N_RE_MATCHES];
  363. int last_offset = 0;
  364. if (regexec(pre, in, MAX_N_RE_MATCHES, matches, 0) != REG_NOMATCH)
  365. {
  366. int match_i;
  367. for(match_i=1; match_i<MAX_N_RE_MATCHES; match_i++)
  368. {
  369. if (matches[match_i].rm_so == -1 || matches[match_i].rm_eo == -1)
  370. break;
  371. zero_str(strip_what, last_offset, matches[match_i].rm_so);
  372. last_offset = matches[match_i].rm_eo;
  373. }
  374. if (last_offset != 0)
  375. {
  376. zero_str(strip_what, last_offset, strlen(in));
  377. }
  378. changed = 1;
  379. }
  380. return changed;
  381. }
  382. char do_strip_column(char *delimiter, int col_nr, char *in, char *strip_what)
  383. {
  384. char changed = 0;
  385. char *p = in;
  386. int del_len = strlen(delimiter);
  387. int col_i;
  388. while(strncmp(p, delimiter, del_len) == 0) p += del_len;
  389. if (!*p) return 0;
  390. for(col_i=0; col_i<col_nr; col_i++)
  391. {
  392. p = strstr(p, delimiter);
  393. if (!p) break;
  394. while(strncmp(p, delimiter, del_len) == 0) p += del_len;
  395. }
  396. if (!p) return 0;
  397. changed = 1;
  398. /* strip the column */
  399. while(strncmp(p, delimiter, del_len) != 0 && *p != 0x00)
  400. {
  401. strip_what[(int)(p - in)] = 0;
  402. p++;
  403. }
  404. /* and strip the delimiter(s) behind it */
  405. while(strncmp(p, delimiter, del_len) == 0)
  406. {
  407. int loop2;
  408. for(loop2=0; loop2<del_len; loop2++)
  409. strip_what[(int)(p - in) + loop2] = 0;
  410. p += del_len;
  411. }
  412. return changed;
  413. }
  414. char * do_strip(proginfo *cur, char *in)
  415. {
  416. int loop, len;
  417. int offset = 0;
  418. char *strip_what;
  419. char *new_string;
  420. char changed = 0;
  421. if (!in || cur -> n_strip == 0)
  422. return NULL;
  423. len = strlen(in);
  424. if (len == 0)
  425. return NULL;
  426. strip_what = (char *)mymalloc(len, __FILE__, __PRETTY_FUNCTION__, __LINE__);
  427. new_string = (char *)mymalloc(len + 1, __FILE__, __PRETTY_FUNCTION__, __LINE__);
  428. memset(strip_what, 0x01, len);
  429. for(loop=0; loop<cur -> n_strip; loop++)
  430. {
  431. if ((cur -> pstrip)[loop].type == STRIP_TYPE_RANGE)
  432. {
  433. memset(&strip_what[(cur -> pstrip)[loop].start], 0x00, (cur -> pstrip)[loop].end - (cur -> pstrip)[loop].start);
  434. changed = 1;
  435. }
  436. else if ((cur -> pstrip)[loop].type == STRIP_TYPE_REGEXP)
  437. {
  438. changed |= do_strip_re(&(cur -> pstrip)[loop].regex, &(cur -> pstrip)[loop].match_count, in, strip_what);
  439. }
  440. else if ((cur -> pstrip)[loop].type == STRIP_TYPE_COLUMN)
  441. {
  442. changed |= do_strip_column((cur -> pstrip)[loop].del, (cur -> pstrip)[loop].col_nr, in, strip_what);
  443. }
  444. else if ((cur -> pstrip)[loop].type == STRIP_KEEP_SUBSTR)
  445. {
  446. changed |= do_keep_re(&(cur -> pstrip)[loop].regex, &(cur -> pstrip)[loop].match_count, in, strip_what);
  447. }
  448. }
  449. if (changed)
  450. {
  451. for(loop=0; loop<len; loop++)
  452. {
  453. if (strip_what[loop])
  454. new_string[offset++] = in[loop];
  455. }
  456. new_string[offset] = 0x00;
  457. myfree(strip_what);
  458. return new_string;
  459. }
  460. myfree(strip_what);
  461. myfree(new_string);
  462. return NULL;
  463. }