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.
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
+