diff --git a/src/modules/spider/Makefile.in b/src/modules/spider/Makefile.in index db8801b5aa389542c5395a117364692ed557814a..d432ac9f545e1ffd052c4f96de44792c97e65a26 100644 --- a/src/modules/spider/Makefile.in +++ b/src/modules/spider/Makefile.in @@ -4,7 +4,7 @@ PREFLAGS=-I. -I$(SRCDIR) -I$(SRCDIR)/../.. -I../.. CFLAGS=$(PREFLAGS) $(OTHERFLAGS) FILES=spider.o discdate.o stardate.o sdebug.o tree.o lock.o streamed_parser.o\ - http_parse.o encode_decode.o + http_parse.o encode_decode.o sharedmem.o spider.a: $(FILES) -rm -f spider.a diff --git a/src/modules/spider/configure b/src/modules/spider/configure index 7ad5275798fc2731fefa0a8bdc60bcdcc76db1e0..190a91edf51fc88b9838ed6c9599ec4eb94920fb 100755 --- a/src/modules/spider/configure +++ b/src/modules/spider/configure @@ -754,8 +754,52 @@ else echo "$ac_t""no" 1>&6 fi +echo $ac_n "checking for -lnsl""... $ac_c" 1>&6 +ac_lib_var=`echo nsl'_'gethostbyname | tr './+\055' '__p_'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 766 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname(); -if test x$ac_cv_lib_thread_mutex_inlock = xno ; then +int main() { return 0; } +int t() { +gethostbyname() +; return 0; } +EOF +if { (eval echo configure:778: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo nsl | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lnsl $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + + +if test x$ac_cv_lib_thread_mutex_unlock = xno ; then echo $ac_n "checking for -lpthread""... $ac_c" 1>&6 ac_lib_var=`echo pthread'_'pthread_mutex_unlock | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then @@ -764,7 +808,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpthread $LIBS" cat > conftest.$ac_ext <<EOF -#line 768 "configure" +#line 812 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -776,7 +820,7 @@ int t() { pthread_mutex_unlock() ; return 0; } EOF -if { (eval echo configure:780: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:824: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -817,13 +861,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext <<EOF -#line 821 "configure" +#line 865 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:827: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:871: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : @@ -832,13 +876,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext <<EOF -#line 836 "configure" +#line 880 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:842: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:886: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : @@ -868,12 +912,12 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 872 "configure" +#line 916 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:877: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:921: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -910,7 +954,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 914 "configure" +#line 958 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -934,7 +978,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:938: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -966,12 +1010,12 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 970 "configure" +#line 1014 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:975: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1019: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -1002,7 +1046,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1006 "configure" +#line 1050 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -1026,7 +1070,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:1030: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:1074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1059,7 +1103,7 @@ if eval "test \"`echo '$''{'lpc_cv_timezone'+set}'`\" = set"; then else cat > conftest.$ac_ext <<EOF -#line 1063 "configure" +#line 1107 "configure" #include "confdefs.h" #include <time.h> @@ -1076,7 +1120,7 @@ int t() { ; return 0; } EOF -if { (eval echo configure:1080: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:1124: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* lpc_cv_timezone='localtime' diff --git a/src/modules/spider/configure.in b/src/modules/spider/configure.in index df06fbc9380c59b61199db1f7fc49383452a53d3..0cfdbb6ec02daa6de13bc1f2608296894bbdd5f1 100644 --- a/src/modules/spider/configure.in +++ b/src/modules/spider/configure.in @@ -6,8 +6,9 @@ AC_PROG_RANLIB AC_CHECK_LIB(thread, mutex_unlock) AC_CHECK_LIB(socket, socket) +AC_CHECK_LIB(nsl, gethostbyname) -if test x$ac_cv_lib_thread_mutex_inlock = xno ; then +if test x$ac_cv_lib_thread_mutex_unlock = xno ; then AC_CHECK_LIB(pthread, pthread_mutex_unlock) fi diff --git a/src/modules/spider/dependencies b/src/modules/spider/dependencies deleted file mode 100644 index 51cda8f59bcc2b8c3b85877e9a1daceb47d5369f..0000000000000000000000000000000000000000 --- a/src/modules/spider/dependencies +++ /dev/null @@ -1,39 +0,0 @@ -discdate.o: discdate.c stralloc.h types.h \ - machine.h global.h config.h port.h \ - macros.h object.h svalue.h add_efun.h \ - hashtable.h las.h dynamic_buffer.h program.h \ - interpret.h mapping.h array.h builtin_efuns.h \ - spider.h -lock.o: lock.c stralloc.h types.h machine.h \ - global.h config.h port.h macros.h \ - object.h svalue.h add_efun.h hashtable.h \ - las.h dynamic_buffer.h program.h interpret.h \ - mapping.h array.h builtin_efuns.h -sdebug.o: sdebug.c stralloc.h types.h machine.h \ - global.h config.h port.h macros.h \ - object.h svalue.h add_efun.h hashtable.h \ - las.h dynamic_buffer.h program.h interpret.h \ - mapping.h array.h builtin_efuns.h spider.h -spider.o: spider.c machine.h stralloc.h types.h \ - global.h config.h port.h macros.h \ - object.h svalue.h add_efun.h hashtable.h \ - las.h dynamic_buffer.h program.h interpret.h \ - mapping.h array.h builtin_efuns.h spider.h conf.h \ - streamed_parser.h -stardate.o: stardate.c stralloc.h types.h \ - machine.h global.h config.h port.h \ - macros.h object.h svalue.h add_efun.h \ - hashtable.h las.h dynamic_buffer.h program.h \ - interpret.h mapping.h array.h builtin_efuns.h \ - spider.h -streamed_parser.o: streamed_parser.c stralloc.h types.h \ - machine.h global.h config.h port.h \ - macros.h object.h svalue.h add_efun.h \ - hashtable.h las.h dynamic_buffer.h program.h \ - interpret.h mapping.h array.h builtin_efuns.h \ - streamed_parser.h -tree.o: tree.c machine.h stralloc.h types.h \ - global.h config.h port.h macros.h \ - object.h svalue.h add_efun.h hashtable.h \ - las.h dynamic_buffer.h program.h interpret.h \ - mapping.h array.h builtin_efuns.h spider.h diff --git a/src/modules/spider/encode_decode.c b/src/modules/spider/encode_decode.c index 4004593f3c5f33ad192bbe55441f49aad2f6a99f..3536893e3941450f03650d0db157bd6ac1203b9e 100644 --- a/src/modules/spider/encode_decode.c +++ b/src/modules/spider/encode_decode.c @@ -14,20 +14,64 @@ #include "spider.h" -#define strcat(buff, s, l) low_my_binary_strcat(s, l, buff) -#define addchar(buff, t) low_my_putchar(t,buff); +#define strcat(buff, s, l) low_my_binary_strcat((s), (l), (buff)) +#define addchar(buff, t) low_my_putchar((t),(buff)) -INLINE static void addint(dynamic_buffer *buff, int t) + +/* + byte 0 byte 1 byte 2 byte 3 byte 4 +int x 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 +----------------------------------------------------------------------------------------- +< 1<<7 1 x x x x x x x +< 1<<8 0 0 0 0 0 0 0 1 x x x x x x x x +< 1<<16 0 0 0 0 0 0 1 0 x x x x x x x x x x x x x x x x +< 1<<24 0 0 0 0 0 0 1 1 x x x x x x x x x x x x x x x x x x x x x x x x +< 1<<32 0 0 0 0 0 1 0 0 x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + + +< 0 0 0 0 0 1 as above +*/ + +INLINE static void add_int_to_buffer(dynamic_buffer *buff, INT32 t) { - t = htonl(t); - strcat(buff, (char *)(&t), sizeof(int)); -} + int negbit = 0; + if((unsigned INT32)t < 0x80) + { + addchar(buff, (unsigned char)((((unsigned INT32)t)|0x80)&0xff)); + return; + } -static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct processing *p) + if(t<0) + { + negbit = 8; + t = -t; + } + + if((unsigned INT32)t < 0x100) { + addchar(buff, 1|negbit); + addchar(buff, (t&255)); + } else if((unsigned INT32)t < 0x10000) { + addchar(buff, 2|negbit); + addchar(buff, (t>>8)&255); + addchar(buff, t&255); + } else if((unsigned INT32)t < 0x1000000) { + addchar(buff, 3|negbit); + addchar(buff, (t>>16)&255); + addchar(buff, (t>>8)&255); + addchar(buff, t&255); + } else { + addchar(buff, 4|negbit); + t = htonl(t); + strcat(buff, (char *)(&t), 4); + } +} + +static void rec_save_value(struct svalue *val, dynamic_buffer *buff, + struct processing *p) { struct processing doing; - int i; + INT32 i; if((1<<val->type)&BIT_COMPLEX) { @@ -41,15 +85,12 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc } -#if 0 - addchar(buff, ((unsigned char)(val->type))); -#else - addint(buff, val->type); -#endif + add_int_to_buffer(buff, val->type); + switch(val->type) { case T_ARRAY: - addint(buff, val->u.array->size); + add_int_to_buffer(buff, val->u.array->size); for(i=0; i<val->u.array->size; i++) rec_save_value(ITEM(val->u.array)+i, buff, p); break; @@ -61,7 +102,7 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc push_mapping(val->u.mapping); f_values(1); - addint(buff, sp[-2].u.array->size); + add_int_to_buffer(buff, sp[-2].u.array->size); for(i=0; i<sp[-2].u.array->size; i++) { rec_save_value(ITEM(sp[-2].u.array)+i, buff, p); /* indices */ @@ -71,7 +112,7 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc break; case T_LIST: - addint(buff, val->u.list->ind->size); + add_int_to_buffer(buff, val->u.list->ind->size); for(i=0; i<val->u.list->ind->size; i++) rec_save_value(ITEM(val->u.list->ind)+i, buff, p); break; @@ -82,10 +123,10 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc APPLY_MASTER("nameof", 1); if(sp[-1].type == T_STRING) { - addint(buff, sp[-1].u.string->len); + add_int_to_buffer(buff, sp[-1].u.string->len); strcat(buff, sp[-1].u.string->str, sp[-1].u.string->len); } else { - addint(buff, 0); + add_int_to_buffer(buff, 0); } pop_stack(); break; @@ -99,10 +140,10 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc APPLY_MASTER("nameof", 1); if(sp[-1].type == T_STRING) { - addint(buff, sp[-1].u.string->len); + add_int_to_buffer(buff, sp[-1].u.string->len); strcat(buff, sp[-1].u.string->str, sp[-1].u.string->len); } else { - addint(buff, 0); + add_int_to_buffer(buff, 0); } pop_stack(); break; @@ -113,28 +154,28 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc APPLY_MASTER("nameof", 1); if(sp[-1].type == T_STRING) { - addint(buff, sp[-1].u.string->len); + add_int_to_buffer(buff, sp[-1].u.string->len); strcat(buff, sp[-1].u.string->str, sp[-1].u.string->len); } else { - addint(buff, 0); + add_int_to_buffer(buff, 0); } pop_stack(); break; case T_STRING: - addint(buff, val->u.string->len); + add_int_to_buffer(buff, val->u.string->len); strcat(buff, val->u.string->str, val->u.string->len); break; case T_INT: - addint(buff, val->u.integer); + add_int_to_buffer(buff, val->u.integer); break; case T_FLOAT: /* How to encode a float _correctly_? */ - if(sizeof(int) < sizeof(float)) /* FIXME FIXME FIXME FIXME */ + if(sizeof(INT32) < sizeof(float)) /* FIXME FIXME FIXME FIXME */ error("Float architecture not supported.\n"); - addint(buff, val->u.integer); + add_int_to_buffer(buff, val->u.integer); break; } } @@ -155,37 +196,62 @@ void f_encode_value(INT32 args) push_string(low_free_buf(&buff)); } -static int extract_int(char **v, unsigned int *l) +static unsigned char extract_char(char **v, unsigned INT32 *l) { - unsigned int j; - int t=0; - char *c = (char *)(&t); + if(!*l) error("Format error, not enough place for char.\n"); + else (*l)--; + (*v)++; + return ((unsigned char *)(*v))[-1]; +} - if(*l<sizeof(int)) - error("Format error, not enough place for integer.\n"); - for(j=0; j<sizeof(int); j++) - c[j] = ((*v)[j]); +static INT32 extract_int(char **v, unsigned INT32 *l) +{ + unsigned INT32 j; + INT32 t=0; + char *c = (char *)(&t); - t = ntohl(t); + if(!*l) + error("Format error: not enough place for short integer.\n"); - *l -= sizeof(int); - *v += sizeof(int); + if((**v) & 0x80) /* (very) Short int. */ + return extract_char(v,l) & 0x7f; - return t; -} + switch(extract_char(v,l)) + { + case 1: /* char */ + return extract_char(v,l); + + case 2: /* word */ + return (extract_char(v,l)<<8) | (extract_char(v,l)); + + case 3: /* 24 bit thingie */ + return (extract_char(v,l)<<16) | (extract_char(v,l)<<8) | extract_char(v,l); -static unsigned char extract_char(char **v, unsigned int *l) -{ - if(!*l) error("Format error, not enough place for char.\n"); - else (*l)--; - *v++; - return (*v)[-1]; + case 4: /* 32 bit number */ + return (extract_char(v,l)<<24) | + (extract_char(v,l)<<16) | (extract_char(v,l)<<8) | + extract_char(v,l); + + case 9: /* -char */ + return -extract_char(v,l); + case 10: /* -word */ + return -((extract_char(v,l)<<8) | (extract_char(v,l))); + case 11: /* -24 bit */ + return -((extract_char(v,l)<<16) | (extract_char(v,l)<<8) | extract_char(v,l)); + case 12: /* -32 bit thingie */ + return -((extract_char(v,l)<<24) | + (extract_char(v,l)<<16) | (extract_char(v,l)<<8) | + extract_char(v,l)); + + } + error("Format Error: Error in format string, invalid integer.\n"); + return t; } -static void rec_restore_value(char **v, int *l) +static void rec_restore_value(char **v, INT32 *l) { - int t,i; + INT32 t,i; switch(extract_int(v,l)) { @@ -195,7 +261,7 @@ static void rec_restore_value(char **v, int *l) case T_FLOAT: /* How to encode a float _correctly_? */ - if(sizeof(int) < sizeof(float)) /* FIXME FIXME FIXME FIXME */ + if(sizeof(INT32) < sizeof(float)) /* FIXME FIXME FIXME FIXME */ error("Float architecture not supported.\n"); push_int(extract_int(v,l)); /* WARNING! */ sp[-1].type = T_FLOAT; @@ -205,7 +271,7 @@ static void rec_restore_value(char **v, int *l) t = extract_int(v,l); if(*l < t) error("Format error, string to short\n"); push_string(make_shared_binary_string(*v, t)); - *l-= t; *v+= t; + (*l)-= t; (*v)+= t; return; case T_ARRAY: @@ -235,21 +301,21 @@ static void rec_restore_value(char **v, int *l) case T_OBJECT: t = extract_int(v,l); push_string(make_shared_binary_string(*v, t)); - *l-= t; *v+= t; + (*l) -= t; (*v) += t; APPLY_MASTER("objectof", 1); return; case T_FUNCTION: t = extract_int(v,l); push_string(make_shared_binary_string(*v, t)); - *l-= t; *v+= t; + (*l) -= t; (*v) += t; APPLY_MASTER("functionof", 1); return; case T_PROGRAM: t = extract_int(v,l); push_string(make_shared_binary_string(*v, t)); - *l-= t; *v+= t; + (*l) -= t; (*v) += t; APPLY_MASTER("programof", 1); return; @@ -262,7 +328,7 @@ void f_decode_value(INT32 args) { struct lpc_string *s; char *v; - int l; + INT32 l; if(args != 1 || (sp[-1].type != T_STRING)) error("Illegal argument to restore_value(STRING)\n"); diff --git a/src/modules/spider/lock.c b/src/modules/spider/lock.c index 771a109dca768ce789754f5d1100eef57af806dc..54c9642d5d6bf23e652d2683f0bc129bc261f5bd 100644 --- a/src/modules/spider/lock.c +++ b/src/modules/spider/lock.c @@ -32,59 +32,7 @@ #include <sys/stat.h> #include <errno.h> - -#ifdef HAVE_MMAP -char *my_shared_malloc(int size) -{ - int fd; - char *pointer; - char *scratch; - - fd = open("/tmp/.spinnerlock", O_RDWR|O_CREAT, 0777); - if(fd == -1) - { - perror("my_shared_malloc::open"); - error("my_shared_malloc(): Can't open() /tmp/.spinnerlock.\n"); - } - unlink("/tmp/.spinnerlock"); - - scratch = malloc(size+sizeof(int)); - write(fd, scratch, size+sizeof(int)); - free(scratch); - - pointer = mmap(NULL,(size+sizeof(int)),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); - if(pointer==MAP_FAILED) - { - perror("my_shared_malloc::mmap"); - error("my_shared_malloc(): Can't mmap() /tmp/.spinnerlock.\n"); - } - close(fd); - ((int *)pointer)[0] = size; - return pointer + sizeof(int); -} - -void *my_shared_free(char *pointer) -{ - int size; - pointer -= sizeof(int); - size = *(int *)pointer; - if(munmap( pointer, size ) < 0) - perror("my_shared_free::munmap"); -} - -#else -/* Should look for shmop, probably */ -char *my_shared_malloc(int size) -{ - return malloc(size); /* Incorrect, really. */ -} - -void *my_shared_free(char *pointer) -{ - free(pointer); -} -#endif - +#include "sharedmem.h" #ifdef HAVE_THREAD_H typedef mutex_t mylock_t; @@ -92,22 +40,27 @@ typedef mutex_t mylock_t; typedef pthread_mutex_t mylock_t; #endif - +#define LOCK_HASH_TABLE_SIZE ((1<<10)-1) /* MUST BE ((1<<n)-1), 1<n<30 */ + struct _lock { mylock_t lock; /* MUST BE FIRST IN THE STRUCT */ int id; struct _lock *next; + struct _lock *next_hash; + struct _lock *prev_hash; struct _lock *prev; } *first_lock=NULL, *last_lock=NULL; +struct _lock *lock_hash_table[LOCK_HASH_TABLE_SIZE+1]; + mylock_t *findlock( int id ) { - struct _lock *current = first_lock; + struct _lock *current = lock_hash_table[ id & LOCK_HASH_TABLE_SIZE ]; while(current) { if(current->id == id) return ¤t->lock; - current = current->next; + current = current->next_hash; } return NULL; } @@ -115,7 +68,8 @@ mylock_t *findlock( int id ) mylock_t *newlock( int id ) { struct _lock *lock; - lock = (struct _lock *)my_shared_malloc( sizeof( struct _lock ) ); + struct _lock *tmp=NULL; + lock = (struct _lock *)shared_malloc( sizeof( struct _lock ) ); lock->id = id; if(!first_lock) { @@ -125,8 +79,15 @@ mylock_t *newlock( int id ) lock->prev = last_lock; lock->next = NULL; last_lock->next = lock; - last_lock = NULL; + last_lock = lock; } + if( tmp = lock_hash_table[ id & LOCK_HASH_TABLE_SIZE] ) + tmp->prev_hash = lock; + + lock_hash_table[ id & LOCK_HASH_TABLE_SIZE] = lock; + lock->next_hash = tmp; + lock->prev_hash = NULL; + #ifdef HAVE_MUTEX_UNLOCK mutex_init( &lock->lock, USYNC_PROCESS, 0 ); #else @@ -172,12 +133,19 @@ void freelock( mylock_t *lock ) if(rlock == last_lock) last_lock = rlock->prev; + if(rlock->next_hash) + rlock->next_hash->prev_hash= rlock->prev_hash; + if(rlock->prev_hash) + rlock->prev_hash->next_hash= rlock->next_hash; + if(lock_hash_table[ rlock->id & LOCK_HASH_TABLE_SIZE] == rlock) + lock_hash_table[ rlock->id & LOCK_HASH_TABLE_SIZE] = rlock->next_hash; + #ifdef HAVE_MUTEX_UNLOCK mutex_destroy( lock ); #else pthread_mutex_destroy( lock ); #endif - my_shared_free( (char *)lock ); + shared_free( (char *)lock ); } void f_lock(INT32 args) @@ -206,18 +174,17 @@ void f_newlock(INT32 args) { int res; int id; - mylock_t *lock; - if(!args) - error("You have to supply the lock-key.\n"); - id = sp[-1].u.integer; - pop_n_elems(args); - if(lock = findlock( id )) + if(args) { - push_int(0); - return; - } - lock = newlock( id ); - push_int(id); + id = sp[-1].u.integer; + pop_n_elems(args); + } else + id = 0; + while(findlock( id )) + id+=rand(); /* This should limit the number of times we have to try. */ + + newlock( id ); + push_int( id ); } diff --git a/src/modules/spider/spider.c b/src/modules/spider/spider.c index 78e29566fa599def691c5284311b7a52751b9239..ddb003b37bf3fab638ccad44f15e4bcf3bcf610f 100644 --- a/src/modules/spider/spider.c +++ b/src/modules/spider/spider.c @@ -1137,9 +1137,10 @@ void f_get_all_active_fd(INT32 args) { int i,fds; struct stat foo; + pop_n_elems(args); for (i=fds=0; i<MAX_OPEN_FILEDESCRIPTORS; i++) - if (!fstat(i,&foo)) + if(!fstat(i,&foo)) { push_int(i); fds++; @@ -1190,39 +1191,54 @@ void f_mark_fd(INT32 args) struct sockaddr_in addr; char *tmp; char buf[20]; + struct stat fs; + pop_stack(); - if(fd_marks[fd]) + if(!fstat(fd,&fs)) { - fd_marks[fd]->refs++; - push_string(fd_marks[fd]); + if(fd_marks[fd]) + { + fd_marks[fd]->refs++; + push_string(fd_marks[fd]); + } else { + push_text(""); + } + + len=sizeof(addr); + if(! getsockname(fd, (struct sockaddr *) &addr, &len)) + { + tmp=inet_ntoa(addr.sin_addr); + push_string(make_shared_string(" Local:")); + push_string(make_shared_string(tmp)); + sprintf(buf,".%d",(int)(ntohs(addr.sin_port))); + push_string(make_shared_string(buf)); + f_add(4); + } + + if(! getpeername(fd, (struct sockaddr *) &addr, &len)) + { + push_string(make_shared_string(" Remote:")); + tmp=inet_ntoa(addr.sin_addr); + push_string(make_shared_string(tmp)); + sprintf(buf,".%d",(int)(ntohs(addr.sin_port))); + push_string(make_shared_string(buf)); + f_add(4); + } + return; } else { + if(fd_marks[fd]) + { + free_string(fd_marks[fd]); + fd_marks[fd]=0; + } push_int(0); + return; } - - len=sizeof(addr); - if(! getsockname(fd, (struct sockaddr *) &addr, &len)) - { - tmp=inet_ntoa(addr.sin_addr); - push_string(make_shared_string(" Local:")); - push_string(make_shared_string(tmp)); - sprintf(buf,".%d",(int)(ntohs(addr.sin_port))); - push_string(make_shared_string(buf)); - f_add(4); - } - - if(! getpeername(fd, (struct sockaddr *) &addr, &len)) - { - push_string(make_shared_string(" Remote:")); - tmp=inet_ntoa(addr.sin_addr); - push_string(make_shared_string(tmp)); - sprintf(buf,".%d",(int)(ntohs(addr.sin_port))); - push_string(make_shared_string(buf)); - f_add(4); - } - - return; } + + + s=sp[-args+1].u.string; s->refs++; if(fd_marks[fd]) @@ -1537,6 +1553,32 @@ void f_alarm(INT32 args) } #endif +void f_fcgi_create_listen_socket(INT32 args) +{ + int fd, true; + struct sockaddr_in addr; + if(!args) + error("No args?\n"); + + true=1; + fd=socket(AF_INET, SOCK_STREAM, 0); + if(fd < 0) + error("socket() failed.\n"); + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&true, sizeof(int)); + get_inet_addr(&addr, "127.0.0.1"); + addr.sin_port = htons( ((u_short)sp[-args].u.integer) ); + if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0 || + listen(fd, 4) < 0 ) + error("Failed to bind() or listen\n"); + if(fd) + { + dup2(fd, 0); + close(fd); + } + pop_n_elems(args); + push_int(1); +} + void f_decode_value(INT32 args); void f_encode_value(INT32 args); @@ -1552,11 +1594,15 @@ void init_spider_efuns(void) make_shared_string("POST"); #endif + add_efun("fcgi_create_listen_socket", f_fcgi_create_listen_socket, + "function(int:int)", OPT_SIDE_EFFECT); + + #if defined(HAVE_PTHREAD_MUTEX_UNLOCK) || defined(HAVE_MUTEX_UNLOCK) add_efun("_lock", f_lock, "function(int:int)", OPT_SIDE_EFFECT); add_efun("_unlock", f_unlock, "function(int:int)", OPT_SIDE_EFFECT); add_efun("_free_lock", f_freelock, "function(int:int)", OPT_SIDE_EFFECT); - add_efun("_new_lock", f_newlock, "function(int:int)", OPT_SIDE_EFFECT); + add_efun("_new_lock", f_newlock, "function(int|void:int)", OPT_SIDE_EFFECT); #endif add_efun("encode_value", f_encode_value, "function(mixed:string)",