This is mailtoc.c in view mode; [Download] [Up]
/* -*-C-*-
*******************************************************************************
*
* File: mailtoc.c
* RCS: /usr/local/sources/CVS/mailapp-utilities/mailtoc.c,v 1.3 1997/04/19 17:37:22 tom Exp
* Description: Table-of-contents access routines for Mail.app utilities
* Author: Carl Edman
* Created: Sun Apr 25 10:31:24 1993
* Modified: Sat Apr 19 14:38:39 1997 Tom Hageman <tom@basil.icce.rug.nl>
* Language: C
* Package: N/A
* Status: Experimental (Do Not Distribute)
*
* (C) Copyright 1993, but otherwise this file is perfect freeware.
*
*******************************************************************************
*/
#import <unistd.h>
#import <stdlib.h>
#import <stdio.h>
#import <string.h>
//#import <time.h>
#import <sys/file.h>
#import <sys/param.h>
#import <sys/types.h>
#import <sys/stat.h>
//#import <sys/dir.h>
#import <errno.h>
#import "mailtoc.h"
/* Works fine for Big Endian machines */
#define NXSwapBigLongToHost
#define NXSwapBigFloatToHost
#define NXConvertHostFloatToSwapped
#define NXSwapHostLongToBig
#define NXConvertSwappedFloatToHost
#define NXSwapHostFloatToBig
#define TOC_MAGIC 890712
#define TOC_MESSAGE_INDEX_MAX 100000
/* arbitrary limit on message index size, to avoid crashes on corrupt mailboxes. */
struct table_of_contents_header *get_table_of_contents_header(FILE *f,int createflag)
{
int n;
struct table_of_contents_header *toc;
toc=malloc(sizeof(*toc));
if(toc==NULL) return 0;
errno=0;
if ((n=fread((void *)toc,1,sizeof(*toc),f))!=sizeof(*toc))
{
if (!(createflag && n==0))
{
free(toc);
return 0;
}
toc->magic=TOC_MAGIC;
toc->num_msgs=0;
toc->mbox_time=-1;
toc->list=102.0;
toc->window.origin.x=271.0;
toc->window.origin.y=151.0;
toc->window.size.width=557.0;
toc->window.size.height=532.0;
/* Write table of contents immediately, so space for it is allocated.
Caveat: this will byteswap the contents of the in-memory toc,
so we'll fall through to the unswapping code below. */
if (put_table_of_contents_header(f,toc)!=0)
{
free(toc);
return 0;
}
}
toc->magic=NXSwapBigLongToHost(toc->magic);
toc->num_msgs=NXSwapBigLongToHost(toc->num_msgs);
toc->mbox_time=NXSwapBigLongToHost(toc->mbox_time);
toc->list=NXSwapBigFloatToHost(NXConvertHostFloatToSwapped(toc->list));
toc->window.origin.x=NXSwapBigFloatToHost(NXConvertHostFloatToSwapped(toc->window.origin.x));
toc->window.origin.y=NXSwapBigFloatToHost(NXConvertHostFloatToSwapped(toc->window.origin.y));
toc->window.size.width=NXSwapBigFloatToHost(NXConvertHostFloatToSwapped(toc->window.size.width));
toc->window.size.height=NXSwapBigFloatToHost(NXConvertHostFloatToSwapped(toc->window.size.height));
if (toc->magic!=TOC_MAGIC) /* basic sanity check. */
{
free(toc);
return 0;
}
return toc;
}
struct message_index *get_message_index(FILE *f)
{
long rl;
struct message_index *mi;
errno=0;
if (fread(&rl,1,sizeof(rl),f)!=sizeof(rl)) return 0;
rl=NXSwapBigLongToHost(rl);
if (rl > TOC_MESSAGE_INDEX_MAX) return 0;
mi=malloc(rl);
if(mi==NULL) return 0;
mi->record_length=rl;
if (fread(((char *)mi)+sizeof(rl),1,rl-sizeof(rl),f)!=rl-sizeof(rl))
{
free(mi);
return 0;
}
mi->mes_offset=NXSwapBigLongToHost(mi->mes_offset);
mi->mes_length=NXSwapBigLongToHost(mi->mes_length);
mi->mes_date=NXSwapBigLongToHost(mi->mes_date);
return mi;
}
int put_message_index(FILE *f,struct message_index *mi)
{
long reclen=mi->record_length;
mi->record_length=NXSwapHostLongToBig(mi->record_length);
mi->mes_offset=NXSwapHostLongToBig(mi->mes_offset);
mi->mes_length=NXSwapHostLongToBig(mi->mes_length);
mi->mes_date=NXSwapHostLongToBig(mi->mes_date);
errno=0;
return (fwrite(mi,1,reclen,f)!=reclen);
}
int put_table_of_contents_header(FILE *f,struct table_of_contents_header *toc)
{
toc->magic=NXSwapHostLongToBig(toc->magic);
toc->num_msgs=NXSwapHostLongToBig(toc->num_msgs);
toc->mbox_time=NXSwapHostLongToBig(toc->mbox_time);
toc->list=NXConvertSwappedFloatToHost(NXSwapHostFloatToBig(toc->list));
toc->window.origin.x=NXConvertSwappedFloatToHost(NXSwapHostFloatToBig(toc->window.origin.x));
toc->window.origin.y=NXConvertSwappedFloatToHost(NXSwapHostFloatToBig(toc->window.origin.y));
toc->window.size.width=NXConvertSwappedFloatToHost(NXSwapHostFloatToBig(toc->window.size.width));
toc->window.size.height=NXConvertSwappedFloatToHost(NXSwapHostFloatToBig(toc->window.size.height));
errno=0;
rewind(f);
return (fwrite(toc,1,sizeof(*toc),f)!=sizeof(*toc));
}
long message_current_date(void)
{
time_t clock;
struct tm *ctm;
time(&clock);
ctm=localtime(&clock);
return ((ctm->tm_mday&0x1f)
+(((ctm->tm_mon+1)&0xf)<<5)
+((ctm->tm_year+1900)<<9));
}
long message_date(int year,const char *month,int day)
{
static const char months[][4]=
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
int m;
for(m=0;m<12;m++) if (!strncmp(month,months[m],3)) break;
m=(m%12)+1; /* Wrap around to January for unidentifiable month
It's better than failing for an unattended program */
return (day&0x1f) + ((m&0xf)<<5) + (year << 9);
}
char *message_from(const struct message_index *mi)
{
char *p=mi->data;
return p;
}
char *message_subject(const struct message_index *mi)
{
char *p=mi->data;
p+=strlen(p)+1;
return p;
}
char *message_reference(const struct message_index *mi)
{
char *p=mi->data;
p+=strlen(p)+1;
p+=strlen(p)+1;
return p;
}
int message_attachsize(const struct message_index *mi)
{
const unsigned char *p=mi->data;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=sizeof(int);
if (p-(const unsigned char *)mi>mi->record_length) return -1;
return (int)((p[-4]<<24)+(p[-3]<<16)+(p[-2]<<8)+p[-1]);
}
int message_set_attachsize(struct message_index *mi,int size)
{
unsigned char *p=mi->data;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=sizeof(int);
if (p-(unsigned char *)mi>mi->record_length) return -1;
p[-4]=size>>24;
p[-3]=size>>16;
p[-2]=size>> 8;
p[-1]=size>> 0;
return size;
}
time_t message_attachtime(const struct message_index *mi)
{
const unsigned char *p=mi->data;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=sizeof(int);
p+=sizeof(time_t);
if (p-(const unsigned char *)mi>mi->record_length) return -1;
return (time_t)((p[-4]<<24)+(p[-3]<<16)+(p[-2]<<8)+p[-1]);
}
time_t message_set_attachtime(struct message_index *mi,time_t time)
{
unsigned char *p=mi->data;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=sizeof(int);
p+=sizeof(time_t);
if (p-(unsigned char *)mi>mi->record_length) return -1;
p[-4]=((int)time)>>24;
p[-3]=((int)time)>>16;
p[-2]=((int)time)>> 8;
p[-1]=((int)time)>> 0;
return time;
}
int message_priority(const struct message_index *mi)
{
const unsigned char *p=mi->data;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=sizeof(int);
p+=sizeof(time_t);
p+=sizeof(int);
if (p-(const unsigned char *)mi>mi->record_length) return -1;
return ((p[-4]<<24)+(p[-3]<<16)+(p[-2]<<8)+p[-1]);
}
int message_set_priority(struct message_index *mi,int priority)
{
unsigned char *p=mi->data;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=strlen(p)+1;
p+=sizeof(int);
p+=sizeof(time_t);
p+=sizeof(int);
if (p-(unsigned char *)mi>mi->record_length) return -1;
p[-4]=priority>>24;
p[-3]=priority>>16;
p[-2]=priority>> 8;
p[-1]=priority>> 0;
return priority;
}
int message_age(const struct message_index *mi)
{
time_t ctmt,mtmt;
struct tm *tmp;
time(&ctmt);
tmp=localtime(&ctmt);
tmp->tm_year=(mi->mes_date>>9)-1900;
tmp->tm_mon =((mi->mes_date>>5)&0xf)-1;
tmp->tm_mday=mi->mes_date&0x1f;
mtmt=mktime(tmp);
return ((ctmt-mtmt+(86400/2))/86400);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.