From urs at tin.org Wed Jun 7 14:49:28 2023 From: urs at tin.org (Urs =?UTF-8?Q?Jan=C3=9Fen?=) Date: Wed, 07 Jun 2023 14:49:28 +0200 Subject: [tin-dev] -C and timeout after reconnect Message-ID: I noticed that when the connection was closed from the servers side while I was composing an article the reconnect and post does succeed but tin directly terminates afterwards with signal_handler(SIGALRM) ("get_server() %d sec elapsed without response", tinrc.nntp_read_timeout_secs) Eneabeling DEBUG_IO in debug.h and capturing stderr was useful. nntp_read_timeout_secs is likely elapsed before resending the commands on reconnect and not reset while doing so. Strangely I could only see this when running tin with -C (and the server does support it (INN 2.6.1)). The following should fix that - but please could someone review it? === modified file 'src/nntplib.c' --- src/nntplib.c 2023-06-01 09:34:32 +0000 +++ src/nntplib.c 2023-06-07 10:39:49 +0000 @@ -930,6 +930,9 @@ /* reset signal_context */ signal_context = save_signal_context; +# if defined(HAVE_ALARM) && defined(SIGALRM) + alarm((unsigned) tinrc.nntp_read_timeout_secs); +# endif /* HAVE_ALARM && SIGALRM */ clear_message(); strcpy(buf, last_put); /* Keep copy here, it will be clobbered a lot otherwise */ @@ -954,6 +957,10 @@ retry = NNTP_TRY_RECONNECT; } +# if defined(HAVE_ALARM) && defined(SIGALRM) + alarm(0); +# endif /* HAVE_ALARM && SIGALRM */ + return retry; } From dennis at d--p.de Wed Jun 7 19:43:53 2023 From: dennis at d--p.de (Dennis Preiser) Date: Wed, 7 Jun 2023 19:43:53 +0200 Subject: [tin-dev] -C and timeout after reconnect In-Reply-To: References: Message-ID: On Wed, Jun 07, 2023 at 02:49:28PM +0200, Urs Jan?en wrote: > I noticed that when the connection was closed from the servers side > while I was composing an article the reconnect and post does succeed > but tin directly terminates afterwards with signal_handler(SIGALRM) > ("get_server() %d sec elapsed without response", tinrc.nntp_read_timeout_secs) > Strangely I could only see this when running tin with -C (and the server > does support it (INN 2.6.1)). > > The following should fix that - but please could someone review it? The code looks good to me and seems to make sense, but it doesn't fix the problem for me. If I start tin with '-QACg $SERVER', write a followup and wait for the server to close the connection, tin reconnects and posts, but then exits with 'NNTP connection error. Exiting...'. Interestingly it works when I call tin with '-D 1' additionally. Dennis From urs at tin.org Thu Jun 22 11:35:11 2023 From: urs at tin.org (Urs =?UTF-8?Q?Jan=C3=9Fen?=) Date: Thu, 22 Jun 2023 11:35:11 +0200 Subject: [tin-dev] [PATCH] no longer pass groupname to draw_page()/toggle_raw()/draw_page_header() Message-ID: if I didn't overlook anything it was used in draw_page_header() only, but that uses curr_group anyway and thus could use curr_group->name instead. === modified file 'include/proto.h' --- include/proto.h 2023-01-30 05:14:28 +0000 +++ include/proto.h 2023-06-22 09:21:56 +0000 @@ -491,10 +491,10 @@ /* page.c */ extern int show_page(struct t_group *group, int start_respnum, int *threadnum); extern void display_info_page(int part); -extern void draw_page(const char *group, int part); +extern void draw_page(int part); extern void info_pager(FILE *info_fh, const char *title, t_bool wrap_at_ends); extern void resize_article(t_bool wrap_lines, t_openartinfo *artinfo); -extern void toggle_raw(struct t_group *group); +extern void toggle_raw(void); /* parsdate.y */ extern time_t parsedate(char *p, TIMEINFO *now); === modified file 'src/feed.c' --- src/feed.c 2023-05-10 14:21:31 +0000 +++ src/feed.c 2023-06-22 09:23:15 +0000 @@ -984,7 +984,7 @@ curr_line = saved_curr_line; if (redraw_screen) - draw_page(group->name, 0); + draw_page(0); else { if (function == FEED_PIPE) clear_message(); === modified file 'src/page.c' --- src/page.c 2023-02-22 07:57:18 +0000 +++ src/page.c 2023-06-22 09:23:34 +0000 @@ -106,7 +106,7 @@ static t_function url_left(void); static t_function url_right(void); static void build_url_line(int i); -static void draw_page_header(const char *group); +static void draw_page_header(void); static void draw_percent_mark(long cur_num, long max_num); static void draw_url_arrow(void); static void free_url_list(void); @@ -369,7 +369,7 @@ case GLOBAL_SHELL_ESCAPE: XFACE_CLEAR(); shell_escape(); - draw_page(group->name, 0); + draw_page(0); break; #endif /* !NO_SHELL_ESCAPE */ @@ -383,13 +383,13 @@ case GLOBAL_PAGE_UP: if (activate_last_ctrl_l()) - draw_page(group->name, 0); + draw_page(0); else { if (curr_line == 0) info_message(_(txt_begin_of_art)); else { curr_line -= ((tinrc.scroll_lines == -2) ? ARTLINES / 2 : ARTLINES); - draw_page(group->name, 0); + draw_page(0); } } break; @@ -397,7 +397,7 @@ case GLOBAL_PAGE_DOWN: /* page down or next response */ case PAGE_NEXT_UNREAD: if (!((func == PAGE_NEXT_UNREAD) && (tinrc.goto_next_unread & GOTO_NEXT_UNREAD_TAB)) && deactivate_next_ctrl_l()) - draw_page(group->name, 0); + draw_page(0); else { if (curr_line + ARTLINES >= artlines) { /* End is already on screen */ switch (func) { @@ -421,7 +421,7 @@ if (tinrc.scroll_lines == -1) /* formerly show_last_line_prev_page */ curr_line--; - draw_page(group->name, 0); + draw_page(0); } } break; @@ -438,7 +438,7 @@ if (reveal_ctrl_l_lines > -1 || curr_line != 0) { reveal_ctrl_l_lines = -1; curr_line = 0; - draw_page(group->name, 0); + draw_page(0); } break; @@ -447,13 +447,13 @@ reveal_ctrl_l_lines = artlines - 1; /* Display a full last page for neatness */ curr_line = artlines - ARTLINES; - draw_page(group->name, 0); + draw_page(0); } break; case GLOBAL_LINE_UP: if (activate_last_ctrl_l()) - draw_page(group->name, 0); + draw_page(0); else { if (curr_line == 0) { info_message(_(txt_begin_of_art)); @@ -462,13 +462,13 @@ i = scroll_page(KEYMAP_UP); curr_line += i; - draw_page(group->name, i); + draw_page(i); } break; case GLOBAL_LINE_DOWN: if (deactivate_next_ctrl_l()) - draw_page(group->name, 0); + draw_page(0); else { if (curr_line + ARTLINES >= artlines) { info_message(_(txt_end_of_art)); @@ -477,7 +477,7 @@ i = scroll_page(KEYMAP_DOWN); curr_line += i; - draw_page(group->name, i); + draw_page(i); } break; @@ -582,7 +582,7 @@ if (func == GLOBAL_SEARCH_SUBJECT_BACKWARD && !reveal_ctrl_l) { reveal_ctrl_l_lines = curr_line + ARTLINES - 1; - draw_page(group->name, 0); + draw_page(0); } process_search(&curr_line, (size_t) artlines, (size_t) ARTLINES, PAGE_LEVEL); break; @@ -634,7 +634,7 @@ case PAGE_PGP_CHECK_ARTICLE: XFACE_SUPPRESS(); if (pgp_check_article(&pgart)) - draw_page(group->name, 0); + draw_page(0); XFACE_SHOW(); break; #endif /* HAVE_PGP_GPG */ @@ -644,12 +644,12 @@ show_all_headers = bool_not(show_all_headers); resize_article(TRUE, &pgart); /* Also recooks it.. */ curr_line = 0; - draw_page(group->name, 0); + draw_page(0); break; case PAGE_TOGGLE_RAW: /* toggle display of whole 'raw' article */ XFACE_CLEAR(); - toggle_raw(group); + toggle_raw(); break; case PAGE_TOGGLE_TEX2ISO: /* toggle German TeX to ISO latin1 style conversion */ @@ -659,14 +659,14 @@ pgart.tex2iso = FALSE; resize_article(TRUE, &pgart); /* Also recooks it.. */ - draw_page(group->name, 0); + draw_page(0); info_message(_(txt_toggled_tex2iso), txt_onoff[group->attribute->tex2iso_conv != FALSE ? 1 : 0]); break; case PAGE_TOGGLE_TABS: /* toggle tab stops 8 vs 4 */ tabwidth = (tabwidth == 8) ? 4 : 8; resize_article(TRUE, &pgart); /* Also recooks it.. */ - draw_page(group->name, 0); + draw_page(0); info_message(_(txt_toggled_tabwidth), tabwidth); break; @@ -679,7 +679,7 @@ */ if (hide_uue && curr_line + ARTLINES > artlines) curr_line = artlines - ARTLINES; - draw_page(group->name, 0); + draw_page(0); /* TODO: info_message()? */ break; @@ -690,7 +690,7 @@ curr_line = 0; } else reveal_ctrl_l_lines = artlines - 1; - draw_page(group->name, 0); + draw_page(0); /* TODO: info_message()? */ break; @@ -704,7 +704,7 @@ if ((n = find_artnum(old_artnum)) == -1 || which_thread(n) == -1) /* We have lost the thread */ return GRP_KILLED; this_resp = n; - draw_page(group->name, 0); + draw_page(0); info_message((func == GLOBAL_QUICK_FILTER_KILL) ? _(txt_info_add_kill) : _(txt_info_add_select)); } break; @@ -721,7 +721,7 @@ return GRP_KILLED; this_resp = n; } - draw_page(group->name, 0); + draw_page(0); break; case GLOBAL_EDIT_FILTER: @@ -736,17 +736,17 @@ return GRP_KILLED; this_resp = n; } - draw_page(group->name, 0); + draw_page(0); break; case GLOBAL_REDRAW_SCREEN: /* redraw current page of article */ my_retouch(); - draw_page(group->name, 0); + draw_page(0); break; case PAGE_TOGGLE_ROT13: /* toggle rot-13 mode */ rotate = rotate ? 0 : 13; - draw_page(group->name, 0); + draw_page(0); info_message(_(txt_toggled_rot13)); break; @@ -785,7 +785,7 @@ if (can_post || art_type != GROUP_TYPE_NEWS) { XFACE_SUPPRESS(); if (cancel_article(group, &arts[this_resp], this_resp)) - draw_page(group->name, 0); + draw_page(0); XFACE_SHOW(); } else info_message(_(txt_cannot_post)); @@ -794,7 +794,7 @@ case PAGE_EDIT_ARTICLE: /* edit an article (mailgroup only) */ XFACE_SUPPRESS(); if (art_edit(group, &arts[this_resp])) - draw_page(group->name, 0); + draw_page(0); XFACE_SHOW(); break; @@ -809,24 +809,24 @@ (void) post_response(group->name, this_resp, (func == PAGE_FOLLOWUP_QUOTE || func == PAGE_FOLLOWUP_QUOTE_HEADERS) ? TRUE : FALSE, func == PAGE_FOLLOWUP_QUOTE_HEADERS ? TRUE : FALSE, show_raw_article); - draw_page(group->name, 0); + draw_page(0); break; case GLOBAL_HELP: /* help */ XFACE_CLEAR(); show_help_page(PAGE_LEVEL, _(txt_art_pager_com)); - draw_page(group->name, 0); + draw_page(0); break; case GLOBAL_CONNECTION_INFO: XFACE_CLEAR(); show_connection_page(PAGE_LEVEL, _(txt_connection_info)); - draw_page(group->name, 0); + draw_page(0); break; case GLOBAL_TOGGLE_HELP_DISPLAY: /* toggle mini help menu */ toggle_mini_help(PAGE_LEVEL); - draw_page(group->name, 0); + draw_page(0); break; case GLOBAL_QUIT: /* return to index page */ @@ -840,14 +840,14 @@ case GLOBAL_TOGGLE_INVERSE_VIDEO: /* toggle inverse video */ toggle_inverse_video(); - draw_page(group->name, 0); + draw_page(0); show_inverse_video_status(); break; #ifdef HAVE_COLOR case GLOBAL_TOGGLE_COLOR: /* toggle color */ if (toggle_color()) { - draw_page(group->name, 0); + draw_page(0); show_color_status(); } break; @@ -867,7 +867,7 @@ return GRP_EXIT; } fixup_thread(this_resp, FALSE); - draw_page(group->name, 0); + draw_page(0); break; case PAGE_NEXT_ARTICLE: /* skip to next article */ @@ -921,7 +921,7 @@ case PAGE_REPLY: XFACE_CLEAR(); mail_to_author(group->name, this_resp, (func == PAGE_REPLY_QUOTE || func == PAGE_REPLY_QUOTE_HEADERS) ? TRUE : FALSE, func == PAGE_REPLY_QUOTE_HEADERS ? TRUE : FALSE, show_raw_article); - draw_page(group->name, 0); + draw_page(0); break; case PAGE_TAG: /* tag/untag article for saving */ @@ -939,7 +939,7 @@ case GLOBAL_POST: /* post a basenote */ XFACE_SUPPRESS(); if (post_article(group->name)) - draw_page(group->name, 0); + draw_page(0); XFACE_SHOW(); break; @@ -947,7 +947,7 @@ if (can_post || art_type != GROUP_TYPE_NEWS) { XFACE_SUPPRESS(); if (pickup_postponed_articles(FALSE, FALSE)) - draw_page(group->name, 0); + draw_page(0); XFACE_SHOW(); } else info_message(_(txt_cannot_post)); @@ -982,7 +982,7 @@ if (j != curr_line) { curr_line = j; - draw_page(group->name, 0); + draw_page(0); } break; @@ -992,7 +992,7 @@ case PAGE_TOGGLE_HIGHLIGHTING: word_highlight = bool_not(word_highlight); - draw_page(group->name, 0); + draw_page(0); info_message(_(txt_toggled_high), txt_onoff[word_highlight != FALSE ? 1 : 0]); break; @@ -1004,7 +1004,7 @@ attachment_page(&pgart); hide_uue = hide_uue_tmp; resize_article(TRUE, &pgart); - draw_page(group->name, 0); + draw_page(0); XFACE_SHOW(); break; @@ -1016,7 +1016,7 @@ resize_article(FALSE, &pgart); /* unbreak long lines */ success = url_page(); resize_article(TRUE, &pgart); /* rebreak long lines */ - draw_page(group->name, 0); + draw_page(0); if (!success) info_message(_(txt_url_done)); XFACE_SHOW(); @@ -1172,7 +1172,6 @@ */ void draw_page( - const char *group, int part) { int start, end; /* 1st, last line to draw */ @@ -1213,7 +1212,7 @@ */ if ((end - start >= ARTLINES) || (part == 0)) { ClearScreen(); - draw_page_header(group); + draw_page_header(); } else MoveCursor(0, 0); @@ -1324,7 +1323,7 @@ */ static void draw_page_header( - const char *group) + void) { char *buf, *tmp; int i; @@ -1394,7 +1393,7 @@ len = cCOLS - 2 * MAX(cur_pos, right_len) - 3; /* group name */ - if ((wtmp = char2wchar_t(group)) != NULL) { + if ((wtmp = char2wchar_t(curr_group->name)) != NULL) { /* wconvert_to_printable(wtmp, FALSE); */ if (tinrc.abbreviate_groupname) wtmp2 = abbr_wcsgroupname(wtmp, len); @@ -1638,9 +1637,9 @@ /* group name */ if (tinrc.abbreviate_groupname) - tmp = abbr_groupname(group, len); + tmp = abbr_groupname(curr_group->name, len); else - tmp = strunc(group, len); + tmp = strunc(curr_group->name, len); if ((i = strlen(tmp)) < len) len = i; @@ -1917,7 +1916,7 @@ reveal_ctrl_l_lines = -1; /* all ^L's active */ hide_uue = tinrc.hide_uue; - draw_page(group->name, 0); + draw_page(0); /* * Automatically invoke attachment viewing if requested @@ -1995,7 +1994,7 @@ switch (help_level) { case PAGE_LEVEL: - draw_page(curr_group->name, 0); + draw_page(0); break; case INFO_PAGER: @@ -2019,7 +2018,7 @@ */ void toggle_raw( - struct t_group *group) + void) { if (show_raw_article) { artline = pgart.cookl; @@ -2128,7 +2127,7 @@ } curr_line = 0; show_raw_article = bool_not(show_raw_article); - draw_page(group ? group->name : "", 0); + draw_page(0); } === modified file 'src/post.c' --- src/post.c 2023-05-10 14:21:31 +0000 +++ src/post.c 2023-06-22 09:23:40 +0000 @@ -3546,7 +3546,7 @@ resize_article(TRUE, &pgart); /* rebreak long lines */ if (raw_data) /* we've been in raw mode, reenter it */ - toggle_raw(group); + toggle_raw(); return (post_loop(POST_RESPONSE, group, POST_EDIT, _(txt_posting), art_type, start_line_offset)); } @@ -4139,7 +4139,7 @@ resize_article(TRUE, &pgart); /* rebreak long lines */ if (raw_data) /* we've been in raw mode */ - toggle_raw(group_find(group, FALSE)); + toggle_raw(); return ret_code; } === modified file 'src/signal.c' --- src/signal.c 2022-11-03 11:55:26 +0000 +++ src/signal.c 2023-06-22 09:23:28 +0000 @@ -307,7 +307,7 @@ case cPage: resize_article(TRUE, &pgart); - draw_page(curr_group->name, 0); + draw_page(0); break; case cPost: @@ -317,7 +317,7 @@ case cPostFup: resize_article(TRUE, &pgart); - draw_page(curr_group->name, 0); + draw_page(0); /* * Reset signal_context because draw_page() * sets signal_context to cPage. From urs at tin.org Tue Jun 27 22:26:40 2023 From: urs at tin.org (Urs =?UTF-8?Q?Jan=C3=9Fen?=) Date: Tue, 27 Jun 2023 22:26:40 +0200 Subject: [tin-dev] [PATCH] cmd execution in x_body Message-ID: like for x_headers and sigfile === modified file 'doc/tin.5' --- doc/tin.5 2023-06-27 09:32:29 +0000 +++ doc/tin.5 2023-06-27 17:59:45 +0000 @@ -645,7 +645,10 @@ .B x_body A piece of text that will be added at the start of a message body. If this string starts with a / or ~ then it is assumed to be the name of a file -containing the text to insert. +containing the text to insert. If the string starts with a ! then what +follows is assumed to be the path to a program to be executed to generate +the content. %G is expanded to the current news.group.name and %P is +expanded to the news.group.name with all '.' replaced by '/'. .TP .B x_comment_to Insert ''X\-Comment\-To:'' header, this is only useful in FIDO groups. === modified file 'src/post.c' --- src/post.c 2023-05-10 04:42:49 +0000 +++ src/post.c 2023-06-27 20:07:55 +0000 @@ -2690,7 +2690,6 @@ msg_add_x_headers(group->attribute->x_headers); start_line_offset = msg_write_headers(fp) + 1; - fprintf(fp, "\n"); /* add a newline to keep vi from bitching */ msg_free_headers(); start_line_offset += msg_add_x_body(fp, group->attribute->x_body); @@ -4821,7 +4820,7 @@ /* * Add an x_body attribute to an article if it exists. - * Can be a piece of text or the name of a file to append + * Can be a piece of text, the name of a file to append or a cmd. to execute * Returns the # of lines appended. */ static int @@ -4829,16 +4828,20 @@ FILE *fp_out, const char *body) { - FILE *fp; + FILE *fp = NULL; char *ptr; char file[PATH_LEN]; char line[HEADER_LEN]; int wrote = 0; - if (!body) + if (!body || !fp_out) return 0; - if (body[0] != '/' && body[0] != '~') { /* FIXME: Unix'ism */ + if (body[0] != '/' && body[0] != '~' && body[0] != '!') { + /* + * copy string as is, no \-format expansion + * if \n is needed the text must come from a file or command + */ STRCPY(line, body); if ((ptr = strrchr(line, '\n')) != NULL) *ptr = '\0'; @@ -4849,17 +4852,26 @@ if (!strfpath(body, file, sizeof(file), &CURR_GROUP, FALSE)) STRCPY(file, body); - if ((fp = fopen(file, "r")) != NULL) { - while (fgets(line, (int) sizeof(line), fp) != NULL) { - fputs(line, fp_out); - wrote++; - } +#ifndef DONT_HAVE_PIPING + if (file[0] == '!') { + if ((fp = popen(file + 1, "r")) == NULL) + return 0; + } +#endif /* !DONT_HAVE_PIPING */ + + if (!fp && ((fp = fopen(file, "r")) == NULL)) + return 0; + + while (fgets(line, (int) sizeof(line), fp) != NULL) { + fputs(line, fp_out); + wrote++; + } +#ifndef DONT_HAVE_PIPING + if (file[0] == '!') + pclose(fp); + else +#endif /* !DONT_HAVE_PIPING */ fclose(fp); - } - } - if (wrote > 1) { - fputc('\n', fp_out); - wrote++; } return wrote; }