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