key.c (3469B)
1 #include "std.h" 2 #include "dat.h" 3 4 Ring ring; 5 6 Key* 7 keyiterate(int skip, char *fmt, ...) 8 { 9 int i; 10 Attr *a; 11 Key *k; 12 va_list arg; 13 14 va_start(arg, fmt); 15 a = parseattrfmtv(fmt, arg); 16 va_end(arg); 17 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 } 32 33 Key* 34 keylookup(char *fmt, ...) 35 { 36 int i; 37 Attr *a; 38 Key *k; 39 va_list arg; 40 41 va_start(arg, fmt); 42 a = parseattrfmtv(fmt, arg); 43 va_end(arg); 44 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 } 57 58 Key* 59 keyfetch(Conv *c, char *fmt, ...) 60 { 61 int i, tag; 62 Attr *a; 63 Key *k; 64 va_list arg; 65 66 va_start(arg, fmt); 67 a = parseattrfmtv(fmt, arg); 68 va_end(arg); 69 70 flog("keyfetch %A", a); 71 tag = 0; 72 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 } 88 89 if(needkey(c, a) < 0) 90 convneedkey(c, a); 91 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; 101 } 102 freeattr(a); 103 return k; 104 } 105 } 106 freeattr(a); 107 werrstr("no key found"); 108 return nil; 109 } 110 111 static int taggen; 112 113 void 114 keyadd(Key *k) 115 { 116 int i; 117 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; 126 } 127 } 128 129 ring.key = erealloc(ring.key, (ring.nkey+1)*sizeof(ring.key[0])); 130 ring.key[ring.nkey++] = k; 131 } 132 133 void 134 keyclose(Key *k) 135 { 136 if(k == nil) 137 return; 138 139 if(--k->ref > 0) 140 return; 141 142 if(k->proto->closekey) 143 (*k->proto->closekey)(k); 144 145 freeattr(k->attr); 146 freeattr(k->privattr); 147 free(k); 148 } 149 150 Key* 151 keyreplace(Conv *c, Key *k, char *fmt, ...) 152 { 153 Key *kk; 154 char *msg; 155 Attr *a, *b, *bp; 156 va_list arg; 157 158 va_start(arg, fmt); 159 msg = vsmprint(fmt, arg); 160 if(msg == nil) 161 sysfatal("out of memory"); 162 va_end(arg); 163 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); 170 } 171 freeattr(bp); 172 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; 182 } 183 184 if(strfindattr(kk->attr, "confirm")){ 185 if(confirmkey(c, kk) != 1){ 186 werrstr("key use not confirmed"); 187 keyclose(kk); 188 return nil; 189 } 190 } 191 return kk; 192 } 193 194 void 195 keyevict(Conv *c, Key *k, char *fmt, ...) 196 { 197 char *msg; 198 Attr *a, *b, *bp; 199 va_list arg; 200 201 va_start(arg, fmt); 202 msg = vsmprint(fmt, arg); 203 if(msg == nil) 204 sysfatal("out of memory"); 205 va_end(arg); 206 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); 213 } 214 freeattr(bp); 215 216 if(badkey(c, k, msg, nil) < 0) 217 convbadkey(c, k, msg, nil); 218 keyclose(k); 219 }