genisovh-0.1/0040755000175000017500000000000007545076772011345 5ustar floflogenisovh-0.1/dvh.h0100644000175000017500000001575307460540247012274 0ustar floflo#ifndef _SYS_DVH_H #define _SYS_DVH_H /* * Format for volume header information * * The volume header is a block located at the beginning of all disk * media (sector 0). It contains information pertaining to physical * device parameters and logical partition information. * * The volume header is manipulated by disk formatters/verifiers, * partition builders (e.g. fx, dvhtool, and mkfs), and disk drivers. * * Previous versions of IRIX wrote a copy of the volume header is * located at sector 0 of each track of cylinder 0. These copies were * never used, and reduced the capacity of the volume header to hold large * files, so this practice was discontinued. * The volume header is constrained to be less than or equal to 512 * bytes long. A particular copy is assumed valid if no drive errors * are detected, the magic number is correct, and the 32 bit 2's complement * of the volume header is correct. The checksum is calculated by initially * zeroing vh_csum, summing the entire structure and then storing the * 2's complement of the sum. Thus a checksum to verify the volume header * should be 0. * * The error summary table, bad sector replacement table, and boot blocks are * located by searching the volume directory within the volume header. * * Tables are sized simply by the integral number of table records that * will fit in the space indicated by the directory entry. * * The amount of space allocated to the volume header, replacement blocks, * and other tables is user defined when the device is formatted. */ /* * device parameters are in the volume header to determine mapping * from logical block numbers to physical device addresses * * Linux doesn't care ... */ struct device_parameters { unsigned char dp_skew; /* spiral addressing skew */ unsigned char dp_gap1; /* words of 0 before header */ unsigned char dp_gap2; /* words of 0 between hdr and data */ unsigned char dp_spares_cyl; /* This is for drives (such as SCSI that support zone oriented sparing, where the zone is larger than one track. It gets subracteded from the cylinder size ( dp_trks0 * dp_sec) when doing partition size calculations */ unsigned short dp_cyls; /* number of usable cylinders (i.e., doesn't include cylinders reserved by the drive for badblocks, etc.). For drives with variable geometry, this number may be decreased so that: dp_cyls * ((dp_heads * dp_trks0) - dp_spares_cyl) <= actualcapacity This happens on SCSI drives such as the Wren IV and Toshiba 156 Also see dp_cylshi below */ unsigned short dp_shd0; /* starting head vol 0 */ unsigned short dp_trks0; /* number of tracks / cylinder vol 0*/ unsigned char dp_ctq_depth; /* Depth of CTQ queue */ unsigned char dp_cylshi; /* high byte of 24 bits of cylinder count */ unsigned short dp_unused; /* not used */ unsigned short dp_secs; /* number of sectors/track */ unsigned short dp_secbytes; /* length of sector in bytes */ unsigned short dp_interleave; /* sector interleave */ int dp_flags; /* controller characteristics */ int dp_datarate; /* bytes/sec for kernel stats */ int dp_nretries; /* max num retries on data error */ int dp_mspw; /* ms per word to xfer, for iostat */ unsigned short dp_xgap1; /* Gap 1 for xylogics controllers */ unsigned short dp_xsync; /* sync delay for xylogics controllers */ unsigned short dp_xrdly; /* read delay for xylogics controllers */ unsigned short dp_xgap2; /* gap 2 for xylogics controllers */ unsigned short dp_xrgate; /* read gate for xylogics controllers */ unsigned short dp_xwcont; /* write continuation for xylogics */ }; /* * Device characterization flags * (dp_flags) */ #define DP_SECTSLIP 0x00000001 /* sector slip to spare sector */ #define DP_SECTFWD 0x00000002 /* forward to replacement sector */ #define DP_TRKFWD 0x00000004 /* forward to replacement track */ #define DP_MULTIVOL 0x00000008 /* multiple volumes per spindle */ #define DP_IGNOREERRORS 0x00000010 /* transfer data regardless of errors */ #define DP_RESEEK 0x00000020 /* recalibrate as last resort */ #define DP_CTQ_EN 0x00000040 /* enable command tag queueing */ /* * Boot blocks, bad sector tables, and the error summary table, are located * via the volume_directory. */ #define VDNAMESIZE 8 struct volume_directory { char vd_name[VDNAMESIZE]; /* name */ int vd_lbn; /* logical block number */ int vd_nbytes; /* file length in bytes */ }; /* * partition table describes logical device partitions * (device drivers examine this to determine mapping from logical units * to cylinder groups, device formatters/verifiers examine this to determine * location of replacement tracks/sectors, etc) * * NOTE: pt_firstlbn SHOULD BE CYLINDER ALIGNED */ struct partition_table { /* one per logical partition */ int pt_nblks; /* # of logical blks in partition */ int pt_firstlbn; /* first lbn of partition */ int pt_type; /* use of partition */ }; #define PTYPE_VOLHDR 0 /* partition is volume header */ #define PTYPE_TRKREPL 1 /* partition is used for repl trks */ #define PTYPE_SECREPL 2 /* partition is used for repl secs */ #define PTYPE_RAW 3 /* partition is used for data */ #define PTYPE_BSD42 4 /* partition is 4.2BSD file system */ #define PTYPE_BSD 4 /* partition is 4.2BSD file system */ #define PTYPE_SYSV 5 /* partition is SysV file system */ #define PTYPE_VOLUME 6 /* partition is entire volume */ #define PTYPE_EFS 7 /* partition is sgi EFS */ #define PTYPE_LVOL 8 /* partition is part of a logical vol */ #define PTYPE_RLVOL 9 /* part of a "raw" logical vol */ #define PTYPE_XFS 10 /* partition is sgi XFS */ #define PTYPE_XFSLOG 11 /* partition is sgi XFS log */ #define PTYPE_XLV 12 /* partition is part of an XLV vol */ #define PTYPE_XVM 13 /* partition is sgi XVM */ #define PTYPE_LSWAP 0x82 /* partition is Linux swap */ #define PTYPE_LINUX 0x83 /* partition is Linux native */ #define NPTYPES 16 #define VHMAGIC 0xbe5a941 /* randomly chosen value */ #define NPARTAB 16 /* 16 unix partitions */ #define NVDIR 15 /* max of 15 directory entries */ #define BFNAMESIZE 16 /* max 16 chars in boot file name */ /* Partition types for ARCS */ #define NOT_USED 0 /* Not used */ #define FAT_SHORT 1 /* FAT filesystem, 12-bit FAT entries */ #define FAT_LONG 4 /* FAT filesystem, 16-bit FAT entries */ #define EXTENDED 5 /* extended partition */ #define HUGE 6 /* huge partition- MS/DOS 4.0 and later */ /* Active flags for ARCS */ #define BOOTABLE 0x00; #define NOT_BOOTABLE 0x80; struct volume_header { int vh_magic; /* identifies volume header */ short vh_rootpt; /* root partition number */ short vh_swappt; /* swap partition number */ char vh_bootfile[BFNAMESIZE]; /* name of file to boot */ struct device_parameters vh_dp; /* device parameters */ struct volume_directory vh_vd[NVDIR]; /* other vol hdr contents */ struct partition_table vh_pt[NPARTAB]; /* device partition layout */ int vh_csum; /* volume header checksum */ int vh_fill; /* fill out to 512 bytes */ }; #endif /* _SYS_DVH_H */ genisovh-0.1/Makefile0100644000175000017500000000016307460540503012762 0ustar floflo CFLAGS=-O0 -g CC=gcc LDFLAGS= OBJS=main.o genisovh: $(OBJS) gcc -o $@ $+ clean: rm -f $(OBJS) genisovh core genisovh-0.1/main.c0100644000175000017500000000646607545076757012451 0ustar floflo #include #include #include #include #include #include #include #include #include #include #include "dvh.h" #if 1 #define SECTORS_PER_TRACK 32 #define BYTES_PER_SECTOR 512 #else #define SECTORS_PER_TRACK 8 #define BYTES_PER_SECTOR 2048 #endif #define __u16 unsigned short #define __u32 unsigned int #define swab16(x) \ ({ \ __u16 __x = (x); \ ((__u16)( \ (((__u16)(__x) & (__u16)0x00ffU) << 8) | \ (((__u16)(__x) & (__u16)0xff00U) >> 8) )); \ }) #define swab32(x) \ ({ \ __u32 __x = (x); \ ((__u32)( \ (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \ (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \ (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \ (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \ }) #if __BYTE_ORDER == __LITTLE_ENDIAN #define be32_to_cpu(x) swab32((x)) #define be16_to_cpu(x) swab16((x)) #define cpu_to_be32(x) swab32((x)) #define cpu_to_be16(x) swab16((x)) #else #define be32_to_cpu(x) ((__u32)(x)) #define be16_to_cpu(x) ((__u16)(x)) #define cpu_to_be32(x) ((__u32)(x)) #define cpu_to_be16(x) ((__u16)(x)) #endif __u32 vh_calc_checksum(struct volume_header *vh) { __u32 oldchecksum, newsum=0, *buffer=(__u32 *) vh; int i; oldchecksum=vh->vh_csum; vh->vh_csum=0; for(i=0;ivh_csum=oldchecksum; return(newsum); } void usage(void ) { printf("Usage:\ngenisovh ... \n"); exit(1); } int main(int argc, char **argv) { int fd, i, v, block, size; char *isoname, *cline, *pos; struct stat st; struct volume_header vh; if (argc < 2) usage(); isoname=argv[1]; if (!(fd=open(isoname, O_RDWR))) { printf("File not found %s\n", isoname); exit(1); } if (fstat(fd, &st)) { printf("Failed to stat file %s\n", isoname); close(fd); exit(1); } memset(&vh, 0, sizeof(struct volume_header)); vh.vh_magic = cpu_to_be32(VHMAGIC); /* Values from an IRIX cd */ vh.vh_dp.dp_secbytes=cpu_to_be16(BYTES_PER_SECTOR); vh.vh_dp.dp_secs=cpu_to_be16(SECTORS_PER_TRACK); vh.vh_dp.dp_flags=cpu_to_be32(DP_RESEEK|DP_IGNOREERRORS|DP_TRKFWD); vh.vh_dp.dp_trks0=cpu_to_be16(1); vh.vh_dp.dp_cyls=cpu_to_be16((st.st_size + BYTES_PER_SECTOR - 1) / (SECTORS_PER_TRACK*BYTES_PER_SECTOR)); for(i=2,v=0;i