assuan/
[gpgme.git] / assuan / assuan-socket.c
1 /* assuan-socket.c
2  * Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3  *
4  * This file is part of Assuan.
5  *
6  * Assuan 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 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Assuan 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, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA. 
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #ifdef HAVE_W32_SYSTEM
25 #include <windows.h>
26 #include <io.h>
27 #else
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #endif
31 #include "assuan-defs.h"
32
33 /* Hacks for Slowaris.  */
34 #ifndef PF_LOCAL
35 # ifdef PF_UNIX
36 #  define PF_LOCAL PF_UNIX
37 # else
38 #  define PF_LOCAL AF_UNIX
39 # endif
40 #endif
41 #ifndef AF_LOCAL
42 # define AF_LOCAL AF_UNIX
43 #endif
44
45 int
46 _assuan_close (int fd)
47 {
48 #ifndef HAVE_W32_SYSTEM
49   return close (fd);
50 #else
51   int rc = closesocket (fd);
52   if (rc && WSAGetLastError () == WSAENOTSOCK)
53       rc = close (fd);
54   return rc;
55 #endif
56 }
57
58
59 int
60 _assuan_sock_new (int domain, int type, int proto)
61 {
62 #ifndef HAVE_W32_SYSTEM
63   return socket (domain, type, proto);
64 #else
65   if (domain == AF_UNIX || domain == AF_LOCAL)
66     domain = AF_INET;
67   return socket (domain, type, proto);
68 #endif
69 }
70
71
72 int
73 _assuan_sock_connect (int sockfd, struct sockaddr * addr, int addrlen)
74 {
75 #ifndef HAVE_W32_SYSTEM
76   return connect (sockfd, addr, addrlen);
77 #else
78   struct sockaddr_in myaddr;
79   struct sockaddr_un * unaddr;
80   FILE * fp;
81   int port = 0;
82   
83   unaddr = (struct sockaddr_un *)addr;
84   fp = fopen (unaddr->sun_path, "rb");
85   if (!fp)
86       return -1;
87   fscanf (fp, "%d", &port);
88   fclose (fp);
89   /* XXX: set errno in this case */
90   if (port < 0 || port > 65535)
91       return -1;
92   
93   myaddr.sin_family = AF_INET;
94   myaddr.sin_port = port; 
95   myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
96
97   /* we need this later. */
98   unaddr->sun_family = myaddr.sin_family;
99   unaddr->sun_port = myaddr.sin_port;
100   unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
101   
102   return connect (sockfd, (struct sockaddr *)&myaddr, sizeof myaddr);
103 #endif
104 }
105
106
107 int
108 _assuan_sock_bind (int sockfd, struct sockaddr * addr, int addrlen)
109 {
110 #ifndef HAVE_W32_SYSTEM
111   return bind (sockfd, addr, addrlen);
112 #else
113   if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
114     {
115       struct sockaddr_in myaddr;
116       struct sockaddr_un * unaddr;
117       FILE * fp;
118       int len = sizeof myaddr;
119       int rc;
120
121       myaddr.sin_port = 0;
122       myaddr.sin_family = AF_INET;
123       myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
124
125       rc = bind (sockfd, (struct sockaddr *)&myaddr, len);
126       if (rc)
127         return rc;
128       rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len);
129       if (rc)
130         return rc;
131       unaddr = (struct sockaddr_un *)addr;
132       fp = fopen (unaddr->sun_path, "wb");
133       if (!fp)
134         return -1;
135       fprintf (fp, "%d", myaddr.sin_port);
136       fclose (fp);
137
138       /* we need this later. */
139       unaddr->sun_family = myaddr.sin_family;
140       unaddr->sun_port = myaddr.sin_port;
141       unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
142       
143       return 0;
144     }
145   return bind (sockfd, addr, addrlen);
146 #endif
147 }
148