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

📄 extract.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Extract files from a tar archive.   Copyright (C) 1988 Free Software FoundationThis file is part of GNU Tar.GNU Tar is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GNU Tar is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Tar; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  *//* * Extract files from a tar archive. * * Written 19 Nov 1985 by John Gilmore, ihnp4!hoptoad!gnu. * * @(#) extract.c 1.32 87/11/11 - gnu */#include <stdio.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#ifdef BSD42#include <sys/file.h>#endif#ifdef USG#include <fcntl.h>#endif#ifdef	MSDOS#include <fcntl.h>#endif	/* MSDOS *//* * Some people don't have a #define for these. */#ifndef	O_BINARY#define	O_BINARY	0#endif#ifndef O_NDELAY#define	O_NDELAY	0#endif#ifdef NO_OPEN3/* We need the #define's even though we don't use them. */#include "open3.h"#endif#ifdef EMUL_OPEN3/* Simulated 3-argument open for systems that don't have it */#include "open3.h"#endifextern int errno;			/* From libc.a */extern time_t time();			/* From libc.a */extern char *index();			/* From libc.a or port.c */#include "tar.h"#include "port.h"extern FILE *msg_file;extern union record *head;		/* Points to current tape header */extern struct stat hstat;		/* Stat struct corresponding */extern int head_standard;		/* Tape header is in ANSI format */extern char *save_name;extern long save_totsize;extern long save_sizeleft;extern void print_header();extern void skip_file();extern void skip_extended_headers();extern void pr_mkdir();int make_dirs();			/* Makes required directories */static time_t now = 0;			/* Current time */static we_are_root = 0;			/* True if our effective uid == 0 */static int notumask = ~0;		/* Masks out bits user doesn't want *//* * "Scratch" space to store the information about a sparse file before * writing the info into the header or extended header *//*struct sp_array	*sparsearray;*//* number of elts storable in the sparsearray *//*int	sp_array_size = 10;*//* * Set up to extract files. */extr_init(){	int ourmask;	now = time((time_t *)0);	if (f_do_chown || geteuid() == 0)		we_are_root = 1;	/*	 * We need to know our umask.  But if f_use_protection is set,	 * leave our kernel umask at 0, and our "notumask" at ~0.	 */	ourmask = umask(0);		/* Read it */	if (!f_use_protection) {		(void) umask (ourmask);	/* Set it back how it was */		notumask = ~ourmask;	/* Make umask override permissions */	}}/* * Extract a file from the archive. */voidextract_archive(){	register char *data;	int fd, check, namelen, written, openflag;	long size;	time_t acc_upd_times[2];	register int skipcrud;	register int i;	int sparse_ind = 0;	union record *exhdr;		int end_nulls;		saverec(&head);			/* Make sure it sticks around */	userec(head);			/* And go past it in the archive */	decode_header(head, &hstat, &head_standard, 1);	/* Snarf fields */	if(f_confirm && !confirm("extract",head->header.name)) {		if (head->header.isextended)			skip_extended_headers();		skip_file((long)hstat.st_size);		saverec((union record **)0);		return;	}	/* Print the record from 'head' and 'hstat' */	if (f_verbose)		print_header();	/*	 * Check for fully specified pathnames and other atrocities.	 *	 * Note, we can't just make a pointer to the new file name,	 * since saverec() might move the header and adjust "head".	 * We have to start from "head" every time we want to touch	 * the header record.	 */	skipcrud = 0;	while (!f_absolute_paths && '/' == head->header.name[skipcrud]) {		static int warned_once = 0;		skipcrud++;	/* Force relative path */		if (!warned_once++) {			msg("Removing leading / from absolute path names in the archive.");		}	}	switch (head->header.linkflag) {	default:		msg("Unknown file type '%c' for %s, extracted as normal file",			head->header.linkflag, skipcrud+head->header.name);		/* FALL THRU */	/* 	 * JK - What we want to do if the file is sparse is loop through	 * the array of sparse structures in the header and read in	 * and translate the character strings representing  1) the offset	 * at which to write and 2) how many bytes to write into numbers,	 * which we store into the scratch array, "sparsearray".  This	 * array makes our life easier the same way it did in creating	 * the tar file that had to deal with a sparse file.	 *	 * After we read in the first five (at most) sparse structures,	 * we check to see if the file has an extended header, i.e., 	 * if more sparse structures are needed to describe the contents	 * of the new file.  If so, we read in the extended headers	 * and continue to store their contents into the sparsearray.	 */	case LF_SPARSE:		sp_array_size = 10;		sparsearray = (struct sp_array *) malloc(sp_array_size * sizeof(struct sp_array));		for (i = 0; i < SPARSE_IN_HDR; i++) {			if (!head->header.sp[i].numbytes)				break;			sparsearray[i].offset = 				from_oct(1+12, head->header.sp[i].offset);			sparsearray[i].numbytes = 				from_oct(1+12, head->header.sp[i].numbytes);		}		/*		end_nulls = from_oct(1+12, head->header.ending_blanks);*/				if (head->header.isextended) {			/* read in the list of extended headers			   and translate them into the sparsearray 			   as before */			/* static */ int ind = SPARSE_IN_HDR;						for (;;) {								exhdr = findrec();				for (i = 0; i < SPARSE_EXT_HDR; i++) {										if (i+ind > sp_array_size-1) {					/*					 * realloc the scratch area					 * since we've run out of room --		 			 */						sparsearray = (struct sp_array *) 								realloc(sparsearray, 								2 * sp_array_size * (sizeof(struct sp_array)));						sp_array_size *= 2;					}					if (!exhdr->ext_hdr.sp[i].numbytes)						break;					sparsearray[i+ind].offset = 						from_oct(1+12, exhdr->ext_hdr.sp[i].offset);					sparsearray[i+ind].numbytes = 						from_oct(1+12, exhdr->ext_hdr.sp[i].numbytes);				}				if (!exhdr->ext_hdr.isextended) 					break;				else {					ind += SPARSE_EXT_HDR;					userec(exhdr);				}			}			userec(exhdr);		}				/* FALL THRU */	case LF_OLDNORMAL:	case LF_NORMAL:	case LF_CONTIG:		/*		 * Appears to be a file.		 * See if it's really a directory.		 */		namelen = strlen(skipcrud+head->header.name)-1;		if (head->header.name[skipcrud+namelen] == '/')			goto really_dir;		/* FIXME, deal with protection issues */	again_file:		openflag = (f_keep?			O_BINARY|O_NDELAY|O_WRONLY|O_CREAT|O_EXCL:			O_BINARY|O_NDELAY|O_WRONLY|O_CREAT|O_TRUNC)			| ((head->header.linkflag == LF_SPARSE) ? 0 : O_APPEND);						/*			 * JK - The last | is a kludge to solve the problem			 * the O_APPEND flag  causes with files we are			 * trying to make sparse:  when a file is opened			 * with O_APPEND, it writes  to the last place			 * that something was written, thereby ignoring			 * any lseeks that we have done.  We add this			 * extra condition to make it able to lseek when			 * a file is sparse, i.e., we don't open the new			 * file with this flag.  (Grump -- this bug caused			 * me to waste a good deal of time, I might add)  			 */		if(f_exstdout) {			fd = 1;			goto extract_file;		}#ifdef O_CTG		/*		 * Contiguous files (on the Masscomp) have to specify		 * the size in the open call that creates them.		 */		if (head->header.linkflag == LF_CONTIG)			fd = open(skipcrud+head->header.name, openflag | O_CTG,				hstat.st_mode, hstat.st_size);		else#endif		{#ifdef NO_OPEN3			/*			 * On raw V7 we won't let them specify -k (f_keep), but			 * we just bull ahead and create the files.			 */			fd = creat(skipcrud+head->header.name, 				hstat.st_mode);#else			/*			 * With 3-arg open(), we can do this up right.			 */			fd = open(skipcrud+head->header.name, openflag,				hstat.st_mode);#endif		}		if (fd < 0) {			if (make_dirs(skipcrud+head->header.name))				goto again_file;			msg_perror("Could not create file %s",skipcrud+head->header.name);			if (head->header.isextended)				skip_extended_headers();			skip_file((long)hstat.st_size);			goto quit;		}	extract_file:		if (head->header.linkflag == LF_SPARSE) {			char	*name;			int	namelen;			/*			 * Kludge alert.  NAME is assigned to header.name			 * because during the extraction, the space that			 * contains the header will get scribbled on, and			 * the name will get munged, so any error messages			 * that happen to contain the filename will look			 * REAL interesting unless we do this.			 */			namelen = strlen(skipcrud+head->header.name);			name = (char *) malloc((sizeof(char)) * namelen);			bcopy(skipcrud+head->header.name, name, namelen);			size = hstat.st_size;			extract_sparse_file(fd, &size, hstat.st_size, 						name);		}					else 				  for (size = hstat.st_size;		       size > 0;		       size -= written) {			long	offset, 				numbytes;			if(f_multivol) {				save_name=head->header.name;				save_totsize=hstat.st_size;				save_sizeleft=size;			}						/*			 * Locate data, determine max length			 * writeable, write it, record that			 * we have used the data, then check			 * if the write worked.			 */			data = findrec()->charptr;

⌨️ 快捷键说明

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