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.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
33 #endif /* HAVE_CONFIG_H */
35 #include <sys/types.h>
37 #include <sys/param.h>
51 #include <atalk/cnid.h>
52 #include <atalk/volinfo.h>
53 #include <atalk/bstrlib.h>
54 #include <atalk/bstradd.h>
55 #include <atalk/util.h>
56 #include <atalk/logger.h>
57 #include <atalk/errchk.h>
60 int log_verbose; /* Logging flag */
62 void _log(enum logtype lt, char *fmt, ...)
65 static char logbuffer[1024];
68 if ( (lt == STD) || (log_verbose == 1)) {
70 len = vsnprintf(logbuffer, 1023, fmt, args);
74 printf("%s\n", logbuffer);
79 * Load volinfo and initialize struct vol
81 * @param path (r) path to evaluate
82 * @param vol (rw) structure to initialize
84 * @returns 0 on success, exits on error
86 int openvol(const char *path, afpvol_t *vol)
90 memset(vol, 0, sizeof(afpvol_t));
92 /* try to find a .AppleDesktop/.volinfo */
93 if (loadvolinfo((char *)path, &vol->volinfo) == 0) {
95 if (vol_load_charsets(&vol->volinfo) == -1)
96 ERROR("Error loading charsets!");
98 /* Sanity checks to ensure we can touch this volume */
99 if (vol->volinfo.v_adouble != AD_VERSION2)
100 ERROR("Unsupported adouble versions: %u", vol->volinfo.v_adouble);
102 if (vol->volinfo.v_vfs_ea != AFPVOL_EA_SYS)
103 ERROR("Unsupported Extended Attributes option: %u", vol->volinfo.v_vfs_ea);
105 /* initialize sufficient struct vol for VFS initialisation */
106 vol->volume.v_adouble = AD_VERSION2;
107 vol->volume.v_vfs_ea = AFPVOL_EA_SYS;
108 initvol_vfs(&vol->volume);
110 if ((vol->volinfo.v_flags & AFPVOL_NODEV))
111 flags |= CNID_FLAG_NODEV;
113 if ((vol->volume.v_cdb = cnid_open(vol->volinfo.v_dbpath,
117 vol->volinfo.v_dbd_host,
118 vol->volinfo.v_dbd_port)) == NULL)
119 ERROR("Cant initialize CNID database connection for %s", vol->volinfo.v_path);
121 cnid_getstamp(vol->volume.v_cdb,
123 sizeof(vol->db_stamp));
129 void closevol(afpvol_t *vol)
131 if (vol->volume.v_cdb)
132 cnid_close(vol->volume.v_cdb);
134 memset(vol, 0, sizeof(afpvol_t));
138 Taken form afpd/desktop.c
140 char *utompath(const struct volinfo *volinfo, const char *upath)
142 static char mpath[ MAXPATHLEN + 2]; /* for convert_charset dest_len parameter +2 */
145 uint16_t flags = CONV_IGNORE | CONV_UNESCAPEHEX;
153 outlen = strlen(upath);
155 if ((volinfo->v_casefold & AFPVOL_UTOMUPPER))
156 flags |= CONV_TOUPPER;
157 else if ((volinfo->v_casefold & AFPVOL_UTOMLOWER))
158 flags |= CONV_TOLOWER;
160 if ((volinfo->v_flags & AFPVOL_EILSEQ)) {
161 flags |= CONV__EILSEQ;
164 /* convert charsets */
165 if ((size_t)-1 == ( outlen = convert_charset(volinfo->v_volcharset,
167 volinfo->v_maccharset,
168 u, outlen, mpath, MAXPATHLEN, &flags)) ) {
169 SLOG("Conversion from %s to %s for %s failed.",
170 volinfo->v_volcodepage, volinfo->v_maccodepage, u);
178 * Build path relativ to volume root
182 * "dir/subdir" with cwd: "/afp_volume/topdir"
184 * "/afp_volume/dir/subdir"
186 * @param path (r) path relative to cwd() or absolute
187 * @param volpath (r) volume path that path is a subdir of (has been computed in volinfo funcs)
189 * @returns relative path in new bstring, caller must bdestroy it
191 static bstring rel_path_in_vol(const char *path, const char *volpath)
195 if (path == NULL || volpath == NULL)
198 bstring fpath = NULL;
200 /* Make path absolute by concetanating for case (a) */
201 if (path[0] != '/') {
202 EC_NULL(fpath = bfromcstr(getcwdpath()));
203 if (bchar(fpath, blength(fpath) - 1) != '/')
204 EC_ZERO(bcatcstr(fpath, "/"));
205 EC_ZERO(bcatcstr(fpath, path));
206 BSTRING_STRIP_SLASH(fpath);
207 SLOG("Built path: %s", cfrombstr(fpath));
209 EC_NULL(fpath = bfromcstr(path));
210 BSTRING_STRIP_SLASH(fpath);
211 SLOG("Built path: %s", cfrombstr(fpath));
216 * fpath: /Volume/netatalk/dir/bla
217 * volpath: /Volume/netatalk/
220 EC_ZERO(bdelete(fpath, 0, strlen(volpath)));
221 SLOG("rel path: %s", cfrombstr(fpath));
230 * ResolvesCNID of a given paths
234 * "dir/subdir" with cwd: "/afp_volume/topdir"
236 * "/afp_volume/dir/subdir"
238 * 1) start recursive CNID search with
239 * a) DID:2 / "topdir"
241 * 2) ...until we have the CNID for
242 * a) "/afp_volume/topdir/dir"
243 * b) "/afp_volume/dir" (no recursion required)
245 cnid_t cnid_for_path(const struct volinfo *vi,
246 const struct vol *vol,
253 bstring rpath = NULL;
254 bstring statpath = NULL;
255 struct bstrList *l = NULL;
258 EC_NULL(rpath = rel_path_in_vol(path, vi->v_path));
259 SLOG("vol:%s, path: %s, rpath: %s", vi->v_path, path, bdata(rpath));
263 EC_NULL(statpath = bfromcstr(vi->v_path));
265 l = bsplit(rpath, '/');
266 SLOG("elem: %s, qty: %u", cfrombstr(l->entry[0]), l->qty);
267 for(int i = 0; i < l->qty ; i++) {
269 EC_ZERO(bconcat(statpath, l->entry[i]));
270 SLOG("statpath: %s", cfrombstr(statpath));
271 EC_ZERO_LOG(stat(cfrombstr(statpath), &st));
272 SLOG("db query: did: %u, name: %s, dev: %08x, ino: %08x",
273 ntohl(did), cfrombstr(l->entry[i]), st.st_dev, st.st_ino);
274 cnid = cnid_add(vol->v_cdb,
277 cfrombstr(l->entry[i]),
278 blength(l->entry[i]),
281 EC_ZERO(bcatcstr(statpath, "/"));