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

📄 isofs.c

📁 LINUX 下, 以 QT/KDE 写的档案管理员
💻 C
📖 第 1 页 / 共 2 页
字号:
				} else if (f & 4) {
					rrentry->t_atime=rrctime(f,c);
					f &= ~4;
				} else if (f & 8) {
					rrentry->t_ctime=rrctime(f,c);
					f &= ~8;
				} else if (f & 16) {
					rrentry->t_backup=rrctime(f,c);
					f &= ~16;
				} else if (f & 32) {
					rrentry->t_expire=rrctime(f,c);
					f &= ~32;
				} else if (f & 64) {
					rrentry->t_effect=rrctime(f,c);
					f &= ~64;
				}

				i -= rrtlen(f);
				c += rrtlen(f);
			}
			ret++;

		} else if (rr->signature[0]=='Z' && rr->signature[1]=='F' && 
			isonum_711(&rr->len)==16) {
				/* Linux-specific extension: transparent decompression */
				rrentry->z_algo[0]=rr->u.ZF.algorithm[0];
				rrentry->z_algo[1]=rr->u.ZF.algorithm[1];
				rrentry->z_params[0]=rr->u.ZF.parms[0];
				rrentry->z_params[1]=rr->u.ZF.parms[1];
				rrentry->z_size=isonum_733(rr->u.ZF.real_size);
				ret++;
		} else {
/*			printf("SUSP sign: %c%c\n",rr->signature[0],rr->signature[1]); */
		}
		
		susplen -= isonum_711(&rr->len);
		r += isonum_711(&rr->len);
		rr = (struct rock_ridge*) r;
	}

	return ret;
}

/**
 * Iterates over the directory entries. The directory is in 'buf',
 * the size of the directory is 'size'. 'callback' is called for each
 * directory entry with the parameter 'udata'.
 */
int ProcessDir(readfunc *read,int extent,int size,dircallback *callback,void *udata) {

	int pos=0,ret=0,siz;
	char *buf;
	struct iso_directory_record *idr;

	if (size & 2047) {
		siz=((size>>11)+1)<<11;
	} else {
		siz=size;
	}

	buf=(char*) malloc(siz);
	if (!buf) return -ENOMEM;
	if (read(buf,extent,siz>>11,udata)!=siz>>11) {
		free(buf);
		return -EIO;
	}

	while (size>0) {
		idr=(struct iso_directory_record*) &buf[pos];
		if (isonum_711(idr->length)==0) {

			size-=(2048 - (pos & 0x7ff));
			if (size<=2) break;
			pos+=0x800;
			pos&=0xfffff800;
			idr=(struct iso_directory_record*) &buf[pos];
		}
		pos+=isonum_711(idr->length);
		pos+=isonum_711(idr->ext_attr_length);
		size-=isonum_711(idr->length);
		size-=isonum_711(idr->ext_attr_length);
		if (size<0) break;
		
		if (isonum_711(idr->length)
<33 ||
			isonum_711(idr->length)<33+isonum_711(idr->name_len)) {
			/* Invalid directory entry */			
			continue;
		}
		if ((ret=callback(idr,udata))) break;
	}

	free(buf);
	return ret;	
}

/**
 * returns the joliet level from the volume descriptor
 */
int JolietLevel(struct iso_volume_descriptor *ivd) {
	int ret=0;
	register struct iso_supplementary_descriptor *isd;
	
	isd = (struct iso_supplementary_descriptor *) ivd;
	
	if (isonum_711(ivd->type)==ISO_VD_SUPPLEMENTARY) {
		if (isd->escape[0]==0x25 && 
			isd->escape[1]==0x2f) {

			switch (isd->escape[2]) {
				case 0x40:
					ret=1;
					break;
				case 0x43:
					ret=2;
					break;
				case 0x45:
					ret=3;
					break;
			}
		}
	}
	return ret;
}

/********************************************************************/
#ifdef ISOFS_MAIN

#include <time.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <iconv.h>

int level=0,joliet=0,dirs,files;
iconv_t iconv_d;
int fd;

int readf(char *buf, int start, int len,void *udata) {
	int ret;
	
	if ((ret=lseek(fd, start << 11, SEEK_SET))<0) return ret;
	ret=read(fd, buf, len << 11);
	if (ret<0) return ret;
	return (ret >> 11);
}

void dumpchars(char *c,int len) {
	while (len>0) {
		printf("%c",*c);
		len--;
		c++;
	}	
}

void sp(int num) {
	int i;
	for (i=0;i<num*5;i++) { printf(" "); };
}

void dumpflags(char flags) {
	if (flags & 1) printf("HIDDEN ");
	if (flags & 2) printf("DIR ");
	if (flags & 4) printf("ASF ");
}

void dumpjoliet(char *c,int len) {

	char outbuf[255];
	size_t out;
	int ret;
	char *outptr;
	
	outptr=(char*) &outbuf;
	out=255;
	if ((iconv(iconv_d,&c,&len,&outptr,&out))<0) {
		printf("conversion error=%d",errno);
		return;
	}
	ret=255-out;
	dumpchars((char*) &outbuf,ret);
}

void dumpchardesc(char *c,int len) {

	if (joliet) 
		dumpjoliet(c,len);
	else {
		dumpchars(c,len);
	}
}

void dumpiso915time(char *t, int hs) {
	
	time_t time;
	char *c;
	
	time=isodate_915(t,hs);
	c=(char*) ctime(&time);
	if (c && c[strlen(c)-1]==0x0a) c[strlen(c)-1]=0;
	if (c) printf("%s",c);
}

void dumpiso84261time(char *t, int hs) {
	
	time_t time;
	char *c;
	
	time=isodate_84261(t,hs);
	c=(char*) ctime(&time);
	if (c && c[strlen(c)-1]==0x0a) c[strlen(c)-1]=0;
	if (c) printf("%s",c);
}

void dumpdirrec(struct iso_directory_record *dir) {
	
	if (isonum_711(dir->name_len)==1) {
		switch (dir->name[0]) {
		case 0:
			printf(".");
			break;
		case 1:
			printf("..");
			break;
		default:
			printf("%c",dir->name[0]);	
			break;
		}
	}
	dumpchardesc(dir->name,isonum_711(dir->name_len));
	printf(" size=%d",isonum_733(dir->size));
	printf(" extent=%d ",isonum_733(dir->extent));
	dumpflags(isonum_711(dir->flags));
	dumpiso915time((char*) &(dir->date),0);
}

void dumprrentry(rr_entry *rr) {
	printf("  NM=[%s] uid=%d gid=%d nlink=%d mode=%o ",
		rr->name,rr->uid,rr->gid,rr->nlink,rr->mode);
	if (S_ISCHR(rr->mode) || S_ISBLK(rr->mode))
		printf("major=%d minor=%d ",rr->dev_major,rr->dev_minor);
	if (rr->mode & S_IFLNK && rr->sl) printf("slink=%s ",rr->sl);
/*
	printf("\n");
	if (rr->t_creat) printf("t_creat: %s",ctime(&rr->t_creat));
	if (rr->st_mtime) printf("st_mtime: %s",ctime(&rr->st_mtime));
	if (rr->st_atime) printf("st_atime: %s",ctime(&rr->st_atime));
	if (rr->st_ctime) printf("st_ctime: %s",ctime(&rr->st_ctime));
	if (rr->t_backup) printf("t_backup: %s",ctime(&rr->t_backup));
	if (rr->t_expire) printf("t_expire: %s",ctime(&rr->t_expire));
	if (rr->t_effect) printf("t_effect: %s",ctime(&rr->t_effect));
*/
}

void dumpsusp(char *c, int len) {
	dumpchars(c,len);
}

void dumpboot(struct el_torito_boot_descriptor *ebd) {
	printf("version: %d\n",isonum_711(ebd->version));
	printf("system id: ");dumpchars(ebd->system_id,ISODCL(8,39));printf("\n");
	printf("boot catalog start: %d\n",isonum_731(ebd->boot_catalog));
}

void dumpdefentry(struct default_entry *de) {
	printf("Default entry: \n");
	printf("  bootid=%x\n",isonum_711(de->bootid));
	printf("  media emulation=%d (",isonum_711(de->media));
	switch(isonum_711(de->media) & 0xf) {
		case 0:
			printf("No emulation");
			break;
		case 1:
			printf("1.2 Mb floppy");
			break;
		case 2:
			printf("1.44 Mb floppy");
			break;
		case 3:
			printf("2.88 Mb floppy");
			break;
		case 4:
			printf("Hard Disk");
			break;
		default:
			printf("Unknown/Invalid");
			break;
	}	
	printf(")\n");
	printf("  loadseg=%d\n",isonum_721(de->loadseg));
	printf("  systype=%d\n",isonum_711(de->systype));
	printf("  start lba=%d count=%d\n",isonum_731(de->start),
		isonum_721(de->seccount));
}

void dumpbootcat(boot_head *bh) {
	boot_entry *be;

	printf("System id: ");dumpchars(bh->ventry.id,ISODCL(28,5));printf("\n");
	be=bh->defentry;
	while (be) {
		dumpdefentry(be->data);
		be=be->next;
	}
}

void dumpdesc(struct iso_primary_descriptor *ipd) {

	printf("system id: ");dumpchardesc(ipd->system_id,ISODCL(9,40));printf("\n");
	printf("volume id: ");dumpchardesc(ipd->volume_id,ISODCL(41,72));printf("\n");
	printf("volume space size: %d\n",isonum_733(ipd->volume_space_size));
	printf("volume set size: %d\n",isonum_723(ipd->volume_set_size));
	printf("volume seq num: %d\n",isonum_723(ipd->volume_set_size));
	printf("logical block size: %d\n",isonum_723(ipd->logical_block_size));
	printf("path table size: %d\n",isonum_733(ipd->path_table_size));
	printf("location of type_l path table: %d\n",isonum_731(ipd->type_l_path_table));
	printf("location of optional type_l path table: %d\n",isonum_731(ipd->opt_type_l_path_table));
	printf("location of type_m path table: %d\n",isonum_732(ipd->type_m_path_table));		
	printf("location of optional type_m path table: %d\n",isonum_732(ipd->opt_type_m_path_table));		
/*
	printf("Root dir record:\n");dumpdirrec((struct iso_directory_record*) &ipd->root_directory_record);
*/
	printf("Volume set id: ");dumpchardesc(ipd->volume_set_id,ISODCL(191,318));printf("\n");
	printf("Publisher id: ");dumpchardesc(ipd->publisher_id,ISODCL(319,446));printf("\n");
	printf("Preparer id: ");dumpchardesc(ipd->preparer_id,ISODCL(447,574));printf("\n");
	printf("Application id: ");dumpchardesc(ipd->application_id,ISODCL(575,702));printf("\n");
	printf("Copyright id: ");dumpchardesc(ipd->copyright_file_id,ISODCL(703,739));printf("\n");
	printf("Abstract file id: ");dumpchardesc(ipd->abstract_file_id,ISODCL(740,776));printf("\n");
	printf("Bibliographic file id: ");dumpchardesc(ipd->bibliographic_file_id,ISODCL(777,813));printf("\n");
	printf("Volume creation date: ");dumpiso84261time(ipd->creation_date,0);printf("\n");
	printf("Volume modification date: ");dumpiso84261time(ipd->modification_date,0);printf("\n");
	printf("Volume expiration date: ");dumpiso84261time(ipd->expiration_date,0);printf("\n");
	printf("Volume effective date: ");dumpiso84261time(ipd->effective_date,0);printf("\n");
	printf("File structure version: %d\n",isonum_711(ipd->file_structure_version));
}

int mycallb(struct iso_directory_record *idr,void *udata) {
	rr_entry rrentry;

	sp(level);dumpdirrec(idr);
	if (level==0) printf(" (Root directory) ");
	printf("\n");
	
	if (ParseRR(idr,&rrentry)>0) {
		sp(level);printf("  ");dumprrentry(&rrentry);printf("\n");
	}
	FreeRR(&rrentry);
	if ( !(idr->flags[0] & 2) ) files++;
	if ( (idr->flags[0] & 2) && (level==0 || isonum_711(idr->name_len)>1) ) {
		level++;
		dirs++;
		ProcessDir(&readf,isonum_733(idr->extent),isonum_733(idr->size),&mycallb,udata);
		level--;
	}
	return 0;
}

/************************************************/

int main(int argc, char *argv[]) {
	
	int i=1,sector=0;
	iso_vol_desc *desc;
	boot_head boot;
	
	if (argc<2) {
		fprintf(stderr,"\nUsage: %s iso-file-name or device [starting sector]\n\n",argv[0]);
		return 0;
	}
	if (argc>=3) {
		sector=atoi(argv[2]);
		printf("Using starting sector number %d\n",sector);
	}
	fd=open(argv[1],O_RDONLY);
	if (fd<0) {
		fprintf(stderr,"open error\n");
		return -1;
	}
	iconv_d=iconv_open("ISO8859-2","UTF16BE");
	if (iconv_d==0) {
		fprintf(stderr,"iconv open error\n");
		return -1;
	}
	
	desc=ReadISO9660(&readf,sector,NULL);
	if (!desc) {
		printf("No volume descriptors\n");
		return -1;
	}
	while (desc) {
		
		printf("\n\n--------------- Volume descriptor (%d.) type %d: ---------------\n\n",
			i,isonum_711(desc->data.type));
		switch (isonum_711(desc->data.type)) {
			case ISO_VD_BOOT: {

				struct el_torito_boot_descriptor* bootdesc;
				bootdesc=&(desc->data);
				dumpboot(bootdesc);
				if ( !memcmp(EL_TORITO_ID,bootdesc->system_id,ISODCL(8,39)) ) {
					
					if (ReadBootTable(&readf,isonum_731(bootdesc->boot_catalog),&boot,NULL)) {
						printf("Boot Catalog Error\n");
					} else {
						dumpbootcat(&boot);
						FreeBootTable(&boot);
					}
				}
			}
				break;

			case ISO_VD_PRIMARY:
			case ISO_VD_SUPPLEMENTARY:
				joliet=0;
				joliet = JolietLevel(&desc->data);
				printf("Joliet level: %d\n",joliet);
				dumpdesc((struct iso_primary_descriptor*) &desc->data);
				printf("\n\n--------------- Directory structure: -------------------\n\n");
				dirs=0;files=0;
				mycallb( &( ((struct iso_primary_descriptor*) &desc->data)->root_directory_record), NULL );
				printf("\nnumber of directories: %d\n",dirs);
				printf("\nnumber of files: %d\n",files);
				break;

		}
		desc=desc->next;
		i++;
	}
	iconv_close(iconv_d);
	close(fd);
	FreeISO9660(desc);
	return 0;
}

#endif /* ISOFS_MAIN */

⌨️ 快捷键说明

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