void hexchat_send_modes (hexchat_plugin *ph, const char **targets, int ntargets, int modes_per_line, char sign, char mode) { char tbuf[514]; /* modes.c needs 512 + null */ send_channel_modes (ph->context, tbuf, (char **)targets, 0, ntargets, sign, mode, modes_per_line); }
static int banlist_unban_inner (gpointer none, banlist_info *banl, int mode_num) { session *sess = banl->sess; GtkTreeModel *model; GtkTreeSelection *sel; GtkTreeIter iter; char tbuf[2048]; char **masks, *mask, *type; int num_sel, i; /* grab the list of selected items */ model = GTK_TREE_MODEL (get_store (sess)); sel = gtk_tree_view_get_selection (get_view (sess)); if (!gtk_tree_model_get_iter_first (model, &iter)) return 0; masks = g_malloc (sizeof (char *) * banl->line_ct); num_sel = 0; do { if (gtk_tree_selection_iter_is_selected (sel, &iter)) { /* Get the mask part of this selected line */ gtk_tree_model_get (model, &iter, TYPE_COLUMN, &type, MASK_COLUMN, &mask, -1); /* If it's the wrong type of mask, just continue */ if (strcmp (_(modes[mode_num].type), type) != 0) continue; /* Otherwise add it to our array of mask pointers */ masks[num_sel++] = g_strdup (mask); g_free (mask); g_free (type); } } while (gtk_tree_model_iter_next (model, &iter)); /* and send to server */ if (num_sel) send_channel_modes (sess, tbuf, masks, 0, num_sel, '-', modes[mode_num].letter, 0); /* now free everything */ for (i=0; i < num_sel; i++) g_free (masks[i]); g_free (masks); return num_sel; }
static int do_server_estab(aClient *cptr) { aClient *acptr; aConnect *aconn; aChannel *chptr; int i; /* "refresh" inpath with host */ char *inpath = get_client_name(cptr, HIDEME); SetServer(cptr); Count.unknown--; Count.server++; Count.myserver++; if(IsZipCapable(cptr) && DoZipThis(cptr)) { sendto_one(cptr, "SVINFO ZIP"); SetZipOut(cptr); cptr->serv->zip_out = zip_create_output_session(); } #ifdef MAXBUFFERS /* let's try to bump up server sock_opts... -Taner */ reset_sock_opts(cptr->fd, 1); #endif /* adds to server list */ add_to_list(&server_list, cptr); set_effective_class(cptr); /* Check one more time for good measure... is it there? */ if ((acptr = find_name(cptr->name, NULL))) { char nbuf[HOSTLEN * 2 + USERLEN + 5]; aClient *bcptr; /* * While negotiating stuff, another copy of this server appeared. * * Rather than KILL the link which introduced it, KILL the * youngest of the two links. -avalon */ bcptr = (cptr->firsttime > acptr->from->firsttime) ? cptr : acptr->from; sendto_one(bcptr, "ERROR :Server %s already exists", cptr->name); if (bcptr == cptr) { sendto_gnotice("from %s: Link %s cancelled, server %s already " "exists (final phase)", me.name, get_client_name(bcptr, HIDEME), cptr->name); sendto_serv_butone(bcptr, ":%s GNOTICE :Link %s cancelled, " "server %s already exists (final phase)", me.name, get_client_name(bcptr, HIDEME), cptr->name); return exit_client(bcptr, bcptr, &me, "Server Exists (final phase)"); } /* inform all those who care (set +n) -epi */ strcpy(nbuf, get_client_name(bcptr, HIDEME)); sendto_gnotice("from %s: Link %s cancelled, server %s reintroduced " "by %s (final phase)", me.name, nbuf, cptr->name, get_client_name(cptr, HIDEME)); sendto_serv_butone(bcptr, ":%s GNOTICE :Link %s cancelled, server %s " "reintroduced by %s (final phase)", me.name, nbuf, cptr->name, get_client_name(cptr, HIDEME)); exit_client(bcptr, bcptr, &me, "Server Exists (final phase)"); } /* error, error, error! if a server is U:'d, and it connects to us, * we need to figure that out! So, do it here. - lucas */ if (find_aUserver(cptr->name)) { Count.myulined++; cptr->flags |= FLAGS_ULINE; /* If the server has special u:line flags, let's set them.. */ cptr->serv->uflags = cptr->serv->aconn->uflags; } fakelinkserver_update(cptr->name, cptr->info); sendto_gnotice("from %s: Link with %s established, states:%s%s%s%s", me.name, inpath, ZipOut(cptr) ? " Output-compressed" : "", RC4EncLink(cptr) ? " encrypted" : "", IsULine(cptr) ? " ULined" : "", DoesTS(cptr) ? " TS" : " Non-TS"); /* * Notify everyone of the fact that this has just linked: the entire * network should get two of these, one explaining the link between * me->serv and the other between serv->me */ sendto_serv_butone(NULL, ":%s GNOTICE :Link with %s established: %s", me.name, inpath, DoesTS(cptr) ? "TS link" : "Non-TS link!"); add_to_client_hash_table(cptr->name, cptr); /* add it to scache */ find_or_add(cptr->name); /* * Old sendto_serv_but_one() call removed because we now need to * send different names to different servers (domain name * matching) Send new server to other servers. */ for (i = 0; i <= highest_fd; i++) { if (!(acptr = local[i]) || !IsServer(acptr) || acptr == cptr || IsMe(acptr)) continue; if ((aconn = acptr->serv->aconn) && !match(my_name_for_link(me.name, aconn), cptr->name)) continue; sendto_one(acptr, ":%s SERVER %s 2 :%s", me.name, cptr->name, cptr->info); } /* * Pass on my client information to the new server * * First, pass only servers (idea is that if the link gets * cancelled beacause the server was already there, there are no * NICK's to be cancelled...). Of course, if cancellation occurs, * all this info is sent anyway, and I guess the link dies when a * read is attempted...? --msa * * Note: Link cancellation to occur at this point means that at * least two servers from my fragment are building up connection * this other fragment at the same time, it's a race condition, * not the normal way of operation... * * ALSO NOTE: using the get_client_name for server names-- see * previous *WARNING*!!! (Also, original inpath is * destroyed...) */ aconn = cptr->serv->aconn; for (acptr = &me; acptr; acptr = acptr->prev) { if (acptr->from == cptr) continue; if (IsServer(acptr)) { if (match(my_name_for_link(me.name, aconn), acptr->name) == 0) continue; sendto_one(cptr, ":%s SERVER %s %d :%s", acptr->serv->up, acptr->name, acptr->hopcount + 1, acptr->info); } } /* send out our SQLINES and SGLINES too */ send_simbans(cptr, SBAN_CHAN|SBAN_NETWORK); send_simbans(cptr, SBAN_NICK|SBAN_NETWORK); send_simbans(cptr, SBAN_GCOS|SBAN_NETWORK); /* Send out fake server list and other 'fake' stuff */ fakeserver_sendserver(cptr); /* Send UHM (user host-masking) type */ if(confopts & FLAGS_HUB) sendto_one(cptr, "SVSUHM %d", uhm_type); /* send clone list */ clones_send(cptr); /* Bursts are about to start.. send a BURST */ if (IsBurst(cptr)) sendto_one(cptr, "BURST"); /* * * Send it in the shortened format with the TS, if it's a TS * server; walk the list of channels, sending all the nicks that * haven't been sent yet for each channel, then send the channel * itself -- it's less obvious than sending all nicks first, but * on the receiving side memory will be allocated more nicely * saving a few seconds in the handling of a split -orabidoo */ { chanMember *cm; static char nickissent = 1; nickissent = 3 - nickissent; /* * flag used for each nick to check if we've sent it yet - must * be different each time and !=0, so we alternate between 1 and * 2 -orabidoo */ for (chptr = channel; chptr; chptr = chptr->nextch) { for (cm = chptr->members; cm; cm = cm->next) { acptr = cm->cptr; if (acptr->nicksent != nickissent) { acptr->nicksent = nickissent; if (acptr->from != cptr) sendnick_TS(cptr, acptr); } } send_channel_modes(cptr, chptr); } /* also send out those that are not on any channel */ for (acptr = &me; acptr; acptr = acptr->prev) if (acptr->nicksent != nickissent) { acptr->nicksent = nickissent; if (acptr->from != cptr) sendnick_TS(cptr, acptr); } } if(confopts & FLAGS_HUB) fakelusers_sendlock(cptr); if(ZipOut(cptr)) { unsigned long inb, outb; double rat; zip_out_get_stats(cptr->serv->zip_out, &inb, &outb, &rat); if(inb) { sendto_gnotice("from %s: Connect burst to %s: %lu bytes normal, " "%lu compressed (%3.2f%%)", me.name, get_client_name(cptr, HIDEME), inb, outb, rat); sendto_serv_butone(cptr, ":%s GNOTICE :Connect burst to %s: %lu " "bytes normal, %lu compressed (%3.2f%%)", me.name, get_client_name(cptr, HIDEME), inb, outb, rat); } } /* stuff a PING at the end of this burst so we can figure out when the other side has finished processing it. */ cptr->flags |= FLAGS_BURST|FLAGS_PINGSENT; if (IsBurst(cptr)) cptr->flags |= FLAGS_SOBSENT; sendto_one(cptr, "PING :%s", me.name); return 0; }
/** Handle a connection that has sent a valid PASS and SERVER. * @param cptr New peer server. * @param aconf Connect block for \a cptr. * @return Zero. */ int server_estab(struct Client *cptr, struct ConfItem *aconf) { struct Client* acptr = 0; const char* inpath; int i; assert(0 != cptr); assert(0 != cli_local(cptr)); inpath = cli_name(cptr); if (IsUnknown(cptr)) { if (aconf->passwd[0]) sendrawto_one(cptr, MSG_PASS " :%s", aconf->passwd); /* * Pass my info to the new server */ sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s6 :%s", cli_name(&me), cli_serv(&me)->timestamp, cli_serv(cptr)->timestamp, MAJOR_PROTOCOL, NumServCap(&me), feature_bool(FEAT_HUB) ? "h" : "", *(cli_info(&me)) ? cli_info(&me) : "IRCers United"); } det_confs_butmask(cptr, CONF_SERVER); if (!IsHandshake(cptr)) hAddClient(cptr); SetServer(cptr); cli_handler(cptr) = SERVER_HANDLER; Count_unknownbecomesserver(UserStats); SetBurst(cptr); /* nextping = CurrentTime; */ /* * NOTE: check for acptr->user == cptr->serv->user is necessary to insure * that we got the same one... bleah */ if (cli_serv(cptr)->user && *(cli_serv(cptr))->by && (acptr = findNUser(cli_serv(cptr)->by))) { if (cli_user(acptr) == cli_serv(cptr)->user) { sendcmdto_one(&me, CMD_NOTICE, acptr, "%C :Link with %s established.", acptr, inpath); } else { /* * if not the same client, set by to empty string */ acptr = 0; *(cli_serv(cptr))->by = '\0'; } } sendto_opmask(acptr, SNO_OLDSNO, "Link with %s established.", inpath); cli_serv(cptr)->up = &me; cli_serv(cptr)->updown = add_dlink(&(cli_serv(&me))->down, cptr); sendto_opmask(0, SNO_NETWORK, "Net junction: %s %s", cli_name(&me), cli_name(cptr)); SetJunction(cptr); /* * Old sendto_serv_but_one() call removed because we now * need to send different names to different servers * (domain name matching) Send new server to other servers. */ for (i = 0; i <= HighestFd; i++) { if (!(acptr = LocalClientArray[i]) || !IsServer(acptr) || acptr == cptr || IsMe(acptr)) continue; if (!match(cli_name(&me), cli_name(cptr))) continue; sendcmdto_one(&me, CMD_SERVER, acptr, "%s 2 0 %Tu J%02u %s%s +%s%s%s :%s", cli_name(cptr), cli_serv(cptr)->timestamp, Protocol(cptr), NumServCap(cptr), IsHub(cptr) ? "h" : "", IsService(cptr) ? "s" : "", IsIPv6(cptr) ? "6" : "", cli_info(cptr)); } /* Send these as early as possible so that glined users/juped servers can * be removed from the network while the remote server is still chewing * our burst. */ gline_burst(cptr); jupe_burst(cptr); /* * Pass on my client information to the new server * * First, pass only servers (idea is that if the link gets * canceled because the server was already there, * there are no NICK's to be canceled...). Of course, * if cancellation occurs, all this info is sent anyway, * and I guess the link dies when a read is attempted...? --msa * * Note: Link cancellation to occur at this point means * that at least two servers from my fragment are building * up connection this other fragment at the same time, it's * a race condition, not the normal way of operation... */ for (acptr = &me; acptr; acptr = cli_prev(acptr)) { /* acptr->from == acptr for acptr == cptr */ if (cli_from(acptr) == cptr) continue; if (IsServer(acptr)) { const char* protocol_str; if (Protocol(acptr) > 9) protocol_str = IsBurst(acptr) ? "J" : "P"; else protocol_str = IsBurst(acptr) ? "J0" : "P0"; if (0 == match(cli_name(&me), cli_name(acptr))) continue; sendcmdto_one(cli_serv(acptr)->up, CMD_SERVER, cptr, "%s %d 0 %Tu %s%u %s%s +%s%s%s :%s", cli_name(acptr), cli_hopcount(acptr) + 1, cli_serv(acptr)->timestamp, protocol_str, Protocol(acptr), NumServCap(acptr), IsHub(acptr) ? "h" : "", IsService(acptr) ? "s" : "", IsIPv6(acptr) ? "6" : "", cli_info(acptr)); } } for (acptr = &me; acptr; acptr = cli_prev(acptr)) { /* acptr->from == acptr for acptr == cptr */ if (cli_from(acptr) == cptr) continue; if (IsUser(acptr)) { char xxx_buf[25]; char *s = umode_str(acptr); sendcmdto_one(cli_user(acptr)->server, CMD_NICK, cptr, "%s %d %Tu %s %s %s%s%s%s %s%s :%s", cli_name(acptr), cli_hopcount(acptr) + 1, cli_lastnick(acptr), cli_user(acptr)->username, cli_user(acptr)->realhost, *s ? "+" : "", s, *s ? " " : "", iptobase64(xxx_buf, &cli_ip(acptr), sizeof(xxx_buf), IsIPv6(cptr)), NumNick(acptr), cli_info(acptr)); } } /* * Last, send the BURST. * (Or for 2.9 servers: pass all channels plus statuses) */ { struct Channel *chptr; for (chptr = GlobalChannelList; chptr; chptr = chptr->next) send_channel_modes(cptr, chptr); } sendcmdto_one(&me, CMD_END_OF_BURST, cptr, ""); return 0; }
static int banlist_unban_inner (gpointer none, struct session *sess, int do_exempts) { GtkTreeModel *model; GtkTreeSelection *sel; GtkTreeIter iter; char tbuf[2048]; char **masks, *tmp, *space; int num_sel, i; /* grab the list of selected items */ model = GTK_TREE_MODEL (get_store (sess)); sel = gtk_tree_view_get_selection (get_view (sess)); num_sel = 0; if (gtk_tree_model_get_iter_first (model, &iter)) { do { if (gtk_tree_selection_iter_is_selected (sel, &iter)) num_sel++; } while (gtk_tree_model_iter_next (model, &iter)); } if (num_sel < 1) return 0; /* create an array of all the masks */ masks = calloc (1, num_sel * sizeof (char *)); i = 0; gtk_tree_model_get_iter_first (model, &iter); do { if (gtk_tree_selection_iter_is_selected (sel, &iter)) { gtk_tree_model_get (model, &iter, MASK_COLUMN, &masks[i], -1); space = strchr (masks[i], ' '); if (do_exempts) { if (space) { /* remove the "(EX) " */ tmp = masks[i]; masks[i] = g_strdup (space + 1); g_free (tmp); i++; } } else { if (!space) i++; } } } while (gtk_tree_model_iter_next (model, &iter)); /* and send to server */ if (do_exempts) send_channel_modes (sess, tbuf, masks, 0, i, '-', 'e', 0); else send_channel_modes (sess, tbuf, masks, 0, i, '-', 'b', 0); /* now free everything, and refresh banlist */ for (i=0; i < num_sel; i++) g_free (masks[i]); free (masks); return num_sel; }