[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Emailing myself pictures to a Maildir; how to extract with script?



On Sat, Sep 11, 2004 at 03:09:26PM -0400, William Ballard wrote:
> I'm emailing myself pics from my cell and procmail puts them into a 
> special maildir.  I'd like to iterate over each message in this maildir, 
> extract the attachments to individual .jpgs, and then delete the 
> message.  (Lazy, done no research yet, but hoping someone can grunt a 
> one word answer).
> 
> Thanks.

Here is something I hacked together when I was doing something
similar. It extracts base64-encoded jpeg attachments from messages.
It doesn't expect more than one attachment, but your problem sounds
like you don't need it to. Compile it, then call it with input and
output filenames, eg.

cd directory/with/messages/in
for x in *; do cleanpic2 $x $x.jpeg; done

-- 
Pigeon

Be kind to pigeons
Get my GPG key here: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x21C61F7F
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

char *do64(char c)
{
   static char list[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
   static char count=0;
   static union 
     {
	unsigned z;
	char s[4];
     } op;
   unsigned x,y;
   
   if (count==0) op.z=0;
   y=0xff;
   for (x=0;x<65;x++) if (c==list[x]) 
     {
	y=x;
	x=65;
     }
   if (y==64) {
      y=0;
   }
   if (y<64) 
     {
	op.z <<= 6;
	op.z |= y;
/*	printf("%02x ",y);*/
	count++;
     }
   if (count==4) 
     {
	op.s[3]=op.s[0];
	op.s[0]=op.s[2];
	op.s[2]=op.s[3];
	op.s[3]=0;
	count=0;
/*	printf("%x ",op.z);
	for (x=0;x<3;x++) printf("%02x ",op.s[x]);
	printf("\n");*/
	return &(op.s[0]);
     }
   else 
     {
	return NULL;
     }
}


int clean(int infd, int outfd, char *name)
{
   int size, x;
   int y=0;
   char *buf, *c, *op;
   
   int gotff=0;
   
   if ((size=lseek(infd, 0, SEEK_END))<0) 
     {
	fprintf(stderr, "%s: Can't seek to end of input file\n",name);
	return -1;
     }
   
   if ((buf=malloc(size+1))==NULL) 
     {
	fprintf(stderr, "%s: Can't allocate %d bytes for buffer\n",name,size);
	return -1;
     }
   
   /* ECCHY ECCHY ECCH */
   buf++;

   lseek(infd, 0, SEEK_SET);
   
   if (read(infd, buf, size)<0) 
     {
	fprintf(stderr, "%s: Error reading input file\n",name);
	size=-1;
     }
   else
     {
	for (x=0,c=buf; x<size; x++,c++) 
        {
	  if (gotff==0) {
	     if ((*(c-1)==0x0a)&&(*c=='/')&&(*(c+1)=='9')&&(*(c+2)=='j')&&(*(c+3)=='/')) y=gotff=1;
	  }	   
	  if (gotff==1) {
	     if ((*c==0x0a)&&(*(c+1)==0x0a)) {
		gotff=0;
		ftruncate(outfd,y);
	     } else {
	         op=do64(*c);
	         if (op!=NULL) {
		    write(outfd, op, 3);
		    y+=3;
		 }
	     }
	  }	  	   
        }
     }
   
   /* See ECCHY ECCHY ECCH */
   buf--;
   free(buf);
   
   return size;
}

int main(int argc, char *argv[])
{
   int infd, outfd;
   char line[256];
   
   if (argc!=3) 
     {
	fprintf(stderr,"%s: input and output filenames required\n",argv[0]);
	exit(1);
     }   
   
   if ((infd=open(argv[1], O_RDONLY))<0) 
     {
	fprintf(stderr,"%s: %s: cannot open for reading\n",argv[0],argv[1]);
	exit(1);
     }
   
   if ((outfd=open(argv[2], O_WRONLY|O_CREAT))<0) 
     {
	fprintf(stderr,"%s: %s: cannot open for writing\n",argv[0],argv[2]);
	exit(1);
     }
   
   if (clean(infd, outfd, argv[0])<0) exit(1);

   close(outfd);
   close(infd);

/* Fudge because it assigns REALLY WEIRD permissions to the output file
 * for no apparent reason - libc bug?? */
	
   snprintf(line, 256, "chmod 664 %s",argv[2]);
   system(line);
	
   exit(0);
}

Attachment: signature.asc
Description: Digital signature


Reply to: