static TIMER(irc_autorejoin_timer) { irc_onkick_handler_t *d = data; if (type == 1) { xfree(d->nick); xfree(d->kickedby); xfree(d->chan); xfree(d); return 0; } debug_white("irc_autorejoin_timer() rejoining to: %s\n", d->chan); irc_autorejoin(d->s, IRC_REJOIN_KICK, (d->chan)+4); return -1; }
void debug_function(struct board *board) { clrscr(); switch(board->turn) { case WHITE: debug_black(board); break; case BLACK: debug_white(board); break; } }
static int check_replyreq(session_t *s, unsigned char **buf, int *len, int *type) { struct { uint16_t type; uint16_t len; } tlv; struct { uint16_t len; uint32_t uid; uint16_t type; uint16_t id; } pkt; if (!icq_unpack(*buf, buf, len, "WW", &tlv.type, &tlv.len) || (tlv.type != 0x0001) || (tlv.len < 10)) { debug_error("check_replyreq() broken(1)\n"); return 0; } if (*len!=tlv.len) { debug_error("icq_snac_extension_replyreq() broken(1,5)\n"); return 0; } if (!icq_unpack(*buf, buf, len, "wiwW", &pkt.len, &pkt.uid, &pkt.type, &pkt.id)) { debug_error("icq_snac_extension_replyreq() broken(2)\n"); return 0; } debug_white("icq_snac_extension_replyreq() uid=%d type=%.4x (len=%d, len2=%d)\n", pkt.uid, pkt.type, *len, pkt.len); if (xstrcmp(s->uid+4, itoa(pkt.uid))) { debug_error("icq_snac_extension_replyreq() 1919 UIN mismatch: %s vs %ld.\n", s->uid+4, pkt.uid); return 0; } if (tlv.len - 2 != pkt.len) { debug("icq_snac_extension_replyreq() 1743 Size mismatch in packet lengths.\n"); return 0; } *type = pkt.type; return 1; }
static int icq_meta_info_reply(session_t *s, unsigned char *buf, int len, private_data_t **info, int show) { /* SNAC(15,03)/07DA SRV_META_INFO_REPLY Meta information response * * This is the server response to client meta info request SNAC(15,02)/07D0. */ struct { uint16_t subtype; uint8_t result; unsigned char *data; } pkt; int userinfo = 0; metasnac_subhandler_t handler; if (!ICQ_UNPACK(&pkt.data, "wc", &pkt.subtype, &pkt.result)) { debug_error("icq_meta_info_reply() broken\n"); return -1; } debug_white("icq_meta_info_reply() subtype=%.4x result=%.2x (len=%d)\n", pkt.subtype, pkt.result, len); if ( (handler = get_userinfo_extension_handler(pkt.subtype)) ) { userinfo = 1; } else { switch (pkt.subtype) { /* search */ case SRV_LAST_USER_FOUND: handler = icq_snac_extension_userfound_last; break; case SRV_USER_FOUND: handler = icq_snac_extension_userfound; break; case META_SET_FULLINFO_ACK: handler = icq_snac_extension_fullinfo_ack; break; case SRV_RANDOM_FOUND: handler = NULL; break; /* XXX, SRV_RANDOM_FOUND */ default: handler = NULL; } } __displayed = 0; if (!handler) { debug_error("icq_meta_info_reply() ignored: %.4x\n", pkt.subtype); icq_hexdump(DEBUG_ERROR, pkt.data, len); return 0; } else { int uid = info ? private_item_get_int(info, "uid") : -1; debug_function("icq_snac_extensions_%s()", icq_lookuptable(meta_name, pkt.subtype)); if (userinfo) debug_function(" uid: %u", uid); debug_function("\n"); if (pkt.result == 0x0A) { handler(s, pkt.data, len, info); } else if (!userinfo){ /* Failed search */ debug_error("icq_snac_extension_userfound() search error: %u\n", pkt.result); } if (show) { __display_info(s, pkt.subtype, *info); if (__displayed) print("icq_userinfo_end", session_name(s), itoa(uid)); } } return 0; }
static int icq_snac_extension_userfound_common(session_t *s, unsigned char *buf, int len, int islast) { char *nickname = NULL; char *first_name = NULL; char *last_name = NULL; char *email = NULL; char *full_name; char *temp; const char *__age = NULL; const char *__gender = ""; char *__active; uint32_t uin; uint16_t len2; uint16_t status, age; uint8_t auth, gender; /* XXX, sprawdzic czy mamy cookie. */ if (!ICQ_UNPACK(&buf, "w", &len2)) return -1; if (len < len2) return -1; if (!ICQ_UNPACK(&buf, "i", &uin)) return -1; if (!ICQ_UNPACK(&buf, "S", &temp)) goto cleanup; nickname = xstrdup(temp); if (!ICQ_UNPACK(&buf, "S", &temp)) goto cleanup; first_name = xstrdup(temp); if (!ICQ_UNPACK(&buf, "S", &temp)) goto cleanup; last_name = xstrdup(temp); if (!ICQ_UNPACK(&buf, "S", &temp)) goto cleanup; email = xstrdup(temp); if (first_name[0] && last_name[0]) full_name = saprintf("%s %s", first_name, last_name); else full_name = xstrdup(first_name[0] ? first_name : last_name); if (ICQ_UNPACK(&buf, "cwcw", &auth, &status, &gender, &age)) { if (age) __age = itoa(age); // XXX calculate birthyear? if (gender) __gender = (gender==2) ? "m" : "f"; } else { debug_error("icq_snac_extension_userfound_common() broken\n"); auth = status = gender = age = 0; } /* XXX, "search_results_multi", "search_results_single" */ /* XXX, instead of email we had city */ /* XXX, some time ago i was thinking to of function which * if data was truncated [because of width in format] * it'd take another line to complete.. * * i don't like truncation of data for instance: * 08:17:12 97320776 | darkjames | Jakub Zawadz | - | darkjames@po * * i was thinking about: * 97320776 | darkjames | Jakub Zawwdz | - | darkjames@po * ki czta.onet.pl * * of course we can do more magic, and wrap... * Jakub * Zawadzki * * or maybe let's align to center? :) * Jakub * Zawadzki */ { const char *fvalue; /* XXX ?wo? new formats for icq status * status (0 - offline, 1 - online, 2 - non_webaware) */ switch (status) { case 0: fvalue = format_find("search_results_multi_notavail"); break; case 1: fvalue = format_find("search_results_multi_avail"); break; default: fvalue = format_find("search_results_multi_unknown"); break; } temp = format_string(fvalue); /* XXX ?wo? add format for "auth" */ __active = saprintf("%s %s", temp, auth ? " " : "A"); xfree(temp); } print_info(NULL, s, "search_results_multi", itoa(uin), full_name, nickname, email, __age ? __age : ("-"), __gender, __active); xfree(__active); xfree(full_name); if (islast && len>=4) { uint32_t omit; ICQ_UNPACK(&buf, "I", &omit); debug_warn("icq_snac_extension_userfound_last() Bulshit warning!\n"); debug_white("icq_snac_extension_userfound_last() %d search results omitted\n", omit); } icq_hexdump(DEBUG_WHITE, buf, len); xfree(nickname); xfree(first_name); xfree(last_name); xfree(email); return 0; cleanup: xfree(nickname); xfree(first_name); xfree(last_name); xfree(email); return -1; }
static void icq_get_user_info(session_t *s, userlist_t *u, struct icq_tlv_list *tlvs, int newstatus) { int caps = 0, desc_chg = 0; char *descr = NULL; icq_tlv_t *t; if (!u) return; debug_function("icq_get_user_info() %s\n", u->uid); descr = u->descr ? xstrdup(u->descr) : NULL; user_private_item_set_int(u, "idle", 0); user_private_item_set_int(u, "status_f", 0); user_private_item_set_int(u, "xstatus", 0); for (t = tlvs; t; t = t->next) { /* Check t->len */ switch (t->type) { case 0x01: if (tlv_length_check("icq_get_user_info()", t, 2)) continue; break; case 0x03: case 0x04: case 0x05: case 0x06: case 0x0a: case 0x0f: if (tlv_length_check("icq_get_user_info()", t, 4)) continue; break; } /* now we've got trusted length */ switch (t->type) { case 0x01: /* User class */ user_private_item_set_int(u, "class", t->nr); break; case 0x03: /* Time when client gone online (unix time_t) */ user_private_item_set_int(u, "online", t->nr); break; case 0x04: /* idle timer */ { uint16_t idle; if ( (idle = t->nr) ) user_private_item_set_int(u, "idle", time(NULL) - 60*idle); break; } case 0x05: /* Time when this account was registered (unix time_t) */ user_private_item_set_int(u, "member", t->nr); break; case 0x06: { /* User status * * ICQ service presence notifications use user status field which consist * of two parts. First is a various flags (birthday flag, webaware flag, * etc). Second is a user status (online, away, busy, etc) flags. */ uint16_t status = t->nr & 0xffff; uint16_t flags = t->nr >> 16; user_private_item_set_int(u, "status_f", flags); debug_white(" %s status flags=0x%04x status=0x%04x\n", u->uid, flags, status); newstatus = icq2ekg_status(status); break; } case 0x0a: /* IP address */ { uint32_t ip; if (icq_unpack_nc(t->buf, t->len, "i", &ip)) { if (ip) user_private_item_set_int(u, "ip", ip); } break; } case 0x0c: /* DC info */ { struct { uint32_t ip; uint32_t port; uint8_t tcp_flag; uint16_t version; uint32_t conn_cookie; uint32_t web_port; uint32_t client_features; /* faked time signatures, used to identify clients */ uint32_t ts1; uint32_t ts2; uint32_t ts3; uint16_t junk; } tlv_c; if (!icq_unpack_nc(t->buf, t->len, "IICWIII", &tlv_c.ip, &tlv_c.port, &tlv_c.tcp_flag, &tlv_c.version, &tlv_c.conn_cookie, &tlv_c.web_port, &tlv_c.client_features)) { debug_error(" %s TLV(C) corrupted?\n", u->uid); continue; } else { user_private_item_set_int(u, "dcc.ip", tlv_c.ip); user_private_item_set_int(u, "dcc.port", tlv_c.port); user_private_item_set_int(u, "dcc.flag", tlv_c.tcp_flag); user_private_item_set_int(u, "version", tlv_c.version); user_private_item_set_int(u, "dcc.cookie", tlv_c.conn_cookie); user_private_item_set_int(u, "dcc.web_port", tlv_c.web_port); // ?wo? do we need it? if (t->len >= 12 && icq_unpack_nc(t->buf, t->len, "23 III", &tlv_c.ts1, &tlv_c.ts3, &tlv_c.ts3)) ; } break; } case 0x0d: /* Client capabilities list */ { unsigned char *data = t->buf; int d_len = t->len; if (tlv_length_check("icq_get_user_info()", t, t->len & ~0xF)) break; while (d_len > 0) { int cid = icq_cap_id(data); if (cid != CAP_UNKNOWN) { caps |= 1 << cid; } else if ((cid = icq_xstatus_id(data))) { user_private_item_set_int(u, "xstatus", cid); } else { /* ?wo? client id???*/ debug_error("Unknown cap\n"); icq_hexdump(DEBUG_ERROR, data, 0x10); } data += 0x10; // capability length d_len -= 0x10; } break; } case 0x0e: /* AOL users. No values */ break; case 0x0f: case 0x10: /* Online time in seconds */ break; case 0x19: /* short caps */ { unsigned char *data = t->buf; int d_len = t->len; while (d_len > 0) { int cid = icq_short_cap_id(data); if (cid != CAP_UNKNOWN) { caps |= 1 << cid; } else { /* WTF? */ } data += 2; // short capability length d_len -= 2; } break; } case 0x1d: /* user icon id & hash */ { static char empty_item[0x10] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; unsigned char *t_data = t->buf; int t_len = t->len; while (t_len > 0) { uint16_t item_type; uint8_t item_flags; uint8_t item_len; if (!icq_unpack(t_data, &t_data, &t_len, "WCC", &item_type, &item_flags, &item_len)) { debug_error(" %s TLV(1D) corrupted?\n", u->uid); break; } /* just some validity check */ if (item_len > t_len) item_len = t_len; if ((item_type == 0x02) && (item_flags == 4)) { /* iChat online message */ if (item_len>4) { char *tmp; uint16_t enc; icq_unpack_nc(t_data, item_len, "Uw", &tmp, &enc); descr = !enc ? ekg_utf8_to_locale_dup(tmp) : xstrdup(tmp); } desc_chg = 1; } else if ((item_type == 0x0e) && (item_len>7)) { /* 000E: Custom Status (ICQ6) */ char *tmp = xstrndup((char *)t_data, item_len); if ( !xstrncmp(tmp, "icqmood", 7) && xisdigit(*(tmp+7)) ) { int xstatus = atoi(tmp+7) + 1; if (xstatus<=XSTATUS_COUNT) user_private_item_set_int(u, "xstatus", xstatus); } xfree(tmp); } else if (memcmp(t_data, empty_item, (item_len < 0x10) ? item_len : 0x10)) { /* Item types * 0000: AIM mini avatar * 0001: AIM/ICQ avatar ID/hash (len 5 or 16 bytes) * 0002: iChat online message * 0008: ICQ Flash avatar hash (16 bytes) * 0009: iTunes music store link * 000C: ICQ contact photo (16 bytes) * 000D: ? */ debug_white(" %s has got avatar: type: %d flags: %d\n", u->uid, item_type, item_flags); icq_hexdump(DEBUG_WHITE, t_data, item_len); /* XXX, display message, get? do something? */ } t_data += item_len; t_len -= item_len; } break; } default: if (t->len==4) debug_warn(" %s Unknown TLV(0x%x) len=4 v=%d (0x%x) (%s)\n", u->uid, t->type, t->nr, t->nr, t->nr?timestamp_time("%Y-%m-%d %H:%M:%S", t->nr):""); else debug_error(" %s Unknown TLV(0x%x) len=%d\n", u->uid, t->type, t->len); } } if (desc_chg || (newstatus != u->status)) { if (!descr && !desc_chg && u->descr) descr = xstrdup(u->descr); protocol_status_emit(s, u->uid, newstatus, descr, time(NULL)); } if (!desc_chg) { if (u->status == EKG_STATUS_NA) { icq_send_snac(s, 0x02, 0x05, NULL, NULL, /* Request user info */ "Ws", (uint32_t) 1, /* request type (1 - general info, 2 - short user info, 3 - away message, 4 - client capabilities) */ u->uid+4); } else { icq_get_description(s, u->uid+4, u->status); } } if (u->status == EKG_STATUS_NA) { user_private_item_set_int(u, "online", 0); user_private_item_set_int(u, "last_ip", user_private_item_get_int(u, "ip")); user_private_item_set_int(u, "ip", 0); if (user_private_item_get_int(u, "version") < 8) { caps &= ~(1<<CAP_SRV_RELAY); debug_warn("icq_snac_buddy_online() Forcing simple messages due to compatibility issues (%s).\n", u->uid); } } user_private_item_set_int(u, "caps", caps); user_private_item_set_int(u, "utf", (caps && (1<<CAP_UTF)) ? 1:0); xfree(descr); }