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

📄 multi.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
📖 第 1 页 / 共 3 页
字号:
			i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1);			continue;		}		*pnt = (struct directory_entry *) e_malloc(sizeof(**rtn));		(*pnt)->next = NULL;#ifdef	DEBUG		error("IDR name: '%s' ist: %d soll: %d\n",			idr->name, strlen(idr->name), idr->name_len[0]);#endif		(*pnt)->isorec = *idr;		(*pnt)->starting_block =				isonum_733((unsigned char *) idr->extent);		(*pnt)->size = isonum_733((unsigned char *) idr->size);		(*pnt)->priority = 0;		(*pnt)->name = NULL;		(*pnt)->got_rr_name = 0;		(*pnt)->table = NULL;		(*pnt)->whole_name = NULL;		(*pnt)->filedir = NULL;		(*pnt)->parent_rec = NULL;		/*		 * Set this information so that we correctly cache previous		 * session bits of information.		 */		(*pnt)->inode = (*pnt)->starting_block;		(*pnt)->dev = PREV_SESS_DEV;		(*pnt)->rr_attributes = NULL;		(*pnt)->rr_attr_size = 0;		(*pnt)->total_rr_attr_size = 0;		(*pnt)->de_flags = SAFE_TO_REUSE_TABLE_ENTRY;		/*		 * Check for and parse any RR attributes for the file. All we		 * are really looking for here is the original name of the		 * file.		 */		rlen = idr->length[0] & 0xff;		cpnt = (unsigned char *) idr;		rlen -= offsetof(struct iso_directory_record, name[0]);		cpnt += offsetof(struct iso_directory_record, name[0]);		rlen -= idr->name_len[0];		cpnt += idr->name_len[0];		if ((idr->name_len[0] & 1) == 0) {			cpnt++;			rlen--;		};		if (no_rr)			rlen = 0;		if (rlen > 0) {			(*pnt)->total_rr_attr_size =						(*pnt)->rr_attr_size = rlen;			(*pnt)->rr_attributes = e_malloc(rlen);			memcpy((*pnt)->rr_attributes, cpnt, rlen);			seen_rockridge = 1;		}#ifdef	DEBUG		error("INT name: '%s' ist: %d soll: %d\n",			(*pnt)->isorec.name, strlen((*pnt)->isorec.name),			idr->name_len[0]);#endif		if (idr->name_len[0] < sizeof((*pnt)->isorec.name)) {			/*			 * Now zero out the remainder of the name field.			 */			cpnt = (unsigned char *) (*pnt)->isorec.name;			cpnt += idr->name_len[0];			memset(cpnt, 0,				sizeof((*pnt)->isorec.name) - idr->name_len[0]);		} else {			/*			 * Simple sanity work to make sure that we have no			 * illegal data structures in our tree.			 */			(*pnt)->isorec.name[MAX_ISONAME] = '\0';			(*pnt)->isorec.name_len[0] = MAX_ISONAME;		}		/*		 * If the filename len from the old session is more		 * then 31 chars, there is a high risk of hard violations		 * if the ISO9660 standard.		 * Run it through our name canonication machine....		 */		if (idr->name_len[0] > LEN_ISONAME || check_oldnames) {			iso9660_check(idr, *pnt);		}		if (parse_rr((*pnt)->rr_attributes, rlen, *pnt) == -1) {#ifdef	USE_LIBSCHILY			comerrno(EX_BAD,			    "Cannot parse Rock Ridge attributes for '%s'.\n",								idr->name);#else			fprintf(stderr,			    "Cannot parse Rock Ridge attributes for '%s'.\n",								idr->name);			exit(1);#endif		}		if (((*pnt)->isorec.name_len[0] == 1)			&& (((*pnt)->isorec.name[0] == 0)	/* "."  entry*/			||((*pnt)->isorec.name[0] == 1))) {	/* ".." entry*/			if ((*pnt)->name != NULL) {				free((*pnt)->name);			}			if ((*pnt)->whole_name != NULL) {				free((*pnt)->whole_name);			}			if ((*pnt)->isorec.name[0] == 0) {				(*pnt)->name = strdup(".");			} else {				(*pnt)->name = strdup("..");			}		}#ifdef DEBUG		fprintf(stderr, "got DE name: %s\n", (*pnt)->name);#endif		if (strncmp(idr->name, trans_tbl, strlen(trans_tbl)) == 0) {			if ((*pnt)->name != NULL) {				free((*pnt)->name);			}			if ((*pnt)->whole_name != NULL) {				free((*pnt)->whole_name);			}/*			(*pnt)->name = strdup("<translation table>");*/			(*pnt)->name = strdup(trans_tbl);			tt_extent = isonum_733((unsigned char *) idr->extent);			tt_size = isonum_733((unsigned char *) idr->size);			if (tt_extent == 0)				tt_size = 0;		}		pnt++;		i += idr->length[0];	}	/*	 * If there was a TRANS.TBL;1 entry, then grab it, read it, and use it	 * to get the filenames of the files.  Also, save the table info, just	 * in case we need to use it.	 *	 * The entries look something like: F ISODUMP.;1 isodump	 */	if (tt_extent != 0 && tt_size != 0) {		nbytes = roundup(tt_size, SECTOR_SIZE);		tt_buf = (unsigned char *) e_malloc(nbytes);		readsecs(tt_extent, tt_buf, nbytes / SECTOR_SIZE);		/*		 * Loop through the file, examine each entry, and attempt to		 * attach it to the correct entry.		 */		cpnt = tt_buf;		cpnt1 = tt_buf;		while (cpnt - tt_buf < tt_size) {			/* Skip to a line terminator, or end of the file. */			while ((cpnt1 - tt_buf < tt_size)				&& (*cpnt1 != '\n')				&& (*cpnt1 != '\0')) {				cpnt1++;			}			/* Zero terminate this particular line. */			if (cpnt1 - tt_buf < tt_size) {				*cpnt1 = '\0';			}			/*			 * Now dig through the actual directories, and try and			 * find the attachment for this particular filename.			 */			for (pnt = rtn, i = 0; i < *nent; i++, pnt++) {				rlen = isonum_711((*pnt)->isorec.name_len);				/*				 * If this filename is so long that it would				 * extend past the end of the file, it cannot				 * be the one we want.				 */				if (cpnt + 2 + rlen - tt_buf >= tt_size) {					continue;				}				/*				 * Now actually compare the name, and make sure				 * that the character at the end is a ' '.				 */				if (strncmp((char *) cpnt + 2,					(*pnt)->isorec.name, rlen) == 0					&& cpnt[2 + rlen] == ' '					&& (p = strchr((char *)&cpnt[2 + rlen], '\t'))) {					p++;					/*					 * This is a keeper. Now determine the					 * correct table entry that we will					 * use on the new image.					 */					if (strlen(p) > 0) {						(*pnt)->table =						   e_malloc(strlen(p) + 4);						sprintf((*pnt)->table,							"%c\t%s\n",							*cpnt, p);					}					if (!(*pnt)->got_rr_name) {						if ((*pnt)->name != NULL) {							free((*pnt)->name);						}						(*pnt)->name = strdup(p);					}					break;				}			}			cpnt = cpnt1 + 1;			cpnt1 = cpnt;		}		free(tt_buf);	} else if (!seen_rockridge && !warning_given) {		/*		 * Warn the user that iso (8.3) names were used because neither		 * Rock Ridge (-R) nor TRANS.TBL (-T) name translations were		 * found.		 */		fprintf(stderr,		    "Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) \n");		fprintf(stderr,		    "name translations were found on previous session.\n");		fprintf(stderr,		    "ISO (8.3) file names have been used instead.\n");		warning_given = 1;	}	if (dirbuff != NULL) {		free(dirbuff);	}	return rtn;}/* read_merging_directory *//* * Free any associated data related to the structures. */intfree_mdinfo(ptr, len)	struct directory_entry **ptr;	int		len;{	int		i;	struct directory_entry **p;	p = ptr;	for (i = 0; i < len; i++, p++) {	/* If the tree-handling code decided that it needed an entry, it will	   have removed it from the list.  Thus we must allow for null	   pointers here. */		if (*p == NULL) {			continue;		}		free_directory_entry(*p);	}	free(ptr);	return 0;}static voidfree_directory_entry(dirp)	struct directory_entry *dirp;{	if (dirp->name != NULL)		free(dirp->name);	if (dirp->whole_name != NULL)		free(dirp->whole_name);	if (dirp->rr_attributes != NULL)		free(dirp->rr_attributes);	if (dirp->table != NULL)		free(dirp->table);	free(dirp);}/* * Search the list to see if we have any entries from the previous * session that match this entry.  If so, copy the extent number * over so we don't bother to write it out to the new session. */intcheck_prev_session(ptr, len, curr_entry, statbuf, lstatbuf, odpnt)	struct directory_entry **ptr;	int		len;	struct directory_entry *curr_entry;	struct stat	*statbuf;	struct stat	*lstatbuf;	struct directory_entry **odpnt;{	int		i;	int		rr;	int		retcode = 0;	/* Default not found */	for (i = 0; i < len; i++) {		if (ptr[i] == NULL) {	/* Used or empty entry skip */			continue;		}#if 0		if (ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1			&& ptr[i]->name[0] == '\0') {			continue;		}		if (ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1			&& ptr[i]->name[0] == 1) {			continue;		}#else		if (ptr[i]->name != NULL && strcmp(ptr[i]->name, ".") == 0) {			continue;		}		if (ptr[i]->name != NULL && strcmp(ptr[i]->name, "..") == 0) {			continue;		}#endif		if (ptr[i]->name != NULL			&& strcmp(ptr[i]->name, curr_entry->name) != 0) {			/* Not the same name continue */			continue;		}		/*		 * It's a directory so we must always merge it with the new		 * session. Never ever reuse directory extents.  See comments		 * in tree.c for an explaination of why this must be the case.		 */		if ((curr_entry->isorec.flags[0] & ISO_DIRECTORY) != 0) {			retcode = 2;	/* Flag directory case */			goto found_it;		}		/*		 * We know that the files have the same name.  If they also		 * have the same file type (i.e. file, dir, block, etc), then		 * we can safely reuse the TRANS.TBL entry for this file. The		 * check_rr_dates() function will do this for us.		 *		 * Verify that the file type and dates are consistent. If not,		 * we probably have a different file, and we need to write it		 * out again.		 */		retcode = 1;	/* We found a non directory */		if (ptr[i]->rr_attributes != NULL) {			if ((rr = check_rr_dates(ptr[i], curr_entry, statbuf,							lstatbuf)) == -1)				return (-1);			if (rr == 0) {	/* Different files */				goto found_it;			}		}		/*		 * Verify size and timestamp.  If rock ridge is in use, we		 * need to compare dates from RR too.  Directories are special,		 * we calculate their size later.		 */		if (ptr[i]->size != curr_entry->size) {			/* Different files */			goto found_it;		}		if (memcmp(ptr[i]->isorec.date,					curr_entry->isorec.date, 7) != 0) {			/* Different files */			goto found_it;		}		/* We found it and we can reuse the extent */		memcpy(curr_entry->isorec.extent, ptr[i]->isorec.extent, 8);		curr_entry->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY;		goto found_it;	}	return retcode;found_it:	if (odpnt != NULL) {		*odpnt = ptr[i];	} else {		free(ptr[i]);	}	ptr[i] = NULL;	return retcode;}/* * open_merge_image:  Open an existing image. */intopen_merge_image(path)	char	*path;{#ifndef	USE_SCG	in_image = fopen(path, "rb");	if (in_image == NULL) {		return -1;	}#else	in_image = fopen(path, "rb");	if (in_image == NULL) {		if (scsidev_open(path) < 0)			return -1;	}#endif	return 0;}/* * close_merge_image:  Close an existing image. */intclose_merge_image(){#ifdef	USE_SCG	return (scsidev_close());#else	return (fclose(in_image));#endif}/* * merge_isofs:  Scan an existing image, and return a pointer * to the root directory for this image. */struct iso_directory_record *merge_isofs(path)	char	*path;{	char		buffer[SECTOR_SIZE];	int		file_addr;	int		i;	struct iso_primary_descriptor *pri = NULL;	struct iso_directory_record *rootp;	struct iso_volume_descriptor *vdp;	/*	 * Start by searching for the volume header. Ultimately, we need to	 * search for volume headers in multiple places because we might be	 * starting with a multisession image. FIXME(eric).	 */	get_session_start(&file_addr);	for (i = 0; i < 100; i++) {		if (readsecs(file_addr / SECTOR_SIZE, buffer,				sizeof(buffer) / SECTOR_SIZE) != sizeof(buffer)) {#ifdef	USE_LIBSCHILY			comerr(" Read error on old image %s\n", path);#else			fprintf(stderr, " Read error on old image %s\n", path);			exit(10);#endif		}		vdp = (struct iso_volume_descriptor *) buffer;		if ((strncmp(vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0)			&& (isonum_711((unsigned char *) vdp->type) == ISO_VD_PRIMARY)) {			break;		}		file_addr += SECTOR_SIZE;	}	if (i == 100) {		return NULL;	}	pri = (struct iso_primary_descriptor *) vdp;	/* Check the blocksize of the image to make sure it is compatible. */	if ((isonum_723((unsigned char *) pri->logical_block_size) != SECTOR_SIZE)		|| (isonum_723((unsigned char *) pri->volume_set_size) != 1)) {		return NULL;	}	/* Get the location and size of the root directory. */	rootp = (struct iso_directory_record *)		malloc(sizeof(struct iso_directory_record));	memcpy(rootp, pri->root_directory_record, sizeof(*rootp));	return rootp;}voidmerge_remaining_entries(this_dir, pnt, n_orig)	struct directory *this_dir;	struct directory_entry **pnt;	int		n_orig;{	int		i;	struct directory_entry *s_entry;	unsigned int	ttbl_extent = 0;	unsigned int	ttbl_index = 0;	char		whole_path[1024];	/*	 * Whatever is leftover in the list needs to get merged back into the	 * directory.	 */	for (i = 0; i < n_orig; i++) {		if (pnt[i] == NULL) {			continue;		}		if (pnt[i]->name != NULL && pnt[i]->whole_name == NULL) {			/* Set the name for this directory. */			strcpy(whole_path, this_dir->de_name);			strcat(whole_path, SPATH_SEPARATOR);			strcat(whole_path, pnt[i]->name);			pnt[i]->whole_name = strdup(whole_path);		}		if (pnt[i]->name != NULL/*	  		&& strcmp(pnt[i]->name, "<translation table>") == 0 )*/			&& strcmp(pnt[i]->name, trans_tbl) == 0) {			ttbl_extent =			   isonum_733((unsigned char *) pnt[i]->isorec.extent);			ttbl_index = i;			continue;		}		/*		 * Skip directories for now - these need to be treated		 * differently.		 */		if ((pnt[i]->isorec.flags[0] & ISO_DIRECTORY) != 0) {			/*			 * FIXME - we need to insert this directory into the			 * tree, so that the path tables we generate will be			 * correct.			 */			if ((strcmp(pnt[i]->name, ".") == 0)				|| (strcmp(pnt[i]->name, "..") == 0)) {				free_directory_entry(pnt[i]);				pnt[i] = NULL;				continue;			} else {				merge_old_directory_into_tree(pnt[i], this_dir);			}		}

⌨️ 快捷键说明

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