| 60 g_free(config_dir); |
60 g_free(config_dir); |
| 61 config_dir = NULL; |
61 config_dir = NULL; |
| 62 |
62 |
| 63 g_free(data_dir); |
63 g_free(data_dir); |
| 64 data_dir = NULL; |
64 data_dir = NULL; |
| 65 } |
|
| 66 |
|
| 67 /************************************************************************** |
|
| 68 * Base16 Functions |
|
| 69 **************************************************************************/ |
|
| 70 gchar * |
|
| 71 purple_base16_encode(const guchar *data, gsize len) |
|
| 72 { |
|
| 73 gsize i; |
|
| 74 gchar *ascii = NULL; |
|
| 75 |
|
| 76 g_return_val_if_fail(data != NULL, NULL); |
|
| 77 g_return_val_if_fail(len > 0, NULL); |
|
| 78 |
|
| 79 ascii = g_malloc(len * 2 + 1); |
|
| 80 |
|
| 81 for (i = 0; i < len; i++) |
|
| 82 g_snprintf(&ascii[i * 2], 3, "%02x", data[i] & 0xFF); |
|
| 83 |
|
| 84 return ascii; |
|
| 85 } |
|
| 86 |
|
| 87 guchar * |
|
| 88 purple_base16_decode(const char *str, gsize *ret_len) |
|
| 89 { |
|
| 90 gsize len, i, accumulator = 0; |
|
| 91 guchar *data; |
|
| 92 |
|
| 93 g_return_val_if_fail(str != NULL, NULL); |
|
| 94 |
|
| 95 len = strlen(str); |
|
| 96 |
|
| 97 g_return_val_if_fail(*str, 0); |
|
| 98 g_return_val_if_fail(len % 2 == 0, 0); |
|
| 99 |
|
| 100 data = g_malloc(len / 2); |
|
| 101 |
|
| 102 for (i = 0; i < len; i++) |
|
| 103 { |
|
| 104 if ((i % 2) == 0) |
|
| 105 accumulator = 0; |
|
| 106 else |
|
| 107 accumulator <<= 4; |
|
| 108 |
|
| 109 if (isdigit(str[i])) |
|
| 110 accumulator |= str[i] - 48; |
|
| 111 else |
|
| 112 { |
|
| 113 switch(tolower(str[i])) |
|
| 114 { |
|
| 115 case 'a': accumulator |= 10; break; |
|
| 116 case 'b': accumulator |= 11; break; |
|
| 117 case 'c': accumulator |= 12; break; |
|
| 118 case 'd': accumulator |= 13; break; |
|
| 119 case 'e': accumulator |= 14; break; |
|
| 120 case 'f': accumulator |= 15; break; |
|
| 121 } |
|
| 122 } |
|
| 123 |
|
| 124 if (i % 2) |
|
| 125 data[(i - 1) / 2] = accumulator; |
|
| 126 } |
|
| 127 |
|
| 128 if (ret_len != NULL) |
|
| 129 *ret_len = len / 2; |
|
| 130 |
|
| 131 return data; |
|
| 132 } |
|
| 133 |
|
| 134 gchar * |
|
| 135 purple_base16_encode_chunked(const guchar *data, gsize len) |
|
| 136 { |
|
| 137 gsize i; |
|
| 138 gchar *ascii = NULL; |
|
| 139 |
|
| 140 g_return_val_if_fail(data != NULL, NULL); |
|
| 141 g_return_val_if_fail(len > 0, NULL); |
|
| 142 |
|
| 143 /* For each byte of input, we need 2 bytes for the hex representation |
|
| 144 * and 1 for the colon. |
|
| 145 * The final colon will be replaced by a terminating NULL |
|
| 146 */ |
|
| 147 ascii = g_malloc(len * 3 + 1); |
|
| 148 |
|
| 149 for (i = 0; i < len; i++) |
|
| 150 g_snprintf(&ascii[i * 3], 4, "%02x:", data[i] & 0xFF); |
|
| 151 |
|
| 152 /* Replace the final colon with NULL */ |
|
| 153 ascii[len * 3 - 1] = 0; |
|
| 154 |
|
| 155 return ascii; |
|
| 156 } |
65 } |
| 157 |
66 |
| 158 /************************************************************************** |
67 /************************************************************************** |
| 159 * Date/Time Functions |
68 * Date/Time Functions |
| 160 **************************************************************************/ |
69 **************************************************************************/ |
| 2505 struct sockaddr_in6 sa_in6; |
2414 struct sockaddr_in6 sa_in6; |
| 2506 #endif |
2415 #endif |
| 2507 struct sockaddr_storage sa_stor; |
2416 struct sockaddr_storage sa_stor; |
| 2508 } PurpleSockaddr; |
2417 } PurpleSockaddr; |
| 2509 |
2418 |
| 2510 char * |
|
| 2511 purple_fd_get_ip(int fd) |
|
| 2512 { |
|
| 2513 PurpleSockaddr addr; |
|
| 2514 socklen_t namelen = sizeof(addr); |
|
| 2515 int family; |
|
| 2516 |
|
| 2517 g_return_val_if_fail(fd != 0, NULL); |
|
| 2518 |
|
| 2519 if (getsockname(fd, &(addr.sa), &namelen)) |
|
| 2520 return NULL; |
|
| 2521 |
|
| 2522 family = addr.sa.sa_family; |
|
| 2523 |
|
| 2524 if (family == AF_INET) { |
|
| 2525 return g_strdup(inet_ntoa(addr.sa_in.sin_addr)); |
|
| 2526 } |
|
| 2527 #if defined(AF_INET6) && defined(HAVE_INET_NTOP) |
|
| 2528 else if (family == AF_INET6) { |
|
| 2529 char host[INET6_ADDRSTRLEN]; |
|
| 2530 const char *tmp; |
|
| 2531 |
|
| 2532 tmp = inet_ntop(family, &(addr.sa_in6.sin6_addr), host, sizeof(host)); |
|
| 2533 return g_strdup(tmp); |
|
| 2534 } |
|
| 2535 #endif |
|
| 2536 |
|
| 2537 return NULL; |
|
| 2538 } |
|
| 2539 |
|
| 2540 int |
2419 int |
| 2541 purple_socket_get_family(int fd) |
2420 purple_socket_get_family(int fd) |
| 2542 { |
2421 { |
| 2543 PurpleSockaddr addr; |
2422 PurpleSockaddr addr; |
| 2544 socklen_t len = sizeof(addr); |
2423 socklen_t len = sizeof(addr); |
| 3285 return utf8; |
3163 return utf8; |
| 3286 |
3164 |
| 3287 g_free(utf8); |
3165 g_free(utf8); |
| 3288 |
3166 |
| 3289 return NULL; |
3167 return NULL; |
| 3290 } |
|
| 3291 |
|
| 3292 #define utf8_first(x) ((x & 0x80) == 0 || (x & 0xe0) == 0xc0 \ |
|
| 3293 || (x & 0xf0) == 0xe0 || (x & 0xf8) == 0xf0) |
|
| 3294 gchar * |
|
| 3295 purple_utf8_salvage(const char *str) |
|
| 3296 { |
|
| 3297 GString *workstr; |
|
| 3298 const char *end; |
|
| 3299 |
|
| 3300 g_return_val_if_fail(str != NULL, NULL); |
|
| 3301 |
|
| 3302 workstr = g_string_sized_new(strlen(str)); |
|
| 3303 |
|
| 3304 do { |
|
| 3305 (void)g_utf8_validate(str, -1, &end); |
|
| 3306 workstr = g_string_append_len(workstr, str, end - str); |
|
| 3307 str = end; |
|
| 3308 if (*str == '\0') |
|
| 3309 break; |
|
| 3310 do { |
|
| 3311 workstr = g_string_append_c(workstr, '?'); |
|
| 3312 str++; |
|
| 3313 } while (!utf8_first(*str)); |
|
| 3314 } while (*str != '\0'); |
|
| 3315 |
|
| 3316 return g_string_free(workstr, FALSE); |
|
| 3317 } |
3168 } |
| 3318 |
3169 |
| 3319 gchar * |
3170 gchar * |
| 3320 purple_utf8_strip_unprintables(const gchar *str) |
3171 purple_utf8_strip_unprintables(const gchar *str) |
| 3321 { |
3172 { |
| 3690 buf[j] = '\0'; |
3541 buf[j] = '\0'; |
| 3691 |
3542 |
| 3692 return buf; |
3543 return buf; |
| 3693 } |
3544 } |
| 3694 |
3545 |
| 3695 void purple_restore_default_signal_handlers(void) |
|
| 3696 { |
|
| 3697 #ifndef _WIN32 |
|
| 3698 signal(SIGHUP, SIG_DFL); /* 1: terminal line hangup */ |
|
| 3699 signal(SIGINT, SIG_DFL); /* 2: interrupt program */ |
|
| 3700 signal(SIGQUIT, SIG_DFL); /* 3: quit program */ |
|
| 3701 signal(SIGILL, SIG_DFL); /* 4: illegal instruction (not reset when caught) */ |
|
| 3702 signal(SIGTRAP, SIG_DFL); /* 5: trace trap (not reset when caught) */ |
|
| 3703 signal(SIGABRT, SIG_DFL); /* 6: abort program */ |
|
| 3704 |
|
| 3705 #ifdef SIGPOLL |
|
| 3706 signal(SIGPOLL, SIG_DFL); /* 7: pollable event (POSIX) */ |
|
| 3707 #endif /* SIGPOLL */ |
|
| 3708 |
|
| 3709 #ifdef SIGEMT |
|
| 3710 signal(SIGEMT, SIG_DFL); /* 7: EMT instruction (Non-POSIX) */ |
|
| 3711 #endif /* SIGEMT */ |
|
| 3712 |
|
| 3713 signal(SIGFPE, SIG_DFL); /* 8: floating point exception */ |
|
| 3714 signal(SIGBUS, SIG_DFL); /* 10: bus error */ |
|
| 3715 signal(SIGSEGV, SIG_DFL); /* 11: segmentation violation */ |
|
| 3716 signal(SIGSYS, SIG_DFL); /* 12: bad argument to system call */ |
|
| 3717 signal(SIGPIPE, SIG_DFL); /* 13: write on a pipe with no reader */ |
|
| 3718 signal(SIGALRM, SIG_DFL); /* 14: real-time timer expired */ |
|
| 3719 signal(SIGTERM, SIG_DFL); /* 15: software termination signal */ |
|
| 3720 signal(SIGCHLD, SIG_DFL); /* 20: child status has changed */ |
|
| 3721 signal(SIGXCPU, SIG_DFL); /* 24: exceeded CPU time limit */ |
|
| 3722 signal(SIGXFSZ, SIG_DFL); /* 25: exceeded file size limit */ |
|
| 3723 #endif /* !_WIN32 */ |
|
| 3724 } |
|
| 3725 |
|
| 3726 static void |
3546 static void |
| 3727 set_status_with_attrs(PurpleStatus *status, ...) |
3547 set_status_with_attrs(PurpleStatus *status, ...) |
| 3728 { |
3548 { |
| 3729 va_list args; |
3549 va_list args; |
| 3730 va_start(args, status); |
3550 va_start(args, status); |
| 3784 } |
3604 } |
| 3785 |
3605 |
| 3786 return g_string_free(string, FALSE); |
3606 return g_string_free(string, FALSE); |
| 3787 } |
3607 } |
| 3788 |
3608 |
| 3789 gchar * |
|
| 3790 purple_uuid_random(void) |
|
| 3791 { |
|
| 3792 guint32 tmp, a, b; |
|
| 3793 |
|
| 3794 tmp = g_random_int(); |
|
| 3795 a = 0x4000 | (tmp & 0xFFF); /* 0x4000 to 0x4FFF */ |
|
| 3796 tmp >>= 12; |
|
| 3797 b = ((1 << 3) << 12) | (tmp & 0x3FFF); /* 0x8000 to 0xBFFF */ |
|
| 3798 |
|
| 3799 tmp = g_random_int(); |
|
| 3800 |
|
| 3801 return g_strdup_printf("%08x-%04x-%04x-%04x-%04x%08x", |
|
| 3802 g_random_int(), |
|
| 3803 tmp & 0xFFFF, |
|
| 3804 a, |
|
| 3805 b, |
|
| 3806 (tmp >> 16) & 0xFFFF, g_random_int()); |
|
| 3807 } |
|
| 3808 |
|
| 3809 void purple_callback_set_zero(gpointer data) |
3609 void purple_callback_set_zero(gpointer data) |
| 3810 { |
3610 { |
| 3811 gpointer *ptr = data; |
3611 gpointer *ptr = data; |
| 3812 |
3612 |
| 3813 g_return_if_fail(ptr != NULL); |
3613 g_return_if_fail(ptr != NULL); |