Hash_SetValue(entry, (long)stb.st_mtime);
Hash_SetValue(entry, (ClientData)((long)stb.st_mtime));
Dir_FindFile (name, path)    char    	  *name;    /* the file to find */    Lst           path;	    /* the Lst of directories to search */{    register char *p1;	    /* pointer into p->name */    register char *p2;	    /* pointer into name */    LstNode       ln;	    /* a list element */    register char *file;    /* the current filename to check */    register Path *p;	    /* current path member */    register char *cp;	    /* index of first slash, if any */    Boolean	  hasSlash; /* true if 'name' contains a / */    struct stat	  stb;	    /* Buffer for stat, if necessary */    Hash_Entry	  *entry;   /* Entry for mtimes table */    /*     * Find the final component of the name and note whether it has a     * slash in it (the name, I mean)     */    cp = strrchr (name, '/');    if (cp) {	hasSlash = TRUE;	cp += 1;    } else {	hasSlash = FALSE;	cp = name;    }    if (DEBUG(DIR)) {	printf("Searching for %s...", name);    }    /*     * No matter what, we always look for the file in the current directory     * before anywhere else and we *do not* add the ./ to it if it exists.     * This is so there are no conflicts between what the user specifies     * (fish.c) and what pmake finds (./fish.c).     */    if ((!hasSlash || (cp - name == 2 && *name == '.')) &&	(Hash_FindEntry (&dot->files, cp) != (Hash_Entry *)NULL)) {	    if (DEBUG(DIR)) {		printf("in '.'\n");	    }	    hits += 1;	    dot->hits += 1;	    return (estrdup (name));    }    if (Lst_Open (path) == FAILURE) {	if (DEBUG(DIR)) {	    printf("couldn't open path, file not found\n");	}	misses += 1;	return ((char *) NULL);    }    /*     * We look through all the directories on the path seeking one which     * contains the final component of the given name and whose final     * component(s) match the name's initial component(s). If such a beast     * is found, we concatenate the directory name and the final component     * and return the resulting string. If we don't find any such thing,     * we go on to phase two...     */    while ((ln = Lst_Next (path)) != NULL) {	p = (Path *) Lst_Datum (ln);	if (DEBUG(DIR)) {	    printf("%s...", p->name);	}	if (Hash_FindEntry (&p->files, cp) != (Hash_Entry *)NULL) {	    if (DEBUG(DIR)) {		printf("here...");	    }	    if (hasSlash) {		/*		 * If the name had a slash, its initial components and p's		 * final components must match. This is false if a mismatch		 * is encountered before all of the initial components		 * have been checked (p2 > name at the end of the loop), or		 * we matched only part of one of the components of p		 * along with all the rest of them (*p1 != '/').		 */		p1 = p->name + strlen (p->name) - 1;		p2 = cp - 2;		while (p2 >= name && p1 >= p->name && *p1 == *p2) {		    p1 -= 1; p2 -= 1;		}		if (p2 >= name || (p1 >= p->name && *p1 != '/')) {		    if (DEBUG(DIR)) {			printf("component mismatch -- continuing...");		    }		    continue;		}	    }	    file = str_concat (p->name, cp, STR_ADDSLASH);	    if (DEBUG(DIR)) {		printf("returning %s\n", file);	    }	    Lst_Close (path);	    p->hits += 1;	    hits += 1;	    return (file);	} else if (hasSlash) {	    /*	     * If the file has a leading path component and that component	     * exactly matches the entire name of the current search	     * directory, we assume the file doesn't exist and return NULL.	     */	    for (p1 = p->name, p2 = name; *p1 && *p1 == *p2; p1++, p2++) {		continue;	    }	    if (*p1 == '\0' && p2 == cp - 1) {		if (DEBUG(DIR)) {		    printf("must be here but isn't -- returing NULL\n");		}		Lst_Close (path);		return ((char *) NULL);	    }	}    }    /*     * We didn't find the file on any existing members of the directory.     * If the name doesn't contain a slash, that means it doesn't exist.     * If it *does* contain a slash, however, there is still hope: it     * could be in a subdirectory of one of the members of the search     * path. (eg. /usr/include and sys/types.h. The above search would     * fail to turn up types.h in /usr/include, but it *is* in     * /usr/include/sys/types.h) If we find such a beast, we assume there     * will be more (what else can we assume?) and add all but the last     * component of the resulting name onto the search path (at the     * end). This phase is only performed if the file is *not* absolute.     */    if (!hasSlash) {	if (DEBUG(DIR)) {	    printf("failed.\n");	}	misses += 1;	return ((char *) NULL);    }    if (*name != '/') {	Boolean	checkedDot = FALSE;	if (DEBUG(DIR)) {	    printf("failed. Trying subdirectories...");	}	(void) Lst_Open (path);	while ((ln = Lst_Next (path)) != NULL) {	    p = (Path *) Lst_Datum (ln);	    if (p != dot) {		file = str_concat (p->name, name, STR_ADDSLASH);	    } else {		/*		 * Checking in dot -- DON'T put a leading ./ on the thing.		 */		file = estrdup(name);		checkedDot = TRUE;	    }	    if (DEBUG(DIR)) {		printf("checking %s...", file);	    }	    if (stat (file, &stb) == 0) {		if (DEBUG(DIR)) {		    printf("got it.\n");		}		Lst_Close (path);		/*		 * We've found another directory to search. We know there's		 * a slash in 'file' because we put one there. We nuke it after		 * finding it and call Dir_AddDir to add this new directory		 * onto the existing search path. Once that's done, we restore		 * the slash and triumphantly return the file name, knowing		 * that should a file in this directory every be referenced		 * again in such a manner, we will find it without having to do		 * numerous numbers of access calls. Hurrah!		 */		cp = strrchr (file, '/');		*cp = '\0';		Dir_AddDir (path, file);		*cp = '/';		/*		 * Save the modification time so if it's needed, we don't have		 * to fetch it again.		 */		if (DEBUG(DIR)) {		    printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),			    file);		}		entry = Hash_CreateEntry(&mtimes, (char *) file,					 (Boolean *)NULL);		Hash_SetValue(entry, (long)stb.st_mtime);		nearmisses += 1;		return (file);	    } else {		free (file);	    }	}	if (DEBUG(DIR)) {	    printf("failed. ");	}	Lst_Close (path);	if (checkedDot) {	    /*	     * Already checked by the given name, since . was in the path,	     * so no point in proceeding...	     */	    if (DEBUG(DIR)) {		printf("Checked . already, returning NULL\n");	    }	    return(NULL);	}    }    /*     * Didn't find it that way, either. Sigh. Phase 3. Add its directory     * onto the search path in any case, just in case, then look for the     * thing in the hash table. If we find it, grand. We return a new     * copy of the name. Otherwise we sadly return a NULL pointer. Sigh.     * Note that if the directory holding the file doesn't exist, this will     * do an extra search of the final directory on the path. Unless something     * weird happens, this search won't succeed and life will be groovy.     *     * Sigh. We cannot add the directory onto the search path because     * of this amusing case:     * $(INSTALLDIR)/$(FILE): $(FILE)     *     * $(FILE) exists in $(INSTALLDIR) but not in the current one.     * When searching for $(FILE), we will find it in $(INSTALLDIR)     * b/c we added it here. This is not good...     */#ifdef notdef    cp[-1] = '\0';    Dir_AddDir (path, name);    cp[-1] = '/';    bigmisses += 1;    ln = Lst_Last (path);    if (ln == NULL) {	return ((char *) NULL);    } else {	p = (Path *) Lst_Datum (ln);    }    if (Hash_FindEntry (&p->files, cp) != (Hash_Entry *)NULL) {	return (estrdup (name));    } else {	return ((char *) NULL);    }#else /* !notdef */    if (DEBUG(DIR)) {	printf("Looking for \"%s\"...", name);    }    bigmisses += 1;    entry = Hash_FindEntry(&mtimes, name);    if (entry != (Hash_Entry *)NULL) {	if (DEBUG(DIR)) {	    printf("got it (in mtime cache)\n");	}	return(estrdup(name));    } else if (stat (name, &stb) == 0) {	entry = Hash_CreateEntry(&mtimes, name, (Boolean *)NULL);	if (DEBUG(DIR)) {	    printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),		    name);	}	Hash_SetValue(entry, (long)stb.st_mtime);	return (estrdup (name));    } else {	if (DEBUG(DIR)) {	    printf("failed. Returning NULL\n");	}	return ((char *)NULL);    }#endif /* notdef */}