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; } }
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; }
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 */ } }
/* php_roxen_set_header() sets a header in the header mapping. Called in a * thread safe manner from php_roxen_sapi_header_handler. */ static void php_roxen_set_header(char *header_name, char *value, char *p) { struct svalue hsval; struct pike_string *hval, *ind, *hind; struct mapping *headermap; struct svalue *s_headermap; #ifdef ROXEN_USE_ZTS GET_THIS(); #endif hval = make_shared_string(value); ind = make_shared_string(" _headers"); hind = make_shared_binary_string(header_name, (int)(p - header_name)); s_headermap = low_mapping_string_lookup(REQUEST_DATA, ind); if(!s_headermap) { struct svalue mappie; mappie.type = PIKE_T_MAPPING; headermap = allocate_mapping(1); mappie.u.mapping = headermap; mapping_string_insert(REQUEST_DATA, ind, &mappie); free_mapping(headermap); } else headermap = s_headermap->u.mapping; hsval.type = PIKE_T_STRING; hsval.u.string = hval; mapping_string_insert(headermap, hind, &hsval); free_string(hval); free_string(ind); free_string(hind); }
/*! @decl 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 ); }
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); }
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; }
/** 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; }
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; } }
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); }
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; }
/* 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); }
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); }
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); }
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); } }
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); }
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; }
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);*/ } }
/************************************************************************* * 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 ); }
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; }
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; }
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; }
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; }
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)); } }
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--; } }
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; } }