Blob


1 #include "std.h"
2 #include "dat.h"
4 Ring ring;
6 Key*
7 keyiterate(int skip, 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 if(skip-- > 0)
22 continue;
23 k->ref++;
24 freeattr(a);
25 return k;
26 }
27 }
28 freeattr(a);
29 werrstr("no key found");
30 return nil;
31 }
33 Key*
34 keylookup(char *fmt, ...)
35 {
36 int i;
37 Attr *a;
38 Key *k;
39 va_list arg;
41 va_start(arg, fmt);
42 a = parseattrfmtv(fmt, arg);
43 va_end(arg);
45 for(i=0; i<ring.nkey; i++){
46 k = ring.key[i];
47 if(matchattr(a, k->attr, k->privattr)){
48 k->ref++;
49 freeattr(a);
50 return k;
51 }
52 }
53 freeattr(a);
54 werrstr("no key found");
55 return nil;
56 }
58 Key*
59 keyfetch(Conv *c, char *fmt, ...)
60 {
61 int i, tag;
62 Attr *a;
63 Key *k;
64 va_list arg;
66 va_start(arg, fmt);
67 a = parseattrfmtv(fmt, arg);
68 va_end(arg);
70 flog("keyfetch %A", a);
71 tag = 0;
73 for(i=0; i<ring.nkey; i++){
74 k = ring.key[i];
75 if(tag < k->tag)
76 tag = k->tag;
77 if(matchattr(a, k->attr, k->privattr)){
78 k->ref++;
79 if(strfindattr(k->attr, "confirm") && confirmkey(c, k) != 1){
80 k->ref--;
81 continue;
82 }
83 freeattr(a);
84 flog("using key %A %N", k->attr, k->privattr);
85 return k;
86 }
87 }
89 if(needkey(c, a) < 0)
90 convneedkey(c, a);
92 for(i=0; i<ring.nkey; i++){
93 k = ring.key[i];
94 if(k->tag <= tag)
95 continue;
96 if(matchattr(a, k->attr, k->privattr)){
97 k->ref++;
98 if(strfindattr(k->attr, "confirm") && confirmkey(c, k) != 1){
99 k->ref--;
100 continue;
102 freeattr(a);
103 return k;
106 freeattr(a);
107 werrstr("no key found");
108 return nil;
111 static int taggen;
113 void
114 keyadd(Key *k)
116 int i;
118 k->ref++;
119 k->tag = ++taggen;
120 for(i=0; i<ring.nkey; i++){
121 if(matchattr(k->attr, ring.key[i]->attr, nil)
122 && matchattr(ring.key[i]->attr, k->attr, nil)){
123 keyclose(ring.key[i]);
124 ring.key[i] = k;
125 return;
129 ring.key = erealloc(ring.key, (ring.nkey+1)*sizeof(ring.key[0]));
130 ring.key[ring.nkey++] = k;
133 void
134 keyclose(Key *k)
136 if(k == nil)
137 return;
139 if(--k->ref > 0)
140 return;
142 if(k->proto->closekey)
143 (*k->proto->closekey)(k);
145 freeattr(k->attr);
146 freeattr(k->privattr);
147 free(k);
150 Key*
151 keyreplace(Conv *c, Key *k, char *fmt, ...)
153 Key *kk;
154 char *msg;
155 Attr *a, *b, *bp;
156 va_list arg;
158 va_start(arg, fmt);
159 msg = vsmprint(fmt, arg);
160 if(msg == nil)
161 sysfatal("out of memory");
162 va_end(arg);
164 /* replace prompted values with prompts */
165 a = copyattr(k->attr);
166 bp = parseattr(k->proto->keyprompt);
167 for(b=bp; b; b=b->next){
168 a = delattr(a, b->name);
169 a = addattr(a, "%q?", b->name);
171 freeattr(bp);
173 if(badkey(c, k, msg, a) < 0)
174 convbadkey(c, k, msg, a);
175 kk = keylookup("%A", a);
176 freeattr(a);
177 keyclose(k);
178 if(kk == k){
179 keyclose(kk);
180 werrstr("%s", msg);
181 return nil;
184 if(strfindattr(kk->attr, "confirm")){
185 if(confirmkey(c, kk) != 1){
186 werrstr("key use not confirmed");
187 keyclose(kk);
188 return nil;
191 return kk;
194 void
195 keyevict(Conv *c, Key *k, char *fmt, ...)
197 char *msg;
198 Attr *a, *b, *bp;
199 va_list arg;
201 va_start(arg, fmt);
202 msg = vsmprint(fmt, arg);
203 if(msg == nil)
204 sysfatal("out of memory");
205 va_end(arg);
207 /* replace prompted values with prompts */
208 a = copyattr(k->attr);
209 bp = parseattr(k->proto->keyprompt);
210 for(b=bp; b; b=b->next){
211 a = delattr(a, b->name);
212 a = addattr(a, "%q?", b->name);
214 freeattr(bp);
216 if(badkey(c, k, msg, nil) < 0)
217 convbadkey(c, k, msg, nil);
218 keyclose(k);