static void write_handler(ae_event_loop *el, int fd, void *priv, int mask) { client *c = (client *)priv; /* Initialize request when nothing was written. */ if (c->written == 0) { if (conf.requests_issued++ >= conf.requests) { free_client(c); return; } c->start = ustime(); c->latency = -1; } if (sdslen(c->obuf) > c->written) { char *ptr = c->obuf + c->written; int nwritten = write(c->fd, ptr, sdslen(c->obuf) - c->written); if (nwritten == -1) { if (errno != EPIPE) { fprintf(stderr, "write failed:%s\n", strerror(errno)); } free_client(c); return; } c->written += nwritten; if (sdslen(c->obuf) == c->written) { ae_delete_file_event(conf.el, c->fd, AE_WRITABLE); ae_create_file_event(conf.el, c->fd, AE_READABLE, read_handler, c); } } }
void tWriteProc(struct aeEventLoop* eventLoop, int fd, void* clientData, int mask) { char pageBuf[512] = {0}; char contentBuf[256] = {0}; client_data_t *c = (client_data_t *)clientData; snprintf(contentBuf, sizeof(contentBuf), "<html>Hello, <a href=\"https://github.com/pandyxu/enhanced-redis-event-lib\">enhanced-redis-event-lib</a> example.<br /><br />%s</html>", server.backgroundBuf); snprintf(pageBuf, sizeof(pageBuf), "HTTP/1.1 200 OK\r\nContent-Length: %ld\r\n\r\n%s", strlen(contentBuf), contentBuf); int data_size = strlen(pageBuf); size_t available = sizeof(c->writeBuf)-c->writeBufPos; if (data_size > available) { ERRLOG("writeBuf not enough."); aeDeleteFileEvent(eventLoop, fd, AE_WRITABLE); free_client(c); return; } memcpy(c->writeBuf+c->writeBufPos, pageBuf, data_size); c->writeBufPos += data_size; int nwritten = 0; while(c->writeBufPos > 0) { nwritten = write(fd, c->writeBuf + c->sentlen, c->writeBufPos - c->sentlen); if (nwritten <= 0) { break; } c->sentlen += nwritten; /* If the buffer was sent, set writeBufPos to zero to continue with * the remainder of the reply. */ if (c->sentlen == c->writeBufPos) { c->writeBufPos = 0; c->sentlen = 0; } } if (nwritten == -1) { if (errno == EAGAIN) { nwritten = 0; } else { ERRLOG("Error writing to client: %s", strerror(errno)); aeDeleteFileEvent(eventLoop, fd, AE_WRITABLE); free_client(c); return; } } aeDeleteFileEvent(eventLoop, fd, AE_WRITABLE); free_client(c); }
/* * add_connection - creates a client which has just connected to us on * the given fd. The sockhost field is initialized with the ip# of the host. * The client is sent to the auth module for verification, and not put in * any client list yet. */ static void add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, struct sockaddr *lai) { struct Client *new_client; s_assert(NULL != listener); /* * get the client socket name from the socket * the client has already been checked out in accept_connection */ new_client = make_client(NULL); if (listener->ssl) { rb_fde_t *xF[2]; if(rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Incoming ssld Connection") == -1) { free_client(new_client); return; } new_client->localClient->ssl_ctl = start_ssld_accept(F, xF[1], new_client->localClient->connid); /* this will close F for us */ if(new_client->localClient->ssl_ctl == NULL) { free_client(new_client); return; } F = xF[0]; SetSSL(new_client); } memcpy(&new_client->localClient->ip, sai, sizeof(struct rb_sockaddr_storage)); memcpy(&new_client->preClient->lip, lai, sizeof(struct rb_sockaddr_storage)); /* * copy address to 'sockhost' as a string, copy it to host too * so we have something valid to put into error messages... */ rb_inet_ntop_sock((struct sockaddr *)&new_client->localClient->ip, new_client->sockhost, sizeof(new_client->sockhost)); rb_strlcpy(new_client->host, new_client->sockhost, sizeof(new_client->host)); new_client->localClient->F = F; new_client->localClient->listener = listener; ++listener->ref_count; start_auth(new_client); }
/* erase a client from the client list */ void erase_client( esd_client_t *client ) { esd_client_t *previous = NULL; esd_client_t *current = esd_clients_list; /* iterate until we hit a NULL */ while ( current != NULL ) { /* see if we hit the target client */ if ( current == client ) { if( previous != NULL ){ /* we are deleting in the middle of the list */ previous->next = current->next; } else { /* we are deleting the head of the list */ esd_clients_list = current->next; } ESDBG_TRACE( printf ( "(%02d) closing client connection\n", client->fd ); ); close( client->fd ); free_client( client ); return; } /* iterate through the list */ previous = current; current = current->next; }
static void lookup_callback(isc_task_t *task, isc_event_t *ev) { client_t *client; client = ev->ev_arg; INSIST(client->find == ev->ev_sender); printf("NAME %s:\n\tTask %p got event %p type %08x from %p, client %p\n\terr4: %s err6: %s\n", client->target, task, ev, ev->ev_type, client->find, client, isc_result_totext(client->find->result_v4), isc_result_totext(client->find->result_v6)); isc_event_free(&ev); ev = NULL; CLOCK(); dns_adb_dumpfind(client->find, stderr); dns_adb_destroyfind(&client->find); ISC_LIST_UNLINK(clients, client, link); free_client(&client); CUNLOCK(); }
int main( int argc, char *argv[] ) { int status = 0; if( argc < 8 ) { printf( "\r\nNative Webpay Client Test\r\n" ); printf( "=========================\r\n" ); printf( "usage: BaseTest.exe <serverlist> <port> <clientid> <cert path> " ); printf( "<cert pass> <ca_file> <num_iters> {\"debug\" or \"no debug\"}>\r\n" ); status = 1; } else { // send a repeated number of transactions int i, numIters = atoi( argv[7] ); for ( i = 0; i < numIters; i++ ) { sendTransaction( argc, argv ); } // free the webpay client resources free_client( ); } return 0; }
static void client_done(client *c) { if (conf.requests_finished == conf.requests) { free_client(c); quit = 1; return; } if (conf.keep_alive) { reset_client(c); } else { --conf.live_clients; create_missing_clients(c); ++conf.live_clients; free_client(c); } }
THREAD_PROC client_reader(void *arg) { Client *C = (Client*) arg; EZS *E = C->E; char rbuf[4096]; int nb; THREAD_DETACH; THREAD_OKCANCEL; C->state++; tot_rt++; if (debug>1) fprintf(stderr, "new client_thread\n"); while (C->state && ((nb=ezs_read(E, rbuf, 4095))>0)) { rbuf[nb] = '\0'; if (debug) printf("[%d] recv %d bytes: %s\n", C->no, nb, rbuf); } if ( nb<=0) report_err(E, "read"); /* THREAD_CANCEL(C->writer); */ if (C->state==0) { ezs_disconnect(E); free_client(C); } else C->state = 0; tot_rt--; }
void Avahi::PresencePublisher::client_callback (AvahiClient* client_, AvahiClientState state) { if (client_ == NULL) return; client = client_; switch (state) { case AVAHI_CLIENT_FAILURE: if (avahi_client_errno (client) == AVAHI_ERR_DISCONNECTED) { free_client (); create_client (); } break; case AVAHI_CLIENT_S_RUNNING: register_services (); break; case AVAHI_CLIENT_S_REGISTERING: case AVAHI_CLIENT_S_COLLISION: case AVAHI_CLIENT_CONNECTING: default: break; // nothing } }
void cs_exit(int32_t sig) { if (cs_dump_stack && (sig == SIGSEGV || sig == SIGBUS || sig == SIGQUIT)) cs_dumpstack(sig); set_signal_handler(SIGHUP , 1, SIG_IGN); set_signal_handler(SIGPIPE, 1, SIG_IGN); struct s_client *cl = cur_client(); if (!cl) return; // this is very important - do not remove if (cl->typ != 's') { cs_debug_mask(D_TRACE, "thread %8lX ended!", (unsigned long)pthread_self()); free_client(cl); //Restore signals before exiting thread set_signal_handler(SIGPIPE , 0, cs_sigpipe); set_signal_handler(SIGHUP , 1, cs_reload_config); pthread_exit(NULL); return; } if (!exit_oscam) exit_oscam = sig?sig:1; }
THREAD_PROC client_writer(void *arg) { Client *C = (Client*) arg; EZS *E = C->E; char *msg; int rc; int no = C->no; THREAD_DETACH; THREAD_OKCANCEL; C->state++; tot_wt++; if (debug>1) fprintf(stderr, "new client_writer\n"); while (C->state) { msg = get_client_msg(C); if (msg) { rc = ezs_write(E, msg, strlen(msg)); if (debug) printf("[%d] sent %d bytes: %s\n", C->no, rc, msg); if (rc<=0) { report_err(E, "write"); if (ezs_geterror(E, NULL)==EZS_ERR_NO_CONNECTION) break; } } else sleep(1); } if (C->state==0) { ezs_disconnect(E); free_client(C); } else C->state = 0; tot_wt--; }
void pollfd_del(struct pollfd_info *p, int i) { if(i < 0 || i >= p->size) return; free_client(p->clients[i]); init_empty_entry(p, i); p->nfds -= 1; }
int mb_client_terminate(MbClientHandle client) { int ret, param; MbCodes code; int fd; fd = create_uds ((mbclient*)client); if (fd < 0) return MB_IO; ret = mb_encode_and_send (((mbclient*)client)->id, fd, TERMINATE, 0); if (ret != 0) { do { ret = mb_client_receive(client, &code, ¶m); } while (ret > 0 && code != TERMINATE); } if (ret < 0) return MB_IO; close (fd); free_client(client); return 0; }
struct client * create_client(struct domain *domain, int sockfd, #ifndef DISABLE_LOGGING struct sockaddr *addr, socklen_t addrlen, #endif int randomfd) { struct client *client; int ret; #ifdef HAVE_DEV_RANDOM ssize_t nbytes; #endif client = calloc(1, sizeof(*client)); if (client == NULL) return NULL; #ifndef DISABLE_LOGGING if ((size_t)addrlen > sizeof(client->address)) addrlen = sizeof(client->address); memcpy(&client->address, addr, addrlen); #endif /* DISABLE_LOGGING */ /* a good random client id is vitally important for security, because secondary connections authorized themselves with it */ #ifdef HAVE_DEV_RANDOM nbytes = read(randomfd, &client->id, sizeof(client->id)); if (nbytes < (ssize_t)sizeof(client->id)) { fprintf(stderr, "random number generation failed\n"); free(client); return NULL; } #else (void)randomfd; client->id = (random() << 24) + (random() << 16) + (random() << 8) + random(); #endif client->sockets[0] = sockfd; client->num_sockets = 1; client->timeout = time(NULL) + 60; #ifndef DISABLE_LOGGING update_client_name(client); #endif ret = add_client(domain, client); if (!ret) { log(1, "domain 0 is full, rejecting new client %s\n", client->name); free_client(client); return NULL; } log(2, "new client: %s\n", client->name); return client; }
int main(int argc, char **argv) { int optidx = 0; setprogname (argv[0]); if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) usage (1); if (help_flag) usage (0); if (version_flag) { print_version (NULL); return 0; } if (optidx != argc) usage (1); if (port_str) { char *ptr; port = strtol (port_str, &ptr, 10); if (port == 0 && ptr == port_str) errx (1, "Bad port `%s'", port_str); } krb5_init_context(&context); { const char *lf = logfile_str; if (lf == NULL) lf = "/dev/tty"; logfile = fopen(lf, "w"); if (logfile == NULL) err(1, "error opening %s", lf); } mini_inetd(htons(port), NULL); fprintf(logfile, "connected\n"); { struct client *c; c = create_client(0, port, moniker_str); /* close(0); */ handleServer(c); free_client(c); } krb5_free_context(context); return 0; }
static void free_all_clients() { dlist_node *node = conf.clients->head, *next; while (node) { next = node->next; free_client((client *)node->value); node = next; } }
void Avahi::PresencePublisher::create_client () { free_client (); // don't get the client there : wait what we'll get from the callback avahi_client_new (avahi_glib_poll_get (glib_poll), AVAHI_CLIENT_NO_FAIL, (AvahiClientCallback)client_cb, this, NULL); }
Avahi::PresencePublisher::~PresencePublisher () { free_client (); avahi_glib_poll_free (glib_poll); avahi_free (name); }
void kill_client(struct client *client) { log(2, "kill_client %s\n", client->name); remove_client(client); free_client(client); }
void Server::free_clients(){ std::map<Client*,bool>::iterator it = clients.begin(); Client *c; while(it!=clients.end()){ c = it->first; it++; free_client(c); } }
void Server::broadcast(Client *c_o,char *buf,int len){ // printf("broadcast!!\n"); std::map<Client*,bool>::iterator it= clients.begin(); Client *c; int s = clients.size(); pthread_t *pt = new pthread_t[s]; int i=0; bool live; // const auto startTime = std::chrono::system_clock::now(); // for(it = clients.begin(); it!=clients.end(); it++){ // pthread_mutex_lock(&mutex); while(it!=clients.end()){ c = it->first; live = it->second; it++; if(live == false) free_client(c); else if(c->stop == true) free_client(c); else if(c != c_o){ // strcpy(c->sendbuf,buf); c->sendbuf = buf; c->sendlen = len; // c->sender(buf,len); pthread_create(&pt[i++],NULL,Client::lanch_sender,c); } } // if(i==0) delete(pt); // else th_m[pt] = i; for (int j = 0; j < i; ++j) { pthread_join(pt[j],NULL); } delete(pt); // pthread_mutex_unlock(&mutex); // const auto endTime = std::chrono::system_clock::now(); // const auto timeSpan = endTime - startTime; // std::cout << "処理時間:" << std::chrono::duration_cast<std::chrono::milliseconds>(timeSpan).count() << "[ms]" << std::endl; // printf("end broadcast\n"); }
void gst_multiudpsink_remove (GstMultiUDPSink * sink, const gchar * host, gint port) { GList *find; GstUDPClient udpclient; GstUDPClient *client; GTimeVal now; udpclient.host = (gchar *) host; udpclient.port = port; g_mutex_lock (sink->client_lock); find = g_list_find_custom (sink->clients, &udpclient, (GCompareFunc) client_compare); if (!find) goto not_found; client = (GstUDPClient *) find->data; GST_DEBUG_OBJECT (sink, "found %d clients with host %s, port %d", client->refcount, host, port); client->refcount--; if (client->refcount == 0) { GST_DEBUG_OBJECT (sink, "remove client with host %s, port %d", host, port); g_get_current_time (&now); client->disconnect_time = GST_TIMEVAL_TO_TIME (now); if (*(client->sock) != -1 && sink->auto_multicast && gst_udp_is_multicast (&client->theiraddr)) gst_udp_leave_group (*(client->sock), &client->theiraddr); /* Unlock to emit signal before we delete the actual client */ g_mutex_unlock (sink->client_lock); g_signal_emit (G_OBJECT (sink), gst_multiudpsink_signals[SIGNAL_CLIENT_REMOVED], 0, host, port); g_mutex_lock (sink->client_lock); sink->clients = g_list_delete_link (sink->clients, find); free_client (client); } g_mutex_unlock (sink->client_lock); return; /* ERRORS */ not_found: { g_mutex_unlock (sink->client_lock); GST_WARNING_OBJECT (sink, "client at host %s, port %d not found", host, port); return; } }
/* * 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; }
/* deregister all events */ int nebmodule_deinit( int flags, int reason ) { int x; gm_log( GM_LOG_TRACE, "nebmodule_deinit(%i, %i)\n", flags, reason ); /* should be removed already, but just for the case it wasn't */ neb_deregister_callback( NEBCALLBACK_PROCESS_DATA, gearman_module_handle ); neb_deregister_callback( NEBCALLBACK_TIMED_EVENT_DATA, gearman_module_handle ); /* only if we have hostgroups defined or general hosts enabled */ if ( mod_gm_opt->do_hostchecks == GM_ENABLED && ( mod_gm_opt->hostgroups_num > 0 || mod_gm_opt->hosts == GM_ENABLED )) neb_deregister_callback( NEBCALLBACK_HOST_CHECK_DATA, gearman_module_handle ); /* only if we have groups defined or general services enabled */ if ( mod_gm_opt->servicegroups_num > 0 || mod_gm_opt->hostgroups_num > 0 || mod_gm_opt->services == GM_ENABLED ) neb_deregister_callback( NEBCALLBACK_SERVICE_CHECK_DATA, gearman_module_handle ); if ( mod_gm_opt->events == GM_ENABLED ) neb_deregister_callback( NEBCALLBACK_EVENT_HANDLER_DATA, gearman_module_handle ); if ( mod_gm_opt->perfdata == GM_ENABLED ) { neb_deregister_callback( NEBCALLBACK_HOST_CHECK_DATA, gearman_module_handle ); neb_deregister_callback( NEBCALLBACK_SERVICE_CHECK_DATA, gearman_module_handle ); } /* register export callbacks */ for(x=0;x<GM_NEBTYPESSIZE;x++) { if(mod_gm_opt->exports[x]->elem_number > 0) neb_deregister_callback( x, gearman_module_handle ); } neb_deregister_callback( NEBCALLBACK_PROCESS_DATA, gearman_module_handle ); gm_log( GM_LOG_DEBUG, "deregistered callbacks\n" ); /* stop result threads */ for(x = 0; x < result_threads_running; x++) { pthread_cancel(result_thr[x]); pthread_join(result_thr[x], NULL); } /* cleanup */ free_client(&client); /* close old logfile */ if(mod_gm_opt->logfile_fp != NULL) { fclose(mod_gm_opt->logfile_fp); } mod_gm_free_opt(mod_gm_opt); return NEB_OK; }
/* ** Removes a client from the client list ** if to_free != 0, liberates the client struct */ void remove_client(t_list **list_clients, t_client *cl, int to_free) { t_client *c; t_client ref; my_printf("Client connected on socket %d has been removed\n", cl->socket); ref.socket = cl->socket; c = my_find_elm_eq_in_list(*list_clients, &ref, client_cmp); my_rm_all_eq_from_list(list_clients, &ref, client_cmp); if (to_free) free_client(c); }
static void auth_kill_client(struct AuthRequest* auth) { assert(0 != auth); unlink_auth_request(auth, (IsDoingAuth(auth)) ? &AuthPollList : &AuthIncompleteList); if (IsDNSPending(auth)) delete_resolver_queries(auth); IPcheck_disconnect(auth->client); Count_unknowndisconnects(UserStats); cli_auth(auth->client) = 0; free_client(auth->client); free_auth_request(auth); }
static void lookup(const char *target) { dns_name_t name; unsigned char namedata[256]; client_t *client; isc_buffer_t t, namebuf; isc_result_t result; unsigned int options; INSIST(target != NULL); client = new_client(); isc_buffer_init(&t, target, strlen(target)); isc_buffer_add(&t, strlen(target)); isc_buffer_init(&namebuf, namedata, sizeof(namedata)); dns_name_init(&name, NULL); result = dns_name_fromtext(&name, &t, dns_rootname, ISC_FALSE, &namebuf); check_result(result, "dns_name_fromtext %s", target); result = dns_name_dup(&name, mctx, &client->name); check_result(result, "dns_name_dup %s", target); options = 0; options |= DNS_ADBFIND_INET; options |= DNS_ADBFIND_INET6; options |= DNS_ADBFIND_WANTEVENT; options |= DNS_ADBFIND_HINTOK; options |= DNS_ADBFIND_GLUEOK; result = dns_adb_createfind(adb, t2, lookup_callback, client, &client->name, dns_rootname, options, now, NULL, view->dstport, &client->find); #if 0 check_result(result, "dns_adb_createfind()"); #endif dns_adb_dumpfind(client->find, stderr); if ((client->find->options & DNS_ADBFIND_WANTEVENT) != 0) { client->target = target; ISC_LIST_APPEND(clients, client, link); } else { printf("NAME %s: err4 %s, err6 %s\n", target, isc_result_totext(client->find->result_v4), isc_result_totext(client->find->result_v6)); dns_adb_destroyfind(&client->find); free_client(&client); } }
/* * Taken the code from ExitOneClient() for this and placed it here. * - avalon */ void remove_client_from_list(struct Client *cptr) { assert(cli_verify(cptr)); assert(con_verify(cli_connect(cptr))); assert(!cli_prev(cptr) || cli_verify(cli_prev(cptr))); assert(!cli_next(cptr) || cli_verify(cli_next(cptr))); assert(!IsMe(cptr)); /* Only remove from the list if it actually IS in the list. * cli_next(cptr) cannot be NULL here if cptr is in the list, * only &me is at the end, and we never try to remove &me -GW */ if(cli_next(cptr)) { if (cli_prev(cptr)) cli_next(cli_prev(cptr)) = cli_next(cptr); else { GlobalClientList = cli_next(cptr); cli_prev(GlobalClientList) = 0; } cli_prev(cli_next(cptr)) = cli_prev(cptr); } cli_next(cptr) = cli_prev(cptr) = 0; if (IsUser(cptr) && cli_user(cptr)) { add_history(cptr, 0); off_history(cptr); } if (cli_user(cptr)) { free_user(cli_user(cptr)); cli_user(cptr) = 0; } if (cli_serv(cptr)) { if (cli_serv(cptr)->user) { free_user(cli_serv(cptr)->user); cli_serv(cptr)->user = 0; } if (cli_serv(cptr)->client_list) MyFree(cli_serv(cptr)->client_list); MyFree(cli_serv(cptr)->last_error_msg); MyFree(cli_serv(cptr)); #ifdef DEBUGMODE --servs.inuse; #endif } free_client(cptr); }
int main(int argc,char *argv[]) { redis_client *c = redis_connect("10.210.210.146","8001"); if(!c || c->fd < 0)die("connect error"); redis_response *resp = redis_command(c,"set key abc"); if(resp) free_response(resp); resp = redis_command(c,"get key"); if(resp) { printf("%s\n",resp->data); } free_response(resp); free_client(c); return 0; }
/** Remove \a cptr from lists that it is a member of. * Specifically, this delinks \a cptr from #GlobalClientList, updates * the whowas history list, frees its Client::cli_user and * Client::cli_serv fields, and finally calls free_client() on it. * @param[in] cptr Client to remove from lists and free. */ void remove_client_from_list(struct Client *cptr) { assert(cli_verify(cptr)); assert(con_verify(cli_connect(cptr))); assert(!cli_prev(cptr) || cli_verify(cli_prev(cptr))); assert(!cli_next(cptr) || cli_verify(cli_next(cptr))); assert(!IsMe(cptr)); /* Only try remove cptr from the list if it IS in the list. * cli_next(cptr) cannot be NULL here, as &me is always the end * the list, and we never remove &me. -GW */ if(cli_next(cptr)) { if (cli_prev(cptr)) cli_next(cli_prev(cptr)) = cli_next(cptr); else { GlobalClientList = cli_next(cptr); cli_prev(GlobalClientList) = 0; } cli_prev(cli_next(cptr)) = cli_prev(cptr); } cli_next(cptr) = cli_prev(cptr) = 0; if (IsUser(cptr) && cli_user(cptr)) { add_history(cptr, 0); off_history(cptr); } if (cli_user(cptr)) { free_user(cli_user(cptr)); cli_user(cptr) = 0; } if (cli_serv(cptr)) { if (cli_serv(cptr)->user) { free_user(cli_serv(cptr)->user); cli_serv(cptr)->user = 0; } if (cli_serv(cptr)->client_list) MyFree(cli_serv(cptr)->client_list); MyFree(cli_serv(cptr)->last_error_msg); MyFree(cli_serv(cptr)); --servs.inuse; --servs.alloc; } free_client(cptr); }