1*8ccd4a63SDavid du Colombier #include <u.h>
2*8ccd4a63SDavid du Colombier #include <libc.h>
3*8ccd4a63SDavid du Colombier #include <auth.h>
4*8ccd4a63SDavid du Colombier
5*8ccd4a63SDavid du Colombier int
_attrfmt(Fmt * fmt)6*8ccd4a63SDavid du Colombier _attrfmt(Fmt *fmt)
7*8ccd4a63SDavid du Colombier {
8*8ccd4a63SDavid du Colombier char *b, buf[1024], *ebuf;
9*8ccd4a63SDavid du Colombier Attr *a;
10*8ccd4a63SDavid du Colombier
11*8ccd4a63SDavid du Colombier ebuf = buf+sizeof buf;
12*8ccd4a63SDavid du Colombier b = buf;
13*8ccd4a63SDavid du Colombier strcpy(buf, " ");
14*8ccd4a63SDavid du Colombier for(a=va_arg(fmt->args, Attr*); a; a=a->next){
15*8ccd4a63SDavid du Colombier if(a->name == nil)
16*8ccd4a63SDavid du Colombier continue;
17*8ccd4a63SDavid du Colombier switch(a->type){
18*8ccd4a63SDavid du Colombier case AttrQuery:
19*8ccd4a63SDavid du Colombier b = seprint(b, ebuf, " %q?", a->name);
20*8ccd4a63SDavid du Colombier break;
21*8ccd4a63SDavid du Colombier case AttrNameval:
22*8ccd4a63SDavid du Colombier b = seprint(b, ebuf, " %q=%q", a->name, a->val);
23*8ccd4a63SDavid du Colombier break;
24*8ccd4a63SDavid du Colombier case AttrDefault:
25*8ccd4a63SDavid du Colombier b = seprint(b, ebuf, " %q:=%q", a->name, a->val);
26*8ccd4a63SDavid du Colombier break;
27*8ccd4a63SDavid du Colombier }
28*8ccd4a63SDavid du Colombier }
29*8ccd4a63SDavid du Colombier return fmtstrcpy(fmt, buf+1);
30*8ccd4a63SDavid du Colombier }
31*8ccd4a63SDavid du Colombier
32*8ccd4a63SDavid du Colombier Attr*
_copyattr(Attr * a)33*8ccd4a63SDavid du Colombier _copyattr(Attr *a)
34*8ccd4a63SDavid du Colombier {
35*8ccd4a63SDavid du Colombier Attr **la, *na;
36*8ccd4a63SDavid du Colombier
37*8ccd4a63SDavid du Colombier na = nil;
38*8ccd4a63SDavid du Colombier la = &na;
39*8ccd4a63SDavid du Colombier for(; a; a=a->next){
40*8ccd4a63SDavid du Colombier *la = _mkattr(a->type, a->name, a->val, nil);
41*8ccd4a63SDavid du Colombier setmalloctag(*la, getcallerpc(&a));
42*8ccd4a63SDavid du Colombier la = &(*la)->next;
43*8ccd4a63SDavid du Colombier }
44*8ccd4a63SDavid du Colombier *la = nil;
45*8ccd4a63SDavid du Colombier return na;
46*8ccd4a63SDavid du Colombier }
47*8ccd4a63SDavid du Colombier
48*8ccd4a63SDavid du Colombier Attr*
_delattr(Attr * a,char * name)49*8ccd4a63SDavid du Colombier _delattr(Attr *a, char *name)
50*8ccd4a63SDavid du Colombier {
51*8ccd4a63SDavid du Colombier Attr *fa;
52*8ccd4a63SDavid du Colombier Attr **la;
53*8ccd4a63SDavid du Colombier
54*8ccd4a63SDavid du Colombier for(la=&a; *la; ){
55*8ccd4a63SDavid du Colombier if(strcmp((*la)->name, name) == 0){
56*8ccd4a63SDavid du Colombier fa = *la;
57*8ccd4a63SDavid du Colombier *la = (*la)->next;
58*8ccd4a63SDavid du Colombier fa->next = nil;
59*8ccd4a63SDavid du Colombier _freeattr(fa);
60*8ccd4a63SDavid du Colombier }else
61*8ccd4a63SDavid du Colombier la=&(*la)->next;
62*8ccd4a63SDavid du Colombier }
63*8ccd4a63SDavid du Colombier return a;
64*8ccd4a63SDavid du Colombier }
65*8ccd4a63SDavid du Colombier
66*8ccd4a63SDavid du Colombier Attr*
_findattr(Attr * a,char * n)67*8ccd4a63SDavid du Colombier _findattr(Attr *a, char *n)
68*8ccd4a63SDavid du Colombier {
69*8ccd4a63SDavid du Colombier for(; a; a=a->next)
70*8ccd4a63SDavid du Colombier if(strcmp(a->name, n) == 0 && a->type != AttrQuery)
71*8ccd4a63SDavid du Colombier return a;
72*8ccd4a63SDavid du Colombier return nil;
73*8ccd4a63SDavid du Colombier }
74*8ccd4a63SDavid du Colombier
75*8ccd4a63SDavid du Colombier void
_freeattr(Attr * a)76*8ccd4a63SDavid du Colombier _freeattr(Attr *a)
77*8ccd4a63SDavid du Colombier {
78*8ccd4a63SDavid du Colombier Attr *anext;
79*8ccd4a63SDavid du Colombier
80*8ccd4a63SDavid du Colombier for(; a; a=anext){
81*8ccd4a63SDavid du Colombier anext = a->next;
82*8ccd4a63SDavid du Colombier free(a->name);
83*8ccd4a63SDavid du Colombier free(a->val);
84*8ccd4a63SDavid du Colombier a->name = (void*)~0;
85*8ccd4a63SDavid du Colombier a->val = (void*)~0;
86*8ccd4a63SDavid du Colombier a->next = (void*)~0;
87*8ccd4a63SDavid du Colombier free(a);
88*8ccd4a63SDavid du Colombier }
89*8ccd4a63SDavid du Colombier }
90*8ccd4a63SDavid du Colombier
91*8ccd4a63SDavid du Colombier Attr*
_mkattr(int type,char * name,char * val,Attr * next)92*8ccd4a63SDavid du Colombier _mkattr(int type, char *name, char *val, Attr *next)
93*8ccd4a63SDavid du Colombier {
94*8ccd4a63SDavid du Colombier Attr *a;
95*8ccd4a63SDavid du Colombier
96*8ccd4a63SDavid du Colombier a = malloc(sizeof(*a));
97*8ccd4a63SDavid du Colombier if(a==nil)
98*8ccd4a63SDavid du Colombier sysfatal("_mkattr malloc: %r");
99*8ccd4a63SDavid du Colombier a->type = type;
100*8ccd4a63SDavid du Colombier a->name = strdup(name);
101*8ccd4a63SDavid du Colombier a->val = strdup(val);
102*8ccd4a63SDavid du Colombier if(a->name==nil || a->val==nil)
103*8ccd4a63SDavid du Colombier sysfatal("_mkattr malloc: %r");
104*8ccd4a63SDavid du Colombier a->next = next;
105*8ccd4a63SDavid du Colombier setmalloctag(a, getcallerpc(&type));
106*8ccd4a63SDavid du Colombier return a;
107*8ccd4a63SDavid du Colombier }
108*8ccd4a63SDavid du Colombier
109*8ccd4a63SDavid du Colombier static Attr*
cleanattr(Attr * a)110*8ccd4a63SDavid du Colombier cleanattr(Attr *a)
111*8ccd4a63SDavid du Colombier {
112*8ccd4a63SDavid du Colombier Attr *fa;
113*8ccd4a63SDavid du Colombier Attr **la;
114*8ccd4a63SDavid du Colombier
115*8ccd4a63SDavid du Colombier for(la=&a; *la; ){
116*8ccd4a63SDavid du Colombier if((*la)->type==AttrQuery && _findattr(a, (*la)->name)){
117*8ccd4a63SDavid du Colombier fa = *la;
118*8ccd4a63SDavid du Colombier *la = (*la)->next;
119*8ccd4a63SDavid du Colombier fa->next = nil;
120*8ccd4a63SDavid du Colombier _freeattr(fa);
121*8ccd4a63SDavid du Colombier }else
122*8ccd4a63SDavid du Colombier la=&(*la)->next;
123*8ccd4a63SDavid du Colombier }
124*8ccd4a63SDavid du Colombier return a;
125*8ccd4a63SDavid du Colombier }
126*8ccd4a63SDavid du Colombier
127*8ccd4a63SDavid du Colombier Attr*
_parseattr(char * s)128*8ccd4a63SDavid du Colombier _parseattr(char *s)
129*8ccd4a63SDavid du Colombier {
130*8ccd4a63SDavid du Colombier char *p, *t, *tok[256];
131*8ccd4a63SDavid du Colombier int i, ntok, type;
132*8ccd4a63SDavid du Colombier Attr *a;
133*8ccd4a63SDavid du Colombier
134*8ccd4a63SDavid du Colombier s = strdup(s);
135*8ccd4a63SDavid du Colombier if(s == nil)
136*8ccd4a63SDavid du Colombier sysfatal("_parseattr strdup: %r");
137*8ccd4a63SDavid du Colombier
138*8ccd4a63SDavid du Colombier ntok = tokenize(s, tok, nelem(tok));
139*8ccd4a63SDavid du Colombier a = nil;
140*8ccd4a63SDavid du Colombier for(i=ntok-1; i>=0; i--){
141*8ccd4a63SDavid du Colombier t = tok[i];
142*8ccd4a63SDavid du Colombier if((p = strchr(t, '='))){
143*8ccd4a63SDavid du Colombier *p++ = '\0';
144*8ccd4a63SDavid du Colombier // if(p-2 >= t && p[-2] == ':'){
145*8ccd4a63SDavid du Colombier // p[-2] = '\0';
146*8ccd4a63SDavid du Colombier // type = AttrDefault;
147*8ccd4a63SDavid du Colombier // }else
148*8ccd4a63SDavid du Colombier type = AttrNameval;
149*8ccd4a63SDavid du Colombier a = _mkattr(type, t, p, a);
150*8ccd4a63SDavid du Colombier setmalloctag(a, getcallerpc(&s));
151*8ccd4a63SDavid du Colombier }
152*8ccd4a63SDavid du Colombier else if(t[strlen(t)-1] == '?'){
153*8ccd4a63SDavid du Colombier t[strlen(t)-1] = '\0';
154*8ccd4a63SDavid du Colombier a = _mkattr(AttrQuery, t, "", a);
155*8ccd4a63SDavid du Colombier setmalloctag(a, getcallerpc(&s));
156*8ccd4a63SDavid du Colombier }else{
157*8ccd4a63SDavid du Colombier /* really a syntax error, but better to provide some indication */
158*8ccd4a63SDavid du Colombier a = _mkattr(AttrNameval, t, "", a);
159*8ccd4a63SDavid du Colombier setmalloctag(a, getcallerpc(&s));
160*8ccd4a63SDavid du Colombier }
161*8ccd4a63SDavid du Colombier }
162*8ccd4a63SDavid du Colombier free(s);
163*8ccd4a63SDavid du Colombier return cleanattr(a);
164*8ccd4a63SDavid du Colombier }
165*8ccd4a63SDavid du Colombier
166*8ccd4a63SDavid du Colombier char*
_strfindattr(Attr * a,char * n)167*8ccd4a63SDavid du Colombier _strfindattr(Attr *a, char *n)
168*8ccd4a63SDavid du Colombier {
169*8ccd4a63SDavid du Colombier a = _findattr(a, n);
170*8ccd4a63SDavid du Colombier if(a == nil)
171*8ccd4a63SDavid du Colombier return nil;
172*8ccd4a63SDavid du Colombier return a->val;
173*8ccd4a63SDavid du Colombier }
174*8ccd4a63SDavid du Colombier
175