/* main.c - main program for file viewer
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <pwd.h>
#include "getopt.h"
#include "ldb.h"
#include "mstring.h"
#include "viewfile.h"


char *current_user;

void display_version(void);
void display_help(void);
int mview(char *, char *, long, char *, unsigned long);
int mview_menu(char *, char *);
int mview_listed(char *, char *);
int ldb_purge(char *, char *);
void sh_int(int);
void sh_quit(int);


/* Process command-line arguments, set option flags, and call mview() for
 * each file named. Directories cannot be viewed.
 */
int main(int argc, char *argv[])
{
	struct option long_options[] = {
		{"line", 1, 0, 'l'},	    /* display options */
		{"menu", 0, 0, 'm'},
		{"listed", 0, 0, 'L'},
		{"bottom", 0, 0, 'z'},
		{"top", 0, 0, 'T'},
		{"no-colour", 0, 0, 'c'},
		{"no-colours", 0, 0, 'c'},
		{"monochrome", 0, 0, 'c'},
		{"ldb", 1, 0, 'd'},	    /* LDB options */
		{"no-ldb", 0, 0, 'n'},
		{"purge-ldb", 0, 0, 'p'},
		{"purge", 0, 0, 'p'},
		{"file", 1, 0, 'f'},
		{"anonymous", 0, 0, 'y'},   /* restrictions */
		{"anon", 0, 0, 'y'},
		{"readonly", 0, 0, 'r'},
		{"no-edit", 0, 0, 'e'},
		{"help", 0, 0, '!'},	    /* informational options */
		{"version", 0, 0, 'V'},
		{0, 0, 0, 0}
	};
	char *short_options = "l:mLzTcd:npf:yreV";
	int option_index = 0;
	char read_something = 0;
	char purge = 0;
	char menu = 0;
	char listed = 0;
	struct stat sb;
	struct passwd *z;
	char *pn;
	int c, r;
	long line = -1;
	char *file = 0;
	char *ldbfile = 0;
	char *fakeas = 0;
	unsigned long flags = MENU_STATUS_ADD | MENU_STATUS_EDIT |
	    MENU_STATUS_DELETE;

	pn = strrchr(argv[0], '/');
	if (pn)
		pn++;
	else
		pn = argv[0];

	current_user = getenv("MVIEW_USER");
	if (!current_user)
		current_user = getenv("MCONV_USER");
	if (!current_user) {
		z = getpwuid(getuid());
		current_user = (z) ? strdup(z->pw_name) : "unknown";
	}

	ldb_init();
	ldbfile = getenv("MVIEW_LDB");

	do {				    /* read options */
		c = getopt_long(argc, argv, short_options, long_options,
				&option_index);
		if (c < 0)
			continue;
		switch (c) {
		case 'l':
			line = atol(optarg);
			break;
		case 'm':
			menu = 1;
			listed = 0;
			break;
		case 'L':
			listed = 1;
			menu = 0;
			break;
		case 'z':
			line = 999999;
			break;
		case 'T':
			line = 0;
			break;
		case 'c':
			mstrtoansi_colours(0);
			break;
		case 'd':
			ldbfile = optarg;
			break;
		case 'n':
			ldbfile = 0;
			break;
		case 'f':
			fakeas = optarg;
			break;
		case 'p':
			purge = 1;
			break;
		case 'y':
			flags |= MENU_STATUS_ANONYMOUS;
			break;
		case 'r':
			flags |= MENU_STATUS_READONLY;
			break;
		case 'e':
			flags -= (flags & MENU_STATUS_EDIT);
			break;
		case 'V':
			display_version();
			return (0);
			break;
		case '!':
			display_help();
			return (0);
			break;
		default:
			fprintf(stderr,
				"Try `%s --help' for more information.\n\r",
				pn);
			return (1);
			break;
		}
	} while (c != -1);

	if (purge) {			    /* purge LDB instead of viewing files */
		return (ldb_purge(ldbfile, pn));
	}

	c = 0;				    /* exit status */

	signal(SIGINT, sh_int);		    /* ignore ^C */
	signal(SIGQUIT, sh_quit);	    /* ignore ^\ */
	signal(SIGALRM, SIG_IGN);	    /* ignore SIGALRM */

	while (optind < argc) {		    /* view each file in turn */

		file = argv[optind];

		if (file[0] == '+') {	    /* not a filename - set line number */
			file++;
			line = atol(file);
			optind++;
			continue;
		}

		if (stat(file, &sb)) {	    /* failed to stat file */
			fprintf(stderr, "%s: %s: skipping (%s)\n\r", pn,
				file, strerror(errno));
			c = 1;
			optind++;
			continue;
		}

		if ((sb.st_mode & S_IFDIR) && (!listed)) {	/* can't view directories */
			fprintf(stderr,
				"%s: %s: is a directory - skipping\n\r",
				pn, file);
			c = 1;
			optind++;
			continue;
		}

		if (menu)
			r = mview_menu(file, ldbfile);
		else if (listed)
			r = mview_listed(file, ldbfile);
		else
			r = mview(file, ldbfile, line, fakeas, flags);
		c |= r;
		if (r) {
			fprintf(stderr, "%s: %s: file error\n\r", pn,
				file);
		}

		read_something = 1;
		optind++;
	}

	if (!read_something) {		    /* no valid files specified */
		fprintf(stderr, "%s: no valid files specified\n\r", pn);
		c = 1;
	}

	return (c);
}

/* EOF */
