Blob


1 #include "std.h"
2 #include "dat.h"
4 Ring ring;
6 Key*
7 keylookup(char *fmt, ...)
8 {
9 int i;
10 Attr *a;
11 Key *k;
12 va_list arg;
14 va_start(arg, fmt);
15 a = parseattrfmtv(fmt, arg);
16 va_end(arg);
18 for(i=0; i<ring.nkey; i++){
19 k = ring.key[i];
20 if(matchattr(a, k->attr, k->privattr)){
21 k->ref++;
22 freeattr(a);
23 return k;
24 }
25 }
26 freeattr(a);
27 werrstr("no key found");
28 return nil;
29 }
31 Key*
32 keyfetch(Conv *c, char *fmt, ...)
33 {
34 int i, tag;
35 Attr *a;
36 Key *k;
37 va_list arg;
39 va_start(arg, fmt);
40 a = parseattrfmtv(fmt, arg);
41 va_end(arg);
43 tag = 0;
45 for(i=0; i<ring.nkey; i++){
46 k = ring.key[i];
47 if(tag < k->tag)
48 tag = k->tag;
49 if(matchattr(a, k->attr, k->privattr)){
50 k->ref++;
51 if(strfindattr(k->attr, "confirm") && confirmkey(c, k) != 1){
52 k->ref--;
53 continue;
54 }
55 freeattr(a);
56 return k;
57 }
58 }
60 if(needkey(c, a) < 0)
61 convneedkey(c, a);
63 for(i=0; i<ring.nkey; i++){
64 k = ring.key[i];
65 if(k->tag <= tag)
66 continue;
67 if(matchattr(a, k->attr, k->privattr)){
68 k->ref++;
69 if(strfindattr(k->attr, "confirm") && confirmkey(c, k) != 1){
70 k->ref--;
71 continue;
72 }
73 freeattr(a);
74 return k;
75 }
76 }
77 freeattr(a);
78 werrstr("no key found");
79 return nil;
80 }
82 static int taggen;
84 void
85 keyadd(Key *k)
86 {
87 int i;
89 k->ref++;
90 k->tag = ++taggen;
91 for(i=0; i<ring.nkey; i++){
92 if(matchattr(k->attr, ring.key[i]->attr, nil)
93 && matchattr(ring.key[i]->attr, k->attr, nil)){
94 keyclose(ring.key[i]);
95 ring.key[i] = k;
96 return;
97 }
98 }
100 ring.key = erealloc(ring.key, (ring.nkey+1)*sizeof(ring.key[0]));
101 ring.key[ring.nkey++] = k;
104 void
105 keyclose(Key *k)
107 if(k == nil)
108 return;
110 if(--k->ref > 0)
111 return;
113 if(k->proto->closekey)
114 (*k->proto->closekey)(k);
116 freeattr(k->attr);
117 freeattr(k->privattr);
118 free(k);
121 Key*
122 keyreplace(Conv *c, Key *k, char *fmt, ...)
124 Key *kk;
125 char *msg;
126 Attr *a, *b, *bp;
127 va_list arg;
129 va_start(arg, fmt);
130 msg = vsmprint(fmt, arg);
131 if(msg == nil)
132 sysfatal("out of memory");
133 va_end(arg);
135 /* replace prompted values with prompts */
136 a = copyattr(k->attr);
137 bp = parseattr(k->proto->keyprompt);
138 for(b=bp; b; b=b->next){
139 a = delattr(a, b->name);
140 a = addattr(a, "%q?", b->name);
142 freeattr(bp);
144 if(badkey(c, k, msg, a) < 0)
145 convbadkey(c, k, msg, a);
146 kk = keylookup("%A", a);
147 freeattr(a);
148 keyclose(k);
149 if(kk == k){
150 keyclose(kk);
151 werrstr("%s", msg);
152 return nil;
155 if(strfindattr(kk->attr, "confirm")){
156 if(confirmkey(c, kk) != 1){
157 werrstr("key use not confirmed");
158 keyclose(kk);
159 return nil;
162 return kk;
165 void
166 keyevict(Conv *c, Key *k, char *fmt, ...)
168 char *msg;
169 Attr *a, *b, *bp;
170 va_list arg;
172 va_start(arg, fmt);
173 msg = vsmprint(fmt, arg);
174 if(msg == nil)
175 sysfatal("out of memory");
176 va_end(arg);
178 /* replace prompted values with prompts */
179 a = copyattr(k->attr);
180 bp = parseattr(k->proto->keyprompt);
181 for(b=bp; b; b=b->next){
182 a = delattr(a, b->name);
183 a = addattr(a, "%q?", b->name);
185 freeattr(bp);
187 if(badkey(c, k, msg, nil) < 0)
188 convbadkey(c, k, msg, nil);
189 keyclose(k);