URI:
       tkey.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tkey.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 }