pkgsrc/sysutils/ruby-quota/patches/patch-ab
2012-05-12 23:10:29 +00:00

555 lines
13 KiB
Text

$NetBSD: patch-ab,v 1.10 2012/05/12 23:10:30 dholland Exp $
- fix package's version number
- remove a debug printout
- need unistd.h for some things
- support dragonfly
- support linux 2.6+ with slightly different API
- support netbsd-3+ with statvfs
- support netbsd-6+ with libquota
- fix solaris code
- ruby API fixes
- ...?
--- quota.c.orig 2002-03-30 14:59:12.000000000 +0000
+++ quota.c
@@ -5,17 +5,25 @@
#include "ruby.h"
-#define RUBY_QUOTA_VERSION "0.4.1"
+#define RUBY_QUOTA_VERSION "0.5.1"
-#ifdef HAVE_LINUX_QUOTA_H /* for linux-2.4.x */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_LINUX_QUOTA_H /* for linux */
# define USE_LINUX_QUOTA
#endif
#ifdef HAVE_SYS_FS_UFS_QUOTA_H /* for Solaris-2.6,7,8 */
# define USE_SOLARIS_QUOTA
#endif
-#ifdef HAVE_UFS_UFS_QUOTA_H /* for *BSD */
+#ifdef HAVE_QUOTA_H /* for NetBSD-6 and up */
+# define USE_NETBSD_QUOTA
+#else
+#ifdef HAVE_UFS_UFS_QUOTA_H /* for traditional *BSD */
# define USE_BSD_QUOTA
#endif
+#endif
#ifdef USE_LINUX_QUOTA
#ifdef HAVE_LINUX_TYPES_H
@@ -29,10 +37,16 @@
# include <sys/quota.h>
#endif
#include <linux/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+# define USE_LINUX_QUOTA_26
+# define qid_t uid_t
+# define dqblk if_dqblk
+#else
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
# define USE_LINUX_QUOTA_24
# define uid_t qid_t
# define dqblk disk_dqblk
+# endif
#endif
#endif
@@ -42,6 +56,12 @@
#include <sys/fs/ufs_quota.h>
#endif
+#ifdef USE_NETBSD_QUOTA
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <quota.h>
+#endif
+
#ifdef USE_BSD_QUOTA
#include <sys/types.h>
#include <sys/fcntl.h>
@@ -51,6 +71,12 @@
#if defined(SYS_UCRED_H)
# include <sys/ucred.h> /* required by NetBSD,FreeBSD */
#endif
+#if defined(__DragonFly__)
+# include <sys/param.h>
+# if __DragonFly_version >= 160000
+# define dqblk ufs_dqblk
+# endif
+#endif
#endif
static VALUE rb_mQuota;
@@ -144,7 +170,6 @@ rb_quotactl(int cmd, char *dev, VALUE vu
uid_t uid;
get_uid(vuid, &uid, &is_gid);
- printf("cmd = %d, dev = %s, uid = %d, gid? = %d\n", cmd, dev, uid, is_gid);
if( is_gid ){
return quotactl(QCMD(cmd,GRPQUOTA),dev,(qid_t)uid,addr);
}
@@ -152,14 +177,18 @@ rb_quotactl(int cmd, char *dev, VALUE vu
return quotactl(QCMD(cmd,USRQUOTA),dev,(qid_t)uid,addr);
};
};
-#elif defined(USE_BSD_QUOTA) /* for *BSD */
+#elif defined(USE_BSD_QUOTA) /* for traditional *BSD */
static int
rb_quotactl(int cmd, char *dev, VALUE vuid, caddr_t addr)
{
char *path;
int is_gid;
uid_t uid;
+#if defined(HAVE_SYS_STATVFS_H) && !defined(__DragonFly__)
+ struct statvfs *buff;
+#else
struct statfs *buff;
+#endif
int i, count, ret;
buff = 0;
@@ -187,12 +216,16 @@ rb_quotactl(int cmd, char *dev, VALUE vu
static int
rb_quotactl(int cmd, char *dev, VALUE vuid, caddr_t addr)
{
- struct quotctl qctl = {cmd, uid, addr};
+ struct quotctl qctl;
int fd;
uid_t uid;
get_uid(vuid, &uid, 0);
+ qctl.op = cmd;
+ qctl.uid = uid;
+ qctl.addr = addr;
+
switch( cmd ){
case Q_QUOTAON:
case Q_QUOTAOFF:
@@ -225,17 +258,217 @@ rb_quotactl(int cmd, char *dev, VALUE vu
};
#endif
+#ifdef USE_NETBSD_QUOTA
+
+static struct quotahandle *
+rb_quotaopen(char *dev)
+{
+ char *path;
+#if defined(HAVE_SYS_STATVFS_H) && !defined(__DragonFly__)
+ struct statvfs *buff;
+#else
+ struct statfs *buff;
+#endif
+ int i, count;
+
+ buff = 0;
+ path = dev;
+ count = getmntinfo(&buff, MNT_WAIT);
+ for( i=0; i<count; i++ ){
+ if( strcmp(buff[i].f_mntfromname, dev) == 0 ){
+ path = buff[i].f_mntonname;
+ break;
+ };
+ };
+
+ return quota_open(path);
+}
+
+static int
+rb_quotaget(char *dev, VALUE vuid, struct quotaval *blocks, struct quotaval *files)
+{
+ struct quotahandle *qh;
+
+ int is_gid;
+ uid_t uid;
+ int ret;
+ struct quotakey qk;
+
+ get_uid(vuid, &uid, &is_gid);
+ qk.qk_idtype = is_gid ? QUOTA_IDTYPE_GROUP : QUOTA_IDTYPE_USER;
+ qk.qk_id = uid;
+ qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
+
+ qh = rb_quotaopen(dev);
+ if (qh == NULL) {
+ return -1;
+ }
+
+ ret = quota_get(qh, &qk, blocks);
+ if (ret) {
+ quota_close(qh);
+ return -1;
+ }
+
+ qk.qk_objtype = QUOTA_OBJTYPE_FILES;
+ ret = quota_get(qh, &qk, files);
+ if (ret) {
+ quota_close(qh);
+ return -1;
+ }
+
+ quota_close(qh);
+ return 0;
+};
+
+static int
+rb_quotaoff(char *dev)
+{
+ struct quotahandle *qh;
+ int ret1, ret2;
+
+ qh = rb_quotaopen(dev);
+ if (qh == NULL) {
+ return -1;
+ }
+ ret1 = quota_quotaoff(qh, QUOTA_IDTYPE_USER);
+ ret2 = quota_quotaoff(qh, QUOTA_IDTYPE_GROUP);
+ quota_close(qh);
+ if (ret1 < 0 || ret2 < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+static int
+rb_quotaon(char *dev)
+{
+ struct quotahandle *qh;
+ int ret1, ret2;
+
+ qh = rb_quotaopen(dev);
+ if (qh == NULL) {
+ return -1;
+ }
+ ret1 = quota_quotaon(qh, QUOTA_IDTYPE_USER);
+ ret2 = quota_quotaon(qh, QUOTA_IDTYPE_GROUP);
+ quota_close(qh);
+ /* fail only if *both* idtypes failed */
+ if (ret1 < 0 && ret2 < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+static int
+rb_quotaput(char *dev, VALUE vuid, const struct quotaval *blocks, const struct quotaval *files)
+{
+ struct quotahandle *qh;
+
+ int is_gid;
+ uid_t uid;
+ int ret;
+ struct quotakey qk;
+
+ get_uid(vuid, &uid, &is_gid);
+ qk.qk_idtype = is_gid ? QUOTA_IDTYPE_GROUP : QUOTA_IDTYPE_USER;
+ qk.qk_id = uid;
+ qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
+
+ qh = rb_quotaopen(dev);
+ if (qh == NULL) {
+ return -1;
+ }
+
+ ret = quota_put(qh, &qk, blocks);
+ if (ret) {
+ quota_close(qh);
+ return -1;
+ }
+
+ qk.qk_objtype = QUOTA_OBJTYPE_FILES;
+ ret = quota_put(qh, &qk, files);
+ if (ret) {
+ quota_close(qh);
+ return -1;
+ }
+
+ quota_close(qh);
+ return 0;
+};
+
+#endif /* USE_NETBSD_QUOTA */
+
+#ifdef USE_NETBSD_QUOTA
+
+void
+rb_diskquota_get(VALUE dqb, struct quotaval *c_blocks, struct quotaval *c_files)
+{
+ VALUE v;
+
+#define GetMemberU(mem) \
+ ((v = rb_struct_getmember(dqb,rb_intern(mem))) == Qnil) ? 0 : (NUM2ULL(v))
+#define GetMemberS(mem) \
+ ((v = rb_struct_getmember(dqb,rb_intern(mem))) == Qnil) ? 0 : (NUM2LL(v))
+
+ c_blocks->qv_hardlimit = GetMemberU("bhardlimit");
+ c_blocks->qv_softlimit = GetMemberU("bsoftlimit");
+ c_blocks->qv_usage = GetMemberU("curblocks");
+ c_blocks->qv_expiretime = GetMemberS("btimelimit");
+ c_blocks->qv_grace = GetMemberS("bgrace");
+ c_files->qv_hardlimit = GetMemberU("ihardlimit");
+ c_files->qv_softlimit = GetMemberU("isoftlimit");
+ c_files->qv_usage = GetMemberU("curinodes");
+ c_files->qv_expiretime = GetMemberS("itimelimit");
+ c_files->qv_grace = GetMemberS("igrace");
+
+#undef GetMemberU
+#undef GetMemberS
+}
+
+VALUE
+rb_diskquota_new(struct quotaval *c_blocks, struct quotaval *c_files)
+{
+ VALUE dqb;
+
+ dqb = rb_struct_new(rb_sDiskQuota,
+ ULL2NUM(c_blocks->qv_hardlimit),
+ ULL2NUM(c_blocks->qv_softlimit),
+ ULL2NUM(c_blocks->qv_usage),
+ ULL2NUM(c_files->qv_hardlimit),
+ ULL2NUM(c_files->qv_softlimit),
+ ULL2NUM(c_files->qv_usage),
+ LL2NUM(c_blocks->qv_expiretime),
+ LL2NUM(c_files->qv_expiretime),
+#if 0 /* not yet */
+ LL2NUM(c_blocks->qv_grace),
+ LL2NUM(c_files->qv_grace),
+#endif
+ 0);
+ return dqb;
+}
+
+#else /* not USE_NETBSD_QUOTA */
+
void
rb_diskquota_get(VALUE dqb, struct dqblk * c_dqb)
{
VALUE v;
+#if defined(USE_LINUX_QUOTA) && \
+ (defined(USE_LINUX_QUOTA_24) || defined(USE_LINUX_QUOTA_26))
+#define GetMember(mem) \
+ ((v = rb_struct_getmember(dqb,rb_intern(mem))) == Qnil) ? 0 : (NUM2ULL(v))
+#else
#define GetMember(mem) \
((v = rb_struct_getmember(dqb,rb_intern(mem))) == Qnil) ? 0 : (NUM2UINT(v))
+#endif
#if defined(USE_LINUX_QUOTA)
c_dqb->dqb_bhardlimit = GetMember("bhardlimit");
c_dqb->dqb_bsoftlimit = GetMember("bsoftlimit");
-#if !defined(USE_LINUX_QUOTA_24)
+#if defined(USE_LINUX_QUOTA_24) || defined(USE_LINUX_QUOTA_26)
+ c_dqb->dqb_curspace = GetMember("curspace");
+#else
c_dqb->dqb_curblocks = GetMember("curblocks");
#endif
c_dqb->dqb_ihardlimit = GetMember("ihardlimit");
@@ -271,20 +504,29 @@ rb_diskquota_new(struct dqblk *c_dqb)
VALUE dqb;
#if defined(USE_LINUX_QUOTA)
+#if defined(USE_LINUX_QUOTA_24) || defined(USE_LINUX_QUOTA_26)
+ dqb = rb_struct_new(rb_sDiskQuota,
+ ULL2NUM(c_dqb->dqb_bhardlimit),
+ ULL2NUM(c_dqb->dqb_bsoftlimit),
+ ULL2NUM(c_dqb->dqb_curspace),
+ ULL2NUM(c_dqb->dqb_ihardlimit),
+ ULL2NUM(c_dqb->dqb_isoftlimit),
+ ULL2NUM(c_dqb->dqb_curinodes),
+ ULL2NUM(c_dqb->dqb_btime),
+ ULL2NUM(c_dqb->dqb_itime),
+ 0);
+#else
dqb = rb_struct_new(rb_sDiskQuota,
UINT2NUM(c_dqb->dqb_bhardlimit),
UINT2NUM(c_dqb->dqb_bsoftlimit),
-#if defined(USE_LINUX_QUOTA_24)
- UINT2NUM(c_dqb->dqb_curspace),
-#else
UINT2NUM(c_dqb->dqb_curblocks),
-#endif
UINT2NUM(c_dqb->dqb_ihardlimit),
UINT2NUM(c_dqb->dqb_isoftlimit),
UINT2NUM(c_dqb->dqb_curinodes),
UINT2NUM(c_dqb->dqb_btime),
UINT2NUM(c_dqb->dqb_itime),
0);
+#endif
#elif defined(USE_BSD_QUOTA)
dqb = rb_struct_new(rb_sDiskQuota,
UINT2NUM(c_dqb->dqb_bhardlimit),
@@ -296,7 +538,7 @@ rb_diskquota_new(struct dqblk *c_dqb)
UINT2NUM(c_dqb->dqb_btime),
UINT2NUM(c_dqb->dqb_itime),
0);
-#elif defined(USE_SOLARIS)
+#elif defined(USE_SOLARIS_QUOTA)
dqb = rb_struct_new(rb_sDiskQuota,
UINT2NUM(c_dqb->dqb_bhardlimit),
UINT2NUM(c_dqb->dqb_bsoftlimit),
@@ -311,18 +553,34 @@ rb_diskquota_new(struct dqblk *c_dqb)
return dqb;
};
+#endif /* USE_NETBSD_QUOTA */
+
static VALUE
rb_quota_getquota(VALUE self, VALUE dev, VALUE uid)
{
- char *c_dev = STR2CSTR(dev);
+ char *c_dev = StringValuePtr(dev);
+#ifdef USE_NETBSD_QUOTA
+ struct quotaval c_blocks, c_files;
+#else
struct dqblk c_dqb;
+#endif
VALUE dqb = Qnil;
+#ifdef USE_NETBSD_QUOTA
+ if( rb_quotaget(c_dev, uid, &c_blocks, &c_files) == -1 ){
+ rb_sys_fail("quota_get");
+ };
+#else
if( rb_quotactl(Q_GETQUOTA,c_dev,uid,(caddr_t)(&c_dqb)) == -1 ){
rb_sys_fail("quotactl");
};
+#endif
+#ifdef USE_NETBSD_QUOTA
+ dqb = rb_diskquota_new(&c_blocks, &c_files);
+#else
dqb = rb_diskquota_new(&c_dqb);
+#endif
return dqb;
};
@@ -330,11 +588,17 @@ rb_quota_getquota(VALUE self, VALUE dev,
VALUE
rb_quota_quotaoff(VALUE self, VALUE dev)
{
- char *c_dev = STR2CSTR(dev);
+ char *c_dev = StringValuePtr(dev);
+#ifdef USE_NETBSD_QUOTA
+ if( rb_quotaoff(c_dev) == -1 ){
+ rb_sys_fail("quota_quotaoff");
+ };
+#else
if( rb_quotactl(Q_QUOTAOFF,c_dev,Qnil,NULL) == -1 ){
rb_sys_fail("quotactl");
};
+#endif
return Qnil;
};
@@ -342,12 +606,20 @@ rb_quota_quotaoff(VALUE self, VALUE dev)
VALUE
rb_quota_quotaon(VALUE self, VALUE dev, VALUE quotas)
{
- char *c_dev = STR2CSTR(dev);
- char *c_quotas = STR2CSTR(quotas);
+ char *c_dev = StringValuePtr(dev);
+ char *c_quotas = StringValuePtr(quotas);
+#ifdef USE_NETBSD_QUOTA
+ /* ignore the quota file names - they must be placed in /etc/fstab */
+ (void)quotas;
+ if( rb_quotaon(c_dev) == -1 ){
+ rb_sys_fail("quota_quotaon");
+ };
+#else
if( rb_quotactl(Q_QUOTAON,c_dev,Qnil,(caddr_t)c_quotas) == -1 ){
rb_sys_fail("quotactl");
};
+#endif
return Qnil;
};
@@ -355,14 +627,28 @@ rb_quota_quotaon(VALUE self, VALUE dev,
VALUE
rb_quota_setquota(VALUE self, VALUE dev, VALUE uid, VALUE dqb)
{
- char *c_dev = STR2CSTR(dev);
+ char *c_dev = StringValuePtr(dev);
+#ifdef USE_NETBSD_QUOTA
+ struct quotaval c_qvb, c_qvf;
+#else
struct dqblk c_dqb;
+#endif
+#ifdef USE_NETBSD_QUOTA
+ rb_diskquota_get(dqb, &c_qvb, &c_qvf);
+#else
rb_diskquota_get(dqb, &c_dqb);
+#endif
+#ifdef USE_NETBSD_QUOTA
+ if( rb_quotaput(c_dev,uid,&c_qvb, &c_qvf) == -1 ){
+ rb_sys_fail("quota_put");
+ };
+#else
if( rb_quotactl(Q_SETQUOTA,c_dev,uid,(caddr_t)(&c_dqb)) == -1 ){
rb_sys_fail("quotactl");
};
+#endif
return Qnil;
};
@@ -371,7 +657,7 @@ VALUE
rb_quota_setqlim(VALUE self, VALUE dev, VALUE uid, VALUE dqb)
{
#ifdef Q_SETQLIM
- char *c_dev = STR2CSTR(dev);
+ char *c_dev = StringValuePtr(dev);
struct dqblk c_dqb;
rb_diskquota_get(dqb, &c_dqb);
@@ -392,18 +678,22 @@ rb_quota_setqlim(VALUE self, VALUE dev,
VALUE
rb_quota_sync(VALUE self, VALUE dev)
{
+#ifdef USE_NETBSD_QUOTA
+ /* nothing */
+#else
char *c_dev;
if( dev == Qnil ){
c_dev = NULL;
}
else{
- c_dev = STR2CSTR(dev);
+ c_dev = StringValuePtr(dev);
};
if( rb_quotactl(Q_SYNC,c_dev,Qnil,NULL) == -1 ){ /* uid and addr are ignored */
rb_sys_fail("quotactl");
};
+#endif /* USE_NETBSD_QUOTA */
return Qnil;
};
@@ -442,7 +732,7 @@ Init_quota()
"curinodes",
"btimelimit",
"itimelimit",
- 0);
+ NULL);
/* for compatibility */
#define DQ_ALIAS(a,b) rb_alias(rb_sDiskQuota,rb_intern(#a),rb_intern(#b))
@@ -454,7 +744,7 @@ Init_quota()
DQ_ALIAS(fsoftlimit=, isoftlimit=);
DQ_ALIAS(curfiles=, curinodes=);
DQ_ALIAS(ftimelimit=, itimelimit=);
-#if defined(USE_LINUX_QUOTA_24)
+#if defined(USE_LINUX_QUOTA_24) || defined(USE_LINUX_QUOTA_26)
DQ_ALIAS(curspace, curblocks);
DQ_ALIAS(curspace=, curblocks=);
#endif