Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"u.h"
2
#include	"../port/lib.h"
3
#include	"mem.h"
4
#include	"dat.h"
5
#include	"fns.h"
6
#include	"../port/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
	snprint(name, sizeof 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
}