]> git.ipfire.org Git - people/ms/rstp.git/blame - ctl_socket_client.c
fixes for 4.3.3 GCC warnings/errors
[people/ms/rstp.git] / ctl_socket_client.c
CommitLineData
ad02a0eb
SH
1/*****************************************************************************
2 Copyright (c) 2006 EMC Corporation.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2 of the License, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Authors: Srinivas Aji <Aji_Srinivas@emc.com>
22
23******************************************************************************/
24
25#include "ctl_socket.h"
26#include <sys/stat.h>
27#include <sys/types.h>
28#include <sys/socket.h>
29#include <sys/un.h>
30#include <unistd.h>
31#include <sys/poll.h>
32#include <stdio.h>
33#include <stdlib.h>
34
b600a2c3 35#define NO_DAEMON
ad02a0eb
SH
36#include "log.h"
37
38static int fd = -1;
39
40int ctl_client_init(void)
41{
11904a35
SH
42 struct sockaddr_un sa_svr;
43 int s;
44 TST(strlen(RSTP_SERVER_SOCK_NAME) < sizeof(sa_svr.sun_path), -1);
45
46 s = socket(PF_UNIX, SOCK_DGRAM, 0);
47 if (s < 0) {
48 ERROR("Couldn't open unix socket: %m");
49 return -1;
50 }
51
52 set_socket_address(&sa_svr, RSTP_SERVER_SOCK_NAME);
53
54 struct sockaddr_un sa;
55 char tmpname[64];
56 sprintf(tmpname, "RSTPCTL_%d", getpid());
57 set_socket_address(&sa, tmpname);
58 /* We need this bind. The autobind on connect isn't working properly.
59 The server doesn't get a proper sockaddr in recvmsg if we don't do this.
60 */
61 if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) != 0) {
62 ERROR("Couldn't bind socket: %m");
63 close(s);
64 return -1;
65 }
66
67 if (connect(s, (struct sockaddr *)&sa_svr, sizeof(sa_svr)) != 0) {
68 ERROR("Couldn't connect to server");
69 close(s);
70 return -1;
71 }
72 fd = s;
73
74 return 0;
ad02a0eb
SH
75}
76
77void ctl_client_cleanup(void)
78{
11904a35
SH
79 if (fd >= 0) {
80 close(fd);
81 fd = -1;
82 }
ad02a0eb
SH
83}
84
b600a2c3
SA
85int send_ctl_message(int cmd, void *inbuf, int lin, void *outbuf, int lout,
86 LogString *log, int *res)
ad02a0eb 87{
11904a35
SH
88 struct ctl_msg_hdr mhdr;
89 struct msghdr msg;
b600a2c3 90 struct iovec iov[3];
11904a35
SH
91 int l;
92
93 msg.msg_name = NULL;
94 msg.msg_namelen = 0;
95 msg.msg_iov = iov;
b600a2c3 96 msg.msg_iovlen = 3;
11904a35
SH
97 msg.msg_control = NULL;
98 msg.msg_controllen = 0;
99
100 mhdr.cmd = cmd;
101 mhdr.lin = lin;
b600a2c3
SA
102 mhdr.lout = lout;
103 mhdr.llog = sizeof(log->buf) - 1;
11904a35
SH
104 iov[0].iov_base = &mhdr;
105 iov[0].iov_len = sizeof(mhdr);
106 iov[1].iov_base = (void *)inbuf;
107 iov[1].iov_len = lin;
b600a2c3
SA
108 iov[2].iov_base = log->buf;
109 iov[2].iov_len = 0;
11904a35
SH
110
111 l = sendmsg(fd, &msg, 0);
112 if (l < 0) {
113 ERROR("Error sending message to server: %m");
114 return -1;
115 }
116 if (l != sizeof(mhdr) + lin) {
117 ERROR("Error sending message to server: Partial write");
118 return -1;
119 }
120
121 iov[1].iov_base = outbuf;
b600a2c3
SA
122 iov[1].iov_len = lout;
123
124 iov[2].iov_base = log->buf;
125 iov[2].iov_len = sizeof(log->buf);
11904a35
SH
126
127 {
128 struct pollfd pfd;
129 int timeout = 5000; /* 5 s */
130 int r;
131
132 pfd.fd = fd;
133 pfd.events = POLLIN;
134 do {
135 r = poll(&pfd, 1, timeout);
136 if (r == 0) {
137 ERROR
138 ("Error getting message from server: Timeout");
139 return -1;
140 }
141 if (r < 0) {
142 ERROR
143 ("Error getting message from server: poll error: %m");
144 return -1;
145 }
146 } while ((pfd.
147 revents & (POLLERR | POLLHUP | POLLNVAL | POLLIN)) ==
148 0);
149
150 l = recvmsg(fd, &msg, 0);
151 if (l < 0) {
152 ERROR("Error getting message from server: %m");
153 return -1;
154 }
b600a2c3
SA
155 if (l < sizeof(mhdr)
156 || l != sizeof(mhdr) + mhdr.lout + mhdr.llog
11904a35
SH
157 || mhdr.cmd != cmd) {
158 ERROR("Error getting message from server: Bad format");
159 return -1;
160 }
b600a2c3
SA
161 if (mhdr.lout != lout) {
162 ERROR("Error, unexpected result length %d, "
163 "expected %d\n", mhdr.lout, lout);
164 return -1;
165 }
166 if (mhdr.llog >= sizeof(log->buf)) {
167 ERROR("Invalid log message length %d", mhdr.llog);
168 return -1;
169 }
11904a35 170 }
11904a35
SH
171 if (res)
172 *res = mhdr.res;
b600a2c3 173 log->buf[mhdr.llog] = 0;
11904a35 174 return 0;
ad02a0eb 175}