File: qpe.c

package info (click to toggle)
altermime 0.3.10-13
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,328 kB
  • sloc: ansic: 17,094; makefile: 82; sh: 15
file content (187 lines) | stat: -rw-r--r-- 4,524 bytes parent folder | download | duplicates (3)
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
#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>

#include "logger.h"
#include "qpe.h"

#define CRLF "\r\n"

#define QPD if (qpe_debug > 0)

int qpe_debug = 0;

int qp_encode_set_debug( int level ) 
{
	qpe_debug = level;

	return 0;
}


int qp_encode( char *out, size_t out_size, char *in, size_t in_size )
{
	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;


	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, CRLF);
			if (lineend == NULL) {
				QPD fprintf(stdout,"No CRLF found, setting line-end to end of the input\n");
			  	lineend = in +in_size;
			} else {
				QPD {
					*lineend = '\0';
					fprintf(stdout,"INPUT STRING: '%s'\n", linestart);
					*lineend = '\r';
				}
				lineend += strlen(CRLF);
			}

		}


		/** Initialize the paragraph **/
		paragraph[0] = '\0';
		pp = paragraph;
		pp_remaining = sizeof(paragraph);
		current_line_length = 0;

		QPD fprintf(stdout,"Starting new line of encoding...\n");

		/** Set p to point to the start of the new line that we have to encode **/
		p = linestart;
		while ((p < lineend)) {

			if (*p < 32 || *p == 61 || *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=\r\n", paragraph);
				op+= strlen(paragraph);// +3; /** jump the output + =\r\n **/
				out_remaining-= (strlen(paragraph)); // Was +3, updated to fix Outlook problems

				QPD fprintf(stdout, "Soft break (%zd + %d > 76 char) for '%s'\n", 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 fprintf(stdout,"charout='%s', size=%d, pp_remain=%zd result='%s'\n", 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 fprintf(stdout,"Adding paragraph '%s' to output\n", 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;
}


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 fprintf(stderr, "Cannot locate file '%s' for loading and QP encoding (%s)\n", 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 fprintf(stdout,"Error allocating %zd bytes for input buffer\n", in_size);
		return -1;
	}

	out_buffer = malloc( sizeof(char) *out_size *3 +1);
	if (in_buffer == NULL) {
		QPD fprintf(stdout,"Error allocating %zd bytes for output buffer\n", 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 fprintf(stdout,"file %s is loaded, size = %zd\n", fname, in_size);

	qp_encode( out_buffer, out_size, in_buffer, in_size );

	fprintf( stdout, "%s", out_buffer );

	free(in_buffer);
	free(out_buffer);

	return 0;
}