/*
* Copyright (c) 2014 Racktop Systems.
*/
/*
* Project.xs contains XS wrappers for the project database maniplulation
* functions as provided by libproject and described in getprojent(3EXACCT).
*/
/* Solaris includes. */
#include <zone.h>
#include <project.h>
#include <pool.h>
#include <sys/pool_impl.h>
#include <rctl.h>
#include <stdio.h>
/* Perl includes. */
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
/*
* Convert and save a struct project on the perl XS return stack.
* In a void context it returns nothing, in a scalar context it returns just
* the name of the project and in a list context it returns a 6-element list
* consisting of (name, projid, comment, users, groups, attr), where users and
* groups are references to arrays containing the appropriate lists.
*/
static int
{
char **cp;
dSP;
return (1);
}
}
return (6);
} else {
return (0);
}
}
static int
{
int *nitemsp;
dSP;
(*nitemsp)++;
return (0);
}
/*
* The XS code exported to perl is below here. Note that the XS preprocessor
* has its own commenting syntax, so all comments from this point on are in
* that form. Note also that the PUTBACK; lines are necessary to synchronise
* the local and global views of the perl stack before calling pushret_project,
* as the code generated by the perl XS compiler twiddles with the stack on
* entry to an XSUB.
*/
#
#
BOOT:
{
char buf[128];
}
int
const char *name;
const char *user_name
void
int nitems;
nitems = 0;
void
char buf[PROJECT_BUFSZ];
} else {
}
void
void
void
char *name
char buf[PROJECT_BUFSZ];
} else {
}
void
char buf[PROJECT_BUFSZ];
} else {
}
void
char *user
char buf[PROJECT_BUFSZ];
} else {
}
void
char buf[PROJECT_BUFSZ];
} else {
}
bool
char *user
char *proj
char buf[PROJECT_BUFSZ];
CODE:
int
char *proj
int id;
} else {
}
#
# 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 = 0;
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;
pool_status_t status;
int fd;
PPCODE:
/*
* libpool may not be present.
*/
if (getzoneid() != GLOBAL_ZONEID) {
XSRETURN_IV(1);
}
XSRETURN_IV(1);
}
if (ioctl(fd, POOL_STATUSQ, &status) < 0) {
(void) close(fd);
XSRETURN_IV(1);
}
close(fd);
if (status.ps_io_state != 1) {
XSRETURN_IV(1);
}
/*
* If pools are enabled, assume libpool is present.
*/
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);