Clean up RPM spec for newer distributions
[clumanager.git] / librhcm / apitcp.c
blob1bb57a5b1fff8f69a2b5d08d4f695c2f4de890a5
1 /*
2 Copyright 2003 Red Hat, Inc.
4 The Red Hat Cluster Manager API Library is free software; you can
5 redistribute it and/or modify it under the terms of the GNU Lesser
6 General Public License as published by the Free Software Foundation;
7 either version 2.1 of the License, or (at your option) any later
8 version.
10 The Red Hat Cluster Manager API Library is distributed in the hope
11 that it will be useful, but WITHOUT ANY WARRANTY; without even the
12 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 PURPOSE. See the GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 USA.
20 /** @file
21 * Thin TCP Socket Functions for Cluster Manager API Library
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <arpa/inet.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <sys/select.h>
31 #include <errno.h>
32 #include <apitcp.h>
33 #include <platform.h>
34 #include <auth_md5.h>
35 #include <xmlwrap.h>
37 int hex2bin(char *, int, char *, int);
39 /**
40 * Connect to localhost on the specified port.
42 * @param port Port to which we intend to connect.
43 * @return fd, or -1 on failure. See socket(2) and connect(2) for
44 * possible errors.
46 int
47 tcp_localconnect(int port)
49 int fd, j;
50 struct sockaddr_in addr;
51 char *key;
52 char keybuf[256];
54 fd = socket(PF_INET, SOCK_STREAM, 0);
55 if (fd < 0)
56 return -1;
58 if (!CFG_Loaded() && (CFG_ReadFile(CLU_CONFIG_FILE) != CFG_OK))
59 auth_md5_init(NULL, 0);
61 if (CFG_Loaded() &&
62 CFG_Get("cluster%key", NULL, &key) == CFG_OK) {
63 j = hex2bin(key, strlen(key), keybuf, sizeof(keybuf));
64 if (j == -1)
65 auth_md5_init(NULL, 0);
66 else
67 auth_md5_init(keybuf, j);
68 } else
69 auth_md5_init(NULL, 0);
71 #if 0
72 j = 1;
73 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &j, sizeof(j));
74 #endif
76 memset(&addr,0,sizeof(addr));
77 addr.sin_family = PF_INET;
78 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
79 if (port == 0 || port > 65535)
80 port = 34001;
81 addr.sin_port = htons(port);
83 j = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
84 if ((j == 0) && (auth_md5(fd) == 0))
85 return fd;
87 j = errno;
88 close(fd);
89 errno = j;
90 return -1;
94 /**
95 * Send a message to a socket.
97 * @param fd
98 * @param msg
99 * @param len
100 * @return Number of bytes send, or -1 on failure.
102 ssize_t
103 tcp_send(int fd, void *msg, uint32_t len)
105 ssize_t ret;
106 uint32_t truesize;
107 void *truemsg;
108 fd_set set;
109 struct timeval tv;
111 if (fd == -1)
112 return -1;
114 if (len == 0)
115 return 0;
118 * Send the # of bytes we intend to send as first 4 bytes.
120 truesize = len + sizeof(uint32_t);
121 truemsg = malloc(truesize);
122 if (!truemsg)
123 return -1;
125 memset(truemsg, 0, truesize);
126 ((uint32_t *)(truemsg))[0] = len;
127 swab32(((uint32_t *)(truemsg))[0]);
128 memcpy(truemsg + sizeof(truesize), msg, len);
130 FD_ZERO(&set);
131 FD_SET(fd, &set);
132 tv.tv_sec = TCP_TIMEOUT;
133 tv.tv_usec = 0;
135 ret = (ssize_t)select(fd+1, NULL, &set, NULL, &tv);
136 if (ret <= 0) {
137 if (ret == 0)
138 errno = ETIMEDOUT;
139 free(truemsg);
140 return -1;
143 ret = write(fd, truemsg, truesize);
144 free(truemsg);
146 if (ret == -1)
147 return -1;
149 if (ret < truesize) {
150 errno = EAGAIN;
151 ret = -1;
154 return len;
159 * Send a message to a socket.
161 * @param fd
162 * @param msg
163 * @param len
164 * @return Number of bytes send, or -1 on failure.
166 ssize_t
167 tcp_receive(int fd, void *msg, uint32_t len)
169 ssize_t ret;
170 uint32_t length, truesize;
171 struct timeval tv;
172 fd_set set;
174 if (fd < 0)
175 return -1;
177 FD_ZERO(&set);
178 FD_SET(fd, &set);
179 tv.tv_sec = TCP_TIMEOUT;
180 tv.tv_usec = 0;
182 ret = (ssize_t)select(fd+1, NULL, &set, NULL, &tv);
183 if (ret <= 0) {
184 if (ret == 0)
185 errno = ETIMEDOUT;
186 return -1;
189 ret = read(fd, (void *)&length, sizeof(length));
190 if (ret != sizeof(length))
191 return -1;
193 /* Fix byte order */
194 swab32(length);
195 if (length > TCP_MAXLEN)
196 return -1;
198 truesize = (length < len) ? length : len;
199 ret = read(fd, msg, truesize);
200 if (ret == -1)
201 return -1;
203 if (ret < truesize) {
204 errno = EAGAIN;
205 ret = -1;
208 return truesize;