~ubuntu-branches/ubuntu/trusty/lifelines/trusty

« back to all changes in this revision

Viewing changes to src/stdlib/path.c

  • Committer: Bazaar Package Importer
  • Author(s): Felipe Augusto van de Wiel (faw)
  • Date: 2007-05-23 23:49:53 UTC
  • mfrom: (3.1.3 edgy)
  • Revision ID: james.westby@ubuntu.com-20070523234953-ogno9rnbmth61i7p
Tags: 3.0.50-2etch1
* Changing docs/ll-reportmanual.xml and docs/ll-userguide.xml to fix
  documentation build problems (Closes: #418347).

* lifelines-reports
  - Adding a dependency to lifelines >= 3.0.50 to prevent file conflict.
    (Closes: #405500).

* Updating French translation. Thanks to Bernard Adrian. (Closes: #356671).

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
 
13
13
#include "llstdlib.h"
14
14
/* llstdlib.h pulls in standard.h, config.h, sys_inc.h */
 
15
#ifndef WIN32
 
16
#include <pwd.h>
 
17
#endif
15
18
 
16
19
/*********************************************
17
20
 * local function prototypes
18
21
 *********************************************/
 
22
static STRING get_user_homedir(STRING username);
19
23
static INT zero_separate_path(STRING path);
20
24
 
21
25
/*===========================================
42
46
#endif
43
47
}
44
48
/*===============================================
 
49
 * is_path -- Is this a path (not a bare filename) ?
 
50
 *  ie, does this have any slashes in it?
 
51
 * (does not handle escaped slashes)
 
52
 *=============================================*/
 
53
BOOLEAN
 
54
is_path (CNSTRING dir)
 
55
{
 
56
 
 
57
        if (strchr(dir,LLCHRDIRSEPARATOR)) return TRUE;
 
58
#ifdef WIN32
 
59
        /* windows \ or / is path separator. */
 
60
        if (strchr(dir,'/')) return TRUE;
 
61
        if (dir[0] && dir[1]==':' && isasciiletter(dir[0])) {
 
62
                return TRUE;
 
63
        }
 
64
#endif
 
65
        return FALSE;
 
66
}
 
67
#ifdef NOTUSED
 
68
/*===============================================
45
69
 * is_absolute_path -- Is this an absolute path ?
46
 
 *  ie, does this begin with directory info
47
 
 *  handle WIN32 characters
 
70
 *  handle WIN32 characters, and ~ homedir references
48
71
 *=============================================*/
49
72
BOOLEAN
50
73
is_absolute_path (CNSTRING dir)
51
74
{
52
 
        if (is_dir_sep(dir[0]) || dir[0] == '.') return TRUE;
 
75
        /* if it starts with a slash, it's absolute */
 
76
        if (is_dir_sep(dir[0])) return TRUE;
 
77
        /* if it starts with a dot, it's relative, but not relative
 
78
        to search path, only to current directory -- as in shell logic 
 
79
        so we say it is absolute */
 
80
        if (dir[0] == '.') return TRUE;
 
81
        /* if it starts with ~, it is a reference to an absolute home dir */
53
82
        if (dir[0] == '~') return TRUE;
54
83
#ifdef WIN32
55
 
        if (is_dir_sep(dir[0]) 
56
 
                || (dir[0] && dir[1]==':' && isasciiletter(dir[0]))) {
 
84
        /* if it starts with a drive letter, it's absolute */
 
85
        if (dir[0] && dir[1]==':' && isasciiletter(dir[0])) {
57
86
                return TRUE;
58
87
        }
59
88
#endif
60
89
        return FALSE;
61
 
}
 
90
}       
 
91
#endif
62
92
/*=========================================
63
93
 * path_match -- are paths the same ?
64
94
 *  handle WIN32 filename case insensitivity
76
106
 * path_cmp -- compare two paths as appropriate
77
107
 *  handle WIN32 filename case insensitivity
78
108
 *===============================*/
79
 
int
 
109
INT
80
110
path_cmp (CNSTRING path1, CNSTRING path2)
81
111
{
82
112
/* Special case for Win32, which needs case-insensitive */
187
217
 * filepath -- Find file in sequence of paths
188
218
 *  handles NULL in either argument
189
219
 *  returns alloc'd buffer
 
220
 * Warning: if called with mode other than "r" this may not 
 
221
 *         do what you want, because 1) if file is not found, it appends ext.
 
222
 *         and 2) file always goes in 1st specified directory of path unless
 
223
 *         name is absolute or ./something
190
224
 *=========================================*/
191
225
STRING
192
226
filepath (CNSTRING name, CNSTRING mode, CNSTRING path, CNSTRING  ext, INT utf8)
197
231
 
198
232
        if (ISNULL(name)) return NULL;
199
233
        if (ISNULL(path)) return strsave(name);
200
 
        if (is_absolute_path(name)) return strsave(name);
201
234
        nlen = strlen(name);
202
 
        if(ext && *ext) {
 
235
        if (ext && *ext) {
203
236
                elen = strlen(ext);
204
237
                if ((nlen > elen) && path_match(name+nlen-elen, ext)) {
205
238
                /*  name has an explicit extension the same as this one */
209
242
        }
210
243
        else { ext = NULL; elen = 0; }
211
244
        if (nlen + strlen(path) + elen >= MAXLINELEN) return NULL;
 
245
 
 
246
        /* for absolute and relative path names we first check the
 
247
         * pathname for validity relative to the current directory
 
248
         */
 
249
        if (is_path(name)) {
 
250
                /* If this is a path, i.e. it has multiple path elements
 
251
                 * use the name as is first.  So absolute paths don't
 
252
                 * get resolved by appending search paths.
 
253
                 */
 
254
                if (ext) {
 
255
                        strcpy(buf1,name);
 
256
                        nlen = strlen(buf1);
 
257
                        if (nlen < elen || strcmp(&buf1[nlen-elen],ext) != 0) {
 
258
                                strcat(buf1, ext);
 
259
                                if (access(buf1, 0) == 0) return strsave(buf1);
 
260
                                buf1[nlen] = '\0'; /* remove extension */
 
261
                        }
 
262
                        if (access(buf1, 0) == 0) return strsave(buf1);
 
263
                } else {
 
264
                        if (access(name, 0) == 0) return strsave(name);
 
265
                }
 
266
                /* fail if get here and name begins with a / or ./
 
267
                 * as we didn't find the file.
 
268
                 * however let foo/bar sneak thru, so we allow access
 
269
                 * to files in subdirectories of the search path if 
 
270
                 * named in the filename.
 
271
                 */
 
272
                if (is_dir_sep(name[0]) || (name[0] == '.' && is_dir_sep(name[1])))
 
273
                        return strsave(name);
 
274
#ifdef WIN32
 
275
                if (name[0] && name[1]==':' && isasciiletter(name[0])) {
 
276
                        return strsave(name);
 
277
                }
 
278
#endif
 
279
        }
 
280
 
 
281
        /* it is a relative path, so search for it in search path */
212
282
        strcpy(buf1, path);
213
283
        zero_separate_path(buf1);
214
284
        p = buf1;
222
292
                        q++;
223
293
                }
224
294
                strcpy(q, name);
225
 
                if(ext) {
226
 
                    strcat(buf2, ext);
227
 
                    if(access(buf2, 0) == 0) return strsave(buf2);
228
 
                    nlen = strlen(buf2);
229
 
                    buf2[nlen-elen] = '\0'; /* remove extension */
 
295
                if (ext) {
 
296
                        nlen = strlen(buf2);
 
297
                        if (nlen < elen || strcmp(&buf2[nlen-elen],ext) != 0) {
 
298
                                strcat(buf2, ext);
 
299
                                if (access(buf2, 0) == 0) return strsave(buf2);
 
300
                                buf2[nlen] = '\0'; /* remove extension */
 
301
                        }
230
302
                }
231
303
                if (access(buf2, 0) == 0) return strsave(buf2);
232
304
                p += strlen(p);
238
310
        strcpy(q, p);
239
311
        expand_special_fname_chars(buf2, sizeof(buf2), utf8);
240
312
        q += strlen(q);
241
 
        strcpy(q, LLSTRDIRSEPARATOR);
242
 
        q++;
 
313
        if (q>buf2 && !is_dir_sep(q[-1])) {
 
314
                strcpy(q, LLSTRDIRSEPARATOR);
 
315
                q++;
 
316
        }
243
317
        strcpy(q, name);
244
 
        if(ext) strcat(q, ext);
 
318
        if (ext) strcat(q, ext);
245
319
        return strsave(buf2);
246
320
}
247
321
/*===========================================
430
504
 *  path:  [IN]  path list to copy
431
505
 *  dirs:  [OUT] output buffer
432
506
 * NB: dirs should be one byte larger than path
 
507
 *     ignore zero length paths
433
508
 *================================================*/
434
509
INT
435
510
chop_path (CNSTRING path, STRING dirs)
483
558
BOOLEAN
484
559
expand_special_fname_chars (STRING buffer, INT buflen, INT utf8)
485
560
{
 
561
        char * sep=0;
486
562
        if (buffer[0]=='~') {
487
563
                if (is_dir_sep(buffer[1])) {
488
564
                        STRING home = get_home();
489
565
                        if (home && home[0]) {
490
566
                                STRING tmp;
491
 
                                if ((INT)strlen(buffer)+(INT)strlen(home)+1 > buflen) {
 
567
                                if ((INT)strlen(home) + 1 + (INT)strlen(buffer) > buflen) {
492
568
                                        return FALSE;
493
569
                                }
494
570
                                tmp = strsave(buffer);
499
575
                                return TRUE;
500
576
                        }
501
577
                }
502
 
                /* TODO: handle other homes (eg, ~someone/) ? */
 
578
                /* check for ~name/... and resolve the ~name */
 
579
                if ((sep = strchr(buffer,LLCHRDIRSEPARATOR))) {
 
580
                        STRING username = strsave(buffer+1);
 
581
                        STRING homedir;
 
582
                        username[sep-buffer+1] = 0;
 
583
                        homedir = get_user_homedir(username);
 
584
                        strfree(&username);
 
585
                        if (homedir) {
 
586
                                STRING tmp=0;
 
587
                                if ((INT)strlen(homedir) + 1 + (INT)strlen(sep+1) > buflen) {
 
588
                                        return FALSE;
 
589
                                }
 
590
                                tmp = strsave(sep+1);
 
591
                                buffer[0] = 0;
 
592
                                llstrapps(buffer, buflen, utf8, homedir);
 
593
                                llstrapps(buffer, buflen, utf8, tmp+(sep-buffer+1));
 
594
                                strfree(&tmp);
 
595
                                return TRUE;
 
596
                        }
 
597
                }
503
598
        }
504
599
        return TRUE;
505
600
}
 
601
/*============================================
 
602
 * get_user_homedir -- Return home directory of specified user
 
603
 *  returns 0 if unknown or error
 
604
 *  returns alloc'd value
 
605
 *==========================================*/
 
606
static STRING
 
607
get_user_homedir (STRING username)
 
608
{
 
609
        struct passwd *pw=0;
 
610
        if (!username) return 0;
 
611
#ifdef WIN32
 
612
        /*
 
613
        This could be implemented for NT+ class using NetUserGetInfo,
 
614
        but I doubt it's worth the trouble. Perry, 2005-11-25.
 
615
        */
 
616
#else /* not WIN32 */
 
617
        setpwent();
 
618
        /* loop through the password file/database
 
619
         * to see if the string following ~ matches
 
620
         * a login name - 
 
621
         */
 
622
        while ((pw = getpwent())) {
 
623
                if (eqstr(pw->pw_name,username)) {
 
624
                        /* found user in passwd file */
 
625
                        STRING homedir = strsave(pw->pw_dir);
 
626
                        endpwent();
 
627
                        return homedir;
 
628
                }
 
629
        }
 
630
        endpwent();
 
631
#endif
 
632
        return 0;
 
633
}