home *** CD-ROM | disk | FTP | other *** search
- /* -*-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);
-