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