2 * Purple's oscar protocol plugin
3 * This file is the legal property of its developers.
4 * Please see the AUTHORS file distributed alongside this file.
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 * A little bit of this
23 * A little bit of that
24 * It started with a kiss
34 static const char * const msgerrreason
[] = {
37 N_("Server rate limit exceeded"),
38 N_("Client rate limit exceeded"),
40 N_("Service unavailable"),
41 N_("Service not defined"),
43 N_("Not supported by host"),
44 N_("Not supported by client"),
45 N_("Refused by client"),
49 N_("Busted SNAC payload"),
50 N_("Insufficient rights"),
51 N_("In local permit/deny"),
52 N_("Warning level too high (sender)"),
53 N_("Warning level too high (receiver)"),
54 N_("User temporarily unavailable"),
57 N_("Request ambiguous"),
59 N_("Not while on AOL")
61 static const gsize msgerrreasonlen
= G_N_ELEMENTS(msgerrreason
);
63 const char *oscar_get_msgerr_reason(size_t reason
)
65 return (reason
< msgerrreasonlen
) ? _(msgerrreason
[reason
]) : _("Unknown reason");
68 int oscar_get_ui_info_int(const char *str
, int default_value
)
72 ui_info
= purple_core_get_ui_info();
73 if (ui_info
!= NULL
) {
75 if (g_hash_table_lookup_extended(ui_info
, str
, NULL
, &value
))
76 return GPOINTER_TO_INT(value
);
82 const char *oscar_get_ui_info_string(const char *str
, const char *default_value
)
85 const char *value
= NULL
;
87 ui_info
= purple_core_get_ui_info();
89 value
= g_hash_table_lookup(ui_info
, str
);
91 value
= default_value
;
96 gchar
*oscar_get_clientstring(void)
98 const char *name
, *version
;
100 name
= oscar_get_ui_info_string("name", "Purple");
101 version
= oscar_get_ui_info_string("version", VERSION
);
103 return g_strdup_printf("%s/%s", name
, version
);;
107 * Calculate the checksum of a given icon.
110 aimutil_iconsum(const guint8
*buf
, int buflen
)
115 for (i
=0, sum
=0; i
+1<buflen
; i
+=2)
116 sum
+= (buf
[i
+1] << 8) + buf
[i
];
119 sum
= ((sum
& 0xffff0000) >> 16) + (sum
& 0x0000ffff);
125 * Check if the given name is a valid AIM username.
127 * Example: Henry_Ford@mac.com
128 * Example: 1KrazyKat@example.com
130 * @return TRUE if the name is valid, FALSE if not.
133 oscar_util_valid_name_aim(const char *name
)
137 if (purple_email_is_valid(name
))
140 /* Normal AIM usernames can't start with a number, period or underscore */
141 if (isalnum(name
[0]) == 0)
144 for (i
= 0; name
[i
] != '\0'; i
++) {
145 if (!isalnum(name
[i
]) && name
[i
] != ' ' && name
[i
] != '.' && name
[i
] != '_')
153 * Check if the given name is a valid ICQ username.
156 * @return TRUE if the name is valid, FALSE if not.
159 oscar_util_valid_name_icq(const char *name
)
163 for (i
= 0; name
[i
] != '\0'; i
++) {
164 if (!isdigit(name
[i
]))
172 * Check if the given name is a valid SMS username.
173 * Example: +19195551234
175 * @return TRUE if the name is valid, FALSE if not.
178 oscar_util_valid_name_sms(const char *name
)
185 for (i
= 1; name
[i
] != '\0'; i
++) {
186 if (!isdigit(name
[i
]))
194 * Check if the given name is a valid oscar username.
196 * @return TRUE if the name is valid, FALSE if not.
199 oscar_util_valid_name(const char *name
)
201 if ((name
== NULL
) || (*name
== '\0'))
204 return oscar_util_valid_name_icq(name
)
205 || oscar_util_valid_name_sms(name
)
206 || oscar_util_valid_name_aim(name
);
210 * This takes two names and compares them using the rules
211 * on usernames for AIM/AOL. Mainly, this means case and space
212 * insensitivity (all case differences and spacing differences are
213 * ignored, with the exception that usernames can not start with
216 * @return 0 if equal, non-0 if different
218 /* TODO: Do something different for email addresses. */
220 oscar_util_name_compare(const char *name1
, const char *name2
)
223 if ((name1
== NULL
) || (name2
== NULL
))
227 while (*name2
== ' ')
229 while (*name1
== ' ')
231 if (toupper(*name1
) != toupper(*name2
))
233 } while ((*name1
!= '\0') && name1
++ && name2
++);
239 * Looks for %n, %d, or %t in a string, and replaces them with the
240 * specified name, date, and time, respectively.
242 * @param str The string that may contain the special variables.
243 * @param name The sender name.
245 * @return A newly allocated string where the special variables are
246 * expanded. This should be g_free'd by the caller.
249 oscar_util_format_string(const char *str
, const char *name
)
256 g_return_val_if_fail(str
!= NULL
, NULL
);
257 g_return_val_if_fail(name
!= NULL
, NULL
);
259 /* Create an empty GString that is hopefully big enough for most messages */
260 cpy
= g_string_sized_new(1024);
273 g_string_append(cpy
, name
);
278 g_string_append(cpy
, purple_date_format_short(tme
));
283 g_string_append(cpy
, purple_time_format(tme
));
287 g_string_append_c(cpy
, *c
);
290 g_string_append_c(cpy
, *c
);
294 g_string_append_c(cpy
, *c
);
299 return g_string_free(cpy
, FALSE
);
303 oscar_format_buddies(GSList
*buddies
, const gchar
*no_buddies_message
)
308 return g_strdup_printf("<i>%s</i>", no_buddies_message
);
310 result
= g_string_new("");
311 for (cur
= buddies
; cur
!= NULL
; cur
= cur
->next
) {
312 PurpleBuddy
*buddy
= cur
->data
;
313 const gchar
*bname
= purple_buddy_get_name(buddy
);
314 const gchar
*alias
= purple_buddy_get_alias_only(buddy
);
315 g_string_append(result
, bname
);
317 g_string_append_printf(result
, " (%s)", alias
);
319 g_string_append(result
, "<br>");
321 return g_string_free(result
, FALSE
);