#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 "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", *p);
charout_size = 3;
} else {
/** encode verbatim **/
snprintf( charout, sizeof(charout), "%c", *p);
charout_size = 1;
}
if (current_line_length +charout_size >= 76) {
//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) +3);
QPD fprintf(stdout, "Soft break (%d + %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=%d result='%s'\n", charout, charout_size, pp_remaining, paragraph);
pp += charout_size;
pp_remaining -= charout_size;
p++;
current_line_length++;
} /** 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 )
{
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 %d 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 %d bytes for output buffer\n", out_size);
return -1;
}
f = fopen( fname, "r" );
fread( in_buffer, 1, in_size, f );
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 = %d\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;
}
syntax highlighted by Code2HTML, v. 0.9.1