Net-NIS

 view release on metacpan or  search on metacpan

NIS.xs  view on Meta::CPAN

    yp_status_get, yp_status_set,
};


/*****************************************************************************\
|*                     Callback used by yp_all()                             *|
\*****************************************************************************/

int
ypallcallback(instatus, inkey, inkeylen, inval, invallen, indata)
int     instatus;
char    *inkey;
int     inkeylen;
char    *inval;
int     invallen;
char    *indata;
{
    if (instatus == YP_TRUE)
    {
	/* Ugh.  Sometimes we get back keys (or values) with a trailing NUL. */
	if (0 < inkeylen && inkey[inkeylen - 1] == '\0')
	    --inkeylen;
	if (0 < invallen && inval[invallen - 1] == '\0')
	    --invallen;

	/* Don't allow a zero-length key -- but zero-length value ("") is OK */
	if (0 < inkeylen) {
	    hv_store((HV*)SvRV(((struct callbackdata *)indata)->results),
		             inkey, inkeylen,
		     newSVpv(inval, invallen), (U32)0);
	}
    }

    ((struct callbackdata *)indata)->status = ypprot_err(instatus);

    if (instatus < 0) return instatus;
    return 0;
}


MODULE = Net::NIS	PACKAGE = Net::NIS

 #
 # YPERR_xxx constants, enumerated above
 #
double
constant(name,arg)
	char *		name
	int		arg

int
yp_bind(domain)
  char *	domain

void
yp_unbind(domain)
  char *	domain

void
yp_get_default_domain()
  PPCODE:
  {
    char	*domain;

    yp_status = yp_get_default_domain(&domain);

    YP_RETURN(newSVpv(domain, strlen(domain)));
  }

 #
 # Looks up a key in a given map (this implements the FETCH part)
 #
void
yp_match(domain, map, key)
  char *	domain
  char *	map
  SV *		key
  PPCODE:
  {
    char	*inkey;
    STRLEN	inkeylen;
    char	*outval;
    int		outvallen = 0;

    if (SvPOK(key))
    {
	inkey = SvPV(key, inkeylen);

	yp_status = yp_match(domain, map, inkey, (int)inkeylen,
			     &outval, &outvallen);
	/* Sigh.  Sometimes we have to include the trailing NUL */
	if (yp_status == YPERR_KEY)
	    yp_status = yp_match(domain, map, inkey, (int)inkeylen+1,
				 &outval, &outvallen);

	/* Like above, sometimes we get an extra trailing NUL char */
	if (yp_status == YPERR_SUCCESS)
	    if (0 < outvallen && outval[outvallen-1] == '\0')
		--outvallen;

    }
    else
    {
	yp_status = YPERR_BADARGS;
    }

    YP_RETURN(newSVpv(outval, outvallen));
  }

void
yp_first(domain, map)
  char *	domain
  char *	map
  PPCODE:
  {
    char	*outkey;
    int		outkeylen;
    char	*outval;
    int		outvallen;

    yp_status = yp_first(domain, map, &outkey, &outkeylen,
			              &outval, &outvallen);
    XPUSHs(sv_2mortal(newSViv(yp_status)));
    if (yp_status == 0)
    {
	XPUSHs(sv_2mortal(newSVpv(outkey, outkeylen)));
	XPUSHs(sv_2mortal(newSVpv(outval, outvallen)));
    }
  }

void
yp_next(domain, map, key)
  char *	domain
  char *	map
  SV *		key
  PPCODE:
  {
    char	*inkey;
    STRLEN	inkeylen;
    char	*outkey;
    int 	outkeylen;
    char	*outval;
    int		outvallen;

    if (SvPOK(key))
    {
	inkey = SvPV(key, inkeylen);

	yp_status = yp_next(domain, map, inkey, (int)inkeylen,
			    &outkey, &outkeylen, &outval, &outvallen);
	XPUSHs(sv_2mortal(newSViv(yp_status)));
	if (yp_status == 0)
	{
	    XPUSHs(sv_2mortal(newSVpv(outkey, outkeylen)));
	    XPUSHs(sv_2mortal(newSVpv(outval, outvallen)));
	}
    }
    else
    {
	XPUSHs(sv_2mortal(newSViv(YPERR_BADARGS)));
    }
  }

void
yp_all(domain, map)
  char *	domain
  char *	map
  PPCODE:
  {
    struct ypall_callback	callback;
    struct callbackdata		data;

    data.results = newRV((SV *) newHV());
    data.status = 0;
    callback.foreach = ypallcallback;
    callback.data = (char *)&data;
    yp_status = yp_all(domain, map, &callback);

    if (yp_status == YPERR_SUCCESS) {
	# Linux & Solaris see NOMORE, FreeBSD gets a plain 0
	if (data.status == YPERR_NOMORE ||
	    data.status == YPERR_SUCCESS) {
	    yp_status = YPERR_SUCCESS;
	}
	else {			/* Unexpected value in callback status block */
	    yp_status = data.status;
	}
    }

    YP_RETURN((SV*)data.results);
  }

void
yp_order(domain, map)
  char *	domain
  char *	map
  PPCODE:
  {
    unsigned long	order;

    yp_status = yp_order(domain, map, &order);
    YP_RETURN(newSViv(order));
  }

void
yp_master(domain, map)
  char *	domain
  char *	map
  PPCODE:
  {
    char	*name;

    yp_status = yp_master(domain, map, &name);
    YP_RETURN(newSVpv(name, strlen(name)));
  }

char *
yperr_string(code)
  int		code

int
ypprot_err(code)
  int		code

 #
 # Tie the magic yp_status variable.  This should be called from our .pm
 #
void
_yp_tie_status(sv)
	SV*	sv
    PREINIT:
	MAGIC *m;
    CODE:
	sv_magic(sv, NULL, '~', "Net::NIS::yp_status_variable",
		         strlen("Net::NIS::yp_status_variable"));
	m = mg_find(sv, '~');
	m->mg_virtual = &yp_status_accessors;
	SvMAGICAL_on(sv);

#ifdef	__linux

  #
  # Returns an array of all the YP map names
  #
void
yp_maplist(domain)
  char *	domain
  PREINIT:
	int		  ret;
	struct ypmaplist *ypmap = NULL;
	AV		 *retval;
  PPCODE:
  {
    ret = yp_maplist( domain, &ypmap );

    if (ret == YPERR_SUCCESS) {
      struct ypmaplist *y, *old;

      for (y=ypmap; y;) {
	// FIXME: check that y->map is not NULL?
	XPUSHs(newSVpv(y->ypml_name,strlen(y->ypml_name)));
	old = y;
	y   = y->ypml_next;
	free(old);
      }
    }
  }


#else	/* Linux */

void
yp_maplist(domain)
    char *	domain
  PPCODE:
  {
    warn("Net::NIS::yp_maplist() -- not implemented on this OS");
    XSRETURN_EMPTY;
  }

#endif



( run in 0.900 second using v1.01-cache-2.11-cpan-71847e10f99 )