Add real factotum.
This commit is contained in:
174
libauth/attr.c
Normal file
174
libauth/attr.c
Normal file
@ -0,0 +1,174 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <auth.h>
|
||||
|
||||
int
|
||||
_attrfmt(Fmt *fmt)
|
||||
{
|
||||
char *b, buf[1024], *ebuf;
|
||||
Attr *a;
|
||||
|
||||
ebuf = buf+sizeof buf;
|
||||
b = buf;
|
||||
strcpy(buf, " ");
|
||||
for(a=va_arg(fmt->args, Attr*); a; a=a->next){
|
||||
if(a->name == nil)
|
||||
continue;
|
||||
switch(a->type){
|
||||
case AttrQuery:
|
||||
b = seprint(b, ebuf, " %q?", a->name);
|
||||
break;
|
||||
case AttrNameval:
|
||||
b = seprint(b, ebuf, " %q=%q", a->name, a->val);
|
||||
break;
|
||||
case AttrDefault:
|
||||
b = seprint(b, ebuf, " %q:=%q", a->name, a->val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return fmtstrcpy(fmt, buf+1);
|
||||
}
|
||||
|
||||
Attr*
|
||||
_copyattr(Attr *a)
|
||||
{
|
||||
Attr **la, *na;
|
||||
|
||||
na = nil;
|
||||
la = &na;
|
||||
for(; a; a=a->next){
|
||||
*la = _mkattr(a->type, a->name, a->val, nil);
|
||||
setmalloctag(*la, getcallerpc(&a));
|
||||
la = &(*la)->next;
|
||||
}
|
||||
*la = nil;
|
||||
return na;
|
||||
}
|
||||
|
||||
Attr*
|
||||
_delattr(Attr *a, char *name)
|
||||
{
|
||||
Attr *fa;
|
||||
Attr **la;
|
||||
|
||||
for(la=&a; *la; ){
|
||||
if(strcmp((*la)->name, name) == 0){
|
||||
fa = *la;
|
||||
*la = (*la)->next;
|
||||
fa->next = nil;
|
||||
_freeattr(fa);
|
||||
}else
|
||||
la=&(*la)->next;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
Attr*
|
||||
_findattr(Attr *a, char *n)
|
||||
{
|
||||
for(; a; a=a->next)
|
||||
if(strcmp(a->name, n) == 0 && a->type != AttrQuery)
|
||||
return a;
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
_freeattr(Attr *a)
|
||||
{
|
||||
Attr *anext;
|
||||
|
||||
for(; a; a=anext){
|
||||
anext = a->next;
|
||||
free(a->name);
|
||||
free(a->val);
|
||||
a->name = (void*)~0;
|
||||
a->val = (void*)~0;
|
||||
a->next = (void*)~0;
|
||||
free(a);
|
||||
}
|
||||
}
|
||||
|
||||
Attr*
|
||||
_mkattr(int type, char *name, char *val, Attr *next)
|
||||
{
|
||||
Attr *a;
|
||||
|
||||
a = malloc(sizeof(*a));
|
||||
if(a==nil)
|
||||
sysfatal("_mkattr malloc: %r");
|
||||
a->type = type;
|
||||
a->name = strdup(name);
|
||||
a->val = strdup(val);
|
||||
if(a->name==nil || a->val==nil)
|
||||
sysfatal("_mkattr malloc: %r");
|
||||
a->next = next;
|
||||
setmalloctag(a, getcallerpc(&type));
|
||||
return a;
|
||||
}
|
||||
|
||||
static Attr*
|
||||
cleanattr(Attr *a)
|
||||
{
|
||||
Attr *fa;
|
||||
Attr **la;
|
||||
|
||||
for(la=&a; *la; ){
|
||||
if((*la)->type==AttrQuery && _findattr(a, (*la)->name)){
|
||||
fa = *la;
|
||||
*la = (*la)->next;
|
||||
fa->next = nil;
|
||||
_freeattr(fa);
|
||||
}else
|
||||
la=&(*la)->next;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
Attr*
|
||||
_parseattr(char *s)
|
||||
{
|
||||
char *p, *t, *tok[256];
|
||||
int i, ntok, type;
|
||||
Attr *a;
|
||||
|
||||
s = strdup(s);
|
||||
if(s == nil)
|
||||
sysfatal("_parseattr strdup: %r");
|
||||
|
||||
ntok = tokenize(s, tok, nelem(tok));
|
||||
a = nil;
|
||||
for(i=ntok-1; i>=0; i--){
|
||||
t = tok[i];
|
||||
if(p = strchr(t, '=')){
|
||||
*p++ = '\0';
|
||||
// if(p-2 >= t && p[-2] == ':'){
|
||||
// p[-2] = '\0';
|
||||
// type = AttrDefault;
|
||||
// }else
|
||||
type = AttrNameval;
|
||||
a = _mkattr(type, t, p, a);
|
||||
setmalloctag(a, getcallerpc(&s));
|
||||
}
|
||||
else if(t[strlen(t)-1] == '?'){
|
||||
t[strlen(t)-1] = '\0';
|
||||
a = _mkattr(AttrQuery, t, "", a);
|
||||
setmalloctag(a, getcallerpc(&s));
|
||||
}else{
|
||||
/* really a syntax error, but better to provide some indication */
|
||||
a = _mkattr(AttrNameval, t, "", a);
|
||||
setmalloctag(a, getcallerpc(&s));
|
||||
}
|
||||
}
|
||||
free(s);
|
||||
return cleanattr(a);
|
||||
}
|
||||
|
||||
char*
|
||||
_strfindattr(Attr *a, char *n)
|
||||
{
|
||||
a = _findattr(a, n);
|
||||
if(a == nil)
|
||||
return nil;
|
||||
return a->val;
|
||||
}
|
||||
|
Reference in New Issue
Block a user