/*
 *  Project   : tin - a Usenet reader
 *  Module    : open.c
 *  Author    : I.Lea & R.Skrenta
 *  Created   : 01-04-91
 *  Updated   : 14-09-93
 *  Notes     : Routines to make reading news locally (ie. /usr/spool/news) 
 *              or via NNTP transparent
 *  Copyright : (c) Copyright 1991-93 by Iain Lea & Rich Skrenta
 *              You may  freely  copy or  redistribute  this software,
 *              so  long as there is no profit made from its use, sale
 *              trade or  reproduction.  You may not change this copy-
 *              right notice, and it must be included in any copy made
 */

#include	"tin.h"

int nntp_codeno = 0;
long head_next;

#ifdef NNTP_ABLE
int compiled_with_nntp = TRUE;		/* used in mail_bug_report() info */
#else
int compiled_with_nntp = FALSE;
#endif

#ifdef NO_POSTING
int	can_post = FALSE;
#else
int	can_post = TRUE;
#endif

char *nntp_server;

int 
nntp_open ()
{
#ifdef NNTP_ABLE	
	int ret;

	if (read_news_via_nntp) {
		debug_nntp ("nntp_open", "BEGIN");

		nntp_server = getserverbyfile (NNTP_SERVER_FILE);

		if (nntp_server == (char *) 0) {
			error_message (txt_cannot_get_nntp_server_name, "");
			error_message (txt_server_name_in_file_env_var, NNTP_SERVER_FILE);
			return -1;
		}

		if (update == FALSE) {
			sprintf (msg, txt_connecting, nntp_server);
			wait_message (msg);
		}
		
		debug_nntp ("nntp_open", nntp_server);

		ret = server_init (nntp_server, NNTP_TCP_NAME, NNTP_TCP_PORT);
		if (update == FALSE && ret != -1 && cmd_line) {
			fputc ('\n', stdout);
		}

		debug_nntp_respcode (ret);

		switch (ret) {
		case OK_CANPOST:
#ifndef NO_POSTING		
			can_post = TRUE;
#endif			
			break;

		case OK_NOPOST:
			can_post = FALSE;
			break;	

		case -1:
			error_message (txt_failed_to_connect_to_server, nntp_server);
			sleep (2);
			return -1;

		default:
			sprintf (msg, "%s: %s", progname, nntp_respcode (ret));
			error_message (msg, "");
			sleep (2);
			return -1;
		}

		/*
		 * If INN NNRP switch to mode reader
		 */
		debug_nntp ("nntp_open", "mode reader");
		put_server ("mode reader");	
		if (get_respcode () != ERR_COMMAND) {
			inn_nntp_server = TRUE;
		}

		/*
		 * Check if NNTP/INN supports XOVER command
		 */
		debug_nntp ("nntp_open", "xover");
		put_server ("xover");	
		if (get_respcode () != ERR_COMMAND) {
			xover_supported = TRUE;
			xindex_supported = TRUE;	/* a hack to get xindex behaviour */
		}

		/*
		 * Check if NNTP supports my XINDEX & XUSER commands
		 */
#ifndef DONT_HAVE_NNTP_EXTS	 
		debug_nntp ("nntp_open", "xindex");
		put_server ("xindex");	
		if (get_respcode () != ERR_COMMAND) {
			xindex_supported = TRUE;
		}
		
		debug_nntp ("nntp_open", "xuser");
		put_server ("xuser");	
		if (get_respcode () != ERR_COMMAND) {
			xuser_supported = TRUE;
		}
#endif	/* DONT_HAVE_NNTP_EXTS */		
		
		/*
		 * Check if NNTP server expects user authorization
		 */
		authorization (nntp_server, userid);

		/*
		 * Check if overview indexes contain Xref: lines
		 */
		xref_supported = overview_xref_support ();
	}
#ifndef DONT_HAVE_NNTP_EXTS
	/*
	 * Find out if NNTP supports SPOOLDIR command
	 */
	get_spooldir ();
#endif	/* DONT_HAVE_NNTP_EXTS */		

#endif	

	return 0;
}


void 
nntp_close ()
{
#ifdef NNTP_ABLE
	if (read_news_via_nntp) {
		debug_nntp ("nntp_close", "END");
		close_server ();
	}
#endif	
}

/*
 * Open the mail active file locally
 */

FILE *
open_mail_active_fp (mode)
	char *mode;
{
	return fopen (mail_active_file, mode);
}

/*
 * Open the news active file locally or send the LIST command via NNTP
 */

FILE *
open_news_active_fp ()
{
	int respcode;
	
	if (read_news_via_nntp) {
#ifdef NNTP_ABLE
		put_server ("list");
		if ((respcode = get_respcode ()) != OK_GROUPS) {
			debug_nntp ("open_news_active_fp", "NOT_OK");
			error_message ("%s", nntp_respcode (respcode));
			return (FILE *) 0;
		}
		debug_nntp ("open_news_active_fp", "OK");
		return nntp_to_fp ();
#else
		return (FILE *) 0;
#endif		
	} else {
		return fopen (news_active_file, "r");
	}
}

/*
 * Open the LIBDIR/overview.fmt file locally or send the LIST OVERVIEW.FMT
 * command via NNTP
 */

FILE *
open_overview_fmt_fp ()
{
	char line[NNTP_STRLEN];
	
	if (read_news_via_nntp) {
#ifdef NNTP_ABLE
		if (xover_supported) {
			sprintf (line, "list %s", OVERVIEW_FMT);
			debug_nntp ("open_overview_fmt_fp", line);
			put_server (line);
			if (get_respcode () != OK_GROUPS) {
				debug_nntp ("open_overview_fmt_fp", "NOT_OK");
				return (FILE *) 0;
			}
			debug_nntp ("open_overview_fmt_fp", "OK");
			return nntp_to_fp ();
		} else {
			return (FILE *) 0;
		}
#else
		return (FILE *) 0;
#endif		
	} else {
		joinpath (line, libdir, OVERVIEW_FMT);
		return fopen (line, "r");
	}
}

/*
 * Open the ~/.tin/active file locally or send the NEWGROUPS command via NNTP
 *
 * NEWGROUPS 311299 235959
 */

FILE *
open_newgroups_fp (index)
	int index;
{
	char line[NNTP_STRLEN];
	
	if (read_news_via_nntp) {
#ifdef NNTP_ABLE
		if (index == -1) {
			return (FILE *) 0;
		}
		sprintf (line, "newgroups %s", active_size[index].attribute);
		debug_nntp ("open_newgroups_fp", line);
		put_server (line);
		if (get_respcode () != OK_NEWGROUPS) {
			debug_nntp ("open_newgroups_fp", "NOT_OK");
			return (FILE *) 0;
		}
		debug_nntp ("open_newgroups_fp", "OK");
		return nntp_to_fp ();
#else
		return (FILE *) 0;
#endif		
	} else {
		joinpath (line, rcdir, ACTIVE_FILE);
		return fopen (line, "r");
	}
}

/*
 * Open the news motd file locally or on the NNTP server
 *
 * XMOTD 311299 235959 [GMT]
 */
 
FILE *
open_motd_fp (motd_file_date)
	char *motd_file_date; 
{
	char line[NNTP_STRLEN];
	
	if (read_news_via_nntp) {
#if defined(NNTP_ABLE) && !defined(DONT_HAVE_NNTP_EXTS)
		sprintf (line, "xmotd %s", motd_file_date);
		debug_nntp ("open_motd_fp", line);
		put_server (line);
		if (get_respcode () != OK_XMOTD) {
			debug_nntp ("open_motd_fp", "NOT_OK");
			return (FILE *) 0;
		}
		debug_nntp ("open_motd_fp", "OK");
		return nntp_to_fp ();
#else
		return (FILE *) 0;
#endif		
	} else {
		return fopen (motd_file, "r");
	}
}


FILE *
open_subscription_fp ()
{
	if (read_news_via_nntp) {
#ifdef NNTP_ABLE
		put_server ("list subscriptions");
		if (get_respcode () != OK_GROUPS) {
			debug_nntp ("open_subscription_fp", "NOT_OK");
			return (FILE *) 0;
		}
		debug_nntp ("open_subscription_fp", "OK");
		return nntp_to_fp ();
#else
		return (FILE *) 0;
#endif		
	} else {
		return fopen (subscriptions_file, "r");
	}
}

/*
 *  Open mail groups description file.
 */
 
FILE *
open_mailgroups_fp ()
{
	return fopen (mailgroups_file, "r");
}


/*
 * If reading via NNTP the newsgroups file will be saved to ~/.tin/newsgroups
 * so that any subsequent rereads on the active file will not have to waste
 * net bandwidth and the local copy of the newsgroups file can be accessed.
 */
 
FILE *
open_newsgroups_fp ()
{
	if (read_news_via_nntp) {
#ifdef NNTP_ABLE
		if (read_local_newsgroups_file) {
			debug_nntp ("open_newsgroups_fp", "Using local copy of newsgroups file");
			return fopen (local_newsgroups_file, "r");
		} else {
			put_server ("list newsgroups");
			if (get_respcode () != OK_GROUPS) {
				debug_nntp ("open_newsgroups_fp", "NOT_OK");
				return (FILE *) 0;
			}
			debug_nntp ("open_newsgroups_fp", "OK");
			return nntp_to_fp ();
		}
#else
		return (FILE *) 0;
#endif		
	} else {
		return fopen (newsgroups_file, "r");
	}
}

/*
 * Open a group XINDEX file
 */
 
FILE *
open_xindex_fp (group_name)
	char *group_name;
{
	extern char index_file[PATH_LEN];
	char line[NNTP_STRLEN];
	int group_type;
	
	group_type = find_index_file (group_name);
	if (group_type == -1) {
		return (FILE *) 0;
	}

	if (debug == 2) {
		error_message ("INDEX file=[%s]", index_file);
	}
	
	if (read_news_via_nntp && xindex_supported && group_type == GROUP_TYPE_NEWS) {
#ifdef NNTP_ABLE
		sprintf (line, "xindex %s", group_name);
		debug_nntp ("open_xindex_fp", line);
		put_server (line);
		if (get_respcode () != OK_XINDEX) {
			debug_nntp ("open_xindex_fp", "NOT_OK");
			return (FILE *) 0;
		}
		debug_nntp ("open_xindex_fp", "OK");
		return nntp_to_fp ();
#else
		return (FILE *) 0;
#endif
	} else {
		return fopen (index_file, "r");
	}
}

/*
 * Open a group XOVER file
 */
 
FILE *
open_xover_fp (group_name, min, max)
	char *group_name;
	long min;
	long max;
{
	char group_path[PATH_LEN];
	char xover_file[PATH_LEN];
	char line[NNTP_STRLEN];

	if (read_news_via_nntp && xover_supported) {
#ifdef NNTP_ABLE
		sprintf (line, "xover %ld-%ld", min, max);
		debug_nntp ("open_xover_fp", line);
		put_server (line);
		if (get_respcode () != OK_XOVER) {
			debug_nntp ("open_xover_fp", "NOT_OK");
			return (FILE *) 0;
		}
		debug_nntp ("open_xover_fp", "OK");
		return nntp_to_fp ();
#else
		return (FILE *) 0;
#endif
	} else {
		make_group_path (group_name, group_path);
		sprintf (xover_file, "%s/%s/%s", novrootdir, group_path, OVERVIEW_FILE);
		if (debug == 2) {
			error_message ("XOVER file=[%s]", xover_file);
		}
		return fopen (xover_file, "r");
	}
}

/*
 * Stat a mail/news article to see if it still exists
 */
 
int 
stat_article (art, group_path)
	long art;
	char *group_path;
{
	char buf[NNTP_STRLEN];
	int i, respcode;
	int art_exists = TRUE;
	struct stat sb;

	i = my_group[cur_groupnum];
	
	if (read_news_via_nntp && active[i].type == GROUP_TYPE_NEWS) {
#ifdef NNTP_ABLE
		sprintf (buf, "stat %ld", art);
		debug_nntp ("stat_article", buf);
		put_server (buf);
		if ((respcode = get_respcode ()) != OK_NOTEXT) {
			art_exists = FALSE;
		}
#endif
	} else {
		joinpath (buf, active[i].spooldir, group_path);
		sprintf (&buf[strlen (buf)], "/%ld", art);

		if (stat (buf, &sb) == -1) {
			art_exists = FALSE;
		}
	}

	return art_exists;
}

char *
open_art_header (art)
	long art;
{
	char *ptr, buf[NNTP_STRLEN];
	FILE *fp;
	int full, items = 0, len;
	int safe_nntp_strlen;
	static char mem[HEADER_LEN];

	if (read_news_via_nntp && active[my_group[cur_groupnum]].type == GROUP_TYPE_NEWS) {
#ifdef NNTP_ABLE
		/*
		 *  Don't bother requesting if we have not got there yet.
		 *  This is a big win if the group has got holes in it (ie. if 000's 
		 *  of articles have expired between active files min & max values).
		 */
		if (art < head_next) {
			return (char *) 0;
		}
		sprintf (buf, "head %ld", art);
		
		debug_nntp ("open_art_header", buf);

		put_server (buf);
		if (get_respcode () != OK_HEAD) {
			debug_nntp ("open_art_header", "NOT_OK_HEAD - Find NEXT");
			/*
			 *  HEAD failed, try to find NEXT
			 */
			put_server ("next");
			if (get_server (buf, NNTP_STRLEN) == -1) {
				error_message (txt_connection_to_server_broken, "");
				tin_done (1);
			}
			if (atoi (buf) == OK_NOTEXT) {
				ptr = buf;
				while (isspace(*ptr) || isdigit(*ptr)) {
					ptr++;
				}
				head_next = atoi (ptr);
			}
			return (char *) 0;
		}
		debug_nntp ("open_art_header", "OK_HEAD");

		full = FALSE;
		safe_nntp_strlen = NNTP_STRLEN - 2;
		len = safe_nntp_strlen;
		ptr = mem;
		while (1) {
			if (full || len < 32) {
				full = TRUE;
				ptr = buf;
				len = safe_nntp_strlen;
			}
			if (get_server (ptr, len) == -1) {
				error_message (txt_connection_to_server_broken, "");
				tin_done (1);
			}
			if (strcmp (ptr, ".") == 0) {	/* end of text */
				break;
			}
			if (ptr[0] == '.') {	/* reduce leading .'s */
				while (ptr[1]) {
					ptr[0] = ptr[1];
					ptr++;
					len++;
				}
			} else {
				while (*ptr) {
					ptr++;
					len++;
				}
				*ptr++ = '\n';
				*ptr = '\0';
				len++;
			}
		}
#else
		return (char *) 0;
#endif		
	} else {
		sprintf (buf, "%ld", art);
		fp = fopen (buf, "r");
		if (fp != (FILE *) 0) {
			items = fread (mem, 1, sizeof (mem)-1, fp);
			fclose (fp);
		}
/*
printf ("Artnum=[%ld] Items=[%d]\n", art, items);		
fflush (stdout);
sleep (1);
*/
		if (items == 0) {
			return (char *) 0;
		}
	}	
	return mem;
}

/*
 * Open a mail/news article
 */
 
FILE *
open_art_fp (group_path, art)
	char *group_path;
	long art;
{
	char buf[NNTP_STRLEN];
	int i, respcode;
	struct stat sb;
	extern long note_size;

	i = my_group[cur_groupnum];
	
	if (read_news_via_nntp && active[i].type == GROUP_TYPE_NEWS) {
#ifdef NNTP_ABLE
		sprintf (buf, "article %ld", art);
		debug_nntp ("open_art_fp", buf);
		put_server (buf);
		if ((respcode = get_respcode ()) != OK_ARTICLE) {
			if (debug == 2) {
				error_message ("%s", nntp_respcode (respcode));
			}
			debug_nntp ("open_art_fp", "NOT OK");
			return (FILE *) 0;
		}

		debug_nntp ("open_art_fp", "OK");

		return nntp_to_fp ();
#else
		return (FILE *) 0;
#endif
	} else {
		joinpath (buf, active[i].spooldir, group_path);
		sprintf (&buf[strlen (buf)], "/%ld", art);

		if (debug == 2) {
			error_message ("ART=[%s]", buf);
		}

		if (stat (buf, &sb) == -1) {
			note_size = 0;
		} else {
			note_size = sb.st_size;
		}
		return fopen (buf, "r");
	}
}


FILE *
open_xhdr_fp (header, min, max)
	char *header;
	long min;
	long max;
{
	char buf[NNTP_STRLEN];

	if (read_news_via_nntp) {
#ifdef NNTP_ABLE	
		sprintf(buf, "xhdr %s %ld-%ld", header, min, max);
		
		debug_nntp ("open_xhdr_fp", buf);

		put_server (buf);
		if (get_respcode () != OK_HEAD) {
			debug_nntp ("open_xhdr_fp", "NOT_OK_XHDR");
			return (FILE *) 0;
		}

		debug_nntp ("open_xhdr_fp", "OK_XHDR");

		return nntp_to_fp ();
#else
		return (FILE *) 0;
#endif		
	} else {
		return (FILE *) 0;
	}
}

/*
 *  Longword comparison routine for the qsort()
 */

int 
base_comp (p1, p2)
	t_comptype *p1;
	t_comptype *p2;
{
	long *a = (long *) p1;
	long *b = (long *) p2;

	if (*a < *b)
		return -1;
	if (*a > *b)
		return 1;
	return 0;
}


/*
 *  Read the article numbers existing in a group's spool directory
 *  into base[] and sort them.  top_base is one past top.
 */

void 
setup_base (group, group_path)
	char *group;
	char *group_path;
{
	char buf[NNTP_STRLEN];
#ifdef NNTP_ABLE
	char line[NNTP_STRLEN];
#endif
	DIR *d;
	DIR_BUF *e;
	int i;
	long art, start, last, dummy, count;

	top_base = 0;
		
	i = my_group[cur_groupnum];

	if (read_news_via_nntp && active[i].type == GROUP_TYPE_NEWS) {
#ifdef NNTP_ABLE
		sprintf (buf, "group %s", group);

		debug_nntp ("setup_base", buf);
		
		put_server (buf);

		if (get_server (line, NNTP_STRLEN) == -1) {
			error_message (txt_connection_to_server_broken, "");
			tin_done (1);
		}

		if (atoi (line) != OK_GROUP) {
			debug_nntp ("setup_base", "NOT_OK");
			return;
		}

		debug_nntp ("setup_base", line);

		sscanf (line,"%ld %ld %ld %ld", &dummy, &count, &start, &last);

		if (inn_nntp_server) {
			sprintf (buf, "listgroup %s", group);
			debug_nntp ("setup_base", buf);
			put_server (buf);
			if (get_server (line, NNTP_STRLEN) == -1) {
				error_message (txt_connection_to_server_broken, "");
				tin_done (1);
			}
			if (atoi (line) != OK_GROUP) {
				debug_nntp ("setup_base, listgroup", "NOT_OK");
				return;
			}
			debug_nntp ("setup_base", line);
			while (TRUE) {
				if (get_server (line, NNTP_STRLEN) == -1) {
					error_message (txt_connection_to_server_broken, "");
					tin_done (1);
				}
				if (strcmp (line, ".") == 0) {
					break;	/* end of text */
				}
				if (top_base >= max_art) {
					expand_art ();
				}
				base[top_base++] = atoi (line);
			}
		} else {
			if (last - count > start) {
				count = last - start;
			}

			while (start <= last) {
				if (top_base >= max_art) {
					expand_art();
				}
				base[top_base++] = start++;
			}
		}
#else
		return; 
#endif
	} else {
		joinpath (buf, active[i].spooldir, group_path);

		if (access (buf, 4) != 0) {
			return;
		}

		d = opendir (buf);
		if (d != NULL) {
			while ((e = readdir (d)) != NULL) {
#ifdef M_OS2
				art = my_atol (e->d_name, strlen (e->d_name));
#else
				art = my_atol (e->d_name, (int) e->D_LENGTH);
#endif
				if (art >= 0) {
					if (top_base >= max_art)
						expand_art ();
					base[top_base++] = art;
				}
			}
			closedir (d);
			qsort ((char *) base, top_base, sizeof (long), base_comp);
		}
	}
}

/*
 *  get a response code from the server and return it to the caller
 */

int 
get_respcode ()
{
#ifdef NNTP_ABLE
	char line[NNTP_STRLEN];

	if (get_server (line, NNTP_STRLEN) == -1) {
		error_message (txt_connection_to_server_broken, "");
		tin_done (1);
	}

	debug_nntp ("get_respcode", line);
	
	return atoi (line);
#else
	return (0);
#endif
}


int 
stuff_nntp (fnam)
	char *fnam;
{
#ifdef NNTP_ABLE
	FILE *fp;
	char line[HEADER_LEN];
	extern char *mktemp ();
	struct stat sb;
	extern long note_size;

	sprintf (fnam, "%stin_nntpXXXXXX", TMPDIR);
	mktemp (fnam);

	if ((fp = fopen (fnam, "w")) == (FILE *) 0) {
		perror_message (txt_stuff_nntp_cannot_open, fnam);
		return FALSE;
	}

	while (1) {
		if (get_server (line, sizeof (line)-1) == -1) {
			error_message (txt_connection_to_server_broken, "");
			tin_done (1);
		}

		debug_nntp ("stuff_nntp", line);
		
		if (strcmp (line, ".") == 0) {	/* end of text */
			break;
		}
		strcat (line, "\n");
		if (line[0] == '.') {		/* reduce leading .'s */
			fputs (&line[1], fp);
		} else {
			fputs (line, fp);
		}
	}
	fclose (fp);

	if (stat (fnam, &sb) < 0) {
		note_size = 0;
	} else {
		note_size = sb.st_size;
	}
	return TRUE;
#else
	return TRUE;
#endif
}


FILE *
nntp_to_fp ()
{
#ifdef NNTP_ABLE
	char fnam[PATH_LEN];
	FILE *fp = (FILE *) 0;
	
	if (! stuff_nntp (fnam)) {
		debug_nntp ("nntp_to_fp", "! stuff_nntp()");
		return (FILE *) 0;
	}

	if ((fp = fopen (fnam, "r")) == (FILE *) 0) {
		perror_message (txt_nntp_to_fp_cannot_reopen, fnam);
		return (FILE *) 0;
	}
	
	unlink (fnam);
	return fp;
#else
	return (FILE *) 0;
#endif
}

/*
 * Log user info to local file or NNTP logfile
 */

void 
log_user ()
{
	char dummy[PATH_LEN];
	char log_file[PATH_LEN];
	char buf[32], *ptr;
	char line[NNTP_STRLEN];
#ifndef DONT_LOG_USER
	FILE *fp;
	long epoch;
#endif
#ifndef M_AMIGA
	extern struct passwd *myentry;

	get_user_info (dummy, buf);

	if (read_news_via_nntp && xuser_supported) {
		if ((ptr = (char *) strchr(buf, ','))) {
			*ptr = '\0';
		}
		sprintf (line, "xuser %s (%s)", myentry->pw_name, buf);

		debug_nntp ("log_user", line);
		put_server (line);
	} else
#endif	/* M_AMIGA */
	{
#ifndef DONT_LOG_USER
		joinpath (log_file, TMPDIR, LOG_USER_FILE);
		
		if ((fp = fopen (log_file, "a+")) != (FILE *) 0) {
			time (&epoch);
			fprintf (fp, "%s%s: %-32s (%-8s) %s", 
				VERSION, PATCHLEVEL,
#ifdef M_AMIGA
				get_val ("REALNAME", "Unknown"),
				get_val ("USERNAME", "Unknown"),
#else
				buf,
				myentry->pw_name, 
#endif
				ctime (&epoch));
			fclose (fp);
			chmod (log_file, 0666);
		}	
#endif	/* DONT_LOG_USER */
	}
}

/*
 * NNTP user authorization. Password read from ~/.newsauth
 * The ~/.newsauth authorization file has the format:  
 *   nntpserver1 password
 *   nntpserver2 password
 *   etc.
 */
 
void 
authorization (server, authuser)
	char *server;
	char *authuser;
{
	char authfile[PATH_LEN];
	char authpass[PATH_LEN];
	char line[NNTP_STRLEN];
	char buf[PATH_LEN], *ptr;
	int found = FALSE;
	FILE *fp;

	/*
	 * Check if running via NNTP
	 */
	if (! read_news_via_nntp) {
		return;
	}

	/*
	 * Lets check if the NNTP supports authorization
	 */
	debug_nntp ("authorization", "authinfo");
	put_server ("authinfo");
	if (get_respcode () == ERR_COMMAND) {
		return;
	}

	joinpath (authfile, homedir, ".newsauth");

	if ((fp = fopen (authfile,"r")) != (FILE *) 0) {
		/*
		 * Search through authorization file for correct NNTP server
		 * File has format:  'nntp-server' 'password'
		 */
		while (fgets (buf, sizeof (buf), fp) != (char *) 0) {
			/*
			 * Get server from 1st part of the line
			 */
			strcpy (line, buf); 
			ptr = (char *) strchr (line, ' ');
			if (ptr != (char *) 0) {
				*ptr = '\0';
			}

			if (strncmp (line, server, sizeof (server)) == 0) {
				/*
				 * Get passwdord from 2nd part of the line
				 */
				ptr = (char *) strrchr (buf, ' ');
				if (ptr != (char *) 0 && ++ptr != (char *) 0) {
					strcpy (authpass, ptr); 
					ptr = (char *) strchr (authpass, '\n');
					if (ptr != (char *) 0) {
						*ptr = '\0';
					}
					found = TRUE;
				}
				break;
			}
		}
		fclose (fp); 

		if (! found) {
			error_message (txt_nntp_authorization_failed, authuser);
		} else {
			sprintf (line, "authinfo user %s", authuser);
			put_server (line);
			get_respcode ();

			sprintf (line, "authinfo pass %s", authpass);
			put_server (line);
			get_respcode ();
		}
	}
}
