Beispiel #1
0
/*-
 *-----------------------------------------------------------------------
 * Targ_End --
 *	Finalize this module
 *
 * Results:
 *	None
 *
 * Side Effects:
 *	All lists and gnodes are cleared
 *-----------------------------------------------------------------------
 */
void
Targ_End(void)
{
#ifdef CLEANUP
    Lst_Destroy(allTargets, NULL);
    if (allGNs)
	Lst_Destroy(allGNs, TargFreeGN);
    Hash_DeleteTable(&targets);
#endif
}
Beispiel #2
0
/*-
 *-----------------------------------------------------------------------
 * ArchFree --
 *	Free memory used by an archive
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	None.
 *
 *-----------------------------------------------------------------------
 */
static void
ArchFree(void *ap)
{
    Arch *a = (Arch *)ap;
    Hash_Search	  search;
    Hash_Entry	  *entry;

    /* Free memory from hash entries */
    for (entry = Hash_EnumFirst(&a->members, &search);
	 entry != NULL;
	 entry = Hash_EnumNext(&search))
	free(Hash_GetValue(entry));

    free(a->name);
    free(a->fnametab);
    Hash_DeleteTable(&a->members);
    free(a);
}
Beispiel #3
0
/*-
 *-----------------------------------------------------------------------
 * TargFreeGN  --
 *	Destroy a GNode
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	None.
 *-----------------------------------------------------------------------
 */
static void
TargFreeGN(void *gnp)
{
    GNode *gn = (GNode *)gnp;


    free(gn->name);
    if (gn->uname)
	free(gn->uname);
    if (gn->path)
	free(gn->path);
    /* gn->fname points to name allocated when file was opened, don't free */

    Lst_Destroy(gn->iParents, NULL);
    Lst_Destroy(gn->cohorts, NULL);
    Lst_Destroy(gn->parents, NULL);
    Lst_Destroy(gn->children, NULL);
    Lst_Destroy(gn->order_succ, NULL);
    Lst_Destroy(gn->order_pred, NULL);
    Hash_DeleteTable(&gn->context);
    Lst_Destroy(gn->commands, NULL);
    free(gn);
}
Beispiel #4
0
/*-
 *-----------------------------------------------------------------------
 * ArchStatMember --
 *	Locate a member of an archive, given the path of the archive and
 *	the path of the desired member.
 *
 * Input:
 *	archive		Path to the archive
 *	member		Name of member. If it is a path, only the last
 *			component is used.
 *	hash		TRUE if archive should be hashed if not already so.
 *
 * Results:
 *	A pointer to the current struct ar_hdr structure for the member. Note
 *	That no position is returned, so this is not useful for touching
 *	archive members. This is mostly because we have no assurances that
 *	The archive will remain constant after we read all the headers, so
 *	there's not much point in remembering the position...
 *
 * Side Effects:
 *
 *-----------------------------------------------------------------------
 */
static struct ar_hdr *
ArchStatMember(char *archive, char *member, Boolean hash)
{
    FILE *	  arch;	      /* Stream to archive */
    int		  size;       /* Size of archive member */
    char	  *cp;	      /* Useful character pointer */
    char	  magic[SARMAG];
    LstNode	  ln;	      /* Lst member containing archive descriptor */
    Arch	  *ar;	      /* Archive descriptor */
    Hash_Entry	  *he;	      /* Entry containing member's description */
    struct ar_hdr arh;        /* archive-member header for reading archive */
    char	  memName[MAXPATHLEN+1];
    	    	    	    /* Current member name while hashing. */

    /*
     * Because of space constraints and similar things, files are archived
     * using their final path components, not the entire thing, so we need
     * to point 'member' to the final component, if there is one, to make
     * the comparisons easier...
     */
    cp = strrchr(member, '/');
    if (cp != NULL) {
	member = cp + 1;
    }

    ln = Lst_Find(archives, archive, ArchFindArchive);
    if (ln != NULL) {
	ar = (Arch *)Lst_Datum(ln);

	he = Hash_FindEntry(&ar->members, member);

	if (he != NULL) {
	    return ((struct ar_hdr *)Hash_GetValue(he));
	} else {
	    /* Try truncated name */
	    char copy[AR_MAX_NAME_LEN+1];
	    size_t len = strlen(member);

	    if (len > AR_MAX_NAME_LEN) {
		len = AR_MAX_NAME_LEN;
		strncpy(copy, member, AR_MAX_NAME_LEN);
		copy[AR_MAX_NAME_LEN] = '\0';
	    }
	    if ((he = Hash_FindEntry(&ar->members, copy)) != NULL)
		return ((struct ar_hdr *)Hash_GetValue(he));
	    return NULL;
	}
    }

    if (!hash) {
	/*
	 * Caller doesn't want the thing hashed, just use ArchFindMember
	 * to read the header for the member out and close down the stream
	 * again. Since the archive is not to be hashed, we assume there's
	 * no need to allocate extra room for the header we're returning,
	 * so just declare it static.
	 */
	 static struct ar_hdr	sarh;

	 arch = ArchFindMember(archive, member, &sarh, "r");

	 if (arch == NULL) {
	    return NULL;
	} else {
	    fclose(arch);
	    return (&sarh);
	}
    }

    /*
     * We don't have this archive on the list yet, so we want to find out
     * everything that's in it and cache it so we can get at it quickly.
     */
    arch = fopen(archive, "r");
    if (arch == NULL) {
	return NULL;
    }

    /*
     * We use the ARMAG string to make sure this is an archive we
     * can handle...
     */
    if ((fread(magic, SARMAG, 1, arch) != 1) ||
    	(strncmp(magic, ARMAG, SARMAG) != 0)) {
	    fclose(arch);
	    return NULL;
    }

    ar = bmake_malloc(sizeof(Arch));
    ar->name = bmake_strdup(archive);
    ar->fnametab = NULL;
    ar->fnamesize = 0;
    Hash_InitTable(&ar->members, -1);
    memName[AR_MAX_NAME_LEN] = '\0';

    while (fread((char *)&arh, sizeof(struct ar_hdr), 1, arch) == 1) {
	if (strncmp( arh.AR_FMAG, ARFMAG, sizeof(arh.AR_FMAG)) != 0) {
	    /*
	     * The header is bogus, so the archive is bad
	     * and there's no way we can recover...
	     */
	    goto badarch;
	} else {
	    /*
	     * We need to advance the stream's pointer to the start of the
	     * next header. Files are padded with newlines to an even-byte
	     * boundary, so we need to extract the size of the file from the
	     * 'size' field of the header and round it up during the seek.
	     */
	    arh.AR_SIZE[sizeof(arh.AR_SIZE)-1] = '\0';
	    size = (int)strtol(arh.AR_SIZE, NULL, 10);

	    (void)strncpy(memName, arh.AR_NAME, sizeof(arh.AR_NAME));
	    for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) {
		continue;
	    }
	    cp[1] = '\0';

#ifdef SVR4ARCHIVES
	    /*
	     * svr4 names are slash terminated. Also svr4 extended AR format.
	     */
	    if (memName[0] == '/') {
		/*
		 * svr4 magic mode; handle it
		 */
		switch (ArchSVR4Entry(ar, memName, size, arch)) {
		case -1:  /* Invalid data */
		    goto badarch;
		case 0:	  /* List of files entry */
		    continue;
		default:  /* Got the entry */
		    break;
		}
	    }
	    else {
		if (cp[0] == '/')
		    cp[0] = '\0';
	    }
#endif

#ifdef AR_EFMT1
	    /*
	     * BSD 4.4 extended AR format: #1/<namelen>, with name as the
	     * first <namelen> bytes of the file
	     */
	    if (strncmp(memName, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 &&
		isdigit((unsigned char)memName[sizeof(AR_EFMT1) - 1])) {

		unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);

		if (elen > MAXPATHLEN)
			goto badarch;
		if (fread(memName, elen, 1, arch) != 1)
			goto badarch;
		memName[elen] = '\0';
		if (fseek(arch, -elen, SEEK_CUR) != 0)
			goto badarch;
		if (DEBUG(ARCH) || DEBUG(MAKE)) {
		    fprintf(debug_file, "ArchStat: Extended format entry for %s\n", memName);
		}
	    }
#endif

	    he = Hash_CreateEntry(&ar->members, memName, NULL);
	    Hash_SetValue(he, bmake_malloc(sizeof(struct ar_hdr)));
	    memcpy(Hash_GetValue(he), &arh, sizeof(struct ar_hdr));
	}
	if (fseek(arch, (size + 1) & ~1, SEEK_CUR) != 0)
	    goto badarch;
    }

    fclose(arch);

    (void)Lst_AtEnd(archives, ar);

    /*
     * Now that the archive has been read and cached, we can look into
     * the hash table to find the desired member's header.
     */
    he = Hash_FindEntry(&ar->members, member);

    if (he != NULL) {
	return ((struct ar_hdr *)Hash_GetValue(he));
    } else {
	return NULL;
    }

badarch:
    fclose(arch);
    Hash_DeleteTable(&ar->members);
    free(ar->fnametab);
    free(ar);
    return NULL;
}