xorriso  1.5.4.pl02
About: GNU xorriso creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. It is suitable for incremental data backup and for production of bootable ISO 9660 images. GNU xorriso is a statical compilation of the libraries libburn, libisofs, libisoburn, and libjte.
  Fossies Dox: xorriso-1.5.4.pl02.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

structure.c
Go to the documentation of this file.
1 
2 /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
3  Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
4  Provided under GPL version 2 or later.
5 */
6 
7 #ifdef HAVE_CONFIG_H
8 #include "../config.h"
9 #endif
10 
11 /* ts A61008 */
12 /* #include <a ssert.h> */
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <ctype.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include <errno.h>
23 
24 /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
25 #ifndef O_BINARY
26 #define O_BINARY 0
27 #endif
28 
29 #include "libburn.h"
30 #include "structure.h"
31 #include "write.h"
32 #include "debug.h"
33 #include "init.h"
34 #include "util.h"
35 #include "transport.h"
36 #include "mmc.h"
37 
38 #include "libdax_msgs.h"
39 extern struct libdax_msgs *libdax_messenger;
40 
41 
42 /* ts A61008 : replaced Assert by if and return 0 */
43 /* a ssert(!(pos > BURN_POS_END)); */
44 
45 #define RESIZE(TO, NEW, pos) {\
46  void *tmp;\
47 \
48  if (pos > BURN_POS_END)\
49  return 0;\
50  if (pos == BURN_POS_END)\
51  pos = TO->NEW##s;\
52  if ((int) pos > TO->NEW##s)\
53  return 0;\
54 \
55  tmp = realloc(TO->NEW, sizeof(struct NEW *) * (TO->NEW##s + 1));\
56  if (!tmp)\
57  return 0;\
58  TO->NEW = tmp;\
59  memmove(TO->NEW + pos + 1, TO->NEW + pos,\
60  sizeof(struct NEW *) * (TO->NEW##s - pos));\
61  TO->NEW##s++;\
62 }
63 
65 {
66  struct burn_disc *d;
67  d = calloc(1, sizeof(struct burn_disc));
68  if (d == NULL) /* ts A70825 */
69  return NULL;
70  d->refcnt = 1;
71  d->sessions = 0;
72  d->session = NULL;
73 
74 #ifdef Libburn_disc_with_incomplete_sessioN
75  d->incomplete_sessions= 0;
76 #endif
77 
78  return d;
79 }
80 
81 void burn_disc_free(struct burn_disc *d)
82 {
83  d->refcnt--;
84  if (d->refcnt == 0) {
85  /* dec refs on all elements */
86  int i;
87 
88  for (i = 0; i < d->sessions; i++)
90  free(d->session);
91  free(d);
92  }
93 }
94 
96 {
97  struct burn_session *s;
98  int i;
99 
100  s = calloc(1, sizeof(struct burn_session));
101  if (s == NULL) /* ts A70825 */
102  return NULL;
103  s->firsttrack = 1;
104  s->lasttrack = 0;
105  s->refcnt = 1;
106  s->tracks = 0;
107  s->track = NULL;
108  s->hidefirst = 0;
109  for (i = 0; i < 8; i++) {
110  s->cdtext[i] = NULL;
111  s->cdtext_language[i] = 0x00; /* Unknown */
112  s->cdtext_char_code[i] = 0x00; /* ISO-8859-1 */
113  s->cdtext_copyright[i] = 0x00;
114  }
115  s->cdtext_language[0] = 0x09; /* Single-block default is English */
116  s->mediacatalog[0] = 0;
117  return s;
118 }
119 
120 void burn_session_hide_first_track(struct burn_session *s, int onoff)
121 {
122  s->hidefirst = onoff;
123 }
124 
126 {
127  int i;
128 
129  s->refcnt--;
130  if (s->refcnt == 0) {
131  /* dec refs on all elements */
132  for (i = 0; i < s->tracks; i++)
133  burn_track_free(s->track[i]);
134  for (i = 0; i < 8; i++)
135  burn_cdtext_free(&(s->cdtext[i]));
136  free(s->track);
137  free(s);
138  }
139 
140 }
141 
143  unsigned int pos)
144 {
145  RESIZE(d, session, pos);
146  d->session[pos] = s;
147  s->refcnt++;
148  return 1;
149 }
150 
151 
152 /* ts A81202: this function was in the API but not implemented.
153 */
155 {
156  int i, skip = 0;
157 
158  if (d->session == NULL)
159  return 0;
160  for (i = 0; i < d->sessions; i++) {
161  if (s == d->session[i]) {
162  skip++;
163  continue;
164  }
165  d->session[i - skip] = d->session[i];
166  }
167  if (!skip)
168  return 0;
170  d->sessions--;
171  return 1;
172 }
173 
174 
176 {
177  struct burn_track *t;
178  int i;
179 
180  t = calloc(1, sizeof(struct burn_track));
181  if (t == NULL) /* ts A70825 */
182  return NULL;
183  t->refcnt = 1;
184  t->indices = 0;
185  for (i = 0; i < 100; i++)
186  t->index[i] = 0x7fffffff;
187  t->offset = 0;
188  t->offsetcount = 0;
189  t->tail = 0;
190  t->tailcount = 0;
191  t->mode = BURN_MODE1;
192  t->isrc.has_isrc = 0;
193  t->pad = 1;
194 
195  /* ts A70213 */
196  t->fill_up_media = 0;
197  /* ts A70218 */
198  t->default_size = 0;
199 
200  t->entry = NULL;
201  t->source = NULL;
202  t->eos = 0;
203 
204  /* ts A61101 */
205  t->sourcecount = 0;
206  t->writecount = 0;
207  t->written_sectors = 0;
208 
209  /* ts A61031 */
210  t->open_ended = 0;
211  t->track_data_done = 0;
212  /* ts B10103 */
213  t->end_on_premature_eoi = 0;
214 
215  t->pregap1 = 0;
216  t->pregap2 = 0;
217  t->pregap2_size = 150;
218 
219  t->postgap = 0;
220  t->postgap_size = 150;
221 
222  /* ts A61024 */
223  t->swap_source_bytes = 0;
224 
225  /* ts B11206 */
226  for (i = 0; i < 8; i++)
227  t->cdtext[i] = NULL;
228 
229  return t;
230 }
231 
233 {
234  int i;
235 
236  t->refcnt--;
237  if (t->refcnt == 0) {
238  /* dec refs on all elements */
239  if (t->source)
241  for (i = 0; i < 8; i++)
242  burn_cdtext_free(&(t->cdtext[i]));
243  free(t);
244  }
245 }
246 
248  unsigned int pos)
249 {
250  RESIZE(s, track, pos);
251  s->track[pos] = t;
252  t->refcnt++;
253  return 1;
254 }
255 
257 {
258  struct burn_track **tmp;
259  int i, pos = -1;
260 
261  /* ts A61008 */
262  /* a ssert(s->track != NULL); */
263  if (s->track == NULL)
264  return 0;
265 
266  burn_track_free(t);
267 
268  /* Find the position */
269  for (i = 0; i < s->tracks; i++) {
270  if (t == s->track[i]) {
271  pos = i;
272  break;
273  }
274  }
275 
276  if (pos == -1)
277  return 0;
278 
279  /* Is it the last track? */
280  if (pos != s->tracks - 1) {
281  memmove(&s->track[pos], &s->track[pos + 1],
282  sizeof(struct burn_track *) * (s->tracks - (pos + 1)));
283  }
284 
285  s->tracks--;
286  tmp = realloc(s->track, sizeof(struct burn_track *) * s->tracks);
287  if (tmp)
288  s->track = tmp;
289  return 1;
290 }
291 
293 {
294  int i;
295  char msg[40];
296 
297  sprintf(msg, "This disc has %d sessions", d->sessions);
298  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
300  msg, 0, 0);
301  for (i = 0; i < d->sessions; i++) {
303  }
304 }
306 {
307  int i;
308  char msg[40];
309 
310  sprintf(msg, " Session has %d tracks", s->tracks);
311  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
313  msg, 0, 0);
314  for (i = 0; i < s->tracks; i++) {
316  }
317 }
319 {
320  char msg[80];
321 
322  sprintf(msg, " track size %d sectors",
324  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
326  msg, 0, 0);
327 }
328 
329 void burn_track_define_data(struct burn_track *t, int offset, int tail,
330  int pad, int mode)
331 {
332  int type_to_form(int mode, unsigned char *ctladr, int *form);
333  int burn_sector_length(int tracktype);
334  unsigned char ctladr;
335  int form = -1; /* unchanged form will be considered an error too */
336  char msg[80];
337 
338  type_to_form(mode, &ctladr, &form);
339  if (form == -1 || burn_sector_length(mode) <= 0) {
340 
341  sprintf(msg,
342  "Attempt to set track mode to unusable value 0x%X",
343  (unsigned int) mode);
344  libdax_msgs_submit(libdax_messenger, -1, 0x00020115,
346  msg, 0, 0);
347  return;
348  }
349 
350  t->offset = offset;
351  t->pad = pad;
352  t->mode = mode;
353  t->tail = tail;
354 }
355 
356 
357 /* ts A61024 */
359 {
360  if (swap_source_bytes != 0 && swap_source_bytes != 1)
361  return 0;
363  return 1;
364 }
365 
366 
367 /* ts A90911 : API */
368 int burn_track_set_cdxa_conv(struct burn_track *t, int value)
369 {
370  if (value < 0 || value > 1)
371  return 0;
372  t->cdxa_conversion = value;
373  return 1;
374 }
375 
376 
377 void burn_track_set_isrc(struct burn_track *t, char *country, char *owner,
378  unsigned char year, unsigned int serial)
379 {
380  int i;
381 
382  /* ts B11226 */
383  t->isrc.has_isrc = 0;
384 
385  for (i = 0; i < 2; ++i) {
386 
387  /* ts A61008 : This is always true */
388  /* a ssert((country[i] >= '0' || country[i] < '9') &&
389  (country[i] >= 'a' || country[i] < 'z') &&
390  (country[i] >= 'A' || country[i] < 'Z')); */
391  /* ts A61008 : now coordinated with sector.c: char_to_isrc() */
392  if (! ((country[i] >= '0' && country[i] <= '9') ||
393  (country[i] >= 'a' && country[i] <= 'z') ||
394  (country[i] >= 'A' && country[i] <= 'Z') ) )
395  goto is_not_allowed;
396 
397  t->isrc.country[i] = country[i];
398  }
399  for (i = 0; i < 3; ++i) {
400 
401  /* ts A61008 : This is always true */
402  /* a ssert((owner[i] >= '0' || owner[i] < '9') &&
403  (owner[i] >= 'a' || owner[i] < 'z') &&
404  (owner[i] >= 'A' || owner[i] < 'Z')); */
405  /* ts A61008 : now coordinated with sector.c: char_to_isrc() */
406  if (! ((owner[i] >= '0' && owner[i] <= '9') ||
407  (owner[i] >= 'a' && owner[i] <= 'z') ||
408  (owner[i] >= 'A' && owner[i] <= 'Z') ) )
409  goto is_not_allowed;
410 
411  t->isrc.owner[i] = owner[i];
412  }
413 
414  /* ts A61008 */
415  /* a ssert(year <= 99); */
416  if (year > 99)
417  goto is_not_allowed;
418 
419  t->isrc.year = year;
420 
421  /* ts A61008 */
422  /* a ssert(serial <= 99999); */
423  if (serial > 99999)
424  goto is_not_allowed;
425 
426  t->isrc.serial = serial;
427 
428  /* ts A61008 */
429  t->isrc.has_isrc = 1;
430  return;
431 is_not_allowed:;
432  libdax_msgs_submit(libdax_messenger, -1, 0x00020114,
434  "Attempt to set ISRC with bad data", 0, 0);
435  return;
436 }
437 
438 /* ts B11226 API */
439 int burn_track_set_isrc_string(struct burn_track *t, char isrc[13], int flag)
440 {
441  unsigned char year;
442  unsigned int serial = 2000000000;
443 
444  if (strlen(isrc) != 12 ||
445  isrc[5] < '0' || isrc[5] > '9' || isrc[6] < '0' || isrc[6] > '9') {
446  libdax_msgs_submit(libdax_messenger, -1, 0x00020114,
448  "Attempt to set ISRC with bad data", 0, 0);
449  return 0;
450  }
451  year = (isrc[5] - '0') * 10 + (isrc[6] - '0');
452  isrc[12] = 0;
453  sscanf(isrc + 7, "%u", &serial);
454  burn_track_set_isrc(t, isrc, isrc + 2, year, serial);
455  return t->isrc.has_isrc;
456 }
457 
459 {
460  t->isrc.has_isrc = 0;
461 }
462 
463 /* ts B20103 API */
464 int burn_track_set_index(struct burn_track *t, int index_number,
465  unsigned int relative_lba, int flag)
466 {
467  if (index_number < 0 || index_number > 99) {
468  libdax_msgs_submit(libdax_messenger, -1, 0x0002019a,
470  "Bad track index number", 0, 0);
471  return 0;
472  }
473 
474  /* >>> if track size known : check index */;
475 
476  t->index[index_number] = relative_lba;
477  if (index_number >= t->indices)
478  t->indices = index_number + 1;
479  return 1;
480 }
481 
482 /* ts B20103 API */
483 int burn_track_clear_indice(struct burn_track *t, int flag)
484 {
485  int i;
486 
487  for (i = 0; i < 100; i++)
488  t->index[i] = 0x7fffffff;
489  t->indices = 0;
490  return 1;
491 }
492 
493 /* ts B20110 API */
494 int burn_track_set_pregap_size(struct burn_track *t, int size, int flag)
495 {
496  t->pregap2 = (size >= 0);
497  t->pregap2_size = size;
498  return 1;
499 }
500 
501 /* ts B20111 API */
502 int burn_track_set_postgap_size(struct burn_track *t, int size, int flag)
503 {
504  t->postgap = (size >= 0);
505  t->postgap_size = size;
506  return 1;
507 }
508 
509 /* ts B20119: outsourced from burn_track_get_sectors()
510  @param flag bit0= do not add post-gap
511 */
512 int burn_track_get_sectors_2(struct burn_track *t, int flag)
513 {
514  /* ts A70125 : was int */
515  off_t size = 0;
516  int sectors, seclen;
517 
518  seclen = burn_sector_length(t->mode);
519 
520  if (t->cdxa_conversion == 1)
521  /* ts A90911 : will read blocks of 2056 bytes and write 2048 */
522  seclen += 8;
523 
524  if (t->source != NULL) { /* ts A80808 : mending sigsegv */
525  size = t->offset + t->source->get_size(t->source) + t->tail;
526  /* ts B20119 : adding post-gap */
527  if (t->postgap && !(flag & 1))
528  size += t->postgap_size;
529  } else if(t->entry != NULL) {
530  /* ts A80808 : all burn_toc_entry of track starts should now
531  have (extensions_valid & 1), even those from CD.
532  */
533  if (t->entry->extensions_valid & 1)
534  size = ((off_t) t->entry->track_blocks) * (off_t) 2048;
535  }
536  sectors = size / seclen;
537  if (size % seclen)
538  sectors++;
539  return sectors;
540 }
541 
542 
544 {
545  return burn_track_get_sectors_2(t, 0);
546 }
547 
548 /* ts A70125 */
549 int burn_track_set_sectors(struct burn_track *t, int sectors)
550 {
551  off_t size, seclen;
552  int ret;
553 
554  seclen = burn_sector_length(t->mode);
555  size = seclen * (off_t) sectors - (off_t) t->offset - (off_t) t->tail;
556  if (size < 0)
557  return 0;
558  ret = t->source->set_size(t->source, size);
559  t->open_ended = (t->source->get_size(t->source) <= 0);
560  return ret;
561 }
562 
563 
564 /* ts A70218 , API since A70328 */
565 int burn_track_set_size(struct burn_track *t, off_t size)
566 {
567  if (t->source == NULL)
568  return 0;
569  if (t->source->set_size == NULL)
570  return 0;
571  t->open_ended = (size <= 0);
572  return t->source->set_size(t->source, size);
573 }
574 
575 
576 /* ts A70213 */
578 {
580  if (fill_up_media)
581  t->open_ended = 0;
582  return 1;
583 }
584 
585 
586 /* ts A70213 */
587 /**
588  @param flag bit0= force new size even if existing track size is larger
589 */
590 int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag)
591 {
592  int max_sectors, ret = 2;
593  char msg[80];
594 
595  if (t->fill_up_media <= 0)
596  return 2;
597  max_sectors = max_size / 2048;
598  if (burn_track_get_sectors(t) < max_sectors || (flag & 1)) {
599  sprintf(msg, "Setting total track size to %ds (payload %ds)\n",
600  max_sectors & 0x7fffffff,
601  (int) ((t->source->get_size(t->source) / 2048)
602  & 0x7fffffff));
603  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
605  msg, 0, 0);
606  ret = burn_track_set_sectors(t, max_sectors);
607  t->open_ended = 0;
608  }
609  return ret;
610 }
611 
612 
613 /* ts A61031 */
615 {
616  return !!t->open_ended;
617 }
618 
619 
620 /* ts A70218 : API */
621 int burn_track_set_default_size(struct burn_track *t, off_t size)
622 {
623  t->default_size = size;
624  return 1;
625 }
626 
627 
628 /* ts A70218 */
630 {
631  return t->default_size;
632 }
633 
634 
635 /* ts A61101 : API function */
637  off_t *read_bytes, off_t *written_bytes)
638 {
639 /*
640  fprintf(stderr, "libburn_experimental: sizeof(off_t)=%d\n",
641  sizeof(off_t));
642 */
643  *read_bytes = t->sourcecount;
644  *written_bytes = t->writecount;
645  return 1;
646 }
647 
648 /* ts A61031 */
650 {
651  return !!t->track_data_done;
652 }
653 
655 {
656  int size;
657  int seclen;
658 
659  seclen = burn_sector_length(t->mode);
660  size = t->offset + t->source->get_size(t->source) + t->tail;
661  if (size % seclen)
662  return seclen - size % seclen;
663  return 0;
664 }
665 
667 {
668  int sectors = 0, i;
669 
670  for (i = 0; i < s->tracks; i++)
671  sectors += burn_track_get_sectors(s->track[i]);
672  return sectors;
673 }
674 
675 
677 {
678  int sectors = 0, i;
679 
680  for (i = 0; i < d->sessions; i++)
681  sectors += burn_session_get_sectors(d->session[i]);
682  return sectors;
683 }
684 
686 {
687  if (t->entry == NULL)
688  memset(entry, 0, sizeof(struct burn_toc_entry));
689  else
690  memcpy(entry, t->entry, sizeof(struct burn_toc_entry));
691 }
692 
694  struct burn_toc_entry *entry)
695 {
696  if (s->leadout_entry == NULL)
697  memset(entry, 0, sizeof(struct burn_toc_entry));
698  else
699  memcpy(entry, s->leadout_entry, sizeof(struct burn_toc_entry));
700 }
701 
702 struct burn_session **burn_disc_get_sessions(struct burn_disc *d, int *num)
703 {
704 
705 #ifdef Libburn_disc_with_incomplete_sessioN
706 
707  *num = d->sessions - d->incomplete_sessions;
708 
709 #else
710 
711  *num = d->sessions;
712 
713 #endif
714 
715 
716  return d->session;
717 }
718 
719 
720 /* ts B30112 : API */
722 {
723 #ifdef Libburn_disc_with_incomplete_sessioN
724 
725  return d->incomplete_sessions;
726 
727 #else
728 
729  return 0;
730 
731 #endif
732 }
733 
734 
735 struct burn_track **burn_session_get_tracks(struct burn_session *s, int *num)
736 {
737  *num = s->tracks;
738  return s->track;
739 }
740 
741 int burn_track_get_mode(struct burn_track *track)
742 {
743  return track->mode;
744 }
745 
747 {
748  return session->hidefirst;
749 }
750 
751 
752 /* ts A80808 : Enhance CD toc to DVD toc */
753 int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
754 {
755  int sidx= 0, tidx= 0, ret, track_offset, alloc_len = 34;
756  struct burn_toc_entry *entry, *prev_entry= NULL;
757  struct burn_disc *d;
758  /* ts A81126 : ticket 146 : There was a SIGSEGV in here */
759  char *msg_data = NULL, *msg;
760  struct buffer *buf = NULL;
761 
762  d = drive->disc;
763  BURN_ALLOC_MEM(msg_data, char, 321);
764  BURN_ALLOC_MEM(buf, struct buffer, 1);
765  strcpy(msg_data,
766  "Damaged CD table-of-content detected and truncated.");
767  strcat(msg_data, " In burn_disc_cd_toc_extensions: ");
768  msg = msg_data + strlen(msg_data);
769  if (d->session == NULL) {
770  strcpy(msg, "d->session == NULL");
771  goto failure;
772  }
773  if (d->sessions <= 0) {
774  ret = 1;
775  goto ex;
776  }
777 
778  for (sidx = 0; sidx < d->sessions; sidx++) {
779  track_offset = burn_session_get_start_tno(d->session[sidx], 0);
780  if (track_offset <= 0)
781  track_offset = 1;
782  if (d->session[sidx] == NULL) {
783  sprintf(msg, "d->session[%d of %d] == NULL",
784  sidx, d->sessions);
785  goto failure;
786  }
787  if (d->session[sidx]->track == NULL) {
788  sprintf(msg, "d->session[%d of %d]->track == NULL",
789  sidx, d->sessions);
790  goto failure;
791  }
792  if (d->session[sidx]->leadout_entry == NULL) {
793  sprintf(msg,
794  " Session %d of %d: Leadout entry missing.",
795  sidx, d->sessions);
796  goto failure;
797  }
798  for (tidx = 0; tidx < d->session[sidx]->tracks + 1; tidx++) {
799  if (tidx < d->session[sidx]->tracks) {
800  if (d->session[sidx]->track[tidx] == NULL) {
801  sprintf(msg,
802  "d->session[%d of %d]->track[%d of %d] == NULL",
803  sidx, d->sessions, tidx, d->session[sidx]->tracks);
804  goto failure;
805  }
806  entry = d->session[sidx]->track[tidx]->entry;
807  if (entry == NULL) {
808  sprintf(msg,
809  "session %d of %d, track %d of %d, entry == NULL",
810  sidx, d->sessions, tidx,
811  d->session[sidx]->tracks);
812  goto failure;
813  }
814  } else
815  entry = d->session[sidx]->leadout_entry;
816  entry->session_msb = 0;
817  entry->point_msb = 0;
818  entry->start_lba = burn_msf_to_lba(entry->pmin,
819  entry->psec, entry->pframe);
820  if (tidx > 0) {
821  prev_entry->track_blocks =
822  entry->start_lba
823  - prev_entry->start_lba;
824 
825  /* The drive might know size restrictions
826  like pre-gaps
827  */
828  ret = mmc_read_track_info(drive,
829  tidx - 1 + track_offset, buf,
830  alloc_len);
831  if (ret > 0) {
832  ret = mmc_four_char_to_int(
833  buf->data + 24);
834  if (ret < prev_entry->track_blocks &&
835  ((!drive->current_is_cd_profile) ||
836  ret < prev_entry->track_blocks - 2))
837  prev_entry->track_blocks = ret;
838  }
839  prev_entry->extensions_valid |= 1;
840  }
841  if (tidx == d->session[sidx]->tracks) {
842  entry->session_msb = 0;
843  entry->point_msb = 0;
844  entry->track_blocks = 0;
845  entry->extensions_valid |= 1;
846  }
847  prev_entry = entry;
848  }
849  }
850  {ret = 1; goto ex;}
851 failure:
852  libdax_msgs_submit(libdax_messenger, -1, 0x0002015f,
854  d->sessions= sidx;
855  ret = 0;
856 ex:;
857  BURN_FREE_MEM(buf);
858  BURN_FREE_MEM(msg_data);
859  return ret;
860 }
861 
862 
863 /* ts B20107 API */
864 int burn_session_set_start_tno(struct burn_session *session, int tno, int flag)
865 {
866  if (tno < 1 || tno > 99) {
867  libdax_msgs_submit(libdax_messenger, -1, 0x0002019b,
869  "CD start track number exceeds range of 1 to 99",
870  0, 0);
871  return 0;
872  }
873  if (tno + session->tracks - 1 > 99) {
874  libdax_msgs_submit(libdax_messenger, -1, 0x0002019b,
876  "CD track number exceeds 99", 0, 0);
877  return 0;
878  }
879  session->firsttrack = tno;
880  return 1;
881 }
882 
883 
884 /* ts B20108 API */
885 int burn_session_get_start_tno(struct burn_session *session, int flag)
886 {
887  return (int) session->firsttrack;
888 }
889 
890 
892 {
893  struct burn_cdtext *t;
894  int i;
895 
896  t = burn_alloc_mem(sizeof(struct burn_cdtext), 1, 0);
897  if (t == NULL)
898  return NULL;
899  for(i = 0; i < Libburn_pack_num_typeS; i ++) {
900  t->payload[i] = NULL;
901  t->length[i] = 0;
902  }
903  return t;
904 }
905 
906 
907 void burn_cdtext_free(struct burn_cdtext **cdtext)
908 {
909  struct burn_cdtext *t;
910  int i;
911 
912  t = *cdtext;
913  if (t == NULL)
914  return;
915  for (i = 0; i < Libburn_pack_num_typeS; i++)
916  if (t->payload[i] != NULL)
917  free(t->payload[i]);
918  free(t);
919 }
920 
921 
922 static int burn_cdtext_name_to_type(char *pack_type_name)
923 {
924  int i, j;
925  static char *pack_type_names[] = {
927  };
928 
929  for (i = 0; i < Libburn_pack_num_typeS; i++) {
930  if (pack_type_names[i][0] == 0)
931  continue;
932  for (j = 0; pack_type_names[i][j]; j++)
933  if (pack_type_names[i][j] != pack_type_name[j] &&
934  tolower(pack_type_names[i][j]) !=
935  pack_type_name[j])
936  break;
937  if (pack_type_names[i][j] == 0)
938  return Libburn_pack_type_basE + i;
939  }
940  return -1;
941 }
942 
943 
944 /* @param flag bit0= double byte characters
945 */
946 static int burn_cdtext_set(struct burn_cdtext **cdtext,
947  int pack_type, char *pack_type_name,
948  unsigned char *payload, int length, int flag)
949 {
950  int i;
951  struct burn_cdtext *t;
952 
953  if (pack_type_name != NULL)
954  if (pack_type_name[0])
955  pack_type = burn_cdtext_name_to_type(pack_type_name);
956  if (pack_type < Libburn_pack_type_basE ||
958  libdax_msgs_submit(libdax_messenger, -1, 0x0002018c,
960  "CD-TEXT pack type out of range", 0, 0);
961  return 0;
962  }
963  t = *cdtext;
964  if (t == NULL) {
965  *cdtext = t = burn_cdtext_create();
966  if (t == NULL)
967  return -1;
968  }
969  i = pack_type - Libburn_pack_type_basE;
970  if (t->payload[i] != NULL)
971  free(t->payload[i]);
972  t->payload[i] = burn_alloc_mem((size_t) length, 1, 0);
973  if (t->payload[i] == NULL)
974  return -1;
975  memcpy(t->payload[i], payload, length);
976  t->length[i] = length;
977  t->flags = (t->flags & ~(1 << i)) | (flag & (1 << i));
978  return 1;
979 }
980 
981 
982 /* @return 1=single byte char , 2= double byte char , <=0 error */
983 static int burn_cdtext_get(struct burn_cdtext *t, int pack_type,
984  char *pack_type_name,
985  unsigned char **payload, int *length, int flag)
986 {
987  if (pack_type_name != NULL)
988  if (pack_type_name[0])
989  pack_type = burn_cdtext_name_to_type(pack_type_name);
990  if (pack_type < Libburn_pack_type_basE ||
992  libdax_msgs_submit(libdax_messenger, -1, 0x0002018c,
994  "CD-TEXT pack type out of range", 0, 0);
995  return 0;
996  }
997  *payload = t->payload[pack_type - Libburn_pack_type_basE];
998  *length = t->length[pack_type - Libburn_pack_type_basE];
999  return 1 + ((t->flags >> (pack_type - Libburn_pack_type_basE)) & 1);
1000 }
1001 
1002 
1003 static int burn_cdtext_check_blockno(int block)
1004 {
1005  if (block < 0 || block > 7) {
1006  libdax_msgs_submit(libdax_messenger, -1, 0x0002018d,
1008  "CD-TEXT block number out of range", 0, 0);
1009  return 0;
1010  }
1011  return 1;
1012 }
1013 
1014 
1015 /* ts B11206 API */
1016 /* @param flag bit0= double byte characters
1017 */
1018 int burn_track_set_cdtext(struct burn_track *t, int block,
1019  int pack_type, char *pack_type_name,
1020  unsigned char *payload, int length, int flag)
1021 {
1022  int ret;
1023 
1024  if (burn_cdtext_check_blockno(block) <= 0)
1025  return 0;
1026  ret = burn_cdtext_set(&(t->cdtext[block]), pack_type, pack_type_name,
1027  payload, length, flag & 1);
1028  return ret;
1029 }
1030 
1031 
1032 /* ts B11206 API */
1033 /* @return 1=single byte char , 2= double byte char , <=0 error */
1034 int burn_track_get_cdtext(struct burn_track *t, int block,
1035  int pack_type, char *pack_type_name,
1036  unsigned char **payload, int *length, int flag)
1037 {
1038  int ret;
1039 
1040  if (burn_cdtext_check_blockno(block) <= 0)
1041  return 0;
1042  if (t->cdtext[block] == NULL) {
1043  *payload = NULL;
1044  *length = 0;
1045  return 1;
1046  }
1047  ret = burn_cdtext_get(t->cdtext[block], pack_type, pack_type_name,
1048  payload, length, 0);
1049  return ret;
1050 }
1051 
1052 
1053 /* ts B11206 API */
1054 int burn_track_dispose_cdtext(struct burn_track *t, int block)
1055 {
1056  int i;
1057 
1058  if (block == -1) {
1059  for (i= 0; i < 8; i++)
1060  burn_cdtext_free(&(t->cdtext[i]));
1061  return 1;
1062  }
1063  if (burn_cdtext_check_blockno(block) <= 0)
1064  return 0;
1065  burn_cdtext_free(&(t->cdtext[0]));
1066  return 1;
1067 }
1068 
1069 
1070 /* ts B11206 API */
1071 /* @param flag bit0= double byte characters
1072 */
1073 int burn_session_set_cdtext(struct burn_session *s, int block,
1074  int pack_type, char *pack_type_name,
1075  unsigned char *payload, int length, int flag)
1076 {
1077  int ret;
1078 
1079  if (burn_cdtext_check_blockno(block) <= 0)
1080  return 0;
1081  ret = burn_cdtext_set(&(s->cdtext[block]), pack_type, pack_type_name,
1082  payload, length, flag & 1);
1083  return ret;
1084 }
1085 
1086 
1087 /* ts B11206 API */
1088 /* @return 1=single byte char , 2= double byte char , <=0 error */
1089 int burn_session_get_cdtext(struct burn_session *s, int block,
1090  int pack_type, char *pack_type_name,
1091  unsigned char **payload, int *length, int flag)
1092 {
1093  int ret;
1094 
1095  if (burn_cdtext_check_blockno(block) <= 0)
1096  return 0;
1097 
1098  if (s->cdtext[block] == NULL) {
1099  *payload = NULL;
1100  *length = 0;
1101  return 1;
1102  }
1103  ret = burn_cdtext_get(s->cdtext[block], pack_type, pack_type_name,
1104  payload, length, 0);
1105  return ret;
1106 }
1107 
1108 
1109 /* ts B11206 API */
1111  int char_codes[8], int copyrights[8],
1112  int block_languages[8], int flag)
1113 {
1114  int i;
1115 
1116  for (i = 0; i < 8; i++) {
1117  if (char_codes[i] >= 0 && char_codes[i] <= 255)
1118  s->cdtext_char_code[i] = char_codes[i];
1119  if (copyrights[i] >= 0 && copyrights[i] <= 255)
1120  s->cdtext_copyright[i] = copyrights[i];
1121  if (block_languages[i] >= 0 && block_languages[i] <= 255)
1122  s->cdtext_language[i] = block_languages[i];
1123  }
1124  return 1;
1125 }
1126 
1127 
1128 /* ts B11206 API */
1130  int char_codes[8], int copyrights[8],
1131  int block_languages[8], int flag)
1132 {
1133  int i;
1134 
1135  for (i = 0; i < 8; i++) {
1136  char_codes[i] = s->cdtext_char_code[i];
1137  copyrights[i] = s->cdtext_copyright[i];
1138  block_languages[i]= s->cdtext_language[i];
1139  }
1140  return 1;
1141 }
1142 
1143 
1144 /* ts B11206 API */
1145 int burn_session_dispose_cdtext(struct burn_session *s, int block)
1146 {
1147  int i;
1148 
1149  if (block == -1) {
1150  for (i= 0; i < 8; i++) {
1152  s->cdtext_char_code[i] = 0x01; /* 7 bit ASCII */
1153  s->cdtext_copyright[i] = 0;
1154  s->cdtext_language[i] = 0;
1155  }
1156  return 1;
1157  }
1158  if (burn_cdtext_check_blockno(block) <= 0)
1159  return 0;
1160  burn_cdtext_free(&(s->cdtext[block]));
1161  s->cdtext_language[block] = 0x09; /* english */
1162  return 1;
1163 }
1164 
1165 
1166 /* --------------------- Reading CDRWIN cue sheet files ----------------- */
1167 
1168 
1170  char *cdtextfile;
1193  int flags;
1194 };
1195 
1196 
1197 static int cue_crs_new(struct burn_cue_file_cursor **reply, int flag)
1198 {
1199  int ret;
1200  struct burn_cue_file_cursor *crs;
1201 
1202  BURN_ALLOC_MEM(crs, struct burn_cue_file_cursor, 1);
1203  crs->cdtextfile = NULL;
1204  crs->source_file = NULL;
1205  crs->source_size = -1;
1206  crs->file_source = NULL;
1207  crs->fifo_size = 0;
1208  crs->fifo = NULL;
1209  crs->swap_audio_bytes = 0;
1210  crs->no_cdtext = 0;
1211  crs->no_catalog_isrc = 0;
1212  crs->start_track_no = 1;
1213  crs->offst_source = NULL;
1214  crs->current_file_ba = -1000000000;
1215  crs->current_index_ba = -1000000000;
1216  crs->prev_track = NULL;
1217  crs->prev_file_ba = -1000000000;
1218  crs->prev_block_size = 0;
1219  crs->track = NULL;
1220  crs->track_no = 0;
1221  crs->track_current_index = -1;
1222  crs->track_has_source = 0;
1223  crs->block_size = 0;
1224  crs->block_size_locked = 0;
1225  crs->track_mode = 0;
1226  crs->flags = 0;
1227 
1228  *reply = crs;
1229  ret = 1;
1230 ex:;
1231  return ret;
1232 }
1233 
1234 
1235 static int cue_crs_destroy(struct burn_cue_file_cursor **victim, int flag)
1236 {
1237  struct burn_cue_file_cursor *crs;
1238 
1239  if (*victim == NULL)
1240  return 2;
1241  crs = *victim;
1242  if (crs->cdtextfile != NULL)
1243  free(crs->cdtextfile);
1244  if (crs->source_file != NULL)
1245  free(crs->source_file);
1246  if (crs->file_source != NULL)
1248  if (crs->fifo != NULL)
1249  burn_source_free(crs->fifo);
1250  if (crs->offst_source != NULL)
1252  if (crs->prev_track != NULL)
1254  if (crs->track != NULL)
1255  burn_track_free(crs->track);
1256  BURN_FREE_MEM(crs);
1257  *victim = NULL;
1258  return 1;
1259 }
1260 
1261 
1262 static char *cue_unquote_text(char *text, int flag)
1263 {
1264  char *ept, *spt;
1265 
1266  spt = text;
1267  for (ept = text + strlen(text); ept > text; ept--)
1268  if (*(ept - 1) != 32 && *(ept - 1) != 9)
1269  break;
1270  if (text[0] == '"') {
1271  spt = text + 1;
1272  if (ept > spt)
1273  if (*(ept - 1) == '"')
1274  ept--;
1275  }
1276  *ept = 0;
1277  return spt;
1278 }
1279 
1280 
1281 /* @param flag bit0= insist in having a track object
1282  bit1= remove quotation marks if present
1283 */
1284 static int cue_set_cdtext(struct burn_session *session,
1285  struct burn_track *track, int pack_type, char *text,
1286  struct burn_cue_file_cursor *crs, int flag)
1287 {
1288  int ret;
1289  char *payload;
1290 
1291  if (crs->no_cdtext == 1) {
1292  libdax_msgs_submit(libdax_messenger, -1, 0x00020195,
1294  "In cue sheet file: Being set to ignore all CD-TEXT aspects",
1295  0, 0);
1296  crs->no_cdtext = 2;
1297  }
1298  if (crs->no_cdtext)
1299  return 2;
1300  if ((flag & 1) && track == NULL) {
1301  libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
1303  "Track attribute set before first track in cue sheet file",
1304  0, 0);
1305  ret = 0; goto ex;
1306  }
1307  if (flag & 2)
1308  payload = cue_unquote_text(text, 0);
1309  else
1310  payload = text;
1311  if (track != NULL) {
1312  ret = burn_track_set_cdtext(track, 0, pack_type, "",
1313  (unsigned char *) payload,
1314  strlen(payload) + 1, 0);
1315  } else {
1316  ret = burn_session_set_cdtext(session, 0, pack_type, "",
1317  (unsigned char *) payload,
1318  strlen(payload) + 1, 0);
1319  }
1320 ex:;
1321  return ret;
1322 }
1323 
1324 
1325 static int cue_attach_track(struct burn_session *session,
1326  struct burn_cue_file_cursor *crs, int flag)
1327 {
1328  int ret;
1329 
1330  if (crs->track == NULL)
1331  return 2;
1332 
1333  if (!crs->track_has_source) {
1334  libdax_msgs_submit(libdax_messenger, -1, 0x00020194,
1336  "In cue sheet file: TRACK without INDEX 01", 0, 0);
1337  return 0;
1338  }
1339  if (crs->track_current_index < 1) {
1340  libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
1342  "No INDEX 01 defined for last TRACK in cue sheet file",
1343  0, 0);
1344  return 0;
1345  }
1346  if (session->tracks == 0) {
1347  crs->start_track_no = crs->track_no;
1348  ret = burn_session_set_start_tno(session, crs->track_no, 0);
1349  if (ret <= 0)
1350  return ret;
1351  }
1352  if (session->tracks + crs->start_track_no - 1 > 99) {
1353  libdax_msgs_submit(libdax_messenger, -1, 0x0002019b,
1355  "CD track number exceeds 99",
1356  0, 0);
1357  return 0;
1358  }
1359  ret = burn_session_add_track(session, crs->track, BURN_POS_END);
1360  if (ret <= 0)
1361  return ret;
1362  if (crs->prev_track != NULL)
1363  burn_track_free(crs->prev_track); /* release reference */
1364  crs->prev_track = crs->track;
1365  crs->prev_file_ba = crs->current_file_ba;
1366  crs->prev_block_size = crs->block_size;
1367  crs->track = NULL;
1368  crs->track_current_index = -1;
1369  crs->track_has_source = 0;
1370  crs->current_file_ba = -1;
1371  crs->current_index_ba = -1;
1372  if (!crs->block_size_locked)
1373  crs->block_size = 0;
1374  return 1;
1375 }
1376 
1377 
1378 /* @param flag bit0= do not alter the content of *payload
1379  do not change *payload
1380 */
1381 static int cue_read_number(char **payload, int *number, int flag)
1382 {
1383  int ret, at_end = 0;
1384  char *apt, *msg = NULL;
1385 
1386  for(apt = *payload; *apt != 0 && *apt != 32 && *apt != 9; apt++);
1387  if (*apt == 0)
1388  at_end = 1;
1389  else if (!(flag & 1))
1390  *apt = 0;
1391  ret = sscanf(*payload, "%d", number);
1392  if (ret != 1) {
1393  BURN_ALLOC_MEM(msg, char, 4096);
1394  sprintf(msg,
1395  "Unsuitable number in cue sheet file: '%.4000s'",
1396  *payload);
1397  libdax_msgs_submit(libdax_messenger, -1, 0x00020194,
1399  burn_printify(msg), 0, 0);
1400  ret = 0; goto ex;
1401  }
1402  /* Find start of next argument */
1403  if (!at_end)
1404  for (apt++; *apt == 32 || *apt == 9; apt++);
1405  if (!(flag & 1))
1406  *payload = apt;
1407 
1408  ret = 1;
1409 ex:
1410  BURN_FREE_MEM(msg);
1411  return ret;
1412 }
1413 
1414 
1415 /* @param flag bit0-7: desired type : 0=any , 1=.wav
1416 */
1417 static int cue_open_audioxtr(char *path, struct burn_cue_file_cursor *crs,
1418  int *fd, int flag)
1419 {
1420  struct libdax_audioxtr *xtr= NULL;
1421  char *fmt, *fmt_info;
1422  int ret, num_channels, sample_rate, bits_per_sample, msb_first;
1423  char *msg = NULL;
1424 
1425  BURN_ALLOC_MEM(msg, char, 4096);
1426 
1427  ret= libdax_audioxtr_new(&xtr, path, 0);
1428  if (ret <= 0)
1429  goto ex;
1430  libdax_audioxtr_get_id(xtr, &fmt, &fmt_info, &num_channels,
1431  &sample_rate, &bits_per_sample, &msb_first, 0);
1432  if ((flag & 255) == 1) {
1433  if (strcmp(fmt, ".wav") != 0) {
1434  sprintf(msg,
1435  "In cue sheet: Not recognized as WAVE : FILE '%.4000s'",
1436  path);
1437  libdax_msgs_submit(libdax_messenger, -1, 0x00020193,
1439  burn_printify(msg), 0, 0);
1440  ret = 0; goto ex;
1441  }
1442  }
1443  ret = libdax_audioxtr_get_size(xtr, &(crs->source_size), 0);
1444  if (ret <= 0) {
1445  sprintf(msg,
1446  "In cue sheet: Cannot get payload size of FILE '%.4000s'",
1447  path);
1448  libdax_msgs_submit(libdax_messenger, -1, 0x00020193,
1450  burn_printify(msg), 0, 0);
1451  ret = 0; goto ex;
1452  }
1453  ret = libdax_audioxtr_detach_fd(xtr, fd, 0);
1454  if (ret <= 0) {
1455  sprintf(msg,
1456  "In cue sheet: Cannot represent payload as plain fd: FILE '%.4000s'",
1457  path);
1458  libdax_msgs_submit(libdax_messenger, -1, 0x00020193,
1460  burn_printify(msg), 0, 0);
1461  ret = 0; goto ex;
1462  }
1463  crs->swap_audio_bytes = (msb_first == 1);
1464 
1465  ret = 1;
1466 ex:
1467  if (xtr != NULL)
1468  libdax_audioxtr_destroy(&xtr, 0);
1469  BURN_FREE_MEM(msg);
1470  return ret;
1471 }
1472 
1473 
1474 /* @param flag bit0-7: desired type : 0=any , 1=.wav
1475  bit8= open by libdax_audioxtr functions
1476 
1477 */
1478 static int cue_create_file_source(char *path, struct burn_cue_file_cursor *crs,
1479  int flag)
1480 {
1481  int fd, ret;
1482  char *msg = NULL;
1483 
1484  BURN_ALLOC_MEM(msg, char, 4096);
1485 
1486  if (flag & 256) {
1487  ret = cue_open_audioxtr(path, crs, &fd, flag & 255);
1488  if (ret <= 0)
1489  goto ex;
1490  } else {
1491  fd = open(path, O_RDONLY | O_BINARY);
1492  if (fd == -1) {
1493  sprintf(msg,
1494  "In cue sheet: Cannot open FILE '%.4000s'",
1495  path);
1496  libdax_msgs_submit(libdax_messenger, -1, 0x00020193,
1498  burn_printify(msg), errno, 0);
1499  ret = 0; goto ex;
1500  }
1501  }
1502  crs->file_source = burn_fd_source_new(fd, -1, crs->source_size);
1503  if (crs->file_source == NULL) {
1504  ret = -1; goto ex;
1505  }
1506 
1507  ret = 1;
1508 ex:;
1509  BURN_FREE_MEM(msg);
1510  return ret;
1511 }
1512 
1513 
1514 static int cue_read_timepoint_lba(char *apt, char *purpose, int *file_ba,
1515  int flag)
1516 {
1517  int ret, minute, second, frame;
1518  char *msg = NULL, msf[3], *msf_pt;
1519 
1520  BURN_ALLOC_MEM(msg, char, 4096);
1521  if (strlen(apt) < 8) {
1522 no_time_point:;
1523  sprintf(msg,
1524  "Inappropriate cue sheet file %s '%.4000s'",
1525  purpose, apt);
1526  libdax_msgs_submit(libdax_messenger, -1, 0x00020194,
1528  burn_printify(msg), 0, 0);
1529  ret = 0; goto ex;
1530  }
1531  if (apt[2] != ':' || apt[5] != ':' ||
1532  (apt[8] != 0 && apt[8] != 32 && apt[8] != 9))
1533  goto no_time_point;
1534  msf[2] = 0;
1535  msf_pt = msf;
1536  strncpy(msf, apt, 2);
1537  ret = cue_read_number(&msf_pt, &minute, 1);
1538  if (ret <= 0)
1539  goto ex;
1540  strncpy(msf, apt + 3, 2);
1541  ret = cue_read_number(&msf_pt, &second, 1);
1542  if (ret <= 0)
1543  goto ex;
1544  strncpy(msf, apt + 6, 2);
1545  ret = cue_read_number(&msf_pt, &frame, 1);
1546  if (ret <= 0)
1547  goto ex;
1548 
1549  *file_ba = ((minute * 60) + second ) * 75 + frame;
1550  ret = 1;
1551 ex:;
1552  BURN_FREE_MEM(msg);
1553  return ret;
1554 }
1555 
1556 static int cue_check_for_track(struct burn_cue_file_cursor *crs, char *cmd,
1557  int flag)
1558 {
1559  int ret;
1560  char *msg = NULL;
1561 
1562  if (crs->track == NULL) {
1563  BURN_ALLOC_MEM(msg, char, 4096);
1564  sprintf(msg, "In cue sheet file: %s found before TRACK",
1565  cmd);
1566  libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
1568  msg, 0, 0);
1569  ret = 0; goto ex;
1570  }
1571  ret = 1;
1572 ex:;
1573  BURN_FREE_MEM(msg);
1574  return ret;
1575 }
1576 
1577 
1578 static int cue_interpret_line(struct burn_session *session, char *line,
1579  struct burn_cue_file_cursor *crs, int flag)
1580 {
1581  int ret, mode, index_no, file_ba, chunks;
1582  int block_size, step, audio_xtr = 0;
1583  off_t size;
1584  char *cmd, *apt, *msg = NULL, *cpt, *filetype;
1585  struct burn_source *src, *inp_src;
1586  enum burn_source_status source_status;
1587  struct stat stbuf;
1588 
1589  BURN_ALLOC_MEM(msg, char, 4096);
1590 
1591  if (line[0] == 0 || line[0] == '#') {
1592  ret = 1; goto ex;
1593  }
1594 
1595  for (cmd = line; *cmd == 32 || *cmd == 9; cmd++);
1596  for(apt = cmd; *apt != 0 && *apt != 32 && *apt != 9; apt++);
1597  if (*apt != 0) {
1598  *apt = 0;
1599  for (apt++; *apt == 32 || *apt == 9; apt++);
1600  }
1601 
1602  if (strcmp(cmd, "ARRANGER") == 0) {
1603  ret = cue_set_cdtext(session, crs->track, 0x84, apt, crs, 2);
1604  if (ret <= 0)
1605  goto ex;
1606 
1607  } else if (strcmp(cmd, "CATALOG") == 0) {
1608  for (cpt = apt; (cpt - apt) < 13 && *cpt == (*cpt & 0x7f);
1609  cpt++);
1610  if ((cpt - apt) < 13) {
1611  libdax_msgs_submit(libdax_messenger, -1, 0x00020194,
1613  "In cue sheet file: Inappropriate content of CATALOG",
1614  0, 0);
1615  ret = 0; goto ex;
1616  }
1617  ret = cue_set_cdtext(session, NULL, 0x8e, apt, crs, 0);
1618  if (ret <= 0)
1619  goto ex;
1620  if (!crs->no_catalog_isrc) {
1621  memcpy(session->mediacatalog, apt, 13);
1622  session->mediacatalog[13] = 0;
1623  }
1624 
1625  } else if (strcmp(cmd, "CDTEXTFILE") == 0) {
1626  if (crs->no_cdtext) {
1627  ret = 1; goto ex;
1628  }
1629  apt = cue_unquote_text(apt, 0);
1630  if (crs->cdtextfile != NULL)
1631  free(crs->cdtextfile);
1632  crs->cdtextfile = strdup(apt);
1633  if (crs->cdtextfile == NULL) {
1634 out_of_mem:;
1635  libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
1637  "Out of virtual memory", 0, 0);
1638  ret = -1; goto ex;
1639  }
1640 
1641  } else if (strcmp(cmd, "COMPOSER") == 0) {
1642  ret = cue_set_cdtext(session, crs->track, 0x83, apt, crs, 2);
1643  if (ret <= 0)
1644  goto ex;
1645 
1646  } else if (strcmp(cmd, "FILE") == 0) {
1647  if (crs->file_source != NULL) {
1648  libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
1650  "In cue sheet file: Multiple occurrences of FILE",
1651  0, 0);
1652  ret = 0; goto ex;
1653  }
1654  /* Obtain type */
1655  for (cpt = apt + (strlen(apt) - 1);
1656  cpt > apt && (*cpt == 32 || *cpt == 9); cpt--);
1657  cpt[1] = 0;
1658  for (; cpt > apt && *cpt != 32 && *cpt != 9; cpt--);
1659  if (cpt <= apt) {
1660  libdax_msgs_submit(libdax_messenger, -1, 0x00020194,
1662  "In cue sheet file: FILE without type word",
1663  0, 0);
1664  ret = 0; goto ex;
1665  }
1666  *cpt = 0;
1667  filetype = cpt + 1;
1668  if (strcmp(filetype, "BINARY") == 0) {
1669  crs->swap_audio_bytes = 0;
1670  } else if (strcmp(filetype, "MOTOROLA") == 0) {
1671  crs->swap_audio_bytes = 1;
1672  } else if (strcmp(filetype, "WAVE") == 0) {
1673  audio_xtr = 0x101;
1674  } else {
1675  sprintf(msg,
1676  "In cue sheet file: Unsupported FILE type '%.4000s'",
1677  filetype);
1678  libdax_msgs_submit(libdax_messenger, -1, 0x00020197,
1680  burn_printify(msg), 0, 0);
1681  ret = 0; goto ex;
1682  }
1683 
1684  apt = cue_unquote_text(apt, 0);
1685  if (*apt == 0)
1686  ret = -1;
1687  else
1688  ret = stat(apt, &stbuf);
1689  if (ret == -1) {
1690 not_usable_file:;
1691  sprintf(msg,
1692  "In cue sheet file: Unusable FILE '%.4000s'",
1693  apt);
1694  libdax_msgs_submit(libdax_messenger, -1, 0x00020194,
1696  burn_printify(msg), 0, 0);
1697  ret = 0; goto ex;
1698  }
1699  if (!S_ISREG(stbuf.st_mode))
1700  goto not_usable_file;
1701  crs->source_size = stbuf.st_size;
1702  if (crs->source_file != NULL)
1703  free(crs->source_file);
1704  crs->source_file = strdup(apt);
1705  if (crs->source_file == NULL)
1706  goto out_of_mem;
1707  ret = cue_create_file_source(apt, crs, audio_xtr);
1708  if (ret <= 0)
1709  goto ex;
1710 
1711  } else if (strcmp(cmd, "FLAGS") == 0) {
1712  ret = cue_check_for_track(crs, cmd, 0);
1713  if (ret <= 0)
1714  goto ex;
1715  while (*apt) {
1716  if (strncmp(apt, "DCP", 3) == 0) {
1717  crs->track_mode |= BURN_COPY;
1718  step = 3;
1719  } else if (strncmp(apt, "4CH", 3) == 0) {
1720  crs->track_mode |= BURN_4CH;
1721  step = 3;
1722  } else if (strncmp(apt, "PRE", 3) == 0) {
1723  crs->track_mode |= BURN_PREEMPHASIS;
1724  step = 3;
1725  } else if (strncmp(apt, "SCMS", 4) == 0) {
1726  crs->track_mode |= BURN_SCMS;
1727  step = 4;
1728  } else {
1729 bad_flags:;
1730  for (cpt = apt;
1731  *cpt != 32 && *cpt != 9 && *cpt != 0; cpt++);
1732  *cpt = 0;
1733  sprintf(msg,
1734  "In cue sheet file: Unknown FLAGS option '%.4000s'",
1735  apt);
1737  0x00020194,
1740  burn_printify(msg), 0, 0);
1741  ret = 0; goto ex;
1742  }
1743 
1744  /* Look for start of next word */
1745  if (apt[step] != 0 && apt[step] != 32 &&
1746  apt[step] != 9)
1747  goto bad_flags;
1748  for (apt += step; *apt == 32 || *apt == 9; apt++);
1749  }
1750  burn_track_define_data(crs->track, 0, 0, 1, crs->track_mode);
1751 
1752  } else if (strcmp(cmd, "INDEX") == 0) {
1753  ret = cue_check_for_track(crs, cmd, 0);
1754  if (ret <= 0)
1755  goto ex;
1756  ret = cue_read_number(&apt, &index_no, 0);
1757  if (ret <= 0)
1758  goto ex;
1759  ret = cue_read_timepoint_lba(apt, "index time point",
1760  &file_ba, 0);
1761  if (ret <= 0)
1762  goto ex;
1763  if (file_ba < crs->prev_file_ba) {
1764 overlapping_ba:;
1765  libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
1767  "Backward INDEX address in cue sheet file",
1768  0, 0);
1769  ret = 0; goto ex;
1770  }
1771  if (file_ba < crs->current_index_ba)
1772  goto overlapping_ba;
1773  if (crs->prev_track != NULL && crs->track_current_index < 0) {
1774  size = (file_ba - crs->prev_file_ba) *
1775  crs->prev_block_size;
1776  if (size <= 0)
1777  goto overlapping_ba;
1778  burn_track_set_size(crs->prev_track, size);
1779  }
1780  if (crs->track_current_index + 1 != index_no &&
1781  !(crs->track_current_index < 0 && index_no <= 1)) {
1782  libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
1784  "Unacceptable INDEX number in cue sheet file",
1785  0, 0);
1786  ret = 0; goto ex;
1787  }
1788  crs->track_current_index = index_no;
1789 
1790  if (crs->current_file_ba < 0)
1791  crs->current_file_ba = file_ba;
1792  crs->current_index_ba = file_ba;
1793 
1794  /* Set index address relative to track source start */
1795  ret = burn_track_set_index(crs->track, index_no,
1796  file_ba - crs->current_file_ba, 0);
1797  if (ret <= 0)
1798  goto ex;
1799 
1800  if (crs->track_has_source) {
1801  ret = 1; goto ex;
1802  }
1803 
1804  if (crs->block_size_locked && crs->fifo == NULL &&
1805  crs->fifo_size > 0) {
1806  /* Now that the block size is known from TRACK:
1807  Create fifo and use it for creating the offset
1808  sources. This will fixate the block size to one
1809  common value.
1810  */
1811  chunks = crs->fifo_size / crs->block_size +
1812  !!(crs->fifo_size % crs->block_size);
1813  if (chunks < 4)
1814  chunks = 4;
1816  crs->block_size, chunks, 0);
1817  if (crs->fifo == NULL) {
1818  ret = -1; goto ex;
1819  }
1820  }
1821  if (crs->fifo != NULL)
1822  inp_src = crs->fifo;
1823  else
1824  inp_src = crs->file_source;
1825  src = burn_offst_source_new(inp_src, crs->offst_source,
1826  (off_t) (file_ba * crs->block_size), (off_t) 0, 1);
1827  if (src == NULL)
1828  goto out_of_mem;
1829 
1830  /* >>> Alternative to above fifo creation:
1831  Create a fifo for each track track.
1832  This will be necessary if mixed-mode sessions get supporded.
1833  */;
1834 
1835  source_status = burn_track_set_source(crs->track, src);
1836  if (source_status != BURN_SOURCE_OK) {
1837  ret = -1; goto ex;
1838  }
1839 
1840  /* Switch current source in crs */
1841  if (crs->offst_source != NULL)
1843  crs->offst_source = src;
1844  crs->track_has_source = 1;
1845 
1846  } else if (strcmp(cmd, "ISRC") == 0) {
1847  ret = cue_check_for_track(crs, cmd, 0);
1848  if (ret <= 0)
1849  goto ex;
1850  ret = cue_set_cdtext(session, crs->track, 0x8e, apt, crs,
1851  1 | 2);
1852  if (ret <= 0)
1853  goto ex;
1854  if (!crs->no_catalog_isrc) {
1855  ret = burn_track_set_isrc_string(crs->track, apt, 0);
1856  if (ret <= 0)
1857  goto ex;
1858  }
1859 
1860  } else if (strcmp(cmd, "MESSAGE") == 0) {
1861  ret = cue_set_cdtext(session, crs->track, 0x85, apt, crs, 2);
1862  if (ret <= 0)
1863  goto ex;
1864 
1865  } else if (strcmp(cmd, "PERFORMER") == 0) {
1866  ret = cue_set_cdtext(session, crs->track, 0x81, apt, crs, 2);
1867  if (ret <= 0)
1868  goto ex;
1869 
1870  } else if (strcmp(cmd, "POSTGAP") == 0) {
1871  ret = cue_check_for_track(crs, cmd, 0);
1872  if (ret <= 0)
1873  goto ex;
1874  ret = cue_read_timepoint_lba(apt, "post-gap duration",
1875  &file_ba, 0);
1876  if (ret <= 0)
1877  goto ex;
1878  ret = burn_track_set_postgap_size(crs->track, file_ba, 0);
1879  if (ret <= 0)
1880  goto ex;
1881 
1882  } else if (strcmp(cmd, "PREGAP") == 0) {
1883  ret = cue_check_for_track(crs, cmd, 0);
1884  if (ret <= 0)
1885  goto ex;
1886  ret = cue_read_timepoint_lba(apt, "pre-gap duration",
1887  &file_ba, 0);
1888  if (ret <= 0)
1889  goto ex;
1890  ret = burn_track_set_pregap_size(crs->track, file_ba, 0);
1891  if (ret <= 0)
1892  goto ex;
1893 
1894  } else if (strcmp(cmd, "REM") == 0) {
1895  ;
1896 
1897  } else if (strcmp(cmd, "SONGWRITER") == 0) {
1898  ret = cue_set_cdtext(session, crs->track, 0x82, apt, crs, 2);
1899  if (ret <= 0)
1900  goto ex;
1901 
1902  } else if (strcmp(cmd, "TITLE") == 0) {
1903  ret = cue_set_cdtext(session, crs->track, 0x80, apt, crs, 2);
1904  if (ret <= 0)
1905  goto ex;
1906 
1907  } else if (strcmp(cmd, "TRACK") == 0) {
1908  if (crs->file_source == NULL) {
1909  libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
1911  "No FILE defined before TRACK in cue sheet file",
1912  0, 0);
1913  ret = 0; goto ex;
1914  }
1915  /* Attach previous track to session */
1916  ret = cue_attach_track(session, crs, 0);
1917  if (ret <= 0)
1918  goto ex;
1919  /* Create new track */;
1920  ret = cue_read_number(&apt, &(crs->track_no), 0);
1921  if (ret <= 0)
1922  goto ex;
1923  if (crs->track_no < 1 || crs->track_no > 99) {
1924  sprintf(msg,
1925  "Inappropriate cue sheet file track number %d",
1926  crs->track_no);
1927  libdax_msgs_submit(libdax_messenger, -1, 0x00020194,
1929  burn_printify(msg), 0, 0);
1930  ret = 0; goto ex;
1931  }
1932  if (strcmp(apt, "AUDIO") == 0) {
1933  mode = BURN_AUDIO;
1934  block_size = 2352;
1935  } else if (strcmp(apt, "MODE1/2048") == 0) {
1936  mode = BURN_MODE1;
1937  block_size = 2048;
1938  } else {
1939  sprintf(msg,
1940  "Unsupported cue sheet file track datatype '%.4000s'",
1941  apt);
1942  libdax_msgs_submit(libdax_messenger, -1, 0x00020197,
1944  burn_printify(msg), 0, 0);
1945  ret = 0; goto ex;
1946  }
1947  if (block_size != crs->block_size && crs->block_size > 0 &&
1948  crs->block_size_locked) {
1949  libdax_msgs_submit(libdax_messenger, -1, 0x00020197,
1951  "In cue sheet file: Unsupported mix track block sizes",
1952  0, 0);
1953  ret = 0; goto ex;
1954  }
1955  crs->block_size = block_size;
1956 
1957  crs->track = burn_track_create();
1958  if (crs->track == NULL)
1959  goto out_of_mem;
1960  crs->track_has_source = 0;
1961  crs->track_mode = mode;
1962  burn_track_define_data(crs->track, 0, 0, 1, mode);
1963  if (mode & BURN_AUDIO)
1965  !!crs->swap_audio_bytes);
1966 
1967  } else {
1968  sprintf(msg, "Unknown cue sheet file command '%.4000s'", line);
1969  libdax_msgs_submit(libdax_messenger, -1, 0x00020191,
1971  burn_printify(msg), 0, 0);
1972  ret = 0; goto ex;
1973  }
1974 
1975  ret = 1;
1976 ex:;
1977  BURN_FREE_MEM(msg);
1978  return ret;
1979 }
1980 
1981 
1982 /* ts B11216 API */
1983 /* @param flag bit0= do not attach CD-TEXT information to session and tracks
1984  bit1= do not attach CATALOG to session or ISRC to track for
1985  writing to Q sub-channel
1986 */
1987 int burn_session_by_cue_file(struct burn_session *session, char *path,
1988  int fifo_size, struct burn_source **fifo,
1989  unsigned char **text_packs, int *num_packs, int flag)
1990 {
1991  int ret, num_tracks, i, pack_type, length, double_byte = 0;
1992  int line_counter = 0;
1993  struct burn_track **tracks;
1994  char *msg = NULL, *line = NULL;
1995  unsigned char *payload;
1996  struct stat stbuf;
1997  FILE *fp = NULL;
1998  struct burn_cue_file_cursor *crs = NULL;
1999 
2000  static unsigned char dummy_cdtext[2] = {0, 0};
2001 
2002  if (fifo != NULL)
2003  *fifo = NULL;
2004  if (text_packs != NULL)
2005  *text_packs = NULL;
2006  *num_packs = 0;
2007 
2008  BURN_ALLOC_MEM(msg, char, 4096);
2009  BURN_ALLOC_MEM(line, char, 4096);
2010  ret = cue_crs_new(&crs, 0);
2011  if (ret <= 0)
2012  goto ex;
2013  crs->no_cdtext = (flag & 1);
2014  crs->no_catalog_isrc = !!(flag & 2);
2015  crs->fifo_size = fifo_size;
2016  crs->block_size_locked = 1; /* No mixed sessions for now */
2017 
2018  tracks = burn_session_get_tracks(session, &num_tracks);
2019  if (num_tracks > 0) {
2020  sprintf(msg,
2021  "Cue sheet file reader called while session has already defined tracks");
2022  libdax_msgs_submit(libdax_messenger, -1, 0x00020196,
2024  burn_printify(msg), 0, 0);
2025  ret = 0; goto ex;
2026  }
2027  if (stat(path, &stbuf) == -1) {
2028 cannot_open:;
2029  sprintf(msg, "Cannot open cue sheet file '%.4000s'",
2030  path);
2031  libdax_msgs_submit(libdax_messenger, -1, 0x00020193,
2033  burn_printify(msg), errno, 0);
2034  ret = 0; goto ex;
2035  }
2036  if (!S_ISREG(stbuf.st_mode)) {
2037  sprintf(msg,
2038  "File is not of usable type: Cue sheet file '%.4000s'",
2039  path);
2040  libdax_msgs_submit(libdax_messenger, -1, 0x00020193,
2042  burn_printify(msg), 0, 0);
2043  ret = 0; goto ex;
2044  }
2045 
2046  fp = fopen(path, "rb");
2047  if (fp == NULL)
2048  goto cannot_open;
2049 
2050  while (1) {
2051  if (burn_sfile_fgets(line, 4095, fp) == NULL) {
2052  if (!ferror(fp))
2053  break;
2054  sprintf(msg,
2055  "Cannot read all bytes from cue sheet file '%.4000s'",
2056  path);
2057  libdax_msgs_submit(libdax_messenger, -1, 0x00020193,
2059  burn_printify(msg), 0, 0);
2060  ret = 0; goto ex;
2061  }
2062  line_counter++;
2063  ret = cue_interpret_line(session, line, crs, 0);
2064  if (ret <= 0) {
2065  sprintf(msg,
2066  "Cue sheet file '%.4000s': Reading aborted after line %d",
2067  path, line_counter);
2068  libdax_msgs_submit(libdax_messenger, -1, 0x00020199,
2070  burn_printify(msg), 0, 0);
2071  goto ex;
2072  }
2073  }
2074 
2075  /* Attach last track to session */
2076  if (crs->track != NULL) {
2077  /* Set track size up to end of file */
2078  if (crs->current_file_ba < 0 || crs->track_current_index < 1) {
2079  libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
2081  "No INDEX 01 defined for last TRACK in cue sheet file",
2082  0, 0);
2083  ret = 0; goto ex;
2084  }
2085  if (crs->current_file_ba * crs->block_size >=
2086  crs->source_size) {
2087  libdax_msgs_submit(libdax_messenger, -1, 0x00020194,
2089  "TRACK start time point exceeds size of FILE from cue sheet file",
2090  0, 0);
2091  ret = 0; goto ex;
2092  }
2093  ret = burn_track_set_size(crs->track, crs->source_size -
2094  (off_t) (crs->current_file_ba * crs->block_size));
2095  if (ret <= 0)
2096  goto ex;
2097 
2098  ret = cue_attach_track(session, crs, 0);
2099  if (ret <= 0)
2100  goto ex;
2101  }
2102  if (crs->cdtextfile != NULL) {
2103  if (text_packs == NULL) {
2104 
2105  /* >>> Warn of ignored text packs */;
2106 
2107  } else {
2109  text_packs, num_packs, 0);
2110  if (ret <= 0)
2111  goto ex;
2112  }
2113  }
2114 
2115  /* Check which tracks have data of pack types where session has not */
2116  tracks = burn_session_get_tracks(session, &num_tracks);
2117  for (pack_type = 0x80; pack_type < 0x8f; pack_type++) {
2118  if (pack_type > 0x86 && pack_type != 0x8e)
2119  continue;
2120  ret = burn_session_get_cdtext(session, 0, pack_type, "",
2121  &payload, &length, 0);
2122  if (ret <= 0)
2123  goto ex;
2124  if (payload != NULL)
2125  continue;
2126  for (i = 0; i < num_tracks; i++) {
2127  ret = burn_track_get_cdtext(tracks[i], 0, pack_type,
2128  "", &payload, &length, 0);
2129  if (ret <= 0)
2130  goto ex;
2131  double_byte = (ret > 1);
2132  if (payload != NULL)
2133  break;
2134  }
2135  if (i < num_tracks) {
2136  ret = burn_session_set_cdtext(session, 0, pack_type,
2137  "", dummy_cdtext, 1 + double_byte,
2138  double_byte);
2139  if (ret <= 0)
2140  goto ex;
2141  }
2142  }
2143  ret = 1;
2144 ex:
2145  if (ret <= 0) {
2146  tracks = burn_session_get_tracks(session, &num_tracks);
2147  for (i = 0; i < num_tracks; i++)
2148  burn_track_free(tracks[i]);
2149  if(text_packs != NULL) {
2150  if(*text_packs != NULL)
2151  free(*text_packs);
2152  *text_packs = NULL;
2153  *num_packs = 0;
2154  }
2155  } else {
2156  if (fifo != NULL) {
2157  *fifo = crs->fifo;
2158  crs->fifo = NULL;
2159  }
2160  }
2161  cue_crs_destroy(&crs, 0);
2162  BURN_FREE_MEM(line);
2163  BURN_FREE_MEM(msg);
2164  if (fp != NULL)
2165  fclose(fp);
2166  return ret;
2167 }
2168 
int burn_cdtext_from_packfile(char *path, unsigned char **text_packs, int *num_packs, int flag)
Definition: cdtext.c:1077
struct burn_source * burn_offst_source_new(struct burn_source *inp, struct burn_source *prev, off_t start, off_t size, int flag)
Definition: file.c:913
struct burn_source * burn_fifo_source_new(struct burn_source *inp, int chunksize, int chunks, int flag)
Definition: file.c:542
struct burn_source * burn_fd_source_new(int datafd, int subfd, off_t size)
Definition: file.c:178
void * burn_alloc_mem(size_t size, size_t count, int flag)
Definition: init.c:653
#define BURN_FREE_MEM(pt)
Definition: init.h:52
#define BURN_ALLOC_MEM(pt, typ, count)
Definition: init.h:40
char * burn_sfile_fgets(char *line, int maxl, FILE *fp)
Definition: util.c:307
char * burn_printify(char *msg)
Definition: util.c:329
int burn_msf_to_lba(int m, int s, int f)
Definition: sector.c:759
int libdax_audioxtr_get_id(struct libdax_audioxtr *xtr, char **fmt, char **fmt_info, int *num_channels, int *sample_rate, int *bits_per_sample, int *msb_first, int flag)
void burn_source_free(struct burn_source *s)
Definition: source.c:20
enum burn_source_status burn_track_set_source(struct burn_track *t, struct burn_source *s)
Definition: source.c:29
int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag)
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag)
#define BURN_POS_END
Definition: libburn.h:76
#define BURN_4CH
Definition: libburn.h:115
int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag)
#define BURN_COPY
Definition: libburn.h:117
#define BURN_PREEMPHASIS
Definition: libburn.h:119
burn_source_status
Definition: libburn.h:281
@ BURN_SOURCE_OK
Definition: libburn.h:283
#define BURN_SCMS
Definition: libburn.h:133
int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag)
#define BURN_MODE1
Definition: libburn.h:92
#define BURN_AUDIO
Definition: libburn.h:113
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code, int severity, int priority, char *msg_text, int os_errno, int flag)
Definition: libdax_msgs.c:334
#define LIBDAX_MSGS_SEV_DEBUG
Definition: libdax_msgs.h:138
#define LIBDAX_MSGS_SEV_FATAL
Definition: libdax_msgs.h:217
#define LIBDAX_MSGS_PRIO_HIGH
Definition: libdax_msgs.h:237
#define LIBDAX_MSGS_SEV_SORRY
Definition: libdax_msgs.h:176
#define LIBDAX_MSGS_SEV_WARNING
Definition: libdax_msgs.h:154
#define LIBDAX_MSGS_PRIO_ZERO
Definition: libdax_msgs.h:234
#define LIBDAX_MSGS_SEV_MISHAP
Definition: libdax_msgs.h:190
#define LIBDAX_MSGS_SEV_FAILURE
Definition: libdax_msgs.h:205
int mmc_four_char_to_int(unsigned char *data)
Definition: mmc.c:297
int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf, int alloc_len)
Definition: mmc.c:405
unsigned char data[65536+4096]
Definition: transport.h:52
int length[0x10]
Definition: structure.h:31
unsigned char * payload[0x10]
Definition: structure.h:30
struct burn_source * file_source
Definition: structure.c:1173
struct burn_source * fifo
Definition: structure.c:1175
struct burn_track * track
Definition: structure.c:1186
struct burn_track * prev_track
Definition: structure.c:1183
struct burn_source * offst_source
Definition: structure.c:1180
int sessions
Definition: structure.h:145
int refcnt
Definition: structure.h:152
struct burn_session ** session
Definition: structure.h:146
int current_is_cd_profile
Definition: transport.h:210
struct burn_disc * disc
Definition: transport.h:392
unsigned char cdtext_char_code[8]
Definition: structure.h:135
unsigned char cdtext_language[8]
Definition: structure.h:137
unsigned char cdtext_copyright[8]
Definition: structure.h:136
unsigned char mediacatalog[14]
Definition: structure.h:140
struct burn_cdtext * cdtext[8]
Definition: structure.h:134
struct burn_toc_entry * leadout_entry
Definition: structure.h:127
unsigned char lasttrack
Definition: structure.h:122
struct burn_track ** track
Definition: structure.h:130
unsigned char firsttrack
Definition: structure.h:121
int(* set_size)(struct burn_source *source, off_t size)
Definition: libburn.h:526
off_t(* get_size)(struct burn_source *)
Definition: libburn.h:509
Definition: libburn.h:351
unsigned char extensions_valid
Definition: libburn.h:380
int start_lba
Definition: libburn.h:389
unsigned char psec
Definition: libburn.h:369
unsigned char pmin
Definition: libburn.h:367
unsigned char point_msb
Definition: libburn.h:387
int track_blocks
Definition: libburn.h:391
unsigned char pframe
Definition: libburn.h:371
unsigned char session_msb
Definition: libburn.h:386
struct isrc isrc
Definition: structure.h:105
int open_ended
Definition: structure.h:74
int end_on_premature_eoi
Definition: structure.h:84
int refcnt
Definition: structure.h:37
int pregap2_size
Definition: structure.h:96
int postgap_size
Definition: structure.h:103
int swap_source_bytes
Definition: structure.h:109
int tailcount
Definition: structure.h:52
struct burn_source * source
Definition: structure.h:63
unsigned char indices
Definition: structure.h:39
int pregap2
Definition: structure.h:92
int pregap1
Definition: structure.h:90
int cdxa_conversion
Definition: structure.h:112
off_t written_sectors
Definition: structure.h:70
int index[100]
Definition: structure.h:44
int fill_up_media
Definition: structure.h:57
int offsetcount
Definition: structure.h:48
int tail
Definition: structure.h:50
int offset
Definition: structure.h:46
struct burn_cdtext * cdtext[8]
Definition: structure.h:115
int mode
Definition: structure.h:88
int postgap
Definition: structure.h:99
off_t sourcecount
Definition: structure.h:68
off_t writecount
Definition: structure.h:69
off_t default_size
Definition: structure.h:60
struct burn_toc_entry * entry
Definition: structure.h:38
int track_data_done
Definition: structure.h:76
Definition: structure.h:11
unsigned int serial
Definition: structure.h:16
unsigned char year
Definition: structure.h:15
char country[2]
Definition: structure.h:13
char owner[3]
Definition: structure.h:14
int has_isrc
Definition: structure.h:12
off_t burn_track_get_default_size(struct burn_track *t)
Definition: structure.c:629
int burn_session_get_sectors(struct burn_session *s)
Definition: structure.c:666
static int cue_create_file_source(char *path, struct burn_cue_file_cursor *crs, int flag)
Definition: structure.c:1478
int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes)
Definition: structure.c:358
void burn_track_free(struct burn_track *t)
Definition: structure.c:232
int burn_session_get_start_tno(struct burn_session *session, int flag)
Definition: structure.c:885
void burn_structure_print_session(struct burn_session *s)
Definition: structure.c:305
static int cue_read_timepoint_lba(char *apt, char *purpose, int *file_ba, int flag)
Definition: structure.c:1514
int burn_track_set_postgap_size(struct burn_track *t, int size, int flag)
Definition: structure.c:502
void burn_track_get_entry(struct burn_track *t, struct burn_toc_entry *entry)
Definition: structure.c:685
int burn_session_add_track(struct burn_session *s, struct burn_track *t, unsigned int pos)
Definition: structure.c:247
void burn_session_free(struct burn_session *s)
Definition: structure.c:125
int burn_disc_get_incomplete_sessions(struct burn_disc *d)
Definition: structure.c:721
int burn_session_set_cdtext(struct burn_session *s, int block, int pack_type, char *pack_type_name, unsigned char *payload, int length, int flag)
Definition: structure.c:1073
int burn_track_get_cdtext(struct burn_track *t, int block, int pack_type, char *pack_type_name, unsigned char **payload, int *length, int flag)
Definition: structure.c:1034
static int cue_crs_destroy(struct burn_cue_file_cursor **victim, int flag)
Definition: structure.c:1235
int burn_track_set_fillup(struct burn_track *t, int fill_up_media)
Definition: structure.c:577
struct burn_session * burn_session_create(void)
Definition: structure.c:95
struct burn_cdtext * burn_cdtext_create(void)
Definition: structure.c:891
static int burn_cdtext_name_to_type(char *pack_type_name)
Definition: structure.c:922
int burn_track_get_mode(struct burn_track *track)
Definition: structure.c:741
#define O_BINARY
Definition: structure.c:26
int burn_track_clear_indice(struct burn_track *t, int flag)
Definition: structure.c:483
static int cue_check_for_track(struct burn_cue_file_cursor *crs, char *cmd, int flag)
Definition: structure.c:1556
#define RESIZE(TO, NEW, pos)
Definition: structure.c:45
int burn_track_set_isrc_string(struct burn_track *t, char isrc[13], int flag)
Definition: structure.c:439
struct libdax_msgs * libdax_messenger
Definition: init.c:42
int burn_track_set_index(struct burn_track *t, int index_number, unsigned int relative_lba, int flag)
Definition: structure.c:464
void burn_session_get_leadout_entry(struct burn_session *s, struct burn_toc_entry *entry)
Definition: structure.c:693
int burn_track_set_size(struct burn_track *t, off_t size)
Definition: structure.c:565
void burn_track_clear_isrc(struct burn_track *t)
Definition: structure.c:458
int burn_track_get_counters(struct burn_track *t, off_t *read_bytes, off_t *written_bytes)
Definition: structure.c:636
int burn_track_set_cdtext(struct burn_track *t, int block, int pack_type, char *pack_type_name, unsigned char *payload, int length, int flag)
Definition: structure.c:1018
static int burn_cdtext_check_blockno(int block)
Definition: structure.c:1003
int burn_track_set_pregap_size(struct burn_track *t, int size, int flag)
Definition: structure.c:494
int burn_disc_add_session(struct burn_disc *d, struct burn_session *s, unsigned int pos)
Definition: structure.c:142
int burn_track_is_data_done(struct burn_track *t)
Definition: structure.c:649
int burn_track_dispose_cdtext(struct burn_track *t, int block)
Definition: structure.c:1054
struct burn_track ** burn_session_get_tracks(struct burn_session *s, int *num)
Definition: structure.c:735
static int cue_set_cdtext(struct burn_session *session, struct burn_track *track, int pack_type, char *text, struct burn_cue_file_cursor *crs, int flag)
Definition: structure.c:1284
static int cue_read_number(char **payload, int *number, int flag)
Definition: structure.c:1381
static int cue_interpret_line(struct burn_session *session, char *line, struct burn_cue_file_cursor *crs, int flag)
Definition: structure.c:1578
int burn_track_set_default_size(struct burn_track *t, off_t size)
Definition: structure.c:621
struct burn_disc * burn_disc_create(void)
Definition: structure.c:64
void burn_structure_print_track(struct burn_track *t)
Definition: structure.c:318
void burn_track_set_isrc(struct burn_track *t, char *country, char *owner, unsigned char year, unsigned int serial)
Definition: structure.c:377
static int cue_crs_new(struct burn_cue_file_cursor **reply, int flag)
Definition: structure.c:1197
int burn_session_set_start_tno(struct burn_session *session, int tno, int flag)
Definition: structure.c:864
int burn_session_by_cue_file(struct burn_session *session, char *path, int fifo_size, struct burn_source **fifo, unsigned char **text_packs, int *num_packs, int flag)
Definition: structure.c:1987
int burn_track_get_sectors(struct burn_track *t)
Definition: structure.c:543
struct burn_track * burn_track_create(void)
Definition: structure.c:175
void burn_session_hide_first_track(struct burn_session *s, int onoff)
Definition: structure.c:120
int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag)
Definition: structure.c:590
int burn_session_remove_track(struct burn_session *s, struct burn_track *t)
Definition: structure.c:256
int burn_track_get_shortage(struct burn_track *t)
Definition: structure.c:654
int burn_disc_get_sectors(struct burn_disc *d)
Definition: structure.c:676
int burn_session_get_cdtext(struct burn_session *s, int block, int pack_type, char *pack_type_name, unsigned char **payload, int *length, int flag)
Definition: structure.c:1089
int burn_session_get_hidefirst(struct burn_session *session)
Definition: structure.c:746
static int cue_open_audioxtr(char *path, struct burn_cue_file_cursor *crs, int *fd, int flag)
Definition: structure.c:1417
int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
Definition: structure.c:753
int burn_session_dispose_cdtext(struct burn_session *s, int block)
Definition: structure.c:1145
int burn_session_get_cdtext_par(struct burn_session *s, int char_codes[8], int copyrights[8], int block_languages[8], int flag)
Definition: structure.c:1129
struct burn_session ** burn_disc_get_sessions(struct burn_disc *d, int *num)
Definition: structure.c:702
void burn_disc_free(struct burn_disc *d)
Definition: structure.c:81
int burn_session_set_cdtext_par(struct burn_session *s, int char_codes[8], int copyrights[8], int block_languages[8], int flag)
Definition: structure.c:1110
void burn_cdtext_free(struct burn_cdtext **cdtext)
Definition: structure.c:907
int burn_track_get_sectors_2(struct burn_track *t, int flag)
Definition: structure.c:512
static int burn_cdtext_get(struct burn_cdtext *t, int pack_type, char *pack_type_name, unsigned char **payload, int *length, int flag)
Definition: structure.c:983
int burn_track_set_sectors(struct burn_track *t, int sectors)
Definition: structure.c:549
int burn_track_is_open_ended(struct burn_track *t)
Definition: structure.c:614
int burn_disc_remove_session(struct burn_disc *d, struct burn_session *s)
Definition: structure.c:154
static int burn_cdtext_set(struct burn_cdtext **cdtext, int pack_type, char *pack_type_name, unsigned char *payload, int length, int flag)
Definition: structure.c:946
void burn_track_define_data(struct burn_track *t, int offset, int tail, int pad, int mode)
Definition: structure.c:329
static int cue_attach_track(struct burn_session *session, struct burn_cue_file_cursor *crs, int flag)
Definition: structure.c:1325
int burn_track_set_cdxa_conv(struct burn_track *t, int value)
Definition: structure.c:368
void burn_structure_print_disc(struct burn_disc *d)
Definition: structure.c:292
static char * cue_unquote_text(char *text, int flag)
Definition: structure.c:1262
#define Libburn_pack_num_typeS
Definition: structure.h:21
#define Libburn_pack_type_nameS
Definition: structure.h:22
#define Libburn_pack_type_basE
Definition: structure.h:20
int burn_sector_length(int tracktype)
Definition: write.c:835
void type_to_form(int mode, unsigned char *ctladr, int *form)
Definition: write.c:126