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); }
// Destroy a services structure. void free_services(l4srv *l){ l4srv *tmp; while( (tmp = l) ){ l = l->next; free_service(tmp); } }
/* * 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; }
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); } }
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 (); }
/* 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; }
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; }