]> arthur.barton.de Git - netatalk.git/blob - libatalk/util/cnid.c
afp_ldap.conf is gone
[netatalk.git] / libatalk / util / cnid.c
1 /*
2  * Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
3  * Copyright (c) 1991, 1993, 1994
4  * The Regents of the University of California.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 4. Neither the name of the University nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif /* HAVE_CONFIG_H */
34
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/stat.h>
38
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <limits.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <stdarg.h>
46 #include <string.h>
47 #include <libgen.h>
48
49 #include <atalk/util.h>
50 #include <atalk/cnid.h>
51 #include <atalk/volinfo.h>
52 #include <atalk/bstrlib.h>
53 #include <atalk/bstradd.h>
54 #include <atalk/logger.h>
55 #include <atalk/errchk.h>
56 #include <atalk/unicode.h>
57
58 /*!
59  * Build path relativ to volume root
60  *
61  * path might be:
62  * (a) relative:
63  *     "dir/subdir" with cwd: "/afp_volume/topdir"
64  * (b) absolute:
65  *     "/afp_volume/dir/subdir"
66  *
67  * @param path     (r) path relative to cwd() or absolute
68  * @param volpath  (r) volume path that path is a subdir of (has been computed in volinfo funcs)
69  *
70  * @returns relative path in new bstring, caller must bdestroy it
71  */
72 bstring rel_path_in_vol(const char *path, const char *volpath)
73 {
74     EC_INIT;
75     int cwd = -1;
76     bstring fpath = NULL;
77     char *dname = NULL;
78     struct stat st;
79
80     if (path == NULL || volpath == NULL)
81         return NULL;
82
83     EC_NEG1_LOG(cwd = open(".", O_RDONLY));
84
85     EC_ZERO_LOGSTR(lstat(path, &st), "lstat(%s): %s", path, strerror(errno));
86
87     if (path[0] == '/') {
88         EC_NULL(fpath = bfromcstr(path));
89     } else {
90         switch (S_IFMT & st.st_mode) {
91         case S_IFREG:
92         case S_IFLNK:
93             EC_NULL_LOG(dname = strdup(path));
94             EC_ZERO_LOGSTR(chdir(dirname(dname)), "chdir(%s): %s", dirname, strerror(errno));
95             free(dname);
96             dname = NULL;
97             EC_NULL(fpath = bfromcstr(getcwdpath()));
98             BSTRING_STRIP_SLASH(fpath);
99             EC_ZERO(bcatcstr(fpath, "/"));
100             EC_NULL_LOG(dname = strdup(path));
101             EC_ZERO(bcatcstr(fpath, basename(dname)));
102             break;
103
104         case S_IFDIR:
105             EC_ZERO_LOGSTR(chdir(path), "chdir(%s): %s", path, strerror(errno));
106             EC_NULL(fpath = bfromcstr(getcwdpath()));
107             break;
108
109         default:
110             EC_FAIL;
111         }
112     }
113
114     BSTRING_STRIP_SLASH(fpath);
115
116     /*
117      * Now we have eg:
118      *   fpath:   /Volume/netatalk/dir/bla
119      *   volpath: /Volume/netatalk/
120      * we want: "dir/bla"
121      */
122     int len = strlen(volpath);
123     if (volpath[len-1] != '/')
124         /* in case volpath has no trailing slash */
125         len ++;
126     EC_ZERO(bdelete(fpath, 0, len));
127
128 EC_CLEANUP:
129     if (dname) free(dname);
130     if (cwd != -1) {
131         fchdir(cwd);
132         close(cwd);
133     }
134     if (ret != 0)
135         return NULL;
136     return fpath;
137 }