Mercurial > pidgin.yaz
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, "&"); | |
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) |