e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
fec6251998-03-25Fredrik Hübinette (Hubbe) #include "global.h"
7806861997-02-13Per Hedbor #include "config.h" #if defined(HAVE_RPCSVC_YPCLNT_H) && defined(HAVE_RPCSVC_YP_PROT_H)
497b2a1997-03-03Henrik Grubbström (Grubba) #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif /* HAVE_SYS_TYPES_H */
6e6fba1997-03-04Henrik Grubbström (Grubba) #ifdef HAVE_RPC_TYPES_H #include <rpc/types.h> #endif /* HAVE_RPC_TYPES_H */ #ifdef HAVE_RPC_RPC_H #include <rpc/rpc.h> #endif /* HAVE_RPC_RPC_H */ #ifdef HAVE_RPC_CLNT_H #include <rpc/clnt.h> #endif /* HAVE_RPC_CLNT_H */
7806861997-02-13Per Hedbor #include <rpcsvc/yp_prot.h>
abfe511998-08-08Henrik Grubbström (Grubba) #include <rpcsvc/ypclnt.h>
7806861997-02-13Per Hedbor  #include "stralloc.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
7806861997-02-13Per Hedbor #include "object.h" #include "constants.h" #include "interpret.h" #include "svalue.h" #include "mapping.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "module_support.h"
7806861997-02-13Per Hedbor 
6dc2772000-07-28Fredrik Hübinette (Hubbe) 
d569182002-05-11Martin Nilsson #define sp Pike_sp
3503362000-08-17Henrik Grubbström (Grubba) #ifdef HAVE_YPERR_STRING
3956132005-04-09Henrik Grubbström (Grubba) #ifdef YPERR_STRING_PROTOTYPE_MISSING char *yperr_string(int incode); #endif /* YPERR_STRING_PROTOTYPE_MISSING */
e9427a2002-11-28Martin Nilsson #define YPERROR(e) do{ if(err) Pike_error("%s\n", yperr_string(e)); }while(0)
3503362000-08-17Henrik Grubbström (Grubba) #else /* !HAVE_YPERR_STRING */
e9427a2002-11-28Martin Nilsson #define YPERROR(e) do{ if(e) Pike_error("YP error %d.\n", (e)); }while(0)
3503362000-08-17Henrik Grubbström (Grubba) #endif /* HAVE_YPERR_STRING */
7806861997-02-13Per Hedbor  struct my_yp_domain { char *domain; int last_size; /* Optimize some allocations */ };
d569182002-05-11Martin Nilsson #define this ((struct my_yp_domain *)Pike_fp->current_storage)
7806861997-02-13Per Hedbor 
6e16522001-01-05Henrik Grubbström (Grubba) /*! @module Yp *! *! This module is an interface to the Yellow Pages functions. Yp is also *! known as NIS (Network Information System) and is most commonly used to *! distribute passwords and similar information within a network. */
e9427a2002-11-28Martin Nilsson /*! @decl string default_domain()
6e16522001-01-05Henrik Grubbström (Grubba)  *! *! Returns the default yp-domain. */
e9427a2002-11-28Martin Nilsson static void f_default_domain(INT32 args)
7806861997-02-13Per Hedbor { int err; char *ret;
12887f1998-05-23Henrik Grubbström (Grubba) 
7806861997-02-13Per Hedbor  err = yp_get_default_domain(&ret);
12887f1998-05-23Henrik Grubbström (Grubba) 
e9427a2002-11-28Martin Nilsson  YPERROR( err );
12887f1998-05-23Henrik Grubbström (Grubba)  pop_n_elems( args );
7806861997-02-13Per Hedbor  push_text( ret ); }
6e16522001-01-05Henrik Grubbström (Grubba) /*! @class Domain */ /*! @decl string server(string map) *! *! Returns the hostname of the server serving the map @[map]. @[map] *! is the YP-map to search in. This must be the full map name. *! eg @tt{passwd.byname@} instead of just @tt{passwd@}. */
7806861997-02-13Per Hedbor static void f_server(INT32 args) { int err;
a098a12004-06-29Martin Nilsson  char *ret, *map;
12887f1998-05-23Henrik Grubbström (Grubba) 
a098a12004-06-29Martin Nilsson  get_all_args("server", args, "%s", &map); err = yp_master(this->domain, map, &ret);
12887f1998-05-23Henrik Grubbström (Grubba) 
e9427a2002-11-28Martin Nilsson  YPERROR( err );
12887f1998-05-23Henrik Grubbström (Grubba)  pop_n_elems( args );
7806861997-02-13Per Hedbor  push_text( ret ); }
6e16522001-01-05Henrik Grubbström (Grubba) /*! @decl void create(string|void domain)
d579c82001-12-08Martin Nilsson  *! @decl void bind(string domain)
6e16522001-01-05Henrik Grubbström (Grubba)  *! *! If @[domain] is not specified , the default domain will be used.
e9427a2002-11-28Martin Nilsson  *! (As returned by @[Yp.default_domain()]).
6e16522001-01-05Henrik Grubbström (Grubba)  *! *! If there is no YP server available for the domain, this *! function call will block until there is one. If no server appears *! in about ten minutes or so, an error will be returned. This timeout *! is not configurable. *! *! @seealso
e9427a2002-11-28Martin Nilsson  *! @[Yp.default_domain()]
6e16522001-01-05Henrik Grubbström (Grubba)  */
7806861997-02-13Per Hedbor static void f_create(INT32 args) { int err; if(!args) {
e9427a2002-11-28Martin Nilsson  f_default_domain(0);
7806861997-02-13Per Hedbor  args = 1; }
e9427a2002-11-28Martin Nilsson  check_all_args("create", args, BIT_STRING,0);
7806861997-02-13Per Hedbor  if(this->domain) { yp_unbind( this->domain ); free(this->domain); } this->domain = strdup( sp[-args].u.string->str ); err = yp_bind( this->domain );
12887f1998-05-23Henrik Grubbström (Grubba) 
e9427a2002-11-28Martin Nilsson  YPERROR( err );
12887f1998-05-23Henrik Grubbström (Grubba)  pop_n_elems(args);
7806861997-02-13Per Hedbor }
6e16522001-01-05Henrik Grubbström (Grubba) /*! @decl mapping(string:string) all(string map) *! *! Returns the whole map as a mapping. *! *! @[map] is the YP-map to search in. This must be the full map name, *! you have to use @tt{passwd.byname@} instead of just @tt{passwd@}. */
7806861997-02-13Per Hedbor static void f_all(INT32 args) { int err, num=0; char *retval, *retkey; int retlen, retkeylen; char *map; struct mapping *res_map;
e9427a2002-11-28Martin Nilsson  check_all_args("all", args, BIT_STRING, 0);
7806861997-02-13Per Hedbor  map = sp[-1].u.string->str; res_map = allocate_mapping( (this->last_size?this->last_size+2:40) ); if(!(err = yp_first(this->domain, map, &retkey,&retkeylen, &retval,&retlen))) do { push_string(make_shared_binary_string(retkey, retkeylen)); push_string(make_shared_binary_string(retval, retlen)); mapping_insert( res_map, sp-2, sp-1 ); pop_stack(); pop_stack(); err = yp_next(this->domain, map, retkey, retkeylen, &retkey, &retkeylen, &retval, &retlen); num++; } while(!err); if(err != YPERR_NOMORE) { free_mapping( res_map );
e9427a2002-11-28Martin Nilsson  YPERROR( err );
7806861997-02-13Per Hedbor  }
12887f1998-05-23Henrik Grubbström (Grubba) 
7806861997-02-13Per Hedbor  this->last_size = num;
12887f1998-05-23Henrik Grubbström (Grubba)  pop_n_elems(args);
7806861997-02-13Per Hedbor  push_mapping( res_map ); }
6e16522001-01-05Henrik Grubbström (Grubba) /*! @decl void map(string map, function(string, string:void) fun) *! *! For each entry in @[map], call the function specified by @[fun]. *!
c2d49b2002-02-14Martin Nilsson  *! @[fun] will get two arguments, the first being the key, and the
6e16522001-01-05Henrik Grubbström (Grubba)  *! second the value. *! *! @[map] is the YP-map to search in. This must be the full map name. *! eg @tt{passwd.byname@} instead of just @tt{passwd@}. */
ed01d51999-08-02Fredrik Hübinette (Hubbe) static void f_map(INT32 args)
7806861997-02-13Per Hedbor { int err; char *retval, *retkey; int retlen, retkeylen; char *map; struct svalue *f = &sp[-1];
3c04e81997-03-13Fredrik Hübinette (Hubbe)  check_all_args("map", args, BIT_STRING, BIT_FUNCTION|BIT_ARRAY, 0 );
7806861997-02-13Per Hedbor  map = sp[-2].u.string->str; if(!(err = yp_first(this->domain,map, &retkey,&retkeylen, &retval, &retlen))) do { push_string(make_shared_binary_string(retkey, retkeylen)); push_string(make_shared_binary_string(retval, retlen)); apply_svalue( f, 2 ); err = yp_next(this->domain, map, retkey, retkeylen, &retkey, &retkeylen, &retval, &retlen); } while(!err); if(err != YPERR_NOMORE)
e9427a2002-11-28Martin Nilsson  YPERROR( err );
12887f1998-05-23Henrik Grubbström (Grubba)  pop_n_elems(args);
7806861997-02-13Per Hedbor }
6e16522001-01-05Henrik Grubbström (Grubba) /*! @decl int order(string map) *! *! Returns the 'order' number for the map @[map]. *! *! This is usually the number of seconds since Jan 1 1970 (see @[time()]). *! When the map is changed, this number will change as well. *! *! @[map] is the YP-map to search in. This must be the full map name. *! eg @tt{passwd.byname@} instead of just @tt{passwd@}. */
7806861997-02-13Per Hedbor static void f_order(INT32 args) { int err;
abfe511998-08-08Henrik Grubbström (Grubba)  YP_ORDER_TYPE ret;
12887f1998-05-23Henrik Grubbström (Grubba) 
e9427a2002-11-28Martin Nilsson  check_all_args("order", args, BIT_STRING, 0);
7806861997-02-13Per Hedbor  err = yp_order( this->domain, sp[-args].u.string->str, &ret);
12887f1998-05-23Henrik Grubbström (Grubba) 
e9427a2002-11-28Martin Nilsson  YPERROR( err );
12887f1998-05-23Henrik Grubbström (Grubba) 
7806861997-02-13Per Hedbor  pop_n_elems( args ); push_int( (INT32) ret ); }
6e16522001-01-05Henrik Grubbström (Grubba) /*! @decl string match(string map, string key) *! *! Search for the key @[key] in the Yp-map @[map]. *! *! @returns *! If there is no @[key] in the map, 0 (zero) will be returned, *! otherwise the string matching the key will be returned. *! *! @note *! @[key] must match exactly, no pattern matching of any kind is done. */
7806861997-02-13Per Hedbor static void f_match(INT32 args) { int err; char *retval; int retlen;
e9427a2002-11-28Martin Nilsson  check_all_args("match", args, BIT_STRING, BIT_STRING, 0);
7806861997-02-13Per Hedbor  err = yp_match( this->domain, sp[-args].u.string->str, sp[-args+1].u.string->str, sp[-args+1].u.string->len, &retval, &retlen ); if(err == YPERR_KEY) {
12887f1998-05-23Henrik Grubbström (Grubba)  pop_n_elems( args );
074dd12011-10-22Henrik Grubbström (Grubba)  push_undefined();
7806861997-02-13Per Hedbor  return; }
e9427a2002-11-28Martin Nilsson  YPERROR( err );
12887f1998-05-23Henrik Grubbström (Grubba)  pop_n_elems( args );
7806861997-02-13Per Hedbor  push_string(make_shared_binary_string( retval, retlen )); } static void init_yp_struct( struct object *o ) { this->domain = 0; this->last_size = 0; } static void exit_yp_struct( struct object *o ) { if(this->domain) { yp_unbind( this->domain ); free(this->domain); } }
6e16522001-01-05Henrik Grubbström (Grubba) /*! @endclass */ /*! @endmodule */
7806861997-02-13Per Hedbor  /******************** PUBLIC FUNCTIONS BELOW THIS LINE */
51ef5c2002-10-21Marcus Comstedt PIKE_MODULE_INIT
7806861997-02-13Per Hedbor {
e9427a2002-11-28Martin Nilsson  /* function(void:string) */ ADD_FUNCTION("default_domain", f_default_domain,tFunc(tVoid,tStr),
7806861997-02-13Per Hedbor  OPT_EXTERNAL_DEPEND); start_new_program();
90e9781999-01-31Fredrik Hübinette (Hubbe)  ADD_STORAGE(struct my_yp_domain);
7806861997-02-13Per Hedbor  set_init_callback( init_yp_struct ); set_exit_callback( exit_yp_struct );
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(string|void:void) */ ADD_FUNCTION("create", f_create,tFunc(tOr(tStr,tVoid),tVoid), 0); /* function(string:void) */ ADD_FUNCTION("bind", f_create,tFunc(tStr,tVoid), 0); /* function(string,string:string) */ ADD_FUNCTION("match", f_match,tFunc(tStr tStr,tStr), 0); /* function(string:string) */ ADD_FUNCTION("server", f_server,tFunc(tStr,tStr), 0); /* function(string:mapping(string:string)) */ ADD_FUNCTION("all", f_all,tFunc(tStr,tMap(tStr,tStr)), 0); /* function(string,function|array(function):void) */ ADD_FUNCTION("map", f_map,tFunc(tStr tOr(tFunction,tArr(tFunction)),tVoid), 0); /* function(string:int) */ ADD_FUNCTION("order", f_order,tFunc(tStr,tInt), 0);
7806861997-02-13Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  end_class("Domain", 0);
7806861997-02-13Per Hedbor }
51ef5c2002-10-21Marcus Comstedt PIKE_MODULE_EXIT
7806861997-02-13Per Hedbor {
61e9a01998-01-25Fredrik Hübinette (Hubbe) 
7806861997-02-13Per Hedbor } #else
51ef5c2002-10-21Marcus Comstedt #include "module.h" PIKE_MODULE_INIT {} PIKE_MODULE_EXIT {}
7806861997-02-13Per Hedbor  #endif