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

📄 extract.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 2 页
字号:
			if (data == NULL) {	/* Check it... */				msg("Unexpected EOF on archive file");				break;			}			/*			 * JK - If the file is sparse, use the sparsearray			 * that we created before to lseek into the new			 * file the proper amount, and to see how many			 * bytes we want to write at that position.			 *//*			if (head->header.linkflag == LF_SPARSE) {				off_t pos;								pos = lseek(fd, (off_t) sparsearray[sparse_ind].offset, 0);				printf("%d at %d\n", (int) pos, sparse_ind);				written = sparsearray[sparse_ind++].numbytes;			} else*/			written = endofrecs()->charptr - data;			if (written > size)				written = size;			errno = 0;			check = write(fd, data, written);			/*			 * The following is in violation of strict			 * typing, since the arg to userec			 * should be a struct rec *.  FIXME.			 */			userec((union record *)(data + written - 1));			if (check == written) continue;			/*			 * Error in writing to file.			 * Print it, skip to next file in archive.			 */			if(check<0)				msg_perror("couldn't write to file %s",skipcrud+head->header.name);			else				msg("could only write %d of %d bytes to file %s",written,check,skipcrud+head->header.name);			skip_file((long)(size - written));			break;	/* Still do the close, mod time, chmod, etc */		}		if(f_multivol)			save_name = 0;			/* If writing to stdout, don't try to do anything			   to the filename; it doesn't exist, or we don't			   want to touch it anyway */		if(f_exstdout)			break;			/*		if (head->header.isextended) {			register union record *exhdr;			register int i;						for (i = 0; i < 21; i++) {				long offset;								if (!exhdr->ext_hdr.sp[i].numbytes)					break;				offset = from_oct(1+12, 						exhdr->ext_hdr.sp[i].offset);				written = from_oct(1+12, 						exhdr->ext_hdr.sp[i].numbytes);				lseek(fd, offset, 0);				check = write(fd, data, written);				if (check == written) continue;			}					}*/ 		check = close(fd);		if (check < 0) {			msg_perror("Error while closing %s",skipcrud+head->header.name);		}			set_filestat:		/*		 * If we are root, set the owner and group of the extracted		 * file.  This does what is wanted both on real Unix and on		 * System V.  If we are running as a user, we extract as that		 * user; if running as root, we extract as the original owner.		 */		if (we_are_root) {			if (chown(skipcrud+head->header.name, hstat.st_uid,				  hstat.st_gid) < 0) {				msg_perror("cannot chown file %s to uid %d gid %d",skipcrud+head->header.name,hstat.st_uid,hstat.st_gid);			}		}		/*		 * If '-k' is not set, open() or creat() could have saved		 * the permission bits from a previously created file,		 * ignoring the ones we specified.		 * Even if -k is set, if the file has abnormal		 * mode bits, we must chmod since writing or chown() has		 * probably reset them.		 *		 * If -k is set, we know *we* created this file, so the mode		 * bits were set by our open().   If the file is "normal", we		 * skip the chmod.  This works because we did umask(0) if -p		 * is set, so umask will have left the specified mode alone.		 */		if ((!f_keep)		    || (hstat.st_mode & (S_ISUID|S_ISGID|S_ISVTX))) {			if (chmod(skipcrud+head->header.name,				  notumask & (int)hstat.st_mode) < 0) {				msg_perror("cannot change mode of file %s to %ld",skipcrud+head->header.name,notumask & (int)hstat.st_mode);			}		}		/*		 * Set the modified time of the file.		 * 		 * Note that we set the accessed time to "now", which		 * is really "the time we started extracting files".		 * unless f_gnudump is used, in which case .st_atime is used		 */		if (!f_modified) {			/* fixme if f_gnudump should set ctime too, but how? */			if(f_gnudump)				acc_upd_times[0]=hstat.st_atime;			else acc_upd_times[0] = now;	         /* Accessed now */			acc_upd_times[1] = hstat.st_mtime; /* Mod'd */			if (utime(skipcrud+head->header.name,			    acc_upd_times) < 0) {				msg_perror("couldn't change access and modification times of %s",skipcrud+head->header.name);			}		}	quit:		break;	case LF_LINK:	again_link:		check = link (head->header.linkname,			      skipcrud+head->header.name);		if (check == 0)			break;		if (make_dirs(skipcrud+head->header.name))			goto again_link;		if(f_gnudump && errno==EEXIST)			break;		msg_perror("Could not link %s to %s",			skipcrud+head->header.name,head->header.linkname);		break;#ifdef S_IFLNK	case LF_SYMLINK:	again_symlink:		check = symlink(head->header.linkname,			        skipcrud+head->header.name);		/* FIXME, don't worry uid, gid, etc... */		if (check == 0)			break;		if (make_dirs(skipcrud+head->header.name))			goto again_symlink;		msg_perror("Could not create symlink to %s",head->header.linkname);		break;#endif#ifdef S_IFCHR	case LF_CHR:		hstat.st_mode |= S_IFCHR;		goto make_node;#endif#ifdef S_IFBLK	case LF_BLK:		hstat.st_mode |= S_IFBLK;		goto make_node;#endif#ifdef S_IFIFO	/* If local system doesn't support FIFOs, use default case */	case LF_FIFO:		hstat.st_mode |= S_IFIFO;		hstat.st_rdev = 0;		/* FIXME, do we need this? */		goto make_node;#endif	make_node:		check = mknod(skipcrud+head->header.name,			      (int) hstat.st_mode, (int) hstat.st_rdev);		if (check != 0) {			if (make_dirs(skipcrud+head->header.name))				goto make_node;			msg_perror("Could not make %s",skipcrud+head->header.name);			break;		};		goto set_filestat;	case LF_DIR:	case LF_DUMPDIR:		namelen = strlen(skipcrud+head->header.name)-1;	really_dir:		/* Check for trailing /, and zap as many as we find. */		while (namelen && head->header.name[skipcrud+namelen] == '/')			head->header.name[skipcrud+namelen--] = '\0';		if(f_gnudump) {		/* Read the entry and delete files					   that aren't listed in the archive */			gnu_restore(skipcrud);				} else if(head->header.linkflag==LF_DUMPDIR)			skip_file((long)(hstat.st_size));		again_dir:		check = mkdir(skipcrud+head->header.name,			      0300 | (int)hstat.st_mode);		if (check != 0) {			if (make_dirs(skipcrud+head->header.name))				goto again_dir;			/* If we're trying to create '.', let it be. */			if (head->header.name[skipcrud+namelen] == '.' && 			    (namelen==0 ||			     head->header.name[skipcrud+namelen-1]=='/'))				goto check_perms;			if(f_gnudump && errno==EEXIST)				break;			msg_perror("Could not make directory %s",skipcrud+head->header.name);			break;		}			check_perms:		if (0300 != (0300 & (int) hstat.st_mode)) {			hstat.st_mode |= 0300;			msg("Added write and execute permission to directory %s",			  skipcrud+head->header.name);		}		goto set_filestat;		/* FIXME, Remember timestamps for after files created? */		/* FIXME, change mode after files created (if was R/O dir) */	case LF_VOLHDR:		if(f_verbose) {			printf("Reading %s\n",head->header.name);		}		break;	case LF_MULTIVOL:		msg("Can't extract '%s'--file is continued from another volume\n",head->header.name);		skip_file((long)hstat.st_size);		break;	}	/* We don't need to save it any longer. */	saverec((union record **) 0);	/* Unsave it */}/* * After a file/link/symlink/dir creation has failed, see if * it's because some required directory was not present, and if * so, create all required dirs. */intmake_dirs(pathname)	char *pathname;{	char *p;			/* Points into path */	int madeone = 0;		/* Did we do anything yet? */	int save_errno = errno;		/* Remember caller's errno */	int check;	if (errno != ENOENT)		return 0;		/* Not our problem */	for (p = index(pathname, '/'); p != NULL; p = index(p+1, '/')) {		/* Avoid mkdir of empty string, if leading or double '/' */		if (p == pathname || p[-1] == '/')			continue;		/* Avoid mkdir where last part of path is '.' */		if (p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))			continue;		*p = 0;				/* Truncate the path there */		check = mkdir (pathname, 0777);	/* Try to create it as a dir */		if (check == 0) {			/* Fix ownership */			if (we_are_root) {				if (chown(pathname, hstat.st_uid,					  hstat.st_gid) < 0) {					msg_perror("cannot change owner of %s to uid %d gid %d",pathname,hstat.st_uid,hstat.st_gid);				}			}			pr_mkdir(pathname, p-pathname, notumask&0777);			madeone++;		/* Remember if we made one */			*p = '/';			continue;		}		*p = '/';		if (errno == EEXIST)		/* Directory already exists */			continue;		/*		 * Some other error in the mkdir.  We return to the caller.		 */		break;	}	errno = save_errno;		/* Restore caller's errno */	return madeone;			/* Tell them to retry if we made one */}extract_sparse_file(fd, sizeleft, totalsize, name)	int	fd;	long	*sizeleft,		totalsize;	char	*name;{			register char	*data;	union record	*datarec;	int	sparse_ind = 0;	int	written,		count;		/* assuming sizeleft is initially totalsize */	while (*sizeleft > 0) {		datarec = findrec();		if (datarec == NULL) {			msg("Unexpected EOF on archive file");			return;		}		lseek(fd, sparsearray[sparse_ind].offset, 0);		written = sparsearray[sparse_ind++].numbytes;		while (written > RECORDSIZE) {			count = write(fd, datarec->charptr, RECORDSIZE);			if (count < 0) 				msg_perror("couldn't write to file %s", name);			written -= count;			*sizeleft -= count;			userec(datarec);			datarec = findrec();		}		count = write(fd, datarec->charptr, written);	        		if (count < 0) {			msg_perror("couldn't write to file %s", name);		} else if (count != written) {			msg("could only write %d of %d bytes to file %s", totalsize - *sizeleft, totalsize, name);			skip_file((long) (*sizeleft));		}		written -= count;		*sizeleft -= count;				userec(datarec);	}	free(sparsearray);/*	if (end_nulls) {		register int i;		printf("%d\n", (int) end_nulls);		for (i = 0; i < end_nulls; i++)			write(fd, "\000", 1);	}*/	userec(datarec);}

⌨️ 快捷键说明

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