comparison src/protocols/oscar/family_locate.c @ 13592:6519aeb66b31

[gaim-migrate @ 15978] Holy cow this is crazy. 34 files changed, 5760 insertions(+), 8517 deletions(-) * Non-blocking I/O for all of oscar. That includes normal FLAP connections as well as file transfers and direct IM. * Kick-ass file transfer and direct IM. Either party can request the connection. Gaim will try both the "public" IP and the "client" IP. It'll fall back to transferring through a proxy if that fails. Should be relatively few memleaks (I didn't have a lot of confidence in the non-memleakiness of the old code). And the code is reasonably generic, so it shouldn't be too much work to add voice chat. This might still be a LITTLE buggy, but it shouldn't be too bad. If anything, file transfer will be more buggy than direct IM. And sending a file will be more buggy than receiving a file. Bug reports with a series of steps to reproduce are welcome. * I merged OscarData and aim_session_t * Somewhere between 50 and 100 hours of work. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Fri, 07 Apr 2006 05:10:56 +0000
parents 87a7c3077c19
children 4d8927a4f1ef
comparison
equal deleted inserted replaced
13591:dcfda39ad547 13592:6519aeb66b31
49 /* 49 /*
50 * These are in ascending numerical order. 50 * These are in ascending numerical order.
51 */ 51 */
52 52
53 /* 53 /*
54 * Perhaps better called AIM_CAPS_SHORTCAPS 54 * Perhaps better called OSCAR_CAPABILITY_SHORTCAPS
55 */ 55 */
56 {AIM_CAPS_ICHAT, 56 {OSCAR_CAPABILITY_ICHAT,
57 {0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 57 {0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1,
58 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 58 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
59 59
60 {AIM_CAPS_SECUREIM, 60 {OSCAR_CAPABILITY_SECUREIM,
61 {0x09, 0x46, 0x00, 0x01, 0x4c, 0x7f, 0x11, 0xd1, 61 {0x09, 0x46, 0x00, 0x01, 0x4c, 0x7f, 0x11, 0xd1,
62 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 62 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
63 63
64 {AIM_CAPS_VIDEO, 64 {OSCAR_CAPABILITY_VIDEO,
65 {0x09, 0x46, 0x01, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 65 {0x09, 0x46, 0x01, 0x00, 0x4c, 0x7f, 0x11, 0xd1,
66 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 66 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
67 67
68 /* "Live Video" support in Windows AIM 5.5.3501 and newer */ 68 /* "Live Video" support in Windows AIM 5.5.3501 and newer */
69 {AIM_CAPS_LIVEVIDEO, 69 {OSCAR_CAPABILITY_LIVEVIDEO,
70 {0x09, 0x46, 0x01, 0x01, 0x4c, 0x7f, 0x11, 0xd1, 70 {0x09, 0x46, 0x01, 0x01, 0x4c, 0x7f, 0x11, 0xd1,
71 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 71 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
72 72
73 /* "Camera" support in Windows AIM 5.5.3501 and newer */ 73 /* "Camera" support in Windows AIM 5.5.3501 and newer */
74 {AIM_CAPS_CAMERA, 74 {OSCAR_CAPABILITY_CAMERA,
75 {0x09, 0x46, 0x01, 0x02, 0x4c, 0x7f, 0x11, 0xd1, 75 {0x09, 0x46, 0x01, 0x02, 0x4c, 0x7f, 0x11, 0xd1,
76 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 76 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
77 77
78 /* In Windows AIM 5.5.3501 and newer */ 78 /* In Windows AIM 5.5.3501 and newer */
79 {AIM_CAPS_GENERICUNKNOWN, 79 {OSCAR_CAPABILITY_GENERICUNKNOWN,
80 {0x09, 0x46, 0x01, 0x03, 0x4c, 0x7f, 0x11, 0xd1, 80 {0x09, 0x46, 0x01, 0x03, 0x4c, 0x7f, 0x11, 0xd1,
81 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 81 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
82 82
83 /* In iChatAV (version numbers...?) */ 83 /* In iChatAV (version numbers...?) */
84 {AIM_CAPS_ICHATAV, 84 {OSCAR_CAPABILITY_ICHATAV,
85 {0x09, 0x46, 0x01, 0x05, 0x4c, 0x7f, 0x11, 0xd1, 85 {0x09, 0x46, 0x01, 0x05, 0x4c, 0x7f, 0x11, 0xd1,
86 0x82, 0x22, 0x44, 0x45, 0x45, 0x53, 0x54, 0x00}}, 86 0x82, 0x22, 0x44, 0x45, 0x45, 0x53, 0x54, 0x00}},
87 87
88 /* 88 /*
89 * Not really sure about this one. In an email from 89 * Not really sure about this one. In an email from
90 * 26 Sep 2003, Matthew Sachs suggested that, "this 90 * 26 Sep 2003, Matthew Sachs suggested that, "this
91 * is probably the capability for the SMS features." 91 * is probably the capability for the SMS features."
92 */ 92 */
93 {AIM_CAPS_SMS, 93 {OSCAR_CAPABILITY_SMS,
94 {0x09, 0x46, 0x01, 0xff, 0x4c, 0x7f, 0x11, 0xd1, 94 {0x09, 0x46, 0x01, 0xff, 0x4c, 0x7f, 0x11, 0xd1,
95 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 95 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
96 96
97 {AIM_CAPS_GENERICUNKNOWN, 97 {OSCAR_CAPABILITY_GENERICUNKNOWN,
98 {0x09, 0x46, 0xf0, 0x03, 0x4c, 0x7f, 0x11, 0xd1, 98 {0x09, 0x46, 0xf0, 0x03, 0x4c, 0x7f, 0x11, 0xd1,
99 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 99 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
100 100
101 {AIM_CAPS_GENERICUNKNOWN, 101 {OSCAR_CAPABILITY_GENERICUNKNOWN,
102 {0x09, 0x46, 0xf0, 0x04, 0x4c, 0x7f, 0x11, 0xd1, 102 {0x09, 0x46, 0xf0, 0x04, 0x4c, 0x7f, 0x11, 0xd1,
103 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 103 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
104 104
105 {AIM_CAPS_GENERICUNKNOWN, 105 {OSCAR_CAPABILITY_GENERICUNKNOWN,
106 {0x09, 0x46, 0xf0, 0x05, 0x4c, 0x7f, 0x11, 0xd1, 106 {0x09, 0x46, 0xf0, 0x05, 0x4c, 0x7f, 0x11, 0xd1,
107 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 107 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
108 108
109 {AIM_CAPS_HIPTOP, 109 {OSCAR_CAPABILITY_HIPTOP,
110 {0x09, 0x46, 0x13, 0x23, 0x4c, 0x7f, 0x11, 0xd1, 110 {0x09, 0x46, 0x13, 0x23, 0x4c, 0x7f, 0x11, 0xd1,
111 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 111 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
112 112
113 {AIM_CAPS_TALK, 113 {OSCAR_CAPABILITY_TALK,
114 {0x09, 0x46, 0x13, 0x41, 0x4c, 0x7f, 0x11, 0xd1, 114 {0x09, 0x46, 0x13, 0x41, 0x4c, 0x7f, 0x11, 0xd1,
115 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 115 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
116 116
117 {AIM_CAPS_SENDFILE, 117 {OSCAR_CAPABILITY_SENDFILE,
118 {0x09, 0x46, 0x13, 0x43, 0x4c, 0x7f, 0x11, 0xd1, 118 {0x09, 0x46, 0x13, 0x43, 0x4c, 0x7f, 0x11, 0xd1,
119 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 119 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
120 120
121 {AIM_CAPS_ICQ_DIRECT, 121 {OSCAR_CAPABILITY_ICQ_DIRECT,
122 {0x09, 0x46, 0x13, 0x44, 0x4c, 0x7f, 0x11, 0xd1, 122 {0x09, 0x46, 0x13, 0x44, 0x4c, 0x7f, 0x11, 0xd1,
123 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 123 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
124 124
125 {AIM_CAPS_DIRECTIM, 125 {OSCAR_CAPABILITY_DIRECTIM,
126 {0x09, 0x46, 0x13, 0x45, 0x4c, 0x7f, 0x11, 0xd1, 126 {0x09, 0x46, 0x13, 0x45, 0x4c, 0x7f, 0x11, 0xd1,
127 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 127 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
128 128
129 {AIM_CAPS_BUDDYICON, 129 {OSCAR_CAPABILITY_BUDDYICON,
130 {0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1, 130 {0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1,
131 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 131 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
132 132
133 {AIM_CAPS_ADDINS, 133 {OSCAR_CAPABILITY_ADDINS,
134 {0x09, 0x46, 0x13, 0x47, 0x4c, 0x7f, 0x11, 0xd1, 134 {0x09, 0x46, 0x13, 0x47, 0x4c, 0x7f, 0x11, 0xd1,
135 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 135 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
136 136
137 {AIM_CAPS_GETFILE, 137 {OSCAR_CAPABILITY_GETFILE,
138 {0x09, 0x46, 0x13, 0x48, 0x4c, 0x7f, 0x11, 0xd1, 138 {0x09, 0x46, 0x13, 0x48, 0x4c, 0x7f, 0x11, 0xd1,
139 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 139 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
140 140
141 {AIM_CAPS_ICQSERVERRELAY, 141 {OSCAR_CAPABILITY_ICQSERVERRELAY,
142 {0x09, 0x46, 0x13, 0x49, 0x4c, 0x7f, 0x11, 0xd1, 142 {0x09, 0x46, 0x13, 0x49, 0x4c, 0x7f, 0x11, 0xd1,
143 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 143 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
144 144
145 /* 145 /*
146 * Indeed, there are two of these. The former appears to be correct, 146 * Indeed, there are two of these. The former appears to be correct,
147 * but in some versions of winaim, the second one is set. Either they 147 * but in some versions of winaim, the second one is set. Either they
148 * forgot to fix endianness, or they made a typo. It really doesn't 148 * forgot to fix endianness, or they made a typo. It really doesn't
149 * matter which. 149 * matter which.
150 */ 150 */
151 {AIM_CAPS_GAMES, 151 {OSCAR_CAPABILITY_GAMES,
152 {0x09, 0x46, 0x13, 0x4a, 0x4c, 0x7f, 0x11, 0xd1, 152 {0x09, 0x46, 0x13, 0x4a, 0x4c, 0x7f, 0x11, 0xd1,
153 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 153 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
154 {AIM_CAPS_GAMES2, 154 {OSCAR_CAPABILITY_GAMES2,
155 {0x09, 0x46, 0x13, 0x4a, 0x4c, 0x7f, 0x11, 0xd1, 155 {0x09, 0x46, 0x13, 0x4a, 0x4c, 0x7f, 0x11, 0xd1,
156 0x22, 0x82, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 156 0x22, 0x82, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
157 157
158 {AIM_CAPS_SENDBUDDYLIST, 158 {OSCAR_CAPABILITY_SENDBUDDYLIST,
159 {0x09, 0x46, 0x13, 0x4b, 0x4c, 0x7f, 0x11, 0xd1, 159 {0x09, 0x46, 0x13, 0x4b, 0x4c, 0x7f, 0x11, 0xd1,
160 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 160 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
161 161
162 /* 162 /*
163 * Setting this lets AIM users receive messages from ICQ users, and ICQ 163 * Setting this lets AIM users receive messages from ICQ users, and ICQ
166 * for ICQ users. And ICQ privacy/invisibility acts like AIM privacy, 166 * for ICQ users. And ICQ privacy/invisibility acts like AIM privacy,
167 * in that if you add a user to your deny list, you will not be able to 167 * in that if you add a user to your deny list, you will not be able to
168 * see them as online (previous you could still see them, but they 168 * see them as online (previous you could still see them, but they
169 * couldn't see you. 169 * couldn't see you.
170 */ 170 */
171 {AIM_CAPS_INTEROPERATE, 171 {OSCAR_CAPABILITY_INTEROPERATE,
172 {0x09, 0x46, 0x13, 0x4d, 0x4c, 0x7f, 0x11, 0xd1, 172 {0x09, 0x46, 0x13, 0x4d, 0x4c, 0x7f, 0x11, 0xd1,
173 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 173 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
174 174
175 {AIM_CAPS_ICQUTF8, 175 {OSCAR_CAPABILITY_ICQUTF8,
176 {0x09, 0x46, 0x13, 0x4e, 0x4c, 0x7f, 0x11, 0xd1, 176 {0x09, 0x46, 0x13, 0x4e, 0x4c, 0x7f, 0x11, 0xd1,
177 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 177 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
178 178
179 {AIM_CAPS_ICQUTF8OLD, 179 {OSCAR_CAPABILITY_ICQUTF8OLD,
180 {0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8, 180 {0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8,
181 0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf}}, 181 0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf}},
182 182
183 /* 183 /*
184 * Chat is oddball. 184 * Chat is oddball.
185 */ 185 */
186 {AIM_CAPS_CHAT, 186 {OSCAR_CAPABILITY_CHAT,
187 {0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1, 187 {0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1,
188 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 188 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
189 189
190 /* 190 /*
191 {AIM_CAPS_ICQ2GO, 191 {OSCAR_CAPABILITY_ICQ2GO,
192 {0x56, 0x3f, 0xc8, 0x09, 0x0b, 0x6f, 0x41, 0xbd, 192 {0x56, 0x3f, 0xc8, 0x09, 0x0b, 0x6f, 0x41, 0xbd,
193 0x9f, 0x79, 0x42, 0x26, 0x09, 0xdf, 0xa2, 0xf3}}, 193 0x9f, 0x79, 0x42, 0x26, 0x09, 0xdf, 0xa2, 0xf3}},
194 */ 194 */
195 195
196 {AIM_CAPS_ICQRTF, 196 {OSCAR_CAPABILITY_ICQRTF,
197 {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 197 {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34,
198 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x92}}, 198 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x92}},
199 199
200 /* This is added by the servers and it only shows up for ourselves... */ 200 /* This is added by the servers and it only shows up for ourselves... */
201 {AIM_CAPS_GENERICUNKNOWN, 201 {OSCAR_CAPABILITY_GENERICUNKNOWN,
202 {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 202 {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34,
203 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x09}}, 203 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x09}},
204 204
205 {AIM_CAPS_APINFO, 205 {OSCAR_CAPABILITY_APINFO,
206 {0xaa, 0x4a, 0x32, 0xb5, 0xf8, 0x84, 0x48, 0xc6, 206 {0xaa, 0x4a, 0x32, 0xb5, 0xf8, 0x84, 0x48, 0xc6,
207 0xa3, 0xd7, 0x8c, 0x50, 0x97, 0x19, 0xfd, 0x5b}}, 207 0xa3, 0xd7, 0x8c, 0x50, 0x97, 0x19, 0xfd, 0x5b}},
208 208
209 {AIM_CAPS_TRILLIANCRYPT, 209 {OSCAR_CAPABILITY_TRILLIANCRYPT,
210 {0xf2, 0xe7, 0xc7, 0xf4, 0xfe, 0xad, 0x4d, 0xfb, 210 {0xf2, 0xe7, 0xc7, 0xf4, 0xfe, 0xad, 0x4d, 0xfb,
211 0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00}}, 211 0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00}},
212 212
213 {AIM_CAPS_EMPTY, 213 {OSCAR_CAPABILITY_EMPTY,
214 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 214 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
216 216
217 {AIM_CAPS_LAST, 217 {OSCAR_CAPABILITY_LAST,
218 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 218 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
220 }; 220 };
221 221
222 /* 222 /*
223 * Add the userinfo to our linked list. If we already have userinfo 223 * Add the userinfo to our linked list. If we already have userinfo
224 * for this buddy, then just overwrite parts of the old data. 224 * for this buddy, then just overwrite parts of the old data.
225 * 225 *
226 * @param userinfo Contains the new information for the buddy. 226 * @param userinfo Contains the new information for the buddy.
227 */ 227 */
228 static void aim_locate_adduserinfo(OscarSession *sess, aim_userinfo_t *userinfo) { 228 static void aim_locate_adduserinfo(OscarData *od, aim_userinfo_t *userinfo) {
229 aim_userinfo_t *cur; 229 aim_userinfo_t *cur;
230 OscarConnection *conn; 230 FlapConnection *conn;
231 aim_rxcallback_t userfunc; 231 aim_rxcallback_t userfunc;
232 232
233 cur = aim_locate_finduserinfo(sess, userinfo->sn); 233 cur = aim_locate_finduserinfo(od, userinfo->sn);
234 234
235 if (cur == NULL) { 235 if (cur == NULL) {
236 cur = (aim_userinfo_t *)calloc(1, sizeof(aim_userinfo_t)); 236 cur = (aim_userinfo_t *)calloc(1, sizeof(aim_userinfo_t));
237 cur->sn = strdup(userinfo->sn); 237 cur->sn = strdup(userinfo->sn);
238 cur->next = sess->locate.userinfo; 238 cur->next = od->locate.userinfo;
239 sess->locate.userinfo = cur; 239 od->locate.userinfo = cur;
240 } 240 }
241 241
242 cur->warnlevel = userinfo->warnlevel; 242 cur->warnlevel = userinfo->warnlevel;
243 cur->idletime = userinfo->idletime; 243 cur->idletime = userinfo->idletime;
244 if (userinfo->flags != 0) 244 if (userinfo->flags != 0)
305 * This callback can be used by a client if they want to know whenever 305 * This callback can be used by a client if they want to know whenever
306 * info for a buddy is updated. For example, if a client shows away 306 * info for a buddy is updated. For example, if a client shows away
307 * messages in its buddy list, then it would need to know if a user's 307 * messages in its buddy list, then it would need to know if a user's
308 * away message changes. 308 * away message changes.
309 */ 309 */
310 conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE); 310 conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE);
311 if ((userfunc = aim_callhandler(sess, conn, OSCAR_FAMILY_LOCATE, OSCAR_SUBTYPE_LOCATE_GOTINFOBLOCK))) 311 if ((userfunc = aim_callhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_GOTINFOBLOCK)))
312 userfunc(sess, NULL, cur); 312 userfunc(od, conn, NULL, cur);
313 } 313 }
314 314
315 faim_export void aim_locate_dorequest(OscarSession *sess) { 315 void aim_locate_dorequest(OscarData *od) {
316 struct userinfo_node *cur = sess->locate.torequest; 316 struct userinfo_node *cur = od->locate.torequest;
317 317
318 if (cur == NULL) 318 if (cur == NULL)
319 return; 319 return;
320 320
321 if (sess->locate.waiting_for_response == TRUE) 321 if (od->locate.waiting_for_response == TRUE)
322 return; 322 return;
323 323
324 sess->locate.waiting_for_response = TRUE; 324 od->locate.waiting_for_response = TRUE;
325 aim_locate_getinfoshort(sess, cur->sn, 0x00000003); 325 aim_locate_getinfoshort(od, cur->sn, 0x00000003);
326 326
327 /* Move this node to the "requested" queue */ 327 /* Move this node to the "requested" queue */
328 sess->locate.torequest = cur->next; 328 od->locate.torequest = cur->next;
329 cur->next = sess->locate.requested; 329 cur->next = od->locate.requested;
330 sess->locate.requested = cur; 330 od->locate.requested = cur;
331 }
332
333 static gboolean
334 gaim_reqinfo_timeout_cb(void *data)
335 {
336 OscarData *od;
337
338 od = data;
339 aim_locate_dorequest(od);
340 od->getinfotimer = 0;
341
342 return FALSE;
331 } 343 }
332 344
333 /** 345 /**
334 * Remove this screen name from our queue. If this info was requested 346 * Remove this screen name from our queue. If this info was requested
335 * by our info request queue, then pop the next element off of the queue. 347 * by our info request queue, then pop the next element off of the queue.
336 * 348 *
337 * @param sess The aim session. 349 * @param od The aim session.
338 * @param sn Screen name of the info we just received. 350 * @param sn Screen name of the info we just received.
339 * @return True if the request was explicit (client requested the info), 351 * @return True if the request was explicit (client requested the info),
340 * false if the request was implicit (libfaim request the info). 352 * false if the request was implicit (libfaim request the info).
341 */ 353 */
342 static int aim_locate_gotuserinfo(OscarSession *sess, const char *sn) { 354 static int
355 aim_locate_gotuserinfo(OscarData *od, FlapConnection *conn, const char *sn)
356 {
343 struct userinfo_node *cur, *del; 357 struct userinfo_node *cur, *del;
344 int was_explicit = TRUE; 358 int was_explicit = TRUE;
345 359
346 while ((sess->locate.requested != NULL) && (aim_sncmp(sn, sess->locate.requested->sn) == 0)) { 360 while ((od->locate.requested != NULL) && (aim_sncmp(sn, od->locate.requested->sn) == 0)) {
347 del = sess->locate.requested; 361 del = od->locate.requested;
348 sess->locate.requested = del->next; 362 od->locate.requested = del->next;
349 was_explicit = FALSE; 363 was_explicit = FALSE;
350 free(del->sn); 364 free(del->sn);
351 free(del); 365 free(del);
352 } 366 }
353 367
354 cur = sess->locate.requested; 368 cur = od->locate.requested;
355 while ((cur != NULL) && (cur->next != NULL)) { 369 while ((cur != NULL) && (cur->next != NULL)) {
356 if (aim_sncmp(sn, cur->next->sn) == 0) { 370 if (aim_sncmp(sn, cur->next->sn) == 0) {
357 del = cur->next; 371 del = cur->next;
358 cur->next = del->next; 372 cur->next = del->next;
359 was_explicit = FALSE; 373 was_explicit = FALSE;
362 } else 376 } else
363 cur = cur->next; 377 cur = cur->next;
364 } 378 }
365 379
366 if (!was_explicit) { 380 if (!was_explicit) {
367 OscarConnection *conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE); 381 od->locate.waiting_for_response = FALSE;
368 aim_rxcallback_t userfunc; 382
369 383 /*
370 sess->locate.waiting_for_response = FALSE; 384 * Wait a little while then call aim_locate_dorequest(od).
371 385 * This keeps us from hitting the rate limit due to
372 if ((userfunc = aim_callhandler(sess, conn, OSCAR_FAMILY_LOCATE, OSCAR_SUBTYPE_LOCATE_REQUESTINFOTIMEOUT))) 386 * requesting away messages and info too quickly.
373 userfunc(sess, NULL); 387 */
374 else 388 if (od->getinfotimer == 0)
375 aim_locate_dorequest(sess); 389 od->getinfotimer = gaim_timeout_add(10000,
390 gaim_reqinfo_timeout_cb, od);
376 } 391 }
377 392
378 return was_explicit; 393 return was_explicit;
379 } 394 }
380 395
381 faim_internal void aim_locate_requestuserinfo(OscarSession *sess, const char *sn) { 396 void aim_locate_requestuserinfo(OscarData *od, const char *sn) {
382 struct userinfo_node *cur; 397 struct userinfo_node *cur;
383 398
384 /* Make sure we aren't already requesting info for this buddy */ 399 /* Make sure we aren't already requesting info for this buddy */
385 cur = sess->locate.torequest; 400 cur = od->locate.torequest;
386 while (cur != NULL) { 401 while (cur != NULL) {
387 if (aim_sncmp(sn, cur->sn) == 0) 402 if (aim_sncmp(sn, cur->sn) == 0)
388 return; 403 return;
389 cur = cur->next; 404 cur = cur->next;
390 } 405 }
391 406
392 /* Add a new node to our request queue */ 407 /* Add a new node to our request queue */
393 cur = (struct userinfo_node *)malloc(sizeof(struct userinfo_node)); 408 cur = (struct userinfo_node *)malloc(sizeof(struct userinfo_node));
394 cur->sn = strdup(sn); 409 cur->sn = strdup(sn);
395 cur->next = sess->locate.torequest; 410 cur->next = od->locate.torequest;
396 sess->locate.torequest = cur; 411 od->locate.torequest = cur;
397 412
398 /* Actually request some info up in this piece */ 413 /* Actually request some info up in this piece */
399 aim_locate_dorequest(sess); 414 aim_locate_dorequest(od);
400 } 415 }
401 416
402 faim_export aim_userinfo_t *aim_locate_finduserinfo(OscarSession *sess, const char *sn) { 417 aim_userinfo_t *aim_locate_finduserinfo(OscarData *od, const char *sn) {
403 aim_userinfo_t *cur = NULL; 418 aim_userinfo_t *cur = NULL;
404 419
405 if (sn == NULL) 420 if (sn == NULL)
406 return NULL; 421 return NULL;
407 422
408 cur = sess->locate.userinfo; 423 cur = od->locate.userinfo;
409 424
410 while (cur != NULL) { 425 while (cur != NULL) {
411 if (aim_sncmp(cur->sn, sn) == 0) 426 if (aim_sncmp(cur->sn, sn) == 0)
412 return cur; 427 return cur;
413 cur = cur->next; 428 cur = cur->next;
414 } 429 }
415 430
416 return NULL; 431 return NULL;
417 } 432 }
418 433
419 faim_internal guint32 aim_locate_getcaps(OscarSession *sess, ByteStream *bs, int len) 434 guint32 aim_locate_getcaps(OscarData *od, ByteStream *bs, int len)
420 { 435 {
421 guint32 flags = 0; 436 guint32 flags = 0;
422 int offset; 437 int offset;
423 438
424 for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x10) { 439 for (offset = 0; byte_stream_empty(bs) && (offset < len); offset += 0x10) {
425 guint8 *cap; 440 guint8 *cap;
426 int i, identified; 441 int i, identified;
427 442
428 cap = aimbs_getraw(bs, 0x10); 443 cap = byte_stream_getraw(bs, 0x10);
429 444
430 for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) { 445 for (i = 0, identified = 0; !(aim_caps[i].flag & OSCAR_CAPABILITY_LAST); i++) {
431 if (memcmp(&aim_caps[i].data, cap, 0x10) == 0) { 446 if (memcmp(&aim_caps[i].data, cap, 0x10) == 0) {
432 flags |= aim_caps[i].flag; 447 flags |= aim_caps[i].flag;
433 identified++; 448 identified++;
434 break; /* should only match once... */ 449 break; /* should only match once... */
435 } 450 }
448 } 463 }
449 464
450 return flags; 465 return flags;
451 } 466 }
452 467
453 faim_internal guint32 aim_locate_getcaps_short(OscarSession *sess, ByteStream *bs, int len) 468 guint32 aim_locate_getcaps_short(OscarData *od, ByteStream *bs, int len)
454 { 469 {
455 guint32 flags = 0; 470 guint32 flags = 0;
456 int offset; 471 int offset;
457 472
458 for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x02) { 473 for (offset = 0; byte_stream_empty(bs) && (offset < len); offset += 0x02) {
459 guint8 *cap; 474 guint8 *cap;
460 int i, identified; 475 int i, identified;
461 476
462 cap = aimbs_getraw(bs, 0x02); 477 cap = byte_stream_getraw(bs, 0x02);
463 478
464 for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) { 479 for (i = 0, identified = 0; !(aim_caps[i].flag & OSCAR_CAPABILITY_LAST); i++) {
465 if (memcmp(&aim_caps[i].data[2], cap, 0x02) == 0) { 480 if (memcmp(&aim_caps[i].data[2], cap, 0x02) == 0) {
466 flags |= aim_caps[i].flag; 481 flags |= aim_caps[i].flag;
467 identified++; 482 identified++;
468 break; /* should only match once... */ 483 break; /* should only match once... */
469 } 484 }
476 } 491 }
477 492
478 return flags; 493 return flags;
479 } 494 }
480 495
481 faim_internal int aimbs_putcaps(ByteStream *bs, guint32 caps) 496 int byte_stream_putcaps(ByteStream *bs, guint32 caps)
482 { 497 {
483 int i; 498 int i;
484 499
485 if (!bs) 500 if (!bs)
486 return -EINVAL; 501 return -EINVAL;
487 502
488 for (i = 0; aim_bstream_empty(bs); i++) { 503 for (i = 0; byte_stream_empty(bs); i++) {
489 504
490 if (aim_caps[i].flag == AIM_CAPS_LAST) 505 if (aim_caps[i].flag == OSCAR_CAPABILITY_LAST)
491 break; 506 break;
492 507
493 if (caps & aim_caps[i].flag) 508 if (caps & aim_caps[i].flag)
494 aimbs_putraw(bs, aim_caps[i].data, 0x10); 509 byte_stream_putraw(bs, aim_caps[i].data, 0x10);
495 510
496 } 511 }
497 512
498 return 0; 513 return 0;
499 } 514 }
500 515
501 static void dumptlv(OscarSession *sess, guint16 type, ByteStream *bs, guint8 len) 516 #if 0
517 static void
518 dumptlv(OscarData *od, guint16 type, ByteStream *bs, guint8 len)
502 { 519 {
503 int i; 520 int i;
504 521
505 if (!sess || !bs || !len) 522 if (!od || !bs || !len)
506 return; 523 return;
507 524
508 gaim_debug_misc("oscar", "userinfo: type =0x%04x\n", type); 525 gaim_debug_misc("oscar", "userinfo: type =0x%04x\n", type);
509 gaim_debug_misc("oscar", "userinfo: length=0x%04x\n", len); 526 gaim_debug_misc("oscar", "userinfo: length=0x%04x\n", len);
510 gaim_debug_misc("oscar", "userinfo: value:\n"); 527 gaim_debug_misc("oscar", "userinfo: value:\n");
511 528
512 for (i = 0; i < len; i++) { 529 for (i = 0; i < len; i++) {
513 if ((i % 8) == 0) 530 if ((i % 8) == 0)
514 gaim_debug_misc("oscar", "\nuserinfo: "); 531 gaim_debug_misc("oscar", "\nuserinfo: ");
515 gaim_debug_misc("oscar", "0x%2x ", aimbs_get8(bs)); 532 gaim_debug_misc("oscar", "0x%2x ", byte_stream_get8(bs));
516 } 533 }
517 534
518 gaim_debug_misc("oscar", "\n"); 535 gaim_debug_misc("oscar", "\n");
519 536
520 return; 537 return;
521 } 538 }
522 539 #endif
523 faim_internal void aim_info_free(aim_userinfo_t *info) 540
541 void aim_info_free(aim_userinfo_t *info)
524 { 542 {
525 free(info->sn); 543 free(info->sn);
526 free(info->iconcsum); 544 free(info->iconcsum);
527 free(info->info); 545 free(info->info);
528 free(info->info_encoding); 546 free(info->info_encoding);
534 552
535 /* 553 /*
536 * AIM is fairly regular about providing user info. This is a generic 554 * AIM is fairly regular about providing user info. This is a generic
537 * routine to extract it in its standard form. 555 * routine to extract it in its standard form.
538 */ 556 */
539 faim_internal int aim_info_extract(OscarSession *sess, ByteStream *bs, aim_userinfo_t *outinfo) 557 int aim_info_extract(OscarData *od, ByteStream *bs, aim_userinfo_t *outinfo)
540 { 558 {
541 int curtlv, tlvcnt; 559 int curtlv, tlvcnt;
542 guint8 snlen; 560 guint8 snlen;
543 561
544 if (!bs || !outinfo) 562 if (!bs || !outinfo)
549 567
550 /* 568 /*
551 * Screen name. Stored as an unterminated string prepended with a 569 * Screen name. Stored as an unterminated string prepended with a
552 * byte containing its length. 570 * byte containing its length.
553 */ 571 */
554 snlen = aimbs_get8(bs); 572 snlen = byte_stream_get8(bs);
555 outinfo->sn = aimbs_getstr(bs, snlen); 573 outinfo->sn = byte_stream_getstr(bs, snlen);
556 574
557 /* 575 /*
558 * Warning Level. Stored as an unsigned short. 576 * Warning Level. Stored as an unsigned short.
559 */ 577 */
560 outinfo->warnlevel = aimbs_get16(bs); 578 outinfo->warnlevel = byte_stream_get16(bs);
561 579
562 /* 580 /*
563 * TLV Count. Unsigned short representing the number of 581 * TLV Count. Unsigned short representing the number of
564 * Type-Length-Value triples that follow. 582 * Type-Length-Value triples that follow.
565 */ 583 */
566 tlvcnt = aimbs_get16(bs); 584 tlvcnt = byte_stream_get16(bs);
567 585
568 /* 586 /*
569 * Parse out the Type-Length-Value triples as they're found. 587 * Parse out the Type-Length-Value triples as they're found.
570 */ 588 */
571 for (curtlv = 0; curtlv < tlvcnt; curtlv++) { 589 for (curtlv = 0; curtlv < tlvcnt; curtlv++) {
572 int endpos; 590 int endpos;
573 guint16 type, length; 591 guint16 type, length;
574 592
575 type = aimbs_get16(bs); 593 type = byte_stream_get16(bs);
576 length = aimbs_get16(bs); 594 length = byte_stream_get16(bs);
577 595
578 endpos = aim_bstream_curpos(bs) + length; 596 endpos = byte_stream_curpos(bs) + length;
579 597
580 if (type == 0x0001) { 598 if (type == 0x0001) {
581 /* 599 /*
582 * Type = 0x0001: User flags 600 * Type = 0x0001: User flags
583 * 601 *
584 * Specified as any of the following ORed together: 602 * Specified as any of the following ORed together:
585 * 0x0001 Trial (user less than 60days) 603 * 0x0001 Trial (user less than 60days)
586 * 0x0002 Unknown bit 2 604 * 0x0002 Unknown bit 2
587 * 0x0004 AOL Main Service user 605 * 0x0004 AOL Main Service user
588 * 0x0008 Unknown bit 4 606 * 0x0008 Unknown bit 4
589 * 0x0010 Free (AIM) user 607 * 0x0010 Free (AIM) user
590 * 0x0020 Away 608 * 0x0020 Away
591 * 0x0400 ActiveBuddy 609 * 0x0400 ActiveBuddy
592 * 610 *
593 */ 611 */
594 outinfo->flags = aimbs_get16(bs); 612 outinfo->flags = byte_stream_get16(bs);
595 outinfo->present |= AIM_USERINFO_PRESENT_FLAGS; 613 outinfo->present |= AIM_USERINFO_PRESENT_FLAGS;
596 614
597 } else if (type == 0x0002) { 615 } else if (type == 0x0002) {
598 /* 616 /*
599 * Type = 0x0002: Account creation time. 617 * Type = 0x0002: Account creation time.
600 * 618 *
601 * The time/date that the user originally registered for 619 * The time/date that the user originally registered for
602 * the service, stored in time_t format. 620 * the service, stored in time_t format.
603 * 621 *
604 * I'm not sure how this differs from type 5 ("member 622 * I'm not sure how this differs from type 5 ("member
606 * 624 *
607 * Note: This is the field formerly known as "member 625 * Note: This is the field formerly known as "member
608 * since". All these years and I finally found out 626 * since". All these years and I finally found out
609 * that I got the name wrong. 627 * that I got the name wrong.
610 */ 628 */
611 outinfo->createtime = aimbs_get32(bs); 629 outinfo->createtime = byte_stream_get32(bs);
612 outinfo->present |= AIM_USERINFO_PRESENT_CREATETIME; 630 outinfo->present |= AIM_USERINFO_PRESENT_CREATETIME;
613 631
614 } else if (type == 0x0003) { 632 } else if (type == 0x0003) {
615 /* 633 /*
616 * Type = 0x0003: On-Since date. 634 * Type = 0x0003: On-Since date.
617 * 635 *
618 * The time/date that the user started their current 636 * The time/date that the user started their current
619 * session, stored in time_t format. 637 * session, stored in time_t format.
620 */ 638 */
621 outinfo->onlinesince = aimbs_get32(bs); 639 outinfo->onlinesince = byte_stream_get32(bs);
622 outinfo->present |= AIM_USERINFO_PRESENT_ONLINESINCE; 640 outinfo->present |= AIM_USERINFO_PRESENT_ONLINESINCE;
623 641
624 } else if (type == 0x0004) { 642 } else if (type == 0x0004) {
625 /* 643 /*
626 * Type = 0x0004: Idle time. 644 * Type = 0x0004: Idle time.
627 * 645 *
628 * Number of minutes since the user actively used the 646 * Number of minutes since the user actively used the
629 * service. 647 * service.
630 * 648 *
631 * Note that the client tells the server when to start 649 * Note that the client tells the server when to start
632 * counting idle times, so this may or may not be 650 * counting idle times, so this may or may not be
633 * related to reality. 651 * related to reality.
634 */ 652 */
635 outinfo->idletime = aimbs_get16(bs); 653 outinfo->idletime = byte_stream_get16(bs);
636 outinfo->present |= AIM_USERINFO_PRESENT_IDLE; 654 outinfo->present |= AIM_USERINFO_PRESENT_IDLE;
637 655
638 } else if (type == 0x0005) { 656 } else if (type == 0x0005) {
639 /* 657 /*
640 * Type = 0x0005: Member since date. 658 * Type = 0x0005: Member since date.
641 * 659 *
642 * The time/date that the user originally registered for 660 * The time/date that the user originally registered for
643 * the service, stored in time_t format. 661 * the service, stored in time_t format.
644 * 662 *
645 * This is sometimes sent instead of type 2 ("account 663 * This is sometimes sent instead of type 2 ("account
646 * creation time"), particularly in the self-info. 664 * creation time"), particularly in the self-info.
647 * And particularly for ICQ? 665 * And particularly for ICQ?
648 */ 666 */
649 outinfo->membersince = aimbs_get32(bs); 667 outinfo->membersince = byte_stream_get32(bs);
650 outinfo->present |= AIM_USERINFO_PRESENT_MEMBERSINCE; 668 outinfo->present |= AIM_USERINFO_PRESENT_MEMBERSINCE;
651 669
652 } else if (type == 0x0006) { 670 } else if (type == 0x0006) {
653 /* 671 /*
654 * Type = 0x0006: ICQ Online Status 672 * Type = 0x0006: ICQ Online Status
655 * 673 *
656 * ICQ's Away/DND/etc "enriched" status. Some decoding 674 * ICQ's Away/DND/etc "enriched" status. Some decoding
657 * of values done by Scott <darkagl@pcnet.com> 675 * of values done by Scott <darkagl@pcnet.com>
658 */ 676 */
659 aimbs_get16(bs); 677 byte_stream_get16(bs);
660 outinfo->icqinfo.status = aimbs_get16(bs); 678 outinfo->icqinfo.status = byte_stream_get16(bs);
661 outinfo->present |= AIM_USERINFO_PRESENT_ICQEXTSTATUS; 679 outinfo->present |= AIM_USERINFO_PRESENT_ICQEXTSTATUS;
662 680
663 } else if (type == 0x0008) { 681 } else if (type == 0x0008) {
664 /* 682 /*
665 * Type = 0x0008 683 * Type = 0x0008
672 * Type = 0x000a 690 * Type = 0x000a
673 * 691 *
674 * ICQ User IP Address. 692 * ICQ User IP Address.
675 * Ahh, the joy of ICQ security. 693 * Ahh, the joy of ICQ security.
676 */ 694 */
677 outinfo->icqinfo.ipaddr = aimbs_get32(bs); 695 outinfo->icqinfo.ipaddr = byte_stream_get32(bs);
678 outinfo->present |= AIM_USERINFO_PRESENT_ICQIPADDR; 696 outinfo->present |= AIM_USERINFO_PRESENT_ICQIPADDR;
679 697
680 } else if (type == 0x000c) { 698 } else if (type == 0x000c) {
681 /* 699 /*
682 * Type = 0x000c 700 * Type = 0x000c
683 * 701 *
684 * random crap containing the IP address, 702 * random crap containing the IP address,
685 * apparently a port number, and some Other Stuff. 703 * apparently a port number, and some Other Stuff.
686 * 704 *
687 * Format is: 705 * Format is:
688 * 4 bytes - Our IP address, 0xc0 a8 01 2b for 192.168.1.43 706 * 4 bytes - Our IP address, 0xc0 a8 01 2b for 192.168.1.43
689 * 707 *
690 * 708 *
691 */ 709 */
692 aimbs_getrawbuf(bs, outinfo->icqinfo.crap, 0x25); 710 byte_stream_getrawbuf(bs, outinfo->icqinfo.crap, 0x25);
693 outinfo->present |= AIM_USERINFO_PRESENT_ICQDATA; 711 outinfo->present |= AIM_USERINFO_PRESENT_ICQDATA;
694 712
695 } else if (type == 0x000d) { 713 } else if (type == 0x000d) {
696 /* 714 /*
697 * Type = 0x000d 715 * Type = 0x000d
698 * 716 *
699 * OSCAR Capability information. 717 * OSCAR Capability information.
700 * 718 *
701 */ 719 */
702 outinfo->capabilities |= aim_locate_getcaps(sess, bs, length); 720 outinfo->capabilities |= aim_locate_getcaps(od, bs, length);
703 outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES; 721 outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;
704 722
705 } else if (type == 0x000e) { 723 } else if (type == 0x000e) {
706 /* 724 /*
707 * Type = 0x000e 725 * Type = 0x000e
713 } else if ((type == 0x000f) || (type == 0x0010)) { 731 } else if ((type == 0x000f) || (type == 0x0010)) {
714 /* 732 /*
715 * Type = 0x000f: Session Length. (AIM) 733 * Type = 0x000f: Session Length. (AIM)
716 * Type = 0x0010: Session Length. (AOL) 734 * Type = 0x0010: Session Length. (AOL)
717 * 735 *
718 * The duration, in seconds, of the user's current 736 * The duration, in seconds, of the user's current
719 * session. 737 * session.
720 * 738 *
721 * Which TLV type this comes in depends on the 739 * Which TLV type this comes in depends on the
722 * service the user is using (AIM or AOL). 740 * service the user is using (AIM or AOL).
723 * 741 *
724 */ 742 */
725 outinfo->sessionlen = aimbs_get32(bs); 743 outinfo->sessionlen = byte_stream_get32(bs);
726 outinfo->present |= AIM_USERINFO_PRESENT_SESSIONLEN; 744 outinfo->present |= AIM_USERINFO_PRESENT_SESSIONLEN;
727 745
728 } else if (type == 0x0019) { 746 } else if (type == 0x0019) {
729 /* 747 /*
730 * Type = 0x0019 748 * Type = 0x0019
731 * 749 *
732 * OSCAR short capability information. A shortened 750 * OSCAR short capability information. A shortened
733 * form of the normal capabilities. 751 * form of the normal capabilities.
734 */ 752 */
735 outinfo->capabilities |= aim_locate_getcaps_short(sess, bs, length); 753 outinfo->capabilities |= aim_locate_getcaps_short(od, bs, length);
736 outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES; 754 outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;
737 755
738 } else if (type == 0x001b) { 756 } else if (type == 0x001b) {
739 /* 757 /*
740 * Type = 0x001a 758 * Type = 0x001a
741 * 759 *
742 * AOL short capability information. A shortened 760 * AOL short capability information. A shortened
743 * form of the normal capabilities. 761 * form of the normal capabilities.
744 */ 762 */
745 763
746 } else if (type == 0x001b) { 764 } else if (type == 0x001b) {
747 /* 765 /*
768 * contain information about the buddy icon the user 786 * contain information about the buddy icon the user
769 * has stored on the server. 787 * has stored on the server.
770 */ 788 */
771 int type2, number, length2; 789 int type2, number, length2;
772 790
773 while (aim_bstream_curpos(bs) < endpos) { 791 while (byte_stream_curpos(bs) < endpos) {
774 type2 = aimbs_get16(bs); 792 type2 = byte_stream_get16(bs);
775 number = aimbs_get8(bs); 793 number = byte_stream_get8(bs);
776 length2 = aimbs_get8(bs); 794 length2 = byte_stream_get8(bs);
777 795
778 switch (type2) { 796 switch (type2) {
779 case 0x0000: { /* This is an official buddy icon? */ 797 case 0x0000: { /* This is an official buddy icon? */
780 /* This is always 5 bytes of "0x02 01 d2 04 72"? */ 798 /* This is always 5 bytes of "0x02 01 d2 04 72"? */
781 aim_bstream_advance(bs, length2); 799 byte_stream_advance(bs, length2);
782 } break; 800 } break;
783 801
784 case 0x0001: { /* A buddy icon checksum */ 802 case 0x0001: { /* A buddy icon checksum */
785 if ((length2 > 0) && ((number == 0x00) || (number == 0x01))) { 803 if ((length2 > 0) && ((number == 0x00) || (number == 0x01))) {
786 free(outinfo->iconcsum); 804 free(outinfo->iconcsum);
787 outinfo->iconcsumtype = number; 805 outinfo->iconcsumtype = number;
788 outinfo->iconcsum = aimbs_getraw(bs, length2); 806 outinfo->iconcsum = byte_stream_getraw(bs, length2);
789 outinfo->iconcsumlen = length2; 807 outinfo->iconcsumlen = length2;
790 } else 808 } else
791 aim_bstream_advance(bs, length2); 809 byte_stream_advance(bs, length2);
792 } break; 810 } break;
793 811
794 case 0x0002: { /* A status/available message */ 812 case 0x0002: { /* A status/available message */
795 free(outinfo->status); 813 free(outinfo->status);
796 free(outinfo->status_encoding); 814 free(outinfo->status_encoding);
797 if (length2 >= 4) { 815 if (length2 >= 4) {
798 outinfo->status_len = aimbs_get16(bs); 816 outinfo->status_len = byte_stream_get16(bs);
799 outinfo->status = aimbs_getstr(bs, outinfo->status_len); 817 outinfo->status = byte_stream_getstr(bs, outinfo->status_len);
800 if (aimbs_get16(bs) == 0x0001) { /* We have an encoding */ 818 if (byte_stream_get16(bs) == 0x0001) { /* We have an encoding */
801 aimbs_get16(bs); 819 byte_stream_get16(bs);
802 outinfo->status_encoding = aimbs_getstr(bs, aimbs_get16(bs)); 820 outinfo->status_encoding = byte_stream_getstr(bs, byte_stream_get16(bs));
803 } else { 821 } else {
804 /* No explicit encoding, client should use UTF-8 */ 822 /* No explicit encoding, client should use UTF-8 */
805 outinfo->status_encoding = NULL; 823 outinfo->status_encoding = NULL;
806 } 824 }
807 } else { 825 } else {
808 aim_bstream_advance(bs, length2); 826 byte_stream_advance(bs, length2);
809 outinfo->status_len = 0; 827 outinfo->status_len = 0;
810 outinfo->status = g_strdup(""); 828 outinfo->status = g_strdup("");
811 outinfo->status_encoding = NULL; 829 outinfo->status_encoding = NULL;
812 } 830 }
813 } break; 831 } break;
814 832
815 default: { 833 default: {
816 aim_bstream_advance(bs, length2); 834 byte_stream_advance(bs, length2);
817 } break; 835 } break;
818 } 836 }
819 } 837 }
820 838
821 } else if (type == 0x001e) { 839 } else if (type == 0x001e) {
835 853
836 } else { 854 } else {
837 855
838 /* 856 /*
839 * Reaching here indicates that either AOL has 857 * Reaching here indicates that either AOL has
840 * added yet another TLV for us to deal with, 858 * added yet another TLV for us to deal with,
841 * or the parsing has gone Terribly Wrong. 859 * or the parsing has gone Terribly Wrong.
842 * 860 *
843 * Either way, inform the owner and attempt 861 * Either way, inform the owner and attempt
844 * recovery. 862 * recovery.
845 * 863 *
846 */ 864 */
865 #if 0
847 gaim_debug_misc("oscar", "userinfo: **warning: unexpected TLV:\n"); 866 gaim_debug_misc("oscar", "userinfo: **warning: unexpected TLV:\n");
848 gaim_debug_misc("oscar", "userinfo: sn =%s\n", outinfo->sn); 867 gaim_debug_misc("oscar", "userinfo: sn =%s\n", outinfo->sn);
849 dumptlv(sess, type, bs, length); 868 dumptlv(od, type, bs, length);
869 #endif
850 } 870 }
851 871
852 /* Save ourselves. */ 872 /* Save ourselves. */
853 aim_bstream_setpos(bs, endpos); 873 byte_stream_setpos(bs, endpos);
854 } 874 }
855 875
856 aim_locate_adduserinfo(sess, outinfo); 876 aim_locate_adduserinfo(od, outinfo);
857 877
858 return 0; 878 return 0;
859 } 879 }
860 880
861 /* 881 /*
862 * Inverse of aim_info_extract() 882 * Inverse of aim_info_extract()
863 */ 883 */
864 faim_internal int aim_putuserinfo(ByteStream *bs, aim_userinfo_t *info) 884 int
885 aim_putuserinfo(ByteStream *bs, aim_userinfo_t *info)
865 { 886 {
866 aim_tlvlist_t *tlvlist = NULL; 887 aim_tlvlist_t *tlvlist = NULL;
867 888
868 if (!bs || !info) 889 if (!bs || !info)
869 return -EINVAL; 890 return -EINVAL;
870 891
871 aimbs_put8(bs, strlen(info->sn)); 892 byte_stream_put8(bs, strlen(info->sn));
872 aimbs_putstr(bs, info->sn); 893 byte_stream_putstr(bs, info->sn);
873 894
874 aimbs_put16(bs, info->warnlevel); 895 byte_stream_put16(bs, info->warnlevel);
875 896
876 if (info->present & AIM_USERINFO_PRESENT_FLAGS) 897 if (info->present & AIM_USERINFO_PRESENT_FLAGS)
877 aim_tlvlist_add_16(&tlvlist, 0x0001, info->flags); 898 aim_tlvlist_add_16(&tlvlist, 0x0001, info->flags);
878 if (info->present & AIM_USERINFO_PRESENT_MEMBERSINCE) 899 if (info->present & AIM_USERINFO_PRESENT_MEMBERSINCE)
879 aim_tlvlist_add_32(&tlvlist, 0x0002, info->membersince); 900 aim_tlvlist_add_32(&tlvlist, 0x0002, info->membersince);
896 aim_tlvlist_add_caps(&tlvlist, 0x000d, info->capabilities); 917 aim_tlvlist_add_caps(&tlvlist, 0x000d, info->capabilities);
897 918
898 if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN) 919 if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN)
899 aim_tlvlist_add_32(&tlvlist, (guint16)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen); 920 aim_tlvlist_add_32(&tlvlist, (guint16)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen);
900 921
901 aimbs_put16(bs, aim_tlvlist_count(&tlvlist)); 922 byte_stream_put16(bs, aim_tlvlist_count(&tlvlist));
902 aim_tlvlist_write(bs, &tlvlist); 923 aim_tlvlist_write(bs, &tlvlist);
903 aim_tlvlist_free(&tlvlist); 924 aim_tlvlist_free(&tlvlist);
904 925
905 return 0; 926 return 0;
906 } 927 }
907 928
908 /* 929 /*
909 * Subtype 0x0001 930 * Subtype 0x0001
910 */ 931 */
911 static int error(OscarSession *sess, aim_module_t *mod, FlapFrame *rx, aim_modsnac_t *snac, ByteStream *bs) 932 static int
933 error(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
912 { 934 {
913 int ret = 0; 935 int ret = 0;
914 aim_rxcallback_t userfunc; 936 aim_rxcallback_t userfunc;
915 aim_snac_t *snac2; 937 aim_snac_t *snac2;
916 guint16 reason; 938 guint16 reason;
917 char *sn; 939 char *sn;
918 int was_explicit; 940 int was_explicit;
919 941
920 if (!(snac2 = aim_remsnac(sess, snac->id))) { 942 if (!(snac2 = aim_remsnac(od, snac->id))) {
921 gaim_debug_misc("oscar", "faim: locate.c, error(): received response from unknown request!\n"); 943 gaim_debug_misc("oscar", "faim: locate.c, error(): received response from unknown request!\n");
922 return 0; 944 return 0;
923 } 945 }
924 946
925 if ((snac2->family != 0x0002) && (snac2->type != 0x0015)) { 947 if ((snac2->family != 0x0002) && (snac2->type != 0x0015)) {
930 if (!(sn = snac2->data)) { 952 if (!(sn = snac2->data)) {
931 gaim_debug_misc("oscar", "faim: locate.c, error(): received response from request without a screen name!\n"); 953 gaim_debug_misc("oscar", "faim: locate.c, error(): received response from request without a screen name!\n");
932 return 0; 954 return 0;
933 } 955 }
934 956
935 reason = aimbs_get16(bs); 957 reason = byte_stream_get16(bs);
936 958
937 /* 959 /*
938 * Remove this screen name from our queue. If the client requested 960 * Remove this screen name from our queue. If the client requested
939 * this buddy's info explicitly, then notify them that we do not have 961 * this buddy's info explicitly, then notify them that we do not have
940 * info for this buddy. 962 * info for this buddy.
941 */ 963 */
942 was_explicit = aim_locate_gotuserinfo(sess, sn); 964 was_explicit = aim_locate_gotuserinfo(od, conn, sn);
943 if (was_explicit == TRUE) 965 if (was_explicit == TRUE)
944 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 966 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
945 ret = userfunc(sess, rx, reason, sn); 967 ret = userfunc(od, conn, frame, reason, sn);
946 968
947 if (snac2) 969 if (snac2)
948 free(snac2->data); 970 free(snac2->data);
949 free(snac2); 971 free(snac2);
950 972
955 * Subtype 0x0002 977 * Subtype 0x0002
956 * 978 *
957 * Request Location services rights. 979 * Request Location services rights.
958 * 980 *
959 */ 981 */
960 faim_export int aim_locate_reqrights(OscarSession *sess) 982 int
961 { 983 aim_locate_reqrights(OscarData *od)
962 OscarConnection *conn; 984 {
963 985 FlapConnection *conn;
964 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE))) 986
987 if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
965 return -EINVAL; 988 return -EINVAL;
966 989
967 return aim_genericreq_n_snacid(sess, conn, OSCAR_FAMILY_LOCATE, OSCAR_SUBTYPE_LOCATE_REQRIGHTS); 990 return aim_genericreq_n_snacid(od, conn, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_REQRIGHTS);
968 } 991 }
969 992
970 /* 993 /*
971 * Subtype 0x0003 994 * Subtype 0x0003
972 * 995 *
974 * t(0001) - short containing max profile length (value = 1024) 997 * t(0001) - short containing max profile length (value = 1024)
975 * t(0002) - short - unknown (value = 16) [max MIME type length?] 998 * t(0002) - short - unknown (value = 16) [max MIME type length?]
976 * t(0003) - short - unknown (value = 10) 999 * t(0003) - short - unknown (value = 10)
977 * t(0004) - short - unknown (value = 2048) [ICQ only?] 1000 * t(0004) - short - unknown (value = 2048) [ICQ only?]
978 */ 1001 */
979 static int rights(OscarSession *sess, aim_module_t *mod, FlapFrame *rx, aim_modsnac_t *snac, ByteStream *bs) 1002 static int
1003 rights(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
980 { 1004 {
981 aim_tlvlist_t *tlvlist; 1005 aim_tlvlist_t *tlvlist;
982 aim_rxcallback_t userfunc; 1006 aim_rxcallback_t userfunc;
983 int ret = 0; 1007 int ret = 0;
984 guint16 maxsiglen = 0; 1008 guint16 maxsiglen = 0;
986 tlvlist = aim_tlvlist_read(bs); 1010 tlvlist = aim_tlvlist_read(bs);
987 1011
988 if (aim_tlv_gettlv(tlvlist, 0x0001, 1)) 1012 if (aim_tlv_gettlv(tlvlist, 0x0001, 1))
989 maxsiglen = aim_tlv_get16(tlvlist, 0x0001, 1); 1013 maxsiglen = aim_tlv_get16(tlvlist, 0x0001, 1);
990 1014
991 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1015 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
992 ret = userfunc(sess, rx, maxsiglen); 1016 ret = userfunc(od, conn, frame, maxsiglen);
993 1017
994 aim_tlvlist_free(&tlvlist); 1018 aim_tlvlist_free(&tlvlist);
995 1019
996 return ret; 1020 return ret;
997 } 1021 }
1014 * To get the previous behavior of awaymsg == "" un-setting the away 1038 * To get the previous behavior of awaymsg == "" un-setting the away
1015 * message, set awaymsg non-NULL and awaymsg_len to 0 (this is the 1039 * message, set awaymsg non-NULL and awaymsg_len to 0 (this is the
1016 * obvious equivalent). 1040 * obvious equivalent).
1017 * 1041 *
1018 */ 1042 */
1019 faim_export int aim_locate_setprofile(OscarSession *sess, 1043 int
1044 aim_locate_setprofile(OscarData *od,
1020 const char *profile_encoding, const gchar *profile, const int profile_len, 1045 const char *profile_encoding, const gchar *profile, const int profile_len,
1021 const char *awaymsg_encoding, const gchar *awaymsg, const int awaymsg_len) 1046 const char *awaymsg_encoding, const gchar *awaymsg, const int awaymsg_len)
1022 { 1047 {
1023 OscarConnection *conn; 1048 FlapConnection *conn;
1024 FlapFrame *fr; 1049 FlapFrame *frame;
1025 aim_snacid_t snacid; 1050 aim_snacid_t snacid;
1026 aim_tlvlist_t *tl = NULL; 1051 aim_tlvlist_t *tl = NULL;
1027 char *encoding; 1052 char *encoding;
1028 static const char defencoding[] = {"text/aolrtf; charset=\"%s\""}; 1053 static const char defencoding[] = {"text/aolrtf; charset=\"%s\""};
1029 1054
1030 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE))) 1055 if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
1031 return -EINVAL; 1056 return -EINVAL;
1032 1057
1033 if (!profile && !awaymsg) 1058 if (!profile && !awaymsg)
1034 return -EINVAL; 1059 return -EINVAL;
1035 1060
1039 1064
1040 /* Build the packet first to get real length */ 1065 /* Build the packet first to get real length */
1041 if (profile) { 1066 if (profile) {
1042 /* no + 1 here because of %s */ 1067 /* no + 1 here because of %s */
1043 encoding = malloc(strlen(defencoding) + strlen(profile_encoding)); 1068 encoding = malloc(strlen(defencoding) + strlen(profile_encoding));
1044 if (encoding == NULL) {
1045 return -ENOMEM;
1046 }
1047 snprintf(encoding, strlen(defencoding) + strlen(profile_encoding), defencoding, profile_encoding); 1069 snprintf(encoding, strlen(defencoding) + strlen(profile_encoding), defencoding, profile_encoding);
1048 aim_tlvlist_add_str(&tl, 0x0001, encoding); 1070 aim_tlvlist_add_str(&tl, 0x0001, encoding);
1049 aim_tlvlist_add_raw(&tl, 0x0002, profile_len, (const guchar *)profile); 1071 aim_tlvlist_add_raw(&tl, 0x0002, profile_len, (const guchar *)profile);
1050 free(encoding); 1072 free(encoding);
1051 } 1073 }
1059 * (that is, if you were away, you'll remain away). 1081 * (that is, if you were away, you'll remain away).
1060 */ 1082 */
1061 if (awaymsg) { 1083 if (awaymsg) {
1062 if (awaymsg_len) { 1084 if (awaymsg_len) {
1063 encoding = malloc(strlen(defencoding) + strlen(awaymsg_encoding)); 1085 encoding = malloc(strlen(defencoding) + strlen(awaymsg_encoding));
1064 if (encoding == NULL) {
1065 return -ENOMEM;
1066 }
1067 snprintf(encoding, strlen(defencoding) + strlen(awaymsg_encoding), defencoding, awaymsg_encoding); 1086 snprintf(encoding, strlen(defencoding) + strlen(awaymsg_encoding), defencoding, awaymsg_encoding);
1068 aim_tlvlist_add_str(&tl, 0x0003, encoding); 1087 aim_tlvlist_add_str(&tl, 0x0003, encoding);
1069 aim_tlvlist_add_raw(&tl, 0x0004, awaymsg_len, (const guchar *)awaymsg); 1088 aim_tlvlist_add_raw(&tl, 0x0004, awaymsg_len, (const guchar *)awaymsg);
1070 free(encoding); 1089 free(encoding);
1071 } else 1090 } else
1072 aim_tlvlist_add_noval(&tl, 0x0004); 1091 aim_tlvlist_add_noval(&tl, 0x0004);
1073 } 1092 }
1074 1093
1075 if (!(fr = flap_frame_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl)))) 1094 frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(&tl));
1076 return -ENOMEM; 1095
1077 1096 snacid = aim_cachesnac(od, 0x0002, 0x0004, 0x0000, NULL, 0);
1078 snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0); 1097 aim_putsnac(&frame->data, 0x0002, 0x004, 0x0000, snacid);
1079 aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid); 1098
1080 1099 aim_tlvlist_write(&frame->data, &tl);
1081 aim_tlvlist_write(&fr->data, &tl);
1082 aim_tlvlist_free(&tl); 1100 aim_tlvlist_free(&tl);
1083 1101
1084 aim_tx_enqueue(sess, fr); 1102 flap_connection_send(conn, frame);
1085 1103
1086 return 0; 1104 return 0;
1087 } 1105 }
1088 1106
1089 /* 1107 /*
1090 * Subtype 0x0004 - Set your client's capabilities. 1108 * Subtype 0x0004 - Set your client's capabilities.
1091 */ 1109 */
1092 faim_export int aim_locate_setcaps(OscarSession *sess, guint32 caps) 1110 int
1093 { 1111 aim_locate_setcaps(OscarData *od, guint32 caps)
1094 OscarConnection *conn; 1112 {
1095 FlapFrame *fr; 1113 FlapConnection *conn;
1114 FlapFrame *frame;
1096 aim_snacid_t snacid; 1115 aim_snacid_t snacid;
1097 aim_tlvlist_t *tl = NULL; 1116 aim_tlvlist_t *tl = NULL;
1098 1117
1099 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE))) 1118 if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
1100 return -EINVAL; 1119 return -EINVAL;
1101 1120
1102 aim_tlvlist_add_caps(&tl, 0x0005, caps); 1121 aim_tlvlist_add_caps(&tl, 0x0005, caps);
1103 1122
1104 if (!(fr = flap_frame_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl)))) 1123 frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(&tl));
1105 return -ENOMEM; 1124
1106 1125 snacid = aim_cachesnac(od, 0x0002, 0x0004, 0x0000, NULL, 0);
1107 snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0); 1126 aim_putsnac(&frame->data, 0x0002, 0x004, 0x0000, snacid);
1108 aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid); 1127
1109 1128 aim_tlvlist_write(&frame->data, &tl);
1110 aim_tlvlist_write(&fr->data, &tl);
1111 aim_tlvlist_free(&tl); 1129 aim_tlvlist_free(&tl);
1112 1130
1113 aim_tx_enqueue(sess, fr); 1131 flap_connection_send(conn, frame);
1114 1132
1115 return 0; 1133 return 0;
1116 } 1134 }
1117 1135
1118 /* 1136 /*
1122 * @param infotype The type of info you wish to request. 1140 * @param infotype The type of info you wish to request.
1123 * 0x0001 - Info/profile 1141 * 0x0001 - Info/profile
1124 * 0x0003 - Away message 1142 * 0x0003 - Away message
1125 * 0x0004 - Capabilities 1143 * 0x0004 - Capabilities
1126 */ 1144 */
1127 faim_export int aim_locate_getinfo(OscarSession *sess, const char *sn, guint16 infotype) 1145 int
1128 { 1146 aim_locate_getinfo(OscarData *od, const char *sn, guint16 infotype)
1129 OscarConnection *conn; 1147 {
1130 FlapFrame *fr; 1148 FlapConnection *conn;
1149 FlapFrame *frame;
1131 aim_snacid_t snacid; 1150 aim_snacid_t snacid;
1132 1151
1133 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)) || !sn) 1152 if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn)
1134 return -EINVAL; 1153 return -EINVAL;
1135 1154
1136 if (!(fr = flap_frame_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 12+1+strlen(sn)))) 1155 frame = flap_frame_new(od, 0x02, 12+1+strlen(sn));
1137 return -ENOMEM; 1156
1138 1157 snacid = aim_cachesnac(od, 0x0002, 0x0005, 0x0000, NULL, 0);
1139 snacid = aim_cachesnac(sess, 0x0002, 0x0005, 0x0000, NULL, 0); 1158
1140 1159 aim_putsnac(&frame->data, 0x0002, 0x0005, 0x0000, snacid);
1141 aim_putsnac(&fr->data, 0x0002, 0x0005, 0x0000, snacid); 1160 byte_stream_put16(&frame->data, infotype);
1142 aimbs_put16(&fr->data, infotype); 1161 byte_stream_put8(&frame->data, strlen(sn));
1143 aimbs_put8(&fr->data, strlen(sn)); 1162 byte_stream_putstr(&frame->data, sn);
1144 aimbs_putstr(&fr->data, sn); 1163
1145 1164 flap_connection_send(conn, frame);
1146 aim_tx_enqueue(sess, fr);
1147 1165
1148 return 0; 1166 return 0;
1149 } 1167 }
1150 1168
1151 /* Subtype 0x0006 */ 1169 /* Subtype 0x0006 */
1152 static int userinfo(OscarSession *sess, aim_module_t *mod, FlapFrame *rx, aim_modsnac_t *snac, ByteStream *bs) 1170 static int
1171 userinfo(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
1153 { 1172 {
1154 int ret = 0; 1173 int ret = 0;
1155 aim_rxcallback_t userfunc; 1174 aim_rxcallback_t userfunc;
1156 aim_userinfo_t *userinfo, *userinfo2; 1175 aim_userinfo_t *userinfo, *userinfo2;
1157 aim_tlvlist_t *tlvlist; 1176 aim_tlvlist_t *tlvlist;
1158 aim_tlv_t *tlv = NULL; 1177 aim_tlv_t *tlv = NULL;
1159 int was_explicit; 1178 int was_explicit;
1160 1179
1161 userinfo = (aim_userinfo_t *)malloc(sizeof(aim_userinfo_t)); 1180 userinfo = (aim_userinfo_t *)malloc(sizeof(aim_userinfo_t));
1162 aim_info_extract(sess, bs, userinfo); 1181 aim_info_extract(od, bs, userinfo);
1163 tlvlist = aim_tlvlist_read(bs); 1182 tlvlist = aim_tlvlist_read(bs);
1164 1183
1165 /* Profile will be 1 and 2 */ 1184 /* Profile will be 1 and 2 */
1166 userinfo->info_encoding = aim_tlv_getstr(tlvlist, 0x0001, 1); 1185 userinfo->info_encoding = aim_tlv_getstr(tlvlist, 0x0001, 1);
1167 if ((tlv = aim_tlv_gettlv(tlvlist, 0x0002, 1))) { 1186 if ((tlv = aim_tlv_gettlv(tlvlist, 0x0002, 1))) {
1179 } 1198 }
1180 1199
1181 /* Caps will be 5 */ 1200 /* Caps will be 5 */
1182 if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) { 1201 if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) {
1183 ByteStream cbs; 1202 ByteStream cbs;
1184 aim_bstream_init(&cbs, tlv->value, tlv->length); 1203 byte_stream_init(&cbs, tlv->value, tlv->length);
1185 userinfo->capabilities = aim_locate_getcaps(sess, &cbs, tlv->length); 1204 userinfo->capabilities = aim_locate_getcaps(od, &cbs, tlv->length);
1186 userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES; 1205 userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES;
1187 } 1206 }
1188 aim_tlvlist_free(&tlvlist); 1207 aim_tlvlist_free(&tlvlist);
1189 1208
1190 aim_locate_adduserinfo(sess, userinfo); 1209 aim_locate_adduserinfo(od, userinfo);
1191 userinfo2 = aim_locate_finduserinfo(sess, userinfo->sn); 1210 userinfo2 = aim_locate_finduserinfo(od, userinfo->sn);
1192 aim_info_free(userinfo); 1211 aim_info_free(userinfo);
1193 free(userinfo); 1212 free(userinfo);
1194 1213
1195 /* 1214 /*
1196 * Remove this screen name from our queue. If the client requested 1215 * Remove this screen name from our queue. If the client requested
1197 * this buddy's info explicitly, then notify them that we have info 1216 * this buddy's info explicitly, then notify them that we have info
1198 * for this buddy. 1217 * for this buddy.
1199 */ 1218 */
1200 was_explicit = aim_locate_gotuserinfo(sess, userinfo2->sn); 1219 was_explicit = aim_locate_gotuserinfo(od, conn, userinfo2->sn);
1201 if (was_explicit == TRUE) 1220 if (was_explicit == TRUE)
1202 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1221 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
1203 ret = userfunc(sess, rx, userinfo2); 1222 ret = userfunc(od, conn, frame, userinfo2);
1204 1223
1205 return ret; 1224 return ret;
1206 } 1225 }
1207 1226
1208 /* 1227 /*
1210 * 1229 *
1211 * This is not the same as aim_location_setprofile! 1230 * This is not the same as aim_location_setprofile!
1212 * privacy: 1 to allow searching, 0 to disallow. 1231 * privacy: 1 to allow searching, 0 to disallow.
1213 * 1232 *
1214 */ 1233 */
1215 faim_export int aim_locate_setdirinfo(OscarSession *sess, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, guint16 privacy) 1234 int aim_locate_setdirinfo(OscarData *od, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, guint16 privacy)
1216 { 1235 {
1217 OscarConnection *conn; 1236 FlapConnection *conn;
1218 FlapFrame *fr; 1237 FlapFrame *frame;
1219 aim_snacid_t snacid; 1238 aim_snacid_t snacid;
1220 aim_tlvlist_t *tl = NULL; 1239 aim_tlvlist_t *tl = NULL;
1221 1240
1222 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE))) 1241 if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
1223 return -EINVAL; 1242 return -EINVAL;
1224 1243
1225 aim_tlvlist_add_16(&tl, 0x000a, privacy); 1244 aim_tlvlist_add_16(&tl, 0x000a, privacy);
1226 1245
1227 if (first) 1246 if (first)
1244 aim_tlvlist_add_str(&tl, 0x000d, zip); 1263 aim_tlvlist_add_str(&tl, 0x000d, zip);
1245 1264
1246 if (street) 1265 if (street)
1247 aim_tlvlist_add_str(&tl, 0x0021, street); 1266 aim_tlvlist_add_str(&tl, 0x0021, street);
1248 1267
1249 if (!(fr = flap_frame_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl)))) 1268 frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(&tl));
1250 return -ENOMEM; 1269
1251 1270 snacid = aim_cachesnac(od, 0x0002, 0x0009, 0x0000, NULL, 0);
1252 snacid = aim_cachesnac(sess, 0x0002, 0x0009, 0x0000, NULL, 0); 1271
1253 1272 aim_putsnac(&frame->data, 0x0002, 0x0009, 0x0000, snacid);
1254 aim_putsnac(&fr->data, 0x0002, 0x0009, 0x0000, snacid); 1273 aim_tlvlist_write(&frame->data, &tl);
1255 aim_tlvlist_write(&fr->data, &tl);
1256 aim_tlvlist_free(&tl); 1274 aim_tlvlist_free(&tl);
1257 1275
1258 aim_tx_enqueue(sess, fr); 1276 flap_connection_send(conn, frame);
1259 1277
1260 return 0; 1278 return 0;
1261 } 1279 }
1262 1280
1263 /* 1281 /*
1264 * Subtype 0x000b - Huh? What is this? 1282 * Subtype 0x000b - Huh? What is this?
1265 */ 1283 */
1266 faim_export int aim_locate_000b(OscarSession *sess, const char *sn) 1284 int aim_locate_000b(OscarData *od, const char *sn)
1267 { 1285 {
1268 OscarConnection *conn; 1286 FlapConnection *conn;
1269 FlapFrame *fr; 1287 FlapFrame *frame;
1270 aim_snacid_t snacid; 1288 aim_snacid_t snacid;
1271 1289
1272 return -EINVAL; 1290 return -EINVAL;
1273 1291
1274 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)) || !sn) 1292 if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn)
1275 return -EINVAL; 1293 return -EINVAL;
1276 1294
1277 if (!(fr = flap_frame_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)))) 1295 frame = flap_frame_new(od, 0x02, 10+1+strlen(sn));
1278 return -ENOMEM; 1296
1279 1297 snacid = aim_cachesnac(od, 0x0002, 0x000b, 0x0000, NULL, 0);
1280 snacid = aim_cachesnac(sess, 0x0002, 0x000b, 0x0000, NULL, 0); 1298
1281 1299 aim_putsnac(&frame->data, 0x0002, 0x000b, 0x0000, snacid);
1282 aim_putsnac(&fr->data, 0x0002, 0x000b, 0x0000, snacid); 1300 byte_stream_put8(&frame->data, strlen(sn));
1283 aimbs_put8(&fr->data, strlen(sn)); 1301 byte_stream_putstr(&frame->data, sn);
1284 aimbs_putstr(&fr->data, sn); 1302
1285 1303 flap_connection_send(conn, frame);
1286 aim_tx_enqueue(sess, fr);
1287 1304
1288 return 0; 1305 return 0;
1289 } 1306 }
1290 1307
1291 /* 1308 /*
1292 * Subtype 0x000f 1309 * Subtype 0x000f
1293 * 1310 *
1294 * XXX pass these in better 1311 * XXX pass these in better
1295 * 1312 *
1296 */ 1313 */
1297 faim_export int aim_locate_setinterests(OscarSession *sess, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy) 1314 int aim_locate_setinterests(OscarData *od, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy)
1298 { 1315 {
1299 OscarConnection *conn; 1316 FlapConnection *conn;
1300 FlapFrame *fr; 1317 FlapFrame *frame;
1301 aim_snacid_t snacid; 1318 aim_snacid_t snacid;
1302 aim_tlvlist_t *tl = NULL; 1319 aim_tlvlist_t *tl = NULL;
1303 1320
1304 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE))) 1321 if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
1305 return -EINVAL; 1322 return -EINVAL;
1306 1323
1307 /* ?? privacy ?? */ 1324 /* ?? privacy ?? */
1308 aim_tlvlist_add_16(&tl, 0x000a, privacy); 1325 aim_tlvlist_add_16(&tl, 0x000a, privacy);
1309 1326
1316 if (interest4) 1333 if (interest4)
1317 aim_tlvlist_add_str(&tl, 0x0000b, interest4); 1334 aim_tlvlist_add_str(&tl, 0x0000b, interest4);
1318 if (interest5) 1335 if (interest5)
1319 aim_tlvlist_add_str(&tl, 0x0000b, interest5); 1336 aim_tlvlist_add_str(&tl, 0x0000b, interest5);
1320 1337
1321 if (!(fr = flap_frame_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl)))) 1338 frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(&tl));
1322 return -ENOMEM; 1339
1323 1340 snacid = aim_cachesnac(od, 0x0002, 0x000f, 0x0000, NULL, 0);
1324 snacid = aim_cachesnac(sess, 0x0002, 0x000f, 0x0000, NULL, 0); 1341
1325 1342 aim_putsnac(&frame->data, 0x0002, 0x000f, 0x0000, 0);
1326 aim_putsnac(&fr->data, 0x0002, 0x000f, 0x0000, 0); 1343 aim_tlvlist_write(&frame->data, &tl);
1327 aim_tlvlist_write(&fr->data, &tl);
1328 aim_tlvlist_free(&tl); 1344 aim_tlvlist_free(&tl);
1329 1345
1330 aim_tx_enqueue(sess, fr); 1346 flap_connection_send(conn, frame);
1331 1347
1332 return 0; 1348 return 0;
1333 } 1349 }
1334 1350
1335 /* 1351 /*
1342 * 0x00000002 - Away message. 1358 * 0x00000002 - Away message.
1343 * 0x00000004 - Capabilities. 1359 * 0x00000004 - Capabilities.
1344 * 0x00000008 - Certification. 1360 * 0x00000008 - Certification.
1345 * @return Return 0 if no errors, otherwise return the error number. 1361 * @return Return 0 if no errors, otherwise return the error number.
1346 */ 1362 */
1347 faim_export int aim_locate_getinfoshort(OscarSession *sess, const char *sn, guint32 flags) 1363 int aim_locate_getinfoshort(OscarData *od, const char *sn, guint32 flags)
1348 { 1364 {
1349 OscarConnection *conn; 1365 FlapConnection *conn;
1350 FlapFrame *fr; 1366 FlapFrame *frame;
1351 aim_snacid_t snacid; 1367 aim_snacid_t snacid;
1352 1368
1353 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)) || !sn) 1369 if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn)
1354 return -EINVAL; 1370 return -EINVAL;
1355 1371
1356 if (!(fr = flap_frame_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+1+strlen(sn)))) 1372 frame = flap_frame_new(od, 0x02, 10+4+1+strlen(sn));
1357 return -ENOMEM; 1373
1358 1374 snacid = aim_cachesnac(od, 0x0002, 0x0015, 0x0000, sn, strlen(sn)+1);
1359 snacid = aim_cachesnac(sess, 0x0002, 0x0015, 0x0000, sn, strlen(sn)+1); 1375
1360 1376 aim_putsnac(&frame->data, 0x0002, 0x0015, 0x0000, snacid);
1361 aim_putsnac(&fr->data, 0x0002, 0x0015, 0x0000, snacid); 1377 byte_stream_put32(&frame->data, flags);
1362 aimbs_put32(&fr->data, flags); 1378 byte_stream_put8(&frame->data, strlen(sn));
1363 aimbs_put8(&fr->data, strlen(sn)); 1379 byte_stream_putstr(&frame->data, sn);
1364 aimbs_putstr(&fr->data, sn); 1380
1365 1381 flap_connection_send(conn, frame);
1366 aim_tx_enqueue(sess, fr);
1367 1382
1368 return 0; 1383 return 0;
1369 } 1384 }
1370 1385
1371 static int snachandler(OscarSession *sess, aim_module_t *mod, FlapFrame *rx, aim_modsnac_t *snac, ByteStream *bs) 1386 static int
1372 { 1387 snachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
1373 1388 {
1374 if (snac->subtype == 0x0001) 1389 if (snac->subtype == 0x0001)
1375 return error(sess, mod, rx, snac, bs); 1390 return error(od, conn, mod, frame, snac, bs);
1376 else if (snac->subtype == 0x0003) 1391 else if (snac->subtype == 0x0003)
1377 return rights(sess, mod, rx, snac, bs); 1392 return rights(od, conn, mod, frame, snac, bs);
1378 else if (snac->subtype == 0x0006) 1393 else if (snac->subtype == 0x0006)
1379 return userinfo(sess, mod, rx, snac, bs); 1394 return userinfo(od, conn, mod, frame, snac, bs);
1380 1395
1381 return 0; 1396 return 0;
1382 } 1397 }
1383 1398
1384 static void locate_shutdown(OscarSession *sess, aim_module_t *mod) 1399 static void
1400 locate_shutdown(OscarData *od, aim_module_t *mod)
1385 { 1401 {
1386 aim_userinfo_t *del; 1402 aim_userinfo_t *del;
1387 1403
1388 while (sess->locate.userinfo) { 1404 while (od->locate.userinfo) {
1389 del = sess->locate.userinfo; 1405 del = od->locate.userinfo;
1390 sess->locate.userinfo = sess->locate.userinfo->next; 1406 od->locate.userinfo = od->locate.userinfo->next;
1391 aim_info_free(del); 1407 aim_info_free(del);
1392 free(del); 1408 free(del);
1393 } 1409 }
1394 } 1410 }
1395 1411
1396 faim_internal int locate_modfirst(OscarSession *sess, aim_module_t *mod) 1412 int
1397 { 1413 locate_modfirst(OscarData *od, aim_module_t *mod)
1398 1414 {
1399 mod->family = OSCAR_FAMILY_LOCATE; 1415 mod->family = SNAC_FAMILY_LOCATE;
1400 mod->version = 0x0001; 1416 mod->version = 0x0001;
1401 mod->toolid = 0x0110; 1417 mod->toolid = 0x0110;
1402 mod->toolversion = 0x0629; 1418 mod->toolversion = 0x0629;
1403 mod->flags = 0; 1419 mod->flags = 0;
1404 strncpy(mod->name, "locate", sizeof(mod->name)); 1420 strncpy(mod->name, "locate", sizeof(mod->name));