Make it build in userlevel and hook it in.
This commit is contained in:
parent
89dd9c69f6
commit
2d9ddf6e73
|
@ -1,9 +1,9 @@
|
|||
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
# $NetBSD: Makefile,v 1.3 2011/03/25 10:30:35 bouyer Exp $
|
||||
# $NetBSD: Makefile,v 1.4 2012/01/30 19:28:11 dholland Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
PROG= quotactl
|
||||
SRCS= quotactl.c
|
||||
SRCS= quotactl.c proplib-interpreter.c
|
||||
MAN= quotactl.8
|
||||
|
||||
DPADD= ${LIBQUOTA} ${LIBRPCSVC} ${LIBPROP}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: proplib-interpreter.c,v 1.1 2012/01/30 19:23:49 dholland Exp $ */
|
||||
/* $NetBSD: proplib-interpreter.c,v 1.2 2012/01/30 19:28:11 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
|
@ -84,42 +84,40 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: proplib-interpreter.c,v 1.1 2012/01/30 19:23:49 dholland Exp $");
|
||||
__RCSID("$NetBSD: proplib-interpreter.c,v 1.2 2012/01/30 19:28:11 dholland Exp $");
|
||||
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/quota.h>
|
||||
#include <sys/quotactl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <quota.h>
|
||||
#include <quota/quotaprop.h>
|
||||
|
||||
#include "proplib-interpreter.h"
|
||||
|
||||
static int
|
||||
vfs_quotactl_getversion(struct mount *mp,
|
||||
vfs_quotactl_getversion(struct quotahandle *qh,
|
||||
prop_dictionary_t cmddict, int q2type,
|
||||
prop_array_t datas)
|
||||
{
|
||||
prop_array_t replies;
|
||||
prop_dictionary_t data;
|
||||
struct quotastat stat;
|
||||
unsigned restrictions;
|
||||
int q2version;
|
||||
struct vfs_quotactl_args args;
|
||||
int error;
|
||||
|
||||
KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
KASSERT(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
assert(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
assert(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
|
||||
args.qc_op = QUOTACTL_STAT;
|
||||
args.u.stat.qc_ret = &stat;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
restrictions = quota_getrestrictions(qh);
|
||||
|
||||
/*
|
||||
* Set q2version based on the stat results. Currently there
|
||||
* are two valid values for q2version, 1 and 2, which we pick
|
||||
* based on whether quotacheck is required.
|
||||
*/
|
||||
if (stat.qs_restrictions & QUOTA_RESTRICT_NEEDSQUOTACHECK) {
|
||||
if (restrictions & QUOTA_RESTRICT_NEEDSQUOTACHECK) {
|
||||
q2version = 1;
|
||||
} else {
|
||||
q2version = 2;
|
||||
|
@ -152,20 +150,19 @@ vfs_quotactl_getversion(struct mount *mp,
|
|||
return ENOMEM;
|
||||
}
|
||||
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vfs_quotactl_quotaon(struct mount *mp,
|
||||
vfs_quotactl_quotaon(struct quotahandle *qh,
|
||||
prop_dictionary_t cmddict, int q2type,
|
||||
prop_array_t datas)
|
||||
{
|
||||
prop_dictionary_t data;
|
||||
const char *qfile;
|
||||
struct vfs_quotactl_args args;
|
||||
|
||||
KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
KASSERT(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
assert(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
assert(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
|
||||
if (prop_array_count(datas) != 1)
|
||||
return EINVAL;
|
||||
|
@ -177,28 +174,30 @@ vfs_quotactl_quotaon(struct mount *mp,
|
|||
&qfile))
|
||||
return EINVAL;
|
||||
|
||||
args.qc_op = QUOTACTL_QUOTAON;
|
||||
args.u.quotaon.qc_idtype = q2type;
|
||||
args.u.quotaon.qc_quotafile = qfile;
|
||||
return VFS_QUOTACTL(mp, &args);
|
||||
/* libquota knows the filename; cannot set it from here */
|
||||
(void)qfile;
|
||||
|
||||
if (quota_quotaon(qh, q2type)) {
|
||||
return errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vfs_quotactl_quotaoff(struct mount *mp,
|
||||
vfs_quotactl_quotaoff(struct quotahandle *qh,
|
||||
prop_dictionary_t cmddict, int q2type,
|
||||
prop_array_t datas)
|
||||
{
|
||||
struct vfs_quotactl_args args;
|
||||
|
||||
KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
KASSERT(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
assert(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
assert(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
|
||||
if (prop_array_count(datas) != 0)
|
||||
return EINVAL;
|
||||
|
||||
args.qc_op = QUOTACTL_QUOTAOFF;
|
||||
args.u.quotaoff.qc_idtype = q2type;
|
||||
return VFS_QUOTACTL(mp, &args);
|
||||
if (quota_quotaoff(qh, q2type)) {
|
||||
return errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -238,7 +237,7 @@ vfs_quotactl_get_addreply(const struct quotakey *qk,
|
|||
}
|
||||
|
||||
static int
|
||||
vfs_quotactl_get(struct mount *mp,
|
||||
vfs_quotactl_get(struct quotahandle *qh,
|
||||
prop_dictionary_t cmddict, int idtype,
|
||||
prop_array_t datas)
|
||||
{
|
||||
|
@ -247,13 +246,12 @@ vfs_quotactl_get(struct mount *mp,
|
|||
prop_array_t replies;
|
||||
uint32_t id;
|
||||
const char *idstr;
|
||||
struct vfs_quotactl_args args;
|
||||
struct quotakey qk;
|
||||
struct quotaval blocks, files;
|
||||
int error;
|
||||
|
||||
KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
KASSERT(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
assert(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
assert(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
|
||||
replies = prop_array_create();
|
||||
if (replies == NULL) {
|
||||
|
@ -284,34 +282,32 @@ vfs_quotactl_get(struct mount *mp,
|
|||
|
||||
qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
|
||||
|
||||
args.qc_op = QUOTACTL_GET;
|
||||
args.u.get.qc_key = &qk;
|
||||
args.u.get.qc_ret = &blocks;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
if (error == EPERM) {
|
||||
/* XXX does this make sense? */
|
||||
continue;
|
||||
} else if (error == ENOENT) {
|
||||
/* XXX does *this* make sense? */
|
||||
continue;
|
||||
} else if (error) {
|
||||
goto fail;
|
||||
if (quota_get(qh, &qk, &blocks)) {
|
||||
if (errno == EPERM) {
|
||||
/* XXX does this make sense? */
|
||||
continue;
|
||||
} else if (errno == ENOENT) {
|
||||
/* XXX does *this* make sense? */
|
||||
continue;
|
||||
} else {
|
||||
error = errno;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
qk.qk_objtype = QUOTA_OBJTYPE_FILES;
|
||||
|
||||
args.qc_op = QUOTACTL_GET;
|
||||
args.u.get.qc_key = &qk;
|
||||
args.u.get.qc_ret = &files;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
if (error == EPERM) {
|
||||
/* XXX does this make sense? */
|
||||
continue;
|
||||
} else if (error == ENOENT) {
|
||||
/* XXX does *this* make sense? */
|
||||
continue;
|
||||
} else if (error) {
|
||||
goto fail;
|
||||
if (quota_get(qh, &qk, &files)) {
|
||||
if (errno == EPERM) {
|
||||
/* XXX does this make sense? */
|
||||
continue;
|
||||
} else if (errno == ENOENT) {
|
||||
/* XXX does *this* make sense? */
|
||||
continue;
|
||||
} else {
|
||||
error = errno;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
error = vfs_quotactl_get_addreply(&qk, &blocks, &files,
|
||||
|
@ -386,7 +382,7 @@ vfs_quotactl_put_extractinfo(prop_dictionary_t data,
|
|||
}
|
||||
|
||||
static int
|
||||
vfs_quotactl_put(struct mount *mp,
|
||||
vfs_quotactl_put(struct quotahandle *qh,
|
||||
prop_dictionary_t cmddict, int q2type,
|
||||
prop_array_t datas)
|
||||
{
|
||||
|
@ -398,11 +394,10 @@ vfs_quotactl_put(struct mount *mp,
|
|||
const char *idstr;
|
||||
struct quotakey qk;
|
||||
struct quotaval blocks, files;
|
||||
struct vfs_quotactl_args args;
|
||||
int error;
|
||||
|
||||
KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
KASSERT(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
assert(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
assert(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
|
||||
replies = prop_array_create();
|
||||
if (replies == NULL)
|
||||
|
@ -416,7 +411,7 @@ vfs_quotactl_put(struct mount *mp,
|
|||
|
||||
while ((data = prop_object_iterator_next(iter)) != NULL) {
|
||||
|
||||
KASSERT(prop_object_type(data) == PROP_TYPE_DICTIONARY);
|
||||
assert(prop_object_type(data) == PROP_TYPE_DICTIONARY);
|
||||
|
||||
if (!prop_dictionary_get_uint32(data, "id", &id)) {
|
||||
if (!prop_dictionary_get_cstring_nocopy(data, "id",
|
||||
|
@ -439,11 +434,8 @@ vfs_quotactl_put(struct mount *mp,
|
|||
qk.qk_id = defaultq ? QUOTA_DEFAULTID : id;
|
||||
qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
|
||||
|
||||
args.qc_op = QUOTACTL_PUT;
|
||||
args.u.put.qc_key = &qk;
|
||||
args.u.put.qc_val = &blocks;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
if (error) {
|
||||
if (quota_put(qh, &qk, &blocks)) {
|
||||
error = errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -451,11 +443,8 @@ vfs_quotactl_put(struct mount *mp,
|
|||
qk.qk_id = defaultq ? QUOTA_DEFAULTID : id;
|
||||
qk.qk_objtype = QUOTA_OBJTYPE_FILES;
|
||||
|
||||
args.qc_op = QUOTACTL_PUT;
|
||||
args.u.put.qc_key = &qk;
|
||||
args.u.put.qc_val = &files;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
if (error) {
|
||||
if (quota_put(qh, &qk, &files)) {
|
||||
error = errno;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -554,17 +543,17 @@ vfs_quotactl_getall_addreply(prop_dictionary_t thisreply,
|
|||
}
|
||||
|
||||
static int
|
||||
vfs_quotactl_getall(struct mount *mp,
|
||||
vfs_quotactl_getall(struct quotahandle *qh,
|
||||
prop_dictionary_t cmddict, int q2type,
|
||||
prop_array_t datas)
|
||||
{
|
||||
struct quotakcursor cursor;
|
||||
struct quotacursor *cursor;
|
||||
struct quotakey *keys;
|
||||
struct quotaval *vals;
|
||||
unsigned loopmax = 8;
|
||||
unsigned loopnum;
|
||||
int num;
|
||||
int skipidtype;
|
||||
struct vfs_quotactl_args args;
|
||||
prop_array_t replies;
|
||||
int atend, atzero;
|
||||
struct quotakey *key;
|
||||
|
@ -572,28 +561,31 @@ vfs_quotactl_getall(struct mount *mp,
|
|||
id_t lastid;
|
||||
prop_dictionary_t thisreply;
|
||||
unsigned i;
|
||||
int error, error2;
|
||||
int error;
|
||||
|
||||
KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
assert(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
|
||||
args.qc_op = QUOTACTL_CURSOROPEN;
|
||||
args.u.cursoropen.qc_cursor = &cursor;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
if (error) {
|
||||
return error;
|
||||
cursor = quota_opencursor(qh);
|
||||
if (cursor == NULL) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
keys = kmem_alloc(loopmax * sizeof(keys[0]), KM_SLEEP);
|
||||
vals = kmem_alloc(loopmax * sizeof(vals[0]), KM_SLEEP);
|
||||
keys = malloc(loopmax * sizeof(keys[0]));
|
||||
if (keys == NULL) {
|
||||
quotacursor_close(cursor);
|
||||
return ENOMEM;
|
||||
}
|
||||
vals = malloc(loopmax * sizeof(vals[0]));
|
||||
if (vals == NULL) {
|
||||
free(keys);
|
||||
quotacursor_close(cursor);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
skipidtype = (q2type == QUOTA_IDTYPE_USER ?
|
||||
QUOTA_IDTYPE_GROUP : QUOTA_IDTYPE_USER);
|
||||
args.qc_op = QUOTACTL_CURSORSKIPIDTYPE;
|
||||
args.u.cursorskipidtype.qc_cursor = &cursor;
|
||||
args.u.cursorskipidtype.qc_idtype = skipidtype;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
quotacursor_skipidtype(cursor, skipidtype);
|
||||
/* ignore if it fails */
|
||||
(void)error;
|
||||
|
||||
replies = prop_array_create();
|
||||
if (replies == NULL) {
|
||||
|
@ -606,43 +598,31 @@ vfs_quotactl_getall(struct mount *mp,
|
|||
atzero = 0;
|
||||
|
||||
while (1) {
|
||||
args.qc_op = QUOTACTL_CURSORATEND;
|
||||
args.u.cursoratend.qc_cursor = &cursor;
|
||||
args.u.cursoratend.qc_ret = &atend;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
if (error) {
|
||||
goto err;
|
||||
}
|
||||
atend = quotacursor_atend(cursor);
|
||||
if (atend) {
|
||||
break;
|
||||
}
|
||||
|
||||
args.qc_op = QUOTACTL_CURSORGET;
|
||||
args.u.cursorget.qc_cursor = &cursor;
|
||||
args.u.cursorget.qc_keys = keys;
|
||||
args.u.cursorget.qc_vals = vals;
|
||||
args.u.cursorget.qc_maxnum = loopmax;
|
||||
args.u.cursorget.qc_ret = &loopnum;
|
||||
num = quotacursor_getn(cursor, keys, vals, loopmax);
|
||||
if (num < 0) {
|
||||
error = errno;
|
||||
} else {
|
||||
error = 0;
|
||||
loopnum = num;
|
||||
}
|
||||
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
if (error == EDEADLK) {
|
||||
/*
|
||||
* transaction abort, start over
|
||||
*/
|
||||
|
||||
args.qc_op = QUOTACTL_CURSORREWIND;
|
||||
args.u.cursorrewind.qc_cursor = &cursor;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
if (error) {
|
||||
if (quotacursor_rewind(cursor)) {
|
||||
error = errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
args.qc_op = QUOTACTL_CURSORSKIPIDTYPE;
|
||||
args.u.cursorskipidtype.qc_cursor = &cursor;
|
||||
args.u.cursorskipidtype.qc_idtype = skipidtype;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
quotacursor_skipidtype(cursor, skipidtype);
|
||||
/* ignore if it fails */
|
||||
(void)error;
|
||||
|
||||
prop_object_release(replies);
|
||||
replies = prop_array_create();
|
||||
|
@ -670,7 +650,7 @@ vfs_quotactl_getall(struct mount *mp,
|
|||
* twice, warn and assume end of iteration.
|
||||
*/
|
||||
if (atzero) {
|
||||
printf("vfs_quotactl: zero items returned\n");
|
||||
warnx("zero items returned");
|
||||
break;
|
||||
}
|
||||
atzero = 1;
|
||||
|
@ -725,26 +705,23 @@ vfs_quotactl_getall(struct mount *mp,
|
|||
error = 0;
|
||||
|
||||
err:
|
||||
kmem_free(keys, loopmax * sizeof(keys[0]));
|
||||
kmem_free(vals, loopmax * sizeof(vals[0]));
|
||||
free(keys);
|
||||
free(vals);
|
||||
|
||||
if (replies != NULL) {
|
||||
prop_object_release(replies);
|
||||
}
|
||||
|
||||
args.qc_op = QUOTACTL_CURSORCLOSE;
|
||||
args.u.cursorclose.qc_cursor = &cursor;
|
||||
error2 = VFS_QUOTACTL(mp, &args);
|
||||
quotacursor_close(cursor);
|
||||
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
error = error2;
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vfs_quotactl_clear(struct mount *mp,
|
||||
vfs_quotactl_clear(struct quotahandle *qh,
|
||||
prop_dictionary_t cmddict, int q2type,
|
||||
prop_array_t datas)
|
||||
{
|
||||
|
@ -755,11 +732,10 @@ vfs_quotactl_clear(struct mount *mp,
|
|||
int defaultq;
|
||||
const char *idstr;
|
||||
struct quotakey qk;
|
||||
struct vfs_quotactl_args args;
|
||||
int error;
|
||||
|
||||
KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
KASSERT(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
assert(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
|
||||
assert(prop_object_type(datas) == PROP_TYPE_ARRAY);
|
||||
|
||||
replies = prop_array_create();
|
||||
if (replies == NULL)
|
||||
|
@ -788,10 +764,8 @@ vfs_quotactl_clear(struct mount *mp,
|
|||
qk.qk_id = defaultq ? QUOTA_DEFAULTID : id;
|
||||
qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
|
||||
|
||||
args.qc_op = QUOTACTL_DELETE;
|
||||
args.u.delete.qc_key = &qk;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
if (error) {
|
||||
if (quota_delete(qh, &qk)) {
|
||||
error = errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -799,10 +773,8 @@ vfs_quotactl_clear(struct mount *mp,
|
|||
qk.qk_id = defaultq ? QUOTA_DEFAULTID : id;
|
||||
qk.qk_objtype = QUOTA_OBJTYPE_FILES;
|
||||
|
||||
args.qc_op = QUOTACTL_DELETE;
|
||||
args.u.delete.qc_key = &qk;
|
||||
error = VFS_QUOTACTL(mp, &args);
|
||||
if (error) {
|
||||
if (quota_delete(qh, &qk)) {
|
||||
error = errno;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -821,7 +793,7 @@ err:
|
|||
}
|
||||
|
||||
static int
|
||||
vfs_quotactl_cmd(struct mount *mp, prop_dictionary_t cmddict)
|
||||
vfs_quotactl_cmd(struct quotahandle *qh, prop_dictionary_t cmddict)
|
||||
{
|
||||
int error;
|
||||
const char *cmd, *type;
|
||||
|
@ -850,19 +822,19 @@ vfs_quotactl_cmd(struct mount *mp, prop_dictionary_t cmddict)
|
|||
prop_dictionary_remove(cmddict, "data"); /* prepare for return */
|
||||
|
||||
if (strcmp(cmd, "get version") == 0) {
|
||||
error = vfs_quotactl_getversion(mp, cmddict, q2type, datas);
|
||||
error = vfs_quotactl_getversion(qh, cmddict, q2type, datas);
|
||||
} else if (strcmp(cmd, "quotaon") == 0) {
|
||||
error = vfs_quotactl_quotaon(mp, cmddict, q2type, datas);
|
||||
error = vfs_quotactl_quotaon(qh, cmddict, q2type, datas);
|
||||
} else if (strcmp(cmd, "quotaoff") == 0) {
|
||||
error = vfs_quotactl_quotaoff(mp, cmddict, q2type, datas);
|
||||
error = vfs_quotactl_quotaoff(qh, cmddict, q2type, datas);
|
||||
} else if (strcmp(cmd, "get") == 0) {
|
||||
error = vfs_quotactl_get(mp, cmddict, q2type, datas);
|
||||
error = vfs_quotactl_get(qh, cmddict, q2type, datas);
|
||||
} else if (strcmp(cmd, "set") == 0) {
|
||||
error = vfs_quotactl_put(mp, cmddict, q2type, datas);
|
||||
error = vfs_quotactl_put(qh, cmddict, q2type, datas);
|
||||
} else if (strcmp(cmd, "getall") == 0) {
|
||||
error = vfs_quotactl_getall(mp, cmddict, q2type, datas);
|
||||
error = vfs_quotactl_getall(qh, cmddict, q2type, datas);
|
||||
} else if (strcmp(cmd, "clear") == 0) {
|
||||
error = vfs_quotactl_clear(mp, cmddict, q2type, datas);
|
||||
error = vfs_quotactl_clear(qh, cmddict, q2type, datas);
|
||||
} else {
|
||||
/* XXX this a bad errno for this case */
|
||||
error = EOPNOTSUPP;
|
||||
|
@ -876,7 +848,7 @@ vfs_quotactl_cmd(struct mount *mp, prop_dictionary_t cmddict)
|
|||
}
|
||||
|
||||
int
|
||||
vfs_quotactl(struct mount *mp, prop_dictionary_t dict)
|
||||
proplib_quotactl(struct quotahandle *qh, prop_dictionary_t dict)
|
||||
{
|
||||
prop_dictionary_t cmddict;
|
||||
prop_array_t commands;
|
||||
|
@ -898,7 +870,7 @@ vfs_quotactl(struct mount *mp, prop_dictionary_t dict)
|
|||
/* XXX shouldn't this be an error? */
|
||||
continue;
|
||||
}
|
||||
error = vfs_quotactl_cmd(mp, cmddict);
|
||||
error = vfs_quotactl_cmd(qh, cmddict);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
int proplib_quotactl(struct quotahandle *qh, prop_dictionary_t dict);
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: quotactl.c,v 1.5 2011/08/31 13:32:40 joerg Exp $ */
|
||||
/* $NetBSD: quotactl.c,v 1.6 2012/01/30 19:28:11 dholland Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2011 Manuel Bouyer
|
||||
* All rights reserved.
|
||||
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: quotactl.c,v 1.5 2011/08/31 13:32:40 joerg Exp $");
|
||||
__RCSID("$NetBSD: quotactl.c,v 1.6 2012/01/30 19:28:11 dholland Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
|
@ -37,7 +37,7 @@ __RCSID("$NetBSD: quotactl.c,v 1.5 2011/08/31 13:32:40 joerg Exp $");
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <prop/proplib.h>
|
||||
#include <sys/quota.h>
|
||||
#include <quota.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
|
@ -48,6 +48,8 @@ __RCSID("$NetBSD: quotactl.c,v 1.5 2011/08/31 13:32:40 joerg Exp $");
|
|||
|
||||
#include <quota/quotaprop.h>
|
||||
|
||||
#include "proplib-interpreter.h"
|
||||
|
||||
__dead static void usage(void);
|
||||
|
||||
#define READ_SIZE 4096
|
||||
|
@ -62,11 +64,14 @@ main(int argc, char * const argv[])
|
|||
char *plist, *p;
|
||||
size_t plistsize;
|
||||
int status = 0, error;
|
||||
#if 0
|
||||
struct plistref pref;
|
||||
#endif
|
||||
prop_dictionary_t qdict, cmd;
|
||||
prop_array_t cmds;
|
||||
prop_object_iterator_t cmditer;
|
||||
const char *mp, *xmlfile = NULL;
|
||||
struct quotahandle *qh;
|
||||
|
||||
while ((ch = getopt(argc, argv, "Dx")) != -1) {
|
||||
switch (ch) {
|
||||
|
@ -95,6 +100,10 @@ main(int argc, char * const argv[])
|
|||
err(1, "%s", xmlfile);
|
||||
}
|
||||
mp = argv[0];
|
||||
qh = quota_open(mp);
|
||||
if (qh == NULL) {
|
||||
err(1, "%s: quota_open", mp);
|
||||
}
|
||||
|
||||
plist = malloc(READ_SIZE);
|
||||
if (plist == NULL)
|
||||
|
@ -114,25 +123,32 @@ main(int argc, char * const argv[])
|
|||
qdict = prop_dictionary_internalize(plist);
|
||||
if (qdict == NULL)
|
||||
err(1, "can't parse %s", xmlfile);
|
||||
free(plist);
|
||||
if (!prop_dictionary_send_syscall(qdict, &pref))
|
||||
err(1, "can't externalize to syscall");
|
||||
if (Dflag) {
|
||||
plist = prop_dictionary_externalize(qdict);
|
||||
fprintf(stderr, "message to kernel:\n%s\n", plist);
|
||||
fprintf(stderr, "message to interpreter:\n%s\n", plist);
|
||||
free(plist);
|
||||
}
|
||||
free(plist);
|
||||
#if 0
|
||||
if (!prop_dictionary_send_syscall(qdict, &pref))
|
||||
err(1, "can't externalize to syscall");
|
||||
prop_object_release(qdict);
|
||||
if (quotactl(mp, &pref) != 0)
|
||||
err(1, "quotactl failed");
|
||||
|
||||
if ((error = prop_dictionary_recv_syscall(&pref, &qdict)) != 0) {
|
||||
errx(1, "error parsing reply from kernel: %s\n",
|
||||
errx(1, "error parsing reply from kernel: %s",
|
||||
strerror(error));
|
||||
}
|
||||
#else
|
||||
error = proplib_quotactl(qh, qdict);
|
||||
if (error) {
|
||||
errx(1, "quotactl failed: %s", strerror(error));
|
||||
}
|
||||
#endif
|
||||
if (Dflag) {
|
||||
plist = prop_dictionary_externalize(qdict);
|
||||
fprintf(stderr, "reply from kernel:\n%s\n", plist);
|
||||
fprintf(stderr, "reply from interpreter:\n%s\n", plist);
|
||||
free(plist);
|
||||
}
|
||||
if (xflag) {
|
||||
|
@ -145,7 +161,7 @@ main(int argc, char * const argv[])
|
|||
}
|
||||
/* parse the reply, looking for errors */
|
||||
if ((error = quota_get_cmds(qdict, &cmds)) != 0) {
|
||||
errx(1, "error parsing reply from kernel: %s\n",
|
||||
errx(1, "error parsing reply from interpreter: %s\n",
|
||||
strerror(error));
|
||||
}
|
||||
cmditer = prop_array_iterator(cmds);
|
||||
|
@ -167,6 +183,7 @@ main(int argc, char * const argv[])
|
|||
status = 2;
|
||||
}
|
||||
}
|
||||
quota_close(qh);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue