17c478bd9Sstevel@tonic-gate /*
2c227543fSJohn Sonnenschein  * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
3*c9f77c52SAndy Stormont  * Copyright (c) 2014 Racktop Systems.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate /*
67c478bd9Sstevel@tonic-gate  * Project.xs contains XS wrappers for the project database maniplulation
77c478bd9Sstevel@tonic-gate  * functions as provided by libproject and described in getprojent(3EXACCT).
87c478bd9Sstevel@tonic-gate  */
97c478bd9Sstevel@tonic-gate 
107c478bd9Sstevel@tonic-gate /* Solaris includes. */
1152978630Ssl #include <zone.h>
127c478bd9Sstevel@tonic-gate #include <project.h>
137c478bd9Sstevel@tonic-gate #include <pool.h>
1452978630Ssl #include <sys/pool_impl.h>
157c478bd9Sstevel@tonic-gate #include <rctl.h>
167c478bd9Sstevel@tonic-gate #include <stdio.h>
177c478bd9Sstevel@tonic-gate 
187c478bd9Sstevel@tonic-gate /* Perl includes. */
197c478bd9Sstevel@tonic-gate #include "EXTERN.h"
207c478bd9Sstevel@tonic-gate #include "perl.h"
217c478bd9Sstevel@tonic-gate #include "XSUB.h"
227c478bd9Sstevel@tonic-gate 
237c478bd9Sstevel@tonic-gate /*
247c478bd9Sstevel@tonic-gate  * Convert and save a struct project on the perl XS return stack.
257c478bd9Sstevel@tonic-gate  * In a void context it returns nothing, in a scalar context it returns just
267c478bd9Sstevel@tonic-gate  * the name of the project and in a list context it returns a 6-element list
277c478bd9Sstevel@tonic-gate  * consisting of (name, projid, comment, users, groups, attr), where users and
287c478bd9Sstevel@tonic-gate  * groups are references to arrays containing the appropriate lists.
297c478bd9Sstevel@tonic-gate  */
307c478bd9Sstevel@tonic-gate static int
pushret_project(const struct project * proj)317c478bd9Sstevel@tonic-gate pushret_project(const struct project *proj)
327c478bd9Sstevel@tonic-gate {
337c478bd9Sstevel@tonic-gate 	char	**cp;
347c478bd9Sstevel@tonic-gate 	AV	*ary;
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate 	dSP;
377c478bd9Sstevel@tonic-gate 	if (GIMME_V == G_SCALAR) {
387c478bd9Sstevel@tonic-gate 		EXTEND(SP, 1);
397c478bd9Sstevel@tonic-gate 		PUSHs(sv_2mortal(newSVpv(proj->pj_name, 0)));
407c478bd9Sstevel@tonic-gate 		PUTBACK;
417c478bd9Sstevel@tonic-gate 		return (1);
427c478bd9Sstevel@tonic-gate 	} else if (GIMME_V == G_ARRAY) {
437c478bd9Sstevel@tonic-gate 		EXTEND(SP, 6);
447c478bd9Sstevel@tonic-gate 		PUSHs(sv_2mortal(newSVpv(proj->pj_name, 0)));
457c478bd9Sstevel@tonic-gate 		PUSHs(sv_2mortal(newSViv(proj->pj_projid)));
467c478bd9Sstevel@tonic-gate 		PUSHs(sv_2mortal(newSVpv(proj->pj_comment, 0)));
477c478bd9Sstevel@tonic-gate 		ary = newAV();
487c478bd9Sstevel@tonic-gate 		for (cp = proj->pj_users; *cp != NULL; cp++) {
497c478bd9Sstevel@tonic-gate 			av_push(ary, newSVpv(*cp, 0));
507c478bd9Sstevel@tonic-gate 		}
517c478bd9Sstevel@tonic-gate 		PUSHs(sv_2mortal(newRV_noinc((SV *)ary)));
527c478bd9Sstevel@tonic-gate 		ary = newAV();
537c478bd9Sstevel@tonic-gate 		for (cp = proj->pj_groups; *cp != NULL; cp++) {
547c478bd9Sstevel@tonic-gate 			av_push(ary, newSVpv(*cp, 0));
557c478bd9Sstevel@tonic-gate 		}
567c478bd9Sstevel@tonic-gate 		PUSHs(sv_2mortal(newRV_noinc((SV *)ary)));
577c478bd9Sstevel@tonic-gate 		PUSHs(sv_2mortal(newSVpv(proj->pj_attr, 0)));
587c478bd9Sstevel@tonic-gate 		PUTBACK;
597c478bd9Sstevel@tonic-gate 		return (6);
607c478bd9Sstevel@tonic-gate 	} else {
617c478bd9Sstevel@tonic-gate 		return (0);
627c478bd9Sstevel@tonic-gate 	}
637c478bd9Sstevel@tonic-gate }
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate static int
pwalk_cb(const projid_t project,void * walk_data)667c478bd9Sstevel@tonic-gate pwalk_cb(const projid_t project, void *walk_data)
677c478bd9Sstevel@tonic-gate {
687c478bd9Sstevel@tonic-gate 	int *nitemsp;
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 	dSP;
717c478bd9Sstevel@tonic-gate 	nitemsp = (int *) walk_data;
727c478bd9Sstevel@tonic-gate 	EXTEND(SP, 1);
737c478bd9Sstevel@tonic-gate 	PUSHs(sv_2mortal(newSViv(project)));
747c478bd9Sstevel@tonic-gate 	(*nitemsp)++;
757c478bd9Sstevel@tonic-gate 	PUTBACK;
767c478bd9Sstevel@tonic-gate 	return (0);
777c478bd9Sstevel@tonic-gate }
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate /*
807c478bd9Sstevel@tonic-gate  * The XS code exported to perl is below here.  Note that the XS preprocessor
817c478bd9Sstevel@tonic-gate  * has its own commenting syntax, so all comments from this point on are in
827c478bd9Sstevel@tonic-gate  * that form.  Note also that the PUTBACK; lines are necessary to synchronise
837c478bd9Sstevel@tonic-gate  * the local and global views of the perl stack before calling pushret_project,
847c478bd9Sstevel@tonic-gate  * as the code generated by the perl XS compiler twiddles with the stack on
857c478bd9Sstevel@tonic-gate  * entry to an XSUB.
867c478bd9Sstevel@tonic-gate  */
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate MODULE = Sun::Solaris::Project PACKAGE = Sun::Solaris::Project
897c478bd9Sstevel@tonic-gate PROTOTYPES: ENABLE
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate  #
927c478bd9Sstevel@tonic-gate  # Define any constants that need to be exported.  By doing it this way we can
937c478bd9Sstevel@tonic-gate  # avoid the overhead of using the DynaLoader package, and in addition constants
947c478bd9Sstevel@tonic-gate  # defined using this mechanism are eligible for inlining by the perl
957c478bd9Sstevel@tonic-gate  # interpreter at compile time.
967c478bd9Sstevel@tonic-gate  #
977c478bd9Sstevel@tonic-gate BOOT:
987c478bd9Sstevel@tonic-gate 	{
997c478bd9Sstevel@tonic-gate 	HV *stash;
1007c478bd9Sstevel@tonic-gate 	char buf[128];
1017c478bd9Sstevel@tonic-gate 	stash = gv_stashpv("Sun::Solaris::Project", TRUE);
1027c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "MAXPROJID", newSViv(MAXPROJID));
1037c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "PROJNAME_MAX", newSViv(PROJNAME_MAX));
1047c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "PROJF_PATH",
1057c478bd9Sstevel@tonic-gate 	    newSVpv(PROJF_PATH, sizeof (PROJF_PATH) - 1));
1067c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "PROJECT_BUFSZ", newSViv(PROJECT_BUFSZ));
1077c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "SETPROJ_ERR_TASK", newSViv(SETPROJ_ERR_TASK));
1087c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "SETPROJ_ERR_POOL", newSViv(SETPROJ_ERR_POOL));
1097c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_NOBASIC",
1107c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_NOBASIC));
1117c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_LOWERABLE",
1127c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_LOWERABLE));
1137c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_DENY_ALWAYS",
1147c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_DENY_ALWAYS));
1157c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_DENY_NEVER",
1167c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_DENY_NEVER));
1177c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_FILE_SIZE",
1187c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_FILE_SIZE));
1197c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_CPU_TIME",
1207c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_CPU_TIME));
1217c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_SIGNAL_NEVER",
1227c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_SIGNAL_NEVER));
1237c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_INFINITE",
1247c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_INFINITE));
1257c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_UNOBSERVABLE",
1267c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_UNOBSERVABLE));
1277c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_BYTES",
1287c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_BYTES));
1297c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_SECONDS",
1307c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_SECONDS));
1317c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_GLOBAL_COUNT",
1327c478bd9Sstevel@tonic-gate 		newSViv(RCTL_GLOBAL_COUNT));
1337c478bd9Sstevel@tonic-gate 	sprintf(buf, "%llu", UINT64_MAX);
1347c478bd9Sstevel@tonic-gate 	newCONSTSUB(stash, "RCTL_MAX_VALUE",
1357c478bd9Sstevel@tonic-gate 		newSVpv(buf, strlen(buf)));
1367c478bd9Sstevel@tonic-gate 	}
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate projid_t
1397c478bd9Sstevel@tonic-gate getprojid()
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate int
1427c478bd9Sstevel@tonic-gate setproject(name, user_name, flags)
1437c478bd9Sstevel@tonic-gate 	const char	*name;
1447c478bd9Sstevel@tonic-gate 	const char	*user_name
1457c478bd9Sstevel@tonic-gate 	uint_t		flags
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate void
1487c478bd9Sstevel@tonic-gate activeprojects()
1497c478bd9Sstevel@tonic-gate PREINIT:
1507c478bd9Sstevel@tonic-gate 	int	nitems;
1517c478bd9Sstevel@tonic-gate PPCODE:
1527c478bd9Sstevel@tonic-gate 	PUTBACK;
1537c478bd9Sstevel@tonic-gate 	nitems = 0;
1547c478bd9Sstevel@tonic-gate 	project_walk(&pwalk_cb, (void*)&nitems);
1557c478bd9Sstevel@tonic-gate 	XSRETURN(nitems);
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate void
1587c478bd9Sstevel@tonic-gate getprojent()
1597c478bd9Sstevel@tonic-gate PREINIT:
1607c478bd9Sstevel@tonic-gate 	struct project	proj, *projp;
1617c478bd9Sstevel@tonic-gate 	char		buf[PROJECT_BUFSZ];
1627c478bd9Sstevel@tonic-gate PPCODE:
1637c478bd9Sstevel@tonic-gate 	PUTBACK;
164*c9f77c52SAndy Stormont 	if ((projp = getprojent(&proj, buf, sizeof (buf)))) {
1657c478bd9Sstevel@tonic-gate 		XSRETURN(pushret_project(projp));
1667c478bd9Sstevel@tonic-gate 	} else {
1677c478bd9Sstevel@tonic-gate 		XSRETURN_EMPTY;
1687c478bd9Sstevel@tonic-gate 	}
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate void
1717c478bd9Sstevel@tonic-gate setprojent()
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate void
1747c478bd9Sstevel@tonic-gate endprojent()
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate void
1777c478bd9Sstevel@tonic-gate getprojbyname(name)
1787c478bd9Sstevel@tonic-gate 	char	*name
1797c478bd9Sstevel@tonic-gate PREINIT:
1807c478bd9Sstevel@tonic-gate 	struct project	proj, *projp;
1817c478bd9Sstevel@tonic-gate 	char		buf[PROJECT_BUFSZ];
1827c478bd9Sstevel@tonic-gate PPCODE:
1837c478bd9Sstevel@tonic-gate 	PUTBACK;
184*c9f77c52SAndy Stormont 	if ((projp = getprojbyname(name, &proj, buf, sizeof (buf)))) {
1857c478bd9Sstevel@tonic-gate 		XSRETURN(pushret_project(projp));
1867c478bd9Sstevel@tonic-gate 	} else {
1877c478bd9Sstevel@tonic-gate 		XSRETURN_EMPTY;
1887c478bd9Sstevel@tonic-gate 	}
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate void
1917c478bd9Sstevel@tonic-gate getprojbyid(id)
1927c478bd9Sstevel@tonic-gate 	projid_t	id
1937c478bd9Sstevel@tonic-gate PREINIT:
1947c478bd9Sstevel@tonic-gate 	struct project	proj, *projp;
1957c478bd9Sstevel@tonic-gate 	char		buf[PROJECT_BUFSZ];
1967c478bd9Sstevel@tonic-gate PPCODE:
1977c478bd9Sstevel@tonic-gate 	PUTBACK;
198*c9f77c52SAndy Stormont 	if ((projp = getprojbyid(id, &proj, buf, sizeof (buf)))) {
1997c478bd9Sstevel@tonic-gate 		XSRETURN(pushret_project(projp));
2007c478bd9Sstevel@tonic-gate 	} else {
2017c478bd9Sstevel@tonic-gate 		XSRETURN_EMPTY;
2027c478bd9Sstevel@tonic-gate 	}
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate void
2057c478bd9Sstevel@tonic-gate getdefaultproj(user)
2067c478bd9Sstevel@tonic-gate 	char	*user
2077c478bd9Sstevel@tonic-gate PREINIT:
2087c478bd9Sstevel@tonic-gate 	struct project	proj, *projp;
2097c478bd9Sstevel@tonic-gate 	char		buf[PROJECT_BUFSZ];
2107c478bd9Sstevel@tonic-gate PPCODE:
2117c478bd9Sstevel@tonic-gate 	PUTBACK;
212*c9f77c52SAndy Stormont 	if ((projp = getdefaultproj(user, &proj, buf, sizeof (buf)))) {
2137c478bd9Sstevel@tonic-gate 		XSRETURN(pushret_project(projp));
2147c478bd9Sstevel@tonic-gate 	} else {
2157c478bd9Sstevel@tonic-gate 		XSRETURN_EMPTY;
2167c478bd9Sstevel@tonic-gate 	}
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate void
2197c478bd9Sstevel@tonic-gate fgetprojent(fh)
2207c478bd9Sstevel@tonic-gate 	FILE	*fh
2217c478bd9Sstevel@tonic-gate PREINIT:
2227c478bd9Sstevel@tonic-gate 	struct project	proj, *projp;
2237c478bd9Sstevel@tonic-gate 	char		buf[PROJECT_BUFSZ];
2247c478bd9Sstevel@tonic-gate PPCODE:
2257c478bd9Sstevel@tonic-gate 	PUTBACK;
226*c9f77c52SAndy Stormont 	if ((projp = fgetprojent(fh, &proj, buf, sizeof (buf)))) {
2277c478bd9Sstevel@tonic-gate 		XSRETURN(pushret_project(projp));
2287c478bd9Sstevel@tonic-gate 	} else {
2297c478bd9Sstevel@tonic-gate 		XSRETURN_EMPTY;
2307c478bd9Sstevel@tonic-gate 	}
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate bool
2337c478bd9Sstevel@tonic-gate inproj(user, proj)
2347c478bd9Sstevel@tonic-gate 	char	*user
2357c478bd9Sstevel@tonic-gate 	char	*proj
2367c478bd9Sstevel@tonic-gate PREINIT:
2377c478bd9Sstevel@tonic-gate 	char	buf[PROJECT_BUFSZ];
2387c478bd9Sstevel@tonic-gate CODE:
2397c478bd9Sstevel@tonic-gate 	RETVAL = inproj(user, proj, buf, sizeof (buf));
240*c9f77c52SAndy Stormont OUTPUT:
241*c9f77c52SAndy Stormont 	RETVAL
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate int
2457c478bd9Sstevel@tonic-gate getprojidbyname(proj)
2467c478bd9Sstevel@tonic-gate 	char	*proj
2477c478bd9Sstevel@tonic-gate PREINIT:
2487c478bd9Sstevel@tonic-gate 	int	id;
2497c478bd9Sstevel@tonic-gate PPCODE:
2507c478bd9Sstevel@tonic-gate 	if ((id = getprojidbyname(proj)) == -1) {
2517c478bd9Sstevel@tonic-gate 		XSRETURN_UNDEF;
2527c478bd9Sstevel@tonic-gate 	} else {
2537c478bd9Sstevel@tonic-gate 		XSRETURN_IV(id);
2547c478bd9Sstevel@tonic-gate 	}
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate # rctl_get_info(name)
2587c478bd9Sstevel@tonic-gate #
2597c478bd9Sstevel@tonic-gate # For the given rctl name, returns the list
2607c478bd9Sstevel@tonic-gate # ($max, $flags), where $max is the integer value
2617c478bd9Sstevel@tonic-gate # of the system rctl, and $flags are the rctl's
2627c478bd9Sstevel@tonic-gate # global flags, as returned by rctlblk_get_global_flags
2637c478bd9Sstevel@tonic-gate #
2647c478bd9Sstevel@tonic-gate # This function is private to Project.pm
2657c478bd9Sstevel@tonic-gate void
2667c478bd9Sstevel@tonic-gate rctl_get_info(name)
2677c478bd9Sstevel@tonic-gate 	char	*name
2687c478bd9Sstevel@tonic-gate PREINIT:
2697c478bd9Sstevel@tonic-gate 	rctlblk_t *blk1 = NULL;
2707c478bd9Sstevel@tonic-gate 	rctlblk_t *blk2 = NULL;
2717c478bd9Sstevel@tonic-gate 	rctlblk_t *tmp = NULL;
2727c478bd9Sstevel@tonic-gate 	rctl_priv_t priv;
2737c478bd9Sstevel@tonic-gate 	rctl_qty_t value;
274*c9f77c52SAndy Stormont 	int flags = 0;
2757c478bd9Sstevel@tonic-gate 	int ret;
2767c478bd9Sstevel@tonic-gate 	int err = 0;
2777c478bd9Sstevel@tonic-gate 	char string[24];	/* 24 will always hold a uint64_t */
2787c478bd9Sstevel@tonic-gate PPCODE:
2797c478bd9Sstevel@tonic-gate 	Newc(0, blk1, rctlblk_size(), char, rctlblk_t);
2807c478bd9Sstevel@tonic-gate 	if (blk1 == NULL) {
2817c478bd9Sstevel@tonic-gate 		err = 1;
2827c478bd9Sstevel@tonic-gate 		goto out;
2837c478bd9Sstevel@tonic-gate 	}
2847c478bd9Sstevel@tonic-gate 	Newc(1, blk2, rctlblk_size(), char, rctlblk_t);
2857c478bd9Sstevel@tonic-gate 	if (blk2 == NULL) {
2867c478bd9Sstevel@tonic-gate 		err = 1;
2877c478bd9Sstevel@tonic-gate 		goto out;
2887c478bd9Sstevel@tonic-gate 	}
2897c478bd9Sstevel@tonic-gate 	ret = getrctl(name, NULL, blk1, RCTL_FIRST);
2907c478bd9Sstevel@tonic-gate 	if (ret != 0) {
2917c478bd9Sstevel@tonic-gate 		err = 1;
2927c478bd9Sstevel@tonic-gate 		goto out;
2937c478bd9Sstevel@tonic-gate 	}
2947c478bd9Sstevel@tonic-gate 	priv = rctlblk_get_privilege(blk1);
2957c478bd9Sstevel@tonic-gate 	while (priv != RCPRIV_SYSTEM) {
2967c478bd9Sstevel@tonic-gate 		tmp = blk2;
2977c478bd9Sstevel@tonic-gate 		blk2 = blk1;
2987c478bd9Sstevel@tonic-gate 		blk1 = tmp;
2997c478bd9Sstevel@tonic-gate 		ret = getrctl(name, blk2, blk1, RCTL_NEXT);
3007c478bd9Sstevel@tonic-gate 		if (ret != 0) {
3017c478bd9Sstevel@tonic-gate 			err = 1;
3027c478bd9Sstevel@tonic-gate 			goto out;
3037c478bd9Sstevel@tonic-gate 		}
3047c478bd9Sstevel@tonic-gate 		priv = rctlblk_get_privilege(blk1);
3057c478bd9Sstevel@tonic-gate 	}
3067c478bd9Sstevel@tonic-gate 	value = rctlblk_get_value(blk1);
3077c478bd9Sstevel@tonic-gate 	flags = rctlblk_get_global_flags(blk1);
3087c478bd9Sstevel@tonic-gate 	ret = sprintf(string, "%llu", value);
3097c478bd9Sstevel@tonic-gate 	if (ret <= 0) {
3107c478bd9Sstevel@tonic-gate 		err = 1;
3117c478bd9Sstevel@tonic-gate 	}
3127c478bd9Sstevel@tonic-gate 	out:
3137c478bd9Sstevel@tonic-gate 	if (blk1)
3147c478bd9Sstevel@tonic-gate 		Safefree(blk1);
3157c478bd9Sstevel@tonic-gate 	if (blk2)
3167c478bd9Sstevel@tonic-gate 		Safefree(blk2);
3177c478bd9Sstevel@tonic-gate 	if (err)
3187c478bd9Sstevel@tonic-gate 		XSRETURN(0);
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 	XPUSHs(sv_2mortal(newSVpv(string, 0)));
3217c478bd9Sstevel@tonic-gate 	XPUSHs(sv_2mortal(newSViv(flags)));
3227c478bd9Sstevel@tonic-gate 	XSRETURN(2);
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate #
3257c478bd9Sstevel@tonic-gate # pool_exists(name)
3267c478bd9Sstevel@tonic-gate #
3277c478bd9Sstevel@tonic-gate # Returns 0 a pool with the given name exists on the current system.
3287c478bd9Sstevel@tonic-gate # Returns 1 if pools are disabled or the pool does not exist
3297c478bd9Sstevel@tonic-gate #
3307c478bd9Sstevel@tonic-gate # Used internally by project.pm to validate the project.pool attribute
3317c478bd9Sstevel@tonic-gate #
3327c478bd9Sstevel@tonic-gate # This function is private to Project.pm
3337c478bd9Sstevel@tonic-gate void
3347c478bd9Sstevel@tonic-gate pool_exists(name)
3357c478bd9Sstevel@tonic-gate 	char	*name
3367c478bd9Sstevel@tonic-gate PREINIT:
3377c478bd9Sstevel@tonic-gate 	pool_conf_t *conf;
3387c478bd9Sstevel@tonic-gate 	pool_t *pool;
33952978630Ssl 	pool_status_t status;
34052978630Ssl 	int fd;
3417c478bd9Sstevel@tonic-gate PPCODE:
34252978630Ssl 
34352978630Ssl 	/*
34452978630Ssl 	 * Determine if pools are enabled using /dev/pool directly, as
34552978630Ssl 	 * libpool may not be present.
34652978630Ssl 	 */
34752978630Ssl 	if (getzoneid() != GLOBAL_ZONEID) {
34852978630Ssl 		XSRETURN_IV(1);
34952978630Ssl 	}
35052978630Ssl 	if ((fd = open("/dev/pool", O_RDONLY)) < 0) {
35152978630Ssl 		XSRETURN_IV(1);
35252978630Ssl 	}
35352978630Ssl 	if (ioctl(fd, POOL_STATUSQ, &status) < 0) {
35452978630Ssl 		(void) close(fd);
35552978630Ssl 		XSRETURN_IV(1);
35652978630Ssl 	}
35752978630Ssl 	close(fd);
35852978630Ssl 	if (status.ps_io_state != 1) {
35952978630Ssl 		XSRETURN_IV(1);
36052978630Ssl 	}
36152978630Ssl 
36252978630Ssl 	/*
36352978630Ssl 	 * If pools are enabled, assume libpool is present.
36452978630Ssl 	 */
3657c478bd9Sstevel@tonic-gate 	conf = pool_conf_alloc();
3667c478bd9Sstevel@tonic-gate 	if (conf == NULL) {
3677c478bd9Sstevel@tonic-gate 		XSRETURN_IV(1);
3687c478bd9Sstevel@tonic-gate 	}
3697c478bd9Sstevel@tonic-gate 	if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY)) {
3707c478bd9Sstevel@tonic-gate 		pool_conf_free(conf);
3717c478bd9Sstevel@tonic-gate 		XSRETURN_IV(1);
3727c478bd9Sstevel@tonic-gate 	}
3737c478bd9Sstevel@tonic-gate 	pool = pool_get_pool(conf, name);
3747c478bd9Sstevel@tonic-gate 	if (pool == NULL) {
3757c478bd9Sstevel@tonic-gate 		pool_conf_close(conf);
3767c478bd9Sstevel@tonic-gate 		pool_conf_free(conf);
3777c478bd9Sstevel@tonic-gate 		XSRETURN_IV(1);
3787c478bd9Sstevel@tonic-gate 	}
3797c478bd9Sstevel@tonic-gate 	pool_conf_close(conf);
3807c478bd9Sstevel@tonic-gate 	pool_conf_free(conf);
3817c478bd9Sstevel@tonic-gate 	XSRETURN_IV(0);
3827c478bd9Sstevel@tonic-gate 
383