Re: Patch
Dirk Nimmich <[email protected]>
| Newsgroups | gmane.network.tin.devel |
|---|---|
| Message-ID | <[email protected]> |
Dirk Nimmich wrote:
> Urs JanÃen wrote:
> > On Sun, Sep 17, 2006 at 01:19:10AM +0200, Dirk Nimmich wrote:
> > > Attached another patch for two other bugs mentioned in TODO.
> >
> > if you are in group level and directly enter an article via
> > GroupNextUnreadArtOrGrp ('TAB') and then press Quit ('q') in the pager
> > and press GroupNextUnreadArtOrGrp again you are back at the same article
> > instead of the next article in the thread/group.
>
> Ok, it seems that thread.c:451 is the crucial line.
It wasn't. :-) Instead the page struct hasn't been updated
accordingly in group.c.
See attached patch which also addresses some other things in TODO.
Side note: Regarding the return value of change_config_file() I did
some archaeological ;-) research to find out its original meaning. I
had to go back to tin 1.1 PL2 only to find that it had been used to
indicate a change of the tinrc variable that switched the kill file
on or off. In tin 1.1 PL3 or PL4 (I didn't find a PL3) the variable
was dropped and the kill (now: filter) file has always been used
since, but the return value and related code remained until now ...
Dirk
192-4.diff
(text/plain, 32 KB)
diff -Nur tin-1.9.2/doc/CHANGES tin-1.9.2-dn/doc/CHANGES --- tin-1.9.2/doc/CHANGES 2006-09-06 16:39:19.000000000 +0200 +++ tin-1.9.2-dn/doc/CHANGES 2006-10-08 15:59:00.000000000 +0200 @@ -2,8 +2,16 @@ U005) Dirk Nimmich <[email protected]> BUG. raw-mode didn't allow rot13 - BUG. can't 'V'iew mime-parts with (illegal) encoded filename - FIX. proto.h, feed.c, page.c, save.c + BUG. can't 'V'iew mime-parts with (illegally) encoded filename + BUG. CatchupNextUnread in page level didn't always work + BUG. 'C'atchup in pager was still not correct (we didn't ever enter the + next group) + BUG. fast/endless reconecction loop after a "200\n\r400\n\r" greeting + BUG. resent command on 503 error + ADD. rewrote NGLIMIT handling + REM. return value of change_config_file() + FIX. proto.h, tin.h, feed.c, group.c, nntplib.c, options_menu.c, page.c + post.c, save.c, select.c 015) Michael Bienia <[email protected]> BUG. 'l' from the pager doesn't reposition cursor to last viewed diff -Nur tin-1.9.2/doc/TODO tin-1.9.2-dn/doc/TODO --- tin-1.9.2/doc/TODO 2006-09-03 03:55:06.000000000 +0200 +++ tin-1.9.2-dn/doc/TODO 2006-10-08 15:52:51.000000000 +0200 @@ -4,11 +4,6 @@ Bugs ---- -o CatchupNextUnread in pagelevel doesn't always work (if commeing directly - from group level (via GroupNextUnreadArtOrGrp)): instead of leaving the - thread and entering the next one it stays at the current article. - [20060515 Urs Janssen <[email protected]>] - o a wrong usename in ~/.newsauth can't be corrected in the first pass [20050816 Urs Janssen <[email protected]>] @@ -19,15 +14,6 @@ (the servers response should be a single line (INN 2.2)) [20050207 Urs Janssen <[email protected]>] -o fast/endless reconecction loop after a "200\n\r400\n\r" greeting, - see - <nntp://news.tin.org/[email protected]> - -o AFAICS change_config_file() currently has a static return value, - but some callers do check the return value and in case we did - change something we should update (global) attributes accordingly. - [20030511 Urs Janssen <[email protected]>] - o Changes to int/bool tinrc variables in the Option Menu don't propagate back to the attributes, not even groups with global attributes. This is because the Option-Menu in {group,page}.c doesn't reread the @@ -35,9 +21,6 @@ flashing changes to all affected groups and remove the reread of the attributes file from select.c -o 'C'atchup in pager is still not correct (we don't ever enter the next group) - [20030515 Urs Janssen <[email protected]>] - o piping/printing articles grabbles screen [20030501 Urs Janssen <[email protected]>] @@ -350,7 +333,7 @@ 'h' (GLOBAL_HELP) 'R' (GLOBAL_BUGREPORT) '!' (GLOBAL_SHELL_ESCAPE) - and maybe a way to changed built in path like DEFAULT_MAILER, PATH_PGP, ... + and maybe a way to change built in path like DEFAULT_MAILER, PATH_PGP, ... o Add to the POST_INFO-level: '?','/','\' search (partly done, currently only the displayed page is @@ -429,11 +412,6 @@ o bring up a warning on a long Newsgroups: (>=5) line and force the user to confirm every single group he wants to post (or redirect followups to) in. (N/y) - rewrite NGLIMIT handling (post.c) ulBuildArgv() would replace a lot of - the current code - (not just truncate Newsgroups:-line after the NGLIMITth newsgroup - - or if we do so - give an extra warning to the user and give him the - chance to reedit the Newsgroups:-line) o bring up a warning when trying to f'up into a binary group (use a regexp to detect binary groups e.g.: diff -Nur tin-1.9.2/include/proto.h tin-1.9.2-dn/include/proto.h --- tin-1.9.2/include/proto.h 2006-09-03 03:50:53.000000000 +0200 +++ tin-1.9.2-dn/include/proto.h 2006-10-08 13:43:31.000000000 +0200 @@ -3,7 +3,7 @@ * Module : proto.h * Author : Urs Janssen <[email protected]> * Created : - * Updated : 2006-09-02 + * Updated : 2006-10-01 * Notes : * * Copyright (c) 1997-2006 Urs Janssen <[email protected]> @@ -435,7 +435,7 @@ /* options_menu.c */ extern char *fmt_option_prompt(char *dst, size_t len, t_bool editing, enum option_enum option); -extern int change_config_file(struct t_group *group); +extern void change_config_file(struct t_group *group); extern int option_row(enum option_enum option); extern t_bool option_is_visible(enum option_enum option); extern void check_score_defaults(void); diff -Nur tin-1.9.2/include/tin.h tin-1.9.2-dn/include/tin.h --- tin-1.9.2/include/tin.h 2006-06-28 14:18:00.000000000 +0200 +++ tin-1.9.2-dn/include/tin.h 2006-10-08 13:43:16.000000000 +0200 @@ -3,7 +3,7 @@ * Module : tin.h * Author : I. Lea & R. Skrenta * Created : 1991-04-01 - * Updated : 2006-06-28 + * Updated : 2006-10-01 * Notes : #include files, #defines & struct's * * Copyright (c) 1997-2006 Iain Lea <[email protected]>, Rich Skrenta <[email protected]> @@ -1200,8 +1200,6 @@ /* * return codes for change_config_file () */ -#define NO_FILTERING 0 -#define FILTERING 1 #define DEFAULT_FILTER_DAYS 28 diff -Nur tin-1.9.2/src/group.c tin-1.9.2-dn/src/group.c --- tin-1.9.2/src/group.c 2006-02-15 19:44:38.000000000 +0100 +++ tin-1.9.2-dn/src/group.c 2006-10-06 22:44:17.000000000 +0200 @@ -3,7 +3,7 @@ * Module : group.c * Author : I. Lea & R. Skrenta * Created : 1991-04-01 - * Updated : 2005-07-02 + * Updated : 2006-10-06 * Notes : * * Copyright (c) 1991-2006 Iain Lea <[email protected]>, Rich Skrenta <[email protected]> @@ -455,7 +455,8 @@ old_artnum = arts[(int) base[grpmenu.curr]].artnum; } n = tinrc.sort_article_type; - if ((change_config_file(group) == NO_FILTERING) && n != tinrc.sort_article_type) + change_config_file(group); + if (n != tinrc.sort_article_type) make_threads(group, TRUE); grpmenu.curr = find_new_pos(old_top, old_artnum, grpmenu.curr); show_group_page(); @@ -1567,14 +1568,19 @@ case GRP_NEXTUNREAD: /* 'C'atchup */ if ((n = next_unread((int) base[grpmenu.curr])) >= 0) { + if (page) + page->art = n; if ((n = which_thread(n)) >= 0) { grpmenu.curr = n; depth = 0; break; /* Drop into next thread with unread */ } } - /* No more unread threads in this group */ - /* FALLTHROUGH */ + /* No more unread threads in this group, enter next group */ + grpmenu.curr = 0; + return GRP_NEXTUNREAD; + /* NOTREACHED */ + break; case GRP_KILLED: grpmenu.curr = 0; diff -Nur tin-1.9.2/src/nntplib.c tin-1.9.2-dn/src/nntplib.c --- tin-1.9.2/src/nntplib.c 2006-03-06 18:42:45.000000000 +0100 +++ tin-1.9.2-dn/src/nntplib.c 2006-10-04 00:09:19.000000000 +0200 @@ -3,7 +3,7 @@ * Module : nntplib.c * Author : S. Barber & I. Lea * Created : 1991-01-12 - * Updated : 2006-03-05 + * Updated : 2006-10-03 * Notes : NNTP client routines taken from clientlib.c 1.5.11 (1991-02-10) * Copyright : (c) Copyright 1991-99 by Stan Barber & Iain Lea * Permission is hereby granted to copy, reproduce, redistribute @@ -957,125 +957,138 @@ char *ptr; int ret = 0; # if 0 /* "CAPABILITIES" will replace "LIST EXTENSIONS" */ - FILE *fp; + char buf[NNTP_STRLEN]; char *d; + int i; - if ((fp = nntp_command("CAPABILITIES", INF_CAPABILITIES, NULL, 0)) != NULL) { - nntp_caps.type = CAPABILITIES; - while ((ptr = tin_fgets(fp, FALSE)) != NULL) { + buf[0] = '\0'; + i = new_nntp_command("CAPABILITIES", INF_CAPABILITIES, buf, sizeof(buf)); + switch (i) { + case INF_CAPABILITIES: + nntp_caps.type = CAPABILITIES; + while ((ptr = tin_fgets(FAKE_NNTP_FP, FALSE)) != NULL) { # ifdef DEBUG - debug_nntp("<<<", ptr); + debug_nntp("<<<", ptr); # endif /* DEBUG */ - /* look for version number(s) */ - if (!nntp_caps.version && nntp_caps.type == CAPABILITIES) { - if (!strcasecmp(ptr, "VERSION")) { - d = ptr + 7; - d = strpbrk(d, " \t"); - while (d != NULL && (d + 1 < (ptr + strlen(ptr)))) { - d++; - nntp_caps.version = MAX(nntp_caps.version, (unsigned int) atoi(d)); + /* look for version number(s) */ + if (!nntp_caps.version && nntp_caps.type == CAPABILITIES) { + if (!strcasecmp(ptr, "VERSION")) { + d = ptr + 7; d = strpbrk(d, " \t"); + while (d != NULL && (d + 1 < (ptr + strlen(ptr)))) { + d++; + nntp_caps.version = MAX(nntp_caps.version, (unsigned int) atoi(d)); + d = strpbrk(d, " \t"); + } } } - } - /* we currently only support CAPABILITIES VERSION 2 */ - if (nntp_caps.version == 2) { - /* - * check for LIST variants - this code is untested - */ - if (!strcasecmp(ptr, "LIST")) { - d = ptr + 4; - d = strpbrk(d, " \t"); - while (d != NULL && (d + 1 < (ptr + strlen(ptr)))) { - d++; - if (!strcasecmp(d, "ACTIVE.TIMES")) - nntp_caps.list_active_times = TRUE; - else if (!strcasecmp(d, "ACTIVE")) - nntp_caps.list_active_times = TRUE; - else if (!strcasecmp(d, "DISTRIB.PATS")) - nntp_caps.list_distrib_pats = TRUE; - else if (!strcasecmp(d, "DISTRIBUTIONS")) /* LIST DISTRIBUTIONS, "private" extension, RFC 2980 */ - nntp_caps.list_distributions = TRUE; - else if (!strcasecmp(d, "HEADERS")) - nntp_caps.list_headers = TRUE; /* HDR requires LIST HEADERS, but not vice versa */ - else if (!strcasecmp(d, "NEWSGROUPS")) - nntp_caps.list_newsgroups = TRUE; - else if (!strcasecmp(d, "OVERVIEW.FMT")) /* OVER requires OVERVIEW.FMT, but not vice versa */ - nntp_caps.list_overview_fmt = TRUE; - else if (!strcasecmp(d, "MOTD")) /* "private" extension */ - nntp_caps.list_motd = TRUE; - else if (!strcasecmp(d, "SUBSCRIPTIONS")) /* "private" extension, RFC 2980 */ - nntp_caps.list_subscriptions = TRUE; - else if (!strcasecmp(d, "MODERATORS")) /* "private" extension */ - nntp_caps.list_moderators = TRUE; + /* we currently only support CAPABILITIES VERSION 2 */ + if (nntp_caps.version == 2) { + /* + * check for LIST variants - this code is untested + */ + if (!strcasecmp(ptr, "LIST")) { + d = ptr + 4; d = strpbrk(d, " \t"); - } - } else if (!strcasecmp(ptr, "IMPLEMENTATION")) - nntp_caps.implementation = my_strdup(ptr + 14); - else if (!strcasecmp(ptr, "MODE-READER")) { - if (!nntp_caps.reader) - nntp_caps.mode_reader = TRUE; - } else if (!strcasecmp(ptr, "READER")) { - nntp_caps.reader = TRUE; - nntp_caps.mode_reader = FALSE; - } else if (!strcasecmp(d, "POST")) - nntp_caps.post = TRUE; - else if (!strcasecmp(ptr, "NEWNEWS")) - nntp_caps.newnews = TRUE; - else if (!strcasecmp(ptr, "XPAT")) /* extension, RFC 2980 */ - nntp_caps.xpat = TRUE; - else if (!strcasecmp(ptr, "STARTTLS")) - nntp_caps.starttls = TRUE; - /* - * NOTE: if we saw OVER, LIST OVERVIEW.FMT _must_ be implemented - */ - else if (!strcasecmp(ptr, &xover_cmds[1])) { - nntp_caps.over = TRUE; - nntp_caps.list_overview_fmt = TRUE; - nntp_caps.over_cmd = &xover_cmds[1]; - d = ptr + strlen(&xover_cmds[1]); - d = strpbrk(d, " \t"); - while (d != NULL && (d + 1 < (ptr + strlen(ptr)))) { - d++; - if (!strcasecmp(d, "MSGID")) - nntp_caps.over_msgid = TRUE; + while (d != NULL && (d + 1 < (ptr + strlen(ptr)))) { + d++; + if (!strcasecmp(d, "ACTIVE.TIMES")) + nntp_caps.list_active_times = TRUE; + else if (!strcasecmp(d, "ACTIVE")) + nntp_caps.list_active_times = TRUE; + else if (!strcasecmp(d, "DISTRIB.PATS")) + nntp_caps.list_distrib_pats = TRUE; + else if (!strcasecmp(d, "DISTRIBUTIONS")) /* LIST DISTRIBUTIONS, "private" extension, RFC 2980 */ + nntp_caps.list_distributions = TRUE; + else if (!strcasecmp(d, "HEADERS")) + nntp_caps.list_headers = TRUE; /* HDR requires LIST HEADERS, but not vice versa */ + else if (!strcasecmp(d, "NEWSGROUPS")) + nntp_caps.list_newsgroups = TRUE; + else if (!strcasecmp(d, "OVERVIEW.FMT")) /* OVER requires OVERVIEW.FMT, but not vice versa */ + nntp_caps.list_overview_fmt = TRUE; + else if (!strcasecmp(d, "MOTD")) /* "private" extension */ + nntp_caps.list_motd = TRUE; + else if (!strcasecmp(d, "SUBSCRIPTIONS")) /* "private" extension, RFC 2980 */ + nntp_caps.list_subscriptions = TRUE; + else if (!strcasecmp(d, "MODERATORS")) /* "private" extension */ + nntp_caps.list_moderators = TRUE; + d = strpbrk(d, " \t"); + } + } else if (!strcasecmp(ptr, "IMPLEMENTATION")) + nntp_caps.implementation = my_strdup(ptr + 14); + else if (!strcasecmp(ptr, "MODE-READER")) { + if (!nntp_caps.reader) + nntp_caps.mode_reader = TRUE; + } else if (!strcasecmp(ptr, "READER")) { + nntp_caps.reader = TRUE; + nntp_caps.mode_reader = FALSE; + } else if (!strcasecmp(d, "POST")) + nntp_caps.post = TRUE; + else if (!strcasecmp(ptr, "NEWNEWS")) + nntp_caps.newnews = TRUE; + else if (!strcasecmp(ptr, "XPAT")) /* extension, RFC 2980 */ + nntp_caps.xpat = TRUE; + else if (!strcasecmp(ptr, "STARTTLS")) + nntp_caps.starttls = TRUE; + /* + * NOTE: if we saw OVER, LIST OVERVIEW.FMT _must_ be implemented + */ + else if (!strcasecmp(ptr, &xover_cmds[1])) { + nntp_caps.over = TRUE; + nntp_caps.list_overview_fmt = TRUE; + nntp_caps.over_cmd = &xover_cmds[1]; + d = ptr + strlen(&xover_cmds[1]); d = strpbrk(d, " \t"); - } - } else if (!strcasecmp(ptr, "AUTHINFO")) { - d = ptr + 8; - d = strpbrk(d, " \t"); - while (d != NULL && (d + 1 < (ptr + strlen(ptr)))) { - d++; - if (!strcasecmp(d, "USER")) - nntp_caps.authinfo_user = TRUE; - if (!strcasecmp(d, "SASL")) - nntp_caps.authinfo_sasl = TRUE; + while (d != NULL && (d + 1 < (ptr + strlen(ptr)))) { + d++; + if (!strcasecmp(d, "MSGID")) + nntp_caps.over_msgid = TRUE; + d = strpbrk(d, " \t"); + } + } else if (!strcasecmp(ptr, "AUTHINFO")) { + d = ptr + 8; d = strpbrk(d, " \t"); + while (d != NULL && (d + 1 < (ptr + strlen(ptr)))) { + d++; + if (!strcasecmp(d, "USER")) + nntp_caps.authinfo_user = TRUE; + if (!strcasecmp(d, "SASL")) + nntp_caps.authinfo_sasl = TRUE; + d = strpbrk(d, " \t"); + } } - } # if 0 - /* - * NOTE: if we saw HDR, LIST HEADERS _must_ be implemented - */ - else if (!strcasecmp(ptr, &xhdr_cmds[1])) { + /* + * NOTE: if we saw HDR, LIST HEADERS _must_ be implemented + */ + else if (!strcasecmp(ptr, &xhdr_cmds[1])) { nntp_caps.hdr_cmd = &xhdr_cmds[1]; nntp_caps.hdr = TRUE; nntp_caps.list_headers = TRUE; - } - else if (!strcasecmp(ptr, "IHAVE")) + } + else if (!strcasecmp(ptr, "IHAVE")) nntp_caps.ihave = TRUE; # endif /* 0 */ - /* - * TODO: SASL, STREAMING - */ - } else - nntp_caps.type = NO; - } + /* + * TODO: SASL, STREAMING + */ + } else + nntp_caps.type = NO; + } + break; + + case ERR_GOODBYE: + ret = i; + error_message(buf); + break; + + default: + break; } # ifdef DEBUG debug_print_nntp_extensions(); # endif /* DEBUG */ - if (!*sec && !nntp_caps.reader) { + if ((ret != ERR_GOODBYE) && !*sec && !nntp_caps.reader) { if (nntp_caps.type == CAPABILITIES && !nntp_caps.mode_reader) return -1; /* no mode-switching and no reader mode, give up */ if ((ret = mode_reader(&*sec)) != 0) @@ -1136,20 +1149,25 @@ /* * as the server did support LIST EXTENSIONS it's likely that it * also can do LIST MOTD (we don't bother to parse the LIST - * EXTENSIONS output for MOTD as it never was standartizised; + * EXTENSIONS output for MOTD as it never was standardized; * draft-ietf-nntpext-base-24.txt only described OVER, HDR and * LISTGROUP). */ nntp_caps.list_motd = TRUE; break; + case ERR_GOODBYE: + ret = i; + error_message(buf); + break; + default: break; } # ifdef DEBUG debug_print_nntp_extensions(); # endif /* DEBUG */ - if (!*sec) + if ((ret != ERR_GOODBYE) && !*sec) ret = mode_reader(&*sec); } # endif /* 0 */ @@ -1553,8 +1571,7 @@ respcode = (int) strtol(ptr, &end, 10); DEBUG_IO((stderr, "get_only_respcode(%d)\n", respcode)); - /* TODO: reconnect on ERR_FAULT? */ - if ((respcode == ERR_FAULT || respcode == ERR_GOODBYE || respcode == OK_GOODBYE) && last_put[0] != '\0' && strcmp(last_put, "QUIT")) { + if ((respcode == ERR_GOODBYE || respcode == OK_GOODBYE) && last_put[0] != '\0' && strcmp(last_put, "QUIT")) { /* * Maybe server timed out. * If so, retrying will force a reconnect. diff -Nur tin-1.9.2/src/options_menu.c tin-1.9.2-dn/src/options_menu.c --- tin-1.9.2/src/options_menu.c 2006-06-28 14:21:33.000000000 +0200 +++ tin-1.9.2-dn/src/options_menu.c 2006-10-08 13:42:34.000000000 +0200 @@ -3,7 +3,7 @@ * Module : options_menu.c * Author : Michael Bienia <[email protected]> * Created : 2004-09-05 - * Updated : 2006-06-28 + * Updated : 2006-10-01 * Notes : Split from config.c * * Copyright (c) 2004-2006 Michael Bienia <[email protected]> @@ -696,17 +696,14 @@ /* * options menu so that the user can dynamically change parameters * - * TODO: - why do we use ret_code when we never modify it? what about calling - * code which checks the return value? - * - when we change something we need to update the related attributes + * TODO: - when we change something we need to update the related attributes * as well (see line 2009). */ -int +void change_config_file( struct t_group *group) { enum option_enum option, old_option; - int ret_code = NO_FILTERING; int mime_encoding = MIME_ENCODING_7BIT; t_bool change_option = FALSE; t_function func; @@ -725,7 +722,7 @@ /* FALLTHROUGH */ case CONFIG_NO_SAVE: clear_note_area(); - return ret_code; + return; case GLOBAL_LINE_UP: unhighlight_option(option); @@ -1517,5 +1514,5 @@ } /* if (change_option) */ } /* forever */ /* NOTREACHED */ - return ret_code; + return; } diff -Nur tin-1.9.2/src/page.c tin-1.9.2-dn/src/page.c --- tin-1.9.2/src/page.c 2006-09-03 03:48:07.000000000 +0200 +++ tin-1.9.2-dn/src/page.c 2006-10-08 13:42:07.000000000 +0200 @@ -3,7 +3,7 @@ * Module : page.c * Author : I. Lea & R. Skrenta * Created : 1991-04-01 - * Updated : 2006-06-28 + * Updated : 2006-10-01 * Notes : * * Copyright (c) 1991-2006 Iain Lea <[email protected]>, Rich Skrenta <[email protected]> @@ -300,7 +300,6 @@ char buf[LEN]; char key[MAXKEYLEN]; int i, n = 0; - int filter_state = NO_FILTERING; int old_sort_art_type = tinrc.sort_article_type; int art_type = GROUP_TYPE_NEWS; t_bool mouse_click_on = TRUE; @@ -791,14 +790,14 @@ case GLOBAL_QUIT: /* return to index page */ return_to_index: XFACE_CLEAR(); - if (filter_state == NO_FILTERING && tinrc.sort_article_type != old_sort_art_type) + if (tinrc.sort_article_type != old_sort_art_type) make_threads(group, TRUE); i = which_thread(this_resp); if (threadnum) *threadnum = which_response(this_resp); - if (filter_state == FILTERING || filtered_articles) { + if (filtered_articles) { int old_top = top_art; long old_artnum = arts[this_resp].artnum; @@ -830,8 +829,7 @@ case GLOBAL_OPTION_MENU: /* option menu */ XFACE_CLEAR(); - if (change_config_file(group) == FILTERING) - filter_state = FILTERING; + change_config_file(group); draw_page(group->name, 0); break; @@ -894,10 +892,13 @@ break; case PAGE_GROUP_SELECT: /* return to group selection page */ +#if 0 + /* Hasn't been used since tin 1.1 PL4 */ if (filter_state == FILTERING) { filter_articles(group); make_threads(group, FALSE); } +#endif /* 0 */ XFACE_CLEAR(); return GRP_RETSELECT; diff -Nur tin-1.9.2/src/post.c tin-1.9.2-dn/src/post.c --- tin-1.9.2/src/post.c 2006-06-16 16:58:52.000000000 +0200 +++ tin-1.9.2-dn/src/post.c 2006-10-08 13:41:23.000000000 +0200 @@ -3,7 +3,7 @@ * Module : post.c * Author : I. Lea * Created : 1991-04-01 - * Updated : 2006-02-15 + * Updated : 2006-10-01 * Notes : mail/post/replyto/followup/repost & cancel articles * * Copyright (c) 1991-2006 Iain Lea <[email protected]> @@ -125,6 +125,7 @@ * Local prototypes */ static FILE *create_mail_headers(char *filename, const char *suffix, const char *to, const char *subject, struct t_header *extra_hdrs); +static char **build_nglist(char *ngs_list, int *ngcnt); static char **split_address_list(const char *addresses, unsigned int *cnt); static char *backup_article_name(const char *the_article); static int add_mail_quote(FILE *fp, int respnum); @@ -147,6 +148,7 @@ static t_bool is_crosspost(const char *xref); static t_bool must_include(const char *id); static t_bool repair_article(t_function *result, struct t_group *group); +static t_bool stripped_double_ngs(char **newsgroups, int *ngcnt); static t_bool submit_mail_file(const char *file, struct t_group *group, FILE *articlefp, t_bool include_text); static t_function prompt_rejected(void); static t_function prompt_to_send(const char *subject); @@ -279,7 +281,7 @@ if (invoke_editor(article_name, start_line_offset)) return TRUE; } else if (func == GLOBAL_OPTION_MENU) { - (void) change_config_file(group); /*OD:*/ + change_config_file(group); /*OD:*/ return TRUE; } return FALSE; @@ -724,7 +726,8 @@ t_bool art_unchanged) { FILE *fp; - char *ngptrs[NGLIMIT], *ftngptrs[NGLIMIT]; + char **newsgroups; + char **followupto; char *line, *cp, *cp2; char references[HEADER_LEN]; char subject[HEADER_LEN]; @@ -743,7 +746,6 @@ int found_subject_lines = 0; int errors_catbp = 0; /* sum of error-codes */ int warnings_catbp = 0; /* sum of warning-codes */ - size_t nglens[NGLIMIT], ftnglens[NGLIMIT]; struct t_group *psGrp; t_bool end_of_header = FALSE; t_bool got_long_line = FALSE; @@ -956,28 +958,10 @@ unfold_header(line); } - strip_double_ngs(cp); - while (*cp) { - if (!(cp2 = strchr(cp, ','))) - cp2 = cp + strlen(cp); - else - *cp2++ = '\0'; - if (ngcnt < NGLIMIT) { - nglens[ngcnt] = strlen(cp); - ngptrs[ngcnt] = my_malloc(nglens[ngcnt] + 1); - if (!ngptrs[ngcnt]) { - for (i = 0; i < ngcnt; i++) - FreeIfNeeded(ngptrs[i]); - for (i = 0; i < ftngcnt; i++) - FreeIfNeeded(ftngptrs[i]); - Raw(oldraw); - return 1; - } - strcpy(ngptrs[ngcnt], cp); - ngcnt++; - } - cp = cp2; - } + newsgroups = build_nglist(cp, &ngcnt); + if (newsgroups && ngcnt) + (void) stripped_double_ngs(newsgroups, &ngcnt); + if (!ngcnt) errors_catbp |= CA_ERROR_EMPTY_NEWSGROUPS; } @@ -987,7 +971,6 @@ ; if (strlen(cp)) /* Followup-To not empty */ found_followup_to_lines++; - strip_double_ngs(cp); if (strchr(cp, ' ') || strchr(cp, '\t')) { #ifdef FOLLOW_USEFOR_DRAFT warnings_catbp |= CA_WARNING_SPACE_IN_FOLLOWUP_TO; @@ -1003,28 +986,10 @@ #endif /* FOLLOW_USEFOR_DRAFT */ unfold_header(line); } - while (*cp) { - if (!(cp2 = strchr(cp, ','))) - cp2 = cp + strlen(cp); - else - *cp2++ = '\0'; - if (ftngcnt < NGLIMIT) { - ftnglens[ftngcnt] = strlen(cp); - ftngptrs[ftngcnt] = my_malloc(ftnglens[ftngcnt] + 1); - if (!ftngptrs[ftngcnt]) { - /* out of memory? */ - for (i = 0; i < ftngcnt; i++) - FreeIfNeeded(ftngptrs[i]); - for (i = 0; i < ngcnt; i++) - FreeIfNeeded(ngptrs[i]); - Raw(oldraw); - return 1; - } - strcpy(ftngptrs[ftngcnt], cp); - ftngcnt++; - } - cp = cp2; - } + + followupto = build_nglist(cp, &ftngcnt); + if (followupto && ftngcnt) + (void) stripped_double_ngs(followupto, &ftngcnt); } } @@ -1215,7 +1180,7 @@ * Is this correct for crosspostings? */ if (ngcnt) - *group = group_find(ngptrs[0]); + *group = group_find(newsgroups[0]); /* * check for known 7bit charsets @@ -1269,7 +1234,7 @@ if (errors_catbp & CA_ERROR_MISSING_NEWSGROUPS) my_fprintf(stderr, _(txt_error_header_line_missing), "Newsgroups"); - /* dublicated headers */ + /* duplicated headers */ if (errors_catbp & CA_ERROR_DUPLICATED_FROM) my_fprintf(stderr, _(txt_error_header_duplicate), found_from_lines, "From"); if (errors_catbp & CA_ERROR_DUPLICATED_SUBJECT) @@ -1360,17 +1325,17 @@ my_fprintf(stderr, _(txt_warn_article_unchanged)); my_fprintf(stderr, _(txt_art_newsgroups), subject, PLURAL(ngcnt, txt_newsgroup)); for (i = 0; i < ngcnt; i++) { - if ((psGrp = group_find(ngptrs[i]))) - my_fprintf(stderr, " %s\t %s\n", ngptrs[i], BlankIfNull(psGrp->description)); + if ((psGrp = group_find(newsgroups[i]))) + my_fprintf(stderr, " %s\t %s\n", newsgroups[i], BlankIfNull(psGrp->description)); else { #ifdef HAVE_FASCIST_NEWSADMIN StartInverse(); errors++; - my_fprintf(stderr, _(txt_error_not_valid_newsgroup), ngptrs[i]); + my_fprintf(stderr, _(txt_error_not_valid_newsgroup), newsgroups[i]); my_fflush(stderr); EndInverse(); #else - my_fprintf(stderr, (!list_active ? /* did we read the whole active file? */ _(txt_warn_not_in_newsrc) : _(txt_warn_not_valid_newsgroup)), ngptrs[i]); + my_fprintf(stderr, (!list_active ? /* did we read the whole active file? */ _(txt_warn_not_in_newsrc) : _(txt_warn_not_valid_newsgroup)), newsgroups[i]); warnings++; #endif /* HAVE_FASCIST_NEWSADMIN */ } @@ -1406,20 +1371,20 @@ #endif /* HAVE_FASCIST_NEWSADMIN */ my_fprintf(stderr, _(txt_followup_newsgroups), PLURAL(ftngcnt, txt_newsgroup)); for (i = 0; i < ftngcnt; i++) { - if ((psGrp = group_find(ftngptrs[i]))) - my_fprintf(stderr, " %s\t %s\n", ftngptrs[i], BlankIfNull(psGrp->description)); + if ((psGrp = group_find(followupto[i]))) + my_fprintf(stderr, " %s\t %s\n", followupto[i], BlankIfNull(psGrp->description)); else { - if (STRCMPEQ("poster", ftngptrs[i])) - my_fprintf(stderr, _(txt_followup_poster), ftngptrs[i]); + if (STRCMPEQ("poster", followupto[i])) + my_fprintf(stderr, _(txt_followup_poster), followupto[i]); else { #ifdef HAVE_FASCIST_NEWSADMIN StartInverse(); - my_fprintf(stderr, _(txt_error_not_valid_newsgroup), ftngptrs[i]); + my_fprintf(stderr, _(txt_error_not_valid_newsgroup), followupto[i]); my_fflush(stderr); EndInverse(); errors++; #else - my_fprintf(stderr, (!list_active ? /* did we read the whole active file? */ _(txt_warn_not_in_newsrc) : _(txt_warn_not_valid_newsgroup)), ftngptrs[i]); + my_fprintf(stderr, (!list_active ? /* did we read the whole active file? */ _(txt_warn_not_in_newsrc) : _(txt_warn_not_valid_newsgroup)), followupto[i]); warnings++; #endif /* HAVE_FASCIST_NEWSADMIN */ } @@ -1441,10 +1406,14 @@ Raw(oldraw); /* restore raw/unraw state */ /* free memory */ - for (i = 0; i < ngcnt; i++) - FreeIfNeeded(ngptrs[i]); - for (i = 0; i < ftngcnt; i++) - FreeIfNeeded(ftngptrs[i]); + if (newsgroups) { + FreeIfNeeded(*newsgroups); + FreeIfNeeded(newsgroups); + } + if (followupto) { + FreeIfNeeded(*followupto); + FreeIfNeeded(followupto); + } return (errors ? 1 : warnings ? 2 : 0); } @@ -1533,7 +1502,7 @@ return ret_code; case GLOBAL_OPTION_MENU: - (void) change_config_file(group); + change_config_file(group); while ((i = check_article_to_be_posted(article_name, art_type, &group, art_unchanged) == 1) && repair_article(&func, group)) ; break; @@ -4833,73 +4802,95 @@ } #endif /* EVIL_INSIDE */ +static char ** +build_nglist( + char *ngs_list, + int *ngcnt) +{ + char **newsgroups; + char *dst; + char *my_list; + char *src; + char cp; + + /* ulBuildArgv likes to have spaces, not commas */ + my_list = my_malloc(strlen(ngs_list) + 1); + src = ngs_list; + dst = my_list; + while (cp = *src++) { + if (cp == ',') cp = ' '; + *dst++ = cp; + } + *dst = cp; + + /* now build the list of newsgroups */ + newsgroups = ulBuildArgv(my_list, ngcnt); + free(my_list); + return newsgroups; +} + +static t_bool +stripped_double_ngs( + char **newsgroups, + int *ngcnt) +{ + char *that_group; + char *this_group; + unsigned int i = 0; + unsigned int j; + unsigned int k; + t_bool changed = FALSE; + + if (*ngcnt < 2) + /* no need to do anything with no or just one group */ + return FALSE; + + while (this_group = newsgroups[i++]) { + j = i; + while (that_group = newsgroups[j]) { + if (strcasecmp(this_group, that_group) == 0) { + /* Double newsgroup. Move all following newsgroups downwards */ + k = j + 1; + do { + newsgroups[k-1] = newsgroups[k]; + } while (newsgroups[k++]); + changed = TRUE; + (*ngcnt)--; + } else + j++; + } + } + return changed; +} -/* - * Strip duplicate newsgroups from within a given list of comma separated - * groups - * 14-Jun-'96 Sven Paulus <[email protected]> - */ static void strip_double_ngs( char *ngs_list) { - char *ptr; /* start of next (outer) newsgroup */ - char *ptr2; /* temporary pointer */ - char ngroup1[HEADER_LEN]; /* outer newsgroup to compare */ - char ngroup2[HEADER_LEN]; /* inner newsgroup to compare */ - char cmplist[HEADER_LEN]; /* last loops output */ - char newlist[HEADER_LEN]; /* the newly generated list without */ - /* any duplicates of the first nwsg */ - int ncnt1; /* counter for the first newsgroup */ - int ncnt2; /* counter for the second newsgroup */ - t_bool over1; /* TRUE when the outer loop is over */ - t_bool over2; /* TRUE when the inner loop is over */ - - /* shortcut, check if there is only 1 group */ - if (strchr(ngs_list, ',') != NULL) { - over1 = FALSE; - ncnt1 = 0; - strcpy(newlist, ngs_list); /* make a "working copy" */ - ptr = newlist; /* the next outer newsg. is the 1st */ - - while (!over1) { - ncnt1++; /* inc. outer counter */ - strcpy(cmplist, newlist); /* duplicate groups for inner loop */ - ptr2 = strchr(ptr, ','); /* search "," ... */ - if (ptr2 != NULL) { /* if found ... */ - *ptr2 = '\0'; - strcpy(ngroup1, ptr); /* chop off first outer newsgroup */ - ptr = ptr2 + 1; /* pointer points to next newsgr. */ - } else { /* ... if not: last group */ - over1 = TRUE; /* wow, everything is done after . */ - strcpy(ngroup1, ptr); /* ... this last outer newsgroup */ - } + char **newsgroups; + int ngcnt; - over2 = FALSE; - ncnt2 = 0; + /* shortcut, only one newsgroup */ + if (strchr(ngs_list, ',') == NULL) + return; - /* - * now compare with each inner newsgroup on the list, - * which is behind the momentary outer newsgroup - * if it is different from the outer newsgroup, append - * to list, strip double-commas - */ - while (!over2) { - ncnt2++; - strcpy(ngroup2, cmplist); - ptr2 = strchr(ngroup2, ','); - if (ptr2 != NULL) { - strcpy(cmplist, ptr2 + 1); - *ptr2 = '\0'; - } else - over2 = TRUE; + if ((newsgroups = build_nglist(ngs_list, &ngcnt)) == NULL) + /* something went wrong */ + return; - if ((ncnt2 > ncnt1) && (strcasecmp(ngroup1, ngroup2)) && (strlen(ngroup2) != 0)) { - strcat(newlist, ","); - strcat(newlist, ngroup2); - } - } + if (stripped_double_ngs(newsgroups, &ngcnt)) { + /* something has changed, rebuild newsgroups list */ + char *this_group; + unsigned int i = 0; + + this_group = newsgroups[i++]; + strcpy(ngs_list, this_group); + while (this_group = newsgroups[i++]) { + strcat(ngs_list, ","); + strcat(ngs_list, this_group); } - strcpy(ngs_list, newlist); /* move string to its real location */ } + free(*newsgroups); + free(newsgroups); } + diff -Nur tin-1.9.2/src/select.c tin-1.9.2-dn/src/select.c --- tin-1.9.2/src/select.c 2006-02-15 19:44:38.000000000 +0100 +++ tin-1.9.2-dn/src/select.c 2006-10-08 13:40:43.000000000 +0200 @@ -3,7 +3,7 @@ * Module : select.c * Author : I. Lea & R. Skrenta * Created : 1991-04-01 - * Updated : 2005-07-02 + * Updated : 2006-10-01 * Notes : * * Copyright (c) 1991-2006 Iain Lea <[email protected]>, Rich Skrenta <[email protected]> @@ -342,7 +342,7 @@ break; case GLOBAL_OPTION_MENU: - (void) change_config_file(NULL); + change_config_file(NULL); read_attributes_files(); show_selection_page(); break;