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.