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

📄 create.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 2 页
字号:
			/* If we're gnudumping, we aren't done yet so don't close it. */			if(!f_gnudump)				finish_header(header);	/* Done with directory header */		}		/* Hack to remove "./" from the front of all the file names */		if (len == 2 && namebuf[0] == '.' && namebuf[1]=='/') {			len = 0;		}		if(f_gnudump) {			int sizeleft;			int totsize;			int bufsize;			union record *start;			int count;			char *buf,*p_buf;			buf=gnu_list_name->dir_contents; /* FOO */			totsize=0;			for(p_buf=buf;p_buf && *p_buf;) {				int tmp;				tmp=strlen(p_buf)+1;				totsize+=tmp;				p_buf+=tmp;			}			totsize++;			to_oct((long)totsize,1+12,header->header.size);			finish_header(header);			p_buf=buf;			sizeleft=totsize;			while(sizeleft>0) {				if(f_multivol) {					save_name=p;					save_sizeleft=sizeleft;					save_totsize=totsize;				}				start=findrec();				bufsize=endofrecs()->charptr - start->charptr;				if(sizeleft<bufsize) {					bufsize=sizeleft;					count=bufsize%RECORDSIZE;					if(count)						bzero(start->charptr+sizeleft,RECORDSIZE-count);				}				bcopy(p_buf,start->charptr,bufsize);				sizeleft-=bufsize;				p_buf+=bufsize;				userec(start+(bufsize-1)/RECORDSIZE);			}			if(f_multivol)				save_name = 0;			break;		}		/* Now output all the files in the directory */		/* if (f_dironly)			break;		/* Unless the cmdline said not to */				errno = 0;		dirp = opendir(p);		if (!dirp) {			if (errno) {				msg_perror ("can't open directory %s",p);			} else {				msg("error opening directory %s",					p);			}			break;		}		/* Should speed this up by cd-ing into the dir, FIXME */		while (NULL != (d=readdir(dirp))) {			/* Skip . and .. */			if(is_dot_or_dotdot(d->d_name))				continue;			if (DP_NAMELEN(d) + len >= NAMSIZ) {				namebuf[len]='\0';				msg("file name %s%s too long\n", 					namebuf, d->d_name);				continue;			}			strcpy(namebuf+len, d->d_name);			if(f_exclude && check_exclude(namebuf))				continue;			dump_file(namebuf, our_device);		}		closedir(dirp);	}		break;#ifdef S_IFCHR	case S_IFCHR:			/* Character special file */		type = LF_CHR;		goto easy;#endif#ifdef S_IFBLK	case S_IFBLK:			/* Block     special file */		type = LF_BLK;		goto easy;#endif#ifdef S_IFIFO	case S_IFIFO:			/* Fifo      special file */				type = LF_FIFO;		goto easy;#endif#ifdef S_IFSOCK# if S_IFSOCK != S_IFIFO	case S_IFSOCK:			/* Socket	pretend its a fifo? */		type = LF_FIFO;		goto easy;# endif#endif	easy:		if (!f_standard) goto unknown;		hstat.st_size = 0;		/* Force 0 size */		header = start_header(p, &hstat);		if (header == NULL) goto badfile;	/* eg name too long */		header->header.linkflag = type;		if (type != LF_FIFO) {			to_oct((long) major(hstat.st_rdev), 8,				header->header.devmajor);			to_oct((long) minor(hstat.st_rdev), 8,				header->header.devminor);		}		finish_header(header);		break;	default:	unknown:		msg("%s: Unknown file type; file ignored.\n", p);		break;	}}intfinish_sparse_file(fd, sizeleft, fullsize, name)	int	fd;	long 	*sizeleft,		fullsize;	char	*name;{	union record	*start;	char		tempbuf[RECORDSIZE];	int		bufsize,			sparse_ind = 0,			count;	long		pos;	while (*sizeleft > 0) {		start = findrec();		bzero(start->charptr, RECORDSIZE);		bufsize = sparsearray[sparse_ind].numbytes;		if (!bufsize) {  /* we blew it, maybe */		        msg("Wrote %ld of %ld bytes to file %s",			           fullsize - *sizeleft, fullsize, name);			break; 	        }		pos = lseek(fd, sparsearray[sparse_ind++].offset, 0);		/* 		 * If the number of bytes to be written here exceeds		 * the size of the temporary buffer, do it in steps.		 */		while (bufsize > RECORDSIZE) {/*			if (amt_read) {				count = read(fd, start->charptr+amt_read, RECORDSIZE-amt_read);				bufsize -= RECORDSIZE - amt_read;				amt_read = 0;				userec(start);				start = findrec();				bzero(start->charptr, RECORDSIZE);			}*/			/* store the data */			count = read(fd, start->charptr, RECORDSIZE);			if (count < 0) 	{				msg_perror("read error at byte %ld, reading %d bytes, in file %s", 						fullsize - *sizeleft, bufsize, name);				return 1;			}						bufsize -= count;			*sizeleft -= count;			userec(start);			start = findrec();			bzero(start->charptr, RECORDSIZE);		}		clear_buffer(tempbuf);		count = read(fd, tempbuf, bufsize);		bcopy(tempbuf, start->charptr, RECORDSIZE);		if (count < 0) 	{			msg_perror("read error at byte %ld, reading %d bytes, in file %s", 					fullsize - *sizeleft, bufsize, name);			return 1;		}/*		if (amt_read >= RECORDSIZE) {			amt_read = 0;			userec(start+(count-1)/RECORDSIZE);			if (count != bufsize) {				msg("file %s shrunk by %d bytes, padding with zeros.\n", name, sizeleft);				return 1;			}			start = findrec();		} else 			amt_read += bufsize;*/		*sizeleft -= count;		userec(start);	}	free(sparsearray);/*	userec(start+(count-1)/RECORDSIZE);*/	return 0;}init_sparsearray(){	register int i;	sp_array_size = 10;	/* 	 * Make room for our scratch space -- initially is 10 elts long	 */	sparsearray = (struct sp_array *) malloc(sp_array_size * sizeof(struct sp_array));	for (i = 0; i < sp_array_size; i++) {		sparsearray[i].offset = 0;		sparsearray[i].numbytes = 0;	}}/* * Okay, we've got a sparse file on our hands -- now, what we need to do is * make a pass through the file and carefully note where any data is, i.e., * we want to find how far into the file each instance of data is, and how * many bytes are there.  We store this information in the sparsearray, * which will later be translated into header information.  For now, we use * the sparsearray as convenient storage. * * As a side note, this routine is a mess.  If I could have found a cleaner * way to do it, I would have.  If anyone wants to find a nicer way to do * this, feel free. */intdeal_with_sparse(name, header, nulls_at_end)	char		*name;	union record 	*header;	{	long	numbytes = 0;	long	offset = 0;	long	save_offset;	int	fd;	int	start,		end;	int	end_nulls = 0;	int	current_size = hstat.st_size;	int	sparse_ind = 0,		cc;	char	buf[RECORDSIZE];	int	read_last_data = 0; /* did we just read the last record? */	int 	amidst_data = 0;		header->header.isextended = 0;	/* 	 * Can't open the file -- this problem will be caught later on,	 * so just return.	 */	if ((fd = open(name, O_RDONLY)) < 0)		return;			init_sparsearray();	clear_buffer(buf);	while ((cc = read(fd, buf, sizeof buf)) != 0) {					if (sparse_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 (cc == sizeof buf) {			if (zero_record(buf)) {				if (amidst_data) {					sparsearray[sparse_ind++].numbytes						= numbytes;					amidst_data = 0;					numbytes = 0;				}				offset += cc;			} else {  /* !zero_record(buf) */				if (!amidst_data) {				        amidst_data = 1;					where_is_data(&start, &end, buf);					numbytes += end - start;					offset += start;					sparsearray[sparse_ind].offset = offset;				} else					numbytes += cc;				offset += cc;			}		} else if (cc < sizeof buf) {			if (!zero_record(buf)) {				if (!amidst_data) {					amidst_data = 1;					where_is_data(&start, &end, buf);					/* In case there are nulls at the 					   end that we need to remember */					if (end < cc)						end = cc;					numbytes += start - end;					offset += start;/*					end_nulls = RECORDSIZE - end;*/				} else {					numbytes += cc;/*					end_nulls = RECORDSIZE - end;*/				}				sparsearray[sparse_ind].numbytes = numbytes;			} /* else				end_nulls = cc;*/		}		clear_buffer(buf);	}	if (numbytes)	        sparsearray[sparse_ind].numbytes = numbytes;	close(fd);/*	printf("%d\n", end_nulls);	*nulls_at_end = end_nulls;*/	return sparse_ind;}/*  * Just zeroes out the buffer so we don't confuse ourselves with leftover * data. */clear_buffer(buf)	char	*buf;{	register int 	i;	for (i = 0; i < RECORDSIZE; i++)		buf[i] = '\0';}/*  * JK -  * This routine takes a character array, and tells where within that array * the data can be found.  It skips over any zeros, and sets the first * non-zero point in the array to be the "start", and continues until it * finds non-data again, which is marked as the "end."  This routine is  * mainly for 1) seeing how far into a file we must lseek to data, given * that we have a sparse file, and 2) determining the "real size" of the * file, i.e., the number of bytes in the sparse file that are data, as * opposed to the zeros we are trying to skip. */where_is_data(from, to, buffer)	int	*from,		*to;	char	*buffer;{	register int	i = 0;	register int	save_to = *to;	int	amidst_data = 0;		while (!buffer[i])		i++;	*from = i;	if (*from < 16)	/* don't bother */		*from = 0;	/* keep going to make sure there isn't more real	   data in this record */	while (i < RECORDSIZE) {		if (!buffer[i]) {			if (amidst_data) {				save_to = i;				amidst_data = 0;			}			i++;		}		else if (buffer[i]) {			if (!amidst_data)				amidst_data = 1;			i++;		}	}	if (i == RECORDSIZE)		*to = i;	else		*to = save_to;		}/* * Takes a recordful of data and basically cruises through it to see if * it's made *entirely* of zeros, returning a 0 the instant it finds * something that is a non-zero, i.e., useful data. */zero_record(buffer)	char	*buffer;{	register int	i;	for (i = 0; i < RECORDSIZE; i++)		if (buffer[i] != '\000')			return 0;	return 1;}find_new_file_size(filesize, highest_index)	int	*filesize;	int	highest_index;{	register int 	i;	*filesize = 0;	for (i = 0; sparsearray[i].numbytes && i <= highest_index; i++)		*filesize += sparsearray[i].numbytes;}	/* * Make a header block for the file  name  whose stat info is  st . * Return header pointer for success, NULL if the name is too long. */union record *start_header(name, st)	char	*name;	register struct stat *st;{	register union record *header;	header = (union record *) findrec();	bzero(header->charptr, sizeof(*header)); /* XXX speed up */	/*	 * Check the file name and put it in the record.	 */	if(!f_absolute_paths) {		static int warned_once = 0;#ifdef MSDOS		if(name[1]==':') {			name+=2;			if(!warned_once++)				msg("Removing drive spec from names in the archive");		}#endif		while ('/' == *name) {			name++;				/* Force relative path */			if (!warned_once++)				msg("Removing leading / from absolute path names in the archive.");		}	}	strcpy(header->header.name, name);	if (header->header.name[NAMSIZ-1]) {		msg("%s: name too long\n", name);		return NULL;	}	to_oct((long) (st->st_mode & ~S_IFMT),					8,  header->header.mode);	to_oct((long) st->st_uid,	8,  header->header.uid);	to_oct((long) st->st_gid,	8,  header->header.gid);	to_oct((long) st->st_size,	1+12, header->header.size);	to_oct((long) st->st_mtime,	1+12, header->header.mtime);	/* header->header.linkflag is left as null */	if(f_gnudump) {		to_oct((long) st->st_atime, 1+12, header->header.atime);		to_oct((long) st->st_ctime, 1+12, header->header.ctime);	}#ifndef NONAMES	/* Fill in new Unix Standard fields if desired. */	if (f_standard) {		header->header.linkflag = LF_NORMAL;	/* New default */		strcpy(header->header.magic, TMAGIC);	/* Mark as Unix Std */		finduname(header->header.uname, st->st_uid);		findgname(header->header.gname, st->st_gid);	}#endif	return header;}/*  * Finish off a filled-in header block and write it out. * We also print the file name and/or full info if verbose is on. */voidfinish_header(header)	register union record *header;{	register int	i, sum;	register char	*p;	void bcopy();	bcopy(CHKBLANKS, header->header.chksum, sizeof(header->header.chksum));	sum = 0;	p = header->charptr;	for (i = sizeof(*header); --i >= 0; ) {		/*		 * We can't use unsigned char here because of old compilers,		 * e.g. V7.		 */		sum += 0xFF & *p++;	}	/*	 * Fill in the checksum field.  It's formatted differently	 * from the other fields:  it has [6] digits, a null, then a	 * space -- rather than digits, a space, then a null.	 * We use to_oct then write the null in over to_oct's space.	 * The final space is already there, from checksumming, and	 * to_oct doesn't modify it.	 *	 * This is a fast way to do:	 * (void) sprintf(header->header.chksum, "%6o", sum);	 */	to_oct((long) sum,	8,  header->header.chksum);	header->header.chksum[6] = '\0';	/* Zap the space */	userec(header);	if (f_verbose) {		/* These globals are parameters to print_header, sigh */		head = header;		/* hstat is already set up */		head_standard = f_standard;		print_header();	}	return;}/* * Quick and dirty octal conversion. * Converts long "value" into a "digs"-digit field at "where", * including a trailing space and room for a null.  "digs"==3 means * 1 digit, a space, and room for a null. * * We assume the trailing null is already there and don't fill it in. * This fact is used by start_header and finish_header, so don't change it! * * This should be equivalent to: *	(void) sprintf(where, "%*lo ", digs-2, value); * except that sprintf fills in the trailing null and we don't. */voidto_oct(value, digs, where)	register long	value;	register int	digs;	register char	*where;{		--digs;				/* Trailing null slot is left alone */	where[--digs] = ' ';		/* Put in the space, though */	/* Produce the digits -- at least one */	do {		where[--digs] = '0' + (char)(value & 7); /* one octal digit */		value >>= 3;	} while (digs > 0 && value != 0);	/* Leading spaces, if necessary */	while (digs > 0)		where[--digs] = ' ';}/* * Write the EOT record(s). * We actually zero at least one record, through the end of the block. * Old tar writes garbage after two zeroed records -- and PDtar used to. */write_eot(){	union record *p;	int bufsize;	void bzero();	p = findrec();	bufsize = endofrecs()->charptr - p->charptr;	bzero(p->charptr, bufsize);	userec(p);}

⌨️ 快捷键说明

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