Annotation of ChivanetAimPidgin/oscarprpl/src/c/util.c, revision 1.1

1.1     ! snw         1: /*
        !             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.
        !             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., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  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: 
        !            30: #include "core.h"
        !            31: 
        !            32: #include <ctype.h>
        !            33: 
        !            34: #ifdef _WIN32
        !            35: #include "win32dep.h"
        !            36: #endif
        !            37: 
        !            38: static const char * const msgerrreason[] = {
        !            39:        N_("Invalid error"),
        !            40:        N_("Invalid SNAC"),
        !            41:        N_("Server rate limit exceeded"),
        !            42:        N_("Client rate limit exceeded"),
        !            43:        N_("Not logged in"),
        !            44:        N_("Service unavailable"),
        !            45:        N_("Service not defined"),
        !            46:        N_("Obsolete SNAC"),
        !            47:        N_("Not supported by host"),
        !            48:        N_("Not supported by client"),
        !            49:        N_("Refused by client"),
        !            50:        N_("Reply too big"),
        !            51:        N_("Responses lost"),
        !            52:        N_("Request denied"),
        !            53:        N_("Busted SNAC payload"),
        !            54:        N_("Insufficient rights"),
        !            55:        N_("In local permit/deny"),
        !            56:        N_("Warning level too high (sender)"),
        !            57:        N_("Warning level too high (receiver)"),
        !            58:        N_("User temporarily unavailable"),
        !            59:        N_("No match"),
        !            60:        N_("List overflow"),
        !            61:        N_("Request ambiguous"),
        !            62:        N_("Queue full"),
        !            63:        N_("Not while on AOL")
        !            64: };
        !            65: static const gsize msgerrreasonlen = G_N_ELEMENTS(msgerrreason);
        !            66: 
        !            67: const char *oscar_get_msgerr_reason(size_t reason)
        !            68: {
        !            69:        return (reason < msgerrreasonlen) ? _(msgerrreason[reason]) : _("Unknown reason");
        !            70: }
        !            71: 
        !            72: int oscar_get_ui_info_int(const char *str, int default_value)
        !            73: {
        !            74:        GHashTable *ui_info;
        !            75: 
        !            76:        ui_info = purple_core_get_ui_info();
        !            77:        if (ui_info != NULL) {
        !            78:                gpointer value;
        !            79:                if (g_hash_table_lookup_extended(ui_info, str, NULL, &value))
        !            80:                        return GPOINTER_TO_INT(value);
        !            81:        }
        !            82: 
        !            83:        return default_value;
        !            84: }
        !            85: 
        !            86: const char *oscar_get_ui_info_string(const char *str, const char *default_value)
        !            87: {
        !            88:        GHashTable *ui_info;
        !            89:        const char *value = NULL;
        !            90: 
        !            91:        ui_info = purple_core_get_ui_info();
        !            92:        if (ui_info != NULL)
        !            93:                value = g_hash_table_lookup(ui_info, str);
        !            94:        if (value == NULL)
        !            95:                value = default_value;
        !            96: 
        !            97:        return value;
        !            98: }
        !            99: 
        !           100: gchar *oscar_get_clientstring(void)
        !           101: {
        !           102:        const char *name, *version;
        !           103: 
        !           104:        name = oscar_get_ui_info_string("name", "Purple");
        !           105:        version = oscar_get_ui_info_string("version", VERSION);
        !           106: 
        !           107:        return g_strdup_printf("%s/%s", name, version);;
        !           108: }
        !           109: 
        !           110: /**
        !           111:  * Calculate the checksum of a given icon.
        !           112:  */
        !           113: guint16
        !           114: aimutil_iconsum(const guint8 *buf, int buflen)
        !           115: {
        !           116:        guint32 sum;
        !           117:        int i;
        !           118: 
        !           119:        for (i=0, sum=0; i+1<buflen; i+=2)
        !           120:                sum += (buf[i+1] << 8) + buf[i];
        !           121:        if (i < buflen)
        !           122:                sum += buf[i];
        !           123:        sum = ((sum & 0xffff0000) >> 16) + (sum & 0x0000ffff);
        !           124: 
        !           125:        return sum;
        !           126: }
        !           127: 
        !           128: /**
        !           129:  * Check if the given name is a valid AIM username.
        !           130:  * Example: BobDole
        !           131:  * Example: Henry_Ford@mac.com
        !           132:  * Example: 1KrazyKat@example.com
        !           133:  *
        !           134:  * @return TRUE if the name is valid, FALSE if not.
        !           135:  */
        !           136: static gboolean
        !           137: oscar_util_valid_name_aim(const char *name)
        !           138: {
        !           139:        int i;
        !           140: 
        !           141:        if (purple_email_is_valid(name))
        !           142:                return TRUE;
        !           143: 
        !           144:        /* Normal AIM usernames can't start with a number, period or underscore */
        !           145:        if (isalnum(name[0]) == 0)
        !           146:                return FALSE;
        !           147: 
        !           148:        for (i = 0; name[i] != '\0'; i++) {
        !           149:                if (!isalnum(name[i]) && name[i] != ' ' && name[i] != '.' && name[i] != '_')
        !           150:                        return FALSE;
        !           151:        }
        !           152: 
        !           153:        return TRUE;
        !           154: }
        !           155: 
        !           156: /**
        !           157:  * Check if the given name is a valid ICQ username.
        !           158:  * Example: 1234567
        !           159:  *
        !           160:  * @return TRUE if the name is valid, FALSE if not.
        !           161:  */
        !           162: gboolean
        !           163: oscar_util_valid_name_icq(const char *name)
        !           164: {
        !           165:        int i;
        !           166: 
        !           167:        for (i = 0; name[i] != '\0'; i++) {
        !           168:                if (!isdigit(name[i]))
        !           169:                        return FALSE;
        !           170:        }
        !           171: 
        !           172:        return TRUE;
        !           173: }
        !           174: 
        !           175: /**
        !           176:  * Check if the given name is a valid SMS username.
        !           177:  * Example: +19195551234
        !           178:  *
        !           179:  * @return TRUE if the name is valid, FALSE if not.
        !           180:  */
        !           181: gboolean
        !           182: oscar_util_valid_name_sms(const char *name)
        !           183: {
        !           184:        int i;
        !           185: 
        !           186:        if (name[0] != '+')
        !           187:                return FALSE;
        !           188: 
        !           189:        for (i = 1; name[i] != '\0'; i++) {
        !           190:                if (!isdigit(name[i]))
        !           191:                        return FALSE;
        !           192:        }
        !           193: 
        !           194:        return TRUE;
        !           195: }
        !           196: 
        !           197: /**
        !           198:  * Check if the given name is a valid oscar username.
        !           199:  *
        !           200:  * @return TRUE if the name is valid, FALSE if not.
        !           201:  */
        !           202: gboolean
        !           203: oscar_util_valid_name(const char *name)
        !           204: {
        !           205:        if ((name == NULL) || (*name == '\0'))
        !           206:                return FALSE;
        !           207: 
        !           208:        return oscar_util_valid_name_icq(name)
        !           209:                        || oscar_util_valid_name_sms(name)
        !           210:                        || oscar_util_valid_name_aim(name);
        !           211: }
        !           212: 
        !           213: /**
        !           214:  * This takes two names and compares them using the rules
        !           215:  * on usernames for AIM/AOL.  Mainly, this means case and space
        !           216:  * insensitivity (all case differences and spacing differences are
        !           217:  * ignored, with the exception that usernames can not start with
        !           218:  * a space).
        !           219:  *
        !           220:  * @return 0 if equal, non-0 if different
        !           221:  */
        !           222: /* TODO: Do something different for email addresses. */
        !           223: int
        !           224: oscar_util_name_compare(const char *name1, const char *name2)
        !           225: {
        !           226: 
        !           227:        if ((name1 == NULL) || (name2 == NULL))
        !           228:                return -1;
        !           229: 
        !           230:        do {
        !           231:                while (*name2 == ' ')
        !           232:                        name2++;
        !           233:                while (*name1 == ' ')
        !           234:                        name1++;
        !           235:                if (toupper(*name1) != toupper(*name2))
        !           236:                        return 1;
        !           237:        } while ((*name1 != '\0') && name1++ && name2++);
        !           238: 
        !           239:        return 0;
        !           240: }
        !           241: 
        !           242: /**
        !           243:  * Looks for %n, %d, or %t in a string, and replaces them with the
        !           244:  * specified name, date, and time, respectively.
        !           245:  *
        !           246:  * @param str  The string that may contain the special variables.
        !           247:  * @param name The sender name.
        !           248:  *
        !           249:  * @return A newly allocated string where the special variables are
        !           250:  *         expanded.  This should be g_free'd by the caller.
        !           251:  */
        !           252: gchar *
        !           253: oscar_util_format_string(const char *str, const char *name)
        !           254: {
        !           255:        char *c;
        !           256:        GString *cpy;
        !           257:        time_t t;
        !           258:        struct tm *tme;
        !           259: 
        !           260:        g_return_val_if_fail(str  != NULL, NULL);
        !           261:        g_return_val_if_fail(name != NULL, NULL);
        !           262: 
        !           263:        /* Create an empty GString that is hopefully big enough for most messages */
        !           264:        cpy = g_string_sized_new(1024);
        !           265: 
        !           266:        t = time(NULL);
        !           267:        tme = localtime(&t);
        !           268: 
        !           269:        c = (char *)str;
        !           270:        while (*c) {
        !           271:                switch (*c) {
        !           272:                case '%':
        !           273:                        if (*(c + 1)) {
        !           274:                                switch (*(c + 1)) {
        !           275:                                case 'n':
        !           276:                                        /* append name */
        !           277:                                        g_string_append(cpy, name);
        !           278:                                        c++;
        !           279:                                        break;
        !           280:                                case 'd':
        !           281:                                        /* append date */
        !           282:                                        g_string_append(cpy, purple_date_format_short(tme));
        !           283:                                        c++;
        !           284:                                        break;
        !           285:                                case 't':
        !           286:                                        /* append time */
        !           287:                                        g_string_append(cpy, purple_time_format(tme));
        !           288:                                        c++;
        !           289:                                        break;
        !           290:                                default:
        !           291:                                        g_string_append_c(cpy, *c);
        !           292:                                }
        !           293:                        } else {
        !           294:                                g_string_append_c(cpy, *c);
        !           295:                        }
        !           296:                        break;
        !           297:                default:
        !           298:                        g_string_append_c(cpy, *c);
        !           299:                }
        !           300:                c++;
        !           301:        }
        !           302: 
        !           303:        return g_string_free(cpy, FALSE);
        !           304: }
        !           305: 
        !           306: gchar *
        !           307: oscar_format_buddies(GSList *buddies, const gchar *no_buddies_message)
        !           308: {
        !           309:        GSList *cur;
        !           310:        GString *result;
        !           311:        if (!buddies) {
        !           312:                return g_strdup_printf("<i>%s</i>", no_buddies_message);
        !           313:        }
        !           314:        result = g_string_new("");
        !           315:        for (cur = buddies; cur != NULL; cur = cur->next) {
        !           316:                PurpleBuddy *buddy = cur->data;
        !           317:                const gchar *bname = purple_buddy_get_name(buddy);
        !           318:                const gchar *alias = purple_buddy_get_alias_only(buddy);
        !           319:                g_string_append(result, bname);
        !           320:                if (alias) {
        !           321:                        g_string_append_printf(result, " (%s)", alias);
        !           322:                }
        !           323:                g_string_append(result, "<br>");
        !           324:        }
        !           325:        return g_string_free(result, FALSE);
        !           326: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>