/* Copyright (C) 2000 Damir Zucic */

/*=============================================================================

				openfile_r.c

Purpose:
	Try to open file for reading. First try with the specified file
	(path)name.  If this  doesn't  work,  check the content  of the
	environment variable MOL_DIR.  If this environment  variable is
	defined, append the file name to the content of MOL_DIR and try
	again.  If this attempt fails,  check  the content of  MOL_PATH
	environment variable. If MOL_PATH is defined, parse the content
	to obtain  the list  of  directories.  Try with  each  of these
	directories if necessary.  If all attempts fail,  return  NULL.
	Directories in  MOL_PATH should be separated by space or colon.
	This function is capable to interpret tilde [~] and $HOME.

Input:
	(1) Input file name (pointer to string).
	(2) The content of environment variable MOL_DIR may be used.
	(3) The content of environment variable MOL_PATH may be used.

Output:
	Return value.

Return value:
	(1) File pointer, on success.
	(2) NULL on failure.

Notes:
	(1) No error messages.

========includes:============================================================*/

#include <stdio.h>

#include <string.h>
#include <stdlib.h>

#include "defines.h"

/*======try to open file:====================================================*/

FILE *OpenFileForReading_ (char *file_nameP)
{
static FILE	*fileP;
static char	*env_valueP;
char		*currentP;
char 		*tokenP;
char		copyA[STRINGSIZE];
char		path_nameA[STRINGSIZE];
int		n, i;

/* If input file name contains the string $HOME: */
if (strstr (file_nameP, "$HOME") == file_nameP)
	{
	/* Get the value of environment variable HOME: */
	if ((env_valueP = getenv ("HOME")) == NULL) return NULL;

	/* Copy this value: */
	strncpy (path_nameA, env_valueP, STRINGSIZE - 1);
	path_nameA[STRINGSIZE - 1] = '\0';

	/* The last character should be slash: */
	n = (int) strlen (path_nameA) - 1;
	if (path_nameA[n] != '/') strcat (path_nameA, "/");

	/* Concatenate the file name (without $HOME): */
	n = STRINGSIZE - (int) strlen (path_nameA) - 1;
	strncat (path_nameA, file_nameP + 5, n);
	path_nameA[STRINGSIZE - 1] = '\0';

	/* Try to open file: */
	fileP = fopen (path_nameA, "r");
	return fileP;
	}

/* If input file name contains tilde [~]: */
else if (*file_nameP == '~')
	{
	/* Tilde alone defines no file: */
	if (strlen (file_nameP) == 1) return NULL;

	/* If the second character is slash [/]: */
	if (*(file_nameP + 1) == '/')
		{
		/* Get the value of environment variable HOME: */
		if ((env_valueP = getenv ("HOME")) == NULL) return NULL;

		/* Copy this value: */
		strncpy (path_nameA, env_valueP, STRINGSIZE - 1);
		path_nameA[STRINGSIZE - 1] = '\0';

		/* The last character should be slash: */
		n = (int) strlen (path_nameA) - 1;
		if (path_nameA[n] != '/') strcat (path_nameA, "/");

		/* Concatenate the file name (without tilde): */
		n = STRINGSIZE - (int) strlen (path_nameA) - 1;
		strncat (path_nameA, file_nameP + 1, n);
		path_nameA[STRINGSIZE - 1] = '\0';

		/* Try to open file: */
		fileP = fopen (path_nameA, "r");
		return fileP;
		}

	/* If the second character is not slash,  remove user name */
	/* from $HOME and replace tilde with the resulting string: */
	else
		{
		/* Get the value of environment variable HOME: */
		if ((env_valueP = getenv ("HOME")) == NULL) return NULL;

		/* Copy this string, but reverted: */
		n = strlen  (env_valueP);
		if (n == 0) return NULL;
		for (i = 0; i < n; i++)
			{
			path_nameA[i] = *(env_valueP + n - 1 - i);
			}
		path_nameA[n] = '\0';

		/* Replace all characters left from the first slash with \0: */
		for (i = 0; i < n; i++)
			{
			if (path_nameA[i] == '/') break;
			else path_nameA[i] = '\0';
			}

		/* Revert the string again: */
		for (i = 0; i < n; i++)
			{
			copyA[i] = path_nameA[n - 1 - i];
			}
		copyA[n] = '\0';
		strncpy (path_nameA, copyA, n);

		/* Concatenate the file name (without tilde): */
		n = STRINGSIZE - (int) strlen (path_nameA) - 1;
		strncat (path_nameA, file_nameP + 1, n);
		path_nameA[STRINGSIZE - 1] = '\0';

		/* Try to open file: */
		fileP = fopen (path_nameA, "r");
		return fileP;
		}
	}

/* If this point  is reached,  the  input  file name */
/* contains neither  $HOME nor  tilde.  Try with the */
/* original file name and two environment variables. */

/* The first attempt to open file: */
if ((fileP = fopen (file_nameP, "r")) != NULL) return fileP;

/* Prepare the file name pointer. If the first character is slash, skip it! */
if (*file_nameP == '/') file_nameP++;

/* The second attempt (with MOL_DIR environment variable): */
if ((env_valueP = getenv ("MOL_DIR")) != NULL)
	{
	/* Copy the value of the MOL_DIR environment variable: */
	strncpy (path_nameA, env_valueP, STRINGSIZE - 1);
	path_nameA[STRINGSIZE - 1] = '\0';

	/* The last character should be slash: */
	n = (int) strlen (path_nameA) - 1;
	if (path_nameA[n] != '/') strcat (path_nameA, "/");

	/* Concatename the file name to directory name: */
	n = STRINGSIZE - (int) strlen (path_nameA) - 1;
	strncat (path_nameA, file_nameP, n);
	path_nameA[STRINGSIZE - 1] = '\0';

	/* The second attempt to open file: */
	if ((fileP = fopen (path_nameA, "r")) != NULL) return fileP;
	}

/* The third attempt (with MOL_PATH environment variable): */
if ((env_valueP = getenv ("MOL_PATH")) != NULL)
	{
	/* Copy the value of the MOL_PATH environment variable: */
	strncpy (copyA, env_valueP, STRINGSIZE - 1);
	copyA[STRINGSIZE - 1] = '\0';

	/* Try token by token: */
	currentP = copyA;
	while ((tokenP = strtok (currentP, " :\n")) != NULL)
		{
		/* Prepare the argument for the next call of strtok: */
		currentP = NULL;

		/* Copy the token: */
		strncpy (path_nameA, tokenP, STRINGSIZE - 1);
		path_nameA[STRINGSIZE - 1] = '\0';

		/* The last character should be slash (/): */
		n = (int) strlen (path_nameA) - 1;
		if (path_nameA[n] != '/') strcat (path_nameA, "/");

		/* Concatename the file name to directory name: */
		n = STRINGSIZE - (int) strlen (path_nameA) - 1;
		strncat (path_nameA, file_nameP, n);
		path_nameA[STRINGSIZE - 1] = '\0';

		/* Try to open file: */
		if ((fileP = fopen (path_nameA, "r")) != NULL) return fileP;
		}
	}

/* If this point is reached, all attempts failed; return NULL: */
return NULL;
}

/*===========================================================================*/


