Пример #1
0
void
populate(char *name)
{
	long blkno, isabs, chksum, linkflg;
	Fileinf f;

	tapefile = open(name, OREAD);
	if (tapefile<0)
		error("Can't open argument file");
	replete = 1;
	for (blkno = 0;;) {
		seek(tapefile, TBLOCK*blkno, 0);
		if (read(tapefile, dblock.dummy, sizeof(dblock.dummy))<sizeof(dblock.dummy))
			break;
		if (dblock.dbuf.name[0]=='\0')
			break;
		f.addr = blkno+1;
		f.mode = strtoul(dblock.dbuf.mode, 0, 8);
		f.uid = strtoul(dblock.dbuf.uid, 0, 8);
		f.gid = strtoul(dblock.dbuf.gid, 0, 8);
		if((uchar)dblock.dbuf.size[0] == 0x80)
			f.size = b8byte(dblock.dbuf.size+3);
		else
			f.size = strtoull(dblock.dbuf.size, 0, 8);
		f.mdate = strtoul(dblock.dbuf.mtime, 0, 8);
		chksum = strtoul(dblock.dbuf.chksum, 0, 8);
		/* the mode test is ugly but sometimes necessary */
		if (dblock.dbuf.linkflag == '5'
		|| (f.mode&0170000) == 040000
		||  strrchr(dblock.dbuf.name, '\0')[-1] == '/'){
			f.mode |= DMDIR;
			f.size = 0;
		}
		f.mode &= DMDIR|0777;
		linkflg = dblock.dbuf.linkflag=='s' || dblock.dbuf.linkflag=='1';
		isabs = dblock.dbuf.name[0]=='/';
		if (chksum != checksum()){
			fprint(1, "bad checksum on %.28s\n", dblock.dbuf.name);
			exits("checksum");
		}
		if (linkflg) {
			/*fprint(2, "link %s->%s skipped\n", dblock.dbuf.name,
			   dblock.dbuf.linkname);*/
			f.size = 0;
			blkno += 1;
			continue;
		}
		f.name = dblock.dbuf.name+isabs;
		if (f.name[0]=='\0')
			fprint(1, "null name skipped\n");
		else
			poppath(f, 1);
		blkno += 1 + (f.size+TBLOCK-1)/TBLOCK;
	}
}
Пример #2
0
void
populate(char *name)
{
	int32_t chksum, linkflg;
	int64_t blkno;
	char *fname;
	Fileinf f;
	Hdr *hp;

	tapefile = open(name, OREAD);
	if (tapefile < 0)
		error("Can't open argument file");
	replete = 1;
	hp = &dblock;
	for (blkno = 0; ; blkno++) {
		seek(tapefile, Tblock*blkno, 0);
		if (readn(tapefile, hp->dummy, sizeof hp->dummy) < sizeof hp->dummy)
			break;
		fname = tarname(hp);
		if (fname[0] == '\0')
			break;

		/* crack header */
		f.addr = blkno + 1;
		f.mode = strtoul(hp->mode, 0, 8);
		f.uid  = strtoul(hp->uid, 0, 8);
		f.gid  = strtoul(hp->gid, 0, 8);
		if((uint8_t)hp->size[0] == 0x80)
			f.size = b8byte(hp->size+3);
		else
			f.size = strtoull(hp->size, 0, 8);
		f.mdate = strtoul(hp->mtime, 0, 8);
		chksum  = strtoul(hp->chksum, 0, 8);
		/* the mode test is ugly but sometimes necessary */
		if (hp->linkflag == LF_DIR || (f.mode&0170000) == 040000 ||
		    strrchr(fname, '\0')[-1] == '/'){
			f.mode |= DMDIR;
			f.size = 0;
		}
		f.mode &= DMDIR | 0777;

		/* make file name safe, canonical and free of . and .. */
		while (fname[0] == '/')		/* don't allow absolute paths */
			++fname;
		cleanname(fname);
		while (strncmp(fname, "../", 3) == 0)
			fname += 3;

		/* reject links */
		linkflg = hp->linkflag == LF_SYMLINK1 ||
			hp->linkflag == LF_SYMLINK2 || hp->linkflag == LF_LINK;
		if (chksum != checksum()){
			fprint(2, "%s: bad checksum on %.28s at offset %lld\n",
				argv0, fname, Tblock*blkno);
			exits("checksum");
		}
		if (linkflg) {
			/*fprint(2, "link %s->%s skipped\n", fname, hp->linkname);*/
			f.size = 0;
		} else {
			/* accept this file */
			f.name = fname;
			if (f.name[0] == '\0')
				fprint(2, "%s: null name skipped\n", argv0);
			else
				poppath(f, 1);
			blkno += (f.size + Tblock - 1)/Tblock;
		}
	}
}