]> arthur.barton.de Git - netatalk.git/commitdiff
Add support for new NetBSD quota subsystem, Bug ID 3249879.
authorFrank Lahm <franklahm@googlemail.com>
Thu, 18 Aug 2011 12:29:48 +0000 (14:29 +0200)
committerFrank Lahm <franklahm@googlemail.com>
Thu, 18 Aug 2011 12:29:48 +0000 (14:29 +0200)
NEWS
etc/afpd/nfsquota.c
etc/afpd/quota.c
etc/afpd/unix.h
macros/quota-check.m4

diff --git a/NEWS b/NEWS
index 0e3c427b2ff3af0c25ae997b193d67a46d0de534..ae1f6b6eac1b591a2af5589fa286254498d6a76a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ Changes in 2.2.1
        to disable ACLs for a volume.
 * UPD: afpd: add a configurable hold time option to FCE file modification event
        generation, default is 60 s, new option "fceholdfmod" to change it
+* UPD: afpd: add support for new NetBSD quota subsystem, Bug ID 3249879
 * FIX: afpd: increase BerkeleyDB locks and lockobjs
 * FIX: afpd: create special folder as root
 * FIX: afpd: fix compilation error if --enable-ddp is used
index e3ad5ddc164a0c2725f4e841552cc6a03024a95d..28e61695722f402dc6bb1e8c806d62da60be3243 100644 (file)
@@ -18,7 +18,7 @@
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
 
-#ifndef NO_QUOTA_SUPPORT
+#if !defined(NO_QUOTA_SUPPORT) && !defined(HAVE_LIBQUOTA)
 #include <stdio.h>
 /* STDC check */
 #if STDC_HEADERS
@@ -185,4 +185,4 @@ int getnfsquota(struct vol *vol, const int uid, const u_int32_t bsize,
     *hostpath = ':';
     return AFPERR_PARAM;
 }
-#endif /* ! NO_QUOTA_SUPPORT */
+#endif /* ! NO_QUOTA_SUPPORT && !HAVE_LIBQUOTA */
index 9992948c1af20576823eca7abb8243f020cca49d..577ddab795961a2fd35be68614ba9745ba20011f 100644 (file)
@@ -47,6 +47,96 @@ char *strchr (), *strrchr ();
 #include "volume.h"
 #include "unix.h"
 
+#ifdef HAVE_LIBQUOTA
+#include <quota/quota.h>
+
+static int
+getfreespace(struct vol *vol, VolSpace *bfree, VolSpace *btotal,
+    uid_t uid, const char *classq)
+{
+       int retq;
+       struct ufs_quota_entry ufsq[QUOTA_NLIMITS];
+       time_t now;
+
+       if (time(&now) == -1) {
+               LOG(log_info, logtype_afpd, "time(): %s",
+                   strerror(errno));
+               return -1;
+       }
+
+       if ( seteuid( getuid() ) != 0 )  {
+               LOG(log_info, logtype_afpd, "seteuid(): %s",
+                   strerror(errno));
+               return -1;
+       }
+       if ((retq = getfsquota(vol->v_path, ufsq, uid, classq)) < 0) {
+               LOG(log_info, logtype_afpd, "getfsquota(%s, %s): %s",
+                   vol->v_path, classq, strerror(errno));
+       }
+        seteuid( uid );
+       if (retq < 1)
+               return retq;
+
+       switch(QL_STATUS(quota_check_limit(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_cur, 1,
+           ufsq[QUOTA_LIMIT_BLOCK].ufsqe_softlimit,
+           ufsq[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit,
+           ufsq[QUOTA_LIMIT_BLOCK].ufsqe_time, now))) {
+       case QL_S_DENY_HARD:
+       case QL_S_DENY_GRACE:
+               *bfree = 0;
+               *btotal = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_cur);
+               break;
+       default:
+               *bfree = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit -
+                   ufsq[QUOTA_LIMIT_BLOCK].ufsqe_cur);
+               *btotal = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit);
+               break;
+       }
+       return 1;
+}
+
+int uquota_getvolspace( struct vol *vol, VolSpace *bfree, VolSpace *btotal, const u_int32_t bsize)
+{
+       int uretq, gretq;
+       VolSpace ubfree, ubtotal;
+       VolSpace gbfree, gbtotal;
+
+       uretq = getfreespace(vol, &ubfree, &ubtotal,
+           uuid, QUOTADICT_CLASS_USER);
+       LOG(log_info, logtype_afpd, "getfsquota(%s): %d %d",
+           vol->v_path, (int)ubfree, (int)ubtotal);
+       if (ngroups >= 1) {
+               gretq = getfreespace(vol, &ubfree, &ubtotal,
+                   groups[0], QUOTADICT_CLASS_GROUP);
+       } else
+               gretq = -1;
+       if (uretq < 1 && gretq < 1) { /* no quota for this fs */
+               return AFPERR_PARAM;
+       }
+       if (uretq < 1) {
+               /* use group quotas */
+               *bfree = gbfree;
+               *btotal = gbtotal;
+       } else if (gretq < 1) {
+               /* use user quotas */
+               *bfree = ubfree;
+               *btotal = ubtotal;
+       } else {
+               /* return smallest remaining space of user and group */
+               if (ubfree < gbfree) {
+                       *bfree = ubfree;
+                       *btotal = ubtotal;
+               } else {
+                       *bfree = gbfree;
+                       *btotal = gbtotal;
+               }
+       }
+       return AFP_OK;
+
+}
+
+#else /* HAVE_LIBQUOTA */
+
 /*
 #define DEBUG_QUOTA 0
 */
@@ -739,4 +829,5 @@ int uquota_getvolspace( struct vol *vol, VolSpace *bfree, VolSpace *btotal, cons
 
        return( AFP_OK );
 }
+#endif /* HAVE_LIBQUOTA */
 #endif
index c663ecac2371ac98dc7915ee72ac700fb9b8116f..be7b7bfb4aa5bd3f8848f9ce4c31be1f80306c0e 100644 (file)
@@ -59,6 +59,7 @@ typedef int   mode_t;
 
 
 #ifndef NO_QUOTA_SUPPORT
+#if !defined(HAVE_LIBQUOTA)
 
 #if !(defined(__svr4__) || defined(HAVE_DQB_BTIMELIMIT))
 #define dqb_btimelimit  dqb_btime
@@ -211,6 +212,7 @@ extern long quotactl (unsigned int, const char *, int, caddr_t);
 extern int getnfsquota (struct vol *, const int, const u_int32_t,
                                 struct dqblk *);
 
+#endif /* ! HAVE_LIBQUOTA */
 extern int uquota_getvolspace (struct vol *, VolSpace *, VolSpace *,
                                        const u_int32_t);
 #endif /* NO_QUOTA_SUPPORT */
index 11ddd6ff526ac4281e1de99b3501128589a7fc51..44e89bc966840548c411952f21f3286d8ead543c 100644 (file)
@@ -15,6 +15,8 @@ AC_DEFUN([AC_CHECK_QUOTA], [
                netatalk_cv_quotasupport="no"
                AC_DEFINE(NO_QUOTA_SUPPORT, 1, [Define if quota support should not compiled])
        ])
+       AC_CHECK_LIB(quota, getfsquota, [QUOTA_LIBS="-lquota -lprop -lrpcsvc"
+           AC_DEFINE(HAVE_LIBQUOTA, 1, [define if you have libquota])], [], [-lprop -lrpcsvc])
        else
                netatalk_cv_quotasupport="no"
                AC_DEFINE(NO_QUOTA_SUPPORT, 1, [Define if quota support should not compiled])