tin  2.4.5
About: TIN is a threaded NNTP and spool based UseNet newsreader.
  Fossies Dox: tin-2.4.5.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

search.c
Go to the documentation of this file.
1 /*
2  * Project : tin - a Usenet reader
3  * Module : search.c
4  * Author : I. Lea & R. Skrenta
5  * Created : 1991-04-01
6  * Updated : 2020-11-18
7  * Notes :
8  *
9  * Copyright (c) 1991-2021 Iain Lea <iain@bricbrac.de>, Rich Skrenta <skrenta@pbm.com>
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright notice,
17  * this list of conditions and the following disclaimer.
18  *
19  * 2. Redistributions in binary form must reproduce the above copyright
20  * notice, this list of conditions and the following disclaimer in the
21  * documentation and/or other materials provided with the distribution.
22  *
23  * 3. Neither the name of the copyright holder nor the names of its
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 
41 #ifndef TIN_H
42 # include "tin.h"
43 #endif /* !TIN_H */
44 
45 
46 /*
47  * local prototypes
48  */
49 static char *get_search_pattern(t_bool *forward, t_bool repeat, const char *fwd_msg, const char *bwd_msg, char *def, int which_hist);
50 static int author_search(int i, char *searchbuf);
51 static int body_search(int i, char *searchbuf);
52 static int subject_search(int i, char *searchbuf);
53 static int search_group(t_bool forward, int current_art, char *searchbuff, int (*search_func) (int i, char *searchbuff));
54 
55 
56 /*
57  * Kludge to maintain some internal state for body search
58  */
59 int srch_lineno = -1;
60 static int total_cnt = 0, curr_cnt = 0;
61 
62 /*
63  * Used by article and body search - this saves passing around large numbers
64  * of parameters all the time
65  */
66 static int srch_offsets[6];
68 static struct regex_cache search_regex = { NULL, NULL };
69 
70 
71 /*
72  * Obtain the search pattern, save it in the default buffer.
73  * Return NULL if no pattern could be found
74  */
75 static char *
77  t_bool *forward,
78  t_bool repeat,
79  const char *fwd_msg,
80  const char *bwd_msg,
81  char *def,
82  int which_hist)
83 {
84  static char tmpbuf[LEN]; /* Hold the last pattern used */
85  static char last_pattern[LEN]; /* last search pattern used; for repeated search */
86  static t_bool last_forward;
87 
88  if (repeat) {
89  *forward = last_forward;
90  my_strncpy(def, last_pattern, LEN);
91  } else {
92  snprintf(tmpbuf, sizeof(tmpbuf), (*forward ? fwd_msg : bwd_msg), def);
93 
94  if (!prompt_string_default(tmpbuf, def, _(txt_no_search_string), which_hist))
95  return NULL;
96 
97  last_forward = *forward;
98  my_strncpy(last_pattern, def, LEN);
99 
100  /* HIST_BODY_SEARCH doesn't exist, hence last_search is set directly in search_body() */
101  if (which_hist == HIST_AUTHOR_SEARCH)
103  else
105  }
106 
108 
109  stow_cursor();
110 
111 #ifdef HAVE_UNICODE_NORMALIZATION
112  /* normalize search pattern */
113  if (IS_LOCAL_CHARSET("UTF-8")) {
114  char *tmp;
115 
116  tmp = normalize(def);
117  my_strncpy(def, tmp, LEN);
118  free(tmp);
119  }
120 #endif /* HAVE_UNICODE_NORMALIZATION */
121 
122  if (tinrc.wildcard) { /* ie, not wildmat() */
123  strcpy(def, quote_wild_whitespace(def));
124  return def;
125  }
126 
127  /*
128  * A gross hack to simulate substrings with wildmat()
129  */
130 /* TODO: somehow use REGEX_FMT here? */
131  snprintf(tmpbuf, sizeof(tmpbuf), "*%s*", def);
132  return tmpbuf;
133 }
134 
135 
136 /*
137  * called by config.c
138  */
139 enum option_enum
141  t_bool forward,
142  t_bool repeat,
143  enum option_enum current,
144  enum option_enum last)
145 {
146  char *pattern, *buf;
147  enum option_enum n = current;
148  enum option_enum result = current;
149 
151  return result;
152 
153  if (tinrc.wildcard && !(compile_regex(pattern, &search_regex, PCRE_CASELESS)))
154  return result;
155 
156  do {
157  if (n == 0 && !forward)
158  n = last;
159  else {
160  if (n == last && forward)
161  n = 0;
162  else
163  n += (forward ? 1 : -1);
164  }
165  /* search only visible options */
166  if (option_is_visible(n)) {
167 #ifdef HAVE_UNICODE_NORMALIZATION
168  if (IS_LOCAL_CHARSET("UTF-8"))
169  buf = normalize(_(option_table[n].txt->opt));
170  else
171 #endif /* HAVE_UNICODE_NORMALIZATION */
172  buf = my_strdup(_(option_table[n].txt->opt));
173 
174  if (match_regex(buf, pattern, &search_regex, TRUE)) {
175  result = n;
176  free(buf);
177  break;
178  }
179  free(buf);
180  }
181  } while (n != current);
182 
183  clear_message();
184  if (tinrc.wildcard) {
187  }
188  return result;
189 }
190 
191 
192 /*
193  * called by save.c (search for attachment) and page.c (search for URL)
194  */
195 int
197  t_bool forward,
198  t_bool repeat,
199  int current,
200  int last,
201  int level)
202 {
203  char *pattern;
204  char buf[BUFSIZ];
205  const char *name, *charset;
206  int n = current;
207  int result = current;
208  t_bool found = FALSE;
209  t_part *part;
210  t_url *urlptr;
211 
213  return result;
214 
215  if (tinrc.wildcard && !(compile_regex(pattern, &search_regex, PCRE_CASELESS)))
216  return result;
217 
218  do {
219  if (n == 0 && !forward)
220  n = last;
221  else {
222  if (n == last && forward)
223  n = 0;
224  else
225  n += (forward ? 1 : -1);
226  }
227  switch (level) {
228  case ATTACHMENT_LEVEL:
229  part = get_part(n);
230  if (!(name = get_filename(part->params))) {
231  if (!(name = part->description))
233  }
234  charset = get_param(part->params, "charset");
235  snprintf(buf, sizeof(buf), "%s %s/%s %s, %s", name, content_types[part->type], part->subtype, content_encodings[part->encoding], charset ? charset : "");
236  break;
237 
238  case URL_LEVEL:
239  urlptr = find_url(n);
240  snprintf(buf, sizeof(buf), "%s", urlptr->url);
241  break;
242 
243  default:
244  buf[0] = '\0';
245  break;
246  }
247  if (match_regex(buf, pattern, &search_regex, TRUE)) {
248  result = n;
249  found = TRUE;
250  break;
251  }
252  } while (n != current);
253 
254  clear_message();
255  if (tinrc.wildcard) {
258  }
259  if (!found)
261 
262  return result;
263 }
264 
265 
266 /*
267  * Search active[] looking for a groupname
268  * Called by select.c
269  * Return index into active of matching groupname or -1
270  */
271 int
273  t_bool forward,
274  t_bool repeat)
275 {
276  char *buf;
277  char *ptr;
278  char buf2[LEN];
279  int i;
280 
281  if (!selmenu.max) {
283  return -1;
284  }
285 
287  return -1;
288 
290  return -1;
291 
292  i = selmenu.curr;
293 
294  do {
295  if (forward) {
296  if (++i >= selmenu.max)
297  i = 0;
298  } else {
299  if (--i < 0)
300  i = selmenu.max - 1;
301  }
302 
303  /*
304  * Get the group name & description into buf2
305  */
306  if (show_description && active[my_group[i]].description) {
307  snprintf(buf2, sizeof(buf2), "%s %s", active[my_group[i]].name, active[my_group[i]].description);
308  ptr = buf2;
309  } else
310  ptr = active[my_group[i]].name;
311 
312  if (match_regex(ptr, buf, &search_regex, TRUE)) {
313  if (tinrc.wildcard) {
316  }
317  return i;
318  }
319  } while (i != selmenu.curr);
320 
321  if (tinrc.wildcard) {
324  }
326  return -1;
327 }
328 
329 
330 /*
331  * Scan the body of an arts[i] for searchbuf
332  * used only by search_body()
333  * Returns: 1 String found
334  * 0 Not found
335  * -1 User aborted search
336  */
337 static int
339  int i,
340  char *searchbuf)
341 {
342  static char msg[LEN]; /* show_progress needs a constant message buffer */
343  char *line, *tmp;
344  t_openartinfo artinfo;
345 
346  switch (art_open(TRUE, &arts[i], curr_group, &artinfo, FALSE, NULL)) {
347  case ART_ABORT: /* User 'q'uit */
348  art_close(&artinfo);
349  return -1;
350 
351  case ART_UNAVAILABLE: /* Treat as string not present */
352  art_close(&artinfo);
354  return 0;
355  }
356 
357  /*
358  * Skip the header - is this right ?
359  */
360  for (i = 0; artinfo.cookl[i].flags & C_HEADER; ++i)
361  ;
362  if (fseek(artinfo.cooked, artinfo.cookl[i].offset, SEEK_SET) != 0) {
363  art_close(&artinfo);
364  return -1;
365  }
366 
367  /*
368  * Now search the body
369  */
370  snprintf(msg, sizeof(msg), _(txt_searching_body), ++curr_cnt, total_cnt);
372  while ((tmp = tin_fgets(artinfo.cooked, FALSE)) != NULL) {
373 #ifdef HAVE_UNICODE_NORMALIZATION
374  if (IS_LOCAL_CHARSET("UTF-8"))
375  line = normalize(tmp);
376  else
377 #endif /* HAVE_UNICODE_NORMALIZATION */
378  line = my_strdup(tmp);
379 
380  if (tinrc.wildcard) {
382  srch_lineno = i;
383  art_close(&pgart); /* Switch the pager over to matched art */
384  pgart = artinfo;
385 #ifdef DEBUG
386  if (debug & DEBUG_MISC)
387  fprintf(stderr, "art_switch(%p = %p)\n", (void *) &pgart, (void *) &artinfo);
388 #endif /* DEBUG */
389  free(line);
390 
391  return 1;
392  }
393  } else {
394  if (wildmatpos(line, searchbuf, TRUE, srch_offsets, srch_offsets_size) == 1) {
395  srch_lineno = i;
396  art_close(&pgart); /* Switch the pager over to matched art */
397  pgart = artinfo;
398  free(line);
399  return 1;
400  }
401  }
402  i++;
403  free(line);
404  }
405 
406  if (tin_errno != 0) { /* User abort */
407  art_close(&artinfo);
408  return -1;
409  }
410 
411  art_close(&artinfo);
412 /* info_message(_(txt_no_match)); */
413  return 0;
414 }
415 
416 
417 /*
418  * Match searchbuff against the From: information in arts[i]
419  * 1 = found, 0 = not found
420  */
421 static int
423  int i,
424  char *searchbuf)
425 {
426  char *buf, *tmp;
427 
428  if (arts[i].name == NULL)
429  tmp = my_strdup(arts[i].from);
430  else {
431  size_t len = strlen(arts[i].from) + strlen(arts[i].name) + 4;
432 
433  tmp = my_malloc(len);
434  snprintf(tmp, len, "%s <%s>", arts[i].name, arts[i].from);
435  }
436 
437 #ifdef HAVE_UNICODE_NORMALIZATION
438  if (IS_LOCAL_CHARSET("UTF-8")) {
439  buf = normalize(tmp);
440  free(tmp);
441  } else
442 #endif /* HAVE_UNICODE_NORMALIZATION */
443  buf = tmp;
444 
445  if (match_regex(buf, searchbuf, &search_regex, TRUE)) {
446  free(buf);
447  return 1;
448  }
449 
450  free(buf);
451  return 0;
452 }
453 
454 
455 /*
456  * Match searchbuff against the Subject: information in arts[i]
457  * 1 = found, 0 = not found
458  */
459 static int
461  int i,
462  char *searchbuf)
463 {
464  char *buf;
465 
466 #ifdef HAVE_UNICODE_NORMALIZATION
467  if (IS_LOCAL_CHARSET("UTF-8"))
468  buf = normalize(arts[i].subject);
469  else
470 #endif /* HAVE_UNICODE_NORMALIZATION */
471  buf = my_strdup(arts[i].subject);
472 
473  if (match_regex(buf, searchbuf, &search_regex, TRUE)) {
474  free(buf);
475  return 1;
476  }
477 
478  free(buf);
479  return 0;
480 }
481 
482 
483 /*
484  * Returns index into arts[] of matching article or -1
485  */
486 static int
488  t_bool forward,
489  int current_art,
490  char *searchbuff,
491  int (*search_func) (int i, char *searchbuff))
492 {
493  int i, ret, loop_cnt;
494 
495  if (grpmenu.curr < 0) {
497  return -1;
498  }
499 
500  /*
501  * precompile if we're using full regex
502  */
503  if (tinrc.wildcard && !(compile_regex(searchbuff, &search_regex, PCRE_CASELESS)))
504  return -1;
505 
506  i = current_art;
507  loop_cnt = 1;
508 
509  do {
510  if (forward) {
511  if ((i = next_response(i)) < 0)
512  i = base[0];
513  } else {
514  if ((i = prev_response(i)) < 0)
516  }
517 
518  /* Only search displayed articles */
520  continue;
521 
522  ret = search_func(i, searchbuff);
523  if (tinrc.wildcard && (ret == 1 || ret == -1)) {
524  /* we will exit soon, clean up */
527  }
528  switch (ret) {
529  case 1: /* Found */
530  clear_message();
531  return i;
532 
533  case -1: /* User abort */
534  return -1;
535  }
536 #ifdef HAVE_SELECT
537  if (wait_for_input()) /* allow abort */
538  return -1;
539 #endif /* HAVE_SELECT */
540  if (loop_cnt % (MODULO_COUNT_NUM * 20) == 0)
541  show_progress(txt_searching, loop_cnt, top_art);
542  } while (i != current_art && loop_cnt++ <= top_art);
543 
544  if (tinrc.wildcard) {
547  }
549  return -1;
550 }
551 
552 
553 /*
554  * Generic entry point to search for fields in arts[]
555  * Returns index into arts[] of matching article or -1
556  */
557 int
560  int current_art,
561  t_bool repeat)
562 {
563  char *buf = NULL;
564  int (*search_func) (int i, char *searchbuff) = author_search;
565  t_bool forward;
566 
568  forward = TRUE;
569  else
570  forward = FALSE;
571 
572  switch (func) {
576  return -1;
577  search_func = subject_search;
578  break;
579 
582  default:
584  return -1;
585  search_func = author_search;
586  break;
587  }
588  return (search_group(forward, current_art, buf, search_func));
589 }
590 
591 
592 /*
593  * page.c (search current article body)
594  * Return line number that matches or -1
595  * If using regex's return vector of character offsets
596  */
597 int
599  t_bool forward,
600  t_bool repeat,
601  int start_line,
602  int lines,
603  t_lineinfo *line,
605  FILE *fp)
606 {
607  char *pattern, *ptr, *tmp;
608  int i = start_line;
609  int tmp_srch_offsets[2] = {0, 0};
610  t_bool wrap = FALSE;
611  t_bool match = FALSE;
612 
614  return 0;
615 
616  if (tinrc.wildcard && !(compile_regex(pattern, &search_regex, PCRE_CASELESS)))
617  return -1;
618 
619  srch_lineno = -1;
620 
621  forever {
622  if (i == start_line && wrap)
623  break;
624 
625  /*
626  * TODO: consider not searching some line types?
627  * 'B'ody search skips hdrs, '/' inside article does not.
628  */
629  if (fseek(fp, line[i].offset, SEEK_SET) != 0)
630  return -1;
631 
632  /* Don't search beyond ^L if hiding is enabled */
633  if ((line[i].flags & C_CTRLL) && i > reveal_ctrl_l_lines)
634  break;
635 
636  if ((tmp = tin_fgets(fp, FALSE)) == NULL)
637  return -1;
638  if (!forward && srch_offsets[0] >= 0) {
639  tmp[srch_offsets[0]] = '\0'; /* ignore anything on this line after the last match */
640  srch_offsets[1] = 0; /* start backwards search at the beginning of the line */
641  }
642 
643 #ifdef HAVE_UNICODE_NORMALIZATION
644  if (IS_LOCAL_CHARSET("UTF-8"))
645  ptr = normalize(tmp);
646  else
647 #endif /* HAVE_UNICODE_NORMALIZATION */
648  ptr = my_strdup(tmp);
649 
650  if (tinrc.wildcard) {
652  match = TRUE;
653  if (forward)
654  break;
655  else {
656  tmp_srch_offsets[0] = srch_offsets[0];
657  tmp_srch_offsets[1] = srch_offsets[1];
658  }
659  }
660  if (match) {
661  if (!forward) {
662  srch_offsets[0] = tmp_srch_offsets[0];
663  srch_offsets[1] = tmp_srch_offsets[1];
664  }
665  srch_lineno = i;
668  free(ptr);
669  return i;
670  }
671  } else {
672  if (wildmatpos(ptr, pattern, TRUE, srch_offsets, srch_offsets_size)) {
673  srch_lineno = i;
674  free(ptr);
675  return i;
676  }
677  }
678  free(ptr);
679 
680  if (forward) {
681  if (i >= lines - 1) {
682  i = 0;
683  wrap = TRUE;
684  } else
685  i++;
686  } else {
687  if (i <= 0) {
688  i = lines - 1;
689  wrap = TRUE;
690  } else
691  i--;
692  }
693 
694  /* search at the beginning of the line */
695  srch_offsets[1] = 0;
696  }
697 
699  if (tinrc.wildcard) {
702  }
703  return -1;
704 }
705 
706 
707 /*
708  * Search the bodies of all the articles in current group
709  * Start the search at the current article
710  * A match will replace the context of the article open in the pager
711  * Save the line # that matched (and the start/end vector for regex)
712  * for later retrieval
713  * Return index in arts[] of article that matched or -1
714  */
715 int
717  struct t_group *group,
718  int current_art,
719  t_bool repeat)
720 {
721  char *buf;
722  int i;
723  t_bool forward_fake = TRUE;
724 
725  if (!(buf = get_search_pattern(
726  &forward_fake, /* we pass a dummy var since body search has no `forward' */
727  repeat,
732  ))) return -1;
733 
734  last_search = GLOBAL_SEARCH_BODY; /* store last search type for repeated search */
735  total_cnt = curr_cnt = 0; /* Reset global counter of articles done */
736 
737  /*
738  * Count up the articles to be processed for the progress meter
739  */
740  if (group->attribute->show_only_unread_arts) {
741  for (i = 0; i < grpmenu.max; i++)
742  total_cnt += new_responses(i);
743  } else {
744  for_each_art(i) {
745  if (!IGNORE_ART(i))
746  total_cnt++;
747  }
748  }
749 
750  srch_lineno = -1;
751  return search_group(1, current_art, buf, body_search);
752 }
753 
754 
755 /*
756  * Return the saved line & start/end info from previous successful
757  * regex search
758  */
759 int
761  int *start,
762  int *end)
763 {
764  int i = srch_lineno;
765 
766  *start = srch_offsets[0];
767  *end = srch_offsets[1];
768  srch_lineno = -1; /* We can only retrieve this info once */
769  return i;
770 }
771 
772 
773 /*
774  * Reset offsets so that the next search starts at the beginning of the line.
775  * This function is needed to access srch_offsets from within other modules.
776  */
777 void
779  void)
780 {
781  srch_offsets[0] = srch_offsets[1] = 0;
782 }
unsigned t_bool
Definition: bool.h:77
#define TRUE
Definition: bool.h:74
#define FALSE
Definition: bool.h:70
#define DEBUG_MISC
Definition: debug.h:54
@ HIST_GROUP_SEARCH
Definition: extern.h:1542
@ HIST_AUTHOR_SEARCH
Definition: extern.h:1540
@ HIST_ART_SEARCH
Definition: extern.h:1539
@ HIST_CONFIG_SEARCH
Definition: extern.h:1555
@ HIST_SUBJECT_SEARCH
Definition: extern.h:1554
t_function last_search
Definition: init.c:117
struct t_option option_table[]
int * my_group
Definition: memory.c:64
constext txt_no_groups[]
Definition: lang.c:675
t_bool show_description
Definition: init.c:152
t_openartinfo pgart
Definition: page.c:63
constext txt_searching_body[]
Definition: lang.c:835
t_menu grpmenu
Definition: group.c:83
int tin_errno
Definition: read.c:59
t_menu selmenu
Definition: select.c:85
struct t_article * arts
Definition: memory.c:69
constext txt_no_search_string[]
Definition: lang.c:690
constext txt_attachment_no_name[]
Definition: lang.c:86
constext txt_search_backwards[]
Definition: lang.c:831
constext * content_encodings[]
Definition: lang.c:1448
constext txt_author_search_forwards[]
Definition: lang.c:105
constext txt_no_arts[]
Definition: lang.c:669
constext txt_searching[]
Definition: lang.c:834
t_artnum * base
Definition: memory.c:65
constext txt_search_body[]
Definition: lang.c:832
constext * content_types[]
Definition: lang.c:1453
int top_art
Definition: art.c:60
struct t_group * curr_group
Definition: group.c:55
struct t_config tinrc
Definition: init.c:191
unsigned short debug
Definition: debug.c:51
constext txt_author_search_backwards[]
Definition: lang.c:104
constext txt_no_match[]
Definition: lang.c:680
struct t_group * active
Definition: memory.c:66
constext txt_search_forwards[]
Definition: lang.c:833
@ GLOBAL_SEARCH_SUBJECT_FORWARD
Definition: keymap.h:220
@ GLOBAL_SEARCH_SUBJECT_BACKWARD
Definition: keymap.h:219
@ GLOBAL_SEARCH_AUTHOR_BACKWARD
Definition: keymap.h:217
@ GLOBAL_SEARCH_AUTHOR_FORWARD
Definition: keymap.h:218
@ GLOBAL_SEARCH_BODY
Definition: keymap.h:215
enum defined_functions t_function
Definition: keymap.h:374
static char buf[16]
Definition: langinfo.c:50
static int reveal_ctrl_l_lines
Definition: page.c:82
#define PCRE_CASELESS
Definition: pcre.h:98
#define PCRE_ERROR_NOMATCH
Definition: pcre.h:125
int pcre_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int)
Definition: pcre_exec.c:3690
static char * end
Definition: plp_snprintf.c:205
char * prompt_string_default(const char *prompt, char *def, const char *failtext, int history)
Definition: prompt.c:558
int num_of_responses(int n)
Definition: thread.c:1072
t_bool wildmatpos(const char *text, char *p, t_bool icase, int *srch_offsets, int srch_offsets_size)
Definition: wildmat.c:164
char * my_strdup(const char *str)
Definition: string.c:139
void info_message(const char *fmt,...)
Definition: screen.c:102
char * quote_wild_whitespace(char *str)
Definition: misc.c:2368
t_bool match_regex(const char *string, char *pattern, struct regex_cache *cache, t_bool icase)
Definition: regex.c:59
int new_responses(int thread)
Definition: thread.c:993
int prev_response(int n)
Definition: thread.c:1269
void art_close(t_openartinfo *artinfo)
Definition: rfc2046.c:1615
int find_response(int i, int n)
Definition: thread.c:1290
void clear_message(void)
Definition: screen.c:243
int next_response(int n)
Definition: thread.c:1228
char * tin_fgets(FILE *fp, t_bool header)
Definition: read.c:317
void wait_message(unsigned int sdelay, const char *fmt,...)
Definition: screen.c:133
void my_strncpy(char *p, const char *q, size_t n)
Definition: string.c:196
void stow_cursor(void)
Definition: screen.c:59
int art_open(t_bool wrap_lines, struct t_article *art, struct t_group *group, t_openartinfo *artinfo, t_bool show_progress_meter, const char *pmesg)
Definition: rfc2046.c:1558
t_bool compile_regex(const char *regex, struct regex_cache *cache, int options)
Definition: regex.c:111
t_url * find_url(int n)
Definition: page.c:2539
t_part * get_part(int n)
Definition: save.c:1996
const char * get_param(t_param *list, const char *name)
Definition: rfc2046.c:568
t_bool option_is_visible(enum option_enum option)
Definition: options_menu.c:187
const char * get_filename(t_param *ptr)
Definition: cook.c:353
void show_progress(const char *txt, t_artnum count, t_artnum total)
Definition: screen.c:489
static int offset
Definition: read.c:62
#define C_CTRLL
Definition: rfc2046.h:166
#define C_HEADER
Definition: rfc2046.h:152
match
Definition: save.c:1384
static int subject_search(int i, char *searchbuf)
Definition: search.c:460
static int srch_offsets_size
Definition: search.c:67
static char * get_search_pattern(t_bool *forward, t_bool repeat, const char *fwd_msg, const char *bwd_msg, char *def, int which_hist)
Definition: search.c:76
static int author_search(int i, char *searchbuf)
Definition: search.c:422
static int curr_cnt
Definition: search.c:60
int search_active(t_bool forward, t_bool repeat)
Definition: search.c:272
void reset_srch_offsets(void)
Definition: search.c:778
int srch_lineno
Definition: search.c:59
int search_article(t_bool forward, t_bool repeat, int start_line, int lines, t_lineinfo *line, int reveal_ctrl_l_lines, FILE *fp)
Definition: search.c:598
int get_search_vectors(int *start, int *end)
Definition: search.c:760
enum option_enum search_config(t_bool forward, t_bool repeat, enum option_enum current, enum option_enum last)
Definition: search.c:140
int generic_search(t_bool forward, t_bool repeat, int current, int last, int level)
Definition: search.c:196
int search_body(struct t_group *group, int current_art, t_bool repeat)
Definition: search.c:716
static int body_search(int i, char *searchbuf)
Definition: search.c:338
static int search_group(t_bool forward, int current_art, char *searchbuff, int(*search_func)(int i, char *searchbuff))
Definition: search.c:487
int search(t_function func, int current_art, t_bool repeat)
Definition: search.c:558
static int srch_offsets[6]
Definition: search.c:66
static int total_cnt
Definition: search.c:60
static struct regex_cache search_regex
Definition: search.c:68
void(* func)(SIG_ARGS)
Definition: signal.c:176
const char * name
Definition: signal.c:117
int flags
Definition: rfc2046.h:176
long offset
Definition: rfc2046.h:175
t_lineinfo * cookl
Definition: rfc2046.h:191
FILE * cooked
Definition: rfc2046.h:189
Definition: rfc2046.h:93
unsigned type
Definition: rfc2046.h:94
char * subtype
Definition: rfc2046.h:100
char * description
Definition: rfc2046.h:101
t_param * params
Definition: rfc2046.h:102
unsigned encoding
Definition: rfc2046.h:95
pcre_extra * extra
Definition: tin.h:1930
pcre * re
Definition: tin.h:1929
unsigned int status
Definition: tin.h:1539
unsigned show_only_unread_arts
Definition: tin.h:1638
char default_search_subject[LEN]
Definition: tinrc.h:90
char default_search_author[HEADER_LEN]
Definition: tinrc.h:87
char default_search_art[LEN]
Definition: tinrc.h:86
char default_search_group[HEADER_LEN]
Definition: tinrc.h:89
int wildcard
Definition: tinrc.h:155
char default_search_config[LEN]
Definition: tinrc.h:88
Definition: tin.h:1783
struct t_attribute * attribute
Definition: tin.h:1801
char * name
Definition: tin.h:1784
int curr
Definition: tin.h:2017
int max
Definition: tin.h:2018
Definition: tin.h:2073
char * url
Definition: tin.h:2074
#define LEN
Definition: tin.h:857
#define SEEK_SET
Definition: tin.h:2456
#define URL_LEVEL
Definition: tin.h:1113
#define IS_LOCAL_CHARSET(c)
Definition: tin.h:779
#define MODULO_COUNT_NUM
Definition: tin.h:865
#define for_each_art(x)
Definition: tin.h:2222
#define IGNORE_ART(i)
Definition: tin.h:1021
#define my_malloc(size)
Definition: tin.h:2207
#define ARRAY_SIZE(array)
Definition: tin.h:2212
#define ART_ABORT
Definition: tin.h:1338
#define ATTACHMENT_LEVEL
Definition: tin.h:1112
#define _(Text)
Definition: tin.h:94
#define forever
Definition: tin.h:813
#define snprintf
Definition: tin.h:2432
#define FreeAndNull(p)
Definition: tin.h:2215
#define ART_UNREAD
Definition: tin.h:1324
#define ART_UNAVAILABLE
Definition: tin.h:1326