comparison src/protocols/oscar/oscar.c @ 4230:9f729d6d88a6

[gaim-migrate @ 4475] This is 128KB of raw kickassyness. AKA ICQ SSI. I've rewritten all the important parts of ssi.c. Things should be better. One thing I like a lot is that gaim will store the alias you assign to buddies in your server list for both AIM and ICQ. WinICQ supports this, but WinAIM doesn't. However, it doesn't seem to interfere with WinAIM, and Gaim can still use it. I dunno, I just think it's neat. Anyway, go nuts. Let me know if something doesn't work, because that's bad. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Tue, 07 Jan 2003 21:19:05 +0000
parents bbd1236e9cc9
children d3069a71f14d
comparison
equal deleted inserted replaced
4229:c1857c9c912d 4230:9f729d6d88a6
127 gboolean killme; 127 gboolean killme;
128 gboolean icq; 128 gboolean icq;
129 GSList *evilhack; 129 GSList *evilhack;
130 130
131 struct { 131 struct {
132 guint maxwatchers; /* max users who can watch you */
132 guint maxbuddies; /* max users you can watch */ 133 guint maxbuddies; /* max users you can watch */
133 guint maxwatchers; /* max users who can watch you */ 134 guint maxgroups; /* max groups in server list */
134 guint maxpermits; /* max users on permit list */ 135 guint maxpermits; /* max users on permit list */
135 guint maxdenies; /* max users on deny list */ 136 guint maxdenies; /* max users on deny list */
136 guint maxsiglen; /* max size (bytes) of profile */ 137 guint maxsiglen; /* max size (bytes) of profile */
137 guint maxawaymsglen; /* max size (bytes) of posted away message */ 138 guint maxawaymsglen; /* max size (bytes) of posted away message */
138 } rights; 139 } rights;
193 unsigned long length; 194 unsigned long length;
194 unsigned long checksum; 195 unsigned long checksum;
195 gboolean request; 196 gboolean request;
196 }; 197 };
197 198
198 struct channel4_data { 199 struct name_data {
199 struct gaim_connection *gc; 200 struct gaim_connection *gc;
200 gchar *uin; 201 gchar *name;
201 gchar *nick; 202 gchar *nick;
202 }; 203 };
204
205 static void gaim_free_name_data(struct name_data *data) {
206 g_free(data->name);
207 g_free(data->nick);
208 g_free(data);
209 }
203 210
204 static struct direct_im *find_direct_im(struct oscar_data *od, const char *who) { 211 static struct direct_im *find_direct_im(struct oscar_data *od, const char *who) {
205 GSList *d = od->direct_ims; 212 GSList *d = od->direct_ims;
206 char *n = g_strdup(normalize(who)); 213 char *n = g_strdup(normalize(who));
207 struct direct_im *m = NULL; 214 struct direct_im *m = NULL;
368 static int gaim_offlinemsg (aim_session_t *, aim_frame_t *, ...); 375 static int gaim_offlinemsg (aim_session_t *, aim_frame_t *, ...);
369 static int gaim_offlinemsgdone (aim_session_t *, aim_frame_t *, ...); 376 static int gaim_offlinemsgdone (aim_session_t *, aim_frame_t *, ...);
370 static int gaim_icqsimpleinfo (aim_session_t *, aim_frame_t *, ...); 377 static int gaim_icqsimpleinfo (aim_session_t *, aim_frame_t *, ...);
371 static int gaim_icqallinfo (aim_session_t *, aim_frame_t *, ...); 378 static int gaim_icqallinfo (aim_session_t *, aim_frame_t *, ...);
372 static int gaim_popup (aim_session_t *, aim_frame_t *, ...); 379 static int gaim_popup (aim_session_t *, aim_frame_t *, ...);
380 #ifndef NOSSI
373 static int gaim_ssi_parserights (aim_session_t *, aim_frame_t *, ...); 381 static int gaim_ssi_parserights (aim_session_t *, aim_frame_t *, ...);
374 static int gaim_ssi_parselist (aim_session_t *, aim_frame_t *, ...); 382 static int gaim_ssi_parselist (aim_session_t *, aim_frame_t *, ...);
383 static int gaim_ssi_parseack (aim_session_t *, aim_frame_t *, ...);
384 static int gaim_ssi_authgiven (aim_session_t *, aim_frame_t *, ...);
385 static int gaim_ssi_authrequest (aim_session_t *, aim_frame_t *, ...);
386 static int gaim_ssi_authreply (aim_session_t *, aim_frame_t *, ...);
387 static int gaim_ssi_gotadded (aim_session_t *, aim_frame_t *, ...);
388 #endif
375 389
376 static int gaim_directim_initiate(aim_session_t *, aim_frame_t *, ...); 390 static int gaim_directim_initiate(aim_session_t *, aim_frame_t *, ...);
377 static int gaim_directim_incoming(aim_session_t *, aim_frame_t *, ...); 391 static int gaim_directim_incoming(aim_session_t *, aim_frame_t *, ...);
378 static int gaim_directim_typing (aim_session_t *, aim_frame_t *, ...); 392 static int gaim_directim_typing (aim_session_t *, aim_frame_t *, ...);
379 static int gaim_update_ui (aim_session_t *, aim_frame_t *, ...); 393 static int gaim_update_ui (aim_session_t *, aim_frame_t *, ...);
887 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG, gaim_offlinemsg, 0); 901 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG, gaim_offlinemsg, 0);
888 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSGCOMPLETE, gaim_offlinemsgdone, 0); 902 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSGCOMPLETE, gaim_offlinemsgdone, 0);
889 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_POP, 0x0002, gaim_popup, 0); 903 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_POP, 0x0002, gaim_popup, 0);
890 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_SIMPLEINFO, gaim_icqsimpleinfo, 0); 904 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_SIMPLEINFO, gaim_icqsimpleinfo, 0);
891 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_ALLINFO, gaim_icqallinfo, 0); 905 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_ALLINFO, gaim_icqallinfo, 0);
906 #ifndef NOSSI
892 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RIGHTSINFO, gaim_ssi_parserights, 0); 907 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RIGHTSINFO, gaim_ssi_parserights, 0);
893 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_LIST, gaim_ssi_parselist, 0); 908 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_LIST, gaim_ssi_parselist, 0);
894 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_NOLIST, gaim_ssi_parselist, 0); 909 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_NOLIST, gaim_ssi_parselist, 0);
910 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_SRVACK, gaim_ssi_parseack, 0);
911 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTH, gaim_ssi_authgiven, 0);
912 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREQ, gaim_ssi_authrequest, 0);
913 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREP, gaim_ssi_authreply, 0);
914 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_ADDED, gaim_ssi_gotadded, 0);
915 #endif
895 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_MSGTIMEOUT, oscar_sendfile_timeout, 0); 916 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_MSGTIMEOUT, oscar_sendfile_timeout, 0);
896 917
897 ((struct oscar_data *)gc->proto_data)->conn = bosconn; 918 ((struct oscar_data *)gc->proto_data)->conn = bosconn;
898 for (i = 0; i < (int)strlen(info->bosip); i++) { 919 for (i = 0; i < (int)strlen(info->bosip); i++) {
899 if (info->bosip[i] == ':') { 920 if (info->bosip[i] == ':') {
2029 2050
2030 return 1; 2051 return 1;
2031 } 2052 }
2032 2053
2033 /* 2054 /*
2034 * Next 2 functions are for when other people ask you for authorization 2055 * Authorization Functions
2056 * Most of these are callbacks from dialogs. They're used by both
2057 * methods of authorization (SSI and old-school channel 4 ICBM)
2035 */ 2058 */
2036 static void gaim_icq_authgrant(struct channel4_data *data) { 2059 static void gaim_auth_request(struct name_data *data) {
2060 struct gaim_connection *gc = data->gc;
2061 struct oscar_data *od = gc->proto_data;
2062 struct buddy *buddy = find_buddy(gc, data->name);
2063 struct group *group = find_group_by_buddy(gc, data->name);
2064 if (buddy && group) {
2065 debug_printf("ssi: adding buddy %s to group %s\n", buddy->name, group->name);
2066 aim_ssi_sendauthrequest(od->sess, od->conn, data->name, "Please authorize me so I can add you to my buddy list.");
2067 aim_ssi_addbuddy(od->sess, od->conn, buddy->name, group->name, get_buddy_alias_only(buddy), NULL, NULL, 1);
2068 }
2069 gaim_free_name_data(data);
2070 }
2071
2072 static void gaim_auth_dontrequest(struct name_data *data) {
2073 /* struct gaim_connection *gc = data->gc; */
2074 /* struct oscar_data *od = gc->proto_data; */
2075 /* XXX - Take the buddy out of our buddy list */
2076 gaim_free_name_data(data);
2077 }
2078
2079 /* When other people ask you for authorization */
2080 static void gaim_auth_grant(struct name_data *data) {
2081 struct gaim_connection *gc = data->gc;
2082 struct oscar_data *od = gc->proto_data;
2037 gchar message; 2083 gchar message;
2038 struct oscar_data *od = (struct oscar_data *)data->gc->proto_data;
2039 message = 0; 2084 message = 0;
2040 aim_send_im_ch4(od->sess, data->uin, AIM_ICQMSG_AUTHGRANTED, &message); 2085 #ifdef NOSSI
2041 show_got_added(data->gc, NULL, data->uin, NULL, NULL); 2086 aim_send_im_ch4(od->sess, data->name, AIM_ICQMSG_AUTHGRANTED, &message);
2042 g_free(data->uin); 2087 show_got_added(gc, NULL, data->name, NULL, NULL);
2043 g_free(data); 2088 #else
2044 } 2089 aim_ssi_sendauthreply(od->sess, od->conn, data->name, 0x01, &message);
2045 2090 #endif
2046 static void gaim_icq_authdeny(struct channel4_data *data) { 2091 gaim_free_name_data(data);
2092 }
2093
2094 /* When other people ask you for authorization */
2095 static void gaim_auth_dontgrant(struct name_data *data) {
2096 struct gaim_connection *gc = data->gc;
2097 struct oscar_data *od = gc->proto_data;
2047 gchar *message; 2098 gchar *message;
2048 struct oscar_data *od = (struct oscar_data *)data->gc->proto_data; 2099 message = g_strdup_printf(_("No reason given."));
2049 message = g_strdup_printf("No reason given."); 2100 #ifdef NOSSI
2050 aim_send_im_ch4(od->sess, data->uin, AIM_ICQMSG_AUTHDENIED, message); 2101 aim_send_im_ch4(od->sess, data->name, AIM_ICQMSG_AUTHDENIED, message);
2051 g_free(data->uin); 2102 #else
2103 aim_ssi_sendauthreply(od->sess, od->conn, data->name, 0x00, message);
2104 #endif
2052 g_free(message); 2105 g_free(message);
2053 g_free(data); 2106 gaim_free_name_data(data);
2054 } 2107 }
2055 2108
2056 /* 2109 /* When someone sends you contacts */
2057 * Next 2 functions are for when someone sends you contacts 2110 static void gaim_icq_contactadd(struct name_data *data) {
2058 */ 2111 struct gaim_connection *gc = data->gc;
2059 static void gaim_icq_contactadd(struct channel4_data *data) { 2112 show_add_buddy(gc, data->name, NULL, data->nick);
2060 show_add_buddy(data->gc, data->uin, NULL, data->nick); 2113 gaim_free_name_data(data);
2061 free(data->uin);
2062 free(data->nick);
2063 g_free(data);
2064 }
2065
2066 static void gaim_icq_contactdontadd(struct channel4_data *data) {
2067 free(data->uin);
2068 free(data->nick);
2069 g_free(data);
2070 } 2114 }
2071 2115
2072 static int incomingim_chan4(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch4_args *args, time_t t) { 2116 static int incomingim_chan4(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch4_args *args, time_t t) {
2073 struct gaim_connection *gc = sess->aux_data; 2117 struct gaim_connection *gc = sess->aux_data;
2074 gchar **msg1, **msg2; 2118 gchar **msg1, **msg2;
2115 } 2159 }
2116 } break; 2160 } break;
2117 2161
2118 case 0x06: { /* Someone requested authorization */ 2162 case 0x06: { /* Someone requested authorization */
2119 if (i >= 6) { 2163 if (i >= 6) {
2120 struct channel4_data *data = g_new(struct channel4_data, 1); 2164 struct name_data *data = g_new(struct name_data, 1);
2121 gchar *dialog_msg = g_strdup_printf(_("The user %lu wants to add you to their buddy list for the following reason: %s"), args->uin, msg2[5] ? msg2[5] : _("No reason given.")); 2165 gchar *dialog_msg = g_strdup_printf(_("The user %lu wants to add you to their buddy list for the following reason: %s"), args->uin, msg2[5] ? msg2[5] : _("No reason given."));
2122 debug_printf("Received an authorization request from UIN %lu\n", args->uin); 2166 debug_printf("Received an authorization request from UIN %lu\n", args->uin);
2123 data->gc = gc; 2167 data->gc = gc;
2124 data->uin = g_strdup_printf("%lu", args->uin); 2168 data->name = g_strdup_printf("%lu", args->uin);
2125 do_ask_dialog(_("Authorization Request"), dialog_msg, data, _("Authorize"), gaim_icq_authgrant, _("Deny"), gaim_icq_authdeny); 2169 data->nick = NULL;
2170 do_ask_dialog(_("Authorization Request"), dialog_msg, data, _("Authorize"), gaim_auth_grant, _("Deny"), gaim_auth_dontgrant);
2126 g_free(dialog_msg); 2171 g_free(dialog_msg);
2127 } 2172 }
2128 } break; 2173 } break;
2129 2174
2130 case 0x07: { /* Someone has denied you authorization */ 2175 case 0x07: { /* Someone has denied you authorization */
2131 if (i >= 1) { 2176 if (i >= 1) {
2132 gchar *dialog_msg = g_strdup_printf(_("The user %lu has denied your request to add them to your contact list for the following reason:\n%s"), args->uin, msg2[0] ? msg2[0] : _("No reason given.")); 2177 gchar *dialog_msg = g_strdup_printf(_("The user %lu has denied your request to add them to your contact list for the following reason:\n%s"), args->uin, msg2[0] ? msg2[0] : _("No reason given."));
2133 do_error_dialog(_("ICQ authorization denied."), dialog_msg, GAIM_ERROR); 2178 do_error_dialog(_("ICQ authorization denied."), dialog_msg, GAIM_INFO);
2134 g_free(dialog_msg); 2179 g_free(dialog_msg);
2135 } 2180 }
2136 } break; 2181 } break;
2137 2182
2138 case 0x08: { /* Someone has granted you authorization */ 2183 case 0x08: { /* Someone has granted you authorization */
2169 if (text) { 2214 if (text) {
2170 num = 0; 2215 num = 0;
2171 for (i=0; i<strlen(text[0]); i++) 2216 for (i=0; i<strlen(text[0]); i++)
2172 num = num*10 + text[0][i]-48; 2217 num = num*10 + text[0][i]-48;
2173 for (i=0; i<num; i++) { 2218 for (i=0; i<num; i++) {
2174 struct channel4_data *data = g_new(struct channel4_data, 1); 2219 struct name_data *data = g_new(struct name_data, 1);
2175 gchar *message = g_strdup_printf(_("ICQ user %lu has sent you a contact: %s (%s)"), args->uin, text[i*2+2], text[i*2+1]); 2220 gchar *message = g_strdup_printf(_("ICQ user %lu has sent you a contact: %s (%s)"), args->uin, text[i*2+2], text[i*2+1]);
2176 data->gc = gc; 2221 data->gc = gc;
2177 data->uin = g_strdup(text[i*2+2]); 2222 data->name = g_strdup(text[i*2+2]);
2178 data->nick = g_strdup(text[i*2+1]); 2223 data->nick = g_strdup(text[i*2+1]);
2179 do_ask_dialog(message, _("Do you want to add this contact to your Buddy List?"), data, _("Add"), gaim_icq_contactadd, _("Deny"), gaim_icq_contactdontadd); 2224 do_ask_dialog(message, _("Do you want to add this contact to your Buddy List?"), data, _("Add"), gaim_icq_contactadd, _("Deny"), gaim_free_name_data);
2180 g_free(message); 2225 g_free(message);
2181 } 2226 }
2182 g_strfreev(text); 2227 g_strfreev(text);
2183 } 2228 }
2184 } break; 2229 } break;
3053 3098
3054 return 1; 3099 return 1;
3055 } 3100 }
3056 3101
3057 static int conninitdone_bos(aim_session_t *sess, aim_frame_t *fr, ...) { 3102 static int conninitdone_bos(aim_session_t *sess, aim_frame_t *fr, ...) {
3058 struct gaim_connection *gc = sess->aux_data;
3059 struct oscar_data *od = gc->proto_data;
3060 3103
3061 aim_reqpersonalinfo(sess, fr->conn); 3104 aim_reqpersonalinfo(sess, fr->conn);
3105
3106 #ifndef NOSSI
3107 debug_printf("ssi: requesting ssi list\n");
3108 aim_ssi_reqrights(sess, fr->conn);
3109 aim_ssi_reqdata(sess, fr->conn, sess->ssi.timestamp, sess->ssi.numitems);
3110 #endif
3111
3062 aim_bos_reqlocaterights(sess, fr->conn); 3112 aim_bos_reqlocaterights(sess, fr->conn);
3063 aim_bos_reqbuddyrights(sess, fr->conn); 3113 aim_bos_reqbuddyrights(sess, fr->conn);
3064
3065 aim_reqicbmparams(sess); 3114 aim_reqicbmparams(sess);
3066
3067 aim_bos_reqrights(sess, fr->conn); 3115 aim_bos_reqrights(sess, fr->conn);
3068 if (od->icq) { 3116
3069 aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS); 3117 #ifdef NOSSI
3070 aim_bos_setprivacyflags(sess, fr->conn, AIM_PRIVFLAGS_ALLOWIDLE | 3118 aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS);
3071 AIM_PRIVFLAGS_ALLOWMEMBERSINCE); 3119 aim_bos_setprivacyflags(sess, fr->conn, AIM_PRIVFLAGS_ALLOWIDLE | AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
3072 } 3120 #endif
3073 3121
3074 return 1; 3122 return 1;
3075 } 3123 }
3076 3124
3077 static int conninitdone_admin(aim_session_t *sess, aim_frame_t *fr, ...) { 3125 static int conninitdone_admin(aim_session_t *sess, aim_frame_t *fr, ...) {
3224 3272
3225 debug_printf("buddy list loaded\n"); 3273 debug_printf("buddy list loaded\n");
3226 3274
3227 aim_clientready(sess, fr->conn); 3275 aim_clientready(sess, fr->conn);
3228 3276
3229 /* XXX - Should call aim_bos_setidle with 0x0000 */ 3277 /* AAA - Should call aim_bos_setidle with 0x0000 */
3230 3278
3231 /* XXX - Should only call reqofflinemsgs when using ICQ? */ 3279 /* AAA - Should only call reqofflinemsgs when using ICQ? */
3232 aim_icq_reqofflinemsgs(sess); 3280 aim_icq_reqofflinemsgs(sess);
3233 3281
3234 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_CHATNAV); 3282 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_CHATNAV);
3235 if (sess->authinfo->email) 3283 if (sess->authinfo->email)
3236 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_EMAIL); 3284 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_EMAIL);
3237
3238 if (!odata->icq) {
3239 debug_printf("ssi: requesting ssi list\n");
3240 aim_ssi_reqrights(sess, fr->conn);
3241 aim_ssi_reqdata(sess, fr->conn, sess->ssi.timestamp, sess->ssi.revision);
3242 }
3243 3285
3244 return 1; 3286 return 1;
3245 } 3287 }
3246 3288
3247 static int gaim_offlinemsg(aim_session_t *sess, aim_frame_t *fr, ...) { 3289 static int gaim_offlinemsg(aim_session_t *sess, aim_frame_t *fr, ...) {
3701 aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_CAPABILITIES); 3743 aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_CAPABILITIES);
3702 } 3744 }
3703 3745
3704 static void oscar_set_dir(struct gaim_connection *g, const char *first, const char *middle, const char *last, 3746 static void oscar_set_dir(struct gaim_connection *g, const char *first, const char *middle, const char *last,
3705 const char *maiden, const char *city, const char *state, const char *country, int web) { 3747 const char *maiden, const char *city, const char *state, const char *country, int web) {
3706 /* FIXME : some of these things are wrong, but i'm lazy */ 3748 /* AAA: some of these things are wrong, but i'm lazy */
3707 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3749 struct oscar_data *odata = (struct oscar_data *)g->proto_data;
3708 aim_setdirectoryinfo(odata->sess, odata->conn, first, middle, last, 3750 aim_setdirectoryinfo(odata->sess, odata->conn, first, middle, last,
3709 maiden, NULL, NULL, city, state, NULL, 0, web); 3751 maiden, NULL, NULL, city, state, NULL, 0, web);
3710 } 3752 }
3711 3753
3855 oscar_set_away_aim(gc, od, message); 3897 oscar_set_away_aim(gc, od, message);
3856 3898
3857 return; 3899 return;
3858 } 3900 }
3859 3901
3860 static void oscar_warn(struct gaim_connection *g, char *name, int anon) { 3902 static void oscar_warn(struct gaim_connection *gc, char *name, int anon) {
3861 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3903 struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
3862 aim_send_warning(odata->sess, odata->conn, name, anon ? AIM_WARN_ANON : 0); 3904 aim_send_warning(odata->sess, odata->conn, name, anon ? AIM_WARN_ANON : 0);
3863 } 3905 }
3864 3906
3865 static void oscar_dir_search(struct gaim_connection *g, const char *first, const char *middle, const char *last, 3907 static void oscar_dir_search(struct gaim_connection *gc, const char *first, const char *middle, const char *last,
3866 const char *maiden, const char *city, const char *state, const char *country, const char *email) { 3908 const char *maiden, const char *city, const char *state, const char *country, const char *email) {
3867 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3909 struct oscar_data *odata = (struct oscar_data *)gc->proto_data;
3868 if (strlen(email)) 3910 if (strlen(email))
3869 aim_usersearch_address(odata->sess, odata->conn, email); 3911 aim_usersearch_address(odata->sess, odata->conn, email);
3870 } 3912 }
3871 3913
3872 static void oscar_add_buddy(struct gaim_connection *g, const char *name) { 3914 static void oscar_add_buddy(struct gaim_connection *gc, const char *name) {
3873 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3915 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3874 if (odata->icq) { 3916 #ifdef NOSSI
3875 aim_add_buddy(odata->sess, odata->conn, name); 3917 aim_add_buddy(od->sess, od->conn, name);
3876 } else { 3918 #else
3877 if ((odata->sess->ssi.received_data) && !(aim_ssi_itemlist_finditem(odata->sess->ssi.items, NULL, name, 0x0000))) { 3919 if ((od->sess->ssi.received_data) && !(aim_ssi_itemlist_exists(od->sess->ssi.local, name))) {
3878 debug_printf("ssi: adding buddy %s to group %s\n", name, find_group_by_buddy(g, name)->name); 3920 struct buddy *buddy = find_buddy(gc, name);
3879 aim_ssi_addbuddies(odata->sess, odata->conn, find_group_by_buddy(g, name)->name, &name, 1); 3921 struct group *group = find_group_by_buddy(gc, name);
3880 } 3922 if (buddy && group) {
3881 } 3923 debug_printf("ssi: adding buddy %s to group %s\n", name, group->name);
3882 } 3924 aim_ssi_addbuddy(od->sess, od->conn, buddy->name, group->name, get_buddy_alias_only(buddy), NULL, NULL, 0);
3883 3925 }
3884 static void oscar_add_buddies(struct gaim_connection *g, GList *buddies) { 3926 }
3885 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3927 #endif
3886 if (odata->icq) { 3928 }
3887 char buf[MSG_LEN]; 3929
3888 int n=0; 3930 static void oscar_add_buddies(struct gaim_connection *gc, GList *buddies) {
3931 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3932 #ifdef NOSSI
3933 char buf[MSG_LEN];
3934 int n=0;
3935 while (buddies) {
3936 if (n > MSG_LEN - 18) {
3937 aim_bos_setbuddylist(od->sess, od->conn, buf);
3938 n = 0;
3939 }
3940 n += g_snprintf(buf + n, sizeof(buf) - n, "%s&", (char *)buddies->data);
3941 buddies = buddies->next;
3942 }
3943 aim_bos_setbuddylist(od->sess, od->conn, buf);
3944 #else
3945 if (od->sess->ssi.received_data) {
3889 while (buddies) { 3946 while (buddies) {
3890 if (n > MSG_LEN - 18) { 3947 struct buddy *buddy = find_buddy(gc, (const char *)buddies->data);
3891 aim_bos_setbuddylist(odata->sess, odata->conn, buf); 3948 struct group *group = find_group_by_buddy(gc, (const char *)buddies->data);
3892 n = 0; 3949 if (buddy && group) {
3950 debug_printf("ssi: adding buddy %s to group %s\n", (const char *)buddies->data, group->name);
3951 aim_ssi_addbuddy(od->sess, od->conn, buddy->name, group->name, get_buddy_alias_only(buddy), NULL, NULL, 0);
3893 } 3952 }
3894 n += g_snprintf(buf + n, sizeof(buf) - n, "%s&", (char *)buddies->data);
3895 buddies = buddies->next; 3953 buddies = buddies->next;
3896 } 3954 }
3897 aim_bos_setbuddylist(odata->sess, odata->conn, buf); 3955 }
3898 } else { 3956 #endif
3899 if (odata->sess->ssi.received_data) { 3957 }
3900 int tmp; 3958
3901 GSList *curgrp, *curbud; 3959 #ifndef NOSSI
3902 for (curgrp=g->groups; curgrp; curgrp=g_slist_next(curgrp)) { 3960 static void oscar_move_buddy(struct gaim_connection *gc, const char *name, const char *old_group, const char *new_group) {
3903 tmp = 0; 3961 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3904 for (curbud=((struct group*)curgrp->data)->members; curbud; curbud=curbud->next) 3962 if (od->sess->ssi.received_data) {
3905 if (!aim_ssi_itemlist_finditem(odata->sess->ssi.items, NULL, ((struct buddy*)curbud->data)->name, 0x0000)) 3963 debug_printf("ssi: moving buddy %s from group %s to group %s\n", name, old_group, new_group);
3906 tmp++; 3964 aim_ssi_movebuddy(od->sess, od->conn, old_group, new_group, name);
3907 if (tmp) { 3965 }
3908 char **sns = (char **)malloc(tmp*sizeof(char*)); 3966 }
3909 tmp = 0; 3967 #endif
3910 for (curbud=((struct group*)curgrp->data)->members; curbud; curbud=curbud->next) 3968
3911 if (!aim_ssi_itemlist_finditem(odata->sess->ssi.items, NULL, ((struct buddy*)curbud->data)->name, 0x0000)) { 3969 static void oscar_remove_buddy(struct gaim_connection *gc, char *name, char *group) {
3912 debug_printf("ssi: adding buddy %s to group %s\n", ((struct buddy*)curbud->data)->name, ((struct group*)curgrp->data)->name); 3970 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3913 sns[tmp] = (char *)((struct buddy*)curbud->data)->name; 3971 #ifdef NOSSI
3914 tmp++; 3972 aim_remove_buddy(od->sess, od->conn, name);
3915 } 3973 #else
3916 aim_ssi_addbuddies(odata->sess, odata->conn, ((struct group*)curgrp->data)->name, (const char**)sns, tmp); 3974 if (od->sess->ssi.received_data) {
3917 free(sns); 3975 debug_printf("ssi: deleting buddy %s from group %s\n", name, group);
3918 } 3976 aim_ssi_delbuddy(od->sess, od->conn, name, group);
3919 } 3977 }
3920 } 3978 #endif
3921 } 3979 }
3922 } 3980
3923 3981 static void oscar_remove_buddies(struct gaim_connection *gc, GList *buddies, const char *group) {
3924 static void oscar_move_buddy(struct gaim_connection *g, const char *name, const char *old_group, const char *new_group) { 3982 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3925 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3983 #ifdef NOSSI
3926 if (!odata->icq) 3984 GList *cur;
3927 if (odata->sess->ssi.received_data) { 3985 for (cur=buddies; cur; cur=cur->next)
3928 aim_ssi_movebuddy(odata->sess, odata->conn, old_group, new_group, name); 3986 aim_remove_buddy(od->sess, od->conn, cur->data);
3929 debug_printf("ssi: moved buddy %s from group %s to group %s\n", name, old_group, new_group); 3987 #else
3930 } 3988 if (od->sess->ssi.received_data) {
3931 } 3989 while (buddies) {
3932 3990 debug_printf("ssi: deleting buddy %s from group %s\n", (char *)buddies->data, group);
3933 static void oscar_remove_buddy(struct gaim_connection *g, char *name, char *group) { 3991 aim_ssi_delbuddy(od->sess, od->conn, buddies->data, group);
3934 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3992 buddies = buddies->next;
3935 if (odata->icq) { 3993 }
3936 aim_remove_buddy(odata->sess, odata->conn, name); 3994 }
3937 } else { 3995 #endif
3938 if (odata->sess->ssi.received_data) { 3996 }
3939 struct aim_ssi_item *ssigroup; 3997
3940 while (aim_ssi_itemlist_finditem(odata->sess->ssi.items, NULL, name, 0x0000) && (ssigroup = aim_ssi_itemlist_findparent(odata->sess->ssi.items, name)) && !aim_ssi_delbuddies(odata->sess, odata->conn, ssigroup->name, &name, 1)) 3998 #ifndef NOSSI
3941 debug_printf("ssi: deleted buddy %s from group %s\n", name, group);
3942 }
3943 }
3944 }
3945
3946 static void oscar_remove_buddies(struct gaim_connection *g, GList *buddies, const char *group) {
3947 struct oscar_data *odata = (struct oscar_data *)g->proto_data;
3948 if (odata->icq) {
3949 GList *cur;
3950 for (cur=buddies; cur; cur=cur->next)
3951 aim_remove_buddy(odata->sess, odata->conn, cur->data);
3952 } else {
3953 if (odata->sess->ssi.received_data) {
3954 GList *cur;
3955 int tmp = 0;
3956 for (cur=buddies; cur; cur=cur->next)
3957 if (aim_ssi_itemlist_finditem(odata->sess->ssi.items, NULL, cur->data, 0x0000))
3958 tmp++;
3959 if (tmp) {
3960 char **sns;
3961 sns = (char **)malloc(tmp*sizeof(char*));
3962 tmp = 0;
3963 for (cur=buddies; cur; cur=cur->next)
3964 if (aim_ssi_itemlist_finditem(odata->sess->ssi.items, NULL, cur->data, 0x0000)) {
3965 debug_printf("ssi: deleting buddy %s from group %s\n", (char *)cur->data, group);
3966 sns[tmp] = cur->data;
3967 tmp++;
3968 }
3969 aim_ssi_delbuddies(odata->sess, odata->conn, group, sns, tmp);
3970 free(sns);
3971 }
3972 }
3973 }
3974 }
3975
3976 static void oscar_rename_group(struct gaim_connection *g, const char *old_group, const char *new_group, GList *members) { 3999 static void oscar_rename_group(struct gaim_connection *g, const char *old_group, const char *new_group, GList *members) {
3977 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 4000 struct oscar_data *od = (struct oscar_data *)g->proto_data;
3978 if (!odata->icq) 4001
3979 if (odata->sess->ssi.received_data) { 4002 if (od->sess->ssi.received_data) {
3980 if (aim_ssi_itemlist_finditem(odata->sess->ssi.items, NULL, new_group, 0x0001)) { 4003 if (aim_ssi_itemlist_finditem(od->sess->ssi.local, new_group, NULL, AIM_SSI_TYPE_GROUP)) {
3981 oscar_remove_buddies(g, members, old_group); 4004 oscar_remove_buddies(g, members, old_group);
3982 oscar_add_buddies(g, members); 4005 oscar_add_buddies(g, members);
3983 debug_printf("ssi: moved all buddies from group %s to %s\n", old_group, new_group); 4006 debug_printf("ssi: moved all buddies from group %s to %s\n", old_group, new_group);
3984 } else { 4007 } else {
3985 aim_ssi_rename_group(odata->sess, odata->conn, old_group, new_group); 4008 aim_ssi_rename_group(od->sess, od->conn, old_group, new_group);
3986 debug_printf("ssi: renamed group %s to %s\n", old_group, new_group); 4009 debug_printf("ssi: renamed group %s to %s\n", old_group, new_group);
3987 } 4010 }
3988 } 4011 }
3989 } 4012 }
3990 4013
3991 static int gaim_ssi_parserights(aim_session_t *sess, aim_frame_t *fr, ...) { 4014 static int gaim_ssi_parserights(aim_session_t *sess, aim_frame_t *fr, ...) {
3992 /* XXX - Fix parsing of the ssi rights packet and pass us the data 4015 struct gaim_connection *gc = sess->aux_data;
3993 fu16_t maxbuddies, maxgroups, maxpermits, maxdenies; 4016 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4017 int numtypes, i;
4018 fu16_t *maxitems;
3994 va_list ap; 4019 va_list ap;
3995 4020
3996 va_start(ap, fr); 4021 va_start(ap, fr);
3997 maxbuddies = (fu16_t)va_arg(ap, unsigned int); 4022 numtypes = va_arg(ap, int);
3998 maxgroupss = (fu16_t)va_arg(ap, unsigned int); 4023 maxitems = va_arg(ap, fu16_t *);
3999 maxpermits = (fu16_t)va_arg(ap, unsigned int);
4000 maxdenies = (fu16_t)va_arg(ap, unsigned int);
4001 va_end(ap); 4024 va_end(ap);
4002 4025
4003 debug_printf("ssi rights: Max buddies = %d / Max groups = %d / Max permits = %d / Max denies = %d\n", maxbuddies, maxgroups, maxpermits, maxdenies); 4026 debug_printf("ssi rights:");
4004 */ 4027 for (i=0; i<numtypes; i++)
4028 debug_printf(" max type %d = %hu, ", i, maxitems[i]);
4029
4030 if (numtypes >= 0)
4031 od->rights.maxbuddies = maxitems[0];
4032 if (numtypes >= 1)
4033 od->rights.maxgroups = maxitems[1];
4034 if (numtypes >= 2)
4035 od->rights.maxpermits = maxitems[2];
4036 if (numtypes >= 3)
4037 od->rights.maxdenies = maxitems[3];
4005 4038
4006 return 1; 4039 return 1;
4007 } 4040 }
4008 4041
4009 static int gaim_ssi_parselist(aim_session_t *sess, aim_frame_t *fr, ...) { 4042 static int gaim_ssi_parselist(aim_session_t *sess, aim_frame_t *fr, ...) {
4010 struct gaim_connection *gc = sess->aux_data; 4043 struct gaim_connection *gc = sess->aux_data;
4011 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 4044 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4012 struct aim_ssi_item *curitem; 4045 struct aim_ssi_item *curitem;
4013 int tmp; 4046 int tmp;
4014 const char **sns; 4047 /* AAA - use these?
4048 va_list ap;
4049
4050 va_start(ap, fr);
4051 fmtver = (fu16_t)va_arg(ap, int);
4052 numitems = (fu16_t)va_arg(ap, int);
4053 items = va_arg(ap, struct aim_ssi_item);
4054 timestamp = va_arg(ap, fu32_t);
4055 va_end(ap); */
4015 4056
4016 debug_printf("ssi: syncing local list and server list\n"); 4057 debug_printf("ssi: syncing local list and server list\n");
4017 4058
4018 if (odata->icq)
4019 return 1;
4020
4021 /* Activate SSI */ 4059 /* Activate SSI */
4060 /* Sending the enable causes other people to be able to see you */
4061 /* Maybe send it after merging the lists? */
4022 debug_printf("ssi: activating server-stored buddy list\n"); 4062 debug_printf("ssi: activating server-stored buddy list\n");
4023 aim_ssi_enable(sess, fr->conn); 4063 aim_ssi_enable(sess, fr->conn);
4024 4064
4025 /* Clean the buddy list */ 4065 /* Clean the buddy list */
4026 aim_ssi_cleanlist(sess, fr->conn); 4066 aim_ssi_cleanlist(sess, fr->conn);
4027 4067
4028 /* Add from server list to local list */ 4068 /* Add from server list to local list */
4029 tmp = 0; 4069 tmp = 0;
4030 for (curitem=sess->ssi.items; curitem; curitem=curitem->next) { 4070 for (curitem=sess->ssi.local; curitem; curitem=curitem->next) {
4031 switch (curitem->type) { 4071 switch (curitem->type) {
4032 case 0x0000: /* Buddy */ 4072 case 0x0000: { /* Buddy */
4033 if ((curitem->name) && (!find_buddy(gc, curitem->name))) { 4073 if ((curitem->name) && (!find_buddy(gc, curitem->name))) {
4034 struct aim_ssi_item *curgroup = sess->ssi.items; 4074 char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, curitem->name);
4035 while (curgroup) { 4075 char *alias = aim_ssi_getalias(sess->ssi.local, gname, curitem->name);
4036 if ((curgroup->type == 0x0001) && (curgroup->gid == curitem->gid) && (curgroup->name)) { 4076 debug_printf("ssi: adding buddy %s to group %s to local list\n", curitem->name, gname);
4037 debug_printf("ssi: adding buddy %s to group %s to local list\n", curitem->name, curgroup->name); 4077 add_buddy(gc, (gname ? gname : "orphans"), curitem->name, alias);
4038 add_buddy(gc, curgroup->name, curitem->name, 0); 4078 free(alias);
4039 tmp++; 4079 tmp++;
4040 }
4041 curgroup = curgroup->next;
4042 }
4043 } 4080 }
4044 break; 4081 } break;
4045 4082
4046 case 0x0002: /* Permit buddy */ 4083 case 0x0001: { /* Group */
4084 if (curitem->name && !find_group(gc, curitem->name))
4085 add_group(gc, curitem->name);
4086 } break;
4087
4088 case 0x0002: { /* Permit buddy */
4047 if (curitem->name) { 4089 if (curitem->name) {
4090 /* if (!find_permdeny_by_name(gc->permit, curitem->name)) { AAA */
4048 GSList *list; 4091 GSList *list;
4049 for (list=gc->permit; (list && aim_sncmp(curitem->name, list->data)); list=list->next); 4092 for (list=gc->permit; (list && aim_sncmp(curitem->name, list->data)); list=list->next);
4050 if (!list) { 4093 if (!list) {
4051 char *name; 4094 char *name;
4052 debug_printf("ssi: adding permit buddy %s to local list\n", curitem->name); 4095 debug_printf("ssi: adding permit buddy %s to local list\n", curitem->name);
4054 gc->permit = g_slist_append(gc->permit, name); 4097 gc->permit = g_slist_append(gc->permit, name);
4055 build_allow_list(); 4098 build_allow_list();
4056 tmp++; 4099 tmp++;
4057 } 4100 }
4058 } 4101 }
4059 break; 4102 } break;
4060 4103
4061 case 0x0003: /* Deny buddy */ 4104 case 0x0003: { /* Deny buddy */
4062 if (curitem->name) { 4105 if (curitem->name) {
4063 GSList *list; 4106 GSList *list;
4064 for (list=gc->deny; (list && aim_sncmp(curitem->name, list->data)); list=list->next); 4107 for (list=gc->deny; (list && aim_sncmp(curitem->name, list->data)); list=list->next);
4065 if (!list) { 4108 if (!list) {
4066 char *name; 4109 char *name;
4069 gc->deny = g_slist_append(gc->deny, name); 4112 gc->deny = g_slist_append(gc->deny, name);
4070 build_block_list(); 4113 build_block_list();
4071 tmp++; 4114 tmp++;
4072 } 4115 }
4073 } 4116 }
4074 break; 4117 } break;
4075 4118
4076 case 0x0004: /* Permit/deny setting */ 4119 case 0x0004: { /* Permit/deny setting */
4077 if (curitem->data) { 4120 if (curitem->data) {
4078 fu8_t permdeny; 4121 fu8_t permdeny;
4079 if ((permdeny = aim_ssi_getpermdeny(sess->ssi.items)) && (permdeny != gc->permdeny)) { 4122 if ((permdeny = aim_ssi_getpermdeny(sess->ssi.local)) && (permdeny != gc->permdeny)) {
4080 debug_printf("ssi: changing permdeny from %d to %d\n", gc->permdeny, permdeny); 4123 debug_printf("ssi: changing permdeny from %d to %hhu\n", gc->permdeny, permdeny);
4081 gc->permdeny = permdeny; 4124 gc->permdeny = permdeny;
4082 tmp++; 4125 tmp++;
4083 } 4126 }
4084 } 4127 }
4085 break; 4128 } break;
4086 4129
4087 case 0x0005: /* Presence setting */ 4130 case 0x0005: { /* Presence setting */
4088 /* We don't want to change Gaim's setting because it applies to all accounts */ 4131 /* We don't want to change Gaim's setting because it applies to all accounts */
4089 break; 4132 } break;
4090 } /* End of switch on curitem->type */ 4133 } /* End of switch on curitem->type */
4091 } /* End of for loop */ 4134 } /* End of for loop */
4135
4136 /* If changes were made, then flush buddy list to file */
4092 if (tmp) 4137 if (tmp)
4093 do_export(gc); 4138 do_export(gc);
4094 4139
4095 /* Add from local list to server list */ 4140 /* Add from local list to server list */
4096 if (gc) { 4141 if (gc) {
4098 4143
4099 /* Buddies */ 4144 /* Buddies */
4100 cur = gc->groups; 4145 cur = gc->groups;
4101 while (cur) { 4146 while (cur) {
4102 GSList *curbud; 4147 GSList *curbud;
4103 tmp = 0;
4104 for (curbud=((struct group*)cur->data)->members; curbud; curbud=curbud->next) 4148 for (curbud=((struct group*)cur->data)->members; curbud; curbud=curbud->next)
4105 if (!aim_ssi_itemlist_finditem(sess->ssi.items, NULL, ((struct buddy*)curbud->data)->name, 0x0000)) 4149 if (!aim_ssi_itemlist_exists(sess->ssi.local, ((struct buddy*)curbud->data)->name)) {
4106 tmp++; 4150 debug_printf("ssi: adding buddy %s from local list to server list\n", ((struct buddy*)curbud->data)->name);
4107 if (tmp) { 4151 aim_ssi_addbuddy(od->sess, od->conn, ((struct buddy*)curbud->data)->name, ((struct group*)cur->data)->name, get_buddy_alias_only((struct buddy *)curbud->data), NULL, NULL, 0);
4108 sns = malloc(tmp*sizeof(char*)); 4152 }
4109 tmp = 0;
4110 for (curbud=((struct group*)cur->data)->members; curbud; curbud=curbud->next)
4111 if (!aim_ssi_itemlist_finditem(sess->ssi.items, NULL, ((struct buddy*)curbud->data)->name, 0x0000)) {
4112 debug_printf("ssi: adding buddy %s from local list to server list\n", ((struct buddy*)curbud->data)->name);
4113 sns[tmp] = ((char *)((struct buddy*)curbud->data)->name);
4114 tmp++;
4115 }
4116 aim_ssi_addbuddies(sess, fr->conn, ((struct group*)cur->data)->name, sns, tmp);
4117 free(sns);
4118 }
4119 cur = g_slist_next(cur); 4153 cur = g_slist_next(cur);
4120 } 4154 }
4121 4155
4122 /* Permit list */ 4156 /* Permit list */
4123 if (gc->permit) { 4157 if (gc->permit) {
4124 tmp = 0;
4125 for (cur=gc->permit; cur; cur=cur->next) 4158 for (cur=gc->permit; cur; cur=cur->next)
4126 if (!aim_ssi_itemlist_finditem(sess->ssi.items, NULL, cur->data, 0x0002)) 4159 if (!aim_ssi_itemlist_finditem(sess->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) {
4127 tmp++; 4160 debug_printf("ssi: adding permit %s from local list to server list\n", (char *)cur->data);
4128 if (tmp) { 4161 aim_ssi_addpermit(od->sess, od->conn, cur->data);
4129 sns = malloc(tmp*sizeof(char*)); 4162 }
4130 tmp = 0;
4131 for (cur=gc->permit; cur; cur=cur->next)
4132 if (!aim_ssi_itemlist_finditem(sess->ssi.items, NULL, cur->data, 0x0002)) {
4133 debug_printf("ssi: adding permit %s from local list to server list\n", (char *)cur->data);
4134 sns[tmp] = cur->data;
4135 tmp++;
4136 }
4137 aim_ssi_addpord(sess, fr->conn, sns, tmp, AIM_SSI_TYPE_PERMIT);
4138 free(sns);
4139 }
4140 } 4163 }
4141 4164
4142 /* Deny list */ 4165 /* Deny list */
4143 if (gc->deny) { 4166 if (gc->deny) {
4144 tmp = 0;
4145 for (cur=gc->deny; cur; cur=cur->next) 4167 for (cur=gc->deny; cur; cur=cur->next)
4146 if (!aim_ssi_itemlist_finditem(sess->ssi.items, NULL, cur->data, 0x0003)) 4168 if (!aim_ssi_itemlist_finditem(sess->ssi.local, NULL, cur->data, AIM_SSI_TYPE_DENY)) {
4147 tmp++; 4169 debug_printf("ssi: adding deny %s from local list to server list\n", (char *)cur->data);
4148 if (tmp) { 4170 aim_ssi_adddeny(od->sess, od->conn, cur->data);
4149 sns = malloc(tmp*sizeof(char*)); 4171 }
4150 tmp = 0;
4151 for (cur=gc->deny; cur; cur=cur->next)
4152 if (!aim_ssi_itemlist_finditem(sess->ssi.items, NULL, cur->data, 0x0003)) {
4153 debug_printf("ssi: adding deny %s from local list to server list\n", (char *)cur->data);
4154 sns[tmp] = cur->data;
4155 tmp++;
4156 }
4157 aim_ssi_addpord(sess, fr->conn, sns, tmp, AIM_SSI_TYPE_DENY);
4158 free(sns);
4159 }
4160 } 4172 }
4161 4173
4162 /* Presence settings (idle time visibility) */ 4174 /* Presence settings (idle time visibility) */
4163 if ((tmp = aim_ssi_getpresence(sess->ssi.items)) != 0xFFFFFFFF) 4175 if ((tmp = aim_ssi_getpresence(sess->ssi.local)) != 0xFFFFFFFF)
4164 if (report_idle && !(tmp & 0x400)) 4176 if (report_idle && !(tmp & 0x400))
4165 aim_ssi_setpresence(sess, fr->conn, tmp | 0x400); 4177 aim_ssi_setpresence(sess, fr->conn, tmp | 0x400);
4166 4178
4167 /* Check for maximum number of buddies */ 4179 /* Check for maximum number of buddies */
4168 for (cur=gc->groups, tmp=0; cur; cur=g_slist_next(cur)) { 4180 for (cur=gc->groups, tmp=0; cur; cur=g_slist_next(cur)) {
4169 struct group* gr = (struct group*)cur->data; 4181 struct group* gr = (struct group*)cur->data;
4170 tmp = tmp + g_slist_length(gr->members); 4182 tmp = tmp + g_slist_length(gr->members);
4171 } 4183 }
4172 if (tmp > odata->rights.maxbuddies) { 4184 if (tmp > od->rights.maxbuddies) {
4173 char *dialog_msg = g_strdup_printf(_("The maximum number of buddies allowed in your buddy list is %d, and you have %d." 4185 char *dialog_msg = g_strdup_printf(_("The maximum number of buddies allowed in your buddy list is %d, and you have %d."
4174 " Until you are below the limit, some buddies will not show up as online."), 4186 " Until you are below the limit, some buddies will not show up as online."),
4175 odata->rights.maxbuddies, tmp); 4187 od->rights.maxbuddies, tmp);
4176 do_error_dialog("Maximum buddy list length exceeded.", dialog_msg, GAIM_WARNING); 4188 do_error_dialog("Maximum buddy list length exceeded.", dialog_msg, GAIM_WARNING);
4177 g_free(dialog_msg); 4189 g_free(dialog_msg);
4178 } 4190 }
4179 4191
4180 } /* end if (gc) */ 4192 } /* end if (gc) */
4193
4194 return 1;
4195 }
4196 #endif
4197
4198 static int gaim_ssi_parseack(aim_session_t *sess, aim_frame_t *fr, ...) {
4199 struct gaim_connection *gc = sess->aux_data;
4200 va_list ap;
4201 struct aim_ssi_tmp *retval;
4202
4203 va_start(ap, fr);
4204 retval = va_arg(ap, struct aim_ssi_tmp *);
4205 va_end(ap);
4206
4207 while (retval) {
4208 debug_printf("ssi: status is 0x%04hx for a 0x%04hx action with name %s\n", retval->ack, retval->action, retval->item ? retval->item->name : "no item");
4209
4210 if (retval->ack != 0xffff)
4211 switch (retval->ack) {
4212 case 0x0000: { /* added successfully */
4213 } break;
4214
4215 case 0x000e: { /* contact requires authorization */
4216 if (retval->action == AIM_CB_SSI_ADD) {
4217 struct name_data *data = g_new(struct name_data, 1);
4218 gchar *dialog_msg = g_strdup_printf(_("The user %s requires authorization before being added to a buddy list. Do you want to send an authorization request?"), retval->name);
4219 data->gc = gc;
4220 data->name = g_strdup(retval->name);
4221 data->nick = NULL;
4222 do_ask_dialog(_("Request Authorization"), dialog_msg, data, _("Request Authorization"), gaim_auth_request, _("Cancel"), gaim_auth_dontrequest);
4223 g_free(dialog_msg);
4224 }
4225 } break;
4226
4227 default: { /* La la la */
4228 debug_printf("ssi: Action 0x%04hx was unsuccessful with error 0x%04hx\n", retval->action, retval->ack);
4229 /* Should remove buddy from local list and give an error message? */
4230 } break;
4231 }
4232
4233 retval = retval->next;
4234 }
4235
4236 return 1;
4237 }
4238
4239 static int gaim_ssi_authgiven(aim_session_t *sess, aim_frame_t *fr, ...) {
4240 struct gaim_connection *gc = sess->aux_data;
4241 va_list ap;
4242 char *sn, *msg;
4243 gchar *dialog_msg;
4244 struct name_data *data;
4245
4246 va_start(ap, fr);
4247 sn = va_arg(ap, char *);
4248 msg = va_arg(ap, char *);
4249 va_end(ap);
4250
4251 debug_printf("ssi: %s has given you permission to add him to your buddy list\n", sn);
4252
4253 dialog_msg = g_strdup_printf(_("The user %s has given you permission to add you to their buddy list. Do you want to add them?"), sn);
4254 data = g_new(struct name_data, 1);
4255 data->gc = gc;
4256 data->name = g_strdup(sn);
4257 data->nick = NULL;
4258 do_ask_dialog(_("Authorization Given"), dialog_msg, data, _("Yes"), gaim_icq_contactadd, _("No"), gaim_free_name_data);
4259 g_free(dialog_msg);
4260
4261 return 1;
4262 }
4263
4264 static int gaim_ssi_authrequest(aim_session_t *sess, aim_frame_t *fr, ...) {
4265 struct gaim_connection *gc = sess->aux_data;
4266 va_list ap;
4267 char *sn, *msg;
4268 gchar *dialog_msg;
4269 struct name_data *data;
4270
4271 va_start(ap, fr);
4272 sn = va_arg(ap, char *);
4273 msg = va_arg(ap, char *);
4274 va_end(ap);
4275
4276 debug_printf("ssi: received authorization request from %s\n", sn);
4277
4278 dialog_msg = g_strdup_printf(_("The user %s wants to add you to their buddy list for the following reason: %s"), sn, msg ? msg : _("No reason given."));
4279 data = g_new(struct name_data, 1);
4280 data->gc = gc;
4281 data->name = g_strdup(sn);
4282 data->nick = NULL;
4283 do_ask_dialog(_("Authorization Request"), dialog_msg, data, _("Authorize"), gaim_auth_grant, _("Deny"), gaim_auth_dontgrant);
4284 g_free(dialog_msg);
4285
4286 return 1;
4287 }
4288
4289 static int gaim_ssi_authreply(aim_session_t *sess, aim_frame_t *fr, ...) {
4290 va_list ap;
4291 char *sn, *msg;
4292 gchar *dialog_msg;
4293 fu8_t reply;
4294
4295 va_start(ap, fr);
4296 sn = va_arg(ap, char *);
4297 reply = (fu8_t)va_arg(ap, int);
4298 msg = va_arg(ap, char *);
4299 va_end(ap);
4300
4301 if (reply) {
4302 /* Granted */
4303 dialog_msg = g_strdup_printf(_("The user %s has granted your request to add them to your contact list."), sn);
4304 do_error_dialog(_("Authorization Granted"), dialog_msg, GAIM_INFO);
4305 } else {
4306 /* Denied */
4307 dialog_msg = g_strdup_printf(_("The user %s has denied your request to add them to your contact list for the following reason:\n%s"), sn, msg ? msg : _("No reason given."));
4308 do_error_dialog(_("Authorization Denied"), dialog_msg, GAIM_INFO);
4309 }
4310 g_free(dialog_msg);
4311
4312 return 1;
4313 }
4314
4315 static int gaim_ssi_gotadded(aim_session_t *sess, aim_frame_t *fr, ...) {
4316 struct gaim_connection *gc = sess->aux_data;
4317 va_list ap;
4318 char *sn;
4319
4320 va_start(ap, fr);
4321 sn = va_arg(ap, char *);
4322 va_end(ap);
4323
4324 debug_printf("ssi: %s added you to their buddy list\n", sn);
4325 show_got_added(gc, NULL, sn, NULL, NULL);
4181 4326
4182 return 1; 4327 return 1;
4183 } 4328 }
4184 4329
4185 static GList *oscar_chat_info(struct gaim_connection *gc) { 4330 static GList *oscar_chat_info(struct gaim_connection *gc) {
4723 return m; 4868 return m;
4724 } 4869 }
4725 4870
4726 static void oscar_set_permit_deny(struct gaim_connection *gc) { 4871 static void oscar_set_permit_deny(struct gaim_connection *gc) {
4727 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 4872 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4728 if (od->icq) { 4873 #ifdef NOSSI
4729 GSList *list, *g; 4874 GSList *list, *g;
4730 char buf[MAXMSGLEN]; 4875 char buf[MAXMSGLEN];
4731 int at; 4876 int at;
4732 4877
4733 switch(gc->permdeny) { 4878 switch(gc->permdeny) {
4734 case 1: 4879 case 1:
4735 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_DENYADD, gc->username); 4880 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_DENYADD, gc->username);
4736 break; 4881 break;
4737 case 2: 4882 case 2:
4738 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, gc->username); 4883 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, gc->username);
4739 break; 4884 break;
4740 case 3: 4885 case 3:
4741 list = gc->permit; 4886 list = gc->permit;
4742 at = 0; 4887 at = 0;
4888 while (list) {
4889 at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", (char *)list->data);
4890 list = list->next;
4891 }
4892 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, buf);
4893 break;
4894 case 4:
4895 list = gc->deny;
4896 at = 0;
4897 while (list) {
4898 at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", (char *)list->data);
4899 list = list->next;
4900 }
4901 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_DENYADD, buf);
4902 break;
4903 case 5:
4904 g = gc->groups;
4905 at = 0;
4906 while (g) {
4907 list = ((struct group *)g->data)->members;
4743 while (list) { 4908 while (list) {
4744 at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", (char *)list->data); 4909 at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", ((struct buddy *)list->data)->name);
4745 list = list->next; 4910 list = list->next;
4746 } 4911 }
4747 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, buf); 4912 g = g->next;
4748 break; 4913 }
4749 case 4: 4914 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, buf);
4750 list = gc->deny; 4915 break;
4751 at = 0; 4916 default:
4752 while (list) { 4917 break;
4753 at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", (char *)list->data); 4918 }
4754 list = list->next; 4919 signoff_blocked(gc);
4755 } 4920 #else
4756 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_DENYADD, buf); 4921 if (od->sess->ssi.received_data)
4757 break; 4922 aim_ssi_setpermdeny(od->sess, od->conn, gc->permdeny, 0xffffffff);
4758 case 5: 4923 #endif
4759 g = gc->groups;
4760 at = 0;
4761 while (g) {
4762 list = ((struct group *)g->data)->members;
4763 while (list) {
4764 at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", ((struct buddy *)list->data)->name);
4765 list = list->next;
4766 }
4767 g = g->next;
4768 }
4769 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, buf);
4770 break;
4771 default:
4772 break;
4773 }
4774 signoff_blocked(gc);
4775 } else {
4776 if (od->sess->ssi.received_data)
4777 aim_ssi_setpermdeny(od->sess, od->conn, gc->permdeny, 0xffffffff);
4778 }
4779 } 4924 }
4780 4925
4781 static void oscar_add_permit(struct gaim_connection *gc, char *who) { 4926 static void oscar_add_permit(struct gaim_connection *gc, char *who) {
4782 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 4927 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4783 if (od->icq) { 4928 #ifdef NOSSI
4784 if (gc->permdeny != 3) return; 4929 if (gc->permdeny != 3) return;
4785 oscar_set_permit_deny(gc); 4930 oscar_set_permit_deny(gc);
4786 } else { 4931 #else
4787 debug_printf("ssi: About to add a permit\n"); 4932 debug_printf("ssi: About to add a permit\n");
4788 if (od->sess->ssi.received_data) 4933 if (od->sess->ssi.received_data)
4789 aim_ssi_addpord(od->sess, od->conn, (const char **) &who, 1, AIM_SSI_TYPE_PERMIT); 4934 aim_ssi_addpermit(od->sess, od->conn, who);
4790 } 4935 #endif
4791 } 4936 }
4792 4937
4793 static void oscar_add_deny(struct gaim_connection *gc, char *who) { 4938 static void oscar_add_deny(struct gaim_connection *gc, char *who) {
4794 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 4939 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4795 if (od->icq) { 4940 #ifdef NOSSI
4796 if (gc->permdeny != 4) return; 4941 if (gc->permdeny != 4) return;
4797 oscar_set_permit_deny(gc); 4942 oscar_set_permit_deny(gc);
4798 } else { 4943 #else
4799 debug_printf("ssi: About to add a deny\n"); 4944 debug_printf("ssi: About to add a deny\n");
4800 if (od->sess->ssi.received_data) 4945 if (od->sess->ssi.received_data)
4801 aim_ssi_addpord(od->sess, od->conn, (const char **) &who, 1, AIM_SSI_TYPE_DENY); 4946 aim_ssi_adddeny(od->sess, od->conn, who);
4802 } 4947 #endif
4803 } 4948 }
4804 4949
4805 static void oscar_rem_permit(struct gaim_connection *gc, char *who) { 4950 static void oscar_rem_permit(struct gaim_connection *gc, char *who) {
4806 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 4951 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4807 if (od->icq) { 4952 #ifdef NOSSI
4808 if (gc->permdeny != 3) return; 4953 if (gc->permdeny != 3) return;
4809 oscar_set_permit_deny(gc); 4954 oscar_set_permit_deny(gc);
4810 } else { 4955 #else
4811 debug_printf("ssi: About to delete a permit\n"); 4956 debug_printf("ssi: About to delete a permit\n");
4812 if (od->sess->ssi.received_data) 4957 if (od->sess->ssi.received_data)
4813 aim_ssi_delpord(od->sess, od->conn, (const char **) &who, 1, AIM_SSI_TYPE_PERMIT); 4958 aim_ssi_delpermit(od->sess, od->conn, who);
4814 } 4959 #endif
4815 } 4960 }
4816 4961
4817 static void oscar_rem_deny(struct gaim_connection *gc, char *who) { 4962 static void oscar_rem_deny(struct gaim_connection *gc, char *who) {
4818 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 4963 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4819 if (od->icq) { 4964 #ifdef NOSSI
4820 if (gc->permdeny != 4) return; 4965 if (gc->permdeny != 4) return;
4821 oscar_set_permit_deny(gc); 4966 oscar_set_permit_deny(gc);
4822 } else { 4967 #else
4823 debug_printf("ssi: About to delete a deny\n"); 4968 debug_printf("ssi: About to delete a deny\n");
4824 if (od->sess->ssi.received_data) 4969 if (od->sess->ssi.received_data)
4825 aim_ssi_delpord(od->sess, od->conn, (const char **) &who, 1, AIM_SSI_TYPE_DENY); 4970 aim_ssi_deldeny(od->sess, od->conn, who);
4826 } 4971 #endif
4827 } 4972 }
4828 4973
4829 static GList *oscar_away_states(struct gaim_connection *gc) 4974 static GList *oscar_away_states(struct gaim_connection *gc)
4830 { 4975 {
4831 struct oscar_data *od = gc->proto_data; 4976 struct oscar_data *od = gc->proto_data;
5035 ret->dir_search = oscar_dir_search; 5180 ret->dir_search = oscar_dir_search;
5036 ret->set_idle = oscar_set_idle; 5181 ret->set_idle = oscar_set_idle;
5037 ret->change_passwd = oscar_change_passwd; 5182 ret->change_passwd = oscar_change_passwd;
5038 ret->add_buddy = oscar_add_buddy; 5183 ret->add_buddy = oscar_add_buddy;
5039 ret->add_buddies = oscar_add_buddies; 5184 ret->add_buddies = oscar_add_buddies;
5185 #ifndef NOSSI
5040 ret->group_buddy = oscar_move_buddy; 5186 ret->group_buddy = oscar_move_buddy;
5041 ret->rename_group = oscar_rename_group; 5187 ret->rename_group = oscar_rename_group;
5188 #endif
5042 ret->file_transfer_cancel = oscar_file_transfer_cancel; 5189 ret->file_transfer_cancel = oscar_file_transfer_cancel;
5043 ret->file_transfer_in = oscar_file_transfer_in; 5190 ret->file_transfer_in = oscar_file_transfer_in;
5044 ret->file_transfer_out = oscar_file_transfer_out; 5191 ret->file_transfer_out = oscar_file_transfer_out;
5045 ret->file_transfer_data_chunk = oscar_file_transfer_data_chunk; 5192 ret->file_transfer_data_chunk = oscar_file_transfer_data_chunk;
5046 ret->file_transfer_nextfile = oscar_file_transfer_nextfile; 5193 ret->file_transfer_nextfile = oscar_file_transfer_nextfile;