00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <ctype.h>
00025 #include <errno.h>
00026 #include <limits.h>
00027 #include <sys/types.h>
00028 #include <sys/stat.h>
00029 #include <fcntl.h>
00030 #include <stdlib.h>
00031 #include <stdio.h>
00032 #include <string.h>
00033 #include <time.h>
00034 #include <sys/times.h>
00035 #include <unistd.h>
00036
00037
00038
00039
00040
00041 #define ISO9660_ID "CD001"
00042 #define HIGH_SIERRA_ID "CDROM"
00043 #define BLOCK_SIZE 2048
00044 #define BLOCK_SHIFT 11
00045
00046
00047
00048 struct iso9660_descriptor
00049 {
00050 char type[1];
00051 char id[5];
00052 char version[1];
00053 char reserved1[1];
00054 char system_id[32];
00055 char volume_id[32];
00056 char reserved2[8];
00057 char volume_size[8];
00058 char reserved3[32];
00059 char volume_set_size[4];
00060 char volume_seq_nr[4];
00061 char block_size[4];
00062 char path_table_size[8];
00063 char type_l_path_table[4];
00064 char opt_type_l_path_table[4];
00065 char type_m_path_table[4];
00066 char opt_type_m_path_table[4];
00067 char root_dir_entry[34];
00068 char vol_set_id[128];
00069 char publ_id[128];
00070 char prep_id[128];
00071 char appl_id[128];
00072 char copyright_file_id[37];
00073 char abstract_file_id[37];
00074 char bibl_file_id[37];
00075 char creation_date[17];
00076 char mod_date[17];
00077 char exp_date[17];
00078 char eff_date[17];
00079 char file_struc_version[1];
00080 char reserved4[1];
00081 char appl_data[512];
00082 char reserved5[653];
00083 };
00084
00085
00086
00087 struct high_sierra_descriptor
00088 {
00089 char reserved1[8];
00090 char type[1];
00091 char id[5];
00092 char version[1];
00093 char reserved2[1];
00094 char system_id[32];
00095 char volume_id[32];
00096 char reserved3[8];
00097 char volume_size[8];
00098 char reserved4[32];
00099 char vol_set_size[4];
00100 char volume_seq_nr[4];
00101 char block_size[4];
00102 char path_table_size[8];
00103 char type_l_path_table[4];
00104 char reserved5[28];
00105 char root_dir_entry[34];
00106 };
00107
00108
00109
00110 struct dir_entry
00111 {
00112 char length[1];
00113 char ext_attr_length[1];
00114 char first_block[8];
00115 char size[8];
00116 char date[7];
00117 char flags[1];
00118 char file_unit_size[1];
00119 char interleave[1];
00120 char volume_seq_nr[4];
00121 char name_length[1];
00122 char name[1];
00123 };
00124
00125
00126 #define STDOUT stdout
00127 #define STDERR stderr
00128 #define NULL_DIR (struct dir_entry *) 0
00129 #define MAX_NAME_LENGTH 255
00130 #define MAX_PATH_LENGTH 1024
00131
00132 #define NR_OF_CHARS 13
00133 #define NR_OF_BLANKS 2
00134 #define NR_OF_COLS (80 / (NR_OF_CHARS + NR_OF_BLANKS))
00135
00136
00137 #define LOWER_CASE(CHR) (CHR >= 'A' && CHR <= 'Z' ? CHR | 0x20 : CHR)
00138
00139
00140 #define IS_DOT(PTR) (PTR->name_length[0] == 1 && PTR->name[0] == 0 ? 1 : 0)
00141 #define IS_DOT_DOT(PTR) (PTR->name_length[0] == 1 && PTR->name[0] == 1 ? 1 : 0)
00142 #define IS_DIR(PTR) (PTR->flags[-High_Sierra] & 2 ? 1 : 0)
00143
00144
00145 _PROTOTYPE (int main, (int argc, char **argv));
00146 _PROTOTYPE (int iso_cmp, (char *name, struct dir_entry *dir_ptr, int dir_flag));
00147 _PROTOTYPE (void list_dir, (struct dir_entry *dir_ptr));
00148 _PROTOTYPE (void list_file, (struct dir_entry *dir_ptr));
00149 _PROTOTYPE (struct dir_entry *look_up, (char *name));
00150 _PROTOTYPE (void recurse_dir, (char *path, struct dir_entry *dir_ptr));
00151 _PROTOTYPE (void read_device, (long offset, int nr_of_bytes, char *buffer));
00152 _PROTOTYPE (int valid_fs, (void) );
00153 _PROTOTYPE (void usage, (void) );
00154 _PROTOTYPE (void print_date, (char *date));
00155 _PROTOTYPE (void print_dir_date, (char *date));
00156 _PROTOTYPE (void iso_info, (struct iso9660_descriptor *vol_desc));
00157 _PROTOTYPE (void hs_info, (struct high_sierra_descriptor *vol_desc));
00158 _PROTOTYPE (int iso_711, (char *c));
00159 _PROTOTYPE (int iso_712, (char *c));
00160 _PROTOTYPE (int iso_721, (char *c));
00161 _PROTOTYPE (int iso_722, (char *c));
00162 _PROTOTYPE (int iso_723, (char *c));
00163 _PROTOTYPE (long iso_731, (char *c));
00164 _PROTOTYPE (long iso_732, (char *c));
00165 _PROTOTYPE (long iso_733, (char *c));
00166
00167
00168 char Buffer[BLOCK_SIZE];
00169 int Device;
00170 struct iso9660_descriptor *Iso_Vol_Desc;
00171 struct high_sierra_descriptor *Hs_Vol_Desc;
00172 int High_Sierra = 0;
00173 int Iso9660 = 0;
00174
00175
00176 char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
00177
00178
00179 int Read_File = 0;
00180 int Read_Dir = 0;
00181 int Read_Info = 0;
00182 int Recurse = 0;
00183 int Verbose = 0;
00184 int ByteOffset = 0;
00185 int Aflag = 0;
00186
00187 int iso_cmp(name, dir_ptr, dir_flag)
00188 char *name;
00189 struct dir_entry *dir_ptr;
00190 int dir_flag;
00191 {
00192
00193
00194
00195
00196
00197
00198 int i;
00199 int len;
00200
00201
00202 len = strlen(name);
00203 if (len > iso_711(dir_ptr->name_length)) return 1;
00204 for (i = 0; i < len; i++)
00205 {
00206 if (dir_ptr->name[i] == ';') return 1;
00207 if (name[i] != LOWER_CASE(dir_ptr->name[i])) return 1;
00208 }
00209 if (dir_ptr->name[i] != ';' && i != len) return 1;
00210
00211
00212 if (dir_flag && !IS_DIR(dir_ptr)) return 1;
00213
00214 return 0;
00215 }
00216
00217
00218 void usage()
00219 {
00220 if (Read_Dir)
00221 fprintf (STDERR, "Usage: isodir [-lrB] inputfile [dir]\n");
00222 else if (Read_Info)
00223 fprintf (STDERR, "Usage: isoinfo inputfile\n");
00224 else
00225 fprintf (STDERR, "Usage: isoread [-a] inputfile file\n");
00226 exit(1);
00227 }
00228
00229
00230 int main(argc, argv)
00231 int argc;
00232 char **argv;
00233 {
00234 struct dir_entry *entry;
00235 char path[MAX_PATH_LENGTH];
00236 char *input_file;
00237 char *basename;
00238 char *file_name;
00239 int i,j;
00240
00241
00242 basename = argv[0];
00243 while (*argv[0] != '\0')
00244 if (*argv[0]++ == '/') basename = argv[0];
00245
00246 if (strcmp(basename,"isodir") == 0) Read_Dir = 1;
00247 else if (strcmp(basename,"isoinfo") == 0) Read_Info = 1;
00248 else Read_File = 1;
00249
00250 if ((argc > 5 && Read_Dir) || (argc != 2 && Read_Info) ||
00251 (argc > 4 && Read_File)) usage();
00252
00253 i = 1;
00254
00255 while (i < argc && argv[i][0] == '-')
00256 {
00257 char *opt = argv[i++] + 1;
00258
00259 if (opt[0] == '-' && opt[1] == '\0') break;
00260
00261 while (*opt != '\0')
00262 {
00263 if (Read_Info) usage();
00264 if (Read_Dir)
00265 switch (*opt++)
00266 {
00267 case 'r': Recurse = 1; break;
00268 case 'l': Verbose = 1; break;
00269 case 'B': ByteOffset = 1; break;
00270 default: usage();
00271 }
00272 if (Read_File)
00273 switch (*opt++)
00274 {
00275 case 'a': Aflag = 1; break;
00276 case 'B': ByteOffset = 1; break;
00277 default: usage();
00278 }
00279 }
00280 }
00281
00282 if (i >= argc) usage();
00283 input_file = argv[i++];
00284
00285 if (Read_File)
00286 {
00287 if (i >= argc) usage();
00288 file_name = argv[i++];
00289 }
00290
00291 if (Read_Dir)
00292 {
00293 file_name = "/";
00294 if (i < argc)
00295 {
00296 file_name = argv[i++];
00297 }
00298 }
00299
00300 if (i < argc) usage();
00301
00302 if (Read_File || Read_Dir)
00303 {
00304 for (i=0; file_name[i] != '\0'; i++)
00305 path[i] = LOWER_CASE(file_name[i]);
00306 path[i] = '\0';
00307 }
00308
00309
00310 if ((Device = open(input_file, O_RDONLY)) < 0)
00311 {
00312 fprintf (STDERR, "cannot open %s: %s\n", input_file, strerror(errno));
00313 exit(-1);
00314 }
00315
00316
00317 if (!valid_fs())
00318 {
00319 fprintf (STDERR, "File system not in ISO9660 or HIGH SIERRA format \n");
00320 exit(-1);
00321 }
00322
00323
00324 if (Read_Info)
00325 {
00326 if (Iso9660)
00327 iso_info(Iso_Vol_Desc);
00328 else
00329 hs_info(Hs_Vol_Desc);
00330 exit(0);
00331 }
00332
00333
00334 if ((entry = look_up(path)) != NULL_DIR)
00335 {
00336 if (Read_Dir)
00337 if (Recurse) recurse_dir(path,entry);
00338 else list_dir(entry);
00339 else
00340 list_file(entry);
00341 }
00342 else
00343 {
00344 if (Read_Dir)
00345 fprintf (STDERR, "Directory");
00346 else
00347 fprintf (STDERR, "File");
00348 fprintf (STDERR, " %s not found\n", path);
00349 exit(-1);
00350 }
00351 return 0;
00352 }
00353
00354
00355 struct dir_entry *look_up(path)
00356 char *path;
00357 {
00358
00359
00360 struct dir_entry *dir_ptr;
00361 long block;
00362 int nr_of_blocks;
00363 int offset;
00364 char name[MAX_NAME_LENGTH + 1];
00365 int name_index = 0;
00366 int last_in_path = 0;
00367 int found;
00368 int i,j;
00369
00370
00371 if (Iso9660)
00372 dir_ptr = (struct dir_entry *) Iso_Vol_Desc->root_dir_entry;
00373 else
00374 dir_ptr = (struct dir_entry *) Hs_Vol_Desc->root_dir_entry;
00375
00376
00377 if (path[0] == '/')
00378 if (strlen(path) == 1) return dir_ptr;
00379 else name_index = 1;
00380
00381
00382 while (!last_in_path)
00383 {
00384
00385 for (i = name_index; i < strlen(path); i++)
00386 {
00387 if (path[i] == '/') break;
00388 name[i - name_index] = path[i];
00389 }
00390 last_in_path =
00391 (i == strlen(path) || (i == strlen(path) - 1 && path[i] == '/'));
00392 name[i-name_index] = '\0';
00393 name_index = i + 1;
00394
00395
00396 block = iso_733(dir_ptr->first_block) + iso_711(dir_ptr->ext_attr_length);
00397 nr_of_blocks = (iso_733(dir_ptr->size) + (BLOCK_SIZE-1)) >> BLOCK_SHIFT;
00398
00399
00400 found = 0;
00401 for (j=0; j < nr_of_blocks && !found; j++)
00402 {
00403
00404 read_device(block*BLOCK_SIZE, BLOCK_SIZE, Buffer);
00405 block++;
00406
00407 dir_ptr = (struct dir_entry *) Buffer;
00408
00409 offset = 0;
00410
00411 while (iso_711(dir_ptr->length) > 0 && offset < BLOCK_SIZE)
00412 {
00413 if (iso_cmp(name, dir_ptr,
00414 (Read_Dir || (!Read_Dir && !last_in_path))) == 0)
00415 {
00416 found = 1;
00417 break;
00418 }
00419
00420 offset += iso_711(dir_ptr->length);
00421 dir_ptr = (struct dir_entry *) (Buffer + offset);
00422 }
00423 }
00424 if (!found) return NULL_DIR;
00425 }
00426 return dir_ptr;
00427 }
00428
00429
00430 void recurse_dir(path, dir_ptr)
00431 char *path;
00432 struct dir_entry *dir_ptr;
00433 {
00434
00435
00436 char tmp_path[MAX_PATH_LENGTH];
00437 int i,j, path_length;
00438 long block, saveblock, dblock;
00439 int nr_of_blocks;
00440 int offset = 0;
00441
00442
00443
00444
00445
00446 block = iso_733(dir_ptr->first_block) + iso_711(dir_ptr->ext_attr_length);
00447 nr_of_blocks = (iso_733(dir_ptr->size) + (BLOCK_SIZE-1)) >> BLOCK_SHIFT;
00448
00449
00450 path_length = strlen(path);
00451 if (path[path_length-1] != '/')
00452 {
00453 path[path_length++] = '/';
00454 path[path_length] = '\0';
00455 }
00456
00457
00458 fprintf(STDOUT,"directory %s:\n\n", path);
00459 list_dir(dir_ptr);
00460 fprintf(STDOUT,"\n\n");
00461
00462 for (j=0; j < nr_of_blocks; j++)
00463 {
00464 read_device(block*BLOCK_SIZE, BLOCK_SIZE, Buffer);
00465 saveblock = block++;
00466
00467
00468
00469
00470 dir_ptr = (struct dir_entry *) Buffer;
00471
00472
00473 offset = 0;
00474 while (iso_711(dir_ptr->length) != 0 && offset < BLOCK_SIZE)
00475 {
00476
00477 if (IS_DIR(dir_ptr) && !IS_DOT(dir_ptr) && !IS_DOT_DOT(dir_ptr))
00478 {
00479
00480 for (i=0; i<path_length; i++) tmp_path[i] = path[i];
00481 for (i=0;i<iso_711(dir_ptr->name_length) && dir_ptr->name[i] != ';';i++)
00482 tmp_path[i+path_length] = LOWER_CASE(dir_ptr->name[i]);
00483 tmp_path[i+path_length] = '/';
00484 tmp_path[i+1+path_length] = '\0';
00485
00486
00487 dblock = iso_733(dir_ptr->first_block);
00488 read_device(dblock*BLOCK_SIZE, BLOCK_SIZE, Buffer);
00489
00490
00491 recurse_dir(tmp_path, (struct dir_entry *) Buffer);
00492
00493
00494 read_device(saveblock*BLOCK_SIZE, BLOCK_SIZE, Buffer);
00495 }
00496
00497
00498 offset += iso_711(dir_ptr->length);
00499 dir_ptr = (struct dir_entry *) (Buffer + offset);
00500 }
00501 }
00502 }
00503
00504
00505 void list_dir(dir_ptr)
00506 struct dir_entry *dir_ptr;
00507 {
00508
00509 int tty;
00510 long block;
00511 int nr_of_blocks;
00512 int i,j;
00513 int offset = 0;
00514 char name[NR_OF_CHARS+NR_OF_BLANKS+1];
00515 int name_len;
00516 int column = 0;
00517 int skip = 0;
00518
00519 tty = isatty(STDOUT_FILENO);
00520
00521 block = iso_733(dir_ptr->first_block) + iso_711(dir_ptr->ext_attr_length);
00522 nr_of_blocks = (iso_733(dir_ptr->size) + (BLOCK_SIZE-1)) >> BLOCK_SHIFT;
00523
00524
00525 for (j=0; j < nr_of_blocks; j++)
00526 {
00527 read_device(block*BLOCK_SIZE, BLOCK_SIZE, Buffer);
00528 block++;
00529
00530 dir_ptr = (struct dir_entry *) (Buffer);
00531 offset = 0;
00532 while (iso_711(dir_ptr->length) != 0 && offset < BLOCK_SIZE)
00533 {
00534 name_len = 0;
00535 if (IS_DOT(dir_ptr))
00536 {
00537 name[name_len++] = '.';
00538 if (!Verbose) skip = 1;
00539 }
00540 else
00541 {
00542 if (IS_DOT_DOT(dir_ptr))
00543 {
00544 name[name_len++] = '.';
00545 name[name_len++] = '.';
00546 if (!Verbose) skip = 1;
00547 }
00548 else
00549 {
00550 for (i=0; i<iso_711(dir_ptr->name_length) &&
00551 i<NR_OF_CHARS; i++)
00552 {
00553 if (dir_ptr->name[i] == ';') break;
00554 name[name_len++] = LOWER_CASE(dir_ptr->name[i]);
00555 }
00556 if (IS_DIR(dir_ptr) && tty) name[name_len++] = '/';
00557 }
00558 }
00559 if (!skip)
00560 {
00561 if (ByteOffset)
00562 {
00563 fprintf (STDOUT, "%10ld ",
00564 (iso_733(dir_ptr->first_block) + iso_711(dir_ptr->ext_attr_length))
00565 * BLOCK_SIZE);
00566 }
00567 if (Verbose || ByteOffset)
00568 {
00569 fprintf (STDOUT, "%10ld ", iso_733(dir_ptr->size));
00570 }
00571 if (Verbose)
00572 {
00573 print_dir_date(dir_ptr->date);
00574 fprintf (STDOUT, " ");
00575 }
00576 if(!tty)
00577 name[name_len] = '\0';
00578 else {
00579 for(i=name_len; i<(NR_OF_CHARS+NR_OF_BLANKS); i++) name[i] = ' ';
00580 name[NR_OF_CHARS+NR_OF_BLANKS] = '\0';
00581 }
00582 fprintf(STDOUT, "%s", name);
00583 if (!(Verbose || ByteOffset))
00584 {
00585 column++;
00586 if (column >= NR_OF_COLS || !tty)
00587 {
00588 column = 0;
00589 fprintf(STDOUT,"\n");
00590 }
00591 }
00592 else fprintf(STDOUT,"\n");
00593 }
00594 skip = 0;
00595 offset += iso_711(dir_ptr->length);
00596 dir_ptr = (struct dir_entry *) (Buffer+offset);
00597 }
00598 }
00599 if (!Verbose && column) fprintf(STDOUT,"\n");
00600 }
00601
00602
00603 void print_dir_date(date)
00604 char *date;
00605 {
00606
00607
00608 int m;
00609
00610 m = iso_711(&date[1]) - 1;
00611 if(m < 0 || m > 11)
00612 fprintf(STDOUT, " ");
00613 else
00614 fprintf(STDOUT,"%.3s",&months[m*3]);
00615
00616 fprintf (STDOUT, " %02d %04d %02d:%02d:%02d",
00617 date[2],
00618 1900+date[0],
00619 date[3],
00620 date[4],
00621 date[5]);
00622 }
00623
00624
00625 void list_file(dir_ptr)
00626 struct dir_entry *dir_ptr;
00627 {
00628
00629
00630 int i;
00631 long block;
00632 long size;
00633 char c;
00634
00635 block = iso_733(dir_ptr->first_block);
00636 size = iso_733(dir_ptr->size);
00637
00638 if (ByteOffset) {
00639 fprintf(STDOUT, "%ld %ld\n", block*BLOCK_SIZE, size);
00640 return;
00641 }
00642
00643 while (size > 0)
00644 if (Aflag == 1) {
00645 read_device(block*BLOCK_SIZE, BLOCK_SIZE, Buffer);
00646 for (i=0; ((i < size) && (i < BLOCK_SIZE)); i++)
00647 if (Buffer[i] != '\r') fprintf(STDOUT, "%c", Buffer[i]);
00648 size-= BLOCK_SIZE;
00649 block++;
00650 } else {
00651 read_device(block*BLOCK_SIZE, BLOCK_SIZE, Buffer);
00652 for (i=0; ((i < size) && (i < BLOCK_SIZE)); i++)
00653 fprintf(STDOUT, "%c", Buffer[i]);
00654 size-= BLOCK_SIZE;
00655 block++;
00656 }
00657 }
00658
00659
00660 void print_date(date)
00661 char *date;
00662 {
00663
00664
00665 fprintf (STDOUT, "%c%c-%c%c-%c%c%c%c %c%c:%c%c:%c%c",
00666 date[4],
00667 date[5],
00668 date[6],
00669 date[7],
00670 date[0],
00671 date[1],
00672 date[2],
00673 date[3],
00674 date[8],
00675 date[9],
00676 date[10],
00677 date[11],
00678 date[12],
00679 date[13]);
00680 }
00681
00682 void iso_info(vol_desc)
00683 struct iso9660_descriptor *vol_desc;
00684 {
00685 int i;
00686
00687 fprintf (STDOUT, "Format: ISO9660 \n");
00688 fprintf (STDOUT, "System id: ");
00689 for (i=0; i< sizeof(vol_desc->system_id); i++)
00690 fprintf(STDOUT, "%c", vol_desc->system_id[i]);
00691 fprintf (STDOUT, "\n");
00692 fprintf (STDOUT, "Volume id: ");
00693 for (i=0; i< sizeof(vol_desc->volume_id); i++)
00694 fprintf(STDOUT, "%c", vol_desc->volume_id[i]);
00695 fprintf (STDOUT, "\n");
00696 fprintf (STDOUT, "Volume size: %ld Kb\n", iso_733(vol_desc->volume_size)*2);
00697 fprintf (STDOUT, "Block size: %d bytes \n", iso_723(vol_desc->block_size));
00698 fprintf (STDOUT, "Creation date: ");
00699 print_date(vol_desc->creation_date);
00700 fprintf(STDOUT, "\n");
00701 fprintf (STDOUT, "Modification date: ");
00702 print_date(vol_desc->mod_date);
00703 fprintf (STDOUT, "\n");
00704 fprintf (STDOUT, "Expiration date: ");
00705 print_date(vol_desc->exp_date);
00706 fprintf (STDOUT, "\n");
00707 fprintf (STDOUT, "Effective date: ");
00708 print_date(vol_desc->eff_date);
00709 fprintf (STDOUT, "\n");
00710 }
00711
00712
00713 void hs_info(vol_desc)
00714 struct high_sierra_descriptor *vol_desc;
00715 {
00716 int i;
00717
00718 fprintf (STDOUT, "Format: HIGH SIERRA \n");
00719 fprintf (STDOUT, "System id: ");
00720 for (i=0; i< sizeof(vol_desc->system_id); i++)
00721 fprintf(STDOUT, "%c", vol_desc->system_id[i]);
00722 fprintf (STDOUT, "\n");
00723 fprintf (STDOUT, "Volume id: ");
00724 for (i=0; i< sizeof(vol_desc->volume_id); i++)
00725 fprintf(STDOUT, "%c", vol_desc->volume_id[i]);
00726 fprintf (STDOUT, "\n");
00727 fprintf (STDOUT, "Volume size: %ld Kb\n", (iso_733(vol_desc->volume_size)*2));
00728 fprintf (STDOUT, "Block size: %d bytes \n", iso_723(vol_desc->block_size));
00729 }
00730
00731
00732 int valid_fs()
00733 {
00734
00735 int i;
00736
00737
00738 for (i=16; i<100; i++)
00739 {
00740
00741 read_device((long)(i)*BLOCK_SIZE, BLOCK_SIZE, Buffer);
00742
00743 Iso_Vol_Desc = (struct iso9660_descriptor *) Buffer;
00744 Hs_Vol_Desc = (struct high_sierra_descriptor *) Buffer;
00745
00746 if (strncmp(Iso_Vol_Desc->id, ISO9660_ID, sizeof Iso_Vol_Desc->id) == 0)
00747 {
00748
00749 Iso9660 = 1;
00750 break;
00751 }
00752
00753 if (strncmp(Hs_Vol_Desc->id, HIGH_SIERRA_ID, sizeof Hs_Vol_Desc->id) == 0)
00754 {
00755
00756 High_Sierra = 1;
00757 break;
00758 }
00759 }
00760
00761 if (i >= 100) return 0;
00762 return 1;
00763 }
00764
00765
00766 void read_device(offset, nr_of_bytes, buffer)
00767 long offset;
00768 int nr_of_bytes;
00769 char *buffer;
00770 {
00771 int bytes_read;
00772
00773 if (lseek(Device, offset, SEEK_SET) == -1)
00774 {
00775 fflush (stdout);
00776 fprintf (STDERR, "seek error: %s\n", strerror(errno));
00777 exit(1);
00778 }
00779
00780 bytes_read = read(Device, buffer, nr_of_bytes);
00781 if (bytes_read != nr_of_bytes)
00782 {
00783 fprintf (STDERR, "read error: %s\n",
00784 bytes_read >= 0 ? "Short read" : strerror(errno));
00785 exit (1);
00786 }
00787 }
00788
00789
00790
00791
00792 int iso_711 (c)
00793 char *c;
00794 {
00795 return (*c & 0xff);
00796 }
00797
00798
00799 int iso_712 (c)
00800 char *c;
00801 {
00802 int n;
00803
00804 n = *c;
00805 if (n & 0x80) n |= 0xffffff00;
00806 return n;
00807 }
00808
00809 int iso_721 (c)
00810 char *c;
00811 {
00812 return ((c[0] & 0xff) | ((c[1] & 0xff) << 8));
00813 }
00814
00815 int iso_722 (c)
00816 char *c;
00817 {
00818 return (((c[0] & 0xff) << 8) | (c[1] & 0xff));
00819 }
00820
00821 int iso_723 (c)
00822 char *c;
00823 {
00824 if (c[0] != c[3] || c[1] != c[2])
00825 {
00826 fprintf (STDERR, "Invalid ISO 7.2.3 number\n");
00827 exit (1);
00828 }
00829 return (iso_721 (c));
00830 }
00831
00832 long iso_731 (c)
00833 char *c;
00834 {
00835 return ((long)(c[0] & 0xff)
00836 | ((long)(c[1] & 0xff) << 8)
00837 | ((long)(c[2] & 0xff) << 16)
00838 | ((long)(c[3] & 0xff) << 24));
00839 }
00840
00841
00842 long iso_732 (c)
00843 char *c;
00844 {
00845 return (((long)(c[0] & 0xff) << 24)
00846 | (((long)c[1] & 0xff) << 16)
00847 | (((long)c[2] & 0xff) << 8)
00848 | ((long)c[3] & 0xff));
00849 }
00850
00851 long iso_733 (c)
00852 char *c;
00853 {
00854 int i;
00855
00856 for (i = 0; i < 4; i++)
00857 {
00858 if (c[i] != c[7-i])
00859 {
00860 fprintf (STDERR, "Invalid ISO 7.3.3 number\n");
00861 exit (1);
00862 }
00863 }
00864 return (iso_731(c));
00865 }