#ifndef lint
static char *RCSid = "$Header: /usr/brule/guest/empire/empire/emprcs/lib/commands/info.c,v 2.6 1995/10/22 21:19:29 empire Exp $";
#endif

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

#include "misc.h"
#include "player.h"
#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>

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

info()
{
	extern	int errno;
	extern	s_char *infodir;
#if (!defined linux) && (!defined FBSD)
	extern	s_char *sys_errlist[];
#endif
	s_char	buf[255];
	FILE	*fp;
	s_char	*bp;
	struct	stat statb;
	struct	dirent *dp;
	s_char	filename[1024];
	DIR	*info_dp;

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

static int biggest;

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

      if ((l = strlen (dp->d_name)) > biggest)
              biggest = l;
	return 1;
}

static int
printdir()
{
	extern	int alphasort();
	extern	s_char *infodir;
	static	time_t lastmodtime;
	static	int number;
	static	struct dirent **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((s_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++) {
		pr("%-*.*s%c", biggest, strlen (dp[i]->d_name),
		       dp[i]->d_name, npl == count ? '\n' : ' ');
		if (npl == count)
			npl = 0;
		else
			npl++;
	}
	if (npl != 0)
		pr("\n");
	return 0;
}
