/* free buffers and extract 'c' from imc_connect_list * called from imc_idle_select when we're done with a connection with * c->state==IMC_CLOSED */ void imc_extract_connect(imc_connect *c) { imc_connect *c_find; if (c->state!=IMC_CLOSED) { imc_logerror("imc_extract_connect: non-closed connection"); return; } imc_free(c->inbuf, c->insize); imc_free(c->outbuf, c->outsize); if (c==imc_connect_list) imc_connect_list=c->next; else { for (c_find=imc_connect_list; c_find && c_find->next!=c; c_find=c_find->next) ; if (!c_find) imc_logerror("imc_extract_connect: not in imc_connect_list"); else c_find->next=c->next; } imc_cancel_event(NULL, c); imc_free(c, sizeof(*c)); }
void imc_cancel_info(imc_info *i) { imc_info *last; if (i==imc_info_list) imc_info_list=i->next; else { for (last=imc_info_list; last && last->next!=i; last=last->next) ; if (!last) imc_logerror("imc_delete_info: not in list"); else last->next=i->next; } if (i->name) imc_strfree(i->name); if (i->host) imc_strfree(i->host); if (i->clientpw) imc_strfree(i->clientpw); if (i->serverpw) imc_strfree(i->serverpw); imc_free(i, sizeof(*i)); }
void imc_delete_info(imc_info *i) { imc_connect *c; imc_info *last; for (c=imc_connect_list; c; c=c->next) if (c->info==i) do_close(c); if (i==imc_info_list) imc_info_list=i->next; else { for (last=imc_info_list; last && last->next!=i; last=last->next) ; if (!last) imc_logerror("imc_delete_info: not in list"); else last->next=i->next; } if (i->name) imc_strfree(i->name); if (i->host) imc_strfree(i->host); if (i->clientpw) imc_strfree(i->clientpw); if (i->serverpw) imc_strfree(i->serverpw); imc_cancel_event(NULL, i); imc_free(i, sizeof(*i)); }
/* free_mail: free a mail structure */ static void free_mail(imc_mail *p) { if (!p) { imc_logerror("BUG: free_mail: freeing NULL pointer"); return; } if (p->usage) { imc_logerror("BUG: free_mail: freeing mail at %p with usage=%d", p, p->usage); return; } if (p->from) imc_strfree(p->from); if (p->to) imc_strfree(p->to); if (p->id) imc_strfree(p->id); if (p->text) imc_strfree(p->text); if (p->subject) imc_strfree(p->subject); if (p->date) imc_strfree(p->date); imc_cancel_event(NULL, p); imc_free(p, sizeof(*p)); }
void icec_localfree(ice_channel *c) { if (c->local) { imc_strfree(c->local->name); imc_strfree(c->local->format1); imc_strfree(c->local->format2); imc_free(c->local, sizeof(icec_lchannel)); c->local=NULL; } }
/* free_mailid: free a mailid */ static void free_mailid(imc_mailid *p) { if (!p) { imc_logerror("BUG: free_mailid: freeing NULL pointer"); return; } if (p->id) imc_strfree(p->id); imc_cancel_event(NULL, p); imc_free(p, sizeof(*p)); }
/* free_qnode: free a qnode */ static void free_qnode(imc_qnode *q) { if (!q) { imc_logerror("BUG: free_qnode: freeing NULL pointer"); return; } if (q->tomud) imc_strfree(q->tomud); if (q->data && !--q->data->usage) delete_ml(q->data); imc_cancel_event(NULL, q); imc_free(q, sizeof(*q)); }
/* put a line onto descriptors output buffer */ static void do_send(imc_connect *c, const char *line) { int len; char *newbuf; int newsize=c->outsize; if (c->state==IMC_CLOSED) return; // imc_debug(c, 1, line); /* log outgoing traffic */ if (!c->outbuf[0]) c->newoutput=1; len=strlen(c->outbuf)+strlen(line)+3; if (len > c->outsize) { #ifdef SHOW_OVERFLOW /* not an error anymore, expected and handled - shogar */ if (len > IMC_MAXBUF) { if (!c->info || !(c->info->flags & IMC_QUIET)) imc_logerror("%s: output buffer overflow", imc_getconnectname(c)); imc_logerror("%d: was allocated", c->outsize); // imc_logerror("current buf: %s", c->outbuf); // do_close(c); // imc_free(c->outbuf,c->outsize); // c->outsize=IMC_MINBUF; // c->outbuf= imc_malloc(c->outsize); // len=strlen(line)+3; // return; } #endif while(newsize < len) newsize*=2; newbuf=imc_malloc(newsize); strcpy(newbuf, c->outbuf); imc_free(c->outbuf, c->outsize); c->outbuf=newbuf; c->outsize=newsize; } if (len<c->outsize/2 && len >= IMC_MINBUF) { newsize=c->outsize/2; newbuf=imc_malloc(newsize); strcpy(newbuf, c->outbuf); imc_free(c->outbuf, c->outsize); c->outbuf=newbuf; c->outsize=newsize; } strcat(c->outbuf, line); strcat(c->outbuf, "\n\r"); if (strlen(c->outbuf)>=c->outsize/2) { imc_cancel_event(ev_shrink_output, c); imc_add_event(IMC_SHRINKTIME, ev_shrink_output, c, 0); } }
/* read waiting data from descriptor. * read to a temp buffer to avoid repeated allocations */ static void do_read(imc_connect *c) { int size; int r; char temp[IMC_MAXBUF]; char *newbuf; int newsize; r=read(c->desc, temp, IMC_MAXBUF-1); if (!r || (r<0 && errno != EAGAIN && errno != EWOULDBLOCK)) { if (!c->info || !(c->info->flags & IMC_QUIET)) { if (r<0) /* read error */ { imc_lerror("%s: read", imc_getconnectname(c)); } else /* socket was closed */ { imc_logerror("%s: read: EOF", imc_getconnectname(c)); } } do_close(c); return; } if (r<0) /* EAGAIN error */ return; temp[r]=0; size=strlen(c->inbuf)+r+1; if (size>=c->insize) { #ifdef SHOW_OVERFLOW /* not an error anymore, expected and handled - shogar */ if (size>IMC_MAXBUF) { imc_logerror("%s: input buffer overflow", imc_getconnectname(c)); imc_logerror("%d: was allocated", c->insize); // do_close(c); // imc_free(c->inbuf,c->insize); // c->insize=IMC_MINBUF; // c->inbuf= imc_malloc(c->insize); // size = r + 1; // return; } #endif newsize=c->insize; while(newsize<size) newsize*=2; newbuf=imc_malloc(newsize); strcpy(newbuf, c->inbuf); imc_free(c->inbuf, c->insize); c->inbuf=newbuf; c->insize=newsize; } if (size>c->insize/2) { imc_cancel_event(ev_shrink_input, c); imc_add_event(IMC_SHRINKTIME, ev_shrink_input, c, 0); } if (size<c->insize/2 && size >= IMC_MINBUF) { newsize=c->insize; newsize/=2; newbuf=imc_malloc(newsize); strcpy(newbuf, c->inbuf); imc_free(c->inbuf, c->insize); c->inbuf=newbuf; c->insize=newsize; } strcat(c->inbuf, temp); imc_stats.rx_bytes += r; }
void imc_shutdown_network(void) { imc_event *ev, *ev_next; imc_connect *c, *c_next; imc_reminfo *p, *pnext; if (imc_active < IA_UP) { imc_logerror("imc_shutdown_network: called with imc_active==%d", imc_active); return; } if (imc_lock) { imc_logerror("imc_shutdown_network: called from within imc_idle_select"); return; } imc_logstring("shutting down network"); if (imc_active == IA_LISTENING) imc_shutdown_port(); imc_logstring("rx %ld packets, %ld bytes (%ld/second)", imc_stats.rx_pkts, imc_stats.rx_bytes, (imc_now == imc_stats.start) ? 0 : imc_stats.rx_bytes / (imc_now - imc_stats.start)); imc_logstring("tx %ld packets, %ld bytes (%ld/second)", imc_stats.tx_pkts, imc_stats.tx_bytes, (imc_now == imc_stats.start) ? 0 : imc_stats.tx_bytes / (imc_now - imc_stats.start)); imc_logstring("largest packet %d bytes", imc_stats.max_pkt); imc_logstring("dropped %d packets by sequence number", imc_stats.sequence_drops); imc_mail_shutdown(); for (c=imc_connect_list; c; c=c_next) { c_next=c->next; do_close(c); imc_extract_connect(c); } imc_connect_list=NULL; if(!imc_is_router) icec_shutdown(); for (p=imc_reminfo_list; p; p=pnext) { pnext=p->next; imc_strfree(p->version); imc_strfree(p->name); if(p->path) imc_strfree(p->path); imc_free(p, sizeof(imc_reminfo)); } imc_reminfo_list=NULL; for (ev=imc_event_list; ev; ev=ev_next) { ev_next=ev->next; imc_free(ev, sizeof(imc_event)); } for (ev=imc_event_free; ev; ev=ev_next) { ev_next=ev->next; imc_free(ev, sizeof(imc_event)); } imc_event_list=imc_event_free=NULL; unlock_prefix(); imc_active=IA_CONFIG2; }