isoinfo.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:18k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /*
  2.  * File isodump.c - dump iso9660 directory information.
  3.  *
  4.    Written by Eric Youngdale (1993).
  5.    Copyright 1993 Yggdrasil Computing, Incorporated
  6.    This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17. static char rcsid[] ="$Id: isoinfo.c,v 1.6 1999/03/02 03:41:36 eric Exp $";
  18. /*
  19.  * Simple program to dump contents of iso9660 image in more usable format.
  20.  *
  21.  * Usage:
  22.  * To list contents of image (with or without RR):
  23.  * isoinfo -l [-R] -i imagefile
  24.  * To extract file from image:
  25.  * isoinfo -i imagefile -x xtractfile > outfile
  26.  * To generate a "find" like list of files:
  27.  * isoinfo -f -i imagefile
  28.  */
  29. #include "../config.h"
  30. #include <stdxlib.h>
  31. #include <unixstd.h>
  32. #include <strdefs.h>
  33. #include <stdio.h>
  34. #include <standard.h>
  35. #include <signal.h>
  36. #include <sys/stat.h>
  37. #include <statdefs.h>
  38. #include "../iso9660.h"
  39. #ifdef __SVR4
  40. #include <stdlib.h>
  41. #else
  42. extern int optind;
  43. extern char *optarg;
  44. /* extern int getopt (int __argc, char **__argv, char *__optstring); */
  45. #endif
  46. #ifndef S_ISLNK
  47. #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
  48. #endif
  49. #ifndef S_ISSOCK
  50. # ifdef S_IFSOCK
  51. #   define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
  52. # else
  53. #   define S_ISSOCK(m) (0)
  54. # endif
  55. #endif
  56. FILE * infile;
  57. int use_rock = 0;
  58. int use_joliet = 0;
  59. int do_listing = 0;
  60. int do_find = 0;
  61. int do_pathtab = 0;
  62. int do_pvd = 0;
  63. char * xtract = 0;
  64. int ucs_level = 0;
  65. struct stat fstat_buf;
  66. char name_buf[256];
  67. char xname[256];
  68. unsigned char date_buf[9];
  69. unsigned int sector_offset = 0;
  70. unsigned char buffer[2048];
  71. #define PAGE sizeof(buffer)
  72. #define ISODCL(from, to) (to - from + 1)
  73. int isonum_721 __PR((char * p));
  74. int isonum_723 __PR((char * p));
  75. int isonum_731 __PR((char * p));
  76. int isonum_733 __PR((unsigned char * p));
  77. void dump_pathtab __PR((int block, int size));
  78. int parse_rr __PR((unsigned char * pnt, int len, int cont_flag));
  79. void dump_rr __PR((struct iso_directory_record * idr));
  80. void dump_stat __PR((int extent));
  81. void extract_file __PR((struct iso_directory_record * idr));
  82. void parse_dir __PR((char * rootname, int extent, int len));
  83. void usage __PR((int excode));
  84. int main __PR((int argc, char *argv[]));
  85. int
  86. isonum_721 (p)
  87. char *p;
  88. {
  89. return ((p[0] & 0xff)
  90. | ((p[1] & 0xff) << 8));
  91. }
  92. int
  93. isonum_723 (p)
  94. char * p;
  95. {
  96. #if 0
  97. if (p[0] != p[3] || p[1] != p[2]) {
  98. #ifdef USE_LIBSCHILY
  99. comerrno(EX_BAD, "invalid format 7.2.3 numbern");
  100. #else
  101. fprintf (stderr, "invalid format 7.2.3 numbern");
  102. exit (1);
  103. #endif
  104. }
  105. #endif
  106. return (isonum_721 (p));
  107. }
  108. int
  109. isonum_731 (p)
  110. char *p;
  111. {
  112. return ((p[0] & 0xff)
  113. | ((p[1] & 0xff) << 8)
  114. | ((p[2] & 0xff) << 16)
  115. | ((p[3] & 0xff) << 24));
  116. }
  117. int
  118. isonum_733 (p)
  119. unsigned char *p;
  120. {
  121. return (isonum_731 ((char *)p));
  122. }
  123. void
  124. printchars(s, n)
  125. char *s;
  126. int n;
  127. {
  128. int i;
  129. char *p;
  130. for (;n > 0 && *s; n--) {
  131. if (*s == ' ') {
  132. p = s;
  133. i = n;
  134. while (--i >= 0 && *p++ == ' ')
  135. ;
  136. if (i <= 0)
  137. break;
  138. }
  139. putchar(*s++);
  140. }
  141. }
  142. void
  143. dump_pathtab(block, size)
  144. int block;
  145. int size;
  146. {
  147.     char * buf;
  148.     int    offset;
  149.     int    idx;
  150.     int    extent;
  151.     int    pindex;
  152.     int    j;
  153.     int    len;
  154.     char   namebuf[255];
  155.     printf("Path table starts at block %d, size %dn", block, size);
  156.     
  157.     buf = (char *) malloc(size);
  158.     
  159.     lseek(fileno(infile), (block - sector_offset) << 11, 0);
  160.     read(fileno(infile), buf, size);
  161.     
  162.     offset = 0;
  163.     idx = 1;
  164.     while(offset < size)
  165.     {
  166. len    = buf[offset];
  167. extent = isonum_731(buf + offset + 2);
  168. pindex  = isonum_721(buf + offset + 6);
  169. switch( ucs_level )
  170. {
  171. case 3:
  172. case 2:
  173. case 1:
  174.     for(j=0; j < len; j++)
  175.     {
  176. namebuf[j] = buf[offset + 8 + j*2+1];
  177.     }
  178.     printf("%4d: %4d %x %sn", idx, pindex, extent, namebuf);
  179.     break;
  180. case 0:
  181.     printf("%4d: %4d %x %sn", idx, pindex, extent, buf + offset + 8);
  182. }
  183. idx++;
  184. offset += 8 + len;
  185. if( offset & 1) offset++;
  186.     }
  187.     free(buf);
  188. }
  189. int parse_rr(pnt, len, cont_flag)
  190. unsigned char *pnt;
  191. int len;
  192. int cont_flag;
  193. {
  194. int slen;
  195. int ncount;
  196. int extent;
  197. int cont_extent, cont_offset, cont_size;
  198. int flag1, flag2;
  199. unsigned char *pnts;
  200. char symlinkname[1024];
  201. int goof;
  202. symlinkname[0] = 0;
  203. cont_extent = cont_offset = cont_size = 0;
  204. ncount = 0;
  205. flag1 = flag2 = 0;
  206. while(len >= 4){
  207. if(pnt[3] != 1 && pnt[3] != 2) {
  208.   printf("**BAD RRVERSION (%d)n", pnt[3]);
  209.   return 0; /* JS ??? Is this right ??? */
  210. };
  211. ncount++;
  212. if(pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff;
  213. if(strncmp((char *)pnt, "PX", 2) == 0) flag2 |= 1; /* POSIX attributes */
  214. if(strncmp((char *)pnt, "PN", 2) == 0) flag2 |= 2; /* POSIX devive number */
  215. if(strncmp((char *)pnt, "SL", 2) == 0) flag2 |= 4; /* Symlink */
  216. if(strncmp((char *)pnt, "NM", 2) == 0) flag2 |= 8; /* Alternate Name */
  217. if(strncmp((char *)pnt, "CL", 2) == 0) flag2 |= 16; /* Child link */
  218. if(strncmp((char *)pnt, "PL", 2) == 0) flag2 |= 32; /* Parent link */
  219. if(strncmp((char *)pnt, "RE", 2) == 0) flag2 |= 64; /* Relocated Direcotry */
  220. if(strncmp((char *)pnt, "TF", 2) == 0) flag2 |= 128; /* Time stamp */
  221. if(strncmp((char *)pnt, "PX", 2) == 0) { /* POSIX attributes */
  222. fstat_buf.st_mode = isonum_733(pnt+4);
  223. fstat_buf.st_nlink = isonum_733(pnt+12);
  224. fstat_buf.st_uid = isonum_733(pnt+20);
  225. fstat_buf.st_gid = isonum_733(pnt+28);
  226. };
  227. if(strncmp((char *)pnt, "NM", 2) == 0) { /* Alternate Name */
  228.   strncpy(name_buf, (char *)(pnt+5), pnt[2] - 5);
  229.   name_buf[pnt[2] - 5] = 0;
  230. }
  231. if(strncmp((char *)pnt, "CE", 2) == 0) { /* Continuation Area */
  232. cont_extent = isonum_733(pnt+4);
  233. cont_offset = isonum_733(pnt+12);
  234. cont_size = isonum_733(pnt+20);
  235. };
  236. if(strncmp((char *)pnt, "PL", 2) == 0 || strncmp((char *)pnt, "CL", 2) == 0) {
  237. extent = isonum_733(pnt+4);
  238. };
  239. if(strncmp((char *)pnt, "SL", 2) == 0) { /* Symlink */
  240.         int cflag;
  241. cflag = pnt[4];
  242. pnts = pnt+5;
  243. slen = pnt[2] - 5;
  244. while(slen >= 1){
  245. switch(pnts[0] & 0xfe){
  246. case 0:
  247. strncat(symlinkname, (char *)(pnts+2), pnts[1]);
  248. break;
  249. case 2:
  250. strcat (symlinkname, ".");
  251. break;
  252. case 4:
  253. strcat (symlinkname, "..");
  254. break;
  255. case 8:
  256. if((pnts[0] & 1) == 0)strcat (symlinkname, "/");
  257. break;
  258. case 16:
  259. strcat(symlinkname,"/mnt");
  260. printf("Warning - mount point requested");
  261. break;
  262. case 32:
  263. strcat(symlinkname,"kafka");
  264. printf("Warning - host_name requested");
  265. break;
  266. default:
  267. printf("Reserved bit setting in symlink");
  268. goof++;
  269. break;
  270. };
  271. if((pnts[0] & 0xfe) && pnts[1] != 0) {
  272. printf("Incorrect length in symlink component");
  273. };
  274. if((pnts[0] & 1) == 0) strcat(symlinkname,"/");
  275. slen -= (pnts[1] + 2);
  276. pnts += (pnts[1] + 2);
  277. if(xname[0] == 0) strcpy(xname, "-> ");
  278. strcat(xname, symlinkname);
  279.        };
  280. symlinkname[0] = 0;
  281. };
  282. len -= pnt[2];
  283. pnt += pnt[2];
  284. if(len <= 3 && cont_extent) {
  285.   unsigned char sector[2048];
  286.   lseek(fileno(infile), (cont_extent - sector_offset) << 11, 0);
  287.   read(fileno(infile), sector, sizeof(sector));
  288.   flag2 |= parse_rr(&sector[cont_offset], cont_size, 1);
  289. };
  290. };
  291. return flag2;
  292. }
  293. void
  294. dump_rr(idr)
  295. struct iso_directory_record *idr;
  296. {
  297. int len;
  298. unsigned char * pnt;
  299. len = idr->length[0] & 0xff;
  300. len -= sizeof(struct iso_directory_record);
  301. len += sizeof(idr->name);
  302. len -= idr->name_len[0];
  303. pnt = (unsigned char *) idr;
  304. pnt += sizeof(struct iso_directory_record);
  305. pnt -= sizeof(idr->name);
  306. pnt += idr->name_len[0];
  307. if((idr->name_len[0] & 1) == 0){
  308. pnt++;
  309. len--;
  310. };
  311. parse_rr(pnt, len, 0);
  312. }
  313. struct todo
  314. {
  315.   struct todo * next;
  316.   char * name;
  317.   int extent;
  318.   int length;
  319. };
  320. struct todo * todo_idr = NULL;
  321. char * months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
  322.        "Aug", "Sep", "Oct", "Nov", "Dec"};
  323. void
  324. dump_stat(extent)
  325. int extent;
  326. {
  327.   int i;
  328.   char outline[80];
  329.   memset(outline, ' ', sizeof(outline));
  330.   if(S_ISREG(fstat_buf.st_mode))
  331.     outline[0] = '-';
  332.   else   if(S_ISDIR(fstat_buf.st_mode))
  333.     outline[0] = 'd';
  334.   else   if(S_ISLNK(fstat_buf.st_mode))
  335.     outline[0] = 'l';
  336.   else   if(S_ISCHR(fstat_buf.st_mode))
  337.     outline[0] = 'c';
  338.   else   if(S_ISBLK(fstat_buf.st_mode))
  339.     outline[0] = 'b';
  340.   else   if(S_ISFIFO(fstat_buf.st_mode))
  341.     outline[0] = 'f';
  342.   else   if(S_ISSOCK(fstat_buf.st_mode))
  343.     outline[0] = 's';
  344.   else
  345.     outline[0] = '?';
  346.   memset(outline+1, '-', 9);
  347.   if( fstat_buf.st_mode & S_IRUSR )
  348.     outline[1] = 'r';
  349.   if( fstat_buf.st_mode & S_IWUSR )
  350.     outline[2] = 'w';
  351.   if( fstat_buf.st_mode & S_IXUSR )
  352.     outline[3] = 'x';
  353.   if( fstat_buf.st_mode & S_IRGRP )
  354.     outline[4] = 'r';
  355.   if( fstat_buf.st_mode & S_IWGRP )
  356.     outline[5] = 'w';
  357.   if( fstat_buf.st_mode & S_IXGRP )
  358.     outline[6] = 'x';
  359.   if( fstat_buf.st_mode & S_IROTH )
  360.     outline[7] = 'r';
  361.   if( fstat_buf.st_mode & S_IWOTH )
  362.     outline[8] = 'w';
  363.   if( fstat_buf.st_mode & S_IXOTH )
  364.     outline[9] = 'x';
  365.   sprintf(outline+11, "%3ld", (long)fstat_buf.st_nlink);
  366.   sprintf(outline+15, "%4lo", (unsigned long)fstat_buf.st_uid);
  367.   sprintf(outline+20, "%4lo", (unsigned long)fstat_buf.st_gid);
  368.   sprintf(outline+33, "%8ld", (long)fstat_buf.st_size);
  369.   if( date_buf[1] >= 1 && date_buf[1] <= 12 )
  370.     {
  371.       memcpy(outline+42, months[date_buf[1]-1], 3);
  372.     }
  373.   sprintf(outline+46, "%2d", date_buf[2]);
  374.   sprintf(outline+49, "%4d", date_buf[0]+1900);
  375.   sprintf(outline+54, "[%6d]", extent);
  376.   for(i=0; i<63; i++)
  377.     if(outline[i] == 0) outline[i] = ' ';
  378.   outline[63] = 0;
  379.   printf("%s %s %sn", outline, name_buf, xname);
  380. }
  381. void
  382. extract_file(idr)
  383. struct iso_directory_record *idr;
  384. {
  385.   int extent, len, tlen;
  386.   unsigned char buff[2048];
  387.   extent = isonum_733((unsigned char *)idr->extent);
  388.   len = isonum_733((unsigned char *)idr->size);
  389.   while(len > 0)
  390.     {
  391.       lseek(fileno(infile), (extent - sector_offset) << 11, 0);
  392.       tlen = (len > sizeof(buff) ? sizeof(buff) : len);
  393.       read(fileno(infile), buff, tlen);
  394.       len -= tlen;
  395.       extent++;
  396.       write(1, buff, tlen);
  397.     }
  398. }
  399. void
  400. parse_dir(rootname, extent, len)
  401. char *rootname;
  402. int extent;
  403. int len;
  404. {
  405.   char testname[256];
  406.   struct todo * td;
  407.   int i;
  408.   struct iso_directory_record * idr;
  409.   if( do_listing)
  410.     printf("nDirectory listing of %sn", rootname);
  411.   while(len > 0 )
  412.     {
  413.       lseek(fileno(infile), (extent - sector_offset) << 11, 0);
  414.       read(fileno(infile), buffer, sizeof(buffer));
  415.       len -= sizeof(buffer);
  416.       extent++;
  417.       i = 0;
  418.       while(1==1){
  419. idr = (struct iso_directory_record *) &buffer[i];
  420. if(idr->length[0] == 0) break;
  421. memset(&fstat_buf, 0, sizeof(fstat_buf));
  422. name_buf[0] = xname[0] = 0;
  423. fstat_buf.st_size = isonum_733((unsigned char *)idr->size);
  424. if( idr->flags[0] & 2)
  425.   fstat_buf.st_mode |= S_IFDIR;
  426. else
  427.   fstat_buf.st_mode |= S_IFREG;
  428. if(idr->name_len[0] == 1 && idr->name[0] == 0)
  429.   strcpy(name_buf, ".");
  430. else if(idr->name_len[0] == 1 && idr->name[0] == 1)
  431.   strcpy(name_buf, "..");
  432. else {
  433.   switch(ucs_level)
  434.     {
  435.     case 3:
  436.     case 2:
  437.     case 1:
  438.       /*
  439.        * Unicode name.  Convert as best we can.
  440.        */
  441.       {
  442. int j;
  443. for(j=0; j < idr->name_len[0] / 2; j++)
  444.   {
  445.     name_buf[j] = idr->name[j*2+1];
  446.   }
  447. name_buf[idr->name_len[0]/2] = '';
  448.       }
  449.       break;
  450.     case 0:
  451.       /*
  452.        * Normal non-Unicode name.
  453.        */
  454.       strncpy(name_buf, idr->name, idr->name_len[0]);
  455.       name_buf[idr->name_len[0]] = 0;
  456.       break;
  457.     default:
  458.       /*
  459.        * Don't know how to do these yet.  Maybe they are the same
  460.        * as one of the above.
  461.        */
  462.       exit(1);
  463.     }
  464. };
  465. memcpy(date_buf, idr->date, 9);
  466. if(use_rock) dump_rr(idr);
  467. if(   (idr->flags[0] & 2) != 0
  468.    && (idr->name_len[0] != 1
  469.        || (idr->name[0] != 0 && idr->name[0] != 1)))
  470.   {
  471.     /*
  472.      * Add this directory to the todo list.
  473.      */
  474.     td = todo_idr;
  475.     if( td != NULL ) 
  476.       {
  477. while(td->next != NULL) td = td->next;
  478. td->next = (struct todo *) malloc(sizeof(*td));
  479. td = td->next;
  480.       }
  481.     else
  482.       {
  483. todo_idr = td = (struct todo *) malloc(sizeof(*td));
  484.       }
  485.     td->next = NULL;
  486.     td->extent = isonum_733((unsigned char *)idr->extent);
  487.     td->length = isonum_733((unsigned char *)idr->size);
  488.     td->name = (char *) malloc(strlen(rootname) 
  489.        + strlen(name_buf) + 2);
  490.     strcpy(td->name, rootname);
  491.     strcat(td->name, name_buf);
  492.     strcat(td->name, "/");
  493.   }
  494. else
  495.   {
  496.     strcpy(testname, rootname);
  497.     strcat(testname, name_buf);
  498.     if(xtract && strcmp(xtract, testname) == 0)
  499.       {
  500. extract_file(idr);
  501.       }
  502.   }
  503. if(   do_find
  504.    && (idr->name_len[0] != 1
  505.        || (idr->name[0] != 0 && idr->name[0] != 1)))
  506.   {
  507.     strcpy(testname, rootname);
  508.     strcat(testname, name_buf);
  509.     printf("%sn", testname);
  510.   }
  511. if(do_listing)
  512.   dump_stat(isonum_733((unsigned char *)idr->extent));
  513. i += buffer[i];
  514. if (i > 2048 - sizeof(struct iso_directory_record)) break;
  515.       }
  516.     }
  517. }
  518. void
  519. usage(excode)
  520. int excode;
  521. {
  522. errmsgno(EX_BAD, "Usage: %s [options]n",
  523.                 get_progname());
  524. error("Options:n");
  525. error("t-h Print this helpn");
  526. error("t-d Print information from the primary volume descriptorn");
  527. error("t-f Generate output similar to 'find .  -print'n");
  528. error("t-J Print information from from Joliet extensionsn");
  529. error("t-l Generate output similar to 'ls -lR'n");
  530. error("t-p Print Path Tablen");
  531. error("t-R Print information from from Rock Ridge extensionsn");
  532. error("t-N sector Sector number where ISO image should start on CDn");
  533. error("t-T sector Sector number where actual session starts on CDn");
  534. error("t-i filename Filename to read ISO-9660 image fromn");
  535. error("t-x pathname Extract specified file to stdoutn");
  536. exit(excode);
  537. }
  538. int
  539. main(argc, argv)
  540. int argc;
  541. char *argv[];
  542. {
  543.   int c;
  544.   char * filename = NULL;
  545.   int toc_offset = 0;
  546.   struct todo * td;
  547.   struct iso_primary_descriptor ipd;
  548.   struct iso_directory_record * idr;
  549. save_args(argc, argv);
  550.   if(argc < 2)
  551. usage(EX_BAD);
  552.   while ((c = getopt(argc, argv, "hdpi:JRlx:fN:T:")) != EOF)
  553.     switch (c)
  554.       {
  555.       case 'h':
  556. usage(0);
  557. break;
  558.       case 'd':
  559. do_pvd++;
  560. break;
  561.       case 'f':
  562. do_find++;
  563. break;
  564.       case 'p':
  565. do_pathtab++;
  566. break;
  567.       case 'R':
  568. use_rock++;
  569. break;
  570.       case 'J':
  571. use_joliet++;
  572. break;
  573.       case 'l':
  574. do_listing++;
  575. break;
  576.       case 'T':
  577. /*
  578.  * This is used if we have a complete multi-session
  579.  * disc that we want/need to play with.
  580.  * Here we specify the offset where we want to
  581.  * start searching for the TOC.
  582.  */
  583. toc_offset = atol(optarg);
  584. break;
  585.       case 'N':
  586. /*
  587.  * Use this if we have an image of a single session
  588.  * and we need to list the directory contents.
  589.  * This is the session block number of the start
  590.  * of the session.
  591.  */
  592. sector_offset = atol(optarg);
  593. break;
  594.       case 'i':
  595. filename = optarg;
  596. break;
  597.       case 'x':
  598. xtract = optarg;
  599. break;
  600.       default:
  601. usage(EX_BAD);
  602.       }
  603.   
  604.   if( filename == NULL )
  605.   {
  606. #ifdef USE_LIBSCHILY
  607. comerrno(EX_BAD, "Error - file not specifiedn");
  608. #else
  609. fprintf(stderr, "Error - file not specifiedn");
  610.    exit(1);
  611. #endif
  612.   }
  613.   infile = fopen(filename,"rb");
  614.   if( infile == NULL )
  615.   {
  616. #ifdef USE_LIBSCHILY
  617. comerr("Unable to open file %sn", filename);
  618. #else
  619. fprintf(stderr,"Unable to open file %sn", filename);
  620. exit(1);
  621. #endif
  622.   }
  623.   /*
  624.    * Absolute sector offset, so don't subtract sector_offset here.
  625.    */
  626.   lseek(fileno(infile), (16 + toc_offset) <<11, 0);
  627.   read(fileno(infile), &ipd, sizeof(ipd));
  628.   if (do_pvd) {
  629. printf("CD-ROM is in ISO 9660 formatn");
  630. printf("System id: ");
  631. printchars(ipd.system_id, 32);
  632. putchar('n');
  633. printf("Volume id: ");
  634. printchars(ipd.volume_id, 32);
  635. putchar('n');
  636. printf("Volume set id: ");
  637. printchars(ipd.volume_set_id, 128);
  638. putchar('n');
  639. printf("Publisher id: ");
  640. printchars(ipd.publisher_id, 128);
  641. putchar('n');
  642. printf("Data preparer id: ");
  643. printchars(ipd.preparer_id, 128);
  644. putchar('n');
  645. printf("Application id: ");
  646. printchars(ipd.application_id, 128);
  647. putchar('n');
  648. printf("Copyright File id: ");
  649. printchars(ipd.copyright_file_id, 37);
  650. putchar('n');
  651. printf("Abstract File id: ");
  652. printchars(ipd.abstract_file_id, 37);
  653. putchar('n');
  654. printf("Bibliographic File id: ");
  655. printchars(ipd.bibliographic_file_id, 37);
  656. putchar('n');
  657. printf("Volume set size is: %dn", isonum_723(ipd.volume_set_size));
  658. printf("Volume set seqence number is: %dn", isonum_723(ipd.volume_sequence_number));
  659. printf("Logical block size is: %dn", isonum_723(ipd.logical_block_size));
  660. printf("Volume size is: %dn", isonum_733((unsigned char *)ipd.volume_space_size));
  661. exit(0);
  662.   }
  663.   if( use_joliet )
  664.     {
  665.       int block = 16;
  666.       while( (unsigned char) ipd.type[0] != ISO_VD_END )
  667. {
  668.   /*
  669.    * Find the UCS escape sequence.
  670.    */
  671.   if(    ipd.escape_sequences[0] == '%'
  672.       && ipd.escape_sequences[1] == '/'
  673.       && ipd.escape_sequences[3] == ''
  674.       && (    ipd.escape_sequences[2] == '@'
  675.    || ipd.escape_sequences[2] == 'C'
  676.    || ipd.escape_sequences[2] == 'E') )
  677.     {
  678.       break;
  679.     }
  680.   block++;
  681.   lseek(fileno(infile), (block + toc_offset) <<11, 0);
  682.   read(fileno(infile), &ipd, sizeof(ipd));
  683. }
  684.       if( (unsigned char) ipd.type[0] == ISO_VD_END )
  685. {
  686. #ifdef USE_LIBSCHILY
  687.   comerrno(EX_BAD, "Unable to find Joliet SVDn");
  688. #else
  689.   fprintf(stderr, "Unable to find Joliet SVDn");
  690.   exit(1);
  691. #endif
  692. }
  693.       switch(ipd.escape_sequences[2])
  694. {
  695. case '@':
  696.   ucs_level = 1;
  697.   break;
  698. case 'C':
  699.   ucs_level = 2;
  700.   break;
  701. case 'E':
  702.   ucs_level = 3;
  703.   break;
  704. }
  705.       if( ucs_level > 3 )
  706. {
  707. #ifdef USE_LIBSCHILY
  708.   comerrno(EX_BAD, "Don't know what ucs_level == %d meansn", ucs_level);
  709. #else
  710.   fprintf(stderr, "Don't know what ucs_level == %d meansn", ucs_level);
  711.   exit(1);
  712. #endif
  713. }
  714.     }
  715.   idr = (struct iso_directory_record *)ipd.root_directory_record;
  716.   if( do_pathtab )
  717.     {
  718.       dump_pathtab(isonum_731(ipd.type_l_path_table), 
  719.    isonum_733((unsigned char *)ipd.path_table_size));
  720.     }
  721.   parse_dir("/", isonum_733((unsigned char *)idr->extent), isonum_733((unsigned char *)idr->size));
  722.   td = todo_idr;
  723.   while(td)
  724.     {
  725.       parse_dir(td->name, td->extent, td->length);
  726.       td = td->next;
  727.     }
  728.   fclose(infile);
  729.   return(0);
  730. }