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 the implementation of text i/o functions.
9 */
10 
11 #ifdef HAVE_CONFIG_H
12 #include "../config.h"
13 #endif
14 
15 #include <ctype.h>
16 #include <sys/types.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <sys/stat.h>
22 #include <sys/time.h>
23 #include <time.h>
24 #include <errno.h>
25 #include <signal.h>
26 #include <pthread.h>
27 #include <fcntl.h>
28 
29 /* O_BINARY is needed for Cygwin but undefined elsewhere */
30 #ifndef O_BINARY
31 #define O_BINARY 0
32 #endif
33 
34 
35 /* for -charset */
36 #include <iconv.h>
37 #include <langinfo.h>
38 #include <locale.h>
39 
40 
41 #ifdef Xorriso_with_readlinE
42 #ifdef Xorriso_with_old_readlinE
43 #include <readline.h>
44 #include <history.h>
45 #else /* Xorriso_with_old_readlinE */
46 #include <readline/readline.h>
47 #include <readline/history.h>
48 #endif /* ! Xorriso_with_old_readlinE */
49 #define Xorriso_with_line_editoR yes
50 #endif /* Xorriso_with_readlinE */
51 
52 #ifdef Xorriso_with_editlinE
53 #include <histedit.h>
54 #define Xorriso_with_line_editoR yes
55 #endif /* Xorriso_with_editlinE */
56 
57 
58 #include "xorriso.h"
59 #include "xorriso_private.h"
60 #include "xorrisoburn.h"
61 
62 
Xorriso_protect_stdout(struct XorrisO * xorriso,int flag)63 int Xorriso_protect_stdout(struct XorrisO *xorriso, int flag)
64 {
65  if(xorriso->dev_fd_1>=0)
66    return(2);
67  xorriso->dev_fd_1= dup(1);
68  close(1);
69  dup2(2,1);
70  return(1);
71 }
72 
73 #ifdef Xorriso_with_editlinE
74 
75 /* These have to be global and shared by all XorrisOs which might be active.
76 */
77 static EditLine *editline_handle= NULL;
78 static History *editline_history= NULL;
79 static int editline_is_initialized= 0;
80 
81 
Xorriso__editline_prompt(EditLine * el_handle)82 char *Xorriso__editline_prompt(EditLine *el_handle)
83 {
84   return "";
85 }
86 
87 
Xorriso_init_editline(struct XorrisO * xorriso,int flag)88 void Xorriso_init_editline(struct XorrisO *xorriso, int flag)
89 {
90  HistEvent ev;
91 
92  /* >>> Need mutex */
93 
94  if(editline_is_initialized != 0)
95    return;
96  editline_is_initialized= -1; /* Invalid */
97 
98  editline_handle= el_init(xorriso->progname, stdin, stdout, stderr);
99  if(editline_handle == NULL)
100    return;
101  el_set(editline_handle, EL_EDITOR, "emacs");
102  el_set(editline_handle, EL_PROMPT, &Xorriso__editline_prompt);
103 
104  editline_history= history_init();
105  if(editline_history == NULL)
106    return;
107  history(editline_history, &ev, H_SETSIZE, 1000);
108  el_set(editline_handle, EL_HIST, history, editline_history);
109 
110  editline_is_initialized= 1; /* Valid now */
111  return;
112 }
113 
114 
Xorriso__shutdown_editline(int flag)115 int Xorriso__shutdown_editline(int flag)
116 {
117  if(editline_history != NULL)
118    history_end(editline_history);
119  editline_history= NULL;
120  if(editline_handle != NULL)
121    el_end(editline_handle);
122  editline_handle= NULL;
123  editline_is_initialized= 0;
124  return(1);
125 }
126 
127 #endif /* Xorriso_with_editlinE */
128 
129 #ifdef Xorriso_with_readlinE
130 
131 /* http://lists.gnu.org/archive/html/bug-readline/2014-06/msg00005.html */
Xorriso__readline_license(int flag)132 const char *Xorriso__readline_license(int flag)
133 {
134 #ifdef RL_VERSION_MAJOR
135 #if RL_VERSION_MAJOR > 5
136 
137  return("GPLv3+");
138 
139 #endif
140 #endif
141 
142  return("GPLv2+");
143 }
144 
145 #endif /* Xorriso_with_readlinE */
146 
147 #ifdef Xorriso_with_line_editoR
148 
Xorriso_emul_readline(struct XorrisO * xorriso,int flag)149 char *Xorriso_emul_readline(struct XorrisO *xorriso, int flag)
150 {
151 
152 #ifdef Xorriso_with_editlinE
153 
154  const char *cpt;
155  int count= 0;
156  char *retpt;
157 
158  /* >>> Need mutex */
159 
160  Xorriso_init_editline(xorriso, 0);
161  if(editline_is_initialized < 0) {
162 
163    /* >>> fallback */;
164 
165  }
166 
167  cpt= el_gets(editline_handle, &count);
168  if(count == -1 || cpt == NULL)
169    return(NULL);
170  retpt= calloc(1, count + 1);
171  if(retpt == NULL)
172    return(NULL);
173  memcpy(retpt, cpt, count);
174  retpt[count]= 0;
175  return(retpt);
176 
177 #else
178 
179 #ifdef Xorriso_with_readlinE
180 
181  char *cpt;
182 
183  cpt= readline("");
184  return(cpt);
185 
186 #else
187 
188  return(NULL);
189 
190 #endif /* ! Xorriso_with_readlinE */
191 #endif /* ! Xorriso_with_editlinE */
192 }
193 
194 
Xorriso_emul_add_history(struct XorrisO * xorriso,char * line,int flag)195 void Xorriso_emul_add_history(struct XorrisO *xorriso, char *line, int flag)
196 {
197 #ifdef Xorriso_with_editlinE
198 
199  HistEvent ev;
200 
201  /* >>> Need mutex */
202 
203  Xorriso_init_editline(xorriso, 0);
204  if(editline_is_initialized < 0)
205    return;
206 
207  history(editline_history, &ev, H_ENTER, line);
208 
209 #else
210 
211 #ifdef Xorriso_with_readlinE
212 
213  add_history(line);
214 
215 #else
216 
217  /* ??? How to raise protest ? */;
218 
219 #endif /* ! Xorriso_with_readlinE */
220 #endif /* ! Xorriso_with_editlinE */
221 }
222 
223 
224 /* @param flag  bit1= do only report to fp
225 */
Xorriso_status_history(struct XorrisO * xorriso,char * filter,FILE * fp,int flag)226 int Xorriso_status_history(struct XorrisO *xorriso, char *filter, FILE *fp,
227                            int flag)
228 {
229 
230 #ifdef Xorriso_with_editlinE
231 
232  int ret, l;
233  HistEvent ev;
234  int hc, i, was_end= 0;
235  char *str= NULL;
236 
237 
238  /* >>> Need mutex */
239 
240  Xorriso_init_editline(xorriso, 0);
241  if(editline_is_initialized < 0)
242    {ret= 0; goto ex;}
243 
244  Xorriso_alloc_meM(str, char, SfileadrL);
245 
246  ret= history(editline_history, &ev, H_LAST);
247  for(hc= 0; ret != -1; hc++) {
248    ret= history(editline_history, &ev, H_PREV);
249    was_end = (strcmp(ev.str, "-end") == 0);
250  }
251  if(was_end)
252    hc--;
253  if(hc >= xorriso->status_history_max)
254    i= hc - xorriso->status_history_max;
255  else
256    i= 0;
257 
258  ret= history(editline_history, &ev, H_LAST);
259  for(; i < hc && ret != -1; i++) {
260    /* Eat newline at line end */
261    strncpy(str, ev.str, SfileadrL - 1);
262    str[SfileadrL - 1]= 0;
263    l= strlen(str);
264    if(l > 0)
265      if(str[l - 1] == '\n')
266        str[l - 1]= 0;
267 
268    sprintf(xorriso->result_line, "-history ");
269    Text_shellsafe(str, xorriso->result_line, 1);
270    strcat(xorriso->result_line, "\n");
271    Xorriso_status_result(xorriso, filter, fp, flag & 2);
272    ret= history(editline_history, &ev, H_PREV);
273  }
274  ret= 1;
275 ex:;
276  Xorriso_free_meM(str);
277  return(ret);
278 
279 #else
280 #ifdef Xorriso_with_readlinE
281 
282  HIST_ENTRY **hl;
283  int hc, i;
284 
285  hl= history_list();
286  if(hl != NULL) {
287    for(hc= 0; hl[hc] != NULL; hc++);
288    if(hc > 0)
289      if(strcmp(hl[hc-1]->line, "-end") == 0)
290        hc--;
291    if(hc >= xorriso->status_history_max)
292      i= hc - xorriso->status_history_max;
293    else
294      i= 0;
295    for(; i < hc; i++) {
296      sprintf(xorriso->result_line, "-history ");
297      Text_shellsafe(hl[i]->line, xorriso->result_line, 1);
298      strcat(xorriso->result_line, "\n");
299      Xorriso_status_result(xorriso, filter, fp, flag & 2);
300    }
301  }
302  return(1);
303 
304 #else /* Xorriso_with_readlinE */
305 
306  return(0);
307 
308 #endif /* ! Xorriso_with_readlinE */
309 #endif /* ! Xorriso_with_editlinE */
310 
311 }
312 
313 #endif /* Xorriso_with_line_editoR */
314 
315 
Xorriso_dialog_input(struct XorrisO * xorriso,char line[],int linesize,int flag)316 int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize,
317                          int flag)
318 /*
319  bit0= do not write to history
320  bit1= do not read input (but eventually write to history)
321  bit2= do not write to history line which begin with "-history:" or "-history "
322  bit3= enforce single line dialog mode
323  bit4= do not read from xorriso->buffered_dialog
324  bit5= write to history in any case (if it is enabled at compile time)
325 */
326 {
327  char **argv= NULL, *linept, *why_append= "";
328  int ret, argc= 0, base_length= 0, l, append_line;
329 #ifdef Xorriso_with_line_editoR
330  static char last_input[SfileadrL]= {""};
331  int no_history= 0;
332  char *cpt= NULL;
333 #endif /* Xorriso_with_line_editoR */
334  double tdiff;
335  struct timeval tv;
336  struct Xorriso_lsT *next_lst;
337 
338  gettimeofday(&tv, NULL);
339  tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec);
340 
341  fflush(stdout);
342  linept= line;
343 
344 #ifdef Xorriso_with_line_editoR
345  no_history= (flag & 1) || xorriso->use_stdin;
346 #endif
347 
348 get_single:;
349 
350  if(xorriso->buffered_dialog != NULL && !(flag & (16 | 2))) {
351    /* Consume next buffered line */
352    next_lst= Xorriso_lst_get_next(xorriso->buffered_dialog, 0);
353    strcpy(line, Xorriso_lst_get_text(xorriso->buffered_dialog, 0));
354    Xorriso_lst_destroy(&(xorriso->buffered_dialog), 0);
355    xorriso->buffered_dialog= next_lst;
356    goto process_single;
357  }
358 
359 #ifdef Xorriso_with_line_editoR
360 
361  if(xorriso->use_stdin || xorriso->dev_fd_1>=0 ||
362     xorriso->tolerate_stdin_eof) {
363    if(flag&2) {
364      if(flag & 32)
365        goto put_into_history;
366      {ret= 1; goto ex;}
367    }
368    if(Sfile_fgets_n(linept,linesize - base_length - 1, stdin,
369                       (xorriso->dialog == 2)) == NULL) {
370      if(xorriso->tolerate_stdin_eof)
371        {ret= -2; goto ex;}
372      /* need a very dramatic end */
373      kill(getpid(),SIGHUP);
374      {ret= -1; goto ex;}
375    }
376    goto process_single;
377  }
378  if(flag&2) {
379    cpt= NULL;
380  } else {
381    cpt= Xorriso_emul_readline(xorriso, 0);
382    if(cpt==NULL) {
383      /* need a very dramatic end */
384      kill(getpid(),SIGHUP);
385      {ret= -1; goto ex;}
386    }
387    l= strlen(cpt);
388    if(l >= linesize - base_length - 1) {
389      strncpy(linept, cpt, linesize - 1);
390      line[linesize - 1]= 0;
391      sprintf(xorriso->info_text,"Input line too long !");
392      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
393      goto new_empty;
394    } else
395      strcpy(linept, cpt);
396  }
397 
398 #else /* Xorriso_with_line_editoR */
399 
400  if(flag&2)
401    {ret= 1; goto ex;}
402  if(Sfile_fgets_n(linept, linesize - base_length - 1, stdin,
403                   (xorriso->dialog == 2)) == NULL) {
404    if(xorriso->tolerate_stdin_eof)
405      {ret= -2; goto ex;}
406    /* need a very dramatic end */
407    kill(getpid(),SIGHUP);
408    {ret= -1; goto ex;}
409  }
410 
411 #endif /* ! Xorriso_with_line_editoR */
412 
413 process_single:;
414 
415  if(xorriso->dialog == 2 && !(flag & 8)) {
416    append_line= 0;
417    if(linept != line && strcmp(linept, "@@@") == 0) {
418      sprintf(xorriso->info_text, "Incomplete input line cleared by %s",
419              linept);
420      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
421 new_empty:;
422      line[0]= 0;
423      linept= line;
424      sprintf(xorriso->info_text, "-------------------------------------\n");
425      Xorriso_info(xorriso,0);
426      sprintf(xorriso->info_text, "Enter new text for empty input line :\n");
427      Xorriso_info(xorriso,0);
428      goto get_single;
429    }
430    l= strlen(line);
431    ret= Sfile_make_argv("", line, &argc, &argv, 16);
432    if(ret < 0)
433      goto ex;
434    if(ret == 0 && !append_line) {
435      /* append a newline character */
436      if(l >= linesize - 1) {
437        sprintf(xorriso->info_text,"Input line too long !");
438        Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
439        goto new_empty;
440      }
441      line[l]= '\n';
442      line[l + 1]= 0;
443      append_line= 1;
444      why_append= "Quoted newline char";
445    }
446    if(l > 0 && !append_line)
447      if(line[l - 1] == '\\') {
448        line[l - 1]= 0;
449        append_line= 1;
450        why_append= "Trailing backslash ";
451      }
452    if(append_line) {
453      base_length= strlen(line);
454      linept= line + base_length;
455      sprintf(xorriso->info_text,
456           "---------------------------------------------------------------\n");
457      Xorriso_info(xorriso,0);
458      sprintf(xorriso->info_text,
459              "%s : Enter rest of line (or @@@ to clear it) :\n", why_append);
460      Xorriso_info(xorriso,0);
461      goto get_single;
462    }
463  }
464 
465 #ifdef Xorriso_with_line_editoR
466 
467 put_into_history:;
468  if((flag & 32) || (line[0]!=0 && strcmp(last_input,line)!=0 && !no_history)) {
469    if(!((flag&4) &&
470       (strncmp(line,"-history:",9)==0 || strncmp(line,"-history ",9)==0))) {
471      Xorriso_emul_add_history(xorriso, line, 0);
472      strncpy(last_input,line,sizeof(last_input)-1);
473      last_input[sizeof(last_input)-1]= 0;
474    }
475  }
476 
477 #endif /* Xorriso_with_line_editoR */
478 
479  ret= 1;
480 ex:;
481 
482 #ifdef Xorriso_with_line_editoR
483  if(cpt!=NULL)
484    free(cpt);
485 #endif
486 
487  gettimeofday(&tv, NULL);
488  xorriso->idle_time+= tv.tv_sec+(1.e-6*(double) tv.tv_usec)-tdiff;
489  return(ret);
490 }
491 
492 
Xorriso_request_confirmation(struct XorrisO * xorriso,int flag)493 int Xorriso_request_confirmation(struct XorrisO *xorriso, int flag)
494 /*
495  bit0= important operation going on:
496        demand confirmation of abort, only abort on @@@
497  bit1= mark '@' and '@@' by return 4
498  bit2= accept: i|n= ignore | do not remove , r|y= retry | remove , q|x= abort
499  bit3= @@@ = 'done reading' rather than 'abort'
500  bit4= in non-dialog mode return 6 rather than 1
501 */
502 /* return: <=0 error
503            1= go on | do not remove existing file
504            2= abort
505            3= redo request for confirmation
506            4= see flag bit1
507           (5= skip volume)
508            6= retry failed operation | remove existing file
509  */
510 {
511  int ret;
512  char *line= NULL, *cpt, *previous_line= NULL;
513  char *abort_req_text,*abort_really_text;
514 
515  Xorriso_alloc_meM(line, char, SfileadrL);
516  Xorriso_alloc_meM(previous_line, char, SfileadrL);
517 
518  if(!xorriso->dialog) {
519    if(flag&16)
520      {ret= 6; goto ex;}
521    {ret= 1; goto ex;}
522  }
523  if(flag&8) {
524    abort_req_text= "request to end";
525    abort_really_text= "done reading";
526  } else {
527    abort_req_text= "request to abort";
528    abort_really_text= "abort this command";
529  }
530  ret= Xorriso_dialog_input(xorriso,line, SfileadrL, 1);
531  xorriso->result_line_counter= 0;
532  xorriso->result_page_counter++;
533  if(ret<=0)
534    if(xorriso->result_page_length>0)
535      xorriso->result_page_length= -xorriso->result_page_length;
536 
537  cpt= line;
538  if(strcmp(cpt,"@@@")==0 ||
539     strcmp(cpt,"x")==0 || strcmp(cpt,"X")==0 ||
540     strcmp(cpt,"q")==0 || strcmp(cpt,"Q")==0) {
541    if(flag&1) {
542      strcpy(previous_line,cpt);
543      sprintf(xorriso->info_text,
544              "... [%s = %s registered. Really %s ? (y/n) ] ...\n",
545              cpt,abort_req_text,abort_really_text);
546      Xorriso_info(xorriso,0);
547      ret= Xorriso_dialog_input(xorriso,line, SfileadrL, 1);
548      if(ret<=0)
549        goto ex;
550      cpt= line;
551      if(strcmp(cpt,previous_line)==0 ||
552         ((*cpt=='Y' || *cpt=='y' || *cpt=='j' || *cpt=='J' || *cpt=='1') &&
553            *(cpt+1)==0)) {
554        xorriso->request_to_abort= 1;
555        sprintf(xorriso->info_text,
556                "------- ( %s confirmed )\n",abort_req_text);
557        Xorriso_info(xorriso,0);
558        {ret= 2; goto ex;}
559      }
560      sprintf(xorriso->info_text, "....... ( %s revoked )\n",abort_req_text);
561      Xorriso_info(xorriso,0);
562      {ret= 3; goto ex;}
563    }
564    xorriso->request_to_abort= 1;
565    sprintf(xorriso->info_text,
566 "----------- [%s = request to abort registered. Operation ends ] ------------\n",
567            cpt);
568    Xorriso_info(xorriso,0);
569    {ret= 2; goto ex;}
570  } else if(*cpt=='@') {
571    if(strcmp(cpt,"@@")==0) {
572      goto klammer_affe;
573 
574    } else if(strcmp(cpt,"@")==0) {
575 klammer_affe:;
576      if(xorriso->result_page_length>0)
577        xorriso->result_page_length= -xorriso->result_page_length;
578      if(flag&1) {
579        sprintf(xorriso->info_text,
580 "... [@ = prompt suppression registered. Prompting disabled temporarily ] ...\n");
581        Xorriso_info(xorriso,0);
582      }
583 
584    } else {
585      Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */
586      sprintf(xorriso->info_text,
587  "--- Unrecognized input beginning with @. Please enter something else.\n");
588      Xorriso_info(xorriso,0);
589      {ret= 3; goto ex;}
590    }
591    if(flag&2)
592      {ret= 4; goto ex;}
593    if(flag&1)
594      {ret= 3; goto ex;}
595    {ret= 1; goto ex;}
596  } else if(flag&4) {
597 
598    if(strcmp(cpt,"i")==0 || strcmp(cpt,"I")==0 ||
599       strcmp(cpt,"n")==0 || strcmp(cpt,"N")==0 ||
600       *cpt==0) {
601      {ret= 1; goto ex;}
602    } else if(strcmp(cpt,"r")==0 || strcmp(cpt,"R")==0 ||
603              strcmp(cpt,"y")==0 || strcmp(cpt,"Y")==0) {
604      {ret= 6; goto ex;}
605    } else {
606      /* >>> unknown input */
607      sprintf(xorriso->info_text,
608           "--- Please enter one of : empty line, i,n, r,y, q,x, @, @@@\n");
609      Xorriso_info(xorriso,0);
610      {ret= 3; goto ex;}
611    }
612 
613  } else if(*cpt!=0 && !(flag&1)) {
614    Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */
615    strcpy(xorriso->pending_option,cpt);
616    xorriso->request_to_abort= 1;
617    sprintf(xorriso->info_text,
618 "-------------- [ Input of option registered. Operation ends ] ---------------\n");
619    Xorriso_info(xorriso,0);
620    {ret= 2; goto ex;}
621 
622  } else if(*cpt!=0) {
623    Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */
624    sprintf(xorriso->info_text,
625            "--- Please enter one of : empty line, @, @@@\n");
626    Xorriso_info(xorriso,0);
627    {ret= 3; goto ex;}
628  }
629  ret= 1;
630 ex:;
631  Xorriso_free_meM(line);
632  Xorriso_free_meM(previous_line);
633  return(ret);
634 }
635 
636 
637 /* @param flag bit0= quoted multiline mode
638                bit1= release allocated memory and return 1
639                bit2= with bit0: warn of empty text arguments
640                bit3= deliver as single quoted text including all whitespace
641                      and without any backslash interpretation
642    @return -1=out of memory , 0=line format error , 1=ok, go on , 2=done
643 */
Xorriso_read_lines(struct XorrisO * xorriso,FILE * fp,int * linecount,int * argc,char *** argv,int flag)644 int Xorriso_read_lines(struct XorrisO *xorriso, FILE *fp, int *linecount,
645                        int *argc, char ***argv, int flag)
646 {
647  char *line= NULL, *linept, *fgot;
648  int l, base_length, append_line, ret, mem_linecount, i;
649 
650  Sfile_make_argv("", line, argc, argv, 2);
651  if(flag & 2)
652    {ret= 1; goto ex;}
653 
654  Xorriso_alloc_meM(line, char, 5 * SfileadrL + 2);
655 
656  mem_linecount= *linecount;
657  linept= line;
658  base_length= 0;
659  while(1) {
660    fgot= Sfile_fgets_n(linept, SfileadrL - base_length - 1, fp,
661                        !!(flag & (1 | 8)));
662    if(fgot == NULL) {
663      if(ferror(fp))
664        {ret= 0; goto ex;}
665      if(linept != line) {
666        sprintf(xorriso->info_text,"Open quotation mark at end of input");
667        Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
668        {ret= 0; goto ex;}
669      }
670      {ret= 2; goto ex;}
671    }
672    l= strlen(line);
673    (*linecount)++;
674    append_line= 0;
675    if(flag & 1) { /* check whether the line is incomplete yet */
676      ret= Sfile_make_argv("", line, argc, argv, 16);
677      if(ret < 0)
678        goto ex;
679      if(ret == 0 && !append_line) {
680        line[l]= '\n';
681        line[l + 1]= 0;
682        append_line= 1;
683      }
684      if(l > 0 && !append_line)
685        if(line[l - 1] == '\\') {
686          line[l - 1]= 0;
687          append_line= 1;
688        }
689    }
690    if(l >= SfileadrL) {
691      sprintf(xorriso->info_text,"Input line too long !");
692      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
693      {ret= 0; goto ex;}
694    }
695    if(!append_line)
696  break;
697    base_length= strlen(line);
698    linept= line + base_length;
699  }
700  if((flag & 1) && !(flag & 8)) {
701    ret= Sfile_make_argv("", line, argc, argv,
702                         1 | ((xorriso->bsl_interpretation & 3) << 5));
703    if(ret < 0)
704      goto ex;
705    if(flag & 4)
706      for(i= 0; i < *argc; i++) {
707        if((*argv)[i][0] == 0) {
708          sprintf(xorriso->info_text, "Empty text as quoted argument in ");
709        } else if(strlen((*argv)[i]) >= SfileadrL) {
710          (*argv)[i][SfileadrL - 1]= 0;
711          sprintf(xorriso->info_text,
712                  "Input text too long and now truncated in");
713        } else
714      continue;
715        if(mem_linecount + 1 < *linecount)
716          sprintf(xorriso->info_text + strlen(xorriso->info_text),
717                  "lines %d to %d", mem_linecount + 1, *linecount);
718        else
719          sprintf(xorriso->info_text + strlen(xorriso->info_text),
720                  "line %d", mem_linecount + 1);
721        Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
722      }
723  } else {
724    (*argv)= Smem_malloC(sizeof(char *));
725    if(*argv == NULL)
726      {ret= -1; goto ex;}
727    (*argv)[0]= strdup(line);
728    if((*argv)[0] == NULL)
729      {ret= -1; goto ex;}
730    *argc= 1;
731  }
732  ret= 1;
733 ex:;
734  Xorriso_free_meM(line);
735  return(ret);
736 }
737 
738 
Xorriso_predict_linecount(struct XorrisO * xorriso,char * line,int * linecount,int flag)739 int Xorriso_predict_linecount(struct XorrisO *xorriso, char *line,
740                               int *linecount, int flag)
741 {
742  int width,l;
743  char *spt,*ept;
744 
745  *linecount= 0;
746  spt= line;
747  width= xorriso->result_page_width;
748  while(1) {
749    ept= strchr(spt,'\n');
750    if(ept==NULL)
751      l= strlen(spt);
752    else
753      l= ept-spt;
754    l+= xorriso->result_open_line_len;
755    if(ept!=NULL && l==0)
756      (*linecount)++;
757    else {
758      (*linecount)+= l/width;
759      if(ept==NULL) {
760        xorriso->result_open_line_len= l%width;
761  break;
762      }
763      (*linecount)+= !!(l%width);
764    }
765    xorriso->result_open_line_len= 0;
766    spt= ept+1;
767  }
768  return(1);
769 }
770 
771 
Xorriso_pager(struct XorrisO * xorriso,char * line,int flag)772 int Xorriso_pager(struct XorrisO *xorriso, char *line, int flag)
773 /*
774  bit1= mark '@' by return 4
775 */
776 /* return: <=0 error , 1=go on , 2=abort , 4=see flag bit1*/
777 {
778  int ret,linecount;
779  char *info_text= NULL;
780 
781  if(xorriso->result_page_length<=0 || xorriso->request_not_to_ask ||
782     xorriso->dialog == 0)
783    {ret= 1; goto ex;}
784  Xorriso_predict_linecount(xorriso,line,&linecount,0);
785  if(xorriso->result_line_counter+linecount>xorriso->result_page_length) {
786 ask_for_page:;
787    if(info_text == NULL)
788      Xorriso_alloc_meM(info_text, char, 10*SfileadrL);
789    strcpy(info_text,xorriso->info_text);
790    sprintf(xorriso->info_text,"\n");
791    Xorriso_info(xorriso,0);
792    sprintf(xorriso->info_text,
793 ".... [Press Enter to continue. @,Enter avoids further stops. @@@ aborts] ....\n");
794    Xorriso_info(xorriso,0);
795    ret= Xorriso_request_confirmation(xorriso,flag&2);
796    strcpy(xorriso->info_text,info_text);
797    if(ret<=0)
798      goto ex;
799    if(ret==2)
800      {ret= 2; goto ex;}
801    if(ret==3)
802      goto ask_for_page;
803  }
804  xorriso->result_line_counter+= linecount;
805  ret= 1;
806 ex:;
807  Xorriso_free_meM(info_text);
808  return(ret);
809 }
810 
811 
812 /* @param flag bit0= no error message in case of failure
813 */
Xorriso_obtain_lock(struct XorrisO * xorriso,pthread_mutex_t * lock_handle,char * purpose,int flag)814 static int Xorriso_obtain_lock(struct XorrisO *xorriso,
815                                pthread_mutex_t *lock_handle,
816                                char *purpose, int flag)
817 {
818  int ret;
819  static int complaints= 0, complaint_limit= 5;
820 
821  ret= pthread_mutex_lock(lock_handle);
822  if(ret != 0) {
823    if(flag & 1)
824      return(-1);
825    /* Cannot report failure through the failing message output system */
826    complaints++;
827    if(complaints <= complaint_limit)
828      fprintf(stderr,
829              "xorriso : pthread_mutex_lock() for %s returns %d\n",
830              purpose, ret);
831    return(-1);
832  }
833  return(1);
834 }
835 
836 
837 /* @param flag bit0= no error message in case of failure
838 */
Xorriso_release_lock(struct XorrisO * xorriso,pthread_mutex_t * lock_handle,char * purpose,int flag)839 static int Xorriso_release_lock(struct XorrisO *xorriso,
840                                pthread_mutex_t *lock_handle,
841                                char *purpose, int flag)
842 {
843  int ret;
844  static int complaints= 0, complaint_limit= 5;
845 
846  ret= pthread_mutex_unlock(lock_handle);
847  if(ret != 0) {
848    if(flag & 1)
849      return(0);
850    /* Cannot report failure through the failing message output system */
851    complaints++;
852    if(complaints <= complaint_limit)
853      fprintf(stderr,
854              "xorriso : pthread_mutex_unlock() for %s returns %d\n",
855              purpose, ret);
856    return(0);
857  }
858  return(1);
859 }
860 
861 
Xorriso_lock_outlists(struct XorrisO * xorriso,int flag)862 static int Xorriso_lock_outlists(struct XorrisO *xorriso, int flag)
863 {
864  int ret;
865 
866  ret= Xorriso_obtain_lock(xorriso, &(xorriso->result_msglists_lock),
867                           "outlists", 0);
868  return(ret);
869 }
870 
871 
Xorriso_unlock_outlists(struct XorrisO * xorriso,int flag)872 static int Xorriso_unlock_outlists(struct XorrisO *xorriso, int flag)
873 {
874  int ret;
875 
876  ret= Xorriso_release_lock(xorriso, &(xorriso->result_msglists_lock),
877                            "outlists", 0);
878  return(ret);
879 }
880 
881 
Xorriso_write_to_msglist(struct XorrisO * xorriso,struct Xorriso_lsT ** xorriso_msglist,char * text,int flag)882 static int Xorriso_write_to_msglist(struct XorrisO *xorriso,
883                                     struct Xorriso_lsT **xorriso_msglist,
884                                     char *text, int flag)
885 {
886  int ret, locked= 0;
887  struct Xorriso_lsT *msglist;
888 
889  ret= Xorriso_lock_outlists(xorriso, 0);
890  if(ret <= 0)
891    goto ex;
892  locked= 1;
893  msglist= *xorriso_msglist;
894  ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0);
895  if(ret <= 0) {
896    ret= -1; goto ex;
897  }
898  if(*xorriso_msglist == NULL)
899    *xorriso_msglist= msglist;
900  ret= 1;
901 ex:;
902  if(locked)
903    Xorriso_unlock_outlists(xorriso, 0);
904  return(ret);
905 }
906 
907 
Xorriso_write_to_channel(struct XorrisO * xorriso,char * in_text,int channel_no,int flag)908 int Xorriso_write_to_channel(struct XorrisO *xorriso,
909                              char *in_text, int channel_no, int flag)
910 /*
911  bit0= eventually backslash encode linefeeds
912  bit1= text is the name of the log file for the given channel
913  bit2= text is the name of the consolidated packet log file for all channels
914  bit3= text is the name of the stderr redirection file
915 bit15= with bit1 to bit3: close depicted log file
916 */
917 {
918  char *rpt, *npt, *text= NULL, *line= NULL;
919  int ret= 1, info_redirected= 0, result_redirected= 0, l;
920  char prefix[16];
921  FILE *logfile_fp, *pktlog_fp;
922  static int num_channels= 4;
923  static char channel_prefixes[4][4]= {".","R","I","M"};
924  int Xorriso_sieve_filter_msg(struct XorrisO *xorriso, char *msg, int flag);
925 
926 #ifdef Xorriso_fetch_with_msg_queueS
927  static int complaints= 0, complaint_limit= 5;
928  int locked= 0, uret;
929 #endif
930 
931  text= in_text; /* might change due to backslash encoding */
932 
933  if(channel_no<0 || channel_no>=num_channels)
934    {ret= -1; goto ex;}
935 
936 #ifdef Xorriso_fetch_with_msg_queueS
937  ret= pthread_mutex_lock(&(xorriso->write_to_channel_lock));
938  if(ret != 0) {
939    /* Cannot report failure through the failing message output system */
940    complaints++;
941    if(complaints <= complaint_limit)
942      fprintf(stderr,
943            "xorriso : pthread_mutex_lock() for write_to_channel returns %d\n",
944            ret);
945    /* Intentionally not aborting here */;
946  } else
947    locked= 1;
948 #endif /* Xorriso_fetch_with_msg_queueS */
949 
950  /* Logfiles */
951  logfile_fp= xorriso->logfile_fp[channel_no];
952  pktlog_fp= xorriso->pktlog_fp;
953  if((flag&2) && logfile_fp!=NULL) {
954    fprintf(logfile_fp,
955      "! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n",
956            channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256));
957    fclose(logfile_fp);
958    xorriso->logfile_fp[channel_no]= logfile_fp= NULL;
959  }
960  if((flag&4) && pktlog_fp!=NULL) {
961    fprintf(pktlog_fp,
962  "I:1:! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n",
963            channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256));
964    fclose(pktlog_fp);
965    xorriso->pktlog_fp= pktlog_fp= NULL;
966  }
967  if((flag & 8) && xorriso->stderr_fp != NULL) {
968    fclose(xorriso->stderr_fp);
969    xorriso->stderr_fp= NULL;
970  }
971  if(flag&(1<<15))
972    {ret= 1; goto ex;}
973  if((flag&2)) {
974    xorriso->logfile_fp[channel_no]= logfile_fp= fopen(text,"a");
975    if(logfile_fp==NULL)
976      {ret= 0; goto ex;}
977    fprintf(logfile_fp,
978   "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : %s : %s\n",
979            channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256));
980    fflush(logfile_fp);
981  }
982  if((flag&4)) {
983    xorriso->pktlog_fp= pktlog_fp= fopen(text,"a");
984    if(pktlog_fp==NULL)
985      {ret= 0; goto ex;}
986    fprintf(pktlog_fp,
987   "I:1:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : . : %s\n",
988            Sfile_datestr(time(0),1|2|256));
989    fflush(pktlog_fp);
990  }
991  if(flag & 8) {
992    ret= truncate(text, (off_t) 0);
993    if(ret == -1 && errno != ENOENT)
994      {ret= 0; goto ex;}
995    xorriso->stderr_fp= fopen(text, "a");
996    if(xorriso->stderr_fp == NULL)
997      {ret= 0; goto ex;}
998  }
999  if(flag & (2 | 4 | 8))
1000    {ret= 1; goto ex;}
1001 
1002  /* Eventually perform backslash encoding of non-printable characters */
1003  if(((xorriso->bsl_interpretation & 32) && channel_no == 1) ||
1004     ((xorriso->bsl_interpretation & 64) && channel_no == 2)) {
1005    ret= Sfile_bsl_encoder(&text, text, strlen(text), 1 | 2 | 4);
1006    if(ret <= 0)
1007      {ret= -1; goto ex;}
1008  }
1009 
1010  /* Pick interesting words for the Xorriso_sieve API */
1011  Xorriso_sieve_filter_msg(xorriso, text,
1012                           (channel_no > 0 ? channel_no - 1 : 0));
1013 
1014  /* Eventually perform message redirection */
1015  if(xorriso->msglist_stackfill > 0) {
1016    if(xorriso->msglist_flags[xorriso->msglist_stackfill - 1] & 1)
1017      result_redirected= 1;
1018    if(xorriso->msglist_flags[xorriso->msglist_stackfill - 1] & 2)
1019      info_redirected= 1;
1020  }
1021 
1022  /* Non-redirected output */
1023  if(!xorriso->packet_output) {
1024    if(channel_no==1 || channel_no==3) {
1025      if(result_redirected) {
1026        ret= Xorriso_write_to_msglist(xorriso,
1027                  &(xorriso->result_msglists[xorriso->msglist_stackfill - 1]),
1028                  text, 0);
1029        if(ret <= 0)
1030          { ret= -1; goto ex; }
1031      } else {
1032        printf("%s",text);
1033        fflush(stdout);
1034      }
1035    }
1036    if(channel_no==2 || channel_no==3) {
1037      if(info_redirected) {
1038        ret= Xorriso_write_to_msglist(xorriso,
1039                  &(xorriso->info_msglists[xorriso->msglist_stackfill - 1]),
1040                  text, 0);
1041        if(ret <= 0)
1042          { ret= -1; goto ex; }
1043      } else {
1044        if(xorriso->stderr_fp != NULL) {
1045          fprintf(xorriso->stderr_fp, "%s", text);
1046          fflush(xorriso->stderr_fp);
1047        } else
1048          fprintf(stderr, "%s", text);
1049      }
1050    }
1051    if(logfile_fp!=NULL) {
1052      fprintf(logfile_fp,"%s",text);
1053      fflush(logfile_fp);
1054    }
1055    if(pktlog_fp==NULL)
1056      {ret= 1; goto ex;}
1057  }
1058  rpt= text;
1059  sprintf(prefix,"%s:x: ",channel_prefixes[channel_no]);
1060  while(*rpt!=0) {
1061    npt= strchr(rpt,'\n');
1062    if(npt==NULL)
1063      prefix[2]= '0';
1064    else
1065      prefix[2]= '1';
1066    if(!result_redirected) {
1067      if(xorriso->packet_output) {
1068        ret= fwrite(prefix,5,1,stdout);
1069        if(ret<=0)
1070          {ret= 0; goto ex;}
1071      }
1072    }
1073    if(pktlog_fp!=NULL) {
1074      ret= fwrite(prefix,5,1,pktlog_fp);
1075      if(ret<=0)
1076        {ret= 0; goto ex;}
1077    }
1078    if(npt==NULL) {
1079      if(xorriso->packet_output) {
1080        if(result_redirected) {
1081          l= strlen(rpt);
1082          Xorriso_alloc_meM(line, char, 5 + l + 1 + 1);
1083          memcpy(line, prefix, 5);
1084          memcpy(line + 5, rpt, l);
1085          line[5 + l] = '\n';
1086          line[5 + l + 1] = 0;
1087          ret= Xorriso_write_to_msglist(xorriso,
1088                    &(xorriso->result_msglists[xorriso->msglist_stackfill - 1]),
1089                    line, 0);
1090          Xorriso_free_meM(line);
1091          line= NULL;
1092          if(ret <= 0)
1093            { ret= -1; goto ex; }
1094        } else {
1095          ret= fwrite(rpt,strlen(rpt),1,stdout);
1096          if(ret<=0)
1097            {ret= 0; goto ex;}
1098          ret= fwrite("\n",1,1,stdout);
1099          if(ret<=0)
1100            {ret= 0; goto ex;}
1101        }
1102      }
1103      if(pktlog_fp!=NULL) {
1104        ret= fwrite(rpt,strlen(rpt),1,pktlog_fp);
1105        if(ret<=0)
1106          {ret= 0; goto ex;}
1107        ret= fwrite("\n",1,1,pktlog_fp);
1108        if(ret<=0)
1109          {ret= 0; goto ex;}
1110      }
1111  break;
1112    } else {
1113      if(xorriso->packet_output) {
1114        if(result_redirected) {
1115          l= npt + 1 - rpt;
1116          Xorriso_alloc_meM(line, char, 5 + l + 1);
1117          memcpy(line, prefix, 5);
1118          memcpy(line + 5, rpt, l);
1119          line[5 + l] = 0;
1120          ret= Xorriso_write_to_msglist(xorriso,
1121                    &(xorriso->result_msglists[xorriso->msglist_stackfill - 1]),
1122                    line, 0);
1123          Xorriso_free_meM(line);
1124          line= NULL;
1125          if(ret <= 0)
1126            { ret= -1; goto ex; }
1127        } else {
1128          ret= fwrite(rpt,npt+1-rpt,1,stdout);
1129          if(ret<=0)
1130            {ret= 0; goto ex;}
1131        }
1132      }
1133      if(pktlog_fp!=NULL) {
1134        ret= fwrite(rpt,npt+1-rpt,1,pktlog_fp);
1135        if(ret<=0)
1136          {ret= 0; goto ex;}
1137      }
1138    }
1139    rpt= npt+1;
1140  }
1141  if(xorriso->packet_output)
1142    fflush(stdout);
1143  if(pktlog_fp!=NULL)
1144    fflush(pktlog_fp);
1145  ret= 1;
1146 ex:
1147  if(text != in_text && text != NULL)
1148    free(text);
1149  Xorriso_free_meM(line);
1150 
1151 #ifdef Xorriso_fetch_with_msg_queueS
1152 
1153  if(locked) {
1154    uret= pthread_mutex_unlock(&(xorriso->write_to_channel_lock));
1155    if(uret != 0) {
1156      /* Cannot report failure through the failing message output system */
1157      complaints++;
1158      if(complaints <= complaint_limit)
1159        fprintf(stderr,
1160           "xorriso : pthread_mutex_unlock() for write_to_channel returns %d\n",
1161           uret);
1162    }
1163  }
1164 
1165 #endif /* Xorriso_fetch_with_msg_queueS */
1166 
1167  return(ret);
1168 }
1169 
1170 
Xorriso_push_outlists(struct XorrisO * xorriso,int * stack_handle,int flag)1171 int Xorriso_push_outlists(struct XorrisO *xorriso, int *stack_handle,
1172                           int flag)
1173 {
1174  int ret, locked= 0;
1175 
1176  ret= Xorriso_lock_outlists(xorriso, 0);
1177  if(ret <= 0)
1178    goto ex;
1179  locked= 1;
1180  if(xorriso->msglist_stackfill + 1 >= Xorriso_max_outlist_stacK) {
1181    Xorriso_unlock_outlists(xorriso, 0);
1182    locked= 0;
1183    Xorriso_msgs_submit(xorriso, 0,
1184                 "Overflow of message output redirection stack", 0, "FATAL", 0);
1185    ret= -1; goto ex;
1186  }
1187  if((flag & 3) == 0)
1188    flag|= 3;
1189  xorriso->msglist_stackfill++;
1190  xorriso->result_msglists[xorriso->msglist_stackfill - 1]= NULL;
1191  xorriso->info_msglists[xorriso->msglist_stackfill - 1]= NULL;
1192  xorriso->msglist_flags[xorriso->msglist_stackfill - 1]= flag & 3;
1193  *stack_handle= xorriso->msglist_stackfill - 1;
1194  ret= 1;
1195 ex:;
1196  if(locked)
1197    Xorriso_unlock_outlists(xorriso, 0);
1198  return(ret);
1199  return(1);
1200 }
1201 
1202 
Xorriso_fetch_outlists(struct XorrisO * xorriso,int stack_handle,struct Xorriso_lsT ** result_list,struct Xorriso_lsT ** info_list,int flag)1203 int Xorriso_fetch_outlists(struct XorrisO *xorriso, int stack_handle,
1204                            struct Xorriso_lsT **result_list,
1205                            struct Xorriso_lsT **info_list, int flag)
1206 {
1207  int ret, locked= 0;
1208 
1209 #ifdef Xorriso_fetch_with_msg_queueS
1210 
1211  ret= Xorriso_process_msg_queues(xorriso, 0);
1212  if(ret <= 0)
1213    goto ex;
1214 
1215 #endif /* Xorriso_fetch_with_msg_queueS */
1216 
1217  if((flag & 3) == 0)
1218    flag|= 3;
1219 
1220  ret= Xorriso_lock_outlists(xorriso, 0);
1221  if(ret <= 0)
1222    goto ex;
1223  locked= 1;
1224 
1225  if(stack_handle == -1)
1226    stack_handle= xorriso->msglist_stackfill - 1;
1227  if(stack_handle < 0 || stack_handle >= xorriso->msglist_stackfill) {
1228    Xorriso_unlock_outlists(xorriso, 0);
1229    locked= 0;
1230    Xorriso_msgs_submit(xorriso, 0,
1231                 "Program error: Wrong message output redirection stack handle",
1232                 0, "FATAL", 0);
1233    ret= -1; goto ex;
1234  }
1235 
1236  if(flag & 1) {
1237    *result_list= xorriso->result_msglists[stack_handle];
1238    xorriso->result_msglists[stack_handle]= NULL;
1239  }
1240  if(flag & 2) {
1241    *info_list= xorriso->info_msglists[stack_handle];
1242    xorriso->info_msglists[stack_handle]= NULL;
1243  }
1244 
1245  ret= 1;
1246 ex:;
1247  if(locked)
1248    Xorriso_unlock_outlists(xorriso, 0);
1249  return(ret);
1250 }
1251 
1252 
Xorriso_peek_outlists(struct XorrisO * xorriso,int stack_handle,int timeout,int flag)1253 int Xorriso_peek_outlists(struct XorrisO *xorriso, int stack_handle,
1254                           int timeout, int flag)
1255 {
1256  int ret, locked= 0, yes= 0;
1257  static int u_wait= 19000;
1258  time_t start_time;
1259 
1260  if((flag & 3) == 0)
1261    flag|= 3;
1262  if(stack_handle == -1)
1263    stack_handle= xorriso->msglist_stackfill - 1;
1264  start_time= time(NULL);
1265 
1266 try_again:;
1267  ret= Xorriso_obtain_lock(xorriso, &(xorriso->msgw_fetch_lock),
1268                           "message watcher fetch operation", 0);
1269  if(ret <= 0)
1270    {yes= -2; goto ex;}
1271  locked= 1;
1272 
1273  yes= 0;
1274  if(stack_handle < 0 || stack_handle >= xorriso->msglist_stackfill)
1275    {yes= -1; goto ex;}
1276  if(flag & 1)
1277    yes|= (xorriso->result_msglists[stack_handle] != NULL);
1278  if(flag & 2)
1279    yes|= (xorriso->info_msglists[stack_handle] != NULL);
1280  if(xorriso->msg_watcher_state == 2 && xorriso->msgw_msg_pending)
1281    yes|= 2;
1282 
1283  ret= Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
1284                            "message watcher fetch operation", 0);
1285  if(ret <= 0)
1286    {yes= -2; goto ex;}
1287  locked= 0;
1288 
1289  if(yes && (flag & 4)) {
1290    usleep(u_wait);
1291    if(time(NULL) <= start_time + timeout)
1292      goto try_again;
1293  }
1294 
1295 ex:;
1296  if(locked) {
1297    ret= Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
1298                              "message watcher fetch operation", 0);
1299    if(ret <= 0 && yes >= 0)
1300      yes= -2;
1301  }
1302  return(yes);
1303 }
1304 
1305 
Xorriso_pull_outlists(struct XorrisO * xorriso,int stack_handle,struct Xorriso_lsT ** result_list,struct Xorriso_lsT ** info_list,int flag)1306 int Xorriso_pull_outlists(struct XorrisO *xorriso, int stack_handle,
1307                           struct Xorriso_lsT **result_list,
1308                           struct Xorriso_lsT **info_list, int flag)
1309 {
1310  int i, ret, locked= 0;
1311 
1312  ret= Xorriso_lock_outlists(xorriso, 0);
1313  if(ret <= 0)
1314    goto ex;
1315  locked= 1;
1316 
1317  if(stack_handle == -1)
1318    stack_handle= xorriso->msglist_stackfill - 1;
1319  if(stack_handle < 0 || stack_handle >= xorriso->msglist_stackfill) {
1320    Xorriso_unlock_outlists(xorriso, 0);
1321    locked= 0;
1322    Xorriso_msgs_submit(xorriso, 0,
1323                 "Program error: Wrong message output redirection stack handle",
1324                 0, "FATAL", 0);
1325    ret= -1; goto ex;
1326  }
1327 
1328  /* Concatenate all redirections above stack_handle */
1329  *result_list= NULL;
1330  *info_list= NULL;
1331  for(i = stack_handle; i < xorriso->msglist_stackfill; i++) {
1332    if(*result_list == NULL)
1333      *result_list= xorriso->result_msglists[i];
1334    else
1335      Xorriso_lst_concat(*result_list, xorriso->result_msglists[i], 0);
1336    if(*info_list == NULL)
1337      *info_list= xorriso->info_msglists[i];
1338    else
1339      Xorriso_lst_concat(*info_list, xorriso->info_msglists[i], 0);
1340  }
1341  xorriso->msglist_stackfill= stack_handle;
1342 
1343  ret= 1;
1344 ex:;
1345  if(locked)
1346    Xorriso_unlock_outlists(xorriso, 0);
1347  return(ret);
1348 }
1349 
1350 
Xorriso_info_handler_stderr(void * handle,char * text)1351 int Xorriso_info_handler_stderr(void *handle, char *text)
1352 {
1353  struct XorrisO *xorriso;
1354 
1355  xorriso= (struct XorrisO *) handle;
1356  if(xorriso->stderr_fp != NULL) {
1357    fprintf(xorriso->stderr_fp, "%s", text);
1358    fflush(xorriso->stderr_fp);
1359  } else {
1360    fprintf(stderr, "%s", text);
1361    fflush(stderr);
1362  }
1363  return(1);
1364 }
1365 
1366 
Xorriso_result_handler_stdout(void * handle,char * text)1367 int Xorriso_result_handler_stdout(void *handle, char *text)
1368 {
1369  printf("%s", text);
1370  fflush(stdout);
1371  return(1);
1372 }
1373 
1374 
Xorriso_result_handler_pkt(void * handle,char * text)1375 int Xorriso_result_handler_pkt(void *handle, char *text)
1376 {
1377  int nl= -1, ret, l;
1378  struct XorrisO *xorriso;
1379 
1380  xorriso= (struct XorrisO *) handle;
1381 
1382  if(!xorriso->packet_output)
1383    return Xorriso_result_handler_stdout(handle, text);
1384 
1385  /* Interpret pkt_output */
1386  l= strlen(text);
1387  if(l >= 5) {
1388    if(strchr("RIM", text[0]) != NULL && text[1] == ':' &&
1389       strchr("01", text[2]) != NULL && text[3] == ':' && text[4] == ' ')
1390      nl= (text[2] == '1');
1391  }
1392  if(nl < 0) /* Not pkt_output format */
1393    return Xorriso_result_handler_stdout(handle, text);
1394 
1395  if(nl == 0) {
1396    /* Suppress newline */
1397    if(text[l - 1] == '\n')
1398      l--;
1399  }
1400 
1401  if(text[0] == 'R') {
1402    ret= fwrite(text + 5, l - 5, 1, stdout);
1403  } else {
1404    ret= fwrite(text + 5, l - 5, 1,
1405                xorriso->stderr_fp != NULL ? xorriso->stderr_fp : stderr);
1406  }
1407  if(ret <= 0)
1408    return(0);
1409  return(1);
1410 }
1411 
1412 
Xorriso_process_msg_lists(struct XorrisO * xorriso,struct Xorriso_lsT * result_list,struct Xorriso_lsT * info_list,int * line_count,int flag)1413 int Xorriso_process_msg_lists(struct XorrisO *xorriso,
1414                                      struct Xorriso_lsT *result_list,
1415                                      struct Xorriso_lsT *info_list,
1416                                      int *line_count, int flag)
1417 {
1418  struct Xorriso_lsT *lpt;
1419  int ret;
1420  int (*handler)(void *handle, char *text);
1421  void *handle;
1422 
1423  handler= xorriso->msgw_result_handler;
1424  handle= xorriso->msgw_result_handle;
1425  if(handler == NULL) {
1426    handler= Xorriso_result_handler_pkt;
1427    handle= xorriso;
1428  }
1429  for(lpt= result_list; lpt != NULL; lpt= lpt->next) {
1430    (*line_count)++;
1431    ret= (*handler)(handle, Xorriso_lst_get_text(lpt, 0));
1432    if(ret < 0)
1433      return(-1);
1434  }
1435  handler= xorriso->msgw_info_handler;
1436  handle= xorriso->msgw_info_handle;
1437  if(handler == NULL) {
1438    handler= Xorriso_info_handler_stderr;
1439    handle= xorriso;
1440  }
1441  for(lpt= info_list; lpt != NULL; lpt= lpt->next) {
1442    (*line_count)++;
1443    ret= (*handler)(handle, Xorriso_lst_get_text(lpt, 0));
1444    if(ret < 0)
1445      return(-1);
1446  }
1447  return(1);
1448 }
1449 
1450 
Xorriso_msg_watcher(void * state_pt)1451 static void *Xorriso_msg_watcher(void *state_pt)
1452 {
1453  struct XorrisO *xorriso;
1454  int ret, u_wait= 25000, line_count, sleep_thresh= 20, lock_failure= 0;
1455  struct Xorriso_lsT *result_list= NULL, *info_list= NULL;
1456  static int debug_sev= 0;
1457 
1458  xorriso= (struct XorrisO *) state_pt;
1459 
1460  if(debug_sev == 0)
1461    Xorriso__text_to_sev("DEBUG", &debug_sev, 0);
1462 
1463  xorriso->msg_watcher_state= 2;
1464  if(xorriso->msgw_info_handler != NULL &&
1465     debug_sev < xorriso->report_about_severity &&
1466     debug_sev < xorriso->abort_on_severity)
1467    (*xorriso->msgw_info_handler)(xorriso,
1468                      "xorriso : DEBUG : Concurrent message watcher started\n");
1469  while(1) {
1470    line_count= 0;
1471 
1472    /* Watch out for end request in xorriso */
1473    if(xorriso->msg_watcher_state == 3)
1474  break;
1475 
1476    ret= Xorriso_obtain_lock(xorriso, &(xorriso->msgw_fetch_lock),
1477                             "message watcher fetch operation", 1);
1478    if(ret <= 0) {
1479      lock_failure= 1;
1480  break;
1481    }
1482    xorriso->msgw_msg_pending= 1;
1483    ret= Xorriso_fetch_outlists(xorriso, -1, &result_list, &info_list, 3);
1484    if(ret > 0) {
1485      /* Process fetched lines */
1486      xorriso->msgw_msg_pending= 2;
1487      Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
1488                           "message watcher fetch operation", 1);
1489      ret= Xorriso_process_msg_lists(xorriso, result_list, info_list,
1490                                     &line_count, 0);
1491      xorriso->msgw_msg_pending= 0;
1492      Xorriso_lst_destroy_all(&result_list, 0);
1493      Xorriso_lst_destroy_all(&info_list, 0);
1494      if(ret < 0)
1495  break;
1496    } else {
1497      xorriso->msgw_msg_pending= 0;
1498      Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
1499                           "message watcher fetch operation", 1);
1500    }
1501    xorriso->msgw_msg_pending= 0;
1502 
1503    if(ret < 0)
1504  break;
1505 
1506    if(line_count < sleep_thresh)
1507      usleep(u_wait);
1508  }
1509  if(xorriso->msgw_info_handler != NULL &&
1510     debug_sev < xorriso->report_about_severity &&
1511     debug_sev < xorriso->abort_on_severity &&
1512     !lock_failure)
1513    (*xorriso->msgw_info_handler)(xorriso,
1514                      "xorriso : DEBUG : Concurrent message watcher ended\n");
1515  xorriso->msg_watcher_state= 0;
1516  return(NULL);
1517 }
1518 
1519 
Xorriso_start_msg_watcher(struct XorrisO * xorriso,int (* result_handler)(void * handle,char * text),void * result_handle,int (* info_handler)(void * handle,char * text),void * info_handle,int flag)1520 int Xorriso_start_msg_watcher(struct XorrisO *xorriso,
1521                     int (*result_handler)(void *handle, char *text),
1522                     void *result_handle,
1523                     int (*info_handler)(void *handle, char *text),
1524                     void *info_handle,
1525                     int flag)
1526 {
1527  int ret, u_wait= 1000, locked= 0, pushed= 0, uret, line_count= 0;
1528  struct Xorriso_lsT *result_list= NULL, *info_list= NULL;
1529  pthread_attr_t attr;
1530  pthread_attr_t *attr_pt = NULL;
1531  pthread_t thread;
1532 
1533  ret= pthread_mutex_lock(&(xorriso->msg_watcher_lock));
1534  if(ret != 0) {
1535    Xorriso_msgs_submit(xorriso, 0,
1536            "Cannot acquire mutex lock for managing concurrent message watcher",
1537             ret, "FATAL", 0);
1538    ret= -1; goto ex;
1539  }
1540  locked= 1;
1541 
1542  /* Check for running watcher */
1543  if(xorriso->msg_watcher_state > 0) {
1544    sprintf(xorriso->info_text,
1545           "There is already a concurrent message watcher running");
1546    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
1547    ret= 0; goto ex;
1548  }
1549 
1550  ret= Xorriso_push_outlists(xorriso, &(xorriso->msgw_stack_handle), 3);
1551  if(ret <= 0)
1552    goto ex;
1553  pushed= 1;
1554 
1555  /* Register watcher */
1556  xorriso->msgw_result_handler= result_handler;
1557  xorriso->msgw_result_handle= result_handle;
1558  xorriso->msgw_info_handler= info_handler;
1559  xorriso->msgw_info_handle= info_handle;
1560  xorriso->msg_watcher_state= 1;
1561 
1562  /* Start thread */
1563  pthread_attr_init(&attr);
1564  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1565  attr_pt= &attr;
1566  ret= pthread_create(&thread, attr_pt, Xorriso_msg_watcher, xorriso);
1567  if(ret != 0) {
1568    sprintf(xorriso->info_text,
1569           "Cannot create thread for concurrent message watcher");
1570    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
1571    ret= 0; goto ex;
1572  }
1573 
1574  /* Wait until watcher has indicated start */
1575  while(xorriso->msg_watcher_state == 1) {
1576 
1577    /* >>> have a timeout ? */;
1578 
1579    usleep(u_wait);
1580  }
1581 
1582  ret= 1;
1583 ex:;
1584  if(ret <= 0 && pushed) {
1585    uret= Xorriso_pull_outlists(xorriso, xorriso->msgw_stack_handle,
1586                               &result_list, &info_list, 0);
1587    if(uret > 0) {
1588      xorriso->msgw_result_handler= NULL;
1589      xorriso->msgw_info_handler= NULL;
1590      Xorriso_process_msg_lists(xorriso, result_list, info_list,
1591                                &line_count, 0);
1592      Xorriso_lst_destroy_all(&result_list, 0);
1593      Xorriso_lst_destroy_all(&info_list, 0);
1594    }
1595  }
1596  if(locked) {
1597    uret= pthread_mutex_unlock(&(xorriso->msg_watcher_lock));
1598    if(uret != 0) {
1599      Xorriso_msgs_submit(xorriso, 0,
1600            "Cannot release mutex lock for managing concurrent message watcher",
1601            uret, "FATAL", 0);
1602      ret= -1;
1603    }
1604  }
1605  return(ret);
1606 }
1607 
1608 
1609 /* @param flag bit0= do not complain loudly if no wather is active
1610 */
Xorriso_stop_msg_watcher(struct XorrisO * xorriso,int flag)1611 int Xorriso_stop_msg_watcher(struct XorrisO *xorriso, int flag)
1612 {
1613  int ret, u_wait= 1000, locked= 0, uret, line_count= 0;
1614  struct Xorriso_lsT *result_list= NULL, *info_list= NULL;
1615 
1616  if((flag & 1) && xorriso->msg_watcher_state != 2)
1617    /* Roughly tolerate non-running watcher */
1618    {ret= 0; goto ex;}
1619 
1620  ret= pthread_mutex_lock(&(xorriso->msg_watcher_lock));
1621  if(ret != 0) {
1622    Xorriso_msgs_submit(xorriso, 0,
1623            "Cannot acquire mutex lock for managing concurrent message watcher",
1624             ret, "FATAL", 0);
1625    ret= -1; goto ex;
1626  }
1627  locked= 1;
1628 
1629  /* Check for running watcher */
1630  if(xorriso->msg_watcher_state != 2) {
1631    sprintf(xorriso->info_text,
1632           "There is no concurrent message watcher running");
1633    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0);
1634    ret= 0; goto ex;
1635  }
1636 
1637  /* Inform watcher of desire to stop it */
1638  xorriso->msg_watcher_state= 3;
1639 
1640  /* Wait until watcher has indicated its end */
1641  while(xorriso->msg_watcher_state != 0) {
1642 
1643    /* >>> have a timeout ? */;
1644 
1645    usleep(u_wait);
1646  }
1647 
1648  ret= Xorriso_obtain_lock(xorriso, &(xorriso->msgw_fetch_lock),
1649                           "message watcher fetch operation", 1);
1650  if(ret <= 0) {
1651    Xorriso_msgs_submit(xorriso, 0,
1652            "Cannot obtain mutex lock for managing concurrent message watcher",
1653            ret, "FATAL", 0);
1654    ret= -1;
1655    goto ex;
1656  }
1657  xorriso->msgw_msg_pending= 1;
1658  ret= Xorriso_pull_outlists(xorriso, xorriso->msgw_stack_handle,
1659                             &result_list, &info_list, 0);
1660  if(ret > 0) {
1661    xorriso->msgw_msg_pending= 2;
1662    Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
1663                         "message watcher fetch operation", 1);
1664    Xorriso_process_msg_lists(xorriso, result_list, info_list,
1665                              &line_count, 0);
1666    xorriso->msgw_msg_pending= 0;
1667    Xorriso_lst_destroy_all(&result_list, 0);
1668    Xorriso_lst_destroy_all(&info_list, 0);
1669  } else {
1670    xorriso->msgw_msg_pending= 0;
1671    Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
1672                         "message watcher fetch operation", 1);
1673  }
1674 
1675  xorriso->msgw_result_handler= NULL;
1676  xorriso->msgw_info_handler= NULL;
1677 
1678  ret= 1;
1679 ex:;
1680  if(locked) {
1681    uret= pthread_mutex_unlock(&(xorriso->msg_watcher_lock));
1682    if(uret != 0) {
1683      Xorriso_msgs_submit(xorriso, 0,
1684            "Cannot release mutex lock for managing concurrent message watcher",
1685            uret, "FATAL", 0);
1686      ret= -1;
1687    }
1688  }
1689  return(ret);
1690 }
1691 
1692 
1693 /* -------------------------- Xorriso_msg_sievE -------------------------- */
1694 
1695 struct Xorriso_msg_filteR {
1696  char *name;
1697  char *prefix;
1698  char *separators;
1699  int channels;         /* What to watch: bit0=result , bit1=info , bit2=mark */
1700 
1701  int num_words;
1702  int *word_idx;
1703  int last_word_line_end;
1704 
1705                 /* Oldest result gets discarded when new surpassed threshold */
1706  int max_results;
1707 
1708  struct Xorriso_lsT *results; /* Serialized tuples of num_words */
1709  int num_results;
1710  int num_delivered;
1711  struct Xorriso_lsT *next_to_deliver;
1712 
1713  struct Xorriso_msg_filteR *prev;
1714  struct Xorriso_msg_filteR *next;
1715 };
1716 int Xorriso_msg_filter_destroy(struct Xorriso_msg_filteR **o, int flag);
1717 
1718 
Xorriso_msg_filter_new(struct Xorriso_msg_filteR ** o,char * name,struct Xorriso_msg_filteR * prev,struct Xorriso_msg_filteR * next,int flag)1719 int Xorriso_msg_filter_new(struct Xorriso_msg_filteR **o, char *name,
1720                            struct Xorriso_msg_filteR *prev,
1721                            struct Xorriso_msg_filteR *next,
1722                            int flag)
1723 {
1724  struct Xorriso_msg_filteR *m;
1725 
1726  m= (*o)= TSOB_FELD(struct Xorriso_msg_filteR, 1);
1727  if((*o) == NULL)
1728    return(-1);
1729  m->name= NULL;
1730  m->prefix= NULL;
1731  m->separators= NULL;
1732  m->channels= 7;
1733  m->num_words= 0;
1734  m->word_idx= NULL;
1735  m->last_word_line_end= flag & 1;
1736  m->max_results= 1;
1737  m->results= NULL;
1738  m->num_results= 0;
1739  m->num_delivered= 0;
1740  m->next_to_deliver= NULL;
1741 
1742  m->name= strdup(name);
1743  if(m->name == NULL)
1744    goto failure;
1745 
1746  m->prev= prev;
1747  if(prev != NULL)
1748    prev->next= m;
1749  m->next= next;
1750  if(next != NULL)
1751    next->prev= m;
1752  return(1);
1753 failure:
1754  Xorriso_msg_filter_destroy(o, 0);
1755  return(-1);
1756 }
1757 
1758 
Xorriso_msg_filter_destroy(struct Xorriso_msg_filteR ** o,int flag)1759 int Xorriso_msg_filter_destroy(struct Xorriso_msg_filteR **o, int flag)
1760 {
1761  struct Xorriso_msg_filteR *m;
1762 
1763  if((*o)==NULL)
1764    return(0);
1765  m= *o;
1766  if(m->name != NULL)
1767    free(m->name);
1768  if(m->prefix != NULL)
1769    free(m->prefix);
1770  if(m->separators != NULL)
1771    free(m->separators);
1772  if(m->word_idx != NULL)
1773    free((char *) m->word_idx);
1774  if(m->results != NULL)
1775    Xorriso_lst_destroy_all(&(m->results), 0);
1776  if(m->prev != NULL)
1777    m->prev->next= m->next;
1778  if(m->next != NULL)
1779    m->next->prev= m->prev;
1780 
1781  free(*o);
1782  *o= NULL;
1783  return(1);
1784 }
1785 
1786 
Xorriso_msg_filter_set_words(struct Xorriso_msg_filteR * m,int num_words,int * word_idx,int flag)1787 int Xorriso_msg_filter_set_words(struct Xorriso_msg_filteR *m,
1788                                  int num_words, int *word_idx, int flag)
1789 {
1790  int i;
1791 
1792  if(m->word_idx != NULL)
1793    free(m->word_idx);
1794  m->num_words= 0;
1795  if(num_words <= 0)
1796    return(1);
1797  m->word_idx= TSOB_FELD(int, num_words);
1798  if(m->word_idx == NULL)
1799    return(-1);
1800  for(i= 0; i < num_words; i++)
1801    m->word_idx[i]= word_idx[i];
1802  m->num_words= num_words;
1803  return(1);
1804 }
1805 
1806 
1807 struct Xorriso_msg_sievE {
1808 
1809  int num_filters;
1810 
1811  struct Xorriso_msg_filteR *first_filter;
1812 
1813 };
1814 
1815 
Xorriso_msg_sieve_new(struct Xorriso_msg_sievE ** o,int flag)1816 int Xorriso_msg_sieve_new(struct Xorriso_msg_sievE **o, int flag)
1817 {
1818  struct Xorriso_msg_sievE *m;
1819 
1820  m= (*o)= TSOB_FELD(struct Xorriso_msg_sievE, 1);
1821  if((*o) == NULL)
1822    return(-1);
1823  m->num_filters= 0;
1824  m->first_filter= NULL;
1825  return(1);
1826 }
1827 
1828 
Xorriso_msg_sieve_destroy(struct Xorriso_msg_sievE ** o,int flag)1829 int Xorriso_msg_sieve_destroy(struct Xorriso_msg_sievE **o, int flag)
1830 {
1831  struct Xorriso_msg_sievE *m;
1832  struct Xorriso_msg_filteR *f, *next_f= NULL;
1833 
1834  if((*o) == NULL)
1835    return(0);
1836  m= *o;
1837  for(f= m->first_filter; f != NULL; f= next_f) {
1838    next_f= f->next;
1839    Xorriso_msg_filter_destroy(&f, 0);
1840  }
1841  free(*o);
1842  *o= NULL;
1843  return(1);
1844 }
1845 
1846 
1847 /* API */
Xorriso_sieve_add_filter(struct XorrisO * xorriso,char * name,int channels,char * prefix,char * separators,int num_words,int * word_idx,int max_results,int flag)1848 int Xorriso_sieve_add_filter(struct XorrisO *xorriso, char *name,
1849                              int channels, char *prefix, char *separators,
1850                              int num_words, int *word_idx, int max_results,
1851                              int flag)
1852 {
1853  int ret;
1854  struct Xorriso_msg_sievE *sieve= NULL;
1855  struct Xorriso_msg_filteR *filter;
1856 
1857  if(xorriso->msg_sieve == NULL) {
1858    ret= Xorriso_msg_sieve_new(&sieve, 0);
1859    if(ret <= 0)
1860      goto no_mem;
1861    xorriso->msg_sieve= sieve;
1862  } else
1863    sieve= xorriso->msg_sieve;
1864  ret= Xorriso_msg_filter_new(&filter, name, NULL, sieve->first_filter,
1865                              flag & 1);
1866  if(ret <= 0)
1867    goto no_mem;
1868  sieve->first_filter= filter;
1869  ret= Xorriso_msg_filter_set_words(filter, num_words, word_idx, 0);
1870  if(ret <= 0)
1871    goto no_mem;
1872  if(prefix != NULL)
1873    filter->prefix= strdup(prefix);
1874  if(separators != NULL)
1875    filter->separators= strdup(separators);
1876  filter->channels= channels;
1877  filter->max_results= max_results;
1878  (sieve->num_filters)++;
1879  return(1);
1880 
1881 no_mem:;
1882  Xorriso_msg_sieve_destroy(&sieve, 0);
1883  Xorriso_no_malloc_memory(xorriso, NULL, 0);
1884  return(-1);
1885 }
1886 
1887 
1888 /* API */
Xorriso_sieve_dispose(struct XorrisO * xorriso,int flag)1889 int Xorriso_sieve_dispose(struct XorrisO *xorriso, int flag)
1890 {
1891  Xorriso_msg_sieve_destroy(&(xorriso->msg_sieve), 0);
1892  return(1);
1893 }
1894 
1895 
1896 /* API */
Xorriso_sieve_clear_results(struct XorrisO * xorriso,int flag)1897 int Xorriso_sieve_clear_results(struct XorrisO *xorriso, int flag)
1898 {
1899  struct Xorriso_msg_filteR *f;
1900 
1901  if(xorriso->msg_sieve == NULL)
1902    return(1);
1903  for(f= xorriso->msg_sieve->first_filter; f != NULL; f= f->next) {
1904    f->num_results= 0;
1905    f->num_delivered= 0;
1906    if(f->results != NULL)
1907      Xorriso_lst_destroy_all(&(f->results), 0);
1908    f->next_to_deliver= NULL;
1909  }
1910  return(1);
1911 }
1912 
1913 
1914 /* API */
1915 /* @param flag bit0= Reset reading to first matching result
1916                bit1= Only inquire number of available results.
1917                      Do not allocate memory.
1918                bit2= If *argv is not NULL, then free it before attaching
1919                      new memory.
1920                bit3= Do not read recorded data but rather list all filter names
1921 */
Xorriso_sieve_get_result(struct XorrisO * xorriso,char * name,int * argc,char *** argv,int * available,int flag)1922 int Xorriso_sieve_get_result(struct XorrisO *xorriso, char *name,
1923                              int *argc, char ***argv, int *available, int flag)
1924 {
1925  struct Xorriso_msg_filteR *f;
1926  struct Xorriso_lsT *lst;
1927  int i;
1928 
1929  if(flag & 4)
1930    Xorriso__dispose_words(argc, argv);
1931  *argc= 0;
1932  *argv= NULL;
1933 
1934  if(xorriso->msg_sieve == NULL)
1935    return(0);
1936 
1937  if(flag & 8) {
1938    if(xorriso->msg_sieve->num_filters <= 0)
1939      return(0);
1940    *argv= calloc(xorriso->msg_sieve->num_filters, sizeof(char *));
1941    if(*argv == NULL)
1942      goto no_mem;
1943    *argc= xorriso->msg_sieve->num_filters;
1944    for(i= 0; i < *argc; i++)
1945      (*argv)[i]= NULL;
1946    i= 0;
1947    for(f= xorriso->msg_sieve->first_filter; f != NULL; f= f->next) {
1948      (*argv)[*argc - i - 1]= strdup(f->name);
1949      if((*argv)[*argc - i - 1] == NULL)
1950        goto no_mem;
1951      i++;
1952    }
1953    *argc= i;
1954    return(1);
1955  }
1956 
1957  for(f= xorriso->msg_sieve->first_filter; f != NULL; f= f->next) {
1958    if(strcmp(f->name, name) != 0)
1959  continue;
1960    *available= f->num_results - f->num_delivered;
1961    if(*available <= 0)
1962      return(0);
1963    if(flag & 2)
1964      return(1);
1965 
1966    if(flag & 1) {
1967      f->num_delivered= 0;
1968      f->next_to_deliver= NULL;
1969    }
1970    if(f->next_to_deliver == NULL) {
1971      f->next_to_deliver= f->results;
1972      for(i= 0; i < f->num_words * f->num_delivered; i++)
1973        if(f->next_to_deliver != NULL)
1974          f->next_to_deliver= Xorriso_lst_get_next(f->next_to_deliver, 0);
1975    }
1976    if(f->next_to_deliver == NULL) {
1977      /* Should not happen */
1978      goto unexpected_null;
1979    }
1980    if(f->num_words <= 0)
1981      return(1);
1982 
1983    *argv= calloc(f->num_words, sizeof(char *));
1984    if(*argv == NULL)
1985      goto no_mem;
1986    *argc= f->num_words;
1987    for(i= 0; i < *argc; i++)
1988      (*argv)[i]= NULL;
1989 
1990    lst= f->next_to_deliver;
1991    for(i= 0; i < *argc; i++) {
1992      if(lst != NULL) {
1993        (*argv)[i]= strdup(Xorriso_lst_get_text(lst, 0));
1994        if((*argv)[i] == NULL)
1995          goto no_mem;
1996      } else {
1997        /* should not happen */
1998 unexpected_null:;
1999        Xorriso_msgs_submit(xorriso, 0,
2000                     "Program error: Unexpected NULL pointer in message sieve.",
2001                     0, "WARNING", 0);
2002        if(*argv != NULL)
2003          Xorriso__dispose_words(argc, argv);
2004        *available= 0;
2005        return(-2);
2006      }
2007      lst= Xorriso_lst_get_next(lst, 0);
2008    }
2009    f->next_to_deliver= lst;
2010    (f->num_delivered)++;
2011    (*available)--;
2012    return(1);
2013  }
2014  return(-2);
2015 no_mem:
2016  if(*argv != NULL)
2017    Xorriso__dispose_words(argc, argv);
2018  Xorriso_no_malloc_memory(xorriso, NULL, 0);
2019  return(-1);
2020 }
2021 
2022 
Xorriso_sieve_big(struct XorrisO * xorriso,int flag)2023 int Xorriso_sieve_big(struct XorrisO *xorriso, int flag)
2024 {
2025  struct Xorriso_sieve_big_filteR {
2026    char *name;
2027    int channels;
2028    char *prefix;
2029    char *separators;
2030    int num_words;
2031    int word_idx[6];
2032    int max_results;
2033    int flag;
2034  };
2035  static struct Xorriso_sieve_big_filteR filters[] = {
2036    {"-changes_pending", 3, "-changes_pending", "", 1,
2037                                                { 0, -1, -1, -1, -1, -1}, 1, 0},
2038    {"?  -dev", 3, "?  -dev", "", 4, { 0,  1,  3,  4, -1, -1},
2039                                                                         10, 0},
2040    {"??  -dev", 3, "??  -dev", "", 4, { 0,  1,  3,  4, -1, -1},
2041                                                                         90, 0},
2042    {"Abstract File:", 3, "Abstract File: ", "", 1, { 0, -1, -1, -1, -1, -1},
2043                                                                          1, 1},
2044    {"After commit :", 3, "After commit :", "", 1, { 0, -1, -1, -1, -1, -1},
2045                                                                          1, 0},
2046    {"App Id       :", 3, "App Id       : ", "", 1, { 0, -1, -1, -1, -1, -1},
2047                                                                          1, 1},
2048    {"Biblio File  :", 3, "Biblio File  : ", "", 1, { 0, -1, -1, -1, -1, -1},
2049                                                                          1, 1},
2050    {"Build timestamp   :", 3, "Build timestamp   :  ", "", 1,
2051                                                { 0, -1, -1, -1, -1, -1}, 1, 1},
2052    {"CopyrightFile:", 3, "CopyrightFile: ", "", 1, { 0, -1, -1, -1, -1, -1},
2053                                                                          1, 1},
2054    {"Creation Time:", 3, "Creation Time: ", "", 1, { 0, -1, -1, -1, -1, -1},
2055                                                                          1, 1},
2056    {"DVD obs 64 kB:", 3, "DVD obs 64 kB:", "", 1, { 0, -1, -1, -1, -1, -1},
2057                                                                          1, 0},
2058    {"Drive current:", 3, "Drive current:", "", 2, { 0,  1, -1, -1, -1, -1},
2059                                                                          2, 0},
2060    {"Drive id     :", 3, "Drive id     :", "", 1, { 0, -1, -1, -1, -1, -1},
2061                                                                          2, 0},
2062    {"Drive type   :", 3, "Drive type   :", "", 3, { 1,  3,  5, -1, -1, -1},
2063                                                                          2, 0},
2064    {"Eff. Time    :", 3, "Eff. Time    : ", "", 1, { 0, -1, -1, -1, -1, -1},
2065                                                                          1, 1},
2066    {"Expir. Time  :", 3, "Expir. Time  : ", "", 1, { 0, -1, -1, -1, -1, -1},
2067                                                                          1, 1},
2068    {"Ext. filters :", 3, "Ext. filters : ", "", 1, { 0, -1, -1, -1, -1, -1},
2069                                                                          1, 1},
2070    {"File damaged :", 3, "File damaged :", "", 4, { 0,  2,  4,  6, -1, -1},
2071                                                                      10000, 0},
2072    {"File data lba:", 3, "File data lba:", "", 5, { 0,  2,  4,  6,  8, -1},
2073                                                                      10000, 0},
2074    {"Format idx   :", 3, "Format idx ", ",: ", 4, { 0,  1,  2,  3, -1, -1},
2075                                                                        100, 1},
2076    {"Format status:", 3, "Format status:", ", ", 2, { 0,  1, -1, -1, -1, -1},
2077                                                                          1, 1},
2078    {"ISO session  :", 3, "ISO session  :", "", 4, { 0,  2,  4,  6, -1, -1},
2079                                                                      10000, 1},
2080    {"Image size   :", 3, "Image size   :", "", 1, { 0, -1, -1, -1, -1, -1},
2081                                                                          1, 0},
2082    {"Jigdo files  :", 3, "Jigdo files  :", "", 1, { 0, -1, -1, -1, -1, -1},
2083                                                                          1, 0},
2084    {"Local ACL    :", 3, "Local ACL    :", "", 1, { 0, -1, -1, -1, -1, -1},
2085                                                                          1, 0},
2086    {"Local xattr  :", 3, "Local xattr  :", "", 1, { 0, -1, -1, -1, -1, -1},
2087                                                                          1, 0},
2088    {"MD5 MISMATCH:", 3, "MD5 MISMATCH:", "", 1, { 0, -1, -1, -1, -1, -1},
2089                                                                      10000, 0},
2090    {"MD5 tag range:", 3, "MD5 tag range:", "", 3, { 0,  2,  4, -1, -1, -1},
2091                                                                      10000, 1},
2092    {"Media blocks :", 3, "Media blocks :", "", 3, { 0,  3,  6, -1, -1, -1},
2093                                                                          2, 0},
2094    {"Media current:", 3, "Media current: ", "", 1, { 0, -1, -1, -1, -1, -1},
2095                                                                          2, 1},
2096    {"Media id     :", 3, "Media id     :", "", 1, { 0, -1, -1, -1, -1, -1},
2097                                                                          2, 0},
2098    {"Media nwa    :", 3, "Media nwa    :", "", 1, { 0, -1, -1, -1, -1, -1},
2099                                                                          1, 0},
2100    {"Media product:", 3, "Media product:", "", 2, { 0,  2, -1, -1, -1, -1},
2101                                                                          2, 1},
2102    {"Media region :", 3, "Media region :", "", 3, { 0,  2,  4, -1, -1, -1},
2103                                                                      10000, 1},
2104    {"Media space  :", 3, "Media space  :", "", 1, { 0, -1, -1, -1, -1, -1},
2105                                                                          1, 0},
2106    {"Media status :", 3, "Media status : ", "", 1, { 0, -1, -1, -1, -1, -1},
2107                                                                          2, 1},
2108    {"Media summary:", 3, "Media summary:", "", 4, { 0,  2,  5,  7, -1, -1},
2109                                                                          2, 0},
2110    {"Modif. Time  :", 3, "Modif. Time  : ", "", 1, { 0, -1, -1, -1, -1, -1},
2111                                                                          1, 1},
2112    {"PVD address  :", 3, "PVD address  :", "", 1, { 0, -1, -1, -1, -1, -1},
2113                                                                          1, 0},
2114    {"Preparer Id  :", 3, "Preparer Id  : ", "", 1, { 0, -1, -1, -1, -1, -1},
2115                                                                          1, 1},
2116    {"Profile      :", 3, "Profile      :", "", 2, { 0,  1, -1, -1, -1, -1},
2117                                                                        256, 1},
2118    {"Publisher Id :", 3, "Publisher Id : ", "", 1, { 0, -1, -1, -1, -1, -1},
2119                                                                          1, 1},
2120    {"Readline     :", 3, "Readline     :", "", 1, { 0, -1, -1, -1, -1, -1},
2121                                                                          1, 0},
2122    {"Size lower   :", 3, "Size lower   :", "", 1, { 0, -1, -1, -1, -1, -1},
2123                                                                          1, 0},
2124    {"Size upper   :", 3, "Size upper   :", "", 1, { 0, -1, -1, -1, -1, -1},
2125                                                                          1, 0},
2126    {"System Id    :", 3, "System Id    : ", "", 1, { 0, -1, -1, -1, -1, -1},
2127                                                                          1, 1},
2128    {"Version timestamp :", 3, "Version timestamp :", "", 1,
2129                                                { 0, -1, -1, -1, -1, -1}, 1, 0},
2130    {"Volume Id    :", 3, "Volume Id    : ", "", 1, { 0, -1, -1, -1, -1, -1},
2131                                                                          1, 1},
2132    {"Volume Set Id:", 3, "Volume Set Id: ", "", 1, { 0, -1, -1, -1, -1, -1},
2133                                                                          1, 1},
2134    {"Volume id    :", 3, "Volume id    :", "", 1, { 0, -1, -1, -1, -1, -1},
2135                                                                          2, 0},
2136    {"Write speed  :", 3, "Write speed  :", "", 2, { 0,  2, -1, -1, -1, -1},
2137                                                                        100, 0},
2138    {"Write speed H:", 3, "Write speed H:", "", 2, { 0,  2, -1, -1, -1, -1},
2139                                                                          1, 0},
2140    {"Write speed L:", 3, "Write speed L:", "", 2, { 0,  2, -1, -1, -1, -1},
2141                                                                          1, 0},
2142    {"Write speed h:", 3, "Write speed h:", "", 2, { 0,  2, -1, -1, -1, -1},
2143                                                                          1, 0},
2144    {"Write speed l:", 3, "Write speed l:", "", 2, { 0,  2, -1, -1, -1, -1},
2145                                                                          1, 0},
2146    {"libburn    in use :", 3, "libburn    in use :", "", 2,
2147                                                { 0,  1, -1, -1, -1, -1}, 1, 1},
2148    {"libburn OS adapter:", 3, "libburn OS adapter:  ", "", 1,
2149                                                { 0, -1, -1, -1, -1, -1}, 1, 1},
2150    {"libisoburn in use :", 3, "libisoburn in use :", "", 2,
2151                                                { 0,  1, -1, -1, -1, -1}, 1, 1},
2152    {"libisofs   in use :", 3, "libisofs   in use :", "", 2,
2153                                                { 0,  1, -1, -1, -1, -1}, 1, 1},
2154    {"libjte     in use :", 3, "libjte     in use :", "", 2,
2155                                                { 0,  1, -1, -1, -1, -1}, 1, 1},
2156    {"xorriso version   :", 3, "xorriso version   :", "", 1,
2157                                                { 0, -1, -1, -1, -1, -1}, 1, 0},
2158    {"zisofs       :", 3, "zisofs       :", "", 1, { 0, -1, -1, -1, -1, -1},
2159                                                                          1, 0},
2160    {"@", 0, "@", "", 0, {-1, -1, -1, -1, -1, -1}, 0, 0}
2161  };
2162 
2163  struct Xorriso_sieve_big_filteR *f;
2164  int ret, i;
2165 
2166  for(i= 0; ; i++) {
2167    f= &(filters[i]);
2168    if(strcmp(f->name, "@") == 0)
2169  break;
2170    ret= Xorriso_sieve_add_filter(xorriso, f->name, f->channels, f->prefix,
2171                                  f->separators, f->num_words, f->word_idx,
2172                                  f->max_results, f->flag);
2173    if(ret <= 0)
2174      goto failure;
2175  }
2176  return(1);
2177 failure:
2178  Xorriso_sieve_dispose(xorriso, 0);
2179  return(-1);
2180 }
2181 
2182 
2183 /* Check for matching filter and eventually extract words.
2184    To be called by Xorriso_result, Xorriso_info, Xorriso_mark,
2185    and alike.
2186    Thus no own message output is allowed here !
2187    @param flag bit0-1= channel:
2188                        0= result channel
2189                        1= info channel
2190                        2= mark channel
2191 */
Xorriso_sieve_filter_msg(struct XorrisO * xorriso,char * msg,int flag)2192 int Xorriso_sieve_filter_msg(struct XorrisO *xorriso, char *msg, int flag)
2193 {
2194  int channel, ret, argc= 0, i, max_words, l, widx, skip;
2195  char **argv= NULL, *prefix_storage= NULL, *prefix, *cpt, *to_parse= NULL;
2196  struct Xorriso_msg_filteR *f;
2197  struct Xorriso_lsT *lst, *prev_lst, *next_lst;
2198 
2199  if(xorriso->msg_sieve == NULL || xorriso->msg_sieve_disabled)
2200    return(1);
2201 
2202  channel= flag & 3;
2203 
2204  for(f= xorriso->msg_sieve->first_filter; f != NULL; f= f->next) {
2205    if(!(f->channels & (1 << channel)))
2206  continue;
2207    prefix= f->prefix;
2208 
2209    if(prefix[0] == '?') {
2210      skip= 0;
2211      for(cpt= prefix; *cpt; cpt++)
2212        if(*cpt == '?')
2213          skip++;
2214        else
2215      break;
2216      l= strlen(prefix);
2217      if(strlen(msg) >= (unsigned int) l) {
2218        if(l - skip == 0 || strncmp(prefix + skip, msg + skip, l - skip) == 0) {
2219          Xorriso_free_meM(prefix_storage);
2220          prefix_storage= NULL;
2221          Xorriso_alloc_meM(prefix_storage, char, l + 1);
2222          strncpy(prefix_storage, msg, l);
2223          prefix_storage[l]= 0;
2224          prefix= prefix_storage;
2225        }
2226      }
2227    }
2228    if(prefix[0])
2229      if(strncmp(prefix, msg, strlen(prefix)) != 0)
2230  continue;
2231 
2232    if (to_parse != NULL)
2233      free(to_parse);
2234    to_parse= strdup(msg);
2235    if(to_parse == NULL)
2236      goto no_mem;
2237    l= strlen(to_parse);
2238    if(l > 0)
2239      if(to_parse[l - 1] == '\n')
2240        to_parse[l - 1]= 0;
2241 
2242    max_words= 0;
2243    if(f->last_word_line_end)
2244      if(f->num_words > 0)                /* Let last word take rest of line */
2245        max_words= f->word_idx[f->num_words - 1];
2246    if(max_words <= 0 && f->last_word_line_end) {
2247      /* Copy rest of line as single word because Xorriso_parse_line understands
2248         max_words == 0 as unlimited number of words. But here it is desired
2249         to get the rest of line already in argv[0].
2250      */
2251      max_words= 0;
2252      argv= calloc(1, sizeof(char *));
2253      if(argv == NULL)
2254        goto no_mem;
2255      argc= 1;
2256      argv[0]= strdup(to_parse + strlen(prefix));
2257      if(argv[0] == NULL)
2258        goto no_mem;
2259      ret= 1;
2260    } else {
2261      ret= Xorriso_parse_line(xorriso, to_parse, prefix, f->separators,
2262                              max_words, &argc, &argv, 0);
2263    }
2264    if(ret < 0)
2265      goto ex;
2266    if(ret == 0)
2267  continue;
2268 
2269    if(f->last_word_line_end && argc > max_words) {
2270      l= strlen(argv[max_words]);
2271      if(l > 0)
2272        if(argv[max_words][l - 1] == '\n')
2273          argv[max_words][l - 1]= 0;
2274    }
2275 
2276    if(f->max_results > 0 && f->num_results >= f->max_results) {
2277      /* Dispose surplus results */
2278      for(i= 0; i < f->num_words; i++) {
2279        if(f->results != NULL) {
2280          next_lst= f->results->next;
2281          Xorriso_lst_destroy(&(f->results), 0);
2282          f->results= next_lst;
2283        }
2284      }
2285      if(f->num_delivered > 0)
2286        (f->num_delivered)--;
2287      if(f->num_delivered == 0)
2288        f->next_to_deliver= NULL;
2289      f->num_results--;
2290    }
2291 
2292    if(f->results == NULL) {
2293      prev_lst= NULL;
2294    } else {
2295      for(prev_lst= f->results; prev_lst->next != NULL;
2296          prev_lst= prev_lst->next);
2297    }
2298    for(i= 0; i < f->num_words; i++) {
2299      widx= f->word_idx[i];
2300      if(widx >= argc || widx < 0)
2301        ret= Xorriso_lst_new(&lst, "", prev_lst, 0);
2302      else if(argv[widx] == NULL)
2303        ret= Xorriso_lst_new(&lst, "", prev_lst, 0);
2304      else
2305        ret= Xorriso_lst_new(&lst, argv[widx], prev_lst, 0);
2306      if(ret <= 0)
2307        goto no_mem;
2308      if(prev_lst == NULL)
2309        f->results= lst;
2310      prev_lst= lst;
2311    }
2312    (f->num_results)++;
2313    Xorriso__dispose_words(&argc, &argv);
2314  }
2315  ret= 1;
2316 ex:
2317  if(to_parse != NULL)
2318    free(to_parse);
2319  Xorriso_free_meM(prefix_storage);
2320  Xorriso__dispose_words(&argc, &argv);
2321  return(ret);
2322 no_mem:;
2323  Xorriso_no_malloc_memory(xorriso, NULL, 1); /* reports to stderr */
2324  ret= -1;
2325  goto ex;
2326 }
2327 
2328 
2329 /* ^^^^^^^^^^^^^^^^^^^^^^^^^^ Xorriso_msg_sievE ^^^^^^^^^^^^^^^^^^^^^^^^^^ */
2330 
2331 
Xorriso_result(struct XorrisO * xorriso,int flag)2332 int Xorriso_result(struct XorrisO *xorriso, int flag)
2333 /*
2334  bit0= no considerations or computations or dialog. Just put out.
2335 */
2336 {
2337  int ret, redirected= 0;
2338 
2339  if(flag&1)
2340    goto put_it_out;
2341  if(xorriso->request_to_abort)
2342    return(1);
2343  if(xorriso->msglist_stackfill > 0)
2344    if(xorriso->msglist_flags[xorriso->msglist_stackfill - 1] & 1)
2345      redirected= 1;
2346  if(xorriso->result_page_length>0 && !redirected) {
2347    ret= Xorriso_pager(xorriso,xorriso->result_line,2);
2348    if(ret<=0)
2349      return(ret);
2350    if(ret==2)
2351      return(1);
2352    if(xorriso->request_to_abort)
2353      return(1);
2354  }
2355 put_it_out:;
2356  xorriso->bar_is_fresh= 0;
2357  ret= Xorriso_write_to_channel(xorriso, xorriso->result_line, 1,0);
2358  return(ret);
2359 }
2360 
2361 
Xorriso_info(struct XorrisO * xorriso,int flag)2362 int Xorriso_info(struct XorrisO *xorriso, int flag)
2363 /*
2364  bit0= use pager (as with result)
2365  bit1= permission to suppress output
2366  bit2= insist in showing output
2367 */
2368 {
2369  int ret;
2370  static int note_sev= 0;
2371 
2372  if(flag&2)
2373    if(xorriso->request_to_abort)
2374      return(1);
2375 
2376  if(note_sev==0)
2377    Xorriso__text_to_sev("NOTE", &note_sev, 0);
2378  if(note_sev<xorriso->report_about_severity &&
2379     note_sev<xorriso->abort_on_severity && !(flag&4))
2380    return(1);
2381 
2382  if(flag&1) {
2383    ret= Xorriso_pager(xorriso,xorriso->info_text,2);
2384    if(ret<=0)
2385      return(ret);
2386    if(ret==2)
2387      return(1);
2388    if(flag&2)
2389      if(xorriso->request_to_abort)
2390        return(1);
2391  }
2392  xorriso->bar_is_fresh= 0;
2393  ret=Xorriso_write_to_channel(xorriso, xorriso->info_text, 2, 0);
2394  return(ret);
2395 }
2396 
2397 
Xorriso_mark(struct XorrisO * xorriso,int flag)2398 int Xorriso_mark(struct XorrisO *xorriso, int flag)
2399 {
2400  int ret= 1,r_ret,i_ret;
2401 
2402  if(xorriso->mark_text[0]==0)
2403    return(1);
2404  if(xorriso->packet_output)
2405    ret=Xorriso_write_to_channel(xorriso, xorriso->mark_text, 3, 0);
2406  else {
2407    sprintf(xorriso->result_line,"%s\n",xorriso->mark_text);
2408    r_ret= Xorriso_result(xorriso,1);
2409    strcpy(xorriso->info_text,xorriso->result_line);
2410    i_ret= Xorriso_info(xorriso,0);
2411    if(r_ret==0 || i_ret==0)
2412      ret= 0;
2413  }
2414  return(ret);
2415 }
2416 
2417 
Xorriso_restxt(struct XorrisO * xorriso,char * text)2418 int Xorriso_restxt(struct XorrisO *xorriso, char *text)
2419 {
2420  int ret;
2421 
2422  strncpy(xorriso->result_line,text,sizeof(xorriso->result_line)-1);
2423  xorriso->result_line[sizeof(xorriso->result_line)-1]= 0;
2424  ret= Xorriso_result(xorriso,0);
2425  return(ret);
2426 }
2427 
2428 
2429 /* @param flag bit0-7= purpose
2430                        0= ERRFILE
2431                        1= mark line (only to be put out if enabled)
2432 */
Xorriso_process_errfile(struct XorrisO * xorriso,int error_code,char msg_text[],int os_errno,int flag)2433 int Xorriso_process_errfile(struct XorrisO *xorriso,
2434                             int error_code, char msg_text[], int os_errno,
2435                             int flag)
2436 {
2437  char ttx[41];
2438  int purpose;
2439 
2440  if(strlen(msg_text)>SfileadrL)
2441    return(-1);
2442 
2443  purpose= flag&255;
2444  if(purpose==1 && !(xorriso->errfile_mode&1))
2445    return(2);
2446  if(xorriso->errfile_fp!=NULL) {
2447    if(purpose==1)
2448      fprintf(xorriso->errfile_fp, "----------------- %s  %s\n",
2449              msg_text, Ftimetxt(time(0), ttx, 1));
2450    else
2451      fprintf(xorriso->errfile_fp, "%s\n", msg_text);
2452    fflush(xorriso->errfile_fp);
2453    return(1);
2454  }
2455  if(xorriso->errfile_log[0]==0)
2456    return(1);
2457  if(strcmp(xorriso->errfile_log, "-")==0 ||
2458     strcmp(xorriso->errfile_log, "-R")==0) {
2459    if(purpose==1)
2460      sprintf(xorriso->result_line, "----------------- %s  %s\n",
2461              msg_text, Ftimetxt(time(0), ttx, 1));
2462    else
2463      sprintf(xorriso->result_line, "%s\n", msg_text);
2464    Xorriso_result(xorriso, 1);
2465    return(1);
2466  }
2467  if(strcmp(xorriso->errfile_log, "-I") == 0 &&
2468     xorriso->info_text != msg_text) { /* (Beware of stepping on own foot) */
2469    if(purpose==1)
2470      sprintf(xorriso->info_text, "ERRFILE_MARK=%s  %s\n",
2471              msg_text, Ftimetxt(time(0), ttx, 1));
2472    else
2473      sprintf(xorriso->info_text, "ERRFILE=%s\n", msg_text);
2474    Xorriso_info(xorriso, 0);
2475    return(1);
2476  }
2477  return(2);
2478 }
2479 
2480 
2481 #ifdef Xorriso_fetch_with_msg_queueS
2482 /* Important: This function must stay thread-safe with all use of xorriso. */
2483 #else
2484 /* Note: It is ok to submit xorriso->info_text as msg_text here. */
2485 #endif
2486 /* flag:
2487      bit0= for Xorriso_info() : use pager (as with result)
2488      bit1= for Xorriso_info() : permission to suppress output
2489      bit2..5= name prefix
2490        0="xorriso"
2491        1="libisofs"
2492        2="libburn"
2493        3="libisoburn"
2494        else: ""
2495      bit6= append carriage return rather than line feed (if not os_errno)
2496      bit7= perform Xorriso_process_msg_queues() first
2497      bit8= do not prepend name prefix and severity
2498 */
Xorriso_msgs_submit(struct XorrisO * xorriso,int error_code,char msg_text[],int os_errno,char severity[],int flag)2499 int Xorriso_msgs_submit(struct XorrisO *xorriso,
2500                         int error_code, char msg_text[], int os_errno,
2501                         char severity[], int flag)
2502 {
2503  int ret, lt, li, sev, i;
2504  char *sev_text= "FATAL", prefix[80], *text= NULL;
2505  static char pfx_list[20][16]= {
2506                    "xorriso : ", "libisofs: ", "libburn : ", "libisoburn: ",
2507                     "", "", "", "", "", "", "", "", "", "", "", "" };
2508 
2509  if(flag&128)
2510    Xorriso_process_msg_queues(xorriso, 0);
2511 
2512  if(strcmp(severity, "ERRFILE")==0)
2513    Xorriso_process_errfile(xorriso, error_code, msg_text, os_errno, 0);
2514 
2515  /* Set problem status */
2516  ret= Xorriso__text_to_sev(severity, &sev, 0);
2517  if(ret<=0)
2518    Xorriso__text_to_sev(sev_text, &sev, 0);
2519  else
2520    sev_text= severity;
2521  if(xorriso->problem_status<sev)
2522    Xorriso_set_problem_status(xorriso, sev_text, 0);
2523 
2524  /* Report problem event */
2525  if(sev<xorriso->report_about_severity && sev<xorriso->abort_on_severity)
2526    {ret= 2; goto ex;}
2527  lt= strlen(msg_text);
2528  if(!(flag & 256)) {
2529    sprintf(prefix,"%s%s : ", pfx_list[(flag>>2)&15], sev_text);
2530    li= strlen(prefix);
2531  } else {
2532    prefix[0]= 0;
2533    li= 0;
2534  }
2535  if(lt > ((int) sizeof(xorriso->info_text)) - li - 2)
2536    lt= sizeof(xorriso->info_text)-li-2;
2537 
2538 #ifdef Xorriso_fetch_with_msg_queueS
2539 
2540  Xorriso_alloc_meM(text, char, sizeof(xorriso->info_text));
2541 
2542 #else /* Xorriso_fetch_with_msg_queueS */
2543 
2544  text= xorriso->info_text;
2545 
2546 #endif /* ! Xorriso_fetch_with_msg_queueS */
2547 
2548  if(msg_text == text) {
2549    if(li > 0) {
2550      for(i= lt; i>=0; i--)
2551        msg_text[i+li]= msg_text[i];
2552      for(i=0; i<li; i++)
2553        msg_text[i]= prefix[i];
2554    }
2555  } else {
2556    if(li > 0)
2557      strcpy(text, prefix);
2558    strncpy(text + li, msg_text, lt);
2559  }
2560  if((flag&64) && os_errno<=0)
2561    text[li+lt]= '\r';
2562  else
2563    text[li+lt]= '\n';
2564  text[li+lt+1]= 0;
2565  if(os_errno>0)
2566    sprintf(text + strlen(text) - 1, " : %s\n", strerror(os_errno));
2567 
2568 #ifdef Xorriso_fetch_with_msg_queueS
2569 
2570  Xorriso_write_to_channel(xorriso, text, 2, 0);
2571 
2572 #else /* Xorriso_fetch_with_msg_queueS */
2573 
2574  Xorriso_info(xorriso,4|(flag&3));
2575 
2576 #endif /* ! Xorriso_fetch_with_msg_queueS */
2577 
2578 ex:;
2579 
2580 #ifdef Xorriso_fetch_with_msg_queueS
2581  Xorriso_free_meM(text);
2582 #endif /* ! Xorriso_fetch_with_msg_queueS */
2583 
2584  return(ret);
2585 }
2586 
2587 
2588 /* To be used with isoburn_set_msgs_submit()
2589 */
Xorriso_msgs_submit_void(void * xorriso,int error_code,char msg_text[],int os_errno,char severity[],int flag)2590 int Xorriso_msgs_submit_void(void *xorriso,
2591                         int error_code, char msg_text[], int os_errno,
2592                         char severity[], int flag)
2593 {
2594  int ret;
2595 
2596  ret= Xorriso_msgs_submit((struct XorrisO *) xorriso, error_code, msg_text,
2597                           os_errno, severity, flag);
2598  return(ret);
2599 }
2600 
2601 
2602 /** @return -1= abort , 0= no , 1= yes
2603 */
Xorriso_reassure(struct XorrisO * xorriso,char * cmd,char * which_will,int flag)2604 int Xorriso_reassure(struct XorrisO *xorriso, char *cmd, char *which_will,
2605                      int flag)
2606 {
2607  int ret;
2608 
2609  if(!xorriso->do_reassure)
2610    return(1);
2611  sprintf(xorriso->info_text, "Really perform %s which will %s ? (y/n)\n",
2612          cmd, which_will);
2613  Xorriso_info(xorriso, 4);
2614  do {
2615    ret= Xorriso_request_confirmation(xorriso, 2|4|16);
2616  } while(ret==3);
2617  if(ret==6 || ret==4) {
2618    sprintf(xorriso->info_text, "%s confirmed", cmd);
2619    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2620    return(1);
2621  }
2622  if(ret==2) {
2623    sprintf(xorriso->info_text, "%s aborted", cmd);
2624    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2625    return(-1);
2626  }
2627  sprintf(xorriso->info_text, "%s revoked", cmd);
2628  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2629  return(0);
2630 }
2631 
2632 
Xorriso_write_session_log(struct XorrisO * xorriso,int flag)2633 int Xorriso_write_session_log(struct XorrisO *xorriso, int flag)
2634 {
2635  FILE *fp= NULL;
2636  char *sfe= NULL, timetext[40], *rpt, *wpt;
2637  int ret;
2638 
2639  if(xorriso->session_logfile[0]==0)
2640    {ret= 2; goto ex;}
2641 
2642  Xorriso_alloc_meM(sfe, char, 5 * SfileadrL);
2643 
2644  fp= fopen(xorriso->session_logfile, "a");
2645  if(fp==0) {
2646    sprintf(xorriso->info_text, "-session_log: Cannot open file %s",
2647            Text_shellsafe(xorriso->session_logfile, sfe, 0));
2648    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2649    {ret= 0; goto ex;}
2650  }
2651  wpt= sfe;
2652  for(rpt= xorriso->volid; *rpt!=0; rpt++) {
2653    if(*rpt=='\n') {
2654      *(wpt++)= '\\';
2655      *(wpt++)= 'n';
2656    } else
2657      *(wpt++)= *rpt;
2658  }
2659  *wpt= 0;
2660  fprintf(fp, "%s %d %d %s\n",
2661          Ftimetxt(time(0), timetext, 2), xorriso->session_lba,
2662          xorriso->session_blocks, sfe);
2663  fclose(fp);
2664  ret= 1;
2665 ex:;
2666  Xorriso_free_meM(sfe);
2667  return(ret);
2668 }
2669 
2670 
Xorriso_status_filter(struct XorrisO * xorriso,char * filter,char * line,int flag)2671 int Xorriso_status_filter(struct XorrisO *xorriso, char *filter, char *line,
2672                           int flag)
2673 {
2674  if(filter!=NULL)
2675    if(filter[0]=='-')
2676      if(strncmp(filter, line, strlen(filter))!=0)
2677        return(0);
2678  return(1);
2679 }
2680 
2681 
Xorriso_status_result(struct XorrisO * xorriso,char * filter,FILE * fp,int flag)2682 int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp,
2683                           int flag)
2684 /*
2685 bit1= do only report to fp
2686 */
2687 {
2688  int ret;
2689 
2690  ret= Xorriso_status_filter(xorriso, filter, xorriso->result_line, 0);
2691  if(ret <= 0)
2692    return(2);
2693  if(!(flag&2))
2694    Xorriso_result(xorriso,0);
2695  if(fp!=NULL) {
2696    ret= fwrite(xorriso->result_line,strlen(xorriso->result_line),1,fp);
2697    if(ret<=0)
2698      return(ret);
2699  }
2700  return(1);
2701 }
2702 
2703 
2704 /*
2705  bit0= do only report non-default settings
2706  bit1= do only report to fp
2707 */
Xorriso_boot_status_sysarea(struct XorrisO * xorriso,char * filter,FILE * fp,int flag)2708 int Xorriso_boot_status_sysarea(struct XorrisO *xorriso, char *filter,
2709                                 FILE *fp, int flag)
2710 {
2711  char *line, *form= "any", *spec= "system_area=";
2712  int sa_type;
2713 
2714  line= xorriso->result_line;
2715 
2716  sa_type= (xorriso->system_area_options & 0xfc) >> 2;
2717  if(sa_type != 0)
2718    return(2);
2719  if (xorriso->system_area_disk_path[0] == 0 && (flag & 1))
2720    return(2);
2721 
2722  if(xorriso->system_area_options & 1) {
2723    form= "grub";
2724    if(xorriso->system_area_options & (1 << 14))
2725      spec= "grub2_mbr=";
2726  } else if(xorriso->system_area_options & 2) {
2727    form= "isolinux";
2728  } if(xorriso->system_area_options & (1 << 14)) {
2729    form= "grub";
2730    spec= "grub2_mbr=";
2731  }
2732  sprintf(line, "-boot_image %s %s", form, spec);
2733  Text_shellsafe(xorriso->system_area_disk_path, line, 1);
2734  strcat(line, "\n");
2735  Xorriso_status_result(xorriso, filter, fp, flag & 2);
2736  return(1);
2737 }
2738 
2739 
Xorriso__speedname(int speed)2740 static char *Xorriso__speedname(int speed)
2741 {
2742  static char name[64];
2743 
2744  if(speed > 0) {
2745    sprintf(name, "%dkB/s", speed);
2746    return(name);
2747  } else if(speed == 0) {
2748    return("max");
2749  } else if(speed == -1) {
2750    return("min");
2751  } else if(speed == -2) {
2752    return("none");
2753  }
2754  sprintf(name, "%d", speed);
2755  return(name);
2756 }
2757 
2758 
Xorriso_status(struct XorrisO * xorriso,char * filter,FILE * fp,int flag)2759 int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
2760 /*
2761  bit0= do only report non-default settings
2762  bit1= do only report to fp
2763  bit2= report current -resume status even if bit0 is set, but only if valid
2764  bit3= report readline history
2765  bit4= report -resume options indirectly as
2766               -options_from_file:${resume_state_file}_pos
2767 */
2768 {
2769  int is_default, no_defaults, i, ret, adr_mode, do_single, behavior;
2770  int show_indev= 1, show_outdev= 1, show_dev= 0;
2771  int part_table_implicit= 0;
2772  char *line, *sfe= NULL, mode[80], *form, *treatment;
2773  char *in_pt, *out_pt, *nl_charset, *local_charset, *mode_pt;
2774  char *dev_filter= NULL, *xorriso_id= NULL;
2775  static char channel_prefixes[4][4]= {".","R","I","M"};
2776  static char load_names[][20]= {"auto", "session", "track", "lba", "volid"};
2777  static int max_load_mode= 4;
2778  static char scsi_family[8][8]=
2779                               {"default", "sr", "scd", "st", "sg", "", "", ""};
2780  struct Xorriso_lsT *paths, *leafs, *s, *plst, *vlst;
2781 
2782  Xorriso_alloc_meM(sfe, char, 5 * SfileadrL + 80);
2783  Xorriso_alloc_meM(xorriso_id, char, 129);
2784 
2785  no_defaults= flag&1;
2786  line= xorriso->result_line;
2787 
2788  if(xorriso->no_rc) {
2789    sprintf(line,"-no_rc\n");
2790    Xorriso_status_result(xorriso,filter,fp,flag&2);
2791  }
2792 
2793  is_default= strcmp(xorriso->list_delimiter, "--") == 0;
2794  sprintf(line,"-list_delimiter %s\n", xorriso->list_delimiter);
2795  if(!(is_default && no_defaults))
2796    Xorriso_status_result(xorriso,filter,fp,flag&2);
2797 
2798  is_default= 0;
2799  if(xorriso->dialog == 2)
2800    sprintf(line,"-dialog on\n");
2801  else if(xorriso->dialog == 1)
2802    sprintf(line,"-dialog single_line\n");
2803  else {
2804    sprintf(line,"-dialog off\n");
2805    is_default= 1;
2806  }
2807  if(!(is_default && no_defaults))
2808    Xorriso_status_result(xorriso,filter,fp,flag&2);
2809 
2810  is_default= (xorriso->result_page_length==0 && xorriso->result_page_width==80);
2811  sprintf(line,"-page %d %d\n",
2812               (xorriso->result_page_length>=0?xorriso->result_page_length
2813                                            :-xorriso->result_page_length),
2814               xorriso->result_page_width);
2815  if(!(is_default && no_defaults))
2816    Xorriso_status_result(xorriso,filter,fp,flag&2);
2817 
2818  is_default= (xorriso->use_stdin==0);
2819  sprintf(line,"-use_readline %s\n", (xorriso->use_stdin?"off":"on"));
2820  if(!(is_default && no_defaults))
2821    Xorriso_status_result(xorriso,filter,fp,flag&2);
2822 
2823  is_default= (xorriso->sh_style_result == 0);
2824  sprintf(line, "-sh_style_result %s\n",
2825          xorriso->sh_style_result ? "on" : "off");
2826  if(!(is_default && no_defaults))
2827    Xorriso_status_result(xorriso,filter,fp,flag&2);
2828 
2829  is_default= (xorriso->bsl_interpretation == 0);
2830  strcpy(line, "-backslash_codes ");
2831  if(xorriso->bsl_interpretation == 0)
2832    strcat(line, "off");
2833  else if(xorriso->bsl_interpretation == (3 | 16 | 32 | 64))
2834    strcat(line, "on");
2835  else {
2836    if((xorriso->bsl_interpretation & 3) == 1)
2837      strcat(line, "in_double_quotes");
2838    else if((xorriso->bsl_interpretation & 3) == 2)
2839      strcat(line, "in_quotes");
2840    else if((xorriso->bsl_interpretation & 3) == 3)
2841      strcat(line, "with_quoted_input");
2842    if(xorriso->bsl_interpretation & 16) {
2843      if(strlen(line) > 17)
2844        strcat(line, ":");
2845      strcat(line, "with_program_arguments");
2846    }
2847    if((xorriso->bsl_interpretation & (32 | 64)) == (32 | 64)) {
2848      if(strlen(line) > 17)
2849        strcat(line, ":");
2850      strcat(line, "encode_output");
2851    } else {
2852      if(xorriso->bsl_interpretation & 32) {
2853        if(strlen(line) > 17)
2854          strcat(line, ":");
2855        strcat(line, "encode_results");
2856      }
2857      if(xorriso->bsl_interpretation & 64) {
2858        if(strlen(line) > 17)
2859          strcat(line, ":");
2860        strcat(line, "encode_infos");
2861      }
2862    }
2863  }
2864  strcat(line, "\n");
2865  if(!(is_default && no_defaults))
2866    Xorriso_status_result(xorriso,filter,fp,flag&2);
2867 
2868  is_default= !xorriso->packet_output;
2869  sprintf(line,"-pkt_output %s\n",(xorriso->packet_output?"on":"off"));
2870  if(!(is_default && no_defaults))
2871    Xorriso_status_result(xorriso,filter,fp,flag&2);
2872 
2873  for(i=0;i<4;i++) {
2874    is_default= (xorriso->logfile[i][0] == 0);
2875    sprintf(line,"-logfile %s %s\n",
2876            channel_prefixes[i],Text_shellsafe(xorriso->logfile[i],sfe,0));
2877    if(!(is_default && no_defaults))
2878      Xorriso_status_result(xorriso,filter,fp,flag&2);
2879  }
2880 
2881  is_default= (xorriso->errfile_log[0]==0);
2882  sprintf(line,"-errfile_log %s\n",Text_shellsafe(xorriso->errfile_log,sfe,0));
2883  if(!(is_default && no_defaults))
2884    Xorriso_status_result(xorriso,filter,fp,flag&2);
2885 
2886  if(xorriso->check_media_default == NULL) {
2887    is_default= 1;
2888    sprintf(line, "-check_media_defaults reset=now %s\n",
2889            xorriso->list_delimiter);
2890  } else {
2891    ret= Xorriso_check_media_list_job(xorriso, xorriso->check_media_default,
2892                                      line, no_defaults);
2893    is_default= (ret == 2);
2894    strcat(line, "\n");
2895  }
2896  if(!(is_default && no_defaults))
2897    Xorriso_status_result(xorriso,filter,fp,flag&2);
2898 
2899  behavior= Xorriso__get_signal_behavior(0);
2900  is_default= (behavior == 1);
2901  treatment= "on";
2902  if(behavior == 0)
2903    treatment= "off";
2904  else if(behavior == 2)
2905    treatment= "sig_dfl";
2906  else if(behavior == 3)
2907    treatment= "sig_ign";
2908  sprintf(line,"-signal_handling %s\n", treatment);
2909  if(!(is_default && no_defaults))
2910    Xorriso_status_result(xorriso,filter,fp,flag&2);
2911 
2912  is_default= (xorriso->img_read_error_mode==2);
2913  treatment= "best_effort";
2914  if(xorriso->img_read_error_mode==1)
2915    treatment= "failure";
2916  else if(xorriso->img_read_error_mode==2)
2917    treatment= "fatal";
2918  sprintf(line,"-error_behavior image_loading %s\n", treatment);
2919  if(!(is_default && no_defaults))
2920    Xorriso_status_result(xorriso,filter,fp,flag&2);
2921  is_default= (xorriso->extract_error_mode == 1);
2922  treatment= "keep";
2923  if(xorriso->extract_error_mode == 0)
2924    treatment= "best_effort";
2925  else if(xorriso->extract_error_mode == 2)
2926    treatment= "delete";
2927  sprintf(line,"-error_behavior file_extraction %s\n", treatment);
2928  if(!(is_default && no_defaults))
2929    Xorriso_status_result(xorriso,filter,fp,flag&2);
2930 
2931  is_default= (xorriso->mark_text[0]==0);
2932  sprintf(line,"-mark %s\n",Text_shellsafe(xorriso->mark_text,sfe,0));
2933  if(!(is_default && no_defaults))
2934    Xorriso_status_result(xorriso,filter,fp,flag&2);
2935 
2936  is_default= (xorriso->temp_mem_limit==16*1024*1024);
2937  if((xorriso->temp_mem_limit/1024/1024)*1024*1024==xorriso->temp_mem_limit)
2938    sprintf(line,"-temp_mem_limit %dm\n", xorriso->temp_mem_limit/1024/1024);
2939  else
2940    sprintf(line,"-temp_mem_limit %dk\n", xorriso->temp_mem_limit/1024);
2941  if(!(is_default && no_defaults))
2942    Xorriso_status_result(xorriso,filter,fp,flag&2);
2943 
2944 
2945  sprintf(line,"-prog %s\n",Text_shellsafe(xorriso->progname,sfe,0));
2946  Xorriso_status_result(xorriso,filter,fp,flag&2);
2947 
2948  if(xorriso->ban_stdio_write) {
2949    sprintf(line,"-ban_stdio_write\n");
2950    Xorriso_status_result(xorriso,filter,fp,flag&2);
2951  }
2952 
2953  is_default= ((xorriso->early_stdio_test & 14) == 0);
2954  sprintf(line, "-early_stdio_test %s\n",
2955                xorriso->early_stdio_test & 6 ? xorriso->early_stdio_test & 8 ?
2956                "appendable_wo" : "on" : "off");
2957  if(!(is_default && no_defaults))
2958    Xorriso_status_result(xorriso,filter,fp,flag&2);
2959 
2960  is_default= ((xorriso->cache_default & 3) == 3);
2961  sprintf(line, "-data_cache_size ");
2962  if(xorriso->cache_default & 1)
2963    sprintf(line + strlen(line), "default ");
2964  else
2965    sprintf(line + strlen(line), "%d ", xorriso->cache_num_tiles);
2966  if(xorriso->cache_default & 2)
2967    sprintf(line + strlen(line), "default\n");
2968  else
2969    sprintf(line + strlen(line), "%d\n", xorriso->cache_tile_blocks);
2970  if(!(is_default && no_defaults))
2971    Xorriso_status_result(xorriso,filter,fp,flag&2);
2972 
2973  is_default= (xorriso->allow_restore==0 && xorriso->do_concat_split==1 &&
2974               xorriso->do_auto_chmod==0 && xorriso->drives_exclusive == 1);
2975  mode_pt= "off";
2976  if(xorriso->allow_restore == -2)
2977    mode_pt= "blocked";
2978  else if(xorriso->allow_restore == -1)
2979    mode_pt= "banned";
2980  else if(xorriso->allow_restore == 1)
2981    mode_pt= "on";
2982  else if(xorriso->allow_restore == 2)
2983    mode_pt= "device_files";
2984  if(xorriso->allow_restore == -1)
2985    sprintf(line,"-osirrox %s\n", mode_pt);
2986  else
2987    sprintf(line,"-osirrox %s:%s:%s:%s:%s:%s\n", mode_pt,
2988          xorriso->do_concat_split ? "concat_split_on" : "concat_split_off",
2989          xorriso->do_auto_chmod ? "auto_chmod_on" : "auto_chmod_off",
2990          xorriso->do_restore_sort_lba ? "sort_lba_on" : "sort_lba_off",
2991          xorriso->drives_exclusive ? "o_excl_on" : "o_excl_off",
2992          (xorriso->do_strict_acl & 1) ? "strict_acl_on" : "strict_acl_off"
2993         );
2994  if(!(is_default && no_defaults))
2995    Xorriso_status_result(xorriso,filter,fp,flag&2);
2996 
2997  is_default= (xorriso->mount_opts_flag == 0);
2998   sprintf(line,"-mount_opts %s\n",
2999           xorriso->mount_opts_flag & 1 ? "shared" : "exclusive");
3000  if(!(is_default && no_defaults))
3001    Xorriso_status_result(xorriso,filter,fp,flag&2);
3002 
3003  Xorriso_boot_image_status(xorriso, filter, fp, flag & 3);
3004 
3005  Xorriso_boot_status_sysarea(xorriso, filter, fp, flag & 3);
3006 
3007  is_default= (xorriso->partition_offset == 0);
3008  sprintf(line,"-boot_image any partition_offset=%lu\n",
3009               (unsigned long int) xorriso->partition_offset);
3010  if(!(is_default && no_defaults))
3011    Xorriso_status_result(xorriso,filter,fp,flag&2);
3012  is_default= (xorriso->partition_secs_per_head == 0);
3013  sprintf(line,"-boot_image any partition_sec_hd=%lu\n",
3014               (unsigned long int) xorriso->partition_secs_per_head);
3015  if(!(is_default && no_defaults))
3016    Xorriso_status_result(xorriso,filter,fp,flag&2);
3017  is_default= (xorriso->partition_heads_per_cyl == 0);
3018  sprintf(line,"-boot_image any partition_hd_cyl=%lu\n",
3019               (unsigned long int) xorriso->partition_heads_per_cyl);
3020  if(!(is_default && no_defaults))
3021    Xorriso_status_result(xorriso,filter,fp,flag&2);
3022 
3023  ret= (xorriso->system_area_options & 0x300) >> 8;
3024  is_default= (ret == 0);
3025  sprintf(line,"-boot_image any partition_cyl_align=%s\n",
3026          ret == 0 ? "auto" : ret == 1 ? "on" : ret == 3 ? "all" : "off");
3027  if(!(is_default && no_defaults))
3028    Xorriso_status_result(xorriso,filter,fp,flag&2);
3029 
3030  if((xorriso->system_area_disk_path[0] || !part_table_implicit) &&
3031     (xorriso->partition_offset == 0 || (xorriso->system_area_options & 2))) {
3032    is_default= ((xorriso->system_area_options & 3) == 0);
3033    sprintf(line,"-boot_image %s partition_table=%s\n",
3034            xorriso->system_area_options & 2 ? "isolinux" : "grub",
3035            xorriso->system_area_options & 3 ? "on" : "off");
3036    if(!(is_default && no_defaults))
3037      Xorriso_status_result(xorriso,filter,fp,flag&2);
3038  }
3039 
3040  is_default= ((xorriso->system_area_options & (1 << 15)) == 0);
3041  sprintf(line, "-boot_image any mbr_force_bootable=%s\n",
3042          (xorriso->system_area_options & (1 << 15)) ? "on" : "off");
3043  if(!(is_default && no_defaults))
3044    Xorriso_status_result(xorriso,filter,fp,flag&2);
3045 
3046  is_default= (xorriso->appended_as_gpt == 0 && xorriso->appended_as_apm == 0);
3047  if(is_default) {
3048    sprintf(line, "-boot_image any appended_part_as=mbr\n");
3049    if(!no_defaults)
3050      Xorriso_status_result(xorriso,filter,fp,flag&2);
3051  } else {
3052    if(xorriso->appended_as_gpt) {
3053      sprintf(line, "-boot_image any appended_part_as=gpt\n");
3054      Xorriso_status_result(xorriso,filter,fp,flag&2);
3055    }
3056    if(xorriso->appended_as_apm) {
3057      sprintf(line, "-boot_image any appended_part_as=apm\n");
3058      Xorriso_status_result(xorriso,filter,fp,flag&2);
3059    }
3060  }
3061 
3062  is_default= (xorriso->part_like_isohybrid == 0);
3063  sprintf(line, "-boot_image any part_like_isohybrid=%s\n",
3064          xorriso->part_like_isohybrid ? "on" : "off");
3065  if(!(is_default && no_defaults))
3066    Xorriso_status_result(xorriso,filter,fp,flag&2);
3067 
3068  is_default= (xorriso->iso_mbr_part_type == -1);
3069  sprintf(line, "-boot_image any iso_mbr_part_type=");
3070  if(xorriso->iso_mbr_part_type == -1)
3071    sprintf(line + strlen(line), "default\n");
3072  else
3073    sprintf(line + strlen(line), "0x%-2.2x\n",
3074            (unsigned int) xorriso->iso_mbr_part_type);
3075  if(!(is_default && no_defaults))
3076    Xorriso_status_result(xorriso,filter,fp,flag&2);
3077 
3078  is_default= (xorriso->gpt_guid_mode == 0);
3079  sprintf(line, "-boot_image any gpt_disk_guid=%s",
3080          xorriso->gpt_guid_mode == 0 ? "random" :
3081          xorriso->gpt_guid_mode == 2 ? "volume_date_uuid" : "");
3082  if(xorriso->gpt_guid_mode == 1)
3083    for(i= 0; i < 16; i++)
3084      sprintf(line + strlen(line), "%-2.2x",
3085              (unsigned int) xorriso->gpt_guid[i]);
3086  strcat(line, "\n");
3087  if(!(is_default && no_defaults))
3088    Xorriso_status_result(xorriso,filter,fp,flag&2);
3089 
3090  ret= ((xorriso->system_area_options & 0x3cfc) == 0x400);
3091  is_default= (ret == 0);
3092  sprintf(line, "-boot_image any chrp_boot_part=%s\n",
3093          ret == 1 ? "on" : "off");
3094  if(!(is_default && no_defaults))
3095    Xorriso_status_result(xorriso, filter, fp, flag & 2);
3096 
3097  is_default= (xorriso->prep_partition[0] == 0);
3098  sprintf(line,"-boot_image any prep_boot_part=%s\n",
3099               Text_shellsafe(xorriso->prep_partition, sfe, 0));
3100  if(!(is_default && no_defaults))
3101    Xorriso_status_result(xorriso, filter, fp, flag & 2);
3102 
3103  is_default= (xorriso->efi_boot_partition[0] == 0);
3104  sprintf(line,"-boot_image any efi_boot_part=%s\n",
3105               Text_shellsafe(xorriso->efi_boot_partition, sfe, 0));
3106  if(!(is_default && no_defaults))
3107    Xorriso_status_result(xorriso, filter, fp, flag & 2);
3108 
3109 #ifdef Xorriso_with_isohybriD
3110  if(strcmp(form, "isolinux") == 0) {
3111    static char modes[4][6]= {"off", "auto", "on", "force"};
3112    is_default= (xorriso->boot_image_isohybrid == 1);
3113    sprintf(line,"-boot_image isolinux isohybrid=%s\n",
3114            modes[xorriso->boot_image_isohybrid & 3]);
3115    if(!(is_default && no_defaults))
3116      Xorriso_status_result(xorriso,filter,fp,flag&2);
3117  }
3118 #endif /* Xorriso_with_isohybriD */
3119 
3120  is_default= 1;
3121  for(i= 0; i < 8; i++)
3122    if(xorriso->hfsp_serial_number[i])
3123      is_default= 0;
3124  sprintf(line, "-boot_image any hfsplus_serial=");
3125  for(i= 0; i < 8; i++)
3126    sprintf(line + strlen(line), "%-2.2X",
3127            (unsigned int) xorriso->hfsp_serial_number[i]);
3128  strcat(line, "\n");
3129  if(!(is_default && no_defaults))
3130    Xorriso_status_result(xorriso, filter, fp, flag & 2);
3131 
3132  is_default= (xorriso->hfsp_block_size == 0);
3133  sprintf(line, "-boot_image any hfsplus_block_size=%d\n",
3134                xorriso->hfsp_block_size);
3135  if(!(is_default && no_defaults))
3136    Xorriso_status_result(xorriso, filter, fp, flag & 2);
3137 
3138  is_default= (xorriso->apm_block_size == 0);
3139  sprintf(line, "-boot_image any apm_block_size=%d\n",
3140                xorriso->apm_block_size);
3141  if(!(is_default && no_defaults))
3142    Xorriso_status_result(xorriso, filter, fp, flag & 2);
3143 
3144  sprintf(line,"-cd ");
3145  if(filter != NULL)
3146    if(strncmp(filter, "-cdi", 4) == 0)
3147      sprintf(line,"-cdi ");
3148  sprintf(line + strlen(line),"%s\n",
3149          (xorriso->wdi[0] ? Text_shellsafe(xorriso->wdi,sfe,0) : "'/'"));
3150  Xorriso_status_result(xorriso,filter,fp,flag&2);
3151  sprintf(line,"-cdx %s\n",
3152          (xorriso->wdx[0] ? Text_shellsafe(xorriso->wdx,sfe,0) : "'/'"));
3153  Xorriso_status_result(xorriso,filter,fp,flag&2);
3154 
3155  is_default= (xorriso->split_size==0);
3156  strcpy(line,"-split_size ");
3157  if(xorriso->split_size % (1024*1024) || xorriso->split_size==0) {
3158    Sfile_off_t_text(line+strlen(line), xorriso->split_size, 0);
3159  } else {
3160    Sfile_off_t_text(line+strlen(line), xorriso->split_size / (1024*1024), 0);
3161    strcat(line, "m");
3162  }
3163  strcat(line, "\n");
3164  if(!(is_default && no_defaults))
3165    Xorriso_status_result(xorriso,filter,fp,flag&2);
3166 
3167  is_default= (xorriso->add_plainly==0);
3168  sprintf(line,"-add_plainly %s\n",
3169          (xorriso->add_plainly == 1 ? "unknown" :
3170           xorriso->add_plainly == 2 ? "dashed" :
3171           xorriso->add_plainly == 3 ? "any" : "none"));
3172  if(!(is_default && no_defaults))
3173    Xorriso_status_result(xorriso,filter,fp,flag&2);
3174 
3175  ret= Exclusions_get_descrs(xorriso->disk_exclusions, &paths, &leafs, 0);
3176  if(ret>0) {
3177    for(; paths!=NULL; paths= paths->next) {
3178      sprintf(line, "-not_paths %s %s\n",
3179              Text_shellsafe(paths->text, sfe, 0), xorriso->list_delimiter);
3180      Xorriso_status_result(xorriso,filter,fp,flag&2);
3181    }
3182    for(; leafs!=NULL; leafs= leafs->next) {
3183      sprintf(line,"-not_leaf %s\n", Text_shellsafe(leafs->text, sfe, 0));
3184      Xorriso_status_result(xorriso,filter,fp,flag&2);
3185    }
3186  }
3187 
3188  is_default= (xorriso->file_name_limit == 255);
3189  sprintf(line, "-file_name_limit %d\n", xorriso->file_name_limit);
3190  if(!(is_default && no_defaults))
3191    Xorriso_status_result(xorriso,filter,fp,flag&2);
3192 
3193  is_default= (xorriso->file_size_limit ==
3194               Xorriso_default_file_size_limiT);
3195  if(xorriso->file_size_limit <= 0)
3196    sprintf(line, "-file_size_limit off %s\n", xorriso->list_delimiter);
3197  else
3198    sprintf(line, "-file_size_limit %.f %s\n",
3199            (double) xorriso->file_size_limit, xorriso->list_delimiter);
3200  if(!(is_default && no_defaults))
3201    Xorriso_status_result(xorriso,filter,fp,flag&2);
3202 
3203  is_default= (xorriso->disk_excl_mode==1);
3204  sprintf(line, "-not_mgt %s:%s:%s:%s\n",
3205          (xorriso->disk_excl_mode&1 ? "on" : "off"),
3206          (xorriso->disk_excl_mode&2 ? "param_on" : "param_off"),
3207          (xorriso->disk_excl_mode&4 ? "subtree_on" : "subtree_off"),
3208          (xorriso->disk_excl_mode&8 ? "ignore_on" : "ignore_off"));
3209  if(!(is_default && no_defaults))
3210    Xorriso_status_result(xorriso,filter,fp,flag&2);
3211 
3212  is_default= (xorriso->do_iso_rr_pattern==1);
3213  sprintf(line,"-iso_rr_pattern %s\n",
3214          (xorriso->do_iso_rr_pattern == 1 ? "on" :
3215          (xorriso->do_iso_rr_pattern == 2 ? "ls" : "off")));
3216  if(!(is_default && no_defaults))
3217    Xorriso_status_result(xorriso,filter,fp,flag&2);
3218 
3219  is_default= (xorriso->do_disk_pattern==2);
3220  sprintf(line,"-disk_pattern %s\n",
3221          (xorriso->do_disk_pattern == 1 ? "on" :
3222          (xorriso->do_disk_pattern == 2 ? "ls" : "off")));
3223  if(!(is_default && no_defaults))
3224    Xorriso_status_result(xorriso,filter,fp,flag&2);
3225 
3226  is_default= xorriso->volid_default;
3227  sprintf(line,"-volid %s\n",Text_shellsafe(xorriso->volid,sfe,0));
3228  if(!(is_default && no_defaults))
3229    Xorriso_status_result(xorriso,filter,fp,flag&2);
3230  if(is_default && xorriso->loaded_volid[0] &&
3231     strcmp(xorriso->loaded_volid, xorriso->volid)!=0 && !no_defaults) {
3232    sprintf(line,"# loaded image effective -volid %s\n",
3233            Text_shellsafe(xorriso->loaded_volid,sfe,0));
3234    Xorriso_status_result(xorriso,filter,fp,flag&2);
3235  }
3236 
3237  Xorriso_preparer_string(xorriso, xorriso_id, 0);
3238  is_default= (strcmp(xorriso->preparer_id, xorriso_id) == 0);
3239  sprintf(line,"-preparer_id %s\n",Text_shellsafe(xorriso->preparer_id,sfe,0));
3240  if(!(is_default && no_defaults))
3241    Xorriso_status_result(xorriso,filter,fp,flag&2);
3242 
3243  is_default= (xorriso->publisher[0]==0);
3244  sprintf(line,"-publisher %s\n",Text_shellsafe(xorriso->publisher,sfe,0));
3245  if(!(is_default && no_defaults))
3246    Xorriso_status_result(xorriso,filter,fp,flag&2);
3247 
3248  is_default= (xorriso->application_id[0]==0);
3249  sprintf(line,"-application_id %s\n",
3250          Text_shellsafe(xorriso->application_id,sfe,0));
3251  if(!(is_default && no_defaults))
3252    Xorriso_status_result(xorriso,filter,fp,flag&2);
3253 
3254  is_default= (xorriso->system_id[0]==0);
3255  sprintf(line,"-system_id %s\n", Text_shellsafe(xorriso->system_id,sfe,0));
3256  if(!(is_default && no_defaults))
3257    Xorriso_status_result(xorriso,filter,fp,flag&2);
3258 
3259  is_default= (xorriso->volset_id[0]==0);
3260  sprintf(line,"-volset_id %s\n", Text_shellsafe(xorriso->volset_id,sfe,0));
3261  if(!(is_default && no_defaults))
3262    Xorriso_status_result(xorriso,filter,fp,flag&2);
3263 
3264  is_default= (xorriso->vol_creation_time == 0);
3265  sprintf(line,"-volume_date c %s\n",
3266          is_default ? "default" :
3267          Ftimetxt(xorriso->vol_creation_time, sfe, 2));
3268  if(!(is_default && no_defaults))
3269    Xorriso_status_result(xorriso,filter,fp,flag&2);
3270 
3271  is_default= (xorriso->vol_modification_time == 0);
3272  sprintf(line,"-volume_date m %s\n",
3273          xorriso->vol_uuid[0] ? "overridden" :
3274          is_default ? "default" :
3275          Ftimetxt(xorriso->vol_modification_time, sfe, 2));
3276  if(!(is_default && no_defaults))
3277    Xorriso_status_result(xorriso,filter,fp,flag&2);
3278 
3279  is_default= (xorriso->vol_expiration_time == 0);
3280  sprintf(line,"-volume_date x %s\n",
3281          is_default ? "default" :
3282          Ftimetxt(xorriso->vol_expiration_time, sfe, 2));
3283  if(!(is_default && no_defaults))
3284    Xorriso_status_result(xorriso,filter,fp,flag&2);
3285 
3286  is_default= (xorriso->vol_effective_time == 0);
3287  sprintf(line,"-volume_date f %s\n",
3288          is_default ? "default" :
3289          Ftimetxt(xorriso->vol_effective_time, sfe, 2));
3290  if(!(is_default && no_defaults))
3291    Xorriso_status_result(xorriso,filter,fp,flag&2);
3292 
3293  is_default= (xorriso->vol_uuid[0] == 0);
3294  sprintf(line,"-volume_date uuid %s\n",
3295          Text_shellsafe(xorriso->vol_uuid,sfe,0));
3296  if(!(is_default && no_defaults))
3297    Xorriso_status_result(xorriso,filter,fp,flag&2);
3298 
3299  is_default= (xorriso->all_file_dates[0] == 0);
3300  sprintf(line,"-volume_date all_file_dates %s\n",
3301          Text_shellsafe(xorriso->all_file_dates,sfe,0));
3302  if(!(is_default && no_defaults))
3303    Xorriso_status_result(xorriso,filter,fp,flag&2);
3304 
3305  is_default= (xorriso->copyright_file[0] == 0);
3306  sprintf(line,"-copyright_file %s\n",
3307         Text_shellsafe(xorriso->copyright_file,sfe,0));
3308  if(!(is_default && no_defaults))
3309    Xorriso_status_result(xorriso,filter,fp,flag&2);
3310 
3311  is_default= (xorriso->biblio_file[0]==0);
3312  sprintf(line,"-biblio_file %s\n",Text_shellsafe(xorriso->biblio_file,sfe,0));
3313  if(!(is_default && no_defaults))
3314    Xorriso_status_result(xorriso,filter,fp,flag&2);
3315 
3316  is_default= (xorriso->abstract_file[0]==0);
3317  sprintf(line,"-abstract_file %s\n",
3318          Text_shellsafe(xorriso->abstract_file,sfe,0));
3319  if(!(is_default && no_defaults))
3320    Xorriso_status_result(xorriso,filter,fp,flag&2);
3321 
3322  is_default= (strcmp(xorriso->application_use, " ") == 0);
3323  sprintf(line, "-application_use %s\n",
3324          Text_shellsafe(xorriso->application_use, sfe, 0));
3325  if(!(is_default && no_defaults))
3326    Xorriso_status_result(xorriso,filter,fp,flag&2);
3327 
3328  is_default= (xorriso->do_joliet==0);
3329  sprintf(line,"-joliet %s\n", (xorriso->do_joliet == 1 ? "on" : "off"));
3330  if(!(is_default && no_defaults))
3331    Xorriso_status_result(xorriso,filter,fp,flag&2);
3332 
3333  is_default= (xorriso->do_rockridge == 1);
3334  sprintf(line, "-rockridge %s\n", (xorriso->do_rockridge == 1 ? "on" : "off"));
3335  if(!(is_default && no_defaults))
3336    Xorriso_status_result(xorriso,filter,fp,flag&2);
3337 
3338  is_default= (xorriso->do_hfsplus == 0);
3339  sprintf(line,"-hfsplus %s\n", (xorriso->do_hfsplus == 1 ? "on" : "off"));
3340  if(!(is_default && no_defaults))
3341    Xorriso_status_result(xorriso,filter,fp,flag&2);
3342 
3343  Xorriso_lst_get_last(xorriso->jigdo_params, &plst, 0);
3344  Xorriso_lst_get_last(xorriso->jigdo_values, &vlst, 0);
3345  if(plst == NULL || vlst == NULL) {
3346    is_default= 1;
3347    sprintf(line,"-jigdo clear 'all'\n");
3348    if(!(is_default && no_defaults))
3349      Xorriso_status_result(xorriso, filter, fp, flag & 2);
3350  }
3351  while(plst != NULL && vlst != NULL) {
3352    sprintf(line,"-jigdo %s %s\n", Xorriso_lst_get_text(plst, 0),
3353            Text_shellsafe(Xorriso_lst_get_text(vlst, 0), sfe, 0));
3354    Xorriso_status_result(xorriso, filter, fp, flag & 2);
3355    plst= Xorriso_lst_get_prev(plst, 0);
3356    vlst= Xorriso_lst_get_prev(vlst, 0);
3357  }
3358 
3359  if(xorriso->do_global_uid) {
3360    sprintf(line,"-uid %lu\n", (unsigned long) xorriso->global_uid);
3361    Xorriso_status_result(xorriso,filter,fp,flag&2);
3362  }
3363 
3364  if(xorriso->do_global_gid) {
3365    sprintf(line,"-gid %lu\n", (unsigned long) xorriso->global_gid);
3366    Xorriso_status_result(xorriso,filter,fp,flag&2);
3367  }
3368 
3369  Xorriso_status_extf(xorriso, filter, fp, flag & 2);
3370  Xorriso_status_zisofs(xorriso, filter, fp, flag & 3);
3371 
3372  is_default= !xorriso->allow_graft_points;
3373  sprintf(line,"-pathspecs %s\n",
3374          (xorriso->allow_graft_points & 2) ? "as_mkisofs" :
3375            xorriso->allow_graft_points ? "on" : "off");
3376  if(!(is_default && no_defaults))
3377    Xorriso_status_result(xorriso,filter,fp,flag&2);
3378 
3379  is_default= (xorriso->do_follow_pattern && (!xorriso->do_follow_param)
3380               && xorriso->do_follow_mount && (!xorriso->do_follow_links)
3381               && xorriso->follow_link_limit==100
3382               && (!xorriso->do_follow_concat));
3383  mode[0]= 0;
3384  if(xorriso->do_follow_pattern &&
3385     !(xorriso->do_follow_links && xorriso->do_follow_mount))
3386    strcat(mode,":pattern");
3387  if(xorriso->do_follow_param && !(xorriso->do_follow_links))
3388    strcat(mode,":param");
3389  if(xorriso->do_follow_links)
3390    strcat(mode,":link");
3391  if(xorriso->do_follow_concat)
3392    strcat(mode,":concat");
3393  if(xorriso->do_follow_mount)
3394    strcat(mode,":mount");
3395  if(mode[0]==0)
3396    strcpy(mode, ":off");
3397  sprintf(mode+strlen(mode), ":limit=%d", xorriso->follow_link_limit);
3398  sprintf(line,"-follow %s\n", mode+1);
3399  if(!(is_default && no_defaults))
3400    Xorriso_status_result(xorriso,filter,fp,flag&2);
3401 
3402  is_default= (xorriso->do_overwrite==2);
3403  sprintf(line,"-overwrite %s\n",(xorriso->do_overwrite == 1 ? "on" :
3404                              (xorriso->do_overwrite == 2 ? "nondir" : "off")));
3405  if(!(is_default && no_defaults))
3406    Xorriso_status_result(xorriso,filter,fp,flag&2);
3407 
3408  is_default= !xorriso->do_reassure;
3409  sprintf(line,"-reassure %s\n",(xorriso->do_reassure == 1 ? "on" :
3410                              (xorriso->do_reassure == 2 ? "tree" : "off")));
3411  if(!(is_default && no_defaults))
3412    Xorriso_status_result(xorriso,filter,fp,flag&2);
3413 
3414  is_default= (xorriso->read_speed == -2);
3415  sprintf(line,"-read_speed %s\n", Xorriso__speedname(xorriso->read_speed));
3416  if(!(is_default && no_defaults))
3417    Xorriso_status_result(xorriso,filter,fp,flag&2);
3418 
3419  is_default= !(xorriso->auto_close || xorriso->do_close);
3420  sprintf(line,"-close %s\n",xorriso->auto_close ? "as_needed" :
3421                             xorriso->do_close ? "on" : "off");
3422  if(!(is_default && no_defaults))
3423    Xorriso_status_result(xorriso,filter,fp,flag&2);
3424 
3425  is_default= (xorriso->do_tao == 0);
3426  sprintf(line,"-write_type %s\n",
3427       xorriso->do_tao == 0 ? "auto" : xorriso->do_tao > 0 ? "tao" : "sao/dao");
3428  if(!(is_default && no_defaults))
3429    Xorriso_status_result(xorriso,filter,fp,flag&2);
3430 
3431  is_default= !xorriso->do_dummy;
3432  sprintf(line,"-dummy %s\n",(xorriso->do_dummy ? "on" : "off"));
3433  if(!(is_default && no_defaults))
3434    Xorriso_status_result(xorriso,filter,fp,flag&2);
3435 
3436  is_default= (xorriso->write_speed==0);
3437  sprintf(line,"-speed %s\n", Xorriso__speedname(xorriso->write_speed));
3438  if(!(is_default && no_defaults))
3439    Xorriso_status_result(xorriso,filter,fp,flag&2);
3440 
3441  is_default= (xorriso->do_stream_recording==0);
3442  strcpy(mode, "off");
3443  if(xorriso->do_stream_recording == 1)
3444    strcpy(mode, "full");
3445  if(xorriso->do_stream_recording == 2)
3446    strcpy(mode, "data");
3447  else if(xorriso->do_stream_recording == 32)
3448    strcpy(mode, "on");
3449  else if(xorriso->do_stream_recording >= 16)
3450    sprintf(mode, "%ds", xorriso->do_stream_recording);
3451  sprintf(line,"-stream_recording %s\n", mode);
3452  if(!(is_default && no_defaults))
3453    Xorriso_status_result(xorriso,filter,fp,flag&2);
3454 
3455  is_default= (xorriso->modesty_on_drive == 0 &&
3456               xorriso->min_buffer_usec == 5000 &&
3457               xorriso->max_buffer_usec == 25000 &&
3458               xorriso->buffer_timeout_sec == 120 &&
3459               xorriso->min_buffer_percent == 90 &&
3460               xorriso->max_buffer_percent == 95);
3461  if(xorriso->modesty_on_drive == 0)
3462    strcpy(mode, "off");
3463  else if(xorriso->modesty_on_drive == 1)
3464    strcpy(mode, "on");
3465  else
3466    sprintf(mode, "%d", xorriso->modesty_on_drive);
3467  sprintf(mode + strlen(mode), ":min_percent=%d", xorriso->min_buffer_percent);
3468  sprintf(mode + strlen(mode), ":max_percent=%d", xorriso->max_buffer_percent);
3469  if(xorriso->buffer_timeout_sec >= 0)
3470    sprintf(mode + strlen(mode), ":timeout_sec=%d", xorriso->buffer_timeout_sec);
3471  if(xorriso->min_buffer_usec >= 0)
3472    sprintf(mode + strlen(mode), ":min_usec=%d", xorriso->min_buffer_usec);
3473  if(xorriso->max_buffer_usec >= 0)
3474    sprintf(mode + strlen(mode), ":max_usec=%d", xorriso->max_buffer_usec);
3475  sprintf(line,"-modesty_on_drive %s\n", mode);
3476  if(!(is_default && no_defaults))
3477    Xorriso_status_result(xorriso,filter,fp,flag&2);
3478 
3479  is_default= (xorriso->dvd_obs == 0);
3480  strcpy(mode, "default");
3481  if(xorriso->dvd_obs == 32768 || xorriso->dvd_obs == 65536)
3482    sprintf(mode, "%dk", xorriso->dvd_obs / 1024);
3483  sprintf(line,"-dvd_obs %s\n", mode);
3484  if(!(is_default && no_defaults))
3485    Xorriso_status_result(xorriso,filter,fp,flag&2);
3486 
3487  is_default= (xorriso->use_immed_bit == 0);
3488  strcpy(line, "-use_immed_bit ");
3489  if(xorriso->use_immed_bit == 0) {
3490    strcat(line, "default");
3491    if(xorriso->use_immed_bit_default > 0)
3492      strcat(line, "/on");
3493    else if(xorriso->use_immed_bit_default < 0)
3494      strcat(line, "/off");
3495    strcat(line, "\n");
3496  } else if(xorriso->use_immed_bit > 0) {
3497    strcat(line, "on\n");
3498  } else if(xorriso->use_immed_bit < 0) {
3499    strcat(line, "off\n");
3500  }
3501  if(!(is_default && no_defaults))
3502    Xorriso_status_result(xorriso,filter,fp,flag&2);
3503 
3504  is_default= (xorriso->stdio_sync == 0);
3505  strcpy(line, "-stdio_sync ");
3506  if(xorriso->stdio_sync == -1)
3507    strcat(line, "off");
3508  else if(xorriso->stdio_sync == 0)
3509    strcat(line, "on");
3510  else if(xorriso->stdio_sync == 1)
3511    strcat(line, "end");
3512  else if(xorriso->stdio_sync % 512) {
3513    Sfile_off_t_text(line+strlen(line), (off_t) (xorriso->stdio_sync * 2048),
3514                     0);
3515  } else {
3516    Sfile_off_t_text(line+strlen(line), (off_t) (xorriso->stdio_sync / 512), 0);
3517    strcat(line, "m");
3518  }
3519  strcat(line, "\n");
3520  if(!(is_default && no_defaults))
3521    Xorriso_status_result(xorriso,filter,fp,flag&2);
3522 
3523  is_default= (xorriso->fs==4*512);
3524  if((xorriso->fs/512)*512==xorriso->fs)
3525    sprintf(line,"-fs %dm\n", xorriso->fs/512);
3526  else
3527    sprintf(line,"-fs %dk\n", xorriso->fs*2);
3528  if(!(is_default && no_defaults))
3529    Xorriso_status_result(xorriso,filter,fp,flag&2);
3530 
3531  is_default= (xorriso->padding==300*1024);
3532  sprintf(line,"-padding %dk\n", xorriso->padding/1024);
3533  if(!(is_default && no_defaults))
3534    Xorriso_status_result(xorriso,filter,fp,flag&2);
3535  is_default= (xorriso->do_padding_by_libisofs == 0);
3536  sprintf(line,"-padding %s\n",
3537          xorriso->do_padding_by_libisofs ? "included" : "appended");
3538  if(!(is_default && no_defaults))
3539    Xorriso_status_result(xorriso,filter,fp,flag&2);
3540 
3541  is_default= (strcmp(xorriso->report_about_text,"UPDATE")==0);
3542  sprintf(line,"-report_about %s\n",xorriso->report_about_text);
3543  if(!(is_default && no_defaults))
3544    Xorriso_status_result(xorriso,filter,fp,flag&2);
3545 
3546  is_default= (xorriso->scsi_log == 0);
3547  sprintf(line,"-scsi_log %s\n", xorriso->scsi_log ? "on" : "off");
3548  if(!(is_default && no_defaults))
3549    Xorriso_status_result(xorriso,filter,fp,flag&2);
3550 
3551  is_default= (xorriso->session_logfile[0]==0);
3552  sprintf(line,"-session_log %s\n",
3553          Text_shellsafe(xorriso->session_logfile,sfe,0));
3554  if(!(is_default && no_defaults))
3555    Xorriso_status_result(xorriso,filter,fp,flag&2);
3556 
3557  is_default= (xorriso->pacifier_style==0);
3558  sprintf(line,"-pacifier '%s'\n",
3559          xorriso->pacifier_style==1 ? "mkisofs" :
3560          xorriso->pacifier_style==2 ? "cdrecord" : "xorriso");
3561  if(!(is_default && no_defaults))
3562    Xorriso_status_result(xorriso,filter,fp,flag&2);
3563  is_default= (xorriso->pacifier_interval == 1.0);
3564  sprintf(line,"-pacifier interval=%f\n", xorriso->pacifier_interval);
3565  if(!(is_default && no_defaults))
3566    Xorriso_status_result(xorriso,filter,fp,flag&2);
3567 
3568  is_default= (strcmp(xorriso->return_with_text,"SORRY")==0 &&
3569               xorriso->return_with_value==32);
3570  sprintf(line,"-return_with %s %d\n",
3571          xorriso->return_with_text, xorriso->return_with_value);
3572  if(!(is_default && no_defaults))
3573    Xorriso_status_result(xorriso,filter,fp,flag&2);
3574 
3575  is_default= 0;
3576  sprintf(line,"-abort_on %s\n",xorriso->abort_on_text);
3577  if(!(is_default && no_defaults))
3578    Xorriso_status_result(xorriso,filter,fp,flag&2);
3579 
3580  if(xorriso->status_history_max!=Xorriso_status_history_maX || !no_defaults) {
3581    sprintf(line,"-status_history_max %d\n",xorriso->status_history_max);
3582    Xorriso_status_result(xorriso,filter,fp,flag&2);
3583  }
3584 
3585 #ifdef Xorriso_with_line_editoR
3586 
3587  if((flag & 8) && xorriso->status_history_max > 0 && !xorriso->use_stdin)
3588    Xorriso_status_history(xorriso, filter, fp, flag & 2);
3589 
3590 #endif /* Xorriso_with_line_editoR */
3591 
3592  is_default= (xorriso->toc_emulation_flag == 0);
3593  sprintf(line,"-rom_toc_scan %s:%s:%s\n",
3594          xorriso->toc_emulation_flag & 4 ? "force" :
3595                                 xorriso->toc_emulation_flag & 1 ? "on" : "off",
3596          xorriso->toc_emulation_flag & 2 ? "emul_off" : "emul_on",
3597          xorriso->toc_emulation_flag & 8 ? "emul_wide" : "emul_narrow");
3598  if(!(is_default && no_defaults))
3599    Xorriso_status_result(xorriso, filter, fp, flag & 2);
3600 
3601  is_default= (xorriso->displacement == 0);
3602  sprintf(line, "-displacement %s%lu\n",
3603                xorriso->displacement_sign < 0 ? "-" : "",
3604                (unsigned long) xorriso->displacement);
3605  if(!(is_default && no_defaults))
3606    Xorriso_status_result(xorriso, filter, fp, flag & 2);
3607 
3608  adr_mode= xorriso->image_start_mode & 0xffff;
3609  if(adr_mode>=0 && adr_mode<=max_load_mode) {
3610    is_default= (adr_mode==0);
3611    sprintf(line,"-load %s ", load_names[adr_mode]);
3612    if(adr_mode==0)
3613      sprintf(line+strlen(line),"''\n");
3614    else if(adr_mode>=1 && adr_mode<=3)
3615      sprintf(line+strlen(line),"%s\n", xorriso->image_start_value);
3616    else
3617      sprintf(line+strlen(line),"%s\n",
3618               Text_shellsafe(xorriso->image_start_value, sfe, 0));
3619    if(!(is_default && no_defaults))
3620      Xorriso_status_result(xorriso,filter,fp,flag&2);
3621  }
3622 
3623  is_default= (xorriso->read_fs == 0);
3624  sprintf(line, "-read_fs %s\n",
3625          xorriso->read_fs == 0 ? "any" :
3626          xorriso->read_fs == 1 ? "norock" :
3627          xorriso->read_fs == 2 ? "nojoliet" : "ecma119");
3628  if(!(is_default && no_defaults))
3629    Xorriso_status_result(xorriso, filter, fp, flag & 2);
3630 
3631  is_default= (xorriso->do_calm_drive & 1);
3632  sprintf(line,"-calm_drive %s\n", xorriso->do_calm_drive & 1 ? "on" : "off");
3633  if(!(is_default && no_defaults))
3634    Xorriso_status_result(xorriso,filter,fp,flag&2);
3635 
3636  is_default= (xorriso->grow_blindly_msc2<0);
3637  sprintf(sfe, "%d", xorriso->grow_blindly_msc2);
3638  sprintf(line,"-grow_blindly %s\n",
3639          xorriso->grow_blindly_msc2 < 0 ? "off" : sfe);
3640  if(!(is_default && no_defaults))
3641    Xorriso_status_result(xorriso,filter,fp,flag&2);
3642 
3643  Xorriso_get_local_charset(xorriso, &local_charset, 0);
3644  nl_charset= nl_langinfo(CODESET);
3645  is_default= (strcmp(local_charset, nl_charset) == 0);
3646  sprintf(line, "-local_charset %s\n", Text_shellsafe(local_charset, sfe, 0));
3647  if(!(is_default && no_defaults))
3648    Xorriso_status_result(xorriso, filter, fp, flag & 2);
3649 
3650  is_default= (xorriso->out_charset == NULL && xorriso->in_charset == NULL);
3651  in_pt= "";
3652  if(xorriso->in_charset != NULL)
3653    in_pt= xorriso->in_charset;
3654  out_pt= "";
3655  if(xorriso->out_charset != NULL)
3656    out_pt= xorriso->out_charset;
3657  do_single= 0;
3658  ret= Xorriso_status_filter(xorriso, filter, "-in_charset", 0);
3659  if(ret <= 0)
3660    ret= Xorriso_status_filter(xorriso, filter, "-out_charset", 0);
3661  if(ret > 0)
3662    do_single= 1;
3663  if(strcmp(in_pt, out_pt) == 0 && !do_single) {
3664    sprintf(line, "-charset %s\n", Text_shellsafe(in_pt, sfe, 0));
3665    if(!(is_default && no_defaults))
3666      Xorriso_status_result(xorriso, filter, fp, flag & 2);
3667  } else {
3668    sprintf(line, "-in_charset %s\n", Text_shellsafe(in_pt, sfe, 0));
3669    if(!(is_default && no_defaults))
3670      Xorriso_status_result(xorriso, filter, fp, flag & 2);
3671    sprintf(line, "-out_charset %s\n", Text_shellsafe(out_pt, sfe, 0));
3672    if(!(is_default && no_defaults))
3673      Xorriso_status_result(xorriso, filter, fp, flag & 2);
3674  }
3675  is_default= ((xorriso->do_aaip & (256 | 512)) == 0);
3676  sprintf(line,"-auto_charset %s\n", (xorriso->do_aaip & 256 ? "on" : "off"));
3677  if(!(is_default && no_defaults))
3678    Xorriso_status_result(xorriso,filter,fp,flag&2);
3679 
3680  is_default= ((xorriso->ino_behavior & 31) == 7);
3681  switch (xorriso->ino_behavior & 15) {
3682  case 0: form= "on";
3683  break; case 8: form= "without_update";
3684  break; default: form= "off";
3685  }
3686  sprintf(line,"-hardlinks %s:%s:%s\n", form,
3687          xorriso->ino_behavior & 32 ?
3688          "no_lsl_count" : "lsl_count",
3689          xorriso->ino_behavior & 16 ?
3690          "cheap_sorted_extract" : "normal_extract");
3691  if(!(is_default && no_defaults))
3692    Xorriso_status_result(xorriso,filter,fp,flag&2);
3693 
3694  is_default= ((xorriso->do_aaip & (1 | 4)) == 0);
3695  sprintf(line,"-acl %s\n", (xorriso->do_aaip & 1 ? "on" : "off"));
3696  if(!(is_default && no_defaults))
3697    Xorriso_status_result(xorriso,filter,fp,flag&2);
3698  is_default= ((xorriso->do_aaip & (2 | 8)) == 0);
3699  sprintf(line,"-xattr %s\n", (xorriso->do_aaip & 4 ?
3700                                 xorriso->do_aaip & 1024 ? "any" : "user"
3701                               : "off"));
3702  if(!(is_default && no_defaults))
3703    Xorriso_status_result(xorriso,filter,fp,flag&2);
3704  is_default= ((xorriso->do_aaip & (16 | 32 | 64)) == 0);
3705  sprintf(line,"-disk_dev_ino %s\n",
3706          (xorriso->do_aaip & 16 ? (xorriso->do_aaip & 128 ? "ino_only" : "on" )
3707                                 : "off"));
3708  if(!(is_default && no_defaults))
3709    Xorriso_status_result(xorriso,filter,fp,flag&2);
3710 
3711  is_default= ((xorriso->do_md5 & 31) == 0);
3712  sprintf(line, "-md5 ");
3713  if(xorriso->do_md5 & 1) {
3714    if((xorriso->do_md5 & 8) == 8) {
3715      strcat(line, "all");
3716    } else {
3717      strcat(line, "on");
3718      if(xorriso->do_md5 & 8)
3719        strcat(line, ":stability_check_on");
3720    }
3721    if(xorriso->do_md5 & 32)
3722      strcat(line, ":load_check_off");
3723    strcat(line, "\n");
3724  } else
3725    strcat(line, "off\n");
3726  if(!(is_default && no_defaults))
3727    Xorriso_status_result(xorriso,filter,fp,flag&2);
3728 
3729  is_default= (xorriso->ecma119_map == 1);
3730  sprintf(line, "-ecma119_map ");
3731  if(xorriso->ecma119_map == 0)
3732    strcat(line, "unmapped\n");
3733  else if(xorriso->ecma119_map == 2)
3734    strcat(line, "uppercase\n");
3735  else if(xorriso->ecma119_map == 3)
3736    strcat(line, "lowercase\n");
3737  else
3738    strcat(line, "stripped\n");
3739  if(!(is_default && no_defaults))
3740    Xorriso_status_result(xorriso,filter,fp,flag&2);
3741 
3742  is_default= (xorriso->scdbackup_tag_name[0] == 0 &&
3743               xorriso->scdbackup_tag_listname[0] == 0);
3744  sprintf(line, "-scdbackup_tag ");
3745  Text_shellsafe(xorriso->scdbackup_tag_listname, line, 1);
3746  strcat(line, " ");
3747  Text_shellsafe(xorriso->scdbackup_tag_name, line, 1);
3748  strcat(line, "\n");
3749  if(!(is_default && no_defaults))
3750    Xorriso_status_result(xorriso,filter,fp,flag&2);
3751 
3752  is_default= (Xorriso_get_relax_text(xorriso, sfe, 0) == 2);
3753  sprintf(line,"-compliance %s\n", sfe);
3754  if(!(is_default && no_defaults))
3755    Xorriso_status_result(xorriso,filter,fp,flag&2);
3756 
3757  is_default= (xorriso->rr_reloc_dir[0] == 0);
3758  sprintf(line, "-rr_reloc_dir ");
3759  Text_shellsafe(xorriso->rr_reloc_dir, line, 1);
3760  strcat(line, "\n");
3761  if(!(is_default && no_defaults))
3762    Xorriso_status_result(xorriso,filter,fp,flag&2);
3763 
3764  is_default= (xorriso->assert_volid[0] == 0);
3765  sprintf(line, "-assert_volid ");
3766  Text_shellsafe(xorriso->assert_volid, line, 1);
3767  strcat(line, " ");
3768  Text_shellsafe(xorriso->assert_volid_sev, line, 1);
3769  strcat(line, "\n");
3770  if(!(is_default && no_defaults))
3771    Xorriso_status_result(xorriso,filter,fp,flag&2);
3772 
3773  is_default= 1;
3774  if(xorriso->drive_blacklist != NULL || xorriso->drive_whitelist != NULL ||
3775     xorriso->drive_greylist == NULL)
3776    is_default= 0;
3777  if(xorriso->drive_greylist != NULL) {
3778    if(strcmp(Xorriso_get_pattern(xorriso, xorriso->drive_greylist, 0, 0),
3779               "/dev") != 0)
3780      is_default= 0;
3781    if(Xorriso_get_pattern(xorriso, xorriso->drive_greylist, 1, 0) != NULL)
3782      is_default= 0;
3783  }
3784  if(!(is_default && no_defaults)) {
3785    for(s= xorriso->drive_blacklist; s != NULL; s= Xorriso_lst_get_next(s, 0)) {
3786      sprintf(line, "-drive_class 'banned'   %s\n",
3787              Text_shellsafe(Xorriso_lst_get_text(s, 0), sfe, 0));
3788      Xorriso_status_result(xorriso,filter,fp,flag&2);
3789    }
3790    for(s= xorriso->drive_greylist; s != NULL; s= Xorriso_lst_get_next(s, 0)) {
3791      sprintf(line, "-drive_class 'caution'  %s\n",
3792              Text_shellsafe(Xorriso_lst_get_text(s, 0), sfe, 0));
3793      Xorriso_status_result(xorriso,filter,fp,flag&2);
3794    }
3795    for(s= xorriso->drive_whitelist; s != NULL; s= Xorriso_lst_get_next(s, 0)) {
3796      sprintf(line, "-drive_class 'harmless' %s\n",
3797              Text_shellsafe(Xorriso_lst_get_text(s, 0), sfe, 0));
3798      Xorriso_status_result(xorriso,filter,fp,flag&2);
3799    }
3800  }
3801 
3802  is_default= (xorriso->linux_scsi_dev_family == 0);
3803  sprintf(line, "-scsi_dev_family %s\n",
3804                scsi_family[xorriso->linux_scsi_dev_family & 7]);
3805  if(!(is_default && no_defaults))
3806    Xorriso_status_result(xorriso,filter,fp,flag&2);
3807 
3808  do_single= 0;
3809  dev_filter= filter;
3810  if(dev_filter != NULL) {
3811    show_dev= Xorriso_status_filter(xorriso, filter, "-dev", 0);
3812    if(show_dev > 0)
3813      dev_filter= NULL;
3814  }
3815  if(dev_filter != NULL) {
3816    show_indev= Xorriso_status_filter(xorriso, filter, "-indev", 0);
3817    show_outdev= Xorriso_status_filter(xorriso, filter, "-outdev", 0);
3818    if(show_outdev > 0 || show_indev > 0)
3819      do_single= 1;
3820  }
3821  if(xorriso->drives_exclusive != xorriso->indev_is_exclusive &&
3822     xorriso->indev[0])
3823    do_single= 1;
3824  else if(xorriso->drives_exclusive != xorriso->outdev_is_exclusive &&
3825          xorriso->outdev[0])
3826    do_single= 1;
3827  if(strcmp(xorriso->indev, xorriso->outdev) == 0 && !do_single) {
3828    sprintf(line,"-dev %s\n", Text_shellsafe(xorriso->indev,sfe,0));
3829    Xorriso_status_result(xorriso, dev_filter, fp, flag & 2);
3830  } else {
3831    if(xorriso->drives_exclusive != xorriso->indev_is_exclusive &&
3832       xorriso->indev[0] && show_indev) {
3833      sprintf(line,"-osirrox o_excl_%s\n",
3834              xorriso->indev_is_exclusive ? "on" : "off");
3835      Xorriso_status_result(xorriso, NULL, fp, flag & 2);
3836    }
3837    sprintf(line,"-indev %s\n", Text_shellsafe(xorriso->indev,sfe,0));
3838    Xorriso_status_result(xorriso, dev_filter, fp, flag & 2);
3839    if(xorriso->drives_exclusive != xorriso->indev_is_exclusive &&
3840       xorriso->indev[0] && show_indev) {
3841      sprintf(line,"-osirrox o_excl_%s\n",
3842              xorriso->drives_exclusive ? "on" : "off");
3843      Xorriso_status_result(xorriso, NULL, fp, flag & 2);
3844    }
3845 
3846    if(xorriso->drives_exclusive != xorriso->outdev_is_exclusive &&
3847       xorriso->outdev[0] && show_outdev) {
3848      sprintf(line,"-osirrox o_excl_%s\n",
3849              xorriso->outdev_is_exclusive ? "on" : "off");
3850      Xorriso_status_result(xorriso, NULL, fp, flag & 2);
3851    }
3852    sprintf(line,"-outdev %s\n", Text_shellsafe(xorriso->outdev,sfe,0));
3853    Xorriso_status_result(xorriso, dev_filter, fp, flag & 2);
3854    if(xorriso->drives_exclusive != xorriso->outdev_is_exclusive &&
3855       xorriso->outdev[0] && show_outdev) {
3856      sprintf(line,"-osirrox o_excl_%s\n",
3857              xorriso->drives_exclusive ? "on" : "off");
3858      Xorriso_status_result(xorriso, NULL, fp, flag & 2);
3859    }
3860  }
3861 
3862  ret= 1;
3863 ex:;
3864  Xorriso_free_meM(sfe);
3865  Xorriso_free_meM(xorriso_id);
3866  return(ret);
3867 }
3868 
3869 
Xorriso_pacifier_reset(struct XorrisO * xorriso,int flag)3870 int Xorriso_pacifier_reset(struct XorrisO *xorriso, int flag)
3871 {
3872  xorriso->start_time= Sfile_microtime(0);
3873  xorriso->last_update_time= xorriso->start_time;
3874  xorriso->pacifier_count= 0;
3875  xorriso->pacifier_prev_count= 0;
3876  xorriso->pacifier_total= 0;
3877  xorriso->pacifier_byte_count= 0;
3878  return(1);
3879 }
3880 
3881 
3882 /* This call is to be issued by long running workers in short intervals.
3883    It will check whether enough time has elapsed since the last pacifier
3884    message and eventually issue an update message.
3885    @param what_done  A sparse description of the action, preferrably in past
3886                      tense. E.g. "done" , "files added".
3887    @param count The number of objects processed so far.
3888                 Is ignored if <=0.
3889    @param todo  The number of objects to be done in total.
3890                 Is ignored if <=0.
3891    @param current_object A string telling the object currently processed.
3892                          Ignored if "".
3893    @param flag  bit0= report unconditionally, no time check
3894                 bit1= report count <=0 (no thank you for being patient then)
3895                 bit2= report xorriso->pacifier_byte_count
3896                 bit3= report speed
3897                 bit4= with bit3: count is in blocks, else in bytes
3898                 bit5= with bit3: report total speed
3899                 bit6= report with carriage return rather than line feed
3900                 bit7= with bit5: speed unit for outdev rather than indev
3901 */
Xorriso_pacifier_callback(struct XorrisO * xorriso,char * what_done,off_t count,off_t todo,char * current_object,int flag)3902 int Xorriso_pacifier_callback(struct XorrisO *xorriso, char *what_done,
3903                               off_t count, off_t todo, char *current_object,
3904                               int flag)
3905 {
3906  double current_time, since, interval_time, speed, speed_factor;
3907  char count_text[80], byte_text[80], profile_name[80], *speed_unit;
3908  int ret, profile_number, short_sec;
3909  off_t amount;
3910 
3911  current_time= Sfile_microtime(0);
3912  interval_time= current_time - xorriso->last_update_time;
3913  if(interval_time < xorriso->pacifier_interval
3914     && !(flag&1))
3915    return(1);
3916  xorriso->last_update_time= Sfile_microtime(0);
3917  since= current_time - xorriso->start_time;
3918  if((flag & 1) && since < 1.0 && xorriso->pacifier_interval >= 1.0)
3919    since= 1.0;
3920  if((flag & 1) && since < 0.1)
3921    since= 0.1;
3922  byte_text[0]= 0;
3923  if(flag&4) {
3924    strcat(byte_text, " (");
3925    Sfile_scale((double) xorriso->pacifier_byte_count,
3926                byte_text+strlen(byte_text), 7, 1e5, 0);
3927    strcat(byte_text, ")");
3928  }
3929  short_sec= 0;
3930  if(count<=0.0 && !(flag&2)) {
3931    if(since < 2)
3932      return(2);
3933    sprintf(xorriso->info_text,
3934            "Thank you for being patient for");
3935  } else if(todo<=0.0) {
3936    if(count<10000000)
3937      sprintf(count_text, "%7.f", (double) count);
3938    else
3939      Sfile_scale((double) count, count_text, 7, 1e5, 1);
3940    sprintf(xorriso->info_text, "%s %s%s in",
3941            count_text, what_done, byte_text);
3942    short_sec= (flag & 64);
3943  } else {
3944    sprintf(xorriso->info_text, "%.f of %.f %s%s in",
3945            (double) count, (double) todo, what_done, byte_text);
3946    short_sec= (flag & (8 | 64));
3947  }
3948  if(xorriso->pacifier_interval < 1.0) {
3949    sprintf(xorriso->info_text + strlen(xorriso->info_text),
3950            " %.1f", since);
3951  } else {
3952    sprintf(xorriso->info_text + strlen(xorriso->info_text),
3953            " %.f", since);
3954  }
3955  sprintf(xorriso->info_text + strlen(xorriso->info_text),
3956            " %s", short_sec ? "s" : "seconds");
3957 
3958  speed= -1.0;
3959  if(flag & 4)
3960    amount= xorriso->pacifier_byte_count;
3961  else
3962    amount= count;
3963  if((flag & 8)) {
3964    if(flag & 32) {
3965      if(since > 0)
3966        speed= amount / since;
3967    } else if(amount >= xorriso->pacifier_prev_count) {
3968      if(interval_time > 0)
3969        speed= (amount - xorriso->pacifier_prev_count) / interval_time;
3970    }
3971  }
3972  if(speed >= 0.0) {
3973    if(flag & 16)
3974      speed*= 2048.0;
3975    ret= Xorriso_get_profile(xorriso, &profile_number, profile_name,
3976                             (flag >> 6) & 2);
3977    speed_factor= 1385000;
3978    speed_unit= "D";
3979    if(ret == 2) {
3980      speed_factor= 150.0*1024;
3981      speed_unit= "C";
3982    } else if(ret == 3) {
3983      speed_factor= 4495625;
3984      speed_unit= "B";
3985    }
3986    sprintf(xorriso->info_text+strlen(xorriso->info_text), " %s %.1fx%s",
3987            (flag & 32 ? "=" : ","), speed / speed_factor, speed_unit);
3988  }
3989  xorriso->pacifier_prev_count= amount;
3990  if(current_object[0]!=0)
3991    sprintf(xorriso->info_text+strlen(xorriso->info_text),
3992            ", now at %s", current_object);
3993  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", (flag&64));
3994  return(1);
3995 }
3996 
3997 
Xorriso_reset_counters(struct XorrisO * xorriso,int flag)3998 int Xorriso_reset_counters(struct XorrisO *xorriso, int flag)
3999 {
4000  xorriso->error_count= 0;
4001  xorriso->insert_count= 0;
4002  xorriso->insert_bytes= 0;
4003  Xorriso_pacifier_reset(xorriso, 0);
4004  return(1);
4005 }
4006 
4007 
4008 /* @param flag bit0= to stderr rather than Xorriso_msgs_submit
4009 */
Xorriso_no_malloc_memory(struct XorrisO * xorriso,char ** to_free,int flag)4010 int Xorriso_no_malloc_memory(struct XorrisO *xorriso, char **to_free, int flag)
4011 {
4012  if(to_free!=NULL)
4013    if(*to_free!=NULL) {
4014      /* Eventual memory sacrifice to get on going */
4015      free(*to_free);
4016      *to_free= NULL;
4017    }
4018  sprintf(xorriso->info_text, "Out of virtual memory");
4019  if(flag & 1) {
4020    fprintf(stderr, "%s", xorriso->info_text);
4021    /* (No need to first check for problem status worse than ABORT) */
4022    Xorriso_set_problem_status(xorriso, "ABORT", 0);
4023  } else
4024    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "ABORT", 0);
4025  return(1);
4026 }
4027 
4028 
4029 /* @param flag bit0=path is in source filesystem , bit1= unconditionally */
Xorriso_much_too_long(struct XorrisO * xorriso,int len,int flag)4030 int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag)
4031 {
4032  if(len>=SfileadrL || (flag&2)) {
4033    sprintf(xorriso->info_text,
4034            "Path given for %s is much too long (%d)",
4035            ((flag&1) ? "local filesystem" : "ISO image"), len);
4036    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4037    return(0);
4038  }
4039  return(1);
4040 }
4041 
4042 
Xorriso_no_findjob(struct XorrisO * xorriso,char * cmd,int flag)4043 int Xorriso_no_findjob(struct XorrisO *xorriso, char *cmd, int flag)
4044 {
4045  sprintf(xorriso->info_text, "%s: cannot create find job object", cmd);
4046  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
4047  return(1);
4048 }
4049 
4050 
Xorriso_report_md5_outcome(struct XorrisO * xorriso,char * severity,int flag)4051 int Xorriso_report_md5_outcome(struct XorrisO *xorriso, char *severity,
4052                                int flag)
4053 {
4054  int has_md5;
4055 
4056  has_md5= Xorriso_image_has_md5(xorriso, 0);
4057  if(xorriso->find_check_md5_result & 1) {
4058    sprintf(xorriso->result_line,
4059            "Mismatch detected between file contents and MD5 checksums.\n");
4060  } else if(xorriso->find_check_md5_result & 8) {
4061    sprintf(xorriso->result_line,
4062            "File contents and their MD5 checksums match.\n");
4063  } else {
4064    sprintf(xorriso->result_line,
4065            "Not a single file with MD5 checksum was found.");
4066    if(has_md5 <= 0)
4067      strcat(xorriso->result_line,
4068             " (There is no MD5 checksum array loaded.)\n");
4069    else
4070      strcat(xorriso->result_line, "\n");
4071  }
4072  Xorriso_result(xorriso,0);
4073  if(xorriso->find_check_md5_result & 2) {
4074    sprintf(xorriso->result_line,
4075            "Encountered errors other than non-match during MD5 checking.\n");
4076    Xorriso_result(xorriso,0);
4077  }
4078  if((xorriso->find_check_md5_result & 4) && has_md5) {
4079    sprintf(xorriso->result_line,
4080    "There were data files which have no MD5 and thus could not be checked.\n");
4081    Xorriso_result(xorriso,0);
4082  }
4083  if((xorriso->find_check_md5_result & 3) && strcmp(severity, "ALL") != 0) {
4084    sprintf(xorriso->info_text, "Event triggered by MD5 comparison mismatch");
4085    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, severity, 0);
4086  }
4087  return(1);
4088 }
4089 
4090 
4091 /* @param flag bit0= do not issue prompt messages on info channel
4092                bit1= use line rather than asking at dialog input
4093 */
Xorriso_msg_op_parse(struct XorrisO * xorriso,char * line,char * prefix,char * separators,int max_words,int pflag,int input_lines,int flag)4094 int Xorriso_msg_op_parse(struct XorrisO *xorriso, char *line,
4095                          char *prefix, char *separators,
4096                          int max_words, int pflag, int input_lines,
4097                          int flag)
4098 {
4099  int ret, i, l, pargc= 0, bsl_mem;
4100  char *pline= NULL, **pargv= NULL, *parse_line, *text= NULL, *text_pt;
4101 
4102  Xorriso_alloc_meM(pline, char, SfileadrL);
4103 
4104  if(!(flag & 1)) {
4105    if(input_lines > 1)
4106      sprintf(xorriso->info_text, "-msg_op parse: Enter %d lines of text\n",
4107                                  input_lines);
4108    else
4109      sprintf(xorriso->info_text, "-msg_op parse: Enter text line\n");
4110    Xorriso_info(xorriso, 0);
4111  }
4112 
4113  if(flag & 2) {
4114    parse_line= line;
4115  } else {
4116    pline[0]= 0;
4117    for(i= 0; i < input_lines; i++) {
4118      l= strlen(pline);
4119      ret= Xorriso_dialog_input(xorriso, pline + l, SfileadrL - l - 1, 8 | 1);
4120      if(ret <= 0)
4121        goto ex;
4122      if(i < input_lines - 1)
4123        strcat(pline, "\n");
4124    }
4125    parse_line= pline;
4126  }
4127  ret= Xorriso_parse_line(xorriso, parse_line, prefix, separators, max_words,
4128                          &pargc, &pargv, pflag);
4129 
4130  /* Temporarily disable backslash encoding of result channel */
4131  bsl_mem= xorriso->bsl_interpretation;
4132  xorriso->bsl_interpretation&= ~32;
4133 
4134  xorriso->msg_sieve_disabled= 1;
4135  sprintf(xorriso->result_line, "%d\n", ret);
4136  Xorriso_result(xorriso, 1);
4137  if(ret == 1) {
4138    sprintf(xorriso->result_line, "%d\n", pargc);
4139    Xorriso_result(xorriso, 1);
4140    for(i= 0; i < pargc; i++) {
4141      text_pt= pargv[i];
4142      if (bsl_mem & 32) {
4143        ret= Sfile_bsl_encoder(&text, pargv[i], strlen(pargv[i]), 4);
4144        if(ret >  0)
4145          text_pt= text;
4146      }
4147      ret= Sfile_count_char(text_pt, '\n') + 1;
4148      sprintf(xorriso->result_line, "%d\n", ret);
4149      Xorriso_result(xorriso, 1);
4150      Sfile_str(xorriso->result_line, text_pt, 0);
4151      strcat(xorriso->result_line, "\n");
4152      Xorriso_result(xorriso, 1);
4153      Xorriso_free_meM(text);
4154      text= NULL;
4155    }
4156  } else {
4157    sprintf(xorriso->result_line, "0\n");
4158    Xorriso_result(xorriso, 1);
4159  }
4160  xorriso->bsl_interpretation= bsl_mem;
4161  ret= 1;
4162 ex:;
4163  Xorriso__dispose_words(&pargc, &pargv);
4164  Xorriso_free_meM(text);
4165  Xorriso_free_meM(pline);
4166  return ret;
4167 }
4168 
4169 
4170 /* @param flag bit0= do not issue prompt messages on info channel
4171 */
Xorriso_msg_op_parse_bulk(struct XorrisO * xorriso,char * prefix,char * separators,int max_words,int pflag,int bulk_lines,int flag)4172 int Xorriso_msg_op_parse_bulk(struct XorrisO *xorriso,
4173                               char *prefix, char *separators,
4174                               int max_words, int pflag, int bulk_lines,
4175                               int flag)
4176 {
4177  int ret, input_lines, i, j, l;
4178  char line[80];
4179  struct Xorriso_lsT *input_list= NULL, *input_end= NULL, *new_lst, *lst;
4180  char *pline= NULL;
4181 
4182  if(!(flag & 1)) {
4183    sprintf(xorriso->info_text,
4184     "Enter %d groups of lines. Each group begins by a line which tells the\n",
4185            bulk_lines);
4186    Xorriso_info(xorriso, 0);
4187    sprintf(xorriso->info_text,
4188     "number of following lines in the group. Then come the announced lines\n");
4189    Xorriso_info(xorriso, 0);
4190    sprintf(xorriso->info_text,
4191     "Do this blindly. No further prompt will appear. Best be a computer.\n");
4192    Xorriso_info(xorriso, 0);
4193  }
4194 
4195  Xorriso_alloc_meM(pline, char, SfileadrL);
4196 
4197  for(i= 0; i < bulk_lines; i++) {
4198    ret= Xorriso_dialog_input(xorriso, line, sizeof(line), 8 | 1);
4199    if(ret <= 0)
4200      goto ex;
4201    input_lines= -1;
4202    sscanf(line, "%d", &input_lines);
4203    pline[0]= 0;
4204    for(j= 0; j < input_lines; j++) {
4205      l= strlen(pline);
4206      ret= Xorriso_dialog_input(xorriso, pline + l, SfileadrL - l - 1, 8 | 1);
4207      if(ret <= 0)
4208        goto ex;
4209      if(j < input_lines - 1)
4210        strcat(pline, "\n");
4211    }
4212    ret= Xorriso_lst_new(&new_lst, pline, input_end, 0);
4213    if(ret <= 0)
4214      goto ex;
4215    if(input_list == NULL)
4216      input_list= new_lst;
4217    input_end= new_lst;
4218  }
4219 
4220  for(lst= input_list; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) {
4221    ret= Xorriso_msg_op_parse(xorriso, Xorriso_lst_get_text(lst, 0),
4222                              prefix, separators, max_words, pflag,
4223                              input_lines, 1 | 2);
4224    if(ret <= 0)
4225      goto ex;
4226  }
4227 
4228  ret= 1;
4229 ex:;
4230  Xorriso_lst_destroy_all(&input_list, 0);
4231  Xorriso_free_meM(pline);
4232  return(1);
4233 }
4234 
4235 
Xorriso_launch_frontend(struct XorrisO * xorriso,int argc,char ** argv,char * cmd_pipe_adr,char * reply_pipe_adr,int flag)4236 int Xorriso_launch_frontend(struct XorrisO *xorriso, int argc, char **argv,
4237                             char *cmd_pipe_adr, char *reply_pipe_adr, int flag)
4238 {
4239  int command_pipe[2], reply_pipe[2], ret, i, cpid, is_banned= 0;
4240  char **exec_argv= NULL, *sfe= NULL, *adrpt;
4241  struct stat stbuf;
4242 
4243  Xorriso_alloc_meM(sfe, char, 5 * SfileadrL);
4244  for(i= 0; i < 2; i++)
4245    command_pipe[i]= reply_pipe[i]= -1;
4246 
4247 #ifndef Xorriso_allow_launch_frontenD
4248  /* To be controlled by: configure --enable-external-filters */
4249 
4250  sprintf(xorriso->info_text, "-launch_frontend : Banned at compile time.");
4251  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4252  sprintf(xorriso->info_text,
4253 "This may be changed at compile time by ./configure option --enable-external-filters");
4254  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
4255  is_banned= 1;
4256 
4257 #endif /* ! Xorriso_allow_launch_frontenD */
4258 
4259 #ifndef Xorriso_allow_launch_frontend_suiD
4260 
4261  /* To be controlled by: configure --enable-external-filters-setuid */
4262 
4263  if(getuid() != geteuid()) {
4264    sprintf(xorriso->info_text,
4265           "-set_filter: UID and EUID differ. Will not run external programs.");
4266    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
4267    sprintf(xorriso->info_text,
4268 "This may be changed at compile time by ./configure option --enable-external-filters-setuid");
4269    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
4270    is_banned= 1;
4271  }
4272 
4273 #endif /* ! Xorriso_allow_launch_frontend_suiD */
4274 
4275  if(is_banned)
4276    {ret= 0; goto ex;}
4277 
4278  if(argc > 0) {
4279    if(strchr(argv[0], '/') == NULL) {
4280      sprintf(xorriso->info_text,
4281            "-launch_frontend : Command path does not contain a '/'-character");
4282      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4283      {ret= 0; goto ex;}
4284    }
4285 
4286    /* Add a NULL pointer for execv() */
4287    Xorriso_alloc_meM(exec_argv, char *, argc + 1);
4288    for(i= 0; i < argc; i++)
4289      exec_argv[i]= argv[i];
4290    exec_argv[argc]= NULL;
4291  } else if(cmd_pipe_adr[0] == 0 || reply_pipe_adr[0] == 0)
4292    {ret= 0; goto ex;}
4293 
4294  if(cmd_pipe_adr[0] && reply_pipe_adr[0]) {
4295    /* Create named pipes if needed */
4296    for(i= 0; i < 2; i++) {
4297      if(i == 0)
4298        adrpt= cmd_pipe_adr;
4299      else
4300        adrpt= reply_pipe_adr;
4301      ret= stat(adrpt, &stbuf);
4302      if(ret == -1) {
4303        ret= mknod(adrpt, S_IFIFO | S_IRWXU | S_IRWXG | S_IRWXO | S_IRWXO,
4304                   (dev_t) 0);
4305        if(ret == -1) {
4306           sprintf(xorriso->info_text,
4307                   "-launch_frontend: Cannot create named pipe %s",
4308                   Text_shellsafe(adrpt, sfe, 0));
4309           Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno,
4310                               "FAILURE", 0);
4311           ret= 0; goto ex;
4312        }
4313      }
4314    }
4315  } else {
4316    ret= pipe(command_pipe);
4317    if (ret == -1) {
4318 no_pipe_open:
4319      sprintf(xorriso->info_text,
4320              "-launch_frontend: Failed to create a nameless pipe object");
4321      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4322      ret= 0; goto ex;
4323    }
4324    ret= pipe(reply_pipe);
4325    if (ret == -1)
4326      goto no_pipe_open;
4327  }
4328 
4329  if(argc > 0) {
4330    cpid = fork();
4331    if (cpid == -1) {
4332      sprintf(xorriso->info_text,
4333              "-launch_frontend: Failed to create a child process");
4334      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4335      ret= 0; goto ex;
4336    }
4337  } else
4338    cpid= -1; /* Dummy child id */
4339 
4340  if (cpid != 0) {
4341    /* Parent becomes the xorriso slave */
4342 
4343    xorriso->use_stdin= 1;
4344    if(cmd_pipe_adr[0] && reply_pipe_adr[0]) {
4345       command_pipe[0]= open(cmd_pipe_adr, O_RDONLY | O_BINARY);
4346       if(command_pipe[0] == -1) {
4347          sprintf(xorriso->info_text,
4348                  "-launch_frontend: Failed to open named command pipe %s",
4349                  Text_shellsafe(cmd_pipe_adr, sfe, 0));
4350          Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno,
4351                              "FAILURE", 0);
4352          ret= 0; goto ex;
4353       }
4354       reply_pipe[1]= open(reply_pipe_adr, O_WRONLY | O_APPEND | O_BINARY);
4355       if(reply_pipe[1] == -1) {
4356          sprintf(xorriso->info_text,
4357                  "-launch_frontend: Failed to open named reply pipe %s",
4358                  Text_shellsafe(reply_pipe_adr, sfe, 0));
4359          Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno,
4360                              "FAILURE", 0);
4361          ret= 0; goto ex;
4362       }
4363    } else {
4364      /* Close unused pipe ends */
4365      close(command_pipe[1]);
4366      close(reply_pipe[0]);
4367    }
4368    close(0);
4369    close(1);
4370    close(2);
4371    ret= dup2(command_pipe[0], 0);
4372    if(ret == -1) {
4373 no_dup:;
4374      sprintf(xorriso->info_text,
4375   "-launch_frontend: Failed to connect pipe to xorriso standard i/o channels");
4376      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4377      ret= -1; goto ex;
4378    }
4379    ret= dup2(reply_pipe[1], 1);
4380    if(ret == -1)
4381      goto no_dup;
4382    ret= dup2(reply_pipe[1], 2);
4383    if(ret == -1)
4384      goto no_dup;
4385    ret= 1; goto ex;
4386  }
4387 
4388  /* Child becomes the frontend program */
4389 
4390  /* Close unused pipe ends */;
4391  if(cmd_pipe_adr[0] && reply_pipe_adr[0]) {
4392    command_pipe[1]= open(cmd_pipe_adr, O_WRONLY | O_APPEND | O_BINARY);
4393    if(command_pipe[1] == -1) {
4394      fprintf(stderr,
4395          "xorriso: -launch_frontend: Failed to open named command pipe '%s'\n",
4396          cmd_pipe_adr);
4397      perror("xorriso: -launch_frontend");
4398      exit(1);
4399    }
4400    reply_pipe[0]= open(reply_pipe_adr, O_RDONLY | O_BINARY);
4401    if(reply_pipe[0] == -1) {
4402      fprintf(stderr,
4403            "xorriso: -launch_frontend: Failed to open named reply pipe '%s'\n",
4404            reply_pipe_adr);
4405      exit(1);
4406    }
4407  } else {
4408    close(command_pipe[0]);
4409    close(reply_pipe[1]);
4410  }
4411  close(0);
4412  close(1);
4413  ret= dup2(command_pipe[1], 1);
4414  if(ret == -1) {
4415    perror("xorriso: -launch_frontend: Error on redirecting standard output for frontend");
4416    exit(1);
4417  }
4418  ret= dup2(reply_pipe[0], 0);
4419  if(ret == -1) {
4420    perror("xorriso: -launch_frontend: Error on redirecting standard input for frontend");
4421    exit(1);
4422  }
4423 
4424  execv(exec_argv[0], exec_argv);
4425  fprintf(stderr, "xorriso: -launch_frontend: Failure to start program '%s'\n",
4426          exec_argv[0]);
4427  perror("xorriso: -launch_frontend");
4428  exit(1);
4429 
4430 ex:;
4431  Xorriso_free_meM(exec_argv);
4432  Xorriso_free_meM(sfe);
4433  return(ret);
4434 }
4435 
4436 
4437 
Xorriso_open_named_pipe(struct XorrisO * xorriso,char fd_names[3][20],int mem_fds[],char * pipe_paths[],int pipe_fds[],int i,int flag)4438 int Xorriso_open_named_pipe(struct XorrisO *xorriso, char fd_names[3][20],
4439                             int mem_fds[], char *pipe_paths[], int pipe_fds[],
4440                             int i, int flag)
4441 {
4442  if(mem_fds[i] == -1)
4443    return(2);
4444  pipe_fds[i]= open(pipe_paths[i], (i == 0 ? O_RDONLY : O_WRONLY) | O_BINARY);
4445  if(pipe_fds[i] == -1) {
4446    sprintf(xorriso->info_text,
4447            "-named_pipe_loop: Failed to open %s pipe ", fd_names[i]);
4448    Text_shellsafe(pipe_paths[i], xorriso->info_text, 1);
4449    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
4450    return(0);
4451  }
4452  close(i);
4453  dup2(pipe_fds[i], i);
4454  return(1);
4455 }
4456 
4457 
4458 /* Usage example via bash:
4459      in=/u/test/xorriso_stdin
4460      out=/u/test/xorriso_stdout
4461      mknod "$in" p
4462      mknod "$out" p
4463      xorriso -abort_on NEVER \
4464              -named_pipe_loop cleanup:buffered "$in" "$out" - &
4465 
4466      # Send command and receive result
4467      xorriso_cmd() {
4468        echo "$@" >/u/test/xorriso_stdin
4469        cat </u/test/xorriso_stdout
4470      }
4471      # Transport safety of filenames by wrapping in quotes and escaping quotes
4472      xorriso_esc() {
4473        echo -n "'"
4474        echo -n "$1" | sed -e "s/'/'"'"'"'"'"'"'/g"
4475        echo -n "'"
4476      }
4477      disk_path=...arbitrary.characters...
4478      iso_path=...arbitrary.characters...
4479      xorriso_cmd map $(xorriso_esc "$disk_path") $(xorriso_esc "$iso_path")
4480 */
4481 /* @param flag bit0= unlink pipes when the loop ends
4482                bit1= read all lines from pipe until EOF before executing them
4483 */
Xorriso_named_pipe_loop(struct XorrisO * xorriso,char * pipe_paths[3],int flag)4484 int Xorriso_named_pipe_loop(struct XorrisO *xorriso,
4485                             char *pipe_paths[3], int flag)
4486 {
4487  char *line= NULL;
4488  int i, ret, mem_fds[3], pipe_fds[3], first_line, hret, pipes_are_valid= 0;
4489  int lst_ret, filling_buffer= 0;
4490  off_t mem_used= 0, mem_needed;
4491  struct stat stbuf;
4492  struct Xorriso_lsT *prev_lst= NULL;
4493  static char fd_names[3][20] = {
4494                        "standard input", "standard output", "standard error" };
4495  char mem_text[80], limit_text[80];
4496 
4497  for(i= 0; i < 3; i++ )
4498    mem_fds[i]= pipe_fds[i]= -1;
4499 
4500  if(xorriso->tolerate_stdin_eof) {
4501    sprintf(xorriso->info_text,
4502     "Already in -named_pipe_loop. Ignoring further -named_pipe_loop command.");
4503    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0);
4504    return(0); /* intentionally not goto ex */
4505  }
4506 
4507  Xorriso_alloc_meM(line, char, SfileadrL);
4508 
4509  /* Memorize stdin, stdout, and stderr. Close originals. */
4510  for(i= 0; i < 3; i++ ) {
4511    if(pipe_paths[i][0] == 0 || strcmp(pipe_paths[i], "-") == 0)
4512  continue;
4513    if(stat(pipe_paths[i], &stbuf) == -1) {
4514      sprintf(xorriso->info_text,
4515              "-named_pipe_loop: Cannot determine properties of file ");
4516      Text_shellsafe(pipe_paths[i], xorriso->info_text, 1);
4517      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4518      ret= 0; goto ex;
4519    }
4520    if(!S_ISFIFO(stbuf.st_mode)) {
4521      sprintf(xorriso->info_text,
4522              "-named_pipe_loop: File is not a named pipe: ");
4523      Text_shellsafe(pipe_paths[i], xorriso->info_text, 1);
4524      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4525      ret= 0; goto ex;
4526    }
4527    mem_fds[i]= dup(i);
4528    if(mem_fds[i] == -1) {
4529      sprintf(xorriso->info_text,
4530              "-named_pipe_loop: Cannot duplicate original %s", fd_names[i]);
4531      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4532      ret= 0; goto ex;
4533    }
4534  }
4535  pipes_are_valid= 1;
4536 
4537  while(1) {
4538    /* Open input pipe */
4539    ret= Xorriso_open_named_pipe(xorriso, fd_names, mem_fds, pipe_paths,
4540                                 pipe_fds, 0, 0);
4541    if(ret <= 0)
4542      goto ex;
4543 
4544    /* As long as the input connection exists */
4545    xorriso->tolerate_stdin_eof= 1;
4546    first_line= 1;
4547    if(flag & 2) {
4548      filling_buffer= 8 | 16; /* single line, no reading from buffered_dialog */
4549      prev_lst= NULL;
4550      mem_used= 0;
4551    }
4552    while(1) {
4553      /* Fetch input line */
4554      if((flag & 2) && xorriso->buffered_dialog == NULL && !filling_buffer) {
4555        ret= -2; /* EOF */
4556      } else {
4557        ret= Xorriso_dialog_input(xorriso, line, SfileadrL, 1 | filling_buffer);
4558      }
4559      if((flag & 2) && filling_buffer) {
4560        /* Fetch and buffer lines before opening output pipes */
4561 
4562        if(ret > 0) {
4563 
4564          /* Check for excessive memory consumption */;
4565          mem_needed= strlen(line) + 8 + sizeof(struct Xorriso_lsT);
4566          if(mem_used + mem_needed > xorriso->temp_mem_limit) {
4567            Sfile_scale((double) (mem_used + mem_needed), mem_text, 5, 1e4, 0);
4568            Sfile_scale((double) xorriso->temp_mem_limit,
4569                        limit_text, 5, 1e4, 0);
4570            sprintf(xorriso->info_text,
4571                    "-named_pipe_loop: List of buffered input lines exceeds -temp_mem_limit (%s > %s)",
4572                    mem_text, limit_text);
4573            Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
4574                                "FAILURE", 0);
4575            ret= -1; goto ex;
4576          }
4577          mem_used+= mem_needed;
4578 
4579          lst_ret= Xorriso_lst_new(&prev_lst, line, prev_lst, 0);
4580          if(lst_ret <= 0) {
4581            Xorriso_msgs_submit(xorriso, 0,
4582              "-named_pipe_loop: Cannot buffer all input lines", 0, "FATAL", 0);
4583            ret= -1; goto ex;
4584          } else {
4585            if(xorriso->buffered_dialog == NULL)
4586              xorriso->buffered_dialog= prev_lst;
4587    continue;
4588          }
4589        }
4590        filling_buffer= 0; /* start consuming buffer */
4591    continue;
4592      }
4593 
4594      /* Open output pipes late to allow the sender to open them after
4595         the first (and usually only) input line was transmitted:
4596           echo ... >stdin_pipe
4597           res=$(cat <stdout_pipe)
4598         This will work independently of the stdin_pipe buffer size.
4599      */
4600      if(first_line) {
4601        first_line= 0;
4602        for(i= 1; i < 3; i++) {
4603          hret= Xorriso_open_named_pipe(xorriso, fd_names, mem_fds, pipe_paths,
4604                                        pipe_fds, i, 0);
4605          if(hret <= 0 && ret > 0)
4606            {ret= hret; goto ex;}
4607        }
4608      }
4609 
4610      /* Now evaluate outcome of Xorriso_dialog_input() */
4611      if(ret == -2) /* EOF at stdin */
4612    break;
4613      if(ret <= 0)  /* Other error */
4614        goto ex;
4615 
4616      /* Regular end of command */
4617      if(strcmp(line, "end_named_pipe_loop") == 0)
4618        {ret= 1; goto ex;}
4619 
4620      /* Perform xorriso command */
4621      ret= Xorriso_execute_option(xorriso, line, (1 << 16));
4622      if(ret <= 0)
4623        goto ex;
4624      if(ret == 3) /* e.g. -end command */
4625        goto ex;
4626      Xorriso_mark(xorriso,0);
4627    }
4628 
4629    /* Restore stdin, stdout and stderr */
4630    for(i= 0; i < 3; i++) {
4631      if(mem_fds[i] != -1) {
4632        if(pipe_fds[i] != -1)
4633          close(pipe_fds[i]);
4634        pipe_fds[i]= -1;
4635        close(i);
4636        dup2(mem_fds[i], i);
4637      }
4638    }
4639  }
4640 
4641  ret= 1;
4642 ex:;
4643  xorriso->tolerate_stdin_eof= 0;
4644  if(flag & 2)
4645    Xorriso_lst_destroy_all(&(xorriso->buffered_dialog), 0);
4646  /* Close any open pipes. Restore stdin, stdout and stderr. */
4647  for(i= 0; i < 3; i++) {
4648    if(pipe_fds[i] != -1) {
4649      if((flag & 1) && pipes_are_valid) {
4650        if(stat(pipe_paths[i], &stbuf) != -1) {
4651          if(S_ISFIFO(stbuf.st_mode)) {
4652            sprintf(xorriso->info_text, "Removing named pipe ");
4653            Text_shellsafe(pipe_paths[i], xorriso->info_text, 1);
4654            Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
4655            unlink(pipe_paths[i]);
4656          }
4657        }
4658      }
4659      close(pipe_fds[i]);
4660    }
4661    if(mem_fds[i] != -1) {
4662      close(i);
4663      dup2(mem_fds[i], i);
4664      close(mem_fds[i]);
4665    }
4666  }
4667  Xorriso_free_meM(line);
4668  return(ret);
4669 }
4670 
4671 
4672 /* @param flag bit0= append to out_text rather than overwrite it
4673                bit1= length limit is 10 * SfileadrL rather than 5 *
4674 */
Xorriso_esc_filepath(struct XorrisO * xorriso,char * in_text,char * out_text,int flag)4675 char *Xorriso_esc_filepath(struct XorrisO *xorriso,
4676                            char *in_text, char *out_text, int flag)
4677 {
4678  int l, w=0, limit= 5 * SfileadrL;
4679  char *res;
4680 
4681  if(xorriso->sh_style_result == 0) {
4682    res= Text_shellsafe(in_text, out_text, flag);
4683    return(res);
4684  }
4685  if(flag&1)
4686    w= strlen(out_text);
4687  if(flag & 2)
4688    limit= 10 * SfileadrL;
4689  l= strlen(in_text);
4690  if(w + l >= limit) {
4691    strcpy(out_text, "'xorriso: TEXT MUCH TOO LONG ...   ");
4692    return(out_text);
4693  }
4694  strcpy(out_text + w, in_text);
4695  return(out_text);
4696 }
4697 
4698