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

📄 multi.c

📁 刻录光盘的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * File multi.c - scan existing iso9660 image and merge into  * iso9660 filesystem.  Used for multisession support. * * Written by Eric Youngdale (1996). * * 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.   */static char rcsid[] ="$Id: multi.c,v 1.15 1999/11/22 02:36:28 eric Exp $";#include "config.h"#include <stdlib.h>#include <string.h>#include <time.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#ifndef VMS#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#else#include <sys/file.h>#include <vms/fabdef.h>#include "vms.h"extern char * strdup(const char *);#endif#include "mkisofs.h"#include "iso9660.h"#ifdef	USE_LIBSCHILY#include <standard.h>#endif#ifndef howmany#define howmany(x, y)   (((x)+((y)-1))/(y))#endif#ifndef roundup#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))#endif#define TF_CREATE 1#define TF_MODIFY 2#define TF_ACCESS 4#define TF_ATTRIBUTES 8static int  isonum_711 __PR((unsigned char * p));static int  isonum_721 __PR((unsigned char * p));static int  isonum_723 __PR((unsigned char * p));static int  isonum_731 __PR((unsigned char * p));static void DECL(free_directory_entry, (struct directory_entry * dirp));static int  DECL(merge_old_directory_into_tree, (struct directory_entry *,						 struct directory *));#ifdef	__STDC__static intisonum_711 (unsigned char * p)#elsestatic intisonum_711 (p)	unsigned char * p;#endif{	return (*p & 0xff);}#ifdef	__STDC__static intisonum_721 (unsigned char * p)#elsestatic intisonum_721 (p)	unsigned char * p;#endif{	return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));}#ifdef	__STDC__static intisonum_723 (unsigned char * p)#elsestatic intisonum_723 (p)	unsigned char * p;#endif{#if 0	if (p[0] != p[3] || p[1] != p[2]) {#ifdef	USE_LIBSCHILY		comerrno(EX_BAD, "invalid format 7.2.3 number\n");#else		fprintf (stderr, "invalid format 7.2.3 number\n");		exit (1);#endif	}#endif	return (isonum_721 (p));}#ifdef	__STDC__static intisonum_731 (unsigned char * p)#elsestatic intisonum_731 (p)	unsigned char * p;#endif{	return ((p[0] & 0xff)		| ((p[1] & 0xff) << 8)		| ((p[2] & 0xff) << 16)		| ((p[3] & 0xff) << 24));}#ifdef	__STDC__intisonum_733 (unsigned char * p)#elseintisonum_733 (p)	unsigned char * p;#endif{	return (isonum_731 (p));}FILE * in_image = NULL;#ifndef	USE_SCG/* * Don't define readsecs if mkisofs is linked with * the SCSI library. * readsecs() will be implemented as SCSI command in this case. * * Use global var in_image directly in readsecs() * the SCSI equivalent will not use a FILE* for I/O. * * The main point of this pointless abstraction is that Solaris won't let * you read 2K sectors from the cdrom driver.  The fact that 99.9% of the * discs out there have a 2K sectorsize doesn't seem to matter that much. * Anyways, this allows the use of a scsi-generics type of interface on * Solaris. */#ifdef	__STDC__static intreadsecs(int startsecno, void *buffer, int sectorcount)#elsestatic intreadsecs(startsecno, buffer, sectorcount)	int	startsecno;	void	*buffer;	int	sectorcount;#endif{	int	f = fileno(in_image);	if (lseek(f, (off_t)startsecno * SECTOR_SIZE, 0) == (off_t)-1) {#ifdef	USE_LIBSCHILY		comerr(" Seek error on old image\n");#else		fprintf(stderr," Seek error on old image\n");		exit(10);#endif	}	if( read(f, buffer, (sectorcount * SECTOR_SIZE))	    != (sectorcount * SECTOR_SIZE) )	{#ifdef	USE_LIBSCHILY		comerr(" Read error on old image\n");#else		fprintf(stderr," Read error on old image\n");		exit(10);#endif	}	return sectorcount * SECTOR_SIZE;}#endif/* * Parse the RR attributes so we can find the file name. */static int FDECL3(parse_rr, unsigned char *, pnt, int, len, struct directory_entry *,dpnt){	int cont_extent, cont_offset, cont_size;	char name_buf[256];	cont_extent = cont_offset = cont_size = 0;	while(len >= 4){		if(pnt[3] != 1 && pnt[3] != 2) {#ifdef	USE_LIBSCHILY		  errmsgno(EX_BAD, "**BAD RRVERSION (%d) for %c%c\n", pnt[3], pnt[0], pnt[1]);#else		  fprintf(stderr, "**BAD RRVERSION (%d) for %c%c\n", pnt[3], pnt[0], pnt[1]);#endif		  return -1;		};		if(strncmp((char *) pnt, "NM", 2) == 0) {		  strncpy(name_buf, (char *) pnt+5, pnt[2] - 5);		  name_buf[pnt[2] - 5] = 0;		  dpnt->name = strdup(name_buf);		  dpnt->got_rr_name = 1;		  return 0;		}		if(strncmp((char *) pnt, "CE", 2) == 0) {			cont_extent = isonum_733(pnt+4);			cont_offset = isonum_733(pnt+12);			cont_size = isonum_733(pnt+20);		};		len -= pnt[2];		pnt += pnt[2];		if(len <= 3 && cont_extent) {		  unsigned char sector[SECTOR_SIZE];		  readsecs(cont_extent, sector, 1);		  if (parse_rr(&sector[cont_offset], cont_size, dpnt) == -1)			return (-1);		};	};	/* Fall back to the iso name if no RR name found */	if (dpnt->name == NULL) {	  char *cp;	  strcpy(name_buf, dpnt->isorec.name);	  cp = strchr(name_buf, ';');	  if (cp != NULL) {	    *cp = '\0';	  }	  dpnt->name = strdup(name_buf);	}	return 0;} /* parse_rr *//* * Returns 1 if the two files are identical * Returns 0 if the two files differ */static int FDECL4(check_rr_dates, struct directory_entry *, dpnt,        struct directory_entry *, current,        struct stat *, statbuf,        struct stat *,lstatbuf){	int cont_extent, cont_offset, cont_size;	int offset;	unsigned char * pnt;	int len;	int same_file;	int same_file_type;	mode_t mode;	char time_buf[7];			cont_extent = cont_offset = cont_size = 0;	same_file = 1;	same_file_type = 1;	pnt = dpnt->rr_attributes;	len = dpnt->rr_attr_size;	/*	 * We basically need to parse the rr attributes again, and	 * dig out the dates and file types.	 */	while(len >= 4){		if(pnt[3] != 1 && pnt[3] != 2) {#ifdef	USE_LIBSCHILY		  errmsgno(EX_BAD, "**BAD RRVERSION (%d) for %c%c\n", pnt[3], pnt[0], pnt[1]);#else		  fprintf(stderr, "**BAD RRVERSION (%d) for %c%c\n", pnt[3], pnt[0], pnt[1]);#endif		  return -1;		};		/*		 * If we have POSIX file modes, make sure that the file type		 * is the same.  If it isn't, then we must always		 * write the new file.		 */		if(strncmp((char *) pnt, "PX", 2) == 0) {		  mode = isonum_733(pnt + 4);		  if( (lstatbuf->st_mode & S_IFMT) != (mode & S_IFMT) )		    {		      same_file_type = 0;		      same_file = 0;		    }		}		if(strncmp((char *) pnt, "TF", 2) == 0) {		  offset = 5;		  if( pnt[4] & TF_CREATE )		    {		      iso9660_date((char *) time_buf, lstatbuf->st_ctime);		      if(memcmp(time_buf, pnt+offset, 7) != 0) 			same_file = 0;		      offset += 7;		    }		  if( pnt[4] & TF_MODIFY )		    {		      iso9660_date((char *) time_buf, lstatbuf->st_mtime);		      if(memcmp(time_buf, pnt+offset, 7) != 0) 			same_file = 0;		      offset += 7;		    }		}		if(strncmp((char *) pnt, "CE", 2) == 0) {			cont_extent = isonum_733(pnt+4);			cont_offset = isonum_733(pnt+12);			cont_size = isonum_733(pnt+20);		};		len -= pnt[2];		pnt += pnt[2];		if(len <= 3 && cont_extent) {		  unsigned char sector[SECTOR_SIZE];		  readsecs(cont_extent, sector, 1);		  if (parse_rr(&sector[cont_offset], cont_size, dpnt) == -1)			return (-1);		};	};	/*	 * If we have the same fundamental file type, then it is clearly	 * safe to reuse the TRANS.TBL entry.	 */	if( same_file_type )	  {	    current->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY;	  }	return same_file;}struct directory_entry **FDECL2(read_merging_directory, struct iso_directory_record *, mrootp,       int *, nent){  unsigned char			* cpnt;  unsigned char			* cpnt1;  char				* dirbuff;  int				  i;  struct iso_directory_record	* idr;  int				  len;  int				  nbytes;  struct directory_entry	**pnt;  int				  rlen;  struct directory_entry	**rtn;  int				  seen_rockridge;  unsigned char			* tt_buf;  int				  tt_extent;  int				  tt_size;  static int warning_given = 0;  /*   * This is the number of sectors we will need to read.  We need to   * round up to get the last fractional sector - we are asking for   * the data in terms of a number of sectors.   */  nbytes = roundup(isonum_733((unsigned char *)mrootp->size), SECTOR_SIZE);  /*   * First, allocate a buffer large enough to read in the entire   * directory.   */  dirbuff = (char *) e_malloc(nbytes);  readsecs(isonum_733((unsigned char *)mrootp->extent), dirbuff,	   nbytes / SECTOR_SIZE);  /*   * Next look over the directory, and count up how many entries we   * have.   */  len = isonum_733((unsigned char *)mrootp->size);  i = 0;  *nent = 0;  while(i < len )    {      idr = (struct iso_directory_record *) &dirbuff[i];      if(idr->length[0] == 0) 	{	  i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1);	  continue;	}      (*nent)++;      i += idr->length[0];    }  /*   * Now allocate the buffer which will hold the array we are   * about to return.   */  rtn = (struct directory_entry **) e_malloc(*nent * sizeof(*rtn));  /*   * Finally, scan the directory one last time, and pick out the   * relevant bits of information, and store it in the relevant   * bits of the structure.   */  i = 0;  pnt = rtn;  tt_extent = 0;  seen_rockridge = 0;  tt_size = 0;  while(i < len )    {      idr = (struct iso_directory_record *) &dirbuff[i];      if(idr->length[0] == 0) 	{	  i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1);	  continue;	}      *pnt = (struct directory_entry *) e_malloc(sizeof(**rtn));      (*pnt)->next = NULL;      (*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;      /*

⌨️ 快捷键说明

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