home *** CD-ROM | disk | FTP | other *** search
/ Dream 49 / Amiga_Dream_49.iso / beos / utils / mkisofs-1.000 / mkisofs-1.11-beos / diag / isodump.c < prev    next >
C/C++ Source or Header  |  1997-04-09  |  12KB  |  478 lines

  1. /*
  2.  * File isodump.c - dump iso9660 directory information.
  3.  *
  4.  
  5.    Written by Eric Youngdale (1993).
  6.  
  7.    Copyright 1993 Yggdrasil Computing, Incorporated
  8.  
  9.    This program is free software; you can redistribute it and/or modify
  10.    it under the terms of the GNU General Public License as published by
  11.    the Free Software Foundation; either version 2, or (at your option)
  12.    any later version.
  13.  
  14.    This program is distributed in the hope that it will be useful,
  15.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.    GNU General Public License for more details.
  18.  
  19.    You should have received a copy of the GNU General Public License
  20.    along with this program; if not, write to the Free Software
  21.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  22.  
  23. static char rcsid[] ="$Id: isodump.c,v 1.2 1997/02/23 19:11:24 eric Rel $";
  24.  
  25. #include "../config.h"
  26.  
  27. #include <stdio.h>
  28. #ifdef HAVE_TERMIOS_H
  29. #include <termios.h>
  30. #include <sys/ioctl.h>
  31. #else
  32. #include <termio.h>
  33. #endif
  34. #include <signal.h>
  35.  
  36. FILE * infile;
  37. int file_addr;
  38. unsigned char buffer[2048];
  39. unsigned char search[64];
  40. int blocksize;
  41.  
  42. #define PAGE sizeof(buffer)
  43.  
  44. #define ISODCL(from, to) (to - from + 1)
  45.  
  46.  
  47. int
  48. isonum_731 (char * p)
  49. {
  50.     return ((p[0] & 0xff)
  51.         | ((p[1] & 0xff) << 8)
  52.         | ((p[2] & 0xff) << 16)
  53.         | ((p[3] & 0xff) << 24));
  54. }
  55.  
  56. int
  57. isonum_721 (char * p)
  58. {
  59.     return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
  60. }
  61.  
  62. int
  63. isonum_723 (char * p)
  64. {
  65. #if 0
  66.     if (p[0] != p[3] || p[1] != p[2]) {
  67.         fprintf (stderr, "invalid format 7.2.3 number\n");
  68.         exit (1);
  69.     }
  70. #endif
  71.     return (isonum_721 (p));
  72. }
  73.  
  74.  
  75. int
  76. isonum_733 (unsigned char * p)
  77. {
  78.     return (isonum_731 (p));
  79. }
  80.  
  81. struct iso_primary_descriptor {
  82.     unsigned char type            [ISODCL (  1,   1)]; /* 711 */
  83.     unsigned char id                [ISODCL (  2,   6)];
  84.     unsigned char version            [ISODCL (  7,   7)]; /* 711 */
  85.     unsigned char unused1            [ISODCL (  8,   8)];
  86.     unsigned char system_id            [ISODCL (  9,  40)]; /* aunsigned chars */
  87.     unsigned char volume_id            [ISODCL ( 41,  72)]; /* dunsigned chars */
  88.     unsigned char unused2            [ISODCL ( 73,  80)];
  89.     unsigned char volume_space_size        [ISODCL ( 81,  88)]; /* 733 */
  90.     unsigned char unused3            [ISODCL ( 89, 120)];
  91.     unsigned char volume_set_size        [ISODCL (121, 124)]; /* 723 */
  92.     unsigned char volume_sequence_number    [ISODCL (125, 128)]; /* 723 */
  93.     unsigned char logical_block_size        [ISODCL (129, 132)]; /* 723 */
  94.     unsigned char path_table_size        [ISODCL (133, 140)]; /* 733 */
  95.     unsigned char type_l_path_table        [ISODCL (141, 144)]; /* 731 */
  96.     unsigned char opt_type_l_path_table    [ISODCL (145, 148)]; /* 731 */
  97.     unsigned char type_m_path_table        [ISODCL (149, 152)]; /* 732 */
  98.     unsigned char opt_type_m_path_table    [ISODCL (153, 156)]; /* 732 */
  99.     unsigned char root_directory_record    [ISODCL (157, 190)]; /* 9.1 */
  100.     unsigned char volume_set_id        [ISODCL (191, 318)]; /* dunsigned chars */
  101.     unsigned char publisher_id        [ISODCL (319, 446)]; /* achars */
  102.     unsigned char preparer_id        [ISODCL (447, 574)]; /* achars */
  103.     unsigned char application_id        [ISODCL (575, 702)]; /* achars */
  104.     unsigned char copyright_file_id        [ISODCL (703, 739)]; /* 7.5 dchars */
  105.     unsigned char abstract_file_id        [ISODCL (740, 776)]; /* 7.5 dchars */
  106.     unsigned char bibliographic_file_id    [ISODCL (777, 813)]; /* 7.5 dchars */
  107.     unsigned char creation_date        [ISODCL (814, 830)]; /* 8.4.26.1 */
  108.     unsigned char modification_date        [ISODCL (831, 847)]; /* 8.4.26.1 */
  109.     unsigned char expiration_date        [ISODCL (848, 864)]; /* 8.4.26.1 */
  110.     unsigned char effective_date        [ISODCL (865, 881)]; /* 8.4.26.1 */
  111.     unsigned char file_structure_version    [ISODCL (882, 882)]; /* 711 */
  112.     unsigned char unused4            [ISODCL (883, 883)];
  113.     unsigned char application_data        [ISODCL (884, 1395)];
  114.     unsigned char unused5            [ISODCL (1396, 2048)];
  115. };
  116.  
  117. struct iso_directory_record {
  118.     unsigned char length            [ISODCL (1, 1)]; /* 711 */
  119.     unsigned char ext_attr_length        [ISODCL (2, 2)]; /* 711 */
  120.     unsigned char extent            [ISODCL (3, 10)]; /* 733 */
  121.     unsigned char size            [ISODCL (11, 18)]; /* 733 */
  122.     unsigned char date            [ISODCL (19, 25)]; /* 7 by 711 */
  123.     unsigned char flags            [ISODCL (26, 26)];
  124.     unsigned char file_unit_size        [ISODCL (27, 27)]; /* 711 */
  125.     unsigned char interleave            [ISODCL (28, 28)]; /* 711 */
  126.     unsigned char volume_sequence_number    [ISODCL (29, 32)]; /* 723 */
  127.     unsigned char name_len        [ISODCL (33, 33)]; /* 711 */
  128.     unsigned char name            [1];
  129. };
  130.  
  131. #ifdef HAVE_TERMIOS_H
  132. struct termios savetty;
  133. struct termios newtty;
  134. #else
  135. struct termio savetty;
  136. struct termio newtty;
  137. #endif
  138.  
  139. reset_tty(){
  140. #ifdef HAVE_TERMIOS_H
  141.   if(tcsetattr(0, TCSANOW, &savetty) == -1)
  142. #else
  143.   if(ioctl(0, TCSETAF, &savetty)==-1)
  144. #endif
  145.     {
  146.       printf("cannot put tty into normal mode\n");
  147.       exit(1);
  148.     }
  149. }
  150.  
  151. set_tty(){
  152. #ifdef HAVE_TERMIOS_H
  153.   if(tcsetattr(0, TCSANOW, &newtty) == -1)
  154. #else
  155.   if(ioctl(0, TCSETAF, &newtty)==-1)
  156. #endif
  157.     {
  158.       printf("cannot put tty into raw mode\n");
  159.       exit(1);
  160.     }
  161. }
  162.  
  163. /* Come here when we get a suspend signal from the terminal */
  164.  
  165. void
  166. onsusp (int signo)
  167. {
  168.     /* ignore SIGTTOU so we don't get stopped if csh grabs the tty */
  169.     signal(SIGTTOU, SIG_IGN);
  170.     reset_tty ();
  171.     fflush (stdout);
  172.     signal(SIGTTOU, SIG_DFL);
  173.     /* Send the TSTP signal to suspend our process group */
  174.     signal(SIGTSTP, SIG_DFL);
  175. /*    sigsetmask(0);*/
  176.     kill (0, SIGTSTP);
  177.     /* Pause for station break */
  178.  
  179.     /* We're back */
  180.     signal (SIGTSTP, onsusp);
  181.     set_tty ();
  182. }
  183.  
  184.  
  185.  
  186. crsr2(int row, int col){
  187.   printf("\033[%d;%dH",row,col);
  188. }
  189.  
  190. int parse_rr(unsigned char * pnt, int len, int cont_flag)
  191. {
  192.     int slen;
  193.     int ncount;
  194.     int extent;
  195.     int cont_extent, cont_offset, cont_size;
  196.     int flag1, flag2;
  197.     unsigned char *pnts;
  198.     char symlink[1024];
  199.     char name[1024];
  200.     int goof;
  201. /*    printf(" RRlen=%d ", len); */
  202.  
  203.     symlink[0] = 0;
  204.  
  205.     cont_extent = cont_offset = cont_size = 0;
  206.  
  207.     ncount = 0;
  208.     flag1 = flag2 = 0;
  209.     while(len >= 4){
  210.         if(ncount) printf(",");
  211.         else printf("[");
  212.         printf("%c%c", pnt[0], pnt[1]);
  213.         if(pnt[3] != 1) {
  214.           printf("**BAD RRVERSION");
  215.           return;
  216.         };
  217.         ncount++;
  218.         if(pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff;
  219.         if(strncmp(pnt, "PX", 2) == 0) flag2 |= 1;
  220.         if(strncmp(pnt, "PN", 2) == 0) flag2 |= 2;
  221.         if(strncmp(pnt, "SL", 2) == 0) flag2 |= 4;
  222.         if(strncmp(pnt, "NM", 2) == 0) {
  223.           slen = pnt[2] - 5;
  224.           pnts = pnt+5;
  225.           if( (pnt[4] & 6) != 0 )
  226.             {
  227.               printf("*");
  228.             }
  229.           memset(name, 0, sizeof(name));
  230.           memcpy(name, pnts, slen);
  231.           printf("=%s", name);
  232.           flag2 |= 8;
  233.         }
  234.         if(strncmp(pnt, "CL", 2) == 0) flag2 |= 16;
  235.         if(strncmp(pnt, "PL", 2) == 0) flag2 |= 32;
  236.         if(strncmp(pnt, "RE", 2) == 0) flag2 |= 64;
  237.         if(strncmp(pnt, "TF", 2) == 0) flag2 |= 128;
  238.  
  239.         if(strncmp(pnt, "PX", 2) == 0) {
  240.             extent = isonum_733(pnt+12);
  241.             printf("=%x", extent);
  242.         };
  243.  
  244.         if(strncmp(pnt, "CE", 2) == 0) {
  245.             cont_extent = isonum_733(pnt+4);
  246.             cont_offset = isonum_733(pnt+12);
  247.             cont_size = isonum_733(pnt+20);
  248.             printf("=[%x,%x,%d]", cont_extent, cont_offset, 
  249.                    cont_size);
  250.         };
  251.  
  252.         if(strncmp(pnt, "PL", 2) == 0 || strncmp(pnt, "CL", 2) == 0) {
  253.             extent = isonum_733(pnt+4);
  254.             printf("=%x", extent);
  255.         };
  256.  
  257.         if(strncmp(pnt, "SL", 2) == 0) {
  258.                 int cflag;
  259.  
  260.             cflag = pnt[4];
  261.             pnts = pnt+5;
  262.             slen = pnt[2] - 5;
  263.             while(slen >= 1){
  264.                 switch(pnts[0] & 0xfe){
  265.                 case 0:
  266.                     strncat(symlink, pnts+2, pnts[1]);
  267.                     break;
  268.                 case 2:
  269.                     strcat (symlink, ".");
  270.                     break;
  271.                 case 4:
  272.                     strcat (symlink, "..");
  273.                     break;
  274.                 case 8:
  275.                     if((pnts[0] & 1) == 0)strcat (symlink, "/");
  276.                     break;
  277.                 case 16:
  278.                     strcat(symlink,"/mnt");
  279.                     printf("Warning - mount point requested");
  280.                     break;
  281.                 case 32:
  282.                     strcat(symlink,"kafka");
  283.                     printf("Warning - host_name requested");
  284.                     break;
  285.                 default:
  286.                     printf("Reserved bit setting in symlink", goof++);
  287.                     break;
  288.                 };
  289.                 if((pnts[0] & 0xfe) && pnts[1] != 0) {
  290.                     printf("Incorrect length in symlink component");
  291.                 };
  292.                 if((pnts[0] & 1) == 0) strcat(symlink,"/");
  293.  
  294.                 slen -= (pnts[1] + 2);
  295.                 pnts += (pnts[1] + 2);
  296.                 
  297.                };
  298.             if(cflag) strcat(symlink, "+");
  299.             printf("=%s", symlink);
  300.             symlink[0] = 0;
  301.         };
  302.  
  303.         len -= pnt[2];
  304.         pnt += pnt[2];
  305.         if(len <= 3 && cont_extent) {
  306.           unsigned char sector[2048];
  307.           lseek(fileno(infile), cont_extent * blocksize, 0);
  308.           read(fileno(infile), sector, sizeof(sector));
  309.           flag2 |= parse_rr(§or[cont_offset], cont_size, 1);
  310.         };
  311.     };
  312.     if(ncount) printf("]");
  313.     if (!cont_flag && flag1 != flag2) 
  314.       printf("Flag %x != %x", flag1, flag2, goof++);
  315.     return flag2;
  316. }
  317.  
  318. int 
  319. dump_rr(struct iso_directory_record * idr)
  320. {
  321.     int len;
  322.     unsigned char * pnt;
  323.  
  324.     len = idr->length[0] & 0xff;
  325.     len -= sizeof(struct iso_directory_record);
  326.     len += sizeof(idr->name);
  327.     len -= idr->name_len[0];
  328.     pnt = (unsigned char *) idr;
  329.     pnt += sizeof(struct iso_directory_record);
  330.     pnt -= sizeof(idr->name);
  331.     pnt += idr->name_len[0];
  332.     if((idr->name_len[0] & 1) == 0){
  333.         pnt++;
  334.         len--;
  335.     };
  336.     parse_rr(pnt, len, 0);
  337. }
  338.  
  339.  
  340. showblock(int flag){
  341.   unsigned int k;
  342.   int i, j;
  343.   int line;
  344.   struct iso_directory_record * idr;
  345.   lseek(fileno(infile), file_addr, 0);
  346.   read(fileno(infile), buffer, sizeof(buffer));
  347.   for(i=0;i<60;i++) printf("\n");
  348.   fflush(stdout);
  349.   i = line = 0;
  350.   if(flag) {
  351.       while(1==1){
  352.           crsr2(line+3,1);
  353.           idr = (struct iso_directory_record *) &buffer[i];
  354.           if(idr->length[0] == 0) break;
  355.           printf("%3d ", idr->length[0]);
  356.           printf("[%2d] ", idr->volume_sequence_number[0]);
  357.           printf("%5x ", isonum_733(idr->extent));
  358.           printf("%8d ", isonum_733(idr->size));
  359.           printf ((idr->flags[0] & 2) ? "*" : " "); 
  360.           if(idr->name_len[0] == 1 && idr->name[0] == 0)
  361.               printf(".             ");
  362.           else if(idr->name_len[0] == 1 && idr->name[0] == 1)
  363.               printf("..            ");
  364.           else {
  365.               for(j=0; j<idr->name_len[0]; j++) printf("%c", idr->name[j]);
  366.               for(j=0; j<14 -idr->name_len[0]; j++) printf(" ");
  367.           };
  368.           dump_rr(idr);
  369.           printf("\n");
  370.           i += buffer[i];
  371.           if (i > 2048 - sizeof(struct iso_directory_record)) break;
  372.           line++;
  373.       };
  374.   };
  375.   printf("\n");
  376.   printf(" Zone, zone offset: %6x %4.4x  ",file_addr / blocksize, 
  377.      file_addr & (blocksize - 1));
  378.   fflush(stdout);
  379. }
  380.  
  381. getbyte()
  382. {
  383.   char c1;
  384.   c1 = buffer[file_addr & (blocksize-1)];
  385.   file_addr++;
  386.   if ((file_addr & (blocksize-1)) == 0) showblock(0);
  387.   return c1;
  388. }
  389.  
  390. main(int argc, char * argv[]){
  391.   char c;
  392.   char buffer[2048];
  393.   int nbyte;
  394.   int i,j;
  395.   struct iso_primary_descriptor ipd;
  396.   struct iso_directory_record * idr;
  397.  
  398.   if(argc < 2) return 0;
  399.   infile = fopen(argv[1],"rb");
  400.  
  401.   file_addr = 16 << 11;
  402.   lseek(fileno(infile), file_addr, 0);
  403.   read(fileno(infile), &ipd, sizeof(ipd));
  404.  
  405.   idr = (struct iso_directory_record *) &ipd.root_directory_record;
  406.  
  407.   blocksize = isonum_723(ipd.logical_block_size);
  408.   if( blocksize != 512 && blocksize != 1024 && blocksize != 2048 )
  409.     {
  410.       blocksize = 2048;
  411.     }
  412.  
  413.   file_addr = isonum_733(idr->extent);
  414.  
  415.   file_addr = file_addr * blocksize;
  416.  
  417. /* Now setup the keyboard for single character input. */
  418. #ifdef HAVE_TERMIOS_H 
  419.     if(tcgetattr(0, &savetty) == -1)
  420. #else
  421.     if(ioctl(0, TCGETA, &savetty) == -1)
  422. #endif
  423.       {
  424.         printf("stdin must be a tty\n");
  425.         exit(1);
  426.       }
  427.     newtty=savetty;
  428.     newtty.c_lflag&=~ICANON;
  429.     newtty.c_lflag&=~ECHO;
  430.     newtty.c_cc[VMIN]=1;
  431.       set_tty();
  432.     signal(SIGTSTP, onsusp);
  433.  
  434.   do{
  435.     if(file_addr < 0) file_addr = 0;
  436.     showblock(1);
  437.     read (0, &c, 1);
  438.     if (c == 'a') file_addr -= blocksize;
  439.     if (c == 'b') file_addr += blocksize;
  440.     if (c == 'g') {
  441.       crsr2(20,1);
  442.       printf("Enter new starting block (in hex):");
  443.       scanf("%x",&file_addr);
  444.       file_addr = file_addr * blocksize;
  445.       crsr2(20,1);
  446.       printf("                                     ");
  447.     };
  448.     if (c == 'f') {
  449.       crsr2(20,1);
  450.       printf("Enter new search string:");
  451.       fgets(search,sizeof(search),stdin);
  452.       while(search[strlen(search)-1] == '\n') search[strlen(search)-1] = 0;
  453.       crsr2(20,1);
  454.       printf("                                     ");
  455.     };
  456.     if (c == '+') {
  457.       while(1==1){
  458.     while(1==1){
  459.       c = getbyte(&file_addr);
  460.       if (c == search[0]) break;
  461.     };
  462.     for (j=1;j<strlen(search);j++) 
  463.       if(search[j] != getbyte()) break;
  464.     if(j==strlen(search)) break;
  465.       };
  466.       file_addr &= ~(blocksize-1);
  467.       showblock(1);
  468.     };
  469.     if (c == 'q') break;
  470.   } while(1==1);
  471.   reset_tty();
  472.   fclose(infile);
  473. }
  474.   
  475.  
  476.  
  477.  
  478.