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)  

sector.c
Go to the documentation of this file.
1 /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
2 
3 /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
4  Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
5  Provided under GPL version 2 or later.
6 */
7 
8 #ifdef HAVE_CONFIG_H
9 #include "../config.h"
10 #endif
11 
12 #include <stdio.h>
13 
14 /* ts A61010 */
15 /* #include <a ssert.h> */
16 
17 #include <unistd.h>
18 #include <string.h>
19 #include "error.h"
20 #include "options.h"
21 #include "transport.h"
22 #include "libburn.h"
23 #include "drive.h"
24 #include "sector.h"
25 #include "crc.h"
26 #include "debug.h"
27 #include "toc.h"
28 #include "write.h"
29 
30 #include "libdax_msgs.h"
31 extern struct libdax_msgs *libdax_messenger;
32 
33 #include "ecma130ab.h"
34 
35 
36 #ifdef Libburn_log_in_and_out_streaM
37 /* ts A61031 */
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #endif /* Libburn_log_in_and_out_streaM */
42 
43 /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
44 #ifndef O_BINARY
45 #define O_BINARY 0
46 #endif
47 
48 /*static unsigned char isrc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";*/
49 
50 #define sector_common(X) d->alba++; d->rlba X;
51 
52 static void uncook_subs(unsigned char *dest, unsigned char *source)
53 {
54  int i, j, code;
55 
56  memset(dest, 0, 96);
57 
58  for (i = 0; i < 12; i++) {
59  for (j = 0; j < 8; j++) {
60  for (code = 0; code < 8; code++) {
61  if (source[code * 12 + i] & 0x80)
62  dest[j + i * 8] |= (1 << (7 - code));
63  source[code * 12 + i] <<= 1;
64  }
65  }
66  }
67 }
68 
69 /* @return >=0 : valid , <0 invalid */
71  enum burn_block_types block_type)
72 {
73  /* ts A61103 : extended SAO condition to TAO */
74  if (write_type == BURN_WRITE_SAO || write_type == BURN_WRITE_TAO)
75  return 0;
76  else
77  switch (block_type) {
78  case BURN_BLOCK_RAW0:
79  return BURN_MODE_RAW;
80  case BURN_BLOCK_RAW16:
82  case BURN_BLOCK_RAW96P:
84  case BURN_BLOCK_RAW96R:
86  case BURN_BLOCK_MODE1:
87  return BURN_MODE1;
88  default:
89  return -1;
90  }
91 
92  /* ts A61007 : now handled in burn_write_opts_set_write_type() */
93  /* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */
94 }
95 
96 /* 0 means "same as inmode" */
97 static int get_outmode(struct burn_write_opts *o)
98 {
99  /* ts A61007 */
101 
102  /* -1 is prevented by check in burn_write_opts_set_write_type() */
103  /* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */
104 }
105 
106 
107 static void get_bytes(struct burn_track *track, int count, unsigned char *data)
108 {
109  int valid, shortage, curr, i, tr;
110 
111 #ifdef Libburn_log_in_and_out_streaM
112  /* ts A61031 */
113  static int tee_fd= -1;
114  if(tee_fd==-1)
115  tee_fd= open("/tmp/libburn_sg_readin",
116  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
117  S_IRUSR | S_IWUSR);
118 #endif /* Libburn_log_in_and_out_streaM */
119 
120 
121 /* no track pointer means we're just generating 0s */
122  if (!track) {
123  memset(data, 0, count);
124  return;
125  }
126 
127 /* first we use up any offset */
128  valid = track->offset - track->offsetcount;
129  if (valid > count)
130  valid = count;
131 
132  if (valid) {
133  track->offsetcount += valid;
134  memset(data, 0, valid);
135  }
136  shortage = count - valid;
137 
138  if (!shortage)
139  goto ex;
140 
141 /* Next we use source data */
142  curr = valid;
143  if (!track->eos) {
144  if (track->source->read != NULL)
145  valid = track->source->read(track->source,
146  data + curr, count - curr);
147  else
148  valid = track->source->read_xt(track->source,
149  data + curr, count - curr);
150  } else valid = 0;
151 
152  if (valid <= 0) { /* ts A61031 : extended from (valid == -1) */
153  track->eos = 1;
154  valid = 0;
155  }
156  track->sourcecount += valid;
157 
158 #ifdef Libburn_log_in_and_out_streaM
159  /* ts A61031 */
160  if(tee_fd!=-1 && valid>0) {
161  write(tee_fd, data + curr, valid);
162  }
163 #endif /* Libburn_log_in_and_out_streaM */
164 
165  curr += valid;
166  shortage = count - curr;
167 
168  if (!shortage)
169  goto ex;
170 
171 /* Before going to the next track, we run through any tail */
172 
173  valid = track->tail - track->tailcount;
174  if (valid > count - curr)
175  valid = count - curr;
176 
177  if (valid) {
178  track->tailcount += valid;
179  memset(data + curr, 0, valid);
180  }
181  curr += valid;
182  shortage -= valid;
183 
184  if (!shortage)
185  goto ex;
186 
187  /* ts A61031 - B10103 */
188  if (shortage >= count)
189  track->track_data_done = 1;
190  if (track->end_on_premature_eoi && shortage >= count &&
191  !track->open_ended) {
192  char msg[80];
193  off_t missing, inp_block_size, track_blocks;
194 
195  inp_block_size = burn_sector_length(track->mode);
196  track_blocks = burn_track_get_sectors_2(track, 1);
197  missing = track_blocks * inp_block_size - track->sourcecount;
198  sprintf(msg,
199  "Premature end of input encountered. Missing: %.f bytes",
200  (double) missing);
201  libdax_msgs_submit(libdax_messenger, -1, 0x00020180,
203  msg, 0,0);
204  /* Memorize that premature end of input happened */
205  track->end_on_premature_eoi = 2;
206  }
207  if (track->open_ended || track->end_on_premature_eoi)
208  goto ex;
209 
210 /* If we're still short, and there's a "next" pointer, we pull from that.
211  if that depletes, we'll just fill with 0s.
212 */
213  if (track->source->next) {
214  struct burn_source *src;
215  printf("pulling from next track\n");
216  src = track->source->next;
217  valid = src->read(src, data + curr, shortage);
218  if (valid > 0) {
219  shortage -= valid;
220  curr += valid;
221  }
222  }
223 ex:;
224  /* ts A61024 : general finalizing processing */
225  if(shortage)
226  memset(data + curr, 0, shortage); /* this is old icculus.org */
227  if (track->swap_source_bytes == 1) {
228  for (i = 1; i < count; i += 2) {
229  tr = data[i];
230  data[i] = data[i-1];
231  data[i-1] = tr;
232  }
233  }
234 }
235 
236 
237 /* ts B20113 : outsourced from get_sector() */
239  struct burn_track *track, int flag)
240 {
241  int err, i;
242  struct buffer *out;
243 
244  out = d->buffer;
245  if (out->sectors <= 0)
246  return 2;
247  err = d->write(d, d->nwa, out);
248  if (err == BE_CANCELLED)
249  return 0;
250 
251  /* ts A61101 */
252  if(track != NULL) {
253  track->writecount += out->bytes;
254  track->written_sectors += out->sectors;
255 
256  /* Determine current index */
257  for (i = d->progress.index; i + 1 < track->indices; i++) {
258  if (track->index[i + 1] > d->nwa + out->sectors)
259  break;
260  d->progress.index = i + 1;
261  }
262  }
263  /* ts A61119 */
264  d->progress.buffered_bytes += out->bytes;
265 
266  d->nwa += out->sectors;
267  out->bytes = 0;
268  out->sectors = 0;
269  return 1;
270 }
271 
272 
273 /* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer
274  and to count hand outs as well as reserved bytes */
275 /* ts A61101 : added parameter track for counting written bytes */
276 static unsigned char *get_sector(struct burn_write_opts *opts,
277  struct burn_track *track, int inmode)
278 {
279  struct burn_drive *d = opts->drive;
280  struct buffer *out = d->buffer;
281  int outmode, seclen, write_ret;
282  unsigned char *ret;
283 
284  outmode = get_outmode(opts);
285  if (outmode == 0)
286  outmode = inmode;
287 
288  /* ts A61009 : react on eventual failure of burn_sector_length()
289  (should not happen if API tested properly).
290  Ensures out->bytes >= out->sectors */
291  seclen = burn_sector_length(outmode);
292  if (seclen <= 0)
293  return NULL;
294  seclen += burn_subcode_length(outmode);
295 
296  /* ts A61219 : opts->obs is eventually a 32k trigger for DVD */
297  /* (there is enough buffer size reserve for track->cdxa_conversion) */
298  if (out->bytes + seclen > BUFFER_SIZE ||
299  (opts->obs > 0 && out->bytes + seclen > opts->obs)) {
300  write_ret = sector_write_buffer(d, track, 0);
301  if (write_ret <= 0)
302  return NULL;
303  }
304  ret = out->data + out->bytes;
305  out->bytes += seclen;
306  out->sectors++;
307 
308  return ret;
309 }
310 
311 /* ts A61031 */
312 /* Revoke the counting of the most recent sector handed out by get_sector() */
313 static void unget_sector(struct burn_write_opts *opts, int inmode)
314 {
315  struct burn_drive *d = opts->drive;
316  struct buffer *out = d->buffer;
317  int outmode;
318  int seclen;
319 
320  outmode = get_outmode(opts);
321  if (outmode == 0)
322  outmode = inmode;
323 
324  /* ts A61009 : react on eventual failure of burn_sector_length()
325  (should not happen if API tested properly).
326  Ensures out->bytes >= out->sectors */
327  seclen = burn_sector_length(outmode);
328  if (seclen <= 0)
329  return;
330  seclen += burn_subcode_length(outmode);
331 
332  out->bytes -= seclen;
333  out->sectors--;
334 }
335 
336 
337 /* either inmode == outmode, or outmode == raw. anything else is bad news */
338 /* ts A61010 : changed type to int in order to propagate said bad news */
339 /** @return 1 is ok, <= 0 is failure */
340 static int convert_data(struct burn_write_opts *o, struct burn_track *track,
341  int inmode, unsigned char *data)
342 {
343  int outlen, inlen;
344  int offset = -1;
345  int outmode;
346 
347  outmode = get_outmode(o);
348  if (outmode == 0)
349  outmode = inmode;
350 
351  outlen = burn_sector_length(outmode);
352  inlen = burn_sector_length(inmode);
353 
354  /* ts A61010 */
355  /* a ssert(outlen >= inlen); */
356  if (outlen < inlen || outlen < 0 || inlen < 0)
357  return 0;
358 
359  if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {
360  /* see MMC-5 4.2.3.8.5.3 Block Format for Mode 2 form 1 Data
361  Table 24 Mode 2 Formed Sector Sub-header Format */
362  if (track != NULL)
363  if (track->cdxa_conversion == 1)
364  inlen += 8;
365 
366  get_bytes(track, inlen, data);
367 
368  if (track != NULL)
369  if (track->cdxa_conversion == 1)
370  memmove(data, data + 8, inlen - 8);
371  return 1;
372  }
373 
374  /* ts A61010 */
375  /* a ssert(outmode & BURN_MODE_RAW); */
376  if (!(outmode & BURN_MODE_RAW))
377  return 0;
378 
379  if (inmode & BURN_MODE1)
380  offset = 16;
381  if (inmode & BURN_MODE_RAW)
382  offset = 0;
383  if (inmode & BURN_AUDIO)
384  offset = 0;
385 
386  /* ts A61010 */
387  /* a ssert(offset != -1); */
388  if (offset == -1)
389  return 0;
390 
391  get_bytes(track, inlen, data + offset);
392  return 1;
393 }
394 
395 static void convert_subs(struct burn_write_opts *o, int inmode,
396  unsigned char *subs, unsigned char *sector)
397 {
398  unsigned char *out;
399  int outmode;
400 
401  outmode = get_outmode(o);
402  if (outmode == 0)
403  outmode = inmode;
404  sector += burn_sector_length(outmode);
405 /* XXX for sao with subs, we'd need something else... */
406 
407  switch (o->block_type) {
408  case BURN_BLOCK_RAW96R:
409  uncook_subs(sector, subs);
410  break;
411 
412  case BURN_BLOCK_RAW16:
413  memcpy(sector, subs + 12, 12);
414  out = sector + 12;
415  out[0] = 0;
416  out[1] = 0;
417  out[2] = 0;
418 /*XXX find a better way to deal with partially damaged P channels*/
419  if (subs[2] != 0)
420  out[3] = 0x80;
421  else
422  out[3] = 0;
423  out = sector + 10;
424 
425  out[0] = ~out[0];
426  out[1] = ~out[1];
427  break;
428  /* ts A61119 : to silence compiler warnings */
429  default:;
430  }
431 }
432 
433 static void subcode_toc(struct burn_drive *d, int mode, unsigned char *data)
434 {
435  unsigned char *q;
436  int track;
437  int crc;
438  int min, sec, frame;
439 
440  track = d->toc_temp / 3;
441  memset(data, 0, 96);
442  q = data + 12;
443 
444  burn_lba_to_msf(d->rlba, &min, &sec, &frame);
445 /*XXX track numbers are BCD
446 a0 - 1st track ctrl
447 a1 - last track ctrl
448 a2 - lout ctrl
449 */
450  q[0] = (d->toc_entry[track].control << 4) + 1;
451  q[1] = 0;
452  if (d->toc_entry[track].point < 100)
453  q[2] = dec_to_bcd(d->toc_entry[track].point);
454  else
455  q[2] = d->toc_entry[track].point;
456  q[3] = dec_to_bcd(min);
457  q[4] = dec_to_bcd(sec);
458  q[5] = dec_to_bcd(frame);
459  q[6] = 0;
460  q[7] = dec_to_bcd(d->toc_entry[track].pmin);
461  q[8] = dec_to_bcd(d->toc_entry[track].psec);
462  q[9] = dec_to_bcd(d->toc_entry[track].pframe);
463 
464 #ifdef Libburn_no_crc_C
465  crc = 0; /* dummy */
466 #else
467  crc = crc_ccitt(q, 10);
468 #endif
469 
470  q[10] = crc >> 8;
471  q[11] = crc & 0xFF;
472  d->toc_temp++;
473  d->toc_temp %= (d->toc_entries * 3);
474 }
475 
476 int sector_toc(struct burn_write_opts *o, int mode)
477 {
478  struct burn_drive *d = o->drive;
479  unsigned char *data;
480  unsigned char subs[96];
481 
482  data = get_sector(o, NULL, mode);
483  if (data == NULL)
484  return 0;
485  /* ts A61010 */
486  if (convert_data(o, NULL, mode, data) <= 0)
487  return 0;
488  subcode_toc(d, mode, subs);
489  convert_subs(o, mode, subs, data);
490  if (sector_headers(o, data, mode, 1) <= 0)
491  return 0;
492  sector_common(++)
493  return 1;
494 }
495 
497  unsigned char tno, unsigned char control, int mode)
498 {
499  struct burn_drive *d = o->drive;
500  unsigned char *data;
501  unsigned char subs[96];
502 
503  data = get_sector(o, NULL, mode);
504  if (data == NULL)
505  return 0;
506  /* ts A61010 */
507  if (convert_data(o, NULL, mode, data) <= 0)
508  return 0;
509  subcode_user(o, subs, tno, control, 0, NULL, 1);
510  convert_subs(o, mode, subs, data);
511  if (sector_headers(o, data, mode, 0) <= 0)
512  return 0;
513  sector_common(--)
514  return 1;
515 }
516 
518  unsigned char tno, unsigned char control, int mode)
519 {
520  struct burn_drive *d = o->drive;
521  unsigned char subs[96];
522  unsigned char *data;
523 
524  data = get_sector(o, NULL, mode);
525  if (data == NULL)
526  return 0;
527  /* ts A61010 */
528  if (convert_data(o, NULL, mode, data) <= 0)
529  return 0;
530 /* use last index in track */
531  subcode_user(o, subs, tno, control, 1, NULL, 1);
532  convert_subs(o, mode, subs, data);
533  if (sector_headers(o, data, mode, 0) <= 0)
534  return 0;
535  sector_common(++)
536  return 1;
537 }
538 
539 static void subcode_lout(struct burn_write_opts *o, unsigned char control,
540  unsigned char *data)
541 {
542  struct burn_drive *d = o->drive;
543  unsigned char *q;
544  int crc;
545  int rmin, min, rsec, sec, rframe, frame;
546 
547  memset(data, 0, 96);
548  q = data + 12;
549 
550  burn_lba_to_msf(d->alba, &min, &sec, &frame);
551  burn_lba_to_msf(d->rlba, &rmin, &rsec, &rframe);
552 
553  if (((rmin == 0) && (rsec == 0) && (rframe == 0)) ||
554  ((rsec >= 2) && !((rframe / 19) % 2)))
555  memset(data, 0xFF, 12);
556  q[0] = (control << 4) + 1;
557  q[1] = 0xAA;
558  q[2] = 0x01;
559  q[3] = dec_to_bcd(rmin);
560  q[4] = dec_to_bcd(rsec);
561  q[5] = dec_to_bcd(rframe);
562  q[6] = 0;
563  q[7] = dec_to_bcd(min);
564  q[8] = dec_to_bcd(sec);
565  q[9] = dec_to_bcd(frame);
566 
567 #ifdef Libburn_no_crc_C
568  crc = 0; /* dummy */
569 #else
570  crc = crc_ccitt(q, 10);
571 #endif
572 
573  q[10] = crc >> 8;
574  q[11] = crc & 0xFF;
575 }
576 
577 static char char_to_isrc(char c)
578 {
579  if (c >= '0' && c <= '9')
580  return c - '0';
581  if (c >= 'A' && c <= 'Z')
582  return 0x11 + (c - 'A');
583  if (c >= 'a' && c <= 'z')
584  return 0x11 + (c - 'a');
585 
586  /* ts A61008 : obsoleted by test in burn_track_set_isrc() */
587  /* a ssert(0); */
588  return 0;
589 }
590 
591 void subcode_user(struct burn_write_opts *o, unsigned char *subcodes,
592  unsigned char tno, unsigned char control,
593  unsigned char indx, struct isrc *isrc, int psub)
594 {
595  struct burn_drive *d = o->drive;
596  unsigned char *p, *q;
597  int crc;
598  int m, s, f, c, qmode; /* 1, 2 or 3 */
599 
600  memset(subcodes, 0, 96);
601 
602  p = subcodes;
603  if ((tno == 1) && (d->rlba == -150))
604  memset(p, 0xFF, 12);
605 
606  if (psub)
607  memset(p, 0xFF, 12);
608  q = subcodes + 12;
609 
610  qmode = 1;
611  /* every 1 in 10 we can do something different */
612  if (d->rlba % 10 == 0) {
613  /* each of these can occur 1 in 100 */
614  if ((d->rlba / 10) % 10 == 0) {
615  if (o->has_mediacatalog)
616  qmode = 2;
617  } else if ((d->rlba / 10) % 10 == 1) {
618  if (isrc && isrc->has_isrc)
619  qmode = 3;
620  }
621  }
622 
623  /* ts A61010 : this cannot happen. Assert for fun ? */
624  /* a ssert(qmode == 1 || qmode == 2 || qmode == 3); */
625 
626  switch (qmode) {
627  case 1:
628  q[1] = dec_to_bcd(tno); /* track number */
629  q[2] = dec_to_bcd(indx); /* index XXX read this shit
630  from the track array */
631  burn_lba_to_msf(d->rlba, &m, &s, &f);
632  q[3] = dec_to_bcd(m); /* rel min */
633  q[4] = dec_to_bcd(s); /* rel sec */
634  q[5] = dec_to_bcd(f); /* rel frame */
635  q[6] = 0; /* zero */
636  burn_lba_to_msf(d->alba, &m, &s, &f);
637  q[7] = dec_to_bcd(m); /* abs min */
638  q[8] = dec_to_bcd(s); /* abs sec */
639  q[9] = dec_to_bcd(f); /* abs frame */
640  break;
641  case 2:
642  /* media catalog number */
643  q[1] = (o->mediacatalog[0] << 4) + o->mediacatalog[1];
644  q[2] = (o->mediacatalog[2] << 4) + o->mediacatalog[3];
645  q[3] = (o->mediacatalog[4] << 4) + o->mediacatalog[5];
646  q[4] = (o->mediacatalog[6] << 4) + o->mediacatalog[7];
647  q[5] = (o->mediacatalog[8] << 4) + o->mediacatalog[9];
648  q[6] = (o->mediacatalog[10] << 4) + o->mediacatalog[11];
649  q[7] = o->mediacatalog[12] << 4;
650 
651  q[8] = 0;
652  burn_lba_to_msf(d->alba, &m, &s, &f);
653  q[9] = dec_to_bcd(f); /* abs frame */
654  break;
655  case 3:
656  c = char_to_isrc(isrc->country[0]);
657  /* top 6 bits of [1] is the first country code */
658  q[1] = c << 2;
659  c = char_to_isrc(isrc->country[1]);
660  /* bottom 2 bits of [1] is part of the second country code */
661  q[1] += (c >> 4);
662  /* top 4 bits if [2] is the rest of the second country code */
663  q[2] = c << 4;
664 
665  c = char_to_isrc(isrc->owner[0]);
666  /* bottom 4 bits of [2] is part of the first owner code */
667  q[2] += (c >> 2);
668  /* top 2 bits of [3] is the rest of the first owner code */
669  q[3] = c << 6;
670  c = char_to_isrc(isrc->owner[1]);
671  /* bottom 6 bits of [3] is the entire second owner code */
672  q[3] += c;
673  c = char_to_isrc(isrc->owner[2]);
674  /* top 6 bits of [4] are the third owner code */
675  q[4] = c << 2;
676 
677  /* [5] is the year in 2 BCD numbers */
678  q[5] = dec_to_bcd(isrc->year % 100);
679  /* [6] is the first 2 digits in the serial */
680  q[6] = dec_to_bcd(isrc->serial % 100);
681  /* [7] is the next 2 digits in the serial */
682  q[7] = dec_to_bcd((isrc->serial / 100) % 100);
683  /* the top 4 bits of [8] is the last serial digit, the rest is
684  zeros */
685  q[8] = dec_to_bcd((isrc->serial / 10000) % 10) << 4;
686  burn_lba_to_msf(d->alba, &m, &s, &f);
687  q[9] = dec_to_bcd(f); /* abs frame */
688  break;
689  }
690  q[0] = (control << 4) + qmode;
691 
692 
693 #ifdef Libburn_no_crc_C
694  crc = 0; /* dummy */
695 #else
696  crc = crc_ccitt(q, 10);
697 #endif
698 
699  q[10] = crc >> 8;
700  q[11] = crc & 0xff;
701 }
702 
703 int sector_lout(struct burn_write_opts *o, unsigned char control, int mode)
704 {
705  struct burn_drive *d = o->drive;
706  unsigned char subs[96];
707  unsigned char *data;
708 
709  data = get_sector(o, NULL, mode);
710  if (!data)
711  return 0;
712  /* ts A61010 */
713  if (convert_data(o, NULL, mode, data) <= 0)
714  return 0;
715  subcode_lout(o, control, subs);
716  convert_subs(o, mode, subs, data);
717  if (sector_headers(o, data, mode, 0) <= 0)
718  return 0;
719  sector_common(++)
720  return 1;
721 }
722 
723 int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
724 {
725  struct burn_drive *d = o->drive;
726  unsigned char subs[96];
727  unsigned char *data;
728 
729  data = get_sector(o, t, t->mode);
730  if (data == NULL)
731  return 0;
732  /* ts A61010 */
733  if (convert_data(o, t, t->mode, data) <= 0)
734  return 0;
735 
736  /* ts A61031 */
737  if ((t->open_ended || t->end_on_premature_eoi) && t->track_data_done) {
738  unget_sector(o, t->mode);
739  return 2;
740  }
741 
742  /* ts A61219 : allow track without .entry */
743  if (t->entry == NULL)
744  ;
745  else if (!t->source->read_sub)
746  subcode_user(o, subs, t->entry->point,
747  t->entry->control, 1, &t->isrc, psub);
748  else if (!t->source->read_sub(t->source, subs, 96))
749  subcode_user(o, subs, t->entry->point,
750  t->entry->control, 1, &t->isrc, psub);
751  convert_subs(o, t->mode, subs, data);
752 
753  if (sector_headers(o, data, t->mode, 0) <= 0)
754  return 0;
755  sector_common(++)
756  return 1;
757 }
758 
759 int burn_msf_to_lba(int m, int s, int f)
760 {
761  if (m < 90)
762  return (m * 60 + s) * 75 + f - 150;
763  else
764  return (m * 60 + s) * 75 + f - 450150;
765 }
766 
767 void burn_lba_to_msf(int lba, int *m, int *s, int *f)
768 {
769  if (lba >= -150) {
770  *m = (lba + 150) / (60 * 75);
771  *s = (lba + 150 - *m * 60 * 75) / 75;
772  *f = lba + 150 - *m * 60 * 75 - *s * 75;
773  } else {
774  *m = (lba + 450150) / (60 * 75);
775  *s = (lba + 450150 - *m * 60 * 75) / 75;
776  *f = lba + 450150 - *m * 60 * 75 - *s * 75;
777  }
778 }
779 
780 int dec_to_bcd(int d)
781 {
782  int top, bottom;
783 
784  top = d / 10;
785  bottom = d - (top * 10);
786  return (top << 4) + bottom;
787 }
788 
789 int sector_headers_is_ok(struct burn_write_opts *o, int mode)
790 {
791  if (mode & BURN_AUDIO) /* no headers for "audio" */
792  return 1;
793  if (o->write_type == BURN_WRITE_SAO)
794  return 1;
795 
796  /* ts A61031 */
797  if (o->write_type == BURN_WRITE_TAO)
798  return 1;
799 
800  if (mode & BURN_MODE1)
801  return 2;
802  return 0;
803 }
804 
805 /* ts A90830 : changed return type to int
806  @return 0= failure
807  1= success
808 */
809 int sector_headers(struct burn_write_opts *o, unsigned char *out,
810  int mode, int leadin)
811 {
812 
813 #ifdef Libburn_ecma130ab_includeD
814 
815  struct burn_drive *d = o->drive;
816  unsigned int crc;
817  int min, sec, frame;
818  int modebyte = -1;
819  int ret;
820 
821  ret = sector_headers_is_ok(o, mode);
822  if (ret != 2)
823  return !!ret;
824  modebyte = 1;
825 
826  out[0] = 0;
827  memset(out + 1, 0xFF, 10); /* sync */
828  out[11] = 0;
829 
830  if (leadin) {
831  burn_lba_to_msf(d->rlba, &min, &sec, &frame);
832  out[12] = dec_to_bcd(min) + 0xA0;
833  out[13] = dec_to_bcd(sec);
834  out[14] = dec_to_bcd(frame);
835  out[15] = modebyte;
836  } else {
837  burn_lba_to_msf(d->alba, &min, &sec, &frame);
838  out[12] = dec_to_bcd(min);
839  out[13] = dec_to_bcd(sec);
840  out[14] = dec_to_bcd(frame);
841  out[15] = modebyte;
842  }
843  if (mode & BURN_MODE1) {
844 
845 #ifdef Libburn_no_crc_C
846  crc = 0; /* dummy */
847 #else
848  crc = crc_32(out, 2064);
849 #endif
850 
851  out[2064] = crc & 0xFF;
852  crc >>= 8;
853  out[2065] = crc & 0xFF;
854  crc >>= 8;
855  out[2066] = crc & 0xFF;
856  crc >>= 8;
857  out[2067] = crc & 0xFF;
858  }
859  if (mode & BURN_MODE1) {
860  memset(out + 2068, 0, 8);
861  burn_rspc_parity_p(out);
862  burn_rspc_parity_q(out);
863  }
865  return 1;
866 
867 #else /* Libburn_ecma130ab_includeD */
868 
869  int ret;
870 
871  ret = sector_headers_is_ok(o, mode);
872  if (ret != 2)
873  return (!! ret);
874 
875  /* ts A90830 : lec.c is copied from cdrdao.
876  I have no idea yet how lec.c implements the Reed-Solomon encoding
877  which is described in ECMA-130 for CD-ROM.
878  So this got removed for now.
879  */
881  0x0002010a,
883  "Raw CD write modes are not supported", 0, 0);
884  return 0;
885 
886 #endif /* ! Libburn_ecma130ab_includeD */
887 
888 }
889 
890 #if 0
891 void process_q(struct burn_drive *d, unsigned char *q)
892 {
893  unsigned char i[5];
894  int mode;
895 
896  mode = q[0] & 0xF;
897 /* burn_print(12, "mode: %d : ", mode);*/
898  switch (mode) {
899  case 1:
900 /* burn_print(12, "tno = %d : ", q[1]);
901  burn_print(12, "index = %d\n", q[2]);
902 */
903  /* q[1] is the track number (starting at 1) q[2] is the index
904  number (starting at 0) */
905 #warning this is totally bogus
906  if (q[1] - 1 > 99)
907  break;
908  if (q[2] > d->toc->track[q[1] - 1].indices) {
909  burn_print(12, "new index at %d\n", d->alba);
910  d->toc->track[q[1] - 1].index[q[2]] = d->alba;
911  d->toc->track[q[1] - 1].indices++;
912  }
913  break;
914  case 2:
915  /* XXX do not ignore these */
916  break;
917  case 3:
918 /* burn_print(12, "ISRC data in mode 3 q\n");*/
919  i[0] = isrc[(q[1] << 2) >> 2];
920 /* burn_print(12, "0x%x 0x%x 0x%x 0x%x 0x%x\n", q[1], q[2], q[3], q[4], q[5]);
921  burn_print(12, "ISRC - %c%c%c%c%c\n", i[0], i[1], i[2], i[3], i[4]);
922 */
923  break;
924  default:
925 
926  /* ts A61009 : if reactivated then without Assert */
927  a ssert(0);
928  }
929 }
930 #endif
931 
932 /* this needs more info. subs in the data? control/adr? */
933 
934 /* ts A61119 : One should not use unofficial compiler extensions.
935  >>> Some day this function needs to be implemented. At least for now
936  the result does not match the "mode" of cdrecord -toc.
937  */
938 /*
939 #warning sector_identify needs to be written
940 */
941 int sector_identify(unsigned char *data)
942 {
943 
944 /*
945  burn_ecma130_scramble(data);
946 check mode byte for 1 or 2
947 test parity to see if it's a valid sector
948 if invalid, return BURN_MODE_AUDIO;
949 else return mode byte (what about mode 2 formless? heh)
950 */
951 
952  return BURN_MODE1;
953 }
unsigned int crc_32(unsigned char *, int len)
unsigned short crc_ccitt(unsigned char *, int len)
#define O_BINARY
Definition: ddlpa.c:54
void burn_print(int level, const char *a,...)
void burn_rspc_parity_p(unsigned char *sector)
Definition: ecma130ab.c:591
void burn_ecma130_scramble(unsigned char *sector)
Definition: ecma130ab.c:693
void burn_rspc_parity_q(unsigned char *sector)
Definition: ecma130ab.c:659
#define BE_CANCELLED
Definition: error.h:6
#define BURN_MODE_RAW
Definition: libburn.h:88
burn_block_types
Definition: libburn.h:192
@ BURN_BLOCK_RAW0
Definition: libburn.h:194
@ BURN_BLOCK_RAW96P
Definition: libburn.h:198
@ BURN_BLOCK_RAW16
Definition: libburn.h:196
@ BURN_BLOCK_MODE1
Definition: libburn.h:202
@ BURN_BLOCK_RAW96R
Definition: libburn.h:200
#define BURN_SUBCODE_P16
Definition: libburn.h:121
#define BURN_SUBCODE_P96
Definition: libburn.h:123
#define BURN_SUBCODE_R96
Definition: libburn.h:125
burn_write_types
Definition: libburn.h:138
@ BURN_WRITE_TAO
Definition: libburn.h:152
@ BURN_WRITE_SAO
Definition: libburn.h:163
#define BURN_MODE_BITS
Definition: libburn.h:79
#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_FATAL
Definition: libdax_msgs.h:217
#define LIBDAX_MSGS_PRIO_HIGH
Definition: libdax_msgs.h:237
#define LIBDAX_MSGS_SEV_FAILURE
Definition: libdax_msgs.h:205
int sector_headers(struct burn_write_opts *o, unsigned char *out, int mode, int leadin)
Definition: sector.c:809
int burn_msf_to_lba(int m, int s, int f)
Definition: sector.c:759
int sector_postgap(struct burn_write_opts *o, unsigned char tno, unsigned char control, int mode)
Definition: sector.c:517
int sector_write_buffer(struct burn_drive *d, struct burn_track *track, int flag)
Definition: sector.c:238
static void subcode_lout(struct burn_write_opts *o, unsigned char control, unsigned char *data)
Definition: sector.c:539
void subcode_user(struct burn_write_opts *o, unsigned char *subcodes, unsigned char tno, unsigned char control, unsigned char indx, struct isrc *isrc, int psub)
Definition: sector.c:591
int sector_pregap(struct burn_write_opts *o, unsigned char tno, unsigned char control, int mode)
Definition: sector.c:496
int sector_get_outmode(enum burn_write_types write_type, enum burn_block_types block_type)
Definition: sector.c:70
int sector_lout(struct burn_write_opts *o, unsigned char control, int mode)
Definition: sector.c:703
struct libdax_msgs * libdax_messenger
Definition: init.c:42
#define sector_common(X)
Definition: sector.c:50
int sector_headers_is_ok(struct burn_write_opts *o, int mode)
Definition: sector.c:789
int dec_to_bcd(int d)
Definition: sector.c:780
static void subcode_toc(struct burn_drive *d, int mode, unsigned char *data)
Definition: sector.c:433
static void convert_subs(struct burn_write_opts *o, int inmode, unsigned char *subs, unsigned char *sector)
Definition: sector.c:395
void burn_lba_to_msf(int lba, int *m, int *s, int *f)
Definition: sector.c:767
static int convert_data(struct burn_write_opts *o, struct burn_track *track, int inmode, unsigned char *data)
Definition: sector.c:340
static int get_outmode(struct burn_write_opts *o)
Definition: sector.c:97
static void unget_sector(struct burn_write_opts *opts, int inmode)
Definition: sector.c:313
int sector_identify(unsigned char *data)
Definition: sector.c:941
int sector_toc(struct burn_write_opts *o, int mode)
Definition: sector.c:476
static unsigned char * get_sector(struct burn_write_opts *opts, struct burn_track *track, int inmode)
Definition: sector.c:276
int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
Definition: sector.c:723
static void uncook_subs(unsigned char *dest, unsigned char *source)
Definition: sector.c:52
static char char_to_isrc(char c)
Definition: sector.c:577
static void get_bytes(struct burn_track *track, int count, unsigned char *data)
Definition: sector.c:107
void process_q(struct burn_drive *d, unsigned char *q)
unsigned char data[65536+4096]
Definition: transport.h:52
int bytes
Definition: transport.h:54
int sectors
Definition: transport.h:53
struct burn_progress progress
Definition: transport.h:395
int global_index
Definition: transport.h:200
struct buffer * buffer
Definition: transport.h:394
int toc_entries
Definition: transport.h:524
struct burn_toc_entry * toc_entry
Definition: transport.h:525
int(* write)(struct burn_drive *, int, struct buffer *)
Definition: transport.h:468
int toc_temp
Definition: transport.h:391
off_t buffered_bytes
Definition: libburn.h:702
int(* read_sub)(struct burn_source *, unsigned char *buffer, int size)
Definition: libburn.h:502
int(* read)(struct burn_source *, unsigned char *buffer, int size)
Definition: libburn.h:493
struct burn_source * next
Definition: libburn.h:540
void * data
Definition: libburn.h:557
int(* read_xt)(struct burn_source *, unsigned char *buffer, int size)
Definition: libburn.h:575
unsigned char psec
Definition: libburn.h:369
unsigned char pmin
Definition: libburn.h:367
unsigned char point
Definition: libburn.h:361
unsigned char control
Definition: libburn.h:357
unsigned char pframe
Definition: libburn.h:371
struct isrc isrc
Definition: structure.h:105
int open_ended
Definition: structure.h:74
int end_on_premature_eoi
Definition: structure.h:84
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 cdxa_conversion
Definition: structure.h:112
off_t written_sectors
Definition: structure.h:70
int index[100]
Definition: structure.h:44
int offsetcount
Definition: structure.h:48
int tail
Definition: structure.h:50
int offset
Definition: structure.h:46
int mode
Definition: structure.h:88
off_t sourcecount
Definition: structure.h:68
off_t writecount
Definition: structure.h:69
struct burn_toc_entry * entry
Definition: structure.h:38
int track_data_done
Definition: structure.h:76
int has_mediacatalog
Definition: options.h:80
enum burn_block_types block_type
Definition: options.h:25
struct burn_drive * drive
Definition: options.h:17
enum burn_write_types write_type
Definition: options.h:23
unsigned char mediacatalog[13]
Definition: options.h:81
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
int burn_track_get_sectors_2(struct burn_track *t, int flag)
Definition: structure.c:512
#define BUFFER_SIZE
Definition: transport.h:21
int burn_sector_length(int tracktype)
Definition: write.c:835
int burn_subcode_length(int tracktype)
Definition: write.c:848