isodump.c

来自「将用户指定的符合iso-9660标准的文件的信息dump出来。」· C语言 代码 · 共 500 行 · 第 1/2 页

C
500 行
字号
  }/* throw out some info */  if( verbose >= 2 ) {    if( in_fd == STDIN_FILENO )      fprintf( VERBOSE_CHANNEL, "%s: Reading from stdin.\n", pn );    else      fprintf( VERBOSE_CHANNEL, "%s: Reading from file `%s'.\n", pn, in_fn );    if( out_fd == STDOUT_FILENO )      fprintf( VERBOSE_CHANNEL, "%s: Writing to stdout.\n", pn );    else      fprintf( VERBOSE_CHANNEL, "%s: Writing to file `%s'.\n", pn, out_fn );    if( hash )      fprintf( VERBOSE_CHANNEL,               "%s: Writing hash marks (%d for full image size).\n",               pn, HASH_MARKS );  }/* dump input file */  blocks= ISO_PD_BLOCK + 1;  bp= buf; buf_size= CD_FRAMESIZE;  tnbr= 0; tnbw= 0;  extra_zero= 1;  padded= 0;  sec0= time( NULL ); sec1= sec0;  if( nrg ) {    /* nrg image, skip first 150 blocks */    if( verbose ) {      fprintf( VERBOSE_CHANNEL,               "%s: Assuming NRG image, skipping first %d blocks.\n",               pn, NRG_BLOCKS );    }    for( blk=0; blk<NRG_BLOCKS; blk++ ) {      if( (nbr=my_read(in_fd,buf,buf_size)) == -1 ) {        fprintf( ERROR_CHANNEL, "%s: Read error at block %d. %s.\n",                 pn, blk, strerror(errno) );        retval= RETVAL_READ_ERROR; goto DIE_NOW;      }      tnbr+= nbr;    }  }  for( blk=0; 1; blk++ ) {    /* read block */    if( (nbr=my_read(in_fd,buf,buf_size)) == -1 ) {      fprintf( ERROR_CHANNEL, "%s: Read error at block %d. %s.\n",               pn, blk, strerror(errno) );      retval= RETVAL_READ_ERROR; goto DIE_NOW;    }    tnbr+= nbr;    /* check for EOF */    if( nbr < buf_size ) {	/* EOF reached */      if( blk < blocks ) {	/* image too small, error or pad */        if( !pad  ||  blk <= ISO_PD_BLOCK ) {          fprintf( ERROR_CHANNEL,                   "%s: Image too small by at least %d-%d= %d blocks.\n",                   pn, blocks, blk, blocks-blk );          retval= RETVAL_BROKEN; goto DIE_NOW;        } else {          padded= padded ? padded : blocks-blk;          for( i=nbr; i<buf_size; i++ ) buf[i]= 0;          nbr= buf_size;        }      } else {			/* image size okay */        if( nbr == 0 ) break;        for( i=nbr; i<buf_size; i++ ) buf[i]= 0;        nbr= buf_size;      }    }    /* virgin loop: check image type and set vars */    if( blk == 0 ) {      /* sync data present? */      if( memcmp(bp,sync,CD_SYNC_SIZE) == 0 ) {        int nbtr= CD_FRAMESIZE_RAW-CD_FRAMESIZE;        buf_size= CD_FRAMESIZE_RAW;        bp+= CD_SYNC_SIZE;        if( (nbr=my_read(in_fd,buf+nbr,nbtr)) == -1 ) {          fprintf( ERROR_CHANNEL, "%s: Read error at block %d. %s.\n",                   pn, blk, strerror(errno) );          retval= RETVAL_READ_ERROR; goto DIE_NOW;        }        tnbr+= nbr;        if( nbr < nbtr ) {          fprintf( ERROR_CHANNEL, "%s: Image broken -- too small.\n", pn );          retval= RETVAL_BROKEN; goto DIE_NOW;        }      }      /* subchannel data present? */      if( memcmp(bp,head,CD_HEAD_SIZE-1) == 0 ) {        uhb= bp[3];        buf_size= CD_FRAMESIZE_RAW;        bp+= CD_HEAD_SIZE;      }      if( xa ) {        buf_size= CD_FRAMESIZE_RAW;        bp= buf + CD_XA_SYNC_HEAD;      }      if( verbose >= 2 ) {        fprintf( VERBOSE_CHANNEL, "%s: Input blocksize set to %d bytes.\n",                 pn, buf_size );        fprintf( VERBOSE_CHANNEL, "%s: Input blockoffset set to %d bytes.\n",                 pn, bp-buf );        if( buf_size > CD_FRAMESIZE )          fprintf( VERBOSE_CHANNEL, "%s: Unidentified header byte is 0x%02x.\n",                   pn, uhb );      }    }    /* if raw (2352 bytes) image: check sync and head data */    if( buf_size == CD_FRAMESIZE_RAW  &&  !padded ) {      /* check sync data */      if( memcmp(buf,sync,CD_SYNC_SIZE) != 0 ) {        fprintf( ERROR_CHANNEL, "%s: Invalid sync data at block %d.\n",                 pn, blk );        retval= RETVAL_ERROR; goto DIE_NOW;      }      /* check head data */      if( memcmp(buf+CD_SYNC_SIZE,setup_head(blk,uhb),CD_HEAD_SIZE) != 0 ) {        fprintf( ERROR_CHANNEL, "%s: Invalid head data at block %d.\n",                 pn, blk );        retval= RETVAL_ERROR; goto DIE_NOW;      }    }    /* write iso9660-block */    if( blk<blocks || all ) {      if( (nbw=write(out_fd,bp,CD_FRAMESIZE)) != CD_FRAMESIZE ) {        fprintf( ERROR_CHANNEL, "%s: Write error at block %d. %s.\n",                 pn, blk, strerror(errno) );        retval= RETVAL_ERROR; goto DIE_NOW;      }      tnbw+= nbw;    }    /* check extra data */    if( blk >= blocks ) {      for( i=0; i<CD_FRAMESIZE; i++ )        if( bp[i] != 0 ) {          extra_zero= 0;          break;        }    }    /* set image size (blocks) and iso9660-magic data */    if( blk == ISO_PD_BLOCK ) {      struct iso_primary_descriptor* ipd= (struct iso_primary_descriptor*) bp;      /* check iso9660-magic */      if( memcmp(ipd->id,id,strlen(id)) != 0 ) {        ipd= (struct iso_primary_descriptor*) (bp+CD_SUBHEAD_SIZE);        if( memcmp(ipd->id,id,strlen(id)) == 0 ) {          fprintf( ERROR_CHANNEL,          "%s: XA image detected. Use the XA disk option.\n",          pn );        }        else { /* nero or unknown image */          int blk_zero= 1;          for( i=0; i<CD_FRAMESIZE; i++ )            if( bp[i] != 0 ) {              blk_zero= 0;              break;            }          if( blk_zero  &&  !nrg ) {            fprintf( ERROR_CHANNEL,            "%s: Unknown image type. Try the nrg image option.\n",            pn );          } else {            fprintf( ERROR_CHANNEL, "%s: Unknown image type. Exiting.\n", pn );          }        }        retval= RETVAL_BROKEN; goto DIE_NOW;      }      /* set and check blocks */      blocks= iso_num_733(ipd->volume_space_size);      if( verbose) {        fprintf( VERBOSE_CHANNEL, "%s: Image has %d blocks, ", pn, blocks );        fprintf( VERBOSE_CHANNEL, "%lld bytes, %lld Mbytes, ",                 blocks*(long long)CD_FRAMESIZE,                 blocks*(long long)CD_FRAMESIZE/1024/1024 );        fprintf( VERBOSE_CHANNEL, "%02d:%02d:%02d msf.\n",                 fra2min(blocks), fra2sec(blocks), fra2fra(blocks) );      }      if( blocks <= blk+1 ) {        fprintf( ERROR_CHANNEL,                 "%s: Image (primary descriptor block) broken. Exiting.\n",                 pn );        retval= RETVAL_BROKEN; goto DIE_NOW;      }    }    /* write has mark(s) */    if( hash && blk>=ISO_PD_BLOCK ) {      int hash_marks_to_print= ((blk+1)*HASH_MARKS)/blocks - hash_marks_printed;      for( i=0; i<hash_marks_to_print; i++ ) fprintf( VERBOSE_CHANNEL, "#" );      hash_marks_printed+= hash_marks_to_print;    }  }  sec1= time( NULL );  if( hash ) fprintf( VERBOSE_CHANNEL, "\n" );  if( padded ) {    fprintf( ERROR_CHANNEL,             "%s: WARNING: Image may be broken, padded by %d blocks!\n",             pn, padded );    retval= RETVAL_PADDED;  }  if( verbose && blk>blocks) {    if( all ) {      fprintf( VERBOSE_CHANNEL,               "%s: Extra data written (%d blocks, %s).\n",               pn, blk-blocks, extra_zero?"all zero":"non-zero" );    }    else {      fprintf( VERBOSE_CHANNEL,               "%s: Extra data cut (%d blocks, %s).\n",               pn, blk-blocks, extra_zero?"all zero":"non-zero" );    }  }/* close output and input */  if( out_fd != STDOUT_FILENO  &&  close(out_fd) == -1 ) {    fprintf( ERROR_CHANNEL, "%s: Cannot close output file `%s'. %s.\n",             pn, out_fn, strerror(errno) );    retval= RETVAL_ERROR;  }  if( in_fd != STDIN_FILENO  &&  close(in_fd) == -1 ) {    fprintf( ERROR_CHANNEL, "%s: Cannot close input file `%s'. %s.\n",             pn, in_fn, strerror(errno) );    retval= RETVAL_ERROR;  }/* give some more info */  if( verbose ) {    /* print overall speed */    double speed_abs, speed_rel;    char unit[]= " "; *unit= '\0';    speed_abs= (double)(sec1==sec0 ? 1.048565e8 : tnbw/(double)(sec1-sec0));    speed_rel= speed_abs/(double)(CD_FRAMESIZE*CD_FRAMES);    if( speed_abs > 1024.0 ) { speed_abs /= 1024.0; unit[0]= 'k'; }    if( speed_abs > 1024.0 ) { speed_abs /= 1024.0; unit[0]= 'M'; }    fprintf( VERBOSE_CHANNEL, "%s: Wall clock speed %5.3f %sbytes/s, %3.1fx.\n",             pn, speed_abs, unit, speed_rel );  }DIE_NOW:  close( out_fd );  close( in_fd );  if( verbose )    fprintf( VERBOSE_CHANNEL, "%s: %lld/%lld bytes read/written.\n",             pn, tnbr, tnbw );  return( retval );}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?