/*
 *  Project   : tin - a threaded Netnews reader
 *  Module    : tin.h
 *  Author    : I.Lea & R.Skrenta
 *  Created   : 01-04-91
 *  Updated   : 22-06-92
 *  Notes     : #include files, #defines & struct's
 *  Copyright : (c) Copyright 1991-92 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	<stdio.h>
#include	<signal.h>
#include	<errno.h>
#ifdef apollo
#	include </bsd4.3/usr/include/sys/types.h>
#else
#	include <sys/types.h>
#endif
#include	<sys/stat.h>
#include	<pwd.h>
#include	<ctype.h>
#include	<time.h>
#if !defined(apollo) && !defined(__NeXT__)
#	include	<unistd.h>
#endif

#ifdef BSD
#	include	<strings.h>
#	include	<fcntl.h>
#else
#	ifndef apollo
#		include	<stdlib.h>
#	endif
#	include	<string.h>
#endif

#ifndef MINIX
#	include <sys/ioctl.h>
#endif

#ifdef M_XENIX
#	include	<prototypes.h>
#endif

#ifdef SVR4
#	include <locale.h>
#endif

#if !defined(BSD) && !defined(sinix) && !defined(RS6000)
#	include	<sys/utsname.h>
#endif

/*
 * Needed for catching child processes
 */

#ifdef SIGCHLD
#	include	<sys/wait.h>
#endif

/*
 * Needed for resizing under an xterm
 */

#if defined(SIGWINCH)
#	ifndef SCO_UNIX
#		include <termios.h>
#	endif
#	if !defined(TIOCGWINSZ) && !defined(TIOCGSIZE)
#		if !defined(sinix) && !defined(nsc)
#			include <sys/stream.h>
#			ifdef PTX
#				include <termio.h>
#			else
#				ifndef apollo
#					include <sys/ptem.h>
#					include <sys/tty.h>
#				endif
#				if !defined(SCO_UNIX) && !defined(SVR4) && !defined(apollo)
#					ifndef _h_BSDTYPES
#						include <sys/bsdtypes.h>
#					endif
#					include <sys/pty.h>
#				endif
#			endif
#		endif
#	endif
#endif

/*
 * Setup support for reading from CD-ROM
 */

#ifdef CDROM_ONLY
#	define CDROM_ABLE
#endif
 
#ifdef CDROM_ABLE
#	define XSPOOLDIR
#	define NNTP_ABLE
#	undef NNTP_ONLY
#	undef NNTP_INEWS
#endif

/*
 * Setup support for reading from NNTP
 */
 
#if defined(NNTP_ABLE) || defined(NNTP_ONLY)
#	ifndef NNTP_ABLE
#		define	NNTP_ABLE
#	endif
#	ifndef NNTP_INEWS
#		define	NNTP_INEWS
#	endif
#endif

/*
 * Index file daemon version of tin. Will create/update index files from cron
 * on NNTP server machine so clients can retreive index file with NNTP XINDEX
 * command from server. Also can be used on machines that just want one copy
 * of all the index files in one place. In this case the normal tin must have
 * access to the index directory (-I dir option) or be setuid news.
 */
 
#ifdef INDEX_DAEMON
#	define	LOCK_FILE "/tmp/tind.LCK"
#	undef	NNTP_ABLE
#	undef	NNTP_ONLY
#	undef	NNTP_INEWS
#endif

/*
 * Determine signal return type
 */
 
#if defined(__GNUC__) || defined(POSIX_JOB_CONTROL)
typedef void sigtype_t;
#else	
#	if defined(sony)
typedef int sigtype_t;
#	else
#		if __STDC__ || defined(SVR4) || defined(sinix) || defined(sun) || \
		   defined(ultrix) || defined(atthcx) || defined(PTX) || defined(sgi)
typedef void sigtype_t;
#		else
typedef int sigtype_t;
#		endif
#	endif
#endif

/*
 * Specify News spool & control directories
 */
 
#ifndef SPOOLDIR
#	define		SPOOLDIR	"/usr/spool/news"
#endif
#ifndef LIBDIR
#	define		LIBDIR		"/usr/lib/news"
#endif
#ifndef INEWSDIR
#	define		INEWSDIR	LIBDIR
#endif

/*
 * Determine machine configuration for external programs & directories
 */

#ifdef BSD
#	if defined(_SEQUENT_) || defined(pyr)
#		define		memcmp(s1, s2, n)	bcmp(s2, s1, n)
#	endif
#	define		strchr(str, ch)	index(str, ch)
#	define		DEFAULT_SHELL	"/bin/csh"
#	define		DEFAULT_EDITOR	"/usr/ucb/vi"
#	define		DEFAULT_PRINTER	"/usr/ucb/lpr"
#	define		DEFAULT_SUM	"sum"
#	ifdef DGUX
#		define		DEFAULT_MAILER	"/bin/mail"
#		define		DEFAULT_MAILBOX	"/usr/mail"
#		define		POSIX_JOB_CONTROL
#		define		USE_INVERSE_HACK
#	endif
#	ifdef pyr
#		define		DEFAULT_MAILER	"/usr/.attbin/mailx"
#	endif
#	ifndef DEFAULT_MAILER
#		define		DEFAULT_MAILER	"/usr/ucb/Mail"
#	endif
#	ifndef DEFAULT_MAILBOX
#		define		DEFAULT_MAILBOX	"/usr/spool/mail"
#	endif
#	ifndef USE_LONG_FILENAMES
#		define USE_LONG_FILENAMES
#	endif
#else
#	ifdef M_XENIX
#		define		DEFAULT_EDITOR	"/bin/vi"
#		define		DEFAULT_MAILER	"/usr/bin/mail"
#		define		DEFAULT_MAILBOX	"/usr/spool/mail"
#	endif
#	if defined(NCR) || defined(atthcx) || defined(HPUX)
#		define		DEFAULT_MAILER	"/usr/bin/mailx"
#	endif
#	ifdef PTX
#		define		DEFAULT_MAILER	"/usr/bin/mailx"
#		ifndef USE_LONG_FILENAMES
#			define	USE_LONG_FILENAMES
#		endif
#	endif
#	ifdef RS6000
#		define		DEFAULT_MAILER	"/usr/bin/mail"
#		define		DEFAULT_PRINTER	"/bin/lp"
#	endif
#	ifdef sinix
#		define		DEFAULT_MAILER	"/bin/rmail"
#		define		DEFAULT_PRINTER	"/bin/lpr"
#		ifndef USE_LONG_FILENAMES
#			define USE_LONG_FILENAMES
#		endif
#	endif
#	ifdef SVR4
#		define		POSIX_JOB_CONTROL
#		ifndef USE_LONG_FILENAMES
#			define	USE_LONG_FILENAMES
#		endif
#	endif
#	ifdef UNIXPC
#		define		DEFAULT_MAILER	"/bin/rmail"
#	endif
#	ifndef DEFAULT_SHELL
#		define		DEFAULT_SHELL	"/bin/sh"
#	endif
#	ifndef DEFAULT_EDITOR
#		define		DEFAULT_EDITOR	"/usr/bin/vi"
#	endif
#	ifndef DEFAULT_MAILBOX
#		define		DEFAULT_MAILBOX	"/usr/mail"
#	endif
#	ifndef DEFAULT_MAILER
#		define		DEFAULT_MAILER	"/bin/mail"
#	endif
#	ifndef DEFAULT_PRINTER
#		define		DEFAULT_PRINTER	"/usr/bin/lp"
#	endif
#	define		DEFAULT_SUM		"sum -r"
#endif

#ifdef USE_LONG_FILENAMES
#	define		LONG_PATH_PART	"part"
#	define		LONG_PATH_PATCH	"patch"
#else
#	define		LONG_PATH_PART	""
#	define		LONG_PATH_PATCH	"p"
#endif

/*
 * Useful for logging user usage
 */
 
#ifdef LOG_USER
#	define		LOG_USER_FILE	"/tmp/.tin_log" 
#endif

/*
 * Should active file be rereaf for new news & if so how often
 */
 
#ifndef NO_RESYNC_ACTIVE_FILE
#	ifndef RESYNC_ACTIVE_SECS
#		define	RESYNC_ACTIVE_SECS	300	/* reread active every n secs */
#	endif
#endif

/*
 * Initial sizes of internal arrays for small (<4MB) & large memory machines
 */
 
#ifdef SMALL_MEMORY_MACHINE
#	define		DEFAULT_ACTIVE_NUM	1800	
#	define		DEFAULT_ARTICLE_NUM	400	
#	define		DEFAULT_KILL_NUM	10	
#	define		DEFAULT_SAVE_NUM	10	
#else
#	define		DEFAULT_ACTIVE_NUM	1800	
#	define		DEFAULT_ARTICLE_NUM	1200	
#	define		DEFAULT_KILL_NUM	30	
#	define		DEFAULT_SAVE_NUM	30	
#endif

#define		RCDIR			".tin"
#define		RCFILE			"tinrc"
#define		INDEXDIR		".index"
#define		KILLFILE		"kill"
#define		POSTFILE		"posted"
#define		UNTHREADFILE	"unthread"
#define		DEFAULT_MAILDIR	"Mail"

#define BUG_REPORT_ADDRESS	"iain%anl433.uucp@Germany.EU.net"

#ifdef TRUE
#	undef TRUE
#endif
#define		TRUE		1

#ifdef FALSE
#	undef FALSE
#endif
#define		FALSE		0

#define		LEN				1024
#define		PATH_LEN			256
#define		HEADER_LEN			1024
#define		MODULO_COUNT_NUM		5
#define		TABLE_SIZE			1409
#define		MAX_PAGES			1000
#define		ctrl(c)				((c) & 0x1F)

#ifndef DEFAULT_COMMENT
#	define		DEFAULT_COMMENT	": "	/* used when by follow-ups & replys */
#endif
#ifndef UNREAD_ART_MARK
#	define		UNREAD_ART_MARK	'+'	/* used to show that an art is unread */
#endif
#ifndef RETURN_ART_MARK
#	define		RETURN_ART_MARK	'-'	/* used to show that an art will return */
#endif
#ifndef HOT_ART_MARK
#	define		HOT_ART_MARK	'*'	/* used to show that an art was auto selected */
#endif
#ifndef READ_ART_MARK
#	define		READ_ART_MARK	' '	/* used to show that an art was not read or seen  */
#endif

#ifdef USE_INVERSE_HACK
#	define		SELECT_MISC_COLS	21
#	define		BLANK_GROUP_COLS	2
#	define		BLANK_PAGE_COLS		2
#else
#	define		SELECT_MISC_COLS	21
#	define		BLANK_GROUP_COLS	0
#	define		BLANK_PAGE_COLS		0
#endif

#define		SCREEN_READ_UNREAD		6		/* position for "  +" / "   " */
#define		INDEX_TOP				2

#ifdef NO_REGEX 
#	define STR_MATCH(s1,s2)	(str_str (s1, s2, strlen (s2)) != 0)
#else		
#	define STR_MATCH(s1,pat)	(wildmat (s1, pat))
#endif

#define IGNORE_ART(i)	((arts[i].thread == ART_EXPIRED) || \
			 (arts[i].killed && kill_level > 0))

/*
 *  used by get_arrow_key()
 */

#define		KEYMAP_UNKNOWN			0
#define		KEYMAP_UP				1
#define		KEYMAP_DOWN				2
#define		KEYMAP_PAGE_UP			3
#define		KEYMAP_PAGE_DOWN		4
#define		KEYMAP_HOME				5
#define		KEYMAP_END				6

/*
 *  used by feed.c - feed_articles()
 */
 
#define		SELECT_LEVEL				1
#define		GROUP_LEVEL				2
#define		PAGE_LEVEL				3

#define		FEED_MAIL				1
#define		FEED_PIPE				2
#define		FEED_PRINT				3
#define		FEED_SAVE				4
#define		FEED_XPOST				5

/*
 *  used in art.c & rcfile.c
 */
 
#define		SORT_BY_NOTHING			0		/* sort types on arts[] array */
#define		SORT_BY_SUBJ_DESCEND	1
#define		SORT_BY_SUBJ_ASCEND		2
#define		SORT_BY_FROM_DESCEND	3
#define		SORT_BY_FROM_ASCEND		4
#define		SORT_BY_DATE_DESCEND	5
#define		SORT_BY_DATE_ASCEND		6

#define		SHOW_FROM_NONE			0
#define		SHOW_FROM_ADDR			1
#define		SHOW_FROM_NAME			2
#define		SHOW_FROM_BOTH			3

/*
 *  used in help.c
 */

#define		HELP_INFO				0
#define		POST_INFO				1

/*
 *  used in save.c
 */

#define		CHECK_ANY_NEWS			0
#define		START_ANY_NEWS			1
#define		MAIL_ANY_NEWS			2
#define		SAVE_ANY_NEWS			3

/*
 *  used in help.c
 */

#define		HEADER_TO				0
#define		HEADER_SUBJECT			1

/*
 *  used in page.c & post.c
 */

#define		POSTED_NONE				0
#define		POSTED_REDRAW			1
#define		POSTED_OK				2

/*
 *  Assertion verifier
 */

#if __STDC__ && !defined(apollo)
#	define	assert(p)	if(! (p)) asfail(__FILE__, __LINE__, #p); else
#else
#	define	assert(p)	if(! (p)) asfail(__FILE__, __LINE__, "p"); else
#endif

#define		ESC		27
#if defined(BSD) || defined(MINIX) || defined(apollo)
#	define		CR		'\r'
#else
#	define		CR		10
#endif

/*
 * return codes for change_rcfile ()
 */

#define		NO_KILLING		0
#define		KILLING			1

/*
 *  art.thread
 */

#define		ART_NORMAL		-1
#define		ART_EXPIRED		-2

/*
 *  art.unread
 */

#define		ART_READ		0
#define		ART_UNREAD		1
#define		ART_WILL_RETURN	2

/*
 * used by group_t & my_group[]
 */
 
#define		UNSUBSCRIBED	0x01	/* haven't put in my_group[] yet */
#define		SUBSCRIBED		0x02	/* subscribed to */

/*
 * kill_type used in struct kill_t
 */
 
#define KILL_SUBJ	1
#define KILL_FROM	2
#define KILL_BOTH	3

/*
 * usedin group.c & page.c
 */
 
#define	ART_UNAVAILABLE	-1


/*
 * used in feed.c & save.c
 */
 
#define POST_PROC_NONE			0
#define POST_PROC_SHAR			1
#define POST_PROC_UUDECODE		2
#define POST_PROC_UUD_LST_ZOO	3
#define POST_PROC_UUD_EXT_ZOO	4

/*
 *  struct article_t - article header
 *
 *  article.artnum:
 *	article number in spool directory for group
 *
 *  article.thread:
 *	-1 initial default
 *	-2 means article has expired (wasn't found in file search
 *	of spool directory for the group)
 *	>=0 points to another arts[] (struct article_t)
 *
 *  article.inthread:
 *	FALSE for the first article in a thread, TRUE for all
 *	following articles in thread
 *
 *  article.unread:
 *	boolean, has this article been read or not
 *
 *  article.killed:
 *	boolean, has this article been killed
 *
 *  article.hot:
 *	boolean, has this article been auto-selected
 *
 *  article.tagged:
 *	count, has this article been tagged for saving (>0) or not (=0)
 *
 *  article.date
 *	date: line used for sorting articles by date order
 *
 *  article.archive:
 *	archive name used in *source* groups
 *
 *  article.part:
 *	part no. of archive
 *
 *  article.patch:
 *	patch no. of archive
 *
 */

struct article_t {
	long artnum;
	char *subject;		/* Subject: line from mail header */
	char *from;		/* From: line from mail header (address) */
	char *name;		/* From: line from mail header (full name) */
	int thread;
	unsigned int inthread:1;/* 0 = thread head, 1 = thread follower */
	unsigned int unread:2;	/* 0 = read, 1 = unread, 2 = will return */
	unsigned int killed:1;	/* 0 = not killed, 1 = killed */
	unsigned int hot:1;	/* 0 = not hot, 1 = hot */
	unsigned int zombie:1;	/* 1 = was alive (unread) before 'X' command */
	unsigned int o_unread:2;/* original value of unread - used in xref */
	int tagged;		/* 0 = not tagged, >0 = tagged */
	char date[16];		/* Date: line from mail header */
	char *archive;		/* Archive-name: line from mail header */
	char *part;		/* part no. of archive */
	char *patch;		/* patch no. of archive */
	char *xref;		/* cross reference line */
};

/*
 *  struct attribute_t - configurable attributes on a per group basis
 */

struct attribute_t {
	char *server;			/* read group locally/via nntp server */
	char *maildir;			/* mail dir if other than ~/Mail */
	char *savedir;			/* save dir if other than ~/News */
	char *sigfile;			/* sig file if other than ~/.Sig */
	unsigned int read:1;		/* marked TRUE if group was entered during session */
	unsigned int showall:1;		/* 0 = only unread, 1 = all */
	unsigned int thread:1;		/* 0 = unthread, 1 = thread */
	unsigned int sortby:4;		/* 0 = none, 1 = , 2 = , 3 = , 4 = , */
	unsigned int author:4;		/* 0 = none, 1 = name, 2 = addr, 3 = both */
	unsigned int autosave:1;	/* 0 = none, 1 = save */
	unsigned int process:4;		/* 0 = none, 1 = shar, 2 = uudecode, 
				  	   3 = uud & list zoo, 4 = uud & ext zoo*/
};

/*
 *  struct group_t - newsgroup info from active file
 */

struct group_t {
	char *name;
	char *description;		/* text from LIBDIR/newsgroups file */
	long max;
	long min;
	char moderated;
	int next;			/* next active entry in hash chain */
	int flag;
	struct attribute_t attribute;	/* per group attributes */ 
};

/*
 *  used in hashstr.c
 */
 
struct hashnode {
	char *s;						/* the string we're saving */
	struct hashnode *next;			/* chain for spillover */
};

/*
 *  used in kill.c
 */
 
struct kill_t {
	unsigned int kill_type:8;
	unsigned int kill_how:8;	/* kill/auto select */
	long kill_group;
	char *kill_subj;
	char *kill_from;
};

struct save_t {
	char *subject;
	char *dir;
	char *file;
	char *archive;
	char *part;
	char *patch;
	int index;	
	int saved;	
	int is_mailbox;	
};

struct screen_t {
	char *col;
};

struct posted_t {
	char date[10];
	char group[80];
	char action;
	char subj[120];
};

struct art_stat_t {
	int total;	/* total article count */
	int unread;	/* number of unread articles (does not include seen) arts */
	int seen;	/* number of seen articles (ART_WILL_RETURN) */
	int hot_total;	/* total hot count */
	int hot_unread; /* hot and unread */
	int hot_seen;	/* hot and seen */
	char art_mark;	/* mark to use for this thread - not used for groups */
};

struct spooldir_t {
	int state;
	char *name;
	char *comment;
};

/*
 *  function prototypes	& extern definitions	
 */ 

#include	"patchlev.h"
#include	"extern.h"
#include	"nntplib.h"
#include	"proto.h"
