/* * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Project.xs contains XS wrappers for the project database maniplulation * functions as provided by libproject and described in getprojent(3EXACCT). */ #pragma ident "@(#)Project.xs 1.4 02/05/20 SMI" /* Solaris includes. */ #include /* 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 pushret_project(const struct project *proj) { char **cp; AV *ary; dSP; if (GIMME_V == G_SCALAR) { EXTEND(SP, 1); PUSHs(sv_2mortal(newSVpv(proj->pj_name, 0))); PUTBACK; return (1); } else if (GIMME_V == G_ARRAY) { EXTEND(SP, 6); PUSHs(sv_2mortal(newSVpv(proj->pj_name, 0))); PUSHs(sv_2mortal(newSViv(proj->pj_projid))); PUSHs(sv_2mortal(newSVpv(proj->pj_comment, 0))); ary = newAV(); for (cp = proj->pj_users; *cp != NULL; cp++) { av_push(ary, newSVpv(*cp, 0)); } PUSHs(sv_2mortal(newRV_noinc((SV *)ary))); ary = newAV(); for (cp = proj->pj_groups; *cp != NULL; cp++) { av_push(ary, newSVpv(*cp, 0)); } PUSHs(sv_2mortal(newRV_noinc((SV *)ary))); PUSHs(sv_2mortal(newSVpv(proj->pj_attr, 0))); PUTBACK; return (6); } else { return (0); } } static int pwalk_cb(const projid_t project, void *walk_data) { int *nitemsp; dSP; nitemsp = (int *) walk_data; EXTEND(SP, 1); PUSHs(sv_2mortal(newSViv(project))); (*nitemsp)++; PUTBACK; 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. */ MODULE = Sun::Solaris::Project PACKAGE = Sun::Solaris::Project PROTOTYPES: ENABLE # # Define any constants that need to be exported. By doing it this way we can # avoid the overhead of using the DynaLoader package, and in addition constants # defined using this mechanism are eligible for inlining by the perl # interpreter at compile time. # BOOT: { HV *stash; stash = gv_stashpv("Sun::Solaris::Project", TRUE); newCONSTSUB(stash, "MAXPROJID", newSViv(MAXPROJID)); newCONSTSUB(stash, "PROJNAME_MAX", newSViv(PROJNAME_MAX)); newCONSTSUB(stash, "PROJF_PATH", newSVpv(PROJF_PATH, sizeof (PROJF_PATH) - 1)); newCONSTSUB(stash, "PROJECT_BUFSZ", newSViv(PROJECT_BUFSZ)); newCONSTSUB(stash, "SETPROJ_ERR_TASK", newSViv(SETPROJ_ERR_TASK)); newCONSTSUB(stash, "SETPROJ_ERR_POOL", newSViv(SETPROJ_ERR_POOL)); } projid_t getprojid() int setproject(name, user_name, flags) const char *name; const char *user_name uint_t flags void activeprojects() PREINIT: int nitems; PPCODE: 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); }