Annotation of ircnowd/src/ngircd/conn-encoding.c, Revision 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