]>
Commit | Line | Data |
---|---|---|
7126d8c2 AK |
1 | /* |
2 | * Copyright (C) 2011-2012 Red Hat, Inc. | |
3 | * | |
4 | * This file is part of LVM2. | |
5 | * | |
6 | * This copyrighted material is made available to anyone wishing to use, | |
7 | * modify, copy, or redistribute it subject to the terms and conditions | |
8 | * of the GNU Lesser General Public License v.2.1. | |
9 | * | |
10 | * You should have received a copy of the GNU Lesser General Public License | |
11 | * along with this program; if not, write to the Free Software Foundation, | |
12 | * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
13 | */ | |
14 | ||
92658f56 | 15 | #include "daemon-shared.h" |
7126d8c2 AK |
16 | #include "daemon-client.h" |
17 | ||
92658f56 PR |
18 | #include <sys/un.h> |
19 | #include <sys/socket.h> | |
20 | #include <string.h> | |
21 | #include <stdio.h> | |
6e4e3082 | 22 | #include <unistd.h> |
92658f56 | 23 | #include <assert.h> |
30896326 | 24 | #include <errno.h> // ENOMEM |
92658f56 PR |
25 | |
26 | daemon_handle daemon_open(daemon_info i) { | |
98b4241b | 27 | daemon_handle h = { .protocol_version = 0, .error = 0 }; |
dc5ba5c3 | 28 | daemon_reply r = { .cft = NULL }; |
92658f56 | 29 | struct sockaddr_un sockaddr; |
6d404585 | 30 | |
98b4241b | 31 | if ((h.socket_fd = socket(PF_UNIX, SOCK_STREAM /* | SOCK_NONBLOCK */, 0)) < 0) |
92658f56 | 32 | goto error; |
98b4241b | 33 | |
92658f56 | 34 | memset(&sockaddr, 0, sizeof(sockaddr)); |
92658f56 PR |
35 | strcpy(sockaddr.sun_path, i.socket); |
36 | sockaddr.sun_family = AF_UNIX; | |
98b4241b | 37 | if (connect(h.socket_fd,(struct sockaddr *) &sockaddr, sizeof(sockaddr))) |
92658f56 | 38 | goto error; |
3f694b12 | 39 | |
dc5ba5c3 | 40 | r = daemon_send_simple(h, "hello", NULL); |
3f694b12 PR |
41 | if (r.error || strcmp(daemon_reply_str(r, "response", "unknown"), "OK")) |
42 | goto error; | |
43 | ||
44 | h.protocol = daemon_reply_str(r, "protocol", NULL); | |
45 | if (h.protocol) | |
46 | h.protocol = dm_strdup(h.protocol); /* keep around */ | |
47 | h.protocol_version = daemon_reply_int(r, "version", 0); | |
48 | ||
49 | if (i.protocol && (!h.protocol || strcmp(h.protocol, i.protocol))) | |
50 | goto error; | |
51 | if (i.protocol_version && h.protocol_version != i.protocol_version) | |
52 | goto error; | |
53 | ||
54 | daemon_reply_destroy(r); | |
92658f56 | 55 | return h; |
98b4241b | 56 | |
92658f56 | 57 | error: |
98b4241b | 58 | h.error = errno; |
92658f56 PR |
59 | if (h.socket_fd >= 0) |
60 | close(h.socket_fd); | |
3f694b12 PR |
61 | if (r.cft) |
62 | daemon_reply_destroy(r); | |
92658f56 PR |
63 | h.socket_fd = -1; |
64 | return h; | |
65 | } | |
66 | ||
67 | daemon_reply daemon_send(daemon_handle h, daemon_request rq) | |
68 | { | |
351aefc8 | 69 | daemon_reply reply = { .cft = NULL, .error = 0 }; |
92658f56 PR |
70 | assert(h.socket_fd >= 0); |
71 | ||
72 | if (!rq.buffer) { | |
73 | /* TODO: build the buffer from rq.cft */ | |
74 | } | |
75 | ||
76 | assert(rq.buffer); | |
98b4241b PR |
77 | if (!write_buffer(h.socket_fd, rq.buffer, strlen(rq.buffer))) |
78 | reply.error = errno; | |
79 | ||
92658f56 | 80 | if (read_buffer(h.socket_fd, &reply.buffer)) { |
c033ea01 | 81 | reply.cft = dm_config_from_string(reply.buffer); |
92658f56 | 82 | } else |
98b4241b | 83 | reply.error = errno; |
92658f56 PR |
84 | |
85 | return reply; | |
86 | } | |
87 | ||
aaca7f11 PR |
88 | void daemon_reply_destroy(daemon_reply r) { |
89 | if (r.cft) | |
6e4e3082 | 90 | dm_config_destroy(r.cft); |
3f694b12 | 91 | dm_free(r.buffer); |
aaca7f11 PR |
92 | } |
93 | ||
d528658f | 94 | daemon_reply daemon_send_simple(daemon_handle h, const char *id, ...) |
30896326 | 95 | { |
6d404585 | 96 | static const daemon_reply err = { .error = ENOMEM, .buffer = NULL, .cft = NULL }; |
ade2b934 | 97 | daemon_request rq = { .cft = NULL }; |
6d404585 | 98 | daemon_reply repl; |
30896326 | 99 | va_list ap; |
6d404585 | 100 | |
30896326 | 101 | va_start(ap, id); |
6d404585 ZK |
102 | rq.buffer = format_buffer("request", id, ap); |
103 | va_end(ap); | |
30896326 | 104 | |
6d404585 | 105 | if (!rq.buffer) |
30896326 | 106 | return err; |
30896326 | 107 | |
6d404585 | 108 | repl = daemon_send(h, rq); |
5627fc8e ZK |
109 | dm_free(rq.buffer); |
110 | ||
30896326 PR |
111 | return repl; |
112 | } | |
113 | ||
114 | void daemon_close(daemon_handle h) | |
115 | { | |
3f694b12 | 116 | dm_free((char *)h.protocol); |
92658f56 | 117 | } |