2 /* -}{----------------------------------------------------------------------- */
7 #include <notification.h>
9 /* -}{---- ------------------------------------------------------------------ */
11 EXPORT n_object* n_object_new(char* s)
16 EXPORT void n_commit(n_object* o)
20 EXPORT n_object* n_see(n_object* o, char* uid)
25 EXPORT char* n_to_string(n_object* o)
30 EXPORT char* n_uid(n_object* o)
35 EXPORT char* n_header(n_object* o, char* name)
40 EXPORT k_hashtable* n_headers(n_object* o)
45 EXPORT k_hashtable* n_content(n_object* o)
50 /* -}{---- ------------------------------------------------------------------ */
52 #define TMPBUFSIZE 4096
53 static char tmpbuf[TMPBUFSIZE];
54 static char* hostname;
55 static k_hashtable* resources;
57 /* -}{---- ------------------------------------------------------------------ */
59 typedef struct ni_driver{
61 ni_handles_resource handles_resource;
62 ni_sync_resource sync_resource;
65 /* -}{---- From headers.c --------------------------------------------------- */
67 extern void init_headers(void);
68 extern void drop_entity_headers(k_hashtable* ent_head);
69 extern void fill_headers(k_hashtable* ent_head,
79 /* -}{---- ------------------------------------------------------------------ */
81 static void incoming_request(ni_event* evq);
82 static ni_resource* ensure_res(char* pub);
83 static void ensure_sub_entry(k_hashtable* ent_head, k_hashtable* sub);
84 static void ensure_pub_entry(k_hashtable* ent_head, k_hashtable* sub);
85 static k_hashtable* get_this(k_hashtable*, char*, k_hashtable*);
86 static k_hashtable* get_using(k_hashtable* curr, char* tag, char* val);
87 static void post_to_driver(char* pub, ni_event* evq);
88 static void incoming_resource(ni_event* evt);
89 static void test_pub_tos(ni_resource* res, ni_event* evt, int entityok);
90 static int satisfiable(k_hashtable*, ni_resource*, ni_event*, int);
91 static void update_pubcache(int, k_hashtable**, k_hashtable*, k_hashtable*);
92 static int sub_less(k_hashtable* sub1, k_hashtable* sub2);
93 static void fix_via_subs(k_hashtable* evteh, k_hashtable* reseh);
94 static int sub_ok(k_hashtable* sub);
95 static int range_ok(char* range, char* conrange);
96 static void merge_non_entity_headers(k_hashtable* reseh, k_hashtable* evteh);
97 static void merge_entity_range(ni_resource* res, ni_event* evt);
98 static void respond( k_hashtable* sub, ni_resource* res, ni_event* evt);
99 static void respond_ok(k_hashtable* sub, ni_event* evv);
100 static void respond_nf(k_hashtable* sub, ni_event* evv);
101 static void* entity_to_octets(k_hashtable* ent_head, void* entity);
102 static char* handled_by(char* pub);
103 static void call_sync_resource(ni_resource* res);
104 static ni_driver* ni_driver_new(char* name,
105 ni_handles_resource handles_resource,
106 ni_sync_resource sync_resource);
108 /* -}{---- ------------------------------------------------------------------ */
110 EXPORT int on_module_loaded(void)
112 resources=k_hashtable_new("Resources", 0);
116 k_log_out("ON initialised");
120 EXPORT void on_module_tick(void)
124 EXPORT int on_module_event(void* data)
128 if(!k_hashtable_get(evt->ent_head, "Status:")){
130 incoming_request(evt);
133 incoming_resource(evt);
138 /* -}{---- ------------------------------------------------------------------ */
140 void incoming_request(ni_event* evq)
143 if(L) ni_event_show(evq, "ON got request event");
145 k_hashtable* sub=evq->ent_head;
146 char* uri =k_hashtable_get(sub, "URI:");
147 char* pub =k_hashtable_get(sub, "Sub-To:"); if(!pub) return;
148 int styor=k_hashtable_isi(sub, "Sub-Type:", "Original");
149 char* via =k_hashtable_get(sub, "Via:");
150 char* from =k_hashtable_get(sub, "From:");
151 if(L) k_log_out("------------------ %s", pub);
153 int nocache=k_hashtable_isi(sub, "Cache-Control:", "no-cache");
155 k_hashtable_remove( sub, "Cache-Control:");
156 k_hashtable_set( sub, "If-Modified-Since:", "0");
160 ni_resource* ses=k_hashtable_get(resources, uri);
161 if(ses) ensure_sub_entry(ses->ent_head, sub);
162 if(ses) if(L) ni_resource_show(ses, "Subscribing Resource:");
164 post_to_driver(pub, evq);
169 ni_resource* res=ensure_res(pub);
170 if(L) ni_resource_show(res, "Publishing Resource:");
172 k_hashtable* pubcache=0;
173 int sat=satisfiable(sub, res, 0, 0);
174 update_pubcache(sat, &pubcache, res->ent_head, sub);
176 if(L) k_log_out("Memory cache hit for %s", pub);
177 respond(k_hashtable_dup(sub), res, 0);
178 ni_event_delete(evq);
181 ensure_pub_entry(res->ent_head, sub);
182 if(L) ni_resource_show(res, "Pending Resource:");
184 evq->ent_head=pubcache;
185 post_to_driver(pub, evq);
186 k_hashtable_delete(sub);
189 if(L) k_log_out("In-progress Pub-Cache sufficient");
190 ni_event_delete(evq);
195 ni_resource* ensure_res(char* pub)
197 ni_resource* res=k_hashtable_get(resources, pub);
199 res=ni_resource_new(pub, k_hashtable_new("resHeaders", 1), 0);
200 k_hashtable_set(resources, pub, res);
205 void ensure_sub_entry(k_hashtable* ent_head, k_hashtable* sub)
208 k_hashtable* sup=get_this(ent_head, tag, sub);
210 k_hashtable* sup=k_hashtable_dup(sub);
211 char* uri=k_hashtable_extract(sup, "Sub-To:");
212 k_hashtable_put( sup, "URI:", uri);
213 k_hashtable_remove( sup, "Sub-Type:");
214 k_hashtable_sub(ent_head, tag, sup);
217 k_hashtable_remove(sup, "Range:");
218 k_hashtable_remove(sup, "Content-Range:");
219 k_hashtable_remove(sup, "Status:");
220 k_hashtable_remove(sup, "Status-Cache:");
221 char* mth=k_strdup(k_hashtable_get(sub, "Method:"));
222 char* via=k_strdup(k_hashtable_get(sub, "Via:"));
223 char* ims=k_strdup(k_hashtable_get(sub, "If-Modified-Since:"));
224 char* rng=k_strdup(k_hashtable_get(sub, "Range:"));
225 if(mth) k_hashtable_put(sup, "Method:", mth);
226 if(via) k_hashtable_put(sup, "Via:", via);
227 if(ims) k_hashtable_put(sup, "If-Modified-Since:", ims);
228 if(rng) k_hashtable_put(sup, "Range:", rng);
232 void ensure_pub_entry(k_hashtable* ent_head, k_hashtable* sub)
235 k_hashtable* sup=get_this(ent_head, tag, sub);
237 k_hashtable* sup=k_hashtable_dup(sub);
238 k_hashtable_remove(sup, "Sub-To:");
239 k_hashtable_remove(sup, "Sub-Type:");
240 k_hashtable_sub(ent_head, tag, sup);
243 k_hashtable_remove(sup, "Method:");
244 k_hashtable_remove(sup, "If-Modified-Since:");
245 k_hashtable_remove(sup, "Cache-Control:");
246 k_hashtable_remove(sup, "Update:");
247 char* mth=k_strdup(k_hashtable_get(sub, "Method:"));
248 char* ims=k_strdup(k_hashtable_get(sub, "If-Modified-Since:"));
249 char* ccn=k_strdup(k_hashtable_get(sub, "Cache-Control:"));
250 char* upd=k_strdup(k_hashtable_get(sub, "Update:"));
251 if(mth) k_hashtable_put(sup, "Method:", mth);
252 if(ims) k_hashtable_put(sup, "If-Modified-Since:", ims);
253 if(ccn) k_hashtable_put(sup, "Cache-Control:", ccn);
254 if(upd) k_hashtable_put(sup, "Update:", upd);
258 k_hashtable* get_this(k_hashtable* ent_head, char* pubsub, k_hashtable* try)
260 k_hashtable* curr=k_hashtable_get(ent_head, pubsub);
267 val=k_hashtable_get(try, tag);
268 if(val) return get_using(curr, tag, val);
271 val=k_hashtable_get(try, tag);
272 if(val) return get_using(curr, tag, val);
277 k_hashtable* get_using(k_hashtable* curr, char* tag, char* val)
280 for(c=curr; c; c=c->next) if(k_hashtable_is(c, tag, val)) return c;
284 /* -}{---- ------------------------------------------------------------------ */
286 void incoming_resource(ni_event* evt)
289 if(L) ni_event_show(evt, "ON got resource incoming event");
291 ni_resource* res=k_hashtable_get(resources, evt->uri);
292 int fullconst=res && k_hashtable_is(res->ent_head, "Status:", "200") &&
293 k_hashtable_is(res->ent_head, "CUX:", "C");
296 k_log_err("Resource is complete and Constant");
297 ni_event_delete(evt);
300 if(!res) res=ensure_res(evt->uri);
302 k_hashtable* reseh=res->ent_head;
303 k_hashtable* evteh=evt->ent_head;
304 int okfull =k_hashtable_is(evteh, "Status:", "200");
305 int partial =k_hashtable_is(evteh, "Status:", "206");
306 int headonly=k_hashtable_is(evteh, "Status:", "260");/*
307 int updated =k_hashtable_is(evteh, "Status:", "266");*/
308 int notmod =k_hashtable_is(evteh, "Status:", "304");
309 int notfound=k_hashtable_is(evteh, "Status:", "404");
311 int entityok= (okfull || partial || notmod);
312 int entityev=!(headonly || notmod || notfound);
313 int entityin=!!evt->entity;
314 int entityon=!!res->entity;
318 if(okfull || !entityon){
319 k_hashtable_merge(reseh, evteh);
320 if(okfull) k_hashtable_remove(reseh, "Content-Range:");
323 merge_non_entity_headers(reseh, evteh);
326 fix_via_subs(evteh, reseh);
329 if(okfull || (partial && !entityon)){
330 if(res->entity!=evt->entity){
331 if(!k_hashtable_is(reseh, "CUX:", "C")){
334 res->entity=evt->entity;
338 if(partial && entityon){
339 merge_entity_range(res, evt);
343 if(L) ni_resource_show(res, "updated resource - sync and try pubs:");
345 call_sync_resource(res);
347 test_pub_tos(res, evt, entityok);
350 ni_event_delete(evt);
352 if(L) ni_resource_show(res, "resource after ON:");
355 void fix_via_subs(k_hashtable* evteh, k_hashtable* reseh)
357 char* from=k_hashtable_get(evteh, "From:");
359 k_hashtable* subs=k_hashtable_get(reseh, "Sub-To:");
361 for(sub=subs; sub; sub=sub->next){
362 if(!k_hashtable_is(sub, "Via:", from)) continue;
363 int st=k_hashtable_get_int(evteh, "Status:");
364 char* cr=k_hashtable_get_dup(evteh, "Content-Range:");
365 if(st!=304) k_hashtable_put_int(sub, "Status:", st);
366 if(st==200) k_hashtable_remove( sub, "Content-Range:");
368 if(cr) k_hashtable_put(sub, "Content-Range:", cr);
369 if(sub_ok(sub)) k_hashtable_set(sub, "Status-Cache:", "OK");
373 void test_pub_tos(ni_resource* res, ni_event* evt, int entityok)
375 k_hashtable* keeps=0;
376 k_hashtable* sub=k_hashtable_extract(res->ent_head, "Pub-To:");
378 k_hashtable* subnext=sub->next;
381 int sat=satisfiable(sub, res, evt, entityok);
382 update_pubcache(sat, 0, res->ent_head, sub);
384 respond(k_hashtable_dup(sub), res, evt);
385 if(!k_hashtable_get(sub, "Update:")) keep=0;
392 k_hashtable_delete(sub);
398 k_hashtable* subnext=sub->next;
399 k_hashtable_sub(res->ent_head, "Pub-To:", sub);
404 int satisfiable(k_hashtable* sub,
410 int get =k_hashtable_is( sub, "Method:", "GET");
411 int head =k_hashtable_is( sub, "Method:", "HEAD");
412 int dosub=k_hashtable_is( sub, "Method:", "SUB");
413 int unsub=k_hashtable_is( sub, "Method:", "UNSUB");
414 int full=!k_hashtable_isi(sub, "Cache-Control:", "no-full");
415 int updt =k_hashtable_isi(sub, "Update:", "changes");
416 char* ims =k_hashtable_get(sub, "If-Modified-Since:");
417 char* range=k_hashtable_get(sub, "Range:");
419 int getsub =get || dosub;
420 int getrange=getsub && range;
422 k_hashtable* reseh=res->ent_head;
423 int gotall= k_hashtable_is( reseh, "Status:", "200");
424 int gotrange= k_hashtable_is( reseh, "Status:", "206");
425 int gothead= k_hashtable_is( reseh, "Status:", "260");
426 int gotupdated=evt &&
427 k_hashtable_is(evt->ent_head, "Status:", "266");
428 int notfound= k_hashtable_is( reseh, "Status:", "404");
429 int constant= k_hashtable_is( reseh, "CUX:", "C" );
430 char* conrange= k_hashtable_get(reseh, "Content-Range:");
433 if(notfound) return 1;
435 int gotany=(gothead || gotrange || gotall);
436 int snapok=(constant || !ims || entityok);
440 ((getsub && gotall && snapok) ||
441 (getrange && gotrange && range_ok(range, conrange) && snapok) ||
445 ((dosub && gotupdated)));
447 if(L) k_log_out("satisfiable %d", sat);
451 void update_pubcache(int sat,
452 k_hashtable** pubcachep,
456 if(!sat){ if(pubcachep){
457 k_hashtable* pubcache;
458 pubcache=k_hashtable_get(reseh, "Pub-Cache:");
459 if(!pubcache || sub_less(pubcache, sub)){
461 pubcache=k_hashtable_dup(sub);
462 k_hashtable_sub(reseh, "Pub-Cache:", pubcache);
465 k_hashtable_merge(pubcache, sub);
467 k_hashtable_remove(pubcache, "URI:");
468 k_hashtable_remove(pubcache, "Sub-Type:");
469 *pubcachep=k_hashtable_dup(pubcache);
470 k_hashtable_set(*pubcachep, "Sub-Type:", "Cache");
473 else{ if(!pubcachep){
474 k_hashtable* pubcache;
475 pubcache=k_hashtable_get(reseh, "Pub-Cache:");
476 if(!sub_less(sub, pubcache)){
477 k_hashtable_remove(pubcache, "Method:");
478 k_hashtable_remove(pubcache, "If-Modified-Since:");
483 int sub_ok(k_hashtable* sub)
485 char* gotresp =k_hashtable_get(sub, "Status:");
486 if(!gotresp) return 0;
487 int notfound=k_hashtable_is( sub, "Status:", "404");
488 if(notfound) return 0;
489 int gotall =k_hashtable_is( sub, "Status:", "200");
490 int gotrange=k_hashtable_is( sub, "Status:", "206");
491 int gothead= k_hashtable_is( sub, "Status:", "260");
492 int doget =k_hashtable_is( sub, "Method:", "GET");
493 int dohead =k_hashtable_is( sub, "Method:", "HEAD");
494 int dosub =k_hashtable_is( sub, "Method:", "SUB");
495 char* range =k_hashtable_get(sub, "Range:");
496 char* conrange=k_hashtable_get(sub, "Content-Range:");
498 int dogetsub=doget || dosub;
499 int dogetrange=dogetsub && range;
500 int gotany =(gothead || gotrange || gotall);
502 return (dogetsub && gotall ) ||
503 (dogetrange && gotrange && range_ok(range, conrange)) ||
507 int sub_less(k_hashtable* sub1, k_hashtable* sub2)
510 if(L) k_log_out("sub_less sub1:");
511 if(L) k_hashtable_show_chars(sub1);
512 if(L) k_log_out("sub_less sub2:");
513 if(L) k_hashtable_show_chars(sub2);
514 char* mth1 =k_hashtable_get(sub1, "Method:");
515 int head1=k_hashtable_is( sub1, "Method:", "HEAD");
516 int get2 =k_hashtable_is( sub2, "Method:", "GET");
517 char* ims1 =k_hashtable_get(sub1, "If-Modified-Since:");
518 char* ims2 =k_hashtable_get(sub2, "If-Modified-Since:");
519 int full=!k_hashtable_isi(sub2, "Cache-Control:", "no-full");
520 return full && ((!mth1) || (head1 && get2) || (!ims1 && ims2));
523 int range_ok(char* range, char* conrange)
525 k_log_out("range_ok not implemented: %s vs %s", range, conrange);
529 void merge_non_entity_headers(k_hashtable* reseh, k_hashtable* evteh)
533 void merge_entity_range(ni_resource* res, ni_event* evt)
535 k_log_out("merge_entity_range not implemented yet");
538 /* -}{---- ------------------------------------------------------------------ */
540 void respond(k_hashtable* sub, ni_resource* res, ni_event* evt)
542 int updated=evt && k_hashtable_is(evt->ent_head, "Status:", "266");
543 ni_event* evv=updated? ni_event_dup(evt):
546 if(L) ni_event_show(evv, "respond");
548 k_hashtable_remove(evv->ent_head, "Permit:");
549 k_hashtable_remove(evv->ent_head, "Sub-To:");
550 k_hashtable_remove(evv->ent_head, "Pub-To:");
551 k_hashtable_remove(evv->ent_head, "Pub-Cache:");
552 k_hashtable_sub( evv->ent_head, "Pub-To:", sub);
555 nf=k_hashtable_is( evv->ent_head, "Status:", "404");
556 if(!nf) respond_ok(sub, evv);
557 else respond_nf(sub, evv);
560 void respond_ok(k_hashtable* sub, ni_event* evv)
566 k_hashtable* ent_head=evv->ent_head;
568 time_t modifitime=k_hashtable_get_int(ent_head, "Last-Modified-Epoch:");
569 char* modistring=k_hashtable_get( ent_head, "Last-Modified:");
571 modifitime=k_time_from_rfc(modistring);
573 char* imss=k_hashtable_get(sub, "If-Modified-Since:");
574 time_t imst=k_time_from_rfc(imss);
576 if(modifitime== -1 || imst== -1 || modifitime > imst){
577 if(k_hashtable_is(sub, "Method:", "HEAD")){
580 if(!k_hashtable_is(ent_head, "CUX:", "C")){
581 evv->entity=entity_to_octets(ent_head, evv->entity);
587 statustext="Not Modified";
591 drop_entity_headers(ent_head);
594 fill_headers(ent_head, status, statustext, 0,
595 modistring? -1: modifitime,
596 datalength, 0, 0, nocache);
598 char* pub =k_hashtable_get(sub, "URI:");
600 if(L) ni_event_show(evv, "respond_ok");
601 post_to_driver(pub, evv);
604 void respond_nf(k_hashtable* sub, ni_event* evv)
606 fill_headers(evv->ent_head, "404", "File Not Found", 0, -1, 0, 0, 0, 1);
607 char* pub =k_hashtable_get(sub, "URI:");
608 post_to_driver(pub, evv);
611 void post_to_driver(char* pub, ni_event* evq)
613 char* driver=handled_by(pub);
614 if(0) k_log_out("Passing %s on to %s", pub, driver);
615 if(0) ni_event_show(evq, "Post to Driver:");
616 k_event_post(driver, evq);
619 void* entity_to_octets(k_hashtable* ent_head, void* entity)
621 if(!entity) return 0;
622 size_t size=k_hashtable_get_int(ent_head, "Content-Length:");
623 return k_memdup(entity, size);
626 /* -}{---- ------------------------------------------------------------------ */
628 EXPORT char* ni_hostname()
630 return hostname? hostname: "not set";
633 EXPORT void ni_hostname_set(char* name)
636 hostname=k_strdup(name);
639 /* -}{---- ------------------------------------------------------------------ */
641 static ni_driver* opdriver;
642 static ni_driver* moddriver;
644 char* handled_by(char* pub)
646 if(moddriver->handles_resource(pub)) return moddriver->name;
650 void call_sync_resource(ni_resource* res)
652 if(moddriver->handles_resource(res->uri)) moddriver->sync_resource(res);
653 else opdriver->sync_resource(res);
656 ni_driver* ni_driver_new(char* name,
657 ni_handles_resource handles_resource,
658 ni_sync_resource sync_resource)
660 ni_driver* driver=k_malloc(sizeof(ni_driver));
662 driver->handles_resource=handles_resource;
663 driver->sync_resource =sync_resource;
667 EXPORT void ni_register_driver(char* name,
668 ni_handles_resource handles_resource,
669 ni_sync_resource sync_resource)
671 ni_driver* d=ni_driver_new(name, handles_resource, sync_resource);
672 if(!strcmp(name, "op")) opdriver=d;
676 /* -}{---- ------------------------------------------------------------------ */
678 EXPORT ni_resource* ni_resource_new(char* uri,
679 k_hashtable* ent_head,
682 char* urih=k_hashtable_get(ent_head, "URI:");
685 if(uri) k_hashtable_put_dup(ent_head, "URI:", uri);
687 ni_resource* res=k_malloc(sizeof(ni_resource));
688 res->uri =(uri? k_strdup(uri): 0);
689 res->ent_head=ent_head;
694 EXPORT ni_resource* ni_resource_dup(ni_resource* res)
696 ni_resource* rep=k_malloc(sizeof(ni_resource));
697 rep->uri =k_strdup( res->uri);
698 rep->ent_head=k_hashtable_dup(res->ent_head);
699 rep->entity = res->entity;
703 EXPORT void ni_resource_delete(ni_resource* res)
706 if(res->entity && res->ent_head){
707 int constant=k_hashtable_is(res->ent_head, "CUX:", "C");
708 if(!constant) k_free(res->entity);
710 k_hashtable_delete(res->ent_head);
715 static char* excto[]={ "Permit:", "Sub-To:", "Pub-To:", 0 };
716 static char* perto[]={ "Permit:", 0 };
717 static char* subto[]={ "Sub-To:", 0 };
718 static char* pubto[]={ "Pub-To:", 0 };
720 EXPORT void ni_resource_show(ni_resource* res, char* text)
723 k_log_out("\n---%s--------\n------------\n\n----------",
730 l+=k_hashtable_snprintf_x(res->ent_head, b+l, s-l, excto);
731 l+=k_hashtable_snprintf_i(res->ent_head, b+l, s-l, perto);
732 l+=k_hashtable_snprintf_i(res->ent_head, b+l, s-l, subto);
733 l+=k_hashtable_snprintf_i(res->ent_head, b+l, s-l, pubto);
734 k_log_out("\n---%s----%s--\n%s----------\n%p\n----------",
735 text, res->uri, tmpbuf, res->entity);
739 /* -}{---- ------------------------------------------------------------------ */
741 EXPORT ni_resource* ni_resource_get(char* uri)
743 return k_hashtable_get(resources, uri);
746 /* -}{---- ------------------------------------------------------------------ */
748 EXPORT ni_event* ni_res_to_evt(ni_resource* res)
750 ni_event* evp=k_malloc(sizeof(ni_event));
751 evp->uri =k_strdup( res->uri);
752 evp->evt_head=k_hashtable_new("vHeaders/ni_res_to_evt", 1);
753 evp->ent_head=k_hashtable_dup(res->ent_head);
754 evp->entity = res->entity;
758 /* -}{---- ------------------------------------------------------------------ */
760 EXPORT ni_event* ni_event_new(char* uri,
761 k_hashtable* evt_head,
762 k_hashtable* ent_head,
765 char* urih=k_hashtable_get(ent_head, "URI:");
768 if(uri) k_hashtable_put_dup(ent_head, "URI:", uri);
770 ni_event* evt=k_malloc(sizeof(ni_event));
771 evt->uri =(uri? k_strdup(uri): 0);
772 evt->evt_head=evt_head;
773 evt->ent_head=ent_head;
778 EXPORT ni_event* ni_event_dup(ni_event* evt)
780 ni_event* evp=k_malloc(sizeof(ni_event));
781 evp->uri =k_strdup( evt->uri);
782 evp->evt_head=k_hashtable_dup(evt->evt_head);
783 evp->ent_head=k_hashtable_dup(evt->ent_head);
784 evp->entity = evt->entity;
788 EXPORT void ni_event_delete(ni_event* evt)
791 if(evt->entity && evt->ent_head){
792 int constant=k_hashtable_is(evt->ent_head, "CUX:", "C");
793 if(!constant) k_free(evt->entity);
795 k_hashtable_delete(evt->evt_head);
796 k_hashtable_delete(evt->ent_head);
801 EXPORT void ni_event_show(ni_event* evt, char* text)
804 k_log_out("\n---%s--------\n------------\n\n----------",
810 int n=k_hashtable_snprintf(evt->evt_head, buf, siz)+1;
811 ; k_hashtable_snprintf(evt->ent_head, buf+n, siz-n);
812 k_log_out("\n---%s----%s--\n"
816 text, evt->uri, buf, buf+n, evt->entity);
820 /* -}{----------------------------------------------------------------------- */