/* Decode %XX encoded strings.*/ INLINE struct pike_string *http_decode_string(unsigned char *foo, int len) { int proc, nlen=0; unsigned char *bar,*end; struct pike_string *newstr; bar = foo; end = foo + len; /* count '%' characters */ for (proc =0 ; foo < end; ) if (*(foo++) == '%') { proc=1; break; } if (!proc) { return make_shared_binary_string((char *)bar, len); } foo = bar; for (proc=0; bar < end; proc++) { if (*bar=='%') { if (bar < end-2) foo[proc]=(( (bar[1] < 'A') ? (bar[1] & 15) :(( bar[1] + 9) &15)) << 4)| ((bar[2] < 'A') ? (bar[2] & 15) : ((bar[2] + 9)& 15)); else foo[proc]=0; bar+=3; nlen++; } else { foo[proc]=*(bar++); nlen++; } } foo[proc] = '\0'; return make_shared_binary_string((char *)foo, nlen); }
static void push_log_entry(struct log_entry *le) { struct object *o = clone_object( aap_log_object_program, 0 ); struct log_object *lo = (struct log_object*)o->storage; lo->time = le->t; lo->sent_bytes = le->sent_bytes; lo->reply = le->reply; lo->received_bytes = le->received_bytes; lo->raw = make_shared_binary_string(le->raw.str, le->raw.len); lo->url = make_shared_binary_string(le->url.str, le->url.len); lo->method = make_shared_binary_string(le->method.str, le->method.len); lo->protocol = le->protocol; le->protocol->refs++; #ifdef HAVE_INET_NTOP { char buffer[64]; lo->from = make_shared_string( inet_ntop(SOCKADDR_FAMILY(le->from), SOCKADDR_IN_ADDR(le->from), buffer, sizeof(buffer)) ); } #else lo->from = make_shared_string( inet_ntoa(*SOCKADDR_IN_ADDR(le->from)) ); #endif push_object( o ); }
/*! @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@}. */ static void f_all(INT32 args) { int err, num=0; char *retval, *retkey; int retlen, retkeylen; char *map; struct mapping *res_map; check_all_args(NULL, args, BIT_STRING, 0); 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 ); YPERROR( err ); } this->last_size = num; pop_n_elems(args); push_mapping( res_map ); }
/*! @decl void map(string map, function(string, string:void) fun) *! *! For each entry in @[map], call the function specified by @[fun]. *! *! @[fun] will get two arguments, the first being the key, and the *! 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@}. */ static void f_map(INT32 args) { int err; char *retval, *retkey; int retlen, retkeylen; char *map; struct svalue *f = &sp[-1]; check_all_args(NULL, args, BIT_STRING, BIT_FUNCTION|BIT_ARRAY, 0 ); 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) YPERROR( err ); }
static void f_extension( INT32 args ) { int i, found=0; struct pike_string *src; char *orig, *ptr; if(Pike_sp[-1].type != T_STRING) SIMPLE_BAD_ARG_ERROR("Caudium.extension", 1, "string"); src = Pike_sp[-1].u.string; if(src->size_shift) { Pike_error("Caudium.extension(): Only 8-bit strings allowed.\n"); } orig = src->str; for(i = src->len-1; i >= 0; i--) { if(orig[i] == 0x2E) { found = 1; i++; break; } } if(found) { int len = src->len - i; switch(orig[src->len-1]) { case '#': case '~': /* Remove unix backup extension */ len--; } pop_n_elems(args); push_string(make_shared_binary_string(orig+i, len)); } else { pop_n_elems(args); push_text(""); } }
/* php_roxen_set_header() sets a header in the header mapping. Called in a * thread safe manner from php_roxen_sapi_header_handler. */ static void php_roxen_set_header(char *header_name, char *value, char *p) { struct svalue hsval; struct pike_string *hval, *ind, *hind; struct mapping *headermap; struct svalue *s_headermap; #ifdef ROXEN_USE_ZTS GET_THIS(); #endif hval = make_shared_string(value); ind = make_shared_string(" _headers"); hind = make_shared_binary_string(header_name, (int)(p - header_name)); s_headermap = low_mapping_string_lookup(REQUEST_DATA, ind); if(!s_headermap) { struct svalue mappie; mappie.type = PIKE_T_MAPPING; headermap = allocate_mapping(1); mappie.u.mapping = headermap; mapping_string_insert(REQUEST_DATA, ind, &mappie); free_mapping(headermap); } else headermap = s_headermap->u.mapping; hsval.type = PIKE_T_STRING; hsval.u.string = hval; mapping_string_insert(headermap, hind, &hsval); free_string(hval); free_string(ind); free_string(hind); }
/*! @decl array(string) _xpm_trim_rows(array(string) rows) */ void f__xpm_trim_rows( INT32 args ) { struct array *a; int i,j=0; get_all_args("_xpm_trim_rows", args, "%a", &a ); for(i=0; i<a->size; i++) { int len,start; struct pike_string *s = a->item[i].u.string; if(a->item[i].type != T_STRING) Pike_error("Array must be array(string).\n"); if(s->len > 4) { for(start=0; start<s->len; start++) if(s->str[start] == '/' || s->str[start] == '"') break; if(s->str[start] == '/') continue; for(len=start+1; len<s->len; len++) if(s->str[len] == '"') break; if(len>=s->len || s->str[len] != '"') continue; free_string(a->item[j].u.string); a->item[j++].u.string=make_shared_binary_string(s->str+start+1,len-start-1); } } pop_n_elems(args-1); }
static int get_next_header(unsigned char *heads, int len, struct mapping *headermap) { int data, count, colon, count2=0; struct svalue skey, sval; skey.type = T_STRING; sval.type = T_STRING; for(count=0, colon=0; count < len; count++) { switch(heads[count]) { case ':': colon = count; data = colon + 1; for(count2 = data; count2 < len; count2++) /* find end of header data */ if(heads[count2] == '\r') break; while(heads[data] == ' ') data++; skey.u.string = lowercase(heads, colon); if (skey.u.string == NULL) return -1; sval.u.string = make_shared_binary_string((char *)(heads+data), count2 - data); mapping_insert(headermap, &skey, &sval); count = count2; free_string(skey.u.string); free_string(sval.u.string); break; case '\n': /*printf("Returning %d read\n", count);*/ return count+1; } } return count; }
INLINE #endif static struct pike_string *lowercase(unsigned char *str, INT32 len) { unsigned char *p, *end; unsigned char *mystr; struct pike_string *pstr; #ifdef HAVE_ALLOCA mystr = (unsigned char *)alloca((len + 1) * sizeof(char)); #else mystr = (unsigned char *)malloc((len + 1) * sizeof(char)); #endif if (mystr == NULL) return (struct pike_string *)NULL; MEMCPY(mystr, str, len); end = mystr + len; mystr[len] = '\0'; for(p = mystr; p < end; p++) { if(*p >= 'A' && *p <= 'Z') { *p |= 32; /* OR is faster than addition and we just need * to set one bit :-). */ } } pstr = make_shared_binary_string((char *)mystr, len); #ifndef HAVE_ALLOCA free(mystr); #endif return pstr; }
static int php_roxen_low_ub_write(const char *str, uint str_length TSRMLS_DC) { int sent_bytes = 0; struct pike_string *to_write = NULL; #ifdef ROXEN_USE_ZTS GET_THIS(); #endif if(!MY_FD_OBJ->prog) { PG(connection_status) = PHP_CONNECTION_ABORTED; zend_bailout(); return -1; } to_write = make_shared_binary_string(str, str_length); push_string(to_write); safe_apply(MY_FD_OBJ, "write", 1); if(Pike_sp[-1].type == PIKE_T_INT) sent_bytes = Pike_sp[-1].u.integer; pop_stack(); if(sent_bytes != str_length) { /* This means the connection is closed. Dead. Gone. *sniff* */ php_handle_aborted_connection(); } return sent_bytes; }
static void image_ttf_face__names(INT32 args) { int ns,res; TT_UShort i; TT_Face face=THISf->face; pop_n_elems(args); if ((ns=TT_Get_Name_Count(face))==-1) Pike_error("Image.TTF.Face->names(): Illegal face handler\n"); for (i=0; i<ns; i++) { unsigned short platformID,encodingID,languageID,nameID; TT_UShort length; char *stringPtr; if ((res=TT_Get_Name_ID(face,i, &platformID,&encodingID,&languageID,&nameID))) my_tt_error("Image.TTF.Face->names()","TT_Get_Name_ID: ",res); push_int(platformID); push_int(encodingID); push_int(languageID); push_int(nameID); if ((res=TT_Get_Name_String(face,i,&stringPtr,&length))) my_tt_error("Image.TTF.Face->names()","TT_Get_Name_String: ",res); push_string(make_shared_binary_string(stringPtr,length)); f_aggregate(5); } f_aggregate(ns); }
/*! @decl array(string) split(string s) *! Works as @[match], but returns an array of the strings that *! matched the subregexps. Subregexps are those contained in "( )" in *! the regexp. Subregexps that were not matched will contain zero. *! If the total regexp didn't match, zero is returned. *! *! @bugs *! You can currently only have 39 subregexps. *! *! @bugs *! The current implementation doesn't support searching *! in strings containing the NUL character or any *! wide character. *! *! @seealso *! @[match] */ static void regexp_split(INT32 args) { struct pike_string *s; struct regexp *r; get_all_args("Regexp.SimpleRegexp->split", args, "%S", &s); if(pike_regexec(r=THIS->regexp, s->str)) { int i,j; add_ref(s); pop_n_elems(args); for(j=i=1;i<NSUBEXP;i++) { if(!r->startp[i] || !r->endp[i]) { push_int(0); }else{ push_string(make_shared_binary_string(r->startp[i], r->endp[i]-r->startp[i])); j=i; } } if(j<i-1) pop_n_elems(i-j-1); push_array(aggregate_array(j)); free_string(s); }else{ pop_n_elems(args); push_int(0); } }
INLINE #endif static struct pike_string *url_decode(unsigned char *str, int len, int exist) { int nlen = 0, i; unsigned char *mystr; /* Work string */ unsigned char *ptr, *end, *prc; /* beginning and end pointers */ unsigned char *endl2; /* == end-2 - to speed up a bit */ struct pike_string *newstr; #ifdef HAVE_ALLOCA mystr = (unsigned char *)alloca((len + 2) * sizeof(char)); #else mystr = (unsigned char *)malloc((len + 2) * sizeof(char)); #endif if (mystr == NULL) return (struct pike_string *)NULL; if(exist) { ptr = mystr+1; *mystr = '\0'; exist = 1; } else ptr = mystr; MEMCPY(ptr, str, len); endl2 = end = ptr + len; endl2 -= 2; ptr[len] = '\0'; for (i = exist; ptr < end; i++) { switch(*ptr) { case '%': if (ptr < endl2) mystr[i] = (((ptr[1] < 'A') ? (ptr[1] & 15) :(( ptr[1] + 9) &15)) << 4)| ((ptr[2] < 'A') ? (ptr[2] & 15) : ((ptr[2] + 9)& 15)); else mystr[i] = '\0'; ptr+=3; nlen++; break; case '+': ptr++; mystr[i] = ' '; nlen++; break; default: mystr[i] = *(ptr++); nlen++; } } newstr = make_shared_binary_string((char *)mystr, nlen+exist); #ifndef HAVE_ALLOCA free(mystr); #endif return newstr; }
INLINE int multiset_string_lookup(struct multiset *multi, char *str) { INT32 member; struct svalue sval; struct pike_string *pstr; pstr = make_shared_binary_string(str, strlen(str)); sval.type = T_STRING; sval.u.string = pstr; member = multiset_member(multi, &sval); free_string(pstr); return member; }
static void push_token( const char * from, int start, int end ) { struct array *a = Pike_sp[-1].u.array; struct pike_string *token = make_shared_binary_string(from+start, end-start+1); if( a->malloced_size < a->size+1 ) { Pike_sp[-1].u.array = a = resize_array( a, a->size+1 ); a->size--; } a->item[a->size].type = PIKE_T_STRING; a->item[a->size].subtype = 0; a->item[a->size].u.string = token; a->size++; }
/* php_caudium_set_header() sets a header in the header mapping. Called in a * thread safe manner from php_caudium_sapi_header_handler. */ INLINE static void php_caudium_set_header(char *header_name, char *value, char *p) { struct svalue hsval; struct pike_string *hval, *ind, *hind; struct mapping *headermap; struct svalue *s_headermap, *soldval; int vallen; GET_THIS(); /* hval = make_shared_string(value); */ ind = make_shared_string(" _headers"); hind = make_shared_binary_string(header_name, (int)(p - header_name)); s_headermap = low_mapping_string_lookup(REQUEST_DATA, ind); if(!s_headermap || s_headermap->type != PIKE_T_MAPPING) { struct svalue mappie; mappie.type = PIKE_T_MAPPING; headermap = allocate_mapping(1); mappie.u.mapping = headermap; mapping_string_insert(REQUEST_DATA, ind, &mappie); free_mapping(headermap); hval = make_shared_string(value); } else { headermap = s_headermap->u.mapping; soldval = low_mapping_string_lookup(headermap, hind); vallen = strlen(value); if(soldval != NULL && soldval->type == PIKE_T_STRING && soldval->u.string->size_shift == 0) { /* Existing, valid header. Prepend.*/ hval = begin_shared_string(soldval->u.string->len + 1 + vallen); MEMCPY(hval->str, soldval->u.string->str, soldval->u.string->len); STR0(hval)[soldval->u.string->len] = '\0'; MEMCPY(hval->str+soldval->u.string->len+1, value, vallen); hval = end_shared_string(hval); } else { hval = make_shared_string(value); } } hsval.type = PIKE_T_STRING; hsval.u.string = hval; mapping_string_insert(headermap, hind, &hsval); free_string(hval); free_string(ind); free_string(hind); }
/* string get_data() */ static void f_get_data(INT32 args) { char *data; int len; GET_PIKE_SEARCH(); if (args) Pike_error("Too many arguments to Search->get_data()\n"); THREADS_ALLOW(); len = avs_search_getdatalen(search->handle); data = avs_search_getdata(search->handle); THREADS_DISALLOW(); push_string(make_shared_binary_string(data, len)); }
static INLINE int do_write(char *buf, int buf_len) { int fd, written = 0; fd = THIS->outp->fd; write_retry: if(fd != -1) { DERR(fprintf(stderr, "do_write() to real fd\n")); THREADS_ALLOW(); written = fd_write(fd, buf, buf_len); THREADS_DISALLOW(); } else { DERR(fprintf(stderr, "do_write() to fake fd\n")); push_string(make_shared_binary_string(buf, buf_len)); apply_low(THIS->outp->file, THIS->outp->write_off, 1); if(Pike_sp[-1].type != T_INT) { written = -1; } else { written = Pike_sp[-1].u.integer; } pop_stack(); } if(written < 0) { DERR(fprintf(stderr, "write returned -1...\n")); switch(errno) { default: DERR(perror("Error while writing")); finished(); return -1; /* -1 == write failed and that's it */ case EINTR: /* interrupted by signal - try again */ DERR(fprintf(stderr, "write -> EINTR = retry.\n")); goto write_retry; case EWOULDBLOCK: DERR(fprintf(stderr, "would block.\n")); return 0; /* Treat this as if we wrote no data */ } } else { DERR(fprintf(stderr, "Wrote %d bytes of %d\n", written, buf_len)); THIS->written += written; } return written; }
static void pextsIgnorableWhitespace(void *ctx, const xmlChar *ch, int len) { DBG_FUNC_ENTER(); if (CB_ABSENT(ignorableWhitespaceSAX)) { DBG_FUNC_LEAVE(); return; } THIS->ctxt = (xmlParserCtxtPtr)ctx; push_object(this_object()); if (ch && len) push_string(make_shared_binary_string((const char*)ch, (size_t) len)); else push_int(0); push_svalue(&THIS->user_data); CB_CALL(ignorableWhitespaceSAX, 3); pop_stack(); DBG_FUNC_LEAVE(); }
static void pextsCdataBlock(void *ctx, const xmlChar *value, int len) { DBG_FUNC_ENTER(); if (CB_ABSENT(cdataBlockSAX)) { DBG_FUNC_LEAVE(); return; } THIS->ctxt = (xmlParserCtxtPtr)ctx; push_object(this_object()); if (value) push_string(make_shared_binary_string((const char*)value, (size_t) len)); else push_int(0); push_svalue(&THIS->user_data); CB_CALL(cdataBlockSAX, 3); pop_stack(); DBG_FUNC_LEAVE(); }
/*! @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. */ static void f_match(INT32 args) { int err; char *retval; int retlen; check_all_args(NULL, args, BIT_STRING, BIT_STRING, 0); 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) { pop_n_elems( args ); push_undefined(); return; } YPERROR( err ); pop_n_elems( args ); push_string(make_shared_binary_string( retval, retlen )); }
static void f_get_address( INT32 args ) { int i; struct pike_string *res, *src; char *orig; if(Pike_sp[-1].type != T_STRING) Pike_error("Invalid argument type, expected 8-bit string.\n"); src = Pike_sp[-1].u.string; if(src->len < 7) { res = make_shared_binary_string("unknown", 7); } else { orig = src->str; /* We have at most 5 digits for the port (16 bit integer) */ i = src->len-6; /* Unrolled loop to find the space separating the IP address and the port * number. We start looking at position 6 from the end and work backwards. * This is because we assume there are more 5 digits ports than 4 digit * ports etc. */ if(!(orig[i] & 0xDF)) /* char 6 */ res = make_shared_binary_string(orig, i); else if(!(orig[++i] & 0xDF)) /* char 5 */ res = make_shared_binary_string(orig, i); else if(!(orig[++i] & 0xDF)) /* char 4 */ res = make_shared_binary_string(orig, i); else if(!(orig[++i] & 0xDF)) /* char 3 */ res = make_shared_binary_string(orig, i); else if(!(orig[++i] & 0xDF)) /* char 2 */ res = make_shared_binary_string(orig, i); else res = make_shared_binary_string("unknown", 7); } pop_stack(); push_string(res); }
/*! @decl program load_module(string module_name) *! *! Load a binary module. *! *! This function loads a module written in C or some other language *! into Pike. The module is initialized and any programs or constants *! defined will immediately be available. *! *! When a module is loaded the C function @tt{pike_module_init()@} will *! be called to initialize it. When Pike exits @tt{pike_module_exit()@} *! will be called. These two functions @b{must@} be available in the module. *! *! @note *! The current working directory is normally not searched for *! dynamic modules. Please use @expr{"./name.so"@} instead of just *! @expr{"name.so"@} to load modules from the current directory. */ void f_load_module(INT32 args) { extern int global_callable_flags; void *module; modfun init, exit; struct module_list *new_module; struct pike_string *module_name; ONERROR err; module_name = Pike_sp[-args].u.string; if((Pike_sp[-args].type != T_STRING) || (module_name->size_shift) || string_has_null(module_name)) { Pike_error("Bad argument 1 to load_module()\n"); } { struct module_list *mp; for (mp = dynamic_module_list; mp; mp = mp->next) if (mp->name == module_name && mp->module_prog) { pop_n_elems(args); ref_push_program(mp->module_prog); return; } } /* Removing RTLD_GLOBAL breaks some PiGTK themes - Hubbe */ /* Using RTLD_LAZY is faster, but makes it impossible to * detect linking problems at runtime.. */ module=dlopen(module_name->str, RTLD_NOW /*|RTLD_GLOBAL*/ ); if(!module) { struct object *err_obj = low_clone (module_load_error_program); #define LOADERR_STRUCT(OBJ) \ ((struct module_load_error_struct *) (err_obj->storage + module_load_error_offset)) const char *err = dlerror(); if (err) { if (err[strlen (err) - 1] == '\n') push_string (make_shared_binary_string (err, strlen (err) - 1)); else push_text (err); } else push_constant_text ("Unknown reason"); add_ref (LOADERR_STRUCT (err_obj)->path = Pike_sp[-args - 1].u.string); add_ref (LOADERR_STRUCT (err_obj)->reason = Pike_sp[-1].u.string); if (Pike_sp[-args].u.string->len < 1024) { throw_error_object (err_obj, "load_module", Pike_sp - args - 1, args, "load_module(\"%s\") failed: %s\n", module_name->str, Pike_sp[-1].u.string->str); } else { throw_error_object (err_obj, "load_module", Pike_sp - args - 1, args, "load_module() failed: %s\n", Pike_sp[-1].u.string->str); } } #ifdef PIKE_DEBUG { struct module_list *mp; for (mp = dynamic_module_list; mp; mp = mp->next) if (mp->module == module && mp->module_prog) { fprintf(stderr, "load_module(): Module loaded twice:\n" "Old name: %s\n" "New name: %s\n", mp->name->str, module_name->str); pop_n_elems(args); ref_push_program(mp->module_prog); return; } } #endif /* PIKE_DEBUG */ init = CAST_TO_FUN(dlsym(module, "pike_module_init")); if (!init) { init = CAST_TO_FUN(dlsym(module, "_pike_module_init")); if (!init) { dlclose(module); Pike_error("pike_module_init missing in dynamic module \"%S\".\n", module_name); } } exit = CAST_TO_FUN(dlsym(module, "pike_module_exit")); if (!exit) { exit = CAST_TO_FUN(dlsym(module, "_pike_module_exit")); if (!exit) { dlclose(module); Pike_error("pike_module_exit missing in dynamic module \"%S\".\n", module_name); } } #if defined(__NT__) && defined(_M_IA64) { fprintf(stderr, "pike_module_init: 0x%p\n" " func: 0x%p\n" " gp: 0x%p\n", init, ((void **)init)[0], ((void **)init)[1]); fprintf(stderr, "pike_module_exit: 0x%p\n" " func: 0x%p\n" " gp: 0x%p\n", exit, ((void **)exit)[0], ((void **)exit)[1]); } #endif /* __NT__ && _M_IA64 */ new_module=ALLOC_STRUCT(module_list); new_module->next=dynamic_module_list; dynamic_module_list=new_module; new_module->module=module; copy_shared_string(new_module->name, Pike_sp[-args].u.string); new_module->module_prog = NULL; new_module->init=init; new_module->exit=exit; enter_compiler(new_module->name, 1); start_new_program(); global_callable_flags|=CALLABLE_DYNAMIC; #ifdef PIKE_DEBUG { struct svalue *save_sp=Pike_sp; #endif SET_ONERROR(err, cleanup_compilation, NULL); #if defined(__NT__) && defined(_M_IA64) fprintf(stderr, "Calling pike_module_init()...\n"); #endif /* __NT__ && _M_IA64 */ (*(modfun)init)(); #if defined(__NT__) && defined(_M_IA64) fprintf(stderr, "pike_module_init() done.\n"); #endif /* __NT__ && _M_IA64 */ UNSET_ONERROR(err); #ifdef PIKE_DEBUG if(Pike_sp != save_sp) Pike_fatal("load_module(%s) left %ld droppings on stack!\n", module_name->str, PTRDIFF_T_TO_LONG(Pike_sp - save_sp)); } #endif pop_n_elems(args); { struct program *p = end_program(); exit_compiler(); if (p) { if ( #if 0 p->num_identifier_references #else /* !0 */ 1 #endif /* 0 */ ) { push_program(p); add_ref(new_module->module_prog = Pike_sp[-1].u.program); } else { /* No identifier references -- Disabled module. */ free_program(p); push_undefined(); } } else { /* Initialization failed. */ new_module->exit(); dlclose(module); dynamic_module_list = new_module->next; free_string(new_module->name); free(new_module); Pike_error("Failed to initialize dynamic module \"%S\".\n", module_name); } } }
/* * This is the Gz module-compatible STRING compressor * Takes a string to compress and returns a compressed string. * Allows an optional INT argument for Gz.deflate compat, but * ignores it. * * It uses a very high-level libbz2 call for simplicity. */ static void f_deflate_deflate(INT32 args) { char *dest; unsigned dlen; struct pike_string *src; int retval; struct pike_string *retstr; int verbosity = 0; switch(args) { case 2: if(ARG(2).type != T_INT) { Pike_error("bzip2.deflate->deflate(): argument 2 not an integer.\n"); } verbosity = ARG(2).u.integer; if( verbosity > 4 || verbosity < 0 ) { Pike_error("bzip2.deflate->deflate(): verbosity should be between 0 and 4.\n"); } /* FALLTHROUGH */ case 1: if (ARG(1).type != T_STRING) Pike_error("bzip2.deflate->deflate(): argument 1 must be a string.\n"); if (!ARG(1).u.string->str || !ARG(1).u.string->len) Pike_error("bzip2.deflate->deflate(): cannot compress an empty string!\n"); src = ARG(1).u.string; break; default: Pike_error("bzip2.deflate->deflate(): expected 1 to 2 arguments.\n"); } /* * We assume the worst case when the destination string doesn't compress * and will instead grow. The assumption is that it can grow by 1/3 of the * source string. We also add an extra 40 bytes since that is what the * minimum size seems to be. */ dlen = (src->len << src->size_shift) + 1; dlen += dlen / 3 + 40; destalloc: /* Yep, I know. goto's are ugly. But efficient. :P */ dest = (char*)calloc(dlen, sizeof(char)); if (!dest) Pike_error("bzip2.deflate->deflate(): out of memory (needed %u bytes)\n", dlen); #ifdef HAVE_OLD_LIBBZ2 retval = bzBuffToBuffCompress(dest, &dlen, src->str, src->len << src->size_shift, THIS->blkSize, verbosity, 0); #else retval = BZ2_bzBuffToBuffCompress(dest, &dlen, src->str, src->len << src->size_shift, THIS->blkSize, verbosity, 0); #endif switch(retval) { #ifdef BZ_CONFIG_ERROR case BZ_CONFIG_ERROR: Pike_error("bzip2.deflate->deflate(): your copy of libbz2 is seriously damaged!\n"); break; /* never reached */ #endif case BZ_MEM_ERROR: Pike_error("bzip2.deflate->deflate(): out of memory compressing block.\n"); break; /* never reached */ case BZ_OUTBUFF_FULL: if (dest) free(dest); dlen <<= 1; goto destalloc; break; /* never reached */ case BZ_OK: break; case BZ_PARAM_ERROR: Pike_error("bzip2.deflate->deflate(): Invalid parameters.\n"); break; default: Pike_error("bzip2.deflate->deflate(): unknown error code %d\n", retval); break; /* never reached */ } pop_n_elems(args); if (dest) { retstr = make_shared_binary_string(dest, dlen); free(dest); push_string(retstr); } else push_int(0); }
/* * Parse the given string and fill the passed multisets with, * respectively, "normal" and "internal" prestates. Note that the * latter is filled only if the FIRST prestate is "internal" and in * such case the former has just one member - "internal". * Returns the passed url without the prestate part. */ static void f_parse_prestates( INT32 args ) { struct pike_string *url; struct multiset *prestate; struct multiset *internal; struct svalue ind; char *tmp; int prestate_end = -1; int done_first = 0, i; int last_start; ind.type = T_STRING; get_all_args("Caudium.parse_prestates", args, "%S%M%M", &url, &prestate, &internal); if (url->len < 5 || url->str[1] != '(') { /* must have at least '/(#)/ */ pop_n_elems(args-1); /* Leave URL on the stack == return it */ return; } tmp = &url->str[3]; while (tmp && *tmp) { if (*tmp == '/' && *(tmp - 1) == ')') { prestate_end = tmp - url->str; break; } tmp++; } if (prestate_end < 0) { pop_n_elems(args-1); /* Leave URL on the stack == return it */ return; /* not a prestate */ } /* * Determine which prestate we should fill. */ last_start = 2; for(i = 2; i <= prestate_end; i++) { if (url->str[i] == ',' || url->str[i] == ')') { int len = i - last_start; switch(done_first) { case 0: if (!MEMCMP(&url->str[last_start], "internal", len)) { done_first = -1; ind.u.string = make_shared_string("internal"); } else { done_first = 1; ind.u.string = make_shared_binary_string(&url->str[last_start], len); } multiset_insert(prestate, &ind); break; case -1: /* internal */ ind.u.string = make_shared_binary_string(&url->str[last_start], len); multiset_insert(internal, &ind); break; default: /* prestate */ ind.u.string = make_shared_binary_string(&url->str[last_start], len); multiset_insert(prestate, &ind); break; } free_svalue(&ind); last_start = i + 1; } } pop_n_elems(args); push_string(make_shared_string(url->str + prestate_end)); }
static rgba_group decode_color( struct buffer *s ) { static struct svalue _parse_color; static struct svalue *parse_color; rgba_group res; res.alpha = 255; if(!s->len) { res.r=res.g=res.b = 0; return res; } if(s->str[0] == '#' && s->len>3) { switch(s->len) { default: res.r = hextoint(s->str[1])*0x10; res.g = hextoint(s->str[2])*0x10; res.b = hextoint(s->str[3])*0x10; break; case 7: res.r = hextoint(s->str[1])*0x10 + hextoint(s->str[2]); res.g = hextoint(s->str[3])*0x10 + hextoint(s->str[4]); res.b = hextoint(s->str[5])*0x10 + hextoint(s->str[6]); break; case 13: res.r = hextoint(s->str[1])*0x10 + hextoint(s->str[2]); res.g = hextoint(s->str[5])*0x10 + hextoint(s->str[6]); res.b = hextoint(s->str[9])*0x10 + hextoint(s->str[10]); break; } return res; } if(s->len==4&&(!strncmp(s->str,"None",4)||!strncmp(s->str,"none",4))) { #ifdef HIDE_WARNINGS res.r = res.g = res.b = 0; #endif res.alpha = 0; return res; } if(!parse_color) { push_text("Image.Color"); SAFE_APPLY_MASTER( "resolv_or_error", 1 ); _parse_color = sp[-1]; parse_color = &_parse_color; sp--; } push_svalue( parse_color ); push_string(make_shared_binary_string(s->str,s->len)); f_index( 2 ); if(sp[-1].type != T_OBJECT) { push_int(0); stack_swap(); } else { push_constant_text( "array" ); apply( sp[-2].u.object, "cast", 1 ); } if(sp[-1].type == T_ARRAY && sp[-1].u.array->size == 3) { res.r = sp[-1].u.array->item[0].u.integer; res.g = sp[-1].u.array->item[1].u.integer; res.b = sp[-1].u.array->item[2].u.integer; } else { res.r = res.g = res.b = 0; } pop_stack(); /* array */ pop_stack(); /* object */ return res; }
static void f_ultraparse( INT32 args ) { FD f = -1; int lines=0, cls, c=0, my_fd=1, tzs=0, state=0, next; unsigned char *char_pointer=0; /* array with offsets for fields in the string buffer */ int buf_points[16]; INT32 v=0, offs0=0, len=0, bytes=0, gotdate=0; INT32 last_hour=0, last_date=0, last_year=0, last_month=0, this_date=0, broken_lines=0, tmpinteger=0, field_position=0; time_t start; unsigned char *read_buf; struct svalue *statfun, *daily, *pagexts=0, *file, *refsval, *log_format; unsigned char *buf; char *field_buf; #ifdef BROKEN_LINE_DEBUG INT32 broken_line_pos=0; unsigned char *broken_line; #endif INT32 *state_list, *save_field_num, *field_endings, num_states; char *notref = 0; INT32 state_pos=0, bufpos=0, i, fieldnum=0; struct pike_string *url_str = 0, *ref_str = 0, *rfc_str = 0, *hst_str = 0, *tmpagent = 0; struct svalue *url_sval; ONERROR unwind_protect; unsigned INT32 hits_per_hour[24]; unsigned INT32 hosts_per_hour[24]; unsigned INT32 pages_per_hour[24]; unsigned INT32 sessions_per_hour[24]; double kb_per_hour[24]; unsigned INT32 session_length[24]; /* struct mapping *unique_per_hour = allocate_mapping(1);*/ struct mapping *hits_per_error = allocate_mapping(10); struct mapping *error_urls = allocate_mapping(10); struct mapping *error_refs = allocate_mapping(10); struct mapping *user_agents = allocate_mapping(10); struct mapping *directories = allocate_mapping(20); struct mapping *referrers = allocate_mapping(1); struct mapping *refsites = allocate_mapping(1); struct mapping *referredto = allocate_mapping(1); struct mapping *pages = allocate_mapping(1); struct mapping *hosts = allocate_mapping(1); struct mapping *hits = allocate_mapping(1); struct mapping *session_start = allocate_mapping(1); struct mapping *session_end = allocate_mapping(1); struct mapping *hits20x = allocate_mapping(300); struct mapping *hits302 = allocate_mapping(2); struct mapping *sites = allocate_mapping(1); struct mapping *domains = allocate_mapping(1); struct mapping *topdomains = allocate_mapping(1); struct mapping *tmpdest = NULL; /* struct mapping *hits30x = allocate_mapping(2);*/ if(args>6 && sp[-1].type == T_INT) { offs0 = sp[-1].u.integer; pop_n_elems(1); --args; } if(args>5 && sp[-1].type == T_STRING) { notref = sp[-1].u.string->str; pop_n_elems(1); --args; } lmu = 0; get_all_args("UltraLog.ultraparse", args, "%*%*%*%*%*", &log_format, &statfun, &daily, &file, &pagexts); if(log_format->type != T_STRING) Pike_error("Bad argument 1 to Ultraparse.ultraparse, expected string.\n"); if(statfun->type != T_FUNCTION) Pike_error("Bad argument 2 to Ultraparse.ultraparse, expected function.\n"); if(daily->type != T_FUNCTION) Pike_error("Bad argument 3 to Ultraparse.ultraparse, expected function.\n"); if(pagexts->type != T_MULTISET) Pike_error("Bad argument 5 to Ultraparse.ultraparse, expected multiset.\n"); if(file->type == T_OBJECT) { f = fd_from_object(file->u.object); if(f == -1) Pike_error("UltraLog.ultraparse: File is not open.\n"); my_fd = 0; } else if(file->type == T_STRING && file->u.string->size_shift == 0) { do { f=fd_open(file->u.string->str, fd_RDONLY, 0); } while(f < 0 && errno == EINTR); if(errno < 0) Pike_error("UltraLog.ultraparse(): Failed to open file for reading (errno=%d).\n", errno); } else Pike_error("Bad argument 4 to UltraLog.ultraparse, expected string or object .\n"); state_list = malloc((log_format->u.string->len +3) * sizeof(INT32)); save_field_num = malloc((log_format->u.string->len +3) * sizeof(INT32)); field_endings = malloc((log_format->u.string->len +3) * sizeof(INT32)); num_states = parse_log_format(log_format->u.string, state_list, field_endings, save_field_num); if(num_states < 1) { free(state_list); free(save_field_num); free(field_endings); Pike_error("UltraLog.ultraparse(): Failed to parse log format.\n"); } fd_lseek(f, offs0, SEEK_SET); read_buf = malloc(READ_BLOCK_SIZE+1); buf = malloc(MAX_LINE_LEN+2); #ifdef BROKEN_LINE_DEBUG broken_line = malloc(MAX_LINE_LEN*10); #endif MEMSET(hits_per_hour, 0, sizeof(hits_per_hour)); MEMSET(hosts_per_hour, 0, sizeof(hosts_per_hour)); MEMSET(session_length, 0, sizeof(session_length)); MEMSET(pages_per_hour, 0, sizeof(pages_per_hour)); MEMSET(sessions_per_hour, 0, sizeof(sessions_per_hour)); MEMSET(kb_per_hour, 0, sizeof(kb_per_hour)); /*url_sval.u.type = TYPE_STRING;*/ BUFSET(0); field_position = bufpos; buf_points[0] = buf_points[1] = buf_points[2] = buf_points[3] = buf_points[4] = buf_points[5] = buf_points[6] = buf_points[7] = buf_points[8] = buf_points[9] = buf_points[10] = buf_points[11] = buf_points[12] = buf_points[13] = buf_points[14] = buf_points[15] = 0; while(1) { /* THREADS_ALLOW();*/ do { len = fd_read(f, read_buf, READ_BLOCK_SIZE); } while(len < 0 && errno == EINTR); /* THREADS_DISALLOW();*/ if(len <= 0) break; /* nothing more to read or error. */ offs0 += len; char_pointer = read_buf+len - 1; while(len--) { c = char_pointer[-len]; cls = char_class[c]; #if 0 fprintf(stdout, "DFA(%d:%d): '%c' (%d) ", state, state_pos, c, (int)c); switch(cls) { case CLS_WSPACE: fprintf(stdout, "CLS_WSPACE\n"); break; case CLS_CRLF: fprintf(stdout, "CLS_CRLF\n"); break; case CLS_TOKEN: fprintf(stdout, "CLS_TOKEN\n"); break; case CLS_DIGIT: fprintf(stdout, "CLS_DIGIT\n"); break; case CLS_QUOTE: fprintf(stdout, "CLS_QUOTE\n"); break; case CLS_LBRACK: fprintf(stdout, "CLS_LBRACK\n"); break; case CLS_RBRACK: fprintf(stdout, "CLS_RBRACK\n"); break; case CLS_SLASH: fprintf(stdout, "CLS_SLASH\n"); break; case CLS_COLON: fprintf(stdout, "CLS_COLON\n"); break; case CLS_HYPHEN: fprintf(stdout, "CLS_HYPHEN/CLS_MINUS\n"); break; case CLS_PLUS: fprintf(stdout, "CLS_PLUS\n"); break; default: fprintf(stdout, "??? %d ???\n", cls); } #endif #ifdef BROKEN_LINE_DEBUG broken_line[broken_line_pos++] = c; #endif if(cls == field_endings[state_pos]) { /* Field is done. Nullify. */ process_field: /* printf("Processing field %d of %d\n", state_pos, num_states);*/ switch(save_field_num[state_pos]) { case DATE: case HOUR: case MINUTE: case UP_SEC: case CODE: /* BUFSET(0);*/ tmpinteger = 0; for(v = field_position; v < bufpos; v++) { if(char_class[buf[v]] == CLS_DIGIT) tmpinteger = tmpinteger*10 + (buf[v]&0xf); else { goto skip; } } BUFPOINT = tmpinteger; break; case YEAR: tmpinteger = 0; for(v = field_position; v < bufpos; v++) { if(char_class[buf[v]] == CLS_DIGIT) tmpinteger = tmpinteger*10 + (buf[v]&0xf); else { goto skip; } } if(tmpinteger < 100) { if(tmpinteger < 60) tmpinteger += 2000; else tmpinteger += 1900; } BUFPOINT = tmpinteger; break; case BYTES: v = field_position; switch(char_class[buf[v++]]) { case CLS_QUESTION: case CLS_HYPHEN: if(v == bufpos) tmpinteger = 0; else { goto skip; } break; case CLS_DIGIT: tmpinteger = (buf[field_position]&0xf); for(; v < bufpos; v++) { if(char_class[buf[v]] == CLS_DIGIT) tmpinteger = tmpinteger*10 + (buf[v]&0xf); else { goto skip; } } /* printf("Digit: %d\n", tmpinteger);*/ break; default: goto skip; } BUFPOINT = tmpinteger; /* bufpos++;*/ break; case MONTH: /* Month */ /* BUFSET(0);*/ /* field_buf = buf + field_positions[state_pos];*/ switch(bufpos - field_position) { case 2: tmpinteger = 0; for(v = field_position; v < bufpos; v++) { if(char_class[buf[v]] == CLS_DIGIT) tmpinteger = tmpinteger*10 + (buf[v]&0xf); else { goto skip; } } break; case 3: switch(((buf[field_position]|0x20)<<16)|((buf[field_position+1]|0x20)<<8)| (buf[field_position+2]|0x20)) { case ('j'<<16)|('a'<<8)|'n': tmpinteger = 1; break; case ('f'<<16)|('e'<<8)|'b': tmpinteger = 2; break; case ('m'<<16)|('a'<<8)|'r': tmpinteger = 3; break; case ('a'<<16)|('p'<<8)|'r': tmpinteger = 4; break; case ('m'<<16)|('a'<<8)|'y': tmpinteger = 5; break; case ('j'<<16)|('u'<<8)|'n': tmpinteger = 6; break; case ('j'<<16)|('u'<<8)|'l': tmpinteger = 7; break; case ('a'<<16)|('u'<<8)|'g': tmpinteger = 8; break; case ('s'<<16)|('e'<<8)|'p': tmpinteger = 9; break; case ('o'<<16)|('c'<<8)|'t': tmpinteger = 10; break; case ('n'<<16)|('o'<<8)|'v': tmpinteger = 11; break; case ('d'<<16)|('e'<<8)|'c': tmpinteger = 12; break; } break; default: goto skip; } /*printf("Month: %0d\n", mm);*/ if(tmpinteger < 1 || tmpinteger > 12) goto skip; /* Broken Month */ BUFPOINT = tmpinteger; /* bufpos++;*/ break; case ADDR: case REFER: case AGENT: case TZ: case METHOD: case URL: case RFC: case PROTO: BUFSET(0); SETPOINT(); /* printf("Field %d, pos %d, %s\n", save_field_num[state_pos],BUFPOINT,*/ /* buf + BUFPOINT); */ break; } state_pos++; field_position = bufpos; if(cls != CLS_CRLF) continue; } else if(cls != CLS_CRLF) { BUFSET(c); continue; } else { /* printf("Processing last field (%d).\n", state_pos);*/ goto process_field; /* End of line - process what we got */ } /* printf("%d %d\n", state_pos, num_states);*/ /* buf_points[8] = buf_points[9] = buf_points[10] = buf_points[11] = buf;*/ /* buf_points[12] = buf_points[13] = buf_points[14] = buf_points[15] = buf;*/ #if 0 if(!((lines+broken_lines)%100000)) { push_int(lines+broken_lines); push_int((int)((float)offs0/1024.0/1024.0)); apply_svalue(statfun, 2); pop_stack(); /*printf("%5dk lines, %5d MB\n", lines/1000, (int)((float)offs0/1024.0/1024.0));*/ } #endif if(state_pos < num_states) { #ifdef BROKEN_LINE_DEBUG broken_line[broken_line_pos] = 0; printf("too few states (pos=%d): %s\n", state_pos, broken_line); #endif broken_lines++; goto ok; } #define yy buf_points[YEAR] #define mm buf_points[MONTH] #define dd buf_points[DATE] #define h buf_points[HOUR] #define m buf_points[MINUTE] #define s buf_points[UP_SEC] #define v buf_points[CODE] #define bytes buf_points[BYTES] this_date = (yy*10000) + (mm*100) + dd; if(!this_date) { broken_lines++; goto ok; } #if 1 if(!last_date) { /* First loop w/o a value.*/ last_date = this_date; last_hour = h; } else { if(last_hour != h || last_date != this_date) { pages_per_hour[last_hour] += hourly_page_hits(hits20x, pages, hits, pagexts->u.multiset, 200); /* pages_per_hour[last_hour] +=*/ /* hourly_page_hits(hits304, pages, hits, pagexts->u.multiset, 300);*/ /* printf("%5d %5d for %d %02d:00\n",*/ /* pages_per_hour[last_hour], hits_per_hour[last_hour],*/ /*last_date, last_hour);*/ if(m_sizeof(session_start)) { summarize_sessions(last_hour, sessions_per_hour, session_length, session_start, session_end); free_mapping(session_start); free_mapping(session_end); session_start = allocate_mapping(1); session_end = allocate_mapping(1); } hosts_per_hour[last_hour] += m_sizeof(sites); do_map_addition(hosts, sites); free_mapping(sites); sites = allocate_mapping(100); last_hour = h; free_mapping(hits20x); /* Reset this one */ /* free_mapping(hits304); Reset this one */ /* hits304 = allocate_mapping(2);*/ hits20x = allocate_mapping(2); } #if 1 if(last_date != this_date) { /* printf("%d %d\n", last_date, this_date);*/ tmpdest = allocate_mapping(1); summarize_refsites(refsites, referrers, tmpdest); free_mapping(referrers); referrers = tmpdest; tmpdest = allocate_mapping(1); clean_refto(referredto, tmpdest, pagexts->u.multiset); free_mapping(referredto); referredto = tmpdest; summarize_directories(directories, pages); summarize_directories(directories, hits); tmpdest = allocate_mapping(1); http_decode_mapping(user_agents, tmpdest); free_mapping(user_agents); user_agents = tmpdest; tmpdest = allocate_mapping(1); summarize_hosts(hosts, domains, topdomains, tmpdest); free_mapping(hosts); hosts = tmpdest; #if 1 push_int(last_date / 10000); push_int((last_date % 10000)/100); push_int((last_date % 10000)%100); push_mapping(pages); push_mapping(hits); push_mapping(hits302); push_mapping(hits_per_error); push_mapping(error_urls); push_mapping(error_refs); push_mapping(referredto); push_mapping(refsites); push_mapping(referrers); push_mapping(directories); push_mapping(user_agents); push_mapping(hosts); push_mapping(domains); push_mapping(topdomains); for(i = 0; i < 24; i++) { push_int(sessions_per_hour[i]); } f_aggregate(24); for(i = 0; i < 24; i++) { push_int(hits_per_hour[i]); hits_per_hour[i] = 0; } f_aggregate(24); for(i = 0; i < 24; i++) { push_int(pages_per_hour[i]); pages_per_hour[i] = 0; } f_aggregate(24); for(i = 0; i < 24; i++) { /* KB per hour.*/ push_float(kb_per_hour[i]); kb_per_hour[i] = 0.0; } f_aggregate(24); for(i = 0; i < 24; i++) { push_float(sessions_per_hour[i] ? ((float)session_length[i] / (float)sessions_per_hour[i]) / 60.0 : 0.0); sessions_per_hour[i] = 0; session_length[i] = 0; } f_aggregate(24); for(i = 0; i < 24; i++) { push_int(hosts_per_hour[i]); hosts_per_hour[i] = 0; } f_aggregate(24); apply_svalue(daily, 23); pop_stack(); #else free_mapping(error_refs); free_mapping(referredto); free_mapping(refsites); free_mapping(directories); free_mapping(error_urls); free_mapping(hits); free_mapping(hits_per_error); free_mapping(pages); free_mapping(hosts); free_mapping(domains); free_mapping(topdomains); free_mapping(referrers); free_mapping(hits302); #endif user_agents = allocate_mapping(10); hits302 = allocate_mapping(1); hits_per_error = allocate_mapping(10); error_urls = allocate_mapping(10); error_refs = allocate_mapping(10); directories = allocate_mapping(20); referrers = allocate_mapping(1); referredto = allocate_mapping(1); refsites = allocate_mapping(1); pages = allocate_mapping(1); hits = allocate_mapping(1); sites = allocate_mapping(1); hosts = allocate_mapping(1); domains = allocate_mapping(1); topdomains = allocate_mapping(1); last_date = this_date; } #endif } #endif #if 1 process_session(buf+buf_points[ADDR], h*3600+m*60+s, h, sessions_per_hour, session_length, session_start, session_end, sites); url_str = make_shared_binary_string((char *)(buf + buf_points[URL]), strlen((char *)(buf + buf_points[URL]))); #if 1 switch(v) { /* Do error-code specific logging. Error urls that are specially treated do not include auth required, service unavailable etc. They are only included in the return code summary. */ case 200: case 201: case 202: case 203: case 204: case 205: case 206: case 207: case 304: mapaddstr(hits20x, url_str); DO_REFERRER(); break; case 300: case 301: case 302: case 303: case 305: mapaddstr(hits302, url_str); DO_REFERRER(); break; case 400: case 404: case 405: case 406: case 408: case 409: case 410: case 411: case 412: case 413: case 414: case 415: case 416: case 500: case 501: DO_ERREF(); map2addint(error_urls, v, url_str); break; } /*rfc_str = http_decode_string(buf + buf_points[RFC]);*/ /*hst_str = make_shared_binary_string(buf, strlen(buf));*/ #endif free_string(url_str); mapaddint(hits_per_error, v); kb_per_hour[h] += (float)bytes / 1024.0; hits_per_hour[h]++; /*#endif*/ if(strlen((char *)(buf + buf_points[AGENT]))>1) { /* Got User Agent */ tmpagent = make_shared_string((char *)(buf + buf_points[AGENT])); mapaddstr(user_agents, tmpagent); free_string(tmpagent); } #endif lines++; #if 0 printf("%s %s %s\n%s %s %s\n%04d-%02d-%02d %02d:%02d:%02d \n%d %d\n", buf + buf_points[ADDR], buf + buf_points[REFER], buf + buf_points[ RFC ], buf + buf_points[METHOD], buf + buf_points[ URL ], buf + buf_points[PROTO], yy, mm, dd, h, m, s, v, bytes); /* if(lines > 10) exit(0);*/ #endif ok: gotdate = /* v = bytes =h = m = s = tz = tzs = dd = mm = yy = */ buf_points[0] = buf_points[1] = buf_points[2] = buf_points[3] = buf_points[4] = buf_points[5] = buf_points[6] = buf_points[7] = /*buf_points[8] = buf_points[9] = buf_points[10] =*/ buf_points[11] = buf_points[12] = buf_points[13] = buf_points[14] = buf_points[15] = bufpos = state_pos = 0; field_position = 1; #ifdef BROKEN_LINE_DEBUG broken_line_pos = 0; #endif BUFSET(0); } } cleanup: free(save_field_num); free(state_list); free(field_endings); free(buf); push_int(lines); push_int((int)((float)offs0 / 1024.0/1024.0)); push_int(1); apply_svalue(statfun, 3); pop_stack(); free(read_buf); #ifdef BROKEN_LINE_DEBUG free(broken_line); #endif if(my_fd) /* If my_fd == 0, the second argument was an object and thus we don't * want to free it. */ fd_close(f); /* push_int(offs0); */ /* printf("Done: %d %d %d ", yy, mm, dd);*/ if(yy && mm && dd) { /* printf("\nLast Summary for %d-%02d-%02d %02d:%02d\n", yy, mm, dd, h, m);*/ pages_per_hour[last_hour] += hourly_page_hits(hits20x, pages, hits, pagexts->u.multiset, 200); if(m_sizeof(session_start)) { summarize_sessions(last_hour, sessions_per_hour, session_length, session_start, session_end); } hosts_per_hour[last_hour] += m_sizeof(sites); do_map_addition(hosts, sites); free_mapping(sites); tmpdest = allocate_mapping(1); summarize_refsites(refsites, referrers, tmpdest); free_mapping(referrers); referrers = tmpdest; summarize_directories(directories, pages); summarize_directories(directories, hits); tmpdest = allocate_mapping(1); clean_refto(referredto, tmpdest, pagexts->u.multiset); free_mapping(referredto); referredto = tmpdest; tmpdest = allocate_mapping(1); http_decode_mapping(user_agents, tmpdest); free_mapping(user_agents); user_agents = tmpdest; tmpdest = allocate_mapping(1); summarize_hosts(hosts, domains, topdomains, tmpdest); free_mapping(hosts); hosts = tmpdest; push_int(yy); push_int(mm); push_int(dd); push_mapping(pages); push_mapping(hits); push_mapping(hits302); push_mapping(hits_per_error); push_mapping(error_urls); push_mapping(error_refs); push_mapping(referredto); push_mapping(refsites); push_mapping(referrers); push_mapping(directories); push_mapping(user_agents); push_mapping(hosts); push_mapping(domains); push_mapping(topdomains); for(i = 0; i < 24; i++) { push_int(sessions_per_hour[i]); } f_aggregate(24); for(i = 0; i < 24; i++) { push_int(hits_per_hour[i]); } f_aggregate(24); for(i = 0; i < 24; i++) { push_int(pages_per_hour[i]); } f_aggregate(24); for(i = 0; i < 24; i++) { push_float(kb_per_hour[i]); } f_aggregate(24); for(i = 0; i < 24; i++) { push_float(sessions_per_hour[i] ? ((float)session_length[i] / (float)sessions_per_hour[i]) / 60.0 : 0.0); } f_aggregate(24); for(i = 0; i < 24; i++) { push_int(hosts_per_hour[i]); hosts_per_hour[i] = 0; } f_aggregate(24); apply_svalue(daily, 23); pop_stack(); } else { free_mapping(error_refs); free_mapping(referredto); free_mapping(refsites); free_mapping(directories); free_mapping(error_urls); free_mapping(hits); free_mapping(hits_per_error); free_mapping(pages); free_mapping(referrers); free_mapping(hits302); free_mapping(user_agents); free_mapping(hosts); free_mapping(domains); free_mapping(topdomains); } free_mapping(hits20x); free_mapping(session_start); free_mapping(session_end); /* free_mapping(hits30x); */ printf("\nTotal lines: %d, broken lines: %d, mapping lookups: %d\n\n", lines, broken_lines, lmu); fflush(stdout); pop_n_elems(args); push_int(offs0); return; skip: broken_lines++; while(1) { while(len--) { #ifdef BROKEN_LINE_DEBUG broken_line[broken_line_pos] = char_pointer[-len]; #endif if(char_class[char_pointer[-len]] == CLS_CRLF) { #ifdef BROKEN_LINE_DEBUG broken_line[broken_line_pos] = 0; printf("Broken Line (pos=%d): %s\n", state_pos, broken_line); #endif goto ok; } } do { len = fd_read(f, read_buf, READ_BLOCK_SIZE); } while(len < 0 && errno == EINTR); if(len <= 0) break; /* nothing more to read. */ offs0 += len; char_pointer = read_buf+len - 1; } goto cleanup; }
static void f_buf_append( INT32 args ) { struct pike_string *str; struct svalue skey, sval; /* header, value */ int slash_n = 0, cnt, num; unsigned char *pp,*ep; struct svalue *tmp; int os=0, i, j=0, l, qmark = -1; unsigned char *in, *query; if( Pike_sp[-1].type != T_STRING ) Pike_error("Wrong type of argument to append()\n"); str = Pike_sp[-1].u.string; if( str->len >= BUF->free ) { pop_n_elems(args); push_int(413); /* Request Entity Too Large */ return; } MEMCPY( BUF->pos, str->str, str->len ); for( ep = (BUF->pos + str->len), pp = MAX(BUF->data, BUF->pos-3); pp < ep && slash_n < 2; pp++ ) if( *pp == '\n' ) slash_n++; else if( *pp != '\r' ) slash_n=0; BUF->free -= str->len; BUF->pos += str->len; BUF->pos[0] = 0; pop_n_elems( args ); if( slash_n != 2 ) { /* need more data */ push_int( 0 ); return; } skey.type = sval.type = T_STRING; sval.u.string = make_shared_binary_string( (char *)pp, BUF->pos - pp); mapping_insert(BUF->other, SVAL(data), &sval); /* data */ free_string(sval.u.string); in = BUF->data; l = pp - BUF->data; /* find method */ for( i = 0; i < l; i++ ) { if( in[i] == ' ' ) break; else if(in[i] == '\n') { push_int( 400 ); /* Bad Request */ return; } } sval.u.string = make_shared_binary_string((char *)in, i); mapping_insert(BUF->other, SVAL(method), &sval); free_string(sval.u.string); i++; in += i; l -= i; /* find file */ for( i = 0; i < l; i++ ) { if(in[i] == ' ') { break; } else if(in[i] == '\n') { push_int( 400 ); /* Bad Request */ return; } } sval.u.string = make_shared_binary_string((char *)in, i); mapping_insert(BUF->other, SVAL(raw_url), &sval); free_string(sval.u.string); /* Decode file part and return pointer to query, if any */ query = char_decode_url(in, i); /* Decoded, query-less file up to the first \0 */ sval.u.string = make_shared_string((char *)in); mapping_insert(BUF->other, SVAL(file), &sval); free_string(sval.u.string); if(query != NULL) { /* Store the query string */ sval.u.string = make_shared_binary_string((char *)query, i - (query-in)); /* Also up to first null */ mapping_insert(BUF->other, SVAL(query), &sval); free_string(sval.u.string); } i++; in += i; l -= i; /* find protocol */ for( i = 0; i < l; i++ ) { if( in[i] == '\n' ) break; else if(in[i] == ' ') { push_int( 400 ); /* Bad Request */ return; } } if( in[i-1] != '\r' ) i++; sval.u.string = make_shared_binary_string((char *)in, i-1); mapping_insert(BUF->other, SVAL(protocol), &sval); free_string(sval.u.string); in += i; l -= i; if( *in == '\n' ) (in++),(l--); for(i = 0; i < l; i++) { if(in[i] >= 'A' && in[i] <= 'Z') in[i] |= 32; /* Lowercasing the header */ else if( in[i] == ':' ) { /* in[os..i-1] == the header */ skey.u.string = make_shared_binary_string((char*)in+os, i - os); os = i+1; while(in[os]==' ') os++; /* Remove initial spaces */ for(j=os;j<l;j++) if( in[j] == '\n' || in[j]=='\r') break; if((tmp = low_mapping_lookup(BUF->headers, &skey)) && tmp->type == T_STRING) { int len = j - os + 1; int len2 = len +tmp->u.string->len; sval.u.string = begin_shared_string(len2); MEMCPY(sval.u.string->str, tmp->u.string->str, tmp->u.string->len); sval.u.string->str[tmp->u.string->len] = ','; MEMCPY(sval.u.string->str + tmp->u.string->len + 1, (char*)in + os, len); sval.u.string = end_shared_string(sval.u.string); } else { sval.u.string = make_shared_binary_string((char*)in + os, j - os); } mapping_insert(BUF->headers, &skey, &sval); if( in[j+1] == '\n' ) j++; os = j+1; i = j; free_string(sval.u.string); free_string(skey.u.string); } } push_int(1); }
if( q[50]&128 ) rotate_atari_palette(pal, ll, rl); else rotate_atari_palette(pal, rl, ll); img = decode_atari_screendump(q+128, res, pal); push_object(img); } f_aggregate(rl-ll+1); size += 10; } UNSET_ONERROR(err); free_atari_palette(pal); fn = make_shared_binary_string((const char *)q+36, 12); push_constant_text("filename"); push_string(fn); size += 2; free_string(s); f_aggregate_mapping(size); } /*! @decl Image.Image decode(string data) *! Decodes the image @[data] into an @[Image.Image] object. */ void image_neo_f_decode(INT32 args) { image_neo_f__decode(args);
static void f_inflate_inflate(INT32 args) { struct pike_string *src; char *dest; unsigned dlen; struct pike_string *retstr; int retval; if (args == 1) { if (ARG(1).type != T_STRING || ARG(1).u.string->size_shift > 0) Pike_error("bzip2.inflate->inflate(): argument 1 must be an 8-bit string\n"); if (!ARG(1).u.string->str || !strlen(ARG(1).u.string->str)) Pike_error("bzip2.inflate->inflate(): cannot decompress an empty string!\n"); src = ARG(1).u.string; } else if (args != 1) { Pike_error("bzip2.inflate->inflate(): expected exactly one argument of type STRING.\n"); } /* * Let's assume the compression ratio was 50% * and create the destination buffer that many * bytes long */ dlen = src->len + 1; dlen <<= 1; destalloc: dest = (char*)calloc(dlen, sizeof(char)); if (!dest) Pike_error("bzip2.inflate->inflate(): out of memory (needed %u bytes)\n", dlen); #ifdef HAVE_OLD_LIBBZ2 retval = bzBuffToBuffDecompress(dest, &dlen, src->str, src->len, THIS->blkSize, 0); #else retval = BZ2_bzBuffToBuffDecompress(dest, &dlen, src->str, src->len, THIS->blkSize, 0); #endif switch(retval) { #ifdef BZ_CONFIG_ERROR case BZ_CONFIG_ERROR: Pike_error("bzip2.inflate->inflate(): your copy of libbz2 is seriously damaged!\n"); break; /* never reached */ #endif case BZ_MEM_ERROR: Pike_error("bzip2.inflate->inflate(): out of memory decompressing block.\n"); break; /* never reached */ case BZ_OUTBUFF_FULL: if (dest) free(dest); dlen <<= 1; /* double it */ goto destalloc; break; /* never reached */ case BZ_DATA_ERROR: Pike_error("bzip2.inflate->inflate(): data integrity error in compressed data\n"); break; case BZ_DATA_ERROR_MAGIC: Pike_error("bzip2.inflate->inflate(): wrong compressed data magic number\n"); break; case BZ_UNEXPECTED_EOF: Pike_error("bzip2.inflate->inflate(): data ends unexpectedly\n"); break; case BZ_OK: break; default: Pike_error("bzip2.inflate->inflate(): unknown error code %d\n", retval); break; /* never reached */ } pop_n_elems(args); if (dest) { retstr = make_shared_binary_string(dest, dlen); free(dest); push_string(retstr); } else push_int(0); }