On Tue, 8 Aug 2006, David Eriksson wrote:

Thanks for the kind words!

I got it running one step at a time, and had the advantage of using a rather
old device. Toughest part was finding the useful packages in the Ubuntu
repository. ;-)

[...]
Based upon pls and pcp I managed to build myself a small fetch-updated-
documents tool that also converts from Pocket Word to RTF.
(I'm just changing the header from {\pwd2 to {\rtf1, but it works so that
I can finish the RTFs with OpenOffice.)

See also http://synce.sourceforge.net/synce/task_pwi.php and
http://www.synce.org/index.php/ISF is probably used for the
hand-drawings.

That's not what I needed. I just wanted to convert the ".pwd" files to ".rtf" and that's just replacing the reader as mentioned above. ".pwi" is not important to me.


Please keep us posted with your progress!

I've done a bit cleaning up on the code and made some features optional.
The result is included as an attachment. It's not intended to be suitable
for a full backup, rather an one-way substitute for MS's synchonisation
folder.


Once that's done, I was thinking about accessing the Pocket Outlook Inbox
ActiveSync folders via rra. Playing around with the rra-tools, I managed
[...]
a resource on how to interpret the binary data around it? It doesn't
matter, if it's a format description or some sourcecode.
[...]
If you really want to dig into this, I suggest you look att Microsoft's
MAPI (Messaging Application Programming Interface) because it's quite
probable that the data transmitted via RRAC is a serialization of the
data used by the IMessage et.al COM objects.

Actually rra-decode, which I 'discovered' five minutes after my first post,
did me a LOT of favors. Only thing it can't handle are "Multi Strings",
they are shown as blobs. But the format is simple (same is used in the
registry):
"String1\0"
"String2\0"
[..some more..]
"\0\0" <- endmarker

Most other stuff should be solveable, since only very few 'magic' numbers
are used. Biggest question to me right now is: how is stored in which folder
(deleted, sent, outbox, inbox) the message belongs?

As far as I'm concerned, the final result of these efforts are two small tools:
- One that pulls out the messages from Pocket Outlook's Outbox in a format
  that can be forwarded to an smtp server, or if that's easier to provide,
  sends them out themself.
- One that stuffs /var/spool/mail/$USER into Pocket Outlook's Inbox.
Of cause there are some problems to solve, not only CE related ones. For
example, I don't want to access the mailfile in a raw mode, but with a
library that helps me dissolving that large text file.

For analysing the Format of the messages, I'll put up a case where all four
folders of PO's "ActiveSync" will contain several messages, dump these
and put it up somewhere (maybe the wiki?) for discussion.

Anyway, bedtime now!
SvOlli
--
|  _______       |
| (  /\          | Welcome to the great republic. Guess I sould show you round.
|__)v\/lli a.k.a.| Where once I was a king and now I am a clown.
|Sven Oliver Moll|   -- ABC, "King Without A Crown"
#include <rapi.h>
#include <synce_log.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

char *opt_devpath = NULL;
RapiConnection* connection = NULL;
const char *progname = NULL;
int opt_verbose = 0;
BOOL opt_rtfconv = false;

typedef struct direntry_s direntry_t;
struct direntry_s {
   direntry_t *next;
   long attributes;
   long size;
   short filename[MAX_PATH];
};

static void show_usage(const char* name)
{
   fprintf(stderr,
      "Syntax:\n"
      "\n"
      "\t%s [-d LEVEL] [-p DEVPATH] [-r] [-t DIRECTORY] [-v[v]] [-h] \\\n"
      "\t             FILES_ON_CE\n"
      "\n"
      "\t-d LEVEL     Set debug log level\n"
      "\t                 0 - No logging (default)\n"
      "\t                 1 - Errors only\n"
      "\t                 2 - Errors and warnings\n"
      "\t                 3 - Everything\n"
      "\t-h           Show this help message\n"
      "\t-p DEVPATH   Device path\n"
      "\t-r           turn on lame Pocket Word to Rich Text Format converion\n"
      "\t-t DIRECTORY Target directory\n"
      "\t-v           opt_verbose: show files (once) and bytes copied (twice)\n"
      "\n"
      "\tFILES_ON_CE  Full path to files on CE device\n"
      "\t             (\"*\" allowed, directories are ignored)\n"
      "\n",
      name);
}


static bool handle_parameters(int argc, char** argv)
{
   int c;
   int log_level = SYNCE_LOG_LEVEL_LOWEST;

   while ((c = getopt(argc, argv, "d:hp:rt:v")) != -1)
   {
      switch (c)
      {
         case 'd':
            log_level = atoi(optarg);
            break;

         case 'p':
            opt_devpath = optarg;
            break;

         case 'r':
            opt_rtfconv = true;
            break;

         case 't':
            if( chdir( optarg ) )
            {
               fprintf( stderr, "couldn't change to directory %s: %s\n",
                        optarg, strerror(errno) );
               return false;
            }
            break;

         case 'v':
            opt_verbose++;
            break;

         case 'h':
         default:
            show_usage(argv[0]);
            return false;
      }
   }

   synce_log_set_level(log_level);

   return true;
}


void scel_exit()
{
   CeRapiUninit();
   rapi_connection_destroy(connection);
}

HRESULT scel_connect()
{
   HRESULT hr;
   
   if( atexit(scel_exit) )
   {
      fprintf(stderr, "%s: Could not register exit-function\n", progname);
      exit(1);
   }
   
   if( (connection = rapi_connection_from_path(opt_devpath)) == NULL )
   {
      fprintf(stderr, "%s: Could not find configuration at path '%s'\n", progname,
              opt_devpath?opt_devpath:"(Default)");
      exit(1);
   }
   rapi_connection_select(connection);
   hr = CeRapiInit();
   if( FAILED(hr) )
   {
      fprintf(stderr, "%s: Unable to initialize RAPI: %s\n", progname,
              synce_strerror(hr));
      exit(1);
   }
}

void scel_read( LPWSTR wpath, LPWSTR wfilename, DWORD size )
{
   WCHAR wfullname[MAX_PATH];
   wstrcpy(wfullname, wpath);
   wstr_append(wfullname, wfilename, MAX_PATH);
   HANDLE handle;
   int fd;
   char *filename;
   char *ext;
   void *buffer;
   DWORD accessed;
   DWORD chunk = 64 * 1024;
   DWORD done = 0;
   BOOL result;
   char *pwd2 = "{\\pwd2";
   char *rtf1 = "{\\rtf1";
   char *pwd  = ".pwd";
   char *rtf  = ".rtf";
   BOOL pwd2rtf = false;
   
   filename = wstr_to_ascii( wfilename );
   
   if( opt_rtfconv )
   {
      ext = filename + strlen( filename ) - 4;
      if( !strcmp( ext, pwd ) )
      {
	 strcpy( ext, rtf );
	 pwd2rtf = true;
      }
   }
   
   handle = CeCreateFile( wfullname, GENERIC_READ, 0, NULL,
                          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
   
   if (handle == INVALID_HANDLE_VALUE)
   {
      synce_error("Failed to open remote file '%s': %s", filename,
                    synce_strerror(CeGetLastError()));
      return;
   }
   
   fd = open( filename, O_WRONLY | O_CREAT | O_TRUNC, 0666 );
   
   buffer = malloc( chunk );
   
   while( done < size )
   {
      result = CeReadFile( handle, buffer, chunk, &accessed, NULL );
      if( pwd2rtf && (done == 0) )
      {
         if( !strncmp( buffer, pwd2, strlen(pwd2) ) )
         {
            memcpy( buffer, rtf1, strlen(rtf1) );
         }
      }
      write( fd, buffer, accessed );
      done += accessed;
      if( opt_verbose >= 2 )
      {
         printf( "%10d\r", done );
      }
      fflush( stdout );
   }
   
   free( buffer );
   close(fd);
   CeCloseHandle( handle );
}


void scel_action( LPWSTR wpath, CE_FIND_DATA *entry )
{
   if( !(entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
   {
      if( opt_verbose >= 1 )
      {
	 char *path = wstr_to_current(wpath);
	 char *filename = wstr_to_current( entry->cFileName );
	 
         printf( "\"%s%s\": %d bytes\n", path, filename, entry->nFileSizeLow );
	 
	 free(path);
	 free(filename);
      }
      scel_read( wpath, entry->cFileName, entry->nFileSizeLow );
   }
}


int main( int argc, char *argv[] )
{
   HRESULT hr;
   BOOL result;
   DWORD find_count = 0;
   CE_FIND_DATA* find_data = NULL;
   DWORD fc;
   long ac;
   LPWSTR wpath;
   WCHAR *wc, *lws;

   synce_log_set_level( SYNCE_LOG_LEVEL_LOWEST );
   progname = argv[0];

   if (!handle_parameters(argc, argv))
   {
      exit(1);
   }
   
   hr = scel_connect();
   
   for( ac = optind; ac < argc; ac++)
   {
      wpath = wstr_from_ascii( argv[ac] );
      
      result = CeFindAllFiles( wpath, 
                               FAF_ATTRIB_NO_HIDDEN | 
                               FAF_NO_HIDDEN_SYS_ROMMODULES |
                               FAF_ATTRIBUTES |
                               FAF_CREATION_TIME |
                               FAF_LASTACCESS_TIME |
                               FAF_LASTWRITE_TIME |
                               FAF_SIZE_HIGH |
                               FAF_SIZE_LOW |
                               FAF_OID |
                               FAF_NAME,
                               &find_count,
                               &find_data );
      
      for( wc = wpath; *wc; wc++)
      {
         if( *wc == '/' ) lws = wc;
      }
      *(lws+1) = '\0';
      
      if( result )
      {
         for( fc = 0; fc < find_count; fc++ )
         {
            scel_action( wpath, find_data + fc );
         }
      }
      
      CeRapiFreeBuffer( find_data );
   }
   return 0;
}
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Synce-devel mailing list
Synce-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/synce-devel

Reply via email to