~ubuntu-branches/ubuntu/hoary/cdrtools/hoary

« back to all changes in this revision

Viewing changes to mkisofs/diag/isovfy.c

  • Committer: Bazaar Package Importer
  • Author(s): Eduard Bloch
  • Date: 2002-04-09 10:03:06 UTC
  • Revision ID: james.westby@ubuntu.com-20020409100306-t4hagiv7gm0fhggv
Tags: upstream-1.10
ImportĀ upstreamĀ versionĀ 1.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* @(#)isovfy.c 1.15 00/12/09 joerg */
 
2
#ifndef lint
 
3
static  char sccsid[] =
 
4
        "@(#)isovfy.c   1.15 00/12/09 joerg";
 
5
#endif
 
6
/*
 
7
 * File isovfy.c - verify consistency of iso9660 filesystem.
 
8
 *
 
9
 
 
10
   Written by Eric Youngdale (1993).
 
11
 
 
12
   Copyright 1993 Yggdrasil Computing, Incorporated
 
13
 
 
14
   This program is free software; you can redistribute it and/or modify
 
15
   it under the terms of the GNU General Public License as published by
 
16
   the Free Software Foundation; either version 2, or (at your option)
 
17
   any later version.
 
18
 
 
19
   This program is distributed in the hope that it will be useful,
 
20
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
21
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
22
   GNU General Public License for more details.
 
23
 
 
24
   You should have received a copy of the GNU General Public License
 
25
   along with this program; if not, write to the Free Software
 
26
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
27
 
 
28
#include <mconfig.h>
 
29
#include <stdxlib.h>
 
30
#include <unixstd.h>
 
31
#include <strdefs.h>
 
32
#include <utypes.h>
 
33
 
 
34
#include <stdio.h>
 
35
#include <standard.h>
 
36
#include <signal.h>
 
37
#include <schily.h>
 
38
 
 
39
FILE * infile;
 
40
int blocksize;
 
41
 
 
42
#define PAGE sizeof(buffer)
 
43
 
 
44
#define ISODCL(from, to) (to - from + 1)
 
45
 
 
46
struct iso_primary_descriptor {
 
47
        unsigned char type                      [ISODCL (  1,   1)]; /* 711 */
 
48
        unsigned char id                                [ISODCL (  2,   6)];
 
49
        unsigned char version                   [ISODCL (  7,   7)]; /* 711 */
 
50
        unsigned char unused1                   [ISODCL (  8,   8)];
 
51
        unsigned char system_id                 [ISODCL (  9,  40)]; /* aunsigned chars */
 
52
        unsigned char volume_id                 [ISODCL ( 41,  72)]; /* dunsigned chars */
 
53
        unsigned char unused2                   [ISODCL ( 73,  80)];
 
54
        unsigned char volume_space_size         [ISODCL ( 81,  88)]; /* 733 */
 
55
        unsigned char unused3                   [ISODCL ( 89, 120)];
 
56
        unsigned char volume_set_size           [ISODCL (121, 124)]; /* 723 */
 
57
        unsigned char volume_sequence_number    [ISODCL (125, 128)]; /* 723 */
 
58
        unsigned char logical_block_size                [ISODCL (129, 132)]; /* 723 */
 
59
        unsigned char path_table_size           [ISODCL (133, 140)]; /* 733 */
 
60
        unsigned char type_l_path_table         [ISODCL (141, 144)]; /* 731 */
 
61
        unsigned char opt_type_l_path_table     [ISODCL (145, 148)]; /* 731 */
 
62
        unsigned char type_m_path_table         [ISODCL (149, 152)]; /* 732 */
 
63
        unsigned char opt_type_m_path_table     [ISODCL (153, 156)]; /* 732 */
 
64
        unsigned char root_directory_record     [ISODCL (157, 190)]; /* 9.1 */
 
65
        unsigned char volume_set_id             [ISODCL (191, 318)]; /* dunsigned chars */
 
66
        unsigned char publisher_id              [ISODCL (319, 446)]; /* achars */
 
67
        unsigned char preparer_id               [ISODCL (447, 574)]; /* achars */
 
68
        unsigned char application_id            [ISODCL (575, 702)]; /* achars */
 
69
        unsigned char copyright_file_id         [ISODCL (703, 739)]; /* 7.5 dchars */
 
70
        unsigned char abstract_file_id          [ISODCL (740, 776)]; /* 7.5 dchars */
 
71
        unsigned char bibliographic_file_id     [ISODCL (777, 813)]; /* 7.5 dchars */
 
72
        unsigned char creation_date             [ISODCL (814, 830)]; /* 8.4.26.1 */
 
73
        unsigned char modification_date         [ISODCL (831, 847)]; /* 8.4.26.1 */
 
74
        unsigned char expiration_date           [ISODCL (848, 864)]; /* 8.4.26.1 */
 
75
        unsigned char effective_date            [ISODCL (865, 881)]; /* 8.4.26.1 */
 
76
        unsigned char file_structure_version    [ISODCL (882, 882)]; /* 711 */
 
77
        unsigned char unused4                   [ISODCL (883, 883)];
 
78
        unsigned char application_data          [ISODCL (884, 1395)];
 
79
        unsigned char unused5                   [ISODCL (1396, 2048)];
 
80
};
 
81
 
 
82
struct iso_directory_record {
 
83
        unsigned char length                    [ISODCL (1, 1)]; /* 711 */
 
84
        unsigned char ext_attr_length           [ISODCL (2, 2)]; /* 711 */
 
85
        unsigned char extent                    [ISODCL (3, 10)]; /* 733 */
 
86
        unsigned char size                      [ISODCL (11, 18)]; /* 733 */
 
87
        unsigned char date                      [ISODCL (19, 25)]; /* 7 by 711 */
 
88
        unsigned char flags                     [ISODCL (26, 26)];
 
89
        unsigned char file_unit_size            [ISODCL (27, 27)]; /* 711 */
 
90
        unsigned char interleave                        [ISODCL (28, 28)]; /* 711 */
 
91
        unsigned char volume_sequence_number    [ISODCL (29, 32)]; /* 723 */
 
92
        unsigned char name_len          [ISODCL (33, 33)]; /* 711 */
 
93
        unsigned char name                      [38];
 
94
};
 
95
 
 
96
int     isonum_721      __PR((char * p));
 
97
int     isonum_723      __PR((char * p));
 
98
int     isonum_711      __PR((char * p));
 
99
int     isonum_731      __PR((char * p));
 
100
int     isonum_722      __PR((char * p));
 
101
int     isonum_732      __PR((char * p));
 
102
int     isonum_733      __PR((unsigned char * p));
 
103
int     parse_rr        __PR((unsigned char * pnt, int len, int cont_flag));
 
104
int     dump_rr         __PR((struct iso_directory_record * idr));
 
105
void    check_tree      __PR((off_t file_addr, int file_size, off_t parent_addr));
 
106
void    check_path_tables __PR((int typel_extent, int typem_extent, int path_table_size));
 
107
void    usage           __PR((int excode));
 
108
int     main            __PR((int argc, char *argv[]));
 
109
 
 
110
int
 
111
isonum_721 (p)
 
112
        char    *p;
 
113
{
 
114
        return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
 
115
}
 
116
 
 
117
int
 
118
isonum_723 (p)
 
119
        char    *p;
 
120
{
 
121
#if 0
 
122
        if (p[0] != p[3] || p[1] != p[2]) {
 
123
#ifdef  USE_LIBSCHILY
 
124
                comerrno(EX_BAD, "invalid format 7.2.3 number\n");
 
125
#else
 
126
                fprintf (stderr, "invalid format 7.2.3 number\n");
 
127
                exit (1);
 
128
#endif
 
129
        }
 
130
#endif
 
131
        return (isonum_721 (p));
 
132
}
 
133
 
 
134
int
 
135
isonum_711 (p)
 
136
        char    *p;
 
137
{
 
138
        return (*p & 0xff);
 
139
}
 
140
 
 
141
int
 
142
isonum_731 (p)
 
143
        char    *p;
 
144
{
 
145
        return ((p[0] & 0xff)
 
146
                | ((p[1] & 0xff) << 8)
 
147
                | ((p[2] & 0xff) << 16)
 
148
                | ((p[3] & 0xff) << 24));
 
149
}
 
150
 
 
151
int
 
152
isonum_722(p)
 
153
        char    *p;
 
154
{
 
155
        return ((p[1] & 0xff)
 
156
                | ((p[0] & 0xff) << 8));
 
157
}
 
158
 
 
159
int
 
160
isonum_732 (p)
 
161
        char    *p;
 
162
{
 
163
        return ((p[3] & 0xff)
 
164
                | ((p[2] & 0xff) << 8)
 
165
                | ((p[1] & 0xff) << 16)
 
166
                | ((p[0] & 0xff) << 24));
 
167
}
 
168
 
 
169
int
 
170
isonum_733 (p)
 
171
        unsigned char   *p;
 
172
{
 
173
        return (isonum_731 ((char *)p));
 
174
}
 
175
 
 
176
char lbuffer[1024];
 
177
int iline;
 
178
int rr_goof;
 
179
 
 
180
 
 
181
int parse_rr(pnt, len, cont_flag)
 
182
        unsigned char   *pnt;
 
183
        int             len;
 
184
        int             cont_flag;
 
185
{
 
186
        int slen;
 
187
        int ncount;
 
188
        int flag1, flag2;
 
189
        int extent;
 
190
        unsigned char *pnts;
 
191
        off_t cont_extent;
 
192
        int cont_offset, cont_size;
 
193
        char symlinkname[1024];
 
194
        sprintf(lbuffer+iline," RRlen=%d ", len);
 
195
        iline += strlen(lbuffer+iline);
 
196
 
 
197
        cont_extent = (off_t)0;
 
198
        cont_offset = cont_size = 0;
 
199
 
 
200
        symlinkname[0] = 0;
 
201
 
 
202
        ncount = 0;
 
203
        flag1 = flag2 = 0;
 
204
        while(len >= 4){
 
205
                if(ncount) sprintf(lbuffer+iline,",");
 
206
                else sprintf(lbuffer+iline,"[");
 
207
                iline += strlen(lbuffer + iline);
 
208
                sprintf(lbuffer+iline,"%c%c", pnt[0], pnt[1]);
 
209
                iline += strlen(lbuffer + iline);
 
210
                if(pnt[0] < 'A' || pnt[0] > 'Z' || pnt[1] < 'A' || 
 
211
                   pnt[1] > 'Z') {
 
212
                        sprintf(lbuffer+iline,"**BAD SUSP %d %d]", 
 
213
                                         pnt[0], pnt[1]);
 
214
                        rr_goof++;
 
215
                        iline += strlen(lbuffer + iline);
 
216
                        return flag2;
 
217
                };
 
218
 
 
219
                if(pnt[3] != 1 && pnt[3] != 2) {
 
220
                        sprintf(lbuffer+iline, "**BAD RRVERSION (%d)\n", pnt[3]);
 
221
                        rr_goof++;
 
222
                        iline += strlen(lbuffer + iline);
 
223
                        return flag2;
 
224
                };
 
225
                ncount++;
 
226
                if(pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff;
 
227
                if(strncmp((char *)pnt, "PX", 2) == 0) flag2 |= 1;
 
228
                if(strncmp((char *)pnt, "PN", 2) == 0) flag2 |= 2;
 
229
                if(strncmp((char *)pnt, "SL", 2) == 0) flag2 |= 4;
 
230
                if(strncmp((char *)pnt, "NM", 2) == 0) flag2 |= 8;
 
231
                if(strncmp((char *)pnt, "CL", 2) == 0) flag2 |= 16;
 
232
                if(strncmp((char *)pnt, "PL", 2) == 0) flag2 |= 32;
 
233
                if(strncmp((char *)pnt, "RE", 2) == 0) flag2 |= 64;
 
234
                if(strncmp((char *)pnt, "TF", 2) == 0) flag2 |= 128;
 
235
 
 
236
                if(strncmp((char *)pnt, "CE", 2) == 0) {
 
237
                        cont_extent = (off_t)isonum_733(pnt+4);
 
238
                        cont_offset = isonum_733(pnt+12);
 
239
                        cont_size = isonum_733(pnt+20);
 
240
                        sprintf(lbuffer+iline, "=[%x,%x,%d]",
 
241
                                         (int)cont_extent, cont_offset, cont_size);
 
242
                        iline += strlen(lbuffer + iline);
 
243
                      };
 
244
 
 
245
                if(strncmp((char *)pnt, "PL", 2) == 0 || strncmp((char *)pnt, "CL", 2) == 0) {
 
246
                        extent = isonum_733(pnt+4);
 
247
                        sprintf(lbuffer+iline,"=%x", extent);
 
248
                        iline += strlen(lbuffer + iline);
 
249
                        if(extent == 0) rr_goof++;
 
250
                };
 
251
                if(strncmp((char *)pnt, "SL", 2) == 0) {
 
252
                        pnts = pnt+5;
 
253
                        slen = pnt[2] - 5;
 
254
                        while(slen >= 1){
 
255
                                switch(pnts[0] & 0xfe){
 
256
                                case 0:
 
257
                                        strncat(symlinkname, (char *)(pnts+2), pnts[1]);
 
258
                                        break;
 
259
                                case 2:
 
260
                                        strcat (symlinkname, ".");
 
261
                                        break;
 
262
                                case 4:
 
263
                                        strcat (symlinkname, "..");
 
264
                                        break;
 
265
                                case 8:
 
266
                                        strcat (symlinkname, "/");
 
267
                                        break;
 
268
                                case 16:
 
269
                                        strcat(symlinkname,"/mnt");
 
270
                                        sprintf(lbuffer+iline,"Warning - mount point requested");
 
271
                                        iline += strlen(lbuffer + iline);
 
272
                                        break;
 
273
                                case 32:
 
274
                                        strcat(symlinkname,"kafka");
 
275
                                        sprintf(lbuffer+iline,"Warning - host_name requested");
 
276
                                        iline += strlen(lbuffer + iline);
 
277
                                        break;
 
278
                                default:
 
279
                                        sprintf(lbuffer+iline,"Reserved bit setting in symlink");
 
280
                                        rr_goof++;
 
281
                                        iline += strlen(lbuffer + iline);
 
282
                                        break;
 
283
                                };
 
284
                                if((pnts[0] & 0xfe) && pnts[1] != 0) {
 
285
                                        sprintf(lbuffer+iline,"Incorrect length in symlink component");
 
286
                                        iline += strlen(lbuffer + iline);
 
287
                                };
 
288
                                if((pnts[0] & 1) == 0)
 
289
                                  strcat(symlinkname,"/");
 
290
                                slen -= (pnts[1] + 2);
 
291
                                pnts += (pnts[1] + 2);
 
292
                                
 
293
                       };
 
294
                        if(symlinkname[0] != 0) {
 
295
                          sprintf(lbuffer+iline,"=%s", symlinkname);
 
296
                          iline += strlen(lbuffer + iline);
 
297
                          symlinkname[0] = 0;
 
298
                        }
 
299
                };
 
300
 
 
301
                len -= pnt[2];
 
302
                pnt += pnt[2];
 
303
                if(len <= 3 && cont_extent) {
 
304
                  unsigned char sector[2048];
 
305
                  lseek(fileno(infile), cont_extent * blocksize, SEEK_SET);
 
306
                  read(fileno(infile), sector, sizeof(sector));
 
307
                  flag2 |= parse_rr(&sector[cont_offset], cont_size, 1);
 
308
                };
 
309
        };
 
310
        if(ncount) 
 
311
          {
 
312
            sprintf(lbuffer+iline,"]");
 
313
            iline += strlen(lbuffer + iline);
 
314
          }
 
315
        if (!cont_flag && flag1 && flag1 != flag2) 
 
316
          {
 
317
            sprintf(lbuffer+iline,"Flag %x != %x", flag1, flag2);
 
318
            rr_goof++;
 
319
            iline += strlen(lbuffer + iline);
 
320
          }
 
321
        return flag2;
 
322
}
 
323
 
 
324
int 
 
325
dump_rr(idr)
 
326
        struct iso_directory_record *idr;
 
327
{
 
328
        int len;
 
329
        char * pnt;
 
330
 
 
331
        len = idr->length[0] & 0xff;
 
332
        len -= (sizeof(struct iso_directory_record) - sizeof(idr->name));
 
333
        len -= idr->name_len[0];
 
334
        pnt = (char *) idr;
 
335
        pnt += (sizeof(struct iso_directory_record) - sizeof(idr->name));
 
336
        pnt += idr->name_len[0];
 
337
 
 
338
        if((idr->name_len[0] & 1) == 0){
 
339
                pnt++;
 
340
                len--;
 
341
        };
 
342
 
 
343
        rr_goof = 0;
 
344
        parse_rr((unsigned char *)pnt, len, 0);
 
345
        return rr_goof;
 
346
}
 
347
 
 
348
 
 
349
int dir_count = 0;
 
350
int dir_size_count = 0;
 
351
int ngoof = 0;
 
352
 
 
353
void
 
354
check_tree(file_addr, file_size, parent_addr)
 
355
        off_t   file_addr;
 
356
        int     file_size;
 
357
        off_t   parent_addr;
 
358
{
 
359
  unsigned char buffer[2048];
 
360
  unsigned int k;
 
361
  int rflag = 0;
 
362
  int i, i1, j, goof;
 
363
  int extent, size;
 
364
  off_t orig_file_addr, parent_file_addr;
 
365
  struct iso_directory_record * idr;
 
366
 
 
367
  i1 = 0;
 
368
 
 
369
  orig_file_addr = file_addr / blocksize;  /* Actual extent of this directory */
 
370
  parent_file_addr = parent_addr / blocksize;
 
371
 
 
372
  if((dir_count % 100) == 0) printf("[%d %d]\n", dir_count, dir_size_count);
 
373
#if 0
 
374
        if (sizeof(file_addr) > sizeof(long)) {
 
375
                printf("Starting directory %ld %d %lld\n",
 
376
                                file_addr, file_size,
 
377
                                (Llong)parent_addr);
 
378
        } else {
 
379
                printf("Starting directory %ld %d %ld\n", file_addr, file_size, parent_addr);
 
380
        }
 
381
#endif
 
382
 
 
383
  dir_count++;
 
384
  dir_size_count += file_size / blocksize;
 
385
 
 
386
  if(file_size & 0x3ff) printf("********Directory has unusual size\n");
 
387
 
 
388
  for(k=0; k < (file_size / sizeof(buffer)); k++){
 
389
          lseek(fileno(infile), file_addr, SEEK_SET);
 
390
          read(fileno(infile), buffer, sizeof(buffer));
 
391
          i = 0;
 
392
          while(1==1){
 
393
                  goof = iline=0;
 
394
                  idr = (struct iso_directory_record *) &buffer[i];
 
395
                  if(idr->length[0] == 0) break;
 
396
                  sprintf(&lbuffer[iline],"%3d ", idr->length[0]);
 
397
                  iline += strlen(lbuffer + iline);
 
398
                  extent = isonum_733(idr->extent);
 
399
                  size = isonum_733(idr->size);
 
400
                  sprintf(&lbuffer[iline],"%5x ", extent);
 
401
                  iline += strlen(lbuffer + iline);
 
402
                  sprintf(&lbuffer[iline],"%8d ", size);
 
403
                  iline += strlen(lbuffer + iline);
 
404
                  sprintf (&lbuffer[iline], "%c", (idr->flags[0] & 2) ? '*' : ' '); 
 
405
                  iline += strlen(lbuffer + iline);
 
406
 
 
407
                  if(idr->name_len[0] > 33)
 
408
                    {
 
409
                      sprintf(&lbuffer[iline],"File name length=(%d)",
 
410
                              idr->name_len[0]);
 
411
                      goof++;
 
412
                      iline += strlen(lbuffer + iline);
 
413
                    }
 
414
                  else if(idr->name_len[0] == 1 && idr->name[0] == 0) {
 
415
                          sprintf(&lbuffer[iline],".             ");
 
416
                          iline += strlen(lbuffer + iline);
 
417
                          rflag = 0;
 
418
                          if(orig_file_addr !=(off_t)(isonum_733(idr->extent) + isonum_711((char *) idr->ext_attr_length)))
 
419
                            {
 
420
                              sprintf(&lbuffer[iline],"***** Directory has null extent.");
 
421
                              goof++;
 
422
                              iline += strlen(lbuffer + iline);
 
423
                            }
 
424
                          if(i1)
 
425
                            {
 
426
                              sprintf(&lbuffer[iline],"***** . not  first entry.");
 
427
                              rr_goof++;
 
428
                              iline += strlen(lbuffer + iline);
 
429
                            }
 
430
                  } else if(idr->name_len[0] == 1 && idr->name[0] == 1) {
 
431
                          sprintf(&lbuffer[iline],"..            ");
 
432
                          iline += strlen(lbuffer + iline);
 
433
                          rflag = 0;
 
434
                          if(parent_file_addr != (off_t)(isonum_733(idr->extent) + isonum_711((char *) idr->ext_attr_length)))
 
435
                            {
 
436
                              sprintf(&lbuffer[iline],"***** Directory has null extent.");
 
437
                              goof++;
 
438
                              iline += strlen(lbuffer + iline);
 
439
                            }
 
440
                          if(i1 != 1)
 
441
                            {
 
442
                              sprintf(&lbuffer[iline],"***** .. not second entry.");
 
443
                              rr_goof++;
 
444
                              iline += strlen(lbuffer + iline);
 
445
                            }
 
446
                          
 
447
                  } else {
 
448
                          if(i1 < 2) 
 
449
                            {
 
450
                              sprintf(&lbuffer[iline]," Improper sorting.");
 
451
                              rr_goof++;
 
452
                            }
 
453
                          for(j=0; j<idr->name_len[0]; j++) 
 
454
                            {
 
455
                              sprintf(&lbuffer[iline],"%c", idr->name[j]);
 
456
                            }
 
457
                          for(j=0; j<14 - (int) idr->name_len[0]; j++) 
 
458
                            {
 
459
                              sprintf(&lbuffer[iline]," ");
 
460
                              iline += strlen(lbuffer + iline);
 
461
                            }
 
462
                          rflag = 1;
 
463
                  };
 
464
 
 
465
                  if(size && extent == 0) 
 
466
                    {
 
467
                      sprintf(&lbuffer[iline],"****Extent==0, size != 0");
 
468
                      goof++;
 
469
                      iline += strlen(lbuffer + iline);
 
470
                    }
 
471
#if 0
 
472
                  /* This is apparently legal. */
 
473
                  if(size == 0 && extent) 
 
474
                    {
 
475
                      sprintf(&lbuffer[iline],"****Extent!=0, size == 0");
 
476
                      goof++;
 
477
                      iline += strlen(lbuffer + iline);
 
478
                    }
 
479
#endif
 
480
 
 
481
                  if(idr->flags[0] & 0xf5)
 
482
                    {
 
483
                          sprintf(&lbuffer[iline],"Flags=(%x) ", idr->flags[0]);
 
484
                          goof++;
 
485
                          iline += strlen(lbuffer + iline);
 
486
                    }
 
487
                  if(idr->interleave[0])
 
488
                    {
 
489
                          sprintf(&lbuffer[iline],"Interleave=(%d) ", idr->interleave[0]);
 
490
                          goof++;
 
491
                          iline += strlen(lbuffer + iline);
 
492
                    }
 
493
 
 
494
                  if(idr->file_unit_size[0])
 
495
                    {
 
496
                        sprintf(&lbuffer[iline],"File unit size=(%d) ", idr->file_unit_size[0]);
 
497
                        goof++;
 
498
                        iline += strlen(lbuffer + iline);
 
499
                    }
 
500
 
 
501
 
 
502
                  if(idr->volume_sequence_number[0] != 1)
 
503
                    {
 
504
                      sprintf(&lbuffer[iline],"Volume sequence number=(%d) ", idr->volume_sequence_number[0]);
 
505
                      goof++;
 
506
                      iline += strlen(lbuffer + iline);
 
507
                    }
 
508
 
 
509
                  goof += dump_rr(idr);
 
510
                  sprintf(&lbuffer[iline],"\n");
 
511
                  iline += strlen(lbuffer + iline);
 
512
 
 
513
 
 
514
                  if(goof){
 
515
                          ngoof++;
 
516
                          lbuffer[iline++] = 0;
 
517
                        if (sizeof(orig_file_addr) > sizeof(long)) {
 
518
                                printf("%llx: %s", (Llong)orig_file_addr, lbuffer);
 
519
                        } else {
 
520
                                printf("%lx: %s", (long)orig_file_addr, lbuffer);
 
521
                        }
 
522
                  };
 
523
 
 
524
 
 
525
 
 
526
                  if(rflag && (idr->flags[0] & 2)) check_tree((off_t)(isonum_733(idr->extent) + isonum_711((char *)idr->ext_attr_length)) * blocksize,
 
527
                                                   isonum_733(idr->size),
 
528
                                                   orig_file_addr * blocksize);
 
529
                  i += buffer[i];
 
530
                  i1++;
 
531
                  if (i > 2048 - sizeof(struct iso_directory_record)) break;
 
532
          };
 
533
          file_addr += sizeof(buffer);
 
534
  };
 
535
  fflush(stdout);
 
536
}
 
537
 
 
538
 
 
539
/* This function simply dumps the contents of the path tables.  No
 
540
   consistency checking takes place, although this would proably be a good
 
541
   idea. */
 
542
 
 
543
struct path_table_info{
 
544
  char * name;
 
545
  unsigned int extent;
 
546
  unsigned short index;
 
547
  unsigned short parent;
 
548
};
 
549
 
 
550
void
 
551
check_path_tables(typel_extent, typem_extent, path_table_size)
 
552
        int     typel_extent;
 
553
        int     typem_extent;
 
554
        int     path_table_size;
 
555
{
 
556
  int count;
 
557
  int j;
 
558
  char * pnt;
 
559
  char * typel, *typem;
 
560
 
 
561
  /* Now read in the path tables */
 
562
 
 
563
  typel = (char *) malloc(path_table_size);
 
564
  lseek(fileno(infile), (off_t)((off_t)typel_extent) * blocksize, SEEK_SET);
 
565
  read(fileno(infile), typel, path_table_size);
 
566
 
 
567
  typem = (char *) malloc(path_table_size);
 
568
  lseek(fileno(infile), (off_t)((off_t)typem_extent) * blocksize, SEEK_SET);
 
569
  read(fileno(infile), typem, path_table_size);
 
570
 
 
571
  j = path_table_size;
 
572
  pnt = typel;
 
573
  count = 1;
 
574
  while(j){
 
575
          int namelen, extent, idx;
 
576
          char name[32];
 
577
          namelen = *pnt++; pnt++;
 
578
          extent = isonum_731(pnt); pnt += 4;
 
579
          idx = isonum_721(pnt); pnt+= 2;
 
580
          j -= 8+namelen;
 
581
          memset(name, 0, sizeof(name));
 
582
 
 
583
          strncpy(name, pnt, namelen);
 
584
          pnt += namelen;
 
585
          if(j & 1) { j--; pnt++;};
 
586
          printf("%4.4d %4.4d %8.8x %s\n",count++, idx, extent, name);
 
587
  };
 
588
 
 
589
  j = path_table_size;
 
590
  pnt = typem;
 
591
  count = 1;
 
592
  while(j){
 
593
          int namelen, extent, idx;
 
594
          char name[32];
 
595
          namelen = *pnt++; pnt++;
 
596
          extent = isonum_732(pnt); pnt += 4;
 
597
          idx = isonum_722(pnt); pnt+= 2;
 
598
          j -= 8+namelen;
 
599
          memset(name, 0, sizeof(name));
 
600
 
 
601
          strncpy(name, pnt, namelen);
 
602
          pnt += namelen;
 
603
          if(j & 1) { j--; pnt++;};
 
604
          printf("%4.4d %4.4d %8.8x %s\n", count++, idx, extent, name);
 
605
  };
 
606
 
 
607
}
 
608
 
 
609
void
 
610
usage(excode)
 
611
        int     excode;
 
612
{
 
613
        errmsgno(EX_BAD, "Usage: %s [options] image\n",
 
614
                get_progname());
 
615
 
 
616
        error("Options:\n");
 
617
        exit(excode);
 
618
}
 
619
 
 
620
int
 
621
main(argc, argv)
 
622
        int     argc;
 
623
        char    *argv[];
 
624
{
 
625
  off_t file_addr;
 
626
  int file_size;
 
627
  struct iso_primary_descriptor ipd;
 
628
  struct iso_directory_record * idr;
 
629
  int typel_extent, typem_extent;
 
630
  int path_table_size;
 
631
 
 
632
        save_args(argc, argv);
 
633
 
 
634
  if(argc < 2)
 
635
        usage(EX_BAD);
 
636
  infile = fopen(argv[1],"rb");
 
637
  if (infile == NULL) {
 
638
#ifdef  USE_LIBSCHILY
 
639
        comerr("Cannot open '%s'.\n", argv[1]);
 
640
#else
 
641
        printf("Cannot open '%s'.\n", argv[1]);
 
642
        exit(1);
 
643
#endif
 
644
  }
 
645
 
 
646
 
 
647
  file_addr = (off_t)32768;
 
648
  lseek(fileno(infile), file_addr, SEEK_SET);
 
649
  read(fileno(infile), &ipd, sizeof(ipd));
 
650
 
 
651
  idr = (struct iso_directory_record *)ipd.root_directory_record;
 
652
 
 
653
  blocksize = isonum_723((char *)ipd.logical_block_size);
 
654
  if( blocksize != 512 && blocksize != 1024 && blocksize != 2048 )
 
655
    {
 
656
      blocksize = 2048;
 
657
    }
 
658
 
 
659
  file_addr = (off_t)isonum_733(idr->extent) + isonum_711((char *)idr->ext_attr_length);
 
660
  file_size = isonum_733(idr->size);
 
661
 
 
662
        if (sizeof(file_addr) > sizeof(long)) {
 
663
                printf("Root at extent %llx, %d bytes\n", (Llong)file_addr, file_size);
 
664
        } else {
 
665
                printf("Root at extent %lx, %d bytes\n", (long)file_addr, file_size);
 
666
        }
 
667
  file_addr = file_addr * blocksize;
 
668
 
 
669
  check_tree(file_addr, file_size, file_addr);
 
670
 
 
671
  typel_extent = isonum_731((char *)ipd.type_l_path_table);
 
672
  typem_extent = isonum_732((char *)ipd.type_m_path_table);
 
673
  path_table_size = isonum_733(ipd.path_table_size);
 
674
 
 
675
  /* Enable this to get the dump of the path tables */
 
676
#if 0
 
677
  check_path_tables(typel_extent, typem_extent, path_table_size);
 
678
#endif
 
679
 
 
680
  fclose(infile);
 
681
 
 
682
  if(!ngoof) printf("No errors found\n");
 
683
  return (0);
 
684
}