Skip to content

Commit

Permalink
Switch from raw Win32 to stdio file operations
Browse files Browse the repository at this point in the history
This is mainly to avoid the 1-byte reads which are exceedingly costly when they mean a system call apiece. It also means I can clean up quite a few unnecessary temporary files.
  • Loading branch information
smowton committed Apr 15, 2019
1 parent 1d69e3c commit 77efd9a
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 195 deletions.
27 changes: 11 additions & 16 deletions Source/base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,25 @@ const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678
}


void encode( HANDLE infile, HANDLE outfile, int linesize ) {
void encode( FILE *infile, FILE *outfile, int linesize ) {

unsigned char in[3], out[4];
int len, blocksout = 0;
int byteread, temp;
char new_line[] = {0x0D, 0x0A};

byteread = 1;

while( byteread != 0 ) {
len = 0;
memset( in, 0, sizeof( in ) );
ReadFile( infile, in, 0x03, &byteread, NULL );
len = byteread;
if( len ) {
encodeblock( in, out, len );
WriteFile( outfile, out, 0x04, &temp, NULL );
blocksout++;
}
if( blocksout >= (linesize/4) || byteread == 0 ) {
while( (len = fread(in, 1, 3, infile)) >= 1 ) {
encodeblock( in, out, len );
fwrite(out, 1, 4, outfile);
blocksout++;
if( blocksout >= (linesize/4) ) {
if( blocksout ) {
WriteFile( outfile, new_line, sizeof( new_line ), &temp, NULL );
fwrite(new_line, 1, sizeof(new_line), outfile);
}
blocksout = 0;
}
}

if (blocksout != 0) {
fwrite(new_line, 1, sizeof(new_line), outfile);
}
}
2 changes: 1 addition & 1 deletion Source/base64.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void encodeblock( unsigned char in[3], unsigned char out[4], int len );
//
//***************************************************************************

void encode( HANDLE infile, HANDLE outfile, int linesize );
void encode( FILE *infile, FILE *outfile, int linesize );
//***************************************************************************
// INPUTS:
//
Expand Down
12 changes: 0 additions & 12 deletions Source/increadimail_convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,6 @@ extern "C" {
//
//***************************************************************************

int ReadOneLine(HANDLE infile, char *buffer, int max_line_length);
//***************************************************************************
// INPUTS:
//
// OUTPUTS:
//
// RETURN VALUE:
//
// DESCRIPTION:
//
//***************************************************************************

int FindDatabaseFiles(char *directory_search, char *temp_file_listing);
//***************************************************************************
// INPUTS:
Expand Down
137 changes: 16 additions & 121 deletions Source/incredimail_convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,29 +163,23 @@ char extract_data[1024];

void insert_attachments( char *im_filename, const char *attachments_path, const char *final_email_filename ) {

HANDLE inputfile, outputfile, encoded_file;
HANDLE encode64_input_file, encode64_output_file;
FILE *inputfile, *outputfile;
FILE *encode64_input_file;

DWORD byteswritten;
char string_1[512], string_2[512];
char string_1[512];
char attachment_name[512];
int attachment_length, read_length, read_encoded_length;
int attachment_length;

char temp_path[MAX_CHAR];
char temp_filename[MAX_CHAR];


inputfile = CreateFile(im_filename, GENERIC_READ, 0x0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
outputfile = CreateFile(final_email_filename, GENERIC_WRITE, 0x0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
read_length = 1;

inputfile = fopen(im_filename, "rb");
outputfile = fopen(final_email_filename, "wb");

GetTempPath( sizeof( temp_path ), temp_path );

if( inputfile && outputfile ) {
while( read_length != 0 ) {
memset( string_1, 0, MAX_CHAR );
read_length = ReadOneLine( inputfile, string_1, MAX_CHAR );

while( fgets(string_1, 512, inputfile) ) {
// search for the ATTACHMENT string
if( strncmp( ATTACHMENT, string_1, 34 ) == 0 ) {
// fix the attachment string
Expand All @@ -195,35 +189,18 @@ char temp_filename[MAX_CHAR];
strncat( attachment_name, &string_1[34], attachment_length - 36 );

// encode the attachement
GetTempFileName( temp_path, "att", 0, temp_filename );
encode64_input_file = CreateFile(attachment_name, GENERIC_READ, 0x0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
encode64_output_file = CreateFile(temp_filename, GENERIC_WRITE, 0x0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL );
if( encode64_input_file && encode64_output_file ) {
encode( encode64_input_file, encode64_output_file, 72 );
CloseHandle( encode64_input_file );
CloseHandle( encode64_output_file );

encoded_file = CreateFile(temp_filename, GENERIC_READ, 0x0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( encoded_file ) {
read_encoded_length = 1;
while( read_encoded_length ) {
memset( string_2, 0, MAX_CHAR );
read_encoded_length = ReadOneLine( encoded_file, string_2, MAX_CHAR );
if( outputfile ) {
WriteFile( outputfile, string_2, read_encoded_length, &byteswritten, NULL );
}
}
CloseHandle( encoded_file );
DeleteFile( temp_filename );
}
}
encode64_input_file = fopen(attachment_name, "rb");
if (encode64_input_file) {
encode(encode64_input_file, outputfile, 72);
fclose(encode64_input_file);
}
} else {
WriteFile( outputfile, string_1, read_length, &byteswritten, NULL );
fwrite( string_1, 1, strlen(string_1), outputfile );
}
}
}
CloseHandle( inputfile );
CloseHandle( outputfile );
fclose( inputfile );
fclose( outputfile );
}

enum find_multipart_states {
Expand Down Expand Up @@ -360,88 +337,6 @@ char temp_version[5];

}

int ReadOneLine( HANDLE infile, char *buffer, int max_line_length ) {
DWORD byteread;
char byte;
int index, end = 0;

// initialize variables
byteread = 1;
end = 0;
index = 0;

// loop will end if:
// (1) there are no more bytes to read in the file
// (2) a DOS/Windows line return is found
// (3) max line length in the buffer
while( byteread != 0 && !end && index < max_line_length ) {
ReadFile( infile, &byte, 0x01, &byteread, NULL );
if( byteread != 0 ) {
buffer[index] = byte;
index++;
// test if it is line feed
if( byte == 0x0D ) {
ReadFile( infile, &byte, 0x01, &byteread, NULL );
if( byte == 0x0A && byteread != 0 ) {
buffer[index] = byte;
index++;
end = 1;
}
}
}
}

return index;
}

int FindDatabaseFiles( char *directory_search, char *temp_file_listing ) {
WIN32_FIND_DATA FindFileData;
HANDLE hFind, list_output;

char database_filename[MAX_CHAR];
char temp_path[MAX_CHAR];
char temp_filename[MAX_CHAR];
char temp_string[MAX_CHAR];

DWORD result_create_temp, dummy;

int total_count = 1;

ZeroMemory( &database_filename, sizeof( database_filename ) );
ZeroMemory( &temp_path, sizeof( temp_path ) );
ZeroMemory( &temp_filename, sizeof( temp_filename ) );
ZeroMemory( &temp_string, sizeof( temp_string ) );

strcpy( database_filename, directory_search );
strcat( database_filename, "\\*.imm" );

// Get temp windows path
result_create_temp = GetTempPath( sizeof( temp_path ), temp_path );
GetTempFileName( temp_path, "lst", 0, temp_filename );

list_output = CreateFile(temp_filename, GENERIC_WRITE, 0x0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );

hFind = FindFirstFile(database_filename, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
return -1;

sprintf(temp_string, "%s\\%s%c%c", directory_search, FindFileData.cFileName, 0x0D, 0x0A );
WriteFile( list_output, temp_string, (DWORD) strlen( temp_string ), &dummy, NULL );

while( FindNextFile(hFind, &FindFileData) != 0 ) {
sprintf(temp_string, "%s\\%s%c%c", directory_search, FindFileData.cFileName, 0x0D, 0x0A );
WriteFile( list_output, temp_string, (DWORD) strlen( temp_string ), &dummy, NULL );
total_count++;
}

strcpy( temp_file_listing, temp_filename );

FindClose( hFind );
CloseHandle( list_output );

return total_count;
}

static int testimdb(const char* filename) {

struct _stat statbuf;
Expand Down
Loading

0 comments on commit 77efd9a

Please sign in to comment.