1 
2 /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
3 
4    Copyright 2007-2016 Thomas Schmitt, <scdbackup@gmx.net>
5 
6    Provided under GPL version 2 or later.
7 
8    This file contains functions which manage the relation between xorriso
9    and the libraries: libburn, libisofs, libisoburn.
10 */
11 
12 #ifdef HAVE_CONFIG_H
13 #include "../config.h"
14 #endif
15 
16 #include <ctype.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/time.h>
24 #include <time.h>
25 #include <errno.h>
26 #include <pthread.h>
27 
28 #ifdef HAVE_STDINT_H
29 #include <stdint.h>
30 #else
31 #ifdef HAVE_INTTYPES_H
32 #include <inttypes.h>
33 #endif
34 #endif
35 
36 /* for -charset */
37 #include <iconv.h>
38 #include <langinfo.h>
39 
40 #ifdef Xorriso_standalonE
41 
42 #ifdef Xorriso_with_libjtE
43 #include "../libjte/libjte.h"
44 #endif
45 
46 #else
47 
48 #ifdef Xorriso_with_libjtE
49 #include <libjte/libjte.h>
50 #endif
51 
52 #endif /* ! Xorriso_standalonE */
53 
54 #include "xorriso.h"
55 #include "xorriso_private.h"
56 #include "xorrisoburn.h"
57 
58 #include "lib_mgt.h"
59 #include "iso_manip.h"
60 
61 
Xorriso_abort(struct XorrisO * xorriso,int flag)62 int Xorriso_abort(struct XorrisO *xorriso, int flag)
63 {
64  int ret;
65 
66  ret= burn_abort(4440, burn_abort_pacifier, "xorriso : ");
67  if(ret<=0) {
68    fprintf(stderr,
69        "\nxorriso : ABORT : Cannot cancel burn session and release drive.\n");
70    return(0);
71  }
72  fprintf(stderr,
73    "xorriso : ABORT : Drive is released and library is shut down now.\n");
74  fprintf(stderr,
75    "xorriso : ABORT : Program done. Even if you do not see a shell prompt.\n");
76  fprintf(stderr, "\n");
77  exit(1);
78 }
79 
80 
81 /* @param flag bit0= asynchronous handling (else catch thread, wait, and exit)
82                bit1= dealing with MMC drive in critical state
83                      behavior 2 -> behavior 1
84 */
Xorriso_set_signal_handling(struct XorrisO * xorriso,int flag)85 int Xorriso_set_signal_handling(struct XorrisO *xorriso, int flag)
86 {
87  char *handler_prefix= NULL;
88  int behavior, mode;
89 
90  behavior= Xorriso__get_signal_behavior(0);
91  if(behavior == 0)
92    return(2);
93  if(behavior == 2 && !(flag & 2))
94    mode= 1;
95  else if(behavior == 3)
96    mode= 2;
97  else
98    mode= (flag & 1) * 0x30;
99  handler_prefix= calloc(strlen(xorriso->progname)+3+1, 1);
100  if(handler_prefix==NULL) {
101    sprintf(xorriso->info_text,
102            "Cannot allocate memory for setting signal handler");
103    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
104    return(-1);
105  }
106  mode|= 256; /* Ignore SIGPIPE */
107 
108  /* <<< */
109  sprintf(xorriso->info_text, "burn_set_signal_handling(%d)", mode);
110  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
111 
112  sprintf(handler_prefix, "%s : ", xorriso->progname);
113  burn_set_signal_handling(handler_prefix, NULL, mode);
114  free(handler_prefix);
115  return(1);
116 }
117 
118 
Xorriso_startup_libraries(struct XorrisO * xorriso,int flag)119 int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag)
120 {
121  int ret, major, minor, micro;
122  char *queue_sev, *print_sev, reason[1024];
123  struct iso_zisofs_ctrl zisofs_ctrl= {0, 6, 15};
124 
125 
126 /* First an ugly compile time check for header version compatibility.
127    If everything matches, then no C code is produced. In case of mismatch,
128    intentionally faulty C code will be inserted.
129 */
130 
131 /* The minimum requirement of xorriso towards the libisoburn header
132    at compile time is defined in xorriso/xorrisoburn.h
133      xorriso_libisoburn_req_major
134      xorriso_libisoburn_req_minor
135      xorriso_libisoburn_req_micro
136    It gets compared against the version macros in libburn/libburn.h :
137      isoburn_header_version_major
138      isoburn_header_version_minor
139      isoburn_header_version_micro
140    If the header is too old then the following code shall cause failure of
141    cdrskin compilation rather than to allow production of a program with
142    unpredictable bugs or memory corruption.
143    The compiler messages supposed to appear in this case are:
144       error: 'LIBISOBURN_MISCONFIGURATION' undeclared (first use in this function)
145       error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisoburn_dot_h_TOO_OLD__SEE_xorrisoburn_dot_c' undeclared (first use in this function)
146       error: 'LIBISOBURN_MISCONFIGURATION_' undeclared (first use in this function)
147 */
148 /* The indendation is an advise of man gcc to help old compilers ignoring */
149  #if xorriso_libisoburn_req_major > isoburn_header_version_major
150  #define Isoburn_libisoburn_dot_h_too_olD 1
151  #endif
152  #if xorriso_libisoburn_req_major == isoburn_header_version_major && xorriso_libisoburn_req_minor > isoburn_header_version_minor
153  #define Isoburn_libisoburn_dot_h_too_olD 1
154  #endif
155  #if xorriso_libisoburn_req_minor == isoburn_header_version_minor && xorriso_libisoburn_req_micro > isoburn_header_version_micro
156  #define Isoburn_libisoburn_dot_h_too_olD 1
157  #endif
158 
159 #ifdef Isoburn_libisoburn_dot_h_too_olD
160 LIBISOBURN_MISCONFIGURATION = 0;
161 INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisoburn_dot_h_TOO_OLD__SEE_xorrisoburn_dot_c = 0;
162 LIBISOBURN_MISCONFIGURATION_ = 0;
163 #endif
164 
165 /* End of ugly compile time test (scroll up for explanation) */
166 
167  reason[0]= 0;
168  ret= isoburn_initialize(reason, 0);
169  if(ret==0) {
170    sprintf(xorriso->info_text, "Cannot initialize libraries");
171    if(reason[0])
172      sprintf(xorriso->info_text+strlen(xorriso->info_text),
173              ". Reason given:\n%s", reason);
174    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
175    return(0);
176  }
177  ret= isoburn_is_compatible(isoburn_header_version_major,
178                             isoburn_header_version_minor,
179                             isoburn_header_version_micro, 0);
180  if(ret<=0) {
181    isoburn_version(&major, &minor, &micro);
182    sprintf(xorriso->info_text,
183           "libisoburn version too old: %d.%d.%d . Need at least: %d.%d.%d .\n",
184           major, minor, micro,
185           isoburn_header_version_major, isoburn_header_version_minor,
186           isoburn_header_version_micro);
187    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
188    return(-1);
189  }
190 
191  xorriso->libs_are_started= 1;
192 
193  queue_sev= "ALL";
194  if(xorriso->library_msg_direct_print) {
195 
196    /* >>> need option for controlling this in XorrisO.
197           See also Xorriso_msgs_submit */;
198 
199    print_sev= xorriso->report_about_text;
200  } else
201    print_sev= "NEVER";
202 
203  iso_set_msgs_severities(queue_sev, print_sev, "libsofs : ");
204  burn_msgs_set_severities(queue_sev, print_sev, "libburn : ");
205 
206  /* ??? >>> do we want united queues ? */
207  /* burn_set_messenger(iso_get_messenger()); */
208 
209  isoburn_set_msgs_submit(Xorriso_msgs_submit_void, (void *) xorriso,
210                          (3<<2) | 128 , 0);
211 
212  ret= Xorriso_set_signal_handling(xorriso, 0);
213  if(ret <= 0)
214    return(ret);
215 
216  ret = iso_zisofs_get_params(&zisofs_ctrl, 0);
217  if (ret == 1) {
218    xorriso->zisofs_block_size= xorriso->zisofs_block_size_default=
219        (1 << zisofs_ctrl.block_size_log2);
220    xorriso->zlib_level= xorriso->zlib_level_default=
221        zisofs_ctrl.compression_level;
222  }
223 
224  iso_node_xinfo_make_clonable(Xorriso__mark_update_xinfo,
225                               Xorriso__mark_update_cloner, 0);
226 
227  /* Second initialization. This time with libs. */
228  Xorriso_preparer_string(xorriso, xorriso->preparer_id, 0);
229 
230  Xorriso_process_msg_queues(xorriso,0);
231  if(reason[0]) {
232    sprintf(xorriso->info_text, "%s", reason);
233    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
234  }
235  strcpy(xorriso->info_text, "Using ");
236  strncat(xorriso->info_text, burn_scsi_transport_id(0), 1024);
237  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
238  return(1);
239 }
240 
241 
242 /* @param flag bit0= global shutdown of libraries */
Xorriso_detach_libraries(struct XorrisO * xorriso,int flag)243 int Xorriso_detach_libraries(struct XorrisO *xorriso, int flag)
244 {
245  Xorriso_give_up_drive(xorriso, 3);
246  if(xorriso->in_volset_handle!=NULL) { /* standalone image */
247    iso_image_unref((IsoImage *) xorriso->in_volset_handle);
248    xorriso->in_volset_handle= NULL;
249    Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
250    Xorriso_destroy_di_array(xorriso, 0);
251    Xorriso_destroy_hln_array(xorriso, 0);
252    xorriso->boot_count= 0;
253  }
254  if(flag&1) {
255    if(xorriso->libs_are_started==0)
256      return(0);
257    isoburn_finish();
258 
259 #ifdef Xorriso_with_editlinE
260    Xorriso__shutdown_editline(0);
261 #endif
262 
263  }
264  return(1);
265 }
266 
267 
268 /* @param flag bit0= suppress messages below UPDATE
269                bit1= suppress messages below FAILURE
270 */
Xorriso_set_image_severities(struct XorrisO * xorriso,int flag)271 int Xorriso_set_image_severities(struct XorrisO *xorriso, int flag)
272 {
273  char *queue_sev, *print_sev;
274 
275  if(flag&2)
276    queue_sev= "FAILURE";
277  else if(flag&1)
278    queue_sev= "UPDATE";
279  else
280    queue_sev= "ALL";
281  if(xorriso->library_msg_direct_print)
282    print_sev= xorriso->report_about_text;
283  else
284    print_sev= "NEVER";
285  iso_set_msgs_severities(queue_sev, print_sev, "libisofs : ");
286  return(1);
287 }
288 
289 
290 /* @param flag bit0=prepare for a burn run */
Xorriso_set_abort_severity(struct XorrisO * xorriso,int flag)291 int Xorriso_set_abort_severity(struct XorrisO *xorriso, int flag)
292 {
293  int ret, abort_on_number;
294  char *sev_text;
295  static int note_number= -1, failure_number= -1;
296 
297  if(note_number==-1)
298    Xorriso__text_to_sev("NOTE", &note_number, 0);
299  if(failure_number==-1)
300    Xorriso__text_to_sev("FAILURE", &failure_number, 0);
301  sev_text= xorriso->abort_on_text;
302  ret= Xorriso__text_to_sev(xorriso->abort_on_text, &abort_on_number, 0);
303  if(ret<=0)
304    return(ret);
305  if(abort_on_number<note_number)
306    sev_text= "NOTE";
307  else if(abort_on_number>failure_number)
308    sev_text= "FAILURE";
309  ret= iso_set_abort_severity(sev_text);
310  return(ret>=0);
311 }
312 
313 
Xorriso_report_lib_versions(struct XorrisO * xorriso,int flag)314 int Xorriso_report_lib_versions(struct XorrisO *xorriso, int flag)
315 {
316  int major, minor, micro;
317  int req_major, req_minor, req_micro;
318 
319  iso_lib_version(&major, &minor, &micro);
320  isoburn_libisofs_req(&req_major, &req_minor, &req_micro);
321  sprintf(xorriso->result_line,
322          "libisofs   in use :  %d.%d.%d  (min. %d.%d.%d)\n",
323          major, minor, micro, req_major, req_minor, req_micro);
324  Xorriso_result(xorriso, 0);
325 
326 #ifdef Xorriso_with_libjtE
327  libjte__version(&major, &minor, &micro);
328  isoburn_libjte_req(&req_major, &req_minor, &req_micro);
329  sprintf(xorriso->result_line,
330          "libjte     in use :  %d.%d.%d  (min. %d.%d.%d)\n",
331          major, minor, micro, req_major, req_minor, req_micro);
332  Xorriso_result(xorriso, 0);
333 #endif
334 
335  burn_version(&major, &minor, &micro);
336  isoburn_libburn_req(&req_major, &req_minor, &req_micro);
337  sprintf(xorriso->result_line,
338          "libburn    in use :  %d.%d.%d  (min. %d.%d.%d)\n",
339          major, minor, micro, req_major, req_minor, req_micro);
340  Xorriso_result(xorriso, 0);
341  strcpy(xorriso->result_line, "libburn OS adapter:  ");
342  strncat(xorriso->result_line, burn_scsi_transport_id(0), 1024);
343  strcat(xorriso->result_line, "\n");
344  Xorriso_result(xorriso, 0);
345  isoburn_version(&major, &minor, &micro);
346  sprintf(xorriso->result_line,
347          "libisoburn in use :  %d.%d.%d  (min. %d.%d.%d)\n",
348          major, minor, micro,
349          isoburn_header_version_major, isoburn_header_version_minor,
350          isoburn_header_version_micro);
351  Xorriso_result(xorriso, 0);
352  return(1);
353 }
354 
355 
Xorriso__sev_to_text(int severity,char ** severity_name,int flag)356 int Xorriso__sev_to_text(int severity, char **severity_name,
357                          int flag)
358 {
359  int ret;
360 
361  ret= iso_sev_to_text(severity, severity_name);
362  if(ret>0)
363    return(ret);
364  ret= burn_sev_to_text(severity, severity_name, 0);
365  if(ret>0)
366    return(ret);
367  *severity_name= "";
368  return(0);
369 }
370 
371 
Xorriso__text_to_sev(char * severity_name,int * severity_number,int flag)372 int Xorriso__text_to_sev(char *severity_name, int *severity_number, int flag)
373 {
374  int ret= 1;
375  char severity[20];
376 
377  Xorriso__to_upper(severity_name, severity, (int) sizeof(severity), 0);
378  ret= iso_text_to_sev(severity, severity_number);
379  if(ret>0)
380    return(ret);
381  ret= burn_text_to_sev(severity, severity_number, 0);
382  return(ret);
383 }
384 
385 
Xorriso__severity_cmp(char * sev1,char * sev2)386 int Xorriso__severity_cmp(char *sev1, char *sev2)
387 {
388  int s1= 0x7fffffff, s2= 0x7fffffff, ret;
389  char *default_sev= "FATAL";
390 
391  ret= Xorriso__text_to_sev(sev1, &s1, 0);
392  if(ret <= 0)
393    Xorriso__text_to_sev(default_sev, &s1, 0);
394  ret= Xorriso__text_to_sev(sev2, &s2, 0);
395  if(ret <= 0)
396    Xorriso__text_to_sev(default_sev, &s2, 0);
397  if(s1 < s2)
398    return -1;
399  if(s1 > s2)
400    return(1);
401  return(0);
402 }
403 
404 
Xorriso__severity_list(int flag)405 char *Xorriso__severity_list(int flag)
406 {
407  return(burn_list_sev_texts(0));
408 }
409 
410 
411 /* @param flag bit0= report libisofs error text
412                bit1= victim is disk_path
413                bit2= do not inquire libisofs, report msg_text and min_severity
414 */
Xorriso_report_iso_error(struct XorrisO * xorriso,char * victim,int iso_error_code,char msg_text[],int os_errno,char min_severity[],int flag)415 int Xorriso_report_iso_error(struct XorrisO *xorriso, char *victim,
416                         int iso_error_code, char msg_text[], int os_errno,
417                         char min_severity[], int flag)
418 {
419  int error_code, iso_sev, min_sev, ret;
420  char *sev_text_pt, *msg_text_pt= NULL;
421  char *sfe= NULL;
422  static int sorry_sev= -1;
423 
424  Xorriso_alloc_meM(sfe, char, 6 * SfileadrL);
425 
426  if(sorry_sev<0)
427    Xorriso__text_to_sev("SORRY", &sorry_sev, 0);
428 
429  if(flag&4) {
430    error_code= 0x00050000;
431    Xorriso__text_to_sev(min_severity, &iso_sev, 0);
432  } else {
433    error_code= iso_error_get_code(iso_error_code);
434    if(error_code < 0x00030000 || error_code >= 0x00040000)
435      error_code= (error_code & 0xffff) | 0x00050000;
436    if(flag&1)
437      msg_text_pt= (char *) iso_error_to_msg(iso_error_code);
438    iso_sev= iso_error_get_severity(iso_error_code);
439  }
440  if(msg_text_pt==NULL)
441    msg_text_pt= msg_text;
442 
443  if(iso_sev >= sorry_sev && (flag & 2) && victim[0])
444    Xorriso_msgs_submit(xorriso, 0, victim, 0, "ERRFILE", 0);
445  sev_text_pt= min_severity;
446  Xorriso__text_to_sev(min_severity, &min_sev, 0);
447  if(min_sev < iso_sev && !(flag&4))
448    Xorriso__sev_to_text(iso_sev, &sev_text_pt, 0);
449  strcpy(sfe, msg_text_pt);
450  if(victim[0]) {
451    strcat(sfe, ": ");
452    Text_shellsafe(victim, sfe+strlen(sfe), 0);
453  }
454  ret= Xorriso_msgs_submit(xorriso, error_code, sfe, os_errno, sev_text_pt, 4);
455 ex:;
456  Xorriso_free_meM(sfe);
457  return(ret);
458 }
459 
460 
Xorriso_get_local_charset(struct XorrisO * xorriso,char ** name,int flag)461 int Xorriso_get_local_charset(struct XorrisO *xorriso, char **name, int flag)
462 {
463  (*name)= iso_get_local_charset(0);
464  return(1);
465 }
466 
467 
Xorriso_set_local_charset(struct XorrisO * xorriso,char * name,int flag)468 int Xorriso_set_local_charset(struct XorrisO *xorriso, char *name, int flag)
469 {
470  int ret;
471  char *nl_charset;
472  iconv_t iconv_ret= (iconv_t) -1;
473 
474  nl_charset= nl_langinfo(CODESET);
475  if(name == NULL)
476    name= nl_charset;
477  if(name == NULL)
478    goto cannot;
479 
480  iconv_ret= iconv_open(nl_charset, name);
481  if(iconv_ret == (iconv_t) -1)
482    goto cannot;
483  else
484    iconv_close(iconv_ret);
485  ret= iso_set_local_charset(name, 0);
486  if(ret <= 0) {
487 cannot:;
488    sprintf(xorriso->info_text,
489            "-local_charset: Cannot assume as local character set: ");
490    if(name != NULL)
491      Text_shellsafe(name, xorriso->info_text, 1);
492    else
493      Text_shellsafe("(NULL-pointer)", xorriso->info_text, 1);
494    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
495    return(0);
496  }
497  sprintf(xorriso->info_text, "Local character set is now assumed as: ");
498  Text_shellsafe(name, xorriso->info_text, 1);
499  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
500  return(1);
501 }
502 
503 
Xorriso_process_msg_queues(struct XorrisO * xorriso,int flag)504 int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag)
505 {
506  int ret, error_code= 0, os_errno= 0, count= 0, pass, imgid, tunneled;
507  int name_prefix_code;
508  char severity[80], *text= NULL;
509 
510 #ifdef Xorriso_fetch_with_msg_queueS
511  int locked= 0, uret;
512 #endif
513 
514 #ifdef Xorriso_with_libjtE
515  char *msg;
516 #endif
517 
518  if(!xorriso->libs_are_started) {
519    ret= 1; goto ex;
520  }
521 
522 #ifdef Xorriso_fetch_with_msg_queueS
523 
524  Xorriso_alloc_meM(text, char, sizeof(xorriso->info_text));
525 
526  ret= pthread_mutex_lock(&(xorriso->lib_msg_queue_lock));
527  if(ret != 0) {
528    Xorriso_msgs_submit(xorriso, 0,
529              "Cannot acquire mutex lock for processing library message queues",
530                ret, "FATAL", 0);
531  } else
532    locked= 1;
533 
534 #else /* Xorriso_fetch_with_msg_queueS */
535 
536  text= xorriso->info_text;
537 
538 #endif /* ! Xorriso_fetch_with_msg_queueS */
539 
540 
541  for(pass= 0; pass< 3; pass++) {
542    while(1) {
543      tunneled= 0;
544      if(pass==0) {
545 #ifdef Xorriso_with_libjtE
546        ret= 0;
547        if(xorriso->libjte_handle != NULL) {
548          msg= libjte_get_next_message(xorriso->libjte_handle);
549          if(msg != NULL) {
550            sprintf(text, "%1.4095s", msg);
551            free(msg);
552            strcpy(severity, "NOTE");
553            error_code= 0;
554            os_errno= 0;
555            ret= 1;
556          }
557        }
558 #else
559    break;
560 #endif /* ! Xorriso_with_libjtE */
561 
562      } else if(pass==1)
563        ret= iso_obtain_msgs("ALL", &error_code, &imgid, text, severity);
564      else {
565        ret= burn_msgs_obtain("ALL", &error_code, text, &os_errno, severity);
566        if((error_code>=0x00030000 && error_code<0x00040000) ||
567           (error_code>=0x00050000 && error_code<0x00060000))
568          tunneled= -1; /* "libisofs:" */
569        else if(error_code>=0x00060000 && error_code<0x00070000)
570          tunneled= 1;  /* "libisoburn:" */
571      }
572      if(ret<=0)
573    break;
574 
575      /* <<< tunneled MISHAP from libisoburn through libburn
576             or well known error codes of MISHAP events
577             With libburn-0.4.4 this is not necessary */
578      if(error_code==0x5ff73 || error_code==0x3ff73 ||
579         error_code==0x3feb9 || error_code==0x3feb2)
580        strcpy(severity, "MISHAP");
581      else if(error_code==0x51001)
582        strcpy(severity, "ERRFILE");
583 
584 #ifdef Xorriso_with_libjtE
585      if(pass == 0)
586        name_prefix_code= 0;
587      else
588        name_prefix_code= pass + tunneled;
589 #else
590      name_prefix_code= pass + tunneled;
591 #endif /* Xorriso_with_libjtE */
592      Xorriso_msgs_submit(xorriso, error_code, text, os_errno,
593                          severity, name_prefix_code << 2);
594      count++;
595    }
596  }
597  if(xorriso->library_msg_direct_print && count>0) {
598    sprintf(text,"   (%d library messages repeated by xorriso)\n", count);
599 
600 #ifdef Xorriso_fetch_with_msg_queueS
601 
602    Xorriso_msgs_submit(xorriso, 0, text, 0, "NOTE", 256);
603 
604 #else /* Xorriso_fetch_with_msg_queueS */
605 
606    Xorriso_info(xorriso, 0);
607 
608 #endif /* Xorriso_fetch_with_msg_queueS */
609 
610  }
611  ret= 1;
612 ex:;
613 
614 #ifdef Xorriso_fetch_with_msg_queueS
615 
616  if(locked) {
617    uret= pthread_mutex_unlock(&(xorriso->lib_msg_queue_lock));
618    if(uret != 0) {
619      Xorriso_msgs_submit(xorriso, 0,
620              "Cannot release mutex lock for processing library message queues",
621               uret, "FATAL", 0);
622      ret= -1;
623    }
624  }
625  Xorriso_free_meM(text);
626 
627 #endif /* Xorriso_fetch_with_msg_queueS */
628 
629  return(ret);
630 }
631 
632 
Xorriso_md5_start(struct XorrisO * xorriso,void ** ctx,int flag)633 int Xorriso_md5_start(struct XorrisO *xorriso, void **ctx, int flag)
634 {
635  int ret;
636 
637  ret= iso_md5_start(ctx);
638  if(ret == 1)
639    return(1);
640  Xorriso_no_malloc_memory(xorriso, NULL, 0);
641  return(-1);
642 }
643 
644 
Xorriso_md5_compute(struct XorrisO * xorriso,void * ctx,char * data,int datalen,int flag)645 int Xorriso_md5_compute(struct XorrisO *xorriso, void *ctx,
646                         char *data, int datalen, int flag)
647 {
648  iso_md5_compute(ctx, data, datalen);
649  return(1);
650 }
651 
652 
Xorriso_md5_end(struct XorrisO * xorriso,void ** ctx,char md5[16],int flag)653 int Xorriso_md5_end(struct XorrisO *xorriso, void **ctx, char md5[16],
654                     int flag)
655 {
656  int ret;
657 
658  ret= iso_md5_end(ctx, md5);
659  Xorriso_process_msg_queues(xorriso,0);
660  if(ret <= 0)
661    return(0);
662  return(1);
663 }
664 
665 
666 /* @param flag  bit0= avoid library calls
667  */
Xorriso_preparer_string(struct XorrisO * xorriso,char xorriso_id[129],int flag)668 int Xorriso_preparer_string(struct XorrisO *xorriso, char xorriso_id[129],
669                             int flag)
670 {
671  int major, minor, micro;
672 
673  xorriso_id[0]= 0;
674  sprintf(xorriso_id, "XORRISO-%d.%d.%d ",
675          Xorriso_header_version_majoR, Xorriso_header_version_minoR,
676          Xorriso_header_version_micrO);
677  if(strlen(xorriso_id) + strlen(Xorriso_timestamP) < 128)
678    strcat(xorriso_id, Xorriso_timestamP);
679  if(flag & 1)
680    return(1);
681  isoburn_version(&major, &minor, &micro);
682  if(strlen(xorriso_id) < 100)
683    sprintf(xorriso_id + strlen(xorriso_id),
684            ", LIBISOBURN-%d.%d.%d", major, minor, micro);
685  iso_lib_version(&major, &minor, &micro);
686  if(strlen(xorriso_id) < 100)
687    sprintf(xorriso_id + strlen(xorriso_id),
688            ", LIBISOFS-%d.%d.%d", major, minor, micro);
689  burn_version(&major, &minor, &micro);
690  if(strlen(xorriso_id) < 100)
691    sprintf(xorriso_id + strlen(xorriso_id),
692            ", LIBBURN-%d.%d.%d", major, minor, micro);
693  return(1);
694 }
695 
696 
697 #ifdef Xorriso_with_libjtE
698 
Xorriso_assert_jte_handle(struct XorrisO * xorriso,int flag)699 int Xorriso_assert_jte_handle(struct XorrisO *xorriso, int flag)
700 {
701  int ret;
702 
703  if(xorriso->libjte_handle == NULL) {
704    ret= libjte_new(&(xorriso->libjte_handle), 0);
705    if(ret <= 0 || xorriso->libjte_handle == NULL) {
706      sprintf(xorriso->info_text,
707              "-jigdo: Failed to create libjte environment object");
708      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
709      return(-1);
710    }
711    /* no stderr, no exit() */
712    libjte_set_error_behavior(xorriso->libjte_handle, 0, 0);
713  }
714  return(1);
715 }
716 
717 #endif /* Xorriso_with_libjtE */
718 
719 
Xorriso_jigdo_interpreter(struct XorrisO * xorriso,char * aspect,char * arg,int flag)720 int Xorriso_jigdo_interpreter(struct XorrisO *xorriso, char *aspect, char *arg,
721                          int flag)
722 {
723 
724 #ifdef Xorriso_with_libjtE
725 
726  int ret, num;
727  struct libjte_env *jte;
728  char *msg = NULL;
729 
730  if(strcmp(aspect, "clear") == 0) {
731    if(xorriso->libjte_handle != NULL)
732    libjte_destroy(&(xorriso->libjte_handle));
733    Xorriso_lst_destroy_all(&(xorriso->jigdo_params), 0);
734    Xorriso_lst_destroy_all(&(xorriso->jigdo_values), 0);
735    xorriso->libjte_params_given= 0;
736    return(1);
737  }
738  ret= Xorriso_assert_jte_handle(xorriso, 0);
739  if(ret <= 0)
740    return(ret);
741  jte= xorriso->libjte_handle;
742 
743  if(strcmp(aspect, "verbose") == 0) {
744    if(strcmp(arg, "on") == 0) {
745      libjte_set_verbose(jte, 1);
746      /* Direct libjte messages to stderr, rather than message list */
747      libjte_set_error_behavior(xorriso->libjte_handle, 1, 0);
748      xorriso->libjte_params_given|= 2;
749    } else if(strcmp(arg, "off") == 0) {
750      libjte_set_verbose(jte, 0);
751      libjte_set_error_behavior(xorriso->libjte_handle, 0, 0);
752      xorriso->libjte_params_given&= ~2;
753    } else
754      goto bad_arg;
755  } else if(strcmp(aspect, "template_path") == 0 ||
756            strcmp(aspect, "-jigdo-template") == 0) {
757    ret= libjte_set_template_path(jte, arg);
758    if(ret <= 0)
759      goto jte_failed;
760    xorriso->libjte_params_given|= 4;
761  } else if(strcmp(aspect, "jigdo_path") == 0 ||
762            strcmp(aspect, "-jigdo-jigdo") == 0) {
763    ret= libjte_set_jigdo_path(jte, arg);
764    if(ret <= 0)
765      goto jte_failed;
766    xorriso->libjte_params_given|= 8;
767  } else if(strcmp(aspect, "md5_path") == 0 ||
768            strcmp(aspect, "-md5-list") == 0) {
769    ret= libjte_set_md5_path(jte, arg);
770    if(ret <= 0)
771      goto jte_failed;
772    xorriso->libjte_params_given|= 16;
773  } else if(strcmp(aspect, "min_size") == 0 ||
774            strcmp(aspect, "-jigdo-min-file-size") == 0) {
775    num= Scanf_io_size(arg, 0);
776    ret= libjte_set_min_size(jte, num);
777    if(ret <= 0)
778      goto jte_failed;
779    xorriso->libjte_params_given|= 32;
780  } else if(strcmp(aspect, "checksum_iso") == 0 ||
781            strcmp(aspect, "-checksum_algorithm_iso") == 0) {
782    ret= libjte_set_checksum_iso(jte, arg);
783    if(ret <= 0)
784      goto jte_failed;
785    xorriso->libjte_params_given|= 64;
786  } else if(strcmp(aspect, "checksum_template") == 0 ||
787            strcmp(aspect, "-checksum_algorithm_template") == 0) {
788    ret= libjte_set_checksum_template(jte, arg);
789    if(ret <= 0)
790      goto jte_failed;
791    xorriso->libjte_params_given|= 128;
792  } else if(strcmp(aspect, "compression") == 0 ||
793            strcmp(aspect, "-jigdo-template-compress") == 0) {
794    ret= libjte_set_compression(jte, arg);
795    if(ret <= 0)
796      goto jte_failed;
797    xorriso->libjte_params_given|= 256;
798  } else if(strcmp(aspect, "exclude") == 0 ||
799            strcmp(aspect, "-jigdo-exclude") == 0) {
800    ret= libjte_add_exclude(jte, arg);
801    if(ret <= 0)
802      goto jte_failed;
803    xorriso->libjte_params_given|= 512;
804  } else if(strcmp(aspect, "demand_md5") == 0 ||
805            strcmp(aspect, "-jigdo-force-md5") == 0) {
806    ret= libjte_add_md5_demand(jte, arg);
807    if(ret <= 0)
808      goto jte_failed;
809    xorriso->libjte_params_given|= 1024;
810  } else if(strcmp(aspect, "mapping") == 0 ||
811            strcmp(aspect, "-jigdo-map") == 0) {
812    ret= libjte_add_mapping(jte, arg);
813    if(ret <= 0)
814      goto jte_failed;
815    xorriso->libjte_params_given|= 2048;
816  } else {
817    sprintf(xorriso->info_text, "-jigdo: unknown aspect '%s'", aspect);
818    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
819    return(0);
820  }
821 
822  ret= Xorriso_lst_new(&(xorriso->jigdo_params), aspect, xorriso->jigdo_params,
823                       1);
824  if(ret > 0)
825    ret= Xorriso_lst_new(&(xorriso->jigdo_values), arg, xorriso->jigdo_values,
826                         1);
827  if(ret <= 0) {
828    Xorriso_no_malloc_memory(xorriso, NULL, 0);
829    return(-1);
830  }
831  Xorriso_process_msg_queues(xorriso, 0);
832  return(1);
833 
834 bad_arg:
835  sprintf(xorriso->info_text, "-jigdo %s : unknown argument '%s'", aspect, arg);
836  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
837  return(0);
838 
839 jte_failed:
840  while(1) {
841    msg= libjte_get_next_message(xorriso->libjte_handle);
842    if(msg == NULL)
843  break;
844    sprintf(xorriso->info_text, "%1.4095s", msg);
845    free(msg);
846    msg= NULL;
847    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
848  }
849  sprintf(xorriso->info_text, "Experienced libjte failure with: -jigdo %s %s",
850          aspect, arg);
851  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
852  return(0);
853 
854 #else /* Xorriso_with_libjtE */
855 
856  sprintf(xorriso->info_text,
857          "Jigdo Template Extraction was not enabled at compile time");
858  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
859  return(0);
860 
861 #endif /* ! Xorriso_with_libjtE */
862 
863 }
864 
865 
Xorriso_list_extras_result(struct XorrisO * xorriso,char * mode,char * what,int flag)866 int Xorriso_list_extras_result(struct XorrisO *xorriso, char *mode,
867                                char *what, int flag)
868 {
869  if(mode[0] != 0 && strcmp(mode, "all") != 0) {
870    if(strcmp(mode, what) != 0 &&
871       (mode[0] != '-' || strcmp(mode + 1, what) != 0))
872      return(2);
873  }
874  Xorriso_result(xorriso, 0);
875  return(1);
876 }
877 
878 
Xorriso_list_extras(struct XorrisO * xorriso,char * mode,int flag)879 int Xorriso_list_extras(struct XorrisO *xorriso, char *mode, int flag)
880 {
881  int ret;
882 
883  if(strcmp(mode, "codes") == 0) {
884    sprintf(xorriso->result_line,
885         "List of xorriso extra feature codes. Usable with or without dash.\n");
886    Xorriso_result(xorriso, 0);
887    sprintf(xorriso->result_line, "Local ACL    : -acl\n");
888    Xorriso_result(xorriso, 0);
889    sprintf(xorriso->result_line, "Local xattr  : -xattr\n");
890    Xorriso_result(xorriso, 0);
891    sprintf(xorriso->result_line, "Jigdo files  : -jigdo\n");
892    Xorriso_result(xorriso, 0);
893    sprintf(xorriso->result_line, "zisofs       : -zisofs\n");
894    Xorriso_result(xorriso, 0);
895    sprintf(xorriso->result_line, "Ext. filters : -external_filter\n");
896    Xorriso_result(xorriso, 0);
897    sprintf(xorriso->result_line, "DVD obs 64 kB: -dvd_obs\n");
898    Xorriso_result(xorriso, 0);
899    sprintf(xorriso->result_line, "Readline     : -use_readline\n");
900    Xorriso_result(xorriso, 0);
901    return(1);
902  }
903  sprintf(xorriso->result_line,
904          "List of xorriso extra features. yes = enabled , no = disabled\n");
905  Xorriso_list_extras_result(xorriso, mode, "list_extras", 0);
906 
907  ret= iso_local_attr_support(3);
908  sprintf(xorriso->result_line, "Local ACL    : %s\n", ret & 1 ? "yes" : "no");
909  Xorriso_list_extras_result(xorriso, mode, "acl", 0);
910  sprintf(xorriso->result_line, "Local xattr  : %s\n", ret & 2 ? "yes" : "no");
911  Xorriso_list_extras_result(xorriso, mode, "xattr", 0);
912 
913  sprintf(xorriso->result_line, "Jigdo files  : %s\n",
914 #ifdef Xorriso_with_libjtE
915          "yes");
916 #else
917          "no");
918 #endif
919  Xorriso_list_extras_result(xorriso, mode, "jigdo", 0);
920 
921  ret= iso_file_add_zisofs_filter(NULL, 4);
922  sprintf(xorriso->result_line, "zisofs       : %s\n", ret == 2 ? "yes" : "no");
923  Xorriso_list_extras_result(xorriso, mode, "zisofs", 0);
924 
925  sprintf(xorriso->result_line, "Ext. filters : %s\n",
926 #ifdef Xorriso_allow_external_filterS
927 #ifdef Xorriso_allow_extf_suiD
928          "yes , setuid allowed");
929 #else
930          "yes , setuid banned");
931 #endif
932 #else
933          "no");
934 #endif
935  Xorriso_list_extras_result(xorriso, mode, "external_filter", 0);
936 
937  sprintf(xorriso->result_line, "DVD obs 64 kB: %s\n",
938 #ifdef Xorriso_dvd_obs_default_64K
939          "yes");
940 #else
941          "no");
942 #endif
943  Xorriso_list_extras_result(xorriso, mode, "dvd_obs", 0);
944 
945  sprintf(xorriso->result_line, "Readline     : %s\n",
946 #ifdef Xorriso_with_editlinE
947          "yes , libedit");
948 #else
949 #ifdef Xorriso_with_readlinE
950          "yes");
951 #else
952          "no");
953 #endif
954 #endif
955  Xorriso_list_extras_result(xorriso, mode, "use_readline", 0);
956 
957  return(1);
958 }
959 
960 
961 /* @param flag bit0= set num_tiles to default value
962                bit1= set tile_blocks to default value
963 */
Xorriso_set_data_cache(struct XorrisO * xorriso,void * o,int num_tiles,int tile_blocks,int flag)964 int Xorriso_set_data_cache(struct XorrisO *xorriso, void *o,
965                            int num_tiles, int tile_blocks, int flag)
966 {
967  int ret, tiles, blocks, set_flag;
968  struct isoburn_read_opts *ropts;
969 
970  ropts= (struct isoburn_read_opts *) o;
971  if(flag & (1 | 2)) {
972    isoburn_ropt_get_data_cache(ropts, &tiles, &blocks, &set_flag, 1);
973    if(flag & 1)
974      num_tiles= tiles;
975    if(flag & 2)
976      tile_blocks= blocks;
977  }
978  ret= isoburn_ropt_set_data_cache(ropts, num_tiles, tile_blocks, 0);
979  return(ret);
980 }
981 
Xorriso_format_guid(struct XorrisO * xorriso,uint8_t guid[16],char * line,int flag)982 int Xorriso_format_guid(struct XorrisO *xorriso, uint8_t guid[16], char *line,
983                         int flag)
984 {
985  int i;
986 
987  line[0]= 0;
988  for(i= 3; i >= 0; i--)
989    sprintf(line + strlen(line), "%-2.2x", guid[i]);
990  sprintf(line + strlen(line), "-");
991  for(i= 5; i >= 4; i--)
992    sprintf(line + strlen(line), "%-2.2x", guid[i]);
993  sprintf(line + strlen(line), "-");
994  for(i= 7; i >= 6; i--)
995    sprintf(line + strlen(line), "%-2.2x", guid[i]);
996  sprintf(line + strlen(line), "-");
997  for(i= 8; i < 10; i++)
998    sprintf(line + strlen(line), "%-2.2x", guid[i]);
999  sprintf(line + strlen(line), "-");
1000  for(i= 10; i < 16; i++)
1001    sprintf(line + strlen(line), "%-2.2x", guid[i]);
1002  return(1);
1003 }
1004 
1005 
Xorriso_make_guid(struct XorrisO * xorriso,char * line,int flag)1006 int Xorriso_make_guid(struct XorrisO *xorriso, char *line, int flag)
1007 {
1008  uint8_t guid[16];
1009  int ret;
1010 
1011  iso_generate_gpt_guid(guid);
1012  ret= Xorriso_format_guid(xorriso, guid, line, 0);
1013  return(ret);
1014 }
1015 
1016