From dfa0b672ab9bb64c57c3815fcf3004891bd33e5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Tue, 21 Jan 1997 21:15:28 -0800 Subject: [PATCH] gethostbyname fixed, socket->query_address() added, module_support added Rev: src/Makefile.in:1.6 Rev: src/module_support.c:1.1 Rev: src/module_support.h:1.1 Rev: src/modules/files/configure.in:1.10 Rev: src/modules/files/efuns.c:1.6 Rev: src/modules/files/file.c:1.22 Rev: src/modules/files/file.h:1.2 Rev: src/modules/files/file_machine.h.in:1.5 Rev: src/modules/files/socket.c:1.5 Rev: src/modules/system/configure.in:1.3 Rev: src/modules/system/system.c:1.4 Rev: src/modules/system/system_machine.h.in:1.3 --- src/Makefile.in | 1 + src/module_support.c | 136 ++++++++ src/module_support.h | 22 ++ src/modules/files/configure.in | 71 +--- src/modules/files/efuns.c | 61 +++- src/modules/files/file.c | 75 +--- src/modules/files/file.h | 4 +- src/modules/files/file_machine.h.in | 12 +- src/modules/files/socket.c | 29 ++ src/modules/system/configure.in | 49 +++ src/modules/system/system.c | 458 +++++++++++-------------- src/modules/system/system_machine.h.in | 8 +- 12 files changed, 506 insertions(+), 420 deletions(-) create mode 100644 src/module_support.c create mode 100644 src/module_support.h diff --git a/src/Makefile.in b/src/Makefile.in index 0fd84dd713..27379f4372 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -88,6 +88,7 @@ OBJ= \ mapping.o \ memory.o \ module.o \ + module_support.o \ object.o \ opcodes.o \ operators.o \ diff --git a/src/module_support.c b/src/module_support.c new file mode 100644 index 0000000000..87650116a1 --- /dev/null +++ b/src/module_support.c @@ -0,0 +1,136 @@ +#include "global.h" +#include "module_support.h" +#include "interpret.h" +#include "svalue.h" +#include "stralloc.h" + +void check_args(const char *fnname, int args, int minargs, ... ) +{ + va_list arglist; + int argno; + + if (args < minargs) { + error("Too few arguments to %s()\n", fnname); + } + + va_start(arglist, minargs); + + for (argno=0; argno < minargs; argno++) + { + int type_mask = va_arg(arglist, unsigned INT32); + + if (!((1UL << sp[argno-args].type) & type_mask)) + { + va_end(arglist); + error("Bad argument %d to %s()\n", argno+1, fnname); + } + } + + va_end(arglist); +} + +/* This function does NOT generate errors, it simply returns how + * many arguments were actually matched. + * usage: get_args(sp-args, args, "%i",&an_int) + * format specifiers: + * %i: INT32 + * %s: char * + * %S: struct pike_string * + * %a: struct array * + * %f: float + * %m: struct mapping * + * %M: struct multiset * + * %o: struct object * + * %p: struct program * + * %*: struct svalue * + */ + +int va_get_args(struct svalue *s, + INT32 num_args, + char *fmt, + va_list ap) +{ + int ret=0; + while(*fmt) + { + if(*fmt != '%') + fatal("Error in format for get_args.\n"); + + if(ret == num_args) return ret; + + switch(*++fmt) + { + case 'd': + if(s->type != T_INT) return ret; + *va_arg(ap, int *)=s->u.integer; + break; + case 'i': + if(s->type != T_INT) return ret; + *va_arg(ap, INT32 *)=s->u.integer; break; + case 's': + if(s->type != T_STRING) return ret; + *va_arg(ap, char **)=s->u.string->str; + break; + case 'S': + if(s->type != T_STRING) return ret; + *va_arg(ap, struct pike_string **)=s->u.string; + break; + case 'a': + if(s->type != T_ARRAY) return ret; + *va_arg(ap, struct array **)=s->u.array; + break; + case 'f': + if(s->type != T_ARRAY) return ret; + *va_arg(ap, float *)=s->u.float_number; + break; + case 'm': + if(s->type != T_MAPPING) return ret; + *va_arg(ap, struct mapping **)=s->u.mapping; + break; + case 'M': + if(s->type != T_MULTISET) return ret; + *va_arg(ap, struct multiset **)=s->u.multiset; + break; + case 'o': + if(s->type != T_OBJECT) return ret; + *va_arg(ap, struct object **)=s->u.object; + break; + case 'p': + if(s->type != T_PROGRAM) return ret; + *va_arg(ap, struct program **)=s->u.program; + break; + case '*': + *va_arg(ap, struct svalue **)=s; + break; + + default: + fatal("Unknown format character in get_args.\n"); + } + ret++; + s++; + fmt++; + } + return ret; +} + +int get_args(struct svalue *s, + INT32 num_args, + char *fmt, ...) +{ + va_list ptr; + int ret; + va_start(ptr, fmt); + ret=va_get_args(s, num_args, fmt, ptr); + va_end(fmt); +} + +void get_all_args(char *fname, INT32 args, char *format, ... ) +{ + va_list ptr; + int ret; + va_start(ptr, format); + ret=va_get_args(sp-args, args, format, ptr); + va_end(ptr); + if((long)ret != (long)strlen(format) / 2) + error("Bad argument %d to %s()\n", ret+1, fname); +} diff --git a/src/module_support.h b/src/module_support.h new file mode 100644 index 0000000000..791535e129 --- /dev/null +++ b/src/module_support.h @@ -0,0 +1,22 @@ +/*\ +||| This file a part of Pike, and is copyright by Fredrik Hubinette +||| Pike is distributed as GPL (General Public License) +||| See the files COPYING and DISCLAIMER for more information. +\*/ + +#ifndef MODULE_SUPPORT_H +#include <stdarg.h> + +/* Prototypes begin here */ +void check_args(const char *fnname, int args, int minargs, ... ); +int va_get_args(struct svalue *s, + INT32 num_args, + char *fmt, + va_list ptr); +int get_args(struct svalue *s, + INT32 num_args, + char *fmt, ...); +void get_all_args(char *fname, INT32 args, char *format, ... ); +/* Prototypes end here */ + +#endif diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in index d3d96f6fb4..74c57f96c1 100644 --- a/src/modules/files/configure.in +++ b/src/modules/files/configure.in @@ -14,77 +14,8 @@ AC_HAVE_HEADERS(arpa/inet.h sys/socketvar.h netinet/in.h \ sys/stream.h sys/protosw.h netdb.h) AC_HEADER_DIRENT AC_CHECK_LIB(socket, socket) -AC_CHECK_LIB(nsl, gethostbyname) - -AC_HAVE_FUNCS(socketpair getwd perror fork1) - -AC_MSG_CHECKING(for solaris style gethostbyname_r) - -AC_CACHE_VAL(pike_cv_have_solaris_gethostbyname_r, -[ -AC_TRY_LINK([ -#define _REENTRANT -#include <netdb.h> -],[ - char data[2000]; - int h_errno; - struct hostent result,*bar; - gethostbyname_r("foo",&result, data, sizeof(data), h_errno)->h_name; -],pike_cv_have_solaris_gethostbyname_r=yes, -pike_cv_have_solaris_gethostbyname_r=no) -]) - -AC_MSG_RESULT($pike_cv_have_solaris_gethostbyname_r) - -if test $pike_cv_have_solaris_gethostbyname_r = yes; then - AC_DEFINE(HAVE_SOLARIS_GETHOSTBYNAME_R) -fi - - -AC_MSG_CHECKING(for OSF1 style gethostbyname_r) - -AC_CACHE_VAL(pike_cv_have_osf1_gethostbyname_r, -[ -AC_TRY_LINK([ -#define _THREAD_SAFE -#include <netdb.h> -],[ - int bar; - struct hostent result; - struct hostent_data data; - bar=gethostbyname_r("foo",&result, &data); -],pike_cv_have_osf1_gethostbyname_r=yes, -pike_cv_have_osf1_gethostbyname_r=no) -]) - -AC_MSG_RESULT($pike_cv_have_osf1_gethostbyname_r) - -if test $pike_cv_have_osf1_gethostbyname_r = yes; then - AC_DEFINE(HAVE_OSF1_GETHOSTBYNAME_R) -fi - -AC_MSG_CHECKING(for h_addr_list) -AC_CACHE_VAL(pike_cv_struct_has_h_addr_list, -[ -AC_TRY_LINK([ -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -],[ -struct hostent foo; -foo.h_addr_list[0]; -],pike_cv_struct_has_h_addr_list=yes,pike_cv_struct_has_h_addr_list=no) -]) - -if test "$pike_cv_struct_has_h_addr_list" = yes; then - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_H_ADDR_LIST) -else - AC_MSG_RESULT(no) -fi +AC_HAVE_FUNCS(socketpair getwd perror fork1 readdir_r) AC_MSG_CHECKING(for working (and failsafe) strerror) AC_CACHE_VAL(pike_cv_func_failsafe_strerror, diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c index dc94929498..9ef8ce799f 100644 --- a/src/modules/files/efuns.c +++ b/src/modules/files/efuns.c @@ -13,6 +13,7 @@ #include "macros.h" #include "fd_control.h" #include "threads.h" +#include "module_support.h" #include "file_machine.h" @@ -167,14 +168,61 @@ void f_get_dir(INT32 args) DIR *dir; struct dirent *d; struct array *a=0; + char *path; - if(!args) - error("Too few arguments to get_dir()\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to get_dir()\n"); + get_all_args("get_dir",args,"%s",&path); - dir=opendir(sp[-args].u.string->str); +#if defined(_REENTRANT) && defined(HAVE_READDIR_R) + THREADS_ALLOW(); + dir=opendir(path); + THREADS_DISALLOW(); + if(dir) + { +#define FPR 1024 + char buffer[MAXPATHLEN * 4]; + char ptrs[FPR]; + int lens[FPR]; + + while(1) + { + int e; + struct dirent tmp; + int num_files=0; + char *bufptr=buffer; + THREADS_ALLOW(); + while(1) + { + d=readdir_r(dir, &tmp); + if(d->d_name[0]=='.') + { + if(!d->d_name[1]) continue; + if(d->d_name[1]=='.' && !d->d_name[2]) continue; + } + if(num_files >= FPR) break; + lens[num_files]=NAMLEN(d); + if(ptr+lens[num_files] >= buffer+sizeof(buffer)) break; + MEMCPY(ptr, d->d_name, lens[num_files]); + ptrs[num_files]=ptr; + ptr+=len; + num_files++; + } + THREADS_DISALLOW(); + for(e=0;e<num_files;e++) + { + push_string(make_shared_string(ptrs[e],lens[e])); + } + if(d) + push_string(make_shared_binary_string(d->d_name,NAMLEN(d))); + else + break; + } + THREADS_ALLOW(); + closedir(dir); + THREADS_DISALLOW(); + a=aggregate_array(sp-save_sp); + } +#else + dir=opendir(path); if(dir) { for(d=readdir(dir); d; d=readdir(dir)) @@ -189,6 +237,7 @@ void f_get_dir(INT32 args) closedir(dir); a=aggregate_array(sp-save_sp); } +#endif pop_n_elems(args); if(a) diff --git a/src/modules/files/file.c b/src/modules/files/file.c index 79435279ef..5d142256e4 100644 --- a/src/modules/files/file.c +++ b/src/modules/files/file.c @@ -6,7 +6,7 @@ #define READ_BUFFER 16384 #include "global.h" -RCSID("$Id: file.c,v 1.21 1997/01/18 22:00:10 hubbe Exp $"); +RCSID("$Id: file.c,v 1.22 1997/01/22 05:14:59 hubbe Exp $"); #include "types.h" #include "interpret.h" #include "svalue.h" @@ -1244,78 +1244,6 @@ static int isipnr(char *s) return 1; } -void get_inet_addr(struct sockaddr_in *addr,char *name) -{ - MEMSET((char *)addr,0,sizeof(struct sockaddr_in)); - - addr->sin_family = AF_INET; - if(!strcmp(name,"*")) - { - addr->sin_addr.s_addr=htonl(INADDR_ANY); - } - else if(isipnr(name)) - { - if ((long)inet_addr(name) == (long)-1) - error("Malformed ip number.\n"); - - addr->sin_addr.s_addr = inet_addr(name); - } - else - { - struct hostent *ret; -#ifdef _REENTRANT -#ifdef HAVE_SOLARIS_GETHOSTBYNAME_R - struct hostent result; - char data[2048]; - int h_errno; - - THREADS_ALLOW(); - ret=gethostbyname_r(name, &result, data, sizeof(data), &h_errno); - THREADS_DISALLOW(); -#else -#ifdef HAVE_OSF1_GETHOSTBYNAME_R - struct hostent result; - struct hostent_data data; - - THREADS_ALLOW(); - MEMSET((char *)&data,0,sizeof(data)); - if(gethostbyname_r(name, &result, &data) < 0) - { - ret=0; - }else{ - ret=&result; - } - THREADS_DISALLOW(); -#else - static MUTEX_T l; - - THREADS_ALLOW(); - - mt_lock(&l); - ret=gethostbyname(name); - mt_unlock(&l); - - THREADS_DISALLOW(); -#endif -#endif -#else - ret=gethostbyname(name); -#endif - if(!ret) - error("Invalid address '%s'\n",name); - -#ifdef HAVE_H_ADDR_LIST - MEMCPY((char *)&(addr->sin_addr), - (char *)ret->h_addr_list[0], - ret->h_length); -#else - MEMCPY((char *)&(addr->sin_addr), - (char *)ret->h_addr, - ret->h_length); -#endif - } -} - static void file_query_address(INT32 args) { struct sockaddr_in addr; @@ -1337,6 +1265,7 @@ static void file_query_address(INT32 args) { ERRNO=errno; push_int(0); + return; } q=inet_ntoa(addr.sin_addr); diff --git a/src/modules/files/file.h b/src/modules/files/file.h index c82375cff4..4b871147b8 100644 --- a/src/modules/files/file.h +++ b/src/modules/files/file.h @@ -34,10 +34,12 @@ struct my_file struct svalue close_callback; }; +extern void get_inet_addr(struct sockaddr_in *addr,char *name); + /* Prototypes begin here */ +struct file_struct; struct object *file_make_object_from_fd(int fd, int mode); int socketpair(int family, int type, int protocol, int sv[2]); -void get_inet_addr(struct sockaddr_in *addr,char *name); void exit_files(); void init_files_programs(); /* Prototypes end here */ diff --git a/src/modules/files/file_machine.h.in b/src/modules/files/file_machine.h.in index 75fe80ac77..ed7b4a9838 100644 --- a/src/modules/files/file_machine.h.in +++ b/src/modules/files/file_machine.h.in @@ -40,15 +40,12 @@ /* Define if you have getwd. */ #undef HAVE_GETWD -/* Define if you have solaris stype gethostbyname_r. */ -#undef HAVE_SOLARIS_GETHOSTBYNAME_R - -/* Define if you have OSF1 stype gethostbyname_r. */ -#undef HAVE_OSF1_GETHOSTBYNAME_R - /* Define if you have fork1. */ #undef HAVE_FORK1 +/* Define if you have a solaris compatible readdir_r. */ +#undef HAVE_READDIR_R + /* Define if you have strerror. */ #undef HAVE_STRERROR @@ -58,8 +55,5 @@ /* Define this if you have perror() */ #undef HAVE_PERROR -/* Define this if your struct hostent has h_addr_list */ -#undef HAVE_H_ADDR_LIST - #endif diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c index ad8fe91869..3ebf4a9b1a 100644 --- a/src/modules/files/socket.c +++ b/src/modules/files/socket.c @@ -308,6 +308,34 @@ static void port_accept(INT32 args) push_object(o); } +static void socket_query_address(INT32 args) +{ + struct sockaddr_in addr; + int i,len; + char buffer[496],*q; + + if(THIS->fd <0) + error("socket->query_address(): Socket not bound yet.\n"); + + len=sizeof(addr); + i=getsockname(THIS->fd,(struct sockaddr *)&addr,&len); + pop_n_elems(args); + if(i < 0 || len < (int)sizeof(addr)) + { + THIS->my_errno=errno; + push_int(0); + return; + } + + q=inet_ntoa(addr.sin_addr); + strncpy(buffer,q,sizeof(buffer)-20); + buffer[sizeof(buffer)-20]=0; + sprintf(buffer+strlen(buffer)," %d",(int)(ntohs(addr.sin_port))); + + push_string(make_shared_string(buffer)); +} + + static void init_port_struct(struct object *o) { THIS->fd=-1; @@ -338,6 +366,7 @@ void port_setup_program() add_function("listen_fd",port_listen_fd,"function(int,void|mixed:int)",0); add_function("set_id",port_set_id,"function(mixed:mixed)",0); add_function("query_id",port_query_id,"function(:mixed)",0); + add_function("query_address",socket_query_address,"function(:string)",0); add_function("errno",port_errno,"function(:int)",0); add_function("accept",port_accept,"function(:object)",0); add_function("create",port_create,"function(void|string,void|mixed:void)",0); diff --git a/src/modules/system/configure.in b/src/modules/system/configure.in index 0f6cd9d90d..1abb41da7d 100644 --- a/src/modules/system/configure.in +++ b/src/modules/system/configure.in @@ -17,6 +17,55 @@ AC_HAVE_HEADERS(sys/types.h errno.h unistd.h pwd.h sys/conf.h sys/socket.h netin AC_HAVE_FUNCS(link symlink readlink initgroups seteuid setresuid geteuid getpgrp getpgid getppid fchroot uname gethostname gethostbyname) + +AC_CHECK_LIB(nsl, gethostbyname) + +AC_MSG_CHECKING(for solaris style gethostbyname_r) + +AC_CACHE_VAL(pike_cv_have_solaris_gethostbyname_r, +[ +AC_TRY_LINK([ +#define _REENTRANT +#include <netdb.h> +],[ + char data[2000]; + int h_errno; + struct hostent result,*bar; + gethostbyname_r("foo",&result, data, sizeof(data), h_errno)->h_name; +],pike_cv_have_solaris_gethostbyname_r=yes, +pike_cv_have_solaris_gethostbyname_r=no) +]) + +AC_MSG_RESULT($pike_cv_have_solaris_gethostbyname_r) + +if test $pike_cv_have_solaris_gethostbyname_r = yes; then + AC_DEFINE(HAVE_SOLARIS_GETHOSTBYNAME_R) +fi + + +AC_MSG_CHECKING(for OSF1 style gethostbyname_r) + +AC_CACHE_VAL(pike_cv_have_osf1_gethostbyname_r, +[ +AC_TRY_LINK([ +#define _THREAD_SAFE +#include <netdb.h> +],[ + int bar; + struct hostent result; + struct hostent_data data; + bar=gethostbyname_r("foo",&result, &data); +],pike_cv_have_osf1_gethostbyname_r=yes, +pike_cv_have_osf1_gethostbyname_r=no) +]) + +AC_MSG_RESULT($pike_cv_have_osf1_gethostbyname_r) + +if test $pike_cv_have_osf1_gethostbyname_r = yes; then + AC_DEFINE(HAVE_OSF1_GETHOSTBYNAME_R) +fi + + AC_MSG_CHECKING(for h_addr_list) AC_CACHE_VAL(pike_cv_struct_has_h_addr_list, [ diff --git a/src/modules/system/system.c b/src/modules/system/system.c index 7bce31eef0..03757c9bd3 100644 --- a/src/modules/system/system.c +++ b/src/modules/system/system.c @@ -1,5 +1,5 @@ /* - * $Id: system.c,v 1.3 1997/01/22 02:55:12 grubba Exp $ + * $Id: system.c,v 1.4 1997/01/22 05:15:27 hubbe Exp $ * * System-call module for Pike * @@ -13,7 +13,8 @@ #include "system_machine.h" #include <global.h> -RCSID("$Id: system.c,v 1.3 1997/01/22 02:55:12 grubba Exp $"); +RCSID("$Id: system.c,v 1.4 1997/01/22 05:15:27 hubbe Exp $"); +#include <module_support.h> #include <las.h> #include <interpret.h> #include <stralloc.h> @@ -127,86 +128,6 @@ static volatile void report_error(const char *function_name) error("%s(): Failed:%s\n", function_name, error_msg); } -#if defined(HAVE_STDARG_H) || !defined(HAVE_VARARGS_H) -#ifdef HAVE_STDARG_H -#include <stdarg.h> -#else -/* Fallback to this if we have neither <stdarg.h> nor <varargs.h>. - * - * Should work on anything that passes all arguments on the stack, - * and the stack grows downwards. - * - * /grubba 1997-01-21 - */ -#define va_list void * -#define va_start(var, last_var) (var = (va_list)(&(last_var)+1)) -/* Could be a NOP as well */ -#define va_end(var) (var = 0) -/* Is the following line legal C? */ -#define va_arg(var, type) (*(((type *)var)++)) -#endif /* HAVE_STDARG_H */ - -static void check_args(const char *fnname, int args, int minargs, ... ) -{ - va_list arglist; - int argno; - - if (args < minargs) { - error("Too few arguments to %s()\n", fnname); - } - - va_start(arglist, minargs); - - for (argno=0; argno < minargs; argno++) { - int type_mask = va_arg(arglist, unsigned INT32); - - if (!((1UL << sp[argno-args].type) & type_mask)) { - va_end(arglist); - error("Bad argument %d to %s()\n", argno+1, fnname); - } - } - - va_end(arglist); -} - -#else /* Only HAVE_VARARGS_H */ - -#include <varargs.h> - -static void check_args(va_alist) -va_dcl -{ - const char *fnname; - int args; - int minargs; - va_list arglist; - int argno; - - va_start(arglist); - - fnname = va_arg(arglist, const char *); - args = va_arg(arglist, int); - minargs = va_arg(arglist, int); - - if (args < minargs) { - error("Too few arguments to %s()\n", fnname); - } - - va_start(arglist, minargs); - - for (argno=0; argno < minargs; argno++) { - int type_mask = va_arg(arglist, unsigned INT32); - - if (!((1UL << sp[argno-args].type) & type_mask)) { - va_end(arglist); - error("Bad argument %d to %s()\n", argno+1, fnname); - } - } - - va_end(arglist); -} - -#endif /* HAVE_STDARG_H || !HAVE_VARARGS_H */ /* * efuns @@ -220,20 +141,7 @@ void f_hardlink(INT32 args) char *to; int err; - check_args("hardlink", args, 2, BIT_STRING, BIT_STRING); -#if 0 - if (args < 2) { - error("Too few arguments to hardlink()\n"); - } - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to hardlink()\n"); - } - if (sp[1-args].type != T_STRING) { - error("Bad argument 2 to hardlink()\n"); - } -#endif /* 0 */ - from = sp[-args].u.string->str; - to = sp[1-args].u.string->str; + get_all_args("hardlink",args, "%s%s", &from, &to); do { THREADS_ALLOW(); @@ -258,20 +166,7 @@ void f_symlink(INT32 args) char *to; int err; - check_args("symlink", args, 2, BIT_STRING, BIT_STRING); -#if 0 - if (args < 2) { - error("Too few arguments to symlink()\n"); - } - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to symlink()\n"); - } - if (sp[1-args].type != T_STRING) { - error("Bad argument 2 to symlink()\n"); - } -#endif /* 0 */ - from = sp[-args].u.string->str; - to = sp[1-args].u.string->str; + get_all_args("symlink",args, "%s%s", &from, &to); do { THREADS_ALLOW(); @@ -297,17 +192,7 @@ void f_readlink(INT32 args) char *buf; int err; - check_args("readlink", args, 1, BIT_STRING); -#if 0 - if (!args) { - error("Too few arguments to readlink()\n"); - } - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to readlink()\n"); - } -#endif /* 0 */ - - path = sp[-args].u.string->str; + get_all_args("readlink",args, "%s", &path); buflen = 100; @@ -338,42 +223,21 @@ void f_readlink(INT32 args) /* void initgroups(string name, int gid) */ void f_initgroups(INT32 args) { - check_args("initgroups", args, 2, BIT_STRING, BIT_INT); -#if 0 - if(args < 2) { - error("Too few arguments to initgroups()\n"); - } - - if(sp[-args].type != T_STRING) { - error("Bad argument 1 to initgroups()\n"); - } - if (sp[1-args].type != T_INT) { - error("Bad argument 2 to initgroups()\n"); - } -#endif /* 0 */ - - initgroups(sp[-args].u.string->str, sp[1-args].u.integer); - + char *user; + INT32 group; + get_all_args("initgroups", args, "%s%i", &user, &group); + initgroups(user, group); pop_n_elems(args); } #endif /* HAVE_INITGROUPS */ void f_setuid(INT32 args) { - int id; + INT32 id; - check_args("setuid", args, 1, BIT_INT); -#if 0 - if (!args) { - error("Too few arguments to setuid()\n"); - } + get_all_args("setuid", args, "%i", &id); - if (sp[-args].type != T_INT) { - error("Bad argument 1 to setuid()\n"); - } -#endif /* 0 */ - - if(sp[-args].u.integer == -1) { + if(id == -1) { struct passwd *pw = getpwnam("nobody"); id = pw->pw_uid; } else { @@ -388,18 +252,9 @@ void f_setgid(INT32 args) { int id; - check_args("setgid", args, 1, BIT_INT); -#if 0 - if (!args) { - error("Too few arguments to setgid()\n"); - } + get_all_args("setgid", args, "%i", &id); - if(sp[-args].type != T_INT) { - error("Bad argumnet 1 to setgid()\n"); - } -#endif /* 0 */ - - if(sp[-args].u.integer == -1) { + if(id == -1) { struct passwd *pw = getpwnam("nobody"); id = pw->pw_gid; } else { @@ -415,18 +270,9 @@ void f_seteuid(INT32 args) { int id; - check_args("seteuid", args, 1, BIT_INT); -#if 0 - if (!args) { - error("Too few arguments to seteuid()\n"); - } - - if (sp[-args].type != T_INT) { - error("Bad argument 1 to seteuid()\n"); - } -#endif /* 0 */ + get_all_args("seteuid", args, "%i", &id); - if(sp[-args].u.integer == -1) { + if(id == -1) { struct passwd *pw = getpwnam("nobody"); id = pw->pw_uid; } else { @@ -445,18 +291,9 @@ void f_setegid(INT32 args) { int id; - check_args("setegid", args, 1, BIT_INT); -#if 0 - if (!args) { - error("Too few arguments to setegid()\n"); - } - - if(sp[-args].type != T_INT) { - error("Bad argument 1 to setegid()\n"); - } -#endif /* 0 */ + get_all_args("setegid", args, "%i", &id); - if(sp[-args].u.integer == -1) + if(id == -1) { struct passwd *pw = getpwnam("nobody"); id = pw->pw_gid; @@ -541,11 +378,6 @@ void f_chroot(INT32 args) check_args("chroot", args, 1, BIT_STRING); #endif /* HAVE_FCHROOT */ -#if 0 - if(args < 1) { - error("Too few arguments to chroot()\n"); - } -#endif /* 0 */ #ifdef HAVE_FCHROOT if(sp[-args].type == T_STRING) @@ -627,42 +459,157 @@ void f_gethostname(INT32 args) } #endif /* HAVE_UNAME || HAVE_GETHOSTNAME */ +int my_isipnr(char *s) +{ + int e,i; + for(e=0;e<3;e++) + { + i=0; + while(*s==' ') s++; + while(*s>='0' && *s<='9') s++,i++; + if(!i) return 0; + if(*s!='.') return 0; + s++; + } + i=0; + while(*s==' ') s++; + while(*s>='0' && *s<='9') s++,i++; + if(!i) return 0; + while(*s==' ') s++; + if(*s) return 0; + return 1; +} + +#ifdef _REENTRANT +#ifdef HAVE_SOLARIS_GETHOSTBYNAME_R + +#define GETHOST_DECLARE() \ + struct hostent *ret; \ + struct hostent result; \ + char data[2048]; \ + int h_errno + +#define CALL_GETHOSTBYNAME(X) \ + THREADS_ALLOW(); \ + ret=gethostbyname_r((X), &result, data, sizeof(data), &h_errno); \ + THREADS_DISALLOW() + +#define CALL_GETHOSTBYADDR(X,Y,Z) \ + THREADS_ALLOW(); \ + ret=gethostbyaddr_r((X),(Y),(Z), &result, data, sizeof(data), &h_errno); \ + THREADS_DISALLOW() + +#else /* HAVE_SOLARIS_GETHOSTBYNAME_R */ +#ifdef HAVE_OSF1_GETHOSTBYNAME_R + +#define GETHOST_DECLARE() \ + struct hostent *ret; \ + struct hostent result; \ + struct hostent_data data + +#define CALL_GETHOSTBYNAME(X) \ + THREADS_ALLOW(); \ + MEMSET((char *)&data,0,sizeof(data)); \ + if(gethostbyname_r((X), &result, &data) < 0) { \ + ret=0; \ + }else{ \ + ret=&result; \ + } \ + THREADS_DISALLOW() + +#define CALL_GETHOSTBYADDR(X,Y,Z) \ + THREADS_ALLOW(); \ + MEMSET((char *)&data,0,sizeof(data)); \ + if(gethostbyaddr_r((X),(Y),(Z), &result, &data) < 0) { \ + ret=0; \ + }else{ \ + ret=&result; \ + } \ + THREADS_DISALLOW() + +#else /* HAVE_OSF1_GETHOSTBYNAME_R */ +static MUTEX_T gethostbyname_mutex; + +#define GETHOST_DECLARE() struct hostent *ret + +#defne CALL_GETHOSTBYNAME(X) \ + THREADS_ALLOW(); \ + mt_lock(&gethostbyname_mutex); \ + ret=gethostbyname(X); \ + mt_unlock(&gethostbyname_mutex); \ + THREADS_DISALLOW() + + +#defne CALL_GETHOSTBYADDR(X,Y,Z) \ + THREADS_ALLOW(); \ + mt_lock(&gethostbyname_mutex); \ + ret=gethostbyaddr((X),(Y),(Z)); \ + mt_unlock(&gethostbyname_mutex); \ + THREADS_DISALLOW() + +#endif /* HAVE_OSF1_GETHOSTBYNAME_R */ +#endif /* HAVE_SOLARIS_GETHOSTBYNAME_R */ +#else /* _REENTRANT */ + #ifdef HAVE_GETHOSTBYNAME -/* array(string|array(string)) gethostbyaddr(string addr) */ -void f_gethostbyaddr(INT32 args) + +#define GETHOST_DECLARE() struct hostent *ret; +#define CALL_GETHOSTBYNAME(X) ret=gethostbyname(X) +#define CALL_GETHOSTBYADDR(X,Y,Z) ret=gethostbyaddr((X),(Y),(Z)) +#endif + +#endif /* REENTRANT */ + +/* this is used from modules/file/file.c ! */ +void get_inet_addr(struct sockaddr_in *addr,char *name) { - u_long addr; - struct hostent *hp; - char **p, **q; - int nelem; - - check_args("gethostbyaddr", args, 1, BIT_STRING); -#if 0 - if (!args) { - error("Too few arguments to gethostbyaddr()\n"); + MEMSET((char *)addr,0,sizeof(struct sockaddr_in)); + + addr->sin_family = AF_INET; + if(!strcmp(name,"*")) + { + addr->sin_addr.s_addr=htonl(INADDR_ANY); } - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to gethostbyaddr()\n"); + else if(my_isipnr(name)) /* I do not entirely trust inet_addr */ + { + if ((long)inet_addr(name) == (long)-1) + error("Malformed ip number.\n"); + + addr->sin_addr.s_addr = inet_addr(name); } -#endif /* 0 */ + else + { +#ifdef GETHOST_DECLARE + GETHOST_DECLARE(); + CALL_GETHOSTBYNAME(name); - if ((int)(addr = inet_addr(sp[-args].u.string->str)) == -1) { - error("gethostbyaddr(): IP-address must be of the form a.b.c.d\n"); + if(!ret) + error("Invalid address '%s'\n",name); + +#ifdef HAVE_H_ADDR_LIST + MEMCPY((char *)&(addr->sin_addr), + (char *)ret->h_addr_list[0], + ret->h_length); +#else + MEMCPY((char *)&(addr->sin_addr), + (char *)ret->h_addr, + ret->h_length); +#endif +#else + error("Invalid address '%s'\n",name); +#endif } - - pop_n_elems(args); +} - THREADS_ALLOW(); - hp = gethostbyaddr((char *)&addr, sizeof (addr), AF_INET); +#ifdef GETHOST_DECLARE +/* array(string|array(string)) gethostbyaddr(string addr) */ - THREADS_DISALLOW(); +static void describe_hostent(struct hostent *hp) +{ + char **p; + INT32 nelem; - if(!hp) { - push_int(0); - return; - } - push_text(hp->h_name); #ifdef HAVE_H_ADDR_LIST @@ -677,74 +624,65 @@ void f_gethostbyaddr(INT32 args) f_aggregate(nelem); nelem=0; - for (q = hp->h_aliases; *q != 0; q++) { - push_text(*q); + for (p = hp->h_aliases; *p != 0; p++) { + push_text(*p); nelem++; } f_aggregate(nelem); #else - f_aggregate(0); + { + struct in_addr in; + memcpy(&in.s_addr, ret->h_addr, sizeof (in.s_addr)); + push_text(inet_ntoa(in)); + } + + f_aggregate(1); f_aggregate(0); #endif /* HAVE_H_ADDR_LIST */ f_aggregate(3); -} +} -/* array(array(string)) gethostbyname(string hostname) */ -void f_gethostbyname(INT32 args) +void f_gethostbyaddr(INT32 args) { - struct hostent *hp; - char **p, **q; - struct svalue *old_sp; + u_long addr; char *name; - int nelem; + GETHOST_DECLARE(); + + get_all_args("gethostbyaddr", args, "%s", &name); - check_args("gethostbyname", args, 1, BIT_STRING); -#if 0 - if (!args) { - error("Too few arguments to gethostbyname()\n"); + if ((int)(addr = inet_addr(name)) == -1) { + error("gethostbyaddr(): IP-address must be of the form a.b.c.d\n"); } - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to gethostbyname()\n"); + + pop_n_elems(args); + + CALL_GETHOSTBYADDR((char *)&addr, sizeof (addr), AF_INET); + + if(!ret) { + push_int(0); + return; } -#endif /* 0 */ - name = sp[-args].u.string->str; + describe_hostent(ret); +} - THREADS_ALLOW(); +/* array(array(string)) gethostbyname(string hostname) */ +void f_gethostbyname(INT32 args) +{ + char *name; + GETHOST_DECLARE(); - hp = gethostbyname(name); + get_all_args("gethostbyname", args, "%s", &name); - THREADS_DISALLOW(); + CALL_GETHOSTBYNAME(name); pop_n_elems(args); - if(!hp) { + if(!ret) { push_int(0); return; } - -#ifdef HAVE_H_ADDR_LIST - nelem=0; - for (p = hp->h_addr_list; *p != 0; p++) { - struct in_addr in; - - memcpy(&in.s_addr, *p, sizeof (in.s_addr)); - push_text(inet_ntoa(in)); - nelem++; - } - f_aggregate(nelem); - - nelem=0; - for (q = hp->h_aliases; *q != 0; q++) { - push_text(*q); - nelem++; - } - f_aggregate(nelem); -#else - f_aggregate(0); - f_aggregate(0); -#endif /* HAVE_H_ADDR_LIST */ - f_aggregate(3); + describe_hostent(ret); } #endif /* HAVE_GETHOSTBYNAME */ @@ -770,7 +708,7 @@ void init_system_efuns(void) add_efun("setgid", f_setgid, "function(int:void)", OPT_SIDE_EFFECT); #if defined(HAVE_SETEUID) || defined(HAVE_SETRESUID) add_efun("seteuid", f_seteuid, "function(int:void)", OPT_SIDE_EFFECT); - add_efun("setegid", f_do_setegid, "function(int:void)", OPT_SIDE_EFFECT); + add_efun("setegid", f_setegid, "function(int:void)", OPT_SIDE_EFFECT); #endif /* HAVE_SETEUID || HAVE_SETRESUID */ add_efun("getuid", f_getuid, "function(:int)", OPT_EXTERNAL_DEPEND); @@ -801,7 +739,7 @@ void init_system_efuns(void) add_efun("gethostname", f_gethostname, "function(:string)",OPT_TRY_OPTIMIZE); #endif /* HAVE_GETHOSTNAME || HAVE_UNAME */ -#ifdef HAVE_GETHOSTBYNAME +#ifdef GETHOST_DECLARE add_efun("gethostbyname", f_gethostbyname, "function(string:array)", OPT_TRY_OPTIMIZE); add_efun("gethostbyaddr", f_gethostbyaddr, "function(string:array)", diff --git a/src/modules/system/system_machine.h.in b/src/modules/system/system_machine.h.in index bacdb76079..07467f211d 100644 --- a/src/modules/system/system_machine.h.in +++ b/src/modules/system/system_machine.h.in @@ -1,5 +1,5 @@ /* - * $Id: system_machine.h.in,v 1.2 1997/01/22 02:55:41 grubba Exp $ + * $Id: system_machine.h.in,v 1.3 1997/01/22 05:15:28 hubbe Exp $ * * System dependant definitions for the system module for Pike * @@ -89,6 +89,12 @@ /* Define if you have uname() */ #undef HAVE_UNAME +/* Define if you have solaris stype gethostbyname_r. */ +#undef HAVE_SOLARIS_GETHOSTBYNAME_R + +/* Define if you have OSF1 stype gethostbyname_r. */ +#undef HAVE_OSF1_GETHOSTBYNAME_R + /* Define if you have gethostname() */ #undef HAVE_GETHOSTNAME -- GitLab