static int pdict_ent_remove_change_listeners(pdict_ent_t *pde) { plist_walk(pde->pde_listeners, pdict_ent_remove_change_listeners_cb, 0); plist_clear(&pde->pde_listeners); return 1; }
void plist_destroy(PList* plist) { if (!plist) { return; } plist_clear(plist); GMEM_DEL(plist, PList*, sizeof(PList)); }
/* Destroy the list freeing memory; the list can't be used after that. */ void plist_free (struct plist *plist) { assert (plist != NULL); plist_clear (plist); free (plist->items); plist->allocated = 0; plist->items = NULL; rb_tree_free (plist->search_tree); }
static ptree_walk_res_t free_na_cb(const void *v1, int level, void *a, void *pwra) { notify_arg_t *na = (notify_arg_t *)v1; plist_walk(na->na_pd_ids, remove_persistent_change_listener_cb, na->na_pdss->pdss_pd); free((void *)na->na_listenid); na->na_listenid = NULL; plist_clear(&na->na_pd_ids); free(na); na = NULL; return PTREE_WALK_CONTINUE; }
/* Step the game simulation by handling events, and drawing: */ int game_step(void *input) { GameData *gd = input; ASSERT_ACTIVE(); EventType temp; /* Handle all queued events: */ while( (temp=gamelib_event_get_type()) != GAME_EVENT_NONE ) { /* Trying to resize the window? */ if(temp == GAME_EVENT_RESIZE) { Rect r = gamelib_event_resize_get_size(); screen_resize(gd->data.active.s, r.w, r.h); /* Trying to toggle fullscreen? */ } else if(temp == GAME_EVENT_TOGGLE_FULLSCREEN) { screen_set_fullscreen(gd->data.active.s, -1); /* Trying to exit? */ } else if(temp == GAME_EVENT_EXIT) { return 1; } /* Done with this event: */ gamelib_event_done(); } /* Clear everything: */ tanklist_map(gd->data.active.tl, tank_clear(t, gd->data.active.b)); plist_clear (gd->data.active.pl, gd->data.active.b); /* Charge a small bit of energy for life: */ tanklist_map(gd->data.active.tl, tank_alter_energy(t, TANK_IDLE_COST)); /* See if we need to be healed: */ tanklist_map(gd->data.active.tl, tank_try_base_heal(t)); /* Move everything: */ plist_step (gd->data.active.pl, gd->data.active.lvl, gd->data.active.tl); tanklist_map(gd->data.active.tl, tank_move(t, gd->data.active.tl)); /* Draw everything: */ plist_draw (gd->data.active.pl, gd->data.active.b); tanklist_map(gd->data.active.tl, tank_draw(t, gd->data.active.b)); screen_draw (gd->data.active.s); return 0; }
static ptree_walk_res_t free_na_cb(const void *v1, int level, void *a, void *pwra) { pds_session_t *pdss = (pds_session_t *)a; notify_arg_t *na = (notify_arg_t *)v1; void *ov; ptree_inorder_walk_remove(&pdss->pdss_notify_args, &ov, pwra, nacmp); assert(na == ov); plist_walk(na->na_pd_ids, remove_persistent_change_listener_cb, na->na_pdss->pdss_pd); free((void *)na->na_listenid); na->na_listenid = NULL; plist_clear(&na->na_pd_ids); free(ov); ov = NULL; return PTREE_WALK_CONTINUE; }
/* * This is started by accept_cb as a thread on a new connection. * Calls pd_getline and sends the data it gets to pds_process_line * until pd_getline > 0 and !pdss->pdss_should_close */ int pds_session_serve(const pds_session_t *arg) { pds_session_t *pdss = (pds_session_t *)arg; char *line = NULL; int res; #ifdef _MACOSX signal (SIGPIPE, SIG_IGN); #endif DPRINT(PUL_INFO, "Started new pds_session_serve thread"); pdss->pdss_errdesc[0] = 0; /* first thing - Authenticate */ if(pdss->pdss_auth) { if(pdss->pdss_auth((pds_session_t *)pdss)){ pu_log(PUL_WARN, pdss->pdss_id, "Authentication failed or bad version - closing connection"); goto authfailed; } } while ((res = pd_getline(pdss->pdss_readbuf, sizeof (pdss->pdss_readbuf), &pdss->pdss_bufcur, &pdss->pdss_buflen, pdss->pdss_read, pdss->pdss_close, pdss->pdss_rfd, &line, pdss->pdss_errdesc, sizeof (pdss->pdss_errdesc))) > 0 && !pdss->pdss_should_close) { pds_process_line((pds_session_t *)pdss, line); free(line); line=NULL; } authfailed: free(line); line=NULL; //Shut down the report thread pdss->pdss_should_close = 1; pthread_mutex_lock(&pdss->pdss_lock); if (pdss->pdss_report_thread) { void *status; //pthread_cond_wait(&pdss->pdss_report_cv, &pdss->pdss_lock); pthread_mutex_unlock(&pdss->pdss_lock); pthread_join(pdss->pdss_report_thread, &status); pthread_mutex_lock(&pdss->pdss_lock); } /* remove keys set to expire at end of session */ pdss->pdss_pd_lock(pdss->pdss_pd_lock_arg); plist_walk(pdss->pdss_expire, expired_key_cb, pdss->pdss_pd); plist_clear(&pdss->pdss_expire); /* write_pending will free pending notifications - it will NOT send them because we freed pdss_write */ pdss->pdss_write = NULL; ptree_walk(pdss->pdss_pending, PTREE_POSTORDER, write_pending, ipmcmp, pdss); assert(!pdss->pdss_pending); //ptree_clear(&pdss->pdss_pending); //pdss->pdss_pending = NULL; //clear the listener list - need to lock the dictionary, //because an add/remove could be enumerating the list as we free it otherwise. ptree_walk(pdss->pdss_notify_args, PTREE_POSTORDER, free_na_cb, nacmp, pdss); //ptree_clear(&pdss->pdss_notify_args); assert(!pdss->pdss_notify_args); //Close the socket pdss->pdss_close(pdss->pdss_wfd, NULL, 0); if(pdss->pdss_wfd != pdss->pdss_rfd) pdss->pdss_close(pdss->pdss_rfd, NULL, 0); pdss->pdss_wfd = pdss->pdss_rfd = INVALID_SOCKET; pdss->pdss_close = NULL; pu_log(PUL_INFO, pdss->pdss_id, "done - session closed"); pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); pthread_mutex_unlock(&pdss->pdss_lock); //make sure no cb threads are running while(pdss->cb_threads_count) SLEEP(10); /* now free the pdss!! */ pds_session_free(pdss); pu_log(PUL_INFO, 0, "Exiting pds_session_serve thread"); return 0; }
void pds_process_line(pds_session_t *pdss, char *line) { regmatch_t pmatch[9]; char *cmdtag = NULL; char *cmdstr = NULL; char *key = NULL; char *val = NULL; char *buf = NULL; char *listenid = NULL; int reportperiod; int forsession; int res; //DPRINT(line); if ((res = regexec(&setex, line, 7, pmatch, 0)) == 0) { getmatchsub(line, &cmdtag, pmatch, 1); if (cmdtag && strcmp(cmdtag, "unknown") == 0) { result(pdss, cmdtag, "304 unknown is a reserved command tag"); free(cmdtag); cmdtag = NULL; return; } if (!getmatchsub(line, &key, pmatch, 2) || !key) goto fail; if (!getmatchsub(line, &val, pmatch, 5) && !getmatchsub(line, &val, pmatch, 4)) goto fail; if (!val) goto fail; if ((forsession = getmatchsub(line, NULL, pmatch, 6)) > 0) { /* mark for expiration, but make sure it's only added once! */ if(plist_walk(pdss->pdss_expire, is_key_in_list, key)) { char *e; if (!(e = strdup(key))) goto fail; plist_add(e, NULL, &pdss->pdss_expire); } } pdss->pdss_pd_lock(pdss->pdss_pd_lock_arg); res = pdict_add(pdss->pdss_pd, key, val, NULL); pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); if (!res) result(pdss, cmdtag, "304 set failed"); else result(pdss, cmdtag, "200 set successful"); if (cmdtag) { free(cmdtag); cmdtag = NULL; } free(key); key = NULL; free(val); val = NULL; return; } if ((res = regexec(&listenex, line, 6, pmatch, 0)) == 0) { notify_arg_t *nap; notify_arg_t na; getmatchsub(line, &cmdtag, pmatch, 1); if (cmdtag && strcmp(cmdtag, "unknown") == 0) { result(pdss, cmdtag, "304 unknown is a reserved command tag"); free(cmdtag); cmdtag = NULL; return; } if ((!getmatchsub(line, &buf, pmatch, 4) && !getmatchsub(line, &buf, pmatch, 3)) || !buf) goto fail; getmatchsub(line, &listenid, pmatch, 5); na.na_pdss = pdss; na.na_listenid = listenid; pthread_mutex_lock(&pdss->pdss_lock); pdss->pdss_pd_lock(pdss->pdss_pd_lock_arg); if (!ptree_contains(&na, pdss->pdss_notify_args, nacmp, (void **)&nap)) { if (!(nap = malloc(sizeof (*nap)))) { pu_log(PUL_WARN, pdss->pdss_id, "insufficient memory"); pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); pthread_mutex_unlock(&pdss->pdss_lock); goto fail; } nap->na_pdss = pdss; nap->na_listenid = listenid; nap->na_pd_ids = NULL; if (!ptree_replace(nap, &pdss->pdss_notify_args, nacmp, NULL)) { free(nap); nap = NULL; pu_log(PUL_WARN, pdss->pdss_id, "insufficient memory"); pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); pthread_mutex_unlock(&pdss->pdss_lock); free(listenid); listenid = NULL; free(buf); buf = NULL; goto fail; } } if (!(res = pdict_add_persistent_change_listener(pdss->pdss_pd, buf, notify, (void *)nap))) { if (!nap->na_pd_ids) { ptree_remove(nap, &pdss->pdss_notify_args, nacmp, NULL); free((void *)nap->na_listenid); nap->na_listenid = NULL; free(nap); nap = NULL; } result(pdss, cmdtag, "303 listen not established--bad pattern?"); } else { if (!plist_add((void *)res, NULL, &nap->na_pd_ids)) { pdict_remove_persistent_change_listener(pdss->pdss_pd, res); if (!nap->na_pd_ids) { ptree_remove(nap, &pdss->pdss_notify_args, nacmp, NULL); free((void *)nap->na_listenid); nap->na_listenid = NULL; free(nap); nap = NULL; } free(buf); buf = NULL; if (cmdtag) { free(cmdtag); cmdtag = NULL; } pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); pthread_mutex_unlock(&pdss->pdss_lock); goto fail; } else { result(pdss, cmdtag,"200 listening, id %s", listenid); } } pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); pthread_mutex_unlock(&pdss->pdss_lock); free(buf); buf = NULL; if (cmdtag) { free(cmdtag); cmdtag = NULL; } return; } if ((res = regexec(&reportex, line, 5, pmatch, 0)) == 0) { getmatchsub(line, &cmdtag, pmatch, 1); if (cmdtag && strcmp(cmdtag, "unknown") == 0) { result(pdss, cmdtag, "304 unknown is a reserved command tag"); free(cmdtag); cmdtag = NULL; return; } if (!getmatchsub(line, &buf, pmatch, 2) || !buf) goto fail; if ((reportperiod = atoi(buf)) < 0 || reportperiod > 10000) { result(pdss, cmdtag, "301 invalid report/wait period" "--specify milliseconds or 0 for off (max 10s)"); if (cmdtag) { free(cmdtag); cmdtag = NULL; } free(buf); buf = NULL; return; } free(buf); buf = NULL; getmatchsub(line, &buf, pmatch, 3); set_report_period(pdss, cmdtag, buf, reportperiod); if (cmdtag) { free(cmdtag); cmdtag = NULL; } if (buf) { free(buf); buf = NULL; } return; } if ((res = regexec(&waitex, line, 5, pmatch, 0)) == 0) { getmatchsub(line, &cmdtag, pmatch, 1); if (cmdtag && strcmp(cmdtag, "unknown") == 0) { result(pdss, cmdtag, "304 unknown is a reserved command tag"); free(cmdtag); cmdtag = NULL; return; } if (!getmatchsub(line, &buf, pmatch, 2) || !buf) goto fail; if (atoi(buf) < 0 || atoi(buf) > 10000) { result(pdss, cmdtag, "301 invalid wait period" "--specify milliseconds (max 10s)"); if (cmdtag) { free(cmdtag); cmdtag = NULL; } return; } usleep(atoi(buf) * 1000); result(pdss, cmdtag, "200 nothin' doin'"); if (cmdtag) { free(cmdtag); cmdtag = NULL; } return; } if ((res = regexec(&flushex, line, 5, pmatch, 0)) == 0) { getmatchsub(line, &cmdtag, pmatch, 1); if (cmdtag && strcmp(cmdtag, "unknown") == 0) { result(pdss, cmdtag, "304 unknown is a reserved command tag"); free(cmdtag); cmdtag = NULL; return; } pthread_mutex_lock(&pdss->pdss_lock); pdss->pdss_pd_lock(pdss->pdss_pd_lock_arg); _flush(pdss); pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); pthread_mutex_unlock(&pdss->pdss_lock); result(pdss, cmdtag, "200 glug glug"); if (cmdtag) { free(cmdtag); cmdtag = NULL; } return; } if ((res = regexec(&walkex, line, 5, pmatch, 0)) == 0) { wa_t wa; getmatchsub(line, &cmdtag, pmatch, 1); if (cmdtag && strcmp(cmdtag, "unknown") == 0) { result(pdss, cmdtag, "304 unknown is a reserved command tag"); free(cmdtag); cmdtag = NULL; return; } if (!getmatchsub(line, &cmdstr, pmatch, 2) || !cmdstr) goto fail; if (!getmatchsub(line, &buf, pmatch, 3) || !buf) { free(cmdstr); cmdstr = NULL; goto fail; } if ((regcomp(&wa.wa_regex, buf, REG_EXTENDED)) != 0) { free(cmdstr); cmdstr = NULL; free(buf); buf = NULL; result(pdss, cmdtag, "305 expression error"); if (cmdtag) { free(cmdtag); cmdtag = NULL; } return; } wa.wa_pdss = pdss; wa.wa_cmdtag = cmdtag; wa.wa_l = NULL; pdss->pdss_pd_lock(pdss->pdss_pd_lock_arg); if (!pdict_walk(pdss->pdss_pd, add_to_wa_list, &wa)) { int e = errno; pu_log(PUL_WARN, pdss->pdss_id, "temporary failure: %s", strerror(e)); result(pdss, cmdtag, "300 temporary failure: %s", strerror(e)); } else { if (strcmp(cmdstr, "remove") == 0) plist_walk(wa.wa_l, remove_wa_list, &wa); else plist_walk(wa.wa_l, print_wa_list, &wa); result(pdss, cmdtag, "200 done"); } plist_clear(&wa.wa_l); pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); regfree(&wa.wa_regex); if (cmdtag) { free(cmdtag); cmdtag = NULL; } free(cmdstr); cmdstr = NULL; free(buf); buf = NULL; return; } if ((res = regexec(&ignoreex, line, 5, pmatch, 0)) == 0) { notify_arg_t *nap; notify_arg_t na; void *arg[2]; int n; getmatchsub(line, &cmdtag, pmatch, 1); if (cmdtag && strcmp(cmdtag, "unknown") == 0) { result(pdss, cmdtag, "304 unknown is a reserved command tag"); if (cmdtag) { free(cmdtag); cmdtag = NULL; } return; } if (!getmatchsub(line, &listenid, pmatch, 2) || !listenid) goto fail; pthread_mutex_lock(&pdss->pdss_lock); pdss->pdss_pd_lock(pdss->pdss_pd_lock_arg); na.na_pdss = pdss; na.na_listenid = listenid; if (!ptree_remove(&na, &pdss->pdss_notify_args, nacmp, (void **)&nap)) { pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); pthread_mutex_unlock(&pdss->pdss_lock); result(pdss, cmdtag, "306 nonexistent key/id"); if (cmdtag) { free(cmdtag); cmdtag = NULL; } return; } n = 0; plist_walk(nap->na_pd_ids, _count, &n); plist_walk(nap->na_pd_ids, remove_persistent_change_listener_cb, pdss->pdss_pd); arg[0] = (void *)nap->na_listenid; arg[1] = &pdss->pdss_pending; ptree_walk(pdss->pdss_pending, PTREE_POSTORDER, remove_pending_id, ipmcmp, arg); free((void *)nap->na_listenid); nap->na_listenid = NULL; plist_clear(&nap->na_pd_ids); free(nap); nap = NULL; assert(!ptree_contains(&na, pdss->pdss_notify_args, nacmp, NULL)); pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); pthread_mutex_unlock(&pdss->pdss_lock); result(pdss, cmdtag, "200 %d listener%s ignored", n, n > 1 ? "s" : ""); if (cmdtag) { free(cmdtag); cmdtag = NULL; } free(listenid); return; } if ((res = regexec(&quitex, line, 5, pmatch, 0)) == 0) { getmatchsub(line, &cmdtag, pmatch, 1); result(pdss, cmdtag, "200 goodbye"); pdss->pdss_should_close = 1; pdss->pdss_close(pdss->pdss_wfd, NULL, 0); if (cmdtag) { free(cmdtag); cmdtag = NULL; } return; } if ((res = regexec(&getidex, line, 5, pmatch, 0)) == 0) { getmatchsub(line, &cmdtag, pmatch, 1); result(pdss, cmdtag, "200 %d", pdss->pdss_id); if (cmdtag) { free(cmdtag); cmdtag = NULL; } return; } if ((res = regexec(&okex, line, 5, pmatch, 0)) == 0) { if (cmdtag) { free(cmdtag); cmdtag = NULL; } return; } result(pdss, NULL, "400 input unrecognized: %s", line); return; fail: result(pdss, cmdtag, "300 command failed: %s", strerror(errno)); if (cmdtag) free (cmdtag); }
/* Move to the next file depending on the options set, the user * request and whether or not there are files in the queue. */ static void go_to_another_file () { int shuffle = options_get_int ("Shuffle"); int go_next = (play_next || options_get_int("AutoNext")); int curr_playing_curr_pos; /* XXX: Shouldn't play_next be protected by mutex? */ LOCK (curr_playing_mut); LOCK (plist_mut); /* If we move forward in the playlist and there are some songs in * the queue, then play them. */ if (plist_count(&queue) && go_next) { logit ("Playing file from queue"); if (!before_queue_fname && curr_playing_fname) before_queue_fname = xstrdup (curr_playing_fname); curr_plist = &queue; curr_playing = plist_next (&queue, -1); server_queue_pop (queue.items[curr_playing].file); plist_delete (&queue, curr_playing); } else { /* If we just finished playing files from the queue and the * appropriate option is set, continue with the file played * before playing the queue. */ if (before_queue_fname && options_get_int("QueueNextSongReturn")) { free (curr_playing_fname); curr_playing_fname = before_queue_fname; before_queue_fname = NULL; } if (shuffle) { curr_plist = &shuffled_plist; if (plist_count(&playlist) && !plist_count(&shuffled_plist)) { plist_cat (&shuffled_plist, &playlist); plist_shuffle (&shuffled_plist); if (curr_playing_fname) plist_swap_first_fname (&shuffled_plist, curr_playing_fname); } } else curr_plist = &playlist; curr_playing_curr_pos = plist_find_fname (curr_plist, curr_playing_fname); /* If we came from the queue and the last file in * queue wasn't in the playlist, we try to revert to * the QueueNextSongReturn = 1 behaviour. */ if (curr_playing_curr_pos == -1 && before_queue_fname) { curr_playing_curr_pos = plist_find_fname (curr_plist, before_queue_fname); } if (play_prev && plist_count(curr_plist)) { logit ("Playing previous..."); if (curr_playing_curr_pos == -1 || started_playing_in_queue) { curr_playing = plist_prev (curr_plist, -1); started_playing_in_queue = 0; } else curr_playing = plist_prev (curr_plist, curr_playing_curr_pos); if (curr_playing == -1) { if (options_get_int("Repeat")) curr_playing = plist_last (curr_plist); logit ("Beginning of the list."); } else logit ("Previous item."); } else if (go_next && plist_count(curr_plist)) { logit ("Playing next..."); if (curr_playing_curr_pos == -1 || started_playing_in_queue) { curr_playing = plist_next (curr_plist, -1); started_playing_in_queue = 0; } else curr_playing = plist_next (curr_plist, curr_playing_curr_pos); if (curr_playing == -1 && options_get_int("Repeat")) { if (shuffle) { plist_clear (&shuffled_plist); plist_cat (&shuffled_plist, &playlist); plist_shuffle (&shuffled_plist); } curr_playing = plist_next (curr_plist, -1); logit ("Going back to the first item."); } else if (curr_playing == -1) logit ("End of the list"); else logit ("Next item"); } else if (!options_get_int("Repeat")) { curr_playing = -1; } else debug ("Repeating file"); if (before_queue_fname) free (before_queue_fname); before_queue_fname = NULL; } UNLOCK (plist_mut); UNLOCK (curr_playing_mut); }
int main(int argc, char *argv[]) { lnode *conf; struct sigaction sa; int i; #ifndef DEBUG /* Make sure we are root */ if (getuid() != 0) { fprintf(stderr, "You must be root to run this program.\n"); return 4; } #endif set_aumessage_mode(MSG_SYSLOG, DBG_YES); /* Register sighandlers */ sa.sa_flags = 0; sigemptyset(&sa.sa_mask); /* Ignore all signals by default */ sa.sa_handler = SIG_IGN; for (i=1; i<NSIG; i++) sigaction(i, &sa, NULL); /* Set handler for the ones we care about */ sa.sa_handler = term_handler; sigaction(SIGTERM, &sa, NULL); sa.sa_handler = hup_handler; sigaction(SIGHUP, &sa, NULL); sa.sa_handler = alarm_handler; sigaction(SIGALRM, &sa, NULL); sa.sa_handler = child_handler; sigaction(SIGCHLD, &sa, NULL); /* move stdin to its own fd */ if (argc == 3 && strcmp(argv[1], "--input") == 0) audit_fd = open(argv[2], O_RDONLY); else audit_fd = dup(0); if (audit_fd < 0) { syslog(LOG_ERR, "Failed setting up input, exiting"); return 1; } /* Make all descriptors point to dev null */ i = open("/dev/null", O_RDWR); if (i >= 0) { if (dup2(0, i) < 0 || dup2(1, i) < 0 || dup2(2, i) < 0) { syslog(LOG_ERR, "Failed duping /dev/null %s, exiting", strerror(errno)); return 1; } close(i); } else { syslog(LOG_ERR, "Failed opening /dev/null %s, exiting", strerror(errno)); return 1; } if (fcntl(audit_fd, F_SETFD, FD_CLOEXEC) < 0) { syslog(LOG_ERR, "Failed protecting input %s, exiting", strerror(errno)); return 1; } /* init the daemon's config */ if (load_config(&daemon_config, config_file)) return 6; load_plugin_conf(&plugin_conf); /* if no plugins - exit */ if (plist_count(&plugin_conf) == 0) { syslog(LOG_ERR, "No plugins found, exiting"); return 0; } /* Plugins are started with the auditd priority */ i = start_plugins(&plugin_conf); /* Now boost priority to make sure we are getting time slices */ if (daemon_config.priority_boost != 0) { errno = 0; (void) nice((int)-daemon_config.priority_boost); if (errno) { syslog(LOG_ERR, "Cannot change priority (%s)", strerror(errno)); /* Stay alive as this is better than stopping */ } } /* Let the queue initialize */ init_queue(daemon_config.q_depth); syslog(LOG_NOTICE, "audispd initialized with q_depth=%d and %d active plugins", daemon_config.q_depth, i); /* Tell it to poll the audit fd */ if (add_event(audit_fd, process_inbound_event) < 0) { syslog(LOG_ERR, "Cannot add event, exiting"); return 1; } /* Create inbound thread */ pthread_create(&inbound_thread, NULL, inbound_thread_main, NULL); /* Start event loop */ while (event_loop()) { hup = 0; reconfigure(); } /* Tell plugins we are going down */ signal_plugins(SIGTERM); /* Cleanup builtin plugins */ destroy_af_unix(); destroy_syslog(); /* Give it 5 seconds to clear the queue */ alarm(5); pthread_join(inbound_thread, NULL); /* Release configs */ plist_first(&plugin_conf); conf = plist_get_cur(&plugin_conf); while (conf) { free_pconfig(conf->p); conf = plist_next(&plugin_conf); } plist_clear(&plugin_conf); /* Cleanup the queue */ destroy_queue(); free_config(&daemon_config); return 0; }
static void reconfigure(void) { int rc; daemon_conf_t tdc; conf_llist tmp_plugin; lnode *tpconf; /* Read new daemon config */ rc = load_config(&tdc, config_file); if (rc == 0) { if (tdc.q_depth > daemon_config.q_depth) { increase_queue_depth(tdc.q_depth); daemon_config.q_depth = tdc.q_depth; } daemon_config.overflow_action = tdc.overflow_action; reset_suspended(); /* We just fill these in because they are used by this * same thread when we return */ daemon_config.node_name_format = tdc.node_name_format; free((char *)daemon_config.name); daemon_config.name = tdc.name; } /* The idea for handling SIGHUP to children goes like this: * 1) load the current config in temp list * 2) mark all in real list unchecked * 3) for each one in tmp list, scan old list * 4) if new, start it, append to list, mark done * 5) else check if there was a change to active state * 6) if so, copy config over and start * 7) If no change, send sighup to non-builtins and mark done * 8) Finally, scan real list for unchecked, terminate and deactivate */ load_plugin_conf(&tmp_plugin); plist_mark_all_unchecked(&plugin_conf); plist_first(&tmp_plugin); tpconf = plist_get_cur(&tmp_plugin); while (tpconf && tpconf->p) { lnode *opconf; opconf = plist_find_name(&plugin_conf, tpconf->p->name); if (opconf == NULL) { /* We have a new service */ if (tpconf->p->active == A_YES) { tpconf->p->checked = 1; plist_last(&plugin_conf); plist_append(&plugin_conf, tpconf->p); free(tpconf->p); tpconf->p = NULL; start_one_plugin(plist_get_cur(&plugin_conf)); } } else { if (opconf->p->active == tpconf->p->active) { if (opconf->p->type == S_ALWAYS) kill(opconf->p->pid, SIGHUP); opconf->p->checked = 1; } else { /* A change in state */ if (tpconf->p->active == A_YES) { /* starting - copy config and exec */ free_pconfig(opconf->p); free(opconf->p); opconf->p = tpconf->p; opconf->p->checked = 1; start_one_plugin(opconf); tpconf->p = NULL; } } } tpconf = plist_next(&tmp_plugin); } /* Now see what's left over */ while ( (tpconf = plist_find_unchecked(&plugin_conf)) ) { /* Anything not checked is something removed from the config */ tpconf->p->active = A_NO; kill(tpconf->p->pid, SIGTERM); tpconf->p->pid = 0; tpconf->p->checked = 1; } /* Release memory from temp config */ plist_first(&tmp_plugin); tpconf = plist_get_cur(&tmp_plugin); while (tpconf) { free_pconfig(tpconf->p); tpconf = plist_next(&tmp_plugin); } plist_clear(&tmp_plugin); }
/* * This is started by accept_cb as a thread on a new connection. * Calls pd_getline and sends the data it gets to pds_process_line * until pd_getline > 0 and !pdss->pdss_should_close */ int pds_session_serve(const pds_session_t *arg) { pds_session_t *pdss = (pds_session_t *)arg; char *line; int res; #ifdef _MACOSX signal (SIGPIPE, SIG_IGN); #endif pdss->pdss_errdesc[0] = 0; while ((res = pd_getline(pdss->pdss_readbuf, sizeof (pdss->pdss_readbuf), &pdss->pdss_bufcur, &pdss->pdss_buflen, pdss->pdss_read, pdss->pdss_close, pdss->pdss_rfd, &line, pdss->pdss_errdesc, sizeof (pdss->pdss_errdesc))) > 0 && !pdss->pdss_should_close) { pds_process_line((pds_session_t *)pdss, line); free(line); line=NULL; } free(line); line=NULL; pdss->pdss_should_close = 1; /*printf("Printing out expiring keys:\n"); plist_walk(pdss->pdss_expire, print_key, NULL); printf("DONE\n");*/ /* remove keys set to expire at end of session */ pdss->pdss_pd_lock(pdss->pdss_pd_lock_arg); plist_walk(pdss->pdss_expire, expired_key_cb, pdss->pdss_pd); plist_clear(&pdss->pdss_expire); pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); pthread_mutex_lock(&pdss->pdss_lock); if (pdss->pdss_report_thread) { void *status; //pthread_cond_wait(&pdss->pdss_report_cv, &pdss->pdss_lock); pthread_mutex_unlock(&pdss->pdss_lock); pthread_join(pdss->pdss_report_thread, &status); pthread_mutex_lock(&pdss->pdss_lock); } ptree_walk(pdss->pdss_notify_args, PTREE_INORDER, free_na_cb, NULL); ptree_clear(&pdss->pdss_notify_args); pthread_mutex_unlock(&pdss->pdss_lock); /* write_pending will free pending notifications */ pdss->pdss_write = NULL; ptree_walk(pdss->pdss_pending, PTREE_INORDER, write_pending, pdss); ptree_clear(&pdss->pdss_pending); assert(!pdss->pdss_pending); assert(!pdss->pdss_notify_args); pu_log(PUL_INFO, pdss->pdss_id, "done - session closed"); /* now free the pdss!! */ pds_session_free(pdss); return res; }