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

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