1 /*:ts=8*/
2 /*****************************************************************************
3  * FIDOGATE --- Gateway UNIX Mail/News <-> FTN NetMail/EchoMail
4  *
5  * $Id: mime.c,v 4.18 2004/08/22 20:19:11 n0ll Exp $
6  *
7  * MIME stuff
8  *
9  *****************************************************************************
10  * Copyright (C) 1990-2004
11  *  _____ _____
12  * |     |___  |   Martin Junius             <mj.at.n0ll.dot.net>
13  * | | | |   | |   Radiumstr. 18
14  * |_|_|_|@home|   D-51069 Koeln, Germany
15  *
16  * This file is part of FIDOGATE.
17  *
18  * FIDOGATE is free software; you can redistribute it and/or modify it
19  * under the terms of the GNU General Public License as published by the
20  * Free Software Foundation; either version 2, or (at your option) any
21  * later version.
22  *
23  * FIDOGATE is distributed in the hope that it will be useful, but
24  * WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26  * General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with FIDOGATE; see the file COPYING.  If not, write to the Free
30  * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
31  *****************************************************************************/
32 
33 #include "fidogate.h"
34 
35 
36 static int is_qpx		(int);
37 static int x2toi		(char *);
38 
39 
is_qpx(int c)40 static int is_qpx(int c)
41 {
42     return isxdigit(c) /**is_digit(c) || (c>='A' && c<='F')**/ ;
43 }
44 
45 
x2toi(char * s)46 static int x2toi(char *s)
47 {
48     int val = 0;
49     int n;
50 
51     n = toupper(*s) - (isalpha(*s) ? 'A'-10 : '0');
52     val = val*16 + n;
53     s++;
54     n = toupper(*s) - (isalpha(*s) ? 'A'-10 : '0');
55     val = val*16 + n;
56 
57     return val;
58 }
59 
60 
61 
62 /*
63  * Dequote string with MIME-style quoted-printable =XX
64  */
mime_dequote(char * d,size_t n,char * s,int flags)65 char *mime_dequote(char *d, size_t n, char *s, int flags)
66 {
67     int i, c=0;
68     char *xl;
69 
70     for(i=0; i<n-1 && *s; i++, s++)
71     {
72 	if( (flags & MIME_QP) && (s[0] == '=') )/* MIME quoted printable */
73 	{
74 	    if(is_qpx(s[1]) && is_qpx(s[2]))	/* =XX */
75 	    {
76 	        c = x2toi(s+1);
77 		s += 2;
78 	    }
79 	    else if(s[1]=='\n'           ||	/* =<LF> and */
80 	       (s[1]=='\r' && s[2]=='\n')  )	/* =<CR><LF> */
81 	    {
82 		break;
83 	    }
84 	}
85 	else if( (flags & MIME_US) && (s[0] == '_') ) /* Underscore */
86 	{
87 	    c = ' ';
88 	}
89 	else {					/* Nothing special to do */
90 	    c = *s;
91 	}
92 
93 	if(c & 0x80)
94 	{
95 	    /* Translate special characters according to charset */
96 	    if( (xl = charset_map_c(c, FALSE)) )
97 	    {
98 		while(*xl && i<n-1)
99 		{
100 		    d[i] = *xl++;
101 		    if(*xl)
102 		        i++;
103 		}
104 	    }
105 	}
106 	else
107 	  d[i] = c;
108     }
109     d[i] = 0;
110 
111     return d;
112 }
113 
114 
115 
116 /*
117  * Decode MIME RFC1522 header
118  *
119  **FIXME: currently always assumes ISO-8859-1 char set
120  **FIXME: optional flag for conversion to 7bit ASCII replacements
121  */
122 #define MIME_HEADER_CODE_START	"=?ISO-8859-1?Q?"
123 #define MIME_HEADER_CODE_END	"?="
124 
mime_deheader(char * d,size_t n,char * s,int flags)125 char *mime_deheader(char *d, size_t n, char *s, int flags)
126 {
127     int i;
128     int mime_flag = FALSE;
129 
130     for(i=0; i<n-1 && *s; )
131     {
132 	if(strnieq(s, MIME_HEADER_CODE_START, strlen(MIME_HEADER_CODE_START)))
133 	{
134 	    mime_flag = TRUE;
135 	    s += strlen(MIME_HEADER_CODE_START);
136 	    continue;
137 	}
138 
139 	if(mime_flag)
140 	{
141 	    if(strneq(s, MIME_HEADER_CODE_END, strlen(MIME_HEADER_CODE_END)))
142 	    {
143 		mime_flag = FALSE;
144 		s += strlen(MIME_HEADER_CODE_END);
145 		continue;
146 	    }
147 
148 	    if(s[0] == '=')	/* Maybe MIME quoted printable */
149 	    {
150 		if(is_qpx(s[1]) && is_qpx(s[2]))	/* =XX */
151 		{
152 		    d[i++] = x2toi(s+1);
153 		    s += 3;
154 		    continue;
155 		}
156 	    }
157 
158 	    if(s[0] == '_')
159 	    {
160 		d[i++] = ' ';
161 		s++;
162 		continue;
163 	    }
164 	}
165 
166 	/* Nothing special to do */
167 	d[i++] = *s++;
168     }
169     d[i] = 0;
170 
171     return d;
172 }
173