summaryrefslogtreecommitdiff
path: root/gnu/usr.sbin/mkisofs/diag
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.sbin/mkisofs/diag')
-rw-r--r--gnu/usr.sbin/mkisofs/diag/README78
-rw-r--r--gnu/usr.sbin/mkisofs/diag/dump.c205
-rw-r--r--gnu/usr.sbin/mkisofs/diag/isodump.c478
-rw-r--r--gnu/usr.sbin/mkisofs/diag/isoinfo.8125
-rw-r--r--gnu/usr.sbin/mkisofs/diag/isoinfo.c554
-rw-r--r--gnu/usr.sbin/mkisofs/diag/isovfy.c514
6 files changed, 1954 insertions, 0 deletions
diff --git a/gnu/usr.sbin/mkisofs/diag/README b/gnu/usr.sbin/mkisofs/diag/README
new file mode 100644
index 00000000000..92315118f7a
--- /dev/null
+++ b/gnu/usr.sbin/mkisofs/diag/README
@@ -0,0 +1,78 @@
+# $OpenBSD: README,v 1.1 1997/09/15 06:01:53 downsj Exp $
+#
+# $From: README,v 1.1 1997/02/23 16:14:56 eric Rel $
+#
+ I am enclosing 3 test programs that I use to verify the
+integrity of an iso9660 disc. The first one (isodump) is pretty
+simple - it dumps to the screen the contents of the various
+directories. The second one (isovfy) goes through and looks for
+problems of one kind or another.
+
+ To use, type something like "./isodump /dev/ramdisk" or
+"./isodump /dev/scd0", depending upon where the iso9660 disc is. It
+starts by displaying the files in the first sector of the root
+directory. It has some pretty simple one letter commands that you
+can use to traverse the directory tree.
+
+ a - move back one sector.
+ b - move forward one sector.
+ g - go to new logical sector.
+ q - quit
+
+The a and b commands do not try and stop you from going past the
+beginning or end of a sector, and the g command does not have any way
+of knowing whether the sector you request is actually a directory or
+not.
+
+ The output is displayed in several columns. The first column
+is the total length of the directory record for the file. The second
+column (in [] brackets) is the volume number. Next comes the starting
+extent number (in hex), and then comes the file size in bytes. Then
+cones the filename (not the Rock Ridge version), and this is preceeded
+by an "*" if the file is a directory. After this is a summary of the
+Rock Ridge fields present along with a display of the translation of
+the symbolic link name if the SL Rock Ridge record is present.
+
+ I tailored this program for debugging some of the problems
+that I was having earlier. The idea is that you can tailor it
+to test for problems that you might be having, so it is not intended
+as a be-all and end-all dump program.
+
+ If you move to a sector that does not contain directory
+information, the results are unpredictable.
+
+ The second program, isovfy, is run in the same way as isodump,
+except that you do not have to do much except let it run. I have it
+written to verify all kinds of different things, and as people find
+other sorts of problems other tests could be added.
+
+ The third program, dump.c, basically does a hexdump of the cd.
+This is screen oriented, and there are some simple commands:
+
+ a - move back one sector.
+ b - move forward one sector.
+ f - enter new search string.
+ + - search forward for search string.
+ g - go to new logical sector.
+ q - quit
+
+
+ Note that with the 'g' command, sectors are always given in
+hex, and represent 2048 byte sectors (as on the cdrom). If you know
+how to decode a raw iso9660 directory, you can pick out the starting
+extent number from the hexdump and know where to go from there. The
+starting extent appears something like 30 bytes prior to the start of
+the iso9660 (not Rock Ridge) filename, and it appears in a 7.3.3
+format (meaning that it occupies 8 bytes, 4 in little endian format,
+and 4 in big endian format). Thus you should see a mirror image of
+the bytes when looking at the extent number.
+
+ The isovfy program can also dump the contents of the path
+tables, but this capability is commented out right now. Feel free
+to enable this to see what is in the tables. Ultimately I may fix
+it so that this checks the integrity of the tables as well.
+
+ The isovfy program gives warnings about things like files that
+have a size of 0 but have an extent number assigned. The mkisofs program
+should never do this, but the YM software does leave these around.
+I think it is probably harmless in the YM case.~
diff --git a/gnu/usr.sbin/mkisofs/diag/dump.c b/gnu/usr.sbin/mkisofs/diag/dump.c
new file mode 100644
index 00000000000..be97d711482
--- /dev/null
+++ b/gnu/usr.sbin/mkisofs/diag/dump.c
@@ -0,0 +1,205 @@
+/* $OpenBSD: dump.c,v 1.1 1997/09/15 06:01:53 downsj Exp $ */
+/*
+ * File dump.c - dump a file/device both in hex and in ASCII.
+
+ Written by Eric Youngdale (1993).
+
+ Copyright 1993 Yggdrasil Computing, 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. */
+
+static char rcsid[] ="$From: dump.c,v 1.2 1997/02/23 19:10:49 eric Rel $";
+
+#include "../config.h"
+
+#include <stdio.h>
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#include <sys/ioctl.h>
+#else
+#include <termio.h>
+#endif
+#include <signal.h>
+
+FILE * infile;
+int file_addr;
+unsigned char buffer[256];
+unsigned char search[64];
+
+#define PAGE 256
+
+#ifdef HAVE_TERMIOS_H
+struct termios savetty;
+struct termios newtty;
+#else
+struct termio savetty;
+struct termio newtty;
+#endif
+
+reset_tty(){
+#ifdef HAVE_TERMIOS_H
+ if(tcsetattr(0, TCSANOW, &savetty) == -1)
+#else
+ if(ioctl(0, TCSETAF, &savetty)==-1)
+#endif
+ {
+ printf("cannot put tty into normal mode\n");
+ exit(1);
+ }
+}
+
+set_tty(){
+#ifdef HAVE_TERMIOS_H
+ if(tcsetattr(0, TCSANOW, &newtty) == -1)
+#else
+ if(ioctl(0, TCSETAF, &newtty)==-1)
+#endif
+ {
+ printf("cannot put tty into raw mode\n");
+ exit(1);
+ }
+}
+
+
+/* Come here when we get a suspend signal from the terminal */
+
+void
+onsusp (int sig)
+{
+ /* ignore SIGTTOU so we don't get stopped if csh grabs the tty */
+ signal(SIGTTOU, SIG_IGN);
+ reset_tty ();
+ fflush (stdout);
+ signal(SIGTTOU, SIG_DFL);
+ /* Send the TSTP signal to suspend our process group */
+ signal(SIGTSTP, SIG_DFL);
+/* sigsetmask(0);*/
+ kill (0, SIGTSTP);
+ /* Pause for station break */
+
+ /* We're back */
+ signal (SIGTSTP, onsusp);
+ set_tty ();
+}
+
+
+
+crsr2(int row, int col){
+ printf("\033[%d;%dH",row,col);
+}
+
+showblock(int flag){
+ unsigned int k;
+ int i, j;
+ lseek(fileno(infile), file_addr, 0);
+ read(fileno(infile), buffer, sizeof(buffer));
+ if(flag) {
+ for(i=0;i<16;i++){
+ crsr2(i+3,1);
+ printf("%8.8x ",file_addr+(i<<4));
+ for(j=15;j>=0;j--){
+ printf("%2.2x",buffer[(i<<4)+j]);
+ if(!(j & 0x3)) printf(" ");
+ };
+ for(j=0;j< 16;j++){
+ k = buffer[(i << 4) + j];
+ if(k >= ' ' && k < 0x80) printf("%c",k);
+ else printf(".");
+ };
+ }
+ };
+ crsr2(20,1);
+ printf(" Zone, zone offset: %6x %4.4x ",file_addr>>11, file_addr & 0x7ff);
+ fflush(stdout);
+}
+
+getbyte()
+{
+ char c1;
+ c1 = buffer[file_addr & (PAGE-1)];
+ file_addr++;
+ if ((file_addr & (PAGE-1)) == 0) showblock(0);
+ return c1;
+}
+
+main(int argc, char * argv[]){
+ char c;
+ int nbyte;
+ int i,j;
+ if(argc < 2) return 0;
+ infile = fopen(argv[1],"rb");
+ for(i=0;i<30;i++) printf("\n");
+ file_addr = 0;
+/* Now setup the keyboard for single character input. */
+#ifdef HAVE_TERMIOS_H
+ if(tcgetattr(0, &savetty) == -1)
+#else
+ if(ioctl(0, TCGETA, &savetty) == -1)
+#endif
+ {
+ printf("stdin must be a tty\n");
+ exit(1);
+ }
+ newtty=savetty;
+ newtty.c_lflag&=~ICANON;
+ newtty.c_lflag&=~ECHO;
+ newtty.c_cc[VMIN]=1;
+ set_tty();
+ signal(SIGTSTP, onsusp);
+
+ do{
+ if(file_addr < 0) file_addr = 0;
+ showblock(1);
+ read (0, &c, 1);
+ if (c == 'a') file_addr -= PAGE;
+ if (c == 'b') file_addr += PAGE;
+ if (c == 'g') {
+ crsr2(20,1);
+ printf("Enter new starting block (in hex):");
+ scanf("%x",&file_addr);
+ file_addr = file_addr << 11;
+ crsr2(20,1);
+ printf(" ");
+ };
+ if (c == 'f') {
+ crsr2(20,1);
+ printf("Enter new search string:");
+ fgets(search,sizeof(search),stdin);
+ while(search[strlen(search)-1] == '\n') search[strlen(search)-1] = 0;
+ crsr2(20,1);
+ printf(" ");
+ };
+ if (c == '+') {
+ while(1==1){
+ while(1==1){
+ c = getbyte(&file_addr);
+ if (c == search[0]) break;
+ };
+ for (j=1;j<strlen(search);j++)
+ if(search[j] != getbyte()) break;
+ if(j==strlen(search)) break;
+ };
+ file_addr &= ~(PAGE-1);
+ showblock(1);
+ };
+ if (c == 'q') break;
+ } while(1==1);
+ reset_tty();
+ fclose(infile);
+}
+
+
+
+
diff --git a/gnu/usr.sbin/mkisofs/diag/isodump.c b/gnu/usr.sbin/mkisofs/diag/isodump.c
new file mode 100644
index 00000000000..f15dae69b64
--- /dev/null
+++ b/gnu/usr.sbin/mkisofs/diag/isodump.c
@@ -0,0 +1,478 @@
+/* $OpenBSD: isodump.c,v 1.1 1997/09/15 06:01:53 downsj Exp $ */
+/*
+ * File isodump.c - dump iso9660 directory information.
+ *
+
+ Written by Eric Youngdale (1993).
+
+ Copyright 1993 Yggdrasil Computing, 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. */
+
+static char rcsid[] ="$From: isodump.c,v 1.2 1997/02/23 19:11:24 eric Rel $";
+
+#include "../config.h"
+
+#include <stdio.h>
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#include <sys/ioctl.h>
+#else
+#include <termio.h>
+#endif
+#include <signal.h>
+
+FILE * infile;
+int file_addr;
+unsigned char buffer[2048];
+unsigned char search[64];
+int blocksize;
+
+#define PAGE sizeof(buffer)
+
+#define ISODCL(from, to) (to - from + 1)
+
+
+int
+isonum_731 (char * p)
+{
+ return ((p[0] & 0xff)
+ | ((p[1] & 0xff) << 8)
+ | ((p[2] & 0xff) << 16)
+ | ((p[3] & 0xff) << 24));
+}
+
+int
+isonum_721 (char * p)
+{
+ return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
+}
+
+int
+isonum_723 (char * p)
+{
+#if 0
+ if (p[0] != p[3] || p[1] != p[2]) {
+ fprintf (stderr, "invalid format 7.2.3 number\n");
+ exit (1);
+ }
+#endif
+ return (isonum_721 (p));
+}
+
+
+int
+isonum_733 (unsigned char * p)
+{
+ return (isonum_731 (p));
+}
+
+struct iso_primary_descriptor {
+ unsigned char type [ISODCL ( 1, 1)]; /* 711 */
+ unsigned char id [ISODCL ( 2, 6)];
+ unsigned char version [ISODCL ( 7, 7)]; /* 711 */
+ unsigned char unused1 [ISODCL ( 8, 8)];
+ unsigned char system_id [ISODCL ( 9, 40)]; /* aunsigned chars */
+ unsigned char volume_id [ISODCL ( 41, 72)]; /* dunsigned chars */
+ unsigned char unused2 [ISODCL ( 73, 80)];
+ unsigned char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
+ unsigned char unused3 [ISODCL ( 89, 120)];
+ unsigned char volume_set_size [ISODCL (121, 124)]; /* 723 */
+ unsigned char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
+ unsigned char logical_block_size [ISODCL (129, 132)]; /* 723 */
+ unsigned char path_table_size [ISODCL (133, 140)]; /* 733 */
+ unsigned char type_l_path_table [ISODCL (141, 144)]; /* 731 */
+ unsigned char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
+ unsigned char type_m_path_table [ISODCL (149, 152)]; /* 732 */
+ unsigned char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
+ unsigned char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
+ unsigned char volume_set_id [ISODCL (191, 318)]; /* dunsigned chars */
+ unsigned char publisher_id [ISODCL (319, 446)]; /* achars */
+ unsigned char preparer_id [ISODCL (447, 574)]; /* achars */
+ unsigned char application_id [ISODCL (575, 702)]; /* achars */
+ unsigned char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
+ unsigned char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
+ unsigned char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
+ unsigned char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
+ unsigned char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
+ unsigned char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
+ unsigned char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
+ unsigned char file_structure_version [ISODCL (882, 882)]; /* 711 */
+ unsigned char unused4 [ISODCL (883, 883)];
+ unsigned char application_data [ISODCL (884, 1395)];
+ unsigned char unused5 [ISODCL (1396, 2048)];
+};
+
+struct iso_directory_record {
+ unsigned char length [ISODCL (1, 1)]; /* 711 */
+ unsigned char ext_attr_length [ISODCL (2, 2)]; /* 711 */
+ unsigned char extent [ISODCL (3, 10)]; /* 733 */
+ unsigned char size [ISODCL (11, 18)]; /* 733 */
+ unsigned char date [ISODCL (19, 25)]; /* 7 by 711 */
+ unsigned char flags [ISODCL (26, 26)];
+ unsigned char file_unit_size [ISODCL (27, 27)]; /* 711 */
+ unsigned char interleave [ISODCL (28, 28)]; /* 711 */
+ unsigned char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
+ unsigned char name_len [ISODCL (33, 33)]; /* 711 */
+ unsigned char name [1];
+};
+
+#ifdef HAVE_TERMIOS_H
+struct termios savetty;
+struct termios newtty;
+#else
+struct termio savetty;
+struct termio newtty;
+#endif
+
+reset_tty(){
+#ifdef HAVE_TERMIOS_H
+ if(tcsetattr(0, TCSANOW, &savetty) == -1)
+#else
+ if(ioctl(0, TCSETAF, &savetty)==-1)
+#endif
+ {
+ printf("cannot put tty into normal mode\n");
+ exit(1);
+ }
+}
+
+set_tty(){
+#ifdef HAVE_TERMIOS_H
+ if(tcsetattr(0, TCSANOW, &newtty) == -1)
+#else
+ if(ioctl(0, TCSETAF, &newtty)==-1)
+#endif
+ {
+ printf("cannot put tty into raw mode\n");
+ exit(1);
+ }
+}
+
+/* Come here when we get a suspend signal from the terminal */
+
+void
+onsusp (int signo)
+{
+ /* ignore SIGTTOU so we don't get stopped if csh grabs the tty */
+ signal(SIGTTOU, SIG_IGN);
+ reset_tty ();
+ fflush (stdout);
+ signal(SIGTTOU, SIG_DFL);
+ /* Send the TSTP signal to suspend our process group */
+ signal(SIGTSTP, SIG_DFL);
+/* sigsetmask(0);*/
+ kill (0, SIGTSTP);
+ /* Pause for station break */
+
+ /* We're back */
+ signal (SIGTSTP, onsusp);
+ set_tty ();
+}
+
+
+
+crsr2(int row, int col){
+ printf("\033[%d;%dH",row,col);
+}
+
+int parse_rr(unsigned char * pnt, int len, int cont_flag)
+{
+ int slen;
+ int ncount;
+ int extent;
+ int cont_extent, cont_offset, cont_size;
+ int flag1, flag2;
+ unsigned char *pnts;
+ char symlink[1024];
+ char name[1024];
+ int goof;
+/* printf(" RRlen=%d ", len); */
+
+ symlink[0] = 0;
+
+ cont_extent = cont_offset = cont_size = 0;
+
+ ncount = 0;
+ flag1 = flag2 = 0;
+ while(len >= 4){
+ if(ncount) printf(",");
+ else printf("[");
+ printf("%c%c", pnt[0], pnt[1]);
+ if(pnt[3] != 1) {
+ printf("**BAD RRVERSION");
+ return;
+ };
+ ncount++;
+ if(pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff;
+ if(strncmp(pnt, "PX", 2) == 0) flag2 |= 1;
+ if(strncmp(pnt, "PN", 2) == 0) flag2 |= 2;
+ if(strncmp(pnt, "SL", 2) == 0) flag2 |= 4;
+ if(strncmp(pnt, "NM", 2) == 0) {
+ slen = pnt[2] - 5;
+ pnts = pnt+5;
+ if( (pnt[4] & 6) != 0 )
+ {
+ printf("*");
+ }
+ memset(name, 0, sizeof(name));
+ memcpy(name, pnts, slen);
+ printf("=%s", name);
+ flag2 |= 8;
+ }
+ if(strncmp(pnt, "CL", 2) == 0) flag2 |= 16;
+ if(strncmp(pnt, "PL", 2) == 0) flag2 |= 32;
+ if(strncmp(pnt, "RE", 2) == 0) flag2 |= 64;
+ if(strncmp(pnt, "TF", 2) == 0) flag2 |= 128;
+
+ if(strncmp(pnt, "PX", 2) == 0) {
+ extent = isonum_733(pnt+12);
+ printf("=%x", extent);
+ };
+
+ if(strncmp(pnt, "CE", 2) == 0) {
+ cont_extent = isonum_733(pnt+4);
+ cont_offset = isonum_733(pnt+12);
+ cont_size = isonum_733(pnt+20);
+ printf("=[%x,%x,%d]", cont_extent, cont_offset,
+ cont_size);
+ };
+
+ if(strncmp(pnt, "PL", 2) == 0 || strncmp(pnt, "CL", 2) == 0) {
+ extent = isonum_733(pnt+4);
+ printf("=%x", extent);
+ };
+
+ if(strncmp(pnt, "SL", 2) == 0) {
+ int cflag;
+
+ cflag = pnt[4];
+ pnts = pnt+5;
+ slen = pnt[2] - 5;
+ while(slen >= 1){
+ switch(pnts[0] & 0xfe){
+ case 0:
+ strncat(symlink, pnts+2, pnts[1]);
+ break;
+ case 2:
+ strcat (symlink, ".");
+ break;
+ case 4:
+ strcat (symlink, "..");
+ break;
+ case 8:
+ if((pnts[0] & 1) == 0)strcat (symlink, "/");
+ break;
+ case 16:
+ strcat(symlink,"/mnt");
+ printf("Warning - mount point requested");
+ break;
+ case 32:
+ strcat(symlink,"kafka");
+ printf("Warning - host_name requested");
+ break;
+ default:
+ printf("Reserved bit setting in symlink", goof++);
+ break;
+ };
+ if((pnts[0] & 0xfe) && pnts[1] != 0) {
+ printf("Incorrect length in symlink component");
+ };
+ if((pnts[0] & 1) == 0) strcat(symlink,"/");
+
+ slen -= (pnts[1] + 2);
+ pnts += (pnts[1] + 2);
+
+ };
+ if(cflag) strcat(symlink, "+");
+ printf("=%s", symlink);
+ symlink[0] = 0;
+ };
+
+ len -= pnt[2];
+ pnt += pnt[2];
+ if(len <= 3 && cont_extent) {
+ unsigned char sector[2048];
+ lseek(fileno(infile), cont_extent * blocksize, 0);
+ read(fileno(infile), sector, sizeof(sector));
+ flag2 |= parse_rr(&sector[cont_offset], cont_size, 1);
+ };
+ };
+ if(ncount) printf("]");
+ if (!cont_flag && flag1 != flag2)
+ printf("Flag %x != %x", flag1, flag2, goof++);
+ return flag2;
+}
+
+int
+dump_rr(struct iso_directory_record * idr)
+{
+ int len;
+ unsigned char * pnt;
+
+ len = idr->length[0] & 0xff;
+ len -= sizeof(struct iso_directory_record);
+ len += sizeof(idr->name);
+ len -= idr->name_len[0];
+ pnt = (unsigned char *) idr;
+ pnt += sizeof(struct iso_directory_record);
+ pnt -= sizeof(idr->name);
+ pnt += idr->name_len[0];
+ if((idr->name_len[0] & 1) == 0){
+ pnt++;
+ len--;
+ };
+ parse_rr(pnt, len, 0);
+}
+
+
+showblock(int flag){
+ unsigned int k;
+ int i, j;
+ int line;
+ struct iso_directory_record * idr;
+ lseek(fileno(infile), file_addr, 0);
+ read(fileno(infile), buffer, sizeof(buffer));
+ for(i=0;i<60;i++) printf("\n");
+ fflush(stdout);
+ i = line = 0;
+ if(flag) {
+ while(1==1){
+ crsr2(line+3,1);
+ idr = (struct iso_directory_record *) &buffer[i];
+ if(idr->length[0] == 0) break;
+ printf("%3d ", idr->length[0]);
+ printf("[%2d] ", idr->volume_sequence_number[0]);
+ printf("%5x ", isonum_733(idr->extent));
+ printf("%8d ", isonum_733(idr->size));
+ printf ((idr->flags[0] & 2) ? "*" : " ");
+ if(idr->name_len[0] == 1 && idr->name[0] == 0)
+ printf(". ");
+ else if(idr->name_len[0] == 1 && idr->name[0] == 1)
+ printf(".. ");
+ else {
+ for(j=0; j<idr->name_len[0]; j++) printf("%c", idr->name[j]);
+ for(j=0; j<14 -idr->name_len[0]; j++) printf(" ");
+ };
+ dump_rr(idr);
+ printf("\n");
+ i += buffer[i];
+ if (i > 2048 - sizeof(struct iso_directory_record)) break;
+ line++;
+ };
+ };
+ printf("\n");
+ printf(" Zone, zone offset: %6x %4.4x ",file_addr / blocksize,
+ file_addr & (blocksize - 1));
+ fflush(stdout);
+}
+
+getbyte()
+{
+ char c1;
+ c1 = buffer[file_addr & (blocksize-1)];
+ file_addr++;
+ if ((file_addr & (blocksize-1)) == 0) showblock(0);
+ return c1;
+}
+
+main(int argc, char * argv[]){
+ char c;
+ char buffer[2048];
+ int nbyte;
+ int i,j;
+ struct iso_primary_descriptor ipd;
+ struct iso_directory_record * idr;
+
+ if(argc < 2) return 0;
+ infile = fopen(argv[1],"rb");
+
+ file_addr = 16 << 11;
+ lseek(fileno(infile), file_addr, 0);
+ read(fileno(infile), &ipd, sizeof(ipd));
+
+ idr = (struct iso_directory_record *) &ipd.root_directory_record;
+
+ blocksize = isonum_723(ipd.logical_block_size);
+ if( blocksize != 512 && blocksize != 1024 && blocksize != 2048 )
+ {
+ blocksize = 2048;
+ }
+
+ file_addr = isonum_733(idr->extent);
+
+ file_addr = file_addr * blocksize;
+
+/* Now setup the keyboard for single character input. */
+#ifdef HAVE_TERMIOS_H
+ if(tcgetattr(0, &savetty) == -1)
+#else
+ if(ioctl(0, TCGETA, &savetty) == -1)
+#endif
+ {
+ printf("stdin must be a tty\n");
+ exit(1);
+ }
+ newtty=savetty;
+ newtty.c_lflag&=~ICANON;
+ newtty.c_lflag&=~ECHO;
+ newtty.c_cc[VMIN]=1;
+ set_tty();
+ signal(SIGTSTP, onsusp);
+
+ do{
+ if(file_addr < 0) file_addr = 0;
+ showblock(1);
+ read (0, &c, 1);
+ if (c == 'a') file_addr -= blocksize;
+ if (c == 'b') file_addr += blocksize;
+ if (c == 'g') {
+ crsr2(20,1);
+ printf("Enter new starting block (in hex):");
+ scanf("%x",&file_addr);
+ file_addr = file_addr * blocksize;
+ crsr2(20,1);
+ printf(" ");
+ };
+ if (c == 'f') {
+ crsr2(20,1);
+ printf("Enter new search string:");
+ fgets(search,sizeof(search),stdin);
+ while(search[strlen(search)-1] == '\n') search[strlen(search)-1] = 0;
+ crsr2(20,1);
+ printf(" ");
+ };
+ if (c == '+') {
+ while(1==1){
+ while(1==1){
+ c = getbyte(&file_addr);
+ if (c == search[0]) break;
+ };
+ for (j=1;j<strlen(search);j++)
+ if(search[j] != getbyte()) break;
+ if(j==strlen(search)) break;
+ };
+ file_addr &= ~(blocksize-1);
+ showblock(1);
+ };
+ if (c == 'q') break;
+ } while(1==1);
+ reset_tty();
+ fclose(infile);
+}
+
+
+
+
diff --git a/gnu/usr.sbin/mkisofs/diag/isoinfo.8 b/gnu/usr.sbin/mkisofs/diag/isoinfo.8
new file mode 100644
index 00000000000..041e5d2af42
--- /dev/null
+++ b/gnu/usr.sbin/mkisofs/diag/isoinfo.8
@@ -0,0 +1,125 @@
+.\" $OpenBSD: isoinfo.8,v 1.1 1997/09/15 06:01:53 downsj Exp $
+.\"
+.\" $From: isoinfo.8,v 1.1 1997/02/23 19:08:53 eric Rel $
+.\"
+.\" -*- nroff -*-
+.TH ISOINFO 8 "23 Feb 1997" "Version 1.10b8"
+.SH NAME
+isoinfo, isovfy, inodump \- Utility programs for dumping and verifying iso9660
+images.
+.SH SYNOPSIS
+.B isodump
+.I isoimage
+.PP
+.B isoinfo
+[
+.B \-R
+]
+[
+.B \-f
+]
+[
+.B \-l
+]
+[
+.B \-T
+]
+[
+.B \-N
+]
+[
+.B \-i
+.I isoimage
+]
+[
+.B \-x
+.I path
+]
+.PP
+.B isovfy
+.I isoimage
+.SH DESCRIPTION
+.B isodump
+is a crude utility to interactively display the contents of iso9660 images
+in order to verify directory integrity. The initial screen is a display
+of the first part of the root directory, and the prompt shows you the
+extent number and offset in the extent. You can use the 'a' and 'b'
+commands to move backwards and forwards within the image. The 'g' command
+allows you to goto an arbitrary extent, and the 'f' command specifies
+a search string to be used. The '+' command searches forward for the next
+instance of the search string, and the 'q' command exits
+.B isodump.
+.PP
+.B isoinfo
+is a utility to perform directory like listings of iso9660 images.
+.PP
+.B isovfy
+is a utility to verify the integrity of an iso9660 image. Most of the tests
+in
+.B isovfy
+were added after bugs were discovered in early versions of
+.B mkisofs.
+It isn't all that clear how useful this is anymore, but it doesn't hurt to
+have this around.
+
+.SH OPTIONS
+Only the
+.B isoinfo
+program has any command line options. These are:
+.TP
+.I -f
+generate output as if a 'find . -print' command had been run on the iso9660
+image. You should not use the
+.B -l
+image with the
+.B -f
+option.
+.TP
+.I -i iso_image
+Specifies the path of the iso9660 image that we wish to examine.
+.TP
+.I -l
+generate output as if a 'ls -lR' command had been run on the iso9660 image.
+You should not use the
+.B -f
+image with the
+.B -l
+option.
+.TP
+.I -N sector
+Quick hack to help examine single session disc files that are to be written to
+a multi-session disc. The sector number specified is the sector number at
+which the iso9660 image should be written when send to the cd-writer. Not
+used for the first session on the disc.
+.TP
+.I \-R
+Extract information from Rock Ridge extensions (if present) for permissions,
+file names and ownerships.
+.TP
+.I -T sector
+Quick hack to help examine multi-session images that have already been burned
+to a multi-session disc. The sector number specified is the sector number for
+the start of the session we wish to display.
+.TP
+.I -x pathname
+Extract specified file to stdout.
+.SH AUTHOR
+Eric Youngdale <ericy@gnu.ai.mit.edu> or <eric@andante.jic.com> is to blame
+for these shoddy hacks. Patches to improve general usability would be
+gladly accepted.
+.SH BUGS
+The user interface really sucks.
+.SH FUTURE IMPROVEMENTS
+These utilities are really quick hacks, which are very useful for debugging
+problems in mkisofs or in an iso9660 filesystem. In the long run, it would
+be nice to have a daemon that would NFS export a iso9660 image.
+.PP
+The isoinfo program is probably the program that is of the most use to
+the general user.
+.SH AVAILABILITY
+These utilities come with the mkisofs package, and the primary ftp site
+is tsx-11.mit.edu in /pub/linux/BETA/cdrom/mkisofs and many other mirror
+sites. Despite the name, the software is not beta.
+.SH SEE ALSO
+mkisofs(8)
+
diff --git a/gnu/usr.sbin/mkisofs/diag/isoinfo.c b/gnu/usr.sbin/mkisofs/diag/isoinfo.c
new file mode 100644
index 00000000000..f0bc41798d2
--- /dev/null
+++ b/gnu/usr.sbin/mkisofs/diag/isoinfo.c
@@ -0,0 +1,554 @@
+/* $OpenBSD: isoinfo.c,v 1.1 1997/09/15 06:01:53 downsj Exp $ */
+/*
+ * File isodump.c - dump iso9660 directory information.
+ *
+
+ Written by Eric Youngdale (1993).
+
+ Copyright 1993 Yggdrasil Computing, 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. */
+
+static char rcsid[] ="$From: isoinfo.c,v 1.2 1997/03/22 02:20:28 eric Rel $";
+
+/*
+ * Simple program to dump contents of iso9660 image in more usable format.
+ *
+ * Usage:
+ * To list contents of image (with or without RR):
+ * isoinfo -l [-R] -i imagefile
+ * To extract file from image:
+ * isoinfo -i imagefile -x xtractfile > outfile
+ * To generate a "find" like list of files:
+ * isoinfo -f -i imagefile
+ */
+
+#include "../config.h"
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/stat.h>
+
+#ifdef __svr4__
+#include <stdlib.h>
+#else
+extern int optind;
+extern char *optarg;
+/* extern int getopt (int __argc, char **__argv, char *__optstring); */
+#endif
+
+FILE * infile;
+int use_rock = 0;
+int do_listing = 0;
+int do_find = 0;
+char * xtract = 0;
+
+struct stat fstat_buf;
+char name_buf[256];
+char xname[256];
+unsigned char date_buf[9];
+unsigned int sector_offset = 0;
+
+unsigned char buffer[2048];
+
+#define PAGE sizeof(buffer)
+
+#define ISODCL(from, to) (to - from + 1)
+
+
+int
+isonum_731 (char * p)
+{
+ return ((p[0] & 0xff)
+ | ((p[1] & 0xff) << 8)
+ | ((p[2] & 0xff) << 16)
+ | ((p[3] & 0xff) << 24));
+}
+
+
+int
+isonum_733 (unsigned char * p)
+{
+ return (isonum_731 (p));
+}
+
+struct iso_primary_descriptor {
+ unsigned char type [ISODCL ( 1, 1)]; /* 711 */
+ unsigned char id [ISODCL ( 2, 6)];
+ unsigned char version [ISODCL ( 7, 7)]; /* 711 */
+ unsigned char unused1 [ISODCL ( 8, 8)];
+ unsigned char system_id [ISODCL ( 9, 40)]; /* aunsigned chars */
+ unsigned char volume_id [ISODCL ( 41, 72)]; /* dunsigned chars */
+ unsigned char unused2 [ISODCL ( 73, 80)];
+ unsigned char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
+ unsigned char unused3 [ISODCL ( 89, 120)];
+ unsigned char volume_set_size [ISODCL (121, 124)]; /* 723 */
+ unsigned char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
+ unsigned char logical_block_size [ISODCL (129, 132)]; /* 723 */
+ unsigned char path_table_size [ISODCL (133, 140)]; /* 733 */
+ unsigned char type_l_path_table [ISODCL (141, 144)]; /* 731 */
+ unsigned char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
+ unsigned char type_m_path_table [ISODCL (149, 152)]; /* 732 */
+ unsigned char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
+ unsigned char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
+ unsigned char volume_set_id [ISODCL (191, 318)]; /* dunsigned chars */
+ unsigned char publisher_id [ISODCL (319, 446)]; /* achars */
+ unsigned char preparer_id [ISODCL (447, 574)]; /* achars */
+ unsigned char application_id [ISODCL (575, 702)]; /* achars */
+ unsigned char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
+ unsigned char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
+ unsigned char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
+ unsigned char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
+ unsigned char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
+ unsigned char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
+ unsigned char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
+ unsigned char file_structure_version [ISODCL (882, 882)]; /* 711 */
+ unsigned char unused4 [ISODCL (883, 883)];
+ unsigned char application_data [ISODCL (884, 1395)];
+ unsigned char unused5 [ISODCL (1396, 2048)];
+};
+
+struct iso_directory_record {
+ unsigned char length [ISODCL (1, 1)]; /* 711 */
+ unsigned char ext_attr_length [ISODCL (2, 2)]; /* 711 */
+ unsigned char extent [ISODCL (3, 10)]; /* 733 */
+ unsigned char size [ISODCL (11, 18)]; /* 733 */
+ unsigned char date [ISODCL (19, 25)]; /* 7 by 711 */
+ unsigned char flags [ISODCL (26, 26)];
+ unsigned char file_unit_size [ISODCL (27, 27)]; /* 711 */
+ unsigned char interleave [ISODCL (28, 28)]; /* 711 */
+ unsigned char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
+ unsigned char name_len [ISODCL (33, 33)]; /* 711 */
+ unsigned char name [1];
+};
+
+
+int parse_rr(unsigned char * pnt, int len, int cont_flag)
+{
+ int slen;
+ int ncount;
+ int extent;
+ int cont_extent, cont_offset, cont_size;
+ int flag1, flag2;
+ unsigned char *pnts;
+ char symlink[1024];
+ int goof;
+
+ symlink[0] = 0;
+
+ cont_extent = cont_offset = cont_size = 0;
+
+ ncount = 0;
+ flag1 = flag2 = 0;
+ while(len >= 4){
+ if(pnt[3] != 1) {
+ printf("**BAD RRVERSION");
+ return;
+ };
+ ncount++;
+ if(pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff;
+ if(strncmp(pnt, "PX", 2) == 0) flag2 |= 1;
+ if(strncmp(pnt, "PN", 2) == 0) flag2 |= 2;
+ if(strncmp(pnt, "SL", 2) == 0) flag2 |= 4;
+ if(strncmp(pnt, "NM", 2) == 0) flag2 |= 8;
+ if(strncmp(pnt, "CL", 2) == 0) flag2 |= 16;
+ if(strncmp(pnt, "PL", 2) == 0) flag2 |= 32;
+ if(strncmp(pnt, "RE", 2) == 0) flag2 |= 64;
+ if(strncmp(pnt, "TF", 2) == 0) flag2 |= 128;
+
+ if(strncmp(pnt, "PX", 2) == 0) {
+ fstat_buf.st_mode = isonum_733(pnt+4);
+ fstat_buf.st_nlink = isonum_733(pnt+12);
+ fstat_buf.st_uid = isonum_733(pnt+20);
+ fstat_buf.st_gid = isonum_733(pnt+28);
+ };
+
+ if(strncmp(pnt, "NM", 2) == 0) {
+ strncpy(name_buf, pnt+5, pnt[2] - 5);
+ name_buf[pnt[2] - 5] = 0;
+ }
+
+ if(strncmp(pnt, "CE", 2) == 0) {
+ cont_extent = isonum_733(pnt+4);
+ cont_offset = isonum_733(pnt+12);
+ cont_size = isonum_733(pnt+20);
+ };
+
+ if(strncmp(pnt, "PL", 2) == 0 || strncmp(pnt, "CL", 2) == 0) {
+ extent = isonum_733(pnt+4);
+ };
+
+ if(strncmp(pnt, "SL", 2) == 0) {
+ int cflag;
+
+ cflag = pnt[4];
+ pnts = pnt+5;
+ slen = pnt[2] - 5;
+ while(slen >= 1){
+ switch(pnts[0] & 0xfe){
+ case 0:
+ strncat(symlink, pnts+2, pnts[1]);
+ break;
+ case 2:
+ strcat (symlink, ".");
+ break;
+ case 4:
+ strcat (symlink, "..");
+ break;
+ case 8:
+ if((pnts[0] & 1) == 0)strcat (symlink, "/");
+ break;
+ case 16:
+ strcat(symlink,"/mnt");
+ printf("Warning - mount point requested");
+ break;
+ case 32:
+ strcat(symlink,"kafka");
+ printf("Warning - host_name requested");
+ break;
+ default:
+ printf("Reserved bit setting in symlink", goof++);
+ break;
+ };
+ if((pnts[0] & 0xfe) && pnts[1] != 0) {
+ printf("Incorrect length in symlink component");
+ };
+ if((pnts[0] & 1) == 0) strcat(symlink,"/");
+
+ slen -= (pnts[1] + 2);
+ pnts += (pnts[1] + 2);
+ if(xname[0] == 0) strcpy(xname, "-> ");
+ strcat(xname, symlink);
+ };
+ symlink[0] = 0;
+ };
+
+ len -= pnt[2];
+ pnt += pnt[2];
+ if(len <= 3 && cont_extent) {
+ unsigned char sector[2048];
+ lseek(fileno(infile), (cont_extent - sector_offset) << 11, 0);
+ read(fileno(infile), sector, sizeof(sector));
+ flag2 |= parse_rr(&sector[cont_offset], cont_size, 1);
+ };
+ };
+ return flag2;
+}
+
+int
+dump_rr(struct iso_directory_record * idr)
+{
+ int len;
+ unsigned char * pnt;
+
+ len = idr->length[0] & 0xff;
+ len -= sizeof(struct iso_directory_record);
+ len += sizeof(idr->name);
+ len -= idr->name_len[0];
+ pnt = (unsigned char *) idr;
+ pnt += sizeof(struct iso_directory_record);
+ pnt -= sizeof(idr->name);
+ pnt += idr->name_len[0];
+ if((idr->name_len[0] & 1) == 0){
+ pnt++;
+ len--;
+ };
+ parse_rr(pnt, len, 0);
+}
+
+struct todo
+{
+ struct todo * next;
+ char * name;
+ int extent;
+ int length;
+};
+
+struct todo * todo_idr = NULL;
+
+char * months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
+ "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+dump_stat(int extent)
+{
+ int i;
+ char outline[80];
+
+ memset(outline, ' ', sizeof(outline));
+
+ if(S_ISREG(fstat_buf.st_mode))
+ outline[0] = '-';
+ else if(S_ISDIR(fstat_buf.st_mode))
+ outline[0] = 'd';
+ else if(S_ISLNK(fstat_buf.st_mode))
+ outline[0] = 'l';
+ else if(S_ISCHR(fstat_buf.st_mode))
+ outline[0] = 'c';
+ else if(S_ISBLK(fstat_buf.st_mode))
+ outline[0] = 'b';
+ else if(S_ISFIFO(fstat_buf.st_mode))
+ outline[0] = 'f';
+ else if(S_ISSOCK(fstat_buf.st_mode))
+ outline[0] = 's';
+ else
+ outline[0] = '?';
+
+ memset(outline+1, '-', 9);
+ if( fstat_buf.st_mode & S_IRUSR )
+ outline[1] = 'r';
+ if( fstat_buf.st_mode & S_IWUSR )
+ outline[2] = 'w';
+ if( fstat_buf.st_mode & S_IXUSR )
+ outline[3] = 'x';
+
+ if( fstat_buf.st_mode & S_IRGRP )
+ outline[4] = 'r';
+ if( fstat_buf.st_mode & S_IWGRP )
+ outline[5] = 'w';
+ if( fstat_buf.st_mode & S_IXGRP )
+ outline[6] = 'x';
+
+ if( fstat_buf.st_mode & S_IROTH )
+ outline[7] = 'r';
+ if( fstat_buf.st_mode & S_IWOTH )
+ outline[8] = 'w';
+ if( fstat_buf.st_mode & S_IXOTH )
+ outline[9] = 'x';
+
+ sprintf(outline+11, "%3d", fstat_buf.st_nlink);
+ sprintf(outline+15, "%4o", fstat_buf.st_uid);
+ sprintf(outline+20, "%4o", fstat_buf.st_gid);
+ sprintf(outline+33, "%8d", fstat_buf.st_size);
+
+ if( date_buf[1] >= 1 && date_buf[1] <= 12 )
+ {
+ memcpy(outline+42, months[date_buf[1]-1], 3);
+ }
+
+ sprintf(outline+46, "%2d", date_buf[2]);
+ sprintf(outline+49, "%4d", date_buf[0]+1900);
+
+ sprintf(outline+54, "[%6d]", extent);
+
+ for(i=0; i<63; i++)
+ if(outline[i] == 0) outline[i] = ' ';
+ outline[63] = 0;
+
+ printf("%s %s %s\n", outline, name_buf, xname);
+}
+
+extract_file(struct iso_directory_record * idr)
+{
+ int extent, len, tlen;
+ unsigned char buff[2048];
+
+ extent = isonum_733(idr->extent);
+ len = isonum_733(idr->size);
+
+ while(len > 0)
+ {
+ lseek(fileno(infile), (extent - sector_offset) << 11, 0);
+ tlen = (len > sizeof(buff) ? sizeof(buff) : len);
+ read(fileno(infile), buff, tlen);
+ len -= tlen;
+ extent++;
+ write(1, buff, tlen);
+ }
+}
+
+parse_dir(char * rootname, int extent, int len){
+ unsigned int k;
+ char testname[256];
+ struct todo * td;
+ int i, j;
+ struct iso_directory_record * idr;
+
+
+ if( do_listing)
+ printf("\nDirectory listing of %s\n", rootname);
+
+ while(len > 0 )
+ {
+ lseek(fileno(infile), (extent - sector_offset) << 11, 0);
+ read(fileno(infile), buffer, sizeof(buffer));
+ len -= sizeof(buffer);
+ extent++;
+ i = 0;
+ while(1==1){
+ idr = (struct iso_directory_record *) &buffer[i];
+ if(idr->length[0] == 0) break;
+ memset(&fstat_buf, 0, sizeof(fstat_buf));
+ name_buf[0] = xname[0] = 0;
+ fstat_buf.st_size = isonum_733(idr->size);
+ if( idr->flags[0] & 2)
+ fstat_buf.st_mode |= S_IFDIR;
+ else
+ fstat_buf.st_mode |= S_IFREG;
+ if(idr->name_len[0] == 1 && idr->name[0] == 0)
+ strcpy(name_buf, ".");
+ else if(idr->name_len[0] == 1 && idr->name[0] == 1)
+ strcpy(name_buf, "..");
+ else {
+ strncpy(name_buf, idr->name, idr->name_len[0]);
+ name_buf[idr->name_len[0]] = 0;
+ };
+ memcpy(date_buf, idr->date, 9);
+ if(use_rock) dump_rr(idr);
+ if( (idr->flags[0] & 2) != 0
+ && (idr->name_len[0] != 1
+ || (idr->name[0] != 0 && idr->name[0] != 1)))
+ {
+ /*
+ * Add this directory to the todo list.
+ */
+ td = todo_idr;
+ if( td != NULL )
+ {
+ while(td->next != NULL) td = td->next;
+ td->next = (struct todo *) malloc(sizeof(*td));
+ td = td->next;
+ }
+ else
+ {
+ todo_idr = td = (struct todo *) malloc(sizeof(*td));
+ }
+ td->next = NULL;
+ td->extent = isonum_733(idr->extent);
+ td->length = isonum_733(idr->size);
+ td->name = (char *) malloc(strlen(rootname)
+ + strlen(name_buf) + 2);
+ strcpy(td->name, rootname);
+ strcat(td->name, name_buf);
+ strcat(td->name, "/");
+ }
+ else
+ {
+ strcpy(testname, rootname);
+ strcat(testname, name_buf);
+ if(xtract && strcmp(xtract, testname) == 0)
+ {
+ extract_file(idr);
+ }
+ }
+ if( do_find
+ && (idr->name_len[0] != 1
+ || (idr->name[0] != 0 && idr->name[0] != 1)))
+ {
+ strcpy(testname, rootname);
+ strcat(testname, name_buf);
+ printf("%s\n", testname);
+ }
+ if(do_listing)
+ dump_stat(isonum_733(idr->extent));
+ i += buffer[i];
+ if (i > 2048 - sizeof(struct iso_directory_record)) break;
+ }
+ }
+}
+
+usage()
+{
+ fprintf(stderr, "isoinfo -i filename [-l] [-R] [-x filename] [-f] [-N nsect]\n");
+}
+
+main(int argc, char * argv[]){
+ int c;
+ char buffer[2048];
+ int nbyte;
+ char * filename = NULL;
+ int i,j;
+ int toc_offset = 0;
+ struct todo * td;
+ struct iso_primary_descriptor ipd;
+ struct iso_directory_record * idr;
+
+ if(argc < 2) return 0;
+ while ((c = getopt(argc, argv, "i:Rlx:fN:T:")) != EOF)
+ switch (c)
+ {
+ case 'f':
+ do_find++;
+ break;
+ case 'R':
+ use_rock++;
+ break;
+ case 'l':
+ do_listing++;
+ break;
+ case 'T':
+ /*
+ * This is used if we have a complete multi-session
+ * disc that we want/need to play with.
+ * Here we specify the offset where we want to
+ * start searching for the TOC.
+ */
+ toc_offset = atol(optarg);
+ break;
+ case 'N':
+ /*
+ * Use this if we have an image of a single session
+ * and we need to list the directory contents.
+ * This is the session block number of the start
+ * of the session.
+ */
+ sector_offset = atol(optarg);
+ break;
+ case 'i':
+ filename = optarg;
+ break;
+ case 'x':
+ xtract = optarg;
+ break;
+ default:
+ usage();
+ exit(1);
+ }
+
+ if( filename == NULL )
+ {
+ fprintf(stderr, "Error - file not specified\n");
+ exit(1);
+ }
+
+ infile = fopen(filename,"rb");
+
+ if( infile == NULL )
+ {
+ fprintf(stderr,"Unable to open file %s\n", filename);
+ exit(1);
+ }
+
+ /*
+ * Absolute sector offset, so don't subtract sector_offset here.
+ */
+ lseek(fileno(infile), (16 + toc_offset) <<11, 0);
+ read(fileno(infile), &ipd, sizeof(ipd));
+
+ idr = (struct iso_directory_record *) &ipd.root_directory_record;
+
+ parse_dir("/", isonum_733(idr->extent), isonum_733(idr->size));
+ td = todo_idr;
+ while(td)
+ {
+ parse_dir(td->name, td->extent, td->length);
+ td = td->next;
+ }
+
+ fclose(infile);
+}
+
+
+
+
diff --git a/gnu/usr.sbin/mkisofs/diag/isovfy.c b/gnu/usr.sbin/mkisofs/diag/isovfy.c
new file mode 100644
index 00000000000..f10447889f3
--- /dev/null
+++ b/gnu/usr.sbin/mkisofs/diag/isovfy.c
@@ -0,0 +1,514 @@
+/* $OpenBSD: isovfy.c,v 1.1 1997/09/15 06:01:53 downsj Exp $ */
+/*
+ * File isovfy.c - verify consistency of iso9660 filesystem.
+ *
+
+ Written by Eric Youngdale (1993).
+
+ Copyright 1993 Yggdrasil Computing, 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. */
+
+static char rcsid[] ="$From: isovfy.c,v 1.2 1997/02/23 19:13:23 eric Rel $";
+
+#include <stdio.h>
+#include <signal.h>
+
+FILE * infile;
+int blocksize;
+
+#define PAGE sizeof(buffer)
+
+#define ISODCL(from, to) (to - from + 1)
+
+struct iso_primary_descriptor {
+ unsigned char type [ISODCL ( 1, 1)]; /* 711 */
+ unsigned char id [ISODCL ( 2, 6)];
+ unsigned char version [ISODCL ( 7, 7)]; /* 711 */
+ unsigned char unused1 [ISODCL ( 8, 8)];
+ unsigned char system_id [ISODCL ( 9, 40)]; /* aunsigned chars */
+ unsigned char volume_id [ISODCL ( 41, 72)]; /* dunsigned chars */
+ unsigned char unused2 [ISODCL ( 73, 80)];
+ unsigned char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
+ unsigned char unused3 [ISODCL ( 89, 120)];
+ unsigned char volume_set_size [ISODCL (121, 124)]; /* 723 */
+ unsigned char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
+ unsigned char logical_block_size [ISODCL (129, 132)]; /* 723 */
+ unsigned char path_table_size [ISODCL (133, 140)]; /* 733 */
+ unsigned char type_l_path_table [ISODCL (141, 144)]; /* 731 */
+ unsigned char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
+ unsigned char type_m_path_table [ISODCL (149, 152)]; /* 732 */
+ unsigned char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
+ unsigned char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
+ unsigned char volume_set_id [ISODCL (191, 318)]; /* dunsigned chars */
+ unsigned char publisher_id [ISODCL (319, 446)]; /* achars */
+ unsigned char preparer_id [ISODCL (447, 574)]; /* achars */
+ unsigned char application_id [ISODCL (575, 702)]; /* achars */
+ unsigned char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
+ unsigned char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
+ unsigned char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
+ unsigned char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
+ unsigned char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
+ unsigned char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
+ unsigned char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
+ unsigned char file_structure_version [ISODCL (882, 882)]; /* 711 */
+ unsigned char unused4 [ISODCL (883, 883)];
+ unsigned char application_data [ISODCL (884, 1395)];
+ unsigned char unused5 [ISODCL (1396, 2048)];
+};
+
+struct iso_directory_record {
+ unsigned char length [ISODCL (1, 1)]; /* 711 */
+ unsigned char ext_attr_length [ISODCL (2, 2)]; /* 711 */
+ unsigned char extent [ISODCL (3, 10)]; /* 733 */
+ unsigned char size [ISODCL (11, 18)]; /* 733 */
+ unsigned char date [ISODCL (19, 25)]; /* 7 by 711 */
+ unsigned char flags [ISODCL (26, 26)];
+ unsigned char file_unit_size [ISODCL (27, 27)]; /* 711 */
+ unsigned char interleave [ISODCL (28, 28)]; /* 711 */
+ unsigned char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
+ unsigned char name_len [ISODCL (33, 33)]; /* 711 */
+ unsigned char name [38];
+};
+
+int
+isonum_723 (char * p)
+{
+#if 0
+ if (p[0] != p[3] || p[1] != p[2]) {
+ fprintf (stderr, "invalid format 7.2.3 number\n");
+ exit (1);
+ }
+#endif
+ return (isonum_721 (p));
+}
+
+int
+isonum_721 (char * p)
+{
+ return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
+}
+
+int
+isonum_711 (char * p)
+{
+ return (*p & 0xff);
+}
+
+int
+isonum_731 (char * p)
+{
+ return ((p[0] & 0xff)
+ | ((p[1] & 0xff) << 8)
+ | ((p[2] & 0xff) << 16)
+ | ((p[3] & 0xff) << 24));
+}
+
+int
+isonum_722 (char * p)
+{
+ return ((p[1] & 0xff)
+ | ((p[0] & 0xff) << 8));
+}
+
+int
+isonum_732 (char * p)
+{
+ return ((p[3] & 0xff)
+ | ((p[2] & 0xff) << 8)
+ | ((p[1] & 0xff) << 16)
+ | ((p[0] & 0xff) << 24));
+}
+
+int
+isonum_733 (unsigned char * p)
+{
+ return (isonum_731 (p));
+}
+
+char lbuffer[1024];
+int iline;
+int rr_goof;
+
+
+int
+dump_rr(struct iso_directory_record * idr){
+ int len;
+ char * pnt;
+
+ len = idr->length[0] & 0xff;
+ len -= (sizeof(struct iso_directory_record) - sizeof(idr->name));
+ len -= idr->name_len[0];
+ pnt = (char *) idr;
+ pnt += (sizeof(struct iso_directory_record) - sizeof(idr->name));
+ pnt += idr->name_len[0];
+
+ if((idr->name_len[0] & 1) == 0){
+ pnt++;
+ len--;
+ };
+
+ rr_goof = 0;
+ parse_rr(pnt, len, 0);
+ return rr_goof;
+}
+
+int parse_rr(unsigned char * pnt, int len, int cont_flag)
+{
+ int slen;
+ int ncount;
+ int flag1, flag2;
+ int extent;
+ unsigned char *pnts;
+ int cont_extent, cont_offset, cont_size;
+ char symlink[1024];
+ iline += sprintf(lbuffer+iline," RRlen=%d ", len);
+
+ cont_extent = cont_offset = cont_size = 0;
+
+ symlink[0] = 0;
+
+ ncount = 0;
+ flag1 = flag2 = 0;
+ while(len >= 4){
+ if(ncount) iline += sprintf(lbuffer+iline,",");
+ else iline += sprintf(lbuffer+iline,"[");
+ iline += sprintf(lbuffer+iline,"%c%c", pnt[0], pnt[1]);
+
+ if(pnt[0] < 'A' || pnt[0] > 'Z' || pnt[1] < 'A' ||
+ pnt[1] > 'Z') {
+ iline += sprintf(lbuffer+iline,"**BAD SUSP %d %d]",
+ pnt[0], pnt[1], rr_goof++);
+ return flag2;
+ };
+
+ if(pnt[3] != 1) {
+ iline += sprintf(lbuffer+iline,"**BAD RRVERSION", rr_goof++);
+ return flag2;
+ };
+ ncount++;
+ if(pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff;
+ if(strncmp(pnt, "PX", 2) == 0) flag2 |= 1;
+ if(strncmp(pnt, "PN", 2) == 0) flag2 |= 2;
+ if(strncmp(pnt, "SL", 2) == 0) flag2 |= 4;
+ if(strncmp(pnt, "NM", 2) == 0) flag2 |= 8;
+ if(strncmp(pnt, "CL", 2) == 0) flag2 |= 16;
+ if(strncmp(pnt, "PL", 2) == 0) flag2 |= 32;
+ if(strncmp(pnt, "RE", 2) == 0) flag2 |= 64;
+ if(strncmp(pnt, "TF", 2) == 0) flag2 |= 128;
+
+ if(strncmp(pnt, "CE", 2) == 0) {
+ cont_extent = isonum_733(pnt+4);
+ cont_offset = isonum_733(pnt+12);
+ cont_size = isonum_733(pnt+20);
+ iline += sprintf(lbuffer+iline, "=[%x,%x,%d]",
+ cont_extent, cont_offset, cont_size);
+ };
+
+ if(strncmp(pnt, "PL", 2) == 0 || strncmp(pnt, "CL", 2) == 0) {
+ extent = isonum_733(pnt+4);
+ iline += sprintf(lbuffer+iline,"=%x", extent);
+ if(extent == 0) rr_goof++;
+ };
+ if(strncmp(pnt, "SL", 2) == 0) {
+ pnts = pnt+5;
+ slen = pnt[2] - 5;
+ while(slen >= 1){
+ switch(pnts[0] & 0xfe){
+ case 0:
+ strncat(symlink, pnts+2, pnts[1]);
+ break;
+ case 2:
+ strcat (symlink, ".");
+ break;
+ case 4:
+ strcat (symlink, "..");
+ break;
+ case 8:
+ strcat (symlink, "/");
+ break;
+ case 16:
+ strcat(symlink,"/mnt");
+ iline += sprintf(lbuffer+iline,"Warning - mount point requested");
+ break;
+ case 32:
+ strcat(symlink,"kafka");
+ iline += sprintf(lbuffer+iline,"Warning - host_name requested");
+ break;
+ default:
+ iline += sprintf(lbuffer+iline,"Reserved bit setting in symlink", rr_goof++);
+ break;
+ };
+ if((pnts[0] & 0xfe) && pnts[1] != 0) {
+ iline += sprintf(lbuffer+iline,"Incorrect length in symlink component");
+ };
+ if((pnts[0] & 1) == 0)
+ strcat(symlink,"/");
+ slen -= (pnts[1] + 2);
+ pnts += (pnts[1] + 2);
+
+ };
+ if(symlink[0] != 0) {
+ iline += sprintf(lbuffer+iline,"=%s", symlink);
+ symlink[0] = 0;
+ }
+ };
+
+ len -= pnt[2];
+ pnt += pnt[2];
+ if(len <= 3 && cont_extent) {
+ unsigned char sector[2048];
+ lseek(fileno(infile), cont_extent * blocksize, 0);
+ read(fileno(infile), sector, sizeof(sector));
+ flag2 |= parse_rr(&sector[cont_offset], cont_size, 1);
+ };
+ };
+ if(ncount) iline += sprintf(lbuffer+iline,"]");
+ if (!cont_flag && flag1 && flag1 != flag2)
+ iline += sprintf(lbuffer+iline,"Flag %x != %x", flag1, flag2, rr_goof++);
+ return flag2;
+}
+
+
+int dir_count = 0;
+int dir_size_count = 0;
+int ngoof = 0;
+
+
+check_tree(int file_addr, int file_size, int parent_addr){
+ unsigned char buffer[2048];
+ unsigned int k;
+ int rflag;
+ int i, i1, j, goof;
+ int extent, size;
+ int line;
+ int orig_file_addr, parent_file_addr;
+ struct iso_directory_record * idr;
+
+ i1 = 0;
+
+ orig_file_addr = file_addr / blocksize; /* Actual extent of this directory */
+ parent_file_addr = parent_addr / blocksize;
+
+ if((dir_count % 100) == 0) printf("[%d %d]\n", dir_count, dir_size_count);
+#if 0
+ printf("Starting directory %d %d %d\n", file_addr, file_size, parent_addr);
+#endif
+
+ dir_count++;
+ dir_size_count += file_size / blocksize;
+
+ if(file_size & 0x3ff) printf("********Directory has unusual size\n");
+
+ for(k=0; k < (file_size / sizeof(buffer)); k++){
+ lseek(fileno(infile), file_addr, 0);
+ read(fileno(infile), buffer, sizeof(buffer));
+ i = 0;
+ while(1==1){
+ goof = iline=0;
+ idr = (struct iso_directory_record *) &buffer[i];
+ if(idr->length[0] == 0) break;
+ iline += sprintf(&lbuffer[iline],"%3d ", idr->length[0]);
+ extent = isonum_733(idr->extent);
+ size = isonum_733(idr->size);
+ iline += sprintf(&lbuffer[iline],"%5x ", extent);
+ iline += sprintf(&lbuffer[iline],"%8d ", size);
+ iline += sprintf (&lbuffer[iline], "%c", (idr->flags[0] & 2) ? '*' : ' ');
+
+ if(idr->name_len[0] > 33)
+ iline += sprintf(&lbuffer[iline],"File name length=(%d)",
+ idr->name_len[0], goof++);
+ else if(idr->name_len[0] == 1 && idr->name[0] == 0) {
+ iline += sprintf(&lbuffer[iline],". ");
+ rflag = 0;
+ if(orig_file_addr !=isonum_733(idr->extent) + isonum_711(idr->ext_attr_length))
+ iline += sprintf(&lbuffer[iline],"***** Directory has null extent.", goof++);
+ if(i1)
+ iline += sprintf(&lbuffer[iline],"***** . not first entry.", rr_goof++);
+ } else if(idr->name_len[0] == 1 && idr->name[0] == 1) {
+ iline += sprintf(&lbuffer[iline],".. ");
+ rflag = 0;
+ if(parent_file_addr !=isonum_733(idr->extent) + isonum_711(idr->ext_attr_length))
+ iline += sprintf(&lbuffer[iline],"***** Directory has null extent.", goof++);
+ if(i1 != 1)
+ iline += sprintf(&lbuffer[iline],"***** .. not second entry.", rr_goof++);
+
+ } else {
+ if(i1 < 2) iline += sprintf(&lbuffer[iline]," Improper sorting.", rr_goof++);
+ for(j=0; j<idr->name_len[0]; j++) iline += sprintf(&lbuffer[iline],"%c", idr->name[j]);
+ for(j=0; j<14 -idr->name_len[0]; j++) iline += sprintf(&lbuffer[iline]," ");
+ rflag = 1;
+ };
+
+ if(size && extent == 0) iline += sprintf(&lbuffer[iline],"****Extent==0, size != 0", goof++);
+#if 0
+ /* This is apparently legal. */
+ if(size == 0 && extent) iline += sprintf(&lbuffer[iline],"****Extent!=0, size == 0", goof++);
+#endif
+
+ if(idr->flags[0] & 0xf5)
+ iline += sprintf(&lbuffer[iline],"Flags=(%x) ", idr->flags[0], goof++);
+
+ if(idr->interleave[0])
+ iline += sprintf(&lbuffer[iline],"Interleave=(%d) ", idr->interleave[0], goof++);
+
+ if(idr->file_unit_size[0])
+ iline += sprintf(&lbuffer[iline],"File unit size=(%d) ", idr->file_unit_size[0], goof++);
+
+ if(idr->volume_sequence_number[0] != 1)
+ iline += sprintf(&lbuffer[iline],"Volume sequence number=(%d) ", idr->volume_sequence_number[0], goof++);
+
+ goof += dump_rr(idr);
+ iline += sprintf(&lbuffer[iline],"\n");
+
+
+ if(goof){
+ ngoof++;
+ lbuffer[iline++] = 0;
+ printf("%x: %s", orig_file_addr, lbuffer);
+ };
+
+
+
+ if(rflag && (idr->flags[0] & 2)) check_tree((isonum_733(idr->extent) + isonum_711(idr->ext_attr_length)) * blocksize,
+ isonum_733(idr->size),
+ orig_file_addr * blocksize);
+ i += buffer[i];
+ i1++;
+ if (i > 2048 - sizeof(struct iso_directory_record)) break;
+ };
+ file_addr += sizeof(buffer);
+ };
+ fflush(stdout);
+}
+
+
+/* This function simply dumps the contents of the path tables. No
+ consistency checking takes place, although this would proably be a good
+ idea. */
+
+struct path_table_info{
+ char * name;
+ unsigned int extent;
+ unsigned short index;
+ unsigned short parent;
+};
+
+
+check_path_tables(int typel_extent, int typem_extent, int path_table_size){
+ int file_addr;
+ int count;
+ int j;
+ char * pnt;
+ char * typel, *typem;
+
+ /* Now read in the path tables */
+
+ typel = (char *) malloc(path_table_size);
+ lseek(fileno(infile), typel_extent * blocksize, 0);
+ read(fileno(infile), typel, path_table_size);
+
+ typem = (char *) malloc(path_table_size);
+ lseek(fileno(infile), typem_extent * blocksize, 0);
+ read(fileno(infile), typem, path_table_size);
+
+ j = path_table_size;
+ pnt = typel;
+ count = 1;
+ while(j){
+ int namelen, extent, index;
+ char name[32];
+ namelen = *pnt++; pnt++;
+ extent = isonum_731(pnt); pnt += 4;
+ index = isonum_721(pnt); pnt+= 2;
+ j -= 8+namelen;
+ memset(name, 0, sizeof(name));
+
+ strncpy(name, pnt, namelen);
+ pnt += namelen;
+ if(j & 1) { j--; pnt++;};
+ printf("%4.4d %4.4d %8.8x %s\n",count++, index, extent, name);
+ };
+
+ j = path_table_size;
+ pnt = typem;
+ count = 1;
+ while(j){
+ int namelen, extent, index;
+ char name[32];
+ namelen = *pnt++; pnt++;
+ extent = isonum_732(pnt); pnt += 4;
+ index = isonum_722(pnt); pnt+= 2;
+ j -= 8+namelen;
+ memset(name, 0, sizeof(name));
+
+ strncpy(name, pnt, namelen);
+ pnt += namelen;
+ if(j & 1) { j--; pnt++;};
+ printf("%4.4d %4.4d %8.8x %s\n", count++, index, extent, name);
+ };
+
+}
+
+main(int argc, char * argv[]){
+ int file_addr, file_size;
+ char c;
+ int nbyte;
+ struct iso_primary_descriptor ipd;
+ struct iso_directory_record * idr;
+ int typel_extent, typem_extent;
+ int path_table_size;
+ int i,j;
+ if(argc < 2) return 0;
+ infile = fopen(argv[1],"rb");
+
+
+ file_addr = 32768;
+ lseek(fileno(infile), file_addr, 0);
+ read(fileno(infile), &ipd, sizeof(ipd));
+
+ idr = (struct iso_directory_record *) &ipd.root_directory_record;
+
+ blocksize = isonum_723(ipd.logical_block_size);
+ if( blocksize != 512 && blocksize != 1024 && blocksize != 2048 )
+ {
+ blocksize = 2048;
+ }
+
+ file_addr = isonum_733(idr->extent) + isonum_711(idr->ext_attr_length);
+ file_size = isonum_733(idr->size);
+
+ printf("Root at extent %x, %d bytes\n", file_addr, file_size);
+ file_addr = file_addr * blocksize;
+
+ check_tree(file_addr, file_size, file_addr);
+
+ typel_extent = isonum_731(ipd.type_l_path_table);
+ typem_extent = isonum_732(ipd.type_m_path_table);
+ path_table_size = isonum_733(ipd.path_table_size);
+
+ /* Enable this to get the dump of the path tables */
+#if 0
+ check_path_tables(typel_extent, typem_extent, path_table_size);
+#endif
+
+ fclose(infile);
+
+ if(!ngoof) printf("No errors found\n");
+}
+
+
+
+