home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Mail / appnmail-1.8-Solaris / mailapp-utilities / mailtoc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-04  |  7.9 KB  |  284 lines

  1. /* -*-C-*-
  2. *******************************************************************************
  3. *
  4. * File:         mailtoc.c
  5. * RCS:          /usr/local/sources/CVS/mailapp-utilities/mailtoc.c,v 1.3 1997/04/19 17:37:22 tom Exp
  6. * Description:  Table-of-contents access routines for Mail.app utilities
  7. * Author:       Carl Edman
  8. * Created:      Sun Apr 25 10:31:24 1993
  9. * Modified:     Sat Apr 19 14:38:39 1997 Tom Hageman <tom@basil.icce.rug.nl>
  10. * Language:     C
  11. * Package:      N/A
  12. * Status:       Experimental (Do Not Distribute)
  13. *
  14. * (C) Copyright 1993, but otherwise this file is perfect freeware.
  15. *
  16. *******************************************************************************
  17. */
  18.  
  19. #import <unistd.h>
  20. #import <stdlib.h>
  21. #import <stdio.h>
  22. #import <string.h>
  23. //#import <time.h>
  24. #import <sys/file.h>
  25. #import <sys/param.h>
  26. #import <sys/types.h>
  27. #import <sys/stat.h>
  28. //#import <sys/dir.h>
  29. #import <errno.h>
  30.  
  31. #import "mailtoc.h"
  32.  
  33. /* Works fine for Big Endian machines */
  34. #define NXSwapBigLongToHost
  35. #define NXSwapBigFloatToHost
  36. #define NXConvertHostFloatToSwapped
  37. #define NXSwapHostLongToBig
  38. #define NXConvertSwappedFloatToHost
  39. #define NXSwapHostFloatToBig
  40.  
  41. #define TOC_MAGIC 890712
  42. #define TOC_MESSAGE_INDEX_MAX 100000
  43.    /* arbitrary limit on message index size, to avoid crashes on corrupt mailboxes. */
  44.  
  45. struct table_of_contents_header *get_table_of_contents_header(FILE *f,int createflag)
  46. {
  47.    int n;
  48.    struct table_of_contents_header *toc;
  49.    toc=malloc(sizeof(*toc));
  50.    if(toc==NULL) return 0;
  51.    errno=0;
  52.    if ((n=fread((void *)toc,1,sizeof(*toc),f))!=sizeof(*toc))
  53.    {
  54.       if (!(createflag && n==0))
  55.       {
  56.      free(toc);
  57.      return 0;
  58.       }
  59.       toc->magic=TOC_MAGIC;
  60.       toc->num_msgs=0;
  61.       toc->mbox_time=-1;
  62.       toc->list=102.0;
  63.       toc->window.origin.x=271.0;
  64.       toc->window.origin.y=151.0;
  65.       toc->window.size.width=557.0;
  66.       toc->window.size.height=532.0;
  67.       /* Write table of contents immediately, so space for it is allocated.
  68.      Caveat: this will byteswap the contents of the in-memory toc,
  69.      so we'll fall through to the unswapping code below. */
  70.       if (put_table_of_contents_header(f,toc)!=0)
  71.       {
  72.      free(toc);
  73.      return 0;
  74.       }
  75.    }
  76.    toc->magic=NXSwapBigLongToHost(toc->magic);
  77.    toc->num_msgs=NXSwapBigLongToHost(toc->num_msgs);
  78.    toc->mbox_time=NXSwapBigLongToHost(toc->mbox_time);
  79.    toc->list=NXSwapBigFloatToHost(NXConvertHostFloatToSwapped(toc->list));
  80.    toc->window.origin.x=NXSwapBigFloatToHost(NXConvertHostFloatToSwapped(toc->window.origin.x));
  81.    toc->window.origin.y=NXSwapBigFloatToHost(NXConvertHostFloatToSwapped(toc->window.origin.y));
  82.    toc->window.size.width=NXSwapBigFloatToHost(NXConvertHostFloatToSwapped(toc->window.size.width));
  83.    toc->window.size.height=NXSwapBigFloatToHost(NXConvertHostFloatToSwapped(toc->window.size.height));
  84.    if (toc->magic!=TOC_MAGIC) /* basic sanity check. */
  85.    {
  86.       free(toc);
  87.       return 0;
  88.    }
  89.    return toc;
  90. }
  91.  
  92. struct message_index *get_message_index(FILE *f)
  93. {
  94.    long rl;
  95.    struct message_index *mi;
  96.    errno=0;
  97.    if (fread(&rl,1,sizeof(rl),f)!=sizeof(rl)) return 0;
  98.    rl=NXSwapBigLongToHost(rl);
  99.    if (rl > TOC_MESSAGE_INDEX_MAX) return 0;
  100.    mi=malloc(rl);
  101.    if(mi==NULL) return 0;
  102.    mi->record_length=rl;
  103.    if (fread(((char *)mi)+sizeof(rl),1,rl-sizeof(rl),f)!=rl-sizeof(rl))
  104.    {
  105.       free(mi);
  106.       return 0;
  107.    }
  108.    mi->mes_offset=NXSwapBigLongToHost(mi->mes_offset);
  109.    mi->mes_length=NXSwapBigLongToHost(mi->mes_length);
  110.    mi->mes_date=NXSwapBigLongToHost(mi->mes_date);
  111.    return mi;
  112. }
  113.  
  114. int put_message_index(FILE *f,struct message_index *mi)
  115. {
  116.    long reclen=mi->record_length;
  117.    mi->record_length=NXSwapHostLongToBig(mi->record_length);
  118.    mi->mes_offset=NXSwapHostLongToBig(mi->mes_offset);
  119.    mi->mes_length=NXSwapHostLongToBig(mi->mes_length);
  120.    mi->mes_date=NXSwapHostLongToBig(mi->mes_date);
  121.    errno=0;
  122.    return (fwrite(mi,1,reclen,f)!=reclen);
  123. }
  124.  
  125. int put_table_of_contents_header(FILE *f,struct table_of_contents_header *toc)
  126. {
  127.    toc->magic=NXSwapHostLongToBig(toc->magic);
  128.    toc->num_msgs=NXSwapHostLongToBig(toc->num_msgs);
  129.    toc->mbox_time=NXSwapHostLongToBig(toc->mbox_time);
  130.    toc->list=NXConvertSwappedFloatToHost(NXSwapHostFloatToBig(toc->list));
  131.    toc->window.origin.x=NXConvertSwappedFloatToHost(NXSwapHostFloatToBig(toc->window.origin.x));
  132.    toc->window.origin.y=NXConvertSwappedFloatToHost(NXSwapHostFloatToBig(toc->window.origin.y));
  133.    toc->window.size.width=NXConvertSwappedFloatToHost(NXSwapHostFloatToBig(toc->window.size.width));
  134.    toc->window.size.height=NXConvertSwappedFloatToHost(NXSwapHostFloatToBig(toc->window.size.height));
  135.    errno=0;
  136.    rewind(f);
  137.    return (fwrite(toc,1,sizeof(*toc),f)!=sizeof(*toc));
  138. }
  139.  
  140. long message_current_date(void)
  141. {
  142.    time_t clock;
  143.    struct tm *ctm;
  144.    time(&clock);
  145.    ctm=localtime(&clock);
  146.    return ((ctm->tm_mday&0x1f)
  147.            +(((ctm->tm_mon+1)&0xf)<<5)
  148.            +((ctm->tm_year+1900)<<9));
  149. }
  150.  
  151. long message_date(int year,const char *month,int day)
  152. {
  153.    static const char months[][4]=
  154.    {
  155.       "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  156.       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  157.    };
  158.    int m;
  159.    
  160.    for(m=0;m<12;m++) if (!strncmp(month,months[m],3)) break;
  161.    m=(m%12)+1; /* Wrap around to January for unidentifiable month
  162.                   It's better than failing for an unattended program */
  163.    
  164.    return (day&0x1f) + ((m&0xf)<<5) + (year << 9);
  165. }
  166.  
  167. char *message_from(const struct message_index *mi)
  168. {
  169.    char *p=mi->data;
  170.    return p;
  171. }
  172.  
  173. char *message_subject(const struct message_index *mi)
  174. {
  175.    char *p=mi->data;
  176.    p+=strlen(p)+1;
  177.    return p;
  178. }
  179.  
  180. char *message_reference(const struct message_index *mi)
  181. {
  182.    char *p=mi->data;
  183.    p+=strlen(p)+1;
  184.    p+=strlen(p)+1;
  185.    return p;
  186. }
  187.  
  188. int message_attachsize(const struct message_index *mi)
  189. {
  190.    const unsigned char *p=mi->data;
  191.    p+=strlen(p)+1;
  192.    p+=strlen(p)+1;
  193.    p+=strlen(p)+1;
  194.    p+=sizeof(int);   
  195.    if (p-(const unsigned char *)mi>mi->record_length) return -1;
  196.    return (int)((p[-4]<<24)+(p[-3]<<16)+(p[-2]<<8)+p[-1]);   
  197. }
  198.  
  199. int message_set_attachsize(struct message_index *mi,int size)
  200. {
  201.    unsigned char *p=mi->data;
  202.    p+=strlen(p)+1;
  203.    p+=strlen(p)+1;
  204.    p+=strlen(p)+1;
  205.    p+=sizeof(int);
  206.    if (p-(unsigned char *)mi>mi->record_length) return -1;
  207.    p[-4]=size>>24;
  208.    p[-3]=size>>16;
  209.    p[-2]=size>> 8;
  210.    p[-1]=size>> 0;
  211.    return size;
  212. }
  213.  
  214. time_t message_attachtime(const struct message_index *mi)
  215. {
  216.    const unsigned char *p=mi->data;
  217.    p+=strlen(p)+1;
  218.    p+=strlen(p)+1;
  219.    p+=strlen(p)+1;
  220.    p+=sizeof(int);
  221.    p+=sizeof(time_t);
  222.    if (p-(const unsigned char *)mi>mi->record_length) return -1;
  223.    return (time_t)((p[-4]<<24)+(p[-3]<<16)+(p[-2]<<8)+p[-1]);   
  224. }
  225.  
  226. time_t message_set_attachtime(struct message_index *mi,time_t time)
  227. {
  228.    unsigned char *p=mi->data;
  229.    p+=strlen(p)+1;
  230.    p+=strlen(p)+1;
  231.    p+=strlen(p)+1;
  232.    p+=sizeof(int);
  233.    p+=sizeof(time_t);
  234.    if (p-(unsigned char *)mi>mi->record_length) return -1;
  235.    p[-4]=((int)time)>>24;
  236.    p[-3]=((int)time)>>16;
  237.    p[-2]=((int)time)>> 8;
  238.    p[-1]=((int)time)>> 0;
  239.    return time;
  240. }
  241.  
  242. int message_priority(const struct message_index *mi)
  243. {
  244.    const unsigned char *p=mi->data;
  245.    p+=strlen(p)+1;
  246.    p+=strlen(p)+1;
  247.    p+=strlen(p)+1;
  248.    p+=sizeof(int);
  249.    p+=sizeof(time_t);
  250.    p+=sizeof(int);
  251.    if (p-(const unsigned char *)mi>mi->record_length) return -1;
  252.    return ((p[-4]<<24)+(p[-3]<<16)+(p[-2]<<8)+p[-1]);
  253. }
  254.  
  255. int message_set_priority(struct message_index *mi,int priority)
  256. {
  257.    unsigned char *p=mi->data;
  258.    p+=strlen(p)+1;
  259.    p+=strlen(p)+1;
  260.    p+=strlen(p)+1;
  261.    p+=sizeof(int);
  262.    p+=sizeof(time_t);
  263.    p+=sizeof(int);
  264.    if (p-(unsigned char *)mi>mi->record_length) return -1;
  265.    p[-4]=priority>>24;
  266.    p[-3]=priority>>16;
  267.    p[-2]=priority>> 8;
  268.    p[-1]=priority>> 0;
  269.    return priority;
  270. }
  271.  
  272. int message_age(const struct message_index *mi)
  273. {   
  274.    time_t ctmt,mtmt;
  275.    struct tm *tmp;
  276.    time(&ctmt);
  277.    tmp=localtime(&ctmt);
  278.    tmp->tm_year=(mi->mes_date>>9)-1900;
  279.    tmp->tm_mon =((mi->mes_date>>5)&0xf)-1;
  280.    tmp->tm_mday=mi->mes_date&0x1f;
  281.    mtmt=mktime(tmp);
  282.    return ((ctmt-mtmt+(86400/2))/86400);
  283. }
  284.