~ubuntu-branches/ubuntu/precise/libisoburn/precise

« back to all changes in this revision

Viewing changes to xorriso/sfile.c

  • Committer: Bazaar Package Importer
  • Author(s): George Danchev
  • Date: 2011-05-26 16:21:32 UTC
  • mfrom: (9.1.12 sid)
  • Revision ID: james.westby@ubuntu.com-20110526162132-9lzoagfaggnera53
Tags: 1.0.8.pl00-4
* [MA] Improve package descriptions and README.Debian.
* [MA] Migrate to format "3.0 (quilt)" and compatibility 8.
  + debian/control: Drop build-dep on 'cdbs'. Require debhelper (>= 8).
  + debian/rules: Reformulate using 'dh'.
  + debian/libisoburn{1,-dev,-doc}.docs: New files.
  + debian/xorriso.docs: Addition of upstream documents.
* [GD] Make sure doxygen documentaton (doc package) is not built
       when dpkg-buildpackage -B is called (i.e. autobuilders).
* [GD] Move doxygen, graphviz to Build-Depends-Indep.
* [GD] Add missing copyrights for debian packaging.
* [GD] Standards-Version: 3.9.2 (no changes needed).
* [GD] More package description and README.Debian improvements;
       thanks to Tony Mancill <tmancill@debian.org>.

Show diffs side-by-side

added added

removed removed

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