vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | 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 }