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