~ubuntu-branches/ubuntu/hardy/pidgin/hardy

« back to all changes in this revision

Viewing changes to libpurple/util.c

  • Committer: Bazaar Package Importer
  • Author(s): Pedro Fragoso
  • Date: 2007-12-21 02:48:06 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20071221024806-pd44a5k9tiyh12mp
Tags: 1:2.3.1-2ubuntu1
* Sync with Debian, remaining Ubuntu changes; (LP: #177811)
  - Set Maintainer to Ubuntu Core Developers.
  - Add build-deps on liblaunchpad-integration-dev, intltool,
    libnm-glib-dev (for --enable-nm) (Ubuntu #112720).
  - Drop build-deps on libsilc-1.1-2-dev | libsilc-dev (>= 1.1.1) as 
    this library is in universe.
  - Drop the libpurple0 recommends on libpurple-bin.
  - Add a gaim transitionnal package for upgrades.
  - Ship compatibility symlinks via debian/gaim.links.
  - Pass --enable-nm to configure to enable NetworkManager support.
  - Pass --disable-silc to configure to disable silc support even if 
    it's installed in the build environment.
  - Add X-Ubuntu-Gettext-Domain to the desktop file and update the
    translation templates in common-install-impl::.
   - Update debian/prefs.xml to set the notify plugin prefs
    /plugins/gtk/X11/notify/* and set /pidgin/plugins/loaded to load 
    the notify plugin; Ubuntu: #13389.
  - Add LPI integration patch, 02_lpi.
  - Add patch 04_let_crasher_for_apport to stop catching the SIGSEGV signal
    and let apport handle it.
  - Add patch 05_default_to_irc_ubuntu_com to set the default IRC 
    server to irc.ubuntu.com.
  - Add autoconf patch, 70_autoconf.

Show diffs side-by-side

added added

removed removed

Lines of Context:
68
68
};
69
69
 
70
70
static char *custom_user_dir = NULL;
71
 
static char *home_dir = NULL;
 
71
static char *user_dir = NULL;
 
72
 
72
73
 
73
74
PurpleMenuAction *
74
75
purple_menu_action_new(const char *label, PurpleCallback callback, gpointer data,
91
92
        g_free(act);
92
93
}
93
94
 
 
95
void
 
96
purple_util_init(void)
 
97
{
 
98
        /* This does nothing right now.  It exists for symmetry with 
 
99
         * purple_util_uninit() and forwards compatibility. */
 
100
}
 
101
 
 
102
void
 
103
purple_util_uninit(void)
 
104
{
 
105
        /* Free these so we don't have leaks at shutdown. */
 
106
 
 
107
        g_free(custom_user_dir);
 
108
        custom_user_dir = NULL;
 
109
 
 
110
        g_free(user_dir);
 
111
        user_dir = NULL;
 
112
}
 
113
 
94
114
/**************************************************************************
95
115
 * Base16 Functions
96
116
 **************************************************************************/
515
535
 * Date/Time Functions
516
536
 **************************************************************************/
517
537
 
518
 
#ifdef _WIN32
519
 
static long win32_get_tz_offset() {
520
 
        TIME_ZONE_INFORMATION tzi;
521
 
        DWORD ret;
522
 
        long off = -1;
523
 
 
524
 
        if ((ret = GetTimeZoneInformation(&tzi)) != TIME_ZONE_ID_INVALID)
525
 
        {
526
 
                off = -(tzi.Bias * 60);
527
 
                if (ret == TIME_ZONE_ID_DAYLIGHT)
528
 
                        off -= tzi.DaylightBias * 60;
529
 
        }
530
 
 
531
 
        return off;
532
 
}
533
 
#endif
534
 
 
535
538
const char *purple_get_tzoff_str(const struct tm *tm, gboolean iso)
536
539
{
537
540
        static char buf[7];
546
549
                g_return_val_if_reached("");
547
550
 
548
551
#ifdef _WIN32
549
 
        if ((off = win32_get_tz_offset()) == -1)
 
552
        if ((off = wpurple_get_tz_offset()) == -1)
550
553
                return "";
551
554
#else
552
555
# ifdef HAVE_TM_GMTOFF
750
753
                 struct tm *tm, long *tz_off, const char **rest)
751
754
{
752
755
        time_t retval = 0;
753
 
        struct tm *t;
 
756
        static struct tm t;
754
757
        const char *c = timestamp;
755
758
        int year = 0;
756
759
        long tzoff = PURPLE_NO_TZ_OFF;
757
760
 
758
761
        time(&retval);
759
 
        t = localtime(&retval);
 
762
        localtime_r(&retval, &t);
760
763
 
761
764
        /* 4 digit year */
762
765
        if (sscanf(c, "%04d", &year) && year > 1900)
764
767
                c += 4;
765
768
                if (*c == '-')
766
769
                        c++;
767
 
                t->tm_year = year - 1900;
 
770
                t.tm_year = year - 1900;
768
771
        }
769
772
 
770
773
        /* 2 digit month */
771
 
        if (!sscanf(c, "%02d", &t->tm_mon))
 
774
        if (!sscanf(c, "%02d", &t.tm_mon))
772
775
        {
773
776
                if (rest != NULL && *c != '\0')
774
777
                        *rest = c;
777
780
        c += 2;
778
781
        if (*c == '-' || *c == '/')
779
782
                c++;
780
 
        t->tm_mon -= 1;
 
783
        t.tm_mon -= 1;
781
784
 
782
785
        /* 2 digit day */
783
 
        if (!sscanf(c, "%02d", &t->tm_mday))
 
786
        if (!sscanf(c, "%02d", &t.tm_mday))
784
787
        {
785
788
                if (rest != NULL && *c != '\0')
786
789
                        *rest = c;
791
794
        {
792
795
                c++;
793
796
 
794
 
                if (!sscanf(c, "%04d", &t->tm_year))
 
797
                if (!sscanf(c, "%04d", &t.tm_year))
795
798
                {
796
799
                        if (rest != NULL && *c != '\0')
797
800
                                *rest = c;
798
801
                        return 0;
799
802
                }
800
 
                t->tm_year -= 1900;
 
803
                t.tm_year -= 1900;
801
804
        }
802
805
        else if (*c == 'T' || *c == '.')
803
806
        {
805
808
                /* we have more than a date, keep going */
806
809
 
807
810
                /* 2 digit hour */
808
 
                if ((sscanf(c, "%02d:%02d:%02d", &t->tm_hour, &t->tm_min, &t->tm_sec) == 3 && (c = c + 8)) ||
809
 
                    (sscanf(c, "%02d%02d%02d", &t->tm_hour, &t->tm_min, &t->tm_sec) == 3 && (c = c + 6)))
 
811
                if ((sscanf(c, "%02d:%02d:%02d", &t.tm_hour, &t.tm_min, &t.tm_sec) == 3 && (c = c + 8)) ||
 
812
                    (sscanf(c, "%02d%02d%02d", &t.tm_hour, &t.tm_min, &t.tm_sec) == 3 && (c = c + 6)))
810
813
                {
811
814
                        gboolean offset_positive = FALSE;
812
815
                        int tzhrs;
813
816
                        int tzmins;
814
817
 
815
 
                        t->tm_isdst = -1;
 
818
                        t.tm_isdst = -1;
816
819
 
817
 
                        if (*c == '.' && *(c+1) >= '0' && *(c+1) <= '9') /* dealing with precision we don't care about */
818
 
                                c += 4;
 
820
                        if (*c == '.') {
 
821
                                do {
 
822
                                        c++;
 
823
                                } while (*c >= '0' && *c <= '9'); /* dealing with precision we don't care about */
 
824
                        }
819
825
                        if (*c == '+')
820
826
                                offset_positive = TRUE;
821
827
                        if (((*c == '+' || *c == '-') && (c = c + 1)) &&
827
833
                                        tzoff *= -1;
828
834
                                /* We don't want the C library doing DST calculations
829
835
                                 * if we know the UTC offset already. */
830
 
                                t->tm_isdst = 0;
 
836
                                t.tm_isdst = 0;
831
837
                        }
832
838
                        else if (utc)
833
839
                        {
834
 
                                t->tm_isdst = -1;
 
840
                                static struct tm tmptm;
 
841
                                time_t tmp;
 
842
                                tmp = mktime(&t);
 
843
                                /* we care about whether it *was* dst, and the offset, here on this
 
844
                                 * date, not whether we are currently observing dst locally *now*.
 
845
                                 * This isn't perfect, because we would need to know in advance the
 
846
                                 * offset we are trying to work out in advance to be sure this
 
847
                                 * works for times around dst transitions but it'll have to do. */
 
848
                                localtime_r(&tmp, &tmptm);
 
849
                                t.tm_isdst = tmptm.tm_isdst;
 
850
#ifdef HAVE_TM_GMTOFF
 
851
                                t.tm_gmtoff = tmptm.tm_gmtoff;
 
852
#endif
835
853
                        }
836
854
 
837
855
                        if (rest != NULL && *c != '\0')
854
872
#endif
855
873
 
856
874
#ifdef _WIN32
857
 
                                if ((sys_tzoff = win32_get_tz_offset()) == -1)
 
875
                                if ((sys_tzoff = wpurple_get_tz_offset()) == -1)
858
876
                                        tzoff = PURPLE_NO_TZ_OFF;
859
877
                                else
860
878
                                        tzoff += sys_tzoff;
861
879
#else
862
880
#ifdef HAVE_TM_GMTOFF
863
 
                                tzoff += t->tm_gmtoff;
 
881
                                tzoff += t.tm_gmtoff;
864
882
#else
865
883
#       ifdef HAVE_TIMEZONE
866
884
                                tzset();    /* making sure */
879
897
 
880
898
        if (tm != NULL)
881
899
        {
882
 
                *tm = *t;
 
900
                *tm = t;
883
901
                tm->tm_isdst = -1;
884
902
                mktime(tm);
885
903
        }
886
904
 
887
 
        retval = mktime(t);
 
905
        retval = mktime(&t);
888
906
        if (tzoff != PURPLE_NO_TZ_OFF)
889
907
                retval += tzoff;
890
908
 
1369
1387
                                                        g_string_append_printf(xhtml, "</%s>", pt->dest_tag);
1370
1388
                                                if(plain && !strcmp(pt->src_tag, "a")) {
1371
1389
                                                        /* if this is a link, we have to add the url to the plaintext, too */
1372
 
                                                        if (cdata && url && !g_string_equal(cdata, url))
 
1390
                                                        if (cdata && url &&
 
1391
                                                                        (!g_string_equal(cdata, url) && (g_ascii_strncasecmp(url->str, "mailto:", 7) != 0 ||
 
1392
                                                                                                         g_utf8_collate(url->str + 7, cdata->str) != 0)))
1373
1393
                                                                g_string_append_printf(plain, " <%s>", g_strstrip(url->str));
1374
1394
                                                        if (cdata) {
1375
1395
                                                                g_string_free(cdata, TRUE);
1550
1570
                                                        if(*q == '\'' || *q == '\"')
1551
1571
                                                                q++;
1552
1572
                                                        while(*q && *q != '\"' && *q != '\'' && *q != ' ') {
1553
 
                                                                url = g_string_append_c(url, *q);
 
1573
                                                                int len;
 
1574
                                                                if ((*q == '&') && (purple_markup_unescape_entity(q, &len) == NULL))
 
1575
                                                                        url = g_string_append(url, "&amp;");
 
1576
                                                                else
 
1577
                                                                        url = g_string_append_c(url, *q);
1554
1578
                                                                q++;
1555
1579
                                                        }
1556
1580
                                                        p = q;
1659
1683
                                        pt->src_tag = "font";
1660
1684
                                        pt->dest_tag = "span";
1661
1685
                                        tags = g_list_prepend(tags, pt);
1662
 
                                        if(style->len)
 
1686
                                        if(style->len && xhtml)
1663
1687
                                                g_string_append_printf(xhtml, "<span style='%s'>", g_strstrip(style->str));
1664
1688
                                        else
1665
1689
                                                pt->ignore = TRUE;
1729
1753
                                xhtml = g_string_append_len(xhtml, c, len);
1730
1754
                        if(plain)
1731
1755
                                plain = g_string_append(plain, pln);
 
1756
                        if(cdata)
 
1757
                                cdata = g_string_append_len(cdata, c, len);
1732
1758
                        c += len;
1733
1759
                } else {
1734
1760
                        if(xhtml)
1754
1780
                *plain_out = g_string_free(plain, FALSE);
1755
1781
        if(url)
1756
1782
                g_string_free(url, TRUE);
 
1783
        if (cdata)
 
1784
                g_string_free(cdata, TRUE);
1757
1785
}
1758
1786
 
1759
1787
/* The following are probably reasonable changes:
2465
2493
{
2466
2494
        if (custom_user_dir != NULL)
2467
2495
                return custom_user_dir;
2468
 
        else if (!home_dir)
2469
 
                home_dir = g_build_filename(purple_home_dir(), ".purple", NULL);
 
2496
        else if (!user_dir)
 
2497
                user_dir = g_build_filename(purple_home_dir(), ".purple", NULL);
2470
2498
 
2471
 
        return home_dir;
 
2499
        return user_dir;
2472
2500
}
2473
2501
 
2474
2502
void purple_util_set_user_dir(const char *dir)
2522
2550
                }
2523
2551
 
2524
2552
                if (g_mkdir(dir, mode) < 0) {
2525
 
                        purple_debug_warning("build_dir", "mkdir: %s\n", strerror(errno));
 
2553
                        purple_debug_warning("build_dir", "mkdir: %s\n", g_strerror(errno));
2526
2554
                        g_strfreev(components);
2527
2555
                        g_free(dir);
2528
2556
                        return -1;
2558
2586
                if (g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
2559
2587
                {
2560
2588
                        purple_debug_error("util", "Error creating directory %s: %s\n",
2561
 
                                                         user_dir, strerror(errno));
 
2589
                                                         user_dir, g_strerror(errno));
2562
2590
                        return FALSE;
2563
2591
                }
2564
2592
        }
2578
2606
        FILE *file;
2579
2607
        size_t real_size, byteswritten;
2580
2608
        struct stat st;
 
2609
#ifndef HAVE_FILENO
 
2610
        int fd;
 
2611
#endif
2581
2612
 
2582
2613
        purple_debug_info("util", "Writing file %s\n",
2583
2614
                                        filename_full);
2593
2624
                {
2594
2625
                        purple_debug_error("util", "Error removing old file "
2595
2626
                                           "%s: %s\n",
2596
 
                                           filename_temp, strerror(errno));
 
2627
                                           filename_temp, g_strerror(errno));
2597
2628
                }
2598
2629
        }
2599
2630
 
2603
2634
        {
2604
2635
                purple_debug_error("util", "Error opening file %s for "
2605
2636
                                   "writing: %s\n",
2606
 
                                   filename_temp, strerror(errno));
 
2637
                                   filename_temp, g_strerror(errno));
2607
2638
                g_free(filename_temp);
2608
2639
                return FALSE;
2609
2640
        }
2612
2643
        real_size = (size == -1) ? strlen(data) : (size_t) size;
2613
2644
        byteswritten = fwrite(data, 1, real_size, file);
2614
2645
 
 
2646
#ifdef HAVE_FILENO
 
2647
        /* Apparently XFS (and possibly other filesystems) do not
 
2648
         * guarantee that file data is flushed before file metadata,
 
2649
         * so this procedure is insufficient without some flushage. */
 
2650
        if (fflush(file) < 0) {
 
2651
                purple_debug_error("util", "Error flushing %s: %s\n",
 
2652
                                   filename_temp, g_strerror(errno));
 
2653
                g_free(filename_temp);
 
2654
                fclose(file);
 
2655
                return FALSE;
 
2656
        }
 
2657
        if (fsync(fileno(file)) < 0) {
 
2658
                purple_debug_error("util", "Error syncing file contents for %s: %s\n",
 
2659
                                   filename_temp, g_strerror(errno));
 
2660
                g_free(filename_temp);
 
2661
                fclose(file);
 
2662
                return FALSE;
 
2663
        }
 
2664
#endif
 
2665
    
2615
2666
        /* Close file */
2616
2667
        if (fclose(file) != 0)
2617
2668
        {
2618
2669
                purple_debug_error("util", "Error closing file %s: %s\n",
2619
 
                                   filename_temp, strerror(errno));
2620
 
                g_free(filename_temp);
2621
 
                return FALSE;
2622
 
        }
 
2670
                                   filename_temp, g_strerror(errno));
 
2671
                g_free(filename_temp);
 
2672
                return FALSE;
 
2673
        }
 
2674
 
 
2675
#ifndef HAVE_FILENO
 
2676
        /* This is the same effect (we hope) as the HAVE_FILENO block
 
2677
         * above, but for systems without fileno(). */
 
2678
        if ((fd = open(filename_temp, O_RDWR)) < 0) {
 
2679
                purple_debug_error("util", "Error opening file %s for flush: %s\n",
 
2680
                                   filename_temp, g_strerror(errno));
 
2681
                g_free(filename_temp);
 
2682
                return FALSE;
 
2683
        }
 
2684
        if (fsync(fd) < 0) {
 
2685
                purple_debug_error("util", "Error syncing %s: %s\n",
 
2686
                                   filename_temp, g_strerror(errno));
 
2687
                g_free(filename_temp);
 
2688
                close(fd);
 
2689
                return FALSE;
 
2690
        }
 
2691
        if (close(fd) < 0) {
 
2692
                purple_debug_error("util", "Error closing %s after sync: %s\n",
 
2693
                                   filename_temp, g_strerror(errno));
 
2694
                g_free(filename_temp);
 
2695
                return FALSE;
 
2696
        }
 
2697
#endif
2623
2698
 
2624
2699
        /* Ensure the file is the correct size */
2625
2700
        if (byteswritten != real_size)
2648
2723
        if (chmod(filename_temp, S_IRUSR | S_IWUSR) == -1)
2649
2724
        {
2650
2725
                purple_debug_error("util", "Error setting permissions of file %s: %s\n",
2651
 
                                                 filename_temp, strerror(errno));
 
2726
                                                 filename_temp, g_strerror(errno));
2652
2727
        }
2653
2728
#endif
2654
2729
 
2657
2732
        {
2658
2733
                purple_debug_error("util", "Error renaming %s to %s: %s\n",
2659
2734
                                   filename_temp, filename_full,
2660
 
                                   strerror(errno));
 
2735
                                   g_strerror(errno));
2661
2736
        }
2662
2737
 
2663
2738
        g_free(filename_temp);
2877
2952
                return FALSE;
2878
2953
        g_free(tmp);
2879
2954
 
2880
 
        return (g_getenv("GNOME_DESKTOP_SESSION_ID") != NULL);
 
2955
        tmp = (gchar *)g_getenv("GNOME_DESKTOP_SESSION_ID");
 
2956
 
 
2957
        return ((tmp != NULL) && (*tmp != '\0'));
2881
2958
#else
2882
2959
        return FALSE;
2883
2960
#endif
3084
3161
                ret[j++] = text[i];
3085
3162
        }
3086
3163
 
3087
 
        purple_debug_misc("purple_str_add_cr", "got: %s, leaving with %s\n",
3088
 
                                        text, ret);
3089
 
 
3090
3164
        return ret;
3091
3165
}
3092
3166
 
3216
3290
char *
3217
3291
purple_str_size_to_units(size_t size)
3218
3292
{
3219
 
        static const char *size_str[4] = { "bytes", "KiB", "MiB", "GiB" };
 
3293
        static const char * const size_str[] = { "bytes", "KiB", "MiB", "GiB" };
3220
3294
        float size_mag;
3221
3295
        int size_index = 0;
3222
3296
 
3409
3483
        char host[256], path[256], user[256], passwd[256];
3410
3484
        int port = 0;
3411
3485
        /* hyphen at end includes it in control set */
3412
 
        static char addr_ctrl[] = "A-Za-z0-9.-";
3413
 
        static char port_ctrl[] = "0-9";
3414
 
        static char page_ctrl[] = "A-Za-z0-9.~_/:*!@&%%?=+^-";
3415
 
        static char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
3416
 
        static char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
 
3486
        static const char addr_ctrl[] = "A-Za-z0-9.-";
 
3487
        static const char port_ctrl[] = "0-9";
 
3488
        static const char page_ctrl[] = "A-Za-z0-9.~_/:*!@&%%?=+^-";
 
3489
        static const char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
 
3490
        static const char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
3417
3491
 
3418
3492
        g_return_val_if_fail(url != NULL, FALSE);
3419
3493
 
3708
3782
                                        if(new_data == NULL) {
3709
3783
                                                purple_debug_error("util",
3710
3784
                                                                "Failed to allocate %u bytes: %s\n",
3711
 
                                                                content_len, strerror(errno));
 
3785
                                                                content_len, g_strerror(errno));
3712
3786
                                                purple_util_fetch_url_error(gfud,
3713
3787
                                                                _("Unable to allocate enough memory to hold "
3714
3788
                                                                  "the contents from %s.  The web server may "
3746
3820
                        return;
3747
3821
                } else {
3748
3822
                        purple_util_fetch_url_error(gfud, _("Error reading from %s: %s"),
3749
 
                                        gfud->website.address, strerror(errno));
 
3823
                                        gfud->website.address, g_strerror(errno));
3750
3824
                        return;
3751
3825
                }
3752
3826
        }
3777
3851
                return;
3778
3852
        else if (len < 0) {
3779
3853
                purple_util_fetch_url_error(gfud, _("Error writing to %s: %s"),
3780
 
                                gfud->website.address, strerror(errno));
 
3854
                                gfud->website.address, g_strerror(errno));
3781
3855
                return;
3782
3856
        }
3783
3857
        gfud->request_written += len;