Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
void plist_destroy(PList* plist) {
  if (!plist) {
    return;
  }

  plist_clear(plist);
  GMEM_DEL(plist, PList*, sizeof(PList));
}
Exemplo n.º 3
0
/* 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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
/* 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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
/*
 * 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;
}
Exemplo n.º 8
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);
}
Exemplo n.º 9
0
/* 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);
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
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);
}
Exemplo n.º 12
0
/*
 * 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;
}