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;
}
|