⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ar_subs.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		    	if (res == 0) {				if (uflag && Dflag) {					if ((arcn->sb.st_mtime<=sb.st_mtime) &&			    		    (arcn->sb.st_ctime<=sb.st_ctime))						continue;				} else if (Dflag) {					if (arcn->sb.st_ctime <= sb.st_ctime)						continue;				} else if (arcn->sb.st_mtime <= sb.st_mtime)					continue;			}		}		/*		 * this file is considered selected. See if this is a hard link		 * to a previous file; modify the name as requested by the		 * user; set the final destination.		 */		ftree_sel(arcn);		if ((chk_lnk(arcn) < 0) || ((res = mod_name(arcn)) < 0))			break;		if ((res > 0) || (set_dest(arcn, dirbuf, dlen) < 0)) {			/*			 * skip file, purge from link table			 */			purg_lnk(arcn);			continue;		}		/*		 * Non standard -Y and -Z flag. When the exisiting file is		 * same age or newer skip		 */		if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) {			if (Yflag && Zflag) {				if ((arcn->sb.st_mtime <= sb.st_mtime) &&				    (arcn->sb.st_ctime <= sb.st_ctime))					continue;			} else if (Yflag) {				if (arcn->sb.st_ctime <= sb.st_ctime)					continue;			} else if (arcn->sb.st_mtime <= sb.st_mtime)				continue;		}		if (vflag) {			(void)fputs(arcn->name, stderr);			vfpart = 1;		}		++flcnt;		/*		 * try to create a hard link to the src file if requested		 * but make sure we are not trying to overwrite ourselves.		 */		if (lflag) 			res = cross_lnk(arcn);		else			res = chk_same(arcn);		if (res <= 0) {			if (vflag && vfpart) {				(void)putc('\n', stderr);				vfpart = 0;			}			continue;		}		/*		 * have to create a new file		 */		if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG)) {			/*			 * create a link or special file			 */			if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG))				res = lnk_creat(arcn);			else				res = node_creat(arcn);			if (res < 0)				purg_lnk(arcn);			if (vflag && vfpart) {				(void)putc('\n', stderr);				vfpart = 0;			}			continue;		}		/*		 * have to copy a regular file to the destination directory.		 * first open source file and then create the destination file		 */		if ((fdsrc = open(arcn->org_name, O_RDONLY, 0)) < 0) {			syswarn(1, errno, "Unable to open %s to read",			    arcn->org_name);			purg_lnk(arcn);			continue;		}		if ((fddest = file_creat(arcn)) < 0) {			rdfile_close(arcn, &fdsrc);			purg_lnk(arcn);			continue;		}		/*		 * copy source file data to the destination file		 */		cp_file(arcn, fdsrc, fddest);		file_close(arcn, fddest);		rdfile_close(arcn, &fdsrc);		if (vflag && vfpart) {			(void)putc('\n', stderr);			vfpart = 0;		}	}	/*	 * restore directory modes and times as required; make sure all	 * patterns were selected block off signals to avoid chance for	 * multiple entry into the cleanup code.	 */	(void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL);	ar_close();	proc_dir();	ftree_chk();}/* * next_head() *	try to find a valid header in the archive. Uses format specific *	routines to extract the header and id the trailer. Trailers may be *	located within a valid header or in an invalid header (the location *	is format specific. The inhead field from the option table tells us *	where to look for the trailer). *	We keep reading (and resyncing) until we get enough contiguous data *	to check for a header. If we cannot find one, we shift by a byte *	add a new byte from the archive to the end of the buffer and try again. *	If we get a read error, we throw out what we have (as we must have *	contiguous data) and start over again. *	ASSUMED: headers fit within a BLKMULT header. * Return: *	0 if we got a header, -1 if we are unable to ever find another one *	(we reached the end of input, or we reached the limit on retries. see *	the specs for rd_wrbuf() for more details) */#if __STDC__static intnext_head(register ARCHD *arcn)#elsestatic intnext_head(arcn)	register ARCHD *arcn;#endif{	register int ret;	register char *hdend;	register int res;	register int shftsz;	register int hsz;	register int in_resync = 0; 	/* set when we are in resync mode */	int cnt = 0;			/* counter for trailer function */		/*	 * set up initial conditions, we want a whole frmt->hsz block as we	 * have no data yet.	 */	res = hsz = frmt->hsz;	hdend = hdbuf;	shftsz = hsz - 1;	for(;;) {		/*		 * keep looping until we get a contiguous FULL buffer		 * (frmt->hsz is the proper size)		 */		for (;;) {			if ((ret = rd_wrbuf(hdend, res)) == res)				break;			/*			 * some kind of archive read problem, try to resync the			 * storage device, better give the user the bad news.			 */			if ((ret == 0) || (rd_sync() < 0)) {				warn(1,"Premature end of file on archive read");				return(-1);			}			if (!in_resync) {				if (act == APPND) {					warn(1,				          "Archive I/O error, cannot continue");					return(-1);				}				warn(1,"Archive I/O error. Trying to recover.");				++in_resync;			}			/*			 * oh well, throw it all out and start over			 */			res = hsz;			hdend = hdbuf;		}		/*		 * ok we have a contiguous buffer of the right size. Call the		 * format read routine. If this was not a valid header and this		 * format stores trailers outside of the header, call the		 * format specific trailer routine to check for a trailer. We		 * have to watch out that we do not mis-identify file data or		 * block padding as a header or trailer. Format specific		 * trailer functions must NOT check for the trailer while we		 * are running in resync mode. Some trailer functions may tell		 * us that this block cannot contain a valid header either, so		 * we then throw out the entire block and start over.		 */		if ((*frmt->rd)(arcn, hdbuf) == 0)			break;		if (!frmt->inhead) {			/*			 * this format has trailers outside of valid headers			 */			if ((ret = (*frmt->trail)(hdbuf,in_resync,&cnt)) == 0){				/*				 * valid trailer found, drain input as required				 */				ar_drain();				return(-1);			}			if (ret == 1) {				/*				 * we are in resync and we were told to throw				 * the whole block out because none of the				 * bytes in this block can be used to form a				 * valid header				 */				res = hsz;				hdend = hdbuf;				continue;			}		}		/*		 * Brute force section.		 * not a valid header. We may be able to find a header yet. So		 * we shift over by one byte, and set up to read one byte at a		 * time from the archive and place it at the end of the buffer.		 * We will keep moving byte at a time until we find a header or		 * get a read error and have to start over.		 */		if (!in_resync) {			if (act == APPND) {				warn(1,"Unable to append, archive header flaw");				return(-1);			}			warn(1,"Invalid header, starting valid header search.");			++in_resync;		}		bcopy(hdbuf+1, hdbuf, shftsz);		res = 1;		hdend = hdbuf + shftsz;	}	/*	 * ok got a valid header, check for trailer if format encodes it in the	 * the header. NOTE: the parameters are different than trailer routines	 * which encode trailers outside of the header!	 */	if (frmt->inhead && ((*frmt->trail)(arcn) == 0)) {		/*		 * valid trailer found, drain input as required		 */		ar_drain();		return(-1);	}	++flcnt;	return(0);}/* * get_arc() *	Figure out what format an archive is. Handles archive with flaws by *	brute force searches for a legal header in any supported format. The *	format id routines have to be careful to NOT mis-identify a format. *	ASSUMED: headers fit within a BLKMULT header. * Return: *	0 if archive found -1 otherwise */#if __STDC__static intget_arc(void)#elsestatic intget_arc()#endif{	register int i;	register int hdsz = 0;	register int res;	register int minhd = BLKMULT;	char *hdend;	int notice = 0;		/*	 * find the smallest header size in all archive formats and then set up	 * to read the archive.	 */	for (i = 0; ford[i] >= 0; ++i) {		if (fsub[ford[i]].hsz < minhd)			minhd = fsub[ford[i]].hsz;	}	if (rd_start() < 0)		return(-1);	res = BLKMULT;	hdsz = 0;	hdend = hdbuf;	for(;;) {		for (;;) {			/*			 * fill the buffer with at least the smallest header			 */			i = rd_wrbuf(hdend, res);			if (i > 0)				hdsz += i;			if (hdsz >= minhd)				break;			/*			 * if we cannot recover from a read error quit			 */			if ((i == 0) || (rd_sync() < 0))				goto out;			/*			 * when we get an error none of the data we already			 * have can be used to create a legal header (we just			 * got an error in the middle), so we throw it all out			 * and refill the buffer with fresh data.			 */			res = BLKMULT;			hdsz = 0;			hdend = hdbuf;			if (!notice) {				if (act == APPND)					return(-1);				warn(1,"Cannot identify format. Searching...");				++notice;			}		}		/*		 * we have at least the size of the smallest header in any		 * archive format. Look to see if we have a match. The array		 * ford[] is used to specify the header id order to reduce the		 * chance of incorrectly id'ing a valid header (some formats		 * may be subsets of each other and the order would then be		 * important).		 */		for (i = 0; ford[i] >= 0; ++i) {			if ((*fsub[ford[i]].id)(hdbuf, hdsz) < 0)				continue;			frmt = &(fsub[ford[i]]);			/* 			 * yuck, to avoid slow special case code in the extract			 * routines, just push this header back as if it was			 * not seen. We have left extra space at start of the			 * buffer for this purpose. This is a bit ugly, but			 * adding all the special case code is far worse.			 */			pback(hdbuf, hdsz);			return(0);		}		/*		 * We have a flawed archive, no match. we start searching, but		 * we never allow additions to flawed archives		 */		if (!notice) {			if (act == APPND)				return(-1);			warn(1, "Cannot identify format. Searching...");			++notice;		}		/*		 * brute force search for a header that we can id.		 * we shift through byte at a time. this is slow, but we cannot		 * determine the nature of the flaw in the archive in a		 * portable manner		 */		if (--hdsz > 0) {			bcopy(hdbuf+1, hdbuf, hdsz);			res = BLKMULT - hdsz;			hdend = hdbuf + hdsz;		} else {			res = BLKMULT;			hdend = hdbuf;			hdsz = 0;		}	}    out:	/*	 * we cannot find a header, bow, apologize and quit	 */	warn(1, "Sorry, unable to determine archive format.");	return(-1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -