You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

358 lines
8.4 KiB

/*
* $Id: pilot-foto-treo650.c,v 1.3 2009/06/04 13:32:30 desrod Exp $
*
* pilot-650foto.c: Grab photos and video off a Treo 650 camera phone.
*
* (c) 2004, Matthew Allum <mallum@o-hand.com>
* (c) 2006, Angus Ainslie <angusa@deltatee.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include "pi-file.h"
#include "pi-header.h"
#include "pi-dlp.h"
#include "pi-socket.h"
#include "pi-userland.h"
#define MEDIA_PATH "/Photos & Videos"
#define MEDIA_VOLUME 1
static int
pi_file_retrieve_VFS(const int fd, const int socket, FileRef file, const char *rpath )
{
int rpathlen = vfsMAXFILENAME;
long attributes;
pi_buffer_t *buffer;
ssize_t readsize,writesize;
int filesize;
int original_filesize;
int written_so_far;
pi_progress_t progress;
enum
{
bad_parameters=-1,
cancel=-2,
bad_vfs_path=-3,
bad_local_file=-4,
insufficient_space=-5,
internal_=-6
};
rpathlen=strlen(rpath);
if (dlp_VFSFileGetAttributes(socket,file,&attributes) < 0)
{
fprintf(stderr," Could not get attributes of VFS file.\n");
(void) dlp_VFSFileClose(socket,file);
return bad_vfs_path;
}
if (attributes & vfsFileAttrDirectory)
{
/* Clear case for later feature. */
fprintf(stderr," Cannot retrieve a directory.\n");
dlp_VFSFileClose(socket,file);
return bad_vfs_path;
}
dlp_VFSFileSize(socket,file,&filesize);
original_filesize = filesize;
memset(&progress, 0, sizeof(progress));
progress.type = PI_PROGRESS_RECEIVE_VFS;
progress.data.vfs.path = (char *)rpath;
progress.data.vfs.total_bytes = filesize;
#define FBUFSIZ 65536
buffer = pi_buffer_new(FBUFSIZ);
readsize = 0;
written_so_far = 0;
while ((filesize > 0) && (readsize >= 0))
{
int offset;
pi_buffer_clear(buffer);
readsize = dlp_VFSFileRead(socket,file,buffer,
( filesize > FBUFSIZ ? FBUFSIZ : filesize));
/*f printf(stderr,"* Read %ld bytes.\n",readsize); */
if (readsize <= 0) break;
filesize -= readsize;
offset = 0;
while (readsize > 0)
{
writesize = write(fd,buffer->data+offset,readsize);
/* fprintf(stderr,"* Wrote %ld bytes.\n",writesize); */
if (writesize < 0)
{
fprintf(stderr,"Error while writing file.\n");
goto cleanup;
}
written_so_far += writesize;
progress.transferred_bytes += writesize;
if ((filesize > 0) || (readsize > 0))
{
/* if (f && (f(socket,&progress) == PI_TRANSFER_STOP)) {
written_so_far = cancel;
pi_set_error(socket,PI_ERR_FILE_ABORTED);
goto cleanup;
}*/
}
readsize -= writesize;
offset += writesize;
}
}
cleanup:
pi_buffer_free(buffer);
#undef FBUFSIZ
dlp_VFSFileClose(socket,file);
return written_so_far;
}
/***********************************************************************
*
* Function: print_fileinfo
*
* Summary: Show information about the given @p file (which is
* assumed to have VFS path @p path).
*
* Parameters: path --> path to file in VFS volume.
* file --> FileRef for already opened file.
*
* Returns: Nothing
*
***********************************************************************/
static void
print_fileinfo(int sd, const char *path, FileRef file)
{
int size;
time_t date;
char *s;
(void) dlp_VFSFileSize(sd,file,&size);
(void) dlp_VFSFileGetDate(sd,file,vfsFileDateModified,&date);
s = ctime(&date);
s[24]=0;
printf(" %8d %s %s\n",size,s,path);
}
/***********************************************************************
*
* Function: print_dir
*
* Summary: Output all the files in the MEDIA_DIR
*
* Parameters: volume --> volume ref number.
* path --> path to directory.
* dir --> file ref to already opened dir.
*
* Returns: Nothing
*
***********************************************************************/
static void
dump_dir(int sd, long volume, const char *path, FileRef dir)
{
unsigned long it = 0;
int max = 64;
struct VFSDirInfo infos[64];
int i;
FileRef file;
char buf[vfsMAXFILENAME];
int pathlen = strlen(path);
int fd;
char *index;
/* Set up buf so it contains path with trailing / and
buflen points to the terminating NUL. */
if (pathlen<1)
{
printf(" NULL path.\n");
return;
}
memset(buf,0,vfsMAXFILENAME);
strncpy(buf,path,vfsMAXFILENAME-1);
if (buf[pathlen-1] != '/')
{
buf[pathlen]='/';
pathlen++;
}
if (pathlen>vfsMAXFILENAME-2)
{
printf(" Path too long.\n");
return;
}
while (dlp_VFSDirEntryEnumerate(sd,dir,&it,&max,infos) >= 0)
{
if (max<1) break;
for (i = 0; i<max; i++)
{
memset(buf+pathlen,0,vfsMAXFILENAME-pathlen);
strncpy(buf+pathlen,infos[i].name,vfsMAXFILENAME-pathlen);
if (dlp_VFSFileOpen(sd,volume,buf,dlpVFSOpenRead,&file) < 0)
{
printf(" %s: No such file or directory.\n",infos[i].name);
}
else
{
if( index = rindex( infos[i].name, '.' ))
{
// printf( "index: %s %d strlen %d\n", infos[i].name, index, strlen( infos[i].name ) );
if(( index + 4 ) == (infos[i].name + strlen( infos[i].name )))
{
print_fileinfo(sd,infos[i].name, file);
if( !strcmp( index,".jpg" ) || !strcmp( index,".3gp" ))
{
fd = open( infos[i].name, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
pi_file_retrieve_VFS( fd, sd, file, buf );
close(fd);
}
}
}
dlp_VFSFileClose(sd,file);
}
}
}
}
int main(int argc, const char *argv[])
{
int sd = -1;
int c;
int ret = 1;
FileRef file;
unsigned long attributes;
enum { mode_none, mode_write = 257 } run_mode = mode_none;
struct poptOption options[] =
{
USERLAND_RESERVED_OPTIONS
{"write",'w', POPT_ARG_NONE,NULL,mode_write,"Write data"},
POPT_TABLEEND
};
poptContext po = poptGetContext("pilot-650foto",argc,argv,options,0);
poptSetOtherOptionHelp(po,"\n\n"
" Copies Treo 650 photos and videos to current directory\n");
if ((argc < 2))
{
poptPrintUsage(po,stderr,0);
return 1;
}
while ((c = poptGetNextOpt(po)) >= 0)
{
switch(c)
{
case mode_write :
if (run_mode == mode_none)
{
run_mode = c;
}
else
{
if (c != run_mode)
{
fprintf(stderr," ERROR: Specify exactly one of -w.\n");
return 1;
}
}
break;
default:
fprintf(stderr," ERROR: Unhandled option %d.\n",c);
return 1;
}
}
if (c < -1)
{
plu_badoption(po,c);
}
if (mode_none == run_mode)
{
fprintf(stderr," ERROR: Specify --write (-w) to output data.\n");
return 1;
}
if ((sd = plu_connect()) < 0)
{
return 1;
}
if (dlp_VFSFileOpen(sd,MEDIA_VOLUME,MEDIA_PATH,dlpVFSOpenRead,&file) < 0)
{
printf(" %s: No such file or directory.\n",MEDIA_PATH);
goto cleanup;
}
if (dlp_VFSFileGetAttributes(sd,file,&attributes) < 0)
{
printf(" %s: Cannot get attributes.\n",MEDIA_PATH);
goto cleanup;
}
if (vfsFileAttrDirectory == (attributes & vfsFileAttrDirectory))
{
/* directory */
dump_dir(sd,MEDIA_VOLUME,MEDIA_PATH,file);
}
ret=0;
cleanup:
if( file >= 0 )
(void) dlp_VFSFileClose(sd,file);
if (sd >= 0)
{
dlp_EndOfSync(sd, 0);
pi_close(sd);
}
return ret;
}
/* vi: set ts=8 sw=4 sts=4 noexpandtab: cin */
/* ex: set tabstop=4 expandtab: */
/* Local Variables: */
/* indent-tabs-mode: t */
/* c-basic-offset: 8 */
/* End: */