~micahg/ubuntu/natty/pidgin/2.7.9-2

« back to all changes in this revision

Viewing changes to libpurple/util.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-08-11 14:16:15 UTC
  • mfrom: (1.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20100811141615-lsqya0vlqrnu14lo
Tags: 1:2.7.3-1ubuntu1
* Resync on Debian, workaround build issue (lp:#600952) 
* debian/control:
  - Build-Depends on liblaunchpad-integration-dev
  - Drop libpurple0 dependency from libpurple-bin
  - Drop pidgin-data dependency from libpurple0
  - Recommends pidgin-libnotify
* debian/libpurple0.symbols: 
  - add epochs
* debian/patches/02_lpi.patch:
  - launchpad integration
* debian/patches/04_let_crasher_for_apport.patch:
  - stop catching the SIGSEGV signal and let apport handle it
* debian/patches/05_default_to_irc_ubuntu_com.patch:
  - set the default IRC server to irc.ubuntu.com
* debian/patches/10_docklet_default_off.patch:
  - default behavior to have no notification area icon.
* debian/patches/11_buddy_list_really_show.patch:
  - the buddy list tries harder to appear.  This fixes some issues with it
    not appearing.
* debian/patches/ 13_sounds_and_timers.patch:
  - adjusts the time out for sounds to be 15 seconds, 
    which helps get fewer spurious login notifications on slow connections.
* debian/patches/60_1024x600_gtk*.c.patch: 
  - add scrollbars into preferences and pounce dialogs
* debian/prefs.xml: 
  - Update to set the notify plugin prefs /plugins/gtk/X11/notify/*, 
    set /pidgin/plugins/loaded to load the notify plugin and enable 
    the standard logging options by default
* debian/rules:
  - install a launcher in the message indicator
  - set translation domain and update template
  - use simple-patchsys rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "core.h"
29
29
#include "debug.h"
30
30
#include "notify.h"
 
31
#include "ntlm.h"
31
32
#include "prpl.h"
32
33
#include "prefs.h"
33
34
#include "util.h"
69
70
        unsigned long data_len;
70
71
        gssize max_len;
71
72
        gboolean chunked;
 
73
        PurpleAccount *account;
72
74
};
73
75
 
74
76
static char *custom_user_dir = NULL;
2053
2055
        return FALSE;
2054
2056
}
2055
2057
 
 
2058
static const char *
 
2059
process_link(GString *ret,
 
2060
                const char *start, const char *c,
 
2061
                int matchlen,
 
2062
                const char *urlprefix,
 
2063
                int inside_paren)
 
2064
{
 
2065
        char *url_buf, *tmpurlbuf;
 
2066
        const char *t;
 
2067
 
 
2068
        for (t = c;; t++) {
 
2069
                if (!badchar(*t) && !badentity(t))
 
2070
                        continue;
 
2071
 
 
2072
                if (t - c == matchlen)
 
2073
                        break;
 
2074
 
 
2075
                if (*t == ',' && *(t + 1) != ' ') {
 
2076
                        continue;
 
2077
                }
 
2078
 
 
2079
                if (t > start && *(t - 1) == '.')
 
2080
                        t--;
 
2081
                if (t > start && *(t - 1) == ')' && inside_paren > 0)
 
2082
                        t--;
 
2083
 
 
2084
                url_buf = g_strndup(c, t - c);
 
2085
                tmpurlbuf = purple_unescape_html(url_buf);
 
2086
                g_string_append_printf(ret, "<A HREF=\"%s%s\">%s</A>",
 
2087
                                urlprefix,
 
2088
                                tmpurlbuf, url_buf);
 
2089
                g_free(tmpurlbuf);
 
2090
                g_free(url_buf);
 
2091
                return t;
 
2092
        }
 
2093
 
 
2094
        return c;
 
2095
}
 
2096
 
2056
2097
char *
2057
2098
purple_markup_linkify(const char *text)
2058
2099
{
2100
2141
                                                break;
2101
2142
                                }
2102
2143
                        }
2103
 
                } else if ((*c=='h') && (!g_ascii_strncasecmp(c, "http://", 7) ||
2104
 
                                        (!g_ascii_strncasecmp(c, "https://", 8)))) {
2105
 
                        t = c;
2106
 
                        while (1) {
2107
 
                                if (badchar(*t) || badentity(t)) {
2108
 
 
2109
 
                                        if ((!g_ascii_strncasecmp(c, "http://", 7) && (t - c == 7)) ||
2110
 
                                                (!g_ascii_strncasecmp(c, "https://", 8) && (t - c == 8))) {
2111
 
                                                break;
2112
 
                                        }
2113
 
 
2114
 
                                        if (*(t) == ',' && (*(t + 1) != ' ')) {
2115
 
                                                t++;
2116
 
                                                continue;
2117
 
                                        }
2118
 
 
2119
 
                                        if (*(t - 1) == '.')
2120
 
                                                t--;
2121
 
                                        if ((*(t - 1) == ')' && (inside_paren > 0))) {
2122
 
                                                t--;
2123
 
                                        }
2124
 
 
2125
 
                                        url_buf = g_strndup(c, t - c);
2126
 
                                        tmpurlbuf = purple_unescape_html(url_buf);
2127
 
                                        g_string_append_printf(ret, "<A HREF=\"%s\">%s</A>",
2128
 
                                                        tmpurlbuf, url_buf);
2129
 
                                        g_free(url_buf);
2130
 
                                        g_free(tmpurlbuf);
2131
 
                                        c = t;
2132
 
                                        break;
2133
 
                                }
2134
 
                                t++;
2135
 
 
2136
 
                        }
2137
 
                } else if (!g_ascii_strncasecmp(c, "www.", 4) && (c == text || badchar(c[-1]) || badentity(c-1))) {
2138
 
                        if (c[4] != '.') {
2139
 
                                t = c;
2140
 
                                while (1) {
2141
 
                                        if (badchar(*t) || badentity(t)) {
2142
 
                                                if (t - c == 4) {
2143
 
                                                        break;
2144
 
                                                }
2145
 
 
2146
 
                                                if (*(t) == ',' && (*(t + 1) != ' ')) {
2147
 
                                                        t++;
2148
 
                                                        continue;
2149
 
                                                }
2150
 
 
2151
 
                                                if (*(t - 1) == '.')
2152
 
                                                        t--;
2153
 
                                                if ((*(t - 1) == ')' && (inside_paren > 0))) {
2154
 
                                                        t--;
2155
 
                                                }
2156
 
                                                url_buf = g_strndup(c, t - c);
2157
 
                                                tmpurlbuf = purple_unescape_html(url_buf);
2158
 
                                                g_string_append_printf(ret,
2159
 
                                                                "<A HREF=\"http://%s\">%s</A>", tmpurlbuf,
2160
 
                                                                url_buf);
2161
 
                                                g_free(url_buf);
2162
 
                                                g_free(tmpurlbuf);
2163
 
                                                c = t;
2164
 
                                                break;
2165
 
                                        }
2166
 
                                        t++;
2167
 
                                }
2168
 
                        }
2169
 
                } else if (!g_ascii_strncasecmp(c, "ftp://", 6) || !g_ascii_strncasecmp(c, "sftp://", 7)) {
2170
 
                        t = c;
2171
 
                        while (1) {
2172
 
                                if (badchar(*t) || badentity(t)) {
2173
 
 
2174
 
                                        if ((!g_ascii_strncasecmp(c, "ftp://", 6) && (t - c == 6)) ||
2175
 
                                                (!g_ascii_strncasecmp(c, "sftp://", 7) && (t - c == 7))) {
2176
 
                                                break;
2177
 
                                        }
2178
 
 
2179
 
                                        if (*(t - 1) == '.')
2180
 
                                                t--;
2181
 
                                        if ((*(t - 1) == ')' && (inside_paren > 0))) {
2182
 
                                                t--;
2183
 
                                        }
2184
 
                                        url_buf = g_strndup(c, t - c);
2185
 
                                        tmpurlbuf = purple_unescape_html(url_buf);
2186
 
                                        g_string_append_printf(ret, "<A HREF=\"%s\">%s</A>",
2187
 
                                                        tmpurlbuf, url_buf);
2188
 
                                        g_free(url_buf);
2189
 
                                        g_free(tmpurlbuf);
2190
 
                                        c = t;
2191
 
                                        break;
2192
 
                                }
2193
 
                                if (!t)
2194
 
                                        break;
2195
 
                                t++;
2196
 
 
2197
 
                        }
2198
 
                } else if (!g_ascii_strncasecmp(c, "ftp.", 4) && (c == text || badchar(c[-1]) || badentity(c-1))) {
2199
 
                        if (c[4] != '.') {
2200
 
                                t = c;
2201
 
                                while (1) {
2202
 
                                        if (badchar(*t) || badentity(t)) {
2203
 
                                                if (t - c == 4) {
2204
 
                                                        break;
2205
 
                                                }
2206
 
                                                if (*(t - 1) == '.')
2207
 
                                                        t--;
2208
 
                                                if ((*(t - 1) == ')' && (inside_paren > 0))) {
2209
 
                                                        t--;
2210
 
                                                }
2211
 
                                                url_buf = g_strndup(c, t - c);
2212
 
                                                tmpurlbuf = purple_unescape_html(url_buf);
2213
 
                                                g_string_append_printf(ret,
2214
 
                                                                "<A HREF=\"ftp://%s\">%s</A>", tmpurlbuf,
2215
 
                                                                url_buf);
2216
 
                                                g_free(url_buf);
2217
 
                                                g_free(tmpurlbuf);
2218
 
                                                c = t;
2219
 
                                                break;
2220
 
                                        }
2221
 
                                        if (!t)
2222
 
                                                break;
2223
 
                                        t++;
2224
 
                                }
2225
 
                        }
 
2144
                } else if (!g_ascii_strncasecmp(c, "http://", 7)) {
 
2145
                        c = process_link(ret, text, c, 7, "", inside_paren);
 
2146
                } else if (!g_ascii_strncasecmp(c, "https://", 8)) {
 
2147
                        c = process_link(ret, text, c, 8, "", inside_paren);
 
2148
                } else if (!g_ascii_strncasecmp(c, "ftp://", 6)) {
 
2149
                        c = process_link(ret, text, c, 6, "", inside_paren);
 
2150
                } else if (!g_ascii_strncasecmp(c, "sftp://", 7)) {
 
2151
                        c = process_link(ret, text, c, 7, "", inside_paren);
 
2152
                } else if (!g_ascii_strncasecmp(c, "file://", 7)) {
 
2153
                        c = process_link(ret, text, c, 7, "", inside_paren);
 
2154
                } else if (!g_ascii_strncasecmp(c, "www.", 4) && c[4] != '.' && (c == text || badchar(c[-1]) || badentity(c-1))) {
 
2155
                        c = process_link(ret, text, c, 4, "http://", inside_paren);
 
2156
                } else if (!g_ascii_strncasecmp(c, "ftp.", 4) && c[4] != '.' && (c == text || badchar(c[-1]) || badentity(c-1))) {
 
2157
                        c = process_link(ret, text, c, 4, "ftp://", inside_paren);
 
2158
                } else if (!g_ascii_strncasecmp(c, "xmpp:", 5) && (c == text || badchar(c[-1]) || badentity(c-1))) {
 
2159
                        c = process_link(ret, text, c, 5, "", inside_paren);
2226
2160
                } else if (!g_ascii_strncasecmp(c, "mailto:", 7)) {
2227
2161
                        t = c;
2228
2162
                        while (1) {
2231
2165
                                        if (t - c == 7) {
2232
2166
                                                break;
2233
2167
                                        }
2234
 
                                        if (*(t - 1) == '.')
 
2168
                                        if (t > text && *(t - 1) == '.')
2235
2169
                                                t--;
2236
2170
                                        if ((d = strstr(c + 7, "?")) != NULL && d < t)
2237
2171
                                                url_buf = g_strndup(c + 7, d - c - 7);
2251
2185
                                        c = t;
2252
2186
                                        break;
2253
2187
                                }
2254
 
                                if (!t)
2255
 
                                        break;
2256
 
                                t++;
2257
 
 
2258
 
                        }
2259
 
                } else if ((*c=='x') && (!g_ascii_strncasecmp(c, "xmpp:", 5)) &&
2260
 
                                   (c == text || badchar(c[-1]) || badentity(c-1))) {
2261
 
                        t = c;
2262
 
                        while (1) {
2263
 
                                if (badchar(*t) || badentity(t)) {
2264
 
 
2265
 
                                        if (t - c == 5) {
2266
 
                                                break;
2267
 
                                        }
2268
 
 
2269
 
                                        if (*(t) == ',' && (*(t + 1) != ' ')) {
2270
 
                                                t++;
2271
 
                                                continue;
2272
 
                                        }
2273
 
 
2274
 
                                        if (*(t - 1) == '.')
2275
 
                                                t--;
2276
 
                                        if ((*(t - 1) == ')' && (inside_paren > 0))) {
2277
 
                                                t--;
2278
 
                                        }
2279
 
 
2280
 
                                        url_buf = g_strndup(c, t - c);
2281
 
                                        tmpurlbuf = purple_unescape_html(url_buf);
2282
 
                                        g_string_append_printf(ret, "<A HREF=\"%s\">%s</A>",
2283
 
                                                        tmpurlbuf, url_buf);
2284
 
                                        g_free(url_buf);
2285
 
                                        g_free(tmpurlbuf);
2286
 
                                        c = t;
2287
 
                                        break;
2288
 
                                }
2289
 
                                t++;
2290
 
 
 
2188
                                t++;
2291
2189
                        }
2292
2190
                } else if (c != text && (*c == '@')) {
2293
2191
                        int flag;
3525
3423
                           char **ret_path, char **ret_user, char **ret_passwd)
3526
3424
{
3527
3425
        gboolean is_https = FALSE;
3528
 
        char scan_info[255];
 
3426
        const char * scan_info;
3529
3427
        char port_str[6];
3530
3428
        int f;
3531
3429
        const char *at, *slash;
3533
3431
        char host[256], path[256], user[256], passwd[256];
3534
3432
        int port = 0;
3535
3433
        /* hyphen at end includes it in control set */
3536
 
        static const char addr_ctrl[] = "A-Za-z0-9.-";
3537
 
        static const char port_ctrl[] = "0-9";
3538
 
        static const char page_ctrl[] = "A-Za-z0-9.~_/:*!@&%%?=+^-";
3539
 
        static const char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
3540
 
        static const char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
 
3434
 
 
3435
#define ADDR_CTRL "A-Za-z0-9.-"
 
3436
#define PORT_CTRL "0-9"
 
3437
#define PAGE_CTRL "A-Za-z0-9.~_/:*!@&%%?=+^-"
 
3438
#define USER_CTRL "A-Za-z0-9.~_/*!&%%?=+^-"
 
3439
#define PASSWD_CTRL "A-Za-z0-9.~_/*!&%%?=+^-"
3541
3440
 
3542
3441
        g_return_val_if_fail(url != NULL, FALSE);
3543
3442
 
3557
3456
        /* Only care about @ char BEFORE the first / */
3558
3457
        at = strchr(url, '@');
3559
3458
        slash = strchr(url, '/');
3560
 
        if ((at != NULL) &&
3561
 
                        (((slash != NULL) && (strlen(at) > strlen(slash))) ||
3562
 
                        (slash == NULL))) {
3563
 
                g_snprintf(scan_info, sizeof(scan_info),
3564
 
                                        "%%255[%s]:%%255[%s]^@", user_ctrl, passwd_ctrl);
 
3459
        f = 0;
 
3460
        if (at && (!slash || at < slash)) {
 
3461
                scan_info = "%255[" USER_CTRL "]:%255[" PASSWD_CTRL "]^@";
3565
3462
                f = sscanf(url, scan_info, user, passwd);
3566
3463
 
3567
 
                if (f ==1 ) {
 
3464
                if (f == 1) {
3568
3465
                        /* No passwd, possibly just username supplied */
3569
 
                        g_snprintf(scan_info, sizeof(scan_info),
3570
 
                                                "%%255[%s]^@", user_ctrl);
 
3466
                        scan_info = "%255[" USER_CTRL "]^@";
3571
3467
                        f = sscanf(url, scan_info, user);
3572
 
                        *passwd = '\0';
3573
3468
                }
3574
3469
 
3575
3470
                url = at+1; /* move pointer after the @ char */
3576
 
        } else {
 
3471
        }
 
3472
 
 
3473
        if (f < 1) {
3577
3474
                *user = '\0';
3578
3475
                *passwd = '\0';
3579
 
        }
3580
 
 
3581
 
        g_snprintf(scan_info, sizeof(scan_info),
3582
 
                           "%%255[%s]:%%5[%s]/%%255[%s]", addr_ctrl, port_ctrl, page_ctrl);
3583
 
 
 
3476
        } else if (f == 1)
 
3477
                *passwd = '\0';
 
3478
 
 
3479
        scan_info = "%255[" ADDR_CTRL "]:%5[" PORT_CTRL "]/%255[" PAGE_CTRL "]";
3584
3480
        f = sscanf(url, scan_info, host, port_str, path);
3585
3481
 
3586
3482
        if (f == 1)
3587
3483
        {
3588
 
                g_snprintf(scan_info, sizeof(scan_info),
3589
 
                                   "%%255[%s]/%%255[%s]",
3590
 
                                   addr_ctrl, page_ctrl);
 
3484
                scan_info = "%255[" ADDR_CTRL "]/%255[" PAGE_CTRL "]";
3591
3485
                f = sscanf(url, scan_info, host, path);
3592
3486
                /* Use the default port */
3593
3487
                if (is_https)
3611
3505
        if (ret_passwd != NULL) *ret_passwd = g_strdup(passwd);
3612
3506
 
3613
3507
        return ((*host != '\0') ? TRUE : FALSE);
 
3508
 
 
3509
#undef ADDR_CTRL
 
3510
#undef PORT_CTRL
 
3511
#undef PAGE_CTRL
 
3512
#undef USER_CTRL
 
3513
#undef PASSWD_CTRL
3614
3514
}
3615
3515
 
3616
3516
/**
3723
3623
 
3724
3624
        if (purple_strcasestr(new_url, "https://") != NULL) {
3725
3625
                gfud->is_ssl = TRUE;
3726
 
                gfud->ssl_connection = purple_ssl_connect(NULL,
 
3626
                gfud->ssl_connection = purple_ssl_connect(gfud->account,
3727
3627
                                gfud->website.address, gfud->website.port,
3728
3628
                                ssl_url_fetch_connect_cb, ssl_url_fetch_error_cb, gfud);
3729
3629
        } else {
3730
 
                gfud->connect_data = purple_proxy_connect(NULL, NULL,
 
3630
                gfud->connect_data = purple_proxy_connect(NULL, gfud->account,
3731
3631
                                gfud->website.address, gfud->website.port,
3732
3632
                                url_fetch_connect_cb, gfud);
3733
3633
        }
4019
3919
 
4020
3920
        gfud = data;
4021
3921
 
4022
 
        if (gfud->request == NULL)
4023
 
        {
 
3922
        if (gfud->request == NULL) {
 
3923
 
 
3924
                PurpleProxyInfo *gpi = purple_proxy_get_setup(gfud->account);
 
3925
                GString *request_str = g_string_new(NULL);
 
3926
 
 
3927
                g_string_append_printf(request_str, "GET %s%s HTTP/%s\r\n"
 
3928
                                                    "Connection: close\r\n",
 
3929
                        (gfud->full ? "" : "/"),
 
3930
                        (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")),
 
3931
                        (gfud->http11 ? "1.1" : "1.0"));
 
3932
 
 
3933
                if (gfud->user_agent)
 
3934
                        g_string_append_printf(request_str, "User-Agent: %s\r\n", gfud->user_agent);
 
3935
 
4024
3936
                /* Host header is not forbidden in HTTP/1.0 requests, and HTTP/1.1
4025
3937
                 * clients must know how to handle the "chunked" transfer encoding.
4026
3938
                 * Purple doesn't know how to handle "chunked", so should always send
4027
3939
                 * the Host header regardless, to get around some observed problems
4028
3940
                 */
4029
 
                if (gfud->user_agent) {
4030
 
                        gfud->request = g_strdup_printf(
4031
 
                                "GET %s%s HTTP/%s\r\n"
4032
 
                                "Connection: close\r\n"
4033
 
                                "User-Agent: %s\r\n"
4034
 
                                "Accept: */*\r\n"
4035
 
                                "Host: %s\r\n\r\n",
4036
 
                                (gfud->full ? "" : "/"),
4037
 
                                (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")),
4038
 
                                (gfud->http11 ? "1.1" : "1.0"),
4039
 
                                (gfud->user_agent ? gfud->user_agent : ""),
4040
 
                                (gfud->website.address ? gfud->website.address : ""));
4041
 
                } else {
4042
 
                        gfud->request = g_strdup_printf(
4043
 
                                "GET %s%s HTTP/%s\r\n"
4044
 
                                "Connection: close\r\n"
4045
 
                                "Accept: */*\r\n"
4046
 
                                "Host: %s\r\n\r\n",
4047
 
                                (gfud->full ? "" : "/"),
4048
 
                                (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")),
4049
 
                                (gfud->http11 ? "1.1" : "1.0"),
4050
 
                                (gfud->website.address ? gfud->website.address : ""));
 
3941
                g_string_append_printf(request_str, "Accept: */*\r\n"
 
3942
                                                    "Host: %s\r\n",
 
3943
                        (gfud->website.address ? gfud->website.address : ""));
 
3944
 
 
3945
                if (purple_proxy_info_get_username(gpi) != NULL
 
3946
                                && (purple_proxy_info_get_type(gpi) == PURPLE_PROXY_USE_ENVVAR
 
3947
                                        || purple_proxy_info_get_type(gpi) == PURPLE_PROXY_HTTP)) {
 
3948
                        /* This chunk of code was copied from proxy.c http_start_connect_tunneling()
 
3949
                         * This is really a temporary hack - we need a more complete proxy handling solution,
 
3950
                         * so I didn't think it was worthwhile to refactor for reuse
 
3951
                         */ 
 
3952
                        char *t1, *t2, *ntlm_type1;
 
3953
                        char hostname[256];
 
3954
                        int ret;
 
3955
        
 
3956
                        ret = gethostname(hostname, sizeof(hostname));
 
3957
                        hostname[sizeof(hostname) - 1] = '\0';
 
3958
                        if (ret < 0 || hostname[0] == '\0') {
 
3959
                                purple_debug_warning("util", "proxy - gethostname() failed -- is your hostname set?");
 
3960
                                strcpy(hostname, "localhost");
 
3961
                        }
 
3962
        
 
3963
                        t1 = g_strdup_printf("%s:%s",
 
3964
                                purple_proxy_info_get_username(gpi),
 
3965
                                purple_proxy_info_get_password(gpi) ?
 
3966
                                        purple_proxy_info_get_password(gpi) : "");
 
3967
                        t2 = purple_base64_encode((const guchar *)t1, strlen(t1));
 
3968
                        g_free(t1);
 
3969
        
 
3970
                        ntlm_type1 = purple_ntlm_gen_type1(hostname, "");
 
3971
        
 
3972
                        g_string_append_printf(request_str,
 
3973
                                "Proxy-Authorization: Basic %s\r\n"
 
3974
                                "Proxy-Authorization: NTLM %s\r\n"
 
3975
                                "Proxy-Connection: Keep-Alive\r\n",
 
3976
                                t2, ntlm_type1);
 
3977
                        g_free(ntlm_type1);
 
3978
                        g_free(t2);
4051
3979
                }
 
3980
 
 
3981
                g_string_append(request_str, "\r\n");
 
3982
 
 
3983
                gfud->request = g_string_free(request_str, FALSE);
4052
3984
        }
4053
3985
 
4054
3986
        if(purple_debug_is_unsafe())
4187
4119
        gfud->include_headers = include_headers;
4188
4120
        gfud->fd = -1;
4189
4121
        gfud->max_len = max_len;
 
4122
        gfud->account = account;
4190
4123
 
4191
4124
        purple_url_parse(url, &gfud->website.address, &gfud->website.port,
4192
4125
                                   &gfud->website.page, &gfud->website.user, &gfud->website.passwd);
4340
4273
 
4341
4274
        g_return_val_if_fail(address != NULL, FALSE);
4342
4275
 
 
4276
        if (*address == '.') return FALSE;
 
4277
 
4343
4278
        /* first we validate the name portion (name@domain) (rfc822)*/
4344
4279
        for (c = address;  *c;  c++) {
4345
4280
                if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) == '\"')) {
4373
4308
        do {
4374
4309
                if (*c == '.' && (c == domain || *(c - 1) == '.' || *(c - 1) == '-'))
4375
4310
                        return FALSE;
4376
 
                if (*c == '-' && *(c - 1) == '.') return FALSE;
 
4311
                if (*c == '-' && (*(c - 1) == '.' || *(c - 1) == '@')) return FALSE;
4377
4312
                if ((*c < '0' && *c != '-' && *c != '.') || (*c > '9' && *c < 'A') ||
4378
4313
                        (*c > 'Z' && *c < 'a') || (*c > 'z')) return FALSE;
4379
4314
        } while (*++c);
4960
4895
                        }
4961
4896
                }
4962
4897
        }
4963
 
 
 
4898
#ifdef _WIN32
 
4899
        /* File/Directory names in windows cannot end in periods/spaces.
 
4900
         * http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx
 
4901
         */
 
4902
        while (j > 0 && (buf[j - 1] == '.' || buf[j - 1] == ' '))
 
4903
                j--;
 
4904
#endif
4964
4905
        buf[j] = '\0';
4965
4906
 
4966
4907
        return buf;