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.