コード例 #1
0
ファイル: cd-info.c プロジェクト: KorolevaFey/libcdio-osx
/* Parse source options. */
static void
parse_source(int opt)
{
  /* NOTE: The libpopt version made use of an extra temporary
     variable (psz_my_source) for all sources _except_ devices.
     This distinction seemed to serve no purpose.
  */

  if (opts.source_image != INPUT_UNKNOWN) {
    report(stderr, "%s: another source type option given before.\n", 
           program_name);
    report(stderr, "%s: give only one source type option.\n", 
           program_name);
    return;
  } 

  /* For all input sources which are not a DEVICE, we need to make
     a copy of the string; for a DEVICE the fill-out routine makes
     the copy.
  */
  if (OP_SOURCE_DEVICE != opt) 
    if (optarg != NULL) source_name = strdup(optarg);
  
  switch (opt) {
  case OP_SOURCE_BIN: 
    opts.source_image  = INPUT_BIN;
    break;
  case OP_SOURCE_CUE: 
    opts.source_image  = INPUT_CUE;
    break;
  case OP_SOURCE_CDRDAO: 
    opts.source_image  = INPUT_CDRDAO;
    break;
  case OP_SOURCE_NRG: 
    opts.source_image  = INPUT_NRG;
    break;
  case OP_SOURCE_AUTO:
    opts.source_image  = INPUT_AUTO;
    break;
    
  case OP_SOURCE_DEVICE: 
    opts.source_image  = INPUT_DEVICE;
    if (optarg != NULL) source_name = fillout_device_name(optarg);
    break;
  }
}
コード例 #2
0
ファイル: cd-drive.c プロジェクト: AaronDnz/xbmc
/* Parse a all options. */
static bool
parse_options (int argc, const char *argv[])
{
  int opt;

  struct poptOption optionsTable[] = {
    {"debug",       'd', POPT_ARG_INT, &opts.debug_level, 0,
     "Set debugging to LEVEL"},
    
    {"cdrom-device", 'i', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, 
     &source_name, OP_SOURCE_DEVICE,
     "show only info about CD-ROM device", "DEVICE"},
    
    {"quiet",       'q', POPT_ARG_NONE, &opts.silent, 0,
     "Don't produce warning output" },
    
    {"version", 'V', POPT_ARG_NONE, &opts.version_only, 0,
     "display version and copyright information and exit"},
    POPT_AUTOHELP {NULL, 0, 0, NULL, 0}
  };
  poptContext optCon = poptGetContext (NULL, argc, argv, optionsTable, 0);

  program_name = strrchr(argv[0],'/');
  program_name = program_name ? strdup(program_name+1) : strdup(argv[0]);

  while ((opt = poptGetNextOpt (optCon)) != -1) {
    switch (opt) {
      
    case OP_SOURCE_DEVICE: 
      if (opts.source_image != DRIVER_UNKNOWN) {
	report( stderr, "%s: another source type option given before.\n", 
		program_name);
	report( stderr, "%s: give only one source type option.\n", 
		program_name);
	break;
      } else {
	opts.source_image  = DRIVER_DEVICE;
	source_name = fillout_device_name(source_name);
	break;
      }
      break;
      
    default:
      poptFreeContext(optCon);
      return false;
    }
  }
  {
    const char *remaining_arg = poptGetArg(optCon);
    if ( remaining_arg != NULL) {
      if (opts.source_image != DRIVER_UNKNOWN) {
	report( stderr, "%s: Source specified in option %s and as %s\n", 
		 program_name, source_name, remaining_arg);
	poptFreeContext(optCon);
	free(program_name);
	exit (EXIT_FAILURE);
      }
      
      if (opts.source_image == DRIVER_DEVICE)
	source_name = fillout_device_name(remaining_arg);
      else 
	source_name = strdup(remaining_arg);
      
      if ( (poptGetArgs(optCon)) != NULL) {
	report( stderr, "%s: Source specified in previously %s and %s\n", 
		 program_name, source_name, remaining_arg);
	poptFreeContext(optCon);
	free(program_name);
	exit (EXIT_FAILURE);
	
      }
    }
  }
  
  poptFreeContext(optCon);
  return true;
}
コード例 #3
0
ファイル: cd-info.c プロジェクト: Gatada/atv2
/* Parse a all options. */
static bool
parse_options (int argc, const char *argv[])
{
  int opt;
  char *psz_my_source;
  
  struct poptOption optionsTable[] = {
    {"access-mode",       'a', POPT_ARG_STRING, &opts.access_mode, 0,
     "Set CD access methed"},
    
    {"debug",       'd', POPT_ARG_INT, &opts.debug_level, 0,
     "Set debugging to LEVEL"},
    
    {"no-tracks",   'T', POPT_ARG_NONE, &opts.no_tracks, 0,
     "Don't show track information"},
    
    {"no-analyze",  'A', POPT_ARG_NONE, &opts.no_analysis, 0,
     "Don't filesystem analysis"},
    
#ifdef HAVE_CDDB
    {"no-cddb",     '\0', POPT_ARG_NONE, &opts.no_cddb, 0,
     "Don't look up audio CDDB information or print that"},
    
    {"cddb-port",   'P', POPT_ARG_INT, &opts.cddb_port, 8880,
     "CDDB port number to use (default 8880)"},
    
    {"cddb-http",   'H', POPT_ARG_NONE, &opts.cddb_http, 0,
     "Lookup CDDB via HTTP proxy (default no proxy)"},
    
    {"cddb-server", '\0', POPT_ARG_STRING, &opts.cddb_server, 0,
     "CDDB server to contact for information (default: freedb.freedb.org)"},
    
    {"cddb-cache",  '\0', POPT_ARG_STRING, &opts.cddb_cachedir, 0,
     "Location of CDDB cache directory (default ~/.cddbclient)"},
    
    {"cddb-email",  '\0', POPT_ARG_STRING, &opts.cddb_email, 0,
     "Email address to give CDDB server (default me@home"},
    
    {"no-cddb-cache", '\0', POPT_ARG_NONE, &opts.cddb_disable_cache, 0,
     "Lookup CDDB via HTTP proxy (default no proxy)"},
    
    {"cddb-timeout",  '\0', POPT_ARG_INT, &opts.cddb_timeout, 0,
     "CDDB timeout value in seconds (default 10 seconds)"},
#endif
  
    {"no-device-info", '\0', POPT_ARG_NONE, &opts.no_device, 0,
     "Don't show device info, just CD info"},
    
    {"no-disc-mode", '\0', POPT_ARG_NONE, &opts.no_disc_mode, 0,
     "Don't show disc-mode info"},
    
    {"dvd",   '\0', POPT_ARG_NONE, &opts.show_dvd, 0,
     "Attempt to give DVD information if a DVD is found."},

#ifdef HAVE_VCDINFO
    {"no-vcd",   'v', POPT_ARG_NONE, &opts.no_vcd, 0,
     "Don't look up Video CD information"},
#else 
    {"no-vcd",   'v', POPT_ARG_NONE, &opts.no_vcd, 1,
     "Don't look up Video CD information - for this build, this is always set"},
#endif
    {"no-ioctl",  'I', POPT_ARG_NONE,  &opts.no_ioctl, 0,
     "Don't show ioctl() information"},
    
    {"bin-file", 'b', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &psz_my_source, 
     OP_SOURCE_BIN, "set \"bin\" CD-ROM disk image file as source", "FILE"},
    
    {"cue-file", 'c', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &psz_my_source, 
     OP_SOURCE_CUE, "set \"cue\" CD-ROM disk image file as source", "FILE"},
    
    {"nrg-file", 'N', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &psz_my_source, 
     OP_SOURCE_NRG, "set Nero CD-ROM disk image file as source", "FILE"},
    
    {"toc-file", 't', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &psz_my_source, 
     OP_SOURCE_CDRDAO, "set cdrdao CD-ROM disk image file as source", "FILE"},
    
    {"input", 'i', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &psz_my_source, 
     OP_SOURCE_AUTO,
     "set source and determine if \"bin\" image or device", "FILE"},
    
    {"iso9660",  '\0', POPT_ARG_NONE, &opts.print_iso9660, 0,
     "print directory contents of any ISO-9660 filesystems"},
    
    {"cdrom-device", 'C', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &source_name, 
     OP_SOURCE_DEVICE,
     "set CD-ROM device as source", "DEVICE"},
    
    {"list-drives",   'l', POPT_ARG_NONE, &opts.list_drives, 0,
     "Give a list of CD-drives" },
    
    {"no-header", '\0', POPT_ARG_NONE, &opts.no_header, 
     0, "Don't display header and copyright (for regression testing)"},
    
#ifdef HAVE_JOLIET    
    {"no-joliet", '\0', POPT_ARG_NONE, &opts.no_joliet, 
     0, "Don't use Joliet extensions"},
#endif /*HAVE_JOLIET*/
    
    {"quiet",       'q', POPT_ARG_NONE, &opts.silent, 0,
     "Don't produce warning output" },
    
    {"version", 'V', POPT_ARG_NONE, &opts.version_only, 0,
     "display version and copyright information and exit"},
    POPT_AUTOHELP {NULL, 0, 0, NULL, 0}
  };
  poptContext optCon = poptGetContext (NULL, argc, argv, optionsTable, 0);

  program_name = strrchr(argv[0],'/');
  program_name = program_name ? strdup(program_name+1) : strdup(argv[0]);

  while ((opt = poptGetNextOpt (optCon)) != -1) {
    switch (opt) {
      
    case OP_SOURCE_AUTO:
    case OP_SOURCE_BIN: 
    case OP_SOURCE_CUE: 
    case OP_SOURCE_CDRDAO: 
    case OP_SOURCE_NRG: 
    case OP_SOURCE_DEVICE: 
      if (opts.source_image != INPUT_UNKNOWN) {
	report(stderr, "%s: another source type option given before.\n", 
		program_name);
	report(stderr, "%s: give only one source type option.\n", 
		program_name);
	break;
      } 

      /* For all input sources which are not a DEVICE, we need to make
	 a copy of the string; for a DEVICE the fill-out routine makes
	 the copy.
       */
      if (OP_SOURCE_DEVICE != opt) 
	source_name = strdup(psz_my_source);
      
      switch (opt) {
      case OP_SOURCE_BIN: 
	opts.source_image  = INPUT_BIN;
	break;
      case OP_SOURCE_CUE: 
	opts.source_image  = INPUT_CUE;
	break;
      case OP_SOURCE_CDRDAO: 
	opts.source_image  = INPUT_CDRDAO;
	break;
      case OP_SOURCE_NRG: 
	opts.source_image  = INPUT_NRG;
	break;
      case OP_SOURCE_AUTO:
	opts.source_image  = INPUT_AUTO;
	break;
      case OP_SOURCE_DEVICE: 
	opts.source_image  = INPUT_DEVICE;
	source_name = fillout_device_name(source_name);
	break;
      }
      break;
      
    default:
      poptFreeContext(optCon);
      return false;
    }
  }
  {
    const char *remaining_arg = poptGetArg(optCon);
    if ( remaining_arg != NULL) {
      if (opts.source_image != INPUT_UNKNOWN) {
	report(stderr, "%s: Source '%s' given as an argument of an option and as "
		 "unnamed option '%s'\n", 
		 program_name, psz_my_source, remaining_arg);
	poptFreeContext(optCon);
	free(program_name);
	exit (EXIT_FAILURE);
      }
      
      if (opts.source_image == INPUT_DEVICE)
	source_name = fillout_device_name(remaining_arg);
      else 
	source_name = strdup(remaining_arg);
      
      if ( (poptGetArgs(optCon)) != NULL) {
	report(stderr, "%s: Source specified in previously %s and %s\n", 
		 program_name, psz_my_source, remaining_arg);
	poptFreeContext(optCon);
	free(program_name);
	exit (EXIT_FAILURE);
	
      }
    }
  }
  
  poptFreeContext(optCon);
  return true;
}
コード例 #4
0
ファイル: cd-read.c プロジェクト: Crome/libcdio
/* Parse a options. */
static bool
parse_options (int argc, char *argv[])
{
  int opt;

  static const char helpText[] =
    "Usage: %s [OPTION...]\n"
    "  -a, --access-mode=STRING        Set CD control access mode\n"
    "  -m, --mode=MODE-TYPE            set CD-ROM read mode (audio, auto, m1f1, m1f2,\n"
    "                                  m2mf1, m2f2)\n"
    "  -d, --debug=INT                 Set debugging to LEVEL\n"
    "  -x, --hexdump                   Show output as a hex dump. The default is a\n"
    "                                  hex dump when output goes to stdout and no\n"
    "                                  hex dump when output is to a file.\n"
    "  -j, --just-hex                  Don't display printable chars on hex\n"
    "                                  dump. The default is print chars too.\n"
    "  --no-header                     Don't display header and copyright (for\n"
    "                                  regression testing)\n"
    "  --no-hexdump                    Don't show output as a hex dump.\n"
    "  -s, --start=INT                 Set LBA to start reading from\n"
    "  -e, --end=INT                   Set LBA to end reading from\n"
    "  -n, --number=INT                Set number of sectors to read\n"
    "  -b, --bin-file[=FILE]           set \"bin\" CD-ROM disk image file as source\n"
    "  -c, --cue-file[=FILE]           set \"cue\" CD-ROM disk image file as source\n"
    "  -i, --input[=FILE]              set source and determine if \"bin\" image or\n"
    "                                  device\n"
    "  -C, --cdrom-device[=DEVICE]     set CD-ROM device as source\n"
    "  -N, --nrg-file[=FILE]           set Nero CD-ROM disk image file as source\n"
    "  -t, --toc-file[=FILE]           set \"TOC\" CD-ROM disk image file as source\n"
    "  -o, --output-file=FILE          Output blocks to file rather than give a\n"
    "                                  hexdump.\n"
    "  -V, --version                   display version and copyright information\n"
    "                                  and exit\n"
    "\n"
    "Help options:\n"
    "  -?, --help                      Show this help message\n"
    "  --usage                         Display brief usage message\n";
  
  static const char usageText[] =
    "Usage: %s [-a|--access-mode STRING] [-m|--mode MODE-TYPE]\n"
    "        [-d|--debug INT] [-x|--hexdump] [--no-header] [--no-hexdump]\n"
    "        [-s|--start INT] [-e|--end INT] [-n|--number INT] [-b|--bin-file FILE]\n"
    "        [-c|--cue-file FILE] [-i|--input FILE] [-C|--cdrom-device DEVICE]\n"
    "        [-N|--nrg-file FILE] [-t|--toc-file FILE] [-o|--output-file FILE]\n"
    "        [-V|--version] [-?|--help] [--usage]\n";
  
  /* Command-line options */
  static const char optionsString[] = "a:m:d:xjs:e:n:b::c::i::C::N::t::o:V?";
  static const struct option optionsTable[] = {
  
    {"access-mode", required_argument, NULL, 'a'},
    {"mode", required_argument, NULL, 'm'},
    {"debug", required_argument, NULL, 'd'},
    {"hexdump", no_argument, NULL, 'x'},
    {"no-header", no_argument, &opts.no_header, 1},
    {"no-hexdump", no_argument, &opts.nohexdump, 1},
    {"just-hex", no_argument, &opts.just_hex, 'j'},
    {"start", required_argument, NULL, 's'},
    {"end", required_argument, NULL, 'e'},
    {"number", required_argument, NULL, 'n'},
    {"bin-file", optional_argument, NULL, 'b'},
    {"cue-file", optional_argument, NULL, 'c'},
    {"input", optional_argument, NULL, 'i'},
    {"cdrom-device", optional_argument, NULL, 'C'},
    {"nrg-file", optional_argument, NULL, 'N'},
    {"toc-file", optional_argument, NULL, 't'},
    {"output-file", required_argument, NULL, 'o'},
    {"version", no_argument, NULL, 'V'},
   
    {"help", no_argument, NULL, '?' },
    {"usage", no_argument, NULL, OP_USAGE },
    { NULL, 0, NULL, 0 }
  };
  
  program_name = strrchr(argv[0],'/');
  program_name = program_name ? strdup(program_name+1) : strdup(argv[0]);

  while ((opt = getopt_long(argc, argv, optionsString, optionsTable, NULL)) >= 0)
    switch (opt)
      {
      case 'a': opts.access_mode = strdup(optarg); break;
      case 'd': opts.debug_level = atoi(optarg); break;
      case 'x': opts.hexdump = 1; break;
      case 's': opts.start_lsn = atoi(optarg); break;
      case 'e': opts.end_lsn = atoi(optarg); break;
      case 'n': opts.num_sectors = atoi(optarg); break;
      case 'b': parse_source(OP_SOURCE_BIN); break;
      case 'c': parse_source(OP_SOURCE_CUE); break;
      case 'i': parse_source(OP_SOURCE_AUTO); break;
      case 'C': parse_source(OP_SOURCE_DEVICE); break;
      case 'N': parse_source(OP_SOURCE_NRG); break;
      case 't': parse_source(OP_SOURCE_CDRDAO); break;
      case 'o': opts.output_file = strdup(optarg); break;
     
      case 'm':
	process_suboption(optarg, modes_sublist,
			  sizeof(modes_sublist) / sizeof(subopt_entry_t),
                            "--mode");
        break;

      case 'V':
        print_version(program_name, VERSION, 0, true);
	free(program_name);
        exit (EXIT_SUCCESS);
        break;

      case '?':
	fprintf(stdout, helpText, program_name);
	free(program_name);
	exit(EXIT_INFO);
	break;
	
      case OP_USAGE:
	fprintf(stderr, usageText, program_name);
	free(program_name);
	exit(EXIT_FAILURE);
	break;

      case OP_HANDLED:
	break;
      }

  if (optind < argc) {
    const char *remaining_arg = argv[optind++];

    /* NOTE: A bug in the libpopt version checked source_image, which
       rendered the subsequent source_image test useless.
    */
    if (source_name != NULL) {
      report( stderr, "%s: Source specified in option %s and as %s\n", 
	      program_name, source_name, remaining_arg );
      free(program_name);
      exit (EXIT_FAILURE);
    }

    if (opts.source_image == INPUT_DEVICE)
      source_name = fillout_device_name(remaining_arg);
    else 
      source_name = strdup(remaining_arg);
      
    if (optind < argc) {
      report( stderr, "%s: Source specified in previously %s and %s\n", 
	      program_name, source_name, remaining_arg );
      free(program_name);
      exit (EXIT_FAILURE);
    }
  }
  
  if (opts.debug_level == 3) {
    cdio_loglevel_default = CDIO_LOG_INFO;
  } else if (opts.debug_level >= 4) {
    cdio_loglevel_default = CDIO_LOG_DEBUG;
  }

  if (opts.read_mode == READ_MODE_UNINIT) {
    report( stderr, 
	    "%s: Need to give a read mode "
	    "(audio, m1f1, m1f2, m2f1, m2f2, or auto)\n",
	    program_name );
    free(program_name);
    exit(10);
  }

  /* Check consistency between start_lsn, end_lsn and num_sectors. */

  if (opts.nohexdump && opts.hexdump != 2) {
    report( stderr, 
	    "%s: don't give both --hexdump and --no-hexdump together\n",
	    program_name );
    exit(13);
  }

  if (opts.nohexdump) opts.hexdump = 0;
  
  if (opts.start_lsn == CDIO_INVALID_LSN) {
    /* Maybe we derive the start from the end and num sectors. */
    if (opts.end_lsn == CDIO_INVALID_LSN) {
      /* No start or end LSN, so use 0 for the start */
      opts.start_lsn = 0;
      if (opts.num_sectors == 0) opts.num_sectors = 1;
    } else if (opts.num_sectors != 0) {
      if (opts.end_lsn <= opts.num_sectors) {
	report( stderr, "%s: end LSN (%lu) needs to be greater than "
		" the sector to read (%lu)\n",
		program_name, (unsigned long) opts.end_lsn, 
		(unsigned long) opts.num_sectors );
	exit(12);
      }
      opts.start_lsn = opts.end_lsn - opts.num_sectors + 1;
    }
  }

  /* opts.start_lsn has been set somehow or we've aborted. */

  if (opts.end_lsn == CDIO_INVALID_LSN) {
    if (0 == opts.num_sectors) opts.num_sectors = 1;
    opts.end_lsn = opts.start_lsn + opts.num_sectors - 1;
  } else {
    /* We were given an end lsn. */
    if (opts.end_lsn < opts.start_lsn) {
      report( stderr, 
	      "%s: end LSN (%lu) needs to be less than start LSN (%lu)\n",
	      program_name, (unsigned long) opts.start_lsn, 
	      (unsigned long) opts.end_lsn );
      free(program_name);
      exit(13);
    }
    if (opts.num_sectors != opts.end_lsn - opts.start_lsn + 1)
      if (opts.num_sectors != 0) {
	 report( stderr, 
		 "%s: inconsistency between start LSN (%lu), end (%lu), "
		 "and count (%d)\n",
		 program_name, (unsigned long) opts.start_lsn, 
		 (unsigned long) opts.end_lsn, opts.num_sectors );
	 free(program_name);
	 exit(14);
	}
    opts.num_sectors = opts.end_lsn - opts.start_lsn + 1;
  }
  
  return true;
}
コード例 #5
0
ファイル: cd-info.c プロジェクト: KorolevaFey/libcdio-osx
/* Parse all options. */
static bool
parse_options (int argc, char *argv[])
{
  int opt; /* used for argument parsing */

  static const char helpText[] =
    "Usage: %s [OPTION...]\n"
    "  -a, --access-mode=STRING        Set CD access method\n"
    "  -d, --debug=INT                 Set debugging to LEVEL\n"
    "  -T, --no-tracks                 Don't show track information\n"
    "  -A, --no-analyze                Don't show filesystem analysis\n"
#ifdef HAVE_CDDB
    "  --no-cddb                       Don't look up audio CDDB information\n"
    "                                  or print it\n"
    "  -P, --cddb-port=INT             CDDB port number to use (default 8880)\n"
    "  -H, --cddb-http                 Lookup CDDB via HTTP proxy (default no\n"
    "                                  proxy)\n"
    "  --cddb-server=STRING            CDDB server to contact for information\n"
    "                                  (default: freedb.freedb.org)\n"
    "  --cddb-cache=STRING             Location of CDDB cache directory\n"
    "                                  (default ~/.cddbclient)\n"
    "  --cddb-email=STRING             Email address to give CDDB server\n"
    "                                  (default me@home)\n"
    "  --no-cddb-cache                 Disable caching of CDDB entries\n"
    "                                  locally (default caches)\n"
    "  --cddb-timeout=INT              CDDB timeout value in seconds\n"
    "                                  (default 10 seconds)\n"
#else
    "  --no-cddb                       Does nothing since this program is not\n"
    "  -P, --cddb-port=INT             CDDB-enabled\n"
    "  -H, --cddb-http\n"
    "  --cddb-server=STRING\n"
    "  --cddb-cache=STRING\n"
    "  --cddb-email=STRING\n"
    "  --no-cddb-cache\n"
    "  --cddb-timeout=INT\n"
#endif
    "  --no-device-info                Don't show device info, just CD info\n"
    "  --no-disc-mode                  Don't show disc-mode info\n"
    "  --dvd                           Attempt to give DVD information if a DVD is\n"
    "                                  found.\n"
#ifdef HAVE_VCDINFO
    "  -v, --no-vcd                    Don't look up Video CD information\n"
#else
    "  -v, --no-vcd                    Don't look up Video CD information - for\n"
    "                                  this build, this is always set\n"
#endif
    "  -I, --no-ioctl                  Don't show ioctl() information\n"
    "  -b, --bin-file[=FILE]           set \"bin\" CD-ROM disk image file as source\n"
    "  -c, --cue-file[=FILE]           set \"cue\" CD-ROM disk image file as source\n"
    "  -N, --nrg-file[=FILE]           set Nero CD-ROM disk image file as source\n"
    "  -t, --toc-file[=FILE]           set cdrdao CD-ROM disk image file as source\n"
    "  -i, --input[=FILE]              set source and determine if \"bin\" image or\n"
    "                                  device\n"
    "  --iso9660                       print directory contents of any ISO-9660\n"
    "                                  filesystems\n"
    "  -C, --cdrom-device[=DEVICE]     set CD-ROM device as source\n"
    "  -l, --list-drives               Give a list of CD-drives\n"
    "  --no-header                     Don't display header and copyright (for\n"
    "                                  regression testing)\n"
#ifdef HAVE_JOLIET
    "  --no-joliet                     Don't use Joliet extensions\n"
#endif
    "  --no-rock-ridge                 Don't use Rock-Ridge-extension information\n"
    "  --no-xa                         Don't use XA-extension information\n"
    "  -q, --quiet                     Don't produce warning output\n"
    "  -V, --version                   display version and copyright information\n"
    "                                  and exit\n"
    "\n"
    "Help options:\n"
    "  -?, --help                      Show this help message\n"
    "  --usage                         Display brief usage message\n";
  
  static const char usageText[] = 
    "Usage: %s [-a|--access-mode STRING] [-d|--debug INT] [-T|--no-tracks]\n"
    "        [-A|--no-analyze] [--no-cddb] [-P|--cddb-port INT] [-H|--cddb-http]\n"
    "        [--cddb-server=STRING] [--cddb-cache=STRING] [--cddb-email=STRING]\n"
    "        [--no-cddb-cache] [--cddb-timeout=INT] [--no-device-info]\n"
    "        [--no-disc-mode] [--dvd] [-v|--no-vcd] [-I|--no-ioctl]\n"
    "        [-b|--bin-file FILE] [-c|--cue-file FILE] [-N|--nrg-file FILE]\n"
    "        [-t|--toc-file FILE] [-i|--input FILE] [--iso9660]\n"
    "        [-C|--cdrom-device DEVICE] [-l|--list-drives] [--no-header]\n"
    "        [--no-joliet] [--no-rock-ridge] [--no-xa] [-q|--quiet] [-V|--version]\n"
    "        [-?|--help] [--usage]\n";

  static const char optionsString[] = "a:d:TAP:HvIb::c::N::t::i::C::lqV?";
  static const struct option optionsTable[] = {
    {"access-mode", required_argument, NULL, 'a'},
    {"debug", required_argument, NULL, 'd' },
    {"no-tracks", no_argument, NULL, 'T' },
    {"no-analyze", no_argument, NULL, 'A' },
    {"no-cddb", no_argument, &opts.no_cddb, 1 },
    {"cddb-port", required_argument, NULL, 'P' },
    {"cddb-http", no_argument, NULL, 'H' },
    {"cddb-server", required_argument, NULL, OP_CDDB_SERVER },
    {"cddb-cache", required_argument, NULL, OP_CDDB_CACHE },
    {"cddb-email", required_argument, NULL, OP_CDDB_EMAIL },
    {"no-cddb-cache", no_argument, NULL, OP_CDDB_NOCACHE },
    {"cddb-timeout", required_argument, NULL, OP_CDDB_TIMEOUT },
    {"no-device-info", no_argument, &opts.no_device, 1 },
    {"no-disc-mode", no_argument, &opts.no_disc_mode, 1 },
    {"dvd", no_argument, &opts.show_dvd, 1 },
    {"no-vcd", no_argument, NULL, 'v' },
    {"no-ioctl", no_argument, NULL, 'I' },
    {"bin-file", optional_argument, NULL, 'b' },
    {"cue-file", optional_argument, NULL, 'c' },
    {"nrg-file", optional_argument, NULL, 'N' },
    {"toc-file", optional_argument, NULL, 't' },
    {"input", optional_argument, NULL, 'i' },
    {"iso9660", no_argument, &opts.print_iso9660, 1 },
    {"cdrom-device", optional_argument, NULL, 'C' },
    {"list-drives", no_argument, NULL, 'l' },
    {"no-header", no_argument, &opts.no_header, 1 }, 
#ifdef HAVE_JOLIET    
    {"no-joliet", no_argument, &opts.no_joliet, 1 },
#endif /*HAVE_JOLIET*/
    {"no-rock-ridge", no_argument, &opts.no_rock_ridge, 1 },
    {"no-xa", no_argument, &opts.no_xa, 1 },
    {"quiet", no_argument, NULL, 'q' },
    {"version", no_argument, NULL, 'V' },

    {"help", no_argument, NULL, '?' },
    {"usage", no_argument, NULL, OP_USAGE },
    { NULL, 0, NULL, 0 }
  };

  program_name = strrchr(argv[0],'/');
  program_name = program_name ? strdup(program_name+1) : strdup(argv[0]);

  while ((opt = getopt_long(argc, argv, optionsString, optionsTable, NULL)) >= 0) {
    switch (opt) {
    case 'a': opts.access_mode = strdup(optarg); break;
    case 'd': opts.debug_level = atoi(optarg); break;
    case 'T': opts.no_tracks = 1; break;
    case 'A': opts.no_analysis = 1; break;
#ifdef HAVE_CDDB
    case 'P': cddb_opts.port = atoi(optarg); break;
    case 'H': cddb_opts.http = 1; break;
    case OP_CDDB_SERVER: cddb_opts.server = strdup(optarg); break;
    case OP_CDDB_CACHE: cddb_opts.cachedir = strdup(optarg); break;
    case OP_CDDB_EMAIL: cddb_opts.email = strdup(optarg); break;
    case OP_CDDB_NOCACHE: cddb_opts.disable_cache = 1; break;
    case OP_CDDB_TIMEOUT: cddb_opts.timeout = atoi(optarg); break;
#endif
    case 'v': opts.no_vcd = 1; break;
    case 'I': opts.no_ioctl = 1; break;
    case 'b': parse_source(OP_SOURCE_BIN); break;
    case 'c': parse_source(OP_SOURCE_CUE); break;
    case 'N': parse_source(OP_SOURCE_NRG); break;
    case 't': parse_source(OP_SOURCE_CDRDAO); break;
    case 'i': parse_source(OP_SOURCE_AUTO); break;
    case 'C': parse_source(OP_SOURCE_DEVICE); break;
    case 'l': opts.list_drives = 1; break;
    case 'q': opts.silent = 1; break;
    case 'V': opts.version_only = 1; break;

    case '?':
      fprintf(stdout, helpText, program_name);
      free(program_name);
      exit(EXIT_INFO);
      break;

    case OP_USAGE:
      fprintf(stderr, usageText, program_name);
      free(program_name);
      exit(EXIT_FAILURE);
      break;

    case OP_HANDLED:
      break;
    }
  }

  if (optind < argc) {
    const char *remaining_arg = argv[optind++];

    if (source_name != NULL) {
      report(stderr, "%s: Source '%s' given as an argument of an option and as "
             "unnamed option '%s'\n", 
             program_name, source_name, remaining_arg);
      free(program_name);
      exit (EXIT_FAILURE);
    }

    if (opts.source_image == INPUT_DEVICE)
      source_name = fillout_device_name(remaining_arg);
    else 
      source_name = strdup(remaining_arg);

    if (optind < argc) {
      report(stderr, "%s: Source specified in previously %s and %s\n", 
             program_name, source_name, remaining_arg);
      free(program_name);
      exit (EXIT_FAILURE);
    }
  }

  return true;
}