URI:
       tmain.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
       ---
       tmain.c (3534B)
       ---
            1 #include "std.h"
            2 #include "dat.h"
            3 #include <9pclient.h>
            4 
            5 int extrafactotumdir;
            6 int debug;
            7 int trysecstore = 1;
            8 char *factname = "factotum";
            9 char *service = "factotum";
           10 char *owner;
           11 char *authaddr;
           12 void gflag(char*);
           13 
           14 void
           15 usage(void)
           16 {
           17         fprint(2, "usage: factotum [-Dd] [-a authaddr] [-m mtpt] [-s service]\n");
           18         fprint(2, " or   factotum -g keypattern\n");
           19         fprint(2, " or   factotum -g 'badkeyattr\\nmsg\\nkeypattern'\n");
           20         threadexitsall("usage");
           21 }
           22 
           23 int
           24 threadmaybackground(void)
           25 {
           26         return 1;
           27 }
           28 
           29 void
           30 threadmain(int argc, char *argv[])
           31 {
           32         char *mtpt;
           33         char err[ERRMAX];
           34 
           35 /*        mtpt = "/mnt"; */
           36         mtpt = nil;
           37         owner = getuser();
           38         quotefmtinstall();
           39         fmtinstall('A', attrfmt);
           40         fmtinstall('H', encodefmt);
           41         fmtinstall('N', attrnamefmt);
           42 
           43         if(argc == 3 && strcmp(argv[1], "-g") == 0){
           44                 gflag(argv[2]);
           45                 threadexitsall(nil);
           46         }
           47 
           48         ARGBEGIN{
           49         default:
           50                 usage();
           51         case 'D':
           52                 chatty9p++;
           53                 break;
           54         case 'a':
           55                 authaddr = EARGF(usage());
           56                 break;
           57         case 'd':
           58                 debug = 1;
           59                 break;
           60         case 'g':
           61                 usage();
           62         case 'm':
           63                 mtpt = EARGF(usage());
           64                 break;
           65         case 's':
           66                 service = EARGF(usage());
           67                 break;
           68         case 'n':
           69                 trysecstore = 0;
           70                 break;
           71         case 'x':
           72                 extrafactotumdir = 1;
           73                 break;
           74         }ARGEND
           75 
           76         if(argc != 0)
           77                 usage();
           78 
           79         if(trysecstore && havesecstore()){
           80                 while(secstorefetch() < 0){
           81                         rerrstr(err, sizeof err);
           82                         if(strcmp(err, "cancel") == 0)
           83                                 break;
           84                         fprint(2, "secstorefetch: %r\n");
           85                         fprint(2, "Enter an empty password to quit.\n");
           86                 }
           87         }
           88 
           89         rfork(RFNOTEG);
           90 
           91         fsinit0();
           92         threadpostmountsrv(&fs, service, mtpt, MBEFORE);
           93         threadexits(nil);
           94 }
           95 
           96 /*
           97  *  prompt user for a key.  don't care about memory leaks, runs standalone
           98  */
           99 static Attr*
          100 promptforkey(int fd, char *params)
          101 {
          102         char *v;
          103         Attr *a, *attr;
          104         char *def;
          105 
          106         attr = _parseattr(params);
          107         fprint(fd, "!adding key:");
          108         for(a=attr; a; a=a->next)
          109                 if(a->type != AttrQuery && a->name[0] != '!')
          110                         fprint(fd, " %q=%q", a->name, a->val);
          111         fprint(fd, "\n");
          112 
          113         for(a=attr; a; a=a->next){
          114                 v = a->name;
          115                 if(a->type != AttrQuery || v[0]=='!')
          116                         continue;
          117                 def = nil;
          118                 if(strcmp(v, "user") == 0)
          119                         def = getuser();
          120                 a->val = readcons(v, def, 0);
          121                 if(a->val == nil)
          122                         sysfatal("user terminated key input");
          123                 a->type = AttrNameval;
          124         }
          125         for(a=attr; a; a=a->next){
          126                 v = a->name;
          127                 if(a->type != AttrQuery || v[0]!='!')
          128                         continue;
          129                 def = nil;
          130                 if(strcmp(v+1, "user") == 0)
          131                         def = getuser();
          132                 a->val = readcons(v+1, def, 1);
          133                 if(a->val == nil)
          134                         sysfatal("user terminated key input");
          135                 a->type = AttrNameval;
          136         }
          137         fprint(fd, "!\n");
          138         close(fd);
          139         return attr;
          140 }
          141 
          142 /*
          143  *  send a key to the mounted factotum
          144  */
          145 static int
          146 sendkey(Attr *attr)
          147 {
          148         int rv;
          149         char buf[8192];
          150         CFid *fid;
          151 
          152         fid = nsopen("factotum", nil, "ctl", OWRITE);
          153         if(fid == nil)
          154                 sysfatal("opening factotum/ctl: %r");
          155         snprint(buf, sizeof buf, "key %A\n", attr);
          156         rv = fswrite(fid, buf, strlen(buf));
          157         fsclose(fid);
          158         return rv;
          159 }
          160 
          161 static void
          162 askuser(int fd, char *params)
          163 {
          164         Attr *attr;
          165 
          166         attr = promptforkey(fd, params);
          167         if(attr == nil)
          168                 sysfatal("no key supplied");
          169         if(sendkey(attr) < 0)
          170                 sysfatal("sending key to factotum: %r");
          171 }
          172 
          173 void
          174 gflag(char *s)
          175 {
          176         char *f[4];
          177         int nf;
          178         int fd;
          179 
          180         if((fd = open("/dev/tty", ORDWR)) < 0)
          181                 sysfatal("open /dev/tty: %r");
          182 
          183         nf = getfields(s, f, nelem(f), 0, "\n");
          184         if(nf == 1){        /* needkey or old badkey */
          185                 fprint(fd, "\n");
          186                 askuser(fd, s);
          187                 threadexitsall(nil);
          188         }
          189         if(nf == 3){        /* new badkey */
          190                 fprint(fd, "\n");
          191                 fprint(fd, "!replace: %s\n", f[0]);
          192                 fprint(fd, "!because: %s\n", f[1]);
          193                 askuser(fd, f[2]);
          194                 threadexitsall(nil);
          195         }
          196         usage();
          197 }