Small tweaks
Lots of new code imported.
This commit is contained in:
parent
a770daa795
commit
2277c5d7bb
86 changed files with 12444 additions and 91 deletions
158
src/cmd/factotum/ctl.c
Normal file
158
src/cmd/factotum/ctl.c
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
#include "std.h"
|
||||
#include "dat.h"
|
||||
|
||||
/*
|
||||
* key attr=val... - add a key
|
||||
* the attr=val pairs are protocol-specific.
|
||||
* for example, both of these are valid:
|
||||
* key p9sk1 gre cs.bell-labs.com mysecret
|
||||
* key p9sk1 gre cs.bell-labs.com 11223344556677 fmt=des7hex
|
||||
* delkey ... - delete a key
|
||||
* if given, the attr=val pairs are used to narrow the search
|
||||
* [maybe should require a password?]
|
||||
*
|
||||
* debug - toggle debugging
|
||||
*/
|
||||
|
||||
static char *msg[] = {
|
||||
"key",
|
||||
"delkey",
|
||||
"debug",
|
||||
};
|
||||
|
||||
static int
|
||||
classify(char *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<nelem(msg); i++)
|
||||
if(strcmp(msg[i], s) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ctlwrite(char *a)
|
||||
{
|
||||
char *p;
|
||||
int i, nmatch, ret;
|
||||
Attr *attr, **l, **lpriv, **lprotos, *pa, *priv, *protos;
|
||||
Key *k;
|
||||
Proto *proto;
|
||||
|
||||
if(a[0] == '#' || a[0] == '\0')
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* it would be nice to emit a warning of some sort here.
|
||||
* we ignore all but the first line of the write. this helps
|
||||
* both with things like "echo delkey >/mnt/factotum/ctl"
|
||||
* and writes that (incorrectly) contain multiple key lines.
|
||||
*/
|
||||
if(p = strchr(a, '\n')){
|
||||
if(p[1] != '\0'){
|
||||
werrstr("multiline write not allowed");
|
||||
return -1;
|
||||
}
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
if((p = strchr(a, ' ')) == nil)
|
||||
p = "";
|
||||
else
|
||||
*p++ = '\0';
|
||||
switch(classify(a)){
|
||||
default:
|
||||
werrstr("unknown verb");
|
||||
return -1;
|
||||
case 0: /* key */
|
||||
attr = parseattr(p);
|
||||
/* separate out proto= attributes */
|
||||
lprotos = &protos;
|
||||
for(l=&attr; (*l); ){
|
||||
if(strcmp((*l)->name, "proto") == 0){
|
||||
*lprotos = *l;
|
||||
lprotos = &(*l)->next;
|
||||
*l = (*l)->next;
|
||||
}else
|
||||
l = &(*l)->next;
|
||||
}
|
||||
*lprotos = nil;
|
||||
if(protos == nil){
|
||||
werrstr("key without protos");
|
||||
freeattr(attr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* separate out private attributes */
|
||||
lpriv = &priv;
|
||||
for(l=&attr; (*l); ){
|
||||
if((*l)->name[0] == '!'){
|
||||
*lpriv = *l;
|
||||
lpriv = &(*l)->next;
|
||||
*l = (*l)->next;
|
||||
}else
|
||||
l = &(*l)->next;
|
||||
}
|
||||
*lpriv = nil;
|
||||
|
||||
/* add keys */
|
||||
ret = 0;
|
||||
for(pa=protos; pa; pa=pa->next){
|
||||
if((proto = protolookup(pa->val)) == nil){
|
||||
werrstr("unknown proto %s", pa->val);
|
||||
ret = -1;
|
||||
continue;
|
||||
}
|
||||
if(proto->checkkey == nil){
|
||||
werrstr("proto %s does not accept keys", proto->name);
|
||||
ret = -1;
|
||||
continue;
|
||||
}
|
||||
k = emalloc(sizeof(Key));
|
||||
k->attr = mkattr(AttrNameval, "proto", proto->name, copyattr(attr));
|
||||
k->privattr = copyattr(priv);
|
||||
k->ref = 1;
|
||||
k->proto = proto;
|
||||
if((*proto->checkkey)(k) < 0){
|
||||
ret = -1;
|
||||
keyclose(k);
|
||||
continue;
|
||||
}
|
||||
keyadd(k);
|
||||
keyclose(k);
|
||||
}
|
||||
freeattr(attr);
|
||||
freeattr(priv);
|
||||
freeattr(protos);
|
||||
return ret;
|
||||
case 1: /* delkey */
|
||||
nmatch = 0;
|
||||
attr = parseattr(p);
|
||||
for(pa=attr; pa; pa=pa->next){
|
||||
if(pa->type != AttrQuery && pa->name[0]=='!'){
|
||||
werrstr("only !private? patterns are allowed for private fields");
|
||||
freeattr(attr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
for(i=0; i<ring.nkey; ){
|
||||
if(matchattr(attr, ring.key[i]->attr, ring.key[i]->privattr)){
|
||||
nmatch++;
|
||||
keyclose(ring.key[i]);
|
||||
ring.nkey--;
|
||||
memmove(&ring.key[i], &ring.key[i+1], (ring.nkey-i)*sizeof(ring.key[0]));
|
||||
}else
|
||||
i++;
|
||||
}
|
||||
freeattr(attr);
|
||||
if(nmatch == 0){
|
||||
werrstr("found no keys to delete");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
case 2: /* debug */
|
||||
debug ^= 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue