// // This C++ program converts a Netscape Messenger mail folder into multiple // POP files, one POP file per message. If you do not want copies of deleted // messages, then you must compact the folder before using this program. // // This program is protected by US law and international treaty. // Copyright 1999 by David G. Holm, Berrien Springs, Michigan, USA. // All rights reserved. Permission for royalty-free distribute of the // source code and any programs derived from the source code is hereby // granted, provided that the copyright and permission notices remain // in the source code and are not modified in any manner. // #include #include #include #include #include #if defined(_MSC_VER) #define timeb _timeb #define ftime _ftime #endif char make_digit( unsigned long value ) { char digit; if( value > 35 ) digit = '!'; // Out of range. else if( value > 25 ) digit = ( value - 26 ) + '0'; // Numeric digit. else digit = value + 'A'; // Alpha digit. return digit; } char * pop_name( char * name_buf, size_t name_size ) { int try_again = 1; static char check_buf[ 16 ]; if( name_size < 13 ) name_buf[ 0 ] = '\0'; else while( try_again ) { char digit; unsigned long temp; struct timeb tb; struct tm * local_time; ftime( &tb ); local_time = localtime( &tb.time ); // The first two characters are the year, with "AA" representing 1900. name_buf[ 0 ] = make_digit( local_time->tm_year / 36 ); name_buf[ 1 ] = make_digit( local_time->tm_year % 36 ); // The last six characters are formed by combining the month, the day // of the month, the hours, the minutes, the seconds, and the tenths // of seconds into a single value. temp = local_time->tm_mon; temp *= 12; temp += local_time->tm_mday - 1; temp *= 24; temp += local_time->tm_hour; temp *= 60; temp += local_time->tm_min; temp *= 60; temp += local_time->tm_sec; temp *= 10; temp += ( tb.millitm / 100 ) % 10; name_buf[ 2 ] = make_digit( temp / ( 36 * 36 * 36 * 36 * 36 ) ); name_buf[ 3 ] = make_digit( temp / ( 36 * 36 * 36 * 36 ) % 36 ); name_buf[ 4 ] = make_digit( temp / ( 36 * 36 * 36 ) % 36 ); name_buf[ 5 ] = make_digit( ( temp / ( 36 * 36 ) ) % 36 ); name_buf[ 6 ] = make_digit( ( temp / 36 ) % 36 ); name_buf[ 7 ] = make_digit( temp % 36 ); name_buf[ 8 ] = '\0'; if( strcmp( check_buf, name_buf ) ) { // If the new name doesn't match the old name, then the name is good. try_again = 0; // Save the new name as the previous name. strcpy( check_buf, name_buf ); // Add the POP file extension, so that the caller doesn't have to. strcat( name_buf, ".POP" ); } } return name_buf; } #define IN_BUF_MAX 32767 #define PATH_MAX 256 int main( int argc, char * argv[] ) { int rc = 0; char path[ PATH_MAX ]; FILE * in_file; FILE * out_file = NULL; fputs( "\nCopyright 1999 by David G. Holm, Berrien Springs, Michigan, USA.\n", stderr ); if( argc != 3 ) rc = 1; else { static char in_buf[ IN_BUF_MAX + 1 ]; static char name[ 16 ]; char * out_buf; size_t in_size; // Open the Netscape Messenger mail folder file. in_file = fopen( argv[ 1 ], "r" ); if( in_file == NULL ) rc = 2; // Check if the output POP file name buffer might overflow. else if( strlen( argv[ 2 ] ) > PATH_MAX - 14 ) rc = 3; else while( !rc && !feof( in_file ) ) { // Read a line from the Netscape Messenger file // (they all end with a single LF character). fgets( in_buf, IN_BUF_MAX, in_file ); if( in_size ) { // Default to writing exactly what was read. out_buf = in_buf; // But first check for the start of a new message. if( strncmp( in_buf, "From - ", 7 ) == 0 ) { // Display a period for each new message. fprintf( stderr, "." ); // Create a new POP file for each new message. strcpy( path, argv[ 2 ] ); strcat( path, "/" ); strcat( path, pop_name( name, sizeof( name ) ) ); // Close the old POP file, if any. if( out_file ) fclose( out_file ); // Open the new POP file. out_file = fopen( path, "wb" ); if( out_file == NULL ) rc = 4; // Note: Netscape's start of message line does NOT // get written to the new POP file. } else { // Check for Netscape's escaping of "from" text. if( strnicmp( in_buf, ">from", 5 ) == 0) { // Undo Netscape's escaping of "from" text. out_buf++; } // If a POP file was created, then write the current // line of the message to the new POP file. if( out_file ) fputs( out_buf, out_file ); } } } // Close the new POP file, if any, then close the Netscape folder. if( out_file ) fclose( out_file ); fclose( in_file ); } if( rc == 4 ) { fprintf( stderr, "\nError: The destination file could not be created:\n %s\n", path ); } if( rc == 3 ) { fprintf( stderr, "\nError: The destination directory path is too long:\n %s\n", argv[ 2 ] ); } if( rc == 2 ) { fprintf( stderr, "\nError: The source file could not be opened:\n %s\n", argv[ 1 ] ); } if( rc == 1 ) { // Find the start of the actual EXE file name. size_t count, last = 0; for( count = 0; count < strlen( argv[ 0 ] ); count++ ) { switch( argv[ 0 ][ count ] ) { case ':': case '\\': case '/': last = count + 1; } } // Display the correct command line syntax. fprintf( stderr, "\nSyntax: %s Netscape_mail_folder_file POP_file_directory\n\n" "This C++ program converts a Netscape Messenger mail folder into multiple\n" "POP files, one POP file per message. If you do not want copies of deleted\n" "messages, then you must compact the folder before using this program.\n" , &argv[ 0 ][ last ] ); } return rc; }