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", ¬e_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