Annotation of ircnowd/src/ngircd/conn-encoding.c, Revision 1.1.1.1
1.1 tomglok 1: /*
2: * ngIRCd -- The Next Generation IRC Daemon
3: * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
4: *
5: * This program is free software; you can redistribute it and/or modify
6: * it under the terms of the GNU General Public License as published by
7: * the Free Software Foundation; either version 2 of the License, or
8: * (at your option) any later version.
9: * Please read the file COPYING, README and AUTHORS for more information.
10: */
11:
12: #define __conn_encoding_c__
13:
14: #define CONN_MODULE
15:
16: #include "portab.h"
17:
18: /**
19: * @file
20: * Functions to deal with character encodings and conversions
21: */
22:
23: #include <assert.h>
24: #include <stdio.h>
25: #include <string.h>
26: #include <strings.h>
27:
28: #include "conn.h"
29:
30: #ifdef ICONV
31:
32: #include "log.h"
33: #include "conn-encoding.h"
34:
35: char Encoding_Buffer[COMMAND_LEN];
36: char *Convert_Message PARAMS((iconv_t Handle, char *Message));
37:
38: /**
39: * Set client character encoding on a connection.
40: *
41: * @param Conn Connection identifier.
42: * @param ClientEnc Client encoding (for example "ASCII", "MacRoman", ...).
43: * @return true on success, false otherwise.
44: */
45: GLOBAL bool
46: Conn_SetEncoding(CONN_ID Conn, const char *ClientEnc)
47: {
48: char client_enc[25], server_enc[25];
49:
50: assert(Conn > NONE);
51: assert(ClientEnc != NULL);
52:
53: Conn_UnsetEncoding(Conn);
54:
55: /* Is the client character set identical to server character set? */
56: if (strcasecmp(ClientEnc, "UTF-8") == 0)
57: return true;
58:
59: snprintf(client_enc, sizeof(client_enc), "%s//TRANSLIT", ClientEnc);
60: snprintf(server_enc, sizeof(server_enc), "%s//TRANSLIT", "UTF-8");
61:
62: My_Connections[Conn].iconv_from = iconv_open(server_enc, client_enc);
63: if (My_Connections[Conn].iconv_from == (iconv_t)(-1)) {
64: Conn_UnsetEncoding(Conn);
65: return false;
66: }
67: My_Connections[Conn].iconv_to = iconv_open(client_enc, server_enc);
68: if (My_Connections[Conn].iconv_to == (iconv_t)(-1)) {
69: Conn_UnsetEncoding(Conn);
70: return false;
71: }
72:
73: LogDebug("Set client character set of connection \"%d\" to \"%s\".",
74: Conn, client_enc);
75: return true;
76: }
77:
78: /**
79: * Remove client character encoding conversion on a connection.
80: *
81: * @param Conn Connection identifier.
82: */
83: GLOBAL void
84: Conn_UnsetEncoding(CONN_ID Conn)
85: {
86: assert(Conn > NONE);
87:
88: if (My_Connections[Conn].iconv_from != (iconv_t)(-1))
89: iconv_close(My_Connections[Conn].iconv_from);
90: if (My_Connections[Conn].iconv_to != (iconv_t)(-1))
91: iconv_close(My_Connections[Conn].iconv_to);
92:
93: My_Connections[Conn].iconv_from = (iconv_t)(-1);
94: My_Connections[Conn].iconv_to = (iconv_t)(-1);
95:
96: LogDebug("Unset character conversion of connection %d.", Conn);
97: }
98:
99: /**
100: * Convert the encoding of a given message.
101: *
102: * This function uses a static buffer for the result of the encoding
103: * conversion which is overwritten by subsequent calls to this function!
104: *
105: * @param Handle libiconv handle.
106: * @param Message The message to convert.
107: * @return Pointer to the result.
108: */
109: char *
110: Convert_Message(iconv_t Handle, char *Message)
111: {
112: size_t in_left, out_left;
113: char *out = Encoding_Buffer;
114:
115: assert (Handle != (iconv_t)(-1));
116: assert (Message != NULL);
117:
118: in_left = strlen(Message);
119: out_left = sizeof(Encoding_Buffer) - 1;
120:
121: if (iconv(Handle, &Message, &in_left, &out, &out_left) == (size_t)(-1)) {
122: /* An error occurred! */
123: LogDebug("Error converting message encoding!");
124: strlcpy(out, Message, sizeof(Encoding_Buffer));
125: iconv(Handle, NULL, NULL, NULL, NULL);
126: } else
127: *out = '\0';
128:
129: return Encoding_Buffer;
130: }
131:
132: #endif /* ICONV */
133:
134: /**
135: * Convert encoding of a message received from a connection.
136: *
137: * Note 1: If no conversion is required, this function returns the original
138: * pointer to the message.
139: *
140: * Note 2: This function uses Convert_Message(), so subsequent calls to this
141: * function will overwrite the earlier results.
142: *
143: * @param Conn Connection identifier.
144: * @param Message The message to convert.
145: * @return Pointer to the result.
146: * @see Convert_Message
147: */
148: GLOBAL char *
149: Conn_EncodingFrom(UNUSED CONN_ID Conn, char *Message)
150: {
151: assert(Conn > NONE);
152: assert (Message != NULL);
153:
154: #ifdef ICONV
155: if (My_Connections[Conn].iconv_from != (iconv_t)(-1))
156: return Convert_Message(My_Connections[Conn].iconv_from, Message);
157: #endif
158: return Message;
159: }
160:
161: /**
162: * Convert encoding of a message for sending on a connection.
163: *
164: * Note 1: If no conversion is required, this function returns the original
165: * pointer to the message.
166: *
167: * Note 2: This function uses Convert_Message(), so subsequent calls to this
168: * function will overwrite the earlier results.
169: *
170: * @param Conn Connection identifier.
171: * @param Message The message to convert.
172: * @return Pointer to the result.
173: * @see Convert_Message
174: */
175: GLOBAL char *
176: Conn_EncodingTo(UNUSED CONN_ID Conn, char *Message)
177: {
178: assert(Conn > NONE);
179: assert (Message != NULL);
180:
181: #ifdef ICONV
182: if (My_Connections[Conn].iconv_to != (iconv_t)(-1))
183: return Convert_Message(My_Connections[Conn].iconv_to, Message);
184: #endif
185: return Message;
186: }
187:
188: /* -eof- */
CVSweb