ruby-quota 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +24 -0
- data/ChangeLog +66 -0
- data/MANIFEST +7 -0
- data/README +48 -0
- data/extconf.rb +23 -0
- data/quota.c +549 -0
- data/test.rb +52 -0
- metadata +68 -0
data/COPYING
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2000-2003 Takaaki Tateishi <ttate@users.sourceforge.jp>
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions
|
6
|
+
are met:
|
7
|
+
1. Redistributions of source code must retain the above copyright
|
8
|
+
notice, this list of conditions and the following disclaimer.
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright
|
10
|
+
notice, this list of conditions and the following disclaimer in the
|
11
|
+
documentation and/or other materials provided with the distribution.
|
12
|
+
3. The name of the author may not be used to endorse or promote products
|
13
|
+
derived from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
16
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
17
|
+
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
18
|
+
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
19
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
20
|
+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
21
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
22
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
24
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/ChangeLog
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
Thu Feb 13 07:48:16 UTC 2003 Takaaki Tateishi <ttate@users.sourceforge.net>
|
2
|
+
|
3
|
+
* Detecting V0 quota format.
|
4
|
+
|
5
|
+
Sat Mar 30 15:01:12 UTC 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
|
6
|
+
|
7
|
+
* version 0.5.1
|
8
|
+
|
9
|
+
Sat Mar 30 14:59:04 UTC 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
|
10
|
+
|
11
|
+
* The memory allocated by getmntinfo() should not be free()'d
|
12
|
+
by Ruby/Quota on FreeBSD and NetBSD.
|
13
|
+
|
14
|
+
Fri Mar 29 04:42:06 UTC 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
|
15
|
+
|
16
|
+
* version 0.5.0.
|
17
|
+
|
18
|
+
Thu Mar 21 18:57:34 UTC 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
|
19
|
+
|
20
|
+
* A memory allocated by getmntinfo() should be free()'d.
|
21
|
+
|
22
|
+
Thu Mar 21 18:54:38 UTC 2002 Kambe Takahiro <taca@sky.yamashina.kyoto.jp>
|
23
|
+
|
24
|
+
* Check on NetBSD and fix typos.
|
25
|
+
|
26
|
+
Wed Mar 20 18:32:57 UTC 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
|
27
|
+
* Use "struct disk_dqblk" defined in linux/quota.h on linux-2.4.
|
28
|
+
The disk_dqblk has a "curspaces" and "id", however don't have
|
29
|
+
"curblocks".
|
30
|
+
|
31
|
+
* Use "qid_t" instead of int or uid_t on linux-2.4.
|
32
|
+
|
33
|
+
* Add UserID and GroupID.
|
34
|
+
|
35
|
+
* Use getmntinfo() to obtain a mounted directory from a filesystem.
|
36
|
+
|
37
|
+
Mon Mar 18 20:18:39 UTC 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
|
38
|
+
* version 0.4.1
|
39
|
+
|
40
|
+
Mon Mar 18 19:36:30 UTC 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
|
41
|
+
* Use sys/quota.h if it exists.
|
42
|
+
|
43
|
+
* Add Quota::VERSION.
|
44
|
+
|
45
|
+
Tue Jul 17 12:53:03 JST 2001 Takaaki Tateishi <ttate@jaist.ac.jp>
|
46
|
+
* version 0.4
|
47
|
+
|
48
|
+
Thu Jul 5 22:29:06 JST 2001 Takaaki Tateishi <ttate@jaist.ac.jp>
|
49
|
+
* the DiskQuota has same structure members for Linux,BSD and Solaris.
|
50
|
+
aliases of the itimelimit, isoftlimit, ihardlimit and curinodes
|
51
|
+
are ftimelimit, fsoftlimit, fhardlimit and curfiles respectively
|
52
|
+
|
53
|
+
Sun Jun 24 12:51:37 JST 2001 Takaaki Tateishi <ttate@jaist.ac.jp>
|
54
|
+
* version 0.3
|
55
|
+
|
56
|
+
Sun Jun 24 12:21:30 JST 2001 Akinori MUSHA <knu@iDaemons.org>
|
57
|
+
* quota.c: support *bsd's quotactl.
|
58
|
+
|
59
|
+
Sun Dec 3 22:35:34 JST 2000 Takaaki Tateishi <ttate@jaist.ac.jp>
|
60
|
+
* version 0.2
|
61
|
+
|
62
|
+
Sun Dec 3 22:17:17 JST 2000 Takaaki Tateishi <ttate@jaist.ac.jp>
|
63
|
+
* quota.c (rb_quotactl): support linux's quotactl.
|
64
|
+
|
65
|
+
Wed Nov 22 14:20:05 JST 2000 Takaaki Tateishi <ttate@jaist.ac.jp>
|
66
|
+
* version 0.1
|
data/MANIFEST
ADDED
data/README
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
Ruby/Quota
|
2
|
+
|
3
|
+
-------------------------------------------------------------------------------
|
4
|
+
This module provides functions which manipulate disk quotas.
|
5
|
+
-------------------------------------------------------------------------------
|
6
|
+
|
7
|
+
SUPPORTED ENVIRONMENT
|
8
|
+
|
9
|
+
* Linux 2.4.x, 2.6.x
|
10
|
+
* Solaris 2.6, 7, 8
|
11
|
+
* FreeBSD
|
12
|
+
* NetBSD
|
13
|
+
* Dragonfly BSD
|
14
|
+
* Mac OS X
|
15
|
+
|
16
|
+
UNTESTED
|
17
|
+
|
18
|
+
* OpenBSD
|
19
|
+
|
20
|
+
-------------------------------------------------------------------------------
|
21
|
+
|
22
|
+
SYNOPSIS
|
23
|
+
|
24
|
+
|
25
|
+
Quota::GroupID.new(id)
|
26
|
+
Quota::GroupID[id]
|
27
|
+
Quota::UserID.new(id)
|
28
|
+
Quota::UserID[id]
|
29
|
+
|
30
|
+
Quota.quotaon(dev, quotas)
|
31
|
+
Quota.quotaoff(dev)
|
32
|
+
Quota.getquota(dev, uid)
|
33
|
+
Quota.setquota(dev, uid, dq)
|
34
|
+
Quota.setqlim(dev, uid, dq) # *BSD does not have this function.
|
35
|
+
Quota.sync(dev)
|
36
|
+
|
37
|
+
* 'dev' is a device file or a mount point (e.g. /dev/hda0, /mnt/foo). On *
|
38
|
+
BSD, this library will try to find a mounted directory from a given filesystem
|
39
|
+
using getmntinfo().
|
40
|
+
|
41
|
+
* 'quotas' is a quotas file.
|
42
|
+
|
43
|
+
* 'uid' can be a integer, in this case it is treated as a user id. If it is
|
44
|
+
a UserID or a GroupID object, it will be treated as desired.
|
45
|
+
|
46
|
+
* 'dq' is an entry of the quotas. its members are same as 'dqblk' structure
|
47
|
+
(e.g. dqb_curblocks => dq.curblocks). see also the quotactl man pages and
|
48
|
+
header files (e.g. linux/quota.h).
|
data/extconf.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#
|
2
|
+
# extconf.rb
|
3
|
+
#
|
4
|
+
# Resource
|
5
|
+
# Copyright (C) 2000 by Takaaki Tateishi <ttate@jaist.ac.jp>
|
6
|
+
# $Id: extconf.rb,v 1.1 2002/11/12 05:43:18 ttate Exp $
|
7
|
+
|
8
|
+
require "mkmf"
|
9
|
+
|
10
|
+
have_header("unistd.h")
|
11
|
+
|
12
|
+
have_header("linux/quota.h") # for linux
|
13
|
+
have_header("linux/types.h")
|
14
|
+
have_header("sys/quota.h")
|
15
|
+
have_header("sys/types.h")
|
16
|
+
|
17
|
+
have_header("sys/fs/ufs_quota.h") # for solaris
|
18
|
+
|
19
|
+
have_header("ufs/ufs/quota.h") # for *bsd
|
20
|
+
have_header("sys/ucred.h") # required by FreeBSD and NetBSD
|
21
|
+
have_header("sys/statvfs.h") # required by NetBSD
|
22
|
+
|
23
|
+
create_makefile("quota")
|
data/quota.c
ADDED
@@ -0,0 +1,549 @@
|
|
1
|
+
/* -*- C -*-
|
2
|
+
* $Id: quota.c,v 1.3 2004/08/25 16:27:50 ttate Exp $
|
3
|
+
* Copyright (C) 2000,2001,2002,2003,2004 Takaaki Tateishi <ttate@ttsky.net>
|
4
|
+
*/
|
5
|
+
|
6
|
+
/*
|
7
|
+
* TODO:
|
8
|
+
* - should use the allocation framework of ruby-1.8.x.
|
9
|
+
*/
|
10
|
+
|
11
|
+
#include "ruby.h"
|
12
|
+
|
13
|
+
#define RUBY_QUOTA_VERSION "0.7.0"
|
14
|
+
|
15
|
+
#ifdef HAVE_UNISTD_H
|
16
|
+
#include <unistd.h>
|
17
|
+
#endif
|
18
|
+
|
19
|
+
#ifdef HAVE_LINUX_QUOTA_H /* for linux-2.4.x, 2.6.x */
|
20
|
+
# define USE_LINUX_QUOTA
|
21
|
+
#endif
|
22
|
+
#ifdef __linux__
|
23
|
+
# define USE_LINUX_QUOTA /* fallback for linux pre 2.4 */
|
24
|
+
#endif
|
25
|
+
#ifdef HAVE_SYS_FS_UFS_QUOTA_H /* for Solaris-2.6,7,8 */
|
26
|
+
# define USE_SOLARIS_QUOTA
|
27
|
+
#endif
|
28
|
+
#ifdef HAVE_UFS_UFS_QUOTA_H /* for *BSD */
|
29
|
+
# define USE_BSD_QUOTA
|
30
|
+
#endif
|
31
|
+
#ifdef __APPLE__
|
32
|
+
# define USE_MACOSX_QUOTA
|
33
|
+
#endif
|
34
|
+
|
35
|
+
#ifdef USE_LINUX_QUOTA
|
36
|
+
#include <linux/version.h>
|
37
|
+
#ifdef HAVE_LINUX_TYPES_H
|
38
|
+
# include <linux/types.h>
|
39
|
+
#else
|
40
|
+
# include <sys/types.h>
|
41
|
+
#endif
|
42
|
+
#ifdef HAVE_LINUX_QUOTA_H
|
43
|
+
# include <linux/quota.h>
|
44
|
+
# /* defined for 64bit quota fields */
|
45
|
+
# define USE_LINUX_QUOTA64 (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
|
46
|
+
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
47
|
+
# define dqblk if_dqblk
|
48
|
+
# else
|
49
|
+
# define uid_t qid_t
|
50
|
+
# define dqblk disk_dqblk
|
51
|
+
# endif
|
52
|
+
#else
|
53
|
+
# include <sys/quota.h>
|
54
|
+
#endif
|
55
|
+
#endif /* USE_LINUX_QUOTA */
|
56
|
+
|
57
|
+
#ifdef USE_SOLARIS_QUOTA
|
58
|
+
#include <sys/types.h>
|
59
|
+
#include <sys/fcntl.h>
|
60
|
+
#include <sys/fs/ufs_quota.h>
|
61
|
+
#endif
|
62
|
+
|
63
|
+
#ifdef USE_BSD_QUOTA
|
64
|
+
#include <sys/types.h>
|
65
|
+
#include <sys/fcntl.h>
|
66
|
+
#include <ufs/ufs/quota.h>
|
67
|
+
#include <sys/param.h>
|
68
|
+
#include <sys/mount.h>
|
69
|
+
#if defined(SYS_UCRED_H)
|
70
|
+
# include <sys/ucred.h> /* required by NetBSD,FreeBSD */
|
71
|
+
#endif
|
72
|
+
#if defined(__DragonFly__)
|
73
|
+
# include <sys/param.h>
|
74
|
+
# if __DragonFly_version >= 160000
|
75
|
+
# define dqblk ufs_dqblk
|
76
|
+
# endif
|
77
|
+
#endif
|
78
|
+
#endif
|
79
|
+
|
80
|
+
/* XXX: bad workaround for Snow Leopard/Lion */
|
81
|
+
#ifdef USE_MACOSX_QUOTA
|
82
|
+
#include <sys/quota.h>
|
83
|
+
#include <sys/mount.h>
|
84
|
+
#define USE_BSD_QUOTA
|
85
|
+
#endif
|
86
|
+
|
87
|
+
/* XXX: Ruby 1.9 workaround */
|
88
|
+
#ifndef STR2CSTR
|
89
|
+
#define STR2CSTR(x) StringValuePtr(x)
|
90
|
+
#endif
|
91
|
+
|
92
|
+
static VALUE rb_mQuota;
|
93
|
+
static VALUE rb_cUID_, rb_cGroupID, rb_cUserID;
|
94
|
+
static VALUE rb_sDiskQuota;
|
95
|
+
static VALUE rb_eQuotaError, rb_eQuotaCtlError;
|
96
|
+
|
97
|
+
typedef struct q_uid_data {
|
98
|
+
uid_t uid;
|
99
|
+
} q_uid_data;
|
100
|
+
|
101
|
+
static uid_t
|
102
|
+
rb_quota_uid(VALUE vuid)
|
103
|
+
{
|
104
|
+
return ((q_uid_data*)DATA_PTR(vuid))->uid;
|
105
|
+
};
|
106
|
+
|
107
|
+
static void
|
108
|
+
rb_quota_uid_free(q_uid_data *data)
|
109
|
+
{
|
110
|
+
if( data ) free(data);
|
111
|
+
};
|
112
|
+
|
113
|
+
static VALUE
|
114
|
+
rb_quota_uid_new(VALUE klass, uid_t uid)
|
115
|
+
{
|
116
|
+
q_uid_data *data;
|
117
|
+
VALUE obj;
|
118
|
+
|
119
|
+
obj = Data_Make_Struct(klass, q_uid_data, 0, rb_quota_uid_free, data);
|
120
|
+
data->uid = uid;
|
121
|
+
|
122
|
+
return obj;
|
123
|
+
};
|
124
|
+
|
125
|
+
static VALUE
|
126
|
+
rb_quota_uid_s_new(int argc, VALUE argv[], VALUE klass)
|
127
|
+
{
|
128
|
+
VALUE num, obj;
|
129
|
+
|
130
|
+
rb_scan_args(argc, argv, "1", &num);
|
131
|
+
obj = rb_quota_uid_new(klass, NUM2UINT(num));
|
132
|
+
|
133
|
+
rb_obj_call_init(obj, argc, argv);
|
134
|
+
|
135
|
+
return obj;
|
136
|
+
};
|
137
|
+
|
138
|
+
static VALUE
|
139
|
+
rb_quota_uid_initialize(int argc, VALUE argv[], VALUE self)
|
140
|
+
{
|
141
|
+
return Qnil;
|
142
|
+
};
|
143
|
+
|
144
|
+
static VALUE
|
145
|
+
rb_quota_uid_to_i(VALUE self)
|
146
|
+
{
|
147
|
+
return UINT2NUM(((q_uid_data*)DATA_PTR(self))->uid);
|
148
|
+
};
|
149
|
+
|
150
|
+
static void
|
151
|
+
get_uid(VALUE vuid, uid_t *uid, int *is_gid)
|
152
|
+
{
|
153
|
+
if( (TYPE(vuid) == T_FIXNUM) || (TYPE(vuid) == T_BIGNUM) ){
|
154
|
+
if( uid ) *uid = NUM2UINT(vuid);
|
155
|
+
if( is_gid ) *is_gid = 0;
|
156
|
+
}
|
157
|
+
else if( vuid == Qnil ){
|
158
|
+
if( uid ) *uid = 0;
|
159
|
+
if( is_gid ) *is_gid = 0;
|
160
|
+
}
|
161
|
+
else if( rb_obj_is_kind_of(vuid, rb_cUserID) ){
|
162
|
+
if( uid ) *uid = rb_quota_uid(vuid);
|
163
|
+
if( is_gid ) *is_gid = 0;
|
164
|
+
}
|
165
|
+
else if( rb_obj_is_kind_of(vuid, rb_cGroupID) ){
|
166
|
+
if( uid ) *uid = rb_quota_uid(vuid);
|
167
|
+
if( is_gid ) *is_gid = 1;
|
168
|
+
}
|
169
|
+
else{
|
170
|
+
rb_raise(rb_eTypeError, "An uid or gid is expected.");
|
171
|
+
};
|
172
|
+
};
|
173
|
+
|
174
|
+
|
175
|
+
#if defined(USE_LINUX_QUOTA) /* for Linux */
|
176
|
+
static int
|
177
|
+
rb_quotactl(int cmd, char *dev, VALUE vuid, caddr_t addr)
|
178
|
+
{
|
179
|
+
int is_gid;
|
180
|
+
uid_t uid;
|
181
|
+
|
182
|
+
get_uid(vuid, &uid, &is_gid);
|
183
|
+
#ifdef DEBUG
|
184
|
+
printf("cmd = %d, dev = %s, uid = %d, gid? = %d\n", cmd, dev, uid, is_gid);
|
185
|
+
#endif
|
186
|
+
if( is_gid ){
|
187
|
+
return quotactl(QCMD(cmd,GRPQUOTA),dev,(uid_t)uid,addr);
|
188
|
+
}
|
189
|
+
else{
|
190
|
+
return quotactl(QCMD(cmd,USRQUOTA),dev,(uid_t)uid,addr);
|
191
|
+
};
|
192
|
+
};
|
193
|
+
#elif defined(USE_BSD_QUOTA) /* for *BSD */
|
194
|
+
static int
|
195
|
+
rb_quotactl(int cmd, char *dev, VALUE vuid, caddr_t addr)
|
196
|
+
{
|
197
|
+
char *path;
|
198
|
+
int is_gid;
|
199
|
+
uid_t uid;
|
200
|
+
#if defined(HAVE_SYS_STATVFS_H) && defined(__NetBSD__)
|
201
|
+
struct statvfs *buff;
|
202
|
+
#else
|
203
|
+
struct statfs *buff;
|
204
|
+
#endif
|
205
|
+
int i, count, ret;
|
206
|
+
|
207
|
+
buff = 0;
|
208
|
+
path = dev;
|
209
|
+
count = getmntinfo(&buff, MNT_WAIT);
|
210
|
+
for( i=0; i<count; i++ ){
|
211
|
+
if( strcmp(buff[i].f_mntfromname, dev) == 0 ){
|
212
|
+
path = buff[i].f_mntonname;
|
213
|
+
break;
|
214
|
+
};
|
215
|
+
};
|
216
|
+
|
217
|
+
get_uid(vuid, &uid, &is_gid);
|
218
|
+
if( is_gid ){
|
219
|
+
ret = quotactl(path,QCMD(cmd,GRPQUOTA),uid,addr);
|
220
|
+
}
|
221
|
+
else{
|
222
|
+
ret = quotactl(path,QCMD(cmd,USRQUOTA),uid,addr);
|
223
|
+
};
|
224
|
+
/* if( buff ) free(buff); */
|
225
|
+
|
226
|
+
return ret;
|
227
|
+
};
|
228
|
+
#elif defined(USE_SOLARIS_QUOTA) /* for Solaris */
|
229
|
+
static int
|
230
|
+
rb_quotactl(int cmd, char *dev, VALUE vuid, caddr_t addr)
|
231
|
+
{
|
232
|
+
struct quotctl qctl;
|
233
|
+
int fd;
|
234
|
+
uid_t uid;
|
235
|
+
|
236
|
+
get_uid(vuid, &uid, 0);
|
237
|
+
|
238
|
+
qctl.op = cmd;
|
239
|
+
qctl.uid = uid;
|
240
|
+
qctl.addr = addr;
|
241
|
+
|
242
|
+
switch( cmd ){
|
243
|
+
case Q_QUOTAON:
|
244
|
+
case Q_QUOTAOFF:
|
245
|
+
case Q_SETQUOTA:
|
246
|
+
case Q_GETQUOTA:
|
247
|
+
case Q_SETQLIM:
|
248
|
+
case Q_SYNC:
|
249
|
+
fd = open(dev,O_RDWR);
|
250
|
+
break;
|
251
|
+
case Q_ALLSYNC:
|
252
|
+
if( dev ){
|
253
|
+
fd = open(dev,O_RDWR);
|
254
|
+
}
|
255
|
+
else{
|
256
|
+
fd = open("/",O_RDWR); /* maybe is it ignored anyways? */
|
257
|
+
};
|
258
|
+
break;
|
259
|
+
default:
|
260
|
+
return -1;
|
261
|
+
}
|
262
|
+
if( fd < 0 ){
|
263
|
+
return -1;
|
264
|
+
};
|
265
|
+
if( ioctl(fd,Q_QUOTACTL,&qctl) == -1 ){
|
266
|
+
close(fd);
|
267
|
+
return -1;
|
268
|
+
};
|
269
|
+
close(fd);
|
270
|
+
|
271
|
+
return 0; /* success */
|
272
|
+
};
|
273
|
+
#endif
|
274
|
+
|
275
|
+
static void
|
276
|
+
rb_diskquota_get(VALUE dqb, struct dqblk * c_dqb)
|
277
|
+
{
|
278
|
+
VALUE v;
|
279
|
+
|
280
|
+
#if defined(USE_LINUX_QUOTA64)
|
281
|
+
#define GetMember(mem) \
|
282
|
+
((v = rb_struct_getmember(dqb,rb_intern(mem))) == Qnil) ? 0 : (NUM2ULL(v))
|
283
|
+
#else
|
284
|
+
#define GetMember(mem) \
|
285
|
+
((v = rb_struct_getmember(dqb,rb_intern(mem))) == Qnil) ? 0 : (NUM2UINT(v))
|
286
|
+
#endif
|
287
|
+
|
288
|
+
#if defined(USE_LINUX_QUOTA)
|
289
|
+
c_dqb->dqb_bhardlimit = GetMember("bhardlimit");
|
290
|
+
c_dqb->dqb_bsoftlimit = GetMember("bsoftlimit");
|
291
|
+
#if defined(HAVE_LINUX_QUOTA_H)
|
292
|
+
c_dqb->dqb_curspace = GetMember("curspace");
|
293
|
+
#else
|
294
|
+
c_dqb->dqb_curblocks = GetMember("curblocks");
|
295
|
+
#endif
|
296
|
+
c_dqb->dqb_ihardlimit = GetMember("ihardlimit");
|
297
|
+
c_dqb->dqb_isoftlimit = GetMember("isoftlimit");
|
298
|
+
c_dqb->dqb_curinodes = GetMember("curinodes");
|
299
|
+
c_dqb->dqb_btime = GetMember("btimelimit");
|
300
|
+
c_dqb->dqb_itime = GetMember("itimelimit");
|
301
|
+
#elif defined(USE_BSD_QUOTA)
|
302
|
+
c_dqb->dqb_bhardlimit = GetMember("bhardlimit");
|
303
|
+
c_dqb->dqb_bsoftlimit = GetMember("bsoftlimit");
|
304
|
+
#if defined(USE_MACOSX_QUOTA)
|
305
|
+
c_dqb->dqb_curbytes = GetMember("curbytes");
|
306
|
+
#else
|
307
|
+
c_dqb->dqb_curblocks = GetMember("curblocks");
|
308
|
+
#endif
|
309
|
+
c_dqb->dqb_ihardlimit = GetMember("ihardlimit");
|
310
|
+
c_dqb->dqb_isoftlimit = GetMember("isoftlimit");
|
311
|
+
c_dqb->dqb_curinodes = GetMember("curinodes");
|
312
|
+
c_dqb->dqb_btime = GetMember("btimelimit");
|
313
|
+
c_dqb->dqb_itime = GetMember("itimelimit");
|
314
|
+
#elif defined(USE_SOLARIS_QUOTA)
|
315
|
+
c_dqb->dqb_bhardlimit = GetMember("bhardlimit");
|
316
|
+
c_dqb->dqb_bsoftlimit = GetMember("bsoftlimit");
|
317
|
+
c_dqb->dqb_curblocks = GetMember("curblocks");
|
318
|
+
c_dqb->dqb_fhardlimit = GetMember("ihardlimit");
|
319
|
+
c_dqb->dqb_fsoftlimit = GetMember("isoftlimit");
|
320
|
+
c_dqb->dqb_curfiles = GetMember("curfiles");
|
321
|
+
c_dqb->dqb_btimelimit = GetMember("btimelimit");
|
322
|
+
c_dqb->dqb_ftimelimit = GetMember("itimelimit");
|
323
|
+
#endif
|
324
|
+
#undef GetMember
|
325
|
+
};
|
326
|
+
|
327
|
+
static VALUE
|
328
|
+
rb_diskquota_new(struct dqblk *c_dqb)
|
329
|
+
{
|
330
|
+
VALUE dqb;
|
331
|
+
|
332
|
+
#if defined(USE_LINUX_QUOTA64)
|
333
|
+
dqb = rb_struct_new(rb_sDiskQuota,
|
334
|
+
ULL2NUM(c_dqb->dqb_bhardlimit),
|
335
|
+
ULL2NUM(c_dqb->dqb_bsoftlimit),
|
336
|
+
ULL2NUM(c_dqb->dqb_curspace),
|
337
|
+
ULL2NUM(c_dqb->dqb_ihardlimit),
|
338
|
+
ULL2NUM(c_dqb->dqb_isoftlimit),
|
339
|
+
ULL2NUM(c_dqb->dqb_curinodes),
|
340
|
+
ULL2NUM(c_dqb->dqb_btime),
|
341
|
+
ULL2NUM(c_dqb->dqb_itime),
|
342
|
+
0);
|
343
|
+
#elif defined(USE_LINUX_QUOTA)
|
344
|
+
dqb = rb_struct_new(rb_sDiskQuota,
|
345
|
+
UINT2NUM(c_dqb->dqb_bhardlimit),
|
346
|
+
UINT2NUM(c_dqb->dqb_bsoftlimit),
|
347
|
+
#if defined(HAVE_LINUX_QUOTA_H)
|
348
|
+
UINT2NUM(c_dqb->dqb_curspace),
|
349
|
+
#else
|
350
|
+
UINT2NUM(c_dqb->dqb_curblocks),
|
351
|
+
#endif
|
352
|
+
UINT2NUM(c_dqb->dqb_ihardlimit),
|
353
|
+
UINT2NUM(c_dqb->dqb_isoftlimit),
|
354
|
+
UINT2NUM(c_dqb->dqb_curinodes),
|
355
|
+
UINT2NUM(c_dqb->dqb_btime),
|
356
|
+
UINT2NUM(c_dqb->dqb_itime),
|
357
|
+
0);
|
358
|
+
#elif defined(USE_BSD_QUOTA)
|
359
|
+
dqb = rb_struct_new(rb_sDiskQuota,
|
360
|
+
UINT2NUM(c_dqb->dqb_bhardlimit),
|
361
|
+
UINT2NUM(c_dqb->dqb_bsoftlimit),
|
362
|
+
#if defined(USE_MACOSX_QUOTA)
|
363
|
+
UINT2NUM(c_dqb->dqb_curbytes),
|
364
|
+
#else
|
365
|
+
UINT2NUM(c_dqb->dqb_curblocks),
|
366
|
+
#endif
|
367
|
+
UINT2NUM(c_dqb->dqb_ihardlimit),
|
368
|
+
UINT2NUM(c_dqb->dqb_isoftlimit),
|
369
|
+
UINT2NUM(c_dqb->dqb_curinodes),
|
370
|
+
UINT2NUM(c_dqb->dqb_btime),
|
371
|
+
UINT2NUM(c_dqb->dqb_itime),
|
372
|
+
0);
|
373
|
+
#elif defined(USE_SOLARIS)
|
374
|
+
dqb = rb_struct_new(rb_sDiskQuota,
|
375
|
+
UINT2NUM(c_dqb->dqb_bhardlimit),
|
376
|
+
UINT2NUM(c_dqb->dqb_bsoftlimit),
|
377
|
+
UINT2NUM(c_dqb->dqb_curblocks),
|
378
|
+
UINT2NUM(c_dqb->dqb_fhardlimit),
|
379
|
+
UINT2NUM(c_dqb->dqb_fsoftlimit),
|
380
|
+
UINT2NUM(c_dqb->dqb_curfiles),
|
381
|
+
UINT2NUM(c_dqb->dqb_btimelimit),
|
382
|
+
UINT2NUM(c_dqb->dqb_ftimelimit),
|
383
|
+
0);
|
384
|
+
#endif
|
385
|
+
return dqb;
|
386
|
+
};
|
387
|
+
|
388
|
+
static VALUE
|
389
|
+
rb_quota_getquota(VALUE self, VALUE dev, VALUE uid)
|
390
|
+
{
|
391
|
+
char *c_dev = STR2CSTR(dev);
|
392
|
+
struct dqblk c_dqb;
|
393
|
+
VALUE dqb = Qnil;
|
394
|
+
|
395
|
+
if( rb_quotactl(Q_GETQUOTA,c_dev,uid,(caddr_t)(&c_dqb)) == -1 ){
|
396
|
+
rb_sys_fail("quotactl");
|
397
|
+
};
|
398
|
+
|
399
|
+
dqb = rb_diskquota_new(&c_dqb);
|
400
|
+
|
401
|
+
return dqb;
|
402
|
+
};
|
403
|
+
|
404
|
+
static VALUE
|
405
|
+
rb_quota_quotaoff(VALUE self, VALUE dev)
|
406
|
+
{
|
407
|
+
char *c_dev = STR2CSTR(dev);
|
408
|
+
|
409
|
+
if( rb_quotactl(Q_QUOTAOFF,c_dev,Qnil,NULL) == -1 ){
|
410
|
+
rb_sys_fail("quotactl");
|
411
|
+
};
|
412
|
+
|
413
|
+
return Qnil;
|
414
|
+
};
|
415
|
+
|
416
|
+
static VALUE
|
417
|
+
rb_quota_quotaon(VALUE self, VALUE dev, VALUE quotas)
|
418
|
+
{
|
419
|
+
char *c_dev = STR2CSTR(dev);
|
420
|
+
char *c_quotas = STR2CSTR(quotas);
|
421
|
+
|
422
|
+
if( rb_quotactl(Q_QUOTAON,c_dev,Qnil,(caddr_t)c_quotas) == -1 ){
|
423
|
+
rb_sys_fail("quotactl");
|
424
|
+
};
|
425
|
+
|
426
|
+
return Qnil;
|
427
|
+
};
|
428
|
+
|
429
|
+
static VALUE
|
430
|
+
rb_quota_setquota(VALUE self, VALUE dev, VALUE uid, VALUE dqb)
|
431
|
+
{
|
432
|
+
char *c_dev = STR2CSTR(dev);
|
433
|
+
struct dqblk c_dqb;
|
434
|
+
|
435
|
+
rb_diskquota_get(dqb, &c_dqb);
|
436
|
+
|
437
|
+
if( rb_quotactl(Q_SETQUOTA,c_dev,uid,(caddr_t)(&c_dqb)) == -1 ){
|
438
|
+
rb_sys_fail("quotactl");
|
439
|
+
};
|
440
|
+
|
441
|
+
return Qnil;
|
442
|
+
};
|
443
|
+
|
444
|
+
static VALUE
|
445
|
+
rb_quota_setqlim(VALUE self, VALUE dev, VALUE uid, VALUE dqb)
|
446
|
+
{
|
447
|
+
#ifdef Q_SETQLIM
|
448
|
+
char *c_dev = STR2CSTR(dev);
|
449
|
+
struct dqblk c_dqb;
|
450
|
+
|
451
|
+
rb_diskquota_get(dqb, &c_dqb);
|
452
|
+
|
453
|
+
if( rb_quotactl(Q_SETQLIM,c_dev,uid,(caddr_t)(&c_dqb)) == -1 ){
|
454
|
+
rb_sys_fail("quotactl");
|
455
|
+
};
|
456
|
+
|
457
|
+
#ifdef DEBUG
|
458
|
+
printf("bhardlimit = %d\n",c_dqb.dqb_bhardlimit);
|
459
|
+
#endif
|
460
|
+
#else
|
461
|
+
rb_raise(rb_eQuotaError, "the system don't have Q_SETQLIM");
|
462
|
+
#endif
|
463
|
+
return Qnil;
|
464
|
+
};
|
465
|
+
|
466
|
+
static VALUE
|
467
|
+
rb_quota_sync(VALUE self, VALUE dev)
|
468
|
+
{
|
469
|
+
char *c_dev;
|
470
|
+
|
471
|
+
if( dev == Qnil ){
|
472
|
+
c_dev = NULL;
|
473
|
+
}
|
474
|
+
else{
|
475
|
+
c_dev = STR2CSTR(dev);
|
476
|
+
};
|
477
|
+
|
478
|
+
if( rb_quotactl(Q_SYNC,c_dev,Qnil,NULL) == -1 ){ /* uid and addr are ignored */
|
479
|
+
rb_sys_fail("quotactl");
|
480
|
+
};
|
481
|
+
|
482
|
+
return Qnil;
|
483
|
+
};
|
484
|
+
|
485
|
+
void
|
486
|
+
Init_quota()
|
487
|
+
{
|
488
|
+
rb_mQuota = rb_define_module("Quota");
|
489
|
+
rb_define_const(rb_mQuota, "VERSION", rb_tainted_str_new2(RUBY_QUOTA_VERSION));
|
490
|
+
rb_eQuotaError = rb_define_class_under(rb_mQuota,
|
491
|
+
"QuotaError",rb_eRuntimeError);
|
492
|
+
rb_eQuotaCtlError = rb_define_class_under(rb_mQuota,
|
493
|
+
"QuotaCtlError",rb_eQuotaError);
|
494
|
+
|
495
|
+
rb_cUID_ = rb_define_class_under(rb_mQuota, "UID_", rb_cObject);
|
496
|
+
rb_define_singleton_method(rb_cUID_, "new", rb_quota_uid_s_new, -1);
|
497
|
+
rb_define_method(rb_cUID_, "initialize", rb_quota_uid_initialize, -1);
|
498
|
+
rb_define_method(rb_cUID_, "to_i", rb_quota_uid_to_i, 0);
|
499
|
+
rb_alias(CLASS_OF(rb_cUID_), rb_intern("[]"), rb_intern("new"));
|
500
|
+
rb_alias(CLASS_OF(rb_cUID_), '|', rb_intern("new"));
|
501
|
+
rb_alias(CLASS_OF(rb_cUID_), '+', rb_intern("new"));
|
502
|
+
|
503
|
+
rb_cUserID = rb_define_class_under(rb_mQuota, "UserID", rb_cUID_);
|
504
|
+
rb_define_singleton_method(rb_cUserID, "new", rb_quota_uid_s_new, -1);
|
505
|
+
|
506
|
+
rb_cGroupID = rb_define_class_under(rb_mQuota, "GroupID", rb_cUID_);
|
507
|
+
rb_define_singleton_method(rb_cUserID, "new", rb_quota_uid_s_new, -1);
|
508
|
+
|
509
|
+
|
510
|
+
rb_sDiskQuota = rb_struct_define("DiskQuota",
|
511
|
+
"bhardlimit",
|
512
|
+
"bsoftlimit",
|
513
|
+
"curblocks",
|
514
|
+
"ihardlimit",
|
515
|
+
"isoftlimit",
|
516
|
+
"curinodes",
|
517
|
+
"btimelimit",
|
518
|
+
"itimelimit",
|
519
|
+
NULL);
|
520
|
+
|
521
|
+
/* for compatibility */
|
522
|
+
#define DQ_ALIAS(a,b) rb_alias(rb_sDiskQuota,rb_intern(#a),rb_intern(#b))
|
523
|
+
DQ_ALIAS(fhardlimit, ihardlimit);
|
524
|
+
DQ_ALIAS(fsoftlimit, isoftlimit);
|
525
|
+
DQ_ALIAS(curfiles, curinodes);
|
526
|
+
DQ_ALIAS(ftimelimit, itimelimit);
|
527
|
+
DQ_ALIAS(fhardlimit=, ihardlimit=);
|
528
|
+
DQ_ALIAS(fsoftlimit=, isoftlimit=);
|
529
|
+
DQ_ALIAS(curfiles=, curinodes=);
|
530
|
+
DQ_ALIAS(ftimelimit=, itimelimit=);
|
531
|
+
#if defined(HAVE_LINUX_QUOTA_H)
|
532
|
+
DQ_ALIAS(curspace, curblocks);
|
533
|
+
DQ_ALIAS(curspace=, curblocks=);
|
534
|
+
#endif
|
535
|
+
#if defined(USE_MACOSX_QUOTA)
|
536
|
+
DQ_ALIAS(curbytes, curblocks);
|
537
|
+
DQ_ALIAS(curbytes=, curblocks=);
|
538
|
+
#endif
|
539
|
+
#undef DQ_ALIAS
|
540
|
+
|
541
|
+
rb_define_const(rb_mQuota, "DiskQuota", rb_sDiskQuota);
|
542
|
+
|
543
|
+
rb_define_module_function(rb_mQuota,"quotaon",rb_quota_quotaon,2);
|
544
|
+
rb_define_module_function(rb_mQuota,"quotaoff",rb_quota_quotaoff,1);
|
545
|
+
rb_define_module_function(rb_mQuota,"getquota",rb_quota_getquota,2);
|
546
|
+
rb_define_module_function(rb_mQuota,"setquota",rb_quota_setquota,3);
|
547
|
+
rb_define_module_function(rb_mQuota,"setqlim",rb_quota_setqlim,3);
|
548
|
+
rb_define_module_function(rb_mQuota,"sync",rb_quota_sync,1);
|
549
|
+
};
|
data/test.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# this script is intended to be run by root on the solaris.
|
3
|
+
|
4
|
+
require 'quota'
|
5
|
+
require 'etc'
|
6
|
+
|
7
|
+
# edit for your OS
|
8
|
+
case `uname -s`
|
9
|
+
when /^Linux/
|
10
|
+
$DEV = "/dev/hda9"
|
11
|
+
$QUOTAS = "/mnt/hda9/aquota.user"
|
12
|
+
when /^SunOS/
|
13
|
+
$DEV = "/quotas"
|
14
|
+
$QUOTAS = "/quotas"
|
15
|
+
when /BSD/
|
16
|
+
$DEV = "/mnt/test"
|
17
|
+
$QUOTAS = "/mnt/test/quota.user"
|
18
|
+
end
|
19
|
+
|
20
|
+
print("user id: ")
|
21
|
+
uid = gets.chop
|
22
|
+
if( uid =~ /\d+/ )
|
23
|
+
$USER = Etc.getpwuid(uid).name
|
24
|
+
$UID = uid.to_i
|
25
|
+
else
|
26
|
+
$USER = uid
|
27
|
+
$UID = Etc.getpwnam(uid).uid
|
28
|
+
end
|
29
|
+
print("uid = #{$USER}(#{$UID})\n")
|
30
|
+
|
31
|
+
begin
|
32
|
+
Quota.quotaon($DEV, $QUOTAS)
|
33
|
+
rescue Errno::EBUSY
|
34
|
+
Quota.quotaoff($DEV)
|
35
|
+
Quota.quotaon($DEV, $QUOTAS)
|
36
|
+
end
|
37
|
+
|
38
|
+
begin
|
39
|
+
dq = Quota.getquota($DEV, $UID)
|
40
|
+
rescue Errno::ESRCH
|
41
|
+
dq = Quota::DiskQuota.new
|
42
|
+
end
|
43
|
+
|
44
|
+
print("quota = #{dq.inspect}\n")
|
45
|
+
print("softlimit: ")
|
46
|
+
softlimit = gets.to_i
|
47
|
+
|
48
|
+
dq.bsoftlimit = softlimit # 1block = 1024byte (SunOS 5.6, edquota(1M))
|
49
|
+
Quota.setquota($DEV, $UID, dq)
|
50
|
+
|
51
|
+
other = Quota.getquota($DEV, $UID)
|
52
|
+
print("quota = #{dq.inspect}\n")
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-quota
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 7
|
8
|
+
- 0
|
9
|
+
version: 0.7.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Takaaki Tateishi, Alex Beregszaszi
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2012-04-25 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Ruby-quota is a Ruby extension providing access to filesystem quota. Supported systems Linux, FreeBSD, NetBSD, Dragonfly BSD, Solaris and Mac OS X.
|
22
|
+
email: ttate@jaist.ac.jp
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions:
|
26
|
+
- extconf.rb
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- COPYING
|
31
|
+
- README
|
32
|
+
- MANIFEST
|
33
|
+
- ChangeLog
|
34
|
+
- test.rb
|
35
|
+
- extconf.rb
|
36
|
+
- quota.c
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/axic/ruby-quota
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
segments:
|
51
|
+
- 0
|
52
|
+
version: "0"
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.3.6
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Ruby-quota is a Ruby extension providing access to filesystem quota.
|
67
|
+
test_files: []
|
68
|
+
|