This is searchmail.m in view mode; [Download] [Up]
/* -*-C-*-
*******************************************************************************
*
* File: searchmail.m
* RCS: /usr/local/sources/CVS/mailapp-utilities/searchmail.m,v 1.2 1996/12/01 17:03:30 tom Exp
* Description: Search mailboxes
* Author: Carl Edman
* Created: Fri Jun 3 20:45:43 1994
* Modified: Fri Apr 7 09:57:27 1995 (Carl Edman) cedman@freedom.princeton.edu
* Language: Objective C
* Package: N/A
* Status: Experimental (Do Not Distribute)
*
* (C) Copyright 1994, but otherwise this file is perfect freeware.
*
*******************************************************************************
*/
#import <appkit/appkit.h>
#import <indexing/indexing.h>
#import "MailBox.h"
#import "MailMessage.h"
#import "mailutil.h"
id manager;
void updatembox(const char *name)
{
#if 0
if (cd_mbox(mbox,0)) return nil;
if (access(".no_search",F_OK)!=-1) return;
/* return if up to date on mbox */
/* Add to list if not in the list */
{
struct table_of_contents_header *toc=(void *)tocbuf;
struct message_index *m;
int i;
unsigned int handle;
unsigned int weight;
id cursor=[manager cursorForAttributeNamed:"Position"],record;
[[manager store] startTransaction];
/* Go through all the records and validate them */
for([cursor setFirst];[cursor isMatch];[cursor setNext])
{
if (![cursor getHandle:&handle andWeight:&weight]) continue;
// if wrong mailbox continue;
record=[manager readRecord:handle fromZone:NXDefaultMallocZone()];
if ([record validate]) continue;
[manager removeRecord:handle];
[record free];
}
/* Go through entire table and create records if they don't exist */
for(i=NXSwapBigLongToHost(toc->num_msgs),
m=(void *)tocbuf+sizeof(struct table_of_contents_header);
(i>0)&&((void *)m<(void *)tocbuf+toclen);
i--,
m=((void *)m)+NXSwapBigLongToHost(m->record_length))
{
unsigned long int offset=((void *)m)-((void *)tocbuf);
if ([cursor setKey:&offset andLength:sizeof(offset)]) continue;
if (record=[[MailMessage alloc] initPos:offset])
[manager addRecord:record];
}
[[manager store] commitTransaction];
[cursor free];
}
if (uncd_mbox()) return;
#endif
}
void main(int ac,char *av[])
{
id parser, query, list;
int c,errflg=0,queryflg=0;
char *expr=0;
char path[MAXPATHLEN];
while((c=getopt(ac,av,"qe:"))!=EOF) switch(c)
{
case 'e':
expr=optarg;
break;
case 'q':
queryflg++;
break;
case '?':
default:
errflg++;
}
if (expr==0)
{
if (optind<ac) expr=av[optind++]; else errflg++;
}
if (errflg)
{
fprintf(stderr,"Usage: %s [-q] [-e expr] expr [mbox...]\n",av[0]);
exit(1);
}
if (!queryflg)
{
int len=256+strlen(expr);
char *tmp;
tmp=alloca(len);
sprintf(tmp,"whole(Content parse(%s))",expr);
expr=tmp;
}
if (optind<ac)
{
int len=256+strlen(expr);
char *tmp,*end;
for(c=optind;c<ac;c++) len+=16+strlen(av[c]);
end=tmp=alloca(len);
sprintf(tmp,"and(%s, or(",expr);
end+=strlen(end);
for(c=optind;c<ac;c++)
{
sprintf(end,"eq(\"Box\" %s), ",av[c]);
end+=strlen(end);
}
end[-2]=')';
end[-1]=')';
expr=tmp;
}
parser=[[IXAttributeParser alloc] init];
query=[[IXAttributeQuery alloc] initQueryString:expr andAttributeParser:parser];
if (query==nil)
{
fprintf(stderr,"Expression '%s' malformed.\n",expr);
exit(2);
}
if (mailboxdir(path)<0) exit(3);
strcat(path,"/search.store");
manager=[[IXRecordManager alloc] initFromName:"messages" inFile:path forWriting:YES];
if (manager==nil)
{
manager=[[IXRecordManager alloc] initWithName:"messages" inFile:path];
if (manager==nil)
{
fprintf(stderr,"Can't create index file '%s'.\n",path);
exit(4);
}
[[manager store] startTransaction];
[manager addAttributeNamed:"Position" forSelector:@selector(position)];
[manager setTargetClass:[MailMessage class] forAttributeNamed:"Position"];
[manager addAttributeNamed:"Box" forSelector:@selector(box)];
[manager setTargetClass:[MailMessage class] forAttributeNamed:"Box"];
[manager addAttributeNamed:"Subject" forSelector:@selector(messageSubject)];
[manager setTargetClass:[MailMessage class] forAttributeNamed:"Subject"];
[manager addAttributeNamed:"From" forSelector:@selector(messageFrom)];
[manager setTargetClass:[MailMessage class] forAttributeNamed:"From"];
[manager addAttributeNamed:"To" forSelector:@selector(messageTo)];
[manager setTargetClass:[MailMessage class] forAttributeNamed:"To"];
[manager addAttributeNamed:"Date" forSelector:@selector(messageDate)];
[manager setTargetClass:[MailMessage class] forAttributeNamed:"Date"];
[manager addAttributeNamed:"Message-Id" forSelector:@selector(messageId)];
[manager setTargetClass:[MailMessage class] forAttributeNamed:"Message-Id"];
[manager addAttributeNamed:"Next-Reference" forSelector:@selector(messageNextReference)];
[manager setTargetClass:[MailMessage class] forAttributeNamed:"Next-Reference"];
[manager addAttributeNamed:"Content" forSelector:@selector(messageContent)];
[manager setTargetClass:[MailMessage class] forAttributeNamed:"Content"];
[manager setParser:parser forAttributeNamed:"Content"];
[[manager store] commitTransaction];
}
if (optind<ac)
for(c=optind;c<ac;c++) updatembox(av[c]);
else
forall_mboxes(&updatembox);
if ([[manager store] areTransactionsEnabled])
{
[[manager store] startTransaction];
[[manager store] compact];
[[manager store] commitTransaction];
}
if (list=[query evaluateFor:manager])
{
const char *m;
id message;
int count=[list count];
for(c=0;c<count;c++)
{
message=[list objectAt:c];
m=[message messageHeaders];
fputs(m,stdout);
fputc('\n',stdout);
m=[message messageContent];
fputs(m,stdout);
}
[[list freeObjects] free];
list=nil;
}
[query free];
}
// NXStream *NXMapFile(const char *pathName, NX_READONLY);
// void NXGetMemoryBuffer(NXStream *stream, char **streambuf, int *len, int *maxlen)
// void NXCloseMemory(NXStream *stream, NX_FREEBUFFER);
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.