Beispiel #1
0
/* 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);
}
Beispiel #2
0
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 );
}
Beispiel #3
0
/*! @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 );
}
Beispiel #4
0
/*! @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 );
}
Beispiel #5
0
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("");
  }
}
Beispiel #6
0
/* 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);
}
Beispiel #7
0
/*! @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);
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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);
}
Beispiel #12
0
/*! @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);
  }
}
Beispiel #13
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;
}
Beispiel #14
0
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;
}
Beispiel #15
0
Datei: rcs.c Projekt: johan/pike
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++;
}
Beispiel #16
0
/* 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);
}
Beispiel #17
0
/* 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));
}
Beispiel #18
0
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;
}
Beispiel #19
0
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();
}
Beispiel #20
0
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();
}
Beispiel #21
0
/*! @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 ));
}
Beispiel #22
0
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);
}
Beispiel #23
0
/*! @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);
    }
  }
}
Beispiel #24
0
/*
 * 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);
}
Beispiel #25
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));
}
Beispiel #26
0
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;
}
Beispiel #27
0
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;
}
Beispiel #28
0
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);
}
Beispiel #29
0
      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);
Beispiel #30
-1
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);    
}