2
|
1 /*
|
|
2 aim_info.c
|
|
3
|
|
4 The functions here are responsible for requesting and parsing information-
|
|
5 gathering SNACs.
|
|
6
|
|
7 */
|
|
8
|
|
9
|
|
10 #include "aim.h" /* for most everything */
|
|
11
|
|
12 u_long aim_getinfo(struct aim_conn_t *conn, const char *sn)
|
|
13 {
|
|
14 struct command_tx_struct newpacket;
|
|
15
|
|
16 if (conn)
|
|
17 newpacket.conn = conn;
|
|
18 else
|
|
19 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
|
|
20
|
|
21 newpacket.lock = 1;
|
|
22 newpacket.type = 0x0002;
|
|
23
|
|
24 newpacket.commandlen = 12 + 1 + strlen(sn);
|
|
25 newpacket.data = (char *) malloc(newpacket.commandlen);
|
|
26
|
|
27 newpacket.data[0] = 0x00;
|
|
28 newpacket.data[1] = 0x02;
|
|
29 newpacket.data[2] = 0x00;
|
|
30 newpacket.data[3] = 0x05;
|
|
31 newpacket.data[4] = 0x00;
|
|
32 newpacket.data[5] = 0x00;
|
|
33
|
|
34 /* SNAC reqid */
|
|
35 newpacket.data[6] = (aim_snac_nextid >> 24) & 0xFF;
|
|
36 newpacket.data[7] = (aim_snac_nextid >> 16) & 0xFF;
|
|
37 newpacket.data[8] = (aim_snac_nextid >> 8) & 0xFF;
|
|
38 newpacket.data[9] = (aim_snac_nextid) & 0xFF;
|
|
39
|
|
40 /* TLV: Screen Name */
|
|
41 /* t(0x0001) */
|
|
42 newpacket.data[10] = 0x00;
|
|
43 newpacket.data[11] = 0x01;
|
|
44 /* l() */
|
|
45 newpacket.data[12] = strlen(sn);
|
|
46 /* v() */
|
|
47 memcpy(&(newpacket.data[13]), sn, strlen(sn));
|
|
48
|
|
49 aim_tx_enqueue(&newpacket);
|
|
50
|
|
51 {
|
|
52 struct aim_snac_t snac;
|
|
53
|
|
54 snac.id = aim_snac_nextid;
|
|
55 snac.family = 0x0002;
|
|
56 snac.type = 0x0005;
|
|
57 snac.flags = 0x0000;
|
|
58
|
|
59 snac.data = malloc(strlen(sn)+1);
|
|
60 memcpy(snac.data, sn, strlen(sn)+1);
|
|
61
|
|
62 aim_newsnac(&snac);
|
|
63 }
|
|
64
|
|
65 return (aim_snac_nextid++);
|
|
66 }
|
|
67
|
|
68 /*
|
|
69 * This parses the user info stuff out all nice and pretty then calls
|
|
70 * the higher-level callback (in the user app).
|
|
71 *
|
|
72 */
|
|
73
|
|
74 int aim_parse_userinfo_middle(struct command_rx_struct *command)
|
|
75 {
|
|
76 char *sn = NULL;
|
|
77 char *prof_encoding = NULL;
|
|
78 char *prof = NULL;
|
|
79 u_short warnlevel = 0x0000;
|
|
80 u_short idletime = 0x0000;
|
|
81 u_short class = 0x0000;
|
|
82 u_long membersince = 0x00000000;
|
|
83 u_long onlinesince = 0x00000000;
|
|
84 int tlvcnt = 0;
|
|
85 int i = 0;
|
|
86
|
|
87 {
|
|
88 u_long snacid = 0x000000000;
|
|
89 struct aim_snac_t *snac = NULL;
|
|
90
|
|
91 snacid = (command->data[6] << 24) & 0xFF000000;
|
|
92 snacid+= (command->data[7] << 16) & 0x00FF0000;
|
|
93 snacid+= (command->data[8] << 8) & 0x0000FF00;
|
|
94 snacid+= (command->data[9]) & 0x000000FF;
|
|
95
|
|
96 snac = aim_remsnac(snacid);
|
|
97
|
|
98 free(snac->data);
|
|
99 free(snac);
|
|
100
|
|
101 }
|
|
102
|
|
103 sn = (char *) malloc(command->data[10]+1);
|
|
104 memcpy(sn, &(command->data[11]), command->data[10]);
|
|
105 sn[(int)command->data[10]] = '\0';
|
|
106
|
|
107 i = 11 + command->data[10];
|
|
108 warnlevel = ((command->data[i++]) << 8) & 0xFF00;
|
|
109 warnlevel += (command->data[i++]) & 0x00FF;
|
|
110
|
|
111 tlvcnt = ((command->data[i++]) << 8) & 0xFF00;
|
|
112 tlvcnt += (command->data[i++]) & 0x00FF;
|
|
113
|
|
114 /* a mini TLV parser */
|
|
115 {
|
|
116 int curtlv = 0;
|
|
117 int tlv1 = 0;
|
|
118
|
|
119 while (curtlv < tlvcnt)
|
|
120 {
|
|
121 if ((command->data[i] == 0x00) &&
|
|
122 (command->data[i+1] == 0x01) )
|
|
123 {
|
|
124 if (tlv1)
|
|
125 break;
|
|
126 /* t(0001) = class */
|
|
127 class = ((command->data[i+4]) << 8) & 0xFF00;
|
|
128 class += (command->data[i+5]) & 0x00FF;
|
|
129 i += (2 + 2 + command->data[i+3]);
|
|
130 tlv1++;
|
|
131 }
|
|
132 else if ((command->data[i] == 0x00) &&
|
|
133 (command->data[i+1] == 0x02))
|
|
134 {
|
|
135 /* t(0002) = member since date */
|
|
136 if (command->data[i+3] != 0x04)
|
|
137 printf("faim: userinfo: **warning: strange v(%x) for t(2)\n", command->data[i+3]);
|
|
138
|
|
139 membersince = ((command->data[i+4]) << 24) & 0xFF000000;
|
|
140 membersince += ((command->data[i+5]) << 16) & 0x00FF0000;
|
|
141 membersince += ((command->data[i+6]) << 8) & 0x0000FF00;
|
|
142 membersince += ((command->data[i+7]) ) & 0x000000FF;
|
|
143 i += (2 + 2 + command->data[i+3]);
|
|
144 }
|
|
145 else if ((command->data[i] == 0x00) &&
|
|
146 (command->data[i+1] == 0x03))
|
|
147 {
|
|
148 /* t(0003) = on since date */
|
|
149 if (command->data[i+3] != 0x04)
|
|
150 printf("faim: userinfo: **warning: strange v(%x) for t(3)\n", command->data[i+3]);
|
|
151
|
|
152 onlinesince = ((command->data[i+4]) << 24) & 0xFF000000;
|
|
153 onlinesince += ((command->data[i+5]) << 16) & 0x00FF0000;
|
|
154 onlinesince += ((command->data[i+6]) << 8) & 0x0000FF00;
|
|
155 onlinesince += ((command->data[i+7]) ) & 0x000000FF;
|
|
156 i += (2 + 2 + command->data[i+3]);
|
|
157 }
|
|
158 else if ((command->data[i] == 0x00) &&
|
|
159 (command->data[i+1] == 0x04) )
|
|
160 {
|
|
161 /* t(0004) = idle time */
|
|
162 if (command->data[i+3] != 0x02)
|
|
163 printf("faim: userinfo: **warning: strange v(%x) for t(4)\n", command->data[i+3]);
|
|
164 idletime = ((command->data[i+4]) << 8) & 0xFF00;
|
|
165 idletime += (command->data[i+5]) & 0x00FF;
|
|
166 i += (2 + 2 + command->data[i+3]);
|
|
167 }
|
|
168 else
|
|
169 {
|
|
170 printf("faim: userinfo: **warning: unexpected TLV t(%02x%02x) l(%02x%02x)\n", command->data[i], command->data[i+1], command->data[i+2], command->data[i+3]);
|
|
171 i += (2 + 2 + command->data[i+3]);
|
|
172 }
|
|
173 curtlv++;
|
|
174 }
|
|
175 }
|
|
176 if (i < command->commandlen)
|
|
177 {
|
|
178 if ( (command->data[i] == 0x00) &&
|
|
179 (command->data[i+1] == 0x01) )
|
|
180 {
|
|
181 int len = 0;
|
|
182
|
|
183 len = ((command->data[i+2] << 8) & 0xFF00);
|
|
184 len += (command->data[i+3]) & 0x00FF;
|
|
185
|
|
186 prof_encoding = (char *) malloc(len+1);
|
|
187 memcpy(prof_encoding, &(command->data[i+4]), len);
|
|
188 prof_encoding[len] = '\0';
|
|
189
|
|
190 i += (2+2+len);
|
|
191 }
|
|
192 else
|
|
193 {
|
|
194 printf("faim: userinfo: **warning: unexpected TLV after TLVblock t(%02x%02x) l(%02x%02x)\n", command->data[i], command->data[i+1], command->data[i+2], command->data[i+3]);
|
|
195 i += 2 + 2 + command->data[i+3];
|
|
196 }
|
|
197 }
|
|
198
|
|
199 if (i < command->commandlen)
|
|
200 {
|
|
201 int len = 0;
|
|
202
|
|
203 len = ((command->data[i+2]) << 8) & 0xFF00;
|
|
204 len += (command->data[i+3]) & 0x00FF;
|
|
205
|
|
206 prof = (char *) malloc(len+1);
|
|
207 memcpy(prof, &(command->data[i+4]), len);
|
|
208 prof[len] = '\0';
|
|
209 }
|
|
210 else
|
|
211 printf("faim: userinfo: **early parse abort...no profile?\n");
|
|
212
|
|
213 i = (aim_callbacks[AIM_CB_USERINFO])(command, sn, prof_encoding, prof, warnlevel, idletime, class, membersince, onlinesince);
|
|
214
|
|
215 free(sn);
|
|
216 free(prof_encoding);
|
|
217 free(prof);
|
|
218
|
|
219 return i;
|
|
220 }
|