source: trunk/third/firefox/config/pathsub.c @ 21695

Revision 21695, 5.4 KB checked in by rbasch, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21694, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Netscape Public License
6 * Version 1.1 (the "License"); you may not use this file except in
7 * compliance with the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/NPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the NPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the NPL, the GPL or the LGPL.
36 *
37 * ***** END LICENSE BLOCK ***** */
38/*
39** Pathname subroutines.
40**
41** Brendan Eich, 8/29/95
42*/
43#include <assert.h>
44#include <sys/types.h>
45#include <dirent.h>
46#include <errno.h>
47#include <stdarg.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <unistd.h>
52#include <sys/stat.h>
53#include "pathsub.h"
54
55#ifdef USE_REENTRANT_LIBC
56#include <libc_r.h>
57#endif
58
59#ifdef SUNOS4
60#include "sunos4.h"
61#endif
62
63#ifndef D_INO
64#define D_INO   d_ino
65#endif
66
67char *program;
68
69void
70fail(char *format, ...)
71{
72    int error;
73    va_list ap;
74
75#ifdef USE_REENTRANT_LIBC
76    R_STRERROR_INIT_R();
77#endif
78
79    error = errno;
80    fprintf(stderr, "%s: ", program);
81    va_start(ap, format);
82    vfprintf(stderr, format, ap);
83    va_end(ap);
84    if (error) {
85
86#ifdef USE_REENTRANT_LIBC
87    R_STRERROR_R(errno);
88        fprintf(stderr, ": %s", r_strerror_r);
89#else
90        fprintf(stderr, ": %s", strerror(errno));
91#endif
92    }
93
94    putc('\n', stderr);
95    exit(1);
96}
97
98char *
99getcomponent(char *path, char *name)
100{
101    if (*path == '\0')
102        return 0;
103    if (*path == '/') {
104        *name++ = '/';
105    } else {
106        do {
107            *name++ = *path++;
108        } while (*path != '/' && *path != '\0');
109    }
110    *name = '\0';
111    while (*path == '/')
112        path++;
113    return path;
114}
115
116#ifdef LAME_READDIR
117#include <sys/param.h>
118/*
119** The static buffer in Unixware's readdir is too small.
120*/
121struct dirent *readdir(DIR *d)
122{
123        static struct dirent *buf = NULL;
124
125        if(buf == NULL)
126                buf = (struct dirent *) malloc(sizeof(struct dirent) + MAXPATHLEN);
127        return(readdir_r(d, buf));
128}
129#endif
130
131char *
132ino2name(ino_t ino, char *dir)
133{
134    DIR *dp;
135    struct dirent *ep;
136    char *name;
137
138    dp = opendir("..");
139    if (!dp)
140        fail("cannot read parent directory");
141    for (;;) {
142        if (!(ep = readdir(dp)))
143            fail("cannot find current directory");
144        if (ep->D_INO == ino)
145            break;
146    }
147    name = xstrdup(ep->d_name);
148    closedir(dp);
149    return name;
150}
151
152void *
153xmalloc(size_t size)
154{
155    void *p = malloc(size);
156    if (!p)
157        fail("cannot allocate %u bytes", size);
158    return p;
159}
160
161char *
162xstrdup(char *s)
163{
164    return strcpy(xmalloc(strlen(s) + 1), s);
165}
166
167char *
168xbasename(char *path)
169{
170    char *cp;
171
172    while ((cp = strrchr(path, '/')) && cp[1] == '\0')
173        *cp = '\0';
174    if (!cp) return path;
175    return cp + 1;
176}
177
178void
179xchdir(char *dir)
180{
181    if (chdir(dir) < 0)
182        fail("cannot change directory to %s", dir);
183}
184
185int
186relatepaths(char *from, char *to, char *outpath)
187{
188    char *cp, *cp2;
189    int len;
190    char buf[NAME_MAX];
191
192    assert(*from == '/' && *to == '/');
193    for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++)
194        if (*cp == '\0')
195            break;
196    while (cp[-1] != '/')
197        cp--, cp2--;
198    if (cp - 1 == to) {
199        /* closest common ancestor is /, so use full pathname */
200        len = strlen(strcpy(outpath, to));
201        if (outpath[len] != '/') {
202            outpath[len++] = '/';
203            outpath[len] = '\0';
204        }
205    } else {
206        len = 0;
207        while ((cp2 = getcomponent(cp2, buf)) != 0) {
208            strcpy(outpath + len, "../");
209            len += 3;
210        }
211        while ((cp = getcomponent(cp, buf)) != 0) {
212            sprintf(outpath + len, "%s/", buf);
213            len += strlen(outpath + len);
214        }
215    }
216    return len;
217}
218
219void
220reversepath(char *inpath, char *name, int len, char *outpath)
221{
222    char *cp, *cp2;
223    char buf[NAME_MAX];
224    struct stat sb;
225
226    cp = strcpy(outpath + PATH_MAX - (len + 1), name);
227    cp2 = inpath;
228    while ((cp2 = getcomponent(cp2, buf)) != 0) {
229        if (strcmp(buf, ".") == 0)
230            continue;
231        if (strcmp(buf, "..") == 0) {
232            if (stat(".", &sb) < 0)
233                fail("cannot stat current directory");
234            name = ino2name(sb.st_ino, "..");
235            len = strlen(name);
236            cp -= len + 1;
237            strcpy(cp, name);
238            cp[len] = '/';
239            free(name);
240            xchdir("..");
241        } else {
242            cp -= 3;
243            strncpy(cp, "../", 3);
244            xchdir(buf);
245        }
246    }
247    strcpy(outpath, cp);
248}
Note: See TracBrowser for help on using the repository browser.