#ifndef lint
static char *RCSid = "$Header: /users/empire/EMP/empmain/COMS/RCS/info.c,v 1.3 89/05/29 22:44:22 emp-src Exp $";
#endif

/*
 * info.c
 *
 * get documentation from INFO directory.
 *
 * Dave Pare, 1986
 */

#include "misc.h"
#include <stdio.h>
/* #include <strings.h> already included by misc.h - bailey@math-cs.kent.edu */
#include <sys/stat.h>
#ifdef hpux
#include <ndir.h>
#else
#include <sys/dir.h>
#endif

DIR	*info_dp;

static	int fileselect();
static	int printdir();

info()
{
	extern	char *argp[];
	extern	int errno;
	extern	char infodir[];
	extern	char *sys_errlist[];
	char	buf[255];
	FILE	*fp;
	char	*bp;
	struct	stat statb;
	struct	direct *dp;

	if (argp[1] == 0 || !*argp[1])
		return printdir();
	/*
	 * don't let sneaky people go outside the info directory
	 */
	if (bp = rindex(argp[1], '/'))
		bp++;
	else
		bp = argp[1];
	if (info_dp == 0) {
		info_dp = opendir(infodir);
		if (info_dp == 0) {
			pr(fmt("Can't open info dir \"%s\"\n", infodir));
			return RET_SYS;
		}
	}
	rewinddir(info_dp);
	fp = fopen(fmt("%s/%s", infodir, bp), "r");
	if (fp == NULL) {
		int	len = strlen(bp);
		/*
		 * may be a "partial" request.
		 */
		while  ((dp = readdir(info_dp)) != 0 && fp == 0) {
			if (strncmp(bp, dp->d_name, len) != 0)
				continue;
			fp = fopen(fmt("%s/%s", infodir, dp->d_name), "r");
		}
		if (fp == NULL) {
			pr(fmt("Sorry, there is no info on %s\n", bp));
			return RET_FAIL;
		}
	}
	if (fstat(fileno(fp), &statb) < 0) {
		pr(fmt("Cannot read info page for \"%s\" (%s)\n",
			dp->d_name, sys_errlist[errno]));
		return RET_SYS;
	}
	if ((statb.st_mode & S_IFREG) == 0) {
		pr(fmt("There is no available information on \"%s\"\n",
			dp->d_name));
		return RET_FAIL;
	}
	pr(fmt("Information on:  %s    Last modification date: %s",
		bp, ctime(&statb.st_mtime)));
	while (fgets(buf, sizeof(buf), fp) != 0)
		pr(buf);
	(void) fclose(fp);
	return RET_OK;
}

static int biggest;

static
int
fileselect(dp)
	struct direct *dp;
{
	if (*dp->d_name == '.')
		return 0;

#ifdef linux
	if (strlen(dp->d_name) > biggest)
		biggest = strlen(dp->d_name);
#else
	if (dp->d_namlen > biggest)
		biggest = dp->d_namlen;
#endif
	return 1;
}

static int
printdir()
{
	extern	int alphasort();
	extern	char infodir[];
	static	time_t lastmodtime;
	static	int number;
	static	struct direct **dp;
	struct	stat st;
	int	count;
	int	i;
	int	npl;

	if (stat(infodir, &st) == -1)
		return RET_FAIL;
	pr("Available topics are:\n");
	if (lastmodtime < st.st_mtime) {
		if (dp)
			free((char *)dp);
		biggest = 0;
		number = scandir(infodir, &dp, fileselect, alphasort);
		lastmodtime = st.st_mtime;
	}
	count = 79 / (biggest + 1) - 1;
	for(i = 0, npl = 0; i < number; i++) {
#ifdef linux
		pr(fmt("%-*.*s%c", biggest, strlen(dp[i]->d_name),
#else
		pr(fmt("%-*.*s%c", biggest, dp[i]->d_namlen,
#endif
		       dp[i]->d_name, npl == count ? '\n' : ' '));
		if (npl == count)
			npl = 0;
		else
			npl++;
	}
	if (npl != 0)
		pr("\n");
	return 0;
}
