Blob


1 #include "std.h"
2 #include "dat.h"
4 void
5 lbkick(Logbuf *lb)
6 {
7 char *s;
8 int n;
9 Req *r;
11 while(lb->wait && lb->rp != lb->wp){
12 r = lb->wait;
13 lb->wait = r->aux;
14 if(lb->wait == nil)
15 lb->waitlast = &lb->wait;
16 r->aux = nil;
17 if(r->ifcall.count < 5){
18 respond(r, "factotum: read request count too short");
19 continue;
20 }
21 s = lb->msg[lb->rp];
22 lb->msg[lb->rp] = nil;
23 if(++lb->rp == nelem(lb->msg))
24 lb->rp = 0;
25 n = r->ifcall.count;
26 if(n < strlen(s)+1+1){
27 memmove(r->ofcall.data, s, n-5);
28 n -= 5;
29 r->ofcall.data[n] = '\0';
30 /* look for first byte of UTF-8 sequence by skipping continuation bytes */
31 while(n>0 && (r->ofcall.data[--n]&0xC0)==0x80)
32 ;
33 strcpy(r->ofcall.data+n, "...\n");
34 }else{
35 strcpy(r->ofcall.data, s);
36 strcat(r->ofcall.data, "\n");
37 }
38 r->ofcall.count = strlen(r->ofcall.data);
39 free(s);
40 respond(r, nil);
41 }
42 }
44 void
45 lbread(Logbuf *lb, Req *r)
46 {
47 if(lb->waitlast == nil)
48 lb->waitlast = &lb->wait;
49 *(lb->waitlast) = r;
50 lb->waitlast = (Req**)&r->aux;
51 r->aux = nil;
52 lbkick(lb);
53 }
55 void
56 lbflush(Logbuf *lb, Req *r)
57 {
58 Req **l;
60 for(l=&lb->wait; *l; l=(Req**)&(*l)->aux){
61 if(*l == r){
62 *l = r->aux;
63 r->aux = nil;
64 if(*l == nil)
65 lb->waitlast = l;
66 closereq(r);
67 break;
68 }
69 }
70 }
72 void
73 lbappend(Logbuf *lb, char *fmt, ...)
74 {
75 va_list arg;
77 va_start(arg, fmt);
78 lbvappend(lb, fmt, arg);
79 va_end(arg);
80 }
82 void
83 lbvappend(Logbuf *lb, char *fmt, va_list arg)
84 {
85 char *s;
87 s = smprint(fmt, arg);
88 if(s == nil)
89 sysfatal("out of memory");
90 if(lb->msg[lb->wp])
91 free(lb->msg[lb->wp]);
92 lb->msg[lb->wp] = s;
93 if(++lb->wp == nelem(lb->msg))
94 lb->wp = 0;
95 lbkick(lb);
96 }
98 Logbuf logbuf;
100 void
101 logread(Req *r)
103 lbread(&logbuf, r);
106 void
107 logflush(Req *r)
109 lbflush(&logbuf, r);
112 void
113 flog(char *fmt, ...)
115 va_list arg;
117 va_start(arg, fmt);
118 lbvappend(&logbuf, fmt, arg);
119 va_end(arg);