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

📄 eltorito.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* @(#)eltorito.c	1.17 00/05/28 joerg */#ifndef lintstatic	char sccsid[] =	"@(#)eltorito.c	1.17 00/05/28 joerg";#endif/* * Program eltorito.c - Handle El Torito specific extensions to iso9660. *   Written by Michael Fulbright <msf@redhat.com> (1996).   Copyright 1996 RedHat Software, Incorporated   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */#include "config.h"#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <unixstd.h>#include <stdxlib.h>#include <fctldefs.h>#include "mkisofs.h"#include "match.h"#include "iso9660.h"#include "diskmbr.h"#include "bootinfo.h"#ifdef	USE_LIBSCHILY#include <standard.h>#include <schily.h>#endif#include <utypes.h>#include <intcvt.h>#undef MIN#define MIN(a, b) (((a) < (b))? (a): (b))static struct eltorito_validation_entry valid_desc;static struct eltorito_boot_descriptor gboot_desc;static struct disk_master_boot_record disk_mbr;static unsigned int bcat_de_flags;	void	init_boot_catalog	__PR((const char *path));	void	insert_boot_cat		__PR((void));static	void	get_torito_desc		__PR((struct eltorito_boot_descriptor *boot_desc));static	void	fill_boot_desc		__PR((struct eltorito_defaultboot_entry *boot_desc_entry,						struct eltorito_boot_entry_info *boot_entry));	void	get_boot_entry		__PR((void));	void	new_boot_entry		__PR((void));static	int	tvd_write		__PR((FILE * outfile));/* * Make sure any existing boot catalog is excluded */voidinit_boot_catalog(path)	const char	*path;{	char           *bootpath;	/* filename of boot catalog */	bootpath = (char *) e_malloc(strlen(boot_catalog) + strlen(path) + 2);	strcpy(bootpath, path);	if (bootpath[strlen(bootpath) - 1] != '/') {		strcat(bootpath, "/");	}	strcat(bootpath, boot_catalog);	/*	 * we are going to create a virtual catalog file	 * - so make sure any existing is excluded	 */	add_match(bootpath);	/* flag the file as a memory file */	bcat_de_flags = MEMORY_FILE;	/* find out if we want to "hide" this file */	if (i_matches(boot_catalog) || i_matches(bootpath))		bcat_de_flags |= INHIBIT_ISO9660_ENTRY;	if (j_matches(boot_catalog) || j_matches(bootpath))		bcat_de_flags |= INHIBIT_JOLIET_ENTRY;	free(bootpath);}/* init_boot_catalog(... *//* * Create a boot catalog file in memory - mkisofs already uses this type of * file for the TRANS.TBL files. Therefore the boot catalog is set up in * similar way */voidinsert_boot_cat(){	struct directory_entry *de,	               *s_entry;	char           *p1,	               *p2,	               *p3;	struct directory *this_dir,	               *dir;	char           *buffer;	init_fstatbuf();	buffer = (char *) e_malloc(SECTOR_SIZE);	memset(buffer, 0, SECTOR_SIZE);	/*	 * try to find the directory that will contain the boot.cat file	 * - not very neat, but I can't think of a better way	 */	p1 = strdup(boot_catalog);	/* get dirname (p1) and basename (p2) of boot.cat */	if ((p2 = strrchr(p1, '/')) != NULL) {		*p2 = '\0';		p2++;		/* find the dirname directory entry */		de = search_tree_file(root, p1);		if (!de) {#ifdef	USE_LIBSCHILY			comerrno(EX_BAD,			"Uh oh, I cant find the boot catalog directory '%s'!\n",								p1);#else			fprintf(stderr,			"Uh oh, I cant find the boot catalog directory '%s'!\n",								p1);			exit(1);#endif		}		this_dir = 0;		/* get the basename (p3) of the directory */		if ((p3 = strrchr(p1, '/')) != NULL)			p3++;		else			p3 = p1;		/* find the correct sub-directory entry */		for (dir = de->filedir->subdir; dir; dir = dir->next)			if (!(strcmp(dir->de_name, p3)))				this_dir = dir;		if (this_dir == 0) {#ifdef	USE_LIBSCHILY			comerrno(EX_BAD,			"Uh oh, I cant find the boot catalog directory '%s'!\n",								p3);#else			fprintf(stderr,			"Uh oh, I cant find the boot catalog directory '%s'!\n",								p3);			exit(1);#endif		}	} else {		/* boot.cat is in the root directory */		this_dir = root;		p2 = p1;	}	/*	 * make a directory entry in memory (using the same set up as for table	 * entries	 */	s_entry = (struct directory_entry *)		e_malloc(sizeof(struct directory_entry));	memset(s_entry, 0, sizeof(struct directory_entry));	s_entry->next = this_dir->contents;	this_dir->contents = s_entry;	s_entry->isorec.flags[0] = ISO_FILE;	s_entry->priority = 32768;	iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime);	s_entry->inode = TABLE_INODE;	s_entry->dev = (dev_t) UNCACHED_DEVICE;	set_723(s_entry->isorec.volume_sequence_number,						volume_sequence_number);	set_733((char *) s_entry->isorec.size, SECTOR_SIZE);	s_entry->size = SECTOR_SIZE;	s_entry->filedir = this_dir;	s_entry->name = strdup(p2);	iso9660_file_length(p2, s_entry, 0);	/* flag file as necessary */	s_entry->de_flags = bcat_de_flags;	if (use_RockRidge && !(bcat_de_flags & INHIBIT_ISO9660_ENTRY)) {		fstatbuf.st_mode = 0444 | S_IFREG;		fstatbuf.st_nlink = 1;		generate_rock_ridge_attributes("",			p2, s_entry,			&fstatbuf, &fstatbuf, 0);	}	/*	 *  memory files are stored at s_entry->table	 * - but this is also used for each s_entry to generate	 * TRANS.TBL entries. So if we are generating tables,	 * store the TRANS.TBL data here for the moment	 */	if (generate_tables && !(bcat_de_flags & INHIBIT_ISO9660_ENTRY)) {		sprintf(buffer, "F\t%s\n", s_entry->name);		/* copy the TRANS.TBL entry info and clear the buffer */		s_entry->table = strdup(buffer);		memset(buffer, 0, SECTOR_SIZE);		/*		 * store the (empty) file data in the		 * unused s_entry->whole_name element for the time being	 	 * - this will be transferred to s_entry->table after any		 * TRANS.TBL processing later		 */		s_entry->whole_name = buffer;	} else {		/* store the (empty) file data in the s_entry->table element */		s_entry->table = buffer;		s_entry->whole_name = NULL;	}}static voidget_torito_desc(boot_desc)	struct eltorito_boot_descriptor	*boot_desc;{	int             checksum;	unsigned char  *checksum_ptr;	struct directory_entry *de2;	/* Boot catalog */	int		i;	int		offset;	struct eltorito_defaultboot_entry boot_desc_record;	memset(boot_desc, 0, sizeof(*boot_desc));	boot_desc->type[0] = 0;	memcpy(boot_desc->id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID));	boot_desc->version[0] = 1;	memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof(EL_TORITO_ID));	/*	 * search from root of iso fs to find boot catalog	 * - we already know where the boot catalog is	 * - we created it above - but lets search for it anyway	 * - good sanity check!	 */	de2 = search_tree_file(root, boot_catalog);	if (!de2 || !(de2->de_flags & MEMORY_FILE)) {#ifdef	USE_LIBSCHILY		comerrno(EX_BAD, "Uh oh, I cant find the boot catalog '%s'!\n",							boot_catalog);#else		fprintf(stderr, "Uh oh, I cant find the boot catalog '%s'!\n",							boot_catalog);		exit(1);#endif	}	set_731(boot_desc->bootcat_ptr,		(unsigned int) get_733(de2->isorec.extent));	/*	 * we have the boot image, so write boot catalog information	 * Next we write out the primary descriptor for the disc	 */	memset(&valid_desc, 0, sizeof(valid_desc));	valid_desc.headerid[0] = 1;	valid_desc.arch[0] = EL_TORITO_ARCH_x86;	/*	 * we'll shove start of publisher id into id field,	 * may get truncated but who really reads this stuff!	 */	if (publisher)		memcpy_max(valid_desc.id, publisher,						MIN(23, strlen(publisher)));	valid_desc.key1[0] = (char) 0x55;	valid_desc.key2[0] = (char) 0xAA;	/* compute the checksum */	checksum = 0;	checksum_ptr = (unsigned char *) &valid_desc;	/* Set checksum to 0 before computing checksum */	set_721(valid_desc.cksum, 0);	for (i = 0; i < sizeof(valid_desc); i += 2) {		checksum += (unsigned int) checksum_ptr[i];		checksum += ((unsigned int) checksum_ptr[i + 1]) * 256;	}	/* now find out the real checksum */	checksum = -checksum;	set_721(valid_desc.cksum, (unsigned int) checksum);	/* now write it to the virtual boot catalog */	memcpy(de2->table, &valid_desc, 32);	for (current_boot_entry = first_boot_entry,offset = sizeof(valid_desc);	     current_boot_entry != NULL;	     current_boot_entry = current_boot_entry->next,	     offset += sizeof(boot_desc_record)) {		if (offset >= SECTOR_SIZE) {#ifdef	USE_LIBSCHILY			comerrno(EX_BAD,			"Too many El Torito boot entries\n");#else			fprintf(stderr,			"Too many El Torito boot entries\n");			exit(1);#endif		}		fill_boot_desc (&boot_desc_record, current_boot_entry);		memcpy(de2->table + offset, &boot_desc_record,					sizeof(boot_desc_record));	}}/* get_torito_desc(... */static void

⌨️ 快捷键说明

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