chandial.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       chandial.c (2276B)
       ---
            1 #include        "u.h"
            2 #include        "lib.h"
            3 #include        "mem.h"
            4 #include        "dat.h"
            5 #include        "fns.h"
            6 #include        "error.h"
            7 #include        "ip/ip.h"
            8 
            9 typedef struct DS DS;
           10 static Chan*        call(char*, char*, DS*);
           11 static void        _dial_string_parse(char*, DS*);
           12 
           13 enum
           14 {
           15         Maxstring=        128,
           16 };
           17 
           18 struct DS
           19 {
           20         char        buf[Maxstring];                        /* dist string */
           21         char        *netdir;
           22         char        *proto;
           23         char        *rem;
           24         char        *local;                                /* other args */
           25         char        *dir;
           26         Chan        **ctlp;
           27 };
           28 
           29 /*
           30  *  the dialstring is of the form '[/net/]proto!dest'
           31  */
           32 Chan*
           33 chandial(char *dest, char *local, char *dir, Chan **ctlp)
           34 {
           35         DS ds;
           36         char clone[Maxpath];
           37 
           38         ds.local = local;
           39         ds.dir = dir;
           40         ds.ctlp = ctlp;
           41 
           42         _dial_string_parse(dest, &ds);
           43         if(ds.netdir == 0)
           44                 ds.netdir = "/net";
           45 
           46         /* no connection server, don't translate */
           47         snprint(clone, sizeof(clone), "%s/%s/clone", ds.netdir, ds.proto);
           48         return call(clone, ds.rem, &ds);
           49 }
           50 
           51 static Chan*
           52 call(char *clone, char *dest, DS *ds)
           53 {
           54         int n;
           55         Chan *dchan, *cchan;
           56         char name[Maxpath], data[Maxpath], *p;
           57 
           58         cchan = namec(clone, Aopen, ORDWR, 0);
           59 
           60         /* get directory name */
           61         if(waserror()){
           62                 cclose(cchan);
           63                 nexterror();
           64         }
           65         n = devtab[cchan->type]->read(cchan, name, sizeof(name)-1, 0);
           66         name[n] = 0;
           67         for(p = name; *p == ' '; p++)
           68                 ;
           69         sprint(name, "%lud", strtoul(p, 0, 0));
           70         p = strrchr(clone, '/');
           71         *p = 0;
           72         if(ds->dir)
           73                 snprint(ds->dir, Maxpath, "%s/%s", clone, name);
           74         snprint(data, sizeof(data), "%s/%s/data", clone, name);
           75 
           76         /* connect */
           77         if(ds->local)
           78                 snprint(name, sizeof(name), "connect %s %s", dest, ds->local);
           79         else
           80                 snprint(name, sizeof(name), "connect %s", dest);
           81         devtab[cchan->type]->write(cchan, name, strlen(name), 0);
           82 
           83         /* open data connection */
           84         dchan = namec(data, Aopen, ORDWR, 0);
           85         if(ds->ctlp)
           86                 *ds->ctlp = cchan;
           87         else
           88                 cclose(cchan);
           89         poperror();
           90         return dchan;
           91 
           92 }
           93 
           94 /*
           95  *  parse a dial string
           96  */
           97 static void
           98 _dial_string_parse(char *str, DS *ds)
           99 {
          100         char *p, *p2;
          101 
          102         strncpy(ds->buf, str, Maxstring);
          103         ds->buf[Maxstring-1] = 0;
          104 
          105         p = strchr(ds->buf, '!');
          106         if(p == 0) {
          107                 ds->netdir = 0;
          108                 ds->proto = "net";
          109                 ds->rem = ds->buf;
          110         } else {
          111                 if(*ds->buf != '/' && *ds->buf != '#'){
          112                         ds->netdir = 0;
          113                         ds->proto = ds->buf;
          114                 } else {
          115                         for(p2 = p; *p2 != '/'; p2--)
          116                                 ;
          117                         *p2++ = 0;
          118                         ds->netdir = ds->buf;
          119                         ds->proto = p2;
          120                 }
          121                 *p = 0;
          122                 ds->rem = p + 1;
          123         }
          124 }