Updated FSF's address.
[gnupg.git] / jnlib / w32-afunix.c
1 /* w32-afunix.c
2  * Copyright (C) 2004 g10 Code GmbH
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21 #ifdef _WIN32
22 #include <stdio.h>
23 #include <windows.h>
24 #include <io.h>
25
26 #include "w32-afunix.h"
27
28 int
29 _w32_close (int fd)
30 {
31   int rc = closesocket (fd);
32   if (rc && WSAGetLastError () == WSAENOTSOCK)
33       rc = close (fd);
34   return rc;
35 }
36
37
38 int
39 _w32_sock_new (int domain, int type, int proto)
40 {
41   if (domain == AF_UNIX || domain == AF_LOCAL)
42     domain = AF_INET;
43   return socket (domain, type, proto);
44 }
45
46
47 int
48 _w32_sock_connect (int sockfd, struct sockaddr * addr, int addrlen)
49 {
50   struct sockaddr_in myaddr;
51   struct sockaddr_un * unaddr;
52   FILE * fp;
53   int port;
54   
55   unaddr = (struct sockaddr_un *)addr;
56   fp = fopen (unaddr->sun_path, "rb");
57   if (!fp)
58     return -1;
59   fscanf (fp, "%d", &port);
60   fclose (fp);
61
62   /* XXX: set errno in this case */
63   if (port < 0 || port > 65535)
64     return -1;
65   
66   myaddr.sin_family = AF_INET;
67   myaddr.sin_port = port; 
68   myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
69
70   /* we need this later. */
71   unaddr->sun_family = myaddr.sin_family;
72   unaddr->sun_port = myaddr.sin_port;
73   unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
74   
75   return connect (sockfd, (struct sockaddr *)&myaddr, sizeof myaddr);
76 }
77
78
79 int
80 _w32_sock_bind (int sockfd, struct sockaddr * addr, int addrlen)
81 {
82   if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
83     {
84       struct sockaddr_in myaddr;
85       struct sockaddr_un * unaddr;
86       FILE * fp;
87       int len = sizeof myaddr;
88       int rc;
89
90       myaddr.sin_port = 0;
91       myaddr.sin_family = AF_INET;
92       myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
93
94       rc = bind (sockfd, (struct sockaddr *)&myaddr, len);
95       if (rc)
96         return rc;
97       rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len);
98       if (rc)
99         return rc;
100       unaddr = (struct sockaddr_un *)addr;
101       fp = fopen (unaddr->sun_path, "wb");
102       if (!fp)
103         return -1;
104       fprintf (fp, "%d", myaddr.sin_port);
105       fclose (fp);
106
107       /* we need this later. */
108       unaddr->sun_family = myaddr.sin_family;
109       unaddr->sun_port = myaddr.sin_port;
110       unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
111       
112       return 0;
113     }
114   return bind (sockfd, addr, addrlen);
115 }
116
117 #endif /*_WIN32*/