#define BOOLEAN int
#define TRUE 1
#define FALSE 0

#define NORMAL 0
#define MATH 1
#define MANUAL 2

#define LEFT 0
#define CENTRAL 1
#define RIGHT 2

#include <sys/param.h>
#include <signal.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <pwd.h>
#include "ps_filter.h"
#include "filter.h"
#include "images.h"

void xxperror(char *s, int line)
{
  perror(s); fprintf(stderr, "Line %d - \"%s\"\n", line, strerror);
}

#define xperror(s) xxperror(s, __LINE__)

/* Definition of Options Template file */

static char *OptionFile[] = {
  "#\n",
  "# .ps2htmlrc - Options file for ps2html\n",
  "#\n",
  "# Created automatically by ps2html 1.0\n",
  "#\n",
  "\n",
  "#\n",
  "# For yes/no settings, ON means yes, OFF means no.\n",
  "#\n",
  "# Lines beginning with \"#\" (like this one!) are comments.\n",
  "#\n",
  "# Note: Never erase the right part of the following assignments\n",
  "# or their format will be distrurbed.\n",
  "\n",
  "# Give a title to produced document\n",
  "Title = Untitled\n",
  "\n",
  "# Make ps2html create images on output\n",
  "Images = ON\n",
  "\n",
  "# Choose format for images (gif/jpeg)\n",
  "IFormat = gif\n",
  "\n",
  "# Attempt to extract images from PostScript document\n",
  "# in their original format\n",
  "PsImages = OFF\n",
  "\n",
  "# There seem to be some problems concerning racing conditions\n",
  "# when images are being created.\n",
  "# (PPM file production and consumption are not syncronized)\n",
  "# The greater value, the more stable image creation.\n",
  "Sleep = 5\n",
  "\n",
  "# Define line alignment (left/center/right)\n",
  "Align = center\n",
  "\n",
  "# Define absolute difference between a line's beginning \n",
  "# and ending in order to identify it as centered or not\n",
  "Difference = 7\n",
  "\n",
  "# Define minimum distance between two lines in order\n",
  "# not to consider them as adjacent\n",
  "MinDistance = 15\n",
  "\n",
  "# Tell ps2html to ignore line breaks\n",
  "# (which means do not translate every \\n as <BR>)\n",
  "LnBreaks = ON\n",
  "\n",
  "# How should ps2html handle user defined fonts ?\n",
  "# (Possible values: normal/math/manual)\n", 
  "Encoding = normal\n",
  "\n",
  "# In case of manual encoding provide ps2html\n",
  "# with a filename containing its Encoding Vector\n",
  "EncFile = null\n",
  0
};

/* Declaration of global variables */

/* Variables used in this file */
static char *cmd; 	/* = argv[0] */
char *PSName,		/* Name of .ps file */
     *HTMLName,		/* Name of .html file (output) */
     Base[20],		/* Name of input file without suffix */
     **web_argv;	/* Table of arguments for webify */

char FullHTMLName[100],	/* Full name of output file */
     FullIndexName[100],/* Full name of "index.html" */
     FullUpperName[100],/* Full name of "left.html" */
     FullErrorName[100];/* Full name of "error.html" */

FILE *out,		/* Pointer to output file */
     *left,		/* Pointer to file left.html */
     *Index,		/* Pointer to file index.html */
     *ErrorTbl;		/* Pointer to file error.html */

int FS=5;		/* Font Size scale factor */
int web_argc;		/* Number of command line arguments */
int MyDebug;		/* Personal temporary variable */
char Creator[50];	/* Creator of PS document */
int BBox_Left=0, BBox_Bot=0,	/* Document's Bounding Box */
    BBox_Right=596, BBox_Top=842; /* (Default is the A4) */

static enum {
  portrait,
  landscapeOther,
  unused,
  landscape} orientation = portrait;

static enum {
  gif,
  jpeg} IFormat = gif;

BOOLEAN Images=TRUE;
BOOLEAN PsImages=FALSE;
BOOLEAN LnBreaks=TRUE;
int EnCoding=NORMAL;
char EncFile[100];
char *ManualDvipsGlyphs[256];
int SleepTime;
int Align;
int Diff;
int MinDist;
int PagesPlus=0;

/* Common varables */
extern char BaseName[100],	/* Base name of file */
     Title[100],		/* Title of HTML document */
     FullPSName[200],		/* Full PostScript name (with .ps) */
     SubDir[100];		/* Name of output directory */

extern int Debug,	/* Debugging option */
           PageNum;	/* Number of pages */

typedef char *BUNDLE[];
extern BUNDLE ps_filter;

/* Declaration of external procedures used in this file */
extern int Filter(FILE *);

/* Declaration of procedures used in this file */
Usage() {
  fprintf(stderr, "\nUsage: %s [options] file.ps [file.html]\n", cmd);
  fprintf(stderr, "Options:\n");
  fprintf(stderr, "  -D <path>        Directory where results should be stored\n");
  fprintf(stderr, "                   (Default: ~/public_html/Results/\n");
  fprintf(stderr, "  -o <filename>    Read options from file <filename>.\n");
  fprintf(stderr, "                   Use this first so that ps2html will\n");
  fprintf(stderr, "                   not override any command line options.\n");
  fprintf(stderr, "  -e <filename>    Use <filename> to decode ligatures\n");
  fprintf(stderr, "                   produced by Type 3 fonts.\n");
  fprintf(stderr, "  -math            Use TeXMathEncoding in order to\n");
  fprintf(stderr, "                   translate math expressions.\n");
  fprintf(stderr, "  -noimages        Do not create images\n");
  fprintf(stderr, "  -gif             Set image format to gif (default)\n");
  fprintf(stderr, "  -jpeg            Set image format to jpeg\n");
  fprintf(stderr, "  -psimages        Extract images in PostScript format\n");
  fprintf(stderr, "  -t <title>       Title of document (one word)\n");
  fprintf(stderr, "  -P <n>           Add <n> to Page Index\n");
  fprintf(stderr, "                   so that soft links work properly\n");
  fprintf(stderr, "  -f <n>           Where n is a number between 0 to 9\n");
  fprintf(stderr, "                   defining the Font Size scale factor\n");
  fprintf(stderr, "                   (0 means no scaling. Default: 5)\n");
  fprintf(stderr, "  -d(ebug)         Debugging option\n");
  fprintf(stderr, "  -check           Check environment (gs,hackppm,ppmtogif)\n");
  fprintf(stderr, "  -h(elp)          Display this message\n");
  fprintf(stderr, "\nThese options can be set directly from command line.\n");
  fprintf(stderr, "More options can be specified by modifing your .ps2htmlrc\n");
  fprintf(stderr, "located in your home directory, or uploading an option\n");
  fprintf(stderr, "file using the -o option.\n");
  fprintf(stderr, "Don't forget to check your results error file (error.html).\n");
}

void putbundle(BUNDLE b, FILE *f)
{
	char **ppLine = b;

	for (ppLine = b;
	     *ppLine != NULL;
	     ppLine++)
		fputs(*ppLine, f);
}

static char *make_temp(b) BUNDLE b; {
  /* Return pathname of temporary file containing bundle "b".  Caller
     should unlink file (and, technically, free pathname). */
  FILE *f;
  char *path = tempnam("/tmp", ",ps2h");
  f = fopen(path, "w");
  if (f==NULL) {xperror("fopen"); exit(1);}
  putbundle(b, f);
  fclose(f);
  return path;
}

static char *ocr_path = NULL, *rotate_path = NULL;
static FILE *gs = NULL;

static int cleanup() {
  int gsstatus, status = 0;
  if (gs!=NULL) {
    gsstatus = pclose(gs);
    if (WIFEXITED(gsstatus)) {
      if (WEXITSTATUS(gsstatus)!=0) status = 3;
      else if (WIFSIGNALED(gsstatus)) status = 4;
    }
  }
  if (rotate_path!=NULL & strcmp(rotate_path, "")!=0) unlink(rotate_path);
  if (ocr_path!=NULL) unlink(ocr_path);
  return status;
}

void index_init()
{
	fprintf(Index, "<HTML>\n");
	fprintf(Index, "<HEAD>\n");
	fprintf(Index, "<TITLE> %s </TITLE>\n", Title);
	fprintf(Index, "</HEAD>\n\n");
	fprintf(Index, "<FRAMESET cols=\"150,*\">\n");
	fprintf(Index, "<FRAME SRC=\"left.html\" name=\"LEFT\" SCROLLING=NO>\n");
	fprintf(Index, "<FRAME SRC=\"%s\" name=\"RIGHT\">\n", HTMLName);
	fprintf(Index, "</FRAMESET>\n");
	fprintf(Index, "</HTML>\n");
	fclose(Index);
}

void left_init()
{
	fprintf(left, "<HTML>\n");
        fprintf(left, "<HEAD>\n");
}

void error_init()
{
	fprintf(ErrorTbl, "<HTML>\n");
	fprintf(ErrorTbl, "<HEAD>\n");
	fprintf(ErrorTbl, "</HEAD>\n");
	fprintf(ErrorTbl, "<BODY BGCOLOR=\"White\">\n");
	fprintf(ErrorTbl, "<CENTER>\n");
	fprintf(ErrorTbl, "<H3> The following table contains objects\n");
	fprintf(ErrorTbl, "whose interpretation might be wrong.\n");
	fprintf(ErrorTbl, "Follow the assosiated links to check it out.</H3>\n");
	fprintf(ErrorTbl, "<TABLE BORDER=1>\n");
	fprintf(ErrorTbl, "<TR><TD ALIGN=MIDDLE><FONT SIZE=5>Type of object</FONT></TD>\n");
	fprintf(ErrorTbl, "<TD ALIGN=MIDDLE><FONT SIZE=5>Link to object</FONT></TD>\n");
	fprintf(ErrorTbl, "<TD ALIGN=MIDDLE><FONT SIZE=5>Possibility of error</FONT></TD></TR>\n");
}

void left_final()
{
	int i;

	fprintf(left, "\t<SCRIPT language=\"JavaScript\">\n");
	fprintf(left, "\t\tvar LastP = %d;\n", PageNum);
	fprintf(left, "\t\tvar FirstP = 1;\n");
	fprintf(left, "\t\tvar CurP = FirstP;\n\n");

	fprintf(left, "\t\tfunction NextPage() {\n");
	fprintf(left, "\t\t\tif (CurP < LastP) {\n");
	fprintf(left, "\t\t\t\t++CurP;\n");
	fprintf(left, "\t\t\t\tparent.RIGHT.location.href =\n");
	fprintf(left, "\t\t\t\t\t\"%s#PAGE\"+CurP;\n\t\t\t}\n", HTMLName);
	fprintf(left, "\t\t\telse {\n");
	fprintf(left, "\t\t\t\talert(\"Last page reached!!!\");\n");
	fprintf(left, "\t\t\t}\n\t\t}\n\n");

	fprintf(left, "\t\tfunction PrevPage() {\n");
	fprintf(left, "\t\t\tif (CurP > FirstP) {\n");
	fprintf(left, "\t\t\t\t--CurP;\n");
	fprintf(left, "\t\t\t\tparent.RIGHT.location.href =\n");
	fprintf(left, "\t\t\t\t\t\"%s#PAGE\"+CurP;\n\t\t\t}\n", HTMLName);
	fprintf(left, "\t\t\telse {\n");
	fprintf(left, "\t\t\t\talert(\"First page reached!!!\");\n");
	fprintf(left, "\t\t\t}\n\t\t}\n\n");

	fprintf(left, "\t\tfunction FirstPage() {\n");
	fprintf(left, "\t\t\tCurP = 1;\n");
	fprintf(left, "\t\t\tparent.RIGHT.location.href =\n");
	fprintf(left, "\t\t\t\t\"%s#PAGE\"+CurP;\n\t\t}\n\n", HTMLName);

	fprintf(left, "\t\tfunction LastPage() {\n");
	fprintf(left, "\t\t\tCurP = LastP;\n");
	fprintf(left, "\t\t\tparent.RIGHT.location.href =\n");
	fprintf(left, "\t\t\t\t\"%s#PAGE\"+CurP;\n\t\t}\n\n", HTMLName);

	fprintf(left, "\t</SCRIPT>\n");
	fprintf(left, "</HEAD>\n\n");

	fprintf(left, "<BODY BGCOLOR=\"White\">\n");
	fprintf(left,  "<FONT SIZE=0>\n");
	fprintf(left, "<B>Document:</B><BR>\n%s\n<HR>\n", Title);
	fprintf(left, "<B>Number of Pages:</B> %d\n<HR>\n", PageNum);
	fprintf(left, "<A HREF=\"error.html\" TARGET=\"RIGHT\">Error file</A>\n");
	fprintf(left, "<HR>\n<B>Indices to pages:</B>\n");
	fprintf(left, "    <FORM NAME=\"buttonbar\">\n");
	fprintf(left, "\t<INPUT TYPE=\"button\" name=\"first\" VALUE=\"First\" onClick=\"FirstPage()\">\n");
	fprintf(left, "\t<INPUT TYPE=\"button\" name=\"last\" VALUE=\"Last\" onClick=\"LastPage()\">\n");
	fprintf(left, "\t<INPUT TYPE=\"button\" name=\"prev\" VALUE=\"Prev\" onClick=\"PrevPage()\">\n");
	fprintf(left, "\t<INPUT TYPE=\"button\" name=\"next\" VALUE=\"Next\" onClick=\"NextPage()\">\n");
	fprintf(left, "    </FORM>\n");
	for (i=1; i<=PageNum; i++)
		fprintf(left, "<A HREF=\"%s#PAGE%d\" TARGET=\"RIGHT\">%d</A>\n", HTMLName, i, i);
	fprintf(left, "</FONT>\n</BODY>\n</HTML>\n");
}

void error_final()
{
	fprintf(ErrorTbl, "</TABLE>\n");
	fprintf(ErrorTbl, "</CENTER>\n");
	fprintf(ErrorTbl, "</BODY>\n");
	fprintf(ErrorTbl, "</HTML>\n");
}

int endoffile() {
  int status = cleanup();
  if (status!=0)
    exit(status);
  exit(1);
}

static void handler() {
  int status = cleanup();
  if (status!=0)
    exit(status);
  exit(2);
}

static do_it(char *path)
{
  char gs_cmd[2*MAXPATHLEN];
  char input[MAXPATHLEN];
  int status;
  char c;

  signal(SIGINT, handler);
  signal(SIGHUP, handler);

  ocr_path = make_temp(ps_filter);

  switch (orientation) {
  case portrait: rotate_path = ""; break;
  }

  if (path==NULL) strcpy(input, "-");
  else {strcpy(input, "-- "); strcat(input, path);}

  fprintf(stderr, "Initializing output files ... ");
  /* Open files for writing */
  out = fopen(FullHTMLName, "w");
  if (out == NULL) { xperror(FullHTMLName); exit(1); }
  Index = fopen(FullIndexName, "w");
  if (Index == NULL) { xperror("fopen"); exit(1); }
  left = fopen(FullUpperName, "w");
  if (left == NULL) { xperror("fopen"); exit(1); }
  ErrorTbl = fopen(FullErrorName, "w");
  if (ErrorTbl == NULL) { xperror("fopen"); exit(1); }

  /* Initializing output interface */
  index_init();
  left_init();
  error_init();

  /* Initializing output file */
  fprintf(out, "<HEAD>\n");
  fprintf(out, "<TITLE> %s </TITLE>\n", Title);
  fprintf(out, "</HEAD>\n\n");
  fprintf(out, "<BODY BGCOLOR=\"White\">\n");
  fprintf(out, "<A NAME=\"PAGE1\"></A>\n");

  fprintf(stderr, "done.\nRunning GS including PostScript library ... ");
  /* Do a first pass in order to extract the text from the .ps file */
  sprintf(gs_cmd, "gs -r72 -sDEVICE=x11 -sOutputFile=/dev/null -dNODISPLAY -dNOBIND -dWRITESYSTEMDICT -q -dNOPAUSE %s %s %s > /tmp/output.tmp",
    ocr_path,
    rotate_path,
    input
    );

  system(gs_cmd);
  gs = fopen("/tmp/output.tmp", "r");
  if (gs == NULL) {xperror("fopen"); exit(1);}

  fprintf(stderr, "done.\nParsing temporary file ... ");
  PageNum = Filter(gs);
  fprintf(stderr, "done.\nClosing open files ... ");

  /* Last lines of output */
  fprintf(out, "</BODY>\n");

  /* Finalize output interface */
  left_final();
  error_final();
  close_files();
  fprintf(stderr, "done.\n");

  /* If ImageHead is NULL it means no Images have been found */
  /* Our job is done !!! */
  /* Otherwise do a second pass in order to extract images */
  /* and other elements from the input file */
  if (Images)
  {
    fprintf(stderr, "Checking for images ... ");
    if (ImageHead != (struct ImageNode *)NULL)
    {
      fprintf(stderr, "done. (yes)\nCreating images ...\n");
      webify(web_argc, web_argv);
      fprintf(stderr, "Creating images ... done.\n");
    }
    else fprintf(stderr, "done. (no)\n");
  }

  /* Do some leftovers ... */
  status = cleanup();
  if (status!=0) exit(status);
}

char *UserHome()
{
	char *user_home;
	DIR *p_DIR;
	uid_t user_id;
	struct passwd *user_passwd;

	user_home = (char *)malloc(MAXPATHLEN*sizeof(char));
	if (user_home == (char *)NULL)
	{ xperror("malloc"); exit(1); }
	user_id = (uid_t)geteuid();
	user_passwd = (struct passwd *)getpwuid(user_id);
	strcpy(user_home, user_passwd->pw_dir);
	return user_home;
}

#define NXTARG (*++arg? arg : argv[++argn])

main(int argc, char *argv[])
{
	FILE *option;
	int argn;
	char *arg;
	char *user_home;

	fprintf(stderr, "This is ps2html 1.0 Copyright 1998, J.K.NIKOP\n");
	cmd = argv[0];
	web_argv = argv;
	web_argc = argc;

	/* Specify user's home directory */
	user_home = UserHome();

	/* Check whether options file exists */
	/* If not, create it */
	CheckOptions(user_home);

	/* Parse options file */
	ParseOptions(user_home);

	/* Parse command line arguments */
	for (argn=1; argn<argc; argn++)
	{
	    if (*(arg=argv[argn]) == '-')
	    {
		if (!strcmp(arg, "-gif"))
		{
		    IFormat = gif;
		    continue;
		}
		if (!strcmp(arg, "-jpeg"))
		{
		    IFormat = jpeg;
		    continue;
		}
		if (!strcmp(arg, "-noimages"))
		{
			Images = FALSE;
			continue;
		}
		if (!strcmp(arg, "-psimages"))
		{
			PsImages = TRUE;
			continue;
		}
		if (!strcmp(arg, "-math"))
		{
			EnCoding = MATH;
			continue;
		}
		if (!strcmp(arg, "-check"))
		{
			CheckEnv();
			exit(0);
		}
		if (!strcmp(arg, "-debug"))
		{
			Debug = TRUE;
			continue;
		}
		if (!strcmp(arg, "-help"))
		{
			Usage();
			exit(0);
		}
  		switch(*++arg)
  		{
		    case 'o': ParseOptions(NXTARG); continue;
		    case 'e': EnCoding = MANUAL;
		    	      FillManualVector(NXTARG);
			      continue;
		    case 'd': Debug=TRUE; continue;
		    case 'h': Usage(); exit(0);
		    case 'f': FS = atoi(NXTARG); continue;
		    case 't': strcpy(Title, NXTARG); continue;
		    case 'r': orientation = atoi(NXTARG); continue;
		    case 'P': PagesPlus = atoi(NXTARG); continue;
		    case 'D': strcpy(SubDir, NXTARG); continue;
		    default: Usage(); exit(1);
		}
	    }
	    else	/* No '-' found in command line */
	    {		/* We suppose next argument is the input file */
		if (!PSName)
		{
		    FILE *fp;
		    PSName = (char *)malloc(strlen(arg)*sizeof(char));
		    if (PSName == (char *)NULL)
		    { xperror("malloc"); exit(1); }
		    strcpy(PSName, arg);
		    if ((fp = fopen(PSName, "r")) == (FILE *)NULL)
		    {
			fprintf(stderr, "ps2html: Can't open input file. Exiting !!!\n");
			fclose(fp);
			exit(1);
		    }
		    ComputeBase(arg);
		    ParsePSName(arg);
		}
		else	/* If PSName is set then this arg must be .html */
		{
		    HTMLName = (char *)malloc((strlen(arg)+2)*sizeof(char));
		    if (HTMLName == (char *)NULL)
		    { xperror("malloc"); exit(1); }
		    strcpy(HTMLName, arg);
		    web_argc--;
		}
	    }
	} 
	if (!PSName) /* No input file */
	{
		Usage();
		exit(1);
	}
	if (!HTMLName) 	/* Output file name was not given. */
	{		/* We compute it now */
		HTMLName = (char *)malloc((strlen(arg)+2)*sizeof(char));
		if (HTMLName == (char *)NULL)
		{ xperror("malloc"); exit(1); }
		ComputeHTMLName();
	}
	if (!strlen(Title))	/* No title ??? Here is one ... */
		strcpy(Title, Base);

	/* Parse input file for valuable info */
	/* ie: Bounding Box */
	if (parse_input(FullPSName))
		exit(1);

	if (MyDebug) print_variables();

	/* Begin parsing */
	do_it(FullPSName);

	fprintf(stderr, "\nOutput is directed to:\n");
	fprintf(stderr, "%s\n", SubDir);
	exit(0);
}

int parse_input(char *filename)
{
	FILE *pin;
	char ch;
	int count=1;
	int i=0;
	int trash, page;
	char *str = (char*)malloc(50*sizeof(char));
	if (str == (char *)NULL)
	{ xperror("malloc"); exit(1); }

	pin = fopen(filename, "r");
	if (pin == (FILE *)NULL)
	{
		fclose(pin);
		return 1;
	}
	else while (fscanf(pin, "%s", str) != EOF)
	    {
		if (!strcmp(str, "%%Page:"))
		{
			fscanf(pin, "%d %d", &trash, &page);
			count = 1;
		}
		if (strstr(str, "Creator"))
		{
			while ((ch = fgetc(pin)) != '\n')
				Creator[i++] = ch;
		}
		if (strstr(str, "BoundingBox:"))
		{
			fscanf(pin, "%d", &BBox_Left);
			fscanf(pin, "%d", &BBox_Bot);
			fscanf(pin, "%d", &BBox_Right);
			fscanf(pin, "%d", &BBox_Top);
		}
		if (PsImages)
		{
		    if (strstr(str, "BeginDocument"))
		    {
			FILE *pout;
			char *filename=(char *)malloc(MAXPATHLEN*sizeof(char));
			if (filename == (char *)NULL)
			{ xperror("malloc"); exit(1); }
			sprintf(filename, "%sP%d_%d.eps", SubDir, page, count);
			pout = fopen(filename, "w");
			if (pout == (FILE *)NULL)
				xperror("fopen");
			else
			{
			    char ch;
			    fprintf(pout, "%s ", str);
			    while (1)
			    {
				if (ch == '%')
				    if ((ch = fgetc(pin)) == '%')
					{
						fprintf(pout, "%%%%EndDocument\n");
						break;
					}
					else fputc('%', pout);
				fputc(ch, pout);
				ch = fgetc(pin);
			    }
			    count++;
			}
			fclose(pout);
		    }
		    else {;}
		}
		else
		{
			fclose(pin);
			return 0;
		}
	    }
	fclose(pin);
	return 0;
}
		
ComputeBase(char *name)
{
	char *p,*q;

	q = strrchr(name, '/');
	if (q == (char *)NULL)
		strcpy(Base, name);
	else
	{
		q++;
		strcpy(Base, q);
	}
	p = strrchr(Base, '.');
	*p = '\0';
}

ComputeHTMLName()
{
	strcpy(HTMLName, Base);
	strcat(HTMLName, ".html");
}

ParsePSName(char *name)
 { char *lastdot=0,*q;
   char *user_home, *cwd;
   DIR *p_DIR;
   uid_t user_id;
   struct passwd *user_passwd;

   cwd = (char *)malloc(MAXPATHLEN*sizeof(char));
   if (cwd == (char *)NULL)
   { xperror("malloc"); exit(1); }
   cwd = (char *)getcwd((char *)NULL, MAXPATHLEN);
   strcat(cwd, "/");
   strcat(cwd, name);
   strcpy(FullPSName, cwd);

   /* Find the "~/public_html" directory */
   /* in order to direct output there */
   user_home = (char *)malloc(MAXPATHLEN*sizeof(char));
   if (user_home == (char *)NULL)
   { xperror("malloc"); exit(1); }
   user_id = (uid_t)geteuid();
   user_passwd = (struct passwd *)getpwuid(user_id);
   strcpy(user_home, user_passwd->pw_dir);

   /* Check whether directories "~/public_html" */
   /* and "~/public_html/Results" exist or not */
	strcat(user_home, "/public_html/");
   	p_DIR = opendir(user_home);
	if (p_DIR == (DIR *)NULL)
	{
		mkdir(user_home, 0775);
		strcat(user_home, "Results/");
		mkdir(user_home, 0775);
	}
	else
	{
		closedir(p_DIR);
		strcat(user_home, "Results/");
		p_DIR = opendir(user_home);
		if (p_DIR == (DIR *)NULL)
			mkdir(user_home, 0775);
	}

   if ((q = strrchr(name, '/')) != (char *)NULL)
	q++;
   else q=name;
   strcat(user_home, q);
   if (SubDir[0] == '\0')
   	strcpy(SubDir, user_home);
   else
   {
	   strcat(SubDir, "/");
	   strcat(SubDir, q);
   }

   lastdot = strrchr(SubDir, '.');
   if (lastdot)
   {
	*lastdot = '/';
        lastdot++;
	*lastdot = '\0';
   }

   strcpy(FullHTMLName, SubDir);
   strcat(FullHTMLName, Base);
   strcat(FullHTMLName, ".html");
   strcpy(FullIndexName, SubDir); 
   strcat(FullIndexName, "index.html");
   strcpy(FullUpperName, SubDir);
   strcat(FullUpperName, "left.html");
   strcpy(FullErrorName, SubDir);
   strcat(FullErrorName, "error.html");
   strcpy(BaseName, SubDir);

   /* Create a directory to store results */
   mkdir(SubDir, 0775);

   free(cwd);
   free(user_home);
}

close_files()
{
	fclose(out);
	/* fclose(Index); /*
	fclose(left);
	fclose(ErrorTbl);
	/* unlink("/tmp/minmax.tmp"); */
	/* unlink("/tmp/output.tmp"); */
	/* free(out); */
	/* free(Index); */
	/* free(left); */
}

print_variables()
{
	fprintf(stderr, "PSName: %s\n", PSName);
	fprintf(stderr, "FullPSName: %s\n", FullPSName);
	fprintf(stderr, "Base: %s\n", Base);
	fprintf(stderr, "BaseName: %s\n", BaseName);
	fprintf(stderr, "SubDir: %s\n", SubDir);
	fprintf(stderr, "HTMLName: %s\n", HTMLName);
	fprintf(stderr, "FullHTMLName: %s\n", FullHTMLName);
	fprintf(stderr, "FullIndexName: %s\n", FullIndexName);
	fprintf(stderr, "FullUpperName: %s\n", FullUpperName);
	fprintf(stderr, "BoundingBox: %d %d %d %d\n", BBox_Left, BBox_Bot, BBox_Right, BBox_Top);
}

/****************************************************************************
 * Check for Options file. Read options from there...                       *
 ****************************************************************************/

int CheckOptions(char *path)
{
	FILE *fp;
	int i;
	strcat(path, "/.ps2htmlrc");

	fp = fopen(path, "r");
	if (fp == (FILE *)NULL)
	{
		/* fclose(fp); */
		fp = fopen(path, "w");
		if (fp == (FILE *)NULL)
		{
			xperror("fopen");
			return 1;
		}
		else for (i=0; OptionFile[i] != (char *)NULL; i++)
			fprintf(fp, "%s", OptionFile[i]);
	}
	fclose(fp);
	return 0;
}

int ParseOptions(char *path)
{
	FILE *fp;
	char *tmp;
	char ch;
	int i=0;
	char *line=(char *)malloc(70*sizeof(char));
	if (line == (char *)NULL)
	{ xperror("malloc"); exit(1); }

	fp = fopen(path, "r");
	while ((ch = fgetc(fp)) != EOF)
	{
		ungetc(ch, fp);
		while((ch = fgetc(fp)) != '\n')
			line[i++] = ch;
		line[i] = '\0';
		if ((*line == '#') || (*line == '\0')); /* Ignore this line */
		else
		{
			tmp = strchr(line, ' ');
			*tmp++ = '\0';
			tmp = strchr(tmp, ' ');
			*tmp++ = '\0';
			if (!strcmp(line, "Title"))
				strcpy(Title, tmp);
			if (!strcmp(line, "Images"))
			{
				if (strstr(tmp, "ON"))
					Images = TRUE;
				else Images = FALSE;
			}
			if (!strcmp(line, "IFormat"))
			{
				if (strstr(tmp, "gif"))
					IFormat = gif;
				else IFormat = jpeg;
			}
			if (!strcmp(line, "PsImages"))
			{
				if (strstr(tmp, "ON"))
					PsImages = TRUE;
				else PsImages = FALSE;
			}
			if (!strcmp(line, "Sleep"))
			{
				SleepTime = atoi(tmp);
			}
			if (!strcmp(line, "Align"))
			{
				if (strstr(tmp, "left"))
					Align = LEFT;
				else if (strstr(tmp, "center"))
					Align = CENTRAL;
				else Align = RIGHT;
			}
			if (!strcmp(line, "Difference"))
			{
				Diff = atoi(tmp);
			}
			if (!strcmp(line, "MinDistance"))
			{
				MinDist = atoi(tmp);
			}
			if (!strcmp(line, "LnBreaks"))
			{
				if (strstr(tmp, "ON"))
					LnBreaks = TRUE;
				else LnBreaks = FALSE;
			}
			if (!strcmp(line, "Encoding"))
			{
				if (strstr(tmp, "normal"))
					EnCoding = NORMAL;
				else if (strstr(tmp, "math"))
					EnCoding = MATH;
				else EnCoding = MANUAL;
			}
			if (!strcmp(line, "EncFile"))
			{
				if (!strcmp(tmp, "null"))
					strcpy(EncFile, tmp);
			}
		}
		*line = '\0';
		i=0;
	}
	if (EnCoding == MANUAL)
		FillManualVector(EncFile);
}

int FillManualVector(char *filename)
{
	FILE *fp;
	int i, size;
	char *name, *tmp;

	name = (char *)malloc(20*sizeof(char));
	if (name == (char *)NULL)
	{ xperror("malloc"); exit(1); }
	tmp = (char *)malloc(10*sizeof(char));
	if (tmp == (char *)NULL)
	{ xperror("malloc"); exit(1); }

	fp = fopen(filename, "r");
	if (fp != (FILE *)NULL)
	{
		fscanf(fp, "%s%d", name, &size);
		for (i=0; i<size; i++)
		{
			fscanf(fp, "%s", tmp);
			ManualDvipsGlyphs[i] = (char *)malloc(strlen(tmp)*sizeof(char));
			tmp++;
			strcpy(ManualDvipsGlyphs[i], tmp);
		}
		fclose(fp);
	}
	else
	{
		xperror("fopen");
		EnCoding = NORMAL;
	}
	free(name);
	free(tmp);
}

/****************************************************************************
 * Check local environment, see if we've got a prayer of working...	    *
 ****************************************************************************/

#define TEMPNAME "ps2html.temp"		/* Temp file for output.	    */

/* Run program, give it args, look for string in its output:		    */

int CheckPgm(char *program, char *args)
 { char buf[200]; int status;
   sprintf(buf, "%s %s > %s 2>&1", program, args, TEMPNAME);

   if (Debug) fprintf(stderr, "System(%s)..." , buf);
   status = system(buf);
   if (Debug) fprintf(stderr, " returns 0x%x\n", status);

   return 0xFF & (status>>8); 
 }

int GrepResult(char *result)
 { char buf[200]; int status;
   sprintf(buf, "grep %c%s%c %s > /dev/null", '"', result, '"', TEMPNAME);
   if (Debug) fprintf(stderr, "System(%s)..." , buf);
   status = system(buf);
   if (Debug) fprintf(stderr, " returns 0x%x\n", status);
   return status & 0xFF00;
 }

int CheckEnv()
 { int errs = 0;

   if (CheckPgm(GSName, "-h"))
    { fprintf(stderr, "Can't run Ghostscript (%s command)...", GSName);
      fprintf(stderr, " is it properly installed?\n");
      unlink(TEMPNAME);
      exit(-1);
    }

   if (1)
    { CheckPgm(PostCommandName, "-h");	
      /* Unfortunately, postprocessor doesn't return appropriate status here... */
      if (GrepResult(PostCommandName))
       { fprintf(stderr, "ps2html: Unrecognized output from %s -h.\n",
		 PostCommandName);
	 fprintf(stderr, "  Are you sure its installed properly?\n");
	 ++errs;
       }
    }

   if (CheckPgm(HackPPMName, "-h"))
    { fprintf(stderr, "Can't execute hackppm command '%s -h'.\n", HackPPMName);
      fprintf(stderr, "  Is %s installed properly?\n", HackPPMName);
      unlink(TEMPNAME);
      exit(-1);
    }

   if (errs)
    { fprintf(stderr, "ps2html WARNING: your envirnonment may not be");
      fprintf(stderr, " appropriately for ps2html!\n");
    }
   else
    { fprintf(stderr, "ps2html: Environment appropriate.\n"); }

   unlink(TEMPNAME);
   return errs;
 }

