/* sc_image.c
   gopher item subclass procedures for image */

     /*---------------------------------------------------------------*/
     /* Xgopher        version 1.3     08 April 1993                  */
     /*                version 1.2     20 November 1992               */
     /*                version 1.1     20 April 1992                  */
     /*                version 1.0     04 March 1992                  */
     /* X window system client for the University of Minnesota        */
     /*                                Internet Gopher System.        */
     /* Allan Tuchman, University of Illinois at Urbana-Champaign     */
     /*                Computing and Communications Services Office   */
     /* Copyright 1992, 1993 by                                       */
     /*           the Board of Trustees of the University of Illinois */
     /* Permission is granted to freely copy and redistribute this    */
     /* software with the copyright notice intact.                    */
     /*---------------------------------------------------------------*/

#include "conf.h"
#include "osdep.h"
#include "globals.h"
#include "gopher.h"
#include "appres.h"
#include "util.h"
#include "status.h"
#include "subst.h"
#include "jobs.h"
#include "sc_image.h"
#include "sc_imageP.h"

#include <sys/file.h>
extern	 errno;



/* getImage
   get an image file and display it.  Since image display may take a
   while, we just fork the process and let it occur asynchronously. */

BOOLEAN
getImage(gi)
gopherItemP	gi;
{
	char	errorString[MESSAGE_STRING_LEN];
	char	tempName[PATH_NAME_LEN];
	char	message[MESSAGE_STRING_LEN];
	int	tempFD;
	BOOLEAN	okSoFar;
	char	*imageCmd;	
	char	*path, *suffix=NULL;

	PID_TYPE	imagePID = (PID_TYPE) 0;


	if ((int) strlen ( appResources->imageCommand ) <= 0 ) {
		showError("Cannot execute the image command");
		return FALSE;
	}

	getTempFile(tempName);

	/* find the file name suffix which may indicate the image
	   file type -- if possible */

	path = vStringValue(&(gi->selector));
	suffix = rindex(path, '.');
	if (suffix != NULL) {

		/* find length of ".xxx".  If it's 4 or fewer characters
		   after the dot, assume that it's a meaningful suffix
		   and copy it to the end of the temp file name. */

		int	nch = strlen(suffix);

		if (nch <= 4) {
			strcat (tempName, suffix);
		}
	}

	if ((tempFD = open(tempName, O_WRONLY | O_CREAT, TMP_FILE_MODE)) < 0) {
		
		perror("getImage");
		(void) removeStatusPanel();

		sprintf(errorString,
			"Cannot open the temporary file %s", tempName);
		showError(errorString);
		fprintf (stderr, "%s\n", errorString);
		return FALSE;
	}

	okSoFar = GI_copyFromNet(tempFD, gi, "Getting image file");

	close(tempFD);

	if (! okSoFar) {
		unlink (tempName);
		return FALSE;
	}

	imageCmd = editCommand(gi, appResources->imageCommand,
				tempName, tempName);
	showStatus("Preparing image for display", STAT_TEMP_MESSAGE,
			(char *) NULL, 0);

	if ((imagePID = fork()) < 0) {
		sprintf(message,
		    "Unable to prepare for an image display (error %d)\n",
		    errno);
		showError(message);
		unlink (tempName);
		free(imageCmd);
		return FALSE;

	} else if (imagePID == 0) {

		/* we should immediately do a 
		      close (ConnectionNumber(XtDisplay(widget)));
		   here.  */

		   
		system(imageCmd);
		unlink (tempName);

		exit(0);
	}

	/* parent just returns as child does the display */

	addJob(gi->type, imagePID);
	free(imageCmd);

	return TRUE;
}


/* GIImage_init
   initialize image class - host access list and prefix. */

void
GIImage_init()
{
	GU_makePrefix(prefixImage,  appResources->prefixImage);
	imageHostList = GU_createAccessList(appResources->imageServers);
	GU_registerNewType(A_IMAGE, &imageSubclass);

	/* as a matter of security, in public mode, if there are no
	   restrictions, images should be banned.  It is easy to
	   overcome these restrictions by creating a list such as
	   ".edu .com .mil .gov .net" etc.  */

	if (appResources->publicMode  &&  imageHostList == NULL) {
		appResources->allowImage = False;
	}

	return;
}


/* GIImage_access
   check the accessability of an image file selection */

BOOLEAN
GIImage_access(gi)
gopherItemP	gi;
{
	BOOLEAN	result;

	if (appResources->allowImage  &&
	    (imageHostList == NULL  ||
				GU_checkAccess(gi->host, imageHostList))) {
		result = TRUE;
	}else {
		result = FALSE;
	}

	return result;
}


/* GIImage_restart
   kill all image command process if possible. */

void
GIImage_restart()
{
	killAllItemType(A_IMAGE);
}


/* GIImage_process
   process an image file selection */

BOOLEAN
GIImage_process(gi)
gopherItemP	gi;
{
	BOOLEAN	result;
	
	result = getImage(gi);

	return result;
}
