/* -*-C-*-
*******************************************************************************
*
* File:         MailMessage.m
* RCS:          /usr/local/sources/CVS/mailapp-utilities/MailMessage.m,v 1.2 1996/12/01 17:03:01 tom Exp
* Description:  Handle mailmessages for searchmail
* Author:       Carl Edman
* Created:      Wed Mar 29 10:18:11 1995
* Modified:     Fri Apr  7 09:59:56 1995 (Carl Edman) cedman@freedom.princeton.edu
* Language:     C
* Package:      N/A
* Status:       Experimental (Do Not Distribute)
*
* (C) Copyright 1995, but otherwise this file is perfect freeware.
*
*******************************************************************************
*/

#import <appkit/appkit.h>
#import <indexing/indexing.h>
#import <ctype.h>
#import <libc.h>
#import "MailMessage.h"
#import "MailBox.h"
#import "mailutil.h"
#import "mailtoc.h"

static int getbox(id box,char **tocbuf,int *toclen,char **mboxbuf,int *mboxlen)
   {
   return 0;
   }

@implementation MailMessage
-finishReading
   {
   return self;
   }

-source:aTranscriber didReadRecord:(unsigned int)aHandle
   {
   return self;
   }

-source:aTranscriber willWriteRecord:(unsigned int)aHandle
   {
   return self;
   }

-(const char *)header:(const char *)header
   {
   char *mboxbuf,*tocbuf;
   int mboxlen,toclen;
   struct message_index *m;
   int moff,mlen,hlen;
   char *mbase,*p;
      
   if (getbox(box,&tocbuf,&toclen,&mboxbuf,&mboxlen)) return "";
   if (pos+len>toclen) return "";

   m=(struct message_index *)(tocbuf+pos);
   moff=NXSwapBigLongToHost(m->mes_offset);
   mlen=NXSwapBigLongToHost(m->mes_length);

   if (moff+mlen>mboxlen) return "";
   mbase=mboxbuf+moff;

   hlen=strlen(header);

   for(p=mbase;p<mbase+mlen;)
      {
      if (!strncmp(p,header,hlen))
         {
         char *beg=p+hlen,*ret;
         
         for(p=beg;p<mbase+mlen;p++)
            if (*(p-1)=='\n' && *p!='\t') 
               {
               p--;
               break;
               }
         ret=malloc(p-beg+1);
         strncpy(ret,beg,p-beg);
         ret[p-beg]='\0';
         return ret;
         }
      if (*p=='\n') break;
      while ((*p!='\n')&&(p<mbase+mlen)) p++;
      p++;
      }
   
   return "";
   }

-initInBox:(id)nbox at:(unsigned int)npos
   {
   char *mboxbuf,*tocbuf;
   int mboxlen,toclen;
   struct message_index *m;

   box=nbox;
   pos=npos;
   
   if (getbox(box,&tocbuf,&toclen,&mboxbuf,&mboxlen)) { [self free]; return nil; }
   if (pos+sizeof(struct message_index)>toclen) { [self free]; return nil; }

   m=(struct message_index *)(tocbuf+pos);
   len=NXSwapBigLongToHost(m->record_length);
   
   if (pos+len>toclen) { [self free]; return nil; }

   crc=calc_crc(tocbuf+pos,len);
   return self;
   }

-(BOOL)validate
   {
   char *mboxbuf,*tocbuf;
   int mboxlen,toclen;
   struct message_index *m;

   if (getbox(box,&tocbuf,&toclen,&mboxbuf,&mboxlen)) return NO;
   if (pos+len>toclen) return NO;

   m=(struct message_index *)(tocbuf+pos);
   if (len!=NXSwapBigLongToHost(m->record_length)) return NO;
   if (crc!=calc_crc(tocbuf+pos,len)) return NO;
   return YES;
   }

-(id)box
   {
   return box;
   }

-(unsigned short)len
   {
   return len;
   }

-(unsigned int)position
   {
   return pos;
   }

-(const char *)messageHeaders
   {
   char *mboxbuf,*tocbuf;
   int mboxlen,toclen;
   struct message_index *m;
   int moff,mlen;
   char *mbase,*p;
      
   if (getbox(box,&tocbuf,&toclen,&mboxbuf,&mboxlen)) return "";
   if (pos+len>toclen) return "";

   m=(struct message_index *)(tocbuf+pos);
   moff=NXSwapBigLongToHost(m->mes_offset);
   mlen=NXSwapBigLongToHost(m->mes_length);

   if (moff+mlen>mboxlen) return "";

   mbase=mboxbuf+moff;
   for(p=mbase;p<mbase+mlen;)
      {
      if (*p=='\n') break;
      while ((*p!='\n')&&(p<mbase+mlen)) p++;
      p++;
      }

      {
      char *ret=malloc(p-mbase+1);
      strncpy(ret,mbase,p-mbase);
      ret[p-mbase]='\0';
      return ret;
      }
   }

-(const char *)messageContent
   {
   char *mboxbuf,*tocbuf;
   int mboxlen,toclen;
   struct message_index *m;
   int moff,mlen;
   char *mbase,*p,*ret;
      
   if (getbox(box,&tocbuf,&toclen,&mboxbuf,&mboxlen)) return "";
   if (pos+len>toclen) return "";

   m=(struct message_index *)(tocbuf+pos);

   p=m->data;
   p+=strlen(p)+1;
   p+=strlen(p)+1;

   if (*p)
      {
      int fd, i;
      char path[MAXPATHLEN];

      if ((i=mailboxdir(path))<0) return "";
      path[i++]='/';
      /* XXX strcat(path,mailboxdir); */
      
      strcat(path,p);
      strcat(path,"/index.rtf");
      if ((fd=open(path,O_RDONLY))<0) return "";
      if ((i=filesize(path))<0) return "";
      p=malloc(i+1);
      if (read(fd,p,i)!=i)
         {
         close(fd);
         return "";
         }
      close(fd);
      p[i]='\0';
      return p;
      }
   
   moff=NXSwapBigLongToHost(m->mes_offset);
   mlen=NXSwapBigLongToHost(m->mes_length);

   if (moff+mlen>mboxlen) return "";
   
   mbase=mboxbuf+moff;
   for(p=mbase;p<mbase+mlen;)
      {
      if (*p=='\n') break;
      while ((*p!='\n')&&(p<mbase+mlen)) p++;
      p++;
      }
   
   p++;
   ret=malloc(mbase+mlen-p+1);
   strncpy(ret,p,mbase+mlen-p+1);
   ret[mbase+mlen-p+1]='\0';
   return ret;
   }

-(const char *)messageSubject
   {
   return [self header:"Subject: "];
   }

-(const char *)messageFrom
   {
   return [self header:"From: "];
   }

-(const char *)messageTo
   {
   return [self header:"To: "];
   }

-(const char *)messageDate
   {
   return [self header:"Date: "];
   }

-(const char *)messageId
   {
   return [self header:"Message-Id: "];
   }

-(const char *)messageNextReference
   {
   return [self header:"Next-Reference: "];
   }
@end
