1 fd04aace 2003-11-23 devnull #include <u.h>
2 fd04aace 2003-11-23 devnull #define NOPLAN9DEFINES
3 fd04aace 2003-11-23 devnull #include <libc.h>
5 fd04aace 2003-11-23 devnull #include <sys/socket.h>
6 fd04aace 2003-11-23 devnull #include <netinet/in.h>
7 fd04aace 2003-11-23 devnull #include <sys/un.h>
9 fd04aace 2003-11-23 devnull extern int _p9dialparse(char*, char**, char**, u32int*, int*);
11 fd04aace 2003-11-23 devnull static int
12 fd04aace 2003-11-23 devnull getfd(char *dir)
16 fd04aace 2003-11-23 devnull if(strncmp(dir, "/dev/fd/", 8) != 0)
17 fd04aace 2003-11-23 devnull return -1;
18 fd04aace 2003-11-23 devnull fd = strtol(dir+8, &dir, 0);
19 fd04aace 2003-11-23 devnull if(*dir != 0)
20 fd04aace 2003-11-23 devnull return -1;
21 fd04aace 2003-11-23 devnull return fd;
24 fd04aace 2003-11-23 devnull static void
25 fd04aace 2003-11-23 devnull putfd(char *dir, int fd)
27 fd04aace 2003-11-23 devnull snprint(dir, NETPATHLEN, "/dev/fd/%d", fd);
30 fd04aace 2003-11-23 devnull #undef unix
33 fd04aace 2003-11-23 devnull p9announce(char *addr, char *dir)
35 fd04aace 2003-11-23 devnull int proto;
36 fd04aace 2003-11-23 devnull char *buf, *unix;
37 fd04aace 2003-11-23 devnull char *net;
38 fd04aace 2003-11-23 devnull u32int host;
39 fd04aace 2003-11-23 devnull int port, s;
40 fd04aace 2003-11-23 devnull int n, sn;
41 fd04aace 2003-11-23 devnull struct sockaddr_in sa;
42 fd04aace 2003-11-23 devnull struct sockaddr_un sun;
44 fd04aace 2003-11-23 devnull buf = strdup(addr);
45 fd04aace 2003-11-23 devnull if(buf == nil)
46 fd04aace 2003-11-23 devnull return -1;
48 fd04aace 2003-11-23 devnull if(_p9dialparse(buf, &net, &unix, &host, &port) < 0){
49 fd04aace 2003-11-23 devnull free(buf);
50 fd04aace 2003-11-23 devnull return -1;
52 fd04aace 2003-11-23 devnull if(strcmp(net, "tcp") == 0)
53 fd04aace 2003-11-23 devnull proto = SOCK_STREAM;
54 fd04aace 2003-11-23 devnull else if(strcmp(net, "udp") == 0)
55 fd04aace 2003-11-23 devnull proto = SOCK_DGRAM;
56 fd04aace 2003-11-23 devnull else if(strcmp(net, "unix") == 0)
57 fd04aace 2003-11-23 devnull goto Unix;
59 fd04aace 2003-11-23 devnull werrstr("can only handle tcp, udp, and unix: not %s", net);
60 fd04aace 2003-11-23 devnull free(buf);
61 fd04aace 2003-11-23 devnull return -1;
63 fd04aace 2003-11-23 devnull free(buf);
65 fd04aace 2003-11-23 devnull memset(&sa, 0, sizeof sa);
66 fd04aace 2003-11-23 devnull memmove(&sa.sin_addr, &host, 4);
67 fd04aace 2003-11-23 devnull sa.sin_family = AF_INET;
68 fd04aace 2003-11-23 devnull sa.sin_port = htons(port);
69 fd04aace 2003-11-23 devnull if((s = socket(AF_INET, proto, 0)) < 0)
70 fd04aace 2003-11-23 devnull return -1;
71 fd04aace 2003-11-23 devnull sn = sizeof n;
72 fd04aace 2003-11-23 devnull if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&n, &sn) >= 0
73 fd04aace 2003-11-23 devnull && n == SOCK_STREAM){
75 fd04aace 2003-11-23 devnull setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n);
77 fd04aace 2003-11-23 devnull if(bind(s, (struct sockaddr*)&sa, sizeof sa) < 0){
78 fd04aace 2003-11-23 devnull close(s);
79 fd04aace 2003-11-23 devnull return -1;
81 fd04aace 2003-11-23 devnull if(proto == SOCK_STREAM){
82 fd04aace 2003-11-23 devnull listen(s, 8);
83 fd04aace 2003-11-23 devnull putfd(dir, s);
84 fd04aace 2003-11-23 devnull print("announce dir: %s\n", dir);
86 fd04aace 2003-11-23 devnull return s;
89 fd04aace 2003-11-23 devnull memset(&sun, 0, sizeof sun);
90 fd04aace 2003-11-23 devnull sun.sun_family = AF_UNIX;
91 fd04aace 2003-11-23 devnull sun.sun_len = sizeof sun;
92 fd04aace 2003-11-23 devnull strcpy(sun.sun_path, unix);
93 fd04aace 2003-11-23 devnull if((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
94 fd04aace 2003-11-23 devnull return -1;
95 fd04aace 2003-11-23 devnull sn = sizeof sun;
96 fd04aace 2003-11-23 devnull if(bind(s, (struct sockaddr*)&sun, sizeof sun) < 0){
97 fd04aace 2003-11-23 devnull close(s);
98 fd04aace 2003-11-23 devnull return -1;
100 fd04aace 2003-11-23 devnull listen(s, 8);
101 fd04aace 2003-11-23 devnull putfd(dir, s);
102 fd04aace 2003-11-23 devnull return s;
106 fd04aace 2003-11-23 devnull p9listen(char *dir, char *newdir)
110 fd04aace 2003-11-23 devnull if((fd = getfd(dir)) < 0){
111 fd04aace 2003-11-23 devnull werrstr("bad 'directory' in listen: %s", dir);
112 fd04aace 2003-11-23 devnull return -1;
115 fd04aace 2003-11-23 devnull print("accept %d", fd);
116 fd04aace 2003-11-23 devnull if((fd = accept(fd, nil, nil)) < 0)
117 fd04aace 2003-11-23 devnull return -1;
118 fd04aace 2003-11-23 devnull print(" -> %d\n", fd);
120 fd04aace 2003-11-23 devnull putfd(newdir, fd);
121 fd04aace 2003-11-23 devnull print("listen dir: %s\n", newdir);
122 fd04aace 2003-11-23 devnull return fd;
126 fd04aace 2003-11-23 devnull p9accept(int cfd, char *dir)
130 fd04aace 2003-11-23 devnull if((fd = getfd(dir)) < 0){
131 fd04aace 2003-11-23 devnull werrstr("bad 'directory' in accept");
132 fd04aace 2003-11-23 devnull return -1;
134 fd04aace 2003-11-23 devnull /* need to dup because the listen fd will be closed */
135 fd04aace 2003-11-23 devnull return dup(fd);