2 * Copyright (C) 2006 by Latchesar Ionkov <lucho@ionkov.net>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * LATCHESAR IONKOV AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
28 #include <sys/socket.h>
29 #include <netinet/in.h>
31 #include <arpa/inet.h>
36 /* this should be at least 3 functions. parse an address into
37 * sockaddr. make a socket. Mount a given sockaddr. This needs
39 * oh, hell, let's just do it.
42 /* parse an address in plan 9 format into a sockaddr
43 * NOT a sockaddr_in yet if ever.
44 * if you want defaults, then put them in the string!
46 struct sockaddr
*parse9net(const char *address
, struct sockaddr
*psaddr
)
49 char *addr
, *name
, *p
, *s
;
50 struct sockaddr_in
*saddr
= (struct sockaddr_in
*)psaddr
;
51 struct hostent
*hostinfo
;
53 addr
= strdup(address
);
54 if (strncmp(addr
, "tcp!", 4) == 0)
60 p
= strrchr(name
, '!');
64 port
= strtoul(p
, &s
, 0);
66 sp_werror("invalid port format", EIO
);
71 hostinfo
= gethostbyname(name
);
73 sp_werror("cannot resolve name: %s", EIO
, name
);
79 saddr
->sin_family
= AF_INET
;
80 saddr
->sin_port
= htons(port
);
81 saddr
->sin_addr
= *(struct in_addr
*) hostinfo
->h_addr
;
83 return (struct sockaddr
*) saddr
;
90 spc_netmount(char *address
, Spuser
*user
, int dfltport
,
91 int (*auth
)(Spcfid
*afid
, Spuser
*user
, void *aux
), void *aux
)
94 char *addr
, *name
, *p
, *s
;
95 struct sockaddr_in saddr
;
96 struct hostent
*hostinfo
;
100 addr
= strdup(address
);
101 if (strncmp(addr
, "tcp!", 4) == 0)
107 p
= strrchr(name
, '!');
111 port
= strtol(p
, &s
, 10);
113 sp_werror("invalid port format", EIO
);
118 fd
= socket(PF_INET
, SOCK_STREAM
, 0);
124 hostinfo
= gethostbyname(name
);
126 sp_werror("cannot resolve name: %s", EIO
, name
);
130 saddr
.sin_family
= AF_INET
;
131 saddr
.sin_port
= htons(port
);
132 saddr
.sin_addr
= *(struct in_addr
*) hostinfo
->h_addr
;
134 if (connect(fd
, (struct sockaddr
*) &saddr
, sizeof(saddr
)) < 0) {
135 /* real computers have errstr */
136 static char error
[128];
137 /* too bad for f-ing gcc and friends */
138 unsigned char octet
[4];
139 octet
[0] = saddr
.sin_addr
.s_addr
>> 24;
140 octet
[1] = saddr
.sin_addr
.s_addr
>>16;
141 octet
[2] = saddr
.sin_addr
.s_addr
>>8;
142 octet
[3] = saddr
.sin_addr
.s_addr
;
143 /* yeah, they broke this too
144 char *i = inet_ntoa(saddr.sin_addr);
147 memset(error
, 0, sizeof(error
));
148 //strerror_r(errno, error, sizeof(error));
149 strcpy(error
, strerror(errno
));
150 error
[strlen(error
)] = ':';
151 sprintf(&error
[strlen(error
)], "%d.%d.%d.%d", octet
[3], octet
[2], octet
[1], octet
[0]);
152 // sp_werror("Host :%s:%s", errno, i, error);
153 sp_werror(error
, errno
);
158 fs
= spc_mount(fd
, NULL
, user
, auth
, aux
);
160 snprintf(buf
, sizeof(buf
), "%s", inet_ntoa(saddr
.sin_addr
));
161 fs
->raddr
= strdup(buf
);
164 if (getsockname(fd
, (struct sockaddr
*) &saddr
, (socklen_t
*) &n
) >= 0) {
165 snprintf(buf
, sizeof(buf
), "%s", inet_ntoa(saddr
.sin_addr
));
166 fs
->laddr
= strdup(buf
);
170 fprintf(stderr
, "connection %p to %s opened\n", fs
, fs
->raddr
);