help-gnu-emacs
[Top][All Lists]
Advanced

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

Re: reading mail with emacs


From: visaris tds.net
Subject: Re: reading mail with emacs
Date: Wed, 13 Aug 2014 21:26:48 -0400

Sorry to spam everyone... its late and I', tired...

In main it should be

if (argc^5) goto usage;


On Wed, Aug 13, 2014 at 9:14 PM, visaris tds.net <visaris@tds.net> wrote:

> I managed to throw together some c code that does the quick-and-dirty
> (with my mail at least).  Here it is in case anyone finds it useful...
>
> #include <stdio.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <dirent.h>
> #include <string.h>
> #include <sys/mman.h>
> #include <unistd.h>
>
> long   PageSize,Start,End,Count,Debug;
> char  *Path,*Address,*Date;
> off_t  H_size, B_size;
>
> char *found(char *p, char t, int d, long l) // string, target, delta, count
> {
>   while (l-- > 0){
>     if (*p == t) return p;
>     p = p+d;
>   }
>   return NULL;
> }
>
> char *locate(char *p, char *t, int d, long l) // string, target, delta,
> count
> {
>   char *q;
>
>   while (*t){
>     if ((q = found(p,*t,d,l))){
>       if (*++t){
>     l -= 1+ ((d>0)? (q-p)/d: -(p-q)/d);
>     p  = q+d;
>     continue;
>       }
>       return q;
>     }
>     return NULL;
>   }
>   return NULL;
> }
>
> char *find(char *p, char *t, long l) // string, target, bound
> {
>   char *q,*r;
>
>   if (strlen(t) < 2) return locate(p,t,1,l);
>
>   while ((q = found(p,*t,1,l))){
>     if (r = find(q+1,t+1,l-(q-p)-1)){
>       if (*t == r[-1]) return r-1;
>       l -= r-p;
>       p  = r;
>       continue;
>     }
>     return NULL;
>   }
>   return NULL;
> }
>
> long address(char *p)
> {
>   char *s,*e;  long i = H_size;
>
>   Address = NULL;
>   if ((s = locate(p,"\n\n",1,i))){
>     if (*++s == '<'){
>       i -= s-p;
>       if ((e = found(s,'\n',1,i))){
>     if (*--e == '>'){
>       if (e-s > 1){
>         Address = ++s;
>         return e-s;
>       }
>     }
>       }
>     }
>   }
>   return 0;
> }
>
> int date(char *p)
> {
>   static char buf[512];
>   char *s,*e,d[64],n[64],m[64],y[64],t[64],z[64];  long i = H_size;
>
>   Date = NULL;
>   if ((s = find(p,"Date: ",i))){
>     i -= s-p;
>     if ((e = found(s,'\n',1,i))&&(e-s < 64)){
>       strncpy(buf,s,63); buf[63] = 0;
>       if (6 == sscanf(buf,"Date: %s %s %s %s %s %s",d,n,m,y,t,z)){
>     if ((s = index(d,','))) *s = 0;
>     sprintf(buf," %s %s %s %s %s\n",d,m,n,t,y);
>     if (strlen(buf) < 64){
>       Date = buf;
>       return 1;
>     }
>       }
>     }
>   }
>   return 0;
> }
>
> void dump(char *p, char *t, char *r)
> {
>   char *s,*e;  long i = H_size;
>
>   if ((s = find(p,t,i))){
>     if ((e = found(s,'\n',1,i))){
>       if (r){
>     s += strlen(t);
>     printf("%s",r);
>       }
>       do putchar(*s); while (s++ < e);
>     }
>   }
> }
>
> void content_type(char *p)
> {
>   char *s,*e;  long i = H_size;
>
>   if ((s = find(p,"Content-Type: ",i))){
>     if ((e = found(s,'\n',1,i))){
>       do putchar(*s); while (s++ < e);
>       s = e+1;
>       while (*++e) if (*e == '\n') break;
>       if ((*e)&&(s = find(s,"boundary",e-s))){
>     putchar('\t');
>     do putchar(*s); while (s++ < e);
>       }
>     }
>   }
> }
>
> void user_agent(char *p)
> {
>   char *s,*e;  long i = H_size;
>
>   printf("User-Agent: (%ld) ", Count);
>   if ((s = find(p,"User-Agent: ",i))){
>     if ((e = found(s,'\n',1,i))){
>       s += 12; e--;
>       do putchar(*s); while (s++ < e);
>     }
>   }
>   putchar('\n');
> }
>
> size_t head(char *h)
> {
>   long i,j;
>
>   if (Debug){
>     for (i = 0; i < H_size; i++){
>       fputc(h[i], stderr);
>     }
>   }
>   if ((i = address(h))){
>     printf("From ");
>     for (j = 0; j < i; j++) putchar(Address[j]);
>     if (date(h))
>       printf("%s",Date);
>
>     //    printf("X-Coding-System: undecided-unix\n");
>
>     dump(h,"Date: "               , NULL           );
>     //    dump(h,"From: "               , ">From: "      );
>     dump(h,"From: "               , NULL           );
>     dump(h,"To: "                 , NULL           );
>     dump(h,"Subject: "            , NULL           );
>     dump(h,"Message-ID: "         , NULL           );
>     dump(h,"References: "         , NULL           );
>     dump(h,"MIME-Version: "       ,"Mime-Version: ");
>     dump(h,"X-MimeOLE: "          , NULL           );
>     content_type(h);
>     dump(h,"Content-Disposition: ", NULL           );
>     dump(h,"In-Reply-To: "        , NULL           );
>     user_agent(h);
>     printf("X-RMAIL-ATTRIBUTES: --------\n");
>     putchar('\n');
>   }
>   return PageSize*(1+(H_size-1)/PageSize);
> }
>
> size_t body(char *b)
> {
>   unsigned long i;
>
>   if (Debug){
>     for (i = 0; i < B_size; i++){
>       fputc(b[i], stderr);
>     }
>   }
>   if (Address){
>     for (i = 0; i < B_size; i++){
>       if (b[i] == '\n')
>     break;
>     }
>     while (++i < B_size) putchar(b[i]);
>     putchar('\n');
>   }
>   return PageSize*(1+(B_size-1)/PageSize);
> }
>
> void message(char *n) // convert and dump to stdout
> {
>   struct stat st;
>   void *p,*q; char *s, name[1024], buf[1024];  int h,b;  size_t hl, bl;
>
>   if ((Start > ++Count)||(Count > End)) return;
>
>   if ((-1 == (h = open(n, O_RDONLY)))){             // open headder?
>     fprintf(stderr,"can't open %s\n", n);
>     return;
>   }
>   if (fstat(h,&st)){
>     fprintf(stderr, "can't stat %s\n", n);
>     close(h);
>     return;
>   }
>   H_size = st.st_size;
>   if (!(p = mmap(0, H_size, PROT_READ, MAP_PRIVATE, h, 0))){
>     fprintf(stderr, "can't mmap %s\n", n);
>     close(h);
>     return;
>   }
>   for (s = n; *s; s++);
>   while (*s^'/') s--;
>   if ((1^sscanf((char *)p, "%1000s", name))||(strcmp(++s, name))){
>     fprintf(stderr,"file %s: format error\n", n);
>     munmap(p,hl);
>     close(h);
>     return;
>   }
>   for (s = n; *s; s++);
>   s[-1] = 'D';
>   if ((-1 == (b = open(n, O_RDONLY)))){             // open body?
>     fprintf(stderr,"can't open %s\n", n);
>     munmap(p,hl);
>     close(h);
>     return;
>   }
>   if (fstat(b,&st)){
>     fprintf(stderr, "can't stat %s\n", n);
>     munmap(p,hl);
>     close(h);
>     return;
>   }
>   B_size = st.st_size;
>   if (!(q = mmap(0, B_size, PROT_READ, MAP_PRIVATE, b, 0))){
>     fprintf(stderr, "can't mmap %s\n", n);
>     munmap(p,hl);
>     close(h);
>     close(b);
>     return;
>   }
>   for (s = n; *s; s++);
>   while (*s^'/') s--;
>   if ((1^sscanf((char *)q, "%1000s", name))||(strcmp(++s, name))){
>     fprintf(stderr,"file %s: format error\n", n);
>     munmap(p,hl);
>     close(h);
>     munmap(q,bl);
>     close(b);
>     return;
>   }
>   hl = head((char *)p);
>   bl = body((char *)q);
>   munmap(p,hl);
>   munmap(q,bl);
>   close(h);
>   close(b);
> }
>
> main(int argc, char *argv[])
> {
>   char *p,*q, buf[4096];  int i,j;   DIR *dirp;  struct dirent *d;
>
>   if (argc^4) goto usage;
>   Debug = atoi(argv[1]);
>   Start = atoi(argv[2]);
>   End   = atoi(argv[3]);
>
>   if (!(p = argv[4])){
>   usage:
>     printf("usage: access debug start end path\n"
>        "where debug is 0 or 1, \n"
>        "start and end are integers (range of messages to convert)\n"
>        "and path is for example /var/spool/exim/input \n"
>        "(locking needs to be added, and it is most certainly incomplete
> and buggy)\n");
>     return 1;
>   }
>   for (i = 0; i < 3072; i++, p++){                  // copy path to buf
>     if ((buf[i] = *p)) continue;
>     break;
>   }
>   if (*(p = buf+i)){                                // p is buf at end of
> path
>     goto usage;
>   }
>   if (!(dirp = opendir(buf))){
>     fprintf(stderr,"can't open %s\n",p);
>     return 1;
>   }
>   PageSize = sysconf(_SC_PAGE_SIZE);
>   if (*--p^'/') *++p = '/';                         // terminate path with
> '/'
>   while ((d = readdir(dirp))){
>     for (i = 1, q = d->d_name; i < 1000; i++, q++){
>       if ((p[i] = *q)) continue;
>       break;
>     }
>     if ((*q)||(q[-1]^'H')) continue;                // find headder files
>     message(buf);                                   // convert and dump to
> stdout
>   }
>   closedir(dirp);
>   return 0;
> }
> /*
> gcc -g -o access access.c
> */
>
>
>
> On Wed, Aug 13, 2014 at 3:56 PM, visaris tds.net <visaris@tds.net> wrote:
>
>> I know movemail purportedly can transfer email from mysterious places to
>> wherever emacs needs to find it, but I don't know how to make movemail work
>> (I've read the documentation several times, but find it baffling).
>>
>> I wrote c code to move messages from /var/spool/input to an RMAIL file,
>> but I evidently have not guessed correctly as to the exact file format
>> emacs needs (M-x rmail complains
>> and chokes on the RMAIL file I generate).
>>
>> I thought exim was a MTA.  I thought it already puts mail in a spool
>> file. All my mail is in /var/spool/exim/input. I believe that exim could be
>> configured somehow to allow emacs to read mail, but I don't know how.
>>
>> I stumbled across a mailing list for exim.  Perhaps I need to start there.
>>
>>
>> On Tue, Aug 12, 2014 at 9:18 PM, Robert Thorpe <
>> rt@robertthorpeconsulting.com> wrote:
>>
>>> "visaris tds.net" <visaris@tds.net> writes:
>>>
>>> > Whereas I have been reading mail with emacs for decades, I did a new
>>> install
>>> > (I'm a gentoo user) and now what once automagically worked nolonger
>>> does...
>>> > Emacs seems to function -- exept for mail.
>>> >
>>> > Although I have fethcmail and exim running, and although mail does
>>> > arive in /var/spool/exim/input, the format is that each message is
>>> split
>>> > into
>>> > a header file and then the body of the message.
>>> >
>>> > M-x rmail does not get mail from  /var/spool/exim/input.
>>>
>>> Did you post about this to the Emacs Reddit group recently?  As someone
>>> else wrote there /var/spool/exim/input is Exim's *input* spool file.
>>> It's where Exim puts emails before they are delivered.  As far as I
>>> understand it Exim is not designed to have users get stuff from that
>>> directory.  In the past it may have only worked by coincidence, because
>>> older versions of Exim stored stuff in some format that movemail
>>> understands.
>>>
>>> > I have spent much time chasing cryptic pointers reading unintelligable
>>> > documents making vague references to "movemail" but it is beyond me.
>>> > I have contemplated perusing the RMAIL file and comparing it with
>>> > contents of /var/spool/exim/input so as to increase the chance that I
>>> can
>>> > make some lucky guesses and write a c program to bridge the gap from
>>> > /var/spool/exim/input to RMAIL.  Surely emacs has not deteriated to the
>>> > point that this would be necessary.  I find it difficult to believe
>>> there
>>> > is not
>>> >  some simple way to proceed.
>>>
>>> "Movemail" fulfills two purposes.  Firstly, it moves mails between
>>> different places on one system.  It can take mail from the spool file(s)
>>> to a mbox file in the user's home directory.  (If the spool file is in
>>> MH or Maildir format it can translate that to mbox).  Secondly, it can
>>> act rather like fetchmail, it can download mails from an IMAP or POP
>>> server and copy them to a mbox file in the user's home directory.
>>>
>>> After movemail has done it's thing rmail itself takes over.  Rmail is
>>> really just a viewer for mbox files.  Rmail runs movemail automatically,
>>> there's no need to run it manually.
>>>
>>> If you have an MTA setup then it's normal to use it in the first way.
>>> The MTA puts mail in a spool file.  Then when you do M-x rmail it calls
>>> movemail which moves it to the "RMAIL" file in your home directory.
>>> That's what happens if you set the MAIL environment variable to your
>>> spool file.  If you want to make that approach work you need to figure
>>> out Exim (I find its manual baffling).  One way that could work is to
>>> use the LMTP transport of Exim to communicate with a mail delivery
>>> program such as maidag or maildrop.  Those programs put mail into spool
>>> files for users to access.  In this case you'll have:
>>> fetchmail(MRA)->Exim(MTA)->Maidag(MDA)->SpoolFile->movemail->rmail.
>>>
>>> Alternatively, you can bring mail directly from your IMAP or POP server
>>> using movemail.  That's what I do, I don't run an MTA on my PC at all, I
>>> deliver using Emac's smtpmail library.  To do this do something like:
>>> (setq send-mail-function 'smtpmail-send-it)
>>> (setq smtpmail-smtp-server "smtp.yourisp.com")
>>> (setq rmail-primary-inbox-list
>>>   '("imap://yourlogin:password@imap.yourisp.com"))
>>>
>>> To use IMAP you need the version of movemail in the GNU mailutils
>>> package.  The one that comes with Emacs only supports POP.
>>>
>>> BR,
>>> Robert Thorpe
>>>
>>
>>
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]