libcdio  2.1.0
About: GNU libcdio is a library for CD-ROM and CD image access.
  Fossies Dox: libcdio-2.1.0.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

cdrdao.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 2004-2008, 2011-2012, 2014, 2017
3  Rocky Bernstein <rocky@gnu.org>
4  toc reading routine adapted from cuetools
5  Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>
6 
7  This program is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 /* This code implements low-level access functions for a CD images
22  residing inside a disk file (*.bin) and its associated cue sheet.
23  (*.cue).
24 */
25 #include "portable.h"
26 
27 #ifdef HAVE_LIMITS_H
28 #include <limits.h>
29 #endif
30 #ifdef HAVE_STDIO_H
31 #include <stdio.h>
32 #endif
33 #ifdef HAVE_STDLIB_H
34 #include <stdlib.h>
35 #endif
36 #ifdef HAVE_STRING_H
37 #include <string.h>
38 #endif
39 #ifdef HAVE_STRINGS_H
40 #include <strings.h>
41 #endif
42 #ifdef HAVE_GLOB_H
43 #include <glob.h>
44 #endif
45 #ifdef HAVE_ERRNO_H
46 #include <errno.h>
47 #endif
48 #ifdef HAVE_INTTYPES_H
49 #include <inttypes.h>
50 #else
51 #define PRId64 "lld"
52 #endif
53 
54 #include <ctype.h>
55 
56 #include <cdio/logging.h>
57 #include <cdio/sector.h>
58 #include <cdio/util.h>
59 #include <stdio.h>
60 #include <cdio/utf8.h>
61 #include <cdio/version.h>
62 
63 #include "image.h"
64 #include "cdio_assert.h"
65 #include "_cdio_stdio.h"
66 
67 /* reader */
68 
69 #define DEFAULT_CDIO_DEVICE "videocd.bin"
70 #define DEFAULT_CDIO_CDRDAO "videocd.toc"
71 
72 #ifdef _WIN32
73 #define CDIO_FOPEN fopen_utf8
74 #else
75 #define CDIO_FOPEN fopen
76 #endif
77 
78 #include "image_common.h"
79 #include "cdtext_private.h"
80 
81 static lsn_t get_disc_last_lsn_cdrdao (void *p_user_data);
82 static bool parse_tocfile (_img_private_t *cd, const char *p_toc_name);
83 
84 
85 static bool
86 check_track_is_blocksize_multiple(const char *psz_fname,
87  track_t i_track, off_t i_size,
88  uint16_t i_blocksize)
89 {
90  if (i_size % i_blocksize) {
91  cdio_info ("image %s track %d size (%" PRId64 ") not a multiple"
92  " of the blocksize (%ld)",
93  psz_fname ? psz_fname : "unknown??", i_track, (int64_t)i_size,
94  (long int) i_blocksize);
95  if (i_size % M2RAW_SECTOR_SIZE == 0)
96  cdio_info ("this may be a 2336-type disc image");
97  else if (i_size % CDIO_CD_FRAMESIZE_RAW == 0)
98  cdio_info ("this may be a 2352-type disc image");
99  return false;
100  }
101  return true;
102 }
103 
104 
108 static bool
110 {
111  lsn_t lead_lsn;
112 
113  if (env->gen.init)
114  return false;
115 
116  /* Have to set init before calling get_disc_last_lsn_cdrdao() or we will
117  get into infinite recursion calling passing right here.
118  */
119  env->gen.init = true;
120  env->gen.i_first_track = 1;
121  env->psz_mcn = NULL;
123 
124  /* Read in TOC sheet. */
125  if ( !parse_tocfile(env, env->psz_cue_name) ) return false;
126 
127  lead_lsn = get_disc_last_lsn_cdrdao( (_img_private_t *) env);
128 
129  if (-1 == lead_lsn)
130  return false;
131 
132  /* Fake out leadout track and sector count for last track*/
133  cdio_lsn_to_msf (lead_lsn, &env->tocent[env->gen.i_tracks].start_msf);
134  env->tocent[env->gen.i_tracks].start_lba = cdio_lsn_to_lba(lead_lsn);
135  env->tocent[env->gen.i_tracks-env->gen.i_first_track].sec_count =
136  cdio_lsn_to_lba(lead_lsn - env->tocent[env->gen.i_tracks-1].start_lba);
137 
138  return true;
139 }
140 
147 static off_t
148 _lseek_cdrdao (void *user_data, off_t offset, int whence)
149 {
150  _img_private_t *env = user_data;
151 
152  /* real_offset is the real byte offset inside the disk image
153  The number below was determined empirically. I'm guessing
154  the 1st 24 bytes of a bin file are used for something.
155  */
156  off_t real_offset=0;
157 
158  unsigned int i;
159 
160  env->pos.lba = 0;
161  for (i=0; i<env->gen.i_tracks; i++) {
162  track_info_t *this_track=&(env->tocent[i]);
163  env->pos.index = i;
164  if ( (this_track->sec_count*this_track->datasize) >= offset) {
165  int blocks = (int) (offset / this_track->datasize);
166  int rem = (int) (offset % this_track->datasize);
167  off_t block_offset = blocks * this_track->blocksize;
168  real_offset += block_offset + rem;
169  env->pos.buff_offset = rem;
170  env->pos.lba += (lba_t)blocks;
171  break;
172  }
173  real_offset += this_track->sec_count*this_track->blocksize;
174  offset -= this_track->sec_count*this_track->datasize;
175  env->pos.lba += this_track->sec_count;
176  }
177 
178  if (i==env->gen.i_tracks) {
179  cdio_warn ("seeking outside range of disk image");
180  return -1;
181  } else {
182  real_offset += env->tocent[i].datastart;
183  return cdio_stream_seek(env->tocent[i].data_source, real_offset, whence);
184  }
185 }
186 
194 static ssize_t
195 _read_cdrdao (void *user_data, void *data, size_t size)
196 {
197  _img_private_t *env = user_data;
198  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
199  char *p = data;
200  ssize_t final_size=0;
201  ssize_t this_size;
202  track_info_t *this_track=&(env->tocent[env->pos.index]);
203  ssize_t skip_size = this_track->datastart + this_track->endsize;
204 
205  while (size > 0) {
206  int rem = (int) (this_track->datasize - env->pos.buff_offset);
207  if (size <= rem) {
208  this_size = cdio_stream_read(this_track->data_source, buf, size, 1);
209  final_size += this_size;
210  memcpy (p, buf, this_size);
211  break;
212  }
213 
214  /* Finish off reading this sector. */
215  cdio_warn ("Reading across block boundaries not finished");
216 
217  size -= rem;
218  this_size = cdio_stream_read(this_track->data_source, buf, rem, 1);
219  final_size += this_size;
220  memcpy (p, buf, this_size);
221  p += this_size;
222  cdio_stream_read(this_track->data_source, buf, rem, 1);
223 
224  /* Skip over stuff at end of this sector and the beginning of the next.
225  */
226  cdio_stream_read(this_track->data_source, buf, skip_size, 1);
227 
228  /* Get ready to read another sector. */
229  env->pos.buff_offset=0;
230  env->pos.lba++;
231 
232  /* Have gone into next track. */
233  if (env->pos.lba >= env->tocent[env->pos.index+1].start_lba) {
234  env->pos.index++;
235  this_track=&(env->tocent[env->pos.index]);
236  skip_size = this_track->datastart + this_track->endsize;
237  }
238  }
239  return final_size;
240 }
241 
248 static lsn_t
249 get_disc_last_lsn_cdrdao (void *p_user_data)
250 {
251  _img_private_t *p_env = p_user_data;
252  track_t i_leadout = p_env->gen.i_tracks;
253  uint16_t i_blocksize = p_env->tocent[i_leadout-1].blocksize;
254  off_t i_size;
255 
256  if (p_env->tocent[i_leadout-1].sec_count) {
257  i_size = p_env->tocent[i_leadout-1].sec_count;
258  } else {
259  if (NULL == p_env->tocent[i_leadout-1].data_source) {
260  if (!p_env->tocent[i_leadout-1].silence) {
261  cdio_warn ("Data source for image %s is null",
262  p_env->gen.source_name);
263  return -1;
264  }
265  /* FIXME: this is only correct if there is one
266  track of silence. */
267  i_size = p_env->tocent[i_leadout-1].silence;
268  } else {
269  /* FIXME: this is only correct if there is one data source. */
270  i_size = cdio_stream_stat(p_env->tocent[i_leadout-1].data_source)
271  - p_env->tocent[i_leadout-1].offset;
272  }
273  if (i_size < 0) {
274  cdio_error ("Disc data size too small for track specification in image %s",
275  p_env->gen.source_name);
276  return (lsn_t)i_size;
277  }
278  if (check_track_is_blocksize_multiple(p_env->tocent[i_leadout-1].filename,
279  i_leadout-1, i_size, i_blocksize)) {
280  i_size /= i_blocksize;
281  } else {
282  /* Round up */
283  i_size = (i_size / i_blocksize) + 1;
284  }
285  }
286 
287  i_size += p_env->tocent[i_leadout-1].start_lba;
288  i_size -= CDIO_PREGAP_SECTORS;
289 
290  return (lsn_t)i_size;
291 }
292 
293 #define MAXLINE 512
294 #define UNIMPLIMENTED_MSG \
295  cdio_log(log_level, "%s line %d: unimplimented keyword: %s", \
296  psz_cue_name, i_line, psz_keyword)
297 
298 
299 static bool
300 parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
301 {
302  /* The below declarations may be common in other image-parse routines. */
303  FILE *fp;
304  char psz_line[MAXLINE]; /* text of current line read in file fp. */
305  unsigned int i_line=0; /* line number in file of psz_line. */
306  int i = -1; /* Position in tocent. Same as
307  cd->gen.i_tracks - 1 */
308  char *psz_keyword, *psz_field, *psz_cue_name_dup;
309  cdio_log_level_t log_level = (cd) ? CDIO_LOG_WARN : CDIO_LOG_INFO ;
310  cdtext_field_t cdtext_key;
311 
312  /* The below declaration(s) may be unique to this image-parse routine. */
313  unsigned int i_cdtext_nest = 0;
314 
315  if (NULL == psz_cue_name)
316  return false;
317 
318  psz_cue_name_dup = _cdio_strdup_fixpath(psz_cue_name);
319  if (NULL == psz_cue_name_dup)
320  return false;
321 
322  fp = CDIO_FOPEN (psz_cue_name_dup, "r");
323  cdio_free(psz_cue_name_dup);
324  if (fp == NULL) {
325  cdio_log(log_level, "error opening %s for reading: %s",
326  psz_cue_name, strerror(errno));
327  return false;
328  }
329 
330  if (cd) {
331  cd->gen.b_cdtext_error = false;
332  }
333 
334  while (fgets(psz_line, MAXLINE, fp)) {
335 
336  i_line++;
337 
338  /* strip comment from line */
339  /* todo: // in quoted strings? */
340  /* //comment */
341  if ((psz_field = strstr (psz_line, "//")))
342  *psz_field = '\0';
343 
344  if ((psz_keyword = strtok (psz_line, " \t\n\r"))) {
345  /* CATALOG "ddddddddddddd" */
346  if (0 == strcmp ("CATALOG", psz_keyword)) {
347  if (-1 == i) {
348  if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
349  if (13 != strlen(psz_field)) {
350  cdio_log(log_level,
351  "%s line %d after word CATALOG:",
352  psz_cue_name, i_line);
353  cdio_log(log_level,
354  "Token %s has length %ld. Should be 13 digits.",
355  psz_field, (long int) strlen(psz_field));
356 
357  goto err_exit;
358  } else {
359  /* Check that we have all digits*/
360  unsigned int j;
361  for (j=0; j<13; j++) {
362  if (!isdigit((unsigned char) psz_field[j])) {
363  cdio_log(log_level,
364  "%s line %d after word CATALOG:",
365  psz_cue_name, i_line);
366  cdio_log(log_level,
367  "Character \"%c\" at postition %i of token \"%s\""
368  " is not all digits.",
369  psz_field[j], j+1, psz_field);
370  goto err_exit;
371  }
372  }
373  if (NULL != cd) cd->psz_mcn = strdup (psz_field);
374  }
375  } else {
376  cdio_log(log_level,
377  "%s line %d after word CATALOG:",
378  psz_cue_name, i_line);
379  cdio_log(log_level, "Expecting 13 digits; nothing seen.");
380  goto err_exit;
381  }
382  } else {
383  goto err_exit;
384  }
385 
386  /* CD_DA | CD_ROM | CD_ROM_XA */
387  } else if (0 == strcmp ("CD_DA", psz_keyword)) {
388  if (-1 == i) {
389  if (NULL != cd)
391  } else {
392  goto not_in_global_section;
393  }
394  } else if (0 == strcmp ("CD_ROM", psz_keyword)) {
395  if (-1 == i) {
396  if (NULL != cd)
398  } else {
399  goto not_in_global_section;
400  }
401 
402  } else if (0 == strcmp ("CD_ROM_XA", psz_keyword)) {
403  if (-1 == i) {
404  if (NULL != cd)
406  } else {
407  goto not_in_global_section;
408  }
409 
410  /* TRACK <track-mode> [<sub-channel-mode>] */
411  } else if (0 == strcmp ("TRACK", psz_keyword)) {
412  i++;
413  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
414  if (0 == strcmp ("AUDIO", psz_field)) {
415  if (NULL != cd) {
419  cd->tocent[i].datastart = 0;
420  cd->tocent[i].endsize = 0;
421  switch(cd->disc_mode) {
424  break;
428  /* Disc type stays the same. */
429  break;
433  break;
434  default:
436  }
437 
438  }
439  } else if (0 == strcmp ("MODE1", psz_field)) {
440  if (NULL != cd) {
448  switch(cd->disc_mode) {
451  break;
455  /* Disc type stays the same. */
456  break;
460  break;
461  default:
463  }
464  }
465  } else if (0 == strcmp ("MODE1_RAW", psz_field)) {
466  if (NULL != cd) {
474  switch(cd->disc_mode) {
477  break;
481  /* Disc type stays the same. */
482  break;
486  break;
487  default:
489  }
490  }
491  } else if (0 == strcmp ("MODE2", psz_field)) {
492  if (NULL != cd) {
497  cd->tocent[i].endsize = 0;
498  switch(cd->disc_mode) {
501  break;
505  /* Disc type stays the same. */
506  break;
510  break;
511  default:
513  }
514  }
515  } else if (0 == strcmp ("MODE2_FORM1", psz_field)) {
516  if (NULL != cd) {
521  cd->tocent[i].endsize = 0;
522  switch(cd->disc_mode) {
525  break;
529  /* Disc type stays the same. */
530  break;
534  break;
535  default:
537  }
538  }
539  } else if (0 == strcmp ("MODE2_FORM2", psz_field)) {
540  if (NULL != cd) {
547  switch(cd->disc_mode) {
550  break;
554  /* Disc type stays the same. */
555  break;
559  break;
560  default:
562  }
563  }
564  } else if (0 == strcmp ("MODE2_FORM_MIX", psz_field)) {
565  if (NULL != cd) {
571  cd->tocent[i].track_green = true;
572  cd->tocent[i].endsize = 0;
573  switch(cd->disc_mode) {
576  break;
580  /* Disc type stays the same. */
581  break;
585  break;
586  default:
588  }
589  }
590  } else if (0 == strcmp ("MODE2_RAW", psz_field)) {
591  if (NULL != cd) {
597  cd->tocent[i].track_green = true;
598  cd->tocent[i].endsize = 0;
599  switch(cd->disc_mode) {
602  break;
606  /* Disc type stays the same. */
607  break;
611  break;
612  default:
614  }
615  }
616  } else {
617  cdio_log(log_level, "%s line %d after TRACK:",
618  psz_cue_name, i_line);
619  cdio_log(log_level, "'%s' not a valid mode.", psz_field);
620  goto err_exit;
621  }
622  }
623  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
624  /* \todo: set sub-channel-mode */
625 #ifdef TODO
626  if (0 == strcmp ("RW", psz_field))
627  ;
628  else if (0 == strcmp ("RW_RAW", psz_field))
629  ;
630 #endif
631  }
632  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
633  goto format_error;
634  }
635 
636  /* track flags */
637  /* [NO] COPY | [NO] PRE_EMPHASIS */
638  } else if (0 == strcmp ("NO", psz_keyword)) {
639  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
640  if (0 == strcmp ("COPY", psz_field)) {
641  if (NULL != cd)
643 
644  } else if (0 == strcmp ("PRE_EMPHASIS", psz_field))
645  if (NULL != cd) {
647  }
648  } else {
649  goto format_error;
650  }
651  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
652  goto format_error;
653  }
654  } else if (0 == strcmp ("COPY", psz_keyword)) {
655  if (NULL != cd && i >= 0)
657  } else if (0 == strcmp ("PRE_EMPHASIS", psz_keyword)) {
658  if (NULL != cd && i >= 0)
660  /* TWO_CHANNEL_AUDIO */
661  } else if (0 == strcmp ("TWO_CHANNEL_AUDIO", psz_keyword)) {
662  if (NULL != cd && i >= 0)
664  /* FOUR_CHANNEL_AUDIO */
665  } else if (0 == strcmp ("FOUR_CHANNEL_AUDIO", psz_keyword)) {
666  if (NULL != cd && i >= 0)
668 
669  /* ISRC "CCOOOYYSSSSS" */
670  } else if (0 == strcmp ("ISRC", psz_keyword)) {
671  if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
672  if (NULL != cd)
673  cd->tocent[i].isrc = strdup(psz_field);
674  } else {
675  goto format_error;
676  }
677 
678  /* SILENCE <length> */
679  } else if (0 == strcmp ("SILENCE", psz_keyword)) {
680  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
681  if (NULL != cd)
682  cd->tocent[i].silence = cdio_mmssff_to_lba (psz_field);
683  } else {
684  goto format_error;
685  }
686  cdio_log(log_level, "%s line %d: SILENCE not fully implimented",
687  psz_cue_name, i_line);
688 
689  /* ZERO <length> */
690  } else if (0 == strcmp ("ZERO", psz_keyword)) {
692 
693  /* [FILE|AUDIOFILE] "<filename>" <start-msf> [<length-msf>] */
694  } else if (0 == strcmp ("FILE", psz_keyword)
695  || 0 == strcmp ("AUDIOFILE", psz_keyword)) {
696  if (0 <= i) {
697  if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
698  /* Handle "<filename>" */
699  if (cd) {
700  char *psz_dirname = cdio_dirname(psz_cue_name);
701  char *psz_filename = cdio_abspath(psz_dirname, psz_field);
702  cd->tocent[i].filename = strdup (psz_filename);
703  free(psz_filename);
704  free(psz_dirname);
705  /* To do: do something about reusing existing files. */
706  if (!(cd->tocent[i].data_source = cdio_stdio_new (psz_field))) {
707  cdio_log (log_level,
708  "%s line %d: can't open file `%s' for reading",
709  psz_cue_name, i_line, psz_field);
710  goto err_exit;
711  }
712  } else {
713  CdioDataSource_t *s = cdio_stdio_new (psz_field);
714  if (!s) {
715  cdio_log (log_level,
716  "%s line %d: can't open file `%s' for reading",
717  psz_cue_name, i_line, psz_field);
718  cdio_stdio_destroy (s);
719  goto err_exit;
720  }
721  cdio_stdio_destroy (s);
722  }
723  }
724 
725  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
726  /* Handle <start-msf> */
727  lba_t i_start_lba =
728  cdio_lsn_to_lba(cdio_mmssff_to_lba (psz_field));
729  if (CDIO_INVALID_LBA == i_start_lba) {
730  cdio_log(log_level, "%s line %d: invalid MSF string %s",
731  psz_cue_name, i_line, psz_field);
732  goto err_exit;
733  }
734 
735  if (NULL != cd) {
736  cd->tocent[i].start_lba = i_start_lba;
737  cdio_lba_to_msf(i_start_lba, &(cd->tocent[i].start_msf));
738  }
739  }
740  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
741  /* Handle <length-msf> */
742  lba_t lba = cdio_mmssff_to_lba (psz_field);
743  if (CDIO_INVALID_LBA == lba) {
744  cdio_log(log_level, "%s line %d: invalid MSF string %s",
745  psz_cue_name, i_line, psz_field);
746  goto err_exit;
747  }
748  if (cd) {
749  off_t i_size = cdio_stream_stat(cd->tocent[i].data_source);
750  if (lba) {
751  if ( (lba * cd->tocent[i].datasize) > i_size) {
752  cdio_log(log_level,
753  "%s line %d: MSF length %s exceeds end of file",
754  psz_cue_name, i_line, psz_field);
755  goto err_exit;
756  }
757  } else {
758  lba = (lba_t) (i_size / cd->tocent[i].blocksize);
759  }
760  cd->tocent[i].sec_count = lba;
761  }
762  }
763  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
764  goto format_error;
765  }
766  } else {
767  goto not_in_global_section;
768  }
769 
770  /* DATAFILE "<filename>" #byte-offset <start-msf> */
771  } else if (0 == strcmp ("DATAFILE", psz_keyword)) {
772  if (0 <= i) {
773  if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
774  /* Handle <filename> */
775  char *psz_dirname = cdio_dirname(psz_cue_name);
776  char *psz_filename = cdio_abspath(psz_dirname, psz_field);
777  if (cd) {
778  cd->tocent[i].filename = strdup(psz_filename);
779  /* To do: do something about reusing existing files. */
780  if (!(cd->tocent[i].data_source = cdio_stdio_new (psz_field))) {
781  cdio_log (log_level,
782  "%s line %d: can't open file `%s' for reading",
783  psz_cue_name, i_line, psz_field);
784  free(psz_filename);
785  free(psz_dirname);
786  goto err_exit;
787  }
788  } else {
789  CdioDataSource_t *s = cdio_stdio_new (psz_filename);
790  if (!s) {
791  cdio_log (log_level,
792  "%s line %d: can't open file `%s' for reading",
793  psz_cue_name, i_line, psz_field);
794  free(psz_filename);
795  free(psz_dirname);
796  goto err_exit;
797  }
798  cdio_stdio_destroy (s);
799  }
800  free(psz_filename);
801  free(psz_dirname);
802  }
803 
804  psz_field = strtok (NULL, " \t\n\r");
805  if (psz_field) {
806  /* Handle optional #byte-offset */
807  if ( psz_field[0] == '#') {
808  long int offset;
809  psz_field++;
810  errno = 0;
811  offset = strtol(psz_field, (char **)NULL, 10);
812  if ( (LONG_MIN == offset || LONG_MAX == offset)
813  && 0 != errno ) {
814  cdio_log (log_level,
815  "%s line %d: can't convert `%s' to byte offset",
816  psz_cue_name, i_line, psz_field);
817  goto err_exit;
818  } else {
819  if (NULL != cd) {
820  cd->tocent[i].offset = offset;
821  }
822  }
823  psz_field = strtok (NULL, " \t\n\r");
824  }
825  }
826  if (psz_field) {
827  /* Handle start-msf */
828  lba_t lba = cdio_mmssff_to_lba (psz_field);
829  if (CDIO_INVALID_LBA == lba) {
830  cdio_log(log_level, "%s line %d: invalid MSF string %s",
831  psz_cue_name, i_line, psz_field);
832  goto err_exit;
833  }
834  if (cd) {
835  cd->tocent[i].start_lba = lba;
837  &(cd->tocent[i].start_msf));
838  }
839  } else {
840  /* No start-msf. */
841  if (cd) {
842  if (i) {
843  uint16_t i_blocksize = cd->tocent[i-1].blocksize;
844  off_t i_size =
846 
848  i-1, i_size, i_blocksize);
849  /* Append size of previous datafile. */
850  cd->tocent[i].start_lba = (lba_t) (cd->tocent[i-1].start_lba +
851  (i_size / i_blocksize));
852  }
853  cd->tocent[i].offset = 0;
856  &(cd->tocent[i].start_msf));
857  }
858  }
859 
860  } else {
861  goto not_in_global_section;
862  }
863 
864  /* FIFO "<fifo path>" [<length>] */
865  } else if (0 == strcmp ("FIFO", psz_keyword)) {
866  goto unimplimented_error;
867 
868  /* START MM:SS:FF */
869  } else if (0 == strcmp ("START", psz_keyword)) {
870  if (0 <= i) {
871  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
872  /* todo: line is too long! */
873  if (NULL != cd) {
874  cd->tocent[i].pregap = cd->tocent[i].start_lba;
875  cd->tocent[i].start_lba += cdio_mmssff_to_lba (psz_field);
877  &(cd->tocent[i].start_msf));
878  }
879  }
880 
881  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
882  goto format_error;
883  }
884  } else {
885  goto not_in_global_section;
886  }
887 
888  /* PREGAP MM:SS:FF */
889  } else if (0 == strcmp ("PREGAP", psz_keyword)) {
890  if (0 <= i) {
891  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
892  if (NULL != cd)
893  cd->tocent[i].pregap = cdio_mmssff_to_lba (psz_field);
894  } else {
895  goto format_error;
896  }
897  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
898  goto format_error;
899  }
900  } else {
901  goto not_in_global_section;
902  }
903 
904  /* INDEX MM:SS:FF */
905  } else if (0 == strcmp ("INDEX", psz_keyword)) {
906  if (0 <= i) {
907  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
908  if (NULL != cd) {
909 #if 0
910  if (1 == cd->tocent[i].nindex) {
911  cd->tocent[i].indexes[1] = cd->tocent[i].indexes[0];
912  cd->tocent[i].nindex++;
913  }
914  cd->tocent[i].indexes[cd->tocent[i].nindex++] =
915  cdio_mmssff_to_lba (psz_field) + cd->tocent[i].indexes[0];
916 #else
917  ;
918 
919 #endif
920  }
921  } else {
922  goto format_error;
923  }
924  if (NULL != strtok (NULL, " \t\n\r")) {
925  goto format_error;
926  }
927  } else {
928  goto not_in_global_section;
929  }
930 
931  /* CD_TEXT { ... } */
932  /* todo: opening { must be on same line as CD_TEXT */
933  } else if (0 == strcmp ("CD_TEXT", psz_keyword)) {
934  if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
935  goto format_error;
936  }
937  if ( 0 == strcmp( "{", psz_field ) ) {
938  i_cdtext_nest++;
939  } else {
940  cdio_log (log_level,
941  "%s line %d: expecting '{'", psz_cue_name, i_line);
942  goto err_exit;
943  }
944 
945  // TODO: implement language mapping
946  } else if (0 == strcmp ("LANGUAGE_MAP", psz_keyword)) {
947  /* LANGUAGE d { ... } */
948  } else if (0 == strcmp ("LANGUAGE", psz_keyword)) {
949  /* Language number */
950  if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
951  goto format_error;
952  }
953  if ( 0 == strcmp( "{", psz_field ) ) {
954  i_cdtext_nest++;
955  }
956  } else if (0 == strcmp ("{", psz_keyword)) {
957  i_cdtext_nest++;
958  } else if (0 == strcmp ("}", psz_keyword)) {
959  if (i_cdtext_nest > 0) i_cdtext_nest--;
960  } else if ( CDTEXT_FIELD_INVALID !=
961  (cdtext_key = cdtext_is_field (psz_keyword)) ) {
962  if (NULL != cd) {
963  if (NULL == cd->gen.cdtext) {
964  cd->gen.cdtext = cdtext_init ();
965  /* until language mapping is implemented ...*/
967  }
968  cdtext_set (cd->gen.cdtext, cdtext_key, (uint8_t*) strtok (NULL, "\"\t\n\r"),
969  (-1 == i ? 0 : cd->gen.i_first_track + i),
970  "ISO-8859-1");
971  }
972 
973  /* unrecognized line */
974  } else {
975  cdio_log(log_level, "%s line %d: warning: unrecognized word: %s",
976  psz_cue_name, i_line, psz_keyword);
977  goto err_exit;
978  }
979  }
980  }
981 
982  if (NULL != cd) {
983  cd->gen.i_tracks = i+1;
984  cd->gen.toc_init = true;
985  }
986 
987  fclose (fp);
988  return true;
989 
990  unimplimented_error:
992  goto err_exit;
993 
994  format_error:
995  cdio_log(log_level, "%s line %d after word %s",
996  psz_cue_name, i_line, psz_keyword);
997  goto err_exit;
998 
999  not_in_global_section:
1000  cdio_log(log_level, "%s line %d: word %s only allowed in global section",
1001  psz_cue_name, i_line, psz_keyword);
1002 
1003  err_exit:
1004  fclose (fp);
1005  return false;
1006 }
1007 
1012 static driver_return_code_t
1013 _read_audio_sectors_cdrdao (void *user_data, void *data, lsn_t lsn,
1014  unsigned int nblocks)
1015 {
1016  _img_private_t *env = user_data;
1017  int ret;
1018 
1019  ret = cdio_stream_seek (env->tocent[0].data_source,
1021  if (ret!=0) return ret;
1022 
1023  ret = cdio_stream_read (env->tocent[0].data_source, data,
1024  CDIO_CD_FRAMESIZE_RAW, nblocks);
1025 
1026  /* ret is number of bytes if okay, but we need to return 0 okay. */
1027  return ret == 0;
1028 }
1029 
1034 static driver_return_code_t
1035 _read_mode1_sector_cdrdao (void *user_data, void *data, lsn_t lsn,
1036  bool b_form2)
1037 {
1038  _img_private_t *env = user_data;
1039  int ret;
1040  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
1041 
1042  ret = cdio_stream_seek (env->tocent[0].data_source,
1044  if (ret!=0) return ret;
1045 
1046  /* FIXME: Not completely sure the below is correct. */
1047  ret = cdio_stream_read (env->tocent[0].data_source, buf,
1049  if (ret==0) return ret;
1050 
1051  memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE,
1053 
1054  return DRIVER_OP_SUCCESS;
1055 }
1056 
1062 static int
1063 _read_mode1_sectors_cdrdao (void *user_data, void *data, lsn_t lsn,
1064  bool b_form2, unsigned int nblocks)
1065 {
1066  _img_private_t *env = user_data;
1067  int i;
1068  int retval;
1069  unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
1070 
1071  for (i = 0; i < nblocks; i++) {
1072  if ( (retval = _read_mode1_sector_cdrdao (env,
1073  ((char *)data) + (blocksize * i),
1074  lsn + i, b_form2)) )
1075  return retval;
1076  }
1077  return DRIVER_OP_SUCCESS;
1078 }
1079 
1084 static driver_return_code_t
1085 _read_mode2_sector_cdrdao (void *user_data, void *data, lsn_t lsn,
1086  bool b_form2)
1087 {
1088  _img_private_t *env = user_data;
1089  int ret;
1090  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
1091  long unsigned int i_off = lsn * CDIO_CD_FRAMESIZE_RAW;
1092 
1093  /* For sms's VCD's (mwc1.toc) it is more like this:
1094  if (i_off > 272) i_off -= 272;
1095  There is that magic 272 that we find in read_audio_sectors_cdrdao again.
1096  */
1097 
1098  /* NOTE: The logic below seems a bit wrong and convoluted
1099  to me, but passes the regression tests. (Perhaps it is why we get
1100  valgrind errors in vcdxrip). Leave it the way it was for now.
1101  Review this sector 2336 stuff later.
1102  */
1103 
1104  ret = cdio_stream_seek (env->tocent[0].data_source, i_off, SEEK_SET);
1105  if (ret!=0) return ret;
1106 
1107  ret = cdio_stream_read (env->tocent[0].data_source, buf,
1109  if (ret==0) return ret;
1110 
1111 
1112  /* See NOTE above. */
1113  if (b_form2)
1114  memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE,
1116  else
1117  memcpy (data, buf + CDIO_CD_XA_SYNC_HEADER, CDIO_CD_FRAMESIZE);
1118 
1119  return DRIVER_OP_SUCCESS;
1120 }
1121 
1127 static driver_return_code_t
1128 _read_mode2_sectors_cdrdao (void *user_data, void *data, lsn_t lsn,
1129  bool b_form2, unsigned int nblocks)
1130 {
1131  _img_private_t *env = user_data;
1132  int i;
1133  int retval;
1134 
1135  for (i = 0; i < nblocks; i++) {
1136  if ( (retval = _read_mode2_sector_cdrdao (env,
1137  ((char *)data) + (CDIO_CD_FRAMESIZE * i),
1138  lsn + i, b_form2)) )
1139  return retval;
1140  }
1141  return 0;
1142 }
1143 
1147 char **
1149 {
1150  char **drives = NULL;
1151  unsigned int num_files=0;
1152 #ifdef HAVE_GLOB_H
1153  unsigned int i;
1154  glob_t globbuf;
1155  globbuf.gl_offs = 0;
1156  glob("*.toc", GLOB_DOOFFS, NULL, &globbuf);
1157  for (i=0; i<globbuf.gl_pathc; i++) {
1158  cdio_add_device_list(&drives, globbuf.gl_pathv[i], &num_files);
1159  }
1160  globfree(&globbuf);
1161 #else
1162  cdio_add_device_list(&drives, DEFAULT_CDIO_DEVICE, &num_files);
1163 #endif /*HAVE_GLOB_H*/
1164  cdio_add_device_list(&drives, NULL, &num_files);
1165  return drives;
1166 }
1167 
1171 char *
1173 {
1174  char **drives = cdio_get_devices_nrg();
1175  char *drive = (drives[0] == NULL) ? NULL : strdup(drives[0]);
1176  cdio_free_device_list(drives);
1177  return drive;
1178 }
1179 
1180 static bool
1181 get_hwinfo_cdrdao ( const CdIo_t *p_cdio, /*out*/ cdio_hwinfo_t *hw_info)
1182 {
1183  strncpy(hw_info->psz_vendor, "libcdio",
1184  sizeof(hw_info->psz_vendor)-1);
1185  hw_info->psz_vendor[sizeof(hw_info->psz_vendor)-1] = '\0';
1186  strncpy(hw_info->psz_model, "cdrdao",
1187  sizeof(hw_info->psz_model)-1);
1188  hw_info->psz_model[sizeof(hw_info->psz_model)-1] = '\0';
1189  strncpy(hw_info->psz_revision, CDIO_VERSION,
1190  sizeof(hw_info->psz_revision)-1);
1191  hw_info->psz_revision[sizeof(hw_info->psz_revision)-1] = '\0';
1192  return true;
1193 }
1194 
1199 static track_format_t
1200 _get_track_format_cdrdao(void *p_user_data, track_t i_track)
1201 {
1202  _img_private_t *p_env = p_user_data;
1203 
1204  if (!p_env->gen.init) return TRACK_FORMAT_ERROR;
1205 
1206  if (i_track > p_env->gen.i_tracks || i_track == 0)
1207  return TRACK_FORMAT_ERROR;
1208 
1209  return p_env->tocent[i_track-p_env->gen.i_first_track].track_format;
1210 }
1211 
1220 static bool
1221 _get_track_green_cdrdao(void *user_data, track_t i_track)
1222 {
1223  _img_private_t *env = user_data;
1224 
1225  if (!env->gen.init) _init_cdrdao(env);
1226 
1227  if (i_track > env->gen.i_tracks || i_track == 0)
1228  return false;
1229 
1230  return env->tocent[i_track-env->gen.i_first_track].track_green;
1231 }
1232 
1240 static lba_t
1241 _get_lba_track_cdrdao(void *p_user_data, track_t i_track)
1242 {
1243  _img_private_t *p_env = p_user_data;
1244  _init_cdrdao (p_env);
1245 
1246  if (i_track == CDIO_CDROM_LEADOUT_TRACK)
1247  i_track = p_env->gen.i_tracks+1;
1248 
1249  if (i_track <= p_env->gen.i_tracks+1 && i_track != 0) {
1250  return p_env->tocent[i_track-1].start_lba;
1251  } else
1252  return CDIO_INVALID_LBA;
1253 }
1254 
1259 bool
1260 cdio_is_tocfile(const char *psz_cue_name)
1261 {
1262  int i;
1263 
1264  if (psz_cue_name == NULL) return false;
1265 
1266  i=strlen(psz_cue_name)-strlen("toc");
1267 
1268  if (i>0) {
1269  if ( (psz_cue_name[i]=='t' && psz_cue_name[i+1]=='o' && psz_cue_name[i+2]=='c')
1270  || (psz_cue_name[i]=='T' && psz_cue_name[i+1]=='O' && psz_cue_name[i+2]=='C') ) {
1271  return parse_tocfile(NULL, psz_cue_name);
1272  }
1273  }
1274  return false;
1275 }
1276 
1282 CdIo_t *
1283 cdio_open_am_cdrdao (const char *psz_source_name, const char *psz_access_mode)
1284 {
1285  if (psz_access_mode != NULL && strcmp(psz_access_mode, "image"))
1286  cdio_warn ("there is only one access mode, 'image' for cdrdao. Arg %s ignored",
1287  psz_access_mode);
1288  return cdio_open_cdrdao(psz_source_name);
1289 }
1290 
1296 CdIo_t *
1297 cdio_open_cdrdao (const char *psz_cue_name)
1298 {
1299  CdIo_t *ret;
1300  _img_private_t *p_data;
1301 
1302  cdio_funcs_t _funcs;
1303 
1304  memset( &_funcs, 0, sizeof(_funcs) );
1305 
1307  _funcs.free = _free_image;
1308  _funcs.get_arg = _get_arg_image;
1309  _funcs.get_cdtext = _get_cdtext_image;
1310  _funcs.get_cdtext_raw = NULL;
1317  _funcs.get_hwinfo = get_hwinfo_cdrdao;
1319  _funcs.get_mcn = _get_mcn_image;
1330  _funcs.lseek = _lseek_cdrdao;
1331  _funcs.read = _read_cdrdao;
1338  _funcs.run_mmc_cmd = NULL;
1339  _funcs.set_arg = _set_arg_image;
1342 
1343  if (NULL == psz_cue_name) return NULL;
1344 
1345  p_data = calloc(1, sizeof (_img_private_t));
1346  p_data->gen.init = false;
1347  p_data->psz_cue_name = NULL;
1348  p_data->gen.data_source = NULL;
1349  p_data->gen.source_name = NULL;
1350 
1351  ret = cdio_new ((void *)p_data, &_funcs);
1352 
1353  if (ret == NULL) {
1354  free(p_data);
1355  return NULL;
1356  }
1357 
1358  ret->driver_id = DRIVER_CDRDAO;
1359  if (!cdio_is_tocfile(psz_cue_name)) {
1360  cdio_debug ("source name %s is not recognized as a TOC file",
1361  psz_cue_name);
1362  free(p_data);
1363  free(ret);
1364  return NULL;
1365  }
1366 
1367  _set_arg_image (p_data, "cue", psz_cue_name);
1368  _set_arg_image (p_data, "source", psz_cue_name);
1369  _set_arg_image (p_data, "access-mode", "cdrdao");
1370 
1371  if (_init_cdrdao(p_data)) {
1372  return ret;
1373  } else {
1374  _free_image(p_data);
1375  free(ret);
1376  return NULL;
1377  }
1378 }
1379 
1380 bool
1382 {
1383  return true;
1384 }
cdio_free_device_list
void cdio_free_device_list(char *device_list[])
Definition: device.c:477
SEEK_SET
#define SEEK_SET
Definition: read.c:171
_set_arg_image
driver_return_code_t _set_arg_image(void *p_user_data, const char key[], const char value[])
Definition: image_common.c:366
_lseek_cdrdao
static off_t _lseek_cdrdao(void *user_data, off_t offset, int whence)
Definition: cdrdao.c:148
lba_t
int32_t lba_t
Definition: types.h:259
track_info_t::blocksize
uint16_t blocksize
Definition: image.h:80
_img_private_t::gen
generic_img_private_t gen
Definition: image_common.h:33
track_info_t::data_source
CdioDataSource_t * data_source
Definition: image.h:62
_CdioDataSource
Definition: _cdio_stream.c:48
generic_img_private_t::i_first_track
track_t i_first_track
Definition: generic.h:61
cdio_funcs_t::lseek
off_t(* lseek)(void *p_env, off_t offset, int whence)
Definition: cdio_private.h:360
cdio_generic_unimplemented_set_speed
int cdio_generic_unimplemented_set_speed(void *p_user_data, int i_speed)
Definition: _cdio_generic.c:92
cdtext_block_s::language_code
cdtext_lang_t language_code
Definition: cdtext_private.h:117
_get_track_msf_image
bool _get_track_msf_image(void *p_user_data, track_t i_track, msf_t *msf)
Definition: image_common.c:215
track_info_t::flags
flag_t flags
Definition: image.h:59
TRACK_FORMAT_XA
Definition: track.h:34
track_info_t::pregap
lba_t pregap
Definition: image.h:54
cdio_have_cdrdao
bool cdio_have_cdrdao(void)
Definition: cdrdao.c:1381
check_track_is_blocksize_multiple
static bool check_track_is_blocksize_multiple(const char *psz_fname, track_t i_track, off_t i_size, uint16_t i_blocksize)
Definition: cdrdao.c:86
CDIO_TRACK_FLAG_PRE_EMPHASIS
Definition: types.h:330
cdio_lsn_to_lba
lba_t cdio_lsn_to_lba(lsn_t i_lsn)
Definition: sector.c:114
cdio_add_device_list
void cdio_add_device_list(char **device_list[], const char *drive, unsigned int *num_drives)
Definition: _cdio_generic.c:238
CDIO_DISC_MODE_CD_MIXED
Definition: disc.h:41
cdio_funcs_t::read_mode2_sectors
int(* read_mode2_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2, unsigned int i_blocks)
Definition: cdio_private.h:410
generic_img_private_t::source_name
char * source_name
Definition: generic.h:48
cdio_warn
void void void void cdio_warn(const char format[],...) GNUC_PRINTF(1
_read_mode1_sector_cdrdao
static driver_return_code_t _read_mode1_sector_cdrdao(void *user_data, void *data, lsn_t lsn, bool b_form2)
Definition: cdrdao.c:1035
cdio_get_devices_cdrdao
char ** cdio_get_devices_cdrdao(void)
Definition: cdrdao.c:1148
cdio_funcs_t::get_media_changed
int(* get_media_changed)(const void *p_env)
Definition: cdio_private.h:273
lsn_t
int32_t lsn_t
Definition: types.h:266
driver_return_code_t
driver_return_code_t
Definition: device.h:205
cdio_funcs_t::get_default_device
char *(* get_default_device)(void)
Definition: cdio_private.h:223
_img_private_t::psz_mcn
char * psz_mcn
Definition: image_common.h:41
cdio_new
CdIo_t * cdio_new(generic_img_private_t *p_env, cdio_funcs_t *p_funcs)
Definition: cdio.c:58
CDTEXT_FIELD_INVALID
Definition: cdtext.h:55
cdio_lba_to_msf
void cdio_lba_to_msf(lba_t i_lba, msf_t *p_msf)
Definition: sector.c:124
cdio_hwinfo::psz_model
char psz_model[CDIO_MMC_HW_MODEL_LEN+1]
Definition: device.h:125
cdio_funcs_t::get_track_preemphasis
track_flag_t(* get_track_preemphasis)(const void *p_env, track_t i_track)
Definition: cdio_private.h:353
cdio_funcs_t::run_mmc_cmd
mmc_run_cmd_fn_t run_mmc_cmd
Definition: cdio_private.h:447
_img_private_t::psz_cue_name
char * psz_cue_name
Definition: image_common.h:36
generic_img_private_t::toc_init
bool toc_init
Definition: generic.h:50
cdio_funcs_t::get_devices
char **(* get_devices)(void)
Definition: cdio_private.h:211
_get_lba_track_cdrdao
static lba_t _get_lba_track_cdrdao(void *p_user_data, track_t i_track)
Definition: cdrdao.c:1241
track_info_t::filename
char * filename
Definition: image.h:61
cdio_funcs_t::get_track_copy_permit
track_flag_t(* get_track_copy_permit)(void *p_env, track_t i_track)
Definition: cdio_private.h:297
cdio_generic_unimplemented_set_blocksize
int cdio_generic_unimplemented_set_blocksize(void *p_user_data, uint16_t i_blocksize)
Definition: _cdio_generic.c:82
get_disc_last_lsn_cdrdao
static lsn_t get_disc_last_lsn_cdrdao(void *p_user_data)
Definition: cdrdao.c:249
cdtext_s::block
struct cdtext_block_s block[CDTEXT_NUM_BLOCKS_MAX]
Definition: cdtext_private.h:128
cdio_hwinfo::psz_revision
char psz_revision[CDIO_MMC_HW_REVISION_LEN+1]
Definition: device.h:126
CDTEXT_LANGUAGE_ENGLISH
Definition: cdtext.h:111
cdio_funcs_t::set_speed
int(* set_speed)(void *p_env, int i_speed)
Definition: cdio_private.h:466
cdio_funcs_t::get_track_lba
lba_t(* get_track_lba)(void *p_env, track_t i_track)
Definition: cdio_private.h:306
_img_private_t::pos
internal_position_t pos
Definition: image_common.h:34
track_info_t::sec_count
int sec_count
Definition: image.h:56
CDIO_CD_FRAMESIZE_RAW
Definition: sector.h:118
read_data_sectors_image
driver_return_code_t read_data_sectors_image(void *p_user_data, void *p_buf, lsn_t i_lsn, uint16_t i_blocksize, uint32_t i_blocks)
Definition: image_common.c:330
track_t
uint8_t track_t
Definition: types.h:276
_get_arg_image
const char * _get_arg_image(void *user_data, const char key[])
Definition: image_common.c:83
cdtext_is_field
cdtext_field_t cdtext_is_field(const char *key)
Definition: cdtext.c:520
_get_first_track_num_image
track_t _get_first_track_num_image(void *p_user_data)
Definition: image_common.c:156
get_hwinfo_cdrdao
static bool get_hwinfo_cdrdao(const CdIo_t *p_cdio, cdio_hwinfo_t *hw_info)
Definition: cdrdao.c:1181
generic_img_private_t::init
bool init
Definition: generic.h:49
CDIO_DISC_MODE_ERROR
Definition: disc.h:55
cdio_funcs_t::get_track_format
track_format_t(* get_track_format)(void *p_env, track_t i_track)
Definition: cdio_private.h:327
version.h
A file containing the libcdio package version number (20100) and OS build name.
_img_private_t
Definition: image_common.h:30
_CdIo
Definition: cdio_private.h:472
CDIO_LOG_INFO
Definition: logging.h:38
PRId64
#define PRId64
Definition: cdrdao.c:51
cdio_funcs_t::get_track_green
bool(* get_track_green)(void *p_env, track_t i_track)
Definition: cdio_private.h:337
track_info_t::track_green
bool track_green
Definition: image.h:70
_get_discmode_image
discmode_t _get_discmode_image(void *p_user_data)
Definition: image_common.c:117
_img_private_t::disc_mode
discmode_t disc_mode
Definition: image_common.h:45
cdio_log_level_t
cdio_log_level_t
Definition: logging.h:36
cdio_debug
void void cdio_debug(const char format[],...) GNUC_PRINTF(1
i
int i
Definition: cdinfo-linux.c:194
_get_num_tracks_image
track_t _get_num_tracks_image(void *p_user_data)
Definition: image_common.c:200
_read_cdrdao
static ssize_t _read_cdrdao(void *user_data, void *data, size_t size)
Definition: cdrdao.c:195
cdio_funcs_t::read_mode1_sector
int(* read_mode1_sector)(void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2)
Definition: cdio_private.h:418
_cdio_strdup_fixpath
char * _cdio_strdup_fixpath(const char path[])
Definition: util.c:147
CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO
Definition: types.h:334
parse_tocfile
static bool parse_tocfile(_img_private_t *cd, const char *p_toc_name)
Definition: cdrdao.c:300
cdio_funcs_t::get_cdtext
cdtext_t *(* get_cdtext)(void *p_env)
Definition: cdio_private.h:191
cdio_hwinfo::psz_vendor
char psz_vendor[CDIO_MMC_HW_VENDOR_LEN+1]
Definition: device.h:124
cdio_error
void void void void void cdio_error(const char format[],...) GNUC_PRINTF(1
CDIO_CD_ECC_SIZE
Definition: sector.h:114
cdio_funcs_t::read_mode2_sector
int(* read_mode2_sector)(void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2)
Definition: cdio_private.h:402
cdio_funcs_t::eject_media
driver_return_code_t(* eject_media)(void *p_env)
Definition: cdio_private.h:166
cdtext_init
cdtext_t * cdtext_init(void)
Definition: cdtext.c:486
NULL
#define NULL
Definition: types.h:184
_cdio_stdio.h
cdtext_s::block_i
uint8_t block_i
Definition: cdtext_private.h:130
UNIMPLIMENTED_MSG
#define UNIMPLIMENTED_MSG
Definition: cdrdao.c:294
CDIO_DISC_MODE_CD_DA
Definition: disc.h:38
cdio_funcs_t::get_hwinfo
bool(* get_hwinfo)(const CdIo_t *p_cdio, cdio_hwinfo_t *p_hw_info)
Definition: cdio_private.h:256
_get_mcn_image
char * _get_mcn_image(const void *p_user_data)
Definition: image_common.c:188
_get_cdtext_image
cdtext_t * _get_cdtext_image(void *user_data)
Definition: image_common.c:103
generic_img_private_t::i_tracks
track_t i_tracks
Definition: generic.h:62
CDIO_CD_EDC_SIZE
#define CDIO_CD_EDC_SIZE
Definition: sector.h:149
_init_cdrdao
static bool _init_cdrdao(_img_private_t *env)
Definition: cdrdao.c:109
cdio_dirname
char * cdio_dirname(const char *fname)
Definition: abs_path.c:84
cdtext_set
void cdtext_set(cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value, track_t track, const char *charset)
Definition: cdtext.c:568
_get_track_format_cdrdao
static track_format_t _get_track_format_cdrdao(void *p_user_data, track_t i_track)
Definition: cdrdao.c:1200
cdio_funcs_t::read_audio_sectors
int(* read_audio_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, unsigned int i_blocks)
Definition: cdio_private.h:373
_read_audio_sectors_cdrdao
static driver_return_code_t _read_audio_sectors_cdrdao(void *user_data, void *data, lsn_t lsn, unsigned int nblocks)
Definition: cdrdao.c:1013
track_info_t::offset
off_t offset
Definition: image.h:63
util.h
Miscellaneous utility functions.
cdio_lsn_to_msf
void cdio_lsn_to_msf(lsn_t i_lsn, msf_t *p_msf)
Definition: sector.c:62
cdio_stream_seek
int cdio_stream_seek(CdioDataSource_t *p_obj, off_t offset, int whence)
Definition: _cdio_stream.c:179
get_track_preemphasis_image
track_flag_t get_track_preemphasis_image(const void *p_user_data, track_t i_track)
Definition: image_common.c:261
j
int j
Definition: cdinfo-linux.c:194
get_track_isrc_image
char * get_track_isrc_image(const void *p_user_data, track_t i_track)
Definition: image_common.c:300
track_info_t::datastart
uint16_t datastart
Definition: image.h:75
cdio_open_cdrdao
CdIo_t * cdio_open_cdrdao(const char *psz_cue_name)
Definition: cdrdao.c:1297
cdio_funcs_t::get_arg
const char *(* get_arg)(void *p_env, const char key[])
Definition: cdio_private.h:176
cdio_funcs_t::get_discmode
discmode_t(* get_discmode)(void *p_env)
Definition: cdio_private.h:234
CDIO_TRACK_FLAG_COPY_PERMITTED
Definition: types.h:332
track_format_t
track_format_t
Definition: track.h:31
cdio_funcs_t::get_disc_last_lsn
lsn_t(* get_disc_last_lsn)(void *p_env)
Definition: cdio_private.h:229
cdio_abspath
char * cdio_abspath(const char *cwd, const char *fname)
Definition: abs_path.c:94
cdio_mmssff_to_lba
lba_t cdio_mmssff_to_lba(const char *psz_mmssff)
Definition: sector.c:192
TRACK_FORMAT_DATA
Definition: track.h:35
track_info_t::endsize
uint16_t endsize
Definition: image.h:77
generic_img_private_t::cdtext
cdtext_t * cdtext
Definition: generic.h:69
image.h
CDIO_DISC_MODE_CD_DATA
Definition: disc.h:39
get_track_pregap_lba_image
lba_t get_track_pregap_lba_image(const void *p_user_data, track_t i_track)
Definition: image_common.c:273
_read_mode2_sector_cdrdao
static driver_return_code_t _read_mode2_sector_cdrdao(void *user_data, void *data, lsn_t lsn, bool b_form2)
Definition: cdrdao.c:1085
DRIVER_CDRDAO
Definition: device.h:162
cdtext_private.h
CDIO_DISC_MODE_NO_INFO
Definition: disc.h:54
err_exit
#define err_exit(fmt, args...)
Definition: cdinfo-linux.c:97
get_track_channels_image
int get_track_channels_image(const void *p_user_data, track_t i_track)
Definition: image_common.c:237
cdio_free
void cdio_free(void *p_memory)
Definition: memory.c:37
track_info_t::datasize
uint16_t datasize
Definition: image.h:73
cdio_stream_read
ssize_t cdio_stream_read(CdioDataSource_t *p_obj, void *ptr, size_t size, size_t nmemb)
Definition: _cdio_stream.c:150
cdio_funcs_t::get_track_msf
bool(* get_track_msf)(void *p_env, track_t i_track, msf_t *p_msf)
Definition: cdio_private.h:346
_get_track_green_cdrdao
static bool _get_track_green_cdrdao(void *user_data, track_t i_track)
Definition: cdrdao.c:1221
_read_mode2_sectors_cdrdao
static driver_return_code_t _read_mode2_sectors_cdrdao(void *user_data, void *data, lsn_t lsn, bool b_form2, unsigned int nblocks)
Definition: cdrdao.c:1128
cdio_info
void void void cdio_info(const char format[],...) GNUC_PRINTF(1
cdio_funcs_t::get_track_isrc
char *(* get_track_isrc)(const void *p_env, track_t i_track)
Definition: cdio_private.h:322
cdio_funcs_t::read_data_sectors
driver_return_code_t(* read_data_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, uint16_t i_blocksize, uint32_t i_blocks)
Definition: cdio_private.h:394
cdio_funcs_t::get_cdtext_raw
uint8_t *(* get_cdtext_raw)(void *p_env)
Definition: cdio_private.h:202
cdio_funcs_t::get_mcn
char *(* get_mcn)(const void *p_env)
Definition: cdio_private.h:279
M2RAW_SECTOR_SIZE
Definition: sector.h:190
cdio_hwinfo
Structure to return CD vendor, model, and revision-level strings obtained via the INQUIRY command
Definition: device.h:122
utf8.h
UTF-8 support.
CDIO_CD_SUBHEADER_SIZE
Definition: sector.h:112
cdio_funcs_t::get_num_tracks
track_t(* get_num_tracks)(void *p_env)
Definition: cdio_private.h:285
sector.h
Things related to CD-ROM layout: tracks, sector sizes, MSFs, LBAs.
track_info_t::start_lba
lba_t start_lba
Definition: image.h:52
CDIO_DISC_MODE_CD_XA
Definition: disc.h:40
cdio_funcs_t::free
void(* free)(void *p_env)
Definition: cdio_private.h:171
DEFAULT_CDIO_DEVICE
#define DEFAULT_CDIO_DEVICE
Definition: cdrdao.c:69
CDIO_CD_HEADER_SIZE
Definition: sector.h:110
internal_position_t::buff_offset
off_t buff_offset
Definition: cdio_private.h:485
cdio_log
void cdio_log(cdio_log_level_t level, const char format[],...) GNUC_PRINTF(2
cdio_funcs_t::set_blocksize
driver_return_code_t(* set_blocksize)(void *p_env, uint16_t i_blocksize)
Definition: cdio_private.h:457
get_track_copy_permit_image
track_flag_t get_track_copy_permit_image(void *p_user_data, track_t i_track)
Definition: image_common.c:248
logging.h
Header to control logging and level of detail of output.
get_media_changed_image
int get_media_changed_image(const void *p_user_data)
Definition: image_common.c:175
CDIO_VERSION
#define CDIO_VERSION
Definition: version.h:10
image_common.h
CDIO_CD_XA_SYNC_HEADER
#define CDIO_CD_XA_SYNC_HEADER
Definition: sector.h:173
generic_img_private_t::data_source
CdioDataSource_t * data_source
Definition: generic.h:59
cdio_funcs_t::get_first_track_num
track_t(* get_first_track_num)(void *p_env)
Definition: cdio_private.h:249
cdio_get_devices_nrg
char ** cdio_get_devices_nrg(void)
Definition: nrg.c:1166
CDIO_CD_M1F1_ZERO_SIZE
#define CDIO_CD_M1F1_ZERO_SIZE
Definition: sector.h:152
generic_img_private_t::b_cdtext_error
bool b_cdtext_error
Definition: generic.h:51
cdio_open_am_cdrdao
CdIo_t * cdio_open_am_cdrdao(const char *psz_source_name, const char *psz_access_mode)
Definition: cdrdao.c:1283
track_info_t::track_format
track_format_t track_format
Definition: image.h:69
cdio_funcs_t::get_drive_cap
void(* get_drive_cap)(const void *p_env, cdio_drive_read_cap_t *p_read_cap, cdio_drive_write_cap_t *p_write_cap, cdio_drive_misc_cap_t *p_misc_cap)
Definition: cdio_private.h:241
CDIO_CDROM_LEADOUT_TRACK
Definition: track.h:78
MAXLINE
#define MAXLINE
Definition: cdrdao.c:293
_CdIo::driver_id
driver_id_t driver_id
Definition: cdio_private.h:473
DRIVER_OP_SUCCESS
Definition: device.h:206
cdio_is_tocfile
bool cdio_is_tocfile(const char *psz_cue_name)
Definition: cdrdao.c:1260
CDIO_CD_FRAMESIZE
Definition: sector.h:116
_free_image
void _free_image(void *p_user_data)
Definition: image_common.c:57
cdio_stdio_new
CdioDataSource_t * cdio_stdio_new(const char pathname[])
Definition: _cdio_stdio.c:244
TRACK_FORMAT_AUDIO
Definition: track.h:32
_get_drive_cap_image
void _get_drive_cap_image(const void *user_data, cdio_drive_read_cap_t *p_read_cap, cdio_drive_write_cap_t *p_write_cap, cdio_drive_misc_cap_t *p_misc_cap)
Definition: image_common.c:128
cdio_funcs_t::set_arg
int(* set_arg)(void *p_env, const char key[], const char value[])
Definition: cdio_private.h:452
track_info_t
Definition: image.h:49
portable.h
track_info_t::isrc
char * isrc
Definition: image.h:60
CDIO_PREGAP_SECTORS
#define CDIO_PREGAP_SECTORS
Definition: sector.h:91
CDIO_INVALID_LBA
#define CDIO_INVALID_LBA
Definition: types.h:291
_eject_media_image
driver_return_code_t _eject_media_image(void *p_user_data)
Definition: image_common.c:46
cdio_get_default_device_cdrdao
char * cdio_get_default_device_cdrdao(void)
Definition: cdrdao.c:1172
track_info_t::silence
lba_t silence
Definition: image.h:55
cdio_stream_stat
off_t cdio_stream_stat(CdioDataSource_t *p_obj)
Definition: _cdio_stream.c:206
internal_position_t::index
track_t index
Definition: cdio_private.h:486
cdio_stdio_destroy
void cdio_stdio_destroy(CdioDataSource_t *p_obj)
Definition: _cdio_stdio.c:238
cdtext_field_t
cdtext_field_t
Enumeration of CD-TEXT text fields.
Definition: cdtext.h:44
CDIO_CD_SYNC_SIZE
Definition: sector.h:104
_read_mode1_sectors_cdrdao
static int _read_mode1_sectors_cdrdao(void *user_data, void *data, lsn_t lsn, bool b_form2, unsigned int nblocks)
Definition: cdrdao.c:1063
TRACK_FORMAT_ERROR
Definition: track.h:39
CDIO_LOG_WARN
Definition: logging.h:40
internal_position_t::lba
lba_t lba
Definition: cdio_private.h:487
cdio_assert.h
cdio_funcs_t::read_mode1_sectors
int(* read_mode1_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2, unsigned int i_blocks)
Definition: cdio_private.h:426
track_info_t::start_msf
msf_t start_msf
Definition: image.h:51
_img_private_t::tocent
track_info_t tocent[CDIO_CD_MAX_TRACKS+1]
Definition: image_common.h:43
cdio_funcs_t
Definition: cdio_private.h:91
cdio_funcs_t::get_track_channels
int(* get_track_channels)(const void *p_env, track_t i_track)
Definition: cdio_private.h:291
cdio_funcs_t::get_track_pregap_lba
lba_t(* get_track_pregap_lba)(const void *p_env, track_t i_track)
Definition: cdio_private.h:313
cdio_funcs_t::read
ssize_t(* read)(void *p_env, void *p_buf, size_t i_size)
Definition: cdio_private.h:367
CDIO_FOPEN
#define CDIO_FOPEN
Definition: cdrdao.c:75