Implemented the chain model for X.509 validation.
[gnupg.git] / jnlib / w32-afunix.c
1 /* w32-afunix.c - AF_UNIX emulation for Windows.
2  * Copyright (C) 2004, 2006 g10 Code GmbH
3  *
4  * This file is part of JNLIB.
5  *
6  * JNLIB is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 3 of
9  * the License, or (at your option) any later version.
10  *
11  * JNLIB is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifdef _WIN32
21 #include <stdio.h>
22 #include <windows.h>
23 #include <fcntl.h>
24 #include <sys/stat.h>
25 #include <io.h>
26 #include <errno.h>
27
28 #include "w32-afunix.h"
29
30 #ifndef S_IRGRP
31 # define S_IRGRP 0
32 # define S_IWGRP 0
33 #endif
34
35
36 int
37 _w32_close (int fd)
38 {
39   int rc = closesocket (fd);
40   if (rc && WSAGetLastError () == WSAENOTSOCK)
41       rc = close (fd);
42   return rc;
43 }
44
45
46 int
47 _w32_sock_new (int domain, int type, int proto)
48 {
49   if (domain == AF_UNIX || domain == AF_LOCAL)
50     domain = AF_INET;
51   return socket (domain, type, proto);
52 }
53
54
55 int
56 _w32_sock_connect (int sockfd, struct sockaddr * addr, int addrlen)
57 {
58   struct sockaddr_in myaddr;
59   struct sockaddr_un * unaddr;
60   FILE * fp;
61   int port;
62   
63   unaddr = (struct sockaddr_un *)addr;
64   fp = fopen (unaddr->sun_path, "rb");
65   if (!fp)
66     return -1;
67   fscanf (fp, "%d", &port);
68   fclose (fp);
69
70   if (port < 0 || port > 65535)
71     {
72       errno = EINVAL;
73       return -1;
74     }
75   
76   myaddr.sin_family = AF_INET;
77   myaddr.sin_port = port; 
78   myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
79
80   /* we need this later. */
81   unaddr->sun_family = myaddr.sin_family;
82   unaddr->sun_port = myaddr.sin_port;
83   unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
84   
85   return connect (sockfd, (struct sockaddr *)&myaddr, sizeof myaddr);
86 }
87
88
89 int
90 _w32_sock_bind (int sockfd, struct sockaddr *addr, int addrlen)
91 {
92   if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
93     {
94       struct sockaddr_in myaddr;
95       struct sockaddr_un *unaddr;
96       int filefd;
97       FILE *fp;
98       int len = sizeof myaddr;
99       int rc;
100
101       unaddr = (struct sockaddr_un *)addr;
102
103       myaddr.sin_port = 0;
104       myaddr.sin_family = AF_INET;
105       myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
106
107       filefd = open (unaddr->sun_path, 
108                      (O_WRONLY|O_CREAT|O_EXCL|O_BINARY), 
109                      (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP));
110       if (filefd == -1)
111         {
112           if (errno == EEXIST)
113             errno = WSAEADDRINUSE;
114           return -1;
115         }
116       fp = fdopen (filefd, "wb");
117       if (!fp)
118         { 
119           int save_e = errno;
120           close (filefd);
121           errno = save_e;
122           return -1;
123         }
124
125       rc = bind (sockfd, (struct sockaddr *)&myaddr, len);
126       if (!rc)
127         rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len);
128       if (rc)
129         {
130           int save_e = errno;
131           fclose (fp);
132           remove (unaddr->sun_path);
133           errno = save_e;
134           return rc;
135         }
136       fprintf (fp, "%d", myaddr.sin_port);
137       fclose (fp);
138
139       /* The caller expects these values. */
140       unaddr->sun_family = myaddr.sin_family;
141       unaddr->sun_port = myaddr.sin_port;
142       unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
143       
144       return 0;
145     }
146   return bind (sockfd, addr, addrlen);
147 }
148
149 #endif /*_WIN32*/