xref: /onnv-gate/usr/src/lib/libnwam/common/libnwam_events.c (revision 12036:aa269fb9cf77)
111767SAnurag.Maskey@Sun.COM /*
211767SAnurag.Maskey@Sun.COM  * CDDL HEADER START
311767SAnurag.Maskey@Sun.COM  *
411767SAnurag.Maskey@Sun.COM  * The contents of this file are subject to the terms of the
511767SAnurag.Maskey@Sun.COM  * Common Development and Distribution License (the "License").
611767SAnurag.Maskey@Sun.COM  * You may not use this file except in compliance with the License.
711767SAnurag.Maskey@Sun.COM  *
811767SAnurag.Maskey@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911767SAnurag.Maskey@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1011767SAnurag.Maskey@Sun.COM  * See the License for the specific language governing permissions
1111767SAnurag.Maskey@Sun.COM  * and limitations under the License.
1211767SAnurag.Maskey@Sun.COM  *
1311767SAnurag.Maskey@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1411767SAnurag.Maskey@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511767SAnurag.Maskey@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1611767SAnurag.Maskey@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1711767SAnurag.Maskey@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1811767SAnurag.Maskey@Sun.COM  *
1911767SAnurag.Maskey@Sun.COM  * CDDL HEADER END
2011767SAnurag.Maskey@Sun.COM  */
2111767SAnurag.Maskey@Sun.COM 
2211767SAnurag.Maskey@Sun.COM /*
2311767SAnurag.Maskey@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
2411767SAnurag.Maskey@Sun.COM  * Use is subject to license terms.
2511767SAnurag.Maskey@Sun.COM  */
2611767SAnurag.Maskey@Sun.COM 
2711767SAnurag.Maskey@Sun.COM #include <assert.h>
2811767SAnurag.Maskey@Sun.COM #include <dirent.h>
2911767SAnurag.Maskey@Sun.COM #include <errno.h>
3011767SAnurag.Maskey@Sun.COM #include <fcntl.h>
3111767SAnurag.Maskey@Sun.COM #include <pthread.h>
3211767SAnurag.Maskey@Sun.COM #include <stdio.h>
3311767SAnurag.Maskey@Sun.COM #include <stdlib.h>
3411767SAnurag.Maskey@Sun.COM #include <strings.h>
3511767SAnurag.Maskey@Sun.COM #include <string.h>
3611767SAnurag.Maskey@Sun.COM #include <syslog.h>
3711767SAnurag.Maskey@Sun.COM #include <sys/msg.h>
3811767SAnurag.Maskey@Sun.COM #include <sys/stat.h>
3911767SAnurag.Maskey@Sun.COM #include <sys/types.h>
4011767SAnurag.Maskey@Sun.COM #include <unistd.h>
4111767SAnurag.Maskey@Sun.COM 
4211767SAnurag.Maskey@Sun.COM #include "libnwam_impl.h"
4311767SAnurag.Maskey@Sun.COM #include <libnwam_priv.h>
4411767SAnurag.Maskey@Sun.COM #include <libnwam.h>
4511767SAnurag.Maskey@Sun.COM 
4611767SAnurag.Maskey@Sun.COM /*
4711767SAnurag.Maskey@Sun.COM  * Implementation of event notification mechanism used by the GUI and
4811767SAnurag.Maskey@Sun.COM  * nwamadm.  Clients register for events via nwam_events_init() and
4911767SAnurag.Maskey@Sun.COM  * unregister via nwam_events_fini().  nwamd sends events via nwam_event_send()
5011767SAnurag.Maskey@Sun.COM  * and applications block waiting for a new event to be delivered in
5111767SAnurag.Maskey@Sun.COM  * nwam_event_wait().  Events are implemented as System V message queues,
5211767SAnurag.Maskey@Sun.COM  * one per event client.  The event mechanism has to be resilient to
5311767SAnurag.Maskey@Sun.COM  * nwamd restarts so that clients do not lose the event connection.
5411767SAnurag.Maskey@Sun.COM  */
5511767SAnurag.Maskey@Sun.COM 
5611767SAnurag.Maskey@Sun.COM #define	NWAM_EVENT_MSG_DIR		"/etc/svc/volatile/nwam/"
5711767SAnurag.Maskey@Sun.COM #define	NWAM_EVENT_MSG_FILE		"nwam_event_msgs"
5811767SAnurag.Maskey@Sun.COM #define	NWAM_EVENT_MSG_FILE_PREFIX	NWAM_EVENT_MSG_DIR NWAM_EVENT_MSG_FILE
5911767SAnurag.Maskey@Sun.COM #define	NWAM_EVENT_MAX_SIZE		(sizeof (struct nwam_event) + \
60*12036SMichael.Hunter@Sun.COM 	(NWAMD_MAX_NUM_WLANS * sizeof (nwam_wlan_t)))
6111767SAnurag.Maskey@Sun.COM #define	NWAM_EVENT_WAIT_TIME		10
6211767SAnurag.Maskey@Sun.COM #define	NWAM_EVENT_MAX_NUM_PENDING	25
6311767SAnurag.Maskey@Sun.COM 
6411767SAnurag.Maskey@Sun.COM /*
6511767SAnurag.Maskey@Sun.COM  * This is protecting simultaneous access to the msqid and its configuration.
6611767SAnurag.Maskey@Sun.COM  */
6711767SAnurag.Maskey@Sun.COM static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;
6811767SAnurag.Maskey@Sun.COM static int event_msqid = -1;
6911767SAnurag.Maskey@Sun.COM 
7011767SAnurag.Maskey@Sun.COM static nwam_error_t
nwam_event_alloc(nwam_event_t * eventp)7111767SAnurag.Maskey@Sun.COM nwam_event_alloc(nwam_event_t *eventp)
7211767SAnurag.Maskey@Sun.COM {
7311767SAnurag.Maskey@Sun.COM 	assert(eventp != NULL);
7411767SAnurag.Maskey@Sun.COM 
7511767SAnurag.Maskey@Sun.COM 	*eventp = calloc(1, NWAM_EVENT_MAX_SIZE);
7611767SAnurag.Maskey@Sun.COM 	if (*eventp == NULL)
7711767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
7811767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
7911767SAnurag.Maskey@Sun.COM }
8011767SAnurag.Maskey@Sun.COM 
8111767SAnurag.Maskey@Sun.COM void
nwam_event_free(nwam_event_t event)8211767SAnurag.Maskey@Sun.COM nwam_event_free(nwam_event_t event)
8311767SAnurag.Maskey@Sun.COM {
8411767SAnurag.Maskey@Sun.COM 	if (event != NULL)
8511767SAnurag.Maskey@Sun.COM 		free(event);
8611767SAnurag.Maskey@Sun.COM }
8711767SAnurag.Maskey@Sun.COM 
8811767SAnurag.Maskey@Sun.COM /*
8911767SAnurag.Maskey@Sun.COM  * Get next event in queue.
9011767SAnurag.Maskey@Sun.COM  */
9111767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_event_wait(nwam_event_t * eventp)9211767SAnurag.Maskey@Sun.COM nwam_event_wait(nwam_event_t *eventp)
9311767SAnurag.Maskey@Sun.COM {
9411767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
9511767SAnurag.Maskey@Sun.COM 	nwam_event_t event;
9611767SAnurag.Maskey@Sun.COM 
9711767SAnurag.Maskey@Sun.COM 	assert(eventp != NULL);
9811767SAnurag.Maskey@Sun.COM 
9911767SAnurag.Maskey@Sun.COM 	if ((err = nwam_event_alloc(&event)) != NWAM_SUCCESS)
10011767SAnurag.Maskey@Sun.COM 		return (err);
10111767SAnurag.Maskey@Sun.COM 	while (msgrcv(event_msqid, (struct msgbuf *)event, NWAM_EVENT_MAX_SIZE,
10211767SAnurag.Maskey@Sun.COM 	    0, 0) == -1) {
10311767SAnurag.Maskey@Sun.COM 		switch (errno) {
10411767SAnurag.Maskey@Sun.COM 			case EAGAIN:
10511767SAnurag.Maskey@Sun.COM 			case EBUSY:
10611767SAnurag.Maskey@Sun.COM 				/*
10711767SAnurag.Maskey@Sun.COM 				 * We see this errno eventhough it isn't
10811767SAnurag.Maskey@Sun.COM 				 * documented.  Try again.  If this causes
10911767SAnurag.Maskey@Sun.COM 				 * a busy loop then grab a trace otherwise
11011767SAnurag.Maskey@Sun.COM 				 * it's a brace 'til we can figure out why it
11111767SAnurag.Maskey@Sun.COM 				 * happens.
11211767SAnurag.Maskey@Sun.COM 				 */
11311767SAnurag.Maskey@Sun.COM 				continue;
11411767SAnurag.Maskey@Sun.COM 
11511767SAnurag.Maskey@Sun.COM 			default:
11611767SAnurag.Maskey@Sun.COM 				nwam_event_free(event);
11711767SAnurag.Maskey@Sun.COM 				return (nwam_errno_to_nwam_error(errno));
11811767SAnurag.Maskey@Sun.COM 		}
11911767SAnurag.Maskey@Sun.COM 	}
12011767SAnurag.Maskey@Sun.COM 
12111767SAnurag.Maskey@Sun.COM 	/* Resize event down from maximum size */
12211767SAnurag.Maskey@Sun.COM 	if ((*eventp = realloc(event, event->nwe_size)) == NULL)
12311767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
12411767SAnurag.Maskey@Sun.COM 
12511767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
12611767SAnurag.Maskey@Sun.COM }
12711767SAnurag.Maskey@Sun.COM 
12811767SAnurag.Maskey@Sun.COM /*
12911767SAnurag.Maskey@Sun.COM  * Register for receipt of events from nwamd.  Event delivery is
13011767SAnurag.Maskey@Sun.COM  * done via a System V message queue.
13111767SAnurag.Maskey@Sun.COM  */
13211767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_events_init(void)13311767SAnurag.Maskey@Sun.COM nwam_events_init(void)
13411767SAnurag.Maskey@Sun.COM {
13511767SAnurag.Maskey@Sun.COM 	char eventmsgfile[MAXPATHLEN];
13611767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
13711767SAnurag.Maskey@Sun.COM 	nwam_error_t rc = NWAM_SUCCESS;
13811767SAnurag.Maskey@Sun.COM 	key_t key;
13911767SAnurag.Maskey@Sun.COM 
14011767SAnurag.Maskey@Sun.COM 	(void) snprintf(eventmsgfile, sizeof (eventmsgfile), "%s.%d",
14111767SAnurag.Maskey@Sun.COM 	    NWAM_EVENT_MSG_FILE_PREFIX, getpid());
14211767SAnurag.Maskey@Sun.COM 
14311767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_lock(&event_mutex);
14411767SAnurag.Maskey@Sun.COM 
14511767SAnurag.Maskey@Sun.COM 	if (event_msqid != -1) {
14611767SAnurag.Maskey@Sun.COM 		rc = NWAM_ENTITY_IN_USE;
14711767SAnurag.Maskey@Sun.COM 		goto exit;
14811767SAnurag.Maskey@Sun.COM 	}
14911767SAnurag.Maskey@Sun.COM 
15011767SAnurag.Maskey@Sun.COM 	if ((err = nwam_request_register_unregister
15111767SAnurag.Maskey@Sun.COM 	    (NWAM_REQUEST_TYPE_EVENT_REGISTER, eventmsgfile)) != NWAM_SUCCESS) {
15211767SAnurag.Maskey@Sun.COM 		rc = err;
15311767SAnurag.Maskey@Sun.COM 		goto exit;
15411767SAnurag.Maskey@Sun.COM 	}
15511767SAnurag.Maskey@Sun.COM 
15611767SAnurag.Maskey@Sun.COM 	if ((key = ftok(eventmsgfile, 0)) == -1) {
15711767SAnurag.Maskey@Sun.COM 		rc = nwam_errno_to_nwam_error(errno);
15811767SAnurag.Maskey@Sun.COM 		goto exit;
15911767SAnurag.Maskey@Sun.COM 	}
16011767SAnurag.Maskey@Sun.COM 
16111767SAnurag.Maskey@Sun.COM 	/* Get system-wide message queue ID */
16211767SAnurag.Maskey@Sun.COM 	if ((event_msqid = msgget(key, 0444)) == -1) {
16311767SAnurag.Maskey@Sun.COM 		rc = nwam_errno_to_nwam_error(errno);
16411767SAnurag.Maskey@Sun.COM 		goto exit;
16511767SAnurag.Maskey@Sun.COM 	}
16611767SAnurag.Maskey@Sun.COM 
16711767SAnurag.Maskey@Sun.COM exit:
16811767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_unlock(&event_mutex);
16911767SAnurag.Maskey@Sun.COM 
17011767SAnurag.Maskey@Sun.COM 	return (rc);
17111767SAnurag.Maskey@Sun.COM }
17211767SAnurag.Maskey@Sun.COM 
17311767SAnurag.Maskey@Sun.COM /*
17411767SAnurag.Maskey@Sun.COM  * Un-register for receipt of events from nwamd.  Make a request to nwamd
17511767SAnurag.Maskey@Sun.COM  * to destroy the message queue.
17611767SAnurag.Maskey@Sun.COM  */
17711767SAnurag.Maskey@Sun.COM void
nwam_events_fini(void)17811767SAnurag.Maskey@Sun.COM nwam_events_fini(void)
17911767SAnurag.Maskey@Sun.COM {
18011767SAnurag.Maskey@Sun.COM 	char eventmsgfile[MAXPATHLEN];
18111767SAnurag.Maskey@Sun.COM 
18211767SAnurag.Maskey@Sun.COM 	(void) snprintf(eventmsgfile, sizeof (eventmsgfile), "%s.%d",
18311767SAnurag.Maskey@Sun.COM 	    NWAM_EVENT_MSG_FILE_PREFIX, getpid());
18411767SAnurag.Maskey@Sun.COM 
18511767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_lock(&event_mutex);
18611767SAnurag.Maskey@Sun.COM 
18711767SAnurag.Maskey@Sun.COM 	(void) nwam_request_register_unregister
18811767SAnurag.Maskey@Sun.COM 	    (NWAM_REQUEST_TYPE_EVENT_UNREGISTER, eventmsgfile);
18911767SAnurag.Maskey@Sun.COM 
19011767SAnurag.Maskey@Sun.COM 	event_msqid = -1;
19111767SAnurag.Maskey@Sun.COM 
19211767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_unlock(&event_mutex);
19311767SAnurag.Maskey@Sun.COM }
19411767SAnurag.Maskey@Sun.COM 
19511767SAnurag.Maskey@Sun.COM /*
19611767SAnurag.Maskey@Sun.COM  * Create an event queue.  Called by nwamd to create System V message queues
19711767SAnurag.Maskey@Sun.COM  * for clients to listen for events.
19811767SAnurag.Maskey@Sun.COM  */
19911767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_event_queue_init(const char * eventmsgfile)20011767SAnurag.Maskey@Sun.COM nwam_event_queue_init(const char *eventmsgfile)
20111767SAnurag.Maskey@Sun.COM {
20211767SAnurag.Maskey@Sun.COM 	int fd;
20311767SAnurag.Maskey@Sun.COM 	key_t key;
20411767SAnurag.Maskey@Sun.COM 
20511767SAnurag.Maskey@Sun.COM 	if ((fd = open(eventmsgfile, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1)
20611767SAnurag.Maskey@Sun.COM 		return (nwam_errno_to_nwam_error(errno));
20711767SAnurag.Maskey@Sun.COM 	(void) close(fd);
20811767SAnurag.Maskey@Sun.COM 
20911767SAnurag.Maskey@Sun.COM 	if ((key = ftok(eventmsgfile, 0)) == -1)
21011767SAnurag.Maskey@Sun.COM 		return (nwam_errno_to_nwam_error(errno));
21111767SAnurag.Maskey@Sun.COM 
21211767SAnurag.Maskey@Sun.COM 	if (msgget(key, 0644 | IPC_CREAT) == -1)
21311767SAnurag.Maskey@Sun.COM 		return (nwam_errno_to_nwam_error(errno));
21411767SAnurag.Maskey@Sun.COM 
21511767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
21611767SAnurag.Maskey@Sun.COM }
21711767SAnurag.Maskey@Sun.COM 
21811767SAnurag.Maskey@Sun.COM /*
21911767SAnurag.Maskey@Sun.COM  * Send event to registered listeners via the set of registered System V
22011767SAnurag.Maskey@Sun.COM  * message queues.
22111767SAnurag.Maskey@Sun.COM  */
22211767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_event_send(nwam_event_t event)22311767SAnurag.Maskey@Sun.COM nwam_event_send(nwam_event_t event)
22411767SAnurag.Maskey@Sun.COM {
22511767SAnurag.Maskey@Sun.COM 	DIR *dirp;
22611767SAnurag.Maskey@Sun.COM 	struct dirent *dp;
22711767SAnurag.Maskey@Sun.COM 	struct msqid_ds buf;
22811767SAnurag.Maskey@Sun.COM 	key_t key;
22911767SAnurag.Maskey@Sun.COM 	int msqid;
23011767SAnurag.Maskey@Sun.COM 	char eventmsgfile[MAXPATHLEN];
23111767SAnurag.Maskey@Sun.COM 	nwam_error_t err = NWAM_SUCCESS;
23211767SAnurag.Maskey@Sun.COM 
23311767SAnurag.Maskey@Sun.COM 	if ((dirp = opendir(NWAM_EVENT_MSG_DIR)) == NULL) {
23411767SAnurag.Maskey@Sun.COM 		return (nwam_errno_to_nwam_error(errno));
23511767SAnurag.Maskey@Sun.COM 	}
23611767SAnurag.Maskey@Sun.COM 
23711767SAnurag.Maskey@Sun.COM 	/*
23811767SAnurag.Maskey@Sun.COM 	 * For each file matching our event message queue file prefix,
23911767SAnurag.Maskey@Sun.COM 	 * check the queue is still being read, and if so send the message.
24011767SAnurag.Maskey@Sun.COM 	 */
24111767SAnurag.Maskey@Sun.COM 	while ((dp = readdir(dirp)) != NULL) {
24211767SAnurag.Maskey@Sun.COM 		if (strncmp(dp->d_name, NWAM_EVENT_MSG_FILE,
24311767SAnurag.Maskey@Sun.COM 		    strlen(NWAM_EVENT_MSG_FILE)) != 0)
24411767SAnurag.Maskey@Sun.COM 			continue;
24511767SAnurag.Maskey@Sun.COM 
24611767SAnurag.Maskey@Sun.COM 		(void) snprintf(eventmsgfile, sizeof (eventmsgfile), "%s/%s",
24711767SAnurag.Maskey@Sun.COM 		    NWAM_EVENT_MSG_DIR, dp->d_name);
24811767SAnurag.Maskey@Sun.COM 
24911767SAnurag.Maskey@Sun.COM 		if ((key = ftok(eventmsgfile, 0)) == -1) {
25011767SAnurag.Maskey@Sun.COM 			int errno_save = errno;
25111767SAnurag.Maskey@Sun.COM 			syslog(LOG_INFO, "nwam_event_send: ftok: %s",
25211767SAnurag.Maskey@Sun.COM 			    strerror(errno_save));
25311767SAnurag.Maskey@Sun.COM 			err = nwam_errno_to_nwam_error(errno_save);
25411767SAnurag.Maskey@Sun.COM 			continue;
25511767SAnurag.Maskey@Sun.COM 		}
25611767SAnurag.Maskey@Sun.COM 
25711767SAnurag.Maskey@Sun.COM 		if ((msqid = msgget(key, 0644)) == -1) {
25811767SAnurag.Maskey@Sun.COM 			int errno_save = errno;
25911767SAnurag.Maskey@Sun.COM 			syslog(LOG_INFO, "nwam_event_send: msgget: %s",
26011767SAnurag.Maskey@Sun.COM 			    strerror(errno_save));
26111767SAnurag.Maskey@Sun.COM 			err = nwam_errno_to_nwam_error(errno_save);
26211767SAnurag.Maskey@Sun.COM 			continue;
26311767SAnurag.Maskey@Sun.COM 		}
26411767SAnurag.Maskey@Sun.COM 
26511767SAnurag.Maskey@Sun.COM 		/* Retrieve stats to analyse queue activity */
26611767SAnurag.Maskey@Sun.COM 		if (msgctl(msqid, IPC_STAT, &buf) == -1) {
26711767SAnurag.Maskey@Sun.COM 			int errno_save = errno;
26811767SAnurag.Maskey@Sun.COM 			syslog(LOG_INFO, "nwam_event_send: msgctl: %s",
26911767SAnurag.Maskey@Sun.COM 			    strerror(errno_save));
27011767SAnurag.Maskey@Sun.COM 			err = nwam_errno_to_nwam_error(errno_save);
27111767SAnurag.Maskey@Sun.COM 			continue;
27211767SAnurag.Maskey@Sun.COM 		}
27311767SAnurag.Maskey@Sun.COM 		/*
27411767SAnurag.Maskey@Sun.COM 		 * If buf.msg_qnum > NWAM_EVENT_MAX_NUM_PENDING
27511767SAnurag.Maskey@Sun.COM 		 * _and_ msg_stime is more than 10s after msg_rtime -
27611767SAnurag.Maskey@Sun.COM 		 * indicating message(s) have been hanging around unclaimed -
27711767SAnurag.Maskey@Sun.COM 		 * we destroy the queue as the client has most likely gone
27811767SAnurag.Maskey@Sun.COM 		 * away. This can happen if a registered client hits Ctrl^C.
27911767SAnurag.Maskey@Sun.COM 		 */
28011767SAnurag.Maskey@Sun.COM 		if (buf.msg_qnum > NWAM_EVENT_MAX_NUM_PENDING &&
28111767SAnurag.Maskey@Sun.COM 		    ((buf.msg_stime + NWAM_EVENT_WAIT_TIME) > buf.msg_rtime)) {
28211767SAnurag.Maskey@Sun.COM 			nwam_event_queue_fini(eventmsgfile);
28311767SAnurag.Maskey@Sun.COM 			continue;
28411767SAnurag.Maskey@Sun.COM 		}
28511767SAnurag.Maskey@Sun.COM 
28611767SAnurag.Maskey@Sun.COM 		/*
28711767SAnurag.Maskey@Sun.COM 		 * This shouldn't ever block.  If it does then log an error and
28811767SAnurag.Maskey@Sun.COM 		 * clean up the queue.
28911767SAnurag.Maskey@Sun.COM 		 */
29011767SAnurag.Maskey@Sun.COM 		if (msgsnd(msqid, (struct msgbuf *)event, event->nwe_size,
29111767SAnurag.Maskey@Sun.COM 		    IPC_NOWAIT) == -1) {
29211767SAnurag.Maskey@Sun.COM 			int errno_save = errno;
29311767SAnurag.Maskey@Sun.COM 			syslog(LOG_ERR, "nwam_event_send: msgsnd: %s, "
29411767SAnurag.Maskey@Sun.COM 			    "destroying message queue %s", strerror(errno_save),
29511767SAnurag.Maskey@Sun.COM 			    eventmsgfile);
29611767SAnurag.Maskey@Sun.COM 			nwam_event_queue_fini(eventmsgfile);
29711767SAnurag.Maskey@Sun.COM 			err = nwam_errno_to_nwam_error(errno_save);
29811767SAnurag.Maskey@Sun.COM 			continue;
29911767SAnurag.Maskey@Sun.COM 		}
30011767SAnurag.Maskey@Sun.COM 
30111767SAnurag.Maskey@Sun.COM 	}
30211767SAnurag.Maskey@Sun.COM 	(void) closedir(dirp);
30311767SAnurag.Maskey@Sun.COM 
30411767SAnurag.Maskey@Sun.COM 	return (err);
30511767SAnurag.Maskey@Sun.COM }
30611767SAnurag.Maskey@Sun.COM 
30711767SAnurag.Maskey@Sun.COM /*
30811767SAnurag.Maskey@Sun.COM  * Destroy an event queue.  Called by nwamd to destroy the associated message
30911767SAnurag.Maskey@Sun.COM  * queue.
31011767SAnurag.Maskey@Sun.COM  */
31111767SAnurag.Maskey@Sun.COM void
nwam_event_queue_fini(const char * eventmsgfile)31211767SAnurag.Maskey@Sun.COM nwam_event_queue_fini(const char *eventmsgfile)
31311767SAnurag.Maskey@Sun.COM {
31411767SAnurag.Maskey@Sun.COM 	key_t key;
31511767SAnurag.Maskey@Sun.COM 	int msqid;
31611767SAnurag.Maskey@Sun.COM 
31711767SAnurag.Maskey@Sun.COM 	if ((key = ftok(eventmsgfile, 0)) != -1 &&
31811767SAnurag.Maskey@Sun.COM 	    (msqid = msgget(key, 0644)) != -1 &&
31911767SAnurag.Maskey@Sun.COM 	    msgctl(msqid, IPC_RMID, NULL) != -1)
32011767SAnurag.Maskey@Sun.COM 		(void) unlink(eventmsgfile);
32111767SAnurag.Maskey@Sun.COM }
32211767SAnurag.Maskey@Sun.COM 
32311767SAnurag.Maskey@Sun.COM /*
32411767SAnurag.Maskey@Sun.COM  * Stop sending events.  Called by nwamd to destroy each System V message queue
32511767SAnurag.Maskey@Sun.COM  * registered.
32611767SAnurag.Maskey@Sun.COM  */
32711767SAnurag.Maskey@Sun.COM void
nwam_event_send_fini(void)32811767SAnurag.Maskey@Sun.COM nwam_event_send_fini(void)
32911767SAnurag.Maskey@Sun.COM {
33011767SAnurag.Maskey@Sun.COM 	DIR *dirp;
33111767SAnurag.Maskey@Sun.COM 	struct dirent *dp;
33211767SAnurag.Maskey@Sun.COM 	char eventmsgfile[MAXPATHLEN];
33311767SAnurag.Maskey@Sun.COM 
33411767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_lock(&event_mutex);
33511767SAnurag.Maskey@Sun.COM 
33611767SAnurag.Maskey@Sun.COM 	if ((dirp = opendir(NWAM_EVENT_MSG_DIR)) == NULL) {
33711767SAnurag.Maskey@Sun.COM 		(void) pthread_mutex_unlock(&event_mutex);
33811767SAnurag.Maskey@Sun.COM 		return;
33911767SAnurag.Maskey@Sun.COM 	}
34011767SAnurag.Maskey@Sun.COM 
34111767SAnurag.Maskey@Sun.COM 	/*
34211767SAnurag.Maskey@Sun.COM 	 * For each file matching our event message queue file prefix,
34311767SAnurag.Maskey@Sun.COM 	 * destroy the queue and message file.
34411767SAnurag.Maskey@Sun.COM 	 */
34511767SAnurag.Maskey@Sun.COM 	while ((dp = readdir(dirp)) != NULL) {
34611767SAnurag.Maskey@Sun.COM 		if (strncmp(dp->d_name, NWAM_EVENT_MSG_FILE,
34711767SAnurag.Maskey@Sun.COM 		    strlen(NWAM_EVENT_MSG_FILE)) != 0)
34811767SAnurag.Maskey@Sun.COM 			continue;
34911767SAnurag.Maskey@Sun.COM 
35011767SAnurag.Maskey@Sun.COM 		(void) snprintf(eventmsgfile, sizeof (eventmsgfile), "%s/%s",
35111767SAnurag.Maskey@Sun.COM 		    NWAM_EVENT_MSG_DIR, dp->d_name);
35211767SAnurag.Maskey@Sun.COM 
35311767SAnurag.Maskey@Sun.COM 		nwam_event_queue_fini(eventmsgfile);
35411767SAnurag.Maskey@Sun.COM 	}
35511767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_unlock(&event_mutex);
35611767SAnurag.Maskey@Sun.COM }
357