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>
35 /* this should be at least 3 functions. parse an address into
36 * sockaddr. make a socket. Mount a given sockaddr. This needs
38 * oh, hell, let's just do it.
41 /* parse an address in plan 9 format into a sockaddr
42 * NOT a sockaddr_in yet if ever.
43 * if you want defaults, then put them in the string!
45 struct sockaddr
*parse9net(const char *address
, struct sockaddr
*psaddr
)
48 char *addr
, *name
, *p
, *s
;
49 struct sockaddr_in
*saddr
= (struct sockaddr_in
*)psaddr
;
50 struct hostent
*hostinfo
;
52 addr
= strdup(address
);
53 if (strncmp(addr
, "tcp!", 4) == 0)
59 p
= strrchr(name
, '!');
63 port
= strtoul(p
, &s
, 0);
65 sp_werror("invalid port format", EIO
);
70 hostinfo
= gethostbyname(name
);
72 sp_werror("cannot resolve name: %s", EIO
, name
);
78 saddr
->sin_family
= AF_INET
;
79 saddr
->sin_port
= htons(port
);
80 saddr
->sin_addr
= *(struct in_addr
*) hostinfo
->h_addr
;
82 return (struct sockaddr
*) saddr
;
89 spc_netmount(char *address
, Spuser
*user
, int dfltport
,
90 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
;
101 addr
= strdup(address
);
102 if (strncmp(addr
, "tcp!", 4) == 0)
108 p
= strrchr(name
, '!');
112 port
= strtol(p
, &s
, 10);
114 sp_werror("invalid port format", EIO
);
119 fd
= socket(PF_INET
, SOCK_STREAM
, 0);
125 hostinfo
= gethostbyname(name
);
127 sp_werror("cannot resolve name: %s", EIO
, name
);
131 saddr
.sin_family
= AF_INET
;
132 saddr
.sin_port
= htons(port
);
133 saddr
.sin_addr
= *(struct in_addr
*) hostinfo
->h_addr
;
135 if (connect(fd
, (struct sockaddr
*) &saddr
, sizeof(saddr
)) < 0) {
136 /* real computers have errstr */
137 static char error
[128];
138 /* too bad for f-ing gcc and friends */
139 a
[0] = saddr
.sin_addr
.s_addr
>> 24;
140 a
[1] = saddr
.sin_addr
.s_addr
>>16;
141 a
[2] = saddr
.sin_addr
.s_addr
>>8;
142 a
[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", a
[3], a
[2], a
[1], a
[0]);
152 // sp_werror("Host :%s:%s", errno, i, error);
153 sp_werror(error
, errno
);
159 fs
= spc_mount(fd
, NULL
, user
, auth
, aux
);
164 if (getsockname(fd
, (struct sockaddr
*) &saddr
, &n
) >= 0) {
165 a
[0] = saddr
.sin_addr
.s_addr
>> 24;
166 a
[1] = saddr
.sin_addr
.s_addr
>> 16;
167 a
[2] = saddr
.sin_addr
.s_addr
>> 8;
168 a
[3] = saddr
.sin_addr
.s_addr
;
169 snprintf(buf
, sizeof(buf
), "%d.%d.%d.%d", a
[3], a
[2], a
[1], a
[0]);
170 fs
->laddr
= strdup(buf
);
174 if (getpeername(fd
, (struct sockaddr
*) &saddr
, &n
) >= 0) {
175 a
[0] = saddr
.sin_addr
.s_addr
>> 24;
176 a
[1] = saddr
.sin_addr
.s_addr
>> 16;
177 a
[2] = saddr
.sin_addr
.s_addr
>> 8;
178 a
[3] = saddr
.sin_addr
.s_addr
;
179 snprintf(buf
, sizeof(buf
), "%d.%d.%d.%d", a
[3], a
[2], a
[1], a
[0]);
180 fs
->raddr
= strdup(buf
);
184 fprintf(stderr
, "connection %p to %s opened\n", fs
, fs
->raddr
);