19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <auth.h>
49a747e4fSDavid du Colombier
59a747e4fSDavid du Colombier int
_attrfmt(Fmt * fmt)69a747e4fSDavid du Colombier _attrfmt(Fmt *fmt)
79a747e4fSDavid du Colombier {
89a747e4fSDavid du Colombier char *b, buf[1024], *ebuf;
99a747e4fSDavid du Colombier Attr *a;
109a747e4fSDavid du Colombier
119a747e4fSDavid du Colombier ebuf = buf+sizeof buf;
129a747e4fSDavid du Colombier b = buf;
139a747e4fSDavid du Colombier strcpy(buf, " ");
149a747e4fSDavid du Colombier for(a=va_arg(fmt->args, Attr*); a; a=a->next){
159a747e4fSDavid du Colombier if(a->name == nil)
169a747e4fSDavid du Colombier continue;
179a747e4fSDavid du Colombier switch(a->type){
189a747e4fSDavid du Colombier case AttrQuery:
19*2ebbfa15SDavid du Colombier b = seprint(b, ebuf, " %q?", a->name);
209a747e4fSDavid du Colombier break;
219a747e4fSDavid du Colombier case AttrNameval:
22*2ebbfa15SDavid du Colombier b = seprint(b, ebuf, " %q=%q", a->name, a->val);
239a747e4fSDavid du Colombier break;
249a747e4fSDavid du Colombier case AttrDefault:
25*2ebbfa15SDavid du Colombier b = seprint(b, ebuf, " %q:=%q", a->name, a->val);
269a747e4fSDavid du Colombier break;
279a747e4fSDavid du Colombier }
289a747e4fSDavid du Colombier }
299a747e4fSDavid du Colombier return fmtstrcpy(fmt, buf+1);
309a747e4fSDavid du Colombier }
319a747e4fSDavid du Colombier
329a747e4fSDavid du Colombier Attr*
_copyattr(Attr * a)339a747e4fSDavid du Colombier _copyattr(Attr *a)
349a747e4fSDavid du Colombier {
359a747e4fSDavid du Colombier Attr **la, *na;
369a747e4fSDavid du Colombier
379a747e4fSDavid du Colombier na = nil;
389a747e4fSDavid du Colombier la = &na;
399a747e4fSDavid du Colombier for(; a; a=a->next){
40*2ebbfa15SDavid du Colombier *la = _mkattr(a->type, a->name, a->val, nil);
419a747e4fSDavid du Colombier setmalloctag(*la, getcallerpc(&a));
429a747e4fSDavid du Colombier la = &(*la)->next;
439a747e4fSDavid du Colombier }
449a747e4fSDavid du Colombier *la = nil;
459a747e4fSDavid du Colombier return na;
469a747e4fSDavid du Colombier }
479a747e4fSDavid du Colombier
489a747e4fSDavid du Colombier Attr*
_delattr(Attr * a,char * name)499a747e4fSDavid du Colombier _delattr(Attr *a, char *name)
509a747e4fSDavid du Colombier {
519a747e4fSDavid du Colombier Attr *fa;
529a747e4fSDavid du Colombier Attr **la;
539a747e4fSDavid du Colombier
549a747e4fSDavid du Colombier for(la=&a; *la; ){
55*2ebbfa15SDavid du Colombier if(strcmp((*la)->name, name) == 0){
569a747e4fSDavid du Colombier fa = *la;
579a747e4fSDavid du Colombier *la = (*la)->next;
589a747e4fSDavid du Colombier fa->next = nil;
599a747e4fSDavid du Colombier _freeattr(fa);
609a747e4fSDavid du Colombier }else
619a747e4fSDavid du Colombier la=&(*la)->next;
629a747e4fSDavid du Colombier }
639a747e4fSDavid du Colombier return a;
649a747e4fSDavid du Colombier }
659a747e4fSDavid du Colombier
669a747e4fSDavid du Colombier Attr*
_findattr(Attr * a,char * n)679a747e4fSDavid du Colombier _findattr(Attr *a, char *n)
689a747e4fSDavid du Colombier {
699a747e4fSDavid du Colombier for(; a; a=a->next)
70*2ebbfa15SDavid du Colombier if(strcmp(a->name, n) == 0 && a->type != AttrQuery)
719a747e4fSDavid du Colombier return a;
729a747e4fSDavid du Colombier return nil;
739a747e4fSDavid du Colombier }
749a747e4fSDavid du Colombier
759a747e4fSDavid du Colombier void
_freeattr(Attr * a)769a747e4fSDavid du Colombier _freeattr(Attr *a)
779a747e4fSDavid du Colombier {
789a747e4fSDavid du Colombier Attr *anext;
799a747e4fSDavid du Colombier
809a747e4fSDavid du Colombier for(; a; a=anext){
819a747e4fSDavid du Colombier anext = a->next;
82*2ebbfa15SDavid du Colombier free(a->name);
83*2ebbfa15SDavid du Colombier free(a->val);
849a747e4fSDavid du Colombier a->name = (void*)~0;
859a747e4fSDavid du Colombier a->val = (void*)~0;
869a747e4fSDavid du Colombier a->next = (void*)~0;
879a747e4fSDavid du Colombier free(a);
889a747e4fSDavid du Colombier }
899a747e4fSDavid du Colombier }
909a747e4fSDavid du Colombier
919a747e4fSDavid du Colombier Attr*
_mkattr(int type,char * name,char * val,Attr * next)929a747e4fSDavid du Colombier _mkattr(int type, char *name, char *val, Attr *next)
939a747e4fSDavid du Colombier {
949a747e4fSDavid du Colombier Attr *a;
959a747e4fSDavid du Colombier
969a747e4fSDavid du Colombier a = malloc(sizeof(*a));
979a747e4fSDavid du Colombier if(a==nil)
989a747e4fSDavid du Colombier sysfatal("_mkattr malloc: %r");
999a747e4fSDavid du Colombier a->type = type;
100*2ebbfa15SDavid du Colombier a->name = strdup(name);
101*2ebbfa15SDavid du Colombier a->val = strdup(val);
102*2ebbfa15SDavid du Colombier if(a->name==nil || a->val==nil)
103*2ebbfa15SDavid du Colombier sysfatal("_mkattr malloc: %r");
1049a747e4fSDavid du Colombier a->next = next;
1059a747e4fSDavid du Colombier setmalloctag(a, getcallerpc(&type));
1069a747e4fSDavid du Colombier return a;
1079a747e4fSDavid du Colombier }
1089a747e4fSDavid du Colombier
1099a747e4fSDavid du Colombier static Attr*
cleanattr(Attr * a)1109a747e4fSDavid du Colombier cleanattr(Attr *a)
1119a747e4fSDavid du Colombier {
1129a747e4fSDavid du Colombier Attr *fa;
1139a747e4fSDavid du Colombier Attr **la;
1149a747e4fSDavid du Colombier
1159a747e4fSDavid du Colombier for(la=&a; *la; ){
116*2ebbfa15SDavid du Colombier if((*la)->type==AttrQuery && _findattr(a, (*la)->name)){
1179a747e4fSDavid du Colombier fa = *la;
1189a747e4fSDavid du Colombier *la = (*la)->next;
1199a747e4fSDavid du Colombier fa->next = nil;
1209a747e4fSDavid du Colombier _freeattr(fa);
1219a747e4fSDavid du Colombier }else
1229a747e4fSDavid du Colombier la=&(*la)->next;
1239a747e4fSDavid du Colombier }
1249a747e4fSDavid du Colombier return a;
1259a747e4fSDavid du Colombier }
1269a747e4fSDavid du Colombier
1279a747e4fSDavid du Colombier Attr*
_parseattr(char * s)1289a747e4fSDavid du Colombier _parseattr(char *s)
1299a747e4fSDavid du Colombier {
1309a747e4fSDavid du Colombier char *p, *t, *tok[256];
1319a747e4fSDavid du Colombier int i, ntok, type;
1329a747e4fSDavid du Colombier Attr *a;
1339a747e4fSDavid du Colombier
1349a747e4fSDavid du Colombier s = strdup(s);
1359a747e4fSDavid du Colombier if(s == nil)
1369a747e4fSDavid du Colombier sysfatal("_parseattr strdup: %r");
1379a747e4fSDavid du Colombier
1389a747e4fSDavid du Colombier ntok = tokenize(s, tok, nelem(tok));
1399a747e4fSDavid du Colombier a = nil;
1409a747e4fSDavid du Colombier for(i=ntok-1; i>=0; i--){
1419a747e4fSDavid du Colombier t = tok[i];
1429a747e4fSDavid du Colombier if(p = strchr(t, '=')){
1439a747e4fSDavid du Colombier *p++ = '\0';
1449a747e4fSDavid du Colombier // if(p-2 >= t && p[-2] == ':'){
1459a747e4fSDavid du Colombier // p[-2] = '\0';
1469a747e4fSDavid du Colombier // type = AttrDefault;
1479a747e4fSDavid du Colombier // }else
1489a747e4fSDavid du Colombier type = AttrNameval;
1499a747e4fSDavid du Colombier a = _mkattr(type, t, p, a);
1509a747e4fSDavid du Colombier setmalloctag(a, getcallerpc(&s));
1519a747e4fSDavid du Colombier }
1529a747e4fSDavid du Colombier else if(t[strlen(t)-1] == '?'){
1539a747e4fSDavid du Colombier t[strlen(t)-1] = '\0';
1549a747e4fSDavid du Colombier a = _mkattr(AttrQuery, t, "", a);
1559a747e4fSDavid du Colombier setmalloctag(a, getcallerpc(&s));
1569a747e4fSDavid du Colombier }else{
1579a747e4fSDavid du Colombier /* really a syntax error, but better to provide some indication */
1589a747e4fSDavid du Colombier a = _mkattr(AttrNameval, t, "", a);
1599a747e4fSDavid du Colombier setmalloctag(a, getcallerpc(&s));
1609a747e4fSDavid du Colombier }
1619a747e4fSDavid du Colombier }
1629a747e4fSDavid du Colombier free(s);
1639a747e4fSDavid du Colombier return cleanattr(a);
1649a747e4fSDavid du Colombier }
1659a747e4fSDavid du Colombier
1669a747e4fSDavid du Colombier char*
_strfindattr(Attr * a,char * n)167*2ebbfa15SDavid du Colombier _strfindattr(Attr *a, char *n)
1689a747e4fSDavid du Colombier {
1699a747e4fSDavid du Colombier a = _findattr(a, n);
1709a747e4fSDavid du Colombier if(a == nil)
1719a747e4fSDavid du Colombier return nil;
172*2ebbfa15SDavid du Colombier return a->val;
1739a747e4fSDavid du Colombier }
1749a747e4fSDavid du Colombier
175