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

📄 tar.c

📁 手机嵌入式Linux下可用的busybox源码
💻 C
📖 第 1 页 / 共 3 页
字号:
				return( FALSE);			}		} else {			actualWriteSz=writeSize;		}		size -= actualWriteSz;	}	/* Now we are done writing the file out, so try 	 * and fix up the permissions and whatnot */	if (extractFlag==TRUE && tostdoutFlag==FALSE) {		close(outFd);		fixUpPermissions(header);	}	return( TRUE);}static inttarExtractDirectory(TarInfo *header, int extractFlag, int tostdoutFlag){	if (extractFlag==FALSE || tostdoutFlag==TRUE)		return( TRUE);	if (make_directory(header->name, header->mode, FILEUTILS_RECUR) < 0)		return( FALSE);	fixUpPermissions(header);	return( TRUE);}static inttarExtractHardLink(TarInfo *header, int extractFlag, int tostdoutFlag){	if (extractFlag==FALSE || tostdoutFlag==TRUE)		return( TRUE);	if (link(header->linkname, header->name) < 0) {		perror_msg("%s: Cannot create hard link to '%s'", header->name,				header->linkname); 		return( FALSE);	}	/* Now set permissions etc. for the new directory */	fixUpPermissions(header);	return( TRUE);}static inttarExtractSymLink(TarInfo *header, int extractFlag, int tostdoutFlag){	if (extractFlag==FALSE || tostdoutFlag==TRUE)		return( TRUE);#ifdef	S_ISLNK	if (symlink(header->linkname, header->name) < 0) {		perror_msg("%s: Cannot create symlink to '%s'", header->name,				header->linkname); 		return( FALSE);	}	/* Try to change ownership of the symlink.	 * If libs doesn't support that, don't bother.	 * Changing the pointed-to-file is the Wrong Thing(tm).	 */#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)	lchown(header->name, header->uid, header->gid);#endif	/* Do not change permissions or date on symlink,	 * since it changes the pointed to file instead.  duh. */#else	error_msg("%s: Cannot create symlink to '%s': %s", 			header->name, header->linkname, 			"symlinks not supported"); #endif	return( TRUE);}static inttarExtractSpecial(TarInfo *header, int extractFlag, int tostdoutFlag){	if (extractFlag==FALSE || tostdoutFlag==TRUE)		return( TRUE);	if (S_ISCHR(header->mode) || S_ISBLK(header->mode) || S_ISSOCK(header->mode)) {		if (mknod(header->name, header->mode, makedev(header->devmajor, header->devminor)) < 0) {			perror_msg("%s: Cannot mknod", header->name); 			return( FALSE);		}	} else if (S_ISFIFO(header->mode)) {		if (mkfifo(header->name, header->mode) < 0) {			perror_msg("%s: Cannot mkfifo", header->name); 			return( FALSE);		}	}	/* Now set permissions etc. for the new directory */	fixUpPermissions(header);	return( TRUE);}/* Parse the tar header and fill in the nice struct with the details */static intreadTarHeader(struct TarHeader *rawHeader, struct TarInfo *header){	int i;	long chksum, sum=0;	unsigned char *s = (unsigned char *)rawHeader;	header->name  = rawHeader->name;	/* Check for and relativify any absolute paths */	if ( *(header->name) == '/' ) {		static int alreadyWarned=FALSE;		while (*(header->name) == '/')			header->name++;		if (alreadyWarned == FALSE) {			error_msg("Removing leading '/' from member names");			alreadyWarned = TRUE;		}	}	header->mode  = strtol(rawHeader->mode, NULL, 8);	header->uid   = strtol(rawHeader->uid, NULL, 8);	header->gid   = strtol(rawHeader->gid, NULL, 8);	header->size  = strtol(rawHeader->size, NULL, 8);	header->mtime = strtol(rawHeader->mtime, NULL, 8);	chksum = strtol(rawHeader->chksum, NULL, 8);	header->type  = rawHeader->typeflag;	header->linkname  = rawHeader->linkname;	header->devmajor  = strtol(rawHeader->devmajor, NULL, 8);	header->devminor  = strtol(rawHeader->devminor, NULL, 8);	/* Check the checksum */	for (i = sizeof(*rawHeader); i-- != 0;) {		sum += *s++;	}	/* Remove the effects of the checksum field (replace 	 * with blanks for the purposes of the checksum) */	s = rawHeader->chksum;	for (i = sizeof(rawHeader->chksum) ; i-- != 0;) {		sum -= *s++;	}	sum += ' ' * sizeof(rawHeader->chksum);	if (sum == chksum )		return ( TRUE);	return( FALSE);}#if defined BB_FEATURE_TAR_EXCLUDEstatic int exclude_file(char **excluded_files, const char *file){	int i;	if (excluded_files == NULL)		return 0;	for (i = 0; excluded_files[i] != NULL; i++) {		if (excluded_files[i][0] == '/') {			if (fnmatch(excluded_files[i], file,						FNM_PATHNAME | FNM_LEADING_DIR) == 0)				return 1;		} else {			const char *p;			for (p = file; p[0] != '\0'; p++) {				if ((p == file || p[-1] == '/') && p[0] != '/' &&						fnmatch(excluded_files[i], p,							FNM_PATHNAME | FNM_LEADING_DIR) == 0)					return 1;			}		}	}	return 0;}#endifstatic int extract_file(char **extract_files, const char *file){	int i;	if (extract_files == NULL)		return 1;	for (i = 0; extract_files[i] != NULL; i++) {		if (fnmatch(extract_files[i], file, FNM_LEADING_DIR) == 0)			return 1;	}	return 0;}/* * Read a tar file and extract or list the specified files within it. * If the list is empty than all files are extracted or listed. */static int readTarFile(int tarFd, int extractFlag, int listFlag, 		int tostdoutFlag, int verboseFlag, char** extractList,		char** excludeList){	int status;	int errorFlag=FALSE;	int skipNextHeaderFlag=FALSE;	TarHeader rawHeader;	TarInfo header;	/* Read the tar file, and iterate over it one file at a time */	while ( (status = full_read(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) {		/* Try to read the header */		if ( readTarHeader(&rawHeader, &header) == FALSE ) {			if ( *(header.name) == '\0' ) {				goto endgame;			} else {				errorFlag=TRUE;				error_msg("Bad tar header, skipping");				continue;			}		}		if ( *(header.name) == '\0' )			continue;		header.tarFd = tarFd;		/* Skip funky extra GNU headers that precede long files */		if ( (header.type == GNULONGNAME) || (header.type == GNULONGLINK) ) {			skipNextHeaderFlag=TRUE;			if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)				errorFlag = TRUE;			continue;		}		if ( skipNextHeaderFlag == TRUE ) { 			skipNextHeaderFlag=FALSE;			error_msg(name_longer_than_foo, NAME_SIZE); 			if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)				errorFlag = TRUE;			continue;		}#if defined BB_FEATURE_TAR_EXCLUDE		if (exclude_file(excludeList, header.name)) {			/* There are not the droids you're looking for, move along */			/* If it is a regular file, pretend to extract it with			 * the extractFlag set to FALSE, so the junk in the tarball			 * is properly skipped over */			if ( header.type==REGTYPE || header.type==REGTYPE0 ) {				if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)					errorFlag = TRUE;			}			continue;		}#endif		if (!extract_file(extractList, header.name)) {			/* There are not the droids you're looking for, move along */			/* If it is a regular file, pretend to extract it with			 * the extractFlag set to FALSE, so the junk in the tarball			 * is properly skipped over */			if ( header.type==REGTYPE || header.type==REGTYPE0 ) {				if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)					errorFlag = TRUE;			}			continue;		}		if (listFlag == TRUE) {			/* Special treatment if the list (-t) flag is on */			if (verboseFlag == TRUE) {				int len, len1;				char buf[35];				struct tm *tm = localtime (&(header.mtime));				len=printf("%s ", mode_string(header.mode));				my_getpwuid(buf, header.uid);				if (! *buf)					len+=printf("%d", header.uid);				else					len+=printf("%s", buf);				my_getgrgid(buf, header.gid);				if (! *buf)					len+=printf("/%-d ", header.gid);				else					len+=printf("/%-s ", buf);				if (header.type==CHRTYPE || header.type==BLKTYPE) {					len1=snprintf(buf, sizeof(buf), "%ld,%-ld ", 							header.devmajor, header.devminor);				} else {					len1=snprintf(buf, sizeof(buf), "%lu ", (long)header.size);				}				/* Jump through some hoops to make the columns match up */				for(;(len+len1)<31;len++)					printf(" ");				printf(buf);				/* Use ISO 8610 time format */				if (tm) { 					printf ("%04d-%02d-%02d %02d:%02d:%02d ", 							tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 							tm->tm_hour, tm->tm_min, tm->tm_sec);				}			}			printf("%s", header.name);			if (verboseFlag == TRUE) {				if (header.type==LNKTYPE)	/* If this is a link, say so */					printf(" link to %s", header.linkname);				else if (header.type==SYMTYPE)					printf(" -> %s", header.linkname);			}			printf("\n");		}		/* List contents if we are supposed to do that */		if (verboseFlag == TRUE && extractFlag == TRUE) {			/* Now the normal listing */			FILE *vbFd = stdout;			if (tostdoutFlag == TRUE)	// If the archive goes to stdout, verbose to stderr				vbFd = stderr;			fprintf(vbFd, "%s\n", header.name);		}					/* Remove files if we would overwrite them */		if (extractFlag == TRUE && tostdoutFlag == FALSE)			unlink(header.name);		/* If we got here, we can be certain we have a legitimate 		 * header to work with.  So work with it.  */		switch ( header.type ) {			case REGTYPE:			case REGTYPE0:				/* If the name ends in a '/' then assume it is				 * supposed to be a directory, and fall through */				if (!last_char_is(header.name,'/')) {					if (tarExtractRegularFile(&header, extractFlag, tostdoutFlag)==FALSE)						errorFlag=TRUE;					break;				}			case DIRTYPE:				if (tarExtractDirectory( &header, extractFlag, tostdoutFlag)==FALSE)					errorFlag=TRUE;				break;			case LNKTYPE:				if (tarExtractHardLink( &header, extractFlag, tostdoutFlag)==FALSE)					errorFlag=TRUE;				break;			case SYMTYPE:				if (tarExtractSymLink( &header, extractFlag, tostdoutFlag)==FALSE)					errorFlag=TRUE;				break;			case CHRTYPE:			case BLKTYPE:			case FIFOTYPE:				if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE)					errorFlag=TRUE;				break;#if 0			/* Handled earlier */			case GNULONGNAME:			case GNULONGLINK:				skipNextHeaderFlag=TRUE;				break;#endif			default:				error_msg("Unknown file type '%c' in tar file", header.type);				close( tarFd);				return( FALSE);		}	}	close(tarFd);	if (status > 0) {		/* Bummer - we read a partial header */		perror_msg("Error reading tar file");		return ( FALSE);	}	else if (errorFlag==TRUE) {		error_msg( "Error exit delayed from previous errors");		return( FALSE);	} else 		return( status);	/* Stuff to do when we are done */endgame:	close( tarFd);	if ( *(header.name) == '\0' ) {

⌨️ 快捷键说明

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