xorriso  1.5.4.pl02
About: GNU xorriso creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. It is suitable for incremental data backup and for production of bootable ISO 9660 images. GNU xorriso is a statical compilation of the libraries libburn, libisofs, libisoburn, and libjte.
  Fossies Dox: xorriso-1.5.4.pl02.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

sfile.c
Go to the documentation of this file.
1 
2 /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
3 
4  Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
5 
6  Provided under GPL version 2 or later.
7 
8  This file contains the implementation of functions around files and strings.
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 <pwd.h>
25 #include <grp.h>
26 
27 
28 #include "sfile.h"
29 
30 
31 /* @param flag bit0= do not clip off carriage return at line end
32 */
33 char *Sfile_fgets_n(char *line, int maxl, FILE *fp, int flag)
34 {
35  int l;
36  char *ret;
37 
38  ret= fgets(line,maxl,fp);
39  if(ret==NULL)
40  return(NULL);
41  l= strlen(line);
42  if(l > 0 && !(flag & 1)) if(line[l-1] == '\r') line[--l]= 0;
43  if(l > 0) if(line[l-1] == '\n') line[--l]= 0;
44  if(l > 0 && !(flag & 1)) if(line[l-1] == '\r') line[--l]= 0;
45  return(ret);
46 }
47 
48 
49 int Sfile_count_char(char *text, char to_count)
50 {
51  int count= 0;
52  char *cpt;
53 
54  for(cpt= text; *cpt != 0; cpt++)
55  if(*cpt == to_count)
56  count++;
57  return count;
58 }
59 
60 
61 int Sfile_count_components(char *path, int flag)
62 /*
63  bit0= do not ignore trailing slash
64  bit1= do not ignore empty components (other than the empty root name)
65 */
66 {
67  int l,count= 0;
68  char *cpt;
69 
70  l= strlen(path);
71  if(l==0)
72  return(0);
73  count= 1;
74  for(cpt= path+l-1;cpt>=path;cpt--) {
75  if(*cpt=='/') {
76  if(*(cpt+1)==0 && !(flag&1))
77  continue;
78  if(*(cpt+1)=='/' && !(flag&2))
79  continue;
80  count++;
81  }
82  }
83  return(count);
84 }
85 
86 
87 int Sfile_component_pointer(char *path, char **sourcept, int idx, int flag)
88 /*
89  bit0= do not ignore trailing slash
90  bit1= do not ignore empty components (other than the empty root name)
91  bit2= accept 0 as '/'
92 */
93 {
94  int count= 0;
95  char *spt;
96 
97  for(spt= path;*spt!=0 || (flag&4);spt++) {
98  if(count>=idx) {
99  *sourcept= spt;
100  return(1);
101  }
102  if(*spt=='/' || *spt==0) {
103  if(*(spt+1)=='/' && !(flag&2))
104  continue;
105  if(*(spt+1)==0 && !(flag&1))
106  continue;
107  count++;
108  }
109  }
110  if((flag&1) && count>=idx)
111  return(1);
112  return(0);
113 }
114 
115 
116 int Sfile_leafname(char *path, char leafname[SfileadrL], int flag)
117 {
118  int count, ret;
119  char *lpt;
120 
121  leafname[0]= 0;
122  count= Sfile_count_components(path, 0);
123  if(count==0)
124  return(0);
125  ret= Sfile_component_pointer(path, &lpt, count-1, 0);
126  if(ret<=0)
127  return(ret);
128  if(Sfile_str(leafname, lpt, 0)<=0)
129  return(0);
130  lpt= strchr(leafname, '/');
131  if(lpt!=NULL)
132  *lpt= 0;
133  return(1);
134 }
135 
136 
137 int Sfile_add_to_path(char path[SfileadrL], char *addon, int flag)
138 {
139  int l;
140 
141  l= strlen(path);
142  if(l+1>=SfileadrL)
143  return(0);
144  if(l==0) {
145  strcpy(path,"/");
146  l= 1;
147  } else if(path[l-1]!='/') {
148  path[l++]= '/';
149  path[l]= 0;
150  }
151  if(l+strlen(addon)>=SfileadrL)
152  return(0);
153  if(addon[0]=='/')
154  strcpy(path+l,addon+1);
155  else
156  strcpy(path+l,addon);
157  return(1);
158 }
159 
160 
161 int Sfile_prepend_path(char *prefix, char path[SfileadrL], int flag)
162 {
163  int l, i, slashes, prefix_len, path_len;
164 
165  l= strlen(prefix);
166  if(l == 0)
167  return(1);
168 
169  /* Do not copy slashes between both parts */
170  for(prefix_len= l; prefix_len > 0; prefix_len--)
171  if(prefix[prefix_len - 1] != '/')
172  break;
173  if(prefix_len == 0)
174  prefix_len= strlen(prefix) - 1;
175  path_len= strlen(path);
176  for(slashes= 0; slashes < path_len; slashes++)
177  if(path[slashes] != '/')
178  break;
179 
180  l= (strlen(path) - slashes) + prefix_len + 1;
181  if(l>=SfileadrL) {
182 
183 #ifdef Not_yeT
184  /* >>> ??? how to transport messages to xorriso ? */
185  sprintf(xorriso->info_text,
186  "Combination of wd and relative address too long (%d > %d)",
187  l,SfileadrL-1);
188  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
189 #endif
190 
191  return(-1);
192  }
193  l-= strlen(path);
194  if(l < 0) {
195  for(i= slashes; i <= path_len + 1; i++)
196  path[i+l]= path[i];
197  } else if(l > 0) {
198  for(i= path_len + 1; i >= slashes; i--)
199  path[i+l]= path[i];
200  }
201  if(prefix_len > 0)
202  memcpy(path, prefix, prefix_len);
203  path[l - 1 + slashes]= '/';
204  return(1);
205 }
206 
207 
208 int Sfile_get_dev_fd_no(char *filename, int flag)
209 {
210  int i, fd= -1;
211 
212  if(strncmp(filename, "/dev/fd/", 8) != 0)
213  return(-1);
214  for(i = 8; filename[i]; i++)
215  if(filename[i] < '0' || filename[i] > '9')
216  break;
217  if(i > 8 && filename[i] == 0)
218  sscanf(filename + 8, "%d", &fd);
219  if(fd < 0)
220  fd = -1;
221  return(fd);
222 }
223 
224 
225 int Sfile_type(char *filename, int flag)
226 /*
227  bit0= return -1 if file is missing
228  bit1= return a hardlink with siblings as type 5
229  bit2= evaluate eventual link target rather than the link object itself
230  bit3= return a socket or a char device as types 7 or 8 rather than 0
231  bit4= interpret /dev/fd/#fd# as open file descriptor fd
232 */
233 /*
234  return:
235  0=unknown
236  1=regular
237  2=directory
238  3=symbolic link
239  4=named pipe
240  5=multiple hardlink (with bit1)
241  6=block device
242  7=socket (with bit3)
243  8=character device (with bit3)
244  | 1024 if interpreted as /dev/fd/#fd#
245  | 2048 if interpreted as /dev/fd/#fd# and not fstatable
246 */
247 {
248  struct stat stbuf;
249  int fd= -1, was_dev_fd= 0, ret;
250 
251  if(flag & 16)
252  fd= Sfile_get_dev_fd_no(filename, 0);
253  if(fd != -1) {
254  was_dev_fd= 1;
255  if(fstat(fd, &stbuf) == -1)
256  return(1024 | 2048);
257  } else if(flag&4) {
258  if(stat(filename,&stbuf)==-1) {
259  if(flag&1) return(-1);
260  else return(0);
261  }
262  } else {
263  if(lstat(filename,&stbuf)==-1) {
264  if(flag&1) return(-1);
265  else return(0);
266  }
267  }
268  if(S_ISREG(stbuf.st_mode)) {
269  if(flag&2)
270  if(stbuf.st_nlink>1)
271  {ret= 5; goto ex;}
272  {ret= 1; goto ex;}
273  }
274  if(S_ISDIR(stbuf.st_mode))
275  {ret= 2; goto ex;}
276  if((stbuf.st_mode&S_IFMT)==S_IFLNK)
277  {ret= 3; goto ex;}
278  if(S_ISFIFO(stbuf.st_mode))
279  {ret= 4; goto ex;}
280  if(S_ISBLK(stbuf.st_mode))
281  {ret= 6; goto ex;}
282  if(flag&8)
283  if((stbuf.st_mode&S_IFMT)==S_IFSOCK)
284  {ret= 7; goto ex;}
285  if(flag&8)
286  if(S_ISCHR(stbuf.st_mode))
287  {ret= 8; goto ex;}
288  ret = 0;
289 ex:;
290  return(ret | (was_dev_fd << 10));
291 }
292 
293 
294 char *Sfile_datestr(time_t tim, short int flag)
295 /*
296  bit0=with hours+minutes
297  bit1=with seconds
298 
299  bit8= local time rather than UTC
300 */
301 {
302  static char zeitcode[80]={"000000"};
303  char puff[80];
304  struct tm *azt;
305 
306  if(flag&256)
307  azt = localtime(&tim);
308  else
309  azt = gmtime(&tim);
310 
311  if(azt->tm_year>99)
312  sprintf(zeitcode,"%c%1.1d%2.2d%2.2d",
313  'A'+(azt->tm_year-100)/10,azt->tm_year%10,
314  azt->tm_mon+1,azt->tm_mday);
315  else
316  sprintf(zeitcode,"%2.2d%2.2d%2.2d",
317  azt->tm_year,azt->tm_mon+1,azt->tm_mday);
318  if(flag&1){
319  sprintf(puff,".%2.2d%2.2d",azt->tm_hour,azt->tm_min);
320  strcat(zeitcode,puff);
321  }
322  if(flag&2){
323  sprintf(puff,"%2.2d",azt->tm_sec);
324  strcat(zeitcode,puff);
325  }
326 
327  return(zeitcode);
328 }
329 
330 
331 int Sfile_scale(double value, char *result, int siz, double thresh, int flag)
332 /*
333  bit0= omit 'b' if it would elsewise be appended
334  bit1= make text as short as possible
335  bit2= no fraction (if it would fit at all)
336 */
337 {
338  char scale_c,scales[7],form[80], *negpt= NULL, *cpt;
339  int i,dec_siz= 0,avail_siz= 1;
340 
341  if(value<0) {
342  value= -value;
343  siz--;
344  result[0]= '-';
345  negpt= result;
346  result++;
347  }
348  strcpy(scales,"bkmgtp");
349  scale_c= scales[0];
350  for(i=1;scales[i]!=0;i++) {
351  if(value<thresh-0.5)
352  break;
353  value/= 1024.0;
354  scale_c= scales[i];
355  }
356  if(scale_c!='b' && !(flag&4)) { /* is there room for fractional part ? */
357  avail_siz= siz-1;
358  sprintf(form,"%%.f");
359  sprintf(result,"%.f",value);
360  if(((int) strlen(result)) <= avail_siz - 2)
361  dec_siz= 1; /* we are very modest */
362  }
363  if(scale_c=='b' && (flag&1)) {
364  if(flag&2)
365  sprintf(form,"%%.f");
366  else
367  sprintf(form,"%%%d.f",siz);
368  sprintf(result,form,value);
369  } else {
370  if(flag&2)
371  sprintf(form,"%%.f%%c");
372  else if(dec_siz>0)
373  sprintf(form,"%%%d.%df%%c",avail_siz,dec_siz);
374  else
375  sprintf(form,"%%%d.f%%c",siz-1);
376  sprintf(result,form,value,scale_c);
377  }
378  if(negpt != NULL) {
379  for(cpt= result; *cpt==' '; cpt++);
380  if(cpt > result) {
381  *negpt= ' ';
382  *(cpt - 1)= '-';
383  }
384  }
385  return(1);
386 }
387 
388 
389 int Sfile_off_t_text(char text[80], off_t num, int flag)
390 {
391  char *tpt;
392  off_t hnum, scale= 1;
393  int digits= 0, d, i;
394 
395  tpt= text;
396  hnum= num;
397  if(hnum<0) {
398  *(tpt++)= '-';
399  hnum= -num;
400  }
401  if(hnum<0) { /* it can stay nastily persistent */
402  strcpy(text, "_overflow_");
403  return(0);
404  }
405  for(i= 0; i<23; i++) { /* good for up to 70 bit = 10 exp 21.07... */
406  if(hnum==0)
407  break;
408  hnum/= 10;
409  if(hnum)
410  scale*= 10;
411  }
412  if(i==0) {
413  strcpy(text, "0");
414  return(1);
415  }
416  if(i==23) {
417  strcpy(text, "_overflow_");
418  return(0);
419  }
420  digits= i;
421  hnum= num;
422  for(; i>0; i--) {
423  d= hnum/scale;
424  tpt[digits-i]= '0'+d;
425  hnum= hnum%scale;
426  scale/= 10;
427  }
428  tpt[digits]= 0;
429  return(1);
430 }
431 
432 
433 /* @return index number of first not interpreted text byte
434 */
435 int Sfile_text_to_off_t(char *text, off_t *num, int flag)
436 {
437  int sig= 1, ridx;
438 
439  *num= 0;
440  ridx= 0;
441  if(text[ridx] == '-') {
442  sig= -1;
443  ridx++;
444  } else if(text[ridx] == '+') {
445  ridx++;
446  }
447  for(; text[ridx] != 0; ridx++) {
448  if(text[ridx] < '0' || text[ridx] > '9')
449  break;
450  if(*num > (((off_t) 1) << 59))
451  return(-1);
452  *num= *num * 10 + text[ridx] - '0';
453  }
454  *num= *num * sig;
455  return(ridx);
456 }
457 
458 
459 /* Converts backslash codes into single characters:
460  \a BEL 7 , \b BS 8 , \e ESC 27 , \f FF 12 , \n LF 10 , \r CR 13 ,
461  \t HT 9 , \v VT 11 , \\ \ 92
462  \[0-9][0-9][0-9] octal code , \x[0-9a-f][0-9a-f] hex code ,
463  \cX control-x (ascii(X)-64)
464  @param upto maximum number of characters to examine for backslash.
465  The scope of a backslash (0 to 3 characters) is not affected.
466  @param eaten returns the difference in length between input and output
467  @param flag bit0= only determine *eaten, do not convert
468  bit1= convert \000 to binary 0
469 */
470 int Sfile_bsl_interpreter(char *text, int upto, int *eaten, int flag)
471 {
472  char *rpt, *wpt, num_text[8], wdummy[8];
473  unsigned int num= 0;
474 
475  *eaten= 0;
476  wpt= text;
477  for(rpt= text; *rpt != 0 && rpt - text < upto; rpt++) {
478  if(flag & 1)
479  wpt= wdummy;
480  if(*rpt == '\\') {
481  rpt++;
482  (*eaten)++;
483  if(*rpt == 'a') {
484  *(wpt++)= 7;
485  } else if(*rpt == 'b') {
486  *(wpt++)= 8;
487  } else if(*rpt == 'e') {
488  *(wpt++)= 27;
489  } else if(*rpt == 'f') {
490  *(wpt++)= 12;
491  } else if(*rpt == 'n') {
492  *(wpt++)= 10;
493  } else if(*rpt == 'r') {
494  *(wpt++)= 13;
495  } else if(*rpt == 't') {
496  *(wpt++)= 9;
497  } else if(*rpt == 'v') {
498  *(wpt++)= 11;
499  } else if(*rpt == '\\') {
500  *(wpt++)= '\\';
501  } else if(rpt[0] >= '0' && rpt[0] <= '7' &&
502  rpt[1] >= '0' && rpt[1] <= '7' &&
503  rpt[2] >= '0' && rpt[2] <= '7') {
504  num_text[0]= '0';
505  num_text[1]= *(rpt + 0);
506  num_text[2]= *(rpt + 1);
507  num_text[3]= *(rpt + 2);
508  num_text[4]= 0;
509  sscanf(num_text, "%o", &num);
510  if((num > 0 || (flag & 2)) && num <= 255) {
511  rpt+= 2;
512  (*eaten)+= 2;
513  *(wpt++)= num;
514  } else
515  goto not_a_code;
516  } else if(rpt[0] == 'x' &&
517  ((rpt[1] >= '0' && rpt[1] <= '9') ||
518  (rpt[1] >= 'A' && rpt[1] <= 'F') ||
519  (rpt[1] >= 'a' && rpt[1] <= 'f'))
520  &&
521  ((rpt[2] >= '0' && rpt[2] <= '9') ||
522  (rpt[2] >= 'A' && rpt[2] <= 'F') ||
523  (rpt[2] >= 'a' && rpt[2] <= 'f'))
524  ) {
525  num_text[0]= *(rpt + 1);
526  num_text[1]= *(rpt + 2);
527  num_text[2]= 0;
528  sscanf(num_text, "%x", &num);
529  if(num > 0 && num <= 255) {
530  rpt+= 2;
531  (*eaten)+= 2;
532  *(wpt++)= num;
533  } else
534  goto not_a_code;
535  } else if(*rpt == 'c') {
536  if(rpt[1] > 64 && rpt[1] < 96) {
537  *(wpt++)= rpt[1] - 64;
538  rpt++;
539  (*eaten)++;
540  } else
541  goto not_a_code;
542  } else {
543 not_a_code:;
544  *(wpt++)= '\\';
545  rpt--;
546  (*eaten)--;
547  }
548  } else
549  *(wpt++)= *rpt;
550  }
551  *wpt= *rpt;
552  return(1);
553 }
554 
555 
556 /* @param flag bit0= only encode inside quotes
557  bit1= encode < 32 outside quotes except 7, 8, 9, 10, 12, 13
558  bit2= encode in any case above 126
559  bit3= encode in any case shellsafe and name-value-safe:
560  <=42 , 59, 60, 61, 62, 63, 92, 94, 96, >=123
561 */
562 int Sfile_bsl_encoder(char **result, char *text, size_t text_len, int flag)
563 {
564  signed char *rpt;
565  char *wpt;
566  int count, sq_open= 0, dq_open= 0;
567 
568  count= 0;
569  for(rpt= (signed char *) text; (size_t) (((char *) rpt) - text) < text_len;
570  rpt++) {
571  count++;
572  if(flag & 8) {
573  if(!(*rpt <= 42 || (*rpt >= 59 && *rpt <= 63) ||
574  *rpt == 92 || *rpt == 94 || *rpt == 96 || *rpt >= 123))
575  continue;
576  } else if(*rpt >= 32 && *rpt <= 126 && *rpt != '\\')
577  continue;
578  if(((*rpt >= 7 && *rpt <= 13) || *rpt == 27 || *rpt == '\\') && !(flag & 8))
579  count++;
580  else
581  count+= 3;
582  }
583  (*result)= wpt= calloc(count + 1, 1);
584  if(wpt == NULL)
585  return(-1);
586  for(rpt= (signed char *) text; (size_t) (((char *) rpt) - text) < text_len;
587  rpt++) {
588  if(*rpt == '\'')
589  sq_open= !(sq_open || dq_open);
590  if(*rpt == '"')
591  dq_open= !(sq_open || dq_open);
592 
593  if(flag & 8) {
594  if(!(*rpt <= 42 || (*rpt >= 59 && *rpt <= 63) ||
595  *rpt == 92 || *rpt == 94 || *rpt == 96 || *rpt >= 123)) {
596  *(wpt++)= *rpt;
597  continue;
598  }
599  } else if(*rpt >= 32 && *rpt <= 126 && *rpt != '\\') {
600  *(wpt++)= *rpt;
601  continue;
602  } else if( ((flag & 1) && !(sq_open || dq_open)) &&
603  !((flag & 2) && (*rpt >= 1 && * rpt <= 31 &&
604  !(*rpt == 7 || *rpt == 8 || *rpt == 9 || *rpt == 10 ||
605  *rpt == 12 || *rpt == 13))) &&
606  !((flag & 4) && (*rpt > 126 || *rpt < 0)) &&
607  !((flag & 6) && *rpt == '\\')) {
608  *(wpt++)= *rpt;
609  continue;
610  }
611  *(wpt++)= '\\';
612  if(((*rpt >= 7 && *rpt <= 13) || *rpt == 27 || *rpt == '\\') && !(flag&8)) {
613  if(*rpt == 7)
614  *(wpt++)= 'a';
615  else if(*rpt == 8)
616  *(wpt++)= 'b';
617  else if(*rpt == 9)
618  *(wpt++)= 't';
619  else if(*rpt == 10) {
620  *(wpt++)= 'n';
621  } else if(*rpt == 11)
622  *(wpt++)= 'v';
623  else if(*rpt == 12)
624  *(wpt++)= 'f';
625  else if(*rpt == 13)
626  *(wpt++)= 'r';
627  else if(*rpt == 27)
628  *(wpt++)= 'e';
629  else if(*rpt == '\\')
630  *(wpt++)= '\\';
631  } else {
632  sprintf(wpt, "%-3.3o", (unsigned int) *((unsigned char *) rpt));
633  wpt+= 3;
634  }
635  }
636  *wpt= 0;
637  return(1);
638 }
639 
640 
641 int Sfile_destroy_argv(int *argc, char ***argv, int flag)
642 {
643  int i;
644 
645  if(*argc>0 && *argv!=NULL){
646  for(i=0;i<*argc;i++){
647  if((*argv)[i]!=NULL)
648  Smem_freE((*argv)[i]);
649  }
650  Smem_freE((char *) *argv);
651  }
652  *argc= 0;
653  *argv= NULL;
654  return(1);
655 }
656 
657 
658 int Sfile_sep_make_argv(char *progname, char *line, char *separators,
659  int max_words, int *argc, char ***argv, int flag)
660 /*
661  bit0= read progname as first argument from line
662  bit1= just release argument list argv and return
663  bit2= abort with return(0) if incomplete quotes are found
664  bit3= eventually prepend missing '-' to first argument read from line
665  bit4= like bit2 but only check quote completeness, do not allocate memory
666  bit5+6= interpretation of backslashes:
667  0= no interpretation, leave unchanged
668  1= only inside double quotes
669  2= outside single quotes
670  3= everywhere
671  bit7= append a NULL element to argv
672 */
673 {
674  int i,pass,maxl=0,l,argzaehl=0,bufl,line_start_argc, bsl_mode, ret= 0, eaten;
675  char *cpt,*start;
676  char *buf= NULL;
677 
678  Sfile_destroy_argv(argc,argv,0);
679  if(flag&2)
680  {ret= 1; goto ex;}
681 
682  if(flag & 16)
683  flag|= 4;
684  bsl_mode= (flag >> 5) & 3;
685 
686  buf= calloc(strlen(line) + SfileadrL, 1);
687  if(buf == NULL)
688  {ret= -1; goto ex;}
689  for(pass=0;pass<2;pass++) {
690  cpt= line-1;
691  if(!(flag&1)){
692  argzaehl= line_start_argc= 1;
693  if(pass==0)
694  maxl= strlen(progname);
695  else
696  strcpy((*argv)[0],progname);
697  } else {
698  argzaehl= line_start_argc= 0;
699  if(pass==0) maxl= 0;
700  }
701  while(*(++cpt)!=0){
702  if(*separators) {
703  if(strchr(separators, *cpt) != NULL)
704  continue;
705  } else if(isspace(*cpt))
706  continue;
707  start= cpt;
708  buf[0]= 0;
709  cpt--;
710 
711  if(max_words > 0 && argzaehl >= max_words && *cpt != 0) {
712  /* take uninterpreted up to the end */
713  cpt+= strlen(cpt) - 1;
714  }
715 
716  while(*(++cpt)!=0) {
717  if(*separators) {
718  if(strchr(separators, *cpt) != NULL)
719  break;
720  } else if(isspace(*cpt))
721  break;
722  if(*cpt=='"'){
723  l= cpt-start; bufl= strlen(buf);
724  if(l>0) {
725  strncpy(buf + bufl, start, l); buf[bufl + l]= 0;
726  if(bsl_mode >= 3) {
727  ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0);
728  if(ret <= 0)
729  goto ex;
730  }
731  }
732  l= strlen(buf);
733  start= cpt+1;
734  while(*(++cpt)!=0) if(*cpt=='"') break;
735  if((flag&4) && *cpt==0)
736  {ret= 0; goto ex;}
737  l= cpt-start; bufl= strlen(buf);
738  if(l>0) {
739  strncpy(buf + bufl, start, l);
740  buf[bufl + l]= 0;
741  if(bsl_mode >= 1) {
742  ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0);
743  if(ret <= 0)
744  goto ex;
745  }
746  }
747  start= cpt+1;
748  }else if(*cpt=='\''){
749  l= cpt-start; bufl= strlen(buf);
750  if(l>0) {
751  strncpy(buf + bufl, start, l); buf[bufl + l]= 0;
752  if(bsl_mode >= 3) {
753  ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0);
754  if(ret <= 0)
755  goto ex;
756  }
757  }
758  l= strlen(buf);
759  start= cpt+1;
760  while(*(++cpt)!=0) if(*cpt=='\'') break;
761  if((flag&4) && *cpt==0)
762  {ret= 0; goto ex;}
763  l= cpt-start; bufl= strlen(buf);
764  if(l>0) {
765  strncat(buf,start,l);buf[bufl+l]= 0;
766  if(bsl_mode >= 2) {
767  ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0);
768  if(ret <= 0)
769  goto ex;
770  }
771  }
772  start= cpt+1;
773  }
774  if(*cpt==0) break;
775  }
776  l= cpt-start;
777  bufl= strlen(buf);
778  if(l>0) {
779  strncpy(buf + bufl, start, l); buf[bufl + l]= 0;
780  if(bsl_mode >= 3) {
781  ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0);
782  if(ret <= 0)
783  goto ex;
784  }
785  }
786  l= strlen(buf);
787  if(pass==0){
788  if(argzaehl==line_start_argc && (flag&8))
789  if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#')
790  l++;
791  if(l>maxl) maxl= l;
792  }else{
793  strcpy((*argv)[argzaehl],buf);
794  if(argzaehl==line_start_argc && (flag&8))
795  if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#')
796  sprintf((*argv)[argzaehl],"-%s", buf);
797  }
798  argzaehl++;
799  if(*cpt==0) break;
800  }
801  if(pass==0){
802  if(flag & 16)
803  {ret= 1; goto ex;}
804  *argc= argzaehl;
805  if(argzaehl>0 || (flag & 128)) {
806  *argv= (char **) Smem_malloC((argzaehl + !!(flag & 128))
807  * sizeof(char *));
808  if(*argv==NULL)
809  {ret= -1; goto ex;}
810  }
811  for(i=0;i<*argc;i++) {
812  (*argv)[i]= (char *) Smem_malloC((maxl+1));
813  if((*argv)[i]==NULL)
814  {ret= -1; goto ex;}
815  }
816  if(flag & 128)
817  (*argv)[*argc]= NULL;
818  }
819  }
820  ret= 1;
821 ex:
822  if(buf != NULL)
823  free(buf);
824  return(ret);
825 }
826 
827 
828 int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
829  int flag)
830 {
831  return Sfile_sep_make_argv(progname, line, "", 0, argc, argv, flag);
832 }
833 
834 
835 /* @param flag bit0= append */
836 int Sfile_str(char target[SfileadrL], char *source, int flag)
837 {
838  int l;
839 
840  l= strlen(source);
841  if(flag&1)
842  l+= strlen(target);
843  if(l>=SfileadrL) {
844  fprintf(stderr, "--- Path string overflow (%d > %d). Malicious input ?\n",
845  l,SfileadrL-1);
846  return(0);
847  }
848  if(flag&1)
849  strcat(target, source);
850  else
851  strcpy(target, source);
852  return(1);
853 }
854 
855 
856 /** Combine environment variable HOME with given filename
857  @param filename Address relative to $HOME
858  @param fileadr Resulting combined address
859  @param fa_size Size of array fileadr
860  @param flag Unused yet
861  @return 1=ok , 0=no HOME variable , -1=result address too long
862 */
863 int Sfile_home_adr_s(char *filename, char *fileadr, int fa_size, int flag)
864 {
865  char *home;
866 
867  strcpy(fileadr,filename);
868  home= getenv("HOME");
869  if(home==NULL)
870  return(0);
871  if((int) (strlen(home) + strlen(filename) + 1) >= fa_size)
872  return(-1);
873  strcpy(fileadr,home);
874  if(filename[0]!=0){
875  strcat(fileadr,"/");
876  strcat(fileadr,filename);
877  }
878  return(1);
879 }
880 
881 
882 /** Return a double representing seconds and microseconds since 1 Jan 1970 */
883 double Sfile_microtime(int flag)
884 {
885  struct timeval tv;
886 
887  gettimeofday(&tv, NULL);
888  return((double) (tv.tv_sec+1.0e-6*tv.tv_usec));
889 }
890 
891 
892 int Sfile_decode_datestr(struct tm *reply, char *text, int flag)
893 /* YYMMDD[.hhmm[ss]] */
894 {
895  int i,l;
896  time_t current_time;
897  struct tm *now;
898 
899  current_time= time(0);
900  now= localtime(&current_time);
901  for(i=0; i < (int) sizeof(struct tm); i++)
902  ((char *) reply)[i]= ((char *) now)[i];
903 
904  if(text[0]<'0'|| (text[0]>'9' && text[0]<'A') || text[0]>'Z')
905  return(0);
906  l= strlen(text);
907  for(i=1;i<l;i++)
908  if(text[i]<'0'||text[i]>'9')
909  break;
910  if(i!=6)
911  return(0);
912  if(text[i]==0)
913  goto decode;
914  if(text[i]!='.' || (l!=11 && l!=13))
915  return(0);
916  for(i++;i<l;i++)
917  if(text[i]<'0'||text[i]>'9')
918  break;
919  if(i!=l)
920  return(0);
921 
922 decode:;
923  reply->tm_hour= 0;
924  reply->tm_min= 0;
925  reply->tm_sec= 0;
926  i= 0;
927  if(text[0]>='A')
928  reply->tm_year= 100+(text[i]-'A')*10+text[1]-'0';
929  else
930  reply->tm_year= 10*(text[0]-'0')+text[1]-'0';
931  reply->tm_mon= 10*(text[2]-'0')+text[3]-'0'-1;
932  reply->tm_mday= 10*(text[4]-'0')+text[5]-'0';
933  if(l==6)
934  return(1);
935  reply->tm_hour= 10*(text[7]-'0')+text[8]-'0';
936  reply->tm_min= 10*(text[9]-'0')+text[10]-'0';
937  if(l==11)
938  return(1);
939  reply->tm_sec= 10*(text[11]-'0')+text[12]-'0';
940  return(1);
941 }
942 
943 
944 /* From libisofs:
945  Find backward from idx the start byte of a possible UTF-8 character.
946  https://en.wikipedia.org/wiki/UTF-8#Description
947 */
948 static
949 int find_utf8_start(char *name, int idx, int flag)
950 {
951  unsigned char *uname, uch;
952  int i;
953 
954  uname= (unsigned char *) name;
955  if ((uname[idx] & 0xc0) != 0x80)
956  return idx; /* not an UTF-8 tail byte */
957  for (i = 0; i < 5 && idx - 1 - i >= 0; i++) {
958  /* up to deprecated 6-byte codes */
959  uch = uname[idx - 1 - i];
960  if ((uch & 0xe0) == 0xc0 || (uch & 0xf0) == 0xe0 ||
961  (uch & 0xf8) == 0xf0 || (uch & 0xfc) == 0xf8 ||
962  (uch & 0xfe) == 0xfc)
963  return (idx - 1 - i); /* UTF-8 start byte found */
964  if ((uch & 0xc0) != 0x80)
965  return idx; /* not an UTF-8 tail byte, so no UTF-8 */
966  }
967  return idx; /* no UTF-8 start found */
968 }
969 
970 
971 int Sfile_flatten_utf8_heads(char *name, int idx, int flag)
972 {
973  int neck;
974 
975  neck = find_utf8_start(name, idx, 0);
976  if(neck >= idx)
977  return(2);
978  for(; neck < idx; neck++)
979  name[neck] = '_';
980  return(1);
981 }
982 
983 
#define SfileadrL
static int find_utf8_start(char *name, int idx, int flag)
Definition: sfile.c:949
int Sfile_off_t_text(char text[80], off_t num, int flag)
Definition: sfile.c:389
int Sfile_bsl_encoder(char **result, char *text, size_t text_len, int flag)
Definition: sfile.c:562
int Sfile_home_adr_s(char *filename, char *fileadr, int fa_size, int flag)
Definition: sfile.c:863
int Sfile_type(char *filename, int flag)
Definition: sfile.c:225
int Sfile_bsl_interpreter(char *text, int upto, int *eaten, int flag)
Definition: sfile.c:470
int Sfile_count_components(char *path, int flag)
Definition: sfile.c:61
int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv, int flag)
Definition: sfile.c:828
int Sfile_sep_make_argv(char *progname, char *line, char *separators, int max_words, int *argc, char ***argv, int flag)
Definition: sfile.c:658
char * Sfile_fgets_n(char *line, int maxl, FILE *fp, int flag)
Definition: sfile.c:33
int Sfile_flatten_utf8_heads(char *name, int idx, int flag)
Definition: sfile.c:971
int Sfile_add_to_path(char path[4096], char *addon, int flag)
Definition: sfile.c:137
int Sfile_get_dev_fd_no(char *filename, int flag)
Definition: sfile.c:208
char * Sfile_datestr(time_t tim, short int flag)
Definition: sfile.c:294
int Sfile_destroy_argv(int *argc, char ***argv, int flag)
Definition: sfile.c:641
int Sfile_leafname(char *path, char leafname[4096], int flag)
Definition: sfile.c:116
int Sfile_decode_datestr(struct tm *reply, char *text, int flag)
Definition: sfile.c:892
double Sfile_microtime(int flag)
Definition: sfile.c:883
int Sfile_str(char target[4096], char *source, int flag)
Definition: sfile.c:836
int Sfile_text_to_off_t(char *text, off_t *num, int flag)
Definition: sfile.c:435
int Sfile_prepend_path(char *prefix, char path[4096], int flag)
Definition: sfile.c:161
int Sfile_count_char(char *text, char to_count)
Definition: sfile.c:49
int Sfile_scale(double value, char *result, int siz, double thresh, int flag)
Definition: sfile.c:331
int Sfile_component_pointer(char *path, char **sourcept, int idx, int flag)
Definition: sfile.c:87
#define Smem_freE
Definition: sfile.h:17
#define Smem_malloC
Definition: sfile.h:16
int Xorriso_msgs_submit(struct XorrisO *xorriso, int error_code, char msg_text[], int os_errno, char severity[], int flag)
Definition: text_io.c:2504