gsasl  1.8.0
nonascii.c
Go to the documentation of this file.
00001 /* server.c --- DIGEST-MD5 mechanism from RFC 2831, server side.
00002  * Copyright (C) 2002-2012 Simon Josefsson
00003  *
00004  * This file is part of GNU SASL Library.
00005  *
00006  * GNU SASL Library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public License
00008  * as published by the Free Software Foundation; either version 2.1 of
00009  * the License, or (at your option) any later version.
00010  *
00011  * GNU SASL Library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with GNU SASL Library; if not, write to the Free
00018  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 /* Get specification. */
00028 #include "nonascii.h"
00029 
00030 #include <stdlib.h>
00031 #include <string.h>
00032 
00033 /* C89 compliant way to cast 'char' to 'unsigned char'. */
00034 static inline unsigned char
00035 to_uchar (char ch)
00036 {
00037   return ch;
00038 }
00039 
00040 char *
00041 latin1toutf8 (const char *str)
00042 {
00043   char *p = malloc (2 * strlen (str) + 1);
00044   if (p)
00045     {
00046       size_t i, j = 0;
00047       for (i = 0; str[i]; i++)
00048         {
00049           if (to_uchar (str[i]) < 0x80)
00050             p[j++] = str[i];
00051           else if (to_uchar (str[i]) < 0xC0)
00052             {
00053               p[j++] = (unsigned char) 0xC2;
00054               p[j++] = str[i];
00055             }
00056           else
00057             {
00058               p[j++] = (unsigned char) 0xC3;
00059               p[j++] = str[i] - 64;
00060             }
00061         }
00062       p[j] = 0x00;
00063     }
00064 
00065   return p;
00066 }
00067 
00068 char *
00069 utf8tolatin1ifpossible (const char *passwd)
00070 {
00071   char *p;
00072   size_t i;
00073 
00074   for (i = 0; passwd[i]; i++)
00075     {
00076       if (to_uchar (passwd[i]) > 0x7F)
00077         {
00078           if (to_uchar (passwd[i]) < 0xC0 || to_uchar (passwd[i]) > 0xC3)
00079             return strdup (passwd);
00080           i++;
00081           if (to_uchar (passwd[i]) < 0x80 || to_uchar (passwd[i]) > 0xBF)
00082             return strdup (passwd);
00083         }
00084     }
00085 
00086   p = malloc (strlen (passwd) + 1);
00087   if (p)
00088     {
00089       size_t j = 0;
00090       for (i = 0; passwd[i]; i++)
00091         {
00092           if (to_uchar (passwd[i]) > 0x7F)
00093             {
00094               /* p[i+1] can't be zero here */
00095               p[j++] =
00096                 ((to_uchar (passwd[i]) & 0x3) << 6)
00097                 | (to_uchar (passwd[i + 1]) & 0x3F);
00098               i++;
00099             }
00100           else
00101             p[j++] = passwd[i];
00102         }
00103       p[j] = 0x00;
00104     }
00105   return p;
00106 }