| 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 } |
|