/* 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)); }
static const char *generate2(const imc_packet * p) { char *temp; char newpath[IMC_PATH_LENGTH]; if (!p->type[0] || !p->i.from[0] || !p->i.to[0]) { imc_logerror("BUG: generate2: bad packet!"); imc_logerror("type: %s from: %s to: %s",p->type,p->i.from,p->i.to); imc_logerror("path: %s data:",p->i.path,printkeys(&p->data)); return NULL; /* catch bad packets here */ } if (!p->i.path[0]) strcpy(newpath, imc_name); else sprintf(newpath, "%s!%s", p->i.path, imc_name); temp=imc_getsbuf(IMC_PACKET_LENGTH); sprintf(temp, "%s %lu %s %s %s %s", p->i.from, p->i.sequence, newpath, p->type, p->i.to, printkeys(&p->data)); imc_shrinksbuf(temp); return temp; }
/* 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_send(imc_packet *p) { if (imc_active < IA_UP) { imc_logerror("imc_send when not active!"); return; } /* initialize packet fields that the caller shouldn't/doesn't set */ p->i.stamp = 0; p->i.path[0] = 0; p->i.sequence = imc_sequencenumber++; if (!imc_sequencenumber) imc_sequencenumber++; imc_sncpy(p->i.to, p->to, IMC_NAME_LENGTH); imc_sncpy(p->i.from, p->from, IMC_NAME_LENGTH); strcat(p->i.from, "@"); imc_sncpy(p->i.from + strlen(p->i.from), imc_name, IMC_NAME_LENGTH - strlen(p->i.from)); forward(p); }
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)); }
/* read_qnode: read a qnode from a file */ static imc_qnode *read_qnode(FILE *in) { imc_qnode *p; imc_mail *m; char line[IMC_DATA_LENGTH]; char temp1[IMC_DATA_LENGTH], temp2[IMC_DATA_LENGTH]; fgets(line, IMC_DATA_LENGTH, in); if (ferror(in) || feof(in)) return NULL; sscanf(line, "%[^ ] %[^\n]", temp1, temp2); m=find_ml(temp1); if (!m) { imc_logerror("read_qnode: ID %s not in mail queue", temp1); return NULL; } p=new_qnode(); m->usage++; p->data = m; p->tomud = imc_strdup(temp2); return p; }
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)); }
/* write_qnode: write a qnode to a file */ static void write_qnode(imc_qnode *q, FILE *out) { if (!q) { imc_logerror("BUG: write_qnode: NULL pointer"); return; } fprintf(out, "%s %s\n", q->data->id, q->tomud); }
static void add_ml(imc_mail *p) { if (!p) { imc_logerror("BUG: add_ml: adding NULL pointer"); return; } p->next=imc_ml_head->next; imc_ml_head->next=p; }
static void delete_ml(imc_mail *node) { imc_mail *last, *p; if (!node) { imc_logerror("BUG: delete_ml: NULL node"); return; } for (last=imc_ml_head, p=last->next; p && p != node; p=p->next) ; if (p) { last->next = p->next; free_mail(p); } else imc_logerror("BUG: delete_ml: node at %p not on list", node); }
/* shut down listening port */ void imc_shutdown_port(void) { if (imc_active!=IA_LISTENING) { imc_logerror("imc_shutdown_port: called with imc_active=%d", imc_active); return; } imc_logstring("closing listen port"); close(control); imc_active=IA_UP; }
/* 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)); }
static imc_mail *find_ml(const char *id) { imc_mail *p; if (!id) { imc_logerror("BUG: find_ml: NULL id"); return NULL; } for (p=imc_ml_head->next; p; p=p->next) if (!strcasecmp(p->id, id)) return p; return NULL; }
/* write_mail: write a single mail to a file */ static void write_mail(imc_mail *p, FILE *out) { if (!p) { imc_logerror("BUG: write_mail: NULL pointer"); return; } fprintf(out, "From %s\n", escape(p->from)); fprintf(out, "To %s\n", escape(p->to)); fprintf(out, "Subject %s\n", escape(p->subject)); fprintf(out, "Date %s\n", escape(p->date)); fprintf(out, "Text %s\n", escape(p->text)); fprintf(out, "ID %s\n", escape(p->id)); fprintf(out, "Received %ld\n", p->received); }
static imc_packet *interpret2(const char *argument) { char seq[20]; static imc_packet out; imc_initdata(&out.data); argument = imc_getarg(argument, out.i.from, IMC_NAME_LENGTH); argument = imc_getarg(argument, seq, 20); argument = imc_getarg(argument, out.i.path, IMC_PATH_LENGTH); argument = imc_getarg(argument, out.type, IMC_TYPE_LENGTH); argument = imc_getarg(argument, out.i.to, IMC_NAME_LENGTH); if(!out.i.from[0] || !seq[0] || !out.i.path[0] || !out.type[0] || !out.i.to[0]) { imc_logerror("interpret2: bad packet received, discarding"); return NULL; } parsekeys(argument, &out.data); out.i.sequence = strtoul(seq, NULL, 10); return &out; }
/* 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)); }
void icec_save_channels(void) { ice_channel *c; FILE *fp; char name[MAX_STRING_LENGTH]; strcpy(name, imc_prefix); strcat(name, "icec"); fp=fopen(name, "w"); if (!fp) { imc_logerror("Can't write to %s", name); return; } for (c=saved_channel_list; c; c=c->next) { /* update */ ice_channel *current=icec_findlchannel(c->local->name); if (current) { imc_strfree(c->name); imc_strfree(c->local->format1); imc_strfree(c->local->format2); c->name=imc_strdup(current->name); c->local->format1=imc_strdup(current->local->format1); c->local->format2=imc_strdup(current->local->format2); c->local->level=current->local->level; } /* save */ fprintf(fp, "%s %s %d\n" "%s\n" "%s\n", c->name, c->local->name, c->local->level, c->local->format1, c->local->format2); } fclose(fp); }
void icec_load_channels(void) { FILE *fp; char name[MAX_STRING_LENGTH]; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char buf3[MAX_STRING_LENGTH]; char buf4[MAX_STRING_LENGTH]; int l; strcpy(name, imc_prefix); strcat(name, "icec"); fp=fopen(name, "r"); if (!fp) { imc_logerror("Can't open %s", name); return; } while (fscanf(fp, "%s %s %d\n" "%[^\n]\n" "%[^\n]\n", buf1, buf2, &l, buf3, buf4) == 5) { ice_channel *c=imc_malloc(sizeof(*c)); c->local=imc_malloc(sizeof(*c->local)); c->name=imc_strdup(buf1); c->local->name=imc_strdup(buf2); c->local->format1=imc_strdup(buf3); c->local->format2=imc_strdup(buf4); c->local->level=l; c->next=saved_channel_list; saved_channel_list=c; imc_logstring("ICEc: configured %s as %s", c->name, c->local->name); } fclose(fp); }
/* write to descriptor */ static void do_write(imc_connect *c) { int size, w; if (c->state==IMC_CONNECTING) { /* Wait for server password */ c->state=IMC_WAIT2; return; } size = strlen(c->outbuf); if (!size) /* nothing to write */ return; w=write(c->desc, c->outbuf, size); if (!w || (w<0 && errno != EAGAIN && errno != EWOULDBLOCK)) { if (!c->info || !(c->info->flags & IMC_QUIET)) { if (w<0) /* write error */ { imc_lerror("%s: write", imc_getconnectname(c)); } else /* socket was closed */ { imc_logerror("%s: write: EOF", imc_getconnectname(c)); } } do_close(c); return; } if (w<0) /* EAGAIN */ return; /* throw away data we wrote */ // memmove(c->outbuf, c->outbuf+w, size-w+1); strcpy(c->outbuf,c->outbuf+w); imc_stats.tx_bytes += w; }
/* close down imc */ void imc_shutdown(void) { imc_ignore_data *ign, *ign_next; imc_info *info, *info_next; if (imc_active==IA_NONE) { imc_logerror("imc_shutdown: called with imc_active==0"); return; } if (imc_active>=IA_UP) imc_shutdown_network(); for (ign=imc_ignore_list; ign; ign=ign_next) { ign_next=ign->next; imc_freeignore(ign); } imc_ignore_list=NULL; for (info=imc_info_list; info; info=info_next) { info_next=info->next; imc_delete_info(info); } imc_info_list=NULL; if (imc_active >= IA_UP) imc_shutdown_network(); imc_strfree(imc_prefix); imc_prefix=NULL; if (imc_active >= IA_CONFIG2) imc_strfree(imc_name); imc_name=NULL; imc_active=IA_NONE; }
/* 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; }
/* connect to given mud */ int imc_connect_to(const char *mud) { imc_info *i; imc_connect *c; int desc; struct sockaddr_in sa; char buf[IMC_DATA_LENGTH]; int r; if (imc_active == IA_NONE) { imc_qerror("IMC is not active"); return 0; } i=imc_getinfo(mud); if (!i) { imc_qerror("%s: unknown mud name", mud); return 0; } if (i->connection) { imc_qerror("%s: already connected", mud); return 0; } if (i->flags & IMC_CLIENT) { imc_qerror("%s: client-only flag is set", mud); return 0; } if (i->flags & IMC_DENY) { imc_qerror("%s: deny flag is set", mud); return 0; } if (!(i->flags & IMC_QUIET)) imc_logstring("connect to %s", mud); /* warning: this blocks. It would be better to farm the query out to * another process, but that is difficult to do without lots of changes * to the core mud code. You may want to change this code if you have an * existing resolver process running. */ if ((sa.sin_addr.s_addr=inet_addr(i->host)) == -1UL) { struct hostent *hostinfo; if (NULL == (hostinfo=gethostbyname(i->host))) { imc_logerror("imc_connect: couldn't resolve hostname"); return 0; } sa.sin_addr.s_addr = *(unsigned long *) hostinfo->h_addr; } sa.sin_port = htons(i->port); sa.sin_family = AF_INET; desc=socket(AF_INET, SOCK_STREAM, 0); if (desc<0) { imc_lerror("socket"); return 0; } r=fcntl(desc, F_GETFL, 0); if (r<0 || fcntl(desc, F_SETFL, O_NONBLOCK | r)<0) { imc_lerror("imc_connect: fcntl"); close(desc); return 0; } if (connect(desc, (struct sockaddr *)&sa, sizeof(sa))<0) if (errno != EINPROGRESS) { imc_lerror("connect"); close(desc); return 0; } c=imc_new_connect(); c->desc = desc; c->state = IMC_CONNECTING; c->info = i; imc_add_event(IMC_LOGIN_TIMEOUT, ev_login_timeout, c, 1); sprintf(buf, "PW %s %s version=%d", imc_name, i->clientpw, IMC_VERSION); do_send(c, buf); return 1; }
/* low-level idle function: read/write buffers as needed, etc */ void imc_idle_select(fd_set *read, fd_set *write, fd_set *exc, time_t now) { const char *command; imc_packet *p; imc_connect *c, *c_next ; if (imc_active<IA_CONFIG1) return; if (imc_lock) { imc_logerror("imc_idle_select: recursive call"); return; } imc_lock=1; if (imc_sequencenumber < (unsigned long)imc_now) imc_sequencenumber=(unsigned long)imc_now; imc_run_events(now); if (imc_active<IA_UP) { imc_lock=0; return; } /* handle results of the select */ if (imc_active >= IA_LISTENING && FD_ISSET(control, read)) do_accept(); for (c=imc_connect_list; c; c=c_next) { c_next=c->next; if (c->state!=IMC_CLOSED && FD_ISSET(c->desc, exc)) do_close(c); if (c->state!=IMC_CLOSED && FD_ISSET(c->desc, read)) do_read(c); while (c->state!=IMC_CLOSED && // (c->spamtime1>=0 || c->spamcounter1<=IMC_SPAM1MAX) && // (c->spamtime2>=0 || c->spamcounter2<=IMC_SPAM2MAX) && (command = get_one_line(c->inbuf)) != NULL) { if (strlen(command) > imc_stats.max_pkt) imc_stats.max_pkt=strlen(command); // imc_debug(c, 0, command); /* log incoming packets */ switch (c->state) { case IMC_CLOSED: break; case IMC_WAIT1: clientpassword(c, command); break; case IMC_WAIT2: serverpassword(c, command); break; case IMC_CONNECTED: p = do_interpret_packet(c, command); if (p) { #ifdef IMC_PARANOIA /* paranoia: check the last entry in the path is the same as the * sending mud. Also check the first entry to see that it matches * the sender. */ imc_stats.rx_pkts++; if (strcasecmp(c->info->name, imc_lastinpath(p->i.path))) imc_logerror("PARANOIA: packet from %s allegedly from %s", c->info->name, imc_lastinpath(p->i.path)); else if (strcasecmp(imc_mudof(p->i.from), imc_firstinpath(p->i.path))) imc_logerror("PARANOIA: packet from %s has firstinpath %s", p->i.from, imc_firstinpath(p->i.path)); else forward(p); /* only forward if its a valid packet! */ #else imc_stats.rx_pkts++; forward(p); #endif #ifdef SPAMPROT if (!strcasecmp(p->type, "chat") || !strcasecmp(p->type, "tell") || !strcasecmp(p->type, "emote") || 1) { if (!c->spamcounter1 && !c->spamtime1) imc_add_event(IMC_SPAM1INTERVAL, ev_spam1, c, 0); c->spamcounter1++; if (!c->spamcounter2 && !c->spamtime2) imc_add_event(IMC_SPAM2INTERVAL, ev_spam2, c, 0); c->spamcounter2++; } #endif imc_freedata(&p->data); } break; } } } for (c=imc_connect_list; c; c=c_next) { c_next=c->next; if (c->state!=IMC_CLOSED && (FD_ISSET(c->desc, write) || c->newoutput)) { // c->newoutput=0; do_write(c); c->newoutput=c->outbuf[0]; } } for (c=imc_connect_list; c; c=c_next) { c_next=c->next; if (c->state==IMC_CLOSED) imc_extract_connect(c); } imc_lock=0; }
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; }
/* start up IMC */ void imc_startup_network(void) { imc_info *info; int toggle=0; /* This is to tell after we've done reconnects if we've connected to a hub or not -- Scion */ if (imc_active != IA_CONFIG2) { imc_logerror("imc_startup_network: called with imc_active==%d", imc_active); return; } if (!imc_siteinfo.name[0]) { imc_logerror("InfoName not set, not initializing"); return; } if (!imc_siteinfo.email[0]) { imc_logerror("InfoEmail not set, not initializing"); return; } imc_logstring("network initializing"); imc_active=IA_UP; control=-1; if (imc_port) imc_startup_port(); imc_stats.start = imc_now; imc_stats.rx_pkts = 0; imc_stats.tx_pkts = 0; imc_stats.rx_bytes = 0; imc_stats.tx_bytes = 0; imc_stats.sequence_drops = 0; imc_add_event(20, ev_keepalive, NULL, 1); /* fill my imclist please - shogar */ imc_add_event(30, ev_request_keepalive, NULL, 1); imc_mail_startup(); /* start up the mailer */ if (!lock_prefix()) { imc_logstring("another process is using the same config prefix, not autoconnecting."); return; } /* do autoconnects */ for (info=imc_info_list; info; info=info->next) if (!(info->flags & IMC_NOAUTO) && !(info->flags & IMC_CLIENT) && !(info->flags & IMC_DENY) /* && !(info->flags & IMC_OLD_HUB) not used anymore - shogar && !(info->flags & IMC_DEAD_HUB) */ && !(info->flags & IMC_HUB)) { if (imc_connect_to(info->name) && ((info->flags & IMC_MAIN_HUB) || (info->flags & IMC_HUB))) toggle=1; } /* Setup optimization to run, it won't if we're a hub -- Scion */ if(imc_hubswitch && !imc_is_router) { imc_add_event(360, ev_imc_pollforhub, NULL, 1); imc_add_event(420, ev_imc_optimize, NULL, 1); imc_logstring("Setting auto-optimize to run in 6 minutes."); } /* Are we connected to any hubs, btw? -- Scion */ if (!toggle) { /* No hubs connected! */ for (info=imc_info_list; info; info=info->next) if ((info->flags & IMC_HUB) && (!toggle)) if (imc_connect_to(info->name)) toggle=0; } /* We're out of ideas, notify the admins -- Scion */ /* if (!toggle) imc_logstring("No hubs connected! Check the configuration!"); */ }
/* 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); } }
/* start up listening port */ void imc_startup_port(void) { int i; struct sockaddr_in sa; if (imc_active!=IA_UP) { imc_logerror("imc_startup_port: called with imc_active=%d", imc_active); return; } if (imc_port==0) { imc_logerror("imc_startup_port: called with imc_port=0"); return; } imc_logstring("binding port %d for incoming connections", imc_port); control = socket(AF_INET, SOCK_STREAM, 0); if (control<0) { imc_lerror("imc_startup_port: socket"); return; } i=1; if (setsockopt(control, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof(i))<0) { imc_lerror("imc_startup_port: SO_REUSEADDR"); close(control); return; } if ((i=fcntl(control, F_GETFL, 0))<0) { imc_lerror("imc_startup_port: fcntl(F_GETFL)"); close(control); return; } if (fcntl(control, F_SETFL, i | O_NONBLOCK)<0) { imc_lerror("imc_startup_port: fcntl(F_SETFL)"); close(control); return; } sa.sin_family = AF_INET; sa.sin_port = htons(imc_port); sa.sin_addr.s_addr = imc_bind; /* already in network order */ if (bind(control, (struct sockaddr *)&sa, sizeof(sa))<0) { imc_lerror("imc_startup_port: bind"); close(control); return; } if (listen(control, 1)<0) { imc_lerror("imc_startup_port: listen"); close(control); return; } imc_active=IA_LISTENING; }