Blame src/vpinit.c

Packit Service c6cebd
/*===========================================================================
Packit Service c6cebd
 Copyright (c) 1998-2000, The Santa Cruz Operation 
Packit Service c6cebd
 All rights reserved.
Packit Service c6cebd
 
Packit Service c6cebd
 Redistribution and use in source and binary forms, with or without
Packit Service c6cebd
 modification, are permitted provided that the following conditions are met:
Packit Service c6cebd
Packit Service c6cebd
 *Redistributions of source code must retain the above copyright notice,
Packit Service c6cebd
 this list of conditions and the following disclaimer.
Packit Service c6cebd
Packit Service c6cebd
 *Redistributions in binary form must reproduce the above copyright notice,
Packit Service c6cebd
 this list of conditions and the following disclaimer in the documentation
Packit Service c6cebd
 and/or other materials provided with the distribution.
Packit Service c6cebd
Packit Service c6cebd
 *Neither name of The Santa Cruz Operation nor the names of its contributors
Packit Service c6cebd
 may be used to endorse or promote products derived from this software
Packit Service c6cebd
 without specific prior written permission. 
Packit Service c6cebd
Packit Service c6cebd
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
Packit Service c6cebd
 IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
Packit Service c6cebd
 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
Packit Service c6cebd
 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
Packit Service c6cebd
 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Packit Service c6cebd
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Packit Service c6cebd
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Packit Service c6cebd
 INTERRUPTION)
Packit Service c6cebd
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit Service c6cebd
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
Packit Service c6cebd
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
Packit Service c6cebd
 DAMAGE. 
Packit Service c6cebd
 =========================================================================*/
Packit Service c6cebd
Packit Service c6cebd
/* vpinit - initialize vpdirs or update vpdirs based on currentdir */
Packit Service c6cebd
Packit Service c6cebd
#include <stdio.h>	/* stderr */
Packit Service c6cebd
#include <stdlib.h>
Packit Service c6cebd
#include <string.h>
Packit Service c6cebd
#include <unistd.h>
Packit Service c6cebd
#include "vp.h"
Packit Service c6cebd
#include "alloc.h"
Packit Service c6cebd
#include "library.h"
Packit Service c6cebd
#include "global.h"
Packit Service c6cebd
#include "constants.h"
Packit Service c6cebd
Packit Service c6cebd
#if !NOMALLOC
Packit Service c6cebd
char	**vpdirs;	/* directories (including current) in view path */
Packit Service c6cebd
#else
Packit Service c6cebd
char	vpdirs[MAXDIR][DIRLEN + 1];
Packit Service c6cebd
#define	MAXVPATH (MAXDIR * (DIRLEN + 1))
Packit Service c6cebd
#endif
Packit Service c6cebd
int	vpndirs;	/* number of directories in view path */
Packit Service c6cebd
Packit Service c6cebd
void
Packit Service c6cebd
vpinit(char *current_dir)
Packit Service c6cebd
{
Packit Service c6cebd
	char	*suffix;	/* path from view path node */
Packit Service c6cebd
	char	*vpath;		/* VPATH environment variable value */
Packit Service c6cebd
	char	buf[MAXPATH + 1];
Packit Service c6cebd
	int	i;
Packit Service c6cebd
	char	*s;
Packit Service c6cebd
#if NOMALLOC
Packit Service c6cebd
	char	*node;		/* view path node */
Packit Service c6cebd
	char	vpathbuf[MAXVPATH + 1];
Packit Service c6cebd
#endif
Packit Service c6cebd
	
Packit Service c6cebd
	/* if an existing directory list is to be updated, free it */
Packit Service c6cebd
	if (current_dir != NULL && vpndirs > 0) {
Packit Service c6cebd
#if !NOMALLOC
Packit Service c6cebd
		for (i = 0; i < vpndirs; ++i) {
Packit Service c6cebd
			free(vpdirs[i]);
Packit Service c6cebd
		}
Packit Service c6cebd
		free(vpdirs);
Packit Service c6cebd
#endif
Packit Service c6cebd
		vpndirs = 0;
Packit Service c6cebd
	}
Packit Service c6cebd
	/* return if the directory list has been computed */
Packit Service c6cebd
	/* or there isn't a view path environment variable */
Packit Service c6cebd
	if (vpndirs > 0 || (vpath = getenv("VPATH")) == NULL ||
Packit Service c6cebd
	    *vpath == '\0') {
Packit Service c6cebd
		return;
Packit Service c6cebd
	}
Packit Service c6cebd
	/* if not given, get the current directory name */
Packit Service c6cebd
	if (current_dir == NULL && (current_dir = getcwd(buf, MAXPATH)) == NULL) {
Packit Service c6cebd
		(void) fprintf(stderr, "%s: cannot get current directory name\n", argv0);
Packit Service c6cebd
		return;
Packit Service c6cebd
	}
Packit Service c6cebd
	/* see if this directory is in the first view path node */
Packit Service c6cebd
	for (i = 0; vpath[i] == current_dir[i] && vpath[i] != '\0'; ++i) {
Packit Service c6cebd
		;
Packit Service c6cebd
	}
Packit Service c6cebd
	if ((vpath[i] != ':' && vpath[i] != '\0') ||
Packit Service c6cebd
	    (current_dir[i] != '/' && current_dir[i] != '\0')) {
Packit Service c6cebd
		return;
Packit Service c6cebd
	}
Packit Service c6cebd
	suffix = &current_dir[i];
Packit Service c6cebd
#if !NOMALLOC
Packit Service c6cebd
Packit Service c6cebd
	/* count the nodes in the view path */
Packit Service c6cebd
	vpndirs = 1;
Packit Service c6cebd
	for (i = 0; vpath[i] != '\0'; ++i) {
Packit Service c6cebd
		if (vpath[i] == ':' && vpath[i + 1]) {
Packit Service c6cebd
			++vpndirs;
Packit Service c6cebd
		}
Packit Service c6cebd
	}
Packit Service c6cebd
	/* create the source directory list */
Packit Service c6cebd
	vpdirs = mymalloc(vpndirs * sizeof(*vpdirs));
Packit Service c6cebd
Packit Service c6cebd
	/* don't change VPATH in the environment */
Packit Service c6cebd
	vpath = my_strdup(vpath);
Packit Service c6cebd
	
Packit Service c6cebd
	/* split the view path into nodes */
Packit Service c6cebd
	for (i = 0, s = vpath; *s != '\0'; ++i) {
Packit Service c6cebd
		vpdirs[i] = s;
Packit Service c6cebd
		while (*s != '\0' && *++s != ':') {
Packit Service c6cebd
			if (*s == '\n') {
Packit Service c6cebd
				*s = '\0';
Packit Service c6cebd
			}
Packit Service c6cebd
		}
Packit Service c6cebd
		if (*s != '\0') {
Packit Service c6cebd
			*s++ = '\0';
Packit Service c6cebd
		}
Packit Service c6cebd
	}
Packit Service c6cebd
	/* convert the view path nodes to directories */
Packit Service c6cebd
	for (i = 0; i < vpndirs; ++i) {
Packit Service c6cebd
		s = mymalloc(strlen(vpdirs[i]) + strlen(suffix) + 1);
Packit Service c6cebd
		(void) strcpy(s, vpdirs[i]);
Packit Service c6cebd
		(void) strcat(s, suffix);
Packit Service c6cebd
		vpdirs[i] = s;
Packit Service c6cebd
	}
Packit Service c6cebd
	free(vpath);
Packit Service c6cebd
#else
Packit Service c6cebd
	/* don't change VPATH in the environment */
Packit Service c6cebd
	if (strlen(vpath) > MAXVPATH) {
Packit Service c6cebd
		(void) fprintf(stderr, "%s: VPATH is longer than %d characters: %s\n", argv0, MAXVPATH, vpath);
Packit Service c6cebd
		return;
Packit Service c6cebd
	}
Packit Service c6cebd
	(void) strcpy(vpathbuf, vpath);
Packit Service c6cebd
	s = vpathbuf;
Packit Service c6cebd
	
Packit Service c6cebd
	/* convert the view path nodes to directories */
Packit Service c6cebd
	while (*s != '\0') {
Packit Service c6cebd
		
Packit Service c6cebd
		/* get the next node */
Packit Service c6cebd
		node = s;
Packit Service c6cebd
		while (*s != '\0' && *++s != ':') {
Packit Service c6cebd
			if (*s == '\n') {
Packit Service c6cebd
				*s = '\0';
Packit Service c6cebd
			}
Packit Service c6cebd
		}
Packit Service c6cebd
		if (*s != '\0') {
Packit Service c6cebd
			*s++ = '\0';
Packit Service c6cebd
		}
Packit Service c6cebd
		/* ignore a directory that is too long */
Packit Service c6cebd
		if (strlen(node) + strlen(suffix) > DIRLEN) {
Packit Service c6cebd
			(void) fprintf(stderr, "%s: VPATH directory is longer than %d characters: %s%s\n", argv0, DIRLEN, node, suffix);
Packit Service c6cebd
		}
Packit Service c6cebd
		else if (vpndirs >= MAXDIR) {
Packit Service c6cebd
			(void) fprintf(stderr, "%s: VPATH has more than %d nodes\n", argv0, vpndirs);
Packit Service c6cebd
			return;
Packit Service c6cebd
		}
Packit Service c6cebd
		else {
Packit Service c6cebd
			/* create the view path directory */
Packit Service c6cebd
			(void) strcpy(vpdirs[vpndirs], node);
Packit Service c6cebd
			(void) strcat(vpdirs[vpndirs], suffix);
Packit Service c6cebd
			++vpndirs;
Packit Service c6cebd
		}
Packit Service c6cebd
	}
Packit Service c6cebd
#endif
Packit Service c6cebd
}