14192
|
1 /*
|
|
2 * Gaim's oscar protocol plugin
|
|
3 * This file is the legal property of its developers.
|
|
4 * Please see the AUTHORS file distributed alongside this file.
|
|
5 *
|
|
6 * This library is free software; you can redistribute it and/or
|
|
7 * modify it under the terms of the GNU Lesser General Public
|
|
8 * License as published by the Free Software Foundation; either
|
|
9 * version 2 of the License, or (at your option) any later version.
|
|
10 *
|
|
11 * This library is distributed in the hope that it will be useful,
|
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14 * Lesser General Public License for more details.
|
|
15 *
|
|
16 * You should have received a copy of the GNU Lesser General Public
|
|
17 * License along with this library; if not, write to the Free Software
|
|
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
19 */
|
|
20
|
|
21 /*
|
|
22 * A little bit of this
|
|
23 * A little bit of that
|
|
24 * It started with a kiss
|
|
25 * Now we're up to bat
|
|
26 */
|
|
27
|
|
28 #include "oscar.h"
|
|
29 #include <ctype.h>
|
|
30
|
|
31 #ifdef _WIN32
|
|
32 #include "win32dep.h"
|
|
33 #endif
|
|
34
|
|
35 /*
|
|
36 * Tokenizing functions. Used to portably replace strtok/sep.
|
|
37 * -- DMP.
|
|
38 *
|
|
39 */
|
|
40 int
|
|
41 aimutil_tokslen(char *toSearch, int theindex, char dl)
|
|
42 {
|
|
43 int curCount = 1;
|
|
44 char *next;
|
|
45 char *last;
|
|
46 int toReturn;
|
|
47
|
|
48 last = toSearch;
|
|
49 next = strchr(toSearch, dl);
|
|
50
|
|
51 while(curCount < theindex && next != NULL) {
|
|
52 curCount++;
|
|
53 last = next + 1;
|
|
54 next = strchr(last, dl);
|
|
55 }
|
|
56
|
|
57 if ((curCount < theindex) || (next == NULL))
|
|
58 toReturn = strlen(toSearch) - (curCount - 1);
|
|
59 else
|
|
60 toReturn = next - toSearch - (curCount - 1);
|
|
61
|
|
62 return toReturn;
|
|
63 }
|
|
64
|
|
65 int
|
|
66 aimutil_itemcnt(char *toSearch, char dl)
|
|
67 {
|
|
68 int curCount;
|
|
69 char *next;
|
|
70
|
|
71 curCount = 1;
|
|
72
|
|
73 next = strchr(toSearch, dl);
|
|
74
|
|
75 while(next != NULL) {
|
|
76 curCount++;
|
|
77 next = strchr(next + 1, dl);
|
|
78 }
|
|
79
|
|
80 return curCount;
|
|
81 }
|
|
82
|
|
83 char *
|
|
84 aimutil_itemindex(char *toSearch, int theindex, char dl)
|
|
85 {
|
|
86 int curCount;
|
|
87 char *next;
|
|
88 char *last;
|
|
89 char *toReturn;
|
|
90
|
|
91 curCount = 0;
|
|
92
|
|
93 last = toSearch;
|
|
94 next = strchr(toSearch, dl);
|
|
95
|
|
96 while (curCount < theindex && next != NULL) {
|
|
97 curCount++;
|
|
98 last = next + 1;
|
|
99 next = strchr(last, dl);
|
|
100 }
|
|
101 next = strchr(last, dl);
|
|
102
|
|
103 if (curCount < theindex) {
|
|
104 toReturn = malloc(sizeof(char));
|
|
105 *toReturn = '\0';
|
|
106 } else {
|
|
107 if (next == NULL) {
|
|
108 toReturn = malloc((strlen(last) + 1) * sizeof(char));
|
|
109 strcpy(toReturn, last);
|
|
110 } else {
|
|
111 toReturn = malloc((next - last + 1) * sizeof(char));
|
|
112 memcpy(toReturn, last, (next - last));
|
|
113 toReturn[next - last] = '\0';
|
|
114 }
|
|
115 }
|
|
116 return toReturn;
|
|
117 }
|
|
118
|
|
119 /**
|
|
120 * Calculate the checksum of a given icon.
|
|
121 */
|
|
122 guint16
|
|
123 aimutil_iconsum(const guint8 *buf, int buflen)
|
|
124 {
|
|
125 guint32 sum;
|
|
126 int i;
|
|
127
|
|
128 for (i=0, sum=0; i+1<buflen; i+=2)
|
|
129 sum += (buf[i+1] << 8) + buf[i];
|
|
130 if (i < buflen)
|
|
131 sum += buf[i];
|
|
132 sum = ((sum & 0xffff0000) >> 16) + (sum & 0x0000ffff);
|
|
133
|
|
134 return sum;
|
|
135 }
|
|
136
|
|
137 /**
|
|
138 * Check if the given screen name is a valid AIM screen name.
|
|
139 * Example: BobDole
|
|
140 * Example: Henry_Ford@mac.com
|
|
141 *
|
|
142 * @return TRUE if the screen name is valid, FALSE if not.
|
|
143 */
|
|
144 static gboolean
|
|
145 aim_snvalid_aim(const char *sn)
|
|
146 {
|
|
147 int i;
|
|
148
|
|
149 for (i = 0; sn[i] != '\0'; i++) {
|
|
150 if (!isalnum(sn[i]) && (sn[i] != ' ') &&
|
|
151 (sn[i] != '@') && (sn[i] != '.') &&
|
|
152 (sn[i] != '_') && (sn[i] != '-'))
|
|
153 return FALSE;
|
|
154 }
|
|
155
|
|
156 return TRUE;
|
|
157 }
|
|
158
|
|
159 /**
|
|
160 * Check if the given screen name is a valid ICQ screen name.
|
|
161 * Example: 1234567
|
|
162 *
|
|
163 * @return TRUE if the screen name is valid, FALSE if not.
|
|
164 */
|
|
165 static gboolean
|
|
166 aim_snvalid_icq(const char *sn)
|
|
167 {
|
|
168 int i;
|
|
169
|
|
170 for (i = 0; sn[i] != '\0'; i++) {
|
|
171 if (!isdigit(sn[i]))
|
|
172 return 0;
|
|
173 }
|
|
174
|
|
175 return 1;
|
|
176 }
|
|
177
|
|
178 /**
|
|
179 * Check if the given screen name is a valid SMS screen name.
|
|
180 * Example: +19195551234
|
|
181 *
|
|
182 * @return TRUE if the screen name is valid, FALSE if not.
|
|
183 */
|
|
184 static gboolean
|
|
185 aim_snvalid_sms(const char *sn)
|
|
186 {
|
|
187 int i;
|
|
188
|
|
189 if (sn[0] != '+')
|
|
190 return 0;
|
|
191
|
|
192 for (i = 1; sn[i] != '\0'; i++) {
|
|
193 if (!isdigit(sn[i]))
|
|
194 return 0;
|
|
195 }
|
|
196
|
|
197 return 1;
|
|
198 }
|
|
199
|
|
200 /**
|
|
201 * Check if the given screen name is a valid oscar screen name.
|
|
202 *
|
|
203 * @return TRUE if the screen name is valid, FALSE if not.
|
|
204 */
|
|
205 gboolean
|
|
206 aim_snvalid(const char *sn)
|
|
207 {
|
|
208 if ((sn == NULL) || (*sn == '\0'))
|
|
209 return 0;
|
|
210
|
|
211 if (isalpha(sn[0]))
|
|
212 return aim_snvalid_aim(sn);
|
|
213 else if (isdigit(sn[0]))
|
|
214 return aim_snvalid_icq(sn);
|
|
215 else if (sn[0] == '+')
|
|
216 return aim_snvalid_sms(sn);
|
|
217
|
|
218 return 0;
|
|
219 }
|
|
220
|
|
221 /**
|
|
222 * Determine if a given screen name is an ICQ screen name
|
|
223 * (i.e. it begins with a number).
|
|
224 *
|
|
225 * @sn A valid AIM or ICQ screen name.
|
|
226 * @return TRUE if the screen name is an ICQ screen name. Otherwise
|
|
227 * FALSE is returned.
|
|
228 */
|
|
229 gboolean
|
|
230 aim_sn_is_icq(const char *sn)
|
|
231 {
|
|
232 if (isalpha(sn[0]))
|
|
233 return FALSE;
|
|
234 return TRUE;
|
|
235 }
|
|
236
|
|
237 /**
|
|
238 * Determine if a given screen name is an SMS number
|
|
239 * (i.e. it begins with a +).
|
|
240 *
|
|
241 * @sn A valid AIM or ICQ screen name.
|
|
242 * @return TRUE if the screen name is an SMS number. Otherwise
|
|
243 * FALSE is returned.
|
|
244 */
|
|
245 gboolean
|
|
246 aim_sn_is_sms(const char *sn)
|
|
247 {
|
|
248 if (sn[0] != '+')
|
|
249 return FALSE;
|
|
250 return TRUE;
|
|
251 }
|
|
252
|
|
253 /**
|
|
254 * This takes a screen name and returns its length without
|
|
255 * spaces. If there are no spaces in the SN, then the
|
|
256 * return is equal to that of strlen().
|
|
257 */
|
|
258 int
|
|
259 aim_snlen(const char *sn)
|
|
260 {
|
|
261 int i = 0;
|
|
262
|
|
263 if (!sn)
|
|
264 return 0;
|
|
265
|
|
266 while (*sn != '\0') {
|
|
267 if (*sn != ' ')
|
|
268 i++;
|
|
269 sn++;
|
|
270 }
|
|
271
|
|
272 return i;
|
|
273 }
|
|
274
|
|
275 /**
|
|
276 * This takes two screen names and compares them using the rules
|
|
277 * on screen names for AIM/AOL. Mainly, this means case and space
|
|
278 * insensitivity (all case differences and spacing differences are
|
|
279 * ignored, with the exception that screen names can not start with
|
|
280 * a space).
|
|
281 *
|
|
282 * Return: 0 if equal
|
|
283 * non-0 if different
|
|
284 */
|
|
285 int
|
|
286 aim_sncmp(const char *sn1, const char *sn2)
|
|
287 {
|
|
288
|
|
289 if ((sn1 == NULL) || (sn2 == NULL))
|
|
290 return -1;
|
|
291
|
|
292 do {
|
|
293 while (*sn2 == ' ')
|
|
294 sn2++;
|
|
295 while (*sn1 == ' ')
|
|
296 sn1++;
|
|
297 if (toupper(*sn1) != toupper(*sn2))
|
|
298 return 1;
|
|
299 } while ((*sn1 != '\0') && sn1++ && sn2++);
|
|
300
|
|
301 return 0;
|
|
302 }
|