home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Mail / appnmail-1.8-Solaris / mailapp-utilities / searchmail.m < prev    next >
Encoding:
Text File  |  1996-12-01  |  6.6 KB  |  219 lines

  1. /* -*-C-*-
  2. *******************************************************************************
  3. *
  4. * File:         searchmail.m
  5. * RCS:          /usr/local/sources/CVS/mailapp-utilities/searchmail.m,v 1.2 1996/12/01 17:03:30 tom Exp
  6. * Description:  Search mailboxes 
  7. * Author:       Carl Edman
  8. * Created:      Fri Jun  3 20:45:43 1994
  9. * Modified:     Fri Apr  7 09:57:27 1995 (Carl Edman) cedman@freedom.princeton.edu
  10. * Language:     Objective C
  11. * Package:      N/A
  12. * Status:       Experimental (Do Not Distribute)
  13. *
  14. * (C) Copyright 1994, but otherwise this file is perfect freeware.
  15. *
  16. *******************************************************************************
  17. */
  18.  
  19. #import <appkit/appkit.h>
  20. #import <indexing/indexing.h>
  21. #import "MailBox.h"
  22. #import "MailMessage.h"
  23. #import "mailutil.h"
  24.  
  25. id manager;
  26.  
  27. void updatembox(const char *name)
  28.    {
  29. #if 0
  30.    if (cd_mbox(mbox,0)) return nil;
  31.    if (access(".no_search",F_OK)!=-1) return;
  32.    /* return if up to date on mbox */
  33.    /* Add to list if not in the list */
  34.    
  35.       {
  36.       struct table_of_contents_header *toc=(void *)tocbuf;
  37.       struct message_index *m;
  38.       int i;
  39.       unsigned int handle;
  40.       unsigned int weight;
  41.       id cursor=[manager cursorForAttributeNamed:"Position"],record;
  42.       
  43.       [[manager store] startTransaction];
  44.       /* Go through all the records and validate them */
  45.       for([cursor setFirst];[cursor isMatch];[cursor setNext])
  46.          {
  47.          if (![cursor getHandle:&handle andWeight:&weight]) continue;
  48.          // if wrong mailbox continue;
  49.          record=[manager readRecord:handle fromZone:NXDefaultMallocZone()];
  50.          if ([record validate]) continue;
  51.          [manager removeRecord:handle];
  52.          [record free];
  53.          }
  54.       
  55.       /* Go through entire table and create records if they don't exist */
  56.       for(i=NXSwapBigLongToHost(toc->num_msgs),
  57.           m=(void *)tocbuf+sizeof(struct table_of_contents_header);
  58.           (i>0)&&((void *)m<(void *)tocbuf+toclen);
  59.           i--,
  60.           m=((void *)m)+NXSwapBigLongToHost(m->record_length))
  61.          {
  62.          unsigned long int offset=((void *)m)-((void *)tocbuf);
  63.          
  64.          if ([cursor setKey:&offset andLength:sizeof(offset)]) continue;
  65.          if (record=[[MailMessage alloc] initPos:offset])
  66.             [manager addRecord:record];
  67.          }
  68.       [[manager store] commitTransaction];
  69.       [cursor free];
  70.       }
  71.  
  72.    if (uncd_mbox()) return;
  73. #endif
  74.    }
  75.  
  76. void main(int ac,char *av[])
  77.    {
  78.    id parser, query, list;
  79.    int c,errflg=0,queryflg=0;
  80.    char *expr=0;
  81.    char path[MAXPATHLEN];
  82.    
  83.    while((c=getopt(ac,av,"qe:"))!=EOF) switch(c)
  84.       {
  85.     case 'e':
  86.       expr=optarg;
  87.       break;
  88.     case 'q':
  89.       queryflg++;
  90.       break;
  91.     case '?':
  92.     default:
  93.       errflg++;      
  94.       }
  95.  
  96.    if (expr==0)
  97.       {
  98.       if (optind<ac) expr=av[optind++]; else errflg++;
  99.       }
  100.  
  101.    if (errflg)
  102.       {
  103.       fprintf(stderr,"Usage: %s [-q] [-e expr] expr [mbox...]\n",av[0]);
  104.       exit(1);
  105.       }
  106.  
  107.    if (!queryflg)
  108.       {
  109.       int len=256+strlen(expr);
  110.       char *tmp;
  111.  
  112.       tmp=alloca(len);
  113.       sprintf(tmp,"whole(Content parse(%s))",expr);
  114.       expr=tmp;
  115.       }
  116.  
  117.    if (optind<ac)
  118.       {
  119.       int len=256+strlen(expr);
  120.       char *tmp,*end;
  121.       
  122.       for(c=optind;c<ac;c++) len+=16+strlen(av[c]);
  123.       end=tmp=alloca(len);
  124.       sprintf(tmp,"and(%s, or(",expr);
  125.       end+=strlen(end);
  126.       
  127.       for(c=optind;c<ac;c++)
  128.          {
  129.          sprintf(end,"eq(\"Box\" %s), ",av[c]);         
  130.          end+=strlen(end);
  131.          }
  132.  
  133.       end[-2]=')';
  134.       end[-1]=')';
  135.       expr=tmp;
  136.       }
  137.  
  138.    parser=[[IXAttributeParser alloc] init];
  139.    
  140.    query=[[IXAttributeQuery alloc] initQueryString:expr andAttributeParser:parser];
  141.    if (query==nil)
  142.       {
  143.       fprintf(stderr,"Expression '%s' malformed.\n",expr);
  144.       exit(2);
  145.       }
  146.    
  147.    if (mailboxdir(path)<0) exit(3);
  148.    strcat(path,"/search.store");
  149.    manager=[[IXRecordManager alloc] initFromName:"messages" inFile:path forWriting:YES];
  150.    if (manager==nil)
  151.       {
  152.       manager=[[IXRecordManager alloc] initWithName:"messages" inFile:path];
  153.       if (manager==nil)
  154.          {
  155.          fprintf(stderr,"Can't create index file '%s'.\n",path);
  156.          exit(4);
  157.          }
  158.       [[manager store] startTransaction];
  159.       [manager addAttributeNamed:"Position" forSelector:@selector(position)];
  160.       [manager setTargetClass:[MailMessage class] forAttributeNamed:"Position"];
  161.       [manager addAttributeNamed:"Box" forSelector:@selector(box)];
  162.       [manager setTargetClass:[MailMessage class] forAttributeNamed:"Box"];
  163.       [manager addAttributeNamed:"Subject" forSelector:@selector(messageSubject)];
  164.       [manager setTargetClass:[MailMessage class] forAttributeNamed:"Subject"];
  165.       [manager addAttributeNamed:"From" forSelector:@selector(messageFrom)];
  166.       [manager setTargetClass:[MailMessage class] forAttributeNamed:"From"];
  167.       [manager addAttributeNamed:"To" forSelector:@selector(messageTo)];
  168.       [manager setTargetClass:[MailMessage class] forAttributeNamed:"To"];
  169.       [manager addAttributeNamed:"Date" forSelector:@selector(messageDate)];
  170.       [manager setTargetClass:[MailMessage class] forAttributeNamed:"Date"];
  171.       [manager addAttributeNamed:"Message-Id" forSelector:@selector(messageId)];
  172.       [manager setTargetClass:[MailMessage class] forAttributeNamed:"Message-Id"];
  173.       [manager addAttributeNamed:"Next-Reference" forSelector:@selector(messageNextReference)];
  174.       [manager setTargetClass:[MailMessage class] forAttributeNamed:"Next-Reference"];
  175.       [manager addAttributeNamed:"Content" forSelector:@selector(messageContent)];
  176.       [manager setTargetClass:[MailMessage class] forAttributeNamed:"Content"];
  177.       [manager setParser:parser forAttributeNamed:"Content"];
  178.       [[manager store] commitTransaction];
  179.       }
  180.    
  181.    if (optind<ac)
  182.       for(c=optind;c<ac;c++) updatembox(av[c]);
  183.    else
  184.       forall_mboxes(&updatembox);
  185.    
  186.    if ([[manager store] areTransactionsEnabled])
  187.       {
  188.       [[manager store] startTransaction];
  189.       [[manager store] compact];
  190.       [[manager store] commitTransaction];
  191.       }
  192.    
  193.    if (list=[query evaluateFor:manager])
  194.       {
  195.       const char *m;
  196.       id message;
  197.       int count=[list count];
  198.       
  199.       for(c=0;c<count;c++)
  200.          {
  201.          message=[list objectAt:c];
  202.          m=[message messageHeaders];
  203.          fputs(m,stdout);         
  204.          fputc('\n',stdout);
  205.          m=[message messageContent];         
  206.          fputs(m,stdout);
  207.          }
  208.       
  209.       [[list freeObjects] free];
  210.       list=nil;
  211.       }
  212.  
  213.    [query free];
  214.    }
  215.  
  216. // NXStream *NXMapFile(const char *pathName, NX_READONLY);
  217. // void NXGetMemoryBuffer(NXStream *stream, char **streambuf, int *len, int *maxlen)
  218. // void NXCloseMemory(NXStream *stream, NX_FREEBUFFER);
  219.