"Fossies" - the Fresh Open Source Software Archive 
Member "xorriso-1.5.4/libburn/options.c" (30 Jan 2021, 16651 Bytes) of package /linux/misc/xorriso-1.5.4.pl02.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "options.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
1.5.2_vs_1.5.4.
1
2 /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
3 Copyright (c) 2006 - 2017 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 #include "libburn.h"
12 #include "options.h"
13 #include "drive.h"
14 #include "transport.h"
15 #include "init.h"
16 #include "write.h"
17
18 /* ts A61007 */
19 /* #include <a ssert.h> */
20
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdio.h>
24
25 #include "libdax_msgs.h"
26 extern struct libdax_msgs *libdax_messenger;
27
28
29 struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
30 {
31 struct burn_write_opts *opts;
32
33 opts = calloc(1, sizeof(struct burn_write_opts));
34 if (opts == NULL) {
35 libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
36 LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
37 "Could not allocate new auxiliary object", 0, 0);
38 return NULL;
39 }
40 opts->drive = drive;
41 opts->refcount = 1;
42 opts->write_type = BURN_WRITE_TAO;
43 opts->block_type = BURN_BLOCK_MODE1;
44 opts->toc_entry = NULL;
45 opts->toc_entries = 0;
46 opts->simulate = 0;
47 opts->underrun_proof = drive->mdata->p2a_valid > 0 &&
48 drive->mdata->underrun_proof;
49 opts->perform_opc = 1;
50 opts->obs = -1;
51
52 #ifdef Libburn_dvd_always_obs_paD
53 opts->obs_pad = 1;
54 #else
55 opts->obs_pad = 0;
56 #endif
57
58 opts->start_byte = -1;
59 opts->fill_up_media = 0;
60 opts->force_is_set = 0;
61 opts->do_stream_recording = 0;
62 opts->dvd_obs_override = 0;
63 opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
64 opts->text_packs = NULL;
65 opts->num_text_packs = 0;
66 opts->no_text_pack_crc_check = 0;
67 opts->has_mediacatalog = 0;
68 opts->format = BURN_CDROM;
69 opts->multi = 0;
70 opts->control = 0;
71 return opts;
72 }
73
74 void burn_write_opts_free(struct burn_write_opts *opts)
75 {
76 if (--opts->refcount > 0)
77 return;
78 if (opts->text_packs != NULL)
79 free(opts->text_packs);
80 free(opts);
81 }
82
83 int burn_write_opts_clone(struct burn_write_opts *from,
84 struct burn_write_opts **to, int flag)
85 {
86 if (*to != NULL)
87 burn_write_opts_free(*to);
88 if (from == NULL)
89 return 1;
90 *to = calloc(1, sizeof(struct burn_write_opts));
91 if (*to == NULL) {
92 out_of_mem:;
93 libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
94 LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
95 "Out of virtual memory", 0, 0);
96 return -1;
97 }
98 memcpy(*to, from, sizeof(struct burn_write_opts));
99 (*to)->text_packs = NULL;
100 (*to)->num_text_packs = 0;
101 if (from->text_packs != NULL && from->num_text_packs > 0) {
102 (*to)->text_packs = calloc(1, from->num_text_packs * 18);
103 if ((*to)->text_packs == NULL)
104 goto out_of_mem;
105 memcpy((*to)->text_packs, from->text_packs,
106 from->num_text_packs * 18);
107 }
108 (*to)->refcount= 1;
109 return 1;
110 }
111
112 struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
113 {
114 struct burn_read_opts *opts;
115
116 opts = calloc(1, sizeof(struct burn_read_opts));
117 opts->drive = drive;
118 opts->refcount = 1;
119 opts->raw = 0;
120 opts->c2errors = 0;
121 opts->subcodes_audio = 0;
122 opts->subcodes_data = 0;
123 opts->hardware_error_recovery = 0;
124 opts->report_recovered_errors = 0;
125 opts->transfer_damaged_blocks = 0;
126 opts->hardware_error_retries = 3;
127 opts->dap_bit = 0;
128
129 return opts;
130 }
131
132 void burn_read_opts_free(struct burn_read_opts *opts)
133 {
134 if (--opts->refcount <= 0)
135 free(opts);
136 }
137
138 int burn_write_opts_set_write_type(struct burn_write_opts *opts,
139 enum burn_write_types write_type,
140 int block_type)
141 {
142 int sector_get_outmode(enum burn_write_types write_type,
143 enum burn_block_types block_type);
144 int spc_block_type(enum burn_block_types b);
145
146 /* ts A61007 */
147 if (! ( (write_type == BURN_WRITE_SAO && block_type == BURN_BLOCK_SAO)
148 || (opts->drive->block_types[write_type] & block_type) ) ) {
149 bad_combination:;
150 libdax_msgs_submit(libdax_messenger, -1, 0x00020112,
151 LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
152 "Bad combination of write_type and block_type", 0, 0);
153 return 0;
154 }
155 /* ts A61007 : obsoleting Assert in sector.c:get_outmode() */
156 if (sector_get_outmode(write_type, (enum burn_block_types) block_type)
157 == -1)
158 goto bad_combination;
159 /* ts A61007 : obsoleting Assert in spc.c:spc_block_type() */
160 if (spc_block_type((enum burn_block_types) block_type) == -1)
161 goto bad_combination;
162
163 opts->write_type = write_type;
164 opts->block_type = block_type;
165 return 1;
166
167 /* a ssert(0); */
168 }
169
170 void burn_write_opts_set_toc_entries(struct burn_write_opts *opts, int count,
171 struct burn_toc_entry *toc_entries)
172 {
173 opts->toc_entries = count;
174 opts->toc_entry = calloc(count, sizeof(struct burn_toc_entry));
175 memcpy(opts->toc_entry, &toc_entries,
176 sizeof(struct burn_toc_entry) * count);
177 }
178
179 void burn_write_opts_set_format(struct burn_write_opts *opts, int format)
180 {
181 opts->format = format;
182 }
183
184 int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim)
185 {
186 opts->simulate = !!sim;
187 return 1;
188 }
189
190 int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
191 int underrun_proof)
192 {
193 if (opts->drive->mdata->p2a_valid <= 0 ||
194 opts->drive->mdata->underrun_proof) {
195 opts->underrun_proof = underrun_proof;
196 return 1;
197 }
198 return 0;
199 }
200
201 void burn_write_opts_set_perform_opc(struct burn_write_opts *opts, int opc)
202 {
203 opts->perform_opc = opc;
204 }
205
206 void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
207 int has_mediacatalog)
208 {
209 opts->has_mediacatalog = has_mediacatalog;
210 }
211
212 void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
213 unsigned char mediacatalog[13])
214 {
215 memcpy(opts->mediacatalog, mediacatalog, 13);
216 }
217
218
219 /* ts A61106 */
220 void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi)
221 {
222 opts->multi = !!multi;
223 }
224
225
226 /* ts B31024 */
227 /* API */
228 void burn_write_opts_set_fail21h_sev(struct burn_write_opts *opts,
229 char *severity)
230 {
231 int ret, sevno;
232
233 ret = libdax_msgs__text_to_sev(severity, &sevno, 0);
234 if (ret <= 0)
235 opts->feat21h_fail_sev = 0;
236 else
237 opts->feat21h_fail_sev = sevno;
238 }
239
240
241 /* ts B11204 */
242 /* @param flag bit0=do not verify checksums
243 bit1= repair mismatching checksums
244 bit2= repair checksums if they are 00 00 with each pack
245 */
246 int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
247 unsigned char *text_packs,
248 int num_packs, int flag)
249 {
250 int ret;
251 unsigned char *pack_buffer = NULL;
252
253 if (num_packs > Libburn_leadin_cdtext_packs_maX ) {
254 libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
255 0x0002018b,
256 LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
257 "Too many CD-TEXT packs", 0, 0);
258 ret= 0; goto ex;
259 }
260
261 if (num_packs > 0)
262 BURN_ALLOC_MEM(pack_buffer, unsigned char, num_packs * 18);
263
264 if (opts->text_packs != NULL) {
265 free(opts->text_packs);
266 opts->text_packs = NULL;
267 }
268
269 if (flag & 1) {
270 opts->no_text_pack_crc_check = 1;
271 } else {
272 opts->no_text_pack_crc_check = 0;
273 ret = burn_cdtext_crc_mismatches(text_packs, num_packs,
274 (flag >> 1) & 3);
275 if (ret > 0) {
276 libdax_msgs_submit(libdax_messenger, -1, 0x0002018f,
277 LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
278 "CD-TEXT pack CRC mismatch", 0, 0);
279 ret = 0; goto ex;
280 } else if (ret < 0) {
281 libdax_msgs_submit(libdax_messenger, -1, 0x00020190,
282 LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
283 "CD-TEXT pack CRC mismatch had to be corrected",
284 0, 0);
285 }
286 }
287
288 if (num_packs > 0) {
289 memcpy(pack_buffer, text_packs, num_packs * 18);
290 opts->text_packs = pack_buffer;
291 pack_buffer = NULL;
292 }
293 opts->num_text_packs = num_packs;
294 ret = 1;
295 ex:;
296 BURN_FREE_MEM(pack_buffer);
297 return ret;
298 }
299
300
301 /* ts A61222 */
302 void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
303 {
304 opts->start_byte = value;
305 }
306
307
308 /* ts A70207 API */
309 /** @param flag Bitfield for control purposes:
310 bit0= do not choose type but check the one that is already set
311 bit1= do not issue error messages via burn_msgs queue
312 */
313 enum burn_write_types burn_write_opts_auto_write_type(
314 struct burn_write_opts *opts, struct burn_disc *disc,
315 char reasons[BURN_REASONS_LEN], int flag)
316 {
317 struct burn_multi_caps *caps = NULL;
318 struct burn_drive *d = opts->drive;
319 struct burn_disc_mode_demands demands;
320 enum burn_write_types wt;
321 int ret, would_do_sao = 0;
322 char *reason_pt;
323
324 reasons[0] = 0;
325
326 if (burn_drive_get_bd_r_pow(d)) {
327 strcat(reasons,
328 "MEDIA: unsuitable BD-R Pseudo Overwrite formatting, ");
329 return BURN_WRITE_NONE;
330 }
331 if (d->status != BURN_DISC_BLANK &&
332 d->status != BURN_DISC_APPENDABLE){
333 if (d->status == BURN_DISC_FULL)
334 strcat(reasons, "MEDIA: closed or not recordable, ");
335 else
336 strcat(reasons,"MEDIA: no writeable media detected, ");
337 if (!(flag & 3))
338 libdax_msgs_submit(libdax_messenger, d->global_index,
339 0x0002013a,
340 LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
341 "No suitable media detected", 0, 0);
342 return BURN_WRITE_NONE;
343 }
344 ret = burn_disc_get_write_mode_demands(disc, opts, &demands,
345 !!opts->fill_up_media);
346 if (ret <= 0) {
347 strcat(reasons, "cannot recognize job demands, ");
348 {wt = BURN_WRITE_NONE; goto ex;}
349 }
350 if (demands.exotic_track && !d->current_is_cd_profile) {
351 if (demands.audio)
352 strcat(reasons, "audio track prohibited by non-CD, ");
353 else
354 strcat(reasons, "exotic track prohibited by non-CD, ");
355 {wt = BURN_WRITE_NONE; goto ex;}
356 }
357 if ((flag & 1) && opts->write_type != BURN_WRITE_SAO)
358 goto try_tao;
359 reason_pt = reasons + strlen(reasons);
360 strcat(reasons, "SAO: ");
361 if (d->status != BURN_DISC_BLANK) {
362 strcat(reasons, "write type SAO works only on blank media, ");
363 goto try_tao;
364 }
365 burn_disc_free_multi_caps(&caps);
366 ret = burn_disc_get_multi_caps(d, BURN_WRITE_SAO, &caps, 0);
367 if (ret < 0) {
368 no_caps:;
369 strcat(reasons, "cannot inquire write mode capabilities, ");
370 {wt = BURN_WRITE_NONE; goto ex;}
371 } else if (ret == 0) {
372 strcat(reasons, "no SAO offered by drive and media, ");
373 goto no_sao;
374 }
375 if ((opts->multi || demands.multi_session) &&
376 !caps->multi_session)
377 strcat(reasons, "multi session capability lacking, ");
378 if (demands.will_append)
379 strcat(reasons, "appended session capability lacking, ");
380 if (demands.multi_track && !caps->multi_track)
381 strcat(reasons, "multi track capability lacking, ");
382 if (demands.unknown_track_size == 1 &&
383 (caps->might_do_sao == 1 || caps->might_do_sao == 3))
384 strcat(reasons, "track size unpredictable, ");
385 if (demands.mixed_mode)
386 strcat(reasons, "tracks of different modes mixed, ");
387 if (demands.exotic_track && !d->current_is_cd_profile)
388 strcat(reasons, "non-data track on non-cd, ");
389 else if (d->current_is_cd_profile)
390 if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
391 demands.block_types)
392 strcat(reasons, "drive dislikes block type, ");
393 if (d->current_is_cd_profile && opts->fill_up_media)
394 strcat(reasons, "cd sao cannot do media fill up yet, ");
395 if (strcmp(reason_pt, "SAO: ") != 0)
396 goto no_sao;
397 would_do_sao = 1;
398 if (demands.unknown_track_size == 2 && (!(flag & 1)) &&
399 (caps->might_do_sao == 1 || caps->might_do_sao == 3)) {
400 strcat(reasons, "would have to use default track sizes, ");
401 goto no_sao;
402 } else if (caps->might_do_sao >= 3 && !(flag & 1))
403 goto try_tao;
404 do_sao:;
405 if (caps->might_simulate == 0 && opts->simulate && !opts->force_is_set)
406 goto no_simulate;
407 if (!(flag & 1))
408 burn_write_opts_set_write_type(
409 opts, BURN_WRITE_SAO, BURN_BLOCK_SAO);
410 {wt = BURN_WRITE_SAO; goto ex;}
411 no_sao:;
412 try_tao:;
413 if (opts->num_text_packs > 0) {
414 strcat(reasons, "CD-TEXT: write type SAO required, ");
415 {wt = BURN_WRITE_NONE; goto ex;}
416 }
417 if ((flag & 1) && opts->write_type != BURN_WRITE_TAO)
418 goto try_raw;
419 reason_pt = reasons + strlen(reasons);
420 strcat(reasons, "TAO: ");
421 burn_disc_free_multi_caps(&caps);
422 ret = burn_disc_get_multi_caps(d, BURN_WRITE_TAO, &caps, 0);
423 if (ret < 0)
424 goto no_caps;
425 if (ret == 0) {
426 strcat(reasons, "no TAO offered by drive and media, ");
427 goto no_tao;
428 }
429 if ((opts->multi || demands.multi_session) && !caps->multi_session)
430 strcat(reasons, "multi session capability lacking, ");
431 if (demands.multi_track && !caps->multi_track)
432 strcat(reasons, "multi track capability lacking, ");
433 if (demands.exotic_track && !d->current_is_cd_profile)
434 strcat(reasons, "non-data track on non-cd, ");
435 if (d->current_is_cd_profile && !opts->force_is_set)
436 if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
437 demands.block_types)
438 strcat(reasons, "drive dislikes block type, ");
439 if (strcmp(reason_pt, "TAO: ") != 0)
440 goto no_tao;
441 /* ( TAO data/audio block size will be handled automatically ) */
442 if (caps->might_simulate == 0 && opts->simulate && !opts->force_is_set)
443 goto no_simulate;
444 if (!(flag & 1))
445 burn_write_opts_set_write_type(
446 opts, BURN_WRITE_TAO, BURN_BLOCK_MODE1);
447 {wt = BURN_WRITE_TAO; goto ex;}
448 no_tao:;
449 if (would_do_sao && !(flag & 1))
450 goto do_sao;
451 if (!d->current_is_cd_profile)
452 goto no_write_mode;
453 try_raw:;
454 if ((flag & 1) && opts->write_type != BURN_WRITE_RAW)
455 goto no_write_mode;
456
457 if (!(flag & 1)) /* For now: no automatic raw write modes */
458 goto no_write_mode;
459
460 reason_pt = reasons + strlen(reasons);
461 strcat(reasons, "RAW: ");
462 if (!d->current_is_cd_profile)
463 strcat(reasons, "write type RAW prohibited by non-cd, ");
464 else if (d->status != BURN_DISC_BLANK)
465 strcat(reasons, "write type RAW works only on blank media, ");
466 else if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
467 demands.block_types)
468 strcat(reasons, "drive dislikes block type, ");
469 if (strcmp(reason_pt, "RAW: ") != 0)
470 goto no_write_mode;
471 if (!opts->force_is_set)
472 goto no_simulate;
473
474 /* For now: no setting of raw write modes */
475
476 {wt = BURN_WRITE_RAW; goto ex;}
477
478 no_write_mode:;
479 {wt = BURN_WRITE_NONE; goto ex;}
480
481 no_simulate:;
482 strcat(reasons,
483 "simulation of write job not supported by drive and media, ");
484 {wt = BURN_WRITE_NONE; goto ex;}
485
486 ex:;
487 burn_disc_free_multi_caps(&caps);
488 if (wt == BURN_WRITE_NONE && !(flag & 3)) {
489 libdax_msgs_submit(libdax_messenger, d->global_index,
490 0x0002012b,
491 LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
492 "Drive offers no suitable write mode with this job",
493 0, 0);
494 }
495 return wt;
496 }
497
498
499 /* ts A70213 : new API function */
500 void burn_write_opts_set_fillup(struct burn_write_opts *opts,int fill_up_media)
501 {
502 opts->fill_up_media = !!fill_up_media;
503 return;
504 }
505
506
507 /* ts A70303: API */
508 void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force)
509 {
510 opts->force_is_set = !!use_force;
511 }
512
513
514 /* ts A80412: API */
515 void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
516 int value)
517 {
518 opts->do_stream_recording = value;
519 }
520
521
522 /* ts A91115: API */
523 void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs)
524 {
525 if (obs != 0 && obs != 32 * 1024 && obs != 64 * 1024)
526 return;
527 opts->dvd_obs_override = obs;
528 }
529
530
531 /* ts B20406: API */
532 void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad)
533 {
534 opts->obs_pad = 2 * !!pad;
535 }
536
537
538 /* ts A91115: API */
539 void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rhythm)
540 {
541 if (rhythm == -1)
542 opts->stdio_fsync_size = -1; /* never */
543 else if (rhythm == 0)
544 opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
545 else if (rhythm == 1)
546 opts->stdio_fsync_size = 0; /* only at end of writing */
547 else if (rhythm >= 32)
548 opts->stdio_fsync_size = rhythm;
549 }
550
551
552 /* ts A70901: API */
553 struct burn_drive *burn_write_opts_get_drive(struct burn_write_opts *opts)
554 {
555 return opts->drive;
556 }
557
558
559 void burn_read_opts_set_raw(struct burn_read_opts *opts, int raw)
560 {
561 opts->raw = raw;
562 }
563
564 void burn_read_opts_set_c2errors(struct burn_read_opts *opts, int c2errors)
565 {
566 opts->c2errors = c2errors;
567 }
568
569 void burn_read_opts_read_subcodes_audio(struct burn_read_opts *opts,
570 int subcodes_audio)
571 {
572 opts->subcodes_audio = subcodes_audio;
573 }
574
575 void burn_read_opts_read_subcodes_data(struct burn_read_opts *opts,
576 int subcodes_data)
577 {
578 opts->subcodes_data = subcodes_data;
579 }
580
581 void burn_read_opts_set_hardware_error_recovery(struct burn_read_opts *opts,
582 int hardware_error_recovery)
583 {
584 opts->hardware_error_recovery = hardware_error_recovery;
585 }
586
587 void burn_read_opts_report_recovered_errors(struct burn_read_opts *opts,
588 int report_recovered_errors)
589 {
590 opts->report_recovered_errors = report_recovered_errors;
591 }
592
593 void burn_read_opts_transfer_damaged_blocks(struct burn_read_opts *opts,
594 int transfer_damaged_blocks)
595 {
596 opts->transfer_damaged_blocks = transfer_damaged_blocks;
597 }
598
599 void burn_read_opts_set_hardware_error_retries(struct burn_read_opts *opts,
600 unsigned char
601 hardware_error_retries)
602 {
603 opts->hardware_error_retries = hardware_error_retries;
604 }
605