/*
 *  Project   : tin - a threaded Netnews reader
 *  Module    : init.c
 *  Author    : I.Lea
 *  Created   : 01-04-91
 *  Updated   : 20-06-92
 *  Notes     :
 *  Copyright : (c) Copyright 1991-92 by Iain Lea
 *              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"

char rcdir[PATH_LEN];
char rcfile[PATH_LEN];
char indexdir[PATH_LEN];
char killfile[PATH_LEN];
char postfile[PATH_LEN];
char unthreadfile[PATH_LEN];
char cvers[LEN];
char nntp_server[LEN];
char active_file[PATH_LEN];
char newsgroups_file[PATH_LEN];
char subscriptions_file[PATH_LEN];
char homedir[PATH_LEN];
char userid[LEN];
char delgroups[LEN];
char default_maildir[PATH_LEN];			/* mailbox dir where = saves are stored */
char newsrc[PATH_LEN];
char newnewsrc[PATH_LEN];
char add_addr[LEN];			/* address to add to rR reply to author with mail */
char bug_addr[LEN];			/* address to add send bug reports to */
char txt_help_bug_report[LEN];	/* address to add send bug reports to */
char reply_to[LEN];			/* Reply-To: address */
char my_org[LEN];			/* Organization: */
char my_distribution[LEN];		/* Distribution: */
char default_select_pattern[LEN];
char default_sigfile[PATH_LEN];
char default_signature[PATH_LEN];
char default_shell_command[LEN];	/* offers user default choice */
char killsubj[LEN];			/* contains Subject:'s not to be shown */
char killfrom[LEN];			/* conatins From:'s not to be shown */
char page_header[LEN];		/* page header of pgm name and version */
char default_savedir[PATH_LEN];			/* directory to save articles to */
char spooldir[PATH_LEN];		/* directory where news is */
char spooldir_alias[PATH_LEN];		/* alias of spooldir being used */
char mail_news_user[LEN];	/* mail new news to this user address */
char mailer[PATH_LEN];			/* mail program */
char mailbox[PATH_LEN];			/* system mailbox for each user */
char printer[LEN];			/* printer program specified from tinrc */
char cmd_line_printer[LEN];	/* printer program specified on cmd line */
char article[PATH_LEN];			/* ~/.article file */
char dead_article[PATH_LEN];	/* ~/dead.article file */
char progname[PATH_LEN];		/* program name */
char redirect_output[LEN];	/* /dev/null or nothing if -D option */

int xindex_supported = FALSE;
int xuser_supported = FALSE;
int xspooldir_supported = FALSE;
int NOTESLINES;						/* set in set_win_size () */
int RIGHT_POS;						/* set in set_win_size () */
int MORE_POS;						/* set in set_win_size () */
int confirm_action;
int max_subj = 0;
int max_from = 0;
int max_active;
int num_active;						/* one past top of active */
int group_top;						/* one past top of my_group */
int groupname_len = 0;					/* one past top of my_group */
int catchup = FALSE;				/* mark all arts read in all subscribed groups */
int update_fork = FALSE;			/* update index files by forked tin -u */
int verbose = FALSE;				/* update index files only mode */
int start_line_offset;				/* used by invoke_editor for line no. */
int inn_nntp_server = FALSE;			/* read news via INN NNTP */
int read_news_via_nntp = FALSE;		/* read news locally or via NNTP */
int local_index;					/* do private indexing? */
int max_art;
int real_gid;
int real_uid;
int real_umask;
int show_description;
int start_editor_offset;
int tin_uid;
int tin_gid;
int top = 0;
int top_base;
int check_any_unread = FALSE;
int notify_new_groups = FALSE;
int start_any_unread = FALSE;

int catchup_read_groups;	/* ask if read groups are to be marked read */
int cmd_line;				/* batch / interactive mode */
int created_rcdir;			/* checks if first time tin is started */
int default_printer;		/* set to false if user give a printer with -p switch */
int default_show_author;	/* show_author value from 'M' menu in tinrc */
int draw_arrow_mark;		/* draw -> or highlighted bar */
int full_page_scroll;		/* page half/full screen of articles/groups */
int killed_articles;		/* killed / auto-selected hot articles */
int mark_saved_read;		/* mark saved article/thread as read */
int num_of_hot_arts;
int num_of_killed_arts;
int num_of_tagged_arts;
int process_id;
int pos_first_unread;		/* position cursor at first/last unread article */
int post_proc_type;			/* type of post processing to be performed */
int print_header;			/* print all of mail header or just Subject: & From lines */
int save_archive_name;		/* save thread with name from Archive-name: field */
int mail_news;				/* mail all arts to specified user */
int save_news;				/* save all arts to savedir structure */
int show_author;			/* show Subject & From or only Subject in group menu */
int show_only_unread;		/* show only new/unread arts or all arts */
int spooldir_is_active;			/* set TRUE if current spooldir is active news feed */
int sort_art_type;			/* sort arts[] array by subject,from or date field */
int thread_arts;			/* thread/unthread articles for viewing */
int system_status;

#ifdef INDEX_DAEMON
int update = TRUE;					/* update index files only mode */
#else
int update = FALSE;					/* update index files only mode */
#endif

struct passwd *myentry;


/*
 * Get users home directory, userid, and a bunch of other stuff!
 */

void init_selfinfo ()
{
	extern char *getlogin ();
	extern struct passwd *getpwnam ();
	char nam[LEN];
	char *p;
	FILE *fp;
	struct stat sb;

	process_id = getpid ();
	
	tin_uid = geteuid ();
	tin_gid = getegid ();
	real_uid = getuid ();
	real_gid = getgid ();

	real_umask = umask (0);
	umask (real_umask);
	
#ifdef SVR4
	setlocale (LC_ALL, "");
#endif
		
	/*
	 * we're setuid, so index in /usr/spool/news even if user root
	 * This is quite essential if non local index files are 
	 * to be updated during the night from crontab by root.
	 */
	if (tin_uid != real_uid) {
		local_index = FALSE;
		set_real_uid_gid ();

	} else {	/* index in users home directory ~/.tin/.index */
		local_index = TRUE;
	}

	myentry = (struct passwd *) 0;
	if (((p = getlogin ()) != (char *) 0) && strlen (p)) {
		myentry = getpwnam (p);
	} else {
		myentry = getpwuid (getuid ());
	}

	strcpy (userid, myentry->pw_name);

	if ((p = (char *) getenv ("HOME")) != NULL) {
		strcpy (homedir, p);
	} else {
		strcpy (homedir, myentry->pw_dir);
	}

	catchup_read_groups = FALSE;
	confirm_action = TRUE;
	created_rcdir = FALSE;
#ifdef USE_INVERSE_HACK
	inverse_okay = FALSE;
	draw_arrow_mark = TRUE;
#else
	draw_arrow_mark = FALSE;
#endif
	default_move_group = 0;
#ifdef BSD
	default_printer = TRUE;
#else	
	default_printer = FALSE;
#endif
	default_show_author = SHOW_FROM_NAME;
	full_page_scroll = TRUE;
	killed_articles = FALSE;
	mark_saved_read = TRUE;
	num_of_hot_arts = 0;
	num_of_killed_arts = 0;
	num_of_tagged_arts = 0;
	post_proc_type = POST_PROC_NONE;
	pos_first_unread = TRUE;
	print_header = FALSE;
	save_archive_name = TRUE;
	save_news = FALSE;
	show_only_unread = FALSE;
	show_description = TRUE;
	sort_art_type = SORT_BY_DATE_ASCEND;
	start_editor_offset = TRUE;
	thread_arts = TRUE;
	
	killsubj[0] = '\0';
	killfrom[0] = '\0';
	
	cmd_line_printer[0] = '\0';
	default_author_search[0] = '\0';
	default_goto_group[0] = '\0';
	default_group_search[0] = '\0';
	default_subject_search[0] = '\0';
	default_art_search[0] = '\0';
	default_crosspost_group[0] = '\0';
	default_mail_address[0] = '\0';
	default_pipe_command[0] = '\0';
	default_post_subject[0] = '\0';
	default_regex_pattern[0] = '\0';
	default_save_file[0] = '\0';
	default_select_pattern[0] = '\0';
	default_shell_command[0] = '\0';
	nntp_server[0] = '\0';
	proc_ch_default = 'n';

	/*
	 * set start spooldir to active newsfeed
	 */
	strcpy (spooldir_alias, "news");
	strcpy (spooldir, SPOOLDIR);

	set_tindir ();	

	sprintf (active_file, "%s/active", LIBDIR);
	sprintf (article, "%s/.article", homedir);
	sprintf (dead_article, "%s/dead.article", homedir);
	sprintf (delgroups, "%s/.delgroups", homedir);
	sprintf (mailbox, "%s/%s", DEFAULT_MAILBOX, userid);
	sprintf (default_maildir, "%s/%s", homedir, DEFAULT_MAILDIR);
	sprintf (default_savedir, "%s/News", homedir);
	sprintf (default_sigfile, "%s/.Sig", homedir);
	sprintf (default_signature, "%s/.signature", homedir);
	sprintf (newsgroups_file, "%s/newsgroups", LIBDIR);
	sprintf (subscriptions_file, "%s/subscriptions", LIBDIR);

	strcpy (mailer, get_val ("MAILER", DEFAULT_MAILER));
	strcpy (printer, DEFAULT_PRINTER);
	strcpy (spooldir, SPOOLDIR);
	strcpy (bug_addr, BUG_REPORT_ADDRESS);
	strcpy (redirect_output, "> /dev/null 2>&1");

#ifdef INDEX_DAEMON
	/*
	 * Check for lock file to stop multiple copies of tind running and
	 * if it does not exist create it so this is the only copy running
	 */
	if (stat (LOCK_FILE, &sb) == 0) {
		if ((fp = fopen (LOCK_FILE, "r")) != (FILE *) 0) {
			fgets (nam, sizeof (nam), fp);
			fclose (fp);
			fprintf(stderr, "%s: Already started pid=[%d] on %s", 
				progname, atoi(nam), nam+8);
			exit (1);
		}
	} else {
		{
			long epoch;
			
			if ((fp = fopen (LOCK_FILE, "w")) != (FILE *) 0) {
				time (&epoch);
				fprintf (fp, "%6d  %s", process_id, ctime (&epoch));
				fclose (fp);
				chmod (LOCK_FILE, 0600);
			}
		}	
	}
	 
	strcpy (newsrc, active_file);	/* so that all groups are indexed */
	sprintf (indexdir, "%s/.index", spooldir);

	if (stat (indexdir, &sb) == -1) {
		mkdir (indexdir, 0777);
	}
#else
	if (stat (rcdir, &sb) == -1) {
		created_rcdir = TRUE;
		mkdir (rcdir, 0755);
	}
	if (tin_uid != real_uid) {
		sprintf (indexdir, "%s/.index", spooldir);

		set_tin_uid_gid ();
		if (stat (indexdir, &sb) == -1) {
			mkdir (indexdir, 0777);
		}
		set_real_uid_gid ();
	} else if (stat (indexdir, &sb) == -1) {
		mkdir (indexdir, 0755);
	}
	if (stat (postfile, &sb) == -1) {
		if ((fp = fopen (postfile, "w")) != NULL) {
			fclose (fp);
		}
	}
	if (stat (unthreadfile, &sb) == -1) {
		if ((fp = fopen (unthreadfile, "w")) != NULL) {
			fclose (fp);
		}
	}

	read_rcfile ();

	show_author = default_show_author;

#endif /* INDEX_DAEMON */	

	if (stat (active_file, &sb) >= 0)
		goto got_active;

	/*
	 *  I hate forgetting to define LIBDIR correctly.  Guess a couple
	 *  of the likely places if it's not where LIBDIR says it is.
	 */

	strcpy (active_file, "/usr/lib/news/active");
	if (stat (active_file, &sb) >= 0)
		goto got_active;

	strcpy (active_file, "/usr/local/lib/news/active");
	if (stat (active_file, &sb) >= 0)
		goto got_active;

	strcpy (active_file, "/usr/public/lib/news/active");
	if (stat (active_file, &sb) >= 0)
		goto got_active;

	/*
	 *  Oh well. Revert to what LIBDIR says it is to produce a useful
	 *  error message when read_active_file () fails later.
	 */

	sprintf (active_file, "%s/active", LIBDIR);

got_active:

	/*
	 *  check enviroment for ORGANIZATION / NEWSORG
	 */
	my_org[0] = '\0';
#ifdef apollo
	if ((p = (char *) getenv ("NEWSORG")) != NULL) {
#else	
	if ((p = (char *) getenv ("ORGANIZATION")) != NULL) {
#endif
		my_strncpy (my_org, p, sizeof (my_org));
		goto got_org;
	}

	/*
	 *  check ~/.tin/organization for organization
	 */
	sprintf (nam, "%s/organization", rcdir);
	fp = fopen (nam, "r");

	/*
	 *  check LIBDIR/organization for system wide organization
	 */
	if (fp == NULL) {
		sprintf (nam, "%s/organization", LIBDIR);
		fp = fopen (nam, "r");
	}

	if (fp == NULL) {
		sprintf (nam, "/usr/lib/news/organization");
		fp = fopen (nam, "r");
	}

	if (fp == NULL) {
		sprintf (nam, "/usr/local/lib/news/organization");
		fp = fopen (nam, "r");
	}

	if (fp == NULL) {
		sprintf (nam, "/usr/public/lib/news/organization");
		fp = fopen (nam, "r");
	}

	if (fp == NULL) {
		sprintf (nam, "/etc/organization");
		fp = fopen (nam, "r");
	}

	if (fp != NULL) {
		if (fgets (my_org, sizeof (my_org), fp) != NULL) {
			for (p = my_org; *p && *p != '\n'; p++)
				continue;
			*p = '\0';
		}
		fclose (fp);
	}

got_org:;

	/*
	 *  check enviroment for REPLYTO
	 */
	reply_to[0] = '\0';
	if ((p = (char *) getenv ("REPLYTO")) != NULL) {
		my_strncpy (reply_to, p, sizeof (reply_to));
		goto got_reply;
	}

	sprintf (nam, "%s/replyto", rcdir);
	if ((fp = fopen (nam, "r")) != NULL) {
		if (fgets (reply_to, sizeof (reply_to), fp) != NULL) {
			reply_to[strlen (reply_to)-1] = '\0';
		}
		fclose (fp);
	}

got_reply:;

	/*
	 *  check enviroment for DISTRIBUTION
	 */
	my_distribution[0] = '\0';
	if ((p = (char *) getenv ("DISTRIBUTION")) != NULL) {
		my_strncpy (my_distribution, p, sizeof (my_distribution));
	}

	/*
	 *  check enviroment for ADD_ADDRESS
 	 */
	add_addr[0] = '\0';
	if ((p = (char *) getenv ("ADD_ADDRESS")) != NULL) {
		my_strncpy (add_addr, p, sizeof (add_addr));
		goto got_add_addr;
	}

	sprintf (nam, "%s/add_address", rcdir);
	if ((fp = fopen (nam, "r")) != NULL) {
		if (fgets (add_addr, sizeof (add_addr), fp) != NULL) {
			add_addr[strlen (add_addr)-1] = '\0';
		}
		fclose (fp);
	}

got_add_addr:;

	/*
	 *  check enviroment for BUG_ADDRESS
	 */
	if ((p = (char *) getenv ("BUG_ADDRESS")) != NULL) {
		my_strncpy (bug_addr, p, sizeof (bug_addr));
		goto got_bug_addr;
	}

	sprintf (nam, "%s/bug_address", rcdir);
	if ((fp = fopen (nam, "r")) != NULL) {
		if (fgets (bug_addr, sizeof (bug_addr), fp) != NULL) {
			bug_addr[strlen (bug_addr)-1] = '\0';
		}
		fclose (fp);
	}

got_bug_addr:;
	sprintf (txt_help_bug_report, txt_help_bug, bug_addr);
}

/*
 * Set up ~/.tin directory & support files depending on where the news
 * is being read from (ie. active news / CD-ROM spooldir).  Note that
 * any control files which may be specific to a given spooldir (various
 * CD issues versus live news) should be under the spooldir_alias 
 * subdirectory also.
 */
 
void set_tindir ()
{
	struct stat sb;
	
	if (strcmp (spooldir_alias, "news") != 0) {
		sprintf (rcdir,  "%s/%s", get_val ("TINDIR", homedir), RCDIR);
		/*
		 * Create directories
		 */
		if (stat (rcdir, &sb) == -1) {
			mkdir (rcdir, 0755);
		}
		sprintf (rcdir, "%s/%s", rcdir, spooldir_alias); 
		if (stat (rcdir, &sb) == -1) {
			created_rcdir = TRUE;
			mkdir (rcdir, 0755);
		}
		/*
		 * Use a separate .newsrc file for every spooldir 
		 */
		sprintf (newsrc, "%s/.newsrc", rcdir);
		sprintf (newnewsrc, "%s/.newnewsrc", rcdir);

		spooldir_is_active = FALSE;
		reread_active_file = FALSE;
		alarm (0);
	} else {
		if (stat (rcdir, &sb) == -1) {
			mkdir (rcdir, 0755);
		}
		sprintf (rcdir,  "%s/%s", get_val ("TINDIR", homedir), RCDIR);
		sprintf (rcfile,   "%s/%s", rcdir, RCFILE);
		sprintf (killfile, "%s/%s", rcdir, KILLFILE);
		sprintf (postfile, "%s/%s", rcdir, POSTFILE);
		sprintf (unthreadfile, "%s/%s", rcdir, UNTHREADFILE);
		sprintf (newsrc, "%s/.newsrc", homedir);
		sprintf (newnewsrc, "%s/.newnewsrc", homedir);

		spooldir_is_active = TRUE;
		reread_active_file = TRUE;
	}
	sprintf (indexdir, "%s/%s", rcdir, INDEXDIR);
	if (stat (indexdir, &sb) == -1) {
		mkdir (indexdir, 0755);
	}
}


int create_mail_save_dirs ()
{
	int created = FALSE;
	struct stat sb;
	
	if (stat (default_maildir, &sb) == -1) {
		mkdir (default_maildir, 0755);
		created = TRUE;
	}
	if (stat (default_savedir, &sb) == -1) {
		mkdir (default_savedir, 0755);
		created = TRUE;
	}
	
	return (created);
}
