2 /* -}{----------------------------------------------------------------------- */
7 #include <notification.h>
9 /* -}{---- ------------------------------------------------------------------ */
11 EXPORT void n_register_driver(char* name,
12 n_handles_object handles_object,
13 n_view_event view_event,
14 n_cast_event cast_event,
15 n_sync_object sync_object )
19 EXPORT n_object* n_object_new(char* s)
24 EXPORT void n_commit(n_object* o)
28 EXPORT n_object* n_view(n_object* o, char* uid)
33 EXPORT char* n_to_string(n_object* o)
38 EXPORT char* n_uid(n_object* o)
43 EXPORT int n_uid_is(n_object* o, char* uid)
48 EXPORT char* n_header(n_object* o, char* name)
53 EXPORT k_hashtable* n_headers(n_object* o)
58 EXPORT k_hashtable* n_content(n_object* o)
63 EXPORT void n_dispatch(n_event* event)
65 /* one callback per view or cast */
66 /* must delete the event */
69 /* -}{---- ------------------------------------------------------------------ */
71 #define TMPBUFSIZE 4096
72 static char tmpbuf[TMPBUFSIZE];
73 static char* hostname;
74 static k_hashtable* resources;
76 /* -}{---- ------------------------------------------------------------------ */
78 typedef struct ni_driver{
80 ni_handles_resource handles_resource;
81 ni_sync_resource sync_resource;
84 /* -}{---- From headers.c --------------------------------------------------- */
86 extern void init_headers(void);
87 extern void drop_entity_headers(k_hashtable* ent_head);
88 extern void fill_headers(k_hashtable* ent_head,
98 /* -}{---- ------------------------------------------------------------------ */
100 static void incoming_request(ni_event* evq);
101 static ni_resource* ensure_res(char* pub);
102 static void ensure_sub_entry(k_hashtable* ent_head, k_hashtable* sub);
103 static void ensure_pub_entry(k_hashtable* ent_head, k_hashtable* sub);
104 static k_hashtable* get_this(k_hashtable*, char*, k_hashtable*);
105 static k_hashtable* get_using(k_hashtable* curr, char* tag, char* val);
106 static void post_to_driver(char* pub, ni_event* evq);
107 static void incoming_resource(ni_event* evt);
108 static void test_pub_tos(ni_resource* res, ni_event* evt, int entityok);
109 static int satisfiable(k_hashtable*, ni_resource*, ni_event*, int);
110 static void update_pubcache(int, k_hashtable**, k_hashtable*, k_hashtable*);
111 static int sub_less(k_hashtable* sub1, k_hashtable* sub2);
112 static void fix_via_subs(k_hashtable* evteh, k_hashtable* reseh);
113 static int sub_ok(k_hashtable* sub);
114 static int range_ok(char* range, char* conrange);
115 static void merge_non_entity_headers(k_hashtable* reseh, k_hashtable* evteh);
116 static void merge_entity_range(ni_resource* res, ni_event* evt);
117 static void respond( k_hashtable* sub, ni_resource* res, ni_event* evt);
118 static void respond_ok(k_hashtable* sub, ni_event* evv);
119 static void respond_nf(k_hashtable* sub, ni_event* evv);
120 static void* entity_to_octets(k_hashtable* ent_head, void* entity);
121 static char* handled_by(char* pub);
122 static void call_sync_resource(ni_resource* res);
123 static ni_driver* ni_driver_new(char* name,
124 ni_handles_resource handles_resource,
125 ni_sync_resource sync_resource);
127 /* -}{---- ------------------------------------------------------------------ */
129 EXPORT int on_module_loaded(void)
131 resources=k_hashtable_new("Resources", 0);
135 k_log_out("ON initialised");
139 EXPORT void on_module_tick(void)
143 EXPORT int on_module_event(void* data)
147 if(!k_hashtable_get(evt->ent_head, "Status:")){
149 incoming_request(evt);
152 incoming_resource(evt);
157 /* -}{---- ------------------------------------------------------------------ */
159 void incoming_request(ni_event* evq)
162 if(L) ni_event_show(evq, "ON got request event");
164 k_hashtable* sub=evq->ent_head;
165 char* uri =k_hashtable_get(sub, "URI:");
166 char* pub =k_hashtable_get(sub, "Sub-To:"); if(!pub) return;
167 int styor=k_hashtable_isi(sub, "Sub-Type:", "Original");
168 char* via =k_hashtable_get(sub, "Via:");
169 char* from =k_hashtable_get(sub, "From:");
170 if(L) k_log_out("------------------ %s", pub);
172 int nocache=k_hashtable_isi(sub, "Cache-Control:", "no-cache");
174 k_hashtable_remove( sub, "Cache-Control:");
175 k_hashtable_set( sub, "If-Modified-Since:", "0");
179 ni_resource* ses=k_hashtable_get(resources, uri);
180 if(ses) ensure_sub_entry(ses->ent_head, sub);
181 if(ses) if(L) ni_resource_show(ses, "Subscribing Resource:");
183 post_to_driver(pub, evq);
188 ni_resource* res=ensure_res(pub);
189 if(L) ni_resource_show(res, "Publishing Resource:");
191 k_hashtable* pubcache=0;
192 int sat=satisfiable(sub, res, 0, 0);
193 update_pubcache(sat, &pubcache, res->ent_head, sub);
195 if(L) k_log_out("Memory cache hit for %s", pub);
196 respond(k_hashtable_dup(sub), res, 0);
197 ni_event_delete(evq);
200 ensure_pub_entry(res->ent_head, sub);
201 if(L) ni_resource_show(res, "Pending Resource:");
203 evq->ent_head=pubcache;
204 post_to_driver(pub, evq);
205 k_hashtable_delete(sub);
208 if(L) k_log_out("In-progress Pub-Cache sufficient");
209 ni_event_delete(evq);
214 ni_resource* ensure_res(char* pub)
216 ni_resource* res=k_hashtable_get(resources, pub);
218 res=ni_resource_new(pub, k_hashtable_new("resHeaders", 1), 0);
219 k_hashtable_set(resources, pub, res);
224 void ensure_sub_entry(k_hashtable* ent_head, k_hashtable* sub)
227 k_hashtable* sup=get_this(ent_head, tag, sub);
229 k_hashtable* sup=k_hashtable_dup(sub);
230 char* uri=k_hashtable_extract(sup, "Sub-To:");
231 k_hashtable_put( sup, "URI:", uri);
232 k_hashtable_remove( sup, "Sub-Type:");
233 k_hashtable_sub(ent_head, tag, sup);
236 k_hashtable_remove(sup, "Range:");
237 k_hashtable_remove(sup, "Content-Range:");
238 k_hashtable_remove(sup, "Status:");
239 k_hashtable_remove(sup, "Status-Cache:");
240 char* mth=k_strdup(k_hashtable_get(sub, "Method:"));
241 char* via=k_strdup(k_hashtable_get(sub, "Via:"));
242 char* ims=k_strdup(k_hashtable_get(sub, "If-Modified-Since:"));
243 char* rng=k_strdup(k_hashtable_get(sub, "Range:"));
244 if(mth) k_hashtable_put(sup, "Method:", mth);
245 if(via) k_hashtable_put(sup, "Via:", via);
246 if(ims) k_hashtable_put(sup, "If-Modified-Since:", ims);
247 if(rng) k_hashtable_put(sup, "Range:", rng);
251 void ensure_pub_entry(k_hashtable* ent_head, k_hashtable* sub)
254 k_hashtable* sup=get_this(ent_head, tag, sub);
256 k_hashtable* sup=k_hashtable_dup(sub);
257 k_hashtable_remove(sup, "Sub-To:");
258 k_hashtable_remove(sup, "Sub-Type:");
259 k_hashtable_sub(ent_head, tag, sup);
262 k_hashtable_remove(sup, "Method:");
263 k_hashtable_remove(sup, "If-Modified-Since:");
264 k_hashtable_remove(sup, "Cache-Control:");
265 k_hashtable_remove(sup, "Update:");
266 char* mth=k_strdup(k_hashtable_get(sub, "Method:"));
267 char* ims=k_strdup(k_hashtable_get(sub, "If-Modified-Since:"));
268 char* ccn=k_strdup(k_hashtable_get(sub, "Cache-Control:"));
269 char* upd=k_strdup(k_hashtable_get(sub, "Update:"));
270 if(mth) k_hashtable_put(sup, "Method:", mth);
271 if(ims) k_hashtable_put(sup, "If-Modified-Since:", ims);
272 if(ccn) k_hashtable_put(sup, "Cache-Control:", ccn);
273 if(upd) k_hashtable_put(sup, "Update:", upd);
277 k_hashtable* get_this(k_hashtable* ent_head, char* pubsub, k_hashtable* try)
279 k_hashtable* curr=k_hashtable_get(ent_head, pubsub);
286 val=k_hashtable_get(try, tag);
287 if(val) return get_using(curr, tag, val);
290 val=k_hashtable_get(try, tag);
291 if(val) return get_using(curr, tag, val);
296 k_hashtable* get_using(k_hashtable* curr, char* tag, char* val)
299 for(c=curr; c; c=c->next) if(k_hashtable_is(c, tag, val)) return c;
303 /* -}{---- ------------------------------------------------------------------ */
305 void incoming_resource(ni_event* evt)
308 if(L) ni_event_show(evt, "ON got resource incoming event");
310 ni_resource* res=k_hashtable_get(resources, evt->uri);
311 int fullconst=res && k_hashtable_is(res->ent_head, "Status:", "200") &&
312 k_hashtable_is(res->ent_head, "CUX:", "C");
315 k_log_err("Resource is complete and Constant");
316 ni_event_delete(evt);
319 if(!res) res=ensure_res(evt->uri);
321 k_hashtable* reseh=res->ent_head;
322 k_hashtable* evteh=evt->ent_head;
323 int okfull =k_hashtable_is(evteh, "Status:", "200");
324 int partial =k_hashtable_is(evteh, "Status:", "206");
325 int headonly=k_hashtable_is(evteh, "Status:", "260");/*
326 int updated =k_hashtable_is(evteh, "Status:", "266");*/
327 int notmod =k_hashtable_is(evteh, "Status:", "304");
328 int notfound=k_hashtable_is(evteh, "Status:", "404");
330 int entityok= (okfull || partial || notmod);
331 int entityev=!(headonly || notmod || notfound);
332 int entityin=!!evt->entity;
333 int entityon=!!res->entity;
337 if(okfull || !entityon){
338 k_hashtable_merge(reseh, evteh);
339 if(okfull) k_hashtable_remove(reseh, "Content-Range:");
342 merge_non_entity_headers(reseh, evteh);
345 fix_via_subs(evteh, reseh);
348 if(okfull || (partial && !entityon)){
349 if(res->entity!=evt->entity){
350 if(!k_hashtable_is(reseh, "CUX:", "C")){
353 res->entity=evt->entity;
357 if(partial && entityon){
358 merge_entity_range(res, evt);
362 if(L) ni_resource_show(res, "updated resource - sync and try pubs:");
364 call_sync_resource(res);
366 test_pub_tos(res, evt, entityok);
369 ni_event_delete(evt);
371 if(L) ni_resource_show(res, "resource after ON:");
374 void fix_via_subs(k_hashtable* evteh, k_hashtable* reseh)
376 char* from=k_hashtable_get(evteh, "From:");
378 k_hashtable* subs=k_hashtable_get(reseh, "Sub-To:");
380 for(sub=subs; sub; sub=sub->next){
381 if(!k_hashtable_is(sub, "Via:", from)) continue;
382 int st=k_hashtable_get_int(evteh, "Status:");
383 char* cr=k_hashtable_get_dup(evteh, "Content-Range:");
384 if(st!=304) k_hashtable_put_int(sub, "Status:", st);
385 if(st==200) k_hashtable_remove( sub, "Content-Range:");
387 if(cr) k_hashtable_put(sub, "Content-Range:", cr);
388 if(sub_ok(sub)) k_hashtable_set(sub, "Status-Cache:", "OK");
392 void test_pub_tos(ni_resource* res, ni_event* evt, int entityok)
394 k_hashtable* keeps=0;
395 k_hashtable* sub=k_hashtable_extract(res->ent_head, "Pub-To:");
397 k_hashtable* subnext=sub->next;
400 int sat=satisfiable(sub, res, evt, entityok);
401 update_pubcache(sat, 0, res->ent_head, sub);
403 respond(k_hashtable_dup(sub), res, evt);
404 if(!k_hashtable_get(sub, "Update:")) keep=0;
411 k_hashtable_delete(sub);
417 k_hashtable* subnext=sub->next;
418 k_hashtable_sub(res->ent_head, "Pub-To:", sub);
423 int satisfiable(k_hashtable* sub,
429 int get =k_hashtable_is( sub, "Method:", "GET");
430 int head =k_hashtable_is( sub, "Method:", "HEAD");
431 int dosub=k_hashtable_is( sub, "Method:", "SUB");
432 int unsub=k_hashtable_is( sub, "Method:", "UNSUB");
433 int full=!k_hashtable_isi(sub, "Cache-Control:", "no-full");
434 int updt =k_hashtable_isi(sub, "Update:", "changes");
435 char* ims =k_hashtable_get(sub, "If-Modified-Since:");
436 char* range=k_hashtable_get(sub, "Range:");
438 int getsub =get || dosub;
439 int getrange=getsub && range;
441 k_hashtable* reseh=res->ent_head;
442 int gotall= k_hashtable_is( reseh, "Status:", "200");
443 int gotrange= k_hashtable_is( reseh, "Status:", "206");
444 int gothead= k_hashtable_is( reseh, "Status:", "260");
445 int gotupdated=evt &&
446 k_hashtable_is(evt->ent_head, "Status:", "266");
447 int notfound= k_hashtable_is( reseh, "Status:", "404");
448 int constant= k_hashtable_is( reseh, "CUX:", "C" );
449 char* conrange= k_hashtable_get(reseh, "Content-Range:");
452 if(notfound) return 1;
454 int gotany=(gothead || gotrange || gotall);
455 int snapok=(constant || !ims || entityok);
459 ((getsub && gotall && snapok) ||
460 (getrange && gotrange && range_ok(range, conrange) && snapok) ||
464 ((dosub && gotupdated)));
466 if(L) k_log_out("satisfiable %d", sat);
470 void update_pubcache(int sat,
471 k_hashtable** pubcachep,
475 if(!sat){ if(pubcachep){
476 k_hashtable* pubcache;
477 pubcache=k_hashtable_get(reseh, "Pub-Cache:");
478 if(!pubcache || sub_less(pubcache, sub)){
480 pubcache=k_hashtable_dup(sub);
481 k_hashtable_sub(reseh, "Pub-Cache:", pubcache);
484 k_hashtable_merge(pubcache, sub);
486 k_hashtable_remove(pubcache, "URI:");
487 k_hashtable_remove(pubcache, "Sub-Type:");
488 *pubcachep=k_hashtable_dup(pubcache);
489 k_hashtable_set(*pubcachep, "Sub-Type:", "Cache");
492 else{ if(!pubcachep){
493 k_hashtable* pubcache;
494 pubcache=k_hashtable_get(reseh, "Pub-Cache:");
495 if(!sub_less(sub, pubcache)){
496 k_hashtable_remove(pubcache, "Method:");
497 k_hashtable_remove(pubcache, "If-Modified-Since:");
502 int sub_ok(k_hashtable* sub)
504 char* gotresp =k_hashtable_get(sub, "Status:");
505 if(!gotresp) return 0;
506 int notfound=k_hashtable_is( sub, "Status:", "404");
507 if(notfound) return 0;
508 int gotall =k_hashtable_is( sub, "Status:", "200");
509 int gotrange=k_hashtable_is( sub, "Status:", "206");
510 int gothead= k_hashtable_is( sub, "Status:", "260");
511 int doget =k_hashtable_is( sub, "Method:", "GET");
512 int dohead =k_hashtable_is( sub, "Method:", "HEAD");
513 int dosub =k_hashtable_is( sub, "Method:", "SUB");
514 char* range =k_hashtable_get(sub, "Range:");
515 char* conrange=k_hashtable_get(sub, "Content-Range:");
517 int dogetsub=doget || dosub;
518 int dogetrange=dogetsub && range;
519 int gotany =(gothead || gotrange || gotall);
521 return (dogetsub && gotall ) ||
522 (dogetrange && gotrange && range_ok(range, conrange)) ||
526 int sub_less(k_hashtable* sub1, k_hashtable* sub2)
529 if(L) k_log_out("sub_less sub1:");
530 if(L) k_hashtable_show_chars(sub1);
531 if(L) k_log_out("sub_less sub2:");
532 if(L) k_hashtable_show_chars(sub2);
533 char* mth1 =k_hashtable_get(sub1, "Method:");
534 int head1=k_hashtable_is( sub1, "Method:", "HEAD");
535 int get2 =k_hashtable_is( sub2, "Method:", "GET");
536 char* ims1 =k_hashtable_get(sub1, "If-Modified-Since:");
537 char* ims2 =k_hashtable_get(sub2, "If-Modified-Since:");
538 int full=!k_hashtable_isi(sub2, "Cache-Control:", "no-full");
539 return full && ((!mth1) || (head1 && get2) || (!ims1 && ims2));
542 int range_ok(char* range, char* conrange)
544 k_log_out("range_ok not implemented: %s vs %s", range, conrange);
548 void merge_non_entity_headers(k_hashtable* reseh, k_hashtable* evteh)
552 void merge_entity_range(ni_resource* res, ni_event* evt)
554 k_log_out("merge_entity_range not implemented yet");
557 /* -}{---- ------------------------------------------------------------------ */
559 void respond(k_hashtable* sub, ni_resource* res, ni_event* evt)
561 int updated=evt && k_hashtable_is(evt->ent_head, "Status:", "266");
562 ni_event* evv=updated? ni_event_dup(evt):
565 if(L) ni_event_show(evv, "respond");
567 k_hashtable_remove(evv->ent_head, "Permit:");
568 k_hashtable_remove(evv->ent_head, "Sub-To:");
569 k_hashtable_remove(evv->ent_head, "Pub-To:");
570 k_hashtable_remove(evv->ent_head, "Pub-Cache:");
571 k_hashtable_sub( evv->ent_head, "Pub-To:", sub);
574 nf=k_hashtable_is( evv->ent_head, "Status:", "404");
575 if(!nf) respond_ok(sub, evv);
576 else respond_nf(sub, evv);
579 void respond_ok(k_hashtable* sub, ni_event* evv)
585 k_hashtable* ent_head=evv->ent_head;
587 time_t modifitime=k_hashtable_get_int(ent_head, "Last-Modified-Epoch:");
588 char* modistring=k_hashtable_get( ent_head, "Last-Modified:");
590 modifitime=k_time_from_rfc(modistring);
592 char* imss=k_hashtable_get(sub, "If-Modified-Since:");
593 time_t imst=k_time_from_rfc(imss);
595 if(modifitime== -1 || imst== -1 || modifitime > imst){
596 if(k_hashtable_is(sub, "Method:", "HEAD")){
599 if(!k_hashtable_is(ent_head, "CUX:", "C")){
600 evv->entity=entity_to_octets(ent_head, evv->entity);
606 statustext="Not Modified";
610 drop_entity_headers(ent_head);
613 fill_headers(ent_head, status, statustext, 0,
614 modistring? -1: modifitime,
615 datalength, 0, 0, nocache);
617 char* pub =k_hashtable_get(sub, "URI:");
619 if(L) ni_event_show(evv, "respond_ok");
620 post_to_driver(pub, evv);
623 void respond_nf(k_hashtable* sub, ni_event* evv)
625 fill_headers(evv->ent_head, "404", "File Not Found", 0, -1, 0, 0, 0, 1);
626 char* pub =k_hashtable_get(sub, "URI:");
627 post_to_driver(pub, evv);
630 void post_to_driver(char* pub, ni_event* evq)
632 char* driver=handled_by(pub);
633 if(0) k_log_out("Passing %s on to %s", pub, driver);
634 if(0) ni_event_show(evq, "Post to Driver:");
635 k_event_post(driver, evq);
638 void* entity_to_octets(k_hashtable* ent_head, void* entity)
640 if(!entity) return 0;
641 size_t size=k_hashtable_get_int(ent_head, "Content-Length:");
642 return k_memdup(entity, size);
645 /* -}{---- ------------------------------------------------------------------ */
647 EXPORT char* ni_hostname()
649 return hostname? hostname: "not set";
652 EXPORT void ni_hostname_set(char* name)
655 hostname=k_strdup(name);
658 /* -}{---- ------------------------------------------------------------------ */
660 static ni_driver* opdriver;
661 static ni_driver* moddriver;
663 char* handled_by(char* pub)
665 if(moddriver->handles_resource(pub)) return moddriver->name;
669 void call_sync_resource(ni_resource* res)
671 if(moddriver->handles_resource(res->uri)) moddriver->sync_resource(res);
672 else opdriver->sync_resource(res);
675 ni_driver* ni_driver_new(char* name,
676 ni_handles_resource handles_resource,
677 ni_sync_resource sync_resource)
679 ni_driver* driver=k_malloc(sizeof(ni_driver));
681 driver->handles_resource=handles_resource;
682 driver->sync_resource =sync_resource;
686 EXPORT void ni_register_driver(char* name,
687 ni_handles_resource handles_resource,
688 ni_sync_resource sync_resource)
690 ni_driver* d=ni_driver_new(name, handles_resource, sync_resource);
691 if(!strcmp(name, "op")) opdriver=d;
695 /* -}{---- ------------------------------------------------------------------ */
697 EXPORT ni_resource* ni_resource_new(char* uri,
698 k_hashtable* ent_head,
701 char* urih=k_hashtable_get(ent_head, "URI:");
704 if(uri) k_hashtable_put_dup(ent_head, "URI:", uri);
706 ni_resource* res=k_malloc(sizeof(ni_resource));
707 res->uri =(uri? k_strdup(uri): 0);
708 res->ent_head=ent_head;
713 EXPORT ni_resource* ni_resource_dup(ni_resource* res)
715 ni_resource* rep=k_malloc(sizeof(ni_resource));
716 rep->uri =k_strdup( res->uri);
717 rep->ent_head=k_hashtable_dup(res->ent_head);
718 rep->entity = res->entity;
722 EXPORT void ni_resource_delete(ni_resource* res)
725 if(res->entity && res->ent_head){
726 int constant=k_hashtable_is(res->ent_head, "CUX:", "C");
727 if(!constant) k_free(res->entity);
729 k_hashtable_delete(res->ent_head);
734 static char* excto[]={ "Permit:", "Sub-To:", "Pub-To:", 0 };
735 static char* perto[]={ "Permit:", 0 };
736 static char* subto[]={ "Sub-To:", 0 };
737 static char* pubto[]={ "Pub-To:", 0 };
739 EXPORT void ni_resource_show(ni_resource* res, char* text)
742 k_log_out("\n---%s--------\n------------\n\n----------",
749 l+=k_hashtable_snprintf_x(res->ent_head, b+l, s-l, excto);
750 l+=k_hashtable_snprintf_i(res->ent_head, b+l, s-l, perto);
751 l+=k_hashtable_snprintf_i(res->ent_head, b+l, s-l, subto);
752 l+=k_hashtable_snprintf_i(res->ent_head, b+l, s-l, pubto);
753 k_log_out("\n---%s----%s--\n%s----------\n%p\n----------",
754 text, res->uri, tmpbuf, res->entity);
758 /* -}{---- ------------------------------------------------------------------ */
760 EXPORT ni_resource* ni_resource_get(char* uri)
762 return k_hashtable_get(resources, uri);
765 /* -}{---- ------------------------------------------------------------------ */
767 EXPORT ni_event* ni_res_to_evt(ni_resource* res)
769 ni_event* evp=k_malloc(sizeof(ni_event));
770 evp->uri =k_strdup( res->uri);
771 evp->evt_head=k_hashtable_new("vHeaders/ni_res_to_evt", 1);
772 evp->ent_head=k_hashtable_dup(res->ent_head);
773 evp->entity = res->entity;
777 /* -}{---- ------------------------------------------------------------------ */
779 EXPORT ni_event* ni_event_new(char* uri,
780 k_hashtable* evt_head,
781 k_hashtable* ent_head,
784 char* urih=k_hashtable_get(ent_head, "URI:");
787 if(uri) k_hashtable_put_dup(ent_head, "URI:", uri);
789 ni_event* evt=k_malloc(sizeof(ni_event));
790 evt->uri =(uri? k_strdup(uri): 0);
791 evt->evt_head=evt_head;
792 evt->ent_head=ent_head;
797 EXPORT ni_event* ni_event_dup(ni_event* evt)
799 ni_event* evp=k_malloc(sizeof(ni_event));
800 evp->uri =k_strdup( evt->uri);
801 evp->evt_head=k_hashtable_dup(evt->evt_head);
802 evp->ent_head=k_hashtable_dup(evt->ent_head);
803 evp->entity = evt->entity;
807 EXPORT void ni_event_delete(ni_event* evt)
810 if(evt->entity && evt->ent_head){
811 int constant=k_hashtable_is(evt->ent_head, "CUX:", "C");
812 if(!constant) k_free(evt->entity);
814 k_hashtable_delete(evt->evt_head);
815 k_hashtable_delete(evt->ent_head);
820 EXPORT void ni_event_show(ni_event* evt, char* text)
823 k_log_out("\n---%s--------\n------------\n\n----------",
829 int n=k_hashtable_snprintf(evt->evt_head, buf, siz)+1;
830 ; k_hashtable_snprintf(evt->ent_head, buf+n, siz-n);
831 k_log_out("\n---%s----%s--\n"
835 text, evt->uri, buf, buf+n, evt->entity);
839 /* -}{----------------------------------------------------------------------- */