コード例 #1
0
ファイル: caudium.c プロジェクト: Letractively/caudium
static void free_buf_struct(struct object *o)
{
  if(BUF->headers != NULL) {
    free_mapping(BUF->headers);
    BUF->headers = NULL;
  }
  if(BUF->other != NULL) {
    free_mapping(BUF->other);
    BUF->other = NULL;
  }
}
コード例 #2
0
ファイル: dictionary.c プロジェクト: hww3/pexts
static int
dict_insert(DICT *dict, struct object *obj, void *data)
{
    INFUN();
    
    if (!obj)
        return DICT_NULL_OBJECT;

    if (!data)
        return DICT_NULL_DATA;

    if (!dict)
        return DICT_NULL_DICT;
    

    if (dict->used && (dict->used >= dict->dict->data->num_keypairs)) {
        struct mapping  *nmap, *tmp;

        nmap = allocate_mapping(dict->dict->data->num_keypairs << 1);
        tmp = merge_mappings(dict->dict, nmap, PIKE_ARRAY_OP_AND);
        free_mapping(dict->dict);
        free_mapping(nmap);
        dict->dict = tmp;
    }

    {
        struct svalue   skey, sval, *tmp;
        char            addr[64];
        
        sval.type = T_OBJECT;
        sval.u.object = obj;

        sprintf(addr, "0x%X", (unsigned)data);
        skey.type = T_STRING;
        skey.u.string = make_shared_string(addr);

        tmp = low_mapping_lookup(dict->dict, &skey);
        if (tmp) {
            free_string(skey.u.string);
	    OUTFUN();
            return DICT_EXISTS;
        }

        mapping_insert(dict->dict, &skey, &sval);
        dict->used++;
    }

    OUTFUN();
    return DICT_OK;
}
コード例 #3
0
ファイル: caudium.c プロジェクト: Letractively/caudium
static void free_buf_struct(struct object *o)
{
  if(BUF->headers != NULL ) {
    free_mapping(BUF->headers);
    BUF->headers = NULL;
  }
  if(BUF->other != NULL) {
    free_mapping(BUF->other);
    BUF->other = NULL;
  }
  if(BUF->data) {
    free(BUF->data);
    BUF->data = NULL; /* just in case */
  }
}
コード例 #4
0
ファイル: roxen.c プロジェクト: austintgriffith/php7
/* 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);
}
コード例 #5
0
ファイル: yp.c プロジェクト: pikelang/Pike
/*! @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 );
}
コード例 #6
0
static void
gupnp_simple_igd_remove_port_real (GUPnPSimpleIgd *self,
                                   const gchar *protocol,
                                   guint external_port)
{
    struct Mapping *mapping = NULL;
    guint i;

    g_return_if_fail (protocol);

    for (i = 0; i < self->priv->mappings->len; i++)
    {
        struct Mapping *tmpmapping = g_ptr_array_index (self->priv->mappings, i);
        if (tmpmapping->requested_external_port == external_port &&
                !strcmp (tmpmapping->protocol, protocol))
        {
            mapping = tmpmapping;
            break;
        }
    }
    if (!mapping)
        return;

    g_ptr_array_remove_index_fast (self->priv->mappings, i);

    free_mapping (self, mapping);
}
コード例 #7
0
ファイル: array.c プロジェクト: DruSatori/AEMud
struct vector *
set_manipulate_array(struct vector *arr1, struct vector *arr2, int op)
{
    struct mapping *m;
    struct vector *r;
    struct svalue tmp, *v;
    char *flags;
    int cnt, res;
    
    if (arr1->size < 1 || arr2->size < 1)
    {
	switch (op)
	{
	case SETARR_SUBTRACT:
	    INCREF(arr1->ref);
	    return arr1;

        case SETARR_INTERSECT:
	    return allocate_array(0);
	}
    }

    m = make_mapping(arr2, 0);
    tmp.type = T_NUMBER;
    tmp.u.number = 1;
    assign_svalue_no_free(get_map_lvalue(m, &arr2->item[0], 1), &tmp);

    res = 0;

    flags = alloca((size_t)arr1->size + 1); 
    for (cnt = 0; cnt < arr1->size; cnt++) 
    {
	flags[cnt] = 0;
	v = get_map_lvalue(m, &(arr1->item[cnt]), 0);
	if (op == SETARR_INTERSECT && v != &const0)
	{
	    flags[cnt] = 1; 
	    res++; 
	}
	else if (op == SETARR_SUBTRACT && v == &const0)
	{
	    flags[cnt] = 1; 
	    res++; 
	}
    }
    r = allocate_array(res);
    if (res) 
    {
	for (cnt = res = 0; cnt < arr1->size; cnt++) 
	{
	    if (flags[cnt]) 
		assign_svalue_no_free(&r->item[res++], &arr1->item[cnt]);
	}
    }
    free_mapping(m);
    return r;
}
コード例 #8
0
ファイル: s_conf.c プロジェクト: kisserlb/enet-1.0
/** Unregister and free all current service mappings. */
static void close_mappings(void)
{
  struct s_map *map, *next;

  for (map = GlobalServiceMapList; map; map = next) {
    next = map->next;
    unregister_mapping(map);
    free_mapping(map);
  }
  GlobalServiceMapList = NULL;
}
コード例 #9
0
ファイル: pike_search.c プロジェクト: ajinkya007/pike-1
void exit_pike_searching(void)
{
  if(pike_search_program)
  {
    free_program(pike_search_program);
    pike_search_program=0;
  }
  if(memsearch_cache)
  {
    free_mapping(memsearch_cache);
    memsearch_cache=0;
  }
}
コード例 #10
0
gboolean
gupnp_simple_igd_delete_all_mappings (GUPnPSimpleIgd *self)
{
    self->priv->no_new_mappings = TRUE;

    while (self->priv->mappings->len)
    {
        free_mapping (self, g_ptr_array_index (self->priv->mappings, 0));
        g_ptr_array_remove_index_fast (self->priv->mappings, 0);
    }

    return (self->priv->deleting_count == 0);
}
コード例 #11
0
ファイル: array.c プロジェクト: DruSatori/AEMud
INLINE struct vector *
union_array(struct vector *arr1, struct vector *arr2)
{
    int i, size;
    struct mapping *mp;
    struct vector *arr3;
    char *set;

    if (arr1->size == 0)
    {
	INCREF(arr2->ref);
	return arr2;
    }

    if (arr2->size == 0)
    {
	INCREF(arr1->ref);
	return arr1;
    }

    mp = allocate_map(arr1->size);

    for (i = 0; i < arr1->size; i++)
	assign_svalue(get_map_lvalue(mp, &arr1->item[i], 1), &const1);

    set = alloca((size_t)arr2->size);

    for (i = size = 0; i < arr2->size; i++)
    {
	if (get_map_lvalue(mp, &arr2->item[i], 0) == &const0)
	    set[i] = 1, size++;
	else
	    set[i] = 0;
    }

    free_mapping(mp);

    arr3 = allocate_array(arr1->size + size);

    for (i = 0; i < arr1->size; i++)
	assign_svalue_no_free(&arr3->item[i], &arr1->item[i]);

    size = arr1->size;

    for (i = 0; i < arr2->size; i++)
	if (set[i])
	    assign_svalue_no_free(&arr3->item[size++], &arr2->item[i]);

    return arr3;
}
コード例 #12
0
ファイル: caudium.c プロジェクト: PHPFORMEEGO/PHPCore
/* 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);
}
コード例 #13
0
ファイル: ultrautil.c プロジェクト: Letractively/caudium
INLINE void map2addint( struct mapping * mappingen, int subkey, struct pike_string *key)
{
  struct svalue *s;                                                   
  intie.u.integer = subkey;                                                
  s = LML( mappingen, &intie );                 
  if( !s ) {
    struct svalue mappie;                                           
    struct mapping *map = allocate_mapping(1);
    mappie.type = T_MAPPING;
    mappie.u.mapping = map;
    mapping_insert( mappingen, &intie, &mappie);
    mapaddstr(map, key);
    free_mapping(map);
  } else 
    mapaddstr(s->u.mapping, key);
}  
コード例 #14
0
ファイル: ultrautil.c プロジェクト: Letractively/caudium
INLINE void mapaddstrmap(struct mapping * mappingen, struct pike_string *key,
			 struct mapping *map)
{
  struct svalue *s;                                                   
  struct svalue skey;
  skey.type = T_STRING;
  skey.u.string = key;
  s = LML( mappingen, &skey );                 
  if( !s ) {
    struct svalue mappie;                                           
    mappie.type = T_MAPPING;
    mappie.u.mapping = map;
    mapping_insert( mappingen, &skey, &mappie);
    free_mapping(map);
  } else                                                                
    do_map_addition(s->u.mapping, map);
}           
コード例 #15
0
ファイル: cfuns.c プロジェクト: xcw0579/mudOS
void c_exit_foreach (void) {
    IF_DEBUG(stack_in_use_as_temporary--);
    if (sp->type == T_REF) {
	if (!(--sp->u.ref->ref) && sp->u.ref->lvalue == 0)
	    FREE(sp->u.ref);
    }
    if ((sp-1)->type == T_LVALUE) {
	/* mapping */
	sp -= 3;
	free_array((sp--)->u.arr);
	free_mapping((sp--)->u.map);
    } else {
	/* array or string */
	sp -= 2;
	if (sp->type == T_STRING)
	    free_string_svalue(sp--);
	else
	    free_array((sp--)->u.arr);
    }
}
コード例 #16
0
ファイル: ultrautil.c プロジェクト: Letractively/caudium
INLINE void map2addstr( struct mapping * mappingen,
			struct pike_string *key,
			struct pike_string *key2)
{
  struct svalue *s;                                                   
  struct svalue mappie;                                            
  struct svalue skey;
  skey.type = T_STRING;
  skey.u.string = key;
  s = LML( mappingen, &skey );                 
  if( !s ) {
    struct mapping *map = allocate_mapping(1);
    mappie.type = T_MAPPING;
    mappie.u.mapping = map;
    mapping_insert( mappingen, &skey, &mappie);
    mapaddstr(map, key2);
    free_mapping(map);
  } else 
    mapaddstr(s->u.mapping, key2);
}  
コード例 #17
0
ファイル: object.c プロジェクト: carriercomm/cd-gamedriver
static struct mapping *
restore_mapping(char **str)
{
    struct mapping *m;

    m = allocate_map(0);
    for(;;)
    {
	if (**str == ']')
	{
	    if (*++*str == ')')
	    {
		++*str;
		return m;
	    }
	    else
		break;
	}
	else
	{
	    struct svalue arg, *val;
	    arg = const0;
	    if (!restore_one(&arg, str))
		break;
      	    if (*(*str)++ != ':')
	    {
		free_svalue(&arg);
		break;
	    }
	    val = get_map_lvalue(m, &arg, 1);
	    free_svalue(&arg);

	    if (!restore_one(val, str) ||
		*(*str)++ != ',')
		break;
	}
    }
    free_mapping(m);
    return 0;
}
コード例 #18
0
ファイル: ultrautil.c プロジェクト: Letractively/caudium
INLINE void mapaddstrint( struct mapping * mappingen,
			  struct pike_string *key,
			  int subkey)
{
  struct svalue *s;                                                   
  struct svalue skey;
  skey.type = T_STRING;
  skey.u.string = key;
  s = LML( mappingen, &skey );                 
  if( !s ) {
    struct svalue mappie;                                           
    struct mapping *map = allocate_mapping(1);
    mappie.type = T_MAPPING;
    mappie.u.mapping = map;
    mapping_insert( mappingen, &skey, &mappie);
    mapaddint(map, subkey);
    /*    mapaddint(map, 0);*/
    free_mapping(map);
  } else {
    mapaddint(s->u.mapping, subkey);
    /*    mapaddint(s->u.mapping, 0);*/
  }
}  
コード例 #19
0
ファイル: pkg-odbc.c プロジェクト: Fuchur/ldmud
/*************************************************************************
 * f_sql_odbc_datasources( void )
 *
 * returns a mapping of all defined datasources.
 * ([ name : description ])
 *************************************************************************/
svalue_t *
f_sql_odbc_datasources( svalue_t * argv, int argc )
{
#if ODBC_DEBUG & DEBUG_FUNC
   printf( "call f_sql_odbc_datasources( )\n" );
#endif
   SQLRETURN   ret;
   
   char        * err;
   
   char        dsName[ 256 ],
               dsDescription[ 256 ];
   SQLSMALLINT dsNameLen,
               dsDescriptionLen;
   
   mapping_t   * map;
   svalue_t    * key;
   svalue_t    * value;

   argv++;

   err = init_odbc_environment();
   if ( err ) {
      errorf( err );
      return( NULL );
   }
   
   map = allocate_mapping( 0, 1 );
   MEM_CHECK( map );
   
   do {
      ret = SQLDataSources( hODBCEnv->hODBCEnv, SQL_FETCH_NEXT, dsName, 256, &dsNameLen,
                                                                dsDescription, 256, &dsDescriptionLen );
      if ( SQL_SUCCEEDED( ret ) ) {
         key = pxalloc( sizeof( svalue_t ) );
         put_malloced_string( key, string_copy( dsName ) );

         value = get_map_lvalue( map, key ); 
         MEM_CHECK( value );

         put_malloced_string( value, string_copy( dsDescription ) );
      }
      
   } while( SQL_SUCCEEDED( ret ) );

   if ( ret != SQL_NO_DATA ) {
      char * err;
      err = extract_diagnostics_info( SQL_HANDLE_ENV, hODBCEnv->hODBCEnv );

      free_mapping( map );

      errorf( (err?err:"Failed to fetch datasource information.\n") );
      return( NULL );
   }

   put_mapping( argv, map );
   
#if ODBC_DEBUG & DEBUG_FUNC
   printf( "ret f_sql_odbc_datasources( )\n" );
#endif
   return( argv );
}
コード例 #20
0
static ngx_int_t ngx_http_f4fhds_handler(ngx_http_request_t *r)
{
    ngx_int_t    rc;
    ngx_chain_t  out;
    u_char *resp_body;
    ngx_buf_t   *resp;
    char *lastslash;
    char *segsuffix;
    size_t root;
    ngx_str_t path;
    ngx_str_t index_map = ngx_null_string;
    ngx_str_t mediafile_map = ngx_null_string;
    unsigned fragnum;
    uint32_t totalsize;
    ngx_table_elt_t *self;

    unsigned afraentries;
    unsigned g_afraentries, g_entry_size = 0;
    unsigned globaltable_offset;
    unsigned long long afraoffset = 0, offsetfromafra = 0;
    unsigned entryindex = 0;

    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
        return NGX_HTTP_NOT_ALLOWED;
    }
 
    if ( (rc = ngx_http_discard_request_body(r)) != NGX_OK ) {
        return rc;
    }

    if ( (self = ngx_list_push(&r->headers_out.headers)) == NULL ) {
        ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "Insufficient memory for ngx_list_push");
        return NGX_ERROR;
    }
    self->hash = 1;
    ngx_str_set(&self->key, "X-Inventos-F4FHDS-Version");
    ngx_str_set(&self->value, VERSION);
 
    ngx_http_map_uri_to_path(r, &path, &root, 0);

    ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "path=%s", path.data);

    lastslash = strrchr((char*)path.data, '/');
    ++lastslash;
    segsuffix = (char *)memmem(lastslash, path.len - (lastslash - (char *)path.data), "Seg1-Frag", 9);
    if ( segsuffix == NULL ) {
        return NGX_HTTP_NOT_FOUND;
    }
    segsuffix += 4; /* "Seg1" */

    fragnum = atoi(segsuffix + /* "-Frag" */ 5);
    if ( fragnum < 1 ) {
        return NGX_HTTP_NOT_FOUND;
    }

    memcpy(segsuffix, ".f4x", 4);
    path.len = segsuffix - (char*)path.data + 4;
    segsuffix[4] = 0;

    ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "f4x_path=%s", path.data);
    if ( (rc = make_mapping((const char *)path.data, &index_map, r)) != NGX_OK ) {
        return rc;
    }

    if ( index_map.len < 8 ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Wrong f4x afra size: %d in %s", index_map.len, path.data);
        goto GENERAL_ERROR;
    }
    if ( memcmp(index_map.data + 4, "afra", 4) != 0 ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Wrong f4x format: %s", path.data);
        goto GENERAL_ERROR;
    }
    if ( getboxlen(index_map.data) != index_map.len ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Wrong f4x prefix size: %d in %s", get32(index_map.data), path.data);
        goto GENERAL_ERROR;
    }

    if ( (index_map.data[12] & 0x20) == 0 ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Global entries are not present in %s", path.data);
        goto GENERAL_ERROR;
    }

    afraentries = get32(index_map.data + 17);
    globaltable_offset = 17 + 4 + afraentries * (8 /* time */ + ((index_map.data[12] & 0x40) ? 8 : 4)) + 4;
    if ( index_map.len < globaltable_offset ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Index file too short: %s", path.data);
        goto GENERAL_ERROR;
    }
    g_afraentries = get32(index_map.data + globaltable_offset - 4);

    switch ( index_map.data[12] & 0xc0 ) {
    case 0xc0: 
        g_entry_size = 32; 
        break;
    case 0x80: 
        g_entry_size = 24; 
        break;
    case 0x40: 
        g_entry_size = 28; 
        break;
    case 0:    
        g_entry_size = 20; 
        break;
    }

    ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "globaltable_offset=%d, afraentries=%d, g_afraentries=%d, entrysize=%d", 
                      globaltable_offset, afraentries, g_afraentries, g_entry_size
                     );

    if ( index_map.len < globaltable_offset + g_afraentries * g_entry_size ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Index file too short: %s, len=%d, need=%d, globaltable_offset=%d, afraentries=%d, g_afraentries=%d, entrysize=%d", 
                      path.data, index_map.len, globaltable_offset + g_afraentries * g_entry_size,
                      globaltable_offset, afraentries, g_afraentries, g_entry_size
                     );
        goto GENERAL_ERROR;
    }

#define FIND_SEGMENT(SEGSIZE, FRAGSIZE, AOSIZE, OFASIZE) \
        for ( entryindex = 0; entryindex < g_afraentries; ++entryindex ) { \
            u_char *pentry = index_map.data + globaltable_offset + entryindex * g_entry_size; \
            unsigned segment = get##SEGSIZE (pentry + 8); \
            unsigned fragment = get##FRAGSIZE (pentry + 8 + SEGSIZE/8); \
            if ( segment == 1 && fragment == fragnum ) { \
                afraoffset = get##AOSIZE (pentry + 8 + SEGSIZE/8 + FRAGSIZE/8); \
                offsetfromafra = get##OFASIZE (pentry + 8 + SEGSIZE/8 + FRAGSIZE/8 + AOSIZE/8); \
                break; \
            } \
        }


    switch ( index_map.data[12] & 0xc0 ) {
    case 0xc0: 
        FIND_SEGMENT(32, 32, 64, 64);
        break;
    case 0x80: 
        FIND_SEGMENT(32, 32, 32, 32);
        break;
    case 0x40: 
        FIND_SEGMENT(16, 16, 64, 64);
        break;
    case 0:    
        FIND_SEGMENT(16, 16, 32, 32);
        break;
    }
    if ( entryindex == g_afraentries ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Fragment #%d not found in %s, g_afraentries=%d", fragnum, path.data, g_afraentries);
        goto NOT_FOUND;
    }
    if ( offsetfromafra != 0 ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "OffsetFromAfra=%llu not supported, %s", offsetfromafra, path.data);
        goto GENERAL_ERROR;
    }


    memcpy(segsuffix, ".f4f", 4);
    if ( (rc = make_mapping((const char *)path.data, &mediafile_map, r)) != NGX_OK ) {
        return rc;
    }

    if ( mediafile_map.len < afraoffset + 8 ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Mediafile is too short: %s", path.data);
        goto GENERAL_ERROR;
    }

    {
    const u_char *afra = mediafile_map.data + afraoffset;
    unsigned long long afralen = getboxlen(afra);
    const u_char *abst = afra + afralen;
    unsigned long long abstlen = getboxlen(abst);
    const u_char *moof = abst + abstlen;
    unsigned long long mooflen = getboxlen(moof);
    const u_char *mdat = moof + mooflen;
    unsigned long long mdatlen = getboxlen(mdat);
    totalsize = afralen + abstlen + mooflen + mdatlen;
    if ( (resp_body = ngx_pcalloc(r->pool, totalsize)) == NULL ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Insufficient memory");
        goto GENERAL_ERROR;
    }
    memcpy(resp_body, afra, totalsize);
    }

    if ( (resp = ngx_pcalloc(r->pool, sizeof(ngx_buf_t))) == NULL ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Insufficient memory");
        goto GENERAL_ERROR;
    }
 
    out.buf = resp;
    out.next = NULL;

    resp->pos = resp_body;
    resp->last = resp_body + totalsize;
    resp->memory = 1; 
    resp->last_buf = 1;
 
    free_mapping(&index_map);
    free_mapping(&mediafile_map);

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = totalsize;

    rc = ngx_http_send_header(r);
    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only || r->method == NGX_HTTP_HEAD) {
        return rc;
    }

    return ngx_http_output_filter(r, &out);

GENERAL_ERROR:
    free_mapping(&index_map);
    free_mapping(&mediafile_map);
    return NGX_HTTP_INTERNAL_SERVER_ERROR;

NOT_FOUND:
    free_mapping(&index_map);
    free_mapping(&mediafile_map);
    return NGX_HTTP_NOT_FOUND;

}
コード例 #21
0
ファイル: mg.c プロジェクト: carriercomm/mudos-1
INLINE void bson_to_mapping P2(const char *, data, svalue_t *, v){
	int id;
	int oi;
	int mask;
	int size;
	int count = 0;
	const char *key_c;
	bson_iterator i;
	mapping_t *m;
	svalue_t key, value;
	mapping_node_t **a, *elt, *elt2;

	size = sizeof_bson(data);
	if (!size) {
		v->type = T_MAPPING;
		v->u.map = allocate_mapping(0);
		return;
    }
    m = allocate_mapping(size);
    a = m->table;                    
    mask = m->table_size;
	bson_iterator_from_buffer( &i, data );
	while(bson_iterator_next( &i )){
		key_c = bson_iterator_key( &i );
		key.u.string = make_shared_string(key_c);
    	key.type = T_STRING;
    	key.subtype = STRING_SHARED;
		bson_to_v(&i,&value);
		oi = MAP_POINTER_HASH(key.u.number);
		id = oi & mask;
		if ((elt2 = elt = a[id])) {
		    do {
			/* This should never happen, but don't bail on it */
				if (msameval(&key, elt->values)) {
				    free_svalue(&key, "bson_to_map: duplicate key");
				    free_svalue(elt->values+1, "bson_to_map: replaced value");
				    *(elt->values+1) = value;
				    break;
				}
		    } while ((elt = elt->next));
		    if (elt)
				continue;
		} else if (!(--m->unfilled)) {
		    if (growMap(m)) {
				a = m->table;
				if (oi & ++mask) 
					elt2 = a[id |= mask];
				mask <<= 1;
				mask--;
		    } else {
				add_map_stats(m, count);
				free_mapping(m);
				free_svalue(&key, "bson_to_map: out of memory");
				free_svalue(&value, "bson_to_map: out of memory");
				error("Out of memory\n");
		    }
		}
	
		if (++count > MAX_MAPPING_SIZE) {
		    add_map_stats(m, count -1);
		    free_mapping(m);
		    free_svalue(&key, "bson_to_map: mapping too large");
		    free_svalue(&value, "bson_to_map: mapping too large");
		    mapping_too_large();
		}
		elt = new_map_node();
		*elt->values = key;
		*(elt->values + 1) = value;
		(a[id] = elt)->next = elt2;
	}
	add_map_stats(m, count);
    v->type = T_MAPPING;
    v->u.map = m;
}
コード例 #22
0
static ngx_int_t ngx_http_mp4frag_handler(ngx_http_request_t *r)
{
    ngx_int_t    rc;
    ngx_chain_t  out;
    u_char *resp_body;
    ngx_buf_t   *resp;
    char *lastslash;
    char *mediafilename;
    u_char *last;
    size_t root;
    ngx_str_t path;
    ngx_str_t index_map = ngx_null_string;
    const u_char *indexptr;
    ngx_str_t mediafile_map = ngx_null_string;
    unsigned medianum, fragnum;
    uint16_t nmedia;
    ngx_str_t videocodecdata, audiocodecdata;
    uint32_t mediaoffset, fragments_offset;
    uint16_t mediafilenamelen;
    uint16_t nsamples, nfragments;
    uint32_t totalsize;
    unsigned int iii;

    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
        return NGX_HTTP_NOT_ALLOWED;
    }
 
    /* discard request body, since we don't need it here */
    rc = ngx_http_discard_request_body(r);
 
    if (rc != NGX_OK) {
        return rc;
    }
 
#if 0
    /* set the 'Content-type' header */
    r->headers_out.content_type.len = sizeof("text/html") - 1;
    r->headers_out.content_type.data = (u_char *) "text/html";
#endif
 
    last = ngx_http_map_uri_to_path(r, &path, &root, 0);
    lastslash = strrchr((char*)path.data, '/');
    if ( lastslash ) {
        path.len = lastslash - (char*)path.data;
    }

    /* определить путь к файлу индекса и номер фрагмента: */
    *lastslash++ = 0;
    // uri - dirname, lastslash - basename
    if ( memcmp(lastslash, "Seg1-Frag", 9) != 0 ) {
        return NGX_HTTP_NOT_FOUND;
    }
    fragnum = atoi(lastslash + 9);

    lastslash = strrchr((char*)path.data, '/');
    if ( !lastslash ) {
        return NGX_HTTP_NOT_FOUND;
    }
    medianum = atoi(lastslash + 1);

    memcpy(lastslash + 1, "index", 6);
    
    if ( (rc = make_mapping((const char *)path.data, &index_map, r)) != NGX_OK ) {
        return rc;
    }
    indexptr = index_map.data;

#define CHECKMAP(nbytes) do { if (indexptr + nbytes >= index_map.data + index_map.len) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "index underrun, offset 0x%0x", nbytes); goto GENERAL_ERROR;}  } while(0)

    CHECKMAP(10); /* 8 for signature and 2 for media count */
    if ( memcmp(index_map.data, "mp4frag", 7) != 0 || index_map.data[7] /* version */ > 2 ) {
        free_mapping(&index_map);
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Bad index format in %s", path.data);
        goto GENERAL_ERROR;
    }
    indexptr += 8;

    nmedia = get16(indexptr);
    if ( medianum >= nmedia ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "No media #%d in %s, total %d media", medianum, path.data, nmedia);
        goto GENERAL_ERROR;
    }
    indexptr += 2;
    CHECKMAP(nmedia * 4);

    mediaoffset = get32(indexptr + medianum * 4);
    if ( mediaoffset >= index_map.len ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "short index in %s", path.data);
        goto GENERAL_ERROR;
    }
    indexptr = index_map.data;
    CHECKMAP(mediaoffset);
    indexptr = index_map.data + mediaoffset;

    CHECKMAP(2);
    mediafilenamelen = get16(indexptr);
    indexptr += 2;
    CHECKMAP(mediafilenamelen);
    if ( index_map.data[7] == 1 ) {
        if ( (mediafilename = ngx_pcalloc(r->pool, mediafilenamelen + 1)) == NULL ) {
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Insufficient memory");
            goto GENERAL_ERROR;
        }
        memcpy(mediafilename, (const char *)indexptr, mediafilenamelen);
        mediafilename[mediafilenamelen] = 0;
    }
    else /* index_map.data[7] == 2 */ {
        mediafilename = (char *)indexptr;
    }

    indexptr += mediafilenamelen;
 
    CHECKMAP(2);
    videocodecdata.len = get16(indexptr);
    indexptr += 2;
    CHECKMAP(videocodecdata.len);
    videocodecdata.data = (u_char*)indexptr;
    indexptr += videocodecdata.len;
    CHECKMAP(2);
    audiocodecdata.len = get16(indexptr);
    indexptr += 2;
    CHECKMAP(audiocodecdata.len);
    audiocodecdata.data = (u_char*)indexptr;
    indexptr += audiocodecdata.len;

    /* number of fragments in the media */
    CHECKMAP(2);
    nfragments = get16(indexptr);
    if ( fragnum > nfragments || fragnum < 1 ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "No fragment #%d in media #%d in file %s", fragnum, medianum, path.data);
        goto NOT_FOUND;
    }
    indexptr += 2;

    CHECKMAP(nfragments * 4);

    fragments_offset = get32(indexptr + (fragnum - 1) * 4);
    indexptr = index_map.data;
    CHECKMAP(fragments_offset);
    indexptr += fragments_offset;

    CHECKMAP(6);  /* first entry should present anyway */
    nsamples = get16(indexptr);
    if ( nsamples < 1 ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Number of samples is 0 for media #%d, fragment #%d, index %s",
                      medianum, fragnum, path.data);
        goto GENERAL_ERROR;
    }

    /* total fragment size in bytes: */
    totalsize = get32(indexptr + 2);

    ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "nsamples=%d, totalsize=%d", nsamples, totalsize);

    indexptr += 6;

    /* allocate memory for response */
    if ( (resp_body = ngx_pcalloc(r->pool, totalsize)) == NULL ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Insufficient memory");
        goto GENERAL_ERROR;
    }

    if ( (resp = ngx_pcalloc(r->pool, sizeof(ngx_buf_t))) == NULL ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Insufficient memory");
        goto GENERAL_ERROR;
    }
 
    out.buf = resp;
    out.next = NULL;

    resp->pos = resp_body;
    resp->last = resp_body + totalsize;
    resp->memory = 1; 
    resp->last_buf = 1;
 
    if ( make_mapping(mediafilename, &mediafile_map, r) != NGX_OK ) goto GENERAL_ERROR;
 
    /* generate the fragment */
    write32(resp_body, totalsize);
    memcpy(resp_body + 4, "mdat", 4);

    CHECKMAP(16 * nsamples - 1); /* check if the last byte still inside the index */

    /* fragment timestamp is equal to first sample timestamp */
    resp_body = write_fragment_prefix(resp_body + 8, &videocodecdata, &audiocodecdata, get32(indexptr + 8));

    for ( iii = 0; iii < nsamples; ++iii ) {
        uint32_t offset = get32(indexptr);
        uint32_t size = get32(indexptr + 4);
        uint32_t timestamp = get32(indexptr + 8);
        uint32_t composition_offset = get24(indexptr + 12);
        uint8_t flags = indexptr[15];
        indexptr += 16;
        if ( flags ) {
            resp_body = write_video_packet(resp_body, flags & 2, 0, composition_offset, timestamp,
                                     mediafile_map.data + offset, size);
        }
        else {
            resp_body = write_audio_packet(resp_body, 0, timestamp, mediafile_map.data + offset, size);
        }
    }

    free_mapping(&index_map);
    free_mapping(&mediafile_map);

    if ( resp_body != resp->last ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "response buffer overrun");
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = totalsize;

    rc = ngx_http_send_header(r);
    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only || r->method == NGX_HTTP_HEAD) {
        return rc;
    }

    /* send the buffer chain of your response */
    return ngx_http_output_filter(r, &out);

GENERAL_ERROR:
    free_mapping(&index_map);
    free_mapping(&mediafile_map);
    return NGX_HTTP_INTERNAL_SERVER_ERROR;

NOT_FOUND:
    free_mapping(&index_map);
    free_mapping(&mediafile_map);
    return NGX_HTTP_NOT_FOUND;

}
コード例 #23
0
ファイル: ultraparse.c プロジェクト: Letractively/caudium
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;
}
コード例 #24
0
ファイル: cfuns.c プロジェクト: xcw0579/mudOS
void c_add() {
    switch (sp->type) {
#ifndef NO_BUFFER_TYPE
    case T_BUFFER:
	{
	    if (!((sp-1)->type == T_BUFFER)) {
		error("Bad type argument to +. Had %s and %s.\n",
		      type_name((sp - 1)->type), type_name(sp->type));
	    } else {
		buffer_t *b;
		
		b = allocate_buffer(sp->u.buf->size + (sp - 1)->u.buf->size);
		memcpy(b->item, (sp - 1)->u.buf->item, (sp - 1)->u.buf->size);
		memcpy(b->item + (sp - 1)->u.buf->size, sp->u.buf->item,
		       sp->u.buf->size);
		free_buffer((sp--)->u.buf);
		free_buffer(sp->u.buf);
		sp->u.buf = b;
	    }
	    break;
	} /* end of x + T_BUFFER */
#endif
    case T_NUMBER:
	{
	    switch ((--sp)->type) {
	    case T_NUMBER:
		sp->u.number += (sp+1)->u.number;
		break;
	    case T_REAL:
		sp->u.real += (sp+1)->u.number;
		break;
	    case T_STRING:
		{
		    char buff[20];
		    
		    sprintf(buff, "%d", (sp+1)->u.number);
		    EXTEND_SVALUE_STRING(sp, buff, "f_add: 2");
		    break;
		}
	    default:
		error("Bad type argument to +.  Had %s and %s.\n",
		      type_name(sp->type), type_name((sp+1)->type));
	    }
	    break;
	} /* end of x + NUMBER */
    case T_REAL:
	{
	    switch ((--sp)->type) {
	    case T_NUMBER:
		sp->type = T_REAL;
		sp->u.real = sp->u.number + (sp+1)->u.real;
		break;
	    case T_REAL:
		sp->u.real += (sp+1)->u.real;
		break;
	    case T_STRING:
		{
		    char buff[40];
		    
		    sprintf(buff, "%f", (sp+1)->u.real);
		    EXTEND_SVALUE_STRING(sp, buff, "f_add: 2");
		    break;
		}
	    default:
		error("Bad type argument to +. Had %s and %s\n",
		      type_name(sp->type), type_name((sp+1)->type));
	    }
	    break;
	} /* end of x + T_REAL */
    case T_ARRAY:
	{
	    if (!((sp-1)->type == T_ARRAY)) {
		error("Bad type argument to +. Had %s and %s\n",
		      type_name((sp - 1)->type), type_name(sp->type));
	    } else {
		/* add_array now free's the arrays */
		(sp-1)->u.arr = add_array((sp - 1)->u.arr, sp->u.arr);
		sp--;
		break;
	    }
	} /* end of x + T_ARRAY */
    case T_MAPPING:
	{
	    if ((sp-1)->type == T_MAPPING) {
		mapping_t *map;
		
		map = add_mapping((sp - 1)->u.map, sp->u.map);
		free_mapping((sp--)->u.map);
		free_mapping(sp->u.map);
		sp->u.map = map;
		break;
	    } else
		error("Bad type argument to +. Had %s and %s\n",
		      type_name((sp - 1)->type), type_name(sp->type));
	} /* end of x + T_MAPPING */
    case T_STRING:
	{
	    switch ((sp-1)->type) {
	    case T_NUMBER:
		{
		    char buff[20];
		    
		    sprintf(buff, "%d", (sp-1)->u.number);
		    SVALUE_STRING_ADD_LEFT(buff, "f_add: 3");
		    break;
		} /* end of T_NUMBER + T_STRING */
	    case T_REAL:
		{
		    char buff[40];
		    
		    sprintf(buff, "%f", (sp - 1)->u.real);
		    SVALUE_STRING_ADD_LEFT(buff, "f_add: 3");
		    break;
		} /* end of T_REAL + T_STRING */
	    case T_STRING:
		{
		    SVALUE_STRING_JOIN(sp-1, sp, "f_add: 1");
		    sp--;
		    break;
		} /* end of T_STRING + T_STRING */
	    default:
		error("Bad type argument to +. Had %s and %s\n",
		      type_name((sp - 1)->type), type_name(sp->type));
	    }
	    break;
	} /* end of x + T_STRING */
	
    default:
	error("Bad type argument to +.  Had %s and %s.\n",
	      type_name((sp-1)->type), type_name(sp->type));
    }
}
コード例 #25
0
ファイル: cfuns.c プロジェクト: xcw0579/mudOS
void c_add_eq(int  is_void) {
    DEBUG_CHECK(sp->type != T_LVALUE,
		"non-lvalue argument to +=\n");
    lval = sp->u.lvalue;
    sp--; /* points to the RHS */
    switch (lval->type) {
    case T_STRING:
	if (sp->type == T_STRING) {
	    SVALUE_STRING_JOIN(lval, sp, "f_add_eq: 1");
	} else if (sp->type == T_NUMBER) {
	    char buff[20];
	    
	    sprintf(buff, "%d", sp->u.number);
	    EXTEND_SVALUE_STRING(lval, buff, "f_add_eq: 2");
	} else if (sp->type == T_REAL) {
	    char buff[40];
	    
	    sprintf(buff, "%f", sp->u.real);
	    EXTEND_SVALUE_STRING(lval, buff, "f_add_eq: 2");
	} else {
	    bad_argument(sp, T_STRING | T_NUMBER | T_REAL, 2,
			 (is_void ? F_VOID_ADD_EQ : F_ADD_EQ));
	}
	break;
    case T_NUMBER:
	if (sp->type == T_NUMBER) {
	    lval->u.number += sp->u.number;
	    /* both sides are numbers, no freeing required */
	} else if (sp->type == T_REAL) {
	    lval->u.number += sp->u.real;
	    /* both sides are numbers, no freeing required */
	} else {
	    error("Left hand side of += is a number (or zero); right side is not a number.\n");
	}
	break;
    case T_REAL:
	if (sp->type == T_NUMBER) {
	    lval->u.real += sp->u.number;
	    /* both sides are numerics, no freeing required */
	}
	if (sp->type == T_REAL) {
	    lval->u.real += sp->u.real;
	    /* both sides are numerics, no freeing required */
	} else {
	    error("Left hand side of += is a number (or zero); right side is not a number.\n");
	}
	break;
#ifndef NO_BUFFER_TYPE
    case T_BUFFER:
	if (sp->type != T_BUFFER) {
	    bad_argument(sp, T_BUFFER, 2, (is_void ? F_VOID_ADD_EQ : F_ADD_EQ));
	} else {
	    buffer_t *b;
	    
	    b = allocate_buffer(lval->u.buf->size + sp->u.buf->size);
	    memcpy(b->item, lval->u.buf->item, lval->u.buf->size);
	    memcpy(b->item + lval->u.buf->size, sp->u.buf->item,
		   sp->u.buf->size);
	    free_buffer(sp->u.buf);
	    free_buffer(lval->u.buf);
	    lval->u.buf = b;
	}
	break;
#endif
    case T_ARRAY:
	if (sp->type != T_ARRAY)
	    bad_argument(sp, T_ARRAY, 2, (is_void ? F_VOID_ADD_EQ : F_ADD_EQ));
	else {
	    /* add_array now frees the arrays */
	    lval->u.arr = add_array(lval->u.arr, sp->u.arr);
	}
	break;
    case T_MAPPING:
	if (sp->type != T_MAPPING)
	    bad_argument(sp, T_MAPPING, 2, (is_void ? F_VOID_ADD_EQ : F_ADD_EQ));
	else {
	    absorb_mapping(lval->u.map, sp->u.map);
	    free_mapping(sp->u.map);	/* free RHS */
	    /* LHS not freed because its being reused */
	}
	break;
    case T_LVALUE_BYTE:
	if (sp->type != T_NUMBER)
	    error("Bad right type to += of char lvalue.\n");
	else *global_lvalue_byte.u.lvalue_byte += sp->u.number;
	break;
    default:
	bad_arg(1, (is_void ? F_VOID_ADD_EQ : F_ADD_EQ));
    }
    
    if (!is_void) {	/* not void add_eq */
	assign_svalue_no_free(sp, lval);
    } else {
	/*
	 * but if (void)add_eq then no need to produce an
	 * rvalue
	 */
	sp--;
    }
}
コード例 #26
0
ファイル: cfuns.c プロジェクト: xcw0579/mudOS
void c_index() {
    int i;
    
    switch (sp->type) {
    case T_MAPPING:
	{
	    svalue_t *v;
	    mapping_t *m;
	    
	    v = find_in_mapping(m = sp->u.map, sp - 1);
	    assign_svalue(--sp, v);    /* v will always have a
					* value */
	    free_mapping(m);
	    break;
	}
#ifndef NO_BUFFER_TYPE
    case T_BUFFER:
	{
	    if ((sp-1)->type != T_NUMBER)
		error("Indexing a buffer with an illegal type.\n");
	    
	    i = (sp - 1)->u.number;
	    if ((i > sp->u.buf->size) || (i < 0))
		error("Buffer index out of bounds.\n");
	    i = sp->u.buf->item[i];
	    free_buffer(sp->u.buf);
	    (--sp)->u.number = i;
	    break;
	}
#endif
    case T_STRING:
	{
	    if ((sp-1)->type != T_NUMBER) {
		error("Indexing a string with an illegal type.\n");
	    }
	    i = (sp - 1)->u.number;
	    if ((i > SVALUE_STRLEN(sp)) || (i < 0))
		error("String index out of bounds.\n");
	    i = (unsigned char) sp->u.string[i];
	    free_string_svalue(sp);
	    (--sp)->u.number = i;
	    break;
	}
    case T_ARRAY:
	{
	    array_t *arr;
	    
	    if ((sp-1)->type != T_NUMBER)
		error("Indexing an array with an illegal type\n");
	    i = (sp - 1)->u.number;
	    if (i<0) error("Negative index passed to array.\n");
	    arr = sp->u.arr;
	    if (i >= arr->size) error("Array index out of bounds.\n");
	    assign_svalue_no_free(--sp, &arr->item[i]);
	    free_array(arr);
	    break;
	}
    default:
	error("Indexing on illegal type.\n");
    }
    
    /*
     * Fetch value of a variable. It is possible that it is a
     * variable that points to a destructed object. In that case,
     * it has to be replaced by 0.
     */
    if (sp->type == T_OBJECT && (sp->u.ob->flags & O_DESTRUCTED)) {
	free_object(sp->u.ob, "F_INDEX");
	*sp = const0u;
    }
}