/*
- * $Id: volume.c,v 1.115.2.2 2010-02-09 14:56:30 franklahm Exp $
+ * $Id$
*
* 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.
- */
+#define VOLOPT_LIMITSIZE 8 /* Limit the size of the volume */
+/* Usable slot: 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:"
options[VOLOPT_FLAGS].i_value &= ~AFPVOL_CACHE;
else if (strcasecmp(p, "tm") == 0)
options[VOLOPT_FLAGS].i_value |= AFPVOL_TM;
- else if (strcasecmp(p, "eject") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_EJECT | AFPVOL_RO;
-
+/* Found this in branch dir-rewrite, maybe we want to use it sometimes */
+#if 0
+ else if (strcasecmp(p, "cdrom") == 0)
+ options[VOLOPT_FLAGS].i_value |= AFPVOL_CDROM | AFPVOL_RO;
+#endif
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);
else if (strcasecmp(val + 1, "none") == 0)
options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_NONE;
+ } else if (optionok(tmp, "volsizelimit:", val)) {
+ options[VOLOPT_LIMITSIZE].i_value = (uint32_t)strtoul(val + 1, NULL, 10);
+
} else {
/* ignore unknown options */
LOG(log_debug, logtype_afpd, "ignoring unknown volume option: %s", tmp);
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;
else
volume->v_adouble = AD_VERSION;
+ if (options[VOLOPT_LIMITSIZE].i_value)
+ volume->v_limitsize = options[VOLOPT_LIMITSIZE].i_value;
+
/* Mac to Unix conversion flags*/
volume->v_mtou_flags = 0;
if (!(volume->v_flags & AFPVOL_NOHEX))
}
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 ));
}
}
#endif
- if (( rc = ustatfs_getvolspace( vol, xbfree, xbtotal,
- bsize)) != AFP_OK ) {
+ if (( rc = ustatfs_getvolspace( vol, xbfree, xbtotal, bsize)) != AFP_OK ) {
return( rc );
}
vol->v_flags = ( ~AFPVOL_GVSMASK & vol->v_flags ) | AFPVOL_USTATFS;
getvolspace_done:
+ if (vol->v_limitsize) {
+ /* FIXME: Free could be limit minus (total minus used), */
+ /* which will confuse the client less ? */
+ *xbfree = min(*xbfree, (vol->v_limitsize * 1024 * 1024));
+ *xbtotal = min(*xbtotal, (vol->v_limitsize * 1024 * 1024));
+ }
+
*bfree = min( *xbfree, maxsize);
*btotal = min( *xbtotal, maxsize);
return( AFP_OK );
LOG(log_info, logtype_afpd, "Volume %s use CNID scheme %s.", volume->v_path, volume->v_cnidscheme);
}
+ LOG(log_info, logtype_afpd, "%s:%s",
+ volume->v_cnidserver ? volume->v_cnidserver : Cnid_srv,
+ volume->v_cnidport ? volume->v_cnidport : Cnid_port);
+
+#if 0
+/* Found this in branch dir-rewrite, maybe we want to use it sometimes */
+
/* Legacy pre 2.1 way of sharing eg CD-ROM */
if (strcmp(volume->v_cnidscheme, "last") == 0) {
/* "last" is gone. We support it by switching to in-memory "tdb" */
}
/* New way of sharing CD-ROM */
- if (volume->v_flags & AFPVOL_EJECT) {
+ if (volume->v_flags & AFPVOL_CDROM) {
flags |= CNID_FLAG_MEMORY;
if (strcmp(volume->v_cnidscheme, "tdb") != 0) {
free(volume->v_cnidscheme);
volume->v_path, volume->v_cnidscheme);
}
}
+#endif
+
+ 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_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)) {
/* The first attempt failed and it wasn't yet an attempt to open in-memory */
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 ( !ret && folder->hide) {
/* Hide it */
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if (ad_open( p, 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);