static void
dmap_mdns_browser_dispose (GObject * object)
{
	DMAPMdnsBrowser *browser = DMAP_MDNS_BROWSER (object);
	GSList *walk;
	DMAPMdnsBrowserService *service;

	for (walk = browser->priv->services; walk; walk = walk->next) {
		service = (DMAPMdnsBrowserService *) walk->data;
		free_service (service);
	}
	g_slist_free (browser->priv->services);

	if (browser->priv->resolvers) {
		g_slist_foreach (browser->priv->resolvers,
				 (GFunc) avahi_service_resolver_free, NULL);
		g_slist_free (browser->priv->resolvers);
	}

	if (browser->priv->service_browser) {
		avahi_service_browser_free (browser->priv->service_browser);
	}

	if (browser->priv->client) {
		avahi_client_free (browser->priv->client);
	}

	if (browser->priv->poll) {
		avahi_glib_poll_free (browser->priv->poll);
	}

	G_OBJECT_CLASS (dmap_mdns_browser_parent_class)->dispose (object);
}
示例#2
0
文件: service.c 项目: ynadji/omphalos
// Destroy a services structure.
void free_services(l4srv *l){
	l4srv *tmp;

	while( (tmp = l) ){
		l = l->next;
		free_service(tmp);
	}
}
示例#3
0
/*
 * taken the code from ExitOneClient() for this and placed it here.
 * - avalon
 * remove client **AND** _related structures_ from lists,
 * *free* them too. -krys
 */
void	remove_client_from_list(aClient *cptr)
{
	checklist();
	/* is there another way, at this point? */
	/* servers directly connected have hopcount=1, but so do their
	 * users, hence the check for IsServer --B. */
	if (cptr->hopcount == 0 ||
		(cptr->hopcount == 1 && IsServer(cptr)))
		istat.is_localc--;
	else
		istat.is_remc--;
	if (cptr->prev)
		cptr->prev->next = cptr->next;
	else
	    {
		client = cptr->next;
		client->prev = NULL;
	    }
	if (cptr->next)
		cptr->next->prev = cptr->prev;

	if (cptr->user)
	    {
		istat.is_users--;
		/* decrement reference counter, and eventually free it */
		cptr->user->bcptr = NULL;
		(void)free_user(cptr->user);
	    }

	if (cptr->serv)
	{
		cptr->serv->bcptr = NULL;
		free_server(cptr->serv);
	}

	if (cptr->service)
		/*
		** has to be removed from the list of aService structures,
		** no reference counter for services, thus this part of the
		** code can safely be included in free_service()
		*/
		free_service(cptr);

#ifdef	DEBUGMODE
	if (cptr->fd == -2)
		cloc.inuse--;
	else
		crem.inuse--;
#endif

	(void)free_client(cptr);
	numclients--;
	return;
}
/**
 * Task run for shutdown.
 *
 * @param cls closure, NULL if we need to self-restart
 * @param tc context
 */
static void
shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct ServiceList *pos;
  struct ServiceList *nxt;
  struct ServiceListeningInfo *sli;

  if (GNUNET_SCHEDULER_NO_TASK != child_restart_task)
  {
    GNUNET_SCHEDULER_cancel (child_restart_task);
    child_restart_task = GNUNET_SCHEDULER_NO_TASK;
  }
  in_shutdown = GNUNET_YES;
  /* first, stop listening */
  for (pos = running_head; NULL != pos; pos = pos->next)
  {
    while (NULL != (sli = pos->listen_head))
      {
	GNUNET_CONTAINER_DLL_remove (pos->listen_head,
				     pos->listen_tail, sli);
	if (sli->accept_task != GNUNET_SCHEDULER_NO_TASK)
	  {
	    GNUNET_SCHEDULER_cancel (sli->accept_task);
	    sli->accept_task = GNUNET_SCHEDULER_NO_TASK;
	  }
	GNUNET_break (GNUNET_OK ==
		      GNUNET_NETWORK_socket_close (sli->listen_socket));
	GNUNET_free (sli->service_addr);
	GNUNET_free (sli);
      }
  }
  /* then, shutdown all existing service processes */
  nxt = running_head;
  while (NULL != (pos = nxt))
  {
    nxt = pos->next;
    if (pos->proc != NULL)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n",
		  pos->name);
      pos->killed_at = GNUNET_TIME_absolute_get ();
      if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM))
	GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
    }
    else
    {
      free_service (pos);
    }
  }
  /* finally, should all service processes be already gone, terminate for real */
  if (running_head == NULL)
    do_shutdown ();
}
void free_rls_services(rls_services_t *rls)
{
	service_t *e, *f;
	if (!rls) return;
	
	e = SEQUENCE_FIRST(rls->rls_services);
	while (e) {
		f = SEQUENCE_NEXT(e);
		free_service(e);
		e = f;
	}
	cds_free(rls);
}
gboolean
dmap_mdns_publisher_withdraw (DMAPMdnsPublisher * publisher,
			      guint port, GError ** error)
{
	struct DMAPMdnsPublisherService *ptr;

	if (publisher->priv->client == NULL) {
		g_set_error (error,
			     DMAP_MDNS_PUBLISHER_ERROR,
			     DMAP_MDNS_PUBLISHER_ERROR_NOT_RUNNING,
			     "%s",
			     _("The avahi MDNS service is not running"));
		return FALSE;
	}

	if (publisher->priv->entry_group == NULL
	    || !(ptr =
		 find_service_by_port (publisher->priv->service, port))) {
		g_set_error (error, DMAP_MDNS_PUBLISHER_ERROR,
			     DMAP_MDNS_PUBLISHER_ERROR_FAILED, "%s",
			     _("The MDNS service is not published"));
		return FALSE;
	}

	free_service (ptr, NULL);
	publisher->priv->service =
		g_slist_remove (publisher->priv->service, ptr);

	if (publisher->priv->service == NULL) {
		avahi_entry_group_reset (publisher->priv->entry_group);
		avahi_entry_group_free (publisher->priv->entry_group);
		publisher->priv->entry_group = NULL;
	} else {
		create_services (publisher, error);
		if (error != NULL)
			return FALSE;
	}

	return TRUE;
}
示例#7
0
文件: service.c 项目: ynadji/omphalos
void observe_service(interface *i,struct l2host *l2,struct l3host *l3,
			unsigned proto,unsigned port,
			const wchar_t *srv,const wchar_t *srvver){
	const omphalos_ctx *octx = get_octx();
	l4srv *services,**prev,*cur;

	services = l3_getservices(l3);
	for(prev = &services ; (cur = *prev) ; prev = &cur->next){
		if(cur->proto > proto){
			break;
		}else if(cur->proto == proto){
			if(cur->port > port){
				break;
			}else if(cur->port == port){
				int r;

				if((r = wcscmp(cur->srv,srv)) == 0){
					return;
				}else if(r > 0){
					break;
				}
			}
		}
	}
	if((cur = new_service(proto,port,srv,srvver)) == NULL){
		return;
	}
	cur->next = *prev;
	*prev = cur;
	if(l3_setservices(l3,services)){
		*prev = cur->next;
		free_service(cur);
	}else if(octx->iface.srv_event){
		cur->opaque = octx->iface.srv_event(i,l2,l3,cur);
	}
}
示例#8
0
int add_service(char *name,
	const char *port,
	int max_connections,
	new_connection_handler_t new_connection_handler,
	input_handler_t input_handler,
	connection_closed_handler_t connection_closed_handler,
	void *priv)
{
	struct service *c, **p;
	struct hostent *hp;
	int so_reuseaddr_option = 1;

	c = malloc(sizeof(struct service));

	c->name = strdup(name);
	c->port = strdup(port);
	c->max_connections = 1;	/* Only TCP/IP ports can support more than one connection */
	c->fd = -1;
	c->connections = NULL;
	c->new_connection = new_connection_handler;
	c->input = input_handler;
	c->connection_closed = connection_closed_handler;
	c->priv = priv;
	c->next = NULL;
	long portnumber;
	if (strcmp(c->port, "pipe") == 0)
		c->type = CONNECTION_STDINOUT;
	else {
		char *end;
		portnumber = strtol(c->port, &end, 0);
		if (!*end && (parse_long(c->port, &portnumber) == ERROR_OK)) {
			c->portnumber = portnumber;
			c->type = CONNECTION_TCP;
		} else
			c->type = CONNECTION_PIPE;
	}

	if (c->type == CONNECTION_TCP) {
		c->max_connections = max_connections;

		c->fd = socket(AF_INET, SOCK_STREAM, 0);
		if (c->fd == -1) {
			LOG_ERROR("error creating socket: %s", strerror(errno));
			free_service(c);
			return ERROR_FAIL;
		}

		setsockopt(c->fd,
			SOL_SOCKET,
			SO_REUSEADDR,
			(void *)&so_reuseaddr_option,
			sizeof(int));

		socket_nonblock(c->fd);

		memset(&c->sin, 0, sizeof(c->sin));
		c->sin.sin_family = AF_INET;

		if (bindto_name == NULL)
			c->sin.sin_addr.s_addr = INADDR_ANY;
		else {
			hp = gethostbyname(bindto_name);
			if (hp == NULL) {
				LOG_ERROR("couldn't resolve bindto address: %s", bindto_name);
				close_socket(c->fd);
				free_service(c);
				return ERROR_FAIL;
			}
			memcpy(&c->sin.sin_addr, hp->h_addr_list[0], hp->h_length);
		}
		c->sin.sin_port = htons(c->portnumber);

		if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
			LOG_ERROR("couldn't bind %s to socket on port %d: %s", name, c->portnumber, strerror(errno));
			close_socket(c->fd);
			free_service(c);
			return ERROR_FAIL;
		}

#ifndef _WIN32
		int segsize = 65536;
		setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG,  &segsize, sizeof(int));
#endif
		int window_size = 128 * 1024;

		/* These setsockopt()s must happen before the listen() */

		setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF,
			(char *)&window_size, sizeof(window_size));
		setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF,
			(char *)&window_size, sizeof(window_size));

		if (listen(c->fd, 1) == -1) {
			LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
			close_socket(c->fd);
			free_service(c);
			return ERROR_FAIL;
		}

		struct sockaddr_in addr_in;
		socklen_t addr_in_size = sizeof(addr_in);
		getsockname(c->fd, (struct sockaddr *)&addr_in, &addr_in_size);
		LOG_INFO("Listening on port %hu for %s connections",
				ntohs(addr_in.sin_port), name);
	} else if (c->type == CONNECTION_STDINOUT) {
		c->fd = fileno(stdin);

#ifdef _WIN32
		/* for win32 set stdin/stdout to binary mode */
		if (_setmode(_fileno(stdout), _O_BINARY) < 0)
			LOG_WARNING("cannot change stdout mode to binary");
		if (_setmode(_fileno(stdin), _O_BINARY) < 0)
			LOG_WARNING("cannot change stdin mode to binary");
		if (_setmode(_fileno(stderr), _O_BINARY) < 0)
			LOG_WARNING("cannot change stderr mode to binary");
#else
		socket_nonblock(c->fd);
#endif
	} else if (c->type == CONNECTION_PIPE) {
#ifdef _WIN32
		/* we currenty do not support named pipes under win32
		 * so exit openocd for now */
		LOG_ERROR("Named pipes currently not supported under this os");
		free_service(c);
		return ERROR_FAIL;
#else
		/* Pipe we're reading from */
		c->fd = open(c->port, O_RDONLY | O_NONBLOCK);
		if (c->fd == -1) {
			LOG_ERROR("could not open %s", c->port);
			free_service(c);
			return ERROR_FAIL;
		}
#endif
	}

	/* add to the end of linked list */
	for (p = &services; *p; p = &(*p)->next)
		;
	*p = c;

	return ERROR_OK;
}
/**
 * Task triggered whenever we receive a SIGCHLD (child
 * process died).
 *
 * @param cls closure, NULL if we need to self-restart
 * @param tc context
 */
static void
maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct ServiceList *pos;
  struct ServiceList *next;
  struct ServiceListeningInfo *sli;
  const char *statstr;
  int statcode;
  int ret;
  char c[16];
  enum GNUNET_OS_ProcessStatusType statusType;
  unsigned long statusCode;
  const struct GNUNET_DISK_FileHandle *pr;

  pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
  child_death_task = GNUNET_SCHEDULER_NO_TASK;
  if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
    {
      /* shutdown scheduled us, ignore! */
      child_death_task =
	GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
					pr, &maint_child_death, NULL);
      return;
    }
  /* consume the signal */
  GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c)));

  /* check for services that died (WAITPID) */
  next = running_head;
  while (NULL != (pos = next))
    {
      next = pos->next;

      if (pos->proc == NULL)
      {
	if (GNUNET_YES == in_shutdown)
	  free_service (pos);
	continue;
      }
      if ((GNUNET_SYSERR ==
	   (ret =
	    GNUNET_OS_process_status (pos->proc, &statusType, &statusCode)))
	  || ((ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED)
	      || (statusType == GNUNET_OS_PROCESS_RUNNING)))
	continue;
      if (statusType == GNUNET_OS_PROCESS_EXITED)
      {
	statstr = _( /* process termination method */ "exit");
	statcode = statusCode;
      }
      else if (statusType == GNUNET_OS_PROCESS_SIGNALED)
      {
	statstr = _( /* process termination method */ "signal");
	statcode = statusCode;
      }
      else
      {
	statstr = _( /* process termination method */ "unknown");
	statcode = 0;
      }
      if (0 != pos->killed_at.abs_value)
      {
	GNUNET_log (GNUNET_ERROR_TYPE_INFO,
		    _("Service `%s' took %llu ms to terminate\n"),
		    pos->name,
		    GNUNET_TIME_absolute_get_duration (pos->killed_at).rel_value);
      }
      GNUNET_OS_process_destroy (pos->proc);
      pos->proc = NULL;
      if (NULL != pos->killing_client)
	{
	  signal_result (pos->killing_client, pos->name,
			 GNUNET_ARM_PROCESS_DOWN);
	  GNUNET_SERVER_client_drop (pos->killing_client);
	  pos->killing_client = NULL;
	  /* process can still be re-started on-demand, ensure it is re-started if there is demand */
	  for (sli = pos->listen_head; NULL != sli; sli = sli->next)
	    {
	      GNUNET_break (GNUNET_SCHEDULER_NO_TASK == sli->accept_task);
	      sli->accept_task =
		GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
					       sli->listen_socket,
					       &accept_connection, sli);
	    }
	  continue;
	}
      if (GNUNET_YES != in_shutdown)
	{
	  if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0))
	    {
	      /* process terminated normally, allow restart at any time */
	      pos->restart_at.abs_value = 0;
	    }
          else
            {
	      if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
	        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
			    _
			    ("Service `%s' terminated with status %s/%d, will restart in %llu ms\n"),
			    pos->name, statstr, statcode, pos->backoff.rel_value);
	      /* schedule restart */
	      pos->restart_at = GNUNET_TIME_relative_to_absolute (pos->backoff);
	      pos->backoff =
	        GNUNET_TIME_relative_min (EXPONENTIAL_BACKOFF_THRESHOLD,
				          GNUNET_TIME_relative_multiply
				          (pos->backoff, 2));
            }
	  if (GNUNET_SCHEDULER_NO_TASK != child_restart_task)
	    GNUNET_SCHEDULER_cancel (child_restart_task);
	  child_restart_task =
	    GNUNET_SCHEDULER_add_with_priority
	    (GNUNET_SCHEDULER_PRIORITY_IDLE, 
	     &delayed_restart_task, NULL);
	}
      else
	{
	  free_service (pos);
	}
    }
  child_death_task =
    GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
				    pr, &maint_child_death, NULL);
  if ((NULL == running_head) && (GNUNET_YES == in_shutdown))
    do_shutdown ();
}
示例#10
0
/* catches and processes user's resource list as rls-services document */
int get_resource_list_from_full_doc(const str_t *user, 
		const str_t *filename, 
		xcap_query_params_t *xcap_params, 
		const char *list_name, flat_list_t **dst)
{
	char *data = NULL;
	int dsize = 0;
	service_t *service = NULL; 
	list_t *list = NULL, *right = NULL;
	int res;
	char *uri = NULL;

	if (!dst) return RES_INTERNAL_ERR;
	
	/* get basic document */
	uri = xcap_uri_for_users_document(xcap_doc_resource_lists,
			user, filename, xcap_params);
	if (!uri) {
		ERROR_LOG("can't get XCAP uri\n");
		return -1;
	}
	DEBUG_LOG("XCAP uri \'%s\'\n", uri);
	res = xcap_query(uri, xcap_params, &data, &dsize);
	if (res != 0) {
		ERROR_LOG("XCAP problems for uri \'%s\'\n", uri);
		if (data) {
			cds_free(data);
		}
		cds_free(uri);
		return RES_XCAP_QUERY_ERR;
	}
	cds_free(uri);
	
	/* parse document as a list element in resource-lists */
	if (parse_as_list_content_xml(data, dsize, &list) != 0) {
		ERROR_LOG("Parsing problems!\n");
		if (list) free_list(list);
		if (data) {
			cds_free(data);
		}
		return RES_XCAP_PARSE_ERR;
	}
/*	DEBUG_LOG("%.*s\n", dsize, data);*/
	if (data) cds_free(data);

	/* rs -> list */
	
	if (!list) {
		ERROR_LOG("Empty resource list!\n");
		*dst = NULL;
		return 0; /* this is not error! */
		/* return RES_INTERNAL_ERR; */
	}

	/* search for right list element */
	right = find_list(list, list_name);
		
	service = (service_t*)cds_malloc(sizeof(*service));
	if (!service) {
		ERROR_LOG("Can't allocate memory!\n");
		return RES_MEMORY_ERR;
	}
	memset(service, 0, sizeof(*service));
	service->content_type = stc_list;
	service->content.list = right;
	/*service->uri = ??? */

	/* create flat document */
	res = create_flat_list(service, xcap_params, dst);

	service->content.list = list; /* free whole document not only "right" list */
	free_service(service);
	
	if (res != RES_OK) {
		ERROR_LOG("Flat list creation error\n");
		free_flat_list(*dst);
		*dst = NULL;
		return res;
	}
	
	return RES_OK;
}
示例#11
0
int get_rls(const str_t *uri, xcap_query_params_t *xcap_params, 
		const str_t *package, flat_list_t **dst)
{
	char *data = NULL;
	int dsize = 0;
	service_t *service = NULL;
	char *xcap_uri = NULL;
	str_t *filename = NULL;
	int res;

	if (!dst) return RES_INTERNAL_ERR;
	
	/* get basic document */
	xcap_uri = xcap_uri_for_global_document(xcap_doc_rls_services, 
			filename, xcap_params);
	if (!xcap_uri) {
		ERROR_LOG("can't get XCAP uri\n");
		return RES_XCAP_QUERY_ERR;
	}
	
	res = xcap_query(xcap_uri, xcap_params, &data, &dsize);
	if (res != 0) {
		ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri);
		if (data) {
			cds_free(data);
		}
		cds_free(xcap_uri);
		return RES_XCAP_QUERY_ERR;
	}
	cds_free(xcap_uri);
	
	/* parse document as a service element in rls-sources */
	if (parse_service(data, dsize, &service) != 0) {
		ERROR_LOG("Parsing problems!\n");
		if (service) free_service(service);
		if (data) {
			cds_free(data);
		}
		return RES_XCAP_PARSE_ERR;
	}
/*	DEBUG_LOG("%.*s\n", dsize, data);*/
	if (data) cds_free(data);
	
	if (!service) {
		DEBUG_LOG("Empty service!\n");
		return RES_XCAP_QUERY_ERR;
	}

	/* verify the package */
	if (verify_package(service, package) != 0) {
		free_service(service);
		return RES_BAD_EVENT_PACKAGE_ERR;
	}
	
	/* create flat document */
	res = create_flat_list(service, xcap_params, dst);
	if (res != RES_OK) {
		ERROR_LOG("Flat list creation error\n");
		free_service(service);
		free_flat_list(*dst);
		*dst = NULL;
		return res;
	}
	free_service(service);
	
	return RES_OK;
}