static gboolean do_login(PurpleConnection *gc) { char *buf, *tmp = NULL; char hostname[256]; const char *username, *realname; struct irc_conn *irc = gc->proto_data; const char *pass = purple_connection_get_password(gc); if (pass && *pass) { buf = irc_format(irc, "vv", "PASS", pass); if (irc_send(irc, buf) < 0) { /* purple_connection_error(gc, "Error sending password"); */ g_free(buf); return FALSE; } g_free(buf); } gethostname(hostname, sizeof(hostname)); hostname[sizeof(hostname) - 1] = '\0'; realname = purple_account_get_string(irc->account, "realname", ""); username = purple_account_get_string(irc->account, "username", ""); if (username == NULL || *username == '\0') { username = g_get_user_name(); } if (username != NULL && strchr(username, ' ') != NULL) { tmp = g_strdup(username); while ((buf = strchr(tmp, ' ')) != NULL) { *buf = '_'; } } buf = irc_format(irc, "vvvv:", "USER", tmp ? tmp : username, hostname, irc->server, strlen(realname) ? realname : IRC_DEFAULT_ALIAS); g_free(tmp); if (irc_send(irc, buf) < 0) { /* purple_connection_error(gc, "Error registering with server");*/ g_free(buf); return FALSE; } g_free(buf); buf = irc_format(irc, "vn", "NICK", purple_connection_get_display_name(gc)); if (irc_send(irc, buf) < 0) { /* purple_connection_error(gc, "Error sending nickname");*/ g_free(buf); return FALSE; } g_free(buf); irc->recv_time = time(NULL); return TRUE; }
char *irc_parse_ctcp(struct irc_conn *irc, const char *from, const char *to, const char *msg, int notice) { PurpleConnection *gc; const char *cur = msg + 1; char *buf, *ctcp; time_t timestamp; /* Note that this is NOT correct w.r.t. multiple CTCPs in one * message and low-level quoting ... but if you want that crap, * use a real IRC client. */ if (msg[0] != '\001' || msg[strlen(msg) - 1] != '\001') return g_strdup(msg); if (!strncmp(cur, "ACTION ", 7)) { cur += 7; buf = g_strdup_printf("/me %s", cur); buf[strlen(buf) - 1] = '\0'; return buf; } else if (!strncmp(cur, "PING ", 5)) { if (notice) { /* reply */ /* TODO: Should this read in the timestamp as a double? */ sscanf(cur, "PING %lu", ×tamp); gc = purple_account_get_connection(irc->account); if (!gc) return NULL; buf = g_strdup_printf(_("Reply time from %s: %lu seconds"), from, time(NULL) - timestamp); purple_notify_info(gc, _("PONG"), _("CTCP PING reply"), buf); g_free(buf); return NULL; } else { buf = irc_format(irc, "vt:", "NOTICE", from, msg); irc_send(irc, buf); g_free(buf); } } else if (!strncmp(cur, "VERSION", 7) && !notice) { buf = irc_format(irc, "vt:", "NOTICE", from, "\001VERSION Purple IRC\001"); irc_send(irc, buf); g_free(buf); } else if (!strncmp(cur, "DCC SEND ", 9)) { irc_dccsend_recv(irc, from, msg + 10); return NULL; } ctcp = g_strdup(msg + 1); ctcp[strlen(ctcp) - 1] = '\0'; buf = g_strdup_printf("Received CTCP '%s' (to %s) from %s", ctcp, to, from); g_free(ctcp); return buf; }
static PurpleRoomlist *irc_roomlist_get_list(PurpleConnection *gc) { struct irc_conn *irc; GList *fields = NULL; PurpleRoomlistField *f; char *buf; irc = gc->proto_data; if (irc->roomlist) purple_roomlist_unref(irc->roomlist); irc->roomlist = purple_roomlist_new(purple_connection_get_account(gc)); f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "channel", TRUE); fields = g_list_append(fields, f); f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT, _("Users"), "users", FALSE); fields = g_list_append(fields, f); f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Topic"), "topic", FALSE); fields = g_list_append(fields, f); purple_roomlist_set_fields(irc->roomlist, fields); buf = irc_format(irc, "v", "LIST"); irc_send(irc, buf); g_free(buf); return irc->roomlist; }
void irc_buddy_query(struct irc_conn *irc) { GList *lp; GString *string; struct irc_buddy *ib; char *buf; string = g_string_sized_new(512); while ((lp = g_list_first(irc->buddies_outstanding))) { ib = (struct irc_buddy *)lp->data; if (string->len + strlen(ib->name) + 1 > 450) break; g_string_append_printf(string, "%s ", ib->name); ib->new_online_status = FALSE; irc->buddies_outstanding = g_list_remove_link(irc->buddies_outstanding, lp); } if (string->len) { buf = irc_format(irc, "vn", "ISON", string->str); irc_send(irc, buf); g_free(buf); irc->ison_outstanding = TRUE; } else irc->ison_outstanding = FALSE; g_string_free(string, TRUE); }
int irc_cmd_away(struct irc_conn *irc, const char *cmd, const char *target, const char **args) { char *buf, *message; if (args[0] && strcmp(cmd, "back")) { message = purple_markup_strip_html(args[0]); purple_util_chrreplace(message, '\n', ' '); buf = irc_format(irc, "v:", "AWAY", message); g_free(message); } else { buf = irc_format(irc, "v", "AWAY"); } irc_send(irc, buf); g_free(buf); return 0; }
static void irc_ison_one(struct irc_conn *irc, struct irc_buddy *ib) { char *buf; ib->flag = FALSE; buf = irc_format(irc, "vn", "ISON", ib->name); irc_send(irc, buf); g_free(buf); }
void irc_msg_ping(struct irc_conn *irc, const char *name, const char *from, char **args) { char *buf; if (!args || !args[0]) return; buf = irc_format(irc, "v:", "PONG", args[0]); irc_send(irc, buf); g_free(buf); }
static gboolean do_login(GaimConnection *gc) { char *buf; char hostname[256]; const char *username, *realname; struct irc_conn *irc = gc->proto_data; const char *pass = gaim_connection_get_password(gc); if (pass && *pass) { buf = irc_format(irc, "vv", "PASS", pass); if (irc_send(irc, buf) < 0) { /* gaim_connection_error(gc, "Error sending password"); */ g_free(buf); return FALSE; } g_free(buf); } gethostname(hostname, sizeof(hostname)); hostname[sizeof(hostname) - 1] = '\0'; username = gaim_account_get_string(irc->account, "username", ""); realname = gaim_account_get_string(irc->account, "realname", ""); buf = irc_format(irc, "vvvv:", "USER", strlen(username) ? username : g_get_user_name(), hostname, irc->server, strlen(realname) ? realname : IRC_DEFAULT_ALIAS); if (irc_send(irc, buf) < 0) { /* gaim_connection_error(gc, "Error registering with server");*/ g_free(buf); return FALSE; } g_free(buf); buf = irc_format(irc, "vn", "NICK", gaim_connection_get_display_name(gc)); if (irc_send(irc, buf) < 0) { /* gaim_connection_error(gc, "Error sending nickname");*/ g_free(buf); return FALSE; } g_free(buf); irc->recv_time = time(NULL); return TRUE; }
static void irc_ison_one(struct irc_conn *irc, struct irc_buddy *ib) { char *buf; if (irc->buddies_outstanding != NULL) { irc->buddies_outstanding = g_list_append(irc->buddies_outstanding, ib); return; } ib->new_online_status = FALSE; buf = irc_format(irc, "vn", "ISON", ib->name); irc_send(irc, buf); g_free(buf); }
static void irc_chat_set_topic(PurpleConnection *gc, int id, const char *topic) { char *buf; const char *name = NULL; struct irc_conn *irc; irc = gc->proto_data; name = purple_conversation_get_name(purple_find_chat(gc, id)); if (name == NULL) return; buf = irc_format(irc, "vt:", "TOPIC", name, topic); irc_send(irc, buf); g_free(buf); }
void irc_msg_nickused(struct irc_conn *irc, const char *name, const char *from, char **args) { char *newnick, *buf, *end; PurpleConnection *gc = purple_account_get_connection(irc->account); if (!args || !args[1]) return; if (gc && purple_connection_get_state(gc) == PURPLE_CONNECTED) { /* We only want to do the following dance if the connection has not been successfully completed. If it has, just notify the user that their /nick command didn't go. */ buf = g_strdup_printf("The nickname \"%s\" is already being used.", irc->reqnick); purple_notify_error(gc, "Nickname in use", "Nickname in use", buf); g_free(buf); g_free(irc->reqnick); irc->reqnick = NULL; return; } if (strlen(args[1]) < strlen(irc->reqnick) || irc->nickused) newnick = g_strdup(args[1]); else newnick = g_strdup_printf("%s0", args[1]); end = newnick + strlen(newnick) - 1; /* try fallbacks */ if((*end < '9') && (*end >= '1')) { *end = *end + 1; } else *end = '1'; g_free(irc->reqnick); irc->reqnick = newnick; irc->nickused = TRUE; purple_connection_set_display_name( purple_account_get_connection(irc->account), newnick); buf = irc_format(irc, "vn", "NICK", newnick); irc_send(irc, buf); g_free(buf); }
/* XXX I don't like messing directly with these buddies */ gboolean irc_blist_timeout(struct irc_conn *irc) { GString *string = g_string_sized_new(512); char *list, *buf; g_hash_table_foreach(irc->buddies, (GHFunc)irc_buddy_append, (gpointer)string); list = g_string_free(string, FALSE); if (!list || !strlen(list)) { g_free(list); return TRUE; } buf = irc_format(irc, "vn", "ISON", list); g_free(list); irc_send(irc, buf); g_free(buf); return TRUE; }
int irc_cmd_ctcp(struct irc_conn *irc, const char *cmd, const char *target, const char **args) { /* we have defined args as args[0] is target and args[1] is ctcp command */ char *buf; GString *string; /* check if we have args */ if (!args || !args[0] || !args[1]) return 0; /* TODO:strip newlines or send each line as separate ctcp or something * actually, this shouldn't be done here but somewhere else since irc should support escaping newlines */ string = g_string_new(args[1]); g_string_prepend_c (string,'\001'); g_string_append_c (string,'\001'); buf = irc_format(irc, "vn:", "PRIVMSG", args[0], string->str); g_string_free(string,TRUE); irc_send(irc, buf); g_free(buf); return 1; }
void irc_parse_msg(struct irc_conn *irc, char *input) { struct _irc_msg *msgent; char *cur, *end, *tmp, *from, *msgname, *fmt, **args, *msg; guint i; PurpleConnection *gc = purple_account_get_connection(irc->account); irc->recv_time = time(NULL); /* * The data passed to irc-receiving-text is the raw protocol data. * TODO: It should be passed as an array of bytes and a length * instead of a null terminated string. */ purple_signal_emit(_irc_plugin, "irc-receiving-text", gc, &input); if (!strncmp(input, "PING ", 5)) { msg = irc_format(irc, "vv", "PONG", input + 5); irc_send(irc, msg); g_free(msg); return; } else if (!strncmp(input, "ERROR ", 6)) { if (g_utf8_validate(input, -1, NULL)) { char *tmp = g_strdup_printf("%s\n%s", _("Disconnected."), input); purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); } else purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Disconnected.")); return; } if (input[0] != ':' || (cur = strchr(input, ' ')) == NULL) { irc_parse_error_cb(irc, input); return; } from = g_strndup(&input[1], cur - &input[1]); cur++; end = strchr(cur, ' '); if (!end) end = cur + strlen(cur); tmp = g_strndup(cur, end - cur); msgname = g_ascii_strdown(tmp, -1); g_free(tmp); if ((msgent = g_hash_table_lookup(irc->msgs, msgname)) == NULL) { irc_msg_default(irc, "", from, &input); g_free(msgname); g_free(from); return; } g_free(msgname); args = g_new0(char *, strlen(msgent->format)); for (cur = end, fmt = msgent->format, i = 0; fmt[i] && *cur++; i++) { switch (fmt[i]) { case 'v': if (!(end = strchr(cur, ' '))) end = cur + strlen(cur); args[i] = g_strndup(cur, end - cur); cur += end - cur; break; case 't': case 'n': case 'c': if (!(end = strchr(cur, ' '))) end = cur + strlen(cur); tmp = g_strndup(cur, end - cur); args[i] = irc_recv_convert(irc, tmp); g_free(tmp); cur += end - cur; break; case ':': if (*cur == ':') cur++; args[i] = irc_recv_convert(irc, cur); cur = cur + strlen(cur); break; case '*': args[i] = g_strdup(cur); cur = cur + strlen(cur); break; default: purple_debug(PURPLE_DEBUG_ERROR, "irc", "invalid message format character '%c'\n", fmt[i]); break; } } tmp = irc_recv_convert(irc, from); (msgent->cb)(irc, msgent->name, tmp, args); g_free(tmp); for (i = 0; i < strlen(msgent->format); i++) { g_free(args[i]); } g_free(args); g_free(from); }
static gboolean do_login(PurpleConnection *gc) { char *buf, *tmp = NULL; char *server; const char *nickname, *identname, *realname; struct irc_conn *irc = gc->proto_data; const char *pass = purple_connection_get_password(gc); #ifdef HAVE_CYRUS_SASL const gboolean use_sasl = purple_account_get_bool(irc->account, "sasl", FALSE); #endif if (pass && *pass) { #ifdef HAVE_CYRUS_SASL if (use_sasl) buf = irc_format(irc, "vv:", "CAP", "REQ", "sasl"); else /* intended to fall through */ #endif buf = irc_format(irc, "v:", "PASS", pass); if (irc_send(irc, buf) < 0) { g_free(buf); return FALSE; } g_free(buf); } realname = purple_account_get_string(irc->account, "realname", ""); identname = purple_account_get_string(irc->account, "username", ""); if (identname == NULL || *identname == '\0') { identname = g_get_user_name(); } if (identname != NULL && strchr(identname, ' ') != NULL) { tmp = g_strdup(identname); while ((buf = strchr(tmp, ' ')) != NULL) { *buf = '_'; } } if (*irc->server == ':') { /* Same as hostname, above. */ server = g_strdup_printf("0%s", irc->server); } else { server = g_strdup(irc->server); } buf = irc_format(irc, "vvvv:", "USER", tmp ? tmp : identname, "*", server, strlen(realname) ? realname : IRC_DEFAULT_ALIAS); g_free(tmp); g_free(server); if (irc_send(irc, buf) < 0) { g_free(buf); return FALSE; } g_free(buf); nickname = purple_connection_get_display_name(gc); buf = irc_format(irc, "vn", "NICK", nickname); irc->reqnick = g_strdup(nickname); irc->nickused = FALSE; if (irc_send(irc, buf) < 0) { g_free(buf); return FALSE; } g_free(buf); irc->recv_time = time(NULL); return TRUE; }