void run_channel_monitor(void) { while (run_loop) { int n_events, i; n_events = epoll_wait(global_event_fd, global_events_list, MAX_EVENTS, 1); if (!run_loop) break; for (i = 0; i < n_events; i++) { struct channel_info *chan_info = (struct channel_info *) global_events_list[i].data.ptr; if ((global_events_list[i].events & EPOLLERR) || (global_events_list[i].events & EPOLLHUP)) { RTE_LOG(DEBUG, CHANNEL_MONITOR, "Remote closed connection for " "channel '%s'\n", chan_info->channel_path); remove_channel(&chan_info); continue; } if (global_events_list[i].events & EPOLLIN) { int n_bytes, err = 0; struct channel_packet pkt; void *buffer = &pkt; int buffer_len = sizeof(pkt); while (buffer_len > 0) { n_bytes = read(chan_info->fd, buffer, buffer_len); if (n_bytes == buffer_len) break; if (n_bytes == -1) { err = errno; RTE_LOG(DEBUG, CHANNEL_MONITOR, "Received error on " "channel '%s' read: %s\n", chan_info->channel_path, strerror(err)); remove_channel(&chan_info); break; } buffer = (char *)buffer + n_bytes; buffer_len -= n_bytes; } if (!err) process_request(&pkt, chan_info); } } } }
void options(canal_t *add_chan,int temp){ switch (temp) { case 1: show_program(add_chan); break; case 2: add_channel(add_chan); break; case 3: remove_channel(add_chan); break; case 4: show_block_channel(add_chan); break; case 5: search_channel_num(add_chan); break; case 6: search_channel_name(add_chan); break; case 7: record_list(add_chan); break; case 8: load_list(add_chan); break; case 9: record_list_bin(add_chan); break; case 10: load_list_bin(); break; default: break; } }
static void p_part(char *from, char **ArgList) { char *channel; if (!from || !*from) return; channel = ArgList[0]; PasteArgs(ArgList, 1); message_from(channel, LOG_CRAP); in_on_who = 1; if ((check_ignore(from, FromUserHost, channel, IGNORE_PARTS | IGNORE_CRAP, NULL) != IGNORED) && do_hook(LEAVE_LIST, "%s %s %s %s", from, channel, FromUserHost, ArgList[1] ? ArgList[1] : empty_str)) put_it("%s", convert_output_format(get_format(FORMAT_LEAVE_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, FromUserHost, channel, ArgList[1] ? ArgList[1] : empty_str)); if (!my_stricmp(from, get_server_nickname(from_server))) { remove_channel(channel, from_server); remove_from_mode_list(channel, from_server); remove_from_join_list(channel, from_server); set_input_prompt(curr_scr_win, get_string_var(INPUT_PROMPT_VAR), 0); } else { remove_from_channel(channel, from, from_server, 0, NULL); } update_all_status(curr_scr_win, NULL, 0); update_input(UPDATE_ALL); message_from(NULL, LOG_CRAP); in_on_who = 0; }
static void read_channels(int create) { struct chanset_t *chan, *chan2; if (!chanfile[0]) return; for (chan = chanset; chan; chan = chan->next) if (!channel_static(chan)) chan->status |= CHAN_FLAGGED; chan_hack = 1; if (!readtclprog(chanfile) && create) { FILE *f; /* assume file isnt there & therfore make it */ putlog(LOG_MISC, "*", "Creating channel file"); f = fopen(chanfile, "w"); if (!f) putlog(LOG_MISC, "*", "Couldn't create channel file: %s. Dropping", chanfile); else fclose(f); } chan_hack = 0; chan = chanset; while (chan != NULL) { if (chan->status & CHAN_FLAGGED) { putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->name); if (!channel_inactive(chan)) dprintf(DP_SERVER, "PART %s\n", chan->name); chan2 = chan->next; remove_channel(chan); chan = chan2; } else chan = chan->next; } }
static void read_channels(int create, int reload) { struct chanset_t *chan, *chan_next; if (!chanfile[0]) return; if (reload) for (chan = chanset; chan; chan = chan->next) chan->status |= CHAN_FLAGGED; chan_hack = 1; if (!readtclprog(chanfile) && create) { FILE *f; /* Assume file isnt there & therfore make it */ putlog(LOG_MISC, "*", "Creating channel file"); f = fopen(chanfile, "w"); if (!f) putlog(LOG_MISC, "*", "Couldn't create channel file: %s. Dropping", chanfile); else fclose(f); } chan_hack = 0; if (!reload) return; for (chan = chanset; chan; chan = chan_next) { chan_next = chan->next; if (chan->status & CHAN_FLAGGED) { putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->dname); remove_channel(chan); } } }
static void got_cpart(char *botnick, char *code, char *par) { if (!par[0]) return; char *chname = newsplit(&par); struct chanset_t *chan = NULL; if (!(chan = findchan_by_dname(chname))) return; char *bots = newsplit(&par); int match = 0; /* if bots is '*' just remove_channel */ if (!strcmp(bots, "*")) match = 0; else match = parsebots(bots, conf.bot->nick); if (match) do_chanset(NULL, chan, "+inactive", DO_LOCAL); else remove_channel(chan); if (conf.bot->hub) write_userfile(-1); }
void part_command(int connfd,char* channel_name,int need_writeback){ char msg[MAX_MSG_LEN]; /* find user of self */ user *u = user_table[connfd]; channel *c = u->located_channel; if(!find_channel(channel_name)) snprintf(msg,MAX_MSG_LEN,"%s:No such channel\n",channel_name); else if(!c || !c->name || strcasecmp(channel_name,c->name)) snprintf(msg,MAX_MSG_LEN,"%s:You're not on that channel\n",channel_name); else{ snprintf(msg,MAX_MSG_LEN,":%s!%s@%s QUIT: See You!~\n",u->nick_name,u->user_name,u->host_name); /* if the channel has no one left, then remove it out*/ int size = remove_int_list(c->member,connfd); if(size == 0){ /* send message to daemon of REMOVECHAN */ send_command_to_daemon("REMOVECHAN",c->name); remove_channel(c); } /* if there is still someone at the channel, send a message to tell them 'u' has left */ else invoke_channel(connfd, msg, c); /* set located channel to null*/ u->located_channel = NULL; } if(need_writeback) send_msg_back(connfd,msg); }
void network_handler(ev, data){ char buf[UIP_BUFSIZE]; // packet data buffer unsigned short cmd; // DataPayload *dp; ChannelState *state = NULL; uint16_t len = uip_datalen(); PRINTF("ipaddr=%d.%d.%d.%d\n", uip_ipaddr_to_quad(&(UDP_HDR->srcipaddr))); PRINTF("Packet is %d bytes long\n",len); memcpy(buf, uip_appdata, len); buf[len] = '\0'; dp = (DataPayload *)buf; PRINTF("Data is %d bytes long\n",uip_ntohs(dp->dhdr.tlen)); cmd = dp->hdr.cmd; // only a byte so no reordering :) PRINTF("Received a %s command.\n", cmdnames[cmd]); PRINTF("Message for channel %d\n",dp->hdr.dst_chan_num); if (dp->hdr.dst_chan_num == HOMECHANNEL || cmd == DISCONNECT){ if (cmd == QACK){ state = &home_channel_state; copy_link_address(state); } else if (cmd == DISCONNECT){ state = get_channel_state(dp->hdr.dst_chan_num); if (state){ remove_channel(state->chan_num); } state = &home_channel_state; copy_link_address(state); } } else{ state = get_channel_state(dp->hdr.dst_chan_num); if (state == NULL){ PRINTF("Channel %d doesn't exist\n", dp->hdr.dst_chan_num); return; } if (check_seqno(state, dp) == 0) { printf("OH NOES\n"); return; }else { //CHECK IF RIGHT CONNECTION //copy_link_address(state); } } // Received a message so reset pingOUT state->pingOUT = 0; if (cmd == QUERY) PRINTF("I'm a controller, Ignoring QUERY\n"); else if (cmd == CONNECT) PRINTF("I'm a controller, Ignoring CONNECT\n"); else if (cmd == QACK) qack_handler(state, dp); else if (cmd == CACK) cack_handler(state, dp); else if (cmd == RESPONSE) response_handler(state, dp); else if (cmd == CMDACK) command_ack_handler(state,dp); else if (cmd == PING) ping_handler(state, dp); else if (cmd == PACK) pack_handler(state, dp); else if (cmd == DISCONNECT) close_handler(state,dp); }
/** * Forces closure of a channel */ static int disconnect_channel(guint64 handle, int passive) { channel_object *c; while ((c = get_channel_by_handle(handle))) { DEBUG("removing channel"); remove_channel(c->path, passive); } return 1; }
static void got_sp(int idx, char *code, char *par) { struct chanset_t *chan = findchan_by_dname(newsplit(&par)); if (chan) { if (conf.bot->hub) { remove_channel(chan); write_userfile(-1); } else chan->channel.parttime = ((atoi(par) + now) - server_lag); } }
void ping_callback(void * s){ ChannelState *state = (ChannelState *)s; if (state->pingOUT < 3){ ping(state); ctimer_restart(&(state->timer)); state->pingOUT++; } else { close_graceful(state); remove_channel(state->chan_num); state->pingOUT =0; } }
static void not_valid_channel(u_char *from, u_char **ArgList) { u_char *channel; u_char *s; if (!(channel = ArgList[0]) || !ArgList[1]) return; PasteArgs(ArgList, 1); s = server_get_name(parsing_server()); if (0 == my_strnicmp(s, from, my_strlen(s))) { remove_channel(channel, parsing_server()); put_it("%s %s %s", numeric_banner(), channel, ArgList[1]); } }
static void mns_chan(int idx, char *par, char *bot) { char *chname = NULL, buf2[1024] = ""; struct chanset_t *chan = NULL; int i; if (!bot) putlog(LOG_CMDS, "*", "#%s# -chan %s", dcc[idx].nick, par); if (!par[0]) { dprintf(idx, "Usage: -chan [%s]<channel>\n", CHANMETA); return; } chname = newsplit(&par); simple_snprintf(buf2, sizeof(buf2), "cpart %s %s", chname, bot ? bot : "*"); if (bot) /* bot will just set it +inactive */ putbot(bot, buf2); else putallbots(buf2); chan = findchan_by_dname(chname); if (!chan) { if ((chan = findchan(chname))) dprintf(idx, "That channel exists with a short name of %s, use that.\n", chan->dname); else dprintf(idx, "That channel doesn't exist!\n"); return; } if (!bot) { for (i = 0; i < dcc_total; i++) { if (dcc[i].type && (dcc[i].type->flags & DCT_CHAT) && !rfc_casecmp(dcc[i].u.chat->con_chan, chan->dname)) { dprintf(i, "%s is no longer a valid channel, changing your console to '*'\n", chname); strlcpy(dcc[i].u.chat->con_chan, "*", 2); console_dostore(i, 0); } } remove_channel(chan); if (conf.bot->hub) write_userfile(idx); dprintf(idx, "Channel %s removed from the botnet.\n", chname); dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n"); } else dprintf(idx, "Channel %s removed from the bot: %s\n", chname, bot); }
static void channels_rehash() { struct chanset_t *chan; setstatic = 0; read_channels(1); /* Remove any extra channels, by checking the flag. */ chan = chanset; for (chan = chanset; chan;) { if (chan->status & CHAN_FLAGGED) { putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->dname); remove_channel(chan); chan = chanset; } else chan = chan->next; } }
static void channels_rehash() { struct chanset_t *chan; setstatic = 0; read_channels(1); /* remove any extra channels */ chan = chanset; while (chan) { if (chan->status & CHAN_FLAGGED) { putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->name); if (!channel_inactive(chan)) dprintf(DP_SERVER, "PART %s\n", chan->name); remove_channel(chan); chan = chanset; } else chan = chan->next; } }
void check_timer(ChannelState *s){ if (s == NULL) return; if (s->state % 2 != 0){ if (s->ticks == 0){ if (s == &home_channel_state || s->pingOUT < 3){ PRINTF("Retrying\n"); resend(s); s->pingOUT++; s->ticks = s->pingOUT * 10; } else { printf("PING OUT = %d\n", s->pingOUT); printf("CLOSING CHANNEL DUE TO TIMEOUT\n"); close_graceful(s); remove_channel(s->chan_num); } } } s->ticks --; }
static void cannot_join_channel(u_char *from, u_char **ArgList) { u_char *chan; u_char buffer[BIG_BUFFER_SIZE]; if (ArgList[0]) chan = ArgList[0]; else return; if (!is_on_channel(chan, parsing_server(), server_get_nickname(parsing_server()))) remove_channel(chan, parsing_server()); else return; PasteArgs(ArgList, 0); if (do_hook(current_numeric(), "%s %s", from, *ArgList)) { my_strmcpy(buffer, ArgList[0], sizeof buffer); switch(-current_numeric()) { case 471: /* #define ERR_CHANNELISFULL 471 */ my_strmcat(buffer, " (Channel is full)", sizeof buffer); break; case 473: /* #define ERR_INVITEONLYCHAN 473 */ my_strmcat(buffer, " (Invite only channel)", sizeof buffer); break; case 474: /* #define ERR_BANNEDFROMCHAN 474 */ my_strmcat(buffer, " (Banned from channel)", sizeof buffer); break; case 475: /* #define ERR_BADCHANNELKEY 475 */ my_strmcat(buffer, " (Bad channel key)", sizeof buffer); break; case 476: /* #define ERR_BADCHANMASK 476 */ my_strmcat(buffer, " (Bad channel mask)", sizeof buffer); break; } put_it("%s %s", numeric_banner(), buffer); } }
void parse_msg(char tokens[MAX_MSG_TOKENS][MAX_MSG_LEN+1], int length, char *sendbuf, int fd) { // app_error("Not Implemented"); // int i = ERR_UNKNOWNCOMMAND; if(!strcmp(tokens[0],"ADDUSER")) { add_user(fd, tokens[1], sendbuf); } else if(!strcmp(tokens[0],"ADDCHAN")) { add_channel(fd, tokens[1], sendbuf); } else if(!strcmp(tokens[0],"REMOVEUSER")) { remove_user(fd, tokens[1], sendbuf); } else if(!strcmp(tokens[0],"REMOVECHAN")) { remove_channel(fd, tokens[1], sendbuf); } else if(!strcmp(tokens[0],"NEXTHOP")) { next_hop(fd, tokens[1], sendbuf); } else if(!strcmp(tokens[0],"NEXTHOPS")) { next_hops(fd, atol(tokens[1]), tokens[2], sendbuf); } else if(!strcmp(tokens[0],"USERTABLE")) { user_table(fd, sendbuf); } else if(!strcmp(tokens[0],"CHANTABLE")) { channel_table(fd, sendbuf); } else { } return; }
static int check_slowjoinpart(struct chanset_t *chan) { /* slowpart */ if (chan->channel.parttime && (chan->channel.parttime < now)) { chan->channel.parttime = 0; dprintf(DP_MODE, "PART %s\n", chan->name); if (chan) /* this should NOT be necesary, but some unforseen bug requires it.. */ remove_channel(chan); return 1; /* if we keep looping, we'll segfault. */ /* slowjoin */ } else if ((chan->channel.jointime) && (chan->channel.jointime < now)) { chan->status &= ~CHAN_INACTIVE; chan->channel.jointime = 0; if (shouldjoin(chan)) join_chan(chan); } else if (channel_closed(chan)) { enforce_closed(chan); } return 0; }
uint8_t LoRaPHY::request_new_channel(int8_t channel_id, channel_params_t *new_channel) { if (!phy_params.custom_channelplans_supported) { return 0; } uint8_t status = 0x03; if (new_channel->frequency == 0) { // Remove if (remove_channel(channel_id) == false) { status &= 0xFC; } } else { new_channel->band = lookup_band_for_frequency(new_channel->frequency); switch (add_channel(new_channel, channel_id)) { case LORAWAN_STATUS_OK: { break; } case LORAWAN_STATUS_FREQUENCY_INVALID: { status &= 0xFE; break; } case LORAWAN_STATUS_DATARATE_INVALID: { status &= 0xFD; break; } case LORAWAN_STATUS_FREQ_AND_DR_INVALID: { status &= 0xFC; break; } default: { status &= 0xFC; break; } } } return status; }
static int tcl_channel(ClientData cd, Tcl_Interp *irp, int argc, char *argv[]) { struct chanset_t *chan; BADARGS(2, 999, " command ?options?"); if (!strcmp(argv[1], "add")) { BADARGS(3, 4, " add channel-name ?options-list?"); if (argc == 3) return tcl_channel_add(irp, argv[2], ""); return tcl_channel_add(irp, argv[2], argv[3]); } if (!strcmp(argv[1], "set")) { BADARGS(3, 999, " set channel-name ?options?"); chan = findchan_by_dname(argv[2]); if (chan == NULL) { if (chan_hack == 1) return TCL_OK; /* Ignore channel settings for a static * channel which has been removed from * the config */ Tcl_AppendResult(irp, "no such channel record", NULL); return TCL_ERROR; } return tcl_channel_modify(irp, chan, argc - 3, &argv[3]); } if (!strcmp(argv[1], "remove")) { BADARGS(3, 3, " remove channel-name"); chan = findchan_by_dname(argv[2]); if (chan == NULL) { Tcl_AppendResult(irp, "no such channel record", NULL); return TCL_ERROR; } remove_channel(chan); return TCL_OK; } Tcl_AppendResult(irp, "unknown channel command: should be one of: ", "add, set, info, remove", NULL); return TCL_ERROR; }
void checkchans(int which) { struct chanset_t *chan = NULL, *chan_next = NULL; if (which == 0 || which == 2) { for (chan = chanset; chan; chan = chan->next) { if (which == 0) { chan->status |= CHAN_FLAGGED; } else if (which == 2) { chan->status &= ~CHAN_FLAGGED; } } } else if (which == 1) { for (chan = chanset; chan; chan = chan_next) { chan_next = chan->next; if (chan->status & CHAN_FLAGGED) { putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->dname); remove_channel(chan); } } } }
/* * numbered_command: does (hopefully) the right thing with the numbered * responses from the server. I wasn't real careful to be sure I got them * all, but the default case should handle any I missed (sorry) * * The format of a numeric looks like so: * * :server-name XXX our-nick Arg1 Arg2 Arg3 ... :ArgN * * The last argument traditionally has a colon before it, but this is not * compulsary. The BreakArgs function has already broken this up into * words for us, so that what we get, looks like this: * * server-name -> from parameter * XXX -> comm parameter * our-nick -> ArgList[0] * Arg1 -> ArgList[1] * Arg2 -> ArgList[2] * ... ... * * BUT! There's a wrinkle in the ointment. The first thing we do is slurp * up ArgList[0] (our-nick) and put it in 'user'. Then we increment the * ArgList array, so what we actually end up with is: * * server-name -> from parameter * XXX -> comm parameter * our-nick -> user * Arg1 -> ArgList[0] * Arg2 -> ArgList[1] * ... ... * ArgN -> ArgList[N-1] * NULL -> ArgList[N] */ void numbered_command (const char *from, const char *comm, char const **ArgList) { const char *target; char *copy; int i; int lastlog_level; int old_current_numeric = current_numeric; int numeric; /* All numerics must have a target (our nickname) */ if (!comm || !*comm) { rfc1459_odd(from, comm, ArgList); return; } numeric = atol(comm); if (numeric < 0 || numeric > 999) { rfc1459_odd(from, comm, ArgList); return; } if (!(target = ArgList[0])) { rfc1459_odd(from, comm, ArgList); return; } ArgList++; lastlog_level = set_lastlog_msg_level(LOG_CRAP); if (ArgList[0] && is_channel(ArgList[0])) message_from(ArgList[0], LOG_CRAP); else message_from(NULL, LOG_CRAP); current_numeric = -numeric; /* must be negative of numeric! */ /* * This first switch statement is only used for those numerics * which either need to perform some action before the numeric * is offered to the user, or by those actions which need to offer * the numeric to the user in some special manner. * * Those numerics which require only special display if the user * does not hook them, are handled below. * * Those numerics which require special action after the numeric * is offered to the user, are also handled below. * * Each of these numerics must either "break" (go to step 2) * or must "goto END" (goto step 3). */ switch (numeric) { /* * I added the "set_server_nickname" here because the client * when auto-fudging your nick will sometimes be confused as * what your nickname really is when you connect. Since the * server always tells us who the message was set to (ie, us) * we just kind of take it at its word. */ case 001: /* #define RPL_WELCOME 001 */ { Timeval i; i.tv_sec = 0; i.tv_usec = 50000; select(0, NULL, NULL, NULL, &i); accept_server_nickname(from_server, target); server_is_registered(from_server, 1); userhostbase(from_server, NULL, got_my_userhost, 1); break; } /* * Now instead of the terribly horrible hack using numeric 002 * to get the server name/server version info, we use the 004 * numeric which is what is the most logical choice for it. * * If any of the arguments are missing, we don't abort, because * the client needs 004 to sync. Instead, we just pass in the * NULL values and hope for the best... */ case 004: /* #define RPL_MYINFO 004 */ { const char *server = NULL, *version = NULL, *umodes = NULL; /* The 004 numeric is too import to "odd server stuff" over. */ /* So if the reply is useless, we'll just wing it */ if (!(server = ArgList[0])) server = version = umodes = NULL; else if (!(version = ArgList[1])) server = version = umodes = NULL; else if (!(umodes = ArgList[2])) server = version = umodes = NULL; else { /* Work around ratbox-1.2-3. */ if (!my_stricmp(umodes, "(brown")) if (ArgList[3] && !my_stricmp(ArgList[3], "paper")) if (ArgList[4] && !my_stricmp(ArgList[4], "bag")) if (ArgList[5] && !my_stricmp(ArgList[5], "release)")) { if (!(umodes = ArgList[6])) { rfc1459_odd(from, comm, ArgList); goto END; } } } got_initial_version_28(server, version, umodes); break; } case 005: { int arg; char *set, *value; for (arg = 0; ArgList[arg] && !strchr(ArgList[arg], ' '); arg++) { set = LOCAL_COPY(ArgList[arg]); value = strchr(set, '='); if (value && *value) *value++ = 0; if (*set == '+') /* parameter append */ { const char *ov = get_server_005(from_server, ++set); value = malloc_strdup2(ov, value); set_server_005(from_server, set, value); new_free(&value); } else if (*set == '-') /* parameter removal */ set_server_005(from_server, ++set, NULL); else if (value && *value) set_server_005(from_server, set, value); else set_server_005(from_server, set, space); } break; } case 10: /* EFNext "Use another server" 010 */ { const char *new_server, *new_port_s, *message; int new_port, old_server; PasteArgs(ArgList, 2); if (!(new_server = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(new_port_s = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } new_port = atol(ArgList[1]); /* Must do these things before calling "display_msg" */ old_server = from_server; add_to_server_list(new_server, new_port, NULL, NULL, get_server_group(from_server), NULL, 0); server_reconnects_to(old_server, from_server); from_server = old_server; break; } case 14: /* Erf/TS4 "cookie" numeric 014 */ { const char * cookie; PasteArgs(ArgList, 0); if (!(cookie = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } use_server_cookie(from_server); set_server_cookie(from_server, cookie); goto END; } case 42: /* ircnet's "unique id" numeric 042 */ { const char * unique_id; const char * message; PasteArgs(ArgList, 1); if (!(unique_id = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } else if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } set_server_unique_id(from_server, unique_id); if (do_hook(current_numeric, "%s %s %s", from, unique_id, message)) goto DISPLAY; goto END; } case 301: /* #define RPL_AWAY 301 */ { const char *nick, *message; PasteArgs(ArgList, 1); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } /* Ach. /on 301 doesn't offer 'from' as $0. Bummer. */ if (do_hook(current_numeric, "%s %s", nick, message)) goto DISPLAY; goto END; } case 340: /* #define RPL_USERIP 307 */ if (!get_server_005(from_server, "USERIP")) break; /* FALLTHROUGH */ case 302: /* #define RPL_USERHOST 302 */ userhost_returned(from_server, from, comm, ArgList); goto END; case 303: /* #define RPL_ISON 303 */ ison_returned(from_server, from, comm, ArgList); goto END; case 315: /* #define RPL_ENDOFWHO 315 */ who_end(from_server, from, comm, ArgList); goto END; case 321: /* #define RPL_LISTSTART 321 */ { const char *channel, *user_cnt, *line; channel = ArgList[0] = "Channel"; user_cnt = ArgList[1] = "Users"; line = ArgList[2] = "Topic"; ArgList[3] = NULL; /* Then see if they want to hook /ON LIST */ if (!do_hook(LIST_LIST, "%s %s %s", channel, user_cnt, line)) goto END; /* * Otherwise, this line is ok. */ break; } case 322: /* #define RPL_LIST 322 */ { const char *channel, *user_cnt, *line; int cnt; int funny_flags, funny_min, funny_max; const char *funny_match; PasteArgs(ArgList, 2); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(user_cnt = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(line = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } funny_flags = get_server_funny_flags(from_server); funny_min = get_server_funny_min(from_server); funny_max = get_server_funny_max(from_server); funny_match = get_server_funny_match(from_server); /* * Do not display if the channel has no topic and the user asked * for only channels with topics. */ if (funny_flags & FUNNY_TOPIC && !(line && *line)) goto END; /* * Do not display if the channel does not have the necessary * number of users the user asked for */ cnt = my_atol(user_cnt); if (funny_min && (cnt < funny_min)) goto END; if (funny_max && (cnt > funny_max)) goto END; /* * Do not display if the channel is not private or public as the * user requested. */ if ((funny_flags & FUNNY_PRIVATE) && (*channel != '*')) goto END; if ((funny_flags & FUNNY_PUBLIC) && (*channel == '*')) goto END; /* * Do not display if the channel does not match the user's * supplied wildcard pattern */ if (funny_match && wild_match(funny_match, channel) == 0) goto END; /* Then see if they want to hook /ON LIST */ if (!do_hook(LIST_LIST, "%s %s %s", channel, user_cnt, line)) goto END; /* * Otherwise, this line is ok. */ break; } case 324: /* #define RPL_CHANNELMODEIS 324 */ { const char *mode, *channel; PasteArgs(ArgList, 1); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(mode = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } /* If we're waiting for MODE reply. */ if (channel_is_syncing(channel, from_server)) { int numonchannel, maxnum; copy = LOCAL_COPY(channel); update_channel_mode(channel, mode); update_all_status(); maxnum = get_server_max_cached_chan_size(from_server); if (maxnum >= 0) { numonchannel = number_on_channel(copy, from_server); if (numonchannel <= maxnum) whobase(from_server, copy, add_user_who, add_user_end); else channel_not_waiting(copy, from_server); } else whobase(from_server, copy, add_user_who, add_user_end); #if 0 goto END; #endif } break; } case 352: /* #define RPL_WHOREPLY 352 */ whoreply(from_server, NULL, comm, ArgList); goto END; case 353: /* #define RPL_NAMREPLY 353 */ { const char *type, *channel, *line; PasteArgs(ArgList, 2); if (!(type = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(channel = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(line = ArgList[2])) { line = empty_string; } if (channel_is_syncing(channel, from_server)) { char *line_copy = LOCAL_COPY(line); char *nick; while ((nick = next_arg(line_copy, &line_copy)) != NULL) { /* XXX - Hack to work around space at end of 353 */ forcibly_remove_trailing_spaces(nick, NULL); /* * 1999 Oct 29 -- This is a hack to compensate for * a bug in older ircd implementations that can result * in a truncated nickname at the end of a names reply. * The last nickname in a names list is then always * treated with suspicion until the WHO reply is * completed and we know that its not truncated. --esl */ if (!line || !*line) add_to_channel(channel, nick, from_server, 1, 0, 0, 0); else add_to_channel(channel, nick, from_server, 0, 0, 0, 0); } message_from(channel, LOG_CRAP); break; } else { int cnt; const char *ptr; int funny_flags, funny_min, funny_max; const char *funny_match; funny_flags = get_server_funny_flags(from_server); funny_min = get_server_funny_min(from_server); funny_max = get_server_funny_max(from_server); funny_match = get_server_funny_match(from_server); ptr = line; for (cnt = -1; ptr; cnt++) { if ((ptr = strchr(ptr, ' ')) != NULL) ptr++; } if (funny_min && (cnt < funny_min)) goto END; else if (funny_max && (cnt > funny_max)) goto END; if ((funny_flags & FUNNY_PRIVATE) && (*type == '=')) goto END; if ((funny_flags & FUNNY_PUBLIC) && ((*type == '*') || (*type == '@'))) goto END; if (funny_match && wild_match(funny_match, channel) == 0) goto END; } /* Everything is OK. */ break; } case 354: /* #define RPL_XWHOREPLY 354 */ xwhoreply(from_server, NULL, comm, ArgList); goto END; /* XXX Yea yea, these are out of order. so shoot me. */ case 346: /* #define RPL_INVITELIST (+I for erf) */ case 348: /* #define RPL_EXCEPTLIST (+e for erf) */ case 367: /* #define RPL_BANLIST */ number_of_bans++; break; case 347: /* #define END_OF_INVITELIST */ case 349: /* #define END_OF_EXCEPTLIST */ case 368: /* #define END_OF_BANLIST */ { const char *channel; if (!get_int_var(SHOW_END_OF_MSGS_VAR)) goto END; if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } #ifdef IRCII_LIKE_BAN_SUMMARY if (do_hook(current_numeric, "%s %s %d", from, channel, number_of_bans)) #else if (do_hook(current_numeric, "%s %d %s", from, number_of_bans, channel)) #endif { put_it("%s Total number of %s on %s - %d", banner(), numeric == 347 ? "invites" : (numeric == 349 ? "exceptions" : (numeric == 368 ? "bans" : "wounds")), channel, number_of_bans); } goto END; } /* XXX Shouldn't this set "You're operator" flag for hybrid? */ case 381: /* #define RPL_YOUREOPER 381 */ if (!is_server_registered(from_server)) { rfc1459_odd(from, comm, ArgList); goto END; } break; /* ":%s 401 %s %s :No such nick/channel" */ case 401: /* #define ERR_NOSUCHNICK 401 */ { const char *nick; if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!is_channel(nick)) { notify_mark(from_server, nick, 0, 0); if (get_int_var(AUTO_WHOWAS_VAR)) { int foo = get_int_var(NUM_OF_WHOWAS_VAR); if (foo > -1) send_to_server("WHOWAS %s %d", nick, foo); else send_to_server("WHOWAS %s", nick); } } break; } /* Bizarre dalnet extended who replies. */ /* ":%s 402 %s %s :No such server" */ case 402: { const char *server; if (!(server = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } fake_who_end(from_server, from, comm, server); break; } /* Yet more bizarre dalnet extended who replies. */ /* ":%s 522 %s :/WHO Syntax incorrect, use /who ? for help" */ /* ":%s 523 %s :Error, /who limit of %d exceed." */ case 522: case 523: { /* * This dalnet error message doesn't even give us the * courtesy of telling us which who request was in error, * so we have to guess. Whee. */ fake_who_end(from_server, from, comm, NULL); break; } case 403: /* #define ERR_NOSUCHCHANNEL 403 */ { const char * s; const char * channel; const char * message; PasteArgs(ArgList, 1); /* Some servers BBC and send back an empty reply. */ if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } /* Do not accept 403's from remote servers. */ s = get_server_itsname(from_server); if (my_strnicmp(s, from, strlen(s))) { rfc1459_odd(from, comm, ArgList); goto END; } /* * Some servers BBC and send this instead of a * 315 numeric when a who request has been completed. */ if (fake_who_end(from_server, from, comm, channel)) ; /* * If you try to JOIN or PART the "*" named channel, as may * happen if epic gets confused, the server may tell us that * channel does not exist. But it would be death to try to * destroy that channel as epic will surely do the wrong thing! * Otherwise, we somehow tried to reference a channel that * this server claims does not exist; we blow the channel away * for good measure. */ else if (strcmp(channel, "*")) remove_channel(channel, from_server); break; } case 421: /* #define ERR_UNKNOWNCOMMAND 421 */ { const char *token; if (!(token = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (check_server_redirect(from_server, token)) goto END; if (check_server_wait(from_server, token)) goto END; break; } case 432: /* #define ERR_ERRONEUSNICKNAME 432 */ { const char *nick; if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!my_stricmp(target, nick)) yell("WARNING: Strange invalid nick message received." " You are probably lagged."); else if (get_int_var(AUTO_NEW_NICK_VAR)) fudge_nickname(from_server); else reset_nickname(from_server); break; } case 437: /* av2.9's "Nick collision" numeric 437 */ /* Also, undernet/dalnet "You are banned" */ /* Also, av2.10's "Can't do that" numeric */ /* Also, cs's "too many nick changes" num */ { /* * Ugh. What a total trainwreck this is. Sometimes, I * really hate all the ircd's out there in the world that * have to be supported. * * Well, there are at least four different, occasionally * scrutable ways we can get this numeric. * * 1a) On ircnet -- As an unregistered user, the NICK that * we are trying to register was used in the past 90 * seconds or so. The server expects us to send * another NICK request. * ARGV[0] IS NICK, REGISTERED IS NO * 1b) On ircnet -- As a registered user, the NICK that * we are trying to register was used in the past 90 * seconds or so. The server expects us not to do * anything (like a 432 numeric). * ARGV[0] IS NICK, REGISTERED IS YES * 2) On ircnet -- As a registered user, we are trying to * join a channel that was netsplit in the past 24 hours * or so. The server expects us not to do anything. * ARGV[0] IS CHANNEL, REGISTERED IS YES * 3) On undernet/dalnet -- As a registered user, who is * on a channel where we are banned, a NICK request * was rejected (because we are banned). The server * expects us not to do anything. * ARGV[0] IS CHANNEL, REGISTERED IS YES * 4) On a comstud efnet servers -- As a registered user, * we have changed our nicknames too many times in * too short a time. The server expects us not to do * anything. * ARGV[0] IS ERROR, ARGV[1] IS NULL. * I understand this numeric will be moving to 439. */ /* * Weed out the comstud one first, since it's the most bizarre. */ if (ArgList[0] && ArgList[1] == NULL) { accept_server_nickname(from_server, target); break; } /* * Now if it's a channel, it might be ircnet telling us we * can't join the channel, or undernet telling us that we * can't change our nickname because we're banned. The * easiest way to tell is to see if we are on the channel. */ if (is_channel(ArgList[0])) { /* XXX Is this really neccesary? */ if (!im_on_channel(ArgList[0], from_server)) remove_channel(ArgList[0], from_server); break; } /* * Otherwise, a nick command failed. Oh boy. * If we are registered, abort the nick change and * hope for the best. */ if (is_server_registered(from_server)) { accept_server_nickname(from_server, target); break; } /* * Otherwise, it's an ircnet "nick not available" error. * Let the nickname reset numerics handle this mess. */ /* FALLTHROUGH */ } case 433: /* #define ERR_NICKNAMEINUSE 433 */ case 438: /* EFnet/TS4 "nick collision" numeric 438 */ case 453: /* EFnet/TS4 "nickname lost" numeric 453 */ { const char *nick; if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!my_stricmp(target, nick)) /* * This should stop the "rolling nicks" in their tracks. */ yell("WARNING: Strange invalid nick message received." " You are probably lagged."); else if (get_int_var(AUTO_NEW_NICK_VAR)) fudge_nickname(from_server); else reset_nickname(from_server); if (!from) from = "-1"; break; } case 439: /* Comstud's "Can't change nickname" */ { accept_server_nickname(from_server, target); break; } case 442: /* #define ERR_NOTONCHANNEL 442 */ { const char * s; const char * channel; const char * message; PasteArgs(ArgList, 1); /* Some servers BBC and send back an empty reply. */ if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } /* Do not accept this numeric from remote servers */ s = get_server_itsname(from_server); if (my_strnicmp(s, from, strlen(s))) { rfc1459_odd(from, comm, ArgList); goto END; } /* Do not ever delete the "*" channel */ if (strcmp(ArgList[0], "*")) remove_channel(ArgList[0], from_server); break; } case 451: /* #define ERR_NOTREGISTERED 451 */ /* * Sometimes the server doesn't catch the USER line, so * here we send a simplified version again -lynx */ register_server(from_server, NULL); break; case 462: /* #define ERR_ALREADYREGISTRED 462 */ change_server_nickname(from_server, NULL); break; case 465: /* #define ERR_YOUREBANNEDCREEP 465 */ { /* * There used to be a say() here, but if we arent * connected to a server, then doing say() is not * a good idea. So now it just doesnt do anything. */ server_reconnects_to(from_server, NOSERV); break; } case 477: /* #define ERR_NEEDREGGEDNICK 477 */ /* IRCnet has a different 477 numeric. */ if (ArgList[0] && *ArgList[0] == '+') break; /* FALLTHROUGH */ case 471: /* #define ERR_CHANNELISFULL 471 */ case 473: /* #define ERR_INVITEONLYCHAN 473 */ case 474: /* #define ERR_BANNEDFROMCHAN 474 */ case 475: /* #define ERR_BADCHANNELKEY 475 */ case 476: /* #define ERR_BADCHANMASK 476 */ { const char *channel; if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } cant_join_channel(ArgList[0], from_server); break; } } /* DEFAULT OFFER */ /* * This is the "default hook" case, where we offer to the user all of * the numerics that were not offered above. We simply catenate * all of the arguments into a string and offer to the user. * If the user bites, then we skip the "default display" section. */ copy = alloca(IRCD_BUFFER_SIZE + 1); *copy = 0; for (i = 0; ArgList[i]; i++) { if (i) strlcat(copy, " ", IRCD_BUFFER_SIZE); strlcat(copy, ArgList[i], IRCD_BUFFER_SIZE); } if (!do_hook(current_numeric, "%s %s", from, copy)) goto END; DISPLAY: /* DEFAULT DISPLAY */ /* * This is the "default display" case, where if the user does not * hook the numeric, we output the message in some special way. * If a numeric does not require special outputting, then we will * just display it with ``display_msg'' */ switch (numeric) { case 221: /* #define RPL_UMODEIS 221 */ { const char *umode; PasteArgs(ArgList, 0); if (!(umode = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s Your user mode is \"%s\"", banner(), umode); break; } case 271: /* #define SILENCE_LIST 271 */ { const char *perp, *victim; PasteArgs(ArgList, 1); if (!(perp = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(victim = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s is ignoring %s", banner(), perp, victim); break; } case 301: /* #define RPL_AWAY 301 */ { const char *nick, *message; PasteArgs(ArgList, 1); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s is away: %s", banner(), nick, message); break; } case 311: /* #define RPL_WHOISUSER 311 */ { const char *nick, *user, *host, *channel, *name; PasteArgs(ArgList, 4); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(user = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(host = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(channel = ArgList[3])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(name = ArgList[4])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s is %s@%s (%s)", banner(), nick, user, host, name); break; } case 312: /* #define RPL_WHOISSERVER 312 */ { const char *nick, *server, *pithy; PasteArgs(ArgList, 2); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(server = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(pithy = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s on irc via server %s (%s)", banner(), server, pithy); break; } case 313: /* #define RPL_WHOISOPERATOR 313 */ { const char *nick, *message; PasteArgs(ArgList, 1); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s %s", banner(), ArgList[0], ArgList[1]); break; } case 314: /* #define RPL_WHOWASUSER 314 */ { const char *nick, *user, *host, *unused, *name; PasteArgs(ArgList, 4); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(user = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(host = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(unused = ArgList[3])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(name = ArgList[4])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s was %s@%s (%s)",banner(), nick, user, host, name); break; } case 317: /* #define RPL_WHOISIDLE 317 */ { const char *nick, *idle_str, *startup_str; int idle; const char * unit; char startup_ctime[128]; if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(idle_str = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(startup_str = ArgList[2])) { /* No problem */; } *startup_ctime = 0; if (startup_str) /* Undernet/TS4 */ { time_t startup; if ((startup = atol(startup_str)) != 0) snprintf(startup_ctime, 128, ", signed on at %s", my_ctime(startup)); } if ((idle = atoi(idle_str)) > 59) { idle /= 60; unit = "minute"; } else unit = "second"; put_it ("%s %s has been idle %d %ss%s", banner(), nick, idle, unit, startup_ctime); break; } case 318: /* #define RPL_ENDOFWHOIS 318 */ { PasteArgs(ArgList, 0); if (get_int_var(SHOW_END_OF_MSGS_VAR)) display_msg(from, comm, ArgList); break; } case 319: /* #define RPL_WHOISCHANNELS 319 */ { const char *nick, *channels; PasteArgs(ArgList, 1); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(channels = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s on channels: %s", banner(), channels); break; } case 321: /* #define RPL_LISTSTART 321 */ /* Our screwy 321 handling demands this. BAH! */ put_it("%s Channel Users Topic", banner()); break; case 322: /* #define RPL_LIST 322 */ { static char format[25]; static int last_width = -1; const char *channel, *user_cnt, *line; PasteArgs(ArgList, 2); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(user_cnt = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(line = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } /* Figure out how to display this to the user. */ if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR)) { if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR))) snprintf(format, 25, "%%-%u.%us %%-5s %%s", (unsigned) last_width, (unsigned) last_width); else strlcpy(format, "%s\t%-5s %s", sizeof format); } if (*channel == '*') say(format, "Prv", user_cnt, line); else say(format, check_channel_type(channel), user_cnt, line); break; } case 324: /* #define RPL_CHANNELMODEIS 324 */ { const char *mode, *channel; PasteArgs(ArgList, 1); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(mode = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s Mode for channel %s is \"%s\"", banner(), channel, mode); break; } case 329: /* #define CREATION_TIME 329 */ { const char *channel, *time1_str, *time2_str, *time3_str; time_t time1, time2, time3; PasteArgs(ArgList, 2); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(time1_str = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(time2_str = ArgList[2])) { /* No problem */; } if (!(time3_str = ArgList[3])) { /* No problem */; } /* Erf/TS4 support */ if (time2_str && time3_str) { time1 = (time_t)my_atol(time1_str); time2 = (time_t)my_atol(time2_str); time3 = (time_t)my_atol(time3_str); put_it("%s Channel %s was created at %ld, " "+c was last set at %ld, " "and has been opless since %ld", banner(), channel, time1, time2, time3); } else { time1 = (time_t)my_atol(time1_str); put_it("%s Channel %s was created at %s", banner(), channel, my_ctime(time1)); } break; } case 330: /* #define RPL_WHOISLOGGEDIN 330 */ { const char *nick, *login, *reason; PasteArgs(ArgList, 2); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(login = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(reason = ArgList[2])) { reason = "is logged in as"; } put_it("%s %s %s %s", banner(), nick, reason, login); break; } case 332: /* #define RPL_TOPIC 332 */ { const char *channel, *topic; PasteArgs(ArgList, 1); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(topic = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s Topic for %s: %s", banner(), channel, topic); break; } case 333: /* #define RPL_TOPICWHOTIME 333 */ { const char *channel, *nick, *when_str; time_t howlong; if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(nick = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(when_str = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } howlong = time(NULL) - my_atol(when_str); put_it("%s The topic was set by %s %ld sec ago",banner(), nick, howlong); break; } case 341: /* #define RPL_INVITING 341 */ { const char *nick, *channel; if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(channel = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } message_from(channel, LOG_CRAP); put_it("%s Inviting %s to channel %s", banner(), nick, channel); break; } case 351: /* #define RPL_VERSION 351 */ { const char *version, *itsname, *stuff; PasteArgs(ArgList, 2); if (!(version = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(itsname = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(stuff = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s Server %s: %s %s",banner(), itsname, version, stuff); break; } case 353: /* #define RPL_NAMREPLY 353 */ { static int last_width; char format[41]; const char *type, *channel, *line; PasteArgs(ArgList, 2); if (!(type = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(channel = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(line = ArgList[2])) { line = empty_string; } /* This is only for when the user joined the channel */ if (channel_is_syncing(channel, from_server)) { /* If the user bites on /ON NAMES, then skip the rest */ message_from(channel, LOG_CRAP); if (do_hook(NAMES_LIST, "%s %s", channel, line)) if (get_int_var(SHOW_CHANNEL_NAMES_VAR)) say("Users on %s: %s", check_channel_type(channel), line); break; } /* If the user grabs /ON NAMES then just stop right here */ if (!do_hook(NAMES_LIST, "%s %s", channel, line)) break; /* This all is for when the user has not just joined channel */ if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR)) { if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR))) snprintf(format, 40, "%%s: %%-%u.%us %%s", (unsigned char) last_width, (unsigned char) last_width); else strlcpy(format, "%s: %s\t%s", sizeof format); } else strlcpy(format, "%s: %s\t%s", sizeof format); message_from(channel, LOG_CRAP); if (*type == '=') { if (last_width && ((int)strlen(channel) > last_width)) { char *channel_copy = LOCAL_COPY(channel); channel_copy[last_width-1] = '>'; channel_copy[last_width] = 0; channel = channel_copy; } put_it(format, "Pub", check_channel_type(channel), line); } else if (*type == '*') put_it(format, "Prv", check_channel_type(channel), line); else if (*type == '@') put_it(format, "Sec", check_channel_type(channel), line); break; } case 364: /* #define RPL_LINKS 364 */ { const char *itsname, *uplink, *stuff; PasteArgs(ArgList, 2); if (!(itsname = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(uplink = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(stuff = ArgList[2])) { stuff = empty_string; } if (stuff) put_it("%s %-20s %-20s %s", banner(), itsname, uplink, stuff); else put_it("%s %-20s %s", banner(), itsname, uplink); break; } case 366: /* #define RPL_ENDOFNAMES 366 */ { const char *channel; if (!get_int_var(SHOW_END_OF_MSGS_VAR)) break; if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!channel_is_syncing(channel, from_server)) display_msg(from, comm, ArgList); break; } case 346: /* +I on erf */ case 348: /* +e on erf */ case 367: /* +b */ { const char *channel, *ban, *perp, *when_str; time_t howlong; if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(ban = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(perp = ArgList[2])) { /* No problem. */ } if (!(when_str = ArgList[3])) { /* No problem. */ } if (perp && when_str) { howlong = time(NULL) - my_atol(when_str); put_it("%s %s %-25s set by %-10s %ld sec ago", banner(), channel, ban, perp, howlong); } else put_it("%s %s %s", banner(), channel, ban); break; } case 401: /* #define ERR_NOSUCHNICK 401 */ { const char *nick, *stuff; PasteArgs(ArgList, 1); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(stuff = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s: %s", banner(), nick, stuff); break; } case 219: /* #define RPL_ENDOFSTATS 219 */ case 232: /* #define RPL_ENDOFSERVICES 232 */ case 365: /* #define RPL_ENDOFLINKS 365 */ case 369: /* #define RPL_ENDOFWHOWAS 369 */ case 374: /* #define RPL_ENDOFINFO 374 */ case 394: /* #define RPL_ENDOFUSERS 394 */ { PasteArgs(ArgList, 0); if (get_int_var(SHOW_END_OF_MSGS_VAR)) display_msg(from, comm, ArgList); break; } case 471: /* #define ERR_CHANNELISFULL 471 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s (Channel is full)", banner(), message); break; } case 473: /* #define ERR_INVITEONLYCHAN 473 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s (You must be invited)", banner(), message); break; } case 474: /* #define ERR_BANNEDFROMCHAN 474 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s (You are banned)", banner(), message); break; } case 475: /* #define ERR_BADCHANNELKEY 475 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s (You must give the correct key)", banner(), message); break; } case 476: /* #define ERR_BADCHANMASK 476 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s (Bad channel mask)", banner(), message); break; } case 477: /* #define ERR_NEEDREGGEDNICK 477 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } /* IRCnet has a different 477 numeric. */ if (message && *message == '+') { display_msg(from, comm, ArgList); break; } PasteArgs(ArgList, 0); put_it("%s %s (You must use a registered nickname)", banner(), message); break; } default: display_msg(from, comm, ArgList); } END: /* * This is where we clean up after our numeric. Numeric-specific * cleanups can occur here, and then below we reset the display * settings. */ switch (numeric) { case 347: /* #define END_OF_INVITELIST */ case 349: /* #define END_OF_EXCEPTLIST */ case 368: number_of_bans = 0; break; case 464: /* #define ERR_PASSWDMISMATCH 464 */ { char server_num[8]; if (oper_command) oper_command = 0; else if (!is_server_registered(from_server)) { server_reconnects_to(from_server, NOSERV); say("Password required for connection to server %s", get_server_name(from_server)); if (!dumb_mode) { strlcpy(server_num, ltoa(from_server), sizeof server_num); add_wait_prompt("Server Password:", password_sendline, server_num, WAIT_PROMPT_LINE, 0); } } } } current_numeric = old_current_numeric; set_lastlog_msg_level(lastlog_level); message_from(NULL, LOG_CRAP); }
static int multi_stop(ErlDrvData port) { fprintf(stderr,"Closing channel %d\n",channels[port].channel); remove_channel(channels[(int)port].channel); }
/* * numbered_command: does (hopefully) the right thing with the numbered * responses from the server. I wasn't real careful to be sure I got them * all, but the default case should handle any I missed (sorry) */ void numbered_command(u_char *from, int comm, u_char **ArgList) { u_char *user; u_char none_of_these = 0; u_char blah[BIG_BUFFER_SIZE]; int flag, lastlog_level; const int from_server = parsing_server(); #if 0 int user_cnt, inv_cnt, server_cnt; #endif /* 0 */ if (!from || !*from) return; if (!*ArgList[0]) user = NULL; else user = ArgList[0]; if (!ArgList[1]) return; lastlog_level = set_lastlog_msg_level(LOG_CRAP); save_message_from(); message_from(NULL, LOG_CRAP); ArgList++; current_numeric_local = -comm; /* must be negative of numeric! */ switch (comm) { case 001: /* #define RPL_WELCOME 001 */ PasteArgs(ArgList, 0); if (my_strcmp(user, server_get_nickname(from_server)) != 0) { yell("=== Setting this servers nickname to \"%s\" from \"%s\"", user, server_get_nickname(from_server)); server_set_nickname(from_server, user); } if (do_hook(current_numeric(), "%s %s", from, *ArgList)) display_msg(from, ArgList); clean_whois_queue(); break; case 002: /* #define RPL_YOURHOST 002 */ PasteArgs(ArgList, 0); snprintf(CP(blah), sizeof blah, "*** %s", ArgList[0]); got_initial_version(blah); if (do_hook(current_numeric(), "%s %s", from, *ArgList)) display_msg(from, ArgList); break; /* should do something with this some day, 2.8 had channel/user mode switches */ case 004: /* #define RPL_MYINFO 004 */ PasteArgs(ArgList, 0); if (do_hook(current_numeric(), "%s %s", from, *ArgList)) display_msg(from, ArgList); break; /* * this part of ircii has been broken for most of ircd 2.7, so someday I'll * make it work for ircd 2.8 ... phone.. */ #if 0 case 251: /* #define RPL_LUSERCLIENT 251 */ display_msg(from, ArgList); if (is_server_connected(from_server)) break; if (from_server == get_primary_server() && ((sscanf(ArgList[1], "There are %d users and %d invisible on %d servers", &user_cnt, &inv_cnt, &server_cnt) == 3)||(sscanf(ArgList[1], "There are %d users and %d invisible on %d servers", &user_cnt, &inv_cnt, &server_cnt) == 3))) { user_cnt =+ inv_cnt; if ((server_cnt < get_int_var(MINIMUM_SERVERS_VAR)) || (user_cnt < get_int_var(MINIMUM_USERS_VAR))) { say("Trying better populated server..."); get_connected(from_server + 1); } } break; #endif /* 0 */ case 301: /* #define RPL_AWAY 301 */ user_is_away(from, ArgList); break; case 302: /* #define RPL_USERHOST 302 */ userhost_returned(from, ArgList); break; case 303: /* #define RPL_ISON 303 */ ison_returned(from, ArgList); break; case 311: /* #define RPL_WHOISUSER 311 */ whois_name(from, ArgList); break; case 312: /* #define RPL_WHOISSERVER 312 */ whois_server(from, ArgList); break; case 313: /* #define RPL_WHOISOPERATOR 313 */ whois_oper(from, ArgList); break; case 314: /* #define RPL_WHOWASUSER 314 */ whowas_name(from, ArgList); break; case 316: /* #define RPL_WHOISCHANOP 316 */ whois_chop(from, ArgList); break; case 317: /* #define RPL_WHOISIDLE 317 */ whois_lastcom(from, ArgList); break; case 318: /* #define RPL_ENDOFWHOIS 318 */ end_of_whois(from, ArgList); break; case 319: /* #define RPL_WHOISCHANNELS 319 */ whois_channels(from, ArgList); break; case 321: /* #define RPL_LISTSTART 321 */ ArgList[0] = UP("Channel\0Users\0Topic"); ArgList[1] = ArgList[0] + 8; ArgList[2] = ArgList[1] + 6; ArgList[3] = NULL; funny_list(from, ArgList); break; case 322: /* #define RPL_LIST 322 */ funny_list(from, ArgList); break; case 324: /* #define RPL_CHANNELMODEIS 324 */ funny_mode(from, ArgList); break; case 341: /* #define RPL_INVITING 341 */ invite(from, ArgList); break; case 352: /* #define RPL_WHOREPLY 352 */ whoreply(NULL, ArgList); break; case 353: /* #define RPL_NAMREPLY 353 */ funny_namreply(from, ArgList); break; case 366: /* #define RPL_ENDOFNAMES 366 */ { u_char *tmp = NULL, *chan; PasteArgs(ArgList, 0); malloc_strcpy(&tmp, ArgList[0]); chan = next_arg(tmp, 0); flag = do_hook(current_numeric(), "%s %s", from, ArgList[0]); if (flag && channel_mode_lookup(chan, CHAN_NAMES | CHAN_MODE, 0) && get_int_var(SHOW_END_OF_MSGS_VAR) && flag) display_msg(from, ArgList); new_free(&tmp); } break; case 381: /* #define RPL_YOUREOPER 381 */ PasteArgs(ArgList, 0); if (do_hook(current_numeric(), "%s %s", from, *ArgList)) display_msg(from, ArgList); server_set_operator(parsing_server(), 1); update_all_status(); /* fix the status line */ break; case 401: /* #define ERR_NOSUCHNICK 401 */ no_such_nickname(from, ArgList); break; case 405: /* #define ERR_TOOMANYCHANNELS 405 */ remove_channel(ArgList[0], parsing_server()); break; case 421: /* #define ERR_UNKNOWNCOMMAND 421 */ if (check_screen_redirect(ArgList[0])) break; if (check_wait_command(ArgList[0])) break; PasteArgs(ArgList, 0); flag = do_hook(current_numeric(), "%s %s", from, *ArgList); if (!my_strncmp("ISON", *ArgList, 4) || !my_strncmp("USERHOST", *ArgList, 8)) { server_set_2_6_2(parsing_server(), 0); convert_to_whois(); } else if (flag) display_msg(from, ArgList); break; case 432: /* #define ERR_ERRONEUSNICKNAME 432 */ case 433: /* #define ERR_NICKNAMEINUSE 433 */ PasteArgs(ArgList, 0); if (do_hook(current_numeric(), "%s %s", from, *ArgList)) display_msg(from, ArgList); reset_nickname(from); break; case 437: /* #define ERR_UNAVAILRESOURCE 437 */ PasteArgs(ArgList, 0); if (do_hook(current_numeric(), "%s %s", from, *ArgList)) display_msg(from, ArgList); if (!is_channel(*ArgList)) reset_nickname(from); break; case 463: /* #define ERR_NOPERMFORHOST 463 */ display_msg(from, ArgList); close_server(parsing_server(), empty_string()); window_check_servers(); if (!connected_to_server()) get_connected(parsing_server() + 1); break; case 464: /* #define ERR_PASSWDMISMATCH 464 */ PasteArgs(ArgList, 0); flag = do_hook(current_numeric(), "%s %s", from, ArgList[0]); if (server_get_oper_command()) { if (flag) display_msg(from, ArgList); } else get_password(); break; case 465: /* #define ERR_YOUREBANNEDCREEP 465 */ { int klined_server = parsing_server(); PasteArgs(ArgList, 0); if (do_hook(current_numeric(), "%s %s", from, ArgList[0])) display_msg(from, ArgList); close_server(parsing_server(), empty_string()); window_check_servers(); if (number_of_servers() > 1) remove_from_server_list(klined_server); if (!connected_to_server()) say("You are not connected to a server. Use /SERVER to connect."); break; } case 471: /* #define ERR_CHANNELISFULL 471 */ case 473: /* #define ERR_INVITEONLYCHAN 473 */ case 474: /* #define ERR_BANNEDFROMCHAN 474 */ case 475: /* #define ERR_BADCHANNELKEY 475 */ case 476: /* #define ERR_BADCHANMASK 476 */ cannot_join_channel(from, ArgList); break; case 484: /* #define ERR_RESTRICTED 484 */ if (do_hook(current_numeric(), "%s %s", from, *ArgList)) display_msg(from, ArgList); server_set_flag(parsing_server(), USER_MODE_R, 1); break; /* * The following accumulates the remaining arguments * in ArgSpace for hook detection. We can't use * PasteArgs here because we still need the arguments * separated for use elsewhere. */ default: { u_char *ArgSpace = NULL; int i, do_message_from = 0; size_t len; for (i = len = 0; ArgList[i]; len += my_strlen(ArgList[i++])) ; len += (i - 1); ArgSpace = new_malloc(len + 1); ArgSpace[0] = '\0'; /* this is cheating */ if (ArgList[0] && is_channel(ArgList[0])) do_message_from = 1; for (i = 0; ArgList[i]; i++) { if (i) my_strcat(ArgSpace, " "); my_strcat(ArgSpace, ArgList[i]); } if (do_message_from) message_from(ArgList[0], LOG_CRAP); i = do_hook(current_numeric(), "%s %s", from, ArgSpace); new_free(&ArgSpace); if (do_message_from) restore_message_from(); if (i == 0) goto done; none_of_these = 1; } } /* the following do not hurt the ircII if intercepted by a hook */ if (none_of_these) { switch (comm) { case 221: /* #define RPL_UMODEIS 221 */ put_it("%s Your user mode is \"%s\"", numeric_banner(), ArgList[0]); break; case 242: /* #define RPL_STATSUPTIME 242 */ PasteArgs(ArgList, 0); if (from && !my_strnicmp(server_get_itsname(parsing_server()), from, my_strlen(server_get_itsname(parsing_server())))) from = NULL; if (from) put_it("%s %s from (%s)", numeric_banner(), *ArgList, from); else put_it("%s %s", numeric_banner(), *ArgList); break; case 332: /* #define RPL_TOPIC 332 */ channel_topic(from, ArgList); break; case 351: /* #define RPL_VERSION 351 */ version(from, ArgList); break; case 364: /* #define RPL_LINKS 364 */ if (ArgList[2]) { PasteArgs(ArgList, 2); put_it("%s %-20s %-20s %s", numeric_banner(), ArgList[0], ArgList[1], ArgList[2]); } else { PasteArgs(ArgList, 1); put_it("%s %-20s %s", numeric_banner(), ArgList[0], ArgList[1]); } break; case 372: /* #define RPL_MOTD 372 */ if (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) || !server_get_motd(parsing_server())) { PasteArgs(ArgList, 0); put_it("%s %s", numeric_banner(), ArgList[0]); } break; case 375: /* #define RPL_MOTDSTART 375 */ if (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) || !server_get_motd(parsing_server())) { PasteArgs(ArgList, 0); put_it("%s %s", numeric_banner(), ArgList[0]); } break; case 376: /* #define RPL_ENDOFMOTD 376 */ if (server_get_attempting_to_connect(parsing_server())) got_initial_version(UP("*** Your host is broken and not running any version")); if (get_int_var(SHOW_END_OF_MSGS_VAR) && (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) || !server_get_motd(parsing_server()))) { PasteArgs(ArgList, 0); put_it("%s %s", numeric_banner(), ArgList[0]); } server_set_motd(parsing_server(), 0); break; case 384: /* #define RPL_MYPORTIS 384 */ PasteArgs(ArgList, 0); put_it("%s %s %s", numeric_banner(), ArgList[0], user); break; case 385: /* #define RPL_NOTOPERANYMORE 385 */ server_set_operator(parsing_server(), 0); display_msg(from, ArgList); update_all_status(); break; case 403: /* #define ERR_NOSUCHCHANNEL 403 */ not_valid_channel(from, ArgList); break; case 451: /* #define ERR_NOTREGISTERED 451 */ /* * Sometimes the server doesn't catch the USER line, so * here we send a simplified version again -lynx */ send_to_server("USER %s %s . :%s", my_username(), irc_umode(), my_realname()); send_to_server("NICK %s", server_get_nickname(parsing_server())); break; case 462: /* #define ERR_ALREADYREGISTRED 462 */ display_msg(from, ArgList); break; #define RPL_CLOSEEND 363 #define RPL_SERVLISTEND 235 case 315: /* #define RPL_ENDOFWHO 315 */ case 323: /* #define RPL_LISTEND 323 */ funny_print_widelist(); case 219: /* #define RPL_ENDOFSTATS 219 */ case 232: /* #define RPL_ENDOFSERVICES 232 */ case 365: /* #define RPL_ENDOFLINKS 365 */ case 368: /* #define RPL_ENDOFBANLIST 368 */ case 369: /* #define RPL_ENDOFWHOWAS 369 */ case 374: /* #define RPL_ENDOFINFO 374 */ #if 0 /* this case needs special handing - see above */ case 376: /* #define RPL_ENDOFMOTD 376 */ #endif /* 0 */ case 394: /* #define RPL_ENDOFUSERS 394 */ if (!get_int_var(SHOW_END_OF_MSGS_VAR)) break; default: display_msg(from, ArgList); } } set_lastlog_msg_level(lastlog_level); done: restore_message_from(); }
static void p_kick(char *from, char **ArgList) { char *channel, *who, *comment; char *chankey = NULL; struct channel *chan = NULL; struct nick_list *tmpnick = NULL; int t = 0; channel = ArgList[0]; who = ArgList[1]; comment = ArgList[2] ? ArgList[2] : "(no comment)"; if ((chan = lookup_channel(channel, from_server, CHAN_NOUNLINK))) tmpnick = find_nicklist_in_channellist(from, chan, 0); message_from(channel, LOG_CRAP); if (channel && who && chan) { if (!my_stricmp(who, get_server_nickname(from_server))) { Window *window = chan->window; if (chan->key) malloc_strcpy(&chankey, chan->key); if (get_int_var(AUTO_REJOIN_VAR)) { send_to_server(SERVER(from_server), "JOIN %s %s", channel, chankey ? chankey : empty_str); add_to_join_list(channel, from_server, window ? window->refnum : 0); } new_free(&chankey); remove_channel(channel, from_server); update_all_status(curr_scr_win, NULL, 0); update_input(UPDATE_ALL); if (do_hook(KICK_LIST, "%s %s %s %s", who, from, channel, comment ? comment : empty_str)) put_it("%s", convert_output_format(get_format(FORMAT_KICK_USER_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, channel, who, comment)); } else { int itsme = 0; itsme = !my_stricmp(get_server_nickname(from_server), from) ? 1 : 0; if ((check_ignore(from, FromUserHost, channel, IGNORE_KICKS | IGNORE_CRAP, NULL) != IGNORED) && do_hook(KICK_LIST, "%s %s %s %s", who, from, channel, comment)) put_it("%s", convert_output_format(get_format(FORMAT_KICK_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, channel, who, comment)); if (!itsme) { struct nick_list *f_nick = NULL; f_nick = find_nicklist_in_channellist(who, chan, 0); if (chan->chop && tmpnick && is_other_flood(chan, tmpnick, KICK_FLOOD, &t)) { if (get_int_var(KICK_ON_KICKFLOOD_VAR) > get_int_var(DEOP_ON_KICKFLOOD_VAR)) send_to_server(SERVER(from_server), "MODE %s -o %s", chan->channel, from); else if (!f_nick->kickcount++) send_to_server(SERVER(from_server), "KICK %s %s :\002Mass kick detected - (%d kicks in %dsec%s)\002", chan->channel, from, get_int_var(KICK_ON_KICKFLOOD_VAR), t, plural(t)); } } remove_from_channel(channel, who, from_server, 0, NULL); } } update_all_status(curr_scr_win, NULL, 0); message_from(NULL, LOG_CRAP); }
static void cmd_slowpart(int idx, char *par) { int intvl = 0, delay = 0, count = 1; char *chname = NULL, *p = NULL; struct chanset_t *chan = NULL; tand_t *bot = NULL; /* slowpart #chan 60 */ putlog(LOG_CMDS, "*", "#%s# slowpart %s", dcc[idx].nick, par); chname = newsplit(&par); p = newsplit(&par); intvl = atoi(p); if (!chname[0] || !p[0]) { dprintf(idx, "Usage: slowpart <channel> <interval-seconds>\n"); return; } if (intvl < 10) { dprintf(idx, "Interval must be at least 10 seconds\n"); return; } if (!(chan = findchan_by_dname(chname))) { dprintf(idx, "No such channel %s\n", chname); return; } if (conf.bot->hub) count = 0; for (bot = tandbot; bot; bot = bot->next) { char tmp[100] = ""; tmp[0] = 0; if (bot->u) { if (bot_hublevel(bot->u) < 999) { /* HUB */ simple_snprintf(tmp, sizeof(tmp), "sp %s 0", chname); } else { /* LEAF */ struct flag_record fr = { FR_CHAN|FR_GLOBAL|FR_BOT, 0, 0, 0 }; get_user_flagrec(bot->u, &fr, chname); /* Only send the 'sp' command if the bot is supposed to be in the channel (backups and such) */ if (bot_shouldjoin(bot->u, &fr, chan)) { /* Variation: 60 secs intvl should be 60 +/- 15 */ int v = (random() % (intvl / 2)) - (intvl / 4); delay += intvl; simple_snprintf(tmp, sizeof(tmp), "sp %s %i", chname, delay + v); count++; } } if (tmp[0]) putbot(bot->bot, tmp); } } remove_channel(chan); if (conf.bot->hub) write_userfile(-1); dprintf(idx, "Channel %s removed from the bot.\n", chname); dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n"); if (findchan_by_dname(chname)) { dprintf(idx, "Failed to remove channel.\n"); return; } dprintf(idx, "%i bots parting %s during the next %i seconds\n", count, chname, delay); if (!conf.bot->hub) dprintf(DP_MODE, "PART %s\n", chname); }
int main(int argc, char* argv[]) { if(argc != 6) { printf("Enter the required Parameters.\n"); printf("<Npmr> <Nc> <Chanel Slices> <simulation duration> <zipf parameter>\n"); return 2; } FILE *fp = fopen("file.txt","w"); if(fp == NULL) { printf("Error in opening file. Exiting...\n"); exit(1); } //Time duration in Decisecond double VIEW_MEAN = 7200; double FLIP_MEAN = 100; double CHANNEL_MEAN = 6; srand(time(NULL)); //Number of peak multicast request int num_users = atoi(argv[1]); //Number of channels int num_channels = atoi(argv[2]); //Number of channels handled by SDV int num_slices = atoi(argv[3]); //The simulation runtime int simulation_time = atoi(argv[4]); //Simulation time in decisecond simulation_time = simulation_time*10; //The zipf shape parameter float alpha = atof(argv[5]); user *userArray = (user *)malloc(num_users * sizeof(user)); channel *channelArray = (channel *)malloc(num_channels * sizeof(channel)); channel_slice *sliceArray = (channel_slice *)malloc(num_slices * sizeof(channel_slice)); int k,m,n; int num_slice = 0; //Initializing the Channel struct for(k = 0; k<num_channels; k++) { channelArray[k].assigned = FALSE; channelArray[k].channel_slice = -1; channelArray[k].num_viewers = 0; } //Initializing the Channel Slice struct for(k = 0; k<num_slices; k++) { sliceArray[k].assigned = FALSE; sliceArray[k].channel = -1; sliceArray[k].active_duration = 0; sliceArray[k].start_time = 0; } int channel, time; int num_flips; for(k = 0; k <num_users; k++) { time = rand()%100; channel = zipfRN(alpha,num_channels); userArray[k].total_request = 1; userArray[k].fail_request = 0; userArray[k].user_state = FLIP; while(!add_channel(channel,num_slices,time,channelArray,sliceArray,fp)) { channel = zipfRN(alpha,num_channels); userArray[k].fail_request++; userArray[k].total_request++; } userArray[k].current_channel = channel; userArray[k].nextEvent_time = time + exponentialRN(1/FLIP_MEAN); num_flips = exponentialRN(1/CHANNEL_MEAN); while(num_flips == 0) { num_flips = exponentialRN(1/CHANNEL_MEAN); } userArray[k].num_flips = num_flips; } int flag; for(k = 0; k<simulation_time; k++) { for(m = 0; m<num_users; m++) { if(userArray[m].nextEvent_time <= k) { //User is in the VIEW state if(userArray[m].user_state == VIEW) { //Removing the current channel channel = userArray[m].current_channel; if(channel != -1) { remove_channel(channel,k,channelArray,sliceArray,fp); } //The number of channels the user will flip through num_flips = exponentialRN(1/CHANNEL_MEAN); while(num_flips == 0) { num_flips = exponentialRN(1/CHANNEL_MEAN); } userArray[m].num_flips = num_flips; //Change to FLIP state userArray[m].user_state = FLIP; viewers_count--; //User moves up to the next channel channel = rand()%num_channels; userArray[m].total_request++; //Adding a new channel flag = add_channel(channel,num_slices,k,channelArray,sliceArray,fp); if(flag) { userArray[m].nextEvent_time += exponentialRN(1/FLIP_MEAN); userArray[m].current_channel = channel; } else if(!flag) { userArray[m].current_channel = -1; userArray[m].fail_request++; } } //User is in the FLIP state else if(userArray[m].user_state == FLIP) { //Removing the current channel channel = userArray[m].current_channel; if(channel != -1) { remove_channel(channel,k,channelArray,sliceArray,fp); //The number of remaining channels the user will flip through userArray[m].num_flips--; } if(userArray[m].num_flips > 0) { //User moves up to the next channel (channel+1) channel = rand()%num_channels; userArray[m].total_request++; //Adding a new channel flag = add_channel(channel,num_slices,k,channelArray,sliceArray,fp); if(flag) { //Viewing Duration (in the Flip State) userArray[m].nextEvent_time += exponentialRN(1/FLIP_MEAN); //Adding the next channel userArray[m].current_channel = channel; } else if (!flag) { userArray[m].current_channel = -1; userArray[m].fail_request++; } } else if(userArray[m].num_flips <= 0) { //Moves to VIEW State userArray[m].user_state = VIEW; viewers_count++; //The new channel user starts viewing channel = zipfRN(alpha,num_channels); userArray[m].total_request++; //Adding a new channel flag = add_channel(channel,num_slices,k,channelArray,sliceArray,fp); if(flag) { userArray[m].nextEvent_time += exponentialRN(1/VIEW_MEAN); userArray[m].current_channel = channel; } else if (!flag) { userArray[m].current_channel = -1; userArray[m].fail_request++; } } } } } } int active_slices = 0; double avg_streams = 0; for(k = 0; k<num_slices; k++) { if(sliceArray[k].assigned == TRUE && sliceArray[k].active_duration == 0) { sliceArray[k].active_duration = simulation_time - sliceArray[k].start_time; } if(sliceArray[k].active_duration > 0) { active_slices++; //printf("Slice:%d Active Duration:%d Utilization:%3.2f\n",k,sliceArray[k].active_duration,(float)(sliceArray[k].active_duration)/simulation_time); avg_streams += (float)(sliceArray[k].active_duration)/simulation_time; } } printf("\n***** SDV Simulation *****\n"); unsigned int total_request = 0; unsigned int fail_request = 0; for(k = 0; k< num_users; k++) { total_request += userArray[k].total_request; fail_request += userArray[k].fail_request; } printf("Fail request: %u\n",fail_request); printf("Total request: %u\n",total_request); printf("Average Number of Streams: %f\n",avg_streams); printf("Peak Number of Slices: %d\n",peak_slice_count); printf("Average Blocking Probability: %3.4f\n",(float)(fail_request)/total_request); fclose(fp); return 0; }