-
Notifications
You must be signed in to change notification settings - Fork 2
/
qpe.c
260 lines (202 loc) · 6.63 KB
/
qpe.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
/*-----------------------------------------------------------------\
*
* CHANGES:
*
* 20081124-1103:PLD:
* -Fixed up compile warnings for long type integers for 64 bit systems
* -Updated code to conform with normal logging/debugging outputs
* -Adjusted qp_encode to allow for a generic line-terminator string
*
*
*
*
*
*
*
*
*
*
*
*/
#include "logger.h"
#include "qpe.h"
#define QPD if (qpe_debug > 0)
int qpe_debug = 0;
/*-----------------------------------------------------------------\
Date Code: : 20081124-083225
Function Name : qp_encode_set_debug
Returns Type : int
----Parameter List
1. int level ,
------------------
Exit Codes :
Side Effects :
--------------------------------------------------------------------
Comments:
--------------------------------------------------------------------
Changes:
\------------------------------------------------------------------*/
int qp_encode_set_debug( int level )
{
qpe_debug = level;
return 0;
}
/*-----------------------------------------------------------------\
Date Code: : 20081124-083227
Function Name : qp_encode
Returns Type : int
----Parameter List
1. char *out,
2. size_t out_size,
3. char *in,
4. size_t in_size ,
------------------
Exit Codes :
Side Effects :
--------------------------------------------------------------------
Comments:
--------------------------------------------------------------------
Changes:
\------------------------------------------------------------------*/
int qp_encode( char *out, size_t out_size, char *in, size_t in_size, char *line_terminator )
{
int result = 0;
size_t out_remaining;
char *linestart, *lineend, *p, *op;
char paragraph[100], *pp;
size_t pp_remaining = 100;
char *input_data_limit = in +in_size;
size_t current_line_length = 0;
char CRLF[]="\r\n";
fprintf(stderr,"%s:%d:DEBUG: Line terminator length = %d", FL, (int)strlen(line_terminator));
if (line_terminator == NULL) line_terminator = CRLF;
linestart = NULL;
lineend = in;
/** Set the output buffer variables **/
op = out;
out_remaining = out_size;
do {
char charout[4];
int charout_size=0;
if (lineend != '\0') {
if (linestart == NULL) {
linestart = in;
} else {
linestart = lineend;
}
lineend = strstr(linestart, line_terminator);
if (lineend == NULL) {
QPD LOGGER_log("%s:%d:qp_encode:DEBUG: No CRLF found, setting line-end to end of the input",FL);
lineend = in +in_size;
} else {
QPD LOGGER_log("%s:%d:qp_encode:DEBUG: INPUT STRING: '%s'", FL, linestart);
lineend += strlen(line_terminator);
}
}
/** Initialize the paragraph **/
paragraph[0] = '\0';
pp = paragraph;
pp_remaining = sizeof(paragraph);
current_line_length = 0;
QPD LOGGER_log("%s:%d:qp_encode:DEBUG:Starting new line of encoding...",FL);
/** Set p to point to the start of the new line that we have to encode **/
p = linestart;
while ((p < lineend)) {
if (*p < ' ' || *p == '=' || *p > 126) {
/** encode as hex **/
snprintf( charout, sizeof(charout), "=%02X", (unsigned char)*p); // 20070212-2238 Fix supplied by Julian Schneider
charout_size = 3;
} else {
/** encode verbatim **/
snprintf( charout, sizeof(charout), "%c", *p);
charout_size = 1;
}
if (current_line_length +charout_size >= 79) { // Was 76, updated to fix Outlook problems
//snprintf(op, out_remaining, "%s=\r\n", paragraph);
snprintf(op, out_remaining, "%s=%s", paragraph, line_terminator);
op+= strlen(paragraph);// +3; /** jump the output + =\r\n **/
out_remaining-= (strlen(paragraph)); // Was +3, updated to fix Outlook problems
QPD LOGGER_log("%s:%d:qp_encode:DEBUG: Soft break (%Zd + %d > 76 char) for '%s'", FL, current_line_length, charout_size, paragraph);
/** reinitialize the paragraph **/
paragraph[0] = '\0';
pp_remaining = sizeof(paragraph);
pp = paragraph;
current_line_length=-1;
}
snprintf(pp, pp_remaining, "%s", charout);
QPD LOGGER_log("%s:%d:qp_encode:DEBUG: charout='%s', size=%d, pp_remain=%Zd result='%s'", FL, charout, charout_size, pp_remaining, paragraph);
pp += charout_size;
pp_remaining -= charout_size;
p++;
current_line_length += charout_size; // 2007030901 - Patch provided by Yossi Gottlieb
} /** for each char in the line to be converted **/
QPD LOGGER_log("%s:%d:qp_encode:DEBUG: Adding paragraph '%s' to output\n", FL, paragraph );
snprintf(op, out_remaining, "%s\r\n", paragraph);
op += (strlen(paragraph) +2);
out_remaining -= (strlen(paragraph) +2);
} while ((lineend < input_data_limit)&&(*lineend != '\0')); /** for each line **/
return result;
}
/*-----------------------------------------------------------------\
Date Code: : 20081124-083232
Function Name : qp_encode_from_file
Returns Type : int
----Parameter List
1. char *fname ,
------------------
Exit Codes :
Side Effects :
--------------------------------------------------------------------
Comments:
--------------------------------------------------------------------
Changes:
\------------------------------------------------------------------*/
int qp_encode_from_file( char *fname )
{
size_t bc;
struct stat st;
int stat_result;
char *in_buffer;
char *out_buffer;
size_t in_size, out_size;
FILE *f;
stat_result = stat( fname, &st );
if (stat_result != 0){
QPD LOGGER_log("%s:%d:qp_encode_from_file:ERROR: Cannot locate file '%s' for loading and QP encoding (%s)", FL, fname, strerror(errno));
return -1;
}
in_size = st.st_size;
out_size = in_size *3;
in_buffer = malloc( sizeof(char) *in_size +1);
if (in_buffer == NULL) {
QPD LOGGER_log("%s:%d:qp_encode_from_file:ERROR: allocating %Zd bytes for input buffer",FL, in_size);
return -1;
}
out_buffer = malloc( sizeof(char) *out_size *3 +1);
if (in_buffer == NULL) {
QPD LOGGER_log("%s:%d:qp_encode_from_file:ERROR: allocating %Zd bytes for output buffer", FL, out_size);
return -1;
}
f = fopen( fname, "r" );
bc = fread( in_buffer, 1, in_size, f );
if (bc != in_size) LOGGER_log("%s:%d:qp_encode_from_file:ERROR: Read %d bytes but requested %d", FL, bc, in_size);
fclose(f);
/** zero terminate the buffer -- uhuh, if you forget that you'll wonder why
** we segfault ;) **/
*(in_buffer +in_size) = '\0';
QPD LOGGER_log("%s:%d:qp_encode_from_file:DEBUG: file %s is loaded, size = %Zd", FL, fname, in_size);
qp_encode( out_buffer, out_size, in_buffer, in_size, NULL );
fprintf( stdout, "%s", out_buffer );
free(in_buffer);
free(out_buffer);
return 0;
}
/** END of qpe.c **/