loudmouth/src/lm-utils.c
changeset 10 59927b2d3b75
parent 0 d0f3a028347a
equal deleted inserted replaced
0:d0f3a028347a 10:59927b2d3b75
     1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
       
     2 /*
       
     3  * Copyright (C) 2003 Imendio AB 
       
     4  *
       
     5  * This program is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU Lesser General Public License as
       
     7  * published by the Free Software Foundation; either version 2 of the
       
     8  * License, or (at your option) any later version.
       
     9  *
       
    10  * This program is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13  * Lesser General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU Lesser General Public
       
    16  * License along with this program; if not, write to the
       
    17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    18  * Boston, MA 02111-1307, USA.
       
    19  */
       
    20 
       
    21 #include <config.h>
       
    22 #include <string.h>
       
    23 #include <stdio.h>
       
    24 #include <stdlib.h>
       
    25 #include <time.h>
       
    26 
       
    27 #include <glib.h>
       
    28 
       
    29 #ifndef G_OS_WIN32
       
    30 #include <unistd.h>
       
    31 #endif
       
    32 
       
    33 #ifdef HAVE_IDN
       
    34 #include <stringprep.h>
       
    35 #include <punycode.h>
       
    36 #include <idna.h>
       
    37 #endif
       
    38 
       
    39 #include "lm-internals.h"
       
    40 #include "lm-utils.h"
       
    41 
       
    42 #ifdef EMULATOR
       
    43 #include "libloudmouth_wsd_solution.h"
       
    44 GET_STATIC_VAR_FROM_TLS(last_id, lm_utils, guint)
       
    45   #define last_id (*GET_WSD_VAR_NAME(last_id, lm_utils, s)())
       
    46   
       
    47 GET_STATIC_ARRAY_FROM_TLS(base64chars, lm_utils, gchar)
       
    48   #define base64chars (GET_WSD_VAR_NAME(base64chars, lm_utils, s)())
       
    49 #endif
       
    50 
       
    51 
       
    52 LmCallback *
       
    53 _lm_utils_new_callback (gpointer func, 
       
    54 			gpointer user_data,
       
    55 			GDestroyNotify notify)
       
    56 {
       
    57 	LmCallback *cb;
       
    58 	
       
    59 	cb = g_new0 (LmCallback, 1);
       
    60 	cb->func = func;
       
    61 	cb->user_data = user_data;
       
    62 	cb->notify = notify;
       
    63 
       
    64 	return cb;
       
    65 }
       
    66 
       
    67 void
       
    68 _lm_utils_free_callback (LmCallback *cb)
       
    69 {
       
    70 	if (!cb) {
       
    71 		return;
       
    72 	}
       
    73 
       
    74 	if (cb->notify) {
       
    75 		(* cb->notify) (cb->user_data);
       
    76 	}
       
    77 	g_free (cb);
       
    78 }
       
    79 
       
    80 gchar *
       
    81 _lm_utils_generate_id (void)
       
    82 {
       
    83 #ifndef EMULATOR
       
    84 	static guint  last_id = 0;
       
    85 #endif
       
    86 	GTimeVal      tv;
       
    87 	glong         val;
       
    88 
       
    89 	g_get_current_time (&tv);
       
    90 	val = (tv.tv_sec & tv.tv_usec) + last_id++;
       
    91 		
       
    92 	return g_strdup_printf ("%ld%ld", val, tv.tv_usec);
       
    93 }
       
    94 
       
    95 gchar * 
       
    96 _lm_utils_base64_encode (const gchar *s)
       
    97 {
       
    98 #ifndef EMULATOR
       
    99 
       
   100 	static const gchar *base64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
       
   101 #endif
       
   102 	guint    i, j;
       
   103 	guint32  bits = 0;
       
   104 	guint    maxlen = (strlen(s) * 2) + 3;
       
   105 	gchar   *str;
       
   106 
       
   107 	str = g_malloc(maxlen);
       
   108 
       
   109 	j = 0;
       
   110 	for (i = 0; i < strlen(s); i++) {
       
   111 		bits <<= 8;
       
   112 		bits |= s[i] & 0xff;
       
   113 
       
   114 		if (!((i+1) % 3)) {
       
   115 			guint indices[4];
       
   116 
       
   117 			indices[0] = (bits >> 18) & 0x3f;
       
   118 			indices[1] = (bits >> 12) & 0x3f;
       
   119 			indices[2] = (bits >> 6) & 0x3f;
       
   120 			indices[3] = bits & 0x3f;
       
   121 			bits = 0;
       
   122 
       
   123 			str[j++] = base64chars[(indices[0])];
       
   124 			str[j++] = base64chars[(indices[1])];
       
   125 			str[j++] = base64chars[(indices[2])];
       
   126 			str[j++] = base64chars[(indices[3])];
       
   127 		}
       
   128 	}
       
   129 
       
   130 	if (j + 4 < maxlen) {
       
   131 		if ((i % 3) == 1) {
       
   132 			guint indices[2];
       
   133 
       
   134 			indices[0] = (bits >> 2) & 0x3f;
       
   135 			indices[1] = (bits << 4) & 0x3f;
       
   136 
       
   137 			str[j++] = base64chars[(indices[0])];
       
   138 			str[j++] = base64chars[(indices[1])];
       
   139 			str[j++] = '=';
       
   140 			str[j++] = '=';
       
   141 		} else if ((i % 3) == 2) {
       
   142 			guint indices[3];
       
   143 
       
   144 			indices[0] = (bits >> 10) & 0x3f;
       
   145 			indices[1] = (bits >> 4) & 0x3f;
       
   146 			indices[2] = (bits << 2) & 0x3f;
       
   147 
       
   148 			str[j++] = base64chars[(indices[0])];
       
   149 			str[j++] = base64chars[(indices[1])];
       
   150 			str[j++] = base64chars[(indices[2])];
       
   151 			str[j++] = '=';
       
   152 		}
       
   153 	}
       
   154 
       
   155 	str[j] = '\0';
       
   156 
       
   157 	return str;
       
   158 }
       
   159 
       
   160 gchar*
       
   161 _lm_utils_hostname_to_punycode (const gchar *hostname)
       
   162 {
       
   163 #ifdef HAVE_IDN
       
   164 	char *s;
       
   165 	uint32_t *q;
       
   166 	int rc;
       
   167 	gchar *result;
       
   168 
       
   169 	q = stringprep_utf8_to_ucs4 (hostname, -1, NULL);
       
   170 	if (q == NULL) {
       
   171 		return g_strdup (hostname);
       
   172 	}
       
   173 
       
   174 	rc = idna_to_ascii_4z (q, &s, IDNA_ALLOW_UNASSIGNED);
       
   175 	free(q);
       
   176 	if (rc != IDNA_SUCCESS) {
       
   177 		return g_strdup (hostname);
       
   178 	}
       
   179 
       
   180 	/* insures result is allocated through glib */
       
   181 	result = g_strdup(s);
       
   182 	free(s);
       
   183 
       
   184 	return result;
       
   185 #else
       
   186 	return g_strdup(hostname);
       
   187 #endif
       
   188 }
       
   189 
       
   190 /**
       
   191  * lm_utils_get_localtime:
       
   192  * @stamp: An XMPP timestamp
       
   193  *
       
   194  * Converts an XMPP timestamp to a struct tm showing local time.
       
   195  * 
       
   196  * Return value: The local time struct.
       
   197  **/
       
   198 EXPORT_C struct tm *
       
   199 lm_utils_get_localtime (const gchar *stamp)
       
   200 {
       
   201 	struct tm tm;
       
   202 	time_t    t;
       
   203 	gint      year, month;
       
   204 	
       
   205 	g_return_val_if_fail (stamp != NULL, NULL);
       
   206 
       
   207 	/* 20021209T23:51:30 */
       
   208 
       
   209 	sscanf (stamp, "%4d%2d%2dT%2d:%2d:%2d", 
       
   210 		&year, &month, &tm.tm_mday, &tm.tm_hour,
       
   211 		&tm.tm_min, &tm.tm_sec);
       
   212 
       
   213 	tm.tm_year = year - 1900;
       
   214 	tm.tm_mon = month - 1;
       
   215 	tm.tm_isdst = -1;
       
   216 
       
   217  	t = mktime (&tm);
       
   218 
       
   219 #if defined(HAVE_TM_GMTOFF)
       
   220 	t += tm.tm_gmtoff;
       
   221 #elif defined(HAVE_TIMEZONE)
       
   222 	t -= timezone;
       
   223 	if (tm.tm_isdst > 0) {
       
   224 		t += 3600;
       
   225 	}
       
   226 #endif	
       
   227 
       
   228 	return localtime (&t);
       
   229 }
       
   230 
       
   231