Project.xs revision 7c478bd95313f5f23a4c958a745db2134aa03244
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * CDDL HEADER START
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * The contents of this file are subject to the terms of the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Common Development and Distribution License, Version 1.0 only
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * (the "License"). You may not use this file except in compliance
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * with the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * or http://www.opensolaris.org/os/licensing.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * See the License for the specific language governing permissions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and limitations under the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * When distributing Covered Code, include this CDDL HEADER in each
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If applicable, add the following below this CDDL HEADER, with the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fields enclosed by brackets "[]" replaced with your own identifying
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * information: Portions Copyright [yyyy] [name of copyright owner]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * CDDL HEADER END
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Use is subject to license terms.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Project.xs contains XS wrappers for the project database maniplulation
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * functions as provided by libproject and described in getprojent(3EXACCT).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma ident "%Z%%M% %I% %E% SMI"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Solaris includes. */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <project.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <pool.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <rctl.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <stdio.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Perl includes. */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "EXTERN.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "perl.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "XSUB.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Convert and save a struct project on the perl XS return stack.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * In a void context it returns nothing, in a scalar context it returns just
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the name of the project and in a list context it returns a 6-element list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * consisting of (name, projid, comment, users, groups, attr), where users and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * groups are references to arrays containing the appropriate lists.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpushret_project(const struct project *proj)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin AV *ary;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dSP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (GIMME_V == G_SCALAR) {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin EXTEND(SP, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSHs(sv_2mortal(newSVpv(proj->pj_name, 0)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUTBACK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } else if (GIMME_V == G_ARRAY) {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin EXTEND(SP, 6);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSHs(sv_2mortal(newSVpv(proj->pj_name, 0)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSHs(sv_2mortal(newSViv(proj->pj_projid)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSHs(sv_2mortal(newSVpv(proj->pj_comment, 0)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ary = newAV();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (cp = proj->pj_users; *cp != NULL; cp++) {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av_push(ary, newSVpv(*cp, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSHs(sv_2mortal(newRV_noinc((SV *)ary)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ary = newAV();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (cp = proj->pj_groups; *cp != NULL; cp++) {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av_push(ary, newSVpv(*cp, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSHs(sv_2mortal(newRV_noinc((SV *)ary)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSHs(sv_2mortal(newSVpv(proj->pj_attr, 0)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUTBACK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (6);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } else {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpwalk_cb(const projid_t project, void *walk_data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int *nitemsp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dSP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nitemsp = (int *) walk_data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin EXTEND(SP, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSHs(sv_2mortal(newSViv(project)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*nitemsp)++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUTBACK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The XS code exported to perl is below here. Note that the XS preprocessor
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * has its own commenting syntax, so all comments from this point on are in
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * that form. Note also that the PUTBACK; lines are necessary to synchronise
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the local and global views of the perl stack before calling pushret_project,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * as the code generated by the perl XS compiler twiddles with the stack on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * entry to an XSUB.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinMODULE = Sun::Solaris::Project PACKAGE = Sun::Solaris::Project
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPROTOTYPES: ENABLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin # Define any constants that need to be exported. By doing it this way we can
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin # avoid the overhead of using the DynaLoader package, and in addition constants
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin # defined using this mechanism are eligible for inlining by the perl
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin # interpreter at compile time.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinBOOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin HV *stash;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buf[128];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stash = gv_stashpv("Sun::Solaris::Project", TRUE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "MAXPROJID", newSViv(MAXPROJID));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "PROJNAME_MAX", newSViv(PROJNAME_MAX));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "PROJF_PATH",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSVpv(PROJF_PATH, sizeof (PROJF_PATH) - 1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "PROJECT_BUFSZ", newSViv(PROJECT_BUFSZ));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "SETPROJ_ERR_TASK", newSViv(SETPROJ_ERR_TASK));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "SETPROJ_ERR_POOL", newSViv(SETPROJ_ERR_POOL));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_NOBASIC",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_NOBASIC));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_LOWERABLE",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_LOWERABLE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_DENY_ALWAYS",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_DENY_ALWAYS));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_DENY_NEVER",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_DENY_NEVER));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_FILE_SIZE",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_FILE_SIZE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_CPU_TIME",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_CPU_TIME));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_SIGNAL_NEVER",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_SIGNAL_NEVER));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_INFINITE",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_INFINITE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_UNOBSERVABLE",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_UNOBSERVABLE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_BYTES",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_BYTES));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_SECONDS",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_SECONDS));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_GLOBAL_COUNT",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSViv(RCTL_GLOBAL_COUNT));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sprintf(buf, "%llu", UINT64_MAX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newCONSTSUB(stash, "RCTL_MAX_VALUE",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newSVpv(buf, strlen(buf)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinprojid_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chingetprojid()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsetproject(name, user_name, flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *user_name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin uint_t flags
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinactiveprojects()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPREINIT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nitems;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPPCODE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUTBACK;
nitems = 0;
project_walk(&pwalk_cb, (void*)&nitems);
XSRETURN(nitems);
void
getprojent()
PREINIT:
struct project proj, *projp;
char buf[PROJECT_BUFSZ];
PPCODE:
PUTBACK;
if (projp = getprojent(&proj, buf, sizeof (buf))) {
XSRETURN(pushret_project(projp));
} else {
XSRETURN_EMPTY;
}
void
setprojent()
void
endprojent()
void
getprojbyname(name)
char *name
PREINIT:
struct project proj, *projp;
char buf[PROJECT_BUFSZ];
PPCODE:
PUTBACK;
if (projp = getprojbyname(name, &proj, buf, sizeof (buf))) {
XSRETURN(pushret_project(projp));
} else {
XSRETURN_EMPTY;
}
void
getprojbyid(id)
projid_t id
PREINIT:
struct project proj, *projp;
char buf[PROJECT_BUFSZ];
PPCODE:
PUTBACK;
if (projp = getprojbyid(id, &proj, buf, sizeof (buf))) {
XSRETURN(pushret_project(projp));
} else {
XSRETURN_EMPTY;
}
void
getdefaultproj(user)
char *user
PREINIT:
struct project proj, *projp;
char buf[PROJECT_BUFSZ];
PPCODE:
PUTBACK;
if (projp = getdefaultproj(user, &proj, buf, sizeof (buf))) {
XSRETURN(pushret_project(projp));
} else {
XSRETURN_EMPTY;
}
void
fgetprojent(fh)
FILE *fh
PREINIT:
struct project proj, *projp;
char buf[PROJECT_BUFSZ];
PPCODE:
PUTBACK;
if (projp = fgetprojent(fh, &proj, buf, sizeof (buf))) {
XSRETURN(pushret_project(projp));
} else {
XSRETURN_EMPTY;
}
bool
inproj(user, proj)
char *user
char *proj
PREINIT:
char buf[PROJECT_BUFSZ];
CODE:
RETVAL = inproj(user, proj, buf, sizeof (buf));
int
getprojidbyname(proj)
char *proj
PREINIT:
int id;
PPCODE:
if ((id = getprojidbyname(proj)) == -1) {
XSRETURN_UNDEF;
} else {
XSRETURN_IV(id);
}
# rctl_get_info(name)
#
# For the given rctl name, returns the list
# ($max, $flags), where $max is the integer value
# of the system rctl, and $flags are the rctl's
# global flags, as returned by rctlblk_get_global_flags
#
# This function is private to Project.pm
void
rctl_get_info(name)
char *name
PREINIT:
rctlblk_t *blk1 = NULL;
rctlblk_t *blk2 = NULL;
rctlblk_t *tmp = NULL;
rctl_priv_t priv;
rctl_qty_t value;
int flags;
int ret;
int err = 0;
char string[24]; /* 24 will always hold a uint64_t */
PPCODE:
Newc(0, blk1, rctlblk_size(), char, rctlblk_t);
if (blk1 == NULL) {
err = 1;
goto out;
}
Newc(1, blk2, rctlblk_size(), char, rctlblk_t);
if (blk2 == NULL) {
err = 1;
goto out;
}
ret = getrctl(name, NULL, blk1, RCTL_FIRST);
if (ret != 0) {
err = 1;
goto out;
}
priv = rctlblk_get_privilege(blk1);
while (priv != RCPRIV_SYSTEM) {
tmp = blk2;
blk2 = blk1;
blk1 = tmp;
ret = getrctl(name, blk2, blk1, RCTL_NEXT);
if (ret != 0) {
err = 1;
goto out;
}
priv = rctlblk_get_privilege(blk1);
}
value = rctlblk_get_value(blk1);
flags = rctlblk_get_global_flags(blk1);
ret = sprintf(string, "%llu", value);
if (ret <= 0) {
err = 1;
}
out:
if (blk1)
Safefree(blk1);
if (blk2)
Safefree(blk2);
if (err)
XSRETURN(0);
XPUSHs(sv_2mortal(newSVpv(string, 0)));
XPUSHs(sv_2mortal(newSViv(flags)));
XSRETURN(2);
#
# pool_exists(name)
#
# Returns 0 a pool with the given name exists on the current system.
# Returns 1 if pools are disabled or the pool does not exist
#
# Used internally by project.pm to validate the project.pool attribute
#
# This function is private to Project.pm
void
pool_exists(name)
char *name
PREINIT:
pool_conf_t *conf;
pool_t *pool;
PPCODE:
conf = pool_conf_alloc();
if (conf == NULL) {
XSRETURN_IV(1);
}
if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY)) {
pool_conf_free(conf);
XSRETURN_IV(1);
}
pool = pool_get_pool(conf, name);
if (pool == NULL) {
pool_conf_close(conf);
pool_conf_free(conf);
XSRETURN_IV(1);
}
pool_conf_close(conf);
pool_conf_free(conf);
XSRETURN_IV(0);