comparison src/protocols/oscar/oscar.c @ 2993:7239a392486c

[gaim-migrate @ 3006] 0.53 :) committer: Tailor Script <tailor@pidgin.im>
author Rob Flynn <gaim@robflynn.com>
date Sat, 02 Mar 2002 04:52:21 +0000
parents 9d11dbb33b6f
children 60018f862a51
comparison
equal deleted inserted replaced
2992:d16a0504f1c8 2993:7239a392486c
99 GSList *hasicons; 99 GSList *hasicons;
100 100
101 gboolean killme; 101 gboolean killme;
102 gboolean icq; 102 gboolean icq;
103 GSList *evilhack; 103 GSList *evilhack;
104
105 struct {
106 guint maxbuddies; /* max users you can watch */
107 guint maxwatchers; /* max users who can watch you */
108 guint maxpermits; /* max users on permit list */
109 guint maxdenies; /* max users on deny list */
110 guint maxsiglen; /* max size (bytes) of profile */
111 guint maxawaymsglen; /* max size (bytes) of posted away message */
112 } rights;
104 }; 113 };
105 114
106 struct create_room { 115 struct create_room {
107 char *name; 116 char *name;
108 int exchange; 117 int exchange;
242 static int conninitdone_bos (aim_session_t *, aim_frame_t *, ...); 251 static int conninitdone_bos (aim_session_t *, aim_frame_t *, ...);
243 static int conninitdone_admin (aim_session_t *, aim_frame_t *, ...); 252 static int conninitdone_admin (aim_session_t *, aim_frame_t *, ...);
244 static int conninitdone_chat (aim_session_t *, aim_frame_t *, ...); 253 static int conninitdone_chat (aim_session_t *, aim_frame_t *, ...);
245 static int conninitdone_chatnav (aim_session_t *, aim_frame_t *, ...); 254 static int conninitdone_chatnav (aim_session_t *, aim_frame_t *, ...);
246 static int gaim_parse_msgerr (aim_session_t *, aim_frame_t *, ...); 255 static int gaim_parse_msgerr (aim_session_t *, aim_frame_t *, ...);
256 static int gaim_parse_locaterights(aim_session_t *, aim_frame_t *, ...);
247 static int gaim_parse_buddyrights(aim_session_t *, aim_frame_t *, ...); 257 static int gaim_parse_buddyrights(aim_session_t *, aim_frame_t *, ...);
248 static int gaim_parse_locerr (aim_session_t *, aim_frame_t *, ...); 258 static int gaim_parse_locerr (aim_session_t *, aim_frame_t *, ...);
249 static int gaim_icbm_param_info (aim_session_t *, aim_frame_t *, ...); 259 static int gaim_icbm_param_info (aim_session_t *, aim_frame_t *, ...);
250 static int gaim_parse_genericerr (aim_session_t *, aim_frame_t *, ...); 260 static int gaim_parse_genericerr (aim_session_t *, aim_frame_t *, ...);
251 static int gaim_memrequest (aim_session_t *, aim_frame_t *, ...); 261 static int gaim_memrequest (aim_session_t *, aim_frame_t *, ...);
258 static int gaim_ssi_parselist (aim_session_t *, aim_frame_t *, ...); 268 static int gaim_ssi_parselist (aim_session_t *, aim_frame_t *, ...);
259 269
260 static int gaim_directim_initiate(aim_session_t *, aim_frame_t *, ...); 270 static int gaim_directim_initiate(aim_session_t *, aim_frame_t *, ...);
261 static int gaim_directim_incoming(aim_session_t *, aim_frame_t *, ...); 271 static int gaim_directim_incoming(aim_session_t *, aim_frame_t *, ...);
262 static int gaim_directim_typing (aim_session_t *, aim_frame_t *, ...); 272 static int gaim_directim_typing (aim_session_t *, aim_frame_t *, ...);
273 static int gaim_update_ui (aim_session_t *, aim_frame_t *, ...);
263 274
264 static char *msgerrreason[] = { 275 static char *msgerrreason[] = {
265 "Invalid error", 276 "Invalid error",
266 "Invalid SNAC", 277 "Invalid SNAC",
267 "Rate to host", 278 "Rate to host",
307 gaim_input_remove(dim->watcher); 318 gaim_input_remove(dim->watcher);
308 319
309 g_snprintf(buf, sizeof buf, _("Direct IM with %s closed"), sn); 320 g_snprintf(buf, sizeof buf, _("Direct IM with %s closed"), sn);
310 if ((cnv = find_conversation(sn))) 321 if ((cnv = find_conversation(sn)))
311 write_to_conv(cnv, buf, WFLAG_SYSTEM, NULL, time(NULL), -1); 322 write_to_conv(cnv, buf, WFLAG_SYSTEM, NULL, time(NULL), -1);
323 update_progress(cnv, 100);
312 324
313 g_free(dim); /* I guess? I don't see it anywhere else... -- mid */ 325 g_free(dim); /* I guess? I don't see it anywhere else... -- mid */
314 g_free(sn); 326 g_free(sn);
315 327
316 return; 328 return;
658 670
659 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_bos, 0); 671 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_bos, 0);
660 aim_conn_addhandler(sess, bosconn, 0x0009, 0x0003, gaim_bosrights, 0); 672 aim_conn_addhandler(sess, bosconn, 0x0009, 0x0003, gaim_bosrights, 0);
661 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0); 673 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0);
662 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT, gaim_handle_redirect, 0); 674 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT, gaim_handle_redirect, 0);
675 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_RIGHTSINFO, gaim_parse_locaterights, 0);
663 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_RIGHTSINFO, gaim_parse_buddyrights, 0); 676 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_RIGHTSINFO, gaim_parse_buddyrights, 0);
664 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING, gaim_parse_oncoming, 0); 677 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING, gaim_parse_oncoming, 0);
665 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING, gaim_parse_offgoing, 0); 678 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING, gaim_parse_offgoing, 0);
666 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, gaim_parse_incoming_im, 0); 679 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, gaim_parse_incoming_im, 0);
667 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, gaim_parse_locerr, 0); 680 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, gaim_parse_locerr, 0);
1106 g_free(host); 1119 g_free(host);
1107 return 1; 1120 return 1;
1108 } 1121 }
1109 1122
1110 static int gaim_parse_oncoming(aim_session_t *sess, aim_frame_t *fr, ...) { 1123 static int gaim_parse_oncoming(aim_session_t *sess, aim_frame_t *fr, ...) {
1111 aim_userinfo_t *info;
1112 time_t time_idle;
1113 int type = 0;
1114 struct gaim_connection *gc = sess->aux_data; 1124 struct gaim_connection *gc = sess->aux_data;
1115 struct oscar_data *od = gc->proto_data; 1125 struct oscar_data *od = gc->proto_data;
1126 aim_userinfo_t *info;
1127 time_t time_idle = 0, signon = 0;
1128 int type = 0;
1129 int caps = 0;
1116 char *tmp; 1130 char *tmp;
1117 int caps;
1118 1131
1119 va_list ap; 1132 va_list ap;
1120 va_start(ap, fr); 1133 va_start(ap, fr);
1121 info = va_arg(ap, aim_userinfo_t *); 1134 info = va_arg(ap, aim_userinfo_t *);
1122 va_end(ap); 1135 va_end(ap);
1123 1136
1124 caps = info->capabilities; 1137 if (info->present & AIM_USERINFO_PRESENT_CAPABILITIES)
1125 1138 caps = info->capabilities;
1126 if (!od->icq) { 1139
1140 if (!od->icq && (info->present & AIM_USERINFO_PRESENT_FLAGS)) {
1127 if (info->flags & AIM_FLAG_ACTIVEBUDDY) 1141 if (info->flags & AIM_FLAG_ACTIVEBUDDY)
1128 type |= UC_AB; 1142 type |= UC_AB;
1129 if (info->flags & AIM_FLAG_UNCONFIRMED) 1143 if (info->flags & AIM_FLAG_UNCONFIRMED)
1130 type |= UC_UNCONFIRMED; 1144 type |= UC_UNCONFIRMED;
1131 if (info->flags & AIM_FLAG_ADMINISTRATOR) 1145 if (info->flags & AIM_FLAG_ADMINISTRATOR)
1134 type |= UC_AOL; 1148 type |= UC_AOL;
1135 if (info->flags & AIM_FLAG_FREE) 1149 if (info->flags & AIM_FLAG_FREE)
1136 type |= UC_NORMAL; 1150 type |= UC_NORMAL;
1137 if (info->flags & AIM_FLAG_AWAY) 1151 if (info->flags & AIM_FLAG_AWAY)
1138 type |= UC_UNAVAILABLE; 1152 type |= UC_UNAVAILABLE;
1139 } else { 1153 }
1140 if (info->icqinfo.status) { 1154
1141 type = (info->icqinfo.status << 6); 1155 if (info->present & AIM_USERINFO_PRESENT_ICQEXTSTATUS) {
1142 if (!(info->icqinfo.status & AIM_ICQ_STATE_CHAT)) 1156 type = (info->icqinfo.status << 6);
1143 type |= UC_UNAVAILABLE; 1157 if (!(info->icqinfo.status & AIM_ICQ_STATE_CHAT))
1144 } 1158 type |= UC_UNAVAILABLE;
1145 if (caps & AIM_CAPS_ICQ) 1159 }
1146 caps ^= AIM_CAPS_ICQ; 1160
1147 debug_printf("icq status: %d\n", info->icqinfo.status); 1161 if (caps & AIM_CAPS_ICQ)
1148 } 1162 caps ^= AIM_CAPS_ICQ;
1149 1163
1150 if (info->idletime) { 1164 if (info->present & AIM_USERINFO_PRESENT_IDLE) {
1151 time(&time_idle); 1165 time(&time_idle);
1152 time_idle -= info->idletime*60; 1166 time_idle -= info->idletime*60;
1153 } else 1167 }
1154 time_idle = 0; 1168
1169 if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN)
1170 signon = time(NULL) - info->sessionlen;
1155 1171
1156 tmp = g_strdup(normalize(gc->username)); 1172 tmp = g_strdup(normalize(gc->username));
1157 if (!strcmp(tmp, normalize(info->sn))) 1173 if (!strcmp(tmp, normalize(info->sn)))
1158 g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", info->sn); 1174 g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", info->sn);
1159 g_free(tmp); 1175 g_free(tmp);
1160 1176
1161 serv_got_update(gc, info->sn, 1, info->warnlevel/10, time(NULL) - info->sessionlen, 1177 serv_got_update(gc, info->sn, 1, info->warnlevel/10, signon,
1162 time_idle, type, caps); 1178 time_idle, type, caps);
1163 1179
1164 return 1; 1180 return 1;
1165 } 1181 }
1166 1182
1244 1260
1245 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, 1261 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING,
1246 gaim_directim_incoming, 0); 1262 gaim_directim_incoming, 0);
1247 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, 1263 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING,
1248 gaim_directim_typing, 0); 1264 gaim_directim_typing, 0);
1249 1265 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DOWNLOADIMAGE,
1266 gaim_update_ui, 0);
1250 for (i = 0; i < (int)strlen(d->ip); i++) { 1267 for (i = 0; i < (int)strlen(d->ip); i++) {
1251 if (d->ip[i] == ':') { 1268 if (d->ip[i] == ':') {
1252 port = atoi(&(d->ip[i+1])); 1269 port = atoi(&(d->ip[i+1]));
1253 break; 1270 break;
1254 } 1271 }
1666 struct gaim_connection *gc = sess->aux_data; 1683 struct gaim_connection *gc = sess->aux_data;
1667 struct oscar_data *od = gc->proto_data; 1684 struct oscar_data *od = gc->proto_data;
1668 GSList *l = od->evilhack; 1685 GSList *l = od->evilhack;
1669 gboolean evilhack = FALSE; 1686 gboolean evilhack = FALSE;
1670 va_list ap; 1687 va_list ap;
1671 char *asc; 1688 gchar *membersince = NULL, *onlinesince = NULL, *idle = NULL;
1672 1689
1673 va_start(ap, fr); 1690 va_start(ap, fr);
1674 info = va_arg(ap, aim_userinfo_t *); 1691 info = va_arg(ap, aim_userinfo_t *);
1675 infotype = (fu16_t)va_arg(ap, unsigned int); 1692 infotype = (fu16_t)va_arg(ap, unsigned int);
1676 prof_enc = va_arg(ap, char *); 1693 prof_enc = va_arg(ap, char *);
1683 "<IMG SRC=\"aol_icon.gif\"> : AOL User <br>" 1700 "<IMG SRC=\"aol_icon.gif\"> : AOL User <br>"
1684 "<IMG SRC=\"dt_icon.gif\"> : Trial AIM User <br>" 1701 "<IMG SRC=\"dt_icon.gif\"> : Trial AIM User <br>"
1685 "<IMG SRC=\"admin_icon.gif\"> : Administrator <br>" 1702 "<IMG SRC=\"admin_icon.gif\"> : Administrator <br>"
1686 "<IMG SRC=\"ab_icon.gif\"> : ActiveBuddy Interactive Agent<br>")); 1703 "<IMG SRC=\"ab_icon.gif\"> : ActiveBuddy Interactive Agent<br>"));
1687 1704
1688 if (info->membersince) 1705 if (info->present & AIM_USERINFO_PRESENT_ONLINESINCE) {
1689 asc = g_strdup_printf("Member Since : <B>%s</B><BR>\n", 1706 onlinesince = g_strdup_printf("Online Since : <B>%s</B><BR>\n",
1690 asctime(localtime(&info->membersince))); 1707 asctime(localtime(&info->onlinesince)));
1691 else 1708 }
1692 asc = g_strdup(""); 1709
1710 if (info->present & AIM_USERINFO_PRESENT_MEMBERSINCE) {
1711 membersince = g_strdup_printf("Member Since : <B>%s</B><BR>\n",
1712 asctime(localtime(&info->membersince)));
1713 }
1714
1715 if (info->present & AIM_USERINFO_PRESENT_IDLE) {
1716 idle = g_strdup_printf("Idle : <B>%d minutes</B>",
1717 info->idletime);
1718 } else
1719 idle = g_strdup("Idle: <B>Active</B>");
1720
1693 g_snprintf(header, sizeof header, 1721 g_snprintf(header, sizeof header,
1694 _("Username : <B>%s</B> %s <BR>\n" 1722 _("Username : <B>%s</B> %s <BR>\n"
1723 "Warning Level : <B>%d %%</B><BR>\n"
1695 "%s" 1724 "%s"
1696 "Warning Level : <B>%d %%</B><BR>\n" 1725 "%s"
1697 "Online Since : <B>%s</B><BR>\n" 1726 "%s<BR>\n"
1698 "Idle Minutes : <B>%d</B>\n<BR>\n<HR><BR>\n"), 1727 "<HR><BR>\n"),
1699 info->sn, images(info->flags), 1728 info->sn, images(info->flags),
1700 asc,
1701 info->warnlevel/10, 1729 info->warnlevel/10,
1702 asctime(localtime(&info->onlinesince)), 1730 onlinesince ? onlinesince : "",
1703 info->idletime); 1731 membersince ? membersince : "",
1704 g_free(asc); 1732 idle ? idle : "");
1733
1734 g_free(onlinesince);
1735 g_free(membersince);
1736 g_free(idle);
1705 1737
1706 while (l) { 1738 while (l) {
1707 char *x = l->data; 1739 char *x = l->data;
1708 if (!strcmp(x, normalize(info->sn))) { 1740 if (!strcmp(x, normalize(info->sn))) {
1709 evilhack = TRUE; 1741 evilhack = TRUE;
2038 2070
2039 return 1; 2071 return 1;
2040 } 2072 }
2041 2073
2042 static int conninitdone_bos(aim_session_t *sess, aim_frame_t *fr, ...) { 2074 static int conninitdone_bos(aim_session_t *sess, aim_frame_t *fr, ...) {
2043 struct gaim_connection *gc = sess->aux_data;
2044 2075
2045 aim_reqpersonalinfo(sess, fr->conn); 2076 aim_reqpersonalinfo(sess, fr->conn);
2046 aim_bos_reqlocaterights(sess, fr->conn); 2077 aim_bos_reqlocaterights(sess, fr->conn);
2047 aim_bos_setprofile(sess, fr->conn, gc->user->user_info, NULL, gaim_caps);
2048 aim_bos_reqbuddyrights(sess, fr->conn); 2078 aim_bos_reqbuddyrights(sess, fr->conn);
2049
2050 account_online(gc);
2051 serv_finish_login(gc);
2052
2053 if (bud_list_cache_exists(gc))
2054 do_import(gc, NULL);
2055
2056 debug_printf("buddy list loaded\n");
2057 2079
2058 aim_reqicbmparams(sess); 2080 aim_reqicbmparams(sess);
2059 2081
2060 aim_bos_reqrights(sess, fr->conn); 2082 aim_bos_reqrights(sess, fr->conn);
2061 aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS); 2083 aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS);
2131 aim_seticbmparam(sess, params); 2153 aim_seticbmparam(sess, params);
2132 2154
2133 return 1; 2155 return 1;
2134 } 2156 }
2135 2157
2136 /* XXX this is frivelous... do you really want to know this info? */ 2158 static int gaim_parse_locaterights(aim_session_t *sess, aim_frame_t *fr, ...)
2159 {
2160 va_list ap;
2161 fu16_t maxsiglen;
2162 struct gaim_connection *gc = sess->aux_data;
2163 struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
2164
2165 va_start(ap, fr);
2166 maxsiglen = va_arg(ap, int);
2167 va_end(ap);
2168
2169 debug_printf("locate rights: max sig len = %d\n", maxsiglen);
2170
2171 odata->rights.maxsiglen = odata->rights.maxawaymsglen = (guint)maxsiglen;
2172
2173 aim_bos_setprofile(sess, fr->conn, gc->user->user_info, NULL, gaim_caps);
2174
2175 return 1;
2176 }
2177
2137 static int gaim_parse_buddyrights(aim_session_t *sess, aim_frame_t *fr, ...) { 2178 static int gaim_parse_buddyrights(aim_session_t *sess, aim_frame_t *fr, ...) {
2138 va_list ap; 2179 va_list ap;
2139 fu16_t maxbuddies, maxwatchers; 2180 fu16_t maxbuddies, maxwatchers;
2181 struct gaim_connection *gc = sess->aux_data;
2182 struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
2140 2183
2141 va_start(ap, fr); 2184 va_start(ap, fr);
2142 maxbuddies = (fu16_t)va_arg(ap, unsigned int); 2185 maxbuddies = (fu16_t)va_arg(ap, unsigned int);
2143 maxwatchers = (fu16_t)va_arg(ap, unsigned int); 2186 maxwatchers = (fu16_t)va_arg(ap, unsigned int);
2144 va_end(ap); 2187 va_end(ap);
2145 2188
2146 debug_printf("buddy list rights: Max buddies = %d / Max watchers = %d\n", maxbuddies, maxwatchers); 2189 debug_printf("buddy list rights: Max buddies = %d / Max watchers = %d\n", maxbuddies, maxwatchers);
2147 2190
2191 odata->rights.maxbuddies = (guint)maxbuddies;
2192 odata->rights.maxwatchers = (guint)maxwatchers;
2193
2148 return 1; 2194 return 1;
2149 } 2195 }
2150 2196
2151 static int gaim_bosrights(aim_session_t *sess, aim_frame_t *fr, ...) { 2197 static int gaim_bosrights(aim_session_t *sess, aim_frame_t *fr, ...) {
2152 fu16_t maxpermits, maxdenies; 2198 fu16_t maxpermits, maxdenies;
2153 va_list ap; 2199 va_list ap;
2200 struct gaim_connection *gc = sess->aux_data;
2201 struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
2154 2202
2155 va_start(ap, fr); 2203 va_start(ap, fr);
2156 maxpermits = (fu16_t)va_arg(ap, unsigned int); 2204 maxpermits = (fu16_t)va_arg(ap, unsigned int);
2157 maxdenies = (fu16_t)va_arg(ap, unsigned int); 2205 maxdenies = (fu16_t)va_arg(ap, unsigned int);
2158 va_end(ap); 2206 va_end(ap);
2159 2207
2160 debug_printf("BOS rights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies); 2208 debug_printf("BOS rights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies);
2209
2210 odata->rights.maxpermits = (guint)maxpermits;
2211 odata->rights.maxdenies = (guint)maxdenies;
2212
2213 account_online(gc);
2214 serv_finish_login(gc);
2215
2216 if (bud_list_cache_exists(gc))
2217 do_import(gc, NULL);
2218
2219 debug_printf("buddy list loaded\n");
2161 2220
2162 aim_clientready(sess, fr->conn); 2221 aim_clientready(sess, fr->conn);
2163 2222
2164 aim_icq_reqofflinemsgs(sess); 2223 aim_icq_reqofflinemsgs(sess);
2165 2224
2340 aim_flap_nop(odata->sess, odata->conn); 2399 aim_flap_nop(odata->sess, odata->conn);
2341 } 2400 }
2342 2401
2343 static char *oscar_name() { 2402 static char *oscar_name() {
2344 return "Oscar"; 2403 return "Oscar";
2404 }
2405
2406 static void oscar_send_typing_stopped(struct gaim_connection *gc, char *name) {
2407 struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
2408 struct direct_im *dim = find_direct_im(odata, name);
2409 if (!dim)
2410 return;
2411 aim_send_typing(odata->sess, dim->conn, FALSE);
2412 }
2413
2414 static int oscar_send_typing(struct gaim_connection *gc, char *name) {
2415 struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
2416 struct direct_im *dim = find_direct_im(odata, name);
2417 if (!dim)
2418 return;
2419 aim_send_typing(odata->sess, dim->conn, TRUE);
2420 return 0;
2345 } 2421 }
2346 2422
2347 static int oscar_send_im(struct gaim_connection *gc, char *name, char *message, int imflags) { 2423 static int oscar_send_im(struct gaim_connection *gc, char *name, char *message, int imflags) {
2348 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 2424 struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
2349 struct direct_im *dim = find_direct_im(odata, name); 2425 struct direct_im *dim = find_direct_im(odata, name);
2445 aim_bos_setidle(odata->sess, odata->conn, time); 2521 aim_bos_setidle(odata->sess, odata->conn, time);
2446 } 2522 }
2447 2523
2448 static void oscar_set_info(struct gaim_connection *g, char *info) { 2524 static void oscar_set_info(struct gaim_connection *g, char *info) {
2449 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 2525 struct oscar_data *odata = (struct oscar_data *)g->proto_data;
2450 char inforeal[1025], away[1025]; 2526 gchar *inforeal;
2451 g_snprintf(inforeal, sizeof(inforeal), "%s", info); 2527
2452 if (g->away) 2528 if (odata->rights.maxsiglen == 0)
2453 g_snprintf(away, sizeof(away), "%s", g->away); 2529 do_error_dialog("oscar_set_info called before locate rights received", "Protocol Error");
2454 if (strlen(info) > 1024) 2530
2455 do_error_dialog("Maximum info length (1024) exceeded, truncating", "Info Too Long"); 2531 if (strlen(info) > odata->rights.maxsiglen) {
2456 aim_bos_setprofile(odata->sess, odata->conn, inforeal, g->away ? NULL : "", gaim_caps); 2532 gchar *errstr;
2457 } 2533
2458 2534 errstr = g_strdup_printf("Maximum info length of %d bytes exceeded, truncating", odata->rights.maxsiglen);
2459 static void oscar_set_away(struct gaim_connection *gc, char *state, char *message) { 2535
2460 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 2536 do_error_dialog(errstr, "Info Too Long");
2461 char away[1025]; 2537
2462 if (!od->icq) { 2538 g_free(errstr);
2463 if (message) 2539 }
2464 g_snprintf(away, sizeof(away), "%s", message); 2540
2465 aim_bos_setprofile(od->sess, od->conn, NULL, message ? away : "", gaim_caps); 2541 inforeal = g_strndup(info, odata->rights.maxsiglen);
2466 if (gc->away) 2542
2467 g_free (gc->away); 2543 aim_bos_setprofile(odata->sess, odata->conn, inforeal, NULL, gaim_caps);
2468 gc->away = NULL; 2544
2469 if (message) { 2545 g_free(inforeal);
2470 if (strlen(message) > sizeof(away)-1) 2546
2471 do_error_dialog("Maximum away length exceeded (1024), truncating", 2547 return;
2472 "Info Too Long"); 2548 }
2473 gc->away = g_strdup (message); 2549
2474 } 2550 static void oscar_set_away_aim(struct gaim_connection *gc, struct oscar_data *od, const char *message)
2551 {
2552
2553 if (od->rights.maxawaymsglen == 0)
2554 do_error_dialog("oscar_set_away_aim called before locate rights received", "Protocol Error");
2555
2556 if (gc->away)
2557 g_free(gc->away);
2558 gc->away = NULL;
2559
2560 if (!message) {
2561 aim_bos_setprofile(od->sess, od->conn, NULL, "", gaim_caps);
2475 return; 2562 return;
2476 } 2563 }
2564
2565 if (strlen(message) > od->rights.maxawaymsglen) {
2566 gchar *errstr;
2567
2568 errstr = g_strdup_printf("Maximum away message length of %d bytes exceeded, truncating", od->rights.maxawaymsglen);
2569
2570 do_error_dialog(errstr, "Away Message Too Long");
2571
2572 g_free(errstr);
2573 }
2574
2575 gc->away = g_strndup(message, od->rights.maxawaymsglen);
2576 aim_bos_setprofile(od->sess, od->conn, NULL, gc->away, gaim_caps);
2577
2578 return;
2579 }
2580
2581 static void oscar_set_away_icq(struct gaim_connection *gc, struct oscar_data *od, const char *state, const char *message)
2582 {
2477 2583
2478 if (gc->away) 2584 if (gc->away)
2479 gc->away = NULL; 2585 gc->away = NULL;
2480 2586
2481 if (!strcmp(state, "Online")) 2587 if (!strcmp(state, "Online"))
2504 gc->away = ""; 2610 gc->away = "";
2505 } else { 2611 } else {
2506 aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL); 2612 aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL);
2507 } 2613 }
2508 } 2614 }
2615
2616 return;
2617 }
2618
2619 static void oscar_set_away(struct gaim_connection *gc, char *state, char *message)
2620 {
2621 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
2622
2623 if (od->icq)
2624 oscar_set_away_icq(gc, od, state, message);
2625 else
2626 oscar_set_away_aim(gc, od, message);
2627
2628 return;
2509 } 2629 }
2510 2630
2511 static void oscar_warn(struct gaim_connection *g, char *name, int anon) { 2631 static void oscar_warn(struct gaim_connection *g, char *name, int anon) {
2512 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 2632 struct oscar_data *odata = (struct oscar_data *)g->proto_data;
2513 aim_send_warning(odata->sess, odata->conn, name, anon ? AIM_WARN_ANON : 0); 2633 aim_send_warning(odata->sess, odata->conn, name, anon ? AIM_WARN_ANON : 0);
3000 3120
3001 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, 3121 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING,
3002 gaim_directim_incoming, 0); 3122 gaim_directim_incoming, 0);
3003 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, 3123 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING,
3004 gaim_directim_typing, 0); 3124 gaim_directim_typing, 0);
3125 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DOWNLOADIMAGE,
3126 gaim_update_ui, 0);
3127 return 1;
3128 }
3129
3130 static int gaim_update_ui(aim_session_t *sess, aim_frame_t *fr, ...) {
3131 va_list ap;
3132 char *sn;
3133 double percent;
3134 struct gaim_connection *gc = sess->aux_data;
3135 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3136 struct conversation *c;
3137 struct direct_im *dim;
3138
3139 va_start(ap, fr);
3140 sn = va_arg(ap, char *);
3141 percent = va_arg(ap, double);
3142 va_end(ap);
3143
3144 dim = find_direct_im(od, sn);
3145 gaim_input_remove(dim->watcher); /* Otherwise, the callback will callback */
3146 if ((c = find_conversation(sn)))
3147 update_progress(c, percent);
3148 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ,
3149 oscar_callback, dim->conn);
3005 3150
3006 return 1; 3151 return 1;
3007 } 3152 }
3008 3153
3009 static int gaim_directim_incoming(aim_session_t *sess, aim_frame_t *fr, ...) { 3154 static int gaim_directim_incoming(aim_session_t *sess, aim_frame_t *fr, ...) {
3010 va_list ap; 3155 va_list ap;
3011 char *msg, *sn; 3156 char *msg, *sn;
3157 int len;
3012 struct gaim_connection *gc = sess->aux_data; 3158 struct gaim_connection *gc = sess->aux_data;
3013 3159
3014 va_start(ap, fr); 3160 va_start(ap, fr);
3015 sn = va_arg(ap, char *); 3161 sn = va_arg(ap, char *);
3016 msg = va_arg(ap, char *); 3162 msg = va_arg(ap, char *);
3163 len = va_arg(ap, int);
3017 va_end(ap); 3164 va_end(ap);
3018 3165
3019 debug_printf("Got DirectIM message from %s\n", sn); 3166 debug_printf("Got DirectIM message from %s\n", sn);
3020 3167
3021 serv_got_im(gc, sn, msg, 0, time(NULL), -1); 3168 serv_got_im(gc, sn, msg, 0, time(NULL), len);
3022 3169
3023 return 1; 3170 return 1;
3024 } 3171 }
3025 3172
3026 static int gaim_directim_typing(aim_session_t *sess, aim_frame_t *fr, ...) { 3173 static int gaim_directim_typing(aim_session_t *sess, aim_frame_t *fr, ...) {
3027 va_list ap; 3174 va_list ap;
3028 char *sn; 3175 char *sn;
3176 int typing;
3177 struct gaim_connection *gc = sess->aux_data;
3029 3178
3030 va_start(ap, fr); 3179 va_start(ap, fr);
3031 sn = va_arg(ap, char *); 3180 sn = va_arg(ap, char *);
3181 typing = va_arg(ap, int);
3032 va_end(ap); 3182 va_end(ap);
3033 3183
3034 /* I had to leave this. It's just too funny. It reminds me of my sister. */ 3184 if (typing) {
3035 debug_printf("ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", sn); 3185 /* I had to leave this. It's just too funny. It reminds me of my sister. */
3036 3186 debug_printf("ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", sn);
3187 serv_got_typing(gc,sn,0);
3188 } else
3189 serv_got_typing_stopped(gc,sn);
3037 return 1; 3190 return 1;
3038 } 3191 }
3039 3192
3040 struct ask_do_dir_im { 3193 struct ask_do_dir_im {
3041 char *who; 3194 char *who;
3362 ret->buddy_menu = oscar_buddy_menu; 3515 ret->buddy_menu = oscar_buddy_menu;
3363 ret->user_opts = oscar_user_opts; 3516 ret->user_opts = oscar_user_opts;
3364 ret->login = oscar_login; 3517 ret->login = oscar_login;
3365 ret->close = oscar_close; 3518 ret->close = oscar_close;
3366 ret->send_im = oscar_send_im; 3519 ret->send_im = oscar_send_im;
3520 ret->send_typing = oscar_send_typing;
3521 ret->send_typing_stopped = oscar_send_typing_stopped;
3367 ret->set_info = oscar_set_info; 3522 ret->set_info = oscar_set_info;
3368 ret->get_info = oscar_get_info; 3523 ret->get_info = oscar_get_info;
3369 ret->set_away = oscar_set_away; 3524 ret->set_away = oscar_set_away;
3370 ret->get_away = oscar_get_away; 3525 ret->get_away = oscar_get_away;
3371 ret->set_dir = oscar_set_dir; 3526 ret->set_dir = oscar_set_dir;