ruby-quota 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|