#include <stdio.h>
#include <stdlib.h>

#include "types.h"
#include "ftn.h"

int main( int argc, char **argv )
{
    FILE *pktf, *msgf;
    byte *buf;			/* buf for pkt */
    long file_length;		/* pkt length */
    ftn_pkt_header *pkt_header;	/* pkt header */
    ftn_message_header msgh;	/* msg header */
    long pos;			/* pos at src pkt */
    char password[9];		/* pkt password */
    int count;			/* counter when copying from, to, subj */
    int msgn;			/* saved msg number */
    char msgname[500];		/* msg file name //* */
    
    if( argc != 2 ) {
        printf( "pktunpack packet\n  unpacks to packet.*.msg\n" );
	return 1;
    }
    pktf=fopen( argv[1], "rb" );
    if( !pktf ) {
        perror( "cannot open packet" );
	return 2;
    }
    fseek( pktf, 0, SEEK_END );
    file_length=ftell( pktf );
    fseek( pktf, 0, SEEK_SET );

    if( file_length < 58 ) {
        printf( "file too short\n" );
	return 3;
    }    
    
    buf=malloc( file_length );
    if( !buf ) {
        printf( "no enough memory\n" );
	return 4;
    }
    
    printf( "loading packet (%d bytes)\n", file_length );
    if( fread( buf, file_length, 1, pktf ) != 1 ) {
        perror( "read failed" );
	return 5;
    }
    fclose( pktf );
    
    pkt_header=(void *)buf;
    if( pkt_header->version != 2 ) {
	printf( "invalid PKT version\n" );
	return 6;
    }
    
    printf( "From: %d:%d/%d.%d  ", pkt_header->origZone, pkt_header->origNet, pkt_header->origNode, pkt_header->origPoint );
    printf( "To: %d:%d/%d.%d  ", pkt_header->destZone, pkt_header->destNet, pkt_header->destNode, pkt_header->destPoint );
    strncpy( password, pkt_header->password, 8 );
    password[8]=0;
    printf( "Password: %s\n", password );
    
    pos=58;
    msgn=1;
    do {
	printf( "At %08X: ", pos );
	/* pos at msg begin */
	if( pos+2 > file_length ) { printf( "unexpected end of file\n" ); return 7; }
	if( *(word *)(buf+pos) == 0 ) { 
	    printf( "end of packet\n" );
	    if( file_length > pos+2 ) {
		printf( "there are some bytes after logical end at %08X\n", pos+2 );
		/* save less of pkt and delete */
		return 8;
	    }
	    /* here delete source pkt */
	    return 0;
	}
	if( *(word *)(buf+pos) != 2 ) {
	    printf( "invalid msg header\n" );
	    /* save less of pkt and delete */
pos++; continue;
	    return 9;
	}
	if( pos+34 > file_length ) { printf( "unexpected end of file\n" ); return 10; }
	msgh.origNode=*(word *)(buf+pos+2);
	msgh.destNode=*(word *)(buf+pos+4);
	msgh.origNet=*(word *)(buf+pos+6);
	msgh.destNet=*(word *)(buf+pos+8);
	msgh.attr=*(word *)(buf+pos+10);
	msgh.cost=*(word *)(buf+pos+12);
	memcpy( msgh.dateTime, buf+pos+14, 20 );
	msgh.timesRead=0;
	msgh.destZone=0;
	msgh.origZone=0;
	msgh.destPoint=0;
	msgh.origPoint=0;
	msgh.replyTo=0;
	msgh.nextReply=0;
	
	pos+=34; /* pos at toName */
	count=0;
	while( count<36 ) {
	    if( pos == file_length ) { printf( "unexpected end of file\n" ); return 11; }
	    if( (msgh.toName[count++]=*(buf+pos++)) == 0 ) break;
	}
	while( count<36 ) {
	    msgh.toName[count++]=0;
	}
	
	/* pos at fromName */
	count=0;
	while( count<36 ) {
	    if( pos == file_length ) { printf( "unexpected end of file\n" ); return 12; }
	    if( (msgh.fromName[count++]=*(buf+pos++)) == 0 ) break;
	}
	while( count<36 ) {
	    msgh.fromName[count++]=0;
	}
	
	/* pos at subject */
	count=0;
	while( count<72 ) {
	    if( pos == file_length ) { printf( "unexpected end of file\n" ); return 13; }
	    if( (msgh.subject[count++]=*(buf+pos++)) == 0 ) break;
	}
	while( count<72 ) {
	    msgh.subject[count++]=0;
	}
	
	/* pos at start of body */
	sprintf( msgname, "%s-%d.msg", argv[1], msgn );
	printf( "Writing %s\n", msgname );
	msgf=fopen( msgname, "wb" );
	fwrite( &msgh, sizeof msgh, 1, msgf );
	for( ; ; ) {
	    if( pos == file_length ) { printf( "unexpected end of file\n" ); return 14; }
	    fwrite( buf+pos, 1, 1, msgf );
	    if( *(buf+pos++) == 0 ) {
	    /* end only if EOF or next message detected afterward */
		if( (pos+2) == file_length ) break; /* EOF */
		if( ( (pos+34) < file_length ) && ( *(word *)(buf+pos) == 2 ) ) break; /* more MSG */
	    }
	}
	fclose( msgf );
	msgn++;
	
	printf( "Message completed\n" );
	
    } while( 1 );
    
    free( buf );
    return 0;
}
