| 1535 if(alt) { |
1535 if(alt) { |
| 1536 if(plain) |
1536 if(plain) |
| 1537 plain = g_string_append(plain, alt->str); |
1537 plain = g_string_append(plain, alt->str); |
| 1538 if(!src && xhtml) |
1538 if(!src && xhtml) |
| 1539 xhtml = g_string_append(xhtml, alt->str); |
1539 xhtml = g_string_append(xhtml, alt->str); |
| |
1540 g_string_free(alt, TRUE); |
| 1540 } |
1541 } |
| 1541 g_string_free(alt, TRUE); |
|
| 1542 g_string_free(src, TRUE); |
1542 g_string_free(src, TRUE); |
| 1543 continue; |
1543 continue; |
| 1544 } |
1544 } |
| 1545 if(!g_ascii_strncasecmp(c, "<a", 2) && (*(c+2) == '>' || *(c+2) == ' ')) { |
1545 if(!g_ascii_strncasecmp(c, "<a", 2) && (*(c+2) == '>' || *(c+2) == ' ')) { |
| 1546 const char *p = c; |
1546 const char *p = c; |
| 1569 pt = g_new0(struct purple_parse_tag, 1); |
1569 pt = g_new0(struct purple_parse_tag, 1); |
| 1570 pt->src_tag = "a"; |
1570 pt->src_tag = "a"; |
| 1571 pt->dest_tag = "a"; |
1571 pt->dest_tag = "a"; |
| 1572 tags = g_list_prepend(tags, pt); |
1572 tags = g_list_prepend(tags, pt); |
| 1573 if(xhtml) |
1573 if(xhtml) |
| 1574 g_string_append_printf(xhtml, "<a href='%s'>", g_strstrip(url->str)); |
1574 g_string_append_printf(xhtml, "<a href='%s'>", url ? g_strstrip(url->str) : ""); |
| 1575 continue; |
1575 continue; |
| 1576 } |
1576 } |
| 1577 if(!g_ascii_strncasecmp(c, "<font", 5) && (*(c+5) == '>' || *(c+5) == ' ')) { |
1577 if(!g_ascii_strncasecmp(c, "<font", 5) && (*(c+5) == '>' || *(c+5) == ' ')) { |
| 1578 const char *p = c; |
1578 const char *p = c; |
| 1579 GString *style = g_string_new(""); |
1579 GString *style = g_string_new(""); |
| 1662 c = p; |
1662 c = p; |
| 1663 pt = g_new0(struct purple_parse_tag, 1); |
1663 pt = g_new0(struct purple_parse_tag, 1); |
| 1664 pt->src_tag = "font"; |
1664 pt->src_tag = "font"; |
| 1665 pt->dest_tag = "span"; |
1665 pt->dest_tag = "span"; |
| 1666 tags = g_list_prepend(tags, pt); |
1666 tags = g_list_prepend(tags, pt); |
| 1667 if(style->len) |
1667 if(style->len && xhtml) |
| 1668 g_string_append_printf(xhtml, "<span style='%s'>", g_strstrip(style->str)); |
1668 g_string_append_printf(xhtml, "<span style='%s'>", g_strstrip(style->str)); |
| 1669 else |
1669 else |
| 1670 pt->ignore = TRUE; |
1670 pt->ignore = TRUE; |
| 1671 g_string_free(style, TRUE); |
1671 g_string_free(style, TRUE); |
| 1672 continue; |
1672 continue; |
| 2565 if (!g_file_test(user_dir, G_FILE_TEST_IS_DIR)) |
2565 if (!g_file_test(user_dir, G_FILE_TEST_IS_DIR)) |
| 2566 { |
2566 { |
| 2567 if (g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1) |
2567 if (g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1) |
| 2568 { |
2568 { |
| 2569 purple_debug_error("util", "Error creating directory %s: %s\n", |
2569 purple_debug_error("util", "Error creating directory %s: %s\n", |
| 2570 user_dir, strerror(errno)); |
2570 user_dir, g_strerror(errno)); |
| 2571 return FALSE; |
2571 return FALSE; |
| 2572 } |
2572 } |
| 2573 } |
2573 } |
| 2574 |
2574 |
| 2575 filename_full = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", user_dir, filename); |
2575 filename_full = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", user_dir, filename); |
| 2600 { |
2603 { |
| 2601 if (g_unlink(filename_temp) == -1) |
2604 if (g_unlink(filename_temp) == -1) |
| 2602 { |
2605 { |
| 2603 purple_debug_error("util", "Error removing old file " |
2606 purple_debug_error("util", "Error removing old file " |
| 2604 "%s: %s\n", |
2607 "%s: %s\n", |
| 2605 filename_temp, strerror(errno)); |
2608 filename_temp, g_strerror(errno)); |
| 2606 } |
2609 } |
| 2607 } |
2610 } |
| 2608 |
2611 |
| 2609 /* Open file */ |
2612 /* Open file */ |
| 2610 file = g_fopen(filename_temp, "wb"); |
2613 file = g_fopen(filename_temp, "wb"); |
| 2611 if (file == NULL) |
2614 if (file == NULL) |
| 2612 { |
2615 { |
| 2613 purple_debug_error("util", "Error opening file %s for " |
2616 purple_debug_error("util", "Error opening file %s for " |
| 2614 "writing: %s\n", |
2617 "writing: %s\n", |
| 2615 filename_temp, strerror(errno)); |
2618 filename_temp, g_strerror(errno)); |
| 2616 g_free(filename_temp); |
2619 g_free(filename_temp); |
| 2617 return FALSE; |
2620 return FALSE; |
| 2618 } |
2621 } |
| 2619 |
2622 |
| 2620 /* Write to file */ |
2623 /* Write to file */ |
| 2621 real_size = (size == -1) ? strlen(data) : (size_t) size; |
2624 real_size = (size == -1) ? strlen(data) : (size_t) size; |
| 2622 byteswritten = fwrite(data, 1, real_size, file); |
2625 byteswritten = fwrite(data, 1, real_size, file); |
| 2623 |
2626 |
| |
2627 #ifdef HAVE_FILENO |
| |
2628 /* Apparently XFS (and possibly other filesystems) do not |
| |
2629 * guarantee that file data is flushed before file metadata, |
| |
2630 * so this procedure is insufficient without some flushage. */ |
| |
2631 if (fflush(file) < 0) { |
| |
2632 purple_debug_error("util", "Error flushing %s: %s\n", |
| |
2633 filename_temp, g_strerror(errno)); |
| |
2634 g_free(filename_temp); |
| |
2635 fclose(file); |
| |
2636 return FALSE; |
| |
2637 } |
| |
2638 if (fsync(fileno(file)) < 0) { |
| |
2639 purple_debug_error("util", "Error syncing file contents for %s: %s\n", |
| |
2640 filename_temp, g_strerror(errno)); |
| |
2641 g_free(filename_temp); |
| |
2642 fclose(file); |
| |
2643 return FALSE; |
| |
2644 } |
| |
2645 #endif |
| |
2646 |
| 2624 /* Close file */ |
2647 /* Close file */ |
| 2625 if (fclose(file) != 0) |
2648 if (fclose(file) != 0) |
| 2626 { |
2649 { |
| 2627 purple_debug_error("util", "Error closing file %s: %s\n", |
2650 purple_debug_error("util", "Error closing file %s: %s\n", |
| 2628 filename_temp, strerror(errno)); |
2651 filename_temp, g_strerror(errno)); |
| 2629 g_free(filename_temp); |
2652 g_free(filename_temp); |
| 2630 return FALSE; |
2653 return FALSE; |
| 2631 } |
2654 } |
| |
2655 |
| |
2656 #ifndef HAVE_FILENO |
| |
2657 /* This is the same effect (we hope) as the HAVE_FILENO block |
| |
2658 * above, but for systems without fileno(). */ |
| |
2659 if ((fd = open(filename_temp, O_RDWR)) < 0) { |
| |
2660 purple_debug_error("util", "Error opening file %s for flush: %s\n", |
| |
2661 filename_temp, g_strerror(errno)); |
| |
2662 g_free(filename_temp); |
| |
2663 return FALSE; |
| |
2664 } |
| |
2665 if (fsync(fd) < 0) { |
| |
2666 purple_debug_error("util", "Error syncing %s: %s\n", |
| |
2667 filename_temp, g_strerror(errno)); |
| |
2668 g_free(filename_temp); |
| |
2669 close(fd); |
| |
2670 return FALSE; |
| |
2671 } |
| |
2672 if (close(fd) < 0) { |
| |
2673 purple_debug_error("util", "Error closing %s after sync: %s\n", |
| |
2674 filename_temp, g_strerror(errno)); |
| |
2675 g_free(filename_temp); |
| |
2676 return FALSE; |
| |
2677 } |
| |
2678 #endif |
| 2632 |
2679 |
| 2633 /* Ensure the file is the correct size */ |
2680 /* Ensure the file is the correct size */ |
| 2634 if (byteswritten != real_size) |
2681 if (byteswritten != real_size) |
| 2635 { |
2682 { |
| 2636 purple_debug_error("util", "Error writing to file %s: Wrote %" |
2683 purple_debug_error("util", "Error writing to file %s: Wrote %" |
| 2655 #ifndef _WIN32 |
2702 #ifndef _WIN32 |
| 2656 /* Set file permissions */ |
2703 /* Set file permissions */ |
| 2657 if (chmod(filename_temp, S_IRUSR | S_IWUSR) == -1) |
2704 if (chmod(filename_temp, S_IRUSR | S_IWUSR) == -1) |
| 2658 { |
2705 { |
| 2659 purple_debug_error("util", "Error setting permissions of file %s: %s\n", |
2706 purple_debug_error("util", "Error setting permissions of file %s: %s\n", |
| 2660 filename_temp, strerror(errno)); |
2707 filename_temp, g_strerror(errno)); |
| 2661 } |
2708 } |
| 2662 #endif |
2709 #endif |
| 2663 |
2710 |
| 2664 /* Rename to the REAL name */ |
2711 /* Rename to the REAL name */ |
| 2665 if (g_rename(filename_temp, filename_full) == -1) |
2712 if (g_rename(filename_temp, filename_full) == -1) |
| 2666 { |
2713 { |
| 2667 purple_debug_error("util", "Error renaming %s to %s: %s\n", |
2714 purple_debug_error("util", "Error renaming %s to %s: %s\n", |
| 2668 filename_temp, filename_full, |
2715 filename_temp, filename_full, |
| 2669 strerror(errno)); |
2716 g_strerror(errno)); |
| 2670 } |
2717 } |
| 2671 |
2718 |
| 2672 g_free(filename_temp); |
2719 g_free(filename_temp); |
| 2673 |
2720 |
| 2674 return TRUE; |
2721 return TRUE; |
| 3416 const char *at, *slash; |
3460 const char *at, *slash; |
| 3417 const char *turl; |
3461 const char *turl; |
| 3418 char host[256], path[256], user[256], passwd[256]; |
3462 char host[256], path[256], user[256], passwd[256]; |
| 3419 int port = 0; |
3463 int port = 0; |
| 3420 /* hyphen at end includes it in control set */ |
3464 /* hyphen at end includes it in control set */ |
| 3421 static char addr_ctrl[] = "A-Za-z0-9.-"; |
3465 static const char addr_ctrl[] = "A-Za-z0-9.-"; |
| 3422 static char port_ctrl[] = "0-9"; |
3466 static const char port_ctrl[] = "0-9"; |
| 3423 static char page_ctrl[] = "A-Za-z0-9.~_/:*!@&%%?=+^-"; |
3467 static const char page_ctrl[] = "A-Za-z0-9.~_/:*!@&%%?=+^-"; |
| 3424 static char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; |
3468 static const char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; |
| 3425 static char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; |
3469 static const char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; |
| 3426 |
3470 |
| 3427 g_return_val_if_fail(url != NULL, FALSE); |
3471 g_return_val_if_fail(url != NULL, FALSE); |
| 3428 |
3472 |
| 3429 if ((turl = purple_strcasestr(url, "http://")) != NULL) |
3473 if ((turl = purple_strcasestr(url, "http://")) != NULL) |
| 3430 { |
3474 { |
| 3715 |
3759 |
| 3716 new_data = g_try_malloc(content_len); |
3760 new_data = g_try_malloc(content_len); |
| 3717 if(new_data == NULL) { |
3761 if(new_data == NULL) { |
| 3718 purple_debug_error("util", |
3762 purple_debug_error("util", |
| 3719 "Failed to allocate %u bytes: %s\n", |
3763 "Failed to allocate %u bytes: %s\n", |
| 3720 content_len, strerror(errno)); |
3764 content_len, g_strerror(errno)); |
| 3721 purple_util_fetch_url_error(gfud, |
3765 purple_util_fetch_url_error(gfud, |
| 3722 _("Unable to allocate enough memory to hold " |
3766 _("Unable to allocate enough memory to hold " |
| 3723 "the contents from %s. The web server may " |
3767 "the contents from %s. The web server may " |
| 3724 "be trying something malicious."), |
3768 "be trying something malicious."), |
| 3725 gfud->website.address); |
3769 gfud->website.address); |