ftp.nice.ch/pub/next/connectivity/mail/bundles/EnhanceMail.2.2p1.NIHS.bs.gnutar.gz#/EnhanceMail-2.2p1/Source/MailBox.m

This is MailBox.m in view mode; [Download] [Up]

/* -*-C-*-
*******************************************************************************
*
* File:         MailBox.m
* RCS:          /usr/local/sources/CVS/EnhanceMail/MailBox.m,v 1.7 1998/05/12 21:32:19 tom Exp
* Description:  
* Author:       Carl Edman
* Created:      Fri Oct 13 11:48:05 1995
* Modified:     Sat Jun 29 16:00:38 1996 (Carl Edman) cedman@capitalist.princeton.edu
* Language:     C
* Package:      N/A
* Status:       Experimental (Do Not Distribute)
*
* (C) Copyright 1995, but otherwise this file is perfect freeware.
*
*******************************************************************************
*/

#import "EnhanceMail.h"
#import "Preferences.h"
#import "MailBox.h"
#import "MailIndex.h"
#import "MailReader.h"
#import	"TransferPanel.h"
#import <libc.h>
#import <indexing/indexing.h>

#define MSG_OPEN_MAILBOX NXLoadLocalizedStringFromTableInBundle("Alerts", nil, "Open Mailbox", NULL)
#define MSG_REBUILD_INDEX NXLocalizedStringFromTableInBundle("Localizable", EnhanceBundle, "Rebuilding full-text index for %s.  Please wait...", NULL, Message for full text index progressor)

static HashTable *StoreNameHash=nil;
static HashTable *ManagerHash=nil;

@implementation EnhanceMailBox

+ finishLoading:(struct mach_header *)header
{
   [self poseAs:[self superclass]];
   StoreNameHash=[[HashTable alloc] initKeyDesc:"@" valueDesc:"*"];
   ManagerHash=[[HashTable alloc] initKeyDesc:"@" valueDesc:"@"];
   return self;
}

+ startUnloading
{
   StoreNameHash=[StoreNameHash free];
   ManagerHash=[ManagerHash free];
   return self;
}

- initMailBox:(const char *)name
{
   char *storeName=0;
   id manager=nil;
   id ret=[super initMailBox:name];
   
   if (!dirname) return ret;
   storeName=strcpy(malloc(strlen(dirname)+20),dirname);
   strcat(storeName,"/content.store");
   [StoreNameHash insertKey:self value:storeName];

   manager=[[IXRecordManager alloc] initFromName:"content" inFile:storeName forWriting:YES];
   [ManagerHash insertKey:self value:manager];

   [self maybeUpdateStore];

   [[TransferPanel new] updateBrowserForMailBoxNamed:dirname];
   return ret;
}

- free
{
   char *storeName=[StoreNameHash valueForKey:self];
   id manager=[ManagerHash valueForKey:self];

   [StoreNameHash removeKey:self];
   if (storeName) free(storeName);
   
   [ManagerHash removeKey:self];
   if (manager)
   {
      id store=[manager store];
      [store startTransaction];
      [store compact];
      [store commitTransaction];
      manager=[manager free];
   }
   
   return [super free];
}

- (int)numberOfNonIndexedMessages
{
   id manager=[ManagerHash valueForKey:self];
   struct u_mailboxstatus stat;
   int count;

   if (manager==nil) return 0;
   
   [self getMailboxStatus:&stat];
   
   count=[manager count]-[manager attributeCount];
   
   if (stat.msgno<=count) return 0;
   
   return stat.msgno-count;
}

- createStore
{
   char *storeName=[StoreNameHash valueForKey:self];
   id manager=[ManagerHash valueForKey:self];

   id parser=[[IXAttributeParser alloc] init];

   if (!storeName) return nil;
   if (manager==nil)
   {
      manager=[[IXRecordManager alloc] initWithName:"content" inFile:storeName];
      [ManagerHash insertKey:self value:manager];
      
      [[manager store] startTransaction];
      [manager addAttributeNamed:"msgId" forSelector:@selector(msgId)];
      [manager setTargetClass:[MailIndex class] forAttributeNamed:"msgId"];
      [manager addAttributeNamed:"Content" forSelector:@selector(messageContent)];
      [manager setTargetClass:[MailIndex class] forAttributeNamed:"Content"];
      [manager setParser:parser forAttributeNamed:"Content"];
#if 0
      [manager addAttributeNamed:"Subject" forSelector:@selector(messageSubject)];
      [manager setTargetClass:[MailIndex class] forAttributeNamed:"Subject"];
      [manager addAttributeNamed:"From" forSelector:@selector(messageFrom)];
      [manager setTargetClass:[MailIndex class] forAttributeNamed:"From"];
      [manager addAttributeNamed:"To" forSelector:@selector(messageTo)];
      [manager setTargetClass:[MailIndex class] forAttributeNamed:"To"];
      [manager addAttributeNamed:"Cc" forSelector:@selector(messageCc)];
      [manager setTargetClass:[MailIndex class] forAttributeNamed:"Cc"];
      [manager addAttributeNamed:"Date" forSelector:@selector(messageDate)];
      [manager setTargetClass:[MailIndex class] forAttributeNamed:"Date"];
      [manager addAttributeNamed:"Message-Id" forSelector:@selector(messageId)];
      [manager setTargetClass:[MailIndex class] forAttributeNamed:"Message-Id"];
      [manager addAttributeNamed:"Next-Reference" forSelector:@selector(messageNextReference)];
      [manager setTargetClass:[MailIndex class] forAttributeNamed:"Next-Reference"];
#endif
      [[manager store] commitTransaction];
   }
   return [self maybeUpdateStore];   
}

- updateStore
{
   id manager=[ManagerHash valueForKey:self];
   struct u_mailboxstatus stat;
   int count;
   Progressor *progress;
   MailIndex *record;
   char buf[MAXPATHLEN+1];

   if (manager==nil) return nil;
   [self getMailboxStatus:&stat];
   count=[manager count]-[manager attributeCount];
   if (stat.msgno<=count) return self;
   [[manager store] startTransaction];
   
   sprintf(buf,MSG_REBUILD_INDEX,dirname);
   progress=[Progressor newWithTitle:MSG_OPEN_MAILBOX message:buf];
   [progress setMinValue:count];
   [progress setMaxValue:stat.msgno];
   [progress setProgress:count];
   [progress setShowProgress:YES];
   [progress beginModalSession];
   
   [MailIndex setMailBox:self];
   for(;(count<stat.msgno) && ![progress cancelled];count++)
   {
      record=[[MailIndex alloc] initMsgId:count];
      [manager addRecord:record];
      record=[record free];
      [progress setProgress:count];
   }
   [MailIndex setMailBox:nil];
   
   [progress endModalSession];
   [[manager store] commitTransaction];

   return (count>=stat.msgno) ? self : nil;
}

- maybeUpdateStore
{
   if ([self numberOfNonIndexedMessages] > 25) return [self updateStore];
   // XXX hardcoded parameter.
   return nil;
}

- deleteStore
{
   char *storeName=[StoreNameHash valueForKey:self];
   id manager=[ManagerHash valueForKey:self];
      
   if (!storeName)
      return nil;

   if (manager)
      [ManagerHash insertKey:self value:(manager=[manager free])];

   if (unlink(storeName)==-1)
      return nil;

   return self;
}

- (BOOL)hasStore
{
   id manager=[ManagerHash valueForKey:self];
      
   return (manager==nil) ? NO : YES;
}

- (int)storeSize
{
   char *storeName=[StoreNameHash valueForKey:self];
   id manager=[ManagerHash valueForKey:self];
   struct stat buf;
   
   if ((manager==nil)||(storeName==0)||(stat(storeName,&buf)==-1)) return -1;
   
   return buf.st_size;
}

- (void)maybeUpdateToc
{
   [super maybeUpdateToc];
   [self maybeUpdateStore];
}

- repairTocFile:(int)start
{
   id ret=[super repairTocFile:start];
   [self maybeUpdateStore];
   return ret;
}

- query:(const char *)expr
{
   id manager,parser,query,list;

   manager=[ManagerHash valueForKey:self];
   if (manager==nil) return nil;
   
   [self updateStore];

   parser=[manager parserForAttributeNamed:"Content"];
   if (parser==nil) return nil;
   [self updateStore];
   query=[[IXAttributeQuery alloc] initQueryString:expr andAttributeParser:parser];
   if (query==nil) return nil;
   list=[query evaluateFor:manager];
   [query free];
   return list;
}

#if 0
- flushMsgState;
{
   //puts("***flushMsgState");
   return [super flushMsgState];
}
#endif

#if 0 // Better handled in [MailReader updateStatus] ?
- (BOOL)setState:(char)fp16 forMsg:(int)fp20 flush:(BOOL)fp24;
{
   //puts("***setState");
   [[self mailReader] updateTransferPanel];
   return [super setState:fp16 forMsg:fp20 flush:fp24];
}
#endif

@end // EnhanceMailBox

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.