[PATCH] reconnection problem & minor cleanups

Urs Janßen <[email protected]> Mon, 14 Apr 2008 20:12:17 +0200
Newsgroups gmane.network.tin.devel
Message-ID <[email protected]>
attached is a (ugly) fix for the reconnection problem in the -n case and
some other minor cleanups.

urs
-- 
"Only whimps use tape backup: _real_ men just upload their important stuff
 on ftp, and let the rest of the world mirror it ;)" - Linus
tin-1.9.3.snaptotin-1.9.3.diff (text/x-diff, 15.3 KB)
diff -Nurp doc/tin.1 doc/tin.1
--- doc/tin.1	2008-03-20 18:31:57.000000000 +0100
+++ doc/tin.1	2008-04-07 08:38:54.679050987 +0200
@@ -19,7 +19,7 @@
 .fi
 ..
 .\"
-.TH tin 1 "March 20th, 2008" "1.9.3" "A Usenet newsreader"
+.TH tin 1 "April 4th, 2008" "1.9.3" "A Usenet newsreader"
 .\"
 .\"
 .SH NAME
@@ -353,7 +353,7 @@ recent articles and the number of killed
 .PP
 .nf
 .\" FIXME - make this autocenter
-            alt.sources (5B -50/23+ 0* 3o 0K).
+            alt.sources (5B \-50/23+ 0* 3o 0K).
 .fi
 .PP
 The characters after the numbers are depending to the configuration and if
@@ -2007,9 +2007,9 @@ Score of an article which should be mark
 .B Number of lines to scroll in pager (scroll_lines)
 The number of lines that will be scrolled up/down in the article pager when
 using cursor-up/down. The default is 1 (line-by-line). Set to 0 to get
-traditional tin page-by-page scrolling. Set to -1 to get page-by-page
+traditional tin page-by-page scrolling. Set to \-1 to get page-by-page
 scrolling where the top/bottom line is carried over onto the next page.
-This setting supersedes show_last_line_prev_page=ON. Set to -2 to get
+This setting supersedes show_last_line_prev_page=ON. Set to \-2 to get
 half-page scrolling. This setting supersedes full_page_scroll=OFF.
 .TP
 .B In group menu, show author by (show_author)
@@ -2455,7 +2455,7 @@ news_quote_format=In %M, %F wrote:
 would expand to:
 .RS
 .Vb
-On 21 Sep 1993 09:45:51 -0400 in alt.sources you wrote:
+On 21 Sep 1993 09:45:51 \-0400 in alt.sources you wrote:
 In <[email protected]>, Joe Bar <[email protected]> wrote:
 .Ve
 .RE
@@ -2766,7 +2766,7 @@ find ${TIN_INDEX_NEWSDIR:\-"${TIN_HOMEDI
 .\"               .article[.$$], .cancel[.$$], .letter[.$$]?
 .\"       $PWD/trace (--with-trace)
 .\"       $TMPDIR/NNTP, $TMPDIR/ARTS, $TMPDIR/ACTIVE, $TMPDIR/BASE,
-\."       $TMPDIR/SAVE_COMP, $TMPDIR/BITMAP, $TMPDIR/MALLOC, $TMPDIR/FILTER
+.\"       $TMPDIR/SAVE_COMP, $TMPDIR/BITMAP, $TMPDIR/MALLOC, $TMPDIR/FILTER
 For a detailed description see
 .BR tin (5).
 .PP
@@ -2920,6 +2920,13 @@ For a detailed description see
 .\" .TP
 .\" .B NNTP_AUTH_FDS
 .\"
+.\" used in xface support
+.\" .TP
+.\" .B DISPLAY
+.\" .TP
+.\" .B WINDOWID
+.\"
+.\"
 .TP
 .B TINRC
 Define this variable if you want to specify command-line options that
diff -Nurp doc/tin.5 doc/tin.5
--- doc/tin.5	2008-03-20 12:03:27.000000000 +0100
+++ doc/tin.5	2008-04-04 15:52:16.570176426 +0200
@@ -16,7 +16,7 @@
 .fi
 ..
 .\"
-.TH tin 5 "October 13th, 2007" "1.9.3" "A Usenet newsreader"
+.TH tin 5 "April 4th, 2008" "1.9.3" "A Usenet newsreader"
 
 .SH NAME
 tin, rtin \- related files
@@ -1786,9 +1786,9 @@ Score of an article which should be mark
 .B scroll_lines
 The number of lines that will be scrolled up/down in the article pager when
 using cursor-up/down. The default is 1 (line-by-line). Set to 0 to get
-traditional page-by-page scrolling. Set to -1 to get page-by-page
+traditional page-by-page scrolling. Set to \-1 to get page-by-page
 scrolling where the top/bottom line is carried over onto the next page.
-This setting supersedes show_last_line_prev_page=ON. Set to -2 to get
+This setting supersedes show_last_line_prev_page=ON. Set to \-2 to get
 half-page scrolling. This setting supersedes full_page_scroll=OFF.
 .TP
 .B show_author
diff -Nurp include/extern.h include/extern.h
--- include/extern.h	2008-03-14 10:21:31.000000000 +0100
+++ include/extern.h	2008-04-14 11:13:23.196956378 +0200
@@ -236,7 +236,7 @@
 	extern int strncasecmp(const char *, const char *, size_t);
 #endif /* DECL_STRNCASECMP */
 #ifdef DECL_STRSEP
-        extern char *strsep(char **, const char *);
+	extern char *strsep(char **, const char *);
 #endif /* DECL_STRSEP */
 #ifdef DECL_STRTOL
 	extern long strtol(const char *, char **, int);
@@ -1301,6 +1301,7 @@ extern t_bool check_for_new_newsgroups;
 extern t_bool cmd_line;
 extern t_bool created_rcdir;
 extern t_bool dangerous_signal_exit; /* TRUE if SIGHUP, SIGTERM, SIGUSR1 */
+extern t_bool did_reconnect;
 extern t_bool disable_gnksa_domain_check;
 extern t_bool disable_sender;
 extern t_bool force_no_post;
diff -Nurp include/proto.h include/proto.h
--- include/proto.h	2008-03-18 08:21:17.000000000 +0100
+++ include/proto.h	2008-04-14 00:20:23.428154853 +0200
@@ -410,16 +410,16 @@ extern void set_default_bitmap(struct t_
 extern FILE *get_nntp_fp(FILE *fp);
 extern FILE *get_nntp_wr_fp(FILE *fp);
 extern char *getserverbyfile(const char *file);
-extern char *get_server(char *string, int size);
 extern int get_respcode(char *, size_t);
 extern int get_only_respcode(char *, size_t);
-extern int new_nntp_command(const char *command, int success, char *message, size_t mlen);
 extern int nntp_open(void);
 extern void nntp_close(void);
-extern void put_server(const char *string);
-extern void u_put_server(const char *string);
 #ifdef NNTP_ABLE
 	extern FILE *nntp_command(const char *, int, char *, size_t);
+	extern char *get_server(char *string, int size);
+	extern int new_nntp_command(const char *command, int success, char *message, size_t mlen);
+	extern void put_server(const char *string);
+	extern void u_put_server(const char *string);
 #endif /* NNTP_ABLE */
 
 /* nrctbl.c */
diff -Nurp src/active.c src/active.c
--- src/active.c	2008-03-20 14:24:26.000000000 +0100
+++ src/active.c	2008-04-14 11:13:12.379880056 +0200
@@ -619,7 +619,7 @@ read_news_active_file(
 				fclose(fp);
 
 				if (j < PIPELINE_LIMIT) {
-					for (i = 0; i < j; i++) {
+					for (i = 0; i < j && !did_reconnect; i++) {
 						if ((r = get_only_respcode(buff, sizeof(buff))) != OK_GROUPS) {
 							if (r == ERR_NOAUTH || r == NEED_AUTHINFO)
 								need_auth = TRUE;
@@ -658,6 +658,7 @@ read_news_active_file(
 						}
 					}
 				}
+				did_reconnect = FALSE;
 			}
 		}
 #	endif /* !DISABLE_PIPELINING */
diff -Nurp src/art.c src/art.c
--- src/art.c	2008-03-14 10:21:31.000000000 +0100
+++ src/art.c	2008-04-14 19:24:12.482085753 +0200
@@ -1520,15 +1520,19 @@ read_overview(
 
 				case 6:		/* Bytes */
 #ifdef DEBUG
-					if (!isdigit((unsigned char) *ptr))
-						oerror += 1<<count;
+					if (*ptr) {
+						if (!isdigit((unsigned char) *ptr))
+							oerror += 1<<count;
+					}
 #endif /* DEBUG */
 					break;
 
 				case 7:		/* Lines */
-					if (isdigit((unsigned char) *ptr))
-						art->line_count = atoi(ptr);
-					handle_overview_fmt_error();
+					if (*ptr) {
+						if (isdigit((unsigned char) *ptr))
+							art->line_count = atoi(ptr);
+						handle_overview_fmt_error();
+					}
 					break;
 
 				case 8:		/* Xref: */
@@ -1546,9 +1550,9 @@ read_overview(
 		/* Complain if incorrect # of fields */
 		if (count < (xref_supported ? 8 : 7) || oerror) {
 			if (debug & DEBUG_MISC)
-				error_message(_("%d Bad overview record (%d fields) '%s'"), oerror, count, BlankIfNull(ptr)); /* TODO move to lang.c */
+				error_message(_("%d Bad overview record %d (%d fields)"), oerror, artnum, count); /* TODO move to lang.c */
 			if (debug & DEBUG_NNTP)
-				debug_print_file("NNTP", "read_overview() %d Bad overview record (%d fields)", oerror, count);
+				debug_print_file("NNTP", "read_overview(%d) %d Bad overview record (%d fields)", artnum, oerror, count);
 		}
 		debug_print_header(art);
 		oerror = 0;
diff -Nurp src/inews.c src/inews.c
--- src/inews.c	2008-03-14 10:21:32.000000000 +0100
+++ src/inews.c	2008-03-28 15:57:38.879214007 +0100
@@ -161,7 +161,7 @@ submit_inews(
 		rewind(fp);
 
 #	ifndef FORGERY
-		if ((ptr = build_sender()) && (!disable_sender)) {
+		if (!disable_sender && (ptr = build_sender())) {
 			sender = sender_needed(from_name + 6, group, ptr);
 			switch (sender) {
 				case -2: /* can't build Sender: */
diff -Nurp src/keymap.c src/keymap.c
--- src/keymap.c	2008-03-26 19:06:42.000000000 +0100
+++ src/keymap.c	2008-04-04 15:47:27.517560102 +0200
@@ -398,7 +398,7 @@ read_keymap_file(
 
 		/*
 		 * TODO: useful? shared keymaps (NFS-Home) may differ
-		 * depending on the OS (i.e. on tin has color the other has not)
+		 * depending on the OS (i.e. one tin has color the other has not)
 		 */
 		if (!process_mapping(kname, keydef)) {
 			wait_message(0, _(txt_keymap_invalid_name), kname);
diff -Nurp src/nntplib.c src/nntplib.c
--- src/nntplib.c	2008-03-19 19:18:28.000000000 +0100
+++ src/nntplib.c	2008-04-14 19:17:58.672796902 +0200
@@ -34,6 +34,8 @@ char *nntp_server = NULL;
 
 /* Flag to show whether tin did reconnect in last get_server() */
 t_bool reconnected_in_last_get_server = FALSE;
+/* Flag used in LIST ACVTIVE loop */
+t_bool did_reconnect = FALSE;
 
 static TCP *nntp_rd_fp = NULL;
 static TCP *nntp_wr_fp = NULL;
@@ -775,8 +777,15 @@ put_server(
 		/*
 		 * remember the last command we wrote to be able to resend it after a
 		 * reconnect. reconnection is handled by get_server()
+		 *
+		 * don't cache "LIST ACTIVE something" as we would need to
+		 * resend all of them but we remeber just the last one. we cache
+		 * "LIST" instead, this will slow down things, but that's ok on
+		 * reconnect.
 		 */
-		if (last_put != string)
+		if (!strncmp(string, "LIST ACTIVE ", 12))
+			STRCPY(last_put, "LIST");
+		else
 			STRCPY(last_put, string);
 	}
 	(void) s_flush(nntp_wr_fp);
@@ -836,6 +845,7 @@ reconnect(
 		}
 		DEBUG_IO((stderr, _("Resend last command (%s)\n"), buf));
 		put_server(buf);
+		did_reconnect = TRUE;
 		return 0;
 	}
 
@@ -873,7 +883,6 @@ get_server(
 	 * NULL socket reads indicates socket has closed. Try a few times more
 	 */
 	while (nntp_rd_fp == NULL || s_gets(string, size, nntp_rd_fp) == NULL) {
-
 		if (quitting)						/* Don't bother to reconnect */
 			tin_done(NNTP_ERROR_EXIT);		/* And don't try to disconnect again! */
 
diff -Nurp src/post.c src/post.c
--- src/post.c	2008-03-26 19:11:43.000000000 +0100
+++ src/post.c	2008-04-12 12:53:51.145468427 +0200
@@ -584,7 +584,7 @@ append_mail(
 	t_bool mmdf = FALSE;
 	t_bool rval = FALSE;
 #ifndef NO_LOCKING
-	int retrys = 10;	/* maximum lock retrys */
+	unsigned int retrys = 11;	/* maximum lock retrys + 1 */
 #endif /* NO_LOCKING */
 
 	if (!strcasecmp(txt_mailbox_formats[tinrc.mailbox_format], "MMDF") && the_mailbox != postponed_articles_file)
@@ -598,17 +598,18 @@ append_mail(
 
 #ifndef NO_LOCKING
 		/* TODO: move the retry/error stuff into a function? */
-		while (retrys-- && fd_lock(fd, FALSE))
+		while (--retrys && fd_lock(fd, FALSE))
 			wait_message(1, _(txt_trying_lock), retrys, the_mailbox);
-		if (retrys < 0) {
+		if (!retrys) {
 			wait_message(5, _(txt_error_couldnt_lock), the_mailbox);
 			fclose(fp_out);
 			fclose(fp_in);
 			return rval;
 		}
-		while (retrys-- && !dot_lock(the_mailbox))
+		retrys++;
+		while (--retrys && !dot_lock(the_mailbox))
 			wait_message(1, _(txt_trying_dotlock), retrys, the_mailbox);
-		if (retrys < 0) {
+		if (!retrys) {
 			wait_message(5, _(txt_error_couldnt_dotlock), the_mailbox);
 			fd_unlock(fd);
 			fclose(fp_out);
@@ -2291,12 +2292,16 @@ damaged_id(
 {
 	while (*id && isspace((unsigned char) *id))
 		id++;
+
 	if (*id != '<')
-		return 1;
+		return TRUE;
+
 	while (isascii((unsigned char) *id) && isgraph((unsigned char) *id) && !iscntrl((unsigned char) *id) && *id != '>')
 		id++;
+
 	if (*id != '>')
 		return TRUE;
+
 	return FALSE;
 }
 
@@ -4319,7 +4324,7 @@ split_address_list(
 	char **argv = NULL;
 	char *addr;
 	const char *start, *end, *curr;
-	size_t len = 0, addr_len = 0;
+	size_t len = 0, addr_len;
 	unsigned int argc = 0, dquotes = 0, parens = 0;
 
 	if (!addresses) {
@@ -4593,7 +4598,7 @@ build_messageid(
 	if (t >= 1041379200) /* 2003-01-01 00:00:00 GMT */
 		t -= 1041379200;
 	else
-		return '\0';
+		return NULL;
 
 	snprintf(buf, sizeof(buf), "<%sT", radix32(seqnum++));
 	strcat(buf, radix32(t));
@@ -4621,15 +4626,27 @@ build_messageid(
 	snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "N%s@%s>", radix32(getuid()), get_fqdn(get_host_name()));
 #	endif /* !FORGERY */
 
-	/* disallow .invalid TLD for Message-IDs */
-	if ((i = strlen(buf) - 9) > 0) /* strlen(".invalid>") */
-		if (!strcasecmp(".invalid>", buf + i))
-			return NULL
+	/*
+	 * disallow .invalid TLD (gnksa_check_from() allows it)
+	 * and Message-IDs > 250 octects (RFC 3977, 3.6)
+	 */
+	if ((j = strlen(buf) - 9) > 0) { /* strlen(".invalid>") */
+		if (!strcasecmp(".invalid>", buf + j) || j > 241) /* 250 - 9 */
+			return NULL;
 	}
 
 	i = gnksa_check_from(buf);
 	if ((GNKSA_OK != i) && (GNKSA_LOCALPART_MISSING > i))
-		buf[0] = '\0';
+		return NULL;
+
+	/*
+	 * I've seen passwd->pw_name with spaces in it (cygwin) and we use
+	 * that in the !FROGERY case -> disallow 'common' junk which is not
+	 * catched by the gnksa_check_from()
+	 */
+	if (damaged_id(buf))
+		return NULL;
+
 	return buf;
 }
 #endif /* EVIL_INSIDE */
diff -Nurp src/rfc2047.c src/rfc2047.c
--- src/rfc2047.c	2008-03-14 10:21:33.000000000 +0100
+++ src/rfc2047.c	2008-04-05 11:45:11.151407841 +0200
@@ -82,7 +82,7 @@ enum {
  */
 static FILE *compose_message_rfc822(FILE *articlefp, t_bool *is_8bit);
 static FILE *compose_multipart_mixed(FILE *textfp, FILE *articlefp);
-static int do_b_encode(char *w, char *b, int max_ewsize, t_bool isstruct_head);
+static int do_b_encode(char *w, char *b, size_t max_ewsize, t_bool isstruct_head);
 static int sizeofnextword(char *w);
 static int which_encoding(char *w);
 static t_bool contains_8bit_characters(FILE *fp);
@@ -355,7 +355,7 @@ static int
 do_b_encode(
 	char *w,
 	char *b,
-	int max_ewsize,
+	size_t max_ewsize,
 	t_bool isstruct_head)
 {
 	char tmp[60];				/* strings to be B encoded */
@@ -515,7 +515,7 @@ rfc1522_do_encode(
 	char *t;
 	char buf2[80];				/* buffer for this and that */
 	int encoding;				/* which encoding to use ('B' or 'Q') */
-	int ew_taken_len;
+	size_t ew_taken_len;
 	int word_cnt = 0;
 	int offset;
 	size_t bufferlen = 2048;		/* size of buffer */
diff -Nurp src/save.c src/save.c
--- src/save.c	2008-03-20 21:45:30.000000000 +0100
+++ src/save.c	2008-04-03 00:58:18.040388947 +0200
@@ -1133,15 +1133,10 @@ start_viewer(
 	t_mailcap *foo;
 
 	if ((foo = get_mailcap_entry(part, path)) != NULL) {
-		char buff[LEN];
-
 		if (foo->nametemplate)	/* honor nametemplate */
 			rename_file(path, foo->nametemplate);
 
 		wait_message(0, _(txt_starting_command), foo->command);
-
-		/* are the () needed if foo->command holds more than one cmd? */
-		snprintf(buff, sizeof(buff), "(%s)", foo->command);
 		if (foo->needsterminal) {
 			set_xclick_off();
 			EndWin();
diff -Nurp src/xface.c src/xface.c
--- src/xface.c	2008-03-14 10:21:33.000000000 +0100
+++ src/xface.c	2008-04-05 11:40:40.512679600 +0200
@@ -57,8 +57,9 @@ slrnface_start(
 {
 	char *fifo;
 	char *ptr;
-	int pathlen, status;
+	int status;
 	pid_t pid, pidst;
+	size_t pathlen;
 	struct utsname u;
 
 	if (!tinrc.use_slrnface)
@@ -105,8 +106,8 @@ slrnface_start(
 	}
 	pathlen = strlen(ptr) + strlen("/.slrnfaces/") + strlen(u.nodename) + 30;
 	fifo = my_malloc(pathlen);
-	sprintf(fifo, "%s/.slrnfaces", ptr);
-	if (mkdir(fifo, 0700)) {	/* TODO: use my_mkdir() */
+	snprintf(fifo, pathlen, "%s/.slrnfaces", ptr);
+	if (my_mkdir(fifo, (mode_t) S_IRWXU)) {
 		if (errno != EEXIST) {
 			perror_message(_("Can't run slrnface: failed to create %s"), fifo);
 			free(fifo);
@@ -115,8 +116,8 @@ slrnface_start(
 	} else {
 		FILE *fp;
 
-		/* We'll abuse fifo filename memory here. It's long enough. */
-		sprintf(fifo, "%s/.slrnfaces/README", ptr);
+		/* We abuse fifo filename memory here. It is long enough. */
+		snprintf(fifo, pathlen, "%s/.slrnfaces/README", ptr);
 		if ((fp = fopen(fifo, "w")) != NULL) {
 			fputs(_("This directory is used to create named pipes for communication between\n"
 "slrnface and its parent process. It should normally be empty because\n"