/*
 * Copyright 1987, 1988 by MIT Student Information Processing Board
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose is hereby granted, provided that
 * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
 * advertising or publicity pertaining to distribution of the software
 * without specific, written prior permission.  M.I.T. and the
 * M.I.T. S.I.P.B. make no representations about the suitability of
 * this software for any purpose.  It is provided "as is" without
 * express or implied warranty.
 */

#include "config.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#else
extern int errno;
#endif
#include <fcntl.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/file.h>
#ifdef NEED_SYS_FCNTL_H
/* just for O_* */
#include <sys/fcntl.h>
#endif
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#include "ss_internal.h"

void ss_help(int argc, char const * const *argv, int sci_idx, pointer info_ptr)
{
    char *buffer;
    char const *request_name;
    int code;
    int fd, child;
    register int idx;
    register ss_data *info;

    request_name = ss_current_request(sci_idx, &code);
    if (code != 0) {
	ss_perror(sci_idx, code, "");
	return;		/* no ss_abort_line, if invalid invocation */
    }
    if (argc == 1) {
	ss_list_requests(argc, argv, sci_idx, info_ptr);
	return;
    }
    else if (argc != 2) {
	/* should do something better than this */
	buffer = malloc(80+2*strlen(request_name));
	if (!buffer) {
		ss_perror(sci_idx, 0,
			  "couldn't allocate memory to print usage message");
		return;
	}
	sprintf(buffer, "usage:\n\t%s [topic|command]\nor\t%s\n",
		request_name, request_name);
	ss_perror(sci_idx, 0, buffer);
	free(buffer);
	return;
    }
    info = ss_info(sci_idx);
    if (info->info_dirs == (char **)NULL) {
	ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
	return;
    }
    if (info->info_dirs[0] == (char *)NULL) {
	ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
	return;
    }
    for (fd = -1, idx = 0; info->info_dirs[idx] != (char *)NULL; idx++) {
        buffer = malloc(strlen (info->info_dirs[idx]) + 1 +
			strlen (argv[1]) + 6);
	if (!buffer) {
	    ss_perror(sci_idx, 0,
		      "couldn't allocate memory for help filename");
	    return;
	}
	(void) strcpy(buffer, info->info_dirs[idx]);
	(void) strcat(buffer, "/");
	(void) strcat(buffer, argv[1]);
	(void) strcat(buffer, ".info");
	fd = open(buffer, O_RDONLY);
	free(buffer);
	if (fd >= 0)
	    break;
    }
    if (fd < 0) {
#define MSG "No info found for "
        char *buf = malloc(strlen (MSG) + strlen (argv[1]) + 1);
	strcpy(buf, MSG);
	strcat(buf, argv[1]);
	ss_perror(sci_idx, 0, buf);
	free(buf);
	return;
    }
    switch (child = fork()) {
    case -1:
	ss_perror(sci_idx, errno, "Can't fork for pager");
	(void) close(fd);
	return;
    case 0:
	(void) dup2(fd, 0); /* put file on stdin */
	ss_page_stdin();
    default:
	(void) close(fd); /* what can we do if it fails? */
	while (wait(NULL) != child) {
	    /* do nothing if wrong pid */
	};
    }
}

#ifndef HAVE_DIRENT_H
#include <sys/dir.h>
#else
#include <dirent.h>
#endif

void ss_add_info_dir(int sci_idx, char *info_dir, int *code_ptr)
{
    register ss_data *info;
    DIR *d;
    int n_dirs;
    register char **dirs;

    info = ss_info(sci_idx);
    if (info_dir == NULL || *info_dir == '\0') {
	*code_ptr = SS_ET_NO_INFO_DIR;
	return;
    }
    if ((d = opendir(info_dir)) == (DIR *)NULL) {
	*code_ptr = errno;
	return;
    }
    closedir(d);
    dirs = info->info_dirs;
    for (n_dirs = 0; dirs[n_dirs] != (char *)NULL; n_dirs++)
	;		/* get number of non-NULL dir entries */
    dirs = (char **)realloc((char *)dirs,
			    (unsigned)(n_dirs + 2)*sizeof(char *));
    if (dirs == (char **)NULL) {
	info->info_dirs = (char **)NULL;
	*code_ptr = errno;
	return;
    }
    info->info_dirs = dirs;
    dirs[n_dirs + 1] = (char *)NULL;
    dirs[n_dirs] = malloc((unsigned)strlen(info_dir)+1);
    strcpy(dirs[n_dirs], info_dir);
    *code_ptr = 0;
}

void ss_delete_info_dir(int sci_idx, char *info_dir, int *code_ptr)
{
    register char **i_d;
    register char **info_dirs;

    info_dirs = ss_info(sci_idx)->info_dirs;
    for (i_d = info_dirs; *i_d; i_d++) {
	if (!strcmp(*i_d, info_dir)) {
	    while (*i_d) {
		*i_d = *(i_d+1);
		i_d++;
	    }
	    *code_ptr = 0;
	    return;
	}
    }
    *code_ptr = SS_ET_NO_INFO_DIR;
}
