DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T p

⟦ab5cff4b6⟧ TextFile

    Length: 7582 (0x1d9e)
    Types: TextFile
    Names: »paths.c«

Derivation

└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
    └─⟦this⟧ »./tex82/cmf/MFlib/paths.c« 

TextFile

/*
** PATHS.C -- external procedures:
**
**	procedure setpaths;
**		{ initialize path database from environment variables	     }
**
**	function testaccess(
**			var	filename: packed array of char;
**			var	realfilename: packed array of char;
**				accessmode: integer;
**				filepath: integer	): boolean;
**		{ check file whose name is in array filename to see	     }
**		{ if it can be accessed using mode specified in accessmode.  }
**		{ use the path selected by filepath to try to find file      }
**		{ NB: >>> side effect <<< is to set array realfilename	     }
**		{ to complete path name of located file.		     }
**		{ Returns "TRUE" if found and can be accessed, else "FALSE"  }
** 
*/

#define	R_OK	4

#include <stdio.h>
#define	EXTERN	extern
#include "../mfd.h"
#undef	close			/* We're going to use the Unix close call */

/*
** These routines reference the following global variables and constants
** from MetaFont and it's associated utilities. If the name or type of
** these variables is changed in the pascal source, be sure to make them
** match here!
*/

#define READACCESS 4			/* args to test_access()	*/
#define WRITEACCESS 2

#define NOFILEPATH 0
#define TEXINPUTFILEPATH 1
#define TEXREADFILEPATH 2
#define TEXFONTFILEPATH 3
#define TEXFORMATFILEPATH 4
#define TEXPOOLFILEPATH 5
#define MFINPUTFILEPATH 6
#define MFBASEFILEPATH 7
#define MFPOOLFILEPATH 8

/*
** Fixed arrays are used to hold the paths, to avoid any
** possible problems involving interaction of malloc and undump
*/

#define	MAXINPATHCHARS		700
#define	MAXOTHPATHCHARS		100

char TeXinputpath[MAXINPATHCHARS] = TEXINPUTS;
char TeXfontpath[MAXOTHPATHCHARS] = TEXFONTS;
char TeXformatpath[MAXOTHPATHCHARS] = TEXFORMATS;
char TeXpoolpath[MAXOTHPATHCHARS] = TEXPOOL;
char MFinputpath[MAXINPATHCHARS] = MFINPUTS;
char MFbasepath[MAXOTHPATHCHARS] = MFBASES;
char MFpoolpath[MAXOTHPATHCHARS] = MFPOOL;

extern char *getenv();

/*
** First, some internal routines:
**
**   path_copypath(s1,s2,n,pathname)
**	copies at most n characters (including the null) from
**	string s2 to string s1, giving an error message for
**	 paths that are too long, identifying the PATH name.
*/
void path_copypath(s1,s2,n,pathname)
    register char *s1,*s2,*pathname;
    register int n;
{
	while ((*s1++ = *s2++) != '\0')
	    if (--n == 0) {
		fprintf(stderr, "! Environment search path '%s' is too big\n",
			pathname);
		*--s1 = '\0';
		return;		/* let user continue with truncated path */
	    }
}

/*
**    path_select(pathsel)
**	returns a char* pointer to the string selected by the path
**	specifier, or NULL if no path or illegal path selected
*/
char *path_select(pathsel)
integer pathsel;
{
    char *pathstring = NULL;

    switch(pathsel) {
	case TEXINPUTFILEPATH:
	case TEXREADFILEPATH:
	    pathstring = TeXinputpath; break;
	case TEXFONTFILEPATH:
	    pathstring = TeXfontpath; break;
	case TEXFORMATFILEPATH:
	    pathstring = TeXformatpath; break;
	case TEXPOOLFILEPATH:
	    pathstring = TeXpoolpath; break;
	case MFINPUTFILEPATH:
	    pathstring = MFinputpath; break;
	case MFBASEFILEPATH:
	    pathstring = MFbasepath; break;
	case MFPOOLFILEPATH:
	    pathstring = MFpoolpath; break;
	default:
	    pathstring = NULL;
    }
    return(pathstring);
}

/*
**   path_buildname(filename, buffername, cpp)
**	makes buffername contain the directory at *cpp,
**	followed by '/', followed by the characters in filename
**	up until the first blank there, and finally a '\0'.
**	The cpp pointer is left pointing at the next directory
**	in the path.
**	
**	But: if *cpp == NULL, then we are supposed to use filename as is.
*/
void path_buildname(filename, buffername, cpp)
    char *filename, *buffername;
    char **cpp;
{
    register char *p,*realname;
    
    realname = buffername;
    if ((p = *cpp)!=NULL) {
	while ((*p != ':') && (*p != '\0')) {
	    *realname++ = *p++;
	    if (realname >= &(buffername[FILENAMESIZE-1]))
		break;
	}
	if (*p == '\0') *cpp = NULL;	/* at end of path now */
	else *cpp = p+1;		/* else get past ':' */
	*realname++ = '/';	/* separate the area from the name to follow */
    }
    /* now append filename to buffername... */
    p = filename;
    if (*p == 0) p++;
    while (*p != ' ' && *p != 0) {
	if (realname >= &(buffername[FILENAMESIZE-1])) {
	    fprintf(stderr,"! Full file name is too long\n");
	    break;
	}
	*realname++ = *p++;
    }
    *realname = '\0';
}

/*
** setpaths is called to set up the default path arrays as follows:
** if the user's environment has a value for the appropriate value,
** then use it;  otherwise, leave the current value of the array
** (which may be the default path, or it may be the result of
** a call to setpaths on a previous run that was made the subject of
** an undump: this will give the maker of a preloaded MetaFont the
** option of providing a new set of "default" paths.
**
** Note that we have to copy the string from the environment area, since
** that will change on the next run (which matters if this is for a
** preloaded MetaFont).
*/

setpaths()
{
	register char *envpath;
	
	if ((envpath = getenv("TEXINPUTS")) != NULL)
	    path_copypath(TeXinputpath,envpath,MAXINPATHCHARS,"TEXINPUTS");
	if ((envpath = getenv("TEXFONTS")) != NULL)
	    path_copypath(TeXfontpath,envpath,MAXOTHPATHCHARS,"TEXFONTS");
	if ((envpath = getenv("TEXFORMATS")) != NULL)
	    path_copypath(TeXformatpath,envpath,MAXOTHPATHCHARS,"TEXFORMATS");
	if ((envpath = getenv("TEXPOOL")) != NULL)
	    path_copypath(TeXpoolpath,envpath,MAXOTHPATHCHARS,"TEXPOOL");
	if ((envpath = getenv("MFINPUTS")) != NULL)
	    path_copypath(MFinputpath,envpath,MAXINPATHCHARS,"MFINPUTS");
	if ((envpath = getenv("MFBASES")) != NULL)
	    path_copypath(MFbasepath,envpath,MAXOTHPATHCHARS,"MFBASES");
	if ((envpath = getenv("MFPOOL")) != NULL)
	    path_copypath(MFpoolpath,envpath,MAXOTHPATHCHARS,"MFPOOL");
}

/*
**   testaccess(filename, realfilename, amode, filepath)
**
**	Test whether or not the file whose name is in filename
**	can be opened for reading (if mode=READACCESS)
**	or writing (if mode=WRITEACCESS).
**
**	The filepath argument is one of the ...FILEPATH constants
**	defined above.  If the filename given in filename does not
**	begin with '/', we try prepending all the ':'-separated directory
**	names in the appropriate path to the filename until access
**	can be made, if it ever can.
**
**	The realfilename array will contain the name that
**	yielded an access success.
*/

int ztestaccess(filename, realfilename, amode, filepath)
    char *filename, *realfilename;
    integer amode, filepath;
{
    register boolean ok;
    register char *p;
    char *curpathplace;
    int f;

    filename++;
    realfilename++;
    
    if (*filename == '/')	/* file name has absolute path */
	curpathplace = NULL;
    else
        curpathplace = path_select(filepath);

    do {
	path_buildname(filename, realfilename, &curpathplace);
	if (amode==READACCESS) {
	    /* use system call "access" to see if we could read it */
	    if (access(realfilename, 04) == 0) ok = true;
	    else ok = false;
	} else {
	    /* WRITEACCESS: use creat to see if we could create it, but close
	    the file again if we're OK, to let pc open it for real */
	    if ((f = creat(realfilename, 0666)) >= 0) {
		ok = true;
		(void) close(f);
	    } else
		ok = false;
	}
    } while (!ok && curpathplace != NULL);

    if (ok) {		/* pad realnameoffile with blanks, as Pascal wants */
	for (p = realfilename; *p != '\0'; p++)
	    ;		/* nothing: find end of string */
	while (p <= &(realfilename[FILENAMESIZE-1]))
	    *p++ = ' ';
    }

    return (ok);
}