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

feed.c
Go to the documentation of this file.
1 /*
2  * Project : tin - a Usenet reader
3  * Module : feed.c
4  * Author : I. Lea
5  * Created : 1991-08-31
6  * Updated : 2019-02-15
7  * Notes : provides same interface to mail,pipe,print,save & repost commands
8  *
9  * Copyright (c) 1991-2020 Iain Lea <iain@bricbrac.de>
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 #ifndef TCURSES_H
45 # include "tcurses.h"
46 #endif /* !TCURSES_H */
47 
48 
49 static t_bool confirm; /* only used for FEED_MAIL */
52 static t_bool supersede = FALSE; /* for reposting only */
53 static t_function pproc_func; /* Post-processing type when saving */
54 #ifndef DONT_HAVE_PIPING
55  static FILE *pipe_fp = (FILE *) 0;
57 #endif /* !DONT_HAVE_PIPING */
58 
59 
60 struct t_counters {
61  int success; /* # arts fed okay */
62  int total; /* # arts fed */
63  int max; /* initial guesstimate of total */
64 };
65 
66 /*
67  * Local prototypes
68  */
69 static char *get_save_filename(struct t_group *group, int function, char *filename, int filelen, int respnum);
70 static t_bool expand_feed_filename(char *outpath, size_t outpath_len, const char *path);
71 static t_bool feed_article(int art, int function, struct t_counters *counter, t_bool use_current, const char *data, struct t_group *group);
72 static t_function get_feed_key(int function, int level, struct t_group *group, struct t_art_stat *thread, int respnum);
73 static t_function get_post_proc_type(void);
74 static void print_save_summary(t_function type, int fed);
75 #ifndef DISABLE_PRINTING
76  static t_bool print_file(const char *command, int respnum, t_openartinfo *artinfo);
77 #endif /* !DISABLE_PRINTING */
78 
79 #ifndef DONT_HAVE_PIPING
80 # define handle_EPIPE() if (got_epipe) goto got_epipe_while_piping
81 #else
82 # define handle_EPIPE() do {} while (0) /* nothing */
83 #endif /* !DONT_HAVE_PIPING */
84 
85 /*
86  * 'filename' holds 'filelen' amount of storage in which to place the
87  * filename to save-to. The filename is also returned after basic syntax
88  * checking. We default to the global save filename or group specific
89  * filename if it exists
90  */
91 static char *
93  struct t_group *group,
94  int function,
95  char *filename,
96  int filelen,
97  int respnum)
98 {
99  char default_savefile[PATH_LEN];
100 
101  filename[0] = '\0';
102 
103  /*
104  * Group attribute savefile overrides tinrc default savefile
105  */
106  my_strncpy(default_savefile, (group->attribute->savefile ? group->attribute->savefile : tinrc.default_save_file), sizeof(default_savefile) - 1);
107 
108  /*
109  * We don't ask when auto'S'aving or Archive-Name saving with auto_save
110  */
111  if (!(function == FEED_AUTOSAVE || (group->attribute->auto_save && arts[respnum].archive))) {
112  if (!prompt_default_string(_(txt_save_filename), filename, filelen, default_savefile, HIST_SAVE_FILE)) {
113  clear_message();
114  return NULL;
115  }
116  str_trim(filename);
117  }
118 
119  /*
120  * Update tinrc.default_save_file if changed
121  */
122  if (*filename)
123  my_strncpy(tinrc.default_save_file, filename, sizeof(tinrc.default_save_file) - 1);
124  else {
125  /*
126  * None chosen (or AUTOSAVING), use tinrc default
127  */
128  if (*default_savefile)
129  my_strncpy(filename, default_savefile, filelen - 1);
130  else { /* No default either */
132  return NULL;
133  }
134  }
135 
136  /*
137  * Punt invalid expansions
138  */
139  if ((filename[0] == '~' || filename[0] == '+') && filename[1] == '\0') {
141  return NULL;
142  }
143  return filename;
144 }
145 
146 
147 /*
148  * Generate a path/filename to save to, using 'path' as input.
149  * The pathname is stored in 'outpath', which should be PATH_LEN in size
150  * Expand metacharacters and use defaults as needed.
151  * Return TRUE if the path is a mailbox, or FALSE otherwise.
152  */
153 static t_bool
155  char *outpath,
156  size_t outpath_len,
157  const char *path)
158 {
159  int ret = strfpath(path, outpath, PATH_LEN, curr_group, TRUE);
160 
161  /*
162  * If no path exists or the above failed in some way, use sensible defaults
163  * Put the generic path into 'outpath'
164  */
165  if ((ret == 0) || !(strrchr(outpath, DIRSEP))) {
166  char buf[PATH_LEN];
167 
169  joinpath(buf, sizeof(buf), homedir, DEFAULT_SAVEDIR);
170  joinpath(outpath, outpath_len, buf, path);
171  return FALSE;
172  }
173  return (ret == 1);
174 }
175 
176 
177 /*
178  * Find out what post-processing to perform.
179  * This is not used when saving to mailboxes (we don't postprocess mailboxes)
180  * Also not used when using the auto-save feature because a default value is
181  * taken from the group attributes
182  * Returns POSTPROCESS_{NO,SHAR,YES} or GLOBAL_ABORT if aborting the save process
183  */
184 static t_function
186  void)
187 {
188  char keyno[MAXKEYLEN], keyyes[MAXKEYLEN], keyquit[MAXKEYLEN];
189  char keyshar[MAXKEYLEN];
190  t_function default_func, func;
191 
193  case POST_PROC_YES:
194  default_func = POSTPROCESS_YES;
195  break;
196 
197  case POST_PROC_SHAR:
198  default_func = POSTPROCESS_SHAR;
199  break;
200 
201  case POST_PROC_NO:
202  default:
203  default_func = POSTPROCESS_NO;
204  break;
205  }
206 
212 
213  if (func == GLOBAL_QUIT || func == GLOBAL_ABORT) { /* exit */
214  clear_message();
215  return GLOBAL_ABORT;
216  }
217  return func;
218 }
219 
220 
221 /*
222  * Return the key mapping for what we are intending to process or
223  * GLOBAL_ABORT if save process is being aborted
224  * Key can be (current) article, (current) thread, tagged articles,
225  * hot articles, or articles matching a pattern
226  * This is automatic in the various auto-save cases, in other
227  * cases this is prompted for based on a chosen default
228  */
229 static t_function
231  int function,
232  int level,
233  struct t_group *group,
234  struct t_art_stat *thread,
235  int respnum)
236 {
237  constext *prompt;
238  t_function default_func, func;
239 
240  switch (function) {
241  case FEED_MAIL:
242  prompt = txt_mail;
243  break;
244 
245  case FEED_MARK_READ:
246  case FEED_MARK_UNREAD:
247  prompt = txt_mark;
248  break;
249 
250 #ifndef DONT_HAVE_PIPING
251  case FEED_PIPE:
252  prompt = txt_pipe;
253  break;
254 #endif /* !DONT_HAVE_PIPING */
255 
256 #ifndef DISABLE_PRINTING
257  case FEED_PRINT:
258  prompt = txt_print;
259  break;
260 #endif /* !DISABLE_PRINTING */
261 
262  /* FEED_AUTOSAVE doesn't prompt */
263  case FEED_SAVE:
264  prompt = txt_save;
265  break;
266 
267  case FEED_REPOST:
268  if (!can_post) { /* Get this over with before asking any Q's */
270  return NOT_ASSIGNED;
271  }
272  prompt = txt_repost;
273  break;
274 
275  default:
276  prompt = "";
277  break;
278  }
279 
280  /*
281  * Try and work out what default the user wants
282  * thread->total = # arts in thread
283  */
284  default_func = (range_active ? FEED_RANGE :
286  (arts_selected() ? FEED_HOT :
287  ((level == GROUP_LEVEL && thread->total > 1) ? FEED_THREAD :
288  (thread->selected_total ? FEED_HOT :
289  FEED_ARTICLE))));
290 
291  /*
292  * Don't bother querying when:
293  * auto'S'aving and there are tagged or selected(hot) articles
294  * using the auto_save feature on Archive postings
295  */
296  if ((function == FEED_AUTOSAVE && (range_active || num_of_tagged_arts || arts_selected()))
297  || (function == FEED_SAVE && group->attribute->auto_save && arts[respnum].archive))
298  func = default_func;
299  else {
300  char buf[LEN];
301  char keyart[MAXKEYLEN], keythread[MAXKEYLEN], keyrange[MAXKEYLEN], keyhot[MAXKEYLEN];
302  char keypat[MAXKEYLEN], keytag[MAXKEYLEN], keyquit[MAXKEYLEN];
303 
312 
313  func = prompt_slk_response(default_func, feed_type_keys, "%s %s", _(prompt), buf);
314  }
315 
316  switch (func) {
317  case FEED_PATTERN:
318  {
320 
322  free(tmp);
323  return GLOBAL_ABORT;
324  }
325  free(tmp);
326  }
327  break;
328 
329  case FEED_RANGE:
330  if (!range_active) {
331  if (set_range(level, 1, currmenu->max, currmenu->curr + 1))
332  range_active = TRUE;
333  else
334  return GLOBAL_ABORT;
335  }
336  break;
337 
338  case GLOBAL_QUIT:
339  case GLOBAL_ABORT:
340  clear_message();
341  return GLOBAL_ABORT;
342  /* NOTREACHED */
343  break;
344 
345  default:
346  break;
347  }
348 
349  return func;
350 }
351 
352 
353 /*
354  * Print a message like:
355  * -- [Article|Thread|Tagged Articles] saved to [mailbox] [filenames] --
356  * 'fed' is the number of articles we tried to save
357  */
358 static void
360  t_function type,
361  int fed)
362 {
363  const char *first, *last;
364  char buf[LEN];
365  char what[LEN];
366 
367  if (fed != num_save)
369 
370  switch (type) {
371  case FEED_HOT:
372  snprintf(what, sizeof(what), _(txt_prefix_hot), PLURAL(fed, txt_article));
373  break;
374 
375  case FEED_TAGGED:
376  snprintf(what, sizeof(what), _(txt_prefix_tagged), PLURAL(fed, txt_article));
377  break;
378 
379  case FEED_THREAD:
380  STRCPY(what, _(txt_thread_upper));
381  break;
382 
383  case FEED_ARTICLE:
384  case FEED_PATTERN:
385  default:
386  snprintf(what, sizeof(what), "%s", PLURAL(fed, txt_article));
387  break;
388  }
389 
390  first = (save[0].mailbox) ? save[0].path : save[0].file;
391  last = (save[num_save - 1].mailbox) ? save[num_save - 1].path : save[num_save - 1].file;
392 
393  /*
394  * We report the range of saved-to files for regular saves of > 1 articles
395  */
396  if (num_save == 1 || save[0].mailbox)
397  snprintf(buf, sizeof(buf), _(txt_saved_to),
398  what, (save[0].mailbox ? _(txt_mailbox) : ""), first);
399  else
400  snprintf(buf, sizeof(buf), _(txt_saved_to_range),
401  what, first, last);
402 
403  wait_message((tinrc.beginner_level) ? 4 : 2, buf);
404 }
405 
406 
407 /*
408  * This is the handler that processes a single article for all the various
409  * FEED_ functions.
410  * Assumes no article is open when we enter - opens and closes the art being
411  * processed. As a performance hack this is not done if 'use_current' is set.
412  * Returns TRUE or FALSE
413  * TODO: option to mail/pipe/print/repost raw vs. cooked?
414  * (all currently raw only) or should we feed according to what
415  * is currently on screen?
416  */
417 static t_bool
419  int art, /* index in arts[] */
420  int function,
421  struct t_counters *counter, /* Accounting */
422  t_bool use_current, /* Use already open pager article */
423  const char *data, /* Extra data if needed, print command or save filename */
424  struct t_group *group)
425 {
426  char *progress_mesg = NULL;
427  t_bool ok = TRUE; /* Assume success */
428  t_openartinfo openart;
429  t_openartinfo *openartptr = &openart;
430 
431  counter->total++;
432 
433  /*
434  * Update the on-screen progress before art_open(), which is the bottleneck
435  * timewise
436  */
437  switch (function) {
438 #ifndef DONT_HAVE_PIPING
439  case FEED_PIPE:
440  progress_mesg = fmt_string("%s (%d/%d)", _(txt_piping), counter->total, counter->max);
441  break;
442 #endif /* !DONT_HAVE_PIPING */
443 
444 #ifndef DISABLE_PRINTING
445  case FEED_PRINT:
446  progress_mesg = fmt_string("%s (%d/%d)", _(txt_printing), counter->total, counter->max);
447  break;
448 #endif /* !DISABLE_PRINTING */
449 
450  case FEED_SAVE:
451  case FEED_AUTOSAVE:
452  progress_mesg = fmt_string("%s (%d/%d)", _(txt_saving), counter->total, counter->max);
453  break;
454  }
455 
456  if (progress_mesg != NULL) {
457  if (!use_current)
458  show_progress(progress_mesg, counter->total, counter->max);
460  }
461 
462  if (use_current)
463  openartptr = &pgart; /* Use art already open in pager */
464  else {
465  if (art_open(FALSE, &arts[art], group, openartptr, FALSE, NULL) < 0)
466  /* User abort or an error */
467  return FALSE;
468  }
469 
470  switch (function) {
471  case FEED_MAIL:
472  switch (mail_to_someone(tinrc.default_mail_address, confirm, openartptr, group)) {
473  case POSTED_REDRAW:
475  /* FALLTHROUGH */
476  case POSTED_NONE:
477  ok = FALSE;
478  break;
479 
480  case POSTED_OK:
481  break;
482  }
483  confirm = bool_not(ok); /* Only confirm the next one after a failure */
484  break;
485 
486  case FEED_MARK_READ:
487  if (arts[art].status == ART_UNREAD || arts[art].status == ART_WILL_RETURN)
489  else
490  ok = FALSE;
491  break;
492 
493  case FEED_MARK_UNREAD:
494  if (arts[art].status == ART_READ)
496  else
497  ok = FALSE;
498  break;
499 
500 #ifndef DONT_HAVE_PIPING
501  case FEED_PIPE:
502  rewind(openartptr->raw);
503  ok = copy_fp(openartptr->raw, pipe_fp);
504  if (errno == EPIPE) /* broken pipe in copy_fp() */
505  got_epipe = TRUE;
506  break;
507 #endif /* !DONT_HAVE_PIPING */
508 
509 #ifndef DISABLE_PRINTING
510  case FEED_PRINT:
511  ok = print_file(data /*print_command*/, art, openartptr);
512  break;
513 #endif /* !DISABLE_PRINTING */
514 
515  case FEED_SAVE:
516  case FEED_AUTOSAVE:
517  ok = save_and_process_art(openartptr, &arts[art], is_mailbox, data /*filename*/, counter->max, (pproc_func != POSTPROCESS_NO));
520  break;
521 
522  case FEED_REPOST:
524  ok = FALSE;
525  else /* POSTED_REDRAW, POSTED_OK */
527  break;
528 
529  default:
530  break;
531  }
532  if (ok)
533  counter->success++;
534 
535  if (!use_current)
536  art_close(openartptr);
537  return ok;
538 }
539 
540 
541 /*
542  * Single entry point for 'feed'ing article(s) to a backend
543  * Function:
544  * FEED_PIPE, FEED_MAIL, FEED_PRINT, FEED_REPOST
545  * FEED_SAVE, FEED_AUTOSAVE, FEED_MARK_READ, FEED_MARK_UNREAD
546  * Level:
547  * GROUP_LEVEL, THREAD_LEVEL, PAGE_LEVEL
548  * Type:
549  * default feed_type; if NOT_ASSIGNED, query what to do
550  * Respnum:
551  * Index in arts[] of starting article
552  *
553  * The following 'groups' of article can be processed:
554  * Single (current) article
555  * Current thread
556  * Range of articles
557  * Tagged articles
558  * Hot articles
559  * Articles matching a pattern
560  *
561  * The selection of Function depends on the key used to get here.
562  * The selection of which article 'group' to process is managed
563  * inside here, or by defaults.
564  *
565  * Returns:
566  * 1 if there are no more unread arts in this group (FEED_MARK_READ)
567  * 0 on success
568  * -1 on failure/abort
569  */
570 int
572  int function,
573  int level,
574  t_function type,
575  struct t_group *group,
576  int respnum)
577 {
578  char *prompt;
579  char outpath[PATH_LEN];
580  int art;
581  int i;
582  int saved_curr_line = -1;
583  int thread_base;
584  struct t_art_stat sbuf;
585  struct t_counters counter = {0, 0, 0};
586  t_bool feed_mark_function = function == FEED_MARK_READ || function == FEED_MARK_UNREAD;
587  t_bool mark_saved = FALSE;
588  t_bool no_next_unread = FALSE;
589  t_bool post_processed_ok = FALSE;
590  t_bool use_current = FALSE;
591  t_function feed_type;
592 
593 #ifdef DONT_HAVE_PIPING
594  if (function == FEED_PIPE) {
595  error_message(2, _(txt_piping_not_enabled));
596  clear_message();
597  return -1;
598  }
599 #endif /* DONT_HAVE_PIPING */
600 
601  if (function == FEED_AUTOSAVE) {
602  if (!range_active && num_of_tagged_arts == 0 && !arts_selected()) {
604  return -1;
605  }
606  }
607 
608  set_xclick_off(); /* TODO: there is no corresponding set_xclick_on()? */
609  if ((thread_base = which_thread(respnum)) >= 0)
610  stat_thread(thread_base, &sbuf);
611  else /* TODO: error message? */
612  return -1;
613 
614  switch (type) {
615  case FEED_ARTICLE:
616  case FEED_THREAD:
617  case FEED_RANGE:
618  feed_type = type;
619  break;
620 
621  default:
622  if ((feed_type = get_feed_key(function, level, group, &sbuf, respnum)) == GLOBAL_ABORT)
623  return -1;
624  break;
625  }
626 
627  /*
628  * Get whatever information is needed to proceed
629  */
630  switch (function) {
631  /* Setup mail - get address to mail to */
632  case FEED_MAIL:
635  free(prompt);
636  return -1;
637  }
638  free(prompt);
639  break;
640 
641 #ifndef DONT_HAVE_PIPING
642  /* Setup pipe - get pipe-to command and open the pipe */
643  case FEED_PIPE:
646  free(prompt);
647  return -1;
648  }
649  free(prompt);
650 
651  got_epipe = FALSE;
652  EndWin(); /* Turn off curses/windowing */
653  Raw(FALSE);
654  fflush(stdout);
656  if ((pipe_fp = popen(tinrc.default_pipe_command, "w")) == NULL) {
659  Raw(TRUE);
660  InitWin();
661  return -1;
662  }
663  break;
664 #endif /* !DONT_HAVE_PIPING */
665 
666 #ifndef DISABLE_PRINTING
667  /* Setup printing - get print command line */
668  case FEED_PRINT:
669  snprintf(outpath, sizeof(outpath), "%s %s", tinrc.printer, REDIRECT_OUTPUT);
670  break;
671 #endif /* !DISABLE_PRINTING */
672 
673  /*
674  * Setup saving, some of these are generated automatically
675  * Determine path/file to save to
676  * Determine post-processing type
677  * Determine if post processed file deletion required
678  */
679  case FEED_SAVE:
680  case FEED_AUTOSAVE:
681  {
682  char savefile[PATH_LEN];
683 
684  /* This will force automatic selection unless changed by user */
685  savefile[0] = '\0';
686 
687  if (get_save_filename(group, function, savefile, sizeof(savefile), respnum) == NULL)
688  return -1;
689 
691  case POST_PROC_YES:
693  break;
694 
695  case POST_PROC_SHAR:
697  break;
698 
699  case POST_PROC_NO:
700  default:
702  break;
703  }
704 
705  /* We don't postprocess mailboxen */
706  if ((is_mailbox = expand_feed_filename(outpath, sizeof(outpath), savefile)) == TRUE)
708  else {
709  if (function != FEED_AUTOSAVE && (pproc_func = get_post_proc_type()) == GLOBAL_ABORT)
710  return -1;
711  }
712  if (!create_path(outpath))
713  return -1;
714  }
715  break;
716 
717  /* repost (or supersede) article */
718  case FEED_REPOST:
719  {
720  char *tmp;
721 #ifndef FORGERY
722  char from_name[PATH_LEN];
723 
724  get_from_name(from_name, (struct t_group *) 0);
725 
726  if (strstr(from_name, arts[respnum].from)) {
727 #endif /* !FORGERY */
728  char *smsg;
729  char buf[LEN];
730  char keyrepost[MAXKEYLEN], keysupersede[MAXKEYLEN];
731  char keyquit[MAXKEYLEN];
732  t_function func;
733 
734  /* repost or supersede? */
741  sized_message(&smsg, buf, arts[respnum].subject));
742  free(smsg);
743 
744  switch (func) {
745  case FEED_SUPERSEDE:
747  supersede = TRUE;
748  break;
749 
750  case FEED_KEY_REPOST:
752  supersede = FALSE;
753  break;
754 
755  default:
756  clear_message();
757  return -1;
758  }
759 #ifndef FORGERY
760  } else {
762  supersede = FALSE;
763  }
764 #endif /* !FORGERY */
766  free(tmp);
767  return -1;
768  }
769  free(tmp);
770  }
771  break;
772 
773  default:
774  break;
775  } /* switch (function) */
776 
777  confirm = TRUE; /* Always confirm the first time */
778  clear_message();
779 
780  /*
781  * Performance hack - If we feed a single art from the pager then we can
782  * re-use the currently open article
783  * Also no need to fetch articles just to mark them (un)read
784  */
785  if (feed_mark_function || (level == PAGE_LEVEL && (feed_type == FEED_ARTICLE || feed_type == FEED_THREAD))) {
786  saved_curr_line = curr_line; /* Save where we were in pager */
787  use_current = TRUE;
788  }
789 
790  /*
791  * This is the main loop
792  * The general idea is to feed_article() for every article to be processed
793  */
794  switch (feed_type) {
795  case FEED_ARTICLE: /* article */
796  counter.max = 1;
797  if (!feed_article(respnum, function, &counter, use_current, outpath, group))
798  handle_EPIPE();
799  break;
800 
801  case FEED_THREAD: /* thread */
802  /* Get accurate count first */
804  if (feed_mark_function || !(curr_group->attribute->process_only_unread && arts[art].status == ART_READ))
805  counter.max++;
806  }
807 
809  if (feed_mark_function || !(curr_group->attribute->process_only_unread && arts[art].status == ART_READ)) {
810  /* Keep going - don't abort on errors */
811  if (!feed_article(art, function, &counter, use_current, outpath, group))
812  handle_EPIPE();
813  }
814  }
815  break;
816 
817  case FEED_RANGE:
818  /* Get accurate count first */
819  for_each_art(art) {
820  if (arts[art].inrange)
821  counter.max++;
822  }
823 
824  for_each_art(art) {
825  if (arts[art].inrange) {
826  arts[art].inrange = FALSE;
827  if (!feed_article(art, function, &counter, use_current, outpath, group))
828  handle_EPIPE();
829  }
830  }
833  break;
834 
835  case FEED_TAGGED: /* tagged articles */
836  counter.max = num_of_tagged_arts;
837  for (i = 1; i <= num_of_tagged_arts; i++) {
838  for_each_art(art) {
839  /* process_only_unread does NOT apply on tagged arts */
840  if (arts[art].tagged == i) {
841  /* Keep going - don't abort on errors */
842  if (!feed_article(art, function, &counter, use_current, outpath, group))
843  handle_EPIPE();
844  }
845  }
846  }
847  untag_all_articles(); /* TODO: this will untag even on partial failure */
849  break;
850 
851  case FEED_HOT: /* hot (auto-selected) articles */
852  case FEED_PATTERN: /* pattern matched articles */
853  {
854  struct regex_cache cache = { NULL, NULL };
855 
856  if ((feed_type == FEED_PATTERN) && tinrc.wildcard && !(compile_regex(tinrc.default_pattern, &cache, PCRE_CASELESS)))
857  break;
858 
859  for_each_art(art) {
860  if (feed_type == FEED_PATTERN) {
861  if (!match_regex(arts[art].subject, tinrc.default_pattern, &cache, TRUE))
862  continue;
863  } else if (!arts[art].selected)
864  continue;
865 
866  if (!feed_mark_function && (curr_group->attribute->process_only_unread && arts[art].status == ART_READ))
867  continue;
868 
869  arts[art].matched = TRUE;
870  counter.max++;
871  }
872 
873  if (tinrc.wildcard) {
874  FreeIfNeeded(cache.re);
875  FreeIfNeeded(cache.extra);
876  }
877  }
878 
879  /* I think we nest like this to preserve any 'ordering' of the arts */
880  for (i = 0; i < grpmenu.max; i++) {
882  if (!arts[art].matched)
883  continue;
884  arts[art].matched = FALSE;
885 
886  /* Keep going - don't abort on errors */
887  if (feed_article(art, function, &counter, use_current, outpath, group)) {
888  if (feed_type == FEED_HOT)
889  arts[art].selected = FALSE;
890  } else
891  handle_EPIPE();
892  }
893  }
895  break;
896 
897  default: /* Should never get here */
898  break;
899  } /* switch (feed_type) */
900 
901  /*
902  * Invoke post-processing if needed
903  * Work out what (if anything) needs to be redrawn
904  */
906  redraw_screen |= mail_check(mailbox); /* in case of sending to oneself */
907 
908  switch (function) {
909  case FEED_MARK_READ:
910  case FEED_MARK_UNREAD:
912  if (level == GROUP_LEVEL) {
913  no_next_unread = group_mark_postprocess(function, feed_type, respnum);
914  break;
915  }
916  if (level == THREAD_LEVEL)
917  no_next_unread = thread_mark_postprocess(function, feed_type, respnum);
918  break;
919 
920 #ifndef DONT_HAVE_PIPING
921  case FEED_PIPE:
922 got_epipe_while_piping:
923  if (got_epipe)
925  got_epipe = FALSE;
926  fflush(pipe_fp);
927  (void) pclose(pipe_fp);
929  my_printf(cCRLF);
930 # ifdef USE_CURSES
931  Raw(TRUE);
932  InitWin();
933 # endif /* USE_CURSES */
934  prompt_continue();
935 # ifndef USE_CURSES
936  Raw(TRUE);
937  InitWin();
938 # endif /* !USE_CURSES */
940  break;
941 #endif /* !DONT_HAVE_PIPING */
942 
943  case FEED_SAVE:
944  case FEED_AUTOSAVE:
945  if (num_save == 0) {
947  break;
948  }
949 
950  if (redraw_screen) {
951  currmenu->redraw();
953  }
954 
955  print_save_summary(feed_type, counter.total);
956  if (pproc_func != POSTPROCESS_NO) {
957  t_bool delete_post_proc = FALSE;
958 
960  delete_post_proc = TRUE;
961  else {
962  if (function != FEED_AUTOSAVE) {
964  delete_post_proc = TRUE;
965  }
966  }
967  post_processed_ok = post_process_files(pproc_func, delete_post_proc);
968  }
969  free_save_array(); /* NB: This is where num_save etc.. gets purged */
970 
971  if (level != PAGE_LEVEL)
972  mark_saved = curr_group->attribute->mark_saved_read;
973  break;
974 
975  default:
976  break;
977  }
978 
979  if (mark_saved || post_processed_ok)
981 
982  if (level == PAGE_LEVEL && !feed_mark_function) {
985 
986  /*
987  * If we were using the paged art return to our former position
988  */
989  if (use_current)
990  curr_line = saved_curr_line;
991 
992  if (redraw_screen)
993  draw_page(group->name, 0);
994  else {
995  if (function == FEED_PIPE)
996  clear_message();
997  }
998  } else {
999  if (redraw_screen) {
1000  currmenu->redraw();
1001  redraw_screen = FALSE;
1002  }
1003  }
1004 
1005  /*
1006  * Finally print a status message
1007  */
1008  switch (function) {
1009  case FEED_MAIL:
1012  else
1013  info_message(_(txt_articles_mailed), counter.success, PLURAL(counter.success, txt_article));
1014  break;
1015 
1016  case FEED_MARK_READ:
1017  case FEED_MARK_UNREAD:
1018  if (no_next_unread)
1020  else {
1021  if (counter.success && level != PAGE_LEVEL) {
1022  const char *ptr;
1023 
1024  ptr = function == FEED_MARK_READ ? _(txt_marked_as_read) : _(txt_marked_as_unread);
1025  if (feed_type == FEED_THREAD) {
1027  } else if (feed_type == FEED_ARTICLE) {
1029  } else {
1031  info_message(ptr, counter.success, counter.max, PLURAL(counter.max, txt_article));
1032  }
1033  }
1034  }
1035  break;
1036 
1037 #ifndef DONT_HAVE_PIPING
1038  case FEED_PIPE:
1039  info_message(_(txt_articles_piped), counter.success, PLURAL(counter.success, txt_article), tinrc.default_pipe_command);
1040  break;
1041 #endif /* !DONT_HAVE_PIPING */
1042 
1043 #ifndef DISABLE_PRINTING
1044  case FEED_PRINT:
1045  info_message(_(txt_articles_printed), counter.success, PLURAL(counter.success, txt_article));
1046  break;
1047 #endif /* !DISABLE_PRINTING */
1048 
1049  case FEED_SAVE: /* Reporting done earlier */
1050  case FEED_AUTOSAVE:
1051  default:
1052  break;
1053  }
1054  return no_next_unread ? 1 : 0;
1055 }
1056 
1057 
1058 #ifndef DISABLE_PRINTING
1059 static t_bool
1061  const char *command,
1062  int respnum,
1063  t_openartinfo *artinfo)
1064 {
1065  FILE *fp;
1066  struct t_header *hdr = &artinfo->hdr;
1067  t_bool ok;
1068 # ifdef DONT_HAVE_PIPING
1069  char cmd[PATH_LEN], file[PATH_LEN];
1070  int i;
1071 # endif /* DONT_HAVE_PIPING */
1072 
1073 # ifdef DONT_HAVE_PIPING
1074  snprintf(file, sizeof(file), TIN_PRINTFILE, respnum);
1075  if ((fp = fopen(file, "w")) == NULL) /* TODO: issue a more correct error message here */
1076 # else
1077  if ((fp = popen(command, "w")) == NULL)
1078 # endif /* DONT_HAVE_PIPING */
1079  {
1080  perror_message(_(txt_command_failed), command);
1081  return FALSE;
1082  }
1083 
1084  rewind(artinfo->raw);
1085  if (!curr_group->attribute->print_header && !(fseek(artinfo->raw, hdr->ext->offset, SEEK_SET))) { /* -> start of body */
1086  if (hdr->newsgroups)
1087  fprintf(fp, "Newsgroups: %s\n", hdr->newsgroups);
1088  if (arts[respnum].from == arts[respnum].name || arts[respnum].name == NULL)
1089  fprintf(fp, "From: %s\n", arts[respnum].from);
1090  else
1091  fprintf(fp, "From: %s <%s>\n", arts[respnum].name, arts[respnum].from);
1092  if (hdr->subj)
1093  fprintf(fp, "Subject: %s\n", hdr->subj);
1094  if (hdr->date)
1095  fprintf(fp, "Date: %s\n\n", hdr->date);
1096  }
1097 
1098  ok = copy_fp(artinfo->raw, fp);
1099 
1100 # ifdef DONT_HAVE_PIPING
1101  fclose(fp);
1102  i = snprintf(cmd, sizeof(cmd), "%s %s", command, file);
1103  if (i > 0 && i < (int) sizeof(cmd))
1104  invoke_cmd(cmd);
1105  else {
1107  unlink(file);
1108  return FALSE;
1109  }
1110  unlink(file);
1111 # else
1112  fflush(fp);
1113  pclose(fp);
1114 # endif /* DONT_HAVE_PIPING */
1115 
1116  return ok;
1117 }
1118 #endif /* !DISABLE_PRINTING */
name
const char * name
Definition: signal.c:117
t_config::wildcard
int wildcard
Definition: tinrc.h:155
txt_delete_processed_files
constext txt_delete_processed_files[]
Definition: lang.c:162
t_header::date
char * date
Definition: rfc2046.h:132
txt_saving
constext txt_saving[]
Definition: lang.c:816
txt_command_failed
constext txt_command_failed[]
Definition: lang.c:150
GROUP_LEVEL
#define GROUP_LEVEL
Definition: tin.h:1102
POST_PROC_YES
#define POST_PROC_YES
Definition: tin.h:1167
_
#define _(Text)
Definition: tin.h:94
txt_prefix_tagged
constext txt_prefix_tagged[]
Definition: lang.c:732
post_process_files
t_bool post_process_files(t_function proc_type_func, t_bool auto_delete)
Definition: save.c:746
FEED_PIPE
#define FEED_PIPE
Definition: tin.h:1115
save_and_process_art
t_bool save_and_process_art(t_openartinfo *artinfo, struct t_article *artptr, t_bool is_mailbox, const char *inpath, int max, t_bool post_process)
Definition: save.c:469
pipe_fp
static FILE * pipe_fp
Definition: feed.c:55
THREAD_LEVEL
#define THREAD_LEVEL
Definition: tin.h:1103
HIST_MAIL_ADDRESS
@ HIST_MAIL_ADDRESS
Definition: extern.h:1543
txt_warn_not_all_arts_saved
constext txt_warn_not_all_arts_saved[]
Definition: lang.c:977
t_attribute::mark_saved_read
unsigned mark_saved_read
Definition: tin.h:1617
t_config::printer
char printer[LEN]
Definition: tinrc.h:78
txt_cannot_post
constext txt_cannot_post[]
Definition: lang.c:130
t_group
Definition: tin.h:1772
t_attribute::post_process_type
unsigned post_process_type
Definition: tin.h:1654
str_trim
char * str_trim(char *string)
Definition: string.c:532
mailbox
char mailbox[PATH_LEN]
Definition: init.c:91
feed_article
static t_bool feed_article(int art, int function, struct t_counters *counter, t_bool use_current, const char *data, struct t_group *group)
Definition: feed.c:418
thread_mark_postprocess
t_bool thread_mark_postprocess(int function, t_function feed_type, int respnum)
Definition: thread.c:1606
txt_save
constext txt_save[]
Definition: lang.c:805
art_mark
void art_mark(struct t_group *group, struct t_article *art, int flag)
Definition: newsrc.c:1571
t_attribute::auto_save
unsigned auto_save
Definition: tin.h:1610
t_article::selected
t_bool selected
Definition: tin.h:1533
txt_supersede_article
constext txt_supersede_article[]
Definition: lang.c:852
openartinfo
Definition: rfc2046.h:183
FEED_PATTERN
@ FEED_PATTERN
Definition: keymap.h:179
REDIRECT_OUTPUT
#define REDIRECT_OUTPUT
Definition: tin.h:2114
t_counters::total
int total
Definition: feed.c:62
txt_art_thread_regex_tag
constext txt_art_thread_regex_tag[]
Definition: lang.c:68
txt_mark
constext txt_mark[]
Definition: lang.c:623
cCRLF
#define cCRLF
Definition: tcurses.h:150
grpmenu
t_menu grpmenu
Definition: group.c:83
for_each_art_in_thread
#define for_each_art_in_thread(x, y)
Definition: tin.h:2212
art
static t_openartinfo * art
Definition: cook.c:78
tinrc
struct t_config tinrc
Definition: init.c:191
txt_repost
constext txt_repost[]
Definition: lang.c:779
perror_message
void perror_message(const char *fmt,...)
Definition: screen.c:220
wait_message
void wait_message(unsigned int sdelay, const char *fmt,...)
Definition: screen.c:133
FEED_SAVE
#define FEED_SAVE
Definition: tin.h:1117
FreeAndNull
#define FreeAndNull(p)
Definition: tin.h:2204
curr_group
struct t_group * curr_group
Definition: group.c:55
txt_articles_mailed
constext txt_articles_mailed[]
Definition: lang.c:77
regex_cache::extra
pcre_extra * extra
Definition: tin.h:1919
feed_supersede_article_keys
struct keylist feed_supersede_article_keys
Definition: keymap.c:64
fmt_string
char * fmt_string(const char *fmt,...)
Definition: string.c:1379
txt_prefix_hot
constext txt_prefix_hot[]
Definition: lang.c:731
t_config::interactive_mailer
int interactive_mailer
Definition: tinrc.h:256
tcurses.h
txt_no_next_unread_art
constext txt_no_next_unread_art[]
Definition: lang.c:681
invoke_cmd
t_bool invoke_cmd(const char *nam)
Definition: misc.c:793
t_menu::max
int max
Definition: tin.h:2007
info_message
void info_message(const char *fmt,...)
Definition: screen.c:102
t_config::beginner_level
t_bool beginner_level
Definition: tinrc.h:208
tin.h
CMDLINE_SAVEDIR
#define CMDLINE_SAVEDIR
Definition: tin.h:1094
t_counters::max
int max
Definition: feed.c:63
can_post
t_bool can_post
Definition: nntplib.c:32
FEED_PRINT
#define FEED_PRINT
Definition: tin.h:1116
cmdline
struct t_cmdlineopts cmdline
Definition: init.c:189
show_progress
void show_progress(const char *txt, t_artnum count, t_artnum total)
Definition: screen.c:477
txt_thread_upper
constext txt_thread_upper[]
Definition: lang.c:877
group_mark_postprocess
t_bool group_mark_postprocess(int function, t_function feed_type, int respnum)
Definition: group.c:1688
prompt_default_string
t_bool prompt_default_string(const char *prompt, char *buf, int buf_len, char *default_prompt, int which_hist)
Definition: prompt.c:108
create_path
t_bool create_path(const char *path)
Definition: save.c:605
PATH_LEN
#define PATH_LEN
Definition: tin.h:837
t_art_stat
Definition: tin.h:1941
expand_feed_filename
static t_bool expand_feed_filename(char *outpath, size_t outpath_len, const char *path)
Definition: feed.c:154
supersede
static t_bool supersede
Definition: feed.c:52
prompt_string_default
char * prompt_string_default(const char *prompt, char *def, const char *failtext, int history)
Definition: prompt.c:558
t_attribute::savefile
char * savefile
Definition: tin.h:1567
t_attribute::process_only_unread
unsigned process_only_unread
Definition: tin.h:1625
Raw
void Raw(int state)
Definition: curses.c:624
stat_thread
int stat_thread(int n, struct t_art_stat *sbuf)
Definition: thread.c:1118
curr_line
int curr_line
Definition: page.c:56
FEED_REPOST
#define FEED_REPOST
Definition: tin.h:1119
strwidth
int strwidth(const char *str)
Definition: string.c:1043
sized_message
char * sized_message(char **result, const char *format, const char *subject)
Definition: prompt.c:646
my_strncpy
void my_strncpy(char *p, const char *q, size_t n)
Definition: string.c:190
DEFAULT_SAVEDIR
#define DEFAULT_SAVEDIR
Definition: tin.h:632
draw_page
void draw_page(const char *group, int part)
Definition: page.c:1172
FEED_KEY_REPOST
@ FEED_KEY_REPOST
Definition: keymap.h:182
txt_pipe
constext txt_pipe[]
Definition: lang.c:1165
homedir
char homedir[PATH_LEN]
Definition: init.c:78
t_article::archive
struct t_archive * archive
Definition: tin.h:1524
t_header::subj
char * subj
Definition: rfc2046.h:133
PLURAL
#define PLURAL(x, y)
Definition: tin.h:1053
art_open
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:1547
POSTED_OK
#define POSTED_OK
Definition: tin.h:1231
txt_print
constext txt_print[]
Definition: lang.c:1157
txt_repost_group
constext txt_repost_group[]
Definition: lang.c:781
t_header::newsgroups
char * newsgroups
Definition: rfc2046.h:136
ART_READ
#define ART_READ
Definition: tin.h:1320
strfpath
int strfpath(const char *format, char *str, size_t maxsize, struct t_group *group, t_bool expand_all)
Definition: misc.c:1701
buf
static char buf[16]
Definition: langinfo.c:50
FEED_SUPERSEDE
@ FEED_SUPERSEDE
Definition: keymap.h:183
feed_articles
int feed_articles(int function, int level, t_function type, struct t_group *group, int respnum)
Definition: feed.c:571
FreeIfNeeded
#define FreeIfNeeded(p)
Definition: tin.h:2203
FEED_THREAD
@ FEED_THREAD
Definition: keymap.h:177
FEED_MAIL
#define FEED_MAIL
Definition: tin.h:1114
t_attribute::savedir
char * savedir
Definition: tin.h:1566
t_art_stat::selected_total
int selected_total
Definition: tin.h:1948
FEED_RANGE
@ FEED_RANGE
Definition: keymap.h:180
txt_mail_art_to
constext txt_mail_art_to[]
Definition: lang.c:610
txt_supersede_group
constext txt_supersede_group[]
Definition: lang.c:853
txt_save_filename
constext txt_save_filename[]
Definition: lang.c:808
txt_marked_arts_as_read
constext txt_marked_arts_as_read[]
Definition: lang.c:621
txt_saved_nothing
constext txt_saved_nothing[]
Definition: lang.c:812
repost_article
int repost_article(const char *groupname, int respnum, t_bool supersede, t_openartinfo *artinfo)
Definition: post.c:4034
PCRE_CASELESS
#define PCRE_CASELESS
Definition: pcre.h:98
t_article::inrange
t_bool inrange
Definition: tin.h:1534
cCOLS
int cCOLS
Definition: curses.c:53
txt_pipe_to_command
constext txt_pipe_to_command[]
Definition: lang.c:1166
LEN
#define LEN
Definition: tin.h:854
t_article::status
unsigned int status
Definition: tin.h:1529
mail_check
t_bool mail_check(const char *mailbox_name)
Definition: misc.c:911
feed_type_keys
struct keylist feed_type_keys
Definition: keymap.c:65
t_function
enum defined_functions t_function
Definition: keymap.h:373
txt_printing
constext txt_printing[]
Definition: lang.c:1158
strstr
char * strstr(const char *text, const char *pattern)
Definition: string.c:327
t_cmdlineopts::savedir
char savedir[255]
Definition: tin.h:1470
num_save
int num_save
Definition: memory.c:57
txt_no_command
constext txt_no_command[]
Definition: lang.c:1164
txt_feed_pattern
constext txt_feed_pattern[]
Definition: lang.c:276
POST_PROC_SHAR
#define POST_PROC_SHAR
Definition: tin.h:1166
t_counters
Definition: feed.c:60
currmenu
t_menu * currmenu
Definition: init.c:165
t_config::default_repost_group
char default_repost_group[LEN]
Definition: tinrc.h:84
which_thread
int which_thread(int n)
Definition: thread.c:1003
t_menu::redraw
void(* redraw)(void)
Definition: tin.h:2009
part::offset
long offset
Definition: rfc2046.h:103
txt_mail
constext txt_mail[]
Definition: lang.c:608
set_xclick_off
void set_xclick_off(void)
Definition: curses.c:703
get_from_name
void get_from_name(char *from_name, struct t_group *thisgrp)
Definition: header.c:307
compile_regex
t_bool compile_regex(const char *regex, struct regex_cache *cache, int options)
Definition: regex.c:111
copy_fp
t_bool copy_fp(FILE *fp_ip, FILE *fp_op)
Definition: misc.c:179
is_mailbox
static t_bool is_mailbox
Definition: feed.c:50
regex_cache::re
pcre * re
Definition: tin.h:1918
untag_all_articles
t_bool untag_all_articles(void)
Definition: tags.c:318
FEED_MARK_UNREAD
#define FEED_MARK_UNREAD
Definition: tin.h:1121
t_attribute::print_header
unsigned print_header
Definition: tin.h:1623
func_to_key
char func_to_key(t_function func, const struct keylist keys)
Definition: keymap.c:124
t_config::default_pipe_command
char default_pipe_command[LEN]
Definition: tinrc.h:73
save
struct t_save * save
Definition: memory.c:70
t_attribute::delete_tmp_files
unsigned delete_tmp_files
Definition: tin.h:1612
ART_WILL_RETURN
#define ART_WILL_RETURN
Definition: tin.h:1322
POSTPROCESS_NO
@ POSTPROCESS_NO
Definition: keymap.h:327
EndWin
void EndWin(void)
Definition: curses.c:368
SEEK_SET
#define SEEK_SET
Definition: tin.h:2441
bool_not
#define bool_not(b)
Definition: bool.h:81
t_header
Definition: rfc2046.h:126
txt_no_mail_address
constext txt_no_mail_address[]
Definition: lang.c:676
PAGE_LEVEL
#define PAGE_LEVEL
Definition: tin.h:1104
my_printf
#define my_printf
Definition: tcurses.h:169
t_config::default_pattern
char default_pattern[LEN]
Definition: tinrc.h:83
feed_post_process_keys
struct keylist feed_post_process_keys
Definition: keymap.c:63
confirm
static t_bool confirm
Definition: feed.c:49
MAXKEYLEN
#define MAXKEYLEN
Definition: keymap.h:136
t_cmdlineopts::args
unsigned int args
Definition: tin.h:1471
t_menu::curr
int curr
Definition: tin.h:2006
t_group::name
char * name
Definition: tin.h:1773
InitWin
void InitWin(void)
Definition: curses.c:355
txt_article_upper
constext txt_article_upper[]
Definition: lang.c:76
get_feed_key
static t_function get_feed_key(int function, int level, struct t_group *group, struct t_art_stat *thread, int respnum)
Definition: feed.c:230
FEED_HOT
@ FEED_HOT
Definition: keymap.h:178
txt_no_filename
constext txt_no_filename[]
Definition: lang.c:671
FALSE
#define FALSE
Definition: bool.h:70
STRCPY
#define STRCPY(dst, src)
Definition: tin.h:814
FEED_AUTOSAVE
#define FEED_AUTOSAVE
Definition: tin.h:1118
num_of_tagged_arts
int num_of_tagged_arts
Definition: tags.c:50
mail_to_someone
int mail_to_someone(const char *address, t_bool confirm_to_mail, t_openartinfo *artinfo, const struct t_group *group)
Definition: post.c:3360
print_save_summary
static void print_save_summary(t_function type, int fed)
Definition: feed.c:359
t_config::default_save_file
char default_save_file[PATH_LEN]
Definition: tinrc.h:85
txt_no_match
constext txt_no_match[]
Definition: lang.c:678
regex_cache
Definition: tin.h:1917
HIST_REGEX_PATTERN
@ HIST_REGEX_PATTERN
Definition: extern.h:1549
get_post_proc_type
static t_function get_post_proc_type(void)
Definition: feed.c:185
joinpath
void joinpath(char *result, size_t result_size, const char *dir, const char *file)
Definition: joinpath.c:50
ART_UNREAD
#define ART_UNREAD
Definition: tin.h:1321
txt_articles_piped
constext txt_articles_piped[]
Definition: lang.c:1162
txt_marked_as_read
constext txt_marked_as_read[]
Definition: lang.c:619
FEED_MARK_READ
#define FEED_MARK_READ
Definition: tin.h:1120
snprintf
#define snprintf
Definition: tin.h:2417
txt_piping
constext txt_piping[]
Definition: lang.c:1167
openartinfo::raw
FILE * raw
Definition: rfc2046.h:188
openartinfo::hdr
struct t_header hdr
Definition: rfc2046.h:185
error_message
void error_message(unsigned int sdelay, const char *fmt,...)
Definition: screen.c:184
pproc_func
static t_function pproc_func
Definition: feed.c:53
t_group::attribute
struct t_attribute * attribute
Definition: tin.h:1790
FEED_TAGGED
@ FEED_TAGGED
Definition: keymap.h:181
GLOBAL_ABORT
@ GLOBAL_ABORT
Definition: keymap.h:186
txt_no_group
constext txt_no_group[]
Definition: lang.c:672
txt_external_mail_done
constext txt_external_mail_done[]
Definition: lang.c:269
art_close
void art_close(t_openartinfo *artinfo)
Definition: rfc2046.c:1604
handle_EPIPE
#define handle_EPIPE()
Definition: feed.c:80
txt_choose_post_process_type
constext txt_choose_post_process_type[]
Definition: lang.c:145
txt_saved_to
constext txt_saved_to[]
Definition: lang.c:814
redraw_screen
static t_bool redraw_screen
Definition: feed.c:51
constext
const typedef char constext
Definition: tin.h:1968
range_active
t_bool range_active
Definition: init.c:147
t_art_stat::total
int total
Definition: tin.h:1943
txt_mailbox
constext txt_mailbox[]
Definition: lang.c:609
t_config::default_mail_address
char default_mail_address[HEADER_LEN]
Definition: tinrc.h:70
t_article::matched
t_bool matched
Definition: tin.h:1535
POSTED_NONE
#define POSTED_NONE
Definition: tin.h:1229
t_bool
unsigned t_bool
Definition: bool.h:77
txt_articles_printed
constext txt_articles_printed[]
Definition: lang.c:1155
FEED_ARTICLE
@ FEED_ARTICLE
Definition: keymap.h:176
errno
int errno
POSTED_REDRAW
#define POSTED_REDRAW
Definition: tin.h:1230
get_save_filename
static char * get_save_filename(struct t_group *group, int function, char *filename, int filelen, int respnum)
Definition: feed.c:92
printascii
char * printascii(char *buf, int ch)
Definition: keymap.c:271
t_save::mailbox
t_bool mailbox
Definition: tin.h:1925
INTERACTIVE_NONE
@ INTERACTIVE_NONE
Definition: tin.h:1157
prompt_yn
int prompt_yn(const char *prompt, t_bool default_answer)
Definition: prompt.c:165
match_regex
t_bool match_regex(const char *string, char *pattern, struct regex_cache *cache, t_bool icase)
Definition: regex.c:59
TRUE
#define TRUE
Definition: bool.h:74
got_epipe
static t_bool got_epipe
Definition: feed.c:56
for_each_art
#define for_each_art(x)
Definition: tin.h:2211
txt_saved_to_range
constext txt_saved_to_range[]
Definition: lang.c:815
POST_PROC_NO
#define POST_PROC_NO
Definition: tin.h:1165
HIST_PIPE_COMMAND
@ HIST_PIPE_COMMAND
Definition: extern.h:1546
arts
struct t_article * arts
Definition: memory.c:69
prompt_continue
void prompt_continue(void)
Definition: prompt.c:774
POSTPROCESS_SHAR
@ POSTPROCESS_SHAR
Definition: keymap.h:328
txt_no_marked_arts
constext txt_no_marked_arts[]
Definition: lang.c:677
set_range
t_bool set_range(int level, int min, int max, int curr)
Definition: tags.c:353
txt_marked_as_unread
constext txt_marked_as_unread[]
Definition: lang.c:620
set_signal_catcher
void set_signal_catcher(int flag)
Definition: signal.c:526
arts_selected
t_bool arts_selected(void)
Definition: tags.c:589
t_header::ext
t_part * ext
Definition: rfc2046.h:146
t_header::from
char * from
Definition: rfc2046.h:128
GLOBAL_QUIT
@ GLOBAL_QUIT
Definition: keymap.h:210
print_file
static t_bool print_file(const char *command, int respnum, t_openartinfo *artinfo)
Definition: feed.c:1060
unlink
#define unlink(file)
Definition: tin.h:384
prompt_slk_response
t_function prompt_slk_response(t_function default_func, const struct keylist keys, const char *fmt,...)
Definition: prompt.c:670
DIRSEP
#define DIRSEP
Definition: tin.h:2104
HIST_SAVE_FILE
@ HIST_SAVE_FILE
Definition: extern.h:1551
HIST_REPOST_GROUP
@ HIST_REPOST_GROUP
Definition: extern.h:1550
pgart
t_openartinfo pgart
Definition: page.c:63
txt_marked_arts_as_unread
constext txt_marked_arts_as_unread[]
Definition: lang.c:622
t_counters::success
int success
Definition: feed.c:61
free_save_array
void free_save_array(void)
Definition: memory.c:481
t_config::force_screen_redraw
t_bool force_screen_redraw
Definition: tinrc.h:213
NOT_ASSIGNED
@ NOT_ASSIGNED
Definition: keymap.h:149
POSTPROCESS_YES
@ POSTPROCESS_YES
Definition: keymap.h:329
clear_message
void clear_message(void)
Definition: screen.c:243
progress_mesg
static const char * progress_mesg
Definition: rfc2046.c:76