1*11767SAnurag.Maskey@Sun.COM /* 2*11767SAnurag.Maskey@Sun.COM * CDDL HEADER START 3*11767SAnurag.Maskey@Sun.COM * 4*11767SAnurag.Maskey@Sun.COM * The contents of this file are subject to the terms of the 5*11767SAnurag.Maskey@Sun.COM * Common Development and Distribution License (the "License"). 6*11767SAnurag.Maskey@Sun.COM * You may not use this file except in compliance with the License. 7*11767SAnurag.Maskey@Sun.COM * 8*11767SAnurag.Maskey@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*11767SAnurag.Maskey@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*11767SAnurag.Maskey@Sun.COM * See the License for the specific language governing permissions 11*11767SAnurag.Maskey@Sun.COM * and limitations under the License. 12*11767SAnurag.Maskey@Sun.COM * 13*11767SAnurag.Maskey@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*11767SAnurag.Maskey@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*11767SAnurag.Maskey@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*11767SAnurag.Maskey@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*11767SAnurag.Maskey@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*11767SAnurag.Maskey@Sun.COM * 19*11767SAnurag.Maskey@Sun.COM * CDDL HEADER END 20*11767SAnurag.Maskey@Sun.COM */ 21*11767SAnurag.Maskey@Sun.COM 22*11767SAnurag.Maskey@Sun.COM /* 23*11767SAnurag.Maskey@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24*11767SAnurag.Maskey@Sun.COM * Use is subject to license terms. 25*11767SAnurag.Maskey@Sun.COM */ 26*11767SAnurag.Maskey@Sun.COM 27*11767SAnurag.Maskey@Sun.COM #include <assert.h> 28*11767SAnurag.Maskey@Sun.COM #include <dirent.h> 29*11767SAnurag.Maskey@Sun.COM #include <errno.h> 30*11767SAnurag.Maskey@Sun.COM #include <fcntl.h> 31*11767SAnurag.Maskey@Sun.COM #include <pthread.h> 32*11767SAnurag.Maskey@Sun.COM #include <stdio.h> 33*11767SAnurag.Maskey@Sun.COM #include <stdlib.h> 34*11767SAnurag.Maskey@Sun.COM #include <strings.h> 35*11767SAnurag.Maskey@Sun.COM #include <string.h> 36*11767SAnurag.Maskey@Sun.COM #include <syslog.h> 37*11767SAnurag.Maskey@Sun.COM #include <sys/msg.h> 38*11767SAnurag.Maskey@Sun.COM #include <sys/stat.h> 39*11767SAnurag.Maskey@Sun.COM #include <sys/types.h> 40*11767SAnurag.Maskey@Sun.COM #include <unistd.h> 41*11767SAnurag.Maskey@Sun.COM 42*11767SAnurag.Maskey@Sun.COM #include "libnwam_impl.h" 43*11767SAnurag.Maskey@Sun.COM #include <libnwam_priv.h> 44*11767SAnurag.Maskey@Sun.COM #include <libnwam.h> 45*11767SAnurag.Maskey@Sun.COM 46*11767SAnurag.Maskey@Sun.COM /* 47*11767SAnurag.Maskey@Sun.COM * Implementation of event notification mechanism used by the GUI and 48*11767SAnurag.Maskey@Sun.COM * nwamadm. Clients register for events via nwam_events_init() and 49*11767SAnurag.Maskey@Sun.COM * unregister via nwam_events_fini(). nwamd sends events via nwam_event_send() 50*11767SAnurag.Maskey@Sun.COM * and applications block waiting for a new event to be delivered in 51*11767SAnurag.Maskey@Sun.COM * nwam_event_wait(). Events are implemented as System V message queues, 52*11767SAnurag.Maskey@Sun.COM * one per event client. The event mechanism has to be resilient to 53*11767SAnurag.Maskey@Sun.COM * nwamd restarts so that clients do not lose the event connection. 54*11767SAnurag.Maskey@Sun.COM */ 55*11767SAnurag.Maskey@Sun.COM 56*11767SAnurag.Maskey@Sun.COM #define NWAM_EVENT_MSG_DIR "/etc/svc/volatile/nwam/" 57*11767SAnurag.Maskey@Sun.COM #define NWAM_EVENT_MSG_FILE "nwam_event_msgs" 58*11767SAnurag.Maskey@Sun.COM #define NWAM_EVENT_MSG_FILE_PREFIX NWAM_EVENT_MSG_DIR NWAM_EVENT_MSG_FILE 59*11767SAnurag.Maskey@Sun.COM #define NWAM_EVENT_MAX_NUM_WLANS 32 60*11767SAnurag.Maskey@Sun.COM #define NWAM_EVENT_MAX_SIZE (sizeof (struct nwam_event) + \ 61*11767SAnurag.Maskey@Sun.COM (NWAM_EVENT_MAX_NUM_WLANS * sizeof (nwam_wlan_t))) 62*11767SAnurag.Maskey@Sun.COM #define NWAM_EVENT_WAIT_TIME 10 63*11767SAnurag.Maskey@Sun.COM #define NWAM_EVENT_MAX_NUM_PENDING 25 64*11767SAnurag.Maskey@Sun.COM 65*11767SAnurag.Maskey@Sun.COM /* 66*11767SAnurag.Maskey@Sun.COM * This is protecting simultaneous access to the msqid and its configuration. 67*11767SAnurag.Maskey@Sun.COM */ 68*11767SAnurag.Maskey@Sun.COM static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER; 69*11767SAnurag.Maskey@Sun.COM static int event_msqid = -1; 70*11767SAnurag.Maskey@Sun.COM 71*11767SAnurag.Maskey@Sun.COM static nwam_error_t 72*11767SAnurag.Maskey@Sun.COM nwam_event_alloc(nwam_event_t *eventp) 73*11767SAnurag.Maskey@Sun.COM { 74*11767SAnurag.Maskey@Sun.COM assert(eventp != NULL); 75*11767SAnurag.Maskey@Sun.COM 76*11767SAnurag.Maskey@Sun.COM *eventp = calloc(1, NWAM_EVENT_MAX_SIZE); 77*11767SAnurag.Maskey@Sun.COM if (*eventp == NULL) 78*11767SAnurag.Maskey@Sun.COM return (NWAM_NO_MEMORY); 79*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 80*11767SAnurag.Maskey@Sun.COM } 81*11767SAnurag.Maskey@Sun.COM 82*11767SAnurag.Maskey@Sun.COM void 83*11767SAnurag.Maskey@Sun.COM nwam_event_free(nwam_event_t event) 84*11767SAnurag.Maskey@Sun.COM { 85*11767SAnurag.Maskey@Sun.COM if (event != NULL) 86*11767SAnurag.Maskey@Sun.COM free(event); 87*11767SAnurag.Maskey@Sun.COM } 88*11767SAnurag.Maskey@Sun.COM 89*11767SAnurag.Maskey@Sun.COM /* 90*11767SAnurag.Maskey@Sun.COM * Get next event in queue. 91*11767SAnurag.Maskey@Sun.COM */ 92*11767SAnurag.Maskey@Sun.COM nwam_error_t 93*11767SAnurag.Maskey@Sun.COM nwam_event_wait(nwam_event_t *eventp) 94*11767SAnurag.Maskey@Sun.COM { 95*11767SAnurag.Maskey@Sun.COM nwam_error_t err; 96*11767SAnurag.Maskey@Sun.COM nwam_event_t event; 97*11767SAnurag.Maskey@Sun.COM 98*11767SAnurag.Maskey@Sun.COM assert(eventp != NULL); 99*11767SAnurag.Maskey@Sun.COM 100*11767SAnurag.Maskey@Sun.COM if ((err = nwam_event_alloc(&event)) != NWAM_SUCCESS) 101*11767SAnurag.Maskey@Sun.COM return (err); 102*11767SAnurag.Maskey@Sun.COM while (msgrcv(event_msqid, (struct msgbuf *)event, NWAM_EVENT_MAX_SIZE, 103*11767SAnurag.Maskey@Sun.COM 0, 0) == -1) { 104*11767SAnurag.Maskey@Sun.COM switch (errno) { 105*11767SAnurag.Maskey@Sun.COM case EAGAIN: 106*11767SAnurag.Maskey@Sun.COM case EBUSY: 107*11767SAnurag.Maskey@Sun.COM /* 108*11767SAnurag.Maskey@Sun.COM * We see this errno eventhough it isn't 109*11767SAnurag.Maskey@Sun.COM * documented. Try again. If this causes 110*11767SAnurag.Maskey@Sun.COM * a busy loop then grab a trace otherwise 111*11767SAnurag.Maskey@Sun.COM * it's a brace 'til we can figure out why it 112*11767SAnurag.Maskey@Sun.COM * happens. 113*11767SAnurag.Maskey@Sun.COM */ 114*11767SAnurag.Maskey@Sun.COM continue; 115*11767SAnurag.Maskey@Sun.COM 116*11767SAnurag.Maskey@Sun.COM default: 117*11767SAnurag.Maskey@Sun.COM nwam_event_free(event); 118*11767SAnurag.Maskey@Sun.COM return (nwam_errno_to_nwam_error(errno)); 119*11767SAnurag.Maskey@Sun.COM } 120*11767SAnurag.Maskey@Sun.COM } 121*11767SAnurag.Maskey@Sun.COM 122*11767SAnurag.Maskey@Sun.COM /* Resize event down from maximum size */ 123*11767SAnurag.Maskey@Sun.COM if ((*eventp = realloc(event, event->nwe_size)) == NULL) 124*11767SAnurag.Maskey@Sun.COM return (NWAM_NO_MEMORY); 125*11767SAnurag.Maskey@Sun.COM 126*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 127*11767SAnurag.Maskey@Sun.COM } 128*11767SAnurag.Maskey@Sun.COM 129*11767SAnurag.Maskey@Sun.COM /* 130*11767SAnurag.Maskey@Sun.COM * Register for receipt of events from nwamd. Event delivery is 131*11767SAnurag.Maskey@Sun.COM * done via a System V message queue. 132*11767SAnurag.Maskey@Sun.COM */ 133*11767SAnurag.Maskey@Sun.COM nwam_error_t 134*11767SAnurag.Maskey@Sun.COM nwam_events_init(void) 135*11767SAnurag.Maskey@Sun.COM { 136*11767SAnurag.Maskey@Sun.COM char eventmsgfile[MAXPATHLEN]; 137*11767SAnurag.Maskey@Sun.COM nwam_error_t err; 138*11767SAnurag.Maskey@Sun.COM nwam_error_t rc = NWAM_SUCCESS; 139*11767SAnurag.Maskey@Sun.COM key_t key; 140*11767SAnurag.Maskey@Sun.COM 141*11767SAnurag.Maskey@Sun.COM (void) snprintf(eventmsgfile, sizeof (eventmsgfile), "%s.%d", 142*11767SAnurag.Maskey@Sun.COM NWAM_EVENT_MSG_FILE_PREFIX, getpid()); 143*11767SAnurag.Maskey@Sun.COM 144*11767SAnurag.Maskey@Sun.COM (void) pthread_mutex_lock(&event_mutex); 145*11767SAnurag.Maskey@Sun.COM 146*11767SAnurag.Maskey@Sun.COM if (event_msqid != -1) { 147*11767SAnurag.Maskey@Sun.COM rc = NWAM_ENTITY_IN_USE; 148*11767SAnurag.Maskey@Sun.COM goto exit; 149*11767SAnurag.Maskey@Sun.COM } 150*11767SAnurag.Maskey@Sun.COM 151*11767SAnurag.Maskey@Sun.COM if ((err = nwam_request_register_unregister 152*11767SAnurag.Maskey@Sun.COM (NWAM_REQUEST_TYPE_EVENT_REGISTER, eventmsgfile)) != NWAM_SUCCESS) { 153*11767SAnurag.Maskey@Sun.COM rc = err; 154*11767SAnurag.Maskey@Sun.COM goto exit; 155*11767SAnurag.Maskey@Sun.COM } 156*11767SAnurag.Maskey@Sun.COM 157*11767SAnurag.Maskey@Sun.COM if ((key = ftok(eventmsgfile, 0)) == -1) { 158*11767SAnurag.Maskey@Sun.COM rc = nwam_errno_to_nwam_error(errno); 159*11767SAnurag.Maskey@Sun.COM goto exit; 160*11767SAnurag.Maskey@Sun.COM } 161*11767SAnurag.Maskey@Sun.COM 162*11767SAnurag.Maskey@Sun.COM /* Get system-wide message queue ID */ 163*11767SAnurag.Maskey@Sun.COM if ((event_msqid = msgget(key, 0444)) == -1) { 164*11767SAnurag.Maskey@Sun.COM rc = nwam_errno_to_nwam_error(errno); 165*11767SAnurag.Maskey@Sun.COM goto exit; 166*11767SAnurag.Maskey@Sun.COM } 167*11767SAnurag.Maskey@Sun.COM 168*11767SAnurag.Maskey@Sun.COM exit: 169*11767SAnurag.Maskey@Sun.COM (void) pthread_mutex_unlock(&event_mutex); 170*11767SAnurag.Maskey@Sun.COM 171*11767SAnurag.Maskey@Sun.COM return (rc); 172*11767SAnurag.Maskey@Sun.COM } 173*11767SAnurag.Maskey@Sun.COM 174*11767SAnurag.Maskey@Sun.COM /* 175*11767SAnurag.Maskey@Sun.COM * Un-register for receipt of events from nwamd. Make a request to nwamd 176*11767SAnurag.Maskey@Sun.COM * to destroy the message queue. 177*11767SAnurag.Maskey@Sun.COM */ 178*11767SAnurag.Maskey@Sun.COM void 179*11767SAnurag.Maskey@Sun.COM nwam_events_fini(void) 180*11767SAnurag.Maskey@Sun.COM { 181*11767SAnurag.Maskey@Sun.COM char eventmsgfile[MAXPATHLEN]; 182*11767SAnurag.Maskey@Sun.COM 183*11767SAnurag.Maskey@Sun.COM (void) snprintf(eventmsgfile, sizeof (eventmsgfile), "%s.%d", 184*11767SAnurag.Maskey@Sun.COM NWAM_EVENT_MSG_FILE_PREFIX, getpid()); 185*11767SAnurag.Maskey@Sun.COM 186*11767SAnurag.Maskey@Sun.COM (void) pthread_mutex_lock(&event_mutex); 187*11767SAnurag.Maskey@Sun.COM 188*11767SAnurag.Maskey@Sun.COM (void) nwam_request_register_unregister 189*11767SAnurag.Maskey@Sun.COM (NWAM_REQUEST_TYPE_EVENT_UNREGISTER, eventmsgfile); 190*11767SAnurag.Maskey@Sun.COM 191*11767SAnurag.Maskey@Sun.COM event_msqid = -1; 192*11767SAnurag.Maskey@Sun.COM 193*11767SAnurag.Maskey@Sun.COM (void) pthread_mutex_unlock(&event_mutex); 194*11767SAnurag.Maskey@Sun.COM } 195*11767SAnurag.Maskey@Sun.COM 196*11767SAnurag.Maskey@Sun.COM /* 197*11767SAnurag.Maskey@Sun.COM * Create an event queue. Called by nwamd to create System V message queues 198*11767SAnurag.Maskey@Sun.COM * for clients to listen for events. 199*11767SAnurag.Maskey@Sun.COM */ 200*11767SAnurag.Maskey@Sun.COM nwam_error_t 201*11767SAnurag.Maskey@Sun.COM nwam_event_queue_init(const char *eventmsgfile) 202*11767SAnurag.Maskey@Sun.COM { 203*11767SAnurag.Maskey@Sun.COM int fd; 204*11767SAnurag.Maskey@Sun.COM key_t key; 205*11767SAnurag.Maskey@Sun.COM 206*11767SAnurag.Maskey@Sun.COM if ((fd = open(eventmsgfile, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1) 207*11767SAnurag.Maskey@Sun.COM return (nwam_errno_to_nwam_error(errno)); 208*11767SAnurag.Maskey@Sun.COM (void) close(fd); 209*11767SAnurag.Maskey@Sun.COM 210*11767SAnurag.Maskey@Sun.COM if ((key = ftok(eventmsgfile, 0)) == -1) 211*11767SAnurag.Maskey@Sun.COM return (nwam_errno_to_nwam_error(errno)); 212*11767SAnurag.Maskey@Sun.COM 213*11767SAnurag.Maskey@Sun.COM if (msgget(key, 0644 | IPC_CREAT) == -1) 214*11767SAnurag.Maskey@Sun.COM return (nwam_errno_to_nwam_error(errno)); 215*11767SAnurag.Maskey@Sun.COM 216*11767SAnurag.Maskey@Sun.COM return (NWAM_SUCCESS); 217*11767SAnurag.Maskey@Sun.COM } 218*11767SAnurag.Maskey@Sun.COM 219*11767SAnurag.Maskey@Sun.COM /* 220*11767SAnurag.Maskey@Sun.COM * Send event to registered listeners via the set of registered System V 221*11767SAnurag.Maskey@Sun.COM * message queues. 222*11767SAnurag.Maskey@Sun.COM */ 223*11767SAnurag.Maskey@Sun.COM nwam_error_t 224*11767SAnurag.Maskey@Sun.COM nwam_event_send(nwam_event_t event) 225*11767SAnurag.Maskey@Sun.COM { 226*11767SAnurag.Maskey@Sun.COM DIR *dirp; 227*11767SAnurag.Maskey@Sun.COM struct dirent *dp; 228*11767SAnurag.Maskey@Sun.COM struct msqid_ds buf; 229*11767SAnurag.Maskey@Sun.COM key_t key; 230*11767SAnurag.Maskey@Sun.COM int msqid; 231*11767SAnurag.Maskey@Sun.COM char eventmsgfile[MAXPATHLEN]; 232*11767SAnurag.Maskey@Sun.COM nwam_error_t err = NWAM_SUCCESS; 233*11767SAnurag.Maskey@Sun.COM 234*11767SAnurag.Maskey@Sun.COM if ((dirp = opendir(NWAM_EVENT_MSG_DIR)) == NULL) { 235*11767SAnurag.Maskey@Sun.COM return (nwam_errno_to_nwam_error(errno)); 236*11767SAnurag.Maskey@Sun.COM } 237*11767SAnurag.Maskey@Sun.COM 238*11767SAnurag.Maskey@Sun.COM /* 239*11767SAnurag.Maskey@Sun.COM * For each file matching our event message queue file prefix, 240*11767SAnurag.Maskey@Sun.COM * check the queue is still being read, and if so send the message. 241*11767SAnurag.Maskey@Sun.COM */ 242*11767SAnurag.Maskey@Sun.COM while ((dp = readdir(dirp)) != NULL) { 243*11767SAnurag.Maskey@Sun.COM if (strncmp(dp->d_name, NWAM_EVENT_MSG_FILE, 244*11767SAnurag.Maskey@Sun.COM strlen(NWAM_EVENT_MSG_FILE)) != 0) 245*11767SAnurag.Maskey@Sun.COM continue; 246*11767SAnurag.Maskey@Sun.COM 247*11767SAnurag.Maskey@Sun.COM (void) snprintf(eventmsgfile, sizeof (eventmsgfile), "%s/%s", 248*11767SAnurag.Maskey@Sun.COM NWAM_EVENT_MSG_DIR, dp->d_name); 249*11767SAnurag.Maskey@Sun.COM 250*11767SAnurag.Maskey@Sun.COM if ((key = ftok(eventmsgfile, 0)) == -1) { 251*11767SAnurag.Maskey@Sun.COM int errno_save = errno; 252*11767SAnurag.Maskey@Sun.COM syslog(LOG_INFO, "nwam_event_send: ftok: %s", 253*11767SAnurag.Maskey@Sun.COM strerror(errno_save)); 254*11767SAnurag.Maskey@Sun.COM err = nwam_errno_to_nwam_error(errno_save); 255*11767SAnurag.Maskey@Sun.COM continue; 256*11767SAnurag.Maskey@Sun.COM } 257*11767SAnurag.Maskey@Sun.COM 258*11767SAnurag.Maskey@Sun.COM if ((msqid = msgget(key, 0644)) == -1) { 259*11767SAnurag.Maskey@Sun.COM int errno_save = errno; 260*11767SAnurag.Maskey@Sun.COM syslog(LOG_INFO, "nwam_event_send: msgget: %s", 261*11767SAnurag.Maskey@Sun.COM strerror(errno_save)); 262*11767SAnurag.Maskey@Sun.COM err = nwam_errno_to_nwam_error(errno_save); 263*11767SAnurag.Maskey@Sun.COM continue; 264*11767SAnurag.Maskey@Sun.COM } 265*11767SAnurag.Maskey@Sun.COM 266*11767SAnurag.Maskey@Sun.COM /* Retrieve stats to analyse queue activity */ 267*11767SAnurag.Maskey@Sun.COM if (msgctl(msqid, IPC_STAT, &buf) == -1) { 268*11767SAnurag.Maskey@Sun.COM int errno_save = errno; 269*11767SAnurag.Maskey@Sun.COM syslog(LOG_INFO, "nwam_event_send: msgctl: %s", 270*11767SAnurag.Maskey@Sun.COM strerror(errno_save)); 271*11767SAnurag.Maskey@Sun.COM err = nwam_errno_to_nwam_error(errno_save); 272*11767SAnurag.Maskey@Sun.COM continue; 273*11767SAnurag.Maskey@Sun.COM } 274*11767SAnurag.Maskey@Sun.COM /* 275*11767SAnurag.Maskey@Sun.COM * If buf.msg_qnum > NWAM_EVENT_MAX_NUM_PENDING 276*11767SAnurag.Maskey@Sun.COM * _and_ msg_stime is more than 10s after msg_rtime - 277*11767SAnurag.Maskey@Sun.COM * indicating message(s) have been hanging around unclaimed - 278*11767SAnurag.Maskey@Sun.COM * we destroy the queue as the client has most likely gone 279*11767SAnurag.Maskey@Sun.COM * away. This can happen if a registered client hits Ctrl^C. 280*11767SAnurag.Maskey@Sun.COM */ 281*11767SAnurag.Maskey@Sun.COM if (buf.msg_qnum > NWAM_EVENT_MAX_NUM_PENDING && 282*11767SAnurag.Maskey@Sun.COM ((buf.msg_stime + NWAM_EVENT_WAIT_TIME) > buf.msg_rtime)) { 283*11767SAnurag.Maskey@Sun.COM nwam_event_queue_fini(eventmsgfile); 284*11767SAnurag.Maskey@Sun.COM continue; 285*11767SAnurag.Maskey@Sun.COM } 286*11767SAnurag.Maskey@Sun.COM 287*11767SAnurag.Maskey@Sun.COM /* 288*11767SAnurag.Maskey@Sun.COM * This shouldn't ever block. If it does then log an error and 289*11767SAnurag.Maskey@Sun.COM * clean up the queue. 290*11767SAnurag.Maskey@Sun.COM */ 291*11767SAnurag.Maskey@Sun.COM if (msgsnd(msqid, (struct msgbuf *)event, event->nwe_size, 292*11767SAnurag.Maskey@Sun.COM IPC_NOWAIT) == -1) { 293*11767SAnurag.Maskey@Sun.COM int errno_save = errno; 294*11767SAnurag.Maskey@Sun.COM syslog(LOG_ERR, "nwam_event_send: msgsnd: %s, " 295*11767SAnurag.Maskey@Sun.COM "destroying message queue %s", strerror(errno_save), 296*11767SAnurag.Maskey@Sun.COM eventmsgfile); 297*11767SAnurag.Maskey@Sun.COM nwam_event_queue_fini(eventmsgfile); 298*11767SAnurag.Maskey@Sun.COM err = nwam_errno_to_nwam_error(errno_save); 299*11767SAnurag.Maskey@Sun.COM continue; 300*11767SAnurag.Maskey@Sun.COM } 301*11767SAnurag.Maskey@Sun.COM 302*11767SAnurag.Maskey@Sun.COM } 303*11767SAnurag.Maskey@Sun.COM (void) closedir(dirp); 304*11767SAnurag.Maskey@Sun.COM 305*11767SAnurag.Maskey@Sun.COM return (err); 306*11767SAnurag.Maskey@Sun.COM } 307*11767SAnurag.Maskey@Sun.COM 308*11767SAnurag.Maskey@Sun.COM /* 309*11767SAnurag.Maskey@Sun.COM * Destroy an event queue. Called by nwamd to destroy the associated message 310*11767SAnurag.Maskey@Sun.COM * queue. 311*11767SAnurag.Maskey@Sun.COM */ 312*11767SAnurag.Maskey@Sun.COM void 313*11767SAnurag.Maskey@Sun.COM nwam_event_queue_fini(const char *eventmsgfile) 314*11767SAnurag.Maskey@Sun.COM { 315*11767SAnurag.Maskey@Sun.COM key_t key; 316*11767SAnurag.Maskey@Sun.COM int msqid; 317*11767SAnurag.Maskey@Sun.COM 318*11767SAnurag.Maskey@Sun.COM if ((key = ftok(eventmsgfile, 0)) != -1 && 319*11767SAnurag.Maskey@Sun.COM (msqid = msgget(key, 0644)) != -1 && 320*11767SAnurag.Maskey@Sun.COM msgctl(msqid, IPC_RMID, NULL) != -1) 321*11767SAnurag.Maskey@Sun.COM (void) unlink(eventmsgfile); 322*11767SAnurag.Maskey@Sun.COM } 323*11767SAnurag.Maskey@Sun.COM 324*11767SAnurag.Maskey@Sun.COM /* 325*11767SAnurag.Maskey@Sun.COM * Stop sending events. Called by nwamd to destroy each System V message queue 326*11767SAnurag.Maskey@Sun.COM * registered. 327*11767SAnurag.Maskey@Sun.COM */ 328*11767SAnurag.Maskey@Sun.COM void 329*11767SAnurag.Maskey@Sun.COM nwam_event_send_fini(void) 330*11767SAnurag.Maskey@Sun.COM { 331*11767SAnurag.Maskey@Sun.COM DIR *dirp; 332*11767SAnurag.Maskey@Sun.COM struct dirent *dp; 333*11767SAnurag.Maskey@Sun.COM char eventmsgfile[MAXPATHLEN]; 334*11767SAnurag.Maskey@Sun.COM 335*11767SAnurag.Maskey@Sun.COM (void) pthread_mutex_lock(&event_mutex); 336*11767SAnurag.Maskey@Sun.COM 337*11767SAnurag.Maskey@Sun.COM if ((dirp = opendir(NWAM_EVENT_MSG_DIR)) == NULL) { 338*11767SAnurag.Maskey@Sun.COM (void) pthread_mutex_unlock(&event_mutex); 339*11767SAnurag.Maskey@Sun.COM return; 340*11767SAnurag.Maskey@Sun.COM } 341*11767SAnurag.Maskey@Sun.COM 342*11767SAnurag.Maskey@Sun.COM /* 343*11767SAnurag.Maskey@Sun.COM * For each file matching our event message queue file prefix, 344*11767SAnurag.Maskey@Sun.COM * destroy the queue and message file. 345*11767SAnurag.Maskey@Sun.COM */ 346*11767SAnurag.Maskey@Sun.COM while ((dp = readdir(dirp)) != NULL) { 347*11767SAnurag.Maskey@Sun.COM if (strncmp(dp->d_name, NWAM_EVENT_MSG_FILE, 348*11767SAnurag.Maskey@Sun.COM strlen(NWAM_EVENT_MSG_FILE)) != 0) 349*11767SAnurag.Maskey@Sun.COM continue; 350*11767SAnurag.Maskey@Sun.COM 351*11767SAnurag.Maskey@Sun.COM (void) snprintf(eventmsgfile, sizeof (eventmsgfile), "%s/%s", 352*11767SAnurag.Maskey@Sun.COM NWAM_EVENT_MSG_DIR, dp->d_name); 353*11767SAnurag.Maskey@Sun.COM 354*11767SAnurag.Maskey@Sun.COM nwam_event_queue_fini(eventmsgfile); 355*11767SAnurag.Maskey@Sun.COM } 356*11767SAnurag.Maskey@Sun.COM (void) pthread_mutex_unlock(&event_mutex); 357*11767SAnurag.Maskey@Sun.COM } 358