+ int flags = 0;
+
+ if ((volume->v_flags & AFPVOL_NODEV)) {
+ flags |= CNID_FLAG_NODEV;
+ }
+
+ if (volume->v_cnidscheme == NULL) {
+ volume->v_cnidscheme = strdup(DEFAULT_CNID_SCHEME);
+ LOG(log_info, logtype_afpd, "Volume %s use CNID scheme %s.", volume->v_path, volume->v_cnidscheme);
+ }
+ if (volume->v_dbpath)
+ volume->v_cdb = cnid_open (volume->v_dbpath, volume->v_umask, volume->v_cnidscheme, flags);
+ else
+ volume->v_cdb = cnid_open (volume->v_path, volume->v_umask, volume->v_cnidscheme, flags);
+
+ if (!volume->v_cdb) {
+ flags |= CNID_FLAG_MEMORY;
+ LOG(log_error, logtype_afpd, "Reopen volume %s using in memory temporary CNID DB.", volume->v_path);
+ volume->v_cdb = cnid_open (volume->v_path, volume->v_umask, "tdb", flags);
+#ifdef SERVERTEXT
+ /* kill ourself with SIGUSR2 aka msg pending */
+ if (volume->v_cdb) {
+ setmessage("Something wrong with the volume's DB ... FIXME with a better msg");
+ kill(getpid(), SIGUSR2);
+ /* XXX desactivate cachecnid ? */
+ }
+#endif
+ }
+
+ return (!volume->v_cdb)?-1:0;
+}
+
+/*
+ Check if the underlying filesystem supports EAs for ea:sys volumes.
+ If not, switch to ea:ad.
+ As we can't check (requires write access) on ro-volumes, we switch ea:auto
+ volumes that are options:ro to ea:none.
+*/
+static void check_ea_sys_support(struct vol *vol)
+{
+ uid_t process_uid = 0;
+ char eaname[] = {"org.netatalk.supports-eas.XXXXXX"};
+ const char *eacontent = "yes";
+
+ if (vol->v_vfs_ea == AFPVOL_EA_AUTO) {
+
+ if ((vol->v_flags & AFPVOL_RO) == AFPVOL_RO) {
+ LOG(log_info, logtype_logger, "read-only volume '%s', can't test for EA support, disabling EAs", vol->v_localname);
+ vol->v_vfs_ea = AFPVOL_EA_NONE;
+ return;
+ }
+
+ mktemp(eaname);
+
+ process_uid = geteuid();
+ if (process_uid)
+ if (seteuid(0) == -1) {
+ LOG(log_error, logtype_logger, "check_ea_sys_support: can't seteuid(0): %s", strerror(errno));
+ exit(EXITERR_SYS);
+ }
+
+ if ((sys_setxattr(vol->v_path, eaname, eacontent, 4, 0)) == 0) {
+ sys_removexattr(vol->v_path, eaname);
+ vol->v_vfs_ea = AFPVOL_EA_SYS;
+ } else {
+ LOG(log_warning, logtype_afpd, "volume \"%s\" does not support Extended Attributes, using ea:ad instead",
+ vol->v_localname);
+ vol->v_vfs_ea = AFPVOL_EA_AD;
+ }
+
+ if (process_uid) {
+ if (seteuid(process_uid) == -1) {
+ LOG(log_error, logtype_logger, "can't seteuid back %s", strerror(errno));
+ exit(EXITERR_SYS);
+ }
+ }
+ }
+}
+
+/* -------------------------
+ * we are the user here
+ */
+int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
+{
+ struct stat st;
+ char *volname;
+ char *p;
+
+ struct vol *volume;
+ struct dir *dir;
+ int len, ret;
+ size_t namelen;
+ u_int16_t bitmap;
+ char path[ MAXPATHLEN + 1];
+ char *vol_uname;
+ char *vol_mname;
+ char *volname_tmp;