/* * Read HandyCar data file * spd@daphne.cps.unizar.es * Version: 0.1.1, Mon May 14 22:22:40 CEST 2012 */ /* * This program will dump entries from your Car.dat file (Symbian HandyCar) * * Known limitations: * - Can't deal with partial records. Imcompete records will end with "..." * - Can't tell if Fuel repost is Partial of Full * - Can't tell if Usage is Personal or Business * - Assumes a fixed lenght file header (true for my sample file) */ /* * Output * * Fuel: * F: Days Date Odometer Gas Cost Full=1 Note ? * Trip: * T: Days Date Destination Odom. ini Odom. end Note * (Trip will end with "..." if incomplete record) * Expense: * E: Days Date Concept Odometer Cost Note * */ #include #include #include #include #include #include #include #include #include #if defined(__i386__) || defined (_M_IX86) || defined (__osf__) # define LITTLEENDIAN #else # define BIGENDIAN #endif #define swap_word(a) ( ((a) << 24) | \ (((a) << 8) & 0x00ff0000) | \ (((a) >> 8) & 0x0000ff00) | \ ((unsigned long)(a) >>24) ) #define swap_half(a) ( ((a & 0xff) << 8) | ((unsigned short)(a) >> 8) ) #ifdef BIGENDIAN # define SWAP_WORD(a) { a = swap_word(a); } # define SWAP_HALF(a) { a = swap_half(a); } #else # define SWAP_WORD(a) # define SWAP_HALF(a) #endif void readstring(int i, int n); #define MAXNAME 256 void readstring(int i, int n) { unsigned char c; if ( n == 0 ) return; n *= 2; for (c=0x00; read(i,&c,1); ) { if ( c != 0xff ) { if ( c != 0x00 ) write(1,&c,1); if ( --n == 0) break; } } } int main(int argc, char **argv) { #ifndef BS #define BS 512 #endif off_t pos; int i; int incomplete=0; int invaliddate=0; unsigned char buffer[BS]; struct stat sbp; int n; unsigned char c; short rc=0; unsigned long l; unsigned short s, date; time_t timer; struct tm *lt; char str[256]; char *exp[]={ "Car wash", "Parking", "Service", "Oil change", "Tyres rotate", "Taxes", "Other" }; assert (sizeof(long)==4); assert (sizeof(short)==2); if ( lstat(argv[1],&sbp)==-1) { perror("stat"); return 1; } if ( -1 == ( i = open( argv[1], O_RDONLY))) { perror("open"); return 1; } read(i,buffer,256); read(i,buffer,256); read(i,buffer,64); while (read(i,&buffer[rc],1)) { rc++; if ( rc == 4 ) { if (( buffer[0] != 0xff ) && (buffer[0] != 0x00 )) { fprintf(stderr, "WARNING! incomplete record detected\n"); incomplete=1; } else { incomplete=0; } read(i,&s,2); read(i,buffer,2); if ( buffer[1]==0xab) { /* Date */ date=s; SWAP_HALF(date); invaliddate = ( date < 3560 ) ; timer=(date * 24 * 3600 + 10); lt=localtime(&timer); sprintf(str,"%d\t%0.2d/%0.2d/%d", date, lt->tm_mday, lt->tm_mon+1, lt->tm_year+1900 ); printf("T:\t%s\t", str);fflush (stdout); /* Destination */ n=(unsigned char) buffer[0]; readstring(i,n); /* Start */ read ( i, &l, sizeof(l)); if ( l == -1 ) { read ( i, &l, sizeof(l)); } SWAP_WORD(l); printf("\t%d", l);fflush (stdout); /* Finish */ read ( i, &l, sizeof(l)); SWAP_WORD(l); printf("\t%d\t", l);fflush (stdout); /* Note */ read(i,buffer,2); n=(unsigned char) buffer[1]; if (incomplete) { /* pos=tell(i);*/ pos=lseek(i, 0, SEEK_CUR); pos %= 64; pos = (64 - pos)/2; if ( n > pos ) n = pos; } readstring(i,n); if (incomplete) printf("..."); fflush (stdout); write(1,"\n",1); rc=0; } else { read(i,buffer+2,2); /* Date */ date=s; SWAP_HALF(date); invaliddate = ( date < 3560 ) ; timer=(date * 24 * 3600 + 10); lt=localtime(&timer); sprintf(str,"%d\t%0.2d/%0.2d/%d", date, lt->tm_mday, lt->tm_mon+1, lt->tm_year+1900 ); /* Odometer */ l=*(unsigned long *) buffer; SWAP_WORD(l); read(i,buffer,2); if (( buffer[0] <= 6 ) && ( buffer[1] != 0xab )) { printf("E:\t%s\t%s\t%d\t", str, exp[buffer[0]], l); fflush(stdout); n=(unsigned char) buffer[1]; readstring(i,n); printf("\t");fflush (stdout); read(i,buffer,2); n=(unsigned char) buffer[1]; readstring(i,n); if (incomplete) printf("..."); fflush (stdout); write(1,"\n",1); rc=0; } else { if ( invaliddate ) { printf("X:\t%s\t%d\t", str, l); fflush(stdout); } else { /* Fuel? */ printf("F:\t%s\t%d\t", str, l); fflush(stdout); n=(unsigned char) buffer[0]; readstring(i,n); printf("\t");fflush (stdout); read(i,buffer,2); n=(unsigned char) buffer[0]; readstring(i,n); read(i,&s,2); SWAP_HALF(s) printf("\t%d\t", s);fflush(stdout); read(i,buffer,2); n=(unsigned char) buffer[0]; readstring(i,n); read(i,&s,2); SWAP_HALF(s) printf("\t%d", s);fflush(stdout); } if (incomplete) printf("..."); fflush (stdout); write(1,"\n",1); rc=0; } } /* pos=tell(i);*/ pos=lseek(i, 0, SEEK_CUR); /* printf("POS %d\n", pos); fflush(stdout);*/ pos %= 64; if ( pos != 0 ) { read(i,buffer,64-pos); } } } close(i); }