libpurple/util.c

changeset 40519
974dbfd7e52f
parent 40441
f23c7e772667
child 40545
5f512eb3857f
equal deleted inserted replaced
40518:d587dad11411 40519:974dbfd7e52f
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);
2914 ret = g_strdup_printf(dngettext(PACKAGE, "%d minute", "%d minutes", mins), mins); 2793 ret = g_strdup_printf(dngettext(PACKAGE, "%d minute", "%d minutes", mins), mins);
2915 } 2794 }
2916 2795
2917 return ret; 2796 return ret;
2918 } 2797 }
2919
2920 2798
2921 size_t 2799 size_t
2922 purple_utf16_size(const gunichar2 *str) 2800 purple_utf16_size(const gunichar2 *str)
2923 { 2801 {
2924 /* UTF16 cannot contain two consequent NUL bytes starting at even 2802 /* UTF16 cannot contain two consequent NUL bytes starting at even
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);

mercurial