/*
 *
 *    Copyright (C) 1989 by the Massachusetts Institute of Technology
 *    Developed by the MIT Student Information Processing Board (SIPB).
 *    For copying information, see the file mit-copyright.h in this release.
 *
 */
/*
 *	Utility routines.
 */


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */

#include <stdio.h>
#include <sys/types.h>
#include <sys/file.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/errno.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif

#include <discuss/discuss.h>
#include <ss/ss.h>
#include "globals.h"

bool	use_editor = TRUE;
char 	*editor_path = NULL;

/*
 * int dsc_edit(fn, editor)
 *
 * fn: pathname of file to edit
 *
 * editor:
 * 	name of editor command to run; if NULL, use the default
 * (specified on the command line or $EDITOR); if "", use a simple
 * type-in prompter.
 * 
 * return value: error_code if error occurs, or child exits with nonzero
 *	status, 0 otherwise
 *
 * call up an editor (from environment variable EDITOR or default
 *	value DEFAULT_EDITOR) on the specified file.
 */

int
dsc_edit(fn, edit_path)
	char *fn;
	char *edit_path;
{
	char *editor_path_e, *editor_path_2 = NULL;
	char *editor_path_v;
	int len;
	int pid;
	void (*handler)();
#if HAVE_UNION_WAIT
	union wait wbuf;
#else
	int wbuf;
#endif
	struct stat buf;
	char buffer[BUFSIZ];
	FILE *the_file = NULL;

	editor_path_e = getenv("EDITOR");
	if (!editor_path_e) editor_path_e = "/bin/ed";
	editor_path_v = getenv("VISUAL");
	if (!editor_path_v) editor_path_v = "/usr/ucb/vi";

	if (use_editor && editor_path && !edit_path)
	    editor_path_2 = editor_path; 
	else if (edit_path && (*edit_path != '\0'))
	    editor_path_2 = edit_path;
	else {
		the_file = fopen(fn, "w");
		if (!the_file) { 
			perror(fn);
			printf("Error opening file: %d\n",errno);
			return(errno);
		}

		ftruncate(fileno(the_file), 0);
		fchmod(fileno(the_file), 0700);
		printf("Enter transaction; end with ^D or '.' on a line by itself.\n");
		for (;;) {
			if (fgets(buffer, sizeof(buffer), stdin) == NULL)
				break;
			len = strlen(buffer);
			if ((len > 0) && (buffer[len-1] == '\n'))
			    buffer[len-1] = 0;
			if (interrupt || (!strcmp(buffer, "."))) {
				break;
			} else if (!strcmp(buffer,"\\f")) {
				editor_path_2 = editor_path_e;
				break;
			} else if (!strcmp(buffer,"~e")) {
				editor_path_2 = editor_path_e;
				break;
			} else if (!strcmp(buffer,"~v")) {
				editor_path_2 = editor_path_v;
				break;
			} else {
				fputs(buffer,the_file);
				fputc('\n',the_file);
			}
		}
	}

	if (editor_path_2) {
		if (the_file) {
			clearerr(stdin);
			fclose(the_file);
		}
		switch ((pid = fork())) {
		case -1:
			perror("couldn't fork");
			printf("Couldn't fork, error %d\n",errno);
			return(errno);
		case 0:
			(void) execlp(editor_path_2, editor_path_2, fn, 0);
			(void) perror(editor_path_2);
			exit(1);
		default:
			break;
		}
		handler = signal(SIGINT, SIG_IGN);
		while (wait(&wbuf) != pid)
			;
		(void) signal(SIGINT, handler);
		if (WIFSIGNALED(wbuf))
			return(ET_CHILD_DIED);
#if HAVE_UNION_WAIT
		if (wbuf.w_retcode != 0)
#else
		if (WEXITSTATUS(wbuf))
#endif
			return(ET_CHILD_ERR);
	} else {
		clearerr(stdin);
		fclose(the_file);
	}

	if (stat (fn, &buf) != 0 || buf.st_size == 0) {
		unlink(fn);
	}
	return(0);
}
