/*
- * $Id: volume.c,v 1.112 2009-12-18 19:18:40 franklahm Exp $
+ * $Id: volume.c,v 1.123 2010-04-04 15:04:45 franklahm Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#define VOLOPT_CASEFOLD 5 /* character case mangling */
#define VOLOPT_FLAGS 6 /* various flags */
#define VOLOPT_DBPATH 7 /* path to database */
-#define VOLOPT_MAPCHARS 8 /* does mtou and utom mappings. syntax:
- m and u can be double-byte hex
- strings if necessary.
- m=u -> map both ways
- m>u -> map m to u
- m<u -> map u to m
- !u -> make u illegal always
- ~u -> make u illegal only as the first
- part of a double-byte character.
- */
+/* Usable slots: 8 and 9 */
#define VOLOPT_VETO 10 /* list of veto filespec */
#define VOLOPT_PREEXEC 11 /* preexec command */
#define VOLOPT_ROOTPREEXEC 12 /* root preexec command */
-
#define VOLOPT_POSTEXEC 13 /* postexec command */
#define VOLOPT_ROOTPOSTEXEC 14 /* root postexec command */
-
#define VOLOPT_ENCODING 15 /* mac encoding (pre OSX)*/
#define VOLOPT_MACCHARSET 16
#define VOLOPT_CNIDSCHEME 17
#define VOLOPT_ADOUBLE 18 /* adouble version */
+
#ifdef FORCE_UIDGID
#warning UIDGID
#include "uid.h"
-#define VOLOPT_FORCEUID 19 /* force uid for username x */
-#define VOLOPT_FORCEGID 20 /* force gid for group x */
+#define VOLOPT_FORCEUID 19 /* force uid for username x */
+#define VOLOPT_FORCEGID 20 /* force gid for group x */
#endif /* FORCE_UIDGID */
-#define VOLOPT_UMASK 21
+#define VOLOPT_UMASK 21
#define VOLOPT_ALLOWED_HOSTS 22
#define VOLOPT_DENIED_HOSTS 23
-#define VOLOPT_DPERM 24 /* dperm default directories perms */
-#define VOLOPT_FPERM 25 /* fperm default files perms */
-#define VOLOPT_DFLTPERM 26 /* perm */
-#define VOLOPT_EA_VFS 27 /* Extended Attributes vfs indirection */
+#define VOLOPT_DPERM 24 /* dperm default directories perms */
+#define VOLOPT_FPERM 25 /* fperm default files perms */
+#define VOLOPT_DFLTPERM 26 /* perm */
+#define VOLOPT_EA_VFS 27 /* Extended Attributes vfs indirection */
+#define VOLOPT_CNIDSERVER 28 /* CNID Server ip address*/
+#define VOLOPT_CNIDPORT 30 /* CNID server tcp port */
-#define VOLOPT_MAX 28 /* <== IMPORTANT !!!!!! */
-#define VOLOPT_NUM (VOLOPT_MAX + 1)
+#define VOLOPT_MAX 31 /* <== IMPORTANT !!!!!! */
+#define VOLOPT_NUM (VOLOPT_MAX + 1)
#define VOLPASSLEN 8
#define VOLOPT_DEFAULT ":DEFAULT:"
p = strtok(NULL, ",");
}
+ } else if (optionok(tmp, "cnidserver:", val)) {
+ setoption(options, save, VOLOPT_CNIDSERVER, val);
+
+ char *p = strrchr(val + 1, ':');
+ if (p) {
+ *p = 0;
+ setoption(options, save, VOLOPT_CNIDPORT, p);
+ }
+
+ LOG(log_debug, logtype_afpd, "CNID Server for volume '%s': %s:%s",
+ volname, val + 1, p ? p + 1 : Cnid_port);
+
} else if (optionok(tmp, "dbpath:", val)) {
setoption(options, save, VOLOPT_DBPATH, val);
options[VOLOPT_FPERM].i_value = (int)strtol(val+1, NULL, 8);
} else if (optionok(tmp, "perm:", val)) {
options[VOLOPT_DFLTPERM].i_value = (int)strtol(val+1, NULL, 8);
- } else if (optionok(tmp, "mapchars:",val)) {
- setoption(options, save, VOLOPT_MAPCHARS, val);
-
} else if (optionok(tmp, "password:", val)) {
setoption(options, save, VOLOPT_PASSWORD, val);
volume->v_ad_options |= ADVOL_UNIXPRIV;
if ((volume->v_flags & AFPVOL_INV_DOTS))
volume->v_ad_options |= ADVOL_INVDOTS;
+ if ((volume->v_flags & AFPVOL_NOADOUBLE))
+ volume->v_ad_options |= ADVOL_NOADOUBLE;
if (options[VOLOPT_PASSWORD].c_value)
volume->v_password = strdup(options[VOLOPT_PASSWORD].c_value);
if (options[VOLOPT_CNIDSCHEME].c_value)
volume->v_cnidscheme = strdup(options[VOLOPT_CNIDSCHEME].c_value);
+ if (options[VOLOPT_CNIDSERVER].c_value)
+ volume->v_cnidserver = strdup(options[VOLOPT_CNIDSERVER].c_value);
+
+ if (options[VOLOPT_CNIDPORT].c_value)
+ volume->v_cnidport = strdup(options[VOLOPT_CNIDPORT].c_value);
+
if (options[VOLOPT_UMASK].i_value)
volume->v_umask = (mode_t)options[VOLOPT_UMASK].i_value;
}
if ( *type == '\0' ) {
- memcpy(em->em_type, "????", sizeof( em->em_type ));
+ memcpy(em->em_type, "\0\0\0\0", sizeof( em->em_type ));
} else {
memcpy(em->em_type, type, sizeof( em->em_type ));
}
if ( *creator == '\0' ) {
- memcpy(em->em_creator, "UNIX", sizeof( em->em_creator ));
+ memcpy(em->em_creator, "\0\0\0\0", sizeof( em->em_creator ));
} else {
memcpy(em->em_creator, creator, sizeof( em->em_creator ));
}
* .Parent file here if it doesn't exist. */
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if ( ad_open_metadata( vol->v_path, vol_noadouble(vol) | ADFLAGS_DIR, O_CREAT, &ad) < 0 ) {
+ if ( ad_open_metadata( vol->v_path, ADFLAGS_DIR, O_CREAT, &ad) < 0 ) {
isad = 0;
vol->v_ctime = AD_DATE_FROM_UNIX(st->st_mtime);
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);
+
+ LOG(log_info, logtype_afpd, "%s:%s", volume->v_cnidserver, volume->v_cnidport);
+
+ volume->v_cdb = cnid_open(volume->v_dbpath ? volume->v_dbpath : volume->v_path,
+ volume->v_umask,
+ volume->v_cnidscheme,
+ flags,
+ volume->v_cnidserver ? volume->v_cnidserver : Cnid_srv,
+ volume->v_cnidport ? volume->v_cnidport : Cnid_port);
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);
+ volume->v_cdb = cnid_open (volume->v_path, volume->v_umask, "tdb", flags, NULL, NULL);
#ifdef SERVERTEXT
/* kill ourself with SIGUSR2 aka msg pending */
if (volume->v_cdb) {
return AFPERR_MISC;
}
+ /* Normalize volume path */
+#ifdef REALPATH_TAKES_NULL
+ if ((volume->v_path = realpath(path, NULL)) == NULL)
+ return AFPERR_MISC;
+#else
+ if ((volume->v_path = malloc(MAXPATHLEN+1)) == NULL)
+ return AFPERR_MISC;
+ if (realpath(path, volume->v_path) == NULL) {
+ free(volume->v_path);
+ return AFPERR_MISC;
+ }
+ /* Safe some memory */
+ char *tmp;
+ if ((tmp = strdup(volume->v_path)) == NULL) {
+ free(volume->v_path);
+ return AFPERR_MISC;
+ }
+ free(volume->v_path);
+ volume->v_path = tmp;
+#endif
+
if (volume_codepage(obj, volume) < 0) {
ret = AFPERR_MISC;
goto openvol_err;
if (!(volume->v_flags & AFPVOL_RO)) {
handle_special_folders( volume );
- savevolinfo(volume, Cnid_srv, Cnid_port);
+ savevolinfo(volume,
+ volume->v_cnidserver ? volume->v_cnidserver : Cnid_srv,
+ volume->v_cnidport ? volume->v_cnidport : Cnid_port);
}
/*
if (vol->v_mtime < tv.tv_sec) {
vol->v_mtime = tv.tv_sec;
/* or finder doesn't update free space
- * XXX is it still true with newer OSX?
+ * AFP 3.2 and above clients seem to be ok without so many notification
*/
- if (afp_version > 21 && obj->options.server_notif) {
+ if (afp_version < 32 && obj->options.server_notif) {
obj->attention(obj->handle, AFPATTN_NOTIFY | AFPATTN_VOLCHANGED);
}
}
if ( !ret && folder->hide) {
/* Hide it */
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if (ad_open( p, vol_noadouble(vol) | ADFLAGS_HF|ADFLAGS_DIR,
- O_RDWR|O_CREAT, 0666, &ad) < 0) {
+ if (ad_open_metadata( p, ADFLAGS_DIR, O_CREAT, &ad) < 0) {
free (p);
free(q);
return (-1);
}
- if ((ad_get_HF_flags( &ad ) & O_CREAT) ) {
- if (ad_getentryoff(&ad, ADEID_NAME)) {
- ad_setentrylen( &ad, ADEID_NAME, strlen(folder->name));
- memcpy(ad_entry( &ad, ADEID_NAME ), folder->name,
- ad_getentrylen( &ad, ADEID_NAME ));
- }
- }
+
+ ad_setname(&ad, folder->name);
ad_getattr(&ad, &attr);
attr |= htons( ntohs( attr ) | ATTRBIT_INVISIBLE );
}
ad_flush( &ad );
- ad_close( &ad, ADFLAGS_HF );
+ ad_close_metadata( &ad);
}
free(p);
free(q);