tin  2.6.1
About: TIN is a threaded NNTP and spool based UseNet newsreader.
  Fossies Dox: tin-2.6.1.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 : 2021-02-23
7 * Notes :
8 *
9 * Copyright (c) 1991-2022 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 */
49static char *get_search_pattern(t_bool *forward, t_bool repeat, const char *fwd_msg, const char *bwd_msg, char *def, int which_hist);
50static int author_search(int i, char *searchbuf);
51static int body_search(int i, char *searchbuf);
52static int subject_search(int i, char *searchbuf);
53static 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 */
59int srch_lineno = -1;
60static 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 */
66static int srch_offsets[6];
68static 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 */
75static 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 */
139enum 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 = (n + (enum option_enum) (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
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 */
195int
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 t_posted *phptr;
212
214 return result;
215
216 if (tinrc.wildcard && !(compile_regex(pattern, &search_regex, PCRE_CASELESS)))
217 return result;
218
219 do {
220 if (n == 0 && !forward)
221 n = last;
222 else {
223 if (n == last && forward)
224 n = 0;
225 else
226 n += (forward ? 1 : -1);
227 }
228 switch (level) {
229 case ATTACHMENT_LEVEL:
230 part = get_part(n);
231 if (!(name = get_filename(part->params))) {
232 if (!(name = part->description))
234 }
235 charset = get_param(part->params, "charset");
236 snprintf(buf, sizeof(buf), "%s %s/%s %s, %s", name, content_types[part->type], part->subtype, content_encodings[part->encoding], charset ? charset : "");
237 break;
238
239 case POSTED_LEVEL:
240 phptr = find_post_hist(n);
241 snprintf(buf, sizeof(buf), "%s %s %s", phptr->date, phptr->group, phptr->subj);
242 break;
243
244 case URL_LEVEL:
245 urlptr = find_url(n);
246 snprintf(buf, sizeof(buf), "%s", urlptr->url);
247 break;
248
249 default:
250 buf[0] = '\0';
251 break;
252 }
253 if (match_regex(buf, pattern, &search_regex, TRUE)) {
254 result = n;
255 found = TRUE;
256 break;
257 }
258 } while (n != current);
259
261 if (tinrc.wildcard) {
264 }
265 if (!found)
267
268 return result;
269}
270
271
272/*
273 * Search active[] looking for a groupname
274 * Called by select.c
275 * Return index into active of matching groupname or -1
276 */
277int
279 t_bool forward,
280 t_bool repeat)
281{
282 char *buf;
283 char *ptr;
284 char buf2[LEN];
285 int i;
286
287 if (!selmenu.max) {
289 return -1;
290 }
291
293 return -1;
294
295 if (tinrc.wildcard && !(compile_regex(buf, &search_regex, PCRE_CASELESS)))
296 return -1;
297
298 i = selmenu.curr;
299
300 do {
301 if (forward) {
302 if (++i >= selmenu.max)
303 i = 0;
304 } else {
305 if (--i < 0)
306 i = selmenu.max - 1;
307 }
308
309 /*
310 * Get the group name & description into buf2
311 */
312 if (show_description && active[my_group[i]].description) {
313 snprintf(buf2, sizeof(buf2), "%s %s", active[my_group[i]].name, active[my_group[i]].description);
314 ptr = buf2;
315 } else
316 ptr = active[my_group[i]].name;
317
318 if (match_regex(ptr, buf, &search_regex, TRUE)) {
319 if (tinrc.wildcard) {
322 }
323 return i;
324 }
325 } while (i != selmenu.curr);
326
327 if (tinrc.wildcard) {
330 }
332 return -1;
333}
334
335
336/*
337 * Scan the body of an arts[i] for searchbuf
338 * used only by search_body()
339 * Returns: 1 String found
340 * 0 Not found
341 * -1 User aborted search
342 */
343static int
345 int i,
346 char *searchbuf)
347{
348 static char msg[LEN]; /* show_progress needs a constant message buffer */
349 char *line, *tmp;
350 t_openartinfo artinfo;
351
352 switch (art_open(TRUE, &arts[i], curr_group, &artinfo, FALSE, NULL)) {
353 case ART_ABORT: /* User 'q'uit */
354 art_close(&artinfo);
355 return -1;
356
357 case ART_UNAVAILABLE: /* Treat as string not present */
358 art_close(&artinfo);
360 return 0;
361 }
362
363 /*
364 * Skip the header - is this right ?
365 */
366 for (i = 0; artinfo.cookl[i].flags & C_HEADER; ++i)
367 ;
368 if (fseek(artinfo.cooked, artinfo.cookl[i].offset, SEEK_SET) != 0) {
369 art_close(&artinfo);
370 return -1;
371 }
372
373 /*
374 * Now search the body
375 */
376 snprintf(msg, sizeof(msg), _(txt_searching_body), ++curr_cnt, total_cnt);
378 while ((tmp = tin_fgets(artinfo.cooked, FALSE)) != NULL) {
379#ifdef HAVE_UNICODE_NORMALIZATION
380 if (IS_LOCAL_CHARSET("UTF-8"))
381 line = normalize(tmp);
382 else
383#endif /* HAVE_UNICODE_NORMALIZATION */
384 line = my_strdup(tmp);
385
386 if (tinrc.wildcard) {
387 if (pcre_exec(search_regex.re, search_regex.extra, line, (int) strlen(line), 0, 0, srch_offsets, srch_offsets_size) != PCRE_ERROR_NOMATCH) {
388 srch_lineno = i;
389 art_close(&pgart); /* Switch the pager over to matched art */
390 pgart = artinfo;
391#ifdef DEBUG
392 if (debug & DEBUG_MISC)
393 fprintf(stderr, "art_switch(%p = %p)\n", (void *) &pgart, (void *) &artinfo);
394#endif /* DEBUG */
395 free(line);
396
397 return 1;
398 }
399 } else {
400 if (wildmatpos(line, searchbuf, TRUE, srch_offsets, srch_offsets_size) == 1) {
401 srch_lineno = i;
402 art_close(&pgart); /* Switch the pager over to matched art */
403 pgart = artinfo;
404 free(line);
405 return 1;
406 }
407 }
408 i++;
409 free(line);
410 }
411
412 if (tin_errno != 0) { /* User abort */
413 art_close(&artinfo);
414 return -1;
415 }
416
417 art_close(&artinfo);
418/* info_message(_(txt_no_match)); */
419 return 0;
420}
421
422
423/*
424 * Match searchbuff against the From: information in arts[i]
425 * 1 = found, 0 = not found
426 */
427static int
429 int i,
430 char *searchbuf)
431{
432 char *buf, *tmp;
433
434 if (arts[i].name == NULL)
435 tmp = my_strdup(arts[i].from);
436 else {
437 size_t len = strlen(arts[i].from) + strlen(arts[i].name) + 4;
438
439 tmp = my_malloc(len);
440 snprintf(tmp, len, "%s <%s>", arts[i].name, arts[i].from);
441 }
442
443#ifdef HAVE_UNICODE_NORMALIZATION
444 if (IS_LOCAL_CHARSET("UTF-8")) {
445 buf = normalize(tmp);
446 free(tmp);
447 } else
448#endif /* HAVE_UNICODE_NORMALIZATION */
449 buf = tmp;
450
451 if (match_regex(buf, searchbuf, &search_regex, TRUE)) {
452 free(buf);
453 return 1;
454 }
455
456 free(buf);
457 return 0;
458}
459
460
461/*
462 * Match searchbuff against the Subject: information in arts[i]
463 * 1 = found, 0 = not found
464 */
465static int
467 int i,
468 char *searchbuf)
469{
470 char *buf;
471
472#ifdef HAVE_UNICODE_NORMALIZATION
473 if (IS_LOCAL_CHARSET("UTF-8"))
474 buf = normalize(arts[i].subject);
475 else
476#endif /* HAVE_UNICODE_NORMALIZATION */
477 buf = my_strdup(arts[i].subject);
478
479 if (match_regex(buf, searchbuf, &search_regex, TRUE)) {
480 free(buf);
481 return 1;
482 }
483
484 free(buf);
485 return 0;
486}
487
488
489/*
490 * Returns index into arts[] of matching article or -1
491 */
492static int
494 t_bool forward,
495 int current_art,
496 char *searchbuff,
497 int (*search_func) (int i, char *searchbuff))
498{
499 int i, ret, loop_cnt;
500
501 if (grpmenu.curr < 0) {
503 return -1;
504 }
505
506 /*
507 * precompile if we're using full regex
508 */
509 if (tinrc.wildcard && !(compile_regex(searchbuff, &search_regex, PCRE_CASELESS)))
510 return -1;
511
512 i = current_art;
513 loop_cnt = 1;
514
515 do {
516 if (forward) {
517 if ((i = next_response(i)) < 0)
518 i = (int) base[0];
519 } else {
520 if ((i = prev_response(i)) < 0)
522 }
523
524 /* Only search displayed articles */
526 continue;
527
528 ret = search_func(i, searchbuff);
529 if (tinrc.wildcard && (ret == 1 || ret == -1)) {
530 /* we will exit soon, clean up */
533 }
534 switch (ret) {
535 case 1: /* Found */
537 return i;
538
539 case -1: /* User abort */
540 return -1;
541 }
542#ifdef HAVE_SELECT
543 if (wait_for_input()) /* allow abort */
544 return -1;
545#endif /* HAVE_SELECT */
546 if (loop_cnt % (MODULO_COUNT_NUM * 20) == 0)
548 } while (i != current_art && loop_cnt++ <= top_art);
549
550 if (tinrc.wildcard) {
553 }
555 return -1;
556}
557
558
559/*
560 * Generic entry point to search for fields in arts[]
561 * Returns index into arts[] of matching article or -1
562 */
563int
566 int current_art,
567 t_bool repeat)
568{
569 char *buf;
570 int (*search_func) (int i, char *searchbuff) = author_search;
571 t_bool forward;
572
574 forward = TRUE;
575 else
576 forward = FALSE;
577
578 switch (func) {
582 return -1;
583 search_func = subject_search;
584 break;
585
588 default:
590 return -1;
591 search_func = author_search;
592 break;
593 }
594 return (search_group(forward, current_art, buf, search_func));
595}
596
597
598/*
599 * page.c (search current article body)
600 * Return line number that matches or -1
601 * If using regex's return vector of character offsets
602 */
603int
605 t_bool forward,
606 t_bool repeat,
607 int start_line,
608 int lines,
609 t_lineinfo *line,
611 FILE *fp)
612{
613 char *pattern, *ptr, *tmp;
614 int i = start_line;
615 int tmp_srch_offsets[2] = {0, 0};
616 t_bool wrap = FALSE;
618
620 return 0;
621
622 if (tinrc.wildcard && !(compile_regex(pattern, &search_regex, PCRE_CASELESS)))
623 return -1;
624
625 srch_lineno = -1;
626
627 forever {
628 if (i == start_line && wrap)
629 break;
630
631 /*
632 * TODO: consider not searching some line types?
633 * 'B'ody search skips hdrs, '/' inside article does not.
634 */
635 if (fseek(fp, line[i].offset, SEEK_SET) != 0)
636 return -1;
637
638 /* Don't search beyond ^L if hiding is enabled */
639 if ((line[i].flags & C_CTRLL) && i > reveal_ctrl_l_lines)
640 break;
641
642 if ((tmp = tin_fgets(fp, FALSE)) == NULL)
643 return -1;
644 if (!forward && srch_offsets[0] >= 0) {
645 tmp[srch_offsets[0]] = '\0'; /* ignore anything on this line after the last match */
646 srch_offsets[1] = 0; /* start backwards search at the beginning of the line */
647 }
648
649#ifdef HAVE_UNICODE_NORMALIZATION
650 if (IS_LOCAL_CHARSET("UTF-8"))
651 ptr = normalize(tmp);
652 else
653#endif /* HAVE_UNICODE_NORMALIZATION */
654 ptr = my_strdup(tmp);
655
656 if (tinrc.wildcard) {
657 while (pcre_exec(search_regex.re, search_regex.extra, ptr, (int) strlen(ptr), srch_offsets[1], 0, srch_offsets, srch_offsets_size) != PCRE_ERROR_NOMATCH) {
658 match = TRUE;
659 if (forward)
660 break;
661 else {
662 tmp_srch_offsets[0] = srch_offsets[0];
663 tmp_srch_offsets[1] = srch_offsets[1];
664 }
665 }
666 if (match) {
667 if (!forward) {
668 srch_offsets[0] = tmp_srch_offsets[0];
669 srch_offsets[1] = tmp_srch_offsets[1];
670 }
671 srch_lineno = i;
674 free(ptr);
675 return i;
676 }
677 } else {
678 if (wildmatpos(ptr, pattern, TRUE, srch_offsets, srch_offsets_size)) {
679 srch_lineno = i;
680 free(ptr);
681 return i;
682 }
683 }
684 free(ptr);
685
686 if (forward) {
687 if (i >= lines - 1) {
688 i = 0;
689 wrap = TRUE;
690 } else
691 i++;
692 } else {
693 if (i <= 0) {
694 i = lines - 1;
695 wrap = TRUE;
696 } else
697 i--;
698 }
699
700 /* search at the beginning of the line */
701 srch_offsets[1] = 0;
702 }
703
705 if (tinrc.wildcard) {
708 }
709 return -1;
710}
711
712
713/*
714 * Search the bodies of all the articles in current group
715 * Start the search at the current article
716 * A match will replace the context of the article open in the pager
717 * Save the line # that matched (and the start/end vector for regex)
718 * for later retrieval
719 * Return index in arts[] of article that matched or -1
720 */
721int
723 struct t_group *group,
724 int current_art,
725 t_bool repeat)
726{
727 char *buf;
728 int i;
729 t_bool forward_fake = TRUE;
730
731 if (!(buf = get_search_pattern(
732 &forward_fake, /* we pass a dummy var since body search has no `forward' */
733 repeat,
738 ))) return -1;
739
740 last_search = GLOBAL_SEARCH_BODY; /* store last search type for repeated search */
741 total_cnt = curr_cnt = 0; /* Reset global counter of articles done */
742
743 /*
744 * Count up the articles to be processed for the progress meter
745 */
746 if (group->attribute->show_only_unread_arts) {
747 for (i = 0; i < grpmenu.max; i++)
749 } else {
750 for_each_art(i) {
751 if (!IGNORE_ART(i))
752 total_cnt++;
753 }
754 }
755
756 srch_lineno = -1;
757 return search_group(1, current_art, buf, body_search);
758}
759
760
761/*
762 * Return the saved line & start/end info from previous successful
763 * regex search
764 */
765int
767 int *start,
768 int *end)
769{
770 int i = srch_lineno;
771
772 *start = srch_offsets[0];
773 *end = srch_offsets[1];
774 srch_lineno = -1; /* We can only retrieve this info once */
775 return i;
776}
777
778
779/*
780 * Reset offsets so that the next search starts at the beginning of the line.
781 * This function is needed to access srch_offsets from within other modules.
782 */
783void
785 void)
786{
787 srch_offsets[0] = srch_offsets[1] = 0;
788}
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:1562
@ HIST_AUTHOR_SEARCH
Definition: extern.h:1560
@ HIST_ART_SEARCH
Definition: extern.h:1559
@ HIST_CONFIG_SEARCH
Definition: extern.h:1575
@ HIST_SUBJECT_SEARCH
Definition: extern.h:1574
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:684
t_bool show_description
Definition: init.c:153
t_openartinfo pgart
Definition: page.c:63
constext txt_searching_body[]
Definition: lang.c:848
t_menu grpmenu
Definition: group.c:83
int tin_errno
Definition: read.c:59
t_menu selmenu
Definition: select.c:84
struct t_article * arts
Definition: memory.c:69
constext txt_no_search_string[]
Definition: lang.c:699
constext txt_attachment_no_name[]
Definition: lang.c:86
constext txt_search_backwards[]
Definition: lang.c:844
constext * content_encodings[]
Definition: lang.c:1461
constext txt_author_search_forwards[]
Definition: lang.c:105
constext txt_no_arts[]
Definition: lang.c:678
constext txt_searching[]
Definition: lang.c:847
t_artnum * base
Definition: memory.c:65
constext txt_search_body[]
Definition: lang.c:845
constext * content_types[]
Definition: lang.c:1466
int top_art
Definition: art.c:60
struct t_group * curr_group
Definition: group.c:55
struct t_config tinrc
Definition: init.c:192
unsigned short debug
Definition: debug.c:51
constext txt_author_search_backwards[]
Definition: lang.c:104
constext txt_no_match[]
Definition: lang.c:689
struct t_group * active
Definition: memory.c:66
constext txt_search_forwards[]
Definition: lang.c:846
@ 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:375
static char buf[16]
Definition: langinfo.c:50
static int reveal_ctrl_l_lines
Definition: page.c:82
static char * end
Definition: plp_snprintf.c:205
int num_of_responses(int n)
Definition: thread.c:1124
t_bool wildmatpos(const char *text, char *p, t_bool icase, int *srch_offsets, int srch_offsets_size)
Definition: wildmat.c:164
char * prompt_string_default(const char *prompt, char *def, const char *failtext, int history)
Definition: prompt.c:587
char * quote_wild_whitespace(char *str)
Definition: misc.c:2362
t_url * find_url(int n)
Definition: page.c:2581
void info_message(const char *fmt,...)
Definition: screen.c:102
t_posted * find_post_hist(int n)
Definition: post.c:691
t_bool match_regex(const char *string, char *pattern, struct regex_cache *cache, t_bool icase)
Definition: regex.c:59
t_part * get_part(int n)
Definition: save.c:1967
const char * get_param(t_param *list, const char *name)
Definition: rfc2046.c:568
char * my_strdup(const char *str)
Definition: string.c:139
int new_responses(int thread)
Definition: thread.c:1045
int prev_response(int n)
Definition: thread.c:1321
void art_close(t_openartinfo *artinfo)
Definition: rfc2046.c:1623
int find_response(int i, int n)
Definition: thread.c:1342
const char * get_filename(t_param *ptr)
Definition: cook.c:353
void clear_message(void)
Definition: screen.c:283
int next_response(int n)
Definition: thread.c:1280
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:1566
t_bool compile_regex(const char *regex, struct regex_cache *cache, int options)
Definition: regex.c:111
t_bool option_is_visible(enum option_enum option)
Definition: options_menu.c:203
void show_progress(const char *txt, t_artnum count, t_artnum total)
Definition: screen.c:529
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:1355
static int subject_search(int i, char *searchbuf)
Definition: search.c:466
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:428
static int curr_cnt
Definition: search.c:60
int search_active(t_bool forward, t_bool repeat)
Definition: search.c:278
void reset_srch_offsets(void)
Definition: search.c:784
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:604
int get_search_vectors(int *start, int *end)
Definition: search.c:766
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:722
static int body_search(int i, char *searchbuf)
Definition: search.c:344
static int search_group(t_bool forward, int current_art, char *searchbuff, int(*search_func)(int i, char *searchbuff))
Definition: search.c:493
int search(t_function func, int current_art, t_bool repeat)
Definition: search.c:564
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
Definition: tin.h:1978
char group[80]
Definition: tin.h:1980
char subj[120]
Definition: tin.h:1982
char date[10]
Definition: tin.h:1979
pcre_extra * extra
Definition: tin.h:1963
pcre * re
Definition: tin.h:1962
unsigned int status
Definition: tin.h:1551
unsigned show_only_unread_arts
Definition: tin.h:1674
char default_search_subject[LEN]
Definition: tinrc.h:102
char default_search_author[HEADER_LEN]
Definition: tinrc.h:99
char default_search_art[LEN]
Definition: tinrc.h:98
char default_search_group[HEADER_LEN]
Definition: tinrc.h:101
int wildcard
Definition: tinrc.h:167
char default_search_config[LEN]
Definition: tinrc.h:100
Definition: tin.h:1816
struct t_attribute * attribute
Definition: tin.h:1834
char * name
Definition: tin.h:1817
int curr
Definition: tin.h:2056
int max
Definition: tin.h:2057
Definition: tin.h:2112
char * url
Definition: tin.h:2113
#define LEN
Definition: tin.h:860
#define SEEK_SET
Definition: tin.h:2512
#define URL_LEVEL
Definition: tin.h:1121
#define IS_LOCAL_CHARSET(c)
Definition: tin.h:782
#define POSTED_LEVEL
Definition: tin.h:1122
#define MODULO_COUNT_NUM
Definition: tin.h:868
#define for_each_art(x)
Definition: tin.h:2260
#define IGNORE_ART(i)
Definition: tin.h:1029
#define my_malloc(size)
Definition: tin.h:2245
#define ARRAY_SIZE(array)
Definition: tin.h:2250
#define ART_ABORT
Definition: tin.h:1360
#define ATTACHMENT_LEVEL
Definition: tin.h:1120
#define _(Text)
Definition: tin.h:94
#define forever
Definition: tin.h:816
#define snprintf
Definition: tin.h:2464
#define FreeAndNull(p)
Definition: tin.h:2253
#define ART_UNREAD
Definition: tin.h:1346
#define ART_UNAVAILABLE
Definition: tin.h:1348