void imc_autoconnect_reply_accept(const char *from, const char *rhost, int rport, const char *rclientpw, const char *rserverpw, int rrcvstamp, int rnoforward, const char *rflags, const char *remotename, const char *confirm) { /* Wow.. what a function name! This gets the packet that says "connection added" in it from the hub, then adds the appropriate connection here. -- Scion */ imc_info *i,*o; imc_logstring("Received autoconnect reply from %s.", remotename); if (strcasecmp(confirm, "connection added")) { /* Don't change this, or it won't work. */ imc_logstring("Confirmation refused: %s", confirm); return; } if (imc_name && !strcasecmp(remotename, imc_name)) { imc_logstring("Autoconnect attempt allegedly from this host! Ignoring."); return; /* Hey! That's our name! */ } else if (!strcasecmp(rhost, "!!!")) { imc_logstring("Unknown host name for %s. Aborting.", remotename); return; } else { /* Setup the new connection... */ if((o=imc_getinfo(remotename))) /* remove old entries - shogar */ { i=imc_insert_info(); i->connection=o->connection; i->flags=o->flags; if(i->connection) i->connection->info=i; imc_cancel_info(o); } else { i=imc_insert_info(); // i->flags = imc_flagvalue("hub reconnect new", imc_connection_flags); i->flags = imc_flagvalue("hub new", imc_connection_flags); } i->name = imc_strdup(remotename); i->host = imc_strdup(rhost); i->port = (unsigned short)rport; i->clientpw = imc_strdup(rclientpw); i->serverpw = imc_strdup(rserverpw); i->rcvstamp = rrcvstamp; i->noforward = rnoforward; i->connect_attempts = 0; imc_saveconfig(); imc_connect_to(remotename); /* All done! */ imc_logstring("Added connection to %s.", remotename); } imc_send_keepalive(); }
void icec_recv_update(const char *from, const char *chan, const char *owner, const char *operators, const char *policy, const char *invited, const char *excluded) { ice_channel *c; const char *mud; mud = imc_mudof(from); /* forged? */ if(!strchr(chan, ':') || strcasecmp(mud, ice_mudof(chan))) { return; } c = icec_findchannel(chan); if(!c) { c = imc_malloc(sizeof(*c)); c->name = imc_strdup(chan); c->owner = imc_strdup(owner); c->operators = imc_strdup(operators); c->invited = imc_strdup(invited); c->excluded = imc_strdup(excluded); c->local = NULL; c->active = NULL; c->next = icec_channel_list; icec_channel_list = c; } else { imc_strfree(c->owner); imc_strfree(c->operators); imc_strfree(c->invited); imc_strfree(c->excluded); c->name = imc_strdup(chan); c->owner = imc_strdup(owner); c->operators = imc_strdup(operators); c->invited = imc_strdup(invited); c->excluded = imc_strdup(excluded); } if(!strcasecmp(policy, "open")) { c->policy = ICE_OPEN; } else if(!strcasecmp(policy, "closed")) { c->policy = ICE_CLOSED; } else { c->policy = ICE_PRIVATE; } if(c->local && !ice_audible(c, imc_name)) { icec_localfree(c); } icec_notify_update(c); imc_cancel_event(ev_icec_timeout, c); imc_add_event(ICEC_TIMEOUT, ev_icec_timeout, c, 0); }
/* update our routing table based on a packet received with path "path" */ static void updateroutes(const char *path) { imc_reminfo *p; const char *sender, *last; const char *temp; /* loop through each item in the path, and update routes to there */ last = imc_lastinpath(path); temp = path; while (temp && temp[0]) { sender=imc_firstinpath(temp); if (strcasecmp(sender, imc_name)) { /* not from us */ /* check if its in the list already */ p = imc_find_reminfo(sender, 1); if (!p) /* not in list yet, create a new entry */ { p=imc_new_reminfo(); p->name = imc_strdup(sender); p->ping = 0; p->alive = imc_now; p->route = imc_strdup(last); p->version = imc_strdup("unknown"); p->type = IMC_REMINFO_NORMAL; } else { /* already in list, update the entry */ if (strcasecmp(last, p->route)) { imc_strfree(p->route); p->route=imc_strdup(last); } p->alive=imc_now; p->type = IMC_REMINFO_NORMAL; } } /* get the next item in the path */ temp=strchr(temp, '!'); if (temp) temp++; /* skip to just after the next '!' */ } }
void imc_startup(const char *prefix) { if (imc_active!=IA_NONE) { imc_logstring("imc_startup: called with imc_active=%d", imc_active); return; } imc_now=time(NULL); /* start our clock */ imc_boot=imc_now; imc_logstring("%s initializing", IMC_VERSIONID); #ifdef USEIOCTL outqsize = getsndbuf(); imc_logstring("found TIOCOUTQ=%d", outqsize); #endif imc_prefix=imc_strdup(prefix); imc_sequencenumber=imc_now; strcpy(imc_lasterror, "no error"); imc_readconfig(); imc_readignores(); imc_active = imc_name ? IA_CONFIG2 : IA_CONFIG1; if (imc_active==IA_CONFIG2) imc_startup_network(); }
/* 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; }
/* called when a keepalive has been received */ void imc_recv_keepalive(const char *from, const char *version, const char *flags) { imc_reminfo *p; if (!strcasecmp(from, imc_name)) return; /* this should never fail, imc.c should create an * entry if one doesn't exist (in the path update * code) */ p=imc_find_reminfo(from, 0); if (!p) /* boggle */ return; if(!time_of_last_ralive) { time_of_last_ralive=time(NULL); } else { time_since_last_ralive = time(NULL) - time_of_last_ralive; time_of_last_ralive =time(NULL); } if (imc_hasname(flags, "hide")) p->hide=1; else p->hide=0; /* lower-level code has already updated p->alive */ if (strcasecmp(version, p->version)) /* remote version has changed? */ { imc_strfree(p->version); /* if so, update it */ p->version=imc_strdup(version); } /* Only routers should ping - and even then, only directly connected muds */ /* and only if there is an open connection - shogar */ if (imc_is_router && imc_getinfo(from) && imc_getinfo(from)->connection && imc_getinfo(from)->connection->state==IMC_CONNECTED) { struct timeval tv; gettimeofday(&tv, NULL); imc_send_ping(from, tv.tv_sec, tv.tv_usec); } /* or muds acting as a hub to another mud - shogar */ if (!imc_is_router && imc_getinfo(from) && imc_getinfo(from)->connection && !(imc_getinfo(from)->flags & IMC_HUB) && mud_has_hub) { struct timeval tv; gettimeofday(&tv, NULL); imc_send_ping(from, tv.tv_sec, tv.tv_usec); } }
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); }
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_notify_update(ice_channel *c) { if (!c->local) { /* saved channel? */ ice_channel *saved; for (saved=saved_channel_list; saved; saved=saved->next) if (!strcasecmp(saved->name, c->name)) { c->local=imc_malloc(sizeof(icec_lchannel)); c->local->name=imc_strdup(saved->local->name); c->local->format1=imc_strdup(saved->local->format1); c->local->format2=imc_strdup(saved->local->format2); c->local->level=saved->local->level; return; } } }
/* init_ml: init the maillist */ static void init_ml(void) { imc_ml_head = new_mail(); imc_ml_head->to = imc_strdup(""); imc_ml_head->from = imc_strdup(""); imc_ml_head->date = imc_strdup(""); imc_ml_head->subject = imc_strdup(""); imc_ml_head->text = imc_strdup(""); imc_ml_head->id = imc_strdup(""); }
/* read_mailid: read a mailid from a file, NULL on EOF */ static imc_mailid *read_mailid(FILE *in) { imc_mailid *p; char line[IMC_DATA_LENGTH]; char temp[IMC_DATA_LENGTH]; time_t r; fgets(line, IMC_DATA_LENGTH, in); if (ferror(in) || feof(in)) return NULL; sscanf(line, "%[^ ] %ld", temp, &r); p=new_mailid(); p->id = imc_strdup(temp); p->received = r; return p; }
/* checkrepeat: check for repeats in the memory table */ static int checkrepeat(const char *mud, unsigned long seq) { int i; for (i=0; i<IMC_MEMORY; i++) if (imc_memory[i].from && !strcasecmp(mud, imc_memory[i].from) && seq == imc_memory[i].sequence) return 1; /* not a repeat, so log it */ if (imc_memory[memory_head].from) imc_strfree(imc_memory[memory_head].from); imc_memory[memory_head].from = imc_strdup(mud); imc_memory[memory_head].sequence = seq; memory_head++; if (memory_head==IMC_MEMORY) memory_head=0; return 0; }
/* read_mail: read a single mail from a file, NULL on EOF */ static imc_mail *read_mail(FILE *in) { imc_mail *p; char line[IMC_DATA_LENGTH]; char temp[IMC_DATA_LENGTH]; fgets(line, IMC_DATA_LENGTH, in); if (ferror(in) || feof(in)) return NULL; p=new_mail(); sscanf(line, "From %[^\n]", temp); p->from=imc_strdup(unescape(temp)); fgets(line, IMC_DATA_LENGTH, in); sscanf(line, "To %[^\n]", temp); p->to=imc_strdup(unescape(temp)); fgets(line, IMC_DATA_LENGTH, in); sscanf(line, "Subject %[^\n]", temp); p->subject=imc_strdup(unescape(temp)); fgets(line, IMC_DATA_LENGTH, in); sscanf(line, "Date %[^\n]", temp); p->date=imc_strdup(unescape(temp)); fgets(line, IMC_DATA_LENGTH, in); sscanf(line, "Text %[^\n]", temp); p->text=imc_strdup(unescape(temp)); fgets(line, IMC_DATA_LENGTH, in); sscanf(line, "ID %[^\n]", temp); p->id=imc_strdup(unescape(temp)); fgets(line, IMC_DATA_LENGTH, in); sscanf(line, "Received %ld", &p->received); p->usage=0; return p; }
/* imc_send_mail: called by the mud to add a piece of mail to the queue */ void imc_send_mail(const char *from, const char *to, const char *date, const char *subject, const char *text) { char temp[IMC_DATA_LENGTH]; imc_mail *m; imc_qnode *qroot, *q; char arg[IMC_NAME_LENGTH]; const char *mud; int when=10; /* set up the entry for the mail list */ m=new_mail(); mudtoaddr(to, temp); /* qualify local addresses */ m->to = imc_strdup(temp); sprintf(temp, "%s@%s", from, imc_name); /* qualify sender */ m->from = imc_strdup(temp); m->date = imc_strdup(date); m->subject = imc_strdup(subject); m->id = imc_strdup(generate_mailid()); m->text = imc_strdup(text); m->received = imc_now; qroot=NULL; /* initialise the local list */ to=imc_getarg(to, arg, IMC_NAME_LENGTH); while (*arg) { /* get a mudname and check if we've already added a queue entry for that * mud. If not, add it */ if (strchr(arg, '@') != NULL && (mud = imc_mudof(arg))[0] != 0 && strcasecmp(mud, imc_name)) { if (!strcmp(mud, "*")) q=NULL; /* catch the @* case - not yet implemented */ else for (q=qroot; q; q=q->next) if (!strcasecmp(q->tomud, mud)) break; if (!q) /* not seen yet */ { /* add to the top of our mini-queue */ q=new_qnode(); q->tomud=imc_strdup(mud); q->data=m; q->next=qroot; m->usage++; qroot=q; imc_add_event(when, ev_qnode_send, q, 1); when += rand()%30+30; } } /* get the next address */ to=imc_getarg(to, arg, IMC_NAME_LENGTH); } if (!qroot) /* boggle, no foreign addresses?? */ { free_mail(m); return; } /* add mail to mail list, add mini-queue to mail queue */ add_ml(m); add_mq(qroot); save_ml(); save_mq(); }
void imc_recv_mail(const char *from, const char *to, const char *date, const char *subject, const char *id, const char *text) { imc_mailid *mid; imc_packet out; char *reason; char temp[IMC_DATA_LENGTH]; /* silently drop broadcast mail */ if (strchr(to, '*')) return; imc_initdata(&out.data); sprintf(out.to, "Mail-daemon@%s", imc_mudof(from)); strcpy(out.from, "Mail-daemon"); /* check if we've already seen it */ mid=find_id(id); if (mid) { strcpy(out.type, "mail-ok"); imc_addkey(&out.data, "id", id); imc_send(&out); imc_freedata(&out.data); mid->received = imc_now; return; } /* check for rignores */ if (imc_isignored(from)) { strcpy(out.type, "mail-reject"); imc_addkey(&out.data, "id", id); imc_addkey(&out.data, "reason", "You are being ignored."); imc_send(&out); imc_freedata(&out.data); return; } /* forward it to the mud */ addrtomud(to, temp); if ((reason=imc_mail_arrived(from, temp, date, subject, text)) == NULL) { /* it was OK */ strcpy(out.type, "mail-ok"); imc_addkey(&out.data, "id", id); imc_send(&out); imc_freedata(&out.data); mid=new_mailid(); mid->id=imc_strdup(id); mid->received=imc_now; add_idlist(mid); save_idlist(); return; } /* mud rejected the mail */ strcpy(out.type, "mail-reject"); imc_addkey(&out.data, "id", id); imc_addkey(&out.data, "reason", reason); imc_send(&out); imc_freedata(&out.data); }
/* add the mud to our list if we're a hub, and reply with our info. -- Scion*/ void imc_recv_autoconnect(const char *to, const char *rhost, int rport, const char *rclientpw, const char *rserverpw, int rrcvstamp, int rnoforward, const char *rflags, const char *remotename) { imc_packet out; char no_port[IMC_MNAME_LENGTH]; int a=0,b=0; imc_info *i,*o; if (imc_active<IA_UP) return; /* Receive all this info: -- Scion imc set <mudname> all <host> <port> <clientpw> <serverpw> <rcvstamp> <noforward> <flags> */ #ifdef NO_OPTIMIZE imc_logstring("Autoconnect refused because NO_OPTIMIZE is defined."); return; #endif if (imc_name && !strcasecmp(remotename, imc_name)) { imc_logstring("Autoconnect attempt allegedly from this server! Ignoring."); return; /* Hey! That's our name! */ } /* Get that pesky port out of the host name */ for (a=0;a<strlen(imc_siteinfo.host); a++) { if (imc_siteinfo.host[a]==':' || imc_siteinfo.host[a]==' ') { break; } no_port[b++]=imc_siteinfo.host[a]; no_port[b]='\0'; } /* Send our information back to the MUD */ imc_initdata(&out.data); strcpy(out.type, "switch-reply"); strcpy(out.from, "*"); strcpy(out.to, "*@"); imc_sncpy(out.to+2, remotename, IMC_MNAME_LENGTH-2); imc_addkey(&out.data, "confirm", "connection added"); imc_addkey(&out.data, "host", no_port); /* don't put the port number in from imc_siteinfo.host b/c it's the game port */ imc_addkeyi(&out.data, "port", (int)imc_port); imc_addkey(&out.data, "clientpw", rclientpw); imc_addkey(&out.data, "serverpw", rserverpw); imc_addkeyi(&out.data, "rcvstamp", 0); imc_addkeyi(&out.data, "noforward", 0); imc_addkey(&out.data, "flags", "none"); imc_addkey(&out.data, "localname", imc_name); imc_send(&out); imc_freedata(&out.data); /* Setup the new connection... */ if((o=imc_getinfo(remotename))) /* remove old entries - shogar */ { i=imc_insert_info(); i->connection=o->connection; i->flags=o->flags; if (i->connection) i->connection->info=i; imc_cancel_info(o); } else { i=imc_insert_info(); i->flags = imc_flagvalue("new", imc_connection_flags); /* Hubs don't need specific flags really */ } i->name = imc_strdup(remotename); i->host = imc_strdup(rhost); i->port = (unsigned short)rport; i->clientpw = imc_strdup(rclientpw); i->serverpw = imc_strdup(rserverpw); i->rcvstamp = rrcvstamp; i->noforward = rnoforward; i->connect_attempts = 0; imc_saveconfig(); /* All done! */ imc_logstring("Autoconnect accepted from %s", to); }
void imc_whoreply_start(const char *to) { wr_sequence=0; wr_to=imc_strdup(to); wr_buf=imc_getsbuf(IMC_DATA_LENGTH); }
/* handle a packet destined for us, or a broadcast */ void imc_recv(const imc_packet *p) { imc_char_data d; int bcast; imc_reminfo *i; bcast=!strcmp(imc_mudof(p->i.to), "*") ? 1 : 0; getdata(p, &d); if(!imc_is_router) { i=imc_find_reminfo(imc_mudof(p->from),0); if(i) { if(i->path) imc_strfree(i->path); i->path=imc_strdup(p->i.path); i->ping=0; i->type=0; } } /* chat: message to a channel (broadcast) */ if (!strcasecmp(p->type, "chat") && !imc_isignored(p->from)) imc_recv_chat(&d, imc_getkeyi(&p->data, "channel", 0), imc_getkey(&p->data, "text", "")); /* emote: emote to a channel (broadcast) */ else if (!strcasecmp(p->type, "emote") && !imc_isignored(p->from)) imc_recv_emote(&d, imc_getkeyi(&p->data, "channel", 0), imc_getkey(&p->data, "text", "")); /* tell: tell a player here something */ else if (!strcasecmp(p->type, "tell")) { if (imc_isignored(p->from)) { imc_sendignore(p->from); } else { imc_recv_tell(&d, p->to, imc_getkey(&p->data, "text", ""), imc_getkeyi(&p->data, "isreply", 0)); } } /* who-reply: receive a who response */ else if (!strcasecmp(p->type, "who-reply")) imc_recv_whoreply(p->to, imc_getkey(&p->data, "text", ""), imc_getkeyi(&p->data, "sequence", -1)); /* who: receive a who request */ else if (!strcasecmp(p->type, "who")) { if (imc_isignored(p->from)) { imc_sendignore(p->from); } else { imc_recv_who(&d, imc_getkey(&p->data, "type", "who")); } } /* whois-reply: receive a whois response */ else if (!strcasecmp(p->type, "whois-reply")) imc_recv_whoisreply(p->to, imc_getkey(&p->data, "text", "")); /* whois: receive a whois request */ else if (!strcasecmp(p->type, "whois")) imc_recv_whois(&d, p->to); /* beep: beep a player */ else if (!strcasecmp(p->type, "beep")) { if (imc_isignored(p->from)) { imc_sendignore(p->from); } else { imc_recv_beep(&d, p->to); } } /* is-alive: receive a keepalive (broadcast) */ else if (!strcasecmp(p->type, "is-alive")) imc_recv_keepalive(imc_mudof(p->from), imc_getkey(&p->data, "versionid", "unknown"), imc_getkey(&p->data, "flags", "")); /* ping: receive a ping request */ else if (!strcasecmp(p->type, "ping")) imc_recv_ping(imc_mudof(p->from), imc_getkeyi(&p->data, "time-s", 0), imc_getkeyi(&p->data, "time-us", 0), p->i.path); /* ping-reply: receive a ping reply */ else if (!strcasecmp(p->type, "ping-reply")) imc_recv_pingreply(imc_mudof(p->from), imc_getkeyi(&p->data, "time-s", 0), imc_getkeyi(&p->data, "time-us", 0), imc_getkey(&p->data, "path", NULL), p->i.path); /* mail: mail something to a local player */ else if (!strcasecmp(p->type, "mail")) imc_recv_mail(imc_getkey(&p->data, "from", "error@hell"), imc_getkey(&p->data, "to", "error@hell"), imc_getkey(&p->data, "date", "(IMC error: bad date)"), imc_getkey(&p->data, "subject", "no subject"), imc_getkey(&p->data, "id", "bad_id"), imc_getkey(&p->data, "text", "")); /* mail-ok: remote confirmed that they got the mail ok */ else if (!strcasecmp(p->type, "mail-ok")) imc_recv_mailok(p->from, imc_getkey(&p->data, "id", "bad_id")); /* mail-reject: remote rejected our mail, bounce it */ else if (!strcasecmp(p->type, "mail-reject")) imc_recv_mailrej(p->from, imc_getkey(&p->data, "id", "bad_id"), imc_getkey(&p->data, "reason", "(IMC error: no reason supplied")); /* handle keepalive requests - shogar */ else if (!strcasecmp(p->type, "keepalive-request")) { if(imc_is_router) imc_logstring("Recieved keepalive request from %s", p->from); imc_send_keepalive(); } /* expire closed hubs - shogar */ else if (!strcasecmp(p->type, "close-notify")) { imc_reminfo *r; char fake[90]; struct timeval tv; if(imc_is_router) imc_logstring("%s reports %s closed.", p->from, imc_getkey(&p->data, "host","unknown")); if(imc_is_router) return; r = imc_find_reminfo(imc_getkey(&p->data,"host","unknown"),0); if(r) { r->type = IMC_REMINFO_EXPIRED; for(r=imc_reminfo_list;r;r=r->next) { char *sf; sprintf(fake,"!%s",imc_getkey(&p->data,"host","___unknown")); if(r->name && r->path && (sf=strstr(r->path,fake)) && sf && (*(sf+strlen(fake))=='!' || *(sf+strlen(fake)) == 0) ) { // imc_logstring("Expiring %s",r->path); r->type = IMC_REMINFO_EXPIRED; gettimeofday(&tv, NULL); imc_send_ping(r->name, tv.tv_sec, tv.tv_usec); } } } } /* These 4 added by me for the auto-hub-swap -- Scion 1/9/99 */ else if (!strcasecmp(p->type, "inforequest")) /* Request connection info from all 1.00a hubs -- Scion */ imc_recv_inforequest(p->from); /* Had to use inforequest because 0.10 responds to info-request :) */ else if (!strcasecmp(p->type, "info-reply")) /* receive the reply from the inforequest :) -- Scion */ imc_recv_info_reply(p->from, imc_getkey(&p->data, "hub", "no"), imc_getkeyi(&p->data, "direct", -1)); else if (!strcasecmp(p->type, "switch-reply")) /* hub confirmed that it added a connection to us. -- Scion */ imc_autoconnect_reply_accept( /* Add a connection back to the hub */ p->from, imc_getkey(&p->data, "host", "!!!"), imc_getkeyi(&p->data, "port", -1), imc_getkey(&p->data, "clientpw", "password"), imc_getkey(&p->data, "serverpw", "password"), imc_getkeyi(&p->data, "rcvstamp", 0), imc_getkeyi(&p->data, "noforward", 0), imc_getkey(&p->data, "flags", "none"), imc_getkey(&p->data, "localname", "!!!"), imc_getkey(&p->data, "confirm", "not accepted") ); else if (!strcasecmp(p->type, "imc-switch")) /* hub receives request to add a connection -- Scion */ imc_recv_autoconnect( p->from, imc_getkey(&p->data, "host", "!!!"), imc_getkeyi(&p->data, "port", -1), imc_getkey(&p->data, "clientpw", "password"), imc_getkey(&p->data, "serverpw", "password"), imc_getkeyi(&p->data, "rcvstamp", 0), imc_getkeyi(&p->data, "noforward", 0), imc_getkey(&p->data, "flags", "none"), imc_getkey(&p->data, "localname", "!!!") ); /* call catch-all fn if present */ else { imc_packet out; if (imc_recv_hook) if ((*imc_recv_hook)(p, bcast)) return; if (bcast || !strcasecmp(p->type, "reject")) return; /* reject packet */ if (!imc_is_router) { strcpy(out.type, "reject"); strcpy(out.to, p->from); strcpy(out.from, p->to); imc_clonedata(&p->data, &out.data); imc_addkey(&out.data, "old-type", p->type); imc_send(&out); imc_freedata(&out.data); } } }