예제 #1
0
void dumpall(struct filenode *node, int lastoff, FILE *f)
{
	struct romfh ri;
	struct filenode *p;

	ri.nextfh = htonl(0x2d726f6d);
	ri.spec = htonl(0x3166732d);
	ri.size = htonl(lastoff);
	ri.checksum = htonl(0x55555555);
	dumpri(&ri, node, f);
	p = node->dirlist.head;
	while (p->next) {
		dumpnode(p, f);
		p = p->next;
	}
	/* Align the whole bunch to ROMBSIZE boundary */
	if (lastoff&1023)
		dumpzero(1024-(lastoff&1023), f);
}
예제 #2
0
int dumpnode(struct filenode *node, FILE *f) {
    struct romfh ri;
    struct filenode *p;

    ri.nextfh = 0;
    ri.spec = 0;
    ri.size = htonl(node->size);
    ri.checksum = htonl(0x55555555);

    if(node->pad)
        dumpzero(node->pad, f);

    if(node->next && node->next->next)
        ri.nextfh = htonl(node->next->offset);

    if((node->modes & 0111) &&
            (S_ISDIR(node->modes) || S_ISREG(node->modes)))
        ri.nextfh |= htonl(ROMFH_EXEC);

    if(node->orig_link) {
        ri.nextfh |= htonl(ROMFH_HRD);
        /* Don't allow hardlinks to convey attributes */
        ri.nextfh &= ~htonl(ROMFH_EXEC);
        ri.spec = htonl(node->orig_link->offset);
        dumpri(&ri, node, f);
    }
    else if(S_ISDIR(node->modes)) {
        ri.nextfh |= htonl(ROMFH_DIR);

        if(listisempty(&node->dirlist)) {
            ri.spec = htonl(node->offset);
        }
        else {
            ri.spec = htonl(node->dirlist.head->offset);
        }

        dumpri(&ri, node, f);
    }
    else if(S_ISLNK(node->modes)) {
        ri.nextfh |= htonl(ROMFH_LNK);
        dumpri(&ri, node, f);
        memset(bigbuf, 0, sizeof(bigbuf));
        if(readlink(node->realname, bigbuf, node->size) < 0) {
            return 1;
        }
        dumpdataa(bigbuf, node->size, f);
    }
    else if(S_ISREG(node->modes)) {
        int offset, len, fd, max, avail;
        ri.nextfh |= htonl(ROMFH_REG);
        dumpri(&ri, node, f);
        offset = 0;
        max = node->size;
        /* XXX warn about size mismatch */
        fd = open(node->realname, O_RDONLY
#ifdef O_BINARY
                  | O_BINARY
#endif
                 );

        if(fd) {
            while(offset < max) {
                avail = max - offset < sizeof(bigbuf) ? max - offset : sizeof(bigbuf);
                len = read(fd, bigbuf, avail);

                if(len <= 0)
                    break;

                dumpdata(bigbuf, len, f);
                offset += len;
            }

            close(fd);
        }

        max = (max + 15)&~15;

        while(offset < max) {
            avail = max - offset < sizeof(bigbuf) ? max - offset : sizeof(bigbuf);
            memset(bigbuf, 0, avail);
            dumpdata(bigbuf, avail, f);
            offset += avail;
        }
    }
    else if(S_ISCHR(node->modes)) {
        ri.nextfh |= htonl(ROMFH_CHR);
        ri.spec = htonl(major(node->devnode) << 16 | minor(node->devnode));
        dumpri(&ri, node, f);
    }
    else if(S_ISBLK(node->modes)) {
        ri.nextfh |= htonl(ROMFH_BLK);
        ri.spec = htonl(major(node->devnode) << 16 | minor(node->devnode));
        dumpri(&ri, node, f);
    }
    else if(S_ISFIFO(node->modes)) {
        ri.nextfh |= htonl(ROMFH_FIF);
        dumpri(&ri, node, f);
    }
    else if(S_ISSOCK(node->modes)) {
        ri.nextfh |= htonl(ROMFH_SCK);
        dumpri(&ri, node, f);
    }

    p = node->dirlist.head;

    while(p->next) {
        if(dumpnode(p, f)) {
            return 1;
        }
        p = p->next;
    }

    return 0;
}