Deleted Added
full compact
procs.c (50479) procs.c (92970)
1/*
2 * Copyright (c) 1995
3 * A.R. Gordon (andrew.gordon@net-tel.co.uk). All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed for the FreeBSD project
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY ANDREW GORDON AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 */
33
34#ifndef lint
35static const char rcsid[] =
1/*
2 * Copyright (c) 1995
3 * A.R. Gordon (andrew.gordon@net-tel.co.uk). All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed for the FreeBSD project
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY ANDREW GORDON AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 */
33
34#ifndef lint
35static const char rcsid[] =
36 "$FreeBSD: head/usr.sbin/rpc.statd/procs.c 50479 1999-08-28 01:35:59Z peter $";
36 "$FreeBSD: head/usr.sbin/rpc.statd/procs.c 92970 2002-03-22 19:43:21Z alfred $";
37#endif /* not lint */
38
39#include <errno.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44#include <rpc/rpc.h>
45#include <syslog.h>
46#include <netdb.h> /* for gethostbyname() */
47
48#include "statd.h"
49
50/* sm_stat_1 --------------------------------------------------------------- */
51/*
52 Purpose: RPC call to enquire if a host can be monitored
53 Returns: TRUE for any hostname that can be looked up to give
54 an address.
55*/
56
57struct sm_stat_res *sm_stat_1_svc(sm_name *arg, struct svc_req *req)
58{
59 static sm_stat_res res;
60
61 if (debug) syslog(LOG_DEBUG, "stat called for host %s", arg->mon_name);
62
63 if (gethostbyname(arg->mon_name)) res.res_stat = stat_succ;
64 else
65 {
66 syslog(LOG_ERR, "invalid hostname to sm_stat: %s", arg->mon_name);
67 res.res_stat = stat_fail;
68 }
69
70 res.state = status_info->ourState;
71 return (&res);
72}
73
74/* sm_mon_1 ---------------------------------------------------------------- */
75/*
76 Purpose: RPC procedure to establish a monitor request
77 Returns: Success, unless lack of resources prevents
78 the necessary structures from being set up
79 to record the request, or if the hostname is not
80 valid (as judged by gethostbyname())
81*/
82
83struct sm_stat_res *sm_mon_1_svc(mon *arg, struct svc_req *req)
84{
85 static sm_stat_res res;
86 HostInfo *hp;
87 MonList *lp;
88
89 if (debug)
90 {
91 syslog(LOG_DEBUG, "monitor request for host %s", arg->mon_id.mon_name);
92 syslog(LOG_DEBUG, "recall host: %s prog: %d ver: %d proc: %d",
93 arg->mon_id.mon_name, arg->mon_id.my_id.my_name,
94 arg->mon_id.my_id.my_prog, arg->mon_id.my_id.my_vers,
95 arg->mon_id.my_id.my_proc);
96 }
97
98 res.res_stat = stat_fail; /* Assume fail until set otherwise */
99 res.state = status_info->ourState;
100
101 /* Find existing host entry, or create one if not found */
102 /* If find_host() fails, it will have logged the error already. */
103 if (!gethostbyname(arg->mon_id.mon_name))
104 {
105 syslog(LOG_ERR, "Invalid hostname to sm_mon: %s", arg->mon_id.mon_name);
106 }
107 else if ((hp = find_host(arg->mon_id.mon_name, TRUE)))
108 {
109 lp = (MonList *)malloc(sizeof(MonList));
110 if (!lp)
111 {
112 syslog(LOG_ERR, "Out of memory");
113 }
114 else
115 {
116 strncpy(lp->notifyHost, arg->mon_id.my_id.my_name, SM_MAXSTRLEN);
117 lp->notifyProg = arg->mon_id.my_id.my_prog;
118 lp->notifyVers = arg->mon_id.my_id.my_vers;
119 lp->notifyProc = arg->mon_id.my_id.my_proc;
120 memcpy(lp->notifyData, arg->priv, sizeof(lp->notifyData));
121
122 lp->next = hp->monList;
123 hp->monList = lp;
124 sync_file();
125
126 res.res_stat = stat_succ; /* Report success */
127 }
128 }
129
130 return (&res);
131}
132
133/* do_unmon ---------------------------------------------------------------- */
134/*
135 Purpose: Remove a monitor request from a host
136 Returns: TRUE if found, FALSE if not found.
137 Notes: Common code from sm_unmon_1_svc and sm_unmon_all_1_svc
138 In the unlikely event of more than one identical monitor
139 request, all are removed.
140*/
141
142static int do_unmon(HostInfo *hp, my_id *idp)
143{
144 MonList *lp, *next;
145 MonList *last = NULL;
146 int result = FALSE;
147
148 lp = hp->monList;
149 while (lp)
150 {
151 if (!strncasecmp(idp->my_name, lp->notifyHost, SM_MAXSTRLEN)
152 && (idp->my_prog == lp->notifyProg) && (idp->my_proc == lp->notifyProc)
153 && (idp->my_vers == lp->notifyVers))
154 {
155 /* found one. Unhook from chain and free. */
156 next = lp->next;
157 if (last) last->next = next;
158 else hp->monList = next;
159 free(lp);
160 lp = next;
161 result = TRUE;
162 }
163 else
164 {
165 last = lp;
166 lp = lp->next;
167 }
168 }
169 return (result);
170}
171
172/* sm_unmon_1 -------------------------------------------------------------- */
173/*
174 Purpose: RPC procedure to release a monitor request.
175 Returns: Local machine's status number
176 Notes: The supplied mon_id should match the value passed in an
177 earlier call to sm_mon_1
178*/
179
180struct sm_stat *sm_unmon_1_svc(mon_id *arg, struct svc_req *req)
181{
182 static sm_stat res;
183 HostInfo *hp;
184
185 if (debug)
186 {
187 syslog(LOG_DEBUG, "un-monitor request for host %s", arg->mon_name);
188 syslog(LOG_DEBUG, "recall host: %s prog: %d ver: %d proc: %d",
189 arg->mon_name, arg->my_id.my_name, arg->my_id.my_prog,
190 arg->my_id.my_vers, arg->my_id.my_proc);
191 }
192
193 if ((hp = find_host(arg->mon_name, FALSE)))
194 {
195 if (do_unmon(hp, &arg->my_id)) sync_file();
196 else
197 {
198 syslog(LOG_ERR, "unmon request from %s, no matching monitor",
199 arg->my_id.my_name);
200 }
201 }
202 else syslog(LOG_ERR, "unmon request from %s for unknown host %s",
203 arg->my_id.my_name, arg->mon_name);
204
205 res.state = status_info->ourState;
206
207 return (&res);
208}
209
210/* sm_unmon_all_1 ---------------------------------------------------------- */
211/*
212 Purpose: RPC procedure to release monitor requests.
213 Returns: Local machine's status number
214 Notes: Releases all monitor requests (if any) from the specified
215 host and program number.
216*/
217
218struct sm_stat *sm_unmon_all_1_svc(my_id *arg, struct svc_req *req)
219{
220 static sm_stat res;
221 HostInfo *hp;
222 int i;
223
224 if (debug)
225 {
226 syslog(LOG_DEBUG, "unmon_all for host: %s prog: %d ver: %d proc: %d",
227 arg->my_name, arg->my_prog, arg->my_vers, arg->my_proc);
228 }
229
230 for (i = status_info->noOfHosts, hp = status_info->hosts; i; i--, hp++)
231 {
232 do_unmon(hp, arg);
233 }
234 sync_file();
235
236 res.state = status_info->ourState;
237
238 return (&res);
239}
240
241/* sm_simu_crash_1 --------------------------------------------------------- */
242/*
243 Purpose: RPC procedure to simulate a crash
244 Returns: Nothing
245 Notes: Standardised mechanism for debug purposes
246 The specification says that we should drop all of our
247 status information (apart from the list of monitored hosts
248 on disc). However, this would confuse the rpc.lockd
249 which would be unaware that all of its monitor requests
250 had been silently junked. Hence we in fact retain all
251 current requests and simply increment the status counter
252 and inform all hosts on the monitor list.
253*/
254
255void *sm_simu_crash_1_svc(void *v, struct svc_req *req)
256{
257 static char dummy;
258 int work_to_do;
259 HostInfo *hp;
260 int i;
261
262 if (debug) syslog(LOG_DEBUG, "simu_crash called!!");
263
264 /* Simulate crash by setting notify-required flag on all monitored */
265 /* hosts, and incrementing our status number. notify_hosts() is */
266 /* then called to fork a process to do the notifications. */
267
268 for (i = status_info->noOfHosts, hp = status_info->hosts; i ; i--, hp++)
269 {
270 if (hp->monList)
271 {
272 work_to_do = TRUE;
273 hp->notifyReqd = TRUE;
274 }
275 }
276 status_info->ourState += 2; /* always even numbers if not crashed */
277
278 if (work_to_do) notify_hosts();
279
280 return (&dummy);
281}
282
283/* sm_notify_1 ------------------------------------------------------------- */
284/*
285 Purpose: RPC procedure notifying local statd of the crash of another
286 Returns: Nothing
287 Notes: There is danger of deadlock, since it is quite likely that
288 the client procedure that we call will in turn call us
289 to remove or adjust the monitor request.
290 We therefore fork() a process to do the notifications.
291 Note that the main HostInfo structure is in a mmap()
292 region and so will be shared with the child, but the
293 monList pointed to by the HostInfo is in normal memory.
294 Hence if we read the monList before forking, we are
295 protected from the parent servicing other requests
296 that modify the list.
297*/
298
299void *sm_notify_1_svc(stat_chge *arg, struct svc_req *req)
300{
301 struct timeval timeout = { 20, 0 }; /* 20 secs timeout */
302 CLIENT *cli;
303 static char dummy;
37#endif /* not lint */
38
39#include <errno.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44#include <rpc/rpc.h>
45#include <syslog.h>
46#include <netdb.h> /* for gethostbyname() */
47
48#include "statd.h"
49
50/* sm_stat_1 --------------------------------------------------------------- */
51/*
52 Purpose: RPC call to enquire if a host can be monitored
53 Returns: TRUE for any hostname that can be looked up to give
54 an address.
55*/
56
57struct sm_stat_res *sm_stat_1_svc(sm_name *arg, struct svc_req *req)
58{
59 static sm_stat_res res;
60
61 if (debug) syslog(LOG_DEBUG, "stat called for host %s", arg->mon_name);
62
63 if (gethostbyname(arg->mon_name)) res.res_stat = stat_succ;
64 else
65 {
66 syslog(LOG_ERR, "invalid hostname to sm_stat: %s", arg->mon_name);
67 res.res_stat = stat_fail;
68 }
69
70 res.state = status_info->ourState;
71 return (&res);
72}
73
74/* sm_mon_1 ---------------------------------------------------------------- */
75/*
76 Purpose: RPC procedure to establish a monitor request
77 Returns: Success, unless lack of resources prevents
78 the necessary structures from being set up
79 to record the request, or if the hostname is not
80 valid (as judged by gethostbyname())
81*/
82
83struct sm_stat_res *sm_mon_1_svc(mon *arg, struct svc_req *req)
84{
85 static sm_stat_res res;
86 HostInfo *hp;
87 MonList *lp;
88
89 if (debug)
90 {
91 syslog(LOG_DEBUG, "monitor request for host %s", arg->mon_id.mon_name);
92 syslog(LOG_DEBUG, "recall host: %s prog: %d ver: %d proc: %d",
93 arg->mon_id.mon_name, arg->mon_id.my_id.my_name,
94 arg->mon_id.my_id.my_prog, arg->mon_id.my_id.my_vers,
95 arg->mon_id.my_id.my_proc);
96 }
97
98 res.res_stat = stat_fail; /* Assume fail until set otherwise */
99 res.state = status_info->ourState;
100
101 /* Find existing host entry, or create one if not found */
102 /* If find_host() fails, it will have logged the error already. */
103 if (!gethostbyname(arg->mon_id.mon_name))
104 {
105 syslog(LOG_ERR, "Invalid hostname to sm_mon: %s", arg->mon_id.mon_name);
106 }
107 else if ((hp = find_host(arg->mon_id.mon_name, TRUE)))
108 {
109 lp = (MonList *)malloc(sizeof(MonList));
110 if (!lp)
111 {
112 syslog(LOG_ERR, "Out of memory");
113 }
114 else
115 {
116 strncpy(lp->notifyHost, arg->mon_id.my_id.my_name, SM_MAXSTRLEN);
117 lp->notifyProg = arg->mon_id.my_id.my_prog;
118 lp->notifyVers = arg->mon_id.my_id.my_vers;
119 lp->notifyProc = arg->mon_id.my_id.my_proc;
120 memcpy(lp->notifyData, arg->priv, sizeof(lp->notifyData));
121
122 lp->next = hp->monList;
123 hp->monList = lp;
124 sync_file();
125
126 res.res_stat = stat_succ; /* Report success */
127 }
128 }
129
130 return (&res);
131}
132
133/* do_unmon ---------------------------------------------------------------- */
134/*
135 Purpose: Remove a monitor request from a host
136 Returns: TRUE if found, FALSE if not found.
137 Notes: Common code from sm_unmon_1_svc and sm_unmon_all_1_svc
138 In the unlikely event of more than one identical monitor
139 request, all are removed.
140*/
141
142static int do_unmon(HostInfo *hp, my_id *idp)
143{
144 MonList *lp, *next;
145 MonList *last = NULL;
146 int result = FALSE;
147
148 lp = hp->monList;
149 while (lp)
150 {
151 if (!strncasecmp(idp->my_name, lp->notifyHost, SM_MAXSTRLEN)
152 && (idp->my_prog == lp->notifyProg) && (idp->my_proc == lp->notifyProc)
153 && (idp->my_vers == lp->notifyVers))
154 {
155 /* found one. Unhook from chain and free. */
156 next = lp->next;
157 if (last) last->next = next;
158 else hp->monList = next;
159 free(lp);
160 lp = next;
161 result = TRUE;
162 }
163 else
164 {
165 last = lp;
166 lp = lp->next;
167 }
168 }
169 return (result);
170}
171
172/* sm_unmon_1 -------------------------------------------------------------- */
173/*
174 Purpose: RPC procedure to release a monitor request.
175 Returns: Local machine's status number
176 Notes: The supplied mon_id should match the value passed in an
177 earlier call to sm_mon_1
178*/
179
180struct sm_stat *sm_unmon_1_svc(mon_id *arg, struct svc_req *req)
181{
182 static sm_stat res;
183 HostInfo *hp;
184
185 if (debug)
186 {
187 syslog(LOG_DEBUG, "un-monitor request for host %s", arg->mon_name);
188 syslog(LOG_DEBUG, "recall host: %s prog: %d ver: %d proc: %d",
189 arg->mon_name, arg->my_id.my_name, arg->my_id.my_prog,
190 arg->my_id.my_vers, arg->my_id.my_proc);
191 }
192
193 if ((hp = find_host(arg->mon_name, FALSE)))
194 {
195 if (do_unmon(hp, &arg->my_id)) sync_file();
196 else
197 {
198 syslog(LOG_ERR, "unmon request from %s, no matching monitor",
199 arg->my_id.my_name);
200 }
201 }
202 else syslog(LOG_ERR, "unmon request from %s for unknown host %s",
203 arg->my_id.my_name, arg->mon_name);
204
205 res.state = status_info->ourState;
206
207 return (&res);
208}
209
210/* sm_unmon_all_1 ---------------------------------------------------------- */
211/*
212 Purpose: RPC procedure to release monitor requests.
213 Returns: Local machine's status number
214 Notes: Releases all monitor requests (if any) from the specified
215 host and program number.
216*/
217
218struct sm_stat *sm_unmon_all_1_svc(my_id *arg, struct svc_req *req)
219{
220 static sm_stat res;
221 HostInfo *hp;
222 int i;
223
224 if (debug)
225 {
226 syslog(LOG_DEBUG, "unmon_all for host: %s prog: %d ver: %d proc: %d",
227 arg->my_name, arg->my_prog, arg->my_vers, arg->my_proc);
228 }
229
230 for (i = status_info->noOfHosts, hp = status_info->hosts; i; i--, hp++)
231 {
232 do_unmon(hp, arg);
233 }
234 sync_file();
235
236 res.state = status_info->ourState;
237
238 return (&res);
239}
240
241/* sm_simu_crash_1 --------------------------------------------------------- */
242/*
243 Purpose: RPC procedure to simulate a crash
244 Returns: Nothing
245 Notes: Standardised mechanism for debug purposes
246 The specification says that we should drop all of our
247 status information (apart from the list of monitored hosts
248 on disc). However, this would confuse the rpc.lockd
249 which would be unaware that all of its monitor requests
250 had been silently junked. Hence we in fact retain all
251 current requests and simply increment the status counter
252 and inform all hosts on the monitor list.
253*/
254
255void *sm_simu_crash_1_svc(void *v, struct svc_req *req)
256{
257 static char dummy;
258 int work_to_do;
259 HostInfo *hp;
260 int i;
261
262 if (debug) syslog(LOG_DEBUG, "simu_crash called!!");
263
264 /* Simulate crash by setting notify-required flag on all monitored */
265 /* hosts, and incrementing our status number. notify_hosts() is */
266 /* then called to fork a process to do the notifications. */
267
268 for (i = status_info->noOfHosts, hp = status_info->hosts; i ; i--, hp++)
269 {
270 if (hp->monList)
271 {
272 work_to_do = TRUE;
273 hp->notifyReqd = TRUE;
274 }
275 }
276 status_info->ourState += 2; /* always even numbers if not crashed */
277
278 if (work_to_do) notify_hosts();
279
280 return (&dummy);
281}
282
283/* sm_notify_1 ------------------------------------------------------------- */
284/*
285 Purpose: RPC procedure notifying local statd of the crash of another
286 Returns: Nothing
287 Notes: There is danger of deadlock, since it is quite likely that
288 the client procedure that we call will in turn call us
289 to remove or adjust the monitor request.
290 We therefore fork() a process to do the notifications.
291 Note that the main HostInfo structure is in a mmap()
292 region and so will be shared with the child, but the
293 monList pointed to by the HostInfo is in normal memory.
294 Hence if we read the monList before forking, we are
295 protected from the parent servicing other requests
296 that modify the list.
297*/
298
299void *sm_notify_1_svc(stat_chge *arg, struct svc_req *req)
300{
301 struct timeval timeout = { 20, 0 }; /* 20 secs timeout */
302 CLIENT *cli;
303 static char dummy;
304 status tx_arg; /* arg sent to callback procedure */
304 sm_status tx_arg; /* arg sent to callback procedure */
305 MonList *lp;
306 HostInfo *hp;
307 pid_t pid;
308
309 if (debug) syslog(LOG_DEBUG, "notify from host %s, new state %d",
310 arg->mon_name, arg->state);
311
312 hp = find_host(arg->mon_name, FALSE);
313 if (!hp)
314 {
315 /* Never heard of this host - why is it notifying us? */
316 syslog(LOG_ERR, "Unsolicited notification from host %s", arg->mon_name);
317 return;
318 }
319 lp = hp->monList;
320 if (!lp) return (FALSE); /* We know this host, but have no */
321 /* outstanding requests. */
322 pid = fork();
323 if (pid == -1)
324 {
325 syslog(LOG_ERR, "Unable to fork notify process - %s", strerror(errno));
326 return;
327 }
328 if (pid) return (&dummy); /* Parent returns */
329
330 while (lp)
331 {
332 tx_arg.mon_name = arg->mon_name;
333 tx_arg.state = arg->state;
334 memcpy(tx_arg.priv, lp->notifyData, sizeof(tx_arg.priv));
335 cli = clnt_create(lp->notifyHost, lp->notifyProg, lp->notifyVers, "udp");
336 if (!cli)
337 {
338 syslog(LOG_ERR, "Failed to contact host %s%s", lp->notifyHost,
339 clnt_spcreateerror(""));
340 }
341 else
342 {
305 MonList *lp;
306 HostInfo *hp;
307 pid_t pid;
308
309 if (debug) syslog(LOG_DEBUG, "notify from host %s, new state %d",
310 arg->mon_name, arg->state);
311
312 hp = find_host(arg->mon_name, FALSE);
313 if (!hp)
314 {
315 /* Never heard of this host - why is it notifying us? */
316 syslog(LOG_ERR, "Unsolicited notification from host %s", arg->mon_name);
317 return;
318 }
319 lp = hp->monList;
320 if (!lp) return (FALSE); /* We know this host, but have no */
321 /* outstanding requests. */
322 pid = fork();
323 if (pid == -1)
324 {
325 syslog(LOG_ERR, "Unable to fork notify process - %s", strerror(errno));
326 return;
327 }
328 if (pid) return (&dummy); /* Parent returns */
329
330 while (lp)
331 {
332 tx_arg.mon_name = arg->mon_name;
333 tx_arg.state = arg->state;
334 memcpy(tx_arg.priv, lp->notifyData, sizeof(tx_arg.priv));
335 cli = clnt_create(lp->notifyHost, lp->notifyProg, lp->notifyVers, "udp");
336 if (!cli)
337 {
338 syslog(LOG_ERR, "Failed to contact host %s%s", lp->notifyHost,
339 clnt_spcreateerror(""));
340 }
341 else
342 {
343 if (clnt_call(cli, lp->notifyProc, xdr_status, &tx_arg, xdr_void, &dummy,
344 timeout) != RPC_SUCCESS)
343 if (clnt_call(cli, lp->notifyProc, xdr_sm_status, &tx_arg, xdr_void,
344 &dummy, timeout) != RPC_SUCCESS)
345 {
346 syslog(LOG_ERR, "Failed to call rpc.statd client at host %s",
347 lp->notifyHost);
348 }
349 clnt_destroy(cli);
350 }
351 lp = lp->next;
352 }
353
354 exit (0); /* Child quits */
355}
345 {
346 syslog(LOG_ERR, "Failed to call rpc.statd client at host %s",
347 lp->notifyHost);
348 }
349 clnt_destroy(cli);
350 }
351 lp = lp->next;
352 }
353
354 exit (0); /* Child quits */
355}