nwrap: Fix the build on Solaris
[obnox/samba/samba-obnox.git] / source3 / torture / msg_source.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  Send messages once a second
4  *  Copyright (C) Volker Lendecke 2014
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "replace.h"
21 #include "includes.h"
22 #include "messages.h"
23 #include "lib/util/tevent_unix.h"
24 #include <stdio.h>
25
26 struct source_state {
27         struct tevent_context *ev;
28         struct messaging_context *msg_ctx;
29         int msg_type;
30         struct timeval interval;
31         struct server_id dst;
32 };
33
34 static void source_waited(struct tevent_req *subreq);
35
36 static struct tevent_req *source_send(TALLOC_CTX *mem_ctx,
37                                       struct tevent_context *ev,
38                                       struct messaging_context *msg_ctx,
39                                       int msg_type,
40                                       struct timeval interval,
41                                       struct server_id dst)
42 {
43         struct tevent_req *req, *subreq;
44         struct source_state *state;
45
46         req = tevent_req_create(mem_ctx, &state, struct source_state);
47         if (req == NULL) {
48                 return NULL;
49         }
50         state->ev = ev;
51         state->msg_ctx = msg_ctx;
52         state->msg_type = msg_type;
53         state->interval = interval;
54         state->dst = dst;
55
56         subreq = tevent_wakeup_send(
57                 state, state->ev,
58                 timeval_current_ofs(state->interval.tv_sec,
59                                     state->interval.tv_usec));
60         if (tevent_req_nomem(subreq, req)) {
61                 return tevent_req_post(req, ev);
62         }
63         tevent_req_set_callback(subreq, source_waited, req);
64         return req;
65 }
66
67 static void source_waited(struct tevent_req *subreq)
68 {
69         struct tevent_req *req = tevent_req_callback_data(
70                 subreq, struct tevent_req);
71         struct source_state *state = tevent_req_data(
72                 req, struct source_state);
73         bool ok;
74         uint8_t buf[200] = { };
75
76         ok = tevent_wakeup_recv(subreq);
77         TALLOC_FREE(subreq);
78         if (!ok) {
79                 tevent_req_error(req, ENOMEM);
80                 return;
81         }
82
83         messaging_send_buf(state->msg_ctx, state->dst, state->msg_type,
84                            buf, sizeof(buf));
85
86         subreq = tevent_wakeup_send(
87                 state, state->ev,
88                 timeval_current_ofs(state->interval.tv_sec,
89                                     state->interval.tv_usec));
90         if (tevent_req_nomem(subreq, req)) {
91                 return;
92         }
93         tevent_req_set_callback(subreq, source_waited, req);
94 }
95
96 static int source_recv(struct tevent_req *req)
97 {
98         int err;
99
100         if (tevent_req_is_unix_error(req, &err)) {
101                 return err;
102         }
103         return 0;
104 }
105
106 int main(int argc, const char *argv[])
107 {
108         TALLOC_CTX *frame = talloc_stackframe();
109         struct tevent_context *ev;
110         struct messaging_context *msg_ctx;
111         struct tevent_req *req;
112         int ret;
113         struct server_id id;
114
115         if (argc != 2) {
116                 fprintf(stderr, "Usage: %s <dst>\n", argv[0]);
117                 return -1;
118         }
119
120         lp_load_global(get_dyn_CONFIGFILE());
121
122         ev = tevent_context_init(frame);
123         if (ev == NULL) {
124                 perror("tevent_context_init failed");
125                 return -1;
126         }
127
128         msg_ctx = messaging_init(ev, ev);
129         if (msg_ctx == NULL) {
130                 perror("messaging_init failed");
131                 return -1;
132         }
133
134         id = server_id_from_string(get_my_vnn(), argv[1]);
135         if (!procid_valid(&id)) {
136                 fprintf(stderr, "pid %s invalid\n", argv[1]);
137                 return -1;
138         }
139
140         req = source_send(ev, ev, msg_ctx, MSG_SMB_NOTIFY,
141                           timeval_set(0, 10000), id);
142         if (req == NULL) {
143                 perror("source_send failed");
144                 return -1;
145         }
146
147         if (!tevent_req_poll(req, ev)) {
148                 perror("tevent_req_poll failed");
149                 return -1;
150         }
151
152         ret = source_recv(req);
153
154         printf("source_recv returned %d\n", ret);
155
156         return 0;
157 }