#include <netinet/in.h>
#include <arpa/inet.h>
#include <inttypes.h>
+#include <time.h>
#include <atalk/asp.h>
#include <atalk/dsi.h>
#include <atalk/bstrlib.h>
#include <atalk/bstradd.h>
#include <atalk/ftw.h>
+#include <atalk/globals.h>
+#include <atalk/fce_api.h>
#ifdef CNID_DB
#include <atalk/cnid.h>
#endif /* CNID_DB*/
-#include "globals.h"
#include "directory.h"
#include "file.h"
#include "volume.h"
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif /* ! MIN */
-#ifndef NO_LARGE_VOL_SUPPORT
-#if BYTE_ORDER == BIG_ENDIAN
-#define hton64(x) (x)
-#define ntoh64(x) (x)
-#else /* BYTE_ORDER == BIG_ENDIAN */
-#define hton64(x) ((u_int64_t) (htonl(((x) >> 32) & 0xffffffffLL)) | \
- (u_int64_t) ((htonl(x) & 0xffffffffLL) << 32))
-#define ntoh64(x) (hton64(x))
-#endif /* BYTE_ORDER == BIG_ENDIAN */
-#endif /* ! NO_LARGE_VOL_SUPPORT */
-
#ifndef UUID_PRINTABLE_STRING_LENGTH
#define UUID_PRINTABLE_STRING_LENGTH 37
#endif
options[VOLOPT_FLAGS].i_value |= AFPVOL_TM;
else if (strcasecmp(p, "searchdb") == 0)
options[VOLOPT_FLAGS].i_value |= AFPVOL_SEARCHDB;
-/* 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
+ else if (strcasecmp(p, "nonetids") == 0)
+ options[VOLOPT_FLAGS].i_value |= AFPVOL_NONETIDS;
+ else if (strcasecmp(p, "noacls") == 0)
+ options[VOLOPT_FLAGS].i_value &= ~AFPVOL_ACLS;
p = strtok(NULL, ",");
}
volume->v_vid = ++lastvid;
volume->v_vid = htons(volume->v_vid);
#ifdef HAVE_ACLS
- if (check_vol_acl_support(volume))
- volume->v_flags |= AFPVOL_ACLS
-;
+ if (!check_vol_acl_support(volume))
+ volume->v_flags &= ~AFPVOL_ACLS;
#endif
/* handle options */
p1->mtime = st.st_mtime;
}
- if ((read_lock(fd, 0, SEEK_SET, 0)) != 0) {
- LOG(log_error, logtype_afpd, "readvolfile: can't lock volume file \"%s\"", path);
- if ( fclose( fp ) != 0 ) {
- LOG(log_error, logtype_afpd, "readvolfile: fclose: %s", strerror(errno) );
+ /* try putting a read lock on the volume file twice, sleep 1 second if first attempt fails */
+ int retries = 2;
+ while (1) {
+ if ((read_lock(fd, 0, SEEK_SET, 0)) != 0) {
+ retries--;
+ if (!retries) {
+ LOG(log_error, logtype_afpd, "readvolfile: can't lock volume file \"%s\"", path);
+ if ( fclose( fp ) != 0 ) {
+ LOG(log_error, logtype_afpd, "readvolfile: fclose: %s", strerror(errno) );
+ }
+ return -1;
+ }
+ sleep(1);
+ continue;
}
- return -1;
+ break;
}
memset(save_options, 0, sizeof(save_options));
/* Enable some default options for all volumes */
save_options[VOLOPT_FLAGS].i_value |= AFPVOL_CACHE;
+#ifdef HAVE_ACLS
+ save_options[VOLOPT_FLAGS].i_value |= AFPVOL_ACLS;
+#endif
save_options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_AUTO;
LOG(log_maxdebug, logtype_afpd, "readvolfile: seeding default umask: %04o",
obj->options.umask);
return 0;
}
+#define GETUSED_CACHETIME 5
/*!
* Calculate used size of a volume with nftw
*
* longer then 30 sec ago
* 1c) - the last volume modification is less then 30 sec old
*
- * @param vol (r) volume to calculate
+ * @param vol (rw) volume to calculate
*/
-static int getused(const struct vol *vol)
+static int getused(struct vol *vol)
{
static time_t vol_mtime = 0;
int ret = 0;
time_t now = time(NULL);
if (!vol_mtime
- || (!vol->v_mtime && ((vol_mtime + 30) < now))
- || (vol->v_mtime && ((vol_mtime + 30) < vol->v_mtime))
+ || (!vol->v_mtime && ((vol_mtime + GETUSED_CACHETIME) < now))
+ || (vol->v_mtime && ((vol_mtime + GETUSED_CACHETIME) < vol->v_mtime))
) {
vol_mtime = now;
getused_size = 0;
+ vol->v_written = 0;
ret = nftw(vol->v_path, getused_stat, NULL, 20, FTW_PHYS); /* 2 */
+ LOG(log_debug, logtype_afpd, "volparams: from nftw: %" PRIu64 " bytes",
+ getused_size);
} else {
+ getused_size += vol->v_written;
+ vol->v_written = 0;
LOG(log_debug, logtype_afpd, "volparams: cached used: %" PRIu64 " bytes",
getused_size);
}
return AFPERR_MISC;
LOG(log_debug, logtype_afpd, "volparams: used on volume: %" PRIu64 " bytes",
getused_size);
+ vol->v_tm_used = getused_size;
*xbtotal = min(*xbtotal, (vol->v_limitsize * 1024 * 1024));
*xbfree = min(*xbfree, *xbtotal < getused_size ? 0 : *xbtotal - getused_size);
return( AFP_OK );
}
+#define FCE_TM_DELTA 10 /* send notification every 10 seconds */
+void vol_fce_tm_event(void)
+{
+ static time_t last;
+ time_t now = time(NULL);
+ struct vol *vol = Volumes;
+
+ if ((last + FCE_TM_DELTA) < now) {
+ last = now;
+ for ( ; vol; vol = vol->v_next ) {
+ if (vol->v_flags & AFPVOL_TM)
+ (void)fce_register_tm_size(vol->v_path, vol->v_tm_used + vol->v_written);
+ }
+ }
+}
+
/* -----------------------
* set volume creation date
* avoid duplicate, well at least it tries
ashort |= VOLPBIT_ATTR_UNIXPRIV;
if (vol->v_flags & AFPVOL_TM)
ashort |= VOLPBIT_ATTR_TM;
-
+ if (vol->v_flags & AFPVOL_NONETIDS)
+ ashort |= VOLPBIT_ATTR_NONETIDS;
if (afp_version >= 32) {
if (vol->v_vfs_ea)
ashort |= VOLPBIT_ATTR_EXT_ATTRS;
static void handle_special_folders (const struct vol * vol)
{
const _special_folder *p = &special_folders[0];
+ uid_t process_uid;
+
+ process_uid = geteuid();
+ if (process_uid) {
+ if (seteuid(0) == -1) {
+ process_uid = 0;
+ }
+ }
if ((vol->v_flags & AFPVOL_RO))
return;
for (; p->name != NULL; p++) {
create_special_folder (vol, p);
}
+
+ if (process_uid) {
+ if (seteuid(process_uid) == -1) {
+ LOG(log_error, logtype_logger, "can't seteuid back %s", strerror(errno));
+ exit(EXITERR_SYS);
+ }
+ }
}
const struct vol *getvolumes(void)