void icec_recv_destroy(const char *from, const char *channel) { ice_channel *c; const char *mud; mud = imc_mudof(from); if(!strchr(channel, ':') || strcasecmp(mud, ice_mudof(channel))) { return; } c = icec_findchannel(channel); if(!c) { return; } if(c == icec_channel_list) { icec_channel_list = c->next; } else { ice_channel *p; for(p = icec_channel_list; p; p = p->next) if(p->next == c) { break; } if(p) { p->next = c->next; } } icec_localfree(c); imc_strfree(c->name); imc_strfree(c->owner); imc_strfree(c->operators); imc_strfree(c->invited); imc_strfree(c->excluded); }
/* Take the data from an info-reply packet and process it. We shouldn't get packets from MUDs, only from hubs. -- Scion */ void imc_recv_info_reply(const char *from, const char *hub, int direct) { /* Globals needed: hubname, directnum */ if (direct > global_directnum) { imc_info *i; /* spin infolist check for noswitch flag - shogar */ for (i=imc_info_list; i; i=i->next) if(i->flags & IMC_NOSWITCH && !strcasecmp(imc_mudof(from),i->name)) { imc_logstring("Rejecting info-reply(%d) from %s", direct,from); return; } imc_sncpy(global_hubname, imc_mudof(from), IMC_MNAME_LENGTH); global_directnum=direct; } imc_logstring("Received info-reply(%d) from %s", direct,from); }
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); }
/* beep a remote player */ void imc_send_beep(const imc_char_data *from, const char *to) { imc_packet out; if (imc_active<IA_UP) return; if (!strcmp(imc_mudof(to), "*")) return; /* don't let them do this */ setdata(&out, from); strcpy(out.type, "beep"); imc_sncpy(out.to, to, IMC_NAME_LENGTH); imc_send(&out); imc_freedata(&out.data); }
static void addrtomud(const char *list, char *output) { char arg[IMC_NAME_LENGTH]; output[0]=0; list=imc_getarg(list, arg, IMC_NAME_LENGTH); while (*arg) { if (!strcasecmp(imc_name, imc_mudof(arg))) sprintf(output + strlen(output), "%s ", imc_nameof(arg)); else sprintf(output + strlen(output), "%s ", arg); list=imc_getarg(list, arg, IMC_NAME_LENGTH); } }
/* respond with a whois-reply */ void imc_send_whoisreply(const char *to, const char *data) { imc_packet out; if (imc_active<IA_UP) return; if (!strcmp(imc_mudof(to), "*")) return; /* don't let them do this */ imc_initdata(&out.data); imc_sncpy(out.to, to, IMC_NAME_LENGTH); strcpy(out.type, "whois-reply"); strcpy(out.from, "*"); imc_addkey(&out.data, "text", data); imc_send(&out); imc_freedata(&out.data); }
/* send a who-request to a remote mud */ void imc_send_who(const imc_char_data *from, const char *to, const char *type) { imc_packet out; if (imc_active<IA_UP) return; if (!strcmp(imc_mudof(to), "*")) return; /* don't let them do this */ setdata(&out, from); sprintf(out.to, "*@%s", to); strcpy(out.type, "who"); imc_addkey(&out.data, "type", type); imc_send(&out); imc_freedata(&out.data); }
/* send a tell to a remote player */ void imc_send_tell(const imc_char_data *from, const char *to, const char *argument, int isreply) { imc_packet out; if (imc_active<IA_UP) return; if (!strcmp(imc_mudof(to), "*")) return; /* don't let them do this */ setdata(&out, from); imc_sncpy(out.to, to, IMC_NAME_LENGTH); strcpy(out.type, "tell"); imc_addkey(&out.data, "text", argument); if (isreply) imc_addkeyi(&out.data, "isreply", isreply); imc_send(&out); imc_freedata(&out.data); }
/* forward a packet - main routing function, all packets pass through here */ static void forward(imc_packet *p) { imc_info *i; int broadcast, isbroadcast; const char *to; imc_reminfo *route; imc_info *direct; imc_connect *c; char recievedfrom[IMC_MAXBUF]; /* SPAM fix - shogar */ imc_connect *rf; /* SPAM fix - shogar */ /* check for duplication, and register the packet in the sequence memory */ if (p->i.sequence && checkrepeat(imc_mudof(p->i.from), p->i.sequence)) return; /* check for packets we've already forwarded */ if (inpath(p->i.path, imc_name)) return; /* check for really old packets */ route=imc_find_reminfo(imc_mudof(p->i.from), 1); if (route) { if ((p->i.sequence+IMC_PACKET_LIFETIME) < route->top_sequence) { imc_stats.sequence_drops++; #ifdef LOG_LATE_PACKETS /* kind of spammy, but late packets are natural when the path is broken between sender and reciever if(imc_is_router) /* spare the muds from seeing this - shogar */ imc_logstring("sequence drop: %s (seq=%ld, top=%ld)", p->i.path, p->i.sequence, route->top_sequence); #endif return; } if (p->i.sequence > route->top_sequence) route->top_sequence=p->i.sequence; } /* update our routing info */ updateroutes(p->i.path); /* forward to our mud if it's for us */ if (!strcmp(imc_mudof(p->i.to), "*") || !strcasecmp(imc_mudof(p->i.to), imc_name)) { strcpy(p->to, imc_nameof(p->i.to)); /* strip the name from the 'to' */ strcpy(p->from, p->i.from); imc_recv(p); } /* if its only to us (ie. not broadcast) don't forward it */ if (!strcasecmp(imc_mudof(p->to), imc_name)) return; /* check if we should just drop it (policy rules) */ if (!can_forward(p)) return; /* convert a specific destination to a broadcast in some cases */ to=imc_mudof(p->i.to); isbroadcast=!strcmp(to, "*"); /* broadcasts are, well, broadcasts */ broadcast=1; /* unless we know better, flood packets */ i=0; /* make gcc happy */ direct=NULL; /* no direct connection to send on */ /* convert 'to' fields that we have a route for to a hop along the route */ if (!isbroadcast && (route=imc_find_reminfo(to, 0)) != NULL && route->route != NULL && !inpath(p->i.path, route->route)) /* avoid circular routing */ { /* check for a direct connection: if we find it, and the route isn't * to it, then the route is a little suspect.. also send it direct */ if (strcasecmp(to, route->route) && (i=imc_getinfo(to))!=NULL && i->connection) direct=i; to=route->route; } /* check for a direct connection */ if (!isbroadcast && (i=imc_getinfo(to)) != NULL && i->connection && !(i->flags & IMC_BROADCAST)) broadcast=0; if (broadcast) { /* need to forward a packet */ /* SPAM fix - hubcnt and who just gave us the packet- shogar */ int hubcnt,fromhub; hubcnt=0; fromhub=0; strcpy(recievedfrom,imc_lastinpath(p->i.path)); for (rf=imc_connect_list; rf; rf=rf->next) { if(rf->info && rf->info->name && !strcmp(recievedfrom,rf->info->name)) { if(rf->info->flags & IMC_HUB) fromhub=1; } } /* end SPAM fix */ for (c=imc_connect_list; c; c=c->next) if (c->state==IMC_CONNECTED) { /* don't forward to sites that have already received it, * or sites that don't need this packet */ if (inpath(p->i.path, c->info->name) || (p->i.stamp & c->info->noforward)!=0) continue; /* SPAM fix - shogar */ if(c->info->flags & IMC_HUB) { if(!imc_is_router) { if (fromhub) continue; if(hubcnt) { continue; } else { hubcnt=1; } } /* if for imc3 we need to do this - shogar */ /* if (imc_getkeyi(&p->data,"channel",0) == 2) continue; */ } /* end SPAM fix */ do_send_packet(c, p); } } else /* forwarding to a specific connection */ { /* but only if they haven't seen it (sanity check) */ if (i->connection && !inpath(p->i.path, i->name)) do_send_packet(i->connection, p); /* send on direct connection, if we have one */ if (direct && direct!=i && direct->connection && !inpath(p->i.path, direct->name)) do_send_packet(direct->connection, p); } }
/* 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 do_chess( CHAR_DATA * ch, const char *argument ) { char arg[MAX_INPUT_LENGTH]; argument = one_argument( argument, arg ); if ( IS_NPC( ch ) ) { send_to_char( "NPC's can't be in chess games.\r\n", ch ); return; } if ( !str_cmp( arg, "begin" ) ) { GAME_BOARD_DATA *board; if ( ch->pcdata->game_board ) { send_to_char( "You are already in a chess match.\r\n", ch ); return; } CREATE( board, GAME_BOARD_DATA, 1 ); init_board( board ); ch->pcdata->game_board = board; ch->pcdata->game_board->player1 = QUICKLINK( ch->name ); send_to_char( "You have started a game of chess.\r\n", ch ); return; } if ( !str_cmp( arg, "join" ) ) { GAME_BOARD_DATA *board = NULL; CHAR_DATA *vch; char arg2[MAX_INPUT_LENGTH]; if ( ch->pcdata->game_board ) { send_to_char( "You are already in a game of chess.\r\n", ch ); return; } argument = one_argument( argument, arg2 ); if ( arg2[0] == '\0' ) { send_to_char( "Join whom in a chess match?\r\n", ch ); return; } #ifdef IMC if ( strstr( arg2, "@" ) ) { if ( !str_cmp( imc_mudof( arg2 ), this_imcmud->localname ) ) { send_to_char( "You cannot join IMC chess on the local mud!\r\n", ch ); return; } if ( !str_cmp( imc_mudof( arg2 ), "*" ) ) { send_to_char( "* is not a valid mud name.\r\n", ch ); return; } if ( !str_cmp( imc_nameof( arg2 ), "*" ) ) { send_to_char( "* is not a valid player name.\r\n", ch ); return; } send_to_char( "Attempting to initiate IMC chess game...\r\n", ch ); CREATE( board, GAME_BOARD_DATA, 1 ); init_board( board ); board->type = TYPE_IMC; board->player1 = QUICKLINK( ch->name ); board->player2 = STRALLOC( arg2 ); board->turn = -1; ch->pcdata->game_board = board; imc_send_chess( ch->name, arg2, "start" ); return; } #endif if ( !( vch = get_char_world( ch, arg2 ) ) ) { send_to_char( "Cannot find that player.\r\n", ch ); return; } if ( IS_NPC( vch ) ) { send_to_char( "That player is an NPC, and cannot play games.\r\n", ch ); return; } board = vch->pcdata->game_board; if ( !board ) { send_to_char( "That player is not playing a game.\r\n", ch ); return; } if ( board->player2 ) { send_to_char( "That game already has two players.\r\n", ch ); return; } board->player2 = QUICKLINK( ch->name ); ch->pcdata->game_board = board; send_to_char( "You have joined a game of chess.\r\n", ch ); vch = get_char_world( ch, board->player1 ); ch_printf( vch, "%s has joined your game.\r\n", ch->name ); return; } if ( !ch->pcdata->game_board ) { send_to_char( "Usage: chess <begin|cease|status|board|move|join>\r\n", ch ); return; } if ( !str_cmp( arg, "cease" ) ) { free_game( ch->pcdata->game_board ); return; } if ( !str_cmp( arg, "status" ) ) { GAME_BOARD_DATA *board = ch->pcdata->game_board; if ( !board->player1 ) send_to_char( "There is no black player.\r\n", ch ); else if ( !str_cmp( board->player1, ch->name ) ) send_to_char( "You are black.\r\n", ch ); else ch_printf( ch, "%s is black.\r\n", board->player1 ); if ( king_in_checkmate( board, BLACK_KING ) ) send_to_char( "The black king is in checkmate!\r\n", ch ); else if ( king_in_check( board, BLACK_KING ) ) send_to_char( "The black king is in check.\r\n", ch ); if ( !board->player2 ) send_to_char( "There is no white player.\r\n", ch ); else if ( !str_cmp( board->player2, ch->name ) ) send_to_char( "You are white.\r\n", ch ); else ch_printf( ch, "%s is white.\r\n", board->player2 ); if ( king_in_checkmate( board, WHITE_KING ) ) send_to_char( "The white king is in checkmate!\r\n", ch ); else if ( king_in_check( board, WHITE_KING ) ) send_to_char( "The white king is in check.\r\n", ch ); if ( !board->player2 || !board->player1 ) return; ch_printf( ch, "%d turns.\r\n", board->turn ); if ( board->turn % 2 == 1 && !str_cmp( board->player1, ch->name ) ) { ch_printf( ch, "It is %s's turn.\r\n", board->player2 ); return; } else if ( board->turn % 2 == 0 && !str_cmp( board->player2, ch->name ) ) { ch_printf( ch, "It is %s's turn.\r\n", board->player1 ); return; } else { send_to_char( "It is your turn.\r\n", ch ); return; } return; } if ( !str_prefix( arg, "board" ) ) { send_to_char( print_big_board( ch, ch->pcdata->game_board ), ch ); return; } if ( !str_prefix( arg, "move" ) ) { CHAR_DATA *opp; char opp_name[MAX_INPUT_LENGTH]; char a, b; int x, y, dx, dy, ret; if ( !ch->pcdata->game_board->player1 || !ch->pcdata->game_board->player2 ) { send_to_char( "There is only 1 player.\r\n", ch ); return; } if ( ch->pcdata->game_board->turn < 0 ) { send_to_char( "The game hasn't started yet.\r\n", ch ); return; } if ( king_in_checkmate( ch->pcdata->game_board, BLACK_KING ) ) { send_to_char( "The black king has been checkmated, the game is over.\r\n", ch ); return; } if ( king_in_checkmate( ch->pcdata->game_board, WHITE_KING ) ) { send_to_char( "The white king has been checkmated, the game is over.\r\n", ch ); return; } if ( !*argument ) { send_to_char( "Usage: chess move [piece to move] [where to move]\r\n", ch ); return; } if ( ch->pcdata->game_board->turn % 2 == 1 && !str_cmp( ch->pcdata->game_board->player1, ch->name ) ) { send_to_char( "It is not your turn.\r\n", ch ); return; } if ( ch->pcdata->game_board->turn % 2 == 0 && !str_cmp( ch->pcdata->game_board->player2, ch->name ) ) { send_to_char( "It is not your turn.\r\n", ch ); return; } if ( sscanf( argument, "%c%d %c%d", &a, &y, &b, &dy ) != 4 ) { send_to_char( "Usage: chess move [dest] [source]\r\n", ch ); return; } if ( a < 'a' || a > 'h' || b < 'a' || b > 'h' || y < 1 || y > 8 || dy < 1 || dy > 8 ) { send_to_char( "Invalid move, use a-h, 1-8.\r\n", ch ); return; } x = a - 'a'; dx = b - 'a'; --y; --dy; ret = is_valid_move( ch, ch->pcdata->game_board, x, y, dx, dy ); if ( ret == MOVE_OK || ret == MOVE_TAKEN ) { GAME_BOARD_DATA *board; int piece, destpiece; board = ch->pcdata->game_board; piece = board->board[x][y]; destpiece = board->board[dx][dy]; board->board[dx][dy] = piece; board->board[x][y] = NO_PIECE; if ( king_in_check( board, IS_WHITE( board->board[dx][dy] ) ? WHITE_KING : BLACK_KING ) && ( board->board[dx][dy] != WHITE_KING && board->board[dx][dy] != BLACK_KING ) ) { board->board[dx][dy] = destpiece; board->board[x][y] = piece; ret = MOVE_INCHECK; } else { ++board->turn; #ifdef IMC if ( ch->pcdata->game_board->type == TYPE_IMC ) { snprintf( arg, LGST, "move %d%d %d%d", x, y, dx, dy ); imc_send_chess( ch->pcdata->game_board->player1, ch->pcdata->game_board->player2, arg ); } #endif } } if ( !str_cmp( ch->name, ch->pcdata->game_board->player1 ) ) { opp = get_char_world( ch, ch->pcdata->game_board->player2 ); if ( !opp ) mudstrlcpy( opp_name, ch->pcdata->game_board->player2, MAX_INPUT_LENGTH ); } else { opp = get_char_world( ch, ch->pcdata->game_board->player1 ); if ( !opp ) mudstrlcpy( opp_name, ch->pcdata->game_board->player1, MAX_INPUT_LENGTH ); } #ifdef IMC # define SEND_TO_OPP(arg,opp) \ if( opp ) \ { \ if( ch->pcdata->game_board->type == TYPE_LOCAL ) \ ch_printf( (opp), "%s\r\n", (arg) ); \ } \ else \ { \ if( ch->pcdata->game_board->type == TYPE_IMC ) \ imc_send_tell( ch->name, opp_name, (arg), 1 ); \ } #else # define SEND_TO_OPP(arg,opp) \ if( opp ) \ { \ if( ch->pcdata->game_board->type == TYPE_LOCAL ) \ ch_printf( (opp), "%s\r\n", (arg) ); \ } #endif switch ( ret ) { case MOVE_OK: send_to_char( "Ok.\r\n", ch ); snprintf( arg, MAX_INPUT_LENGTH, "%s has moved.\r\n", ch->name ); SEND_TO_OPP( arg, opp ); break; case MOVE_INVALID: send_to_char( "Invalid move.\r\n", ch ); break; case MOVE_BLOCKED: send_to_char( "You are blocked in that direction.\r\n", ch ); break; case MOVE_TAKEN: send_to_char( "You take the enemy's piece.\r\n", ch ); snprintf( arg, MAX_INPUT_LENGTH, "%s has taken one of your pieces!", ch->name ); SEND_TO_OPP( arg, opp ); break; case MOVE_CHECKMATE: send_to_char( "That move would result in a checkmate.\r\n", ch ); snprintf( arg, MAX_INPUT_LENGTH, "%s has attempted a move that would result in checkmate.", ch->name ); SEND_TO_OPP( arg, opp ); break; case MOVE_OFFBOARD: send_to_char( "That move would be off the board.\r\n", ch ); break; case MOVE_SAMECOLOR: send_to_char( "Your own piece blocks the way.\r\n", ch ); break; case MOVE_CHECK: send_to_char( "That move would result in a check.\r\n", ch ); snprintf( arg, MAX_INPUT_LENGTH, "%s has made a move that would result in a check.", ch->name ); SEND_TO_OPP( arg, opp ); break; case MOVE_WRONGCOLOR: send_to_char( "That is not your piece.\r\n", ch ); break; case MOVE_INCHECK: send_to_char( "You are in check, you must save your king.\r\n", ch ); break; default: bug( "%s: Unknown return value", __FUNCTION__ ); break; } #undef SEND_TO_OPP return; } send_to_char( "Usage: chess <begin|cease|status|board|move|join>\r\n", ch ); }
/* 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); } } }
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); }
/* imc_recv_mailok: a mail-ok packet was received */ void imc_recv_mailok(const char *from, const char *id) { delete_mq(id, imc_mudof(from)); save_mq(); save_ml(); /* we might have removed the mail if usage==0 */ }
/* 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(); }