1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
|
.TH DIAL 3
.SH NAME
dial, announce, listen, accept, reject, netmkaddr, dialparse \- make and break network connections
.SH SYNOPSIS
.B #include <u.h>
.br
.B #include <libc.h>
.PP
.B
int dial(char *addr, char *local, char *dir, int *cfdp)
.PP
.B
int announce(char *addr, char *dir)
.PP
.B
int listen(char *dir, char *newdir)
.PP
.B
int accept(int ctl, char *dir)
.PP
.B
int reject(int ctl, char *dir, char *cause)
.PP
.B
char* netmkaddr(char *addr, char *defnet, char *defservice)
.\" .PP
.\" .B
.\" void setnetmtpt(char *to, int tolen, char *from)
.\" .PP
.\" .B
.\" NetConnInfo* getnetconninfo(char *conndir, int fd)
.\" .PP
.\" .B
.\" void freenetconninfo(NetConnINfo*)
.PP
.B
int dialparse(char *addr, char **net, char **unix,
.br
.B
u32int *host, int *port)
.SH DESCRIPTION
For these routines,
.I addr
is a network address of the form
.IB network ! netaddr ! service\f1,
.IB network ! netaddr\f1,
or simply
.IR netaddr .
.I Network
is
.BR tcp ,
.BR udp ,
.BR unix ,
or the special token,
.BR net .
.B Net
is a free variable that stands for any network in common
between the source and the host
.IR netaddr .
.I Netaddr
can be a host name, a domain name, or a network address.
.\" or a meta-name of the form
.\" .BI $ attribute\f1,
.\" which
.\" is replaced by
.\" .I value
.\" from the value-attribute pair
.\" .IB attribute = value
.\" most closely associated with the source host in the
.\" network data base (see
.\" .IR ndb (6)).
.PP
On Plan 9, the
.I dir
argument is a path name to a
.I line directory
that has files for accessing the connection.
To keep the same function signatures,
the Unix port of these routines uses strings of the form
.BI /dev/fd/ n
instead of line directory paths.
These strings should be treated as opaque data and ignored.
.PP
.I Dial
makes a call to destination
.I addr
on a multiplexed network.
If the network in
.I addr
is
.BR net ,
.I dial
will try in succession all
networks in common between source and destination
until a call succeeds.
It returns a file descriptor open for reading and writing the
.B data
file in the line directory.
The
.B addr
file in the line directory contains the address called.
.\" If the network allows the local address to be set,
.\" as is the case with UDP and TCP port numbers, and
.\" .IR local
.\" is non-zero, the local address will be set to
.\" .IR local .
.IR Dial 's
.IR local ,
.IR dir ,
and
.I cfdp
arguments
are not supported and must be zero.
.PP
.I Announce
and
.I listen
are the complements of
.IR dial .
.I Announce
establishes a network
name to which calls can be made.
Like
.IR dial ,
.I announce
returns an open
.B ctl
file.
The
.I netaddr
used in announce may be a local address or an asterisk,
to indicate all local addresses, e.g.
.BR tcp!*!echo .
The
.I listen
routine takes as its first argument the
.I dir
of a previous
.IR announce .
When a call is received,
.I listen
returns an open
.B ctl
file for the line the call was received on.
It sets
.I newdir
to the path name of the new line directory.
.I Accept
accepts a call received by
.IR listen ,
while
.I reject
refuses the call because of
.IR cause .
.I Accept
returns a file descriptor for the data file opened
.BR ORDWR .
.PP
.I Netmkaddr
makes an address suitable for dialing or announcing.
It takes an address along with a default network and service to use
if they are not specified in the address.
It returns a pointer to static data holding the actual address to use.
.PP
.I Dialparse
parses a network address as described above
into a network name, a Unix domain socket address,
an IPv4 host address, and an IPv4 port number.
.\" .PP
.\" .I Getnetconninfo
.\" returns a structure containing information about a
.\" network connection. The structure is:
.\" .EX
.\" typedef struct NetConnInfo NetConnInfo;
.\" struct NetConnInfo
.\" {
.\" char *dir; /* connection directory */
.\" char *root; /* network root */
.\" char *spec; /* binding spec */
.\" char *lsys; /* local system */
.\" char *lserv; /* local service */
.\" char *rsys; /* remote system */
.\" char *rserv; /* remote service */
.\" };
.\" .EE
.\" .PP
.\" The information is obtained from the connection directory,
.\" .IR conndir .
.\" If
.\" .I conndir
.\" is nil, the directory is obtained by performing
.\" .IR fd2path (3)
.\" on
.\" .IR fd .
.\" .I Getnetconninfo
.\" returns either a completely specified structure, or
.\" nil if either the structure can't be allocated or the
.\" network directory can't be determined.
.\" The structure
.\" is freed using
.\" .IR freenetconninfo .
.\" .PP
.\" .I Setnetmtpt
.\" copies the name of the network mount point into
.\" the buffer
.\" .IR to ,
.\" whose length is
.\" .IR tolen .
.\" It exists to merge two pre-existing conventions for specifying
.\" the mount point.
.\" Commands that take a network mount point as a parameter
.\" (such as
.\" .BR dns ,
.\" .BR cs
.\" (see
.\" .IR ndb (8)),
.\" and
.\" .IR ipconfig (8))
.\" should now call
.\" .IR setnetmtpt .
.\" If
.\" .I from
.\" is
.\" .BR nil ,
.\" the mount point is set to the default,
.\" .BR /net .
.\" If
.\" .I from
.\" points to a string starting with a slash,
.\" the mount point is that path.
.\" Otherwise, the mount point is the string pointed to by
.\" .I from
.\" appended to the string
.\" .BR /net .
.\" The last form is obsolete and is should be avoided.
.\" It exists only to aid in conversion.
.SH EXAMPLES
Make a call and return an open file descriptor to
use for communications:
.IP
.EX
int callkremvax(void)
{
return dial("kremvax", 0, 0, 0);
}
.EE
.PP
Connect to a Unix socket served by
.IR acme (4):
.IP
.EX
int dialacme(void)
{
return dial("unix!/tmp/ns.ken.:0/acme", 0, 0, 0);
}
.EE
.PP
Announce as
.B kremvax
on TCP/IP and
loop forever receiving calls and echoing back
to the caller anything sent:
.IP
.EX
int
bekremvax(void)
{
int dfd, acfd, lcfd;
char adir[40], ldir[40];
int n;
char buf[256];
acfd = announce("tcp!*!7", adir);
if(acfd < 0)
return -1;
for(;;){
/* listen for a call */
lcfd = listen(adir, ldir);
if(lcfd < 0)
return -1;
/* fork a process to echo */
switch(fork()){
case -1:
perror("forking");
close(lcfd);
break;
case 0:
/* accept the call and open the data file */
dfd = accept(lcfd, ldir);
if(dfd < 0)
return -1;
/* echo until EOF */
while((n = read(dfd, buf, sizeof(buf))) > 0)
write(dfd, buf, n);
exits(0);
default:
close(lcfd);
break;
}
}
}
.EE
.SH SOURCE
.B \*9/src/lib9/dial.c
.br
.B \*9/src/lib9/announce.c
.br
.B \*9/src/lib9/_p9dialparse.c
.SH DIAGNOSTICS
.IR Dial ,
.IR announce ,
and
.I listen
return \-1 if they fail.
.SH BUGS
To avoid name conflicts with the underlying system,
.IR dial ,
.IR announce ,
.IR listen ,
.IR netmkaddr ,
and
.I reject
are preprocessor macros defined as
.IR p9dial ,
.IR p9announce ,
and so on;
see
.IR intro (3).
|