blob: 732cbb6916b896549eb43bfc7721f0672f722152 [file] [log] [blame]
rscfd04aac2003-11-23 18:12:54 +00001#include <u.h>
2#include <libc.h>
3
4#undef accept
5#undef announce
6#undef dial
7#undef setnetmtpt
8#undef hangup
9#undef listen
10#undef netmkaddr
11#undef reject
12
13#include <sys/socket.h>
14#include <netinet/in.h>
rscd51419b2004-02-09 19:33:05 +000015#include <netinet/tcp.h>
rscfd04aac2003-11-23 18:12:54 +000016#include <sys/un.h>
17#include <netdb.h>
18
rscfd04aac2003-11-23 18:12:54 +000019#undef unix
20
21int
22p9dial(char *addr, char *dummy1, char *dummy2, int *dummy3)
23{
24 char *buf;
25 char *net, *unix;
26 u32int host;
27 int port;
28 int proto;
29 struct sockaddr_in sa;
30 struct sockaddr_un su;
31 int s;
32
33 if(dummy1 || dummy2 || dummy3){
34 werrstr("cannot handle extra arguments in dial");
35 return -1;
36 }
37
38 buf = strdup(addr);
39 if(buf == nil)
40 return -1;
41
rsce42882d2004-06-16 16:45:09 +000042 if(p9dialparse(buf, &net, &unix, &host, &port) < 0){
rscfd04aac2003-11-23 18:12:54 +000043 free(buf);
44 return -1;
45 }
46
47 if(strcmp(net, "tcp") == 0)
48 proto = SOCK_STREAM;
49 else if(strcmp(net, "udp") == 0)
50 proto = SOCK_DGRAM;
51 else if(strcmp(net, "unix") == 0)
52 goto Unix;
53 else{
54 werrstr("can only handle tcp, udp, and unix: not %s", net);
55 free(buf);
56 return -1;
57 }
58 free(buf);
59
60 memset(&sa, 0, sizeof sa);
61 memmove(&sa.sin_addr, &host, 4);
62 sa.sin_family = AF_INET;
63 sa.sin_port = htons(port);
64 if((s = socket(AF_INET, proto, 0)) < 0)
65 return -1;
66 if(connect(s, (struct sockaddr*)&sa, sizeof sa) < 0){
67 close(s);
68 return -1;
69 }
rscd51419b2004-02-09 19:33:05 +000070 if(proto == SOCK_STREAM){
71 int one = 1;
72 setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one);
73 }
rscfd04aac2003-11-23 18:12:54 +000074 return s;
75
76Unix:
77 memset(&su, 0, sizeof su);
rscfd04aac2003-11-23 18:12:54 +000078 su.sun_family = AF_UNIX;
79 if(strlen(unix)+1 > sizeof su.sun_path){
80 werrstr("unix socket name too long");
81 free(buf);
82 return -1;
83 }
84 strcpy(su.sun_path, unix);
85 free(buf);
86 if((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
87 return -1;
88 if(connect(s, (struct sockaddr*)&su, sizeof su) < 0){
89 close(s);
90 return -1;
91 }
92 return s;
93}
94