comparison libpurple/util.c @ 27735:98604b4bfa3b

propagate from branch 'im.pidgin.pidgin' (head cc8513f94aa94550d600cd8a5d42475dbf7249c0) to branch 'im.pidgin.pidgin.yaz' (head 3a859b75c16c1c1e2e79d4f4acb4424d13af5e0b)
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Thu, 22 Nov 2007 07:44:59 +0000
parents 3f5b0039428b 07588cb48434
children 4e6e39be7fef
comparison
equal deleted inserted replaced
27734:3f5b0039428b 27735:98604b4bfa3b
68 }; 68 };
69 69
70 static char *custom_user_dir = NULL; 70 static char *custom_user_dir = NULL;
71 static char *user_dir = NULL; 71 static char *user_dir = NULL;
72 72
73
73 PurpleMenuAction * 74 PurpleMenuAction *
74 purple_menu_action_new(const char *label, PurpleCallback callback, gpointer data, 75 purple_menu_action_new(const char *label, PurpleCallback callback, gpointer data,
75 GList *children) 76 GList *children)
76 { 77 {
77 PurpleMenuAction *act = g_new0(PurpleMenuAction, 1); 78 PurpleMenuAction *act = g_new0(PurpleMenuAction, 1);
87 { 88 {
88 g_return_if_fail(act != NULL); 89 g_return_if_fail(act != NULL);
89 90
90 g_free(act->label); 91 g_free(act->label);
91 g_free(act); 92 g_free(act);
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;
92 } 112 }
93 113
94 /************************************************************************** 114 /**************************************************************************
95 * Base16 Functions 115 * Base16 Functions
96 **************************************************************************/ 116 **************************************************************************/
1352 struct purple_parse_tag *pt = tags->data; 1372 struct purple_parse_tag *pt = tags->data;
1353 if(xhtml) 1373 if(xhtml)
1354 g_string_append_printf(xhtml, "</%s>", pt->dest_tag); 1374 g_string_append_printf(xhtml, "</%s>", pt->dest_tag);
1355 if(plain && !strcmp(pt->src_tag, "a")) { 1375 if(plain && !strcmp(pt->src_tag, "a")) {
1356 /* if this is a link, we have to add the url to the plaintext, too */ 1376 /* if this is a link, we have to add the url to the plaintext, too */
1357 if (cdata && url && !g_string_equal(cdata, url)) 1377 if (cdata && url &&
1378 (!g_string_equal(cdata, url) && (g_ascii_strncasecmp(url->str, "mailto:", 7) != 0 ||
1379 g_utf8_collate(url->str + 7, cdata->str) != 0)))
1358 g_string_append_printf(plain, " <%s>", g_strstrip(url->str)); 1380 g_string_append_printf(plain, " <%s>", g_strstrip(url->str));
1359 if (cdata) { 1381 if (cdata) {
1360 g_string_free(cdata, TRUE); 1382 g_string_free(cdata, TRUE);
1361 cdata = NULL; 1383 cdata = NULL;
1362 } 1384 }
1533 url = g_string_new(""); 1555 url = g_string_new("");
1534 cdata = g_string_new(""); 1556 cdata = g_string_new("");
1535 if(*q == '\'' || *q == '\"') 1557 if(*q == '\'' || *q == '\"')
1536 q++; 1558 q++;
1537 while(*q && *q != '\"' && *q != '\'' && *q != ' ') { 1559 while(*q && *q != '\"' && *q != '\'' && *q != ' ') {
1538 url = g_string_append_c(url, *q); 1560 int len;
1561 if ((*q == '&') && (purple_markup_unescape_entity(q, &len) == NULL))
1562 url = g_string_append(url, "&amp;");
1563 else
1564 url = g_string_append_c(url, *q);
1539 q++; 1565 q++;
1540 } 1566 }
1541 p = q; 1567 p = q;
1542 } 1568 }
1543 p++; 1569 p++;
1642 c = p; 1668 c = p;
1643 pt = g_new0(struct purple_parse_tag, 1); 1669 pt = g_new0(struct purple_parse_tag, 1);
1644 pt->src_tag = "font"; 1670 pt->src_tag = "font";
1645 pt->dest_tag = "span"; 1671 pt->dest_tag = "span";
1646 tags = g_list_prepend(tags, pt); 1672 tags = g_list_prepend(tags, pt);
1647 if(style->len) 1673 if(style->len && xhtml)
1648 g_string_append_printf(xhtml, "<span style='%s'>", g_strstrip(style->str)); 1674 g_string_append_printf(xhtml, "<span style='%s'>", g_strstrip(style->str));
1649 else 1675 else
1650 pt->ignore = TRUE; 1676 pt->ignore = TRUE;
1651 g_string_free(style, TRUE); 1677 g_string_free(style, TRUE);
1652 continue; 1678 continue;
1712 } 1738 }
1713 if(xhtml) 1739 if(xhtml)
1714 xhtml = g_string_append_len(xhtml, c, len); 1740 xhtml = g_string_append_len(xhtml, c, len);
1715 if(plain) 1741 if(plain)
1716 plain = g_string_append(plain, pln); 1742 plain = g_string_append(plain, pln);
1743 if(cdata)
1744 cdata = g_string_append_len(cdata, c, len);
1717 c += len; 1745 c += len;
1718 } else { 1746 } else {
1719 if(xhtml) 1747 if(xhtml)
1720 xhtml = g_string_append_c(xhtml, *c); 1748 xhtml = g_string_append_c(xhtml, *c);
1721 if(plain) 1749 if(plain)
1737 *xhtml_out = g_string_free(xhtml, FALSE); 1765 *xhtml_out = g_string_free(xhtml, FALSE);
1738 if(plain_out) 1766 if(plain_out)
1739 *plain_out = g_string_free(plain, FALSE); 1767 *plain_out = g_string_free(plain, FALSE);
1740 if(url) 1768 if(url)
1741 g_string_free(url, TRUE); 1769 g_string_free(url, TRUE);
1770 if (cdata)
1771 g_string_free(cdata, TRUE);
1742 } 1772 }
1743 1773
1744 /* The following are probably reasonable changes: 1774 /* The following are probably reasonable changes:
1745 * - \n should be converted to a normal space 1775 * - \n should be converted to a normal space
1746 * - in addition to <br>, <p> and <div> etc. should also be converted into \n 1776 * - in addition to <br>, <p> and <div> etc. should also be converted into \n
2505 g_free(dir); 2535 g_free(dir);
2506 return -1; 2536 return -1;
2507 } 2537 }
2508 2538
2509 if (g_mkdir(dir, mode) < 0) { 2539 if (g_mkdir(dir, mode) < 0) {
2510 purple_debug_warning("build_dir", "mkdir: %s\n", strerror(errno)); 2540 purple_debug_warning("build_dir", "mkdir: %s\n", g_strerror(errno));
2511 g_strfreev(components); 2541 g_strfreev(components);
2512 g_free(dir); 2542 g_free(dir);
2513 return -1; 2543 return -1;
2514 } 2544 }
2515 } 2545 }
2541 if (!g_file_test(user_dir, G_FILE_TEST_IS_DIR)) 2571 if (!g_file_test(user_dir, G_FILE_TEST_IS_DIR))
2542 { 2572 {
2543 if (g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1) 2573 if (g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
2544 { 2574 {
2545 purple_debug_error("util", "Error creating directory %s: %s\n", 2575 purple_debug_error("util", "Error creating directory %s: %s\n",
2546 user_dir, strerror(errno)); 2576 user_dir, g_strerror(errno));
2547 return FALSE; 2577 return FALSE;
2548 } 2578 }
2549 } 2579 }
2550 2580
2551 filename_full = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", user_dir, filename); 2581 filename_full = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", user_dir, filename);
2561 { 2591 {
2562 gchar *filename_temp; 2592 gchar *filename_temp;
2563 FILE *file; 2593 FILE *file;
2564 size_t real_size, byteswritten; 2594 size_t real_size, byteswritten;
2565 struct stat st; 2595 struct stat st;
2596 #ifndef HAVE_FILENO
2597 int fd;
2598 #endif
2566 2599
2567 purple_debug_info("util", "Writing file %s\n", 2600 purple_debug_info("util", "Writing file %s\n",
2568 filename_full); 2601 filename_full);
2569 2602
2570 g_return_val_if_fail((size >= -1), FALSE); 2603 g_return_val_if_fail((size >= -1), FALSE);
2576 { 2609 {
2577 if (g_unlink(filename_temp) == -1) 2610 if (g_unlink(filename_temp) == -1)
2578 { 2611 {
2579 purple_debug_error("util", "Error removing old file " 2612 purple_debug_error("util", "Error removing old file "
2580 "%s: %s\n", 2613 "%s: %s\n",
2581 filename_temp, strerror(errno)); 2614 filename_temp, g_strerror(errno));
2582 } 2615 }
2583 } 2616 }
2584 2617
2585 /* Open file */ 2618 /* Open file */
2586 file = g_fopen(filename_temp, "wb"); 2619 file = g_fopen(filename_temp, "wb");
2587 if (file == NULL) 2620 if (file == NULL)
2588 { 2621 {
2589 purple_debug_error("util", "Error opening file %s for " 2622 purple_debug_error("util", "Error opening file %s for "
2590 "writing: %s\n", 2623 "writing: %s\n",
2591 filename_temp, strerror(errno)); 2624 filename_temp, g_strerror(errno));
2592 g_free(filename_temp); 2625 g_free(filename_temp);
2593 return FALSE; 2626 return FALSE;
2594 } 2627 }
2595 2628
2596 /* Write to file */ 2629 /* Write to file */
2597 real_size = (size == -1) ? strlen(data) : (size_t) size; 2630 real_size = (size == -1) ? strlen(data) : (size_t) size;
2598 byteswritten = fwrite(data, 1, real_size, file); 2631 byteswritten = fwrite(data, 1, real_size, file);
2599 2632
2633 #ifdef HAVE_FILENO
2634 /* Apparently XFS (and possibly other filesystems) do not
2635 * guarantee that file data is flushed before file metadata,
2636 * so this procedure is insufficient without some flushage. */
2637 if (fflush(file) < 0) {
2638 purple_debug_error("util", "Error flushing %s: %s\n",
2639 filename_temp, g_strerror(errno));
2640 g_free(filename_temp);
2641 fclose(file);
2642 return FALSE;
2643 }
2644 if (fsync(fileno(file)) < 0) {
2645 purple_debug_error("util", "Error syncing file contents for %s: %s\n",
2646 filename_temp, g_strerror(errno));
2647 g_free(filename_temp);
2648 fclose(file);
2649 return FALSE;
2650 }
2651 #endif
2652
2600 /* Close file */ 2653 /* Close file */
2601 if (fclose(file) != 0) 2654 if (fclose(file) != 0)
2602 { 2655 {
2603 purple_debug_error("util", "Error closing file %s: %s\n", 2656 purple_debug_error("util", "Error closing file %s: %s\n",
2604 filename_temp, strerror(errno)); 2657 filename_temp, g_strerror(errno));
2605 g_free(filename_temp); 2658 g_free(filename_temp);
2606 return FALSE; 2659 return FALSE;
2607 } 2660 }
2661
2662 #ifndef HAVE_FILENO
2663 /* This is the same effect (we hope) as the HAVE_FILENO block
2664 * above, but for systems without fileno(). */
2665 if ((fd = open(filename_temp, O_RDWR)) < 0) {
2666 purple_debug_error("util", "Error opening file %s for flush: %s\n",
2667 filename_temp, g_strerror(errno));
2668 g_free(filename_temp);
2669 return FALSE;
2670 }
2671 if (fsync(fd) < 0) {
2672 purple_debug_error("util", "Error syncing %s: %s\n",
2673 filename_temp, g_strerror(errno));
2674 g_free(filename_temp);
2675 close(fd);
2676 return FALSE;
2677 }
2678 if (close(fd) < 0) {
2679 purple_debug_error("util", "Error closing %s after sync: %s\n",
2680 filename_temp, g_strerror(errno));
2681 g_free(filename_temp);
2682 return FALSE;
2683 }
2684 #endif
2608 2685
2609 /* Ensure the file is the correct size */ 2686 /* Ensure the file is the correct size */
2610 if (byteswritten != real_size) 2687 if (byteswritten != real_size)
2611 { 2688 {
2612 purple_debug_error("util", "Error writing to file %s: Wrote %" 2689 purple_debug_error("util", "Error writing to file %s: Wrote %"
2631 #ifndef _WIN32 2708 #ifndef _WIN32
2632 /* Set file permissions */ 2709 /* Set file permissions */
2633 if (chmod(filename_temp, S_IRUSR | S_IWUSR) == -1) 2710 if (chmod(filename_temp, S_IRUSR | S_IWUSR) == -1)
2634 { 2711 {
2635 purple_debug_error("util", "Error setting permissions of file %s: %s\n", 2712 purple_debug_error("util", "Error setting permissions of file %s: %s\n",
2636 filename_temp, strerror(errno)); 2713 filename_temp, g_strerror(errno));
2637 } 2714 }
2638 #endif 2715 #endif
2639 2716
2640 /* Rename to the REAL name */ 2717 /* Rename to the REAL name */
2641 if (g_rename(filename_temp, filename_full) == -1) 2718 if (g_rename(filename_temp, filename_full) == -1)
2642 { 2719 {
2643 purple_debug_error("util", "Error renaming %s to %s: %s\n", 2720 purple_debug_error("util", "Error renaming %s to %s: %s\n",
2644 filename_temp, filename_full, 2721 filename_temp, filename_full,
2645 strerror(errno)); 2722 g_strerror(errno));
2646 } 2723 }
2647 2724
2648 g_free(filename_temp); 2725 g_free(filename_temp);
2649 2726
2650 return TRUE; 2727 return TRUE;
2860 2937
2861 if (tmp == NULL) 2938 if (tmp == NULL)
2862 return FALSE; 2939 return FALSE;
2863 g_free(tmp); 2940 g_free(tmp);
2864 2941
2865 return (g_getenv("GNOME_DESKTOP_SESSION_ID") != NULL); 2942 tmp = (gchar *)g_getenv("GNOME_DESKTOP_SESSION_ID");
2943
2944 return ((tmp != NULL) && (*tmp != '\0'));
2866 #else 2945 #else
2867 return FALSE; 2946 return FALSE;
2868 #endif 2947 #endif
2869 } 2948 }
2870 2949
3066 for (; i < strlen(text); i++) { 3145 for (; i < strlen(text); i++) {
3067 if (text[i] == '\n' && text[i - 1] != '\r') 3146 if (text[i] == '\n' && text[i - 1] != '\r')
3068 ret[j++] = '\r'; 3147 ret[j++] = '\r';
3069 ret[j++] = text[i]; 3148 ret[j++] = text[i];
3070 } 3149 }
3071
3072 purple_debug_misc("purple_str_add_cr", "got: %s, leaving with %s\n",
3073 text, ret);
3074 3150
3075 return ret; 3151 return ret;
3076 } 3152 }
3077 3153
3078 void 3154 void
3199 } 3275 }
3200 3276
3201 char * 3277 char *
3202 purple_str_size_to_units(size_t size) 3278 purple_str_size_to_units(size_t size)
3203 { 3279 {
3204 static const char *size_str[4] = { "bytes", "KiB", "MiB", "GiB" }; 3280 static const char * const size_str[] = { "bytes", "KiB", "MiB", "GiB" };
3205 float size_mag; 3281 float size_mag;
3206 int size_index = 0; 3282 int size_index = 0;
3207 3283
3208 if (size == -1) { 3284 if (size == -1) {
3209 return g_strdup(_("Calculating...")); 3285 return g_strdup(_("Calculating..."));
3392 const char *at, *slash; 3468 const char *at, *slash;
3393 const char *turl; 3469 const char *turl;
3394 char host[256], path[256], user[256], passwd[256]; 3470 char host[256], path[256], user[256], passwd[256];
3395 int port = 0; 3471 int port = 0;
3396 /* hyphen at end includes it in control set */ 3472 /* hyphen at end includes it in control set */
3397 static char addr_ctrl[] = "A-Za-z0-9.-"; 3473 static const char addr_ctrl[] = "A-Za-z0-9.-";
3398 static char port_ctrl[] = "0-9"; 3474 static const char port_ctrl[] = "0-9";
3399 static char page_ctrl[] = "A-Za-z0-9.~_/:*!@&%%?=+^-"; 3475 static const char page_ctrl[] = "A-Za-z0-9.~_/:*!@&%%?=+^-";
3400 static char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; 3476 static const char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
3401 static char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; 3477 static const char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
3402 3478
3403 g_return_val_if_fail(url != NULL, FALSE); 3479 g_return_val_if_fail(url != NULL, FALSE);
3404 3480
3405 if ((turl = purple_strcasestr(url, "http://")) != NULL) 3481 if ((turl = purple_strcasestr(url, "http://")) != NULL)
3406 { 3482 {
3691 3767
3692 new_data = g_try_malloc(content_len); 3768 new_data = g_try_malloc(content_len);
3693 if(new_data == NULL) { 3769 if(new_data == NULL) {
3694 purple_debug_error("util", 3770 purple_debug_error("util",
3695 "Failed to allocate %u bytes: %s\n", 3771 "Failed to allocate %u bytes: %s\n",
3696 content_len, strerror(errno)); 3772 content_len, g_strerror(errno));
3697 purple_util_fetch_url_error(gfud, 3773 purple_util_fetch_url_error(gfud,
3698 _("Unable to allocate enough memory to hold " 3774 _("Unable to allocate enough memory to hold "
3699 "the contents from %s. The web server may " 3775 "the contents from %s. The web server may "
3700 "be trying something malicious."), 3776 "be trying something malicious."),
3701 gfud->website.address); 3777 gfud->website.address);
3729 if(len < 0) { 3805 if(len < 0) {
3730 if(errno == EAGAIN) { 3806 if(errno == EAGAIN) {
3731 return; 3807 return;
3732 } else { 3808 } else {
3733 purple_util_fetch_url_error(gfud, _("Error reading from %s: %s"), 3809 purple_util_fetch_url_error(gfud, _("Error reading from %s: %s"),
3734 gfud->website.address, strerror(errno)); 3810 gfud->website.address, g_strerror(errno));
3735 return; 3811 return;
3736 } 3812 }
3737 } 3813 }
3738 3814
3739 if((len == 0) || got_eof) { 3815 if((len == 0) || got_eof) {
3760 3836
3761 if (len < 0 && errno == EAGAIN) 3837 if (len < 0 && errno == EAGAIN)
3762 return; 3838 return;
3763 else if (len < 0) { 3839 else if (len < 0) {
3764 purple_util_fetch_url_error(gfud, _("Error writing to %s: %s"), 3840 purple_util_fetch_url_error(gfud, _("Error writing to %s: %s"),
3765 gfud->website.address, strerror(errno)); 3841 gfud->website.address, g_strerror(errno));
3766 return; 3842 return;
3767 } 3843 }
3768 gfud->request_written += len; 3844 gfud->request_written += len;
3769 3845
3770 if (gfud->request_written < total_len) 3846 if (gfud->request_written < total_len)