Blob


1 #include <u.h>
2 #include <libc.h>
4 #undef accept
5 #undef announce
6 #undef dial
7 #undef setnetmtpt
8 #undef hangup
9 #undef listen
10 #undef netmkaddr
11 #undef reject
13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 #include <netinet/tcp.h>
16 #include <sys/un.h>
17 #include <netdb.h>
19 #undef unix
21 int
22 p9dial(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;
33 if(dummy1 || dummy2 || dummy3){
34 werrstr("cannot handle extra arguments in dial");
35 return -1;
36 }
38 buf = strdup(addr);
39 if(buf == nil)
40 return -1;
42 if(p9dialparse(buf, &net, &unix, &host, &port) < 0){
43 free(buf);
44 return -1;
45 }
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);
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 }
70 if(proto == SOCK_STREAM){
71 int one = 1;
72 setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one);
73 }
74 return s;
76 Unix:
77 memset(&su, 0, sizeof su);
78 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 }