static void dns_name_callback (GObject *obj, GAsyncResult *result, gpointer user_data) { GResolver *resolver = G_RESOLVER(obj); session *sess = (session*)user_data; GList* addrs; gchar* addr; GList* list; g_return_if_fail (is_session (sess)); addrs = g_resolver_lookup_by_name_finish (resolver, result, NULL); if (addrs) { PrintText (sess, _("Resolved to:")); for (list = g_list_first (addrs); list; list = g_list_next (list)) { addr = g_inet_address_to_string (list->data); PrintTextf (sess, " %s", addr); } g_resolver_free_addresses (addrs); } else PrintText (sess, _("Not found")); }
void xchat_print(xchat_plugin *ph, const char *text) { if (!is_session(ph->context)) { DEBUG(PrintTextf(0, "%s\txchat_print called without a valid context.\n", ph->name)); return; } PrintText(ph->context, (char*)text); }
static gint servlist_cycle_cb(server *serv) { if (serv->network) { PrintTextf(serv->server_session, _("Cycling to next server in %s...\n"), ((ircnet *)serv->network)->name); servlist_connect(serv->server_session, serv->network, TRUE); } return 0; }
static gint servlist_cycle_cb (server *serv) { if (serv->network) { PrintTextf (serv->server_session, _("Cycling to next server in %s...\n"), serv->network->name.c_str()); servlist_connect(serv->server_session, *serv->network, true); } return 0; }
static void plugin_auto_load_cb (char *filename) { char *pMsg; pMsg = plugin_load (ps, filename, NULL); if (pMsg) { PrintTextf (ps, "AutoLoad failed for: %s\n", filename); PrintText (ps, pMsg); } }
static void dns_addr_callback (GObject *obj, GAsyncResult *result, gpointer user_data) { GResolver *resolver = G_RESOLVER(obj); session *sess = (session*)user_data; gchar *addr; g_return_if_fail (is_session(sess)); addr = g_resolver_lookup_by_address_finish (resolver, result, NULL); if (addr) PrintTextf (sess, _("Resolved to %s"), addr); else PrintText (sess, _("Not found")); }
static void plugin_auto_load_cb(char *filename) { char *pMsg; #ifndef WIN32 /* black listed */ if (!strcmp(file_part(filename), "dbus.so")) return; #endif pMsg = plugin_load(ps, filename, nullptr); if (pMsg) { PrintTextf(ps, "AutoLoad failed for: %s\n", filename); PrintText(ps, pMsg); } }
void hexchat_command (hexchat_plugin *ph, const char *command) { char *command_utf8; if (!is_session (ph->context)) { DEBUG(PrintTextf(0, "%s\thexchat_command called without a valid context.\n", ph->name)); return; } /* scripts/plugins continue to send non-UTF8... *sigh* */ command_utf8 = text_fixup_invalid_utf8 (command, -1, NULL); handle_command (ph->context, command_utf8, FALSE); g_free (command_utf8); }
void xchat_command(xchat_plugin *ph, const char *command) { char *conv; int len = -1; if (!is_session(ph->context)) { DEBUG(PrintTextf(0, "%s\txchat_command called without a valid context.\n", ph->name)); return; } // scripts/plugins continue to send non-UTF8... *sigh* conv = text_validate((char**)&command, &len); handle_command(ph->context, (char*)command, FALSE); g_free (conv); }
void do_dns (session *sess, char *nick, char *host, const message_tags_data *tags_data) { GResolver *res = g_resolver_get_default (); GInetAddress *addr; char *po; po = strrchr (host, '@'); if (po) host = po + 1; if (nick) EMIT_SIGNAL_TIMESTAMP (XP_TE_RESOLVINGUSER, sess, tags_data->timestamp, nick, host); PrintTextf (sess, _("Looking up %s..."), host); addr = g_inet_address_new_from_string (host); if (addr) g_resolver_lookup_by_address_async (res, addr, NULL, dns_addr_callback, sess); else g_resolver_lookup_by_name_async (res, host, NULL, dns_name_callback, sess); }
const char * hexchat_get_info (hexchat_plugin *ph, const char *id) { session *sess; guint32 hash; /* 1234567890 */ if (!strncmp (id, "event_text", 10)) { char *e = (char *)id + 10; if (*e == ' ') e++; /* 2.8.0 only worked without a space */ return text_find_format_string (e); } hash = str_hash (id); /* do the session independant ones first */ switch (hash) { case 0x325acab5: /* libdirfs */ #ifdef USE_PLUGIN return plugin_get_libdir (); #else return NULL; #endif case 0x14f51cd8: /* version */ return PACKAGE_VERSION; case 0xdd9b1abd: /* xchatdir */ case 0xe33f6c4a: /* xchatdirfs */ case 0xd00d220b: /* configdir */ return get_xdir (); } sess = ph->context; if (!is_session (sess)) { DEBUG(PrintTextf(0, "%s\thexchat_get_info called without a valid context.\n", ph->name)); return NULL; } switch (hash) { case 0x2de2ee: /* away */ if (sess->server->is_away) return sess->server->last_away_reason; return NULL; case 0x2c0b7d03: /* channel */ return sess->channel; case 0x2c0d614c: /* charset */ { const char *locale; if (sess->server->encoding) return sess->server->encoding; locale = NULL; g_get_charset (&locale); return locale; } case 0x30f5a8: /* host */ return sess->server->hostname; case 0x1c0e99c1: /* inputbox */ return fe_get_inputbox_contents (sess); case 0x633fb30: /* modes */ return sess->current_modes; case 0x6de15a2e: /* network */ return server_get_network (sess->server, FALSE); case 0x339763: /* nick */ return sess->server->nick; case 0x4889ba9b: /* password */ case 0x438fdf9: /* nickserv */ if (sess->server->network) return ((ircnet *)sess->server->network)->pass; return NULL; case 0xca022f43: /* server */ if (!sess->server->connected) return NULL; return sess->server->servername; case 0x696cd2f: /* topic */ return sess->topic; case 0x3419f12d: /* gtkwin_ptr */ return fe_gui_info_ptr (sess, 1); case 0x506d600b: /* native win_ptr */ return fe_gui_info_ptr (sess, 0); case 0x6d3431b5: /* win_status */ switch (fe_gui_info (sess, 0)) /* check window status */ { case 0: return "normal"; case 1: return "active"; case 2: return "hidden"; } return NULL; } return NULL; }
static void process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) { server *serv = sess->server; char ip[128], nick[NICKLEN]; char *text, *ex; int len = strlen (type); /* fill in the "ip" and "nick" buffers */ ex = strchr (word[1], '!'); if (!ex) /* no '!', must be a server message */ { safe_strcpy (ip, word[1], sizeof (ip)); safe_strcpy (nick, word[1], sizeof (nick)); } else { safe_strcpy (ip, ex + 1, sizeof (ip)); ex[0] = 0; safe_strcpy (nick, word[1], sizeof (nick)); ex[0] = '!'; } if (len == 4) { guint32 t; t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); /* this should compile to a bunch of: CMP.L, JE ... nice & fast */ switch (t) { case WORDL('J','O','I','N'): { char *chan = word[3]; if (*chan == ':') chan++; if (!serv->p_cmp (nick, serv->nick)) inbound_ujoin (serv, chan, nick, ip); else inbound_join (serv, chan, nick, ip); } return; case WORDL('K','I','C','K'): { char *kicked = word[4]; char *reason = word_eol[5]; if (*kicked) { if (*reason == ':') reason++; if (!strcmp (kicked, serv->nick)) inbound_ukick (serv, word[3], nick, reason); else inbound_kick (serv, word[3], kicked, nick, reason); } } return; case WORDL('K','I','L','L'): EMIT_SIGNAL (XP_TE_KILL, sess, nick, word_eol[5], NULL, NULL, 0); return; case WORDL('M','O','D','E'): handle_mode (serv, word, word_eol, nick, FALSE); /* modes.c */ return; case WORDL('N','I','C','K'): inbound_newnick (serv, nick, (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3], FALSE); return; case WORDL('P','A','R','T'): { char *chan = word[3]; char *reason = word_eol[4]; if (*chan == ':') chan++; if (*reason == ':') reason++; if (!strcmp (nick, serv->nick)) inbound_upart (serv, chan, ip, reason); else inbound_part (serv, chan, nick, ip, reason); } return; case WORDL('P','O','N','G'): inbound_ping_reply (serv->server_session, (word[4][0] == ':') ? word[4] + 1 : word[4], word[3]); return; case WORDL('Q','U','I','T'): inbound_quit (serv, nick, ip, (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3]); return; } goto garbage; } else if (len >= 5) { guint32 t; t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); /* this should compile to a bunch of: CMP.L, JE ... nice & fast */ switch (t) { case WORDL('I','N','V','I'): if (ignore_check (word[1], IG_INVI)) return; if (word[4][0] == ':') EMIT_SIGNAL (XP_TE_INVITED, sess, word[4] + 1, nick, serv->servername, NULL, 0); else EMIT_SIGNAL (XP_TE_INVITED, sess, word[4], nick, serv->servername, NULL, 0); return; case WORDL('N','O','T','I'): { int id = FALSE; /* identified */ text = word_eol[4]; if (*text == ':') text++; if (serv->have_idmsg) { if (*text == '+') { id = TRUE; text++; } else if (*text == '-') text++; } if (!ignore_check (word[1], IG_NOTI)) inbound_notice (serv, word[3], nick, text, ip, id); } return; case WORDL('P','R','I','V'): { char *to = word[3]; int len; int id = FALSE; /* identified */ if (*to) { text = word_eol[4]; if (*text == ':') text++; if (serv->have_idmsg) { if (*text == '+') { id = TRUE; text++; } else if (*text == '-') text++; } len = strlen (text); if (text[0] == 1 && text[len - 1] == 1) /* ctcp */ { text[len - 1] = 0; text++; if (strncasecmp (text, "ACTION", 6) != 0) flood_check (nick, ip, serv, sess, 0); if (strncasecmp (text, "DCC ", 4) == 0) /* redo this with handle_quotes TRUE */ process_data_init (word[1], word_eol[1], word, word_eol, TRUE, FALSE); ctcp_handle (sess, to, nick, ip, text, word, word_eol, id); } else { if (is_channel (serv, to)) { if (ignore_check (word[1], IG_CHAN)) return; inbound_chanmsg (serv, NULL, to, nick, text, FALSE, id); } else { if (ignore_check (word[1], IG_PRIV)) return; inbound_privmsg (serv, nick, ip, text, id); } } } } return; case WORDL('T','O','P','I'): inbound_topicnew (serv, nick, word[3], (word_eol[4][0] == ':') ? word_eol[4] + 1 : word_eol[4]); return; case WORDL('W','A','L','L'): text = word_eol[3]; if (*text == ':') text++; EMIT_SIGNAL (XP_TE_WALLOPS, sess, nick, text, NULL, NULL, 0); return; } } else if (len == 3) { guint32 t; t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); switch (t) { case WORDL('C','A','P','\0'): if (strncasecmp(word[4], "ACK", 3) == 0) { if (strncasecmp(word[5][0]==':' ? word[5]+1 : word[5], "identify-msg", 12) == 0) { serv->have_idmsg = TRUE; tcp_send_len(serv, "CAP END\r\n", 9); } } else if (strncasecmp(word[4], "LS", 2) == 0) { if (strstr(word_eol[5], "identify-msg") != 0) tcp_send_len(serv, "CAP REQ :identify-msg\r\n", 23); else tcp_send_len(serv, "CAP END\r\n", 9); } else if (strncasecmp(word[4], "NAK",3) == 0) { tcp_send_len(serv, "CAP END\r\n", 9); } return; } } garbage: /* unknown message */ PrintTextf (sess, "GARBAGE: %s\n", word_eol[1]); }
static void process_numeric (session * sess, int n, char *word[], char *word_eol[], char *text) { server *serv = sess->server; /* show whois is the server tab */ session *whois_sess = serv->server_session; /* unless this setting is on */ if (prefs.irc_whois_front) whois_sess = serv->front_session; switch (n) { case 1: inbound_login_start (sess, word[3], word[1]); /* if network is PTnet then you must get your IP address from "001" server message */ if ((strncmp(word[7], "PTnet", 5) == 0) && (strncmp(word[8], "IRC", 3) == 0) && (strncmp(word[9], "Network", 7) == 0) && (strrchr(word[10], '@') != NULL)) { serv->use_who = FALSE; if (prefs.ip_from_server) inbound_foundip (sess, strrchr(word[10], '@')+1); } /* use /NICKSERV */ if (strcasecmp (word[7], "DALnet") == 0 || strcasecmp (word[7], "BRASnet") == 0) serv->nickservtype = 1; /* use /NS */ else if (strcasecmp (word[7], "FreeNode") == 0) serv->nickservtype = 2; goto def; case 4: /* check the ircd type */ serv->use_listargs = FALSE; serv->modes_per_line = 3; /* default to IRC RFC */ if (strncmp (word[5], "bahamut", 7) == 0) /* DALNet */ { serv->use_listargs = TRUE; /* use the /list args */ } else if (strncmp (word[5], "u2.10.", 6) == 0) /* Undernet */ { serv->use_listargs = TRUE; /* use the /list args */ serv->modes_per_line = 6; /* allow 6 modes per line */ } else if (strncmp (word[5], "glx2", 4) == 0) { serv->use_listargs = TRUE; /* use the /list args */ } goto def; case 5: inbound_005 (serv, word); goto def; case 263: /*Server load is temporarily too heavy */ if (fe_is_chanwindow (sess->server)) { fe_chan_list_end (sess->server); fe_message (word_eol[5] + 1, FE_MSG_ERROR); } goto def; case 290: /* CAPAB reply */ if (strstr (word_eol[1], "IDENTIFY-MSG")) { serv->have_idmsg = TRUE; break; } goto def; case 301: inbound_away (serv, word[4], (word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5]); break; case 302: if (serv->skip_next_userhost) { char *eq = strchr (word[4], '='); if (eq) { *eq = 0; if (!serv->p_cmp (word[4] + 1, serv->nick)) { char *at = strrchr (eq + 1, '@'); if (at) inbound_foundip (sess, at + 1); } } serv->skip_next_userhost = FALSE; break; } else goto def; case 303: word[4]++; notify_markonline (serv, word); break; case 305: inbound_uback (serv); goto def; case 306: inbound_uaway (serv); goto def; case 312: if (!serv->skip_next_whois) EMIT_SIGNAL (XP_TE_WHOIS3, whois_sess, word[4], word_eol[5], NULL, NULL, 0); else inbound_user_info (sess, NULL, NULL, NULL, word[5], word[4], NULL, 0xff); break; case 311: /* WHOIS 1st line */ serv->inside_whois = 1; inbound_user_info_start (sess, word[4]); if (!serv->skip_next_whois) EMIT_SIGNAL (XP_TE_WHOIS1, whois_sess, word[4], word[5], word[6], word_eol[8] + 1, 0); else inbound_user_info (sess, NULL, word[5], word[6], NULL, word[4], word_eol[8][0] == ':' ? word_eol[8] + 1 : word_eol[8], 0xff); break; case 314: /* WHOWAS */ inbound_user_info_start (sess, word[4]); EMIT_SIGNAL (XP_TE_WHOIS1, whois_sess, word[4], word[5], word[6], word_eol[8] + 1, 0); break; case 317: if (!serv->skip_next_whois) { time_t timestamp = (time_t) atol (word[6]); long idle = atol (word[5]); char *tim; char outbuf[64]; snprintf (outbuf, sizeof (outbuf), "%02ld:%02ld:%02ld", idle / 3600, (idle / 60) % 60, idle % 60); if (timestamp == 0) EMIT_SIGNAL (XP_TE_WHOIS4, whois_sess, word[4], outbuf, NULL, NULL, 0); else { tim = ctime (×tamp); tim[19] = 0; /* get rid of the \n */ EMIT_SIGNAL (XP_TE_WHOIS4T, whois_sess, word[4], outbuf, tim, NULL, 0); } } break; case 318: /* END OF WHOIS */ if (!serv->skip_next_whois) EMIT_SIGNAL (XP_TE_WHOIS6, whois_sess, word[4], NULL, NULL, NULL, 0); serv->skip_next_whois = 0; serv->inside_whois = 0; break; case 313: case 319: if (!serv->skip_next_whois) EMIT_SIGNAL (XP_TE_WHOIS2, whois_sess, word[4], word_eol[5] + 1, NULL, NULL, 0); break; case 307: /* dalnet version */ case 320: /* :is an identified user */ if (!serv->skip_next_whois) EMIT_SIGNAL (XP_TE_WHOIS_ID, whois_sess, word[4], word_eol[5] + 1, NULL, NULL, 0); break; case 321: if (!fe_is_chanwindow (sess->server)) EMIT_SIGNAL (XP_TE_CHANLISTHEAD, serv->server_session, NULL, NULL, NULL, NULL, 0); break; case 322: if (fe_is_chanwindow (sess->server)) { fe_add_chan_list (sess->server, word[4], word[5], word_eol[6] + 1); } else { PrintTextf (serv->server_session, "%-16s %-7d %s\017\n", word[4], atoi (word[5]), word_eol[6] + 1); } break; case 323: if (!fe_is_chanwindow (sess->server)) EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, word[1], word[2], NULL, 0); else fe_chan_list_end (sess->server); break; case 324: sess = find_channel (serv, word[4]); if (!sess) sess = serv->server_session; if (sess->ignore_mode) sess->ignore_mode = FALSE; else EMIT_SIGNAL (XP_TE_CHANMODES, sess, word[4], word_eol[5], NULL, NULL, 0); fe_update_mode_buttons (sess, 't', '-'); fe_update_mode_buttons (sess, 'n', '-'); fe_update_mode_buttons (sess, 's', '-'); fe_update_mode_buttons (sess, 'i', '-'); fe_update_mode_buttons (sess, 'p', '-'); fe_update_mode_buttons (sess, 'm', '-'); fe_update_mode_buttons (sess, 'l', '-'); fe_update_mode_buttons (sess, 'k', '-'); handle_mode (serv, word, word_eol, "", TRUE); break; case 329: sess = find_channel (serv, word[4]); if (sess) { if (sess->ignore_date) sess->ignore_date = FALSE; else channel_date (sess, word[4], word[5]); } break; case 330: if (!serv->skip_next_whois) EMIT_SIGNAL (XP_TE_WHOIS_AUTH, whois_sess, word[4], word_eol[6] + 1, word[5], NULL, 0); break; case 332: inbound_topic (serv, word[4], (word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5]); break; case 333: inbound_topictime (serv, word[4], word[5], atol (word[6])); break; #if 0 case 338: /* Undernet Real user@host, Real IP */ EMIT_SIGNAL (XP_TE_WHOIS_REALHOST, sess, word[4], word[5], word[6], (word_eol[7][0]==':') ? word_eol[7]+1 : word_eol[7], 0); break; #endif case 341: /* INVITE ACK */ EMIT_SIGNAL (XP_TE_UINVITE, sess, word[4], word[5], serv->servername, NULL, 0); break; case 352: /* WHO */ { unsigned int away = 0; session *who_sess = find_channel (serv, word[4]); if (*word[9] == 'G') away = 1; inbound_user_info (sess, word[4], word[5], word[6], word[7], word[8], word_eol[11], away); /* try to show only user initiated whos */ if (!who_sess || !who_sess->doing_who) EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, word[1], word[2], NULL, 0); } break; case 354: /* undernet WHOX: used as a reply for irc_away_status */ { unsigned int away = 0; session *who_sess; /* irc_away_status sends out a "152" */ if (!strcmp (word[4], "152")) { who_sess = find_channel (serv, word[5]); if (*word[7] == 'G') away = 1; /* :SanJose.CA.us.undernet.org 354 z1 152 #zed1 z1 H@ */ inbound_user_info (sess, word[5], 0, 0, 0, word[6], 0, away); /* try to show only user initiated whos */ if (!who_sess || !who_sess->doing_who) EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, word[1], word[2], NULL, 0); } else goto def; } break; case 315: /* END OF WHO */ { session *who_sess; who_sess = find_channel (serv, word[4]); if (who_sess) { if (!who_sess->doing_who) EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, word[1], word[2], NULL, 0); who_sess->doing_who = FALSE; } else { if (!serv->doing_dns) EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, word[1], word[2], NULL, 0); serv->doing_dns = FALSE; } } break; case 348: /* +e-list entry */ if (!inbound_banlist (sess, atol (word[7]), word[4], word[5], word[6], TRUE)) goto def; break; case 349: /* end of exemption list */ sess = find_channel (serv, word[4]); if (!sess) { sess = serv->front_session; goto def; } if (!fe_is_banwindow (sess)) goto def; fe_ban_list_end (sess, TRUE); break; case 353: /* NAMES */ inbound_nameslist (serv, word[5], (word_eol[6][0] == ':') ? word_eol[6] + 1 : word_eol[6]); break; case 366: if (!inbound_nameslist_end (serv, word[4])) goto def; break; case 367: /* banlist entry */ inbound_banlist (sess, atol (word[7]), word[4], word[5], word[6], FALSE); break; case 368: sess = find_channel (serv, word[4]); if (!sess) { sess = serv->front_session; goto def; } if (!fe_is_banwindow (sess)) goto def; fe_ban_list_end (sess, FALSE); break; case 369: /* WHOWAS end */ case 406: /* WHOWAS error */ EMIT_SIGNAL (XP_TE_SERVTEXT, whois_sess, text, word[1], word[2], NULL, 0); serv->inside_whois = 0; break; case 372: /* motd text */ case 375: /* motd start */ if (!prefs.skipmotd || serv->motd_skipped) EMIT_SIGNAL (XP_TE_MOTD, serv->server_session, text, NULL, NULL, NULL, 0); break; case 376: /* end of motd */ case 422: /* motd file is missing */ inbound_login_end (sess, text); break; case 433: /* nickname in use */ case 432: /* erroneous nickname */ if (serv->end_of_motd) goto def; inbound_next_nick (sess, word[4]); break; case 437: if (serv->end_of_motd || is_channel (serv, word[4])) goto def; inbound_next_nick (sess, word[4]); break; case 471: EMIT_SIGNAL (XP_TE_USERLIMIT, sess, word[4], NULL, NULL, NULL, 0); break; case 473: EMIT_SIGNAL (XP_TE_INVITE, sess, word[4], NULL, NULL, NULL, 0); break; case 474: EMIT_SIGNAL (XP_TE_BANNED, sess, word[4], NULL, NULL, NULL, 0); break; case 475: EMIT_SIGNAL (XP_TE_KEYWORD, sess, word[4], NULL, NULL, NULL, 0); break; case 601: notify_set_offline (serv, word[4], FALSE); break; case 605: notify_set_offline (serv, word[4], TRUE); break; case 600: case 604: notify_set_online (serv, word[4]); break; default: if (serv->inside_whois && word[4][0]) { /* some unknown WHOIS reply, ircd coders make them up weekly */ if (!serv->skip_next_whois) EMIT_SIGNAL (XP_TE_WHOIS_SPECIAL, whois_sess, word[4], (word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5], word[2], NULL, 0); return; } def: if (is_channel (serv, word[4])) { session *realsess = find_channel (serv, word[4]); if (!realsess) realsess = serv->server_session; EMIT_SIGNAL (XP_TE_SERVTEXT, realsess, text, word[1], word[2], NULL, 0); } else { EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, word[1], word[2], NULL, 0); } } }
int cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { int wild = FALSE; int or = FALSE; int off = FALSE; int quiet = FALSE; int erase = FALSE; int i = 0, finds = 0, found; int idx = 2; int prev_numeric; char *var, *val, *prev_string; if (g_ascii_strcasecmp (word[2], "-e") == 0) { idx++; erase = TRUE; } /* turn a bit OFF */ if (g_ascii_strcasecmp (word[idx], "-off") == 0) { idx++; off = TRUE; } /* turn a bit ON */ if (g_ascii_strcasecmp (word[idx], "-or") == 0 || g_ascii_strcasecmp (word[idx], "-on") == 0) { idx++; or = TRUE; } if (g_ascii_strcasecmp (word[idx], "-quiet") == 0) { idx++; quiet = TRUE; } var = word[idx]; val = word_eol[idx+1]; if (!*var) { set_list (sess, tbuf); return TRUE; } if ((strchr (var, '*') || strchr (var, '?')) && !*val) { wild = TRUE; } if (*val == '=') { val++; } do { if (wild) { found = !match (var, vars[i].name); } else { found = g_ascii_strcasecmp (var, vars[i].name); } if (found == 0) { finds++; switch (vars[i].type) { case TYPE_STR: if (erase || *val) { /* save the previous value until we print it out */ prev_string = (char*) malloc (vars[i].len + 1); strncpy (prev_string, (char *) &prefs + vars[i].offset, vars[i].len); /* update the variable */ strncpy ((char *) &prefs + vars[i].offset, val, vars[i].len); ((char *) &prefs)[vars[i].offset + vars[i].len - 1] = 0; if (!quiet) { PrintTextf (sess, "%s set to: %s (was: %s)\n", var, (char *) &prefs + vars[i].offset, prev_string); } free (prev_string); } else { set_showval (sess, &vars[i], tbuf); } break; case TYPE_INT: case TYPE_BOOL: if (*val) { prev_numeric = *((int *) &prefs + vars[i].offset); if (vars[i].type == TYPE_BOOL) { if (atoi (val)) { *((int *) &prefs + vars[i].offset) = 1; } else { *((int *) &prefs + vars[i].offset) = 0; } if (!g_ascii_strcasecmp (val, "YES") || !g_ascii_strcasecmp (val, "ON")) { *((int *) &prefs + vars[i].offset) = 1; } if (!g_ascii_strcasecmp (val, "NO") || !g_ascii_strcasecmp (val, "OFF")) { *((int *) &prefs + vars[i].offset) = 0; } } else { if (or) { *((int *) &prefs + vars[i].offset) |= atoi (val); } else if (off) { *((int *) &prefs + vars[i].offset) &= ~(atoi (val)); } else { *((int *) &prefs + vars[i].offset) = atoi (val); } } if (!quiet) { PrintTextf (sess, "%s set to: %d (was: %d)\n", var, *((int *) &prefs + vars[i].offset), prev_numeric); } } else { set_showval (sess, &vars[i], tbuf); } break; } } i++; } while (vars[i].name); if (!finds && !quiet) { PrintText (sess, "No such variable.\n"); } else if (!save_config ()) { PrintText (sess, "Error saving changes to disk.\n"); } return TRUE; }
const char* xchat_get_info(xchat_plugin *ph, const char *id) { session *sess; unsigned int hash; // 1234567890 if (!strncmp(id, "event_text", 10)) { char *e = (char*)id + 10; if (*e == ' ') e++; // 2.8.0 only worked without a space return text_find_format_string(e); } hash = str_hash(id); // do the session independant ones first switch (hash) { case 0x325acab5: // libdirfs return XCHATLIBDIR; case 0x14f51cd8: // version return PACKAGE_VERSION; case 0xdd9b1abd: // xchatdir return get_xdir_utf8(); case 0xe33f6c4a: // xchatdirfs return get_xdir_fs(); } sess = ph->context; if (!is_session(sess)) { DEBUG(PrintTextf(0, "%s\txchat_get_info called without a valid context.\n", ph->name)); return nullptr; } switch (hash) { case 0x2de2ee: // away if (sess->server->is_away) return sess->server->last_away_reason; return nullptr; case 0x2c0b7d03: // channel return sess->channel; case 0x2c0d614c: // charset { const char *locale; if (sess->server->encoding) return sess->server->encoding; locale = nullptr; g_get_charset(&locale); return locale; } case 0x30f5a8: // host return sess->server->hostname; case 0x1c0e99c1: // inputbox return fe_get_inputbox_contents(sess); case 0x633fb30: // modes return sess->current_modes; case 0x6de15a2e: // network return server_get_network(sess->server, FALSE); case 0x339763: // nick return sess->server->nick; case 0x438fdf9: // nickserv if (sess->server->network) return ((ircnet*)sess->server->network)->nickserv; return nullptr; case 0xca022f43: // server if (!sess->server->connected) return nullptr; return sess->server->servername; case 0x696cd2f: // topic return sess->topic; case 0x3419f12d: // gtkwin_ptr return (const char*)fe_gui_info_ptr(sess, 1); case 0x506d600b: // native win_ptr return (const char*)fe_gui_info_ptr(sess, 0); case 0x6d3431b5: // win_status switch (fe_gui_info(sess, 0)) // check window status { case 0: return "normal"; case 1: return "active"; case 2: return "hidden"; } return nullptr; } return nullptr; }
static void process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) { server *serv = sess->server; char ip[128], nick[NICKLEN]; char *text, *ex; int len = strlen (type); /* fill in the "ip" and "nick" buffers */ ex = strchr (word[1], '!'); if (!ex) /* no '!', must be a server message */ { safe_strcpy (ip, word[1], sizeof (ip)); safe_strcpy (nick, word[1], sizeof (nick)); } else { safe_strcpy (ip, ex + 1, sizeof (ip)); ex[0] = 0; safe_strcpy (nick, word[1], sizeof (nick)); ex[0] = '!'; } if (len == 4) { guint32 t; t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); /* this should compile to a bunch of: CMP.L, JE ... nice & fast */ switch (t) { case WORDL('J','O','I','N'): { char *chan = word[3]; if (*chan == ':') chan++; if (!serv->p_cmp (nick, serv->nick)) inbound_ujoin (serv, chan, nick, ip); else inbound_join (serv, chan, nick, ip); } return; case WORDL('K','I','C','K'): { char *kicked = word[4]; char *reason = word_eol[5]; if (*kicked) { if (*reason == ':') reason++; if (!strcmp (kicked, serv->nick)) inbound_ukick (serv, word[3], nick, reason); else inbound_kick (serv, word[3], kicked, nick, reason); } } return; case WORDL('K','I','L','L'): EMIT_SIGNAL (XP_TE_KILL, sess, nick, word_eol[5], NULL, NULL, 0); return; case WORDL('M','O','D','E'): handle_mode (serv, word, word_eol, nick, FALSE); /* modes.c */ return; case WORDL('N','I','C','K'): inbound_newnick (serv, nick, (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3], FALSE); return; case WORDL('P','A','R','T'): { char *chan = word[3]; char *reason = word_eol[4]; if (*chan == ':') chan++; if (*reason == ':') reason++; if (!strcmp (nick, serv->nick)) inbound_upart (serv, chan, ip, reason); else inbound_part (serv, chan, nick, ip, reason); } return; case WORDL('P','O','N','G'): inbound_ping_reply (serv->server_session, (word[4][0] == ':') ? word[4] + 1 : word[4], word[3]); return; case WORDL('Q','U','I','T'): inbound_quit (serv, nick, ip, (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3]); return; } goto garbage; } else if (len >= 5) { guint32 t; t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); /* this should compile to a bunch of: CMP.L, JE ... nice & fast */ switch (t) { case WORDL('I','N','V','I'): if (ignore_check (word[1], IG_INVI)) return; if (word[4][0] == ':') EMIT_SIGNAL (XP_TE_INVITED, sess, word[4] + 1, nick, serv->servername, NULL, 0); else EMIT_SIGNAL (XP_TE_INVITED, sess, word[4], nick, serv->servername, NULL, 0); return; case WORDL('N','O','T','I'): { int id = FALSE; /* identified */ text = word_eol[4]; if (*text == ':') text++; if (serv->have_idmsg) { if (*text == '+') { id = TRUE; text++; } else if (*text == '-') text++; } if (!ignore_check (word[1], IG_NOTI)) inbound_notice (serv, word[3], nick, text, ip, id); } return; case WORDL('P','R','I','V'): { char *to = word[3]; int len; int id = FALSE; /* identified */ if (*to) { text = word_eol[4]; if (*text == ':') text++; if (serv->have_idmsg) { if (*text == '+') { id = TRUE; text++; } else if (*text == '-') text++; } len = strlen (text); if (text[0] == 1 && text[len - 1] == 1) /* ctcp */ { text[len - 1] = 0; text++; if (g_ascii_strncasecmp (text, "ACTION", 6) != 0) flood_check (nick, ip, serv, sess, 0); if (g_ascii_strncasecmp (text, "DCC ", 4) == 0) /* redo this with handle_quotes TRUE */ process_data_init (word[1], word_eol[1], word, word_eol, TRUE, FALSE); ctcp_handle (sess, to, nick, ip, text, word, word_eol, id); } else { if (is_channel (serv, to)) { if (ignore_check (word[1], IG_CHAN)) return; inbound_chanmsg (serv, NULL, to, nick, text, FALSE, id); } else { if (ignore_check (word[1], IG_PRIV)) return; inbound_privmsg (serv, nick, ip, text, id); } } } } return; case WORDL('T','O','P','I'): inbound_topicnew (serv, nick, word[3], (word_eol[4][0] == ':') ? word_eol[4] + 1 : word_eol[4]); return; case WORDL('W','A','L','L'): text = word_eol[3]; if (*text == ':') text++; EMIT_SIGNAL (XP_TE_WALLOPS, sess, nick, text, NULL, NULL, 0); return; } } else if (len == 3) { guint32 t; guint32 want_cap; /* format the CAP REQ string based on previous capabilities being requested or not */ guint32 want_sasl; /* CAP END shouldn't be sent when SASL is requested, it needs further responses */ char *pass; /* buffer for SASL password */ char buffer[256]; /* buffer for requesting capabilities and emitting the signal */ t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); switch (t) { case WORDL('C','A','P','\0'): if (strncasecmp (word[4], "ACK", 3) == 0) { EMIT_SIGNAL (XP_TE_CAPACK, sess->server->server_session, word[1], word[5][0]==':' ? ++word_eol[5] : word_eol[5], NULL, NULL, 0); if (strstr (word_eol[5], "identify-msg") != 0) { serv->have_idmsg = TRUE; } if (strstr (word_eol[5], "multi-prefix") != 0) { serv->have_namesx = TRUE; } if (strstr (word_eol[5], "sasl") != 0) { serv->have_sasl = TRUE; EMIT_SIGNAL (XP_TE_SASLAUTH, serv->server_session, sess->server->sasluser, NULL, NULL, NULL, 0); tcp_send_len (serv, "AUTHENTICATE PLAIN\r\n", 20); pass = encode_sasl_pass (sess->server->sasluser, sess->server->saslpassword); tcp_sendf (sess->server, "AUTHENTICATE %s\r\n", pass); free (pass); } } else if (strncasecmp (word[4], "LS", 2) == 0) { EMIT_SIGNAL (XP_TE_CAPLIST, serv->server_session, word[1], word[5][0]==':' ? ++word_eol[5] : word_eol[5], NULL, NULL, 0); want_cap = 0; want_sasl = 0; if (strstr (word_eol[5], "identify-msg") != 0) { strcpy (buffer, "CAP REQ :identify-msg"); want_cap = 1; } if (strstr (word_eol[5], "multi-prefix") != 0) { want_cap ? strcat (buffer, " multi-prefix") : strcpy (buffer, "CAP REQ :multi-prefix"); want_cap = 1; } /* if the SASL password is set, request SASL auth */ if (strstr (word_eol[5], "sasl") != 0 && strlen (sess->server->saslpassword) != 0) { want_cap ? strcat (buffer, " sasl") : strcpy (buffer, "CAP REQ :sasl"); want_sasl = 1; } if (want_cap) { /* buffer + 9 = emit buffer without "CAP REQ :" */ EMIT_SIGNAL (XP_TE_CAPREQ, sess->server->server_session, buffer + 9, NULL, NULL, NULL, 0); tcp_sendf (serv, "%s\r\n", buffer); } if (!want_sasl) { /* if we use SASL, CAP END is dealt via raw numerics */ tcp_send_len (serv, "CAP END\r\n", 9); } } else if (strncasecmp (word[4], "NAK", 3) == 0) { tcp_send_len (serv, "CAP END\r\n", 9); } return; } } garbage: /* unknown message */ PrintTextf (sess, "GARBAGE: %s\n", word_eol[1]); }
int chanopt_command (session *sess, char *tbuf, char *word[], char *word_eol[]) { int dots, i = 0, j, p = 0; guint8 val; int offset = 2; char *find; gboolean quiet = FALSE; int newval = -1; if (!strcmp (word[2], "-quiet")) { quiet = TRUE; offset++; } find = word[offset++]; if (word[offset][0]) { if (!g_ascii_strcasecmp (word[offset], "ON")) newval = 1; else if (!g_ascii_strcasecmp (word[offset], "OFF")) newval = 0; else if (word[offset][0] == 'u') newval = SET_DEFAULT; else newval = atoi (word[offset]); } if (!quiet) PrintTextf (sess, "\002Network\002: %s \002Channel\002: %s\n", sess->server->network ? server_get_network (sess->server, TRUE) : _("<none>"), sess->channel[0] ? sess->channel : _("<none>")); while (i < sizeof (chanopt) / sizeof (channel_options)) { if (find[0] == 0 || match (find, chanopt[i].name) || (chanopt[i].alias && match (find, chanopt[i].alias))) { if (newval != -1) /* set new value */ { *(guint8 *)G_STRUCT_MEMBER_P(sess, chanopt[i].offset) = newval; } if (!quiet) /* print value */ { strcpy (tbuf, chanopt[i].name); p = strlen (tbuf); tbuf[p++] = 3; tbuf[p++] = '2'; dots = 20 - strlen (chanopt[i].name); for (j = 0; j < dots; j++) tbuf[p++] = '.'; tbuf[p++] = 0; val = G_STRUCT_MEMBER (guint8, sess, chanopt[i].offset); PrintTextf (sess, "%s\0033:\017 %s", tbuf, chanopt_value (val)); } } i++; } return TRUE; }
int cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { int wild = FALSE; int or = FALSE; int off = FALSE; int quiet = FALSE; int erase = FALSE; int i = 0, finds = 0, found; int idx = 2; char *var, *val; if (strcasecmp (word[2], "-e") == 0) { idx++; erase = TRUE; } /* turn a bit OFF */ if (strcasecmp (word[idx], "-off") == 0) { idx++; off = TRUE; } /* turn a bit ON */ if (strcasecmp (word[idx], "-or") == 0 || strcasecmp (word[idx], "-on") == 0) { idx++; or = TRUE; } if (strcasecmp (word[idx], "-quiet") == 0) { idx++; quiet = TRUE; } var = word[idx]; val = word_eol[idx+1]; if (!*var) { set_list (sess, tbuf); return TRUE; } if ((strchr (var, '*') || strchr (var, '?')) && !*val) wild = TRUE; if (*val == '=') val++; do { if (wild) found = !match (var, vars[i].name); else found = strcasecmp (var, vars[i].name); if (found == 0) { finds++; switch (vars[i].type) { case TYPE_STR: if (erase || *val) { strncpy ((char *) &prefs + vars[i].offset, val, vars[i].len); ((char *) &prefs)[vars[i].offset + vars[i].len - 1] = 0; if (!quiet) PrintTextf (sess, "%s set to: %s\n", var, (char *) &prefs + vars[i].offset); } else { set_showval (sess, &vars[i], tbuf); } break; case TYPE_INT: case TYPE_BOOL: if (*val) { if (vars[i].type == TYPE_BOOL) { if (atoi (val)) *((int *) &prefs + vars[i].offset) = 1; else *((int *) &prefs + vars[i].offset) = 0; if (!strcasecmp (val, "YES") || !strcasecmp (val, "ON")) *((int *) &prefs + vars[i].offset) = 1; if (!strcasecmp (val, "NO") || !strcasecmp (val, "OFF")) *((int *) &prefs + vars[i].offset) = 0; } else { if (or) *((int *) &prefs + vars[i].offset) |= atoi (val); else if (off) *((int *) &prefs + vars[i].offset) &= ~(atoi (val)); else *((int *) &prefs + vars[i].offset) = atoi (val); } if (!quiet) PrintTextf (sess, "%s set to: %d\n", var, *((int *) &prefs + vars[i].offset)); } else { set_showval (sess, &vars[i], tbuf); } break; } } i++; } while (vars[i].name); if (!finds && !quiet) PrintText (sess, "No such variable.\n"); return TRUE; }