ruby-quota 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (8) hide show
  1. data/COPYING +24 -0
  2. data/ChangeLog +66 -0
  3. data/MANIFEST +7 -0
  4. data/README +48 -0
  5. data/extconf.rb +23 -0
  6. data/quota.c +549 -0
  7. data/test.rb +52 -0
  8. 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
@@ -0,0 +1,7 @@
1
+ COPYING
2
+ MANIFEST
3
+ README
4
+ extconf.rb
5
+ quota.c
6
+ test.rb
7
+ ChangeLog
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
+